面灵AI→

海信嵌入式技术面:C/C++ 八股 + 项目细节

轮次
技术面
时间
2026-10
来源
牛客网

《面试题目》

  1. 自我介绍
  2. C 语言函数传参是值传递还是引用传递?
  3. C 语言传递数组怎么传递?
  4. C++ 多态如何实现?虚函数如何实现?
  5. 用过哪些智能指针?
  6. unique_ptr 和 shared_ptr 的区别,使用场景分别是什么?
  7. 知道什么排序算法?它们的复杂度是什么?
  8. 什么时候选择归并排序而不是快速排序?
  9. 迭代器遍历时可能出问题,为什么会导致出问题?
  10. 进程和线程的区别?
  11. 线程共享进程的哪些资源?
  12. 怎么避免死锁?
  13. 互斥锁和信号量的区别?
  14. 项目开发遇到问题如何调试?
  15. rk3566 与 ws63 如何进行同步?
  16. 云端服务器的作用?
  17. 用的 HTTP 还是 HTTPS?
  18. HTTPS 客户端与服务端通信的大致流程?

《参考解析》

C 语言只有值传递,数组「传递」传的是首元素地址:形参永远是实参的副本,指针形参传的也是地址这个值,所以函数内改 *p 能影响外部、改 p 本身不能。数组作为参数会退化为指向首元素的指针,函数内 sizeof(arr) 拿到的是指针大小而不是数组长度,因此必须额外传长度,或用「结构体包数组」「指向数组的指针 int (*p)[N]」来保留长度信息;字符串用 char * 加 \0 约定。追问常落在 const char * 与 char * const 的区别、以及返回局部数组地址为什么是未定义行为。

多态与虚函数要答到实现机制:C++ 运行时多态靠虚函数表——含虚函数的类在对象里放一个 vptr,指向该类的 vtable,调用虚函数时通过 vptr 查表间接跳转;构造函数里虚表尚未就绪,所以构造/析构中不体现多态,析构函数应声明为 virtual 以免基类指针删除派生对象时漏析构。追问会延伸对象内存布局、override/final、纯虚与抽象类、以及 RTTI 与 dynamic_cast 的代价。智能指针方面:unique_ptr 独占所有权、零额外开销、可移动不可拷贝,用于明确单一归属的资源,默认首选;shared_ptr 共享所有权、靠引用计数,代价是控制块、原子操作和循环引用风险(用 weak_ptr 打破),用于生命周期确实需要多方共管的场景;weak_ptr 不增计数,用来观察与破环。

排序算法的取舍得说出条件:快排平均 O(n log n)、原地、常数小、缓存友好,最坏 O(n²)(可通过随机化基准或三数取中缓解),不稳定;归并排序稳定、最坏也保证 O(n log n),代价是 O(n) 额外空间;堆排序 O(n log n) 原地但不稳定且缓存不友好;插入/冒泡 O(n²) 适合小规模或近乎有序。选归并的场景是:需要稳定排序、数据规模大且对最坏情况有硬性时限、外部排序(内存放不下需要多路归并)、或链表排序(无需额外空间)。嵌入式里还要考虑代码体积、栈深度与实时性,qsort 的比较函数开销也常被追问。

迭代器失效源于容器重分配或元素搬移:vector 扩容会重新分配内存,所有迭代器、指针、引用全部失效;erase 会让被删位置之后的迭代器失效,所以「边遍历边删除」的经典写法要改成 it = v.erase(it)。deque 在首尾插入可能使部分迭代器失效,list/map/set 只有被删元素的迭代器失效。另外还有一类是逻辑错误而不是容器机制:迭代过程中修改容器导致迭代器越界、以及 end() 在循环中被反复求值导致的条件错乱。答这一题最好的方式是举一个你实际踩过的例子,并说清修复写法。

进程线程与同步机制是嵌入式岗的必考区:进程有独立地址空间,是资源分配单位;线程共享进程的地址空间,是调度单位,切换代价小但一个线程崩溃会拖垮整个进程。线程间共享代码段、数据段(全局与静态变量)、堆、文件描述符与信号处理,只有栈、寄存器上下文、线程局部存储(TLS)和 errno 是私有的——共享什么正是竞态的根源。避免死锁的通用做法是破坏四个必要条件之一:统一加锁顺序、用 try_lock 加超时、一次性申请全部资源,再配合锁粒度尽量细、临界区不做阻塞调用、以及用无锁队列或消息传递替代共享内存。互斥锁强调「所有权与保护临界区」,同一线程可重入问题要看具体实现;信号量是计数器,可用于资源计数和线程/中断间的通知,不一定有所有者,所以能在中断里 give 而不能在中断里拿互斥锁。

项目类问题按「架构—数据流—调试」组织答案:rk3566(Linux 应用处理器)与 ws63(Wi-Fi/蓝牙 MCU)之间的同步,本质是异构双芯通信——常见链路是 UART/SPI/SDIO 或 socket(Wi-Fi 透传),协议要有帧头、长度、序号与校验,同步靠「请求应答 + 序号去重 + 超时重发」,可靠性要求高时加事务确认与状态机。云端服务器的作用通常是设备管理(注册、鉴权、OTA)、数据汇聚与转发、以及远程控制指令下发的通道。HTTP 与 HTTPS 的取舍要看场景:内网调试常用 HTTP,对外一律 HTTPS。HTTPS 大致流程是 TCP 握手后做 TLS 握手——客户端发 ClientHello(支持的版本与密码套件、随机数),服务端回 ServerHello 和证书,客户端校验证书链与域名、生成预主密钥并用公钥加密传输(或走 ECDHE 协商),双方用随机数与预主密钥导出对称会话密钥,之后用对称加密传输数据并做完整性校验;面试里能说出「非对称只用于握手,数据用对称」就抓住了重点。调试方法论则要给出层次:先复现与定位范围(硬件/驱动/应用),再用日志、示波器、gdb/core dump、strace、抓包逐层收敛,最后写清复现条件与回归验证。