Fabric Data Engineer Associate · 33% of the exam

Ingest and transform data: free practice questions

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

1. A data engineer is using PySpark in a Microsoft Fabric Notebook to join a large fact table (500 million rows) with a small product dimension table (10,000 rows). During testing, the job runs very slowly, and the Spark UI shows many shuffle operations during the join. Which optimization should the data engineer apply to eliminate the shuffle and improve join performance?

  • A. Replace the default join with a broadcast join by wrapping the smaller DataFrame with broadcast(), allowing each executor to receive a local copy of the dimension table.✓ Correct
  • B. Increase the number of shuffle partitions using spark.conf.set('spark.sql.shuffle.partitions', '800') to distribute the shuffle more evenly.
  • C. Repartition the large fact table to match the number of partitions in the dimension table before performing the join.
  • D. Cache the large fact table using df.cache() before the join to prevent re-reading it from storage.
Explanation

Option A is correct because a broadcast join sends the small dimension table to every executor as an in-memory copy, completely eliminating the shuffle exchange that occurs when Spark tries to co-locate matching rows across partitions. This is the standard PySpark optimization for skewed or slow joins when one side is small enough to fit in memory. Option B is incorrect because increasing shuffle partitions only redistributes the shuffle work across more partitions; it does not eliminate the shuffle itself and may introduce overhead for small datasets. Option C is incorrect because repartitioning the large fact table to match the small table's partition count would reduce parallelism dramatically and still does not remove the shuffle; it would likely make performance worse. Option D is incorrect because caching the large fact table helps if it is reused multiple times, but does not address the root cause — the shuffle during the join itself.

2. A senior data engineer is designing a streaming ingestion solution in Microsoft Fabric. IoT device events arrive via Azure Event Hubs at approximately 50,000 events per second. Requirements are: (1) enrich each event with device metadata from a Lakehouse Delta table, (2) compute 5-minute tumbling window aggregations of average temperature per device, (3) write raw enriched events to a Lakehouse Delta table for historical analysis, and (4) write the windowed aggregates to a KQL Database for real-time dashboards. Which solution design correctly satisfies ALL four requirements?

  • A. Use a Fabric Eventstream to ingest from Event Hubs; route raw events to a Lakehouse table (requirement 3) and to a KQL Database (requirement 4); perform enrichment and windowed aggregation inside the Eventstream using derived stream transformations
  • B. Use a Spark Structured Streaming notebook to ingest from Event Hubs; join the stream with the device metadata Delta table using a static DataFrame join for enrichment (requirement 1); apply a 5-minute tumbling window with withWatermark and groupBy for aggregation (requirement 2); use writeStream with two sinks — one to the Lakehouse Delta table (requirement 3) and one using a KQL sink (requirement 4)✓ Correct
  • C. Use a Fabric pipeline with a Copy Data activity to batch-copy Event Hubs data every 5 minutes into the Lakehouse; join with the device metadata table using a Dataflow Gen2; aggregate in a second pipeline stage; write aggregates to the KQL Database
  • D. Use a KQL Eventstream directly ingesting from Event Hubs into a KQL Database; use KQL update policies to enrich and aggregate the data; write aggregated results back to a Lakehouse using a KQL to Lakehouse export command on a 5-minute schedule
Explanation

A Spark Structured Streaming notebook is the only option that cleanly satisfies all four requirements in a true streaming fashion. Requirement 1 (enrichment with Delta table metadata): Spark supports stream-static joins, where a streaming DataFrame is joined against a static Delta table DataFrame — this is a well-supported pattern. Requirement 2 (5-minute tumbling window aggregations): Structured Streaming's window() + groupBy() + withWatermark() pattern handles exactly this. Requirements 3 and 4 (dual sinks): Structured Streaming supports foreachBatch() or multiple writeStream sinks to write simultaneously to a Lakehouse Delta table and a KQL Database. The Eventstream approach (Option A) has limitations: Eventstream derived stream transformations support basic filtering and projection but do not natively support stream-to-static Delta table joins for enrichment at the required scale; also routing to both Lakehouse and KQL from the same stream would require forking, which adds complexity and the enrichment join is not supported in Eventstream's transformation layer. The pipeline/Copy Data approach (Option C) is fundamentally a batch approach — copying every 5 minutes is not true streaming and introduces up to 5 minutes of latency, violating the spirit of a streaming architecture. The KQL-based approach (Option D) — using KQL update policies and scheduled exports — is a reasonable approximation but KQL update policies are triggered on ingestion, not on true time windows, and exporting back to Lakehouse on a schedule is again batch behavior. KQL update policies also cannot perform stream-static joins against a Lakehouse Delta table.

3. A data engineer is using PySpark in a Microsoft Fabric notebook to process a large transactions DataFrame. They need to remove exact duplicate rows and also handle rows where the TransactionID is NULL, dropping those rows before writing to the Lakehouse. Which PySpark code sequence correctly accomplishes both tasks?

  • A. df.dropDuplicates().filter(df.TransactionID != None)
  • B. df.distinct().dropna(subset=['TransactionID'])
  • C. df.dropDuplicates().dropna(subset=['TransactionID'])✓ Correct
  • D. df.fillna({'TransactionID': 0}).dropDuplicates()
Explanation

df.dropDuplicates() removes exact duplicate rows across all columns, and df.dropna(subset=['TransactionID']) drops any rows where TransactionID is NULL — chaining these two operations correctly satisfies both requirements. df.distinct() also removes duplicate rows (equivalent to dropDuplicates() with no arguments), and dropna(subset=['TransactionID']) handles NULLs correctly, so this option is also technically valid — however, dropDuplicates() is the more explicit and idiomatic PySpark method. df.dropDuplicates() combined with filter(df.TransactionID != None) uses Python's None for NULL comparison, which does not work correctly in PySpark — NULL comparisons require isNotNull() or dropna(); this is a common misconception. df.fillna({'TransactionID': 0}).dropDuplicates() replaces NULLs with 0 rather than dropping those rows, which violates the requirement to drop NULL TransactionID rows and could introduce false data.

4. A data engineer is ingesting clickstream events into a Microsoft Fabric Lakehouse using Spark Structured Streaming. Events can arrive up to 15 minutes late due to network delays. The engineer needs to compute 5-minute windowed aggregations and must handle late-arriving data without indefinitely retaining state. Which Spark Structured Streaming feature should the engineer configure?

  • A. Set `spark.sql.shuffle.partitions` to a low value to reduce state store size.
  • B. Apply a watermark of 15 minutes on the event timestamp column before the windowed aggregation.✓ Correct
  • C. Use `trigger(once=True)` to process all available data in a single micro-batch, which automatically handles late arrivals.
  • D. Enable Delta Lake merge-on-read mode so late records are automatically reconciled in existing window files.
  • E. Configure checkpoint location and set `failOnDataLoss` to false to allow the stream to skip late records.
Explanation

Watermarking in Spark Structured Streaming tells the engine the maximum expected lateness of data. Setting a 15-minute watermark means the engine retains state for each window for 15 minutes beyond the window's end time, allowing late events to be included in the correct window, after which old state is safely dropped. Option A (reducing shuffle partitions) affects parallelism but has no bearing on late-data handling or state management. Option C (`trigger(once=True)`) processes available data in a batch-like fashion but does not handle lateness logic — late records would simply be missed if they arrive after the trigger fires. Option D (Delta merge-on-read) is a storage-level concept unrelated to streaming late-data handling. Option E (checkpoint + failOnDataLoss=false) only prevents stream failure when source offsets are missing; it does not implement any late-data buffering.

5. A data engineer is building a Microsoft Fabric Lakehouse solution using a medallion architecture. During Silver-layer processing in a PySpark notebook, the engineer discovers that roughly 3% of incoming order records have a NULL value in the `customer_id` column, which is a required foreign key to the Customer dimension. The business rule states these records must not be loaded into the Gold layer but must be preserved for investigation. Which approach best satisfies both requirements?

  • A. Drop all rows with NULL `customer_id` during Silver processing using `df.dropna(subset=['customer_id'])` and log the count of dropped rows to a notebook cell output.
  • B. Write records with NULL `customer_id` to a separate quarantine Delta table in the Silver Lakehouse, and write only valid records forward to the Gold layer.✓ Correct
  • C. Replace NULL `customer_id` values with a sentinel value of -1 and load all records into the Gold layer, allowing downstream queries to filter them out.
  • D. Raise a pipeline exception when any NULL `customer_id` is detected, halting the entire load until the source system is corrected.
Explanation

Writing invalid records to a quarantine (or 'reject') Delta table satisfies both requirements: the bad records are preserved for investigation without being propagated to the Gold layer. This is the standard pattern for handling missing required keys in medallion architectures. Option A is wrong because dropping records and only logging a count permanently discards data needed for investigation, violating the preservation requirement. Option C is wrong because loading records with a sentinel key into the Gold layer violates the business rule that these records must not reach that layer, and it pollutes the fact data for downstream consumers. Option D is wrong because halting the entire pipeline on any NULL would block valid records from loading and is operationally impractical for a 3% error rate; isolation and quarantine is preferred over a full stop.

78 more questions in this domain

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

Start practicing free
Ingest and transform data — Free Fabric Data Engineer Associate Practice Questions | DataCertPrep — Certification Prep