Course contents

Capstone — mock interview drill (Music Playlist)

Sign in to run this lab and save your progress

Learn

Before you start

This lesson simulates a real 45-minute design interview slot. Read the problem. Set a timer. Design. Implement. Test.

Why timed

Real interviews are timed. Every hour has a shape:

  • First 5 min — clarify. Take notes.
  • Next 10 min — sketch entities, name patterns.
  • Next 25 min — write real code.
  • Last 5 min — walk through your design with the interviewer.

Untimed practice teaches design thinking. Timed practice teaches design UNDER PRESSURE. Different muscle.

How to actually time yourself

  1. Read the problem once, briefly.
  2. Set a timer for 45 minutes.
  3. Start.
  4. When it goes off — STOP whatever you're doing. Note where you are.
  5. THEN keep going to finish (untimed).

That "stop and note" moment is where the learning is. Did you finish? Did you spend all your time in design? Did you rush the implementation? Different failure modes, different fixes.

The problem's design signals

Music Playlist has two patterns worth naming:

  • Strategy for playback order — sequential vs shuffle. Different algorithms, same "give me the next song" question.
  • State for playback — idle / playing / paused. But three states with a single field is defensible compared to full State classes. Argue both.

Whether you use them, don't use them, or use them in combination — pin your reasoning.

The rules discipline (last time in this course)

Three rules matter:

  1. Playlists hold only known songs. Enforced at add_to_playlist by checking the song exists in the catalog.
  2. Playback position is always valid after next/prev. Enforced by modular arithmetic — you can't overshoot.
  3. Users only touch their own playlists. Enforced by... actually, we didn't say this in the requirements. You have a choice: enforce it and add tests, or say in Trade-offs that you skipped it for scope.

That third one is a real interview trap. Requirements are often INCOMPLETE. Do you enforce authorization or note the gap? The strong answer is "I noticed the requirements were silent on multi-user isolation; for MVP I skipped it, would add an owner check on each mutation for production."

Do NOT do these

  • Skip design.md to save time. It's graded. Skipping it means a 0.
  • Copy the shape of a module-4 lesson blindly. This is a NEW problem — Strategy + State signal, not "just Strategy" like Rate Limiter.
  • Panic when the timer's running low. Ship the smallest version that passes tests, then iterate.

After you're done

Whether you finished on time or ran over, review honestly:

  • Which section ate the most time? (Usually implementation.)
  • What would you cut to have finished in time?
  • Did your design.md hold up after you coded, or did you learn something that would change your answer?
  • Would the AI Code Review find issues you missed?

Interview readiness comes from the REVIEW cycle, not the first attempt.

Your task

Timed drill. Target: 45 minutes. Simulates a real LLD interview slot.

You've already done 12 LLD problems in module 4. This one is a NEW problem. Same v3 template — design.md + main.py, both graded — but do it under a self-imposed 45-minute cap. Set a timer.

The problem

Design a music playlist system.

Requirements

  • MusicApp() — main entry point.
  • Users:
    • add_user(user_id)
  • Songs (a shared catalog):
    • add_song(song_id, title, duration_seconds)
  • Playlists (per-user):
    • create_playlist(user_id, playlist_name) — returns playlist_id
    • add_to_playlist(playlist_id, song_id) — appends to end
    • remove_from_playlist(playlist_id, song_id) — removes first occurrence
    • playlist(playlist_id) — returns ordered list of song_ids
    • playlist_duration(playlist_id) — total seconds
  • Playback:
    • play(playlist_id) — starts at index 0 (or current position if paused)
    • pause() — freezes position
    • next_song() — advance to next in current playlist. Loops back to 0 at end.
    • prev_song() — go back. Loops to end from 0.
    • now_playing() — returns {"song_id": ..., "title": ..., "playlist_id": ...} OR None if nothing playing.
  • Shuffle mode:
    • set_shuffle(enabled: bool) — when True, next_song() picks a RANDOM song (not the sequential next). We sidestep randomness by having a shuffle_seed(seed) method — deterministic for tests.

Error cases

  • Unknown user/song/playlist → ValueError
  • Duplicate user/song/playlist_id → ValueError
  • pause/next_song/prev_song/now_playing when nothing playing → return None or (for control ops) raise ValueError

Timer suggestion (spend approx.)

  • 5 min: read requirements, ask (yourself) clarifying questions, jot the answers in design.md's Requirements section
  • 10 min: entities + patterns + trade-offs in design.md
  • 25 min: implement main.py
  • 5 min: polish design.md's invariants section based on what you learned coding

If you go over: keep going. But note it. Real interviews sometimes run over. Real interviews sometimes don't finish.

Design goals

  • Adding a new playback mode (like "repeat one song") should be a manageable change.
  • Shuffle should be swappable — deterministic for tests, random in prod.
  • Invariants: playlists can't hold unknown songs; a user only owns playlists they created; playback position stays valid across next/prev.

Your task

Write design.md + main.py. Grader runs pytest -q on the provided tests (this is a graded problem, not open-ended like lesson 1 — we ship a test suite).

Click Submit to run the tests.

Starter files

Preview only — open the lab to edit and run.

files_dir
02-mock-interview-starter