每年春招,算法岗都是竞争最激烈的方向之一。阿里云作为国内云计算头部的公司,它的算法岗笔试第一轮,光是看门槛就能筛掉不少人。这篇文章不聊虚的,就结合2025年春招阿里云算法岗第一批笔试的实际情况,把题型结构、高频考点、刷题思路、以及我在机考现场踩过的坑,一次性讲透。准备冲春招、或者打算投阿里云算法岗的同学,可以先收藏,这篇内容足够你少走很多弯路。
笔试这东西,和面试最大的区别在于:它不看脸、不聊天,就是几十道题往你面前一放,计时的,编译器只给你用自带的,代码从零开始写,跑不出结果就是零分。而阿里云的算法岗笔试题,既考算法底子,也考机器学习和工程落地的综合能力。很多人拿到题目直接懵,不是因为不会写,而是因为不知道它到底想考什么、考到什么深度。下面我把整个备考和实战过程完整拆一遍。
1. 笔试前,你至少要搞清楚的几件事
1.1 2025年春招算法岗笔试到底在考什么
首先明确一点:阿里云算法岗笔试不是单纯的LeetCode刷题,它是“算法题 + 机器学习理论 + 工程场景题”的混合体。从我个人的经历和周围朋友的反馈来看,整体题型可以分成四类:
- 编程题(2-3道):涉及数组、字符串、树、图、动态规划、贪心等经典数据结构和算法,难度基本对标LeetCode中的中等偏上题。
- 机器学习基础选择题(约8-12道):考察LR、SVM、决策树、集成学习、损失函数、评价指标、过拟合、特征工程等基础概念。
- 数学与统计推导(1-2道):比如概率计算、贝叶斯公式、最大似然估计推导、矩阵运算或简单的最优化问题。
- 场景题(1道左右):给一个云资源调度、日志分析、数据倾斜、推荐排序等实际业务场景,让你设计算法方案或写伪代码。
这个结构意味着,你不能只刷题,还得把机器学习基础打得足够牢。有同学问:算法岗笔试到底刷多少题够用?我的看法是,与其盲目刷500道题,不如把一个类型的规律吃透。阿里云更看重解决问题的思维方式,不是你背了多少模板。
1.2 投递渠道、批次和时间安排
阿里云春招通常分批次进行,第一批笔试一般安排在3月中上旬,第二批和第三批会根据岗位需求和HC情况滚动安排。每年具体时间会有点浮动,但整体的时间窗口差不多:
- 网申投递:提前批一般在2月底到3月初开放。
- 简历筛选:投递后1-2周内会收到笔试通知。
- 第一批笔试:3月上中旬。
- 面试邀请:笔试通过后,一般1-2周内会邮件或短信通知。
给大家一个实测经验:简历投得越早,被捞的概率越大。不要卡着截止时间投,尤其是第一志愿,很多部门在第一批笔试时就已经把候选池建立起来了,后面的批次虽然也有机会,但坑位会变少。
1.3 机考平台与赛制规则细节
阿里云校招用的在线笔试平台经常是赛码网,这个平台和牛客网、LeetCode不太一样,有几个细节需要提前留意:
- 编译器版本偏老:比如C++可能不是最新标准,Python有过版本兼容问题,最好提前熟悉平台默认环境。
- 不提供自动补全:平台编辑器很朴素,既没有代码补全也没有括号匹配高亮,平时习惯在IDE里敲代码的人刚上手会非常难受。
- 输入输出格式要求严格:所有题目都是标准输入输出,必须自己写
input/sys.stdin.read或cin/Scanner,不写对格式,本地过了样例也是零分。 - 样例通过不代表能过:样例只是帮你验证基本思路,隐藏测试用例的边界条件、大数溢出、超时限制,才是真正拉开差距的地方。
所以说,笔试前一定要去赛码网做几套模拟题,先把输入输出的手感练出来,不然考试现场光调试格式就要浪费二三十分钟。
2. 核心考点拆解:数据结构和算法
数据结构和算法是整个笔试中最硬核的部分。阿里云的算法题不会出那些简单的“背模板”题,往往会在经典模型上加上一层变化,考察你对算法底层的理解程度。下面我按高频考点逐一拆解。
2.1 高频算法模板:排序、二分、贪心、动态规划
排序算法在笔试中直接考的几率不大,但它的思想会渗透到各种题目里,比如求“第K大的数”用的快速选择、求“逆序对”用的归并排序、求“前K个高频元素”用的堆排序。这些面试八股里的经典变种,笔试里是实打实要手写代码的。
二分查找更是大厂笔试常客,但难的不是模板本身,而是把问题抽象成“在一个有序空间里找边界”。常见三类变体:
- 找目标值:基础版。
- 找左右边界:比如旋转排序数组中的最小值、第一个坏版本。
- 二分答案:比如最小化最大值、最大化最小值,这类题需要你反过来用二分去猜最优值,再配合贪心或双指针去验证。
动态规划是重点中的重点。阿里云笔试喜欢考线性DP、区间DP、背包类DP、状态压缩DP的入门级变形。给大家一个实用的判断标准:只要题目有“最大/最小/最多/最少/多少种方案”这类字眼,而且符合前一个状态能推出下一个状态的递推关系,优先考虑DP。
我在准备阶段总结了DP解题四步口诀:
- 明确dp数组下标的含义。
- 推导状态转移方程。
- 确定初始化条件和遍历顺序。
- 通过打印dp表验证边界。
这四个步骤看起来简单,但大部分DP做不出来的人,都是卡在第一步:dp定义就没想清楚,后面全崩。
2.2 字符串处理与KMP算法
字符串问题在算法题里出现频率极高。如果有字符串匹配类的题目,KMP算法是必须掌握的。这里给大家讲一个很典型的例子,模式串p = "abacaba",它的next数组计算过程就很值得琢磨。
先说约定,这里的next[i]定义为:模式串从0到i-1的子串中,最长的相同真前缀和真后缀的长度(当i=0时,next[0]=-1,作为特殊标记)。这个模式串长度为7,我们可以一步步推:
next[0] = -1,这是因为空串没有真前缀。next[1]:对应子串"a",没有真前缀,取0。next[2]:对应子串"ab",前缀"a"和后缀"b"不相等,取0。next[3]:对应子串"aba",前缀"a"等于后缀"a",长度1,取1。next[4]:对应子串"abac",前缀"a"不等于后缀"c",其他长度更长的也不匹配,取0。next[5]:对应子串"abaca",前缀"a"等于后缀"a",长度1,取1。next[6]:对应子串"abacab",最长的相等前后缀是"ab",长度2,取2。next[7]:对应完整模式串"abacaba",最长相等前后缀是"aba",长度3,取3。
所以最终数组为[-1, 0, 0, 1, 0, 1, 2, 3]。
实际匹配时,当主串某个位置和模式串匹配失败,不要从头开始再匹配,而是让模式串的指针跳转到next[j]对应的位置继续比较。这个“跳转”的动作,就是把已经匹配的前后缀利用起来,避免重复扫描,把时间复杂度稳定在O(m+n)。很多同学不理解为什么KMP比暴力快,核心就快在这个“不回头”的匹配过程上。
2.3 二叉树、图与拓扑排序
二叉树相关的题目,比如最大深度、层序遍历、最近公共祖先、前中后序的迭代写法,这些都是必须闭着眼睛能写出来的。图相关的题,DFS、BFS、拓扑排序、最短路径(Dijkstra)、并查集,其中拓扑排序和并查集在云资源调度、任务依赖这类场景题里特别常见。
我记得有一道云资源调度的场景题,本质就是给一堆互相依赖的任务排序,限制条件很简单,但如果你想不到拓扑排序,就会写成一个超级复杂的递归回溯,既容易超时又容易错。所以学和算法一定要“带着场景去学”,不是孤立地背代码。
2.4 高频题型与LeetCode对照
为了方便大家备考,我把高频考点和LeetCode上的经典题做个对照,方便直接刷:
| 考点 | 典型题 | 备注 |
|---|---|---|
| 二分查找 | LeetCode 33、153、852 | 旋转数组、山脉数组 |
| 双指针/滑动窗口 | LeetCode 3、76、209 | 最长无重复子串、最小覆盖子串 |
| 动态规划 | LeetCode 322、300、152 | 零钱兑换、最长递增子序列、乘积最大子数组 |
| 拓扑排序 | LeetCode 207、210 | 课程表及其变体 |
| KMP | LeetCode 28、459 | 不用死记,会推导next数组 |
| 堆排序 | LeetCode 215、347 | 前K大、前K高频 |
| 并查集 | LeetCode 547、684 | 省份数量、冗余连接 |
| 贪心 | LeetCode 55、45、435 | 跳跃游戏、无重叠区间 |
实测下来,把这几类题刷扎实,基本就能覆盖阿里云笔试编程题的大部分考点。不建议去刷太多偏难怪题目,性价比不高。
3. 机器学习与统计基础,算法岗的隐形分水岭
很多人准备算法岗笔试,把精力全扑在刷题上,结果到了考场发现还有大量机器学习选择题和推导题,直接心态崩掉。这其实是算法岗和普通后端岗笔试最大的区别,也是阿里云算法岗刷人的隐形分水岭。
3.1 必须拿下的基础概念
选择题覆盖的知识点很广,但都不算深入。我整理了一份高频清单:
- 模型评估:准确率、精确率、召回率、F1、AUC、ROC、混淆矩阵。
- 过拟合与正则化:L1和L2的区别、Dropout、数据增强、早停。
- 损失函数:交叉熵、均方误差(MSE)、Hinge Loss,以及各自的适用场景。
- 优化算法:SGD、Momentum、RMSProp、Adam的区别。
- 经典模型:线性回归、逻辑回归、SVM、决策树、随机森林、GBDT、XGBoost,以及它们各自的优缺点。
- 特征工程:归一化、标准化、处理缺失值、类别特征编码。
这些概念不需要你背得一字不差,但一定要理解原理,因为选择题往往会用“下列哪个说法错误”这种形式来出,而错误选项往往藏在原理细节里。
3.2 逻辑回归和交叉熵推导,直接看公式
推导题是拉分项。有一类高频题型是:给你逻辑回归的损失函数,要求你推导梯度下降的更新公式。这里把最核心的交叉熵推导过程写一下。
逻辑回归的预测概率为:
[ h_{\theta}(x) = \frac{1}{1 + e^{-\theta^T x}} ]
损失函数为交叉熵:
[ J(\theta) = -\frac{1}{m}\sum_{i=1}^{m}\left[y^{(i)}\log(h_{\theta}(x^{(i)})) + (1-y^{(i)})\log(1-h_{\theta}(x^{(i)}))\right] ]
对参数 (\theta_j) 求偏导的关键,是用到sigmoid函数的一个性质:(h'(z) = h(z)(1-h(z))),其中 (z = \theta^T x)。
逐步推导可得:
[ \frac{\partial J(\theta)}{\partial \theta_j} = \frac{1}{m}\sum_{i=1}^{m}\left(h_{\theta}(x^{(i)}) - y^{(i)}\right)x_j^{(i)} ]
最后梯度下降更新公式就很简洁了:
[ \theta_j := \theta_j - \alpha \frac{1}{m}\sum_{i=1}^{m}\left(h_{\theta}(x^{(i)}) - y^{(i)}\right)x_j^{(i)} ]
这个推导,最好自己在本子上多写几遍,做到能默写。笔试现场如果考到类似的推导题,你写了就可以拿分,不需要什么临场发挥。
3.3 手写K-Means或KNN伪代码,是基本功
阿里云笔试有时会让手写K-Means聚类的伪代码或关键步骤,这种题不难但考基本功。K-Means的核心步骤就四步:
- 随机选择K个初始质心。
- 计算每个样本到各质心的距离,把它分到距离最近的簇。
- 对每个簇重新计算质心(取簇内所有点的均值)。
- 重复2-3步,直到质心不再变化或达到指定迭代次数。
写伪代码时,注意把“初始化质心”“分配样本”“更新质心”“收敛条件”四段写清楚,逻辑完整就能拿大部分分数。这类题大家都会写,比的是谁写得干净、有条理。
4. 实操过程:一道模拟机考题的全过程复盘
这里用一个比较典型的模拟题目,完整走一遍笔试现场的思考流程和代码实现。这道题是我根据阿里云算法岗历年的高频考点改编的,题目场景贴合云计算资源分配,非常有代表性。
4.1 题目描述与题意建模
题目大意是:云计算平台上一台物理服务器有固定的CPU核数M和内存大小N,现在有一批待部署的虚拟机和待运行的容器任务,每个任务包含需要的CPU核数、内存大小以及运行产生的收益。要求在物理服务器资源上限内,选择若干个任务运行,使得总收益最大化。
这个题目一读就知道,本质上是一个二维背包问题,每个任务只能选或不选,其中CPU核数是背包一维容量,内存大小是另一维容量,收益就是价值。如果直接暴力枚举所有子集,复杂度是O((2^n)),任务一多就超时,所以必须用二维背包的DP解法。
4.2 完整推导:从状态定义到代码实现
我们用DP[i][j]表示“在CPU资源上限为i、内存资源上限为j时,当前能获得的最大收益”。任务列表逐个遍历,对于每个任务(需要CPU、内存、收益),状态转移就是两个选择:
- 不选这个任务,那DP[i][j]保持不变。
- 选这个任务,前提是i >= cpu且j >= memory,此时收益为DP[i-cpu][j-memory] + profit,取最大值。
初始化DP全为0,从小到大遍历容量,最后DP[M][N]就是答案。
Python代码如下:
def max_profit(tasks, M, N): # tasks: [(cpu, memory, profit), ...] # M: CPU总核数, N: 内存总大小 dp = [[0] * (N + 1) for _ in range(M + 1)] for cpu, memory, profit in tasks: # 一维背包压缩后的模板,容量从大到小遍历 for i in range(M, cpu - 1, -1): for j in range(N, memory - 1, -1): dp[i][j] = max(dp[i][j], dp[i - cpu][j - memory] + profit) return dp[M][N] # 示例 tasks = [(2, 4, 10), (3, 2, 12), (1, 3, 8), (4, 5, 20)] print(max_profit(tasks, 8, 10))这段代码里最关键的地方在于:容量循环必须从大到小。这是0-1背包压缩成一维数组后的铁律,如果从小到大遍历,任务会被重复选择,变成完全背包问题,结果就错了。很多人在笔试中写错,就是忽略了这个循环顺序问题。
4.3 笔试现场的时间分配策略
我自己的习惯是拿到试卷后,先花2分钟把每道题快速浏览一遍,然后按照“先易后难、先拿分后思考”的原则排序做题:
- 选择题优先做:性价比最高,会就是会,不需要编译跑测试。
- 编程题先做最有把握的那道:确保至少有一题AC,心里踏实了,再做难题。
- 推导题放到编程题之后:如果时间不够,写上关键推导步骤也能拿部分分。
- 场景题最后写:这类题通常没有标准答案,重点是把方案写完整、逻辑写清楚。
一个比较大的坑是:看到第一道编程题难一点,就死磕到底,结果后面明明很简单的一道题没时间做。笔试是先保证整体得分,再追求单题完美。
5. 常见问题与坑点实录
5.1 赛码网机考的经典问题排查表
| 常见问题 | 表现形式 | 排查方法 |
|---|---|---|
| 输入输出格式错误 | 本地通过,提交0分 | 确认是否要读取多行输入、是否有多余空格、是否用了while True死循环 |
| 大数组越界/栈溢出 | 报错或程序崩溃 | 检查数组下标是否负数、是否超范围,递归过深时改成迭代 |
| 超时 | 运行时间超限 | 检查算法复杂度,O(n²)的循环扩大到n=10^5以上基本凉,换O(nlogn)或O(n)解法 |
| 整数溢出 | 答案错误 | C++使用long long,Python原生大整数一般没问题 |
| 边界条件漏判 | 隐藏测试用例失败 | 重点检查空列表、单元素、所有元素相等、极大数据等边界情况 |
| 编译器版本差异 | 语法报错 | 提前查平台上C++是否支持某些现代特性,Java和Python同理 |
5.2 容易丢分的三个细节
第一个,是输出格式。题目要求“输出结果占一行,每个数字之间用空格隔开”,有些人用默认打印列表,逗号和空格就错了。建议养成join(map(str, result))的输出习惯。
第二个,是代码里写死样例。有的同学在本地反复调试时,直接写了个if input == "特定值": print("对应输出")的硬编码分支,测试样例过了,但隐藏测试全部失败。这种痕迹一旦被检测出来,可能直接进黑名单。
第三个,是复杂度过高。比如求斐波那契数列用递归,当n很大时直接超时;求和用两重循环暴力枚举,当数据量到10^5级别时超时。笔试前一定要有复杂度分析的意识,写完代码先算一下最坏情况下的执行次数,超过10^8基本上就得换思路。
5.3 笔试后的加分细节
笔试不只是做对题就完事,代码的可读性和注释也会在后续面试官review时起到印象分的作用。我踩过坑后总结了几条:
- 变量名要有意义。别再写
a、b、c了,用cpu、memory、profit这种能让人一看就懂的命名。 - 关键步骤加注释。哪怕是一行
# dp[i][j]表示当前cpu为i、内存为j时最大收益,都会让面试官觉得你思路清晰。 - 复杂题可以在代码末尾用注释简述思路。比如空间复杂度和时间复杂度的分析,为什么要用DP而不是贪心。
- 写完代码再跑一遍自己设计的极端用例。这是自查环节,比如空数组、超大值、资源刚好够用等情况。
这些细节不一定直接给笔试加分,但到了面试阶段,面试官会翻你的笔试代码,这时候,一份干净整洁、有注释、有思考的代码,会比一份能跑但乱成一团的代码多出不少印象分。
5.4 如何高效准备剩下的批次
如果你没赶上第一批,或者第一批笔试没发挥好,一定不要气馁。后面的批次还有机会,关键是针对性地补强:
- 整理错题本:把笔试中不会的题、做错的题、超时的题,全部按考点归类整理,冲刺阶段只看错题本。
- 每周至少两场全真模拟:限制时间、禁用IDE自动补全、只用标准输入输出,模拟考场环境做题。
- 机器学习基础专项复习:每天留出1小时专门刷机器学习理论题,重点看模型评估、损失函数、优化算法这些高频点。
- 多看场景题:阿里云笔试很喜欢考资源调度、数据倾斜、日志分析、流量预测这类云场景问题,多积累几个典型的方案设计思路。
根据我个人的经验,笔试不一定是看绝对分数,而是看相对排名。只要整体稳定发挥,高于同一批次的平均线,就有很大概率进面试。阿里云春招的第一批笔试,与其说是一场考试,不如说是一次能力筛选。它筛选的不是谁刷题最多,而是谁在有限时间内能把问题定义清楚、把方案想清楚、把代码写干净。
最后再给大家一个小建议:笔试前一天,别刷难题了,把常用模板默写一遍,早点休息。真正上了考场,心态稳住、节奏拉满,你就已经赢了大部分人。祝各位都能收获满意的offer。