Bird
Raised Fist0

Airline Reservation System

LLDmediumInterview freq: medium
Choose your preparation mode4 modes available
🏗️
Airline Reservation System
Design an Airline Reservation System with Seats, Classes, Waitlist, and Cancellation
mediumBooking and Reservation SystemsFreq: medium
Prerequisites:OOP FundamentalsJava Concurrency BasicsDesign Patterns (Factory, Observer, Strategy)
⚙️
Functional Requirements
  • Support multiple seat classes with different pricing and availability
  • Allow passengers to book, cancel, and view seat status
  • Maintain a waitlist queue per class for overbooked flights
  • Automatically allocate seats to waitlisted passengers upon cancellation
  • Prevent double booking of the same seat under concurrent requests
  • Provide seat availability status in real-time
  • Support cancellation and refund processing
👤
Use Cases
  • Passenger books a seat in a specific class (Economy, Business, First)
  • Passenger cancels a booked seat
  • System manages waitlist for fully booked classes
  • Booking Agent queries seat availability
  • System upgrades waitlisted passengers when seats become available
  • System handles concurrent booking requests
🧑‍💻
Actors
  • Passenger
  • Booking Agent
  • System Administrator
  • Flight
❓
Clarifying Questions to Ask
  • How many concurrent booking threads or agents are expected per flight?
  • Is pricing fixed per class or dynamic based on demand?
  • What happens if a passenger cancels a waitlist spot?
  • Are seat upgrades (e.g., Economy to Business) supported?
  • How to handle partial cancellations (group bookings)?
  • Is overbooking allowed beyond seat capacity?
Out of Scope
✗ Payment processing and refund transactions
✗ Flight scheduling and routing
✗ User authentication and authorization
✗ Dynamic pricing algorithms
🔢
Enumerations
enum SeatClass
ECONOMY | BUSINESS | FIRST
Defines fixed seat classes to prevent typo bugs and enable exhaustive switch-case handling in seat allocation logic.
enum SeatStatus
AVAILABLE | BOOKED | WAITLISTED | CANCELLED
Represents seat lifecycle states explicitly, enabling clear state transitions and concurrency-safe status checks.
enum BookingStatus
CONFIRMED | WAITLISTED | CANCELLED
Distinguishes booking outcomes to manage passenger notifications and waitlist promotions.
📦
Flight
3 fields
private final String flightNumberprivate final Map<SeatClass, List<Seat>> seatsByClassprivate final Map<SeatClass, Waitlist> waitlistsByClass
Manages seats and waitlists per class for a flight; coordinates booking and cancellation requests.
public synchronized Booking bookSeat(String passengerId, SeatClass seatClass)Attempts to book an available seat in the specified class or adds passenger to waitlist if full.
public synchronized boolean cancelBooking(String passengerId, String seatId)Cancels a confirmed booking and promotes waitlisted passengers if any.
public synchronized List<Seat> getAvailableSeats(SeatClass seatClass)Returns a list of currently available seats for the given class.
📦
Seat
4 fields
private final String seatIdprivate final SeatClass seatClassprivate volatile SeatStatus statusprivate volatile String bookedByPassengerId
Represents a seat with class and booking status; manages atomic state changes to prevent double booking.
public synchronized boolean book(String passengerId)Atomically books the seat if available; returns false if already booked.
public synchronized boolean cancel(String passengerId)Cancels booking if passengerId matches; returns false if seat not booked by passenger.
public boolean isAvailable()Checks if seat status is AVAILABLE; volatile ensures visibility across threads.
📦
Booking
4 fields
private final String bookingIdprivate final String passengerIdprivate final Seat seatprivate volatile BookingStatus status
Encapsulates booking details and status; status changes are volatile for thread visibility.
public synchronized void confirm()Sets booking status to CONFIRMED.
public synchronized void cancel()Sets booking status to CANCELLED.
📦
Waitlist
1 fields
private final Queue<String> passengerQueue
Manages FIFO queue of passengers waiting for seats; thread-safe enqueue and dequeue operations.
public synchronized void addPassenger(String passengerId)Adds passenger to waitlist queue.
public synchronized String popNextPassenger()Removes and returns the next passenger in waitlist or null if empty.
public synchronized boolean isEmpty()Checks if waitlist queue is empty.
📦
Passenger
2 fields
private final String passengerIdprivate final String name
Represents a passenger entity with identity; used for booking and waitlist references.
public String getPassengerId()Returns passenger unique identifier.
🔗
Relationships
Flight◆──►Seat[1..*]
compositionFlight owns Seats; Seats destroyed with Flight
Flight◆──►Waitlist[1 per SeatClass]
compositionFlight owns Waitlists; Waitlists destroyed with Flight
Booking──►Seat[1]
associationBooking references Seat; Seat exists independently
Booking──►Passenger[1]
associationBooking references Passenger; Passenger exists independently
Waitlist◇──►Passenger[0..*]
aggregationWaitlist holds references to Passengers; Passengers exist independently

Practice

(1/5)
1. In designing the Vehicle abstraction for the Car Rental System, should Vehicle be an abstract class or an interface, and why?
easy
A. Interface, because Vehicle only defines behavior without any shared state or implementation.
B. Interface, because Java interfaces can now have default methods to share implementation and state.
C. Abstract class, because Vehicle has common state like licensePlate and shared methods like calculateRentalPrice().
D. Abstract class, because interfaces cannot enforce method signatures for subclasses.

Solution

  1. Step 1: Identify Vehicle's shared state and behavior

    Vehicle has common fields like licensePlate and methods with shared logic such as calculateRentalPrice(), which require state and partial implementation.
  2. Step 2: Determine appropriate abstraction

    Abstract classes allow shared state and method implementations, while interfaces cannot hold instance state. Thus, Vehicle should be an abstract class.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Shared state + common methods -> abstract class [check]
Hint: Shared state? Use abstract class, not interface [check]
Common Mistakes:
2. In the Hotel Management System, if the parkVehicle() method is not synchronized, which exact sequence of events between Thread 1 and Thread 2 causes double-booking of the same parking spot?
medium
A. Thread 1 checks spot availability -> true, context switch before marking occupied; Thread 2 checks availability -> true, both park simultaneously.
B. Thread 1 marks spot occupied, Thread 2 reads spot as occupied and waits indefinitely.
C. Thread 1 parks vehicle, Thread 2 waits until Thread 1 finishes, then parks another vehicle.
D. Thread 1 and Thread 2 both crash due to simultaneous access causing deadlock.

Solution

  1. Step 1: Identify the check-then-act race condition

    Without synchronization, Thread 1 reads spot as available and is preempted before marking it occupied.
  2. Step 2: Thread 2 also reads spot as available and proceeds to park, causing double-booking.

    This is the classic check-then-act gap causing race condition.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Check availability -> true by both threads before marking occupied -> double-booking [check]
Hint: Check-then-act gap -> double-booking without synchronization [check]
Common Mistakes:
3. In a concurrent Job Scheduler, if the scheduleJob() method is not synchronized, which exact thread interleaving causes the same Job to be scheduled twice?
medium
A. Thread 1 and Thread 2 both call scheduleJob() simultaneously and both succeed without checks.
B. Thread 1 adds job, then Thread 2 removes it before completion, causing inconsistency.
C. Thread 1 checks if job exists -> false, context switch; Thread 2 checks -> false; both add job concurrently.
D. Thread 1 waits for Thread 2 to finish scheduling, causing deadlock.

Solution

  1. Step 1: Identify the check-then-act race condition

    Both threads check if the job is already scheduled before adding. Without synchronization, both see job absent.
  2. Step 2: Trace thread interleaving

    Thread 1 checks -> false, context switch before adding; Thread 2 checks -> false, adds job; Thread 1 resumes and adds job again, causing double scheduling.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Check-then-act gap without synchronization -> double scheduling [check]
Hint: Check-then-act gap -> double scheduling race [check]
Common Mistakes:
4. Adding a WeekendFeeStrategy to the parking lot pricing requires which minimum change to comply with SOLID principles?
medium
A. Modify the existing FeeCalculator class to add weekend logic with an if-else block.
B. Add a boolean isWeekend flag to Vehicle and change pricing logic accordingly.
C. Create a new WeekendFeeStrategy class implementing FeeStrategy and inject it without modifying existing classes.
D. Combine all fee strategies into one large class with multiple methods for each pricing rule.

Solution

  1. Step 1: Identify the SOLID principle involved

    The Open-Closed Principle (OCP) requires that classes be open for extension but closed for modification.
  2. Step 2: Evaluate options against OCP

    Create a new WeekendFeeStrategy class implementing FeeStrategy and inject it without modifying existing classes. respects OCP by adding a new strategy class without modifying existing code. Add a boolean isWeekend flag to Vehicle and change pricing logic accordingly. violates OCP by modifying Vehicle state, which is unrelated to pricing and causes tight coupling.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    New strategy class -> OCP-compliant extension [check]
Hint: OCP: add new class, don't modify existing ones [check]
Common Mistakes:
5. To support ElectricCar bidders requiring ChargingSpot reservations in the auction system, what is the minimum change to the current Java design to maintain extensibility without modifying existing classes?
hard
A. Modify Vehicle base class to include charging logic and add ChargingSpot as a subclass of Spot.
B. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map externally.
C. Create a new ElectricCarChargingManager class that extends AuctionManager and handles charging spots internally.
D. Add charging logic directly inside existing Bid and Spot classes to handle electric cars.

Solution

  1. Step 1: Identify extensibility without modification

    Adding new enum values and subclasses extends functionality without changing existing class code.
  2. Step 2: Update SpotCompatibility map externally to maintain compatibility rules without modifying existing classes.

  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Extend enums + subclass + external map update -> minimal change [check]
Hint: Extend enums + subclass + external map update -> minimal change [check]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard