首先,我只找非Qt非后端的C++,所以要求降低,只需要
计算机网络 tcp 操作系统 cpp socket 多线程 内存管理 面向对象 设计模式 stl
gdb cmake git
收集到了很多面试题,也进行了简单的分类,接下来需要全部吸收,整理成自己的文档
首先需要把知识串联,先理一个大纲,逐步添加知识点,此文档记录所有面试问题,以及对应的口语化回答,所以重点在于得分关键词
我上份工作是 公交车载智能终端上的 Linux应用开发,熟悉Linux基本操作,了解C++应用的开发和调试流程,有网络编程和多线程开发的经验,还可以编写简单的脚本辅助开发。
八股
操作系统
1进程间通信:管道, 消息队列, 共享内存, 信号, 信号量, 套接字
2进程间同步:互斥锁, 读写锁, 条件变量, 信号量, 屏障, 记录锁
3线程间同步:互斥锁, 读写锁, 条件变量, 信号量, 屏障, 自旋锁
4
5P 申请资源 可能阻塞 V 释放资源 唤醒等待线程
6
7进程和线程的区别:
8 进程是资源分配的单位,线程是调度的单位
9 资源:进程拥有独立的地址空间,文件描述符,多个线程共享一个进程的资源
10 切换:进程 内核调度,上下文切换,内核态和用户态的切换,开销大
11 线程 栈 寄存器 程序计数器
12 通信:进程 IPC 数据共享和通信 慢,线程 共享资源 同步 快
13
14内核态 系统调用(软中断) 异常(文件损坏 缺页异常 内中断) 硬件设备(信号线通知CPU 硬中断)
15
16进程调度
17 先来先服务
18 最短作业优先
19 高响应比优先
20 时间片轮转
21 最高优先级
22 多级反馈队列
23
24页面置换
25 最佳页面(OPT)
26 先进先出(FIFO)
27 最近最久未使用(LRU)
28 时钟页面(Lock)
29 最不常用(LFU)
30
31系统调用
32 fork
33 socket bind listen accept select poll epoll
34 open read write close
35
36命令
37 文件目录 ls cd mkdir pwd cp mv rm
38 查看编辑 cat tail less more head vi
39 权限 chmod
40 网络 ip ifconfig ping netstat tcpdump
41 传输文件 ftp sftp scp wget curl
42 文本处理 awk sed cut sort wc
43 日志 dmesg journalctl
44 系统信息 ps top free env printenv uname uptime
45 进程 kill jobs fg bg
46 文件系统 mount umount df du
47 服务状态 systemctl status service
计算机网络
网络分层
1应用层 http https ftp smtp dns dhcp telnet ssh mqtt
2传输层 tcp udp quic
3 nat(网络地址转换)
4网络层 ip icmp(网络诊断ping) arp(ip到mac) ospf bgp
5 vpn(封装加密ip包)
6数据链路层 ethernet ppp vlan wifi mac
7物理层 网线 光纤 无线电信号
TCP三次握手
1- 客户端发 SYN, 请求连接 CLOSED → SYN_SENT
2- 服务端回 SYN+ACK, 确认并同步 LISTEN → SYN_RCVD
3- 客户端再回 ACK, 双方确认收发能力,连接建立 SYN_SENT/SYN_RCVD → ESTABLISHED
TCP四次挥手
1客户端发 FIN, ESTABLISHED → FIN_WAIT_1
2服务端回 ACK; ESTABLISHED → CLOSE_WAIT;客户端进入 FIN_WAIT_2
3服务端再发 FIN, CLOSE_WAIT → LAST_ACK
4客户端回 ACK,连接关闭 FIN_WAIT_2 → TIME_WAIT,等待 2MSL 后进入 CLOSED;服务端收到 ACK 后 LAST_ACK → CLOSED
cpp
RAII 把“资源申请”和“资源释放”都放进对象的生命周期里,用构造函数获取资源,用析构函数释放资源,这样就能避免忘记释放、异常中断导致泄露等问题
| 类别 | 关键字 / 语法 | 考点说明 |
|---|---|---|
| 变量与常量 | auto, const, constexpr, static, mutable | 类型推导、常量定义、静态变量作用域、可变成员 |
| 控制流 | if, switch, for, while, do, break, continue, goto | 条件判断、循环、跳转 |
| 函数 | inline, virtual, override, final, friend, explicit | 内联函数、虚函数重写、友元函数、构造函数防隐式转换 |
| 内存管理 | new, delete, delete[] | 堆分配与释放、数组与单对象区别 |
| 类型 | typedef, using, enum, enum class, typeid, decltype | 类型别名、枚举、RTTI、类型推导 |
| 类与对象 | class, struct, union, private, protected, public | 封装、访问控制、内存布局 |
| 模板 | template, typename, class | 泛型编程、模板类型参数、非类型模板参数 |
| 异常 | try, catch, throw, noexcept | 异常处理、异常规范 |
| 其他关键字 | namespace, using namespace, extern, volatile, register | 命名空间、外部变量、内存可见性 |
设计模式
工具
调试工具 gdb
| 分类 | 命令 | 说明 |
|---|---|---|
| 启动调试 | gdb ./a.out |
调试可执行文件 |
gdb ./a.out core |
调试 core dump | |
gdb ./a.out <pid> |
附加到进程 | |
| 运行控制 | run [args] |
运行程序并传参 |
start |
运行到 main |
|
continue / c |
继续运行 | |
next / n |
单步(不进函数) | |
step / s |
单步(进入函数) | |
finish |
运行到函数返回 | |
| 断点 | break main |
在 main() 设置断点 |
break file.cpp:42 |
在文件某行断点 | |
condition 1 x>5 |
给断点加条件 | |
delete 1 |
删除断点 | |
| 栈与线程 | backtrace / bt |
查看调用栈 |
frame n |
切换栈帧 | |
info threads |
查看线程 | |
thread 3 |
切换到线程 3 | |
| 变量与寄存器 | print x |
打印变量 |
display x |
每次停下打印 | |
watch x |
监视变量变化 | |
set var x=10 |
修改变量 | |
info registers |
查看寄存器 | |
| 查看源码 | list |
查看源代码 |
| 退出 | quit |
退出 gdb |
1(gdb) set follow-fork-mode parent # 默认:跟踪父进程
2(gdb) set follow-fork-mode child # 改成跟踪子进程
3
4(gdb) set detach-on-fork on # 默认:只跟踪一个,另一个继续运行
5(gdb) set detach-on-fork off # 父子都调试(GDB 会同时管理多个进程)
6
7(gdb) info inferiors # 列出所有进程
8(gdb) inferior 2 # 切换到子进程
9
10(gdb) set follow-exec-mode new # 跟踪 exec 之后的新程序
11
12gdb -p <child_pid> # 手动 attach
13(gdb) attach <child_pid>
调试工具 strace
| 分类 | 命令 | 说明 |
|---|---|---|
| 基本运行 | strace ./a.out |
跟踪系统调用 |
strace -p <pid> |
跟踪运行中的进程 | |
strace -o log.txt ./a.out |
输出到文件 | |
| 系统调用过滤 | strace -e openat ./a.out |
只跟踪 openat |
strace -e read,write ./a.out |
跟踪读写调用 | |
strace -e trace=network ./a.out |
跟踪网络调用 | |
strace -e trace=file ./a.out |
跟踪文件调用 | |
| 性能分析 | strace -c ./a.out |
统计调用次数/耗时 |
| 输出控制 | strace -s 100 ./a.out |
设置字符串长度 |
strace -f ./a.out |
跟踪子进程 |
版本控制 Git
| 命令 | 功能 | 示例 |
|---|---|---|
git init |
初始化本地仓库 | git init myproject |
git clone |
克隆远程仓库 | git clone https://github.com/user/repo.git |
git status |
查看当前状态(未提交、暂存等) | git status |
git add |
将文件加入暂存区 | git add file.txt / git add . |
git commit |
提交到本地仓库 | git commit -m "message" |
git push |
推送到远程仓库 | git push origin main |
git pull |
拉取远程更新并合并 | git pull origin main |
git branch |
查看/创建分支 | git branch / git branch feature |
git checkout |
切换分支或恢复文件 | git checkout dev / git checkout file.txt |
git merge |
合并分支 | git merge feature |
git log |
查看提交历史 | git log / git log --oneline --graph --all |
git diff |
查看差异 | git diff / git diff HEAD~1 |
git reset |
回退提交或重置文件 | git reset --hard HEAD~1 / git reset file.txt |
git stash |
暂存当前改动 | git stash / git stash pop |
tcpdump
| 命令 | 功能 | 示例 |
|---|---|---|
tcpdump |
默认抓所有接口的数据包 | tcpdump |
tcpdump -i eth0 |
指定抓取网卡 | tcpdump -i eth0 |
tcpdump -nn |
不解析主机名和端口名 | tcpdump -i eth0 -nn |
tcpdump -v / -vv / -vvv |
输出详细信息 | tcpdump -i eth0 -vv |
tcpdump -c 10 |
抓指定数量包 | tcpdump -c 10 -i eth0 |
tcpdump -w file.pcap |
抓包保存到文件 | tcpdump -i eth0 -w capture.pcap |
tcpdump -r file.pcap |
读取抓包文件 | tcpdump -r capture.pcap |
BPF
项目
1# 国标协议适配与设备平台对接
2
3这个项目是 公交车载智能终端的 国标化 通信协议 开发,我作为主要开发 负责 实现国标协议的整个通信流程,解耦原有的业务与协议,然后新增业务。同时参与了 需求分析和 任务拆分等 项目相关的工作。
4
5连接管理 / 协议层 / 适配层 / 业务层
6socket管理 I/O多路复用 拆包组包 消息队列(生产者消费者) 业务分发(协议层 继承多态) 注册回调的事件
7
8## socket管理
9 socket连接管理 TCP长连接 I/O多路复用
10 拆包组包(单元测试)状态机 断线重连 指数退避策略 消息持久化
11
12## 多线程消息处理
13 生产者-消费者模型 消息队列 队列满时阻塞等待 结合TCP流控 互斥锁+条件变量
14
15 Q: 为什么用多线程 + 消息队列?
16 A: 为了避免业务处理阻塞网络收发,采用生产者-消费者模式。确保实时性,和可拓展性
17 加分点: 这实际上是 Reactor 模式 的一个实现,常见于高并发网络编程。
18
19 Q: 为什么用多线程消息队列,而不是单线程?
20 A: 单线程也能跑,但业务处理可能阻塞接收。多线程分工,保证网络收发不被业务影响。
21 展开: 这是 生产者-消费者模型,用接收线程+发送线程,队列作为缓冲,避免阻塞。
22
23 Q: 消息队列满了怎么处理?
24 A: 采用阻塞等待,不丢弃消息。TCP 本身有流量控制,阻塞比丢弃更安全。
25 展开: 用 条件变量 + 环形队列,线程唤醒等待,避免忙等。
26
27 Q: 线程安全怎么保证?
28 A: 用互斥锁和条件变量,接收队列和发送队列分开锁,减少竞争。
29 展开: 可以说成 细粒度加锁,比全局锁更高效。
30
31## 协议层
32 单纯的继承
33
34 Q: 协议状态机是怎么优化的?
35 A:重写了 TCP 状态管理,采用有限状态机(FSM)。
36 展开:之前实现逻辑分散、易出错,我改为使用 FSM,每个状态(连接、鉴权、心跳、业务处理)有明确的事件驱动与迁移条件。
37 加分点:FSM 能提升代码可维护性,并减少异常情况下的分支错误。
38
39 Q: TCP 本来可靠,为什么还要做心跳?
40 A: TCP 只保证字节流可靠,但检测断开可能延迟。心跳能更快发现异常。
41 展开: 同时实现 TCP KeepAlive + 应用层心跳,兼顾 OS 层和业务层需求。
42
43 Q: 非法报文怎么处理?
44 A: 先校验校验字节,不合法就丢弃并发异常报文提醒平台。
45 展开: 保证客户端健壮性,不因平台错误报文影响终端运行。
46
47 Q: 断线重连怎么做的?
48 A: 根据心跳超时,自动重连,带退避策略,避免频繁重连。
49
50## 适配层
51 适配器模式 接口与私有协议业务兼容 不影响原功能
52 耦合是指私有协议的业务 从socket接收到数据之后直接就开始业务处理,然后调用发送接口直接发送了。
53
54 Q: 为什么要加适配层?
55 A: 避免协议层直接调用业务逻辑,保证原有业务不用改动。
56 展开: 协议解析和业务接口解耦,未来增加协议时,只需新增适配器。
57
58 Q: 为什么要做协议层和业务层解耦?
59 A: 原有协议和业务耦合严重,改协议需要大改业务,风险大。解耦后,协议变化只影响协议层,业务逻辑独立。
60 展开: 根据协议基础版本制定基类,不同地市通过继承扩展,适配层则用适配器模式屏蔽协议差异。
61
62 Q: 协议层和业务层的解耦是怎么做的?
63 A: 通过适配层实现解耦。
64 展开: 原私有协议与业务紧耦合(全局变量、单例静态依赖),我改为 显式传参,并抽象出适配层,使业务接口独立于协议层。这一思路接近 Adapter 模式 和 依赖倒置原则(DIP)。
65 加分点: 这样后续更换协议或新增业务接口时,只需扩展适配层,不必修改核心业务。
66
67## 业务开发
68 考勤 设备校时 车辆三检
69
70## 运维工具 Json转换
71
72 Q: 运维工具是怎么用的?
73 A: 支持把旧私有协议配置快速转换成国标配置,减少人工操作错误。
74 展开: 避免大量重构,降低了项目延期风险。
75
76 Q: 为什么要把二进制配置转成 JSON?
77 A: JSON 更可读,方便调试和扩展。
78 展开: 我还设计了 key 映射规则,保证配置项有统一命名。
79
80## 日志优化 基于zlog 调整日志格式 快速定位
81
82
83
84## 质量和优化
85 Q: 没有单元测试,怎么保证质量?
86 A: 协议层内置校验字节,保证报文合法性;同时日志优化,黑盒测试覆盖主要功能。
87 展开: 这是客观限制,但我通过 日志可追溯 + 协议校验 保证稳定性。
88
89 Q: 性能优化有哪些?
90 A: 队列多线程解耦避免阻塞,细粒度加锁减少竞争,协议状态机重构提升逻辑可靠性。
91 展开: 客户端流量不大,但架构上已为未来扩展做准备。
92
93 Q: 性能或稳定性挑战有吗?
94 A:主要是保障消息实时性与异常恢复。
95 展开:
96 采用 锁 + 有界队列 控制内存占用,避免消息积压。
97 在心跳机制和重连逻辑中,做了退避重试,确保网络波动下的稳定性。
98 压测结果显示,在常见车载场景下,延迟与丢包都在国标允许范围内。
99
100## 项目价值
101保证稳定性的前提下 快速完成协议对接 缩短交付时间
102架构清晰 扩展性强 统一了所有国标类协议代码 泰国定制
103
104## 项目经理职责 需求分析 风险评估 工时拆分
105虽然我不是正式项目经理,但在这个项目里,我除了开发,还参与了需求澄清、架构设计、任务拆解和风险评估,做了一部分项目管理的工作。
106
107在需求阶段,梳理了国标协议和私有协议的差异,明确了需要新增的业务,比如新的考勤、车辆三检等。
108
109在架构设计上,我提出分层方案:通信协议层只负责 TCP 连接、状态机和报文解析;适配层负责把国标报文转换为统一接口;业务层保持原有逻辑,方便维护。这样减少了耦合,也方便后续扩展。
110
111在开发阶段,我承担了超过 70% 的编码工作,包括 TCP 长连接、心跳与重连机制、收发分离的消息队列,以及协议状态机的重构。比如在收发处理上,我采用了生产者-消费者模型,把消息缓存到队列,避免业务处理阻塞网络收发。
112
113在风险控制方面,我设计了断线恢复和报文校验机制,并提前做了配置文件的转换工具,减少了上线风险。
114
115测试和上线环节,模拟平台,验证了掉线重连、异常报文丢弃、批量上报等场景,确保客户端在高并发和异常情况下稳定运行。
116
117 Q: 你提到承担了项目经理部分工作,具体包括哪些?
118 A: 我做过需求分析、架构设计、任务拆解和风险评估,并和平台方沟通技术问题。
119
120 Q: 你写了 70% 的代码,哪些是核心模块?
121 A: 协议层(TCP连接、协议解析/组包)、消息队列(收发线程)、适配层、新增业务接口。
122
123### 需求分析阶段 强调差异梳理 & 新增业务
124
125工作内容:
126 阅读国标协议文档(GB/T xxxx),与平台方确认业务范围。
127 梳理现有私有协议与国标差异,列出新增业务(如远程调度、配置下发、心跳机制)。
128 输出需求清单和优先级。
129示例:
130 平台要求终端支持“线路配置下发”,原系统未实现 → 我设计了 JSON 格式的线路配置,支持热更新。
131
132### 架构设计阶段 强调分层解耦 & 接口文档
133
134工作内容:
135 设计整体通信架构(TCP + 多线程消息队列)。
136 拆分为 连接管理层 / 协议层 / 适配层 / 业务层 四层,明确接口边界。
137 制定模块接口文档。
138示例:
139 协议层只负责收发与解析;适配层将国标报文转为业务 API 调用;业务层保持原有逻辑。
140 举例:校时请求 → 协议层解析字段 → 适配层封装 → 业务层调用调度接口。
141
142### 任务拆解与开发阶段 强调工时预估 & 核心开发
143
144工作内容:
145 根据模块拆分任务,进行工时预估。
146 分配任务:协议收发、状态机、配置解析、业务对接等。
147 自己承担核心开发(超过 70% 代码)。
148示例:
149 另一同事写了 TCP 连接模块,我发现状态机不健壮,重写为 FSM(有限状态机)。
150 开发中同步维护工时记录。
151
152### 风险评估与进度控制 强调预案 & 调整计划
153
154工作内容:
155 分析潜在风险:网络不稳定、协议实现歧义、平台兼容性。
156 提前制定预案:心跳重连、字段兼容、日志调试工具。
157 每周汇报进度,调整开发优先级。
158示例:
159 国标字段与私有协议字段对不上 → 我提出增加 字段映射表,避免硬编码,提升兼容性。
160
161### 测试与上线 强调端到端验证 & 异常场景
162
163工作内容:
164 编写单元测试(解析模块、状态机)。
165 搭建模拟平台,进行端对端联调。
166 协助 测试 制定测试场景:掉线重连、异常报文、批量位置上报。
167示例:
168 模拟 1000 条位置上报,验证消息队列不丢包。
169 在掉线场景下,确认 FSM 自动进入重连状态。
170
171### 维护与交付 强调文档 & 客户支持
172
173工作内容:
174 编写技术文档(协议对接说明、配置文件格式)。
175 支持后续 bug 修复与客户反馈处理。
176示例:
177 平台反馈部分配置解析失败 → 通过日志定位到 UTF-8 编码问题 → 修复文件解析器。
178
179# 设备状态自检模块开发
180
181没什么技术,作为部门项目,主要是推动了这个子系统的代码结构更新,对原系统的一个优化,是排查日志库的封装,解决了一个长期困扰的bug,然后重构了定时器。
182
183线程 最小时间间隔轮询
184最小堆 / 红黑树 + 系统接口
185时间轮
186
187# 笔试
188
189## 算法题
190
191排序算法
192 快速排序
193 归并排序
194 选择排序
195 冒泡排序
196
197红黑树
198- 红黑树是二叉排序树 左根右
199- 每个节点不是红色就是黑色 根叶黑
200 - 根节点一定是黑色
201 - 叶子结点(null)一定是黑色
202- 不允许存在两个相邻的红色节点 不红红
203- 从任意节点到达任一叶子结点的路径上黑色节点的数量相同 黑路同
204
205节点到叶子节点的最长路径不会超过最短路径的2倍
206
207## 场景题
208
209# 话术
210
211我写个最小化 demo,展示下 xxx 怎么用,实际项目中是要封装成 RAII 类来管理的
212
213## GAP
214
215这段时间对开发有更多方向上的探索,接触过开发后端和微服务的 golang( goroutine + channel),跨平台UI框架 flutter,主打 内存安全和高性能的 Rust (所有权机制),然后又回到C++,看过一些库的源码,不过很吃力(Redis Zset)。
216
217然后我大学室友 一起打比赛的 在自己创业,有和他一起做了很多尝试,后面主要是AIGC,套壳网站,视频翻译,视频创作。主要针对海外用户群体,他运营账号,打通一条 AI 全流程工具链。算是分红的方式吧,不多,变现方式也是在探索中,主要还是流量带来的广告收入。近半年他家里出了变动,前两月回老家了,暂时不搞了。
218
219这段经历让我接触并实践了多种技术栈,对软件开发的不同方向有了更全面的认识。但也正是在横向探索中,我意识到自己真正热衷并愿意长期投入的还是 C++ 及底层系统开发,因此更加坚定了未来在这一方向深耕的选择。
220
221涵盖了 大模型调用 到 多模态生成 并使用 comfyUI 等技术搭建过实际的工作流,同时也关注了 模型上下文协议 等新兴方向。
222
223大语言模型 transformer Chatgpt Claude Gemini
224扩散模型 diffusion 视频veo3 wan2.2 图像Nano Banana GPT
225python库 openai
226工作流 comfyUI
227后端 FastAPI
228提取字幕 whisper
229语音生成 TTS B站index-tts
230图像编辑 qwen-image
231上下文协议 MCP Context Engineering