Bird
Raised Fist0

Why LLD Exists and What HLD Cannot Tell You

LLDmediumInterview freq: high
Choose your preparation mode4 modes available
🏗️
Why LLD Exists and What HLD Cannot Tell You
Understanding the necessity of Low-Level Design to capture detailed OOP decisions beyond High-Level Design abstractions
mediumOOP Foundations for InterviewsFreq: high
Prerequisites:OOP Fundamentals
⚙️
Functional Requirements
  • Capture instance state management decisions (fields vs no fields)
  • Show concurrency control using Java mechanisms (synchronized, volatile, Atomic classes)
  • Demonstrate SOLID principles in extensibility
  • Explain lifecycle ownership in relationships (composition vs aggregation)
  • Provide full Java method signatures with concurrency modifiers
  • Illustrate how abstract classes differ from interfaces in Java
  • Show how to avoid race conditions with exact thread interleaving
👤
Use Cases
  • Explain why LLD is necessary beyond HLD
  • Identify Java-specific OOP decisions in design
  • Demonstrate concurrency control in Java
  • Show how to extend design without modifying existing classes
  • Discuss lifecycle ownership of objects
  • Clarify state vs behavior in design choices
🧑‍💻
Actors
  • Software Engineer (Candidate)
  • Interviewer
  • System Architect
❓
Clarifying Questions to Ask
  • How many concurrent threads or actors will interact with the system?
  • What concurrency control mechanisms are expected or allowed in Java?
  • Are there any pricing or resource allocation strategies to consider?
  • What are the edge cases for object lifecycle and state transitions?
  • Should the design allow extension without modifying existing classes (Open-Closed Principle)?
  • Is there a need for lazy initialization or singleton patterns?
  • How should failures or exceptions be handled in concurrent scenarios?
Out of Scope
✗ High-Level Architecture diagrams
✗ Non-Java language specifics
✗ UI/UX design considerations
✗ Database schema design
⚡
QPS Calculation
expected qps1000
peak qps5000
write qps300
read qps700
🖥️
Server Estimate
app servers5
db servers3
cache servers2
🔢
Enumerations
enum DesignDecisionType
ABSTRACT_CLASS | INTERFACE | CONCURRENCY_CONTROL | LIFECYCLE_OWNERSHIP
Enumerates key design decision categories to avoid string typos and enable exhaustive switch statements in Java.
enum ConcurrencyMechanism
SYNCHRONIZED | VOLATILE | ATOMIC | NONE
Defines Java concurrency mechanisms explicitly to clarify which mechanism is applied in each scenario.
📦
DesignDecision
3 fields
private final DesignDecisionType typeprivate final String descriptionprivate final ConcurrencyMechanism concurrencyMechanism
Represents a single Java-specific OOP design decision with type, description, and concurrency mechanism used.
public DesignDecisionType getType()Returns the type of design decision.
public String getDescription()Returns detailed description of the design decision.
public ConcurrencyMechanism getConcurrencyMechanism()Returns the concurrency mechanism applied.
📦
Entity
4 fields
private final String nameprivate final List<String> attributesprivate final String responsibilitiesprivate final List<MethodSignature> keyMethods
Models a Java class or interface with attributes, responsibilities, and key methods including concurrency modifiers.
public String getName()Returns the entity name.
public List<String> getAttributes()Returns list of attribute declarations.
public String getResponsibilities()Returns the responsibilities description.
public List<MethodSignature> getKeyMethods()Returns list of key methods with full Java signatures.
📦
MethodSignature
3 fields
private final String nameprivate final String signatureprivate final String description
Encapsulates a method's name, full Java signature including concurrency modifiers, and description.
public String getName()Returns method name.
public String getSignature()Returns full Java method signature.
public String getDescription()Returns method description.
📦
LifecycleOwnership
6 fields
private final String fromEntityprivate final String toEntityprivate final String typeprivate final String cardinalityprivate final String lifecycleprivate final String umlNotation
Defines the relationship type and lifecycle ownership between two entities in Java OOP context.
public String getFromEntity()Returns source entity name.
public String getToEntity()Returns target entity name.
public String getType()Returns relationship type (composition, aggregation, etc).
public String getCardinality()Returns cardinality string.
public String getLifecycle()Returns lifecycle ownership description.
public String getUmlNotation()Returns UML notation string.
🔗
Relationships
DesignDecision──►DesignDecisionType[1..1]
associationDesignDecision depends on DesignDecisionType but DesignDecisionType exists independently
Entity◆──►MethodSignature[1..*]
compositionMethodSignatures are created and destroyed with Entity
Entity──►Entity[1..1]
inheritanceSubclass depends on superclass but superclass exists independently
Entity──►Entity[1..1]
realizationImplementing class depends on interface but interface exists independently
Entity◆──►Entity[1..*]
compositionComposite entity owns contained entities; contained entities destroyed with composite
🗄️
DesignDecision
PK: type
type STRINGdescription STRINGconcurrencyMechanism STRING
Stores Java-specific design decisions with concurrency info.
🗄️
Entity
PK: name
name STRINGattributes LIST<STRING>responsibilities STRING
Models Java classes/interfaces with attributes and responsibilities.
🔌
GetDesignDecision
Request
{
  "type": "DesignDecisionType"
}
Response
{
  "designDecision": "DesignDecision"
}
Fetches design decision details by type.
🔌
ListEntities
Request
{
  "filter": "optional string"
}
Response
{
  "entities": "List<Entity>"
}
Lists entities optionally filtered by name or responsibility.
🔌
CreateMethodSignature
Request
{
  "entityName": "string",
  "methodSignature": "MethodSignature"
}
Response
{
  "success": "boolean"
}
Adds a method signature to an entity.

Practice

(1/5)
1. In the Online Tic-Tac-Toe game design, the Board class uses a private constructor and a static synchronized getInstance() method to provide access. Which design pattern is applied here and why is this the correct choice?
easy
A. Singleton pattern, to ensure only one game board instance exists per game session.
B. Factory pattern, because it controls object creation centrally.
C. Builder pattern, to incrementally construct the board state.
D. Prototype pattern, to clone board states for undo functionality.

Solution

  1. Step 1: Identify the pattern from constructor and method

    The private constructor prevents external instantiation, and the static synchronized getInstance() ensures a single instance is created and accessed safely in concurrent contexts.
  2. Step 2: Why Singleton fits the Board class

    Since the game requires exactly one board per session to maintain consistent state, Singleton enforces this constraint. Factory and Builder patterns do not restrict instance count, and Prototype is for cloning, not single-instance control.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Private constructor + synchronized getInstance() -> Singleton pattern [check]
Hint: Private constructor + static getInstance() -> Singleton [check]
Common Mistakes:
2. To add a WeekendFeeStrategy for weekend pricing in the current booking system design, which minimal change respects the Open-Closed Principle (OCP)?
medium
A. Modify the existing FeeCalculator class to add weekend logic with if-else conditions.
B. Create a new class implementing FeeStrategy interface for weekend fees and inject it without changing existing classes.
C. Add a boolean flag isWeekend in Booking and handle fees there.
D. Extend FeeCalculator with a subclass that overrides fee calculation for weekends.

Solution

  1. Step 1: Identify OCP requirement

    OCP requires adding new functionality without modifying existing tested code.
  2. Step 2: Evaluate options

    Add a boolean flag isWeekend in Booking and handle fees there. adds weekend flag in Booking, which violates OCP by modifying Booking class. Create a new class implementing FeeStrategy interface for weekend fees and inject it without changing existing classes. creates a new FeeStrategy class, respecting OCP by extension. Modify the existing FeeCalculator class to add weekend logic with if-else conditions. and D modify existing classes, violating OCP.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    New FeeStrategy class -> extend without modifying existing code [check]
Hint: New strategy class -> extend, don't modify [check]
Common Mistakes:
3. In a multi-threaded environment, if the clone() method is not synchronized, which exact sequence of events can cause two threads to receive the same cloned object instance, leading to shared mutable state?
medium
A. Thread 1 calls clone(), completes; Thread 2 calls clone(), completes immediately after
B. Thread 1 starts clone(), copies partial state; context switch; Thread 2 starts clone(), copies same partial state; both return identical shared references
C. Thread 1 and Thread 2 both call clone() simultaneously but get different instances due to JVM guarantees
D. Thread 1 calls clone(), context switch; Thread 2 calls clone(), but Thread 1 finishes first, so no conflict

Solution

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

    Without synchronization, clone() can copy partial or inconsistent state if interrupted mid-copy.
  2. Step 2: Trace exact interleaving causing shared mutable state

    Thread 1 copies partial state, context switch to Thread 2 which copies same partial state, both return references to the same underlying mutable object.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Unsynchronized clone() -> partial copy race -> shared mutable instance [check]
Hint: Unsync clone() -> partial copy race -> shared object [check]
Common Mistakes:
4. To add a WeekendFeeStrategy for weekend parking fees without modifying existing classes, which SOLID principle is being applied and what is the minimal required change?
medium
A. Single Responsibility Principle; modify ParkingLot to add weekend fee logic.
B. Open-Closed Principle; create a new WeekendFeeStrategy class implementing FeeStrategy and inject it without changing existing code.
C. Dependency Inversion Principle; invert dependencies by making ParkingLot depend on concrete weekend fee classes.
D. Liskov Substitution Principle; override existing fee methods in ParkingLot subclass for weekend fees.

Solution

  1. Step 1: Identify SOLID principle

    Open-Closed Principle (OCP) requires extending behavior without modifying existing classes.
  2. Step 2: Apply minimal change

    Create new WeekendFeeStrategy implementing FeeStrategy and inject it; no existing class changes needed.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    OCP: new fee class added, existing classes unchanged [check]
Hint: OCP: extend with new class, no existing code changes [check]
Common Mistakes:
5. The system needs to support ElectricCar vehicles and ChargingSpot parking spots without modifying existing classes. What is the minimum change to the current Java design to support this extensibility?
hard
A. Modify Vehicle base class to add isElectric flag and add ChargingSpot as a subclass of existing Spot class.
B. Create a new ElectricVehicle interface and make ElectricCar implement it; modify existing Vehicle class to support interface checks.
C. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType enum, create ElectricCar subclass, and update SpotCompatibility map; no existing classes modified.
D. Add a boolean field 'supportsCharging' to Spot class and modify Vehicle class to check this field during parking.

Solution

  1. Step 1: Identify extensibility without modifying existing classes

    Adding new enum values and new subclasses allows extension without changing existing class code, preserving OCP.
  2. Step 2: Why updating compatibility map is needed

    SpotCompatibility map controls which vehicle types fit which spots; updating it supports new ElectricCar and ChargingSpot types without class changes.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    New enums + subclass + compatibility map update -> no existing class changes [check]
Hint: Extend enums + subclasses + compatibility map, no class edits [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