LLD Dojo

Designing under pressure · chapter 33 of 33

Your first full round, start to finish

Chapter 4.5 · Part 4, Designing under pressure · about 45 minutes

What you need before this chapter: chapters 4.1 to 4.4, and everything in Parts 1 to 3. This is the last chapter of the course. After it, the app takes over.

When you finish this chapter you will be able to:


1. Picking a problem

Everything in this chapter walks through one attempt at corpus/parking-lot, the problem chapters 4.1 through 4.3 already used. It is tier 1, the easiest tier in the corpus, and by now you have read its ambiguous prompt, its out_of_scope list, and a diagram of three of its classes. Starting your first real attempt on a problem you already partly know is not cheating. It means the first time you sit down to a full round, you are learning the shape of the round itself, not the shape of the problem at the same time.

A full round is eight rungs, called the Ladder inside the app. This chapter walks the first six, because they are the ones a single attempt actually uses.

2. Phase 0: vocabulary, with no thinking required

Before a clock ever starts, Phase 0 has you type a short list of constructs from a blank file until each one compiles in under ninety seconds, twice. An enum carrying its own behaviour is on the list, and so are a record value object, a sealed interface for a closed set of variants, an EnumMap, and a chain of Comparators. So is a builder once a constructor grows past four arguments, and the equals/hashCode contract. Round it out with a small exception hierarchy, and the four shapes that show up in almost every later problem: a policy interface, a factory, a listener, and a repository.

None of this is new material. Parts 1 to 3 taught every one of these constructs already. Phase 0 exists so that typing them stops being a decision you make mid-round. An interviewer's clock does not pause while you recall the exact syntax for a sealed interface. Phase 0's whole purpose is moving that recall below the level of thought, before the clock that actually matters starts.

3. Phase 1: requirement extraction, ten minutes, no code

This is chapter 4.1 and chapter 4.2, timed. Ten minutes, starting from prompt_ambiguous, ending with actors, entities, requirements, and an out_of_scope list. Add three clarifying questions and the core method signatures you expect your design to need, and the phase is done. No code gets written at any point in it.

Your answer is checked against must_haves, using the same stemmed word-overlap matcher chapter 4.1 described. You need to cover 80% of the reference list, phrased in your own words, to move on. A missed out_of_scope entry and a missed requirement route to two different lessons afterward, because skipping a requirement and forgetting to refuse a feature are two different mistakes with two different fixes.

4. Phase 2: the skeleton sprint, twelve minutes, types only

Twelve minutes to write enums, records, interfaces, and class stubs with real method signatures. No logic goes inside any method body yet. The one rule that matters is that it has to compile.

While you type, the editor tracks two required interface names live, in this problem's case PricingPolicy and SpotAllocator, and lights each one up the moment it exists. Everything else, every class name, every field, every private method, is entirely yours to choose. That is not a minor courtesy. It is the actual rule the grader runs on: hidden tests only ever call one file, Entry.create(), and everything on the far side of that one line is invisible to them. A test can never fail because you called a field idNumber where the reference called it vehicleNumber, because no test ever looks at a field. It can only see what ParkingLotApi declares.

This is worth saying plainly, because it answers the fear most people bring into a first attempt: the app will never fail you on naming. A design with a working park method and an oddly named internal class still passes. A design that never compiles, or whose Entry.create() never returns a working implementation, is not scored as a failure either. It is marked invalid, nothing is recorded against you, and you are told exactly which method is missing so you can run it again. Naming quality is not ignored entirely. It moves into how clearly your classes read as the actual problem, which is a small part of one dimension in section 8 below. There, it can cost you a fraction of a score. It can never zero one, and it can never be the reason a run does not count at all.

5. Phase 3: the core build, thirty minutes to a green suite

This is where logic goes in. Thirty minutes against a hidden JUnit suite whose @DisplayNames you can already read before you start, so you know exactly what is being checked without seeing the assertions that check it. A main method that actually runs your design end to end is not optional. Interviewers run the program before they read a line of the source. A submission with no working driver is treated as not functioning at all, whatever else the rest of the code gets right.

6. Phase 4: the curveball, fifteen minutes

Your working design from Phase 3 inherits a new requirement. For corpus/parking-lot, one of the recorded curveballs lets two motorbikes share a single standard spot. You get fifteen minutes to absorb it. Two numbers come out the other side: whether the new test suite passes, and how many lines you touched in files that already existed before the curveball landed. New files are free. Chapter 4.2 showed you the exact formula behind that second number. A scope decision you made ten minutes earlier, in Phase 1, is what this phase is quietly checking the bill for.

7. Phase 5: defence

Four kinds of question, asked in writing, clocked. Why this pattern here, rather than the obvious alternative? How would you extend the design for a named future requirement? What would break under two threads, and where would the actual race be? Answers are graded against the problem's own decision log, the same way your code was graded against must_haves. This single phase is 30 to 50% of a real interview's outcome, and almost nobody trains it alone. There is no compiler to say whether a written justification was any good.

8. The verdict

Every attempt is scored against five dimensions, and the weights are fixed:

DimensionWhat it checksWeightWho decides
D1Code design and structure30%a model, reading your code
D2Working functionality25%a compiler and a test runner
D3Design patterns and SOLID20%a model, reading your code
D4Extensibility15%a diff tool, measuring your curveball
D5Edge cases and error handling10%a test suite plus a model

Read that middle column again. D2 and D4, 40% of your score, never go through a model at all. A compiler either accepts your code or it does not. A test either passes or it does not. A diff tool counts lines whether you like the count or not. Nothing about those two numbers can be argued with, and that is deliberate: it is what makes the other 60% worth trusting.

Every dimension is scored on the same four levels: 0 for absent, 1 for attempted, 2 for competent, and 3 for exemplary. Level 2 is the hire bar, the score a candidate who actually gets the offer usually lands at. A weighted total at or above that bar earns a hire verdict, with one exception that overrides everything else. A single dimension scored at 0 is a no-hire regardless of what the rest of your total adds up to. A real interviewer rejects on exactly that pattern, one glaring gap, whatever else went well.

9. Demonstrated, and held

Passing one problem once is not the finish line. Every syllabus item, the 34 named skills chapters 1.1 through 4.4 have been teaching you, moves through three states. Not yet, meaning you have never cleared level 2 on it. Demonstrated, meaning you cleared level 2 once, with a date attached. Held, meaning you cleared level 2 twice, on two attempts at least three days apart.

Held is the real target, and the three-day gap is not an arbitrary delay. Reproducing a design choice on the evening you happened to read about it is one claim. Producing it cold, three days later, is a different and stronger one. The app's own summary of your progress reads like this: "21 of 34 demonstrated, 14 held," followed by exactly which items still need a second attempt. That sentence has a denominator, and the denominator does not move. Low-level design, at the level this app trains, is a closed list, not an unbounded pile of things you might still not know.

Going deeper

Section 8 said D2 and D4 never go through a model. The other three dimensions do, and the interesting question is what stops a model from grading the same code differently on two different days.

Every score above level 0 has to name evidence: a file and a line number, or a type name that actually appears in your submission. The harness checks each one mechanically before accepting the score at all. A cited file that does not exist in what you submitted, or a line number past the end of the file, gets the whole response rejected and asked for again once. If it fails a second time, that dimension is marked unscored rather than guessed at. Nothing is recorded against you for it, the same way a run that never compiles is marked invalid rather than failed. At level 2 or 3, the model also has to name counter_evidence, something that argues against the score it just gave, or say plainly that it found none. That forces it to go looking for a reason it might be wrong before it can finish grading. A model held to that standard is measurably harder to flatter than one that only has to justify a number it already picked.

One in six full rounds gets graded twice, independently, and both scores are kept. A one-level gap between the two is treated as normal disagreement. A gap of two or more is not read as evidence that your work was ambiguous. It is logged as a defect in the anchor itself, the wording that told the model what each level means, and that wording gets sharpened afterward. The standard is what is assumed to be broken when two readings disagree by that much, not you.

None of this makes the 60% as certain as the 40% a compiler decides. It means every uncertain score still has to show its work, in a form you can open and check line by line. You are never asked to trust a number that arrived with no reasoning attached. That is the actual bar for trusting a graded score: not that a model is never wrong, but that being wrong leaves a trail. You can read that trail, question it, and in the worst case, throw the score out without it costing you anything.

Next: close this course and open the Ladder. Pick corpus/parking-lot, tier 1, and start Phase 0. Type the vocabulary until it compiles twice under ninety seconds, then let Phase 1 hand you the same ambiguous prompt this chapter has been quoting from the start. You already know how to read it.

← 4.4 Two threads, one object · All chapters