2020B站校招算法笔试卷复盘:从KMP到背包问题的高频考点全解析
2026/8/31 6:43:27 网站建设 项目流程

2020年我完整跟了一遍哔哩哔哩校园招聘算法岗的笔试卷,那套题给我的感觉是:它比纯互联网大厂的卷子更"杂",比传统软件公司的卷子更"活"。这背后其实和B站的内容生态有直接关系——一个以UGC视频、弹幕文化、社区互动为核心的平台,算法工程师面对的问题从来不是纯推荐或者纯搜索,而是内容理解、用户画像、分发策略、社区治理等多个维度同时上阵。所以这套算法笔试卷并不是单纯考你背了多少数据结构,而是看你在有限时间里能不能把基础算法用熟、用准、用出边界感。

这篇文章我想把试卷的整体结构、高频考点、典型题解法和备考思路完整拆一遍。无论你是正在准备视频行业算法岗的应届生,还是想检验自己基础算法功底的工程师,这篇复盘应该都能给你一些有价值的参考。

1. 先给这套试卷定个位:它不是"难",是"宽"

1.1 视频社区算法岗的人才画像

B站的算法岗和电商、网约车、金融风控这类公司的算法岗,表面上考察的科目差不多,但底层逻辑差异很大。做交易类业务,算法要围绕转化率、GMV、风险损失来建模;做内容社区,算法要理解的是内容质量、用户兴趣、社区氛围、创作者生态。这就决定了笔试命题时,出题人不会只盯着"你是不是会写Transformer",而是更在意你计算机基础扎不扎实、能不能快速把问题抽象成算法模型。

2020年这套卷子给我最直观的感觉是:选择题覆盖面非常广,编程题难度整体控制在LeetCode中等水平,但每一道题都留了"坑"。它不是靠偏题怪题来拉开差距,而是靠基础题里的细节和边界条件来筛人。这其实很符合内容平台的需求——算法工程师每天都要和大量真实、嘈杂、充满异常的数据打交道,边界感比炫技重要得多。

1.2 线上笔试环境对做题策略的影响

这一届校招正赶上笔试全面线上化,牛客网、赛码网这类平台成为主战场。线上笔试和纸质卷最大的区别是:你不能在纸上画草图、写写划划,所有思考都得在脑子里完成;其次,编程题的输入输出处理变得更加重要,很多人不是不会解题,而是挂在解析输入上。

我在复盘这套试卷时,把这作为一条主线:做题策略不只是"会做",还包括"在线上评测系统里做对"。比如选择题部分,很多人因为不熟悉"多选少选不得分"的规则丢分;编程题部分,有人输出格式差了换行就整题零分。这些在复盘时都得纳入考虑。

2. 试卷结构全景:选择题和编程题各自承担什么角色

2.1 选择题覆盖的知识模块

2020年这套试卷的选择题部分,正常题量在20到30之间,题型以单选为主、多选穿插。覆盖的知识模块基本可以分成四块:数据结构与算法、计算机基础知识、机器学习基础、逻辑推理与数学。这里面数据结构与算法占比最高,大概能到40%;机器学习基础差不多25%;计算机网络和操作系统加起来20%;剩下的是数学和逻辑题。

我整理了这套卷子里最常出现的考点,做了一个梳理表:

知识模块具体考点出现频次
数据结构栈与队列特性、二叉树遍历、哈希冲突处理、堆的调整过程高频
算法KMP的next数组、排序算法稳定性、贪心与DP辨析、二分查找边界高频
机器学习过拟合与正则化、精确率/召回率/F1、梯度下降变体、特征工程中高频
操作系统进程线程区别、死锁条件、虚拟内存、页面置换算法低频
计算机网络TCP握手、HTTP状态码、DNS解析流程低频
数学逻辑概率计算、排列组合、逻辑推理中频

从考点分布能看出一个趋势:B站招聘算法岗,并不指望你在笔试阶段就展现出对深度学习框架的精通,而是先把CS基础这层地板铺好。机器学习相关的题也偏基础,不会直接让你推导Transformer的注意力公式,但会问你"L1和L2正则化哪个更容易产生稀疏解""类别不平衡怎么处理"这类实战问题。

2.2 编程题的难度阶梯

编程题部分一般有3到4道,难度是阶梯式上升的。第一题通常是字符串或简单模拟,属于送分题,但送分不等于白给,往往设置了输入格式的坑;第二题和第三题是重点得分区,动态规划、贪心、双指针都可能出现;最后一题如果出现,往往是图论或复杂DP,给全场最顶尖的那批人区分度用的。

我复盘时发现一个有意思的现象:这套卷子的编程题很少直接贴一个"最长回文子串"或者"两数之和"这种原题,而是会套一层业务壳。比如会问"根据用户的连续观看记录,找出最长的无重复兴趣标签序列",本质上是LeetCode第三题"无重复字符的最长子串"的换皮。所以如果你刷题只背原题答案,不理解解法背后的抽象逻辑,考场上很容易被这层壳吓住。

3. 高频考点硬核拆解:KMP、排序、贪心与动态规划

3.1 KMP的next数组:一字一句推演"abacaba"

热搜里关于模式串p="abacaba"的next数组求解,是一个非常经典的考点,也是B站这类笔试选择题里出现频率很高的题。很多人对KMP的理解停留在"背代码",一旦next数组定义略作调整就懵了。这里我完整推一遍。

先明确一个常用的定义:next[i]表示模式串p[0..i]这个子串中,最长相等前后缀的长度(不包含子串自身)。比如p[0..0]="a",它的前缀集合和后缀集合都是空集(不含自身),所以next[0] = 0

我们一步一步看p = "abacaba"

  • i = 0,子串"a",最长相等前后缀长度为0,next[0]=0
  • i = 1,子串"ab",前缀有"a",后缀有"b",不相等,next[1]=0
  • i = 2,子串"aba",前缀有"a","ab",后缀有"ba","a",最长相等的是"a",长度1,next[2]=1
  • i = 3,子串"abac",前缀"a","ab","aba",后缀"bac","ac","c",没有相等的,next[3]=0
  • i = 4,子串"abaca",前缀"a","ab","aba","abac",后缀"baca","aca","ca","a",最长相等为"a",长度1,next[4]=1
  • i = 5,子串"abacab",注意看,前缀"a","ab","aba","abac","abaca",后缀"bacab","acab","cab","ab","b",最长相等的是"ab",长度2,next[5]=2
  • i = 6,子串"abacaba",前缀最后几个是"abacab","abaca","abac","aba","ab","a",后缀是"bacaba","acaba","caba","aba","ba","a",最长相等的是"aba",长度3,next[6]=3

所以next数组为{0, 0, 1, 0, 1, 2, 3}

这里推荐用next[i]表示"前i个字符组成的子串的最长相等前后缀长度"也很常见,这种定义下数组整体会往后错一位。刷题时一定要先看题目给的定义,否则同样的字符串可能得出不同的数组。我当年在这个考点的建议是:不要死记结论,考场上花30秒手推一遍更稳。

3.2 排序算法选择题里藏着的坑

排序算法是选择题的常客,而且B站这套卷子特别喜欢在"稳定性"和"时间复杂度细节"上做文章。直接贴一个对比表,方便你自检:

排序算法平均时间复杂度最坏时间复杂度空间复杂度稳定性
冒泡排序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(n²)O(n²)O(1)稳定
希尔排序O(n^1.3~1.5)O(n²)O(1)不稳定
选择排序O(n²)O(n²)O(1)不稳定

光背这张表还不够,真题往往会这样问:"对近似有序的数组,以下哪种排序算法性能最好?"答案是插入排序,因为它的最好时间复杂度是O(n),几乎有序时接近线性。再比如"归并排序为什么是稳定的而快速排序不是",这就要理解底层操作:归并时遇到相等元素先取左半部分,所以稳定;快排的partition交换过程中,相等元素的相对顺序可能被打乱。

还有一类题是给一个中间状态,问这是哪种排序的第几趟结果。比如"第一趟排序后,最小的元素被放到了最前面,但其他元素相对顺序不变",这是冒泡排序的特征;如果是最小元素放最前面但其他元素顺序可能改变,那就是选择排序。这类题没有捷径,只能靠理解每轮排序做了什么。

3.3 贪心和动态规划:同一个场景,两种解法

选择题里非常爱考贪心和DP的辨析,而且出题人很鸡贼,经常给一个可以用贪心解、也可以用DP解的场景,问你哪个对。我复盘到的经典例子是"找零钱问题"。

如果硬币面额是1, 5, 10, 25这种,贪心策略(每次取不超过剩余金额的最大面额)一定正确,因为这套面额设计满足贪心选择性质。但如果面额换成1, 3, 4,要找6块钱,贪心会先取4,剩下2只能取两个1,一共3枚;而最优解是取两个3,一共2枚。这种场景就只能用动态规划。

动态规划的状态转移方程是:dp[i] = min(dp[i - coin[j]] + 1),其中coin[j]是硬币面额。如果题目再进一步,问你能不能输出具体的找零方案,那还要加一个path数组记录每一步选了哪枚硬币。

从这里能看出,笔试选择题里的算法题,核心不是考察你能不能写出代码,而是考察你知不知道"什么情况能用贪心、什么情况必须上DP"。判断标准也很朴素:局部最优能不能推出全局最优,能不能找到反例。平时刷题时多问自己一句"这题我为什么用DP不用贪心",比多刷十道题管用。

4. 编程题实战:典型题解法和考场上的边界处理

4.1 字符串题:把"无重复最长子串"用到业务场景

前面提到了这套卷子喜欢给算法题套业务壳,最典型的就是字符串处理。我这里写一个通用解法,大家练的时候一定要把模板吃透。

假设题目变成"给定一个字符串表示用户连续观看的视频标签,输出最长的没有重复标签的连续子串长度"。这个壳子剥掉后就是LeetCode第三题。

def length_of_longest_substring(s: str) -> int: # 用哈希表记录每个字符最近一次出现的位置 pos = {} left = 0 max_len = 0 for right, ch in enumerate(s): if ch in pos and pos[ch] >= left: # 如果当前字符在滑动窗口内出现过,把左边界移到上次出现位置的下一个 left = pos[ch] + 1 pos[ch] = right max_len = max(max_len, right - left + 1) return max_len

这段代码有两个必考的边界点。一是pos[ch] >= left这个条件,如果少了它,遇到窗口外的历史位置也会错误地移动左边界;二是left指针更新后,max_len要基于新的窗口长度计算,不能拿旧的窗口去更新。

我在牛客这类平台刷题时发现,很多人会问"用set能不能做"。能,但用set的写法需要做删除操作,复杂度虽然是O(n),实际跑起来比哈希表pos版本慢不少,而且在线上笔试环境里,极端长字符串用例有超时风险。这里建议直接写哈希表版本。

4.2 0-1背包的一维优化:从二维DP到一维数组

背包类DP是算法笔试卷里的常客,B站这套卷子里也出现过。0-1背包的标准状态定义是dp[i][j]表示前i件物品放入容量为j的背包能获得的最大价值,转移方程为:

dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])

考场上必须会的优化是滚动数组压缩到一维。因为dp[i]只依赖dp[i-1],所以可以用一维数组从后往前更新:

dp = [0] * (capacity + 1) for i in range(n): for j in range(capacity, w[i] - 1, -1): dp[j] = max(dp[j], dp[j - w[i]] + v[i])

这里最重要的一个细节是内层循环必须从大到小遍历。如果从小到大,dp[j - w[i]]可能已经被当前这一件物品更新过,相当于一件物品被用了多次,那就变成了完全背包。这个细节几乎每年笔试都会有人踩,值得反复提醒自己。

如果是完全背包,内层循环改成从小到大即可:

for j in range(w[i], capacity + 1): dp[j] = max(dp[j], dp[j - w[i]] + v[i])

两种背包只差一个遍历方向,但含义天差地别。建议大家刷到这类题时,把二维转移方程、一维优化、遍历方向三个层次一次性串起来理解,而不是分别背。

4.3 线上笔试的输入输出陷阱

说真的,编程题写不出解法只是输的一种方式,还有一种是写出了解法却因为输入输出处理不对而零分。我复盘2020年的线上笔试时,发现环境用的是标准输入输出,也就是要自己写sys.stdininput()读取。这里有几个高频坑。

第一个坑是多行输入。题目可能第一行给n,第二行给n个整数。如果只用input()读一次,就会少读一行:

import sys def main(): data = sys.stdin.read().strip().split() if not data: return n = int(data[0]) arr = list(map(int, data[1:1 + n])) result = solve(arr) print(result) if __name__ == "__main__": main()

一次性把标准输入全部读进来再解析,是线上笔试最稳的方式,能避免换行符、行尾空格等问题。

第二个坑是输出格式。有些题目要求每个结果占一行,有些人把所有结果用空格隔开输出,系统比对字符串就会判错。遇到这类题,先把构建结果列表,最后用"\n".join(...)拼接成整体输出。

第三个坑是Python递归深度。如果编程题需要用递归处理、而且数据规模到10的5次方以上,默认递归深度会报RecursionError,非递归写法或者增加递归深度限制sys.setrecursionlimit(1 << 25)要提前想好。

5. 机器学习与智能算法:B站笔试里的"算法"不止数据结构

5.1 机器学习基础考点:过拟合、评估指标、类别不平衡

如果岗位明确是算法工程师、推荐算法工程师,那笔试卷里一定会出现机器学习基础题。B站这套卷子涉及的机器学习考点,我复盘之后总结了几个高频方向。

过拟合的识别与处理是必考的。题目会给你一个训练集准确率98%、测试集准确率72%的场景,问可能是什么问题、应该怎么解决。答案很明确:过拟合,解决手段包括增加数据量、降低模型复杂度、加正则化、早停、Dropout。这里容易混淆的是正则化类型,L1会产生稀疏解、可以用于特征选择,L2会让权重趋向0但不会精确等于0。

评估指标是另一个高频方向。推荐场景中正负样本往往极不平衡,精确率和召回率比准确率更有参考价值。公式要熟:精确率 = TP/(TP+FP),召回率 = TP/(TP+FN),F1是精确率和召回率的调和平均数。会出一道简单的计算题:测试集100个样本,正样本20个,模型预测出15个正样本,其中12个是真阳性,问精确率和召回率是多少。答案是精确率 = 12/15 = 0.8,召回率 = 12/20 = 0.6。这种题没有技巧,就是熟练。

类别不平衡的处理在B站这种内容平台很有实战意义,因为正反馈和负反馈天然不均衡。常见方案:过采样少数类、欠采样多数类、调整类别权重、使用Focal Loss、用AUC等对不平衡不敏感的指标。知道这些属于"话题型"考点,不需要你推导公式,但至少要答得出大致方向。

5.2 粒子群算法这类"非主流"考点怎么准备

热搜里出现了"粒子群算法原理",这其实也是算法笔试选择题的一个可能方向。粒子群算法(PSO)属于群体智能优化算法,和遗传算法、模拟退火算法并称三大经典启发式算法。在刷题时很多人会忽略这类知识,因为他们更关注确定性算法。

B站这类业务场景中,很多问题并不是标准解析解能解决的,比如推荐策略中的多目标参数调优、视频转码参数组合寻优,都可能用到这类启发式算法。所以笔试卷中出现粒子群算法的选择题并不突兀。

粒子群算法的核心思想是模拟鸟群觅食:每个候选解是一个"粒子",粒子有位置和速度,每次迭代根据个体历史最优位置(pBest)和群体历史最优位置(gBest)来更新速度,再更新位置。

关键公式是速度更新:

v[i] = w * v[i] + c1 * r1 * (pBest[i] - x[i]) + c2 * r2 * (gBest - x[i])

其中w是惯性权重,c1c2是学习因子,r1r2[0,1]之间的随机数。位置更新就是x[i] = x[i] + v[i]

选择题如果考PSO,一般就是问"粒子群算法中,粒子的速度和位置更新依赖哪些量"或者"惯性权重w的作用是什么"。前者答案是个体历史最优和群体历史最优,后者答案是平衡全局搜索和局部搜索的能力。这类题不需要写代码,把概念理清就够了。复习建议是:把遗传算法、模拟退火、粒子群三个算法的核心思想、参数、优缺点做成一张对比表,考前几天过一遍。

6. 复盘之后,给后来人的几点实在建议

6.1 刷题要有"业务抽象"意识

这套卷子给我最大的教训是:B站这种内容平台的算法笔试,不满足于考原题。同样的知识点,它会包装成"用户观看序列""弹幕情感标签""内容推荐候选集"等业务场景。平时刷LeetCode时,我建议每做完一道题,停下来想一步:"这个算法在公司业务里会出现在哪里?"

比如滑动窗口,现实中就是"用户在一定时间窗口内的行为序列分析";单调栈,就是"在视频序列中找下一个热度更高的视频";拓扑排序,就是"课程依赖关系/内容推荐依赖关系"。有了这层业务抽象能力,考场上看到任何披着业务壳的题,你都能快速剥壳还原成核心算法模型。

6.2 错题本比题量重要

我不是反对大量刷题,而是反对"无脑刷"。同样是刷200道题,有人是靠AC数量堆上去的,有人是靠错题本迭代上去的,后者的效果完全不一样。建议给常见的错误分类:边界条件遗漏(空数组、单元素、越界)、数据结构选择失误(该用哈希表却用了列表)、贪心和DP误判、输入输出处理不当。每次笔试或模拟考后更新一次错题本,考前重点翻错题本而不是重新刷题。

6.3 前30分钟的选择题策略

线上笔试的时间分配直接决定编程题能不能做完。建议先快速扫一遍选择题,遇到需要复杂计算的先标记跳过,把时间留给后面的编程题。我见过太多人卡在选择题的某道概率题上算半天,最后编程题没时间写。选择题一道也就2到4分,编程题一道至少20到30分,这个账要算清楚。

6.4 有条件的话,模拟一次真实笔试环境

很多人平时在IDE里刷题很顺,一上牛客的在线评测系统就各种不适应。建议考前至少完整模拟一次:开计时器,不开代码补全,不查API文档,全程用标准输入输出,一次性提交通过。这一套流程走下来,能暴露很多平时发现不了的问题。


这套2020年的B站校招算法笔试卷,整体难度放在今天看依然有参考价值。它不考验记忆力和偏题储备,考验的是你在有限时间内对基础算法的熟练度和判断力。准备这类笔试,与其焦虑"还有多少题没刷",不如把基础模块一个一个夯实:KMP能手推next数组,排序能说清稳定性和复杂度,贪心和DP能准确辨析,背包模板能闭眼写对遍历方向,机器学习基础概念能快速反应。这几板斧在考场上比任何花哨技巧都管用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询