公司动态
B站2023校招算法笔试卷B拆解:高频考点与实战策略
去年秋招帮学弟做模拟面试的时候他拿了一套哔哩哔哩2023校园招聘算法方向的笔试卷B出来说连着做了两遍选择题还好一到编程题和问答题就心里没底。我翻了翻这套卷子发现它其实很有代表性——它不只是B站的笔试基本上覆盖了国内互联网大厂算法校招的常见出题范围。这篇文章我就从这套卷子出发把每一类考点怎么准备、底层原理是什么、答题的坑在哪里完整拆一遍。不管你是准备投B站还是打算海投算法岗这份拆解都能直接用在复习规划里。1. 先看清这份试卷的“出题逻辑”1.1 笔试卷B的整体结构与时间压力先聊个很多人忽略的问题为什么校招笔试喜欢按A、B卷出题一般一个批次有两次笔试机会A卷考挂了会进备胎池B卷就是给补考或者硬核筛选用的。我对照过不少同学的反馈B卷的整体难度通常会比A卷稍微高一点覆盖范围也更杂。B站这套算法卷题型大致是单选、多选、填空题加上两到三道编程题最后还会有一两行简答题时间一般是90到120分钟。听起来时间不少但实际做题会发现真正难的不是每道题有多深而是你在有限时间内能不能快速切换思维状态。我画过一个时间分配模型如果卷面是90分钟选择题和填空题最好控制在20到25分钟内编程题每题留20到30分钟简答题最后剩10到15分钟。很多同学一上来就跟第一道编程题死磕等AC了再看表剩下40分钟连蒙带猜做其他题基本就崩了。笔试的筛选思路是“先看全面性再看深度”你把基础题全拿稳比在某一道题上写出最优解更重要。这套卷还有一个特点题目表面是B站风格比如直播间连麦调度、视频推荐召回、弹幕去重但剥开外壳以后全是经典算法问题。所以备考的时候不要只看校园招聘题库里那几十道题更要把“业务场景”翻译成“数据结构与算法”的能力练出来。面试官要的不是你会背某个模板而是给你一个带着业务壳的问题你能认出它到底在考什么。1.2 为什么算法岗笔试几乎都绕着“排序、匹配、路径、优化”转做了几年校招相关的内容我发现算法笔试题再怎么变核心场景永远集中在四个方向排序与TopK、字符串与模式匹配、图论与路径规划、优化问题与动态规划。这不是出题人偷懒而是因为这些基础能力在真实业务里用得最多。拿B站举例你刷到的视频推荐流本质上就是“海量内容按某个分数排序后取TopK”弹幕审核里的敏感词过滤落到实现层就是多模式字符串匹配直播CDN节点选择、视频转码任务调度能抽象成图上的最短路径或最小费用流而搜推广场景里的CTR预测、超参调优又会用上各种优化算法。笔试考排序和KMP不是让你毕业以后手写快排而是考察你有没有理解这些底层工具的边界和代价。所以我给学弟的建议很直接复习的时候不要按“今天刷链表、明天刷树”这种单一模式走而是按场景去组织知识。比如把所有能解决“第K大”问题的方法放到一起对比——快速选择、堆、排序后取下标、甚至Partition变形。等你在脑子里有了一堆“场景—算法—复杂度—适用边界”的映射表做笔试卷B这种混合题型就会顺畅很多。2. 数据结构与基础算法最容易拿分也最容易翻车的板块2.1 排序算法快排、堆排、冒泡的高频考点这套卷子里排序算法几乎每年都会出现而且考法越来越刁钻。以前就是“写出快排代码”或者“快排时间复杂度是多少”现在则喜欢考边界情况和稳定性判断。我整理了一张对比表是笔试前必须刻在脑子里的排序算法平均时间复杂度最坏时间复杂度额外空间稳定性冒泡排序O(n²)O(n²)O(1)稳定快速排序O(n log n)O(n²)O(log n)递归栈不稳定堆排序O(n log n)O(n log n)O(1)不稳定归并排序O(n log n)O(n log n)O(n)稳定笔试里常挖的一个坑是“快排什么时候退化成O(n²)”。如果每次选取的pivot都是当前区间最小或最大元素划分极度不均衡递归深度就变成n时间复杂度退化成O(n²)。解决方法就是随机选pivot或者三数取中。再追问一步为什么快排不稳定因为Partition过程中元素会隔着距离交换相同的值可能被换到另一边去相对顺序没法保证。堆排序的易错点在于建堆过程。从最后一个非叶子节点也就是下标n/2 - 1开始从下往上做向下调整。很多人把建堆写成了从堆顶往下调整那就成了“把数组当堆”的错觉。笔试考动态TopK的时候堆是一个很关键的思路维护一个大小为K的小顶堆新元素如果比堆顶大就替换并调整这样堆里始终是最大的K个元素时间复杂度O(n log K)。这和堆排序“排序整个数组”是两种用法一定要分清。2.2 KMP和next数组从“abacaba”看模式匹配的边界问题字符串匹配是笔试试卷的保留节目而KMP算法又几乎是最常考的。热词里有一道很典型的题模式串pabacaba求其next数组。这里next[i]的定义在不同教材里略有差异答题时务必看清楚题干给的是“从1开始下标”还是“从0开始下标”否则答案会差一位。我按常见的“next[i]表示p[0..i-1]的最长相等前后缀长度”来算也就是next[0]-1迁移到从1开始的表示法时要整体加1下标i子串p[0..i]最长相等前后缀长度next[i]从0开始0a不存在-11ab002aba1前缀a后缀a13abac004abaca1前缀a后缀a15abacab2前缀ab后缀ab26abacaba3前缀aba后缀aba3很多同学背KMP模板背得很熟但一到“求next数组”这种题就翻车原因是对“最长相等前后缀”这个概念理解不透。前后缀的定义是前缀不能包含最后一个字符后缀不能包含第一个字符。所以求某个位置的next值本质是在它前面的所有前缀后缀里找最长的、完全相等的那一对。KMP能写成O(nm)时间复杂度的核心就是失配时不需要回退主串指针而是通过next数组把模式串向右滑动到合适位置。这个“主串不回头”的思想比代码本身更重要。笔试如果考KMP的改进版也就是nextval则要在next数组基础上再检查一次p[i]与p[next[i]]是否相等若相等则继续向前跳转目的是进一步减少无意义的比较。这两者的区别面试官一句话就能问出来。2.3 Dijkstra、快速幂、贪心三类爱考的基础算法图论里最常考的不是复杂的网络流而是Dijkstra最短路径。B站的笔试场景会包装成“直播间转播线路切换从源站到边缘节点找最低延迟路线”。Dijkstra是典型的贪心思想每次从未访问节点中选距离最小的节点用优先队列优化后复杂度为O((VE) log V)。这里有个高频坑Dijkstra不能处理负权边因为一旦出现负权当前距离最小的节点可能在后续被更短的路径更新而它已经被标记为“已确定”。遇到负权图要用Bellman-Ford或SPFA。快速幂算法是数论和动态规划里都爱考的基础工具。题目一般就这么出计算a的b次方对mod取模b的范围能到10的18次方。核心思路是把指数b写成二进制按位处理。C模板可以这样写long long fastPow(long long a, long long b, long long mod) { long long res 1 % mod; a % mod; while (b 0) { if (b 1) { res res * a % mod; } a a * a % mod; b 1; } return res; }这里有两个细节容易被忽略。一是res初始化为“1 % mod”防止mod1导致结果不对。二是每一步乘完都取模避免中间结果溢出long long。如果题目里模数是1e97这种大质数乘法用long long是安全的如果模数更大到1e18级别就得用快速乘或者__int128否则乘法溢出会让答案直接错。贪心算法在笔试卷里常常以小应用题出现比如“活动安排问题”“区间覆盖问题”。贪心最难的其实不是写代码而是证明贪心策略的正确性。笔试答题时建议用“交换论证法”简短写几句假设最优解里存在和贪心选择不同的安排通过交换可以变成贪心解而不破坏可行性因此贪心解就是最优解。能把证明思路写出来哪怕不完整也能让阅卷人看到你有算法思维而不是只会背题。3. 机器学习与深度学习笔试里的“业务向”考察3.1 KNN为什么会问“应用能力包括哪三个方面”热词里专门有一条“KNN算法的应用能力包括哪三个方面”这明显是笔试原题或者面试题的变体。KNNK近邻是机器学习里最简单的非参数方法之一它的应用能力可以从三个维度去理解分类、回归和缺失值填充/异常检测。分类是KNN最常见的用法把待预测样本的K个最近邻居找出来按多数投票决定类别回归则是对K个邻居的目标值取平均或加权平均预测连续值在异常检测场景里可以计算每个样本到其K近邻的平均距离距离明显偏大的样本就是离群点。KNN在B站这种内容平台落地时常见的是做用户兴趣相似度匹配——找到和你历史行为最像的一批用户把他们都喜欢的视频推荐给你本质上就是KNN思想的应用。KNN笔试里还有个必考点是“特征缩放的重要性”。KNN依赖距离度量如果某个特征的量纲特别大比如播放时长有10万秒而另一个特征只有0到1欧氏距离就会被播放时长主导。解决办法是做标准化或归一化。另外K值选择也很讲究K太小容易过拟合噪声样本会直接影响预测结果K太大容易欠拟合把很多不同类别的样本都卷进投票范围。笔试里如果问你K怎么选答“交叉验证”基本不会错。3.2 聚类算法在内容分发里的落地聚类在笔试卷里通常以概念题或简单计算题出现但考察频率很高。K-Means的流程是先随机选K个中心点然后把每个样本分配到最近的中心点所在的簇再重新计算每个簇的均值作为新中心反复迭代直到中心变化很小或达到最大迭代次数。它的优化目标是最小化所有样本到所属簇中心的平方距离之和。笔试高频坑是K-Means的两个先天缺陷。一是K值需要事先指定实际业务里你不知道应该把用户分成几类才最合理。常见解决方法是肘部法则画簇内误差平方和SSE随K变化的曲线找拐点但拐点多多少少带点主观性。二是K-Means对初始中心点敏感不同的初始化可能得到完全不同的聚类结果所以工程上常用K-Means做初始化让初始中心点互相离得远一点。聚类算法在B站的典型应用是视频内容聚合和弹幕主题聚类。比如把用户上传的大量视频按画面特征或标题语义聚类辅助运营做内容分层再比如把同一时间段大量弹幕做聚类能提取出大家都在讨论的梗或者重点。笔试如果出“结合实际业务设计一个聚类方案”不要只答算法流程一定要提数据怎么清洗、特征怎么选、K怎么定、结果怎么评估——这才会让阅卷人觉得你是能干活的。3.3 强化学习和深度学习的常见送命题这套笔试卷对强化学习的考察不算深但会问基础概念。Q-Learning的核心更新公式是Q(s,a) Q(s,a) α[r γ * max(Q(s,a)) - Q(s,a)]这个公式必须能默写。其中α是学习率γ是折扣因子max(Q(s,a))表示下一状态所有动作里Q值的最大值。笔试常问的问题是“探索和利用怎么平衡”标准答法是ε-greedy策略以ε的概率随机探索新动作以1-ε的概率选择当前Q值最大的动作。深度学习部分更偏向概念辨析比如问“Batch Normalization为什么能加速训练”“Dropout为什么能缓解过拟合”。前者是因为BN把每层的输入分布拉回到均值为0、方差为1的相对稳定状态避免梯度消失或梯度爆炸从而可以使用更大的学习率后者是训练时随机丢弃一部分神经元迫使网络学习到更鲁棒的特征而推理时要把权重乘以保留概率做补偿。还有一个容易被问住的细节训练集和验证集的划分方式。很多同学答“按8比2随机切分”但笔试常会追问“如果数据有类别不均衡怎么办”。这时候要答分层抽样保证切分后训练集和验证集里各类别比例和原始数据一致。再深一层如果数据存在时间顺序比如弹幕热度预测就不能随机切分必须按时间切否则就是用未来数据预测过去产生数据泄漏。4. 容易被忽略却真实出现的扩展算法考点4.1 粒子群、模拟退火两种典型的启发式优化粒子群算法PSO和模拟退火SA在校招笔试里通常作为选择题或判断题出现但B站这套B卷里它们其实是拿来考“你对优化算法有没有全局视野”的。粒子群算法的灵感来自鸟群觅食每个粒子有位置和速度位置代表候选解速度代表搜索方向。每次迭代粒子会向两个方向更新一个是自己历史最优位置pbest一个是群体历史最优位置gbest。粒子群的核心更新公式是v wv c1r1*(pbest-x) c2r2(gbest-x)x x v。其中w是惯性权重控制保留上一次速度的程度c1是自我学习因子c2是社会学习因子r1和r2是0到1的随机数。笔试如果问“w太大或太小的影响”标准答法是w太大全局搜索能力强但收敛慢w太小容易陷入局部最优。很多领域做超参寻优比如调XGBoost或者神经网络的超参数如果参数空间连续且没有梯度信息粒子群是比网格搜索更高效的方案。模拟退火的核心是Metropolis准则如果新解比当前解好无条件接受如果更差以概率exp(-ΔE/T)接受其中ΔE是能量差T是当前温度。高温时接受差解的概率大有利于跳出局部最优温度逐步降低接受差解的概率变小最终收敛到近似最优解。笔试里模拟退火常和旅行商问题、排班问题结合起来考你不用现场实现完整的SA但必须说清楚“初始温度怎么设置、降温速率取多少、终止条件是什么”。这些细节最能区分真懂和假懂。4.2 卡尔曼滤波和PID状态估计与控制算法的经典组合卡尔曼滤波出现在笔试里可能会让不少同学意外但B站的音视频链路、服务器电源控制、传感器数据处理都有它的影子。卡尔曼滤波解决的核心问题是系统有噪声观测也有噪声我该怎么估计真实的系统状态。经典五条公式分两组预测组和更新组。预测根据系统模型推算出当前状态和协方差更新则结合观测值对预测结果做修正最终输出的状态估计是“预测”和“观测”的加权融合权重由两者噪声大小决定。笔试对卡尔曼滤波的考察一般不会要求推导公式但会问“卡尔曼滤波和高斯滤波的区别”“卡尔曼滤波的假设是什么”。标准答法是卡尔曼滤波假设系统是线性的、噪声服从高斯分布且状态转移矩阵和观测矩阵已知。如果系统是非线性的需要扩展卡尔曼滤波EKF或无迹卡尔曼滤波UKF通过局部线性化或者采样点逼近来近似非线性变换。PID算法在热词里出现了两种业务场景一个是CRPS电源一个是无人机/机器人控制。PID三个字母对应比例、积分、微分三个环节P项根据当前误差大小做修正I项累积历史误差消除稳态误差D项根据误差变化趋势提前抑制超调。笔试里最常见的操作题是“系统出现稳态误差该调哪个参数”——答案是加大Ki积分项能消除系统长时间存在的固定偏差。而“系统超调严重、震荡剧烈”则优先调大Kd或适当减小Kp。这三个参数的调节顺序是我实际调参的经验先调P让系统稳定再调I消除稳态误差最后调D抑制超调。这种经验比单纯背公式更能体现工程能力。4.3 SM2/SM3/SM4/ZUC、音频重采样、图像锐化业务驱动的偏门考点有时候笔试卷会混入一些“看着和算法岗不搭”的题其实它们背后都有业务逻辑。B站涉及视频内容安全、账号加密、播放鉴权所以商用密码算法也会偶尔作为选择题出现。SM2是椭圆曲线公钥密码算法用于加解密和数字签名SM3是密码杂凑算法输出256位摘要常用于完整性校验SM4是分组密码算法用于数据加密ZUC是流密码算法主要用于移动通信和实时加密场景。笔试只需知道它们各自属于哪一类、应用在哪个环节即可一般不要求手动实现。音频重采样算法会出现在音视频部门的算法题里考的是“把44.1kHz采样率转成48kHz怎么做”。最基础的方法是线性插值但音频信号对质量要求高直接线性插值会引入混叠失真工程上常用多相滤波器实现在时域做高倍插值、低通滤波、抽取三步。图像锐化的拉普拉斯算法则常考一个卷积核中心为-4或正4上下左右为1或负1。锐化的原理是原图加上拉普拉斯算子提取的边缘信息公式写作g(x,y) f(x,y) - ∇²f按中心取负的算子约定。这类题目不需要你现场写几万行工程代码但它能考察你是否愿意深入了解业务链路里用到的算法而不是只会刷LeetCode。5. 笔试实战答题策略、易错点与排查技巧5.1 答题顺序与时间分配的实测经验我见过太多同学在笔试时因为顺序不对导致翻车。按我自己的实测经验最优策略是先花1分钟快速扫一遍全部题目标记出“会做的”“有点思路的”“完全没思路的”。然后优先做完全会做的题把分先拿到手再做有点思路的题每道题限制时间超时就先跳最后再攻克完全没思路的题。不要期望每道题都AC笔试是选拔性考试你比同批人拿到的分数高就能进面。还有一个很多人忽视的点编程题里除了正确性要考虑边界条件。比如输入为空、数组长度为1、目标值不存在时程序会不会崩。笔试平台的测试用例里藏着大量边界用例你写出的代码如果只在样例上通过一提交就出现“段错误”或“数组越界”那基本就是边界处理没做好。我在帮学弟复盘时经常说写代码前先用两分钟把输入类型、取值范围、是否可能有负数、是否会溢出这些问题在草稿上列出来再动手其实比写完之后反复调试更省时间。选择题和填空题的答题策略也很关键。遇到不会的题不要空着排除掉明显错误的选项再根据常识判断。像“快排最坏时间复杂度是O(n²)”这种题即使忘了是快排还是归并也可以从“不稳定最坏退化”的记忆点反推。如果填空题要求写某个算法的复杂度尽量带上推导比如“堆排序建堆O(n)每次调整O(log n)共n-1次所以总复杂度O(n log n)”这样即使最后结论写错阅卷也可能给步骤分。5.2 编程题里反复出现的几个隐患这套笔试卷的编程题我把它常考的隐患整理成了排查清单笔试前过一遍隐患现象原因解决方法整数溢出大数用例WAint相乘超出2^31-1使用long long涉及取模及时mod递归栈溢出大数据用例RE递归深度过大改迭代实现或设置更大栈空间快排退化有序数组TLE固定选第一个元素作为pivot随机选pivot或三数取中KMP越界失配时j1越界next数组边界没处理手动模拟一遍abacaba优先队列比较器写反TopK结果相反大顶堆小顶堆用混仔细审题确认是求最大还是最小比如快速排序如果你的实现固定选择第一个元素作为pivot而测试数据里有“几乎有序”的序列递归深度趋近于n程序直接爆栈。笔试平台不会告诉你“你的算法退化了”只会显示“运行超时”。这一类非显性错误很难排查最有效的办法就是写完排序或搜索类代码后自己补一个“有序数组”“逆序数组”“全等数组”的测试用例跑一遍。另一个高频坑是返回值的类型。题目让你返回的是“最少操作次数”还是“操作方案”是“数组索引”还是“数组元素”有时候就差这一行改错导致完全不对。做题时先把题目里的输出描述圈出来写代码前确认一遍。5.3 主观题答题框架“原理复杂度场景”三段式笔试卷最后的简答题或者设计题是很多人放弃的板块但其实这类题有固定的得分框架。我在给学弟讲题的时候反复强调一个三段式答法先写原理再写复杂度最后写场景适配。这三段都写全即使分析不够精准也能拿到大部分分数。举一个真实场景题目“如何设计一个弹幕实时去重系统”。原理部分可以写用哈希表存储最近时间窗口内的弹幕指纹指纹可以用MD5或SimHash提取复杂度部分写出时间O(n)、空间O(m)其中n是弹幕数量m是滑动窗口大小场景适配部分说明弹幕具有短时重复率高、总量大的特征滑动窗口比较合适但要注意哈希冲突率和内存上限如果内存不够可以考虑布隆过滤器。这样分段作答阅卷人能快速抓到你的知识结构比长篇大论更有效。如果是“请设计一个视频推荐召回算法”这类开放性更强的题框架同样适用。先写召回阶段用协同过滤、双塔模型、向量检索中的哪一种再说明离线训练流程和在线服务链路最后给出复杂度预估和评估指标比如召回率、精确率、AUC。哪怕没有真正做过推荐系统只要把原理讲清楚、数据流向写明白也能展示扎实的算法基础。另外注意主观题里提到“模型训练”时最好能顺带写一句数据划分和评估方式。比如“按用户行为时间划分训练集和测试集避免数据泄漏”这类细节是区分“背过八股”和“真正做过项目”的关键。我在实际带人刷这套卷的时候最大的体会是算法笔试考察的不只是一堆知识点的堆砌而是你在压力下能不能保持结构化思维。很多人拿到试卷第一反应是“这题我没见过”但如果你能把它往经典算法框架上靠找到对应的模型再按“原理—复杂度—边界条件—业务场景”的顺序逐步展开绝大多数题都能找到突破口。这份拆解不是让你死记答案而是帮你建立一套应对任何算法笔试的思考路径。最后再分享一个小技巧每做完一道题不要急着看题解先在草稿纸上把“我用了什么数据结构、为什么用这个、复杂度是多少、最坏情况是什么”写下来。坚持一个月你会发现自己做笔试卷的状态完全不一样。