一、语言基础与内存管理
-
const
与constexpr
的区别?应用场景?const
:运行时常量,修饰变量/函数不可修改。constexpr
:编译期常量(C++11),用于优化计算(如数组大小)。
constexpr int size = 10; // 编译期确定 const int x = get_value(); // 运行时确定
-
指针与引用的本质区别?
- 指针:独立变量存储地址,可重指向、可为
nullptr
。 - 引用:别名,绑定后不可变,无空引用,更安全。
- 指针:独立变量存储地址,可重指向、可为
-
智能指针(
unique_ptr
/shared_ptr
/weak_ptr
)的实现原理与使用场景?unique_ptr
:独占所有权,零开销(替代auto_ptr
)。shared_ptr
:引用计数(原子操作),循环引用需weak_ptr
解决。- ★ 阿里高频:手写
shared_ptr
引用计数实现。
-
移动语义(Move Semantics)与完美转发(Perfect Forwarding)的作用?
std::move
:将左值转为右值,触发移动构造(避免深拷贝)。std::forward
:保持参数原始值类型(左值/右值),用于泛型编程。
-
volatile
与atomic
的区别?volatile
:阻止编译器优化(不保证多线程原子性)。atomic
:硬件级原子操作(如load
/store
),线程安全。
二、面向对象与多态
-
虚函数表(vtable)与虚指针(vptr)的工作原理?
- 每个含虚函数的类有一个vtable,对象通过vptr访问,运行时动态绑定。
-
为何基类析构函数需声明为
virtual
?- 避免派生类对象通过基类指针删除时资源泄漏(未调用派生类析构)。
-
纯虚函数与抽象类的联系?
- 纯虚函数(
=0
)使类成为抽象类,强制派生类实现接口。
- 纯虚函数(
-
多重继承下的菱形继承问题如何解决?
- 虚继承(
virtual
关键字),确保公共基类仅存一份实例。
class D : public B, virtual public C { ... }; // 虚继承C
- 虚继承(
三、STL与模板编程
-
vector
底层实现与扩容策略?- 动态数组,2倍扩容(避免频繁分配),
reserve()
预分配空间优化。
- 动态数组,2倍扩容(避免频繁分配),
-
map
(红黑树)与unordered_map
(哈希表)的性能对比?操作 map
unordered_map
插入/删除 O(log n) O(1) 平均 有序性 是 否 -
☆ C++17的
std::optional
/std::variant
应用场景?optional
:安全处理可能缺失的值(替代nullptr
或非法值)。variant
:类型安全的联合体(替代union
),编译期类型检查。
std::optional<int> find(int id); // 返回有效值或std::nullopt
-
模板元编程(TMP)的应用案例?
- 编译期计算(如斐波那契数列)、类型萃取(
type_traits
)。
- 编译期计算(如斐波那契数列)、类型萃取(
四、并发与多线程
-
std::thread
vsstd::async
?thread
:直接创建线程,需手动管理。async
:可能复用线程池,通过future
自动管理结果。
-
死锁条件与解决方法?
- 条件:互斥、请求保持、不可剥夺、环路等待。
- 解决:按固定顺序加锁、
std::lock()
原子加锁、超时机制。
-
无锁编程的
memory_order
选项(如relaxed
/seq_cst
)?relaxed
:允许乱序(性能高,无同步)。seq_cst
:全局顺序一致(默认,性能低)。
-
☆ 协程(Coroutines)的原理与优势(C++20)?
- 用户态线程,切换成本低(20~50ns vs 线程1~10μs),支持异步I/O。
- 字节跳动真题:实现百万级协程调度器(Work-Stealing + 无锁队列)。
五、系统设计与性能优化
-
零拷贝(Zero-Copy)技术实现方案?
sendfile()
(Linux):文件→Socket直传(内核2.2+)。splice()
+pipe
:跨文件描述符传输(无用户态拷贝)。
-
高并发日志系统设计要点?
- 无锁分片队列 + 独立压缩线程 + Kafka顺序写(美团真题:500万条/秒)。
-
分布式缓存一致性协议(如Raft)?
- Leader选举 + 日志复制(多数派确认),脑裂防护(Lease机制)。
- 阿里真题:Redis集群脑裂解决方案。
六、现代C++新特性(C++17/20)
-
☆ 结构化绑定(Structured Binding) :
auto [id, name] = std::make_pair(1, "Alice"); // 解包pair/tuple
-
☆ 概念(Concepts)的作用(C++20)? :
- 约束模板参数,替代SFINAE,提升可读性。
template <typename T> requires integral<T> // 限定T为整型 T add(T a, T b) { return a + b; }
-
☆ Range库(C++20)的优势? :
- 管道式操作:
data | views::filter(...) | views::transform(...)
。
- 管道式操作: