2023年腾讯音乐秋招技术研究岗第二批笔试,我是在九月中旬的某个晚上参加的。当时投的是TME的推荐算法方向,岗位名称叫“技术研究”,但实际做的东西和推荐系统、用户增长、内容理解都沾边。笔试用的是牛客的在线平台,双机位监控,三个小时,题量不算小,整体难度在当年的互联网大厂笔试里属于中上水平。这篇东西我就按自己的回忆和复盘来写,尽量把题型、考点、踩坑都讲清楚,给后面准备TME或者类似音娱公司算法岗的同学一个参考。
1. 笔试整体体验与题型分布
先说整体感受:TME的第二批笔试和我之前做的其他厂子风格不太一样,它更偏向“工程+算法”的结合,而不是纯刷题。
我当时拿到的卷子大概是四个部分:选择题、算法编程题、问答论述题、以及一道开放性系统设计题。总时长180分钟,但我实际做完只剩不到20分钟检查,时间非常紧张。选择题大概20道,单选多选混合,覆盖机器学习基础、深度学习、数据结构、概率统计和一小部分音频相关的信号处理常识。编程题三道,分值占比最高,其中两道是LeetCode中等偏上难度,一道是偏业务场景的模拟题。问答论述题两道,一道是模型调优类,一道是推荐系统策略类。最后一道系统设计题是给一个具体的音乐场景,让你设计方案。
从分值结构来看,编程题大约占40%,选择题占20%,问答和设计题占40%,所以纯coding能力强的人能拿基础分,但真正拉分的反而是后面那两道论述题和设计题。这一点我觉得是TME笔试和字节、阿里等偏重算法的笔试最大的区别,它非常看重你对业务场景的理解,而不只是模型能力。
时间分配上我吃了点亏。选择题我花了大概30分钟,编程题用了70分钟左右,但第三道题卡了挺久,最后问答和设计题只剩不到50分钟,写得比较赶。如果再来一次,我会把选择控制在20分钟内,给后面的设计题多留15分钟。
2. 选择题与基础知识点解析
选择题这部分,说难不难,但有几个点很刁钻,尤其是多选,错选一个就全错,拿分并不容易。我把能回忆起来的题型归了一下类,基本集中在以下几块。
2.1 机器学习与深度学习基础
这部分考得很常规,但要注意细节。比如有一道题是关于Bagging和Boosting的区别,选项里设置了一个很坑的干扰项:“Bagging可以降低模型的偏差,Boosting可以降低模型的方差”。这个说法就是错的,正确理解是Bagging主要降低方差,Boosting主要降低偏差。如果你只是背概念而没理解背后的数学原理,这道多选就很容易选错。
还有一道题是关于Batch Normalization的,问它在训练和推理时的差异。这个我印象很深,因为选项里说“推理时使用当前batch的均值和方差”和“推理时使用训练阶段累计的全局统计量”,正确答案是后者。很多同学如果不做推理部署,真的会忽略这个细节。如果你为了准备笔试去刷面经,这类题几乎是必考的,建议把BN、LayerNorm的原理彻底搞懂。
2.2 概率统计与数据结构
有一道概率题大概是这个意思:一个音乐App的日活用户中,每天听歌超过30分钟的用户占40%,在这部分用户中,开通会员的比例是30%,而在听歌不足30分钟的用户中,开通会员的比例只有10%。随机抽一个用户,发现他开通了会员,求他每天听歌超过30分钟的概率。
这就是典型的贝叶斯公式题。P(A|B) = P(B|A)P(A) / P(B),其中P(A)=0.4,P(B|A)=0.3,P(B)=0.4×0.3+0.6×0.1=0.18,所以结果就是0.12/0.18=2/3。这种题难倒是不难,但考场上容易在算P(B)的时候漏掉用户分组,建议列个表格算,别心算。
数据结构部分有一道是关于红黑树和AVL树的对比,问在插入操作频繁的场景下哪个更合适。答案是红黑树,因为AVL树的平衡条件更严格,插入删除时旋转次数更多,虽然查询更快,但写入开销大。这道题如果只是背“红黑树是近似平衡”是不够的,还得理解为什么。
2.3 音频与信号处理常识
这部分大概是TME笔试的特色了。有一道题是关于音频采样率的,问的是“CD音质标准的采样率是多少”,答案是44.1kHz,选项里还混了48kHz和96kHz,后者常见于视频制作和高解析度音频,但CD标准就是44.1kHz。还有一道题问“傅里叶变换在音频分析中的作用”,选项有“提取音高”“去除噪声”“压缩音频”“识别乐器”,根据上下文选相关项。说实话这题不算难,但对纯推荐算法方向的同学来说可能有点冷门,我当时也是凭常识做的。
我的建议是,如果你的方向不是音频算法岗,不用花太多时间在这块,分值占比不高,把基础的采样定理、频谱概念搞明白就够了。
3. 编程题全解析:算法与数据结构的实战
编程题是整场笔试的重头戏,直接影响你能不能进下一轮。TME的三道题我回忆了一下,基本覆盖了“基础数据结构 + 二分/贪心 + 场景模拟”这三个层级。
3.1 第一题:链表重排
这道题我记得很清楚,是给一个单链表,要求按照“头节点、尾节点、第二个节点、倒数第二个节点”的顺序重新排列。比如链表是1->2->3->4->5,重排后变成1->5->2->4->3。
思路其实不复杂:先用快慢指针找到链表的中点,把后半部分反转,然后交替合并两个链表。这道题的核心考点就是“找中点 + 反转链表 + 合并链表”三步走,每一步都是链表题的基础操作。
我当时用的Python,写的时候没有用额外数组存储节点值,而是直接改指针,这样空间复杂度是O(1)。我见过一些同学直接用列表存节点再重建链表,虽然也能过,但在面试官眼里观感会差一些,可能影响后续面试的评价。如果你时间充裕,建议把这种链表题的“原地操作”练熟,笔试时能加分。
注意:这类需要修改链表结构的题目,写完一定自己走一遍“奇数节点/偶数节点”的边界case,偶数节点时合并操作的终止条件特别容易写错。
3.2 第二题:区间合并的变种
第二题是一个区间合并的变种,大概是给一组歌曲的播放时间段,每段用[start, end]表示,要求合并所有重叠的区间,并返回合并后的总时长。力扣上有个原题叫“合并区间”,但这题多了一个变化:有些区间的end是开区间,有些是闭区间,需要分开处理。
如果全是闭区间,先按左端点排序,再遍历处理就行。但开闭区间混合后,边界条件就复杂了。比如[1,5]和(5,10]应该算作有重叠,因为5这个点是闭的;但[1,5)和[5,10]就不重叠,因为你没有覆盖到5。我当时用了一个技巧:把开区间转换成小数。比如[1,5)变成[1, 4.999...],(5,10]变成[5.001, 10],这样就把所有区间统一成闭区间处理了。精度上注意用分数或epsilon来控制。
这个技巧是我在准备笔试时学到的一个骚操作,用在这里意外地好用。但要注意,如果后台测试数据比较严格,浮点数误差可能成为问题,保险起见可以用分数处理或者写一个比较函数。
3.3 第三题:模拟题——弹幕系统
第三题是一道场景模拟题,大致需求是:一个直播间的弹幕系统,要求实现两条功能,发送弹幕和查询某个时间点的弹幕列表。但有个限制,每个用户每10秒只能发一条弹幕,发送时如果违反了频率限制就丢弃。查询时,需要返回从当前时间往前推30秒内的所有弹幕,按时间从早到晚排序。
这道题本身逻辑不难,但实现的时候很容易绕晕。因为发送和查询是交替进行的,你得维护一个数据结构,既要支持高频插入,又要支持按时间窗口清理数据。我当时用的是队列来存弹幕记录,用字典存每个用户最近一次发送时间。队列只保留30秒内的弹幕,每次查询前先把队首过期的数据弹出。这样查询的时候直接遍历队列就是有序的。
这题的核心考点其实是“滑动窗口 + 哈希表”,不是什么高级算法,但如果你用list存所有记录然后每次查询都遍历,时间复杂度就顶不住了。约3秒就要查一次,查询窗口内弹幕数可能上千,遍历一次问题不大,但如果有10万次查询就超时了。我当时队列+哈希的解法,每次查询的时间复杂度是O(k),k是窗口内弹幕条数,整体没问题。
心得:TME的编程题不会刻意出那种“一看就知道是某道力扣原题”的题,而是把常见的算法包装到业务场景里。这个思路和很多大厂笔试是一致的——他们想看的是你在有业务约束的情况下,能不能把基础算法用好。
4. 问答论述题:模型调优与推荐策略
问答论述题是最能拉开差距的部分,因为编程题大家都能写个七七八八,但论述题如果你没有实际项目经验,很难写出有深度的答案。我当时拿到两道题,一道是关于模型调优的,一道是关于推荐系统冷启动的。
4.1 点击率模型线上线下不一致的排查思路
这道题问的是:你训练了一个点击率预估模型,离线AUC表现很好,但上线后点击率没有提升,甚至下降了,请分析可能的原因并给出排查思路。
这道题非常经典,几乎是所有推荐、广告岗位的必考题。我答题的时候分了几层来写:
第一层,先怀疑特征一致性。线上和离线用的是否是同一套特征?有没有特征穿越,比如把未来信息当特征用了?有没有特征拼接逻辑不一致,比如离线用了标准化,线上忘了做?
第二层,怀疑样本分布不一致。线上遇到的样本和离线训练集的分布是否有偏移?比如离线训练数据是过去30天的,但用户的兴趣已经变了。如果是这种情况,可以引入在线学习或者做周期性重训。
第三层,怀疑模型本身的问题。比如离线AUC高但线上没提升,可能是模型过拟合了历史数据,泛化能力差。可以结合GAUC、AUC等指标做分层分析,看是不是只在某些用户群体上有效,整体被平均掉了。
第四层,怀疑实验设计和评估指标的问题。比如上了模型但流量分配不均匀,或者观察时间太短,点击率波动还没收敛。这时候要检查实验AA组的稳定性和置信区间。
这题我答得不算特别出彩,但亮点在于我把排查过程写成了“从特征到样本、从模型到实验”的递进逻辑,能体现实际问题排查的系统性。我后来在腾讯音乐的面试复盘里也把这个思路复用了一次,面试官反馈比较好。
4.2 新歌冷启动的推荐策略设计
第二道论述题更有业务感:平台上新歌很多,但大部分新歌没有用户行为数据,如果让它们参与推荐,怎么设计一套冷启动策略,保证新歌有露出机会,又不至于伤害用户体验。
这道题我先拆解了“体验”和“冷启动”的矛盾——新歌没有数据,模型预估不准,推荐出去用户不爱听,就会拉低时长和留存,但完全不推新歌,平台的内容生态就会僵化。所以核心就是“怎么在探索和利用之间做权衡”。
我的方案分了三条线:
线上一条,用Content-based策略兜底,提取新歌的音频特征(比如节奏、曲风、人声特征),计算和用户历史偏好歌曲的相似度,把相似度高的新歌推到用户的候选池里,但限制曝光占比,比如不超过10%。
第二条线,利用Bandit算法做探索,比如Thompson Sampling,给新歌一个较高的探索概率,根据用户的实时反馈(点击、完播、收藏、跳过)更新beta分布参数,好歌迅速提权,差歌快速降权。
第三条线,用冷启动迁移学习,把相似艺人的历史歌曲行为迁移到新歌上,或者用老歌做数据增强,训练一个“歌曲embedding”模型,让新歌在向量空间里有位置,再靠向量召回进入推荐链路。
最后我还加了一个兜底机制:新歌的曝光位控制在“非首屏”的次推荐位,并且加入时间衰减因子,如果一首歌曝光多次但反馈数据一直很差,就提前结束探索,减少用户体验损伤。答题时我强调这是一个“分层决策”系统,不是单点策略。
现在回头看,这题我答得比较好的原因在于,我不只是堆了一些名词,而是给出了“曝光控制、实时反馈、效果兜底”的闭环逻辑。这是面试官真正想看到的。
5. 开放性设计题:音乐场景下的个性化歌单生成
最后一题是一个综合设计题,和前面的论述题不同,它更偏系统整体架构。题目大概是:用户每天打开App,在“每日推荐”板块看到的歌单是由算法生成的,假设你是这个系统的负责人,请设计一套完整的歌单生成方案,要求覆盖数据收集、候选集生成、排序模型、线上服务、效果评估五个模块。
这道题的范围很大,给的时间又紧,我当时的策略是“框架优先、细节点睛”。先画出一个完整的推荐链路,然后在每个环节挑一两个最核心的点展开,而不是试图把所有细节都写全。
数据收集这块,我重点写了“实时行为流”和“离线特征仓库”的配合。实时流处理用户的点击、跳过、收藏等行为,延迟控制在秒级别,用于个性化召回的快速反馈;离线仓库则以天为单位更新用户的长期偏好,比如常听艺人、喜欢的语种、时段偏好等。
候选召回环节,我设计了多路召回策略:基于用户历史播放列表的协同过滤召回、基于歌曲embedding的向量召回、基于艺人维度的聚类召回,以及热门歌曲兜底召回。多路召回的目的是保证候选集的多样性,避免排序模型只在单一类型里打转。
排序部分我写的是“粗排 + 精排”两阶段。粗排用双塔模型,对全量候选做一个快速打分;精排用DeepFM类模型,加入更多交叉特征。我特意提了一句“样本偏差修正”,因为粗排筛掉的样本不会进精排训练集,会导致精排学到有偏的分布,这个细节能体现你对工程链路有真正的理解。
线上服务我写的是“多级缓存 + 增量更新”。歌单列表接口的RT要求很高,一般要控制在50ms以内,所以方案里要有redis缓存和预计算逻辑,同时要支持用户最近行为对结果的实时扰动,比如用户刚收藏了一首歌,希望在下一轮刷新时能看到类似风格的歌。
效果评估这块我写了两层目标:第一层是业务指标,包括推荐点击率、完播率、人均播放时长和次日留存;第二层是策略评估指标,包括新歌曝光占比、冷启动成功率、推荐多样性(类别熵)。我说评估的关键是“分层看指标”,不能只看均值,还要看不同用户群的差异,比如深度用户和新用户在同一策略下的反应可能是完全相反的。
这题的分数我估计拿得不错,因为结构清晰,而且每一块都能落地,没有什么空话。
6. 备战复盘与避坑指南
笔试结束后我做了好几轮复盘,主要针对时间管理、薄弱知识点和心态调整这三个维度。这可能是这篇博客里最值得反复看的部分,因为我确实用血泪换来了这些经验。
6.1 时间分配与做题顺序的建议
做题顺序真的是笔试最大的隐形分数。我的建议是,不要按题目顺序做,而是先花3分钟扫一遍所有题目,标记出“会做但耗时”和“有点思路但不太确定”的题。优先做选择题中确定能拿分的,再做编程题里你最有把握的那道,最后攻坚难题和设计题。
编程题的时间定额也很重要。一道题如果30分钟内没有稳定的AC思路,先标记跳过,不要恋战。我当时就是卡在第三道模拟题上,结果后边的论述题时间不够,写出来的质量明显比预期低。现在回头看,第三道题即使只写个暴力版本也能拿一部分分,但论述题如果答得空洞,一分都拿不到。要学会“止损”。
6.2 我的备战周期和核心资料
我是收到笔试邮件之后才开始集中复习的,大概有一周的准备时间。这一周里我做了三件事:第一是用力扣刷了80道高频题,重点覆盖二分、链表、二叉树、动态规划、滑动窗口这几个专题;第二是把机器学习面试高频考点系统性过了一遍,包括偏差方差、正则化、交叉验证、BN原理、常见损失函数等;第三是找了两篇推荐系统相关的技术博客精读,关于冷启动和双塔召回的。
如果你准备的时间更充裕,我建议提前一个月开始做分配表。前三周每周一个专题,最后一周专门做“真题模拟”和复盘。刷题不在数量多,关键是每道题都要能讲清楚时间复杂度和为什么对,这样笔试时即使碰到变种题也能快速迁移。
6.3 常见失分原因和应对策略
我复盘时发现自己失分主要有三个原因:一是多选题漏选,考场上为了保险只选确定的项,结果漏了正确答案;二是编程题忘记处理输入输出的边界条件,比如链表为空、区间重叠的边界等;三是论述题写得太平,只列要点没展开。这三个问题都有对应的应对方法:多选题练习时就要逼自己写出每个选项对或错的依据,不能“感觉对”;编程题提交前必须检查空值、单元素、大数等边界情况;论述题写作时强制用“结论-理由-例子”的结构。
注意:笔试结束后,建议立刻把你记得的题目做一遍完整复盘,写成文档。这不仅是巩固知识,更重要的是,TME的面试很可能会问你笔试时的思路,如果你能拿出一个清晰的分析文档,会显得非常专业。
6.4 心态调整与临场发挥
最后一个想聊的是心态。我参加笔试那天,正好赶上学校实验室的组会,时间非常紧张,进考场前十幾分钟还在处理实验数据。结果前半小时我脑子都是懵的,选择题硬是看了两遍才敢选。后来我深呼吸调整了一下,告诉自己“目标不是满分,是过线”,心态反而稳了,后面的题做得顺了很多。
所以我的建议是,考前留出至少半个小时的“放空时间”,不要再看任何技术资料,让大脑进入一个干净的状态。遇到不会的题,先跳过,不要在单题上耗太久。这是一个“全局最优解”的游戏,不是每道题都要完美,能拿到80%的分数已经是很好的结果。
7. 个人对这场笔试的复盘总结
写完上面这些内容,我最大的感受是:TME的技术研究岗笔试,本质上是在筛选“能把算法用于实际业务”的人。它不像一些公司那样只考模型推导或只考算法题,而是试图在你解题的过程中,看出你有没有产品sense和工程思维。
我后来顺利进入了面试环节,面试时有一半以上的时间都在围绕笔试中的设计题展开,问怎么评估冷启动效果、怎么权衡探索和利用、如果线上效果不好怎么排查。这些问题如果笔试时没有认真思考过,面试现场会非常被动。
如果你正在准备类似岗位,我建议你除了刷题、看理论,也要多问自己一句:“这个模型/算法在这个业务场景下,到底为什么有效,什么时候会失效?”想清楚这个问题,你的笔试和面试都能上一个台阶。