跳到主要内容

项目

自用别看

周一 6月 27 2005
13711 字 · 52 分钟

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 CallingJSON 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。兜底保证弱模型也能跑通—— 这是可用性兜底,不是性能优化。

→ 他会接着问:「那怎么防止死循环?」

防死循环的四层(要能一口气说完):

  1. 硬性迭代上限 maxIterations = 10,超了强制返回 done
  2. System Prompt 约束:「Do not call tools unnecessarily」
  3. 工具报错时把错误作为 ToolMessage 喂回去,让模型自己改策略或放弃
  4. 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 → 解包一层
2JSON 不合法 / 被 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 🔥🔥🔥 「这个项目最大的缺点是什么?」

🔴 主动承认比被追问出来强十倍。 按这个顺序说,把最致命的放前面:

  1. 索引不持久化——Code Intel 的符号图和 BM25 索引全在内存,服务重启全丢,冷启动要重建全仓库。
  2. 无认证、无命令沙箱——RunCommand 直接把模型生成的命令交给 shell,这是最大的安全短板。
  3. Python 解析用正则不严谨——只覆盖常见语法形态,遇到装饰器嵌套、多行字符串等会失真。
  4. 上下文无管理——消息历史全量塞给模型,长任务会撑爆上下文窗口。
  5. 缺少集成测试——有单元测试(AST/BM25/graph/patch/各解析器),但没有跨服务端到端测试,也没有 LLM mock 测试。

→ 他会接着问:「那如果重做,你会改什么?」

答(五个方向,正好对应上面五个缺点): ① 索引持久化到 PostgreSQL/Redis ② 加 JWT 认证 + 命令白名单 + 路径沙箱 + 危险操作人工确认 ③ 换 tree-sitter 统一多语言解析 ④ 加上下文管理(滑动窗口 + 历史摘要)⑤ 补集成测试、metrics、分布式追踪。


2.9 🔥🔥 「五层微服务,对这个项目是不是过度设计?」

🔴 这题答好不容易, 准备一个两分钟版本:

  • 先承认:对一个个人项目,五层微服务确实偏重。
  • 再讲为什么还是这么做了:
    1. 异构负载——Tools(跑测试/跑命令,分钟级重 IO)和 Agent(等 LLM,长阻塞)资源特征完全不同,拆开后可以独立设超时、独立扩容;
    2. 故障隔离——命令执行是最危险的一环,单独成服务便于将来加沙箱,崩了不带崩 Agent;
    3. 技术验证目的——这个项目本身就是为了把微服务 + gRPC 流式的完整链路跑通。
  • 收在务实的一句:

    如果重做,我会先做成模块化单体——Go 的 package 边界先划清楚,等真的出现独立扩容或隔离需求再拆进程。* 拆分应该由真实痛点驱动,而不是一开始就按理想架构画。*


2.10 🔥 「有没有什么题你想主动说的?」

如果面试官问「你还有什么想补充的」,说这两个,都是加分项:

  • 多 provider 容灾:Agent 层通过 Eino 抽象了多个模型厂商,某个 provider 不可用可以切到另一个(🔴 前提是你确实实现了—— [A37] 提到支持扩展新 provider,去核实一下是否真的做了运行时切换,没做就不要说”容灾”,改成”接口上具备切换能力”)。
  • 安全降级优先于功能完整:整个项目的设计取向是「宁可安全降级,也不 panic」,这在生产系统里比”功能多”更重要。

项目一 · 必背数字

数字口径备注
5 层微服务Gateway / Agent / Code Intel / Tools / Validation🔴 与「4 个 gRPC」口径要统一
双模式 ReActNative 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 过期瞬间大量请求打穿到 DBCachedConn 内置 SingleFlight,同 key 并发回源只放行一个 🟢
穿透查根本不存在的 id,缓存永不命中🟡 若没实现就承认,给方案:缓存空值(短 TTL)或布隆过滤器
雪崩大量 key 同时过期🟡 若没实现就承认,给方案:TTL 加随机抖动

200ms 窗口内的脏读:这是最终一致性的固有代价。应对——强一致场景走读主库;给缓存加版本号对比 binlog 位点;内容平台对 200ms 延迟不敏感,业务上可以接受。


3.4 🔥🔥🔥 「压测数据怎么来的?环境是什么?」

🔴 这题决定你那四个数字可不可信。

必须能说清的四件事(现在就补上):

  1. 机器配置(CPU 核数 / 内存 / 是否容器 / MySQL 和 Redis 是否同机)
  2. 测的是哪几个接口(如果是文章详情/列表读接口,要明说——读多写少场景)
  3. 数据集规模(多少篇文章 / 缓存预热了没有)
  4. 工具参数(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)热点文章 + 压测窗口内
同步延迟 ≈200msbinlog → Redis 端到端
Kafka 3.7 万条/s(18MB/s)生产者吞吐
10 万条消费后 LAG 归零消费能力跟得上

第 4 章 · 🔴 项目文档里没有、但几乎必问的 10 题

这 10 题不是从代码里长出来的,是从 你简历的字面矛盾里长出来的。项目文档推演不出它们,但面试官看得出来。 这一章的优先级高于前面所有章节。


4.1 🔥🔥🔥 「ClaudeCode、Cursor、Codex 都这么成熟了,你为什么还要自己做一个 AI 编程助手?」

🔴🔴🔴 命中率最高的题。 你简历同时写了”熟练使用 ClaudeCode、Codex”和”自己做了 AI 编程助手”,面试官一定会问这个矛盾。

答法(三段式,别急着辩解):

  1. 先坦诚:不是为了做一个替代它们的产品,规模上完全不可比。
  2. 再说动机:我用 ClaudeCode 的时候好奇它内部到底怎么工作——它怎么找到相关代码的?为什么有时候改错文件?工具调用失败了怎么处理? 我想知道答案,最直接的办法是自己实现一个最小版本。
  3. 落到收获:做完之后我真正理解了一个 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 多轮,这题躲不掉。

先说现状:目前消息历史是 全量累积的,没有做压缩——这是明确的弱点。

再说方案(要能说出至少四种):

  1. 滑动窗口:保留最近 N 轮,更早的丢弃
  2. 历史摘要:把早期的对话压缩成一段摘要塞进 system prompt
  3. 工具输出裁剪:这是最大的 token 消耗源——读一个大文件全塞进去是最亏的,应该只保留相关片段(比如只保留符号定义和报错行附近)
  4. 长期记忆外置:历史消息存向量库,按需检索召回,而不是全量带上
  5. 中间信息丢失(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 万符号/秒)是你自己测的吗?怎么测的?」

🔴 真实性检验。 面试官不一定怀疑你,但他一定会确认你对数字的掌控程度。

通用应对原则(适用于所有数字):

  1. 先说怎么测的(工具 + 参数 + 环境)
  2. 再说测的什么(哪个接口 / 什么场景 / 什么数据集)
  3. 最后主动说局限(这一步最关键)——比如”并发 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 写得够不够清楚——这就是你踩的那个坑(通用 args schema 导致参数被多包一层)。

5.5 🔥🔥 「结构化输出怎么保证?」

至少说出四层:

  1. 原生 JSON mode / Function Calling(最可靠,模型层面保证语法正确)
  2. prompt 里给示例 + 明确格式要求
  3. 解析容错:去 markdown 代码块、找首尾括号、截断修复
  4. 校验 + 重试:不符合预期就带上错误信息让模型重来(你的项目就是这个思路)

🔴 一定要提: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:改配置 + 加/换适配器,业务代码不动。
  • 但还有几件事要处理:
    1. tool calling 能力差异——弱模型要切到 JSON Prompt 兜底模式
    2. prompt 要重新调——不同模型对指令的敏感度不同
    3. 上下文长度不同——影响你的上下文管理策略
    4. 成本差异——影响你能跑几轮循环

第 6 章 · 基础抽查(每个 1 分钟,速答)

面试官不会在这部分深挖,但答不上来很伤。只列最高频的。

Go(🔴 最深挖)

  • 并发:GMP 调度、channel 有/无缓冲、select、sync.Mutex vs RWMutex、context 传播与取消、goroutine 泄漏怎么查(pprof / goroutine 数监控)
  • 内存:GC 三色标记 + 混合写屏障、逃逸分析、sync.Pool
  • 错误处理:error 是值、errors.Is/As、%w 包装
  • 接口:隐式实现、小接口原则、用 interface 做测试 mock
  • 高频八股:slice 扩容、map 实现与并发安全、defer 执行顺序、闭包陷阱、SingleFlight vs sync.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 🔥 「你怎么学一个新技术的?举个最近的例子」

给一个可复用的四步法:

  1. 官方文档 + 最小 Demo 跑通
  2. 找一个真实场景做端到端实现
  3. 读关键源码或设计文档理解取舍
  4. 压测 / 边界测试,验证它的边界在哪

举例:学 Eino 时先跑通 Tool Calling Demo,再在 ReAct 项目里落地,踩到参数 schema 的坑后回去读了 ToolInfo 的转换逻辑。

8.3 🔥 「你最有成就感的一段代码?」

不要选复杂的,选 有判断力的。推荐:畸形返回的安全降级逻辑,或者参数 schema 精确化 + 防御性解包那一处。理由:它体现的是” 我知道模型不可靠,所以我设计了兜底”。

8.4 🔥🔥🔥 「你还有什么想问我的?」

选 2–3 个(别空手,也别问薪资福利和网上能查到的):

  1. 「这个岗位日常负责的是哪类 AI 应用?偏 RAG/知识库、偏 Agent 编排,还是偏模型服务工程?」
  2. 「团队现在在 AI 落地过程中,觉得最棘手的是效果、成本,还是工程稳定性?」
  3. 「新人入职前三个月,通常期望能独立承担什么样的事情?」
  4. 「团队目前的技术栈和研发流程是怎样的?代码评审和上线流程怎么走?」

❌ 别问:薪资福利(留给 HR)、通过概率、加班情况、官网能查到的问题。

8.5 🟡 「能实习多久/到岗时间?」

如实答。27 届本科,提前确认好学校那边的时间安排,别现场算。


附录 A · 必背数字速查表

项目数字一句话口径
AI 助手5 层微服务Gateway / Agent / Code Intel / Tools / Validation 🔴 与「4 个 gRPC」统一口径
AI 助手双模式 ReActNative 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
KnHubgRPC 2.00ms / P99 4.88ms / 2.14 万 QPS并发 50–100、30s、直打 RPC 层
KnHubHTTP 8.85ms / P99 26.81ms / 1.22 万 QPS经网关,多一跳 + JSON + 中间件
KnHub成功率 99.99%+🟡 能说清失败请求是什么
KnHub命中率 100%(1.7 万+ 读 0 miss)热点文章 + 压测窗口内,非常态 SLA
KnHub同步延迟 ≈200ms最终一致
KnHubKafka 3.7 万条/s(18MB/s)生产者吞吐
KnHub10 万条消费后 LAG 归零消费能力跟得上

附录 B · 176 道原题的正确用法

那 176 题(ai-coding-agent 100 题 + KnHub 76 题) 不是考纲,是素材库。

它的价值:当你在某道题上答不出来时,回源文档看完整答案。题号对应:

  • A## → E:\暮晓\coding\ai-coding-agent\docs\interview-qa.md
  • K## → D:\GolandProjects\KnHub\docs\interview-qa.md

它的问题:由代码推演生成,缺少”这道题面试官会不会问”的过滤,也缺少从简历字面矛盾推导出的题(那部分在第 4 章)。

建议用法:本手册的题先过一遍 → 哪题没底,去附录 B 找对应题号 → 回源文档看完整答案。

本手册各章对应的原题号(查漏用):

章节对应原题
2.1 讲项目A1 A12 A44 A45
2.2 双模式 ReActA17 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+KafkaK9 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 个

感谢您的阅读!如果可以,给俺点些关注吧~

项目

周一 6月 27 2005
13711 字 · 52 分钟