金山 C++ 一面 面经

1. 自我介绍

简单做一下自我介绍,重点介绍自己的技术栈、做过的项目、项目中承担的职责,以及和 C++ 岗位相关的能力即可。

回答时不需要铺得太开,控制在 1 分钟左右比较合适。

参考回答:

面试官您好,我是 XX,目前主要学习和使用的是 C++,系统学过 C++ 基础、数据结构、操作系统、计算机网络和数据库等内容。项目方面,我做过一个基于 C++ 的高并发服务端项目,也接触过多线程、网络编程、线程同步、内存管理等内容。在项目里我主要负责模块设计、接口实现和问题排查。今天也希望通过这次面试,和您交流一下我对 C++ 岗位相关知识的理解。

2. 讲一下你做过的一个 C++ 项目,重点说你负责的部分

参考回答:

回答这个问题时,不要从头到尾流水账介绍项目,而是建议按“项目背景 - 技术选型 - 个人职责 - 难点 - 收获”来讲。

例如可以这样回答:

我做过一个基于 C++ 的网络服务端项目,项目主要目标是实现多客户端连接、消息收发和业务处理。技术上主要用了 C++11、多线程、socket 编程、互斥锁、条件变量等。

我主要负责的是客户端连接管理、任务分发和部分业务逻辑模块的开发。

在实现过程中,比较大的难点是多个线程同时访问共享队列时容易出现竞争问题,所以我引入了互斥锁和条件变量来保证线程安全,同时减少线程空转带来的性能损耗。

通过这个项目,我对 C++ 在工程中的使用、多线程同步、资源管理等有了更深入的理解。

这个问题的核心不是项目有多大,而是你能不能把自己的工作讲清楚,尤其要能讲出“你做了什么”“遇到了什么问题”“怎么解决的”。

3. 进程和线程有什么区别

参考回答:

进程和线程都是操作系统进行资源管理和任务调度的重要概念,但两者有明显区别。

第一,进程是资源分配的基本单位。

每个进程都有自己独立的地址空间、代码段、数据段和打开的文件等资源。不同进程之间默认相互隔离,一个进程崩溃一般不会直接影响另一个进程。

第二,线程是 CPU 调度的基本单位。

线程是进程中的执行单元,同一个进程内的多个线程共享进程的地址空间、全局变量、堆、文件描述符等资源,但每个线程有自己的栈、寄存器上下文和程序计数器。

第三,创建和切换开销不同。

进程创建和销毁的开销通常更大,线程相对更轻量;线程间切换的代价一般也比进程间切换更小。

第四,通信方式不同。

进程之间因为资源隔离,需要借助管道、消息队列、共享内存、socket 等 IPC 方式进行通信。线程由于共享进程内存,可以直接读写共享数据,但也因此更容易出现线程安全问题。

总结来说,进程更强调资源隔离,线程更强调执行并发。

4. 线程同步常见方式有哪些

参考回答:

线程同步的核心目的是协调多个线程对共享资源的访问,避免竞态条件、数据不一致等问题。常见方式主要有以下几种。

第一,互斥锁。

互斥锁用于保护临界区,保证同一时刻只有一个线程能访问共享资源。它适合对共享变量、共享容器等进行保护。

缺点是如果加锁范围过大,可能会影响并发性能;如果使用不当,还可能导致死锁。

第二,读写锁。

读写锁区分读操作和写操作。当多个线程都只是读取数据时,可以同时加读锁;只有写操作时才需要独占。

这种方式适合“读多写少”的场景。

第三,条件变量。

条件变量通常和互斥锁一起使用,用于线程之间的等待和通知。例如生产者消费者模型中,当队列为空时消费者等待,当生产者放入数据后通知消费者。

它可以避免线程不断轮询带来的 CPU 浪费。

第四,原子操作。

对于简单的共享变量操作,比如计数器加减,可以直接使用原子类型。原子操作底层通常借助 CPU 指令实现,效率高于传统加锁。

但原子操作更适合简单场景,复杂逻辑一般还是要配合锁来做。

第五,信号量。

信号量本质上是一个计数器,用于控制多个线程对有限资源的访问数量。例如一个资源池最多允许 N 个线程同时使用。

实际开发中,应该根据共享资源的复杂度和性能要求选择合适的同步机制,而不是一律使用互斥锁。

5. 什么是死锁,死锁产生的条件是什么

参考回答:

死锁是指多个线程或进程在执行过程中,因为争夺资源而相互等待,最终谁都无法继续执行的状态。

死锁产生通常需要同时满足以下四个条件。

第一,互斥条件。

资源在某一时刻只能被一个线程占用。

第二,请求并保持条件。

线程已经持有一个资源,同时又请求新的资源,并且在等待新资源时不释放已有资源。

第三,不可剥夺条件。

线程已经获得的资源在没有使用完之前,不能被其他线程强行夺走。

第四,循环等待条件。

多个线程之间形成一个资源等待环。比如线程 A 等待线程 B 手里的资源,线程 B 又等待线程 A 手里的资源。

举个简单例子:

线程 A 先拿锁 1 再等锁 2,线程 B 先拿锁 2 再等锁 1,这时就可能产生死锁。

避免死锁的常见方法有:

  1. 固定加锁顺序,所有线程按相同顺序申请锁。
  2. 尽量减少锁的嵌套。
  3. 使用 std::lock 或一次性获取多个锁。
  4. 设置超时机制,避免无限等待。
  5. 优化设计,减少共享资源竞争。

6. std::vectorstd::list 有什么区别

参考回答:

std::vectorstd::list 都是 STL 容器,但底层结构和适用场景差别很大。

std::vector 底层是连续内存空间,类似动态数组。

优点是:

  1. 支持随机访问,vector[i] 的时间复杂度是 O(1)。
  2. 缓存友好,遍历效率高。
  3. 尾部插入和删除效率较高,均摊复杂度通常是 O(1)。

缺点是:

  1. 中间插入和删除效率低,因为可能需要移动大量元素。
  2. 扩容时可能发生整块内存重新分配,导致迭代器失效。

std::list 底层通常是双向链表。

优点是:

  1. 任意位置插入和删除效率高,在已知位置的情况下时间复杂度通常是 O(1)。
  2. 插入删除时不会像 vector 那样大规模搬移元素。
  3. 节点地址相对稳定,已有迭代器通常不容易整体失效。

缺点是:

  1. 不支持随机访问。
  2. 每个节点需要额外存储前后指针,内存开销更大。
  3. 节点分散,缓存局部性差,遍历效率往往不如 vector

如果业务主要是大量遍历、随机访问、尾插,优先考虑 vector

如果业务是频繁在中间位置插入删除,而且已经持有对应迭代器,list 才更有优势。

7. mapunordered_map 的区别是什么

参考回答:

二者都是键值对容器,但底层实现和使用特点不同。

map 底层通常基于红黑树实现,特点是:

  1. 元素默认按 key 有序。
  2. 查找、插入、删除的时间复杂度通常是 O(logn)。
  3. 支持范围查找、有序遍历等操作。

unordered_map 底层通常基于哈希表实现,特点是:

  1. 元素无序。
  2. 平均情况下查找、插入、删除复杂度是 O(1)。
  3. 最坏情况下如果哈希冲突严重,复杂度可能退化到 O(n)。

选择时一般这样考虑:

  1. 如果需要按 key 有序输出,或者需要上下界查询、范围操作,选 map
  2. 如果只关心快速查找,不关心顺序,通常选 unordered_map
  3. 如果 key 类型复杂,使用 unordered_map 时需要考虑哈希函数和冲突问题。

面试时最好补充一点:

unordered_map 虽然平均性能更高,但在工程里不一定绝对优于 map,因为哈希冲突、rehash、内存占用等问题也需要考虑。

8. 左值、右值、左值引用、右值引用分别是什么

参考回答:

这是现代 C++ 中比较重要的基础概念。

左值,一般可以理解为“有名字、可定位、生命周期较明确”的对象。

例如普通变量:

int a = 10;

这里的 a 就是左值,因为它有明确的内存位置,可以被取地址。

右值,一般可以理解为“临时值、即将销毁的值、不能长期持有地址的值”。

例如:

a + 1
5
std::string("abc")

这些通常都是右值。

左值引用使用 T& 表示,只能绑定左值:

int a = 10;
int& ref = a;

右值引用使用 T&& 表示,主要用于绑定右值:

int&& rref = 10;

右值引用的重要意义在于支持移动语义和完美转发。

以前对象拷贝可能会带来额外开销,而引入右值引用后,可以“窃取”临时对象内部资源,减少不必要的深拷贝。

例如 std::vector 扩容或函数返回大对象时,移动语义能显著提升效率。

所以这个问题不能只停留在“谁能取地址”,更重要的是要理解它和 C++11 性能优化的关系。

9. 什么是移动语义,什么情况下会用到移动构造

参考回答:

移动语义是 C++11 引入的重要特性,目的是减少对象拷贝开销,特别是对于内部持有堆资源的对象。

传统拷贝构造会把源对象的数据完整复制一份,比如一个内部有动态数组的类,拷贝时需要重新申请内存并复制内容,这样

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

C++八股文全集 文章被收录于专栏

本专栏系统梳理C++技术面试核心考点,涵盖语言基础、面向对象、内存管理、STL容器、模板编程及经典算法。从引用指针、虚函数表、智能指针等底层原理,到继承多态、运算符重载等OOP特性从const、static、inline等关键字辨析,到动态规划、KMP算法、并查集等手写实现。每个知识点以面试答题形式呈现,注重原理阐述而非冗长代码,帮助你快速构建完整知识体系,从容应对面试官提问,顺利拿下offer。

全部评论
佬 考虑我司么 考虑的话 可以看我主页帖子
点赞 回复 分享
发布于 04-10 16:34 上海
拼多多招27届实习生啦 https://careers.pddglobalhr.com/campus/intern/detail?t=dRvUVvcTiA
点赞 回复 分享
发布于 04-10 14:18 上海
春招投的嘛 我这边一直没推进呜呜
点赞 回复 分享
发布于 04-10 13:22 安徽

相关推荐

04-10 18:32
已编辑
四川大学 Java
牛客17492028...:我只能说你这学历boss有的是人要,
点赞 评论 收藏
分享
评论
1
3
分享

创作者周榜

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