十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

小红书2020校招算法笔试题全解析:考点、题型与备考策略

小红书2020校招算法笔试题全解析:考点、题型与备考策略 小红书2020校招算法笔试题卷三我拿到手之后整体刷过两遍也拿它给身边准备秋招的朋友做过模拟。这套卷子在当年的校招题库里属于风格比较典型的那一类算法题占比高、机器学习基础考得细、场景题非常贴近内容平台的业务逻辑和单纯刷LeetCode的感觉完全不一样。如果你正准备算法岗的校招或者想看看内容社区公司筛人的技术口味这份拆解应该能帮你少走不少弯路。我会按整套卷子的考点分布、每类题型的解题思路、以及实际操作中容易踩的坑三个层面来讲中间会穿插一些代码和推导方便直接对着练。1. 这套卷子的整体画像考点分布与设计逻辑1.1 题型结构与分值算法题占大头机器学习紧随其后整套卷子给我的第一感受是它不是一个单纯考“会不会写代码”的卷子而是一个“能不能上手解决实际问题”的筛选器。题型大概可以分成四块数据结构与算法题、机器学习基础题、深度学习概念题、业务场景题。从分值上看算法题占了最大头大约40%的分量集中在数组、字符串、动态规划、贪心这些经典类别上。机器学习基础题紧随其后大概占30%重点考的是模型原理、损失函数、优化方法这类不背熟就容易翻车的内容。剩下的深度学习概念和业务场景题各占15%左右看似占比不高但往往是拉开差距的地方因为场景题没有标准答案考察的是你把算法思想落地到真实业务的能力。这个配比其实很有代表性。算法题能快速筛掉代码功底不扎实的候选人机器学习基础题能看出你是不是真的理解模型而不只是会调包场景题则是检验你在信息流推荐、内容分发这类业务里能不能把技术用对地方。如果你只刷LeetCode而忽略机器学习基础或者只背八股文而代码写得磕磕绊绊在这套卷子里都会暴露得很明显。1.2 考点背后的业务逻辑内容平台到底想招什么样的人这套卷子出题风格之所以偏“业务”和这家公司的基因有很大关系。内容社区的核心业务是推荐分发、多模态内容理解、用户增长和搜索这些都依赖算法工程师对数据和模型有扎实的理解。笔试里出现概率统计题、ML基础题并不是为了为难你而是这些能力在真实业务里真的会被高频使用。比如排序题考堆排序表面上是考数据结构实际上是在为 TopK 问题做铺垫——在推荐系统里你需要从海量候选物品中快速挑出得分最高的那一批堆排就是最高效的思路之一。再比如动态规划题在业务里可能对应的是流量分配、成本优化这类带约束的决策问题。也就是说每道题背后都站着一个真实的业务场景把这些连接起来看你就明白为什么要这么考了。我当时复习的时候也走过弯路前两周全在刷LeetCode结果刷到后面发现机器学习基础题一旦展开问自己的回答就变得很虚。后来调整了策略算法保持每天两三道的手感但把更多时间花在把模型原理推导清楚上效果明显好了很多。所以如果你也在准备这类公司的笔试建议从一开始就两条腿走路算法题保持手感理论基础同步加深。1.3 答题时间分配如果我在考场上会怎么做整套卷子的标准时长是90分钟题量大概在12到14道左右包含选择题、简答题和编程题。时间分配上我个人建议选择题控制在25分钟以内简答题控制在30分钟左右最后的编程题留出30到35分钟。选择题里有一些是硬记型考点比如某个算法的时间复杂度、某个函数在某库里的默认参数这类题会就是会不会也别纠结太久先选一个标记好回头再想。简答题重在展示思路不需要像写论文一样长篇大论把关键公式、关键步骤、关键理由写清楚就行。编程题是最容易因为时间不够而丢分的哪怕思路完全正确提交的时候代码没写完也是零分所以一定要给足时间。我见过不少同学在前面选择题上死磕一道拿不准的题结果后面编程题只剩十分钟这种情况特别可惜。我自己做题的习惯是先把所有题目快速扫一遍心里对每道题的难度有个数然后按先易后难、先分值高后分值低的顺序做确保确定性强的分数先拿到手。2. 高频数据结构与经典算法题详解2.1 KMP的next数组一个字符串题就能筛掉大多数人这套卷子里出现了一道很典型的字符串题模式串 p abacaba要求手算 next 数组。这个题表面上是考KMP实际上是在考察你是否真正理解了“最长公共前后缀”的概念而不只是背过KMP的模板。先把 next 数组的定义说清楚。next[i] 表示在模式串的前缀 p[0...i-1] 中除去自身之外的最长相等前后缀的长度。注意它和 nextval 数组是有区别的校招笔试里如果没有特别说明默认考的是 next 数组而不是优化后的 nextval。对于 p abacaba我们按前缀逐个计算i 0next[0] -1或0取决于不同教材约定这里用-1 i 1前缀 a没有真前后缀next[1] 0 i 2前缀 ab没有相等前后缀next[2] 0 i 3前缀 aba最长相等前后缀是 a长度1next[3] 1 i 4前缀 abac没有相等前后缀next[4] 0 i 5前缀 abaca最长相等前后缀是 a长度1next[5] 1 i 6前缀 abacab最长相等前后缀是 ab长度2next[6] 2 i 7前缀 abacaba最长相等前后缀是 aba长度3next[7] 3最终 next 数组是[-1, 0, 0, 1, 0, 1, 2, 3]这里next[i]表示前 i 个字符组成的子串的最长相等前后缀长度是主流的“字符串中 next”约定。实际笔试中还有一个高频变体给你一个字符串求它的所有前缀里有多少个前缀同时也是某个后缀且长度不为0。这种题本质上也是KMP的 next 数组应用你算出 next[n]再沿着 next 链往上走每走一步的长度值都是一个满足条件的前后缀长度。考场经验KMP的代码可以不要求一次写对但 next 数组的手算一定要全程无卡顿。多练几组不同的模式串比如 aaaaab、abcabcabc 这类带重复特征的算得多了才能真正理解规律而不是靠记忆硬背。我当年就在这里吃过亏背熟了模板却算不对 abacaba 这种带交叉重复的串后来才明白问题出在没有真正理解 next 的递推过程。2.2 动态规划与贪心边界条件和状态定义决定成败这套卷子里的动态规划题不算难但非常经典考的是最长递增子序列LIS和背包类问题。这类题的技术含量不在于“会不会套模板”而在于状态定义是否清晰、边界条件是否考虑周全。比如一道简化版的最长递增子序列问题给一个数组nums求最长的严格递增子序列长度。最常规的 DP 解法时间复杂度是 O(n²)def length_of_lis(nums): n len(nums) if n 0: return 0 dp [1] * n for i in range(n): for j in range(i): if nums[j] nums[i]: dp[i] max(dp[i], dp[j] 1) return max(dp)不过如果面试官追问“能不能优化到 O(n log n)”你就得会用辅助数组加二分查找的贪心思路。这其实是 LIS 的经典优化用一个tails数组维护当前长度下最小的末尾元素然后对每个元素二分查找插入位置。笔试中如果限时O(n²) 的写法足够拿分但如果你能写出 O(n log n) 的版本印象分会高很多。再比如背包类问题核心在于区分 0-1 背包和完全背包。0-1 背包要求物品只能选一次所以内层循环要逆序遍历容量完全背包物品可以选多次内层循环要正序遍历。这个“正序还是逆序遍历”的细节是笔试中出现频率最高的易错点。很多人在电脑上写代码时能跑通但换成手写代码或者在纸上写就容易把遍历方向搞反白白丢分。贪心题在卷子里相对简单但容易犯一个错误看到局部最优就以为是全局最优没有证明就直接用。考场上比较稳妥的做法是先用反例验证一下贪心策略是否成立再决定是否采用。比如区间调度类问题按结束时间排序的贪心是被证明过的经典解法可以直接用但有些变种的区间覆盖问题按开始时间排序就是不成立的需要重新分析。2.3 手写排序与堆考的不是会不会而是写得多干净我在卷子里看到了一道要求手写堆排序的编程题输入是一组无序数组要求输出前K大的元素。这道题其实是“堆排序 TopK”的组合也是校招笔试里非常高频的一道综合题。最朴素的思路是把整个数组排序然后取前K个时间复杂度 O(n log n)。但如果你在堆排序的基础上用大小为K的最小堆时间复杂度能降到 O(n log K)在K远小于n的场景下优势很明显。代码实现如下import heapq def top_k(nums, k): heap [] for num in nums: if len(heap) k: heapq.heappush(heap, num) elif num heap[0]: heapq.heapreplace(heap, num) return sorted(heap, reverseTrue)注意这里用的是 Python 的heapq默认是最小堆。如果你用 Cpriority_queueint, vectorint, greaterint就是最小堆不要随手写成默认的最大堆。这个细节看起来小但真的有不少人在写的时候搞混导致输出的正好是前K小。除了堆排序快速排序也是笔试题里的常客。手写快排的时候最容易出错的是分区函数的边界。比如用 Lomuto 分区还是 Hoare 分区退化成 O(n²) 的情况怎么避免。我自己更推荐在笔试中写 Hoare 分区的快排因为它的交换次数更少而且退化概率相对低一些。但你要把两种分区的代码都练熟因为有的面试官会有自己习惯的写法你得能看懂他的代码。排序题想拿高分光会写是不够的。你得对每种排序的时间复杂度、空间复杂度、稳定性、适用场景都烂熟于心。我当时做了一张表贴在电脑旁边每天睡前扫一遍后面笔试里遇到“哪种排序算法是稳定的”这类选择题基本就是一秒出答案。3. 机器学习与深度学习基础题拆解3.1 从经典模型到激活函数概念题也要会推导这套卷子的机器学习题覆盖面很广从线性回归、逻辑回归到SVM、决策树都有涉及。有一个比较有代表性的简答题是解释逻辑回归的损失函数为什么用交叉熵而不是均方误差并写出梯度推导过程。这是一个非常经典的考题核心答案可以概括为两点第一逻辑回归的最终输出经过了 sigmoid 映射如果使用均方误差损失函数关于参数的梯度里会包含 sigmoid 的导数项而 sigmoid 在两端区域导数接近0会导致梯度消失收敛速度极慢第二交叉熵配合 sigmoid求导之后形式非常简洁梯度的大小直接跟预测值与真实值的差成正比优化起来更高效。推导过程也不复杂。假设二分类问题预测值为 ŷ σ(w·x b)真实标签为 y ∈ {0,1}交叉熵损失为L -[y log(ŷ) (1-y) log(1-ŷ)]对 w 求导利用 sigmoid 的导数性质 σ(z) σ(z)(1-σ(z))最后会得到∂L/∂w (ŷ - y)·x这个形式说明当模型预测接近真实值时梯度接近于零当预测错误时梯度较大非常符合直觉。笔试里如果你能把这一步推导写出来基本上这题就是满分。类似的考点还有为什么 ReLU 比 sigmoid 更适合深层网络、softmax 和交叉熵组合的数值稳定性问题、SVM 的核函数选择等。这些都属于需要“会推导”而非“会背诵”的范畴建议你在复习时拿一张白纸不看任何资料自己把每个模型的推导流程写一遍写不出来的地方就是你的知识盲区。3.2 优化器与损失函数选型背后的数学直觉卷子里有一道关于优化器的问题要求比较 SGD、Momentum、RMSProp、Adam 的异同并说明在实际训练中如何选择。这种题看起来是问概念其实是在看你有没有真正跑过模型、调过参数。SGD 是最朴素的梯度下降方法不稳定但有时能跳出局部最优Momentum 加入了对历史梯度的累积能让更新方向更平稳适合损失曲面比较崎岖的情况RMSProp 对每个参数使用不同的学习率适配不同维度的梯度尺度Adam 则是把 Momentum 和 RMSProp 结合起来自带一阶动量估计和二阶动量估计还有偏差修正机制大部分场景下默认选它都不会出大错。但也别把 Adam 当万能药。我在实际项目里遇到过一个情况某个模型用 Adam 训练loss 一直降不下来换成 SGD 配合 momentum 之后反而收敛得更稳定。原因在于 Adam 的适应性学习率会掩盖一些需要精细调节的梯度信号而 SGD 则强制模型走一条更“保守”但更“自觉”的路。笔试里如果让你说说实际经验能讲出这类具体的对比案例会比干巴巴地背定义有说服力得多。关于损失函数这套卷子还考了 MAE 和 MSE 的区别。核心要点是MSE 对离群点敏感因为误差是平方量级MAE 对离群点更鲁棒梯度始终是一个常数不会因为误差大而梯度爆炸。但 MAE 在零点不可导这是一个隐藏考点很多人会忽略。3.3 推荐系统场景题把算法落到内容分发上小红书这类内容平台笔试里的场景题绕不开推荐系统而这套卷子也确实在最后留了一道开放题如果视频播放完成率显著下降你会如何排查和优化。这种题没有标准答案但考官想看到的是你有没有一套完整的分析思路。比较稳妥的回答结构是分三步。第一步先确认指标下降是真实的还是数据问题比如是不是埋点上报有延迟、是不是口径有变动、是不是某些异常流量在干扰。第二步对问题做归因可以从“用户侧、内容侧、系统侧”三个维度拆解用户侧看是不是特定人群的下降更明显内容侧看是不是某些品类的视频天然时长变长导致完成率下降系统侧看是不是推荐排序策略发生了变化。第三步提出具体的实验方案和迭代方向比如调整召回策略、引入新的时长预估模型、优化视频封面和标题的匹配度等。这种开放题的答题节奏也很重要。千万不要只写一两行结论就停笔要写出你的分析框架和排查步骤哪怕有些步骤在真实工作中不一定会用也要展现你的逻辑完整性。面试官看重的是“你对业务指标有没有敬畏心”、“你的分析会不会一上来就动模型”而不是“你能不能立刻给一个最优解”。3.4 概率统计与业务题一个贝叶斯题能看出基本功概率统计在这套卷子里虽然不是大头但每道题都出得很巧。我印象最深的是这样一道题某内容平台上一篇文章被点击的概率为 P(A)0.2被点赞的概率为 P(B)0.1既被点击又被点赞的概率为 P(A∩B)0.05。求在已知文章被点击的条件下它被点赞的概率。这就是最基础的贝叶斯公式应用P(B|A) P(A∩B) / P(A) 0.05 / 0.2 0.25这道题的考点在于能不能分清条件和联合概率的区别。很多人在笔试里看到这种题第一反应是去套复杂的公式反而忽略了这个最直观的比值关系。实际上条件概率的定义就是 P(B|A) P(A∩B) / P(A)只要把分子分母找对了答案自然就出来了。另一类高频概率题是“生日悖论”的变种比如一个用户分布有多少人时存在两个人在同一天浏览同一个内容的概率超过50%。这类题考的是对概率互补事件的理解先算所有人都互不相同的概率再用1去减。推导过程也不复杂但能完整写出来的人确实不多。概率统计题还有一个隐藏考点期望的线性性质。比如求随机变量和的期望即使它们之间不独立和的期望也等于期望的和。这个性质在分析推荐系统的累积指标时非常有用如果能在场景题里主动提出来会显得你数学功底比较扎实。4. 真实复盘易错点、套路与备考建议4.1 我见过的最可惜的失误准备校招笔试的时候我最常听到的遗憾是“题目会做但看错了条件”。在校招笔试的限时压力下看错条件太容易发生了而且往往发生在那些你觉得自己一定会的题目上。常见的失误包括题目要求输出“逆序排列”结果你按正序输出题目说“非递减”你按“严格递增”处理题目说“可能包含重复元素”你的代码没处理重复题目说“数据范围很大可能溢出”你还在用 int。这些细节错一个可能整道题的分就没了非常可惜。有一个非常有效的应对方法做题前先把题目的输入输出样例跑一遍把样例输入代入你的思路一步一步推演确认每一步都跟样例输出对得上再开始写正式代码。这就像写文章之前先列大纲看着慢实际上能省很多返工的时间。我自己的习惯是每道题写完代码之后先不要急着提交花十秒钟检查这三个点一是空数组、空字符串时会不会报错二是只有单个元素时能不能跑通三是数据规模大时时间复杂度和空间复杂度是否可接受。这三个点检查完之后代码的质量基本上就有保障了。4.2 这些隐藏考察点比题目本身更重要笔试不仅能看出你会不会做某道题还能看出你有没有工程师的基本素养。比如变量命名、代码缩进、注释质量这些在纸面笔试里不直接加分但会给阅卷人留下“这个人代码功底不错”的隐性印象。我在帮别人做模拟面试的时候发现很多候选人代码逻辑没问题但函数命名用的是a、b、c循环变量全是i嵌套j嵌套k整个代码读起来像在解谜。要是笔试是机器判题还好如果是人工阅卷这种代码的观感就会打不少折扣。一个简单的建议是函数名用动词开头比如getMaxValue、buildNextArray变量名用有含义的名词比如count、idx、dp这样不仅阅卷人看得舒服你自己调试的时候也不会晕。隐藏考察点还有一个边界条件的完整度。一道编程题如果只过了普通例子但边界情况全挂那机器判题的时候分数会很难看。因此平时练习的时候就要养成一个习惯每做完一道题主动构造边界测试用例比如空输入、只有一个元素、全部相等、逆序排列等把这些情况全部跑通再算真正做完。4.3 如果重来一次我会怎么准备说了这么多踩坑的经历最后聊点方法论层面的东西。如果把准备周期拉长到三个月我会把复习分成三个阶段。第一阶段第一个月打基础主攻数据结构与经典算法把线性表、树、图、排序、查找、DP、贪心、回溯这八类问题的基础题全部过一遍同时把机器学习基础中的线性模型、决策树、SVM、贝叶斯、集成学习这些内容的原理推导一遍做到合上书能自己推公式。第二阶段第二个月刷综合开始按套卷做题每周至少完成两套完整的校招笔试真题不限时地做但每道题都要写代码并跑通。然后分析错题把错题归类比如“边界条件错误”、“状态定义不清晰”、“时间复杂度超限”等针对性地补弱。第三阶段第三个月模拟冲刺严格按照考场的时长和环境来模拟到时间就停笔模拟完再复盘。这个阶段的重点是训练时间分配和心理素质。我见过很多平时实力不错的人一到限时环境就慌原本会写的题都写不出来模拟考就是专门治这个的。对于“要不要刷遍所有题”这个问题我的答案是没必要。校招笔试的考点非常集中反复出现的就是那几十个核心知识点你只要把每个核心知识点吃透、做熟比盲目刷五百道题有效得多。关键不在数量而在复盘的质量。这套卷子刷下来我自己最大的收获是意识到一件事算法岗的笔试考的从来不只是算法。它是代码能力、数学功底、工程习惯和业务理解这几项能力的综合检验。每道题背后都在考察你未来能不能在真实业务里解决问题而不只是今天能不能AC一道题。抱着这个心态去复习你走的每一步都会更扎实。
返回列表