A thread-safe, production-ready P2P delivery system similar to Dunzo, built for Flipkart's SDE-3 Machine Coding Round.
- ✅ Onboarding: Add customers and drivers to the system
- ✅ Preconfigured Items: Fixed catalog of deliverable items
- ✅ Order Management: Create and cancel orders
- ✅ Driver Assignment: Auto-assign orders to available drivers using FIFO queue
- ✅ Order Lifecycle: Drivers can pickup and deliver orders
- ✅ Status Tracking: View order, driver, and system status
- ✅ Cancellation Rules: Orders cannot be cancelled after pickup
- ✅ Multiple Orders: Customers can place multiple orders simultaneously
- ✅ Thread Safety: Complete concurrency handling
- ✅ Notification System: Email and SMS notifications (mock vendors)
- ✅ Rating System: Customers can rate drivers after delivery
- ✅ Driver Dashboard: Top drivers by deliveries, ratings, and combined score
- ✅ Auto-Cancel: Orders auto-cancel if not picked up within configurable timeout
Class: DeliverySystem
Reasoning: Provides a simplified, unified interface to the complex subsystems (assignment, notification, rating, dashboard). This makes the system easy to use and hides internal complexity from clients.
Benefits:
- Single entry point for all operations
- Loose coupling between client code and subsystems
- Easier to test and maintain
Classes: DashboardService, RankingStrategy and implementations
Reasoning: Allows different ranking algorithms (by deliveries, ratings, combined score) to be selected at runtime without changing the dashboard service code.
Benefits:
- Easy to add new ranking strategies
- Follows Open/Closed Principle
- Runtime flexibility
Class: CompositeNotificationService
Reasoning: Allows sending notifications through multiple channels (Email, SMS) simultaneously. Treats individual notification services and composite uniformly.
Benefits:
- Easy to add new notification channels
- Uniform interface for single and multiple notifications
- Flexible notification routing
Class: OrderAssignmentService with BlockingQueue
Reasoning: Pending orders (producers) are queued and consumed by available drivers. This decouples order creation from assignment and handles the scenario where demand exceeds driver availability.
Benefits:
- Thread-safe order queuing
- Natural FIFO ordering
- Efficient resource utilization
Services: OrderAssignmentService, RatingService, DashboardService
Reasoning: Each service is instantiated once in DeliverySystem and manages its domain, ensuring centralized state management.
Benefits:
- Single source of truth
- Centralized business logic
- Easier testing with dependency injection
-
ConcurrentHashMap: For all data stores (customers, drivers, items, orders)
- Thread-safe without external synchronization
- Better performance than synchronized HashMap
-
AtomicReference: For mutable fields in Order and Driver
- Lock-free atomic operations
- Ensures visibility across threads
-
ReentrantLock: In OrderAssignmentService
- Ensures atomic assignment operations
- Prevents race conditions during driver-order assignment
-
ReentrantReadWriteLock: For driver list operations
- Multiple readers can access simultaneously
- Exclusive write access
- Better performance for read-heavy operations
-
Synchronized Methods: In Driver and Order classes
- Ensures atomic state transitions
- Prevents concurrent modification issues
-
BlockingQueue: For pending orders
- Thread-safe producer-consumer pattern
- Built-in synchronization
- Order Assignment: Lock prevents race condition where multiple drivers try to take same order
- Driver Status Change: Synchronized to prevent inconsistent state
- Order State Transitions: Synchronized to ensure valid state machine progression
- Rating Calculation: Synchronized to prevent race conditions in average calculation
com.flipkart.delivery
├── model/
│ ├── Customer.java (Immutable)
│ ├── Driver.java (Thread-safe)
│ ├── Item.java (Immutable)
│ ├── Order.java (Thread-safe)
│ ├── OrderStatus.java
│ └── DriverStatus.java
├── service/
│ ├── OrderAssignmentService.java (FIFO queue + thread safety)
│ ├── RatingService.java (Thread-safe rating management)
│ ├── DashboardService.java (Strategy pattern for ranking)
│ ├── OrderTimeoutService.java (Scheduled auto-cancellation)
│ └── notification/
│ ├── NotificationService.java (Interface)
│ ├── EmailNotificationService.java
│ ├── SmsNotificationService.java
│ └── CompositeNotificationService.java
├── exception/
│ ├── DeliveryException.java
│ ├── InvalidOperationException.java
│ └── ResourceNotFoundException.java
├── DeliverySystem.java (Facade)
└── Main.java (Demo/Driver)
- Java 11 or higher
- Maven 3.6+
mvn clean compilemvn testmvn exec:java -Dexec.mainClass="com.flipkart.delivery.Main"Or compile and run:
mvn clean package
java -cp target/p2p-delivery-system-1.0-SNAPSHOT.jar com.flipkart.delivery.Main- OrderTest: Order lifecycle and state transitions
- DriverTest: Driver state management and rating
- DeliverySystemTest: Integration tests for all operations
- OrderAssignmentServiceTest: Assignment logic and queue management
- RatingServiceTest: Rating validation and duplicate prevention
- DashboardServiceTest: Ranking strategies
- ✅ Basic CRUD operations
- ✅ Auto-assignment with FIFO
- ✅ Order cancellation rules
- ✅ Driver availability management
- ✅ Concurrent order creation
- ✅ Rating system with validation
- ✅ Dashboard ranking strategies
- ✅ Edge cases and error handling
# Run all tests
mvn test
# Run specific test class
mvn test -Dtest=DeliverySystemTest
# Run with coverage (if jacoco configured)
mvn clean test jacoco:report- Driver Availability: Drivers are available 24x7 and don't go offline
- Travel Time: Ignored as per requirements
- Item Catalog: Fixed list of 7 predefined items; new items cannot be added at runtime
- Same Item Orders: Multiple customers can order the same item simultaneously
- Order Priority: FIFO (First-In-First-Out) for pending orders
- Auto-Assignment: Orders are immediately assigned if drivers available, otherwise queued
- Timeout: Default 30 minutes (configurable), but 5 seconds used in demo for visibility
-
In-Memory Storage: All data stored in memory using concurrent data structures
- Reasoning: Fast access, simple implementation, suitable for machine coding round
- Trade-off: Data lost on restart, but avoids database complexity
-
No Authentication: System assumes valid user IDs are provided
- Reasoning: Focus on core business logic rather than auth complexity
-
Notification Delivery: Mock services that only log (don't actually send)
- Reasoning: Demonstrates design without external dependencies
-
Single System Instance: No distributed systems or replication
- Reasoning: Appropriate scope for machine coding round
-
Order ID Generation: Uses UUID for uniqueness
- Reasoning: Simple, thread-safe, no need for distributed ID generation
-
Error Handling: Runtime exceptions for invalid operations
- Reasoning: Fail-fast approach, clear error messages
-
Synchronous Operations: All operations are synchronous
- Reasoning: Simpler to reason about, easier testing
- No Payment System: Orders don't involve actual payment
- No Location/GPS: No real-world coordinates or routing
- No Order Modifications: Orders cannot be modified after creation
- No Partial Cancellations: Cancel entire order only
- No Driver Rejection: Drivers cannot reject assigned orders
- No Order History Archive: All orders remain in memory
DeliverySystem system = new DeliverySystem();
// Onboard customers
Customer customer = system.onboardCustomer("C001", "Alice Johnson");
// Onboard drivers
Driver driver = system.onboardDriver("D001", "Bob Driver");// Create order (auto-assigns to available driver or queues)
Order order = system.createOrder("C001", "ITEM001");
// Cancel order (only before pickup)
system.cancelOrder(order.getId());
// Driver pickup
system.pickupOrder("D001", order.getId());
// Complete delivery
system.completeOrder("D001", order.getId());// Order status
String orderStatus = system.getOrderStatus(order.getId());
// Driver status
String driverStatus = system.getDriverStatus("D001");
// System overview
String systemStatus = system.getSystemStatus();// Rate driver after delivery
system.rateDriver(order.getId(), 4.5);
// Show driver dashboard
system.showDriverDashboard(5); // Top 5 drivers
// Get available items
List<Item> items = system.getAvailableItems();Orders are added to a LinkedBlockingQueue when no driver is available. When a driver becomes free (after completing an order), the system automatically assigns the oldest pending order.
All critical state changes (order status, driver status) use synchronized methods or atomic operations to ensure consistency in concurrent scenarios.
Uses ScheduledExecutorService to schedule cancellation tasks when orders are created. Tasks are cancelled if order is picked up before timeout.
Composite pattern allows notifications to be sent via multiple channels. Easy to add new channels (Push, WhatsApp, etc.) by implementing NotificationService interface.
Strategy pattern allows dynamic switching between ranking algorithms for driver dashboard without code modification.
- ConcurrentHashMap: O(1) average case for lookups
- BlockingQueue: O(1) for enqueue/dequeue operations
- Lock Contention: Minimized by using read-write locks where appropriate
- Memory: All data in-memory for fast access
- Scalability: Can handle thousands of concurrent orders with proper tuning
- Persistent Storage: Add database layer with repositories
- Distributed System: Use message queues (Kafka) for order assignment
- Location-Based Assignment: Assign nearest driver instead of FIFO
- Priority Orders: Add order priority/express delivery
- Driver Zones: Assign drivers based on geographic zones
- Analytics Dashboard: Real-time metrics and reporting
- Admin Console: Manage system configuration and monitoring
Author: Flipkart SDE-3 Candidate
Date: October 2025
Time Complexity: Core operations are O(1) or O(log n)
Space Complexity: O(n) where n is total entities (orders + drivers + customers)