ARTICLE DETAIL

建站实战干货

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

网易算法工程师笔试复盘:从KMP到粒子群,考点全解析

2026/9/1 21:45:39 拓冰建站 浏览量
网易算法工程师笔试复盘:从KMP到粒子群,考点全解析 2020届秋招提前批我投了网易的算法工程师岗位。当时正值7月底实验室项目刚收尾我一边刷题一边整理机器学习笔记紧赶慢赶才赶上了提前批笔试那一班车。现在回头看这场笔试网易考得不算猎奇题目风格非常典型——基础算法要吃透机器学习理论要能手推编程题则看你的优化链路是否完整。这篇文章是我对那次笔试的完整复盘包括题型分布、高频考点、两道编程题的详细推演以及事后总结出的备战方法。如果你正在准备互联网公司的算法岗笔试或者想了解网易提前批的考察风格这篇应该对你有用。1. 网易2020提前批算法笔试复盘题型结构、时间压力与整体难度感知1.1 笔试平台与时间安排的第一印象网易校招笔试一般走牛客网提前批也不例外。进考场后第一件事是调试环境C、Java、Python都能选我选的C。这里有个小提醒牛客的在线IDE和本地编译器在某些情况下输出格式要求很严格比如行尾空格、换行符提交前最好自己在心里过一遍样例格式。我当时就遇见过本地跑得好好的粘贴到牛客却因为多打了一个空格被判格式错误的情况非常亏。时间上我印象里是90分钟到120分钟题目分选择题和编程题两大块。选择题大概20道左右单选多选混在一起多选少选、错选都不得分。编程题是3道难度梯度很明显第一道基础第二道中等第三道偏难。时间压力主要来自选择题的干扰项设置——有些题不是不会而是选项长得太像需要反复推敲。1.2 题型分布与分值比例从内容上看选择题覆盖了数据结构、算法策略、机器学习、深度学习这几大模块。数据结构部分数组、链表、二叉树、堆、图都有涉及但不会直接考概念而是给一段代码让你推输出或者给一个场景让选合适的数据结构。算法策略部分动态规划、贪心、分治、回溯占了大头偶尔穿插一两个智能优化算法的概念题。机器学习部分的分值比我预想的高几乎占选择题的一半。经典算法问原理场景题问选型还有一些理论推导类的题。深度学习方面反向传播、激活函数、损失函数、梯度消失是常客基本每家互联网公司都会考。整体难度属于“认真准备过就能做裸考大概率挂”的水平区分度主要在编程题的完成度和正确率上。1.3 整体难度感知与淘汰逻辑拿我自己和周围同学反馈来看网易提前批笔试的淘汰率不低。原因不是题目本身有多难而是综合考查面很宽。有些人数据结构很强但机器学习理论薄弱有些人模型调参经验丰富但手写代码速度跟不上。笔试真正想筛掉的是那种“单点突出但短板明显”的候选人。编程题部分尤其能拉开差距。第一道送分题必须全对这是底线第二道是拉分题做出来基本能进面试第三道是筛选题给最顶尖的那批人准备的。我当时的策略是先把第一道和第二道稳稳写出来第三道如果没思路就写暴力解骗部分分数最后回头检查选择题。这个策略后来证明是有效的因为我认识的几个同学在第三道上死磕太久反而第一道第二道出现了低级错误。2. 基础算法高频题从哪来以KMP、排序和字符串题为线索2.1 KMP的next数组一道看似送分却暗藏定义的题网络热词里有一条很扎眼在KMP算法中对于模式串pabacaba其next数组next[i]定义为……。这种题在网易笔试里确实出现过表面上是送分题实际上坑在于next数组的定义并不统一。不同教材对next数组有两种常见定义一种表示当前子串的最长相等前后缀长度不含自身另一种表示失配时应跳转到的下标后者往往还要附加next[0] -1的处理。我按第一种定义推一遍。模式串p abacaba逐个位置取子串i 0子串a没有前后缀next[0] 0i 1子串ab前缀a后缀b不相等next[1] 0i 2子串aba前缀有a、ab后缀有ba、a最长相等前后缀是anext[2] 1i 3子串abac前缀a、ab、aba后缀bac、ac、c无相等前后缀next[3] 0i 4子串abaca前缀a、ab、aba、abac后缀baca、aca、ca、a最长相等前后缀是anext[4] 1i 5子串abacab前缀a、ab、aba、abac、abaca后缀bacab、acab、cab、ab、b最长相等前后缀是abnext[5] 2i 6子串abacaba前缀a、ab、aba、abac、abaca、abacab后缀bacaba、acaba、caba、aba、ba、a最长相等前后缀是abanext[6] 3所以第一种定义下next数组是[0, 0, 1, 0, 1, 2, 3]。如果题目明确next[i]定义成失配跳转位置那就需要在这个结果上做偏移有些教材会整体减一或加一个哨兵。笔试时务必先看清题目给的定义再动手否则一步错步步错。提示KMP的next数组计算是笔试中的高频送分题但一定要先确认定义方式。2.2 排序算法不止是背复杂度更要会推过程排序算法在网易笔试里从来不是单纯问“快排时间复杂度是多少”这种送分题而是会给出一个具体序列问你冒泡排序第一趟之后的结果、堆排序建堆后的数组形态、归并排序某一次合并后的中间状态。这类题考察的是你是不是真的理解排序机制的每一层循环。我举一个典型的堆排序考点。给定一个乱序数组要求建最大堆。很多人的习惯是背诵“从最后一个非叶子节点开始向下调整”但到了考场上真让你画出调整后的数组就容易乱。记一个关键点建堆的调整顺序是从右往左、从下往上而不是从堆顶开始。另一个易错点是堆排序每一趟会把堆顶元素和当前堆的末尾元素交换交换后堆的大小减一然后再对新的堆顶做向下调整。如果想当然地不缩小堆的大小写出的代码和手推的答案都会错。冒泡排序的C代码比较简单但笔试可能这样考在一个基本有序的数组上冒泡排序做了几轮提前终止。这就涉及到优化冒泡的“是否发生交换”标记。我当时遇到的选择题就是这个变体答案不是n-1轮而是提前几轮退出。所以刷排序题时不要只背代码务必把每个排序的趟数、比较次数、交换次数、稳定性这些细节在纸上演算几遍。2.3 图论与搜索Dijkstra、拓扑排序和二分图在哪出现图论在网易笔试里属于中高频考点但不会考太偏的算法。Dijkstra是典型的考察对象通常以选择题或填空题形式出现问某个图在优先队列优化下从源点到各点的最短路更新过程。这里有个细节Dijkstra要求边权非负如果题目里出现了负权边那答案大概率不是Dijkstra而应该用Bellman-Ford或SPFA。拓扑排序同样常考尤其是“判断有向图中是否存在环”和“输出一种拓扑序”这两个角度。这个知识点在编程题部分也容易结合具体场景出现比如课程先修关系、任务依赖调度。Kahn算法的核心就是记录每个节点的入度用队列维护所有入度为0的节点逐个弹出并更新邻居入度。整个过程本质上就是BFS的变体理解了入度的含义就不容易写错。热词里还有一个“二分图HK算法”——Hopcroft-Karp算法这是二分图最大匹配中比匈牙利算法更快的一个实现复杂度O(E√V)。网易笔试选择题可能会问“二分图最大匹配的HK算法时间复杂度”或“什么数据结构适合维护增广路径”但不至于要求现场手写完整HK算法。如果你准备的是CV或推荐方向的算法岗图匹配的概念了解一下即可不用死磕。3. 机器学习与深度学习笔试考点从KNN到XGBoost网易在考什么3.1 经典机器学习考点原理推导加场景应用网易笔试里机器学习部分并不满足于问“KNN是什么”而是会出类似“KNN算法的应用能力包括哪三个方面”这种题。常见答案可以归结为分类、回归和异常检测有些资料会写成推荐场景。这三种应用背后其实是同一个机制基于样本相似度做推断。分类时取最近邻的类别投票回归时取最近邻的值加权平均异常检测时看样本点与近邻的距离是否显著偏离整体分布。K-Means也是高频考点。笔试常问它和KNN的区别以及K-Means的优缺点。K-Means需要预设簇数K对初始中心敏感容易陷入局部最优而且对噪声和离群点敏感。这些不能只背要能说得清为什么。比如对初始中心敏感是因为算法本身是坐标下降式的迭代优化目标函数非凸初值不同收敛到的局部解就不同。理解了这一点遇到场景题“哪些数据不适合用K-Means”就能举一反三。聚类那边还有一个容易考的点是DBSCAN。它不需要预设簇数可以发现任意形状的簇还能识别噪声点。笔试喜欢给一组点问哪些是核心点、哪些是边界点、哪些是噪声点核心是理解半径eps和最小样本数MinPts两个参数的含义。我当时复习时特意画了几个不同分布的数据点反复练最后考到类似题时完全不慌。3.2 深度学习高频题反向传播、梯度消失与损失函数深度学习的考察以理论为主。反向传播几乎必考但不会让你真的手动算整个网络的梯度而是给一个简单的两层网络要求推导某个参数的梯度表达式核心是链式法则。我当时遇到的是含sigmoid激活函数的二分类问题要写出损失对第一个权重矩阵的梯度。这时候如果记得sigmoid的导数形式σ(x) σ(x)(1 - σ(x))推导会快很多。梯度消失是另一个高频点通常以“为什么深层网络难以训练”这种形式出现。原因在于反向传播时梯度逐层相乘如果激活函数的导数小于1比如sigmoid、tanh的饱和区多层相乘后梯度会指数级衰减到接近0。解决办法也常考换ReLU等导数恒定的激活函数、BatchNorm、残差连接、合理的权重初始化。网易的选项里有时会混淆“增加学习率”这种治标不治本的手段要仔细分辨。损失函数方面KL散度是一个容易出概念题的点。KL散度用来衡量两个分布之间的差异但它是非对称的KL(P||Q)不等于KL(Q||P)这意味着它不是一个严格意义上的距离度量。热词里提到的“KL ELBO算法原理”其实就是变分推断里的核心概念把对数似然分解为ELBO加KL散度然后通过最大化ELBO来逼近真实后验。网易不太会要求现场推导变分推断但选择题里可能会问“为什么ELBO可以做优化目标”答案就是“最大化ELBO等价于最小化KL散度同时弥补了后验不可直接计算的短板”。3.3 优化算法与新兴热点粒子群、模拟退火和它们的位置热词里出现了“粒子群算法原理”和“模拟退火算法”这些在网易笔试中的出现率不高但偶尔会在选择题里露脸。它们属于元启发式优化算法不算大厂笔试的主流但是一旦出现考的多是核心思想而非复杂推导。粒子群算法PSO模拟鸟群觅食每个粒子代表解空间中的一个候选解粒子有位置和速度两个属性。每次迭代中粒子根据个体最优pbest和全局最优gbest更新速度再更新位置。核心公式是速度更新带有惯性权重w、个体认知项c1和群体社会项c2。笔试如果考PSO大概率会问“惯性权重w的作用”——答案是平衡全局探索和局部开发w较大时粒子飞得远、全局搜索能力强w较小时收敛到局部更精细的区域。我当时就是靠记住了这句话在一道选择题里排除了两个干扰项。模拟退火的核心是Metropolis准则算法在搜索过程中以一定概率接受比当前解更差的邻居解并且这个接受概率随着温度降低而逐渐减小。这样做是为了跳出局部最优因为最优解搜索最怕“走上小山坡就以为到了山顶”。模拟退火的考点通常是“温度下降曲线对搜索的影响”或“为什么需要以一定概率接受恶化解”。这些题很简单记住思想就行不用现场推导。4. 编程题实战拆解从暴力解到最优解的两道完整真题4.1 和为K的最长连续子数组前缀和加哈希的经典套路网易编程题第一题的风格通常是基础的数组或字符串处理。我印象很深的一道题是给定一个整数数组nums和一个目标值K求nums中和为K的最长连续子数组长度。输入规模大概是10^5级别所以O(n^2)的暴力解只能过部分数据。暴力做法很好想枚举每个起点i从i开始累加一旦累加和等于K就更新答案。但这样是O(n^2)对于10^5的规模直接超时。优化的核心是把问题转化成前缀和。设prefix[i]表示前i个元素的和那么子数组[j1, i]的和等于prefix[i] - prefix[j]。要找和为K的子数组就是找一对(i, j)使得prefix[i] - prefix[j] K即prefix[j] prefix[i] - K。于是问题变成遍历i时如果之前出现过前缀和为prefix[i] - K的位置j那么j1到i这段子数组的和就是K。为了求最长我们只需要记录每个前缀和第一次出现的位置因为第一次出现的位置最靠前对应的子数组长度最大。C实现如下#include bits/stdc.h using namespace std; int main() { int n, K; cin n K; vectorint nums(n); for (int i 0; i n; i) cin nums[i]; unordered_mapint, int firstPos; // 前缀和 - 第一次出现的位置 firstPos[0] -1; // 前缀和为0出现在起始位置之前 int sum 0, ans 0; for (int i 0; i n; i) { sum nums[i]; int target sum - K; if (firstPos.count(target)) { ans max(ans, i - firstPos[target]); } if (!firstPos.count(sum)) { firstPos[sum] i; } } cout ans endl; return 0; }这里有两个容易踩的坑。第一个是边界前缀和为0的位置要初始化为-1这样如果整个数组从开头到某个位置的累加和等于K答案才能正确计算。第二个坑是“记录第一次出现位置”和“查询”的顺序每次先查询target再记录当前sum避免出现子数组长度为0的情况。如果你把顺序写反对于K0的用例会拿到错误的长度。我在笔试时是先写了暴力版本验算小数据再改成前缀和版本。这种“先暴力验证思路再优化”的流程可以帮助减少因题目理解偏差导致的返工。4.2 课程表拓扑排序Kahn算法的完整推导与代码第二道编程题我有印象的是课程先修关系的变体给定n门课程编号0到n-1以及m条先修关系每条关系表示要学课程a必须先学课程b问能否学完所有课程如果能则输出一种学习顺序。这就是典型的拓扑排序Kahn算法是标准解法。Kahn算法的步骤如下根据先修关系建图记录每个节点的入度。把所有入度为0的节点放入队列。每次从队列取出一个节点加入拓扑序并把它的所有后继节点的入度减1。如果某个后继节点的入度变为0就把它加入队列。最后如果拓扑序中的节点数等于总节点数说明无环否则存在环无法学完所有课程。这个算法背后的原理很直观入度为0意味着“当前没有必须先修的课程”可以随时学学完之后它作为先修条件的影响就消失了所以让后继节点的入度减1。如果存在环环上的节点永远不会出现入度为0的情况最后队列会提前为空。C实现#include bits/stdc.h using namespace std; int main() { int n, m; cin n m; vectorvectorint graph(n); vectorint indegree(n, 0); for (int i 0; i m; i) { int a, b; cin a b; // 学a先学b即b - a graph[b].push_back(a); indegree[a]; } queueint q; vectorint order; for (int i 0; i n; i) { if (indegree[i] 0) q.push(i); } while (!q.empty()) { int cur q.front(); q.pop(); order.push_back(cur); for (int nxt : graph[cur]) { indegree[nxt]--; if (indegree[nxt] 0) q.push(nxt); } } if ((int)order.size() ! n) { cout 存在环课程无法完成 endl; } else { for (int x : order) cout x ; cout endl; } return 0; }拓扑排序有一个常见变体如果有多种学习顺序要求输出字典序最小的。这时把queue改成priority_queue每次取出编号最小的入度为0节点即可。网易的题很可能在这里“暗改”条件我在笔试时遇到过要求在输出顺序上做文章的情况。所以光会标准Kahn还不够要能根据题目要求灵活调整弹栈/出队的数据结构。4.3 编程题答题策略拿分优先还是最优解优先我的经验是笔试现场永远先保证“能过样例的完整代码”再谈最优解。如果你一上来就追求最优解结果卡在推导细节上很可能连基础分都没拿到。反过来先用暴力解把题目做出来、验证了思路再优化至少能保证部分通过。网易的编程题不像竞赛题那样“要么满分要么零分”牛客的评测通常按测试用例比例给分。暴力解通过30%到60%的用例很常见。所以我建议大家按“暴力解确认思路、优化解拿满分”的顺序来写。第三题如果实在没思路就把最朴素的做法写上去哪怕只过小数据也比空着强。另外提交前一定自己构造边缘用例跑一遍。比如空数组、只有一个元素、K为0、所有元素相等这些情况。很多隐蔽的bug都是在这类边界条件下暴露的提前发现能挽回不少分数。5. 针对网易风格笔试的备战建议与时间规划5.1 刷题顺序从数据结构到算法专题再到模拟如果你离笔试还有一个月左右我的建议是分三个阶段。第一阶段花一周把数组、链表、栈、队列、哈希表、二叉树、堆这些基础数据结构的经典题刷一遍熟练度目标是“看到题就知道用什么数据结构”。第二阶段花两周按专题刷算法排序与二分、双指针、滑动窗口、贪心、动态规划、DFS/BFS、并查集、前缀和、拓扑排序。每个专题先看3到5道经典题理解套路再刷对应练习。第三阶段是笔试前最后一周做模拟。牛客网上有很多历年大厂校招真题按真实考试时间限时训练。模拟的目的是训练时间分配和临场心态而不是刷题量。我见过不少同学平时刷题很猛模拟考前三天才第一次限时做套题结果真正考场上时间完全不够用。从第三周开始每天一套限时模拟效果会好很多。5.2 机器学习与深度学习怎么复习资料选择与笔记方法机器学习的复习不能只看网课必须动手推导。我当时用李航的《统计学习方法》作为主线把感知机、KNN、朴素贝叶斯、决策树、逻辑回归、SVM、AdaBoost、EM算法这些经典模型逐个过了一遍重点看损失函数和参数更新公式。笔试选择题里“哪个模型对应哪个损失函数”“哪些模型是判别式、哪些是生成式”这类题直接对应书里的章节内容。深度学习的理论部分要能熟练手推反向传播至少是两层全连接网络的程度。这里推荐通过写代码来加深理解用numpy纯手写一个简单的BP网络从输入到损失再到梯度更新全程不依赖框架。写过一遍之后很多选择题里的干扰项会自动浮现出来。笔记方法上我不建议大段抄书而是做“一问一答”式的卡片。比如“XGBoost比GBDT强在哪里”答案是二阶泰勒展开、正则项、列采样、Shrinkage。再比如“梯度消失的解决方案有哪些”答案是换激活函数、BatchNorm、残差、合理初始化。笔试前一周反复过这些卡片比抱着书从头翻到尾高效得多。5.3 笔试现场的时间分配与骗分技巧最后聊一下考场上的实操。我的时间分配大致是这样拿到卷子先花2到3分钟快速浏览所有题目特别是编程题的难度分布。选择题部分一定要控制时间如果一道题超过2分钟还没思路先凭第一感觉选一个并标记最后如果有剩余时间再回来算。我自己的教训是在一道SVM核函数的选择题上死磕了将近10分钟结果编程题最后没时间调试损失惨重。编程题的骗分技巧要大大方方用。第一道题写完后用自己构造的边界用例测试一下再提交。第二道题如果时间只剩15分钟就直接写暴力解不要犹豫。第三道题如果连题目理解都困难把输入按照模板读进来输出一个猜测值至少能保证不会因为编译错误得零分。还有一个容易被忽略的点读题一定要慢。网易的编程题有时候会把约束条件藏在最后一两行比如“数组长度不超过10^5所有数字绝对值不超过10^9”这些信息直接决定算法选型。如果你只看了示例输入就开始写大概率会漏掉关键约束被迫中途推翻重写。我个人的体会有两点。一是“框架感”比“知识点列表”更重要复习时不要追求面面俱到地记每个理论而要建立“遇到一个问题先判断它属于哪一类再套对应的思路”的思维模式网易笔试的题量不允许你临时思考每一种可能性。二是错题复盘的价值远大于刷新题每做完一套模拟把错题涉及的知识点写进卡片一周后重做一遍你会发现有些错误会重复出现。这种反复磨错的功夫才是笔试稳定发挥的基础。