面试面经 · 华为
【华为】【Agent 开发】【暑期实习一面】面经(八股+大模型项目+手撕)
海外一年制硕士,投递华为 2012 实验室下属的 Agent 方向暑期实习,笔试后约一周收到一面通知,全程 60 分钟,技术 50 分钟 + 反问 10 分钟,面试官是团队里做 Agent 平台的后端。
题目摘要
- Go 语言基础:slice 底层结构与扩容规则、map 并发安全问题、
defer执行顺序与返回值陷阱、goroutine 泄漏的常见场景 - MySQL / Redis 八股:聚簇索引与回表、
EXPLAIN关键字段、事务隔离级别与 MVCC 可见性判断;Redis 缓存穿透/击穿/雪崩的区分与各自解法、分布式锁的续期问题 - Agent 项目深挖:RAG 检索链路的分段策略与召回评估、Function Calling 的工具描述设计与参数校验、多轮对话的上下文窗口管理、推理成本与延迟的优化手段
- 手撕算法:LRU 缓存(LeetCode 146),要求手写双向链表 + map,并说明为什么不用 Go 的
container/list
一面题目细节
Go 部分问得比预期细。先问 slice 扩容:Go 1.18 之后小于 256 是翻倍,大于等于 256 是按 1.25 倍左右增长并做内存对齐,追问「扩容后原数组的修改会不会影响新 slice」——答不会,因为底层数组已经换了,但如果没触发扩容就是共享的,这个点面试官明显在等我踩坑。
defer 那题给了个带命名返回值的函数,问最终返回值。关键结论:return x 不是原子操作,先给返回值赋值、再执行 defer、最后真正返回,所以 defer 里改命名返回值会生效。这题答对了,面试官没继续追。
goroutine 泄漏问的是「起了一个带 context.WithTimeout 的 goroutine 去请求下游,超时后 goroutine 一定会退出吗」。正确答法是:只有下游调用本身接受 context 并响应取消才会退出,如果是阻塞在 channel 接收或 time.Sleep 上,照样泄漏。
MySQL 问了聚簇索引,追问「为什么建议用自增主键而不是 UUID」。要点是 UUID 随机插入导致页分裂和碎片,自增主键顺序写入、页填充率高。Redis 问了缓存击穿,我答了互斥锁 + 逻辑过期两种方案,面试官追问「逻辑过期方案里,异步重建失败怎么办」——这块我答得一般,说了降级返回旧值和加告警,面试官补了一句「还要考虑重建任务的幂等」。
项目深挖是重头。我简历上写了一个基于 RAG 的代码问答 Agent,面试官顺着问了三个层次。
项目深挖
追问一:你的分段策略是什么,怎么验证分段没把语义切碎?
参考回答方向:不要说「按 512 token 切」就完事,要讲清楚切分依据——按 Markdown 标题层级做语义切分,超长段落再按句子边界二次切分,并保留 chunk 的父级标题作为元数据拼进 embedding。验证方式上,构造一组「答案跨 chunk 边界」的评测 query,看召回是否命中,如果命中率低说明切太碎,考虑加 overlap 或做父子块检索(小块召回、大块喂给模型)。
追问二:Function Calling 的工具多了以后,模型选错工具怎么处理?
参考回答方向:先分层——工具描述层面,把 name 和 description 写清楚边界,description 里明确「什么时候用、什么时候不用」,参数用 JSON Schema 加 enum 约束;工程层面,工具数量超过 20 个时不要全量塞进 prompt,先做一轮工具检索(按 query 召回 Top-K 工具)再给模型选;兜底层面,模型返回的参数做 schema 校验,校验失败把错误信息回灌给模型重试一次,仍失败则走规则路由。
追问三:多轮对话上下文越来越长,成本和延迟怎么控?
参考回答方向:分三层讲。一是裁剪,保留 system prompt + 最近 N 轮 + 历史摘要,中间轮次用模型压缩成摘要;二是缓存,system prompt 和工具定义这类固定前缀走 prompt caching,能省掉重复的 prefill;三是路由,简单意图(打招呼、确认类)走小模型或不走模型直接规则处理,只有复杂推理才调大模型。可以补一句「我们线上统计过,压缩后 token 消耗降了大概 40%」,但别编具体数字,说个量级即可。
手撕算法:LRU 缓存。题意是设计一个容量为 capacity 的缓存,支持 Get 和 Put,两者都要 O(1)。关键思路是哈希表存 key 到链表节点的映射,双向链表维护访问顺序,头部是最近使用、尾部是最久未用。Get 命中后把节点移到头部,Put 时若 key 存在则更新并移到头部,不存在则新建插头部,超容量就删尾节点并从 map 里移除。面试官要求手写双向链表而不是用 container/list,理由是「想看你指针操作熟不熟」。写完跑了两组用例,边界是 capacity=1 的情况。
准备建议
- Go 别只背语法,把 runtime 层面的坑过一遍。重点看 slice 扩容、map 并发写 panic、channel 关闭后的读写行为、context 取消的传播路径。这几个是华为 Go 岗的高频区,且都喜欢追问「为什么」。
- Agent 项目要能画出完整链路图,并给每一环准备一个「如果这里出问题怎么办」。面试官不会满足于「我用了 RAG」,他会问分段、召回评估、rerank 有没有上、工具调用的失败重试、上下文超限的降级。提前把链路上每个节点的失败模式列出来,比背八股有用。
- 八股按「为什么这么设计」组织,而不是背结论。比如 MVCC 不要只背 read view,要能说清楚 RC 和 RR 下 read view 生成时机的差异,以及这个差异如何导致不可重复读。手撕题把 LRU、LFU、TopK、合并区间这几道限时 15 分钟内写完,练到手熟。
反问环节我问了团队现在 Agent 主要落地在什么场景、实习生会不会独立负责模块,面试官说主要做运维和研发效率方向的 Agent,实习生会跟一个 mentor 做完整需求。
一面通过,三天后约了二面。
想系统备战大厂大模型/Agent 开发?NiceOffer 提供 SDE+LLM 双轨 1v1 陪跑,合同保底 40w 年薪,文末扫码咨询。