文章

Linux/RTOS C++ 岗位面试知识图谱(由浅入深)

Linux/RTOS C++ 岗位面试知识图谱(由浅入深)

前言

如果你的目标岗位是 Linux/RTOS + C++ 开发(比如智能硬件、车载、工业控制、机器人、网络设备),面试一般不会只问“会不会语法”,而是会分层考察:

  1. 能不能写对(基础语法、内存安全、并发正确性)
  2. 能不能跑稳(实时性、资源受限、异常恢复)
  3. 能不能落地(调试定位、性能优化、工程化协作)

这篇文章按“由浅入深”的顺序整理高频知识点,并给出每层常见面试题与回答抓手。


1. 入门层:C/C++ 基础是否扎实

这一层是门槛。面试官关注你是否能写出可维护且不埋雷的代码。

1.1 指针、引用、const、volatile

高频追问:

  • const int*int* constconst int* const 区别?
  • volatile 能不能保证线程安全?
  • 为什么寄存器映射地址常配合 volatile

回答要点:

  • const 约束“谁可变”;
  • volatile 只保证“每次都从内存读写,不被编译器优化掉”,不保证原子性和同步顺序
  • 线程安全仍需要互斥锁、原子变量或内存序语义。

1.2 RAII、智能指针、对象生命周期

高频追问:

  • 为什么推荐 RAII?
  • unique_ptr / shared_ptr / weak_ptr 各自场景?
  • 为什么 shared_ptr 在实时线程中要慎用?

回答要点:

  • RAII 让资源释放绑定对象生命周期,异常路径也安全;
  • shared_ptr 有原子引用计数开销,时延敏感路径要评估;
  • RTOS/嵌入式常更偏向静态分配或对象池。

1.3 C++ 三/五法则、移动语义

高频追问:

  • 什么时候需要自定义拷贝构造、移动构造、析构?
  • 移动语义为什么能提性能?

回答要点:

  • 管理独占资源(文件句柄、socket、DMA buffer)时要显式定义;
  • 移动语义避免深拷贝,尤其对大对象和容器扩容收益明显。

2. 进阶层:Linux 系统编程核心能力

2.1 进程、线程、调度基础

高频追问:

  • 进程与线程本质区别?
  • 用户态线程和内核线程区别?
  • 上下文切换成本来自哪里?

回答要点:

  • 线程共享地址空间,切换成本通常小于进程;
  • 切换成本主要来自寄存器现场保存/恢复、缓存/TLB 影响、调度开销。

2.2 常见 IPC 与选型

必备:pipe/FIFO、消息队列、共享内存、socket、mmap

面试常问:

  • 低时延高吞吐为什么常用共享内存?
  • 共享内存为什么必须配合同步原语?

回答要点:

  • 共享内存绕过多次数据拷贝,吞吐高;
  • 但并发访问会有竞态,必须配锁/信号量/无锁队列。

2.3 I/O 模型与网络编程

高频点:阻塞/非阻塞、select/poll/epoll、边沿触发与水平触发、粘包拆包。

回答要点:

  • epoll 更适合大连接数;
  • ET 模式通常要求循环读到 EAGAIN
  • TCP 是字节流,需要应用层协议定义边界(长度字段或分隔符)。

2.4 Linux 内存与性能基础

高频追问:

  • 堆、栈、静态区区别?
  • 缺页异常是什么?
  • 什么是内存碎片,如何缓解?

回答要点:

  • 解释虚拟内存与页表;
  • 提到池化分配、对象复用、减少频繁小块申请释放。

3. RTOS 专项:实时系统面试核心

这是 Linux 应用岗与 RTOS 岗的主要分水岭。

3.1 软实时 vs 硬实时

高频追问:

  • 两者区别?
  • 硬实时系统最怕什么?

回答要点:

  • 软实时允许少量超时;硬实时强调 deadline 不可违反;
  • 最怕不可预测时延抖动,包括锁竞争、关中断过久、不可控内存分配。

3.2 任务调度与优先级

高频追问:

  • 抢占式调度与协作式调度区别?
  • 什么是优先级反转?怎么解决?

回答要点:

  • 抢占式响应更好但设计复杂;
  • 优先级反转:低优先级持锁阻塞高优先级,中优先级长期抢占;
  • 解决:优先级继承/优先级天花板协议

3.3 中断、底半部、任务分工

高频追问:

  • ISR(中断服务)里为什么不能做重活?
  • ISR 与任务线程怎么通信?

回答要点:

  • ISR 要尽量短,避免拉长中断关闭窗口;
  • 常见做法:ISR 只采样/置标志,再通过队列、信号量、事件组唤醒任务处理。

3.4 RTOS 内存管理策略

高频追问:

  • 为什么很多 RTOS 项目禁用运行时动态分配?
  • 固定块内存池优点?

回答要点:

  • 动态分配会带来不可预测时延和碎片;
  • 固定块分配时间可控,更适合实时场景。

4. Linux + RTOS 融合能力:岗位真正看重的部分

4.1 跨平台抽象设计

常见题:

  • 如何让同一业务逻辑跑在 Linux 和 RTOS 上?

回答框架:

  • 抽象 OSAL(OS Abstraction Layer),封装线程、锁、时间、队列;
  • 业务层只依赖接口,不直接绑具体系统调用;
  • 编译期通过宏/配置切换实现。

4.2 C++ 在嵌入式中的“可用边界”

常见题:

  • 在资源受限设备上,C++ 哪些特性慎用?

回答要点:

  • 谨慎异常、RTTI、过度模板膨胀;
  • 控制二进制体积与启动时间;
  • -ffunction-sections -fdata-sections + 链接裁剪无用符号(视工具链而定)。

4.3 可观测性与故障定位

常见题:

  • 线上卡死/高时延如何定位?

回答思路:

  1. 先分层:CPU 是否被抢满?是否锁等待?是否 I/O 堵塞?
  2. Linux 侧用 top/htop/vmstat/iostat/perf/strace
  3. RTOS 侧看任务栈水位、调度统计、事件追踪;
  4. 最后形成“复现条件 -> 根因 -> 修复 -> 回归指标”的闭环。

5. 面试高频综合题(建议背后的思路)

题 1:你如何设计一个“高优先级周期任务 + 低优先级日志任务”的系统?

可答:

  • 高优先级任务只做采集与关键控制;
  • 日志异步落盘,使用无锁环形队列或有界队列;
  • 队列满时启用降级策略(丢低优先级日志、保核心告警);
  • 全流程定义 deadline 与监控指标。

题 2:遇到偶发死锁怎么排查?

可答:

  • 拉线程栈 + 锁依赖关系;
  • 检查锁顺序是否一致、是否存在回调重入;
  • 缩小临界区,必要时拆分大锁;
  • 引入超时锁和死锁检测日志。

题 3:为什么你的系统“平均很快”,但偶发超时?

可答:

  • 实时系统看的是 worst-case latency,不是平均值;
  • 排查长尾:中断风暴、页缺失、锁竞争、内存回收、日志阻塞;
  • 给出 P99/P999 指标并基于 tracing 优化。

6. 面试准备路线(4 周版)

第 1 周:夯实 C/C++ + Linux 基础

  • 每天 1~2 小时:内存模型、并发基础、网络 I/O;
  • 手写:线程安全队列、定时器、简易 reactor。

第 2 周:RTOS 核心机制

  • 重点掌握任务调度、中断机制、同步原语、内存池;
  • 做一个小项目:传感器采集 + 控制任务 + 通信任务。

第 3 周:工程与排障

  • 学会使用 gdbperfstrace、core dump 分析;
  • 整理 3 个“线上问题复盘故事”(问题现象、定位过程、修复结果)。

第 4 周:模拟面试 + 项目表达

  • 准备 2 分钟项目电梯陈述;
  • 每个项目都能讲清楚:
    • 技术选型为什么这样做
    • 遇到什么困难
    • 如何量化结果(CPU、内存、延迟、稳定性)

7. 一份可直接复述的“自我介绍模板”(节选)

我主要做 Linux/RTOS 下的 C++ 开发,负责过多线程并发、设备通信和实时任务调度。项目里重点优化过任务时延和资源占用,比如把关键路径从动态分配改为内存池,P99 延迟下降明显;同时通过锁拆分与队列异步化降低了主线程阻塞。定位问题时我会结合 Linux 工具链和系统日志做分层排查,确保修复可验证、可回归。


结语

如果你准备的是 Linux/RTOS C++ 相关岗位,建议不要把复习停留在“背答案”。真正拉开差距的是:

  • 你能否解释底层机制;
  • 你能否把机制映射到真实工程问题;
  • 你能否给出可验证的优化与稳定性结果。

当你能把“原理、代码、指标、复盘”讲成一个完整闭环,面试通过率通常会有明显提升。

本文由作者按照 CC BY 4.0 进行授权