奇瑞汽车嵌入式软件一面:从自我介绍到 const、数组退化与 RTOS 调度
- 轮次
- 一面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 先做一下自我介绍,重点讲讲和嵌入式相关的经历?
- 本科成绩大概什么水平?平时用得最多的语言是哪些?
- 简历里挑一个最能体现能力的项目,讲讲整体架构和你的分工?
- C 里
const int *p、int * const p、const int * const p分别限制什么? - 传数组进函数后,为什么经常说「数组退化成指针」?这对长度计算有什么影响?
- 裸机程序和跑 RTOS 的单片机程序,调度方式差在哪里?
《参考解析》
自我介绍按「四段式」组织,控制在 1 到 2 分钟:第一段给硬信息(学校、专业、求职方向,明确到嵌入式软件或车载软件);第二段讲 1 到 2 个代表性项目,每个说清用了什么 MCU/平台、自己负责哪一层、最终结果是什么;第三段按层次列技术栈(C/C++、外设驱动、RTOS/Linux、通信协议、调试手段),这样面试官知道该往哪个方向追问;第四段落到求职动机,为什么投这家、想做车载嵌入式的哪一块。细节留给追问,不要在自我介绍里把整个项目讲完。
成绩和主力语言这两问是在确认基础。成绩可以说专业排名区间,或者核心课的成绩(C 语言、数电、计算机组成原理、操作系统);主力语言一般就是 C,因为嵌入式驱动、协议栈、裸机与 RTOS 代码都靠它。有 C++ 就补上智能指针、RAII、少量面向对象封装;脚本语言可以提 Python 和 Shell,用来说明日志解析、自动化测试、烧录脚本这类活你干过。这里有一个措辞上的分寸:强调「用过」和「写过项目」的区别,不要把只会语法说成精通,嵌入式面试官很爱顺着这个往下问。
项目讲解要有可验证的结果。顺序是:一句话概括项目目标(某个外设采集、通信网关、OTA、诊断或控制系统)→ 画清架构(应用层、中间件/协议、驱动、硬件接口分别是什么)→ 明确自己负责的模块(接口设计、时序、缓冲、错误处理、和谁联调)→ 讲关键难点(实时性、丢包、重入、内存占用、启动时序)→ 给出可验证的结果(吞吐、延迟、稳定性、覆盖率或量产联调结论)。最后这一项最容易漏,但它是「你真的做过」和「你只是看过」的分界线。
const 的三种写法看 * 和 const 的相对位置:const int *p 是「指向常量的指针」,不能通过 p 修改所指的值,但 p 本身可以改指向;int * const p 是「指针常量」,p 不能改指向,但可以改 *p;两者都 const 则指向和内容都不能改。函数参数里最常用的是第一种,表示只读访问,防止误改调用方的数据。这里可以补一句深度:const 变量的存储位置和链接属性要一起看,放在 Flash 里的常量区和放在 RAM 里的 const 变量,语义不同。
数组退化的本质是函数参数传递的是首地址。C 里函数参数写 int a[] 实际等价于 int *a,传的是数组首元素的地址,不是整个数组对象。所以在函数内对参数做 sizeof(a) 得到的是指针大小(32 位是 4、64 位是 8),不是原数组的总字节数。要知道元素个数,必须额外传一个 len,或者用结构体把数组和长度包在一起。二维数组的退化规则更绕——int a[3][4] 作为参数退化成 int (*)[4],第二维不能省。字符串处理时还要分清 sizeof 和 strlen:前者是对象占的字节数(含结尾的 \0,如果数组是按字符串初始化的),后者数到 \0 为止。
裸机与 RTOS 的调度差别,核心在「谁决定下一个执行谁」。裸机是前后台结构:中断处理紧急事件、置标志,主循环轮询标志并依次处理,任务的执行顺序由代码的书写顺序决定,本质是协作式的、没有抢占。RTOS 则由调度器按优先级决定:每个任务有独立栈和优先级,高优先级任务就绪就能抢占低优先级任务,任务通过阻塞(等信号量、等延时、等队列)主动让出 CPU。由此带来几个工程上的差别:裸机里长任务会拖慢所有响应,RTOS 里要给每个任务分配合理的优先级和栈大小;裸机共享变量靠关中断保护,RTOS 里还要考虑任务间的优先级反转(用带优先级继承的互斥量);裸机没有栈溢出的概念(只有一个栈),RTOS 每个任务一个栈,栈溢出会踩坏相邻内存且极难排查。