HireHireInterview Quizzes › Data Engineer

Data Engineer Interview Questions

Think you're ready? These are the questions that actually decide Data Engineer interviews. Warm up on Easy — then face the Hard round, where 95% of candidates crumble. 79 questions across 3 levels, instant score, completely free.

79Questions
3Difficulty levels
95%Fail the hard round
FreeInstant score
Easy
Warm-up · 20 Qs
Medium
Practical · 29 Qs
Hard
Brutal · 30 Qs
⚡ Take the Data Engineer quiz — get your score →

The Data Engineer interview questions

Below are the real questions, grouped by difficulty. Expand any one to reveal the correct answer and why — or take the timed quiz for a score you can share. Can you clear the Hard round?

Easy round 20 questions

You run `SELECT dept, COUNT(*) FROM emp GROUP BY dept HAVING COUNT(*) > 5`. Why is HAVING used here instead of WHERE?
  • A. WHERE cannot filter on aggregate results like COUNT(*) ✓
  • B. HAVING runs faster than WHERE on grouped data
  • C. HAVING filters individual rows after they are sorted by GROUP BY
  • D. HAVING is required whenever GROUP BY is present
Correct answer: A. WHERE filters rows before grouping, so it cannot reference aggregates; HAVING filters after aggregation.
A LEFT JOIN between orders (100 rows) and a customers table returns 100 rows, but some customer columns are NULL. What does this indicate?
  • A. Those orders have no matching customer row ✓
  • B. The join key is duplicated in customers
  • C. The customers table is empty
  • D. An INNER JOIN would return more rows
Correct answer: A. A LEFT JOIN keeps all left rows and fills unmatched right-side columns with NULL, so NULLs mean no matching customer.
Given the values (10, NULL, 20, NULL, 30) in a column, what does AVG(col) return?
  • A. 20 ✓
  • B. 12
  • C. 60
  • D. NULL
Correct answer: A. AVG ignores NULLs, averaging only 10, 20, 30 = 60/3 = 20.
You need to remove exact duplicate rows from a query result. Which is the simplest correct approach?
  • A. Add DISTINCT to the SELECT ✓
  • B. Add a HAVING clause
  • C. Use ORDER BY
  • D. Add a GROUP BY on the primary key
Correct answer: A. SELECT DISTINCT collapses identical result rows into one.
A batch pipeline reprocesses yesterday's data and you want re-runs to be safe. Which design makes the load idempotent?
  • A. Delete the target partition then insert, so re-runs produce the same result ✓
  • B. Always append new rows on every run
  • C. Disable primary keys on the target table
  • D. Use SELECT INTO a new table each run
Correct answer: A. Delete-then-insert (overwrite) for a partition means re-running yields identical output with no duplicates.
Your Spark job on a 500GB dataset spends most time in one task while others finish quickly. What is the most likely cause?
  • A. Data skew concentrating rows on one partition key ✓
  • B. Garbage-collection pauses on the driver node
  • C. Using DataFrames instead of RDDs
  • D. The cluster has too many executors
Correct answer: A. A single slow task usually signals skew, where one key holds a disproportionate share of the data.
You are storing analytical data queried mostly by selecting a few columns over billions of rows. Which format fits best?
  • A. Columnar format like Parquet ✓
  • B. Plain CSV
  • C. Row-based JSON lines
  • D. Fixed-width text
Correct answer: A. Columnar formats like Parquet only read the needed columns and compress well, ideal for analytics.
A dimension table records a customer's city and you must keep full history when it changes. Which SCD type do you use?
  • A. Type 2 with new rows and effective dates ✓
  • B. Type 1 overwrite
  • C. No SCD, just delete old rows
  • D. Type 0 keep original only
Correct answer: A. SCD Type 2 inserts a new version row with validity dates, preserving history.
In a star schema, where do numeric measures like sales_amount typically live?
  • A. In the fact table ✓
  • B. In every dimension table
  • C. In a separate lookup table only
  • D. In the bridge table
Correct answer: A. Facts hold the additive measures; dimensions hold descriptive attributes.
Your daily Airflow DAG must not run today's task until yesterday's succeeded. Which mechanism enforces this?
  • A. Setting depends_on_past=True ✓
  • B. Increasing the task retries
  • C. Using a shorter schedule_interval
  • D. Adding more worker slots
Correct answer: A. depends_on_past makes a task instance wait for the previous run's same task to succeed.
A Kafka consumer group has 4 consumers but the topic has only 2 partitions. What happens?
  • A. 2 consumers stay idle since a partition maps to one consumer per group ✓
  • B. All 4 consumers read every message
  • C. The topic auto-creates 2 more partitions
  • D. Consumption fails with an error
Correct answer: A. Within a group each partition is assigned to one consumer, so extra consumers beyond partition count sit idle.
You add a WHERE filter on a huge table's user_id but the query still does a full table scan. What most likely helps?
  • A. Creating an index on user_id ✓
  • B. Rewriting the filter to use an OR condition
  • C. Increasing the database's shared buffer cache
  • D. Casting user_id to text
Correct answer: A. An index on the filtered column lets the engine seek rows instead of scanning the whole table.
In ETL vs ELT, what is the practical difference when loading into a modern cloud warehouse?
  • A. ELT loads raw data first and transforms inside the warehouse ✓
  • B. ELT never transforms data
  • C. ETL always runs faster than ELT
  • D. ELT cannot handle structured data
Correct answer: A. ELT lands raw data then leverages the warehouse's compute to transform, unlike ETL which transforms before loading.
You partition a warehouse table by event_date and queries filter on that date. What benefit do you get?
  • A. Partition pruning scans only relevant date partitions ✓
  • B. Automatic deduplication of rows
  • C. Guaranteed uniqueness of keys
  • D. Faster INSERTs regardless of query
Correct answer: A. Filtering on the partition column lets the engine skip irrelevant partitions, reducing scanned data.
A window function `ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY ts DESC)` is used with a filter rn = 1. What does this produce?
  • A. The latest row per user ✓
  • B. The oldest row per user
  • C. A running total per user
  • D. All rows sorted by user
Correct answer: A. Ranking by ts descending and keeping row 1 gives each user's most recent record.
You must join a huge fact table with a tiny 2MB lookup table in Spark. Which optimization avoids a costly shuffle?
  • A. A broadcast join of the small table ✓
  • B. A sort-merge join
  • C. Repartitioning both tables by key
  • D. Caching the huge table
Correct answer: A. Broadcasting the small table to every executor avoids shuffling the large one.
A downstream report shows inflated revenue after a pipeline change. You suspect the join grain. What is the classic cause?
  • A. A one-to-many join duplicated fact rows ✓
  • B. Using LEFT instead of INNER JOIN
  • C. Filtering with WHERE after the aggregation runs
  • D. Summing a measure that was already totaled upstream
Correct answer: A. Joining a fact to a dimension that has multiple matches per key fans out rows and double-counts measures.
You expose data with a schema that may add fields over time. Which choice best supports backward-compatible schema evolution?
  • A. Avro with a schema registry ✓
  • B. A fixed CSV with positional columns
  • C. Pickled Python objects
  • D. Hardcoded column order in code
Correct answer: A. Avro plus a schema registry manages compatible additions of fields across producer/consumer versions.
Your incremental load pulls only new records using a `last_updated` watermark. What risk must you guard against?
  • A. Records updated at the exact boundary time being missed or double-read ✓
  • B. The last_updated column must be the table's primary key
  • C. Watermark loads always force a full table scan
  • D. Reading only new rows corrupts the target table's indexes
Correct answer: A. Boundary/late-arriving rows at the watermark can be skipped or reprocessed without careful inclusive/exclusive handling.
A table has 1 billion rows and you need an approximate count of distinct users fast. Which is appropriate?
  • A. APPROX_COUNT_DISTINCT (HyperLogLog) ✓
  • B. COUNT(*)
  • C. SELECT DISTINCT then COUNT in app code
  • D. ORDER BY user_id then count changes
Correct answer: A. Approximate distinct-count functions use HyperLogLog to estimate cardinality far cheaper than exact COUNT(DISTINCT).

Medium round 29 questions

You need to keep only the most recent row per (user_id, event_date) group, ordered by event_timestamp. Which SQL approach is the standard way to do this?
  • A. SELECT DISTINCT user_id, event_date FROM events
  • B. Use ROW_NUMBER() OVER (PARTITION BY user_id, event_date ORDER BY event_timestamp DESC) and keep rows where it equals 1 ✓
  • C. GROUP BY user_id, event_date HAVING COUNT(*) > 1
  • D. A self-join on user_id filtered by WHERE rownum = 1
Correct answer: B. ROW_NUMBER() partitioned by the group and ordered by timestamp descending lets you keep exactly the latest row per group by filtering to rank 1.
In a typical ELT pipeline loading into a cloud data warehouse like Snowflake or BigQuery, how does it primarily differ from a traditional ETL pipeline?
  • A. ELT transforms data in a staging engine before it reaches the warehouse
  • B. ELT loads raw data into the warehouse first and performs transformations inside the warehouse afterward ✓
  • C. ELT cannot handle incremental loads
  • D. ELT always requires less storage than ETL
Correct answer: B. ELT loads raw data into the warehouse and leverages its compute to transform afterward, whereas ETL transforms data before loading it.
You store large analytical datasets in a data lake and typically query a few columns with aggregations. Which file format is generally the best choice?
  • A. CSV
  • B. Parquet ✓
  • C. Line-delimited JSON
  • D. XML
Correct answer: B. Parquet is a columnar format offering good compression and column pruning, ideal for reading a few columns from large analytical datasets.
A nightly batch job re-processes the entire source table and is getting slow as data grows. The source has a reliable updated_at column. What is the most appropriate improvement?
  • A. Add executor memory so the full reload finishes in time
  • B. Implement incremental loading, processing only rows where updated_at is newer than the last successful run ✓
  • C. Create an index on every column of the source table
  • D. Drop and recreate the target table each night
Correct answer: B. Incremental loading using a high-water mark on updated_at processes only changed rows, avoiding costly full reloads as data grows.
In Apache Airflow, what does setting a task's `retries` and `retry_delay` accomplish?
  • A. It runs the task multiple times in parallel to speed it up
  • B. It automatically re-runs a failed task the specified number of times, waiting retry_delay between attempts ✓
  • C. It schedules the DAG to run more frequently
  • D. It caches the task output so it never re-runs
Correct answer: B. retries and retry_delay make Airflow automatically re-attempt a failed task up to the retry count, pausing retry_delay between attempts.
You are designing a star schema for sales analytics. Which of the following best describes a fact table?
  • A. It stores descriptive attributes like customer name and product category
  • B. It stores measurable business events (e.g., sales amount, quantity) plus foreign keys to dimensions ✓
  • C. It stores only slowly changing metadata about the schema
  • D. It is always denormalized to a single flat table with no keys
Correct answer: B. A fact table holds numeric measures of business events along with foreign keys referencing the surrounding dimension tables.
A dimension table must track history so that when a customer's city changes, past facts still reflect the old city. Which technique handles this?
  • A. SCD Type 1 (overwrite the old value)
  • B. SCD Type 2 (add a new row with effective/expiry dates) ✓
  • C. Truncate and reload the dimension nightly
  • D. Store the city only in the fact table
Correct answer: B. Slowly Changing Dimension Type 2 inserts a new versioned row with validity dates, preserving historical values for past facts.
Your Spark job reads a large dataset and one stage is very slow with a few tasks taking far longer than the rest. What is the most likely cause?
  • A. The shuffle partition count exceeds the number of executors
  • B. Data skew, where some partition keys have far more records than others ✓
  • C. Using Parquet instead of ORC
  • D. The DataFrame API instead of RDDs
Correct answer: B. Uneven distribution of keys (data skew) makes a few partitions much larger, so their tasks lag behind the rest of the stage.
In a partitioned table on a data lake (e.g., partitioned by event_date), what is the main benefit when a query filters on the partition column?
  • A. It automatically deduplicates all rows
  • B. Partition pruning lets the engine skip reading files for irrelevant dates, scanning far less data ✓
  • C. It converts the table to columnar storage automatically
  • D. It guarantees exactly-once processing
Correct answer: B. Filtering on the partition column enables partition pruning, so the engine reads only the relevant partitions and scans much less data.
You want to load data from a REST API that paginates results and enforces a rate limit. Which approach is most robust in your ingestion script?
  • A. Fire all page requests concurrently as fast as possible
  • B. Loop through pages sequentially, handle the next-page token, and back off/retry on 429 responses ✓
  • C. Request only the first page and assume it is complete
  • D. Disable error handling so the job fails fast on any hiccup
Correct answer: B. Iterating pages with the pagination token and backing off on HTTP 429 respects rate limits while retrieving the complete dataset reliably.
You must load only new/changed records daily from a source table with an updated_at column. Which pattern fits best?
  • A. Full table reload each run
  • B. Incremental load using a high-water-mark on updated_at ✓
  • C. Random sampling of rows
  • D. Dropping and recreating indexes only
Correct answer: B. Tracking a high-water-mark (max updated_at) lets you pull only rows changed since the last run.
In a Type 2 Slowly Changing Dimension, how is a changed attribute handled?
  • A. Overwrite the existing row in place
  • B. Insert a new row version and mark the old one inactive/expired ✓
  • C. Delete the row and skip history
  • D. Store the change only in the fact table
Correct answer: B. SCD Type 2 preserves history by adding a new versioned row and closing out the previous one.
A Spark job suffers from severe data skew on a join key. Which technique helps most?
  • A. Increasing the number of output files
  • B. Salting the skewed key to distribute it across partitions ✓
  • C. Switching from Parquet to CSV
  • D. Disabling shuffle entirely
Correct answer: B. Key salting spreads a hot key across multiple partitions, balancing the shuffle load.
In Kafka, what guarantees message ordering?
  • A. Ordering is guaranteed across the whole topic
  • B. Ordering is guaranteed only within a single partition ✓
  • C. Ordering depends on consumer group size
  • D. Ordering is guaranteed only with compaction enabled
Correct answer: B. Kafka preserves order within a partition, not across partitions of a topic.
Which approach best avoids the 'small files problem' in a data lake?
  • A. Writing one file per record
  • B. Compacting many small files into larger files periodically ✓
  • C. Using JSON instead of Parquet
  • D. Disabling partitioning entirely
Correct answer: B. Compaction merges many tiny files into fewer large ones, reducing metadata and read overhead.
What is the main benefit of partitioning a large table on a date column in a warehouse like BigQuery?
  • A. It encrypts the data automatically
  • B. It enables partition pruning so queries scan less data ✓
  • C. It removes the need for any indexes
  • D. It guarantees exactly-once loads
Correct answer: B. Partition pruning lets the engine skip irrelevant partitions, cutting scanned bytes and cost.
In a window function, what does ROW_NUMBER() OVER (PARTITION BY user ORDER BY ts DESC) produce?
  • A. A running total per user
  • B. A rank restarting at 1 per user, ordered by ts descending ✓
  • C. The count of rows per user
  • D. A random ordering within each user
Correct answer: B. ROW_NUMBER assigns sequential numbers starting at 1 within each partition per the ORDER BY.
You need exactly-once processing in a streaming pipeline. Which combination supports it?
  • A. At-most-once delivery with no offsets
  • B. Idempotent writes plus transactional/atomic offset commits ✓
  • C. Fire-and-forget producers
  • D. Auto-commit offsets before processing
Correct answer: B. Exactly-once requires coupling idempotent/transactional sinks with offset commits so records aren't double-applied.
Which normalization issue does a denormalized wide table intentionally trade away for query speed?
  • A. Referential integrity via foreign keys
  • B. Data redundancy and update anomalies ✓
  • C. Column-level compression
  • D. Primary key uniqueness
Correct answer: B. Denormalization accepts redundancy (and update anomalies) to reduce joins and speed reads.
In dbt, what does an incremental model with a unique_key do on subsequent runs?
  • A. Rebuilds the whole table every run
  • B. Merges/upserts only new or changed rows matched on the unique_key ✓
  • C. Deletes the target table
  • D. Runs only in development environments
Correct answer: B. An incremental dbt model appends and, using unique_key, upserts changed rows rather than full rebuilds.
You need to implement a Slowly Changing Dimension that preserves full history of attribute changes. Which SCD type should you use?
  • A. SCD Type 0
  • B. SCD Type 1
  • C. SCD Type 2 ✓
  • D. SCD Type 4 with only current values
Correct answer: C. SCD Type 2 adds a new row for each change with effective/end dates, preserving complete history.
In Apache Spark, what typically triggers a shuffle operation?
  • A. A map() transformation
  • B. A filter() transformation
  • C. A groupByKey() or join across partitions ✓
  • D. Reading a file from disk
Correct answer: C. Wide transformations like groupByKey and joins require redistributing data across partitions, causing a shuffle.
A pipeline must guarantee that reprocessing the same input never creates duplicate output records. What property must the pipeline have?
  • A. Idempotency ✓
  • B. Eventual consistency
  • C. Backpressure
  • D. Serializability
Correct answer: A. Idempotency ensures that applying the same operation multiple times yields the same result without duplicates.
In Kafka, a consumer group has 4 consumers and the topic has 3 partitions. What happens?
  • A. All 4 consumers read all partitions
  • B. 3 consumers each get one partition and 1 consumer stays idle ✓
  • C. The topic is automatically repartitioned to 4
  • D. Consumption fails with an error
Correct answer: B. Each partition is assigned to at most one consumer in a group, so with 3 partitions one of the 4 consumers is idle.
You have a query with a WHERE clause on a high-cardinality column that returns few rows from a huge table. Which index type is generally most appropriate?
  • A. Bitmap index
  • B. B-tree index ✓
  • C. No index at all
  • D. Hash index for range scans
Correct answer: B. B-tree indexes are ideal for high-cardinality columns and selective equality or range lookups.
In Apache Airflow, what does setting a DAG's schedule_interval to '@daily' combined with catchup=True cause when you deploy it with a start_date one month in the past?
  • A. It runs only once for today
  • B. It backfills a run for each missed daily interval since start_date ✓
  • C. It never runs until manually triggered
  • D. It runs continuously every second
Correct answer: B. With catchup=True, Airflow schedules a run for every missed interval between start_date and now.
In a dimensional model, a factless fact table is typically used to record what?
  • A. Only monetary transactions
  • B. Events or coverage relationships that have no numeric measure ✓
  • C. Aggregated summary metrics
  • D. Dimension hierarchies
Correct answer: B. A factless fact table captures the occurrence of events or relationships (e.g., student attendance) without numeric measures.
You must join a very large fact table with a small lookup table in Spark efficiently. Which optimization helps most?
  • A. Broadcast hash join of the small table ✓
  • B. Sort-merge join of both tables
  • C. Cartesian product
  • D. Repartitioning the large table by a random key
Correct answer: A. Broadcasting the small table to all executors avoids shuffling the large table, making the join far more efficient.
What guarantee does Kafka provide about message ordering?
  • A. Global ordering across all partitions
  • B. Ordering only within a single partition ✓
  • C. No ordering guarantees at all
  • D. Ordering across all topics in a cluster
Correct answer: B. Kafka guarantees ordering only within an individual partition, not across partitions or topics.

Hard round 30 questions

A Spark job joining a 2 TB fact table to a small dimension runs for hours, and the Spark UI shows one task in the final stage processing 400x more shuffle data than the median task while 199 tasks finished quickly. AQE is enabled. The join key `customer_id` has a null/`'UNKNOWN'` value for ~30% of fact rows. Which fix directly addresses the root cause?
  • A. Increase `spark.sql.shuffle.partitions` from 200 to 2000 so the hot key spreads across more partitions
  • B. Split the join: filter out the null/`'UNKNOWN'` keys, broadcast-join the remainder, and union the skewed rows handled separately (or salt the hot key) ✓
  • C. Enable `spark.sql.adaptive.coalescePartitions.enabled` so AQE merges the small partitions
  • D. Cache the dimension table with `.persist(MEMORY_AND_DISK)` before the join
Correct answer: B. All rows sharing the single hot key hash to one partition regardless of partition count, so only isolating/salting that key (or broadcasting) redistributes its load.
You maintain an SCD Type 2 dimension. The source system updates records in place and reuses the same natural key, and there is NO reliable `updated_at` timestamp. You must detect real changes and close/open versions correctly. Which approach is most robust?
  • A. Compare the full row to the current version using a hash of all tracked attributes; if the hash differs, close the current row (set end_date) and insert a new current version ✓
  • B. Trust the source's `updated_at` column and only process rows where it is greater than the last load watermark
  • C. Truncate the dimension each run and reload it fully from the source's current state
  • D. Use `SELECT DISTINCT` on the natural key to remove duplicates before loading
Correct answer: A. With no trustworthy timestamp, a hash-based comparison of tracked attributes against the current version is the standard way to detect genuine changes and drive SCD2 version transitions.
A Kafka consumer group processes payments with `enable.auto.commit=true` and default `auto.commit.interval.ms=5000`. The application reads a batch, writes to a database, and occasionally crashes mid-batch. On restart you observe some payments were processed twice. What is the correct cause and fix?
  • A. Auto-commit can commit offsets for records that were fetched but not yet fully processed; disable auto-commit and commit offsets manually only after the DB write succeeds (ideally in the same transaction / idempotent write) ✓
  • B. The consumer has too few partitions; add partitions so each record is processed once
  • C. Set `isolation.level=read_committed` on the consumer to prevent duplicate processing
  • D. Increase `max.poll.interval.ms` so the consumer is not kicked out of the group during processing
Correct answer: A. Auto-commit advances offsets on a timer regardless of processing completion, so a crash after commit but before the DB write replays; manual commit after the sink write (plus idempotency) fixes it.
In a Flink event-time pipeline computing 1-minute tumbling windows of clickstream data, you set a bounded-out-of-orderness watermark of 10 seconds. Events routinely arrive up to 3 minutes late due to mobile clients going offline. What is the observable consequence of this configuration?
  • A. Windows will never fire because the watermark can never advance past late events
  • B. Late events beyond the 10-second bound are dropped (or diverted to side output), so window aggregates for those minutes are silently undercounted ✓
  • C. The watermark forces all late events into the current processing-time window, corrupting later windows
  • D. Flink automatically extends the watermark to 3 minutes once it detects the late events
Correct answer: B. A watermark defines when a window is considered complete and fired; events later than the 10s bound arrive after their window closed and are dropped unless captured via allowed lateness or a side output.
A nightly backfill job re-runs the last 30 partitions of a Delta table and appends rows with `INSERT INTO`. Operators frequently retry failed runs. You are seeing duplicated rows for reprocessed dates. Which change makes the job idempotent for safe reruns?
  • A. Add `OPTIMIZE` and `VACUUM` after each write to compact and remove duplicates
  • B. Switch the write to a `MERGE INTO ... WHEN MATCHED THEN UPDATE WHEN NOT MATCHED THEN INSERT` keyed on the business+partition key, or replace-by-partition with `replaceWhere` ✓
  • C. Wrap the `INSERT INTO` in a `try/except` so failed runs do not append
  • D. Enable Delta's automatic schema evolution with `mergeSchema=true`
Correct answer: B. An append is inherently non-idempotent on retry; a keyed MERGE or a partition-scoped overwrite (`replaceWhere`) makes reprocessing produce the same final state regardless of how many times it runs.
A real-time fraud system must return a decision in under 100ms at ~5,000 events/sec with strict correctness on account balances. A teammate proposes exactly-once end-to-end via a two-phase-commit sink to the downstream API. Under the latency SLA, which reasoning is soundest?
  • A. Exactly-once via 2PC is always required for money, so accept the latency cost of the transactional coordinator
  • B. Use at-least-once delivery with an idempotent sink (dedup by event_id/request key), since 2PC's coordination adds latency and the idempotent sink prevents duplicate effects ✓
  • C. Use at-most-once to guarantee sub-100ms, accepting that some fraud events are dropped
  • D. Exactly-once and at-least-once are identical in throughput, so pick based on team familiarity
Correct answer: B. Distributed transactional commit adds coordination latency that threatens the SLA; at-least-once plus an idempotent (dedup-keyed) sink achieves effectively-once results without the 2PC cost.
You register Avro schemas in a Schema Registry set to BACKWARD compatibility. A producer team wants to add a new field `loyalty_tier` to an event that existing consumers must keep reading without redeployment. What must they do for the change to be accepted and safe?
  • A. Add `loyalty_tier` as a required field with no default; BACKWARD compatibility allows adding required fields
  • B. Add `loyalty_tier` with a default value so consumers using the new schema can read old data lacking the field ✓
  • C. Rename the event's existing `tier` field to `loyalty_tier`; renames are backward compatible
  • D. Remove an unused optional field in the same change to offset the addition
Correct answer: B. Under BACKWARD compatibility a new-schema reader must read data written with the old schema, which requires the added field to have a default so missing values resolve.
A dbt model deduplicates a CDC stream keyed on `order_id`, keeping the latest state per key. The current SQL is `SELECT DISTINCT * FROM raw_orders`. Analysts report both stale and current versions of some orders appear. What is the correct fix?
  • A. `SELECT DISTINCT ON (order_id) * FROM raw_orders ORDER BY order_id` in standard ANSI SQL
  • B. Use `ROW_NUMBER() OVER (PARTITION BY order_id ORDER BY event_ts DESC, op_seq DESC)` and keep rows where the rank = 1 ✓
  • C. Add `GROUP BY order_id` and select the remaining columns without aggregation
  • D. Replace `SELECT DISTINCT *` with `SELECT DISTINCT order_id`
Correct answer: B. `DISTINCT *` only removes fully identical rows, so different versions of the same order survive; windowing by key ordered by event time/sequence and keeping rank 1 selects the true latest state.
A daily pipeline technically succeeds every run (no errors, no failed tasks), but a downstream revenue dashboard shows a 40% drop for one region. Investigation reveals an upstream API silently started returning `null` for `amount` on ~40% of that region's rows. Which control would have caught this BEFORE the dashboard did?
  • A. A retry policy with exponential backoff on the extraction task
  • B. A data-quality assertion on null-rate / distribution of `amount` per region that fails or alerts when it deviates from the historical baseline ✓
  • C. Increasing the Airflow task timeout so the job has more time to complete
  • D. A schema check that the `amount` column still exists and is numeric
Correct answer: B. The job succeeded and the schema was unchanged, so only a value-level quality check (null-rate/volume anomaly vs. baseline) detects a silent correctness failure of this kind.
An Airflow DAG has a task `load_gold` that reads yesterday's silver partition. It is configured with `retries=3` and `depends_on_past=False`, and the sensor waiting on the silver partition uses `poke` mode with a 6-hour timeout. During a Spark cluster outage, dozens of DAG runs pile up and worker slots are exhausted. What is the primary design flaw?
  • A. `depends_on_past=False` caused the runs to execute out of order
  • B. `retries=3` is too low for a production pipeline and should be increased
  • C. The `poke`-mode sensor holds a worker slot for up to 6 hours while idle-waiting, causing slot starvation; use `reschedule` mode (or a deferrable sensor) ✓
  • D. The DAG needs `catchup=False` to prevent it from scheduling multiple runs
Correct answer: C. A poke-mode sensor occupies a worker slot the entire time it waits, so long timeouts across many runs exhaust the pool; reschedule/deferrable sensors free the slot between checks.
In Spark, why can a broadcast join outperform a sort-merge join?
  • A. It always uses less total memory
  • B. It avoids shuffling the large table by sending the small table to every executor ✓
  • C. It requires both tables to be bucketed
  • D. It disables serialization overhead
Correct answer: B. Broadcasting the small table to all executors lets each partition join locally, eliminating the large-table shuffle.
A CDC pipeline using log-based capture must handle a source row deleted then re-inserted with the same PK. What ensures correct final state downstream?
  • A. Applying events by arrival time only
  • B. Ordering and applying events by the source log sequence/LSN ✓
  • C. Ignoring delete events entirely
  • D. Deduplicating solely on primary key
Correct answer: B. Applying changes in source log-sequence (LSN/SCN) order guarantees the final state reflects the true event order.
In a lakehouse table format like Delta/Iceberg, how is a consistent snapshot read achieved during concurrent writes?
  • A. Locking the entire table for readers
  • B. Reading an immutable manifest/version so readers see a fixed snapshot ✓
  • C. Disabling writes while any read runs
  • D. Reading directly from the write-ahead log
Correct answer: B. These formats use versioned metadata/manifests, so a reader pins a snapshot and is isolated from in-flight commits.
Your Airflow DAG backfills 2 years daily but downstream API rate-limits you. Which is the most correct control?
  • A. Increase parallelism to finish faster
  • B. Set max_active_runs and task pool/concurrency limits ✓
  • C. Remove retries to reduce calls
  • D. Switch the schedule to @once
Correct answer: B. Limiting max_active_runs plus pools caps concurrent task execution to respect the downstream rate limit.
When is the 'exactly-once' claim of a system actually 'effectively-once' at the sink?
  • A. When the sink is non-idempotent and retries occur
  • B. When end-to-end idempotency/dedup makes duplicate deliveries harmless ✓
  • C. When offsets are never committed
  • D. When the producer disables acknowledgments
Correct answer: B. Most systems achieve effectively-once by making the sink idempotent/deduplicating, so redelivered records don't change state.
In a columnar format, predicate pushdown with min/max statistics primarily reduces cost by:
  • A. Skipping row groups whose value range can't match the filter ✓
  • B. Caching row groups in memory for reuse across queries
  • C. Compressing string columns better
  • D. Forcing a full table scan for accuracy
Correct answer: A. Per-row-group min/max stats let the reader skip groups that cannot satisfy the predicate, cutting I/O.
A star-schema fact table joins to a Type-2 dimension. To get the attribute value 'as of' the event, you should join on:
  • A. The dimension's current surrogate key only
  • B. The surrogate key captured at load time (point-in-time key) ✓
  • C. The natural/business key alone
  • D. The most recent dimension row by max effective date
Correct answer: B. Storing the SCD2 surrogate key valid at event time gives correct point-in-time attributes rather than current values.
You see duplicate rows after a Kafka-to-warehouse pipeline restart despite at-least-once semantics. The cleanest fix is:
  • A. Lower the consumer's session timeout
  • B. Use an idempotent upsert keyed on a stable event id ✓
  • C. Increase the number of partitions
  • D. Enable auto-commit before processing
Correct answer: B. Upserting on a stable unique event id makes reprocessed messages idempotent, eliminating duplicates.
For a slowly growing dimension queried heavily by BI, why might bucketing/clustering on the join key beat plain partitioning?
  • A. It removes the need for statistics
  • B. It co-locates matching keys to reduce shuffle/scan on joins without exploding partition counts ✓
  • C. It guarantees ACID transactions
  • D. It compresses better than any codec
Correct answer: B. Clustering/bucketing groups equal keys together, improving join and filter locality without high-cardinality partition sprawl.
In a distributed shuffle, which factor most directly drives spill-to-disk and OOM in a wide aggregation?
  • A. Number of output columns
  • B. High-cardinality group keys exceeding executor memory for the hash map ✓
  • C. Using Parquet as input
  • D. The presence of a LIMIT clause
Correct answer: B. Very high-cardinality grouping inflates the in-memory aggregation state, forcing spills and risking out-of-memory.
In a lakehouse table format like Apache Iceberg or Delta Lake, how is snapshot isolation for concurrent writers typically achieved?
  • A. By locking the entire table for every write
  • B. Via optimistic concurrency control with atomic metadata/manifest commits ✓
  • C. By serializing all writers through a single node
  • D. By disabling concurrent writes entirely
Correct answer: B. These formats use optimistic concurrency: writers prepare files then atomically swap metadata, retrying on conflict.
A Spark job suffers severe data skew where one key holds 80% of records, causing one task to run far longer than others. Which technique specifically addresses this?
  • A. Increasing spark.sql.shuffle.partitions only
  • B. Salting the skewed key to distribute it across multiple reducers ✓
  • C. Switching to a broadcast join for the large-large join
  • D. Caching the input RDD
Correct answer: B. Salting adds a random prefix to the hot key so its records spread across multiple partitions/tasks, balancing load.
In exactly-once stream processing with Kafka, what mechanism prevents duplicate side effects when a producer retries after an ambiguous failure?
  • A. Consumer auto-commit
  • B. Idempotent producer with a producer ID and sequence numbers plus transactional writes ✓
  • C. Increasing replication factor
  • D. Larger batch sizes
Correct answer: B. The idempotent producer deduplicates via PID+sequence numbers, and transactions make read-process-write atomic for exactly-once.
You must design a merge (upsert) into a partitioned Delta table where only a few partitions change per batch. What optimization minimizes rewritten data?
  • A. Rewriting the entire table each merge
  • B. Partition pruning in the merge predicate so only affected partitions are touched ✓
  • C. Disabling the transaction log
  • D. Converting the table to CSV before merging
Correct answer: B. Including partition columns in the merge condition lets the engine prune and rewrite only the affected partitions.
In an event-time streaming pipeline, what is the primary role of a watermark?
  • A. To encrypt event payloads
  • B. To bound how long the system waits for late data before finalizing a window ✓
  • C. To assign partitions to consumers
  • D. To compress state stored in memory
Correct answer: B. A watermark tracks event-time progress and defines the lateness threshold after which windows can be finalized and state cleared.
When implementing Change Data Capture from a relational source, which log-based approach is generally preferred over query-based polling and why?
  • A. Polling a modified_at column, because it captures deletes reliably
  • B. Reading the database transaction/WAL log, because it captures all changes including deletes with low source overhead ✓
  • C. Full table snapshots each cycle, because they are cheapest
  • D. Trigger-based capture, because triggers never affect write latency
Correct answer: B. Log-based CDC reads the WAL/binlog to capture inserts, updates, and deletes with minimal load and without missing changes between polls.
A star-schema query aggregating a 10-billion-row fact table by month is slow. Beyond partitioning by date, which storage-layout choice most improves scan performance for filtered analytical queries?
  • A. Storing the fact table as row-oriented JSON
  • B. Clustering/sorting (Z-ordering) columnar data on frequently filtered columns ✓
  • C. Adding more OLTP-style B-tree indexes
  • D. Increasing the block size to 1 GB uniformly
Correct answer: B. Sorting/Z-ordering colocates related values so predicate pushdown and min/max statistics skip more row groups during scans.
In Airflow, two tasks in the same DAG run must share a large intermediate dataset. Why is passing it through XCom generally a poor choice?
  • A. XCom cannot pass any data between tasks
  • B. XCom stores values in the metadata database and is meant for small values, not large datasets ✓
  • C. XCom only works across separate DAGs
  • D. XCom bypasses task dependencies
Correct answer: B. XCom persists to the metadata DB and is designed for small control values; large data should be passed via external storage with references.
You need at-least-once delivery from Kafka but observe data loss during broker failover. Which producer/broker configuration combination prevents acknowledged messages from being lost?
  • A. acks=0 with replication.factor=1
  • B. acks=all with min.insync.replicas>=2 and replication.factor>=3 ✓
  • C. acks=1 with unclean.leader.election enabled
  • D. acks=all with min.insync.replicas=1 and unclean.leader.election enabled
Correct answer: B. acks=all plus min.insync.replicas>=2 on a replication.factor>=3 topic ensures a write survives a single broker failure without loss.
A batch pipeline recomputes daily aggregates but late-arriving events for prior days must be corrected without full reprocessing. Which pattern best fits?
  • A. Append-only immutable output with no recomputation
  • B. Incremental merge/upsert into affected partitions using a lookback window ✓
  • C. One-time full snapshot at pipeline start
  • D. Storing all data only in memory
Correct answer: B. A bounded lookback window with idempotent upserts into affected partitions corrects late data without reprocessing everything.

Prep for another role

Questions are original, written and independently verified for HireHire's role interview quizzes. They reflect the kind of knowledge Data Engineer interviews test, not any specific company's questions. HireHire maps live tech & IT jobs across India, updated regularly. Last updated: August 2026.