面灵AI→

嵌入式面试体检清单:C 语言、中断、总线、RTOS 与项目排障

时间
2026-09
来源
牛客网

《面试题目》

C 语言与内存

  1. volatile 在嵌入式里有哪些典型使用场景?
  2. 结构体内存对齐规则是什么?如何计算 sizeof?
  3. 栈溢出常见现象有哪些?你怎么定位?
  4. 野指针和悬空指针区别是什么?
  5. 大小端如何判断?协议解析时要注意什么?
  6. 你项目里哪次因为内存或指针出问题?你是怎么定位的?

中断与并发

  1. 中断上下文和任务上下文有什么限制差异?
  2. ISR 里为什么不能做耗时操作?
  3. 临界区有哪些保护手段?分别适什么场景?
  4. 中断优先级和抢占怎么理解?
  5. 轮询、中断、DMA 传输如何选型?
  6. 这个数据为什么放中断里收、任务里处理?共享变量怎么保护,只靠 volatile 够不够?

MCU 与总线

  1. MCU 从上电复位到进入 main() 经历哪些步骤?
  2. I2C 通信基本时序是什么?出现 NACK 怎么处理?
  3. SPI 四种模式含义是什么?片选如何管理?
  4. UART 如何处理粘包、半包和丢字节?
  5. CAN 仲裁机制是什么?为什么不是「谁先发谁优先」那么简单?
  6. 看门狗怎么配才有意义?喂太勤会有什么问题?

RTOS

  1. FreeRTOS 任务状态有哪些?调度何时触发?
  2. 信号量和互斥量区别是什么?
  3. 什么是优先级反转?如何解决?
  4. 哪些 FreeRTOS API 能在中断中调用?
  5. 你的任务是怎么拆的?为什么这个用队列不用全局变量?出过优先级反转吗?

项目与排障

  1. 掉线重连怎么做?半包粘包怎么处理?
  2. DMA 丢数怎么查?HardFault / 死机标准排查路径是什么?
  3. 看门狗、日志、版本回滚有没有考虑?

《参考解析》

  1. volatile 的三类场景讲全,才算真懂:它约束的是编译器优化,不提供原子性和内存屏障。三类典型场景是硬件寄存器(值可能被外设改写,编译器不能把它缓存进寄存器)、中断与任务共享的变量(ISR 里改、主循环里读,不加 volatile 可能读到寄存器里的旧值)、以及无锁的多线程共享标志。高频追问是「加了 volatile 是不是就线程安全了」——不是,volatile 只保证每次真的去内存读,读改写仍可能交错,计数类共享变量还要靠临界区或原子操作。

  2. 内存对齐要能算,也要知道为什么:规则是每个成员的偏移量必须是自身对齐数的整数倍,结构体总大小是最大对齐数的整数倍,对齐数取成员自身大小与编译器对齐参数(常见 4 或 8)中的较小值。之所以要对齐,一是 CPU 访问未对齐地址可能触发异常或拆成多次总线访问(Cortex-M 上部分指令要求对齐),二是对齐后的单次访问是原子的。答题时顺手说一句「调整成员顺序能省空间」「跨平台传输不要直接发结构体、要按字节序逐字段序列化」,就跳出了背公式的层次。

  3. 中断上下文的边界是嵌入式最容易被追问塌的地方:ISR 运行在特权上下文里,抢占的是当前任务,所以不能阻塞、不能睡眠、不能等锁、不能跑长循环,printf 这类会走缓冲和信号量的调用尤其危险。能做的事是把数据收下、把事件投递出去——给队列、放信号量、置标志位,把重活留给任务。临界区三种手段的取舍也要说清:关中断最硬但影响实时性,关调度只挡任务间竞争(挡不住 ISR),拿锁灵活但要注意持锁时间;共享变量只加 volatile 挡不住并发写。

  4. 总线题按「时序 → 机制 → 异常 → 选型」四步答:I2C 要能画起始和停止条件、讲清第 9 个时钟的 ACK / NACK、时钟拉伸和 7 位寻址(同一条总线上地址不冲突的从机都能挂,实际数量受总线电容 400pF 限制)。NACK 的排查顺序是先确认从机地址和上电状态,再看时序与上拉,必要时用逻辑分析仪抓波形;总线拉死通常是某个从机把 SDA 拉低不放(复位时序错乱、供电异常、从机死机),恢复手段是从机复位或主机补 9 个时钟把它顶出去。SPI 则要讲清 CPOL / CPHA 四种模式、片选管理和全双工,以及没有应答机制导致只能靠协议层校验。

  5. RTOS 要讲成设计选择,不是教材目录:任务状态、优先级、调度时机的定义背下来只算入门,面试官想听的是「你项目里为什么这么拆」。信号量与互斥量的区别要落到所有权和优先级继承——信号量是计数与同步工具,互斥量带所有者、可用于优先级继承;优先级反转是低优先级任务持锁、被中优先级任务抢占、把高优先级任务堵在锁上的现象,解法是优先级继承(互斥量)或优先级天花板,根本解法是缩短临界区、避免多把锁嵌套。

  6. 看门狗要配得有意义:喂狗点必须放在「系统真的健康」的判据之后——比如主循环完整跑完一轮、关键任务都在心跳上报,而不是在定时器中断里无脑喂。喂太勤(比如放在高优先级中断里)会把死锁、任务饿死这类故障一起喂掉,看门狗就只剩复位功能。要能说清复位后怎么留痕(备份寄存器写故障码、日志落 flash)以及怎么定位是哪一步卡住。

  7. 项目排障的答法是固定的五步:现象 → 假设 → 验证 → 结论 → 改动。面试官要的是可复现的推理链,不是「后来就好了」。常见追问都有标准动作:掉线重连要讲退避策略与幂等;半包粘包要在协议里带长度字段或用固定帧头帧尾;DMA 丢数要查缓冲区大小与完成中断的竞争、以及内存对齐和 cache 一致性;HardFault 先看 LR / PC / 栈回溯,再对照是空指针、越界还是对齐异常。把异常路径、日志和指标补齐,比再堆一个同质化 Demo 收益高得多。

  8. 简历上写过的词就是承诺:「了解过 Linux」和「负责过驱动联调」在面试官耳朵里是两个级别,写了设备树、字符设备、platform 模型就得扛住 probe 路径、file_operations、设备树覆盖原则这些追问。时间紧的话按这个顺序压:C 与内存 → 中断边界与选型 → UART / SPI / I2C(车载工控再加 CAN)→ RTOS 调度与同步 → 按目标岗补 Linux 驱动,最后把一个主项目挖到能讲清模块划分、数据流和故障案例。