
1. 这套笔试卷考什么出题逻辑与宏观解读1.1 从岗位JD看考察目标网易有道事业部当年招算法工程师定位是搜索、广告、翻译这些核心产品线背后的算法支撑。你去看他们的岗位描述基本都会提到自然语言处理、用户行为建模、排序策略优化这类方向而2018年又是一波深度学习在工业界大规模落地的时期所以笔试题不可能只考一个维度。我拿到这份卷子后的第一感受是它不是在难为你而是在筛选“基础扎实、能写代码、对机器学习有系统理解”的人。换句话说它考的东西都是你日常做项目一定会接触到的数组、字符串、排序、树、图、经典机器学习模型、深度学习基本概念。难点不在题目本身而在覆盖面广、时间紧、需要快速切换思维模式。对比互联网大厂常见的笔试题型网易这套卷子的风格更偏“基本功摸底”不像有些公司只堆偏题怪题。如果你当时正在准备校招这套卷子其实是一个很好的自测标准——能把这套题吃透大部分互联网公司的算法岗笔试你都有底气。1.2 题型分布与侧重点分析整套试卷大致分成三类一是数据结构与经典算法约占总分的四成。数组、链表、字符串匹配、排序、贪心、动态规划、图的最短路径都有涉及。这里的题目不会要求你徒手实现红黑树但KMP、快排、堆排这类高频考点几乎必出。二是机器学习与深度学习基础约占总分的三成。常见模型对比LR vs SVM、Bagging vs Boosting、损失函数选择、过拟合处理手段、评估指标的含义这些是考察重点。有道业务天然带NLP属性所以词向量、序列模型这类题目也出现过。三是工程思维与数学基础约占总分三成。概率统计题、海量数据处理题、代码边界情况处理这部分最能拉开差距。很多人栽在看似简单的题上不是不会做而是没有考虑数据规模、没有处理好边界条件体现出“工程敏感度”不够。从备考角度说你不能只刷LeetCode。算法题只是入场券机器学习理论和数学基础同样重要。接下来我按知识板块把每一类考点的核心东西拆开讲。2. 数据结构与基础算法绕不开的基本功2.1 KMP与字符串匹配next数组的完整计算过程字符串匹配几乎是算法岗笔试的保留节目KMP又是字符串匹配里考得最多的。很多人背了模板但不会算next数组题目一换就卡壳。我先说说next数组的本质。next[i]的定义是模式串P的前缀P[0...i]中最长相等真前缀和真后缀的长度。“真”的意思是长度小于这个子串本身。比如模式串abacaba我们逐个位置算一下。P a b a c a b a 下标从0开始0 1 2 3 4 5 6i0时子串是a没有真前缀真后缀next[0] -1有些实现定义为0或-1看约定。i1时子串是ab前缀a后缀b不相等next[1] 0。i2时子串是aba前缀集合{a,ab}后缀集合{a,ba}最长的相等的是a长度1next[2] 1。i3时子串是abac前缀a,ab,aba后缀c,ac,bac无相等next[3] 0。i4时子串是abaca相等的最长前后缀还是a长度1next[4] 1。i5时子串是abacab前面是ab后面是ab长度2next[5] 2。i6时子串是abacaba前面是aba后面是aba长度3next[6] 3。这个数组最终是[-1, 0, 0, 1, 0, 1, 2, 3]如果你把next[0]放前面完整写出来就是从0到6。它告诉你的是匹配失败后模式串指针跳到哪个位置继续。KMP的核心思想是匹配过程中文本串指针永不回溯只移动模式串。失配时利用已经匹配的信息把模式串一次性移动到位从而把时间复杂度稳定在O(nm)。这里n是文本长度m是模式长度。我当年备考时喜欢亲手画一遍匹配过程文本串abacababacaba模式串abacaba。画完你就彻底明白了一旦模式串匹配到最后一个a时失配next[6] 3直接把模式串第3位即下标3的字符c对齐到刚才失配的位置而不是从头开始。这个“跳”的感觉是KMP的精髓。另外补充一点笔试里偶尔会出现BM算法或Sunday算法的对比。你不需要把每个字符串算法都实现一遍但至少要知道KMP是O(nm)BM平均更快但最坏也是O(n*m)Sunday在某些场景实现更简单。考对比题时能说清楚就行。2.2 排序算法全家桶复杂度、稳定性与场景选型排序是数据结构的基础笔试考察方式通常是给你若干排序算法问你某个特定序列下的比较次数、交换次数或者给你一个场景让你选最合适的算法。我在复习时给自己列了一个速查表直到现在带新人还在用算法平均时间复杂度最坏时间复杂度空间复杂度稳定性适用场景冒泡排序O(n²)O(n²)O(1)稳定几乎不用教学用插入排序O(n²)O(n²)O(1)稳定近乎有序的小规模数据选择排序O(n²)O(n²)O(1)不稳定简单但慢快速排序O(n log n)O(n²)O(log n)不稳定通用首选工程常用归并排序O(n log n)O(n log n)O(n)稳定需要稳定的外部排序堆排序O(n log n)O(n log n)O(1)不稳定需要O(1)空间的场景高频考点集中在快速排序和堆排序。快速排序的原理一句话每次选一个pivot把数组分成小于pivot和大于等于pivot两部分递归处理。它平均情况很快但最坏情况——比如每次pivot都选到最大或最小值——会退化成O(n²)。解决办法是随机选pivot或三数取中。C的std::sort在数据量小的时候会切到插入排序也是这个道理快排递归到小规模子数组时插入排序的常数优势更明显。堆排序的考点在于建堆和堆化的时间复杂度。很多答案说“建堆是O(n)”有人不理解为什么不是O(n log n)。其实你算一下堆的倒数第二层节点最多只需下移1次倒数第三层最多下移2次累加下来是一个收敛的级数总复杂度是O(n)。而上浮和下沉操作每次都是O(log n)。笔试里的排序题我建议多花时间理解“稳定性如何破坏的”快排不稳定是因为交换时可能把相等元素的相对顺序搞乱堆排序不稳定是因为堆调整时会把元素移来移去归并排序稳定本质是合并时遇到相等元素先取左半部分冒泡、插入稳定是相邻元素比较交换不会跨越式移动2.3 贪心、动态规划与搜索三分钟判断解题方向笔试算法题里贪心和动态规划是最容易混淆的。我的判断方法很直接每一步的最优能直接导致全局最优局部最优不互相制约 → 贪心子问题有重叠最优解由子问题最优解组合而成 → 动态规划每一步有多个选择但不知道哪个好 → 回溯/搜索典型贪心例子活动选择问题按结束时间排序、跳跃游戏、区间覆盖。你可以反证法验证其正确性笔试里如果时间紧张先猜贪心再补证明是个可行的策略。动态规划的考点则集中在几个经典模型背包问题0-1背包、完全背包、多重背包最长公共子序列LCS最长递增子序列LIS编辑距离区间DP、状态压缩DP以0-1背包为例状态定义是dp[i][j]表示前i件物品中容量为j时能获得的最大价值。转移方程是dp[i][j] max(dp[i-1][j], dp[i-1][j-w[i]] v[i])。空间上可以压缩成一维但要保证j从大到小遍历不然会重复取当前物品。搜索类题目一般DFS剪枝能解决大部分走迷宫最短路或带权图最短路直接上BFS或Dijkstra。很多同学问我Dijkstra和BFS的区别我用一句话说明BFS是按层扩展无权图最短距离天然的BFSDijkstra是带权的最短路用优先队列维护“当前距离最小的点”本质是贪心DP的结合但要求边权不为负。我在笔试现场遇到这类题的做法是先花30秒判断题型再花1分钟设计状态然后直接开写。状态定义对了转移自然就通。如果是贪心题先不管证明写出来跑通再说贪心的证明可以放到最后。3. 机器学习与深度学习从理论到实践的综合考察3.1 经典模型对比LR、SVM、决策树与集成学习笔试卷机器学习部分几乎必出模型对比题。我当年遇到的高频组合是逻辑回归LR和支持向量机SVM的区别。这题的满分回答通常包含几个层次损失函数层面LR用的是对数损失SVM用的是合页损失hinge loss。LR输出的是概率值天然适合需要置信度的场景SVM输出的是距离超平面的函数间隔本身不直接是概率要做概率输出还得额外校准。目标函数层面LR关注最大化似然SVM关注最大化间隔。SVM只关心距离超平面最近的那些样本支持向量这意味着它对边界附近的点很敏感LR则是所有样本都对模型有贡献即使离超平面很远的点也会产生梯度。适用场景层面LR更适合大规模数据、特征维度高、特征间有重叠的场景SVM在小样本、非线性可分时配合核技巧效果更好。你说不出哪个绝对好要分场景。这在笔试里是加分项因为说明你有工程判断力不是背答案。决策树和集成学习也是必考点。你需要理清楚Bagging和Boosting的差异Bagging并行训练多个基学习器各自独立最后投票或平均。代表是随机森林它额外在树分裂时随机选特征子集降低树之间的相关性。它的核心是降低方差——如果你发现模型方差过高过拟合随机森林是很好的选择。Boosting串行训练每个新模型关注之前模型的错误样本。代表是AdaBoost和GBDT。它的核心是降低偏差——如果你的模型偏差过高欠拟合用Boosting明显更合适。XGBoost那种题目出现时通常考点在于它相比GBDT的优化点目标函数加了二阶泰勒展开和正则项支持列抽样和并行化。你用“让每一轮损失下降得更准、同时控制复杂度”来回答基本不会错。3.2 评估指标与损失函数理解背后的业务含义算法工程师必须懂评估指标因为指标选错模型方向就错了。笔试经常会考精确率Precision、召回率Recall、F1、AUC这些概念。你需要信手拈来精确率 TP / (TP FP)预测为正的样本中实际为正的比例召回率 TP / (TP FN)实际为正的样本中被预测为正的比例F1 2 * P * R / (P R)精确率和召回率的调和平均AUCROC曲线下的面积随机选一个正样本和一个负样本正样本预测值大于负样本预测值的概率打个比方搜索场景里你希望召回率高一点因为宁可多给几个结果也不要漏掉用户想找的垃圾邮件过滤里你希望精确率高一点因为误杀一封正常邮件比漏掉一封垃圾邮件更让用户恼火。指标的选择永远服务业务目标。关于AUC还有一个常考的题AUC0.5说明什么说明模型跟随机猜测差不多。AUC0.8呢有80%的概率把正样本排在负样本前面。AUC对样本类别不均衡不敏感所以很多点击率预估模型都用AUC做离线评估。但AUC也有坑它不关心预测的绝对分数只关心排序如果你要校准概率比如做竞价排序要估计真实点击率还得看LogLoss。损失函数方面分类问题默认交叉熵回归问题默认均方误差MSE。考点在于为什么分类不用MSE因为MSE在softmax输出层上梯度容易饱和学习速度慢而且MSE假设误差服从高斯分布对分类问题的分布假设不匹配。交叉熵配合softmax梯度形式更漂亮量级适中训练更稳。3.3 深度学习核心概念优化、正则化与网络结构有道的业务天然和NLP绑得紧所以卷子里深度学习相关的内容一半是通用基础一半偏序列模型。通用基础这里有几个高频考点反向传播的链式法则这是必考的。你需要能够徒手推导一个两层的全连接网络的梯度知道为什么梯度消失/爆炸会发生——因为链式法则连乘时每层导数小于1会越乘越小大于1会越乘越大。解决办法就是ReLU系列激活函数、残差连接、BatchNorm、合适的初始化方法。优化器这块SGD、Momentum、Adam的对比是高频题。一句话总结SGD稳定但慢Momentum用动量来克服局部震荡Adam结合了Momentum和一阶二阶矩估计自适应调整学习率收敛快但可能有泛化性问题。近年很多实践又开始回归SGD余弦退火因为Adam在某些任务上泛化不如SGD。笔试里你答到“Adam快但可能需要调学习率SGD稳但慢”这个层次就足够了。过拟合的处理手段标准答案要分几个维度正则化L1、L2注意L1产生稀疏解、L2限制权重大小、Dropout训练时随机丢弃神经元相当于模型集成、数据增强图像翻转裁剪、文本回译、早停Early Stopping。在这里避坑的点是笔试如果给你一个specific场景不要只答“用dropout”要说明在什么层加、dropout率一般怎么设。推荐从0.2到0.5之间调如果模型已经严重欠拟合就别加dropout。序列模型方面RNN、LSTM、GRU的结构对比是常见考点。LSTM通过输入门、遗忘门、输出门来控制信息流动本质是解决RNN的长期依赖问题。你不需要背每个公式但需要知道门控机制让它能学会“什么时候记住、什么时候忘记”。Transformer出现后很多笔试也开始考self-attention它通过Q、K、V三个矩阵做注意力加权摆脱了RNN的序列依赖可以并行计算。词向量word2vec考的频率也很高。CBOW和Skip-gram区别CBOW用上下文预测中心词Skip-gram用中心词预测上下文。二选一的话Skip-gram对低频词更友好但训练更慢。负采样是优化训练速度的关键它让每次更新只采样少量负样本而不是在全词表上算softmax。4. 数学基础与工程思维容易被忽视的得分点4.1 概率统计与组合数学经典题型与答题套路算法工程师的数学功底重点不在高深公式而在概率直觉和计算能力。笔试卷中概率题通常占10%到15%形式上大概有三种。第一种是最简单的古典概型。比如“从52张牌中抽5张含至少一对A的概率”这类。解法是“算反面”用1减去不含A的概率计算量小很多。第二种是条件概率与贝叶斯公式。考法通常是某个疾病检测准确率99%患病率0.1%检测阳性的人真的患病的概率是多少答案是约9%。很多人算错是因为把“患病率”和“检测准确率”直接混淆了。列贝叶斯公式算一遍P(病|阳) P(阳|病)P(病) / P(阳) 0.99 * 0.001 / (0.99 * 0.001 0.01 * 0.999) ≈ 0.0902。这类题考察的是对先验概率和后验概率的理解贝叶斯公式一定要烂熟。第三种是期望与方差的计算。比如掷骰子直到出现6所需次数的期望这服从几何分布期望是1/p 6。还有一类题是“随机变量是均匀分布还是正态分布”配合切比雪夫不等式估算概率区间。组合数学方面经典模型是“n个球放入m个盒子球是否相同、盒子是否相同、是否允许空盒”这一大类。你别死记关键在于“插板法”和“隔板法”对于“相同的球放入不同的盒允许空盒”方案数是C(nm-1, m-1)。你把m个盒子看成m-1个隔板n个球排列成一行球和隔板一共nm-1个位置选出m-1个放隔板即可。我强烈建议考前把经典的计数模型通刷一遍比如圆周排列、可重复组合、容斥原理。每年笔试都有考生把组合数公式记混导致后面题全错。这个板块拿分性价比很高。4.2 海量数据处理TopK、去重与大文件处理工程思维在海量数据处理题里体现得最明显。题目长这样“10亿个整数找出最大的100个”。这类题在笔试中出现率极高答案也不唯一按数据规模分层给方案内存放得下时直接用堆维护一个大小为K的最小堆前K个元素先入堆之后每来一个元素和堆顶比较比堆顶大就替换并调整堆。时间复杂度O(n log K)。当n10亿、K100时log K约等于7非常快。内存放不下时分治归并。把10亿个数切分成多个小文件每个文件能加载到内存分别求TopK最后对每个文件的TopK做归并。这本质上是“分而治之”面试官还会追问你用什么hash函数做切分还记得要保证同一个数不会被分到多个文件吗这时不要用id取模而是对数值本身取模。去重类题目典型的比如“几十亿个URL找出重复的URL”。一个思路是布隆过滤器Bloom Filter用多个哈希函数映射到位数组如果某个URL映射的位置全是1可能重复只要有0肯定不重复。它能快速过滤掉大部分不重复的剩下的再拿精确去重做。代价是有误判率但位数组大小选好后可以控制得很低。这笔笔试里如果答出“可以先用布隆过滤器粗筛再对候选集精确去重”一定会加分。我在笔试中的经验是遇到海量数据处理题先算内存。把数字量级转成字节10亿个int约4GB10⁹ * 4字节显然不能全部载入内存。接下来无论你说堆、分治还是布隆过滤器都要以“内存限制”为出发点推导。这样答题才有逻辑而不是背套路。4.3 常考算法思想的横向对比笔试里还会出现几个看似独立、但本质相同的算法思想。我建议把它们放在一起对比记忆二分法适用于单调有序的搜索空间。不管是二分查找、二分答案还是浮点数的精度控制本质是不断缩窄可能性范围。分治法把大问题拆成小问题如归并排序。它和动态规划的区别是分治的子问题独立DP的子问题重叠。回溯法DFS的一种形式核心是“试探-回退”。在全排列、N皇后、子集等问题里写DFS然后回溯“恢复现场”是标准写法。很多同学漏了恢复现场导致答案重复或错误。剪枝回溯的优化手段在搜索过程中及时放弃不可能产生解的路径。常见剪枝有可行性剪枝当前路径已不符合条件、最优性剪枝当前结果已经不可能超过已知最优解。把剪枝加进DFS就是“带优化的暴力搜索”能解决一部分中等难度的笔试题。我画过一张简易对照表方便考前快速回顾思想核心策略典型应用常见复杂度二分每次排除一半有序数组查找、二分答案O(log n)分治分解-解决-合并归并排序、快排O(n log n)贪心每步取局部最优活动选择、哈夫曼编码O(n log n)DP缓存子问题解背包、LCS、编辑距离O(n²)左右回溯试探所有可能全排列、N皇后O(2^n)这个表的意义不是让你背复杂度而是提醒你拿到题先判断“问题是搜索型、优化型还是规划型”再选思想。我见过太多人上来就写递归写一半发现超时这就是题型判断错误。5. 笔试实战时间分配、答题顺序与易错点清单5.1 我建议的答题顺序与时间分配笔试时间一般两个小时题量大概10到15道含选择题和编程题。我的策略是“先挑软柿子再啃硬骨头”。第一步花3分钟把整张卷子扫一遍标记题目的难度。选择题先做概念型。比如“LR和SVM的主要区别”“下列哪种排序稳定”这类30秒内可以直接过的先做掉保证稳定得分。第二步做中等难度的编程题。这类题一般是字符串处理、排序、数据结构应用比如实现一个堆、写个KMP、用队列模拟栈。这些题你熟练的话每道15到20分钟内应该能搞定。不要边做边怀疑“是不是有更优解法”笔试找的是正确答案不是完美最优解能跑通就给分。第三步留40分钟给两道难题一般是动态规划或机器学习场景题。先想清楚状态定义再动笔写如果你10分钟内思路还没理清换下一道别死磕。过来人的心得时间不够时哪怕是写伪代码也比空白强。很多笔试评分是按步骤给分的你状态定义写对、转移方程写出来就算代码没能跑通也能拿到大部分分数。我把这道题的教训写在这里希望你别跟我当年一样最后留了一道看了15分钟觉得不会就空着的题出考场才发现能想到一半。5.2 高频易错点清单每一个都是血泪我把自己备考和实际笔试中踩过的坑整理成一份清单供你自查数组越界KMP计算next、快排分区时循环边界很容易写错。写代码前先把边界条件列出来。递归终止条件漏写递归函数没写终止条件直接死循环或栈溢出。这是新手最常见的错误。字符串处理空串输入可能是空串、全是空格、全是分隔符要提前考虑。整数溢出计算乘积、累加时int会溢出。笔试时优先用long long再考虑边界。排序顺序排序时没考虑稳定性要求或者比较器写反导致答案错误。动态规划数组初始化dp数组要初始化成什么值最大值还是0取决于你求的是最大值还是最小值忘记初始化会导致错误累积。精度误差浮点数比较不能用等于号要用绝对值小于1e-6的方式。SGD、Adam这些优化器在实现时不考虑学习率衰减导致后期震荡不收敛这也是机器学习手写代码题的扣分点。5.3 机器学习手写题与代码风格建议有一部分笔试会让你手写一个简单的模型训练流程比如线性回归的梯度下降。我的建议是把代码结构写清晰分块实现数据清洗与预处理特征标准化、缺失值处理模型初始化权重设为小随机数前向传播计算预测值计算损失函数反向传播求梯度更新参数迭代至收敛。代码风格上你不需要写出非常工程化的代码但要做到变量命名可读关键步骤有注释循环边界清晰。阅卷人可能没有时间逐行看你的代码但结构清晰的代码更容易给分。一个我常用的速写模板# 线性回归梯度下降 def train(X, y, lr0.01, epochs1000): m, n X.shape theta np.zeros(n) for epoch in range(epochs): y_pred X.dot(theta) grad X.T.dot(y_pred - y) / m theta - lr * grad return theta如果遇到“需要把学习率调小一点怎么办”这类追问你直接说增加学习率衰减策略就可以把epoch分成几段每段衰减一次学习率。面试官看到这样的代码第一反应是“这个人有训练模型的基本功”而不是只会调包。笔试也是一样你写的不是最优代码而是一眼能看懂的代码。6. 从这份笔试卷延伸开校招算法岗的备考路线6.1 刷题之外的三个核心能力很多备考者把精力全放在刷题上结果算法题刷了三百道机器学习题依然踩坑因为笔试考察的是“系统能力”。我认为刷题之外还要重点补三个能力第一纸上推导能力。面试或笔试时没有IDE帮你跑代码你必须在纸上写清楚状态转移、梯度推导、复杂度计算。备考时建议每周手写几道算法题的完整过程特别是动态规划和KMP这类细节多的题写一遍比看十遍有用。第二机器学习概念的口语化表达能力。笔试虽然不用说话但你把概念用口语化方式复述一遍往往能发现自己理解上的漏洞。比如“为什么L1正则化产生稀疏解”用“L1的等值线是菱形和损失等值线相交时更容易落在坐标轴上”来解释比死记公式更靠谱。第三场景到技术的映射能力。笔试里会出现“你在有道词典里做一个搜索建议功能你会怎么做”这种开放式问题。你要能把问题拆成用户输入的处理拼写纠错、候选召回编辑距离、前缀树、排序点击率预估模型。这种映射能力靠刷题刷不出来必须多看业务场景的案例分析。6.2 不同背景考生的补充建议如果你是科班出身计算机基础扎实建议把重点放在机器学习理论细节和深度学习最新进展上。笔试卷中偏业务场景的题目往往是拉分点。如果你是转专业背景算法基础相对薄弱建议先用两周把数据结构过一遍数组、链表、栈、队列、树、图的基本操作然后集中刷排序和字符串匹配。算法题至少刷100道再上考场不刷够很难拿到稳定分数。如果你想投递有道事业部这类偏搜索和NLP的岗位建议专门补充自然语言处理的基础知识中文分词、TF-IDF、BM25、word2vec、注意力机制。这些名词在笔试试卷中出现的概率很高你需要至少能写出BM25的公式结构知道TF-IDF的核心思想是“词频高且文档频率低的词更有区分度”。6.3 以赛代练模拟笔试的三个标准我备考时最常做的一件事是给自己搞“模拟笔试”。具体标准有三条限时。两个小时内完成一套题期间不上网查资料不使用IDE的语法提示。这一点很关键因为真实笔试现场往往比想象中更紧张平时不掐表考场容易写不完。手写核心代码。真正笔试时你可能会在线上编辑器敲代码但纸上推演还是必要的。每道编程题先在草稿纸上写出主要逻辑再誊抄到编辑器里可以大幅减少低级错误。复盘错题。不是看一遍标准答案就完事而是把错题归类是数据结构不熟、数学推导错误还是代码实现细节遗漏针对性补充最薄弱的部分。我最后两周做的事几乎全是复盘错题效果比刷新题好得多——你要相信考场上最可能出问题的就是你最容易错的那一类题。说回这套2018年的网易有道笔试卷它其实代表了那个阶段互联网算法岗通用的考察范式基础算法、机器学习理论、数学功底、工程思维一个都不能少。我前前后后把这套卷子复盘过三遍每次都有新体会。最后一件事想告诉你笔试只是整个校招流程的开头它考察的不是你有多聪明而是你有没有系统准备过。把这套卷子吃透你带走的远不止一份offer而是一套相对完整的算法工程师思维框架。