How to Approach

The interviewer just said…

“OK, that scope works. How would you approach the design?”

They’ve agreed on v1. Now they want to see structure — not a flood of classes.


What you should do next

Apply the LLD delivery framework in order. Say the steps aloud, then execute them on the whiteboard:

  1. Requirements — done (search, shows, seats, book, cancel)
  2. Entities & relationships — Movie, Theater, Screen, Show, ShowSeat, Ticket
  3. Service APIs — method signatures a client would call
  4. Core flow — happy path: reserve → pay → book → ticket
  5. Extensions — failure compensation; concurrency if time remains

This mirrors LLD delivery in a hurry: narrow problem → model → API → flow → hard parts last.


Timeboxing for a 45-minute round

Phase Minutes Deliverable
Clarify + read-back 5 Agreed v1 scope
Entities + seat state machine 10 Boxes, ShowSeat lifecycle
Service APIs 8 5 interfaces, key methods
Happy path walkthrough 10 reserve → pay → book → ticket on board
Failure / cancel 7 Catch blocks, release/refund
Concurrency (if asked) 5+ “Critical section is reserve”; one strategy

If you’re running long, cut Movie metadata fluff, not the booking saga. Interviewers remember whether you understood RESERVE before payment.


The approach in one paragraph (memorize this shape)

“I’ll model theaters in cities with screens and scheduled shows. Each show has its own seat inventory via ShowSeat rows with status AVAILABLE, RESERVE, or BOOKED. MovieService handles city search; ShowService handles availability and seat transitions; BookingService orchestrates reserve, payment stub, book, and ticket creation; TicketService persists tickets. Cancel reverses book. If two users race for the same seat, the reserve step must be atomic — we can discuss synchronized blocks or DB row locks after the happy path.”

That paragraph is your roadmap. Everything below fills in details.


Core flow (sketch before coding)

User picks show + seats


  reserveSeat()     ──► AVAILABLE → RESERVE


  payment (stub)    ──► may throw PaymentException


  bookSeat()        ──► RESERVE → BOOKED


  bookTicket()      ──► return ticketId

Cancel (separate path):

cancelTicket(ticketId) → load Ticket → releaseSeat → refund stub

Where concurrency fits (don’t lead with it)

The critical section is between reading a seat as AVAILABLE and writing RESERVE. Two threads in that gap → double booking.

For v1 implementation in hub/scripts/movie-ticket-sourced/, ShowService.reserveSeat starts with synchronized — enough for a single JVM demo. In the interview, mention show-level or row-level locks and distributed options after the domain is clear. Leading with Redis before ShowSeat exists is a red flag.


Mapping phases to this course

Delivery step Course chapter Code location
Entities Design entities com.interview.model.*
APIs Design service APIs com.interview.service.*
Implement models/repos Implement models com.interview.repo.*
Happy path Booking happy path BookingService, Main.java
Failures Failure handling try/catch in BookingService
Concurrency The race (next module) ShowService* variants