
说实话算法岗的校招笔试每年题目都在换但考察的内核从来没变过。我见过太多同学死磕“难题偏题”结果在基础算法上翻了车也见过不少刷题量很大、但一考到原理分析就卡壳的候选人。这篇东西不是给你罗列题目答案而是想借一批校招算法方向笔试中反复出现的核心考点把算法岗笔试到底在考什么、怎么准备、踩过哪些坑一次讲清楚。不管你是正在准备秋招的应届生还是打算转行做算法的工程师这篇文章都适用。我会先从考察版图说起再把热搜里出现频率极高的几个算法KMP、粒子群、BM25、模拟退火、卡尔曼滤波等逐个拆开最后聊一聊备战节奏和实战技巧。1. 校招算法岗笔试的考察版图光会刷题远远不够1.1 数据结构与算法基础笔试的硬通货算法岗笔试的第一关永远是数据结构与算法。数组、链表、栈、队列、树、图、字符串这些基础数据结构的基本操作必须烂熟于心。排序算法、查找算法、动态规划、贪心、回溯、分治这些经典算法思想更是考察的重中之重。以我这些年看到的笔试题目分布来看各家公司比例略有不同但大体上可以分成三块数据结构题约30%多为链表操作、二叉树遍历、堆的使用、并查集等重点考察对数据结构特性的理解程度。经典算法题约40%排序、二分、DP、贪心、图论算法等考察建模能力和算法设计能力。综合应用题约30%通常给一个业务场景让你抽象成算法问题并求解考察的是把实际问题转化为算法问题的能力。很多人以为算法岗笔试最难的是“最后一题”实际上通过率最低的往往是中间那道“看起来不难”的基础题。原因很简单基础题要求你在短时间内写出无 bug 的代码一旦有个边界条件没处理好整道题可能就废了。1.2 机器学习与数学基础算法岗面试的第二道关卡与纯开发岗不同算法岗笔试里还有相当一部分机器学习相关的内容。这部分的考察方式通常是概念题、推导题或者给你一个场景让你选择合适模型。常见考点包括经典机器学习模型线性回归、逻辑回归、SVM、决策树、随机森林、GBDT、XGBoost等聚类算法K-Means、DBSCAN、层次聚类等降维算法PCA、LDA等概率统计基础贝叶斯、最大似然估计、假设检验等最优化方法梯度下降及其变体、牛顿法、拟牛顿法等这些内容的考察重点不是“会不会调包”而是“懂不懂原理”。比如问到逻辑回归就一定要能说出它的损失函数、梯度推导过程、正则化方式、为什么用交叉熵而不是均方误差。问到SVM就得能画出支持向量的图、理解核函数的作用。数学基础同样不能忽视。线性代数里的矩阵运算、特征值分解、奇异值分解概率论里的常见分布、期望方差、条件概率微积分里的偏导数、梯度、拉格朗日乘子法这些都是算法工程师的日常工具。1.3 编程语言与工程能力代码写得“漂亮”也很重要很多候选人算法思路完全正确代码却写得一塌糊涂。笔试环节对代码质量的要求其实被很多人低估了。我在批改笔试代码时比较看重几点变量命名是否清晰有没有用 a、b、c、tmp 这种毫无信息量的名字代码结构是否合理有没有把核心逻辑堆在一个巨型函数里边界条件是否考虑完整比如空数组、单元素数组、溢出情况复杂度是否说明清楚最好能主动分析时间复杂度和空间复杂度算法岗最终是要写生产代码的所以笔试中代码的工程规范性往往被当作判断候选人工程素养的重要信号。哪怕时间紧张也至少做到结构清晰、命名规范、缩进统一这比多写一个功能还重要。2. KMP算法的next数组一道题区分“背模板”和“真懂串匹配”2.1 以模式串“abacaba”为例手算next数组全过程热搜里出现了这样一道题目对于模式串 pabacaba其 next 数组是多少next[i] 定义为...。这类题目在笔试里出现的频率非常高因为它考察的不是“会不会写KMP代码”而是“是否真正理解前缀后缀与失配跳转”。很多同学到现在还在背上一种next数组的模板换个定义就懵了。我建议还是从根本上理解推导过程。先明确一种常见定义next[i] 表示模式串前 i 个字符组成的子串中最长相等真前后缀的长度。所谓“真前后缀”就是前缀和后缀都不能等于整个子串本身。以 p abacaba 为例下标从 0 开始i子串 p[0..i-1]最长相等真前后缀next[i]0无-1约定1a无真前后缀为空02ab无03abaa14abac无05abacaa16abacabab27abacabaaba3所以这一定义下next 数组为 [-1, 0, 0, 1, 0, 1, 2, 3]。我来手动演示推导过程i3子串是 aba。前缀有 a、ab后缀有 ba、a。相等且最长的是 a长度1所以 next[3]1。i6子串是 abacab。前缀有 a、ab、aba、abac、abaca后缀有 b、ab、cab、acab、bacab。相等且最长的是 ab长度2所以 next[6]2。i7子串是 abacaba。前缀有 a、ab、aba、abac、abaca、abacab后缀有 a、ba、aba、caba、acaba、bacaba。相等且最长的是 aba长度3所以 next[7]3。这个过程手工算不算难难的是在考场上快速、不遗漏。我一般会先写下所有前缀再对所有后缀然后从最长往最短比对这样效率最高、也最不容易错。2.2 next数组的不同定义与失配跳转很多同学看KMP的next数组容易蒙圈是因为不同教材、不同代码里next[i] 的定义不一样。常见的至少有三种定义一前面用的next[i] 表示前 i 个字符的最长相等真前后缀长度。定义二next[i] 表示当第 i 个字符失配时模式串指针应该跳转到的位置。此时 next[i] 与前缀长度有关且值通常等于定义一中的 next[i]部分实现中加一或减一。定义三next[i] 表示以第 i 个字符结尾的子串的最长相等真前后缀长度这时数组下标含义与定义一不同。笔试时如果题目明确写了“next[i] 定义为”就按题目定义来做。如果没有明确最好在回答时先说清楚自己的定义再给出计算结果。这既说明你真的懂也能避免答案与出题人预期不一致。我自己在笔试和面试时习惯先说一句“我按 next[i] 表示前 i 个字符最长相等真前后缀长度的定义来算”然后再开始计算整个过程就非常清晰。这个习惯建议大家都养成。2.3 KMP笔试常见变形不只是求next数组真正有区分度的题目往往不会只让你算一个next数组而是会结合匹配过程、复杂度分析一起考。常见变形包括给一个文本串和模式串手写KMP匹配全过程写出每一趟比较的位置和失配时的跳转。问KMP算法的时间复杂度为什么是 O(nm)。关键在于每个位置至多回溯一次指针不回退。问能不能用KMP统计模式串在文本串中出现的次数以及如何避免重叠计数。把next数组改成nextval数组优化版让你比较两者的区别并手算nextval。nextval数组的优化点在于当 next[i] 指向的字符与当前字符相同时跳转后还是会失配不如直接跳到 next[next[i]]。这个优化在模式串中有大量重复字符时收益明显。如果备考时间有限KMP这块建议大家把“手工计算next/nextval”和“代码实现”都亲自过一遍因为笔试手写代码环节KMP是高频题背模板而不懂原理的话稍微变形就露馅。3. 从热搜词反推高频考点粒子群、BM25、模拟退火与卡尔曼滤波3.1 粒子群算法PSO从鸟群觅食到参数寻优粒子群算法Particle Swarm Optimization是热搜里排名很靠前的一个词也是笔试面试中常被问到的群体智能优化算法。它模拟的是鸟群觅食行为每只鸟粒子在搜索空间中飞行既受自身历史最优位置影响也受群体历史最优位置影响逐步向最优解靠近。每个粒子用两个基本属性描述位置 x 和速度 v。迭代公式为v w * v c1 * r1 * (pbest - x) c2 * r2 * (gbest - x)x x v其中w 是惯性权重平衡全局搜索与局部开发能力c1 是自我认知系数c2 是社会认知系数r1、r2 是[0,1]之间的随机数pbest 是粒子自身历史最优位置gbest 是整个种群的历史最优位置笔试中常见的问题是惯性权重 w 的作用是什么如果 w 过大或过小会怎样答案是 w 越大粒子保持原有运动趋势的能力越强全局搜索能力越强但收敛可能变慢w 过小则容易陷入局部最优。实践里常用的做法是从 0.9 线性递减到 0.4前期多探索、后期多收敛。我见过不少笔试题目会结合具体业务场景考PSO比如“用粒子群算法优化SVM的两个惩罚参数C和gamma设计一个方案”。这时候不要把重点放在粒子群公式背诵上而要展示完整的优化流程定义适应度函数比如交叉验证准确率→ 初始化粒子群 → 迭代更新 → 输出最优参数。这能反映出你理解算法如何解决实际问题。3.2 检索和排序中避不开的BM25BM25是信息检索领域经典的相关性排序算法也是现代搜索引擎、推荐系统里用于“召回排序”的基础算法。热搜词里有BM25算法说明这个东西在校招笔试和面试中被提及的频率越来越高尤其是内容推荐、搜索方向的技术岗。BM25的核心思想是对于一个查询 Q 和一篇文档 D计算两者之间的相关性分数。分数由查询词在文档中的出现情况决定涉及三个关键因素词频TF词在文档中出现次数越多相关性越高但边际收益递减。逆文档频率IDF词越罕见携带的信息量越大。文档长度归一化文档越长词频的自然放大效应越需要抑制。BM25的公式通常写成score(D, Q) Σ IDF(qi) * [ tf(qi, D) * (k1 1) ] / [ tf(qi, D) k1 * (1 - b b * |D| / avgdl) ]其中k1 控制词频饱和程度一般取 1.2 到 2.0b 控制文档长度归一化的强度一般取 0.75|D| 是文档长度avgdl 是语料库平均文档长度笔试里最常见的考法是给你一个简单的文档集合让你手算查询词与两个文档的BM25分数比较哪个文档更相关。这类题算起来并不难但要注意 IDF 到底怎么算。有的定义是 IDF ln((N - n 0.5) / (n 0.5) 1)有的版本没有后面的 1计算结果会有差异。做题时先确认公式版本这很重要。我记得有一次面试面试官问我“BM25和TF-IDF相比本质区别是什么”我当时回答的核心点是TF-IDF中词频是线性增长的而BM25引入了词频饱和机制让同一词出现10次和出现20次之间的相关性差距不再线性放大。这在实际搜索场景里非常有意义。回答完面试官明显比较满意。3.3 模拟退火Metropolis准则到底在干什么模拟退火Simulated Annealing是一种受金属退火过程启发的随机优化算法经常和粒子群、遗传算法一起出现在“智能优化算法”的考察范围里。算法的核心关键是 Metropolis 准则当新解比当前解更优时一定接受当新解更差时以一定概率接受这个概率随温度降低而减小。P exp(-ΔE / T)其中 ΔE 是新旧解的差值能量差T 是当前温度。为什么“差解”还要以概率接受因为在复杂优化问题中局部最优到处都是如果只接受更优解算法很容易困在局部最优里出不来。模拟退火通过在高温阶段接受差解让搜索过程有机会跳出局部最优再通过缓慢降温逐步收敛到全局最优附近。笔试里常见的题有几种手写模拟退火的核心伪代码解释为什么降温速率不能太快给一个具体函数用模拟退火找最小值的过程比较模拟退火与贪心算法的核心区别其实模拟退火的代码并不复杂核心就是三层循环外层控制温度下降中层控制每个温度下的迭代次数内层生成新解并判断是否接受。不少同学在笔试时写不出来往往是没理解“退火”这个物理过程与算法步骤之间的对应关系。理解了对应关系代码自然就流畅了。3.4 卡尔曼滤波状态估计的“预测-更新”框架卡尔曼滤波是信号处理、导航、无人机、自动驾驶等领域绕不开的经典算法。笔试中出现卡尔曼滤波通常不是要你背公式而是考察你是否理解“预测与更新”这个核心思想。卡尔曼滤波解决的核心问题是系统状态无法直接精确测量只能从带噪声的观测中估计。它用两个步骤循环迭代预测基于上一时刻的状态和控制量预测当前时刻的状态和协方差。更新结合预测结果与当前观测计算卡尔曼增益得到最优估计。卡尔曼增益 K 的直觉理解是如果观测噪声小就多相信观测如果过程噪声小就多相信预测。笔试中可能出现的考法包括解释卡尔曼滤波和普通低通滤波的区别。卡尔曼滤波是自适应地融合预测和观测而低通滤波只是固定权重地平滑。写出预测与更新的五个核心公式。讨论卡尔曼滤波的适用条件线性系统、高斯噪声。如果是非线性系统要用扩展卡尔曼滤波EKF或无迹卡尔曼滤波UKF。考到这类题时只要能清晰画出“预测-更新”的循环框架再把核心公式写出来就足够拿大部分分数了。4. 基础算法族的备战优先级排序、贪心、Dijkstra、堆与二分图4.1 排序算法能手写也能比较排序算法为什么在校招笔试里出现频率这么高不是因为工作里天天要手写排序而是因为排序是理解更复杂算法的基础也是考察候选人编码基本功的试金石。我建议至少能手写以下算法且能说清原理与复杂度快速排序平均 O(n log n)最坏 O(n^2)核心是分治与 partition。归并排序稳定 O(n log n)核心是先分后合需要额外 O(n) 空间。堆排序O(n log n)利用堆这种数据结构实现选择排序的优化。冒泡排序、插入排序、选择排序虽然效率低但手写概率极高不能出错。计数排序、基数排序线性排序考察对“非比较排序”的理解。笔试中常见的进阶题是给一个特殊数据分布让你选择最优排序方案。比如数据范围很小但有大量重复时计数排序可能是最优解数据基本有序时插入排序比快排更高效。这类问题的核心是理解不同排序算法的特性和适用场景。我自己的经验是快排一定要熟练到“闭眼能写”的程度并且 partition 用哪种方案Lomuto 还是 Hoare也要心里有数因为两种方案在等值元素较多的场景下表现差异很大。笔试中如果题目没有特殊要求用最常见的形式就好别在非关键处炫技。4.2 贪心算法什么时候贪什么时候不能贪贪心算法在笔试里的出镜率非常高因为它的代码通常很短但正确性证明才是真正的难点。贪心算法的思想很直白每步都做当前看起来最优的选择希望通过局部最优得到全局最优。但并非所有问题都适用贪心只有满足“贪心选择性质”和“最优子结构”的问题才可以使用。笔试中常见的贪心题包括活动选择问题区间调度分发饼干跳跃游戏加油站问题哈夫曼编码最容易翻车的地方是想当然地贪心错把不适合贪心的问题当成贪心来做。比如找零问题在特定面额组合下贪心是错的。好在这类例子在多数字典和刷题平台都能刷到考前过一遍能起很大作用。我的做题习惯是拿到一道题先不急着写代码先想“如果每一步都做局部最优最后能得到全局最优吗”如果能给出一个直观的证明思路再动手如果发现局部最优与全局最优可能存在矛盾就改用动态规划或搜索。这个判断过程本身就是笔试要考察的能力。4.3 Dijkstra与图论最短路的多种考法Dijkstra算法是图论题里最常考的最短路算法之一。很多人在准备阶段刷过它的模板题但一上考场题目往往不会直接说“求最短路”而是把最短路问题隐藏在某个场景里。Dijkstra算法有个重要前提边权不能为负。原因是算法基于贪心策略每次选择当前距离最近的未访问节点一旦边权为负已经确定的最近距离可能被后来发现的负权边更新贪心就失效了。笔试里常见的变形包括求网格地图中最短路径同时存在障碍物给一个图求从某点到所有点的最短距离并要求输出路径求次短路公交线路换乘问题边权建模为换乘次数关于实现方式常见的有朴素版本 O(V^2) 和优先队列优化版 O((VE)logV)。一般笔试时直接用优先队列优化版也就是 Dijkstra 堆代码并不长。热词里也有“堆排序”“Dijkstra算法”同屏出现说明这两者经常被放到一起考察因为堆正是Dijkstra优化的核心工具。有一年我帮朋友模拟面试出了一个看似是BFS的网格题其实由于每一步的代价不同必须用Dijkstra才能解。候选人一开始就用BFS来写写着写着才发现问题浪费了大量时间。这个教训值得记住凡是求“最小代价路径”且“代价不是均匀1”的问题优先考虑Dijkstra而不是BFS。4.4 二分图最大匹配与HK算法图论里的进阶考点热搜里出现了“二分图 hk算法”可能不少同学不熟悉我简单说下它是什么。HK算法Hopcroft-Karp算法是求解二分图最大匹配的经典算法是匈牙利算法Hungarian Algorithm也叫Kuhn-Munkres算法的进阶版本。我在这里说的匈牙利算法是指图论中求最大匹配的算法与“匈牙利命名法”无关校招笔试中出现的也是这一算法。二分图最大匹配问题的核心场景是把两类对象进行配对每个对象只能配对一次求最多能配成多少对。比如“员工与岗位的匹配”“课程与教室的分配”等。基本解法是增广路算法而HK算法通过同时寻找多条不相交增广路将复杂度从 O(VE) 优化到 O(E√V)适合边数较多的图。笔试中很多同学连“构建二分图模型”这一步都想不到所以在复习时建议把常见的建模套路过一遍哪些问题本质上可以抽象成二分图匹配最典型的是“两个集合之间有限制条件的配对问题”。如果时间紧张至少要掌握匈牙利算法的递归实现HK算法能做出来更好。在面试中能够分析出“这个题是二分图最大匹配”本身就已经很加分了。5. 工程细节题哈希、正则、Rete与SSH算法协商这类“非典型”考点5.1 哈希表与弱哈希从工程角度看算法算法岗笔试不全是纯算法题还有相当多的工程细节题。哈希表是其中出现频率极高的一块。常见的考法有哈希表的底层实现原理数组加链表/红黑树扩容机制负载因子。哈希冲突的解决办法链地址法、开放地址法、再哈希法。如何设计一个高效的哈希函数。弱哈希算法的识别与修复思路。关于弱哈希热搜里有一句“SSL 证书使用了弱 hash 算法怎么修复”这其实是一个工程安全题。简单说某些旧版证书签名算法如 SHA-1被业界认为强度不足需要迁移到更强的签名算法。笔试中遇到这类题重点呈现“识别问题—评估影响—制定迁移方案—验证兼容性”的排查思路即可不需要深入到具体的加密实现。哈希表的性能分析也很重要。很多人只知道“哈希表查找是O(1)”但没想过最坏情况是O(n)——所有元素都冲突到同一个桶里时查找就退化成链表遍历。工程实现中通常通过良好的哈希函数和合理的负载因子来控制这种情况的发生概率。5.2 正则表达式与字符串处理笔试里的“送分题”也可能丢分正则表达式在算法岗笔试中并不少见尤其是涉及日志解析、文本清洗、URL解析等业务场景时。考法主要有两种一是给出一个正则让你说出匹配哪些字符串二是让你写一个正则完成特定提取要求。很多人觉得正则是“背符号”不需要专门准备结果一上考场就挂在细节上。比如贪婪匹配与懒惰匹配的区别分组与捕获非捕获分组 (?:)零宽断言lookahead / lookbehind回溯对性能的影响以及如何避免灾难性回溯我见过一道题给定一段日志文本要求提取所有“时间戳错误码”的组合。候选人正则写了半天要么匹配范围过大要么漏掉了边界情况。正确的做法是先把日志格式拆解成结构化字段再针对每个字段写正则最后拼起来整体验证而不是一上来就写一个超长正则。5.3 规则引擎的Rete算法知识工程领域的常客“规则引擎drools的rete算法实现原理和事实匹配过程”这个热搜词有点冷门但在某些偏业务策略的算法岗笔试中真的会出现。Rete算法是规则引擎如Drools背后的核心匹配算法它解决的问题是当大量规则和大量事实同时存在时如何高效地找到所有被满足的规则。Rete算法的核心思想可以概括为两点共享子条件不同规则的相同条件部分只计算一次。状态缓存把匹配过程的中间结果保存下来事实变化时只做增量更新而不是全量重新匹配。面试中如果被问到能够讲清楚这两个思想基本上就够了。笔试中如果涉及通常会给一个简单规则集让你画出Rete网络的匹配过程。我建议备考时不要把Rete当成一个复杂算法去啃而是把它理解成一个“用空间换时间的匹配缓存系统”。这样无论题目怎么变核心思想都能答出来。5.4 SSH算法协商失败的排查思路运维场景里的“算法不匹配”“xshell找不到匹配的host key算法”这个热搜词本质上是一个工程问题客户端与服务器在进行安全连接时双方的算法列表取不到交集导致握手失败。这个问题的排查思路其实非常值得学习因为它体现了一种通用的问题解决框架确认报错信息明确是密钥交换算法、主机密钥算法还是加密算法的问题。查看客户端支持的算法列表和服务端配置的算法列表。找到交集为空的具体原因通常是服务端OpenSSH版本过老或过新导致某些算法被禁用。选择解决方案升级服务端组件或调整客户端算法配置让双方找到共同接受的算法。验证连接是否恢复并记录后续需要注意的兼容性事项。这类问题在校招笔试里出现通常不是考具体命令而是考你“看到算法不匹配时知道从哪个方向排查”的工程思维。这也是算法岗区别于纯研究岗的地方不仅要知道算法原理还要能在真实系统中定位和解决问题。6. 备战时间线、模拟笔试与考场上的实战技巧6.1 三个月备战节奏基础→专题→模拟以一秋招提前批的时间线来看我建议备考周期至少三个月。太短则基础不牢太长则容易疲惫且遗忘。第一个月夯实算法基本功。把数据结构教材或精品在线课程从头到尾过一遍配合刷题网站上对应专题的题目做到每个主题至少30道题。这个阶段不追求速度追求“做一道会一类”。第二个月专题强化与原理复习。按照“动态规划”“图论”“字符串”“机器学习”等专题集中突破同时把简历上写过的项目里的算法原理全部整理成文档确保能从头推导。第三个月模拟笔试与总结复盘。每周至少安排两次完整的限时模拟笔试题目难度要贴近目标公司真实水平。做完后认真复盘哪些题卡住了为什么卡住是思路问题、代码问题还是时间分配问题。6.2 限时模拟笔试的策略先易后难及时止损真正参加笔试时最怕的不是题目难而是时间分配不合理。我见过太多次候选人死磕一道难题导致后面三道简单题都没时间做最终成绩惨淡。合理的策略是拿到试卷后先把所有题目快速扫一遍对难度有个大致判断。先做自己有把握的题保证基础分拿到手。对没思路的题先标记完成其他题目后再回来。每一道题都设置一个“止损时间”比如15分钟没有实质性进展就果断放弃。笔试本质上是“在有限时间内拿尽可能多的分”不是“把所有题都解出来”。这个观念要尽早建立。6.3 现场手写代码的规范别让细节拖你后腿笔试现场写代码和平时在IDE里写代码是两回事。没有代码补全、没有调试器、甚至可能没有语法高亮一旦开始写就要尽量一次写对。几个实用的习惯先写注释写明函数输入输出与核心逻辑。既帮自己理清思路也能让阅读代码的人快速理解。使用有意义的变量名避免 a、b、c、tmp。写完立刻做边界测试空输入、单元素输入、最大输入、重复元素、负值等。如果一个方法复杂度太高会在题目要求范围内超时及时换思路不要在错误方向上补丁叠补丁。关于代码风格还有一个容易被忽略的点如果你的解法包含多个步骤把它们拆成有语义的小函数而不是全部堆在 main 里。这样既清晰也方便后续修改。6.4 我的个人复盘方法错题本加考点图谱最后分享一个我在备考和带人过程中验证过很多次的方法建立自己的“考点图谱”。做法很简单把遇到的每一道题按“考点题型难度关键思路”四个维度记录成一个表格。一段时间后你会发现自己最薄弱的几个考点非常集中接下来就可以有针对性地专项补齐。这个表格不需要做得多花哨一个在线表格就行。我自己当年是按“数组”“字符串”“树”“图”“动态规划”“机器学习”六大类分的每一类下面再细分。每个月末过一遍图谱把已经掌握的知识点标记为绿色模糊的标记为黄色完全不懂的标记为红色。复习的时候就盯着黄色和红色区域效率比从头到尾再过一遍高出很多。笔试不是终点而是第一道筛选器。真正能走到面试环节的人靠的不是运气而是扎实的基础、清晰的思路和稳定的临场发挥。希望这篇东西能帮你少走一些我走过的弯路。