海辰储能嵌入式 MCU 岗面试
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 请做一下自我介绍。
- const、static、volatile 三个关键字有什么区别?
- 中断是什么?
- DMA 是什么,用来解决什么问题?
- FreeRTOS 的任务调度是怎么实现的?
- 信号量和互斥锁有什么区别?
- 什么是优先级反转,怎么解决?
- 多任务场景下优先级怎么设置?
- 英语口语怎么样?
《参考解析》
const、static、volatile 各自的语义
这三个关键字考的是「编译器怎么理解你的内存」。const 是只读约束,编译器可以据此把值折叠进指令、也可以把变量放进只读段,但指针 const 要分清是「指向常量的指针」还是「指针本身不可改」。static 分三处看:修饰全局变量或函数时把链接属性收成内部链接、其他文件不可见;修饰局部变量时生命周期变成整个程序、只初始化一次;在 C++ 里修饰类成员则表示属于类而不是对象。volatile 告诉编译器「这个值随时可能被外部改」,禁止把它缓存到寄存器、禁止优化掉看似无用的读写,典型场景是硬件寄存器、中断与主循环共享的变量、以及多线程共享标志位——它只保证不被优化,不提供任何原子性或内存屏障。
中断与 DMA
中断是外设或异常打断 CPU 正常执行流、跳去执行处理函数的机制,回答时要带出中断向量表、现场保存与恢复、中断嵌套和优先级、以及中断服务程序要尽量短(耗时操作丢给任务或下半部)这几层。DMA 让外设与内存之间直接搬数据,不需要 CPU 逐字节搬运,CPU 只负责配置源地址、目的地址和长度,搬运完成再用中断通知。串口/UART、ADC 采样、SPI 大批量收发是典型用例,配合乒乓缓冲或环形缓冲,能把 CPU 从数据搬运里解放出来。
FreeRTOS 的任务调度
FreeRTOS 的调度器是抢占式的,每个任务有独立栈和优先级,调度器始终运行处于就绪态里优先级最高的那个,同优先级按时间片轮转(时间片大小由 tick 决定)。回答时最好把这几件事串起来:任务状态(运行/就绪/阻塞/挂起)与就绪链表、SysTick 驱动的时间片与延时、任务切换发生在中断退出时(PendSV),以及空闲任务与钩子函数的用途。如果问到具体开销,能说清上下文切换保存哪些寄存器、每 tick 一次调度带来的开销。
信号量与互斥锁的区别
二值信号量更像「通知」:可以在中断里 give、用来同步任务与中断,谁拿到都能给的语义也比较宽松;互斥锁强调「所有权」,只有加锁的任务能解锁,因此能实现优先级继承。这个差别直接引出下一个问题——用二值信号量做互斥会引发优先级反转,用互斥锁则能从机制上缓解。
优先级反转与多任务优先级设置
优先级反转是「高优先级任务等一个被低优先级任务持有的锁,而低优先级任务又被中优先级任务抢占」,于是高优先级任务被中优先级任务间接阻塞。两种经典解法:优先级继承(持锁任务临时提升到等待者的优先级,FreeRTOS 的互斥锁就是这套)和优先级天花板(把锁的天花板设成所有可能加锁任务里的最高优先级)。优先级设置一般按「响应时间要求越紧、优先级越高」来定,控制类与中断下半部靠前,日志、统计这类非实时任务放最低,同时尽量少用优先级继承之外的共享资源。