PracHub
QuestionsCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates debugging, refactoring, naming and exception handling, input validation, code structure, and concurrency-safety design skills within a legacy codebase, requiring both hands-on code changes and higher-level reasoning about immutability, confinement, synchronization, and concurrent data structures.

  • medium
  • DoorDash
  • Coding & Algorithms
  • Software Engineer

Debug and refactor a legacy module

Company: DoorDash

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Onsite

Given a legacy module named DasherPicker and a failing test suite, systematically debug and refactor the code while following a provided review checklist. Identify and fix issues in naming conventions, exception handling, input validation, and code structure so that all tests pass. Then outline a plan to make the module safe for multi-threaded execution (e.g., immutability, confinement, synchronization, concurrent data structures) and describe how you would validate correctness under concurrency (tests, stress tools, and diagnostics).

Quick Answer: This question evaluates debugging, refactoring, naming and exception handling, input validation, code structure, and concurrency-safety design skills within a legacy codebase, requiring both hands-on code changes and higher-level reasoning about immutability, confinement, synchronization, and concurrent data structures.

Part 1: Refactor DasherPicker Selection Logic

Refactor the `DasherPicker` selection logic so it assigns each delivery order to the single best eligible dasher, using deterministic tie-breaking, strict input validation, and no mutation of the caller's data. ### Implement ``` def solution(dashers, orders): ... ``` Return a **list of integers** — one entry per order, in the same order the orders are given. Each entry is either the **id of the chosen dasher** or `-1` if no dasher could be assigned. When `orders` is empty, the natural result is an empty list `[]` (there are no orders to assign). ### Input format - **`dashers`** — a list of dasher records. Each record is `[id, x, y, rating, capacity, active]` (a list or tuple), where: - `id` is a positive, unique integer - `x`, `y` are the dasher's coordinates - `rating` is the dasher's rating - `capacity` is how many more orders the dasher can take - `active` is `1` if the dasher is active, `0` if inactive - **`orders`** — a list of orders. Each order is `[x, y, min_rating]` (a list or tuple), where `x`, `y` are the order's location and `min_rating` is the minimum rating required. ### What to do Process the orders **from left to right** (first to last). For each order, choose exactly one **eligible** dasher. A dasher is **eligible** for an order when **all** of the following hold: 1. The dasher is active (`active == 1`). 2. The dasher has **remaining capacity greater than `0`**. 3. The dasher's `rating` is **at least** the order's `min_rating` (`rating >= min_rating`). Among the eligible dashers, pick the best one by this priority: 1. **Smallest Manhattan distance** to the order location, where distance `= |dasher_x - order_x| + |dasher_y - order_y|`. 2. If still tied, the **higher `rating`**. 3. If still tied, the **smaller `id`**. Append the chosen dasher's `id` to the result. Then **decrease only that dasher's remaining capacity by `1`** (tracked internally, so later orders see the updated capacity). If **no** dasher is eligible for an order, append `-1` for that order and leave all capacities unchanged. ### Important rules - **Do not mutate the input.** Capacity must be tracked on internal copies; the original `dashers` list and its records must be unchanged when the function returns. - Each order is independent only in choice — capacity consumed by earlier orders carries forward to later orders. ### Validation — return `[]` on any invalid input If **any** part of the input is malformed or out of range, return an **empty list** `[]` instead of raising an exception. (Note that `[]` is also the natural result when `orders` is empty — see the examples below.) The input is invalid if any of these fail: - `dashers` and `orders` must each be a list. - Every dasher record must be **exactly 6 integers**: `[id, x, y, rating, capacity, active]`. Booleans are **not** accepted as integers. - Every order record must be **exactly 3 integers**: `[x, y, min_rating]`. Booleans are **not** accepted as integers. - Dasher `id` values must be **positive and unique** (a duplicate id makes the whole input invalid). - All coordinates `x`, `y` (for both dashers and orders) must satisfy `-10^6 <= x, y <= 10^6`. - `rating` and `min_rating` must satisfy `0 <= value <= 500`. - `capacity >= 0`. - `active` must be either `0` or `1`. ### Constraints - `0 <= len(dashers) <= 1000` - `0 <= len(orders) <= 1000` ### Examples - `dashers = [[1, 0, 0, 500, 1, 1], [2, 10, 0, 400, 2, 1]]`, `orders = [[0, 0, 0], [1, 0, 0], [9, 0, 0], [0, 0, 450]]` → `[1, 2, 2, -1]`. - Order `[0,0,0]`: dasher 1 is closest → assign `1`, its capacity drops to 0. - Order `[1,0,0]`: dasher 1 is out of capacity, so dasher 2 is chosen → `2` (capacity now 1). - Order `[9,0,0]`: dasher 2 is closest → `2` (capacity now 0). - Order `[0,0,450]`: requires rating `>= 450`; dasher 1 is out of capacity and dasher 2's rating is too low → `-1`. - `dashers = [[1, 0, 0, 500, 1, 1], [1, 1, 1, 400, 1, 1]]`, `orders = [[0, 0, 0]]` → `[]` (duplicate dasher id — invalid input). - `dashers = [[1, 0, 0, 500, 1, 1]]`, `orders = []` → `[]` (no orders, so the result is the empty assignment list).

Constraints

  • 0 <= len(dashers) <= 1000
  • 0 <= len(orders) <= 1000
  • Each dasher record must have exactly 6 integers: [id, x, y, rating, capacity, active].
  • Each order record must have exactly 3 integers: [x, y, min_rating].
  • Dasher ids must be positive and unique.
  • -10^6 <= x, y <= 10^6
  • 0 <= rating <= 500 and 0 <= min_rating <= 500
  • capacity >= 0
  • active must be either 0 or 1
  • Invalid input must return [] rather than throwing an exception.

Examples

Input: ([[101, 0, 0, 480, 2, 1], [102, 2, 1, 500, 1, 1], [103, 1, 1, 450, 1, 0], [104, 1, 0, 480, 1, 1]], [[1, 0, 470], [2, 1, 490], [0, 0, 470]])

Expected Output: [104, 102, 101]

Explanation: Order 1 chooses dasher 104 because distance is 0. Order 2 requires rating 490, so dasher 102 is chosen. Order 3 then chooses dasher 101.

Input: ([[1, 0, 0, 450, 1, 1], [2, 0, 0, 500, 1, 1], [3, 1, 0, 500, 1, 1]], [[0, 0, 400], [1, 0, 400]])

Expected Output: [2, 3]

Explanation: For the first order, dashers 1 and 2 are equally close, so higher rating wins. For the second order, dasher 2 has no capacity left, so dasher 3 is selected.

Input: ([[1, 0, 0, 500, 1, 1], [2, 10, 0, 400, 2, 1]], [[0, 0, 0], [1, 0, 0], [9, 0, 0], [0, 0, 450]])

Expected Output: [1, 2, 2, -1]

Explanation: Capacity is consumed over time. The last order requires rating 450, but dasher 1 is full and dasher 2 has rating 400.

Input: ([[1, 0, 0, 500, 1, 1]], [])

Expected Output: []

Explanation: Edge case: there are no orders to process.

Input: ([[1, 0, 0, 500, 1, 1], [1, 1, 1, 400, 1, 1]], [[0, 0, 0]])

Expected Output: []

Explanation: Invalid input because dasher ids must be unique.

Hints

  1. Turn the selection rule into a tuple comparison: distance, negative rating, then id.
  2. Copy the mutable dasher state before processing orders so that caller-owned input is not modified.

Part 2: Classify a Concurrency Safety Plan

Implement `solution(resources, operations)` that produces a deterministic concurrency-safety plan for a module being prepared for multi-threaded execution. Instead of writing prose, you must encode a fixed classification rule: for each declared resource decide a single thread-safety **strategy**, then assemble a **validation checklist**. ## Input Two arguments, each a list: - **`resources`** — a list of `[name, kind]` records describing the module's resources. `kind` is one of: - `value` — a scalar or immutable-style value - `counter` — a numeric counter - `collection` — a map/set/queue/cache/list-like resource - `composite` — a multi-field object whose fields may carry invariants - **`operations`** — a list of `[resource_name, thread_id, op]` records describing operations threads performed. `op` is one of: - **Non-mutating:** `read`, `iterate` - **Mutating:** `write`, `inc`, `put`, `remove` Each record may be given as a list or a tuple, but must have exactly the length shown (2 for a resource, 3 for an operation). ## Output Return a list of exactly two lists: `[strategy_lines, validation]`. ### `strategy_lines` One entry per resource, **in the same order the resources were given**, formatted as the string `"<name>:<strategy>"` (the resource name, a colon, then the chosen strategy). For each resource, pick the **first** strategy whose condition holds, checking the rules **in this order**: 1. **`immutable`** — the resource has **no** mutating operations. 2. **`confined`** — the resource has at least one mutating operation, but every operation referencing it comes from a single (one) `thread_id`. 3. **`atomic`** — the resource is a `counter`, is touched by more than one thread, and **every** mutating operation on it is `inc`. 4. **`concurrent_collection`** — the resource is a `collection` touched by more than one thread (and is not covered by the rules above). 5. **`synchronized`** — any remaining resource that is mutated and shared across more than one thread. A resource counts as **shared** when more than one distinct `thread_id` appears in its operations. Only mutating operations count toward "has mutations"; `read` and `iterate` never make a resource mutable but they **do** count toward how many distinct threads touched it. ### `validation` A checklist list, built in this exact order: - Always include `unit_tests`. - If **at least one** resource was classified as `atomic`, `concurrent_collection`, or `synchronized`, append (in order) `stress_tests`, then `race_detector`. - If **at least one** resource was classified as `synchronized`, append `deadlock_diagnostics` next. - If **at least one** resource was classified as `atomic`, `concurrent_collection`, or `synchronized`, append `contention_metrics` last. (So the only sources added beyond `unit_tests` are tied to the presence of shared, mutable resources, and `deadlock_diagnostics` appears only when something is `synchronized`, positioned before `contention_metrics`.) ## Invalid input Return `[[], ['invalid_input']]` if any of the following is violated: - `resources` and `operations` must each be a list, and every record must have the correct shape (a list/tuple of length 2 for `[name, kind]`, a list/tuple of length 3 for `[resource_name, thread_id, op]`). - Each resource `name` must be a **non-empty string** and **unique** across resources. - Each resource `kind` must be one of `value`, `counter`, `collection`, `composite`. - Every operation must reference an **existing** resource name. - Each `thread_id` must be a non-empty string. - Each `op` must be one of `read`, `iterate`, `write`, `inc`, `put`, `remove`. ## Constraints - `0 <= len(resources) <= 200000` - `0 <= len(operations) <= 200000` ## Examples **Resource declared but never operated on** (e.g. a `counter` with no operations) has no mutating operations, so it is `immutable`. **Empty input** (`resources = []`, `operations = []`) is valid and returns `[[], ['unit_tests']]`.

Constraints

  • 0 <= len(resources) <= 200000
  • 0 <= len(operations) <= 200000
  • Resource names must be non-empty strings and unique.
  • Resource kind must be one of: value, counter, collection, composite.
  • Each operation must reference an existing resource.
  • Thread ids must be non-empty strings.
  • Operation type must be one of: read, iterate, write, inc, put, remove.
  • Invalid input must return [[], ['invalid_input']].

Examples

Input: ([['config', 'value'], ['cache', 'collection'], ['load', 'counter'], ['routeState', 'composite']], [['config', 'T1', 'read'], ['config', 'T2', 'read'], ['cache', 'T1', 'put'], ['cache', 'T2', 'read'], ['cache', 'T3', 'remove'], ['load', 'T1', 'inc'], ['load', 'T2', 'read'], ['load', 'T3', 'inc'], ['routeState', 'T1', 'write'], ['routeState', 'T2', 'read']])

Expected Output: [['config:immutable', 'cache:concurrent_collection', 'load:atomic', 'routeState:synchronized'], ['unit_tests', 'stress_tests', 'race_detector', 'deadlock_diagnostics', 'contention_metrics']]

Explanation: The config is read-only, cache is a shared mutable collection, load is a shared increment-only counter, and routeState is shared mutable composite state requiring synchronization.

Input: ([['queue', 'collection'], ['scratch', 'composite']], [['queue', 'worker1', 'put'], ['queue', 'worker1', 'remove'], ['scratch', 'worker1', 'write'], ['scratch', 'worker1', 'read']])

Expected Output: [['queue:confined', 'scratch:confined'], ['unit_tests']]

Explanation: Both mutable resources are accessed only by worker1, so thread confinement is sufficient.

Input: ([['settings', 'value'], ['catalog', 'collection'], ['unused', 'counter']], [['settings', 'T1', 'read'], ['catalog', 'T2', 'iterate']])

Expected Output: [['settings:immutable', 'catalog:immutable', 'unused:immutable'], ['unit_tests']]

Explanation: All resources have no mutating operations. A resource with no operations is also classified as immutable.

Input: ([['count', 'counter']], [['missing', 'T1', 'inc']])

Expected Output: [[], ['invalid_input']]

Explanation: The operation references an unknown resource.

Input: ([], [])

Expected Output: [[], ['unit_tests']]

Explanation: Edge case: an empty module still has a minimal validation checklist.

Hints

  1. For each resource, track the set of accessing threads and the list or count of mutating operation types.
  2. Apply the strategy rules in the given order; for example, a read-only counter is immutable, not atomic.
Last updated: Jun 15, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Validate a Shopping Cart - DoorDash (medium)
  • Implement Timeout Refund Workflow - DoorDash (medium)
  • Calculate Driver Payments - DoorDash (medium)
  • Maximize Chef Assignment Profit - DoorDash (medium)
  • Compute Courier Delivery Pay - DoorDash (easy)