AnyLearn
All interview prep
Quantitative financeMid-levelQuantitative Developer

Quantitative Developer Interview Prep: Questions and a Mock Test

The quantitative developer sits between research and production, and the interview reflects that split. It is a genuine software engineering loop with an unusual emphasis: correctness under concurrency, latency measured rather than assumed, numerical behaviour that most applications can ignore and this one cannot, and enough market knowledge that you understand what the code is for. This page covers each area and ends with a graded mock across six of them.

The loop

How the process is structured

The interview loop: each round, how long it runs, and what it tests
RoundLengthWhat it tests
1.Coding and data structures[3]Not publishedAlgorithms with a follow-up about constant factors and memory layout. Language built-in costs are fair game, since choosing a list where a set is needed converts a linear algorithm into a quadratic one.
2.Concurrency and systems[3]Not publishedRaces, deadlock, atomicity versus visibility, memory ordering, and the honest tradeoffs of lock-free design. Expect a scenario where the bug only appears under load or on a different core count.
3.Performance and numerics[1]Not publishedCache behaviour, false sharing, allocation in hot paths, and measuring tail latency rather than averages. Floating point comes up here, anchored on facts such as 0.1 not being exactly representable in binary.
4.Domain and design[2]Not publishedOrder types, market data sequencing and recovery, and designing a component such as an order book or a fills reconciler. The SEC's framing is the precise one: a market order guarantees execution and not price, a limit order the reverse.

Bracketed markers point to the dated sources at the end of this article. Loops change; check the retrieval dates before relying on a round count.

Data structures chosen for the machine, not the textbook

Coding rounds here look like ordinary algorithm interviews with one difference: the follow-up is always about constant factors and memory behaviour, not only about asymptotic complexity.

Asymptotics still come first, and the costs of language built-ins are part of that. Python's documented average cases make the point compactly: appending to a list is O(1) while inserting at position zero is O(n), indexing is O(1) while membership testing with x in list is O(n), and set membership and dictionary access are O(1). A seen-before check written against a list rather than a set turns a linear algorithm into a quadratic one with almost no visible change to the code.

What is added in this domain is the layout question. A structure with the same complexity can be an order of magnitude apart in practice because of memory access patterns. An array of contiguous values is scanned far faster than a linked structure of the same length, because the hardware prefetches sequential memory and every pointer chase is a potential cache miss. That is why a flat vector frequently outperforms a linked list even for operations the linked list is supposedly better at, and why a linear scan of a small contiguous array can beat a hash lookup.

For an order book specifically, the interview conversation is about the access pattern rather than the ideal abstraction: prices near the top of the book are touched constantly, prices far away almost never, and updates are overwhelmingly at or near the touch. A design that optimises the common case and accepts a slower path for the rare one is the expected answer.

Concurrency, and the failure that only appears in production

Concurrency questions dominate the systems rounds because the bugs are hard to find and expensive when they escape.

The basics are examined precisely. A race condition is two threads accessing shared state with at least one writing, without synchronisation ordering them. A deadlock requires a cycle of threads each holding a lock another needs, and the standard prevention is a consistent global lock ordering. Livelock is threads actively responding to each other without progressing. Starvation is a thread never getting scheduled or never acquiring a contended lock.

The distinction interviewers probe most is atomicity versus visibility. Making an operation atomic ensures it happens indivisibly; ensuring visibility means another thread will actually observe the result rather than a cached older value. A variable can be updated atomically and still be read stale by another core, which is what memory ordering and barriers exist to control, and it is why a naive check of a flag in a loop can spin forever.

Lock-free structures come up constantly, and the honest framing scores better than enthusiasm. Lock-free means progress is guaranteed for at least one thread and no thread can block others by being descheduled while holding a lock, which removes the worst latency tail. It does not mean faster in the average case, it is far harder to get right, and the ABA problem, where a value is changed and changed back so a compare-and-swap succeeds when it should not, is the classic trap.

The single-writer principle is worth naming: much of the fastest financial software avoids the problem entirely by giving one thread ownership of a piece of state.

Latency, and measuring it honestly

Performance rounds test whether you reason about the machine and whether you measure before optimising.

The mental model expected is a rough hierarchy of costs: a register access is essentially free, an L1 cache hit costs a few cycles, an L2 hit more, main memory is a large multiple of that, and anything crossing the network is in a completely different regime. You are not expected to recite exact figures, and quoting them confidently to two significant figures is worse than describing the shape, but you are expected to know that the gaps are orders of magnitude and that memory access dominates most real workloads.

The consequences are practical. False sharing occurs when two threads write to different variables that happen to occupy the same cache line, so the line ping-pongs between cores and performance collapses without any logical contention; padding the variables apart fixes it. Branch misprediction costs a pipeline flush, which is why branchless formulations sometimes win. Allocation in a hot path is usually the first thing to remove, since it can trigger unpredictable pauses.

On measurement, the discipline being assessed is not to report an average. Latency distributions in this domain are heavily skewed and the tail is the point: p99 and p99.9 are what a trading system lives or dies by, and a mean hides exactly the events that matter. Measure on the target hardware, with realistic input, with the system warm, and be aware that the measurement apparatus itself perturbs what it measures. A candidate who says they would profile before optimising, and names what they would look at, outscores one who lists optimisations.

Floating point, and never storing money in a double

This is the topic most reliably separating candidates who have worked with financial data from those who have not.

The underlying fact is documented plainly in Python's own tutorial: "no matter how many base 2 digits you're willing to use, the decimal value 0.1 cannot be represented exactly as a base 2 fraction. In base 2, 1/10 is the infinitely repeating fraction 0.0001100110011001100110011001100110011001100110011...". The visible consequence follows: summing three values of 0.1 does not equal 0.3, and the documentation shows exactly that, with 0.1 + 0.1 + 0.1 == 0.3 evaluating to False.

Three practical rules follow. Never compare floats with equality; the documentation points at math.isclose for "comparing inexact values". Never store money as a binary float; use an integer number of minor units, or a decimal type with defined rounding. And be aware that error accumulates over long summations, which is why the standard library's sum "uses extended precision for intermediate rounding steps as values are added onto a running total", and why compensated summation exists.

Ordering matters too: adding a very small number to a very large one can lose the small number entirely, so summing from smallest to largest is more accurate than the reverse. Subtracting two nearly equal numbers loses precision catastrophically, which is why numerically stable formulations of variance and of quadratic roots are written differently from the textbook version.

Expect a question about rounding a price to a tick, and remember that naive rounding of a value already carrying representation error produces off-by-one-tick bugs that are extremely hard to trace.

Knowing what the code is for

You are not being interviewed as a trader, but you are expected to understand the domain well enough to spot a specification that cannot be right.

Order semantics are the foundation, and the SEC's own definitions are exact. A market order "guarantees that the order will be executed, but does not guarantee the execution price", with the explicit warning that "the last-traded price is not necessarily the price at which a market order will be executed". A limit order is "an order to buy or sell a security at a specific price or better". A stop order becomes a market order once the stop price is reached, inheriting the price uncertainty precisely when prices are moving fastest.

That asymmetry drives real implementation decisions: a system that treats a fill price as known in advance is wrong, and one that assumes a limit order will fill is equally wrong.

Market data handling is the other half. Feeds are sequenced, and gap detection plus recovery is a correctness requirement rather than a nicety, because a silently dropped message leaves your book wrong in a way that produces confident bad decisions. Snapshot plus incremental update is the standard construction, and the interview question is usually how you resynchronise after a gap without stopping.

The vocabulary to have ready: the top of book, the spread as the immediate cost of a round trip, and the difference between a trade print and a quote update. And be able to say what your system should do when it does not know the state of an order, since the answer, treating the outcome as unknown and reconciling rather than assuming, is the same idempotency reasoning that applies everywhere else.

Open-ended

What they actually ask

  1. 1.Design the data structure behind a limit order book. What are you optimising for?

    What a strong answer covers

    Strong answers start from the access pattern rather than from an abstraction: adds, cancels and modifies vastly outnumber trades, activity concentrates at and near the touch, and the top of book is read constantly. That argues for a structure giving O(1) access to the best bid and offer, with price levels held in a form that is cheap to walk near the touch and can be sparse further out, plus a hash index from order id to its position so a cancel does not require a search. They discuss the tradeoff between an array indexed by price ticks, which is fast and memory-hungry and needs bounds handling, and a tree or skip list, which is general and pointer-chasing. The best answers name what they would measure to choose, and mention cancel being the highest-volume operation.

  2. 2.Two threads produce correct results in testing and occasionally wrong results in production. How do you approach it?

    What a strong answer covers

    The expected recognition is that a bug appearing under load and not in tests is almost always a race whose window is too narrow to hit at low concurrency, or a visibility problem that manifests only across physical cores. Strong answers enumerate: shared mutable state without synchronisation, a check-then-act sequence that is not atomic, reliance on a value being visible to another thread without the ordering that guarantees it, and lock ordering that only deadlocks under a particular interleaving. Diagnostics matter: thread sanitizers, stress tests with artificial delays inserted at suspected points, and reducing to a minimal reproduction. The strongest close is structural, that the durable fix is usually to remove the sharing, by giving one thread ownership of the state, rather than to add another lock.

  3. 3.A pricing calculation produces results that differ in the last few digits between runs. Should you be worried?

    What a strong answer covers

    The answer depends on the cause, and identifying it is the point. Non-determinism from parallel reduction is expected and benign in itself, because floating point addition is not associative, so summing in a different order produces slightly different results. Non-determinism from an uninitialised value or a race is a genuine bug. Strong candidates separate the two by checking whether the difference is at the level of representation error or larger, and by testing with a fixed reduction order. They then ask what tolerance the downstream consumer needs, since a difference invisible in a risk report can matter in a comparison used to trigger a trade, and they note that comparing such results with exact equality is the actual defect in many cases.

  4. 4.How would you store and compute with monetary amounts?

    What a strong answer covers

    The core answer is not a binary float, because values such as 0.1 have no exact binary representation and error accumulates through arithmetic, which produces amounts that fail to reconcile. The alternatives are an integer count of minor units, which is exact and requires care with instruments quoted in fractions of a cent, or a decimal type with an explicitly specified precision and rounding mode. Strong candidates raise rounding policy as a business decision rather than a technical default, since half-up, half-even and truncation produce different totals over many transactions, and note that the rounding rule must be applied at defined points rather than incidentally. They also mention that currency must travel with the amount, since a bare number invites the worst class of bug.

  5. 5.Your market data feed drops a sequence number. What does your system do?

    What a strong answer covers

    The essential recognition is that a gap means the book is now wrong and any decision made from it is unsafe, so silently continuing is the worst option. Strong answers detect the gap by sequence number rather than by noticing odd prices, mark the affected instrument's state as unreliable and stop acting on it, then recover, usually by requesting a retransmission if the feed supports one or by rebuilding from a snapshot and applying buffered increments from the snapshot's sequence onward. They cover buffering incoming messages during recovery so nothing is lost, and the ordering subtlety of applying only increments after the snapshot point. The mature addition is that recovery must be tested deliberately, since it is the path that only runs when something is already going wrong.

  6. 6.A function in the hot path is too slow. Walk me through what you do.

    What a strong answer covers

    Measure first, on representative input and target hardware, and be specific about the metric: the tail rather than the mean, since a p99 is what matters and an average hides it. Then find where the time goes rather than guessing, using a profiler and looking at cache misses and branch misses as well as cycles. Then the usual suspects in this domain: allocation in the hot path, indirection causing cache misses, false sharing between threads writing adjacent variables, an unnecessary lock, and copying where a reference would do. Strong candidates state the arithmetic before optimising, since a function taking 5 percent of the time cannot yield more than a 5 percent improvement, and they insist on re-measuring afterwards because plausible optimisations frequently make things slower.

Worked examples

Three sample questions, answered

These three show the level the mock is pitched at, with the answer and the reasoning in the open. The graded paper keeps its answer key server-side.

1.Why does 0.1 + 0.1 + 0.1 == 0.3 evaluate to False?
Floating point and money
  • Because addition of three values loses precision by design
  • Because the comparison operator uses a tolerance internally
  • Because 0.1 has no exact binary representation, so the accumulated value differs from the literal 0.3
  • Because floating point addition is not commutative

Why: As the documentation states, "the decimal value 0.1 cannot be represented exactly as a base 2 fraction", since in base 2 one tenth is an infinitely repeating fraction. Each 0.1 is stored as a nearby value, and the sum of three of them is not the nearest double to 0.3. The recommended comparison is math.isclose. Addition is commutative but not associative here.

2.Two threads write to separate variables that sit in the same cache line. What is the effect?
Latency, caches and measurement
  • False sharing: the line ping-pongs between cores and throughput collapses despite no logical contention
  • A data race, since writes to the same line are not atomic
  • Nothing, since the variables are logically independent
  • A deadlock, if the writes occur in different orders

Why: Cache coherence operates at cache line granularity, so a write by one core invalidates the whole line in the other's cache even though the variables are unrelated. The result is heavy coherence traffic and a severe slowdown with no correctness bug. The fix is padding or aligning the variables so they occupy different lines.

3.Per the SEC, what does a limit order guarantee?
Order semantics and market data
  • That the order will be executed within the trading session
  • That the order will be executed at the last traded price or better
  • That execution will occur before any market order at the same price
  • That if it executes, it does so at the specified price or better

Why: A limit order is "an order to buy or sell a security at a specific price or better": price is guaranteed, execution is not. A market order inverts that, guaranteeing execution but not price, with the explicit caution that the last traded price is not necessarily the execution price. Systems that assume either guarantee holds for both are wrong in expensive ways.

The mock

An 18-question knowledge check

This is a knowledge check, not a simulation. The real loop happens on a whiteboard, in an editor, and in conversation. What this paper does measure is the underlying knowledge those rounds draw on: each question is tagged with a topic, grading happens per topic, and a weak topic points you at the course that fixes it.

Your paper0 / 18 answered
  1. 1.Which structure gives the best cache behaviour for a full sequential scan of a million integers?
    Data structures and memory layout
  2. 2.For a small collection of roughly ten elements checked repeatedly, why might a linear scan of an array beat a hash lookup?
    Data structures and memory layout
  3. 3.Removing an order from an order book by scanning for its id is what complexity, and what is the standard fix?
    Data structures and memory layout
  4. 4.What distinguishes atomicity from visibility in a concurrent program?
    Concurrency and lock-free design
  5. 5.What is the ABA problem in lock-free programming?
    Concurrency and lock-free design
  6. 6.What does 'lock-free' actually guarantee?
    Concurrency and lock-free design
  7. 7.Which latency figure should you report for a trading system's request path?
    Latency, caches and measurement
  8. 8.A function accounts for 4 percent of total runtime. What is the maximum speedup available from optimising it?
    Latency, caches and measurement
  9. 9.Why is memory allocation usually removed from a latency-critical hot path?
    Latency, caches and measurement
  10. 10.How should monetary amounts be stored?
    Floating point and money
  11. 11.Why does summing a long list of floats from smallest to largest generally give a more accurate result?
    Floating point and money
  12. 12.Why does subtracting two nearly equal floating point numbers lose precision?
    Floating point and money
  13. 13.What happens to a stop order once its stop price is reached?
    Order semantics and market data
  14. 14.A market data feed's sequence number jumps from 10,451 to 10,455. What is the correct behaviour?
    Order semantics and market data
  15. 15.Your system sends an order and the connection drops before any acknowledgement. What is the correct assumption?
    Order semantics and market data
  16. 16.Why does TCP's reliability not make application-level sequence numbers unnecessary in a market data feed?
    Networking and systems
  17. 17.Nagle's algorithm can harm a latency-sensitive request path because it does what?
    Networking and systems
  18. 18.What is the primary reason kernel bypass networking is used in low-latency systems?
    Networking and systems
18 questions left to answer.
Apparatus

Sources

Hiring loops change. Every claim above carries a retrieval date so you can judge how current it is.

  1. [1]Python Documentation, Floating-Point Arithmetic: Issues and Limitations · retrieved 2026-08-13
  2. [2]U.S. Securities and Exchange Commission, Investor.gov, Types of Orders · retrieved 2026-08-13
  3. [3]Python Wiki, TimeComplexity · retrieved 2026-08-13
Keep preparing

Refresh your memory

Free learning paths covering the ground this loop tests, whatever your score. Each one ends with a shareable certificate.