面试问题汇总(来源于网络)
🔧 一面(11.18 技术面)
-
Hadoop 了解多少?
-
窗口函数
-
SQL 连续问题(如连续登录、连续成交)
-
SQL 查找最近一年没登录的客户
-
了解 Hive 吗?以及组成架构
-
数据倾斜以及解决方法
-
行转列、列转行
-
字符串连接函数
-
数据仓库分层以及 ODS 层数据来源;全量表、增量表、拉链表
-
事实表分类以及具体应用场景
-
对 AI Agent、大模型这方面了解多少?
💼 二面(11.24 HR面)
-
自我优点、缺点,以及与团队相匹配的能力
-
最有成就感的事
-
北京、上海怎么选择?
-
哪里人?
-
目前研究生在学什么?
-
课题组在干嘛?
⚙️ 三面(11.27 深度技术面)
-
Hadoop 读写流程(HDFS 读写流程)
-
数据倾斜了解嘛?怎么解决(进阶版,结合 Hive/Spark)
-
Hive 了解嘛?具体有哪些优化参数
-
Shuffle 原理流程;Shuffle 阶段有哪些优化
问题详细解答
🔧 一面(11.18 技术面)
❓ Hadoop了解多少?
回答:Hadoop 是 Apache 开源的分布式计算与存储框架,核心解决海量数据的“存”与“算”问题,基于“分而治之”思想,具备高可靠、高扩展、高容错、低成本特点,核心组件包括 HDFS(分布式文件系统)和 MapReduce(分布式计算模型),生态还延伸出 YARN(资源调度)、HBase(分布式数据库)等组件。
-
核心组件 1:HDFS 👉 主从架构,NameNode(主节点)管理元数据(文件路径、存储位置等),DataNode(从节点)存储实际数据块(默认 128MB),SecondaryNameNode 辅助 NameNode 备份元数据,避免单点故障。适合存储大文件(GB/TB 级),不适合小文件和随机读写。
-
核心组件 2:MapReduce 👉 分“Map 阶段”和“Reduce 阶段”的计算模型:Map 负责数据分片处理(如过滤、提取关键字),输出键值对;Shuffle 阶段负责将相同 Key 的键值对聚合分发到同一 Reduce;Reduce 负责汇总计算(如统计、求和)。
-
核心组件 3:YARN 👉 资源调度平台,ResourceManager(主)负责全局资源分配,NodeManager(从)负责单节点资源管理,通过 ApplicationMaster 为 MapReduce、Spark 等计算框架分配 CPU/ 内存资源。
-
核心思想 👉 移动计算比移动数据更高效(将计算任务分发到数据存储节点)、容错性(DataNode 数据多副本,默认 3 份;任务失败自动重试)。
❓ 窗口函数
回答:窗口函数(Window Function)是 SQL 中用于“分组后在组内进行排序、聚合或行级计算”的函数,核心特点是不压缩结果集(与 GROUP BY 分组后合并行不同),能保留每行数据的原始信息,语法为「函数名 ()OVER (PARTITION BY 分组列 ORDER BY 排序列 [ROWS/RANGE 窗口范围])」。
-
分类及常用函数: 排序窗口函数:ROW_NUMBER()(组内唯一序号,无并列)、RANK()(并列跳号,如 1,2,2,4)、DENSE_RANK()(并列不跳号,如 1,2,2,3),常用于 TopN、排名场景。
-
聚合窗口函数:SUM()、AVG()、COUNT()、MAX(),将聚合结果关联到每一行,如“计算每个用户的订单金额及累计总额”。
-
行偏移窗口函数:LAG(列名, n)(取组内前 n 行数据)、LEAD(列名, n)(取组内后 n 行数据),用于计算连续变化(如环比增长)。
-
其他:NTILE(n)(将组内数据分为 n 组,返回组号)、PERCENT_RANK()(计算排名百分比)。
-
应用示例:“查询每个商品的订单记录,并显示该商品的订单金额排名”
SELECT 商品ID, 订单ID, 金额, ROW_NUMBER() OVER (PARTITION BY 商品ID ORDER BY 金额 DESC) AS 商品金额排名 FROM 订单表;
❓ SQL连续问题(如连续登录、连续成交)
回答:SQL 连续问题的核心思路是「通过“行号差固定”或“日期差固定”标记连续区间」,再对区间分组统计,以下以“查询连续登录 3 天及以上的用户”为例说明常用方法:
-
方法 1:行号(ROW_NUMBER)差值法(推荐,适用于无缺失日期)对用户按登录日期排序,生成组内行号;
-
计算“登录日期 - 行号”,连续日期的结果会相同(形成连续区间标识);
-
按用户和区间标识分组,统计每组天数,筛选≥3 的用户。
-
方法 2:铅锤函数(LAG)日期差法(适用于需验证相邻日期)通过 LAG 取上一次登录日期,计算与当前日期的差值,若差值 =1 则连续,再用累计求和标记连续区间,最终统计区间长度。
-
延伸场景:连续成交、连续打卡等问题,仅需将“登录日期”替换为对应业务日期(如成交日期),逻辑完全复用。
❓ SQL查找最近一年没登录的客户
回答:核心是「筛选“最后登录日期≤当前日期 -1 年”或“无登录记录”的客户」,需结合客户主表和登录表,处理“从未登录”的边缘场景:
-- 方法:左连接关联登录表,筛选无登录记录或最后登录时间超1年的客户
SELECT c.客户ID, c.客户名称
FROM 客户主表 c
LEFT JOIN (
-- 取每个客户的最后登录日期(去重同一天多次登录)
SELECT 客户ID, MAX(登录日期) AS 最后登录日期
FROM 登录表
GROUP BY 客户ID
) l ON c.客户ID = l.客户ID
-- 条件:1. 从未登录(最后登录日期为NULL);2. 最后登录≤1年前
WHERE l.最后登录日期 IS NULL
OR l.最后登录日期 ≤ DATE_SUB(CURDATE(), INTERVAL 1 YEAR);
-- 补充:若仅用登录表,无法获取“从未登录”的客户,必须关联客户主表
❓ 了解Hive吗?以及组成架构
回答:Hive 是基于 Hadoop 的数据仓库工具,核心是将 SQL 转换为 MapReduce/Spark 任务执行,实现对海量数据的结构化分析,而非数据库(不支持实时写入和事务,早期)。
核心组成架构(自上而下):
-
用户接口层:提供 SQL 交互入口,包括 CLI(命令行)、JDBC/ODBC(程序调用)、Web UI(Hue 等可视化工具)。
-
驱动层(Driver):SQL 解析执行的核心,分 4 步: 解析器(Parser):将 SQL 解析为抽象语法树(AST),检查语法错误;
-
分析器(Analyzer):结合元数据校验表、字段存在性,生成逻辑执行计划;
-
优化器(Optimizer):优化逻辑计划(如列裁剪、分区过滤、Join 顺序调整);
-
执行器(Executor):将优化后的计划转换为 MapReduce/Spark 任务,提交给 YARN 执行。
-
元数据存储(Metastore):存储 Hive 的结构化信息,如数据库、表名、字段类型、分区信息、数据存储路径(HDFS 地址),默认用 Derby,生产常用 MySQL(支持多用户共享)。
-
计算引擎层:Hive 依赖的计算框架,早期默认 MapReduce,现在主流 Spark(Hive on Spark),也支持 Tez,提升计算效率。
-
存储层:默认存储在 HDFS,也支持 S3 等分布式存储,数据以文件形式存在(如 ORC、Parquet、TextFile)。
核心特点:支持结构化 / 半结构化数据、支持分区和分桶、SQL 友好、适合离线批处理,不适合实时查询(毫秒 / 秒级响应)。
❓ 数据倾斜以及解决方法
回答:数据倾斜是分布式计算中“某几个任务节点数据量远超其他节点”导致的问题,表现为任务执行时间过长、部分节点 OOM,核心原因是「Key 分布不均」(如某类数据占比 90%),常见于 Shuffle 阶段(如 Join、Group By)。
1. 常见场景及根因:
-
Group By 倾斜:某类 Key 的数量极多(如统计“未知用户”的行为);
-
Join 倾斜:大表与小表 Join 时,小表无数据分布,或大表中某 Key 集中(如用户表与订单表 Join,某网红用户订单占比极高);
-
Count(Distinct) 倾斜:某值重复极多,导致聚合压力集中。
2. 通用解决方法:
-
业务层面优化(优先): 过滤无效数据:提前过滤“未知用户”“测试数据”等倾斜 Key;
-
拆分倾斜 Key:将高频 Key 单独处理(如将“未知用户”拆分为多个虚拟 Key 计算,再合并结果)。
-
SQL 层面优化: Group By 倾斜:用「分桶 + 随机前缀」打散 Key,或开启 Hive 的负载均衡参数(hive.groupby.skewindata=true,自动拆分倾斜 Key 为两个 Job);
-
Join 倾斜: - 小表广播:用 MAPJOIN 将小表加载到内存(Hive 自动优化,或显式指定 /*+ MAPJOIN(小表) */),避免 Shuffle; - 大表倾斜 Key 拆分:将倾斜 Key 的大表数据与小表单独 Join,非倾斜部分正常 Join,最后 Union;
-
Count(Distinct) 倾斜:用「先 Group By 去重,再 Count」替代,或拆分倾斜 Key 单独计算。
-
参数层面优化: Hive:hive.skewjoin.key=100000(设置 Key 数量阈值,超过则触发倾斜优化);
-
MapReduce:增大 Reduce 任务数(mapreduce.job.reduces),缩小单个 Reduce 处理的数据量;
-
Spark:调整 shuffle 分区数(spark.sql.shuffle.partitions,默认 200,可增至 1000+)。
❓ 行转列、列转行
回答:行转列与列转行是 SQL 中数据格式转换的常用操作,Hive 和 MySQL 均支持,核心依赖聚合函数 +CASE WHEN 或专用函数。
1. 行转列(多行合并为一行,多列):将同一维度的多行数据,按 Key 合并为一行多列(如“将学生的多门成绩从多行转为一行多列”)
-- 原始数据(学生成绩表)
-- 学生ID | 科目 | 成绩
-- 101 | 语文 | 90
-- 101 | 数学 | 85
-- 102 | 语文 | 95
-- 行转列SQL(Hive/MySQL通用)
SELECT
学生ID,
MAX(CASE WHEN 科目='语文' THEN 成绩 END) AS 语文成绩,
MAX(CASE WHEN 科目='数学' THEN 成绩 END) AS 数学成绩,
MAX(CASE WHEN 科目='英语' THEN 成绩 END) AS 英语成绩
FROM 学生成绩表
GROUP BY 学生ID;
-- Hive专用函数:concat_ws + collect_list(合并为字符串,非多列)
SELECT 学生ID, concat_ws(',', collect_list(科目||':'||成绩)) AS 成绩汇总
FROM 学生成绩表
GROUP BY 学生ID;
2. 列转行(一行多列拆分为多行):将同一行的多列数据,按 Key 拆分为多行(如“将学生的多门成绩从一行拆为多行”)
-- 原始数据(学生成绩宽表)
-- 学生ID | 语文成绩 | 数学成绩 | 英语成绩
-- 101 | 90 | 85 | 88
-- 列转行SQL(Hive用LATERAL VIEW,MySQL用UNION ALL)
-- Hive版本
SELECT 学生ID, 科目, 成绩
FROM 学生成绩宽表
LATERAL VIEW explode(
array(
named_struct('科目','语文','成绩',语文成绩),
named_struct('科目','数学','成绩',数学成绩),
named_struct('科目','英语','成绩',英语成绩)
)
) t AS 成绩信息
LATERAL VIEW json_tuple(to_json(成绩信息), '科目', '成绩') t2 AS 科目, 成绩;
-- MySQL版本(简单直接,适合列数少的场景)
SELECT 学生ID, '语文' AS 科目, 语文成绩 AS 成绩 FROM 学生成绩宽表
UNION ALL
SELECT 学生ID, '数学' AS 科目, 数学成绩 AS 成绩 FROM 学生成绩宽表
UNION ALL
SELECT 学生ID, '英语' AS 科目, 英语成绩 AS 成绩 FROM 学生成绩宽表;
❓ 字符串连接函数
回答:不同 SQL 引擎的字符串连接函数略有差异,核心用于将多个字符串或字段拼接为一个字符串,常见场景:数据汇总、字段组合(如姓名 + 手机号脱敏)。
实战示例:Hive 中“将用户 ID、用户名、注册日期用‘|’连接,忽略 NULL 字段”
SELECT concat_ws('|', 用户ID, 用户名, 注册日期) AS 用户信息
FROM 用户表;
❓ 数据仓库分层以及ODS层数据来源;全量表、增量表、拉链表
回答:数据仓库分层是为了“解耦数据、提升复用性、简化维护”,采用“自下而上”的分层架构,行业通用分层为“ODS → DWD → DWS → ADS”,部分会增加 DIM(维度表)层。
1. 数据仓库核心分层:
-
ODS 层(操作数据存储层): 定位:数据仓库的“入口”,存储原始业务数据,不做清洗或轻量清洗(如去重、格式标准化),保持数据与业务系统一致;
-
数据来源:业务数据库(MySQL/Oracle)、日志数据(用户行为日志)、第三方接口数据(支付数据)、离线文件(Excel/CSV);
-
核心作用:保留原始数据,支持数据回溯和重新计算。
-
DWD 层(数据明细层): 定位:对 ODS 层数据进行“清洗、脱敏、维度关联”,生成结构化的明细数据;
-
操作:处理空值、异常值,关联用户维度、商品维度等,如将“用户 ID”替换为“用户名 + 所属城市”;
-
核心作用:为上层提供干净、可用的明细数据。
-
DWS 层(数据服务层 / 汇总层): 定位:按“业务主题”(如用户、商品、订单)对 DWD 层数据进行聚合,生成汇总数据;
-
示例:用户主题表(近 7 天登录次数、累计订单数)、商品主题表(近 30 天销量、好评率);
-
核心作用:减少上层重复计算,提升查询效率。
-
ADS 层(应用数据层): 定位:面向具体业务需求(如报表、dashboard、数据分析),是数据仓库的“出口”;
-
示例:月度销售报表、用户增长漏斗数据;
-
核心作用:直接支撑业务决策和应用系统。
2. 数据存储类型(全量表、增量表、拉链表):
❓ 事实表分类以及具体应用场景
回答:事实表是数据仓库中“存储业务度量值”的核心表(如订单金额、销量、点击量),与维度表(如用户、商品、时间)关联使用,按业务粒度和用途分为 4 类:
-
事务事实表(Transaction Fact Table)特点:记录“单次业务事件”,粒度最细,一条记录对应一个事务(如一笔订单、一次点击),无更新,仅追加;
-
应用场景:需要追溯具体业务事件的分析,如“查询 2024 年 11 月的每笔订单详情”“统计每小时的用户点击次数”;
-
示例:订单事务表(订单 ID、用户 ID、商品 ID、下单时间、金额)、点击日志事实表(用户 ID、页面 ID、点击时间、停留时长)。
-
周期快照事实表(Periodic Snapshot Fact Table)特点:按“固定周期”(如每日、每周)记录业务状态的快照,粒度是“周期 + 实体”,记录累计度量值;
-
应用场景:分析业务状态的变化趋势,如“查询每个商品的每日库存快照”“统计用户的每周账户余额”;
-
示例:商品库存快照表(商品 ID、快照日期、当日库存、当日入库量、当日出库量)。
-
累积快照事实表(Accumulating Snapshot Fact Table)特点:记录“业务流程中多个关键节点的时间和度量”,数据会随流程推进而更新(如订单从下单到支付、发货、签收的全流程);
-
应用场景:分析业务流程的流转效率,如“统计订单从下单到签收的平均时长”“分析支付环节的转化率”;
-
示例:订单流程快照表(订单 ID、下单时间、支付时间、发货时间、签收时间、金额、物流费用)。
-
无事实事实表(Factless Fact Table)特点:无明确的度量值,仅记录“事件的发生关联”(如用户登录、会议参与);
-
应用场景:分析事件的参与情况或关联关系,如“统计每月的活跃用户数”“查询参与某场培训的员工名单”;
-
示例:用户登录事实表(用户 ID、登录日期、登录设备)、培训参与事实表(员工 ID、培训 ID、参与日期)。
❓ 对AI Agent、大模型这方面了解多少
回答:AI Agent(人工智能智能体)是“具备自主感知、决策、执行能力的 AI 系统”,核心是通过大模型作为“大脑”,结合工具调用、记忆机制,实现端到端的复杂任务处理,是大模型落地的重要形态。
-
核心组成: 大模型(核心驱动):如 GPT-4、文心一言,负责理解需求、生成逻辑、调用工具;
-
记忆模块:分为短期记忆(当前任务上下文)和长期记忆(历史交互、领域知识),支持任务连续性;
-
工具调用能力:通过 API 调用外部工具(如数据库查询、Excel 处理、API 接口),延伸大模型的能力边界;
-
规划与反思机制:能拆分复杂任务(如“生成销售报表”拆分为“取数→计算→可视化”),并对执行结果反思优化。
-
与数据开发的结合场景: 智能 SQL 生成:通过自然语言(如“统计北京地区近 30 天的订单量”)自动生成 SQL,降低非技术人员的使用门槛;
-
数据运维自动化:监控数据任务运行状态,自动排查失败原因(如 SQL 语法错误、数据倾斜),并给出修复建议;
-
智能数据分析:自动完成“取数→清洗→建模→可视化”全流程,如自动生成月度经营分析报告;
-
元数据管理:自动识别表结构、字段含义,生成数据字典,支持模糊查询(如“找包含用户手机号的表”)。
当前挑战:逻辑复杂任务的规划能力不足、工具调用的准确性待提升、数据安全与隐私保护(如避免敏感数据泄露)。
💼 二面(11.24 HR面)
❓ 自我优点、缺点,以及与团队相匹配的能力
回答思路:优点紧扣“数据开发岗位需求”(如细心、抗压、技术扎实),缺点“真实不致命”(避免说“粗心”“不喜欢沟通”),匹配能力突出“团队协作 + 问题解决”。
【优点】
1. 技术扎实且严谨:研究生期间主攻数据仓库方向,熟练掌握Hive、Spark、SQL等核心技术,参与过课题组的电商数据中台项目,负责DWD层数据清洗,通过编写自动化脚本将数据异常率从5%降至0.1%,养成了“写代码前先梳理逻辑、上线前反复测试”的习惯。
2. 抗压能力强:项目上线前曾连续1周跟进数据任务,面对“数据倾斜导致任务延迟”的问题,通过拆分倾斜Key、调整Shuffle参数快速解决,确保了项目按时交付。
3. 主动沟通:在团队中会主动同步任务进度,遇到技术难点时,会先查资料梳理思路,再带着问题请教师兄/导师,避免无效沟通。
【缺点】
经验偏向技术落地,对业务理解的深度有待提升:之前的项目更多聚焦“数据处理本身”,对数据背后的业务逻辑(如电商的促销规则对订单数据的影响)思考较少,目前通过关注京东零售的业务动态、阅读行业报告补充这部分认知。
【与团队匹配的能力】
1. 快速落地能力:数据开发需要“技术+效率”,我能快速将业务需求转化为技术方案,比如之前将“用户画像生成”需求拆解为“数据抽取→特征计算→标签输出”三步,3天内完成核心代码开发。
2. 团队协作意识:理解数据开发是“流水线作业”,会严格遵守团队的代码规范和数据命名规则,确保自己的输出能被下游同事高效复用,之前项目中曾优化过团队的SQL模板,提升了整体开发效率。
❓ 最有成就感的事
回答思路:用 STAR 法则(情境 S- 任务 T- 行动 A- 结果 R),突出“个人贡献 + 能力体现 + 价值产出”,优先选与技术相关的经历。
最有成就感的是研究生期间主导的“校园二手书交易平台数据中台”项目。
【情境】平台积累了10万+用户的交易数据,但数据分散在MySQL、日志文件中,运营团队需要手动汇总数据,生成一份月度报告要花2天时间,且容易出错。
【任务】我负责设计数据中台的核心分层(ODS→DWD→DWS),实现数据自动同步、清洗和汇总,支撑运营报表的自动化生成。
【行动】
1. 需求梳理:和运营团队确认核心指标(如各品类销量、用户复购率),设计数据模型;
2. 技术落地:用Sqoop同步MySQL数据,Flume采集日志,Hive实现数据清洗,编写Shell脚本调度任务,确保每日凌晨自动执行;
3. 问题解决:遇到“二手书分类混乱导致数据倾斜”,通过人工标注+正则匹配优化分类规则,将倾斜任务的执行时间从2小时缩短至20分钟。
【结果】
1. 运营报表生成时间从2天缩短至10分钟,且数据准确率达99.9%;
2. 基于中台数据,运营团队发现“考研类书籍复购率低”,推出“旧书回收+新书租赁”活动,带动平台月活提升30%;
3. 项目被评为课题组年度优秀项目,我的技术方案被师兄们借鉴到其他校园项目中。
❓ 北京、上海怎么选择?
回答思路:结合“个人规划 + 京东业务布局 + 城市特点”,体现“以工作为核心”的态度,避免绝对化表述。
我的选择核心基于“工作内容和个人发展”,两个城市对我来说都很有吸引力:
1. 从工作角度:我了解到京东的零售、物流等核心业务在北京和上海都有重要布局,无论哪个城市的岗位,只要能让我深入参与数据开发的核心项目(如数据仓库优化、数据倾斜解决方案落地),我都非常愿意接受。
2. 个人适配:我是XX人(结合自身情况),对北方的生活环境更熟悉,若选择北京,能更快融入;但上海的互联网产业氛围也很吸引我,若公司需要,我也能快速适应上海的生活节奏。
3. 最终服从公司安排:我更看重京东的平台和团队,相信公司会根据业务需求和我的能力进行最优分配,我完全服从。
❓ 其他问题:哪里人?目前研究生在学什么?课题组在干嘛?
回答思路:简洁真实,突出“与岗位相关的学习 / 科研经历”,避免无关信息。
1. 哪里人:我是XX省XX市人,性格比较开朗,适应新环境的能力还不错。
2. 研究生学习:目前研二,主修课程有《分布式计算》《数据仓库与数据挖掘》《机器学习》,核心聚焦“海量数据处理技术”,GPA3.8/4.0,专业排名前10%。
3. 课题组情况:我们课题组主要和企业合作做“数据智能”相关项目,比如和本地的电商公司合作开发用户画像系统,我的核心工作是负责底层数据的抽取、清洗和建模,用Hive和Spark处理每日百万级的交易数据,输出结构化的用户特征表,支撑上层的推荐算法模型。
⚙️ 三面(11.27 深度技术面)
❓ Hadoop读写流程(HDFS读写流程)
回答:HDFS 的读写流程基于“主从架构”(NameNode 管理元数据,DataNode 存储数据),核心保障“数据可靠性”和“读写效率”。
1. HDFS 读流程(客户端读取文件):
-
客户端通过 DistributedFileSystem 向 NameNode 发送“读文件请求”,指定文件路径;
-
NameNode 查询元数据,返回文件的“数据块列表”(包含每个块的存储 DataNode 节点、块大小等信息),优先返回客户端所在节点或距离近的 DataNode(机架感知);
-
客户端直接与 DataNode 建立连接,按数据块顺序读取数据(无需 NameNode 参与,减少主节点压力);
-
客户端将读取的多个数据块合并为完整文件,关闭连接。
2. HDFS 写流程(客户端写入文件):
-
客户端通过 DistributedFileSystem 向 NameNode 发送“写文件请求”,指定文件路径和大小;
-
NameNode 校验权限和路径合法性,若通过,返回“可写入的 DataNode 节点列表”(按副本策略分配,如 3 副本分配到不同机架的 DataNode);
-
客户端与第一个 DataNode(主副本节点)建立数据传输通道,并同步连接其他副本节点,形成“数据传输 pipeline”;
-
客户端将文件拆分为数据块(默认 128MB),按数据包形式写入主副本节点,主副本节点同步到第二个副本节点,第二个再同步到第三个,形成链式复制;
-
所有副本节点写入完成后,向客户端返回“写入成功”,客户端向 NameNode 发送“文件写入完成”请求;
-
NameNode 更新元数据(记录文件与数据块的关联、副本位置),写流程结束。
❓ 数据倾斜了解嘛?怎么解决(进阶版,结合Hive/Spark)
回答:在三面中,需结合具体计算引擎(Hive/Spark)的底层机制回答,突出“针对性优化”,核心思路与一面一致,但需补充引擎特有方案:
1. Hive 数据倾斜解决(基于 MapReduce/Spark 引擎):
-
Group By 倾斜: 开启负载均衡参数:
set hive.groupby.skewindata=true;,原理是将 Group By 拆分为两个 Job:第一个 Job 随机分发 Key,打散倾斜 Key;第二个 Job 按真实 Key 聚合,避免单点压力; -
随机前缀法:对倾斜 Key 添加随机前缀(如“未知用户”→“未知用户 _1”“未知用户 _2”),打散后分组聚合,再去掉前缀二次聚合。
Join 倾斜: MAPJOIN 强制小表广播:select /*+ MAPJOIN(小表) */ 大表.*, 小表.* from 大表 join 小表 on 大表.key=小表.key;,将小表加载到 Map 端内存,避免 Shuffle;
倾斜 Key 单独处理:将大表拆分为“倾斜 Key 数据”和“非倾斜 Key 数据”,倾斜部分与小表单独 Join,非倾斜部分正常 Join,最后 Union 结果。
2. Spark 数据倾斜解决(基于 Spark SQL/CORE):
-
调整 Shuffle 参数: 增大 Shuffle 分区数:
spark.sql.shuffle.partitions=1000(默认 200),缩小单个分区数据量; -
开启 Shuffle 压缩:
spark.shuffle.compress=true,减少数据传输量。
代码层面优化: 广播变量(Broadcast):对应 Hive 的 MAPJOIN,将小表转为广播变量,val 小表广播 = spark.sparkContext.broadcast(小表DF.collectAsMap()),在 Map 端关联;
随机前缀 + 扩容小表:对大表倾斜 Key 加随机前缀,小表 Key 扩容为“原 Key_1”到“原 Key_N”,Join 后去掉前缀,适合大表倾斜 Key 集中的场景。
❓ Hive了解嘛?具体有哪些优化参数
回答:Hive 优化核心围绕“减少数据量、提升并行度、避免 Shuffle”,常用优化参数按场景分类如下:
-
数据过滤优化:
set hive.exec.dynamic.partition.mode=nonstrict;:开启动态分区(加载数据时自动按字段分区); -
set hive.optimize.principal=ON;:开启谓词下推,将过滤条件下推到 Map 端执行,提前过滤数据(如 where 条件在 Join 前执行); -
set hive.optimize.skewjoin.compiletime=true;:编译时识别倾斜 Key,提前优化。 -
并行度优化:
set hive.exec.parallel=true;:开启任务并行执行(如多个独立的子查询可并行); -
set hive.exec.parallel.thread.number=8;:设置并行任务数(默认 8); -
set mapreduce.job.reduces=100;:设置 Reduce 任务数(根据数据量调整,避免太少导致倾斜,太多导致资源浪费)。 -
存储与压缩优化:
set hive.default.fileformat=orc;:默认存储格式设为 ORC(列存格式,压缩比高、查询快),替代 TextFile; -
set hive.exec.compress.intermediate=true;:开启 Map 端中间结果压缩; -
set hive.exec.compress.output=true;:开启 Reduce 端输出压缩。 -
Join 优化:
set hive.auto.convert.join=true;:自动将小表转为 MAPJOIN(默认开启,小表阈值由 hive.mapjoin.smalltable.filesize 控制,默认 25MB); -
set hive.skewjoin.key=100000;:当 Key 的数量超过阈值时,触发倾斜 Join 优化。
❓ Shuffle原理流程;Shuffle阶段有哪些优化
回答:Shuffle 是分布式计算中“将 Map 端输出按 Key 分发到对应 Reduce 端”的核心阶段,是数据倾斜和性能瓶颈的高发区,以 MapReduce 和 Spark 为例说明:
1. Shuffle 原理流程:
-
MapReduce Shuffle 流程: Map 端:Map 任务输出键值对→写入环形缓冲区(默认 100MB,80% 时溢出)→按 Partition(分区)排序→溢写到磁盘形成小文件→合并小文件(Merge)为大文件,按 Key 排序;
-
Reduce 端:通过 HTTP 拉取所有 Map 端的对应 Partition 数据→合并(Merge)所有拉取的文件→按 Key 排序→分组(相同 Key 的 Value 聚在一起)→送入 Reduce 函数计算。
-
Spark Shuffle 流程(以 SortShuffle 为例): Map 端(Shuffle Write):Task 输出键值对→按 Partition 和 Key 排序→写入本地磁盘文件(含索引)→生成 MapStatus(记录文件位置和大小);
-
Reduce 端(Shuffle Read):Driver 获取所有 MapStatus→为每个 Reduce Task 分配拉取范围→Reduce Task 拉取数据→合并排序→分组计算。