C++ 面试越来越爱问什么:八股文背完了,为什么还是过不了
这两年看 C++ 面试题,有个很明显的变化:面试官还是会问基础,但已经不太满足于你把“定义”背出来。以前很多同学准备 C++,重点放在语法点、STL、几道经典手撕题上,确实能应付一部分岗位。现在不一样,尤其是后台、客户端、基础架构、自动驾驶、游戏引擎、嵌入式 Linux、量化开发这些方向,面试官更喜欢从一个基础点一路追到语言机制、工程实践和性能取舍。
也就是说,C++ 八股文还得会,但只会八股远远不够。真正拉开差距的,是你能不能把“语言特性为什么这样设计”“在项目里为什么这么用”“这样写的代价是什么”讲明白。
一、现在 C++ 面试的重心到底变了什么
先说结论:C++ 面试不是不问基础了,而是基础问得更深、更偏工程化了。
过去常见的是:
new和malloc的区别- 虚函数是什么
- 智能指针有哪些
- vector 和 list 的区别
- 左值右值是什么
现在更常见的是:
new背后除了分配内存还做了什么,operator new和 placement new 分别解决什么问题- 虚函数表为什么能支持动态绑定,析构函数为什么经常要求写成虚函数
shared_ptr为什么可能有循环引用,原子引用计数带来什么性能代价vector为什么扩容通常更快但仍然可能踩迭代器失效- 移动语义到底减少了什么成本,什么场景下 move 了也不一定快
本质上就是一句话:从“会不会”变成“懂不懂”。
核心大厂开发面试题以及基础八股文资料汇总:
https://www.nowcoder.com/creation/manager/columnDetail/Mq7XWW
二、C++ 面试里最容易被追问的 8 条主线
1. 对象模型
这是很多人最容易学得零散的一块。平时写类会写,但一到面试就容易只停留在表面。
现在高频会被问到的内容包括:
- 类对象在内存里大致长什么样
- 成员变量、静态成员、虚函数表指针分别在什么位置
- 继承之后对象布局可能怎么变化
- 多态调用为什么能在运行时决定调用哪个函数
- 构造函数里调虚函数为什么不可靠
- 析构顺序为什么必须清楚
这部分如果只会说“虚函数实现多态”,基本不够。面试官想听的是你知不知道背后的对象模型。
2. 拷贝控制与资源管理
这条线属于经典中的经典,而且特别容易和项目挂钩。
高频点包括:
- 拷贝构造、拷贝赋值、移动构造、移动赋值、析构函数
- 三法则、五法则、零法则
- RAII 的核心思想
- 为什么资源类通常要禁拷贝或显式定义拷贝行为
- 什么叫深拷贝,什么叫浅拷贝
- 自定义类里什么时候必须自己写析构
很多人八股能背全,但一让你写一个管理堆内存、文件句柄、锁资源的类,马上就乱。因为这部分本质上不是语法题,是“资源生命周期管理能力”。
3. 智能指针
这个点几乎必问,而且问法越来越细。
常见问题有:
unique_ptr、shared_ptr、weak_ptr的区别shared_ptr引用计数放哪make_shared为什么通常优于直接new- 循环引用为什么会泄漏
- 多线程下
shared_ptr的线程安全边界在哪里 - 智能指针是不是一定比裸指针好
真正答得好的关键不是背定义,而是你能不能说明:什么时候该独占,什么时候该共享,什么时候只观察不拥有。
4. STL 容器与迭代器失效
这个模块几乎是每个方向都能问到的。
高频题包括:
vector、list、deque、map、unordered_map的底层结构- 插入删除复杂度为什么不同
map为什么是有序的,unordered_map为什么查找快但不稳定- 哈希冲突怎么处理
vector扩容会发生什么- 哪些操作会导致迭代器失效
这里最容易掉坑的是“背表格式回答”。面试官追问下去时,往往会变成:
- 为什么你的项目里选
unordered_map而不是map - 高频插入删除为什么不直接上
list vector连续内存带来了什么缓存优势- 红黑树为什么适合做
map
这时候只会结论不够,得能讲原因。
5. 模板与泛型编程
这部分在中高级岗位和高性能岗位里特别容易被问。
高频点包括:
- 函数模板和类模板
- 模板特化、偏特化
- 模板实例化时机
typename和class在模板参数里的区别auto、decltype、decltype(auto)- 完美转发和
std::forward - SFINAE、concept 的基本作用
这里很多人会卡在一个问题上:平时能用,但说不清模板为什么这么写。尤其是现代 C++ 里,模板已经不只是“泛型写法”,而是整个库设计的核心基础。
6. 右值引用、移动语义、完美转发
这是现代 C++ 面试里几乎绕不过去的一块。
常问的有:
- 左值、右值、将亡值到底怎么区分
- 右值引用为什么能优化性能
- 被
std::move之后对象还能不能用 - 为什么“有名字的右值引用”本身是左值
- 模板里的万能引用是什么
std::forward为什么不能乱用
这部分最容易出的问题是:概念懂一点,但放到代码里判断表达式类型就开始混乱。准备时一定要把“语法名词”和“对象生命周期”“资源转移”联系起来看。
7. 多线程与并发
只要岗位不是特别初级,这块基本都会摸一下。
常见问题包括:
- 线程和进程的区别
- 互斥锁、自旋锁、读写锁适用场景
- 条件变量怎么避免假唤醒
- 原子操作和锁的区别
- 内存序到底在解决什么问题
- 死锁的必要条件是什么
- 单例在多线程下怎么安全初始化
如果岗位偏后台、基础架构、音视频、交易系统,这块追问会更深。问到最后通常会落到“你项目里到底怎么保证线程安全”。
8. 编译链接与二进制层面
这是近两年非常容易被忽略,但面试里又很有区分度的一条线。
高频点包括:
- 编译、汇编、链接分别做什么
- 头文件为什么容易导致编译膨胀
inline真正解决了什么问题- 静态库和动态库区别
- 动态链接为什么节省空间
- 符号重定义为什么会报错
- 虚表、RTTI、异常处理大致带来哪些额外开销
这类问题特别适合区分“写过 C++”和“理解 C++ 工程体系”的人。
三、现在更像“热点”的 C++ 面试题方向
如果说哪些内容最近更值得重点准备,我会把下面这几类放在前面。
1. 现代 C++ 特性落地
很多岗位越来越希望你不是只会老 C++98 风格,而是知道现代 C++ 怎么提升可维护性和安全性,比如:
autonullptr- 范围 for
- 智能指针
- 右值引用
emplace_backconstexproptionalvariantstring_viewspanlambda
面试官不一定每个都问,但很喜欢从项目里问:你们有没有用现代 C++,为什么用,收益是什么,踩过什么坑。
2. 性能与内存
现在很多 C++ 岗位,尤其是偏底层、偏高性能的,都不满足于你“功能写对”,而是会问:
- 为什么这里会有拷贝
- 为什么这里堆分配太多
- 为什么这个容器不合适
- 为什么缓存命中率会影响性能
- 为什么对象池能减轻分配压力
- 为什么小对象频繁申请释放会抖动
一句话,C++ 的强项之一是性能可控,所以面试官会默认你该对性能有感觉。
3. 工程与设计能力
纯八股之外,现在越来越常见的问法是:
- 你怎么设计一个线程池
- 你怎么设计一个 LRU Cache
- 你怎么设计一个日志模块
- 你怎么设计一个观察者模式在项目里的落地
- 你怎么拆模块边界,避免头文件相互包含
也就是说,面试不再只是“这题你会不会”,而是“这能力你有没有”。
四、C++ 面试八股里最值得反复刷的 25 个题目
下面这 25 个题目,基本可以当成一轮高频自测清单。
new/delete和malloc/free的区别是什么?- 拷贝构造函数和拷贝赋值运算符的区别是什么?
- 什么情况下编译器会自动生成移动构造和移动赋值?
- RAII 的核心思想是什么,为什么它在 C++ 里特别重要?
unique_ptr、shared_ptr、weak_ptr分别适合什么场景?make_shared和直接new后交给shared_ptr有什么区别?- 虚函数表是怎么支持多态的?
- 构造函数和析构函数里调用虚函数会有什么问题?
vector扩容时会发生什么,为什么可能导致迭代器失效?map和unordered_map的底层结构和适用场景分别是什么?- 左值、右值、右值引用、万能引用分别怎么理解?
std::move和std::forward的作用分别是什么?- 为什么“有名字的右值引用”是左值?
- 模板特化和偏特化的区别是什么?
auto、decltype、decltype(auto)分别适合什么场景?- 线程安全和可重入的区别是什么?
- 互斥锁、自旋锁、读写锁分别适合什么场景?
- 条件变量为什么要和 while 一起使用,而不是 if?
- 原子操作是否可以完全替代互斥锁?
- 编译、链接、装载三个阶段分别做了什么?
- 静态库和动态库的区别是什么?
inline的作用到底是什么?- C++ 异常机制带来了哪些好处和代价?
- 为什么高性能项目里经常强调减少堆分配?
- 如果让你设计一个资源管理类,你会优先考虑哪些拷贝与析构问题?
这 25 题的价值不只是“会答”,而是它们能把 C++ 面试的主要知识树串起来。
五、为什么很多人八股背了,面试还是挂
这个问题其实挺常见。原因通常不是“不努力”,而是准备方式不对。
1. 只记结论,不懂推导
比如记住了:
vector插入删除慢list插入删除快unordered_map查找快
但一问为什么,就答不出来。
这类回答很容易在第二轮追问里崩掉。
2. 只会单点,不会串线
C++ 面试越来越喜欢串起来问。比如从右值引用问到移动构造,再问到 vector 扩容,再问到为什么 emplace 更合适,再问到项目里是否做过性能优化。
如果知识点是散的,就很容易中途断掉。
3. 项目说不出语言细节
很多人项目经历看着不错,但一追问代码层面:
- 为什么这里用
shared_ptr - 为什么这里不直接用对象
- 为什么这里不用引用返回
- 为什么这里需要虚函数
- 这里有没有拷贝成本
答不出来。那面试官就会判断:项目写过,但没有真正从 C++ 语言层面思考过。
六、准备 C++ 面试,建议按这 5 条线复习
如果最近正在准备 C++ 岗位,复习顺序可以按这几条走。
1. 语言基础线
包括:
- 指针、引用、const
- 类与对象
- 继承、多态
- 拷贝控制
- 虚函数
- 生命周期
这一层是地基。
2. 现代 C++ 线
包括:
- 智能指针
- 右值引用
- 移动语义
- 完美转发
- lambda
auto/decltypeoptional/string_view
这一层决定你是不是“现代 C++ 风格”。
3. STL 与模板线
包括:
- 常见容器
- 迭代器
- 算法
- 模板
- 特化
- 泛型思维
这一层会直接影响你写业务代码和手撕代码的质量。
4. 并发与性能线
包括:
- 线程同步
- 原子操作
- 死锁
- 锁设计
- 内存分配
- 对象生命周期
- 性能瓶颈判断
这一层决定你能不能胜任更高要求的岗位。
5. 工程与项目线
包括:
- 编译链接
- 库设计
- 模块拆分
- 日志系统
- 配置系统
- 缓存
- 项目中的性能优化案例
这一层最能拉开差距。
七、结尾
C++ 面试的难点,从来都不是知识点多,而是知识点之间连得太紧。你以为在准备语法,最后会问到对象模型;你以为在准备容器,最后会问到缓存和性能;你以为在准备智能指针,最后会问到资源所有权设计。
所以准备 C++,别只把自己训练成“背题机器”。真正有用的方式,是把每个高频题都往下多问两层:
- 它为什么这样设计?
- 这样做解决了什么问题?
- 这样做带来了什么代价?
- 在项目里我什么时候真的会这么用?
把这几层想明白,C++ 面试里的大多数题,味道就开始不一样了。