2021/3/29 下午 C++后端 字节跳动 暑期实习生一面
- C++方面
- 项目
看游双的书慢慢攒了一个web后台服务器小项目,开始先让介绍一下这个项目,blabla介绍……(这点答的不好,没有系统性地介绍,东一点西一点的,这个后续要准备 )
问题1. 你用了Reactor事件处理模式,介绍一下Reactor和Proactor。 (没答好, 只是笼统地说了一下思想,没有具体讲出二者的过程)
Reactor:
主线程监听I/O事件,工作线程处理读写就绪事件。(只答了这么多,后面的也应该讲出来), 主线程注册socket的读就绪事件,调用epoll_wait监听socket上的EPOLLIN,EPOLLOUT事件,当有可读/可写时事件时,主线程将数据读/写事件添加到请求队列,子线程处理I/O和逻辑。主线程向子线程通知的是就绪事件,I/O操作由子线程来做。
Proactor:
主线程和内核处理 I/O, 子线程负责业务逻辑。(只答了这么多,后面的也应该讲出来), 主线程通过aio_read向内核注册读完事件,告知其用户缓冲区的位置,并设定完成时内核如何通知应用程序。内核执行读写,完成后通知子线程,例如用信号,子线程处理业务逻辑,注册写完成事件,告知内核用户缓冲区的位置。 子线程得到的是完成事件和数据,I/O操作是由内核完成的。
模拟Proactor: (没有问,感觉说一下比较好)
由主线程执行I/O操作,之后主线程向子线程这一完成事件。主线程调用epoll_wait循环监听/等待连接socket上的事件。如果是写事件,直接往socket写入数据;如果是读事件,循环读入客户数据,将任务添加到请求队列,睡眠的子线程通过竞争,如加互斥锁,获得事件的处理权
问题2. 说一说你的基于升序链表的定时器 。
问题3. 说一说epoll.
说了一下select, poll的实现,epoll的底层实现,维护的就绪事件表,效率的对比,活跃链接的数量占比比较大的时候效率的对比
问题4. 你使用定时器处理非活动链接,TCP断开连接这个过程有个time_wait状态,这个状态出现在哪一方,为什么要有这个状态?
答的很差,复习之后再来填坑……
- 撕代码
旋转操作是指将数组从某个地方截断为两段,将第二段放到第一段前面。
例如:[1, 2, 3, 4, 5, 6, 7] -> [4, 5, 6, 7, 1, 2, 3]
时间要求 : log(n)
思路:首先判断是否旋转过,这一步直接比较arr[0]和arr[arr.size() - 1]就可以,如果旋转过,arr[0]一定大于arr[arr.size()-1];
第二步,如果没有旋转直接二分法
如果旋转过, 先找到最大值的位置, 最大值两侧分别是有序的子数组,对两个子数组分别二分法。
问题就是如果在log(n)内找到最大值的位置,这个没想到。面试官提示了一下,当时没反应过来。直接让写下一题了
2. 反转单链表
3. 分段反转单链表, 每k个节点内部反转,最后不够k个不反转
例:输入[1, 2, 3, 4, 5, 6, 7, 8] k = 3
输出[3, 2, 1, 6, 5, 4, 7, 8]
没写完,面试官说(面试)时间超时了,差不多面试要结束了。
全部评论
(3) 回帖