如果你正在准备算法岗校招,或者已经在刷题软件里泡了三个月,应该会好奇:2020年小米算法工程师笔试到底考了什么?这份"笔试题二"流传得挺广,但二手消息散得到处都是,很少有人把它掰开揉碎讲清楚。我整理了不少当时参加笔试的同学的回忆,也对照过能查到的题干,把这份卷子从头到尾捋了一遍。它不只是一张试卷,更像是一份挂在算法工程师门口的能力清单——数据结构、机器学习、图像处理、工程优化,每一道题都在悄悄问一个问题:你是真的理解这个算法,还是只会套模板?这篇文章就按题型维度拆开讲,该补的原理、该避的坑、该记的结论,一次说清楚。
1. 先说清楚:这份试卷到底在考什么
1.1 从"笔试题二"这个编号能读出什么
很多人忽略了一个信息:试题编号里带个"二",说明这不是唯一一套卷子。小米校招的算法岗笔试会按投递方向拆成多套题,比如计算机视觉方向、机器学习方向、大数据方向各有侧重。你拿到哪一套,很大程度上取决于内推时填的岗位意向。
"笔试题二"大概率对应的是通用型算法工程师岗位,不偏向某个具体的业务线。这类岗位对候选人的要求很明确:基础扎实、覆盖面广、能在工程和模型之间找到平衡点。所以你会发现这套题里既有KMP算法、排序、图论这些经典数据结构问题,也掺着机器学习、深度学习的概念题,甚至会冒出来PID、卡尔曼滤波这类信号控制领域的算法术语。
我当时在备考阶段犯过一个错误:只盯着深度学习框架和模型结构看,觉得笔试一定是问Transformer、问CNN。结果做了几套大厂真题后发现,算法岗笔试真正爱考的反而是那些"看起来基础、但多数人答不完整"的东西。基础算法题占了三分之一以上的分值,而且全部是待编码或待推导的硬核内容,没有半点水分。
1.2 算法岗笔试的"三重筛选"逻辑
如果把面试理解为"看这个人能不能聊",那笔试就是在"看这个人能不能做"。算法岗笔试的设计者通常带着三个目的出题。
第一重是筛选代码能力。能不能在有限时间内把思路转成运行正确的代码,这是工程师的基本功。第二重是筛选理论深度。关键算法不能只会调用API,原理推导、复杂度分析、适用边界都要有概念。第三重是筛选场景迁移能力。同样的排序思想,放到海量数据里怎么优化;同样的搜索算法,放到推荐系统里怎么变体应用。这三重逻辑贯穿整张试卷,理解了这个,你就知道为什么有些题目看起来和"算法工程师"的日常工作没什么直接关系,但就是年年都考。
网上那些堆砌"面经"的帖子往往只告诉你题目,不讲背后的出题意图。我的建议是反过来:先搞清楚某类题目为什么被反复考,再去做题,效率会高很多。
2. 数据结构与基础算法:那些"送分题"为什么总有人丢分
2.1 KMP的next数组:题目都见过,但定义一改就懵
这套卷子里有一道流传度很高的题,题干是:在KMP算法中,对于模式串 p="abacaba",其 next 数组(next[i]定义为……)是多少?
很多人在网上看到过这道题的回忆版,但答案五花八门。原因很简单——KMP的next数组存在多种定义方式,不同教材、不同博客对"next[i]代表什么"这个问题的口径不统一。真题里一旦把定义写清楚,你要做的就是从定义出发重新计算,而不是默背一个标准答案。
我按最常见的定义来推一遍:next[i] 表示模式串前 i 个字符组成的子串中,最长相等前缀后缀的长度(也就是前缀函数),并约定 next[0] = -1。
p = "abacaba",我们逐个位置算:
- i = 0:按约定 next[0] = -1。
- i = 1:考虑前1个字符"a",长度为1的字符串没有真前缀和真后缀,所以最长相等前后缀长度为0,next[1] = 0。
- i = 2:前2个字符"ab",前缀有"a",后缀有"b",不相等,next[2] = 0。
- i = 3:前3个字符"aba",前缀"a"和后缀"a"相等,长度为1;再看前缀"ab"和后缀"ba",不相等。所以 next[3] = 1。
- i = 4:前4个字符"abac",按同样方法检查,没有任何一组相等前后缀,next[4] = 0。
- i = 5:前5个字符"abaca",前缀"a"和后缀"a"相等,长度为1;前缀"ab"和后缀"ca"不等。next[5] = 1。
- i = 6:前6个字符"abacab",后缀最后一个字符是"b",单字符后缀"b"和前缀"a"不等;两字符后缀"ab"和前缀"ab"相等,长度是2。所以 next[6] = 2。
最终结果:next = [-1, 0, 0, 1, 0, 1, 2]。
如果题目里换一种定义,比如"当第 i 个字符失配时,模式串指针应该跳转到的位置",得到的数组就完全不同。这也是这类题的高频丢分点。我的建议是:看到题目先别急着算,花10秒确认定义和下标起始位置,这两种口径下结果是两套东西。
2.2 排序与堆:笔试里的"基础弹药"
数据结构与算法模块里,排序和堆排序基本是必考领域。这套卷子相关的回忆里,出现了堆排序算法、快速排序、快速幂算法等关键词。
以堆排序为例,笔试爱考的不只是"你能写出来",而是三个细节:建堆过程的时间复杂度、排序过程中调整堆的次数、以及稳定性。堆排序的时间复杂度是O(n log n),建堆的复杂度是O(n)(很多人会误写为O(n log n),这是面试官特别喜欢引导你追问的点)。它是不稳定排序,因为堆调整过程会打乱相同元素的相对顺序。
快速排序的考点则更偏向"最坏情况"和"优化策略"。经典快排在近乎有序的数组上会退化成O(n^2),所以实际工程里会用随机化选主元或者三数取中法来规避。笔试里经常会给一个具体的输入序列,让你模拟一趟划分过程,这比默写代码更能看出你是不是真正理解了Partition的逻辑。
快速幂算法是另一个高频考点,因为它把"计算 a^b mod p"这类问题的时间复杂度从O(b)降到了O(log b)。核心思想是"指数二进制展开 + 分治",可以拿来做矩阵快速幂、斐波那契数列优化的前置知识点。这类题代码量不大,但边界条件很容易出错,比如指数为0、模数为1的情况,稍不留神就爆掉。
2.3 Dijkstra、贪心与图论:理解比背板更重要
图论部分在算法岗笔试里出现的频率相当高。从热搜词里能看到 Dijkstra 算法、二分图 HK 算法、Kahn 算法这些关键词,恰好对应了最短路径、二分图最大匹配、拓扑排序三个经典问题。
Dijkstra 算法是每年的"老熟人",但它有个最重要的前置条件:不能处理带负权边的图。为什么?因为 Dijkstra 基于贪心策略,每次从当前未确定最短路的节点中选一个距离最小的进行松弛,一旦存在负权边,"当前距离最小"这个结论就不再成立。笔试里如果给一个带负权边的图让你用 Dijkstra 求最短路,结果一定是错的;正确做法是用 Bellman-Ford 或 SPFA。
Kahn 算法是拓扑排序的经典解法,思路是"反复删除入度为0的节点,并更新邻居入度"。如果最终删除的节点数量不等于图中节点总数,说明图中存在环。很多实际场景题会从这里切入,比如课程安排、任务调度、依赖解析。
二分图 HK 算法(Hopcroft-Karp)相对冷门一些,但它是二分图最大匹配算法里效率较高的一种,时间复杂度O(E√V),比匈牙利算法的O(VE)在稠密图上要好不少。笔试题如果出现,一般不会让你完整实现,而是考察"为什么它能加速"——核心就在于每次寻找多条增广路径(通过BFS分层)然后一次性增广,而不是像匈牙利算法那样一条一条找。
贪心算法是另一个常见主题。贪心的难点不在于"实现",而在于"证明"。你得能说明为什么局部最优能推出全局最优。比如活动安排问题,按结束时间排序就是正确的贪心策略;但如果换一个题目背景,按开始时间排序就直接错了。面试官特别喜欢反着问:你换一种贪心策略,能不能推翻它?这比正向证明更能考查理解深度。
3. 机器学习与深度学习理论基础:概念题背后的"坑"
3.1 KNN的"三个方面"与聚类算法考点
热搜词里有一条非常具体的题目线索:KNN算法的应用能力包括哪三个方面。这属于典型的"背了概念但不一定答得全"的题。
KNN(K近邻)的三个应用能力分别是:分类、回归和密度估计。分类时通过K个近邻投票决定类别;回归时通过K个近邻的均值或加权均值预测数值;密度估计时可以借助K近邻的平均距离来估计样本局部分布密度,进而用于异常检测等场景。
出题人喜欢从"三个方面"这个角度出题,是因为很多人学KNN的时候只记住了"分类+回归",忽略了密度估计。但如果放到实际业务里,比如工业异常检测场景,KNN做密度估计来识别离群点是非常常见的思路。我在实际项目里用KNN做过一个告警日志的异常检测模块,效果比简单的阈值法稳得多,核心思想就是"正常样本的近邻距离小,异常样本的近邻距离大"。
聚类算法也是笔试重灾区。K-Means 的考点集中在几个点上:初始中心点选择的敏感性(可能收敛到局部最优)、K值怎么确定(肘部法则)、算法是否保证收敛(目标函数单调下降所以会收敛)、能否处理非球形簇(不能)。
出题人经常给一个"如果用K-Means聚类一个圆环形状的数据集"这种题,答案就是效果很差,因为它基于欧氏距离的簇分配策略对非凸簇无能为力。这时候应该选DBSCAN这类基于密度的聚类方法。
3.2 XGBoost与集成学习:从GBDT到XGBoost的推导线索
如果你是做算法岗,机器学习部分大概率逃不过集成学习。热搜词里出现了 XGBoost 和"KL ELBO 算法原理详解",这两者正好代表了机器学习的两个出题方向:传统集成模型和概率图模型。
XGBoost 为什么比 GBDT 强?这是最常问的题。回答的时候要有层次:第一,XGBoost 在目标函数里加入了正则项(叶子节点数和叶子权重的L2范数),从工程和理论上抑制过拟合;第二,它用二阶泰勒展开近似损失函数,比GBDT只用一阶梯度信息更精确;第三,它在实现上做了特征子采样、列块存储、并行化等优化。
如果笔试只要求"说原理",答出上面这几点就够。但如果遇到推导题,你得能写出目标函数的变换过程:把损失函数展开到二阶,把样本遍历转换成叶子节点遍历,最后得到叶子节点最优权重和对应的增益公式。这类推导看起来繁琐,实际上套路固定,考前花两个小时专门练一遍,性价比很高。
3.3 概率图与变分推断:ELBO、KL散度为什么总被考
"KL ELBO 算法原理详解"出现在热搜词里,说明这套卷子很可能涉及变分推断相关概念。这类题对很多同学来说是噩梦,因为学校课程里讲得少,工作中用到的人也不多,但它恰恰是大厂算法岗喜欢考的"区分度题"。
变分推断的核心思想是:当后验分布 p(z|x) 难以直接计算时,用一个简单的分布 q(z) 去近似它。做法是最大化证据下界 ELBO,因为:
log p(x) = ELBO + KL(q(z) || p(z|x))
KL散度永远≥0,所以ELBO是log p(x)的下界。当KL散度=0时,q(z)完全等于后验。但由于后验未知,KL散度算不了,转而最大化ELBO,得到了一个既能优化又可以让q逼近后验的目标函数。
笔试题如果到这里就结束了,那还算友好。麻烦的是出题人喜欢加一个"为什么选ELBO而不是直接最小化KL"的追问。答案在于:ELBO里只涉及联合分布 p(x,z) 和 q(z),这些都是可计算的,而KL散度里的后验分布恰恰不可算。所以我们在计算上做了一个"曲线救国"——想算的东西算不了,就去算一个等价目标。
强化学习算法、粒子群算法原理、模拟退火算法这些关键词在这份试卷的讨论里也被频繁提起。它们共同指向一个大类:在不确定环境或高维搜索空间里求解最优化问题。粒子群算法和模拟退火都属于元启发式优化算法,它们的共性是不依赖梯度信息,适用于目标函数不可导或者搜索空间非凸的场景。强化学习则可以理解为"带延迟奖励的序列决策优化",Q-learning和SARSA的区别(off-policy vs on-policy)是经常出现的基础题。
4. 综合场景题:当"算法"遇上"业务"
4.1 图像算法:拉普拉斯锐化和Sobel的考点真相
从热搜词来看,"图像锐化的拉普拉斯算法"和"Sobel算法"都是这类笔试题的常客。图像算法在通用算法岗笔试题里很少考端到端的深度学习模型,反而倾向于考经典数字图像处理,原因是经典算法原理清晰、代码量小、能快速看出候选人有没有图像处理的基本盘。
拉普拉斯算子是一个二阶微分算子。为什么它能做锐化?因为边缘处灰度变化激烈,二阶导数在边缘处会产生"零交叉"现象,拉普拉斯算子可以突出灰度的突变区域。常用的4邻域模板是:
0 1 0 1 -4 1 0 1 0锐化的公式通常是 g(x,y) = f(x,y) - c * ∇²f(x,y),其中c为正的系数。注意,这里到底是"减"还是"加",取决于模板中心是负值还是正值。如果用上面这个中心为-4的模板,就需要用"减去拉普拉斯结果"来得到锐化图像。如果模板中心是4(即整体取反),那锐化公式就变成"加上拉普拉斯结果"。这是笔试里特别容易搞反的点。
Sobel算子则是基于一阶导数的边缘检测算子,分横向和纵向两个方向:横向模板检测竖直方向的边缘,纵向模板检测水平方向的边缘。实际使用时常常将两个方向的梯度幅值合并,用近似公式 G = |Gx| + |Gy| 来加速计算。输出结果是梯度幅值图,梯度大的地方是边缘。
这类题出成编程题的话,一般的坑在边界处理。比如1x3的Sobel卷积核在图像边界处无法完整覆盖,那么边界像素是补零、复制还是忽略,直接影响输出结果。笔试题如果给了具体的图像矩阵和卷积核,务必看清楚边界处理规则再动手。
4.2 信号与控制类算法:卡尔曼滤波、PID、FOC、MPPT的工程指向
这套卷子的讨论里出现了"卡尔曼滤波算法""PID算法在CRPS PSU power中的作用""FOC算法""MPPT算法"等关键词,乍看像是电控岗位的题目,但通用算法岗笔试也会考它们的基本原理。
卡尔曼滤波是所有状态估计算法里出镜率最高的。它基于两个假设:系统模型是线性的,噪声服从高斯分布。核心流程分为两步:预测(根据上一时刻的后验状态预测当前先验状态和协方差)和更新(用当前观测更新后验估计)。笔试里如果让写公式,五个核心公式一个都不能少。
真实业务里,卡尔曼滤波最常见的应用是传感器融合。比如机器人定位,用IMU做短时间积分精度尚可但会漂移,用GPS做绝对定位但有噪声和延迟,卡尔曼滤波可以把两者融合起来,得到一个比任何单一传感器都平滑、都接近真实状态的估计。这道题如果在笔试中出成场景题,通常会让考生解释"为什么需要融合,而不是直接信任某个传感器"。
PID算法在电源管理(PSU)中的作用,核心是闭环反馈调节。比例项P快速响应误差,积分项I消除稳态误差,微分项D抑制超调和振荡。在CRPS(一种电源冗余规范)架构的PSU中,PID常用于电压环和电流环的控制,保证输出稳定。如果笔试问PID参数的调节规律,答题要点是:P过大会震荡,I过大会超调,D过大会放大噪声。
MPPT(最大功率点跟踪)常见于光伏逆变器场景,核心思路是让系统始终工作在输出功率最大的电压/电流点。扰动观察法会持续小步扰动工作点并观察功率变化方向,电导增量法通过比较瞬时电导和增量电导来判断最大功率点方向。
FOC(磁场定向控制)是电机控制里的主流算法,核心思想是把三相交流电机的电流解耦成直轴(d轴)和交轴(q轴)两个分量,让控制问题从"交流"变成"直流"问题,从而可以用类似直流电机的策略来控制交流电机。这类题对不搞嵌入式方向的候选人来说比较陌生,但掌握"解耦"这个核心思想就能回答大部分概念题。
4.3 检索与工程系统:BM25、Rete算法、音频重采样背后的"行业知识"
有些考点一看就是"业务倒推出来的题目"。BM25算法、规则引擎Drools的Rete算法、音频重采样算法这三组热搜词,分别对应搜索、规则引擎、音视频处理三条业务线。
BM25是文本检索领域非常经典的排序函数,广泛用于搜索引擎和推荐系统的召回阶段。它的核心思想:一个词在文档中出现的次数越多(TF越高),文档得分越高;但这个词如果在所有文档中出现得越频繁(DF越高),它对区分文档的贡献就越小,需要被IDF惩罚。同时它还引入了文档长度归一化,避免长文档天然得分高的问题。
笔试如果考BM25,一般不会要求手写完整公式,而是会问"为什么关键词出现次数不是越多越好"或者"为什么常见的词权重反而低"。所有信息检索的考点都是为了让候选人理解"稀有词比常见词更有区分力"这个核心直觉。
Rete算法是规则引擎(比如Drools)背后的匹配算法。为什么规则引擎会慢?因为每次事实变化时,如果重新匹配所有规则,代价很高。Rete算法的巧妙之处在于构建了一个模式匹配网络,利用节点共享和部分匹配结果的缓存,只对变更部分做增量计算。这是一种典型的"空间换时间"策略。
这个思想在工程上有很多延伸,比如复杂事件处理、实时风控规则匹配。笔试题如果出现Rete,想考察的往往不是算法本身,而是你有没有"用空间冗余换时间开销"这个工程意识。只要你能结合具体业务场景解释清楚,得分就低不了。
音频重采样算法在音视频处理中很常见,核心是把一个采样率下的音频数据转换为另一个采样率。最简单的实现是线性插值,但会产生频谱混叠和噪声。高质量的采样率转换通常需要结合低通滤波,先插值再抽取。笔试题一般不会要求实现完整算法,但会问"为什么48kHz音频转16kHz需要有抗混叠滤波"这类问题,答案是:如果不滤波,高于目标采样率奈奎斯特频率的成分会折叠回有效频带,导致音质急剧劣化。
5. 备考建议:从套题练习到能力沉淀
5.1 考场上时间怎么分
算法岗笔试的时间通常非常紧张,尤其当题目包含编程题和概念题时,"先把简单题拿满、再啃难题"的策略永远是最优解。
我的习惯是:拿到试卷先快速浏览所有题目,把题目分成三类——"马上能写的"、"需要推导的"、"完全不熟的"。第一类顺手就做掉,保证基础分;第二类按分值从高到低推进;第三类除非时间非常充裕,否则不要死磕,随便蒙一个基于直觉的答案都比空白交卷强。
编程题注意边界条件测试。写完之后花半分钟想一组极端输入跑一遍:空数组、只有一个元素、全部相等、数量极大。这一半分钟的收益可能比写一个小时的代码都高,很多笔试挂掉都是因为边界条件没过。
5.2 这类题怎么刷才能举一反三
备考算法岗笔试,光刷LeetCode远远不够。LeetCode主要练"算法实现能力",而校招笔试里大比例的"原理选择题"和"场景设计题"需要的是"算法理解能力"。
我的建议是把复习拆成三条线并行。第一条线是数据结构与算法基础,以LeetCode的中等题为主,但每做一道题都要反问自己:这个算法的时间复杂度怎么推导的?空间复杂度能不能优化?有没有更简单的替代方案?第二条线是机器学习/深度学习概念,找几篇高质量的技术博客,把KNN、SVM、决策树、XGBoost、Transformer背后的数学推导手推一遍。第三条线是业务场景题,去翻各个公司的面经,把常见的"工业异常检测怎么做""推荐系统召回策略有哪些"这类问题按自己的逻辑整理出答题框架。
这三条线缺一不可。只刷题不学理论,碰到原理题就懵;只学理论不刷题,编程题就是灾难。
5.3 心态与细节:笔试不只是正确率
最后说一点很多人忽略的事情:大厂校招笔试题这几年越来越难完全押中,更重要的是通过反复练习形成"算法直觉"。看到一个题,30秒内判断它属于哪一类、能用哪些算法解、约束条件是否支持O(n log n)复杂度——这种判断力只能靠大量实战慢慢养出来。
笔试并不是一锤子买卖。就算没有拿到满分,只要整体排名在一定的百分比以内,依然有机会进入面试。而面试官看笔试成绩的时候,更关注的是"这道题你答了但没有答完整"时暴露出来的思维过程。
我现在回过头看这套2020年的"笔试题二",其实考点分布和现在很多公司的算法岗笔试没有本质区别。核心永远是:基础算法的底层逻辑、机器学习模型的推导能力、以及把业务问题抽象成算法问题的迁移能力。把这三点吃透,不管题目怎么变,你都能稳住基本盘。