C++ 常考面试题总结(附复习思路)

前言

C++ 这门语言,在开发岗位里一直都挺特殊的。

一方面,它历史足够久,语法特性很多,往深了问几乎问不完;另一方面,它又一直活跃在高性能开发的一线,不管是后端、客户端、音视频、游戏、基础架构,还是嵌入式方向,很多岗位都会明确要求有 C++ 基础。

所以面试里,C++ 基本属于绕不过去的一块。

而且 C++ 面试有个很明显的特点:不太容易只停留在表面。很多问题看起来像基础题,但只要面试官愿意追问,很快就会从语法问到原理,从原理问到工程实践。

比如:

  • 为什么基类析构函数通常要写成虚函数?
  • vectorlist 到底怎么选?
  • shared_ptr 为什么会有循环引用问题?
  • 右值引用到底解决了什么问题?
  • 多线程里加了锁,为什么性能还是可能很差?

这些问题如果只是背过概念,往往不太够。真正到面试里,还是得看能不能把东西讲明白。

这篇文章就简单整理一版 C++ 面试里比较常见的 20 个问题,只列问题,适合面试前过一遍。后面再补一下我比较建议的准备思路,方便复习的时候抓重点。

一、C++ 常见面试题

基础语法

  1. C++ 里指针和引用有什么区别?
  2. const 在 C++ 中有哪些常见用法?
  3. static 关键字在不同场景下分别有什么作用?
  4. #defineconstinline 之间有什么区别?
  5. 函数重载、重写、隐藏分别是什么意思?

类与对象

  1. classstruct 在 C++ 里的区别是什么?
  2. 什么是封装、继承、多态?C++ 是怎么支持多态的?
  3. 什么是虚函数、纯虚函数、虚析构函数?
  4. 构造函数、析构函数、拷贝构造函数、移动构造函数分别在什么情况下调用?
  5. C++ 对象模型里,虚函数表是怎么工作的?

内存管理

  1. 栈上对象和堆上对象有什么区别?
  2. new/deletemalloc/free 有什么区别?
  3. 什么是内存泄漏?常见原因有哪些?怎么排查?
  4. 什么是 RAII?为什么 C++ 很强调这个思想?
  5. unique_ptrshared_ptrweak_ptr 的区别和使用场景是什么?

现代 C++ / STL / 并发

  1. 什么是左值、右值、右值引用?移动语义解决了什么问题?
  2. std::movestd::forward 的区别是什么?
  3. 模板的本质是什么?模板实例化发生在什么时候?
  4. vectorlistdequemapunordered_map 这些常用容器怎么选?
  5. C++ 多线程里常见的同步方式有哪些?互斥锁、条件变量、原子变量分别适合什么场景?

如果你也面试C++不妨看看我的专栏: C++常考面试题总结

二、C++ 面试前怎么准备会更有效

很多人准备 C++ 面试的时候,容易一上来就开始背题。但说实话,C++ 的点太碎了,单纯按题目去背,背到后面很容易乱。

我自己的建议是,最好按模块去准备。

1. 先把主干知识捋顺

C++ 面试里高频的内容,大致就这几块:

  • 基础语法
  • 类和对象
  • 内存管理
  • STL 容器
  • 智能指针
  • 模板
  • C++11 之后的新特性
  • 多线程和并发

先把这些主干内容分清楚,再去看具体问题,会轻松很多。

比如在看智能指针的时候,就可以顺便把 RAII、资源管理、析构函数、异常安全这些内容一起串起来。看多态的时候,也可以顺带把虚函数表、虚析构、对象模型这些内容一起补上。

这样复习怎么也比“今天背 50 道题”更稳。

2. 不要只记结论,尽量往下多想一层

C++ 面试很容易考“为什么”。

像下面这些题,如果只是会背一句话,其实很容易被继续追问:

  • 为什么 vector 插入尾部快?
  • 为什么 list 不一定比 vector 更适合频繁插入删除?
  • 为什么 shared_ptr 有性能开销?
  • 为什么移动语义可以减少拷贝?
  • 为什么基类析构函数不写成虚函数会有问题?

所以很多知识点,最好别只停留在“是什么”,而是尽量把下面几层也想明白:

  • 它解决了什么问题?
  • 它是怎么实现的?
  • 它有什么好处?
  • 它有没有副作用或者使用成本?

这样在面试里回答出来,会明显比单纯背定义更像“真懂”。

3. 一定要能和项目联系起来

这一点挺重要的。

很多人八股背得不少,但一问项目就说不出来。面试官其实也很关心:学这些东西,到底有没有在实际开发里用过。

所以建议准备的时候,顺手把自己项目里和 C++ 有关的内容也整理一下,比如:

  • 项目里主要用了哪些 STL 容器?
  • 为什么这里选 vector,那里选 unordered_map
  • 有没有用到智能指针?
  • 有没有遇到过内存泄漏、野指针、崩溃问题?
  • 有没有做过性能优化?
  • 有没有写过多线程代码?怎么做同步的?
  • 有没有踩过锁竞争、死锁、线程安全之类的坑?

很多时候,同一个问题,只讲理论和“理论 + 项目例子”,给人的感觉是完全不一样的。

4. STL 和现代 C++ 基本是重点

这几年面试里,传统语法当然还会问,但现代 C++ 的比重确实越来越高了。

像下面这些内容,出现频率都不低:

  • auto
  • nullptr
  • override
  • 右值引用
  • 移动语义
  • 完美转发
  • lambda
  • 智能指针
  • emplace_back
  • unordered_map
  • thread
  • mutex
  • atomic

尤其 STL,几乎是必问的。

至少得把几个常用容器的特点和适用场景说清楚,不然面试官很容易顺着往下问。比如

  • vector 为什么这么常用?
  • list 的优缺点是什么?
  • mapunordered_map 怎么选?
  • 哪些操作会导致迭代器失效?
  • 提前 reserve 有什么意义?

这些都属于很常见的问题。

5. 并发这块,最好单独过一遍

如果投的是后端、高性能、基础架构这类岗位,那并发题基本是跑不掉的

常见内容一般包括:

  • 线程和线程同步
  • 互斥锁
  • 条件变量
  • 原子类型
  • 死锁
  • 竞态条件
  • 伪共享
  • 内存模型
  • 线程池

这一块很多人平时也许用过 mutex,但不一定真的理解得比较完整。面试官如果继续问:

  • 条件变量为什么要搭配谓词使用?
  • 原子操作能不能完全替代锁?
  • 为什么会有伪共享?
  • 线程池一般要考虑哪些问题?

如果没提前整理过,临场容易有点乱。

所以这一块建议最好单独做一轮专题复习,不然挺容易吃亏。

6. 有时间的话,适当看一点源码

这个不一定非要啃特别深,但确实挺有帮助。

比如去看看这些内容的简单实现或者源码思路:

  • vector
  • string
  • shared_ptr
  • unordered_map
  • 简单线程池

看完之后,很多原来抽象的点会变得具体很多。不一定要把每一行代码都记住,但至少要知道:

  • 它底层大概是什么结构
  • 它为什么这样设计
  • 它这样设计的代价是什么

面试里如果问到原理,回答起来会自然很多。

7. 最后一定要练口头表达

这个是很多人最容易忽略的。

平时自己看题的时候,常常会觉得“这个我会”。但真正到了面试现场,要求两分钟内把一个问题讲清楚,很多人就开始卡壳。

所以建议在复习的时候,最好自己开口说一说。哪怕是对着手机录音,或者对着文档自言自语,也比只看不说强。

回答问题的时候,可以尽量按这个顺序来:

  1. 先说定义
  2. 再说原理
  3. 再说适用场景
  4. 最后补一句常见坑或者注意点

这样的回答会显得更完整,也更有层次。

三、面试前建议重点看的内容

如果时间有限,我觉得可以优先看这些:

第一梯队

  1. 指针、引用、const
  2. 类、继承、多态、虚函数
  3. 栈和堆、内存泄漏
  4. RAII 和智能指针
  5. STL 常用容器
  6. 左值右值、移动语义

第二梯队

  1. new/deletemalloc/free
  2. 模板基础
  3. 迭代器失效
  4. mapunordered_map
  5. 锁、条件变量、原子操作

第三梯队

  1. 对象模型和虚函数表
  2. 内存模型
  3. 伪共享
  4. 线程池设计
  5. 崩溃定位、性能分析

如果是校招或者实习,前两部分基本就够用了。如果是社招或者 C++ 开发岗,第三部分最好也补一下。

结语

C++ 面试难的地方,其实不一定是题有多偏,而是它特别容易从一个基础问题一路追问到底。

以为只是问个语法,结果可能最后问到:

  • 底层实现
  • 内存布局
  • 性能影响
  • 工程实践
  • 项目经验

所以准备 C++ 面试,最好的方式还是两步:

  • 一步是把常见知识点系统过一遍
  • 一步是把这些知识点和自己的项目经验连起来

这样面试的时候,才不会只剩下“背过一点印象”,而是真的能把问题答完整。

全部评论

相关推荐

点赞 评论 收藏
分享
牛至超人:我将凌晨两点给你打电话
点赞 评论 收藏
分享
评论
2
5
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务