
京东2019春招京东算法类试卷我自己当年也刷过不少后来还帮学弟学妹做过好几次复盘。这套试卷虽然名字带着“2019”但里面的考点到现在依然是国内互联网大厂算法岗笔试的“标配套餐”基础数据结构、排序与字符串、机器学习与深度学习理论、以及带有业务色彩的算法应用题。无论你是准备校招、跳槽还是单纯想系统梳理算法知识这套试卷的考察逻辑都很值得研究。先说一个核心判断京东算法类试卷并不追求“偏题怪题”它更看重候选人的基本功是否扎实、能不能把算法模型落到真实的电商场景里。比如搜索排序、供应链预测、用户画像、图像审核这些都是京东业务的高频场景。试卷里的题目会刻意把理论知识和这些场景绑定如果你只刷LeetCode不关注业务很容易在简答题和应用题上卡壳。这篇文章不是带你背答案而是把试卷背后隐藏的考点、原理、手写代码的细节、以及我踩过的坑拆开揉碎讲一遍。内容会覆盖KMP、排序、贪心、最短路、聚类、KNN、粒子群、模拟退火、卡尔曼滤波这些高频点并给出可以直接复用的实操思路。1. 京东算法岗位与试卷整体思路拆解1.1 春招算法岗都有哪些方向试卷到底在筛什么京东的算法类岗位不是只有“算法工程师”一个名字实际招聘里会分成搜索推荐算法、供应链与运筹优化算法、风控算法、自然语言处理、计算机视觉等好几条线。2019春招面向次年毕业或当年毕业补录和秋招相比时间更紧岗位更偏向于“来了就能上手”的同学所以笔试题目会更侧重基础编码能力、机器学习理论、以及对业务场景的理解。试卷在筛选上分了两层。第一层是“硬实力”数据结构、排序、字符串、图论、动态规划这些基础算法题必须写得快、写得对。线上编程题通常有2到3道每道题要求在30到40分钟内完成工程能力不够很容易超时。第二层是“软实力”简答题和场景题考察你是否理解某个算法为什么在这个场景下有效比如“为什么京东搜索要用BM25而不是简单的TF-IDF”“推荐系统冷启动有哪些方案”。这两种题型的解法完全不同基础题靠刷题肌肉记忆场景题靠业务积累和归纳能力。1.2 试卷结构、题型分布与时间分配策略从题型结构看京东2019春招算法类试卷大概分三大部分单选多选、编程题、简答/场景题。选择题覆盖的范围很广从“KMP算法中next数组的求法”到“堆排序的稳定性”“bootstrap抽样与bagging的关系”都有可能出现。编程题通常围绕字符串处理、数组操作、动态规划展开难度介于LeetCode Medium到Hard之间。简答题则会给出一个业务问题让你设计方案。时间分配上我的经验是选择题控制在30分钟内不要在一两道偏题上纠结编程题留出70到90分钟优先做有明确思路的题最后留20分钟写简答题。很多同学喜欢先做简答题觉得“写文字比写代码快”其实简答题很容易写多而且分值不一定比编程题高。先把代码题拿到满分再回头写文字题心态会更稳。2. 高频考点深度解析与实战要点2.1 数据结构与基础算法KMP、排序、堆、图论是永远的主旋律字符串算法里KMP是京东这类大厂笔试的常客。热词里专门提到“对于模式串pabacaba其next数组”这种题目考察的不是你会不会用KMP而是你对next数组到底理解了没有。next[i]的定义是“模式串p中前i个字符组成的子串中最长相等前后缀的长度”。以pabacaba为例我们逐个推next[1]0因为只有a没有真前后缀。next[2]对应ab前缀a后缀b不相等所以是0。next[3]对应aba前缀a后缀a相等长度1再长一点前缀ab后缀ba不等所以是1。next[4]对应abac最长相等前后缀是0。next[5]对应abaca前缀a后缀a相等长度1前缀ab后缀ca不等所以是1。next[6]对应abacab前缀ab后缀ab相等长度2更长的前缀aba后缀cab不等所以是2。next[7]对应整个串abacaba最长的相等前后缀是aba长度3所以next[7]3。如果你把next数组理解为“失配后模式串跳转的位置”那是nextval的变体容易混淆。笔试里看清题目给的是next还是nextval避免踩坑。排序算法同样是必考。冒泡排序C版本虽然简单但不少同学在“每轮是否提前退出”这种细节上翻车快速排序要注意pivot选取和递归终止堆排序则要分清“建堆”和“堆调整”操作。热词里还有“排序算法”“数据结构排序算法”说明这属于基础盘。一个关键知识点稳定的排序算法有哪些归并排序、插入排序、冒泡排序、基数排序是稳定的快速排序、堆排序、选择排序不稳定。京东试卷可能会用选择题考你“哪些排序算法是稳定的”以及“快排最坏时间复杂度”遇到的话要能秒答。图论算法里Dijkstra是最短路的常客。它适用于非负权图核心是贪心每次从当前未确定最短路的节点中选一个距离最小的松弛它的邻居。很多人写Dijkstra时用堆优化但容易忽略“同一个节点可能被多次push进堆”需要在出堆时判断visited。Kahn算法则是拓扑排序的经典实现不断删除入度为0的节点并用队列维护删除顺序。它常用于检测有向图是否有环以及任务调度场景。京东供应链里有大量流程依赖问题这个考点非常贴近业务。2.2 机器学习与深度学习基础聚类、KNN、损失函数、注意力机制机器学习部分是选择题和简答题的大头。聚类算法里K-Means是默认的“万金油”考点。你要清楚K-Means的步骤随机初始化K个中心点计算每个样本到中心的距离并分配簇重新计算每个簇的均值重复直到中心点不再变化或达到最大迭代。热词里专门有“knn算法的应用能力包括哪三个方面”说明KNN也常考。KNN的三个应用能力是指分类、回归、异常检测。分类是多数投票回归是取均值或加权均值异常检测则是看样本与邻居的距离是否过远。这里面有一个容易忽视的细节KNN没有显式训练过程它是“懒惰学习”每次预测都要计算样本与全部训练数据的距离所以在京东海量用户数据场景下朴素KNN很难直接用通常要配合KD-Tree或局部敏感哈希。深度学习的考察更偏基础原理。神经网络的反向传播、损失函数选择、过拟合抑制是三大常客。热词里还有“kl elbo算法原理详解”这是变分自编码器(VAE)的核心概念。ELBO证据下界推导时要用到Jensen不等式把对数边际似然分解成重构项和KL散度项。如果笔试出现这类题通常不会让你推完整公式而是问“VAE的损失函数为什么由重构损失和KL散度组成”。我当时写了一个不错的答案直接优化边际似然不可行转而优化它的下界重构损失鼓励隐变量编码有效信息KL散度约束隐变量分布接近先验两者互相平衡。很多同学容易忽略的是“传统机器学习与深度学习的对比”。比如决策树与随机森林、GBDT与XGBoost的区别京东场景题特别爱考。XGBoost在GBDT基础上加了正则项、二阶泰勒展开和列抽样这些内容如果没系统梳理过简答题很难写出彩。2.3 业务场景算法搜索排序、推荐、运筹优化、异常检测京东作为电商平台搜索推荐是算法岗的核心方向。试卷里很可能出现“如何设计一个商品搜索排序模型”。这时候你不要只回答“用CTR预估”而要从召回、粗排、精排三个层级展开。召回层可以用BM25算法对商品标题和描述打分BM25相比TF-IDF引入了文档长度归一化和饱和函数可以有效避免长文档占便宜。精排层可以用深度学习模型比如DINDeep Interest Network等结合用户历史行为序列建模。供应链与运筹优化是京东非常看重的一块业务。热词中的“粒子群算法原理”“模拟退火算法”“pid算法在crps psu power的作用”“foc算法”都指向了优化控制方向。粒子群算法和模拟退火都是元启发式算法常用于求解路径规划、库存优化、调度问题。京东物流的配送路径优化本质上是一个带约束的车辆路径问题VRP精确算法算不了就需要用启发式算法。如果你能在简答题里提到“用模拟退火求解TSP温度下降策略选择线性或指数邻域操作用2-opt”面试官会认为你真正做过落地。异常检测也是电商风控的常见话题。“工业异常检测算法”热词提示我们需要了解孤立森林、局部异常因子、基于重构误差的深度异常检测。京东风控场景中刷单、恶意评价、盗号行为都属于异常检测。一个常用的套路是先用无监督方法孤立森林/自编码器做召回再用有监督模型做精排。如果笔试问到“如何识别恶意用户”这个思路就很有用。2.4 热门算法与边缘考点卡尔曼滤波、强化学习、PID控制卡尔曼滤波和PID控制虽然不是所有算法岗都会遇到但在京东的供应链、仓储机器人、自动驾驶配送车等方向它们可能是加分项。热词里“卡尔曼滤波算法”“增量式pid算法”都出现了。卡尔曼滤波的核心是预测和更新两个步骤预测阶段用状态转移方程预测先验状态和协方差更新阶段用卡尔曼增益融合预测值和观测值。很多人记不住公式我的窍门是把它理解成一个“带权重的平均”权重由预测误差和观测噪声的比值决定。PID算法属于控制领域但在仓储机器人、无人机配送中经常用到。增量式PID只是输出控制量的增量它相比位置式PID的优势是没有积分饱和问题且对执行器的冲击更小。理解它的关键在于比例、积分、微分三个环节的意义比例消除当前误差积分消除稳态误差微分抑制超调。热词中“pid算法在crps psu power的作用”虽然听起来很垂直但背后的思想是通用的。强化学习热词也出现了京东在推荐、定价、广告竞价等场景都尝试过强化学习。笔试往往只考概念比如马尔可夫决策过程、Q-learning更新公式、策略梯度中的REINFORCE。要牢记Q-learning的更新公式Q(s,a)Q(s,a)α[rγ·max_aQ(s,a)-Q(s,a)]。同时与确定性策略梯度(DDPG)比较DDPG使用了Actor-Critic框架适合连续动作空间。能把这些说清楚已经超过大多数候选人。3. 实操复现几类典型题目与关键实现3.1 手撕KMP从next数组到匹配过程京东2019春招选择题曾经考过next数组计算编程题有可能让你实现KMP匹配。我建议你手写一遍标准代码不要用STL的find糊弄。下面是C的KMP实现含next数组的求解和匹配#include vector #include string using namespace std; vectorint buildNext(const string p) { int m p.size(); vectorint next(m, 0); int j 0; for (int i 1; i m; i) { while (j 0 p[i] ! p[j]) { j next[j - 1]; } if (p[i] p[j]) { j; } next[i] j; } return next; } int kmpSearch(const string s, const string p) { vectorint next buildNext(p); int n s.size(), m p.size(); int j 0; for (int i 0; i n; i) { while (j 0 s[i] ! p[j]) { j next[j - 1]; } if (s[i] p[j]) { j; } if (j m) { return i - m 1; // 返回首次匹配的起始位置 } } return -1; }注意buildNext里用的是“当前匹配的前缀长度”回退这实际上是next数组的经典写法。求next[i]时我们利用p[0..i-1]已经求出的next值通过while循环不断回退。很多人会在这里写错成从next[i-1]直接取值忽略了还要比较字符。笔试如果考手写代码建议把这段代码背下来同时能讲清楚“为什么失配时jnext[j-1]”。3.2 快排与堆排序容易翻车的边界处理快排在笔试里出现频率极高。下面是一个简洁的随机化快排模板#include vector #include algorithm using namespace std; void quickSort(vectorint nums, int l, int r) { if (l r) return; int idx l rand() % (r - l 1); swap(nums[l], nums[idx]); int pivot nums[l]; int i l, j r; while (i j) { while (i j nums[j] pivot) --j; nums[i] nums[j]; while (i j nums[i] pivot) i; nums[j] nums[i]; } nums[i] pivot; quickSort(nums, l, i - 1); quickSort(nums, i 1, r); }很多人写快排时使用“挖坑法”先保存pivot然后从右往左找比pivot小的填左边再从左往右找比pivot大的填右边最后把pivot放回i位置。要特别注意循环里的“”和“”如果去掉等于号数组中有大量重复元素时会无限循环。堆排序的核心是“向下调整”void heapify(vectorint nums, int n, int i) { int largest i; int left 2 * i 1; int right 2 * i 2; if (left n nums[left] nums[largest]) largest left; if (right n nums[right] nums[largest]) largest right; if (largest ! i) { swap(nums[i], nums[largest]); heapify(nums, n, largest); } } void heapSort(vectorint nums) { int n nums.size(); for (int i n / 2 - 1; i 0; --i) heapify(nums, n, i); for (int i n - 1; i 0; --i) { swap(nums[0], nums[i]); heapify(nums, i, 0); } }容易出错的地方建堆时从最后一个非叶子节点开始而叶子节点不需要调整每次交换堆顶和堆尾后堆的大小减1heapify的范围是i而不是n。如果笔试机器环境比较老不能用C11的lambda这种标准代码要烂熟于心。3.3 用模拟退火求解TSP的完整思路京东物流路径规划特别适合用模拟退火做演示。假设有N个城市坐标求一条最短的遍历所有城市的路径。模拟退火的核心是以一定概率接受比当前解更差的解概率随温度降低而减小。初始温度可以设为1000终止温度设为1e-3降温系数设为0.998。每次迭代中用“2-opt”交换产生新解随机选择两个位置i、j把i到j之间的子路径逆序。伪代码如下current 随机初始路径 temperature 1000 while temperature 1e-3: new_solution 2opt(current) delta length(new_solution) - length(current) if delta 0: current new_solution else: if random() exp(-delta / temperature): current new_solution temperature temperature * 0.998 输出current很多同学问我既然可以随机产生邻居为什么用2-opt而不是随机交换两个城市因为2-opt是相邻边交换产生的新解与当前解差距不大更容易保持局部结构的优势收敛速度也快。而随机交换两个城市会破坏路径的两个片断效果差很多。这类细节在面试中讲出来会成为加分项。3.4 机器学习手写题K-Means与KNN的Python实现笔试偶尔会让你写K-Means的伪代码或简单Python实现。核心就三步初始化中心、分配样本、更新中心。下面是一个用numpy写的最小实现import numpy as np def kmeans(X, k, max_iter100): # X: (N, d) n, d X.shape centers X[np.random.choice(n, k, replaceFalse)] for _ in range(max_iter): distances np.linalg.norm(X[:, None, :] - centers, axis2) labels np.argmin(distances, axis1) new_centers np.array([X[labels i].mean(axis0) for i in range(k)]) if np.allclose(centers, new_centers): break centers new_centers return labels, centers这里有个重要陷阱如果某个簇没有分配到样本X[labels i]会是空数组mean会得到nan。笔试中要处理这种情况常见做法是重新随机初始化这个中心或者删除空簇。另外K-Means对初始中心敏感所以实际中常用K-Means初始化。如果在笔试中主动写出“我用K-Means来减少局部最优的风险”面试官会觉得你理解得深。KNN的实现更简单但笔试可能考察的不是代码而是数学上的“距离归一化”。因为KNN基于距离度量如果特征量纲不同比如身高和收入收入会主导距离必须做标准化。4. 常见问题与排查技巧实录4.1 时间复杂度和边界条件从TLE到WA的坑笔试中最常见的问题是代码超时TLE和答案错误WA。TLE通常说明算法复杂度太高比如字符串匹配用了O(n*m)暴力而数据量是10^5肯定过不了。这时候要立刻想到KMP或者字符串哈希。WA则往往藏在边界条件里数组越界、循环变量从0还是1开始、空数组、单元素数组、负数等。我在实际做京东在线编程题时养成了一个习惯写完代码后先自测极端用例比如vectorint nums {}、{5}、{1,1,1,1}、所有元素相等的情况。很多排序和二分题目在重复元素多的时候容易翻车。KMP的边界是模式串为空快排的边界是左右指针交错堆排序的边界是堆大小为1时。这些一开始就要想清楚而不是等测试用例报错再改。4.2 浮点精度与随机性问题算法题中经常涉及浮点数比较比如模拟退火里面计算路径长度由于double精度直接用比较可能出错。解决方法是设一个eps比如if (abs(a - b) 1e-6)。在聚类题目中如果让输出聚类中心要注意输出格式比如保留四位小数。京东选择题里也会问“下面哪个算法受随机数影响最大”答案大概率是随机森林中的特征抽样或K-Means初始中心。随机性问题还体现在代码的可复现性上。在笔试环境里如果使用了rand()每次运行结果可能不同。有些题目要求输出固定答案而你的算法里有随机初始化这时候要设置固定随机种子的习惯比如srand(0)或np.random.seed(42)。当然有些在线评测系统会忽略随机种子但你至少要在代码注释里说明“为了可复现设置了种子”表现出你的工程素养。4.3 手写代码的规范与测试习惯很多人都以为笔试只要答案正确就行其实代码风格和测试习惯也在面试官的评分量表里。函数命名要有意义不要写a、b这种变量要有分模块的注释不要在main函数里写几百行逻辑至少分成一个独立的函数。我在自己面试别人时如果看到候选人的代码没有边界检查、没有空指针判断第一印象就会差很多。有一个实用技巧写完函数后直接在旁边列出三个测试用例和预期结果。比如写快排列出[4,2,7,1] - [1,2,4,7]、[5] - [5]、[3,3,3] - [3,3,3]。虽然在线笔试不会要求你输出测试用例但这样能帮你快速定位逻辑错误。如果可以用本地IDE一定要先运行这几个用例再提交。4.4 机器学习场景题的常见回答误区场景题最容易犯的毛病是“答得太泛”或者“堆术语”。比如“如何做商品推荐”很多人会从协同过滤说到FM再到深度学习但没有任何细节。面试官想听到的是你做过的具体方案、遇到的数据问题、怎么评估。即使是笔试简答题也要有“假设—方案—验证”的结构。比如问到“京东搜索的召回阶段怎么做为什么用BM25”我会这样写首先分析商品标题和类目构建倒排索引BM25计算query与doc的score公式为sum(idf(qi) * (f(qi,D) * (k11)) / (f(qi,D) k1 * (1 - b b * |D|/avgdl)))其中k1约取1.2b约取0.75相比TF-IDFBM25对长文档更友好词频饱和效果更好。然后补充能想到的优化针对京东商品短标题的特点可以调整b值或者引入商品点击率加权。这样既有公式又有落地思考。如果只是写“用BM25算法”那等于没写。5. 备考建议与扩展思路5.1 按知识点建自己的“算法题模板库”京东2019春招算法类试卷涉及的算法点很多都能套模板。我建议你把每个高频算法整理成“模板卡片”包括算法原理、适用场景、标准代码、复杂度和易错点。比如KMP一张卡、快排一张卡、Dijkstra堆优化一张卡、K-Means一张卡。这样考前不需要重新翻几百道题只需要过一遍模板卡。模板卡要注意“精”而不是“多”。我见过有人整理了几十张卡每张都大段复制代码但真正遇到变体题时还是不会用。正确做法是每个模板配一道真题或改编题并写上“为什么这个场景能用这个算法”。比如看到“最小生成树”的题你要能迅速反应出这是Kruskal或Prim模板看到“区间调度”的题要能想到贪心按结束时间排序。这个“看到题—映射到模板”的反射速度就是刷题的目的。5.2 结合业务扩展从试卷到项目实战如果你正在准备类似京东这样的电商公司算法岗只刷题是不够的。建议找一个和业务相关的开源数据集完整跑一遍搜索/推荐/风控流程。哪怕只是一个小的KNN分类器或K-Means聚类也要把数据清洗、特征标准化、交叉验证、结果评估做完整。我在面试候选人时比起“我用了XGBoostAUC到了0.9”更欣赏“我发现特征A存在大量缺失值因为业务含义是用户手动填写的标签所以我把缺失值单独编码为一个类别AUC提升了1%”这种回答。试卷里的算法是“术”把算法用到业务里是“道”。京东的笔试是一个检测点但长期来看你的竞争优势来自对业务问题的理解和解决问题的能力。热词里的“规则引擎drools的rete算法实现原理和事实匹配过程”“工业异常检测算法”这些都需要你在实战中积累。5.3 还想再补充一个冷门但可能踩坑的点选择题偶尔会考“外部排序”和“大数据算法”。比如有10亿条京东用户购买记录内存只有1GB如何按用户ID排序。这时候不能用普通快排要想到外部排序分块读入块内快排然后多路归并。热词里虽然没有直接出现但“排序算法”和“数据量”是常考组合。这道题在京东考过不止一次很多人上来就答“快排”忽略了内存限制。看到“海量数据”“内存受限”这些关键词优先考虑分治归并。还有“快速幂算法C”这是数学类题目的底座。计算a^b mod qb的范围可能达到10^18暴力肯定超时。快速幂核心是二进制分解指数把乘法次数从O(b)降到O(log b)。模板很简单long long fastPow(long long a, long long b, long long mod) { long long res 1; a % mod; while (b 0) { if (b 1) res res * a % mod; a a * a % mod; b 1; } return res; }这个方法可以用于计算组合数、哈希碰撞概率等很多场景建议和“快速幂”一起记下来。最后再分享一个我个人的体会刷京东这套试卷最大的收获不是记住某个算法的代码而是训练出一种“算法直觉”——看到题意能快速判断出题人想考察哪个知识点并顺着那个知识点的经典解法往下推。这种直觉需要大量刻意练习但一旦建立起来应对其他大厂的算法笔试也会轻松很多。在准备过程中多给自己模拟考试的压力环境严格限时手写代码练完后再复盘每道题的知识点和优化空间坚持一段时间你会发现自己的编码速度和对算法的理解都会上一个台阶。