1. Comment concevoir un systeme de raccourcissement d'URL (type bit.ly) ?
Requirements : generer des URL courtes, rediriger rapidement, analytics optionnels. Base de donnees : table avec colonnes (short_code, original_url, created_at, click_count). Le short_code est genere en encodant un ID auto-increment en base62 (a-zA-Z0-9), donnant des codes courts (7 caracteres = 3.5 trillions de combinaisons). Architecture : API REST (POST pour creer, GET pour rediriger avec 301/302). Cache Redis pour les URL les plus accedees (pattern read-through). Load balancer devant plusieurs serveurs applicatifs. Base de donnees : sharding par hash du short_code pour la scalabilite. Considerations : expiration des URLs, detection de spam, rate limiting, analytics avec des compteurs asynchrones (Kafka + batch processing).
2. Expliquez les concepts de scalabilite horizontale vs verticale.
Scalabilite verticale (scale up) : augmenter les ressources d'une machine (CPU, RAM, stockage). Simple mais limitee par le hardware maximal, single point of failure, downtime pour upgrade. Scalabilite horizontale (scale out) : ajouter des machines. Plus complexe mais theoriquement illimitee, resiliente, zero-downtime. Pour scaler horizontalement : application stateless (session externalisee dans Redis), load balancer pour distribuer le trafic, base de donnees replication/sharding. Les applications modernes privilegient le scale out. Pattern : microservices independamment scalables, conteneurs orchestres par Kubernetes, auto-scaling base sur les metriques. Le scaling horizontal necessite de gerer la coherence des donnees distribuees.
3. Comment concevoir un systeme de chat en temps reel ?
Protocole : WebSocket pour la communication bidirectionnelle persistante. Fallback : Server-Sent Events ou long polling. Architecture : serveurs WebSocket derriere un load balancer avec session sticky. Quand un utilisateur envoie un message, le serveur identifie le destinataire et route vers le bon serveur WebSocket. Message broker (Redis Pub/Sub ou Kafka) pour la communication inter-serveurs. Stockage : messages dans Cassandra ou DynamoDB (write-heavy, partitionne par conversation). Presence : heartbeats WebSocket + Redis pour le statut en ligne. Notifications push pour les utilisateurs offline. Scalabilite : sharding des conversations, groupes limites en taille, messages anciens archives dans un stockage froid.
4. Qu'est-ce que le CAP theorem et ses implications pratiques ?
Le theoreme CAP (Brewer) stipule qu'un systeme distribue ne peut garantir simultanement que deux des trois proprietes : Consistency (tous les noeuds voient la meme donnee au meme moment), Availability (chaque requete recoit une reponse), Partition tolerance (le systeme fonctionne malgre des pertes de communication reseau). Les partitions reseau sont inevitables, donc le choix reel est entre CP (consistance + partition tolerance, ex: ZooKeeper, HBase) et AP (disponibilite + partition tolerance, ex: DynamoDB, Cassandra). En pratique, PACELC affine : en cas de Partition choisir A ou C, sinon choisir Latency ou Consistency. La plupart des systemes modernes offrent une eventual consistency tunable.
5. Comment concevoir un systeme de notification (push, email, SMS) ?
Architecture event-driven : les services emettent des evenements (commande validee, message recu) dans une file de messages (Kafka/SQS). Un service de notification consomme les evenements et orchestre l'envoi. Template engine pour les contenus (titre, body, variables). Routage : le service determine le canal (push, email, SMS) selon les preferences utilisateur et le type de notification. Files separees par canal et priorite (urgente vs marketing). Rate limiting pour eviter le spam. Idempotence : deduplication par event_id pour eviter les doublons. Tracking : enregistrer les envois, deliveries, opens, clicks. Retry avec backoff exponentiel pour les echecs. Stocker les preferences et l'historique dans une base dediee.
6. Expliquez les patterns de communication inter-services (synchrone vs asynchrone).
Synchrone (requete-reponse) : REST ou gRPC. Simple, resultat immediat, mais couplage fort et risque de cascade de pannes. Asynchrone (messaging) : message queues (RabbitMQ, SQS) pour le point-to-point, event streaming (Kafka) pour le publish-subscribe. Decouplage, resilience, mais complexite accrue et eventual consistency. Patterns : Saga pour les transactions distribuees (choreography ou orchestration), CQRS pour separer lectures et ecritures, Event Sourcing pour stocker les evenements plutot que l'etat. Circuit Breaker (Hystrix, Resilience4j) pour isoler les pannes. En pratique, combiner les deux : synchrone pour les requetes utilisateur necessitant une reponse immediate, asynchrone pour les traitements en arriere-plan.
7. Comment concevoir un systeme de cache distribue ?
Strategies de caching : Cache-aside (l'application gere le cache explicitement), Read-through (le cache charge depuis la source automatiquement), Write-through (ecriture synchrone cache + source), Write-behind (ecriture asynchrone vers la source). Eviction : LRU (Least Recently Used), LFU (Least Frequently Used), TTL (Time To Live). Architecture : Redis Cluster ou Memcached distribue. Consistent hashing pour distribuer les cles entre les noeuds sans redistribution massive lors de l'ajout/suppression. Cache stampede : lock ou probabilistic early expiration pour eviter les requetes simultanees a l'expiration. Invalidation : la plus grande difficulte en informatique. Strategies : TTL, event-driven invalidation, version-based keys.
8. Qu'est-ce que le sharding de base de donnees et comment le mettre en place ?
Le sharding (partitionnement horizontal) distribue les donnees sur plusieurs serveurs de base de donnees. Strategies : range-based (par date, par ID range), hash-based (hash de la cle mod N), directory-based (table de lookup). Cle de sharding : choix critique, doit distribuer uniformement les donnees et les requetes. Mauvais choix = hotspots. Problemes : jointures cross-shard complexes, transactions distribuees, rebalancing lors de l'ajout de shards. Solutions : denormaliser pour eviter les jointures, utiliser des ID globaux (snowflake), consistent hashing pour le rebalancing minimal. Alternatives au sharding manuel : bases de donnees nativement distribuees (CockroachDB, Vitess pour MySQL, Citus pour PostgreSQL).
9. Comment concevoir un moteur de recherche simplifie ?
Indexation : crawler parcourt les pages, extracteur parse le HTML, index inverse mappe chaque mot aux documents le contenant (mot -> liste de doc_ids avec positions et frequences). Stockage dans une structure optimisee (B-tree ou hash). Recherche : tokenisation de la requete, lookup dans l'index inverse, intersection des resultats pour les requetes multi-mots. Ranking : TF-IDF (frequence du terme * rarete dans le corpus) comme base, PageRank pour la popularite, signaux de fraicheur, proximite des mots. Architecture : index partitionne (sharded) par documents, replicas pour la disponibilite. Elasticsearch implemente tout cela avec Lucene : index inverse, analyseurs linguistiques, scoring BM25, aggregations, suggestions autocomplete.
10. Comment aborder un entretien de system design ?
Methodologie en 4 etapes : 1) Clarifier les requirements (5 min) : utilisateurs, fonctionnalites cles, contraintes (traffic, stockage, latence). Estimer les chiffres (QPS, stockage). 2) High-level design (15 min) : composants principaux (client, API, services, base de donnees, cache), diagramme d'architecture, flux de donnees. 3) Deep dive (15 min) : approfondir 2-3 composants critiques, discuter les trade-offs, gerer les edge cases. 4) Wrap-up (5 min) : bottlenecks, monitoring, evolution future. Principes transversaux : estimer avant de concevoir, privilegier la simplicite, nommer les trade-offs explicitement, considerer les pannes. Les recruteurs evaluent la pensee structuree et la capacite a naviguer les compromis, pas la solution parfaite.