Bird
Raised Fist0

Food Ordering System

LLDmediumInterview freq: high
Choose your preparation mode4 modes available
🏗️
Food Ordering System
Design a scalable and extensible food ordering system with menu, cart, order, kitchen queue, and delivery management.
mediumFinancial and E-Commerce OOPFreq: high
Prerequisites:OOP FundamentalsJava Concurrency BasicsDesign Patterns (Factory, Observer, Strategy)SOLID Principles
⚙️
Functional Requirements
  • Menu supports multiple food items with categories and prices
  • Cart allows adding, removing, and updating quantities of menu items
  • Order creation validates cart contents and calculates total price
  • Kitchen queue manages order preparation status (e.g., Pending, Preparing, Ready)
  • Delivery module tracks order delivery status and assigns delivery personnel
  • Support concurrent order placements without data corruption
  • Pricing strategy supports discounts and taxes extensibly
👤
Use Cases
  • Customer browses menu and adds items to cart
  • Customer places an order from the cart
  • Kitchen staff views and updates order status in kitchen queue
  • Delivery personnel picks up and delivers orders
  • System administrator manages menu items and pricing
🧑‍💻
Actors
  • Customer
  • Kitchen Staff
  • Delivery Personnel
  • System Administrator
❓
Clarifying Questions to Ask
  • How many concurrent order placements are expected? How many threads/gates handle order creation?
  • Is pricing fixed per item or dynamic with discounts and taxes? Should pricing be extensible?
  • What happens if kitchen queue is full or delayed? Is there a retry or cancellation policy?
  • Can multiple delivery personnel be assigned to one order or partial deliveries?
  • Are menu updates frequent and do they affect ongoing orders?
  • Should the system support order cancellation or modification after placement?
Out of Scope
✗ Payment gateway integration
✗ User authentication and authorization
✗ Real-time notifications and UI design
✗ Inventory management for ingredients
⚡
QPS Calculation
write qps100
read qps500
peak concurrent orders50
🖥️
Server Estimate
application servers5
database servers3
cache servers2
🔢
Enumerations
enum OrderStatus
PENDING | PREPARING | READY | DELIVERING | DELIVERED | CANCELLED
Defines finite states of an order lifecycle. Enum prevents typo bugs and enables exhaustive switch-case handling in Java.
enum PaymentStatus
UNPAID | PAID | FAILED | REFUNDED
Tracks payment state for orders. Using enum ensures type safety and clear state transitions.
enum DeliveryStatus
NOT_ASSIGNED | ASSIGNED | IN_TRANSIT | DELIVERED | FAILED
Represents delivery progress. Enum usage enforces valid states and simplifies concurrency control.
enum MenuCategory
APPETIZER | MAIN_COURSE | DESSERT | BEVERAGE
Categorizes menu items for filtering and display. Enum avoids string-based errors and supports switch logic.
📦
MenuItem
4 fields
private final String idprivate String nameprivate MenuCategory categoryprivate double price
Represents a single food item with immutable id, mutable name, category, and price. Provides accessors and price calculation.
public synchronized double getPrice()Returns the current price of the menu item. Synchronized to ensure visibility if price changes.
public synchronized void setPrice(double price)Updates the price of the menu item atomically to prevent race conditions.
📦
CartItem
2 fields
private final MenuItem menuItemprivate volatile int quantity
Represents an item in the cart with a reference to MenuItem and quantity. Quantity is volatile to ensure visibility across threads.
public synchronized void incrementQuantity(int amount)Atomically increases the quantity by the specified amount.
public synchronized void decrementQuantity(int amount)Atomically decreases the quantity by the specified amount, ensuring it does not go below zero.
public int getQuantity()Returns the current quantity with volatile read guarantees.
📦
Cart
1 fields
private final Map<String, CartItem> items = new HashMap<>()
Manages a collection of CartItems. Supports adding, removing, updating quantities, and calculating total price.
public synchronized void addItem(MenuItem item, int quantity)Adds a MenuItem to the cart or increments quantity if already present. Synchronized to prevent concurrent modification.
public synchronized void removeItem(String menuItemId)Removes the CartItem by menu item ID atomically.
public synchronized double getTotalPrice()Calculates total price of all items in the cart atomically to ensure consistency.
📦
Order
6 fields
private final String orderIdprivate final List<CartItem> orderItemsprivate volatile OrderStatus statusprivate volatile PaymentStatus paymentStatusprivate volatile DeliveryStatus deliveryStatusprivate final double totalPrice
Represents a placed order with immutable orderId, items snapshot, and volatile statuses for concurrency visibility.
public synchronized void updateStatus(OrderStatus newStatus)Atomically updates the order status to prevent race conditions.
public synchronized void updatePaymentStatus(PaymentStatus newStatus)Atomically updates payment status.
public synchronized void updateDeliveryStatus(DeliveryStatus newStatus)Atomically updates delivery status.
public double getTotalPrice()Returns the total price of the order.
📦
KitchenQueue
2 fields
private final Queue<Order> orderQueue = new LinkedList<>()private final int capacity
Manages the queue of orders to be prepared. Controls capacity and thread-safe enqueue/dequeue operations.
public synchronized boolean enqueueOrder(Order order)Adds an order to the queue if capacity allows. Returns false if full.
public synchronized Order dequeueOrder()Removes and returns the next order to prepare, or null if empty.
public synchronized boolean isFull()Checks if the queue has reached its capacity.
🗄️
Orders
PK: orderId
orderId STRINGcustomerId STRINGorderItems LIST<STRING>totalPrice DOUBLEstatus STRINGpaymentStatus STRINGdeliveryStatus STRINGcreatedAt TIMESTAMP
🗄️
MenuItems
PK: category
id STRINGname STRINGcategory STRINGprice DOUBLEavailable BOOLEAN
🔌
POST /cart/add
Request
{
  "customerId": "string",
  "menuItemId": "string",
  "quantity": "int"
}
Response
{
  "success": "boolean",
  "message": "string"
}
Adds specified quantity of menu item to customer's cart.
🔌
POST /order/place
Request
{
  "customerId": "string",
  "cartId": "string"
}
Response
{
  "orderId": "string",
  "status": "string",
  "totalPrice": "double"
}
Places an order from the customer's cart after validation.
🔌
GET /kitchen/orders
Request
{
  "staffId": "string"
}
Response
{
  "orders": "List<Order>"
}
Retrieves orders pending preparation for kitchen staff.

Practice

(1/5)
1. Given a Vehicle abstraction that requires both state (e.g., speed) and behavior (e.g., move()), should Vehicle be an abstract class or an interface? Why?
easy
A. Abstract class, because it can hold shared state and provide default behavior implementations.
B. Interface, because it allows multiple inheritance and defines behavior without state.
C. Interface, because Java interfaces can now hold state with default methods.
D. Abstract class, because interfaces cannot define any methods.

Solution

  1. Step 1: Analyze state and behavior requirements

    Vehicle needs to hold state like speed and provide behavior like move(), which requires shared fields and method implementations.
  2. Step 2: Evaluate abstract class vs interface

    Abstract classes can hold instance variables and provide default method implementations; interfaces cannot hold instance state (only constants) despite default methods.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    State + behavior -> abstract class, not interface [check]
Hint: State needs abstract class; interfaces lack instance variables [check]
Common Mistakes:
2. A class has a private constructor and a static synchronized getInstance() method returning the single instance. Which pattern is applied and why is this the CORRECT use case?
easy
A. Singleton pattern, because it ensures only one instance exists and controls concurrent access.
B. Factory Method pattern, because it controls object creation with a static method.
C. Builder pattern, because it constructs complex objects step-by-step.
D. Prototype pattern, because it clones existing instances to avoid new construction.

Solution

  1. Step 1: Identify Singleton pattern characteristics

    The private constructor prevents external instantiation, and the static synchronized getInstance() method ensures a single instance with thread-safe lazy initialization.
  2. Step 2: Eliminate other creational patterns

    Factory Method controls subclass instantiation, Builder separates construction from representation, and Prototype clones objects; none enforce single instance or thread safety.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Private constructor + synchronized static getInstance() -> Singleton pattern [check]
Hint: Private constructor + synchronized getInstance() -> Singleton [check]
Common Mistakes:
3. In a multi-threaded parking system using the Decorator pattern, the parkVehicle() method checks if a spot is available and then marks it occupied. Without synchronization, which exact thread interleaving causes double-booking?
medium
A. Thread 1 checks spot available -> true, context switch; Thread 2 checks spot available -> true; both mark spot occupied concurrently.
B. Thread 1 marks spot occupied, Thread 2 waits and then parks safely.
C. Thread 1 parks vehicle, Thread 2 reads spot status after parking completes.
D. Thread 1 and Thread 2 both wait on a lock, preventing double-booking.

Solution

  1. Step 1: Identify the check-then-act race condition

    Without synchronization, Thread 1 reads spot as available (true) but before marking it occupied, context switches.
  2. Step 2: Trace Thread 2's actions

    Thread 2 also reads spot as available (true) and proceeds to mark it occupied. Both threads think the spot is free and park vehicles, causing double-booking.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Check-then-act without sync allows both threads to park simultaneously [check]
Hint: Check-then-act gap causes double-booking without sync [check]
Common Mistakes:
4. In the Library Management System, the reserveBook() method is not synchronized. Which exact sequence of Thread 1 and Thread 2 calls causes double reservation of the same book copy?
medium
A. Thread 1 checks availability -> true, context switch; Thread 2 checks availability -> true; both reserve simultaneously.
B. Thread 1 reserves, then Thread 2 checks availability -> false and aborts.
C. Thread 1 calls reserveBook(), Thread 2 waits until Thread 1 finishes, then reserves.
D. Thread 1 and Thread 2 both wait on a lock, so no double reservation occurs.

Solution

  1. Step 1: Identify the check-then-act race condition

    Without synchronization, both threads can read availability as true before either updates the reservation status.
  2. Step 2: Trace thread interleaving causing double booking

    Thread 1 reads available=true, context switch; Thread 2 reads available=true; both proceed to reserve, causing double booking.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Unsynchronized check-then-act -> both see available=true -> double reservation [check]
Hint: Check availability -> context switch -> both reserve -> double booking [check]
Common Mistakes:
5. In a parking lot system, if parkVehicle() is not synchronized, which exact thread interleaving causes double-booking of the same spot?
medium
A. Thread 1 checks spot availability -> true, context switch; Thread 2 checks availability -> true; both park simultaneously.
B. Thread 1 parks vehicle, Thread 2 parks vehicle after Thread 1 finishes.
C. Thread 1 parks vehicle, Thread 2 waits for lock release before parking.
D. Thread 1 releases spot, Thread 2 immediately occupies it without checking.

Solution

  1. Step 1: Identify the check-then-act race condition

    Without synchronization, Thread 1 reads spot as available but before marking it occupied, context switches to Thread 2 which also reads available.
  2. Step 2: Both threads proceed to park, causing double-booking

    Both threads believe the spot is free and park simultaneously, violating mutual exclusion.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Check-then-act gap without synchronization -> double-booking [check]
Hint: Check availability -> context switch -> both park -> double-booking [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