网易2023校招提前批的计算机视觉算法工程师笔试,我完整走了一遍。这篇文章不聊投递流程和面试玄学,只把笔试本身掰开揉碎讲清楚——考什么、怎么准备、答题节奏怎么安排、哪些坑是我实际踩过的。如果你正准备CV算法岗的校招笔试,或者对这类技术岗的考核方式好奇,这篇直接拿去参考。
我参加的批次是在线笔试,时长两个小时,题目形式不单一:选择题、编程题、问答题混在一起,整体感觉更像“在限定时间内完成一套综合知识考察”,而不是纯粹刷LeetCode那种单题攻坚。有意思的是,这套题里计算机视觉和深度学习相关内容占比明显高,和常规后端岗的笔试题风格差别很大。
1. 笔试的整体结构:和常规算法岗不一样,CV岗有自己的侧重
1.1 考试形式与平台体验
网易提前批的笔试走的是牛客网这类在线评测系统,支持多种语言提交代码(C++、Java、Python都行),选择题直接在网页上勾选,编程题需要在一个编辑器里写完并跑测试用例。我那个批次全程开着摄像头,屏幕切出会有提醒,整体环境监管比较严格。
时间分配上,两个小时听起来充裕,实际做起来并不轻松。理由不是题目数量多到写不完,而是每道题都需要一定思考深度,尤其编程题和问答题,磨时间的方式五花八门。我身边的同学考完交流,几乎没有人做到“时间还剩很多”的状态。
提前批的笔试和正式批一个明显区别:时间更早,很多人的知识体系还没完全过完一轮。我那个批次里,周围不少同学的状态是“数据结构刷过但深度学习基础还没系统复习”,结果遇到机器学习和CV相关的选择题时特别吃亏。
1.2 客观题的考察范围比想象中宽
我整理的客观题部分(单选+多选),按知识点可以大致分成四块:
| 知识模块 | 典型考点 | 占比感受 |
|---|---|---|
| 数据结构与基础算法 | KMP的next数组、排序算法稳定性、堆与快排、贪心策略 | 约三成 |
| 机器学习与深度学习 | 过拟合缓解方案、交叉熵、梯度消失、BN的作用 | 约四成 |
| 图像处理与视觉基础 | 卷积输出尺寸、感受野、双线性插值、图像锐化 | 约两成 |
| 工程与场景题 | 检测后处理、类别不平衡、数据增强 | 约一成 |
看到这个分布,你就明白准备方向不能只押算法题。我曾预期这套选择题全是“LeetCode Hot 100”那种代码题前置知识,结果不少题目直接考手推公式和模型理解,比如给一个输入尺寸、卷积核大小、步长和padding,让你算输出特征图尺寸。这类题看着简单,但一旦公式不熟练或者对padding模式理解不透,很容易算错。
1.3 题型设计上的几个“反套路”
传统印象里,算法工程师笔试主要考代码题,但这次的感觉是:客观题占了相当比重,而且和CV方向紧密结合。这其实反映了岗位需求——CV算法工程师不只是写代码调模型,还得对图像处理、特征提取、模型结构有底层理解。
另一个反套路是,笔试里出现了一些“工程取向”的题目,比如多任务处理优先级选择、A/B实验如何分析、训练数据质量如何评估等。这类题目没有标准计算过程,更多考察工程直觉。我当时一度觉得这些题有点像大厂产品经理的题,但它们出现在算法岗笔试里,恰恰说明企业希望候选人不仅懂理论,还要有工程落地的思维。
2. 选择题核心冲刺:从数据结构到深度学习的知识扫描
2.1 数据结构与基础算法:KMP、排序、快选等高频考点
选择题里的数据结构部分,一个很集中的方向是字符串匹配和排序算法。我在考卷里确实看到了和KMP相关的题目,具体形式是给一个模式串,让算next数组或者判断某次匹配失败后模式串的移动位置。这种题不能靠死记硬背,得理解失配后“最长公共前后缀”的跳转逻辑。
我记得复习时用了这样一个例子:模式串 p = "abacaba",要算出它的 next 数组。先手动列一遍它的前缀后缀:
- 长度为1时,前缀 a,后缀 a,相同,长度为1
- 长度为2时,前缀 ab,后缀 ba,不同
- 长度为3时,前缀 aba,后缀 aba,相同,长度为3
- 更长的前缀后缀就不一样了
所以 next[3] 可以取1,next[5] 可以是3。这类题的关键在于:快速准确地提取“最长相等前后缀长度”,而不是背一个死板的模板。建议考前自己手动推几个典型模式串,比如 “ababcabaa”或“aaaa”,推一遍就形成肌肉记忆了。
排序算法也是选择题的常客。我当时遇到的具体问题包括:哪种排序在最坏情况下时间复杂度仍是O(n log n)、快速排序在什么样的情况下退化、归并排序的空间复杂度。最经典的考察点是“稳定性和原地性”,这里整理一个常用对照表:
| 算法 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 稳定性 |
|---|---|---|---|---|
| 快速排序 | O(n log n) | O(n²) | 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²) | O(n²) | O(1) | 稳定 |
| 插入排序 | O(n²) | O(n²) | O(1) | 稳定 |
这个表格值得考前过一眼,因为选择题里真的会问“下面哪个排序算法是稳定的”“归并排序的空间复杂度是多少”这种看似基础但容易混淆的点。
数据结构部分还有一个容易被忽略的点:二叉树。笔试里出现过按层遍历的顺序判断、完全二叉树的节点计算、前序中序还原后序等。这些都是模板类知识,但需要熟练到“看到就能秒选”的程度。我的建议是考前把二叉树遍历(前序、中序、后序、层序)的递归和迭代写法各过一遍,尤其注意层序遍历用队列、迭代前序用栈这种细节。
2.2 机器学习与深度学习基础:从梯度消失到BN
选择题里占比最大的一块是机器学习与深度学习基础。我遇到的题目包括:交叉熵损失如何处理多分类问题、什么情况下使用Focal Loss、批量归一化(BN)在训练和推理时的差异、梯度消失产生的原因及缓解方案等。
这里特别提一嘴BN。不少同学对BN的理解停留在“对上一层输出做归一化然后缩放平移”,但笔试里会问到细节:训练时用的是当前batch的均值和方差,推理时用的是训练阶段累计的全局统计量。这个差别特别容易被忽略,但它既是选择题考点,也是面试常问的切入点。我在复习时专门做了个笔记:训练阶段更新global mean和global variance,推理阶段直接用global值做归一化,不参与梯度更新。
梯度消失的题目也很有代表性。题目通常给几个激活函数,要求选出哪些能缓解梯度消失,或者问梯度消失的原因。我自己的理解框架是:链式法则连乘导致梯度递减,sigmoid函数在饱和区的导数趋近于0,所以深层网络用ReLU类激活函数会更稳。这个结论笔试里直接用,面试时也得会解释。
关于优化器,选择题里出现过SGD、Adam、带动量SGD的区别。我当时重点复习了动量项的意义:加速收敛、减少震荡;Adam则结合了一阶动量和二阶动量,自适应调整学习率。这类题陷阱在于:问“Adam是否保证收敛到全局最优”时,大部分情况应该选“否”,因为随机目标函数和自适应学习率并不提供全局收敛保证。
2.3 图像处理与视觉基础:卷积尺寸、感受野与插值方法
这部分是CV岗笔试的“护城河”题型,也是区分候选人的一个分水岭。最基础也最高频的是卷积层输出尺寸计算。公式是:
output_size = (input_size - kernel_size + 2 * padding) / stride + 1这个公式必须刻进脑子里。我考场上遇到的是:输入 7×7,卷积核 3×3,stride=2,padding=1,算输出。代入公式:(7-3+2)/2+1 = 16/2+1 = 4。简单,但要特别注意除法是否整除,以及“same”模式下的输出尺寸计算。如果题目故意设一个不能整除的尺寸,往往是在考察你知不知道“以向下取整为准”还是“以向上取整为准”——torch里默认是向下取整(floor),但有些框架实现不同,这个细节容易踩坑。
感受野计算也是一道“送分但容易错”的题。我当时给自己总结了一套递推法:从最后一层往前逐层推,或者直接用公式:
RF_output = RF_input + (kernel_size - 1) * stride_cumulated关键是步长要连乘。比如两层3×3卷积,stride都为1,则输出感受野是5×5;如果第二层stride是2,感受野会更大。笔试时如果时间紧,可以直接按“每经过一个卷积层,感受野线性增加 (kernel-1)”来速算,前提是前层stride都为1。
双线性插值的题目也出现过。它不是直接让你手写代码,而是给一个目标坐标,让你结合四个邻近像素的灰度值做加权计算。我当时在草稿纸上画出水平和垂直方向的比例关系,然后逐步计算。复习这个小知识点时,我特意拿了一张实际灰度图在Python里跑了一遍cv2.resize,用不同插值方法对比结果,加深了“双线性插值是做了两次线性插值(先在x方向、再在y方向)”的理解。
图像锐化相关的题目在热词中也有呈现,拉普拉斯算子就是最典型的例子。笔试如果考锐化,通常会给一个卷积核模板:
0 -1 0 -1 5 -1 0 -1 0这就是原图加上四邻居拉普拉斯算子的结果,本质是边缘增强。如果题目让你判断某个卷积核是锐化还是模糊,核心就看中心系数是否明显大于周围系数且总和是否接近1。这个判断在选择题里能救急。
2.4 工程经验与场景题:类别不平衡、数据增强与后处理
最后的工程场景题,虽然占比不高,但我觉得最考验“积累”。题目往往设计成一个真实项目场景,比如“检测模型在类别分布极不平衡时,你会怎么处理”“训练集与测试集分布不一致怎么办”“如何设计一个提升小目标检测效果的数据增强策略”。
我得到的直接经验是:类别不平衡,最基本的套路是重采样、调整类别权重、用Focal Loss或OHEM(在线困难样本挖掘)。如果题目里给的是检测任务,那还可以提及调整anchor比例或增加正样本预标注。数据增强方面,针对小目标,比较实用的方案是复制粘贴(copy-paste增强)或马赛克增强(mosaic),把多个图像拼在一起增加目标密度。我答这类题时的方法套路是:先定性说清楚“问题的本质是什么”,再给出2-3个具体手段,最后补一句“需要根据验证集指标来评估效果”。
3. 编程题的核心思路:代码能力之外的考察点
3.1 编程题最常见的几种类型
编程题在整张试卷中占大概30-40%的分值,考法比较标准。我那个批次遇到的编程题类型大致是:
- 数组处理类:找第K大、合并区间、最大子数组和
- 字符串类:字符串匹配、编辑距离
- 图与搜索:最短路、DFS/BFS模板题
- 动态规划:背包问题变体、最长递增子序列
这些题对应届生来说都不算超纲,但有两层隐藏考察:第一是基本功熟练度;第二是代码风格,比如边界条件是否考虑周全、是否写出注释、命名是否可读。
我个人强推的复习方式是:考前把“高频模板题”刷透,不追求刷题数量,而追求“每个模板都能5分钟内默写出来”。常见模板包括:二分查找的闭区间写法、二叉树层序遍历、拓扑排序、KMP、Dijkstra、归并排序的merge过程、快排的partition过程。能把它们写到“肌肉记忆”程度,笔试编程题就没那么慌了。
3.2 一道“找第K大”题目的完整复盘
我那次遇到的一道编程题,和“找数组中第K大的数”高度相似。题目大概是:给定一个无序数组,要求在不使用内置排序函数的前提下,尽可能高效地返回第K大的数。输入规模没有明说,但看测试数据量,O(n log n)应该可行,O(n²)有风险。
我当时写了两种方案对比,考场上的节奏是先把最简单的快排partition方案写了,再根据剩余时间和题目限制决定要不要优化。这里给出一个基于快速选择(QuickSelect)的参考实现:
import random def find_kth_largest(nums, k): def partition(left, right): pivot_idx = random.randint(left, right) nums[pivot_idx], nums[right] = nums[right], nums[pivot_idx] pivot = nums[right] i = left for j in range(left, right): if nums[j] > pivot: nums[i], nums[j] = nums[j], nums[i] i += 1 nums[i], nums[right] = nums[right], nums[i] return i left, right = 0, len(nums) - 1 k = k - 1 # 转成索引 while True: pos = partition(left, right) if pos == k: return nums[pos] elif pos < k: left = pos + 1 else: right = pos - 1几个我踩过的细节:
- 随机化pivot很重要,否则最坏情况退化到O(n²)。
- 题目问“第K大”,partition时用“大于pivot”放左边,这样pos索引位置直接对应第(pos+1)大。
- 如果题目改成“第K小”,只需要把比较符号换一下方向。
如果时间宽裕,我会补充一个“如果数据规模极大且内存受限”的讨论,比如用大小为K的最小堆维护。这种叙述性补充,有时比代码本身更能体现工程思维。
3.3 编程语言选择与写法上的细节
笔试系统支持的编程语言我印象里至少有C++、Java、Python三种。我自己的选择是:纯逻辑题用Python,涉及复杂数据结构和手动内存管理倾向的题目用C++。原因很简单:Python写得快,容易在有限时间内跑通;C++则更稳,性能上限高,但开发速度慢一些。
不过有几个细节需要注意:
- 输入输出格式:在线笔试系统往往要求手动读入读出,要明确用sys.stdin/input()还是scanf/cin。建议固定一种输入解析模板,不要考场上现推。
- 边界样例:数组长度为1、空数组、K等于数组长度,这种极端情况必须提前想好。
- 变量命名:我一向建议用有意义的命名,而不是a、b、c,因为笔试现场回看代码时,好命名能让你快速定位错误。
编程题环节还有一个容易忽略的“隐形分数”——时间复杂度的说明。有些题目在解答末尾附一句“算法时间复杂度O(n),空间复杂度O(1)”之类的备注,面试官看代码时会觉得你思路清晰。虽然在线评测不一定看这行字,但养成这个习惯对后续面试也有帮助。
4. 计算机视觉专项题:模型结构、损失设计与目标检测
4.1 模型结构对比:从ResNet到轻量化设计
深度学习在CV领域的笔试考察,通常会从“你熟悉的模型”展开。网易这套题里出现了几道和模型结构相关的选择题,比如ResNet的残差连接解决了什么问题、为什么比VGG更容易训练、Depthwise Separable Convolution相比普通卷积减少了多少计算量等。
ResNet那道题的正确答案思维链我理一遍:深层网络退化,不是因为过拟合,而是因为训练变得困难,残差连接让梯度可以绕过非线性层直接传播,至少让网络在训练初期表现得像“浅层网络+恒等映射”,从而缓解退化。如果你在面试里答这道题,建议进一步举例说明:一个34层的残差网络和一个34层的plain网络,同样的训练轮次下plain网络的训练误差反而更高。
选择题里如果考轻量化模型,我建议准备MobileNet系列的基础概念:深度可分离卷积把标准卷积拆成“逐通道卷积”加“逐点卷积”,参数量和计算量大约降为标准卷积的 1/9 到 1/8(取决于输出通道数)。这个结论能快速响应“如何减少模型参数量”一类题目。
4.2 检测与分割任务的经典考点
目标检测是CV算法工程师笔试的重头戏。考察方向包括:Anchor Box如何设计、NMS的作用和实现细节、IoU计算、mAP如何计算等。其中“NMS的作用”最常考,我的回答框架是:移除冗余检测框,对同一类别的框按置信度排序,选择置信度最高的框,并删除与其IoU大于阈值的其他框,然后迭代这个过程。
IoU计算的代码,笔试里可能让你现场实现,也可能给几个框让你算结果:
def compute_iou(box1, box2): # box = [x1, y1, x2, y2] x1 = max(box1[0], box2[0]) y1 = max(box1[1], box2[1]) x2 = min(box1[2], box2[2]) y2 = min(box1[3], box2[3]) inter_w = max(0, x2 - x1) inter_h = max(0, y2 - y1) inter_area = inter_w * inter_h area1 = (box1[2] - box1[0]) * (box1[3] - box1[1]) area2 = (box2[2] - box2[0]) * (box2[3] - box2[1]) union_area = area1 + area2 - inter_area return inter_area / union_area if union_area > 0 else 0关键点是:不重叠时IoU为0,而不是负数。我当时看完题目才发现,题目里给的框坐标可能顺序不同(有的给xyxy,有的给xywh),考场上务必先确认格式再写代码。
mAP的计算也经常出现在问答题里:对每个类分别算AP,再对所有类取平均。AP通常基于precision-recall曲线(或11点插值)计算,这里如果能把“召回率上升时精确率下降”的权衡关系说清楚,答题质量会提升不少。
4.3 问答题的“开放题”怎么答:anchor、小目标、长尾
笔试的问答题部分,有时会出一道没有标准答案的开放题。我遇到的类似题目包括:“如果目标检测中小目标检测效果差,你打算怎么解决”“训练集中类别分布极不均衡怎么办”“如何设计一个数据增强策略来提升鲁棒性”。
这类题我给一个“结构化答题模板”,亲测好用:
- 先定义问题:小目标检测难在哪?低分辨率、特征提取后信息损失严重、IoU计算对像素偏移敏感。
- 再给出方案:多尺度特征融合(FPN)、提高输入分辨率、复制粘贴增强、针对小目标的anchor尺寸调整、增加小目标的采样权重。
- 最后补一个验证方案:在验证集上按目标尺寸分组看AP,对比不同方案的提升幅度。
这个模板最大的优点:即使你对具体细节了解不深,也能让阅卷人感受到你有工程思路,而不是只会背模型名字。
5. 时间分配与答题策略:笔试里的隐形分差
5.1 我实际用的时间分配
我那次笔试把两个小时拆成了大致四块:
| 时间段 | 任务 | 策略 |
|---|---|---|
| 前10分钟 | 快速浏览全部题目 | 标记简单题和难题 |
| 40分钟 | 单选题+多选题 | 先做会做的,不会的凭记忆排除法 |
| 40分钟 | 编程题 | 从最熟悉的模板题开始 |
| 30分钟 | 问答题和开放题 | 结构化作答,写关键词和公式 |
| 最后5分钟 | 复查选择题 | 重点复查计算类题目 |
这个安排的关键在于:不把时间卡死在单个难题上。选择题里有一道手推双线性插值的题,我当时算了两遍,看起来浪费了5分钟,但有效避免了低级计算错误。
5.2 遇到不会的题,怎么“抢分”
笔试不像面试,不会的题硬写没有意义,但抢分策略是有的:
- 选择题:排除法优先。先去掉明显不对的选项,再在剩下两个中凭概率,能明显提高命中率。
- 编程题:写出暴力解法或部分正确解法,往往也能拿到部分测试样例的分数。不要一上来就追求最优解,先拿分再优化。
- 问答题:把从题目中能想到的关键词、公式、步骤全部列出来,即使逻辑不完整,也比空白强。我答题时习惯用“第一步、第二步”的结构,不仅自己好组织,阅卷人也方便抓采分点。
5.3 草稿纸与公式推导的使用细节
在线笔试虽然用不上实体草稿纸或白板,但系统往往提供一个在线编辑器或记事本。我的使用习惯是:先在编辑器顶部用注释写关键公式,比如卷积输出尺寸、感受野递推式、KMP的next数组定义。这样做的好处是:遇到计算类题目时,直接调出公式,不需要重新推导。用注释写公式也有副作用:有些在线平台会把这个附注写上“代码注释”计入答案,但通常不会扣分。另一个常用操作:把不确定的编程题用一个小测试用例先跑一遍,验证思路后再提交完整代码。有些平台支持在线运行,务必要利用好这个功能,比直接用脑子硬想到底稳得多。
5.4 复查清单
我每次笔试都会留最后5分钟做一次快速复查,核心顺序是:
- 所有题目是否都已作答(包括不确定的选择题)。
- 编程题是否处理了数组长度为0、K越界这类边界情况。
- 选择题里的计算题是否代入过公式验证。
- 姓名/学号/岗位代号等基本信息是否填写正确,有时候这决定成绩是否有效。
这套复查看起来琐碎,但确实能救回不少分。
6. 备考路线与笔试后的复盘
6.1 考完当晚我做的几件事
笔试结束不等于可以彻底放松。我习惯在记忆还新鲜的时候,用半小时左右的时间把考过的知识点记下来。比如“数据结构部分考了KMP的next数组”“选择题里出现了BN训练和推理的差异”“编程题考了找第K大”。这样做的原因是:同一场招聘可能还有下一批笔试,有些知识点复现率很高,哪怕不为了二批笔试,也能整理成一份“个人错题集”留给后续其他公司的笔试。
时间充裕的话,我还会把编程题在本地再写一遍,加一些极端用例跑一遍。比如找第K大的题,我会把k改为1、len(nums)、以及数组全一样的情况,确认代码不是碰巧通过。
6.2 从笔试暴露的短板倒推复习方向
如果笔试里发现自己某个知识块明显薄弱,后续复习就要立刻调整。比如我当时发现自己在“图像处理基础”上有疏漏:插值算法、边缘检测模板,虽然知道概念但计算不熟练。于是花了两个晚上把双线性插值、拉普拉斯锐化、Sobel算子做了集中练习,还整理了一个小抄模板,方便考前翻阅。
建议大家也做一次“笔试错题归因”:是知识盲区、计算不熟、答题策略不对,还是时间分配失控。归因不同,备考的侧重点完全不一样。完全归因于“知识盲区”的去背公式;归因于“计算不熟”的就多做几道推导题;归因于“时间分配”的,下次直接调整做题顺序。
6.3 几条通用的复习路线
从我自己的备考经历来看,针对网易这类大厂校招笔试,可以按下面这个优先级安排复习:
- 第一优先级(必拿分):数据结构与基础算法,尤其是数组、链表、二叉树、排序、二分、动态规划的模板题,保证编程题至少有一半能快速写出。
- 第二优先级(区分度):机器学习和深度学习基础概念,包括损失函数、优化器、正则化、批归一化、经典CNN结构。
- 第三优先级(CV特色):图像处理基础、目标检测后处理、常用CV任务评价指标、小样本和类别不平衡问题。
- 第四优先级(工程思维):开放场景题,这类题没有标准答案,但可以通过结构化表达提升得分。
另外,笔试前最好在牛客网或类似平台把真实在线笔试环境模拟一遍,哪怕只是看看题型和输入输出格式,也不至于考场上因为操作不熟练而浪费宝贵的5分钟。
6.4 笔试和后续流程的衔接
笔试只是整个招聘流程的一环,尤其是提前批,笔试之后往往很快就进入面试环节。如果笔试通过,面试官很可能直接拿着你的笔试卷子来问:“这道编程题你为什么这么写”“这道开放题你再说说思路”。所以笔试结束后的复盘,实质上也是为面试做的准备。我在复盘编程题时,会额外想清楚各种解法的优劣,比如堆方案和快选方案的空间复杂度差异、最坏情况下哪个更稳。这些内容面试时随时可能被追问。
如果笔试没有通过,也不用过度纠结。提前批本身就是试水,很多人的笔试题量是攒出来的,后续正式批还有机会。关键是每一次笔试都尽量让自己暴露问题、积累经验。
6.5 一道实操题:把“复习笔记”转化为“答题模板”
最后分享一个小技巧。我复习时会把每个高频考点整理成“快答模板”,格式是:题目可能怎么问+我要答的几个要点。举例:
- 题目可能怎么问:如何缓解类别不平衡问题?
- 答题要点:数据层面(重采样、数据增强)、损失函数层面(Focal Loss、OHEM)、评估层面(使用mAP或PR曲线而非accuracy)。
这个模板的好处是答题时不用现场组织语言,直接按清单输出,既快又不容易漏点。我在考前把卷积输出尺寸、感受野计算、KMP next数组、BN训练推理差异、NMS流程、mAP计算都做了这样的模板,总共大概十来个。笔试时碰到原题或变形题,写起来特别快,而且准确率明显提高。这个“快答模板”方法,我觉得对新手尤其友好,可以参考。