Requirements


Functional Requirements:


1. Parking Spot Assignment

  • Assign spot based on vehicle size compatibility:
    • Motorcycle → small (preferred), medium, large
    • Car → medium (preferred), large
    • Truck → large only
  • System should pick the smallest available suitable spot.

2. Vehicle Entry

  • On entry:
    • Check availability
    • If available:
      • Assign spot
        • Generate a ParkingTicketticketId
        • vehicle details (number, type)
        • assigned spot
        • entry timestamp
    • If full:
      • Reject entry
      • Show “Parking Full”

3. Vehicle Exit

  • On exit:
    • Fetch ticket
    • Calculate duration
    • Compute fee using pricing strategy
    • Mark spot as free

4. Parking Fee Calculation

  • Fee based on:
    • Entry time → Exit time
    • Pricing strategy (pluggable/configurable)
      • Example:
        • Hourly
        • Flat rate
        • Tiered pricing

5. Parking Lot Capacity Handling

  • System should:
    • Detect when all spots are full
    • Prevent new entries
    • Provide a lot-full indicator

6. Multi-Floor Support

  • Parking lot contains:
    • Multiple floors
  • Each floor contains:
    • Small spots
    • Medium spots
    • Large spots



Non-Functional Requirements:


1. Scalability

  • System should handle:
    • Large parking lots (multiple floors, thousands of spots)
    • High traffic (many vehicles entering/exiting simultaneously)
  • Design should support adding more floors without major changes.

2. Performance

  • Low latency for:
    • Spot allocation (entry should be fast)
    • Fee calculation (exit should be quick)
  • Avoid scanning all spots → use optimized data structures (e.g., indexed by size & availability).

3. Concurrency

  • Multiple vehicles may:
    • Enter at the same time
    • Exit at the same time
  • System must avoid:
    • Double allocation of same spot
  • Requires thread-safe operations / locking mechanism.

4. Availability

  • System should be highly available:
    • Entry/exit should not fail frequently
  • Graceful handling:
    • If system is down → fallback/manual mode (optional discussion point)

5. Consistency

  • Strong consistency required for:
    • Spot availability
    • Ticket validity
  • A spot should never be:
    • Assigned to two vehicles at once

6. Extensibility

  • Easy to extend:
    • New vehicle types
    • New pricing strategies
    • Reservation system (future)
  • Suggests use of:
    • Interfaces / Strategy Pattern / Open-Closed Principle

7. Maintainability

  • Clean, modular design
  • Separation of concerns:
    • Allocation logic
    • Pricing logic
    • Ticket management

8. Reliability

  • System should:
    • Correctly track entry/exit
    • Avoid data loss (tickets, timestamps)
  • Handle edge cases:
    • Invalid ticket
    • Duplicate exit

9. Observability (Nice-to-have)

  • Logs for:
    • Entry/exit events
    • Failures (e.g., full lot)
  • Metrics:
    • Occupancy rate
    • Revenue

10. Configurability

  • Pricing strategy should be configurable without code changes (ideally).
  • Spot distribution per floor can be flexible.



Core Objects & Relationships

1. ParkingLot

  • Represents the entire system
  • Attributes:
    • list of ParkingFloor
  • Responsibilities:
    • Initialize system
    • Delegate parking requests

2. ParkingFloor

  • Represents one floor
  • Attributes:
    • floorId
    • list of ParkingSpot
  • Responsibilities:
    • Manage spots on that floor
    • Provide available spots

3. ParkingSpot (Abstract)

  • Base class for all spot types
  • Attributes:
    • spotId
    • isOccupied
    • vehicle (optional)
  • Types:
    • SmallSpot
    • MediumSpot
    • LargeSpot

4. Vehicle (Abstract)

  • Attributes:
    • vehicleNumber
    • vehicleType
  • Types:
    • Motorcycle
    • Car
    • Truck

5. ParkingTicket

  • Attributes:
    • ticketId
    • vehicle
    • parkingSpot
    • entryTime
    • exitTime
    • totalFee
  • Responsibility:
    • Store parking session info

6. ParkingLotManager (or ParkingService)

  • Core business logic class
  • Responsibilities:
    • Assign spot
    • Create ticket
    • Handle exit
    • Free spot

7. PricingStrategy (Interface)

  • Method:
    • calculateFee(entryTime, exitTime)
  • Implementations:
    • HourlyPricingStrategy
    • FlatRatePricingStrategy



Relationships Between Objects

1. Composition (Strong Ownership)

  • ParkingLot → contains → ParkingFloor
  • ParkingFloor → contains → ParkingSpot

If ParkingLot is deleted, everything goes away.

2. Inheritance (Generalization)

  • ParkingSpot → Small / Medium / Large
  • Vehicle → Motorcycle / Car / Truck
  • PricingStrategy → different strategies

3. Association

  • ParkingTicket → has → Vehicle
  • ParkingTicket → has → ParkingSpot

4. Dependency

  • ParkingLotManager depends on:
    • ParkingLot
    • PricingStrategy

5. One-to-Many Relationships

  • One ParkingLot → many ParkingFloor
  • One ParkingFloor → many ParkingSpot
  • One ParkingSpot → at most one Vehicle





APIs & Class Members

For each class, define the attributes (data) it will hold and the methods (functions) that operate on the attributes. Ensure they align with the object's responsibilities and adhere to the principle of encapsulation. Write your code in the code editor below.



Deep Dive

🧠 1. Design Tradeoffs

⚖️ 1. Simplicity vs Performance

Choice made:

  • Used Queue per SpotTypeO(1) allocation

Tradeoff:

  • ✅ Fast allocation
  • ❌ No guarantee of nearest spot

Alternative:

  • Use PriorityQueue (distance-based)
    • ✅ Better UX (nearest spot)
    • ❌ Slightly higher complexity (log n)

⚖️ 2. Global Lock vs Fine-Grained Locking

Choice made:

  • synchronized at ParkingLotManager
  • ReentrantLock at floor level

Tradeoff:

  • ✅ Easy to implement, safe
  • ❌ Limits parallelism under heavy load

Alternative:

    • Lock per SpotType or even per ParkingSpot✅ Better concurrency
    • ❌ More complex, risk of deadlocks

⚖️ 3. In-Memory Storage vs Persistent Storage

Choice made:

  • HashMap<String, ParkingTicket> (in-memory)

Tradeoff:

  • ✅ Fast, simple
  • ❌ Data loss on crash

Alternative:

  • Database-backed storage
    • ✅ Durable
    • ❌ Latency + infra complexity

⚖️ 4. Floor Iteration Strategy

Choice made:

  • Sequentially check floors

Tradeoff:

  • ✅ Simple
  • ❌ Not optimal for large systems

Alternative:

    • Maintain global availability indexFaster lookup
    • More bookkeeping

🧩 2. SOLID Principles Check

S — Single Responsibility Principle

✔ Mostly followed:

  • ParkingFloor → manages spots
  • ParkingLotManager → orchestrates parking
  • PricingStrategy → fee logic

⚠️ Minor issue:

  • ParkingLotManager does multiple things:
    • allocation + ticketing + orchestration

👉 Improvement:

  • Split into:
    • SpotAllocator
    • TicketService

O — Open/Closed Principle

✔ Well followed:

  • Add new pricing → implement PricingStrategy
  • Add new vehicle → extend Vehicle

❌ Slight violation:

  • Spot preference logic uses switch

👉 Improvement:

  • Move logic into:
vehicle.getAllowedSpotTypes()

L — Liskov Substitution Principle

✔ Fully followed:

  • Car, Truck can replace Vehicle
  • SmallSpot, LargeSpot behave consistently

I — Interface Segregation Principle

✔ Good:

  • PricingStrategy is clean and minimal

Could improve:

  • Introduce smaller interfaces like:
    • Allocatable
    • Billable

⚠️ D — Dependency Inversion Principle

Partially followed:

  • Depends on PricingStrategy abstraction ✅

But:

  • ParkingLotManager directly depends on ParkingFloor

👉 Improvement:

  • Introduce:
interface SpotAllocator

🚀 3. Scalability & Extensibility

📈 Scaling the System

Current Limitations:

  • Single JVM (in-memory)
  • Sequential floor scan
  • Coarse locking

✅ How to Scale

1. Horizontal Scaling

    • Move to microservicesParking Service
    • Ticket Service
    • Payment Service

2. Database Integration

  • Store:
    • Tickets
    • Spot states
  • Use:
    • Redis → fast availability lookup
    • SQL → durability

3. Distributed Locking

  • Use:
    • Redis locks
    • Zookeeper

4. Event-Driven Architecture

  • Emit events:
    • VEHICLE_PARKED
    • VEHICLE_EXITED

🧱 Extensibility

Easy to Extend:

✅ Add new pricing:

class WeekendPricing implements PricingStrategy

✅ Add EV charging spots:

  • Add EVSpot extends ParkingSpot

✅ Add reservations:

  • Add ReservationService

🔮 4. Future Improvements

🅰️ 1. Smarter Allocation

  • Nearest spot (distance-based)
  • Priority queue per entry gate

🅱️ 2. Multi-Entry Gate Support

  • Each gate:
    • Has its own allocator
    • Maintains local view

🅲 3. Real-Time Display Boards

  • Show:
    • Available spots per floor
  • Use observer pattern

🅳 4. Fault Tolerance

  • Backup ticket store
  • Recovery mechanism

🅴 5. Payment Integration

  • Add:
    • UPI / Card / Wallet
  • Separate PaymentService

🅵 6. Analytics

  • Occupancy rate
  • Revenue trends
  • Peak hours

🏁 Final Interview Summary (Say This)

👉 “The design prioritizes simplicity and O(1) allocation using queues, while maintaining extensibility through strategy patterns. It adheres well to SOLID principles with minor improvements possible around SRP and DIP. For scaling, we can move to distributed services with caching and event-driven architecture. The system is easily extensible for features like reservations, EV spots, and dynamic pricing.”