华为后端开发岗面经合集:C++ 编译、TCP 与 RAG 基础
- 轮次
- 多轮面试合集
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
面经 01(10 月 15 日)
- 手撕:左上到右下路径数目(递归实现)。
- C++ 编译产物及编译过程。
- 各个数据库的区别(运用到工程部署怎么选择)。
- 有没有用过 agent?
- 手撕:二分查找。
- 有没有感到迷茫的时候?
- 为什么选择就业而不是继续深造?
面经 02(9 月 24 日)
- 五层架构,举出各个层的协议。
- HTTP,还有哪些类似的协议?
- 磁盘和内存的区别。
- 堆和栈的区别。
- 请介绍 RAG 的基本原理。
- 为什么免笔试?
- 为什么不考研?
- 你目前的代码能力如何?
面经 03(9 月 22 日)
- TCP 建立和断开连接的过程是什么?
- 你如何理解进程和线程?
- C++ 代码如何经过编译生成二进制文件?
- 什么是线程池?为什么要使用线程池?
- 请介绍你用过的数据类型。
- 写代码时如何验证功能?代码出错后如何调试?
- 你用过哪些抓包工具或 API 调试工具,例如 Postman?
- 你了解哪些代码规范?
- 手撕:独一无二单词(哈希集合)。(原帖在此处被截断)
《参考解析》
1. 路径数目与二分查找。 左上到右下、只能向右/向下走,dp[i][j] = dp[i-1][j] + dp[i][j-1],边界第一行/第一列都是 1,时间 O(mn)、空间可压到 O(n)。面试要求「递归实现」时写出 f(i,j) = f(i-1,j) + f(i,j-1),并说明朴素递归会重复计算、复杂度指数级,加记忆化后 O(mn);如果格子有障碍就把该点置 0。二分查找要写对边界:while (l <= r)、mid = l + (r - l) / 2 防溢出、根据 nums[mid] 与 target 的关系收缩,找不到返回 -1;变体(第一个 ≥ target、最后一个 ≤ target)要能说清 l = mid + 1 / r = mid - 1 的选择。
2. C++ 编译过程。 四个阶段:预处理(展开宏、包含头文件、条件编译,产出 .i)→ 编译(词法/语法/语义分析、优化,生成汇编 .s)→ 汇编(转成机器码目标文件 .o,含符号表与重定位信息)→ 链接(合并目标文件与库,解析符号,生成可执行文件或动态库/静态库)。要能区分静态链接(把库代码拷进可执行文件,体积大但不依赖)与动态链接(运行时加载 .so,体积小但要处理版本与路径),以及 -O2、-g、-fPIC 这些常用选项的作用。
3. 数据库选型。 关系型(MySQL/PostgreSQL)适合强事务、结构化查询、复杂 join;KV(Redis)适合缓存、会话、计数;文档型(MongoDB)适合结构多变的 JSON;列式(ClickHouse/Doris)适合大规模分析与聚合;搜索(Elasticsearch)适合全文检索与日志;向量库(Milvus/pgvector)适合语义检索;时序库(InfluxDB/TDengine)适合监控指标。工程选型看四点:数据模型与查询模式、一致性与事务要求、写入/读取的量级与延迟、运维成本与团队熟悉度。常见组合是「MySQL 存业务主数据 + Redis 做缓存 + ES 做搜索 + ClickHouse 做报表」,而不是一个库打天下。
4. 网络分层与协议。 五层:物理层(比特传输)、数据链路层(以太网、ARP、PPP)、网络层(IP、ICMP、路由协议)、传输层(TCP、UDP、QUIC)、应用层(HTTP/HTTPS、DNS、FTP、SMTP、SSH、WebSocket、gRPC)。HTTP 之外常被问到的类似协议:HTTPS(HTTP + TLS)、HTTP/2(多路复用、头部压缩、二进制分帧)、HTTP/3(基于 QUIC/UDP,减少握手延迟)、WebSocket(全双工长连接)、gRPC(HTTP/2 + Protobuf, RPC 场景)。回答时把「协议解决什么问题、在哪个层、依赖谁」讲清楚,比背端口号有用。
5. 磁盘、内存、堆、栈。 磁盘是持久化、容量大、随机读写慢(毫秒级),内存是易失、容量小、纳秒级,二者之间靠页缓存和 mmap 缩小差距。堆是进程运行时动态分配的内存(malloc/new),生命周期由程序控制,碎片和泄漏都出在这里;栈是函数调用时自动分配,存放局部变量、参数、返回地址,大小有限(默认几 MB),溢出就是 stack overflow。要补一句:栈的分配/释放是移动栈指针,极快;堆要经过分配器查找空闲块,慢且有碎片。
6. RAG 原理。 检索增强生成:把外部知识离线解析、切分、向量化后存进向量库;在线时把用户问题向量化,召回最相似的若干片段(常配合关键词检索和重排),拼进提示词让模型基于这些片段作答,并要求给出来源。它解决的是模型知识过期、私有数据不可见、以及幻觉不可控的问题;效果取决于切分质量、召回质量和提示词约束,工程上要分别评测,并处理「检索不到」时的兜底(明确说不知道,而不是编)。
7. TCP 与进程线程。 建立连接三次握手(SYN、SYN+ACK、ACK),断开四次挥手(FIN、ACK、FIN、ACK),因为 TCP 是全双工,两个方向要分别关闭;主动关闭方最后进入 TIME_WAIT 等待 2MSL,确保最后一个 ACK 能到达、并让旧连接的重复报文失效。进程是资源分配单位(独立地址空间),线程是调度单位(共享进程资源、独立栈和寄存器),协程是用户态调度、切换成本更低。线程池预先创建线程复用,避免频繁创建销毁的开销,并统一控制并发度、队列和拒绝策略,防止把下游打挂。
8. 调试、工具与规范。 验证功能先写清预期(输入、输出、边界),再用单测覆盖正常/边界/异常三类,跑通后做集成验证;调试手段包括打印日志、断点、gdb/lldb、valgrind 查内存、strace 看系统调用、以及二分定位(注释掉一半代码/回滚提交)。抓包用 Wireshark/tcpdump,接口调试用 Postman/curl,抓 HTTPS 要配证书。代码规范常见的有命名(驼峰/下划线统一)、函数长度、圈复杂度、错误处理(不许吞异常)、资源管理(RAII)、注释解释「为什么」而不是「是什么」;团队里通常用 clang-format、clang-tidy、lint 和 code review 固化。
9. 手撕:独一无二单词。 用哈希集合统计每个单词出现次数,再按顺序取第一个计数为 1 的;或者两次遍历:第一次建频次表,第二次找第一个频次为 1 的字符/单词。注意大小写、标点与空串的处理,时间复杂度 O(n)、空间 O(n);如果要求 O(1) 额外空间且字符集有限,可以用固定大小数组代替哈希表。