面灵AI→

百度车载嵌入式三面:多传感器数据同步、多核 cache 一致性与 AUTOSAR

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

《面试题目》

一面(技术面,约 55min)

  1. 自我介绍,并挑一个最有挑战的项目讲
  2. volatile 什么场景必须加,多核环境下它够不够用?
  3. static 修饰局部变量、全局变量、函数分别什么效果?
  4. const 和指针的那几种写法都什么意思?
  5. 内存对齐规则是什么?给一个结构体算大小,再问怎么省内存
  6. 指针和引用的区别,函数传参传哪个好?
  7. 堆和栈的区别,一个大数组你放堆还是栈,为什么?
  8. malloc 底层大概怎么实现的,小块内存和大块内存处理一样吗?
  9. 进程和线程的区别,线程间怎么同步?
  10. 项目里传感器数据量大,用什么机制在进程间传,为什么不用管道?
  11. CAN 总线的帧结构讲一下,车上为什么大量用 CAN?
  12. CAN 和车载以太网各自什么场景用?
  13. 手撕:给一段传感器数据流,写一个滑动窗口求均值,考虑数据持续进来的情况;如果数据是多个线程同时写进来的,你的代码有什么问题?

二面(技术面,约 1h10min)

  1. 先讲项目里一个最难定位的 bug(偶发数据错乱最终定位到多线程竞争)
  2. 什么是实时性,硬实时和软实时的区别,自动驾驶属于哪种?
  3. 一个感知到决策的链路,端到端延迟你怎么保证,怎么测?
  4. 中断响应时间由哪几部分组成,怎么优化?
  5. 多核系统里,怎么把不同任务绑到不同核上,为什么要这么做?
  6. 多核之间怎么保证 cache 一致性,对你写代码有什么影响?
  7. 自旋锁和互斥锁的区别,多核下自旋锁要注意什么?
  8. 内存屏障是干嘛的,什么场景下不加会出问题?
  9. 进程间大数据量通信,共享内存为什么快,它依不依赖内核?
  10. 共享内存的同步问题怎么解决,光有共享内存够吗?
  11. DDS 或者 SOME/IP 这类车载通信中间件了解吗,跟传统 socket 比好在哪?
  12. 数据量大的时候零拷贝怎么做,为什么能提速?
  13. AUTOSAR 了解吗,AP 和 CP 的区别,自动驾驶为什么多用 AP?

三面(交叉面,约 45min)

  1. 你为什么想做自动驾驶这个方向?
  2. 一个域控制器上跑着感知、规划、控制多个模块,资源怎么分配,怎么隔离?
  3. 某个模块崩了,怎么保证不影响整车安全,有什么机制?
  4. 功能安全 ISO 26262 听过吗,ASIL 分几级?
  5. 车上的软件怎么升级,OTA 中间断电了怎么保证不变砖?
  6. 大量日志和数据怎么在车端存、怎么回传分析?
  7. 你怎么理解车规级和消费级的区别?
  8. 以后想往底层平台走还是往上层应用走,为什么?

《参考解析》

多传感器数据同步与时间戳对齐,是自动驾驶数据链路的第一个真问题。 同步要分两个层次:硬件层用同一时钟源触发多个传感器(共用 PPS/触发信号、或使用支持硬件时间戳的采集卡),从源头上保证采样时刻一致;软件层在数据进入系统时打时间戳(尽量用硬件时间戳而不是收包时刻,因为网络栈排队会引入抖动),再按时间对齐做插值或重采样。常见做法有三类:硬同步(同源触发)、软同步(按时间戳归并到统一时间轴,用一个滑动窗口内的样本做插值)、以及基于已知固定延迟的补偿(相机曝光与读出有固定延迟,标定后补偿)。面试官追问「怎么保证」时,答案要落到**时钟统一(PTP/gPTP 或共用时钟)、延迟可测(标定)、以及误差可观测(监控各传感器时间戳偏差)**这三条上。

多核 cache 一致性与内存屏障,是写出正确多核代码的门槛。 现代多核 CPU 有硬件 cache 一致性协议(MESI 之类)保证「某个核写过的数据,其他核最终能看到」,所以题目的重点不是「要不要手动刷 cache」,而是看不到的时机与顺序:编译器和 CPU 都可能在保证单线程语义的前提下重排指令,导致「标志位先于数据可见」,于是另一个核看到标志位为真、读到的数据却是旧的。内存屏障(acquire/release 语义)就是为了约束这个顺序,在无锁队列、双缓冲切换、驱动与中断共享状态这些场景里不加会出偶发、极难复现的 bug。volatile 在多核下不够正是这个道理:它只保证每次重新从内存读取,不提供原子性和顺序保证,也不能防止编译器重排——多核共享状态应该用 atomic 类型或显式屏障,而不是靠 volatile。

自旋锁与互斥锁的选择,取决于临界区长度与是否能睡眠。 自旋锁忙等、不切换上下文,适合极短临界区且不能睡眠的场合(内核中断上下文、多核上的计数器);临界区长时会一直占着 CPU,还可能引出优先级反转。互斥锁拿不到就睡眠、让出 CPU,适合临界区较长或可能阻塞的场景,代价是两次上下文切换。多核下用自旋锁要特别注意三点:必须在真正多核上才有意义(单核自旋纯浪费)、必须配内存屏障(否则临界区外可能先看到锁变量的变化、后看到受保护数据)、以及不能长时间持有(否则其他核空转,整体吞吐下降)。还要注意中断上下文与传统自旋锁的死锁风险(本核中断尝试拿同一把已被本核持有的锁),所以内核里会分 spin_lock / spin_lock_irqsave 等变体。

绑定 CPU 核(绑核)在实时系统里是常规手段。 目的有三:减少迁移抖动(任务在不同核间迁移会丢失 cache 局部性、且迁移本身有开销)、隔离干扰(把中断/高负载任务固定到某些核,给实时任务留出独占核)、以及提升 cache 命中率。代价是负载不均和核利用率下降,所以绑核通常配合同步策略(把相关任务绑在同一核上共享缓存,把 I/O 中断绑到专用核)。回答里如果能提到「中断亲和性也要一起调」会更完整——只绑任务不绑中断,等于把抖动源留在原地。

端到端延迟的保证和测量,要按「分段设预算 + 逐段可观测」来答。 链路从传感器曝光 → 采集 → 传输(以太网/CAN) → 感知推理 → 融合 → 规划 → 控制 → 执行器响应,每一段都要有明确的延迟预算和监控点,否则总延迟超标时无法定位。测量方式包括硬件时间戳打点(最准)、软件埋点(有抖动但便宜)、以及离线录包回放。实时性上,自动驾驶整体属于硬实时里偏软的部分——刹车的最终执行是硬实时的,而感知规划更像是有严格截止时间的软实时(偶尔超时可以通过降级策略兜住),所以架构上会用「确定性优先 + 降级兜底」的方式保证安全。

中断响应时间的组成与优化。 时间由四部分构成:中断被识别到 CPU 响应(受当前是否关中断、是否有更高优先级中断在处理影响)→ 保存现场 → 执行 ISR → 恢复现场与返回。优化手段是:缩短关中断临界区、提高中断优先级并合理分级、把 ISR 做短(只置标志或投递消息,处理放到任务里)、减少高优先级中断的频率(能用 DMA 就不要每次中断)、以及避免在中断里做打印、内存分配、拿锁这类不可预期开销的操作。要能给出**最坏情况(WCET)**的思路,而不只是平均值。

共享内存、零拷贝与车载中间件,三条线可以串起来讲。 共享内存快的原因是数据只拷贝一次甚至零次,而且访问路径完全在用户态(mmap 之后读写就是普通内存访问,不再经过系统调用与内核缓冲区);但它本身不携带同步语义,「光有共享内存不够」,还需要信号量/互斥量/无锁队列或 futex 来协调,否则会读到半写状态。零拷贝的手段包括 mmap + write、sendfile、splice、以及用户态协议栈/DPDK 绕过内核,本质都是减少内存拷贝次数和用户态-内核态切换。DDS 与 SOME/IP 相比裸 socket 的价值在于面向数据的发布订阅模型(QoS 可配:可靠性、时效性、历史深度)、服务发现、以及为车载场景做的确定性优化;AUTOSAR 的 CP(Classic Platform)基于 OSEK,面向深嵌入式、静态配置、确定性极高,AP(Adaptive Platform)基于 POSIX,支持动态部署、面向服务通信和更高算力,因此自动驾驶域多用 AP——它需要跑感知与规划这类算力密集、迭代频繁的软件。

三面偏架构与安全,回答要体现「分层兜底」的意识。 域控制器上的资源分配与隔离靠:进程级隔离(地址空间、cgroup/资源限额)、时间隔离(时间分区调度、实时核独占)、以及硬件隔离(Hypervisor 划分虚拟机、MPU/MMU 保护、多核分区)。模块崩溃不影响整车安全,靠的是分层监控(看门狗、心跳、健康管理)+ 安全状态降级(限速、靠边停车、切备份通道)+ 冗余设计,而不是指望模块不崩。ISO 26262 的 ASIL 分 A/B/C/D 四级(D 最严),由严重度(S)、暴露率(E)、可控性(C)三个维度查表得出;ASIL 决定了开发流程、诊断覆盖率、冗余度的要求。OTA 断电不变砖的关键是 A/B 分区 + 引导校验 + 原子切换:新固件写到备用分区、校验签名与完整性、只在成功后切换启动标志,失败自动回滚到旧分区。车规与消费级的差别集中在温度范围、寿命、可靠性(失效率 ppm 级)、EMC、功能安全流程与长周期供货,而不仅是「更贵更慢」。