Hand-Write a Parallel Sort Using Multiple Worker Threads or Processes

Quick Overview

A concurrency coding question that asks for a hand-written parallel sort: split an integer list across several worker threads or processes and return exactly what a sequential sort would. It tests work decomposition, worker coordination and error propagation, and reasoning about where the speedup stops.

Hand-Write a Parallel Sort Using Multiple Worker Threads or Processes

Company: xAI

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Onsite

Implement a parallel sort by hand. Write a function `parallel_sort(values, num_workers)` that returns the elements of `values` in ascending order, exactly what a sequential sort would return, while splitting the work across up to `num_workers` concurrent workers (threads or processes). ```python def parallel_sort(values: list[int], num_workers: int) -> list[int]: ... ``` The parallel structure must be your own code: how the input is divided, how workers are started, coordinated and joined, and how their partial results are combined into one sorted list. A single call to a library routine that already sorts in parallel does not count. ```hint Split, then combine Decide what each worker receives and what it hands back, then work out what it costs to turn those partial results into one sorted list. ``` ```hint Find the serial part Identify the phase of your design that still runs on a single worker, and estimate how much it limits the speedup as `num_workers` grows. ``` ### Constraints and Clarifications - The result must equal `sorted(values)` for every input, including an empty list, many duplicates, and `num_workers` larger than `len(values)`. - `num_workers >= 1`. - If any worker fails, the call must raise an error instead of returning a partial result. ### Clarifying Questions - Which language and runtime? In CPython, do threads give real parallelism for CPU-bound sorting, or should the solution use processes? - Roughly how large are the inputs, and how many cores are available? Is falling back to a sequential sort below some input size acceptable? - May each worker use the language's built-in sequential sort on its piece, or must every step be hand-written? - Must the sort be in place, or may it return a new list? Is stability required when records are sorted by a key? - Are the values plain integers, or large objects that are expensive to move between workers? ### What a Strong Answer Covers - A decomposition with an argument that the combined output equals a sequential sort - The worker lifecycle: start, join, a bounded number of workers, and error propagation - A choice between threads and processes that fits the runtime, with the copying cost it implies - Work and span analysis that names the sequential bottleneck and how to shrink it - Handling of small inputs, skewed data and heavy duplication - A test plan that compares the result with a sequential sort on adversarial inputs ### Follow-up Questions - Your final combine step runs on one worker. How would you parallelize it? - How would you choose partition boundaries so that every worker gets a similar amount of data when values are skewed or heavily duplicated? - The data no longer fits in the memory of one machine. What changes in the design? - How would you write this in Go with goroutines, or in Java with a fixed thread pool, and what would you do differently from Python?

Overview: A concurrency coding question that asks for a hand-written parallel sort: split an integer list across several worker threads or processes and return exactly what a sequential sort would. It tests work decomposition, worker coordination and error propagation, and reasoning about where the speedup stops.

|Home/Software Engineering Fundamentals/xAI
xAI logo
xAI
Sep 5, 2026
mediumSoftware EngineerOnsiteSoftware Engineering Fundamentals
0
0

Implement a parallel sort by hand. Write a function parallel_sort(values, num_workers) that returns the elements of values in ascending order, exactly what a sequential sort would return, while splitting the work across up to num_workers concurrent workers (threads or processes).

def parallel_sort(values: list[int], num_workers: int) -> list[int]:
    ...

The parallel structure must be your own code: how the input is divided, how workers are started, coordinated and joined, and how their partial results are combined into one sorted list. A single call to a library routine that already sorts in parallel does not count.

Constraints and Clarifications

  • The result must equal sorted(values) for every input, including an empty list, many duplicates, and num_workers larger than len(values) .
  • num_workers >= 1 .
  • If any worker fails, the call must raise an error instead of returning a partial result.

Clarifying Questions Guidance

  • Which language and runtime? In CPython, do threads give real parallelism for CPU-bound sorting, or should the solution use processes?
  • Roughly how large are the inputs, and how many cores are available? Is falling back to a sequential sort below some input size acceptable?
  • May each worker use the language's built-in sequential sort on its piece, or must every step be hand-written?
  • Must the sort be in place, or may it return a new list? Is stability required when records are sorted by a key?
  • Are the values plain integers, or large objects that are expensive to move between workers?

What a Strong Answer Covers Guidance

  • A decomposition with an argument that the combined output equals a sequential sort
  • The worker lifecycle: start, join, a bounded number of workers, and error propagation
  • A choice between threads and processes that fits the runtime, with the copying cost it implies
  • Work and span analysis that names the sequential bottleneck and how to shrink it
  • Handling of small inputs, skewed data and heavy duplication
  • A test plan that compares the result with a sequential sort on adversarial inputs

Follow-up Questions Guidance

  • Your final combine step runs on one worker. How would you parallelize it?
  • How would you choose partition boundaries so that every worker gets a similar amount of data when values are skewed or heavily duplicated?
  • The data no longer fits in the memory of one machine. What changes in the design?
  • How would you write this in Go with goroutines, or in Java with a fixed thread pool, and what would you do differently from Python?
Loading comments...