百度 AI Infra 校招 二面 (2)
Q: CNN和DNN的区别?
两者都是前馈神经网络,但在结构假设和参数效率上有本质区别:
DNN(全连接网络/MLP):
- 每层所有神经元与前一层全连接,参数量 = input_dim * output_dim
- 无结构假设,将输入当作一维向量处理
- 参数量随输入尺寸平方增长(如 224x224 图像展平后全连接到 1024 维需 ~50M 参数仅一层)
- 适合表格数据等无空间结构的输入
CNN(卷积神经网络):
- 利用卷积核实现局部连接(每个神经元只看局部区域)和权值共享(同一卷积核在所有位置共享参数)
- 大幅减少参数:3x3 conv 在 64 通道上只有 64649 ≈ 37K 参数,与输入尺寸无关
- 池化层降低空间维度,逐层提取从低级到高级的特征
- 天然编码了平移不变性和空间局部性假设
核心区别:CNN 通过归纳偏置(局部性+共享性)在图像/语音等空间数据上极度参数高效;DNN 对输入无任何假设但参数多且不编码结构信息。
Q: C++智能指针有哪些?
shared_ptr(引用计数共享所有权,原子操作保证计数线程安全,make_shared 高效一次分配)、unique_ptr(独占所有权零额外开销,不可拷贝只可 move,默认首选)、weak_ptr(弱引用不增计数,lock() 提升,打破循环引用/实现缓存观察)。
选择原则:默认 unique_ptr -> 需共享用 shared_ptr -> 需观察不拥有用 weak_ptr。
Q: 迭代和递归的优缺点?
| 对比 | 递归 | 迭代 |
|---|---|---|
| 优点 | 代码简洁直观,天然适配分治/树形结构 | 无函数调用开销,不受栈深度限制 |
| 缺点 | 函数调用开销(压栈/出栈/寄存器保存)、栈空间有限(默认 8MB,深度 ~10 万层即溢出) | 某些问题实现复杂(如树遍历需手动维护栈) |
| 空间 | O(递归深度)的栈空间 | O(1)或显式数据结构 |
| 尾递归 | 编译器可优化为迭代(但 C++ 不保证) | 天然无此问题 |
实践建议:递归深度可控(如平衡二叉树 ~30 层)时用递归保持代码清晰;可能深度递归时改用迭代 + 显式栈(如 DFS 的非递归实现)。
Q: CPU会对if语句做什么优化?
分支预测(Branch Prediction):现代 CPU 流水线深度 15-20 级,遇到条件分支时不能等待条件计算完成再取后续指令。CPU 通过分支预测器(BPU)提前预测走向并投机执行。
预测策略:
- 静态预测:后跳(循环)预测走,前跳预测不走
- 动态预测:基于历史记录(2-bit 饱和计数器、TAGE 预测器),准确率 >95%
预测失败代价:需要 flush 流水线中投机执行的指令,penalty 约 10-20 个周期(现代 CPU 约 15 cycles)。
优化手段:
- 编译器提示:
[[likely]]/[[unlikely]](C++20)或__builtin_expect,影响代码布局使热路径不跳转 - PGO(Profile-Guided Optimization):用运行时 profile 数据指导编译器优化分支布局
- 无分支代码:用条件移动指令(cmov)或算术运算替代分支。如
max(a,b)可以不用 if - 分支消除:将条件判断移出循环(循环分裂),或用 lookup table 替代 switch-case
Q: 手撕:删除有序数组中的重复元素?
(编程题)