In this article
  1. Before you start
  2. Why interviewers ask this
  3. Machine-coding and low-level design take-homes from first principles
  4. The Staff-level answer
  5. The rubric
  6. Three variants of this question
  7. Common mistakes
  8. Follow-up questions
  9. Sources

Before you start

For where a coding exercise sits among the other rounds, see the interview process.

Why interviewers ask this

A design drawn on a whiteboard hides whether you can finish anything. A machine-coding exercise removes that gap: the code either runs or it does not, and the reviewer sees how you structure it under a clock or over a few evenings.

Candidates report a wide spread of briefs: a circuit breaker in a pair-programming session, a block editor with undo, a rate limiter inside an online assessment, a file-directory navigator that is later extended and refactored, a load balancer exposed as a representational state transfer (REST) service, a stock broker with first in, first out (FIFO) order matching, and a long home assignment followed by a review of it.1 The shape is always the same: a small domain, a working program, then a change.

A weak submission works for the sample input and breaks on the first new requirement. A strong one works, is tested, and shows where each likely change would go. A Staff-level one also says what it left out and why.

Machine-coding and low-level design take-homes from first principles

Machine-coding round
A machine-coding round is a timed or take-home exercise in which you build a small, runnable program from a written brief, with attention to behaviour, class design, tests and how easily the code absorbs a requirement that changes after the first version works.
Seam
A seam is a place in the code where behaviour can be swapped or extended, usually an interface or a function parameter, without editing the code that uses it, so a new requirement becomes a new class or setting instead of a rewrite.

In plain words

Imagine a workshop where a customer hands you a note: "build a toaster." You build it. Then the customer says: "now it must toast bagels." If you welded the slot shut around bread, you start again. If you made the slot width a setting, you turn a screw.

A machine-coding round is that note, followed by that change. The analogy breaks in one place: a reviewer can read your code, so the screw must be visible and named. In one precise sentence, you split the program so the part that is likely to change sits behind one interface and the rest never needs editing.

Low-level design (LLD) is the class-level design of one component: its classes, interfaces, methods and how they interact, as opposed to high-level design (HLD), which arranges services, data stores and traffic. A machine-coding round tests low-level design in running code.

Step 1: Clarify the brief and write the contract

Clarifying the brief means turning loose text into a short written contract of operations, inputs, outputs, errors and non-goals before any class exists. Input: the brief. Output: a list you can check the finished program against.

List the nouns (breaker, call, state) and the verbs (call, record failure, reset). Then decide the open questions. For a circuit breaker: what counts as a failure, is the state per process, and where does time come from? In a pair-programming round, ask the interviewer and say your assumption aloud. In a take-home, write the assumptions at the top of the README file. Name the non-goals too, such as persistence or a user interface, so nobody wonders whether you forgot them.

Check the brief for rules on tools and libraries first; the AI-assisted coding interview page covers rounds where assistants are allowed. You now have a contract; the next step decides its shape.

Step 2: Put the rule that will change behind one seam

Putting the changing rule behind one seam means choosing the single decision most likely to be altered and making it an interface, while everything else stays plain code. Input: your contract. Output: a small set of classes with one named extension point.

For a circuit breaker the rule that changes is when to trip. Fowler (2014) shows a failure count that resets on success, then notes a more sophisticated approach might trip on a failure rate, say 50%. A TripPolicy interface covers both. The clock is the second seam: pass a time source in instead of reading the system clock inside the class.

The same move works elsewhere. In a block editor, each edit becomes an object with apply and revert methods, so undo is a stack of those objects (the Command pattern). In a load balancer, the choice of backend becomes a Strategy. The reviewer's change request now has an obvious home. You now know where the extension goes; the next step makes the core run.

Step 3: Build the thin core and test it

Building the thin core means writing the smallest version that runs end to end and checking it with unit tests before adding anything else. Input: the classes of Step 2. Output: a tested program.

A fake clock is a small object whose time you advance by hand, so a test of a timeout never has to wait. Azure's pattern page describes three states: closed counts failures, open rejects calls at once, and half-open lets trial calls through. Successful trials close the breaker; a failed one reopens it.

Take illustrative settings, where each call is one tick of the fake clock: open after three failures in a row, wait four calls, close after two successful trials. Over 16 calls where the backend fails at call 2 and again from call 4 to call 13, the breaker passes 10 calls to the backend and rejects 6.2 Without it, the failing service would receive 11 failing calls, not 5.2

In the illustrative run the breaker opens at call 6, fails a trial at call 10 and closes again after call 15.
CallState during the callWhat happensState after
6closedthird failure in a row reaches the backendopen
7 to 9openrejected without calling the backendopen
10half-opentrial call failsopen
11 to 13openrejected without calling the backendopen
14half-openfirst trial succeedshalf-open
15half-opensecond trial succeedsclosed

Half-open is the state in which only trial calls reach the service, so a recovering service is not flooded. On the timeline, the breaker opens after the sixth call and closes after the fifteenth.2

The breaker opens after call 6 and closes after call 15Timeline over 16 calls with illustrative settings: closed until call 6, open for calls 7 to 9, a failed trial at call 10, open again to call 13, two successful trials, closed after call 15.0481216callOpensTrial failsClosesClosedOpenTrialOpenTrialClosedDiagram: Interview Clozo, CC BY 4.0 ·interview.clozo.ai/blog/machine-coding-low-level-design-take-homes.html
While the breaker is open it rejects calls, so the failing service sees far fewer of them.CC BY 4.0 — source: How do you do a machine-coding or low-level design take-home, step by step?
Text description of the diagram
  • The breaker opens after the sixth call.
  • It closes again after the fifteenth call.

Step 4: Extend, refactor, then write the notes

Extending means adding the second requirement in small steps while the tests stay green, then refactoring so the new code looks planned. Input: the working core and a change request. Output: the extended program, passing tests and a short README.

Add the change behind a new class where the seam allows it. If it does not fit, refactor first in one small move, run the tests, then add the feature. The refactor take-home page covers that skill on its own. In a timed round, get the core running first and leave the extras for last; in a multi-evening take-home the same order holds. Finish with the README: assumptions, what you built, what you left out, and what you would do next with more time.

When a review follows the exercise, expect questions on performance, tests and the design choices; the project deep dive page shows how to answer them. Order matters. Write the contract before any class. Put the rule that will change behind one interface. Get a tested core running end to end. Extend and refactor last, then write the notes.

A take-home runs from contract to seam, core and extensionFlow of four steps: clarify the brief into a written contract, put the rule that will change behind one interface, build a tested core that runs end to end, then extend and refactor.ClarifywrittencontractSeamone interfaceCoretested end toendExtendrefactor, notesDiagram: Interview Clozo, CC BY 4.0 ·interview.clozo.ai/blog/machine-coding-low-level-design-take-homes.html

Each step leaves the program working, so a change request lands on a design that already has room for it.CC BY 4.0 — source: How do you do a machine-coding or low-level design take-home, step by step?
Step-by-step description
  1. Write the contract before any class.
  2. Put the changing rule behind one interface.
  3. Get a tested core running end to end.
  4. Extend and refactor, then write the notes.
  • Write the contract before any class.
  • Put the rule that will change behind one interface.
  • Get a tested core running end to end.
  • Extend and refactor last, then write the notes.

Knowing it is half the job. Saying it is the other half.

Interview Clozo is an AI interview copilot for real interview rounds: it hears the question and puts a strong answer on your screen, and you say it in your own words. See the features or how it works.

Start Free Trial →

The Staff-level answer

Interviewer asks

You have a pair-programming hour. Implement a circuit breaker. How do you start?

A strong answer

I spend the first few minutes on the contract: the breaker wraps one call, counts consecutive failures, opens at a threshold, rejects while open, and after a wait lets a trial call through. I ask what counts as a failure and whether state is per process. Then I write three small pieces: a state type, a trip policy I can swap, and a clock I can fake.

The breaker itself stays thin, and I make its state update atomic so concurrent callers see one state. I get closed-to-open working with one test, then add half-open and the timeout. At the end I say what I left out: a shared store for many pods, metrics, and a failure-rate policy. The store and the policy already have a seam; metrics would hang off a listener.

What makes it Staff-level: the answer names its omissions and shows where each one would plug in, instead of claiming completeness.

The rubric

A stronger submission differs from a weaker one in tests, change readiness and how clearly it explains its choices.
DimensionWeak answerStrong answerStaff answer
CorrectnessWorks on the sample input onlyHandles the main path and the main failureAlso covers repeated trial failure and atomic state updates
DesignOne large class holds everythingSmall classes with clear jobsOne named seam for the rule most likely to change
TestsManual run onlyUnit tests for the main behaviourTests use a fake clock and cover each state change
CommunicationSilent, then a code dumpStates assumptions and narrates choicesNames trade-offs and what was left out
Follow-up readinessA new requirement forces a rewriteA new requirement needs a small editThe change drops into the seam with no rewrite

This table is advice about what a strong submission shows, not any company's scoring sheet.

Three variants of this question

What if the brief is a block editor with drag-and-drop and undo?

Model each block type behind one interface, keep the document as an ordered list, and make every edit an object with apply and revert so undo and redo are two stacks. Reordering by drag-and-drop is then one more edit object.

What if the take-home ends in a review of your own code?

Treat the README as your script for that review. Write the decisions and the omissions down while you remember them, and be ready to justify each seam.

What if the brief is a rate limiter with per-user and per-time limits?

Put the counting rule behind an interface and key the state by user. Inject the clock as in the breaker, so a time window can be tested without waiting.

Common mistakes

  • "I will start coding classes now." (wrong) Without a contract you build the wrong thing quickly. (right) "First I will confirm inputs, outputs, errors and what is out of scope."
  • "I used five design patterns." (wrong) Counting patterns says nothing about whether the code works or can change. (right) "I used one interface, where the rule is most likely to change."
  • "The breaker reads the system time inside its methods." (wrong) A test of the timeout must then wait. (right) "Time is passed in, so a fake clock can advance it."
  • "I will skip the tests and the README to finish the feature." (wrong) The reviewer then cannot see how you reason. (right) "A small tested core and a short README come before extras."
  • "I will rewrite it for the new requirement." (wrong) A rewrite throws away tested code. (right) "I refactor in small steps with the tests green, then add the feature."

Follow-up questions

Is a centralised store needed for a circuit breaker across many pods?

Not necessarily. Local state per pod is simple and adds no network dependency, but each pod learns about an outage separately. A shared store gives one view at the cost of an extra dependency on every call. Azure's guidance warns that many concurrent instances can use the same breaker and it must not block requests or add heavy overhead, so state the trade-off and keep the store behind a seam.

Is a circuit breaker the same as a retry or a rate limiter?

No. Azure's documentation says retry expects an operation to eventually succeed, while a circuit breaker stops an operation that is likely to fail; the two can be combined. A rate limiter is different again: it caps how often a caller may call, whether or not the service is healthy.

How do you test code that depends on time?

Pass the clock in as a parameter and use a fake clock in tests, so a wait of several calls or seconds takes no real time. Assert the state after each call, as in the trace above.

How is low-level design different from high-level (system) design?

Low-level design shapes the classes, interfaces and methods of one component, while high-level design arranges services, data stores and traffic between components. A system design interview is mostly high-level discussion; a machine-coding round asks for running low-level code with tests. Both reward stating assumptions and trade-offs.

What if the interviewer changes the requirement halfway?

Say what the change touches, check whether it fits a seam, and refactor one small step before adding it. The staff follow-up page covers how to handle that moment.

Key takeaways
  • A machine-coding take-home is a small program a reviewer runs and reads, so working code and tests come first.
  • Write the contract, then put the rule most likely to change behind one interface.
  • Inject the clock so time-based behaviour can be tested without waiting.
  • Extend in small steps with the tests green, and refactor rather than rewrite.
  • Close with a README that names what you left out and where it would plug in.

Sources

  1. Circuit Breaker — martinfowler.com (Martin Fowler), 6 Mar 2014
  2. Circuit Breaker pattern - Azure Architecture Center — Microsoft Learn, 26 Sep 2026