蚂蚁 C++开发 一面
1. 自我介绍
2. 讲一下你做过的项目,重点说说其中最难的技术点
3. 我看你实习了一年了 怎么没留在上家公司
4. 说一下线程、进程、协程的区别,如果放到你的项目里会怎么选
答案:进程是资源隔离单位,线程是 CPU 调度单位,协程更像用户态轻量执行流。进程的隔离性最好,但切换和通信成本更高;线程共享地址空间,适合同一个服务内并行处理任务,但要处理锁竞争和共享数据一致性;协程切换开销小,特别适合高并发 I/O 等待场景。如果放到服务端项目里,我通常会让网络接入层偏事件驱动或协程化,避免大量阻塞线程;真正的 CPU 密集型计算,比如压缩、解析、聚合,会放到线程池里做。所以不是三选一,而是看场景组合使用。
5. 线程同步有哪些手段,互斥锁、读写锁、条件变量分别适合什么场景
答案:互斥锁适合保护共享资源的修改,语义最直接,也是最常用的。读写锁适合读多写少的场景,可以允许多个读线程并发进入,但写线程要独占。条件变量适合线程间通知,比如生产者放入任务后唤醒消费者,不适合单纯拿来做互斥。如果只是计数器、状态位这种简单共享数据,原子操作会比大锁更轻。工程里真正要注意的是临界区长度和共享粒度,锁本身只是工具,设计共享数据的方式往往比“选哪把锁”更关键。
代码:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
using namespace std;
mutex mtx;
condition_variable cv;
queue<int> tasks;
bool stopFlag = false;
void worker() {
while (true) {
unique_lock<mutex> lock(mtx);
cv.wait(lock, [] { return !tasks.empty() || stopFlag; });
if (stopFlag && tasks.empty()) break;
int x = tasks.front();
tasks.pop();
lock.unlock();
cout << "process task: " << x << endl;
}
}
6. C++ 里 new/delete 和 malloc/free 的区别是什么
答案:malloc/free 是 C 风格内存管理,分配的是原始字节块,不会调用构造和析构。new/delete 是 C++ 运算符,除了分配内存,还会调用对象的构造函数和析构函数。所以对于普通 POD 类型,有些时候看起来都能用,但对类对象来说语义差别非常大。另外 new 失败时默认抛异常,malloc 失败时返回 NULL。底层上它们都可能走到同一套分配器,但语言层面的对象生命周期管理完全不是一回事,不能混用。
7. 说一下 C++ 的虚函数、多态以及虚表一般是怎么实现的
答案:多态通常依赖虚函数实现。父类声明虚函数后,子类重写它,通过父类指针或引用调用时,实际执行哪个函数会在运行期决定。主流编译器实现里,带虚函数的对象通常会有一个隐藏的虚表指针 vptr,它指向该类型对应的虚函数表。调用虚函数时,程序先通过 vptr 找到虚表,再定位真正的函数入口。虚函数代码本身不在对象里,对象里一般只是多了一个指针。如果涉及多继承和虚继承,布局会复杂很多,因为编译器还要处理基类偏移和对象调整。
8. map 和 unordered_map 有什么区别,线上怎么选
map 通常基于红黑树实现,键有序,查找、插入、删除是 O(log n);unordered_map 通常基于哈希表实现,键无序,平均复杂度接近 O(1)。如果业务需要有序遍历、范围查询、lower_bound 这类能力,选 map 更自然。如果业务更看重单点查找性能,且不要求顺序,通常优先 unordered_map。线上选型时我还会看 key 分布是否容易冲突、内存占用是否敏感、扩容 rehash 是否可接受,因为哈希表在极端情况下性能也会退化。
9. 说一下 mmap 和 read/write 的区别,什么时候更适合用 mmap
答案:read/write 是显式把数据从内核缓冲区拷到用户缓冲区,程序自己控制读写过程。mmap 是把文件映射到进程虚拟地址空间,访问文件内容更像直接访问内存。mmap 的优势是减少了一层显式拷贝,随机访问大文件会比较自然,也适合多个进程共享映射区域。但它也不是银弹,页面缺失、写回时机、地址空间占用、访问局部性差时的抖动都要考虑。如果是顺序流式读取,read 往往更直观;如果是大文件随机访问或需要共享映射,mmap 更有优势。
10. 你怎么理解零拷贝,它真的完全没有拷贝吗
零拷贝的核心目标是减少 CPU 参与的数据复制次数,降低上下文切换和内存带宽消耗。像 sendfile、mmap + write、DMA 这
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本专栏系统梳理C++方向, 大中厂高频高频面试考点 , 内容皆来自真实面试经历,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力.
