分享深信服(信锐科技)C/C++ 开发面经(已OC)
可能有的内容答得不完善不正确,请大家注意甄别。
一面(9.15 40min)
1. 自我介绍
2. C 与 Python 区别(C 是编译型语言,Python 是解释型语言;C 是把 C 源码经预处理、编译、汇编、链接生成可执行文件,然后运行,Python 是解释器把 Python 源码解释成 C 代码等运行;C 是面向过程的编程语言,Python 是面向对象的编程语言;C 需要程序员手动管理内存,Python 用 GC 自动管理;区别很多 )
3. socket 在 TCP/IP 模型的哪一层,从 socket 中读写除了 read() 和 write(),还可以用什么(传输层,还可以用 recv( )和 send(),这两个系统调用的最后一个参数如果为0,那么等同于 read() 和 write(),这个参数还可以是NOROUTE 不路由,PEEK 只读取不清空等;UDP 还可以使用 recvfrom( )和 sendto() 参数列表最后再加两个参数,标识对端的地址)
4. 堆和栈(栈由编译器管理,内存地址自上向下生长,无内存碎片,不需要程序员手动释放,空间较小;堆由程序员手动管理或智能指针辅助管理,内存地址自下向上生长,可能有先申请但已释放,但后申请的未释放造成的内存碎片,ptmalloc 用一个哈希表帮助管理这些内存碎片(合并,分配),空间较大。堆在发生 malloc 的时候会根据申请的大小使用 brk() 或 mmap() 系统调用,这是实际从用户态陷入内核态向操作系统申请内存空间的操作。malloc() 的大小未必等于 brk() 的大小,brk() 会申请出一个内存池,由 ptmalloc 管理;当堆的上方申请空间(top chunk)足够大会发生 brk 紧缩,这是实际从用户态陷入内核态向操作系统归还内存空间的操作)
5. 常见二叉树(大(小)顶堆,二叉搜索树,AVL平衡树,红黑树等)
6. 快速排序的思路,选轴策略,如果递归实现快排最后小尺度的优化思路(选轴后,从左到右搜索到一个比轴大的,从右向左搜索到一个比轴小的,交换位置,左右相遇时,左右中间是轴的位置,然后两侧重新选轴,继续分治;选轴策略是为了避免快排在某些极端情况下时间复杂度退化到 O(n^2)(比如:选第一个为轴的降序数组快排),可以随机选轴,中位选轴;递归实现最后小尺度时,寻找函数入口,保存现场等工作会造成较大的开销,可以使用选择排序替代快速排序。C++ 中的 sort() 方法用的就是快速排序结合选择排序的实现)
7. 数组和链表(数组在存储上是物理连续的,链表不是。所以链表在存储上更加灵活,对于在链表插入删除的时间复杂度是 O(1),但是链表查找的时间复杂度是 O(n) 不支持随机访问;相反数组插入删除的时间复杂度是 O(n),因为需要调整后续的存储,但支持随机访问,查找的时间复杂度是 O(1))
8. 怎么优化链表遍历(我理解的面试官的提问意图是结合数组链表的优秀特性,答的 STL 库中的 deque 容器,deque 的存储结构是一段连续的内存空间作为中控区,每一个中控区挂在一个哈希桶,用双向链表实现;deque 需要做的工作就是,让使用者感觉在使用一段连续的内存空间,所以 deque 的迭代器复杂,需要存储四个值(中控区中的哈希桶索引,哈希桶链表的首地址,尾地址,和当前地址)。思路在于把一个长链表剪短,挂载在可以随机访问的中控区中,用较多的迭代器信息记录帮助随机访问,从而实现随机访问和灵活物理存储)
9. SQL 事务(在 MySQL 中在 begin; 和 commit; 中间的内容,使用事务是为了实现多条语句在运行时数据库系统也能为其提供原子性,和对应的隔离性(RC,RR))
10. 怎么优化数据库 (合理设置索引;添加缓存;主写从读,读写分离;分库分表等)
二面(9.16 45min)
1. 自我介绍
2. 设计模式了解哪些,用过哪些(用过工厂模式,适配器模式,代理模式)
3. 用 OC 手撕一个代理模式(不会,写不出来)
4. 算法:冒泡排序
5. 项目(20分钟拷打,通信板子是什么架构的?从数据产生到信号产生的过程(用户态产生数据,通过套接字被用户态获取,编码、调制,用网卡发出去的详细过程,答得不好))
HR面(9.23 1h10min)次日已OC,开奖(21 * 13~15)已拒