Beginner12 min readMachine Coding Practicelive prototype

A repeatable 5-step framework

In a machine coding round you get one problem, one hour, and one rule: it must run at the end. The framework is the order you do things in — clarify → entities → API → diagram → code — so you spend the hour building instead of guessing. Same five steps for a parking lot, a vending machine, or Splitwise. Only the nouns change.

The idea

What it is

A machine coding round is simple to describe and hard to survive: you get one problem statement ("design a parking lot"), 60–90 minutes, and at the end your code has to actually run. No slides, no hand-waving. Most people fail it the same way — they read the problem, feel the clock, and start typing immediately. Twenty minutes later they realise they modelled the wrong thing, and the rewrite eats the round.

The fix is boring and it always works: do the same five steps, in the same order, every single time. Clarify the problem, name the entities, fix the API, draw the class diagram, then code. Roughly 20 minutes of thinking buys you 40 minutes of typing that you never have to undo.

The whole framework in one line

Clarify → Entities → API → Class diagram → Code & demo. Each step produces something you can point at, and each one feeds the next: the questions decide the nouns, the nouns become classes, the classes get methods, the methods get wired, and the wiring gets typed out.

Why an order helps at all

Every step removes decisions from the step after it. By the time you start typing, you already know what classes exist, what they're called, what methods they have, and who holds whom — so coding becomes transcription instead of design. That's why it feels faster, not slower.

Mechanics

How it works

Step 1 · Clarify — about 5 minutes

The problem statement is deliberately vague. Your first job is to shrink it. Ask a handful of short questions and write the answers down where you can see them — that written list is your scope, and it is the thing you'll point at later when you decide not to build something.

  • How big? — one floor or many, 30 spots or 30,000. This decides whether a plain list is fine.
  • What kinds? — bike, car, truck. Types usually turn into an enum and a sizing rule.
  • What are the rules? — how the fee is charged, what happens when the lot is full.
  • What's out? — payments, login, UI, persistence. A question that removes work is the most valuable one you can ask.

The two questions that waste your clock

"Which database?" and "What should the UI look like?" — in a 60-minute round the answers are always in-memory and a main() demo. Assume them out loud in one sentence and move on. Time spent in a rabbit hole is time not spent on code that runs.

Step 2 · Entities — about 8 minutes

Read your clarified statement and underline the nouns. Nouns are candidate classes; verbs are candidate methods. Parking lot, spot, vehicle, ticket → four classes. Park, unpark, calculate fee → three methods that will live on those classes.

Keep the names the same as the words the interviewer used. If they said "ticket", your class is Ticket — not ParkingReceiptEntity. And don't invent a class that isn't in the problem: ParkingLotManagerFactoryImpl is a red flag, not a design.

Step 3 · API — about 10 minutes

Before any implementation, write the method signatures a caller would use. Just the shapes — name, parameters, return type. Three or four of them usually describe the entire system:

text
lot.park(vehicle)            -> Ticket
lot.unpark(ticket)           -> Fee
lot.availableSpots(type)     -> int

This is the step people skip, and it's the one that saves the most time. Once the signatures are fixed, every later decision has an answer: does this method belong here? does this class need that field? — you check against the API. Getters and setters are not the API; they're plumbing you add when a method actually needs them.

Step 4 · Class diagram — about 7 minutes

Now connect the boxes. For each pair of classes ask one question: has-a or is-a? A ParkingLot has many ParkingSpots. A ParkingSpot holds one Vehicle (or none). A Car is a Vehicle. That's it — three relationships and the design is settled.

The classic wrong turn

Reaching for extends when you mean "has a". A ParkingSpot is not a kind of Vehicle just because it holds one. Inheritance is only for is-a; everything else is a field. See Composition vs Inheritance.

This is also the only moment to consider a design pattern — and only if a force in the problem demands it. "Fees are hourly or flat or weekend rates" is a real force → Strategy. "A spot's state drives what you can do to it" → State. No force, no pattern: a plain method is the right answer far more often than a pattern is. See Pattern overuse & anti-patterns.

Step 5 · Code & demo — the remaining ~30 minutes

Code in an order that keeps you demo-able at every moment, so that whenever the timer stops you have something that runs:

  1. Skeletons — the classes and enums from step 2, fields only. Ten minutes of typing, no thinking.
  2. The happy pathpark() end to end. No edge cases yet.
  3. The return tripunpark() and the fee. Now the loop closes.
  4. A main() demo — park two vehicles, unpark one, print the result. This is your test; it's what you run in front of the interviewer.
  5. Edge cases, if time is left — lot full, invalid ticket, wrong vehicle type.

Working beats complete

A small system that runs scores far higher than a large one that doesn't compile. If you're at minute 50 with an unfinished feature, stub it, get the demo green, and say what you'd do next — interviewers grade the thinking too.

What the interviewer is actually grading

  • Does it run? — the one non-negotiable.
  • Is the model sensible? — do the class names match the domain, and does behaviour live inside the class that owns the data?
  • Can it be extended? — if they say "now add electric-vehicle charging", how many files do you touch? One new class is a great answer; a giant switch you have to edit is a poor one.
  • Is it readable? — small methods, clear names, no dead code. Nobody is grading cleverness.

Interactive prototype

See it. Build it. Break it.

A sandboxed, hands-on simulation — no setup, no install. Play with it as you read.

About this simulation

A live 60-minute machine coding roundDesign a Parking Lot. Work the five steps on the left; the design document on the right builds itself as you go: scope lines, class chips, method signatures, a wired class diagram, then code. Every good pick spends its budgeted minutes; every rabbit hole (which database? what colour is the UI?) costs you +2 minutes of rework on the clock. Finish all five and ▶ Run the demo prints working output at minute 60. Or hit ⏭ Skip the plan, just code to see the other ending: the clock jumps straight to 60, the board fills with ✖, and nothing runs.

Hands-on

Try these yourself

Open the prototype above, predict what happens, then verify.

try 01

Ask the questions that shrink the problem

In the prototype, step 1 gives you six questions. Pick three that pin down scope — how many spots, which vehicle types, how the fee works, whether payments are real. Each one lands as a line in the Scope section on the right, and the clock advances by its budgeted minutes. Notice that "Real payment gateway?" is worth asking precisely because the answer removes work.

try 02

Step into a rabbit hole on purpose

Now click "Which database?" or "What should the UI look like?". The chip shakes red, nothing lands on the board, and the clock jumps +2 minutes with a rework counter. That's the whole lesson about clarifying: not every question is worth 2 minutes of a 60-minute round. Assume in-memory, assume a main() demo, keep moving.

try 03

Run the round end to end — then skip it

Work through entities → API → diagram → code. Watch the right-hand board fill in: class chips, then method signatures, then real lines connecting ParkingLot ◆— ParkingSpot — Vehicle. Hit ▶ Run the demo and the output prints at minute 60. Now press ↺ Reset and instead hit ⏭ Skip the plan, just code: the clock jumps straight to 60, every section fills with ✖, and there's no demo to show. Same hour, opposite ending.

In practice

When to use it — and what trips people up

Use the framework when...

  • You're in a timed machine coding round — this is exactly what it was built for. 60–90 minutes, one problem, code that must run.
  • You're in an object-oriented design interview — the same five steps, minus the typing. You just talk through steps 1–4 and sketch instead of code.
  • You're starting any small feature at work — clarify, name the things, agree the API, sketch the wiring, then build. It scales down fine.

Bend it when...

  • The interviewer hands you the entities already — if the prompt lists the classes, steps 1–2 shrink to two minutes. Don't perform the ritual, use the time saved on code.
  • The problem is one algorithm, not a system — an LRU cache is 80% data structure. Clarify, agree the API, and start coding; a class diagram of two boxes helps nobody.
  • You're at minute 40 with nothing running — abandon polish, get main() green. A demo that works beats a diagram that's beautiful.

What it gives you

  • No rewrites — the expensive mistake (wrong model discovered at minute 40) is caught at minute 10 when it costs nothing.
  • The clock stops being scary — each step has a budget, so you always know whether you're ahead or behind.
  • You always have something to show — coding happy-path-first means there's a running demo at every moment after minute 35.
  • It's problem-agnostic — parking lot, vending machine, Splitwise, chess: the same five steps, only the nouns change.
  • It makes your thinking visible — the interviewer sees scope, entities and an API, which is most of what they're grading.

Common mistakes

  • It costs ~20 minutes up front, which feels wrong when the clock is running and your hands want to type.
  • Done rigidly it wastes time — a two-box class diagram for an LRU cache is ceremony, not design.
  • Step 4 tempts you into patterns — the diagram invites a Strategy or a Factory that the problem never asked for.
  • Steps 1–4 can drift long — without a per-step budget, clarifying quietly eats the coding time it was meant to protect.

Reference

Code & further reading

A minimal reference implementation and pointers worth bookmarking.

// STEP 1 · scope (write it down, it decides everything below)
//   1 floor · 30 spots · Bike|Car|Truck · ₹/hour paid at exit
//   out of scope: payments, UI, database

// STEP 2 · entities — the nouns of the problem
enum VehicleType { BIKE, CAR, TRUCK }

class Vehicle {
  constructor(readonly plate: string, readonly type: VehicleType) {}
}

class ParkingSpot {
  vehicle: Vehicle | null = null;                 // has-a, not is-a
  constructor(readonly id: string, readonly type: VehicleType) {}
  get isFree() { return this.vehicle === null; }
}

class Ticket {
  constructor(
    readonly id: string,
    readonly spot: ParkingSpot,                   // issued FOR a spot
    readonly inTime: number,
  ) {}
}

// STEP 3 · API — three methods describe the whole system
class ParkingLot {
  private seq = 0;
  constructor(private spots: ParkingSpot[], private ratePerHour = 30) {}

  park(vehicle: Vehicle): Ticket {                // happy path first
    const spot = this.spots.find(s => s.isFree && s.type === vehicle.type);
    if (!spot) throw new Error("lot full for " + VehicleType[vehicle.type]);
    spot.vehicle = vehicle;
    return new Ticket("T" + ++this.seq, spot, Date.now());
  }

  unpark(ticket: Ticket): number {                // the return trip
    const hours = Math.max(1, Math.ceil((Date.now() - ticket.inTime) / 3_600_000));
    ticket.spot.vehicle = null;                   // free the spot
    return hours * this.ratePerHour;              // the fee
  }

  availableSpots(type: VehicleType): number {
    return this.spots.filter(s => s.isFree && s.type === type).length;
  }
}

// STEP 5 · main() demo — this is what you RUN for the interviewer
const spots = [new ParkingSpot("S1", VehicleType.CAR), new ParkingSpot("S2", VehicleType.BIKE)];
const lot = new ParkingLot(spots);

const t1 = lot.park(new Vehicle("KA-01", VehicleType.CAR));
console.log("parked ->", t1.id, t1.spot.id);
console.log("fee    ->", lot.unpark(t1));
console.log("free   ->", lot.availableSpots(VehicleType.CAR));

References & further reading

7 sources

Knowledge check

Did it land?

Quick questions, answers revealed on submit. Sign in to save your best score.

question 01 / 06

What are the five steps, in order?

question 02 / 06

In a 60-minute round, what is the best use of the first five minutes?

question 03 / 06

You ask the interviewer "which database should I use?". What has that question cost you?

question 04 / 06

In step 2 you're pulling entities out of the statement. Which of these should NOT become a class?

question 05 / 06

In step 4 you need to relate ParkingSpot and Vehicle. Which is right?

question 06 / 06

It's minute 50, and your extra features aren't finished. What's the best move?

0/6 answered