十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

搜狗校招研究岗笔试复盘:算法、NLP与备考策略全解析

搜狗校招研究岗笔试复盘:算法、NLP与备考策略全解析 搜狗2020校招研究岗的第一场笔试说实话是我秋招季里做得最纠结的一场。纠结不是因为题太难而是它把“算法工程师”和“研究员”这两个方向的考察点揉在了一起你既要刷得动LeetCode又得答得出Transformer的细节还得在有限时间里做对概率题。考完出来我最大的感受是搜狗这场笔试出题人真的很懂他们想要什么样的人。这篇文章我拖了很久才写因为确实值得认真复盘。如果你准备投搜狗乃至其他互联网公司的NLP、搜索、推荐方向研究岗这篇内容可以作为你的备考参照。我会把整场笔试的题型分布、每一类题目背后的考察逻辑、编程题的完整思路推演、以及我踩过的坑都拆开讲一遍。哪怕你还没到校招季提前看看这类“研究岗”笔试的出题套路也能帮你少走很多弯路。1. 从这场笔试看搜狗研究岗的选拔逻辑1.1 搜狗的业务盘子决定了考察方向搜狗的核心业务是搜索、输入法、语音和AI硬件研究岗的招聘方向基本聚集在自然语言处理、query理解、排序推荐、语音技术、OCR这些领域。这就决定了笔试题目不会像纯互联网大厂那样只考通用算法而是会把计算机基础、机器学习和NLP的比重拉得很高。我当时投递的是NLP方向的研究岗笔试通知里没有明确说考什么只说“综合能力测试”。但根据搜狗的往年经验和岗位JD基本可以判断出三个重点机器学习基础、深度学习与NLP、数据结构和算法。这三块的比重几乎是三分天下外加少量数学题和逻辑题。这个结构跟很多做搜索和推荐场景的公司类似但搜狗在NLP上的权重会更高一些毕竟那是他们的命根子。如果你是冲着“研究岗”去的一定要提前意识到这个岗位的笔试比开发岗更看重理论深度而不是单纯的刷题量。你不仅要会写代码还得能说清楚“为什么这么做有效”。比如一道题问你“为什么LSTM能缓解梯度消失”这要求你从反向传播的链式法则角度去解释而不是背一句“因为引入了门控机制”就完事。1.2 笔试整体结构、时长与策略准备搜狗这场笔试是在牛客网线上进行的三个小时题量不算小。我印象中大概是这样的结构题型题量分值占比建议时间单选/多选约20道40%60分钟编程题3道60%120分钟这个时间分配是我后来复盘时的建议值实际考场上因为紧张我选择题做得有点快后面编程题反而被一道题卡了太久。线上笔试不像现场笔试你面对的是屏幕和编译器不能像纸笔那样随意标注所以提前熟悉牛客网的代码编辑器、测试用例提交逻辑非常重要。从策略上讲选择题部分要果断不会的题先标记、随后跳过不要在一道题上死磕。编程题部分则要按“易、中、难”的顺序来做先把能拿的分拿到。搜狗的笔试系统支持本地IDE和在线编辑器代码提交后有实时判题反馈这个机制比较友好但也意味着你提交一次就会消耗一次“错误记录”所以提交前务必自己多跑几个边界用例。2. 选择题部分不是在考记忆而是在考判断力2.1 机器学习与深度学习的高频考点选择题的覆盖面非常广但有一个很明显的规律考察你对模型本质的理解而不是公式的死记硬背。这类题目占比最高做起来也最考验平时的积累。比如有一道题给了一个训练过程中loss曲线先快速下降然后趋于平稳但验证集loss在某个epoch后开始上升问最可能的原因和应对措施。这种题看似简单其实在考察过拟合的识别和处理。选项里会有“降低学习率”“增加正则化”“使用dropout”“扩大训练集”等如果你只是刷过概念而没有亲手调过模型很容易在这类题上犹豫。还有一道我印象深的是关于梯度消失的。题目问的是“在深层网络中sigmoid激活函数相比ReLU更容易导致梯度消失的原因是什么”。这题的关键在于你知不知道sigmoid的导数最大值是0.25在反向传播时每过一层梯度至少要乘以0.25层数一多梯度就指数衰减。而ReLU在正区间的导数是1梯度能更顺畅地回传。这种题光靠背“sigmoid容易梯度消失”这个结论是不够的你得能从数学上解释清楚。另一个高频出题点是集成学习。Boosting和Bagging的区别、随机森林的特征采样、XGBoost和GBDT的差别这类题几乎每次笔试都会出现。特别是“随机森林的随机性体现在哪里”这种题它其实是在考察你对样本采样和特征采样的理解而不是简单记住“随机森林多棵决策树”。2.2 NLP专项从词向量到Attention的常规考法搜狗对NLP的考察是重头戏选择题里至少有五六道跟NLP直接相关。word2vec的CBOW和Skip-gram的区别、负采样的作用、Glove和word2vec的对比这些是基础中的基础基本属于必考范围。有一道题让我想了很久问的是“在Transformer中self-attention的计算公式中为什么要除以\sqrt{d_k}”。这个问题的标准解释是当维度d_k较大时点积的结果会变得很大导致softmax的输出落入梯度极小的区域除以\sqrt{d_k}可以缩放点积的数值范围保持梯度的稳定。背后的数学直觉是如果query和key是均值为0方差为1的独立随机变量它们的点积的方差是d_k所以需要除以\sqrt{d_k}来归一化方差。这道题考察的是你对attention机制细节的理解而不仅仅是会调包。还有一道关于BERT的预训练任务问的是“MLM和NSP分别解决什么问题”。选项里有“MLM用于学习词级别的上下文表示NSP用于学习句子级别的关系”。这道题在当年可能还算前沿放在现在已经是常规考点了但当年还是有不少人看到BERT就发憷直接跳过去。如果你准备校招Transformer和BERT相关的细节是绝对绕不开的。2.3 数学基础题概率统计和线代的实际应用研究岗的笔试里数学题不会像考研那样出“求行列式”这种纯计算而是会结合算法的实际场景。比如有一道概率题说的是“一个语言模型在测试集上的困惑度是100另一个是50问哪个模型更好、困惑度越低说明什么”。这题如果你不知道困惑度是交叉熵的指数形式、越低代表模型对真实分布的预测越准确就会选反。线代方面的考察也很务实有一道题涉及矩阵的特征值分解和PCA的关系问的是“PCA降维时为什么要选特征值最大的几个方向”。这其实是考察你对方差最大化这个目标的理解特征值越大代表该方向上的数据方差越大保留它能最大程度保留原始信息。这类题本质上是在考“你有没有真正用过这些数学工具”而不是停留在会算题。这个时候我强烈建议复习时把数学基础跟算法模型关联起来看。不要单独刷“概率论习题”而是去看“这个概率知识点在机器学习中出现在哪里”。比如贝叶斯公式对应朴素贝叶斯分类器最大似然估计对应逻辑回归的损失函数来源分布采样对应强化学习中的策略梯度。这样复习效率高得多也不是死记硬背。3. 编程题部分从读题到AC的完整思路推演3.1 第一题字符串处理类的“送分题”编程题的第一题通常是用来稳住心态的考察的是最基本的编码能力。搜狗这道题跟他们的业务结合得很巧妙给定一串文本统计其中出现频率最高的单词输出单词和次数。听起来很简单但如果只是用Python的split然后数一下你就踩坑了——题面里规定了要考虑标点符号的切分、大小写不敏感、以及可能出现连续的多个空格。这道题的正确解法是先做清洗把非字母字符统一替换为空格再全部转成小写最后用split切分。统计部分可以用defaultdict或者Counter但注意输出顺序要求——如果两个单词频率相同需要按字典序输出。这个“字典序”就是典型的边界条件很多人在这个细节上翻车。import re from collections import Counter def most_frequent_word(text): # 替换非字母字符为空格统一小写 cleaned re.sub(r[^a-zA-Z], , text).lower() words cleaned.split() counter Counter(words) # 按频率降序字典序升序排序 max_freq max(counter.values()) candidates [w for w, c in counter.items() if c max_freq] return sorted(candidates)[0], max_freq这道题说白了就是给你热身的但它的意义在于考察你的工程素养测试用例里会包含空字符串、只有标点、大写混排等极端情况。如果你只写了核心逻辑而没考虑这些边界很可能只过一部分测试用例。我在写的时候特意多检查了一条如果所有单词都被清洗掉了应该返回什么。题面没明说但返回空字符串通常能兼容更多场景。3.2 第二题动态规划类的“拉分题”第二题开始上强度了是一道典型的动态规划题。题目大意是给定一个数组每个位置的数字代表你最多可以向前跳几步问从第一个位置跳到最后一个位置最少需要跳几次。这就是经典的“跳跃游戏II”在LeetCode上是中等难度但在笔试环境下做出来的人数会明显减少。我当时的思路是贪心加BFS而不是纯DP。用dp数组记录到达每个位置的最少步数需要O(n^2)的时间而贪心维护“当前步数能覆盖的最远距离”和“下一步能覆盖的最远距离”只需要一次遍历O(n)搞定。笔试时间有限能用更优解法就不要写O(n^2)的版本因为测试数据一大就可能超时。def min_jumps(nums): n len(nums) if n 1: return 0 jumps 0 cur_end 0 farthest 0 for i in range(n - 1): farthest max(farthest, i nums[i]) if i cur_end: jumps 1 cur_end farthest if cur_end n - 1: break return jumps这道题的陷阱在于很容易想到DP然后花大量时间在“dp[i] min(dp[j] 1)”的状态转移上。但如果没注意到“每个位置都能到达”这个隐含条件写出来的DP在边界上会出错。我记得考场上我卡了大概二十分钟最后想明白用贪心才跑通。这个教训告诉我笔试前一定要把LeetCode上的贪心、DP、双指针这三种高频思路练到肌肉记忆不然考场上根本没有时间慢慢推导。3.3 第三题综合类的“选做题”第三题其实是一道“看起来像图论、实际上考并查集”的题目。题面大致是给定一组点和一组边关系问这些点和边能构成几个连通分量。这个在业务场景里对应的可能是“社交网络的好友圈数量”或者“文本聚类中的簇数量”。并查集的模板并不复杂核心是find函数里的路径压缩和union时的按秩合并。这道题真正的考点是空间复杂度的优化题目给的点编号可能很大且不连续你不能直接开一个上百万的数组来存父节点而要用哈希表做离散化。def count_components(n, edges): if n 0: return 0 parent list(range(n)) rank [0] * n def find(x): if parent[x] ! x: parent[x] find(parent[x]) return parent[x] def union(x, y): rx, ry find(x), find(y) if rx ! ry: if rank[rx] rank[ry]: parent[rx] ry elif rank[rx] rank[ry]: parent[ry] rx else: parent[ry] rx rank[rx] 1 return True return False comps n for u, v in edges: if union(u, v): comps - 1 return comps这道题能算是整套笔试题里最考察综合能力的一道你得识别出这是并查集、会写模板、能处理数据范围的坑还要理解连通分量的含义跟实际业务场景的关系。我后来复盘时想到如果是我自己去设计题目大概率也会出这种题因为它能同时考察算法基础和业务抽象能力性价比非常高。4. 出题人视角一场笔试看穿你的真实水平4.1 基础扎实度决定了你的下限考试的时候觉得题多考完再看会发现每道题其实都在做一件事验证你有没有真正理解那些最朴素的概念。比如选择题里反复出现的softmax、交叉熵、过拟合、梯度消失这些谁都说自己会但被换个包装出成题就能筛掉一大批人。从出题人的角度讲研究岗的笔试不需要你做出多难的题更关键的是看你基础扎不扎实。一个连“为什么softmax里要减去最大值”这种数值稳定性问题都答不上来的人很难让人相信你能在训练模型时处理好NaN的问题。搜狗这场笔试给我的感觉就是每一道题都在问你“你平时是真的在写模型还是在调包”。所以如果你还在准备阶段我建议你花时间把深度学习里的基础概念一个个过一遍做到能用三句话向别人讲清楚原理。这个过程很笨但效果极好。我当时就是把SVM、决策树、逻辑回归、LSTM、Attention这些模型全部写了一遍笔记把推导过程和直觉理解都写下来应对选择题基本就够用了。4.2 编程题的隐藏考察点代码风格和边界意识编程题除了考察算法另一个隐形评分点在代码的规范程度。虽然大部分在线判题系统只关心你AC没AC但如果后续有面试官人工查看试卷你的变量命名、函数划分、注释习惯都会成为参考。这个“人工查看”环节并不是所有公司都有但搜狗这类注重算法和数据结构的公司是有一定概率看代码的。我当时在写第一题的时候把整个流程拆成了清洗、分词、统计三个步骤每个步骤单独一个功能函数。这样做的目的不是说多高大上而是如果判题出了问题我能快速定位是哪个模块没写对。实战中这是一个很有用的习惯尤其在线编辑器没有断点调试功能你只能靠print输出日志来排查问题。如果代码全堆在一起排查起来会非常痛苦。还有一个细节是输入输出的处理。在线笔试通常用标准输入有时候题目会故意让你处理一行或多个case如果你用了input()但没考虑末尾换行符就很容易出现问题。我建议平时练习时就统一用sys.stdin.read()来读数据然后自己split这样能兼容几乎所有输入格式。5. 从这场笔试回看整条校招备战路线5.1 三轮复习法基础、专题、模考考完之后我复盘了自己的准备过程基本是按照三轮来安排的。第一轮是基础扫盲把所有可能考的知识点列成清单逐个攻克第二轮是专题强化重点刷DP、贪心、并查集、图论这几类高频算法第三轮是整套模考严格按照3小时、在线平台的节奏来练。三轮复习的时间分配大概是20%基础、40%专题、40%模考。模考特别重要因为很多人在平时刷题时是“看着答案做”的一到考场上就现出原形。我备战的时候用了牛客网上历年的各家真题虽然题目时效性有限但模拟考场节奏、练习时间分配的价值很高。一个有用的技巧是每次模考后不管成绩如何都花至少一小时复盘把错题分类成“概念不懂”“思路想不到”“代码写错”三种。这样你能明确知道自己的短板在哪里而不是笼统地说“我算法不行”。我当时统计发现“思路想不到”占比最高于是集中补了一段时间的题解思路后来编程题的正确率提升明显。5.2 时间分配和做题顺序的实战经验我考场上体会到最重要的一件事是不要按题目顺序做。拿到试卷后先花两三分钟整体扫一遍判断哪些题是你有把握的、哪些是模棱两可的、哪些是完全不会的。我当时的策略是先把选择题里非NLP的数学题做完因为这些题的答案比较确定做完能稳定情绪然后跳过错综复杂的NLP分析题先去写编程题最后再回头啃剩下的选择题。这个策略帮我保住了编程题的分数。考场上最怕的就是在一道选择题上纠结十分钟等到编程题时时间不够了心理也慌。编程题的分数占比高、得分可控性强理应优先保障。你甚至可以在扫完卷子之后先把稳拿的编程题代码在草稿纸上写好再回到选择题部分这样会更从容。5.3 资料与工具清单结合搜狗这场笔试的特点我建议的准备资源如下算法方面LeetCode高频题刷三遍特别是动态规划和贪心机器学习方面李航的《统计学习方法》重点看前八章加上周志华的《机器学习》深度学习与NLP方面动手实现一遍word2vec、Transformer的代码尤其是attention的计算细节。还有一个容易被忽视的工具typing库和代码模板。考场上写代码时,提前准备好并查集、二叉树遍历、最短路径、快排这些模板会节省大量时间。我当时是把常见模板整理到一个本地文件里考前过一遍考场上虽然不能直接复制但心里有底写起来会快很多。6. 踩过的坑与考场上的生存经验6.1 牛客网在线笔试环境的几个坑现在很多公司都用牛客网做笔试搜狗这场也不例外。我第一次用牛客网在线笔试时还真吃了亏——它的在线编辑器默认不开启自动补全所有函数名都要自己手敲。如果你平时用IDE写Python大量依赖自动补全到了笔试环境会非常不适应。我的建议是至少在考前一周开始用牛客网的模拟环境练习把不依赖补全写代码的手感找回来。另外一个坑是输入输出的格式。牛客网的判题系统有些题目是多组输入有些是单组输入你需要仔细看题目说明。如果没注意“多组输入直到EOF”这种描述代码只处理了一组数据就直接退出判题结果基本是运行错误。我见过不少人在牛客网刷题时只写了核心函数没写读入逻辑这在线下刷题没问题但笔试时必挂。6.2 遇到完全不会的题最忌讳的一件事考试时我遇到了一道关于CRF条件随机场的选择题选项里还提到了维特比算法、前向后向算法这些概念。我当时对CRF只能算眼熟谈不上理解第一时间是想蒙一个答案但想了想还是先标记等做完所有题再回来仔细推理。这里我要特别强调一个经验遇到完全不会的题最忌讳的是当场死磕因为这种题往往做不对还消耗大量时间和情绪。我的做法是先把题号记下来跳过继续做后面的题。等到所有能拿的分都拿到了再回来仔细分析。很多时候你在做后面题目的过程中会想到前面那道题的线索或者状态松弛下来之后再看题目反而能看懂它到底在问什么。这道CRF题我最后是按照“维特比算法是求最优路径、前向后向是求概率”这个记忆猜的运气不错蒙对了选项。但即使猜错损失也完全可以接受。还有一个小经验在线笔试时准备好纸笔或者开一个本地记事本。遇到复杂推理时先在草稿纸或记事本上整理思路再动键盘敲代码。我见过有人直接在编辑器里写注释当草稿这样会污染代码结构提交时容易漏删。纸笔演练比你想的更高效特别是图论和动态规划这类需要画状态转移的题目。另外笔试过程中要保持冷静的心态别被倒计时干扰。当时我旁边的人在疯狂敲键盘确实会有点焦虑但其实大家题都一样你被干扰的时候别人也在被干扰。按照自己的节奏走宁可稳一点也不要因为着急提交出低级错误。在线笔试允许提前交卷但如果你提前了半小时交卷大概率是漏掉了什么——我见过太多人提前交卷出来后发现自己少做了一面。还有一个我后来才知道的细节搜狗笔试结束后不要立刻关掉页面有的场次会弹出主观题或调查问卷。这些内容虽然不计入总分但有些HR会查看你有没有认真填写。我那次就直接关掉了现在想想如果里面存在“你印象最深的一个项目是什么”这样的问题认真写几句也许能帮助简历进入下一轮。细节决定成败这句话在校招里是真的会应验的。
返回列表