PySpark Interview Questions & Answers
Curated Top 20 most frequently asked PySpark Data Engineering interview questions, architecture scenarios, code snippets, and Databricks real-world solutions.
Core fundamental question testing knowledge of Spark abstraction evolution.
Used In: PySpark Architecture Fundamentals
RDD (Low-level) vs DataFrame (Row Struct) vs DataSet (Type-safe Scala/Java)# RDD: No schema, opaque Java objects
rdd = sc.parallelize([('Alice', 30)])
# DataFrame: Named columns, Catalyst optimized
df = spark.createDataFrame([('Alice', 30)], ['name', 'age'])RDD: Unstructured | DataFrame: Structured Schema | DataSet: Type-safeTests understanding of Spark execution model (Transformations vs Actions).
Used In: Query Optimization, DAG Build
Transformations (Lazy) -> Action (Triggers DAG Execution)df1 = spark.read.csv('data.csv') # Lazy (No execution)
df2 = df1.filter(col('age') > 21) # Lazy (No execution)
df3 = df2.select('name') # Lazy (No execution)
df3.count() # ACTION: Triggers DAG build & physical plan execution!Count: 4500Tests understanding of network shuffles and stage boundaries.
Used In: Stage Boundary Analysis, Bottleneck Debugging
Narrow: 1-to-1 partition mapping | Wide: Many-to-Many shuffle mapping# Narrow (No Shuffle): filter, map, select, flatMap, union
df_narrow = df.filter(col('status') == 'ACTIVE')
# Wide (Triggers Network Shuffle): groupBy, join, distinct, repartition, reduceByKey
df_wide = df.groupBy('department').count()Narrow: 0 Shuffles (Fast) | Wide: Network Shuffle Stage BoundaryTests deep understanding of distributed data movement across cluster nodes.
Used In: Shuffle Management, Performance Optimization
Map Side Write -> Disk Spill -> Network Transfer -> Reduce Side Read# Shuffle triggered by Wide transformation:
df.groupBy('country').sum('revenue')Data re-distributed across worker network partitionsExtremely frequent interview question on partition management.
Used In: Output File Consolidation, Partition Resizing
repartition(N) [Full Shuffle] vs coalesce(N) [No Shuffle for Reducing]# Reduce 100 partitions to 10 efficiently without shuffle:
df_coalesced = df.coalesce(10)
# Increase 10 partitions to 50 or rebalance skewed data (Full Shuffle):
df_repartitioned = df.repartition(50)coalesce: Zero Shuffle | repartition: Full Network ShuffleTests knowledge of map-side combining (combiners).
Used In: RDD Aggregation Optimization
reduceByKey (Map-side Combine) vs groupByKey (Full Network Transfer)rdd = sc.parallelize([('a', 1), ('a', 2), ('b', 3)])
# Efficient: Combines locally on mapper node before sending across network
rdd.reduceByKey(lambda x, y: x + y)[('a', 3), ('b', 3)]Tests join optimization techniques for small lookup tables.
Used In: Fact-Dimension Joins, Lookup Tables
from pyspark.sql.functions import broadcast
large_df.join(broadcast(small_df), 'key')orders_df.join(broadcast(country_lookup_df), 'country_code')BroadcastHashJoin executed without shuffling large_dfScenario question asked in 90%+ Senior Data Engineer interviews.
Used In: Straggler Task Mitigation, High-volume ETL
Salting: Add random salt key to spread skewed key across partitions# Add random salt (0-9) to skewed dataframe:
df_salted = df.withColumn('salted_key', concat(col('user_id'), lit('_'), floor(rand() * 10)))Uniform partition distribution without straggler tasksDebugging and production troubleshooting scenario.
Used In: Production Incident Debugging, Cluster Sizing
Driver OOM vs Executor OOM# Driver OOM Fix: Avoid collect(), increase driver RAM:
--driver-memory 8g
# Executor OOM Fix: Increase executor RAM, fix data skew, lower shuffle partitions:
--executor-memory 16g --conf spark.memory.fraction=0.8Stable memory allocation without container evictionTests modern Spark 3.x runtime optimization features.
Used In: Production Spark 3.x Optimization
spark.conf.set('spark.sql.adaptive.enabled', 'true')# AQE automatically applies 3 key runtime optimizations:
# 1. Coalesces small shuffle partitions dynamically
# 2. Converts Sort-Merge Join to Broadcast Join at runtime
# 3. Handles Skew Joins automaticallyDynamic physical plan adaptation at stage boundariesTests Python-to-JVM serialization knowledge and Apache Arrow.
Used In: Custom Python Logic, Vectorized Data Processing
@pandas_udf(DoubleType()) def calc(v: pd.Series) -> pd.Series:import pandas as pd
from pyspark.sql.functions import pandas_udf
@pandas_udf('double')
def vectorized_tax(salary: pd.Series) -> pd.Series:
return salary * 0.2
df.withColumn('tax', vectorized_tax(col('salary')))10x-100x faster execution using Apache Arrow zero-copy memory transferData Lake storage architecture question.
Used In: Lakehouse Maintenance, Parquet Storage Optimization
coalesce(N) | Delta OPTIMIZE / ZORDER# For vanilla Parquet: Coalesce before write
df.coalesce(5).write.parquet('/path')
# For Delta Lake: Run OPTIMIZE and ZORDER
spark.sql('OPTIMIZE delta_table ZORDER BY (date, customer_id)')Compacted 100MB-1GB target filesDeep engine internals question.
Used In: Catalyst Engine Internals
Unresolved Logical Plan -> Analyzed -> Optimized -> Physical Plan -> Code Generation# 4 Catalyst Stages:
# 1. Analysis (Catalog verification of column names/types)
# 2. Logical Optimization (Predicate pushdown, column pruning)
# 3. Physical Planning (Selecting join algorithms: Broadcast vs Sort-Merge)
# 4. Code Generation (WholeStageCodegen compiling Java bytecode)Optimized Java Bytecode Execution PlanMemory storage levels question.
Used In: Multi-action Pipeline Caching
cache() [MEMORY_AND_DISK] vs persist(StorageLevel) [Custom Level]from pyspark import StorageLevel
# cache() uses default MEMORY_AND_DISK in DataFrames:
df.cache()
# persist() allows custom storage levels:
df.persist(StorageLevel.MEMORY_ONLY_SER)DataFrame cached in executor RAM/DiskShared variable primitives in Spark.
Used In: Global Counters, Read-only Dictionary Lookups
Accumulators (Write-only counters) | Broadcast Variables (Read-only lookups)# Broadcast Variable (Read-only on workers):
b_lookup = sc.broadcast({'US': 'United States', 'CA': 'Canada'})
# Accumulator (Write-only aggregate from workers):
err_counter = sc.accumulator(0)Shared cluster variablesSQL/PySpark ranking and analytical query question.
Used In: Top-N per Category, Leaderboards, Running Aggregations
row_number() vs rank() vs dense_rank() OVER (PARTITION BY ... ORDER BY ...)from pyspark.sql.window import Window
from pyspark.sql.functions import row_number, rank, dense_rank
w = Window.partitionBy('dept').orderBy(col('salary').desc())
df.select('salary',
row_number().over(w).alias('rn'), # 1, 2, 3
rank().over(w).alias('rk'), # 1, 1, 3 (skips 2 on tie)
dense_rank().over(w).alias('dr') # 1, 1, 2 (no gap on tie)
)Tied Salaries [100, 100, 90] -> rn:[1,2,3], rk:[1,1,3], dr:[1,1,2]Modern Databricks Lakehouse storage architecture question.
Used In: Lakehouse Data Architecture, Bronze/Silver/Gold Medallion
Delta = Parquet Data Files + JSON Transaction Log (_delta_log/)# Delta Lake Features:
# 1. ACID Transactions (Serializability)
# 2. Time Travel (Query past table versions)
# 3. MERGE INTO (Upserts & Deletes)
# 4. Schema Enforcement & Schema EvolutionACID compliant Lakehouse table formatAdvanced query optimization feature.
Used In: Star Schema Data Warehouse Queries
spark.sql.optimizer.dynamicPartitionPruning.enabled = true# Joining Fact table partitioned by date_id with filtered Date Dim table:
fact_sales.join(dim_date.filter(col('year') == 2024), 'date_id')Skips reading non-matching partition directories at runtimeReal-time streaming window analytics question.
Used In: Real-time Event Streaming, Late Data Handling
df.withWatermark('event_time', '10 minutes')df.withWatermark('event_time', '10 minutes')\
.groupBy(window('event_time', '5 minutes'), 'device_id')\
.count()Late arriving event handling windowCluster submit and deployment mode question.
Used In: Production Job Scheduling, Databricks Jobs
spark-submit --deploy-mode client | cluster# Client Mode: Driver runs on submit machine (Notebooks/IDE)
spark-submit --deploy-mode client script.py
# Cluster Mode: Driver runs inside worker node in cluster (Production)
spark-submit --deploy-mode cluster script.pyClient: Local Driver | Cluster: Distributed Worker Driver