3. 数据工程核心技能栈

本章核心目标:建立“技能点→考察逻辑→回答结构”的快速映射,确保面试时每道题都有清晰的表达框架。

数据工程面试中,SQL、Python、大数据框架(Spark / Flink / Hive)是三大必考技能。面试官不会只考语法,而是关注场景理解、性能调优、异常处理。掌握统一回答框架:拆解需求 → 分步实现 → 说出优化点 → 引用项目指标。

数据工程技能回答框架 SQL 高频:窗口/聚合/分区 考察:逻辑与性能意识 回答:分步+索引+计划 Python 高频:Pandas/内存/倾斜 考察:高效处理与异常 回答:讲场景+写伪代码 大数据框架 高频:Shuffle/分区/调优 考察:原理理解与实战 回答:项目参数+对比 回答框架:拆解需求 → 分步实现 → 说出优化点 → 引用项目指标

三大技能栈面试问答卡片

📌 面试问题:

写一个 SQL 查询,统计每个部门过去 30 天内销售额排名前 3 的员工及销售额。

🎯 面试官考察点

  • 窗口函数(RANK / DENSE_RANK)与分区(PARTITION BY)
  • 日期过滤与时序数据处理
  • SQL 执行计划意识(是否考虑索引/分区剪裁)

🧩 回答框架

  1. 拆需求:部门内、过去30天、Top3 → 窗口函数 + 日期过滤
  2. 写框架:子查询 + RANK() OVER(PARTITION BY 部门 ORDER BY 销售额 DESC)
  3. 加优化:日期列建立索引 / 按月份分区表 / 使用 BETWEEN 避免函数包裹
  4. 提验证:测试边界(当天数据是否包含、平排名如何处理)

💬 简短示例回答(约80字)

SELECT 部门, 员工, 销售额, rnk
FROM (
  SELECT *, RANK() OVER(PARTITION BY 部门 ORDER BY 销售额 DESC) AS rnk
  FROM sales
  WHERE sale_date >= DATEADD(day, -30, GETDATE())
) t WHERE rnk <= 3;

并补充:为 sale_date 建索引,若表按日期分区还需确认是否实现分区剪裁,避免全表扫描。

🔍 可能追问

  • RANK 与 DENSE_RANK 区别?若 Top3 含并列如何处理?
  • 如果数据量 10 亿行,如何优化此查询?
  • 如何用 Hive Spark SQL 改写?窗口函数在分布式中注意事项?
⚠️ 避坑提醒:不要在 SELECT 条件中对日期列使用函数(如 DATE(列)),会导致索引失效;窗口函数 OVER 内部 ORDER BY 方向写错(DESC/ASC)也是常见低级错误。

📌 面试问题:

用 Pandas 处理一个 10GB 的 CSV 文件,如何避免内存溢出并完成分组聚合?

🎯 面试官考察点

  • 大数据场景下 Pandas 的局限性认知
  • 分块读取(chunksize)与类型优化(dtype)
  • 是否了解 Dask / Modin 等替代方案

🧩 回答框架

  1. 评估问题:10GB 远超单机内存 → 不能全量读入
  2. 给出方案:pd.read_csv(chunksize=10000) 迭代处理,每块聚合后合并
  3. 深度优化:指定 dtype(如 int32/float32),解析日期时用 parse_dates 参数
  4. 扩展建议:若多次再处理可用 Dask DataFrame 并行计算

💬 简短示例回答(约90字)

chunk_iter = pd.read_csv('file.csv', chunksize=10000, dtype={'col1':'int32'})
result = []
for chunk in chunk_iter:
    result.append(chunk.groupby('dept')['sales'].sum())
final = pd.concat(result).groupby(level=0).sum()

同时说明:若列范围小,可使用类别类型(category)进一步压缩内存。

🔍 可能追问

  • 如果文件是 GZIP 压缩的,chunksize 如何影响解压?
  • Dask DataFrame 底层如何实现分块?与 Pandas 的兼容性?
  • 如果需要在每个 chunk 内排序后取 TopN,如何实现?
⚠️ 避坑提醒:不要忘记在最终合并时再次 groupby,因为不同 chunk 可能含相同分组键;chunksize 不宜过大(一般 5k~50k),否则内存不降反升。

📌 面试问题:

在 Spark 中遇到数据倾斜(某个 key 数据量特别大),如何定位原因并解决?

🎯 面试官考察点

  • 是否理解 Shuffle 与分区机制
  • 倾斜诊断方法(stage 耗时/数据量对比)
  • 常见解决方案:加盐/广播/调整分区/自定义分区器

🧩 回答框架

  1. 定位:看 Spark UI 中某个 stage 长时间运行、task 数据量差距大
  2. 分析原因:group by / join 时 key 分布不均
  3. 给出解法:① 加随机前缀(salting)打散大 key ② 小表广播(broadcast join)③ 增大 shuffle 分区数
  4. 选最优:若倾斜 key 少且大,优先 salting;若表较小,优先广播

💬 简短示例回答(约90字)

// 加盐示例:对倾斜key拼接随机后缀
df.withColumn("new_key", 
  when(col("key") === "hot_key", concat(col("key"), lit("_"), floor(rand()*10)))
  .otherwise(col("key")))
.groupBy("new_key").agg(...)

同时说明:聚合后再将随机前缀去掉,倾斜 key 被分散到 10 个分区,性能提升明显。

🔍 可能追问

  • salting 后如何还原结果?对后续 join 是否有影响?
  • 如何判断应广播左表还是右表?Spark 3.0 自适应查询如何自动处理?
  • 如果倾斜发生在 reduce 端而非 map 端(如 distinct count),怎么处理?
⚠️ 避坑提醒:不要盲目用 repartition(1000) 解决所有问题,要先分析倾斜 key 的分布;salting 时随机后缀范围(如 10~100)要适中,太小仍走同一个 task,太大则小文件增多。

技能点对比速查表

技能 最高频考点 面试官底层意图 黄金回答结构
SQL 窗口函数、表连接优化、复杂聚合 是否具备性能和逻辑拆解意识 分步拆需求 + 写伪 SQL + 加索引/分区 + 测边界
Python Pandas 内存管理、数据倾斜处理、异常捕获 是否真的处理过 GB 级数据 场景评估 + 分块/类型优化 + 伪代码 + 扩展方案
大数据框架 Shuffle 原理、数据倾斜、调优参数 是否理解分布式框架核心瓶颈 定位(UI)+ 分析原因 + 给出 2-3 种解法 + 选最优
💡 面试官解读:不要只背答案,要展示“思考过程”——比如回答 SQL 时先说“我先确认表结构与索引”,回答 Spark 时先说“我先看 Spark UI 中的 task 数据量分布”。这种过程框架比结果更值分。