百度 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)。

优化手段

  1. 编译器提示[[likely]]/[[unlikely]](C++20)或 __builtin_expect,影响代码布局使热路径不跳转
  2. PGO(Profile-Guided Optimization):用运行时 profile 数据指导编译器优化分支布局
  3. 无分支代码:用条件移动指令(cmov)或算术运算替代分支。如 max(a,b) 可以不用 if
  4. 分支消除:将条件判断移出循环(循环分裂),或用 lookup table 替代 switch-case

Q: 手撕:删除有序数组中的重复元素?

(编程题)