1. 为什么这8个问题成了LLM面试的分水岭面过LLM岗位的人大概都有体会面试官不会花一个小时跟你聊人生理想往往前二十分钟就能判断出你是“真做过”还是“背过”。标题里说的“答不上来直接淘汰”不是危言耸听我带过几轮校招和社招之后发现真正拉开差距的就是那8个反复出现的问题。它们覆盖了从Transformer架构到Tokenization、从Function Calling到智能体容错的完整链路任何一个环节答得含糊面试官基本就能判断你只是调用过API没碰过底层。这篇文章不是面试八股文的复读机。我会把这8个问题拆开讲清楚每个问题背后面试官到底想听什么、常见的错误回答长什么样、以及一个合格从业者应该怎么组织答案。适合准备算法工程师面试、智能体工程师面试、AIGC产品经理面试的朋友也适合已经在大模型方向工作但想系统梳理知识体系的人。全文基于我自己的面试经历和带人经验整理涉及参数计算和代码的地方我会给出具体过程方便你直接抄作业。先说一个前提这8个问题不是孤立的它们之间有清晰的依赖关系。Transformer是地基Tokenization是输入层注意力机制是核心引擎Function Calling是模型与外部世界交互的接口智能体容错是工程落地的保障。面试官问的顺序通常也是从底层往上走所以你的回答也要有层次感不能东一榔头西一棒子。2. 问题一Transformer为什么能取代RNN2.1 面试官真正想听的不是“并行计算”四个字几乎每个人都会说“Transformer可以并行计算RNN不行”。这个答案对但只值60分。面试官接着会问并行计算具体体现在哪一步为什么RNN不能并行如果你答不上来就暴露了你只是背了结论。Transformer的并行性体现在训练阶段。RNN的隐藏状态 ( h_t ) 依赖于 ( h_{t-1} )这是一个严格的串行依赖链第100个时间步必须等前99个算完。而Transformer的自注意力机制中每个位置的输出可以同时计算因为注意力权重 ( \text{softmax}(QK^T/\sqrt{d_k})V ) 中Q、K、V三个矩阵的运算是矩阵乘法GPU可以一次性并行处理所有位置。但这里有个容易被忽略的点Transformer在推理阶段自回归生成其实也是串行的每生成一个token都要等前一个token出来。所以准确的说法是“训练并行推理自回归”。能把这个区分讲清楚面试官会认为你真的跑过模型。2.2 复杂度对比与位置编码的必要性面试官常追问的第二个层次是复杂度。RNN的序列操作复杂度是 ( O(n) )Transformer的自注意力是 ( O(n^2) )其中n是序列长度。这意味着序列越长Transformer的计算和显存开销增长越快。这也是为什么后来出现了各种稀疏注意力、线性注意力的变体。位置编码是另一个必问点。因为自注意力本身是置换不变的打乱输入顺序输出不变所以必须注入位置信息。原始论文用的是正弦位置编码[ PE_{(pos, 2i)} \sin(pos / 10000^{2i/d_{model}}) ] [ PE_{(pos, 2i1)} \cos(pos / 10000^{2i/d_{model}}) ]现在主流模型多用可学习的位置编码或RoPE旋转位置编码。RoPE的核心思想是通过旋转矩阵将位置信息编码进Q和K的内积中使得注意力分数天然携带相对位置信息。面试时如果能提到RoPE并解释它为什么在长文本场景下更优基本能加分。注意不要一上来就背公式先讲直觉。位置编码就像给每个词发一个“座位号”没有座位号模型分不清“猫追狗”和“狗追猫”。2.3 实操心得手写Transformer时最容易翻车的三个地方我试过从零手写Transformer踩过的坑分享给你。第一注意力掩码写错。解码器需要因果掩码确保位置i只能看到位置≤i的信息如果掩码矩阵写反了模型训练loss会异常低但推理时完全胡说。第二层归一化的位置。原始论文是Post-LN残差后归一化后来GPT系列改成Pre-LN残差前归一化Pre-LN训练更稳定不容易梯度爆炸。第三学习率预热。Transformer对学习率非常敏感warmup步数设少了前期loss震荡设多了收敛慢通常取总步数的1%到5%。3. 问题二Tokenization到底在做什么3.1 从字符到子词的权衡逻辑Tokenization是很多人觉得“太基础”而忽略的环节但面试官恰恰喜欢从这里切入因为它是连接原始文本和模型的桥梁。核心问题是为什么不用字符级或词级而要用子词级字符级词表小英文26个字母但序列太长一个句子几百个token注意力计算吃不消。词级词表大几十万但遇到未登录词就抓瞎而且中文分词本身就有歧义。子词级Subword是折中方案代表算法有BPE、WordPiece、Unigram。BPEByte Pair Encoding的思路很直接从字符开始统计相邻字符对频率把最高频的 pair 合并成新token重复直到达到目标词表大小。比如“lower”出现频率高“l o w e r”可能被合并成“low”和“er”。WordPiece和BPE类似但合并标准是似然增益而非频率。Unigram反过来从大词表开始逐步裁剪。3.2 中文场景下的特殊坑中文的Tokenization比英文更麻烦。一个中文字符可能对应多个byteUTF-8编码下常用汉字占3个byte。如果直接按byte做BPE一个汉字可能被拆成3个token序列长度膨胀三倍。所以中文模型通常会在预处理阶段做特殊处理或者直接用字符级tokenizer配合大词表。我实测过一个中文句子用某开源tokenizer编码后token数是原字数的1.8倍而英文大约是0.75倍。这意味着同样长度的中英文文本中文消耗的上下文窗口更多。做长文本应用时这个差异必须考虑进去否则你会奇怪为什么中文文档总是超长。提示面试时如果被问到“如何优化中文Tokenization”可以从词表扩充、字符级回退、以及训练领域专用tokenizer三个角度回答。3.3 词表大小对模型的影响词表大小是个需要权衡的参数。词表太小序列变长注意力开销大词表太大embedding矩阵参数量暴涨而且低频token训练不充分。常见模型词表在3万到15万之间。LLaMA系列用32000ChatGLM用130000左右因为中文需要更大词表。embedding矩阵的参数量计算很简单词表大小 × 隐藏维度。比如词表50000、隐藏维度4096embedding层就有约2亿参数。如果词表翻倍这部分参数也翻倍对小模型来说负担很重。4. 问题三注意力机制的QKV到底怎么理解4.1 用图书馆类比讲清楚QKVQKV是面试必问中的必问。我见过太多人背“Query是查询Key是键Value是值”然后就没有然后了。面试官想听的是你能否用直觉解释清楚。我的类比是图书馆找书。你走进图书馆脑子里有一个需求Query比如“我想找一本讲深度学习的书”。书架上的每本书都有一个标签Key比如“深度学习”“烹饪”“历史”。你拿Query去和每个Key比对匹配度高的书获得高权重。最后你把这些书的内容Value按权重加权求和得到你要的答案。对应到公式( \text{Attention}(Q,K,V) \text{softmax}(\frac{QK^T}{\sqrt{d_k}})V )。( QK^T ) 就是Query和每个Key的点积相似度除以 ( \sqrt{d_k} ) 是为了防止点积过大导致softmax梯度消失。softmax归一化后得到权重再乘以V。4.2 多头注意力为什么有效多头注意力是把Q、K、V分别投影到多个子空间每个头独立计算注意力最后拼接。直觉解释是不同的头可以关注不同的模式。有的头关注语法关系主谓宾有的头关注语义相似度有的头关注位置邻近。面试官可能追问多头注意力的计算量比单头大多少假设隐藏维度是d头数是h每个头的维度是d/h。单头注意力的计算量是 ( O(n^2 \cdot d) )多头是 ( h \cdot O(n^2 \cdot d/h) O(n^2 \cdot d) )理论上计算量相同。但实际实现中多头会有额外的投影和拼接开销所以略慢一点。4.3 代码层面的实现细节手写多头注意力时关键步骤是reshape和transpose。假设输入形状是(batch, seq_len, d_model)先经过线性层得到Q、K、V形状不变。然后reshape成(batch, seq_len, num_heads, d_k)再transpose成(batch, num_heads, seq_len, d_k)。这样每个头就能独立做矩阵乘法。import torch import torch.nn as nn class MultiHeadAttention(nn.Module): def __init__(self, d_model, num_heads): super().__init__() self.num_heads num_heads self.d_k d_model // num_heads self.W_q nn.Linear(d_model, d_model) self.W_k nn.Linear(d_model, d_model) self.W_v nn.Linear(d_model, d_model) self.W_o nn.Linear(d_model, d_model) def forward(self, x, maskNone): batch, seq_len, _ x.shape Q self.W_q(x).view(batch, seq_len, self.num_heads, self.d_k).transpose(1, 2) K self.W_k(x).view(batch, seq_len, self.num_heads, self.d_k).transpose(1, 2) V self.W_v(x).view(batch, seq_len, self.num_heads, self.d_k).transpose(1, 2) scores torch.matmul(Q, K.transpose(-2, -1)) / (self.d_k ** 0.5) if mask is not None: scores scores.masked_fill(mask 0, -1e9) attn torch.softmax(scores, dim-1) out torch.matmul(attn, V).transpose(1, 2).contiguous().view(batch, seq_len, -1) return self.W_o(out)这段代码面试时如果被要求手写注意三个点mask的填充值用负无穷或很大的负数、transpose后要contiguous才能view、以及缩放因子 ( \sqrt{d_k} ) 不能漏。5. 问题四Function Calling的底层原理是什么5.1 从Prompt到结构化输出的演进Function Calling是当前智能体方向面试的高频题。早期做法是在prompt里描述工具让模型输出特定格式的文本然后正则解析。这种做法脆弱模型稍微跑偏就解析失败。后来OpenAI推出了原生Function Calling模型直接输出结构化的JSON包含函数名和参数。底层原理其实不神秘。模型在训练阶段见过大量“用户请求-函数调用”的配对数据学会了在特定语境下输出特定格式。推理时系统会把可用函数的schema名称、描述、参数类型作为特殊token注入上下文模型根据这些信息决定是否调用、调用哪个、参数填什么。5.2 参数校验与错误处理实际工程中Function Calling最麻烦的不是让模型输出JSON而是处理模型输出的错误参数。比如模型可能把日期写成“明天”而不是“2026-05-12”或者把数字写成字符串。所以生产环境必须在模型输出后加一层校验。我的做法是定义严格的JSON Schema用Pydantic或类似库做校验。校验失败时把错误信息回传给模型让它重新生成。这个重试机制通常设置2到3次上限避免死循环。注意不要完全信任模型的输出。我见过模型在参数里塞入额外字段、漏掉必填字段、甚至输出不存在的函数名。校验层是必须的不是可选的。5.3 多工具编排的挑战当可用工具超过10个时模型的选择准确率会下降。解决方案有两种一是分层路由先用一个轻量模型或规则做粗筛缩小候选工具范围二是把工具描述写得更有区分度避免功能重叠。另一个坑是工具调用的顺序依赖。比如先查天气再订机票如果模型并行调用两个工具可能拿到错误结果。这时候需要在系统提示里明确说明依赖关系或者在编排层做串行控制。6. 问题五如何评估一个LLM的输出质量6.1 自动指标与人工评估的取舍评估是面试中容易被低估的环节。很多人只会说“用BLEU和ROUGE”但这两个指标在生成式任务上相关性很差。BLEU基于n-gram重叠对于开放式生成几乎没用因为同一个意思可以有无数种表达。现在主流的自动评估方案有三类基于嵌入的相似度如BERTScore、基于LLM的评估用GPT-4打分、以及任务特定指标如代码任务的passk。BERTScore计算生成文本和参考文本的语义相似度比BLEU好很多但仍有局限。LLM评估更灵活但成本高且有位置偏见倾向于给靠前的选项高分。人工评估是金标准但成本高、一致性差。我的经验是自动指标做日常迭代监控人工评估做关键节点验收。两者结合不要偏废。6.2 构建领域评估集的实操步骤通用评估集如MMLU、HellaSwag只能反映模型的通用能力不能反映它在你的业务场景下的表现。所以必须构建领域评估集。步骤是这样的第一从真实业务日志中采样500到1000条输入覆盖主要场景和边缘case。第二为每条输入写参考答案或者定义评分标准如事实准确性、格式合规性、安全性。第三用待评估模型生成输出人工或LLM打分。第四计算平均分和方差方差大说明模型不稳定。这个过程听起来简单但实际做起来很耗时。我建议先用100条快速验证评估流程跑通后再扩展到全量。6.3 常见评估陷阱第一个陷阱是数据泄漏。评估集的问题如果出现在训练数据里分数会虚高。所以评估集必须严格隔离最好由不同的人构建。第二个陷阱是评估标准模糊。比如“回答是否有帮助”这种标准不同标注员理解不同导致一致性低。解决办法是把标准拆细比如“是否包含用户问的所有要点”“是否有事实错误”“格式是否符合要求”。第三个陷阱是忽略延迟和成本。一个模型准确率高但推理慢、费用贵在生产环境可能不可用。所以评估要包含延迟、吞吐量、单次调用成本等工程指标。7. 问题六智能体的容错控制怎么做7.1 智能体失败的典型模式智能体Agent和单轮问答的最大区别是它要执行多步操作每一步都可能出错。常见失败模式有工具调用参数错误、工具返回异常未处理、多步规划偏离目标、陷入循环、以及上下文超长导致遗忘。面试官问容错控制其实是想看你有没有真正部署过智能体。只做过demo的人通常没考虑过这些。7.2 分层容错架构我的方案是三层防护。第一层是输入校验在工具调用前检查参数合法性不合法直接拦截并让模型重新生成。第二层是执行监控每一步执行后检查结果是否符合预期比如API返回码、数据格式、数值范围。第三层是全局兜底设置最大步数限制和超时机制超过阈值就终止并返回当前最佳结果。重试策略也要区分。参数错误可以重试但网络超时重试可能加重服务负担需要指数退避。逻辑错误如规划偏离重试没用需要重新规划。7.3 状态管理与回滚多步智能体需要维护状态。我通常用一个状态字典记录每一步的输入、输出、时间戳和状态标记。如果某一步失败可以回滚到上一个成功状态而不是从头开始。这个设计在长流程任务中特别重要。比如一个订票智能体已经选好航班和座位支付步骤失败了回滚到选座状态比重新搜索航班高效得多。提示状态管理要考虑持久化。如果智能体运行时间较长进程崩溃后状态丢失会很麻烦。可以用Redis或数据库做checkpoint。8. 问题七如何优化LLM的推理速度8.1 量化、蒸馏与剪枝的适用场景推理优化是工程岗必问。三大方向量化、蒸馏、剪枝。量化是把FP16权重转成INT8或INT4减少显存占用和计算量。蒸馏是用大模型教小模型让小模型获得接近大模型的能力。剪枝是去掉不重要的权重或层。量化最实用因为改动小、收益明显。INT8量化通常能减少一半显存速度提升30%到50%精度损失很小。INT4量化更激进显存减少75%但精度损失需要评估。GPTQ和AWQ是当前主流的量化方法。蒸馏适合需要极致延迟的场景但训练成本高且小模型的能力上限受限于大模型。剪枝在LLM上效果不如在CV模型上明显因为LLM的权重分布更密集。8.2 KV Cache的原理与显存计算KV Cache是自回归生成的关键优化。没有KV Cache时每生成一个token都要重新计算所有历史token的K和V计算量随序列长度平方增长。有了KV Cache历史K和V缓存下来每步只计算新token的K和V计算量降为线性。但KV Cache占显存。计算公式是2 × batch_size × seq_len × num_layers × num_heads × d_k × 精度字节数。以LLaMA-7B为例32层、32头、d_k128、FP16精度序列长度2048、batch size 1时KV Cache约1GB。序列长度翻倍显存也翻倍。这就是长文本推理显存暴涨的原因。8.3 批处理与连续批处理批处理能提高GPU利用率但传统批处理要等最长的序列生成完才能处理下一批短序列浪费了等待时间。连续批处理Continuous Batching动态地把新请求插入到正在运行的批次中显著提升吞吐量。vLLM和TensorRT-LLM都支持这个特性。我实测过在同等硬件下连续批处理比朴素批处理吞吐量提升2到4倍具体取决于请求长度分布。如果请求长度差异大提升更明显。9. 问题八如何设计一个可靠的LLM应用架构9.1 从原型到生产的鸿沟最后一个问题通常是开放式的让你设计一个LLM应用。很多人会画一个“用户输入-模型-输出”的简单图但这远远不够。生产级架构要考虑缓存、限流、降级、监控、日志、安全过滤等。我的架构通常分四层接入层负责鉴权和限流编排层负责prompt组装和工具调度模型层负责推理和量化数据层负责缓存和日志。每层之间用异步消息队列解耦避免单点故障。9.2 缓存策略与成本控制LLM调用成本高缓存是必须的。缓存分两种精确缓存和语义缓存。精确缓存对相同输入直接返回结果实现简单但命中率低。语义缓存用嵌入向量做相似度匹配命中率高但有误判风险。我的做法是两级缓存先查精确缓存未命中再查语义缓存相似度阈值设0.95以上避免返回不相关结果。缓存失效策略用LRU加TTLTTL根据业务更新频率设定。9.3 监控指标与告警生产环境必须监控的指标包括请求延迟P50、P95、P99、错误率、token消耗量、缓存命中率、以及模型输出的安全违规率。告警阈值根据业务SLA设定比如P99延迟超过3秒告警。日志要记录完整的请求和响应但要注意脱敏。用户隐私数据不能明文存储可以用哈希或掩码处理。注意不要等到出问题才加监控。我见过团队上线三个月后才开始看延迟指标结果发现P99一直超标用户体验早就受损了。10. 面试中的表达技巧与避坑指南10.1 如何组织一个高分回答面试官问一个问题你的回答结构应该是先给结论再解释原理然后举实际例子最后说注意事项。比如问“Transformer为什么能并行”先说“因为自注意力是矩阵运算不依赖前一步结果”再解释QKV计算过程然后举训练和推理的区别最后提一句“推理阶段仍是自回归”。这个结构让面试官觉得你既有理论深度又有工程经验。切忌一上来就背公式也不要只讲概念不讲实践。10.2 遇到不会的问题怎么办诚实是最好的策略但不要只说“不会”。可以说“这个点我没有深入做过但我的理解是……如果让我做我会从……入手”。这样展示的是你的思考能力而不是知识盲区。面试官通常不会因为一个点不会就淘汰你但如果不懂装懂、胡编乱造一旦被追问就露馅那才是致命的。10.3 反问环节该问什么反问环节不是走过场。问得好能加分问得差会减分。推荐问三类问题团队当前的技术挑战是什么、模型部署的规模和数据量级、以及团队对新人前三个月的期望。避免问薪资福利、加班情况这些HR环节该问的问题。我个人的经验是反问环节能看出一个团队的技术成熟度。如果面试官能清晰描述技术栈和挑战说明团队有积累如果含糊其辞可能还在摸索阶段。11. 我踩过的坑与最后几条实用建议面了这么多轮也面了这么多人有几个坑我反复见到。第一个坑是只背不练。很多人把八股文背得滚瓜烂熟但让他手写一个注意力机制就卡壳。面试官一旦让你写代码背的东西全露馅。所以每个核心模块都要亲手实现一遍哪怕只是简化版。第二个坑是忽略工程细节。比如问“怎么部署模型”只回答“用vLLM”是不够的面试官会追问显存怎么估算、并发怎么处理、故障怎么恢复。这些细节才是区分候选人的关键。第三个坑是不关注最新进展。LLM领域变化快RoPE、GQA、MoE、FlashAttention这些技术如果完全没听过会显得你跟不上节奏。不需要每个都精通但至少知道它解决什么问题。最后分享一个我自己的习惯每次面试后把被问倒的问题记下来回去查清楚下次就不会再栽同一个坑。面试本身就是最好的学习机会哪怕这次没过把暴露的短板补上下一次就是你的主场。
阅读完成 · 觉得有帮助?