2023年秋天,我投了掌阅科技算法岗,还专门找了上一届的面经来刷。等到笔试邮件真正落进邮箱的时候,心里反而踏实了——至少简历这关过了。掌阅这家的笔试风格和字节、阿里那些不太一样,更偏业务落地,算法题虽然也考,但不会刻意刁难人,反倒是一堆和推荐、搜索、文本理解相关的题目占了大头,对于一个做阅读产品的公司来说,这个导向其实非常明确。
如果你也在准备这类内容平台公司的算法岗笔试,我强烈建议你不要只埋头刷LeetCode,而是要花时间搞清楚这家公司到底在用什么算法解决什么问题。掌阅的算法岗笔试,本质上就是一轮筛选,筛掉那些只会背题但不理解业务逻辑的人。接下来我就把这轮笔试的完整复盘、考点拆解和备考建议分享出来,尽量还原当时真实考场上的每一步判断。
1. 笔试整体印象与题型分布
1.1 掌阅算法岗笔试到底考什么
先给大家一个总体的印象:2023年掌阅秋招算法岗笔试是在线进行的,时长90分钟,整体分为两大块,一块是基础算法编程题,另一块是机器学习、深度学习和推荐系统相关的理论题。编程题占比大概四成,理论题占比六成。和很多大厂笔试动辄四道hard级算法题不同,掌阅的编程题难度控制在leetcode中等偏下,基本不考偏题怪题,但理论题覆盖面很广,从经典机器学习到深度学习模型再到推荐系统链路都会涉及。
我印象最深的是,整个试卷从第一题开始就带着一种强烈的“业务感”,比如数据分析题会直接给你一个阅读用户的行为序列,让你推导某个场景下的推荐策略输出。这种题不是靠刷题刷出来的,而是要在平时做项目、看论文的时候有意识地积累业务直觉。所以如果你现在还在大而全地刷算法题,建议赶紧调整节奏,把重心放在机器学习模型原理和推荐系统的实践细节上。
这里也给大家一个参考题型分布表,是我根据记忆整理出来的大致比例,不一定完全准确,但可以帮助你判断复习重点:
| 题型分类 | 大致占比 | 考察重点 | 难度感受 |
|---|---|---|---|
| 编程题(数据结构与算法) | 40% | 数组、字符串、动态规划、贪心、搜索 | 中等偏低 |
| 机器学习理论题 | 20% | 经典模型、损失函数、防止过拟合、特征工程 | 中等 |
| 深度学习理论题 | 20% | Transformer、Embedding、NLP基础 | 中等 |
| 推荐系统场景题 | 15% | 召回、排序、冷启动、多样性 | 中等偏高 |
| 开放性设计题 | 5% | 针对阅读场景设计算法方案 | 有一定区分度 |
这个结构让我有点意外的是,纯粹的数据结构和算法题并没有想象中那么多,但这并不意味着可以轻视。恰恰相反,如果你连编程题都做不顺,后面的理论题再多也救不回来。毕竟算法岗的笔试,代码是敲门砖,模型理论是分水岭,业务理解是加分项。
1.2 从题目反推岗位职责与团队方向
笔试题目其实是一个很好的“岗位情报来源”。我做完掌阅这套题之后,明显感觉到这个岗位背后需要承担的工作,和这家公司的核心业务——数字阅读——是强绑定的。比如题目里频繁出现的书籍推荐、用户阅读偏好预测、搜索关键词匹配,都暗示你入职后做的事情大概率集中在首页信息流推荐、书籍搜索排序、用户画像构建这些方向上。
另外一个细节让我印象深刻:试卷里有两道题都涉及长文本处理,一道是小说摘要生成,一道是长文本分类。这让我确认掌阅的算法团队一定在深耕NLP方向,因为阅读平台上大量内容是长篇连载小说,而且很多书的章节动辄几千上万字,这和新闻、微博那种短文本场景完全不同。如果你对长文本建模没有概念,只熟悉BERT跑个分类这种常规操作,遇到这种题会很容易卡住。
所以我的建议是,准备掌阅笔试之前,先去把它的APP下载下来,花一个周末好好体验一下产品。看看首页的推荐位是怎么排的、书架里的书是怎么分类的、搜索结果是怎么排序的、评论区的情感倾向是怎么分级的。你只有真正理解了产品,才能在做场景设计题的时候言之有物,而不是生搬硬套模板。
2. 基础算法与数据结构——笔试中的硬门槛
2.1 高频考点:排序、KMP与字符串处理
虽然掌阅的算法题难度不算高,但覆盖面还算广。排序算法是肯定跑不掉的,我记得第一道编程题是和堆排序相关,要求你用O(n log n)的复杂度排序一个大量重复元素的数组。这道题其实暗含了一个考点:排序算法的稳定性,以及面对大量重复元素时的时间复杂度退化问题。很多人上来就写Arrays.sort(),但如果你说不清快排在极端情况下的退化原因,这题的隐性分就丢了。
字符串处理也是掌阅笔试的偏爱方向,毕竟做阅读平台,文本就是它的核心资产。我记得有一道题是和KMP算法相关的,给出模式串p="abacaba",要求写出它的next数组计算过程。这道题看起来经典,却非常能检验基本功。如果你只是会背代码而没理解next数组的语义,很容易在计算的时候出错。这里给大家一个口诀式的记忆方式:
next[i]表示的是模式串前缀中子串的最长相等前后缀的长度。这里的“前缀”是包含当前字符i的子串,而“最长相等前后缀”要求前缀和后缀相同,但前缀不包含最后一个字符,后缀不包含第一个字符。
我分享一个我当时的手算过程,大家对照着来感受一下。模式串p = "abacaba",下标从0开始:
- next[0]:对于子串"a",没有真前缀和真后缀,所以next[0] = 0
- next[1]:子串"ab",最长相等前后缀是0
- next[2]:子串"aba",前缀"a"等于后缀"a",所以next[2] = 1
- next[3]:子串"abac",最长相等前后缀是0
- next[4]:子串"abaca",前缀"a"等于后缀"a",所以next[4] = 1
- next[5]:子串"abacab",前缀"ab"等于后缀"ab",所以next[5] = 2
- next[6]:子串"abacaba",前缀"aba"等于后缀"aba",所以next[6] = 3
所以p="abacaba"的next数组是[0, 0, 1, 0, 1, 2, 3]。这个结果如果你能心算出来,KMP这关基本就过了。
除此之外,二分查找、链表反转、二叉树遍历这些也都是常见考点。我建议你把剑指Offer里的经典题刷两遍,再把LeetCode热门100题的简单和中等难度搞定,掌阅算法岗的编程题基本就稳了。
2.2 动态规划与贪心:拉开差距的关键
编程题里最让我纠结的是一道动态规划题,题目大意是:给定一个整数数组,每次操作可以选择一个子数组并将其中所有元素减1,问最少操作多少次能将整个数组变为0。这道题其实是经典的“用最少操作将数组变为0”的变体,本质上可以通过贪心策略,也可以借助单调栈的思想来做,但在考场上紧张状态下很容易绕进去。
我当时先是写了一个双重循环的朴素解法,复杂度O(n^2),最后优化的版本是把问题等价为求“差分数组中正数之和”。这里也提醒大家一个考试技巧:如果一时间想不出最优解,先把暴力解写出来,保证得分,再在草稿纸上推导优化思路。笔试判分通常是有过程分的,一个正确的暴力解很可能比一个思路错误但代码量大的“半成品”拿分更高。
另外一道贪心题也很有意思:有n本书,每本书有一个阅读时间和一个收益值,要求在给定总时间内选择若干本书,使得总收益最大。乍一看是0-1背包的动态规划问题,但仔细读题会发现每本书的阅读时间都是相同的,这时候贪心选择收益最高的书即可。这种“伪装成DP的贪心”是笔试中非常爱考的类型,它考验的是你对问题本质的洞察力,而不是单纯的算法模板记忆。
我自己在刷题的时候,总结出了一个经验:拿到算法题,先不急着写代码,花两分钟问自己三个问题——能不能排序?能不能用双指针?能不能用贪心证明?如果三个问题都推翻,再考虑动态规划、搜索这些更重的算法。这套思路帮我省下了大量时间。
2.3 排序算法的复杂度对比与选型思路
说到排序,这是笔试中无论如何都绕不开的考点,掌阅也不例外。我记得理论题里有一道给出多个排序算法的复杂度和稳定性,让你选择最适合某种数据场景的排序方案。这类题最大的坑在于:很多人只记住了平均复杂度,却忽略了最坏情况复杂度和额外空间复杂度。
这里给大家整理一份实用对照表,直接背下来用就行:
| 排序算法 | 平均时间 | 最坏时间 | 额外空间 | 稳定性 |
|---|---|---|---|---|
| 冒泡排序 | O(n^2) | O(n^2) | O(1) | 稳定 |
| 快速排序 | O(n log n) | O(n^2) | 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+k) | O(n+k) | O(k) | 稳定 |
场景题如果问你“10万条阅读记录按时间排序选哪种”,计数排序或归并排序就是更好的选择,因为阅读时间通常集中在某个范围内,计数排序能轻松跑进线性时间。但如果你只知道快排,就会在这个送分题上失分。这就是我反复强调的:做题不是背答案,而是理解每个算法在真实数据场景下的适用边界。
3. 机器学习与推荐系统——掌阅的重头戏
3.1 经典机器学习理论:从KNN到聚类算法
掌阅笔试的机器学习理论题,并没有刻意追求新潮,反而很注重基础。比如有一道题问KNN算法的三个基本要素是什么,答案是距离度量、K值选择、分类决策规则。看似简单,但很多人只答得出“距离度量”和“K值”,忘了“分类决策规则”。这道题提醒我,经典机器学习算法的复习一定要回归教材,不能只靠项目经验。
聚类算法也是高频考点,尤其是K-Means和DBSCAN的对比。笔试里的一道选择题是这样设置的:给定一组噪声较多的用户行为数据,问选择哪种聚类算法更合适,并说明原因。正确答案是DBSCAN,因为它能识别噪声点,而K-Means对离群点敏感,且需要预设簇数。这种题不是考你背概念,而是让你在具体场景中做算法选型。
我当时还遇到了一道和FM(因子分解机)相关的题,问的是FM相比线性模型和多项式模型的优势是什么。这道题要用到特征交叉的概念来解释:FM通过隐向量内积来建模二阶特征组合,能在稀疏数据下更好地捕捉特征之间的关系。在推荐系统里,用户的阅读历史、点击行为都是高度稀疏的,所以FM以及它后续的DeepFM、xDeepFM等模型在业务中应用很广。掌阅考这个点,说明候选人需要具备特征交叉和稀疏数据建模的基本意识。
3.2 推荐系统核心链路:召回、排序、重排
推荐系统场景题是掌阅笔试里最有区分度的部分。有一道题我到现在还记得很清楚:给定用户过去30天的书籍阅读记录、书籍的分类信息、书籍的热度信息,让你设计一个首页信息流推荐方案。这道题看起来开放,但其实是在考察你有没有完整的推荐系统知识体系。
我的答题思路是先拆链路,再讲细节,最后补策略:
- 召回阶段:可以同时使用协同过滤(基于用户的协同过滤和基于物品的协同过滤)、向量召回(双塔模型生成用户和物品的Embedding,用内积或余弦相似度召回)、热度召回(兜底保证内容多样性)三路召回,最后做融合去重。
- 排序阶段:粗排用轻量模型(如双塔、FM),精排用复杂模型(如DeepFM、DIN),训练数据来自用户的历史曝光和点击日志,样本权重按业务目标调整,比如完读率高的样本权重更大。
- 重排阶段:考虑多样性、新鲜度、频控等规则,避免用户看到的全是同一类型的小说,也避免同一个作者的书籍扎堆出现。
这道题之所以让我印象深,是因为它没有一个唯一的正确答案,而是看你的方案是否有逻辑、是否可落地。哪怕你说用到了强化学习里的Bandit算法做冷启动探索,只要你能自圆其说,面试官也会认可。这也是我在做题时总结出来的经验:场景题不用追求“标准答案”,但要追求“思考框架的完整性”。
3.3 排序与搜索算法:从BM25到Learning to Rank
掌阅有一个搜索业务,所以在笔试中专门考了一道和文本检索相关的题:给定一批书籍的标题和简介,以及用户的搜索query,让你设计一个搜索结果排序方案。这道题的得分点是BM25算法。
BM25是一种经典的文本检索排序函数,它的核心思想是:对于一个查询词,在文档中出现的频率越高,文档得分越高,但同时要考虑文档长度和整个语料库中该词的逆文档频率(IDF)。如果某个词在很多文档中都出现,说明它区分度低,权重应该下调。我当时把BM25的公式写了一遍,然后针对书籍搜索场景做了两点补充:一是引入书籍的热度作为乘法因子,二是对完全匹配标题的结果做加权。这种“算法加业务规则”的组合,才是面试官真正想看到的答案。
顺便提一句,Learning to Rank在搜索和推荐中的应用也是笔试潜在考点,pointwise、pairwise、listwise三种策略的概念最好能熟练说出来。我当时准备了一个对比记忆:pointwise把排序问题转化为回归或分类问题,pairwise比较两两文档的顺序关系,listwise直接优化整个排序列表的损失。掌阅笔试虽然没有直接考这三种策略的细节,但在场景题里如果你能主动提到LTR,能明显提升答案的专业度。
3.4 冷启动与探索利用问题
推荐系统里有一个无论如何都绕不开的问题——冷启动,掌阅笔试自然也考了。题目是这样设计的:一个刚注册的新用户,几乎没有行为数据,如何给他推荐书籍?这个问题让我意识到,我不仅要懂模型,还要懂产品策略。
我当时的回答分了三层:
- 第一层,基于注册信息做粗粒度的个性化。比如用户注册时选择的兴趣标签、年龄段、性别,用这些维度匹配书籍分类。
- 第二层,用热门书籍和编辑精选做兜底。新用户没有行为数据时,推送平台整体热度最高的内容,是最稳妥的方案。
- 第三层,用Bandit算法做探索。给用户展示一批候选书籍,根据用户的即时反馈(点击、加入书架、阅读时长)动态调整推荐策略,在探索和利用之间找平衡。
这个问题背后其实还有一个更深层的考量:冷启动不只是新用户的问题,新书同样有冷启动问题。掌阅作为阅读平台,每天都有大量新书上线,如果推荐系统永远只推老书,新书作者就没有动力继续创作了。所以你在回答冷启动问题时,如果能补充说明“对新书做流量扶持”的策略,会让你的答案更有业务深度。
4. 深度学习与NLP——文本语义理解的底层能力
4.1 Transformer与预训练模型的核心考点
掌阅笔试的深度学习部分,并没有直接让你默写Transformer的公式,而是考了一些更实际的问题,比如:为什么Transformer要使用位置编码?为什么自注意力机制能捕捉长距离依赖?这类题目让我很欣慰,因为这恰恰说明这家公司看重的是你对模型设计动机的理解,而不是背公式的能力。
如果你还没有深入理解Transformer,我建议从“动机”入手来学,而不是直接扎进源码。自注意力机制本质上是在计算序列中任意两个位置之间的相关性,这解决了RNN无法并行、LSTM难以捕捉超长距离依赖的问题。位置编码的引入则是因为自注意力本身是“排列不变”的,如果不加位置信息,模型会把“我打你”和“你打我”当成完全相同的输入。
掌阅笔试里有一道选择题问BERT的预训练任务有哪些,答案是Masked Language Model和Next Sentence Prediction。我在这里多说一句:BERT的MLM是随机mask掉15%的token让模型预测,而不是全部mask,这个细节很多人记不清。而且在实际业务中,像小说这种长文本,直接用BERT去做全篇编码并不现实,更常见的做法是用分段编码,或者用Sentence-BERT生成段落向量,再去做下游任务。
4.2 Word2Vec、Embedding与向量召回
考完掌阅笔试之后,我对Embedding的重要性有了更直观的感受。有一道题是:给定一批书籍的阅读序列数据,如何为每本书生成一个向量表示,并用于相似书籍推荐。这道题实际上就是在让你设计一个Item2Vec的训练方案,本质上是把Word2Vec的思想迁移到书籍序列上。
我当时给出的方案是:把每个用户在某段时间内阅读过的书籍按时间顺序排列,形成一条“句子”,然后把书籍当作“单词”,用Skip-gram或CBOW训练得到书籍的Embedding。训练好之后,计算两本书Embedding之间的余弦相似度,就能作为相似书籍推荐的基础。
这道题的延展考点是向量召回:你可以在召回阶段先用向量相似度从海量书库中粗筛出Top200候选,再进入排序模型精排。这种“向量召回加精排”的两阶段架构,是当前工业界推荐系统的标配,掌阅考这道题,说明它的技术栈是紧跟主流趋势的。
4.3 长文本建模与阅读场景的NLP应用
掌阅笔试里有一道开放性设计题,让我至今记忆犹新:如何为一本连载中的网络小说自动生成章节摘要。这道题包含了两个难点,一是文本长度很长,二是连载小说的信息是逐步累积的,早期章节的信息可能对后续摘要很重要。
我当时的思路是分层处理:先把章节按段落分块,用预训练模型生成每个段落的向量表示,然后对段落向量做聚类或关键句抽取,选出信息密度最高的几个段落,最后用生成式模型把选出的段落内容压缩成摘要。这个方法虽然不算新颖,但至少能落地,而且针对超长文本,你不能一口气把整章塞进模型,分治是必然选择。
这道题给我的启发是:掌阅的算法团队一定花了不少精力在长文本建模上,因为网文的平均长度远超普通新闻和社交媒体文本。如果你有幸进入面试环节,提前准备一些长文本建模的项目经验,会是非常大的加分项。
5. 备考策略与经验复盘——我的踩坑总结
5.1 时间分配:刷题、理论和业务的平衡
回顾整个掌阅笔试的备考周期,我觉得最值得分享的教训是:时间分配比天赋重要得多。我在复习初期花了大量时间刷LeetCode hard题,结果发现掌阅笔试的编程题难度根本到不了hard,反倒是机器学习理论和推荐系统场景题占了很大比例。如果我一开始就能按照“40%刷题、40%理论、20%业务”的比例来安排时间,应该能轻松很多。
具体的备考路线,我建议分成三个阶段。第一个阶段(提前三周):集中刷数据结构与算法,重点复习数组、字符串、链表、树、动态规划、贪心这六大块。第二个阶段(提前两周):系统回顾机器学习和深度学习的核心概念,包括经典模型的推导、损失函数的设计、过拟合的解决方案、Embedding的原理。第三个阶段(提前一周):针对目标公司做业务调研,下载APP体验产品,研究推荐方向和搜索方向的技术方案。
我笔试前一周还专门做了个动作:把掌阅过去半年的技术博客、招聘宣讲和公开分享看了一遍,整理出了一些和业务相关的技术关键词。没想到笔试中真的有两道题可以用上这些信息,一道是关于长文本摘要的,一道是关于用户兴趣演进的。做产品公司的笔试题,了解产品真的不是玄学。
5.2 考场上的时间控制与答题策略
在线笔试最大的风险是时间失控。掌阅这套题90分钟,我实际写完编程题已经用了40分钟,理论题只能加快速度。这里给大家一个非常实用的建议:拿到卷子先花2分钟快速浏览所有题目,把每道题的价值和难度做一个初步判断,然后按“先易后难、先高分后低分”的顺序作答。
编程题我强烈建议先写一个能跑通的暴力解,再尝试优化。有些同学一上来就想写最优解,结果卡在细节里,最后连暴力解都没写完,这是最可惜的。理论题遇到不会的也不要空着,尽量写一些相关的知识点,阅卷老师能看到你的思维过程,会给出一定的步骤分。
还有一个小技巧是,多利用题目给的样例来理解题意。掌阅笔试中有一道题要求你实现一个带过期时间的缓存,样例输入输出已经能反推出数据结构和算法逻辑了。如果你没看懂题面,先跑一遍样例,能帮你节省大量读题时间。
5.3 复盘:笔试后的自我评估与下一步准备
笔试结束之后,我花了一个晚上认真复盘了整套卷子。我给自己列了一个查漏补缺清单,哪道题是应该做对的却做错了,哪道题是完全不会的后续需要补,哪道题是虽然做对了但效率不高的。这份清单直接指导了我后续的面试准备,尤其是把推荐系统链路和长文本建模这两块知识反复巩固了一遍。
如果你考完笔试之后收到了面试通知,恭喜你,接下来大概率会有两到三轮技术面试,重点会围绕你的项目经历、算法推导能力和业务理解展开。笔试中没答好的题目,面试官很有可能会追问,所以复盘就显得格外重要。我能通过掌阅的后续面试,很大程度上就归功于考后那晚的认真复盘。
最后再分享一个我个人的小习惯:每次笔试或者面试之后,我都会把遇到的新题目和新的解题思路整理到一个专门的文档里,按知识点打标签。平时不觉得有什么,但秋招战线拉长之后,这份“题库”就成了我最宝贵的备考资料。你要是现在还在秋招途中,建议也从今天开始,建立属于自己的题库笔记,坚持记到最后一轮面试结束,你会感谢自己这个决定的。