← Databricks Interview Insights

Databricks·Software Engineer·Onsite - System Design / Architecture·Senior

Senior
Jul 2026

Summary

Databricks system design round focused entirely on building a versioned, snapshot-capable set data structure from scratch. The question had a lot of moving parts and the design discussion went deep fast.

Questions Asked (4)

Q1

Design a SnapshotSet data structure supporting add, remove, contains, snapshot (returning a snapshot ID), and iterate over a past snapshot. It needs to handle many concurrent snapshots while the live set keeps changing, with O(log n) updates and O(1) amortized iterator next.

System DesignAlgorithms & Data StructuresTechnical Trade-offs
Author's notes

This one sprawled in ways I didn't expect.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements and constraints, then propose a versioned data structure like a persistent balanced BST or a copy-on-write approach with reference counting. Explain how snapshots are created in O(1) by capturing the current root, and how iteration over a snapshot works in O(1) amortized per element using an iterator that traverses the immutable version.

Pro tip: Emphasize that snapshots are immutable and share structure with the live set, so memory overhead is proportional to changes, not snapshot count. Also, discuss how to handle concurrent modifications safely, perhaps using a lock-free or fine-grained locking scheme.

1. Clarify Requirements and Constraints

Ask about concurrency level, snapshot lifetime, memory constraints, and whether snapshots can be garbage collected. Confirm that updates are O(log n) and iterator next is O(1) amortized.

2. Choose a Core Data Structure

Propose a persistent balanced BST (e.g., red-black tree) or a copy-on-write hash trie. Explain how each update creates a new version with path copying, giving O(log n) updates and O(1) snapshot creation.

3. Design Snapshot and Iteration

Snapshots are represented by a reference to the root of the version. Iteration uses an iterator that traverses the immutable tree, yielding elements in O(1) amortized time per next() via an explicit stack.

4. Handle Concurrency and Memory

Use atomic reference counting or epoch-based reclamation to manage memory of old versions. For concurrency, use a read-write lock or lock-free techniques to allow concurrent reads and snapshots while updates proceed.

5. Analyze Trade-offs and Optimizations

Discuss trade-offs: persistent trees have higher constant factors but guarantee O(log n) updates; copy-on-write arrays are simpler but may have O(n) worst-case updates. Mention possible optimizations like path compression or batching.

Key Points to Mention

  • Persistent data structures (e.g., balanced BST, hash trie) enable O(log n) updates and O(1) snapshot creation via structural sharing.
  • Snapshots are immutable; iteration over a snapshot uses an iterator that traverses the version's root, achieving O(1) amortized next().
  • Memory management: reference counting or epoch-based reclamation to free old versions when no longer needed.
  • Concurrency: use fine-grained locking or lock-free algorithms to allow concurrent snapshots and updates without blocking.
  • Trade-offs: persistent trees have overhead but meet complexity; alternatives like copy-on-write may not meet O(log n) updates.
  • Garbage collection of snapshots: provide a way to release snapshots to reclaim memory.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

Walk through the memory usage and snapshot reclamation strategy for your design. How do you free memory from old snapshots that are no longer referenced?

System DesignTechnical Trade-offs
Author's notes

Talked about reference counting on shared nodes and a registry that tracks which snapshot IDs are still alive.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by outlining the overall memory architecture and how snapshots are represented, then explain the lifecycle of a snapshot from creation to reclamation. Focus on the mechanisms for detecting unreferenced snapshots and safely freeing their memory, while highlighting trade-offs between eager and lazy reclamation.

Pro tip: Emphasize the importance of reference counting or mark-and-sweep with epoch-based reclamation to avoid use-after-free bugs, and mention how Databricks' Delta Lake uses time travel and vacuum to manage snapshot retention.

1. Describe snapshot representation

Explain how snapshots are stored in memory (e.g., metadata, data blocks, indexes) and how they reference shared data structures. Mention copy-on-write or persistent data structures if applicable.

2. Explain reference tracking

Detail how the system tracks which snapshots are still referenced (e.g., by active queries, transactions, or time-travel queries). Discuss reference counting, epoch-based reclamation, or garbage collection roots.

3. Outline reclamation triggers

Describe when reclamation occurs: periodically, on memory pressure, or explicitly via a vacuum command. Mention how you balance eager reclamation (freeing memory quickly) vs. lazy reclamation (deferring to avoid overhead).

4. Detail safe reclamation process

Explain the steps to safely free memory: identify unreferenced snapshots, ensure no concurrent access (e.g., using epochs or locks), and deallocate memory. Highlight how to avoid race conditions and use-after-free.

5. Discuss trade-offs and optimizations

Cover trade-offs: memory overhead vs. reclamation latency, impact on query performance, and how to handle long-running queries. Mention optimizations like incremental reclamation or background compaction.

Key Points to Mention

  • Reference counting vs. mark-and-sweep for snapshot liveness tracking
  • Epoch-based reclamation to handle concurrent readers safely
  • Copy-on-write and persistent data structures to minimize duplication
  • Time travel and retention policies (e.g., Delta Lake's vacuum with retention threshold)
  • Memory pressure triggers and backpressure mechanisms
  • Trade-offs between eager reclamation (low memory, higher overhead) and lazy reclamation (higher memory, lower overhead)

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

What are the trade-offs between copy-on-write, a persistent balanced tree, and versioned hash buckets for this use case?

Technical Trade-offsSystem DesignAlgorithms & Data Structures
Author's notes

Copy-on-write is simple but O(n) per snapshot if the set is large.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the use case and its requirements (e.g., read/write ratio, concurrency, versioning needs, memory constraints). Then compare the three data structures across key dimensions such as time/space complexity, concurrency, persistence, and implementation complexity, and conclude with a recommendation tailored to the use case.

Pro tip: At Databricks, emphasize how these structures support ACID transactions and snapshot isolation in a distributed setting, and mention Delta Lake's use of copy-on-write and persistent trees for metadata management.

1. Clarify the use case

Ask questions to understand the specific requirements: expected read/write ratio, concurrency level, need for versioning or snapshots, memory constraints, and persistence requirements.

2. Define evaluation criteria

Establish dimensions for comparison: time complexity (read, write, update), space overhead, concurrency support, ease of implementation, and suitability for persistence/versioning.

3. Analyze each structure

For each option, describe its characteristics and trade-offs. For example, copy-on-write is simple but can be space-inefficient; persistent balanced trees offer O(log n) operations with structural sharing; versioned hash buckets provide O(1) average access but may have overhead for versioning.

4. Compare and contrast

Directly compare the structures on the criteria, highlighting scenarios where each excels or falls short. Use concrete examples if possible.

5. Recommend and justify

Based on the use case, recommend one approach (or a hybrid) and justify why it best meets the requirements, acknowledging any remaining trade-offs.

Key Points to Mention

  • Copy-on-write: simplicity, snapshot isolation, but high write amplification and space overhead.
  • Persistent balanced trees (e.g., immutable AVL or red-black trees): O(log n) operations, structural sharing, good for versioned data, but higher constant factors and complexity.
  • Versioned hash buckets: O(1) average access, but versioning can lead to many buckets or require garbage collection; may not support ordered traversal.
  • Concurrency: copy-on-write and persistent trees allow lock-free reads, while versioned hash buckets may need synchronization for writes.
  • Use case alignment: Databricks often deals with large-scale data and ACID transactions, so structures that support snapshot isolation and efficient versioning are valuable.
  • Hybrid approaches: e.g., using persistent trees for metadata and hash buckets for data, or combining copy-on-write with persistent structures.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q4

Describe the unit tests you would write for this data structure, specifically covering an empty set, deletions before and after a snapshot, and concurrent mutation during iteration.

Algorithms & Data StructuresAPI & Integrations
Author's notes

The concurrent mutation case is the interesting one.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the data structure's semantics (e.g., persistent/immutable set with snapshot isolation) and the expected behavior under concurrent access. Then structure your answer around the three scenarios, describing specific test cases, assertions, and edge conditions for each. Emphasize how you would use deterministic concurrency control (e.g., latches, barriers) to reliably reproduce race conditions.

Pro tip: Mention that you would test not only functional correctness but also invariants like memory safety and absence of data races using tools like ThreadSanitizer or stress tests with randomized interleavings. This shows you think about production reliability, which is crucial at Databricks.

1. Clarify the data structure and its contract

Ask or state the expected semantics: is it a persistent set with snapshots? What are the guarantees for concurrent iteration? This ensures your tests target the right behavior.

2. Test empty set behavior

Write tests for an empty set: size, contains, iteration, snapshot creation, and deletion attempts. Verify no exceptions and correct empty results.

3. Test deletions before and after snapshot

Create a set, take a snapshot, delete elements, and verify the snapshot remains unchanged while the live set reflects deletions. Also test deletions before snapshot to ensure snapshot captures the correct state.

4. Test concurrent mutation during iteration

Simulate concurrent iteration and mutation using threads, barriers, or latches. Assert that iteration either sees a consistent snapshot or throws a well-defined exception (e.g., ConcurrentModificationException) based on the contract.

5. Summarize and discuss edge cases

Wrap up by mentioning additional edge cases like multiple snapshots, nested iterations, and stress tests with high contention to ensure robustness.

Key Points to Mention

  • Snapshot isolation: deletions after snapshot should not affect the snapshot's view.
  • Empty set edge cases: operations like delete, contains, and iteration should behave gracefully.
  • Concurrent modification detection: use versioning or fail-fast iterators, and test that the expected exception is thrown.
  • Deterministic concurrency testing: use CountDownLatch, CyclicBarrier, or Phaser to control thread interleavings.
  • Invariant checking: after each operation, verify size, uniqueness, and consistency between live set and snapshots.
  • Tooling: mention ThreadSanitizer, stress tests, or property-based testing for concurrency.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.