Guide complet gratuit

Uber (Ride Hailing)

Concevez Uber (Ride Hailing).

00

Points de contrôle de pratique

Le rythme de l’entretien reste compact, pour que la page consacre son attention aux vraies décisions de conception.

  1. 01
    Clarifier le périmètre
  2. 02
    Besoins + échelle
  3. 03
    API + modèle de données
  4. 04
    Dessiner l’architecture
  5. 05
    Deep dive
  6. 06
    Décision de compromis
01

Les besoins qui façonnent la conception

Ne vous contentez pas d’énoncer les besoins : demandez-les. Chaque carte associe la contrainte de conception à une question de clarification que vous pouvez dire à voix haute avant de dessiner l’architecture.

Besoins fonctionnels

01Que voit le passager en premier — un prix avant de s'engager ?

Les passagers saisissent le point de prise en charge et la destination et obtiennent une estimation de course (prix + ETA) avant de commander la course.

02Que se passe-t-il après avoir tapé « commander » — en combien de temps une mise en relation doit-elle revenir ?

Les passagers demandent une course au tarif estimé et sont mis en relation avec un chauffeur disponible à proximité en une minute environ. Si aucun chauffeur n'est disponible, ils reçoivent un échec clair.

03Que fait le côté chauffeur ?

Les chauffeurs se mettent en ligne, envoient des pings de localisation, et reçoivent une offre de course à la fois à accepter ou refuser. À l'acceptation, ils naviguent vers la prise en charge puis la dépose.

04Un passager peut-il annuler après la mise en relation, et que vit le chauffeur ?

Oui. Après une annulation, le chauffeur redevient immédiatement disponible pour de nouvelles courses, et le système enregistre qui a annulé et quand.

05Le passager suit-il l'approche du chauffeur en direct ?

Oui. La localisation du chauffeur est streamée au passager mis en relation uniquement pendant que la course est active. Tous les autres voient une disponibilité approximative, jamais une trace traçable.

06Aucun chauffeur n'accepte dans la fenêtre de mise en relation — et alors ?

La demande échoue clairement avec des consignes de nouvelle tentative — un non ferme en moins d'une minute vaut mieux qu'un indicateur qui tourne sans jamais aboutir.

Hors périmètreNotes (passager et chauffeur) · Courses programmées et gammes de véhicules (X/XL/Comfort) · Mécanique de tarification dynamique et règlement des paiements

Besoins non fonctionnels

01Un chauffeur peut-il jamais recevoir deux courses à la fois ?

La mise en relation est fortement cohérente : un chauffeur détient au plus une offre ou une course active à la fois — jamais de double affectation.

02À quel point les positions des chauffeurs doivent-elles être fraîches ?

Les chauffeurs envoient un ping toutes les quelques secondes tant qu'ils sont en ligne ; la recherche de proximité peut voir des données vieilles de quelques secondes, jamais de minutes.

03Pour quel débit de pointe de mises à jour de position des chauffeurs devons-nous concevoir ?

Nous concevons pour un plafond de stress délibéré : 10M de chauffeurs en ligne dans le monde, chacun pingeant toutes les ~5 secondes. Cela fait environ 2M d'écritures de localisation par seconde.

04Que se passe-t-il quand un stade se vide ?

Une rafale de ~100K demandes de course venant d'une seule zone est mise en file et s'écoule gracieusement — les zones voisines et les autres villes restent intactes.

05À quelle vitesse chaque étape doit-elle paraître ?

Estimation de course en quelques secondes ; mise en relation (ou un échec clair) en une minute environ de bout en bout.

Continuez à demander — l’entretien est une conversation

Les vrais entretiens sondent bien plus qu’une liste propre. Ces questions de périmètre séparent ceux qui interrogent le problème de ceux qui le récitent.

  • Combien de temps l'historique des courses et les traces de position des chauffeurs doivent-ils rester stockés — et la trace d'un chauffeur doit-elle être supprimable sur demande ?
  • Devons-nous gérer l'usurpation de GPS ou les chauffeurs qui trichent avec la mise en relation, ou la fraude est-elle filtrée ailleurs ?
  • Est-ce une seule ville au lancement ou mondial dès le premier jour — et les données de chaque région doivent-elles rester dans cette région ?
  • Y a-t-il un taux de réussite de mise en relation auquel nous sommes tenus contractuellement, ou un échec clair en moins d'une minute est-il acceptable ?
  • La tarification dynamique et les notes sont-elles hors périmètre ?
02

Les chiffres qui forcent les décisions d’architecture

Traitez chaque estimation comme une pression qui justifie un composant : cache, file, partition, réplica, pool de workers ou chemin de repli.

01

Torrent d'écritures de position

un plafond de charge de 10M de chauffeurs en ligne dans le monde × 1 ping toutes les 5 s10,000,000 ÷ 5 ≈ 2M écritures/s

Aucune base relationnelle n'absorbe cela — les positions vont dans un index géographique en mémoire (compartiments geohash/H3) avec éviction par TTL.

02

Coût d'une recherche de proximité

Le point de prise en charge tombe dans une cellule geohash ; couvrir le rayon de recherche signifie cette cellule plus ses 8 voisines — une grille 3 × 3, 9 cellules9 lectures de cellules × bien moins de 1 ms par lookup en mémoire ≈ quelques millisecondes

Le geohash transforme « qui est près de moi » en une poignée de lectures de clés au lieu d'un balayage de table.

03

Rafale de concert

~100K demandes depuis un quartier sur ~10 minutes100,000 ÷ 600 s ≈ 170 mises en relation/s dans une zone

Partitionner la file de mise en relation par zone géographique — le pic sature les consommateurs d'une zone, pas toute la ville.

04

Budget d'offre

Mise en relation en 60 s ; chaque chauffeur sollicité a ~10 s pour répondre60 s ÷ 10 s ≈ 5-6 chauffeurs essayés avant l'échéance

Le verrou d'offre de 10 secondes limite combien de chauffeurs vous pouvez essayer dans la minute. Alors classez bien les candidats au lieu d'arroser d'offres.

05

Nettoyage des chauffeurs fantômes

Les entrées de position expirent 15-30 s après le dernier ping — soit 3-6 pings manqués à la cadence de 5 s15-30 s ÷ 5 s par ping = 3-6 intervalles silencieux → l'entrée expire ; un chauffeur planté cesse de recevoir des offres en ~30 s au pire

Les chauffeurs qui plantent ou se déconnectent disparaissent de l'index tout seuls — pas de tâche de nettoyage, pas d'offres aux fantômes.

Exemple de décision

Les chiffres

Ce système porte deux charges très différentes. Les chauffeurs streament environ 2M d'écritures de localisation par seconde. Chaque mise en relation n'a besoin que d'une poignée de candidats proches en une minute.

Mon choix

Garder les localisations des chauffeurs dans un index géo en mémoire (buckets geohash/H3) avec un TTL court, si bien que les chauffeurs qui cessent de pinger disparaissent simplement. La mise en relation tire les candidats proches et offre la course à un chauffeur à la fois, en verrouillant ce chauffeur pendant environ 10 secondes. L'acceptation gagne la course ; un timeout ou un refus libère le verrou et le candidat suivant reçoit l'offre. Pendant un pic, les demandes de course attendent dans une file partitionnée par zone, si bien qu'un stade qui se vide ralentit ce quartier, pas toute la ville.

À éviter

Ce que je NE ferais PAS : écrire chaque ping de localisation dans la base principale et la balayer pour trouver les chauffeurs proches. À 2M d'écritures par seconde, ça plus les balayages, ça la tue. Je n'offrirais pas non plus une course à plusieurs chauffeurs à la fois sans verrou, car deux acceptations peuvent arriver ensemble et les deux chauffeurs croient avoir eu la course. Et je ne sharderais pas le système de mise en relation dès le premier jour. Mesurez d'abord le débit par zone ; sharder trop tôt ajoute des modes de défaillance sans ajouter la capacité dont vous avez réellement besoin.

Changer si

Si la qualité de la mise en relation compte plus que la vitesse, comme pour les courses partagées ou le regroupement, je collecterais les demandes pendant quelques secondes et les mettrais en relation par petits lots au lieu d'une à la fois.

03

Chemin d’architecture

D’abord une image complète, puis chaque chemin comme son propre schéma — le chemin d’écriture et le chemin de lecture portent un trafic différent et justifient des composants différents.

Image complète

Vue d’ensemble — chaque composant

Rider / DriverAppsAPI GatewayRide ServiceMatching ServiceGeo Index (enmémoire)Ride DB (état)cycle de vie de la courseNotificationServiceoffre → chauffeurMapping Providertarif + ETA

Les pings des chauffeurs affluent directement dans l'index géographique en mémoire ; la mise en relation y lit les candidats proches et offre les courses un chauffeur à la fois. La vérité de la course vit dans la base — l'index est jetable.

Chemin 1

Chemin de demande — estimer, demander, mettre en relation

Rider AppRide ServiceMatching ServiceGeo Index(chauffeursDriver Offer (10s)

Tarif d'abord, puis demande. La mise en relation tire une poignée de candidats proches et offre à un chauffeur à la fois ; le verrou de 10 secondes empêche la double affectation et passe automatiquement au suivant quand un chauffeur ignore l'offre.

Chemin 2

Chemin de position — le torrent d'écritures

Driver AppAPI GatewayLocation ServiceGeo Index(geohash/H3)TTL Eviction

Environ 2M de pings par seconde atterrissent en mémoire, répartis en cellules geohash/H3 ; les entrées expirent après 15-30 secondes pour que les chauffeurs qui cessent de pinger disparaissent d'eux-mêmes.

04

API et modèle de données

Avant d’optimiser, rendez le contrat inspectable : endpoints, entités, propriété, retries et état.

POST/fare

req{ pickup, destination }

rés200 { fare_id, estimated_fare, eta }

Appelle le fournisseur cartographique pour l'itinéraire + l'ETA ; l'estimation est enregistrée pour que la demande de course puisse la référencer.

POST/rides

req{ fare_id }

rés201 { ride_id, state: requested } · 404 fare expiré

Lance la mise en relation ; le passager reçoit le résultat par push (ou sonde).

POST/drivers/location

req{ lat, lng }

rés200

L'identité du chauffeur vient du jeton de session, jamais du corps de la requête. Écriture à haute fréquence directement dans l'index géographique.

PATCH/rides/{ride_id}

req{ accept | decline }

rés200 ride · 409 offre expirée

Accept bascule l'offre atomiquement ; decline ou un délai de 10 secondes libère le chauffeur et le candidat suivant reçoit l'offre.

Entités principales

Rider

rider_id (PK) · payment_profile

Driver

driver_id (PK) · vehicle · status: offline/available/offered/on_trip

Le champ status est le garde-fou contre la double affectation : seul un chauffeur available peut recevoir une offre, et la bascule est atomique.

Fare

fare_id (PK) · pickup · destination · estimated_fare · eta

Créé au moment de l'estimation ; la demande de course référence fare_id pour que le prix annoncé ne puisse pas changer en silence.

Ride

ride_id (PK) · rider_id · driver_id · fare_id · state: requested/matched/in_progress/completed

DriverLocation

driver_id · lat/lng · updated_at

Vit dans l'index géographique en mémoire (cellules geohash/H3 avec un TTL), pas dans le magasin relationnel — ce sont des données jetables.

05

Directions de deep dive

Choisissez une voie pour le dernier tiers de l’entretien. Chaque voie vous donne le sujet, la question de l’examinateur à laquelle répondre, et le mode d’échec à éviter.

Focus

Le torrent de positions

Question

10M de chauffeurs pingent toutes les 5 secondes. Où vont 2M d'écritures par seconde, et comment répondez-vous à « qui est près de cette prise en charge » ?

Réponse

Les pings vont vers un index géo en mémoire, jamais vers la base relationnelle. Elle ne peut pas encaisser 2 M d'écritures par seconde. Rangez chaque position dans une cellule geohash ou H3 avec un TTL court. Pour trouver qui est près d'un point de prise en charge, lisez cette cellule plus ses 8 voisines — neuf lookups mémoire en quelques millisecondes à un chiffre, pas un scan de table.

À éviter

Écrire les pings dans la base principale et la balayer pour la proximité — elle meurt à ce débit.

Focus

Ne jamais affecter un chauffeur deux fois

Question

Deux demandes de course veulent le même chauffeur proche au même instant. Comment exactement un seul l'emporte ?

Réponse

Saisissez le chauffeur avec un court verrou exclusif. C'est un compare-and-set atomique, donc exactement une requête gagne et le perdant passe à son candidat suivant. La base détient le vrai état de la course : accepter fait passer le chauffeur en course, et une annulation le relâche vers disponible pour qu'aucune réservation périmée ne traîne.

À éviter

Offrir à plusieurs chauffeurs à la fois sans verrou — deux acceptations croient toutes deux avoir gagné.

Focus

Le chauffeur ne répond pas

Question

Le chauffeur sollicité ignore la demande. Que se passe-t-il à la 10e seconde, et comment la course se met-elle quand même en relation en moins d'une minute ?

Réponse

L'offre est un verrou de 10 secondes, pas une attente bloquante. À la seconde 10, elle expire d'elle-même et l'appariement passe au chauffeur suivant dans le classement. À environ 10 secondes chacun, 5-6 chauffeurs tiennent dans le budget de 60 secondes. C'est pourquoi on classe les candidats avec soin au lieu d'arroser d'offres partout.

À éviter

Bloquer la course sur un seul chauffeur qui ne répond pas au lieu d'un TTL de verrou qui passe au suivant.

Focus

Un stade se vide

Question

100K personnes demandent des courses depuis un quartier en quelques minutes. Comment gardez-vous le reste de la ville intact ?

Réponse

Partitionnez la file d'appariement par zone géo. 100 K requêtes sur 10 minutes, ça ne fait qu'environ 170 appariements par seconde. Ça sature les consommateurs de cette seule zone pendant que toutes les autres se vident normalement. La zone chaude voit une file honnête — une attente plus longue ou un échec net. Le reste de la ville tourne bien.

À éviter

Une seule file de mise en relation globale — un pic local devient une panne à l'échelle de la ville.

Focus

Chauffeurs fantômes

Question

Une appli chauffeur plante alors qu'elle est marquée available. Combien de temps peuvent-ils encore recevoir des offres, et qu'est-ce qui les nettoie ?

Réponse

Chaque entrée de position expire 15-30 secondes après le dernier ping. À la cadence de 5 secondes, ça ne fait que 3-6 pings manqués, donc un chauffeur planté disparaît de l'index tout seul. Aucune tâche de nettoyage n'est nécessaire. Le plus longtemps qu'un fantôme peut continuer à recevoir des offres, c'est environ 30 secondes.

À éviter

Aucun TTL sur les entrées de position — les offres continuent d'aller à des chauffeurs partis il y a une heure.

Prêt à vous entraîner ?

Expliquez Uber (Ride Hailing) à voix haute et obtenez une évaluation IA de votre explication.

S’entraîner avec l’IA →