乐鑫科技嵌入式软件开发 一面面经
1. 为什么很多嵌入式项目仍然优先使用 C,而不是完全使用 C++?
答案:
- C 更贴近底层硬件,和寄存器、内存映射、中断向量表这类底层开发模型更契合。
- C 的运行时依赖更少,代码体积通常更可控,更适合资源受限场景。
- 很多芯片厂商提供的 SDK、驱动库、启动代码本身就是 C 风格接口。
- C++ 不是不能用,而是要看项目资源、编译链、异常机制、RTTI、代码尺寸这些成本能不能接受。
2. const、define、enum 在嵌入式开发里分别适合什么场景?
答案:
#define本质是预处理替换,适合做宏开关、寄存器位定义、条件编译。const是有类型检查的常量,适合替代普通数值常量,提高可读性和安全性。enum更适合表示一组有限状态、错误码、模式选择,语义比define更清晰。- 如果需要调试友好、类型更明确,优先考虑
const和enum;如果涉及预处理或位操作封装,宏仍然有价值。
3. 局部变量、全局变量、静态变量、字符串常量通常分别放在哪些存储区域?
答案:
- 局部非静态变量通常放在栈上。
- 已初始化的全局变量和静态变量通常在
.data段,未初始化的通常在.bss段。 - 字符串常量一般放在只读数据区。
- 动态申请的内存在堆上。
- 具体结果和编译器、链接脚本、优化选项有关,但大的分类通常是这样。
4. 为什么结构体“理论字段之和”不等于“实际 sizeof”?
答案:
- 编译器会做内存对齐,保证成员按合适边界存放,提高访问效率。
- 成员之间可能插入 padding,导致结构体实际大小变大。
- 结构体整体大小通常还要对齐到最大成员对齐要求的整数倍。
- 在通信协议、存储格式、寄存器映射场景里,这个问题尤其关键,因为它直接影响数据布局是否一致。
5. 如果一个结构体需要通过串口逐字节发送,哪些问题必须先想清楚?
答案:
- 结构体是否存在对齐填充字节,如果直接发送整个结构体,接收端可能无法按预期解析。
- 大小端问题,如果多字节字段跨平台传输,字节序可能不一致。
- 结构体版本兼容问题,一旦字段增减,通信协议就会失配。
- 更稳妥的做法通常是按协议字段逐个打包,而不是盲目直接发送内存镜像。
6. 进程、线程、任务在不同系统里为什么容易被混着说?它们本质区别是什么?
答案:
- 在 Linux 里,进程和线程是操作系统资源管理与调度的概念。
- 在 RTOS 里更常说“任务”,本质上更接近轻量级线程。
- 进程通常有独立地址空间,线程共享进程资源;RTOS 任务很多时候共享同一地址空间。
- 所以它们在“执行流”层面有相似性,但在资源隔离、切换开销、安全性上差异很大。
7. 多线程环境下,volatile 能不能解决共享变量同步问题?
答案:
volatile只能告诉编译器不要随意优化对变量的访问。- 它不能保证原子性,也不能替代锁、信号量、临界区。
- 在中断和主循环共享变量的场景下,
volatile常常是必要的,但仍可能需要关中断或加同步保护。 - 很多人误以为加
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
嵌入式面试八股文全集 文章被收录于专栏
这是一个全面的嵌入式面试专栏。主要内容将包括:操作系统(进程管理、内存管理、文件系统等)、嵌入式系统(启动流程、驱动开发、中断管理等)、网络通信(TCP/IP协议栈、Socket编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。
