接上篇 :上一篇《大厂 C/C++ 面试题汇总(问题清单篇)》,我把 12 家大厂近三年的 C/C++ 面试真题整理成了 120 道题目清单,只列题、没给答案,让你先看清「该复习什么」。本篇就是那 120 道题的答案详解 :一题一题答完,每题给答案 + 易错点 + 面试官追问角度。
两篇怎么配合:上篇的章节顺序和本篇一一对应(上篇第三章字节 = 本篇第三章字节,以此类推),建议你先在上篇把题目自己过一遍、心里有数,再回本篇对答案、补细节;直接背答案也能用,但先答后对印象更深。
回顾这套题的整体逻辑:考来考去就是那几个核心坑------虚表布局、智能指针循环引用、vector 扩容、epoll 的 ET/LT、TCP 的 TIME_WAIT......上篇已经把「哪家爱问哪个、哪个季节更难、双非该怎么排优先级」标清楚了,本篇按同样的顺序把答案补齐。
一、先说清楚:数据从哪来、季节怎么标(诚实声明)
**来源:**本文题目与答案来自公开面经聚合------牛客网、面试鸭、CSDN、知乎上 2023--2025 年校招/实习/提前批的 C/C++ 后端、客户端、音视频、基础架构方向的真实复盘,能对应到公开讨论的考点都按「公开面经共识」给出。大厂考点三年高度稳定,所以按稳定图谱组织。
幸存者偏差: 面经是「过了/面崩了」的人写的,有记忆误差和幸存者偏差,不是官方题库,用来建立复习靶心,不能替代系统啃书(《C++ Primer》《STL 源码剖析》《操作系统概念》《TCP/IP 详解》)。
季节标注方法论(重点): 大厂校招节奏是 提前批(7--8 月,最难、常考源码/设计)→ 秋招主批(8--11 月,题量最大、底层深挖最多)→ 春招/暑期实习(3--5 月,偏基础+项目+中等手撕)。同一知识点全年都可能出现,所以我的标签是「季型」而非伪造具体日期:
|-----------|------------------------------|
| 标签 | 含义 |
| 【秋招·主批】 | 秋招主战场,题量最大、底层追问最多 |
| 【提前批·高难】 | 7--8 月提前批,竞争小但难度最高,常考系统设计/源码 |
| 【春招·实习】 | 3--5 月春招与暑期实习,偏基础+项目+中等手撕 |
| 【四季通用·基础】 | 全年各场都可能出现的基础题 |
| 【待验证】 | 来源面经未明确季节/年份,按规律推断,需你自行核对 |
说明:题目→季节的精确对应无法逐条溯源,故以「季型」标注;凡我推断处均打【待验证】,绝不编造具体面试日期与面试官原话。
二、目录
- 三、字节跳动(难度 ★★★☆)
- 四、腾讯(难度 ★★★★)
- 五、阿里巴巴(难度 ★★★★)
- 六、美团(难度 ★★★☆)
- 七、百度(难度 ★★★)
- 八、华为 / 华为 OD(难度 ★★☆)
- 九、京东(难度 ★★★)
- 十、网易(难度 ★★★)
- 十一、拼多多(难度 ★★★★)
- 十二、快手(难度 ★★★☆)
- 十三、小米(难度 ★★★)
- 十四、滴滴(难度 ★★★☆)
- 十五、各大厂面试特点横向对比
- 十六、在校生与应届生分阶段备考路线
- 十七、结语
三、字节跳动(难度 ★★★☆,算法权重最高)|对应上篇第三章
风格: 手撕代码必考且占比大(一面往往直接写题),C++ 基础 + STL + 操作系统 + 网络都要,二面重项目深挖与系统设计。算法不好基本过不了,白板写对 + 讲清复杂度是硬门槛。
① 基础层(C/C++ 语法、基础数据结构)
- 【四季通用·基础】static 有几种用法? 答:①局部 static 延长生命周期、只初始化一次;②全局 static 限制文件内可见(内部链接);③类成员 static 属于类而非对象、所有实例共享;④类函数 static 无 this、只能访问 static 成员。
- 【秋招·主批】const 与 constexpr 区别? 答:const 是「运行期只读承诺」,constexpr 是「编译期可求值」。constexpr 变量/函数能在编译期算出来(如数组大小),const 不一定。
- 【春招·实习】C 和 C++ 的 struct 区别? 答:C 的 struct 只能包数据、不能有函数;C++ 的 struct 默认 public、能有成员函数/构造函数/继承,和 class 唯一区别是默认访问权限。
- 【四季通用·基础】四种 cast 各自何时用? 答:static_cast(基础类型、上行转换,无运行时检查);dynamic_cast(下行安全转换,依赖 RTTI,仅用于多态);const_cast(去/加 const);reinterpret_cast(比特位重解释,最危险,如指针转整数)。
- 【秋招·主批】快排时间复杂度与最坏情况?稳定吗? 答:平均 O(n log n),最坏 O(n²)(已有序且选首尾为 pivot),不稳定。工程中用「三数取中 + 小数组转插排」规避最坏。
② 进阶层(对象模型、内存、STL、OS/网络)
- 【秋招·主批】虚函数怎么实现?vptr 在哪?多继承虚表怎么布局? 答:每个含虚函数的类有一张 vtable(存虚函数指针),对象头部有 vptr 指向它;调用虚函数经 vptr→vtable→偏移找函数,一次间接寻址(约几 ns)。多继承时对象可能有多个 vptr(每个有虚函数的基类一个),this 指针在跨基类调用时要调整偏移。虚继承(菱形)额外引入虚基类表,解决二义性但更复杂。
- 【秋招·主批】shared_ptr 引用计数存在哪?线程安全吗? 答:计数在对象外的「控制块」里(make_shared 把对象和控制块一次分配)。引用计数增减是原子操作(线程安全),但对象本身的读写不是,多个 shared_ptr 指向同一对象仍要自己加锁。
- 【秋招·主批】vector 扩容机制?哪些操作会使迭代器失效? 答:size==capacity 时按约 1.5~2 倍(GCC 2 倍、MSVC 1.5 倍)重新分配并搬移;reserve 可预分配避免反复搬。insert/erase 导致搬移时所有迭代器失效;erase 后只有被删位置之后的失效(C++11 起 erase 返回下一有效迭代器)。
- 【秋招·主批】内存对齐为什么重要?#pragma pack 做什么? 答:CPU 按字长读内存,未对齐可能触发多次读取甚至硬件异常;对齐也利于缓存行。#pragma pack(n) 强制按 n 字节对齐,常用于网络协议包/结构体序列化,但牺牲空间换确定布局。
- 【秋招·主批】TCP 为什么 TIME_WAIT 是 2MSL?太多怎么办? 答:2MSL 保证「最后的 ACK 能重传」+「旧报文在网络中消亡」。过多会占端口:可开启 tcp_tw_reuse(客户端)/ 调小 MSL / 用长连接,不要盲目开 tcp_tw_recycle(已废弃、NAT 下会丢包)。
- 【秋招·主批】epoll 的 ET 和 LT 区别?ET 下 accept 为何可能丢连接? 答:LT 水平触发(没处理完一直通知);ET 边缘触发(状态变化才通知一次,必须一次读/写到 EAGAIN)。ET 下若一次 accept 只取一个连接,剩余连接不会再次通知 → 丢连接;所以 ET 必须配合非阻塞 + 循环 accept 到 EAGAIN。
③ 高难层(并发、手撕、设计)
- 【提前批·高难】手写线程安全单例(C++11 之后的最优写法)。 答:用 magic static(函数内 static 局部变量,C++11 保证线程安全初始化):
static Singleton& get(){ static Singleton s; return s; }。比双检锁简洁且无内存屏障坑。
- 【秋招·主批】手撕 LRU Cache,get/put 都 O(1)。 答:哈希表(key→链表节点)+ 双向链表(按访问顺序);get 命中移到头,put 满则删尾;节点同时挂在哈希和链表上。
- 【提前批·高难】TopK 怎么求?海量数据(内存放不下)怎么办? 答:内存够用:维护 K 大小小顶堆 O(n log K);或快排 partition 平均 O(n)。海量:分桶/哈希分片到磁盘,每片求 TopK 再归并,或用「堆 + 外排」。
- 【提前批·高难】std::move 到底做了什么?右值引用、完美转发是什么? 答:std::move 只是 static_cast 成右值引用,不移动任何东西,真正的资源转移发生在移动构造/赋值里。右值引用(&&)绑定临时对象;完美转发用 forward<T> 在模板里「原样」传递左/右值,靠引用折叠规则。
- 【秋招·主批】手写一个简易线程池。 答:核心=任务队列(mutex+condvar 保护)+ N 个 worker 线程(循环取任务执行)+ 提交接口(加锁入队+notify)。考察点:队列线程安全、优雅退出、任务用 std::function 包装。
四、腾讯(难度 ★★★★,底层深挖最狠)|对应上篇第四章
风格:「基础扎实 + 深度挖 + 项目真实落地」。追问不是「会不会用」而是「底层怎么实现、能不能画图」。后台/游戏/音视频方向对 C++ 对象模型、内存、网络、并发挖到源码级。
① 基础层
- 【四季通用·基础】C++ 程序的内存布局(text/rodata/data/bss/heap/stack)各自存什么? 答:text 代码(只读)、rodata 常量字符串/const、data 已初始化全局/静态、bss 未初始化全局/静态(不占文件体积)、heap 向高地址增长、stack 向低地址增长。这是腾讯几乎必问的「背下来」题。
- 【秋招·主批】构造函数/析构函数能是虚函数吗?为什么? 答:构造函数不能是虚函数(对象未建好、vptr 还没设);析构函数作为基类时必须声明 virtual,否则通过基类指针 delete 派生类对象只调基类析构 → 内存泄漏/未定义行为。
- 【秋招·主批】new/delete 与 malloc/free 的 11 层差异(说核心几条)。 答:new 是运算符、调构造函数、失败抛 bad_alloc、可重载;malloc 是库函数、只分配裸内存、失败返回 NULL、返回 void* 要强转。new int10 实际分配 = 10sizeof(int) + 调试头尾,不是精确 104。
- 【春招·实习】深拷贝 vs 浅拷贝,何时必须自己写拷贝构造? 答:浅拷贝只复制指针值(两对象指向同一块内存,析构双释放崩);深拷贝另开内存拷贝内容。类里有裸指针/资源管理时必须自定义「三五法则」。
② 进阶层
- 【秋招·主批】虚函数表内存布局画出来:Base{foo();int x} : Derived{bar();int y} 的对象长什么样? 答:对象首部 vptr → 指向 Derived 的 vtable(含 foo、bar);之后是 Base::x,再 Derived::y。vptr 在最前(主流实现),虚表指针解引用一次 + 跳转一次即动态绑定开销。
- 【秋招·主批】final 关键字两个作用? 答:①
virtual void f() final禁止子类重写;②class D final : B禁止被继承。编译器对 final 类可做去虚拟化(devirtualization)优化,去掉间接调用。
- 【秋招·主批】智能指针三重陷阱:循环引用怎么破?unique_ptr 所有权转移底层怎么实现? 答:循环引用用 weak_ptr(不增计数)打破;unique_ptr 通过删除拷贝构造 + 保留移动构造实现独占所有权,零运行时开销。
- 【秋招·主批】死锁四个必要条件?怎么预防? 答:互斥、占有且等待、不可剥夺、循环等待。预防:破坏任一条------按固定顺序加锁、一次申请全部资源、加锁超时回退、用 std::lock 同时锁多个。
- 【秋招·主批】互斥锁、自旋锁、读写锁、条件变量各自适用场景? 答:互斥锁(临界区短、会睡眠);自旋锁(临界区极短、多核、不睡眠忙等);读写锁(读多写少);条件变量(等待某个条件成立,配 mutex 用)。volatile 不能替代原子操作(不保证原子性、不防重排)。
③ 高难层
- 【提前批·高难】设计一个简易日志库 / 定时器 / 限流器(选一)。 答:限流器用令牌桶------定时 refill 令牌到桶、请求来取令牌、空则拒绝;线程安全用原子或锁。考察:定时精度、并发安全、突发流量处理。
- 【提前批·高难】内存屏障(memory barrier)是什么?为什么需要? 答:编译器和 CPU 会重排指令,内存屏障阻止特定方向重排,保证可见性顺序。双检锁旧写法漏 barrier 会拿到未构造完的对象,所以用 magic static / atomic 替代。
- 【秋招·主批】手写 vector 简易版(含扩容、拷贝、移动)。 答:考察三/五法则:析构释放、拷贝构造深拷贝、拷贝赋值(先释放再拷)、移动构造/赋值(偷指针+置空源)。很多人只写对扩容,漏移动语义。
- 【秋招·主批】select/poll/epoll 区别?为什么 epoll 高并发下更快? 答:select/poll 每次要把全量 fd 拷进内核 + 遍历 O(n);epoll 用内核红黑树管理 fd、就绪队列只返回就绪的 O(1) 取值。fd 上万时差距巨大。
- 【提前批·高难】常见的设计模式(单例、工厂、观察者)在你们项目怎么用的? 答:腾讯重「真实落地」,背定义没用,要能说清「为什么用、解决了什么耦合/扩展问题、有没有过度设计」。
五、阿里巴巴(难度 ★★★★,重 JVM 之外的 C++ 基础 + 系统设计)|对应上篇第五章
**风格:**阿里 C++ 岗(如钉钉、淘天、云智能基础软件)偏「基础 + 系统设计 + 业务场景」。一面基础扎实,二面开始怼项目架构和扩展性,对 STL 源码、并发、网络要求不比腾讯低,但手撕强度略低于字节。
① 基础层
- 【四季通用·基础】引用和指针的区别?(已对比,阿里常让你当面说全) 答:指针是变量存地址、可为空可重指向有自身地址;引用是别名、必须初始化、不可重绑定、无独立地址。传参想避免拷贝且允许空用指针,必非空用引用。
- 【秋招·主批】const 成员函数(void f() const)有什么用? 答:承诺不修改对象成员变量(mutable 除外);const 对象只能调 const 成员函数;是接口契约,也利于编译器优化和线程安全推理。
- 【春招·实习】函数重载和重写的区别? 答:重载(overload)同作用域、同名不同参(编译期决议);重写(override)子类覆盖基类虚函数(运行期多态)。override 关键字让编译器帮你检查是否真的重写了。
- 【秋招·主批】什么是 RAII?举一个项目里用的例子。 答:Resource Acquisition Is Initialization------把资源(内存/锁/文件句柄)生命周期绑到对象上,构造获取、析构释放,借助栈展开自动回收,杜绝泄漏。例子:用 unique_ptr 管理 new 的对象、用 lock_guard 管理互斥锁。
② 进阶层
- 【秋招·主批】unordered_map 哈希冲突怎么处理?最坏情况是什么? 答:主流用链地址法(桶+链表/红黑树,元素多转树)。最坏:所有 key 哈希到同一桶 → 退化为 O(n);攻击者构造哈希碰撞可造成 DoS。所以 key 设计要散列均匀,避免用易被碰撞的类型。
- 【秋招·主批】什么是移动语义?为什么它能提升性能? 答:移动构造/赋值「偷」临时对象的资源(指针)而非深拷贝,把源置空。对大对象(大 vector、string)避免 O(n) 拷贝,从 O(n) 降到 O(1)。配合 std::move 把左值当右值用。
- 【秋招·主批】C++11/14/17/20 你最常用哪些新特性? 答:11(auto/lambda/智能指针/右值引用/thread)、14(泛型 lambda)、17(structured binding / std::optional / if constexpr)、20(concepts / 协程 / 模块)。面试挑 2~3 个讲清解决的问题即可,别列清单。
- 【秋招·主批】什么是内存泄漏?C++ 里怎么系统化避免? 答:分配的内存不再被引用却没释放。避免:优先智能指针(RAII)、配 ASan/Valgrind 检测、避免裸指针所有权不清、循环引用用 weak_ptr。
③ 高难层
- 【提前批·高难】设计一个高并发计数器 / 限流中间件(阿里爱问设计)。 答:单机可用原子变量;分布式要一致性(Redis incr + 过期、或令牌桶+时钟同步)。考察:并发安全、精度、单机 vs 分布式的边界。
- 【提前批·高难】std::atomic 能保证什么?memory_order 有哪几种? 答:保证对该变量的操作原子性(不会被打断)。memory_order 有 relaxed(只原子不排序)、acquire/release(同步读写顺序)、seq_cst(默认全序最安全但最慢)。无锁编程里用对 order 是关键。
- 【秋招·主批】手撕:合并两个有序链表 / 反转链表(白板)。 答:阿里手撕偏中等,链表题必会;反转链表用三指针(prev/cur/next),合并用哑节点+双指针。要求边界(空链表、单节点)正确。
- 【秋招·主批】你的项目里怎么处理高并发下的数据共享? 答:无锁(原子)还是锁(互斥/读写锁)?为什么?有没有 false sharing(伪共享)问题?阿里重「你真懂还是背的」。
六、美团(难度 ★★★☆,偏业务落地 + 工程细节)|对应上篇第六章
**风格:**美团到店/外卖/配送的后台 C++ 岗,重「工程能力 + 业务场景 + 基础」。手撕中等偏上,对 STL、网络、数据库结合问得多,喜欢「给你个业务场景怎么设计」。
① 基础层
- 【四季通用·基础】sizeof 和 strlen 区别? 答:sizeof 是编译期运算符,算类型/对象占用字节(含 '\0');strlen 是库函数,运行时数到 '\0' 止(不含)。数组退化成指针后 sizeof 退化成指针大小------经典坑。
- 【春招·实习】数组名和指针区别? 答:数组名是「指向首元素的常量指针」,sizeof(数组名) 是数组总大小;作为参数退化成指针后 sizeof 变 8。数组不可整体赋值/重指向。
- 【秋招·主批】宏定义和 inline 函数区别? 答:宏是文本替换(无类型检查、易出错、无作用域);inline 是函数(有类型检查、可调试),只是建议编译器展开,是否展开由编译器决定。
② 进阶层
- 【秋招·主批】vector 和 list 区别?(已对比)什么场景用 deque? 答:vector 连续、头插 O(n);list 链表、头尾插 O(1) 但访问 O(n)。deque 双端队列,头尾插删都 O(1) 且随机访问 O(1),底层是分块数组,适合队列/栈且要随机访问。
- 【秋招·主批】遍历容器时正确删除元素怎么写? 答:用 erase 返回的下一迭代器:
it = v.erase(it);而非v.erase(it); it++;(后者在失效后自增是 UB)。关联容器同理用返回值。
- 【秋招·主批】进程间通信有哪些方式? 答:管道(匿名/命名)、消息队列、共享内存(最快,需配信号量同步)、信号、socket。本文补共享内存/信号量。
- 【秋招·主批】TCP 拥塞控制知道吗(慢启动/拥塞避免/快重传)? 答:慢启动指数涨 cwnd 到阈值;拥塞避免线性涨;丢包触发快重传/快恢复或超时退慢启动。美团网络问得比纯后台厂浅但基础要会。
③ 高难层
- 【提前批·高难】设计一个短链系统 / 外卖配送路径缓存(业务场景题)。 答:短链=发号器(雪花算法)+ 映射存储(Redis);缓存=缓存穿透/击穿/雪崩怎么防(布隆过滤器/互斥锁/随机过期)。美团爱把基础包装成业务题。
- 【秋招·主批】手撕:二叉树层序遍历 / 最近公共祖先(LCA)。 答:层序用队列;LCA 二叉搜索树可借大小关系,普通树用后序+哈希父节点或倍增。要求递归/迭代都讲清。
- 【秋招·主批】MySQL 索引为什么用 B+ 树?和红黑树/哈希对比? 答:B+ 树矮胖、磁盘友好(一次 IO 读一页)、叶子链表支持范围查询;红黑树高、IO 多;哈希不支持范围。
七、百度(难度 ★★★,重算法 + 搜索/基础架构)|对应上篇第七章
**风格:**百度 C++ 岗(搜索、凤巢、基础架构)算法占比高、对数据结构与 STL 要求扎实,底层追问比腾讯温和但广度不低,春招实习相对友好。
① 基础层
- 【四季通用·基础】指针数组和数组指针区别? 答:int* p10 是「指针数组」(10 个 int*);int (*p)10 是「数组指针」(指向含 10 个 int 的数组)。结合优先级和结合性讲清。
- 【春招·实习】什么是野指针?怎么避免? 答:指向已释放/未初始化/越界内存的指针。避免:释放后置 NULL、初始化即赋、不用返回局部变量地址、用智能指针。
- 【秋招·主批】struct 内存大小怎么算(含对齐与位域)? 答:按成员对齐(自身大小对齐到 min(自身,pack))、整体是最大成员对齐倍数;位域可压缩但跨平台布局不定,慎用于网络协议。
② 进阶层
- 【秋招·主批】哈希表(unordered_map)和红黑树(map)在百度搜索场景怎么选? 答:要 O(1) 查找、不要求有序用哈希;要有序遍历/范围查询/稳定最坏用红黑树。百度索引/词典场景两者都见。
- 【秋招·主批】什么是迭代器失效?vector/map 各举一个例子。 答:vector insert/erase 搬移导致迭代器/引用/指针失效;map 增删节点不影响其他迭代器(节点独立),但 erase 当前迭代器会失效需用返回值。
- 【秋招·主批】C++ 的拷贝优化(RVO/NRVO)是什么? 答:返回值优化------编译器直接在调用方内存构造返回对象,省一次拷贝/移动。C++17 强制 RVO;别为了「优化」写成 std::move 返回局部变量,反而可能抑制 NRVO。
③ 高难层
- 【提前批·高难】海量日志里找出现频率最高的 TopK 个 URL(百度经典)。 答:单机内存不够 → 哈希分片(按 URL hash 落不同文件)→ 每片用哈希表统计频次求 TopK → 多路归并。或单机用堆。
- 【秋招·主批】手写快排 / 堆排,并分析稳定性与复杂度。 答:快排平均 O(n log n) 不稳定、最坏 O(n²);堆排 O(n log n) 不稳定、原地。百度手撕常让你当场写并解释边界。
- 【秋招·主批】手撕:无重复字符的最长子串 / 三数之和。 答:滑窗(哈希记录字符最后位置)O(n);三数之和排序+双指针 O(n²)。要讲清去重逻辑。
八、华为 / 华为 OD(难度 ★★☆,重基础广度 + 机试)|对应上篇第八章
**风格:**华为正式批偏「基础全面 + 手撕机试(多为 LeetCode 简单~中等)」,对双非相对友好;华为 OD(外包转全)机试占比大(3 道编程题),面试问得比一线大厂浅,但范围广、不深挖。注意华为 OD 简历筛选和机试分数线是硬门槛。
① 基础层
- 【四季通用·基础】C++ 三大特性是什么? 答:封装(数据+行为绑定、隐藏实现)、继承(代码复用+层次)、多态(同一接口不同实现,靠虚函数运行期绑定)。
- 【春招·实习】new/delete 和 malloc/free 区别?(华为必问基础) 答:见腾讯章,核心:new 调构造/抛异常/可重载,malloc 仅分配/返 NULL/返 void*。
- 【秋招·主批】引用和指针区别?(华为基础题高频) 答:见跨文章对比表,必须能完整说。
- 【四季通用·基础】纯虚函数和虚函数区别? 答:纯虚函数
virtual f()=0无实现、含它的类叫抽象类不能实例化,用于定义接口;虚函数有默认实现、子类可选覆盖。
② 进阶层
- 【秋招·主批】多态怎么实现(底层)? 答:虚函数表 vtable + 虚指针 vptr,运行期查表调用。
- 【秋招·主批】shared_ptr 和 unique_ptr 怎么选? 答:独占用 unique_ptr(零开销、不可拷可移);共享用 shared_ptr(引用计数);循环引用用 weak_ptr 打破。华为问「为什么不用裸指针」------答案就是 RAII 防泄漏。
- 【秋招·主批】vector 和 list 区别?(华为常考容器对比) 答:见对比表,重点讲复杂度与适用场景。
- 【四季通用】const 的常见用法? 答:常量变量、函数参数(防改)、成员函数(const 承诺)、常量指针/指针常量(const int* vs int* const)。
③ 高难层(华为偏少,OD 机试为主)
- 【待验证】OD 机试常见题型:字符串处理、哈希计数、模拟、DFS/BFS 简单图。 答:刷 LeetCode 热题 100 简单~中等足够;重点练「读题快、边界全、不超时」。华为 OD 更看重机试分数而非深挖。
- 【秋招·主批】怎么避免内存泄漏? 答:智能指针 + 配对 new/delete + 工具检测(Valgrind/ASan)。
九、京东(难度 ★★★,偏后台业务 + 基础)|对应上篇第九章
**风格:**京东零售/物流后台 C++ 岗,基础和字节类似但手撕难度略低,重视 STL、网络、数据库结合业务,对「工程规范、代码可读性」有要求。
① 基础层
- 【春招·实习】extern "C" 是干什么的? 答:让 C++ 编译器按 C 的命名规则(不做 name mangling)编译函数,使 C++ 能调用 C 写的库。常用于封装 C 库的头文件。
- 【四季通用·基础】头文件为什么要加 include guard / #pragma once? 答:防止同一头文件被重复包含导致重定义。#pragma once 是编译器扩展(快、不易错),include guard 标准可移植。
- 【秋招·主批】左值、右值、左值引用、右值引用? 答:左值有名字有地址(可取 &);右值是临时对象/字面量(即将销毁)。左值引用 & 绑左值;右值引用 && 绑右值,是移动语义基础。
② 进阶层
- 【秋招·主批】string 的 SSO(短字符串优化)是什么? 答:短字符串(通常 <=15 字节)直接存在 string 对象内部的小缓冲区,不堆分配,省一次 new/delete、对缓存友好;超过才堆分配。考察你对「看似简单类型」的底层了解。
- 【秋招·主批】map 和 unordered_map 区别?(已对比) 答:见对比表,京东常让你现场选容器并说理由。
- 【秋招·主批】什么是缓存一致性?MESI 了解吗? 答:多核各自有缓存,需协议保证看到一致数据;MESI 用 Modified/Exclusive/Shared/Invalid 四状态跟踪缓存行。京东后台问得不算深但要懂概念。
③ 高难层
- 【提前批·高难】设计一个购物车/库存扣减的高并发方案。 答:扣减用 Redis + Lua 原子脚本防超卖;落库用事务/消息队列削峰;缓存与 DB 一致性(先更新 DB 再删缓存 + 延迟双删)。业务场景题。
- 【秋招·主批】手撕:环形链表检测 / 相交链表。 答:快慢指针(Floyd)判环;相交链表用双指针走两遍(长度差抵消)。要求讲清为什么有效。
- 【秋招·主批】手撕:实现 strStr / 最长回文子串。 答:KMP 或双指针;回文用中心扩展或 DP。京东手撕中等偏上。
十、网易(难度 ★★★,游戏/后台双线)|对应上篇第十章
**风格:**网易 C++ 岗分两路:游戏(雷火/互娱,重 C++ 底层、内存、渲染相关)和后台(严选/云音乐,偏网络/并发)。整体基础扎实 + 一定手撕,游戏线对 C++ 功力要求更高。
① 基础层
- 【春招·实习】什么是多态?编译期多态和运行期多态分别指什么? 答:编译期(模板、函数重载、operator 重载);运行期(虚函数,靠 vtable)。网易游戏线常追问两者性能差异。
- 【四季通用·基础】inline 函数会不会一定被展开? 答:不会,inline 只是「建议」,递归/虚函数/太大通常被忽略;且 inline 函数定义要放在头文件(否则链接找不到)。
- 【秋招·主批】什么是未定义行为(UB)?举三个例子。 答:同一表达式多次修改同一变量无序列点、数组越界、解引用空/野指针、有符号溢出。UB 是 C/C++ 最危险的坑,编译器可任意处理。
② 进阶层
- 【秋招·主批】虚继承解决什么问题?代价是什么? 答:解决菱形继承的二义性和数据冗余(虚基类只存一份)。代价:额外虚基类表指针、访问虚基类成员多一次间接寻址、构造顺序复杂。游戏引擎里用得多。
- 【秋招·主批】智能指针的引用计数线程安全怎么理解?(已讲,网易游戏线深挖) 答:计数增减原子安全;对象访问不安全,多线程读写同一对象仍要外部同步。
- 【秋招·主批】std::thread 和 pthread 区别?detach 和 join 区别? 答:std::thread 是 C++ 标准封装,跨平台;pthread 是 POSIX 库。join 等线程结束(可拿结果)、detach 分离后台跑(主线程不等,注意生命周期别悬空引用)。
③ 高难层
- 【提前批·高难】游戏里大量小对象(子弹/粒子)怎么管理内存? 答:对象池(object pool)------预分配一批复用,避免频繁 new/delete 造成碎片和卡顿;配合内存池/定制分配器。网易游戏线经典题。
- 【秋招·主批】手撕:实现一个定长内存池 / 简单的对象池。 答:用链表把空闲块串起来,分配取头、释放回头;固定大小块无碎片。考察对「为什么不能直接 new」的理解。
- 【秋招·主批】手撕:对称的二叉树 / 二叉树的镜像。 答:递归比较左右子树镜像;或层序。网易手撕偏树,要求递归清晰、边界正确。
十一、拼多多(难度 ★★★★,重算法 + 高并发 + 抗压)|对应上篇第十一章
**风格:**拼多多 C++ 岗(电商/支付/风控后台)以「算法硬 + 手撕多 + 问得深」著称,面试轮次多、节奏快,对 STL 底层、并发、海量数据题要求高,是除字节外手撕最狠的厂之一。
① 基础层
- 【四季通用·基础】侯捷说的「C++ 对象模型」你了解多少? 答:对象内存布局(vptr、数据成员顺序)、继承下的内存、多态的虚表机制------拼多多喜欢从这里挖。建议读《深度探索 C++ 对象模型》。
- 【秋招·主批】volatile 关键字到底保证什么、不保证什么? 答:只保证「不从寄存器读旧值、每次从内存取」,不保证原子性、不防重排。多线程同步别用它替代 mutex/atomic。
- 【春招·实习】什么是 trivial / non-trivial 类型? 答:没有用户定义构造/析构/拷贝/赋值的类型是 trivial,可安全 memcpy、利于优化和容器优化;反之 non-trivial 不能随便位拷贝。
② 进阶层
- 【秋招·主批】shared_ptr 的循环引用具体代码怎么写、怎么破?(已讲) 答:A 持 B 的 shared_ptr、B 持 A 的 shared_ptr → 计数永不为 0 → 泄漏;把其中一方改 weak_ptr 即可。拼多多会让你当场写这个坑。
- 【秋招·主批】vector 扩容时迭代器/指针/引用全失效,为什么? 答:重新分配内存、对象搬到新地址,旧指针指向已释放内存。所以扩容后别再用旧迭代器,重新获取。
- 【秋招·主批】epoll 为什么比 select 适合十万级连接?(已讲,拼多多高并发必问) 答:select 每次拷贝全量 fd + 遍历 O(n);epoll 内核红黑树管理、只返回就绪 O(1)。拼多多的海量连接场景直接考这个。
③ 高难层
- 【提前批·高难】10 亿整数找中位数(内存限制 1G)?海量数据去重? 答:中位数用「桶统计 + 二分值域」或外排序;去重用位图(bitmap,10 亿只需 ~125MB)或布隆过滤器(允许误判)。经典海量题。
- 【秋招·主批】手撕:接雨水 / 最大矩形(单调栈)?编辑距离(DP)? 答:拼多多手撕偏难,单调栈和 DP 是高频;要求 O(n) 解法且边界正确。
- 【秋招·主批】手撕:实现一个线程安全的阻塞队列。 答:mutex + condition_variable,push 时 notify,pop 时 wait 直到非空。考察并发基础是否真会写。
- 【提前批·高难】高并发下如何设计一个秒杀系统(拼多多核心业务)? 答:前端限流 + 库存预热到 Redis + Lua 原子扣减 + 消息队列异步落库 + 防超卖/防刷。把基础(锁/原子/缓存)串成系统。
十二、快手(难度 ★★★☆,短视频后台 + 算法)|对应上篇第十二章
**风格:**快手 C++ 岗(短视频/推荐/基础设施)基础和算法并重,手撕中等偏上,对网络、存储、分布式概念有要求,整体接近美团/百度的难度区间。
① 基础层
- 【四季通用·基础】前置 ++ 和后置 ++ 的区别(运算符重载角度)? 答:前置返回引用(自增后对象)、效率高;后置返回临时副本(先存旧值再增),多一次拷贝。重载时后置要多一个 int 哑参。
- 【春招·实习】this 指针是什么?为什么有时会为空也能调用成员函数? 答:this 指向调用对象;非虚、不访问成员变量的成员函数,即使 this 为空(如
((A*)0)->f())也可能不崩------但这是 UB,面试考你对「成员函数不自动解引用 this」的理解。
② 进阶层
- 【秋招·主批】模板特化和偏特化是什么? 答:全特化针对特定类型完全重写;偏特化针对一类类型(如指针、引用)。STL 大量用特化优化,如
vector<bool>位压缩。
- 【秋招·主批】完美转发(forward)为什么需要引用折叠? 答:模板参数 T&& 在传入左值时折叠成左值引用、右值时折叠成右值引用,forward 据此「原样」转发,保留值类别。是写泛型工厂/包装器的核心。
- 【秋招·主批】shared_ptr 的 enable_shared_from_this 是干嘛的? 答:在类内部想安全地返回自己的 shared_ptr 时用,避免从 this 另造一个控制块导致双释放。快手常考这个「坑中坑」。
③ 高难层
- 【提前批·高难】设计一个推荐系统的特征缓存层(快手业务)。 答:热点特征放本地缓存(LRU)+ 全量放 Redis;一致性用版本号/过期;考察缓存命中率与失效策略。
- 【秋招·主批】手撕:最长递增子序列(LIS)/ 编辑距离。 答:LIS 用贪心+二分 O(n log n);编辑距离 DP O(nm)。快手手撕偏 DP/贪心。
- 【秋招·主批】手撕:K 个一组翻转链表。 答:分段反转 + 连接,递归或迭代;考察指针操作熟练度与边界(最后一组不足 K)。
十三、小米(难度 ★★★,偏嵌入式/手机系统 + 后台)|对应上篇第十三章
**风格:**小米 C++ 岗分手机系统/嵌入式(MIUI、澎湃、IoT)和互联网后台两路。系统/嵌入式线重 C + 底层(内存、驱动、跨平台),后台线接近京东难度。整体比一线大厂温和,对双非友好度较高。
① 基础层
- 【春招·实习】C 和 C++ 在嵌入式里怎么选?extern "C" 在混合编程里干嘛?(已讲) 答:C 更贴近硬件、确定性好、无异常开销;C++ 提供抽象但要小心 RTOS 下异常/STL 的代价。extern "C" 让 C++ 调 C 库。
- 【四季通用·基础】大端小端是什么?怎么判断本机字节序? 答:多字节数据高位存低地址为小端(x86 默认)。判断:联合体存 1,看 char 字节是 1(小端)还是 0(大端)。网络传输统一大端,要注意转换(htons/htonl)。
② 进阶层
- 【秋招·主批】volatile 在嵌入式里的真实用途? 答:映射硬件寄存器、被中断/多线程改的全局变量,防止编译器优化掉「看似无用」的读。但注意仍不保证原子(已讲)。
- 【秋招·主批】malloc 在嵌入式里的问题?为什么常用内存池? 答:malloc 有碎片、不确定延迟、线程不安全(或小锁开销);实时系统用静态内存池/固定块分配器保证确定性。
③ 高难层
- 【待验证】小米系统线可能问:内存碎片怎么排查?栈溢出怎么防? 答:碎片用工具(dmalloc)/ 内存池规避;栈溢出用静态分析、限制递归深度、关键栈加大。属【待验证】,因嵌入式岗差异大,需结合具体部门。
- 【秋招·主批】手撕:二分查找(含边界变体)/ 两个有序数组的中位数。 答:二分边界(left/right 收口、mid 防溢出用 left+(right-left)/2)是小米常考基础。
十四、滴滴(难度 ★★★☆,出行后台 + 算法 + 地图)|对应上篇第十四章
**风格:**滴滴 C++ 岗(出行/地图/调度后台)基础和算法并重,地图/空间相关题有特色,对 STL、网络、并发要求扎实,难度介于美团和字节之间。
① 基础层
- 【四季通用·基础】constexpr 和 const 在编译期的区别?(已讲) 答:constexpr 强制编译期可求值,可用于数组大小、模板非类型参数、编译期计算(如编译期算斐波那契)。
- 【春招·实习】什么是命名空间(namespace)?using namespace std 为什么不推荐写在头文件? 答:避免命名冲突;头文件里 using 会把 std 泄漏到所有包含它的文件,造成污染和冲突。只应在 .cpp 局部或显式用 std::。
② 进阶层
- 【秋招·主批】unordered_map 的 reserve 有什么用?rehash 代价? 答:reserve 预分配桶数,避免插入时反复 rehash(重建哈希表、搬移所有元素,O(n) 且可能卡顿)。滴滴高并发插入场景会问。
- 【秋招·主批】条件变量为什么必须和互斥锁一起用、且用 while 而非 if 判断? 答:wait 内部释放锁→休眠→被唤醒重新加锁;用 while 防「虚假唤醒」(多个 waiter 被同时唤醒、资源已被别人取走)。滴滴并发必考。
③ 高难层
- 【提前批·高难】设计一个司机就近派单的匹配模块(滴滴业务)。 答:用地理网格/GeoHash 分桶 + 优先队列按距离/评分排序;实时性用内存索引而非全表扫。把空间索引 + 数据结构串起来。
- 【秋招·主批】手撕:滑动窗口最大值(单调队列)/ 柱状图最大矩形(单调栈)。 答:滴滴手撕偏单调栈/队列这种「有技巧」的题,要求 O(n)。
- 【秋招·主批】手撕:岛屿数量(DFS/BFS)/ 朋友圈(并查集)。 答:并查集(路径压缩+按秩合并)是滴滴地图/连通性题的常客。
十五、各大厂面试特点横向对比|对应上篇第十五章
|-------|------|---------|----------------------------|----------|----------|
| 大厂 | 整体难度 | 风格标签 | 偏爱考点 | 手撕强度 | 对双非态度 |
| 字节跳动 | ★★★☆ | 算法为王 | 算法+STL+OS+网络,白板写对 | 极高 | 较友好(看能力) |
| 腾讯 | ★★★★ | 底层深挖 | 对象模型/虚表、内存布局、epoll、死锁 | 高 | 偏重基础深度 |
| 阿里巴巴 | ★★★★ | 基础+设计 | STL 源码、并发、系统设计、业务场景 | 中高 | 看项目落地 |
| 美团 | ★★★☆ | 业务落地 | STL、网络、MySQL、业务场景设计 | 中 | 中等友好 |
| 百度 | ★★★ | 算法+广度 | 数据结构、STL、海量数据题 | 高 | 较友好 |
| 华为/OD | ★★☆ | 基础+机试 | 三大特性、基础容器、机试编程 | 中(OD 机试) | 双非最友好 |
| 京东 | ★★★ | 后台业务 | STL、网络、高并发业务设计 | 中 | 中等 |
| 网易 | ★★★ | 游戏/后台双线 | 虚继承、对象池、内存管理 | 中 | 中等 |
| 拼多多 | ★★★★ | 算法+高并发 | 海量数据、并发、STL 底层、秒杀 | 极高 | 看硬实力 |
| 快手 | ★★★☆ | 算法+存储 | DP/单调栈、模板、shared_from_this | 中高 | 中等 |
| 小米 | ★★★ | 嵌入式/后台 | C 底层、字节序、内存池 | 中 | 双非友好 |
| 滴滴 | ★★★☆ | 出行+地图 | 单调栈/队列、并查集、并发 | 中高 | 中等 |
15.1 横向规律(值得记住的 5 条)
- **底层是分水岭:**腾讯/拼多多/阿里把「虚表布局、智能指针计数、vector 扩容、epoll」挖到实现级,只会背定义一定被挂;字节/百度更看「写对 + 讲清复杂度」。
- **手撕是硬门槛:**字节、拼多多手撕最狠(中等偏难、当场写对);腾讯/阿里手撕中等但会让你「边写边讲为什么」;华为 OD 机试是分数门槛。
- **季节差异真实存在:**提前批(7--8 月)最难、常考设计/源码;秋招主批(8--11 月)题量最大、底层追问最多;春招/实习(3--5 月)偏基础+项目+中等手撕,是双非性价比最高的窗口。
- **STL 底层是共同高频:**十二家里十一家都问 vector/map/unordered_map 的底层与复杂度,这是性价比最高的复习板块。
- **双非突围靠「深度+项目」:**华为/小米/美团/百度对双非相对友好,但都需要你能把某一块讲到比科班生深、且项目能经得起追问。
十六、在校生与应届生分阶段备考路线|对应上篇第十六章
无论你是刚入门的大一大二在校生,还是即将秋招的应届生,时间窗口都还在。按「先夯实、再深挖、后冲刺」三阶段排:
16.1 大一/大二上:把基础焊死(现在--明年)
- **啃透 C++ 对象模型与 STL 源码:**读《C++ Primer》打底,再读《STL 源码剖析》把 vector/map/unordered_map 底层画出来。
- **数据结构与算法刷穿:**LeetCode 热题 100 + 剑指 Offer,链表/树/DP/二分/滑窗/单调栈是面试重灾区,白板写对是底线。
16.2 大二下/大三:冲底层 + 做项目
- 操作系统与网络系统学:《操作系统概念》《TCP/IP 详解》,把本文的 epoll/死锁/TCP 从「会答」练到「能画图讲」。这部分恰恰是拉开差距的关键。
- **做一个能讲深的项目:**推荐自研「轻量线程池 / 网络库 / 简易 Redis」,把 RAII、智能指针、epoll、锁都用上,面试时经得起追问。
- **开始投实习:**大二下暑期争取小厂/中厂实习,大三上冲大厂暑期实习(春招窗口,难度低于秋招)。
16.3 大三下/大四:秋招冲刺
- **按厂刷面经:**提前批冲字节/拼多多(拼算法),秋招主批广投腾讯/阿里/美团/百度,华为 OD/小米作为保底双非友好项。
- **把本文当靶心:**每张表、每个易混点都能闭眼答 + 画图,手撕题限时写对。本文覆盖的十二家考点就是你的复习地图。
- **诚实定位:**双非不是死局,但「只背八股、项目水」一定挂;把某一两块讲到比科班深,比泛泛铺广度有用。
十七、结语
上篇给题目、本篇给答案,两篇合起来就是一套完整的大厂 C/C++ 面试题复习地图:先看上篇的题目清单摸清范围,再回本篇逐题啃答案。每道题都给了要点和追问角度,但看答案 ≠ 会答:面试要你白板写、口头讲,所以建议每题先自己作答再对照答案补漏,重点题练到能脱稿讲清。具体题→季节的精确对应无法逐条溯源,凡我推断处都打了【待验证】,请结合你刷到的实时面经自行核对;面经有幸存者偏差,最终还是要回到系统啃书 + 白板写对。
如果觉得有用,点赞收藏走一波。哪道题的答案讲得不够透、或想让我单独深拆某一道(比如虚表布局、STL 底层源码),评论区点名,我单独出深度篇。
