Debug a Random Dasher Registry

Read the full interview experience this question came from →

Quick Overview

Debug a random dasher registry backed by a dense array and an ID-to-index map. Repair empty and swap-delete edge cases, preserve representation invariants, narrow error handling, and extend the design for concurrency and slow dependencies.

Debug a Random Dasher Registry

Company: DoorDash

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Onsite

## Debug a Random Dasher Registry A registry supports adding dashers and randomly selecting and removing one. It uses a dense array of dasher IDs plus a map from ID to array index so addition, lookup, and swap-delete can be constant time. The implementation has failures around an empty registry, removing the only element, removing the last element, moving the last element into a removed slot without updating its map entry, and overly broad exception handling. Debug the data structure, then discuss concurrent access and slow upstream or downstream services. ### Part 1 — State the Representation Invariant Define the array and map relationship before and after every operation, including the empty state. #### What This Part Should Cover - Exactly one array position and one matching map entry per registered ID. - `indexById[array[i]] == i` for every valid position. - A defined result for add-duplicate and pick-from-empty. - Random-index generation restricted to the current array length. ```hint Write the invariant before the branch cases The one-element and last-element cases become easier to reason about when every successful mutation must restore the same array-map equation. ``` ### Part 2 — Repair Random Selection and Swap-Delete Give safe pseudocode for choosing a random index, returning its ID, removing it, moving the old last ID when necessary, and updating the map. #### What This Part Should Cover - Empty check before random selection. - Capturing removed and last IDs before mutation. - Updating the moved ID's index only when a move occurs. - Removing the chosen ID's map entry exactly once. ```hint Distinguish remove-last from move-last When the chosen slot already is the last slot, there is no surviving element whose index needs to be rewritten. ``` ### Part 3 — Handle Errors and Test Boundaries Replace catch-all exception behavior with explicit expected errors and tests. Include empty, one item, last item, middle item, duplicates, repeated draining, and deterministic random choices. #### What This Part Should Cover - Typed or documented outcomes for empty and duplicate operations. - No partial mutation after an expected failure. - An injectable random-number source for deterministic tests. - Invariant checks after every step of randomized operation sequences. ```hint Do not use exceptions as control flow for corruption An index error caused by a broken invariant should remain visible during testing rather than being converted into an ordinary empty result. ``` ### Part 4 — Add Concurrency and Dependency Resilience Explain how multiple threads safely add or pick dashers and what happens when registering or dispatching requires a slow service call. #### What This Part Should Cover - One atomic critical section for the coupled array and map mutation. - No network call while holding a long-lived registry lock. - Reservation, rollback, or durable state for an ambiguous dispatch outcome. - Timeouts, bounded retries, idempotency, backpressure, and observability. ```hint Keep remote latency outside the lock Reserve local state briefly, perform the slow call without blocking unrelated registry operations, then finalize through a versioned transition. ``` ### What a Strong Answer Covers - Derives the fix from the array-map invariant. - Handles empty, singleton, and last-index cases explicitly. - Uses narrow error handling and deterministic fault-revealing tests. - Preserves atomic local state while treating remote outcomes as potentially uncertain. ### Follow-up Questions 1. How would you support removing a known dasher as well as a random one? 2. Is one mutex sufficient, and when would it become a bottleneck? 3. What happens if dispatch succeeds remotely but the local response times out? 4. How would you make selection weighted while retaining efficient updates?

Overview: Debug a random dasher registry backed by a dense array and an ID-to-index map. Repair empty and swap-delete edge cases, preserve representation invariants, narrow error handling, and extend the design for concurrency and slow dependencies.

Read the full DoorDash Software Engineer interview experience this question came from

|Home/Software Engineering Fundamentals/DoorDash
DoorDash logo
DoorDash
Apr 3, 2026
mediumSoftware EngineerOnsiteSoftware Engineering Fundamentals
4
0

Debug a Random Dasher Registry

A registry supports adding dashers and randomly selecting and removing one. It uses a dense array of dasher IDs plus a map from ID to array index so addition, lookup, and swap-delete can be constant time.

The implementation has failures around an empty registry, removing the only element, removing the last element, moving the last element into a removed slot without updating its map entry, and overly broad exception handling. Debug the data structure, then discuss concurrent access and slow upstream or downstream services.

Part 1 — State the Representation Invariant

Define the array and map relationship before and after every operation, including the empty state.

What This Part Should Cover Guidance

  • Exactly one array position and one matching map entry per registered ID.
  • indexById[array[i]] == i for every valid position.
  • A defined result for add-duplicate and pick-from-empty.
  • Random-index generation restricted to the current array length.

Part 2 — Repair Random Selection and Swap-Delete

Give safe pseudocode for choosing a random index, returning its ID, removing it, moving the old last ID when necessary, and updating the map.

What This Part Should Cover Guidance

  • Empty check before random selection.
  • Capturing removed and last IDs before mutation.
  • Updating the moved ID's index only when a move occurs.
  • Removing the chosen ID's map entry exactly once.

Part 3 — Handle Errors and Test Boundaries

Replace catch-all exception behavior with explicit expected errors and tests. Include empty, one item, last item, middle item, duplicates, repeated draining, and deterministic random choices.

What This Part Should Cover Guidance

  • Typed or documented outcomes for empty and duplicate operations.
  • No partial mutation after an expected failure.
  • An injectable random-number source for deterministic tests.
  • Invariant checks after every step of randomized operation sequences.

Part 4 — Add Concurrency and Dependency Resilience

Explain how multiple threads safely add or pick dashers and what happens when registering or dispatching requires a slow service call.

What This Part Should Cover Guidance

  • One atomic critical section for the coupled array and map mutation.
  • No network call while holding a long-lived registry lock.
  • Reservation, rollback, or durable state for an ambiguous dispatch outcome.
  • Timeouts, bounded retries, idempotency, backpressure, and observability.

What a Strong Answer Covers Guidance

  • Derives the fix from the array-map invariant.
  • Handles empty, singleton, and last-index cases explicitly.
  • Uses narrow error handling and deterministic fault-revealing tests.
  • Preserves atomic local state while treating remote outcomes as potentially uncertain.

Follow-up Questions Guidance

  1. How would you support removing a known dasher as well as a random one?
  2. Is one mutex sufficient, and when would it become a bottleneck?
  3. What happens if dispatch succeeds remotely but the local response times out?
  4. How would you make selection weighted while retaining efficient updates?
Loading comments...