Data Engineer Interview Prep: Questions and a Mock Test
Data engineering interviews have a reputation for being easier than software engineering interviews. They are not, they are differently shaped. The algorithmic bar is usually lower and the correctness bar is usually higher, because the failure mode of this job is not a slow endpoint, it is a number on a dashboard that is quietly wrong and has been for three weeks. This page covers what the loop tests, why re-runnability comes up in almost every round, and ends with a graded mock over six areas.
How the process is structured
| Round | Length | What it tests |
|---|---|---|
| 1.SQL[3] | Not published | Live query writing against a small schema, usually with a deliberate trap: NULL semantics, a join that fans out, a window function requirement, or a predicate that silently converts an outer join to an inner one. Assessed on correctness and on whether you validate assumptions about cardinality before aggregating. |
| 2.Data modelling[1] | Not published | Designing tables for a described business. Grain, facts and dimensions, slowly changing dimension strategy, and the tradeoff between normalised and flattened shapes on a columnar warehouse. Marked on the defence of the choice rather than the diagram. |
| 3.Pipeline and systems design[2] | Not published | An end to end pipeline: ingestion, storage layout and partitioning, transformation, orchestration, and how it is re-run after a failure or a correction. Distributed execution details come up here, including shuffles, skew and broadcast joins, where Spark's documented broadcast threshold defaults to 10 MB. |
| 4.Quality, governance and behaviour[1] | Not published | How you find out a table is wrong before a stakeholder does, what you test and where, lineage and ownership, and stories about a pipeline that broke. Data tests in the dbt sense, select statements that return failing rows and pass when they return none, are the common shared vocabulary. |
Bracketed markers point to the dated sources at the end of this article. Loops change; check the retrieval dates before relying on a round count.
SQL is tested for correctness, not cleverness
Almost every data engineering loop has a live SQL round, and the questions are chosen so that a plausible-looking query gives a wrong answer. The recurring traps are worth rehearsing until they are reflexes.
NULL handling is the first. NULL is not a value, it is the absence of one, so any comparison with it yields unknown rather than true or false. That means a WHERE clause of the form status != 'closed' silently discards rows where status is NULL, and NOT IN against a subquery containing a single NULL returns no rows at all. COUNT(column) skips NULLs while COUNT(*) does not.
The second is join fan-out. An inner join to a table with duplicate keys multiplies rows, so any SUM computed afterwards is inflated. Interviewers introduce this deliberately and watch whether you check cardinality before aggregating.
The third is the difference between filtering in WHERE and filtering in the ON clause of an outer join. A predicate on the right-hand table placed in WHERE turns a LEFT JOIN into an inner join, because the NULLs the join produced fail the test.
Window functions are expected fluency at mid level: running totals, ranking within a group, deduplicating by taking the first row per key, and knowing why ROW_NUMBER, RANK and DENSE_RANK differ on ties.
Modelling questions want a defended tradeoff
Modelling rounds ask you to design tables for a described business, and the mark is for the reasoning rather than the diagram. Star schemas are still the common vocabulary: facts hold the measurements and the foreign keys, dimensions hold the descriptive attributes. Normalising a dimension into a snowflake reduces duplication and costs you joins, and on columnar warehouses that tradeoff usually favours the flatter shape.
Slowly changing dimensions come up constantly because they force you to say what the business actually needs. Type 1 overwrites and loses history. Type 2 adds a new row with validity dates and a current flag, preserving history at the cost of every downstream query having to filter correctly. The good answer starts by asking whether anyone needs to reconstruct the past, and only then picks.
Grain is the question behind the question. Being able to state "one row per order line per day" precisely, and to explain what breaks if the grain is mixed, is what separates a modelling answer from a table-drawing answer. The most common real defect in warehouses is a fact table whose grain nobody wrote down.
Distributed batch: shuffles, skew, and actual numbers
Spark questions are rarely about the API. They are about knowing which operations move data across the network and what happens when the data is unevenly distributed.
A shuffle is the expensive event: any join or aggregation that needs matching keys on the same executor writes intermediate data and reads it back over the network. Spark's documented default for spark.sql.shuffle.partitions is 200, which "configures the number of partitions to use when shuffling data for joins or aggregations". That number being fixed regardless of data size is why it is a classic tuning question.
Broadcast joins avoid the shuffle entirely by sending the small side to every executor. The documented threshold, spark.sql.autoBroadcastJoinThreshold, defaults to 10485760 bytes, which is 10 MB, and "by setting this value to -1, broadcasting can be disabled".
Adaptive Query Execution has changed several stock interview answers, so it is worth being current. It has been "enabled by default since Apache Spark 3.2.0". It coalesces post-shuffle partitions using runtime statistics toward an advisory size that defaults to 64 MB, and it handles skew: with skewJoin enabled by default, "Spark dynamically handles skew in sort-merge join by splitting (and replicating if needed) skewed partitions", with the skew threshold defaulting to 256 MB. Salting a skewed key is still a valid manual answer, but a candidate who presents it as the only answer sounds several years out of date.
Streaming: the semantics question, answered properly
Streaming rounds converge on delivery guarantees, and the answers are more specific than the labels suggest.
At most once means a message may be lost but never processed twice, which is what you get when the consumer commits its offset before doing the work. At least once means a message is never lost but may be processed more than once, which is what you get when the work happens before the commit. Exactly once is not a property of the message bus alone; it is a property of the whole path, and it is achieved either by transactional writes that atomically commit the output and the offset together, or by making the consumer idempotent so that duplicates are harmless.
Interviewers like this because at-least-once plus idempotency is usually the right engineering answer, and reaching for it shows you understand what exactly-once costs.
Ordering is the second recurring topic. Order is guaranteed within a partition and not across partitions, so any requirement to process a given entity's events in order becomes a partitioning decision: key by that entity. The follow-up is usually about what happens when you need more parallelism than you have keys, or when one key is far hotter than the rest.
Expect event time versus processing time, and watermarks as the mechanism for deciding how long to wait for late data before closing a window.
Pipelines that can be safely re-run
The most reliable senior signal in a data engineering interview is treating idempotency and backfill as design constraints rather than as afterthoughts. Every pipeline is eventually re-run: because it failed halfway, because upstream sent a correction, because someone found a bug in a transformation that has been live for a month.
The practical form is that a task for a given time window must produce the same result whether it runs once or five times. That usually means writing partitioned output and replacing the partition rather than appending to it, and it means avoiding transformations that depend on the wall clock at execution time, since a backfill runs today for data that belongs to March.
Testing is the other half. dbt's framing is worth borrowing whatever tool you use: "Data tests are SQL select statements that seek to grab failing records, ones that disprove your assertion", and "if the data test returns zero failing rows, it passes". Its four built-in generic tests, unique, not_null, accepted_values and relationships, cover the assertions that catch most real breakage, and a singular test is just a one-off query asserting something specific to one model.
Be ready to say where the tests run. Testing after loading catches problems that have already reached consumers; testing in a staging area before promotion is what stops a bad load being visible at all.
What they actually ask
1.A daily job that has run cleanly for a year suddenly takes six hours instead of forty minutes. Nothing was deployed. Where do you look?
What a strong answer coversStrong answers separate the change in the data from a change in the system. On the data side: a volume spike, a new value making a join key skewed, a source that started sending duplicates, or a partition that stopped being pruned because a filter no longer matches the layout. On the system side: contention from another workload, a shrunken cluster, or a spilled shuffle caused by memory pressure. Good candidates go to the execution plan and stage-level metrics rather than guessing, look for one task in a stage taking far longer than the rest as the signature of skew, and mention that Spark handles some of this automatically now, with adaptive skew join splitting skewed partitions by default since 3.2.
2.Design a pipeline that ingests clickstream events and serves a daily active users metric.
What a strong answer coversExpected coverage: ingestion path and whether it is batch or streaming, a raw immutable landing zone kept separate from transformed layers, partitioning by event date, deduplication strategy and the key it uses, and late-arriving data. The distinguishing question is what event time means here and how long you wait for stragglers before declaring a day final, which is exactly what a watermark encodes. Strong answers define the metric precisely, including how a user is identified and what happens when identity resolution changes, and cover how yesterday's number is corrected if data arrives after the fact, since a metric that silently changes is worse than one that is late.
3.How do you make a pipeline safe to re-run?
What a strong answer coversThe core is that a task for a given window must be replayable to the same result. Practical mechanisms: write to a partition and replace it rather than appending, use deterministic keys so an upsert can recognise a row it has already written, avoid depending on the execution wall clock since a backfill runs today for old data, and make any external side effect idempotent through a request key. Strong answers also cover the orchestration layer: parameterising tasks by logical date rather than by now, bounding concurrency so a backfill does not overwhelm a source, and separating a failed run's partial output from committed output so a retry does not read its own garbage.
4.The finance team says last month's revenue figure changed after they had already reported it. How do you respond?
What a strong answer coversThis is a judgement question as much as a technical one. Good answers start by establishing what changed and why: late-arriving transactions, a restatement upstream, a code change applied retroactively to historic partitions, or a slowly changing dimension implemented as type 1 so an attribute update rewrote history. They then separate legitimate restatement from a defect. The engineering conclusions are the valuable part: snapshotting reported figures so a number that was published can always be reproduced, making transformation code versioned and its version recorded with the output, and agreeing a close process after which a period is frozen. Answers that only debug the query miss that the real problem is the absence of a contract.
5.When would you choose streaming over a scheduled batch job?
What a strong answer coversThe strong answer resists the assumption that streaming is the more advanced choice. It starts from the decision the data supports: if nobody acts on the number faster than daily, streaming adds operational cost and failure modes for no benefit. Genuine reasons to stream include fraud or abuse detection where the action must happen in seconds, operational dashboards driving live decisions, and event-driven integrations. Costs to name: harder testing and replay, state management and its checkpoints, out-of-order and late data, and on-call load. Many strong candidates land on micro-batch as the pragmatic middle, and note that the same pipeline logic being runnable in both modes is what makes backfill tractable.
6.Where would you put data quality tests, and what would you test?
What a strong answer coversExpected structure: test at the boundary where you can still stop bad data, not only after it lands. Categories worth naming are schema and type conformance, uniqueness of the primary key, not-null on required fields, referential integrity between fact and dimension, accepted values on enumerations, and volume or distribution checks that catch a source silently halving. Strong answers distinguish tests that should block promotion from tests that should only alert, because a pipeline that halts on every anomaly gets disabled by the people it wakes. Mentioning that a test is just a query returning rows that disprove an assertion, and passing means zero rows, shows the mechanism is understood rather than the tool.
Three sample questions, answered
These three show the level the mock is pitched at, with the answer and the reasoning in the open. The graded paper keeps its answer key server-side.
- 700
- 1000
- 500
- 800
Why: Comparing anything to NULL yields unknown, not true, so the 200 NULL rows fail the predicate and are excluded along with the 300 'closed' rows. That leaves 500. Capturing the NULL rows requires an explicit OR status IS NULL. This silent row loss is one of the most common real defects in production SQL.
- At most once: a message can be lost but never processed twice
- At least once: a message can be processed twice but never lost
- Exactly once, provided the broker supports transactions
- No guarantee at all
Why: If the offset is committed first and the consumer crashes before finishing the work, the message is never retried and is lost. That is at most once. Processing first and committing afterwards gives at least once, because a crash between the two causes redelivery. Exactly once requires the output write and the offset commit to be atomic, or an idempotent consumer.
- Appending results to a target table on every run
- Using the current timestamp to filter source data
- Setting a longer task timeout
- Writing to a partition keyed by the logical execution date and replacing it
Why: Backfill re-runs a task today for a window that belongs to the past. Appending duplicates on every retry, and filtering by the wall clock produces different results depending on when the task happens to run. Writing the window's output into its own partition and replacing that partition makes the task idempotent by construction.
An 18-question knowledge check
This is a knowledge check, not a simulation. The real loop happens on a whiteboard, in an editor, and in conversation. What this paper does measure is the underlying knowledge those rounds draw on: each question is tagged with a topic, grading happens per topic, and a weak topic points you at the course that fixes it.
- 1.You LEFT JOIN orders to refunds and then add WHERE refunds.amount > 0. What have you done?SQL semantics and joins
- 2.Which window function assigns 1, 2, 2, 4 to a group of four rows where the second and third tie?SQL semantics and joins
- 3.An inner join between an orders table and a customer_addresses table returns more rows than orders had. What is the most likely cause?SQL semantics and joins
- 4.You state that a fact table's grain is 'one row per order line'. Why does this matter most?Modelling, grain and the lakehouse
- 5.A customer changes address. The business needs historical orders to show the address at the time of purchase. Which approach applies?Modelling, grain and the lakehouse
- 6.Why do columnar formats such as Parquet suit analytical workloads?Modelling, grain and the lakehouse
- 7.Spark's spark.sql.shuffle.partitions has what documented default?Distributed batch processing
- 8.One task in a Spark stage takes 40 minutes while the other 199 finish in under a minute. What is the diagnosis?Distributed batch processing
- 9.What does Spark's spark.sql.autoBroadcastJoinThreshold control, and what is its documented default?Distributed batch processing
- 10.In a partitioned log like Kafka, what ordering guarantee actually holds?Streaming and delivery semantics
- 11.What problem does a watermark solve in stream processing?Streaming and delivery semantics
- 12.Which combination is the usual practical route to effectively-once processing?Streaming and delivery semantics
- 13.Which dbt test is a singular test rather than a generic one?Transformation and data tests
- 14.A data test returns 14 rows. What does that mean?Transformation and data tests
- 15.Why is a raw landing zone usually kept immutable and separate from transformed tables?Transformation and data tests
- 16.PostgreSQL implements how many distinct isolation levels internally, and what happens to a request for Read Uncommitted?Orchestration, idempotency and backfill
- 17.Your DAG runs hourly. A source system was down for a day and has now replayed everything. What is the risk?Orchestration, idempotency and backfill
- 18.A pipeline computes 'events in the last 7 days' using the current date at execution time. Why is this a problem?Orchestration, idempotency and backfill
Sources
Hiring loops change. Every claim above carries a retrieval date so you can judge how current it is.
- [1]dbt Labs, Add data tests to your DAG · retrieved 2026-08-13
- [2]Apache Spark, Performance Tuning (SQL guide) · retrieved 2026-08-13
- [3]PostgreSQL Documentation, Transaction Isolation · retrieved 2026-08-13
Refresh your memory
Free learning paths covering the ground this loop tests, whatever your score. Each one ends with a shareable certificate.
- ProgrammingData Engineering Foundations
An eight-lesson path from SQL fundamentals to a modern data stack. You'll learn how to query and tune relational data, cache hot reads, model with dbt, choose between lakehouse and warehouse architectures, and wire pipelines together with Kafka and Airflow. By the end you can reason about every layer a production data platform actually runs on.
8 lessons - ProgrammingDatabase Internals
Go beneath the SQL surface and understand how databases actually work. After this track you will be able to explain how data is laid out on disk, why B-trees dominate relational indexes, when to reach for an LSM-tree instead, and how MVCC lets Postgres serve thousands of concurrent readers and writers without blocking. You will read query plans, tune buffer pools and checkpoints, design indexes that avoid heap fetches, and reason precisely about isolation levels and concurrency anomalies.
4 lessons - ProgrammingDistributed Systems Fundamentals
After finishing this cursus you will be able to design, evaluate, and reason about distributed systems with engineering precision: model failures and time correctly, choose the right consistency level for a workload, explain why consensus is hard and how Raft solves it safely, and architect replication and partitioning strategies that scale without creating hot spots or correctness bugs.
4 lessons - BusinessData Governance: How Organizations Make Data Trustworthy
Data governance is dismissed as bureaucracy and misunderstood as an IT chore, yet it is what separates organizations that can trust their data from those drowning in conflicting numbers. This cursus explains it clearly and practically: what governance actually is and why most programs fail, who owns data through roles and operating models, the machinery of quality, metadata, lineage, and master data, and the control layer of classification, access, and policy that keeps data safe while still usable.
4 lessons - ProgrammingObservability: Knowing Why Production Is Slow
Monitoring answers the questions you wrote down in advance; production fails in ways you did not. This path builds observability from its raw materials: the three telemetry signals and their very different bills, the percentile and cardinality arithmetic that decides what your data can honestly say, tracing and the craft of throwing spans away, and the SLO machinery that turns reliability into a number a team can actually spend.
4 lessons

