跳转至

第十四章 面试专项:从简历证据到项目深挖

大模型岗位面试通常同时验证四件事:基础原理是否扎实,代码与算法是否能落地,项目是否真正做过,面对未知问题是否能建立可验证的分析。近期公开面经反复出现 RAG 切块/召回/重排、Agent 工具与记忆、微调数据与 LoRA、服务性能、模型结构和项目 bad case。准备时不要背孤立答案,而要建立“定义—机制—取舍—指标—故障”的表达框架。

大模型面试能力金字塔

图 14-1 项目表达建立在基础、代码和评估之上;只背术语无法承受追问。

14.1 先读岗位,而不是先刷题

先建立直觉。 岗位描述是能力假设,不是关键词清单。先判断岗位偏模型、训练、应用、推理还是平台,再把要求映射到可证明的项目证据。 读这一节时,先不要急着记缩写,而要不断追问:输入是什么,经过了哪些可观察变换,输出又怎样被验证。

把过程拆开看:

  1. 标出必须项和加分项。
  2. 按职责归类技术。
  3. 找到自己证据与缺口。
  4. 决定准备优先级。

最小例子。 岗位强调 RAG 评估与上线,就应准备数据、指标、故障和监控,而不是只背 Transformer 公式。 例子越小,越容易手算、打印中间量并判断实现是否偏离定义。

容易踩坑。 一份简历投所有岗位、只按出现频次背题、把不会的工具写熟练,都会在追问中暴露。 排错时应保存失败输入和版本,先定位最早出现异常的步骤,再决定是否调整模型或超参数。

动手任务:选择三个真实 JD 做能力矩阵,写出共同核心与岗位差异。 完成后不要只保存最终输出,还要保存代码、配置、中间张量或检索结果,以及你对结果的解释。

将 JD 拆成模型算法、应用算法、平台工程、多模态或研究方向。模型算法偏训练、对齐和分布式;应用算法偏 RAG、Agent、评估与服务;平台工程偏推理引擎、调度、监控和成本。为每项要求准备一条证据:课程不算证据,代码、实验、指标、设计文档和线上结果才算。

建立技能矩阵:能解释、能手写、能调试、能设计、能量化。不会的内容如实标注学习中,不要把“调用过 API”写成“精通模型训练”。

14.2 简历:每个数字都能被复现

从问题出发。 简历的每个数字都是一个实验结论,应能回答定义、基线、数据、硬件、时间窗口、个人贡献和不确定性。项目 bullet 用问题—约束—动作—取舍—指标表达。 先把名词放到一边,沿着输入、状态变化和输出走一遍;只有能指出证据落在哪一步,概念才算真正掌握。

沿数据流逐步检查:

  1. 给出业务和技术基线。
  2. 说明你亲自做的决策。
  3. 写指标及评估条件。
  4. 准备失败与局限。

用小数据走一遍。 Recall@5 从 0.69 到 0.84 必须说明相关块标注、查询数、索引版本和是否存在数据泄漏。 先在纸面预测结果,再让程序打印中间状态;预测与运行不一致的地方,正是需要继续追查的知识缺口。

这里最容易出现的误解。 数字无出处、把团队成果写成个人、只列技术栈、没有失败样例,会降低可信度。 出现异常时先冻结样本、配置和环境,从最靠近输入的环节开始验证;不要同时更换模型、数据和超参数。

小实验:逐条给简历数字建立证据卡;无法复现的数字删除或改成定性描述。 提交物应包含预期、运行证据和失败记录;只有别人能按同样步骤复现,结果才具有学习价值。

项目 bullet 推荐结构:业务问题 + 约束 + 个人动作 + 技术取舍 + 指标 + 评估条件。不要写“负责 RAG 系统,准确率提高 30%”而不说明准确率定义。

一段可追问的写法:

面向 8 万页设备手册的售后问答,负责解析、标题感知切块和检索评估。构建 360 条人工标注查询,以 BM25 为基线,引入 Dense+BM25 RRF 与 Cross-Encoder 重排,将 Recall@5 从 0.69 提升至 0.84、引用准确率从 76% 提升至 90%;通过异步召回和重排批处理将 P95 从 2.8 秒降至 1.7 秒。

准备数字的出处:评估集怎样抽样、谁标注、基线版本、置信区间、硬件和时间窗口。没有真实线上数据就明确写“离线评估”,不要暗示线上收益。

14.3 三分钟项目介绍

先看它解决什么。 三分钟介绍要先让听者理解问题和约束,再讲方案与个人决策,最后用指标和失败证明真实做过。组件清单不是项目故事。 理解的标准不是会复述定义,而是能画出数据流、预测中间结果,并设计一个让错误暴露出来的检查。

可以把实现分成以下环节:

  1. 30 秒背景与目标。
  2. 30 秒数据和约束。
  3. 60 秒核心方案与取舍。
  4. 40 秒结果。
  5. 20 秒失败和下一步。

一个可以手算的例子。 讲混合检索时说明为何纯向量漏掉型号、怎样标注评估集、RRF 带来何种可复现提升。 这里故意不用大模型或大数据,因为小输入能把每个轴、分数和状态变化完整暴露出来。

排错时先看这些地方。 铺垫两分钟、只念架构图、不说个人贡献、结果只有‘效果很好’,都会失去重点。 修复不能止于‘这次跑通’,还要把失败样本变成自动测试,防止同类问题在下一版本重新出现。

现在动手:录制三次项目介绍,分别删减到 180 秒并让不了解项目的人复述。 把关键断言写进测试,并在 README 说明怎样运行、怎样判断正确、当前实现还不支持什么。

建议按以下顺序:

  1. 背景:用户是谁,痛点是什么,为什么需要大模型。
  2. 约束:数据、延迟、成本、隐私、更新频率。
  3. 方案:数据流和关键组件,为什么这样选。
  4. 本人贡献:亲自实现、设计和决策的部分。
  5. 结果:基线、指标、实验条件。
  6. 失败与迭代:最难 bad case、如何定位、还剩什么问题。

面试官最关心第 4—6 项。架构图能帮助表达,但不要花两分钟念组件名。

14.4 高频基础题:回答骨架

技术问题回答框架

图 14-2 一个可追问的答案应包含定义、机制、取舍、证据和边界。 抓住这一节的主线。 高频基础题要用定义—机制—公式或形状—取舍—验证五层回答。先给结论,再逐层展开,遇到不确定边界要明确。 遇到新术语,先找它在系统中的位置:它读取什么、保存什么、改变什么,以及失败时会留下什么信号。

真正动手时按这个顺序走:

  1. 一句话定义术语。
  2. 画数据流或写关键公式。
  3. 说明为什么这样设计。
  4. 比较替代方案。
  5. 给实验或故障例子。

先做最小实验。 回答 GQA 时先说 KV 头少于 Q 头,再写缓存公式,最后讨论质量、内存和 kernel 支持。 把随机性固定并保留中间量,这个例子就能成为后续优化时的回归基线。

别被表面现象带偏。 只背标准句、公式无变量、绝对化说‘更好’、混淆论文与具体模型实现,会被连续追问击穿。 先区分定义错误、实现错误、数据问题和性能瓶颈。四类问题需要的证据不同,不能靠盲目调参混在一起处理。

验证任务:为每类问题写 90 秒答案,并让同伴连续追问三个‘为什么’。 实验结束后写三句话:观察到了什么、这些证据支持什么结论、还有哪种解释尚未排除。

Transformer

为什么缩放点积要除以 \(\sqrt{d_k}\) 假设 q/k 各维独立、均值 0、方差 1,点积方差随 \(d_k\) 增长;缩放让 logits 尺度稳定,避免 Softmax 过饱和、梯度过小。进一步说明真实分布未必独立,但初始化尺度分析仍有指导意义。

Pre-Norm 与 Post-Norm? 说明归一化位置、残差路径与深层训练稳定性;不要只说“Pre-Norm 更好”,还可讨论最终归一化和模型具体实现。

MHA/GQA/MQA? 从 Q 头与 KV 头数量、KV Cache、质量和 kernel 支持比较,并写出缓存公式。

RoPE 为什么能表达相对位置? 旋转后的 q/k 点积只依赖角度差;说明它作用于 q/k,不作用于 v,并讨论长上下文外推不是改配置。

训练与微调

LoRA 为什么有效? 任务适配的权重更新常呈低内在秩;冻结 W,学习 BA。继续说明 rank/alpha、目标模块、初始化、合并与不足。

SFT 后复读? 从数据重复和模板单一、epoch/学习率、EOS、解码、标签 mask、灾难性遗忘逐层排查,用生成样例和 n-gram 重复率验证。

RAG 与微调如何选? 动态事实/引用优先 RAG,行为/格式优先 SFT;可组合。比较更新成本、可追溯、延迟和评估。

RAG

Chunk 多大? 没有固定答案。依据文档结构、Embedding 最大长度、问题粒度、召回与上下文预算,通过标注集搜索。说明 overlap 和父子块。

检索不准怎么排查? 先确认解析与标注,再看查询改写、Embedding、索引 Recall、过滤、top-k、混合检索、重排;不要直接换大模型。

怎样评估? 检索 Recall@K/MRR/nDCG,生成正确性/忠实度/引用,外加延迟成本;错误归因到组件。

Agent

记忆与上下文工程关系? 记忆是可持久状态来源,上下文工程决定每轮把哪些状态、工具、历史和证据放入有限窗口。说明写入审核、检索和遗忘。

Agent 为什么失败? 工具契约、状态、停止、权限、注入、重试与评估。给一个自己项目中的 trace 例子。

多 Agent 何时有价值? 子任务可分、并行收益高、输出可验证时;否则通信和故障成本大于收益。

对齐与推理

DPO 与 PPO? 从数据在线/离线、是否显式 RM/价值模型、实现复杂度、分布外探索和稳定性比较,并能写 DPO loss。

GRPO 的优势怎样算? 同一 prompt 多个回答的奖励做组内标准化;不需要独立价值模型。说明奖励同质和可验证奖励的限制。

FlashAttention 为什么快? IO-aware 分块减少 HBM 访问,是精确注意力;算术复杂度仍为二次。

量化精度为何下降? 尺度和舍入产生误差,离群值、粒度、校准数据、敏感层影响不同。区分真实 kernel 加速与仅存储压缩。

14.5 手撕代码题

先把概念落到可观察对象上。 手撕代码考察的是问题澄清、接口、正确性、复杂度和测试。大模型岗位常要求数值稳定与张量形状,不能只写 happy path。 这一节的重点是建立因果链。先说明问题,再看计算或流程,最后用可重复实验验证结论。

把抽象概念还原成操作:

  1. 先确认输入输出与边界。
  2. 写最小正确实现。
  3. 解释时间空间复杂度。
  4. 主动构造极值和错误输入。

把它缩小到能逐项检查。 稳定 Softmax 先减最大值;注意力要说明 axis、mask、dtype 和形状;LRU 要说明容量为零。 如果这个小例子还不能解释清楚,扩大数据只会让错误更难发现。

需要特别守住的边界。 沉默写代码、用库函数绕过核心、无测试、忽略 NaN/空输入/dtype,都会丢分。 保留完整 trace 比猜原因更重要。找到第一次偏离预期的位置,通常比分析最终错误输出更高效。

本节练习:限时手写 Softmax、RMSNorm、Attention、RoPE、RRF 和 LRU,并为每题写三个测试。 除代码外,请保留一份结果说明,标明环境、随机种子、输入规模和你主动检查过的边界。

优先练习:Softmax 数值稳定版、LayerNorm/RMSNorm、Self-Attention 与 mask、RoPE、GQA repeat_kv、Top-k/Top-p、交叉熵、LoRA Linear、DPO loss、余弦检索、RRF、LRU cache、生产者消费者、梯度累积。

写代码时先说输入输出与边界,再实现主逻辑,最后给测试。下面是稳定 Softmax:

import numpy as np

def softmax(x, axis=-1):
    x = np.asarray(x, dtype=np.float64)
    shifted = x - np.max(x, axis=axis, keepdims=True)
    exp = np.exp(shifted)
    return exp / np.sum(exp, axis=axis, keepdims=True)

def test_softmax():
    y = softmax([[1000.0, 1001.0]])
    assert np.all(np.isfinite(y))
    assert np.allclose(y.sum(axis=-1), 1.0)

面试中边写边解释形状、复杂度和数值稳定性。完成后主动测极值、空输入、维度和 dtype。

14.6 算法题准备

先建立直觉。 算法准备按模式建立迁移能力:哈希、双指针、滑窗、栈、二分、树、堆、图和动态规划。目标是从约束识别状态与不变量。 读这一节时,先不要急着记缩写,而要不断追问:输入是什么,经过了哪些可观察变换,输出又怎样被验证。

把过程拆开看:

  1. 复述题目并举例。
  2. 先给朴素解。
  3. 找重复计算或单调性。
  4. 证明优化并测试。

最小例子。 滑动窗口只有在窗口扩张/收缩能维护目标性质时成立;包含负数的和问题未必保持单调。 例子越小,越容易手算、打印中间量并判断实现是否偏离定义。

容易踩坑。 背模板不验证前提、复杂度说错、边界全交给面试官提醒、刷题后不重写,都会影响表现。 排错时应保存失败输入和版本,先定位最早出现异常的步骤,再决定是否调整模型或超参数。

动手任务:建立错题本,每题记录识别信号、核心不变量、最小反例和一周后重写结果。 完成后不要只保存最终输出,还要保存代码、配置、中间张量或检索结果,以及你对结果的解释。

大模型岗仍会考通用算法。按模式练习数组/哈希、双指针、滑窗、栈队列、二分、链表、树、堆、图、动态规划。目标不是刷数量,而是看到题能识别状态、证明正确、分析复杂度并写测试。

建立错题本:错误原因、正确模式、最小反例、重写日期。模拟面试限制 30—40 分钟,先澄清再编码;不要沉默十分钟后突然给答案。

14.7 系统设计题

从问题出发。 系统设计先问需求与 SLO,再估算流量、token、存储和模型资源,之后才画组件。答案要包含数据、接口、容量、安全、故障和成本。 先把名词放到一边,沿着输入、状态变化和输出走一遍;只有能指出证据落在哪一步,概念才算真正掌握。

沿数据流逐步检查:

  1. 澄清用户、规模和一致性。
  2. 估算峰值 QPS/token。
  3. 画主链路与异步链路。
  4. 设计降级、监控和回滚。

用小数据走一遍。 设计 70B 服务要讨论并行、prefill/decode、KV Cache、批处理和流量分布,而不是只说用 vLLM。 先在纸面预测结果,再让程序打印中间状态;预测与运行不一致的地方,正是需要继续追查的知识缺口。

这里最容易出现的误解。 一上来画微服务、没有数量级估算、忽略租户权限和数据删除、只谈正常路径,都会显得空泛。 出现异常时先冻结样本、配置和环境,从最靠近输入的环节开始验证;不要同时更换模型、数据和超参数。

小实验:完成企业 RAG、Agent 平台和模型服务三道设计,每道写容量估算。 提交物应包含预期、运行证据和失败记录;只有别人能按同样步骤复现,结果才具有学习价值。

典型题:“设计企业知识助手”“设计多租户 Agent 平台”“如何服务 70B 模型”。回答顺序:需求与 SLO、流量与数据、接口、架构、容量、安全、评估、故障与成本。

企业 RAG 重点谈权限、版本、引用、更新和评估;Agent 平台重点谈工具沙箱、凭据、确认、trace 和预算;模型服务重点谈 TTFT/TPOT、continuous batching、KV Cache、并行、量化和降级。

14.8 Bad case 深挖

先看它解决什么。 Bad case 深挖要讲首次异常信号、假设、证据、实验、修复和回归。面试官关注你怎样排除错误假设,而不只是最终换了什么组件。 理解的标准不是会复述定义,而是能画出数据流、预测中间结果,并设计一个让错误暴露出来的检查。

可以把实现分成以下环节:

  1. 冻结失败样本和版本。
  2. 分层构造假设。
  3. 一次验证一个变量。
  4. 修复后加入回归集。

一个可以手算的例子。 扫描 PDF 召回下降时,通过分文档类型发现 OCR 和标题丢失,修解析后恢复,而不是直接换 embedding。 这里故意不用大模型或大数据,因为小输入能把每个轴、分数和状态变化完整暴露出来。

排错时先看这些地方。 归因于‘模型不行’、没有失败数据、同时改多个组件、只报成功不报代价,都会不可信。 修复不能止于‘这次跑通’,还要把失败样本变成自动测试,防止同类问题在下一版本重新出现。

现在动手:为每个项目准备三个真实失败故事和一个仍未解决的问题。 把关键断言写进测试,并在 README 说明怎样运行、怎样判断正确、当前实现还不支持什么。

使用一张表准备每个项目的三个失败:现象、影响范围、假设、证据、实验、修复、回归。面试官可能连续问“为什么”,直到触及你的真实工作边界。

例如召回下降:先按文档类型分桶发现扫描 PDF 最差;检查 OCR 字符错误率与标题丢失;更换版面解析并保留页级标题;Recall@5 恢复;新增扫描件回归集。这个故事比“换了更好的 Embedding”更可信。

14.9 行为与协作

抓住这一节的主线。 行为题用具体情境说明决策与协作:目标冲突、信息不完整、时间压力和责任边界。STAR 只是结构,证据和反思才有价值。 遇到新术语,先找它在系统中的位置:它读取什么、保存什么、改变什么,以及失败时会留下什么信号。

真正动手时按这个顺序走:

  1. 交代任务与约束。
  2. 说明自己的判断和沟通。
  3. 给出结果与证据。
  4. 说明之后怎样改流程。

先做最小实验。 技术分歧中可讲如何定义共同指标、做小实验、记录决策,而不是说‘我说服了别人’。 把随机性固定并保留中间量,这个例子就能成为后续优化时的回归基线。

别被表面现象带偏。 把失败归因他人、故事没有个人动作、结果无法验证、每题套同一案例,都会显得准备痕迹重。 先区分定义错误、实现错误、数据问题和性能瓶颈。四类问题需要的证据不同,不能靠盲目调参混在一起处理。

验证任务:准备冲突、失败、取舍、推动和学习五个故事,每个控制在两分钟。 实验结束后写三句话:观察到了什么、这些证据支持什么结论、还有哪种解释尚未排除。

准备一次技术分歧、一次失败、一次跨团队协作、一次在约束下取舍。使用 STAR,但结果包含证据和反思。不要把所有问题归因于别人;说明你怎样改变流程,避免复发。

14.10 模拟面试清单

先把概念落到可观察对象上。 模拟面试要复现真实压力并产生反馈闭环。按岗位组合原理、代码、项目和系统设计,录音后逐项评分,而不是只数刷题数量。 这一节的重点是建立因果链。先说明问题,再看计算或流程,最后用可重复实验验证结论。

把抽象概念还原成操作:

  1. 建立评分量表。
  2. 严格计时和连续追问。
  3. 复盘事实错误与表达。
  4. 隔几天无稿重答。

把它缩小到能逐项检查。 回答正确但用了八分钟、没有先给结论,仍需改进;评分应包含结构、准确、证据和节奏。 如果这个小例子还不能解释清楚,扩大数据只会让错误更难发现。

需要特别守住的边界。 只和熟悉朋友练、提前知道题、复盘只看答案、最后一天高强度堆题,都会降低迁移。 保留完整 trace 比猜原因更重要。找到第一次偏离预期的位置,通常比分析最终错误输出更高效。

本节练习:完成至少三轮不同面试官的全流程模拟,记录可量化改进项。 除代码外,请保留一份结果说明,标明环境、随机种子、输入规模和你主动检查过的边界。

  • 60 秒自我介绍,3 分钟项目,10 分钟项目深挖。
  • 20 道核心原理题能够画图、写公式、说取舍。
  • 10 道手撕代码可在无补全环境写出并测试。
  • 2 道系统设计能估算容量与说明安全。
  • 每个简历数字有来源,每项技术能说一个失败。
  • 准备反问:团队目标、数据与评估、上线责任、研究/工程比例和成功标准。

14.11 经验来源与使用方式

先建立直觉。 公开面经用于发现能力维度和追问方式,不是公司固定题库。信息有样本偏差与时效性,应与岗位、官方技术栈和自身经历交叉验证。 读这一节时,先不要急着记缩写,而要不断追问:输入是什么,经过了哪些可观察变换,输出又怎样被验证。

把过程拆开看:

  1. 记录发布时间与岗位。
  2. 抽取反复出现的能力主题。
  3. 映射回本书章节。
  4. 用真实项目证据准备。

最小例子。 多篇面经提到 RAG 切块和评估,说明应会解释取舍,但不意味着背一个固定 chunk size。 例子越小,越容易手算、打印中间量并判断实现是否偏离定义。

容易踩坑。 照抄答案、泄露公司保密题、把个例当招聘标准、为匹配面经虚构经历,都会适得其反。 排错时应保存失败输入和版本,先定位最早出现异常的步骤,再决定是否调整模型或超参数。

动手任务:汇总 20 篇近期公开面经,按能力而非题目建立频次表,并标注来源。 完成后不要只保存最终输出,还要保存代码、配置、中间张量或检索结果,以及你对结果的解释。

公开面经具有样本偏差,不能据此推断每家公司固定题库;它们的价值是发现反复出现的能力维度。近期牛客面经中,项目深挖常涉及多 Agent 编排、失败重试、RAG 热更新、Embedding/Rerank 选择、切块优化、微调复读与算法题。将这些主题映射回本书对应章节,比背“标准答案”更有效。

最后的判断标准不是“背了多少题”,而是能否把一个陌生问题拆成可验证假设,能否写出正确最小实现,能否用数据解释取舍。这也是整本书希望训练的能力。

本章配套代码

下面的脚本与正文使用相同符号。建议先在代码中打印形状和中间量,再运行断言;若依赖尚未安装,至少先阅读入口函数、输入输出和测试部分。

本章端到端实验:把知识变成可复现证据

本实验不是把本章代码重新抄一遍,而是把概念、实现、测试和解释串成一个小型工程。请新建独立目录,保存 README.md、环境文件、源代码、测试、运行日志和结果图。README 至少说明任务、输入输出、运行命令、预期现象、已知限制和复现条件。

实验步骤

  1. 选择三个真实 JD 做能力矩阵,写出共同核心与岗位差异。
  2. 逐条给简历数字建立证据卡;无法复现的数字删除或改成定性描述。
  3. 录制三次项目介绍,分别删减到 180 秒并让不了解项目的人复述。
  4. 为每类问题写 90 秒答案,并让同伴连续追问三个‘为什么’。
  5. 限时手写 Softmax、RMSNorm、Attention、RoPE、RRF 和 LRU,并为每题写三个测试。
  6. 建立错题本,每题记录识别信号、核心不变量、最小反例和一周后重写结果。

每完成一步,先写下预期,再运行代码。若结果与预期不一致,不要覆盖旧日志;建立 failures.md,记录现象、假设、证据、修复和回归测试。这样得到的不是一次性 Demo,而是一份能证明你真正理解本章内容的实验档案。

验收标准

  • 全新环境能够按照 README 从头运行,依赖和随机种子已记录。
  • 关键函数至少有正常、边界和错误输入三类测试;涉及数值计算时检查有限值与合理误差。
  • 结果包含一个基线和至少一个受控改动,能够说明变化来自哪里。
  • 日志保留输入规模、耗时、内存或显存、软件版本和失败样本。
  • 结论区分“实验直接证明的事实”“根据事实做出的推断”和“仍未验证的猜想”。

本章自测

  1. 不看正文,用自己的话解释“岗位描述是能力假设,不是关键词清单”,并给出一个可以证伪的测试。
  2. 不看正文,用自己的话解释“简历的每个数字都是一个实验结论,应能回答定义、基线、数据、硬件、时间窗口、个人贡献和不确定性”,并给出一个可以证伪的测试。
  3. 不看正文,用自己的话解释“三分钟介绍要先让听者理解问题和约束,再讲方案与个人决策,最后用指标和失败证明真实做过”,并给出一个可以证伪的测试。
  4. 不看正文,用自己的话解释“高频基础题要用定义—机制—公式或形状—取舍—验证五层回答”,并给出一个可以证伪的测试。
  5. 不看正文,用自己的话解释“手撕代码考察的是问题澄清、接口、正确性、复杂度和测试”,并给出一个可以证伪的测试。
  6. 不看正文,用自己的话解释“算法准备按模式建立迁移能力:哈希、双指针、滑窗、栈、二分、树、堆、图和动态规划”,并给出一个可以证伪的测试。

回答时先画图或写形状,再给结论。若只能说出术语而不能给出最小例子、边界条件和验证方法,说明这一节仍需要回到代码中重做。