Bird
Raised Fist0

Online Auction System

LLDmediumInterview freq: medium
Choose your preparation mode4 modes available
▶
Class Trace
Step 1/4
Auction and AuctionTimer composition

Auction has a composition relationship with AuctionTimer, indicating Auction owns the timer lifecycle.

🎯 Tests if candidate understands composition in Java means Auction creates and controls AuctionTimer lifecycle, enforcing strong ownership.
public class Auction {
    private final AuctionTimer timer = new AuctionTimer(); // composition
    public synchronized boolean placeBid(Bid bid) {
        if (timer.isExpired()) return false;
        // bid logic
        return true;
    }
}
NotificationService Singleton with volatile instance

NotificationService is a Singleton with a volatile instance field to prevent half-constructed object visibility.

🎯 Tests if candidate knows volatile is needed on Singleton instance to prevent JVM reordering and ensure safe publication.
public class NotificationService {
    private static volatile NotificationService instance;
    private NotificationService() {}
    public static NotificationService getInstance() {
        if (instance == null) {
            synchronized(NotificationService.class) {
                if (instance == null) instance = new NotificationService();
            }
        }
        return instance;
    }
    public void notify(Notification n) {
        n.send();
    }
}
Observer pattern realization via NotificationService and Notification

NotificationService associates with Notification to send messages, realizing the Observer pattern for auction events.

🎯 Tests if candidate understands association means Notification can exist independently and NotificationService uses it to decouple notification logic.
public class Notification {
    private final String message;
    public Notification(String msg) { this.message = msg; }
    public void send() {
        System.out.println("Notify: " + message);
    }
}
Synchronized placeBid method in Auction

placeBid is synchronized to atomically check timer expiry and update current winner safely in concurrent environment.

🎯 Tests if candidate knows synchronized keyword ensures atomicity and visibility of shared mutable state in Java multithreading.
public class Auction {
    private Bid currentWinner;
    private final AuctionTimer timer = new AuctionTimer();
    public synchronized boolean placeBid(Bid bid) {
        if (timer.isExpired()) return false;
        if (bid.getAmount() > currentWinner.getAmount()) {
            currentWinner = bid;
            NotificationService.getInstance().notify(
                new Notification("New highest bid: " + bid.getAmount()));
            return true;
        }
        return false;
    }
}
📐
Class Diagram
Class Diagram
       +----------------+
       |    Auction     |
       +----------------+
       | -reservePrice  |
       | -currentWinner |
       +----------------+
       | +placeBid(Bid) [sync] |
       | +getWinner()          |
       +----------------+
              ◆
              │ composition
              │ lifecycle: Auction owns AuctionTimer
       +----------------+
       | AuctionTimer   |
       +----------------+
       | -endTime       |
       +----------------+
       | +startTimer()  |
       | +isExpired()   |
       +----------------+
              ─ ─ ─►
              | realization
       +----------------------+
       | NotificationService  |
       | <<Singleton>>        |
       +----------------------+
       | -instance volatile   |
       +----------------------+
       | +getInstance()       |
       | +notify(Notification)|
       +----------------------+
              ──►
              | association
       +----------------+
       | Notification   |
       +----------------+
       | -message       |
       +----------------+
       | +send()        |
       +----------------+

This diagram illustrates key Java design decisions in an Online Auction System. Auction composes AuctionTimer, enforcing lifecycle ownership and encapsulating timing logic. NotificationService is implemented as a thread-safe Singleton using a volatile instance field and double-checked locking to ensure safe publication. The Observer pattern is realized by NotificationService associating with Notification objects, decoupling notification sending from auction logic. The placeBid method in Auction is synchronized to atomically check timer expiry and update the current winner, ensuring thread safety and visibility of shared mutable state. These decisions demonstrate mastery of Java concurrency, composition, and design patterns.

Primary Focus

✓ Observer pattern realization + Composition lifecycle + synchronized methods + Singleton volatile

Practice

(1/5)
1. In designing the Row abstraction for the in-memory SQL database, should Row be an abstract class or an interface, and why?
easy
A. Row should be an interface because it only defines behavior without state, allowing multiple implementations.
B. Row should be an abstract class because it holds common state like column values and provides default behavior.
C. Row should be an interface to allow multiple inheritance of behavior from other components.
D. Row should be an abstract class to enforce immutability of row data.

Solution

  1. Step 1: Analyze state and behavior requirements of Row

    A Row holds column values (state) and provides methods to access or modify them (behavior). Interfaces cannot hold state in Java.
  2. Step 2: Choose between abstract class and interface

    Abstract class can hold common state and provide default implementations, fitting Row's needs. Interface would force all implementations to duplicate state management.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Row holds state -> abstract class needed [check]
Hint: Stateful abstraction -> abstract class, stateless -> interface [check]
Common Mistakes:
2. In a multi-threaded parking lot system using Abstract Factory to create vehicles and spots, if parkVehicle() is not synchronized, which exact thread interleaving causes double-booking of the same spot?
medium
A. Thread 1 parks vehicle, Thread 2 parks vehicle after Thread 1 finishes.
B. Thread 1 checks spot availability -> true, context switch; Thread 2 checks spot availability -> true; both park simultaneously.
C. Thread 1 parks vehicle, Thread 2 waits for Thread 1 to release lock before parking.
D. Thread 1 and Thread 2 both fail to find any available spots and abort.

Solution

  1. Step 1: Identify race condition in parkVehicle()

    Without synchronization, two threads can both check spot availability before either marks it occupied.
  2. Step 2: Trace exact interleaving

    Thread 1 calls isAvailable() -> true, context switch before marking occupied; Thread 2 calls isAvailable() -> true; both proceed to park, causing double-booking.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Check-then-act gap without synchronization causes double-booking [check]
Hint: Check-then-act gap -> both see available, both park [check]
Common Mistakes:
3. In a multi-threaded Chess game server, without synchronizing the makeMove() method, which exact sequence of thread interleaving causes two players to move simultaneously, violating turn order?
medium
A. Thread 1 reads current player as White, moves piece; Thread 2 reads current player as Black, moves piece simultaneously.
B. Thread 1 checks if it's White's turn -> true, context switch; Thread 2 checks if it's White's turn -> true; both proceed to move.
C. Thread 1 locks board, moves piece; Thread 2 waits but proceeds after unlock.
D. Thread 1 updates board state; Thread 2 reads stale board state but waits for turn.

Solution

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

    Both threads read the turn state before either updates it, causing both to believe it's their turn.
  2. Step 2: Trace thread interleaving

    Thread 1 checks turn -> true, context switch before move; Thread 2 checks turn -> true, both move simultaneously, violating turn order.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Check-then-act gap allows double move without synchronization [check]
Hint: Check turn then act without lock -> race condition [check]
Common Mistakes:
4. You want to add a WeekendRetryPolicy to the Job Scheduler without modifying existing classes. Which SOLID principle guides the minimum change, and what is the correct approach?
medium
A. Open/Closed Principle: create a new class WeekendRetryPolicy implementing RetryPolicy interface without changing existing code.
B. Single Responsibility Principle: modify RetryPolicy to handle weekends explicitly.
C. Dependency Inversion Principle: inject WeekendRetryPolicy into Job class by modifying Job constructor.
D. Liskov Substitution Principle: override existing RetryPolicy methods to add weekend logic.

Solution

  1. Step 1: Identify the SOLID principle for extensibility

    Open/Closed Principle (OCP) states software entities should be open for extension but closed for modification.
  2. Step 2: Apply OCP to add WeekendRetryPolicy

    Create a new class implementing RetryPolicy interface to add weekend-specific logic without modifying existing RetryPolicy or Job classes.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    New class implements interface -> no existing code changed [check]
Hint: OCP: extend by new class, don't modify existing [check]
Common Mistakes:
5. ElectricCar needs ChargingSpots in the Stack Overflow vehicle analogy. What is the minimum change to support this without modifying existing classes?
hard
A. Add charging logic directly inside existing Spot class with if-else for electric cars
B. Modify Vehicle class to add isElectric flag and add charging logic inside existing methods
C. Create a new ElectricCar class unrelated to Vehicle and a ChargingSpot class unrelated to Spot, manage compatibility externally
D. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar extends Vehicle, update SpotCompatibility.COMPATIBILITY_MAP accordingly

Solution

  1. Step 1: Identify extensibility without modifying existing classes

    Adding new enum values and subclass ElectricCar extends Vehicle allows extension without changing existing class code.
  2. Step 2: Update compatibility map externally

    Updating SpotCompatibility.COMPATIBILITY_MAP supports new types without modifying core logic, preserving OCP.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Enum extension + subclass + external map update -> minimal change [check]
Hint: Extend enums + subclass + external map -> 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