
1. 笔试题型全景当年那份卷子到底在考什么先把时间拉回2018年春季网易实习生招聘的机器学习算法岗笔试。那阵子正是各大厂实习生招聘最集中投递的阶段简历过筛之后笔试是第一道硬门槛。我身边好几个同学都把宝押在了算法岗上结果卷子一发下来心态先崩了一半——题量不小而且风格和大厂统一出的“行测专业题”路数不太一样更偏向对机器学习基础功底的深挖。先说结论网易这场笔试的题型大致可以分为三类一是选择题覆盖机器学习基础概念、概率统计、线性代数、数据结构常识二是编程题通常两到三道考察代码实现能力和算法设计三是简答/手推题专门考验你对常见模型的原理理解深度。不同年份题量略有浮动但核心考察逻辑一直没变它不关心你背了多少模型名字而是关心你能不能把一个模型从损失函数推到最优化过程再落到代码实现上。这也解释了为什么很多人“看过西瓜书”“刷过sklearn文档”却依然挂掉笔试。因为笔试考的是推导和细节而不是调包。比如面试官会问逻辑回归的损失函数怎么来的SVM的对偶问题为什么要引入核函数朴素贝叶斯里“朴素”到底体现在哪里。这些如果你只停留在“会用model.fit()”的层面是没有办法在有限时间内答好的。我当时复习的节奏是先快速过一遍基础概念然后重点做手推题最后留两天集中练编程题。如果你的时间也比较紧张建议按这个优先级来。下面我把每个模块具体考什么、怎么准备拆开讲清楚。2. 机器学习核心考点逐题拆解面试官最喜欢挖的五个地方2.1 逻辑回归不只是sigmoid套一层逻辑回归在笔试里的出现频率基本是“必考”级别。为什么因为它足够基础又足够深。表面上看逻辑回归就是线性模型加了一个sigmoid函数把输出映射到0到1之间。但真正理解它的人应该能回答这么几个层层递进的问题为什么用sigmoid把线性输出w^T x通过sigmoid变换恰好可以得到一个概率值。更深一层逻辑回归可以从“广义线性模型”的角度推导出来假设y服从伯努利分布连接函数选logit函数就能得到sigmoid形式。这个推导过程是简答题的高频考点。损失函数为什么是交叉熵而不是均方误差因为逻辑回归的极大似然估计取负对数之后就是交叉熵形式。如果改用均方误差损失函数变成非凸函数用梯度下降很容易陷入局部最优而交叉熵配合sigmoid梯度形式是(h(x) - y)x虽然也有饱和区但整体优化更稳健。梯度下降的公式怎么推对交叉熵损失求偏导最后得到θ_j : θ_j - α * Σ(h(x_i) - y_i) * x_{ij}这个更新公式在面试中经常被要求现场推一遍。我印象很深的一道选择题是“逻辑回归中如果对特征做标准化会对模型训练产生什么影响”很多人会选“没有影响”因为逻辑回归的理论解与特征尺度无关。但实际上如果不做标准化使用梯度下降时不同特征的梯度量级差异很大会导致收敛路径震荡训练效率极低。所以答案应该是“能加快梯度下降的收敛速度但不改变模型的理论表达能力”。这种题就是典型的一看就会、一选就错。2.2 SVM对偶、核函数、软间隔的三角关系SVM是机器学习算法实习生笔试里的“硬骨头”也是个分水岭。选择题和简答题都可能出现而且一旦出现往往就是拉分题。我对SVM的复习思路是抓住三条主线原始问题、对偶问题、核技巧。原始问题是一个带不等式约束的凸优化问题目标是最小化1/2 ||w||^2约束是y_i(w^T x_i b) 1。为了用拉格朗日对偶性求解我们构造拉格朗日函数然后通过对偶问题把原问题转化成一个只依赖样本内积的形式。为什么费这么大劲转成对偶一方面是因为对偶问题有更高效的求解方式SMO算法另一方面是为了引出核函数——因为对偶形式里样本只以内积x_i, x_j出现所以我们可以用核函数K(x_i, x_j)替换这个内积从而隐式地把样本映射到高维空间。还有一个必考点是软间隔。现实数据几乎不可能完全线性可分所以引入松弛变量ξ_i和惩罚参数C。C越大意味着对误分类的惩罚越重模型越倾向于“严格分类”但也越容易过拟合C越小模型越容忍误分类泛化能力通常更好但可能欠拟合。这个C的含义和结果是选择题的高频素材。我当时复习的时候在网上找了不少往年的题目其中最典型的一道是“SVM中核函数的作用是什么以下说法错误的是A. 将线性不可分的数据映射到高维空间后线性可分B. 核函数可以避免在高维空间中直接计算C. 核函数可以降低模型的复杂度D. 核矩阵必须满足半正定性”。答案是C。核函数确实避免了高维显式计算也利用了高维映射来提升线性可分性但它本身并不会降低模型复杂度反而可能因为过拟合导致泛化能力下降。这种考法非常能区分“背概念”和“真理解”。2.3 决策树与集成学习信息增益、基尼系数和随机森林决策树这块笔试里常考三种特征选择标准信息增益、信息增益率、基尼指数。ID3用信息增益C4.5用信息增益率CART用基尼指数。每一种标准的定义公式、计算例子、优缺点对比都得烂熟于心。为什么C4.5要用信息增益率因为信息增益有一个天然的问题——它倾向于选择取值数目较多的特征。比如“样本ID”这个特征每个样本一个值那么在这个特征上划分后每个子节点的纯度都是100%信息增益最大。但这显然没有泛化意义。信息增益率通过除以特征自身的内在信息IV来惩罚取值过多的情况缓解了这个问题但代价是可能偏好取值较少的特征所以C4.5实际使用时还会加一个启发式规则先从信息增益高于平均水平的特征里选再选增益率最高的。集成学习也是必考。Bagging和Boosting的区别可以说是面试中的“送分题”和“送命题”并存。送分是因为区别本身很清晰Bagging对训练集有放回采样训练多个基学习器最后投票或平均核心是降低方差Boosting则是串行训练每个基学习器重点关注前一个学习器分类错误的样本核心是降低偏差。送命是因为一旦深挖下去很多人开始含糊。比如随机森林的随机性到底体现在哪里答案是两层一是样本随机二是特征随机。每次分裂时不是从全部特征里选最优而是先随机抽一个特征子集再从中选最优。这个操作的好处是进一步降低树与树之间的相关性因为如果所有树都在最强特征上分裂那它们会高度相似集成的多样性就没了。我在备考时自己动手推过一道题给定一个二分类数据集某个特征下A类的条件概率是0.8求该特征的基尼指数。这类计算题只要你记住公式Gini 1 - Σp_k^2很快就能算出来。但要注意如果题目问的是“按某个特征划分后的基尼指数”那需要先算每个子节点的基尼指数再按样本比例加权平均。2.4 概率统计条件概率、贝叶斯公式和极大似然估计概率统计是笔试里的“稳定得分区”但前提是你真的熟练。常见的出题方向有全概率公式、贝叶斯公式、常见分布伯努利、二项、高斯、泊松的性质、期望与方差的线性性质、极大似然估计的求解过程。贝叶斯公式这道经典题几乎年年有“某种疾病的患病率为0.1%检测试剂的准确率为99%。如果一个人检测结果为阳性那他真正患病的概率是多少”很多人第一反应是99%但正确答案远低于这个值。用贝叶斯公式算P(患病|阳性) (0.001 * 0.99) / (0.001*0.99 0.999*0.01) ≈ 0.0902也就是约9%。这个结果反直觉但恰恰是面试官想看到的——你是否理解先验概率对后验概率的影响。极大似然估计也是简答题的高频考点。经典题型是假设样本服从高斯分布N(μ, σ^2)用极大似然估计求出μ和σ^2。流程是写出似然函数取对数分别对μ和σ^2求偏导并令其等于0。结果你会发现μ的估计就是样本均值σ^2的估计是1/n * Σ(x_i - μ_hat)^2注意这里分母是n而不是n-1因为极大似然估计得到的是有偏估计。如果你够敏锐可以顺带提一句“如果希望无偏应该用样本方差公式分母是n-1”这会让面试官觉得你连估计量的性质都考虑过。2.5 聚类与降维K-Means的收敛性和PCA的本质聚类和降维也是实习生笔试的常客。K-Means的高频考点是它的目标和收敛性。K-Means的目标函数是“每个样本到其所属簇中心距离的平方和”算法通过交替迭代分配样本到最近中心、重新计算中心来最小化这个目标。但K-Means只能保证收敛到局部最优对初始中心的选择非常敏感所以才会出现K-Means这类改进初始化策略的算法。PCA的高频考点是它的数学本质找一个方向让数据投影后的方差最大。这个方向其实就是数据协方差矩阵的最大特征值对应的特征向量。主成分的求解过程可以概括为数据中心化、计算协方差矩阵、对协方差矩阵做特征值分解、按特征值大小排序取前k个特征向量构成投影矩阵。这里经常考的一个细节是PCA前为什么要中心化因为如果不减去均值第一主成分可能被数据的均值而不是方差主导导致降维方向偏离真正方差最大的方向。这些知识点看起来零散但其实是连成片的。逻辑回归和SVM都是分类模型决策树是另一种分类思路贝叶斯是概率框架下的分类方法聚类是无监督学习PCA是特征工程工具。复习的时候最好自己画一张知识地图把一个模型放到它该在的位置上然后顺着它去回忆相关的推导和细节。这比零散地刷题要高效得多。3. 数据结构与算法编程题笔试真正的分水岭3.1 编程题的题型与整体风格机器学习算法实习生的编程题难度通常在中等到偏上时间限制在几十分钟内完成所以考察的核心是“快速想到正确思路写出无bug的代码”。常考的题型包括数组与字符串处理、排序与查找、动态规划、贪心算法、树与图的遍历、字符串匹配。网易这道笔试题也不例外。我记得网上流传的题目里有几个方向很典型一道字符串相关的题一道动态规划/贪心相关的题可能还有一道数学思维题。这类题目不一定会直接考机器学习算法但会考计算机基础算法原因是实习岗位需要你有扎实的代码功底能快速实现模型训练或数据处理逻辑。这里给一个建议刷题不要只刷“知道思路”就跳过一定要亲手在编辑器里写完并跑通。笔试时的代码编辑器通常没有本地IDE那么强大自动补全和报错提示都有限平时练出手感很重要。我自己的标准是一道题如果15分钟内想不出思路就看题解但看完必须自己独立写一遍。3.2 KMP算法next数组的推导是笔试常客所有数据结构教材里都会讲字符串匹配而KMP算法是其中的重点。看似是传统考点但这些年招聘笔试里依旧频繁出现因为在文本处理、序列匹配等场景中KMP的思路极其重要。对于模式串pabacaba它的next数组按不同教材的定义会略有差异但核心思想是一样的next[i]表示当p[i]与主串失配时模式串应该回退到的位置。计算next数组的经典方法是“递推回溯”本质上是在算模式串内部的最长相等前后缀长度。abacaba这个串的前缀和后缀有重叠所以next数组不会是单调递增的手动推导一遍会让你对KMP有深刻的理解。手推过程是这样的以下采用“next[i]表示i位置之前的子串最长相等前后缀长度”的定义方式next[0]-1a没有真前后缀所以next[1]0ab最长相等前后缀长度为0next[2]0aba有最长相等前后缀a长度1next[3]1abac没有next[4]0abaca有a长度1next[5]1abacab有ab长度2next[6]2abacaba有aba长度3next[7]3。这里的每个值都对应一次“失配后该如何跳转”的决策理解了它KMP的代码自然就记住了。我在笔试时遇到过KMP的选择题考察——问某个模式串的next数组值。如果你平时没有亲手推过很容易在“前后缀重叠”的细节上出错。所以考前强烈建议自己推导3到5个不同的模式串做到“不看课本也能推导出来”。3.3 动态规划从暴力递归到状态压缩动态规划是编程题的重灾区也是最容易拉开差距的题型。常见模型有背包问题、最长公共子序列、最长递增子序列、编辑距离等。备考时我给自己定了一个公式化的解题路径先定义状态含义再写状态转移方程最后确定初始化和遍历顺序。举个例子最长递增子序列问题。状态定义可以是dp[i]表示以nums[i]结尾的最长递增子序列长度。转移方程是dp[i] max(dp[j] 1)其中j i且nums[j] nums[i]。初始化时dp[i] 1因为每个元素自身是一个长度为1的递增子序列。这个解法的时间复杂度是O(n^2)如果n很大需要优化到O(n log n)用维护一个递增的“tails”数组配合二分查找实现。笔试时动态规划最常见的失误不是不会写转移方程而是初始化和边界条件出错。比如编辑距离问题里dp[0][j] j和dp[i][0] i这两个初始条件分别表示空串到另一个串的编辑距离就是另一个串的长度。如果漏掉或写错整个dp表都会错。3.4 贪心算法与排序的代码实现贪心算法也是笔试常考的题型。经典的题目包括区间调度、跳跃游戏、分发饼干等。贪心的难点在于如何证明贪心策略是正确的。这个证明在笔试中不需要写出来但如果你自己不确定就很容易写出一个“看起来对但实际有反例”的算法。排序算法这块面试官不太会直接考“快排怎么写”而是会考排序算法的稳定性、时间复杂度和空间复杂度对比或者让你在特定场景下选择最合适的排序算法。比如排序算法平均时间复杂度最坏时间复杂度空间复杂度稳定性冒泡排序O(n^2)O(n^2)O(1)稳定快速排序O(n log n)O(n^2)O(log n)不稳定归并排序O(n log n)O(n log n)O(n)稳定堆排序O(n log n)O(n log n)O(1)不稳定为什么快排是不稳定的因为它基于partition操作交换元素时可能改变相等元素的相对顺序。为什么归并排序稳定因为合并两个有序数组时当左右两边的元素相等我们总可以先把左边的元素放入结果数组从而保持稳定性。这些细节都是选择题的素材。我在笔试时遇到过一个场景题已知系统内存有限需要对一个大文件中的记录进行外部排序你会选择什么排序思路答案是归并排序因为它是稳定的并且天然适合外部排序可以分块读入内存排好序后再做多路归并。这个答案如果你只背过“归并排序时间复杂度O(n log n)”是答不出来的需要你对排序算法的特点和实际应用场景有感知。4. 一道概率题的手推全过程与易错点复盘笔试里有一道经典概率题我印象特别深它看起来很基础但每年都有很多人栽在这里。题目大概是某事件发生的概率为p重复独立试验n次求事件发生次数不少于k次的概率。这题本质上是二项分布的累积概率计算但笔试经常会变形比如加一个“至少发生一次”或“恰好发生两次”的条件。我遇到的一个变形题是这样的小明每天上班有两条路可以选A路遇到红灯的概率是0.2B路遇到红灯的概率是0.4。如果小明随机选路某天他遇到了红灯问他走的是A路的概率是多少这题的考点是贝叶斯公式。设事件R为“遇到红灯”事件A为“走A路”事件B为“走B路”。已知P(A)P(B)0.5P(R|A)0.2P(R|B)0.4。要求P(A|R)。根据贝叶斯公式P(A|R) P(R|A)P(A) / [P(R|A)P(A) P(R|B)P(B)] (0.2 * 0.5) / (0.2 * 0.5 0.4 * 0.5) 0.1 / 0.3 ≈ 0.3333所以答案是约33.3%。很多人会不假思索地选“0.2”因为觉得A路遇到红灯的概率是0.2但他忘了这是一个条件概率的逆向求解问题。这题在笔试里出现时选项大概率会设置0.2、0.33、0.4、0.5这几个干扰项专门考察学生对贝叶斯公式的掌握程度。再补充一个类似的易错点题目如果问“已知他遇到了红灯求他走A路且遇到红灯的概率”。这个表述和上面是不同的“走A路且遇到红灯”是联合概率P(A∩R)用乘法公式可以求出0.5 * 0.2 0.1但“遇到了红灯条件下走的是A路”是条件概率P(A|R)值是1/3。笔试时一定要仔细读题区分“且”和“条件下”这两个词。概率题的复习建议是把全概率公式、贝叶斯公式、常见分布的性质都自己在纸上推导一遍然后把常见的变型题做熟。尤其是二项分布和泊松分布的关系——当n很大p很小时二项分布可以用泊松分布近似这个结论在选择题里也经常出现。5. 备考路线与时间分配一个月冲刺方案最后这部分我想结合自己和身边同学的备考经验给一份适合大多数人的时间规划。如果你是距离笔试还有一个月左右的在校生可以参考这个节奏来安排核心原则是“基础优先、推导为主、代码为辅”。第一周集中火力过基础概念。把逻辑回归、SVM、决策树、朴素贝叶斯、K-Means、PCA这六个模型吃透每个模型都要能回答三个问题模型解决什么问题损失函数/目标函数是什么怎么优化/推导同时把条件概率、贝叶斯公式、极大似然估计的高频题型做一遍。第二周主攻手推题和计算题。找往年的笔试题和面经把逻辑回归的梯度推导、SVM的对偶问题推导、朴素贝叶斯的分类计算、信息增益和基尼指数的计算全部手推一遍。不要只在脑子里过一定要在纸上写出来。因为你以为你会的一写可能就卡住了。第三周编程题强化。按“字符串KMP、滑动窗口→动态规划背包、LIS、编辑距离→贪心→排序”这个顺序刷题每天保持两到三道编程题的节奏。重点是亲手写完并跑通而不是“看懂思路”。如果时间充裕可以再刷一遍“Top K问题”和“并查集”相关的题目这些都是大厂笔试的高频考点。第四周全真模拟。找一套完整的往年笔试题目卡着时间做一遍模拟真实笔试的节奏。做完之后不管对错认认真真复盘一遍把每个错题的知识点对应到具体章节做针对性补漏。这时候如果发现某个知识点还是很模糊不要犹豫立刻回去看书重推一遍。笔试前一周再把自己手推过的公式和推导过程快速过一遍保持手感。还有一个小技巧笔试开始前把常用的排序算法、KMP的next数组求法、DP的经典模板代码在编辑器里快速写一遍相当于“热身”。这不仅帮你进入状态还能避免一上来就手生。我这里分享一个真实踩过的坑第一次参加笔试时我在一道编程题上卡了太久导致后面的简答题没时间写最后挂了。第二次我学乖了做题顺序调整为先做简答和选择再回头做编程题。因为简答题只要你写了多少能拿步骤分而编程题如果思路不对可能一分都没有。根据个人情况合理安排做题顺序也是笔试中很重要的策略。不管怎么说笔试只是一道门槛过线之后还有面试。但只要你在笔试阶段把模型推导、概率计算、代码实现这三块基础打扎实了后面的面试你也会自信很多。如果这篇文章能帮你在备考路上少走一点弯路那就值得了。