Concurrency Questions in Quant Developer Interviews
Concurrency questions in quant developer interviews center on a lock-free queue, a single writer, a fixed lock order and atomic counters.
Concurrency questions in quant developer interviews center on a small set of recurring scenarios: passing market data from a feed handler thread to a strategy thread without a lock, letting many strategy threads read a shared order book while one thread updates it, avoiding a deadlock when two threads must update two related books together, and aggregating statistics safely across many threads without paying for a lock on every update. Each scenario has a standard answer and a standard follow-up about what happens once the assumption behind the standard answer is removed.
State the problem precisely: a feed handler thread receives market data ticks and a separate strategy thread consumes them, and the transfer between the two threads must not block the feed handler, since any delay there widens the gap between what the strategy sees and what the market is actually doing. The standard answer is a single-producer single-consumer ring buffer, a fixed-size circular array with separate read and write indices, where the producer only ever advances the write index and the consumer only ever advances the read index, avoiding a lock entirely because each index is only ever written by one of the two threads.
The follow-up asks what happens when the strategy thread falls behind and the ring buffer fills up before the consumer catches up, since the producer cannot simply block without becoming exactly the delayed feed handler the design was meant to avoid. The candidate is expected to propose either overwriting the oldest unread tick, accepting data loss in exchange for staying current, or growing the buffer within a bounded limit, and to state plainly that unlimited growth is not an acceptable answer in a system where memory and latency are both bounded resources.
State the problem precisely: several strategy threads need to read the current state of an order book while a single feed thread continuously updates it, and a naive lock around every read would serialize all the strategies behind each other and behind every update, which defeats the purpose of running multiple strategies in parallel in the first place. The standard answer keeps a single writer thread as the only thread ever allowed to mutate the book, publishing a new immutable snapshot, or a versioned pointer swap, that readers pick up without ever taking a lock, since a reader that only ever reads a fully-formed snapshot cannot observe a partially updated book.
The follow-up asks how a reader is guaranteed to see either the old snapshot completely or the new one completely, never a mixture of the two, which is where the candidate needs to name a specific mechanism, such as an atomic pointer swap to a new snapshot object, rather than mutating fields of a shared object in place. A second follow-up, common at firms like Hudson River Trading, asks about the memory cost of publishing a full new snapshot on every update, which points toward publishing only the changed levels alongside a versioned base rather than a full copy each time.