一、核心面试问题集锦 🎯
1. 项目是根据什么业务场景来划分的
🔍 考察重点:项目规划逻辑、业务与数据的关联能力、数仓 / 大数据项目的划分思路
📌 核心解答:
大数据项目的业务场景划分,核心是 “以业务需求为导向,结合数据产生的源头和用途”,常见划分维度及落地逻辑如下:
① 按核心业务域划分(最主流):
根据企业核心业务板块拆分,比如视频平台可划分为 “用户行为域”(观看、点赞、评论)、“内容运营域”(视频上传、审核、推荐)、“用户管理域”(注册、登录、画像)、“商业化域”(广告投放、充值)等。
逻辑:每个业务域对应一套完整的业务流程,数据需求和加工逻辑相对独立,便于团队分工和数据管理。
② 按业务目标划分:
围绕具体业务目标拆分场景,比如 “用户增长场景”(统计新增用户、留存率)、“内容优化场景”(视频完播率、热门视频分析)、“风控场景”(异常观看行为检测)等。
逻辑:直接对齐业务决策需求,确保数据产出能直接支撑业务目标达成。
③ 按数据来源 / 形态划分:
比如 “日志数据场景”(用户行为埋点日志)、“业务数据库同步场景”(用户信息、视频元数据)、“实时监控场景”(实时在线人数、实时播放量)等。
逻辑:不同来源 / 形态的数据,处理技术(批处理 / 流处理)和存储方式不同,按此划分可提升技术选型的针对性。
💡 示例(视频平台场景):
若需做 “视频内容优化” 相关项目,会划分到 “内容运营域 - 内容效果分析场景”,核心处理视频观看日志、完播数据,支撑运营同学调整视频推荐策略。
2. 对 Hadoop 的理解
🔍 考察重点:Hadoop 核心组件、核心思想、适用场景、行业价值
📌 核心解答:
Hadoop 是开源的分布式大数据处理框架,核心解决 “海量数据的存储和并行计算” 问题,是大数据生态的基础,主要包含三大核心组件及周边生态工具。
① 核心组件(Hadoop 2.x + 核心架构):
-
HDFS(分布式文件系统):负责海量数据的分布式存储,采用 “主从架构”——NameNode(主节点)管理元数据(文件名、路径、Block 位置),DataNode(从节点)存储实际数据块(默认 128MB / 块),通过多副本(默认 3 份)保证数据可靠性。
-
YARN(资源管理框架):负责集群资源(CPU、内存)的调度和管理,接收计算任务请求,分配资源给任务节点,监控任务执行状态。
-
MapReduce(分布式计算框架):基于 “分而治之” 思想,实现海量数据的并行计算,分为 Map(映射)和 Reduce(归约)两个核心阶段,依赖 YARN 调度资源、HDFS 存储数据。
② 核心思想:
-
分布式存储:将大文件拆分为多个小数据块,分散存储在多个节点,突破单节点存储上限;
-
并行计算:将大任务拆分为多个小任务,在多个节点同时执行,提升计算效率;
-
容错性:通过数据多副本、节点故障自动切换(如 NameNode HA),保证集群稳定运行。
③ 适用场景:
批处理海量数据(如日志分析、离线报表统计),不适合实时计算(如毫秒级响应)、小数据量计算场景。
④ 生态周边:
Hive(基于 Hadoop 的数据仓库工具,将 SQL 转为 MapReduce 任务)、Spark(基于内存的计算框架,兼容 Hadoop 生态)、HBase(分布式列式数据库)等,共同构成大数据处理生态。
3. 讲一下 MapReduce 的执行过程
🔍 考察重点:MapReduce 核心执行流程、各阶段关键操作、数据流转逻辑
📌 核心解答:
MapReduce 执行过程分为 “输入→Map 阶段→Shuffle 阶段→Reduce 阶段→输出”5 个核心步骤,全程由 YARN 调度资源、HDFS 提供数据存储,具体流程如下:
① 输入阶段(Input):
-
读取 HDFS 上的原始数据,由 InputFormat(默认 TextInputFormat)将数据拆分为多个 InputSplit(输入分片),每个 InputSplit 对应一个 Map 任务;
-
注意:InputSplit 不是实际数据块,而是数据的逻辑分片,默认与 HDFS Block 大小一致(128MB),确保数据本地性(Map 任务优先在数据所在节点执行,减少网络传输)。
② Map 阶段(映射):
-
Map 任务接收 InputSplit 数据,通过 RecordReader 解析为 <key,value> 键值对(如文本数据默认 < 行号,行内容 >);
-
执行用户自定义的 map () 函数,对键值对进行处理(如过滤、转换),输出中间键值对 < k1, v1>;
-
中间结果先写入内存缓冲区(默认 100MB),当缓冲区达到阈值(默认 80%),会触发溢写(Spill),将数据排序(Sort)后写入本地磁盘临时文件。
③ Shuffle 阶段(洗牌,核心桥梁):
Map 输出到 Reduce 输入的中间数据流转阶段,核心是 “数据分区、排序、合并”,确保相同 key 的数据集被分发到同一个 Reduce 任务,具体步骤:
-
分区(Partition):Map 阶段溢写前,按 Reduce 任务数量对中间键值对分区(默认 HashPartition),相同 key 落在同一分区;
-
排序(Sort):溢写时对每个分区内的键值对按 key 排序;
-
合并(Combine+Merge):Map 端可通过自定义 Combine 函数(可选)对同一分区的相同 key 数据预聚合(减少数据量);之后 Reduce 端通过 Shuffle Fetcher 线程拉取所有 Map 节点对应分区的临时文件,再进行合并(Merge)和二次排序,得到有序的 <k1, list (v1)>。
④ Reduce 阶段(归约):
-
Reduce 任务接收 Shuffle 阶段传来的 <k1, list (v1)>,执行用户自定义的 reduce () 函数(如聚合、统计),输出最终键值对 < k2, v2>;
-
若有多个 Reduce 任务,输出结果分别写入 HDFS 的不同文件(最终可通过合并工具合并为一个文件)。
⑤ 输出阶段(Output):
由 OutputFormat(默认 TextOutputFormat)将 Reduce 输出的 <k2, v2> 写入 HDFS,完成整个计算流程。
4. Shuffle 的必要性
🔍 考察重点:Shuffle 在 MapReduce 中的核心作用、无 Shuffle 的问题
📌 核心解答:
Shuffle 是 MapReduce 中连接 Map 和 Reduce 的核心桥梁,其必要性源于 “Map 任务并行执行的分散性” 与 “Reduce 任务聚合需求的集中性” 的矛盾,具体作用如下:
① 实现数据的 “分区分发”:
Map 任务是并行执行的,每个 Map 只处理部分数据,而 Reduce 任务需要对 “相同 key 的全量数据” 进行聚合(如统计每个视频的总观看次数,需收集所有 Map 输出的该视频 key 数据)。Shuffle 通过分区机制,确保同一 key 的所有数据精准分发到同一个 Reduce 任务,为聚合提供数据基础。
② 保证数据有序性,提升计算效率:
Shuffle 过程中会对数据进行排序(Map 端溢写排序、Reduce 端合并排序),有序的数据可减少 Reduce 阶段的计算开销(如无需再对相同 key 的数据重新排序),同时支持后续的分组(Group)操作。
③ 减少数据传输量,优化性能:
Shuffle 的 Combine(Map 端预聚合)和 Merge(Reduce 端合并)操作,可将相同 key 的重复数据提前合并,减少从 Map 端到 Reduce 端的网络传输量,降低集群网络压力,提升整体任务执行效率。
💡 反证:若无 Shuffle,Map 输出的分散数据无法按 key 聚合到 Reduce 任务,Reduce 无法完成全局计算(如无法统计全量的 key 对应的结果),MapReduce 的 “分而治之” 思想无法落地,海量数据的并行聚合计算也就无法实现。
5. 维度建模是怎么建模的,事实表和维度表有什么区别
🔍 考察重点:维度建模流程、事实表与维度表的核心差异、落地逻辑
📌 核心解答:
一、维度建模流程
维度建模是以 “分析需求” 为核心,围绕 “事实” 和 “维度” 构建数据模型的方法,核心流程为 “确定业务过程→识别事实→识别维度→构建模型(星型 / 雪花)→加载数据”:
-
确定业务过程:明确要分析的核心业务场景(如视频观看、订单支付、用户注册);
-
识别事实:提取业务过程中可量化、可统计的核心指标(如观看次数、支付金额、注册人数),形成事实表;
-
识别维度:提取描述事实的上下文信息(如观看时间、视频分类、用户性别),形成维度表;
-
构建模型:根据维度表的规范化程度,选择星型模型或雪花模型;
-
加载数据:将 ODS 层数据清洗转换后,加载到事实表和维度表。
二、事实表和维度表的区别(对比梳理)
6. 星型模型和雪花模型区别
🔍 考察重点:两种维度建模模型的结构差异、优缺点、适用场景
📌 核心解答:
星型模型和雪花模型的核心差异在于 “维度表的规范化程度”,均以事实表为中心,维度表围绕事实表关联,具体区别如下:
💡 示例(视频场景):
-
星型模型:事实表(video_watch_fact)直接关联 user_dim(用户)、video_dim(视频)、time_dim(时间);
-
雪花模型:video_dim 拆分为 video_main_dim(视频基本信息,含 category_id)和 category_dim(分类信息),事实表→video_main_dim→category_dim 关联。
7. 讲一下对维度的理解,如果从视频和观看时间来看,会怎么去区分事实和维度
🔍 考察重点:维度的核心定义、事实与维度的区分逻辑、业务场景落地能力
📌 核心解答:
一、对维度的理解
维度是 “描述事实的上下文信息”,核心作用是为事实数据提供 “筛选、分组、聚合的分析视角”,是维度建模的核心组成部分。
-
本质:回答 “谁、何时、何地、什么、如何” 等分析问题的属性集合(如分析视频观看事实,可通过 “用户维度” 回答 “谁看的”,“时间维度” 回答 “何时看的”);
-
特点:数据相对稳定、可重复复用,粒度可粗可细(如时间维度可分为年、月、日、时);
-
常见类型:时间维度、用户维度、商品 / 内容维度(如视频)、地域维度等。
二、视频和观看时间场景下的事实与维度区分
区分核心原则:
-
事实:可量化、记录业务过程发生的 “行为 / 指标”(是 “动作” 或 “结果”);
-
维度:描述事实的 “属性 / 上下文”(是 “描述信息”,用于分析筛选)。
具体区分(视频观看场景):
-
维度识别:
-
视频维度:属于 “内容维度”,描述视频本身的属性,如视频 ID(video_id)、视频分类(category)、视频时长(duration)、上传者(uploader_id)等;
-
观看时间维度:属于 “时间维度”,描述观看行为发生的时间上下文,如观看日期(watch_date)、观看小时(watch_hour)、是否周末(is_weekend)等;
-
补充维度:用户维度(user_id、gender)、设备维度(device_type)等也属于描述观看事实的维度。
-
事实识别:
-
核心事实:观看行为本身及可量化指标,如是否观看(watch_flag)、观看时长(watch_duration)、是否完播(is_complete)、观看次数(watch_count)等;
-
事实表示例:video_watch_fact(user_id、video_id、watch_date、watch_duration、is_complete),其中 user_id、video_id、watch_date 是维度外键,watch_duration、is_complete 是事实指标。
💡 总结:视频和观看时间的 “属性信息” 是维度,基于视频发生的 “观看动作及量化结果” 是事实。
8. 数据去重的方法;count distinct 和 group by 区别
🔍 考察重点:数据去重的实际落地方法、两种计数方式的核心差异与适用场景
📌 核心解答:
一、数据去重的方法(按场景分类)
-
单字段去重:
-
用 DISTINCT 关键字:适用于简单的单字段去重查询(如 SELECT DISTINCT user_id FROM video_watch_log);
-
用 GROUP BY 分组:通过分组实现单字段去重(如 SELECT user_id FROM video_watch_log GROUP BY user_id),效果与 DISTINCT 一致。
-
多字段去重(按组合维度去重):
-
用 DISTINCT 多字段:SELECT DISTINCT user_id, video_id FROM video_watch_log(去重 “同一用户观看同一视频” 的重复记录);
-
用 GROUP BY 多字段:SELECT user_id, video_id FROM video_watch_log GROUP BY user_id, video_id,与 DISTINCT 多字段效果一致。
-
窗口函数去重(保留其他字段):
当需要去重同时保留其他字段时,用 ROW_NUMBER () 开窗排序去重,如去重同一用户同一视频的重复观看记录,保留最新一条:
sql
WITH ranked_log AS (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY user_id, video_id ORDER BY watch_time DESC) AS rn
FROM video_watch_log
)
SELECT * FROM ranked_log WHERE rn = 1;
-
存储层去重:
-
写入数据时去重:用 INSERT OVERWRITE + DISTINCT/GROUP BY 覆盖写入,避免重复数据累积;
-
用主键约束:如 Hive 中无严格主键,但可通过业务主键(如 user_id+video_id+watch_date)在加工时保证唯一性。
二、count distinct 和 group by 区别