Bird
Raised Fist0
Interview Prepoop-design-patternshardAmazonGoogleMicrosoftFlipkartSwiggyRazorpayPhonePeCREDZepto

Design a Parking Lot - LLD with OOP (Classes, Patterns, Extensibility)

Choose your preparation mode3 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
🎯
Design a Parking Lot - LLD with OOP (Classes, Patterns, Extensibility)
hardOOPAmazonGoogleMicrosoft

Imagine you are tasked with designing the software for a multi-level parking lot that can handle different vehicle types, dynamic pricing, and future feature additions without major rewrites.

💡 Beginners often confuse design problems like this with algorithmic puzzles and miss the importance of extensibility and design patterns in managing complexity.
📋
Interview Question

Explain how you would design a parking lot system using object-oriented principles, focusing on class design, design patterns, and extensibility for future requirements.

Object-oriented design principles (encapsulation, abstraction, inheritance, polymorphism)Design patterns relevant to LLD (Factory, Strategy, Singleton)Extensibility and maintainability in system design
💡
Scenario & Trace
ScenarioA parking lot supports multiple vehicle types (car, bike, truck) and different spot sizes.
Vehicle objects are created with type info → ParkingSpot objects are categorized by size → ParkingLot manages allocation by matching vehicle type to spot size → Factory pattern creates vehicle and spot instances → Strategy pattern handles different pricing models per vehicle type.
ScenarioThe parking lot needs to add a new feature for monthly subscriptions without changing existing code.
Subscription pricing strategy is added as a new class implementing the pricing interface → ParkingLot uses the Strategy pattern to switch pricing dynamically → Existing classes remain unchanged, demonstrating extensibility.
  • What if all parking spots are full but a vehicle arrives?
  • How to handle different vehicle sizes that don’t fit standard spots?
  • What happens when multiple vehicles arrive simultaneously for the last available spot?
⚠️
Common Mistakes
Treating the problem as just an algorithmic puzzle rather than a design problem

Interviewer perceives lack of system design thinking and OOP understanding

Focus on class design, relationships, and extensibility rather than just parking allocation logic

Ignoring extensibility and hardcoding vehicle types or pricing logic

Design becomes rigid and unmaintainable, interviewer doubts scalability

Use design patterns like Factory and Strategy to allow easy addition of new types and policies

Not considering concurrency or edge cases like full capacity or simultaneous requests

Design appears naive and incomplete, raising red flags about real-world readiness

Discuss synchronization, locking, or queuing mechanisms and how the system handles no available spots

Confusing inheritance with composition and overusing inheritance

Design becomes inflexible and tightly coupled, making future changes difficult

Favor composition and programming to interfaces to enhance flexibility

🧠
Basic Definition - What It Is
💡 This level covers the fundamental understanding of what a parking lot design entails in OOP terms.

Intuition

Designing a parking lot system means modeling real-world entities as classes and defining their relationships.

Explanation

At the basic level, designing a parking lot involves identifying key entities such as Vehicle, ParkingSpot, and ParkingLot. Each entity is represented as a class with attributes and behaviors. For example, a Vehicle class might have properties like vehicle type and license number, while ParkingSpot has size and availability status. The ParkingLot class manages the collection of spots and handles parking and unparking operations. This level focuses on clear class definitions and simple interactions without deep pattern usage or extensibility considerations.

Memory Hook

💡 Think of the parking lot as a set of boxes (spots) and items (vehicles) that fit into them.

Interview Questions

What classes would you create for a parking lot system?
  • Vehicle class with type and license
  • ParkingSpot class with size and availability
  • ParkingLot class managing spots and vehicles
Depth Level
Interview Time30 seconds
Depthbasic

Covers fundamental class identification and relationships; sufficient for quick screening.

Interview Target: Minimum floor - never go below this

Knowing only this will help you pass initial screening but won’t impress in detailed design rounds.

🧠
Mechanism Depth - How It Works
💡 This level explains the internal design mechanisms, patterns, and extensibility strategies expected in product company interviews.

Intuition

A robust parking lot design uses design patterns and OOP principles to handle complexity and future changes gracefully.

Explanation

At this level, you explain how design patterns like Factory are used to instantiate different vehicle and parking spot types, enabling easy addition of new types without modifying existing code. The Strategy pattern allows dynamic pricing models or parking policies to be swapped without changing core logic. Singleton pattern ensures a single instance of ParkingLot manages the entire system state. You also discuss how inheritance and interfaces abstract common behaviors (e.g., Vehicle interface with Car, Bike subclasses). Extensibility is achieved by programming to interfaces and using composition over inheritance where appropriate. Concurrency considerations for simultaneous parking requests and handling edge cases like full capacity are also addressed.

Memory Hook

💡 Design patterns are the toolkit that lets your parking lot grow and adapt like a well-oiled machine.

Interview Questions

How would you add a new vehicle type or pricing strategy without changing existing classes?
  • Use Factory pattern to create new vehicle and spot types
  • Implement new pricing strategy class following Strategy interface
  • ParkingLot uses interfaces and composition to remain unchanged
How do you ensure only one ParkingLot instance manages the system?
  • Implement Singleton pattern for ParkingLot
  • Provide global access point while preventing multiple instances
Depth Level
Interview Time2-3 minutes
Depthintermediate

Demonstrates understanding of design patterns, OOP principles, and extensibility; expected in FAANG on-sites.

Interview Target: Target level for FAANG on-sites

Mastering this level distinguishes you from most candidates and shows readiness for complex system design.

📊
Explanation Depth Levels
💡 Choose your explanation depth based on the interview stage and company expectations.
LevelInterview TimeSuitable ForRisk
Basic Definition30sScreening call or initial roundsToo shallow for on-site or design-focused interviews
Mechanism Depth2-3 minutesOn-site interviews at FAANG and top product companiesRequires strong understanding; missing this level reduces chances of success
💼
Interview Strategy
💡 Use this guide to structure your explanation clearly and confidently before every mock or real interview.

How to Present

Start with a clear definition of the problem and key classes involvedGive a relatable example or analogy to ground your explanationExplain the internal design using relevant design patterns and OOP principlesDiscuss edge cases and how your design handles them

Time Allocation

Definition: 30s → Example: 1min → Mechanism: 2min → Edge cases: 30s. Total ~4min

What the Interviewer Tests

Interviewer checks your ability to model real-world entities, apply design patterns, ensure extensibility, and handle edge cases.

Common Follow-ups

  • How would you handle concurrency when multiple vehicles arrive simultaneously?
  • What changes if the parking lot supports monthly subscriptions or dynamic pricing?
💡 These follow-ups test your depth in concurrency and adaptability of your design.
🔍
Pattern Recognition

When to Use

When asked to design a real-world system with multiple interacting entities and future extensibility requirements.

Signature Phrases

'Explain how you would design...''Compare different design approaches for...''What happens when you add a new feature to...'

NOT This Pattern When

Similar Problems

Practice

(1/5)
1. You are designing a system where multiple unrelated classes must guarantee implementation of certain methods but share no common code. Which abstraction mechanism is most appropriate to enforce this contract?
easy
A. Use an abstract class to define the methods and provide partial implementation.
B. Use an abstract class only if all classes share a common ancestor.
C. Use a concrete class and rely on inheritance for code reuse.
D. Use an interface to declare the methods without any implementation.

Solution

  1. Step 1: Identify the need for a contract without shared code

    Interfaces define method signatures without implementation, perfect for unrelated classes needing a common contract.
  2. Step 2: Why abstract classes are less suitable here

    Abstract classes provide partial implementation and require a common ancestor, which unrelated classes lack.
  3. Step 3: Why concrete classes and inheritance don't fit

    Concrete classes imply implementation and inheritance assumes a hierarchy, which is not guaranteed.
  4. Final Answer:

    Option D -> Option D
  5. Quick Check:

    Interfaces enforce contracts without imposing inheritance or shared code.
Hint: Use interfaces when only a contract is needed, abstract classes when sharing code.
Common Mistakes:
  • Assuming abstract classes are always better for abstraction.
  • Confusing contract enforcement with code reuse.
  • Believing unrelated classes can share an abstract class.
2. When an object composed of multiple behaviors receives a request to perform an action, what is the typical sequence of internal steps that occur to fulfill this request?
easy
A. The object delegates the action to one or more composed behavior objects which execute their respective parts
B. The object checks flags internally and runs conditional code for each behavior
C. The object directly executes the action code inherited from its superclass
D. The object creates a new subclass instance dynamically to handle the action

Solution

  1. Step 1: Understand delegation in composition

    In composition, the main object delegates responsibilities to composed behavior objects rather than handling all logic itself.
  2. Step 2: Analyze each option

    The object directly executes the action code inherited from its superclass describes inheritance, not composition. The object checks flags internally and runs conditional code for each behavior implies flag-based conditional logic, which is less flexible. The object creates a new subclass instance dynamically to handle the action is not a typical or practical approach.
  3. Step 3: Confirm correct flow

    The composed behaviors receive the delegated call and execute their specific logic, enabling modular and maintainable design.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Delegation to composed objects is the hallmark of composition-based design.
Hint: Composition means delegation to behavior objects, not direct inheritance execution.
Common Mistakes:
  • Confusing inheritance method calls with composition delegation
  • Assuming flags control behavior execution internally
3. Trace the sequence of events when a client calls a method on a subclass instance that violates the Liskov Substitution Principle by strengthening a postcondition. What happens step-by-step?
easy
A. The client receives a result that meets the superclass contract, so no issues arise.
B. The subclass method returns a stricter result than expected, potentially causing client failures.
C. The client silently ignores the stricter postcondition, so behavior is unaffected.
D. The subclass method throws an exception due to the strengthened postcondition.

Solution

  1. Step 1: Recall LSP postcondition rule

    Subclasses must not strengthen postconditions; they can only maintain or weaken them.
  2. Step 2: Trace client call

    The client expects results conforming to the superclass contract. If subclass returns stricter results, some clients expecting broader results may fail.
  3. Step 3: Analyze options

    The subclass method returns a stricter result than expected, potentially causing client failures. correctly identifies potential client failures due to stricter postconditions. The client receives a result that meets the superclass contract, so no issues arise. is false because stricter postconditions can break clients. The client silently ignores the stricter postcondition, so behavior is unaffected. is incorrect; clients cannot ignore contract violations silently. The subclass method throws an exception due to the strengthened postcondition. is not guaranteed; exceptions are not implied by postcondition strengthening.
  4. Final Answer:

    Option B -> Option B
  5. Quick Check:

    Strengthening postconditions risks breaking client expectations.
Hint: Strengthening postconditions breaks client assumptions and causes failures.
Common Mistakes:
  • Assuming stricter postconditions are safe
  • Believing clients ignore contract violations
  • Confusing exceptions with contract violations
4. Which of the following is a common trade-off or limitation when strictly applying the Open/Closed Principle in a large software system?
medium
A. It forces all changes to be made in a single base class, increasing risk of bugs
B. It can lead to excessive class proliferation, making the codebase harder to navigate
C. It eliminates the need for interfaces or abstract classes, simplifying design
D. It guarantees zero runtime overhead due to polymorphism

Solution

  1. Step 1: Identify trade-offs of OCP

    Strict adherence often results in many small subclasses, increasing complexity.
  2. Step 2: Why other options are false

    It forces all changes to be made in a single base class, increasing risk of bugs is opposite to OCP's goal; changes are made via extension, not base modification. It eliminates the need for interfaces or abstract classes, simplifying design is false because OCP relies on abstractions like interfaces. It guarantees zero runtime overhead due to polymorphism is incorrect; polymorphism can introduce slight runtime overhead.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    Class explosion is a known practical downside of OCP.
Hint: OCP can cause many small classes [OK]
Common Mistakes:
  • Thinking OCP centralizes changes in base classes
  • Believing OCP removes need for abstractions
  • Assuming polymorphism has no runtime cost
5. Identify the bug in the following Python code implementing deep copy for the Profile class:
import copy

class Profile:
    def __init__(self, name, scores):
        self.name = name
        self.scores = scores

    def __deepcopy__(self, memo):
        new_name = self.name  # Bug here
        new_scores = copy.deepcopy(self.scores, memo)
        return Profile(new_name, new_scores)

original = Profile('Alice', [10, 20])
copy_obj = copy.deepcopy(original)
copy_obj.scores.append(30)
print(original.scores)
medium
A. Line assigning new_name = self.name does not deepcopy the name string
B. Line assigning new_scores = copy.deepcopy(self.scores, memo) incorrectly copies scores
C. The __init__ method does not initialize scores properly
D. The return statement returns a new Profile instead of modifying self

Solution

  1. Step 1: Examine __deepcopy__ method

    The line new_name = self.name copies the reference to the name string instead of deep copying it.
  2. Step 2: Understand impact

    Strings are immutable in Python, so shallow copy is usually safe, but if name were a mutable object, this would cause shared references and bugs. Proper deep copy should be used for consistency.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Only new_name assignment lacks deepcopy -> subtle bug [OK]
Hint: All nested fields must be deep copied consistently [OK]
Common Mistakes:
  • Forgetting to deepcopy all nested fields, assuming immutables are safe