2025年大厂C++面试题总结与解析
目录
-
语言特性与内存管理
-
面向对象与多态
-
STL与设计模式
-
网络编程与系统设计
-
算法与手撕代码
-
面试准备策略总结
1. 语言特性与内存管理
1.1 指针与引用的区别
-
核心区别:指针是存储内存地址的变量,可修改指向;引用是对象的别名,初始化后不可更改。
-
应用场景:引用常用于函数参数传递(避免拷贝开销)和返回值优化;指针用于动态内存操作和数据结构实现。
-
代码示例:
int a = 10; int *p = &a; // 指针 int &r = a; // 引用
1.2 const
关键字的用法
-
修饰变量:
const int a = 10;
表示变量不可修改。 -
修饰成员函数:
void func() const;
表示该函数不修改对象状态。 -
与指针结合:
-
const int* p
(常量指针):指向的值不可变。 -
int* const p
(指针常量):指针本身不可变。
-
1.3 内存管理:new/delete
与malloc/free
-
区别:
-
new
会调用构造函数,malloc
仅分配内存。 -
delete
会调用析构函数,free
直接释放内存。
-
-
内存泄漏防范:优先使用智能指针(
shared_ptr
、unique_ptr
)管理资源,避免手动释放。
1.4 智能指针的实现原理
-
核心机制:基于RAII(资源获取即初始化)和引用计数。
-
shared_ptr
与weak_ptr
:-
shared_ptr
通过引用计数共享所有权。 -
weak_ptr
解决循环引用问题,不增加引用计数。
-
2. 面向对象与多态
2.1 虚函数与多态实现
-
虚函数表(vtable):每个含虚函数的类维护一张虚函数表,对象通过虚表指针(vptr)访问虚函数。
-
纯虚函数:
virtual void func() = 0;
定义接口,派生类必须实现。 -
多态的作用:通过基类指针调用派生类方法,实现接口统一。
2.2 析构函数为何需要声明为虚函数
-
内存泄漏风险:若基类析构函数非虚,通过基类指针删除派生类对象时,只会调用基类析构函数,导致派生类资源泄漏。
-
示例:
class Base { public:virtual ~Base() {} // 虚析构 }; class Derived : public Base { /* ... */ };
2.3 继承与访问控制
-
访问权限:
-
public
继承:基类成员保持原有访问权限。 -
protected
继承:基类public
成员变为protected
。 -
private
继承:基类所有成员变为private
。
-
3. STL与设计模式
3.1 vector
与list
的区别
-
底层实现:
-
vector
:动态数组,支持随机访问(O(1)),插入删除效率低(O(n))。 -
list
:双向链表,插入删除高效(O(1)),不支持随机访问。
-
-
扩容机制:
vector
通常以2倍容量扩容,避免频繁内存分配。
3.2 单例模式的实现
-
线程安全版本:
class Singleton { public:static Singleton& getInstance() {static Singleton instance; // C++11保证线程安全return instance;}Singleton(const Singleton&) = delete; // 禁止拷贝 private:Singleton() {} // 私有构造 };
3.3 右值引用与移动语义
-
作用:避免深拷贝,提升性能。通过
std::move
将资源从临时对象“移动”到新对象。 -
示例:
std::vector<int> v1 = {1, 2, 3}; std::vector<int> v2 = std::move(v1); // v1变为空
4. 网络编程与系统设计
4.1 TCP三次握手与四次挥手
-
三次握手:确保双方收发能力正常。
-
四次挥手:保证数据完整传输,
TIME_WAIT
状态防止旧数据干扰新连接。
4.2 解决TIME_WAIT
过多的问题
-
方法:
-
设置
SO_REUSEADDR
允许端口复用。 -
调整
tcp_fin_timeout
缩短等待时间。
-
4.3 I/O多路复用:select
、poll
、epoll
-
区别:
-
select
:基于轮询,支持文件描述符数量有限。 -
epoll
:基于事件驱动,高效处理高并发连接。
-
5. 算法与手撕代码
5.1 反转链表
ListNode* reverseList(ListNode* head) {ListNode *prev = nullptr, *curr = head;while (curr) {ListNode *next = curr->next;curr->next = prev;prev = curr;curr = next;}return prev;
}
5.2 LRU缓存实现
-
核心结构:哈希表+双向链表,保证O(1)的插入和查询。
6. 面试准备策略总结
6.1 核心学习资料
-
书籍:
-
《C++ Primer》:掌握语言基础。
-
《Effective C++》:学习最佳实践。
-
《STL源码剖析》:深入理解容器实现。
-
6.2 高频考点梳理
-
必刷题:虚函数机制、智能指针、TCP状态机、手写LRU。
-
项目经验:结合实际项目解释设计模式与性能优化。
6.3 模拟面试与实战
-
刷题平台:LeetCode、牛客网(如牛客网C++题库)。
-
模拟面试:重点练习大厂真题(如百度、美团、腾讯等)。
结语:C++面试不仅考察语言细节,更注重底层原理与系统设计能力。建议结合理论学习和实战编码,逐步构建知识体系。最后,保持对新技术(如C++20特性)的关注,提升竞争力。