
我花了两个晚上把网易2018年数据挖掘实习生云音乐方向的笔试原题翻出来重新做了一遍。说实话这套题放在今天看依然有很强的参考价值它几乎把数据挖掘实习生应该具备的核心能力都覆盖到了机器学习基础、推荐系统思路、特征工程、SQL取数甚至还有一点业务 Sense。更关键的是题目紧紧贴着云音乐的业务场景不是那种背背公式就能过的卷子。这篇文章我打算拆解这套题背后的考点逻辑再给出一份可以直接照着准备的复习路线无论你是准备校招还是在职跳槽都能从中挖出点东西。先给个结论网易这道笔试题并不是单纯考“你会不会用 sklearn”它实际想筛选的是——能理解业务、能处理数据、能落地模型的人。云音乐的核心业务就是“听歌”所以题目几乎都围绕着用户行为、歌曲推荐、播放序列这些真实场景展开。如果你只会调包而说不清样本怎么构造、召回和排序有什么区别这套题会把你打回原形。1. 笔试整体结构复盘网易云音乐在找什么样的数据挖掘实习生1.1 云音乐的业务特征决定了考点方向网易云音乐和其他音乐App最不一样的地方有两块个性化推荐和歌单UGC生态。日推、私人FM、每日歌单这些功能背后全是数据挖掘的活。所以笔试题目从推荐链路切入是非常自然的。数据挖掘实习生进了云音乐团队之后日常工作大概是这几类用户画像建设给用户打标签比如“喜欢民谣”“偏好粤语老歌”“深夜听歌人群”内容理解对歌曲、歌单做语义分析提取风格、情感、场景标签推荐系统优化召回策略迭代、排序模型升级、重排规则调整运营分析活动效果评估、用户生命周期分析、流失预警对应到笔试题上考察点就非常清晰了。选择题部分重点覆盖概率统计、机器学习基础、特征工程常识编程和简答题则围绕用户行为数据展开考察 SQL 取数、基础算法实现和推荐流程设计。整套题的设计逻辑是先确认理论基础再考察工程能力最后用业务场景判断你的数据思维。1.2 各模块的考察逻辑和典型题型从我回忆的真题结构来看这套卷子大致分为三个部分选择题约40%主要考基础概念。比如给一组样本让你算信息增益、给两个事件判断是否独立、给一个损失函数问它对应什么模型。这部分其实是在筛“基本功扎不扎实”因为机器学习入门谁都会调库但能够手推公式、理解原理的人才是团队想要的。简答题约30%围绕音乐推荐业务出题。常见的有“如何为冷启动用户推荐歌曲”“如何评估推荐系统的效果”“如何从行为日志中提取用户特征”等。这些题没有标准答案面试官关注的是你有没有清晰的解决思路。比如冷启动问题你能不能想到用注册时选择的歌手类别做种子兴趣再叠加热门歌曲兜底这就是业务经验差异所在。编程题约30%通常是 SQL 和基础算法混合出题。SQL 会给你一张用户听歌记录表、一张歌曲信息表让你统计播放量Top10歌曲、计算用户活跃天数等。算法题则可能是手写一个协同过滤或者实现一个简单分类器。这部分考察工程落地能力写不出来基本就凉了。这里要插一句很多人重视算法题却忽略SQL这是大忌。数据挖掘实习生进了团队前三个月干得最多的就是写SQL取数。如果连窗口函数都用不利索哪怕模型原理背得再好也很难过面试官这关。2. 核心考点深度拆解从推荐链路到机器学习细节2.1 推荐系统链路召回、排序、重排这套笔试题里几乎一定会出现推荐相关题目所以我第一时间把推荐链路完整梳理了一遍。一个完整的推荐系统通常分成三块每一块的考察重心完全不同。召回阶段的目标是从全量歌曲库可能有几千万首中快速筛出几百首候选歌曲。常用方法包括协同过滤UserCF/ItemCF、基于内容的相似推荐、向量召回如 Item2Vec、双塔模型等。笔试常见考法是给你用户行为日志让你设计一个召回策略。这个时候你要明确说明召回为什么用协同过滤而不是训练一个排序模型。因为协同过滤不需要复杂特征只需要用户-物品交互矩阵计算成本低、可解释性强适合第一轮粗筛。而深度模型召回虽然精度高但需要大量特征和训练资源在工业场景中通常作为精排之后的升级方案而不是一开始就上。排序阶段负责对召回出的几百首候选歌做精细化打分。常用模型是 LR、GBDT、FM以及后来的 DeepFM、DIN 等。笔试中常考的是给定一组特征用户年龄、歌曲风格、播放时长、收藏次数等你选择什么模型为什么。这个题目没有唯一答案但你要体现出对特征和模型的匹配理解。比如 LR 适合处理大规模稀疏特征可解释性强GBDT 能自动发现特征交叉适合处理数值型特征FM 则擅长二阶特征交叉。如果面试官接着问“你线上用哪个”你要会说“先用 LR 做基线再迭代到 GBDTLR 或 FM”。重排阶段则是站在业务视角做调整。比如避免连续推荐同一歌手的歌、控制推荐列表的多样性、给新歌更多曝光机会。这块虽然模型上不复杂但很考验产品感觉。笔试如果问“推荐结果单一怎么办”你要能从多样性、新颖性、探索与利用EE这几个角度去回答。2.2 机器学习基础样本构造、特征工程、评估指标数据挖掘的笔试机器学习基础是躲不过的。但在云音乐的场景下基础知识的考察会有很强的“落地倾向”。举几个高频考点样本构造是最容易出问题的地方。推荐系统的样本通常来自用户曝光日志和播放日志。暴露给用户但没有点击/播放的歌曲就是负样本点击/播放了就是正样本。但这个逻辑有个坑很多曝光用户根本没看见没看见不等于不喜欢所以负样本有大量噪声。更好做法是“随机负采样”即从未曝光歌曲中随机抽取一部分作为额外负样本保持正负样本比例在合理范围比如1:3到1:5。笔试如果问到“如何构造训练样本”你要能把这个思考过程讲出来。特征工程方面云音乐场景最常用的是用户行为序列特征。比如用户最近一周播放的歌曲风格分布、播放时长均值、收藏次数、歌手喜爱度Top3等。时间衰减也很重要——用户上周听过的歌和半年前听过的歌信号强度完全不同。常见做法是给行为加上时间衰减权重比如 ( w e^{-\lambda \Delta t} )(\lambda) 根据业务调整通常取值0.01~0.1。评估指标更是必考。推荐系统常用的是 AUC、GAUC、NDCG、RecallK、PrecisionK。其中 AUC 衡量的是排序能力而 GAUC 是按用户分组计算的 AUC 加权平均更贴近推荐场景因为推荐结果是给单个用户看的整体 AUC 会被活跃用户主导。笔试问你“用什么指标评估推荐效果”你说 AUC 没错但能补充 GAUC 和业务指标播放率、收藏率、完播率会明显加分。2.3 SQL 取数和数据处理的实战套路SQL 是数据挖掘实习生的基本功2018年网易这套题里也出现了。很多候选人死磕算法题结果在 SQL 上翻车非常可惜。常见题型是给你用户行为表user_id, song_id, play_time, duration, event_type、歌曲信息表song_id, singer, genre, publish_date要求统计各种指标。基本上把这几类 SQL 练熟就够用了基础聚合统计每个用户的播放次数、播放时长、活跃天数。这时候用 GROUP BY 加聚合函数就行。窗口函数统计每个用户最近一次播放的歌曲、按播放次数排名前3的歌手。这里要用 ROW_NUMBER() 或 RANK() 配合 PARTITION BY。2018年很多学校课程不讲窗口函数所以这道题能筛掉一批人。TopN问题找出每个风格下播放量最高的歌。先 JOIN 两表再用窗口函数或子查询取 Top1。这类题在真实工作中极其常见比如“每个城市播放量最高的歌”“每个用户最常听的歌手”。如果一道 SQL 题你只会写 GROUP BY 和 JOIN那基本只能拿到一半分数。窗口函数这个东西笔试前必须练熟。3. 实操环节手写一道简化版的云音乐推荐题3.1 题目设定网易这套笔试题里编程题是当场写代码我在这里给出一道高度类似的简化版练习题方便大家感受考场上要做什么。原题核心思想大概是给定用户历史播放记录预测每个用户未来一周可能播放的歌曲输出 Top10 推荐列表。这道题看起来简单实际要处理的问题不少数据稀疏、冷启动、相似度计算、排序去重。下面是我按当时考核难度设计的练习版本大家可以在本地跑一跑完整走一遍数据挖掘的工作流。数据格式是两个 CSV用户行为表user_id, song_id, play_count, timestamp和歌曲属性表song_id, singer, genre。目标基于用户历史播放行为为每个用户预测未来可能播放的10首歌。3.2 基于 ItemCF 的完整实现我直接用 ItemCF物品协同过滤来实现因为这是工业界最简单可落的召回方案之一考试时间有限的前提下最优选择。ItemCF 的核心思路如果很多用户同时听了 A 歌和 B 歌那么 A 和 B 相似。给用户推荐时找出他听过的歌曲的相似歌曲按相似度加权排序。import pandas as pd import numpy as np from collections import defaultdict # 1. 加载数据 behavior pd.read_csv(user_behavior.csv) song_info pd.read_csv(song_info.csv) # 2. 构建“用户 - 已听歌曲集合” user_songs defaultdict(set) for uid, sid in zip(behavior[user_id], behavior[song_id]): user_songs[uid].add(sid) # 3. 构建“歌曲 - 哪些用户听过” song_users defaultdict(set) for uid, sid in zip(behavior[user_id], behavior[song_id]): song_users[sid].add(uid) # 4. 计算歌曲两两相似度余弦相似度简化版 # sim(a,b) |N(a) ∩ N(b)| / sqrt(|N(a)| * |N(b)|) song_sim defaultdict(dict) song_list list(song_users.keys()) for i in range(len(song_list)): s1 song_list[i] users1 song_users[s1] for j in range(i1, len(song_list)): s2 song_list[j] users2 song_users[s2] common len(users1 users2) if common 0: continue sim common / np.sqrt(len(users1) * len(users2)) song_sim[s1][s2] sim song_sim[s2][s1] sim # 5. 为每个用户生成推荐 def recommend(uid, top_k10): listened user_songs[uid] score defaultdict(float) for s in listened: for s2, sim in song_sim[s].items(): if s2 in listened: continue # 去掉已经听过的歌 score[s2] sim # 按分数排序取TopK rec sorted(score.items(), keylambda x: x[1], reverseTrue)[:top_k] return [s for s, sc in rec] # 6. 输出每个用户的推荐结果 for uid in list(user_songs.keys())[:10]: # 先看前10个用户 rec_songs recommend(uid) print(uid, rec_songs)这个代码跑起来不会有太大问题但说实话只是实现了最基础的逻辑。如果要拿高分还需要考虑几件事播放次数要作为权重加入而不只是用“是否听过”这个二值信号时间衰减要加进去最近播放的歌曲应该有更高权重相似歌曲如果同一歌手占比过高要去重或做多样性惩罚3.3 代码调试和常见坑点我在复现这个题时踩了几个坑写在这里给大家避雷。第一个坑相似度计算开销太大。如果歌的数量有10万首两两计算就是 (10^{10}) 量级直接跑死。真实做法是只对“有过共同用户”的歌曲对计算相似度或者用 MinHash/LSH 做近似计算。笔试时数据量小无所谓但你得在答案里提一句“大规模场景下要如何优化”这就能和其他考生拉开差距。第二个坑推荐结果没有去重。用户听过周杰伦的《晴天》系统可能推荐周杰伦的《七里香》《简单爱》《稻香》……结果 Top10 全是周杰伦。这个结果准确率可能不低但用户体验很差。实际工业做法会在重排阶段做同歌手限制Top10里同一个歌手最多出现2首。第三个坑忽略冷启动用户。如果某个用户只听了1首歌他的推荐结果基本只能从这1首歌的相似歌里出覆盖率极低。处理方式是对行为数量少于N比如5首的用户用热门歌曲兜底。这个逻辑在代码里要单独写一个分支不能直接走常规推荐流程。4. 笔试之后的面试追问题目背后的深水区4.1 评估指标的隐藏陷阱笔试考你“用什么指标评估推荐效果”很多人回答“AUC”面试官表面点头实际心里在等你补充。如果你只说“AUC”大概率会被追问“线下AUC涨了线上指标没涨甚至跌了你排查思路是什么”这个问题非常经典。可能原因有三个。样本选择偏差。线下训练的样本来自曝光日志但曝光结果本身就受当前推荐策略影响。如果线上推荐策略变了样本分布也就变了线下评估自然失真。解决办法是加探索流量、做无偏学习比如IPS加权。特征不一致。线下训练时用了未来数据比如未来一周的播放量标签但线上预测时这些特征不存在结果线下分数虚高。这种情况我见过太多次处理办法是严格按时间切分训练集和验证集保证特征时间一致性。评估指标与业务目标不一致。AUC衡量的是排序相对关系但业务目标可能是播放率提升、收藏率提升。如果排序把用户可能收藏的歌排到前面但用户平时就是随便听播放率反而可能下降。所以正确做法是线下看AUC同时做离线仿真估算线上业务指标的变化方向。4.2 新用户冷启动怎么办我相信这套笔试题的面试环节一定绕不开冷启动问题因为音乐产品的新用户冷启动场景太典型了。我的思路分三层。第一层是注册时获取兴趣信号。云音乐在注册时会让你选喜欢的歌手和风格这就是强信号。把这些种子歌手作为初始召回池从中用内容相似度扩展出候选集合。第二层是实时行为反馈。用户进入App后的每一次点击、播放、跳过都要实时反馈到推荐策略里。比如用户连点了三首民谣下一轮推荐就应该多出民谣候选。第三层是热门兜底。冷启动阶段没有个性化信号给最热门的歌是保证体验下限的选择。热门歌有播放数据有用户反馈能帮助系统更快学习用户偏好。这三层是递进关系从强信号到弱信号从个性化到普适化。面试其实就是在考察你能不能构建这样一套完整的链路。4.3 数据倾斜怎么处理音乐推荐场景里数据倾斜问题非常常见。周杰伦的播放量可能是普通歌手的几百倍这会导致推荐结果向头部歌曲集中。处理方式有几种对热门物品降权在协同过滤计算中如果物品的流行度过高可以对其相似度贡献做惩罚对热门歌曲做抽样限制控制每个用户听歌记录中热门歌曲的比例在召回阶段分桶把歌曲按热度分成不同的桶每个桶内独立做协同过滤最后再合并。这些方法在笔试里如果能提到两个以上面试官会认为你真有实战经验。5. 给准备校招的同学复习范围和实操建议5.1 时间分配建议如果你离笔试还有两个月我建议按这个比例分配复习时间数据结构和算法30%机器学习和统计学30%SQL和数据能力25%推荐系统基础15%。为什么算法和SQL加起来超过一半因为笔试首先是一道编程门槛过不去其他免谈。如果你只有一个月时间把SQL和机器学习基础复习扎实性价比最高。刷题方面LeetCode 刷150-200题足够重点放在数组、链表、哈希表、字符串、二叉树上动态规划适量刷。SQL 刷题推荐做 LeetCode 的数据库板块把窗口函数、JOIN、子查询练熟。5.2 容易被忽视的考察细节有几个知识点很多人觉得不重要但网易这套题里确实出现过我单独列一下概率统计不是背公式就行的。条件概率、贝叶斯公式、期望方差、常见分布正态、泊松、二项要能结合实际场景算题。比如“用户平均每天听20首歌每首歌被收藏概率0.1问用户7天收藏超过20首歌的概率”这种题就是泊松分布的应用场景。交叉熵损失函数为什么分类问题用交叉熵而不用均方误差。背后是梯度更新的角度因为SigmoidMSE会导致梯度消失。这种“为什么”的问题特别容易被笔试选择题和面试追问考到。样本不平衡怎么处理。虽然这个知识点在2018年还没有现在这么火但在数据挖掘面试中一直是高频问题。上采样、下采样、Focal Loss、代价敏感学习至少要知道两三种方案。5.3 成套练习的复盘方式刷题不是刷完就完了复盘比刷题本身更重要。我建议每次笔试模拟后做三层复盘。第一层看自己哪些题不会做。这暴露的是知识盲区需要针对性补课。第二层看哪些题会做但速度慢。这暴露的是熟练度问题需要多刷同类型题目提高肌肉记忆。第三层看哪些题做对了但在面试中可能被追问。这种题目不能止步于答案本身要多问自己几个“为什么”把背后的原理吃透。我记得当时准备网易这套题时考完最深的体会是这套卷子考的不是你背了多少公式而是你有没有真正理解数据挖掘在业务里的位置和作用。云音乐需要的人不是会调参的“炼丹师”而是能理解用户为什么听歌、为什么收藏、为什么切歌的人。如果你能从数据里读懂用户再从用户需求反推模型设计那这套题无论怎么变化你都能找到解题的切入点。最后分享一个小技巧复习的时候不要把题目和业务割裂开。每次学到一个算法试着想一下它在云音乐的场景里能解决什么问题、有哪些局限。比如倒排索引可以解决相似歌曲快速检索Focal Loss 可以缓解收藏行为稀疏问题这一切都在考查你的业务理解力。把这种思维训练成习惯笔试、面试都会顺很多。