NiceOffer

面试面经 · 懂车帝

【懂车帝】【Agent 开发】【暑期实习一面】面经(八股+大模型项目+手撕)

懂车帝面经Agent 开发实习

懂车帝 Agent 开发 暑期实习一面

背景:海外一年制硕士,之前有一段大模型应用相关的项目经历,投递方向为 Agent 开发。

题目摘要

  1. Go 语言基础:goroutine 与 channel 的使用场景、GMP 模型简述、内存逃逸分析
  2. MySQL/Redis 八股:索引失效场景、MVCC 原理、Redis 持久化机制与缓存穿透解决方案
  3. Agent 项目深挖:RAG 检索优化、Function Calling 的容错设计、上下文窗口管理策略、推理成本控制
  4. 手撕算法:实现一个带过期时间的 LRU Cache(LeetCode 460 变体)

项目深挖

面试官在项目深挖环节连环追问了约 20 分钟,节奏很快,每个回答都会引出下一个问题。核心围绕我的一个「汽车资讯问答 Agent」项目展开。

追问一:你的 RAG 检索结果直接拼进 prompt,如果检索到的内容与用户问题无关,怎么处理?

参考回答方向:首先明确这属于检索质量而非生成问题。我的方案是三层过滤——第一层用 embedding 相似度阈值(0.75 以上才进入候选);第二层用 LLM 做相关性打分(让模型输出 0-10 分,低于 6 分丢弃);第三层在 prompt 中显式加入「如果以下参考内容与问题无关,请直接回答不知道」的指令。同时,系统会记录低分检索案例并定期分析,找出是分词问题还是 embedding 模型覆盖不足,针对性优化。

追问二:Function Calling 场景下,如果模型选错了工具或者参数格式错误,你的 Agent 怎么处理?

参考方向:需要区分「模型理解错」和「工具执行失败」两种情况。模型选错工具时,我会让模型先输出一个 intent 判断结果,只有置信度高于阈值才真正调用工具,否则进入澄清流程反问用户。参数格式错误则依靠 JSON Schema 校验,失败后把错误信息返回给模型并附上正确的参数示例,让模型自我纠正。面试官比较认可这个设计,但追问了「如果模型连续两次纠正都失败呢?」——这时应当降级为人工兜底或直接告诉用户暂时无法处理,避免死循环消耗 token。

追问三:上下文窗口有限,长对话中历史消息怎么管理?

参考方向:我用了分层策略——最近 5 轮对话完整保留,更早的消息用摘要压缩存储(每 10 轮做一次总结),系统级指令和工具定义固定占用前缀位置。面试官追问「摘要本身也是 token 成本,怎么控制」,我回答会设置摘要触发的轮次阈值和摘要长度上限,并定期清理不再需要的中间摘要。另外,针对懂车帝场景,用户通常只关心某一款车型的具体参数,所以会做意图识别,只提取与当前问题相关的历史片段注入上下文,而不是全量拼接。

手撕算法:带过期时间的 LRU Cache

题目:设计一个数据结构,支持 get(key) 和 put(key, value, ttl) 操作,其中 ttl 为过期时间(毫秒),过期后 get 返回 -1。要求 get 和 put 的平均时间复杂度为 O(1)。

关键思路:核心是「过期」和「淘汰」两个维度的叠加。基础结构用哈希表 + 双向链表实现 LRU。过期处理有两种方案——惰性删除(get 时检查时间戳)和主动清理(后台协程扫描)。面试时我先给出惰性删除的方案,因为代码量最少且不影响主流程时间复杂度。主动清理需要额外的优先队列或时间轮,面试官点头后我就没再深入。实现时注意双向链表的虚拟头尾节点可以简化边界判断,哈希表的 value 需要同时存数据、过期时间戳、链表节点指针三个字段。因为题目要求 ttl 是 put 时传入的,所以每个节点的过期时间不同,不能全局统一。写完后面试官问了一个 follow-up:如果同一个 key 被重复 put,旧节点的过期时间怎么处理?答案是直接覆盖并更新链表位置,旧节点会被 GC 回收。

准备建议

三条具体建议,按优先级排序:

  1. Go 语言必须能讲清并发模型。Agent 开发岗位对 Go 的要求不低,面试官直接问 GMP 模型和 channel 的底层实现。建议把《Go 语言设计与实现》的并发章节精读两遍,配合 LeetCode 上 channel 相关的并发题(如交替打印、协程池)实操。如果投递方向偏 Java,则把 ConcurrentHashMap 的 CAS + synchronized 演进和 ThreadLocal 的内存泄漏问题吃透。
  1. Agent 项目要准备「失败案例」。面试官一定会追问你项目中哪里做得不好、怎么改进的。建议提前梳理 2-3 个具体问题,比如检索不准、工具调用超时、token 超预算等,每个都要有「现象 → 原因分析 → 解决方案 → 效果对比」的完整链路。不要只说「我用了 RAG」,要说清楚为什么用、基线是多少、优化后提升多少。
  1. 手撕题按「变体题」准备。LRU 本身是高频题,但加了过期时间就变成 Medium 偏 Hard。建议把 LeetCode 146、460、895 三道题都刷熟,同时理解它们之间的演进关系——基础 LRU → LFU → 带过期时间的变体。面试时先给出最简单的可行方案再逐步优化,比一开始就写复杂实现更稳妥。

结果反馈

一面持续约 50 分钟,手撕算法完成后十分钟内收到二面通知,间隔两天。

想系统备战大厂大模型/Agent 开发?NiceOffer 提供 SDE+LLM 双轨 1v1 陪跑,合同保底 40w 年薪,文末扫码咨询。