跳转到内容

15 · 高频八股题库合集(考前冲刺浓缩版)

定位:第 8 周冲刺专用。把 02~14 章的全部高频题浓缩成“题 + 一句话答案”,考前 3 天每天过一遍:先盖住答案自己讲,卡壳的题号记下来回对应章节补。 用法:每题能不看答案讲出要点即过关;不能光“看着眼熟”,要出声讲。


Part 1 · 编译链接与内存(02 章)

Section titled “Part 1 · 编译链接与内存(02 章)”

Q1 编译四阶段? 预处理(展开头文件/宏)→ 编译(词法/语法/语义→汇编)→ 汇编(.o+符号表)→ 链接(符号解析+重定位)。

Q2 静态/动态库区别? 静态链接期拷入代码、体积大、独立部署;动态运行期加载、体积小可共享可热更,但缺 dll 运行时报错。

Q3 全局/static/局部/常量放哪? 全局和 static 全局→.data/.bss;static 局部→.data/.bss 但作用域函数内;局部→栈;字符串常量→.rodata;new→堆。

Q4 栈和堆区别? 栈自动快容量小无碎片;堆手动慢容量大有碎片。

Q5 sizeof 对齐怎么算? 成员按自身大小对齐,总大小=最大对齐数的整数倍;大成员放前面省 padding。

Q6 为什么内存对齐? CPU 按字访问,对齐保证一次取到,快。

Q7 判断大小端? union 或 char* 取首字节:低字节存低地址=小端。

Q8 #pragma once vs #ifndef? 前者编译器按文件路径去重、更快;后者靠宏名防重、跨平台。

Q9 extern “C”? 关掉 C++ 名字修饰,让 C++ 能链 C 符号。

Q10 undefined reference 原因? 只声明没定义、源文件没编译、没链库、符号名不一致。


Part 2 · 指针/引用/内存管理(03 章)

Section titled “Part 2 · 指针/引用/内存管理(03 章)”

Q11 指针 vs 引用(5 点)? 引用是别名必须初始化不能改绑无 NULL;指针可空可改可多级;引用无地址概念、指针存地址;传引用不拷贝、传指针也传拷贝的指针。

Q12 new vs malloc? new 调构造返回类型化指针失败抛异常;malloc 只分配 void* 失败返 NULL;delete 调析构。

Q13 内存泄漏怎么防? RAII + 智能指针 + 检测工具(Valgrind/ASAN);谁 new 谁负责。

Q14 智能指针三兄弟? unique_ptr 独占(移动转移);shared_ptr 计数在堆上控制块,拷贝+1;weak_ptr 不增强引用计数(只增弱计数),lock() 提升防悬垂。

Q15 循环引用? 两个 shared_ptr 互相持有计数永不归零→泄漏;一方改 weak_ptr。

Q16 make_shared vs new? make_shared 一次分配(对象+控制块)异常安全;new 可能两次分配、裸指针构造有异常泄漏窗口。

Q17 野/悬垂/空指针? 野=未初始化;悬垂=指向已释放;空=nullptr。释放后置空+智能指针避免。

Q18 const 指针读法? 从右往左读:int* const 指针本身 const;const int* 指向 const。

Q19 内存池? 预分配大块按块分配,避免通用分配器开销与碎片;游戏高频对象用。


Q20 构造顺序? 基类→成员(声明顺序)→自身;析构反向(自身→成员→基类)。

Q21 拷贝构造 vs 赋值? 传值/返回/新对象初始化→拷贝构造;对已存在对象赋值→赋值运算符。

Q22 深浅拷贝? 浅拷指针,深拷内容;默认是浅,含指针成员要自己写深。

Q23 移动什么时候触发? 右值作参(临时、move 结果);移动后源对象“有效但未指定”(典型实现指针被置空,标准不保证),内容不可依赖。

Q24 初始化列表为什么快? 直接构造一次;体内 m = 42 要先构造临时对象再赋值,多一步。const/引用/无默认构造成员必须用初始化列表。

Q25 空类大小? 1 字节(保证对象地址不同);加虚函数=8/16(含 vptr)。

Q26 explicit? 禁隐式转换;单参数构造建议加。

Q27 =delete/=default? 禁函数/要默认实现。


Part 4 · 继承/多态/虚函数(05 章)

Section titled “Part 4 · 继承/多态/虚函数(05 章)”

Q28 多态原理? 含虚函数的类有虚表(存虚函数地址),对象含 vptr 指向虚表,运行时查表间接调用。

Q29 静态/动态绑定? 静态=编译期(非虚、值传递);动态=运行时(虚函数+指针/引用)。

Q30 构造里调虚函数? 走当前类版本,无多态——基类构造时虚表还是基类的。

Q31 菱形继承? 二义性+基类子对象重复;虚继承共享基类子对象。

Q32 抽象类? 含纯虚函数=0,不能实例化,派生实现全部纯虚才能实例化。

Q33 基类析构为什么虚? 否则基类指针 delete 派生对象是未定义行为,常见表现只调基类析构、派生资源泄漏。

Q34 override/final? override 校验重写签名;final 禁止重写/继承。

Q35 虚函数能内联吗? 只有静态绑定调用(对象直接调)才能内联;多态查表调用不能。


Q36 vector 底层/扩容? 连续动态数组(begin/end/capacity 三指针),×1.5~2 扩容搬元素,摊还 O(1)。

Q37 迭代器失效? push_back 扩容全失效;insert/erase 使插入点/被删点及其后失效(扩容则全失效);map/set 删除不影响其他。

Q38 map vs unordered_map? map=红黑树有序 O(logn) 稳定;unordered=哈希表平均 O(1) 无序,要哈希+相等函数。

Q39 map 为什么红黑树? 平衡宽松(最长≤2×最短)旋转少、无最坏退化,统计性能好。

Q40 哈希冲突/负载因子? 链地址法;负载因子=元素/桶数,超阈值 rehash 扩容重散列。

Q41 emplace vs push? emplace 原地构造省一次拷贝/移动;push 先构造临时再拷/移。

Q42 reserve vs resize? reserve 只扩容不动 size;resize 改变 size(多的默认构造)。

Q43 list vs vector? list 插入删除 O(1) 迭代器稳定但无随机访问;vector 相反,缓存友好。

Q44 deque? 分段连续(多段定长缓冲+中控 map),头尾 O(1) 可下标。

Q45 set/map key 迭代器? key 要能比较;set 迭代器只读;map 迭代器指向 pair<const Key, T>,key 不可改、value 可改。


Q46 模板实例化时机? 编译期,用到哪种类型生成哪种;类模板成员函数惰性实例化。

Q47 特化 vs 偏特化? 全特化=具体类型;偏特化=限定一类(T*);函数模板不能偏特化(用重载)。

Q48 SFINAE? 替换失败不是错误:某个候选替换非法就跳过找别的重载。

Q49 enable_if? enable_if_t<条件,T>:条件成立才存在,用于按类型开关重载;C++17 用 if constexpr 更直观。

Q50 可变参数模板? 递归展开(剥第一个)或折叠表达式 (args + ...)

Q51 模板为什么在头文件? 实例化发生在编译期使用处,看不见定义没法生成代码。

Q52 模板和虚函数? 模板不能是虚函数;但可调虚函数;模板+CRTP=编译期多态。


Q53 值类别? 左值=有名字可取址;纯右值=临时;将亡值=可偷资源的右值(move 结果)。

Q54 move 本质? 只是 static_cast<T&&>,不移动任何东西;真正搬资源的是移动构造。

Q55 完美转发? T&& 转发引用接收 + std::forward 保持值类别;引用折叠 T&+&&→&、T&&+&&→&&。

Q56 forward vs move? move 无条件转右值;forward 有条件(T 是右值引用才转)。

Q57 lambda 底层? 匿名仿函数类(重载 operator()),捕获变量成为成员;值捕获快照、引用捕获看外面、空捕获可转函数指针。

Q58 auto vs decltype? auto 按值推导丢 const/引用;decltype 原样保留;decltype(auto) 兼得。

Q59 constexpr vs const? const 运行期不可改;constexpr 编译期可求值(可做数组大小/模板参数)。

Q60 C++14/17/20 各 3 个? 14:泛型 lambda、初始化捕获、返回类型推导;17:结构化绑定、if constexpr、折叠表达式、string_view;20:concepts、协程、三向比较、ranges。

Q61 协程 vs 线程? 协程协作式挂起恢复开销极小适合 I/O 并发;线程内核调度可抢占适合多核并行。

Q62 移动构造为什么 noexcept? vector 用 move_if_noexcept:移动非 noexcept 且有拷贝可用时退化为拷贝;不可拷贝仍移动。

Q63 nullptr vs NULL? NULL 是整数 0 宏会选错重载;nullptr 是 nullptr_t 类型专表空指针。


Q64 进程 vs 线程? 进程独立内存隔离好切换贵;线程共享内存切换快一个崩全崩。

Q65 死锁四条件? 互斥、占有且等待、不可剥夺、循环等待。避免:固定顺序加锁、scoped_lock、try_lock 超时。

Q66 lock_guard vs unique_lock? lock_guard 自动加解锁不能手动;unique_lock 可手动 lock/unlock 可移动,条件变量必须用它。

Q67 条件变量为什么配 unique_lock? wait 要原子地释放锁挂起、唤醒后重新上锁。

Q68 虚假唤醒? 被唤醒但条件未满足;wait 必须带谓词(内部 while 循环)。

Q69 atomic vs mutex? atomic 单变量原子操作(主流平台通常无锁,标准不保证)快;mutex 保护任意临界区慢。

Q70 内存序? relaxed 只保证原子(计数器);acquire/release 配对发布-消费同步;seq_cst 全局强一致(默认)。

Q71 线程安全单例? Magic Static:局部 static 变量,C++11 标准保证首次初始化线程安全。

Q72 线程池/job system? 固定线程+任务队列+条件变量复用线程;job system 拆任务并行用满多核(UE TaskGraph)。


Part 9 · 设计模式/性能/游戏专项(10~13 章)

Section titled “Part 9 · 设计模式/性能/游戏专项(10~13 章)”

Q73 单例为什么被诟病? 全局状态、隐藏依赖、难测试、生命周期不可控;替代:依赖注入、引擎持有子系统。

Q74 观察者/状态/命令游戏场景? 观察者=事件系统/UI 订阅;状态=角色状态机;命令=输入队列/撤销/回放/联机。

Q75 对象池? 预分配+借还复用,避免 new/delete 开销与碎片,归还重置状态。

Q76 虚函数开销? 查虚表间接跳转+无法内联+分支预测差;每帧海量对象时明显。

Q77 缓存友好? 连续内存顺序遍历(vector>list)、SoA 布局、按访问顺序排列、避免随机跳转。

Q78 AoS vs SoA? AoS 对象数组;SoA 字段数组批量处理缓存友好,ECS/粒子用 SoA。

Q79 内存池 vs 对象池? 内存池管内存块;对象池管对象生命周期;常叠加。

Q80 分支预测? CPU 猜 if 走向,猜错清流水线惩罚大;排序、branchless、查找表缓解。

Q81 游戏主循环? 输入→更新(固定步长逻辑+物理)→渲染(可变+插值);物理固定步长保证稳定确定。

Q82 ECS? 实体=ID、组件=纯数据、系统=逻辑;缓存友好+灵活组合+易并行+无深继承。

Q83 四元数? 4 分量无万向节死锁、slerp 平滑插值;欧拉角有万向锁+插值不平滑。

Q84 碰撞空间分区? 四叉树 2D、八叉树 3D、BVH 动态物体、网格哈希均匀分布;先粗筛后细查。

Q85 图形管线? 顶点着色→光栅化→片元着色→输出合并(深度/混合)。

Q86 DrawCall? 一次绘制命令,贵在 CPU-GPU 通信+状态切换;减少:合批、图集、实例化、减切换。

Q87 前向 vs 延迟渲染? 前向多光源贵适合移动;延迟 GBuffer 统一光照支持多光源适合 PC。

Q88 UE UObject/反射/GC? UObject 提供反射/GC/序列化/编辑器;反射=宏+UHT 生成元数据;GC=可达性分析 Mark-Sweep。

Q89 Mono vs IL2CPP? Mono JIT 迭代快可热更;IL2CPP 转 C++ AOT 性能好防破解包大;发布用 IL2CPP。

Q90 状态同步 vs 帧同步? 状态同步传状态(MMO/射击);帧同步只传输入确定模拟(RTS/格斗)。


  • 考前 3 天:每天完整过一遍,出声讲;卡壳的题号记在下面:
    第一天卡壳:______
    第二天卡壳:______
    第三天卡壳:______
  • 卡壳题 → 回对应章节精读 + 让我抽查。
  • 这份是“浓缩”,细节和代码例子一定要回原章看——只背这句话答不了追问。