数仓面试题汇总:分层建模与SQL调优核心考点解析

发布时间:2026/9/19 18:04:44
数仓面试题汇总:分层建模与SQL调优核心考点解析 简介这是一份聚焦实时数仓方向的2021年面试题汇总适合正在准备数据仓库、大数据开发岗位面试的候选人。随着实时数仓在电商、金融等领域广泛落地这些高频考点已成为筛选大数据工程师的重要参考。内容覆盖数仓理论与建模星型/雪花模型、分层结构、MapReduce执行流程与HDFS写入、Hive数据倾斜与小文件治理、SQL子句执行顺序及grouping sets/cube/rollup用法并涉及Kafka offset管理与exactly once等高频考点同时附有数据异常排查、数据质量保证、调度交接等开放题思路。包内含单个PDF文档共1个文件大小仅89KB体量精简、便于快速浏览。目前已有623人学习下载。PDF中不仅罗列问题还对星型/雪花模型优缺点、HDFS写入确认机制、Hive文件格式选择、数据倾斜解决方案等做了展开说明适合在面试前集中梳理实时数仓核心知识点。1. 数仓面试题汇总背后真正决定面试结果的是知识骨架“2021数仓面试题汇总.pdf”这个标题在资料清单里只是一个小文件但真正值得琢磨的是它的内容结构。大部分人的复习方式是打开 PDF 从第一道题刷到最后一道题背下几十个答案就觉得准备完了。结果面试时面试官在“你们数仓分几层”之后加一句“为什么 DWD 要落 Hive 而不直接留在 Kafka”就立刻卡住。原因很直接面试题 PDF 给的是问题和答案但不给上下文。数仓面试要考察的是分层、建模、技术选型、SQL 调优、实时数仓等几块能力的交叉理解。本文按我自己的复习路径展开把这份汇总当成考点检索表先建理论骨架再补齐技术栈细节最后用反复追问的方式把书面答案转成口头表达。这个方法适合准备数据仓库开发、大数据开发岗位的人也适合带新人时做能力盘点。2. 数仓分层及各层作用先讲清 ODS/DWD/DWS/ADS 的关系2.1 把四层架构讲成一套决策链而不是背英文缩写数仓分层是数仓面试题里的第一个高频关卡。很多人能背出每个层的英文全称但被问到“你这层的表是从哪来的”“为什么 ODS 不建索引”“DWS 为什么不做明细”就露怯。我一般会用一条决策链来记两个核心目标一是避免重复计算二是方便权限和成本治理。ODS 只承担接入DWD 做清洗和标准化DWS 做主题汇总ADS 做应用支撑。每一层的产出都回答一个问题数据到了这一步要服务谁。进一步讲数仓分层及各层作用在面试里不是背诵题而是判断题。例如 ODS 层遇到上游变更要不要保留两份历史如果上游只是数值修改ODS 一般选择保留快照如果上游做了字段变更ODS 会多存一个 schema 版本。面试官问 ODS 层有没有清洗如果你回答“没清洗”需要立刻补充“只是做格式校验和压缩真正的脏数据在 DWD 处理”否则他会继续追问数据的责任边界。2.2 用一张表理清四层职责以及面试官的追问方向分层核心职责典型表面试追问ODS数据原样接入ods_order_info全量还是增量delete 怎么处理DWD清洗、脱敏、维度退化dwd_order_detail比 ODS 数据量变大还是变小DWS按主题轻度汇总dws_user_order_day粒度怎么定义ADS按应用冗余宽表ads_order_rank指标口径怎么统一这张表别只用于看要能口头填出来。建议准备一个自己的项目场景例如订单主题ODS 表的同步频率是每 5 分钟一次DWD 层做数据质量检测和维度退化DWS 层按用户、商品、店铺三个维度做每日汇总ADS 层直接给前端报表出 TopN。讲解时把“为什么这么做”说出来比只报层名有价值。2.3 数仓建模维度建模和三范式建模的取舍数仓建模的题目和分层强相关。面试官最常见的问法是“星型模型和雪花模型区别”“为什么数仓不用三范式”。回答时可以先把定义说清楚维度建模以业务过程为中心事实表搭配一组维度表维度表允许冗余查询时依靠关联输出宽表三范式以消除冗余为目标适合 OLTP不适合大规模分析查询。说完定义后要落到场景报表查询需要减少表关联所以星型模型更常见。2.3.1 一张 DWD 事实表的建表示例-- DWD 层订单事实表设计示例按天分区 CREATE TABLE dwd_order_fact ( order_id STRING COMMENT 订单ID, user_sk BIGINT COMMENT 用户维度代理键, shop_sk BIGINT COMMENT 店铺维度代理键, order_amount DECIMAL(12,2) COMMENT 订单金额统一口径为实付金额, order_status STRING COMMENT 订单状态, dt STRING COMMENT 分区日期 ) PARTITIONED BY (dt) STORED AS ORC TBLPROPERTIES (orc.compressZLIB);这段代码的重点不在语法而在字段设计。user_sk和shop_sk是维度代理键不是原始用户 ID。代理键的用途是让维度表的变化不影响事实表历史order_amount的注释要写明口径否则 DWS 和 ADS 层算出来的指标对不上。建表后可以自问如果上游订单金额字段改名这张表要不要重建答案是不需要只要 ETL 里做字段映射即可这就是分层带来的好处。面试中追问建模还可能涉及总线矩阵和一致性维度。回答时用这句话收尾“先有总线矩阵再做一致性维度最后落到事实表和维度表。” 如果面试官继续追问就举例订单和用户是两个业务过程公共维度是时间、地域这两组维度在 DWD 层使用同一张维表避免 DWS 层出现总量不一致。3. 技术栈面试题Hadoop、Spark、Kafka 的作答路径3.1 HDFS 小文件问题的定位与解决方案数仓岗位面试中谈到 Hadoop很少只问“MapReduce 原理”更多会从实际数据链路切入。最典型的是 HDFS 小文件问题因为生产环境每天都会遇到。为什么小文件会在数仓建设中造成麻烦从两个角度回答NameNode 内存方面每个文件不管多小都要占据一条元数据记录计算调度方面一个文件对应至少一个 InputSplit小文件越多Map 任务数量越大。不要只答“合并小文件”要说明为什么 HDFS 默认块大小是 128MB以及合并操作在哪个阶段做。常见的解决路径有三类第一在写入端控制文件大小例如 Spark 写入前用coalesce调整分区数第二在调度端做攒批把 5 分钟一次的同步改成小时级第三在底层定期用INSERT OVERWRITE重写小分区同时关注hive.merge.mapfiles和hive.merge.size.per.task等参数。面试官一般会补问一句“你生产环境用过哪个” 这时不需要讲得很复杂只需要说出一次真实问题即可。例如我处理过 ODS 层一张埋点表单日分区有 3000 多个小文件查询时启动 3000 个 Map 任务调度耗时比计算耗时还长改成按小时分区重写后文件数量降到 300查询耗时回到正常范围。3.2 Spark 数据倾斜从定位到两阶段聚合Spark 数仓面试题中出现频率最高的是“数据倾斜”。答题时不要直接说“加盐”而要把排查过程说出来。第一步看 Spark UI如果某个 stage 的 task 运行时间明显高于平均水平而且大量 task 处理的数据量很小就说明 key 分桶不均。第二步找出倾斜 key常见方法是读上游数据分布而不是在面试时拍脑袋。第三步才是选择解决策略小表 join 大表用广播大表 join 大表考虑加盐后两阶段聚合倾斜 key 单独分桶。from pyspark.sql import functions as F # 对热 key 加盐普通 key 保持原样 df df.withColumn( join_key, F.when(F.col(city_id) hot_city, F.concat(F.lit(F.rand()), F.lit(_), F.col(city_id))) .otherwise(F.col(city_id)) ) # 第一阶段聚合 stage1 df.groupBy(join_key).agg(F.sum(amount).alias(amount)) # 去掉盐前缀第二阶段聚合 result stage1.withColumn( city_id, F.regexp_replace(join_key, r^\d\.\d_, ) ).groupBy(city_id).agg(F.sum(amount).alias(amount))注意这里有两个雷区一是对count distinct不能随便加盐因为随机前缀会让 distinct 被分到不同分组最终结果偏大二是加盐后的第二阶段聚合要用sum对中间结果求和不能再用count。另外如果倾斜 key 比较少更简单的做法是单独过滤出来用普通聚合再和主体结果 union避免随机数导致的数据扩散。这些细节比“加盐”这个名词本身更值钱。3.3 Kafka 可靠性实时数仓面试的必答组合Kafka 在数仓岗位的面试题中通常和实时数仓绑定出现。比如“实时计算时如何保证不丢不重”这是一道需要分层回答的题。丢数据可能发生在 Producer、Broker、Consumer 三个环节重复数据可能发生在发送重试或下游重放时。因此回答要从下往上分成三部分第一Producer 设置acksall和retries降低写入失败导致的丢消息第二Broker 侧设置replication.factor与min.insync.replicas保证同步副本数量第三Consumer 侧关闭自动提交在业务处理成功后才手动提交位移。环节避免丢数据避免重复数据Produceracksallretries 重试开启幂等 ProducerBroker多副本min.insync.replicas无直接作用Consumer手动提交 offset业务侧做幂等例如主键去重或去重表面试官接下来常会追问“Spark Structured Streaming 的 exactly-once 能不能保证端到端”。答案要谨慎中间结果输出可以做到精确一次但端到端还依赖下游存储是否支持事务。Hive 表不支持精确一次写入Doris 或 ClickHouse 的部分表模型可以做到幂等。这样回答说明你把 Kafka 和应用存储边界分清楚而不是堆概念。4. 数仓面试题里的 SQL 与指标口径连登、拉链表和口径统一4.1 连续登录天数一类窗口函数的通用写法数仓 SQL 面试题并不追求复杂算法而看重窗口函数。连续登录天数就是一道高频题常见解法是“登录日期减行号”。如果日期连续减出来的分组日期不变如果断档分组日期会跳变。只要按用户和分组日期聚合就能算出连续区间长度。补充一点登录表若存在一天多次登录要先去重否则行号会多算。-- 连续登录天数示例兼容 Hive/Spark SQL WITH login_dedup AS ( SELECT user_id, login_date FROM user_login WHERE dt BETWEEN 2025-01-01 AND 2025-01-31 GROUP BY user_id, login_date ), grp AS ( SELECT user_id, login_date, date_sub(login_date, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date)) AS grp_date FROM login_dedup ) SELECT user_id, COUNT(*) AS continuous_days FROM grp GROUP BY user_id, grp_date HAVING COUNT(*) 3;这段 SQL 有三个细节值得记一是GROUP BY user_id, login_date完成去重二是ROW_NUMBER的窗口范围是用户内按日期排序三是date_sub要和分区字段区分清楚不要写成dt和login_date混用。实际面试时如果要求返回“最长连续登录天数”就在外层再加一个MAX(continuous_days)这种变形能体现对结果结构的掌控。4.2 拉链表从字段设计到合并更新拉链表是考查数仓建模中“时间维度”处理能力的典型题目。题目通常这样描述用户表每天都会全量同步但大部分用户不会每天变化希望只保留一份全量数据又能回溯历史。最直接的回答是在表中增加start_date和end_date两个字段当前有效记录用一个大日期表示。面试官接着会追问“新数据来了怎么合并”合并逻辑可以概括为把旧有效记录拆成不变和要被替换两批不变的原样保留被替换的关闭再将增量数据作为新记录插入。-- 拉链表合并示意关闭被替换的旧记录并加入新记录 INSERT OVERWRITE TABLE dim_user_zip SELECT user_id, user_name, start_date, end_date FROM dim_user_zip WHERE end_date 9999-12-31 AND NOT EXISTS ( SELECT 1 FROM user_delta d WHERE d.user_id dim_user_zip.user_id ) UNION ALL SELECT user_id, user_name, start_date, 2025-01-14 AS end_date FROM dim_user_zip WHERE end_date 9999-12-31 AND EXISTS ( SELECT 1 FROM user_delta d WHERE d.user_id dim_user_zip.user_id ) UNION ALL SELECT user_id, user_name, 2025-01-15 AS start_date, 9999-12-31 AS end_date FROM user_delta;这种写法直接读拉链表旧数据将旧的有效记录与新增量数据做存在性判断。需要注意Hive 的INSERT OVERWRITE TABLE会覆盖整张表如果表很大生产上通常按分区或使用更高效的合并工具。拉链表的面试考点不在“会不会写 SQL”而在“何时选用拉链表、何时用全量快照”。如果一张表需要频繁查询当前全量状态同时又要知道历史状态拉链表比全量快照省磁盘如果业务上更需要“某一天所有数据”快照表更直接。能说出这个取舍就是不错的回答。4.3 指标一致性数仓面试里容易被低估的软实力SQL 题之后面试官往往会问“你们订单金额怎么定义”。这不是故意抬杠而是用指标口径来考察数据规范能力。常见误区是把“订单金额”解释成“下单金额”实际上业务部门里订单金额可能是订单原价、优惠后金额、实付金额三者差异巨大。更专业的回答是拆成“原子指标 修饰词 时间周期”。例如“近 30 天北京地区用户订单实付总金额”原子指标是“实付总金额”修饰词有“北京地区”时间周期是“近 30 天”。在 ADS 层建表时就要把这种口径写到元数据里。面试中提到这个话题时还可以补充“指标口径为什么经常不一致”。常见原因有数据源不同业务库和埋点库的订单状态更新时机不同时间字段不同下单时间和支付时间都可能被拿来算金额维度表不统一用户归属地区在多个维表里不一致。这些问题不是 SQL 能解决的而要靠数仓分层过程中的标准定义。你在回答时强调“我们在 DWD 层统一用支付成功时间在 DWS 层统一用用户维度代理键”就把问题拉回到了工程规范层面。5. 把“2021数仓面试题汇总.pdf”用出最大价值追问式复习法5.1 第一遍先用“讲题”代替“读题”拿到这份 PDF不要一开始就按顺序背答案。建议先随机抽出 20 道题每道题给自己 1 分钟不看答案口头讲一遍。讲的时候能覆盖多少细节都不重要重要的是暴露出哪些地方讲不下去。对每一道讲不完整的题在旁边标记两个标签一类是“概念不清晰”一类是“没有项目案例”。两类复习方式完全不同前者回去看书后者去翻自己过去写的 ETL 或 SQL补一个具体例子。5.2 输出一份自己的考点标签地图从 PDF 中整理出四类标签数仓分层、数仓建模、计算引擎、数据质量。每一类先列高频题再写自己的答案模板。下面是我常用的模板结构考点标签高频问题回答模板关键词数仓分层ODS/DWD/DWS/ADS 作用职责 选型原因 项目例子数仓建模星型和雪花区别定义 场景 反例计算引擎Spark 数据倾斜怎么办定位 原因 方案 踩坑数据质量指标不一致定义口径 分层保障第二步是为每个回答模板填充两个追问。例如“数据倾斜怎么办”的追问可以写“加盐后怎么处理 count distinct”然后把答案直接写在标签地图里。地图做好后后续复习不再需要翻完整份 PDF只看这些标签和追问即可速度会快很多。5.3 模拟面试时故意留一个“薄弱点”最后两天做模拟面试不要把所有问题都答得滴水不漏。建议选一两个真实存在缺陷的模块比如“我对 ClickHouse 的副本机制不太熟”然后观察自己能否在被追问时用已知概念推导。面试官通常不会因为一个弱点直接否定候选人反而会引导你表达思路。一遍模拟下来把没接住的问题及时补充进标签地图。这份 PDF 的核心价值不在于让你背熟原题而在于帮你把知识骨架铺开铺得足够宽才能在每次追问中落到自己的项目经历上。本文还有配套的精品资源点击获取