The interviewer just said…
“OK, let’s see some code. Start with your models.”
In many interviews you stop at diagrams; in this course you implement. The code lives in the hub/scripts/movie-ticket-sourced/ repo under com.interview — build it as you read.
What you should do next
- Create the package layout
- Add Lombok
@Builder/@Datamodels (match entities from previous chapter) - Add in-memory repos with just enough methods to seed and query data
- Add
ShowSeat.reserveTimeand the 5-minute soft-expiry idea (full sweeper optional)
Package layout
com.interview
├── model/ Movie, Theater, Screen, Show, ShowSeat, Ticket
├── enums/ SeatStatus
├── repo/ *Repo (in-memory HashMap stores)
├── service/ MovieService, ShowService, BookingService, TicketService
├── exception/ ReserveException, PaymentException, ...
└── Main.java seed + demo
This mirrors standard Spring-style layering without bringing in Spring — interview-friendly.
Models (Java)
Align with the whiteboard. Example ShowSeat:
@Builder
@Data
public class ShowSeat {
String showId;
String SeatId;
SeatStatus status;
LocalDateTime reserveTime;
}
Other models match hub/scripts/movie-ticket-sourced/src/main/java/com/interview/model/ — copy field names exactly so repos and services compile together.
SeatStatus enum:
public enum SeatStatus {
AVAILABLE, BOOKED, RESERVE
}
In-memory repositories
Interviewers accept HashMap stores. Each repo owns one entity type.
public class ShowSeatRepo {
Map<String, ShowSeat> store = new HashMap<>();
public void add(ShowSeat seat) {
store.put(seat.getShowId() + seat.getSeatId(), seat);
}
public List<ShowSeat> findByShowId(String showId) {
return store.values().stream()
.filter(s -> s.getShowId().equals(showId))
.toList();
}
public List<ShowSeat> getAvailableSeatsByShowId(String showId) { /* filter AVAILABLE */ }
public void bookSeats(String showId, List<String> seatIds) { /* RESERVE→BOOKED */ }
public void releaseSeats(List<String> seatIds, String showId) { /* → AVAILABLE */ }
}
Mirror the pattern for MovieRepo, TheaterRepo, ScreenRepo, ShowRepo, TicketRepo.
Say in interview: “I’m using in-memory repos for clarity; in production these become JPA repositories or SQL with SELECT FOR UPDATE on reserve.”
Seeding ShowSeat rows
When a Show is created, materialize one ShowSeat per seat label:
for (String seatId : show.getSeats()) {
showSeatRepo.add(ShowSeat.builder()
.showId(show.getId())
.SeatId(seatId)
.status(SeatStatus.AVAILABLE)
.build());
}
Main.java in the repo does this manually for demo show sh1 with seats A1–A3.
reserveTime + 5-minute soft expiry (idea)
When reserveSeat runs:
s.setStatus(SeatStatus.RESERVE);
s.setReserveTime(LocalDateTime.now());
Soft expiry rule: If now - reserveTime > 5 minutes, treat seat as releasable (background job or lazy check on read).
boolean isExpired(ShowSeat s) {
return s.getStatus() == SeatStatus.RESERVE
&& s.getReserveTime().plusMinutes(5).isBefore(LocalDateTime.now());
}
For v1 demo you may skip the sweeper — but mention it in the interview so holds don’t leak forever if payment hangs.
Wire services in Main via constructor injection — no Spring required.