ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

金山办公NLP笔试真题解析:从中文分词到文本摘要的考点全拆解

2026/8/31 5:20:47 拓冰建站 浏览量
金山办公NLP笔试真题解析:从中文分词到文本摘要的考点全拆解 1. 试卷整体观察金山办公NLP岗位到底在考什么拿到这份2020年金山办公校招NLP工程师笔试题的时候我第一反应是这公司招NLP的人是真拿来干活的。金山办公的核心产品是WPS和金山文档日常要处理的文本场景极其具体——用户写文档时的拼写纠错、OCR识别后的文本校正、语音输入的文字后处理、文档自动分类归档。所以笔试题没有太多花架子全程围绕中文文本处理这条主线展开统计学习方法和深度学习方法都有涉及比例大概五五开。整套题下来我能明显感受到出题人的几个意图。第一考察基础是否扎实N-gram语言模型、HMM、CRF、TF-IDF这类经典概念绝对不能含糊。第二考察工程落地能力好几道题都要求你手推公式或者写伪代码而不是简单背概念。第三考察对中文文本特殊性的理解比如分词歧义、未登录词、繁体简体转换这些都是办公软件里天天要面对的真实问题。第四考察对深度学习常用组件的掌握程度Word2Vec、LSTM、Attention都有涉及但难度控制在知道原理、能写出来的程度不要求手推Transformer完整反向传播。从岗位匹配度来说这份题其实相当克制。没有出现那种特别偏门的研究型题目比如最新的预训练模型对比、小样本学习的前沿方法等基本都在经典NLP知识体系框架内。这意味着只要系统学过自然语言处理课程、认真做过几个项目、把常用模型的原理都弄明白的候选人是完全可以拿下的。但反过来靠刷几道LeetCode就来投NLP岗的同学大概率会在语言模型和序列标注这两块栽跟头。整体题量不大我记得是四道大题加若干小题考试时间给了一个半小时。题型分布大概是第一部分是基础概念题快速判断和简答第二部分是算法实现题手写核心逻辑第三部分是模型原理题推导和计算第四部分是业务场景设计题给一个具体需求让你方案设计。下面我按题型逐个拆。2. 基础概念题拆解这些送分题拿不到就是亏2.1 语言模型与平滑策略这份试卷里关于语言模型的那道题很有代表性问的是给定一个语料库用N-gram模型计算一个句子的概率遇到未登录词怎么处理。这题在NLP笔试里属于经典中的经典金山办公出这题的原因其实很朴素——WPS的智能拼写检查、自动补全功能底层就依赖语言模型来做候选排序。要答好这道题必须先理清N-gram模型的基本逻辑。一个句子的概率被拆解成一系列条件概率的乘积比如二元模型Bigram下P(今天天气真好) P(今天) × P(天气|今天) × P(真好|天气)。计算方式是从语料中统计词频和共现频次然后算最大似然估计P(w_i | w_{i-1}) Count(w_{i-1}, w_i) / Count(w_{i-1})。但问题在于训练语料永远不可能覆盖所有词序列组合一旦遇到今天天气超级无敌好这种表达如果超级无敌这个组合没在语料中出现过概率直接变成0这显然不合理。这时候就需要平滑策略。经典的平滑方法有几种加1平滑Laplace Smoothing把每个计数都加1简单粗暴但会让概率分布偏离实际Good-Turing估计用出现r次的类别数量来估计出现0次的概率相对精准Kneser-Ney平滑是目前效果比较好的方法它不仅考虑词频还考虑词在上下文中的多样性比如Fresno这个词虽然频次高但它只出现在in Fresno这个搭配中所以它作为续接词的概率应该调低。我当时的答题思路是先写出Bigram概率公式然后依次说明加1平滑的计算方式再用实际数字举例。比如语料中天气出现10次天气真好出现3次那么P(真好|天气) (31)/(10V)V是词表大小假设V10000结果就是4/10010约等于0.0004。同时也要指出加1平滑的局限——它给所有未出现搭配一个相同的概率这不符合语言实际如果时间允许可以补充说明Kneser-Ney为什么更优。这道题还有一个容易漏掉的细节评估语言模型用困惑度Perplexity它是句子概率的几何平均的倒数值越小说明模型对语料的拟合越好。笔试中不一定会直接问但如果你在解答里主动提到困惑度概念会显得理解更完整。2.2 中文分词的关键难点金山办公的笔试对中文分词特别执着这完全可以理解。WPS的文档校对、关键词提取、语音识别后处理都绕不开分词这个前置步骤。试卷里那几道分词相关的题核心考点集中在两个地方歧义消解和未登录词识别。先说歧义。中文分词里有个经典例子南京市长江大桥可以切分成南京市/长江大桥也可以切分成南京/市长/江大桥这就是交集型歧义。处理方式通常有两种思路一种是基于规则的维护一个词典同时定义一些切分规则比如正向最大匹配和反向最大匹配两者结果不一致时用启发式规则选一个另一种是基于统计的用HMM或CRF等序列标注模型把分词问题转化为给每个字打标签的问题——B词首、M词中、E词尾、S单字成词。我当时在答题时把两者都写了出来并重点解释了为什么统计方法逐渐成为主流基于规则的方法对词典的依赖太大词典里没有的词或者没覆盖的歧义模式都没办法而且开发新领域的分词器时要不断堆规则维护成本极高。基于统计的方法则不需要手工维护词典只要标注好训练语料模型能自动学到上下文特征。再说未登录词。比如人名、地名、机构名、网络新词这些词不在词典里也不容易通过规则覆盖。经典的解决方案是HMM模型配合Viterbi算法把人名、地名等作为特定的标注类型。在中文里还有一个比较实用的技巧——利用单字成词概率和词内字的转移概率来识别新词。比如江大桥这几个字在语料里频繁相邻出现而且内部字的互信息值很高就可以考虑它是潜在的新词。现在工业界还会用统计规则结合的方式先跑一遍统计模型再用词表、停用词表等低成本手段做修正。2.3 TF-IDF与文本表示还有一道看起来简单但容易答不透彻的题是让解释TF-IDF的原理并说明它的局限性。很多同学的答案只写了公式TF-IDF TF × IDFTF是词频IDF log(N/df)N是文档总数df是包含该词的文档数。然后结束。这样答只能拿一半分。要想答全得说出它背后的直觉一个词在一篇文档里出现次数多说明它可能重要但如果它在所有文档里都频繁出现那它就没有区分度比如我们、的这类停用词。所以TF衡量的是局部重要性IDF衡量的是全局区分度。公式里取对数是为了缓解文档频率差异过大带来的影响加1有些版本还会做平滑处理是为了避免除零。局限性的回答要注意几个层次。一是对于短文本TF可能失真因为词频统计不充分二是IDF只考虑了词是否出现没考虑词的位置和词性比如标题中的词重要性和正文中的词显然不同三是它无法处理一词多义和同义词问题苹果指的是水果还是公司从TF-IDF向量本身看不出来。在办公文档场景里TF-IDF可以用来做关键词提取和文本相似度计算但如果要更精确地做语义理解通常得换用词向量或预训练模型。我在这道题后面补了一句实际项目中我一般会结合词性过滤先做分词和词性标注只保留名词、动词等实词再做TF-IDF加权效果比直接用全词要好不少。3. 算法实现题手写代码到底在考什么这套题里有一道手写实现题要求写出给定文本集下计算某个词TF-IDF值的代码。题目本身不复杂但它考察了好几个工程细节数据结构设计、字符串处理、时间复杂度优化。我给出的参考实现是这样的。import math from collections import Counter class TfidfCalculator: def __init__(self, corpus): # corpus 是文档列表每个文档是分词后的词列表 self.corpus corpus self.doc_count len(corpus) # 统计每个词的文档频率 df self.df Counter() for doc in corpus: # 每个文档内先去重再统计 df unique_words set(doc) for word in unique_words: self.df[word] 1 def tf(self, word, doc): # 词频可以直接用计数除以总词数 total len(doc) if total 0: return 0.0 return doc.count(word) / total def idf(self, word): # 加1平滑防止除零 return math.log((self.doc_count 1) / (self.df.get(word, 0) 1)) 1 def tfidf(self, word, doc): return self.tf(word, doc) * self.idf(word)写这段代码时有两个点值得注意。第一代码里我用set(doc)去重后再统计文档频率这符合IDF的定义——只关心这个词在多少篇文档中出现过不关心具体出现几次否则一篇文档里出现10次就会被计10次df完全错误。这个细节我在面试中问过不少候选人能主动意识到的不足三成。第二IDF做了加1平滑避免词完全不在语料中出现时出现负值或除零错误实际项目中还会对分母做进一步的拉普拉斯平滑。如果笔试时间富裕扩展一个小功能能加分不少。比如输出某个文档中TF-IDF值排名前K的关键词这样更贴近实际应用场景。可以加一行代码def extract_keywords(self, doc, k10): scores {word: self.tfidf(word, doc) for word in set(doc)} return sorted(scores.items(), keylambda x: x[1], reverseTrue)[:k]这道题在WPS场景里对应什么功能文档关键词提取。用户导入一篇长文系统自动生成关键词标签方便归档和检索。底层逻辑就是先分词去停用词算TF-IDF取Top K。如果进一步扩展还可以用TextRank算法做无监督关键词抽取它考虑词与词之间的共现关系效果通常更好但算法复杂度也更高笔试一般不会要求现场写。除了TF-IDF这套题还出现了一道编辑距离Levenshtein Distance的题目。编辑距离是拼写纠错的核心算法之一在WPS里输错一个单词系统给建议时就要计算候选词和错误词之间的编辑距离。题目要求用动态规划实现这也是NLP工程师的基本功。def edit_distance(s1, s2): m, n len(s1), len(s2) dp [[0] * (n 1) for _ in range(m 1)] for i in range(m 1): dp[i][0] i for j in range(n 1): dp[0][j] j for i in range(1, m 1): for j in range(1, n 1): if s1[i - 1] s2[j - 1]: dp[i][j] dp[i - 1][j - 1] else: dp[i][j] min( dp[i - 1][j] 1, # 删除 dp[i][j - 1] 1, # 插入 dp[i - 1][j - 1] 1 # 替换 ) return dp[m][n]动规的递推逻辑不复杂但要写对边界条件。第0行和第0列要初始化为对应的下标表示从空串变成另一个串需要操作的次数。如果只要求算距离空间复杂度还可以优化成一维数组但不建议在笔试里冒险稳妥写出二维版本就够了。换一个角度如果这道题变成给定一个错误词和候选词列表找出最可能的正确词答案的思路就变成了先计算错误词和所有候选词的编辑距离然后按距离排序距离相等的情况下再用语言模型计算候选词在上下文中的概率来排序。比如用户输入今天我去了BeijingBeijing拼写没问题但如果系统判断它和上下文搭配不自然有可能会推荐北京。这种多层排序在真实的输入法、编辑器纠错里是标配做法。4. 模型原理题从HMM到Attention的层层深入4.1 序列标注模型HMM还是CRF试卷中有一道大题围绕中文命名实体识别展开要求对比HMM和CRF在处理序列标注问题时的差异。这个问题在办公场景里非常实际——比如在WPS中自动识别文档里的日期、人名、公司名称然后提供格式化或快捷操作功能。HMM是一个生成式模型它假设观察序列由隐状态序列生成。具体到命名实体识别就是每个字对应一个隐状态比如B-PER表示人名开头隐状态之间满足一阶马尔可夫假设即当前状态只依赖于上一个状态每个隐状态生成一个观察值即当前字且观察值只依赖于当前状态。因此HMM要建模三类概率初始状态概率、状态转移概率、发射概率。求解最可能的隐状态序列时用Viterbi算法做动态规划。HMM的缺陷在于两个强假设。一阶马尔可夫假设认为当前状态只和上一个状态有关但真实语言中一个字是不是人名的一部分可能要看前面好几个字。观察独立假设认为当前字只由当前状态决定也不符合实际比如小明去了北京中明与小之间存在强烈的关联HMM这种单字独立的建模方式会丢失这些信息。CRF是一个判别式模型它不建模联合概率P(X, Y)直接建模条件概率P(Y|X)。它最大的优势是可以定义任意的特征函数可以把当前位置的字、前一个字、后一个字、词性、词典命中等各种信息都作为特征塞进去模型自动学习权重。从解模型的角度看CRF求解的是给定观察序列下最大条件概率的标注序列训练过程需要用到极大似然估计和迭代优化算法比如L-BFGS。笔试题如果要求谈实际选择我的观点是数据量小、特征工程做得深的情况下CRF效果更稳可控性强特征可以人工设计来解释结果数据量大、希望省去特征工程的情况下用BiLSTM-CRF或Bert加CRF效果更好。金山办公这种场景如果做专业领域文档合同、法律文书的实体识别标注数据有限人工特征很重要CRF的性价比其实很高。4.2 Word2Vec与词向量表示还有一种常考的题是Word2Vec。会问Skip-gram和CBOW的区别以及为什么Word2Vec得到的词向量有语义性质。如果只答Skip-gram用中心词预测上下文CBOW用上下文预测中心词只能算答对了一半。更深一层的考察在于Word2Vec本质上是把词共现信息压缩到低维向量它之所以能学到语义相似性是因为分布假说——出现在相似语境中的词具有相似的含义。这个思想是NLP词表示方法的基石后来的Glove、ELMo、Bert本质上都是这个思想的不同实现方式。我建议在笔试回答里补充一个细节Word2Vec训练时用了负采样Negative Sampling它把多分类问题转化为二分类问题让模型判断一个词对是否来自真实上下文这样能大幅降低计算复杂度。还要提到词向量的局限性——静态词向量无法解决一词多义问题。例如苹果在水果和公司两种上下文中Word2Vec只能给出一个固定的向量而Bert这类基于上下文的预训练模型在输入苹果很好吃和苹果发布了新手机时编码器会为同一个词生成不同的表示。如果将来要进工业界做文本匹配、情感分析这个问题尤其关键。4.3 Attention机制的原理Attention几乎是NLP面试必考题这份卷子自然也没放过。问法通常是简述Attention机制的计算过程为什么它在Seq2Seq模型中比固定长度向量更有效。答题框架可以这么组织。首先给出动机传统的Seq2Seq模型把源端所有信息编码成一个固定长度的向量句子一长信息就会丢失解码质量明显下降。Attention的思路是解码每个词时不再只看这一个固定向量而是动态地从源端所有隐状态中挑选相关信息把注意力集中在对当前解码最有用的部分。计算过程分三步第一打分用某种函数计算当前解码器隐状态与源端每个位置编码器隐状态的匹配程度常见的打分函数有加性Attention、点积Attention、缩放点积Attention第二归一化把打分结果过Softmax转为概率分布表示每个源端位置的重要程度第三加权求和用这个分布对源端所有隐状态做加权平均得到上下文向量作为当前解码步的输入。有一个容易被追问的点为什么Transformer中要用缩放点积Attention这是因为当向量维度变大后点积数值的方差也会变大导致Softmax梯度极小除以根号下d_k可以稳定训练。此外Self-Attention中的Query、Key、Value分别是从输入向量线性变换得到的通过这种变换模型可以学习到哪些位置之间存在关联比如翻译他喜欢猫时Self-Attention可以让他和喜欢、猫之间建立连接。在WPS的文档摘要生成任务里Bert这类模型能够捕捉长距离依赖根本上靠的就是多层Self-Attention堆叠。5. 业务场景题办公软件中NLP的真实战场5.1 拼写检查与纠错方案设计金山办公笔试最后一道大题基本是方案设计题。我记得是要围绕用户在WPS中输入了一段中文文本请设计一个自动拼写纠错系统来展开。这题没有标准答案考查的核心是系统设计能力和对NLP技术栈的综合运用能力。我在回答时把方案拆成了5个模块。第一分词和词性标注作为前置处理第二错误检测用语言模型计算每个位置的词在当前上下文中的概率概率低于某个阈值的词标记为可疑错误同时结合词典规则比如不在词典中且无法归类的词直接标记第三候选召回对可疑位置的词做编辑距离计算从词典中找出距离较近的词作为候选如果是拼音输入导致的错误还可以做拼音匹配第四候选排序用三元语言模型计算每个候选词放入上下文后的整体概率概率最高的作为最优结果还可以加入一个基于用户历史的个性化加分项比如用户经常输入某些专业术语就提高这些词的权重第五交互策略不是所有错误都要自动修改对于高置信度的错误可以直接改低置信度的给出提示让用户选择否则容易在用户看都没看的情况下改错意思。这种设计思路在工业界确实可行因为办公文档的文本规范程度比较高不需要像社交网络文本那样处理大量无规律表达。但如果要深入一点还可以考虑引入深度学习模型做错别字检测比如用Bert的掩码语言模型能力——把可疑位置的词Mask掉让模型预测该位置的词如果预测结果与原文差异较大则有较大概率是错别字。这种方法的优点是语义理解能力强能抓住一些编辑距离无法发现的错误比如同音字、形近字。缺点是计算量大在大型文档上逐词Mask耗时很长通常只作为二级精排使用。5.2 文本摘要与关键词提取还有一道题跟文档摘要相关问的是给一篇长文档生成自动摘要的方法。这题在WPS场景中对应文档速读功能用户没时间看完一篇长报告系统自动生成摘要帮助快速了解内容。经典的方案有抽取式和生成式两种路线。抽取式摘要本质上是个排序问题先把文档按句子切分每句话表示成TF-IDF向量或句向量然后计算每句话与整篇文档的相似度相似度高的句子作为摘要句或者用TextRank算法把句子当作节点、句子之间的相似度作为边的权重迭代计算每个句子的得分选出Top K个句子组成摘要。TextRank的核心公式是类似PageRank的迭代传播一个句子的得分等于所有指向它的句子的得分除以各自出度的加权和。句子之间的相似度可以用词向量的平均值来计算也可以用BM25这样的稀疏表示。优点是无需训练数据快速可上线缺点是句子选择可能缺乏连贯性有时候摘出来的句子拼在一起逻辑不通。生成式摘要则用Seq2Seq模型或Bert系列模型直接生成新句子质量更高、可读性更好但需要大量训练数据推理耗时更长。笔试里说清楚两种方案的优缺点和适用场景就够了但如果你能补充一个实用经验——实际开发中可以先抽取后压缩先用抽取式定位关键句再用生成式模型对关键句做压缩和改写效果和效率都很好——这一段回答会明显有区分度。接着说一下句子相似度计算这是所有抽取式摘要的基础。最简单的方法是用词向量的TF-IDF加权平均得到句向量然后算余弦相似度。但词向量平均容易受高频无意义词的干扰实际工程中我通常会做两步处理第一过滤停用词和标点第二使用SIFSmooth Inverse Frequency加权法给高频词更低的权重效果会提升不少。如果项目中已经引入了Bert模型也可以直接用Bert的CLS向量作为句向量但注意长文本需要截断一般取前512个token就够。5.3 OCR后处理与语音文本修正金山办公的笔试题还有一个隐藏的方向藏在场景应用题里OCR识别之后的中文文本校正。因为WPS自带图片转文字功能但OCR引擎输出的文本经常会有错别字比如弯识别成变、日识别成曰这时候就需要NLP后处理来修正。这个场景的挑战在于OCR错误和输入法错误模式不同前者更多是视觉相似导致的字形混淆后者更多是拼音相似导致的同音错误。所以纠错方案要针对性地利用字形信息。一个思路是把候选词的编码距离换成字形距离——用笔画序列或字形结构特征做相似度计算另一个思路是用混淆矩阵来引导候选召回比如提前整理好常见的形近字混淆表OCR识别到某个词时优先从混淆表里找候选。同时语言模型仍然要做最终排序确保修正后的整句语义流畅。我当时在笔试里没有展开太多OCR的细节因为这个方向属于专门领域但在面试环节被追问到了如果OCR结果里出现了大量标点符号错乱怎么处理这个问题我当时的思路是先基于规则复原标点比如句号、逗号在中文中不能连续出现引号必须成对再对分句位置进行合法性检查如果发现一个句子超过一定长度都没有标点就需要用语言模型判断在何处插入标点最合理。这部分在实际项目中占了很大工作量因为OCR的标点错误会影响后续分句、摘要和关键词提取的效果。6. 笔试之外的现实思考6.1 这套题对求职者的方向指引做完这套题后我当时最大的感受是金山办公的NLP岗位更看重扎实的基础和解决实际问题的能力而不是追逐热点。整张卷子没有出现太多2019、2020年那段时间特别火的预训练模型内容比如Bert的细粒度微调、文本对抗训练等更多是把经典模型考察透彻。这其实是一个信号办公软件领域的NLP落地核心能力是把已有的、稳定的算法模型组合起来解决具体问题而不是拿着新模型到处试验。如果你正在准备类似的NLP岗位笔试我建议重点复习的方向是中文分词、语言模型、序列标注HMM/CRF/BiLSTM-CRF、文本表示TF-IDF/Word2Vec/Bert、文本分类、信息抽取、文本摘要。每一个方向都要做到知道原理、能写公式、能手推关键步骤、能说出实际应用场景这四层。特别是手推公式这一步很多同学以为笔试只要看懂公式就行结果考场上让写出Softmax的梯度推导就会卡壳。我自己的经验是每个模型都试着从损失函数出发自己推导一遍反向传播哪怕只是草稿级别也比死记硬背扎实得多。另外还要提醒一点尽量熟悉Python和常用的NLP库比如jieba、HanLP、gensim、transformers。笔试中如果涉及代码填空题这些库的API设计思路能帮你快速理解题目的意图。比如题目让你实现一个文本分类接口你如果知道transformers里AutoModel的用法写出来的代码结构就会接近面试官期望的工程风格。6.2 实际工作与笔试之间的落差笔试题和真实工作之间永远存在差距。在笔试里输入的数据都是干净整洁的示例文本输出也不是很复杂。但到了实际工作中处理的文档五花八门有的客户上传的PDF排版混乱有的表格扫描件歪歪扭扭有的文档同时混着中英日三种语言。笔试里你只需要写一个算法函数实际工作中你需要先写20行代码做数据清洗再用算法最后还要设计兜底逻辑。我自己在接业务需求时总结出一个方法论先明确最差可接受的结果是什么再设计算法路径。比如做文档摘要如果模型效果不好最低限度也要保证摘要中的每一句话都出现在原文中不能胡编乱造这是抽取式摘要的一大优点。如果做智能纠错宁可少改也不要乱改用户发现自己写对的内容被改成错的比不改更让人崩溃。这类产品经验和取舍思维笔试里不会直接考但往往才是决定你能不能留在这家公司的关键。笔试能反映一个候选人的基本功扎实程度但真正影响Offer决策的还是看你对业务场景的理解和解决问题的思维方式。金山办公的这份试卷出得中规中矩却清晰地划出了一个好用的NLP工程师需要具备什么能力的边界。6.3 从笔试到Offer的最后一公里笔试过了之后还有一轮技术面试在等着你。面试官大概率会拿着你笔试答案里的某个点展开询问所以交卷之前一定要把每个公式、每段代码的逻辑都弄明白。比如你在试卷里写了用Viterbi算法解HMM的代码面试官会追问Viterbi的时间复杂度是多少如果状态空间特别大有没有优化空间你写的DP代码里保存路径的方式是什么这些问题都是考察你有没有真正吃透模型而不只是背了模板。我个人的建议是笔试之后花15分钟时间把每道题的核心知识点在脑子里过一遍列出如果被追问应该从哪几个角度回答。比如TF-IDF那道题你要准备好被追问TF-IDF有哪些变体BM25和TF-IDF的关系是什么实际项目中你是怎么做停用词过滤的这样的连环问题。这些东西不需要写得很多但每个点都要能展开说30秒以上。笔试中还有一个小技巧如果一道题有好几种解法把你认为最优的解法写在前面同时在旁边用一句话说明为什么不选其他方案。比如语言模型平滑那题你可以写道这里我用加1平滑是因为实现简单在数据量适中时稳定可靠如果数据量稀疏可以考虑改用Kneser-Ney但实现复杂度会高一些。这样既展示了知识广度又体现了工程判断力。最后再补一个实用心得关于时间分配。一个半小时做四道大题时间相当紧张。我的策略是先花5分钟浏览全部题目挑自己最有把握的题先做保证基础分全部拿到再做第二有把握的最后留时间给方案设计题。方案设计题没有标准答案只要逻辑清晰、结构完整、有实际可行性一般都能拿到不错的分数。如果你一开始就死磕某一道硬核推导题最后可能导致简单题没时间写得不偿失。这道策略在我后来指导学弟学妹的过程中反复被验证真的很管用。