腾讯嵌入式软件开发一面 面经
一、C / C++ 基础
1. const 和 volatile 分别有什么作用?在嵌入式开发里为什么经常一起出现?
参考答案:
const表示变量是只读语义,告诉编译器这个值不应该被程序修改。volatile表示变量可能被“程序之外”的因素改变,比如中断、DMA、硬件寄存器、多线程共享变量等,编译器不能擅自优化对它的读取。- 在嵌入式里常见场景是硬件寄存器映射,例如寄存器地址的值可能随硬件状态变化,因此通常会用
volatile。 - 如果某个寄存器是只读状态寄存器,就可能写成
const volatile,意思是“程序不能写,但每次读都必须真的去读内存/寄存器”。
2. 指针和引用的区别是什么?函数传参时各自适合什么场景?
参考答案:
- 指针本质上存的是地址,可以为空,可以修改指向。
- 引用本质上是变量别名,定义时必须初始化,通常不能改绑定对象。
- 指针更适合: 可能为空的场景需要表达“可选对象”需要做地址运算或底层操作
- 引用更适合: 明确对象一定存在简化语法C++接口设计中表达“必传对象”
- 嵌入式里底层驱动、寄存器访问、缓冲区处理更常见指针;上层模块接口、类成员函数参数更常用引用。
3. malloc/free 和 new/delete 有什么区别?为什么嵌入式项目里常常限制动态内存分配?
参考答案:
malloc/free是 C 风格内存管理,只负责分配和释放原始内存,不会调用构造和析构。new/delete是 C++ 风格,除了分配释放内存,还会调用构造函数和析构函数。- 嵌入式项目常限制动态内存的原因: 容易产生内存碎片长时间运行后稳定性变差分配失败风险高实时性不好,分配时间不可完全预测
- 所以很多嵌入式系统会优先使用: 静态内存对象池内存池启动时一次性分配
4. 什么是函数重载、重写、隐藏?它们的区别是什么?
参考答案:
- 重载(overload):同一个作用域中,函数名相同但参数列表不同。编译期决定调用哪个函数。
- 重写(override):子类重新实现父类的虚函数,体现运行时多态。
- 隐藏(hide):子类定义了与父类同名函数,即使参数不同,也可能把父类同名函数隐藏掉。
- 区别核心: 重载看参数列表重写看继承 + 虚函数隐藏是名字屏蔽
二、数据结构与算法
5. 栈和队列的区别是什么?在嵌入式系统里各自常见于哪些场景?
参考答案:
- 栈是 LIFO,后进先出。
- 队列是 FIFO,先进先出。
- 栈常见于: 函数调用现场保存局部变量存储中断上下文切换
- 队列常见于: 任务间通信消息传递数据缓冲生产者消费者模型
- RTOS 里消息队列就是非常典型的队列应用。
6. 说一下链表和数组的优缺点。
参考答案:
- 数组优点: 连续内存,访问快,支持随机访问CPU cache 友好
- 数组缺点: 插入删除成本高长度通常固定,扩容麻烦
- 链表优点: 插入删除方便,只需改指针不要求连续内存
- 链表缺点: 不能随机访问额外指针开销cache 不友好,遍历效率低
- 嵌入式中如果资源紧张、追求确定性和访存效率,数组通常更常用;链表多用于任务管理、定时器链表、内核对象组织等。
7. 如何判断一个单向链表是否有环?
参考答案:
- 使用快慢指针。
- 慢指针每次走一步,快指针每次走两步。
- 如果链表有环,快慢指针最终会相遇。
- 如果快指针走到
NULL,说明无环。 - 时间复杂度
O(n),空间复杂度O(1)。 - 这是面试中非常经典的方法,也叫 Floyd 判圈算法。
8. 什么是时间复杂度 O(1)、O(logn)、O(n)?举例说明。
参考答案:
- 时间复杂度描述的是算法执行时间随数据规模增长的趋势。
O(1):常数时间,比如数组按下标访问。O(logn):对数时间,比如二分查找。O(n):线性时间,比如遍历数组。- 面试里重点不是背定义,而是能结合实
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
嵌入式面试八股文全集 文章被收录于专栏
这是一个全面的嵌入式面试专栏。主要内容将包括:操作系统(进程管理、内存管理、文件系统等)、嵌入式系统(启动流程、驱动开发、中断管理等)、网络通信(TCP/IP协议栈、Socket编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。


查看14道真题和解析