System Design (High-Level Design) Module 30 – Interview practice and study plans
Study plans: one week, six weeks, three months
Three system design study plans, for one week, six weeks and three months, with what to study in which order, when to run mocks and how to tell you are ready.
What you will learn
- Choose a study plan that fits the time you have and the level you are aiming for
- Order fundamentals, building blocks and case studies so that each comes after what it builds on
- Measure readiness with self-mocks on new prompts instead of hours studied
Before you start
What you’ll learn · Before you start
What you will learn
- Choose a study plan that fits the time you have and the level you are aiming for
- Order fundamentals, building blocks and case studies so that each comes after what it builds on
- Measure readiness with self-mocks on new prompts instead of hours studied
Before you start
On this page
How to prepare for a design round depends on the time you have, but the order matters more than the amount. Every plan below studies the track in the order it builds: the method and estimation first, then fundamentals such as caching and replication, then building blocks, the recurring problems and, last, case studies. Every plan also starts with a self-mock in its first days and keeps running them, because a mock measures what the round measures.
- One week, the interview week, about 15 hours: the method, estimation, five building blocks and five case studies, with a mock every other day. It is triage for people who already build services.
- Six weeks, about 66 hours at 12 hours a week: every fundamentals module at reading depth, all the building blocks, twelve case studies and a mock every week.
- Three months, about 129 hours at 10 hours a week: the whole track in full, with postmortems of real outages for depth.
Whichever you choose, you are ready when three self-mocks in a row meet your target level on prompts you had not studied, not when some number of hours has passed. No plan can promise how a round will go; it can make sure the round is not the first time you design a system aloud.
Choose a plan by the time you have
Here is what each plan holds, by the track’s own time estimates:
- One week: 14 h 40 min at 2 h 30 min a day. Modules 1 and 2, five building blocks and five case studies, with 4 mocks. It suits engineers who already build services and whose round is close.
- Six weeks: 65 h 35 min at 12 hours a week. Modules 1 to 21, most of them at reading depth, and twelve case studies, with 6 mocks. It suits learners who know some fundamentals and have a month or more.
- Three months: 128 h 50 min at 10 hours a week. All 30 modules in full, every one of the track’s 59 case studies and four modules of postmortems, with 13 mocks. It suits newcomers, and anyone who wants the depth for work too.
If you have less time than a plan needs, take the shorter plan rather than squeezing the longer one into your days: a plan that runs out before its case studies leaves you with fundamentals you have never used in a whole design. The first lesson of the track plans a route module by module; the plans here go further, day by day or week by week, with the mocks in place and a check of the order.
The order every plan follows
Case studies come last because they are where everything else meets. This track’s URL shortener, for example, builds on 21 earlier lessons, from the estimation drills to an ID generator and the cache patterns; with the case study itself, that is about 9.5 hours of work by the track’s estimates. Together with the lessons they build on, the five case studies of the interview week come to 47 lessons and about 22 hours. A case study read before the lessons behind it can still teach its method, but the reasons for its choices will not make sense yet.
Mocks run through every plan from the first days. A mock before you have studied anything feels pointless, but it gives you scores to compare with later and shows which dimension needs the most work. It also helps you learn: in two experiments in which students read short texts, those who were tested on them remembered more after two days and after a week than those who reread them, although rereading did better on a test five minutes later and left students more confident (Roediger and Karpicke). A review of ten study techniques rated practice testing and distributed practice, spreading study over several sessions, as the most useful, and rereading and highlighting among the least (Dunlosky and colleagues). A mock is a practice test for design, and a plan that spreads lessons and mocks over days is distributed practice.
The loop every plan repeats, and when it ends
Text description of the diagram
The diagram is a loop of boxes joined by arrows, from top to bottom:
- Study the next block, in the track's order: method, fundamentals, building blocks, case studies.
- Self-mock on a new prompt: 45 minutes, recorded.
- Score the recording against the rubric.
- A decision: three new prompts in a row at the target level?
From the decision, "yes" leads to "Ready for the round". "Not yet" leads to "Practise the dimension furthest below target", and from there an arrow leads back to the first box, studying the next block.
The plans below are programs, so that every number in this lesson can be checked and changed. They share one file of helpers, which packs a plan’s blocks into days or weeks in order (a block of 45 minutes or less is never split, because a lesson is read in one sitting) and checks that each case study comes after the modules it builds on:
"""What the three study plans share: their blocks, packing them into days or weeks, and the order check.
Minutes are this track's own estimates for reading and doing each lesson; practice on your own comes on top.
"""
import textwrap
MOCK = 60 # a 45-minute round, then 15 minutes to score it from the recording
WHOLE = 45 # a block this short is never split: one lesson is read in one sitting
PIECE = 15 # a longer block is never cut into a piece shorter than this
# Minutes of each module of the track: the sum of its lessons' estimates.
MODULE_MINUTES = {
1: 135, 2: 145, 3: 255, 4: 180, 5: 200, 6: 245, 7: 160, 8: 145, 9: 160, 10: 175,
11: 135, 12: 175, 13: 160, 14: 190, 15: 160, 16: 190, 17: 165, 18: 175, 19: 385, 20: 345,
21: 215, 22: 340, 23: 330, 24: 340, 25: 265, 26: 295, 27: 235, 28: 180, 29: 210, 30: 85,
}
# Case studies: their minutes, and the modules that hold every lesson they build on, however far back.
CASES = {
"real-time leaderboard": (30, {1, 6, 9}),
"web crawler": (40, {1, 2, 4, 5, 12, 14}),
"search autocomplete": (35, {1, 2, 4, 5, 6, 9, 12, 14}),
"top-k trending": (35, {1, 2, 4, 5, 6, 9, 12, 14}),
"music streaming": (35, {1, 2, 4, 6, 15}),
"URL shortener": (40, {1, 2, 3, 4, 6, 7, 8, 10, 19}),
"file sync": (40, {1, 2, 3, 4, 5, 6, 12, 15, 19, 20}),
"calendar": (35, {1, 2, 3, 4, 5, 6, 8, 10, 12, 19, 20}),
"news feed": (40, {1, 2, 4, 5, 6, 7, 9, 12, 21}),
"chat delivery": (40, {1, 2, 4, 5, 6, 9, 12, 19, 21}),
"movie seat booking": (40, {1, 2, 3, 6, 8, 10, 21}),
"ride-hailing matching": (40, {1, 2, 4, 5, 6, 12, 14, 19, 21}),
}
# A block is (label, minutes, key): the key is a module's number, a case study's name, or None.
def module(number, share=1.0):
"""A whole module; a share below 1 reads it faster (rounded to 5 minutes)."""
return (f"module {number}", round(MODULE_MINUTES[number] * share / 5) * 5, number)
def case(name):
return (name, CASES[name][0], name)
def lesson(name, minutes):
return (name, minutes, None)
def with_cases(blocks, names):
"""The blocks, with each case study placed right after the last module it builds on."""
out, done, waiting = [], set(), list(names)
for block in blocks:
out.append(block)
if isinstance(block[2], int):
done.add(block[2])
for name in [n for n in waiting if CASES[n][1] <= done]:
out.append(case(name))
waiting.remove(name)
return out + [case(name) for name in waiting]
def order_problems(blocks):
"""Each case study that starts before modules it builds on, with those modules."""
done, problems = set(), []
for label, _, key in blocks:
if isinstance(key, int):
done.add(key)
elif key in CASES and not CASES[key][1] <= done:
problems.append((label, sorted(CASES[key][1] - done)))
return problems
def pack(blocks, minutes_per_slot, slots, mock_slots):
"""Fill the slots (days or weeks) with the blocks in order; each slot in mock_slots starts with a mock.
Returns one list of (text, minutes) per slot, and the labels of the blocks that did not fit.
"""
queue = [[label, minutes, minutes] for label, minutes, _ in blocks] # label, minutes left, minutes in all
plan, mocks = [], 0
for slot in range(slots):
room, items = minutes_per_slot, []
if slot in mock_slots:
mocks += 1
items.append((f"mock {mocks}", MOCK))
room -= MOCK
while queue and room > 0:
label, left, total = queue[0]
if left > room and total <= WHOLE:
break # a short block waits for the next slot
used = min(left, room)
if used < left: # the block is cut: leave at least PIECE minutes of it for later
used = min(used, left - PIECE)
if used < PIECE:
break # too little room to be worth starting: the rest of the slot stays spare
if used == total:
text = label
elif left == total:
text = f"{label} ({used} of {total} min)"
elif used == left:
text = f"{label} (last {used} min)"
else:
text = f"{label} ({used} more min)"
items.append((text, used))
room -= used
queue[0][1] -= used
if queue[0][1] == 0:
queue.pop(0)
plan.append(items)
return plan, [label for label, _, _ in queue]
def hm(minutes):
"""870 -> '14 h 30 min'."""
h, m = divmod(minutes, 60)
return " ".join(part for part in (f"{h} h" if h else "", f"{m} min" if m else "") if part) or "0 min"
def joined(texts):
"""'module 3; module 4; module 5' -> 'modules 3 to 5': runs of whole modules are written as one item."""
out, run = [], []
for text in texts + [""]:
if text.startswith("module ") and text[7:].isdigit() and (not run or int(text[7:]) == run[-1] + 1):
run.append(int(text[7:]))
continue
if len(run) == 1:
out.append(f"module {run[0]}")
elif len(run) == 2:
out.append(f"modules {run[0]} and {run[1]}")
elif run:
out.append(f"modules {run[0]} to {run[-1]}")
run = []
if text.startswith("module ") and text[7:].isdigit():
run.append(int(text[7:]))
elif text:
out.append(text)
return "; ".join(out)
def show(title, plan, leftover, unit, minutes_per_slot):
"""Print the plan, one slot a paragraph."""
print(title)
planned = 0
for number, items in enumerate(plan, 1):
planned += sum(minutes for _, minutes in items)
head = f" {unit} {number}".ljust(10)
print(textwrap.fill(joined([text for text, _ in items]) or "spare", 76, initial_indent=head, subsequent_indent=" " * 10))
print(f" Planned {hm(planned)} of {hm(minutes_per_slot * len(plan))}.")
if leftover:
print(f" Not in the plan: {', '.join(leftover)}.") One week: the interview week
The week covers the method (module 1) and estimation (module 2) in full, then five building blocks the five case studies lean on: unique IDs for the URL shortener, a distributed cache for the shortener and the news feed, publish-subscribe messaging for chat delivery and ride-hailing matching, a lock service for seat booking, and rate limiting, which almost every public service needs. A mock opens days 1, 3, 5 and 7, and the first one is taken before any study, as a baseline.
"""The interview week: the method and estimation in full, five building blocks and five case studies, with a
mock on days 1, 3, 5 and 7. The first mock is a baseline, taken before any study."""
from planner import case, lesson, module, order_problems, pack, show
BLOCKS = [
module(1),
module(2),
lesson("unique IDs", 35),
lesson("distributed cache", 35),
lesson("pub-sub", 30),
lesson("lock service", 30),
lesson("rate limiting", 30),
case("URL shortener"),
case("news feed"),
case("chat delivery"),
case("movie seat booking"),
case("ride-hailing matching"),
]
plan, leftover = pack(BLOCKS, minutes_per_slot=150, slots=7, mock_slots={0, 2, 4, 6})
show("The interview week: 7 days of 2 h 30 min", plan, leftover, "Day", 150)
print(" Order check:")
for name, missing in order_problems(BLOCKS):
print(f" {name} builds on {len(missing)} modules that this week skips") Output
The interview week: 7 days of 2 h 30 min
Day 1 mock 1; module 1 (90 of 135 min)
Day 2 module 1 (last 45 min); module 2 (105 of 145 min)
Day 3 mock 2; module 2 (last 40 min); unique IDs
Day 4 distributed cache; pub-sub; lock service; rate limiting
Day 5 mock 3; URL shortener; news feed
Day 6 chat delivery; movie seat booking; ride-hailing matching
Day 7 mock 4
Planned 14 h 40 min of 17 h 30 min.
Order check:
URL shortener builds on 7 modules that this week skips
news feed builds on 7 modules that this week skips
chat delivery builds on 7 modules that this week skips
movie seat booking builds on 5 modules that this week skips
ride-hailing matching builds on 7 modules that this week skips
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 one_week.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
The week fits into 2 hours 30 minutes a day with almost three hours to spare, and the spare hours matter: after each mock, spend them on the dimension that scored lowest instead of on new material.
The order check at the end is honest about the cost. Each case study builds on five to seven modules that the week leaves out, and with those lessons the five come to the 47 lessons and 22 hours counted above. The week works for someone who already builds services and knows most of those ideas. For someone new to the subject it is triage, and the six-week plan is the real preparation.
Six weeks
Six weeks read modules 1 and 2 and the building blocks and recurring problems (modules 19 to 21) in full, and modules 3 to 18 at reading depth: about two thirds of their estimated time, enough to read each lesson and run its examples while leaving the exercises for later. Twelve case studies are added, each right after the last module it builds on, and a mock opens every week.
"""Six weeks of 12 hours: modules 1 and 2 in full, modules 3 to 18 at reading depth (two thirds of their time:
read and run the examples, leave the exercises), the building blocks and recurring problems (19 to 21) in full,
twelve case studies, each right after the last module it builds on, and a mock to open every week."""
from planner import CASES, module, order_problems, pack, show, with_cases
READING = 2 / 3
MODULES = [module(1), module(2)] + [module(n, READING) for n in range(3, 19)] + [module(n) for n in (19, 20, 21)]
BLOCKS = with_cases(MODULES, CASES)
plan, leftover = pack(BLOCKS, minutes_per_slot=12 * 60, slots=6, mock_slots=set(range(6)))
show("Six weeks of 12 hours", plan, leftover, "Week", 12 * 60)
problems = order_problems(BLOCKS)
print(" Order check:", "every case study comes after what it builds on." if not problems else problems) Output
Six weeks of 12 hours
Week 1 mock 1; modules 1 to 4; module 5 (90 of 135 min)
Week 2 mock 2; module 5 (last 45 min); modules 6 to 9; real-time
leaderboard; module 10
Week 3 mock 3; modules 11 to 14; web crawler; search autocomplete; top-k
trending; module 15
Week 4 mock 4; music streaming; modules 16 to 18; module 19 (275 of 385
min)
Week 5 mock 5; module 19 (last 110 min); URL shortener; module 20; file
sync; calendar; module 21 (90 of 215 min)
Week 6 mock 6; module 21 (last 125 min); news feed; chat delivery; movie
seat booking; ride-hailing matching
Planned 65 h 35 min of 72 h.
Order check: every case study comes after what it builds on.
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 six_weeks.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
The case studies do not arrive two a week, as a neat timetable would place them. Each one waits for the last module it builds on, so the real-time leaderboard comes in week 2, three studies follow in week 3, and the URL shortener waits for the building blocks in week 5; four of the twelve land in the last week. That is the order check doing its job. The 6 h 25 min to spare make room for a second mock in each of the last two weeks, once the case studies give the mocks more to work with.
Three months
Three months cover the whole track in full: all 211 lessons, about 106 hours by their estimates, with their exercises. After the observability and delivery modules, the plan adds four modules of postmortems from the Systems Papers & Postmortems track: how real systems failed under overload, bad configuration, failover and shared dependencies, which is depth that case studies alone do not give.
"""Three months of 10 hours a week: the whole track in order and in full, four modules of postmortems from the
Systems Papers & Postmortems track after module 18, and a mock to open every week."""
from planner import lesson, module, pack, show
POSTMORTEMS = [
lesson("postmortems: overload and retries", 135),
lesson("postmortems: configuration and deploys", 200),
lesson("postmortems: failover and operators", 105),
lesson("postmortems: shared dependencies", 135),
]
BLOCKS = [module(n) for n in range(1, 19)] + POSTMORTEMS + [module(n) for n in range(19, 31)]
plan, leftover = pack(BLOCKS, minutes_per_slot=10 * 60, slots=13, mock_slots=set(range(13)))
show("Three months: 13 weeks of 10 hours", plan, leftover, "Week", 10 * 60) Output
Three months: 13 weeks of 10 hours
Week 1 mock 1; modules 1 to 3
Week 2 mock 2; modules 4 and 5; module 6 (160 of 245 min)
Week 3 mock 3; module 6 (last 85 min); modules 7 and 8; module 9 (145 of
160 min)
Week 4 mock 4; module 9 (last 15 min); modules 10 to 12; module 13 (40 of
160 min)
Week 5 mock 5; module 13 (last 120 min); modules 14 and 15; module 16 (70
of 190 min)
Week 6 mock 6; module 16 (last 120 min); modules 17 and 18; postmortems:
overload and retries (80 of 135 min)
Week 7 mock 7; postmortems: overload and retries (last 55 min);
postmortems: configuration and deploys; postmortems: failover and
operators; postmortems: shared dependencies; module 19 (45 of 385
min)
Week 8 mock 8; module 19 (last 340 min); module 20 (200 of 345 min)
Week 9 mock 9; module 20 (last 145 min); module 21; module 22 (180 of 340
min)
Week 10 mock 10; module 22 (last 160 min); module 23; module 24 (50 of 340
min)
Week 11 mock 11; module 24 (last 290 min); module 25 (250 of 265 min)
Week 12 mock 12; module 25 (last 15 min); module 26; module 27 (220 of 235
min)
Week 13 mock 13; module 27 (last 15 min); modules 28 to 30
Planned 128 h 50 min of 130 h.
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 three_months.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
At 10 hours a week the plan fits with 1 h 10 min to spare, which is tight. If your weeks are shorter, stretch the plan to 14 or 15 weeks rather than dropping the mocks. Every case study comes after the modules it builds on here by construction, because the track’s own order puts the fundamentals first.
Press Edit on any plan to change its hours or move its blocks. In the first two plans, the order check says when a case study has moved in front of what it builds on.
Study Planner & Revision Timetable Lay a plan out as a timetable, with reviews spaced between the study sessions.When you are ready: mocks, not hours
Hours studied measure effort, not readiness. The round measures how you handle a problem you have not seen, so the signal is a run of mocks: three in a row at or above your target level, each on a prompt you had not studied, each scored from a recording with the rubric from How design rounds are assessed. A studied prompt does not count, because it measures how well you remember one answer. Three in a row, because one good mock can be luck: if every mock had an even chance of a lucky score, three lucky ones in a row would come about one time in eight.
The program below applies the rule to two logs of mocks:
"""Readiness from a log of self-mocks: three in a row at or above the target level, each on a new prompt.
A mock on a prompt you had studied before is listed, but it neither counts nor breaks the run: it shows how well
you remember that answer. A mock on a new prompt below the target starts the run again. Levels are read with the
rubric of the lesson on how design rounds are assessed.
"""
# The lowest score each level expects on navigation, design, depth and communication.
BARS = {"fresher": (2, 2, 2, 2), "mid": (3, 3, 2, 2), "senior": (3, 3, 3, 3), "staff": (4, 4, 4, 3)}
LEVELS = list(BARS)
IN_A_ROW = 3
def level_reached(scores):
"""The highest level whose bar every score meets, or None below the lowest bar."""
reached = None
for level, bar in BARS.items():
if any(score < low for score, low in zip(scores, bar)):
break
reached = level
return reached
def check(target, log):
print(f"Target: {target}")
run = 0
for number, (prompt, studied, scores) in enumerate(log, 1):
level = level_reached(scores)
if studied:
note = "studied: not counted"
elif level is not None and LEVELS.index(level) >= LEVELS.index(target):
run += 1
note = f"{run} in a row"
else:
run = 0
note = "below target: restart"
marks = " ".join(map(str, scores))
print(f" {number}. {prompt:<23} {marks} {level or 'none':<7} {note}")
if run >= IN_A_ROW:
print(f" Ready: the last {run} new prompts all met the {target} bar.")
else:
print(f" Not yet: {run} of {IN_A_ROW} new prompts in a row.")
check("senior", [
("URL shortener", True, (3, 3, 3, 3)),
("parking payments", False, (3, 3, 2, 3)),
("live quiz scores", False, (3, 3, 3, 3)),
("appointment reminders", True, (3, 4, 3, 3)),
("shared shopping lists", False, (3, 3, 3, 4)),
("bus arrival boards", False, (4, 3, 3, 3)),
])
print()
check("mid", [
("paste service", True, (3, 3, 2, 3)),
("URL shortener", True, (3, 3, 3, 2)),
("news feed", True, (3, 3, 2, 2)),
("photo print orders", False, (2, 3, 2, 2)),
]) Output
Target: senior 1. URL shortener 3 3 3 3 senior studied: not counted 2. parking payments 3 3 2 3 mid below target: restart 3. live quiz scores 3 3 3 3 senior 1 in a row 4. appointment reminders 3 4 3 3 senior studied: not counted 5. shared shopping lists 3 3 3 4 senior 2 in a row 6. bus arrival boards 4 3 3 3 senior 3 in a row Ready: the last 3 new prompts all met the senior bar. Target: mid 1. paste service 3 3 2 3 mid studied: not counted 2. URL shortener 3 3 3 2 mid studied: not counted 3. news feed 3 3 2 2 mid studied: not counted 4. photo print orders 2 3 2 2 fresher below target: restart Not yet: 0 of 3 new prompts in a row.
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 readiness.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
- The first learner met the senior bar on a studied prompt in mock 1, which proves nothing, then missed it on a new prompt, then met it on three new prompts in a row. The studied prompt in mock 4 neither counted nor broke the run.
- The second learner met the mid bar three times, but always on studied prompts, and reached only the fresher bar on the one new prompt. That is a common trap: practising the same few prompts until they score well. The way out is new prompts from the first week, and the spare hours spent on the dimension that dropped.
New prompts are easy to find: take a case study of this track that you have not read, use its title as the prompt, and read it only after you have scored your mock.
Interview questions
What is a better sign that you are ready for a design round than the hours you have studied?
Mock results on prompts you have not studied. Hours measure effort, not what you can do with a new problem in 45 minutes. A practical rule is three self-mocks in a row at or above your target level, each on a new prompt, scored from a recording against a written rubric. A mock on a prompt you have practised mostly measures how well you remember that answer, so it does not count, and one good result can be luck, which is why the rule asks for three in a row.
Key takeaways
- Choose the plan by the time you have: the interview week (about 15 hours) is triage for people who already build services, six weeks (about 66 hours) is real preparation, and three months (about 129 hours) covers the whole track in full.
- Study in the order the track builds: method and estimation, fundamentals, building blocks, recurring problems, case studies.
- A case study waits for what it builds on: with the lessons behind them, the five case studies of the interview week come to 47 lessons and about 22 hours.
- Take a baseline mock in the first days and keep taking them: testing yourself helps you remember more than rereading does.
- You are ready after three mocks in a row at your target level, each on a prompt you had not studied.
Exercise
Exercise · Easy · Python
Check that a study plan puts every lesson after its prerequisites
A plan you write yourself is easy to get out of order: a case study the day before the building block it relies on. Write prerequisite_problems(plan, prerequisites) in order_check.py so that it finds every such problem.
planis a list of lesson slugs in the order you will study them, such as["what-is-system-design", "requirements-and-scope", "delivery-framework"].prerequisitesis a dictionary from a lesson's slug to the list of lessons it builds on directly. A lesson that is not a key has no prerequisites.
Return a list of pairs (lesson, prerequisite) for every prerequisite that is not studied before its lesson, either because it comes later in the plan or because it is not in the plan at all. List them in plan order, and for one lesson in the order its prerequisites are listed. A plan with no problems gives []. A lesson that appears twice in the plan is a mistake: raise ValueError.
The sample tests use real lessons of this track with their prerequisites, import the function from order_check.py and run in your browser.
Starter code · order_check.py
def prerequisite_problems(plan, prerequisites):
"""Every (lesson, prerequisite) pair of the plan whose prerequisite is not studied before the lesson."""
# Replace this line with your code.
return None The sample tests · test_order_check.py
from order_check import prerequisite_problems
# Lessons of this track and the lessons each one builds on directly.
PREREQUISITES = {
"requirements-and-scope": ["what-is-system-design"],
"quality-attributes-and-trade-offs": ["requirements-and-scope"],
"delivery-framework": ["requirements-and-scope", "quality-attributes-and-trade-offs"],
"units-and-powers-of-two": ["what-is-system-design"],
"estimating-traffic": ["units-and-powers-of-two"],
"where-caches-live": ["life-of-a-request"],
"cache-read-write-patterns": ["where-caches-live"],
"design-url-shortener": ["estimation-drills", "bb-unique-id-generator", "cache-read-write-patterns"],
}
def test_in_order():
"""a plan in order has no problems"""
plan = ["what-is-system-design", "requirements-and-scope", "quality-attributes-and-trade-offs", "delivery-framework"]
assert prerequisite_problems(plan, PREREQUISITES) == []
assert prerequisite_problems([], PREREQUISITES) == []
def test_comes_later():
"""a prerequisite that comes later in the plan is a problem"""
plan = ["what-is-system-design", "requirements-and-scope", "delivery-framework", "quality-attributes-and-trade-offs"]
assert prerequisite_problems(plan, PREREQUISITES) == [("delivery-framework", "quality-attributes-and-trade-offs")]
def test_missing():
"""a prerequisite that is not in the plan at all is a problem too, listed in order"""
plan = ["life-of-a-request", "where-caches-live", "estimation-drills", "design-url-shortener", "cache-read-write-patterns"]
assert prerequisite_problems(plan, PREREQUISITES) == [
("design-url-shortener", "bb-unique-id-generator"),
("design-url-shortener", "cache-read-write-patterns"),
]
def test_plan_order():
"""problems come in plan order, and lessons without prerequisites are fine"""
plan = ["estimating-traffic", "units-and-powers-of-two", "requirements-and-scope", "what-is-system-design"]
assert prerequisite_problems(plan, PREREQUISITES) == [
("estimating-traffic", "units-and-powers-of-two"),
("units-and-powers-of-two", "what-is-system-design"),
("requirements-and-scope", "what-is-system-design"),
]
def test_repeated_lesson():
"""a lesson twice in the plan raises ValueError"""
try:
prerequisite_problems(["what-is-system-design", "requirements-and-scope", "what-is-system-design"], PREREQUISITES)
except ValueError:
return
raise AssertionError("expected a ValueError") A hint
Walk through the plan once, keeping a set of the lessons studied so far. For each lesson, look up prerequisites.get(lesson, []) and add a pair for every prerequisite that is not in the set yet; then add the lesson to the set. Check for a repeated lesson first: len(set(plan)) is smaller than len(plan) when one is repeated.
Results of the sample tests
| Test | Result | Details |
|---|
What your code printed
The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.
Check yourself
6 questions about this lesson. Every answer and why it is right is on the page, behind “Show the answer”. Your score stays in this browser.
References
- Test-enhanced learning: taking memory tests improves long-term retention (Psychological Science (PubMed record))
- Improving Students' Learning With Effective Learning Techniques (Psychological Science in the Public Interest (PubMed record))
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress