面灵AI→

商汤科技 C++ 一面面经(27届秋招)

轮次
一面
时间
2026-10
来源
牛客网

《面试题目》

  1. 你接触过模型部署 / 推理优化吗?做到什么程度?
  2. TensorRT 你了解吗?INT8 量化对精度的影响怎么评估?
  3. 推理延迟的大头在哪?服务端怎么提速?
  4. GPU 和 CPU 的显存 / 内存拷贝怎么优化?
  5. OpenCV Mat 的内存布局?深拷贝和浅拷贝怎么控制?
  6. 图像 resize 的插值方法怎么选?
  7. 颜色空间转换(BGR / RGB / YUV / GRAY)有什么坑?
  8. CUDA 你写过 kernel 吗?线程网格怎么组织?

《参考解析》

TensorRT 与量化:TensorRT 的流水线是 ONNX / Caffe 导入 → 图优化(层融合、常量折叠、kernel 自动调优)→ 精度校准(FP16 一般直接开,INT8 需要校准集统计激活分布)→ 序列化 engine,运行时反序列化加载。INT8 的精度评估不能靠肉眼看几个样本:要在同一验证集上比量化前后的业务指标(mAP、准确率、召回),并关注分层敏感度——首层和检测头通常对量化最敏感,可以配置逐层回退到 FP16。常见的坑是校准集不覆盖真实分布(量化值域偏了)、输入 shape 的动态范围没提前固定(导致反复 rebuild engine)、以及量化后输出的数值范围变化没有同步调整后处理阈值。

延迟瓶颈在哪:推理延迟的组成通常有四块——数据预处理(CPU 侧 decode / resize / normalize)、H2D 拷贝、GPU kernel 计算、后处理与 D2H 回传。定位方法是抓 timeline(nsys / nvprof):如果 GPU 利用率低而 CPU 段很长,瓶颈在预处理;如果 copy 段占比高,问题在拷贝;如果 kernel 排不满(batch 小),要合并 batch 或换更高效的实现。提速的组合拳是:预处理 GPU 化(CUDA / NPP / DALI)、pinned memory 异步拷贝、多流并发、动态 batch 合并、算子融合与量化。指标上要看 p99 和首帧延迟,平均值会掩盖长尾;GPU 利用率低时优先查 CPU 瓶颈。

拷贝优化与 OpenCV Mat:PCIe 带宽有限,大图或点云单帧的 H2D 就可能吃掉毫秒级预算,主线是「减少次数 + 压缩体积」。手段有:页锁定(pinned)内存 + cudaMemcpyAsync 异步拷贝、合并 batch 一次搬、NV12 / YUV 直接喂模型免去 CPU 转换、端侧 NPU 直读相机 buffer;拷贝和计算放在不同 stream 才能 overlap,别在默认流里串行排队。OpenCV 的 Mat 是「头(宽高、步长、通道、引用计数)+ 指向数据的指针」,赋值和传参只拷头、共享数据(浅拷贝),clone() / copyTo() 才深拷贝。ROI 是共享底层 buffer 的视图,改视图等于改原图,处理管线里要明确哪一步必须 clone;性能上要避免每帧 clone 大图,跨模块传引用或 shared_ptr<Mat>。

resize 与颜色空间:最近邻最快、保留硬边缘,适合分割 mask 和标签图,放大块状明显;双线性是速度与质量的折中,放大 4 倍内够用;双三次 / Lanczos 质量最好但慢,适合最终输出,下采样要先低通滤波防混叠。颜色空间最经典的坑是 OpenCV 默认 BGR 而模型训练多用 RGB——顺序搞错不会报错,但指标会莫名其妙变差,这类 bug 最难查。其次是归一化要和训练时的 mean / std 与数值范围(0-1 还是 0-255)逐项对齐;YUV 转换的整数定点实现和浮点公式结果有差异,跨平台时要固定实现和 OpenCV 版本。

CUDA 线程组织:grid → block → thread 三级结构,block 内的线程可以共享 shared memory 并用 __syncthreads() 同步,block 之间默认不能同步(需要靠 kernel 拆分或 cooperative groups)。图像处理一般是「一个线程处理一个像素或一个 tile」,block 大小常取 16×16 / 32×32(对齐 warp,32 的倍数),这样访存能合并、shared memory 也够用。性能要点是合并访存(相邻线程访问相邻地址)、减少 bank conflict、尽量用 shared memory 做复用、以及让线程块数量远大于 SM 数(否则 occupancy 不够)。

这一轮的定位:这场面试把「AI 岗的 C++」拆成了「写模型的算法工程化」和「写服务的工程应用」两条线,全程围绕推理部署的工程细节追问。回答策略上,有真实部署经验就深讲(格式、框架、量化、你负责哪一段),没有就用 C++ 功底和工程迁移能力来补,并明确表达自己站哪一边。商汤这类公司尤其在意「你是不是只调过库、没动过底层」——把 nsys timeline、pinned memory、stream overlap 这些细节讲出来,比背 TensorRT 的 API 名字更有说服力。