☰
京东算法岗笔试全解析:从KMP到模拟退火的高频考点
2026/10/24 13:36:13 网站建设 项目流程

京东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是京东这类大厂笔试的常客。热词里专门提到“对于模式串p='abacaba',其next数组”,这种题目考察的不是你会不会用KMP,而是你对next数组到底理解了没有。next[i]的定义是“模式串p中前i个字符组成的子串中,最长相等前后缀的长度”。以p="abacaba"为例,我们逐个推:

  • 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引入了文档长度归一化和饱和函数,可以有效避免长文档占便宜。精排层可以用深度学习模型,比如DIN(Deep 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_a'Q(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; vector<int> buildNext(const string& p) { int m = p.size(); vector<int> 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) { vector<int> 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]直接取值,忽略了还要比较字符。笔试如果考手写代码,建议把这段代码背下来,同时能讲清楚“为什么失配时j=next[j-1]”。

3.2 快排与堆排序容易翻车的边界处理

快排在笔试里出现频率极高。下面是一个简洁的随机化快排模板:

#include <vector> #include <algorithm> using namespace std; void quickSort(vector<int>& 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(vector<int>& 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(vector<int>& 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); } }

容易出错的地方:建堆时从最后一个非叶子节点开始,而叶子节点不需要调整;每次交换堆顶和堆尾后,堆的大小减1,heapify的范围是i而不是n。如果笔试机器环境比较老,不能用C++11的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_iter=100): # X: (N, d) n, d = X.shape centers = X[np.random.choice(n, k, replace=False)] for _ in range(max_iter): distances = np.linalg.norm(X[:, None, :] - centers, axis=2) labels = np.argmin(distances, axis=1) new_centers = np.array([X[labels == i].mean(axis=0) 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开始、空数组、单元素数组、负数等。

我在实际做京东在线编程题时,养成了一个习惯:写完代码后先自测极端用例,比如vector<int> 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) * (k1+1)) / (f(qi,D) + k1 * (1 - b + b * |D|/avgdl))),其中k1约取1.2,b约取0.75;相比TF-IDF,BM25对长文档更友好,词频饱和效果更好。然后补充能想到的优化:针对京东商品短标题的特点,可以调整b值,或者引入商品点击率加权。这样既有公式又有落地思考。如果只是写“用BM25算法”,那等于没写。

5. 备考建议与扩展思路

5.1 按知识点建自己的“算法题模板库”

京东2019春招算法类试卷涉及的算法点,很多都能套模板。我建议你把每个高频算法整理成“模板卡片”,包括:算法原理、适用场景、标准代码、复杂度和易错点。比如KMP一张卡、快排一张卡、Dijkstra堆优化一张卡、K-Means一张卡。这样考前不需要重新翻几百道题,只需要过一遍模板卡。

模板卡要注意“精”而不是“多”。我见过有人整理了几十张卡,每张都大段复制代码,但真正遇到变体题时还是不会用。正确做法是每个模板配一道真题或改编题,并写上“为什么这个场景能用这个算法”。比如看到“最小生成树”的题,你要能迅速反应出这是Kruskal或Prim模板;看到“区间调度”的题,要能想到贪心按结束时间排序。这个“看到题—映射到模板”的反射速度,就是刷题的目的。

5.2 结合业务扩展:从试卷到项目实战

如果你正在准备类似京东这样的电商公司算法岗,只刷题是不够的。建议找一个和业务相关的开源数据集,完整跑一遍搜索/推荐/风控流程。哪怕只是一个小的KNN分类器或K-Means聚类,也要把数据清洗、特征标准化、交叉验证、结果评估做完整。我在面试候选人时,比起“我用了XGBoost,AUC到了0.9”,更欣赏“我发现特征A存在大量缺失值,因为业务含义是用户手动填写的标签,所以我把缺失值单独编码为一个类别,AUC提升了1%”这种回答。

试卷里的算法是“术”,把算法用到业务里是“道”。京东的笔试是一个检测点,但长期来看,你的竞争优势来自对业务问题的理解和解决问题的能力。热词里的“规则引擎drools的rete算法实现原理和事实匹配过程”“工业异常检测算法”这些,都需要你在实战中积累。

5.3 还想再补充一个冷门但可能踩坑的点

选择题偶尔会考“外部排序”和“大数据算法”。比如有10亿条京东用户购买记录,内存只有1GB,如何按用户ID排序。这时候不能用普通快排,要想到外部排序:分块读入,块内快排,然后多路归并。热词里虽然没有直接出现,但“排序算法”和“数据量”是常考组合。这道题在京东考过不止一次,很多人上来就答“快排”,忽略了内存限制。看到“海量数据”“内存受限”这些关键词,优先考虑分治+归并。

还有“快速幂算法C++”,这是数学类题目的底座。计算a^b mod q,b的范围可能达到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; }

这个方法可以用于计算组合数、哈希碰撞概率等很多场景,建议和“快速幂”一起记下来。

最后再分享一个我个人的体会:刷京东这套试卷,最大的收获不是记住某个算法的代码,而是训练出一种“算法直觉”——看到题意,能快速判断出题人想考察哪个知识点,并顺着那个知识点的经典解法往下推。这种直觉需要大量刻意练习,但一旦建立起来,应对其他大厂的算法笔试也会轻松很多。在准备过程中,多给自己模拟考试的压力环境,严格限时手写代码,练完后再复盘每道题的知识点和优化空间,坚持一段时间,你会发现自己的编码速度和对算法的理解都会上一个台阶。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询