All posts

Data engineer interview questions by company, deduplicated and answered

What 29 companies reportedly asked data engineers, collected from public interview-experience posts, merged into one list of unique questions grouped by topic, with what a strong answer has to cover.

50 min read Interview

TL;DR

  • Interview-experience posts from 29 companies, from Amazon and Netflix to the large IT services firms, collapse into 75 question groups once duplicates and near-duplicates are merged. Window functions came up at 19 of the 29; duplicates and idempotent reloads, slow-job investigations and late-arriving data at 12 or 13 each.
  • Product companies (Amazon, Netflix, Atlassian, Grab, Paytm) spend their rounds on system design and failure scenarios. Services and consulting firms (TCS, Infosys, Cognizant, PwC, KPMG, Deloitte) spend theirs on Azure Data Factory, Databricks and SCD implementation, plus a managerial round.
  • Treat company labels as hints, not facts. The same question list is posted under different company names, and some posts are verbatim copies across accounts. The questions are real interview material; which company asked a given question cannot be verified.
  • Every technical question has a collapsed answer outline: the mechanism, the trap and the follow-up you should expect. Click a question to open it.

A list of “questions asked at company X” is only useful if it tells you what the interviewer is testing. Most of the posts these questions came from do not: they give a question title and move on, and the same thirty titles repeat under a different company name every week.

This post does the merging. It takes the questions from public LinkedIn interview-experience posts for data engineer roles, removes duplicates and near-duplicates, rewrites each one as a precise question, and groups them by the skill they test. Each technical question then gets an outline of what a strong answer covers, written the way the Spark interview questions post does it: the mechanism first, then the trap.

How the questions were collected

The source set is public LinkedIn posts from October 2026 that describe a data engineer interview at a named company, found through LinkedIn content search for “data engineer interview experience” and “interview experience PySpark SQL round”. Only posts that listed concrete questions were kept. Posts that described a process without questions, and posts for other roles (UX designer, GenAI engineer), were dropped.

Three things about this source are worth knowing before you use it:

The company attribution is weak. One twelve-question banking list appears word for word under Wipro, American Express and Databricks. One American Express post appears from four different accounts, one PayPal post from three, and one Cognizant post from three. Many of the posting accounts sell interview kits. Read a company label as “this question set circulated with this name on it”, not as a transcript.

The questions are still representative. The same question reaching you from five accounts says nothing about one company, but it says a lot about the market. The frequency counts below are the most reliable signal in the set.

Compensation figures were left out. The posts quote CTC ranges, but none can be checked, and they are not what you prepare against.

 public posts ──► keep posts that list questions ──► normalise wording
                                                        │
             ┌──────────────────────────────────────────┘
             ▼
   merge duplicates and near-duplicates ──► tag each question with
             │                              the companies it came from
             ▼
   group by skill ──► outline what a strong answer covers

What each company focuses on

The table summarises the reported rounds for each company and the question that best captures what it tests. Companies are grouped by type, because the type predicts the interview better than the name does.

Product and platform companies

Company Reported rounds Focus Signature question
Amazon Online assessment, technical deep dive, system design, bar raiser Scale, cost, idempotency, leadership principles 50 billion small files in S3 and queries slowing daily: give a remediation plan with no downtime
Microsoft Coding (Python, SQL), Spark, end-to-end system design SQL depth (self-join, recursive CTE), schema drift, SCD Handle schema drift in a batch pipeline without breaking downstream tables
Netflix SQL and modeling, PySpark, system design, production scenarios Event data at scale, Iceberg table management One task takes 45 minutes while the rest finish in 3. Why?
Atlassian DSA, SQL, data system design, behavioural Algorithms plus streaming design Merge overlapping intervals, then design a real-time analytics pipeline with exactly-once semantics
Grab SQL, Spark internals, project deep dive, design Ride-sharing data model, small files in streaming Small-file build-up in a high-throughput Kafka-fed pipeline
Walmart SQL, Spark, DSA, project discussion Consecutive-day patterns, migration, reconciliation Daily sales reports are wrong after a deployment. Investigate.
Comcast SQL, Spark, streaming Partitioning, event time, freshness Find customers whose monthly usage rose three months in a row
Ford Pipeline design, Spark, data quality Vehicle and sensor data, SCD Type 2 Process millions of real-time vehicle sensor events

Fintech and banking

Company Reported rounds Focus Signature question
Goldman Sachs Modeling and SQL, big data, platform design, production and leadership Trade data, table formats, lineage Delta Lake vs Hudi vs Iceberg for a financial data lake
American Express SQL and Python, Spark, architecture, HR Recursive SQL, Spark memory, cost vs SLA Optimise Spark cluster cost while holding the SLA
PayPal Intro, SQL and Python, coding, design, behavioural Payment ETL, late data, warehouse design Design an ETL pipeline for payment transactions
Paytm Design-heavy Exactly-once, Kafka, fraud Achieve exactly-once processing for payment events
HDFC Bank ADF, Spark tuning, Delta scenario, SQL Incremental snapshot design Distinct phone numbers over 90 or 180 days of daily snapshots without scanning them all

Data and analytics vendors

Company Reported rounds Focus Signature question
Databricks Delta Lake, streaming, governance Delta internals, Unity Catalog, multi-tenancy A multi-terabyte Delta table has slowed down. Optimise it.
IBM Coding, SQL, project Window functions, Spark, Kafka basics Second-highest salary without a subquery
Tiger Analytics SQL, design, behavioural Fundamentals, late data Handle late-arriving data in pipelines
HCA Healthcare SQL and PySpark, GCP architecture, debugging Medallion on GCP, Airflow Upstream data has not arrived while the DAG is running. What happens?

Consulting and IT services

Company Reported rounds Focus Signature question
PwC SQL and Python, ADF and Databricks, managerial ADF runtime, MERGE, modeling Azure IR vs self-hosted IR
EY Spark, ADF, SQL Retries, incremental loads A pipeline fails halfway. Retry without duplicating data.
KPMG SQL and Python, ADF and Databricks, managerial ETL fundamentals, PySpark operations Join two large datasets that run out of memory
Deloitte Technical, case study, managerial Migration, GDPR, lineage Migrate 500 TB of banking history from Oracle to Synapse with zero downtime
Wipro Banking-domain design Compliance reporting, CDC, audit Inconsistent balances in a regulatory report. Investigate.
Infosys Technical, ADF and Delta, managerial End-to-end pipeline explanation repartition() vs coalesce() vs repartitionByRange()
TCS Technical, technical and managerial, HR Reusable ETL, banking pipelines Design a reusable ETL framework for 20 clients with different schemas
Cognizant Technical, Azure, managerial, HR Azure end to end, cost Databricks cluster cost doubled this month. Where do you start?
HCLTech Advanced Spark, Delta and Azure AQE, Delta internals, IaC Row-level deletes in Delta without rewriting the partition
Capgemini Technical, client technical GCP plus Databricks Penultimate order for every customer
Coforge SQL and Python, PySpark and Databricks, client design SCD2 with MERGE, idempotency An ADF pipeline loads twice after a retry. Make it idempotent.
EPAM Technical ADF, Spark joins, Unity Catalog Incremental load with no primary key and no timestamp

What comes up most

Counting how many of the 29 companies each topic appeared under gives the clearest picture of where to spend preparation time. The counts come from the company tags on the questions below, so they are lower bounds: a post that only named a topic (“Spark optimisation”) without a question is not counted.

Topic Companies Typical form
Window functions (rank, running totals, latest row) 19 Write it, then explain the tie behaviour
Duplicates and idempotent reloads 13 “The job ran twice” or “the source resent records”
Slow job investigation 13 “It used to take 2 hours, now 8”
Late-arriving data 12 Already-aggregated tables, reports
Data skew and salting 10 Diagnose from the Spark UI, then fix
SCD Type 2 10 Implement with MERGE or in PySpark
Incremental load and CDC 8 Watermarks, MERGE
Delta Lake ACID and maintenance 8 Transaction log, OPTIMIZE, VACUUM
Schema evolution and drift 6 Without breaking downstream consumers
repartition vs coalesce 6 Plus when each is wrong

The pattern is clear: correctness under failure matters more than API recall. Duplicates, retries, late data and schema change make up most of the scenario questions, and they are all versions of one question: what happens to the data when something goes wrong.

SQL

Each question lists the companies it was reported under in brackets.

1. Find the Nth highest salary, overall and per department, using more than one approach. [PwC, PayPal, Atlassian, IBM, Infosys, TCS, Capgemini, HCA Healthcare]

Expect to give three approaches and say when each one breaks.

  • DENSE_RANK() OVER (PARTITION BY dept ORDER BY salary DESC) = N is the default. It treats ties correctly, so the “second highest” is the second distinct value.
  • A correlated subquery, WHERE N - 1 = (SELECT COUNT(DISTINCT salary) FROM emp e2 WHERE e2.salary > e1.salary AND e2.dept = e1.dept), works without window functions. It is quadratic per group, so say so.
  • ORDER BY salary DESC LIMIT 1 OFFSET N-1 over SELECT DISTINCT salary is fine for the overall case and awkward per department.

The trap: ROW_NUMBER() returns a wrong answer when two people share the top salary, because it gives them ranks 1 and 2. The “without RANK or a subquery” variant (TCS, IBM) wants a self-join: MAX(e1.salary) where a strictly greater e2.salary exists.

2. ROW_NUMBER vs RANK vs DENSE_RANK, and when can a ROW_NUMBER solution be rewritten with DENSE_RANK? [PwC, EY, Walmart, Atlassian, Capgemini, IBM]

For the values 100, 100, 90:

Function Result Use it for
ROW_NUMBER() 1, 2, 3 Exactly one row per group (deduplication, latest record)
RANK() 1, 1, 3 Competition ranking with gaps
DENSE_RANK() 1, 1, 2 Nth distinct value

They agree only when the ORDER BY key is unique within the partition. Once there are ties, a DENSE_RANK() = 1 filter returns several rows per group where ROW_NUMBER() = 1 returns one.

The follow-up is determinism. ROW_NUMBER() over a non-unique sort key picks an arbitrary row among the ties, and in Spark that choice can change between runs. Add a tiebreaker column.

3. Find duplicate records, delete them, and keep only the latest record per business key. [PwC, EY, Microsoft, PayPal, Tiger Analytics, Ford, HCA Healthcare]

Find: GROUP BY key HAVING COUNT(*) > 1.

Keep the latest:

SELECT * FROM (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY business_key
                               ORDER BY updated_at DESC, ingest_id DESC) AS rn
  FROM src) t
WHERE rn = 1;

Delete in place depends on the engine. In SQL Server, a CTE with ROW_NUMBER() and DELETE ... WHERE rn > 1 works. In Delta or Iceberg, write the deduplicated result with MERGE or INSERT OVERWRITE rather than issuing row-by-row deletes.

The follow-up: an exact duplicate (every column equal) and a key duplicate (same key, different values) are different problems. The first is a DISTINCT. The second needs a rule for which version wins, and that rule belongs to the business, not to you.

4. Running totals: claim amount per policy, account balance per transaction, sales per day. [Coforge, Wipro, American Express, Databricks, Microsoft, PayPal, Atlassian]

SUM(amount) OVER (PARTITION BY account_id ORDER BY txn_ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW).

State the frame explicitly. With an ORDER BY and no frame, the default is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW. That includes every peer row with the same txn_ts, so two transactions in the same second both show the combined total. ROWS gives a true row-by-row balance.

For a balance, debits must be negative before the sum. Say that you would check the sign convention in the source.

5. Consecutive patterns: orders on consecutive days, usage rising three months in a row, a value appearing three times in a row. [Walmart, Comcast, American Express]

Two standard techniques:

  • LAG/LEAD comparison. For “three rising months”, compare usage with LAG(usage, 1) and LAG(usage, 2) in the same row.
  • Gaps and islands. date - ROW_NUMBER() OVER (PARTITION BY user ORDER BY date) is constant across a run of consecutive dates. Group by that difference and keep groups with COUNT(*) >= k.

Gaps and islands generalises to any run length. LAG needs one comparison per step. Deduplicate dates first: two orders on the same day break the ROW_NUMBER() arithmetic.

6. Anti-joins: customers who ordered in January but not February at 100M rows, customers with no transaction in 90 days, LEFT SEMI vs LEFT ANTI, and missing records without a LEFT JOIN. [Cognizant, Wipro, American Express, EPAM]

NOT EXISTS or a LEFT ANTI JOIN is the correct shape. NOT IN is the trap: if the subquery returns a single NULL, x NOT IN (...) is never true and the query returns zero rows.

LEFT SEMI JOIN returns left rows that have a match, with no right-hand columns and no duplication when the right side has several matches. LEFT ANTI JOIN returns left rows with no match.

At 100M rows in Spark, both are hash or sort-merge joins on the key. Prune the right side to distinct keys for February before the join, and partition by month so January and February are each a single scan. EXCEPT on the key columns also works, at the cost of a full deduplication.

7. Second most recent login for every user, or the penultimate order for every customer. [PwC, Capgemini]

ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_ts DESC) = 2.

Expect the follow-up: what about a user with only one login? This query drops them. If the requirement is “one row per user, null when there is no second”, left join the result back to the distinct users.

8. Traverse a hierarchy (employees to managers, components to leaf parts) with a recursive CTE. [Microsoft, American Express]
WITH RECURSIVE chain AS (
  SELECT emp_id, manager_id, 1 AS depth FROM emp WHERE manager_id IS NULL
  UNION ALL
  SELECT e.emp_id, e.manager_id, c.depth + 1
  FROM emp e JOIN chain c ON e.manager_id = c.emp_id)
SELECT * FROM chain;

Name the two failure modes: a cycle in the data recurses forever, so cap the depth or track visited ids, and the recursion cost grows with depth. Leaf nodes are rows whose id never appears as a parent: an anti-join on manager_id.

Spark 3.5 does not support WITH RECURSIVE. There, the usual answer is an iterative self-join loop in the driver that stops when an iteration adds no new rows.

9. List currently active accounts from an accounts table and a status-audit table, where accounts with no audit record count as active. [HDFC Bank]

Take the latest audit row per account with ROW_NUMBER(), left join it to accounts, and keep rows where COALESCE(latest_status, 'ACTIVE') = 'ACTIVE'.

The test is whether you notice that an inner join silently drops accounts that were never audited, which is the “count as active” clause.

10. Top 3 salaries per department, or top 3 products per region. [KPMG, Microsoft, Infosys]

DENSE_RANK() <= 3 if ties should all be returned, ROW_NUMBER() <= 3 if exactly three rows are required. Ask which. In PySpark the same logic is Window.partitionBy("region").orderBy(F.desc("sales")) with F.dense_rank().

11. A query that ran in 2 minutes now takes 20, or a query over billions of rows with several large joins needs optimising. [EY, Walmart, Comcast, PwC, KPMG, PayPal, EPAM, Ford]

Work from evidence, in this order:

  1. Compare the plans. Get the execution plan now and, if possible, from when it was fast. A changed join strategy or a lost index or partition filter explains most regressions.
  2. Check what changed. Data volume, statistics (stale statistics lead to bad join orders), a new predicate that stopped partition pruning, a function wrapped around a filter column.
  3. Reduce the bytes read. Partition and cluster on filter columns, select only needed columns, push filters below joins.
  4. Fix the joins. Pre-aggregate before joining, filter early, broadcast the small side, check for row explosion from many-to-many keys.

The “it used to be fast” framing is deliberate. The interviewer wants to hear that you start with the plan diff, not with adding indexes.

12. NULL semantics: in aggregates, joins and filters, and what happens with a = null, b = null, a == b? [Comcast, PayPal, Tiger Analytics, KPMG]
  • Comparison: NULL = NULL is NULL, not true, so a filter drops the row. Use IS NULL, Spark’s null-safe <=>, or eqNullSafe in PySpark.
  • Joins: null keys never match in an equi-join. Two rows with a null customer_id do not join to each other.
  • Aggregates: COUNT(col) and AVG(col) skip nulls, while COUNT(*) counts every row. An average that “drops” rows is usually this.
  • Grouping: GROUP BY puts all nulls into one group.
13. SQL fundamentals asked as quick checks: CTE vs subquery, GROUP BY vs HAVING, TRUNCATE vs DELETE, indexing, materialized views. [KPMG, Tiger Analytics, PayPal, Capgemini]
Pair The answer in one line
CTE vs subquery Same plan in most engines; a CTE is readable and can be referenced twice, but is not automatically materialised
WHERE vs HAVING WHERE filters rows before grouping, HAVING filters groups after
TRUNCATE vs DELETE TRUNCATE deallocates all data with minimal logging and no WHERE; DELETE removes rows and can be filtered
Index A sorted structure that turns a scan into a seek; costs write throughput and storage
Materialized view A stored query result, refreshed on a schedule or incrementally; trades freshness for read cost

On a lakehouse, the index question usually becomes partitioning, clustering and file-level statistics, because Parquet tables have no B-tree indexes.

14. Find customers whose purchases in the last 90 days exceed their average monthly purchase by more than 50%. [Deloitte]

Two aggregates at different grains, joined on customer: total over the last 90 days, and average of monthly totals over a baseline period. Then filter on recent_90d > 1.5 * avg_month * 3, or compare per-month rates.

The question is testing whether you define the baseline before writing SQL. “Average monthly purchase” over which months, and including months with zero purchases? Months with no rows do not exist in a GROUP BY, so the average is overstated unless you generate a month calendar.

Python and coding

These rounds are about clean, correct code under pressure, not about algorithms rarely seen in data engineering.

15. Data-shaped Python: deduplicate a list keeping order, count frequencies, find duplicate employees by ID, group consecutive numbers into ranges. [PwC, EY, Azure-role interviews]
  • Order-preserving dedupe: list(dict.fromkeys(items)), since dicts keep insertion order. A seen set with a loop is the explicit version.
  • Frequency: collections.Counter(items).
  • Duplicates by key: group into a defaultdict(list) keyed by ID, keep groups with more than one record.
  • Consecutive ranges: sort, then start a new range whenever x != prev + 1.

State the complexity for each: all are O(n) after the O(n log n) sort in the last case.

16. Classic algorithm questions: merge overlapping intervals, longest substring without repeating characters, longest consecutive sequence, first non-repeating character, pairs summing to a target, top K frequent elements. [Atlassian, PwC, Walmart, PayPal, Tiger Analytics]
Problem Approach Complexity
Merge intervals Sort by start, extend the last interval while overlapping O(n log n)
Longest substring without repeats Sliding window with last-seen index map O(n)
Longest consecutive sequence Set; start counting only from x where x-1 is absent O(n)
First non-repeating character Counter, then one pass in original order O(n)
Pairs summing to target Hash set of complements O(n)
Top K frequent Counter plus heapq.nlargest, or bucket sort O(n log k)

For “first non-repeating element in a stream” (PayPal), the follow-up is memory: an ordered dict of candidates plus a set of seen-twice values.

17. Flatten nested JSON, process a multi-GB CSV without loading it into memory, and compute top routes by revenue without pandas. [Coforge, Microsoft, Tiger Analytics, PwC, KPMG]
  • Nested JSON: a recursive function that joins parent keys with a separator, and turns lists into either indexed keys or exploded rows. Decide which with the interviewer, because it changes the row count.
  • Large CSV: stream with csv.reader line by line, or pandas.read_csv(chunksize=...), keeping only aggregates in memory. For anything that needs a sort or join, say you would hand it to Spark or DuckDB.
  • Top routes without pandas: a defaultdict(float) of route to revenue, then heapq.nlargest(3, ...).
18. Python language questions: decorators, multithreading vs multiprocessing, mutable vs immutable objects, exceptions. [American Express, Data QA interviews]
  • Decorator: a function that takes a function and returns a wrapped one; use functools.wraps to keep the name and docstring. A retry or timing decorator is a good example to give.
  • Threads vs processes: CPython’s GIL lets only one thread run Python bytecode at a time, so threads help I/O-bound work and processes help CPU-bound work.
  • Mutability: lists, dicts and sets are mutable; tuples, strings and frozensets are not. The classic bug is a mutable default argument shared across calls.

Spark architecture and execution

19. What happens, end to end, when a Spark application is submitted? [Grab, Azure-role interviews]
  1. spark-submit launches the driver, which creates the SparkSession.
  2. The driver asks the cluster manager (YARN, Kubernetes, standalone) for executors.
  3. Code builds a logical plan; nothing runs until an action.
  4. On an action, Catalyst analyses and optimises the plan and picks a physical plan.
  5. The DAG scheduler cuts the plan into stages at shuffle boundaries.
  6. The task scheduler sends one task per partition per stage to executors.
  7. Shuffle files are written at each stage boundary and read by the next stage.
  8. Results go back to the driver or are written to storage.

The follow-up is always “where does it break?”: driver memory on collect(), executors at shuffle, and the cluster manager when resources are not granted.

20. Given a sequence (read CSV, repartition(2), filter, select, groupBy, collect), say how many jobs, stages and tasks Spark creates. [Azure-role interviews]

Work it from the shuffles. repartition(2) is one exchange and groupBy is another, so the action produces three stages: the scan stage (one task per input split), a stage of 2 tasks after the repartition, and the post-aggregation stage with spark.sql.shuffle.partitions tasks (200 by default), which AQE may coalesce to fewer.

Reading a CSV with schema inference adds its own job before any of this, because Spark has to read the file to infer the types. That extra job is the detail the question is designed to catch.

21. Narrow vs wide transformations, transformations vs actions, and lazy evaluation. [Capgemini, Azure-role interviews, HCA Healthcare]

A narrow transformation (filter, select, withColumn) computes each output partition from one input partition. A wide one (groupBy, join, distinct, repartition) needs data from many, which forces a shuffle and a stage boundary.

Transformations only add to the plan; actions (collect, count, write) trigger execution. Laziness is what lets Catalyst push filters into the scan and collapse projections before anything runs.

22. RDD vs DataFrame vs Dataset, and SparkContext vs SparkSession. [HCA Healthcare, American Express, Azure-role interviews]

RDDs are opaque objects that Spark cannot optimise. DataFrames carry a schema, so Catalyst can prune columns and push filters, and Tungsten stores rows in a compact binary format. A Dataset is a typed DataFrame in Scala and Java; in Python only the DataFrame exists.

SparkSession (since 2.0) is the entry point for SQL, DataFrames and the catalog. It wraps a SparkContext, which is the lower-level connection to the cluster.

23. What is the Catalyst optimizer, and what is predicate pushdown? [Grab, Comcast, Azure-role interviews]

Catalyst turns a query into a parsed plan, resolves it against the catalog (analysed plan), applies rule-based rewrites (optimised logical plan), then picks a physical plan with strategies and cost estimates. Whole-stage code generation then compiles parts of the physical plan to JVM bytecode.

Predicate pushdown moves filters as close to the data as possible: into the Parquet reader, where row-group min/max statistics skip data, or into a JDBC source’s WHERE clause. Show it with df.explain(): PushedFilters in the scan node.

24. How does Spark decide the number of partitions, and what is a good target partition size? [Comcast, Azure-role interviews]
  • File scans: splits are bounded by spark.sql.files.maxPartitionBytes, 128 MB by default, adjusted by openCostInBytes so many small files are packed together. File count does not set partition count directly.
  • Shuffles: spark.sql.shuffle.partitions, 200 by default, which AQE coalesces toward spark.sql.adaptive.advisoryPartitionSizeInBytes (64 MB).
  • Explicit: repartition(n) and coalesce(n).

A useful target is 100 to 200 MB of input per task. Too small means scheduling overhead dominates; too large means spills and long tasks.

Partitioning, shuffle and joins

25. repartition() vs coalesce() vs repartitionByRange(): what happens internally and when to use each. [EY, Walmart, Infosys, American Express, HDFC Bank, TCS, Azure-role interviews]
Operation Shuffle Result
repartition(n, cols) Full Even, hash-partitioned partitions
coalesce(n) None Merges partitions on the same executor; can be uneven
repartitionByRange(n, cols) Full, after sampling Sorted ranges; good before writing sorted output

The trap: coalesce(1) before a write does not just produce one file. With no shuffle to separate them, it pulls the upstream stage down to one task, so the whole computation runs single-threaded. repartition(1) keeps upstream parallelism and pays for one shuffle instead.

26. How does a broadcast join work, when do you avoid it, and what if neither side is small? [American Express, HCLTech, EPAM, Netflix, Azure-role interviews]

The driver collects the small side, builds a hash relation and sends it to every executor, so the large side joins locally with no shuffle. Spark picks it automatically below spark.sql.autoBroadcastJoinThreshold (10 MB by default), or when you add a broadcast() hint.

Avoid it when the “small” side is large after decompression, because it must fit in driver memory and in every executor. A forced hint on a wrong size estimate is a common source of driver OOM.

When neither side is small: filter and project both sides first, pre-aggregate if possible, bucket both tables on the join key to avoid the shuffle on repeated joins, and let AQE switch strategy at runtime once actual sizes are known.

27. Broadcasting vs bucketing, and partitioning vs bucketing. [KPMG, Azure-role interviews]

Partitioning splits a table into directories by column value, which lets queries skip directories. It suits low-cardinality filter columns like date.

Bucketing hashes a column into a fixed number of files per partition. Two tables bucketed the same way on the join key can sort-merge join with no shuffle. It suits high-cardinality join keys.

Broadcasting is a per-query choice for one small table. Bucketing is a layout choice paid once at write time for repeated large joins.

28. What are bloom filters, and how do they speed up joins? [American Express]

A bloom filter is a compact bit array that answers “definitely not present” or “possibly present”. Built from the join keys of the smaller side, it lets the larger side drop rows that cannot match before the shuffle. Spark added a runtime bloom-filter join optimisation in 3.3, controlled by spark.sql.optimizer.runtime.bloomFilter.enabled.

Parquet and Delta also use bloom filters on columns, for point lookups on high-cardinality fields that min/max statistics cannot prune.

29. Joining two large datasets runs out of memory. What do you do? [KPMG, Netflix, Azure-role interviews]

Find where it fails before changing anything. An executor OOM during a sort-merge join is usually skew: one key’s rows do not fit in one task. A driver OOM is usually a broadcast that was too large.

Then: remove a forced broadcast hint, filter and project before the join, check for a many-to-many key that multiplies rows, handle skew (AQE or salting), and raise shuffle partitions so each task holds less. Increasing executor memory is the last step, not the first.

Data skew

30. How do you identify data skew in the Spark UI? One task runs 45 minutes while the rest finish in 3. [Netflix, Comcast, Azure-role interviews]

In the stage’s task table, compare the max with the median for duration, shuffle read size and records. A max many times the median, on a stage that follows a shuffle, is skew. Spill on that one task confirms it.

Then find the key: df.groupBy(key).count().orderBy(desc("count")) usually shows one value, often a null or a default like 0 or UNKNOWN.

31. Fix skew: AQE skew join, salting, and what to do when AQE is disabled or one key holds 60% of the rows. [HCLTech, Coforge, American Express, HDFC Bank, PwC, Ford, HCA Healthcare]

AQE skew join (on by default since Spark 3.2) splits a shuffle partition that is both 5 times the median (skewedPartitionFactor) and larger than 256 MB (skewedPartitionThresholdInBytes) into smaller pieces, and replicates the matching partition from the other side. It only acts on sort-merge joins, and only above those thresholds.

Salting by hand: add a random salt 0..N-1 to the skewed side’s key, explode the other side’s matching rows N times with the same salt range, join on (key, salt), then aggregate.

Choosing N (HDFC asked this directly): roughly the hot key’s size divided by the target partition size. Too small leaves the hot partition hot; too large multiplies the other side by N for no benefit.

When one key is 60% of the data, check whether that key should be joined at all. If it is a null or placeholder, filter it out and union it back after the join. That is often the whole fix.

Memory and caching

32. cache() vs persist(): default storage levels, what happens when cached data does not fit, and how to release it. [HCLTech, Cognizant, Azure-role interviews]

cache() is persist() with the default level. For a DataFrame the default is memory and disk (PySpark shows it as MEMORY_AND_DISK_DESER); for an RDD it is MEMORY_ONLY. persist(level) lets you choose.

When it does not fit: with a memory-and-disk level, evicted blocks spill to local disk; with memory only, they are dropped and recomputed from lineage when next needed. Cached storage competes with execution memory in the unified pool, so caching too much slows shuffles.

Release with unpersist(). The follow-up: caching is lazy, so nothing is stored until an action runs over the cached DataFrame.

33. Spark memory management, driver vs executor memory, and why a job hits OOM despite enough cluster resources. [American Express, Netflix, Azure-role interviews]

Executor heap minus 300 MB reserved is split by spark.memory.fraction (0.6) into a unified pool shared by execution (shuffles, joins, sorts) and storage (cache). Execution can evict storage; storage cannot evict execution below spark.memory.storageFraction. Off-heap overhead (spark.executor.memoryOverhead) covers JVM internals, Python workers and network buffers.

OOM with ample cluster capacity is a per-task problem: one skewed partition, an oversized broadcast, collect() on the driver, or Python UDF workers exceeding overhead, which shows up as a container killed by YARN or Kubernetes rather than a Java heap error.

Performance and troubleshooting

34. A job that took 2 hours now takes 8 (or 3x or 4x longer). Walk through the investigation. [Wipro, Deloitte, TCS, Databricks, EY, Azure-role interviews]
  1. What changed? Input volume, code, cluster, configs, upstream schema. Most regressions are a change nobody announced.
  2. Compare the Spark UI for a good and a bad run, stage by stage. Find the stage whose time grew.
  3. In that stage, check input size, shuffle size, spill, task time distribution (skew), GC time and failed or retried tasks.
  4. Check the storage layer: small files accumulating, a partition filter that stopped pruning, a table growing without compaction.
  5. Fix the cause and verify on comparable data.

Interviewers listen for a hypothesis tested against evidence, not a list of tuning parameters.

35. A Spark job or streaming query gets slower over days or weeks. What do you look at? [Azure-role interviews, Netflix]

Things that grow without bound: the number of small files in the input table, streaming state size (no watermark, so state is never dropped), the checkpoint or metadata log, Delta or Iceberg metadata without maintenance, and an ever-growing lookup table that was once small enough to broadcast.

36. Too many small files: in a PySpark job, a streaming pipeline, or 50 billion files in an S3 lake. [Amazon, Comcast, Grab, HCLTech, Netflix]

Prevent: repartition by the table’s partition columns before writing, use optimised or auto-compacting writes, and give streaming triggers a sensible interval so each micro-batch writes fewer, larger files.

Repair: run compaction (OPTIMIZE in Delta, rewrite_data_files in Iceberg, clustering in Hudi) partition by partition. Table formats commit the rewrite atomically, so readers see old or new files and never a mix. That is how you get “no downtime”.

At 50 billion files, add that listing itself is the bottleneck. Moving to a table format replaces directory listing with a metadata scan, and compaction then runs in batches ordered by query value.

37. How do you size a cluster for 100 GB, optimise a 500 GB CSV, or cut Spark cost while holding the SLA? [Azure-role interviews, TCS, American Express, Cognizant]

Size from partitions: 100 GB at about 128 MB per task is roughly 800 tasks. A few waves of those across executors with 4 to 5 cores each sets the cluster size. Then check shuffle volume, which is often larger than input.

For a 500 GB CSV: give an explicit schema (inference reads the data twice), make sure the file is splittable (gzip is not), and convert to Parquet once if it will be read again.

For cost: autoscaling, spot or preemptible workers for stateless stages, file compaction so fewer tasks run, and removing unnecessary caching. Measure cost per run before and after.

Streaming and Kafka

38. How do you achieve exactly-once processing for payment events? [Paytm, Atlassian, Netflix]

Exactly-once is an end-to-end property, not a setting. In Structured Streaming it needs a replayable source (Kafka offsets), checkpointed progress, and an idempotent or transactional sink. Spark’s own Kafka sink is at-least-once, so writing back to Kafka needs downstream deduplication.

In practice: write to a Delta, Iceberg or Hudi table, whose commits are tied to the batch ID, or MERGE on the event ID. On the producer side, Kafka’s idempotent producer and transactions stop duplicates entering the topic.

39. Duplicate events in Kafka or a streaming job writing duplicates to Delta: how do you prevent and resolve them? [Paytm, Databricks, Netflix]

dropDuplicatesWithinWatermark (Spark 3.5+) or dropDuplicates on the event ID plus event time with a watermark, so state is bounded. Then make the write idempotent: MERGE on the event ID inside foreachBatch, or Delta’s txnAppId and txnVersion options so a replayed batch is skipped.

To repair existing duplicates, rewrite the affected partitions with a ROW_NUMBER() dedupe.

40. Event time vs processing time, out-of-order and late events, and watermarks. [Comcast, Paytm, Amazon, Netflix]

Event time is when it happened; processing time is when Spark saw it. Window aggregations should use event time, or a delayed batch puts events in the wrong window.

A watermark (withWatermark("event_ts", "2 hours")) tells Spark how late data may arrive. State older than the watermark is dropped, and events later than it are discarded.

For Amazon’s version (“30% of events arrive 45 minutes late”): either widen the watermark past 45 minutes and pay for the state, or keep a tight watermark for the real-time view and correct with a batch job that re-aggregates late data into the affected windows.

41. Checkpointing in Structured Streaming: what is in it, and what happens if the checkpoint directory is deleted? [HCLTech, Comcast]

The checkpoint holds the offset log (what each batch will read), the commit log (which batches completed) and the state store for stateful operators. Restart reads it to resume exactly where the query stopped.

Delete it and the query starts as new: offsets come from startingOffsets, so you reprocess or skip data, and all aggregation state is lost. Duplicates in a non-idempotent sink are the usual result.

42. Kafka consumer lag keeps growing, or a streaming job falls behind at peak. How do you troubleshoot? [Paytm, Netflix, Databricks]

Compare input rate with processing rate in the streaming query progress. If processing is slower: check for skew across Kafka partitions, too few partitions for the consumers, slow sinks, and state growth. Spark reads at most one task per Kafka partition unless minPartitions splits them.

Fixes: more topic partitions, maxOffsetsPerTrigger to bound batch size, a cheaper sink path, and scaling executors. A lag graph that grows steadily means capacity; a sawtooth means slow batches.

43. Batch vs micro-batch vs continuous streaming, and how to choose batch or streaming. [Databricks, Ford, PayPal, Tiger Analytics, Atlassian]

Micro-batch (the Structured Streaming default) runs small batches with second-level latency and exactly-once with a suitable sink. Continuous processing targets millisecond latency, but supports only map-like operations with at-least-once guarantees, and is rarely used.

Choose streaming when the consumer acts on data within minutes. Otherwise a scheduled batch is cheaper and easier to backfill. Many teams run streaming with availableNow triggers to get streaming semantics at batch cost.

44. Find users who viewed the same product three times in one hour without purchasing. [Amazon]

Aggregate views by (user, product) over a one-hour event-time window, keep counts of three or more, and anti-join against purchases for the same (user, product) and window. In streaming, a watermark bounds the state.

Clarify “one hour”: tumbling windows miss three views that straddle a boundary, so a sliding window or a session-style range check is the honest answer.

Lakehouse and table formats

45. How does Delta Lake provide ACID transactions and handle concurrent reads and writes without locks? [Databricks, PwC, Infosys, Cognizant]

Every change is a new JSON commit file in _delta_log, numbered in sequence. A table version is the result of replaying commits, with Parquet checkpoints every so often to keep that fast.

Readers pick a version and read exactly its files, so they never see a partial write. Writers use optimistic concurrency: they write data files, then try to create the next commit file atomically. If another writer took that version first, Delta checks whether the two touched conflicting files, and either retries or fails with a ConcurrentModificationException subclass.

46. Time travel, OPTIMIZE, VACUUM and Z-ordering in Delta. [Databricks, KPMG, Capgemini]
  • Time travel: VERSION AS OF or TIMESTAMP AS OF reads an old version, for audits, reproducing a report or undoing a bad write with RESTORE.
  • OPTIMIZE: compacts small files into larger ones.
  • Z-order: OPTIMIZE ... ZORDER BY (col) co-locates values so file-level statistics skip more files on filters.
  • VACUUM: deletes files no longer referenced by any version within the retention period, 7 days by default.

The trap: VACUUM below the retention period removes the files time travel needs, and can break long-running readers.

47. A Delta table has grown to several terabytes and reads are slow. Why, and how do you fix it? [Databricks, EPAM]

Check in this order: small files (count files per partition), filters that do not match the partitioning or clustering, stale or missing column statistics, a long transaction log without recent checkpoints, and wide rows read in full.

Fixes are compaction, clustering or Z-ordering on the common filter columns, selecting fewer columns, and moving partitioning off high-cardinality columns.

48. Delete individual rows in Delta without rewriting whole files, and how data skipping differs from SQL indexes. [HCLTech]

Deletion vectors mark deleted rows in a small sidecar file, so a DELETE touches only metadata, and the rewrite happens later during compaction. Without them, Delta rewrites every file containing a deleted row (copy-on-write).

Data skipping uses per-file min/max statistics in the transaction log to skip whole files. Unlike a B-tree index it does not locate individual rows; it only works when values are clustered across files, which is why it pairs with Z-ordering.

49. Delta Lake vs Hudi vs Iceberg, and Parquet vs ORC vs Avro. [Goldman Sachs]
  Delta Lake Apache Hudi Apache Iceberg
Metadata Ordered JSON log with checkpoints Timeline of instants Snapshot, manifest list, manifests
Strength Spark and Databricks integration Upserts, record-level index, incremental pulls Engine neutrality, hidden partitioning, partition evolution
Row updates Copy-on-write or deletion vectors Copy-on-write or merge-on-read Copy-on-write or delete files

Parquet and ORC are columnar and suit analytics. Avro is row-based with an embedded schema and suits streaming and record exchange. The format choice is about the workload, not a ranking. The open table formats comparison goes further.

50. Auto Loader vs COPY INTO, Medallion architecture, and Unity Catalog. [Coforge, Databricks, EPAM, Capgemini, HCA Healthcare]
  • COPY INTO is an idempotent SQL load that skips files it already loaded. It suits thousands of files arriving in batches.
  • Auto Loader (cloudFiles) is a streaming source that discovers new files incrementally, with schema inference and evolution. It suits continuous arrival and millions of files.
  • Medallion: Bronze keeps raw data for replay, Silver holds cleaned and deduplicated data, Gold holds business aggregates. The point is recoverability: a Silver bug is fixed by reprocessing from Bronze, not by re-pulling the source.
  • Unity Catalog: one governance layer for tables, files and models across workspaces, with grants, lineage and audit.

Data modeling and warehousing

51. Implement SCD Type 2 with MERGE or in PySpark, and explain Types 1, 2 and 3. [Coforge, HDFC Bank, Deloitte, Ford, Wipro, Infosys, TCS, Capgemini, Databricks, Microsoft, Azure-role interviews]

Type 1 overwrites, Type 2 keeps history with a new row per change, Type 3 adds a “previous value” column.

Type 2 in one MERGE needs the staged-union trick: the change rows appear twice, once with the real key (to match and close the current row) and once with a null merge key (so they fall through to the insert branch):

MERGE INTO dim_customer t
USING (
  SELECT s.customer_id AS merge_key, s.* FROM staged s
  UNION ALL
  SELECT NULL AS merge_key, s.* FROM staged s
  JOIN dim_customer d ON s.customer_id = d.customer_id
  WHERE d.is_current AND s.address <> d.address) u
ON t.customer_id = u.merge_key AND t.is_current
WHEN MATCHED AND t.address <> u.address THEN
  UPDATE SET is_current = false, end_date = u.effective_date
WHEN NOT MATCHED THEN
  INSERT (customer_id, address, effective_date, end_date, is_current)
  VALUES (u.customer_id, u.address, u.effective_date, NULL, true);

Follow-ups: compare a hash of tracked columns rather than each column, handle nulls in the comparison (use <=>), and decide what happens to late changes that arrive out of order.

52. Star vs snowflake schema, normalization vs denormalization, and many-to-many relationships in a star schema. [PwC, KPMG, Tiger Analytics, PayPal, HCLTech]

A star schema has denormalised dimensions joined directly to the fact, which means fewer joins and simple BI queries. A snowflake normalises dimensions into sub-dimensions, which saves storage and keeps hierarchies consistent but costs joins. Lakehouse BI generally favours star.

Many-to-many (an account with several holders) goes through a bridge table between fact and dimension, with a weighting factor if measures must not be double-counted. The data modeling guide covers grain and fact types.

53. Data lake vs warehouse vs mart vs lakehouse, and when to choose an RDBMS, NoSQL, a lake or a warehouse. [Wipro, TCS, PwC, Infosys, Grab, KPMG]

A lake stores raw files of any shape cheaply. A warehouse stores modelled, governed tables for SQL. A mart is a subject-specific slice of the warehouse. A lakehouse puts table formats on lake storage to get warehouse guarantees (ACID, schema, time travel) without copying data into a separate system.

Choose an RDBMS for transactional consistency and point lookups, NoSQL (DynamoDB, Cassandra) for key-value access at high write rates, and a lake or warehouse for scans and aggregation.

54. Design data models: retail sales by product, vendor, location and time; ride-sharing metrics; a real-time analytics model. [Amazon, Grab, Microsoft]

Start with the grain: one row per order line, or per ride. The fact holds measures (quantity, revenue, duration), and dimensions are product, vendor, store, date and customer. Name additive versus non-additive measures. Ratios like average ride duration are computed, not stored.

Then answer the follow-ups the interviewer will ask: which dimensions change (SCD), how to partition the fact (by date), and what changes at a billion rows (clustering on the common filter keys, pre-aggregated rollups).

55. Count distinct phone numbers over the last 90 or 180 days from a 100M-row table snapshotted daily, without scanning everything. [HDFC Bank]

Do not scan 180 full snapshots. Build an incremental table of first-seen and last-seen dates per phone number, updated daily from the latest snapshot only. A 90-day count is then a filter on last_seen >= current_date - 90.

If approximate is acceptable, keep a daily HyperLogLog sketch per day and merge 90 of them. Either way, the insight is to change the storage design so the query becomes cheap.

Pipeline design and reliability

56. A pipeline fails halfway, or loads twice after a retry. How do you make it idempotent? [Coforge, EY, Amazon, Netflix, Atlassian, Ford]

Running a step twice must give the same result as running it once:

  • Overwrite by partition, not append: INSERT OVERWRITE the day you are loading, or Delta’s replaceWhere.
  • MERGE on a business key for upserts.
  • Commit atomically. Write to a staging location and swap, or rely on the table format’s commit, so a half-finished run leaves nothing visible.
  • Track what was processed: a watermark or batch ID table updated in the same transaction as the data.

For “the same financial transaction arrives twice” (Amazon), the key is a natural or producer-assigned transaction ID with a uniqueness check at write.

57. Incremental loading and CDC, including the case with no primary key and no timestamp. [PwC, Ford, Microsoft, Wipro, Infosys, EPAM, Cognizant, KPMG]

With a reliable updated_at, store the high-water mark and pull rows above it, with a small overlap to catch clock skew. With log-based CDC (Debezium, ADF CDC, database change feeds), read the change stream with operation types and apply it with MERGE.

With no key and no timestamp (EPAM), compute a hash of each full row, compare the current extract with the previous one, and treat new hashes as inserts and missing hashes as deletes. It costs a full extract each time, so say that the real fix is asking the source owner for a change column.

58. Late-arriving data in a table that has already been aggregated, or late cancellations in a Gold table. [Cognizant, Coforge, Walmart, Ford, PayPal, Tiger Analytics, Microsoft, Atlassian]

Store data by event date, not load date. Each run re-aggregates every event date touched by newly arrived records, not just “yesterday”, and overwrites those Gold partitions.

Keep a lookback window (for example, recompute the last 7 days every run) when late arrival is routine, and a targeted backfill for rare very late data. For dimensions that arrive after their facts, insert a placeholder dimension row and update it when the real one lands.

59. Handle schema drift and schema evolution without breaking downstream consumers. [Microsoft, Walmart, Ford, HCLTech, PwC, Netflix, Azure-role interviews]

Separate tolerant ingestion from strict consumption. Bronze accepts new columns (schema evolution on write, or keep the raw payload in a string or VARIANT column). Silver and Gold have explicit contracts.

Additive changes (a new nullable column) can flow through automatically. Breaking changes (rename, type narrowing, dropped column) should fail loudly at a validation step and alert, rather than silently produce nulls downstream. Mention a schema registry for streaming sources and data contracts with producers.

60. Data quality and reconciliation: source has 1 million rows, target has 990,000. Find out why. [Data QA interviews, Walmart, Wipro, Databricks, Deloitte, Ford]

Reconcile stage by stage: counts and key sums at extract, Bronze, Silver and Gold. The stage where counts diverge locates the problem. Then check that stage’s filters, join types (an inner join to a dimension with missing keys is the classic loss), deduplication rules, rejected-record outputs and watermark logic.

Identify the missing keys with an anti-join of source against target, and group them by an attribute to find the pattern. For ongoing checks: row-count, null-rate, uniqueness and freshness assertions that fail the pipeline, not just a dashboard.

61. A pipeline succeeds but the business metrics are wrong, or reports changed after a deployment. How do you debug it? [Netflix, Walmart, Wipro, Databricks]

Treat it as a correctness incident. Pin down which metric, since when, and by how much. Diff the output of the previous code version and the new one on the same input. Most such bugs are join fan-out (duplicates multiplying a sum), a filter change, timezone handling at day boundaries, or a changed upstream definition.

Then prevent recurrence with a regression test that compares key metrics on a fixed sample before deploy.

62. Data lineage and audit: track transformations across an eight-stage pipeline. [Wipro, Deloitte, Goldman Sachs, HCA Healthcare]

Capture lineage automatically rather than documenting it: OpenLineage events from Spark and Airflow, or a catalog such as Unity Catalog that records table- and column-level lineage. Add run metadata (job ID, code version, input snapshot IDs) as columns or in an audit table, so any output row can be traced to the run and inputs that produced it.

63. Migrate an on-premise warehouse (Oracle, 500 TB, 10 years of history) to the cloud with minimal or zero downtime. [Deloitte, Walmart, Amazon]
  1. Bulk-copy history from a consistent snapshot, partitioned by date, and validate each partition with counts and checksums.
  2. Start CDC from the snapshot point so the target stays current.
  3. Run both systems in parallel and reconcile key reports daily.
  4. Cut consumers over in waves, starting with read-only analytics, and keep the old system as a rollback until sign-off.

Mention transfer limits (500 TB over the network may need a physical transfer appliance), type mapping differences, and who signs off on reconciliation.

64. System design: process billions of payment transactions a day, with real-time fraud detection. [Paytm, Databricks, PayPal, Wipro]

Shape the answer around the two consumers. Producers write to Kafka with an idempotent producer, keyed by account so per-account ordering holds. A streaming job scores transactions against features held in a low-latency store, and emits alerts. A separate path lands every event in a lakehouse table for reporting and model training, with MERGE on the transaction ID.

Cover: partitioning by account, out-of-order events, exactly-once writes, replay from Kafka retention, PII handling, and reconciliation with the core banking ledger.

65. System design: one architecture for real-time order status and hourly analytics at 500 million orders a day. [Amazon, Coforge, Walmart, Ford, Grab, Comcast]

Use a single event log (Kafka or Kinesis) with two consumers. A streaming job maintains current status per order in a key-value store for customer lookups. A second streaming or micro-batch job appends events to a lakehouse table partitioned by event hour, with hourly aggregates built on top.

At about 6,000 orders per second on average, size for peak, not average. Discuss late events, idempotent upserts into the status store, and replaying from the log to rebuild either side.

66. Design a multi-tenant data platform, or a reusable ETL framework for 20 clients with different schemas. [Databricks, TCS, Deloitte]

Make the pipeline metadata-driven: one engine, with per-client configuration for source, schema mapping, rules and schedule stored in tables, not code. Isolate tenants by catalog or schema with separate permissions, and tag compute for cost attribution.

The trade-off to name: a shared framework cuts duplicated code but makes one client’s special case everyone’s risk. Version the framework, and allow plug-in transforms for exceptions.

67. Storage cost is exploding because the same purchase history is read 50 times a day by different jobs. [Amazon]

The problem is repeated computation, not storage. Find the common transformation those 50 jobs perform, materialise it once as a curated table (or materialised view) partitioned and clustered for their access patterns, and point the jobs at it. Then tier cold history to cheaper storage classes.

Back it with numbers: bytes scanned per day before and after.

68. What do you check before calling a pipeline production-ready, and how do you handle a 2 AM failure? [HCA Healthcare, Capgemini, Infosys, KPMG, PwC]

Production-ready means: correct output validated against a source, idempotent reruns, alerts on failure and on lateness, data-quality checks, a documented backfill procedure, least-privilege access, and known cost per run.

For the 2 AM failure: read the error and the failing step, check whether upstream data arrived, check recent changes, rerun safely if the cause was transient, and communicate the impact on downstream SLAs. Write up the root cause afterwards.

Cloud services

Azure

69. Azure IR vs self-hosted IR, integration runtime vs linked service, and Copy Activity vs Data Flows. [PwC, HDFC Bank, HCLTech]

A linked service is connection information (where and how to connect). An integration runtime is the compute that runs the activity. The Azure IR is managed and reaches public or managed-private endpoints. A self-hosted IR is installed on your own machines to reach on-premise or private-network sources. An Azure-SSIS IR runs SSIS packages.

Copy Activity moves data and is billed by data integration units and time. Mapping Data Flows run transformations on a managed Spark cluster, with cluster start-up time and per-core billing, so they cost more for simple copies.

70. An ADF pipeline is stuck in Queued, or fails every Monday at 6 AM but runs fine otherwise. Investigate. [PwC, Cognizant]

Queued usually means it is waiting for capacity: pipeline or activity concurrency limits reached, a self-hosted IR node offline or saturated, or waiting on a dependency.

Monday-only failures point at what is different on Mondays: a larger weekend backlog, a source system maintenance window, a credential or certificate rotated over the weekend, or another job scheduled at the same time competing for the same IR. Compare the Monday run’s inputs and timing with a good Tuesday run.

71. Secrets, masking and row-level security on Azure: Key Vault, dynamic data masking, Synapse RLS, and infrastructure as code. [PwC, HCLTech, Cognizant]

Keep secrets in Key Vault and reference them from linked services and Databricks secret scopes, accessed with managed identities so no credential is in code. Dynamic data masking hides values at query time for unprivileged users. Row-level security uses a predicate function bound to a security policy to filter rows per user or client. Define all of it with Bicep or Terraform so environments are reproducible and reviewed.

72. Azure Databricks vs Synapse, and an end-to-end Blob → ADF → Databricks → Synapse → Power BI pipeline with its failure points. [EY, Cognizant]

Databricks suits Spark engineering, streaming and ML on Delta. Synapse dedicated SQL pools suit a warehouse-first team with T-SQL skills. Many architectures use Databricks to transform and a SQL serving layer for BI.

Failure points by stage: file arrival and partial files (Blob), IR capacity and credentials (ADF), cluster start-up, skew and schema changes (Databricks), load concurrency and statistics (Synapse), and refresh timeouts (Power BI). Each needs its own alert.

GCP

73. BigQuery partitioning vs clustering, cost reduction, and MERGE. [Capgemini, HCA Healthcare, GCP-role interviews]

Partitioning (by date, ingestion time or integer range) prunes whole partitions and makes cost predictable. Clustering sorts data within partitions by up to four columns, so filters on them read fewer blocks. Cost is driven by bytes scanned: select only needed columns, require partition filters, and use materialised views for repeated aggregates. MERGE in BigQuery follows standard SQL with WHEN MATCHED and WHEN NOT MATCHED clauses.

74. Airflow and Composer: operators, and what to do when upstream data has not arrived while the DAG is running. [HCA Healthcare, Capgemini, Walmart]

Operators are the task types: they wrap an action (run a query, submit a Dataproc job, call an API) so a DAG is configuration, not custom code. For missing upstream data, use a sensor (in deferrable mode, so it does not hold a worker slot) with a timeout, alert when it times out, and keep downstream tasks from running on partial data. Rerunning must be idempotent.

AWS

75. S3 storage classes, moving data between tiers, and DynamoDB vs RDS. [KPMG, AWS-role interviews]

S3 offers Standard, Intelligent-Tiering, Standard-IA, One Zone-IA and the Glacier classes (Instant Retrieval, Flexible Retrieval, Deep Archive). Lifecycle rules move objects by age automatically. Watch the minimum storage durations and retrieval charges on the infrequent and archive tiers.

DynamoDB is a managed key-value store for predictable single-digit-millisecond access at any scale. RDS is a managed relational database for joins and transactions.

Behavioural and managerial rounds

These came up at nearly every company with a managerial round (PwC, KPMG, Deloitte, Cognizant, TCS, Infosys, Atlassian, Amazon, PayPal). The questions merge into eight:

  1. Walk through one end-to-end project: design, your decisions, challenges and impact.
  2. Tell me about a production failure you owned and what you changed afterwards.
  3. A technical decision you disagreed with. What evidence did you use?
  4. A time you took ownership beyond your role.
  5. How you handle conflicting requirements from stakeholders.
  6. Delivering under a tight deadline: what you cut, and the consequence.
  7. Explaining a technical problem (for example, data lag) to a non-technical client.
  8. A teammate’s mistake caused data loss. How do you handle it?

Prepare two or three real stories and adapt them, rather than one answer per question. Use situation, action and result, and put a number in the result. Amazon’s bar raiser will test each story against its leadership principles, so expect “what data did you use” and “what would you do differently” follow-ups.

How to prepare from this list

Start with the frequency table. Window functions, skew, idempotency, late data and incremental loads appear at most companies. Being solid on those five covers most rounds.

Prepare by company type. For product companies, practise designing systems out loud and coding without an IDE. For services and consulting firms, know Azure Data Factory and Databricks operationally, implement SCD Type 2 from memory, and prepare the managerial stories.

Answer scenarios with evidence. For every “it became slow” or “the numbers are wrong” question, the structure is the same: what changed, where you look, what you found, what you fixed, and how you verified it. That structure is what these interviews reward.

Do not memorise answers. Interviewers change one condition (“now the key is null”, “now there is no timestamp”) and watch whether the answer adapts. Every outline above names the mechanism so you can reason from it.

References

Trademarks

Apache Spark, Apache Kafka, Apache Hudi, Apache Iceberg, Apache Airflow, Apache Parquet, Apache ORC, Apache Avro and Apache are either registered trademarks or trademarks of The Apache Software Foundation in the United States and other countries. Delta Lake is a trademark of the Linux Foundation. Databricks and Unity Catalog are trademarks of Databricks, Inc. Azure, Synapse and Power BI are trademarks of Microsoft Corporation. BigQuery and Google Cloud are trademarks of Google LLC. Amazon S3, Amazon Kinesis and DynamoDB are trademarks of Amazon.com, Inc. or its affiliates. Company names are used only to identify where questions were reported.

Found this useful?

These posts and tools are free. If one saved you an afternoon, you can buy me a coffee.

Buy me a coffee