# 1. RDD(弹性分布式数据集)的五大特性 A 分区器对普通 RDD 也存在,用于所有分区 B 分区列表决定并行度,依赖关系支撑容错与阶段划分,首选位置用于数据本地性调度 ✓ 正确答案 C 依赖关系只用于存储,与调度无关 D RDD 是可变的,可原地修改数据
# 2. Sort-based Shuffle 原理与调优(shuffle partitions/压缩/溢写) A Hash Shuffle 每个 task 只生成一个文件,是 Spark 默认 B Sort-based Shuffle 每个 task 排序后生成一个数据文件加索引,减少文件数,`spark.sql.shuffle.partitions` 控制分区数 ✓ 正确答案 C 分区数越多越好,能消除所有倾斜 D Spark 默认关闭 shuffle 压缩
# 3. Spark 动态资源分配(Dynamic Allocation)的原理与关键参数 A 动态资源分配会固定 Executor 数量不变 B 动态资源分配按任务积压扩容、空闲超时回收 Executor,需配合外部 Shuffle Service 保留 shuffle 数据 ✓ 正确答案 C 启用动态分配无需任何额外配置 D 动态分配只减不增 Executor
# 4. Spark Streaming 与 Structured Streaming 的差异,微批 vs 连续处理、端到端 Exactly-Once 如何实现? A Structured Streaming 只有微批模式,无连续处理 B 连续处理模式支持所有流式操作 C DStream 基于 DataFrame,Structured Streaming 基于 RDD D Structured Streaming 把流视为无限表,支持 watermark 与精确语义,端到端 Exactly-Once 需源可重放+checkpoint+幂等输出三者配合 ✓ 正确答案
# 5. RDD 的血缘(Lineage)与容错机制,为什么窄依赖可以高效重算、宽依赖需要 Checkpoint,与缓存(Cache)的差别如何? A 宽依赖丢失分区只需重算个别父分区 B Cache 与 Checkpoint 都截断血缘 C RDD 不记录血缘,故障全部重算 D Cache 只加速不截断血缘,节点故障仍沿血缘重算;Checkpoint 截断血缘落盘,避免长链重算,宽依赖恢复代价高故需 checkpoint ✓ 正确答案
# 6. 内存管理与 Tungsten 引擎,UnsafeRow 二进制格式与堆外内存管理 A Tungsten 用 UnsafeRow 二进制编码行、支持堆外内存与 codegen,减少 GC 与对象开销,提升 CPU 缓存友好度 ✓ 正确答案 B Tungsten 只能使用堆内存 C UnsafeRow 使用 Java 对象保存行,便于 GC D Tungsten 会增加大量对象头开销
# 7. Catalyst 优化器与 AQE(自适应查询执行),动态合并 shuffle 分区/倾斜处理 A Catalyst 是运行时优化,AQE 是编译期优化 B AQE 无法处理数据倾斜 C AQE 会固定分区数绝不合并 D Catalyst 负责 SQL 逻辑与物理计划优化,AQE 在运行时动态合并 shuffle 分区、切换 join 策略并处理倾斜分区 ✓ 正确答案
# 8. 广播 Join 与 Sort-Merge Join 的取舍,broadcast hint 与阈值(spark.sql.autoBroadcastJoinThreshold) A Broadcast Join 把小表广播到各 executor 本地 join,避免 shuffle,受 `spark.sql.autoBroadcastJoinThreshold` 阈值约束,大表 join 大表用 Sort-Merge ✓ 正确答案 B Sort-Merge Join 适合小表 join 大表,无 shuffle C Broadcast Join 适合大表 join 大表 D 广播 join 会扩大 shuffle 量
# 9. 数据倾斜的定位与治理,salting/skew join hint/两阶段聚合 A 数据倾斜只能通过加内存解决 B 加盐是在倾斜 key 上随机化前缀打散到多分区,两阶段聚合用于 group by 倾斜,skew join hint 用于 join 倾斜 ✓ 正确答案 C 两阶段聚合适用于 join 倾斜 D 加盐会消除所有任务,无需再聚合
# 10. Spark DAG 与 Stage/Task 划分,宽依赖(shuffle)与窄依赖(pipeline)的边界 A 宽依赖一个父分区被多个子分区使用需 shuffle,DAG 在宽依赖处切分 Stage,窄依赖可 pipeline 合并执行 ✓ 正确答案 B 所有依赖都产生 shuffle C 窄依赖在 DAG 调度器处切分 Stage D Stage 内可包含任意宽窄依赖
# 11. Spark Job/Stage/Task 的划分,DAG 调度器如何根据宽窄依赖切分 Stage,Stage 内并行度由谁决定? A 每个 Action 触发一个 Job,DAG 按宽依赖切分 Stage,Stage 内并行度由该 Stage 最后一个 RDD 的分区数决定 ✓ 正确答案 B Stage 内并行度由 Executor 数量决定 C 窄依赖处切分 Stage D 一个 Job 只包含一个 Stage
# 12. Spark 的数据倾斜治理全览,定位(stage 耗时/堆栈)、加盐、两阶段聚合、skew join hint、动态分区重分布如何? A 先通过 stage 耗时/堆栈定位,再按场景选择加盐、两阶段聚合、skew hint 或 AQE 动态分区重分布 ✓ 正确答案 B 只能通过增加 Executor 内存解决 C 数据倾斜无法定位,只能盲目调参 D 加盐与两阶段聚合是同一种方法
# 13. Spark 的调度,DAG→Stage→Task 划分,宽窄依赖与 stage 间 shuffle 如何? A TaskScheduler 负责切分 Stage B 窄依赖处产生 shuffle C 一个 Stage 可跨多次 shuffle D DAGScheduler 把 DAG 按宽依赖切分 Stage,TaskScheduler 把 Task 分发给 Executor,宽依赖处产生 shuffle 作为 Stage 边界 ✓ 正确答案
# 14. RDD 持久化级别(StorageLevel)的选择与 Kryo 序列化配置 A MEMORY_ONLY 永不丢失分区 B Kryo 序列化比 Java 慢很多 C MEMORY_AND_DISK_SER 在内存不足时溢写磁盘且序列化存储,能省内存但增加 CPU 开销;Kryo 序列化比 Java 快且体积小但需注册类 ✓ 正确答案 D StorageLevel 与控制存储介质无关
# 15. Spark SQL 的谓词下推与列裁剪,DataSource V2 的过滤器下推 A 谓词下推只减少输出列,列裁剪只减少输出行 B 谓词下推与列裁剪都会增加 IO C DataSource V2 不支持过滤器下推 D 谓词下推把 where 条件下推到数据源减少读取行,列裁剪只读所需列,DataSource V2 通过 SupportsPushDownFilters 把过滤下推给数据源 ✓ 正确答案
# 16. Spark 与 Flink 的选型,批流一体、状态管理、延迟与吞吐在不同场景下的取舍如何? A Spark 延迟低于 Flink,实时性更强 B Flink 不支持批处理 C Spark 以批处理与微批流见长、延迟秒级,Flink 真流式延迟毫秒级且原生状态管理强,实时低延迟场景选 Flink ✓ 正确答案 D Flink 状态管理弱于 Spark
# 17. Spark 内存模型,执行内存与存储内存的 Unified Memory 管理如何? A 执行内存与存储内存完全隔离,互不借用 B Unified Memory 中执行内存与存储内存动态互借,执行内存可抢占存储内存,spark.memory.fraction 控制 Unified 占堆比例 ✓ 正确答案 C spark.memory.storageFraction 控制执行内存初始占比 D 所有内存都是堆外内存
# 18. Spark 的 checkpoint 与 cache 的区别,血缘关系与容错恢复的差异如何? A 二者都从内存恢复 B Cache 截断血缘,Checkpoint 保留血缘 C Checkpoint 落盘并截断血缘,故障时从可靠存储恢复;Cache 保留血缘只加速,缓存丢失时沿血缘重算 ✓ 正确答案 D Checkpoint 只用于加速,不用于容错
# 19. 广播变量(Broadcast)的实现与内存边界 A 广播变量把数据发送给每个 Task 各一份 B 广播变量适合广播任意大小的数据 C 广播变量把只读数据一次性分发到每个 Executor 供所有 Task 共享,以内存换传输,但广播数据常驻内存、过大易撑爆 Executor ✓ 正确答案 D 广播变量每次使用都重新从 Driver 拉取