ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

携程春招技术笔试全复盘:算法考点与备考攻略

携程春招技术笔试全复盘:算法考点与备考攻略 先交代一下背景2023年3月中下旬我参加了携程春招技术通用岗的第一批笔试。整场做下来最大的感受是——它不像某些大厂笔试那样全靠难题“劝退”也不像另一些公司那样题量少到像走过场而是非常典型的一套“基础扎实 算法过硬”的组合拳。如果你正打算投携程或者同类在线旅游平台的技术岗这篇文章我把整场笔试的题型分布、编程题复盘、高频考点、备考节奏和考场踩坑全部整理出来希望能帮你少走弯路。这里先说明一下不同批次、不同岗位的题目会有差异但考察思路和侧重点通常很一致尤其“技术通用岗”这个标签下算法题是绝对的重头戏。下面我按实际笔试的模块顺序来拆。1. 笔试基本信息与题型构成先把规则看明白再动手1.1 整场笔试的时间、题量与分值分布携程春招笔试通常安排在官方通知的时间段内一般给足两个小时。我当时那场是90分钟题型分为两个大模块第一部分是技术选择题第二部分是编程题。不同年份可能略有浮动但总体框架是稳定的。我遇到的情况是这样的选择题一共20道左右涵盖数据结构、计算机网络、操作系统、数据库、Java/Golang基础等编程题3道难度梯度很明显——简单题、中等题、偏难题各一道。分值上编程题占比更高这也意味着算法题做不出来选择题全对也很难翻盘。从题量上看90分钟做20道选择题加3道编程题时间并不宽裕。选择题平均每题只有1分多钟的思考时间编程题则需要留出至少50到60分钟。这里要特别提醒一句先把3道编程题快速扫一遍评估难度分布再决定做题顺序。很多人习惯按顺序做结果卡在简单题上反复调试反而没时间写后面的中等题这是最亏的。1.2 为什么是“选择题 编程题”的组合很多同学会问笔试为什么不用纯算法题还要加一堆选择题其实从招聘方的角度很好理解选择题用来快速筛选计算机基础知识的广度编程题用来考察代码能力和算法思维的深度。两者合在一起能在较短的时间内评估一个候选人“能不能干活”和“有没有潜力”。携程作为在线旅游平台业务场景涉及订单系统、搜索推荐、支付交易、行程规划等对候选人的基本功要求很高。所以选择题部分基本围绕大厂通用考点出题并没有太多“偏门”知识。只要把计算机网络、操作系统、数据库、数据结构这几门核心课认真过一遍选择题拿个七八成正确率是不难的。还有一点要注意笔试链接通常会在开考前30分钟发到邮箱或手机短信并附有“正式笔试”和“模拟笔试”两个入口。强烈建议提前做一遍模拟笔试至少把摄像头、麦克风、浏览器权限这些环境问题提前搞定否则正式开考后光折腾环境就会浪费十几分钟。2. 编程题逐一复盘三道题考察的是同一种底层能力编程题是整个笔试的胜负手。我把自己那场遇到的三道题整理如下。题目细节凭记忆还原描述可能不完全一致但核心考点和解题思路是准确的。2.1 第一题字符串处理与统计类题目简单题题目大意给定一个字符串统计其中出现次数最多的字符如果存在多个字符出现次数相同则按ASCII码升序输出第一个字符并输出其出现次数。这类题目属于“送分题”的范畴核心考察点有三个字符串遍历与字符计数哈希表HashMap或数组的使用对题目约束条件的仔细阅读我当时直接用一个长度为128的int数组来统计字符出现频率——因为题目说明字符串中只包含ASCII可见字符用数组比HashMap更快也更简洁。public static void main(String[] args) { Scanner sc new Scanner(System.in); String s sc.nextLine(); int[] count new int[128]; for (char c : s.toCharArray()) { count[c]; } int maxCount 0; char result 0; for (int i 0; i 128; i) { if (count[i] maxCount) { maxCount count[i]; result (char) i; } } System.out.println(result); System.out.println(maxCount); }需要注意两个细节。第一循环顺序必须从0到127这样才能在出现次数相同时保留ASCII码更小的字符。如果用“大于等于”来更新反而会被覆盖成更大ASCII码的字符导致答案错误。第二输入字符串可能包含换行符所以读取时最好用nextLine而不是next否则遇到空格会截断。这个细节看起来不起眼但很容易在自测用例中翻车。这类题目没有算法难度考察的就是“能不能快速、准确地写出细节完整的代码”。我见过不少同学一看到简单题就放松警惕结果因为边界条件没考虑全而被扣分实在可惜。2.2 第二题动态规划类题目中等题题目大意给定一个数组每个元素代表一天的价格变动情况要求计算最多进行两次交易买入和卖出各算一次时能获得的最大利润。必须先买入后卖出第二次买入前必须卖出第一次持有的股票。这就是经典的“最多两笔交易”股票问题属于动态规划中“状态机DP”的典型代表。核心思路是把每一天的状态抽象成五种未进行过任何操作进行过一次买入进行过一次买入和一次卖出进行过第二次买入完成两笔交易这里可以压缩成四个变量来滚动更新分别表示上述后四种状态下的最大利润public int maxProfit(int[] prices) { int buy1 Integer.MIN_VALUE, sell1 0; int buy2 Integer.MIN_VALUE, sell2 0; for (int price : prices) { buy1 Math.max(buy1, -price); sell1 Math.max(sell1, buy1 price); buy2 Math.max(buy2, sell1 - price); sell2 Math.max(sell2, buy2 price); } return sell2; }这个解法的复杂度是O(n)空间复杂度O(1)是面试和笔试中标准的优化答案。我当时做题的过程中也想过用分治把数组从中间切开分别求左半段一次交易的最大利润和右半段一次交易的最大利润然后相加取最大值。这个思路能过一部分测试用例但无法覆盖“两笔交易都在同一侧”的场景所以不是正解。这道题给我们的启示是DP题不要一开始就想着优化空间先把状态定义写清楚转移方程推导正确再考虑能不能滚动数组。在笔试环境中写一个二维DP数组版本也是完全能AC的只要逻辑正确、不超内存限制即可。为了追求花式优化反而写出bug得不偿失。2.3 第三题图论与拓扑排序偏难题题目大意给定n门课程以及若干先修关系如学习课程B之前必须先学习课程A要求输出一种可行的学习顺序如果存在环导致无法学完输出空数组。课程表问题LeetCode上代号207和210的原题。第三题考了一个最标准的图算法——拓扑排序考察点包括图的构建邻接表入度数组的维护队列实现BFS环检测我写的是BFS版本的拓扑排序public int[] findOrder(int numCourses, int[][] prerequisites) { ListListInteger graph new ArrayList(); int[] indegree new int[numCourses]; for (int i 0; i numCourses; i) { graph.add(new ArrayList()); } for (int[] edge : prerequisites) { graph.get(edge[1]).add(edge[0]); indegree[edge[0]]; } QueueInteger queue new LinkedList(); for (int i 0; i numCourses; i) { if (indegree[i] 0) { queue.offer(i); } } ListInteger order new ArrayList(); while (!queue.isEmpty()) { int cur queue.poll(); order.add(cur); for (int next : graph.get(cur)) { indegree[next]--; if (indegree[next] 0) { queue.offer(next); } } } return order.size() numCourses ? order.stream().mapToInt(i - i).toArray() : new int[0]; }说实话第三题放到春招笔试里难度是中等偏上的。因为拓扑排序这个知识点在学校的算法课上不一定讲得很深如果平时刷题没有专门复习“图”这一大类考场上是很难在15分钟内写出来的。我当时能顺利通过主要靠的是提前把LeetCode的图论专题刷过一遍。这道题给我们的启示是笔试的难题并不在于模型有多复杂而在于你能否快速识别出“这是拓扑排序”。题目只要出现“依赖关系”“先后顺序”“能否学完”等关键词第一反应就应该是建图、算入度、做队列BFS。3. 选择题考点雷达这些基础知识几乎每场都会出现编程题之外选择题占了笔试的半壁江山。我复盘了一下20道选择题覆盖的知识点非常集中基本可以归类为五个方向。下面用表格整理出来方便大家对照复习。知识板块高频考点常考形式数据结构栈与队列特性、二叉树遍历、哈希冲突处理、堆的调整给出一段代码或序列选择输出结果计算机网络TCP三次握手、TCP与UDP对比、HTTP状态码、DNS解析流程概念辨析、特性判断操作系统进程与线程区别、死锁产生的四个必要条件、页面置换算法概念理解、条件判断数据库索引数据结构与失效场景、事务ACID、隔离级别、MVCC场景判断、SQL结果分析编程语言基础Java集合类特性、HashMap底层原理、JVM内存区域、GC算法源码阅读、运行结果判断3.1 数据结构选择题的送分题主力数据结构题往往是选择题中最容易拿分的。栈的后进先出、队列的先进先出、二叉树的前中后序遍历顺序、哈希表冲突后的链地址法和开放地址法这些都是“背了就有分”的知识点。但要注意的是携程这类公司出题常常会把数据结构与具体算法场景结合。比如给出一个数组模拟栈的过程问你最终栈内元素的顺序或者给出一棵平衡二叉树问你插入一个节点后如何旋转调整。这类题目光背概念不够必须动手画一画理解树旋转的整个过程。我当时就遇到一道关于HashMap的题问JDK1.8中HashMap在链表长度超过多少时会转为红黑树答案是8以及为什么转换阈值是8。这个题考察的其实是对“泊松分布”的掌握但也间接要求你对HashMap源码有过真实阅读而不是只背面试题答案。3.2 计算机网络TCP是永远的主角计算机网络选择题中TCP相关的题目占比接近一半。三次握手的状态迁移、四次挥手后TIME_WAIT的作用、TCP与UDP的区别、流量控制和拥塞控制的差异都值得重点复习。我印象比较深的一道题是在TCP连接建立过程中客户端收到服务器发送的SYNACK包后会进入什么状态答案是SYN_SENT到ESTABLISHED的转换。这道题考得非常细如果只看书不复盘状态机很容易把SYN_RCVD和ESTABLISHED搞混。另一个常考的坑是HTTP状态码。301永久重定向、302临时重定向、403禁止访问、404资源不存在、503服务不可用这些要能快速区分。稍微进阶一点的是DNS解析的完整流程——从浏览器缓存到系统缓存到本地DNS服务器再到根域名服务器。携程的面试官特别喜欢在后续的面试环节追问DNS劫持和CDN加速的关系所以笔试阶段遇到DNS题目别只背答案把整个过程串起来理解会更有帮助。3.3 操作系统死锁、进程调度三板斧操作系统选择题集中在三个话题进程与线程的区别、死锁的四个必要条件、常见页面置换算法。死锁的四个必要条件——互斥、持有并等待、不可剥夺、循环等待——几乎是每年必考。题目常常换着花样问你“破坏哪个条件可以避免死锁”。比如说资源一次性分配就是破坏了“持有并等待”而允许抢占则破坏了“不可剥夺”。要把每个条件对应的典型解决手段背熟。进程和线程的区别也是高频题尤其关注“同一个进程中的多个线程共享哪些资源”。地址空间、全局变量、文件描述符是共享的但寄存器和栈是独立的。这道题很多同学在做题时会踩坑把栈误认为共享资源。页面置换算法里LRU最近最久未使用和OPT最优置换是比较的对象。常考的形式是给出一段页面访问序列让你手动计算出缺页次数。这类题没有捷径多练几道就熟了。3.4 数据库索引与事务最核心数据库选择题基本围绕索引和事务展开。索引部分一定会考最左前缀原则和索引失效的场景事务部分一定会考ACID和四种隔离级别以及每种隔离级别分别解决了什么问题。我遇到的一道题是在可重复读隔离级别下事务A读取了一行数据事务B对这行数据进行了修改并提交事务A再次读取这条数据会看到什么答案是看到旧值因为在可重复读隔离级别下快照读具有一致性视图。这个知识点其实已经涉及MVCC多版本并发控制了需要理解undo log版本链和ReadView的生成机制。对于Java后端方向的同学来说数据库题目不排除还会出现一些SQL编写比如多表连接查询、聚合函数分组查询等。但形式通常是以选择题给出多个SQL语句让你判断哪个能正确得到结果不会要求手写大段SQL。3.5 Java/Golang基础语言特性考察贴合真实业务携程的主要后端语言是Java但技术通用岗也会考察一些Golang的知识点。我当时遇到的选择题里Java相关占了大头HashMap的底层结构、ConcurrentHashMap在1.8中如何保证线程安全CAS synchronized、JVM堆内存的划分、GC Root包含哪些对象。Golang相关的题相对基础比如goroutine和线程的区别、channel的收发特性、defer的执行顺序。如果你是Java方向提前花一晚上看一下Golang的基础语法和并发模型应付选择题足够了。这块复习的关键是“重源码、轻八股”。不要只背结论比如“ConcurrentHashMap是线程安全的”而要能说出它为什么线程安全——JDK1.8里放入元素时对桶的头节点加synchronized锁结合CAS操作实现高效并发。这种层面的理解遇到偏门的变形题也不慌。4. 技术题里藏着的“业务影子”携程为什么这样出题如果只是把上面的考点列出来你可能会觉得“这和普通大厂笔试没什么区别”。但复盘之后我发现携程的笔试题目背后其实藏着一条完整的业务逻辑线。4.1 订单系统与并发编程的关系携程作为在线旅游平台核心链路是“搜索→选择→预订→支付→出票”。这个过程中用户的每一次点击都可能触发对库存系统的并发读写。所以笔试中对并发编程、HashMap并发场景、事务隔离级别的考察本质上都在为一个目标服务你能不能写出在高并发环境下依然正确的代码。比如ConcurrentHashMap的考点对应的就是订单系统中库存扣减的高并发场景。而事务隔离级别的考点对应的则是“多个用户同时预定同一个航班最后一个座位”时如何保证不超卖。理解了这层关系你复习时会更有方向感——不是孤立地背知识点而是带着问题去理解技术选型。4.2 动态规划与搜索推荐的关系很多人想不到动态规划在旅游平台也有广泛的应用场景。搜索推荐系统中最短路径计算、行程规划中的行程合并与价格最优化本质上都是DP问题。题目中关于“最多两次交易”的设定也可以理解成一种简化版的资源分配模型。面试官其实并不指望一个春招候选人能设计出完整的分销系统但通过算法题他们能看出你的逻辑推理能力和对状态转移的敏感度。这种能力训练过和没训练过差异非常明显。4.3 图论与行程规划的天然联系拓扑排序那道题放在旅游平台的语境下就更清晰了。一个用户的行程可能包含机票、酒店、景点门票、当地交通等多个资源这些资源之间有先后依赖关系比如先入住酒店才能预约接送机。课程表的先修关系模型和行程资源依赖模型是同构的。所以如果你在复习图论时能多想想“这个算法能解决什么现实问题”不仅笔试时理解题目更快在后续面试中聊项目时也会让面试官觉得你有业务sense。4.4 计算机网络与高可用架构的映射TCP的连接管理映射到携程的网关层和负载均衡层就是如何在海量连接下保持服务的稳定。HTTP状态码的掌握对于排查线上接口问题至关重要。我后来在工作中的第一个线上Bug排查就是从一条504网关超时日志开始的。这些知识在学校里学的时候可能觉得抽象但在真实的业务系统里它们每天都在发挥作用。这也是为什么类似携程这样的公司笔试一定会覆盖计算机网络——这不是为了为难你而是因为生产环境真的需要这些基本功。5. 备考节奏与刷题路线我的实操安排聊完题目本身再聊聊更重要的如果时间可以重来我会怎么准备这场笔试。下面这套节奏是我自己实践下来觉得比较稳妥的供大家参考。5.1 三个阶段的时间线安排阶段时间范围核心任务每日投入基础夯实笔试前3个月刷完LeetCode热题100的“热门前50题”2至3小时专题强化笔试前1个月按专题刷题DP、图论、字符串3小时冲刺模拟笔试前1周做2至3套完整笔试模拟题3至4小时第一个阶段不要急于求成。按“数组→链表→栈和队列→哈希表→二叉树→排序→二分→双指针→动态规划→图论”的顺序刷题。每天争取做两道新题和一道旧题。旧题回顾非常重要我见过太多人刷题如流水过一个月回头看之前写的代码已经没印象了这就等于白刷。第二个阶段是提分的关键。这时候要进行专项训练比如连续三天只做动态规划把“背包问题”“线性DP”“状态机DP”这几个子类型吃透再用两天时间攻克图论重点练习拓扑排序和并查集。专题训练的意义在于让大脑形成“题型联想”——看到题目特征就能马上往对应的算法框架上靠这种条件反射式的反应速度在笔试中特别值钱。第三个阶段做整套模拟题。不一定要找携程的真题真题很难拿到用牛客网或者其他平台上的大厂笔试套题即可。关键是模拟真实考试环境限时、开摄像头、不允许中途查资料。模拟时的心态越接近真实考试真正上场时就越从容。5.2 刷题优先级的取舍策略笔试备考时间通常有限不可能把LeetCode两千多道题全刷完。我的建议是按下面的优先级来LeetCode热题100全部刷完这是性价比最高的一批题。剑指Offer的经典题尤其是数据结构和“双指针”大类。高频题单比如CodeTop上按公司分类的题库。遇到不会的题不要死磕超过30分钟直接看题解但要在看完后自己重新写一遍。这个优先级的逻辑是笔试高频考点高度集中在“双指针、哈希、二叉树、动态规划、图论、字符串”这几个大类。像什么位运算、计算几何、线段树之类的小众题型笔试遇到概率极低时间不够可以战略放弃。5.3 复习资料的选择与避坑复习资料我用过不少这里说几个真实体验。《代码随想录》的刷题顺序和总结很适合笔试备考尤其二叉树和回溯算法的章节讲得清晰。LeetCode的“精选Top Interview Questions”值得反复做。牛客网的历年真题库对模拟笔试环境帮助很大。关于系统设计题笔试阶段不用投入精力那是面试环节才需要准备的。避坑提示不要一上来就钻研“最优解”。笔试评分是按测试用例通过的多少来给的能AC比什么都重要。哪怕你的解法不是最优只要复杂度在可接受范围内、能通过全部测试用例分数一样拿满。很多大厂笔试中暴力解法也能拿到50%左右的分值所以别轻易跳过任何一个题目。5.4 模拟笔试环境的重要性最后这一条容易被忽略。正式笔试是在线上平台进行的代码编辑器通常不支持自动补全也没有本地IDE那么智能的错误提示。如果你平时都用IDE刷题建议提前一到两周切换到在线编辑器模式适应“裸写代码”的感觉。我在正式笔试前一周每天在一家在线刷题平台上固定做两道题完全用平台自带的编辑器。第一次切换时确实不习惯但等到第三四天就明显顺手了。考场上也因此节省了不少时间。6. 考场上容易踩的坑输入输出、时间分配与心态6.1 ACM模式下的输入输出陷阱携程笔试的编程题采用的是ACM模式即需要自己写完整的输入输出逻辑而不是像LeetCode那样只填充核心函数。这一点非常容易踩坑。举个例子如果题目输入格式是“第一行一个整数n第二行n个整数”你需要用Scanner逐行读取。很多同学习惯一次性读取一行用空格分割但如果数字之间既有空格又有换行就容易出错。遇到这种情况最稳妥的做法是用一个循环持续读取直到读够n个整数为止。Scanner sc new Scanner(System.in); int n sc.nextInt(); int[] nums new int[n]; for (int i 0; i n; i) { nums[i] sc.nextInt(); }不要在同一行输入和换行输入之间做假设用Scanner的nextInt连续读取是最安全的方式。另外笔试平台上通常可以选择编程语言。如果你对某个不太常用的语言不熟悉千万别在考场上尝试“秀操作”换冷门语言。选自己最有把握的语言能写出AC代码才是王道。6.2 编程题的时间分配策略我给自己定的时间分配是选择题控制在25到30分钟内完成编程题预留60到65分钟。三道编程题的用时比例约为10分钟、25分钟、25分钟。实践中这个比例可能需要微调但核心原则不变简单题必须在8分钟内AC如果超过15分钟还没过立刻转场做中等题。很多人的失败不是题不会做而是把时间砸在了一道题上导致后面简单题没时间写。如果一道题完全没有思路至少要把输入读取部分写完把可能的暴力解法框架打上去。哪怕只能通过30%的测试用例也比你交白卷强。我见过有些同学心态崩了直接交卷这种放弃是最可惜的——笔试看的是绝对得分率多过一题就可能把你从落选名单里拉回来。6.3 选择题的做题策略与草稿纸用法选择题有一个容易被忽略的技巧不会的题先标记不要卡住。20道选择题里通常有5到6道是存在迷惑性的如果在一道题上纠结超过2分钟后面编程题的时间就会被压缩。考试时准备好一张干净的草稿纸和两支笔。遇到二叉树遍历、哈希冲突、页面置换这类需要推导的题直接画图或列步骤。草稿过程本身就是一种校验能有效避免“凭空想当然”的粗心错误。我复盘自己那场笔试时发现选择题有几道其实不难但因为在草稿上写得不清晰推导过程中抄错了一个数导致答案选错。所以草稿纸的排版也要工整每一题标注题号对完答案后检查也方便。6.4 摄像监控与考试环境的那些细节春招笔试通常要求开启摄像头部分还会进行分屏监控。开考前15分钟一定要把房间灯光调亮桌面收拾干净确保摄像头范围内没有与考试无关的电子设备或纸张。网络方面最好用有线网络连接电脑或者确保Wi-Fi信号稳定。之前有朋友在笔试过程中中途断网刷新重新进入后却被告知需要重新作答耽误了将近10分钟才恢复心态直接崩了一半。所以有条件的话先跑到一个网络稳定的地方再开考。手机热点也可以作为备用方案但要注意接电话会断网。浏览器方面建议提前用Chrome或Edge安装好平台要求的插件关闭所有广告拦截插件。部分笔试平台会检测浏览器环境环境异常会被视为作弊风险。这些细节看着不起眼实际考场上任何一个出问题都会打乱节奏。最后再说几句笔试前几天不少同学容易陷入“临时抱佛脚”的焦虑状态疯狂刷难题。我的个人经验是最后的几天与其刷新题不如把错题本和之前的代码翻出来看一遍。笔试考场上真正能救你的往往不是临考前突击来的新知识而是你已经反复练习到形成肌肉记忆的东西。另外笔试结束后一般几天内会收到面试通知。这段时间不要干等第一时间把笔试中不会的题复盘一遍——因为你很可能在面试中被问到“笔试那道题是怎么想的”。如果笔试时用了暴力解法面试官很可能会追问“还能怎么优化”。提前想好优化思路不仅是对笔试的交代也是给面试加分的机会。最后再分享一个小建议投携程春招时可以同时关注它的暑期实习岗位。两者针对的时间点不同但笔试题目风格往往接近等于多了一次练手和兜底的机会。祝看到这里的各位都能顺利通过笔试拿到心仪的面试邀请。
返回列表