Data Engineer Professional · 30% of the exam

Data Processing: free practice questions

5 sample questions from our 75-question bank for this domain — answers and explanations included. These are the same scenario-based style as the real Databricks exam.

1. A data engineer profiles a Spark job that joins two large DataFrames and observes extreme task skew: most tasks complete in under 5 seconds, but a handful take over 8 minutes. Adaptive Query Execution (AQE) is enabled. Which AQE feature is most directly responsible for addressing this skew, and how does it work?

  • A. Dynamic partition coalescing: AQE merges small shuffle partitions after the shuffle to reduce the number of tasks and eliminate the straggler tasks.
  • B. Skew join optimization: AQE detects skewed partitions at runtime based on partition size statistics, splits the skewed partitions into smaller sub-partitions, and replicates the corresponding partition from the non-skewed side to process them in parallel.✓ Correct
  • C. Broadcast join conversion: AQE converts the skewed side of the join into a broadcast variable, eliminating the shuffle entirely.
  • D. Dynamic predicate pushdown: AQE rewrites the query plan to push filter predicates down to the scan stage, reducing the amount of data shuffled to the join.
Explanation

AQE's skew join optimization specifically targets data skew in shuffle-based joins. It detects which partitions are significantly larger than average, splits those large partitions into smaller chunks, and duplicates the matching partition from the other side so that work can be parallelized — directly solving the straggler task problem. Option A describes dynamic partition coalescing, which merges many small partitions into fewer larger ones — the opposite problem (too many small tasks, not a few huge ones). Option C is incorrect because AQE can convert joins to broadcast joins based on runtime size statistics, but this applies to cases where one side is small enough to broadcast; it does not help when one side has skewed but large partitions. Option D describes predicate pushdown, which is a Catalyst optimizer feature, not an AQE runtime skew optimization.

2. A data engineering team is running a Structured Streaming job that performs stateful aggregations (session windows) on clickstream events. After a cluster failure, the job restarts but begins reprocessing data from scratch, ignoring prior state. What is the MOST LIKELY cause of this behavior?

  • A. The trigger interval was set to `Trigger.Once()`, which does not support stateful operations.
  • B. The streaming query was started without a `checkpointLocation` option, so no state or progress information was persisted.✓ Correct
  • C. The streaming query used `outputMode('complete')`, which always recomputes state from the beginning on restart.
  • D. The Delta Lake source does not support stateful aggregations in Structured Streaming.
Explanation

Exactly-once semantics and state recovery in Structured Streaming depend entirely on a configured checkpoint location (`checkpointLocation`). Without it, there is no WAL (write-ahead log) or state store, so on restart the job has no memory of prior progress or aggregation state and begins from scratch. Option A is wrong: `Trigger.Once()` does support stateful operations and respects checkpoints. Option C is wrong: `complete` output mode does rewrite the full result set each trigger, but this is unrelated to state being lost on restart — checkpointing still preserves state across restarts in complete mode. Option D is wrong: Delta Lake sources are fully supported for stateful Structured Streaming jobs.

3. A data engineer is implementing a Structured Streaming job that performs a stream-stream join between an `orders` stream and a `fulfillments` stream on `order_id`. Both streams are keyed by `order_id` and have event timestamps. The engineer wants to ensure that the join state does not grow unboundedly. Which approach correctly bounds state in a stream-stream join?

  • A. Apply `dropDuplicates("order_id")` on both streams before the join to eliminate redundant keys and limit state growth.
  • B. Apply `withWatermark` on the event-time column of BOTH streams before the join, and specify the join time constraint using a time range condition (e.g., `orders.order_time BETWEEN fulfillments.fulfill_time - INTERVAL 1 HOUR AND fulfillments.fulfill_time`). Spark uses the watermarks and time constraint together to determine when state for unmatched records can be dropped.✓ Correct
  • C. Set `spark.sql.streaming.stateStore.maxKeys = 10000` to cap the number of keys retained in the state store.
  • D. Use `Trigger.ProcessingTime("1 hour")` to flush state every hour automatically, preventing unbounded accumulation.
Explanation

In Structured Streaming stream-stream joins, state grows unboundedly unless Spark knows when it is safe to evict unmatched records from both sides. This requires: (1) `withWatermark` applied to the event-time column on BOTH input streams, AND (2) a time-range join condition (inequality predicate on the time columns) that bounds how far apart matching events can be. Together, these allow Spark to determine that once the watermark has advanced sufficiently, any unmatched record cannot receive a future match and can be dropped from state. Option A is wrong: `dropDuplicates` removes duplicate keys within a single stream but does not bound join state, which accumulates all unmatched records waiting for a partner. Option C is wrong: `spark.sql.streaming.stateStore.maxKeys` is not a valid Spark parameter; there is no built-in key cap for state stores. Option D is wrong: trigger intervals control micro-batch cadence, not state eviction; state accumulates across triggers regardless of the trigger interval.

4. A production Delta Lake table receives continuous CDC updates. The data engineering team wants to retain the ability to time-travel back 60 days but also ensure that the physical data files backing deleted records are eligible for cleanup after 7 days to control storage costs. Which table properties should they configure?

  • A. SET TBLPROPERTIES ('delta.logRetentionDuration' = 'interval 60 days', 'delta.deletedFileRetentionDuration' = 'interval 7 days')✓ Correct
  • B. SET TBLPROPERTIES ('delta.logRetentionDuration' = 'interval 7 days', 'delta.deletedFileRetentionDuration' = 'interval 60 days')
  • C. SET TBLPROPERTIES ('delta.dataRetentionDuration' = 'interval 60 days', 'delta.vacuumRetentionDuration' = 'interval 7 days')
  • D. SET TBLPROPERTIES ('delta.logRetentionDuration' = 'interval 60 days') and separately run VACUUM RETAIN 168 HOURS on a weekly schedule.
Explanation

delta.logRetentionDuration controls how long the Delta transaction log (and therefore time-travel history) is preserved — setting it to 60 days allows queries against snapshots up to 60 days old. delta.deletedFileRetentionDuration controls how long data files that are no longer referenced by the current table version are kept before VACUUM can remove them — setting it to 7 days means VACUUM can clean up stale files older than 7 days. Option B reverses the two properties, which would restrict time travel to only 7 days and retain deleted file data for 60 days — the opposite of the requirement. Option C uses invented property names (delta.dataRetentionDuration and delta.vacuumRetentionDuration) that do not exist in Delta Lake. Option D only sets log retention; without also adjusting deletedFileRetentionDuration, VACUUM defaults to retaining files for 7 days anyway, but it does not give the team explicit, declarative control over both settings together, and manually scheduling VACUUM with RETAIN 168 HOURS overrides the table property per-run rather than storing it persistently.

5. A data engineer migrates a row-level transformation from a standard Python UDF to a Pandas UDF (vectorized UDF) using @pandas_udf. Which statement MOST accurately describes the performance difference and its root cause?

  • A. Pandas UDFs pass data between the JVM and Python in Apache Arrow columnar batches, eliminating per-row serialization overhead and allowing NumPy/Pandas vectorized operations; this typically yields 10–100x better throughput than row-at-a-time Python UDFs.✓ Correct
  • B. Pandas UDFs are always faster than standard Python UDFs because they bypass the Python interpreter entirely and execute the transformation as JVM bytecode.
  • C. Standard Python UDFs run on the JVM using Spark's internal code generation (Tungsten), so they have lower overhead than Pandas UDFs, which still require a Python process.
  • D. Pandas UDFs eliminate the need for serialization because they share the same JVM memory space as the Spark executor, allowing zero-copy data access.
Explanation

The key performance improvement of Pandas UDFs is the use of Apache Arrow for JVM-to-Python data transfer. Arrow's columnar, zero-copy-friendly format allows entire batches of rows to be transferred at once rather than serializing/deserializing each row individually (as standard Python UDFs do via Pickle). Once data is in Python, Pandas and NumPy operations are vectorized, further improving throughput. Option B is wrong because Pandas UDFs do NOT bypass the Python interpreter — they still execute in a Python worker process; the improvement comes from batch transfer and vectorized operations, not JVM compilation. Option C is wrong because standard Python UDFs do NOT run on the JVM — they are deserialized row-by-row into a Python worker process using Pickle serialization, which is exactly what makes them slow. Tungsten/code generation applies to JVM-native operations, not Python UDFs. Option D is wrong because Python UDFs (both standard and Pandas) run in a separate Python worker process, not in the JVM memory space; they do NOT share JVM memory. Arrow reduces serialization cost but still involves inter-process communication.

70 more questions in this domain

Practice the full bank with instant grading, flashcards, and a timed mock exam.

Start practicing free
Data Processing — Free Data Engineer Professional Practice Questions | DataCertPrep — Certification Prep