大厂数仓笔试真题回忆:这些题我面试时真的遇到了
最近星球里有好几个同学刚参加完大厂的数仓笔试,跟我分享了题目。我整理了一下,发现有些题目反复出现,几乎成了"固定题型"。
今天我把这些笔试真题回忆版放出来(已脱敏),每道题配上解题思路。不管你是不是最近要笔试,这些题都值得做一遍,因为它们考的是数仓开发的核心能力。
第一部分:SQL题(必考,占笔试60%左右)
第1题:用户行为路径分析
题目: 给出用户行为日志表 user_action(user_id, action_type, action_time),action_type包括:进入首页(P)、浏览商品(V)、加入购物车(C)、提交订单(O)、支付成功(W)。求满足路径 P→V→C→O→W 的用户数。
解题思路:
这道题考的是有序事件匹配。核心是用LEAD窗口函数把同一用户的行为按时间排列,然后判断路径。
WITHordered_actionsAS(SELECTuser_id,action_type,action_time,LEAD(action_type,1)OVER(PARTITIONBYuser_idORDERBYaction_time)asact2,LEAD(action_type,2)OVER(PARTITIONBYuser_idORDERBYaction_time)asact3,LEAD(action_type,3)OVER(PARTITIONBYuser_idORDERBYaction_time)asact4,LEAD(action_type,4)OVER(PARTITIONBYuser_idORDERBYaction_time)asact5FROMuser_action)SELECTCOUNT(DISTINCTuser_id)asuser_cntFROMordered_actionsWHEREaction_type='P'ANDact2='V'ANDact3='C'ANDact4='O'ANDact5='W';
注意点: 题目没说"连续"(中间不能有其他行为),如果要求严格连续,上面的写法就对了。如果不要求连续(只要求先后顺序),需要用子查询的方式判断时间先后。
第2题:重叠时间段合并
题目: 会议表 meeting(meeting_id, user_id, start_time, end_time),同一个用户的会议时间可能重叠,把重叠的会议合并成不重叠的时间段。
解题思路:
这是一道经典的区间合并题。思路是:按start_time排序后,如果下一个区间的start_time <= 上一个区间的end_time,就合并(取更大的end_time)。
WITHordered_meetingsAS(SELECTmeeting_id,user_id,start_time,end_time,ROW_NUMBER()OVER(PARTITIONBYuser_idORDERBYstart_time)asrnFROMmeeting),mergedAS(SELECTuser_id,start_time,MAX(end_time)OVER(PARTITIONBYuser_idORDERBYstart_time,rnROWSBETWEENUNBOUNDEDPRECEDINGANDUNBOUNDEDFOLLOWING)asmax_endFROMordered_meetings)SELECTDISTINCTuser_id,start_time,max_endasend_timeFROMmergedWHEREstart_time<=max_endORDERBYuser_id,start_time;
实际笔试中这题很难用纯SQL优雅实现,更常见的做法是写出思路和伪代码。重点是展示你理解区间合并的算法逻辑。
第3题:多行转多列(复杂行转列)
题目: 学生选课表 student_course(student_id, course_name, score),输出每个学生每门课的分数,且列名是课程名。但课程名不固定,可能新增课程。
解题思路:
固定列名的行转列用CASE WHEN就行(之前文章讲过)。不固定列名有两种处理方式:
- 动态SQL:先查出所有不重复的课程名,拼接成SQL字符串再执行
- 使用JSON格式输出:把多门课的成绩转成JSON数组,一条记录一个学生
笔试中通常考的是思路,写出伪代码或方案描述即可。
第4题:滑动窗口求均值
题目: 股票交易表 stock_trade(trade_date, price),求每只股票的7日滑动平均价。
解题思路:
标准窗口函数题:
SELECTtrade_date,price,AVG(price)OVER(ORDERBYtrade_dateROWSBETWEEN6PRECEDINGANDCURRENTROW)asma7FROMstock_trade;
变体问法: 如果不是连续交易日怎么办?跳过周末和节假日,只取最近7个交易日的均值。那就不能用ROWS了,要用RANGE,或者确保trade_date是连续的。
第二部分:数仓设计题(占笔试25%左右)
第5题:电商订单数仓设计
题目: 一个电商平台有用户表、商品表、订单表、订单明细表、支付表、物流表。请设计一套数仓分层方案,支持以下需求:1. 每日GMV统计2. 各品类销售排名3. 用户复购率分析4. 商品库存预警
解题思路:
ODS层: 原始数据直接落库,按天分区。
DWD层(明细层):- dwd_order_detail:订单明细事实表(order_id, user_id, sku_id, category_id, amount, pay_time, ...)- dwd_user_register:用户注册事实表- dwd_product_info:商品维度快照表
DWS层(汇总层):- dws_user_daily:用户日汇总表(user_id, order_cnt, order_amount, first_order_time, ...)- dws_category_daily:品类日汇总表(category_id, order_cnt, gmv, ...)- dws_product_daily:商品日汇总表
ADS层(应用层):- ads_daily_gmv:每日GMV报表- ads_category_rank:品类销售排名- ads_user_repurchase:用户复购率报表- ads_inventory_alert:库存预警表
关键点: 面试官不是看你画个图就完事了,他会追问:- 你的粒度怎么定的?(比如DWS层按用户+天粒度)- 你怎么处理退单?(退款后的GMV怎么算)- 你怎么保证数据一致性?(订单和支付数据的时间差怎么处理)
第6题:日志数据入仓方案
题目: 每天有来自多个业务系统的日志数据(JSON格式),格式不统一、字段有缺失、有时间戳偏差。请设计入仓方案。
解题思路:
这道题考的是ETL实战能力。
- 数据采集
- ODS层
- 清洗规则
- 时间戳统一:不同系统的时区/格式不同,统一转为标准格式
- 数据类型校验:金额字段必须是数字,日期字段必须是合法日期
- DWD层
- 数据质量监控:入库量对比(源端vs数仓)、空值率监控、业务规则校验
这道题说清楚"你遇到过什么脏数据、怎么处理的"就是高分答案。
第三部分:开放题(占笔试15%左右)
第7题:如何评估数据模型的合理性?
解题思路:
从几个维度回答:- 规范性:命名是否规范、分层是否清晰、粒度是否统一- 完整性:是否覆盖了所有核心业务过程和维度- 性能:查询效率是否满足业务需求,有没有冗余计算- 扩展性:新增业务场景时,是否容易扩展- 数据一致性:跨表/跨层的数据是否能对齐
笔试时间和分配建议
通常大厂数仓笔试时长是60-90分钟。建议时间分配:
写在最后
大厂笔试考的不是你会不会背答案,而是你的思路是否清晰。SQL题不会做的,写出伪代码也比空着强。数仓设计题不会画完整架构的,把核心思路写出来也能拿到部分分数。
我把星球里同学们分享的更多笔试真题(含字节跳动、阿里、美团、京东等)整理成了一个题库,持续更新中。想看的同学可以加入知识星球获取。
在评论区说说你遇到过最难的笔试题是什么?大家一起讨论。