

推荐阅读:
以下是大厂高级数据仓库工程师面试中常见问题的详细解答,涵盖大数据体系理解、数仓架构、建模思想、数据质量、计算引擎原理、实时架构以及SQL实战等内容。内容深入浅出,适合中高级岗位准备。
面试题列表
1、对大数据体系整体的一个理解是怎么样的?
2、数仓架构与分层,这样分层的好处?
3、数仓维度建模思想,PK维度建模异同与利弊?
4、数仓有哪些主题域,如何划分?
5、主题建模、过程建模,分别适用场景和如何做的?
6、你们制定了哪些数仓规范,分别说一下?
7、模型优化项目做过哪些具体的动作,有哪些收益?
8、如何保障数据质量?
9、如何管理指标和保障一致性?
10、HDFS的读写过程(client,namenode,datanode)?
11、数据倾斜的场景与解决方法?
12、spark与MapReduce 计算对比,map、reduce数?
13、Spark宽依赖,窄依赖区别,哪些算子有shuffle?
14、RDD中reduceBykey与groupByKey哪个性能好,为什么?
15、flink和hadoop、spark有什么区别,优势在哪?
16、join的实现原理?
17、实时技术架构,你的理解和存在的问题?
17、SQL面试题,1)用户留存模型 2)波峰波谷SQL 3)连续n日登陆
扫码添免费获取福利(备注资料)。文末有更多资料哦。

1. 对大数据体系整体的一个理解是怎么样的?
回答要点:
大数据体系是一个围绕海量数据采集、存储、处理、分析和服务的完整技术生态,其核心目标是实现数据驱动决策。主要包括以下几个层次:
数据源层(Data Sources)
包括业务系统(如ERP、CRM)、日志系统(Nginx、App日志)、IoT设备、第三方API等。 数据类型多样:结构化(MySQL)、半结构化(JSON)、非结构化(图片、文本)。 数据采集层(Ingestion)
工具:Flume、Kafka、Logstash、Sqoop、DataX、Flink CDC。 实时/离线采集并存,Kafka常用于实时管道。 数据存储层(Storage)
HDFS:分布式文件系统,适合大文件存储。 HBase:列式存储,支持随机读写。 Hive:基于HDFS的数据仓库,支持SQL查询。 S3/对象存储:云原生常用。 资源调度与计算引擎层
离线批处理:MapReduce、Spark。 实时流处理:Flink、Storm、Spark Streaming。 多模态:Spark Structured Streaming。 资源管理:YARN、Kubernetes。 计算框架: 数据仓库与数据湖层
数仓(Data Warehouse):结构化建模,主题域划分,服务于BI和报表。 数据湖(Data Lake):原始数据存储,支持多种格式,灵活性高(如Delta Lake、Iceberg)。 湖仓一体趋势明显(如Databricks、阿里云Hologres)。 数据服务与应用层
BI工具:Superset、Tableau、Power BI。 数据API服务:提供指标查询接口。 推荐系统、风控模型等AI应用。 元数据管理 & 数据治理
元数据:表结构、血缘关系、字段含义。 数据质量监控、权限控制、生命周期管理。
✅ 总结: 大数据体系是“采集 → 存储 → 计算 → 建模 → 服务”的闭环,强调可扩展性、容错性、高并发与一致性。
2. 数仓架构与分层,这样分层的好处?
常见的数据仓库分层架构(以5层为例):
ODS层(Operation Data Store):原始数据层,保持数据原貌不做处理 DWD层(Data Warehouse Detail):明细数据层,对ODS数据进行清洗转换 DWS层(Data Warehouse Service):服务数据层,面向主题的轻度汇总 ADS层(Application Data Store):应用数据层,面向业务的个性化统计 DIM层(Dimension):维度表层,存储一致性维度
分层的好处:
清晰数据结构:每层有明确职责,便于理解和使用 减少重复开发:规范数据从原始到应用的全流程 统一数据口径:保证数据一致性 简化复杂问题:将复杂ETL流程分解到各层 数据血缘追踪:便于数据溯源和影响分析 隔离原始数据:保护原始数据不被直接访问和修改
3. 数仓维度建模思想,PK维度建模异同与利弊?
维度建模思想: 由Ralph Kimball提出,以分析需求为驱动,通过事实表(Fact)和维度表(Dimension)构建星型或雪花模型。
维度建模 vs 范式建模(3NF):
利弊分析:
维度建模优点:查询性能高,理解简单,适合分析场景 维度建模缺点:数据冗余,灵活性差,ETL复杂 范式建模优点:数据一致性好,更新效率高 范式建模缺点:查询性能差,不适合分析场景
实际应用中,常采用"维度建模+适当冗余"的混合模式。
4. 数仓有哪些主题域,如何划分?
常见主题域划分:
用户主题:用户属性、行为、画像等 商品主题:商品信息、类目、价格等 交易主题:订单、支付、退款等 物流主题:仓储、配送、库存等 营销主题:活动、优惠券、广告等 服务主题:客服、售后、评价等 财务主题:账务、结算、发票等 风控主题:欺诈识别、异常监控等
划分原则:
按业务过程划分(如订单、支付等) 按业务部门划分(如销售、财务等) 按分析视角划分(如用户、商品等) 保持主题域内高内聚,主题域间低耦合 每个主题域有明确的负责人和边界
5. 主题建模、过程建模,分别适用场景和如何做的?
主题建模(Subject-Oriented Modeling):
适用场景:面向分析需求,强调数据如何被使用 做法: 识别关键业务主题(如用户、商品) 定义主题边界和关系 设计星型/雪花模型 确定事实表和维度表 设计层次结构和属性
过程建模(Process-Oriented Modeling):
适用场景:面向数据生产过程,强调数据如何被加工 做法: 分析业务过程和数据流 识别关键实体和关系 设计规范化模型(3NF) 定义数据转换规则 设计ETL流程和数据质量检查点
对比:
主题建模适合分析型应用,过程建模适合操作型系统 主题建模以用户需求为驱动,过程建模以业务流程为驱动 实际项目中常结合使用,过程建模为底层,主题建模为上层
6. 你们制定了哪些数仓规范,分别说一下?
常见数仓规范包括:
命名规范:
表命名:层次_主题_描述_周期,如dwd_trade_order_di 字段命名:snake_case风格,如user_id 模型设计规范:
分层定义和职责 事实表和维度表设计标准 缓慢变化维处理方案 开发规范:
SQL编写规范(缩进、注释等) ETL开发流程 脚本版本管理 数据质量规范:
完整性、准确性、一致性标准 数据监控指标和阈值 问题处理流程 指标管理规范:
指标命名和口径定义 派生指标和原子指标管理 指标一致性保障机制 安全规范:
数据分级和访问控制 敏感数据脱敏规则 审计日志要求 运维规范:
任务调度和依赖配置 资源分配标准 故障处理流程
7. 模型优化项目做过哪些具体的动作,有哪些收益?
模型优化动作:
分区优化:
将大表按日期、业务线等合理分区 收益:查询扫描数据量减少70% 分桶优化:
对高频JOIN字段进行分桶 收益:JOIN性能提升50% 数据压缩:
采用Snappy/ZSTD压缩格式 收益:存储节省40% 冗余设计:
适当增加冗余字段减少JOIN 收益:查询响应时间缩短60% 维度降维:
将多层雪花模型简化为星型模型 收益:模型复杂度降低,ETL效率提高 冷热分离:
将历史冷数据归档到低成本存储 收益:热数据查询性能提升,存储成本降低30% 索引优化:
对高频查询条件建立合适索引 收益:点查性能提升10倍
总体收益:
查询性能平均提升3-5倍 存储成本降低30-50% ETL任务运行时间缩短40% 资源使用效率提高
8. 如何保障数据质量?
数据质量保障体系:
事前预防:
制定数据标准和规范 设计合理的数仓模型 建立数据血缘关系 事中监控:
完整性:非空检查、枚举值检查 准确性:值域检查、逻辑规则检查 一致性:跨表一致性检查、指标一致性检查 及时性:数据到达时间监控 设置质量阈值和告警机制 事后治理:
质量问题跟踪和修复 数据质量评分和报告 定期数据质量审计 技术工具:
数据质量检测工具(Griffin、DQC等) 数据血缘工具(Atlas等) 自定义监控脚本 组织流程:
明确数据Owner职责 建立数据质量SLA 质量问题闭环处理流程
9. 如何管理指标和保障一致性?
指标管理方法:
指标分层:
原子指标:最细粒度指标,如订单金额 派生指标:原子指标+统计维度,如每日订单金额 复合指标:多个指标计算得出,如转化率 统一元数据:
建立指标中心,集中管理所有指标 记录指标名称、定义、口径、维度、数据源等 维护指标的血缘关系和变更历史 一致性保障:
相同指标统一数据来源和计算逻辑 派生指标必须基于原子指标构建 指标变更需要评审和影响分析 技术实现:
使用指标管理系统或数据字典 通过视图或中间表实现指标逻辑 自动化指标一致性检查 组织流程:
设立指标治理委员会 制定指标开发和维护流程 定期进行指标一致性审计
10. HDFS的读写过程(client,namenode,datanode)?
HDFS写流程:
Client向NameNode发起文件写入请求 NameNode检查权限和文件是否存在,返回可写入的DataNode列表 Client将文件分块(Block),建立数据管道(pipeline) Client将第一个Block写入管道中的第一个DataNode 第一个DataNode接收数据并写入本地,同时转发给第二个DataNode 第二个DataNode同样操作,直到最后一个DataNode 管道确认信息逆向返回给Client 完成一个Block写入后,继续写入下一个Block 所有Block写入完成后,Client通知NameNode提交文件
HDFS读流程:
Client向NameNode发起文件读取请求 NameNode返回文件Block所在的DataNode列表(按网络拓扑排序) Client选择最近的DataNode建立连接 DataNode发送数据给Client 如果第一个Block读取完成,继续从下一个Block的DataNode读取 所有Block读取完成后,Client合并成完整文件
11. 数据倾斜的场景与解决方法?
常见倾斜场景:
Group By倾斜:某些key数据量远大于其他 Join倾斜:关联键分布不均 分区倾斜:分区策略不合理导致某些分区过大 Skew Join:大表关联小表但小表key集中
解决方法:
参数调优:
设置 hive.map.aggr=true
(map端聚合)调整 hive.groupby.skewindata=true
(两阶段聚合)增加reduce数( set mapred.reduce.tasks=N
)SQL改写:
倾斜key单独处理再UNION ALL 将随机前缀加到倾斜key上分散数据 小表JOIN大表改为MAP JOIN( /*+ MAPJOIN(b) */
)业务调整:
与业务方沟通修改数据分布 过滤掉异常倾斜数据 改变分区策略 特殊处理:
对倾斜key采样估算后单独增加reduce资源 使用SkewJoin优化器(如Spark的 spark.sql.adaptive.skewJoin.enabled
)
12. spark与MapReduce 计算对比,map、reduce数?
Spark vs MapReduce:
map/reduce数确定:
MapReduce:
map数:由输入数据量和分片大小决定( mapred.max.split.size
)reduce数:用户指定( mapred.reduce.tasks
),默认1Spark:
分区数(类似map数):由输入源决定,可 repartition()
调整shuffle分区数:由 spark.sql.shuffle.partitions
控制(默认200)
Spark的优化在于可以自动调整分区,且不需要严格区分map和reduce阶段。
13. Spark宽依赖,窄依赖区别,哪些算子有shuffle?
宽依赖 vs 窄依赖:
会引起shuffle的算子:
重分区: repartition
、coalesce
(部分情况)聚合: groupByKey
、reduceByKey
、aggregateByKey连接: join
、cogroup
、intersection排序: sortBy
、sortByKey去重: distinct
14. RDD中reduceBykey与groupByKey哪个性能好,为什么?
reduceByKey性能更好,原因:
Combiner优化:
reduceByKey
会在map端先进行本地聚合(combiner)groupByKey
直接传输所有数据,不进行map端聚合数据传输量:
reduceByKey
传输的是聚合后的数据,量更小groupByKey
传输原始数据,量大内存使用:
reduceByKey
内存压力小groupByKey
可能引起OOM(当key对应的value很多时)
使用建议:
需要聚合时优先使用 reduceByKey只有在需要保留所有value时才用 groupByKey类似优化的还有 aggregateByKey
、foldByKey
等
15. flink和hadoop、spark有什么区别,优势在哪?
Flink vs Hadoop/Spark:
Flink优势:
真正的流处理:非微批架构,低延迟 流批统一:同一套API处理流批场景 事件时间支持:完善的时间语义和窗口机制 状态管理:支持大规模有状态计算 Exactly-once:精确一次语义保证 高吞吐低延迟:性能优于Spark Streaming
16. join的实现原理?
常见Join实现方式:
Nested Loop Join:
双重循环匹配 适合小表join小表 Hash Join:
阶段1:对小表构建hash表 阶段2:扫描大表在hash表中查找匹配 适合小表join大表 Sort Merge Join:
阶段1:对两表按join key排序 阶段2:归并扫描匹配记录 适合大表join大表 Broadcast Join:
将小表广播到所有节点 与大表本地join Spark中 spark.sql.autoBroadcastJoinThreshold
控制Shuffle Hash Join:
按join key分区 每个分区内hash join 适合中等表join Semi/Anti Join:
只关心是否存在匹配 可优化为半连接
分布式环境下的Join优化:
尽量让join在分区内完成 小表广播避免shuffle 倾斜key特殊处理 合理设置并行度
17. 实时技术架构,你的理解和存在的问题?
实时技术架构理解:
典型Lambda架构和Kappa架构:
Lambda架构:
问题:两套代码维护成本高,结果一致性难保证
批层:处理全量数据,保证准确性 速度层:处理增量数据,保证低延迟 服务层:合并批流结果 Kappa架构:
问题:消息队列存储成本高,长窗口计算资源消耗大
只有流处理层,历史数据通过重放处理 简化架构,一套代码
现代实时架构趋势:
流批一体(Flink) 实时数仓(实时ODS→DWD→DWS) 状态化流处理 实时OLAP(ClickHouse/Druid)
存在的问题:
资源消耗:实时计算需要长期占用资源 状态管理:故障恢复和扩缩容复杂 数据一致性:精确一次语义实现成本高 长窗口计算:内存和存储压力大 实时离线对齐:结果不一致时的处理策略 监控运维:复杂度高于批处理
18. SQL面试题
1) 用户留存模型
-- 计算次日留存率、3日留存率、7日留存率
WITH
first_day_users AS (
SELECT
user_id,
MIN(event_date) AS first_day
FROM user_events
GROUPBY user_id
),
retention_stats AS (
SELECT
first_day,
COUNT(DISTINCT f.user_id) AS new_users,
COUNT(DISTINCTCASEWHENDATEDIFF(e.event_date, f.first_day) = 1THEN e.user_id END) AS day1_retained,
COUNT(DISTINCTCASEWHENDATEDIFF(e.event_date, f.first_day) = 2THEN e.user_id END) AS day2_retained,
COUNT(DISTINCTCASEWHENDATEDIFF(e.event_date, f.first_day) = 6THEN e.user_id END) AS day7_retained
FROM first_day_users f
LEFTJOIN user_events e ON f.user_id = e.user_id
GROUPBY first_day
)
SELECT
first_day,
new_users,
day1_retained,
day2_retained,
day7_retained,
ROUND(day1_retained * 100.0 / new_users, 2) AS day1_retention_rate,
ROUND(day2_retained * 100.0 / new_users, 2) AS day3_retention_rate,
ROUND(day7_retained * 100.0 / new_users, 2) AS day7_retention_rate
FROM retention_stats
ORDERBY first_day;
2) 波峰波谷SQL
-- 找出每日访问量的波峰和波谷
WITH daily_visits AS (
SELECT
visit_date,
COUNT(*) AS visit_count,
LAG(COUNT(*), 1) OVER (ORDERBY visit_date) AS prev_count,
LEAD(COUNT(*), 1) OVER (ORDERBY visit_date) AS next_count
FROM user_visits
GROUPBY visit_date
)
SELECT
visit_date,
visit_count,
CASE
WHEN visit_count > prev_count AND visit_count > next_count THEN'peak'
WHEN visit_count < prev_count AND visit_count < next_count THEN'valley'
ELSE'normal'
ENDAS peak_valley_status
FROM daily_visits
ORDERBY visit_date;
3) 连续n日登陆
-- 找出连续登录至少5天的用户
WITH
user_login_dates AS (
SELECTDISTINCT
user_id,
login_date
FROM user_logins
),
login_groups AS (
SELECT
user_id,
login_date,
DATE_SUB(login_date, ROW_NUMBER() OVER (PARTITIONBY user_id ORDERBY login_date)) AS grp
FROM user_login_dates
),
consecutive_logins AS (
SELECT
user_id,
grp,
MIN(login_date) AS start_date,
MAX(login_date) AS end_date,
COUNT(*) AS login_days
FROM login_groups
GROUPBY user_id, grp
HAVINGCOUNT(*) >= 5
)
SELECT
user_id,
start_date,
end_date,
login_days
FROM consecutive_logins
ORDERBY login_days DESC, user_id;
据统计,99%的大咖都关注了这个公众号👇
大家都在看:
数据仓库分层设计:ODS/DWD/DWS/ADS到底该怎么划边界?
Doris vs StarRocks vs ClickHouse:新一代MPP引擎的终极对决
数据仓库中的“一致性维度”是什么?为什么它能统一指标口径?(文末送福利)
数据血缘 vs 数据目录:元数据管理的两大核心,谁更重要?(文末送数据治理体系解决方案ppt)
80%的数据项目失败,竟是因为忽略了元数据!(附元数据技术架构设计方案ppt)





