2023携程春招技术岗笔试复盘:流程、题型与编程题解析

2023携程春招技术岗笔试复盘:流程、题型与编程题解析 如果正在准备携程或者其他互联赛道大厂的春招技术岗笔试这篇关于2023年携程春招技术通用岗第一批笔试的复盘应该能帮到你。我是在去年春季批次参加的这场笔试当时提前做了不少功课但真正坐到电脑前才发现很多细节和策略跟网上流传的经验贴是有出入的。这篇文章我会尽量还原笔试从考前准备到交卷的全过程把行测、专业选择题和四道编程题的题型结构、解题思路、踩坑点都拆开来讲最后附上针对下一届同学的备考优先级建议。无论你是第一次参加在线笔试还是想在编程题上再冲一冲分数这篇内容都值得收藏慢慢看。需要先说清楚的是大厂的在线笔试题目基本不会完整流出来以下内容是基于我参加的那场笔试以及和同期同学考后对题整理的复盘题目细节做了脱敏和还原核心考点和技术点是准确的。1. 笔试全流程复盘从收到通知到交卷的七个关键节点1.1 考前三天你需要做好的环境准备携程的春招笔试通知一般会提前三到五天发到邮箱和手机短信标题通常是“【携程校招】您已进入2023春招技术岗笔试环节”。收到通知之后真正考验人的不是刷题而是把考试环境准备好。我参加的第一批笔试使用的是牛客网在线笔试系统同时需要开启腾讯会议做第二机位监控。通知邮件里会附一个考务链接点进去之后能看到你的考试时间、考试链接、腾讯会议号以及一系列设备要求。这里有几个关键点很多人会忽略浏览器要用Chrome或者Edge的最新版本IE内核基本进不去答题页Firefox有时会出现代码编辑器显示异常。牛客网的系统对摄像头权限要求很严格如果浏览器里之前设置过“禁止摄像头”考试界面会直接提示检测不到人脸。建议提前一天在牛客网模拟笔试页面测一次。第二机位手机需要登录腾讯会议并且要保持全程开启摄像头。手机最好插上电源放在侧后方45度左右的位置能拍到你的手部和桌面。草稿纸一般允许准备一张A4空白纸和一支笔但考前需要对着摄像头展示正反面。我用一个表格把清单列出来方便你们考前逐项打勾项目要求备注浏览器Chrome/Edge最新版提前测试摄像头权限网络有线优先备用4G/5G热点断网会导致交卷失败第一机位电脑自带摄像头/外接摄像头能清晰拍到面部第二机位手机登录腾讯会议开飞行模式连WiFi防电话打扰草稿纸一张A4空白纸笔考前向摄像头展示身份证/学生证备好部分批次会抽查这些听起来都是小事但笔试当天真的会因为一件小事影响心态。我一个同学就是因为摄像头权限没开折腾了快十分钟才进入答题界面行测时间被严重压缩。1.2 笔试当天的时间线与真实体验第一批笔试的时间我记得是晚上19:00到21:00两个小时整。总体上分三个模块行测、专业基础选择题、编程题。但要注意这三个模块不是三张卷子分开发而是在同一个答题页面里按照顺序出现你可以自己控制每个模块的停留时间也可以跨模块回看修改答案。建议提前30分钟就进入腾讯会议等待考务人员会挨个检查第二机位摆放情况。19:00整牛客网页面会自动刷新出试题考试计时同步开始。进入答题页之后第一感受是选择题部分是可以分屏看别的资料的系统不会报警。但我不建议这么干一是没时间二是切屏记录会留在后台万一后面进入人工复核阶段有风险。编程题部分更敏感切出页面超过一定次数会被警告甚至强制交卷。编程题的代码编辑器是牛客网标准编辑器支持C、Java、Python、Go等主流语言但有一个让很多人不习惯的点没有自动补全。平时在IDE里写代码依赖提示的同学第一题可能会写得很慢。所以考前至少要用牛客网的在线编辑器练三五道题熟悉那种“裸写”的感觉。1.3 提交规则与防作弊细节决定生死携程的笔试系统有一个比较有特点的规则编程题允许多次提交以最后一次提交为准不会因为多次提交扣分。这意味着你写出一版能过的答案后不要急着交卷可以先提交一次保底如果时间充裕再回头优化。但是“编译错误”不会被当作有效提交一定要把代码跑通再提交。这个规则的分量等你遇到一道题一直卡在编译错误的时候就懂了。再就是代码查重。牛客网的系统会对所有提交代码做相似度检测不只是查同一场考试内的相似度还会和历史题库里的提交做比对。我当时有个朋友在最后一道题用了网上比较流行的模板写法虽然自己改了不少但相似度还是被判得很高最后这题直接被判0分。所以我的建议是参考别人的思路没问题但代码一定要自己重新写一遍变量命名、函数拆分的风格要带自己的习惯。2. 通用岗笔试题型分布与分值结构2.1 题型构成行测、专业选择、编程题三段式先给一张大致的题型分布表是我和几个同批同学考后拼出来的可能和官方分数统计有出入但结构基本准确模块题量分值占比建议用时行测言语理解/数字推理/图形推理/逻辑判断约10题15%-20%10分钟专业基础选择题数据结构/网络/OS/数据库/Java约20题25%-30%20分钟编程题4道难度递增4题50%-55%80-90分钟从分值结构能看出来编程题才是笔试的重头戏行测和专业选择题的定位更接近“门槛”。但注意“门槛”不等于“随便做”因为通用岗的简历筛选一直很凶笔试作为第一道硬性筛选行测和专业选择题的分数是会被用来拉排名的。我认识的一个同学编程题AC了三道半但行测正确率只有一半最后也进了面试说明编程题权重确实高但如果行测全蒙、选择半猜想靠四个编程题全对翻盘风险还是很大的。2.2 分值权重背后的策略含义“编程题占比过半”这个信息直接决定了答题顺序策略。我的个人建议是拿到试卷后先花30秒扫一遍编程题的四道题目大概判断难度梯度然后按顺序先把行测快速做完专业选择控制在20分钟内把最后剩下的时间全部砸在编程题上。为什么不是先做编程题因为行测和选择题在最前面界面上不支持一键跳到编程题模块。而且系统是按模块展示的你必须滚动到编程题区域才能看到题目。与其焦虑地来回翻不如老老实实按顺序推进把该拿的分都拿稳。还有一个容易被忽略的细节行测和选择题的答案是可以修改的但编程题提交后如果想改必须切回编程题区域重新编辑并再次提交最后一次提交才有效。所以先做完行测和选择可以避免后面回头改答案时把编程题的提交覆盖掉。2.3 时间分配的实战参考两小时怎么拆以我实际使用的时间线为参考19:00-19:10行测每题最多思考90秒超过就凭第一印象选。做完后不检查直接进入下一模块。19:10-19:30专业选择题涉及Java、数据结构、Linux、网络等主要靠平时积累。拿不准的先标记时间紧张时优先保证后面编程题。19:30-20:10编程题前两题。第一题基本是送分题10分钟内AC第二题是贪心或模拟题20分钟左右AC。20:10-20:50编程第三题和第四题。第三题能做出来最好第四题拿部分分。20:50-21:00检查前面选择题有没有漏答编程题是否都在最后一次提交状态。这个时间分配不一定适合所有人但思路是对的把大头时间留给分值最高的编程题行测和选择题用时压缩到极限。3. 编程题真题复盘四道题从读题到AC全过程3.1 第一题字符串还原简单题必须全拿第一题属于看完题就能动手的类型。题目大意是给定一个经过加密的字符串s加密规则是先将字符串反转再将每个字符的ASCII码值加3得到新字符。现在给定加密后的字符串要求输出原始字符串。输入输出示例输入khoor 输出hello思路非常直接先对每个字符做ASCII码减3的逆操作再反转字符串。但有一个边界状况在牛客网中很常见输入的字符串可能包含多行或者带前后空格。我们直接用Python的strip()方法处理掉换行符即可。s input().strip() 加密规则是反转ASCII码3 第一步每个字符ASCII码-3 第二步反转字符串 raw .join(chr(ord(ch) - 3) for ch in s) print(raw[::-1])这个题有两个实际踩坑点不要先反转再减3虽然理论上结果一样但容易在细节上绕晕。先把字符逐一还原再整体反转逻辑更清晰。不要用reversed()之后拼接字符串而不join直接print(.join(reversed(raw)))也是可以的但raw[::-1]更直观。第一题的唯一要求就是又快又稳。我当时想都没想直接写的大概3分钟解决。3.2 第二题区间覆盖的最少删除次数贪心第二题考查的是贪心算法题面是经典的区间调度变种。题目描述大致如下给定n个区间每个区间表示为[l, r]问最少删除多少个区间才能使剩下的区间两两不重叠两个区间端点重合不算重叠即l2 r1时不冲突。当时题目的数据范围是n不超过10的5次方l和r都是1到10的9次方。这个题的核心是“反过来想”如果已知最多能选多少个互不重叠的区间那么删除的最少数量就是总区间数 - 最多不重叠区间数。求解最多不重叠区间数用的是贪心中最经典的“按右端点排序”策略。n int(input()) intervals [] for _ in range(n): l, r map(int, input().split()) intervals.append((l, r)) # 按右端点升序排序 intervals.sort(keylambda x: (x[1], x[0])) count 1 # 至少可以选第一个区间 last_r intervals[0][1] for l, r in intervals[1:]: if l last_r: count 1 last_r r print(n - count)为什么按右端点排序因为右端点越小的区间结束得越早它给后面的区间留下的空间越大。这个贪心选择的正确性可以用交换论证法证明在最优解中如果第一个选择的区间不是右端点最小的那个把它替换成右端点更小的区间不会让结果变差。这个题在面试里也经常被问到不只是一个笔试考点。建议理解证明过程而不是背代码面试官追问的时候能讲清楚才是真的会了。3.3 第三题带冷却时间的任务调度优先队列第三题开始有点区分度了考的是带冷却时间的任务调度。题目大意是给出一个任务列表每个任务用一个大写字母表示类型。每个任务的执行时间为1个单位时间。相同类型的任务两次执行之间必须间隔至少n个单位时间冷却时间。问完成所有任务所需要的最短时间。核心思路是贪心加优先队列每次从剩余次数最多的任务里挑一个执行因为这样能最大化利用冷却时间。如果当前没有可执行的任务就让时间单位空转。import heapq from collections import Counter tasks input().strip() n int(input()) counter Counter(tasks) # 因为 Python 默认是小顶堆所以存剩余次数的相反数 heap [] for cnt in counter.values(): heapq.heappush(heap, -cnt) time 0 while heap: # 每一轮最多取 n1 个任务执行 temp [] for _ in range(n 1): if heap: cnt -heapq.heappop(heap) if cnt 1: temp.append(cnt - 1) else: break # 如果本轮不足 n1 个且堆已空说明任务执行完了不用补空转 if heap: time n 1 else: time (n 1) - len([x for x in temp if x 0]) for cnt in temp: heapq.heappush(heap, -cnt) print(time)这个写法有一个细节需要注意当堆已经空了说明任务全部执行完毕最后一轮不需要补满n1个时间单位的外壳。其实这个题有更简洁的数学解法。统计出现次数最多的任务次数max_count和有多少个任务达到这个次数num_max然后答案就是max(len(tasks), (max_count-1)*(n1)num_max)。但笔试里用优先队列模拟更稳不容易在边界条件上出错也更容易推演答案。我当时用的就是优先队列法因为数学公式虽然快但如果一下子没想清楚num_max怎么统计写出来的答案很容易差1。优先队列的模拟过程更机械写对了几乎不可能出错。3.4 第四题状态压缩下的最短路问题较难题第四题是压轴题难度明显上一个台阶。题目背景大概是有n个城市n ≤ 15城市之间由m条无向边连接每条边有一个通行时间。现在有一条旅行路线要求必须经过k个指定景点问从城市1出发到城市n结束且把k个指定景点全部经过一次可重复经过城市和边的最短时间是多少。这个题一看就知道不是简单的最短路因为“必须经过特定点”这个约束用普通的Dijkstra解决不了。正确的打开方式是Floyd预处理出所有城市两两之间的距离然后对“必须经过的点”做状态压缩动态规划。思路拆解如下先用Floyd算法求出任意两点之间的最短距离。因为n最多15Floyd的O(n^3)完全没有压力。设dp[mask][i]表示当前已经经过的城市集合为mask且最后停在第i个关键城市关键点是起点、终点和k个景点的最短时间。状态转移时枚举下一个要去的关键城市从cur走到nxtmask加上nxt对应的那一位。最终答案是所有覆盖了全部k个景点的mask中dp[mask][终点]的最小值。INF 10**18 n, m map(int, input().split()) dist [[INF] * (n 1) for _ in range(n 1)] for i in range(1, n 1): dist[i][i] 0 for _ in range(m): u, v, w map(int, input().split()) dist[u][v] min(dist[u][v], w) dist[v][u] min(dist[v][u], w) # Floyd 预处理任意两点最短路 for k in range(1, n 1): for i in range(1, n 1): for j in range(1, n 1): if dist[i][j] dist[i][k] dist[k][j]: dist[i][j] dist[i][k] dist[k][j] k int(input()) spots list(map(int, input().split())) # 必须经过的k个景点 # 把起点、所有景点、终点组成关键城市列表 points [1] spots [n] p_len len(points) # 预处理关键城市之间的最短距离 g [[INF] * p_len for _ in range(p_len)] for i in range(p_len): for j in range(p_len): if dist[points[i]][points[j]] INF: g[i][j] dist[points[i]][points[j]] # 起点是 points[0]终点是 points[-1] # 为了表示必须经过的k个景点状态mask需要包含spot对应的位 # 方便起见索引0是起点索引1..k是景点索引k1是终点 dp [[INF] * p_len for _ in range(1 (k 1))] # 初始状态从起点出发一个景点都没去过 dp[1][0] 0 for mask in range(1 (k 1)): for last in range(p_len): if dp[mask][last] INF: continue # 尝试去下一个景点 for nxt in range(1, k 1): # 只枚举景点 if mask nxt 1: continue new_mask mask | (1 nxt) dp[new_mask][nxt] min(dp[new_mask][nxt], dp[mask][last] g[last][nxt]) # 最后从任意一个景点走到终点 full_mask (1 (k 1)) - 1 # 起点位 k个景点位全部为1 ans INF for last in range(1, k 1): if dp[full_mask][last] INF: ans min(ans, dp[full_mask][last] g[last][k 1]) print(ans if ans INF else -1)这道题的难点在于状态定义。很多人第一反应是“直接在原图上做Dijkstra每次经过景点就标记一下”但最短路问题的子结构在没有状态约束时不成立一个“先绕路去景点A再去景点B”的路径未必包含“去景点A的最短路”所以必须把“当前访问过哪些景点”这个状态维度加进去。这就是状压DP最核心的思维方式。如果考试现场真的遇到这题我建议先想清楚dp数组的维度然后把Floyd预处理写出来这已经能拿到一部分分了。很多同学不是因为不会写最后的DP而是连Floyd预处理都不写就直接放弃那部分分就白白丢了。4. 行测与专业选择题低分陷阱与高效答题策略4.1 行测五个模块的性价比排序携程技术岗笔试的行测部分整体难度不算高但它的坑在于“浪费时间”。逻辑推理题里经常有一些题干很长的文字题如果你正常阅读并推导每一题可能要花两三分钟但它的分值跟10秒能做完的数字推理题完全一样。我的经验是先做图形推理和数字推理这两个部分不需要大段阅读刷过题库的人基本上一眼能出答案。然后做资料分析最后做逻辑判断和言语理解。言语理解里的病句辨析真的是磨人精选项里每个句子看起来都对细品全都别扭这种题最容易让人陷进去。以当时考到的几道题为例数字推理题1, 3, 7, 15, 31, ?答案63规律是前一项乘2再加1。这种题就是个熟练度问题看见数字敏感的人直接选。图形推理题给一组图形问下一张图是什么通常是旋转90度加对称。这种题注意不要死磕看10秒没思路就跳过。逻辑判断题给一段文字问最能削弱论点的是哪项。这个需要一定的做题技巧关键词是“削弱”“加强”“前提”看到这些词就知道是形式逻辑题抓住论点和论据的对应关系就能选。整个行测模块我建议最多分配10分钟超过10分钟还没做完剩下的题全部按第一感觉选。行测的分值撑死了也就15分你花20分钟做行测而挤掉了编程题的20分钟是笔非常不划算的买卖。4.2 专业选择题高频考点清单专业选择题大概20题覆盖的面比较广但考来考去都是那些高频基础点。结合我自己的备考经验和考后回忆列的清单如下数据结构二叉树前中后序遍历、栈与队列特性、哈希表冲突处理、排序算法时间/空间复杂度。计算机网络TCP三次挥手为什么是四次、HTTP状态码含义301/302/404/502、DNS解析过程、IP地址子网掩码计算。操作系统进程与线程区别、死锁产生的四个必要条件、页面置换算法LRU/FIFO、常见Linux命令。数据库事务ACID特性、索引失效场景、SQL查询优化、三大范式。Java基础HashMap底层原理数组链表/红黑树、ArrayList与LinkedList区别、JVM垃圾回收、final关键字的作用。这里我要特别提醒Java基础在选择题里占比不低。携程是典型的Java技术栈公司通用技术岗的笔试试卷里Java相关题目会明显比C多。如果你是Java选手考前把HashMap的put流程、ConcurrentHashMap的锁分段机制、JVM内存区域划分这些经典问题过一遍能稳稳拿下好几题。如果你主语言是C或Golang也建议临时抱佛脚地看一眼Java基础不亏。举一道当时印象深刻的题问HashMap在JDK 1.8中当链表长度达到多少时转为红黑树答案是8并且数组长度会先用MIN_TREEIFY_CAPACITY校验是否扩容。这种题就是纯记忆背下来就能拿分。4.3 不会做的题怎么蒙三选一排除法专业选择题里遇到不会的蒙也有蒙的门道。我的方法是先排除明显错误的选项。比如题目问“以下哪种排序算法时间复杂度为O(n log n)”如果选项里有冒泡排序、插入排序、选择排序这三个都是O(n^2)直接排除剩下的那个大概率是正确答案。如果四个选项分不清对错优先考虑“看起来最专业”的选项。这个有点玄学但牛客网的选择题选项往往喜欢把正确选项写得措辞更长、更复杂。这招不保证对但比瞎猜正确率高一些。另外选择题很多时候会出现“以下说法错误的是”这类反向提问。审题时一定要看清“正确”还是“错误”考场上因为看错方向而丢分的例子太多了而且是那种出了考场才反应过来的丢分特别让人懊悔。5. 从笔试复盘看备考优先级下一届同学可以直接照抄的复习路线5.1 考点出现频率统计考后我和几个同批的同学拼了一份考点回忆清单把编程题和选择题里涉及的考点按出现频次做了个简单的统计考点方向出现频率题型分布字符串处理与模拟高编程第1题、选择题贪心算法高编程第2题、部分选择题动态规划/状态压缩DP中高编程第4题图论最短路/最小生成树中编程第4题、选择题数据结构基础高选择题计算机网络中选择题操作系统中选择题Java基础高选择题从这里可以得出两个结论第一编程题考得并不偏全是LeetCode上常见题型和算法的变体没必要去刷偏难怪题。第二选择题的考点重心非常清晰数据结构基础加Java基础几乎占了选择题的一半。5.2 刷题量与刷题范围建议如果你距离笔试还有三到四周我建议把刷题目标定在LeetCode Hot 100里的字符串、贪心、动态规划、DFS/BFS、堆和优先队列类题目至少刷两遍。然后配合《剑指offer》的题目巩固基础。牛客网的企业真题可以放在考前一周用来熟悉题库系统和键盘输入的习惯。数字上说如果时间有限每天保证3到5道代码题的手感重点不是数量而是每道题都要想清楚“为什么用这个算法”以及“能不能用更优的解法”。面试时你拿着一道美团真题的AC代码远不如能把一道普通题目的两种解法讲清楚更有说服力。5.3 关于携程笔试的六个避坑经验最后分享六个我在实际笔试中踩过或者看别人踩过的坑希望下一届的同学直接避开第一题千万别大意。很多同学觉得第一题简单就匆匆提交结果没注意到字符串末尾的换行符测试用例能过但提交判0分。一定要用strip()清一下输入。代码编辑器里没有代码格式化快捷键代码一旦缩进乱了找bug的时间比写代码还长。平时写代码不要太依赖IDE的自动格式化。牛客网提交代码时如果报编译错误不要反复提交先复制报错信息在本地跑一遍。编译错误不耗提交次数但非常耗时间。选择题界面如果没有“标记”功能就在草稿纸上记下题号方便最后回头检查。行测和选择题可以返回修改但编程题的“最后一次提交”才会被记录。如果你先提交了一版代码后来改了一版但没提交成功成绩只认最后一次成功的提交。这个机制很坑一定要在最后两分钟点一次提交。心态上不要追求全AC。四道编程题能做出三道就属于中上水平最后一道题做不出很常见。我最后一题当时也只写了一半的状态转移但其他题稳住了一样拿到了面试资格。携程笔试的考察风格整体上非常务实不玩文字游戏更看重基础是否扎实、代码是否稳定。如果你已经刷了不少题但总是差一点突破希望这篇复盘能帮你把那些“软实力”的坑填上上岸就会顺利很多。