Bird
Raised Fist0

Airline Reservation System

LLDmediumInterview freq: medium
Choose your preparation mode4 modes available
▶
Class Trace
Step 1/4
Flight abstract class

Flight is an abstract class holding state like flightNumber and a list of Seat objects. It defines synchronized bookSeat method to atomically check and reserve seats.

🎯 Tests understanding that Flight must be abstract class (not interface) because it holds instance state like seats and flightNumber, which interfaces cannot hold in Java.
public abstract class Flight {
    protected String flightNumber;
    protected List<Seat> seats;
    public synchronized boolean bookSeat(Booking booking) {
        // atomically check seat availability and reserve
        Seat seat = booking.getSeat();
        if (!seat.isAvailable()) return false;
        seat.reserve();
        return true;
    }
    public abstract double calculatePrice();
}
Composition Flight ◆ Seat

Flight composes Seat objects, meaning Flight owns the lifecycle of Seats. Seats cannot exist independently without a Flight.

🎯 Tests whether candidate distinguishes composition (Flight owns Seats lifecycle) from association, enforcing strong lifecycle ownership per SOLID principle of single responsibility.
public class Flight {
    private List<Seat> seats = new ArrayList<>();
    public Flight() {
        // Seats created and owned by Flight
        seats.add(new Seat("1A", SeatClass.ECONOMY));
    }
}
Strategy pattern for Booking

Booking encapsulates passenger and seat info and can use different pricing or cancellation strategies (not shown here) to follow OCP.

🎯 Tests if candidate understands Strategy pattern allows Booking behavior to be extended without modifying Booking class, adhering to Open-Closed Principle.
public class Booking {
    private Passenger passenger;
    private Seat seat;
    private BookingStatus status;
    public void confirm() {
        // confirm booking logic
    }
    public void cancel() {
        // cancel booking logic
    }
}
Observer pattern in Waitlist

Waitlist maintains a synchronized queue of passengers waiting for seats and notifies them when seats become available.

🎯 Tests understanding of concurrency control using synchronized methods to avoid race conditions when adding passengers and notifying them, implementing Observer pattern.
public class Waitlist {
    private Queue<Passenger> passengers = new LinkedList<>();
    public synchronized void addPassenger(Passenger p) {
        passengers.add(p);
    }
    public void notifyAvailable() {
        // notify passengers about seat availability
    }
}
📐
Class Diagram
Class Diagram
       +----------------------+
       |      <<Abstract>>    |
       |        Flight        |
       +----------------------+
       | - flightNumber: String|
       | - seats: List<Seat>   |
       +----------------------+
       | + getAvailableSeats():|
       |   List<Seat>          |
       | + bookSeat(Booking):  |
       |   boolean [sync]      |
       +----------------------+
               │ extends
               │
       +----------------------+
       |      DomesticFlight   |
       +----------------------+
       | + calculatePrice():   |
       |   double              |
       +----------------------+
               │
               │ composition ◆
               │
       +----------------------+
       |         Seat          |
       +----------------------+
       | - seatNumber: String  |
       | - seatClass: SeatClass|
       | - isAvailable: boolean|
       +----------------------+
       | + reserve(): boolean  |
       | + release(): void     |
       +----------------------+
               │
               │ association ──►
               │
       +----------------------+
       |       Booking         |
       +----------------------+
       | - passenger: Passenger|
       | - seat: Seat          |
       | - status: BookingStatus|
       +----------------------+
       | + confirm(): void     |
       | + cancel(): void      |
       +----------------------+
               │
               │ association ──►
               │
       +----------------------+
       |      Waitlist         |
       +----------------------+
       | - passengers: Queue   |
       +----------------------+
       | + addPassenger(Pass): |
       |   void [sync]         |
       | + notifyAvailable():  |
       |   void                |
       +----------------------+

This class diagram illustrates key Java-specific design decisions in an Airline Reservation System. Flight is an abstract class because it holds mutable state like flightNumber and a list of Seat objects, which interfaces cannot hold in Java. Flight composes Seat objects, enforcing strong lifecycle ownership, so Seats cannot exist independently, adhering to SOLID's single responsibility principle. Booking uses the Strategy pattern to allow extensible pricing and cancellation behaviors without modifying existing code, following the Open-Closed Principle. Waitlist implements the Observer pattern with synchronized methods to safely manage concurrent passenger additions and notifications, preventing race conditions. These decisions demonstrate precise use of Java concurrency and OOP mechanisms for extensibility and correctness.

Primary Focus

✓ Abstract class vs Interface + Composition lifecycle + Strategy pattern OCP + Observer concurrency

Practice

(1/5)
1. In designing the Wallet System, should the Account class be an abstract class or an interface, considering it holds state like balance and transaction history? Why?
easy
A. Interface, because it enforces method signatures without implementation, suitable for stateful classes.
B. Abstract class, because it prevents multiple inheritance issues common with interfaces.
C. Interface, because Java interfaces can now hold state with default methods.
D. Abstract class, because it allows sharing state and common behavior like balance management across subclasses.

Solution

  1. Step 1: Analyze state and behavior requirements

    The Account class holds mutable state (balance, transaction history) and common behavior (debit, credit), which requires shared implementation and fields.
  2. Step 2: Abstract class vs interface for stateful behavior

    Interfaces cannot hold instance state (fields), only constants and default methods without backing fields. Abstract classes allow fields and method implementations, making them suitable for shared state and behavior.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Stateful class with shared behavior -> Abstract class [check]
Hint: State + behavior shared -> abstract class, not interface [check]
Common Mistakes:
2. In a vending machine modeled with the State pattern, each state class implements the same interface and handles input differently. Which OOP concept does this best illustrate?
easy
A. Inheritance to share common state variables across states
B. Encapsulation to hide the internal state machine logic from clients
C. Abstraction to define a generic state without implementation
D. Polymorphism to delegate behavior to state-specific classes

Solution

  1. Step 1: Identify the role of state classes

    Each state class implements the same interface but provides different behavior for the same method calls, which is polymorphism.
  2. Step 2: Eliminate other options

    Inheritance alone does not explain different behaviors; encapsulation hides data but does not delegate behavior; abstraction defines interface but does not implement behavior.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    State classes override interface methods -> polymorphism [check]
Hint: State pattern uses polymorphism to vary behavior by state [check]
Common Mistakes:
3. The current Order Management System uses a FeeStrategy interface for pricing. To add a WeekendFeeStrategy that applies extra fees on weekends, which minimal change respects SOLID principles?
medium
A. Create a WeekendFeeDecorator that wraps existing FeeStrategy implementations and adds weekend fees.
B. Add WeekendFeeStrategy as a new class implementing FeeStrategy and configure Order to use it without modifying existing classes.
C. Modify the existing FeeStrategy implementation to check for weekends and apply extra fees.
D. Add a boolean weekend flag to Order and modify FeeStrategy implementations to check it.

Solution

  1. Step 1: Identify SOLID principle involved

    Open-Closed Principle (OCP) requires adding new behavior without modifying existing code.
  2. Step 2: Evaluate options

    Add a boolean weekend flag to Order and modify FeeStrategy implementations to check it. modifies existing classes violating OCP; Modify the existing FeeStrategy implementation to check for weekends and apply extra fees. also modifies existing code; Add WeekendFeeStrategy as a new class implementing FeeStrategy and configure Order to use it without modifying existing classes. adds new class but requires Order modification; Create a WeekendFeeDecorator that wraps existing FeeStrategy implementations and adds weekend fees. adds decorator without modifying existing classes, respecting OCP and DIP.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Decorator adds behavior without modifying existing classes [check]
Hint: Decorator adds features without changing existing code [check]
Common Mistakes:
4. In a Singleton class without synchronized on getInstance(), what EXACT sequence of Thread 1 and Thread 2 calls can cause two instances to be created?
medium
A. Thread 1 checks instance == null -> true, context switch before creation; Thread 2 checks instance == null -> true, both create separate instances.
B. Thread 1 calls getInstance(), completes instance creation; Thread 2 calls getInstance() and returns same instance.
C. Thread 1 calls getInstance() twice in a row; Thread 2 waits until Thread 1 finishes.
D. Thread 1 and Thread 2 both call getInstance() after instance is created, returning the same instance.

Solution

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

    Without synchronization, both threads can see instance == null before either creates it.
  2. Step 2: Trace thread interleaving

    Thread 1 checks instance == null -> true, context switch before creating instance. Thread 2 also checks instance == null -> true, proceeds to create a second instance, causing double instantiation.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Unsynchronized lazy init -> check-then-act race causes two instances [check]
Hint: Check-then-act without sync -> double instance creation [check]
Common Mistakes:
5. ElectricCar requires ChargingSpots in the parking lot system. What is the minimum change to support this without modifying existing classes?
hard
A. Add a boolean isElectric flag to Vehicle and Spot classes and handle compatibility internally.
B. Modify Vehicle and Spot classes to add electric-specific fields and logic directly.
C. Create a new ElectricParkingLot subclass handling electric vehicles and spots separately.
D. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map externally.

Solution

  1. Step 1: Identify extensibility without modifying existing classes

    To comply with OCP and avoid class explosion, new types should be added via enums and new subclasses without changing existing code.
  2. Step 2: Explain why Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map externally. fits minimal change

    Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map externally. adds new enum values and creates a new ElectricCar subclass, updating compatibility externally, preserving existing classes unchanged. Options B, C, and D modify existing classes or create subclasses that duplicate logic, violating OCP or SRP.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    New enums + subclass + external compatibility update -> minimal change [check]
Hint: Add enums + subclass + external map update -> no existing class changes [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