面灵AI→

小米 C++ 二面:epoll、智能指针与线程池设计

轮次
二面
时间
2026-10
来源
牛客网

《面试题目》

  1. 是否了解过岗位的需求,这个岗位做什么?
  2. 自我介绍。
  3. 实习的主要工作是什么,使用的语言?
  4. 讲解一下平时怎么使用 AI 开发?
  5. 简历上写了学习 CUDA 和 AI,问我对 Agent 有什么了解?
  6. 为什么选择 epoll 而不是 poll?epoll 是怎么实现的?
  7. 套接字编程客户端和服务端的 API 有哪些?
  8. 项目里线程池的数量怎么确定?
  9. 常用的 Linux 命令有哪些?
  10. 有虚函数的类,为什么实例的 sizeof 会大一些?
  11. C++ 的内存怎么管理?你的项目里怎么应用智能指针?
  12. 智能指针有哪些?unique_ptr 和 shared_ptr 的区别是什么?
  13. epoll 有哪些函数和相关 API?
  14. 使用最多的语言是什么?
  15. 手撕:反转字符串,考虑健壮性。

《参考解析》

epoll 相比 poll 的优势是「不随连接数线性变慢」。poll 每次调用要把整个 fd 数组从用户态拷到内核态并线性扫描;epoll 用红黑树管理注册的 fd、用就绪链表返回事件,epoll_wait 只取就绪的,所以连接多但活跃少时效率高。实现上是 epoll_create 建实例、epoll_ctl 增删改、epoll_wait 等待;支持水平触发和边缘触发,边缘触发必须配合非阻塞 IO 一次读到 EAGAIN。

套接字 API 按顺序记:服务端 socket → bind → listen → accept → read/write → close;客户端 socket → connect → read/write → close。注意字节序转换、部分读写、EINTR 重试和关闭时的 TIME_WAIT。

线程池数量看任务类型:CPU 密集型约等于核数(+1 防抖),IO 密集型可以远大于核数,按「核数 × (1 + 等待时间/计算时间)」估算;最终要靠压测调,并配上有界队列和拒绝策略,避免无限堆积。

有虚函数的类会多一个虚表指针(64 位下 8 字节),用于运行时多态;多继承可能有多份。空类 sizeof 为 1 是为了保证不同对象地址不同。

智能指针:unique_ptr 独占所有权、不可拷贝只可移动、零额外开销;shared_ptr 共享所有权、控制块里放强引用计数和弱引用计数、计数原子但对象访问仍需同步;weak_ptr 打破循环引用。优先 unique_ptr,确实共享再用 shared_ptr。

反转字符串的健壮性:处理空串、单字符、UTF-8 多字节(按字符而不是字节反转会复杂)、以及入参是 const 时要不要返回新串。双指针原地交换是最常见的写法。