Bird
Raised Fist0

Design a Music Streaming Library - Tracks, Albums, Playlists, Playback Queue

LLDmediumInterview freq: medium
Choose your preparation mode4 modes available
ā–¶
Class Trace
Step 1/4
Track abstract class

Track is an abstract class holding shared state like id, title, and duration, and behavior like play and pause.

šŸŽÆ Tests whether candidate understands abstract class is used because Track holds instance state and behavior that interfaces cannot hold in Java.
public abstract class Track {
    protected String id;
    protected String title;
    protected int duration;
    public abstract void play();
    public abstract void pause();
}
Album composition relationship

Album composes multiple Track objects with a List<Track> field, showing strong lifecycle ownership.

šŸŽÆ Tests whether candidate knows composition means Album controls Track lifecycle and uses synchronized methods to safely modify tracks list.
public class Album extends Track {
    private final List<Track> tracks = new ArrayList<>();
    public synchronized void addTrack(Track t) {
        tracks.add(t);
    }
    public synchronized void removeTrack(Track t) {
        tracks.remove(t);
    }
    @Override public void play() { /* play album tracks */ }
    @Override public void pause() { /* pause album tracks */ }
}
Playlist composition vs association

Playlist also composes Tracks but can contain tracks from multiple albums, showing flexible composition with synchronized add/remove methods.

šŸŽÆ Tests candidate's understanding that Playlist composition means it owns track references but tracks can exist independently, enforcing Single Responsibility Principle.
public class Playlist {
    private final List<Track> items = new ArrayList<>();
    public synchronized void addTrack(Track t) {
        items.add(t);
    }
    public synchronized void removeTrack(Track t) {
        items.remove(t);
    }
}
PlaybackQueue association relationship

PlaybackQueue holds a queue of Tracks but does not own their lifecycle, showing association with weak lifecycle coupling.

šŸŽÆ Tests candidate's knowledge that PlaybackQueue uses association because Tracks exist independently and concurrency is handled by synchronized enqueue/dequeue methods.
public class PlaybackQueue {
    private final Queue<Track> queue = new LinkedList<>();
    public synchronized void enqueue(Track t) {
        queue.offer(t);
    }
    public synchronized Track dequeue() {
        return queue.poll();
    }
}
šŸ“
Class Diagram
Class Diagram
       +----------------+
       |    <<Abstract>>|
       |      Track     |
       +----------------+
       | -id: String    |
       | -title: String |
       | -duration: int |
       +----------------+
       | +play(): void  |
       | +pause(): void |
       +----------------+
              ā–²
              │
       +----------------+
       |     Album      |
       +----------------+
       | -tracks: List<Track>ā—†|
       +----------------+
       | +addTrack(t:Track):void [sync] |
       | +removeTrack(t:Track):void [sync]|
       +----------------+
              │
              │ composition
              │
       +----------------+
       |   Playlist     |
       +----------------+
       | -items: List<Track>ā—†|
       +----------------+
       | +addTrack(t:Track):void [sync] |
       | +removeTrack(t:Track):void [sync]|
       +----------------+
              │
              │ association
              │
       +----------------+
       | PlaybackQueue  |
       +----------------+
       | -queue: Queue<Track> |
       +----------------+
       | +enqueue(t:Track):void [sync] |
       | +dequeue():Track [sync] |
       +----------------+

This class diagram illustrates key Java OOP design decisions for a Music Streaming Library. Track is an abstract class because it holds shared state and behavior that interfaces cannot hold in Java. Album and Playlist both compose Track objects, enforcing strong lifecycle ownership and thread safety with synchronized methods, demonstrating the Composite pattern. PlaybackQueue associates with Track objects without owning their lifecycle, reflecting a weak association relationship. These design choices enforce SOLID principles such as Single Responsibility and Open-Closed by allowing extension without modification. Synchronization on collection-modifying methods prevents race conditions in concurrent environments. The diagram clarifies composition versus association lifecycles and why abstract classes are preferred over interfaces when instance state is needed.

Primary Focus

āœ“ Composite pattern composition lifecycle + Abstract class state vs interface + Association vs Composition lifecycle

Practice

(1/5)
1. In a vending machine design, a State interface defines methods like selectProduct(), insertMoney(), and dispense(). Concrete classes like IdleState, HasMoneyState, and SoldState implement this interface. Which design pattern is applied here and why is it the correct choice?
easy
A. Observer pattern, because states notify the vending machine when transitions occur.
B. Strategy pattern, because it allows changing algorithms at runtime for product selection.
C. Decorator pattern, because it adds responsibilities to states dynamically without altering their interface.
D. State pattern, because it encapsulates state-specific behavior and transitions within state classes.

Solution

  1. Step 1: Identify the role of State interface and concrete states

    The State interface defines behavior that varies depending on the vending machine's current state. Concrete classes implement these behaviors and handle transitions.
  2. Step 2: Match pattern intent to scenario

    The State pattern encapsulates state-specific behavior and transitions, allowing the vending machine to change behavior dynamically without complex conditionals.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    State pattern encapsulates state behavior and transitions [check]
Hint: State pattern encapsulates behavior per state [check]
Common Mistakes:
2. To add a new WeekendFeeStrategy pricing rule in the Workflow Engine's fee calculation, which minimal change respects SOLID principles?
medium
A. Modify the existing FeeCalculator class to add weekend logic inside its calculate() method.
B. Create a new WeekendFeeStrategy class implementing FeeStrategy interface and inject it without changing FeeCalculator.
C. Add a boolean flag isWeekend to FeeCalculator and branch logic accordingly.
D. Combine all fee strategies into one large class with if-else for each pricing rule.

Solution

  1. Step 1: Identify SOLID principle involved

    Open-Closed Principle (OCP) requires classes to be open for extension but closed for modification.
  2. Step 2: Apply OCP to fee strategy

    Adding a new WeekendFeeStrategy class extends behavior without modifying existing FeeCalculator, respecting OCP and Dependency Inversion Principle.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    New strategy class + no FeeCalculator change -> OCP respected [check]
Hint: OCP: extend with new class, don't modify existing [check]
Common Mistakes:
3. Adding a WeekendFeeStrategy to the current parking fee system requires which minimum change to comply with SOLID principles?
medium
A. Add a boolean flag isWeekend in ParkingLot and conditionally apply fees inside existing strategies.
B. Create a new WeekendFeeStrategy class implementing FeeStrategy without modifying existing classes.
C. Modify the existing FeeStrategy interface to add a isWeekend() method and update all implementations.
D. Combine all fee strategies into one class with conditional logic for weekends.

Solution

  1. Step 1: Identify applicable SOLID principle

    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 without modifying existing classes. respects OCP by adding a new class without modifying existing ones. Add a boolean flag isWeekend in ParkingLot and conditionally apply fees inside existing strategies. violates OCP by modifying ParkingLot and existing strategies with conditional logic.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    New strategy class added, existing code unchanged -> OCP respected [check]
Hint: Add new strategy class, don't modify existing ones [check]
Common Mistakes:
4. LinkedIn wants to add ElectricCar profiles and ChargingSpot types without modifying existing classes. What is the minimum change to the current Java design to support this extensibility?
hard
A. Modify Vehicle and Spot base classes to add electric-specific fields and methods directly.
B. Create a new ElectricVehicle interface and modify existing classes to implement it.
C. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map without changing existing classes.
D. Add a boolean isElectric flag to Vehicle and Spot classes and handle logic conditionally.

Solution

  1. Step 1: Identify extensibility without modifying existing classes

    Adding new enum values and subclasses allows extension without changing existing class code, preserving OCP.
  2. Step 2: Update compatibility map externally

    Updating SpotCompatibility.COMPATIBILITY_MAP to include new types supports new logic without modifying existing classes.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    New enums + subclass + external map update -> no existing class changes [check]
Hint: Add enums + subclass + external map update, no class edits [check]
Common Mistakes:
5. ElectricCar needs to use ChargingSpots in the parking lot system. What is the minimum change to the current design to support this without modifying existing classes?
hard
A. Add a flag in ParkingLot to treat ElectricCars differently and hardcode charging spot logic.
B. Modify Vehicle class to add a boolean isElectric field and add logic in ParkingSpot to check it.
C. Create a new ElectricCar class and a new ChargingSpot class, then modify ParkingLot to handle both explicitly.
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

    Adding new enum values and subclasses allows extension without changing existing class code, preserving OCP.
  2. Step 2: Update compatibility externally

    Updating SpotCompatibility map outside existing classes avoids modifying their code and prevents class explosion or god-class logic.
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Extend enums + subclass + external compatibility update -> minimal change [check]
Hint: Extend enums and subclasses, update compatibility externally [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