2017年那会儿互联网大厂的算法岗还没有今天这么卷但美团那场秋招笔试说实话给我留下的印象比后来很多面试都深。当时试卷上印着的“算法工程师B”看起来和A岗没什么区别实际考下来才发现它考察的粒度完全不同。A岗更偏模型调参和业务senseB岗则是实打实地在筛基本功——数据结构、字符串处理、最短路、排序、贪心甚至还有信号处理和图像处理的基础概念。这篇文章不是来找真题答案的而是我基于这场笔试做的一次完整复盘。我会把试卷背后的设计逻辑、每类题型的核心考点、做题时的思考过程以及我自己踩过的坑全部捋一遍。如果你正在准备大厂算法笔试尤其是偏底层、偏工程实现的算法岗这篇文章应该能帮你少走很多弯路。1. 笔试整体设计思路与考察方向拆解1.1 试卷结构从选择题到场景题的分层筛选美团这场算法工程师B的笔试整体结构大致分四个板块选择题、编程题、简答/推导题、开放场景题。选择题大约占30分覆盖面非常广从KMP算法的next数组推导到堆排序的时间复杂度再到模拟退火和粒子群的基本原理都有涉及。编程题一般两道一道偏经典算法一道偏工程实现。简答题则集中在机器学习基础比如特征工程、模型评估、正则化这些。最后一道开放题往往是给你一个业务场景让你设计算法方案。这个结构其实是典型的“海选分层”逻辑。选择题用一个小时内快速筛掉基础不牢的人编程题筛掉动手能力差的人推导题筛掉“背八股”的人场景题筛掉没有工程思维和业务理解的人。所以它不是单纯考你会不会写代码而是考你在有限时间内能不能把学过的知识用出来。1.2 为什么“算法工程师B”比A岗更看重底层原理我后来复盘时才明白美团把岗位分成A和B并不是简单的“一个难一个简单”。A岗偏向搜索、推荐、广告这类业务型算法它们更看重模型效果和AB实验而B岗更像是平台型或基础型算法服务的可能是配送调度、运筹优化、图像识别、语音信号处理这类硬核场景。这类岗位对算法原理的掌握程度要求很高因为你要直接跟数据结构和计算过程打交道而不是调个包就完事。所以你会发现试卷里出现的内容很多都是教科书里的“标准件”。比如字符串匹配、拓扑排序、最小生成树、最短路、动态规划甚至PID控制和sobel算子这些工科基础都会以选择题的形式出现。这其实传递了一个信号美团B岗的算法工程师得是能看懂底层实现、能做性能优化、能处理真实物理世界数据的工程师而不是仅会调用框架的“调参侠”。2. 核心算法题解析从KMP到贪心与动态规划2.1 字符串匹配与KMP算法next数组到底在干什么那场笔试的选择题里有一道是关于KMP算法的next数组计算。题目给了模式串pabacaba要求手算next数组。很多人一看到这道题就慌了因为平时刷LeetCode很少手推next数组都是直接背模板。KMP的核心思想其实一句话就能讲清楚当匹配失败时不要从头再来而是利用已经匹配的部分信息把模式串尽可能右移。next数组就是“已经匹配的前缀中最长相等前后缀的长度”。对于“abacaba”这个串它的前后缀关系是这样的前缀包括a、ab、aba、abac、abaca、abacab后缀包括a、ba、aba、caba、acaba、bacaba最长相等前后缀是“aba”长度为3。所以当最后一个字符匹配失败时我们可以直接跳到模式串的第4个字符索引3继续比较。我在实际做题时有个习惯就是先把next数组和nextval数组分开记。nextval是优化版本它处理了“当p[next[j]] p[j]时直接跳到next[next[j]]”的情况。笔试里如果没有特别说明通常默认求next数组。但如果你能额外写出nextval的区别在简答题里会很加分。我当时的做法是先在草稿纸上画出模式串每个位置的前后缀匹配表再逐位填入next值这样不容易错。2.2 排序算法与贪心这道题不只是考冒泡排序编程题第一道我记得很清楚是一道“最少等待时间”的调度问题。题目描述类似有若干个任务每个任务有处理时长要求安排执行顺序使得所有任务的平均等待时间最小。这题一看就是贪心策略是最短作业优先。要证明这个策略的正确性可以用交换论证法假设有两个任务a和b处理时长分别为Ta和Tb。如果先a后b那么总等待时间是Ta (TaTb)如果先b后a总等待时间是Tb (TbTa)。两者相差(Ta-Tb)所以Ta越小先执行它就越优。用这个思路对处理时长排序然后依次累加等待时间就是答案。但这里有个坑任务可能还有优先级、截止时间等约束。如果只按处理时长排序很可能忽略掉“带权等待时间最小”这个变种。带权的话就要用“处理时长/权重”来排序也就是Smith规则。我当时先把简单版本写完再检查题目里有没有权重约束确认没有才提交。这个检查习惯帮我避免过一次拿题就做的失误。从这道题能看出来美团考察的重点不是你能不能默写出冒泡排序而是你能不能从实际问题里抽象出“该用什么策略”和“为什么这个策略是对的”。2.3 图论与最短路Dijkstra算法的实际场景变形另一道编程题考的是Dijkstra但不是一个裸的最短路模板而是城市配送场景若干个配送点每个点之间有距离有些点之间因为管制不能通行要求计算从一个点到另一个点的最短时间并且在距离相同的情况下优先选择经过配送站数量更少的路径。这就是Dijkstra的经典变形——双关键字最短路。实现上可以用dist[i]存最短距离cnt[i]存对应最短距离下最少经过的节点数。在松弛时如果dist[v] dist[u] w就同时更新dist和cnt如果dist[v] dist[u] w就取cnt[v] min(cnt[v], cnt[u]1)。这个细节很多人会漏掉结果只能过部分测试用例。还有一个更细的坑如果图是无向图边的松弛要双向进行如果是用邻接表存图注意不要重复添加边导致内存翻倍。我当时选择用Python的heapq实现优先队列优化版的Dijkstra注意Python的堆默认是小根堆所以压入时存(dist, node)的顺序不能反。熟练使用这些模板能帮你在笔试里挤出至少十分钟的时间去检查前面的选择题。3. 机器学习与深度学习基础B岗也不放过的模型题3.1 模型评估与特征工程样本不均衡、交叉验证和评估指标选择题里有一道题问“在正负样本比例1:99的情况下以下哪个指标最能反映模型性能”选项有准确率、精确率、召回率、F1-score、AUC。如果你背过八股会直接选AUC但题目如果继续追问“为什么”很多人就答不上来了。AUC对样本不均衡不敏感因为它衡量的是排序能力本质上是随机取一个正样本和一个负样本正样本得分高于负样本的概率。所以不管正负比例怎么变这个相对排序关系不太受影响。而准确率在样本极不均衡时会虚高——模型全预测成负样本准确率也有99%。美团这类公司特别看重候选人对评估指标的理解程度因为推荐、搜索、广告场景里样本不均衡才是常态。我当时在简答题里还写到了交叉验证的做法特别是分层K折要保证每一折的正负样本比例和全局一致。这道题还延展到一个高频考点如果你的CTR模型点击率只有1%你会用什么采样方式训练这已经不完全是在考算法了而是在考你对真实业务的理解。3.2 深度学习与过拟合激活函数、Dropout和BatchNorm还有一道选择题考查了深度学习的基础知识在ReLU、sigmoid、tanh中哪个激活函数在深层网络中更容易导致梯度消散这道题不算难但我看到的时候提醒自己要多想一步为什么ReLU能缓解梯度消散因为它在正区间导数为1不会把梯度越乘越小但也因此可能出现“神经元死亡”问题即某个神经元输出恒为0梯度再也无法回流。笔试里考这种题说明B岗并不是完全不碰模型。它可能不需要你做SOTA炼丹但要你理解模型底层的数值计算过程。比如BatchNorm为什么能加速收敛因为它把每一层的输入分布拉回到均值为0、方差为1的区间缓解了Internal Covariate Shift。Dropout为什么能缓解过拟合因为它每轮随机丢弃一部分神经元等价于训练了多个子网络的集成。我当时把这些答案都组织成了“原理公式效果”的结构后来想想这种答题方式对阅卷人来说确实友好一眼就能看出你是否真的懂。3.3 集成学习与聚类从XGBoost到K-Means的高频考点试卷里还出现了一道关于XGBoost的选择题问XGBoost相对于GBDT做了哪些改进。它的核心改进包括目标函数加入了正则项、用了二阶泰勒展开、支持列抽样、能自动处理缺失值。如果有简答题让你写XGBoost的损失函数一定要写出Obj Σl(y_i, ŷ_i) ΣΩ(f_k)并且强调正则项在控制模型复杂度中的作用。聚类算法也考了一道问K-Means的优缺点以及怎么选K值。K-Means简单高效但对初始聚类中心敏感容易陷入局部最优所以实际用的时候一般会跑多次取最好结果或者采用K-Means初始化。选择K值可以用肘部法则也可以用轮廓系数。我在答题时顺手写了一个“可以用Gap Statistic做统计检验”的进阶答案这算是给阅卷人一个惊喜点。如果你面试时被问到类似问题这招同样好用。4. 场景题与工程题从PID控制到图像算法基础4.1 配送场景里的算法设计PID和运筹优化的应用有一道场景题我记得大概是“外卖配送的骑手在途中遇到红绿灯、电梯等待等不确定因素预计送达时间不准请你提出一个算法方案来动态修正配送时间。”这个题其实是个开放题没有标准答案但你说到什么程度直接反映你的工程经验。我当时答的角度是把配送时间修正建模成一个控制问题用PID控制器的思路动态调整。我们可以设定一个目标——剩余配送时间误差趋近于0然后用实际的超时误差作为输入P项负责按当前误差比例修正I项负责累积消除稳态误差D项负责抑制突发波动。当然这不是真的给骑手发指令而是给调度系统一个更精确的预计时间。后来我了解到美团这类平台的订单预计时间背后确实有大量ETA模型和动态修正模块PID思路虽然不是最终方案但作为答题切入点至少能体现你有跨学科迁移能力。与之相关的还有一道小题提到了“MPPT算法”这类电气工程的概念。虽然和美团核心业务关联不大但它们在硬件或者IoT场景里属于常见算法。我当时就在想可能是想考察候选人的知识广度。遇到这种不会的题不要慌直接跳过先把有把握的分数拿住。4.2 图像处理基础sobel算子和拉普拉斯算子到底怎么用选择题里有一道图像处理相关的题目问“用于边缘检测的一阶微分算子有哪些”选项里有sobel、拉普拉斯、canny、高斯滤波等。其实sobel是一阶微分算子拉普拉斯是二阶微分算子canny是一阶二阶的组合高斯滤波是平滑操作。这道题本身不难但能看出来B岗可能会接触图像、视频相关的算法任务不一定是做CV但底层的图像处理知识不能是空白。如果你对图像算法不熟我建议至少掌握sobel用来求梯度幅值和方向拉普拉斯对噪声敏感所以通常先做高斯平滑再求拉普拉斯也就是LoG。还有非极大值抑制、双阈值检测这些canny流程。它们虽然只是知识点但在笔试选择题里经常出现属于“背了就能拿分”的部分。4.3 信号处理和其他工程算法音频重采样与卡尔曼滤波另一道题考了音频重采样算法。音频重采样的本质是插值常见方法有最近邻插值、线性插值、三次样条插值、FFT插值等。你要是用过音频库一定知道librosa里的resample函数它默认用的kaiser窗重采样效果比朴素的线性插值好很多。这道题背后的逻辑是考察你是否具备处理非结构化数据的能力以及是否理解采样率变化对信号频谱的影响。还有一道选择题提到了卡尔曼滤波。卡尔曼滤波的五大公式本质上是“预测更新”的迭代过程用状态方程预测再用观测数据修正整个过程是在高斯噪声假设下的最优线性估计。我建议你在复习时亲手推导一遍一维卡尔曼滤波的公式因为笔试不一定会让你手推但面试时挺容易让你讲清楚它和普通低通滤波的区别。5. 常见问题与排查技巧实录5.1 时间分配选择填空一卡就是半小时我自己的一个教训是选择题里如果连续两道题不会就容易心态失衡导致后面编程题时间不够。后来复盘时我总结了一条规则选择题单题思考时间超过3分钟就先跳先保证编程题能完整提交。因为编程题的分值更大而且只要过了样例就能拿大部分分。你可以先把所有会做的题做完再回头啃难题。5.2 边界条件编程题最常见的失分点很多人在做调度类题目时容易漏掉任务时长为0的情况。这个情况听起来很离谱但真实业务里完全可能存在——一个已取消的订单、一个长度为0的音频帧。如果你的排序算法没有处理这种边界后续累加等待时间的逻辑就会出错。另一类边界是数据范围例如n达到10^5时O(n^2)的算法一定会超时这时你得提前意识到需要用O(nlogn)或O(n)的解法。5.3 简答题只给结论不给推导等于没答笔试简答题里我见过很多人只写“使用交叉验证评估模型”却不写具体怎么做、为什么这么做。阅卷人想看到的是你的推导过程和思考深度。比如你写交叉验证至少要说清楚数据集怎么划分、评估指标是什么、如何避免数据泄漏、为什么用分层采样。如果你还能补充一句“在时间序列场景下应该用前向验证而不是K折”那就是高分答案。5.4 知识盲区急救遇到不会的题先猜考点我在考场上也遇到过完全没见过的概念比如某个音频处理术语。那时我的策略是根据选项反推先把明显错误的排除掉再把最接近的选项选上。如果是简答题就把自己知道的相关内容写上去并且注明“这个方向我了解不多但根据经验判断……”。至少能给阅卷人一个“这个候选人有逻辑”的印象比留空白强得多。当然这种急救方法只是止损真正稳妥的做法还是在复习时把高频考点覆盖全。6. 笔试复盘与后续准备建议这个部分我用自己的做法来分享。笔试交卷后我第一时间把当时没把握的题全部重新做了一遍并把它们归类到不同的知识模块数据结构、图论、机器学习、图像处理、信号处理。做完之后我给自己列了一张表每一类写清楚“掌握程度、易错点、下一步复习方向”。这种复盘方式能让你在后续面试前快速定位薄弱项而不是漫无目的地刷题。如果你正在准备类似的笔试我建议你至少把这几块内容过一遍数据结构与算法KMP、堆排序、Dijkstra、拓扑排序、贪心证明、动态规划状态定义。机器学习基础模型评估指标、交叉验证、正则化、偏差方差分解、集成学习。深度学习基础反向传播、梯度消失/爆炸、BatchNorm、Dropout、不同激活函数的对比。工程基础PID控制、卡尔曼滤波、音频重采样、图像边缘检测算子。按这个框架准备即使遇到没有见过的题目你也能根据考点归类找到思路而不是完全无从下手。最后再说一个我在实际刷题中发现的规律大厂笔试不一定追求偏题怪题反而特别爱考那些“课本里反复出现但你从来没手推过”的知识点。比如KMP的next数组、Dijkstra的双关键字扩展、XGBoost的损失函数推导。你平时用框架、调库、复制模板太顺手了这些基本功反而容易生疏。所以我的建议是每周至少抽两小时关掉IDE自动补全用纯文本编辑器手写一遍常见算法的核心逻辑写不出来就返回去再看。这样练上一个月笔试时的思路会明显清晰很多。