C++ 岗多公司面经合集:笔试、八股与项目拷打
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 【世炬网络·笔试】图的遍历。
- 【世炬网络·笔试】某个进程占用大量内存,如何排查?
- 【世炬网络·笔试】某个模块很慢,如何解决?
- 【世炬网络·笔试】实现一个消息队列(伪代码描述)。
- 【世炬网络·笔试】空间不足的情况下,对一个链表进行排序(伪代码描述)。
- 【世炬网络·面试】看你做的东西,哪里做得不对,就让你讲哪里。
- 【世炬网络·面试】讲一讲工作经历。
- 【世炬网络·面试】讲一讲自己的项目。
- 【新威尔电子】new、delete 与 malloc、free 有什么共同点和区别?
- 【新威尔电子】封装、继承、多态说一下。
- 【新威尔电子】内存泄漏是什么?怎么排查?
- 【新威尔电子】怎么查一条 MySQL 查询结果的条数?
- 【新威尔电子】怎么对查询结果排序?
- 【新威尔电子】怎么对一个 float 和 0 做比较?
- 【新威尔电子】struct 和 class 有什么共同点和区别?
- 【新威尔电子】谈一谈你对 union 的理解。
- 【新威尔电子】指针和引用的区别是什么?
- 【新威尔电子】函数传参有哪几种方式?
- 【新威尔电子】结构体里有 char、int、double、float 四个变量,这个结构体的大小是多少?
- 【新威尔电子】64 位计算机上,int、double、float 各占几个字节?
- 【新威尔电子】指针数组和数组指针的区别是什么?各自 +1 会有什么结果?
- 【华汉伟业·笔试】选择题:技术相关但范围很杂,包含浏览器渲染等与 C++ 无关的内容。
- 【华汉伟业·笔试】填空题:看图找规律。
- 【华汉伟业·笔试】编程题:给定链表结构,实现指定 index 的插入操作。
- 【华汉伟业·一面】vector 和 list 的底层数据结构是什么?各自的使用场景?
- 【华汉伟业·一面】sizeof 相关:32 位系统下
char str[] = "hello"的 sizeof(str)、void fun(char str[100])里的 sizeof(str)、char *p = str的 sizeof(p)、sizeof(char)、sizeof(int) 分别是多少? - 【华汉伟业·一面】map 的底层数据结构是什么?怎么实现查找?
- 【华汉伟业·一面】lambda 的优缺点是什么?
- 【华汉伟业·一面】Qt 信号和槽的机制是怎么样的?
- 【华汉伟业·一面】讲一下你的项目。
- 【华汉伟业·一面】Modbus 是一个怎么样的协议?你怎么理解?
- 【华汉伟业·二面】自我介绍。
- 【华汉伟业·二面】辞职后的这三个月在做什么?
- 【华汉伟业·二面】在公司里做什么?是否涉及核心业务开发?
- 【华汉伟业·二面】工作不忙吗,还有空做自己的项目?
- 【易点云】你的项目做了哪些功能?
- 【易点云】hook 是怎么实现的?
- 【易点云】你用协程管理项目,那 socket 不需要重新连接吗?
- 【易点云】项目里的连接池是怎么实现的?
- 【易点云】讲一下你过往公司里的经历。
- 【易点云】八股(内容偏基础)。
- 【视开智能·视觉软件开发】自我介绍。
- 【视开智能·视觉软件开发】简历里写了 OpenCV:如果有一个小物体太小检测不到,怎么办?有没有自己的思路?
- 【视开智能·视觉软件开发】和上位机、机械配合时出了 bug,你怎么调试并确定不是上位机的问题?
- 【久益信息·C++游戏服务端】讲一下你的项目。
- 【久益信息·C++游戏服务端】为什么济南的 offer 没有接?
- 【久益信息·C++游戏服务端】能不能接受加班?
- 【灼视科技】一个矩阵里有红色不规则方块,怎么标出它的外接矩阵?
- 【灼视科技】指针和引用的区别?
- 【灼视科技】const 放在指针前后有什么区别?
- 【灼视科技】struct 和 class 有什么区别?
- 【灼视科技】堆和栈有什么区别?
- 【灼视科技】一个矩阵求它的膨胀矩阵:对每个元素以它为中心取 3×3 小矩阵,小矩阵里所有数填充为其中的最大值,需要几个 for 循环?每个 for 循环的边界是什么?
- 【橙子便利店·管培生(AI 数字化)】之前的工作内容是什么?为什么离职?
- 【橙子便利店·管培生(AI 数字化)】其他部门的人员对 AI 接受度不高、不愿意用你改进的工具,怎么办?
- 【橙子便利店·管培生(AI 数字化)】其他部门对 AI 热情很高、你忙不过来,怎么决定先做哪个?
- 【橙子便利店·管培生(AI 数字化)】加班接受程度、薪资接受程度?
《参考解析》
sizeof 三连:数组退化、对齐与补齐:char str[] = "hello" 的 sizeof(str) 是 6——数组名在 sizeof 里不退化,字符串字面量初始化的数组含结尾的 '\0'。真正高频的坑是函数参数:void fun(char str[100]) 里的 str 已经退化成 char *,sizeof(str) 就是指针大小(32 位 4、64 位 8),传 100 也不改变这一点,所以函数内想拿数组长度必须另传参数或改用 std::array/容器。char *p = str 的 sizeof(p) 同理是指针大小。结构体的大小按「成员对齐 + 尾部补齐」算:32 位下 char 按 1 字节、int 4、double 8(若按 8 对齐)、float 4,char 后补 3 字节、double 后为让整个结构体大小是最大对齐数的整数倍再补 4 字节,合计 24;只要调换成员顺序结果就变(把 double 放最前面常常更省),这正是面试官想考的点。再往上追问会问 #pragma pack 的作用(压紧对齐,代价是可能的非对齐访问开销)和 64 位下的差异(指针 8 字节,对齐规则按平台 ABI)。
vector 与 list 的底层结构与使用场景:vector 是连续内存的动态数组,随机访问 O(1),尾插均摊 O(1),中间插入删除要搬移元素 O(n),扩容时按倍数重新分配并搬移,会让所有迭代器、指针和引用失效;它的优势是内存连续带来的缓存友好和预取效率,实际性能常常优于理论复杂度更好的结构。list 是双向链表,已知位置的插入删除 O(1),不支持随机访问,每个节点多两个指针的内存开销,节点分散导致缓存命中差。选择上:绝大多数场景优先 vector,需要频繁在中间插入删除、或者要求「插入后已有的迭代器与引用保持有效」(对象池、LRU 链表、观察者列表)才用 list;splice 可以 O(1) 拼接两个链表,这是它独有的能力。面试常追问「遍历时删除元素」怎么写(vector 用 erase 的返回值或 remove_if,list 用 it = erase(it))、以及 deque 的定位(分段连续,两端插入删除 O(1)、支持随机访问)。
map 的底层结构与查找:标准要求的是平衡二叉搜索树,主流实现用红黑树。查找从根开始按 key 比较大小决定走左还是右,复杂度 O(log n);插入删除后通过旋转和变色恢复平衡,保证树高在 2log(n+1) 以内。红黑树的性质要能说全:节点非红即黑、根为黑、红节点的子节点必为黑、任一节点到其所有叶子的路径上黑节点数相同。常追问与 AVL 的取舍(AVL 更严格平衡、查询略快,但插入删除旋转更多,红黑树在读写混合场景更均衡)、与 unordered_map 的区别(哈希表平均 O(1) 但无序、不支持范围查询、rehash 会让迭代器失效)。map 的独有价值正是有序:中序遍历天然有序、支持 lower_bound / upper_bound 做区间查询和「第一个不小于」的查找,所以有顺序或范围需求时选 map,纯点查选 unordered_map;自定义类型做 key 要提供严格弱序的比较(map)或哈希与相等(unordered_map)。
Qt 信号与槽的机制:核心是元对象系统。带 Q_OBJECT 宏的类会先经 moc(元对象编译器)扫描,生成 moc_*.cpp,里面包含信号函数的实现、静态元对象数据和 qt_metacall 的派发代码——信号函数本身没有函数体,它的实现是 moc 生成的(这也是「信号只需要声明、不需要定义」的原因)。emit signal(args) 本质上是一次普通函数调用,内部通过元对象索引找到已连接的槽并按连接类型分发:DirectConnection 在发射线程里同步调用,QueuedConnection 把调用打包成事件投递到接收者线程的事件循环里异步执行,AutoConnection 按发射线程与接收者线程的亲和性自动选择,BlockingQueuedConnection 则跨线程阻塞等待返回。默认的 Auto 让跨线程通信天然安全,代价是排队参数必须是元类型(自定义类型要先 qRegisterMetaType)。要补充的几个点:槽函数执行在哪个线程由接收者对象的线程亲和性决定,不是由发射者决定;QObject 析构时会自动断开所有连接,所以父子对象生命周期管理得当就不会回调到野指针;重复 connect 会导致槽被调用多次,可用 Qt::UniqueConnection 防重;信号槽比回调慢在索引查找与可能的排队,但解耦和线程安全的收益通常更值。
Modbus 协议怎么理解:它是工业现场常用的主从(客户端—服务器)模式应用层协议,报文核心是 PDU(功能码 + 数据),常用的功能码是 01/02/03/04 读线圈与寄存器、05/06 写单个、15/16 写多个。承载方式不同就派生三个版本:RTU 走串口,二进制编码加 CRC16 校验,靠 3.5 个字符时间的静默间隔分帧;ASCII 用可读字符加 LRC;TCP 走以太网,加一个 MBAP 头(含事务标识、协议标识、长度、单元标识),默认端口 502。理解它的心智模型是「四张表」:线圈(可读写布尔)、离散输入(只读布尔)、输入寄存器(只读 16 位)、保持寄存器(可读写 16 位),每个从站地址各自独立编址,主站轮询、从站不应答或回异常码。工程实现的坑集中在:地址偏移(文档里 40001 与协议 0 基地址差 1)、寄存器是大端且 32 位量要拼两个寄存器(还分高低字顺序)、超时与重试策略、多个从站在同一条链路上必须串行轮询、以及异常码 0x83/0x02 这类回包要解析出来而不是当成超时。C++ 侧可以直接用 libmodbus,也可以自己按帧头长度解析——面试里能讲清「主从、四张表、三个版本、地址与字节序坑」就足够有说服力。