项目
自用别看
AI 应用开发岗 · 面试实战手册
这份文档怎么看(先读这半页)
这份文档的做法是:
- 按真实对话流组织,而不是按知识树组织。面试官问完 A 大概率接 B,我用
→ 他会接着问标出来。 - 每题标命中概率:🔥🔥🔥 = 几乎必问 / 🔥🔥 = 高概率 / 🔥 = 可能被问。时间不够就只准备 🔥🔥🔥。
- 只保留能区分人的题,砍掉 60 道左右伪问题(清单见附录 C,说明为什么砍)。
- 新增一个专区(第 4 章),放那些项目文档里没有、但从你简历字面就能推出会被问的题。
风险标记:🔴 已知硬伤或口径矛盾,必须提前准备 | 🟡 需要你本人确认,我没法替你确定 | 🟢 有据可查,照说即可
第 0 章 · 面试真实流程还原
先建立时间感。一场 35 分钟的面试,面试官的注意力大概这么分配:
0–3 min 自我介绍 + 你挑一个项目讲 → 1 个问题3–18 min 深挖 AI 智能编程助手(和你岗位最对口) → 6–8 个问题,层层下钻18–25min 快扫 go-zero 内容平台 → 3–4 个问题,只问关键点25–32min 基础抽查(Go / Redis / Kafka / SQL) → 3–5 个问题,每个 1 分钟32–35min 反问 → 你提问推论(很重要):
- 面试官问完一个问题后, 是从你的回答里挑一个词继续问。所以他问什么,很大程度上由你说什么决定——这是你可以主动引导的。
第 1 章 · 开场(3 分钟,决定后面 30 分钟他往哪挖)
🔥🔥🔥 「做个自我介绍 / 挑一个项目讲讲」
结构固定,别自由发挥:
面试官好,我是xxx,xxxx大学 27 届本科生,xxxxx专业,CET-6。我投的是 AI 应用开发岗。
课外我做了两个比较完整的项目。第一个是 AI 智能编程助手,Go 写的,五层微服务。核心是一个双模式 ReAct 推理引擎,配 AST 符号图和混合检索做代码理解,再加一条自动校验流水线兜底模型生成的代码质量。
第二个是 go-zero 微服务内容平台,网关加 gRPC 微服务,重点在 Canal+Kafka 的缓存同步链路和压测验证。
我比较想做的是把模型能力和工程系统结合落地这件事,希望能在真实业务里继续提升。
然后——关键动作——用结尾那句话给面试官递钩子:
其中我对 AI 助手这个项目花的时间最多,这块我可以展开讲。
面试官 90% 会顺着你指的走。 开场就把战场定在你最熟的地方,这是唯一你能完全控制的环节。
第 2 章 · 项目一:AI 智能编程助手(主战场 15 分钟)
一句话定位(先记住这个,所有回答都从它展开):
一个能读代码库、改代码、并且自动验证改得对不对的 Agent。 五层:Gateway(WebSocket 接入)→ Agent(ReAct 推理)→ Code Intel(代码理解)/ Tools(动手执行)/ Validation(事后校验)。
2.1 🔥🔥🔥 第一问一定是:「展开讲讲这个项目」
答 90 秒,按”链路 + 两个我最在意的点”结构:
链路是这样:前端 WebSocket 连到 Gateway,Gateway 转 gRPC 调 Agent。Agent 跑 ReAct 循环,每一轮的事件(thought / action / tool_output)通过 gRPC server-streaming 推回前端。
循环里需要理解代码时调 Code Intel,需要动手时调 Tools,改完代码自动触发 Validation 流水线回灌结果。
两个我比较在意的点: 一是 ReAct 做了 双模式——Native Tool Calling 为主,JSON Prompt 兜底,并且对畸形 LLM 返回做了降级,我构造的 5 组畸形输入都能安全降级成 finish、零 panic; 二是代码理解不是纯靠向量,而是 AST 符号图 + BM25 + pgvector 三层组合,301 符号的仓库建图约 1ms。
这一答里你主动抛出了 5 个可下钻的点:双模式 ReAct、畸形返回降级、AST 符号图、混合检索、1ms。 下面四问就是从这五个词里长出来的—— 你是主动的。
2.2 🔥🔥🔥 「双模式 ReAct 是什么?两种有什么区别?」
| Native Tool Calling | JSON Prompt 兜底 | |
|---|---|---|
| 触发条件 | 模型支持 function calling | 模型不支持 / 返回解析失败 |
| 解析方式 | 直接读结构化 ToolCall | 从文本里抠 JSON,要容错 |
| 结束信号 | 模型不返回 tool_call | 模型输出 {"action":"finish"} |
| 可靠性 | 高 | 依赖 prompt 约束 + 解析容错 |
循环骨架(他要是让你画,就这么画):
用户输入 → 组装 messages(system prompt + 历史 + 工具定义) → for i := 0; i < 10; i++ { // maxIterations = 10 ① 调 LLM → 解析出 thought/action/args ② action == finish → 退出,返回 done 事件 ③ 否则执行工具 → 结果作为 ToolMessage 追加回 messages ④ 本轮事件通过 stream 推回前端 }为什么要有兜底:不是所有模型都稳定支持 Tool Calling。兜底保证弱模型也能跑通—— 这是可用性兜底,不是性能优化。
→ 他会接着问:「那怎么防止死循环?」
防死循环的四层(要能一口气说完):
- 硬性迭代上限
maxIterations = 10,超了强制返回 done - System Prompt 约束:「Do not call tools unnecessarily」
- 工具报错时把错误作为 ToolMessage 喂回去,让模型自己改策略或放弃
- JSON 模式的
finish动作,允许模型主动结束
主动说出来很加分——目前缺的四层:重复调用检测(相同参数 hash)、进展评估(连续几轮无新信息则终止)、Token 预算、滑动窗口(消息历史无限增长会撑爆上下文)。
2.3 🔥🔥🔥 「『5 组畸形 LLM 返回』具体是哪 5 组?怎么降级的?」
🔴 这题是全简历最危险的一题。 你写了”5 组”和”零 panic”,报不出具体是哪 5 组,这一行的可信度直接归零。
先说结论(这个定位很重要):
目标是**「零 panic」而不是「100% 把事做对」**——宁可安全降级成 finish,也不能让服务崩。
五组典型畸形(现在就去核对你当时记录的用例,写成逐字稿):
| # | 畸形形态 | 降级处理 |
|---|---|---|
| 1 | 参数被多包一层:{"args":{"path":"main.go"}} | 检测 len(args)==1 && args["args"] 是 map → 解包一层 |
| 2 | JSON 不合法 / 被 markdown 代码块包住 / 截断半截 | 容错提取(去代码块标记、找首尾括号)→ 失败则降级 finish |
| 3 | 工具名不存在(幻觉工具名) | 注册表查不到 → 返回错误 ToolMessage 让模型重试 → 超限则 finish |
| 4 | 缺必填参数 | 参数校验失败 → 返回明确错误让模型补 → 超限则 finish |
| 5 | 纯文本无 action 字段(兜底模式解析不出 JSON) | 视为 finish,把文本作为最终回复 |
零 panic 是怎么保证的(这句话要背):
所有 JSON 解析都带 error 分支、所有 map 取值都做带
ok的 type assert、不对 nil 做解引用。降级路径统一是:解析失败 → 记录事件 → 不再重试同一畸形输入 → 返回 finish 并说明「无法完成」。
→ 他会接着问(这题是项目里最真实的坑,答好非常加分):
2.4 🔥🔥 「LLM 返回的参数不对,你是怎么排查的?」
用 STAR 讲,这个故事是你项目里最值得讲的一段:
- S:Agent 调工具频繁报参数缺失,一开始我以为是模型不稳定。
- T:定位根因,而不是靠重试掩盖。
- A:在 NativeReActLoop 里打印
tc.Function.Arguments的原始值,发现模型返回的是{"args":{"path":"main.go"}},而工具期望{"path":"main.go"}。往上追溯,发现是convertRegistryTools给所有工具定义了一个通用 schema{"args":{"type":"object"}}—— 模型没错,它严格照着我的 schema 生成的,是我的 schema 写得不好。 改法是双管齐下:①toolParams为每个工具精确定义参数 schema,逐个声明类型和 Required;② 加防御性解包作为安全网。 - R:工具调用成功率明显提升,并且形成了一条原则 👇
金句(收尾用):
LLM 工具调用的可靠性 = 参数 schema 的精确性 + 防御性的参数处理。
2.5 🔥🔥🔥 「代码检索为什么既用 BM25 又用向量?」
| BM25(关键词) | 向量(语义) | |
|---|---|---|
| 匹配方式 | 精确 token | 语义相似 |
| 典型场景 | 查 handleError 的定义 | 查「处理数据库连接错误的代码」 |
| 速度 | 内存计算,毫秒级 | 要调 embedding 模型,慢 |
| 弱点 | 不懂同义词、跨语言表述 | 会召回语义相关但不精确的结果 |
组合策略:BM25 先粗召回(top 100)→ 向量做语义补充与精排 → 合并去重 → 综合分数排序。
一句总结: 精确查找靠 BM25,模糊意图靠向量,互补而非替代。
→ 他会接着问:「那 BM25 为什么自己实现,不用现成的?」
答:① BM25 核心公式不复杂(TF 饱和 + IDF + 长度归一化),自己实现可控无依赖;② 针对代码场景做了分词适配(驼峰/下划线切分),通用分词器对标识符不友好;③ 索引常驻内存,毫秒级检索,不需要为一个公式引入 ES。 但主动补一句:规模上去后自实现 BM25 缺分布式和持久化能力,那时候应该换 ES 或专用引擎。
2.6 🔥🔥 「符号图怎么构建的?301 符号 1ms 是什么量级?」
- 流程:遍历仓库 → 按语言选解析器(Go 用
go/ast,Python 用正则/ast模块)→ 提取符号(函数/类型/变量/导入)→ 建节点 → 建边。 - 4 类关系边: calls(调用)、 imports(依赖)、 defines(定义)、 uses(引用)。
- 存储:内存图 +
sync.RWMutex。读多写少——Search 走读锁可并发,IndexFile 走写锁会阻塞所有检索。 - 性能:301 个符号的仓库建图约 1ms,折算约 21 万符号/秒。
🔴 这题有个埋雷,见第 4 章 4.3——为什么不用 tree-sitter。
🟡 诚实补充:这是单机小规模实测,未做多轮统计和预热。规模上去后解析是 O (文件数),内存索引会先成为瓶颈(100 万文件时不可行,需要持久化 + 分片)。
2.7 🔥🔥 「校验流水线跑哪些检查?『召回率 100%』是什么意思?」
流水线结构:Agent 生成/修改代码后,自动调 Validation.Validate(聚合 RPC,一次请求内部跑完多类检查再统一返回)。
检查项 5 类: 静态检测(lint)、类型检查、单元测试、安全漏洞扫描、LLM 专业评审。
关键工程点(这段最能体现真实做过):不同工具的 stdout 格式完全不同——Go test 的 --- FAIL、pytest 的 summary、golangci-lint 的 file:line:col: msg、gosec 的输出——所以为每一类写了独立的 输出解析器,统一成结构化 Issue{File, Line, Severity, Message},再作为 ToolMessage 回灌给 Agent,形成「生成 → 校验 → 反馈 → 再生成」闭环。
🔴 「召回率 100%」必须自己先拆自己的台:
这里要先澄清口径:它指的是 对解析器的召回率——我本地构造的 N 个已知故障样例,被解析器正确识别出来的比例。 不是 「流水线能发现所有 bug」。 局限也要说:样本是我自己构造的,不是真实分布;样本量也不大。真实场景下工具版本差异、非英文 locale、超长输出都可能导致解析失败。
为什么这条流水线有价值(收尾句):
不信任模型的自述,只信任可执行验证的结果。用确定性的工具结果去对冲 LLM 的不确定性。
2.8 🔥🔥🔥 「这个项目最大的缺点是什么?」
🔴 主动承认比被追问出来强十倍。 按这个顺序说,把最致命的放前面:
- 索引不持久化——Code Intel 的符号图和 BM25 索引全在内存,服务重启全丢,冷启动要重建全仓库。
- 无认证、无命令沙箱——RunCommand 直接把模型生成的命令交给 shell,这是最大的安全短板。
- Python 解析用正则不严谨——只覆盖常见语法形态,遇到装饰器嵌套、多行字符串等会失真。
- 上下文无管理——消息历史全量塞给模型,长任务会撑爆上下文窗口。
- 缺少集成测试——有单元测试(AST/BM25/graph/patch/各解析器),但没有跨服务端到端测试,也没有 LLM mock 测试。
→ 他会接着问:「那如果重做,你会改什么?」
答(五个方向,正好对应上面五个缺点): ① 索引持久化到 PostgreSQL/Redis ② 加 JWT 认证 + 命令白名单 + 路径沙箱 + 危险操作人工确认 ③ 换 tree-sitter 统一多语言解析 ④ 加上下文管理(滑动窗口 + 历史摘要)⑤ 补集成测试、metrics、分布式追踪。
2.9 🔥🔥 「五层微服务,对这个项目是不是过度设计?」
🔴 这题答好不容易, 准备一个两分钟版本:
- 先承认:对一个个人项目,五层微服务确实偏重。
- 再讲为什么还是这么做了:
- 异构负载——Tools(跑测试/跑命令,分钟级重 IO)和 Agent(等 LLM,长阻塞)资源特征完全不同,拆开后可以独立设超时、独立扩容;
- 故障隔离——命令执行是最危险的一环,单独成服务便于将来加沙箱,崩了不带崩 Agent;
- 技术验证目的——这个项目本身就是为了把微服务 + gRPC 流式的完整链路跑通。
- 收在务实的一句:
如果重做,我会先做成模块化单体——Go 的 package 边界先划清楚,等真的出现独立扩容或隔离需求再拆进程。* 拆分应该由真实痛点驱动,而不是一开始就按理想架构画。*
2.10 🔥 「有没有什么题你想主动说的?」
如果面试官问「你还有什么想补充的」,说这两个,都是加分项:
- 多 provider 容灾:Agent 层通过 Eino 抽象了多个模型厂商,某个 provider 不可用可以切到另一个(🔴 前提是你确实实现了——
[A37]提到支持扩展新 provider,去核实一下是否真的做了运行时切换,没做就不要说”容灾”,改成”接口上具备切换能力”)。 - 安全降级优先于功能完整:整个项目的设计取向是「宁可安全降级,也不 panic」,这在生产系统里比”功能多”更重要。
项目一 · 必背数字
| 数字 | 口径 | 备注 |
|---|---|---|
| 5 层微服务 | Gateway / Agent / Code Intel / Tools / Validation | 🔴 与「4 个 gRPC」口径要统一 |
| 双模式 ReAct | Native Tool Calling 为主 + JSON Prompt 兜底 | |
| maxIterations = 10 | 死循环硬上限 | |
| 5 组畸形返回 → 降级 finish,零 panic | 🔴 要能当场报出哪 5 组 | |
| 8 类工具 | 🔴 要能报出 8 个名字 | |
| 4 类关系边 | calls / imports / defines / uses | |
| 301 符号 ≈1ms(≈21 万符号/秒) | 单机小规模实测 | 🟡 折算口径要自己确认 |
| 召回率 100% | 解析器对构造故障样例的召回率 | 🔴 必须自曝口径 |
第 3 章 · 项目二:go-zero 内容平台(8 分钟,快进快出)
定位先想清楚:这个项目在你这场面试里只值 8 分钟。它证明的是 工程落地能力,不是 AI 能力。所以准备 8 题就够,别在这上面耗时间。
一句话定位:网关 + gRPC 微服务的内容平台,重点在缓存一致性和压测验证过的性能。
3.1 🔥🔥🔥 「简单讲讲这个项目」
一句话: 一个文章 content 平台,重点在微服务拆分和数据同步链路。 网关层用 go-zero 的 REST 承接 HTTP,内部 article / user 等 RPC 服务用 gRPC 通信,etcd 做服务发现。 核心难点是缓存一致性:我没有在业务代码里同步更新缓存,而是用 Canal 监听 MySQL binlog 推到 Kafka,消费者异步重建 Redis 缓存。压测下来 gRPC 层平均 2ms,HTTP 网关 8.85ms,部署在 K8s 上带 Prometheus + Grafana 监控。
3.2 🔥🔥🔥 「为什么用 Canal + Kafka,而不是业务代码里直接更新缓存?」
🔴 这题是项目二的核心,必问。
- 解耦:业务代码只管写 DB,缓存维护交给独立链路。双写会让「写 DB + 写缓存」变成分布式事务问题,且每处新增写逻辑都要记得同步改缓存,极易漏。
- 可靠:binlog 是 MySQL 的事实日志,任何写入(包括人工改库、别的系统写入)都能捕获,不会漏。
- 削峰:Kafka 承接写入尖峰,消费者按自己节奏消费(实测生产者 3.7 万条/s,10 万条消费后 LAG 归零,说明消费能力跟得上)。
- 代价: 最终一致,存在约 200ms 的窗口期。
3.3 🔥🔥🔥 「缓存和数据库的一致性怎么保证?」
完整链路:业务写 MySQL → binlog → Canal(伪装成 MySQL slave 拉取)→ Kafka(按主键分区,保证同一行变更有序)→ 消费者根据变更类型决定 更新/删除/失效缓存 → Redis。
🔴 「删缓存还是更新缓存」是必考八股,必须答对:
删除(失效)优于更新。 ① 更新缓存要构造完整的缓存对象,可能涉及多表聚合,成本高还容易算错; ② 并发写时两个线程先后更新可能乱序,导致缓存里留下旧值; ③ 删除是幂等的,重复删除无害; ④ 删了之后下次读自然回源重建(懒加载)。 例外是热点极高的 key——删了之后瞬间大量回源,这种情况用
SingleFlight合并回源请求(go-zero 的CachedConn内置了)。
缓存三兄弟(也要能一口气说完):
| 问题 | 现象 | 你的做法 |
|---|---|---|
| 击穿 | 热点 key 过期瞬间大量请求打穿到 DB | CachedConn 内置 SingleFlight,同 key 并发回源只放行一个 🟢 |
| 穿透 | 查根本不存在的 id,缓存永不命中 | 🟡 若没实现就承认,给方案:缓存空值(短 TTL)或布隆过滤器 |
| 雪崩 | 大量 key 同时过期 | 🟡 若没实现就承认,给方案:TTL 加随机抖动 |
200ms 窗口内的脏读:这是最终一致性的固有代价。应对——强一致场景走读主库;给缓存加版本号对比 binlog 位点;内容平台对 200ms 延迟不敏感,业务上可以接受。
3.4 🔥🔥🔥 「压测数据怎么来的?环境是什么?」
🔴 这题决定你那四个数字可不可信。
必须能说清的四件事(现在就补上):
- 机器配置(CPU 核数 / 内存 / 是否容器 / MySQL 和 Redis 是否同机)
- 测的是哪几个接口(如果是文章详情/列表读接口,要明说——读多写少场景)
- 数据集规模(多少篇文章 / 缓存预热了没有)
- 工具参数(ghz 压 gRPC、wrk 压 HTTP,并发 50–100,持续 30s)
数字背后的解释(必考):
| 现象 | 原因 |
|---|---|
| HTTP 8.85ms 比 gRPC 2.00ms 慢 4 倍 | ① 多一跳网络(API 层 → RPC 层)② JSON vs Protobuf 序列化 ③ 中间件链(JWT/校验/限流/日志/trace)④ HTTP/1.1 无多路复用 |
| QPS 反而更低(1.22 万 vs 2.14 万) | 同样因为多一跳 + JSON + 中间件;且一个 API 请求可能扇出调用多个 RPC(article-rpc 拿文章 + user-rpc 拿作者) |
| P99 是平均值的 3 倍 | 长尾来自 GC 停顿、连接池争抢、Redis 网络抖动、日志写盘、容器 CPU 限流。平均值掩盖长尾,所以同时报 P99 是正确的做法——这句主动说,说明你会看数据 |
🟡 主动降调:并发 50–100 属于中低并发,这个数字是 单机读场景下的结果,不是全站容量。
3.5 🔥🔥 「命中率 100%(1.7 万次读 0 miss)怎么测的?」
🔴 又是一个必须自曝口径的数字:
口径是:在 热点文章集合上,压测期间共 1.7 万+ 次读请求,无一次回源到 MySQL。 三个前提要说清:① 是 热点文章(已预热/已访问过),不是全量随机;② 是 读请求,写入路径仍走 MySQL;③ 压测窗口内缓存未被主动失效。 真实场景下冷启动、缓存失效窗口、Redis 重启都会产生 miss—— 100% 是特定压测场景下的结果,不是常态 SLA。
3.6 🔥🔥 「Redis 挂了会怎样?」
- 表现:读请求全部回源 MySQL,DB 压力陡增甚至被打垮。
- 降级方案:① 熔断——缓存错误率超阈值时快速失败,而不是全打到 DB;② 限流——保护 DB 只放部分流量;③ 本地缓存兜底一份热点;④ Redis 集群 + 哨兵保证高可用。
- 🟡 如实区分”我已经做了”和”这是我的方案”。
3.7 🔥🔥 「密码为什么用 MD5?」
🔴 诚实是唯一正确的答法,不要辩解:
当时为了简单,用 MD5 是错的。 问题在于:MD5 是快哈希,加 GPU/彩虹表可以在很短时间内反查;而且我当时没有加 salt,相同密码的哈希值一样。 生产应该用 bcrypt / argon2——它们自带随机 salt、是慢哈希(可调工作因子,能随硬件升级提高成本)、天然抗彩虹表。 迁移方案:新用户直接 bcrypt;老用户在下次登录时用明文密码重新计算 bcrypt 并写回,逐步完成迁移。
顺带把项目二的其他技术债一起说了(显得有全局观):无数据库事务(改成最终一致 + 幂等 + 重试)、pkg/ 公共包职责混杂、JWT secret 硬编码在配置里、测试覆盖不足。
3.8 🔥 「为什么用 go-zero 而不是 Gin / Kratos?」
- 一体化:
goctl从.api/.proto一键生成 API 层、RPC 层、model 层代码,省掉大量样板。 - 内置治理:熔断、限流、超时、自适应降载、
SingleFlight——这些在 Gin 里都要自己接。 - 缓存与 DB 一体:
sqlc.CachedConn把「查缓存 → 未命中查 DB → 回写缓存」封装进 model 层。 - 可观测:内置 OpenTelemetry 链路追踪、Prometheus 指标。
项目二 · 必背数字
| 数字 | 口径 |
|---|---|
| gRPC 2.00ms / P99 4.88ms / 2.14 万 QPS | 并发 50–100、30s、直打 RPC 层 🟡 补环境 |
| HTTP 8.85ms / P99 26.81ms / 1.22 万 QPS | 经 API 网关 |
| 成功率 99.99%+ | 🟡 能说清失败请求是什么错 |
| 命中率 100%(1.7 万+ 读 0 miss) | 热点文章 + 压测窗口内 |
| 同步延迟 ≈200ms | binlog → Redis 端到端 |
| Kafka 3.7 万条/s(18MB/s) | 生产者吞吐 |
| 10 万条消费后 LAG 归零 | 消费能力跟得上 |
第 4 章 · 🔴 项目文档里没有、但几乎必问的 10 题
这 10 题不是从代码里长出来的,是从 你简历的字面矛盾里长出来的。项目文档推演不出它们,但面试官看得出来。 这一章的优先级高于前面所有章节。
4.1 🔥🔥🔥 「ClaudeCode、Cursor、Codex 都这么成熟了,你为什么还要自己做一个 AI 编程助手?」
🔴🔴🔴 命中率最高的题。 你简历同时写了”熟练使用 ClaudeCode、Codex”和”自己做了 AI 编程助手”,面试官一定会问这个矛盾。
答法(三段式,别急着辩解):
- 先坦诚:不是为了做一个替代它们的产品,规模上完全不可比。
- 再说动机:我用 ClaudeCode 的时候好奇它内部到底怎么工作——它怎么找到相关代码的?为什么有时候改错文件?工具调用失败了怎么处理? 我想知道答案,最直接的办法是自己实现一个最小版本。
- 落到收获:做完之后我真正理解了一个 Agent 系统里哪些地方最容易出问题——LLM 返回的格式不可靠、工具参数的 schema 定义直接决定调用成功率、上下文会膨胀、检索的召回质量决定了 Agent 的上限。这些是看文档看不出来的,只有自己写过才知道。
加分收尾:
我现在用 ClaudeCode 的时候,看它的行为和以前不一样了——我能大致判断它这一步是在检索、在规划、还是在做工具调用,以及它为什么卡住。
4.2 🔥🔥🔥 「你简历写『熟练使用 ClaudeCode、Codex』,那这两个项目有多少代码是 AI 写的?」
🔴🔴🔴 第二危险。 这题看似在问 AI 使用率,实际在问 你有没有独立工程判断能力。
绝对不要做的事:
- ❌ 说”大部分是我自己写的”(不诚实,而且面试官能从代码风格和细节追问里试出来)
- ❌ 说”基本都是 AI 写的”(那是自爆)
- ❌ 回避或含糊
正确答法——坦诚 + 划清边界 + 举具体例子:
AI 参与了相当一部分,主要在:样板代码(handler/model 骨架、proto 定义)、测试用例、文档、以及部分工具输出的解析逻辑。
但有几件事是我自己定的:
- 架构选型——为什么拆五层、为什么用 gRPC streaming、为什么双模式 ReAct;
- 降级策略——5 组畸形返回怎么降级,这是我踩了参数被多包一层的坑之后自己设计的;
- 数据口径——压测怎么测、数字是什么含义、局限在哪,这些是我自己定义的。
我的原则是: AI 提高产出速度,但架构判断和数据可信度由我负责。
为什么这个答法有效:你举的三个例子(架构/降级/数据口径)恰好是 AI 最不擅长、最需要人来判断的三件事。**你主动把它们点出来了。 **
4.3 🔥🔥🔥 「代码解析为什么不直接用 tree-sitter / LSP / ctags?」
🔴 你的技术选型里最明显的弱点。 Go 用 go/ast 还说得通,但 Python 用正则解析,这是一定会挨打的点。
答法——先承认,再讲当时的约束,再讲如果重做会怎么选:
tree-sitter 确实更合适,这个我承认。它的优势是:多语言统一 API、增量解析、语法容错(代码不完整也能解析出部分 AST)、社区维护的语法定义全。
我当时选
go/ast是因为项目先支持 Go,标准库零依赖,能最快跑通链路。Python 用正则是权宜之计——它只能覆盖常见的语法形态,遇到装饰器嵌套、多行字符串、复杂缩进会失真, 这是我的技术债之一。如果要扩展到多语言,我会直接换 tree-sitter,而不是继续给每种语言写一套解析。
为什么这个答法好:承认弱点 + 说清当时约束 + 给出正确方向 = 面试官想看到的”有判断力的工程师”,而不是”死不认错”或” 不知道自己弱在哪”。
4.4 🔥🔥🔥 「你自己用过这个助手吗?真的能用吗?」
🔴 真实性检验题。 如果答”没怎么用过”,整个项目的说服力会大打折扣。
如实答,但要有具体场景:
- 用过的话,说具体做了什么任务(比如”让它给我的 KnHub 项目加一个接口”),成功的地方和需要人工介入的地方。
- 如果没重度使用,就说:
我在自己项目上跑过,简单任务(读代码、定位函数、小范围修改)能跑通;复杂任务(跨多个文件的重构)还是需要人工介入。 这也是我加校验流水线的原因—— 就是因为它的输出不可靠,所以才需要确定性的工具去验证。
🔴 不要吹。说”能跑通简单任务”比说”基本都能用”可信得多,而且后面那句”所以才需要校验流水线”把弱点转化成了设计动机。
4.5 🔥🔥🔥 「你怎么评估你的 Agent 到底好不好用?有什么指标?」
🔴🔴 这题是 AI 应用开发岗和普通后端岗的分水岭。 大部分候选人答不上来——因为他们只做了功能,没想过” 做完了怎么知道它好不好”。
分层答:
离线评估(应该有的):
- 构造固定的任务集(比如 20 个真实的代码修改任务),跑一遍看 任务成功率
- 工具调用准确率:参数是否正确、是否调了不该调的工具
- 平均轮次:越少越好,轮次多说明规划能力差或检索不准
- 检索召回质量:相关代码是否被召回(这个可以单独测)
- 幻觉拦截率:校验流水线拦下了多少错误代码
在线监控(生产必需的):
- 每任务 token 消耗和成本、平均耗时、失败率、用户是否采纳了修改
成本类:单次任务的钱、P95 token 消耗
🔴 必须承认的不足(这比硬编指标可信):
目前我没有建立系统化的 eval 集,前面这些是事后复盘的指标,不是一开始就设计好的评估体系。 如果继续做,第一件事就是补这个 ——没有 eval 就没有办法判断改动是变好还是变差。
为什么这题这么重要:AI 应用开发和传统后端最大的差别就是 输出不确定。一个工程师如果没想过”怎么衡量不确定性” ,说明他还没进入这个领域。
4.6 🔥🔥 「一次任务大概消耗多少 token?成本多少钱?」
🔴 成本意识是 AI 岗的硬指标。 你项目里没有做 token 统计,所以要承认并给方案。
目前没有做 token 统计,这是缺失的一块。 如果加,我会在 Agent 层拦住每次 LLM 调用的 usage 字段,按 session 聚合,暴露成 Prometheus 指标(prompt tokens / completion tokens / 估算成本),并按任务类型打标签。 有了这个才能回答”哪个环节最烧钱”——我预期是 ReAct 循环里反复把代码上下文塞给模型那一块占大头,对应的优化是缓存 system prompt(部分厂商支持 prompt caching)和裁剪工具输出。
顺带展示你知道的优化手段:prompt caching、工具输出截断、小模型做路由/分类、大模型只做关键步骤、批量请求。
4.7 🔥🔥 「上下文窗口爆了怎么办?多轮对话怎么管理?」
🔴 简历写了 ReAct 多轮,这题躲不掉。
先说现状:目前消息历史是 全量累积的,没有做压缩——这是明确的弱点。
再说方案(要能说出至少四种):
- 滑动窗口:保留最近 N 轮,更早的丢弃
- 历史摘要:把早期的对话压缩成一段摘要塞进 system prompt
- 工具输出裁剪:这是最大的 token 消耗源——读一个大文件全塞进去是最亏的,应该只保留相关片段(比如只保留符号定义和报错行附近)
- 长期记忆外置:历史消息存向量库,按需检索召回,而不是全量带上
- 中间信息丢失(lost in the middle):长上下文里模型对开头和结尾记得最清楚,中间最差——所以重要的约束要放在开头或结尾
→ 他会接着问:「那你这个项目的上下文大概多长?」🟡 去估一下,别瞎说。
4.8 🔥🔥 「你了解 MCP 吗?你的项目和它是什么关系?」
🔴 2025–2026 的必问热点。 你简历写了 ClaudeCode/Codex,这题命中率很高。
先讲清 MCP 是什么:Model Context Protocol,把”工具”从 Agent 内部抽出来,做成一个独立进程(MCP server),通过标准协议暴露给任何支持 MCP 的客户端(Claude Desktop、Cursor、Claude Code)。解决的是 工具的跨应用复用——写一次工具,所有 Agent 都能用。
再说你的项目和它的关系:
我的工具是直接内嵌注册在进程内的。好处是零网络开销、类型安全、参数 schema 在编译期就能校验;坏处是不能被别的 Agent 复用、不能运行时动态增删工具、跨语言要重新实现。 如果要让我的代码检索能力被 Claude Code 调用,正确做法是把它包成一个 MCP server 暴露出去—— 这是我很明确的下一步。
加分:如果能说出”MCP 的 transport 有 stdio 和 HTTP/SSE 两种,本地工具用 stdio,远程服务用 SSE”更好。🟡 不确定就别硬说细节。
4.9 🔥🔥🔥 「你两个项目看起来都是后端,为什么不投后端开发,投 AI 应用开发?」
🔴 动机题。 简历上一眼看过去确实全是后端技术栈,这题几乎必问。
答法——用”我花时间在哪”来证明志向,而不是用口号:
两个项目看起来是后端,但我花时间最多的地方不在后端。 在 AI 助手项目里,我最耗时的两个问题是: LLM 返回不稳定怎么处理(5 组畸形降级、参数 schema 的坑),和 检索怎么才能准 (符号图 + BM25 + 向量怎么组合)。这两个问题不是后端问题,是 AI 应用的问题。 后端能力是我的工具——微服务、缓存、消息队列这些让我能 把一个 AI 能力真正做成可靠的服务,而不只是一个 demo。 大数据专业是我的背景,它给我的是数据 Pipeline 的整体观,在做 Canal+Kafka 同步链路和 RAG 检索链路的时候直接派上用场。
一句话收尾:
我不是从后端转 AI,我是一直在往”让模型能力可靠落地”这个方向走,后端和数据是我走这条路的工具。
4.10 🔥🔥🔥 「这些数字(2.14 万 QPS、100% 命中率、21 万符号/秒)是你自己测的吗?怎么测的?」
🔴 真实性检验。 面试官不一定怀疑你,但他一定会确认你对数字的掌控程度。
通用应对原则(适用于所有数字):
- 先说怎么测的(工具 + 参数 + 环境)
- 再说测的什么(哪个接口 / 什么场景 / 什么数据集)
- 最后主动说局限(这一步最关键)——比如”并发 50–100 属于中低并发""是热点文章不是全量""是单机小规模实测,未做多轮统计”
🔴 三个必须主动自曝的口径:
- 「召回率 100%」= 解析器对 构造故障样例的召回率,不是”能发现所有 bug”
- 「命中率 100%」= 热点文章在 压测窗口内的读命中率,不是常态 SLA
- 「21 万符号/秒」= 由 301 符号 / 1ms 折算,🟡 折算口径你要自己核一遍,别让面试官心算对不上
通用原则: 先自己拆自己的台,比被拆穿强一百倍。 主动说局限会让数字更可信,而不是更不可信。
第 5 章 · AI 岗专业追问(技能栏逐条 + 深水区)
你技能栏写了「熟悉 RAG 完整链路,掌握 Agent ReAct 推理、Tool Calling 工具编排,熟悉 Eino 基本应用」。 写什么就会被问什么,这一章按技能栏顺序准备。
5.1 🔥🔥🔥 「『熟悉 RAG 完整链路』——讲讲」
完整链路(要能一口气说下来):
文档加载 → 切分(chunking) → 向量化(embedding) → 存入向量库 ↓查询 → 查询改写/扩展 → 向量化 → 检索(可混合 BM25) → 重排(rerank) → 拼装上下文 → 生成 → (可选)引用标注/后校验每一环的考点:
| 环节 | 他会追问 | 你的答案要点 |
|---|---|---|
| 切分 | 怎么切?多大? | 固定长度 vs 语义切分 vs 按结构切;overlap 的作用是防止切断语义;代码场景要按 AST 结构切(函数/类),不能按字符数切 |
| 向量化 | 模型怎么选? | 维度、中文能力、是否需要微调;换 embedding 模型必须重建索引 |
| 存储 | 为什么 pgvector? | 已用 PostgreSQL,不想再引入重组件;规模不大时 HNSW 索引够用;量大再考虑 Milvus |
| 检索 | 怎么提召回? | Query 改写/扩展、HyDE(生成假答案再检索)、混合检索(BM25+向量)、父子块(小 chunk 检索、大 chunk 生成) |
| 重排 | 为什么要 rerank? | 向量召回是粗排,rerank 用 cross-encoder 精排,准确率高但慢,所以只作用在 top-k 上 |
| 生成 | 怎么防幻觉? | 要求模型只基于上下文回答、带引用出处、无法回答时明确说”不知道” |
RAG 常见失败模式(主动说出来很加分): ① 切分破坏了语义 ② 召回噪声多(相关度不够)③ 上下文过长导致中间信息丢失 ④ 检索到但没有答案时模型仍强行生成 ⑤ 知识库更新了但索引没更新
5.2 🔥🔥 「代码 RAG 和文档 RAG 有什么不同?」
🔴 这题答好非常加分,说明你理解 RAG 不是只有一种形态。
| 维度 | 文档 RAG | 代码 RAG |
|---|---|---|
| 切分 | 按段落/固定长度 | 按 AST 结构(函数、类、方法) |
| 检索粒度 | chunk 级 | 符号级 + chunk 级 |
| 匹配方式 | 语义为主 | 精确匹配(标识符)优先,语义为辅 |
| 上下文 | 段落文本 | 要带文件路径、行号、符号签名 |
| 额外信息 | 无 | 依赖关系图(谁调用谁、imports) |
| 时效性 | 相对静态 | 代码频繁变更,索引要增量更新 |
5.3 🔥🔥🔥 「ReAct 和 Function Calling 是什么关系?」
这是最容易答混的一题,把关系说清楚:
- Function Calling 是模型能力(协议层):模型原生支持输出结构化的工具调用请求。
- ReAct 是编排模式(框架层):Thought → Action → Observation 的交替循环。
- 关系:Function Calling 让 ReAct 的 Action 这一步变得更结构化、更可靠,但 ReAct 不依赖它——没有 Function Calling,用 prompt 约束模型输出 JSON 也能实现 ReAct( 你的兜底模式就是这个)。
其他 Agent 范式(能说出取舍更好):
| 范式 | 做法 | 适用 |
|---|---|---|
| ReAct | 边想边做,逐步观察 | 探索性任务,需要动态调整 |
| Plan-and-Execute | 先规划完整步骤,再执行 | 步骤明确、依赖关系清晰的任务 |
| Reflection | 生成 → 自我批评 → 修订 | 质量优先、可接受多轮开销 |
你的项目为什么选 ReAct:代码修改是探索性的——你不看代码就不知道要改哪,所以必须边看边想。
5.4 🔥🔥 「Function Calling 的实现原理是什么?模型是怎么『学会』调用的?」
- 不是模型”真的调用”了什么—— 模型只是输出了一段结构化的 JSON(工具名 + 参数)。
- 真正的执行在你的代码里:你解析 JSON → 调本地函数 → 把结果拼回 messages → 再让模型继续。
- 模型之所以会输出这种格式,是因为 训练时见过大量 tool-calling 的样本,而且推理时你把工具的 JSON Schema 放在请求里,模型按 schema 生成。
- 🔑 关键认知:工具调用的成功率很大程度取决于 你给的 schema 写得够不够清楚——这就是你踩的那个坑(通用
argsschema 导致参数被多包一层)。
5.5 🔥🔥 「结构化输出怎么保证?」
至少说出四层:
- 原生 JSON mode / Function Calling(最可靠,模型层面保证语法正确)
- prompt 里给示例 + 明确格式要求
- 解析容错:去 markdown 代码块、找首尾括号、截断修复
- 校验 + 重试:不符合预期就带上错误信息让模型重来(你的项目就是这个思路)
🔴 一定要提:JSON mode 只保证 语法合法,不保证 语义正确(字段值可能是错的)。所以还需要业务层校验。
5.6 🔥🔥 「你怎么做 prompt 的评测?改了 prompt 怎么知道是变好还是变差?」
🔴 AI 岗高频,很多人答不上来。
- 必须有固定的测试集:挑 20–50 个代表性 case,改 prompt 前后各跑一遍。
- 有明确的判定标准:能用代码判定的用代码(比如格式是否正确、字段是否齐全),不能的用 人工评分或** 用强模型当裁判(LLM-as-judge) **。
- 要有 baseline:不能”改完感觉不错”,要有数字对比。
- 注意波动:LLM 输出有随机性,单次结果不可信,要不固定 temperature,要么跑多次看分布。
🟡 承认不足:你项目里没有系统化的 prompt eval,这是真实的缺失,说出来并说”如果继续做会先补这个”。
5.7 🔥 「为什么用 Eino,不用 LangChain / 别家?」
- Eino 是 Go 生态的 AI 应用框架, 你的项目是 Go 的——LangChain 主要是 Python/JS,Go 版本(langchain-go)生态弱很多。
- 它提供统一的
ToolCallingChatModel接口 + 厂商适配器(openai / claude / qwen),换模型不改业务代码。 - 统一消息类型
schema.Message,ToolInfo+ParamsOneOf自动转成各家要求的 JSON Schema。 - 🟡 你说的是”熟悉基本应用”,被问到这一层就够, 别主动往源码层深入。
5.8 🔥 「如果换一个新模型,你要改什么?」
- 因为用了 Eino:改配置 + 加/换适配器,业务代码不动。
- 但还有几件事要处理:
- tool calling 能力差异——弱模型要切到 JSON Prompt 兜底模式
- prompt 要重新调——不同模型对指令的敏感度不同
- 上下文长度不同——影响你的上下文管理策略
- 成本差异——影响你能跑几轮循环
第 6 章 · 基础抽查(每个 1 分钟,速答)
面试官不会在这部分深挖,但答不上来很伤。只列最高频的。
Go(🔴 最深挖)
- 并发:GMP 调度、channel 有/无缓冲、
select、sync.MutexvsRWMutex、context传播与取消、goroutine 泄漏怎么查(pprof / goroutine 数监控) - 内存:GC 三色标记 + 混合写屏障、逃逸分析、
sync.Pool - 错误处理:
error是值、errors.Is/As、%w包装 - 接口:隐式实现、小接口原则、用 interface 做测试 mock
- 高频八股:slice 扩容、map 实现与并发安全、
defer执行顺序、闭包陷阱、SingleFlightvssync.Once - 🔴 能手撕:单例(双重检查 +
sync.Once)、生产者消费者、令牌桶限流、WaitGroup控并发
Redis
- 数据结构与场景( ZSet —— 你项目里的文章列表就是
Sorted Set) - 过期策略(惰性 + 定期)、内存淘汰(LRU/LFU)
- 持久化 RDB vs AOF、高可用(主从/哨兵/集群)
- 缓存三兄弟(见 3.3)、分布式锁(
SETNX+ 过期 + Redlock 的争议)
Kafka
- 为什么快:顺序写 + 零拷贝 + 批量压缩 + 分区并行
- 分区与消费者组: 一个分区只能被组内一个消费者消费,分区数决定并行度
- 消费语义:at least once(先消费后提交会重复 → 需幂等)
- 顺序性:只保证分区内有序——所以 Canal 消息要按主键分区,才能保证同一行的变更有序
- 重复消费 / 消息丢失 / LAG 堆积的排查
SQL(🔴 高概率手撕)
- 索引: B+ 树、最左前缀、覆盖索引、索引失效场景
- 事务与隔离级别: MVCC、幻读、可重复读的实现
EXPLAIN解读、JOIN、窗口函数、深分页用游标优化- 结合项目:文章表
content为什么用 TEXT、mobile为什么 varchar (128)、点赞表设计
Canal
- 原理: 伪装成 MySQL slave,发 dump 协议拉取 binlog 后解析
- binlog 格式必须是 ROW(STATEMENT 拿不到行数据)
- 与 MQ 结合后的顺序性和幂等
第 7 章 · 交叉追问与场景题
7.1 🔥🔥🔥 「KnHub 是内容平台,和你投的 AI 岗关系不大,为什么放进来?」
🔴 必问。不要说”凑数的”。
KnHub 证明的是 工程落地能力——服务拆分、缓存一致性、压测与数据验证、K8s 部署与监控。 AI 应用开发不是只写 prompt, 模型能力最终要跑在可靠的工程系统上。 而且我做的 Canal+Kafka「变更捕获 → 异步管道 → 最终一致」链路,本质上和一个 RAG 系统里「数据变更 → 重建索引」是同一类问题。
这句话建议背下来,它把一个”不相关”的项目直接接到了岗位需求上。
7.2 🔥🔥 「两个项目都是微服务,一个手写 gRPC 一个用 go-zero,为什么不同?」
- 目标不同:AI 助手是探索性项目,我需要完全掌控流式链路和 ReAct 编排,go-zero 的 REST 抽象对 gRPC server-streaming 支持不如原生顺手,所以手写;KnHub 是业务型项目,CRUD + 缓存 + 鉴权这类模式化需求占大头,go-zero 的
goctl和内置治理(熔断、限流、SingleFlight)能省下大量重复劳动。 - 总结: 选型取决于项目的主要矛盾是「控制力」还是「开发效率」。
- 反思:如果 AI 助手重做,我会在 Gateway 层也用框架,只保留 Agent/CodeIntel 的原生 gRPC。
7.3 🔥🔥🔥 「如果要给 KnHub 加一个 AI 功能(智能推荐 / AI 摘要),你怎么设计?」
🔴 AI 岗高频场景题。背下这个模板,任何 AI 场景题都能套。
以「AI 自动生成文章摘要和标签」为例:
1. 需求边界:摘要用来干什么?(列表页展示 / 搜索增强)→ 决定质量要求和成本上限2. 触发方式:写时同步生成(发布时阻塞,伤体验) vs 异步生成(Kafka 消费 binlog 后触发,文章先发布、摘要后到) → 选异步,复用现有 Canal+Kafka 链路3. 上下文构造:正文切分 → 太长用 map-reduce 摘要;或只取前 N 段 + 标题 + 已有标签4. 模型与成本:小模型批量处理 + 大模型兜底难例;相同内容 hash 缓存;限流5. 质量保障:结构化输出(JSON schema / function calling)→ 校验 → 失败重试 → 人工兜底6. 可观测:生成耗时、token 消耗、失败率、摘要长度分布7. 降级:LLM 不可用时列表页用「正文前 80 字」兜底,不影响主流程🔑 要点:任何 AI 场景题都要主动讲到 成本、降级、可观测、质量校验 这四件事——这是区分”玩过 API”和”做过工程”的分水岭。
7.4 🔥 「微服务的核心代价是什么?」
代价:分布式事务、网络不可靠(超时/重试/幂等)、可观测性复杂(一个请求跨 N 个服务,排查要 trace)、部署运维成本、本地开发调试困难。 收益:独立扩容、独立部署、故障隔离、技术异构。 两边都说出来才算答完整。
7.5 🔥 「两个用户同时让 Agent 改同一个文件怎么办?」
🟡 你的项目肯定没做文件锁。 承认 + 给方案:加文件级锁(按路径 hash 分桶)、或者用乐观锁(记录文件最后修改时间,改之前校验是否变化)、或者把修改序列化到队列按文件维度串行处理。
第 8 章 · 行为面 + 反问
8.1 🔥🔥 「项目中遇到的最大困难/挫折是什么?」
用 STAR,推荐讲「LLM 参数被多包一层」那个真实案例(第 2.4 节已经写好了),因为它真实、有排查过程、有结果,而且能接上你的设计原则。
备选:从”ReAct 死循环”或”检索召回不准”里选一个你印象最深的。
8.2 🔥 「你怎么学一个新技术的?举个最近的例子」
给一个可复用的四步法:
- 官方文档 + 最小 Demo 跑通
- 找一个真实场景做端到端实现
- 读关键源码或设计文档理解取舍
- 压测 / 边界测试,验证它的边界在哪
举例:学 Eino 时先跑通 Tool Calling Demo,再在 ReAct 项目里落地,踩到参数 schema 的坑后回去读了 ToolInfo 的转换逻辑。
8.3 🔥 「你最有成就感的一段代码?」
不要选复杂的,选 有判断力的。推荐:畸形返回的安全降级逻辑,或者参数 schema 精确化 + 防御性解包那一处。理由:它体现的是” 我知道模型不可靠,所以我设计了兜底”。
8.4 🔥🔥🔥 「你还有什么想问我的?」
选 2–3 个(别空手,也别问薪资福利和网上能查到的):
- 「这个岗位日常负责的是哪类 AI 应用?偏 RAG/知识库、偏 Agent 编排,还是偏模型服务工程?」
- 「团队现在在 AI 落地过程中,觉得最棘手的是效果、成本,还是工程稳定性?」
- 「新人入职前三个月,通常期望能独立承担什么样的事情?」
- 「团队目前的技术栈和研发流程是怎样的?代码评审和上线流程怎么走?」
❌ 别问:薪资福利(留给 HR)、通过概率、加班情况、官网能查到的问题。
8.5 🟡 「能实习多久/到岗时间?」
如实答。27 届本科,提前确认好学校那边的时间安排,别现场算。
附录 A · 必背数字速查表
| 项目 | 数字 | 一句话口径 |
|---|---|---|
| AI 助手 | 5 层微服务 | Gateway / Agent / Code Intel / Tools / Validation 🔴 与「4 个 gRPC」统一口径 |
| AI 助手 | 双模式 ReAct | Native Tool Calling 为主 + JSON Prompt 兜底 |
| AI 助手 | maxIterations = 10 | 死循环硬上限 |
| AI 助手 | 5 组畸形返回 → finish,零 panic | 🔴 要能当场报出哪 5 组 |
| AI 助手 | 8 类工具 | 🔴 要能报出 8 个名字 |
| AI 助手 | 4 类关系边 | calls / imports / defines / uses |
| AI 助手 | 301 符号 ≈1ms(≈21 万符号/秒) | 单机小规模实测 🟡 折算口径自己核 |
| AI 助手 | 召回率 100% | 解析器对构造故障样例,不是发现所有 bug |
| KnHub | gRPC 2.00ms / P99 4.88ms / 2.14 万 QPS | 并发 50–100、30s、直打 RPC 层 |
| KnHub | HTTP 8.85ms / P99 26.81ms / 1.22 万 QPS | 经网关,多一跳 + JSON + 中间件 |
| KnHub | 成功率 99.99%+ | 🟡 能说清失败请求是什么 |
| KnHub | 命中率 100%(1.7 万+ 读 0 miss) | 热点文章 + 压测窗口内,非常态 SLA |
| KnHub | 同步延迟 ≈200ms | 最终一致 |
| KnHub | Kafka 3.7 万条/s(18MB/s) | 生产者吞吐 |
| KnHub | 10 万条消费后 LAG 归零 | 消费能力跟得上 |
附录 B · 176 道原题的正确用法
那 176 题(ai-coding-agent 100 题 + KnHub 76 题) 不是考纲,是素材库。
它的价值:当你在某道题上答不出来时,回源文档看完整答案。题号对应:
A##→E:\暮晓\coding\ai-coding-agent\docs\interview-qa.mdK##→D:\GolandProjects\KnHub\docs\interview-qa.md
它的问题:由代码推演生成,缺少”这道题面试官会不会问”的过滤,也缺少从简历字面矛盾推导出的题(那部分在第 4 章)。
建议用法:本手册的题先过一遍 → 哪题没底,去附录 B 找对应题号 → 回源文档看完整答案。
本手册各章对应的原题号(查漏用):
| 章节 | 对应原题 |
|---|---|
| 2.1 讲项目 | A1 A12 A44 A45 |
| 2.2 双模式 ReAct | A17 A59 A78 |
| 2.3 畸形返回降解 | A16 A18 A60 |
| 2.5 混合检索 | A8 A11 A20 A91 |
| 2.6 符号图 | A21 A30 A70 |
| 2.7 校验流水线 | A23 A31 A83 A84 |
| 2.8 最大缺点 | A38 A95 A86 A87 A88 |
| 2.9 过度设计 | A2 A41 A76 A77 |
| 3.2 Canal+Kafka | K9 K18 K11 |
| 3.3 缓存一致性 | K14 K16 K22 K23 K40 K59 K67 |
| 3.4 压测 | K24 K26 K25 |
| 3.7 安全与技术债 | K10 K32 K33 K48 K52 K53 |
| 3.8 go-zero 选型 | K5 K6 K39 K70 |
| 第 5 章 AI 专业 | A7 A57 A58 A94 |
| 第 6 章 基础 | A51–A56 K35–K38 K59–K61 |
面试前 24 小时 checklist
🔴 必做(一问就穿帮的位置,现在就去核实)
- 「五层微服务」vs「4 个 gRPC」——数量对不上,确认是笔误还是某个服务不走 gRPC, 必要时改简历
- 「≈21 万符号/秒」的折算口径——301 符号 / 1ms 到底怎么算的,自己先算一遍
- 压测环境(CPU / 内存 / 是否容器 / 依赖是否同机 / 数据集规模)——写下来背住
- 5 组畸形返回 具体是哪 5 组——写成逐字稿
- 8 类工具 的名字——写成逐字稿
- 课程项目:部署了哪些模型 + 参数量 + 结论——写在纸上背住
准备顺序(时间紧就按这个走)
- 第 1 章开场逐字稿, 出声念 3 遍并计时(不是默读,60 秒内)
- 第 4 章 10 题,每题出声答一遍(🔴 优先级最高)
- 附录 A 的 15 个数字,遮住右列能自己报出来
- 第 2 章项目一的 🔥🔥🔥 题,每题控制在 90 秒内
- 第 3 章项目二只过 🔥🔥🔥 的 5 题
- 第 5 章 AI 专业:RAG 链路 / ReAct vs Function Calling / 怎么评估 Agent
- 第 6 章基础:Go 并发 + Redis 三兄弟 + Kafka 顺序性 + SQL 索引
- 手撕热身:SQL 索引与窗口函数、Go 单例、令牌桶限流
- 反问问题准备 2–3 个