Bird
Raised Fist0

Traffic Light System - State Machine, Sensor Input, Emergency Override

LLDmediumInterview freq: medium
Choose your preparation mode4 modes available
🏗️
Traffic Light System - State Machine, Sensor Input, Emergency Override
Design a robust traffic light controller with state machine logic, sensor inputs, and emergency vehicle override.
mediumSystems with State MachinesFreq: medium
Prerequisites:OOP BasicsFinite State Machines
⚙️
Functional Requirements
  • Traffic lights cycle through states in a fixed order: GREEN -> YELLOW -> RED -> GREEN.
  • Sensor input can extend or shorten GREEN light duration dynamically.
  • Emergency override immediately switches light to GREEN for emergency direction and RED for others.
  • System must prevent conflicting green lights in intersecting directions.
  • State transitions must be thread-safe to handle concurrent sensor and override inputs.
  • System should log state changes for audit and debugging.
  • Manual override can pause or reset the state machine.
👤
Use Cases
  • Normal traffic light cycling through RED, GREEN, YELLOW states based on timers.
  • Adjust light durations dynamically based on sensor input detecting vehicle presence.
  • Emergency override to immediately switch lights to allow emergency vehicle passage.
  • Manual override by maintenance operator for testing or emergency.
  • Fail-safe behavior when sensors fail or no input is received.
🧑‍💻
Actors
  • TrafficLightController
  • VehicleSensor
  • EmergencyVehicleDetector
  • TrafficLight
  • MaintenanceOperator
❓
Clarifying Questions to Ask
  • How many traffic lights or intersections are managed concurrently? (Concurrency level)
  • Are sensor inputs polled or event-driven? How frequent are updates?
  • What is the expected maximum duration for each light state?
  • How should the system behave if multiple emergency overrides occur simultaneously?
  • Is there a pricing or cost model affecting sensor usage or override priority?
  • What happens if sensor input is lost or corrupted?
  • Should the system support pedestrian crossing signals?
Out of Scope
✗ Physical hardware interfacing details (e.g., actual light bulbs).
✗ Network communication protocols for remote control.
✗ Detailed UI for operator control beyond basic manual override.
⚡
QPS Calculation
read qps1000
write qps200
🖥️
Server Estimate
count2
typestandard
Estimated QPS based on expected sensor input frequency and override events; data volume based on logs and state changes; server count supports redundancy and concurrency.
🔢
Enumerations
enum LightState
RED | YELLOW | GREEN
Enum prevents typo bugs and enables exhaustive switch statements for traffic light states, ensuring compile-time safety.
enum Direction
NORTH_SOUTH | EAST_WEST
Enum defines fixed directions for traffic flow, preventing invalid direction values and enabling clear logic separation.
enum OverrideType
NONE | EMERGENCY | MANUAL
Enum captures override modes explicitly, enabling clear state management and preventing invalid override states.
📦
TrafficLight
3 fields
private volatile LightState currentStateprivate final Direction directionprivate volatile boolean isOperational
Represents a single traffic light with a direction and current state; manages state updates and operational status.
Why thisUsing volatile and synchronized methods ensures thread-safe state updates without external libraries.
Why notAvoided using external concurrency frameworks like Akka to keep design simple and focused.
public synchronized LightState getCurrentState()Returns the current light state in a thread-safe manner.
public synchronized void setState(LightState state)Sets the current light state atomically to prevent race conditions.
public boolean isOperational()Returns whether the traffic light is operational; volatile ensures visibility.
public synchronized void setOperational(boolean operational)Sets the operational status atomically.
📦
TrafficLightController
3 fields
private final Map<Direction, TrafficLight> trafficLightsprivate volatile OverrideType currentOverrideprivate final Object stateLock
Manages traffic light states using a state machine, processes sensor inputs, and handles emergency/manual overrides.
Why thisSynchronized methods and volatile fields provide thread safety without complex frameworks.
Why notDid not use distributed coordination tools like Zookeeper as system assumed to be single-node.
public synchronized void startCycle()Starts the traffic light state machine cycle.
public synchronized void processSensorInput(Direction direction, boolean vehicleDetected)Adjusts light timing based on sensor input for the specified direction.
public synchronized void applyEmergencyOverride(Direction priorityDirection)Immediately switches lights to allow emergency vehicle passage in priority direction.
public synchronized void clearOverride()Clears any active override and resumes normal cycling.
public OverrideType getCurrentOverride()Returns the current override type; volatile ensures visibility.
📦
VehicleSensor
2 fields
private final Direction directionprivate volatile boolean vehicleDetected
Detects vehicle presence in a specific direction and reports to controller.
Why thisSimple synchronized methods ensure consistent sensor state updates.
Why notAvoided event-driven frameworks to keep design straightforward.
public synchronized void detectVehicle(boolean detected)Updates vehicle detection status atomically.
public boolean isVehicleDetected()Returns current vehicle detection status; volatile ensures visibility.
📦
EmergencyVehicleDetector
2 fields
private volatile boolean emergencyDetectedprivate volatile Direction priorityDirection
Detects emergency vehicles and signals priority direction for override.
Why thisVolatile fields and synchronized updates ensure thread-safe emergency detection.
Why notDid not use external event processing systems to maintain simplicity.
public synchronized void detectEmergency(boolean detected, Direction direction)Updates emergency detection status and priority direction atomically.
public boolean isEmergencyDetected()Returns emergency detection status; volatile ensures visibility.
public Direction getPriorityDirection()Returns the direction with emergency priority.
📦
StateMachine
2 fields
private volatile LightState currentStateprivate final Map<LightState, LightState> stateTransitions
Encapsulates the finite state machine logic for traffic light state transitions.
Why thisSynchronized methods ensure consistent state transitions without race conditions.
Why notAvoided using external state machine libraries to keep control internal and simple.
public synchronized LightState getNextState()Returns the next state in the cycle atomically.
public synchronized void setCurrentState(LightState state)Sets the current state atomically.
public synchronized LightState getCurrentState()Returns the current state atomically.
🗄️
TrafficLightStateLog
PK: direction
direction STRINGtimestamp TIMESTAMPstate STRINGoverride_type STRING
Stores logs of traffic light state changes for audit.
🗄️
SensorEventLog
PK: sensor_id
sensor_id STRINGevent_time TIMESTAMPvehicle_detected BOOLEAN
Stores vehicle sensor detection events.
🔌
POST
/trafficlight/start
Request
{
  "intersectionId": "string"
}
Response
{
  "status": "string",
  "message": "string"
}
Starts the traffic light cycle for a given intersection.
🔌
POST
/trafficlight/override
Request
{
  "direction": "string",
  "overrideType": "string"
}
Response
{
  "status": "string",
  "message": "string"
}
Applies an override (emergency or manual) to the traffic lights.
🔌
POST
/trafficlight/override/clear
Request
{}
Response
{
  "status": "string",
  "message": "string"
}
Clears any active override and resumes normal operation.

Practice

(1/5)
1. In designing the ATM system, should the Card entity be modeled as an abstract class or an interface, considering it has state (card number, expiry) and behavior (validate PIN)? Why?
easy
A. Abstract class, because Card has shared state and behavior that concrete card types inherit.
B. Interface, because Card only defines behavior and no state, allowing multiple inheritance.
C. Interface, because Java interfaces can now have default methods to hold behavior and state.
D. Abstract class, because it enforces implementation of all methods without sharing state.

Solution

  1. Step 1: Analyze Card's characteristics

    Card holds state (card number, expiry) and behavior (validate PIN), so it needs to share state and common logic.
  2. Step 2: Choose between abstract class and interface

    Abstract class supports shared state and behavior inheritance. Interface cannot hold instance state, only constants and default methods without instance fields.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Shared state + behavior -> abstract class [check]
Hint: Stateful base entity -> abstract class, not interface [check]
Common Mistakes:
2. A class provides a createIterator() method that returns an object allowing traversal over its elements without exposing its internal data structure. Which design pattern is being applied and why is this the correct choice?
easy
A. Factory Method pattern, because it encapsulates object creation logic.
B. Decorator pattern, because it adds traversal behavior dynamically.
C. Iterator pattern, because it separates traversal logic from the collection's internal structure.
D. Composite pattern, because it treats individual and composite objects uniformly.

Solution

  1. Step 1: Identify the role of createIterator()

    This method returns an object that allows clients to traverse elements without exposing the collection's internal representation, which is the core intent of the Iterator pattern.
  2. Step 2: Eliminate other patterns

    Factory Method focuses on object creation, Decorator adds responsibilities dynamically, and Composite manages tree structures. None focus on traversal abstraction.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Iterator separates traversal from collection internals [check]
Hint: Iterator hides structure, exposes traversal [check]
Common Mistakes:
3. You want to add a WeekendFeeStrategy to calculate parking fees differently on weekends. According to SOLID principles, what is the minimum change required in the current Abstract Factory design?
medium
A. Add a boolean weekend flag to ParkingLot and modify fee calculation accordingly.
B. Create a new WeekendFeeStrategy class implementing FeeStrategy and inject it without modifying existing classes.
C. Combine all fee strategies into one class with multiple methods for each pricing rule.
D. Modify the existing FeeStrategy class to add weekend logic with if-else checks.

Solution

  1. Step 1: Identify SOLID principle involved

    Open-Closed Principle (OCP) requires new functionality added via extension, not modification.
  2. Step 2: Evaluate options

    Create a new WeekendFeeStrategy class implementing FeeStrategy and inject it without modifying existing classes. respects OCP by adding a new class without modifying existing ones. Add a boolean weekend flag to ParkingLot and modify fee calculation accordingly. modifies ParkingLot, violating OCP. Options A and D modify existing classes, violating OCP.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    New strategy class added, existing classes unchanged [check]
Hint: OCP: extend with new class, don't modify existing ones [check]
Common Mistakes:
4. Given the current parking lot design, adding a WeekendFeeStrategy requires which minimum change to comply with SOLID principles?
medium
A. Add a boolean flag isWeekend in FeeCalculator and use conditional logic.
B. Create a new WeekendFeeStrategy class implementing FeeStrategy and inject it without changing existing classes.
C. Modify the FeeCalculator class to add weekend fee logic inside existing methods.
D. Extend FeeCalculator with a subclass WeekendFeeCalculator overriding fee methods.

Solution

  1. Step 1: Identify the SOLID principle involved

    The Open-Closed Principle (OCP) requires that classes be open for extension but closed for modification.
  2. Step 2: Evaluate each option against OCP

    Modify the FeeCalculator class to add weekend fee logic inside existing methods. and C modify existing classes violating OCP. Extend FeeCalculator with a subclass WeekendFeeCalculator overriding fee methods. creates subclass but may cause code duplication. Create a new WeekendFeeStrategy class implementing FeeStrategy and inject it without changing existing classes. adds a new strategy class implementing FeeStrategy and injects it, extending behavior without modifying existing code.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    New strategy class + injection -> OCP-compliant extension [check]
Hint: OCP: extend with new class, don't modify existing code [check]
Common Mistakes:
5. You need to add support for ElectricCar that requires ChargingSpot compatibility in the current parking system. What is the minimum change to the design to support this without modifying existing classes?
hard
A. Modify Vehicle class to add a boolean needsCharging and update parking logic to check this flag.
B. Add ELECTRIC_CAR to VehicleType enum, CHARGING to SpotType, create ElectricCar subclass, and update SpotCompatibility.COMPATIBILITY_MAP accordingly.
C. Create a new ElectricParkingLot subclass that handles electric cars and charging spots separately.
D. Add a ChargingSpot field to Vehicle and modify all parking methods to handle it.

Solution

  1. Step 1: Identify extensibility requirements

    ElectricCar and ChargingSpot are new types requiring compatibility mapping without changing existing classes.
  2. Step 2: Apply minimal invasive change

    Adding new enum values and subclass plus updating compatibility map extends functionality without modifying existing class code, preserving OCP.
  3. Step 3: Avoid violating OCP

    Options B, C, and D modify existing classes or create parallel hierarchies, increasing complexity and violating OCP.
  4. Final Answer:

    Option B -> Option B
  5. Quick Check:

    Extend enums and map, subclass ElectricCar -> minimal change [check]
Hint: Extend enums and map, subclass new type -> 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