ARTICLE DETAIL

资讯详情

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

网易深度学习算法笔试复盘:核心考点与避坑指南

网易深度学习算法笔试复盘:核心考点与避坑指南 2023年网易提前批深度学习算法工程师的笔试我是在线上完成的。整套题做完最大的感受是网易的笔试不是单纯考你“会不会调模型”而是考你在有限时间内能不能把基础概念算清楚、把代码写利索。整个笔试大概三个小时内容覆盖了深度学习基础、机器学习基础、数据结构与算法还有几道偏工程实现的题目。这篇复盘我尽量按考试时的真实体验来写包括题型分布、重点考点、我当时的解题思路以及考完以后对完答案才明白的坑希望对后面准备大厂算法岗笔试的朋友有价值。先说结论网易这套题整体难度中等偏上但在选择题和填空题上挖了不少“概念细节”的坑。比如Float32和Float16在深度学习训练中的区别、CNN感受野的具体计算、KMP算法中next数组的手算结果这些题目在刷LeetCode时很少碰到却在网易的卷子里占了不少分值。如果你也想走深度学习算法工程师这条路建议除了刷题也要把深度学习框架底层的浮点数规则、卷积计算细节都过一遍。1. 笔试整体复盘今年的题型和节奏1.1 熟悉网易笔试的风格和题型分布网易2023校招提前批笔试和往年一样采用的是在线编程系统题目结构大概分三块单选题、多选题、编程题。单选和多选覆盖机器学习、深度学习、算法与数据结构编程题则是两到三道算法题需要在规定时间内提交支持C、Java、Python等主流语言。从题型权重来看深度学习和机器学习相关的选择题占了将近一半的分值剩下的数据结构和算法又占了三成左右编程题虽然只有两三道但单题分值很高所以编程题能不能AC直接决定你能不能进下一轮面试。今年我印象最深的是选择题里出现了不少“工程向”的题目比如混合精度训练时不同浮点格式的取舍这在大厂笔试中越来越常见但很多同学在准备时只盯着Transformer和卷积网络很容易把这类基础题漏掉。1.2 提前批与正式批的差异提前批笔试和正式批最大的区别在于提前批更看重候选人的全面性。我当时对比过身边同学参加正式批的回忆版题目发现正式批的笔试似乎更偏向于深度学习模型本身比如对Transformer和CNN结构的理解而提前批则明显加入了大量算法题和机器学习基础题。这可能意味着在提前批阶段面试官更希望筛选出工程基础扎实、综合能力强的候选人。另一个区别是时间节奏。提前批笔试通常安排在投递简历后一到两周而且很多部门是“先到先得”你笔试成绩出来得越早面试官约面就越早。所以如果你准备投提前批最好在投递之前就把数据结构刷过一轮不要等系统发了笔试通知才开始准备那样大概率会手忙脚乱。1.3 我当时的准备思路与复盘框架我的准备周期大约是四周前两周把机器学习经典算法和深度学习基础理论过了一遍第三周主攻LeetCode热题HOT 100和剑指Offer第四周刷了大概近两年的网易笔试回忆题和牛客网上的模拟卷。考前最后两天没有再做新题而是把所有错题重新整理了一遍尤其是浮点数、卷积计算、排序稳定性这类容易混淆的细节点。这份复盘我会按题型逐一展开选择题部分挑那些“考完才后悔没多看一眼”的题目来细讲编程题部分则把我考场上的解法和赛后优化思路一起写出来包括复杂度分析、边界条件处理以及一些笔试环境里容易踩的输入输出坑。2. 核心考点拆解深度学习基础题才是胜负手2.1 卷积计算与感受野一道题考出基本功考场上有道选择题大概是这样的一个输入特征图尺寸是 224×224×3第一层卷积用 16 个 7×7 的卷积核stride2padding3问输出特征图的尺寸是多少。标准公式是[ output \lfloor \frac{input 2 \times padding - kernel}{stride} \rfloor 1 ]代入的话是[ \lfloor \frac{224 2 \times 3 - 7}{2} \rfloor 1 \lfloor \frac{223}{2} \rfloor 1 111 1 112 ]所以输出是 112×112×16。这道题本身不难但有两个容易粗心的地方一是计算时忘记把padding乘以2很多人直接算成 (224-7)/21得到大约108.5再取整就错了。二是把stride2漏掉直接从224算出218导致选项对不上。接着还有一道延伸题问两层卷积串联之后的感受野。假设第一层是3×3卷积stride1第二层还是3×3卷积stride1那么第二层输出特征图上的一个点实际上对应原始输入上的多大区域第一层感受野是3第二层在第一层的基础上再往外扩计算公式为[ RF_2 RF_1 (kernel_2 - 1) \times stride_accumulate ]由于每一层的stride都是1所以[ RF_2 3 (3-1) \times 1 5 ]也就是说两层3×3卷积串联后的有效感受野是5×5这和一层5×5卷积在感受野上是等价的但参数量更少。这个知识在面试里也经常被问到笔试里考一次非常合理。2.2 损失函数与优化器必考的对比题网易这份卷子里损失函数和优化器一共出了至少四道题这个密度相当高。有一道多选题问的是“关于交叉熵损失和均方误差损失的说法哪些是正确的”选项包括交叉熵损失常用于分类任务均方误差对异常值更敏感Softmax与交叉熵结合时梯度形式更简洁以及MSE在分类任务中会导致梯度更新过慢。这几个选项其实全对。我重点说第三个选项。很多人不理解为什么分类任务推荐“Softmax 交叉熵损失”而不是“Softmax MSE”。我们可以推导一下假设网络输出经过Softmax后得到概率 ( p )真实标签是 one-hot 向量 ( y )。交叉熵对 Softmax 输入的梯度算下来是 ( p - y )这个形式非常简单误差越大梯度越大模型学得越快。而 MSE 的梯度还要再乘一项 ( p(1-p) )当 p 接近0或1时梯度会变得非常小训练速度就会明显变慢。笔试里不要求推导但你得知道结论这个结论通常能帮你快速排除错误选项。优化器那边考了SGD、 Momentum、RMSProp、Adam 的区别。关键记忆点有两个第一只有带动量的优化器才会在更新时考虑“历史梯度的指数衰减平均”用来抑制震荡第二RMSProp 和 Adam 都对梯度做了逐参数的自适应缩放区别是 Adam 还额外加了一阶动量。如果选项里出现“Adam 相当于 Momentum RMSProp”那基本是正确的。2.3 工程部署相关FP16、BF16、TF32浮点数选型今年卷子里出现了一道很有区分度的题目问的是“在英伟达Ampere架构GPU上进行混合精度训练时以下关于FP16、BF16、TF32的说法哪个是错误的”。这个知识点如果只盯着模型结构准备很容易完全不会。先理清几个概念。FP32是单精度浮点数1位符号位、8位指数位、23位尾数位训练时的默认精度。FP16是半精度1位符号位、5位指数位、10位尾数位优点是计算快、省显存缺点是数值范围窄容易溢出。BF16也是16位1位符号位、8位指数位、7位尾数位指数范围和FP32一样所以不容易溢出但尾数精度比FP16还低。TF32是英伟达Ampere架构引入的一种格式它不是独立的存储格式而是计算时默认把FP32的输入截断到19位1位符号位、8位指数位、10位尾数位用于Tensor Core加速矩阵乘法的精度通常不低于FP16。那道题的错误选项大概是“TF32的存储占用和FP32相同”。这就错了TF32虽然保留了FP32的指数位宽度但它在计算时尾数位被截断成10位实际上Tensor Core会把输入转换成19位格式来计算和FP32的23位尾数相比精度是有损失的。如果题目问的是“为什么混合精度训练中BF16常用于大模型预训练”答案应该选“BF16动态范围大不容易溢出训练更稳定”。浮点数这类题目表面上考的是格式实际考的是你是否理解模型训练过程中的数值稳定性。我建议准备笔试时不光要背每个格式的位数分配还要知道它们分别用在什么场景FP32用于默认训练FP16和BF16用于混合精度训练TF32主要用于A100这类GPU上的矩阵乘法加速。知道这层关系遇到换着花样的选项也不慌。3. 数据结构与算法题代码题从暴力到最优解3.1 KMP next数组一道送分题变成失分题有道题是给一个模式串 P “abacaba”要求写出它的 next 数组next[i] 定义为“模式串前 i 个字符组成的子串中最长相同前后缀的长度”。这类题目其实在《数据结构》里属于必学内容但很多人刷LeetCode都不太手算KMP考场上我花了足足三分钟才确定结果。求解过程是这样的先看整个字符串 “abacaba”最长相同前后缀是“aba”长度3所以 next[7]3。再看前6个字符 “abacab”最长相同前后缀是“ab”长度2所以 next[6]2。前5个字符 “abaca”最长相同前后缀是“a”长度1所以 next[5]1。前4个字符 “abac”没有相同前后缀所以 next[4]0。前3个字符 “aba”最长相同前后缀是“a”长度1所以 next[3]1。前2个字符 “ab”没有相同前后缀所以 next[2]0。前1个字符 “a”没有真前后缀所以 next[1]0。于是完整的 next 数组是 0 0 1 0 1 2 3。当时我旁边有位同学说答案是 0 0 1 0 1 2 3也有人写成 -1 0 0 1 0 1 2。其实这两个都对应一种KMP实现风格前者是“最大公共前后缀长度”版本后者是把所有下标减1的“失败链接”版本。问题在于如果你平时写代码用的是“next[0]-1”的写法遇到选择题却只给“最大前后缀长度”选项就很容易看错。所以准备笔试时最好把两种约定都记清楚并且理解它们是同一个逻辑的不同表述。理解这一点比背任何一个数组都重要。3.2 排序算法与复杂度高频选择题算法选择题里排序几乎是必考。今年网易考了堆排序和快速排序的比较具体题目大意是有一组基本有序的数据问用哪种排序算法最快答案应该是插入排序因为数据基本有序时插入排序的时间复杂度可以退化到 O(n)。而不是快速排序因为快速排序在数组已经有序或逆序时如果基准值选得不好会退化到 O(n²)。另外有题考查了各种排序算法的空间复杂度。常见的结论要记牢冒泡排序、插入排序、选择排序平均时间复杂度 O(n²)空间复杂度 O(1)归并排序平均时间复杂度 O(n log n)空间复杂度 O(n)快速排序平均时间复杂度 O(n log n)最坏 O(n²)空间复杂度 O(log n) 到 O(n)堆排序平均和最坏时间复杂度都是 O(n log n)空间复杂度 O(1)考试时容易混淆的一点是堆排序和归并排序的最坏时间复杂度都是 O(n log n)但堆排序空间占用小归并排序需要额外 O(n) 的辅助空间。如果题目问“哪种排序算法不适合大数组排序”答案多半选归并排序因为内存占用大。如果题目问“哪种排序算法利用了大根堆的性质”则选堆排序。3.3 笔试实战一道“求第K大数”的完整复盘编程题里有一道题让我印象很深给定一个无序整数数组求第 K 大的元素。这个题LeetCode上有原型但网易给了两个版本一个数组长度 n 较小n ≤ 1000另一个 n 非常大n ≤ 10⁷。实际考场上给出的数据范围决定了用哪种算法。n 较小时直接调用nth_element或者排序后取值都可以。n 非常大时排序显然不现实最佳方案是维护一个大小为 K 的最小堆遍历数组时如果当前元素比堆顶大就弹出堆顶把当前元素入堆。最后堆顶就是第 K 大的元素。时间复杂度 O(n log K)空间复杂度 O(K)。我考场上用C写了一版#include bits/stdc.h using namespace std; int findKthLargest(vectorint nums, int k) { priority_queueint, vectorint, greaterint minHeap; for (int num : nums) { if (minHeap.size() k) { minHeap.push(num); } else if (num minHeap.top()) { minHeap.pop(); minHeap.push(num); } } return minHeap.top(); }这题的边界条件主要有两个一是 K 可能等于1这时堆只有一个元素每次比较大根堆逻辑要小心二是 K 可能等于 n这时相当于求最小值如果数组长度为1minHeap.top()直接返回那个唯一元素即可不会出错。如果 K 比数组长度还大题目一般不会给这样用例但保险起见可以先判断。复盘时我又想了一遍更优解法如果允许修改数组可以用快速选择算法平均时间复杂度 O(n)最坏 O(n²)。笔试时我不太建议用快速选择因为它的最坏情况退化比较难预估而且面试官更希望你写出“稳定、可解释”的堆解法。堆解法虽然慢一些但时间复杂度稳定面试问起来也容易讲清楚是笔试环境下的稳妥之选。4. 常见问题与避坑技巧4.1 时间分配不当导致编程题没做完这是我在牛客网上看到不少人反馈的问题也是我自己差点踩的坑。网易笔试的编程题不是非常难但前面选择题和填空题比较花时间尤其是多选题漏选、错选都不得分。如果你前面耗时太久编程题即使想到思路也可能因为没时间调试而提交失败。我的建议是先快速浏览一遍整张卷子把编程题的时间预留出来。如果一道选择题思考超过两分钟先标记跳过等做完编程题再回来。编程题哪怕只AC一道也比选择题硬磨半小时要划算。另外现在在线笔试系统普遍支持“分题计时”但整体时间是固定的所以必须有全局时间感。准考证上一般会写明总时长建议按“编程题至少60分钟选择题和填空最多90分钟”来切分。4.2 网上找不到原题用知识点反查提前批笔试题有保密协议考后一般搜不到原题。但网上会有很多往届生写的“考点回忆”比如“今年考了FP16和BF16的区别”“考了KMP的next数组计算”“考了几分排序算法稳定性”。这些回忆虽然没有完整题目但已经足够帮你锁定复习范围。我在提前批准备阶段就是靠牛客网上近两年的网易笔试讨论帖把高频考点整理成了一份清单再按清单逐项补基础。这种方法比盲目刷题更高效。因为大厂笔试的知识点范围其实是有限的浮点数格式、KMP、感受野、排序算法、优化器、卷积计算这类“经典考点”会反复出现只是每年换一个问法。你只要把每个考点背后的原理搞明白题目怎么变都能应付。把考点整理成自己的“反查清单”以后看到任何一条新热词都能快速定位也不会被带偏。4.3 环境与输入输出问题线上笔试的隐形杀手网易的在线笔试环境一般支持本机IDE调试再提交到系统判题。这个流程看起来简单实际上挺多坑。首先是语言版本问题比如你用C提交系统可能默认是C14如果你代码里用了C17的新特性比如std::optional直接编译报错这类问题不是算法问题却是实实在在的失分原因。建议考前先确认支持的语言标准写代码时尽量用最基础的语法。其次是输入输出格式。在线判题系统普遍要求从标准输入读取数据输出到标准输出不需要也不允许用文件读写。很多同学平时在本地IDE里写代码习惯读文件考场上忘了改就会导致“本地跑得通提交零分”。我自己的习惯是封装两个函数一个solve负责读数据并计算一个main只调用solve。这样切换文件输入和标准输入时只需要改main里的一行代码非常方便。4.4 考前一周应该重点复习什么如果距离笔试只剩一周我不建议再开新题了。优先级最高的是错题和易混淆知识点其次是自己做过的编程题思路总结最后才是查漏补缺。深度学习基础方面重点看卷积输出尺寸计算、BN在训练和推理时的不同行为、各种损失函数的适用场景算法方面重点看KMP的 next 数组手动推导、快排和堆排的过程、二叉树和链表的常见题型数值方面重点看FP16和BF16的位数分配以及训练时为什么需要 loss scaling。考前前一天可以把上面这些整理成一份简洁的速查卡不用背浏览一遍就行。我吃过亏的地方在于花了大量时间刷LeetCode困难题结果笔试反而考了不少“概念性”选择题比如“感受野公式”“浮点格式”“KMP next 数组”这些不用写代码但不会就是不会。所以对深度学习算法岗来说笔试复习一定要“基础理论 代码题”两条腿走路缺一不可。5. 一些亲测有效的准备方法和心路历程5.1 复盘比刷新题更重要考完提前批笔试后我没有立刻进入下一家笔试的准备而是花了一天时间把考试的题目尽量回忆出来分门别类整理成了自己的错题本。复盘时我发现一个规律真正让我犹豫的题目往往不是需要深度的题目而是“好像知道但又记不准”的题目。比如浮点数那题我知道FP16、BF16、TF32的名字但没仔细对比过指数位和尾数位的分配考场上只能靠排除法猜。这种模糊地带在深度学习算法工程师的笔试里往往就是拉分项。所以准备过程中我会建议你专门给“概念对比”留出一个文档把所有相似概念放在一起对比着记。比如FP32/FP16/BF16/TF32、BN/LN/IN、SGD/Momentum/RMSProp/Adam、交叉熵/MSE、卷积/池化/全连接。用表格把位数、公式、适用场景列出来不看不知道一看就能发现自己到底哪里没搞懂。这个方法听着笨但真的比反复刷题更能查漏补缺。5.2 心理节奏和做题顺序的调整在线笔试最大的挑战不是题目本身而是屏幕上那个倒计时。我考完提前批以后回想有两三道选择题如果放在平时我肯定能推导出正确答案但因为时间紧、心理紧张手一抖就选了错误选项。后来我用牛客网上的模拟卷练习特意训练自己“先做能拿分、再做难拿分”的顺序编程题留足时间选择题不要恋战。这个实战策略很管用到了考场上心里就稳得多。还有一个小技巧当选择题完全没思路时先排除明显违反常识的选项。比如浮点数那题选项里出现“FP16的指数位和FP32一样”这就明显错了因为FP16如果用8位指数位那它和BF16的区别就说不通。排除两个错误选项后即使靠猜正确率也能从25%提升到50%。5.3 调整复习权重笔试和面试的关注点不一样笔试和面试考察重点其实存在明显差异。面试官更喜欢问项目、问模型结构、问为什么而笔试更偏爱计算公式、写伪代码、判断概念的准确性。所以如果你已经在准备面试不要以为笔试可以裸考。我见过项目很扎实的同学笔试却因为不会手动算 KMP next 数组而挂掉。建议是在笔试冲刺阶段把复习重心放到“可计算、可推导”的知识点上来。比如卷积输出尺寸、感受野、参数量和计算量、BN的推理公式、Softmax与交叉熵梯度推导、KMP next 数组、排序算法复杂度、浮点数转换等。这些内容不需要很强的工程能力但需要你愿意静下心去算、去推。一旦推过一遍记忆会比单纯背诵牢固得多。5.4 关注时间线笔试结束后如何衔接面试提前批笔试通过后部门一般会在一到两周内约面试。我个人的经验是笔试结束不等于可以放松最好在等结果期间就把简历上的项目细节重新过一遍尤其是“为什么用这个方案”“有没有对比过其他方案”“指标提升了多少”这类问题。网易的面试很喜欢深挖项目如果因为你简历上的某个技术名词表述不准确而被追问然后又答不圆那比笔试挂掉更可惜。另外要留意不同岗位的提前批节奏可能不一样。我在牛客网上看到有些同学投的是网易云音乐有些投的是网易互娱还有些投的是网易有道这几个业务的笔试题型都会有差异。互娱方向更偏图形学和游戏AI云音乐偏推荐系统有道偏NLP所以准备时也要结合目标岗位做定向复习。如果时间紧张优先保证通用基本功再根据岗位方向补充一到两个专项考点。6. 最后想对准备2024及以后校招的朋友说几句网易这套题放到现在来看依然有很高的参考价值。因为它代表了一类大厂通用型算法岗位的筛选逻辑先看基础扎不扎实再看代码能不能落地最后才看你对深度学习的理解深不深。这个逻辑在未来的校招笔试里大概率还会延续。建议你从现在开始把复习资料沉淀成自己的知识库。不只是收藏别人的面经而是每做完一套题就把错题和考点整理成属于自己的文档这样等到投递简历前的冲刺阶段你只需要复习自己的错题本而不是从头再刷一遍所有资料。这个方法能节省大量时间也能精准打击你的知识盲区。另外心态上不要把所有希望都寄托在一次提前批上。提前批本身也有很强的“筛人”属性没进面试不代表你不行只代表这次准备可能还不够全面。秋招正式批还有机会很多人在提前批挂了之后在正式批总结教训反而拿到了offer。保持持续学习的状态比一次成败重要得多。最后分享一个我后来一直用的小技巧把笔试中遇到的每一个新知识点当天就用自己的话写进知识库并配一个“为什么”的解释。这个过程相当于在潜意识里做了一次输出记忆效果远好过读十遍资料。你有这些积累以后不管是笔试还是面试面对那些“好像哪里见过”的题目都能更有底气。
返回列表