ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

算法岗笔试复盘:从KMP到推荐系统的考察逻辑与备考路径

算法岗笔试复盘:从KMP到推荐系统的考察逻辑与备考路径 2023年秋招小红书算法岗第一批笔试我至今还记得打开笔试系统那一刻的感受题量比预想中大题型比预想中杂有些题目看起来像是八股但仔细一读又全是业务味。作为经历过完整秋招、最终拿到几家大厂算法offer的过来人这篇复盘我拖了很久才写就是想把自己从“接到笔试通知”到“提交试卷”再到“复盘整理”的全过程尽量还原成一套可复用的准备路径。如果你正在准备算法岗的笔试尤其是互联网内容平台方向的公司这篇文章应该能帮你少走不少弯路。先说结论小红书算法岗的笔试不是纯刷题平台那种“四道Hard题定生死”的风格而是“算法题打底 机器学习/深度学习基础 业务场景分析”的组合拳。它的筛选逻辑很明确——既要你代码写得动也要你原理讲得清还要你对业务场景有感觉。下面我从试卷的整体结构、核心算法题的复盘、非算法题的考察重点、提交前的自查清单、以及后续准备方向的调整这几个维度逐一展开。1. 从收到笔试通知到打开答卷这批题到底在考什么1.1 笔试平台与答题节奏先交代一下客观情况。2023年秋招的笔试大多通过牛客网或者赛码网进行小红书这批用的是其中一家支持本地IDE调试后粘贴代码也支持在线编辑。整场笔试时长一般在90到120分钟题型分布大致是单选/多选题、2到4道编程题、若干道简答或设计题。这个结构意味着什么意味着你没法用“只刷LeetCode”的方式去应对因为算法题只是其中一个环节选择题和简答题同样占分而且往往是决定能否进入面试的关键分水岭。我当时的节奏是这样的先花3到5分钟快速浏览全部题目判断每道题的难度和熟悉度。编程题先挑有思路的做不会的标记下来回头再想选择题和简答题放在编程题之后集中处理。这个策略帮我避免了一个很常见的坑——在一道难题上死磕40分钟结果后面的基础题没时间写。笔试不是竞赛不要求你每道题都得满分但要求你在有限时间里拿到尽可能多的分数这是一种典型的“分数最优”思维。1.2 热搜词背后的考点雷达一张知识点地图笔试结束之后我习惯性地去复盘知识点分布。有意思的是如果把这个阶段搜索热度较高的一些算法词拉出来看基本就是一张算法岗笔试的考点雷达图。它们大致可以归成这几类数据结构与基础算法KMP算法与next数组、排序、堆排序、快速幂、二分、贪心、前缀和、剪枝。机器学习KNN、聚类、XGBoost、强化学习、BM25、异常检测、特征工程。深度学习与数学基础KL散度、ELBO、图像分类、EVA-02、CNN/Transformer以及拉普拉斯锐化、音频重采样等信号处理概念。经典优化与状态估计粒子群算法、模拟退火、卡尔曼滤波、PID、Minimax。我把它整理成一张表格方便按图索骥考察板块高频知识点常见出题方式备考优先级数据结构KMP、堆、二分、贪心、前缀和编程题、选择高机器学习KNN、聚类、XGBoost、过拟合、AUC选择、简答高深度学习注意力机制、KL散度、ELBO、图像分类选择、简答中高经典算法粒子群、模拟退火、卡尔曼滤波、PID选择、场景分析中业务场景推荐链路、冷启动、AB实验简答、设计高这张表不是用来背的而是用来自测的。拿出一张纸把每个知识点默写一遍能写清楚它的思想、适用场景、复杂度说明你过关了写不出来说明这里还有盲区。很多人在笔试前把精力全压在LeetCode上结果选择题问“KL散度不对称性怎么体现”直接懵了非常可惜。2. 四道算法题复盘从暴力解到最优解的思考路径算法题永远是最核心的拉分项。这批笔试里的大题难度介于LeetCode Medium到Hard之间题型不算偏但不少题都隐含了业务场景的设置。下面我按当时的复盘笔记挑四类高频题目做拆解。注意我不会直接贴“真题”而是把它抽象成题目原型重点是还原思考路径。2.1 字符串匹配与最小循环节KMP的next数组不是背出来的第一类高频题是字符串处理典型原型是给定一个字符串s判断它是否由某个子串重复拼接而成如果是输出最小循环节长度。这个题在LeetCode上有类似题目比如重复子字符串问题主流解法就是KMP。我当时的初始想法很朴素枚举所有可能的循环节长度L判断s[i] s[i % L]对所有i是否成立时间复杂度O(n^2)在n到10^5级别的时候必挂。于是我想到了KMP。KMP的核心是前缀函数也就是next数组。对于模式串pnext[i]表示p[0...i]的最长相等真前后缀长度。利用next数组最小循环节长度的判断就变成了计算字符串s的next数组即前缀函数。设L n - next[n-1]注意这里取决于next数组的下标定义。如果n % L 0那么L就是最小循环节长度否则不存在循环节答案就是n本身。这个过程的关键在于为什么n - next[n-1]就是候选循环节长度因为如果整个字符串s存在循环节那么它的最长相等前后缀长度一定是n - L。这个结论可以自己画图推一遍一个周期串“abcabcabc”的最长相等前后缀是“abcabc”长度为6n9n - 6 3正好是循环节长度。这个推导过程比记结论重要得多因为笔试选择题很容易变形考。再补一个热门的考察细节模式串p abacaba的next数组怎么手算。i0字符anext[0] 0因为没有真前后缀。i1字符串ab最长相等前后缀长度0next[1]0。i2字符串aba最长相等前后缀是a长度1next[2]1。i3字符串abac前辍a和后缀c不同长度0next[3]0。i4字符串abaca最长相等前后缀是a长度1next[4]1。i5字符串abacab最长相等前后缀ab长度2next[5]2。i6字符串abacaba最长相等前后缀是aba长度3next[6]3。所以p abacaba的next数组是[0, 0, 1, 0, 1, 2, 3]。这个手算过程在笔试中经常以选择题形式出现不要只看书上的结论一定要自己多找几个串练一遍。KMP的复杂度是O(nm)相比暴力匹配的优势在模式串很长、重复匹配很多的时候非常明显这也是它在搜索、推荐、NLP场景里被广泛应用的原因。2.2 任务调度与贪心堆优化贪心不是猜交换论证才是底气第二类高频题是任务调度类。典型原型是给定n个任务每个任务有处理耗时time[i]和截止时间deadline[i]每个任务耗时相同权重求最多能完成多少个任务。这个问题我在笔试里遇到过好几个变体解法都是同一个套路按截止时间排序用小根堆或者大根堆维护已选任务如果当前累计耗时超过当前任务的截止时间就把已选任务中耗时最大的任务丢出去。很多同学到这里会疑惑为什么按截止时间排序为什么移除的是耗时最大的任务而不是当前任务我当时的理解是这样的按截止时间排序是经典的“最紧迫任务优先”策略。对于一组任务如果截止时间较早的任务都无法完成那截止时间更晚的任务更不可能在这个时间窗口内完成所以先处理截止早的任务是合理的。当累计耗时超了我们需要从已选任务中删掉一个。为了“损失最小”应该删掉耗时最大的那个因为删掉它之后节省出来的时间最多能容纳更多任务。这个推理可以用交换论证严格证明任何最优解都可以调整成这种贪心选择的形式而不改变任务数量。复杂度上排序是O(nlogn)堆的插入和删除都是O(logn)整体O(nlogn)在n10^5级别下没有任何压力。踩坑提醒题目里一定要看清任务之间是否独立。如果任务之间有依赖关系A必须在B之前完成那这就变成了拓扑排序调度的组合题上面的贪心策略就不成立了。我当时就因为在读题时默认任务独立差点把一道带依赖的任务题当成普通贪心做了幸好检查时发现题目里有一句“某些任务依赖前置任务完成”及时切换思路。2.3 前缀和与双指针O(n^2)到O(n)的优化是怎么想到的第三类高频题是数组类典型原型是给定一个长度为n的非负整数数组nums和一个目标值target求和大于等于target的连续子数组的最短长度。这个题在LeetCode上是209题很经典。第一思路肯定是暴力枚举所有连续子数组计算区间和然后比较O(n^2)复杂度。然后想到用前缀和优化区间和的计算把内层循环从求和变成一次减法但依然是O(n^2)。真正能到O(n)的做法是两个前缀和二分。因为数组非负所以前缀和数组是单调递增的。我们可以枚举左端点二分查找第一个使得区间和≥target的右端点复杂度O(nlogn)。双指针滑动窗口。维护窗口的左右指针窗口内和小于target就扩展右指针大于等于target就尝试收缩左指针同时更新答案。每个元素最多被访问两次复杂度O(n)。我当时写的双指针版本大致是这样的def minSubArrayLen(target: int, nums: list[int]) - int: n len(nums) left 0 window_sum 0 ans float(inf) for right in range(n): window_sum nums[right] while window_sum target: ans min(ans, right - left 1) window_sum - nums[left] left 1 return 0 if ans float(inf) else ans这题最佳解法为什么是滑窗而不是二分因为滑窗在遍历过程中既更新了左右边界又同步维护了区间和省掉了二分查找的logn因子在数据量极大时更稳妥。而且这种“看到单调性就想到优化”的思路在后续很多二分类似题里都是通用的——比如“找到AUC最大的阈值区间”“找到满足转化目标的最短投放窗口”等本质都是在有序序列上做指针移动。2.4 TopK问题堆、快速选择与数据流场景第四类高频题是TopK问题尤其是“数据流中动态求第K大元素”这种变体。原型题目设计一个类支持add(val)操作并随时返回当前所有元素中第K大的值。这个题LeetCode 703算法岗考它的频率极高因为它能同时考察堆、排序、二分多个知识点还经常和推荐系统的“热门内容TopK”业务场景结合。我的思路演进是这样的全局排序每次add之后重新排序取第K个时间复杂度O(m log m)m为当前元素个数。数据量小的时候无所谓数据流一大就废了。最小堆维护一个大小为K的最小堆堆顶就是第K大的元素。add时如果堆的大小小于K直接入堆否则如果新元素比堆顶大就弹出堆顶、加入新元素。这样每次add的复杂度是O(logK)空间O(K)非常优雅。快速选择如果只是一次性查询而不是持续维护可以用快速选择算法平均O(n)找到第K大元素但最坏O(n^2)并且不能很好地处理流式数据。笔试里我强烈建议直接用堆因为它的复杂度稳定、代码短、不容易写错。如果考官后续追问“内存不够怎么办”再说分桶、小顶堆大顶堆组合或者哈希计数等方式。另外注意TopK有两个变种——第K大和第K小对应的堆类型正好相反写代码前先确认清楚。3. 非算法题里的能力考察机器学习、深度学习与数学基本功3.1 机器学习概念题不是背八股而是考你有没有真正理解小红书这批笔试的选择题和简答题里机器学习相关的比重很高。最常出现的是这几类KNN的投票机制和距离度量、K-Means的初始化和收敛、过拟合的判别与缓解、AUC和LogLoss的适用场景、样本不均衡的处理方式、冷启动问题。这些问题看起来像八股但出题人往往会换一个业务场景来包装。比如“新用户没有任何行为数据怎么给他做内容推荐”本质就是在考冷启动。我的回答套路是三步先给结论再展开原理最后结合场景举例。比如KNN结论是“基于邻居标签投票的分类方法”原理是“通过距离度量找到最近的K个样本以多数投票决定类别”场景举例是“在用户相似度召回中可以用KNN的思路找到相似用户再用协同过滤生成推荐候选”。这样回答既有信息量又体现了业务感觉。另外抽样评估指标也很重要。AUC是排序能力的度量适合正负样本不均衡的场景LogLoss是对概率预测质量的度量适合需要校准概率的场景。如果你只是说“AUC越大越好”那是背答案如果你能说“AUC对阈值不敏感适合点击率预估中正样本极其稀疏的局面”那才是真的理解。3.2 深度学习与概率基础从KL散度到ELBO为什么数学是算法岗的分水岭这批笔试里出现了一个很值得注意的考点KL散度与ELBOEvidence Lower Bound的关系。很多同学一看这题就懵觉得这是生成模型才用的东西跟推荐算法有什么关系。但仔细想VAE、扩散模型、甚至一些多模态模型的训练目标都离不开这个数学基础。笔试考它本质是在筛选“能读得懂最新论文”的候选人而不只是会调包调参的人。我建议用这个通俗理解方式去消化KL散度衡量的是两个概率分布之间的差异它是不对称的也就是说KL(P||Q)不等于KL(Q||P)这一点经常被出成选择题。ELBO则是对数似然log p(x)的下界它把难以直接计算的log p(x)转化为“重构误差先验正则项”的形式让模型可以通过最大化ELBO来近似最大化似然。这就好比你想知道一个复杂机器的真实功率log p(x)但没法直接测于是你用一个简化模型q(z)去逼近它并不断优化这个逼近过程ELBO就是那个“逼近得好不好”的度量。这类题没有捷径必须自己动手推一遍VAE的损失函数推导。只背“ELBO 重构损失 - KL散度”这个结论一到变式题就露馅。我备考时花了整整两天的时间把KL散度的定义、ELBO的推导、重参数化技巧完整手推了一遍之后的笔面试里遇到相关问题基本都能接住。3.3 经典算法场景题粒子群、卡尔曼滤波、PID不是没用的冷知识热搜词里出现了粒子群算法、模拟退火算法、卡尔曼滤波算法、PID算法很多人觉得这些是控制论或者运筹学的内容算法岗笔试考这些是不是超纲了其实不然。这些算法体现的是一个候选人的知识广度以及“在真实系统里做决策优化”的能力。我整理过这些算法的适用场景对比算法本质典型应用场景复杂度特点粒子群算法群体智能搜索连续参数优化、特征选择、超参搜索每轮评估所有粒子O(N*D)模拟退火概率型局部搜索组合优化、布局规划、离散决策迭代次数较多但单次评估便宜卡尔曼滤波最优状态估计轨迹预测、传感器融合、视频目标跟踪线性复杂度适合在线计算PID控制反馈控制播放器码率控制、流量调控、系统稳定性O(1)几乎无计算压力Minimax博弈树搜索棋类AI、对抗策略、游戏平衡指数级需要剪枝优化如果选择题里问“视频播放卡顿时如何平滑码率”那答案思路一定是卡尔曼滤波或PID——因为这类问题本质是“用带噪声的观测实时估计真实状态并做出平滑控制”。再比如“在超参搜索时如何平衡探索和利用”粒子群和模拟退火都是合理的选项要能说清楚它们各自怎么跳出局部最优。这些不是需要你手写完整实现的知识但一定要在场景题里认得出、选得对。3.4 业务场景简答题召回、精排、AB实验的答题框架小红书这类内容平台的业务场景简答题基本绕不开推荐链路。我当时遇到的问题是围绕“如何评估一次推荐策略的上线效果”展开的要求给出方案设计。我的回答框架是这样的首先明确评估目标——是提升点击率、停留时长、还是关注转化率不同目标对应不同指标然后设计AB实验说明分流方式用户级分流还是请求级分流实验组和对照组要保证同分布接着确定核心指标和护栏指标比如核心指标是人均点击次数护栏指标是内容举报率不能上升最后是显著性检验和上线决策标准比如p值低于0.05且效果量达到预期阈值才允许全量。这类简答题没有标准答案但框架完整、逻辑清晰、业务感强的回答比堆砌术语更容易拿高分。我在笔试前专门整理了一个“推荐系统问题回答模板”从问题拆解、候选方案、评估方式、风险控制四个维度组织答案笔试的时候直接套结构效率高很多。4. 提交之前最该检查的细节边界、复杂度与平台规则4.1 边界条件与平台规则笔试题最容易在细节上翻车笔试和平时刷题最大的不同在于平台判题是“黑盒”的。你自己本地跑通了几个用例不代表提交后能AC。我印象最深的一次是在一道数组题里忽略了输入数组长度为1的情况结果在平台上的第一个隐藏用例就挂了。那种感觉非常绝望因为你根本看不到具体是哪个边界条件出了问题。所以我的经验是每道题写完先停下来问自己三个问题——数组为空怎么办数组长度是1怎么办目标值可能是负数或0吗如果涉及大数运算还要考虑整型溢出问题Python还好Java和C选手尤其要注意Long的使用。另外牛客网这类平台经常需要自己处理多组输入有些题要求读完整行而不是单个token输出时注意换行和空格这些细节看似简单但每年都有大量人因为格式问题被判0分。4.2 复杂度的自我评估提交之前先算清楚提交代码之前一定要先估算一下最坏情况下的时间复杂度和空间复杂度。一个简单的准则如果n 10^3O(n^2)基本可以接受。如果n 10^5O(n^2)大概率超时必须优化到O(n log n)或O(n)。如果n 10^7O(n)可能是极限尽量考虑O(log n)或O(1)的解法。涉及递归时注意Python默认递归深度只有1000深搜类的题最好改成迭代或者设置sys.setrecursionlimit。我当时有一道题一开始写的是O(n^2)暴力提交前自测时发现n给到了10^5果断重写。虽然重写花了十几分钟但保住了整道题的分数。这个“提交前复杂度假死”的步骤应该像系安全带一样成为肌肉记忆。4.3 本地调试与在线评测的差异从TLE到AC的排查思路还有一个高频的翻车点是本地IDE和在线评测环境不一致。最常见的问题是本地用了Python 3.9的语法特性比如dict的合并操作符|但线上环境是Python 3.8直接语法报错。所以笔试前一定要确认目标平台支持的Python版本尽量写“保守”代码不要用太新的语法特性。如果提交后遇到TLE超时不要盲目优化常数先把自己的算法复杂度再算一遍。TLE往往不是常数问题而是算法量级错了。比如KMP写成了暴力匹配堆排序写成了每次排序这些都是量级错误再怎么优化局部也救不回来。遇到TLE最优做法是冷静下来重新审题、换解法而不是在原有代码上做无意义的微调。5. 复盘后的三点体会对后续笔面试的实质帮助笔试结束后我花了两天时间做完整复盘不只是记录对错而是把所有题目按知识点重新分类建了一个自己的错题和知识图谱。这个过程带来的收益远不止一场笔试而是直接改变了后续所有笔面试的备考策略。第一点体会是算法题一定要练“思考路径”而不是“背答案”。我看到很多同学刷了几百道题遇到新题还是不会原因就是他只记住了“这题用DP”但没想明白“为什么这题能用DP、状态怎么定义、转移方程怎么推”。我之后每次刷题都强制自己在纸上写三行字暴力思路是什么、瓶颈在哪、怎么优化。这个习惯让我在三面手撕代码的环节里明显比对手稳。第二点体会是机器学习原理的深度比广度重要。小红书这批笔试让我意识到光是“知道AUC是什么”不够要能推AUC的计算公式、能解释它为什么对阈值不敏感、能说明它在样本不均衡时的表现。于是我花时间把逻辑回归、Softmax、AUC、KL散度、注意力机制这些高频原理全部手推了一遍后面面试里遇到手推损失函数梯度的题目基本都能应对自如。第三点体会是业务场景题要多积累答题框架但不要背话术。如果你提前准备过“新用户冷启动怎么做”“推荐评估指标体系怎么搭”这类问题的结构化回答笔试时就能快速组织答案。但如果你只是背了几个专业术语就往上堆判卷人一眼就能看出来。真正有用的是建立一个“拆解问题-给出方案-评估效果-控制风险”的思维模型然后往里填充具体的业务理解。最后再分享一个笔试后的小技巧无论考得好不好当天晚上趁记忆还热乎立刻写下自己能回忆起的每一道题和当时的解题思路。这份“热乎复盘”比你过一周后再整理要有效得多因为它保存了大量细节——包括你做错时的第一反应、卡住的位置、检查时关注的边界条件。这些细节才是下一场笔试真正能用的弹药。我的经验是能走到最后的候选人通常在每一场笔试后都做了这件事区别只在记录的深度和重构的认真程度。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进