Skip to content

Cookies on Jobverse

We use cookies that are needed to sign you in and keep the site working. With your permission we’d also use an analytics cookie to count job views, and Google advertising cookies to show ads. The site works the same whatever you choose. Read the Cookie Policy.

Jobverse
Sign in

Data Engineer Top 100 Interview Questions

100 data engineer interview questions with structured answers, comparison tables, flow diagrams, worked calculations and runnable examples. Covers SQL, data modeling, ingestion, storage, distributed processing, streaming, Python, data quality, governance and system design, from fundamentals to production operations.

100 questions

Questions 1-20 of 100

  1. Q1.What are the core responsibilities of a data engineer?

    A data engineer builds and operates systems that turn source data into dependable datasets. The role connects business requirements with ingestion, storage, transformation, and delivery.

    • Requirements: define who uses the data, what each field means, how fresh it must be, and which failures would affect important decisions.
    • Construction: implement pipelines and data models that preserve source meaning, support expected queries, and handle changing volume and schemas.
    • Reliability: test completeness and correctness, monitor processing, investigate incidents, and make recovery and reruns predictable.
    • Ownership: document datasets, protect sensitive information, manage access and cost, and coordinate changes with producers and downstream consumers.

    Success is measured by useful, trustworthy data delivered consistently, rather than by the number of pipelines created.

  2. Q2.What would you clarify before designing a data pipeline?

    I would define the business outcome and measurable delivery requirements before choosing the architecture. Volume alone does not determine whether a pipeline should be batch or streaming.

    1. Identify consumers, decisions, source owners, required fields, business definitions, and the consequences of incorrect or unavailable data.
    2. Estimate typical and peak volume, growth, update patterns, acceptable freshness, retention, and the need to recover historical changes.
    3. Check source access, delivery guarantees, privacy requirements, budget, and operational ownership; agree on how completeness will be verified.
    4. Choose the simplest design that meets these constraints, then document acceptance criteria and test representative failure scenarios.
    flowchart TD
    A["Identify consumer need"]
    B["Define delivery targets"]
    C{"Continuous updates needed?"}
    D["Evaluate streaming"]
    E["Evaluate scheduled batches"]
    F["Validate cost and recovery"]
    A --> B
    B --> C
    C -->|yes| D
    C -->|no| E
    D --> F
    E --> F

    Trade-offs:

    • Lower latency usually requires more continuous infrastructure and operational attention; confirm that consumers benefit from it.
    • A stricter recovery target can justify extra retained history and redundancy even when the ordinary workload is small.
  3. Q3.How do ETL and ELT differ?

    ETL transforms extracted data before loading it into the target analytical store. ELT loads it first and performs transformations using the target environment.

    ETLELT
    Transforms data before loading the targetTransforms data inside the target environment
    Controls data before it arrivesUses target compute and keeps the raw inputs

    When to use which:

    • Use ETL when sensitive fields must be removed before entering the destination or when the destination cannot perform the required transformations efficiently.
    • Use ELT when scalable analytical compute is available and retaining source-shaped data makes new transformations and historical reprocessing easier.
    • Choose a hybrid when ingestion requires basic validation or redaction but most business transformations belong close to the analytical data.

    Both approaches still need versioned logic, quality checks, access controls, and recovery procedures. Loading raw data does not automatically make ELT simpler or cheaper.

  4. Q4.When should you use batch, micro-batch, or continuous stream processing?

    The choice depends on acceptable delay, workload behavior, and operational complexity. Streaming is useful when decisions cannot wait for the next scheduled batch.

    BatchMicro-batchContinuous stream
    Processes a bounded datasetProcesses frequent small batchesProcesses events as they arrive
    Fits periodic reportingFits low-delay aggregatesFits immediate reactions

    When to use which:

    • Use batch for workloads with relaxed freshness requirements, predictable processing windows, and substantial historical transformations that benefit from bounded inputs.
    • Use micro-batches when short delays are acceptable and batching improves throughput or simplifies checkpointed processing of incoming records.
    • Use continuous processing when event-level responsiveness has measurable value and the team can operate state, ordering, backpressure, and recovery correctly.

    Measure complete source-to-consumer delay rather than only processing time. A fast engine cannot compensate for a source that publishes data once per day.

  5. Q5.What is the difference between OLTP and OLAP workloads?

    OLTP supports operational transactions, while OLAP supports analytical questions across many records. They favor different access patterns and physical designs.

    OLTPOLAP
    Small targeted reads and writesLarge scans and aggregations
    Goal: reliable transaction responseGoal: efficient analysis
    Often normalized and row-orientedOften dimensional and column-oriented

    When to use which:

    • Use an OLTP design when individual business operations must update a small amount of data with appropriate transactional guarantees and low response time.
    • Use an OLAP design when users compare trends, combine historical datasets, or aggregate large portions of a table across many dimensions.
    • Separate heavy analytics from operational traffic when scans and transformations would compete with customer-facing transactions for resources.

    These are workload categories rather than absolute product boundaries. A system may support both, but isolation, concurrency, and cost still need evaluation.

  6. Q6.How do a data warehouse, a data lake, and a lakehouse differ?

    These architectures organize storage and analytical access differently. Their usefulness depends on governance, query performance, supported data types, and operational requirements.

    WarehouseLakeLakehouse
    Emphasizes managed analytical tablesEmphasizes files in scalable storageEmphasizes lake storage with table management
    Concern: flexible access to raw inputsConcern: consistent metadata and qualityConcern: engine and table compatibility

    When to use which:

    • Use a warehouse when governed SQL analytics, stable table semantics, and predictable reporting are the central requirements for most consumers.
    • Use a lake when retaining varied source data and enabling multiple processing patterns are important, while explicitly providing ownership and metadata management.
    • Use a lakehouse when shared file storage should support transactional table operations and analytical queries across compatible engines.

    The label does not guarantee reliability. Verify transaction boundaries, schema enforcement, access controls, maintenance costs, and behavior when multiple writers update the same data.

  7. Q7.How do structured, semi-structured, and unstructured data affect pipeline design?

    The categories describe how explicitly records expose their organization. Every category still requires decisions about interpretation, validation, and downstream use.

    • Structured data: records follow defined columns and types, making schema checks straightforward; business constraints and relationships still require separate validation.
    • Semi-structured data: nested objects or varying fields preserve useful hierarchy, but pipelines must handle missing attributes, changing types, and repeated elements deliberately.
    • Unstructured data: documents, images, and recordings may require extraction before they can support relational analysis; retain provenance and extraction confidence where relevant.
    • Design consequence: preserve a governed source representation, define the intended analytical schema, and record transformations so consumers can trace derived values.

    Schema-on-read delays some interpretation decisions; it does not eliminate the need for a schema or dependable data contracts.

  8. Q8.What problems do first, second, and third normal forms address?

    Normalization organizes relational data to reduce redundant facts and the update anomalies they cause. It is based on keys and functional dependencies, not simply on splitting large tables.

    • First normal form: represent values within the chosen relational domains without repeating column groups; each row must be identifiable and have a consistent structure.
    • Second normal form: satisfy first normal form and ensure every non-key attribute depends on the whole of each candidate key, not only part of a composite key.
    • Third normal form: remove inappropriate dependencies between non-key attributes; formally, each nontrivial dependency has a superkey determinant or a prime attribute on its right side.
    • Practical trade-off: normalization helps maintain operational consistency, while deliberate denormalization can simplify analytical reads at the cost of additional update responsibility.
  9. Q9.What do the ACID properties guarantee in a database transaction?

    ACID describes properties that make a transaction a dependable unit of database work. The guarantees apply within the database's documented transaction boundary and configuration.

    • Atomicity: all operations in a transaction commit together or their changes are rolled back, preventing a partial business update from becoming the final state.
    • Consistency: committed work preserves enforced constraints and application-defined invariants when the transaction logic is correct; the database cannot infer every business rule.
    • Isolation: concurrent transactions interact according to the selected isolation level, which determines which intermediate effects or anomalies may be observed.
    • Durability: acknowledged commits survive the failures covered by the configured persistence and replication guarantees.

    A transaction does not automatically include a separate message broker, external API, or file write. Coordinating those effects requires an additional design.

  10. Q10.How does SQL handle NULL values and three-valued logic?

    NULL represents an unknown or missing value rather than zero or an empty string. Comparisons involving NULL usually produce UNKNOWN, so ordinary two-valued reasoning can give incorrect results.

    • Filtering: a WHERE clause keeps rows whose condition is TRUE; both FALSE and UNKNOWN are excluded, so use IS NULL or IS NOT NULL for missing values.
    • Aggregation: COUNT(*) counts rows, while COUNT(column) ignores NULL values; most numerical aggregates also ignore NULL inputs and can return NULL for an empty group.
    • Defaults: COALESCE supplies a replacement when that replacement has an agreed business meaning; turning an unknown amount into zero can distort reporting.
    • Anti-matching: a NULL in a NOT IN subquery can make otherwise unmatched comparisons UNKNOWN; an appropriately correlated NOT EXISTS often expresses the intended rule more safely.
  11. Q11.How do INNER, LEFT, FULL OUTER, and CROSS joins differ?

    A join combines rows according to a matching rule. Select the join based on which unmatched records must remain visible in the result.

    INNERLEFTFULL OUTERCROSS
    Keeps matching pairsKeeps all left rows and their matchesKeeps matched and unmatched rowsKeeps every possible pair
    Use to require a corresponding recordUse to preserve a reference populationUse to reconcile both datasetsUse to generate combinations

    When to use which:

    • Use an inner join when unmatched records should be excluded intentionally, after confirming that missing keys do not hide a data-quality problem.
    • Use a left or full outer join when missing matches carry business meaning, such as identifying customers without activity or comparing two extracts.
    • Use a cross join only when the full combination is needed and its expected row count is acceptable.

    Any matching key with multiple rows can multiply the result. Filtering a right-side column in WHERE after a left join can also remove its unmatched rows.

  12. Q12.What is the difference between WHERE and HAVING?

    WHERE filters input rows before grouping. HAVING filters the resulting groups, usually using aggregate conditions such as a minimum total or count.

    WHEREHAVING
    Filters before groupingFilters after grouping
    Example: order status is completedExample: customer total exceeds a limit

    When to use which:

    • Use WHERE to remove records that should not contribute to the calculation, such as canceled transactions when measuring completed revenue.
    • Use HAVING to select groups based on their aggregate results, such as customers whose completed revenue exceeds a defined threshold.
    • Use both when the input population and the group-level acceptance rule differ; state those rules separately so the query remains auditable.

    Filtering rows early can reduce work, but moving an aggregate condition into WHERE changes the meaning or makes the statement invalid. The logical evaluation stages do not prescribe an engine’s exact physical execution order.

  13. Q13.When should you use UNION rather than UNION ALL?

    UNION combines compatible query results and removes duplicate result rows. UNION ALL combines them while preserving every occurrence, including duplicates.

    UNIONUNION ALL
    Removes duplicate complete rowsKeeps all rows
    Costs deduplication workUsually less merging work

    When to use which:

    • Use UNION ALL when duplicates represent legitimate repeated events, when source partitions are disjoint, or when business-key deduplication occurs explicitly in another step.
    • Use UNION when duplicate complete output rows are genuinely interchangeable and set semantics match the intended result.
    • Check column positions, compatible types, and consistent units before combining results; matching column names alone does not establish compatibility.

    Neither operator guarantees presentation order without a final ORDER BY. UNION also does not resolve conflicting versions of one entity when their non-key values differ.

  14. Q14.How do GROUP BY aggregates differ from window functions?

    GROUP BY reduces input rows to one result per group. A window function computes across related rows while retaining each row in the windowed result.

    GROUP BYWindow function
    Returns one row per groupKeeps every input row
    Example: customer totalsExample: running totals or rankings

    When to use which:

    • Use GROUP BY when the requested output is a summary at a different grain, such as one total per customer instead of one row per order.
    • Use a window function when each detail row must remain available alongside a comparison, rank, previous value, or cumulative measurement.
    • Combine the techniques when you first need a daily summary and then want to compare each daily result with previous days.

    A window’s PARTITION BY defines independent groups, ORDER BY establishes sequence, and its frame controls which rows participate in applicable calculations. These clauses serve different purposes.

  15. Q15.How do ROW_NUMBER, RANK, and DENSE_RANK handle ties?

    These functions assign positions within an ordered window, but they treat tied ordering values differently. The tie policy must match the question being answered.

    ROW_NUMBERRANKDENSE_RANK
    Scores 90, 90, 80 get 1, 2, 3Scores 90, 90, 80 get 1, 1, 3Scores 90, 90, 80 get 1, 1, 2
    A distinct position for every rowEqual ranks for ties, with gapsEqual ranks for ties, without gaps

    When to use which:

    • Use ROW_NUMBER to select a fixed number of rows or one winning version, adding a stable unique tie-breaker when reproducible selection matters.
    • Use RANK when competition positions should reflect how many rows precede a tied group, leaving the corresponding gaps afterward.
    • Use DENSE_RANK when the requirement refers to distinct score or salary levels, so ties share a position and the next level follows immediately.

    Adding a unique identifier to the ranking order removes ties. Do that only when distinct row positions, rather than shared business ranks, are intended.

  16. Q16.How would you select the latest record for each entity in SQL?

    I would rank each entity’s versions by the authoritative update sequence and retain the first row. A timestamp alone may not establish a unique winner.

    • Partition: group versions by the complete business identifier, including a source identifier if different systems can reuse the same key.
    • Order: sort by the business update time or source sequence descending, then use a deterministic tie-breaker with a documented meaning.
    • Select: calculate ROW_NUMBER in a subquery or common table expression and filter to position one in the outer query.
    • Validate: check equal timestamps, missing ordering values, deletions, and late arrivals; ingest time should not replace business ordering without justification.

    The result is a current-state projection, so retain the original version history separately when historical reconstruction is required.

    Example

    This query keeps the newest customer record and breaks equal timestamps by a unique sequence.

    WITH updates(customer_id, updated_at, sequence_no, city) AS (
        VALUES (1, '2026-01-01 09:00:00', 1, 'Pune'),
               (1, '2026-01-02 09:00:00', 2, 'Delhi'),
               (2, '2026-01-01 10:00:00', 3, 'Chennai')
    ), ranked AS (
        SELECT *, ROW_NUMBER() OVER (
            PARTITION BY customer_id
            ORDER BY updated_at DESC, sequence_no DESC
        ) AS rn
        FROM updates
    )
    SELECT customer_id, city
    FROM ranked
    WHERE rn = 1
    ORDER BY customer_id;
    -- Expected rows: (1, 'Delhi'), (2, 'Chennai')
  17. Q17.How would you find the nth highest distinct salary in SQL?

    I would rank distinct salary levels in descending order and select the requested rank. Clarifying whether ties count separately prevents a common interpretation error.

    • Input rule: exclude missing salaries unless the business question defines a meaningful ordering for them, and require n to be a positive integer.
    • Ranking: use DENSE_RANK over salary descending so equal salaries share a level and later distinct salaries receive consecutive ranks.
    • Output: select the requested rank and return a distinct salary; include employee fields instead if the request is for all employees at that level.
    • Edge cases: return no matching row when fewer than n salary levels exist, and define whether the calling application should display a missing value.

    An offset over all employee rows answers a different question when salaries are tied.

    Example

    This query finds the second highest distinct salary rather than the second employee row.

    WITH employees(employee_id, salary) AS (
        VALUES (1, 100), (2, 100), (3, 90), (4, 80)
    ), ranked AS (
        SELECT salary,
               DENSE_RANK() OVER (ORDER BY salary DESC) AS salary_rank
        FROM employees
        WHERE salary IS NOT NULL
    )
    SELECT DISTINCT salary
    FROM ranked
    WHERE salary_rank = 2;
    -- Expected row: (90)
  18. Q18.How would you return the top three products by revenue within each category?

    I would aggregate revenue to one row per category and product before ranking products within each category. Ranking transaction rows would answer the wrong question.

    • Aggregation: calculate revenue using agreed rules for refunds, discounts, and currency, ensuring every transaction contributes once to the intended product total.
    • Partitioning: create an independent ranking for each category rather than applying one global limit to the whole result.
    • Tie policy: use ROW_NUMBER with a deterministic product tie-breaker for at most three products; use shared ranks if all ties must be returned.
    • Validation: check categories with fewer than three products, equal revenues, and products that changed categories during the measurement period.

    State the reporting interval explicitly in a production query so its results remain reproducible.

    Example

    This query returns at most three products per category and resolves revenue ties by product identifier.

    WITH sales(category, product_id, revenue) AS (
        VALUES ('A', 1, 10), ('A', 1, 5), ('A', 2, 20),
               ('A', 3, 20), ('A', 4, 1), ('B', 5, 7)
    ), totals AS (
        SELECT category, product_id, SUM(revenue) AS total
        FROM sales
        GROUP BY category, product_id
    ), ranked AS (
        SELECT *, ROW_NUMBER() OVER (
            PARTITION BY category ORDER BY total DESC, product_id
        ) AS rn
        FROM totals
    )
    SELECT category, product_id, total
    FROM ranked
    WHERE rn <= 3
    ORDER BY category, rn;
    -- Expected rows: ('A', 2, 20), ('A', 3, 20), ('A', 1, 15), ('B', 5, 7)
  19. Q19.How would you find customers who have never placed an order?

    I would use a correlated NOT EXISTS condition to keep customers for whom no matching order exists. It directly expresses an anti-join without multiplying customer rows.

    • Population: begin with the authoritative customer table so customers with no activity are present in the starting dataset.
    • Matching: correlate orders using the complete customer key and apply any relevant business rule, such as whether canceled orders count as orders.
    • Missing keys: decide how unassigned orders should be handled separately; a NULL customer key in an order does not establish a match to a valid customer.
    • Performance: inspect the execution plan and available access paths for the matching key rather than assuming one SQL spelling is always fastest.

    Filtering the order table first cannot reveal customers who never appear in it.

    Example

    This query remains correct even though one order has an unknown customer identifier.

    WITH customers(customer_id) AS (
        VALUES (1), (2), (3)
    ), orders(order_id, customer_id) AS (
        VALUES (10, 1), (11, 1), (12, NULL)
    )
    SELECT c.customer_id
    FROM customers c
    WHERE NOT EXISTS (
        SELECT 1 FROM orders o
        WHERE o.customer_id = c.customer_id
    )
    ORDER BY c.customer_id;
    -- Expected rows: (2), (3)
  20. Q20.How would you calculate a running total in SQL?

    I would use a windowed SUM with an explicit ordering and row frame. The frame makes it clear that the result includes the current row and all preceding rows.

    • Grain: first decide whether the cumulative measure should advance per transaction, day, or another business unit, and aggregate to that grain when necessary.
    • Partition: restart the total at the correct boundary, such as each account, instead of mixing unrelated balances or revenue streams.
    • Ordering: add a deterministic tie-breaker for equal timestamps when individual transaction order affects intermediate totals.
    • Frame: specify ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW for row-by-row accumulation; default peer-based behavior may combine equal ordering values.

    Window ordering determines the calculation, while a final ORDER BY controls how returned rows are displayed.

    Example

    This query calculates an independent running amount for each account.

    WITH transactions(account_id, transaction_id, amount) AS (
        VALUES (1, 1, 10), (1, 2, -3), (1, 3, 8), (2, 4, 5)
    )
    SELECT account_id, transaction_id,
           SUM(amount) OVER (
               PARTITION BY account_id ORDER BY transaction_id
               ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
           ) AS running_amount
    FROM transactions
    ORDER BY account_id, transaction_id;
    -- Expected rows: (1, 1, 10), (1, 2, 7), (1, 3, 15), (2, 4, 5)