生而为人

程序员的自我修养

0%

数据仓库面试宝典一

[toc]

数据仓库离线 + 实时全级别面试宝典(含详细答案)

第一部分 0-1 年(应届生 / 入门级)面试题 + 详细答案

2. 用 SQL 实现用户每日登录次数统计,表结构:user_login (user_id string, login_time timestamp)

答案

1
2
3
4
5
6
7
8
-- 按用户、日期分组统计登录次数
SELECT
user_id,
DATE(login_time) AS login_date,
COUNT(*) AS login_times
FROM user_login
GROUP BY user_id, DATE(login_time)
ORDER BY login_date, user_id;

3. 如何用 SQL 实现两张表的左连接,以及左连接、内连接、右连接、全连接的区别

答案

  • 左连接 SQL 示例(用户表左连订单表,查询所有用户及其订单):
1
2
3
4
5
SELECT
a.user_id, a.user_name, b.order_id, b.order_amount
FROM user_info a
LEFT JOIN order_info b
ON a.user_id = b.user_id;
  • 四种连接的核心区别:

    1. 内连接(INNER JOIN):只返回两张表中匹配条件一致的数据,不匹配的直接过滤。
    2. 左连接(LEFT JOIN):以左表为基准,返回左表所有数据,右表匹配不到的字段补 NULL。
    3. 右连接(RIGHT JOIN):以右表为基准,返回右表所有数据,左表匹配不到的字段补 NULL。
    4. 全连接(FULL JOIN):返回两张表的所有数据,匹配不到的字段补 NULL。

答案

Flink 的 Exactly-Once 语义,指的是每条数据只会被精确处理一次,即使任务发生故障重启,也不会出现数据重复处理、也不会出现数据丢失,最终的计算结果和数据只处理一次完全一致

Flink 的 Exactly-Once 语义分为两个层面:引擎内部的 Exactly-Once端到端的 Exactly-Once,实现原理如下:

一、引擎内部的 Exactly-Once:基于 Checkpoint 机制

Checkpoint 是 Flink 实现容错和精准一次的核心,本质是定时对所有算子的状态做一个全局快照,持久化到远程存储中,任务故障重启时,从最新的 Checkpoint 恢复状态,保证数据只处理一次。

Checkpoint 的执行流程:

  1. JobManager 触发 Checkpoint,向所有 Source 算子发送 Checkpoint Barrier(屏障),Barrier 是一个特殊的标记,代表该 Barrier 之前的所有数据都已经处理完成。
  2. Source 算子收到 Barrier 后,停止数据处理,将自己的状态(如 Kafka Offset)持久化到 Checkpoint 存储中,然后向 JobManager 确认 Checkpoint 完成,再将 Barrier 发送给下游算子。
  3. 下游算子收到所有上游通道的 Barrier 后(Barrier 对齐),停止处理数据,将自己的状态持久化到 Checkpoint 存储中,向 JobManager 确认,再将 Barrier 继续向下游发送。
  4. 当所有 Sink 算子都完成 Checkpoint,向 JobManager 确认后,本次 Checkpoint 全局完成。
  5. 任务故障重启时,所有算子都从最新的 Checkpoint 中恢复状态,Source 从记录的 Offset 重新消费数据,保证数据只处理一次,不会重复也不会丢失。
二、端到端的 Exactly-Once:基于两阶段提交(2PC)

Checkpoint 只能保证 Flink 引擎内部的 Exactly-Once,要实现端到端(从 Source 到 Sink)的 Exactly-Once,还需要 Sink 端支持事务,Flink 通过两阶段提交(2PC) 实现,核心是在 Checkpoint 的过程中,实现 Sink 端的事务提交和回滚。

两阶段提交的执行流程:

  1. 预提交阶段(Pre-Commit):当算子收到 Barrier,完成状态快照后,Sink 算子会开启一个事务,将本次 Checkpoint 周期内的所有数据预写入外部系统,但不提交事务,数据对外不可见;同时将事务信息持久化到 Checkpoint 中。
  2. 提交阶段(Commit):当 JobManager 收到所有算子的 Checkpoint 完成确认,标记本次 Checkpoint 全局完成后,会向所有算子发送 Checkpoint 完成的通知,Sink 算子收到通知后,正式提交之前预提交的事务,数据对外可见,完成最终写入。
  3. 异常回滚:如果 Checkpoint 过程中发生故障,任务重启后,会从最新的完成的 Checkpoint 恢复,未提交的事务会直接回滚,保证数据不会重复写入,最终实现端到端的 Exactly-Once。

注意事项:要实现端到端的 Exactly-Once,外部 Sink 系统必须支持事务,比如 Kafka、JDBC 数据库、支持事务的 ClickHouse;对于不支持事务的系统,只能通过幂等写入实现最终的 Exactly-Once。


附加部分 面试通用工具包

1. 各经验级别项目自我介绍模板

0-1 年应届生 / 入门级

面试官您好,我是 XX,有 XX 年数仓开发经验,主要参与了 XX 公司的离线数仓建设项目。我的核心工作是基于 Hive 进行数仓分层开发,编写 SQL 完成数据清洗、指标计算,配合调度工具完成任务上线,同时参与了基础的实时数据采集和 Flink 实时任务开发。在项目中,我掌握了数仓基础建模、Hive SQL 优化、Kafka 和 Flink 的基础使用,解决了数据倾斜、小文件等常见问题,具备独立完成数仓基础模块开发的能力。

1-3 年初级开发级

面试官您好,我是 XX,有 XX 年数仓开发经验,全程参与了 XX 公司离线 + 实时数仓的搭建与迭代。我负责的核心工作包括:业务需求调研、数仓分层建模、Hive/Spark 离线任务开发、Flink 实时任务开发、SQL 性能优化、生产问题排查。主导了用户行为分析、交易指标统计等核心模块的建设,解决了生产环境中的数据倾斜、任务超时、Kafka 堆积、Flink 反压等常见问题,同时搭建了基础的数据质量监控体系,保障了数仓任务的稳定运行。具备独立完成数仓全流程开发、解决生产复杂问题的能力。

3-5 年高级开发级

面试官您好,我是 XX,有 XX 年数仓开发经验,主导了 XX 公司从 0 到 1 的离线 + 实时一体化数仓建设。我负责整体数仓架构设计、技术选型、建模规范制定、核心模块开发,同时带领团队完成数仓迭代与运维。在项目中,我设计了基于湖仓一体的流批一体架构,解决了 PB 级海量数据的性能优化、口径一致性、高可用等核心问题,主导了大促期间数仓稳定性保障方案的落地,同时搭建了企业级数据治理体系,实现了数据资产的全生命周期管理。具备数仓架构设计、复杂问题攻坚、团队管理的能力。

5 年以上专家 / 架构师级

面试官您好,我是 XX,有 XX 年大数据和数仓架构经验,负责多家企业的企业级数仓体系从 0 到 1 的规划、设计、落地与运营。我核心聚焦于通过数据架构支撑企业数字化转型,擅长企业级流批一体、湖仓一体架构设计,数据治理体系搭建,数据资产化运营。在过往的项目中,我主导制定了企业级数据战略,设计了支撑多业务线、多租户的企业级数仓架构,解决了跨部门数据孤岛、口径不一致、数据价值无法落地等核心痛点,推动企业从业务数据化到数据业务化的升级,同时带领团队完成了技术体系升级、团队能力建设,具备企业级数据架构顶层设计、跨部门协调、团队管理与数据价值运营的能力。

2. 数仓面试避坑 10 条

  1. 不说空话,所有的技术点都要结合自己的项目经历,不要只背理论,面试官一定会追问你在项目中是怎么用的。
  2. 不夸大自己的经验,没做过的内容不要说,面试官几个追问就会露馅,诚实比夸大更重要。
  3. 遇到不会的问题,直接坦诚说自己没接触过,不要瞎编,同时可以说自己的理解思路,体现自己的学习能力和思考能力。
  4. 回答问题要有逻辑,分点说明,先说结论,再说细节,不要东拉西扯,让面试官抓不住重点。
  5. 不要贬低之前的公司、团队和技术架构,多从自己的成长、解决的问题出发,体现自己的专业性。
  6. 指标口径是数仓面试的核心,所有的指标都要明确口径,比如 DAU,要说明是怎么定义活跃、怎么去重、时间口径是什么,体现自己的严谨性。
  7. 性能优化的问题,不要只说调参数,要先说排查思路,再说优化方案,最后说优化效果,比如优化前任务运行多久,优化后多久,体现自己的实战能力。
  8. 架构设计的问题,不要只堆技术组件,要先说明业务痛点,再说架构设计的思路,为什么选这个技术栈,解决了什么问题,体现自己的架构思维,而不是技术堆砌。
  9. 面试前一定要熟悉自己简历上写的所有项目和技术点,面试官 90% 的问题都会围绕简历展开,不要简历上写了,自己却不熟悉。
  10. 反问环节,不要问薪资、加班这种太功利的问题,优先问团队的技术栈、业务方向、这个岗位的核心挑战,体现自己对岗位的兴趣和专业性。

3. 面试反问环节话术模板

0-1 年应届生 / 入门级

  1. 请问这个岗位的核心职责是什么,团队对这个岗位的期望是怎样的?
  2. 请问团队的技术栈是怎样的,新人入职会有相关的培训和带教吗?
  3. 请问团队目前的数仓建设处于什么阶段,接下来的规划是怎样的?

1-3 年初级开发级

  1. 请问这个岗位需要负责的核心业务和模块是什么,目前团队面临的最大的技术挑战是什么?
  2. 请问团队的数仓架构是怎样的,离线和实时的占比是多少,接下来有架构升级的规划吗?
  3. 请问团队的开发流程是怎样的,需求评审、代码评审、上线流程是怎么规范的?

3-5 年高级开发级

  1. 请问这个岗位是偏向架构设计,还是偏向业务开发,需要带领团队吗?
  2. 请问公司目前的数仓建设处于什么阶段,存在哪些痛点,希望这个岗位的人来解决哪些问题?
  3. 请问公司对数据团队的定位是怎样的,是支撑业务,还是驱动业务,未来的发展规划是怎样的?

5 年以上专家 / 架构师级

  1. 请问公司目前的数字化转型处于什么阶段,对数据架构的核心诉求是什么?
  2. 请问公司目前的数据体系存在哪些核心痛点,希望通过这个岗位的加入,带来哪些改变?
  3. 请问公司对数据团队的长期规划是怎样的,在数据资产化、数据驱动业务方面,有怎样的布局?

数据仓库岗位面试常问的设计题

数据仓库岗位面试的设计题,核心是在考察你是否具备解决实际业务问题的结构化思维工程化落地能力,而不是寻找一个标准答案-31。面试官期待的是一个逻辑清晰、考虑周全(例如明确分层、划分数据域、阐述建模选择的理由)的方案-31

下面,我会拆解三高频题,并提炼出一个通用的解题思路,让你可以“举一反三”。

💎 三大经典设计题及参考答案

1. 经典电商数仓设计:围绕“下单”设计

题目示例:假设你是电商公司的数仓负责人,要为公司设计一个数据仓库,核心是分析“用户下单”这一业务过程,你会怎么做?

这道题考察的是对数仓建设的整体把控能力,建议的答题思路是:

  • 需求与数据调研:首先明确业务需求(例如分析GMV、用户复购率、大促活动效果),同时梳理数据来源,如订单系统(MySQL)、用户行为(埋点日志)、商品和用户维度等信息。
  • 明确数据域与业务过程:此场景下的数据域是交易域,核心业务过程就是下单
  • 确定数据粒度:DWD(数据仓库明细)层的订单事实表,粒度应为“订单的每一个子项(SKU)”。这能支持最灵活的分析,比如分析某个商品的销量。
  • ETL流程说明
    • ODS层:从业务库增量同步原始数据。
    • DWD层:对数据进行清洗(如处理异常订单状态、清洗无效用户ID)、维度退化(如将订单状态、支付方式等编码,冗余为可读字段)和关联(如关联商品维度补齐商品类目)。这部分是数据开发的核心,也常被面试官提及。
    • DWS层:按天、按用户或商品粒度,预计算“下单次数”、“下单金额”等派生指标,以加速查询。
  • 技术选型:例如,存储用Hive/Spark,计算引擎用Spark/Flink,查询加速用ClickHouse,作业调度用Airflow/DolphinScheduler

2. 商品维度缓慢变化:如何处理“商品类目改名”?

题目示例:电商的商品类目可能会调整,比如将“女装/连衣裙”改为“女士/裙装”,如何在数仓中优雅地处理这种变化?

这道题聚焦于经典的缓慢变化维度问题-。

  • 识别问题:商品类目的变化,会影响所有基于历史类目的分析,例如同比数据。因此需要选择策略来保留或覆盖历史。
  • 选择处理策略
    • Type 1(直接覆盖)不适用。这会丢失历史,导致统计口径不一致。
    • Type 2(增加行)这是最推荐电商商品维度的方案。当类目变化时,为商品维度表新增一条记录,并标记生效时间(start_date)和失效时间(end_date)。此方案可以完整保留历史,支持按时间点切片分析-14
    • Type 3(增加列):增加“原类目”和“现类目”列,但只能保留上一次变化,不够灵活-14
  • ETL实现:在每日ETL中,比较源系统的类目信息和当前维表,若发现变化,则关闭旧记录(更新end_date)并插入一条新记录。

3. 用户行为分析设计:围绕“用户点击”设计

题目示例:我们现在要分析用户在App上的点击行为,比如每日活跃、点击流、页面转化等,如何设计相关表?

这道题考察的是对事实表类型的理解,以及对海量日志数据的处理能力。

  • 设计重点:用户点击流数据,是典型的事务事实表。每一行代表一个点击事件,粒度是“单次点击”。
  • 数据来源与ETL
    • 数据来源:前端或客户端上报的埋点日志
    • ODS层:将原始日志数据落地到ODS(操作数据存储) 层。
    • DWD层:进行清洗(如过滤爬虫、剔除脏数据)、解析(如将User-Agent解析为操作系统和浏览器类型)和维表关联(如关联用户维表和页面信息维表)。
  • 用户识别与维度建模:构建会话唯一标识 session_id,将连续点击组织成会话,以便分析用户路径和页面转化率。

📝 通用答题框架

无论遇到什么场景,都可以套用这套“四步法”来组织回答:

  1. 明确业务目标与边界:首先用一句话点明设计要解决的核心问题(例如“分析订单”),并划定数据范围,界定问题边界。
  2. 规划分层架构与数据流向ODS→DWD→DWS→ADS。这是数仓设计的基石,最好是能画出数据流向图,向面试官展示对整个流程的掌控力。这个分层思想在面试中经常出现-5-12
  3. 深入核心模型设计:阐述FACT(事实表)和DIM(维度表)的设计。
    • 事实表:确定“谁(用户)、在什么时间(时间维度)、在哪里(页面/地点维度)、做了什么(事实,如下单金额)”-12
    • 维度表:确认涉及的维度,并指出是否有缓慢变化维度(SCD)-14
    • 建模方法:优先选择易于理解和查询的星型模型-2。如果被追问,可适当提及雪花模型-1
  4. 考虑可扩展性与技术选型:展望未来,主动提及可扩展性设计并给出技术选型的理由。
    • 扩展性:例如,即使当前只有订单数据,表设计也需预留用户ID字段,为未来的用户维度分析做准备。
    • 技术选型:简明扼要地说明在每一层选择的计算、存储组件及理由,这能体现你对成本和性能的权衡。

✨ 写在最后

除了技术细节,数据仓库设计面试还特别看重你的工程化思想

  • 技术与业务结合:你的所有设计决策,最终都要落到“如何更好地支撑业务分析”这一点上。
  • 数据治理意识:主动提及数据质量监控(如空值率、唯一性检查)和元数据管理,这会是很好的加分项-1
  • 保持沟通与提问:在“设计”过程中,要主动向面试官提问以澄清需求,例如:“这个报表的刷新频率要求是?(实时/小时/天)”。这体现了你的沟通能力和严谨性。

同时,牢记以下扩展的知识点,能在回答时有效提升回答的深度与广度:

  • 数仓分层原则:面试官很关心你能否清晰阐述ODS(操作数据存储层)、DWD(数据仓库明细层)、DWS(数据仓库汇总层)和ADS(应用数据层)的划分标准和各自职责-5-18
  • 拉链表设计:掌握SCD Type 2的拉链表实现原理,并能清晰说明其如何通过start_dateend_date等字段来管理历史状态-14
  • 事实表类型:除了事务事实表,最好还能区分出周期快照事实表(例如每日账户余额)和累积快照事实表(例如记录订单从“下单”到“签收”的全生命周期状态)-1
  • 缓慢变化维处理方式:除了最常见的Type 1和Type 2,了解Type 3等其他方式的适用场景,会让你的回答更完整。
  • 总线矩阵与数据域划分:明白如何通过总线矩阵来规划企业的核心业务过程和一致性维度,展现出宏观的架构设计思维-5
  • 常见面试题:“数据仓库和数据库的区别”、“为什么需要数据分层”等基础知识虽然看似简单,但在面试中依然高频出现,建议务必准备-12-12