Skip to content
Reliable Data Engineering
Lesson
Open in the interactive app

Delta Lake and the Databricks Platform

A practical map of the features senior Databricks interviews probe, with the “why” behind each.


1. Delta Lake features you must know

FeatureWhat it doesInterview angle
ACID transaction logAtomic commits, snapshot isolationHow concurrency works (optimistic), conflicts
Time travelVERSION AS OF, TIMESTAMP AS OF, RESTORERecovery from bad writes; limited by VACUUM retention
MERGEUpserts, deletes, SCDPerformance: partition/cluster predicates in ON clause
Schema enforcement & evolutionReject mismatches; mergeSchema, ALTER TABLE ADD COLUMNS; column mapping for renames/dropsContracts vs flexibility
Change Data Feed (CDF)Row-level changes between versions (_change_type)Incremental downstream processing without full scans
Deletion vectorsMark deleted rows without rewriting filesFast DELETE/UPDATE/MERGE; physical purge later (GDPR)
Liquid clusteringIncremental, changeable clustering keysReplaces partitioning + Z-order for most tables
OPTIMIZE / VACUUMCompaction / remove unreferenced filesScheduling, retention vs time travel
ConstraintsNOT NULL, CHECKData quality at write time
Generated / identity columnsComputed columns, surrogate keysIdentity columns serialise inserts on concurrent writers
UniFormExpose Iceberg (and Hudi) metadataInterop with other engines

Incremental processing with CDF

changes = (spark.readStream
           .option("readChangeFeed", "true")
           .option("startingVersion", 120)
           .table("silver.orders"))
# rows carry _change_type in (insert, update_preimage, update_postimage, delete), _commit_version

2. Structured Streaming on Delta

flowchart LR
    SRC[Kafka / AutoLoader / Delta table] --> Q[Streaming query<br/>micro-batches]
    Q -->|checkpoint: offsets + state| CK[(Checkpoint location)]
    Q -->|idempotent commit per batch| SINK[(Delta table)]
    SINK --> DOWN[Downstream stream / batch readers]
ConceptKey points
TriggersprocessingTime="1 minute", availableNow=True (process all available then stop: incremental batch), continuous/real-time mode for low latency
CheckpointsStore source offsets, state, sink commit info. Never share between queries; changing the query logic may require a new checkpoint
Exactly-onceReplayable source + checkpoint + Delta sink’s idempotent commits (txnAppId/txnVersion); foreachBatch needs your own idempotency (MERGE)
foreachBatchArbitrary batch logic per micro-batch (MERGE, multiple sinks)
Watermarks & stateBound state for aggregations, dedup (dropDuplicatesWithinWatermark), stream-stream joins; RocksDB state store for large state
Schema evolutionAutoLoader schemaEvolutionMode; restart stream on new columns (by design)
Rate limitingmaxFilesPerTrigger, maxBytesPerTrigger, maxOffsetsPerTrigger

3. Lakeflow Declarative Pipelines (formerly Delta Live Tables)

Declarative pipelines: you declare tables/views and their queries; the platform handles orchestration, dependencies, retries, checkpoints, scaling and data quality.

CREATE OR REFRESH STREAMING TABLE bronze_orders
AS SELECT * FROM STREAM read_files('/landing/orders', format => 'json');

CREATE OR REFRESH STREAMING TABLE silver_orders (
  CONSTRAINT valid_amount EXPECT (amount >= 0) ON VIOLATION DROP ROW,
  CONSTRAINT has_id       EXPECT (order_id IS NOT NULL) ON VIOLATION FAIL UPDATE
) AS SELECT * FROM STREAM bronze_orders;

CREATE OR REFRESH MATERIALIZED VIEW gold_daily_revenue
AS SELECT order_date, SUM(amount) AS revenue FROM silver_orders GROUP BY order_date;

4. Unity Catalog

flowchart TB
    MS[Metastore per region] --> C1[Catalog: sales_prod]
    MS --> C2[Catalog: finance_prod]
    C1 --> S1[Schema: silver]
    C1 --> S2[Schema: gold]
    S2 --> T[Tables, views, volumes,<br/>functions, models]
    UC["Governance: GRANTs, tags, ABAC policies,<br/>row filters, column masks, lineage,<br/>audit logs, system tables"] -.-> MS

5. Compute and cost

ComputeUse
Job clusters / serverless jobsProduction pipelines (isolated, terminate after run)
All-purpose clustersInteractive development (don’t run prod on them)
SQL warehouses (serverless/pro)BI and SQL workloads
PhotonVectorised C++ engine: large speedups for SQL/DataFrame workloads; costs more per DBU, so check the job actually benefits

Cost levers: auto-termination, autoscaling, spot workers, right-sized node types, serverless for spiky loads, predictive optimization (automatic OPTIMIZE/VACUUM), cluster policies, tagging + system billing tables for chargeback.

6. Workflows (Lakeflow Jobs)

Multi-task jobs (notebooks, Python wheels, SQL, dbt, pipelines), task dependencies, retries, repair runs (re-run only failed tasks), parameters, file-arrival and table-update triggers, and Asset Bundles (databricks.yml) for CI/CD of jobs, pipelines and their configuration as code.

7. Interview questions

MERGE into a 5 TB Delta table takes an hour. How do you speed it up?

Reduce the target files touched: add partition/cluster predicates to the ON clause (e.g. t.event_date >= current_date() - 3), cluster the target by the merge key, enable deletion vectors (cheaper updates), dedupe the source first (duplicate source keys cause errors or extra work), make the source small (only changed rows, e.g. from CDF), ensure the source can be broadcast, and compact small files. Check the MERGE metrics (files scanned/rewritten).

availableNow trigger vs a normal batch job?

availableNow runs a streaming query that processes everything new since the last checkpoint and then stops. You get incremental processing with exactly-once bookkeeping (checkpointed offsets, AutoLoader file tracking) on a batch schedule, and switching to continuous later means changing one line. A plain batch job must track “what’s new” itself.

How does Unity Catalog lineage help in an incident?

It shows upstream sources and downstream consumers of a table/column automatically: find the root cause (which upstream changed), assess blast radius (which dashboards/models/jobs read it), and notify owners. System tables make this queryable.

Liquid clustering vs partitioning: which for a new 10 TB events table?

Liquid clustering on the common filter columns (e.g. event_date, customer_id). It avoids small-file problems from over-partitioning, handles high-cardinality keys, clusters incrementally, and the keys can change later without a full rewrite. Partitioning only makes sense for very large tables with a clear, low-cardinality filter, or for lifecycle management (dropping old partitions).