大厂 AI Coding 面试:把 AI 当 Junior,把自己当 Tech Lead
核心判断:既然允许用 AI 写代码,面试官就不再考「手写语法速度」,而是考你如何指挥、约束、审核一个手速极快、但没有业务大局观的初级程序员。
代码跑通只是及格。SSP 级表现来自:架构边界、契约设计、验收驱动、一眼看穿 AI 的坑、以及生产演进思考。
0. 先换身份:你不是「会用 Cursor 的人」
把角色钉死再动手:
| 角色 | 职责 | 面试官真正在看什么 |
|---|---|---|
| 你 = Tech Lead | 定需求、定契约、定验收、收口风险、拍板上线 | 工程判断力 |
| AI = Junior | 按规格填实现、跑测试、按你的纠偏重写 | 你管它的能力 |
| 面试官 = 业务方 / 架构评审 | 看你怎么对齐、怎么拦错、怎么演进 | 你能不能独立扛一块 |
瓶颈已经从「实现速度」挪到了「意图传达质量」。AI 最容易出的错不是语法,而是:
- 跑偏需求(理解错一半还往下写)
- 加无关功能(看起来合理,规格里没有)
- 幻觉 API(调用看起来应该存在、实际不存在的方法)
- 并发/一致性漏洞(单线程能过,高并发超卖)
- 看起来正常(不报错、不抛异常,功能其实是死的)
所以满分工作流不是「Prompt 一次生成整个项目」,而是:先把意图锁死,再让 AI 填空,最后你来收口。
1. 面试高分 5 步工作流(压缩版也能打满分)
现场通常只有 45--60 分钟。不要把流程做成表演,但五步一个都不能省,可以压缩,不能跳步。
口头对齐需求 → 手写契约/接口 → 写下验收标准
↓
分步驱动 AI(底层 → 核心 → 接口)
↓
大声 Review + 口述生产演进
第 1 步:明确需求与边界(Requirement & Scope)
谋定而后动。不要一上来就打开 AI 输入框。
离开键盘,看着面试官,把这四类问题问清楚:
- 核心链路:主路径是什么?成功长什么样?
- 边缘场景:空值、重复请求、过期、超限、非法参数怎么处理?
- 非功能:单机还是分布式?一致性要到什么程度?延迟/吞吐有没有底线?
- 失败策略:依赖挂了是失败、降级,还是放行?
话术模板:
在让 AI 写代码前,我想先对齐边界:这是单机还是分布式?存储底座我打算用什么?算法先选简单可验证的,还是直接上生产级?失败时是 fail-close 还是 fail-open?我们现在开始吗?
为什么这步值钱: 面试官立刻知道你不是「需求翻译器」,而是会砍范围、会做取舍的人。Demo 里主动选 Fixed Window 而不是一上来 Token Bucket,本身就是工程判断。
第 2 步:定义契约与接口(Contract / Spec Coding)
先画护城河,再让 AI 填海。
在让 AI 写实现之前,自己手写(或口头定稿)这三样:
- Interface / Trait / 抽象类
- 核心数据结构(Config、Result、Error)
- API 入参出参与错误语义
这就是 SDD(规格驱动) 在面试现场的最小形态:规格是唯一真源,AI 必须贴着契约走,不能自由发挥把架构带跑。
话术:
我先把接口和数据结构定下来。后面无论 AI 怎么生成,都必须符合这个入参出参,不会破坏整体架构。
加分点: 主动解释你为什么这样设计------例如 Check 返回 (allowed, remaining, err) 而不是只返回 bool,是因为调用方需要做提示、打点和排障。面试官要的是「为什么」,不是「写了 interface」。
第 3 步:编写验收标准(Acceptance Criteria / verify.md)
明确告诉面试官:为了防止 AI 幻觉,我先写验收。
用 Markdown 或注释写下 可验证 的用例。不要写「功能正确」「显示正常」这种三个月后自己都说不清的句子。
好的验收长这样:
- 给定输入 X,必须得到输出 Y
- 第 11 次必须拒绝
- 100 并发最终放行必须严格是 10,不能超卖
这就是 ATDD:完成的定义不是「代码写完了」,而是「清单每一条都打勾」。
对纯函数(换算、窗口计算、配额算术)再补 TDD;对并发/分布式,验收必须包含竞态用例,否则 AI 给你的「能跑」毫无意义。
行为描述用 BDD 文风写进 Prompt,不要上 Cucumber 工具链:
Given 同一 userID 在 1 分钟窗口内已成功 10 次
When 第 11 次请求到达
Then allowed = false,且 remaining = 0
前置 / 操作 / 期望被强制拆开,AI 就没法「理解错一半还往下写」。
第 4 步:分步驱动 AI,并大声排坑(Drive Generation)
不要一个 Prompt 写完全项目。 顺序固定:
存储/基础设施 → 核心算法(原子性) → 接口层/错误处理 → 测试
遇到 AI 写错,不要自己默默改。大声说出来:
面试官您看,这段 Get + Incr 在单线程没问题,但高并发是 Race Condition。两步操作不原子,会超卖。作为 Tech Lead 我不能收这段代码。我要让它改成 Lua 脚本 / INCR+EXPIRE 保证原子性。
然后改 Prompt 让 AI 重写。面试官要看的不是你手改得快,而是:
- 你能识别 Junior 的典型坑
- 你能把问题描述成可执行的纠偏指令
- 你知道正确方向(原子性、幂等、超时、降级)而不是「再生成一次碰运气」
派单 Prompt 最低要带这 6 段(现场可口述精简):
- 规格锚点:接口签名、配置含义、章节/约束原文
- 验收准则:可勾选的清单
- 行为描述:Given / When / Then
- 项目管线:用什么库、禁止绕过(禁止裸调、禁止跳过事务、禁止自造工具类)
- 实现约束:语言、存储、复杂度、是否需要二审
- 幻觉防护:调用任何「看起来应该存在」的 API 前先核验;规格没有的守卫/字段不要自造,标待确认
后两段是长周期项目里踩出来的:管线没写进 Prompt,AI 就会用「看起来合理」的方式绕过标准路径,产物全废;幻觉防护没写,AI 不会说「我不确定」,它会给一个看起来对的答案继续往下写。
第 5 步:深度 Review + 生产演进(Code Review & Evolution)
代码跑绿只是及格。你必须主动挑刺,并口述「如果要上生产还缺什么」。
Review 时按这个清单扫,比「这段写得不优雅」更像后端:
| 维度 | 典型 AI 坑 | 你该说的话 |
|---|---|---|
| 并发/原子性 | Get-then-Set、先查后改 | 必须 Lua / Txn / CAS |
| 一致性 | 固定窗口边界突发 | 生产要滑动窗口或令牌桶 |
| 依赖故障 | Redis 超时直接 500 | 降级:超时走本地限流或 fail-open 策略(需业务拍板) |
| 热点 | 大 V 打穿单个 Redis 分片 | 本地配额 + 异步上报 |
| 安全 | userID 未校验、key 可预测 | 鉴权、key 前缀隔离、防枚举 |
| 可观测性 | 没有 metrics/log | 限流触发率、拒绝原因、依赖耗时 |
| 幂等 | 重试导致重复扣配额 | 请求 ID / 窗口内去重 |
| 资源泄漏 | 连接不关、脚本不缓存 | Pool、SCRIPT LOAD |
升华话术(限流题可直接用,其他题换成对应隐患):
Demo 已经满足需求并通过并发验收。生产上还有三件事必须做:
1)Redis 强依赖要有降级,不能让所有业务一起挂;
2)热点 Key 要用本地缓存 + 异步上报,避免打满单分片;
3)接口要打点,限流触发频率要告警。
这些不是这 45 分钟的范围,但是我会在设计里把扩展点留出来。
面试官听到的是:你知道 Demo 和 Production 的边界,并且不会把 AI 生成的能跑代码直接当上线方案。
2. 实战样板:分布式限流 API
题目:用 AI 辅助,实现按 userID 限流,每分钟最多 10 次。
2.1 口头对齐(30--60 秒)
- 分布式(多网关)→ Redis 做存储
- Demo 用固定窗口,承认边界突发是已知取舍
- 失败策略先 fail-close(内部错误不放行),生产再讨论降级
- 验收必须包含并发超卖
2.2 先写契约,不写逻辑
go
type RateLimiter interface {
// Check 检查 userID 是否允许访问
// allowed: 是否放行; remaining: 剩余次数; err: 内部错误(依赖故障等)
Check(ctx context.Context, userID string) (allowed bool, remaining int, err error)
}
type LimiterConfig struct {
MaxRequests int // 例如 10
Window time.Duration // 例如 1 分钟
}
2.3 先写 verify.md
markdown
## 限流器验收
1. 正常请求:同一 userID 连续 10 次,全部 allowed = true
2. 触发限流:第 11 次必须 allowed = false
3. 窗口重置:等待窗口结束后再次请求,allowed = true,剩余次数重置
4. 并发安全:100 个并发请求,最终放行必须严格是 10,不能超卖
5. 依赖故障:Redis 超时/不可用时返回 err,不静默放行(Demo 约定 fail-close)
2.4 驱动 AI,并当场抓住经典坑
AI 常写出:
go
count, _ := redis.Get(ctx, key).Int()
if count < config.MaxRequests {
redis.Incr(ctx, key) // 坑:Get 与 Incr 非原子,并发超卖
return true, ...
}
return false, ...
你要立刻指出:这是 Junior 级代码。正确方向是 INCR + 首次 EXPIRE ,或 Lua 脚本 把读-判-写收成一次原子执行。同时提醒:EXPIRE 必须跟在首次 INCR 之后且要处理脚本失败,否则 key 可能永不过期。
纠偏 Prompt 示例:
你的实现有并发问题,Get 和 Incr 不是原子操作。请用 Redis Lua 重写 Check,保证计数、阈值判断、过期设置在同一次脚本执行内完成;并补上并发超卖测试。
2.5 跑绿之后的演进(30 秒说完)
- 固定窗口 → 滑动窗口 / 令牌桶(削掉窗口边界双倍突发)
- Redis 故障 → 本地限流降级 + 明确 fail-open / fail-close 的业务选择
- 热点 userID → 网关本地 token + 异步同步 Redis
- Metrics:
rate_limit_allowed_total/rate_limit_rejected_total/redis_error_total
3. 工程内核:面试流程背后其实是一套协作范式
现场 5 步不是表演,它对应真实 AI 协作里已经被验证的分层:
规格层 SDD 接口、PRD、API 契约 → 做什么的唯一真源
验收层 ATDD verify.md / 卡点表 → 做完了的判据
协作层 BDD Given/When/Then Prompt → 降低理解错半截的概率
单测层 TDD 只打纯函数 → 精确狙击,不地毯轰炸
纪律层 管线 + 幻觉防护 → 四种范式都覆盖不到的第五层
默认组合:SDD + ATDD 为主干,TDD 局部补,BDD 当 Prompt 模板。
不要为了「显得专业」在面试里强推全量 TDD。很多坑根本进不了单测:
- 框架 debug/release 行为不一致
- 跨网络时序竞态
- 提交流程漏文件
- 静默失效的守卫(代码不报错,路径从未走到)
这些要靠:架构设计、人工收口、grep 核验真实 API、二审但不盲信。
3.1 人工必须收口的点(后端尤其如此)
把这句话背熟:
AI 负责提速,人负责边界正确性。AI 不会主动报告「这里我不确定」。
后端高频收口清单:
- 协议字段与调用方口径是否一致
- 状态机是否防重(领取、扣费、下单)
- 扣减与发放是否匹配配置,有没有超卖
- 错误码是否覆盖边界,失败是可重试还是不可重试
- 任何「看起来应该存在」的方法/配置/错误码,先核验真实定义
3.2 跨会话与并行:面试里也可以展示这层意识
如果题目做大了,或面试官问「你平时怎么带 AI 做需求」,补这三句就够:
- AI 没有工作记忆,稍大的任务必须把验收清单落到文件,否则换会话就丢进度
- 多 Agent 并行会把单点幻觉复制扩散;任务要按验收条目切分,不能按「你做这一块」这种模糊边界切
- 二审 Agent 也会出错,主责任人必须对「API 不存在 / 拼写错误」类警告做 grep 复核,不能凭印象判假阳性
面试现场一般是单 Agent。你只要表现出「我知道并行会放大错误」,已经比大多数候选人高一层。
4. 现场时间分配(45 分钟建议)
| 时间 | 动作 | 目的 |
|---|---|---|
| 0--5 min | 对齐需求、说出取舍 | 证明你会定 Scope |
| 5--10 min | 手写接口 + verify.md | 证明你会定契约和完成定义 |
| 10--25 min | 分步 Prompt + 指出 AI 的坑 | 证明你能管 Junior |
| 25--35 min | 跑验收、修原子性/边界 | 证明你能把质量闭环 |
| 35--45 min | Review + 生产演进 | 证明你有线上意识 |
宁可少写一个 CRUD 页面,也不要跳过并发验收和生产演进。 大厂后端面试官对「能跑的错误代码」零好感。
5. 高分话术 vs 减分行为
5.1 建议当众说出来的话
- 「我先不定实现,先定接口和验收。」
- 「这个取舍是为了 Demo 可验证;生产我会换成......」
- 「AI 这段在单线程正确,并发会超卖,我不能收。」
- 「规格没写的守卫我不会让它自造,先标待确认。」
- 「测试绿灯只说明清单覆盖到的路径过了,时序和依赖故障还要单独看。」
5.2 明确减分的做法
| 减分行为 | 面试官心里的评价 |
|---|---|
| 打开 AI 就说「帮我实现一个限流器」 | 把面试交给工具 |
| 一个 Prompt 生成整个项目 | 没有架构控制力 |
| AI 写错了默默手改,不解释 | 浪费了展示排坑的机会 |
| 绿灯就停,不 Review | 只有执行没有判断 |
| 把 Demo 说成生产方案 | 缺乏线上意识 |
| 编造自己没做过的流程/数据 | 诚信风险,一票否决 |
| 为了显得会 AI 而强上 Cucumber/全量 TDD | 工具崇拜,不懂取舍 |
5.3 什么时候自己写,什么时候交给 AI
- 自己写: 接口、关键不变量、验收用例、错误语义、降级策略
- 交给 AI: 样板实现、Lua 脚本草稿、测试脚手架、重复的 CRUD
- 必须你审: 并发、金钱/配额、鉴权、状态机、和外部系统的契约
一句话:意图、契约、风险归你;体积和速度归 AI。
6. 把实习经历接进这套叙事(真实、可核对)
对外只讲方法,不讲内部路径、工单号、文档原文。
可稳定使用的三条:
- 用「规格锚点 + 验收清单 + 结构化派单」做 AI 协作,降低跨会话跑偏。
- AI 出草案,人工收口协议字段、状态流转、扣费发奖、错误码边界。
- 并行小需求用拆解、二审、留痕防止同类错误重复出现。
对应面试问答:
Q:你说规格锚点 + 验收清单,具体怎么做?
先拆不可变条件(协议、状态机)和可变配置(ID、数量)。清单覆盖参数、扣费、发奖、状态、错误码。跨会话也按同一标准收口。
Q:人工收口收什么?
协议口径、防重状态、配置与发放一致性、错误码边界。这四类不把关,上线风险最高。
Q:那你个人价值在哪?
AI 是加速器,不是替代判断。价值在需求抽象、边界识别、协同推进、上线收口。
更细的脱敏话术与案例见同目录:奥拉星实习_AI协作包装与面试话术.md。
7. 面试官视角:怎样才算「最好」
最好的方式不是 Prompt 写得花、也不是生成速度最快,而是让面试官连续看到这四件事:
- 系统设计: 先定接口和边界,再允许 AI 动代码
- 质量保障: 先写 verify / 关键测试,用验收锁死幻觉
- 后端基本功: 一眼看穿竞态、超卖、非原子、静默失败
- 大局观: 绿灯之后主动讲降级、热点、监控、演进
这四件事叠在一起,面试官看到的就不是「会用工具的应届/实习生」,而是:在有了 AI 这个超级 Junior 之后,工程思维足够深、收口足够狠的人。
记住最后一句,作为整场面试的自我定位:
我不是在用 AI 写代码。我是在用规格、验收和审查,管理一个不会说「我不确定」的高速执行器。