Machine Coding Round Strategy for LLD Interviews

Updated 2026-03-11

TL;DR

Machine coding rounds require you to write complete, runnable code in 60-90 minutes, unlike whiteboard OOD which focuses on design discussions. Success depends on structured time management, knowing when to code vs. design, and delivering working software with clean architecture rather than perfect design.

Prerequisites: Understanding of basic OOP principles (classes, inheritance, polymorphism), familiarity with at least one programming language (Python, Java, or C++), and experience writing code in an IDE or text editor. Basic knowledge of design patterns is helpful but not required.

After this topic: Execute a machine coding round successfully by managing time effectively, structuring your project with proper separation of concerns, writing runnable code that demonstrates both functionality and clean design, and knowing which corners to cut strategically when time is limited.

Core Concept

What Makes Machine Coding Different

Machine coding rounds test your ability to write working code under time pressure while maintaining reasonable design quality. Unlike whiteboard OOD interviews where you discuss architecture and draw diagrams, here you must produce executable code that an interviewer can run and test.

The key difference: delivery matters more than perfection. A working solution with 80% design quality beats a beautifully architected solution that doesn’t run.

The 60-90 Minute Challenge

Most machine coding rounds give you 60-90 minutes to build a small application (parking lot, chess game, splitwise). This time constraint forces trade-offs:

  • You can’t implement every design pattern you know
  • You must prioritize core functionality over edge cases
  • Code organization matters, but extensive refactoring is a luxury
  • Testing is often manual demonstration rather than unit tests

The Three Phases Approach

Phase 1: Clarify & Design (15-20 minutes)

  • Understand requirements and ask clarifying questions
  • Identify core entities and their relationships
  • Sketch a basic class structure (on paper or comments)
  • Define the main operations/APIs needed

Phase 2: Build Core (35-45 minutes)

  • Start with data models (classes with attributes)
  • Implement the most critical use case end-to-end
  • Get something runnable as quickly as possible
  • Add remaining features incrementally

Phase 3: Polish & Demo (10-15 minutes)

  • Add input validation for demonstrated scenarios
  • Clean up obvious code smells
  • Prepare a demo script showing key features
  • Test the happy path thoroughly

Project Structure That Scales

Even in 60 minutes, organize your code into logical files:

project/
├── models/          # Core entities (User, Ride, Vehicle)
├── services/        # Business logic (RideService, PaymentService)
├── managers/        # Orchestration (RideManager)
└── main.py          # Demo/driver code

This structure shows design thinking without over-engineering.

Visual Guide

Machine Coding Round Timeline

gantt
    title 90-Minute Machine Coding Timeline
    dateFormat mm
    axisFormat %M min
    
    section Clarify
    Understand requirements    :00, 5m
    Ask questions              :05, 5m
    Sketch design              :10, 10m
    
    section Build
    Create models              :20, 15m
    First working feature      :35, 20m
    Add remaining features     :55, 20m
    
    section Polish
    Test & fix bugs            :75, 10m
    Prepare demo               :85, 5m

Recommended time allocation for a 90-minute machine coding round. Adjust proportionally for 60-minute rounds.

Code Organization Strategy

graph TD
    A[Start Coding] --> B{Can I run something?}
    B -->|No| C[Build simplest model]
    C --> D[Add one operation]
    D --> B
    B -->|Yes| E{All features done?}
    E -->|No| F[Add next feature]
    F --> E
    E -->|Yes| G[Polish & test]
    G --> H[Demo ready]
    
    style B fill:#ffe6e6
    style E fill:#ffe6e6
    style H fill:#e6ffe6

Iterative approach: get something running first, then add features incrementally.

Examples

Example 1: Parking Lot - Time-Boxed Implementation

Problem: Design a parking lot system that can park and unpark vehicles.

15-Minute Design Phase Output (comments as design):

# models/vehicle.py
class Vehicle:
    """Represents a vehicle with type and license plate"""
    pass

# models/parking_spot.py
class ParkingSpot:
    """A spot that can hold one vehicle"""
    pass

# services/parking_service.py
class ParkingService:
    """Handles parking and unparking logic"""
    def park_vehicle(self, vehicle):
        # Find available spot
        # Assign vehicle to spot
        # Return ticket
        pass
    
    def unpark_vehicle(self, ticket):
        # Find spot by ticket
        # Remove vehicle
        # Calculate fee
        pass

45-Minute Build Phase Output (working code):

# models/vehicle.py
from enum import Enum

class VehicleType(Enum):
    BIKE = 1
    CAR = 2
    TRUCK = 3

class Vehicle:
    def __init__(self, license_plate, vehicle_type):
        self.license_plate = license_plate
        self.vehicle_type = vehicle_type

# models/parking_spot.py
class ParkingSpot:
    def __init__(self, spot_id, spot_type):
        self.spot_id = spot_id
        self.spot_type = spot_type  # VehicleType
        self.vehicle = None
        self.is_occupied = False
    
    def park(self, vehicle):
        if self.is_occupied:
            return False
        if vehicle.vehicle_type != self.spot_type:
            return False
        self.vehicle = vehicle
        self.is_occupied = True
        return True
    
    def unpark(self):
        self.vehicle = None
        self.is_occupied = False

# models/ticket.py
import time

class Ticket:
    def __init__(self, spot_id, vehicle):
        self.ticket_id = f"{spot_id}_{int(time.time())}"
        self.spot_id = spot_id
        self.vehicle = vehicle
        self.entry_time = time.time()

# services/parking_service.py
class ParkingService:
    def __init__(self):
        self.spots = []
        self.tickets = {}
    
    def add_spot(self, spot):
        self.spots.append(spot)
    
    def park_vehicle(self, vehicle):
        # Find first available spot of matching type
        for spot in self.spots:
            if not spot.is_occupied and spot.spot_type == vehicle.vehicle_type:
                if spot.park(vehicle):
                    ticket = Ticket(spot.spot_id, vehicle)
                    self.tickets[ticket.ticket_id] = ticket
                    return ticket
        return None  # No spot available
    
    def unpark_vehicle(self, ticket_id):
        if ticket_id not in self.tickets:
            return None
        
        ticket = self.tickets[ticket_id]
        for spot in self.spots:
            if spot.spot_id == ticket.spot_id:
                spot.unpark()
                del self.tickets[ticket_id]
                
                # Simple fee calculation
                duration = time.time() - ticket.entry_time
                fee = int(duration / 3600) * 10  # $10 per hour
                return fee
        return None

# main.py - Demo
if __name__ == "__main__":
    service = ParkingService()
    
    # Setup parking lot
    service.add_spot(ParkingSpot("B1", VehicleType.BIKE))
    service.add_spot(ParkingSpot("C1", VehicleType.CAR))
    service.add_spot(ParkingSpot("C2", VehicleType.CAR))
    
    # Park vehicles
    car1 = Vehicle("ABC123", VehicleType.CAR)
    ticket1 = service.park_vehicle(car1)
    print(f"Parked car, ticket: {ticket1.ticket_id}")
    
    bike1 = Vehicle("XYZ789", VehicleType.BIKE)
    ticket2 = service.park_vehicle(bike1)
    print(f"Parked bike, ticket: {ticket2.ticket_id}")
    
    # Unpark
    fee = service.unpark_vehicle(ticket1.ticket_id)
    print(f"Unparked car, fee: ${fee}")

Expected Output:

Parked car, ticket: C1_1703001234
Parked bike, ticket: B1_1703001235
Unparked car, fee: $0

What This Demonstrates:

  • Working code in ~45 minutes
  • Clear separation: models, services, demo
  • Core functionality: park, unpark, fee calculation
  • Extensible design (can add more spot types)

What’s Intentionally Missing (to save time):

  • No floors/levels (can add if time permits)
  • No payment processing (mentioned in comments)
  • Minimal error handling (just None returns)
  • No persistence (in-memory only)

Example 2: Ride Sharing - Incremental Feature Addition

Core Implementation (first 30 minutes):

# models/user.py
class User:
    def __init__(self, user_id, name):
        self.user_id = user_id
        self.name = name

class Rider(User):
    pass

class Driver(User):
    def __init__(self, user_id, name, vehicle_number):
        super().__init__(user_id, name)
        self.vehicle_number = vehicle_number
        self.is_available = True

# models/ride.py
from enum import Enum

class RideStatus(Enum):
    REQUESTED = 1
    ONGOING = 2
    COMPLETED = 3

class Ride:
    def __init__(self, ride_id, rider, source, destination):
        self.ride_id = ride_id
        self.rider = rider
        self.driver = None
        self.source = source
        self.destination = destination
        self.status = RideStatus.REQUESTED
    
    def assign_driver(self, driver):
        self.driver = driver
        self.status = RideStatus.ONGOING
    
    def complete(self):
        self.status = RideStatus.COMPLETED
        if self.driver:
            self.driver.is_available = True

# services/ride_service.py
class RideService:
    def __init__(self):
        self.rides = {}
        self.drivers = []
        self.ride_counter = 1
    
    def add_driver(self, driver):
        self.drivers.append(driver)
    
    def request_ride(self, rider, source, destination):
        ride = Ride(f"R{self.ride_counter}", rider, source, destination)
        self.ride_counter += 1
        
        # Simple matching: first available driver
        for driver in self.drivers:
            if driver.is_available:
                ride.assign_driver(driver)
                driver.is_available = False
                break
        
        self.rides[ride.ride_id] = ride
        return ride
    
    def complete_ride(self, ride_id):
        if ride_id in self.rides:
            self.rides[ride_id].complete()
            return True
        return False

# main.py
if __name__ == "__main__":
    service = RideService()
    
    # Add drivers
    driver1 = Driver("D1", "John", "CAR123")
    driver2 = Driver("D2", "Jane", "CAR456")
    service.add_driver(driver1)
    service.add_driver(driver2)
    
    # Request rides
    rider1 = Rider("R1", "Alice")
    ride1 = service.request_ride(rider1, "LocationA", "LocationB")
    
    if ride1.driver:
        print(f"Ride {ride1.ride_id} assigned to {ride1.driver.name}")
    else:
        print(f"Ride {ride1.ride_id} waiting for driver")
    
    # Complete ride
    service.complete_ride(ride1.ride_id)
    print(f"Ride {ride1.ride_id} completed")

Expected Output:

Ride R1 assigned to John
Ride R1 completed

Next 15 Minutes - Add Pricing (if time permits):

# services/pricing_service.py
class PricingService:
    BASE_FARE = 50
    PER_KM = 10
    
    @staticmethod
    def calculate_fare(distance_km):
        return PricingService.BASE_FARE + (distance_km * PricingService.PER_KM)

# Update Ride model
class Ride:
    def __init__(self, ride_id, rider, source, destination, distance_km=5):
        # ... existing code ...
        self.distance_km = distance_km
        self.fare = None
    
    def complete(self):
        self.status = RideStatus.COMPLETED
        self.fare = PricingService.calculate_fare(self.distance_km)
        if self.driver:
            self.driver.is_available = True

# Updated demo
ride1 = service.request_ride(rider1, "LocationA", "LocationB")
service.complete_ride(ride1.ride_id)
print(f"Fare: ${ride1.fare}")

Try it yourself: Add a rating system where riders can rate drivers (1-5 stars) after completing a ride. Store ratings with the driver and calculate average rating.

Common Mistakes

1. Over-Designing Before Coding

Mistake: Spending 30-40 minutes designing the perfect class hierarchy with multiple design patterns before writing any code.

Why it’s bad: You risk running out of time with nothing runnable to show. Interviewers value working code over theoretical perfection.

Fix: Spend max 15-20 minutes on design. Start with simple classes and refactor as you go. Your first version should be runnable within 30 minutes.

2. Building Everything in One File

Mistake: Writing all classes in main.py or a single file, creating a 500-line monolith.

Why it’s bad: Shows poor code organization skills. Makes it hard for interviewers to navigate your code. Signals lack of real-world project experience.

Fix: Even in 60 minutes, create separate files for models, services, and demo code. This takes 2 extra minutes but demonstrates professional habits.

# Bad - everything in one file
# main.py (500 lines)
class User: ...
class Ride: ...
class RideService: ...
if __name__ == "__main__": ...

# Good - organized structure
# models/user.py
# models/ride.py
# services/ride_service.py
# main.py (demo only)

3. No Working Demo Until the End

Mistake: Writing all classes and methods, then trying to run the code for the first time at minute 85.

Why it’s bad: You discover bugs too late to fix them. If you run out of time, you have nothing to demonstrate.

Fix: Get something runnable by minute 30. Even if it’s just creating objects and printing them. Build incrementally with frequent testing.

# Minute 30 - should have this working:
user = User("U1", "Alice")
print(f"Created user: {user.name}")  # Test immediately

# Minute 45 - should have core feature:
ride = service.request_ride(user, "A", "B")
print(f"Ride status: {ride.status}")  # Verify it works

4. Ignoring the Happy Path

Mistake: Implementing extensive error handling and edge cases (“What if the user enters a negative distance?”) before the main functionality works.

Why it’s bad: You waste time on 20% cases while the 80% core functionality remains incomplete.

Fix: Make the happy path work first. Add validation only for cases you’ll demonstrate. Use simple checks (if/else) rather than custom exception hierarchies.

# Bad - premature error handling
def park_vehicle(self, vehicle):
    if not vehicle:
        raise InvalidVehicleException("Vehicle cannot be None")
    if not isinstance(vehicle, Vehicle):
        raise TypeError("Expected Vehicle instance")
    # ... more validation ...

# Good - simple validation for demo
def park_vehicle(self, vehicle):
    if not vehicle:
        return None
    # Core logic here

5. Not Preparing a Demo Script

Mistake: Finishing code at minute 88 and saying “Let me just run this…” without knowing what to demonstrate.

Why it’s bad: You fumble during demo, forget to show key features, or discover bugs while the interviewer watches.

Fix: In the last 10 minutes, write a clear demo in main.py that shows each feature. Test it once before presenting.

# main.py - Clear demo script
if __name__ == "__main__":
    print("=== Parking Lot Demo ===")
    
    print("\n1. Setup parking lot")
    service = ParkingService()
    service.add_spot(ParkingSpot("C1", VehicleType.CAR))
    print("Added 1 car spot")
    
    print("\n2. Park a car")
    car = Vehicle("ABC123", VehicleType.CAR)
    ticket = service.park_vehicle(car)
    print(f"Ticket issued: {ticket.ticket_id}")
    
    print("\n3. Unpark the car")
    fee = service.unpark_vehicle(ticket.ticket_id)
    print(f"Fee charged: ${fee}")

Interview Tips

Time Management Strategy

Set hard time boundaries: Use your phone/watch to set alarms:

  • 15 min: Design phase must end, start coding
  • 30 min: First runnable code checkpoint
  • 60 min: All core features done, start polish
  • 75 min: Stop adding features, test only

Communicate your timeline: Tell the interviewer, “I’m planning to spend 15 minutes on design, 45 on implementation, and 15 on testing. Does that sound reasonable?” This shows planning skills.

What to Code First

Start with the data model: Classes with attributes and simple constructors. This gives you building blocks.

# Start here (5 minutes)
class Vehicle:
    def __init__(self, license_plate, vehicle_type):
        self.license_plate = license_plate
        self.vehicle_type = vehicle_type

Then add one complete operation: Pick the most important use case and implement it end-to-end. For a parking lot, that’s parking a vehicle.

Finally add remaining features: Once you have one working flow, adding others is faster.

Strategic Shortcuts

Use simple data structures: Don’t build a custom HashMap when Python’s dict works fine. Don’t implement a priority queue when a sorted list suffices for your demo.

Hardcode reasonable values: Instead of complex distance calculations, use distance_km=5 as a parameter. Instead of real-time pricing, use fixed rates.

Skip persistence: In-memory storage is fine. Don’t waste time on database code or file I/O unless explicitly required.

Defer complex algorithms: If the problem needs matching riders to drivers, start with “first available driver” logic. Mention “In production, we’d use location-based matching” but don’t implement it.

Communication During Coding

Think aloud briefly: When starting a new class or method, say “Now I’m implementing the parking logic” but don’t narrate every line.

Ask clarifying questions early: “Should I handle multiple vehicle types or just cars?” “Do you want me to implement payment processing or just calculate the fee?”

Show your priorities: “I’m going to implement parking and unparking first, then add pricing if time permits.”

Acknowledge trade-offs: “I’m using a simple list search here. In production, I’d use a HashMap for O(1) lookup, but for this demo, the list is clearer.”

The Demo Presentation

Walk through your structure first: “I’ve organized the code into models, services, and a demo. Let me show you the main classes…”

Run the happy path: Show the main use case working end-to-end.

Highlight design decisions: “I used the Strategy pattern here for pricing” or “I separated the service layer to keep business logic independent.”

Be honest about limitations: “Given more time, I’d add validation for X and implement Y. But the core functionality is working.”

Language-Specific Tips

Python: Use dataclasses for simple models to save time. Leverage built-in collections (defaultdict, Counter).

from dataclasses import dataclass

@dataclass
class Vehicle:
    license_plate: str
    vehicle_type: str

Java: Use ArrayList and HashMap from collections. Don’t waste time on custom data structures. Use enums for types.

C++: Use STL containers (vector, map). Avoid manual memory management unless necessary. Use smart pointers if you need dynamic allocation.

What Interviewers Actually Evaluate

  1. Does it run? (40% weight) - Working code beats perfect design
  2. Is it organized? (30% weight) - Clear structure, separation of concerns
  3. Is it extensible? (20% weight) - Can new features be added easily?
  4. Is it clean? (10% weight) - Readable names, reasonable methods

Not evaluated heavily: Perfect design patterns, comprehensive error handling, optimal algorithms (unless specified), extensive testing.

Recovery Strategies

If you’re behind at 45 minutes: Cut features. Implement the absolute minimum viable product. Tell the interviewer: “I’m going to focus on getting parking/unparking working, and skip the pricing feature.”

If you have a bug at 80 minutes: Don’t panic. Comment out the broken feature and demo what works. Say: “There’s a bug in the pricing calculation I’d need more time to debug, but let me show you the core parking functionality.”

If you finish early: Don’t add complex features. Instead, refactor for clarity, add comments, or implement simple validation. Ask the interviewer: “I have 15 minutes left. Would you like me to add [feature X] or improve [aspect Y]?”

Key Takeaways

  • Working code beats perfect design: Deliver a runnable solution in 60-90 minutes rather than an incomplete architectural masterpiece. Interviewers can run and test your code, which demonstrates competence more than diagrams.

  • Follow the 15-45-15 rule: Spend 15 minutes clarifying and designing, 45 minutes building core features, and 15 minutes polishing and preparing your demo. Set alarms to enforce these boundaries.

  • Get something running by minute 30: Build incrementally with frequent testing. Your first checkpoint should be a simple but complete operation (e.g., parking one vehicle) that you can demonstrate.

  • Organize code into logical files from the start: Separate models, services, and demo code even in a 60-minute round. This takes minimal extra time but shows professional software engineering habits.

  • Prioritize the happy path and defer edge cases: Make the main use case work perfectly before adding validation, error handling, or complex features. Strategic shortcuts (hardcoded values, simple algorithms) are acceptable when communicated clearly.