今日头条面试题

       本宝宝从来没想过会去头条面试,但是莫名的收到了头条HR的电话,问我是否在找实习,什么时候有时间可以面试,既然已经约好面试的时间,那还是要好好准备一下,为了准备头条的面试,把网上关于头条的所有面试题刷了一遍,并且顺利的通过了一面和二面(虽然全程都是都程序写代码,其他的什么都没问,全程被两个面试官虐了两个小时四十一分钟)顺利收到了三面的通知,以为这一面可以面一些网络方面,操作系统方面的,没想到三面面试官一上来就出算法题,我很快就写出来了,让我讲一下 tcp  ip http 本宝宝巴拉巴拉一顿,面试官就开始问项目,嫌弃我的项目,因为本宝宝是通信专业的,所以做的项目也是偏于通信的,三面仅仅面了三十一分钟,最后把我刷掉了,虽然他把我刷掉了,但是也让我明白了找互联网工作是需要互联网方面的项目经验,现在已经每天都在做互联网项目,撒一波福利,希望秋招可以去我心心念念的那家公司。。。。(我是打不到的铜豌豆)

本宝宝心心念念的公司也嫌弃自己的项目太理论化,心心念念的公司一面面了一个小时二十一分钟,最后被挂掉了,你知道到吗,心心念念的那家面试官太好了,给我讲要怎样做互联网的项目,挂掉电话的时候我居然莫名的留下了眼泪(我相信在经过四五个月的锤炼,我是可以去那里的)。所以筒子们如果想转行走互联网这条路要多实践,不要天天看书,刷题,这些是远远不够的。

这是本宝宝在准备头条时,把所有题仔细刷了一遍,而最终无果,筒子们虽然春招实习我最终只收到一家的offer(目前已经不想去实习)几乎所有的都嫌弃我的项目,筒子们如果面试失败了,不要灰心,不要失落,坚持下去,最后一定会有结果的,就像我的好朋友和我说的那句话:一切都是为了最好的准备,现在你所经历的,可能就是为了最好的那家,最适合你的那家要经历的,只有经历了,你才会知道有哪些不足,好了筒子们,我就不再啰嗦了,下面是头条的面试题目:

 

n个整数的无序数组,找到每个元素后面比它大的第一个数,要求时间复杂度为O(N),在面试官提醒下写出来了,用栈+栈底指针

介绍5种IO模型

异步编程的事件循环

操作系统为什么要分内核态和用户态

为什么要有page cache,操作系统怎么设计的page cache

STL里resize和reserve的区别

撸一个std::lower_bound,不断优化,直到最坏复杂度也为O(logN)

C++11新特性

怎么实现线程池

用到哪些C++的新特性

怎么唤醒,调度线程

什么是LRU缓存

怎么设计的LRU缓存,详细

实现一个二叉树的持久化方案,可以伪代码,必须用指针

主要是序列化和反序列化的过程

(卡在指针的持久化,然后他不是很满意,说我应该做得出,然后我只能把我的另一种不用指针的方案给他讲,才算勉强过)

实现二叉树的层序遍历再按层输出

tcpudp的区别

http的启动方法,没答出来

算法题:二叉树层级遍历,以及follow up是每下一层遍历方向颠倒

hashmap实现原理,冲突等

算法题:二叉树最小公共祖先【一开始问的是一棵树里最远的两个节点间的距离,思考的有点久于是换题了...】

算法题:链表成环判断

算法题:链表交叉判断

http请求的组成

get,post的区别

怎么解决hash冲突,然后让我讲讲Http协议,好像讲的不太好,第一题好像是个链表的,几下写完了,然后面试官又抛出一个合并k个链表,我的做法是用最小堆去维护,然后面试官说可以,第三题好像是按照字典序打印1~N的排序,从1开头比N小的数开始枚举就好了,也不难,期间面试官说去开会,让我写完打他电话,应该在10分钟左右debug完成,面试说这面通过,第二天HR打电话说安排下一轮,时间还是一周后同一天

· 进程线程的区别(这个问得比较细,不只是简单的内存共享之类的,还包括操作系统的进程描述,写时复制,操作系统启动等问题,推荐《深入理解计算机系统》)

· epoll,IO多路复用,聊到nginx的原理,和Apache的区别

· 常见的网络攻击方法,比如跨站脚本,sql注入之类的

· Https,非对称加密等

· 一个秒杀系统的架构,包括CDN,反向代理,session共享,由于分布式数据库我不熟,所以数据一致性那部分没有解决。

· Hashmap的实现原理,优化方法(其实JDK 8已经用二叉树替换链表了,思路差不多就是这个)

· 脑筋急转弯,1000桶牛奶,1桶有毒,用10只小白鼠试出来。其实就是二进制,网上有答案,提示:2^10 = 1024.

3.OSI 7层协议?有哪些是可靠的网络连接?TCP为什么是可靠连接?cookie vs. session

 Linux命令:查看端口的的命令(此处忘记耍帅,<(^′)>),查看cpu/內存, 文件权限管理(chmod)

 线程池的原理

给一个数组返回最小堆(把核心代码写出来了,但是面试官好像不怎么看,让我输入测试下。我又写了半天输入输出,连续面了三个小时,加上对好久没写了不熟悉弄了半天,他不承认我写出来了。。丧) 

    最小堆的插入时间复杂度

    二分查找的时间复杂度怎么求出来的,怎么证明。

    malloc函数,你所知道的一切。(只记得一点点了)

httphttps的区别(没有答的很好)快速排序的时间复杂度,为什么是nlogn,最坏的情况是什么,最坏情况下的时间复杂度是什么。

给一些数据,使用LRU计算命中次数,并用编码实现

2、说一下自己值得分享的一个项目

3、继续问了https的原理是什么

4tcp连接的过程

·      介绍I/O复用技术,epoll优于select的原因

·      介绍线程池

·      图的邻接矩阵和邻接表的表示,邻接表的数据结构。敲代码不运行

  • 介绍C ++内存管理(C ++的内存模型是热门问题
  • 对文件系统的了解

·      · 算法题1:给定数组,快速求出所有数右边第一个比其大的数。回答思路

·      · 算法题2:给定k个数组,每个数组都是有序的,且每个数组最大值-最小值<1000,1<k<1000,求所有数的中位数。回答思路

·      · 进程与线程区别

·       ·  STL内存分配

·      一棵树上路径和为固定值的那些路径

·      归并排序

·      封装、继承、多态

·      c++c的区别,和现有更高级语言的区别

  • 二分查找
    • 无重复元素的二分查找
    • 含重复元素的二分查找
  • 找第k大数
    • 快排实现、堆实现
    • 进阶:不用额外空间,尽可能快的找到第k大数

·      两个栈实现一个队列、怎么优化

·      数组每一个元素找出数组右边第一个大于自己的数

·      实现LRU

·      TCP四次握手

·      滑动窗口、窗口大小

·      线程与进程区别

·      什么是线程安全

·      乐观锁、悲观锁

·      进程间通信

·      管道怎么实现

·      左连接、右连接

·      索引、主键的区别

给定n,将1,2,,n按字典序排列,求第k大的数

·      求两个有序数组前K大的数

·      拓展:求m个有序数组前K大的数

·      设计一个带有有效时间TTL的KV存储系统,包含set(key,value,ttl)、get(key)方法、怎么优化

·      循环有序数组的二分查找

·      手写继承实现

·      2.洗牌算法

·      3.柯里化实现

·      4.数组去重(写出一种远远不够,3种方式)

·      .同步和异步,阻塞和非阻塞

·      7.了解http 2.0么?多路复用在非IO阻塞中有没有用到?

·      求解两个栈模拟队列

·      2.求解一个区间的和乘以这个区间最小值的最大值?单调栈,个人很久没有刷题了,这道题复杂度用的比较大

·      3.求解一个矩阵中找一条最长的递增路径?好像是用DP做,个人用有向图DFS和记忆化搜索处理

·      1.引用与指针的区别

·      2.c++与java的区别

·      3.实现hashmap,怎么扩容,怎么处理数据冲突?怎么高效率的实现数据迁移?

·      4.TCP三次握手各个的状态和发送的包

·       tcp 断开连接的各种状态变化,tcp拥塞控制算法的详细介绍,tcp\udp区别

·       熟悉的Linux命令
Linux:统计文本中有多少行
TCP拥塞控制

  1. 写代码:多线程实现从A,B,C三个文件中读取文件放到D文件中,优化:如何同步实现
  2. 多线程中有哪些锁
  3. 写一个单例模式,什么时候用到,还了解哪些设计模式,装饰者模式是什么,举例
  4. 异常:见过哪些异常,classCastException是什么异常,在什么时候出现
  5. 算法实现:求数组最大连续子序列
  6. 计算机网络:post和get的区别
  7. 线程和进程的区别
  1. 线程的状态
  2. 介绍死锁和如何避免
  3. 三次握手
  4. 介绍http tcp
  5. 输入url,到浏览器显示的过程
  6. gc
  7. 算法实现:单链表旋转
  1. 写代码:找出字符数组中只出现三次,且最早出现完三次的字符(eg:aabcbba输出b)

2.  hadoop已知每一个点的neighbor,求每一个点的二度邻居

3.  2. 有一个排好序的数组,先将其随机循环右移,求在数组中查找指定target的位置 lgn

4.  3. 有字符串,将所有连续的ac跟单独的b去掉后的字符串:如acccccb->ccc; aacceacdb->ed

5.  时间复杂度O(n) 空间复杂度O(n) --> 时间复杂度O(n) 空间复杂度O(1)

6.  4. 二分查找,查第一个出现的位置

7.  5. 数组:找第k大的数 (无序数组) O(N) -> 数组无法修改,额外空间O(1) 时间O(N)

8.  6.tcp慢启动过程

9.  2、写代码 两个栈实现队列

10.3、写代码 数组的最大连续子集(和最大的连续子集)

6、malloc和new的区别

2、写代码  建一个数组循环左移N位,最好不要用辅助空间(我最后还是用了= =)

11.3、写代码 复杂指针的复制

12.4、地址栏输入一个url到最后内容出现在页面上,中间经历了哪些过程

13.5、stl有哪些容器

14.6、vector的底层实现以及如何删除内容释放内存的

15.7、有哪些内存区

16.8、状态码有哪些

17.9、基于UDP和TCP的socket通信过程 

18.2、写代码  压缩驼峰字符串

19.3、如果四川地区大量群众都表示无法打开头条网站,请说明一下原因

20.4、基于上个问题,我也是半蒙半猜,我说可能是1、头条服务器的问题2、运营商的问题3、路由问题

21.然后面试官就问如何测试是否是这三个的问题,瞎答了一波

22.5、如果是自动获取DNS,那么如何查看当前计算机的DNS地址

8、电脑用久了之后开机时间变长,请问有什么原因

23.9、一道选择题,题目特别长,关于战争时期美国海军招新宣传:现在纽约市民的死亡率是千分之16,美国海军的死亡率只有千分9。

24.让选择一个答案,正确答案是:纽约市民中有很多生存能力不高的幼儿和老人(大概是这样)

25.10、基于上述材料,举一个生活中的例子。。。。。。。。。。。。。

· TCP与UDP的区别

· TCP与UDP分别应用在什么方面

· TCP和UDP分别对应协议(应用层)

· 同步和异步的优缺点

· TCP三次握手四次挥手

· TCP三次握手的缺陷

· 短链接和长链接的特点以及应用在什么场合

· 乐观锁和悲观锁

· 自旋锁是什么样的

· 进程同步的方式

· 线程池的结构与如何实现同步

· 单例模式多线程

·       ·  其他设计模式

· TCP与UDP的区别

  1. 基于连接与无连接
  2. TCP要求系统资源较多,UDP较少;
  3. UDP程序结构较简单
  4. 流模式(TCP)与数据报模式(UDP);
  5. TCP保证数据正确性,UDP可能丢包
  6. TCP保证数据顺序,UDP不保证

· TCP与UDP分别应用在什么方面

  1. TCP:对效率要求低,对准确性要求较高 (如文件传输、重要状态的更新等)
  2. UDP:对效率要求高,对准确性要求较低 (如视频传输、实时通信等)。

· TCP和UDP分别对应协议(应用层)

  1. TCP: STMP, TELNET, HTTP, FTP
  2. UDP: DNS,TFTP,RIP,DHCP,SNMP

· 同步和异步的优缺点

  1. 同步和异步的特点
    1. 异步传输是面向字符的传输,而同步传输是面向比特的传输。
    2. 异步传输的单位是字符而同步传输的单位是帧。
    3. 异步传输通过字符起止的开始和停止码抓住再同步的机会,而同步传输则是以数据中抽取同步信息。
    4. 异步传输对时序的要求较低,同步传输往往通过特定的时钟线路协调时序。
    5. 异步传输相对于同步传输效率较低。
  2. 同步的好处:
    1. 同步流程对结果处理通常更为简单,可以就近处理。
    2. 同步流程对结果的处理始终和前文保持在一个上下文内。
    3. 同步流程可以很容易捕获、处理异常。
    4. 同步流程是最天然的控制过程顺序执行的方式。
  3. 异步的好处:
    1. 异步流程可以立即给调用方返回初步的结果。
    2. 异步流程可以延迟给调用方最终的结果数据,在此期间可以做更多额外的工作,例如结果记录等等。
    3. 异步流程在执行的过程中,可以释放占用的线程等资源,避免阻塞,等到结果产生再重新获取线程处理。
    4. 异步流程可以等多次调用的结果出来后,再统一返回一次结果集合,提高响应效率。

· TCP三次握手四次挥手

· TCP三次握手的缺陷

  1. SYN- Flood攻击: 通过向网络服务所在端口发送大量的伪造源地址的攻击报文,就可能造成目标服务器中的半开连接队列被占满,从而阻止其他合法用户进行访问。
  2. 防范:
  • 无效连接监视释放 这种方法不停的监视系统中半开连接和不活动连接,当达到一定阈值时拆除这些连接,释放系统资源。这种绝对公平的方法往往也会将正常的连接的请求也会被释放掉,”伤敌一千,自损八百“
  • 延缓TCB分配方法
  • 使用SYN 2Proxy防火墙

· 短链接和长链接的特点以及应用在什么场合

  1. 长连接:
  • 长连接多用于操作频繁,点对点的通讯,而且连接数不能太多的情况。
  • 每个TCP连接的建立都需要三次握手,每个TCP连接的断开要四次握手。
  • 如果每次操作都要建立连接然后再操作的话处理速度会降低,所以每次操作后,下次操作时直接发送数据就可以了,不用再建立TCP连接。例如:数据库的连接用长连接,如果用短连接频繁的通信会造成socket错误,频繁的socket创建也是对资源的浪费。

短连接:

  • web网站的http服务一般都用短连接。因为长连接对于服务器来说要耗费一定的资源。像web网站这么频繁的成千上万甚至上亿客户端的连接用短连接更省一些资源。试想如果都用长连接,而且同时用成千上万的用户,每个用户都占有一个连接的话,可想而知服务器的压力有多大。所以并发量大,但是每个用户又不需频繁操作的情况下需要短连接。总之:长连接和短连接的选择要根据需求而定。

· 乐观锁和悲观锁

  • 乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读,发生冲突的概率低的应用类型,这样可以提高吞吐量。
  • 悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。悲观锁适用于可靠的持续性连接,诸如C/S应用。对于Web应用的HTTP连接,先天不适用。

· 自旋锁是什么样的

  • 对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁。
  • 如果等待的时间比较短,适合使用自旋锁
  • 占用大量的CPU资源

· 进程同步的方式

  1. 临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
  2. 互斥量:为协调共同对一个共享资源的单独访问而设计的。
  3. 信号量:为控制一个具有有限数量用户资源而设计。
  4. 事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。

· 线程池的结构与如何实现同步

  1. 线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
  2. 工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
  3. 任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
  4. 任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。

· 单例模式多线程

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

class Lock

  {

  private:      

      CCriticalSection m_cs;

  public:

      Lock(CCriticalSection  cs) : m_cs(cs)

      {

          m_cs.Lock();

      }

      ~Lock()

      {

          m_cs.Unlock();

      }

  };

 

  class Singleton

  {

  private:

      Singleton();

      Singleton(const Singleton &);

      Singleton& operator = (const Singleton &);

 

  public:

      static Singleton *Instantialize();

      static Singleton *pInstance;

      static CCriticalSection cs;

  };

 

  Singleton* Singleton::pInstance = 0;

 

  Singleton* Singleton::Instantialize()

  {

      if(pInstance == NULL)

      {   //double check

          Lock lock(cs);           //用lock实现线程安全,用资源管理类,实现异常安全

          //使用资源管理类,在抛出异常的时候,资源管理类对象会被析构,析构总是发生的无论是因为异常抛出还是语句块结束。

          if(pInstance == NULL)

          {

              pInstance = new Singleton();

          }

      }

      return pInstance;

  }

1.重复了一面的自我介绍之后,面试官也很直接的在题目上写了一个二叉树,然后要求层序遍历输出这个二叉树,要求换行...刚庆幸自己之前看过的时候,发现想不起来了,贼尴尬

其实我只是写了一个层序遍历,然后面试官让讲思路的时候,我就一边讲一边改,最后总算是弄出来了...

3.TCP/UDP的区别,介绍区别顺带说了使用场景,最后补刀TCP头20字节,UDP头8字节,然后问TCP头结构(自己坑自己)

4.TCP如何保证可靠性. 把三次握手很详细地说了一遍,发送什么码进入什么状态..

5.除了三次握手还有么?滑动窗口,1比特等待协议,回退N针协议,选择性重传协议说了一边

6.还有么?不用说的那么详细,时间不太多了 说了 快重传 快恢复 超时重传,然后实在不知道了

7.操作系统,进程线程的区别,进程间通信方式

8.网络编程,答没用过,不会

9.select/epoll了解不.答了解,但不知道对不对,希望不要介意,说了select用户态到内核态,epoll只负责活跃的,不管那些不活跃的

10.简单介绍Nginx是如果工作的.答了masterwork之类的,然后没话可说了赶紧补充一些Apache的prefork时怎么工作的做了一下对比

2.网络模型以及各层协议,TCP拥塞控制
3.IO复用以及select,poll,epoll区别
4.指针和引用区别
5.数据库索引有哪些,他们的数据结构
6.复杂度为Onlogn的排序有哪些
7.LRU cache  ,leetcode原题,但是stl规定只能用map,其他全都自己实现。(写了好久,主要是要自己写双向链表list不能用STL)