尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

数仓面试题核心考点:分层建模与离线技术栈全解析

数仓面试题核心考点:分层建模与离线技术栈全解析 简介这是一份面向大数据与数仓岗位求职者的实时数仓面试题汇总内容精炼覆盖面试高频考点适合面试前突击复习也可作为系统梳理数仓知识体系的参考。全包仅含1个PDF文件大小约89KB轻量便携可随时在手机或电脑上阅读。正文按问答形式展开涵盖数仓理论、MapReduce、Hive、SQL、Kafka等核心模块既辨析星型模型与雪花模型的优缺点、说明数仓分层结构也详解MapReduce全流程、FileInputFormat切分算法、HDFS写入流程针对Hive常见难题给出了数据倾斜和小文件问题的处理方案并梳理了HQL转MapReduce的执行思路。SQL部分介绍了grouping sets、cube、rollup的聚合差异以及Kafka中offset管理与exactly once实现方式开放题部分还整理了数据异常排查、数据质量保障、调度任务交接等实战经验。目前已有623人学习对快速补齐实时数仓高频面试考点很有帮助。1. 2021数仓面试题汇总把考点藏在哪分层、建模与离线技术栈考数据仓库岗位面试官手里那套题翻来覆去就那么几板斧。2021数仓面试题汇总.pdf 看似只是当年面经的堆叠实际暴露了三个固定考点带第一是数仓分层问“你们 ODS 到 ADS 怎么分、数据流向是什么”第二是数仓建模问事实表和维度表的区别、缓慢变化维度怎么处理第三是离线技术栈Hive、Spark、Kafka 随机挑一个问原理。这三个考点覆盖了初级和中级数仓开发 80% 以上的面试时长。这篇文章按这条主线拆解每一块都给出可复用的答题结构和被追问时的应变办法用一份 2021 年的 PDF讲透 2026 年还能用的答题思路。2. 数仓分层及各层作用从 ODS 到 ADS 的职责边界与高频追问2.1 数仓分层的经典四层结构每一层只做一件事数仓分层的核心目的不是把表堆得好看而是要管理数据加工过程中的血缘和复用。最经典的数仓分层是 ODS、DWD、DWS、ADS 四层少数公司会拆出 DIM 层或把 DWD 细分成明细层与轻度汇总层。2021数仓面试题里“数仓分层及各层作用”基本是必考题直接背概念得分不高要把每层之间的责任边界说清楚。层级核心职责表命名习惯数据粒度ODS原样接入业务库、日志、消息队列的数据不丢字段ods_表名_inc / _full与源系统一致DWD清洗、去重、统一格式生成明细事实表dwd_主题_明细_inc最细粒度业务事件DWS按维度做轻度汇总面向复用dws_维度_主题_di用户/商品等业务对象粒度ADS面向应用或报表的个性化加工ads_应用名_指标_di指标口径可定制注意考试时不必死背每一层英文全称但必须能讲清“上一层的输出是什么、下一层拿到后做了什么”。面试官最喜欢按这条线追问“ODS 和业务库到底有什么区别”答案要落在“ODS 只保留原始事实不做业务过滤”上。2.1.1 以用户订单为例看数据怎么一层层流动假设业务端有订单明细表 order_detail从 ODS 到 DWD 的加工路径是这样的-- ODS 层原样接入只做基础校验不要做业务过滤 CREATE TABLE IF NOT EXISTS ods.ods_order_detail_inc ( order_id STRING, user_id STRING, sku_id STRING, sku_num BIGINT, create_time STRING ) PARTITIONED BY (dt STRING) STORED AS ORC; -- DWD 层清洗空时间戳、转类型生成最细粒度的事实明细 INSERT OVERWRITE TABLE dwd.dwd_order_detail_inc PARTITION (dt${bizdate}) SELECT order_id, user_id, sku_id, sku_num, CAST(create_time AS TIMESTAMP) AS create_time FROM ods.ods_order_detail_inc WHERE dt ${bizdate} AND create_time IS NOT NULL AND sku_num 0;ODS 层只做两件事按天分区存储、基础类型透传不处理业务语义上的脏数据。DWD 层才承担清洗任务把空时间戳过滤掉、负数数量排除、字符串时间转成时间戳。这种分工是“分层边界”题的标准答法。新人容易犯的错是让 ODS 直接过滤一旦上游口径变化需要重放历史数据ODS 里已经没有原始字段可用血缘断掉后就只能返工。2.2 数仓分层对应的 SQL 面试题重算与回刷怎么设计分层结构搭好后面试题会落到实际操作上最常见的是“某一天的数据算错了怎么回刷”。这道题考的是对分层的依赖方向理解ODS 重拉、DWD 重算、DWS 逐级刷新不能跨层直接改数。-- 重刷 DWS 之前先把依赖的 DWD 分区重建 INSERT OVERWRITE TABLE dws.dws_order_1d_di PARTITION (dt${bizdate}) SELECT user_id, COUNT(DISTINCT order_id) AS order_cnt, SUM(sku_num) AS goods_cnt, SUM(sku_num * sku_price) AS gross_amount FROM dwd.dwd_order_detail_inc WHERE dt ${bizdate} GROUP BY user_id;这里的参数说明PARTITION (dt${bizdate}) 里的 bizdate 是调度系统传入的业务日期重刷时必须保证 ODS 对应分区数据已经就绪。如果只刷 DWS 而不看 DWD 是否更新就会出现“上层指标已经变了明细还是旧数据”的口径不一致问题。面试回答时补一句“重刷按依赖顺序即 ODS → DWD → DWS → ADS 逐层执行”基本就能完整覆盖考点了。3. 数仓建模面试题怎么答维度建模、事实表与缓慢变化维度3.1 先分清“维度”和“事实”这张表到底该放哪边数仓建模面试题没有标准答案面试官更在意你是否理解某种建模选择的代价。“这个字段要不要拆进维度表”这类题目最佳回答不是直接给答案而是先讲三件事事实表的粒度、维度表的属性、查询时由谁驱动。下面这一组对比可以直接当作答题锚点维度事实表维度表内容业务事件、度量值描述性属性数据量巨大随时间膨胀相对稳定缓慢增长主键复合键多个外键组合单一代理键更新方式增量追加为主低频更新典型例子订单明细、支付流水用户资料、商品分类答题时把“数据量”和“主键”当成入口事实表不能用业务主键做主键因为同一订单会被拆成多行维度表则恰恰相反需要唯一键来支撑关联。3.1.1 用一条 SQL 验证事实表粒度复合主键是否唯一在建模面试的实操环节常被要求“设计一张事实表并说明粒度”。粒度指一行记录代表的含义订单明细表每行代表“一个订单的一个商品”而不是“一个订单”。如果粒度不确认后面所有聚合都会出错。下面这条 SQL 用来验证复合主键是否真正唯一-- 验证事实表粒度若出现重复则说明主键组合不唯一 SELECT order_id, sku_id, COUNT(*) AS cnt FROM dwd.dwd_order_detail_inc WHERE dt ${bizdate} GROUP BY order_id, sku_id HAVING COUNT(*) 1;查询返回记录说明这张表的最小粒度不是 order_id sku_id可能存在同一用户同一天对同一商品多次下单但缺少渠道或订单行号维度。面试作答时忌讳只说“保证主键唯一”要主动讲“先确定业务过程的事实粒度再去找能唯一标识一行的维度列组合”。能说出这一层就已经区别于只会背定义的候选人。3.2 缓慢变化维度的处理策略用户改手机号到底该不该覆盖线上用户表经常出现电话号码、所在城市变化数仓建模里处理这类属性变化就是“缓慢变化维度”考题。SCD1 直接覆盖原值、SCD2 保留完整历史、SCD3 保留当前值和原值三者的适用边界要分清策略做法适用场景主要代价SCD1直接覆盖原值属性价值低、不需要回溯历史彻底丢失SCD2新增一行记录生效与失效时间需要准确历史统计、拉链表表膨胀、查询变复杂SCD3新增一列存原值只需最近一个历史值只能回溯一层用一个用户修改城市为例如果业务要统计“用户所在地与下单地的匹配关系”必须用 SCD2因为 SCD1 覆盖后无法重算历史区间如果只是展示当前城市SCD1 就够用。老手一般会被追问“SCD2 拉链表怎么更新”答题时补一句批量更新时先动态关掉前一天分区即把 end_date 设为当天再插入新的有效分区而不是物理覆盖历史数据。3.2.1 拉链表更新的最小 SQL 框架-- 关闭当天之前仍在生效的旧版本 UPDATE dim.dim_user_scd2 SET end_date date_sub(${bizdate}, 1) WHERE user_id IN (SELECT user_id FROM tmp_user_new) AND end_date 9999-12-31; -- 插入新版本保留历史记录 INSERT INTO dim.dim_user_scd2 SELECT user_id, user_name, city_id, ${bizdate} AS start_date, 9999-12-31 AS end_date FROM tmp_user_new;关于参数说明end_date 统一用无限大的 9999-12-31 表示当前生效版本是数仓里极常见的约定date_sub 的减一天是为了闭合时间区间避免新旧版本重叠。实际生产里这两条语句会在同一个事务中执行保证不会被调度中途打断造成状态不一致。3.3 星型建模 vs 雪花建模为什么数仓里星型更多星型模型维度表保持冗余雪花模型把维度表继续规范化成多张关联表。数仓面试题的常见问法是“为什么多数场景下选星型”标准回答必须包含“取数快、易理解、关联少”三个关键词。还有一个容易被忽略的点OLAP 场景的加载策略是先宽后窄尽量在建模阶段把维度展开到事实表附近由上层引擎按需裁剪。-- 将雪花模型中的多张维度表展开到用户维表上减少 join 次数 SELECT o.order_id, o.user_id, u.user_name, c.city_name, c.province_name FROM dwd.dwd_order_inc o LEFT JOIN dim.dim_user u ON o.user_id u.user_id LEFT JOIN dim.dim_city c ON u.city_id c.city_id;这段 SQL 的效果是把用户和城市两次 join 变成一次让维度表冗余进事实关联路径。面试时补一句“星型不代表放弃规范化而是在查询路径和存储冗余之间做取舍”就能避免被认为只会背结论。如果面试官追问“宽表会不会太重”可以从“按业务域拆开 按复用频次决定是否落宽表”的角度接住。4. 离线数仓技术栈串讲Hive、Spark、Kafka 在面试题里的高频考点4.1 Hive 数仓面试题分区、分桶、文件格式三选一问到底数仓面试题的另一大半来自离线技术栈三个主角是 Hive、Spark、Kafka2021数仓面试题汇总网上流传的“绝密100个spark面试题”标签也印证了 Spark 必考的地位。Hive 高频题集中在分区与分桶区别、ORC 与 Parquet 选型。面试官常用一个反问试探“分区字段和分桶字段有什么区别”答案是分区按 dt 等列物理分目录用于查询裁剪分桶按列哈希分文件用于提升 join 和抽样效率分区字段是伪列分桶字段必须是真实列。CREATE TABLE hive_order_detail ( order_id STRING, user_id STRING, sku_id STRING ) PARTITIONED BY (dt STRING) CLUSTERED BY (user_id) INTO 64 BUCKETS STORED AS ORC;追问通常会落在“桶数和并发怎么设”。可以顺势回答CLUSTERED BY 指定桶数实际 Reduce 任务数要结合桶数、数据量和 Spark 的 shuffle 分区数一起考虑盲目开大并发反而会产生大量空文件和极小文件。Hive 侧的表还要关注小文件问题常见做法是设置hive.merge.mapred.filestrue或通过中间层合并回答里带上这句更显实战经验。4.2 Spark 面试题宽窄依赖与数据倾斜的答题角度Spark 面经里最常翻车的是一组概念题宽依赖和窄依赖。窄依赖指父 RDD 每个分区最多被子 RDD 一个分区使用宽依赖则相反。面试官真正想听的是对 shuffle 的影响窄依赖不触发 shuffle宽依赖会触发 shuffle。2026 年还在考这道题说明多数候选人对“为什么需要 shuffle”没有现场推导能力。数据倾斜是这一块的必追问题常用处理办法有四条加随机前缀打散 key、提高 shuffle 并行度、广播变量 join 小表、对倾斜 key 单独走一条聚合分支。拿一条实际 SQL 来说-- 处理订单表与用户表 join 用户侧数据膨胀的问题 -- 先用窗口函数定位热 key再决定是否走广播或拆分 WITH user_cnt AS ( SELECT user_id, COUNT(*) AS order_cnt, ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC) AS rn FROM dwd.dwd_order_inc WHERE dt ${bizdate} GROUP BY user_id ) SELECT /* BROADCAST(u) */ order_id, o.user_id, u.user_name FROM dwd.dwd_order_inc o LEFT JOIN dim.dim_user u ON o.user_id u.user_id;注意这里的 BROADCAST 提示只对小表有效如果 dim_user 本身超过广播阈值这个 hint 会被引擎忽略。答题时强调“先定位倾斜 key再决定用哪条策略”比照背随机前缀写法更稳。可以补充一句HBase 在数仓链路中有时候承担维度查询加速的角色把热维度的实时查询从离线表分离但 2021 年这批离线面试题里它更多作为选型讨论出现不需要深入。4.3 Kafka 面试题及答案从消息丢失到精确一次语义的递进回答Kafka 在数仓中的角色是从业务系统同步数据到 ODS 的管道。面试题围绕三件事消息不丢失、幂等、事务。高效回应分三段答生产端开启 acksall 并配合重试服务端设置副本因子和最小同步副本消费端处理成功后再手动提交 offset。# 生产端关键必填参数 acksall retries3 enable.idempotencetrue # 服务端关键参数 replication.factor3 min.insync.replicas2 # 消费端必须手动提交 enable.auto.commitfalse参数说明里的逻辑是acksall 保证 leader 和 ISR 中副本都写入成功min.insync.replicas2 则让至少两个副本确认防止单点宕机后丢数据。面到高阶会追问“acksall 为什么还不够”你需要补一句ack 只能说明 broker 接收成功如果消费者在处理完数据但还没提交 offset 时宕机重新消费会再次处理同一条消息所以下游写入必须幂等。数仓实时链路里常见做法是用 Kafka 接 Flink再通过 Flink 的 checkpoint 配合 Kafka 事务实现端到端精确一次这一步可以作为加分闭环。5. 背题之外的加分项把2021数仓面试题汇总变成自己的追问脚本八股文背一百遍不如把一道题拆成三层来答这层能力可以自己训练。拿到 PDF 里任何一道题不要直接看答案而是按“结论 → 代价 → 反例”三层组织。比如看到“为什么数仓要分层”先答结论“为了复用与血缘清晰”再补一句“但分层会带来加工延迟和存储冗余”最后说“如果公司报表实时性要求极高可以适当压缩层数”。三层都答到面试官基本没有继续追问的空间。实操时准备一个追问脚本拿纸笔给每道题写三个“假如”假如数据量扩大一百倍怎么办、假如源头字段口径变化怎么办、假如查询特别慢怎么办。对应关系如下原题第一层追问第二层追问第三层追问ODS 和业务库区别ODS 为什么要保留原始数据重刷历史怎么保证不丢源表删字段怎么兼容事实表粒度怎么定同一订单多商品怎么拆复合主键不唯一怎么办迟到的数据怎么处理SCD2 拉链表怎么更新历史分区关闭失败怎么办拉链表越拉越长怎么归档与实时维度怎么对齐这样一个题变成三个题2021数仓面试题汇总里两百道题就能扩展成六百个自测点。注意每道题的答案都要求给出“先判断场景再选方案”的句式例如先问“这个属性需要回溯历史吗”再决定 SCD1 还是 SCD2。不要上来就背“我们用的是 SCD2”这会显得像复读机。最后建议每周末挑一道题做一次“限时口述”打开手机录音三分钟内讲完且不卡壳再回放检查有没有口头禅和含糊用词。面试的本质是表述的稳定性知识库已经在这份 PDF 里能把稳定输出练出来的人通过率明显更高。本文还有配套的精品资源点击获取
返回列表