数仓开发落地手册
数仓面试前必看这5道题答不上来基本没戏写在前面最近辅导了好几个准备数仓面试的粉丝发现一个扎心的现象很多人简历上写着精通数仓建模真到面试时被追问两三个问题就露馅了。不是不够努力而是面试官问的那些高频难题恰恰是日常工作中容易一笔带过的细节。今天老张把近半年面试辅导中遇到的 5 道最高频、最容易翻车的数仓面试题整理出来每道题都给你拆解到底题目本身在考什么大多数人的回答差在哪面试官想听到的满分回答长什么样建议收藏面试前反复看。题目一缓慢变化维度SCD怎么处理这道题几乎逢面试必问但能答到位的人不超过三成。面试官的原题维度数据是会变化的比如客户的手机号换了、部门改名了。你们数仓里怎么处理这种缓慢变化维度分别说说 Type1、Type2、Type3 的区别和适用场景。大多数人的回答Type1 就是直接覆盖Type2 是加新行记录历史Type3 是加新列……然后没有然后了。问题出在哪只背了概念没说清楚Type2 具体怎么实现生效日期和失效日期怎么设标志字段叫什么没讲清楚什么业务场景该用哪种类型面试官觉得你知其然不知其所以然没提到拉链表这是 Type2 最常见的工程实现不说等于没答满分回答应该是这样的先给结论再展开SCD类型处理方式适用场景Type 1直接覆盖旧值不保留历史数据错误修正、不重要的属性变更Type 2新增一行记录新值用生效/失效日期标记时间段需要完整追溯历史的维度客户地址、产品分类等Type 3在原行新增列存旧值只需对比变更前 vs 变更后两种状态Type 6Type1Type2Type3 混合特殊业务需求实际中较少使用然后一定要补充工程实现细节我们在实际项目中Type2 是用拉链表来实现的。拉链表的核心思路每条记录有 start_date 和 end_date 两个字段当前有效记录的 end_date 设为 9999-12-31。维度发生变化时将旧记录的 end_date 更新为变更日期同时插入一条新记录start_date 设为变更日期end_date 设为 9999-12-31。查询某个时间点的维度状态时用 WHERE dt BETWEEN start_date AND end_date 过滤即可。这样回答面试官知道你不光懂概念还真正做过落地。题目二数仓分层中 DWD 和 DWS 哪层更难这是一道争议型题目面试官想看你对数仓分层的理解深度而不是让你站队。面试官的原题你们数仓是怎么分层的DWD 层和 DWS 层分别做什么你觉得哪层更难做为什么大多数人翻车在哪只说分层名称和职责不解释难在哪面试官已经知道 ODS/DWD/DWS/ADS 是什么了他想听你的思考一边倒说某层更难没看到另一层的难点显得思考片面没有结合自己的项目经验来谈干巴巴的教科书答案满分回答应该是这样的先简述分层再对比难点最后给出你的判断分层DWD明细层DWS汇总层核心职责数据清洗、标准化、明细事实表建模按主题轻度聚合产出宽表和汇总指标难点所在业务过程拆解是否准确粒度定义是否合理维度退化字段怎么冗余多源指标口径统一公共汇总粒度的抽象指标复用和扩展性易踩的坑粒度太细导致膨胀、维度冗余过多、清洗规则不统一口径不一致导致数据对不上、宽表越建越宽难以维护然后给出你的判断关键我认为 DWS 层更难。因为 DWD 层的难点主要在技术执行把脏数据洗干净、维度冗余合理就行方法论相对成熟。但 DWS 层的难点在业务理解你得搞清楚每个指标的统计口径不同业务部门对同一个指标的定义可能完全不同如何抽象出公共粒度、避免重复建设这些靠的不只是技术还有对业务的深度理解。DWD 是脏活累活DWS 是真正的脑力活。记住面试官不是在考你选哪个而是在考你能不能说出理由。有观点、有论据、有项目经验这才是加分项。题目三事实表的三种类型怎么区分维度建模的基础题但很多人在累积快照型事实表上翻了车。面试官的原题事实表有几种类型分别说说它们的区别和使用场景。你在项目中用的是哪种大多数人翻车在哪把三种类型的名字背出来了但说不出本质区别粒度不同不知道累积快照型事实表会更新以为事实表只能追加不能改举不出项目中的实际例子面试官觉得你没真正建过模满分回答应该是这样的核心记住一句话三种事实表的区别本质是粒度和生命周期不同。类型粒度生命周期典型场景事务型一条业务事件一行只追加不更新订单明细、支付流水、日志记录周期快照型每个周期每个维度组合一行每个周期新增一批不更新每日账户余额快照、每日库存快照累积快照型一个业务流程一行会更新随流程推进修改订单从下单到签收的全流程跟踪关键加分点一定要主动讲累积快照型事实表的更新逻辑累积快照型事实表是三种里面最特殊的。以订单流程为例一行记录的粒度是一个订单包含下单时间、支付时间、发货时间、签收时间等多个里程碑日期字段。订单刚创建时只有下单时间有值其他都是空。随着业务流程推进每次更新对应的时间字段。这一点非常关键很多面试者以为事实表只能 INSERT 不能 UPDATE但累积快照型恰恰是允许更新的。漏掉这个细节面试官就觉得你对维度建模的理解还停留在表面。题目四数据倾斜怎么排查和解决这道题考察的是实战能力面试官想听的是你的排查思路和解决方案不是背诵概念。面试官的原题你在做数仓任务的时候遇到过数据倾斜吗怎么发现的怎么解决的大多数人翻车在哪只会说加盐增加并行度这不叫排查思路这叫背答案说不出怎么发现倾斜面试官想知道你的监控手段没有举具体例子比如 null 值导致倾斜、大 key 导致倾斜满分回答应该是这样的分三步走怎么发现、怎么定位、怎么解决。第一步怎么发现倾斜任务运行时间突然变长之前跑20 分钟的任务突然跑 2 小时看Spark UI / YARN 日志发现某个 Task 处理的数据量远超其他 Task配置DQC 监控自动检测各 Task 数据分布是否均匀第二步怎么定位原因NULL 值倾斜某个字段大量为 NULLGROUP BY 时全分到一个 Task大Key 倾斜某个 key 的数据量特别大如热门商品 ID、大客户 ID数据类型不一致JOIN 时隐式转换导致无法正确 Hash 分发小表JOIN 大表未走 MapJoin导致全表 Shuffle第三步怎么解决针对不同原因解决方法也不同倾斜原因解决方案NULL 值倾斜给 NULL 加随机前缀打散或者先过滤 NULL 单独处理再 UNION大 Key 倾斜对大 Key 加盐打散加随机数后缀聚合后再二次聚合去盐数据类型不一致JOIN 前显式 CAST 统一类型小表 JOIN 大表开启 MapJoinHive: /* MAPJOIN(small_table) */小表加载到内存无法定位设置 skew join 开关让引擎自动处理倾斜 Key这样回答面试官能看出你不仅有理论知识还有真实的排查经验。题目五拉链表怎么设计怎么查询历史快照拉链表是数仓面试的必考题也是区分背过概念和真正做过的分水岭。面试官的原题你们项目中用拉链表吗说说拉链表的设计思路。如果要查某个用户在 2024 年 6 月 1 日的部门信息你怎么写 SQL大多数人翻车在哪只知道拉链表有开始时间和结束时间但说不清楚增量数据怎么合并到全量拉链表里写不出历史快照查询的SQL这是面试官最想验证的点没说清楚初始化和每日更新的流程满分回答应该是这样的拉链表的设计结构拉链表的每个字段字段名说明user_id用户ID主键之一user_name用户名dept_id部门IDdept_name部门名称start_date本条记录生效日期end_date本条记录失效日期当前有效记录设为 9999-12-31每日更新流程第一步从业务系统拉取当日增量数据新增 修改的记录第二步将全量拉链表中受影响记录的 end_date 更新为当日日期即关闭旧记录第三步将增量数据作为新记录插入start_date 设为当日end_date 设为 9999-12-31第四步未发生变化的记录保持不变历史快照查询 SQL查某个用户在 2024 年 6 月 1 日的部门信息SELECT user_id, user_name, dept_name FROM user_zipper WHERE user_id 123 AND start_date 2024-06-01 AND end_date 2024-06-01如果查全表在那个时间点的快照去掉 user_id 条件即可。这个 SQL 能当场写出来面试官基本就确认你真的用过拉链表了。写在最后以上 5 道题覆盖了数仓面试中最高频的考点维度建模SCD 事实表类型、分层设计、数据倾斜、拉链表。你会发现这些题的共同特点是概念不难背但面试官追问的是你怎么落地每道题都有一个关键细节答到了就是加分项没答到就是减分项光看文章不够你得结合自己的项目经验去内化如果你正在准备数仓面试但不知道简历该怎么包装项目经验写出来的简历石沉大海面试时总是紧张明明会的东西说不出来不确定自己的回答是否到位没人帮你模拟和复盘想系统提升数仓技术能力但不知道该往哪个方向努力这些老张都能帮你。服务项目详情简历修改逐句打磨项目描述突出技术亮点和业务价值让简历从能看变成想约面模拟面试还原真实面试场景高频题项目深挖连环追问面完给你逐题复盘面试辅导针对目标岗位定制备考方案薄弱环节专项突破拿到 offer 不是终点技术提升数仓建模、分层设计、性能优化等核心技术体系化提升不局限于面试