三月份眼看春招就全面铺开了,后台不少准备投数据开发工程师岗位的同学来问我:携程集团的笔试到底怎么准备?第一批题量大不大?考的是纯SQL还是连Spark、Flink原理一起上?说实话,我过去几年参与过不少数据团队的招聘流程,也帮人模拟评过很多份笔试答卷,对这个岗位的考察套路算是比较熟悉。这篇文章就把2025年春招携程集团数据开发工程师第一批笔试的考察逻辑、高频考点、刷题思路一次讲透,另外附上完整的实战拆解和踩坑提醒。不管你是刚准备转行做数据开发,还是已经在实习、想冲一把大厂offer,这轮笔试的应对思路,都值得你静下心来跟着走一遍。
1. 先摸清岗位画像:携程数据开发笔试究竟在筛什么样的人
1.1 从业务形态反推考点
在准备任何一场笔试之前,我的习惯是先搞清楚这个岗位日常到底干什么,因为考点一定是从岗位日常反推出来的。携程的核心业务是旅游出行,包括机票、酒店、火车票、度假线路、商旅、景区门票等,这些业务背后每天产生极其海量的订单流、用户行为流、库存变动流。
数据开发工程师在携程这类公司里干的活,大致可以分为三块:一是建设数据仓库,把散落在各个业务库、日志系统里的数据做清洗、结构化、分层加工;二是搭建和维护离线与实时数据管道,保证从业务库到数仓、从数仓到报表应用的数据链路稳定高效;三是为业务方提供数据服务,包括报表、指标体系、用户画像标签、算法特征等。此外,跟算法团队配合做特征工程,跟数据分析师配合做数据质量治理,也都是日常工作的一部分。
由此可以看出,笔试的重点领域是很明确的:SQL能力是绝对的基础门槛,数据仓库建模和分层设计是专业分水岭,大数据组件原理(Hive、Spark、Flink、Kafka)是区分"只会写SQL"和"真懂数据开发"的关键,再加上一两道算法题检验编程基本功。这四块基本构成了试卷的主体。
1.2 第一批笔试的整体结构与时间压力
根据近几年头部互联网公司数据开发岗位笔试的通用形态,携程的数据开发笔试通常是线上限时完成,总时长大约在90到120分钟。题型一般可以分为三个平行的部分:
| 题型 | 大致题量 | 考察重点 | 建议时间分配 |
|---|---|---|---|
| 单选题/多选题 | 15-25道 | 数据仓库概念、Hadoop生态、Hive/Spark/Flink原理、基础Java/Python | 30-35分钟 |
| SQL编程题 | 3-5道 | 窗口函数、多表关联、去重、累加、连续问题、TopN | 40-50分钟 |
| 算法编程题 | 1-2道 | 数组、字符串、哈希、贪心、DFS/BFS等 | 20-30分钟 |
这里必须提醒一句:客观题里经常混入"选非题",就是选不正确的那一项,这个非常阴险。很多人看到熟悉的知识点就手快选了正确答案,结果题目问的是"以下哪项是错误的"。第一轮笔试刷人最多的往往不是不会做的题,而是会做的题看错了问法。后面我会在每个章节里点出具体的高危陷阱。
另外,线上笔试的考试系统一般会切换页面检测,甚至有的会要求开启摄像头,所以考前要找一个安静的环境,把通讯软件全部关掉,保持网络稳定。这些细枝末节虽然不算智力考察,但每年都有人因为这些低级问题翻车。
2. SQL是生死线:窗口函数与业务场景的组合拳
2.1 为什么说SQL直接决定你能不能进下一轮
我做过一个统计,在数据开发岗位的笔试中,SQL题的分值占比通常在三成到四成之间,但它的区分度远比分值占比更高。因为客观题大家靠背八股文都能蒙对不少,算法题很多人直接放弃,唯独SQL是"会就会、不会就是写不出来"的硬功夫。阅卷时,哪怕你的SQL只是思路对但语法有瑕疵,往往也能得到部分分数,而如果思路完全偏掉,这一题基本就是零分。
携程这种业务场景,SQL题一定会结合旅游业务出,常见的有:统计每个城市的订单总量和环比增长率、找出连续N天有登录行为的用户、计算用户累计消费金额、查询每个酒店类目下销量排名前几的商品、分析机票订单和退改签记录之间的关联等。这些题表面看是业务分析题,本质考的都是窗口函数。
2.2 三个必须拿下的核心题型
第一类:累计类问题。比如计算每个用户从注册至今的累计下单金额,这是在携程这种交易型平台里最常见的数据需求。解法很简单,就是开窗累加:
SELECT user_id, order_date, order_amount, SUM(order_amount) OVER (PARTITION BY user_id ORDER BY order_date) AS cumulative_amount FROM user_orders ORDER BY user_id, order_date;这一题想拿满分,有一个容易被忽略的细节:窗口函数里的ORDER BY order_date需要跟ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW配合,虽然在默认情况下SUM() OVER的窗口帧就是到当前行为止,但有些线上判题系统对SQL方言的支持并不一致,写上完整窗口帧规范反而更严谨。另外,如果题目要求按"自然月"累计,那就需要在PARTITION BY里加上月份字段,改成分区键为user_id, month。
第二类:连续N天问题。这是互联网公司笔试里的常青树,结合旅游业务就变成了"找出连续3天浏览过携程酒店频道的用户"。核心套路是用日期减去行号,把连续日期归到同一个组:
WITH tmp AS ( SELECT user_id, visit_date, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY visit_date) AS rn FROM hotel_channel_visits WHERE visit_date IS NOT NULL AND user_id IS NOT NULL ) SELECT user_id, MIN(visit_date) AS start_date, MAX(visit_date) AS end_date, COUNT(*) AS continuous_days FROM ( SELECT user_id, visit_date, DATE_SUB(visit_date, rn) AS grp_date FROM tmp ) t GROUP BY user_id, grp_date HAVING COUNT(*) >= 3;这个思路第一次接触的人会觉得绕,但想通了之后就很简单:同一组连续日期,每天减去它对应的行号,得到的日期是同一个,于是按这个差值分组就能切出连续段。需要注意两个细节:一是如果有重复日期要先进行DISTINCT去重,否则行号会错位,导致本来连续的日期被拆成两组;二是DATE_SUB在Hive、MySQL、PostgreSQL里的写法不完全一样,考试前最好确认系统指定的SQL环境。
第三类:分组TopN问题。比如"找出每个出发城市销量最高的3条机票线路"。这类问题用RANK()、DENSE_RANK()、ROW_NUMBER()都能解,关键在于搞清楚三者的区别,因为判题系统往往对排序的并列情况有明确要求:
SELECT departure_city, route_id, sales_amount FROM ( SELECT departure_city, route_id, sales_amount, RANK() OVER (PARTITION BY departure_city ORDER BY sales_amount DESC) AS rk FROM flight_route_sales ) t WHERE rk <= 3;如果题目要求"取前3条且并列只算一个名次",用RANK();如果要求"按行数取前3行、不管并列",用ROW_NUMBER();如果要求"并列算同一名次但后续名次连续递增",用DENSE_RANK()。我见过太多人在这个细节上丢分,明明SQL逻辑全对,就栽在三个函数的语义差异上。
2.3 SQL题里那些"送命题"
笔试里还有一种常见考法,是给你一段有问题的SQL,让你找出报错原因或优化方向。这类题常见陷阱包括:GROUP BY后面选了没分组的列、WHERE里使用了聚合函数、ON和WHERE的过滤顺序搞混导致关联结果不同、NULL值参与比较恒为UNKNOWN等。
这里特别提醒一个关于NULL的坑:统计订单金额平均值时,AVG会忽略NULL行,但如果你把NULL转成0再取平均,结果会完全不同。题目如果问"过滤掉未支付订单后计算退款率",你要先想清楚未支付订单和已支付但未退款订单分别在什么表里、NULL表示什么含义。这种业务语义的判断题,比你多会几个函数重要得多。
3. 数仓理论与建模:看似送分实则拉分的客观题板块
3.1 维度建模的核心概念必须形成答题框架
客观题里数据仓库部分的占比通常很大,而且这些题的知识点非常密集。从往年真题规律来看,维度建模是最核心的出题区域,主要包括:事实表和维度表的区别、星形模型和雪花模型的区别、缓慢变化维的几种处理策略、退化维度、代理键、事实表的粒度等。
我建议你搭建一个清晰的答题框架,而不是零散背知识点。比如拿到"事实表"相关题目,先想到它的核心特征:记录业务过程、每行表示一个度量事件、行数是天文数字、以可累加的数值度量为主;而维度表则是"描述业务过程的上下文",包含文本属性,行数相对少。星形模型用一句话概括就是"中心一张事实表,周围一圈维度表",雪花模型则是把维度表进一步规范化拆成多层。
关于缓慢变化维(SCD)也是高频考点:第一种策略是直接覆盖旧值,不保留历史;第二种策略是新增一行,用开始日期和结束日期标记有效期,可以保留完整历史;第三种策略是新增一列存储历史值,只能保留上一次变化。笔试里最常见的问法是"要统计某个酒店在过去三个月内价格调整的次数"该用哪种SCD策略,答案很明显是第二种。
3.2 数仓分层:ODS、DWD、DWS、ADS的边界要拎清
携程这种规模的公司,数仓一定是分层的,笔试也一定会考分层的意义和各层职责。标准分层通常包括:原始数据层(ODS)、明细数据层(DWD)、汇总数据层(DWS)和应用数据层(ADS)。
这里有一个我在评卷时经常见到的误区:很多人分不清DWD和DWS的边界,以为DWD就是"清洗后的数据",DWS就是"宽表"。更准确的说法是,DWD以业务过程为粒度,保留最细的明细,做一致性清洗和标准化,比如把不同业务库里的日期格式统一、枚举值统一;DWS则面向分析主题做轻度汇总,比如按用户、按商品维度聚合出日成交额,或者把多个维度的指标拼接到同一张宽表里。ADS则是直接服务于报表和大屏应用,通常按具体业务需求定制。
客观题常见的出法有:给你一个加工场景,问"这个清洗逻辑应该落在哪一层";或者给你一张表的字段列表,判断它是事实表还是维度表。答这类题的关键是抓住"粒度"两个字:一张表的粒度是什么,决定了它属于哪一层。能对应到一行记录的原子业务事件,就是DWD;如果一行记录代表多个事件的汇总,就往DWS靠。
3.3 数据倾斜与一致性:工程实践题的理论底子
数据开发笔试中还经常出现关于数据倾斜、数据质量、调度依赖的题目。数据倾斜几乎是排查类题目的头号考点,出题方式通常是"一个SQL跑了很久,如何定位原因并优化"。你要能说出常见的倾斜原因:一是JOIN时关联键有大量空值或热点值,二是GROUP BY的键分布严重不均匀,三是COUNT(DISTINCT)在某些引擎上的性能问题。
对应的优化思路要能条理化答出:先看执行计划确认倾斜发生在哪个阶段,然后针对热点键做加盐随机拆分,或者把大表拆成多个小任务并行处理;空值键可以单独过滤后用随机值替换再关联;COUNT(DISTINCT)可以改成先GROUP BY去重再COUNT,或者用近似去重函数。这些不光是笔试答案,实际工作中也是万能排查三板斧。
4. 大数据组件原理:Hive、Spark、Flink的知识密度
4.1 Hive专题:内外表、分区、文件格式一个不落
Hive是数据开发工程师的日常工具,笔试客观题几乎是必考的。常考的点集中在:内部表和外部表的区别、分区表和分桶表的适用场景、常用文件格式的优缺点、Hive SQL转换为MapReduce的执行流程。
内部表和外部表的区别,最简洁的表述是:内部表由Hive管理数据生命周期,删表即删数据;外部表仅管理元数据,删除表不会删除HDFS上的底层文件。实际生产中,数据湖或ODS层的原始数据一般使用外部表,避免误删,而在数仓内部加工产生的中间结果用内部表,失真的可能性低。
分区表这个点,笔试喜欢问"一张按日期分区的订单表,查询时为什么必须带上分区条件"。答案很好理解:Hive本质上从HDFS读文件,没有分区裁剪就得全表扫描,文件量级是PB还是MB的差别。与之相关的是动态分区的概念,插入数据时不手动指定分区值,而是由SQL自动根据最后一列的值生成分区目录。但用动态分区要注意小文件问题,如果分区数极多而且每个分区数据量很小,会产生大量小文件,后续读取时的NameNode压力和任务调度开销会非常高。
4.2 Spark专题:RDD的血缘、宽窄依赖、Lazy机制
客观题里Spark的考察比Hive更有深度,而且出题方式往往不是直接问"RDD是什么",而是给一段场景判断行为。高频知识点包括:RDD的惰性求值与血统机制、转换算子和行动算子的区别、窄依赖与宽依赖、DataFrame和RDD的优劣势、发生Shuffle的场景。
先说惰性求值。很多人在刚接触Spark时都困惑过:为什么map和filter调用后日志里没有显示任务执行,直到执行count或saveAsTextFile才有动静。因为转换算子只是生成新的RDD,记录依赖关系,真正触发计算的是行动算子。这个机制带来的好处是Spark可以做流水线优化,把多个转换算子合并到同一个阶段,也方便在真正计算前做逻辑优化。
宽依赖和窄依赖的区分也是高频题。窄依赖:每个父RDD分区最多被子RDD的一个分区使用,例如map、filter、union;宽依赖:多个子分区需要同一个父分区,典型操作是groupByKey、reduceByKey、join,这会引入Shuffle。笔试里如果问"某某算子是否会发生Shuffle",你要牢记:任何打乱数据重新分区的操作,都会带来网络传输,数据量大时这是性能瓶颈的核心来源。
4.3 Flink专题:事件时间、Watermark、Checkpoint必考
近几年实时数仓越来越重要,携程这类公司在交易风控、实时营销场景对Flink的要求很高,所以笔试里Flink的出现频率也在上升。最常考的三块:时间语义与Watermark、窗口类型(滚动、滑动、会话)、状态管理与Checkpoint的精确一次语义。
先说时间语义。处理时间(Processing Time)是数据到达机器的时间,事件时间(Event Time)是事件实际发生的时间,对于订单这种天然存在网络延迟的数据,必须用事件时间才能做准确的窗口统计。Watermark是一个处理乱序数据的机制,本质是"迟到数据的容忍水位线",表示"早于这个时间的数据可以认为已经全部到达,可以触发窗口计算了"。笔试里经常给出一串带延迟的数据流,问你Watermark设为多少才能保证95%的数据被正确统计,这需要理解Watermark的计算公式和乱序程度的关系。
再说精确一次消费。这是Flink+Kafka组合的经典考点:Flink的Checkpoint机制会周期性地保存每个算子的状态和Kafka消费位点,当任务失败重启时,从最近一次成功的Checkpoint恢复状态和位点,配合Kafka的幂等生产者与事务性写入,可以实现端到端的精确一次语义。面试官和笔试都爱从一个细节切入:Checkpoint的间隔设置太长会导致恢复时重复计算的数据量过大,太短又会增加存储和IO开销,如何权衡。所以这个点不是背概念,而是要理解背后的成本逻辑。
5. 编程题与算法题:限时场景下的保分策略
5.1 高频题型与现场思路推导
数据开发岗的算法题整体难度略低于后端开发岗,但也不能掉以轻心,通常是LeetCode的简单到中等难度。结合近几年各大公司数据岗笔试的出题偏好,最高频的是数组类、字符串类、哈希表和简单动态规划。
以一道典型的出题方式为例:"给定一个整数数组,找出数组中两个数之和等于目标值的下标组合"。很多人第一反应是双重循环,但你要知道笔试系统可能对数据规模有要求,双重循环在数组长度超过1万时就会超时。正确的姿势是用哈希表存"目标值与当前值的差",一次遍历即可得到结果,时间复杂度从O(n^2)降到O(n)。
笔试题的判分通常按测试用例通过比例来计算,这意味着你要主动考虑边界条件:数组元素有负数、目标值是0、存在多组解时输出哪一组、空数组和单个元素数组的行为。把这些边界条件都处理掉的代码,即使不是最优解,也能拿到比"裸暴力但对边界不加处理"的代码更高的分数。
5.2 时间不够时的答题顺序与本地调试技巧
我见过不少笔试翻车案例,共同原因都是"死磕一道题导致后面全崩"。合理的答题顺序建议是:先快速把客观题做一遍,不会的标记跳过,不要反复纠结;然后做SQL题,因为SQL题思路相对固定,得分性价比最高;最后留30分钟左右做算法题。
算法题如果卡住了,有一个自救思路:先写出严格按题意模拟的暴力解法,保证核心功能正确,再去考虑优化。测试用例通常有一组是小规模的,暴力解法能通过这部分用例,得分就不至于归零。另外,很多在线笔试环境支持本地编译器测试,建议在自己的IDE里先把样例跑通再粘贴进考试系统。千万注意不要直接依赖在线编辑器,代码提示和缩进检查都不如本地IDE好用。
还有一个小细节:如果题目没有明确指定语言,优先选择你最有把握手写出来的语言。这里说的"有把握"不只是会写语法,而是你熟悉标准库里的常用数据结构和API。平时刷题用什么语言顺手,笔试就用什么语言,不要临时切换。
6. 那些容易被人忽视的隐性考察点
6.1 数据敏感性与业务理解
很多人在准备笔试时只盯着技术知识,忽略了携程这类业务驱动型公司对数据敏感性的考察。笔试中有些题目看起来是一道普通的SQL题,但隐藏了业务理解的考察点。比如统计"酒店订单的取消率"时,分母是全部订单还是仅包含已支付的订单?分子是取消的订单数还是最终未入住的订单数?日期口径是按下单日期还是按入住日期?
我在实际评卷时经常看到答卷里出现答案完全不同的两种情况,但这两种答案单独看都"逻辑自洽"。这说明很多候选人缺少一个关键习惯:在下笔之前先定义清楚指标的统计口径。口径没有定清楚,不管代码写得多漂亮,最终算出来的指标在业务上都是不可信的。
所以答题的时候,哪怕题目没有明确要求,最好也在SQL注释里或解题思路里写明你的口径假设,这个动作能让阅卷人一眼看出你懂业务,而不是一个只会套模板的工具人。
6.2 会SQL不等于会数据开发
最后一个想认真强调的点:笔试通过只是入场券,真正的分水岭在后面。数据开发工程师说到底做的是"让数据可信、可用、高效流动"的工作。如果你只是刷熟了窗口函数、背熟了Spark源码层面的概念,但说不清楚一个数仓任务从上游业务库变更到下游报表展示之间经历了哪些环节,也不理解某个指标为什么连续两天波动,那即使笔试通过,后续面试也会被深挖到底。
建议在等待笔试结果的同时,自己动手做一个端到端的小项目,比如搭建一个简化版的订单数仓:用模拟数据生成订单表,用Spark或Flink做清洗和加工,落到Hive或Doris里,再用SQL完成一个复购分析报表。这个过程中你会遇到真实的数据倾斜、重复数据、时区问题、空值过滤问题,这些才是笔试题目背后真正想筛选的实战意识。
我在实际带人的经验里发现一个规律:那些笔试SQL写得非常标准的人,往往在团队里也能最快定位线上数据问题的原因,因为SQL的严谨程度就是一个人逻辑思维的投影。相反,SQL写得松松垮垮、时对时错的人,在后续做数据治理时通常也会埋下一堆坑。
笔试只是一个开始,2025年的春招竞争整体依然激烈,但数据开发这个岗位的门槛是"练出来的"而不是"背出来的"。每天抽一到两个小时集中刷SQL窗口函数和数仓建模题,坚持三周,你的手感会完全不一样。祝你这轮笔试能顺利过关,我们面试阶段见。