Data Engineering

Apache Spark — Interview Cheat Sheet

RDD vs DataFrame, lazy evaluation, shuffle, partitioning, caching, and job optimization.

Interview tip Shuffle is the enemy — explain wide transformations (groupBy, join) vs narrow (map, filter) and how to minimize data movement.

① Spark architecture overview

Spark cluster
Driver (SparkContext / SparkSession)
Cluster Manager (YARN / K8s / standalone)
Executor 1
Executor 2
Executor N
Driver: builds DAG, schedules tasks, tracks stages.

Executors: run tasks, store cached data, shuffle read/write.

Lazy evaluation: transformations build plan; actions (count, collect, write) trigger execution.

② RDD vs DataFrame vs Dataset

APITypingOptimizationStatus
RDDLow-level, opaque objectsManual — you optimizeLegacy — use when need fine control
DataFrameUntyped rows + schema (Spark SQL)Catalyst optimizer + TungstenDefault for ETL
DatasetTyped (Scala/Java)Catalyst + encoderScala/Java — type-safe
Python PySpark uses DataFrame API almost exclusively. Prefer DataFrame over RDD unless you need custom partition-level logic.

③ Transformations — narrow vs wide

TypeExamplesShuffle?
Narrowmap, filter, select, union (same partition count)No — pipelined in same stage
WidegroupByKey, reduceByKey, join, repartition, distinctYes — shuffle exchange
Shuffle exchange
Map side writeShuffle filesReduce side read
groupByKey vs reduceByKey: reduceByKey combines locally before shuffle — almost always prefer reduceByKey over groupByKey + mapValues.

④ Partitioning & parallelism

OperationEffect
repartition(n)Full shuffle — increase/decrease partitions evenly
coalesce(n)Narrow — decrease partitions without full shuffle (if shuffle=false)
partitionBy(col)Hash/range partition on write
spark.default.parallelismDefault partitions for shuffle operations
Rule of thumb: 2–3× cores for partition count; too many tiny partitions → task overhead; too few → skew and memory pressure. Target 128MB–256MB per partition.

⑤ Join strategies

StrategyWhenRisk
Broadcast hash joinSmall table fits in memory (spark.sql.autoBroadcastJoinThreshold)Driver/executor OOM if table too large
Sort-merge joinLarge-large joinExpensive shuffle — both sides sorted
Shuffle hash joinMedium tablesMemory for hash table
CartesianMissing join condition bugExplosion — always avoid accidentally
Fix skew: salting hot keys, AQE skew join (Spark 3), isolate heavy key to separate processing.

⑥ Caching & persistence

LevelStorageUse
MEMORY_ONLYDeserialized JVM objectsFast if fits RAM
MEMORY_AND_DISKSpill to disk on overflowDefault safe choice for iterative
DISK_ONLYDiskToo large for memory
MEMORY_ONLY_SERSerialized bytesLess memory, more CPU deserialize
When to cache: DataFrame reused in multiple downstream branches (ML iterations, graph loops). Unpersist when done. df.cache() = MEMORY_AND_DISK.

⑦ Structured Streaming (brief)

Micro-batch model: treat stream as append table — trigger queries on new data. Checkpoint dir for fault tolerance and exactly-once sinks.

Watermark: handle late-arriving events in windowed aggregations.

Output modes: append, complete, update.
Streaming pipeline
Kafka sourceSpark transformCheckpointDelta / Parquet sink

⑧ Optimization checklist

  • Filter early — push predicates before join
  • Select only needed columns — avoid SELECT *
  • Broadcast small dimension tables explicitly
  • Replace UDFs with Spark SQL built-ins (Catalyst cannot optimize UDFs well)
  • Avoid collect() on large data — use write or take/sample
  • Enable AQE (Adaptive Query Execution) Spark 3+
  • Fix data skew before scaling cluster

⑨ Debugging slow jobs

SymptomLikely causeFix
One task much slowerData skew on keySalt keys, AQE, isolate hot key
Executor OOMToo much data per partition, large broadcastRepartition, increase memory, reduce broadcast size
Many small tasksToo many partitionscoalesce after filter
4+ hour shuffleCartesian or missing filterCheck join condition, filter early
Spill to diskMemory pressureIncrease executor memory or reduce partition size
Use Spark UI: Stages tab → skewed task duration histogram; SQL tab → physical plan (broadcast hint visible).

⑩ Interview Q&A & revision

QuestionAnswer sketch
What triggers shuffle?Wide transformation requiring data redistribution across partitions
Lazy evaluation benefit?Optimize full DAG — predicate pushdown, combine filters
RDD lineage?Graph of transformations — rebuild lost partitions from lineage + checkpoints
Spark vs MapReduce?In-memory iteratives, DAG scheduler, 10–100× faster for iterative ML/ETL
When Spark over pandas?Data does not fit in memory, distributed cluster, production ETL pipelines
  • Explained narrow vs wide transformations
  • Named shuffle cause and mitigation
  • Compared RDD vs DataFrame
  • Described broadcast join use case
  • Listed skew debugging steps
sparkshuffledataframepartitioningoptimization