Core Entities
Vehicle: vehicle_id, license_plate, type (SEDAN, VAN, TRUCK), capacity_kg, fuel_type, status (AVAILABLE, ON_TRIP, MAINTENANCE, OFFLINE), current_location (lat, lng), odometer_km, last_service_date. Driver: driver_id, name, license_number, phone, status (AVAILABLE, ON_TRIP, OFFLINE), current_vehicle_id, rating, total_trips. Trip: trip_id, vehicle_id, driver_id, origin, destination, status (SCHEDULED, IN_PROGRESS, COMPLETED, CANCELLED), scheduled_at, started_at, completed_at, distance_km, cargo_weight_kg. GPSEvent: event_id, vehicle_id, timestamp, lat, lng, speed_kmh, heading. MaintenanceRecord: record_id, vehicle_id, type, description, cost, performed_at, next_service_at.
Real-Time Vehicle Tracking
GPS devices in vehicles send location events every 5-30 seconds. Ingestion: events stream via MQTT (lightweight IoT protocol) or WebSocket to an ingestion service. The ingestion service publishes to Kafka (partitioned by vehicle_id for ordering). A stream processor consumes and: (1) updates the vehicle’s current location in Redis (HSET vehicle:{id} lat {lat} lng {lng} timestamp {ts} speed {speed}). (2) Appends to the GPS time-series database (InfluxDB or TimescaleDB) for trip history and analytics. The operations dashboard reads current locations from Redis for real-time display — fast O(1) reads. Historical trip replay reads from the time-series DB. Redis expiry: if a vehicle sends no update for 5 minutes, mark it OFFLINE.
Driver and Vehicle Assignment
When a trip is requested: find the best available vehicle and driver. Vehicle matching criteria: type matches cargo requirements, weight capacity >= cargo_weight, fuel level sufficient for the trip distance. Driver matching: AVAILABLE status, assigned to a vehicle of the right type, highest rating, lowest current trip count (for load balancing). Geospatial matching: among candidates, prioritize the closest vehicle to the pickup location. Use a geospatial index (PostGIS or Redis GEOSEARCH) to find vehicles within a radius. GEOSEARCH fleet_vehicles FROMLONLAT {lng} {lat} BYRADIUS 20 km ASC COUNT 10 gives the 10 nearest vehicles sorted by distance. Score candidates by: proximity weight * (1/distance) + rating weight * rating + availability weight * (1 if AVAILABLE else 0).
Route Optimization
Single trip routing: use a routing engine (OSRM, Valhalla) with the road network graph. Input: origin + destination + vehicle type (trucks have height/weight restrictions). Output: optimal route with turn-by-turn directions, estimated distance and duration. Multi-stop optimization (vehicle routing problem, VRP): assign N deliveries to M vehicles to minimize total distance. This is NP-hard. Practical approach: nearest-neighbor heuristic for initial assignment, then 2-opt local search improvement. For real-time re-routing: monitor traffic data; if a delay is detected on the current route, re-calculate and push updated directions to the driver’s device via WebSocket.
Maintenance Scheduling
Proactive maintenance based on: odometer (every 10,000 km), time (every 6 months), engine hours, or fault codes from the vehicle’s OBD-II interface. On each GPS event update, check if odometer_km >= last_service_km + 10000. If yes: create a MaintenanceRecord with status=SCHEDULED, notify the fleet manager, and set vehicle status=MAINTENANCE_DUE. A vehicle on MAINTENANCE_DUE can still run trips but is flagged. When maintenance is completed: update performed_at, cost, next_service_at, reset the odometer threshold, set status=AVAILABLE. Predictive maintenance: stream engine telemetry (temperature, RPM, fault codes) to an ML model that predicts component failures before they occur.
Analytics and Reporting
Key metrics: fleet utilization (% of time vehicles are on trips vs idle), average trip duration and distance by vehicle type, fuel efficiency (km/liter) by vehicle, driver performance (on-time rate, safety score from speed/braking telemetry), maintenance cost per vehicle. Aggregate GPS speed data to detect harsh braking (speed drops > 20 km/h in 1 second) and speeding (speed > road limit). Score drivers on safety daily. Reports: daily fleet summary emailed to fleet managers, monthly cost-per-km by vehicle for financial planning, anomaly alerts (vehicle exceeds geofence, driver inactive for > 30 minutes during a trip).
{
“@context”: “https://schema.org”,
“@type”: “FAQPage”,
“mainEntity”: [
{
“@type”: “Question”,
“name”: “How do you efficiently query the nearest available vehicle to a pickup location?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Store active vehicle locations in Redis using geospatial commands. On each GPS update: GEOADD fleet_vehicles {lng} {lat} vehicle:{id}. When a trip is requested: GEOSEARCH fleet_vehicles FROMLONLAT {pickup_lng} {pickup_lat} BYRADIUS 20 km ASC COUNT 20 returns the 20 nearest vehicles sorted by distance in O(N+log M) where M is total vehicles. Filter by vehicle status (AVAILABLE) and vehicle type in the application layer. For scaling: partition by city or region into separate Redis keys (fleet_vehicles:nyc, fleet_vehicles:sf) to keep each key manageable. Update vehicle location in Redis on every GPS event (every 5-30 seconds). Expire vehicle entries if no update received for 5 minutes — vehicle is offline.”
}
},
{
“@type”: “Question”,
“name”: “How do you handle GPS data loss and vehicle tracking gaps?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “GPS signals can be lost in tunnels, parking garages, or dead zones. Strategies: (1) Dead reckoning: use the last known speed and heading to estimate position during gaps. Store speed and heading in the Redis vehicle hash. (2) Stale location detection: if the last GPS event is older than 2 minutes, mark the vehicle’s displayed location as approximate. The UI shows a grayed-out icon. (3) On reconnect: when GPS resumes, the device sends a burst of buffered events (if it has local storage). The stream processor ingests them in order (use event timestamp, not arrival timestamp). (4) Trip distance correction: if GPS was lost for part of a trip, use odometer delta (from OBD-II) to estimate the distance driven during the gap.”
}
},
{
“@type”: “Question”,
“name”: “How do you implement geofencing alerts for a fleet?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “A geofence is a polygon or circle defining an allowed or restricted area. Store geofences in PostGIS: table with (geofence_id, fleet_id, name, type ALLOWED/RESTRICTED, geometry POLYGON). On each GPS event, check if the vehicle is inside its assigned geofences: SELECT geofence_id FROM geofences WHERE ST_Contains(geometry, ST_Point({lng}, {lat})). If a vehicle exits an ALLOWED zone or enters a RESTRICTED zone: publish a GeofenceViolation event, notify the fleet manager via push/email, log the violation. Performance: spatial index (GIST) on geometry makes the ST_Contains query fast even with thousands of geofences. For higher throughput: cache geofence geometries for each vehicle in memory and run the containment check in the application layer using a fast geometry library (Shapely, S2).”
}
},
{
“@type”: “Question”,
“name”: “How does the driver assignment algorithm handle multiple simultaneous trip requests?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “Naive approach: process requests serially — first request gets the best available driver, second gets the next best. Problem: two requests arriving within milliseconds both see the same driver as available and both assign them. Solution: use optimistic locking. When assigning driver D to trip T: UPDATE drivers SET status=ON_TRIP, current_trip_id=T WHERE driver_id=D AND status=AVAILABLE. If rows_affected == 0: driver was assigned concurrently, retry with the next candidate. This is a single atomic compare-and-swap using the database. For high-concurrency dispatch (100s of requests/sec): use Redis SETNX as a distributed lock per driver: SET driver:{id}:lock trip:{id} NX EX 5. Only the first request succeeds; others try the next available driver. Release the lock after the database assignment commits.”
}
},
{
“@type”: “Question”,
“name”: “How do you calculate and store trip routes efficiently?”,
“acceptedAnswer”: {
“@type”: “Answer”,
“text”: “On trip creation: call a routing engine (OSRM self-hosted, Google Directions API, Valhalla) with origin and destination. Store the result: route_polyline (encoded Google polyline, ~1KB for a typical urban route), estimated_distance_km, estimated_duration_min, turn_by_turn_directions (JSON array). Push the route to the driver’s device via WebSocket. Re-routing triggers: if the driver deviates significantly from the route (> 200m off route for > 30 seconds), request a new route from the current GPS position. For efficiency: run all routing requests through a queue, not inline in the trip creation API. Routing takes 100-500ms; the trip can be created and confirmed before the route is ready. Cache routes for common origin-destination pairs (e.g., airport to hotel district).”
}
}
]
}
Asked at: Uber Interview Guide
Asked at: Lyft Interview Guide
Asked at: DoorDash Interview Guide
Asked at: Airbnb Interview Guide