Entraînement Practice
Flashcards pour répéter tes réponses à voix haute, QCM pour vérifier que c'est acquis. Comme en entretien : réponds avant de révéler. Flashcards to rehearse answers out loud, quizzes to check they stuck. Like a real interview: answer before revealing.
Jour 57 Day 57 Raconter ses projets en entretien Telling your projects in interviews
Flashcards Flashcards
Quelle est la structure STAR adaptée au tech pour raconter un projet ? What is the tech-adapted STAR structure for telling a project?
Contexte (quoi, pour qui, quelle équipe, quel délai) → Problème (la difficulté concrète) → Décisions (les choix, leurs alternatives, qui a fait quoi) → Résultat (ce qui a marché, avec des chiffres) → Leçons (ce qu'on referait autrement). Le tout en 90 secondes, puis l'intervieweur creuse. Context (what, for whom, what team, what deadline) → Problem (the concrete difficulty) → Decisions (the choices, their alternatives, who did what) → Result (what worked, with numbers) → Lessons (what you'd redo differently). All in 90 seconds, then the interviewer digs.
Combien de projets préparer pour un entretien, et à quel niveau de détail ? How many projects should you prepare for an interview, and at what level of detail?
2 à 3 projets connus à fond : architecture dessinable au tableau, décisions et alternatives, un ou deux chiffres, ce qui a raté, ce qu'on referait autrement. Trois histoires maîtrisées valent mieux que huit lignes de CV survolées. 2 to 3 projects known inside out: architecture drawable on a whiteboard, decisions and alternatives, one or two numbers, what went wrong, what you'd redo differently. Three mastered stories beat eight skimmed CV lines.
Pourquoi quantifier ses résultats de projet, même modestement ? Why quantify your project results, even modestly?
Un chiffre transforme une affirmation en preuve : « le chargement est passé de 4 s à 800 ms » raconte une investigation, là où « une app rapide » ne dit rien. Utilisateurs, latence, volume, temps gagné — un chiffre honnête bat un superlatif. A number turns a claim into evidence: "load time went from 4 s to 800 ms" tells an investigation, where "a fast app" says nothing. Users, latency, volume, time saved — an honest number beats a superlative.
« Pourquoi Postgres ? » alors que la vraie raison est « on connaissait » : que répondre ? "Why Postgres?" when the real reason is "we knew it": what do you answer?
L'assumer, en le contextualisant : « c'est la base qu'on connaissait, nos données étaient relationnelles, c'était le choix sûr en trois semaines » — honnête et défendable. Bonus : nommer ce qu'on comparerait aujourd'hui. Inventer une justification savante a posteriori s'effondre à la deuxième question. Own it, with context: "it's the database we knew, our data was relational, it was the safe choice in three weeks" — honest and defensible. Bonus: name what you'd compare today. Inventing a scholarly after-the-fact justification collapses at the second question.
Comment répondre à « qu'est-ce qui a raté dans ce projet ? » ? How do you answer "what went wrong in this project?"
Jamais « rien ». Un raté précis + sa cause + ce qu'on a changé depuis : « on a perdu une semaine faute d'avoir figé le schéma ; depuis je commence par le modèle ». Le recruteur juge la lucidité et la boucle d'apprentissage, pas l'échec lui-même. Never "nothing". One precise failure + its cause + what you changed since: "we lost a week for not freezing the schema; since then I start with the model". The interviewer judges lucidity and the learning loop, not the failure itself.
Quel est le piège du projet de groupe en entretien, et comment l'éviter ? What is the group-project trap in interviews, and how do you avoid it?
L'intervieweur isole votre contribution : « qu'as-tu fait, toi, précisément ? ». S'attribuer le projet entier se détecte en trois questions techniques. Réponse au « je » avec un périmètre net, en créditant les autres : « j'ai pris le serveur de jeu ; le front, c'était Marie et Tom ». The interviewer isolates your contribution: "what did you, precisely, do?". Claiming the whole project gets detected within three technical questions. Answer in the first person with a clear scope, crediting the others: "I took the game server; the front end was Marie and Tom".
Que contient un README qui « fait la moitié du travail » ? What does a README that "does half the work" contain?
Une capture d'écran (ou un GIF de démo), une ou deux phrases sur le quoi et le pourquoi, des instructions de lancement qui marchent (idéalement docker compose up), pas de node_modules commité ni de secrets dans l'historique. C'est le seul document qui parle pour vous en votre absence. A screenshot (or a demo GIF), one or two sentences on the what and the why, launch instructions that work (ideally docker compose up), no committed node_modules and no secrets in the history. It's the only document that speaks for you in your absence.
Comment sécuriser une démo de projet le jour de l'entretien ? How do you secure a project demo on interview day?
Tester l'URL déployée le matin même, et préparer un plan B hors ligne : capture vidéo de 30 s ou GIF dans le README. La démo live échoue pour des raisons étrangères à votre travail (wifi, service gratuit endormi) ; enchaîner calmement sur la vidéo fait partie de l'évaluation. Test the deployed URL that same morning, and prepare an offline plan B: a 30 s video capture or a GIF in the README. Live demos fail for reasons unrelated to your work (wifi, sleeping free tier); calmly switching to the video is part of the evaluation.
QCM Quiz
« Présente-moi un projet dont tu es fier. » Quelle est la meilleure ouverture ? "Tell me about a project you're proud of." What's the best opening?
La structure STAR commence par le contexte puis le problème : c'est ce qui donne envie d'écouter la suite. La stack arrive plus tard, dans les décisions ; le monologue épuise l'attention ; la fausse modestie sabote le projet avant de le montrer. The STAR structure starts with context then problem: that's what makes people want to hear the rest. The stack comes later, in the decisions; the monologue exhausts attention; false modesty sabotages the project before showing it.
« Qu'est-ce qui a raté dans ce projet ? » Quelle réponse marque des points ? "What went wrong in this project?" Which answer scores points?
L'intervieweur évalue la lucidité et la boucle d'apprentissage. « Rien » n'est pas crédible, accuser un coéquipier est un red flag, et l'autoflagellation inquiète. Le trio raté → cause → changement montre exactement la maturité recherchée. The interviewer evaluates lucidity and the learning loop. "Nothing" isn't credible, blaming a teammate is a red flag, and self-flagellation worries people. The failure → cause → change trio shows exactly the maturity they're looking for.
Quel énoncé de résultat est le plus convaincant dans un pitch de projet ? Which result statement is the most convincing in a project pitch?
Un chiffre avant/après raconte une investigation : mesure, hypothèse, correction, re-mesure. Les superlatifs (« rapide », « adoré », « meilleures ») ne sont ni vérifiables ni mémorables — un chiffre honnête, même modeste, bat tous les adjectifs. A before/after number tells an investigation: measure, hypothesis, fix, re-measure. Superlatives ("fast", "loved", "best") are neither verifiable nor memorable — an honest number, even a modest one, beats every adjective.
Dans un projet de groupe, quelle formulation est la bonne en entretien ? In a group project, which phrasing is right for an interview?
Un périmètre net au « je », en créditant les autres : c'est vérifiable, crédible, et ça résiste aux questions techniques qui suivront. Le flou comme l'appropriation totale se détectent en trois questions — et créditer l'équipe renforce votre crédibilité. A clear first-person scope, crediting the others: verifiable, credible, and it survives the technical questions that follow. Both vagueness and total appropriation get detected within three questions — and crediting the team strengthens your credibility.
Quel est le meilleur plan B pour une démo le jour de l'entretien ? What's the best plan B for a demo on interview day?
La démo live échoue pour des raisons étrangères à votre travail : wifi, service gratuit endormi, dépendance cassée. La vidéo préparée montre le produit ET votre gestion de l'imprévu ; relancer nerveusement son terminal montre l'inverse. Live demos fail for reasons unrelated to your work: wifi, sleeping free tier, broken dependency. The prepared video shows the product AND how you handle the unexpected; nervously restarting your terminal shows the opposite.
« Pourquoi avoir choisi cette techno ? » — la vraie raison est la familiarité. Que faire ? "Why did you choose this technology?" — the real reason is familiarity. What do you do?
« C'est ce qu'on connaissait, et c'était le choix sûr dans notre délai » est honnête, contextualisé et défendable — surtout suivi de « aujourd'hui je comparerais avec X ». La justification inventée s'effondre à la question suivante, et l'esquive se voit. "It's what we knew, and it was the safe choice given our deadline" is honest, contextualized and defensible — especially followed by "today I'd compare it with X". The invented justification collapses at the next question, and the dodge is obvious.
Jour 56 Day 56 Les nids à bugs : UTF-8, dates & regex Bug magnets: UTF-8, dates & regex
Flashcards Flashcards
Quelle différence entre un octet, un code point et un graphème ? What's the difference between a byte, a code point and a grapheme?
L'octet est l'unité de stockage (UTF-8 : 1 à 4 octets par code point). Le code point est le numéro Unicode d'un caractère (é = U+00E9). Le graphème est ce que l'utilisateur voit à l'écran — il peut regrouper plusieurs code points (e + accent combinant, emoji famille avec ZWJ). The byte is the storage unit (UTF-8: 1 to 4 bytes per code point). The code point is a character's Unicode number (é = U+00E9). The grapheme is what the user sees on screen — it can group several code points (e + combining accent, family emoji with ZWJs).
Pourquoi 'é'.length peut-il valoir 2 en JavaScript ? Why can 'é'.length equal 2 in JavaScript?
Deux raisons : en forme NFD, é est décomposé en deux code points (e + accent combinant U+0301) ; et length compte des unités UTF-16, pas des graphèmes ('👍'.length === 2 à cause de la paire de substitution). Fix : normalize('NFC') et Intl.Segmenter pour compter les graphèmes. Two reasons: in NFD form, é is decomposed into two code points (e + combining accent U+0301); and length counts UTF-16 units, not graphemes ('👍'.length === 2 because of the surrogate pair). Fix: normalize('NFC') and Intl.Segmenter to count graphemes.
Qu'est-ce que la normalisation NFC/NFD et quand l'appliquer ? What is NFC/NFD normalization and when do you apply it?
NFC = forme précomposée (é en un code point), NFD = forme décomposée (e + accent). Deux chaînes visuellement identiques peuvent différer binairement — la comparaison et la recherche échouent alors. Normaliser en NFC aux frontières du système : formulaires, imports, noms de fichiers (macOS produit du NFD). NFC = precomposed form (é as one code point), NFD = decomposed form (e + accent). Two visually identical strings can differ at the binary level — comparison and search then fail. Normalize to NFC at system boundaries: forms, imports, filenames (macOS produces NFD).
Qu'est-ce que le mojibake et d'où vient-il ? What is mojibake and where does it come from?
Du texte corrompu du type été au lieu de été : des octets UTF-8 décodés avec le mauvais charset (Latin-1 par exemple). é en UTF-8 = deux octets C3 A9, que Latin-1 relit comme deux caractères é. Fix : UTF-8 déclaré explicitement partout — fichiers, en-têtes HTTP, connexion DB. Corrupted text like été instead of été: UTF-8 bytes decoded with the wrong charset (Latin-1 for instance). é in UTF-8 is two bytes C3 A9, which Latin-1 re-reads as the two characters é. Fix: UTF-8 explicitly declared everywhere — files, HTTP headers, DB connection.
Quelle est la règle d'or pour stocker les dates, et son exception ? What is the golden rule for storing dates, and its exception?
Stocker en UTC au format ISO 8601, convertir dans le fuseau de l'utilisateur uniquement à l'affichage. Exception : un événement futur lié à un lieu (réunion à 9 h à Paris) se stocke en heure locale + identifiant IANA (Europe/Paris), car les règles de fuseau peuvent changer avant l'événement. Store in UTC in ISO 8601 format, convert to the user's timezone only at display time. Exception: a future event tied to a place (9am meeting in Paris) is stored as local time + IANA identifier (Europe/Paris), because timezone rules may change before the event.
Qu'est-ce que le bug du « minuit local » ? What is the "local midnight" bug?
Stocker une date-seule (anniversaire, deadline) comme timestamp à minuit dans le fuseau local : affichée depuis un fuseau plus à l'ouest, elle recule d'un jour. Fix : un type date sans heure (DATE en SQL, Temporal.PlainDate en JS), jamais un timestamp. Storing a date-only value (birthday, deadline) as a timestamp at midnight in the local timezone: displayed from a timezone further west, it moves back a day. Fix: a time-less date type (DATE in SQL, Temporal.PlainDate in JS), never a timestamp.
Greedy vs lazy en regex : quelle différence, et quelle troisième option ? Greedy vs lazy in regex: what's the difference, and what's the third option?
Un quantificateur glouton (.+) avale le maximum puis rétrocède (backtracking) ; lazy (.+?) prend le minimum puis étend. Sur '<b>x</b>', <.+> capture tout, <.+?> capture '<b>'. Troisième option, souvent la meilleure : la classe négée <[^>]+> — même résultat, sans backtracking. A greedy quantifier (.+) swallows the maximum then backs off (backtracking); lazy (.+?) takes the minimum then extends. On '<b>x</b>', <.+> captures everything, <.+?> captures '<b>'. Third option, often the best: the negated class <[^>]+> — same result, no backtracking.
Qu'est-ce que le ReDoS et comment s'en protéger ? What is ReDoS and how do you protect against it?
Le Regular expression Denial of Service : une regex à quantificateurs imbriqués comme (a+)+$ part en backtracking exponentiel sur une entrée hostile, et gèle un thread avec une seule requête (pannes Stack Overflow 2016, Cloudflare 2019). Parades : éviter les quantificateurs imbriqués, timeout d'exécution, moteur linéaire (RE2, regex Rust). Regular expression Denial of Service: a regex with nested quantifiers like (a+)+$ goes into exponential backtracking on hostile input, freezing a thread with a single request (Stack Overflow 2016 and Cloudflare 2019 outages). Countermeasures: avoid nested quantifiers, execution timeout, linear engine (RE2, Rust regex).
QCM Quiz
Combien d'octets occupe le caractère '€' (U+20AC) en UTF-8 ? How many bytes does the character '€' (U+20AC) take in UTF-8?
UTF-8 est à longueur variable : 1 octet pour l'ASCII, 2 pour é, 3 pour € (E2 82 AC) et la plupart des idéogrammes, 4 pour les emojis. Le préfixe du premier octet (1110xxxx ici) annonce la longueur. UTF-8 is variable-length: 1 byte for ASCII, 2 for é, 3 for € (E2 82 AC) and most ideograms, 4 for emojis. The first byte's prefix (1110xxxx here) announces the length.
En JavaScript, comment est interprété new Date('2026-10-29') ? In JavaScript, how is new Date('2026-10-29') interpreted?
Une chaîne ISO date-seule est parsée comme minuit UTC, mais '2026-10-29T00:00' (avec heure) comme minuit LOCAL. Cette incohérence historique de Date décale des dates d'un jour selon le fuseau — d'où Temporal et les bibliothèques modernes. A date-only ISO string is parsed as midnight UTC, but '2026-10-29T00:00' (with a time) as LOCAL midnight. This historical Date inconsistency shifts dates by a day depending on the timezone — hence Temporal and modern libraries.
Quelle regex extrait '<b>' de '<b>gras</b>' sans backtracking ? Which regex extracts '<b>' from '<b>bold</b>' without backtracking?
<.+> et <.*> sont gloutons et capturent jusqu'au dernier '>'. <.+?> (lazy) donne le bon résultat mais procède par extensions successives. La classe négée <[^>]+> exprime l'intention — « tout sauf > » — et matche en un passage. <.+> and <.*> are greedy and capture up to the last '>'. <.+?> (lazy) gives the right result but works by successive extensions. The negated class <[^>]+> states the intent — "anything but >" — and matches in one pass.
Deux chaînes « café » s'affichent à l'identique mais ne sont pas égales à la comparaison. Cause la plus probable ? Two "café" strings display identically but compare as unequal. Most likely cause?
é existe en un code point (U+00E9, NFC) ou deux (U+0065 + U+0301, NFD) : rendu identique, octets différents. Fix : normalize('NFC') des deux côtés avant de comparer. L'encodage interne du langage ne change pas l'égalité logique. é exists as one code point (U+00E9, NFC) or two (U+0065 + U+0301, NFD): identical rendering, different bytes. Fix: normalize('NFC') on both sides before comparing. The language's internal encoding doesn't change logical equality.
Comment stocker « réunion le 15 mars 2027 à 9 h, heure de Paris » ? How do you store "meeting on March 15, 2027 at 9am, Paris time"?
C'est l'exception à « UTC partout » : l'intention est « 9 h à Paris », et si les règles de DST changent d'ici 2027, la conversion UTC figée deviendrait fausse. On stocke l'intention (heure locale + fuseau IANA) et on convertit au moment voulu. UTC reste la règle pour les instants passés ou absolus. This is the exception to "UTC everywhere": the intent is "9am in Paris", and if DST rules change before 2027, a frozen UTC conversion becomes wrong. Store the intent (local time + IANA timezone) and convert when needed. UTC remains the rule for past or absolute instants.
Que se passe-t-il quand (a+)+$ est évaluée sur 'aaaaaaaaaaaaaaaaaaaaab' ? What happens when (a+)+$ is evaluated against 'aaaaaaaaaaaaaaaaaaaaab'?
Le moteur à backtracking essaie toutes les façons de découper les 'a' entre les deux quantificateurs avant de conclure à l'échec : 2^n combinaisons. C'est le ReDoS — la syntaxe est valide, et le moteur ne « voit » pas le b final à l'avance. Les moteurs linéaires (RE2) éliminent le problème. The backtracking engine tries every way of splitting the 'a's between the two quantifiers before concluding failure: 2^n combinations. That's ReDoS — the syntax is valid, and the engine doesn't "see" the trailing b in advance. Linear engines (RE2) eliminate the problem.
Jour 55 Day 55 LLM en production : coûts, latence, evals & limites LLMs in production: cost, latency, evals & limits
Flashcards Flashcards
Pourquoi le coût cumulé d'une conversation LLM croît-il quasi quadratiquement ? Why does the cumulative cost of an LLM conversation grow almost quadratically?
L'API est sans état : chaque tour renvoie tout l'historique en tokens d'entrée. Au tour n, on re-paye les n−1 tours précédents. Mitigations : tronquer ou résumer l'historique, et cache de prompts sur le préfixe stable. The API is stateless: every turn resends the whole history as input tokens. At turn n, you re-pay the previous n−1 turns. Mitigations: truncate or summarize the history, and prompt-cache the stable prefix.
Qu'est-ce que le TTFT et pourquoi le streaming change-t-il la latence perçue ? What is TTFT and why does streaming change perceived latency?
Le time-to-first-token est le délai avant le premier token de la réponse. Le streaming affiche les tokens au fil de la génération : la durée totale ne change pas, mais l'utilisateur commence à lire au TTFT (quelques centaines de ms) au lieu d'attendre la réponse complète. Time-to-first-token is the delay before the first token of the answer. Streaming displays tokens as they are generated: total duration is unchanged, but the user starts reading at the TTFT (a few hundred ms) instead of waiting for the full answer.
Comment fonctionne le cache de prompts et quelle contrainte impose-t-il ? How does prompt caching work and what constraint does it impose?
Le fournisseur facture ~10 % du prix normal pour un préfixe de prompt déjà vu (le prefill est réutilisé). Contrainte : le préfixe doit être identique octet pour octet — d'où instructions système et documents stables en tête, contenu variable en fin de prompt. The provider bills ~10% of the normal price for a prompt prefix it has already seen (the prefill is reused). Constraint: the prefix must be byte-identical — hence system instructions and stable documents at the head, variable content at the tail.
Pourquoi valider les sorties d'un LLM avec un schéma (zod, pydantic) ? Why validate LLM outputs with a schema (zod, pydantic)?
La sortie d'un LLM est une entrée non fiable : JSON invalide, champ manquant, format inattendu, même à température 0. La validation par schéma transforme du texte libre en données typées garanties conformes, avec retry puis fallback en cas d'échec. LLM output is untrusted input: invalid JSON, missing fields, unexpected formats, even at temperature 0. Schema validation turns free text into typed data guaranteed to conform, with retry then fallback on failure.
Qu'est-ce qu'une eval automatisée pour une feature LLM ? What is an automated eval for an LLM feature?
Un jeu de test métier (50-200 cas réels annotés) rejoué à chaque changement de prompt ou de modèle, comme des tests de non-régression. Sans evals, modifier un prompt en prod revient à déployer sans tests — et le choix d'un modèle plus petit ne peut pas se justifier. A business test set (50-200 annotated real cases) replayed on every prompt or model change, like regression tests. Without evals, changing a prompt in production is deploying without tests — and switching to a smaller model can't be justified.
Quels sont les biais connus du LLM-as-judge ? What are the known biases of LLM-as-judge?
Verbosity bias (préférence pour les réponses longues), position bias (préférence pour la première réponse dans une comparaison), self-preference (préférence pour ses propres sorties). Parade : calibrer le juge contre un échantillon annoté par des humains. Verbosity bias (preference for long answers), position bias (preference for the first answer in a comparison), self-preference (preference for its own outputs). Countermeasure: calibrate the judge against a human-annotated sample.
Pourquoi dit-on que les hallucinations se mitigent mais ne se corrigent pas ? Why do we say hallucinations can be mitigated but not fixed?
Elles sont structurelles : le modèle prédit le texte le plus plausible, pas le plus vrai. On réduit leur fréquence et leur impact — RAG pour ancrer sur des sources, citations vérifiables, humain dans la boucle sur les actions critiques — mais aucun réglage ne les élimine. They are structural: the model predicts the most plausible text, not the most true. You reduce their frequency and impact — RAG to ground answers in sources, verifiable citations, human in the loop on critical actions — but no setting eliminates them.
Qu'est-ce que la prompt injection et pourquoi n'a-t-elle pas de correctif définitif ? What is prompt injection and why is there no definitive fix?
Des instructions hostiles cachées dans le contenu que le LLM traite (document, page web, email). Le modèle ne sépare pas instructions et données dans son contexte — il n'existe pas d'équivalent des requêtes préparées. Défense en profondeur : moindre privilège des outils, validation des sorties, confirmation humaine des actions sensibles. Hostile instructions hidden in content the LLM processes (a document, web page, email). The model doesn't separate instructions from data in its context — there is no equivalent of prepared statements. Defense in depth: least privilege for tools, output validation, human confirmation of sensitive actions.
QCM Quiz
Quel levier réduit le coût d'un chatbot sans toucher à la qualité des réponses ? Which lever cuts a chatbot's cost without touching answer quality?
Le cache de prompts facture le préfixe déjà vu ~10 % du prix, sans changer le modèle ni la réponse. La température ne joue pas sur le coût, et retirer la validation ou augmenter max_tokens dégrade fiabilité ou budget. Prompt caching bills the already-seen prefix at ~10% of the price, without changing the model or the answer. Temperature doesn't affect cost, and removing validation or raising max_tokens hurts reliability or budget.
Pour quel cas d'usage la Batch API (−50 %) est-elle adaptée ? Which use case is the Batch API (−50%) suited for?
Le batch rend les résultats en minutes ou en heures : parfait pour l'asynchrone massif (classification, enrichissement), inutilisable pour tout ce qui attend une réponse immédiate. Batch returns results in minutes or hours: perfect for massive async work (classification, enrichment), unusable for anything expecting an immediate answer.
Que mesure le time-to-first-token (TTFT) ? What does time-to-first-token (TTFT) measure?
Le TTFT couvre réseau + prefill (traitement du prompt) jusqu'au premier token. Avec le streaming, c'est LA métrique de latence perçue ; le débit (tokens/s) gouverne la suite. TTFT covers network + prefill (prompt processing) up to the first token. With streaming, it's THE perceived-latency metric; throughput (tokens/s) governs the rest.
Quel biais documenté du LLM-as-judge fausse le plus souvent les comparaisons ? Which documented LLM-as-judge bias most often skews comparisons?
Verbosity bias et position bias sont mesurés dans la littérature (Zheng et al., 2023) : réponses longues et premières positions surnotées. D'où l'inversion des positions et la calibration sur un échantillon humain. Verbosity bias and position bias are measured in the literature (Zheng et al., 2023): long answers and first positions get overrated. Hence position swapping and calibration on a human sample.
Comment obtenir de façon fiable du JSON exploitable d'un LLM ? How do you reliably get usable JSON from an LLM?
Le prompt seul ne garantit rien, la température 0 n'est pas déterministe, et aucun modèle n'est infaillible. Seule la chaîne complète — contrainte côté API, validation côté client, retry puis fallback — tient en prod. The prompt alone guarantees nothing, temperature 0 isn't deterministic, and no model is infallible. Only the full chain — API-side constraint, client-side validation, retry then fallback — holds in production.
Un agent LLM lit des emails et peut envoyer des réponses. Quelle est la meilleure défense contre la prompt injection ? An LLM agent reads emails and can send replies. What is the best defense against prompt injection?
Les instructions défensives dans le prompt se contournent et les filtres par mots-clés aussi ; le chiffrement ne change rien au contexte lu par le modèle. Sans correctif garanti, on limite les dégâts possibles : privilèges minimaux et humain dans la boucle. Defensive prompt instructions can be bypassed and so can keyword filters; encryption changes nothing about the context the model reads. With no guaranteed fix, you limit the possible damage: minimal privileges and a human in the loop.
Jour 54 Day 54 Recherche full-text & Elasticsearch Full-text search & Elasticsearch
Flashcards Flashcards
Pourquoi `LIKE '%mot%'` ne scale-t-il pas ? Why doesn't `LIKE '%word%'` scale?
Le joker en tête de motif empêche l'utilisation d'un index B-tree (qui ordonne par préfixe) : la base scanne toute la table à chaque requête, O(n). Et fonctionnellement : pas de stemming, pas de score de pertinence, pas de tolérance aux fautes. The leading wildcard prevents any B-tree index use (B-trees order by prefix): the database scans the whole table on every query, O(n). And functionally: no stemming, no relevance scoring, no typo tolerance.
Qu'est-ce qu'un index inversé ? What is an inverted index?
La structure qui inverse la relation document→termes en terme→documents : pour chaque terme (après analyse), la liste des documents qui le contiennent (postings, avec positions). Chercher devient une lecture directe suivie d'intersections (AND) ou d'unions (OR) de listes, triées par score. The structure that inverts the document→terms relation into term→documents: for each term (after analysis), the list of documents containing it (postings, with positions). Searching becomes a direct lookup followed by list intersections (AND) or unions (OR), sorted by score.
Que fait un analyzer et pourquoi la requête doit-elle subir la même analyse que les documents ? What does an analyzer do and why must the query go through the same analysis as the documents?
Il transforme le texte brut en termes : tokenization, lowercase, suppression des stop words, stemming — par langue. La requête passe par le même pipeline, sinon « Chaussure » (requête) ne matcherait jamais « chaussur » (terme stocké dans l'index). It turns raw text into terms: tokenization, lowercasing, stop word removal, stemming — per language. The query goes through the same pipeline, otherwise "Shoe" (query) would never match "shoe" (the stemmed term stored in the index).
Quelle est l'intuition derrière TF-IDF et qu'ajoute BM25 ? What's the intuition behind TF-IDF and what does BM25 add?
TF-IDF : un terme pèse plus s'il est fréquent dans le document (TF) et rare dans le corpus (IDF) — « running » discrimine, « de » non. BM25 ajoute la saturation du TF (les répétitions rapportent de moins en moins) et la normalisation par longueur du document (un match dans un titre court pèse plus). TF-IDF: a term weighs more if it's frequent in the document (TF) and rare in the corpus (IDF) — "running" discriminates, "the" doesn't. BM25 adds TF saturation (repetitions yield less and less) and document-length normalization (a match in a short title weighs more).
Dans un mapping Elasticsearch, quelle différence entre un champ `text` et un champ `keyword` ? In an Elasticsearch mapping, what's the difference between a `text` field and a `keyword` field?
`text` est analysé (tokenizé, stemmé) : fait pour la recherche full-text via `match`. `keyword` est stocké brut : fait pour les filtres exacts (`term`), les tris et les agrégations. Trier sur un champ analysé ou faire du full-text sur un keyword sont les deux erreurs classiques. `text` is analyzed (tokenized, stemmed): made for full-text search via `match`. `keyword` is stored raw: made for exact filters (`term`), sorting and aggregations. Sorting on an analyzed field or full-text searching a keyword are the two classic mistakes.
Dans une requête bool, quelle différence entre `must` et `filter` ? In a bool query, what's the difference between `must` and `filter`?
`must` participe au score BM25 (pertinence) ; `filter` est binaire : il élimine sans noter, il est plus rapide et son résultat est mis en cache. Pattern type : le texte cherché en must (match), la catégorie et la fourchette de prix en filter (term, range). `must` contributes to the BM25 score (relevance); `filter` is binary: it eliminates without scoring, runs faster and its result is cached. Typical pattern: the searched text in must (match), category and price range in filter (term, range).
Comment synchroniser Elasticsearch avec la base source de vérité ? How do you keep Elasticsearch in sync with the source-of-truth database?
Double écriture applicative (simple, mais gérer l'échec d'indexation après le commit : retry, file de messages) ou CDC — Debezium lit le WAL de la base et rejoue les changements vers l'index. Dans tous les cas : cohérence à terme, et une réindexation complète pour rattraper les dérives. Application-level double write (simple, but handle indexing failure after the commit: retry, message queue) or CDC — Debezium reads the database's WAL and replays changes to the index. Either way: eventual consistency, plus a full reindex to catch up on drift.
Que propose Postgres pour le full-text search ? What does Postgres offer for full-text search?
`tsvector` (document analysé : tokenisation, stemming par dictionnaire de langue) + `tsquery` (requête), l'opérateur `@@` pour matcher, un index GIN pour la vitesse et `ts_rank` pour trier par pertinence. Dans la même base que les données : transactionnel et zéro synchro — souvent suffisant. `tsvector` (analyzed document: tokenization, stemming via language dictionaries) + `tsquery` (the query), the `@@` operator to match, a GIN index for speed and `ts_rank` to sort by relevance. In the same database as the data: transactional and zero sync — often enough.
QCM Quiz
Que stocke fondamentalement un index inversé ? What does an inverted index fundamentally store?
C'est l'inversion qui donne son nom à la structure : terme → documents (postings). Chercher un terme devient une lecture directe au lieu d'un parcours de tous les documents. The inversion gives the structure its name: term → documents (postings). Looking up a term becomes a direct read instead of walking every document.
Pourquoi une requête `term: "Running"` sur un champ `text` ne renvoie-t-elle rien ? Why does a `term: "Running"` query on a `text` field return nothing?
Le champ text est analysé à l'indexation (lowercase, stemming) mais term compare la valeur brute. Il faut match (qui analyse la requête) pour le full-text, et réserver term aux champs keyword. The text field is analyzed at indexing time (lowercase, stemming) but term compares the raw value. Use match (which analyzes the query) for full-text, and keep term for keyword fields.
Selon BM25, quel match pèse le plus lourd ? According to BM25, which match weighs the most?
BM25 = IDF élevé (terme rare) × TF saturé × normalisation par longueur. Un terme rare dans un titre court cumule les trois ; un terme omniprésent a un IDF quasi nul, et les répétitions saturent. BM25 = high IDF (rare term) × saturated TF × length normalization. A rare term in a short title checks all three; a ubiquitous term has near-zero IDF, and repetitions saturate.
Dans le pattern « DB + index de recherche », quel est le principal problème à gérer ? In the "DB + search index" pattern, what is the main problem to handle?
La DB reste source de vérité, l'index en est une projection : chaque écriture doit être propagée. Double écriture naïve = pertes silencieuses en cas de crash ; d'où files avec retry ou CDC (Debezium), et cohérence à terme assumée. The DB stays the source of truth, the index is a projection: every write must be propagated. Naive double writes silently lose data on crashes; hence queues with retries or CDC (Debezium), and owning eventual consistency.
Quel duo Postgres fournit la recherche full-text indexée ? Which Postgres duo provides indexed full-text search?
tsvector stocke le document analysé (stemming par langue), tsquery exprime la requête, @@ les confronte et l'index GIN rend le tout rapide. ts_rank trie par pertinence — sans système externe ni synchro. tsvector stores the analyzed document (per-language stemming), tsquery expresses the query, @@ matches them and the GIN index makes it fast. ts_rank sorts by relevance — no external system, no sync.
Pourquoi ne faut-il PAS utiliser Elasticsearch comme base de données primaire ? Why should you NOT use Elasticsearch as a primary database?
Si l'index est perdu, on le reconstruit depuis la DB. Si les données ne vivaient QUE dans Elasticsearch, elles sont perdues : pas de transactions ni de contraintes d'intégrité comparables à une base relationnelle. If the index is lost, you rebuild it from the DB. If the data lived ONLY in Elasticsearch, it's gone: no transactions or integrity constraints comparable to a relational database.
Jour 53 Day 53 OOP vs programmation fonctionnelle OOP vs functional programming
Flashcards Flashcards
Qu'est-ce qu'une fonction pure ? What is a pure function?
Une fonction dont la sortie ne dépend que de ses arguments (même entrée → même sortie) et qui ne produit aucun effet de bord : pas d'I/O, pas de mutation externe, pas de Date.now() ni Math.random() cachés. Conséquences : testable sans mock, mémoïsable, parallélisable. A function whose output depends only on its arguments (same input → same output) and that produces no side effect: no I/O, no external mutation, no hidden Date.now() or Math.random(). Consequences: testable without mocks, memoizable, parallelizable.
Pourquoi préférer la composition à l'héritage ? Why prefer composition over inheritance?
L'héritage couple fortement la classe fille à l'implémentation de la mère : un changement se propage silencieusement et les hiérarchies profondes finissent par mentir. La composition assemble des capacités (un objet POSSÈDE plutôt qu'il n'HÉRITE) : couplage faible, testable pièce par pièce, recombinable. Inheritance tightly couples the child class to the parent's implementation: a change propagates silently and deep hierarchies end up lying. Composition assembles capabilities (an object HAS rather than IS-A): loose coupling, testable piece by piece, recombinable.
Pourquoi l'état mutable partagé est-il considéré comme la vraie racine des bugs ? Why is shared mutable state considered the real root of bugs?
Quand deux morceaux de code peuvent modifier la même structure, chacun casse les hypothèses de l'autre : bugs d'action à distance, difficiles à reproduire, aggravés en concurrence (race conditions). L'OOP le contrôle (encapsulation), la FP le supprime (immutabilité). When two pieces of code can modify the same structure, each breaks the other's assumptions: action-at-a-distance bugs, hard to reproduce, worse under concurrency (race conditions). OOP controls it (encapsulation), FP removes it (immutability).
Que font map, filter et reduce ? What do map, filter and reduce do?
map transforme chaque élément (n éléments → n éléments), filter garde ceux qui passent un prédicat (n → ≤n), reduce replie la liste en une seule valeur via un accumulateur et une valeur initiale. Ensemble : un pipeline déclaratif qui remplace la boucle à accumulateur. map transforms each element (n elements → n elements), filter keeps those passing a predicate (n → ≤n), reduce folds the list into a single value via an accumulator and a seed. Together: a declarative pipeline replacing the accumulator loop.
Qu'est-ce que le pattern « functional core, imperative shell » ? What is the "functional core, imperative shell" pattern?
Un cœur de logique métier écrit en fonctions pures (calculs, validation, décisions), entouré d'une coquille fine impérative qui gère les effets de bord (DB, HTTP, fichiers, horloge). On teste le cœur sans mock et la coquille en tests d'intégration. A core of business logic written as pure functions (computation, validation, decisions), surrounded by a thin imperative shell handling side effects (DB, HTTP, files, clock). You test the core without mocks and the shell with integration tests.
Qu'est-ce que l'encapsulation apporte réellement en OOP ? What does encapsulation actually bring in OOP?
Elle rend les états invalides impossibles : l'état privé ne se modifie que par des méthodes qui garantissent les invariants (ex. un BankAccount dont le solde ne change que via deposit/withdraw qui vérifient les règles). Une classe anémique (getters/setters sans logique) n'encapsule rien. It makes invalid states impossible: private state only changes through methods that guarantee invariants (e.g. a BankAccount whose balance only changes via deposit/withdraw enforcing the rules). An anemic class (getters/setters with no logic) encapsulates nothing.
Qu'est-ce qu'une fonction d'ordre supérieur ? Donnez des exemples au-delà de map/filter. What is a higher-order function? Give examples beyond map/filter.
Une fonction qui prend une fonction en argument ou en retourne une. Exemples courants : les middlewares Express (reçoivent next), les hooks React (useEffect prend un callback), les décorateurs, debounce/throttle, ou un comparateur passé à sort(). A function that takes a function as argument or returns one. Common examples: Express middlewares (receive next), React hooks (useEffect takes a callback), decorators, debounce/throttle, or a comparator passed to sort().
Qu'est-ce qu'une union discriminée en TypeScript et quel lien avec la FP ? What is a discriminated union in TypeScript and how does it relate to FP?
Un type somme, ex. `{ ok: true; data: User } | { ok: false; error: string }` : le champ discriminant force le switch à traiter chaque cas et le compilateur signale les cas oubliés. C'est un concept venu des langages fonctionnels (types sommes + pattern matching) adopté par le typage moderne. A sum type, e.g. `{ ok: true; data: User } | { ok: false; error: string }`: the discriminant field forces the switch to handle every case and the compiler flags forgotten ones. It's a concept from functional languages (sum types + pattern matching) adopted by modern type systems.
QCM Quiz
Laquelle de ces fonctions est pure ? Which of these functions is pure?
Seule (x, rate) => x * rate ne dépend que de ses arguments et ne modifie rien. push mute l'argument, la variable globale est une dépendance cachée, Math.random() rend la sortie non déterministe. Only (x, rate) => x * rate depends solely on its arguments and modifies nothing. push mutates the argument, the global variable is a hidden dependency, Math.random() makes the output non-deterministic.
Quel est le principal reproche fait à l'héritage profond ? What is the main criticism of deep inheritance?
Le problème est le couplage fort et fragile : modifier la classe mère se propage à toutes les filles, et les hiérarchies profondes finissent par ne plus correspondre au domaine. D'où « composition > héritage ». The problem is strong, brittle coupling: changing the parent propagates to every child, and deep hierarchies eventually stop matching the domain. Hence "composition over inheritance".
Que vaut [1, 2, 3, 4].filter(n => n % 2 === 0).map(n => n * 10).reduce((s, n) => s + n, 0) ? What does [1, 2, 3, 4].filter(n => n % 2 === 0).map(n => n * 10).reduce((s, n) => s + n, 0) evaluate to?
filter garde [2, 4], map donne [20, 40], reduce additionne à partir de 0 : 60. Un pipeline se lit étape par étape, chaque sortie devient l'entrée suivante. filter keeps [2, 4], map yields [20, 40], reduce sums from 0: 60. A pipeline reads step by step, each output becoming the next input.
En JavaScript, que garantit exactement `const arr = [1, 2]` ? In JavaScript, what exactly does `const arr = [1, 2]` guarantee?
const interdit la réassignation (arr = autre), pas la mutation (arr.push marche). L'immutabilité de la valeur est une discipline : spread, readonly en TS, Object.freeze ou Immer. const forbids reassignment (arr = other), not mutation (arr.push works). Value immutability is a discipline: spread, readonly in TS, Object.freeze or Immer.
Où placer les effets de bord selon le pattern « functional core, imperative shell » ? Where do side effects go according to the "functional core, imperative shell" pattern?
Un programme sans aucun effet de bord ne ferait rien d'observable. L'idée n'est pas de les interdire mais de les repousser aux bords : le cœur pur se teste sans mock, la coquille en intégration. A program with zero side effects would do nothing observable. The idea is not to forbid them but to push them to the edges: the pure core tests without mocks, the shell in integration.
Pourquoi une fonction pure est-elle si facile à tester ? Why is a pure function so easy to test?
Rien d'extérieur n'entre en jeu (pas de DB, pas d'horloge, pas d'état global) : le test est un simple couple entrée/sortie, déterministe et indépendant de l'ordre d'exécution. Nothing external is involved (no DB, no clock, no global state): the test is a simple input/output pair, deterministic and independent of execution order.
Jour 52 Day 52 Gestion des secrets Secrets management
Flashcards Flashcards
Pourquoi un secret commité puis supprimé au commit suivant reste-t-il dangereux ? Why is a secret that was committed then deleted in the next commit still dangerous?
Git n'oublie rien : l'ancien blob reste dans l'historique, les reflogs, les forks et les clones existants (`git log -p` le retrouve). Le secret est considéré comme compromis dès le push : la seule réponse correcte est de le révoquer et d'en générer un nouveau. Git never forgets: the old blob stays in the history, reflogs, forks and existing clones (`git log -p` finds it). The secret is considered compromised as soon as it's pushed: the only correct response is to revoke it and generate a new one.
Quelles sont les limites des variables d'environnement pour stocker des secrets ? What are the limitations of environment variables for storing secrets?
Elles sont visibles dans `/proc/<pid>/environ` et via `ps e` pour les processus du même utilisateur, héritées par tous les processus enfants (y compris les scripts tiers), et finissent facilement dans les logs d'erreur et crash reports. Bon transport, mauvais stockage. They're visible in `/proc/<pid>/environ` and via `ps e` for same-user processes, inherited by every child process (including third-party scripts), and easily end up in error logs and crash reports. Good transport, bad storage.
À quoi sert le fichier .env.example et pourquoi est-il versionné ? What is the .env.example file for and why is it versioned?
Il documente les NOMS des variables attendues avec des valeurs bidon : c'est le contrat de configuration. Versionné, il permet à un nouveau dev de faire `cp .env.example .env` et de remplir — sans lui, quelqu'un finira par commiter le vrai .env. It documents the NAMES of the expected variables with dummy values: it's the configuration contract. Versioned, it lets a new dev run `cp .env.example .env` and fill it in — without it, someone eventually commits the real .env.
Quelle est la procédure correcte quand un secret fuite, dans l'ordre ? What is the correct procedure when a secret leaks, in order?
1) Révoquer/rotater le secret immédiatement (stoppe l'hémorragie), 2) vérifier les logs d'accès pour évaluer l'exploitation, 3) nettoyer l'historique git (git filter-repo) et forcer le push, 4) ajouter un garde-fou (gitleaks en pre-commit). Nettoyer sans révoquer ne sert à rien. 1) Revoke/rotate the secret immediately (stops the bleeding), 2) check access logs to assess exploitation, 3) clean the git history (git filter-repo) and force-push, 4) add a guardrail (gitleaks in pre-commit). Cleaning without revoking is pointless.
Qu'est-ce que le principe du moindre privilège appliqué aux secrets ? What is the principle of least privilege applied to secrets?
Chaque token ou clé n'a que les droits strictement nécessaires à sa fonction : la clé du service de mails ne peut pas toucher au stockage. En cas de fuite, les dégâts sont proportionnels aux droits accordés — un scope minimal limite l'incident. Each token or key gets only the rights strictly needed for its job: the email service's key can't touch storage. If it leaks, the damage is proportional to the rights granted — a minimal scope contains the incident.
Qu'est-ce que gitleaks et où le brancher ? What is gitleaks and where do you wire it?
Un scanner de secrets qui détecte les patterns connus (clés AWS, tokens GitHub) et les chaînes à forte entropie. On le branche en hook pre-commit — le seul moment où bloquer est encore gratuit, avant que le secret n'entre dans l'historique — et en CI comme filet. A secret scanner that detects known patterns (AWS keys, GitHub tokens) and high-entropy strings. You wire it as a pre-commit hook — the only moment when blocking is still free, before the secret enters the history — and in CI as a safety net.
Comment les secrets sont-ils gérés dans une CI comme GitHub Actions ? How are secrets handled in a CI like GitHub Actions?
Via le store de secrets chiffrés du repo/org, référencés par `${{ secrets.MY_KEY }}`, injectés en variables d'environnement au run et masqués dans les logs (***). Jamais en clair dans le YAML. Le masquage est un filet : un base64 le contourne. Through the repo/org encrypted secrets store, referenced with `${{ secrets.MY_KEY }}`, injected as environment variables at run time and masked in the logs (***). Never in plain text in the YAML. Masking is a net: base64 bypasses it.
Pourquoi une variable NEXT_PUBLIC_* ou VITE_* ne peut-elle jamais être un secret ? Why can a NEXT_PUBLIC_* or VITE_* variable never be a secret?
Ces variables sont intégrées au bundle JavaScript envoyé au navigateur : tout ce qui part côté client est public par définition. Un appel nécessitant une vraie clé secrète doit passer par le backend, qui garde la clé côté serveur. These variables are baked into the JavaScript bundle sent to the browser: anything shipped client-side is public by definition. A call requiring a real secret key must go through the backend, which keeps the key server-side.
QCM Quiz
Un secret a été poussé sur GitHub il y a 5 minutes. Quelle est la PREMIÈRE action ? A secret was pushed to GitHub 5 minutes ago. What is the FIRST action?
Le secret est déjà compromis (des bots scannent les commits publics en continu) : révoquer d'abord, c'est ce qui stoppe l'exploitation. Le nettoyage d'historique vient ensuite. The secret is already compromised (bots scan public commits continuously): revoke first, that's what stops exploitation. History cleanup comes after.
Que doit contenir un fichier .env.example ? What should a .env.example file contain?
Le .env.example est versionné : il documente le contrat de configuration (les noms) sans jamais exposer de valeur réelle. Les vraies valeurs vivent dans le .env gitignoré. The .env.example is versioned: it documents the configuration contract (the names) without ever exposing a real value. Real values live in the gitignored .env.
Pourquoi le masquage des secrets dans les logs CI n'est-il pas une protection suffisante ? Why is secret masking in CI logs not sufficient protection?
Le masquage remplace la chaîne exacte par *** : `echo $KEY | base64` ressort en clair. C'est un filet contre les accidents, pas une barrière contre l'exfiltration. Masking replaces the exact string with ***: `echo $KEY | base64` prints in the clear. It's a net against accidents, not a barrier against exfiltration.
Quel outil permet de versionner des fichiers de secrets CHIFFRÉS dans le repo ? Which tool lets you version ENCRYPTED secret files inside the repo?
sops (Mozilla) chiffre les valeurs d'un fichier YAML/JSON/env avec une clé externe (age, KMS) : le fichier chiffré peut être commité. gitleaks scanne, dotenv charge un .env en clair. sops (Mozilla) encrypts the values of a YAML/JSON/env file with an external key (age, KMS): the encrypted file can be committed. gitleaks scans, dotenv loads a plaintext .env.
Pourquoi un `COPY .env` dans un Dockerfile est-il un problème même si le fichier est supprimé dans une instruction suivante ? Why is a `COPY .env` in a Dockerfile a problem even if the file is deleted in a later instruction?
Comme git, les couches d'image gardent l'historique : `docker history` et l'inspection des couches retrouvent le fichier. Utiliser les secrets de build (--secret) ou l'injection au runtime. Like git, image layers keep history: `docker history` and layer inspection recover the file. Use build secrets (--secret) or runtime injection.
Quel est l'intérêt principal d'un secrets manager (Vault, AWS Secrets Manager) par rapport à un fichier .env sur le serveur ? What is the main advantage of a secrets manager (Vault, AWS Secrets Manager) over a .env file on the server?
Un .env sur le serveur n'est ni chiffré, ni audité, ni rotaté. Le coffre ajoute ces trois garanties — et sait souvent injecter les secrets en env vars au démarrage de l'app. A .env on the server is neither encrypted, audited, nor rotated. The vault adds those three guarantees — and often injects secrets as env vars at app startup.
Jour 51 Day 51 Web performance & caching Web performance & caching
Flashcards Flashcards
Que mesurent les trois Core Web Vitals ? What do the three Core Web Vitals measure?
LCP (Largest Contentful Paint, < 2,5 s) : le temps d'affichage du plus gros élément visible — le chargement perçu. INP (Interaction to Next Paint, < 200 ms) : la réactivité aux interactions. CLS (Cumulative Layout Shift, < 0,1) : la stabilité visuelle (les éléments qui se décalent). Elles comptent aussi pour le SEO. LCP (Largest Contentful Paint, < 2.5 s): render time of the largest visible element — perceived loading. INP (Interaction to Next Paint, < 200 ms): responsiveness to interactions. CLS (Cumulative Layout Shift, < 0.1): visual stability (elements shifting around). They also count for SEO.
Quelle est la différence entre Cache-Control: no-cache et no-store ? What is the difference between Cache-Control: no-cache and no-store?
no-cache autorise le stockage mais impose une revalidation à chaque utilisation (requête conditionnelle ETag → 304 si inchangé). no-store interdit tout stockage — pour les données sensibles. Le piège d'entretien classique : no-cache ne veut PAS dire « ne pas cacher ». no-cache allows storage but forces revalidation on every use (conditional ETag request → 304 if unchanged). no-store forbids any storage — for sensitive data. The classic interview trap: no-cache does NOT mean "don't cache".
Comment fonctionne la revalidation avec ETag et 304 ? How does revalidation with ETag and 304 work?
Le serveur envoie un ETag (empreinte du contenu) avec la ressource. Quand elle est périmée ou en no-cache, le navigateur renvoie If-None-Match: <etag>. Si le contenu n'a pas changé, le serveur répond 304 Not Modified sans corps : le navigateur garde sa copie. On paie un aller-retour, pas le transfert. The server sends an ETag (a fingerprint of the content) with the resource. When it's stale or under no-cache, the browser sends If-None-Match: <etag>. If the content hasn't changed, the server answers 304 Not Modified with no body: the browser keeps its copy. You pay a round trip, not the transfer.
Décris la stratégie de cache « deux vitesses » d'une SPA moderne. Describe the "two-speed" cache strategy of a modern SPA.
HTML en no-cache (+ ETag) : revalidé à chaque visite, jamais périmé. Assets buildés avec un hash du contenu dans le nom (app.9f3ab2.js) en public, max-age=31536000, immutable : cachés un an sans revalidation. Un déploiement change le hash → nouvelle URL référencée par le HTML frais. On n'invalide jamais : on change d'URL. HTML on no-cache (+ ETag): revalidated on every visit, never stale. Built assets with a content hash in the name (app.9f3ab2.js) on public, max-age=31536000, immutable: cached one year with no revalidation. A deploy changes the hash → new URL referenced by the fresh HTML. You never invalidate: you change the URL.
Quels leviers pour alléger les images d'une page ? What levers shrink a page's images?
Formats modernes (WebP/AVIF : 30-50 % plus légers que JPEG), loading="lazy" natif sous la ligne de flottaison (jamais sur l'image LCP), srcset/sizes pour servir la bonne résolution par écran, et width/height ou aspect-ratio systématiques pour réserver l'espace et éviter le CLS. Modern formats (WebP/AVIF: 30-50% lighter than JPEG), native loading="lazy" below the fold (never on the LCP image), srcset/sizes to serve the right resolution per screen, and systematic width/height or aspect-ratio to reserve space and avoid CLS.
Code splitting, tree shaking, defer : à quoi sert chacun ? Code splitting, tree shaking, defer: what does each do?
Code splitting : découper le bundle (par route, imports dynamiques) pour ne charger que le nécessaire. Tree shaking : éliminer au build le code jamais importé. defer : télécharger le script en parallèle mais l'exécuter après le parsing du HTML, sans bloquer le rendu. Les trois réduisent le coût du JS — téléchargement ET exécution sur le main thread. Code splitting: cutting the bundle (per route, dynamic imports) to load only what's needed. Tree shaking: removing never-imported code at build time. defer: downloading the script in parallel but executing it after HTML parsing, without blocking rendering. All three reduce JS cost — download AND main-thread execution.
Comment optimiser le chargement des webfonts ? How do you optimize webfont loading?
font-display: swap pour afficher le texte immédiatement en police système (petit swap visuel plutôt que texte invisible), <link rel="preload"> pour charger tôt la font critique, self-host pour éviter DNS + connexion vers un domaine tiers, et limiter les variantes (chaque graisse est un fichier à télécharger). font-display: swap to show text immediately in a system font (a small visual swap rather than invisible text), <link rel="preload"> to load the critical font early, self-hosting to avoid DNS + a third-party connection, and limiting variants (every weight is a file to download).
Quel est le rôle d'un CDN et de s-maxage ? What is the role of a CDN and of s-maxage?
Le CDN place des serveurs edge près des utilisateurs : ils cachent les réponses de l'origin et coupent la latence géographique (plus absorption des pics et protection de l'origin). s-maxage est le max-age spécifique aux caches partagés : il permet un cache CDN différent du cache navigateur (ex. s-maxage=600 au CDN, no-cache au navigateur). A CDN places edge servers near users: they cache origin responses and cut geographic latency (plus spike absorption and origin shielding). s-maxage is the max-age specific to shared caches: it allows a CDN cache different from the browser cache (e.g. s-maxage=600 at the CDN, no-cache in the browser).
QCM Quiz
Que signifie Cache-Control: no-cache ? What does Cache-Control: no-cache mean?
no-cache = « stocke, mais revérifie » : requête conditionnelle avec ETag, réponse 304 si inchangé. C'est no-store qui interdit le stockage. Question piège d'entretien par excellence. no-cache = "store, but re-check": a conditional request with the ETag, a 304 answer if unchanged. It's no-store that forbids storage. The quintessential interview trick question.
Que contient une réponse 304 Not Modified ? What does a 304 Not Modified response contain?
Le 304 répond à une requête conditionnelle (If-None-Match) : « ta copie est encore bonne ». Pas de corps transféré — on paie l'aller-retour réseau, pas le poids de la ressource. The 304 answers a conditional request (If-None-Match): "your copy is still good". No body transferred — you pay the network round trip, not the resource's weight.
Pourquoi peut-on mettre max-age=31536000, immutable sur app.9f3ab2.js sans risque ? Why is max-age=31536000, immutable safe on app.9f3ab2.js?
L'URL EST le contenu : un nouveau build produit un nouveau hash, donc une nouvelle URL, référencée par un HTML toujours revalidé (no-cache). L'ancienne version peut rester cachée un an, plus personne ne la demande. The URL IS the content: a new build produces a new hash, hence a new URL, referenced by an always-revalidated HTML (no-cache). The old version can stay cached for a year — nobody asks for it anymore.
Quelle erreur dégrade directement le LCP ? Which mistake directly degrades LCP?
Lazy-loader l'image LCP retarde exactement l'élément mesuré : le navigateur attend au lieu de la charger en priorité. Sur l'image hero : pas de lazy, et plutôt fetchpriority="high". Le lazy loading, c'est pour sous la ligne de flottaison. Lazy-loading the LCP image delays exactly the measured element: the browser waits instead of loading it with priority. On the hero image: no lazy, rather fetchpriority="high". Lazy loading is for below the fold.
Quelle métrique se dégrade quand le main thread est saturé de JavaScript ? Which metric degrades when the main thread is saturated with JavaScript?
INP mesure le délai entre une interaction et le prochain rendu : si le main thread exécute du JS, le clic attend. Remèdes : code splitting, tree shaking, defer, déplacer le lourd hors du main thread (workers). INP measures the delay between an interaction and the next paint: if the main thread is running JS, the click waits. Remedies: code splitting, tree shaking, defer, moving heavy work off the main thread (workers).
« Le site est lent. » Quelle est la première action correcte ? "The site is slow." What is the correct first move?
Mesurer avant d'optimiser : identifier le goulot dominant (image LCP ? bundle JS ? absence de cache ?), le traiter, re-mesurer. Optimiser à l'aveugle, c'est minifier 10 Ko de CSS pendant qu'une image de 4 Mo plombe le LCP. Measure before optimizing: identify the dominant bottleneck (LCP image? JS bundle? no caching?), fix it, re-measure. Optimizing blind is minifying 10 KB of CSS while a 4 MB image sinks the LCP.
Jour 50 Day 50 Robustesse : timeouts, retries & circuit breakers Robustness: timeouts, retries & circuit breakers
Flashcards Flashcards
Pourquoi faut-il un timeout sur chaque appel réseau ? Why does every network call need a timeout?
Parce qu'un appel peut ne jamais répondre : sans timeout, le thread ou la connexion de pool qui attend est bloqué indéfiniment. Sous charge, ces attentes s'accumulent et épuisent les ressources du service appelant — la panne de la dépendance devient la vôtre. Un appel sans timeout est une fuite de ressources en puissance. Because a call may never answer: without a timeout, the waiting thread or pool connection is blocked indefinitely. Under load, these waits pile up and exhaust the caller's resources — the dependency's outage becomes yours. A call without a timeout is a resource leak waiting to happen.
Qu'est-ce que le budget de latence en cascade ? What is the cascading latency budget?
Dans une chaîne A → B → C, les timeouts doivent décroître : si A accorde 2 s à B, B doit accorder moins (ex. 1,5 s) à C, sinon B répond après que A a abandonné — travail gaspillé et erreurs incohérentes. On découpe le SLO de bout en bout en budgets par étage, chacun avec une marge. In a chain A → B → C, timeouts must decrease: if A gives B 2 s, B must give C less (e.g. 1.5 s), otherwise B answers after A has given up — wasted work and inconsistent errors. The end-to-end SLO is split into per-tier budgets, each with a margin.
Pourquoi ajouter du jitter à l'exponential backoff ? Why add jitter to exponential backoff?
Sans jitter, tous les clients tombés au même moment réessaient exactement aux mêmes instants (1 s, 2 s, 4 s…) : des vagues synchronisées frappent le service pendant qu'il tente de se relever. Le jitter (délai aléatoire, ex. full jitter : uniforme entre 0 et le plafond) étale les tentatives et casse la synchronisation. Without jitter, all clients that failed at the same moment retry at exactly the same instants (1 s, 2 s, 4 s…): synchronized waves hit the service while it tries to recover. Jitter (random delay, e.g. full jitter: uniform between 0 and the cap) spreads attempts out and breaks the synchronization.
Pourquoi retry une requête non idempotente est-il dangereux ? Why is retrying a non-idempotent request dangerous?
Parce qu'un échec apparent peut être un succès dont la réponse s'est perdue : rejouer un POST /payments dans ce cas crée un paiement en double. Solution : les idempotency keys — le client joint un identifiant unique, le serveur détecte le rejeu et renvoie la réponse originale au lieu de ré-exécuter. Because an apparent failure may be a success whose response got lost: replaying a POST /payments in that case creates a double charge. Solution: idempotency keys — the client attaches a unique identifier, the server detects the replay and returns the original response instead of re-executing.
Décris les trois états d'un circuit breaker. Describe the three states of a circuit breaker.
Closed : les appels passent, les échecs sont comptés. Open (déclenché quand les échecs dépassent un seuil) : échec immédiat sans appeler le service, pendant un délai de repos. Half-open (après ce délai) : quelques appels de sonde passent ; s'ils réussissent → closed, s'ils échouent → open. But : laisser récupérer le service aval et échouer vite côté appelant. Closed: calls pass, failures are counted. Open (triggered when failures exceed a threshold): instant failure without calling the service, for a cool-down period. Half-open (after that delay): a few probe calls pass; if they succeed → closed, if they fail → open. Goal: let the downstream service recover and fail fast on the caller side.
Qu'est-ce que le pattern bulkhead ? What is the bulkhead pattern?
Cloisonner les ressources par dépendance, comme les compartiments étanches d'un navire : pools de connexions/threads séparés, quotas. Si une dépendance devient lente, elle sature son propre pool (ex. 10 connexions) sans épuiser les ressources globales du service — la panne reste contenue. Partitioning resources per dependency, like a ship's watertight compartments: separate connection/thread pools, quotas. If a dependency turns slow, it saturates its own pool (e.g. 10 connections) without exhausting the service's global resources — the failure stays contained.
Liveness vs readiness : quelle différence et pourquoi c'est important ? Liveness vs readiness: what's the difference and why does it matter?
Liveness : « le process tourne-t-il ? » — en cas d'échec, on le redémarre. Readiness : « peut-il servir du trafic ? » — en cas d'échec, on le retire du load balancer sans le tuer. Les confondre provoque des redémarrages en boucle quand une dépendance est juste lente ; et un readiness check qui teste les dépendances peut sortir toutes les instances du LB d'un coup. Liveness: "is the process running?" — on failure, restart it. Readiness: "can it serve traffic?" — on failure, pull it from the load balancer without killing it. Confusing them causes restart loops when a dependency is merely slow; and a readiness check that tests dependencies can pull every instance from the LB at once.
Qu'est-ce que le thundering herd et comment s'en protéger ? What is the thundering herd and how do you defend against it?
Une masse de clients (ou d'entrées de cache expirant ensemble) frappe l'origine au même instant — au redémarrage d'un service ou à l'expiration d'un cache populaire. Parades : jitter sur les TTL et les reconnexions, request coalescing (une seule requête régénère le cache, les autres attendent le résultat), warm-up progressif du trafic. A mass of clients (or cache entries expiring together) hits the origin at the same instant — on a service restart or a popular cache expiry. Countermeasures: jitter on TTLs and reconnections, request coalescing (a single request regenerates the cache, the others wait for the result), progressive traffic warm-up.
QCM Quiz
Quel est le rôle principal d'un circuit breaker ? What is the main role of a circuit breaker?
Le breaker ne réessaie rien — c'est l'inverse : il coupe les appels vers un service à terre pour le laisser récupérer et libérer les ressources de l'appelant. Le retry gère les blips transitoires ; le breaker, les pannes durables. The breaker retries nothing — quite the opposite: it cuts calls to a downed service so it can recover and the caller's resources are freed. Retry handles transient blips; the breaker, lasting outages.
Dans une chaîne A → B → C, A donne 2 s de timeout à B. Quel timeout B doit-il donner à C ? In a chain A → B → C, A gives B a 2 s timeout. What timeout should B give C?
Les timeouts décroissent en cascade : si B attend C plus longtemps que A n'attend B, B finira son travail pour un appelant déjà parti. On raisonne en budget de latence, chaque étage gardant une marge pour son propre traitement. Timeouts decrease down the cascade: if B waits on C longer than A waits on B, B finishes work for a caller that's already gone. Think latency budget, each tier keeping a margin for its own processing.
Quelle requête est une bonne candidate au retry automatique ? Which request is a good candidate for automatic retry?
On ne retry que le transitoire (503, timeout, connexion reset) ET le sûr (GET est idempotent). Un 404 ou un 400 donneront le même résultat à chaque rejeu ; un POST de paiement sans idempotency key risque le paiement en double. Only retry the transient (503, timeout, connection reset) AND the safe (GET is idempotent). A 404 or 400 will yield the same result every replay; a payment POST without an idempotency key risks a double charge.
Qu'est-ce qu'un retry storm ? What is a retry storm?
Service lent → timeouts → chaque client retry 3× → trafic ×3-4 au pire moment → effondrement, et chaque instance qui redémarre est saturée instantanément. Parades : retry budget, circuit breakers, backoff + jitter, load shedding. Slow service → timeouts → each client retries 3× → traffic ×3-4 at the worst moment → collapse, and every restarting instance is instantly saturated. Countermeasures: retry budget, circuit breakers, backoff + jitter, load shedding.
Le service de recommandations est mort. Quelle est la meilleure réponse côté page produit ? The recommendations service is dead. What's the best response on the product page?
Graceful degradation : une page 90 % fonctionnelle vaut mieux qu'un 500 ou qu'une attente interminable. Le fallback (contenu statique, cache stale) se prévoit par feature, avec un timeout court sur la dépendance non critique. Graceful degradation: a 90%-functional page beats a 500 or an endless wait. The fallback (static content, stale cache) is planned per feature, with a short timeout on the non-critical dependency.
Un client HTTP retry 3×, le service appelant retry 3×, la gateway retry 3×. Combien d'appels au maximum pour une requête ? An HTTP client retries 3×, the calling service retries 3×, the gateway retries 3×. How many calls at most for one request?
Les retries se multiplient à chaque étage : 3 × 3 × 3 = 27 appels potentiels pour une seule requête utilisateur — un amplificateur de panne. Règle : un seul étage est propriétaire du retry, les autres échouent vite. Retries multiply at every tier: 3 × 3 × 3 = 27 potential calls for a single user request — an outage amplifier. Rule: one tier owns the retry, the others fail fast.
Jour 49 Day 49 Garbage collection & gestion mémoire Garbage collection & memory management
Flashcards Flashcards
Quelle est la différence entre la stack et le heap ? What is the difference between the stack and the heap?
La stack stocke les frames d'appel et les variables locales, allouées/libérées automatiquement par déplacement d'un pointeur (rapide, une stack par thread, durée de vie liée à la fonction). Le heap stocke les objets à durée de vie arbitraire, partagé entre threads, géré par un allocateur et un GC (ou manuellement en C). The stack holds call frames and local variables, allocated/freed automatically by moving a pointer (fast, one stack per thread, lifetime tied to the function). The heap holds objects with arbitrary lifetimes, shared between threads, managed by an allocator and a GC (or manually in C).
Quel problème fondamental un garbage collector résout-il ? What fundamental problem does a garbage collector solve?
Savoir quand libérer un objet du heap : un objet ne peut être libéré que quand plus personne ne peut y accéder. Le GC détecte automatiquement les objets inaccessibles depuis les racines (stack, globals) et récupère leur mémoire, éliminant use-after-free, double free et libérations oubliées. Knowing when to free a heap object: an object can only be freed when nobody can reach it anymore. The GC automatically detects objects unreachable from the roots (stack, globals) and reclaims their memory, eliminating use-after-free, double free and forgotten releases.
Pourquoi le reference counting ne suffit-il pas seul ? Why is reference counting not enough on its own?
À cause des cycles : deux objets qui se référencent mutuellement gardent chacun un compteur ≥ 1, même devenus inaccessibles — ils ne sont jamais libérés. Il faut un mécanisme complémentaire : détecteur de cycles (CPython) ou weak references (Swift/ARC). Because of cycles: two objects referencing each other each keep a counter ≥ 1, even once unreachable — they are never freed. A complementary mechanism is needed: a cycle detector (CPython) or weak references (Swift/ARC).
Comment fonctionne un GC mark & sweep ? How does a mark & sweep GC work?
Phase mark : depuis les racines (stack, globals, registres), on suit récursivement toutes les références et on marque chaque objet atteint. Phase sweep : tout objet non marqué est libéré. Les cycles inaccessibles sont collectés naturellement puisque personne ne les marque. Souvent complété par une compaction pour défragmenter. Mark phase: from the roots (stack, globals, registers), recursively follow all references and mark every reached object. Sweep phase: every unmarked object is freed. Unreachable cycles are collected naturally since nobody marks them. Often complemented by compaction to defragment.
Qu'est-ce que l'hypothèse générationnelle et comment les GC l'exploitent-ils ? What is the generational hypothesis and how do GCs exploit it?
L'observation empirique que la plupart des objets meurent jeunes (temporaires, objets d'une requête). Les GC séparent donc le heap : une young generation collectée souvent et vite (minor GC — seuls les rares survivants sont copiés), et une old generation collectée rarement (major/full GC, plus coûteux). C'est le design de V8 et de la JVM. The empirical observation that most objects die young (temporaries, per-request objects). GCs therefore split the heap: a young generation collected often and fast (minor GC — only the few survivors are copied), and an old generation collected rarely (major/full GC, more expensive). That's the design of V8 and the JVM.
Cite quatre causes classiques de fuite mémoire dans un langage à GC. Name four classic causes of memory leaks in a GC'd language.
1) Listeners jamais retirés (l'emitter garde une référence vers le callback et tout son scope capturé). 2) Caches sans borne (Map qui grossit indéfiniment — penser WeakMap ou éviction LRU). 3) Closures qui capturent de gros objets. 4) Variables globales qui accumulent. Dans tous les cas : l'objet reste accessible, donc incollectable. 1) Listeners never removed (the emitter keeps a reference to the callback and its whole captured scope). 2) Unbounded caches (a Map growing forever — think WeakMap or LRU eviction). 3) Closures capturing large objects. 4) Global variables that accumulate. In every case: the object stays reachable, hence uncollectable.
Comment diagnostiquer une fuite mémoire dans une app JavaScript ? How do you diagnose a memory leak in a JavaScript app?
Symptôme : mémoire en marches d'escalier qui ne redescend pas après GC. Méthode : heap snapshots (DevTools → Memory) avant/après le scénario suspect, comparer, trier par retained size, puis remonter la chaîne des retainers jusqu'à la référence coupable (souvent un listener ou un cache). Sur Node : --inspect + Chrome DevTools. Symptom: staircase-shaped memory that never comes down after GC. Method: heap snapshots (DevTools → Memory) before/after the suspect scenario, compare, sort by retained size, then walk the retainers chain up to the guilty reference (often a listener or a cache). On Node: --inspect + Chrome DevTools.
Comment Rust garantit-il la sécurité mémoire sans garbage collector ? How does Rust guarantee memory safety without a garbage collector?
Par l'ownership : chaque valeur a un propriétaire unique et sa libération est insérée à la compilation quand le propriétaire sort du scope. Le borrow checker vérifie statiquement qu'aucune référence ne survit à la valeur qu'elle pointe. Résultat : ni GC ni pauses, sécurité mémoire prouvée à la compilation. Through ownership: every value has a single owner and its release is inserted at compile time when the owner goes out of scope. The borrow checker statically verifies that no reference outlives the value it points to. Result: no GC, no pauses, memory safety proven at compile time.
QCM Quiz
Quel type d'objet un garbage collector peut-il libérer ? Which objects can a garbage collector free?
Le seul critère est l'accessibilité : aucun chemin de références depuis une racine. Un objet inutilisé mais encore référencé reste incollectable — c'est exactement ce qui rend les fuites possibles malgré le GC. The only criterion is reachability: no reference path from any root. An unused but still-referenced object stays uncollectable — exactly what makes leaks possible despite the GC.
Pourquoi deux objets qui se référencent mutuellement posent-ils problème au reference counting ? Why do two objects referencing each other break reference counting?
Chacun maintient le compteur de l'autre à ≥ 1, même quand le cycle devient inaccessible de l'extérieur. Un GC traçant, lui, les collecte : personne ne les marque depuis les racines. Each keeps the other's counter at ≥ 1, even when the cycle becomes unreachable from outside. A tracing GC does collect them: nothing marks them from the roots.
Qu'est-ce qu'une pause « stop-the-world » ? What is a "stop-the-world" pause?
Pour marquer un graphe cohérent, le GC doit figer le programme. Les GC modernes (ZGC, GC incrémental de V8) rendent l'essentiel du travail concurrent pour réduire ces pauses à quelques ms, sans les éliminer totalement. To mark a consistent graph, the GC must freeze the program. Modern GCs (ZGC, V8's incremental GC) make most of the work concurrent to shrink these pauses to a few ms, without fully eliminating them.
Pourquoi un minor GC sur la young generation est-il si rapide ? Why is a minor GC on the young generation so fast?
C'est l'hypothèse générationnelle : la plupart des objets meurent jeunes. Le coût d'un GC copiant dépend des survivants, pas des morts — une young gen presque vide de vivants se collecte en un éclair. That's the generational hypothesis: most objects die young. A copying GC's cost depends on survivors, not corpses — a young gen with few live objects collects in a flash.
Une SPA fuit : la mémoire monte à chaque navigation. Quel est le premier réflexe ? A SPA leaks: memory grows on every navigation. What's the first move?
Mesurer avant de corriger : snapshot avant/après le scénario, comparaison, retained size, puis remonter les retainers jusqu'à la référence coupable (souvent un listener jamais retiré). Forcer le GC ou augmenter la limite ne fait que masquer. Measure before fixing: snapshot before/after the scenario, compare, retained size, then walk the retainers to the guilty reference (often a never-removed listener). Forcing GC or raising limits only hides it.
Que garantit l'ownership de Rust par rapport à un langage à GC ? What does Rust's ownership guarantee compared to a GC'd language?
La libération est décidée à la compilation (sortie de scope du propriétaire unique), vérifiée par le borrow checker : pas de runtime GC, pas de pause. Mais on peut toujours fuir logiquement (Rc cyclique, Vec qui grossit sans fin). Release is decided at compile time (the single owner going out of scope), verified by the borrow checker: no GC runtime, no pauses. But you can still leak logically (cyclic Rc, an endlessly growing Vec).
Jour 48 Day 48 Agents, function calling & prompt engineering Agents, function calling & prompt engineering
Flashcards Flashcards
Qu'est-ce que le function calling ? What is function calling?
Un mécanisme où l'on décrit des outils au modèle (nom, description, JSON schema) ; le modèle peut alors répondre par un appel structuré (nom + paramètres JSON) au lieu de prose. Le code applicatif valide, exécute la vraie fonction et renvoie le résultat au modèle — le modèle n'exécute jamais rien lui-même. A mechanism where tools are described to the model (name, description, JSON schema); the model can then reply with a structured call (name + JSON parameters) instead of prose. The application code validates, executes the real function and returns the result to the model — the model never executes anything itself.
Décris la boucle agentique. Describe the agentic loop.
Objectif → le LLM raisonne et choisit un outil → le code exécute l'appel → le résultat (observation) est réinjecté dans le contexte → le modèle raisonne à nouveau, jusqu'à la réponse finale ou une limite (itérations, budget). Tout l'historique est renvoyé à chaque tour. Goal → the LLM reasons and picks a tool → the code executes the call → the result (observation) is fed back into the context → the model reasons again, until a final answer or a limit (iterations, budget). The whole history is resent every turn.
Pourquoi dit-on que la description d'un outil est du prompt engineering ? Why do we say a tool's description is prompt engineering?
C'est la description que le modèle lit pour décider quand et comment utiliser l'outil. Une bonne description précise quand l'utiliser, quand ne pas l'utiliser, ce que l'outil retourne et ses limites. La plupart des mauvais choix d'outil viennent d'une description floue, pas du modèle. The description is what the model reads to decide when and how to use the tool. A good one states when to use it, when not to, what it returns and its limits. Most wrong tool choices come from a fuzzy description, not from the model.
Quels sont les quatre leviers d'un prompt sérieux ? What are the four levers of a serious prompt?
Un rôle clair (« tu es un agent support de X »), des contraintes explicites (format, longueur, interdits), des exemples few-shot (2-3 paires entrée/sortie), et une sortie structurée (JSON conforme à un schéma) exploitable par un programme. Pas d'« astuces magiques » : elles ne survivent pas au changement de modèle. A clear role ("you are a support agent for X"), explicit constraints (format, length, prohibitions), few-shot examples (2-3 input/output pairs), and structured output (JSON conforming to a schema) usable by a program. No "magic tricks": they don't survive a model change.
Quel problème MCP résout-il pour les agents ? What problem does MCP solve for agents?
L'intégration N outils × M applications : sans standard, chaque app re-code chaque connexion. MCP (Model Context Protocol) standardise l'exposition d'outils et de ressources via un protocole client/serveur : un serveur MCP écrit une fois est utilisable par tout client compatible. The N tools × M applications integration problem: without a standard, every app re-codes every connection. MCP (Model Context Protocol) standardizes exposing tools and resources through a client/server protocol: an MCP server written once is usable by any compatible client.
Cite trois modes d'échec classiques d'un agent. Name three classic agent failure modes.
1) La boucle infinie : l'agent réessaie sans fin un appel qui échoue. 2) L'hallucination d'outil : appel d'un outil inexistant ou paramètres inventés. 3) L'explosion des coûts : l'historique complet repart à chaque tour, donc un agent qui boucle consomme le contexte à répétition. 1) The infinite loop: the agent endlessly retries a failing call. 2) Tool hallucination: calling a nonexistent tool or inventing parameters. 3) Cost explosion: the full history is resent every turn, so a looping agent consumes the context repeatedly.
Qu'est-ce que la prompt injection et pourquoi est-ce grave pour un agent ? What is prompt injection and why is it serious for an agent?
Du contenu externe lu par l'agent (page web, email, ticket) qui contient des instructions détournant le modèle (« ignore tes consignes et… »). Grave car l'agent a des outils : l'injection peut déclencher des actions réelles (exfiltration, suppression). Pas de correctif définitif — mitigations : moindre privilège, validation humaine, séparer données et instructions. External content read by the agent (web page, email, ticket) containing instructions that hijack the model ("ignore your instructions and…"). Serious because the agent has tools: the injection can trigger real actions (exfiltration, deletion). No definitive fix — mitigations: least privilege, human approval, separating data from instructions.
Quels garde-fous mettre sur un agent en production ? What guardrails should a production agent have?
Limite dure d'itérations et budget de tokens, timeouts sur les outils, validation stricte des paramètres contre le schéma, permissions graduées par outil (lecture libre, écriture sur validation), humain dans la boucle pour les actions irréversibles, et logs de chaque appel d'outil pour l'observabilité. A hard iteration limit and token budget, timeouts on tools, strict parameter validation against the schema, graduated per-tool permissions (free reads, writes behind approval), a human in the loop for irreversible actions, and logs of every tool call for observability.
QCM Quiz
Quand un modèle « appelle » une fonction via le function calling, que se passe-t-il réellement ? When a model "calls" a function via function calling, what actually happens?
Le modèle ne fait qu'émettre une intention structurée (nom + paramètres). L'exécution, la validation et les permissions restent entièrement côté application. The model only emits a structured intent (name + parameters). Execution, validation and permissions stay entirely on the application side.
Qu'est-ce qui transforme un simple appel LLM en agent ? What turns a plain LLM call into an agent?
Un agent, c'est un LLM dans une boucle avec des outils : il choisit dynamiquement les étapes en fonction des observations, là où un pipeline classique fixe le chemin à l'avance. An agent is an LLM in a loop with tools: it dynamically picks its steps based on observations, whereas a classic pipeline fixes the path in advance.
Un agent choisit systématiquement le mauvais outil. Quelle est la cause la plus probable ? An agent consistently picks the wrong tool. What is the most likely cause?
La description est ce que le modèle lit pour choisir : si deux outils se ressemblent ou qu'une description ne dit pas quand ne PAS l'utiliser, le choix se dégrade. C'est un problème de prompt engineering, pas de modèle. The description is what the model reads to choose: if two tools look alike or a description doesn't say when NOT to use it, the choice degrades. It's a prompt engineering problem, not a model problem.
Pourquoi un agent qui boucle 50 fois coûte-t-il si cher ? Why does an agent looping 50 times cost so much?
À chaque tour, tout le contexte (objectif + appels + observations) repart en entrée. 50 tours = 50 fois un contexte qui grossit. D'où les limites d'itérations et le prompt caching. Every turn, the whole context (goal + calls + observations) is sent again as input. 50 turns = 50 times a growing context. Hence iteration limits and prompt caching.
Quelle combinaison rend une attaque par prompt injection vraiment dangereuse ? Which combination makes a prompt injection attack truly dangerous?
C'est la « triple létale » : si l'agent lit du contenu attaquable, touche des données sensibles ET peut envoyer quelque chose vers l'extérieur, une injection peut exfiltrer. Retirer un des trois casse l'attaque. That's the "lethal trifecta": if the agent reads attackable content, touches sensitive data AND can send something out, an injection can exfiltrate. Removing any of the three breaks the attack.
Quel levier de prompt engineering est le plus efficace pour obtenir un format de sortie précis ? Which prompt engineering lever works best for getting a precise output format?
Montrer 2-3 exemples entrée → sortie et imposer un schéma (JSON schema, balises) est reproductible d'un modèle à l'autre. Les « astuces magiques », elles, vieillissent mal. Showing 2-3 input → output examples and enforcing a schema (JSON schema, tags) is reproducible across models. "Magic tricks" age badly.
Jour 47 Day 47 CSS moderne & accessibilité Modern CSS & accessibility
Flashcards Flashcards
Comment se calcule la spécificité CSS ? How is CSS specificity calculated?
Un triplet (id, classes/attributs/pseudo-classes, éléments/pseudo-éléments) comparé de gauche à droite : (1,0,0) bat (0,15,3) — un id bat n'importe quel nombre de classes. À égalité exacte, la dernière règle déclarée gagne. L'inline surclasse tout, `!important` court-circuite le mécanisme. A triplet (id, classes/attributes/pseudo-classes, elements/pseudo-elements) compared left to right: (1,0,0) beats (0,15,3) — one id beats any number of classes. On an exact tie, the last declared rule wins. Inline style tops everything, `!important` short-circuits the mechanism.
Pourquoi dit-on que `!important` est un aveu ? Why is `!important` called a confession?
On l'utilise quand on a perdu le contrôle de sa spécificité : il masque le conflit au lieu de le résoudre et déclenche la surenchère (le prochain conflit exigera un autre `!important`). Le vrai fix : comprendre quelle règle gagne et baisser la spécificité (des classes, pas d'id). You use it when you've lost control of your specificity: it hides the conflict instead of resolving it and triggers an arms race (the next conflict will require another `!important`). The real fix: understand which rule wins and lower specificity (classes, no ids).
Flexbox vs Grid : comment choisir ? Flexbox vs Grid: how do you choose?
Une dimension → flexbox (navbar, ligne de boutons : les items se répartissent le long d'un axe, pilotés par le contenu). Deux dimensions → grid (layout de page, galerie : lignes et colonnes définies par le conteneur). Ils se combinent : grid pour la structure, flexbox dans les composants. One dimension → flexbox (navbar, row of buttons: items distribute along an axis, driven by content). Two dimensions → grid (page layout, gallery: rows and columns defined by the container). They combine: grid for structure, flexbox inside components.
Pourquoi utiliser `rem` plutôt que `px` pour les tailles de texte ? Why use `rem` rather than `px` for text sizes?
`rem` est relative à la taille racine, donc au réglage de l'utilisateur : quelqu'un qui a agrandi sa police système voit le texte grandir. `px` fige la taille et ignore ce réglage. C'est un enjeu d'accessibilité, pas seulement de style. `rem` is relative to the root size, hence to the user's setting: someone who enlarged their system font sees the text grow. `px` freezes the size and ignores that setting. It's an accessibility issue, not just a style one.
Que donne un `<button>` natif que le `<div>` cliquable n'a pas ? What does a native `<button>` provide that a clickable `<div>` doesn't?
Gratuitement : focus clavier (atteignable au Tab), rôle annoncé aux lecteurs d'écran, activation Entrée/Espace, état `:disabled`, comportement dans les formulaires. Le div exige tabindex, role et handler keydown — une réimplémentation toujours incomplète. For free: keyboard focus (reachable via Tab), a role announced to screen readers, Enter/Space activation, the `:disabled` state, form behavior. The div requires tabindex, role and a keydown handler — an always-incomplete reimplementation.
Quand faut-il utiliser ARIA, et quelle est sa première règle ? When should you use ARIA, and what is its first rule?
Quand le HTML natif ne suffit pas : états dynamiques (`aria-expanded` pour un menu, `aria-live` pour du contenu mis à jour). Première règle du W3C : ne pas utiliser ARIA quand un élément natif existe. Et un mauvais ARIA est pire que pas d'ARIA : il promet des comportements que le JS n'assure pas. When native HTML isn't enough: dynamic states (`aria-expanded` for a menu, `aria-live` for updated content). The W3C's first rule: don't use ARIA when a native element exists. And bad ARIA is worse than no ARIA: it promises behaviors the JS doesn't deliver.
À quoi sert `:focus-visible` ? What is `:focus-visible` for?
À afficher un contour de focus net pendant la navigation clavier sans l'afficher au clic souris. Ça résout proprement le conflit « l'outline est moche » : on garde le site utilisable au clavier sans polluer l'expérience souris. Supprimer l'outline sans remplacement rend le site inutilisable au clavier. Showing a clear focus outline during keyboard navigation without showing it on mouse clicks. It cleanly solves the 'the outline is ugly' conflict: the site stays keyboard-usable without polluting the mouse experience. Removing the outline with no replacement makes the site keyboard-unusable.
Que fait `clamp(1rem, 2.5vw, 1.5rem)` ? What does `clamp(1rem, 2.5vw, 1.5rem)` do?
Une taille fluide bornée : la valeur préférée (2.5vw) suit la largeur du viewport, sans jamais descendre sous 1rem ni dépasser 1.5rem. C'est la typo responsive sans media query. Cousines modernes : `dvh` corrige le bug du 100vh sur mobile, les custom properties sont des variables vivantes dans la cascade. A bounded fluid size: the preferred value (2.5vw) follows the viewport width, never going below 1rem nor above 1.5rem. It's responsive typography without a media query. Modern cousins: `dvh` fixes the 100vh bug on mobile, custom properties are live variables in the cascade.
QCM Quiz
Entre `#nav a` et `.nav .menu .item .link` (4 classes), quelle règle gagne ? Between `#nav a` and `.nav .menu .item .link` (4 classes), which rule wins?
La spécificité se compare position par position : (1,0,1) contre (0,4,0). La colonne id se compare en premier, 1 > 0, fin du match. L'ordre de déclaration ne départage que les égalités exactes. Specificity is compared position by position: (1,0,1) versus (0,4,0). The id column is compared first, 1 > 0, match over. Declaration order only settles exact ties.
Tu construis une galerie photo alignée en lignes ET en colonnes. Quel outil ? You're building a photo gallery aligned in rows AND columns. Which tool?
Deux dimensions alignées ensemble = grid : `grid-template-columns: repeat(auto-fit, minmax(200px, 1fr))` fait une galerie responsive en une ligne. Flex-wrap crée des rangées indépendantes, sans alignement vertical cohérent. Two dimensions aligned together = grid: `grid-template-columns: repeat(auto-fit, minmax(200px, 1fr))` makes a responsive gallery in one line. Flex-wrap creates independent rows with no consistent vertical alignment.
Que manque-t-il à un `<div onclick="...">` pour être accessible ? What is a `<div onclick="...">` missing to be accessible?
Le div est invisible au Tab, muet pour les lecteurs d'écran et sourd au clavier. Le rendre accessible exige tabindex, role et handler keydown — soit réimplémenter, mal, ce qu'un `<button>` donne nativement. The div is invisible to Tab, mute for screen readers and deaf to the keyboard. Making it accessible requires tabindex, role and a keydown handler — reimplementing, badly, what a `<button>` provides natively.
Quel est le ratio de contraste minimum WCAG AA pour du texte normal ? What is the minimum WCAG AA contrast ratio for normal text?
WCAG AA exige 4.5:1 pour le texte normal et 3:1 pour le grand texte (18pt ou 14pt gras). Vérifiable en deux clics dans les DevTools ou le contrast checker de WebAIM. WCAG AA requires 4.5:1 for normal text and 3:1 for large text (18pt, or 14pt bold). Checkable in two clicks in DevTools or WebAIM's contrast checker.
Pourquoi mettre `alt=""` (vide) sur une image purement décorative ? Why put `alt=""` (empty) on a purely decorative image?
`alt=""` dit explicitement « décorative, à ignorer ». Sans attribut alt du tout, beaucoup de lecteurs d'écran annoncent le nom du fichier (« IMG_4523.jpg ») — bruit inutile. Vide et absent, ce n'est pas pareil. `alt=""` explicitly says 'decorative, ignore me'. With no alt attribute at all, many screen readers announce the file name ('IMG_4523.jpg') — useless noise. Empty and missing are not the same.
À quoi sert `@media (prefers-reduced-motion: reduce)` ? What is `@media (prefers-reduced-motion: reduce)` for?
Certains utilisateurs (troubles vestibulaires, sensibilité au mouvement) désactivent les animations dans leur OS. Cette media query expose ce réglage au CSS : le respecter coûte cinq lignes et évite un site physiquement pénible. Some users (vestibular disorders, motion sensitivity) disable animations in their OS. This media query exposes that setting to CSS: honoring it costs five lines and avoids a physically unpleasant site.
Jour 46 Day 46 Scaler une app : reverse proxy, load balancing & haute dispo Scaling an app: reverse proxy, load balancing & high availability
Flashcards Flashcards
Scaling vertical vs horizontal : quelle différence ? Vertical vs horizontal scaling: what's the difference?
Vertical (scale up) : une machine plus grosse — zéro changement de code, mais plafond matériel et le SPOF reste. Horizontal (scale out) : plus de machines identiques derrière un load balancer — quasi illimité et tolérant aux pannes, mais exige une app stateless. Vertical (scale up): a bigger machine — zero code changes, but a hardware ceiling and the SPOF remains. Horizontal (scale out): more identical machines behind a load balancer — nearly unlimited and fault-tolerant, but requires a stateless app.
Pourquoi le stateless est-il le prérequis du scaling horizontal ? Why is statelessness the prerequisite of horizontal scaling?
Le LB route chaque requête vers n'importe quelle instance : un état en mémoire locale (session, cache, fichier) devient invisible pour les autres. On externalise : sessions dans Redis ou JWT, fichiers en object storage, vérité en base. Test : tuer une instance à tout instant sans impact utilisateur. The LB routes each request to any instance: state in local memory (session, cache, file) becomes invisible to the others. Externalize it: sessions in Redis or JWT, files in object storage, truth in the database. Test: kill any instance at any moment with zero user impact.
Quels services rend un reverse proxy en plus de transmettre les requêtes ? What services does a reverse proxy provide beyond forwarding requests?
TLS termination (HTTPS s'arrête au proxy, certificats gérés en un seul endroit), compression gzip/brotli, cache du statique, routing par domaine ou chemin, et en-têtes comme X-Forwarded-For pour conserver l'IP réelle du client. TLS termination (HTTPS stops at the proxy, certificates managed in one place), gzip/brotli compression, static caching, routing by domain or path, and headers like X-Forwarded-For to preserve the client's real IP.
Round-robin vs least-connections : quand préférer l'un ou l'autre ? Round-robin vs least-connections: when to prefer one or the other?
Round-robin distribue équitablement en nombre de requêtes : bien quand elles se valent. Least-connections envoie vers l'instance ayant le moins de connexions actives : meilleur quand les durées varient (une grosse requête ne bloque pas la file). Health checks obligatoires dans les deux cas. Round-robin distributes evenly by request count: fine when requests are similar. Least-connections sends to the instance with the fewest active connections: better when durations vary (one big request doesn't block the queue). Health checks are mandatory either way.
À quoi servent les health checks d'un load balancer ? What are a load balancer's health checks for?
Le LB sonde régulièrement chaque instance (ex. endpoint /health) et sort du pool celles qui ne répondent plus, puis les réintègre quand elles guérissent. C'est le mécanisme qui transforme « une instance est morte » en « personne ne l'a remarqué ». The LB regularly probes each instance (e.g. a /health endpoint) and removes from the pool those that stop responding, then reinstates them when they recover. It's the mechanism that turns 'an instance died' into 'nobody noticed'.
C'est quoi les sticky sessions, et pourquoi les éviter ? What are sticky sessions, and why avoid them?
Le LB colle un client à une instance fixe (cookie) pour que son état en mémoire reste accessible. À éviter : répartition de charge dégradée, et la mort d'une instance déconnecte tous ses clients d'un coup. La vraie solution : rendre l'app stateless. The LB pins a client to a fixed instance (cookie) so its in-memory state stays reachable. Avoid them: degraded load distribution, and one instance dying disconnects all its clients at once. The real fix: make the app stateless.
C'est quoi un SPOF et comment l'éliminer ? What is a SPOF and how do you eliminate it?
Single point of failure : un composant unique dont la panne emporte tout. On les traque étage par étage : N instances d'app, DB primary + replica avec failover, deux LB avec IP flottante (keepalived). La haute dispo se vérifie maillon par maillon. Single point of failure: a unique component whose failure takes everything down. Hunt them tier by tier: N app instances, primary + replica DB with failover, two LBs with a floating IP (keepalived). High availability is verified link by link.
C'est quoi le replication lag et quel problème pose-t-il ? What is replication lag and what problem does it cause?
Le délai entre une écriture sur le primary et sa propagation aux replicas. Une lecture sur replica juste après une écriture peut renvoyer l'ancien état. Pour les lectures critiques (« read your own writes »), on lit sur le primary. The delay between a write on the primary and its propagation to the replicas. A read on a replica right after a write can return the old state. For critical reads ('read your own writes'), read from the primary.
QCM Quiz
Que signifie « TLS termination » sur un reverse proxy ? What does 'TLS termination' on a reverse proxy mean?
Le proxy déchiffre le TLS et transmet en HTTP sur le réseau interne : un seul endroit où gérer les certificats, et les instances restent simples. L'app apprend qu'elle est derrière HTTPS via X-Forwarded-Proto. The proxy decrypts TLS and forwards plain HTTP on the internal network: one single place to manage certificates, and instances stay simple. The app learns it's behind HTTPS via X-Forwarded-Proto.
Quel est LE prérequis pour passer une app au scaling horizontal ? What is THE prerequisite for moving an app to horizontal scaling?
Sans stateless, le LB casse tout : une session en mémoire sur l'instance A est invisible depuis B. Sessions dans Redis ou JWT, fichiers en object storage — microservices et Kubernetes sont optionnels, pas le stateless. Without statelessness, the LB breaks everything: a session in instance A's memory is invisible from B. Sessions in Redis or JWT, files in object storage — microservices and Kubernetes are optional, statelessness isn't.
Dans nginx, que provoque `max_fails=3 fail_timeout=30s` sur un serveur d'upstream ? In nginx, what does `max_fails=3 fail_timeout=30s` on an upstream server cause?
C'est le health check passif de nginx : 3 échecs dans la fenêtre → l'instance est marquée indisponible pendant 30 s, puis retentée. Le trafic continue vers les instances saines — personne ne remarque la panne. That's nginx's passive health check: 3 failures within the window → the instance is marked unavailable for 30 s, then retried. Traffic continues to healthy instances — nobody notices the failure.
Pourquoi les sticky sessions sont-elles déconseillées ? Why are sticky sessions discouraged?
Coller les clients à une instance recrée le problème que le LB devait résoudre : charge inégale et panne non transparente. C'est une béquille pour app stateful — la vraie solution est d'externaliser les sessions. Pinning clients to an instance recreates the problem the LB was meant to solve: uneven load and non-transparent failures. It's a crutch for stateful apps — the real solution is externalizing sessions.
Un utilisateur modifie son profil puis le recharge aussitôt et voit l'ancienne version. Cause probable dans une archi primary/replica ? A user edits their profile then reloads immediately and sees the old version. Likely cause in a primary/replica architecture?
L'écriture est allée sur le primary, la lecture sur un replica en retard de quelques millisecondes ou secondes. Pattern classique « read your own writes » : ces lectures-là doivent viser le primary. The write went to the primary, the read to a replica lagging by milliseconds or seconds. Classic 'read your own writes' pattern: those reads must target the primary.
Quel est le premier réflexe sain avant d'ajouter des instances à une app lente ? What is the healthy first reflex before adding instances to a slow app?
Le goulot est rarement où on croit : souvent une requête sans index bien avant le CPU. Doubler les instances qui exécutent du code lent multiplie le coût, pas la performance. Mesurer (APM, load testing), puis scaler ce qui sature. The bottleneck is rarely where you think: often an unindexed query long before the CPU. Doubling instances running slow code multiplies cost, not performance. Measure (APM, load testing), then scale what saturates.
Jour 45 Day 45 Aborder une codebase inconnue Approaching an unknown codebase
Flashcards Flashcards
Quel est l'objectif réaliste quand on découvre une grosse codebase ? What is the realistic goal when discovering a large codebase?
Pas de tout comprendre : construire une carte progressive — les 5-6 modules principaux, leurs frontières, qui parle à qui. Le détail se charge à la demande, quand un ticket vous y emmène. Même les seniors fonctionnent avec une carte grossière + des techniques de recherche. Not to understand everything: build a progressive map — the 5-6 main modules, their boundaries, who talks to whom. Details load on demand, when a ticket takes you there. Even seniors work with a rough map + search techniques.
Que faire le tout premier jour dans une codebase inconnue ? What should you do on the very first day in an unknown codebase?
Cloner, suivre le README à la lettre, faire tourner l'app en local et lancer les tests — en notant chaque étape manquante ou fausse (variable d'env non documentée, version implicite…). Ces notes deviennent une PR de doc. Rien d'autre le jour 1. Clone, follow the README to the letter, get the app running locally and run the tests — writing down every missing or wrong step (undocumented env var, implicit version…). Those notes become a docs PR. Nothing else on day 1.
Pourquoi les tests sont-ils la meilleure documentation d'une codebase ? Why are tests the best documentation of a codebase?
Ils décrivent le comportement attendu avec des exemples exécutables, cas nominaux et cas limites inclus, et ils sont à jour par construction : s'ils mentaient, la CI serait rouge. Un README ou un wiki, lui, peut dériver sans que personne ne s'en aperçoive. They describe expected behavior with executable examples, nominal and edge cases included, and they're current by construction: if they lied, CI would be red. A README or wiki can drift without anyone noticing.
Comment trouver qui peut t'aider sur un module précis ? How do you find who can help you on a specific module?
`git shortlog -sn -- chemin/` liste les auteurs par nombre de commits sur ce chemin ; `git blame` sur une ligne précise remonte au commit et à son auteur. On pose ensuite la question à la bonne personne, avec le contexte du commit. `git shortlog -sn -- path/` lists authors by commit count on that path; `git blame` on a specific line leads to the commit and its author. Then you ask the right person, armed with the commit's context.
Comment poser une question intelligemment quand on est bloqué ? How do you ask a question intelligently when stuck?
Timeboxer la recherche (30-45 min), puis demander en montrant le chemin parcouru : ce qu'on a grep, les fichiers regardés, l'hypothèse actuelle. Cette forme prouve l'effort, cadre la réponse et transforme la question en signal positif plutôt qu'en aveu. Timebox the search (30-45 min), then ask while showing the path covered: what you grepped, the files checked, your current hypothesis. This form proves effort, frames the answer and turns the question into a positive signal instead of a confession.
C'est quoi une bonne première PR dans une nouvelle équipe ? What makes a good first PR in a new team?
Petite, sûre, utile : typo, étape de setup manquante dans le README, test sur un cas limite non couvert. Elle sert à traverser tout le pipeline (branche, conventions, review, CI, merge) sur un changement à risque nul — pas à briller. Small, safe, useful: a typo, a missing setup step in the README, a test on an uncovered edge case. Its purpose is to cross the whole pipeline (branch, conventions, review, CI, merge) on a zero-risk change — not to shine.
Pourquoi suivre une requête de bout en bout est-il si rentable ? Why is following one request end to end so valuable?
Un seul aller-retour (route → controller → service → repository → DB) révèle l'architecture réelle : les couches, les conventions de nommage, où vit la logique métier. C'est la compréhension maximale par minute investie, contrairement à la lecture linéaire. A single round trip (route → controller → service → repository → DB) reveals the real architecture: the layers, naming conventions, where business logic lives. It's the maximum understanding per minute invested, unlike linear reading.
C'est quoi la barrière de Chesterton, appliquée au code ? What is Chesterton's fence, applied to code?
Ne jamais supprimer ou refactorer un code « bizarre » avant d'avoir compris pourquoi il existe : contrainte métier, bug historique, dépendance externe. `git log` et `git blame` donnent souvent la raison. Proposer un grand refactoring en semaine 1 est le signal junior type. Never delete or refactor 'weird' code before understanding why it exists: business constraint, historical bug, external dependency. `git log` and `git blame` often reveal the reason. Proposing a big refactoring in week 1 is the classic junior signal.
QCM Quiz
Quelle est la priorité absolue du premier jour dans une codebase inconnue ? What is the absolute priority on day one in an unknown codebase?
Une app qui tourne est un terrain d'expérimentation : on peut poser des breakpoints, modifier, observer. Lire du code qu'on ne peut pas exécuter, c'est de la fiction. Le reste vient après. A running app is a playground: you can set breakpoints, modify, observe. Reading code you can't execute is fiction. Everything else comes later.
Le README dit X mais le code fait Y. Que faire ? The README says X but the code does Y. What do you do?
Le code est ce qui tourne en prod ; le README date. Mais l'écart est une info : git log dit si Y est récent, l'équipe confirme si c'est voulu, et la correction du README fait une première PR parfaite. The code is what runs in production; the README ages. But the gap is information: git log tells you if Y is recent, the team confirms whether it's intended, and fixing the README makes a perfect first PR.
Quel est le meilleur point de départ pour localiser une feature dans une codebase inconnue ? What is the best starting point to locate a feature in an unknown codebase?
Une chaîne visible (erreur, label) existe forcément quelque part dans le code : c'est une ancre fiable. Un nom supposé, lui, échoue si les conventions diffèrent des vôtres. A visible string (error, label) necessarily exists somewhere in the code: it's a reliable anchor. An assumed name fails whenever the conventions differ from yours.
À quoi sert `git log --follow` sur un fichier ? What is `git log --follow` on a file for?
Sans `--follow`, l'historique s'arrête au dernier renommage du fichier. Avec, git remonte toute sa vie — précieux dans les vieilles codebases où les fichiers ont déménagé plusieurs fois. Without `--follow`, the history stops at the file's last rename. With it, git traces its whole life — precious in old codebases where files have moved several times.
Pourquoi éviter de proposer un gros refactoring dès la première semaine ? Why avoid proposing a big refactoring in your first week?
Contrainte métier, bug historique, dépendance externe : la raison existe souvent, et git log la retrouve. On ne retire une barrière qu'après avoir compris pourquoi elle est là. Business constraint, historical bug, external dependency: the reason often exists, and git log can find it. You only remove a fence after understanding why it's there.
Quelle est la bonne manière de demander de l'aide quand on est bloqué ? What is the right way to ask for help when stuck?
Le timebox évite les deux extrêmes : demander sans chercher (crédit grillé) et rester bloqué des heures (temps perdu pour l'équipe). Montrer le chemin parcouru prouve l'effort et cadre la réponse. The timebox avoids both extremes: asking without searching (burned credit) and staying stuck for hours (wasted team time). Showing the path covered proves effort and frames the answer.
Jour 44 Day 44 ORM, migrations & N+1 ORMs, migrations & N+1
Flashcards Flashcards
Qu'apporte un ORM, en trois points ? What does an ORM bring, in three points?
Le mapping objet-relationnel (une ligne ↔ un objet, une clé étrangère ↔ une propriété), des requêtes typées vérifiées par le compilateur/l'IDE, et un système de migrations qui versionne le schéma comme du code. Object-relational mapping (a row ↔ an object, a foreign key ↔ a property), typed queries checked by the compiler/IDE, and a migration system that versions the schema like code.
C'est quoi le problème N+1 ? Donne un exemple chiffré. What is the N+1 problem? Give a numbered example.
Une requête pour charger une liste, puis une requête par élément dans la boucle qui suit. Exemple : 100 auteurs et leurs articles = 1 + 100 = 101 requêtes, soit ~500 ms à 5 ms de round-trip, contre 2 requêtes (~10 ms) avec un eager loading. One query to load a list, then one query per element in the following loop. Example: 100 authors and their posts = 1 + 100 = 101 queries, i.e. ~500 ms at 5 ms per round-trip, versus 2 queries (~10 ms) with eager loading.
Eager vs lazy loading : quelle différence et quel risque pour chacun ? Eager vs lazy loading: what's the difference and the risk of each?
Lazy charge la relation au moment de l'accès (risque : N+1 dès qu'on itère) ; eager la charge dès la requête initiale via JOIN ou WHERE IN (risque : sur-charger des données inutiles). Règle pratique : eager explicite partout où on boucle. Lazy loads the relation on access (risk: N+1 as soon as you iterate); eager loads it with the initial query via JOIN or WHERE IN (risk: over-fetching useless data). Rule of thumb: explicit eager wherever you loop.
Comment détecter un N+1 en pratique ? How do you detect an N+1 in practice?
Compter les requêtes : activer le log SQL en dev (log: ['query'] chez Prisma, echo=True chez SQLAlchemy) et regarder ce qu'un écran déclenche. Si le nombre de requêtes croît avec le nombre d'éléments affichés, c'est un N+1. En prod : APM. Count the queries: enable SQL logging in dev (log: ['query'] in Prisma, echo=True in SQLAlchemy) and watch what one screen triggers. If the query count grows with the number of displayed items, it's an N+1. In production: APM.
Pourquoi ne faut-il jamais éditer une migration déjà appliquée ? Why should you never edit an already-applied migration?
Elle a déjà tourné sur d'autres bases (collègues, CI, prod) : l'éditer fait diverger l'historique, les outils le détectent (checksum chez Prisma) et refusent d'avancer. Une erreur se corrige en avant, par une nouvelle migration. It has already run on other databases (colleagues, CI, production): editing it makes the history diverge, tools detect it (Prisma checksums) and refuse to proceed. Mistakes are fixed forward, with a new migration.
Décris les trois phases d'un expand/contract. Describe the three phases of expand/contract.
Expand : ajouter le nouveau (colonne nullable, double écriture) sans toucher à l'ancien. Migrate : backfill des données existantes et bascule du code vers le nouveau. Contract : supprimer l'ancien quand plus personne ne le lit. Un déploiement par phase — jamais de rename direct. Expand: add the new (nullable column, dual writes) without touching the old. Migrate: backfill existing data and switch the code to the new. Contract: remove the old once nobody reads it. One deployment per phase — never a direct rename.
Quand est-il légitime d'écrire du SQL brut plutôt que passer par l'ORM ? When is it legitimate to write raw SQL instead of going through the ORM?
Rapports et agrégations complexes, window functions, bulk updates, et les hot paths où le SQL généré est inefficace. Tous les ORM ont une trappe de sortie ($queryRaw, text(), native queries) prévue pour ça — l'ORM garde le CRUD répétitif. Complex reports and aggregations, window functions, bulk updates, and hot paths where the generated SQL is inefficient. Every ORM has an escape hatch ($queryRaw, text(), native queries) designed for this — the ORM keeps the repetitive CRUD.
À quoi servent les seeds et pourquoi varient-ils par environnement ? What are seeds for and why do they vary per environment?
Ce sont les données initiales scriptées et versionnées (comptes de test, référentiels). Le dev veut des données réalistes pour travailler, le CI un jeu minimal et déterministe pour des tests reproductibles, la prod presque rien — jamais les comptes de test. They are the scripted, versioned initial data (test accounts, reference tables). Dev wants realistic data to work with, CI a minimal deterministic set for reproducible tests, production almost nothing — never the test accounts.
QCM Quiz
Une page liste 100 auteurs et, dans une boucle, requête les articles de chacun. Combien de requêtes SQL partent ? A page lists 100 authors and, in a loop, queries each one's posts. How many SQL queries are fired?
1 requête pour la liste + 1 par auteur = 101. C'est la définition du N+1 : le coût est dominé par les round-trips réseau, pas par le volume de données. 1 query for the list + 1 per author = 101. That's the definition of N+1: the cost is dominated by network round-trips, not data volume.
Comment corriger un N+1 avec Prisma ? How do you fix an N+1 with Prisma?
include (ou select) déclenche un eager loading : l'ORM ramène la relation en 1-2 requêtes (JOIN ou WHERE IN). Transaction et index ne réduisent pas le nombre de round-trips. include (or select) triggers eager loading: the ORM fetches the relation in 1-2 queries (JOIN or WHERE IN). Transactions and indexes don't reduce the number of round-trips.
Tu découvres un bug dans une migration déjà appliquée en prod. Que fais-tu ? You find a bug in a migration already applied in production. What do you do?
Une migration appliquée a déjà tourné sur d'autres bases : l'éditer fait diverger l'historique (checksum invalide). On corrige toujours en avant, avec une nouvelle migration. An applied migration has already run on other databases: editing it makes the history diverge (invalid checksum). You always fix forward, with a new migration.
Dans quel ordre se déroule un expand/contract pour renommer une colonne ? In what order does an expand/contract run to rename a column?
Expand (ajouter), migrate (backfill + bascule du code), contract (supprimer) : à chaque étape, l'ancien code et le nouveau restent compatibles avec le schéma. Un rename direct casse le code encore déployé. Expand (add), migrate (backfill + code switch), contract (drop): at every step, old and new code stay compatible with the schema. A direct rename breaks the code still deployed.
Pourquoi un N+1 passe-t-il souvent inaperçu en développement ? Why does an N+1 often go unnoticed in development?
En local, 11 requêtes à 0,1 ms ne se voient pas. En prod, 10 001 requêtes à 5 ms de latence réseau, si. D'où le réflexe : compter les requêtes en dev, pas mesurer le temps. Locally, 11 queries at 0.1 ms are invisible. In production, 10,001 queries at 5 ms of network latency are not. Hence the reflex: count queries in dev, don't just measure time.
Que restaure le down d'une migration DROP COLUMN ? What does the down of a DROP COLUMN migration restore?
Le down recrée la structure, pas les données détruites par le DROP. Le vrai filet de sécurité d'une migration destructive : backup vérifié + phase contract (plus aucun lecteur), jamais un vendredi soir. The down recreates the structure, not the data destroyed by the DROP. The real safety net of a destructive migration: verified backup + contract phase (no readers left), never on a Friday evening.
Jour 43 Day 43 Closures, prototypes & this Closures, prototypes & this
Flashcards Flashcards
Donne la définition exacte d'une closure. Give the exact definition of a closure.
Une fonction qui capture les variables de son scope lexical de définition et les garde vivantes après la fin de la fonction englobante. « Lexical » = déterminé par la position du code, pas par l'appel. La closure référence les variables elles-mêmes, pas une copie de leurs valeurs. A function that captures the variables of its lexical definition scope and keeps them alive after the enclosing function returns. "Lexical" = determined by the code's position, not by the call. The closure references the variables themselves, not a copy of their values.
Pourquoi `for (var i = 0; i < 3; i++) setTimeout(() => console.log(i))` affiche 3, 3, 3 ? Why does `for (var i = 0; i < 3; i++) setTimeout(() => console.log(i))` print 3, 3, 3?
var n'a pas de scope de bloc : les trois callbacks capturent la même variable i. Ils s'exécutent après la fin de la boucle, quand i vaut 3. Avec let, chaque itération crée une nouvelle liaison → 0, 1, 2. La closure capture la variable, pas sa valeur au moment de la création. var has no block scope: all three callbacks capture the same variable i. They run after the loop ends, when i equals 3. With let, each iteration creates a new binding → 0, 1, 2. A closure captures the variable, not its value at creation time.
Cite trois usages réels des closures. Name three real uses of closures.
1) État privé : un compteur dont la variable est invisible de l'extérieur (pattern module). 2) Callbacks qui se souviennent de leur contexte (handlers, debounce/throttle, memoization). 3) Les hooks React, entièrement construits sur les closures (d'où le bug de la « stale closure » dans useEffect). 1) Private state: a counter whose variable is invisible from outside (module pattern). 2) Callbacks that remember their context (handlers, debounce/throttle, memoization). 3) React hooks, built entirely on closures (hence the "stale closure" bug in useEffect).
Comment fonctionne la lecture d'une propriété sur un objet JavaScript ? How does property lookup work on a JavaScript object?
Le moteur cherche la propriété sur l'objet lui-même ; s'il ne la trouve pas, il remonte le lien [[Prototype]] d'objet en objet jusqu'à Object.prototype puis null. C'est la chaîne de prototypes : l'héritage JS est une délégation, pas une copie. The engine looks for the property on the object itself; if not found, it follows the [[Prototype]] link from object to object up to Object.prototype and then null. That's the prototype chain: JS inheritance is delegation, not copying.
Que fait vraiment le mot-clé class en JavaScript ? What does the class keyword really do in JavaScript?
Du sucre syntaxique sur les prototypes : les méthodes sont posées sur Class.prototype (partagées par toutes les instances, pas copiées), extends câble Class.prototype.[[Prototype]] vers le parent. typeof Class renvoie « function ». Le modèle objet reste prototypal. Syntactic sugar over prototypes: methods are placed on Class.prototype (shared by all instances, not copied), extends wires Class.prototype.[[Prototype]] to the parent. typeof Class returns "function". The object model remains prototypal.
Quelles sont les quatre règles de binding de this, par ordre de priorité ? What are the four this-binding rules, in priority order?
1) new f() → l'objet fraîchement créé. 2) f.call/apply/bind(ctx) → le ctx explicite. 3) obj.f() → l'objet avant le point. 4) f() appel simple → undefined en strict mode (globalThis sinon). À évaluer au site d'appel, jamais au lieu de définition. 1) new f() → the freshly created object. 2) f.call/apply/bind(ctx) → the explicit ctx. 3) obj.f() → the object before the dot. 4) plain f() → undefined in strict mode (globalThis otherwise). Evaluated at the call site, never at the definition site.
En quoi les arrow functions sont-elles spéciales vis-à-vis de this ? What makes arrow functions special with respect to this?
Elles n'ont pas de this propre : elles utilisent celui du scope lexical englobant, figé à l'écriture. Parfaites pour les callbacks dans une classe (setTimeout(() => this.tick())), mauvaises comme méthodes d'objet. Elles n'ont pas non plus d'arguments et ne sont pas constructibles. They have no this of their own: they use the enclosing lexical scope's this, fixed at write time. Perfect for callbacks inside a class (setTimeout(() => this.tick())), bad as object methods. They also lack arguments and are not constructible.
Hoisting et TDZ : quelle différence entre var et let/const ? Hoisting and TDZ: what's the difference between var and let/const?
var est hissée ET initialisée à undefined : lisible avant sa ligne, sans erreur (bugs silencieux). let/const sont hissées mais non initialisées : y accéder avant la déclaration jette une ReferenceError — c'est la temporal dead zone, qui transforme un bug silencieux en erreur franche. var is hoisted AND initialized to undefined: readable before its line, without error (silent bugs). let/const are hoisted but uninitialized: accessing them before the declaration throws a ReferenceError — the temporal dead zone, which turns a silent bug into a loud error.
QCM Quiz
Qu'est-ce qu'une closure capture exactement ? What exactly does a closure capture?
La closure référence les variables, pas leurs valeurs : si la variable change ensuite, la closure voit la nouvelle valeur. C'est tout le piège de la boucle var → 3, 3, 3. (Le this lexical, lui, est le propre des arrow functions.) A closure references variables, not their values: if the variable later changes, the closure sees the new value. That's the whole var-loop trap → 3, 3, 3. (Lexical this is an arrow-function thing.)
Que corrige le remplacement de var par let dans la boucle avec setTimeout ? What does replacing var with let fix in the setTimeout loop?
Avec let, chaque tour de boucle a SA variable : chaque closure capture une liaison différente → 0, 1, 2. Ce n'est pas une copie de valeur : c'est bien une variable neuve par itération, toujours capturée par référence. With let, each loop turn has ITS OWN variable: each closure captures a different binding → 0, 1, 2. It's not a value copy: it's a fresh variable per iteration, still captured by reference.
Où vivent les méthodes définies dans une class JavaScript ? Where do methods defined in a JavaScript class live?
class n'est que du sucre sur les prototypes : les méthodes sont posées une seule fois sur Class.prototype, et chaque instance les trouve en remontant son [[Prototype]]. Mille instances, une seule fonction. class is just sugar over prototypes: methods are placed once on Class.prototype, and each instance finds them by walking its [[Prototype]]. A thousand instances, a single function.
En strict mode, que vaut this dans `const f = user.greet; f();` ? In strict mode, what is this in `const f = user.greet; f();`?
this se détermine au site d'appel : f() est un appel simple (règle 4), donc undefined en strict mode. Remèdes : user.greet.bind(user), un wrapper arrow, ou un champ de classe en arrow function. this is determined at the call site: f() is a plain call (rule 4), hence undefined in strict mode. Fixes: user.greet.bind(user), an arrow wrapper, or an arrow class field.
Pourquoi une arrow function est-elle un mauvais choix comme méthode d'objet ? Why is an arrow function a bad choice as an object method?
L'arrow capture le this lexical de l'endroit où elle est écrite — pour un littéral d'objet, ce n'est jamais l'objet lui-même. La règle « objet avant le point » ne s'applique pas aux arrows. Elles restent idéales pour les callbacks dans une classe. An arrow captures the lexical this of where it's written — for an object literal, that's never the object itself. The "object before the dot" rule doesn't apply to arrows. They remain ideal for callbacks inside a class.
Quelle est la différence entre Dog.prototype et rex.__proto__ (rex étant une instance de Dog) ? What's the difference between Dog.prototype and rex.__proto__ (rex being a Dog instance)?
prototype n'existe que sur les fonctions constructrices : c'est le futur [[Prototype]] de leurs instances. __proto__ (déprécié, préférer Object.getPrototypeOf) expose le lien interne. Pour rex créé par new Dog(), les deux désignent le même objet — mais par des chemins différents. prototype only exists on constructor functions: it's the future [[Prototype]] of their instances. __proto__ (deprecated, prefer Object.getPrototypeOf) exposes the internal link. For rex created by new Dog(), both designate the same object — via different paths.
Jour 42 Day 42 System design junior : l'URL shortener Junior system design: the URL shortener
Flashcards Flashcards
Quelle est la méthode en 4 étapes face à un exercice de system design ? What is the 4-step method for a system design exercise?
1) Clarifier les besoins (fonctionnels + non fonctionnels : volumétrie, latence, disponibilité). 2) Estimer les ordres de grandeur (req/s, stockage). 3) Dessiner le schéma simple qui répond au besoin. 4) Itérer sur les goulots d'étranglement. Et annoncer ce plan à voix haute dès le début. 1) Clarify the requirements (functional + non-functional: volume, latency, availability). 2) Estimate orders of magnitude (req/s, storage). 3) Draw the simple diagram that meets the need. 4) Iterate on the bottlenecks. And announce this plan out loud from the start.
Quels sont les deux endpoints d'un URL shortener et leurs réponses ? What are a URL shortener's two endpoints and their responses?
POST /shorten : reçoit l'URL longue, la valide, renvoie 201 avec le code court. GET /:code : renvoie une redirection 301 ou 302 vers l'URL longue, ou 404 si le code n'existe pas. POST /shorten: receives the long URL, validates it, returns 201 with the short code. GET /:code: returns a 301 or 302 redirect to the long URL, or 404 if the code doesn't exist.
Compteur + base62 vs hash tronqué : quels trade-offs pour générer le code court ? Counter + base62 vs truncated hash: what are the trade-offs for generating the short code?
Compteur + base62 : simple, zéro collision, codes courts, mais prévisibles (énumérables) — corrigible par permutation secrète. Hash tronqué : pas de compteur central, même URL → même code, mais collisions dues à la troncature (paradoxe des anniversaires) → vérifier en base et retry. Counter + base62: simple, zero collisions, short codes, but predictable (enumerable) — fixable with a secret permutation. Truncated hash: no central counter, same URL → same code, but collisions from truncation (birthday paradox) → check the DB and retry.
Pourquoi le choix 301 vs 302 est-il crucial pour un URL shortener ? Why is the 301 vs 302 choice crucial for a URL shortener?
Le 301 est mis en cache par le navigateur : les clics suivants vont directement à la cible sans repasser par le service → analytics perdues. Le 302 n'est pas mis en cache : chaque clic traverse le service et peut être compté. Si le tracking est un besoin (cas bit.ly), c'est 302. A 301 is cached by the browser: subsequent clicks go straight to the target without passing through the service → analytics lost. A 302 isn't cached: every click traverses the service and can be counted. If tracking is a requirement (bit.ly's case), it's 302.
Quel modèle de stockage pour un URL shortener, et pourquoi ? What storage model for a URL shortener, and why?
Une table clé-valeur : code (clé primaire) → url, created_at. Aucune jointure ni transaction complexe, donc n'importe quel store convient. À ~50 Go/an et 300 lectures/s, un Postgres bien indexé suffit largement ; le NoSQL ne se justifie qu'à une échelle bien supérieure. A key-value table: code (primary key) → url, created_at. No joins or complex transactions, so any store fits. At ~50 GB/year and 300 reads/s, a well-indexed Postgres is plenty; NoSQL is only justified at a much larger scale.
Comment le cache s'intègre-t-il dans l'architecture, et pourquoi marche-t-il si bien ici ? How does the cache fit into the architecture, and why does it work so well here?
En cache-aside : on lit Redis, sur miss on lit la base et on remplit le cache avec un TTL. Ça marche très bien car la popularité suit une loi de Zipf (peu d'URLs concentrent le trafic) et les URLs sont immuables — quasiment aucun problème d'invalidation. Cache-aside: read Redis, on miss read the DB and fill the cache with a TTL. It works very well because popularity follows a Zipf distribution (few URLs concentrate the traffic) and URLs are immutable — almost no invalidation problem.
Pourquoi le rate limiting est-il indispensable sur POST /shorten ? Why is rate limiting essential on POST /shorten?
Sans lui, un spammeur crée des millions de liens : phishing relayé par votre domaine, pollution de l'espace de codes, coûts de stockage. Solution : token bucket par IP ou clé API, réponse 429, plus validation stricte des URLs (schémas http/https uniquement). Without it, a spammer creates millions of links: phishing relayed through your domain, code-space pollution, storage costs. Solution: token bucket per IP or API key, 429 response, plus strict URL validation (http/https schemes only).
Qu'évalue vraiment l'interviewer dans un system design junior ? What does the interviewer really evaluate in a junior system design?
Le raisonnement, pas les buzzwords : clarifier avant de dessiner, poser des ordres de grandeur, justifier chaque brique par un chiffre (« un cache parce que la lecture domine »), connaître les limites de son design, et savoir commencer simple. Reasoning, not buzzwords: clarifying before drawing, putting down orders of magnitude, justifying every box with a number ("a cache because reads dominate"), knowing the design's limits, and knowing how to start simple.
QCM Quiz
Quelle doit être votre toute première action face à « Conçois-moi un URL shortener » ? What should your very first move be when asked "Design a URL shortener"?
Clarifier les besoins est l'étape 1 de la méthode : les chiffres obtenus dictent tout le design. Dessiner avant de questionner est l'erreur junior numéro un. Clarifying requirements is step 1 of the method: the numbers you get dictate the whole design. Drawing before questioning is the number one junior mistake.
Un URL shortener sert 100 M d'URLs/an avec un ratio lecture/écriture de 100:1. Quel ordre de grandeur de trafic ? A URL shortener serves 100M URLs/year with a 100:1 read/write ratio. What order of magnitude of traffic?
100 M / (~30 M de secondes par an) ≈ 3 écritures/s, × 100 = 300 lectures/s. Conclusion à énoncer : ça tient sur un seul Postgres — le calcul de coin de table évite la sur-ingénierie. 100M / (~30M seconds per year) ≈ 3 writes/s, × 100 = 300 reads/s. Conclusion to state: it fits on a single Postgres — the back-of-the-envelope calculation prevents over-engineering.
Pourquoi bit.ly utilise-t-il une redirection 302 plutôt que 301 ? Why does bit.ly use a 302 redirect rather than a 301?
Le navigateur met le 301 en cache et ne repasse plus jamais par le service : impossible de compter les clics. Le 302 force chaque clic à traverser le service — le tracking est précisément le business model. The browser caches a 301 and never comes back through the service: clicks can't be counted. A 302 forces every click through the service — and tracking is precisely the business model.
Quel est le principal défaut de la génération de code par hash tronqué à 7 caractères ? What is the main flaw of generating codes by hashing truncated to 7 characters?
Tronquer un hash réduit l'espace : les collisions arrivent bien avant de l'épuiser (paradoxe des anniversaires). Il faut vérifier l'existence en base et ré-essayer avec un salt. À l'inverse, un compteur + base62 ne collisionne jamais. Truncating a hash shrinks the space: collisions occur long before it runs out (birthday paradox). You must check existence in the DB and retry with a salt. A counter + base62, by contrast, never collides.
Pourquoi les serveurs applicatifs doivent-ils être stateless ? Why must the app servers be stateless?
Tout l'état vit en base et en cache : n'importe quel serveur peut traiter n'importe quelle requête. Le scaling horizontal de la lecture devient trivial — on ajoute des instances derrière le LB. All state lives in the DB and cache: any server can handle any request. Horizontal read scaling becomes trivial — just add instances behind the LB.
Quelle réponse dessert le plus un candidat junior en system design ? Which answer hurts a junior candidate most in system design?
La soupe de buzzwords sans chiffre est l'anti-signal : elle montre du plaquage de mots-clés, pas du raisonnement. Les trois autres réponses sont exactement ce que l'interviewer veut entendre d'un junior. Buzzword soup without numbers is the anti-signal: it shows keyword-dropping, not reasoning. The other three answers are exactly what the interviewer wants to hear from a junior.
Jour 41 Day 41 Agile/Scrum tel qu'on le vit Agile/Scrum as actually lived
Flashcards Flashcards
Quelles sont les quatre valeurs du manifeste agile ? What are the four values of the agile manifesto?
Les individus et leurs interactions plus que les processus et outils ; un logiciel qui fonctionne plus qu'une doc exhaustive ; la collaboration avec le client plus que la négociation contractuelle ; l'adaptation au changement plus que le suivi d'un plan. Nuance clé : les seconds éléments ont de la valeur, on privilégie juste les premiers. Individuals and interactions over processes and tools; working software over comprehensive documentation; customer collaboration over contract negotiation; responding to change over following a plan. Key nuance: the items on the right have value, the left is just valued more.
Quels sont les trois rôles de Scrum et leurs responsabilités ? What are Scrum's three roles and their responsibilities?
Le Product Owner porte la vision produit et priorise le backlog (le quoi). Le Scrum Master facilite, lève les obstacles et protège l'équipe — ce n'est pas un chef de projet. L'équipe de développement s'auto-organise et décide du comment. The Product Owner carries the product vision and prioritizes the backlog (the what). The Scrum Master facilitates, removes obstacles and protects the team — not a project manager. The development team self-organizes and decides the how.
À quoi sert le daily, et quel est son format ? What is the daily for, and what is its format?
15 minutes debout, chaque jour : ce que j'ai avancé, ce sur quoi je pars, ce qui me bloque. Objectif : synchroniser l'équipe et surfacer les blocages tôt — pas rapporter au manager. Les discussions de fond se prennent à deux, après. 15 minutes standing, every day: what I moved forward, what I'm on, what blocks me. Goal: sync the team and surface blockers early — not reporting to the manager. Deep discussions happen in pairs, afterwards.
Quelle différence entre la sprint review et la rétrospective ? What's the difference between the sprint review and the retrospective?
La review regarde le produit : démo du logiciel qui marche aux parties prenantes, feedback. La rétro regarde le process : l'équipe, entre elle, identifie ce qui a frotté et décide d'une ou deux actions concrètes pour le sprint suivant. The review looks at the product: demo of working software to stakeholders, feedback. The retro looks at the process: the team, among itself, identifies friction and decides on one or two concrete actions for the next sprint.
Que sont les story points et la vélocité, et quelle est leur dérive classique ? What are story points and velocity, and what is their classic abuse?
Les story points estiment la complexité relative d'une story (Fibonacci : 1, 2, 3, 5, 8…), pas des heures. La vélocité = points livrés par sprint, outil de prévision interne. Dérive : en faire une métrique de performance ou comparer les équipes → les estimations gonflent (loi de Goodhart). Story points estimate a story's relative complexity (Fibonacci: 1, 2, 3, 5, 8…), not hours. Velocity = points delivered per sprint, an internal forecasting tool. The abuse: turning it into a performance metric or comparing teams → estimates inflate (Goodhart's law).
Qu'est-ce que la definition of done et pourquoi est-elle indispensable ? What is the definition of done and why is it essential?
Une checklist commune qui rend « fini » objectif : par exemple code écrit + testé + relu + mergé + déployé en staging. Sans elle, chacun a sa définition de « fini » et le sprint « terminé » explose en recette. A shared checklist that makes "finished" objective: e.g. code written + tested + reviewed + merged + deployed to staging. Without it, everyone has their own definition of "done" and the "finished" sprint blows up in acceptance testing.
Quand choisir kanban plutôt que Scrum ? When should you pick kanban over Scrum?
Quand le flux entrant est imprévisible (support, ops, maintenance) : pas de sprint figé, flux continu avec limite de WIP, mesuré au lead time / cycle time. Scrum convient mieux au développement produit planifiable avec un backlog priorisable. When the incoming flow is unpredictable (support, ops, maintenance): no frozen sprint, continuous flow with a WIP limit, measured by lead time / cycle time. Scrum fits plannable product development with a prioritizable backlog better.
Qu'attend-on concrètement d'un stagiaire dans une équipe agile ? What is concretely expected of an intern on an agile team?
Trois réflexes : découper une tâche floue en sous-tâches d'une journée testables ; signaler un blocage tôt (au daily ou avant, jamais la veille de la démo) ; demander de l'aide au bon moment — 30 à 60 minutes de recherche sérieuse, puis solliciter en montrant ce qu'on a déjà essayé. Three reflexes: splitting a fuzzy task into one-day testable subtasks; flagging a blocker early (at the daily or before, never the eve of the demo); asking for help at the right time — 30 to 60 minutes of serious digging, then asking while showing what you already tried.
QCM Quiz
Que dit exactement le manifeste agile à propos des processus et outils ? What exactly does the agile manifesto say about processes and tools?
La nuance oubliée du manifeste : « nous reconnaissons la valeur des seconds éléments, mais privilégions les premiers ». Agile n'élimine ni process ni doc — il les subordonne au feedback et aux gens. The manifesto's forgotten nuance: "while there is value in the items on the right, we value the items on the left more". Agile eliminates neither process nor docs — it subordinates them to feedback and people.
Quel est le rôle du Scrum Master ? What is the Scrum Master's role?
Le SM n'est pas un chef de projet : il ne distribue pas le travail (l'équipe s'auto-organise) et ne priorise pas le backlog (c'est le PO). Il déblaye et fait vivre le process. The SM is not a project manager: they don't hand out work (the team self-organizes) and don't prioritize the backlog (that's the PO). They clear the path and keep the process alive.
Un daily qui dure 45 minutes est le symptôme de quoi ? A 45-minute daily is a symptom of what?
Le daily synchronise et surface les blocages en 15 minutes. Les sujets de fond se traitent ensuite entre les personnes concernées — pas devant toute l'équipe qui attend son tour. The daily syncs and surfaces blockers in 15 minutes. Deep topics are then handled between the people concerned — not in front of a whole team waiting its turn.
Pourquoi ne faut-il jamais faire de la vélocité un objectif de management ? Why should velocity never become a management target?
Loi de Goodhart : une mesure qui devient un objectif cesse d'être une bonne mesure. Une équipe fliquée sur ses points les gonfle en silence — la vélocité redevient utile quand elle ne sert qu'à l'équipe pour prévoir. Goodhart's law: a measure that becomes a target stops being a good measure. A team policed on its points quietly inflates them — velocity is only useful when the team alone uses it to forecast.
Qu'est-ce qu'un « sprint mini-waterfall » ? What is a "mini-waterfall sprint"?
Découper le waterfall en tranches de deux semaines n'est pas de l'agile : l'incrément doit être « done » — tests inclus — à la fin du sprint. Sinon la dette de test s'accumule et la démo ment. Slicing waterfall into two-week chunks isn't agile: the increment must be "done" — tests included — by the end of the sprint. Otherwise test debt piles up and the demo lies.
Vous êtes stagiaire, bloqué depuis 45 minutes sur un bug malgré une vraie recherche. Que faire ? You're an intern, stuck on a bug for 45 minutes despite real digging. What do you do?
La règle des 30-60 minutes : chercher sérieusement, puis demander en apportant le contexte (« j'ai essayé X et Y, voici l'erreur »). Un blocage signalé tôt coûte une heure ; tû jusqu'à la démo, il coûte le sprint. The 30-60 minute rule: dig seriously, then ask while bringing context ("I tried X and Y, here's the error"). A blocker flagged early costs an hour; kept quiet until the demo, it costs the sprint.
Jour 40 Day 40 Chiffrement symétrique/asymétrique & TLS Symmetric/asymmetric encryption & TLS
Flashcards Flashcards
Quelle est la différence entre chiffrement symétrique et asymétrique ? What is the difference between symmetric and asymmetric encryption?
Symétrique (AES) : une seule clé partagée, très rapide (Go/s), mais problème de l'échange de la clé. Asymétrique (RSA, courbes elliptiques) : une paire publique/privée, résout l'échange de clé, mais ~1000 fois plus lent et limité à de petits messages. Symmetric (AES): a single shared key, very fast (GB/s), but the key-exchange problem. Asymmetric (RSA, elliptic curves): a public/private pair, solves key exchange, but ~1000× slower and limited to small messages.
Pourquoi TLS combine-t-il les deux familles de chiffrement ? Why does TLS combine both encryption families?
L'asymétrique (ECDHE + certificat) sert uniquement à établir un secret commun et à authentifier le serveur ; le trafic est ensuite chiffré en symétrique (AES-GCM), mille fois plus rapide. C'est le chiffrement hybride : la sécurité de l'un, la vitesse de l'autre. Asymmetric crypto (ECDHE + certificate) is only used to establish a shared secret and authenticate the server; traffic is then encrypted symmetrically (AES-GCM), a thousand times faster. That's hybrid encryption: one's security, the other's speed.
Décris le handshake TLS 1.3 en quatre étapes. Describe the TLS 1.3 handshake in four steps.
1) ClientHello : versions, ciphers, part Diffie-Hellman éphémère. 2) ServerHello : sa part DH, son certificat, une signature de sa clé privée. 3) Chacun dérive la même clé de session sans qu'elle circule. 4) Trafic chiffré en symétrique (AES-GCM). Un seul aller-retour. 1) ClientHello: versions, ciphers, ephemeral Diffie-Hellman share. 2) ServerHello: its DH share, its certificate, a signature from its private key. 3) Both derive the same session key without it ever traveling. 4) Traffic encrypted symmetrically (AES-GCM). One single round trip.
À quoi sert un certificat TLS et que contient-il ? What is a TLS certificate for, and what does it contain?
Il authentifie le serveur (il ne chiffre rien) : il lie une clé publique à un domaine, avec des dates de validité, le tout signé par une CA. Le client remonte la chaîne de confiance (feuille → CA intermédiaire → CA racine préinstallée) pour le valider. It authenticates the server (it encrypts nothing): it binds a public key to a domain, with validity dates, all signed by a CA. The client walks the chain of trust (leaf → intermediate CA → preinstalled root CA) to validate it.
Quelle différence entre chiffrer et signer un message ? What's the difference between encrypting and signing a message?
Chiffrer = clé publique du destinataire, pour la confidentialité : lui seul déchiffre. Signer = clé privée de l'émetteur sur le hash du message, pour l'authenticité et l'intégrité : tout le monde vérifie avec la clé publique. Une signature ne cache rien. Encrypt = the recipient's public key, for confidentiality: only they decrypt. Sign = the sender's private key over the message hash, for authenticity and integrity: anyone verifies with the public key. A signature hides nothing.
Qu'est-ce que la forward secrecy ? What is forward secrecy?
La garantie qu'une compromission future de la clé privée du serveur ne permet pas de déchiffrer le trafic passé. Obtenue avec des clés Diffie-Hellman éphémères (ECDHE) : chaque session a son propre secret, jeté ensuite. Obligatoire en TLS 1.3. The guarantee that a future compromise of the server's private key cannot decrypt past traffic. Achieved with ephemeral Diffie-Hellman keys (ECDHE): each session has its own secret, discarded afterwards. Mandatory in TLS 1.3.
Pourquoi un hash n'est-il pas du chiffrement ? Why is a hash not encryption?
Un hash (SHA-256) est irréversible et sans clé : on ne peut pas retrouver l'entrée, seulement tester des candidats. Le chiffrement est réversible pour qui a la clé. Usages du hash : intégrité, signatures, mots de passe (avec bcrypt/argon2, lents et salés). A hash (SHA-256) is irreversible and keyless: you can't recover the input, only test candidates. Encryption is reversible for whoever holds the key. Hash uses: integrity, signatures, passwords (with bcrypt/argon2, slow and salted).
Qu'apportent TLS 1.3 et Let's Encrypt ? What do TLS 1.3 and Let's Encrypt bring?
TLS 1.3 : handshake en un seul aller-retour, forward secrecy obligatoire, suppression des algos cassés (RC4, SHA-1, échange RSA). Let's Encrypt : certificats gratuits et automatisés via le protocole ACME (renouvelés tous les 90 jours) — le HTTPS partout est devenu la norme. TLS 1.3: one-round-trip handshake, mandatory forward secrecy, removal of broken algorithms (RC4, SHA-1, RSA key exchange). Let's Encrypt: free, automated certificates via the ACME protocol (renewed every 90 days) — HTTPS everywhere became the norm.
QCM Quiz
Pour envoyer un message confidentiel à Alice, avec quelle clé le chiffrez-vous ? To send Alice a confidential message, which key do you encrypt it with?
On chiffre avec la clé publique du destinataire : seule sa clé privée peut déchiffrer. Votre clé privée à vous sert à signer, pas à assurer la confidentialité. You encrypt with the recipient's public key: only their private key can decrypt. Your own private key is for signing, not for confidentiality.
Quel est le problème central que résout le chiffrement asymétrique ? What is the core problem asymmetric encryption solves?
Avec une paire publique/privée, plus besoin de partager un secret à l'avance : la clé publique se distribue librement. C'est justement l'asymétrique qui est lent, pas le symétrique. With a public/private pair, no need to share a secret in advance: the public key is distributed freely. Asymmetric crypto is the slow one, not symmetric.
Dans TLS 1.3, qu'est-ce qui chiffre le trafic après le handshake ? In TLS 1.3, what encrypts the traffic after the handshake?
Le handshake asymétrique ne sert qu'à dériver une clé de session ; tout le trafic passe ensuite en chiffrement symétrique authentifié, mille fois plus rapide. Le certificat, lui, n'a fait qu'authentifier le serveur. The asymmetric handshake only derives a session key; all traffic then uses authenticated symmetric encryption, a thousand times faster. The certificate merely authenticated the server.
Que garantit la forward secrecy ? What does forward secrecy guarantee?
Les clés Diffie-Hellman sont éphémères : chaque session a son secret, jeté ensuite. Compromettre la clé privée du serveur plus tard ne rejoue pas les sessions passées. C'est pour ça que TLS 1.3 a supprimé l'échange de clé RSA. Diffie-Hellman keys are ephemeral: each session has its own secret, discarded afterwards. Compromising the server's private key later cannot replay past sessions. That's why TLS 1.3 removed RSA key exchange.
Quel est le rôle d'une Certificate Authority (CA) ? What is the role of a Certificate Authority (CA)?
La CA signe le certificat : elle atteste que cette clé publique appartient bien à ce domaine. Le client remonte la chaîne jusqu'à une racine préinstallée. La CA ne voit jamais ni clé privée ni trafic. The CA signs the certificate: it attests that this public key really belongs to this domain. The client walks the chain up to a preinstalled root. The CA never sees a private key or any traffic.
Pourquoi stocke-t-on les mots de passe hashés (bcrypt) plutôt que chiffrés ? Why are passwords stored hashed (bcrypt) rather than encrypted?
Chiffré = réversible pour qui a la clé, et la clé traîne sur le serveur. Un hash lent et salé ne se « déchiffre » pas : on ne peut que vérifier une tentative. La taille et la vitesse ne sont pas le sujet. Encrypted = reversible for whoever has the key, and the key sits on the server. A slow, salted hash cannot be "decrypted": you can only verify an attempt. Size and speed are beside the point.
Jour 39 Day 39 Structures & parcours : listes, arbres, graphes Structures & traversals: lists, trees, graphs
Flashcards Flashcards
Tableau vs liste chaînée : forces et faiblesses ? Array vs linked list: strengths and weaknesses?
Tableau : mémoire contiguë, accès par index O(1), cache-friendly, mais insertion/suppression au milieu en O(n). Liste chaînée : insertion/suppression O(1) si on tient déjà le nœud, mais accès et recherche O(n). En pratique le tableau dynamique gagne presque toujours grâce au cache CPU. Array: contiguous memory, O(1) index access, cache-friendly, but O(n) insertion/deletion in the middle. Linked list: O(1) insertion/deletion if you already hold the node, but O(n) access and search. In practice the dynamic array wins almost every time thanks to the CPU cache.
Pile vs file : différence et usages typiques ? Stack vs queue: difference and typical uses?
Pile (stack) = LIFO, push/pop au sommet : call stack, undo, DFS, parsing. File (queue) = FIFO, on entre d'un côté et sort de l'autre : files de tâches, buffers, BFS. Les deux offrent leurs opérations en O(1) — et échanger l'une pour l'autre transforme BFS en DFS. Stack = LIFO, push/pop at the top: call stack, undo, DFS, parsing. Queue = FIFO, in on one side, out on the other: task queues, buffers, BFS. Both offer O(1) operations — and swapping one for the other turns BFS into DFS.
Quel est l'invariant d'un BST, et que produit son parcours in-ordre ? What is the BST invariant, and what does its in-order traversal produce?
Pour chaque nœud, tout le sous-arbre gauche est plus petit et tout le sous-arbre droit plus grand — l'invariant porte sur les sous-arbres entiers, pas seulement les enfants directs. Conséquence : le parcours in-ordre (gauche, nœud, droite) visite les valeurs dans l'ordre trié. For every node, the entire left subtree is smaller and the entire right subtree larger — the invariant covers whole subtrees, not just direct children. Consequence: the in-order traversal (left, node, right) visits the values in sorted order.
Pourquoi équilibrer un BST, et comment font AVL et rouge-noir ? Why balance a BST, and how do AVL and red-black trees do it?
Un BST naïf dégénère en liste chaînée O(n) si on insère des valeurs déjà triées. Les arbres auto-équilibrés (AVL, rouge-noir) se rééquilibrent par rotations à chaque insertion/suppression pour garantir une hauteur en O(log n), donc recherche, insertion et suppression en O(log n) dans le pire cas. A naive BST degenerates into an O(n) linked list if you insert already-sorted values. Self-balancing trees (AVL, red-black) rebalance through rotations on each insertion/deletion to guarantee O(log n) height, hence O(log n) worst-case search, insertion and deletion.
Qu'est-ce qu'un heap et à quoi sert-il ? What is a heap and what is it for?
Un arbre binaire complet où chaque parent est ≤ ses enfants (min-heap) : le minimum est à la racine en O(1), insertion et extraction en O(log n). C'est l'implémentation standard de la priority queue : Dijkstra, ordonnanceurs, top-k, fusion de k listes triées. A complete binary tree where each parent is ≤ its children (min-heap): the minimum sits at the root in O(1), insertion and extraction in O(log n). It's the standard implementation of the priority queue: Dijkstra, schedulers, top-k, merging k sorted lists.
BFS vs DFS : quelle structure de stockage, et lequel donne le plus court chemin ? BFS vs DFS: which storage structure, and which one gives the shortest path?
BFS utilise une file (FIFO) et explore par niveaux : la première visite d'un sommet emprunte un chemin minimal en arêtes → plus court chemin non pondéré. DFS utilise une pile (souvent la call stack, en récursif) et plonge en profondeur : cycles, tri topologique, backtracking. BFS uses a queue (FIFO) and explores by levels: the first visit of a vertex uses a path with minimum edges → unweighted shortest path. DFS uses a stack (often the call stack, recursively) and dives deep: cycles, topological sort, backtracking.
Liste d'adjacence vs matrice d'adjacence : quand choisir quoi ? Adjacency list vs adjacency matrix: when to pick which?
Liste ({sommet: [voisins]}) : O(V+E) en mémoire, itération efficace sur les voisins — idéale pour les graphes creux, c'est-à-dire presque tous les cas réels. Matrice V×V : test d'arête en O(1) mais O(V²) en mémoire — pour les graphes denses ou très petits. List ({vertex: [neighbors]}): O(V+E) memory, efficient neighbor iteration — ideal for sparse graphs, i.e. almost every real-world case. V×V matrix: O(1) edge test but O(V²) memory — for dense or very small graphs.
Dijkstra en une phrase : quand, comment, et sa limite ? Dijkstra in one sentence: when, how, and its limit?
Quand les arêtes ont des poids positifs, Dijkstra généralise BFS en remplaçant la file par une priority queue qui extrait toujours le sommet à distance minimale — plus court chemin pondéré (GPS, routage). Limite : avec des poids négatifs, ses résultats sont faux ; il faut Bellman-Ford. When edges have positive weights, Dijkstra generalizes BFS by replacing the queue with a priority queue that always extracts the minimum-distance vertex — weighted shortest path (GPS, routing). Limit: with negative weights its results are wrong; you need Bellman-Ford.
QCM Quiz
Que produit le parcours in-ordre d'un BST ? What does the in-order traversal of a BST produce?
Gauche < nœud < droite appliqué récursivement : l'in-ordre visite tout dans l'ordre croissant. Par niveaux = BFS ; racine d'abord = pré-ordre. Left < node < right applied recursively: in-order visits everything in ascending order. Level by level = BFS; root first = pre-order.
Quelle structure de données est au cœur de BFS ? Which data structure is at the heart of BFS?
La file garantit l'exploration par niveaux : les sommets à distance k sortent tous avant ceux à distance k+1. Avec une pile, on obtient un DFS ; avec une priority queue, Dijkstra. The queue guarantees level-by-level exploration: all vertices at distance k come out before those at distance k+1. With a stack you get DFS; with a priority queue, Dijkstra.
Plus court chemin dans un graphe NON pondéré : quel algorithme suffit ? Shortest path in an UNWEIGHTED graph: which algorithm is enough?
BFS explore par niveaux : la première visite d'un sommet passe par un chemin minimal en arêtes. DFS ne garantit rien sur la distance ; Dijkstra/Bellman-Ford ne servent qu'avec des poids. BFS explores by levels: the first visit of a vertex uses a minimum-edge path. DFS guarantees nothing about distance; Dijkstra/Bellman-Ford only matter with weights.
Quelle est la complexité d'une recherche dans un BST équilibré de n éléments ? What is the complexity of a search in a balanced BST of n elements?
Chaque comparaison élimine la moitié de l'arbre : hauteur O(log n) si équilibré. Attention : un BST dégénéré (valeurs insérées triées) retombe à O(n). Each comparison eliminates half the tree: O(log n) height when balanced. Careful: a degenerate BST (values inserted in sorted order) falls back to O(n).
Pour un graphe creux (peu d'arêtes), quelle représentation choisir ? For a sparse graph (few edges), which representation do you pick?
Sur un graphe creux, la matrice gaspille O(V²) cases presque toutes vides. La liste stocke exactement les voisins existants — c'est le choix par défaut des cas réels (dépendances, routes, réseaux). On a sparse graph the matrix wastes O(V²) mostly-empty cells. The list stores exactly the existing neighbors — the default choice in real cases (dependencies, roads, networks).
Comment npm peut-il détecter un cycle dans le graphe des dépendances ? How can npm detect a cycle in the dependency graph?
DFS avec les états blanc/gris/noir : une arête vers un sommet gris (encore dans la pile de visite) révèle un cycle. Alternative : le tri topologique de Kahn qui n'épuise pas tous les sommets. DFS with white/gray/black states: an edge to a gray vertex (still on the visit stack) reveals a cycle. Alternative: Kahn's topological sort failing to exhaust all vertices.
Jour 38 Day 38 Linux pour développeur Linux for developers
Flashcards Flashcards
SIGTERM vs SIGKILL : quelle différence ? SIGTERM vs SIGKILL: what's the difference?
SIGTERM (15) est une demande d'arrêt propre : le processus peut l'intercepter pour fermer ses connexions, flusher ses buffers, puis sortir. SIGKILL (9) est ininterceptable : le noyau supprime le processus sans aucun cleanup. `docker stop` envoie SIGTERM, attend 10 s, puis SIGKILL — d'où l'importance de gérer SIGTERM dans une app conteneurisée. SIGTERM (15) is a clean-shutdown request: the process can catch it to close connections, flush buffers, then exit. SIGKILL (9) is uncatchable: the kernel removes the process with zero cleanup. `docker stop` sends SIGTERM, waits 10 s, then SIGKILL — hence the importance of handling SIGTERM in a containerized app.
Que signifie « tout est fichier » sous Linux ? Donne un exemple avec /proc. What does "everything is a file" mean on Linux? Give an example with /proc.
Disques, sockets, état du noyau : tout s'expose via l'interface fichier (lire, écrire, rediriger). /proc est un filesystem virtuel : /proc/<pid>/ décrit chaque processus en cours, `cat /proc/cpuinfo` lit les CPU, /proc/meminfo la mémoire — aucune de ces « données » n'existe sur le disque. Disks, sockets, kernel state: everything is exposed through the file interface (read, write, redirect). /proc is a virtual filesystem: /proc/<pid>/ describes each running process, `cat /proc/cpuinfo` reads the CPUs, /proc/meminfo the memory — none of this "data" exists on disk.
Comment un nouveau processus est-il créé sous Linux ? How is a new process created on Linux?
Par fork() : le parent se clone (même code, mémoire copiée), puis le clone appelle généralement exec() pour remplacer son image par le nouveau programme. Le shell fait fork + exec pour chaque commande tapée, puis wait() pour récupérer le code de sortie de l'enfant. Through fork(): the parent clones itself (same code, copied memory), then the clone usually calls exec() to replace its image with the new program. The shell does fork + exec for every typed command, then wait() to collect the child's exit code.
Que veut dire chmod 755 ? Et 600 ? What does chmod 755 mean? And 600?
Octal : r=4, w=2, x=1, un chiffre par triplet (propriétaire, groupe, autres). 755 = rwxr-xr-x : le propriétaire fait tout, les autres lisent et exécutent — typique d'un script ou d'un répertoire. 600 = rw------- : seul le propriétaire lit et écrit — obligatoire pour une clé SSH privée. Octal: r=4, w=2, x=1, one digit per triplet (owner, group, others). 755 = rwxr-xr-x: the owner does everything, others read and execute — typical for a script or directory. 600 = rw-------: only the owner reads and writes — mandatory for a private SSH key.
Quels sont les trois flux standard d'un processus, et que fait `cmd > f 2>&1` ? What are a process's three standard streams, and what does `cmd > f 2>&1` do?
stdin (0), stdout (1), stderr (2). `> f` redirige stdout vers le fichier f, puis `2>&1` branche stderr sur la destination actuelle de stdout : les deux flux finissent dans f. L'ordre compte : `2>&1 > f` enverrait stderr au terminal. stdin (0), stdout (1), stderr (2). `> f` redirects stdout to file f, then `2>&1` plugs stderr into stdout's current destination: both streams end up in f. Order matters: `2>&1 > f` would send stderr to the terminal.
En quoi consiste la philosophie Unix, et quel opérateur l'incarne ? What is the Unix philosophy, and which operator embodies it?
Chaque programme fait une seule chose bien, le texte est l'interface universelle, et on compose les programmes entre eux. Le pipe `|` l'incarne : il branche la sortie d'un programme sur l'entrée du suivant sans fichier intermédiaire — ex. `grep … | sort | uniq -c | sort -rn` pour analyser des logs. Each program does one thing well, text is the universal interface, and programs compose with each other. The pipe `|` embodies it: it plugs one program's output into the next one's input without an intermediate file — e.g. `grep … | sort | uniq -c | sort -rn` to analyze logs.
À quoi sert le PATH, et pourquoi lance-t-on un script local avec ./ ? What is PATH for, and why do you run a local script with ./?
Le PATH est la liste ordonnée des répertoires où le shell cherche un exécutable quand on tape une commande sans chemin — premier trouvé, premier servi. Le répertoire courant n'y figure pas (sécurité) : il faut donc `./script.sh` pour lancer un script local. `which cmd` montre quel binaire sera exécuté. PATH is the ordered list of directories where the shell looks for an executable when you type a command without a path — first found, first served. The current directory isn't in it (security): hence `./script.sh` to run a local script. `which cmd` shows which binary will run.
Pourquoi préférer les clés SSH aux mots de passe ? Why prefer SSH keys over passwords?
Une paire clé publique/privée : la publique va dans ~/.ssh/authorized_keys du serveur, la privée ne quitte jamais votre machine. Rien à deviner par force brute, pas de secret transmis au serveur, révocation simple (retirer la clé publique), et automatisation possible (CI, déploiements) sans stocker de mot de passe. A public/private key pair: the public key goes into the server's ~/.ssh/authorized_keys, the private one never leaves your machine. Nothing to brute-force, no secret sent to the server, easy revocation (remove the public key), and automation possible (CI, deployments) without storing a password.
QCM Quiz
Que fait `docker stop` pour arrêter un conteneur ? What does `docker stop` do to stop a container?
SIGTERM d'abord pour laisser le PID 1 du conteneur s'arrêter proprement, SIGKILL après le délai de grâce. Si l'app ignore SIGTERM, elle meurt brutalement à chaque déploiement. SIGTERM first so the container's PID 1 can shut down cleanly, SIGKILL after the grace period. If the app ignores SIGTERM, it dies brutally on every deployment.
À quelles permissions correspond chmod 644 ? Which permissions does chmod 644 correspond to?
6 = 4+2 = rw- pour le propriétaire ; 4 = r-- pour le groupe et les autres. C'est le mode standard d'un fichier non exécutable partageable en lecture. 6 = 4+2 = rw- for the owner; 4 = r-- for group and others. It's the standard mode for a non-executable, read-shareable file.
Quelle commande liste les ports en écoute et les processus associés ? Which command lists listening ports and their owning processes?
ss (successeur de netstat) : -t TCP, -l sockets en écoute, -n ports numériques, -p processus propriétaire. ps liste les processus, df l'espace disque. ss (netstat's successor): -t TCP, -l listening sockets, -n numeric ports, -p owning process. ps lists processes, df disk space.
Pourquoi faut-il `sort` avant `uniq -c` dans un pipeline ? Why do you need `sort` before `uniq -c` in a pipeline?
uniq compare chaque ligne à la précédente : des doublons non adjacents sont comptés séparément. Le tri les regroupe d'abord — uniq ne plante pas, il compte juste faux. uniq compares each line to the previous one: non-adjacent duplicates are counted separately. Sorting groups them first — uniq doesn't crash, it just miscounts.
Qu'est-ce que /proc ? What is /proc?
Rien dans /proc n'existe sur le disque : le noyau génère le contenu à la lecture. /proc/<pid>/ décrit chaque processus, /proc/cpuinfo les CPU — illustration directe du « tout est fichier ». Nothing in /proc exists on disk: the kernel generates the content on read. /proc/<pid>/ describes each process, /proc/cpuinfo the CPUs — a direct illustration of "everything is a file".
Comment suivre en direct les logs d'un service systemd ? How do you follow a systemd service's logs live?
journalctl lit le journal de systemd : -u filtre par unité (service), -f suit en continu comme tail -f. `systemctl logs` n'existe pas, et systemd n'écrit pas un fichier par service. journalctl reads systemd's journal: -u filters by unit (service), -f follows continuously like tail -f. `systemctl logs` doesn't exist, and systemd doesn't write one file per service.
Jour 37 Day 37 Concurrence : threads, race conditions & locks Concurrency: threads, race conditions & locks
Flashcards Flashcards
Quelle est la différence entre un processus et un thread ? What is the difference between a process and a thread?
Le processus a son propre espace mémoire, isolé par l'OS ; le thread est un fil d'exécution à l'intérieur d'un processus, qui partage le heap (variables globales, objets) avec les autres threads mais garde sa propre pile. Threads : communication gratuite mais synchronisation obligatoire. Processus : isolation forte, communication explicite (IPC). A process has its own memory space, isolated by the OS; a thread is an execution flow inside a process, sharing the heap (globals, objects) with the other threads but keeping its own stack. Threads: free communication but mandatory synchronization. Processes: strong isolation, explicit communication (IPC).
Concurrence vs parallélisme : quelle différence ? Concurrency vs parallelism: what's the difference?
La concurrence, c'est gérer plusieurs tâches sur la même période (elles peuvent s'entrelacer sur un seul cœur) : une question de structure. Le parallélisme, c'est les exécuter au même instant sur plusieurs cœurs : une question de matériel. Node.js est concurrent sans parallélisme JS ; un calcul découpé sur 8 cœurs est parallèle. Concurrency is dealing with several tasks over the same period (they may interleave on a single core): a matter of structure. Parallelism is executing them at the same instant on several cores: a matter of hardware. Node.js is concurrent without JS parallelism; a computation split across 8 cores is parallel.
Pourquoi `compteur++` n'est-il pas thread-safe ? Why isn't `counter++` thread-safe?
Parce que c'est en réalité trois instructions : load (lire la valeur en mémoire), add (incrémenter le registre), store (réécrire). L'ordonnanceur peut suspendre un thread entre deux instructions : deux threads lisent la même valeur, et l'écriture de l'un écrase celle de l'autre — un incrément est perdu. Because it's actually three instructions: load (read the value from memory), add (increment the register), store (write it back). The scheduler can suspend a thread between two instructions: two threads read the same value, and one write clobbers the other — an increment is lost.
Qu'est-ce qu'une section critique et à quoi sert un mutex ? What is a critical section and what is a mutex for?
La section critique est la portion de code qui lit-modifie-écrit un état partagé. Un mutex (mutual exclusion) garantit qu'un seul thread à la fois l'exécute : les autres bloquent à l'entrée jusqu'à la libération du verrou. Règle d'or : le lock protège des données — tout accès à cet état, lectures comprises, doit passer par le même verrou. The critical section is the code portion that reads-modifies-writes shared state. A mutex (mutual exclusion) guarantees only one thread at a time executes it: the others block at the entrance until the lock is released. Golden rule: a lock protects data — every access to that state, reads included, must go through the same lock.
Quelles sont les quatre conditions d'un deadlock, et le remède le plus courant ? What are the four deadlock conditions, and the most common remedy?
Conditions de Coffman : exclusion mutuelle, rétention et attente (hold & wait), pas de préemption des verrous, attente circulaire. En casser une seule suffit. Remède le plus courant : imposer un ordre global d'acquisition des locks (toujours les prendre dans le même ordre), ce qui rend l'attente circulaire impossible. The Coffman conditions: mutual exclusion, hold & wait, no lock preemption, circular wait. Breaking a single one is enough. Most common remedy: impose a global lock-acquisition order (always take locks in the same order), which makes circular wait impossible.
Qu'est-ce qu'une opération atomique et quand la préférer à un mutex ? What is an atomic operation and when should you prefer it to a mutex?
Une instruction matérielle indivisible (fetch_add, compare-and-swap) qu'aucun autre thread ne peut couper en deux. Pour un simple compteur ou un flag, `std::atomic` / `AtomicInteger` est plus léger qu'un mutex : pas de blocage, pas de deadlock possible. Dès que plusieurs variables doivent rester cohérentes ensemble, il faut revenir au lock. An indivisible hardware instruction (fetch_add, compare-and-swap) that no other thread can cut in half. For a simple counter or flag, `std::atomic` / `AtomicInteger` is lighter than a mutex: no blocking, no possible deadlock. As soon as several variables must stay consistent together, go back to a lock.
Que fait le GIL de Python, et quelle conséquence pratique ? What does Python's GIL do, and what is the practical consequence?
Le Global Interpreter Lock fait qu'un seul thread exécute du bytecode Python à la fois. Conséquence : les threads Python sont utiles pour l'I/O (le GIL est relâché pendant les attentes réseau/disque) mais n'apportent aucun gain sur du calcul pur — pour le CPU-bound, on passe par multiprocessing. The Global Interpreter Lock means only one thread executes Python bytecode at a time. Consequence: Python threads are useful for I/O (the GIL is released during network/disk waits) but bring no gain on pure computation — for CPU-bound work, use multiprocessing.
Async/await ou threads : quel est LE critère de choix ? Async/await or threads: what is THE deciding criterion?
La nature de la charge. I/O-bound (le programme attend : API, DB, fichiers) → async/event loop, qui gère des milliers d'attentes sur un seul thread. CPU-bound (le programme calcule : encodage, crypto, ML) → plusieurs processus ou threads natifs, environ un par cœur. L'async n'accélère jamais un calcul. The nature of the workload. I/O-bound (the program waits: APIs, DB, files) → async/event loop, handling thousands of waits on a single thread. CPU-bound (the program computes: encoding, crypto, ML) → several processes or native threads, roughly one per core. Async never speeds up a computation.
QCM Quiz
Que partagent les threads d'un même processus ? What do the threads of the same process share?
Les threads partagent le heap (objets, globales) — c'est ce qui rend la communication gratuite et les races possibles. Pile et registres restent propres à chaque thread. Threads share the heap (objects, globals) — that's what makes communication free and races possible. Stack and registers stay per-thread.
En combien d'instructions machine `compteur++` se décompose-t-il typiquement ? Into how many machine instructions does `counter++` typically decompose?
Lire la valeur en mémoire, incrémenter le registre, réécrire. L'ordonnanceur peut suspendre le thread entre chacune : c'est là que l'entrelacement perd des écritures. Read the value from memory, increment the register, write it back. The scheduler can suspend the thread between each: that's where interleaving loses writes.
Quelle stratégie casse l'attente circulaire et évite le deadlock ? Which strategy breaks circular wait and avoids deadlock?
Si tous les threads prennent les verrous dans le même ordre, aucun cycle d'attente ne peut se former. Plus de locks ou du sleep ne changent rien aux quatre conditions de Coffman. If every thread takes locks in the same order, no wait cycle can form. More locks or sleeps do nothing about the four Coffman conditions.
Vous devez encoder 1000 vidéos en Python. Quel outil choisir ? You need to encode 1000 videos in Python. Which tool do you pick?
L'encodage est CPU-bound : il faut de vrais cœurs en parallèle. Le GIL neutralise threading pour le calcul, et l'async n'accélère aucun calcul — il ne fait qu'attendre efficacement. Encoding is CPU-bound: you need real cores in parallel. The GIL neutralizes threading for computation, and async speeds up no computation — it only waits efficiently.
Qu'est-ce qui caractérise une race condition ? What characterizes a race condition?
Race condition = résultat non déterministe selon l'entrelacement des threads sur un état partagé non synchronisé. L'attente infinie sur un verrou, c'est le deadlock. Race condition = non-deterministic result depending on thread interleaving over unsynchronized shared state. Waiting forever on a lock is a deadlock.
Pourquoi n'y a-t-il pas de race sur les variables entre deux callbacks JavaScript ? Why is there no race on variables between two JavaScript callbacks?
L'event loop exécute les callbacks un par un sur un seul thread : pas d'accès simultané à la mémoire. Les races logiques restent possibles (réponses qui arrivent dans le désordre). The event loop runs callbacks one at a time on a single thread: no simultaneous memory access. Logical races remain possible (responses arriving out of order).
Jour 36 Day 36 Embeddings & RAG Embeddings & RAG
Flashcards Flashcards
Qu'est-ce qu'un embedding et à quoi sert-il ? What is an embedding and what is it for?
Un vecteur dense de nombres flottants (384 à 3072 dimensions) produit par un modèle entraîné pour que deux textes proches en sens donnent des vecteurs proches. Il permet la recherche sémantique : on retrouve des textes par similarité de sens, pas par mots-clés. A dense vector of floats (384 to 3072 dimensions) produced by a model trained so that texts close in meaning yield close vectors. It enables semantic search: finding texts by similarity of meaning, not by keywords.
Comment mesure-t-on la proximité entre deux embeddings ? How do you measure how close two embeddings are?
Avec la similarité cosinus : le cosinus de l'angle entre les deux vecteurs (1 = même direction, 0 = sans rapport). Avec des vecteurs normalisés, c'est un simple produit scalaire, et le classement est identique à celui de la distance euclidienne. With cosine similarity: the cosine of the angle between the two vectors (1 = same direction, 0 = unrelated). With normalized vectors it's a simple dot product, and the ranking matches Euclidean distance.
Décris les deux phases du pipeline RAG. Describe the two phases of the RAG pipeline.
Indexation (offline) : documents → chunking → embedding de chaque chunk → stockage en base vectorielle avec texte et métadonnées. Requête (online) : question → embedding (même modèle) → recherche top-k par similarité → chunks injectés dans le prompt → génération par le LLM. Indexing (offline): documents → chunking → embedding of each chunk → storage in a vector database with text and metadata. Query (online): question → embedding (same model) → top-k similarity search → chunks injected into the prompt → LLM generation.
Pourquoi choisir RAG plutôt que fine-tuning pour de la connaissance d'entreprise ? Why choose RAG over fine-tuning for company knowledge?
Fraîcheur (réindexer un document suffit, pas de réentraînement), coût (embeddings marginaux contre GPU + dataset), citations (sources traçables et vérifiables). Le fine-tuning sert à modifier le comportement (ton, format), pas à injecter des faits. Freshness (reindexing a document is enough, no retraining), cost (marginal embeddings versus GPUs + dataset), citations (traceable, verifiable sources). Fine-tuning is for changing behavior (tone, format), not injecting facts.
Qu'est-ce que pgvector et quand le préférer à une base vectorielle dédiée ? What is pgvector and when should you prefer it over a dedicated vector database?
Une extension PostgreSQL qui ajoute un type vecteur, la recherche par similarité et des index HNSW/IVFFlat. À préférer par défaut : les vecteurs restent dans la base qu'on administre déjà, avec SQL et jointures. Les bases dédiées (Qdrant, Weaviate, Pinecone) ne se justifient qu'à très grande échelle. A PostgreSQL extension adding a vector type, similarity search and HNSW/IVFFlat indexes. Prefer it by default: vectors stay in the database you already run, with SQL and joins. Dedicated databases (Qdrant, Weaviate, Pinecone) only pay off at very large scale.
Qu'est-ce que le chunking et pourquoi un chunking naïf pose-t-il problème ? What is chunking and why is naive chunking a problem?
Le découpage des documents en morceaux avant embedding. Un découpage naïf (tous les N caractères) coupe phrases et tableaux en deux → chunks incompréhensibles et retrieval dégradé. Mieux : découper selon la structure (titres, paragraphes) avec 10-20 % de chevauchement. Splitting documents into pieces before embedding. Naive splitting (every N characters) cuts sentences and tables in half → incomprehensible chunks and degraded retrieval. Better: split along structure (headings, paragraphs) with 10-20% overlap.
Qu'apportent la recherche hybride et le reranking ? What do hybrid search and reranking bring?
L'hybride combine recherche lexicale (BM25, exacte sur les mots — attrape codes d'erreur et références) et vectorielle (sémantique), fusionnées par RRF. Le reranking re-classe les ~50 premiers candidats avec un cross-encoder plus précis mais plus lent, pour un top-5 de qualité. Hybrid combines lexical search (BM25, exact on words — catches error codes and references) and vector search (semantic), fused with RRF. Reranking re-orders the top ~50 candidates with a more precise but slower cross-encoder, yielding a high-quality top-5.
Comment évalue-t-on un système RAG ? How do you evaluate a RAG system?
Le retrieval d'abord : sur un jeu de questions annotées, mesurer si les bons chunks remontent (recall@k). Ensuite seulement la génération : fidélité au contexte, taux de citation. Si le retrieval rate, aucun prompt ne sauvera la réponse. Retrieval first: on an annotated question set, measure whether the right chunks come back (recall@k). Only then generation: faithfulness to context, citation rate. If retrieval misses, no prompt will save the answer.
QCM Quiz
Deux textes ont une similarité cosinus proche de 1. Qu'est-ce que cela signifie ? Two texts have a cosine similarity close to 1. What does that mean?
La similarité cosinus mesure l'angle entre les vecteurs, donc la proximité sémantique — indépendamment des mots exacts, de la longueur ou de la provenance. Cosine similarity measures the angle between vectors, i.e. semantic proximity — regardless of exact words, length or origin.
Dans un pipeline RAG, que fait-on au moment de la requête utilisateur ? In a RAG pipeline, what happens at user query time?
Le corpus est indexé offline ; à la requête, seul l'embedding de la question est calculé, puis recherche kNN et injection du contexte. Aucun réentraînement, jamais tout le corpus. The corpus is indexed offline; at query time only the question's embedding is computed, then kNN search and context injection. No retraining, never the whole corpus.
Ton RAG donne de mauvaises réponses. Quel est le premier réflexe de débogage ? Your RAG gives bad answers. What is the first debugging reflex?
Le retrieval d'abord : la plupart des mauvaises réponses viennent de mauvais chunks. Si le contexte ne contient pas la réponse, ni le prompt ni un LLM plus gros n'y changeront rien. Retrieval first: most bad answers come from bad chunks. If the context doesn't contain the answer, neither the prompt nor a bigger LLM will fix it.
Pourquoi la recherche hybride (BM25 + vecteurs) est-elle utile ? Why is hybrid search (BM25 + vectors) useful?
Les embeddings capturent le sens mais ratent souvent les identifiants exacts ; BM25 les attrape lexicalement. Les deux listes sont fusionnées (RRF). C'est complémentaire au reranking, pas un remplacement. Embeddings capture meaning but often miss exact identifiers; BM25 catches them lexically. The two result lists are fused (RRF). It complements reranking, not replaces it.
Que se passe-t-il si on indexe avec un modèle d'embedding et qu'on requête avec un autre ? What happens if you index with one embedding model and query with another?
Chaque modèle définit son propre espace vectoriel. Même à dimensions égales, les axes n'ont aucun rapport : le retrieval devient du bruit. Changer de modèle impose de tout réindexer. Each model defines its own vector space. Even with equal dimensions, the axes are unrelated: retrieval becomes noise. Switching models forces a full reindex.
Quel cas justifie le fine-tuning plutôt que le RAG ? Which case justifies fine-tuning rather than RAG?
Le fine-tuning modifie le comportement (style, format, respect de consignes). Fraîcheur des données et citations sont précisément les points forts du RAG. Fine-tuning changes behavior (style, format, instruction following). Data freshness and citations are exactly RAG's strong points.
Jour 35 Day 35 Sécurité front : XSS, CSRF, CORS & CSP Front-end security: XSS, CSRF, CORS & CSP
Flashcards Flashcards
Quels sont les trois types de XSS ? What are the three types of XSS?
Stocké : le payload est persisté (commentaire en DB) et servi à tous les visiteurs. Réfléchi : le payload voyage dans l'URL et est renvoyé dans la page (il faut faire cliquer la victime). DOM-based : la faille est entièrement côté client, le JS injecte une donnée non fiable dans le DOM (innerHTML). Stored: the payload is persisted (comment in DB) and served to every visitor. Reflected: the payload travels in the URL and is echoed back into the page (the victim must click). DOM-based: the flaw is entirely client-side, JS injects untrusted data into the DOM (innerHTML).
Pourquoi innerHTML est-il dangereux et comment le neutraliser ? Why is innerHTML dangerous and how do you neutralize it?
innerHTML interprète la chaîne comme du HTML : un `<img src=x onerror=...>` s'exécute. Neutralisation : textContent quand on affiche du texte (le payload s'affiche sans s'exécuter) ; si on a vraiment besoin de HTML riche, sanitizer avec DOMPurify. En React, même règle pour dangerouslySetInnerHTML. innerHTML interprets the string as HTML: an `<img src=x onerror=...>` executes. Neutralization: textContent when displaying text (the payload is shown, not executed); if you genuinely need rich HTML, sanitize with DOMPurify. In React, same rule for dangerouslySetInnerHTML.
Comment fonctionne une attaque CSRF ? How does a CSRF attack work?
Le navigateur joint automatiquement les cookies d'un site à toute requête vers ce site. Un site malveillant fait donc soumettre (formulaire caché auto-submit) une requête vers bank.com par le navigateur d'une victime connectée : le cookie de session part avec, le serveur voit une requête authentifiée valide. L'attaquant n'exécute aucun code sur bank.com. The browser automatically attaches a site's cookies to any request headed to it. A malicious site therefore makes a logged-in victim's browser submit (hidden auto-submitted form) a request to bank.com: the session cookie goes along, and the server sees a valid authenticated request. The attacker executes no code on bank.com.
Que valent Strict, Lax et None pour l'attribut SameSite d'un cookie ? What do Strict, Lax and None mean for a cookie's SameSite attribute?
Strict : le cookie ne part jamais en contexte cross-site (même en cliquant un lien). Lax (défaut moderne) : il part uniquement sur les navigations top-level en GET. None : il part toujours, et exige Secure. Lax bloque le CSRF classique en POST — d'où la règle « jamais de mutation d'état en GET ». Strict: the cookie never travels in cross-site contexts (even when clicking a link). Lax (modern default): it only travels on top-level GET navigations. None: it always travels, and requires Secure. Lax blocks classic POST CSRF — hence the rule "never mutate state on GET".
Qu'est-ce que CORS et qui l'applique ? What is CORS and who enforces it?
Un assouplissement contrôlé de la same-origin policy : le serveur déclare via Access-Control-Allow-Origin quelles origines web peuvent lire ses réponses. Il est appliqué par le navigateur uniquement — curl, Postman ou un autre serveur l'ignorent. CORS protège les utilisateurs, pas l'API : la sécurité serveur reste l'authentification/autorisation. A controlled relaxation of the same-origin policy: the server declares via Access-Control-Allow-Origin which web origins may read its responses. It is enforced by the browser only — curl, Postman or another server ignore it. CORS protects users, not the API: server security remains authentication/authorization.
Qu'est-ce qu'un preflight CORS et quand a-t-il lieu ? What is a CORS preflight and when does it happen?
Une requête OPTIONS envoyée automatiquement par le navigateur avant une requête « non simple » (Content-Type JSON, headers custom, PUT/DELETE…). Le serveur y répond avec les méthodes, headers et origines autorisés (Access-Control-Allow-*). Si le preflight échoue, la vraie requête n'est jamais envoyée : c'est l'« erreur CORS » de la console. An OPTIONS request the browser automatically sends before a "non-simple" request (JSON Content-Type, custom headers, PUT/DELETE…). The server replies with the allowed methods, headers and origins (Access-Control-Allow-*). If the preflight fails, the real request is never sent: that's the console's "CORS error".
À quoi sert une CSP (Content Security Policy) ? What is a CSP (Content Security Policy) for?
C'est une liste blanche déclarative (header HTTP) de ce que la page peut charger et exécuter : script-src, img-src, frame-ancestors… Bien configurée (sans 'unsafe-inline'), elle bloque l'exécution des scripts inline injectés : même si un payload XSS passe l'échappement, il ne s'exécute pas. Défense en profondeur, pas un remplacement de l'échappement. A declarative allowlist (HTTP header) of what the page may load and execute: script-src, img-src, frame-ancestors… Properly configured (without 'unsafe-inline'), it blocks injected inline scripts from executing: even if an XSS payload gets past escaping, it doesn't run. Defense in depth, not a replacement for escaping.
localStorage vs cookie httpOnly pour stocker un token : quel arbitrage ? localStorage vs httpOnly cookie for storing a token: what's the trade-off?
localStorage : lisible par le JS, donc n'importe quel XSS exfiltre le token. Cookie httpOnly : illisible par le JS (le XSS ne peut plus voler le token) mais envoyé automatiquement, donc exposé au CSRF — à couvrir avec SameSite + token anti-CSRF. Recommandation générale : cookie httpOnly + Secure + SameSite. Un XSS reste grave dans les deux cas. localStorage: readable by JS, so any XSS exfiltrates the token. httpOnly cookie: unreadable by JS (XSS can no longer steal the token) but sent automatically, hence exposed to CSRF — covered with SameSite + an anti-CSRF token. General recommendation: httpOnly + Secure + SameSite cookie. XSS remains serious either way.
QCM Quiz
Que protège réellement CORS ? What does CORS actually protect?
CORS est appliqué par le navigateur uniquement : tout client hors navigateur l'ignore. Il protège les utilisateurs (leurs cookies, leurs sessions), pas votre serveur — la sécurité de l'API, c'est l'authentification et l'autorisation. CORS is enforced by the browser only: any non-browser client ignores it. It protects users (their cookies, their sessions), not your server — API security is authentication and authorization.
Pourquoi une attaque CSRF fonctionne-t-elle sans exécuter de code sur le site cible ? Why does a CSRF attack work without executing any code on the target site?
Tout le CSRF repose sur ce comportement : un formulaire auto-soumis depuis evil.site vers bank.com part AVEC le cookie de session de la victime. Parades : token anti-CSRF, SameSite, vérification de l'Origin. All of CSRF rests on that behavior: a form auto-submitted from evil.site to bank.com goes out WITH the victim's session cookie. Defenses: anti-CSRF token, SameSite, Origin check.
Un utilisateur poste le commentaire `<img src=x onerror="alert(1)">`. Quelle ligne l'affiche sans l'exécuter ? A user posts the comment `<img src=x onerror="alert(1)">`. Which line displays it without executing it?
textContent traite la chaîne comme du texte brut : le payload s'affiche à l'écran mais n'est jamais interprété comme du HTML. innerHTML et document.write interprètent le HTML (le onerror s'exécute), eval exécute directement du JS. textContent treats the string as plain text: the payload is displayed on screen but never interpreted as HTML. innerHTML and document.write parse the HTML (the onerror fires), eval executes JS directly.
Quel est le principal risque d'un JWT stocké en localStorage ? What is the main risk of a JWT stored in localStorage?
localStorage est lisible par tout JS de la page : un XSS exfiltre le token en une ligne. C'est le cookie (envoyé automatiquement) qui expose au CSRF — localStorage, lui, n'est jamais envoyé automatiquement. localStorage is readable by any JS on the page: an XSS exfiltrates the token in one line. It's the cookie (sent automatically) that exposes to CSRF — localStorage is never sent automatically.
Quand le navigateur envoie-t-il un preflight OPTIONS ? When does the browser send an OPTIONS preflight?
Les requêtes « simples » (GET/POST en form-urlencoded, sans header custom) partent directement. Le reste déclenche un OPTIONS préalable : le serveur doit répondre avec les Access-Control-Allow-* adéquats, sinon la vraie requête n'est jamais envoyée. "Simple" requests (GET/POST as form-urlencoded, no custom headers) go straight out. Everything else triggers a prior OPTIONS: the server must reply with the right Access-Control-Allow-* headers, or the real request is never sent.
Pourquoi `'unsafe-inline'` dans script-src vide-t-il une CSP de son intérêt ? Why does `'unsafe-inline'` in script-src defeat a CSP's purpose?
L'intérêt majeur d'une CSP anti-XSS est de bloquer les scripts inline injectés ; 'unsafe-inline' les réautorise tous. Pour les scripts inline légitimes, on utilise des nonces ou des hashes, pas 'unsafe-inline'. The main anti-XSS value of a CSP is blocking injected inline scripts; 'unsafe-inline' re-allows them all. For legitimate inline scripts, use nonces or hashes, not 'unsafe-inline'.
Jour 34 Day 34 Kafka & l'event-driven Kafka & event-driven architecture
Flashcards Flashcards
Quelle est la différence fondamentale entre Kafka et une file de messages comme RabbitMQ ? What is the fundamental difference between Kafka and a message queue like RabbitMQ?
Kafka est un log distribué append-only : lire ne détruit rien, chaque consommateur avance son propre offset dans un journal immuable conservé selon une rétention (replay possible). RabbitMQ est une file : un message consommé et acquitté est supprimé, et le routage (exchanges, bindings) y est beaucoup plus riche. Kafka is a distributed append-only log: reading destroys nothing, each consumer advances its own offset through an immutable journal kept per a retention policy (replay possible). RabbitMQ is a queue: a consumed and acked message is deleted, and routing (exchanges, bindings) is much richer.
Topic, partition, offset : définitions ? Topic, partition, offset: definitions?
Un topic est un flux nommé d'événements, découpé en partitions. Chaque partition est un journal ordonné et immuable ; chaque message y reçoit un offset croissant. La partition est l'unité d'ordre et de parallélisme ; l'offset est le curseur de lecture de chaque groupe de consommateurs. A topic is a named stream of events, split into partitions. Each partition is an ordered, immutable log; each message in it gets an increasing offset. The partition is the unit of ordering and parallelism; the offset is each consumer group's read cursor.
Quelle est la règle d'assignation des partitions dans un consumer group ? What is the partition assignment rule in a consumer group?
Au sein d'un groupe, chaque partition est assignée à exactement un consumer (un consumer peut avoir plusieurs partitions). Conséquence : le parallélisme maximal d'un groupe = le nombre de partitions ; les consumers excédentaires restent idle. Ajouter/retirer un consumer déclenche un rebalance. Within a group, each partition is assigned to exactly one consumer (a consumer can hold several partitions). Consequence: a group's maximum parallelism = the partition count; extra consumers sit idle. Adding/removing a consumer triggers a rebalance.
Quel rôle joue la clé de partitionnement ? What role does the partition key play?
Le producteur hash la clé pour choisir la partition : tous les événements d'une même clé vont dans la même partition et y restent ordonnés. Kafka ne garantit l'ordre QUE par partition — les événements devant rester ordonnés entre eux doivent donc partager la même clé (ex. order-id). Sans clé : round-robin, aucun ordre. The producer hashes the key to pick the partition: all events with the same key go to the same partition and stay ordered there. Kafka guarantees order ONLY per partition — events that must stay ordered relative to each other must share the same key (e.g. order-id). Without a key: round-robin, no ordering.
Qu'est-ce que le replay et pourquoi est-ce un avantage majeur de Kafka ? What is replay and why is it a major Kafka advantage?
Les messages restent dans le log jusqu'à expiration de la rétention (temps/taille), lus ou non. On peut donc remettre les offsets d'un groupe en arrière et retraiter tout l'historique : reconstruire un cache, alimenter un nouveau service, rejouer après un bug. Une queue classique supprime à la consommation : replay impossible. Messages stay in the log until retention expires (time/size), read or not. You can therefore rewind a group's offsets and reprocess the whole history: rebuild a cache, feed a new service, replay after a bug. A classic queue deletes on consumption: no replay possible.
At-least-once, at-most-once, exactly-once : que garantit Kafka par défaut ? At-least-once, at-most-once, exactly-once: what does Kafka guarantee by default?
Par défaut : at-least-once — si le consumer crash entre le traitement et le commit d'offset, le message est relivré (doublons possibles). Committer avant de traiter = at-most-once (perte possible). L'exactly-once (producteur idempotent + transactions) vaut surtout en périmètre Kafka→Kafka ; bout en bout, on vise at-least-once + consumer idempotent. By default: at-least-once — if the consumer crashes between processing and committing the offset, the message is redelivered (duplicates possible). Committing before processing = at-most-once (possible loss). Exactly-once (idempotent producer + transactions) mostly holds within Kafka→Kafka; end to end, aim for at-least-once + an idempotent consumer.
Event sourcing et CQRS en une phrase chacun ? Event sourcing and CQRS in one sentence each?
Event sourcing : stocker la séquence d'événements comme source de vérité et reconstruire l'état en les rejouant (audit complet, replay, mais complexité réelle : versionnage, projections). CQRS : séparer le modèle d'écriture (commandes → événements) du modèle de lecture (projections optimisées). On peut être event-driven sans faire d'event sourcing complet. Event sourcing: store the sequence of events as the source of truth and rebuild state by replaying them (full audit, replay, but real complexity: versioning, projections). CQRS: separate the write model (commands → events) from the read model (optimized projections). You can be event-driven without doing full event sourcing.
Quand Kafka est-il overkill ? When is Kafka overkill?
Faible volume, un seul consommateur, pas de besoin de replay : une table jobs en Postgres, RabbitMQ ou Redis Streams suffisent pour une fraction du coût opérationnel (cluster de brokers, monitoring, rebalances). Kafka se justifie par : gros volumes, plusieurs lecteurs indépendants, replay/rétention, streaming temps réel. Low volume, a single consumer, no replay needs: a jobs table in Postgres, RabbitMQ or Redis Streams suffice at a fraction of the operational cost (broker cluster, monitoring, rebalances). Kafka is justified by: large volumes, several independent readers, replay/retention, real-time streaming.
QCM Quiz
Un topic a 3 partitions et un consumer group compte 5 consumers. Combien consomment réellement ? A topic has 3 partitions and a consumer group has 5 consumers. How many actually consume?
Dans un groupe, une partition est assignée à exactement un consumer : le parallélisme maximal = le nombre de partitions. Les consumers excédentaires sont idle (utiles seulement comme standby en cas de panne). Within a group, a partition is assigned to exactly one consumer: maximum parallelism = the partition count. Extra consumers are idle (useful only as standby in case of failure).
Que garantit Kafka concernant l'ordre des messages ? What does Kafka guarantee about message ordering?
L'ordre n'existe que par partition. Pour ordonner les événements d'une même entité, on leur donne la même clé (même partition). L'ordre global sur un topic multi-partitions n'existe pas, quel que soit le nombre de producteurs. Ordering only exists per partition. To order one entity's events, give them the same key (same partition). Global ordering on a multi-partition topic does not exist, regardless of producer count.
Un consumer crash après avoir traité un message mais avant de committer l'offset. Que se passe-t-il ? A consumer crashes after processing a message but before committing the offset. What happens?
C'est la définition de l'at-least-once : au redémarrage (ou après rebalance), la lecture reprend au dernier offset committé, donc le message est retraité. Le traitement doit être idempotent (clé unique, upsert, dédoublonnage). That's the definition of at-least-once: on restart (or after a rebalance), reading resumes from the last committed offset, so the message is reprocessed. Processing must be idempotent (unique key, upsert, deduplication).
Où vont deux messages produits avec la même clé « user-42 » ? Where do two messages produced with the same key "user-42" go?
hash(clé) mod nombre de partitions : même clé → même partition → ordre préservé pour cette clé. Attention : changer le nombre de partitions change ce mapping pour les nouveaux messages. hash(key) mod partition count: same key → same partition → order preserved for that key. Careful: changing the partition count changes this mapping for new messages.
Que devient un message Kafka une fois lu par tous les consumer groups ? What happens to a Kafka message once every consumer group has read it?
La lecture est non destructive : le log ne dépend pas des consommateurs, seul le temps (ou la taille) configuré en rétention supprime les messages. C'est ce qui rend le replay possible. Reading is non-destructive: the log doesn't depend on consumers; only the configured retention time (or size) deletes messages. That's what makes replay possible.
Quel cas d'usage justifie RabbitMQ plutôt que Kafka ? Which use case favors RabbitMQ over Kafka?
Des tâches à exécuter une fois par un pool de workers = le modèle file : RabbitMQ excelle (ack, retry, routage riche). Replay, lecteurs multiples indépendants et très gros débit sont les points forts du log Kafka. Tasks to be executed once by a worker pool = the queue model: RabbitMQ excels (ack, retry, rich routing). Replay, multiple independent readers and very high throughput are the strengths of Kafka's log.
Actu News Plugin4Shell : une seule faille ouvre les quatre agents de code, et deux éditeurs sur quatre n'ont rien corrigé Plugin4Shell: one flaw opens all four coding agents, and two vendors out of four shipped nothing
Flashcards Flashcards
Qu'est-ce que Plugin4Shell, divulgué le 17 septembre 2026, et quels produits sont touchés ? What is Plugin4Shell, disclosed on September 17, 2026, and which products are affected?
Une exécution de code à distance sans aucune action de l'utilisateur (zéro clic), découverte par le labo Air Security, présente simultanément dans les quatre principaux agents de code : Claude Code, OpenAI Codex, GitHub Copilot et Gemini CLI. Un plugin compromis s'exécute avec les permissions du développeur qui lance l'agent : code source local, identifiants cloud, clés SSH, dépôts internes, accès de production. C'est la première faille de chaîne d'approvisionnement de l'écosystème des agents. A remote code execution needing no user action at all (zero-click), found by the Air Security lab, present simultaneously in the four major coding agents: Claude Code, OpenAI Codex, GitHub Copilot and Gemini CLI. A compromised plugin runs with the permissions of the developer launching the agent: local source code, cloud credentials, SSH keys, internal repositories, production access. It is the first supply chain vulnerability of the agent ecosystem.
Comment fonctionne techniquement le contournement du pin SHA dans Plugin4Shell ? How does the SHA pinning bypass in Plugin4Shell work technically?
L'agent épingle un commit SHA de 40 caractères hexadécimaux et fait un git checkout dessus, mais ne vérifie jamais que l'arbre de travail correspond bien à ce commit. Or git autorise des noms de branche qui ressemblent à un hash : l'attaquant crée une branche nommée exactement comme le SHA épinglé, la déclare branche par défaut, et le checkout résout vers la branche au lieu du commit. Gemini CLI tombait par une variante, un défaut séparé dans la récupération du commit. Le correctif tient en deux lignes : comparer git rev-parse HEAD au SHA attendu après le checkout et échouer si ça diverge. The agent pins a 40-character hexadecimal commit SHA and runs git checkout on it, but never verifies that the working tree actually matches that commit. Git allows branch names that look like a hash: the attacker creates a branch named exactly like the pinned SHA, makes it the default branch, and the checkout resolves to the branch instead of the commit. Gemini CLI fell through a variant, a separate flaw in commit fetching. The fix is two lines: compare git rev-parse HEAD to the expected SHA after checkout and fail if they diverge.
Pourquoi Plugin4Shell est-il qualifié de zéro clic, et où en sont les correctifs ? Why is Plugin4Shell called zero-click, and where do the patches stand?
Zéro clic parce que Claude Code et Codex mettent à jour les plugins installés en arrière-plan par défaut : l'attaquant publie un plugin d'apparence honnête, attend son adoption, puis modifie le dépôt amont, et la mise à jour automatique rejoue le checkout vulnérable sans intervention. Chronologie : découverte en mai 2026, signalement aux quatre éditeurs en juin. Anthropic a corrigé le 17 juin (Claude Code 2.1.179), OpenAI dans Codex 0.146.0 vérifié le 12 août, Google a annoncé le 4 août qu'il ne corrigerait pas (Gemini CLI déprécié au profit d'Antigravity) et GitHub n'avait pas publié de correctif pour Copilot à la divulgation. Zero-click because Claude Code and Codex update installed plugins in the background by default: the attacker publishes an honest-looking plugin, waits for adoption, then modifies the upstream repository, and the auto-update replays the vulnerable checkout with no user involvement. Timeline: found in May 2026, disclosed to all four vendors in June. Anthropic fixed it on June 17 (Claude Code 2.1.179), OpenAI in Codex 0.146.0 verified August 12, Google announced on August 4 that it would not patch (Gemini CLI deprecated in favour of Antigravity), and GitHub had no fix for Copilot at disclosure time.
Que dit le R&D Automation Index publié par Anthropic le 17 septembre 2026 ? What does Anthropic's R&D Automation Index, published September 17, 2026, say?
Claude mène 26 % du travail de R&D IA d'Anthropic en août 2026, contre moins de 1 % en février. « Mener » signifie exécuter l'essentiel d'une tâche de bout en bout depuis une consigne de haut niveau, avec un humain qui supervise ; la participation dépasse 90 % du travail mais l'autonomie complète est à 0 %. L'échelle va de AL0 à AL5, définie par Epoch AI. Environ 30 000 agents travaillent en permanence, et sur plus d'un milliard de décisions en août, 1 sur 47 000 (0,002 %) a été bloquée par le monitoring en ligne. Claude leads 26% of Anthropic's AI R&D work as of August 2026, against under 1% in February. 'Leads' means completing most of a task end to end from a high-level prompt, with a human supervising; participation exceeds 90% of the work but full autonomy sits at 0%. The scale runs AL0 to AL5, defined by Epoch AI. Roughly 30,000 agents work at any given time, and out of more than a billion decisions in August, 1 in 47,000 (0.002%) was blocked by the online monitor.
QCM Quiz
Quelle est la cause racine de Plugin4Shell ? What is the root cause of Plugin4Shell?
Aucune clé n'a été volée et git se comporte comme documenté : il autorise des noms de branche qui ressemblent à un hash. Le défaut est entièrement côté agents, qui demandaient le bon commit et acceptaient ce qu'ils recevaient. L'attaquant crée une branche nommée exactement comme le SHA épinglé et la déclare branche par défaut. C'est un time of check to time of use appliqué à la chaîne d'approvisionnement, et le correctif tient à comparer git rev-parse HEAD au SHA attendu. No key was stolen and git behaves as documented: it allows branch names that look like a hash. The defect is entirely on the agent side, asking for the right commit and accepting whatever came back. The attacker creates a branch named exactly like the pinned SHA and makes it the default branch. It is a time-of-check-to-time-of-use issue applied to the supply chain, and the fix is comparing git rev-parse HEAD to the expected SHA.
Quel est l'état des correctifs pour Plugin4Shell au moment de la divulgation publique ? What was the patch status for Plugin4Shell at public disclosure?
Air Security a découvert la faille en mai 2026 et l'a signalée aux quatre éditeurs en juin. Anthropic a corrigé dès le 17 juin dans Claude Code 2.1.179 et OpenAI dans Codex 0.146.0, vérifié le 12 août. Google a annoncé le 4 août qu'il ne corrigerait pas Gemini CLI, déprécié au profit d'Antigravity, et GitHub n'avait rien publié pour Copilot. Retenir la nuance : déprécié n'est pas corrigé, l'outil reste installé sur des milliers de machines. Air Security found the flaw in May 2026 and disclosed to all four vendors in June. Anthropic fixed it as early as June 17 in Claude Code 2.1.179 and OpenAI in Codex 0.146.0, verified August 12. Google announced on August 4 that it would not patch Gemini CLI, deprecated in favour of Antigravity, and GitHub had published nothing for Copilot. Keep the nuance: deprecated is not fixed, the tool stays installed on thousands of machines.
Que s'est-il réellement passé dans l'incident Gemini divulgué le 18 septembre 2026 ? What actually happened in the Gemini incident disclosed on September 18, 2026?
Il s'agit d'une erreur de configuration du banc de test, pas d'une attaque. Dans un cas, le modèle a deviné des mots de passe en boucle jusqu'à entrer dans un service protégé ; dans deux autres, il a trouvé des identifiants exposés dans des dépôts publics et s'en est servi pour s'authentifier. Dans les trois cas il s'est arrêté en comprenant que la cible était réelle. Irregular a prévenu Google fin juillet, et Google estime que ce n'est pas un désalignement puisque les garde-fous ont fonctionné. C'est le premier cas connu de piratage non dirigé par un modèle de Google. This was a test-harness misconfiguration, not an attack. In one run the model guessed passwords repeatedly until it entered a protected service; in two others it found exposed credentials in public repositories and used them to authenticate. In all three cases it stopped once it realised the target was real. Irregular notified Google in late July, and Google holds that this is not misalignment since the safeguards worked. It is the first known case of an undirected hack by a Google model.
Jour 33 Day 33 Debugger méthodiquement Systematic debugging
Flashcards Flashcards
Quelles sont les étapes de la méthode scientifique appliquée au debugging ? What are the steps of the scientific method applied to debugging?
1) Reproduire le bug de façon fiable ; 2) réduire au cas minimal (par dichotomie) ; 3) formuler une hypothèse falsifiable ; 4) mener une expérience en ne changeant qu'une variable à la fois ; 5) hypothèse confirmée → corriger + test de non-régression, réfutée → nouvelle hypothèse. 1) Reproduce the bug reliably; 2) reduce to a minimal case (by bisection); 3) form a falsifiable hypothesis; 4) run an experiment changing only one variable at a time; 5) hypothesis confirmed → fix + regression test, refuted → new hypothesis.
Pourquoi ne changer qu'une variable à la fois pendant une expérience de debugging ? Why change only one variable at a time during a debugging experiment?
Si on change deux choses et que le bug disparaît, impossible de savoir laquelle était la cause — et on a peut-être introduit un second bug qui masque le premier. Une expérience doit pouvoir confirmer ou réfuter UNE hypothèse précise. If you change two things and the bug disappears, you can't know which one was the cause — and you may have introduced a second bug masking the first. An experiment must be able to confirm or refute ONE precise hypothesis.
Comment fonctionne git bisect et quelle est sa complexité ? How does git bisect work and what is its complexity?
C'est une recherche binaire dans l'historique Git : on marque un commit `good` et un commit `bad`, Git checkout le commit du milieu, on teste et on répond good/bad, et on converge vers le premier commit cassé en O(log n) — ~10 tests pour 1000 commits. `git bisect run <cmd>` automatise tout via le code de sortie. It's a binary search through Git history: you mark a `good` and a `bad` commit, Git checks out the midpoint, you test and answer good/bad, converging on the first broken commit in O(log n) — ~10 tests for 1000 commits. `git bisect run <cmd>` automates it via the exit code.
Debugger vs printf : quand utiliser lequel ? Debugger vs printf: when to use which?
Debugger : explorer un état complexe à un instant T — breakpoints (y compris conditionnels), watch, step over/into, sans redéployer. printf/logs : capturer une chronologie (asynchrone, bugs intermittents) et déboguer la prod, où les logs sont le seul debugger disponible. Les deux sont complémentaires. Debugger: exploring complex state at a point in time — breakpoints (including conditional), watch, step over/into, without redeploying. printf/logs: capturing a timeline (async code, intermittent bugs) and debugging prod, where logs are the only debugger available. The two are complementary.
Pourquoi un bug peut-il disparaître dès qu'on lance le debugger ou qu'on ajoute un print ? Why can a bug disappear as soon as you attach a debugger or add a print?
C'est un heisenbug : l'observation modifie l'expérience. Le debugger fige les threads et le print ralentit l'exécution, ce qui change l'ordonnancement — signature typique d'une race condition ou d'un problème de timing. Réflexe : logging léger horodaté, thread sanitizer, relire les sections critiques. It's a heisenbug: observing changes the experiment. The debugger freezes threads and the print slows execution, altering scheduling — the typical signature of a race condition or timing issue. Reflex: lightweight timestamped logging, thread sanitizer, re-read the critical sections.
Pourquoi le rubber duck debugging fonctionne-t-il ? Why does rubber duck debugging work?
Expliquer le problème à voix haute, ligne par ligne, force à verbaliser et donc à vérifier chaque hypothèse implicite (« ici cette variable vaut forcément X… ah non »). C'est en général une de ces hypothèses non vérifiées qui est fausse. D'où les questions qui se résolvent pendant qu'on les pose. Explaining the problem out loud, line by line, forces you to verbalize and therefore check every implicit assumption ("here this variable must be X… oh wait"). One of those unchecked assumptions is usually the false one. Hence questions that solve themselves while being asked.
Que doit contenir une bonne demande d'aide sur un bug ? What should a good request for help on a bug contain?
Un cas minimal reproductible (le code le plus court qui montre le bug), le comportement attendu, le comportement observé (message d'erreur complet), ce qui a déjà été essayé, et les versions/environnement. Construire le cas minimal résout souvent le problème avant même de poser la question. A minimal reproducible example (the shortest code showing the bug), the expected behavior, the observed behavior (full error message), what was already tried, and versions/environment. Building the minimal case often solves the problem before the question is even asked.
Comment lire efficacement une stack trace ? How do you read a stack trace effectively?
D'abord le message d'erreur en entier (le quoi), puis parcourir les frames jusqu'à la première qui appartient à VOTRE code (le où) — les frames du framework sont du contexte, pas des suspects. Attention au sens de lecture : selon le langage, l'appel le plus profond est en haut ou en bas (Python : en bas). First the full error message (the what), then walk the frames to the first one that belongs to YOUR code (the where) — framework frames are context, not suspects. Mind the reading order: depending on the language, the deepest call is at the top or the bottom (Python: bottom).
QCM Quiz
Un test échoue en CI mais passe en local. Quel est le meilleur premier réflexe ? A test fails in CI but passes locally. What is the best first reflex?
Le bug vit forcément dans un delta entre les deux environnements : versions, variables d'env, données, ordre ou parallélisme des tests. Relancer ou désactiver ne fait que masquer — souvent une vraie race condition. The bug necessarily lives in a delta between the two environments: versions, env vars, data, test order or parallelism. Re-running or disabling only masks it — often a real race condition.
Combien d'étapes faut-il environ à git bisect pour isoler un commit fautif parmi 1000 ? About how many steps does git bisect need to isolate a faulty commit among 1000?
git bisect est une recherche binaire : chaque test élimine la moitié des commits restants, donc log2(1000) ≈ 10 étapes. C'est ce qui rend la méthode utilisable même sur un gros historique. git bisect is a binary search: each test eliminates half the remaining commits, so log2(1000) ≈ 10 steps. That's what makes the method practical even on a large history.
Un bug disparaît dès que vous ajoutez un console.log. Cause la plus probable ? A bug disappears as soon as you add a console.log. Most likely cause?
C'est un heisenbug : le log ralentit le code et modifie l'ordonnancement, ce qui masque la course. Le bug est toujours là — il reviendra en prod, là où personne n'a mis de log. It's a heisenbug: the log slows the code down and alters scheduling, which hides the race. The bug is still there — it will come back in prod, where nobody added a log.
Avec `git bisect run npm test`, comment git interprète-t-il le résultat de la commande ? With `git bisect run npm test`, how does git interpret the command's result?
Convention Unix : exit code 0 = succès, donc commit good ; tout code non nul (hors 125, qui signifie « skip ») marque le commit bad. La bisection devient alors entièrement automatique. Unix convention: exit code 0 = success, hence a good commit; any non-zero code (except 125, which means "skip") marks the commit bad. The bisection then becomes fully automatic.
Qu'est-ce que le « shotgun debugging » ? What is "shotgun debugging"?
L'anti-méthode par excellence : même si le symptôme disparaît, on n'a rien appris et on a probablement masqué la cause racine. À ne pas confondre avec la réduction dichotomique, qui est contrôlée et raisonnée. The anti-method par excellence: even if the symptom disappears, you've learned nothing and probably masked the root cause. Not to be confused with bisection-based reduction, which is controlled and reasoned.
Quelle est la meilleure structure pour répondre à « raconte-moi ton bug le plus dur » ? What is the best structure to answer "tell me about your hardest bug"?
Le recruteur évalue la méthode, pas l'exploit : une histoire courte et structurée, avec une fausse piste assumée et une mesure de prévention, vaut mieux qu'un récit épique en vrac. The interviewer evaluates the method, not the feat: a short, structured story, with an owned dead end and a prevention measure, beats an epic jumble.
Jour 32 Day 32 Transactions & niveaux d'isolation Transactions & isolation levels
Flashcards Flashcards
Que signifie ACID, avec l'exemple du virement bancaire ? What does ACID mean, using the bank transfer example?
Atomicité : débit + crédit, tout ou rien. Cohérence : les contraintes (solde >= 0) restent respectées. Isolation : personne ne voit l'état intermédiaire débité-mais-pas-crédité. Durabilité : commit acquitté = écrit dans le WAL, survit au crash. Atomicity: debit + credit, all or nothing. Consistency: constraints (balance >= 0) stay respected. Isolation: nobody sees the debited-but-not-credited intermediate state. Durability: acknowledged commit = written to the WAL, survives a crash.
Qu'est-ce qu'un dirty read ? What is a dirty read?
Lire une valeur modifiée par une transaction qui n'a pas encore commité. Si elle rollback, on a travaillé sur une donnée qui n'a jamais existé. Empêché dès READ COMMITTED (le défaut Postgres). Reading a value modified by a transaction that hasn't committed yet. If it rolls back, you've worked on data that never existed. Prevented from READ COMMITTED up (the Postgres default).
Quelle différence entre non-repeatable read et phantom read ? What's the difference between a non-repeatable read and a phantom read?
Non-repeatable : une ligne existante relue a changé (UPDATE commité entre deux lectures). Phantom : l'ensemble des lignes matchant un critère a changé (INSERT/DELETE commité) — des lignes apparaissent ou disparaissent. REPEATABLE READ du standard bloque le premier, pas le second. Non-repeatable: an existing row re-read has changed (committed UPDATE between two reads). Phantom: the set of rows matching a predicate has changed (committed INSERT/DELETE) — rows appear or disappear. The standard's REPEATABLE READ blocks the former, not the latter.
Décris le scénario du lost update. Describe the lost update scenario.
T1 et T2 lisent solde=100, chacune calcule en mémoire (100-80 et 100-50), chacune écrit son résultat : la seconde écriture écrase la première — 130 retirés, solde final 50. Corrections : update atomique (SET solde = solde - X), SELECT FOR UPDATE, ou verrou optimiste (colonne version). T1 and T2 both read balance=100, each computes in memory (100-80 and 100-50), each writes its result: the second write overwrites the first — 130 withdrawn, final balance 50. Fixes: atomic update (SET balance = balance - X), SELECT FOR UPDATE, or optimistic locking (version column).
Comment fonctionne MVCC dans Postgres ? How does MVCC work in Postgres?
Chaque UPDATE crée une nouvelle version de la ligne au lieu d'écraser l'ancienne ; chaque transaction lit un snapshot cohérent des versions commitées à son début. Lecteurs et écrivains ne se bloquent jamais mutuellement ; seules deux écritures sur la même ligne se sérialisent. VACUUM recycle les versions mortes. Each UPDATE creates a new version of the row instead of overwriting the old one; each transaction reads a consistent snapshot of the versions committed at its start. Readers and writers never block each other; only two writes to the same row serialize. VACUUM recycles dead versions.
Que fait SELECT ... FOR UPDATE ? What does SELECT ... FOR UPDATE do?
Lit la ligne et la verrouille jusqu'au COMMIT/ROLLBACK : toute transaction concurrente voulant la modifier ou la verrouiller attend. Verrou pessimiste qui ferme la fenêtre read-modify-write — l'anti-lost-update quand le calcul doit passer par l'applicatif. Reads the row and locks it until COMMIT/ROLLBACK: any concurrent transaction wanting to modify or lock it waits. A pessimistic lock closing the read-modify-write window — the anti-lost-update when the computation must go through application code.
Qu'est-ce qu'un deadlock et comment le prévenir ? What is a deadlock and how do you prevent it?
T1 verrouille A puis attend B ; T2 verrouille B puis attend A : attente circulaire. La base le détecte et tue une des transactions (à retenter). Prévention : acquérir les verrous toujours dans le même ordre (id croissant) — plus de cycle possible — et garder les transactions courtes. T1 locks A then waits for B; T2 locks B then waits for A: circular wait. The database detects it and kills one transaction (to be retried). Prevention: always acquire locks in the same order (ascending id) — no cycle possible — and keep transactions short.
Pourquoi ne faut-il jamais faire d'I/O externe (appel HTTP, email) dans une transaction ? Why should you never do external I/O (HTTP call, email) inside a transaction?
La transaction garde ses verrous et son snapshot pendant toute l'attente : connexions saturées, contention en cascade, VACUUM bloqué. Et si l'I/O réussit mais que la transaction rollback (ou l'inverse), les deux mondes divergent. I/O externe toujours hors transaction. The transaction holds its locks and snapshot for the whole wait: saturated connections, cascading contention, blocked VACUUM. And if the I/O succeeds but the transaction rolls back (or the reverse), the two worlds diverge. External I/O always outside the transaction.
QCM Quiz
T1 lit une ligne modifiée par T2 qui n'a pas commité, puis T2 rollback. Quelle anomalie T1 a-t-elle subie ? T1 reads a row modified by T2, which hasn't committed, then T2 rolls back. Which anomaly did T1 suffer?
T1 a lu une donnée non commitée qui n'a finalement jamais existé : c'est le dirty read. Il est empêché dès le niveau READ COMMITTED — le défaut de Postgres, où ce scénario est donc impossible. T1 read uncommitted data that ultimately never existed: that's the dirty read. It's prevented from READ COMMITTED up — the Postgres default, where this scenario is thus impossible.
Quel est le niveau d'isolation par défaut de PostgreSQL ? What is PostgreSQL's default isolation level?
Postgres tourne en READ COMMITTED par défaut : pas de dirty reads, mais non-repeatable reads, phantoms et lost updates restent possibles. MySQL/InnoDB, lui, est en REPEATABLE READ par défaut — « ça dépend du moteur » est la réponse d'expert. Postgres runs READ COMMITTED by default: no dirty reads, but non-repeatable reads, phantoms and lost updates remain possible. MySQL/InnoDB defaults to REPEATABLE READ — "it depends on the engine" is the expert answer.
Deux requêtes concurrentes exécutent `UPDATE comptes SET solde = solde - 50 WHERE id = 1` (solde initial 100). Résultat final ? Two concurrent queries run `UPDATE accounts SET balance = balance - 50 WHERE id = 1` (initial balance 100). Final result?
`solde = solde - 50` calcule dans la base : la deuxième transaction attend le verrou de ligne de la première, puis relit la valeur commitée (50) et écrit 0. Pas de fenêtre read-modify-write, donc pas de lost update — c'est tout l'intérêt de l'update atomique. `balance = balance - 50` computes inside the database: the second transaction waits for the first one's row lock, then re-reads the committed value (50) and writes 0. No read-modify-write window, so no lost update — the whole point of the atomic update.
Dans Postgres (MVCC), que se passe-t-il quand un long SELECT analytique tourne pendant qu'une autre transaction UPDATE les mêmes lignes ? In Postgres (MVCC), what happens when a long analytical SELECT runs while another transaction UPDATEs the same rows?
C'est le principe de MVCC : les lecteurs ne bloquent jamais les écrivains et inversement. Le SELECT voit les versions commitées à son début ; l'UPDATE écrit de nouvelles versions à côté. Seules deux écritures sur la même ligne se bloquent. That's the MVCC principle: readers never block writers and vice versa. The SELECT sees the versions committed at its start; the UPDATE writes new versions alongside. Only two writes to the same row block each other.
Deux virements simultanés A→B et B→A deadlockent. Quelle est la vraie prévention ? Two simultaneous transfers A→B and B→A deadlock. What is the real prevention?
Le deadlock exige un cycle d'attente : si tout le monde verrouille d'abord le plus petit id, aucun cycle n'est possible. SERIALIZABLE ne supprime pas les deadlocks, le sleep ne fait que les raréfier, et verrouiller la table tue la concurrence. A deadlock requires a wait cycle: if everyone locks the smallest id first, no cycle is possible. SERIALIZABLE doesn't remove deadlocks, the sleep only makes them rarer, and locking the table kills concurrency.
Que doit obligatoirement prévoir une application qui tourne en SERIALIZABLE ? What must an application running in SERIALIZABLE necessarily include?
SERIALIZABLE avorte des transactions par design quand il détecte une dépendance non sérialisable : c'est le prix de l'isolation parfaite. Sans retry sur ces erreurs (40001), vous transformez un mécanisme normal en 500 aléatoires. SERIALIZABLE aborts transactions by design when it detects a non-serializable dependency: that's the price of perfect isolation. Without retries on those errors (40001), you turn a normal mechanism into random 500s.
Jour 31 Day 31 SSR, CSR, SSG & hydration SSR, CSR, SSG & hydration
Flashcards Flashcards
Quelle question unique résume CSR, SSR, SSG et ISR ? Which single question sums up CSR, SSR, SSG and ISR?
« Où et quand le HTML est-il produit ? » CSR : dans le navigateur à l'exécution. SSR : sur le serveur à chaque requête. SSG : au build, une fois. ISR : au build, puis régénéré page par page en arrière-plan après expiration. "Where and when is the HTML produced?" CSR: in the browser at runtime. SSR: on the server per request. SSG: at build time, once. ISR: at build time, then regenerated page by page in the background after expiry.
Qu'est-ce que l'hydration et pourquoi est-elle nécessaire ? What is hydration and why is it necessary?
Le HTML rendu côté serveur n'a aucun event listener : il est visible mais inerte. L'hydration ré-exécute les composants dans le navigateur et rattache état et événements au DOM existant. Nécessaire car l'interactivité vit dans le JS ; coûteuse car on paie le rendu deux fois. Server-rendered HTML has no event listeners: it's visible but inert. Hydration re-executes the components in the browser and reattaches state and events to the existing DOM. Necessary because interactivity lives in JS; costly because you pay for rendering twice.
Pourquoi une SPA en CSR pur a-t-elle un SEO fragile ? Why does a pure-CSR SPA have fragile SEO?
Le HTML initial est une coquille vide ; le contenu n'apparaît qu'après exécution du JS. Google l'exécute mais avec délai et budget de crawl, et les aperçus de liens (Slack, réseaux sociaux) ne l'exécutent jamais. Contenu à indexer = contenu dans le HTML initial (SSR/SSG). The initial HTML is an empty shell; content only appears after JS executes. Google runs it but with delay and a crawl budget, and link previews (Slack, social networks) never run it. Content to index = content in the initial HTML (SSR/SSG).
Quel problème l'ISR résout-il par rapport au SSG pur ? Which problem does ISR solve compared to pure SSG?
Le SSG fige le contenu jusqu'au prochain build complet — intenable avec 50 000 pages à reconstruire pour un prix corrigé. L'ISR régénère chaque page individuellement en arrière-plan après un délai (revalidate) ou sur webhook : TTFB du statique, fraîcheur contrôlée, sans rebuild global. SSG freezes content until the next full build — untenable with 50,000 pages to rebuild for one corrected price. ISR regenerates each page individually in the background after a delay (revalidate) or on webhook: static TTFB, controlled freshness, no global rebuild.
Qu'est-ce que l'islands architecture (Astro) ? What is the islands architecture (Astro)?
La page est du HTML statique par défaut, sans JS ; seuls des îlots explicitement marqués interactifs (client:load, client:visible) reçoivent leur bundle et s'hydratent. On n'envoie du JS que là où il y a une interaction réelle — le contraire d'une SPA qui hydrate tout. The page is static HTML by default, with no JS; only islands explicitly marked interactive (client:load, client:visible) receive their bundle and hydrate. JS is shipped only where an actual interaction exists — the opposite of a SPA hydrating everything.
Qu'est-ce qu'un hydration mismatch et comment l'éviter ? What is a hydration mismatch and how do you avoid it?
Quand le rendu client ne correspond pas au HTML serveur (new Date(), Math.random(), window.innerWidth au premier rendu) : le framework avertit et re-rend, causant flash et perte de perf. Solution : premier rendu déterministe, valeurs client-only déplacées dans un useEffect. When the client render doesn't match the server HTML (new Date(), Math.random(), window.innerWidth in the first render): the framework warns and re-renders, causing a flash and lost perf. Fix: deterministic first render, client-only values moved into a useEffect.
Quand le CSR pur est-il le bon choix ? When is pure CSR the right choice?
App derrière une authentification (dashboard, back-office, SaaS) : aucun enjeu SEO, utilisateurs récurrents avec bundle en cache, interactivité riche. Le SSR ajouterait un coût et une complexité serveur pour un premier affichage que personne n'indexe. An app behind authentication (dashboard, back-office, SaaS): no SEO stakes, recurring users with a cached bundle, rich interactivity. SSR would add server cost and complexity for a first paint nobody indexes.
Que sont les React Server Components, en une phrase ? What are React Server Components, in one sentence?
Des composants qui s'exécutent uniquement côté serveur et ne s'hydratent jamais : leur code ne quitte pas le serveur, seul le résultat rendu voyage vers le client — moins de JS envoyé, l'hydration étant réservée aux composants client interactifs. Components that run only on the server and never hydrate: their code never leaves the server, only the rendered result travels to the client — less JS shipped, with hydration reserved for interactive client components.
QCM Quiz
Entre le premier affichage d'une page SSR et la fin de l'hydration, que se passe-t-il si l'utilisateur clique sur un bouton ? Between a SSR page's first paint and the end of hydration, what happens if the user clicks a button?
C'est l'« uncanny valley » du SSR : la page est visible (bon FCP) mais sourde jusqu'à la fin de l'hydration (TTI). Les handlers React ne sont pas des attributs inline : ils n'existent que dans le JS pas encore attaché. That's SSR's "uncanny valley": the page is visible (good FCP) but deaf until hydration completes (TTI). React handlers aren't inline attributes: they only exist in the not-yet-attached JS.
Un blog dont les articles changent une fois par semaine, même contenu pour tous. Quelle stratégie ? A blog whose posts change once a week, same content for everyone. Which strategy?
Contenu identique pour tous et rarement modifié = le cas d'école du SSG : TTFB minimal, SEO parfait, coût quasi nul. Le SSR recalculerait à chaque requête un résultat identique ; le CSR sacrifierait le SEO pour rien. Identical content for everyone, rarely modified = the textbook SSG case: minimal TTFB, perfect SEO, near-zero cost. SSR would recompute an identical result per request; CSR would sacrifice SEO for nothing.
Que fait `revalidate: 3600` dans getStaticProps (Next.js) ? What does `revalidate: 3600` do in getStaticProps (Next.js)?
C'est l'Incremental Static Regeneration, en mode stale-while-revalidate : après expiration, le visiteur suivant reçoit encore l'ancienne version pendant que la nouvelle se génère derrière. On garde le TTFB statique avec une fraîcheur périodique. That's Incremental Static Regeneration, stale-while-revalidate style: after expiry, the next visitor still gets the old version while the new one generates behind the scenes. Static TTFB is kept with periodic freshness.
Quel avantage principal l'islands architecture apporte-t-elle par rapport au SSR classique d'une SPA ? What main advantage does the islands architecture bring over a SPA's classic SSR?
Une SPA SSR hydrate toute la page, même les parties purement statiques. Avec les islands (Astro), le texte reste du HTML sans JS et seuls les îlots marqués client:* paient le coût de l'hydration — bundle minuscule, TTI immédiat. A SSR SPA hydrates the whole page, even the purely static parts. With islands (Astro), text stays JS-free HTML and only the client:*-marked islands pay the hydration cost — tiny bundle, immediate TTI.
`curl -s https://monsite.com` renvoie `<div id="root"></div>` et un tag script. Qu'en déduire ? `curl -s https://mysite.com` returns `<div id="root"></div>` and a script tag. What do you conclude?
curl n'exécute pas le JS : si la réponse ne contient pas le contenu, c'est qu'il est construit côté client (CSR). En SSR/SSG, le contenu serait présent dans le HTML de la réponse. Test simple à montrer en entretien. curl doesn't run JS: if the response lacks the content, it's built client-side (CSR). With SSR/SSG, the content would be present in the response HTML. A simple test worth showing in an interview.
Quel code provoque un hydration mismatch en React SSR ? Which code causes a hydration mismatch in React SSR?
L'heure calculée au rendu serveur diffère de celle du rendu client : le DOM ne correspond plus, React avertit et re-rend. Le useEffect, lui, est justement la bonne solution : il ne s'exécute qu'après hydration, côté client uniquement. The time computed during the server render differs from the client render: the DOM no longer matches, React warns and re-renders. The useEffect option is precisely the right fix: it only runs after hydration, client-side only.
Jour 30 Day 30 TCP, UDP & le réseau du développeur TCP, UDP & the developer's network
Flashcards Flashcards
Décris le three-way handshake TCP. Describe the TCP three-way handshake.
SYN : le client propose son numéro de séquence initial. SYN-ACK : le serveur l'acquitte et propose le sien. ACK : le client confirme. Les deux côtés ont synchronisé leurs numéros de séquence ; la connexion est établie au prix d'un RTT complet avant toute donnée. SYN: the client proposes its initial sequence number. SYN-ACK: the server acknowledges it and proposes its own. ACK: the client confirms. Both sides have synchronized sequence numbers; the connection is established at the cost of a full RTT before any data.
Quelles garanties TCP offre-t-il qu'UDP n'offre pas ? Which guarantees does TCP provide that UDP does not?
Livraison dans l'ordre et sans doublon (numéros de séquence), retransmission des segments perdus (ACK + timeout), flow control (fenêtre du récepteur) et congestion control (adaptation au réseau). UDP n'ajoute que les ports et un checksum au-dessus d'IP. In-order, duplicate-free delivery (sequence numbers), retransmission of lost segments (ACK + timeout), flow control (receiver window) and congestion control (adapting to the network). UDP only adds ports and a checksum on top of IP.
Pourquoi DNS utilise-t-il UDP ? Why does DNS use UDP?
L'échange est minuscule : une question, une réponse, qui tiennent dans un datagramme. Établir une connexion TCP (1 RTT) coûterait plus cher que l'échange lui-même ; en cas de perte, le client réessaie simplement. TCP reste utilisé pour les grandes réponses et les transferts de zone. The exchange is tiny: one question, one answer, fitting in a single datagram. Establishing a TCP connection (1 RTT) would cost more than the exchange itself; on loss, the client simply retries. TCP is still used for large responses and zone transfers.
Qu'est-ce qui identifie une connexion TCP unique ? What identifies a unique TCP connection?
Le quadruplet (IP source, port source, IP destination, port destination). C'est pour ça qu'un serveur peut servir des milliers de clients sur le même port 443 : chaque client a une IP/port source différent, donc un quadruplet différent. The 4-tuple (source IP, source port, destination IP, destination port). That's why a server can serve thousands of clients on the same port 443: each client has a different source IP/port, hence a different tuple.
Comment fonctionne le NAT et quelle est sa conséquence pour un serveur ? How does NAT work and what is the consequence for a server?
Le routeur réécrit IP/port source des paquets sortants vers son IP publique et mémorise le mapping pour router les réponses. Conséquence : une machine derrière un NAT ne peut pas recevoir de connexion entrante spontanée — il faut une redirection de port ou des techniques STUN/TURN (WebRTC). The router rewrites outgoing packets' source IP/port to its public IP and memorizes the mapping to route replies back. Consequence: a machine behind NAT cannot receive spontaneous incoming connections — you need port forwarding or STUN/TURN techniques (WebRTC).
Latence vs bande passante : quelle différence et pourquoi ça compte ? Latency vs bandwidth: what's the difference and why does it matter?
La bande passante est le débit du tuyau (Mo/s), la latence le temps d'un aller-retour (ms). Les petites requêtes sont dominées par la latence : 3-4 RTT (DNS, handshake TCP, TLS) avant le premier octet. Augmenter le débit n'y change rien ; il faut réduire les allers-retours (keep-alive, HTTP/2-3, CDN). Bandwidth is the pipe's throughput (MB/s), latency the time of one round trip (ms). Small requests are latency-bound: 3-4 RTTs (DNS, TCP handshake, TLS) before the first byte. More throughput changes nothing; you must cut round trips (keep-alive, HTTP/2-3, CDN).
Que fait le congestion control de TCP ? What does TCP congestion control do?
L'émetteur sonde prudemment le réseau (slow start : débit doublé à chaque RTT, puis évitement de congestion) et réduit fortement son débit dès qu'une perte est détectée. C'est ce qui empêche l'effondrement d'Internet et explique qu'un transfert TCP n'atteint pas son débit max instantanément. The sender cautiously probes the network (slow start: rate doubled every RTT, then congestion avoidance) and sharply cuts its rate as soon as a loss is detected. It's what prevents Internet collapse and why a TCP transfer doesn't reach max throughput instantly.
Quels outils utiliser pour diagnostiquer un problème réseau, et pour quoi ? Which tools do you use to diagnose a network issue, and for what?
ss -tlnp : qui écoute sur quels ports. ping : latence et joignabilité ICMP. traceroute : le chemin saut par saut. dig : résolution DNS. curl -w : décomposer une requête HTTP (DNS, TCP, TLS, TTFB, total). tcpdump : voir les paquets bruts. ss -tlnp: who listens on which ports. ping: ICMP latency and reachability. traceroute: the path hop by hop. dig: DNS resolution. curl -w: break an HTTP request down (DNS, TCP, TLS, TTFB, total). tcpdump: see raw packets.
QCM Quiz
Combien d'allers-retours (RTT) le three-way handshake TCP coûte-t-il avant le premier octet de données ? How many round trips (RTT) does the TCP three-way handshake cost before the first byte of data?
SYN et SYN-ACK font l'aller-retour ; l'ACK final peut déjà accompagner les premières données. Un RTT complet est donc « perdu » avant tout octet utile — et TLS en ajoute par-dessus. C'est ce que QUIC cherche à éliminer. SYN and SYN-ACK make the round trip; the final ACK can already ride with the first data. A full RTT is thus "lost" before any useful byte — and TLS adds more on top. That's what QUIC eliminates.
Pourquoi un jeu en temps réel préfère-t-il UDP à TCP ? Why does a real-time game prefer UDP over TCP?
TCP retransmettrait la position perdue et bloquerait les suivantes en attendant (head-of-line blocking) — alors qu'une position vieille de 200 ms est déjà obsolète. UDP laisse le jeu envoyer la position la plus récente et oublier les pertes. TCP would retransmit the lost position and block newer ones while waiting (head-of-line blocking) — while a 200 ms-old position is already obsolete. UDP lets the game send the latest position and forget about losses.
Quelle est la raison principale du passage d'HTTP/3 à UDP (via QUIC) ? What is the main reason HTTP/3 moves to UDP (via QUIC)?
En TCP, une seule perte bloque tout le flux multiplexé ; QUIC gère des streams indépendants et combine connexion + TLS 1.3 en un handshake. TCP étant figé dans les noyaux et middleboxes, UDP était le seul véhicule possible. In TCP, a single loss blocks the whole multiplexed stream; QUIC manages independent streams and combines connection + TLS 1.3 in one handshake. With TCP frozen into kernels and middleboxes, UDP was the only possible vehicle.
Avec `curl -w`, TTFB est mauvais mais DNS, TCP et TLS sont rapides. Où est le problème ? With `curl -w`, TTFB is bad but DNS, TCP and TLS are fast. Where is the problem?
TTFB - TLS ≈ temps de calcul serveur : la connexion est établie vite, mais le premier octet tarde → requête SQL lente, code lent, file d'attente. La bande passante n'affecterait que le temps total de transfert, pas le premier octet. TTFB - TLS ≈ server compute time: the connection is established quickly but the first byte is late → slow SQL, slow code, queuing. Bandwidth would only affect total transfer time, not the first byte.
Que garantit réellement TCP ? What does TCP actually guarantee?
TCP ne peut rien livrer si le lien est coupé : il garantit que ce qui arrive est ordonné, complet et sans doublon, et retransmet ce qui manque. Ni délai borné, ni chiffrement (c'est TLS). L'application doit gérer timeouts et reconnexions. TCP can deliver nothing if the link is cut: it guarantees that what arrives is ordered, complete and duplicate-free, and retransmits what's missing. No bounded delay, no encryption (that's TLS). The application must handle timeouts and reconnections.
Un serveur écoute sur le port 443. Comment distingue-t-il les milliers de clients connectés simultanément ? A server listens on port 443. How does it tell thousands of simultaneously connected clients apart?
Le port serveur ne change jamais : c'est le couple IP/port du client qui varie, rendant chaque quadruplet unique. Chaque accept() retourne une socket dédiée associée à ce quadruplet. The server port never changes: it's the client's IP/port pair that varies, making each 4-tuple unique. Each accept() returns a dedicated socket bound to that tuple.
Actu News Des centaines d'agents IA piratent 395 organisations, et Anthropic demande à l'industrie de ralentir Hundreds of AI agents breached 395 organizations, and Anthropic asked the industry to slow down
Flashcards Flashcards
Que s'est-il passé dans la campagne PaperCut révélée le 10 septembre 2026, et quels sont les chiffres à retenir ? What happened in the PaperCut campaign disclosed on September 10, 2026, and what are the key numbers?
Un attaquant russophone a lancé des centaines d'agents IA (propulsés par OpenAI Codex et un modèle DeepSeek) contre des serveurs d'impression PaperCut, en exploitant CVE-2026-81578 (contournement d'authentification) et CVE-2026-82078 (exécution de code à distance). Bilan : 440 instances compromises, 395 organisations dans 48 pays, dont 204 écoles et universités. Première RCE en moins de 4 heures après le début, et 11 organisations compromises en 26 secondes au pic. Signalé indépendamment par Blackpoint Cyber et GreyNoise. A Russian-speaking attacker turned hundreds of AI agents (powered by OpenAI Codex and a DeepSeek model) loose on PaperCut print servers, exploiting CVE-2026-81578 (authentication bypass) and CVE-2026-82078 (remote code execution). The toll: 440 compromised instances, 395 organizations in 48 countries, 204 of them schools and universities. First RCE in under 4 hours, and 11 organizations compromised in 26 seconds at peak. Independently reported by Blackpoint Cyber and GreyNoise.
Qu'est-ce qui était réellement nouveau dans l'attaque PaperCut, et qu'est-ce qui ne l'était pas ? What was genuinely new in the PaperCut attack, and what was not?
L'outillage offensif n'avait rien de nouveau : Mimikatz, SharpHound, Certipy, Rubeus, Impacket, des charges Meterpreter en Java, tous publics depuis des années. Ce qui était nouveau, c'est que personne ne les pilotait à la main. Les agents tournaient en parallèle dans AionUi et partageaient leurs acquis via Hindsight, un service de mémoire persistante. L'IA n'a pas augmenté la sophistication de l'attaque, elle a effondré le coût marginal d'une cible supplémentaire, en supprimant le facteur limitant historique : le temps d'un humain compétent. The offensive tooling was not new: Mimikatz, SharpHound, Certipy, Rubeus, Impacket, Java Meterpreter payloads, all public for years. What was new is that nobody was driving them by hand. The agents ran in parallel inside AionUi and shared what they learned through Hindsight, a persistent memory service. AI did not raise the sophistication of the attack, it collapsed the marginal cost of one more target by removing the historic bottleneck: the time of a skilled human.
Que propose Dario Amodei dans « We Must Pace the Frontier » du 12 septembre 2026 ? What does Dario Amodei propose in 'We Must Pace the Frontier' (September 12, 2026)?
Un essai de 3 800 mots dont la thèse est « nous devons ralentir le rythme auquel nous améliorons les capacités des modèles ». Son avertissement : dans 6 à 12 mois, un essaim d'agents autonomes pourrait prendre le contrôle d'une bonne partie d'Internet via un botnet persistant, pour des centaines de milliards de dollars de dégâts. Plan en trois temps : des évaluateurs tiers embarqués avec un accès de niveau salarié (Anthropic s'y engage unilatéralement), des standards de sécurité communs entre laboratoires, puis leur extension par les États. Altman et Musk ont approuvé en quelques heures, Trump a rejeté l'appel le lendemain. A 3,800-word essay whose thesis is 'we must slow the pace at which we improve the capabilities of AI models'. His warning: within 6 to 12 months, a swarm of autonomous agents could take over much of the internet with a persistent botnet, causing hundreds of billions of dollars in damage. Three-part plan: embedded third-party evaluators with employee-level access (Anthropic committing unilaterally), common safety standards across labs, then their extension by governments. Altman and Musk agreed within hours, Trump dismissed the call the next day.
Pourquoi les 12 organisations sur 395 ayant perdu leur domain admin sont-elles une bonne nouvelle ? Why are the 12 out of 395 organizations that lost domain admin actually good news?
Parce que malgré une récolte d'identifiants presque généralisée (280 instances) et de secrets système ou de domaine sur 147, l'escalade complète jusqu'au domain admin a échoué dans 97 % des cas. Les agents couvrent très bien de la surface mais restent faibles sur ce qui demande du jugement. Ce sont les fondamentaux sans IA qui ont tenu : segmentation réseau, moindre privilège, comptes d'administration séparés. Les basiques n'ont pas été périmés par l'IA, ils viennent d'être validés grandeur nature. Because despite near-universal credential harvesting (280 instances) and OS or domain secrets on 147, full escalation to domain admin failed in 97% of cases. Agents cover surface very well but stay weak at anything requiring judgment. The AI-free fundamentals held: network segmentation, least privilege, separate admin accounts. The basics were not made obsolete by AI, they were validated at full scale.
QCM Quiz
Dans la campagne PaperCut de septembre 2026, quelle affirmation est exacte ? In the September 2026 PaperCut campaign, which statement is accurate?
Rien de nouveau dans l'outillage : Mimikatz, SharpHound, Certipy, Rubeus et Impacket sont publics depuis des années. La nouveauté est l'automatisation par des centaines d'agents tournant en parallèle dans AionUi avec une mémoire partagée (Hindsight). Les cibles n'étaient pas exotiques : 204 des 395 victimes sont des écoles et universités, avec des serveurs d'impression exposés et non patchés. Et Codex et DeepSeek n'ont pas été piratés, ils ont été utilisés comme outils de développement à des fins offensives. Nothing new in the tooling: Mimikatz, SharpHound, Certipy, Rubeus and Impacket have been public for years. The novelty is automation by hundreds of agents running in parallel in AionUi with shared memory (Hindsight). The targets were not exotic: 204 of the 395 victims are schools and universities, with exposed, unpatched print servers. And Codex and DeepSeek were not hacked, they were used as developer tools for offensive ends.
Que retenir du Patch Tuesday du 8 septembre 2026 et du zero-day Magento de la même semaine ? What should you take away from the September 8, 2026 Patch Tuesday and the same week's Magento zero-day?
Record absolu pour Microsoft : 972 CVE, plus du double d'août, dont 113 critiques et 2 zero-days déjà exploités (CVE-2026-81963 dans le Windows Update Stack et CVE-2026-85880 dans ALPC). Côté Adobe, StyleSmuggler touche toutes les versions de 2.4.4 à 2.4.9 et était exploité depuis le 4 septembre, trois jours avant le hotfix du 7. Leçon : installer le correctif ne désinstalle pas un webshell déjà déposé, il faut aussi chercher les indicateurs de compromission. An all-time record for Microsoft: 972 CVEs, more than double August's, including 113 critical and 2 already-exploited zero-days (CVE-2026-81963 in the Windows Update Stack and CVE-2026-85880 in ALPC). On the Adobe side, StyleSmuggler affects every version from 2.4.4 through 2.4.9 and was exploited from September 4, three days before the September 7 hotfix. Lesson: installing the patch does not uninstall a webshell that is already there, you must also hunt for indicators of compromise.
Qu'est-ce qui distingue Fugu Max et Fugu Ultra v2, sortis par Sakana AI le 11 septembre 2026 ? What sets Sakana AI's Fugu Max and Fugu Ultra v2, released September 11, 2026, apart?
Fugu est un orchestrateur entraîné : un modèle qui apprend à router chaque tâche vers un pool de modèles open weight et spécialisés (dont Nemotron de Nvidia) et peut s'appeler lui-même récursivement, derrière une API compatible OpenAI. Ultra v2 est meilleur ou à égalité sur 5 benchmarks sur 8, avec 48,3 sur Chartography contre 27,3 pour Opus 5. Tarifs : 2 $ / 6 $ le million de tokens pour Max, 5 $ / 30 $ pour Ultra v2. Le pattern est transposable sans rien entraîner : un petit modèle rapide pour la classification, un gros pour le raisonnement. Fugu is a trained orchestrator: a model that learns to route each task to a pool of open-weight and specialist models (including Nvidia's Nemotron) and can call itself recursively, behind an OpenAI-compatible API. Ultra v2 is best or joint-best on 5 of 8 benchmarks, scoring 48.3 on Chartography against 27.3 for Opus 5. Pricing: $2 / $6 per million tokens for Max, $5 / $30 for Ultra v2. The pattern transfers without training anything: a small fast model for classification, a big one for reasoning.
Jour 29 Day 29 Mots de passe : hashing & stockage Passwords: hashing & storage
Flashcards Flashcards
Pourquoi ne faut-il jamais stocker un mot de passe chiffré (et pas seulement jamais en clair) ? Why must you never store an encrypted password (not just never plaintext)?
Le chiffrement est réversible par définition : quiconque obtient la clé (dump, backup, admin malveillant) récupère tous les mots de passe d'un coup. On stocke un hash cryptographique, fonction à sens unique impossible à inverser. Encryption is reversible by definition: anyone who obtains the key (dump, backup, malicious admin) recovers every password at once. You store a cryptographic hash, a one-way function that cannot be inverted.
Pourquoi MD5 ou SHA-256 seuls ne conviennent-ils pas pour les mots de passe ? Why are MD5 or SHA-256 alone unsuitable for passwords?
Ce sont des hashs conçus pour être rapides : un GPU en calcule des milliards par seconde, rendant brute force et dictionnaires praticables sur un dump. Il faut un algorithme volontairement lent et coûteux : bcrypt, scrypt ou argon2id. They are hashes designed to be fast: a GPU computes billions per second, making brute force and dictionaries practical on a dump. You need a deliberately slow, costly algorithm: bcrypt, scrypt or argon2id.
À quoi sert le salt et contre quelle attaque protège-t-il ? What is the salt for and which attack does it defeat?
Valeur aléatoire unique par utilisateur ajoutée avant hashing : deux mots de passe identiques donnent des hashs différents, et les rainbow tables (tables hash → mot de passe précalculées) deviennent inutiles. Chaque hash doit être attaqué individuellement. A unique random value per user added before hashing: two identical passwords yield different hashes, and rainbow tables (precomputed hash → password tables) become useless. Every hash must be attacked individually.
Le salt doit-il rester secret ? Must the salt stay secret?
Non. bcrypt le stocke en clair dans sa chaîne de sortie ($2b$12$salt+hash). Le modèle de menace suppose que l'attaquant a tout : le salt combat le précalcul, c'est la lenteur de l'algorithme qui fournit la protection. No. bcrypt stores it in plain sight in its output string ($2b$12$salt+hash). The threat model assumes the attacker has everything: the salt defeats precomputation, and the algorithm's slowness provides the protection.
Qu'est-ce que le facteur de coût de bcrypt/argon2id et comment le régler ? What is the bcrypt/argon2id cost factor and how do you tune it?
Un paramètre qui contrôle la lenteur du calcul (2^cost itérations pour bcrypt, mémoire/temps pour argon2id). On vise ~100 ms par hash côté serveur : invisible pour un login, ruineux pour un attaquant. On l'augmente quand le matériel progresse. A parameter controlling how slow the computation is (2^cost iterations for bcrypt, memory/time for argon2id). Aim for ~100 ms per hash server-side: invisible for one login, ruinous for an attacker. Raise it as hardware improves.
Qu'est-ce qu'une timing attack et comment s'en protéger ? What is a timing attack and how do you defend against it?
Une comparaison naïve (===) s'arrête au premier octet différent : le temps de réponse fuit de l'information et permet de deviner un secret octet par octet. Contre-mesure : comparaison en temps constant (crypto.timingSafeEqual, bcrypt.compare). A naive comparison (===) stops at the first differing byte: response time leaks information, letting an attacker guess a secret byte by byte. Countermeasure: constant-time comparison (crypto.timingSafeEqual, bcrypt.compare).
Comment concevoir un flow « mot de passe oublié » sûr ? How do you design a safe "forgot password" flow?
Token aléatoire à usage unique et expirant (15-60 min), dont on stocke le hash en DB ; invalidé après usage ; réponse identique que l'email existe ou non (anti-énumération) ; on envoie un lien, jamais le mot de passe. Random single-use expiring token (15-60 min) whose hash is stored in the DB; invalidated after use; identical response whether the email exists or not (anti-enumeration); you send a link, never the password.
Que changent les passkeys (WebAuthn) par rapport aux mots de passe ? What do passkeys (WebAuthn) change compared to passwords?
Plus de secret partagé : une paire de clés est générée par appareil, le serveur ne stocke que la clé publique. Rien à hasher, rien à faire fuiter, résistant au phishing — le navigateur vérifie l'origine du site. No shared secret anymore: a key pair is generated per device and the server stores only the public key. Nothing to hash, nothing to leak, phishing-resistant — the browser verifies the site's origin.
QCM Quiz
Quelle est la bonne façon de stocker un mot de passe ? What is the correct way to store a password?
AES est réversible (la clé fuit), SHA-256 est trop rapide (brute force GPU), le clair est indéfendable. Seul un algorithme lent dédié avec salt (bcrypt, argon2id) tient sur un dump de base. AES is reversible (keys leak), SHA-256 is too fast (GPU brute force), plaintext is indefensible. Only a dedicated slow salted algorithm (bcrypt, argon2id) survives a database dump.
Contre quoi le salt protège-t-il principalement ? What does the salt mainly protect against?
Le salt rend chaque hash unique : le précalcul (rainbow tables) devient inutile et deux utilisateurs avec le même mot de passe sont indistinguables. Il n'empêche ni le vol ni le brute force en ligne (rate limiting). The salt makes every hash unique: precomputation (rainbow tables) becomes useless and two users with the same password are indistinguishable. It prevents neither theft nor online brute force (that's rate limiting).
Pourquoi bcrypt est-il volontairement lent ? Why is bcrypt deliberately slow?
~100 ms par tentative est invisible pour un login légitime mais multiplie par des millions le coût d'un attaquant qui teste des milliards de candidats sur un dump. La lenteur est la feature, réglable via le cost factor. ~100 ms per attempt is invisible for a legitimate login but multiplies an attacker's cost by millions when testing billions of candidates on a dump. Slowness is the feature, tunable via the cost factor.
Un site vous renvoie votre mot de passe par email après un « mot de passe oublié ». Qu'en déduisez-vous ? A site emails you your password back after a "forgot password". What do you conclude?
Un hash est à sens unique : impossible de retrouver le mot de passe, quel que soit le coût ou le salt. Si le site peut le renvoyer, c'est qu'il ne l'a jamais hashé. Un reset correct envoie un lien à token expirant. A hash is one-way: recovering the password is impossible, whatever the cost or salt. If the site can send it back, it never hashed it. A proper reset sends an expiring token link.
Pourquoi comparer un token secret avec === est-il dangereux ? Why is comparing a secret token with === dangerous?
C'est la timing attack : en mesurant finement les temps de réponse, on devine le secret octet par octet. On utilise crypto.timingSafeEqual (ou bcrypt.compare, qui l'intègre) pour un temps constant. That's the timing attack: by finely measuring response times, you guess the secret byte by byte. Use crypto.timingSafeEqual (or bcrypt.compare, which includes it) for constant time.
Que contient la chaîne bcrypt « $2b$12$N9qo8uLO... » stockée en base ? What does the bcrypt string "$2b$12$N9qo8uLO..." stored in the DB contain?
Le format est auto-descriptif : $2b$ (version), 12 (coût, 2^12 itérations), puis salt et hash encodés. C'est pour ça qu'il n'y a pas de colonne salt et que bcrypt.compare n'a besoin que de cette chaîne. The format is self-describing: $2b$ (version), 12 (cost, 2^12 iterations), then encoded salt and hash. That's why there is no salt column and bcrypt.compare needs only this string.
Jour 28 Day 28 Bien concevoir une API Designing a good API
Flashcards Flashcards
Quelle est la convention de nommage des ressources dans une API REST ? What is the resource naming convention in a REST API?
Des noms au pluriel, jamais de verbes : `GET /users/42/orders` et non `/getOrdersOfUser`. Le verbe est porté par la méthode HTTP (GET lit, POST crée, PUT remplace, PATCH modifie, DELETE supprime). Plural nouns, never verbs: `GET /users/42/orders`, not `/getOrdersOfUser`. The verb is carried by the HTTP method (GET reads, POST creates, PUT replaces, PATCH updates, DELETE removes).
Quelle différence entre les codes 401 et 403 ? What's the difference between 401 and 403?
401 Unauthorized = le client n'est pas authentifié (credentials absents ou invalides). 403 Forbidden = le client est authentifié mais n'a pas les droits. Bonus : certaines API renvoient 404 au lieu de 403 pour ne pas révéler l'existence d'une ressource. 401 Unauthorized = the client is not authenticated (missing or invalid credentials). 403 Forbidden = the client is authenticated but lacks permission. Bonus: some APIs return 404 instead of 403 to avoid revealing a resource exists.
Qu'est-ce que RFC 9457 (Problem Details) ? What is RFC 9457 (Problem Details)?
Le standard des erreurs HTTP structurées : content-type `application/problem+json` avec les champs `type` (URL identifiant la catégorie d'erreur), `title`, `status`, `detail`, `instance`, plus des extensions métier. Un client peut brancher sur `type` sans parser un message texte. The standard for structured HTTP errors: `application/problem+json` content type with the fields `type` (a URL identifying the error category), `title`, `status`, `detail`, `instance`, plus business extensions. A client can branch on `type` without parsing a text message.
Pourquoi la pagination par cursor est-elle préférée à l'offset pour les gros volumes ? Why is cursor pagination preferred over offset for large volumes?
Performance : l'offset force la DB à lire et jeter N lignes (lent en profondeur), le cursor fait un seek d'index direct (`WHERE created_at < :cursor`). Stabilité : des insertions pendant le parcours créent doublons ou trous avec l'offset, pas avec le cursor. Contrepartie : pas de saut direct à la page N. Performance: offset forces the DB to read and discard N rows (slow at depth), a cursor does a direct index seek (`WHERE created_at < :cursor`). Stability: inserts while paging create duplicates or gaps with offset, not with a cursor. Trade-off: no direct jump to page N.
À quoi sert le header Idempotency-Key ? What is the Idempotency-Key header for?
À rendre un POST rejouable sans danger. Le client envoie une clé unique par opération ; le serveur stocke `clé → réponse` et, si la même clé revient (retry après timeout), renvoie la réponse enregistrée sans réexécuter. Popularisé par Stripe pour éviter les doubles paiements. Making a POST safely replayable. The client sends a unique key per operation; the server stores `key → response` and, if the same key returns (retry after timeout), replays the recorded response without re-executing. Popularized by Stripe to prevent double charges.
Comment une API doit-elle signaler qu'un client dépasse le rate limit ? How should an API signal that a client exceeds the rate limit?
Code `429 Too Many Requests` avec un header `Retry-After` (secondes ou date) indiquant quand réessayer, plus les headers informatifs `RateLimit-Limit` / `RateLimit-Remaining`. Le client applique alors un backoff exponentiel avec jitter. Status `429 Too Many Requests` with a `Retry-After` header (seconds or a date) indicating when to retry, plus the informative `RateLimit-Limit` / `RateLimit-Remaining` headers. The client then applies exponential backoff with jitter.
Comment sécurise-t-on un webhook sortant ? How do you secure an outgoing webhook?
En signant le payload en HMAC-SHA256 avec un secret partagé, signature transmise en header et incluant un timestamp pour bloquer le rejeu. Le récepteur vérifie la signature (comparaison constante) et la fraîcheur, répond 2xx immédiatement, traite en asynchrone et déduplique par event id. By signing the payload with HMAC-SHA256 using a shared secret, the signature sent in a header and including a timestamp to block replay. The receiver verifies the signature (constant-time compare) and freshness, answers 2xx immediately, processes asynchronously and deduplicates by event id.
Quand faut-il créer une nouvelle version d'API (v2) ? When should you create a new API version (v2)?
Uniquement sur breaking change : suppression ou renommage de champ, changement de type ou de sémantique. Ajouter un champ ou un endpoint est rétrocompatible (les clients doivent ignorer les champs inconnus). Et on maintient la v1 avec une date de fin de vie annoncée. Only on breaking changes: field removal or rename, type or semantics change. Adding a field or endpoint is backward compatible (clients must ignore unknown fields). And you keep v1 alive with an announced end-of-life date.
QCM Quiz
Quel code de statut pour un payload JSON valide syntaxiquement mais qui viole une règle métier ? Which status code for a syntactically valid JSON payload that violates a business rule?
422 = le serveur comprend la requête mais ne peut pas la traiter (validation métier). 400 = requête malformée (JSON invalide), 409 = conflit d'état (ex. ressource déjà existante), 500 = bug côté serveur. 422 = the server understands the request but can't process it (business validation). 400 = malformed request (invalid JSON), 409 = state conflict (e.g. resource already exists), 500 = server-side bug.
Pourquoi répondre 200 avec `{"success": false}` est-il un anti-pattern ? Why is replying 200 with `{"success": false}` an anti-pattern?
Le code de statut est le canal d'erreur standard : proxies, monitoring et clients HTTP s'y fient. Un 200 qui contient une erreur casse le cache, fausse les métriques et empêche les retries automatiques. The status code is the standard error channel: proxies, monitoring and HTTP clients rely on it. A 200 carrying an error breaks caching, skews metrics and prevents automatic retries.
Un client parcourt une liste paginée par offset pendant que des éléments sont insérés en tête. Que risque-t-il ? A client pages through an offset-paginated list while items are inserted at the top. What can happen?
L'offset compte depuis le début de la liste : si la liste bouge entre deux pages, les éléments glissent (doublons) ou sautent (trous). Le cursor, ancré sur le dernier élément vu, est insensible aux insertions. Offset counts from the start of the list: if the list shifts between pages, items slide (duplicates) or skip (gaps). A cursor, anchored on the last seen item, is immune to inserts.
Quel changement d'API est un breaking change nécessitant une v2 ? Which API change is a breaking change requiring a v2?
Renommer un champ casse tous les clients qui le lisent. Ajouter un champ, un endpoint ou un param optionnel est rétrocompatible : les clients doivent ignorer ce qu'ils ne connaissent pas. Renaming a field breaks every client reading it. Adding a field, an endpoint or an optional param is backward compatible: clients must ignore what they don't know.
Pourquoi un consommateur de webhooks doit-il dédupliquer les événements par id ? Why must a webhook consumer deduplicate events by id?
L'émetteur réessaie tant qu'il n'a pas reçu de 2xx : si votre 2xx se perd, l'événement revient. La livraison est at-least-once, le traitement doit donc être idempotent (dédupliquer par event id). The sender retries until it receives a 2xx: if your 2xx is lost, the event comes again. Delivery is at-least-once, so processing must be idempotent (deduplicate by event id).
Que doit faire un client qui reçoit un 429 avec `Retry-After: 30` ? What should a client do upon receiving a 429 with `Retry-After: 30`?
`Retry-After` indique le délai minimal avant de réessayer. Un client bien élevé le respecte et applique un backoff exponentiel avec jitter — marteler l'API ne fera qu'allonger le ban. `Retry-After` states the minimum delay before retrying. A well-behaved client honors it and applies exponential backoff with jitter — hammering the API only extends the ban.
Jour 27 Day 27 Hashmaps en profondeur Hashmaps in depth
Flashcards Flashcards
Pourquoi une hashmap offre-t-elle un accès en O(1) en moyenne ? Why does a hashmap offer O(1) access on average?
La fonction de hachage transforme la clé en entier, réduit modulo la capacité du tableau interne : l'index du bucket est obtenu par un simple calcul + un accès tableau, indépendamment du nombre d'éléments. « En moyenne » car les collisions peuvent allonger un bucket. The hash function turns the key into an integer, reduced modulo the internal array's capacity: the bucket index comes from a simple computation + one array access, regardless of the number of elements. "On average" because collisions can lengthen a bucket.
Quelles sont les deux grandes stratégies de résolution des collisions ? What are the two main collision resolution strategies?
Le chaining : chaque bucket contient une liste (ou un arbre) des entrées en collision. L'open addressing : en cas de collision, on sonde d'autres cases du tableau (probing) — plus compact et cache-friendly, mais load factor < 1 obligatoire et suppression via tombstones. Chaining: each bucket holds a list (or tree) of colliding entries. Open addressing: on collision, probe other slots of the array — more compact and cache-friendly, but requires a load factor < 1 and deletion via tombstones.
Qu'est-ce que le load factor et que déclenche-t-il ? What is the load factor and what does it trigger?
Le ratio nombre d'éléments / nombre de buckets. Quand il dépasse un seuil (0.75 en Java, ~0.66 en CPython), la table alloue un tableau plus grand (souvent ×2) et re-hache toutes les entrées, car hash mod capacité change avec la capacité. The ratio of elements to buckets. When it crosses a threshold (0.75 in Java, ~0.66 in CPython), the table allocates a larger array (usually ×2) and rehashes every entry, because hash mod capacity changes with the capacity.
Pourquoi dit-on que l'insertion reste en O(1) amorti malgré le resize en O(n) ? Why is insertion amortized O(1) despite the O(n) resize?
Le resize coûte O(n) mais se déclenche de plus en plus rarement (environ toutes les n insertions). Réparti sur l'ensemble des insertions, le surcoût moyen par opération reste constant — même raisonnement que pour un tableau dynamique (ArrayList, vector). The resize costs O(n) but triggers less and less often (roughly every n insertions). Spread across all insertions, the average extra cost per operation stays constant — the same reasoning as for a dynamic array (ArrayList, vector).
Qu'est-ce qu'une attaque par hash flooding et comment s'en défend-on ? What is a hash flooding attack and how do you defend against it?
Un attaquant forge des milliers de clés qui collisionnent toutes (fonction de hachage connue) : chaque insertion devient O(n), le serveur qui parse un JSON ou des paramètres HTTP tombe en DoS. Défenses : hachage à graine aléatoire par processus (SipHash dans Python, Ruby, Rust) et treeification des buckets (Java 8+). An attacker forges thousands of keys that all collide (known hash function): every insertion becomes O(n) and the server parsing JSON or HTTP parameters falls to a DoS. Defenses: per-process random-seeded hashing (SipHash in Python, Ruby, Rust) and bucket treeification (Java 8+).
Qu'est-ce qui fait une bonne clé de hashmap ? What makes a good hashmap key?
Une clé immuable (ou qui ne mute jamais tant qu'elle est dans la map) avec égalité et hash cohérents : a.equals(b) implique hash(a) == hash(b). Une clé mutée après insertion devient introuvable (mauvais bucket) ; en Java, redéfinir equals sans hashCode est le bug classique. An immutable key (or one that never mutates while in the map) with consistent equality and hash: a.equals(b) implies hash(a) == hash(b). A key mutated after insertion becomes unfindable (wrong bucket); in Java, overriding equals without hashCode is the classic bug.
Quand préférer Map à un objet en JavaScript ? When should you prefer Map over an object in JavaScript?
Clés dynamiques ou non-string, besoin de .size, insertions/suppressions fréquentes, et surtout données venant de l'utilisateur (l'objet nu est vulnérable à la pollution de prototype via __proto__). L'objet reste bien pour une struct à forme fixe (config, DTO). Dynamic or non-string keys, need for .size, frequent insertions/deletions, and above all user-provided data (a bare object is vulnerable to prototype pollution via __proto__). The object remains fine for a fixed-shape struct (config, DTO).
Comment résoudre two-sum en O(n) avec une hashmap ? How do you solve two-sum in O(n) with a hashmap?
Un seul passage : pour chaque nums[i], calculer le complément target - nums[i] ; s'il est déjà dans la map (valeur → index), retourner les deux indices, sinon insérer nums[i] → i. Chaque test et insertion est en O(1), contre O(n²) pour la double boucle naïve. A single pass: for each nums[i], compute the complement target - nums[i]; if it's already in the map (value → index), return both indices, otherwise insert nums[i] → i. Each check and insertion is O(1), versus O(n²) for the naive double loop.
QCM Quiz
Comment une hashmap trouve-t-elle le bucket d'une clé ? How does a hashmap find a key's bucket?
Hash → entier → modulo capacité → index du bucket : un calcul et un accès tableau, sans parcourir les autres clés. C'est ça, le O(1) moyen. Hash → integer → modulo capacity → bucket index: one computation and one array access, without scanning other keys. That's the average O(1).
Qu'est-ce que le load factor d'une hashmap ? What is a hashmap's load factor?
Load factor = n / capacité. Quand il dépasse un seuil (0.75 en Java), la table double sa capacité et re-hache toutes les entrées pour garder des buckets courts. Load factor = n / capacity. When it crosses a threshold (0.75 in Java), the table doubles its capacity and rehashes every entry to keep buckets short.
Quelle est la complexité d'un get dans le pire cas pour une hashmap à chaînage simple (sans treeification) ? What is the worst-case complexity of a get in a plain chaining hashmap (no treeification)?
Si toutes les clés collisionnent dans le même bucket, la table dégénère en liste chaînée : parcours en O(n). Java 8+ limite la casse à O(log n) en transformant les gros buckets en arbre rouge-noir. If every key collides into the same bucket, the table degenerates into a linked list: an O(n) scan. Java 8+ caps the damage at O(log n) by turning large buckets into red-black trees.
En quoi consiste une attaque par hash flooding ? What does a hash flooding attack consist of?
L'attaquant exploite une fonction de hachage prévisible pour envoyer des clés toutes en collision (params HTTP, JSON) : chaque insertion devient O(n) et le CPU s'effondre. Parade : SipHash avec graine aléatoire, treeification. The attacker exploits a predictable hash function to send all-colliding keys (HTTP params, JSON): each insertion becomes O(n) and the CPU collapses. Countermeasures: random-seeded SipHash, treeification.
En Java, que doit garantir une classe utilisée comme clé de HashMap ? In Java, what must a class used as a HashMap key guarantee?
Le contrat equals/hashCode : deux objets égaux doivent avoir le même hash, sinon ils atterrissent dans des buckets différents et get ne retrouve rien. Redéfinir equals sans hashCode est le bug Java classique. The equals/hashCode contract: two equal objects must share the same hash, otherwise they land in different buckets and get finds nothing. Overriding equals without hashCode is the classic Java bug.
Dans two-sum en O(n), qu'associe la hashmap ? In O(n) two-sum, what does the hashmap associate?
On stocke valeur → index au fil du parcours ; pour chaque élément on teste si son complément (target - valeur) a déjà été vu, en O(1). Un seul passage suffit. You store value → index as you go; for each element you check in O(1) whether its complement (target - value) was already seen. A single pass is enough.
Jour 25 Day 25 La code review : donner et recevoir Code review: giving and receiving
Flashcards Flashcards
À quoi sert vraiment une code review (au-delà de « trouver des bugs ») ? What is a code review really for (beyond "finding bugs")?
Trois choses : partager la connaissance (personne n'est le seul à comprendre un module — assurance contre le bus factor), garantir la cohérence du codebase (patterns, conventions, gestion d'erreurs), et améliorer la conception grâce à une deuxième paire d'yeux (API, cas limites, tests, sécurité). Three things: sharing knowledge (nobody is the only one who understands a module — insurance against the bus factor), keeping the codebase consistent (patterns, conventions, error handling), and improving design through a second pair of eyes (API, edge cases, tests, security).
Pourquoi le style ne doit-il pas être commenté en review ? Why shouldn't style be commented on in a review?
Parce que les linters et formatters (ESLint, Prettier, Black, clang-format) le vérifient automatiquement en CI, sans fatigue ni débat. Un humain qui commente l'indentation gaspille le temps de deux personnes ; si l'équipe débat du style en review, il manque un outil. Because linters and formatters (ESLint, Prettier, Black, clang-format) check it automatically in CI, without fatigue or debate. A human commenting on indentation wastes two people's time; if the team argues about style in review, a tool is missing.
Quelle est la première chose à faire quand on review une PR ? What is the first thing to do when reviewing a PR?
Comprendre l'intention : lire le titre, la description et le ticket lié avant la première ligne de diff. Puis aller du général (l'approche est-elle la bonne ?) au particulier (logique ligne à ligne, cas limites, tests). Understand the intent: read the title, the description and the linked ticket before the first line of diff. Then go from general (is the approach right?) to specific (line-by-line logic, edge cases, tests).
Que sont les conventional comments et quels préfixes faut-il connaître ? What are conventional comments and which prefixes should you know?
Un format de commentaire de review `label: sujet` (conventionalcomments.org) qui lève l'ambiguïté sur la gravité : `blocking:` (à résoudre avant merge), `question:` (besoin d'une réponse), `suggestion:` (amélioration proposée), `nit:` (détail mineur, jamais bloquant), `praise:` (souligner ce qui est bien). A review comment format `label: subject` (conventionalcomments.org) that removes ambiguity about severity: `blocking:` (must be resolved before merge), `question:` (needs an answer), `suggestion:` (proposed improvement), `nit:` (minor detail, never blocking), `praise:` (highlighting what's good).
Pourquoi préférer les questions aux ordres dans un commentaire de review ? Why prefer questions over orders in a review comment?
Parce que le reviewer n'a pas tout le contexte. « Que se passe-t-il si la liste est vide ? » ouvre une discussion et laisse la porte à « c'est garanti non vide en amont » ; « gère la liste vide » présuppose que le reviewer a raison et braque l'auteur. Because the reviewer doesn't have all the context. "What happens if the list is empty?" opens a discussion and leaves room for "it's guaranteed non-empty upstream"; "handle the empty list" assumes the reviewer is right and puts the author on the defensive.
Pourquoi viser des PR d'environ 200 lignes maximum ? Why aim for PRs of roughly 200 lines maximum?
L'attention du reviewer décroche avec la taille du diff (les études SmartBear situent le décrochage vers 400 lignes) : une grosse PR est survolée et approuvée d'un « LGTM » distrait. Petite PR = review profonde, feedback rapide, moins de conflits, revert facile. Une grosse feature se découpe en PR successives. Reviewer attention drops with diff size (the SmartBear studies place the drop-off around 400 lines): a big PR gets skimmed and approved with a distracted "LGTM". Small PR = deep review, fast feedback, fewer conflicts, easy revert. A big feature gets split into successive PRs.
Quelles sont les trois règles pour bien recevoir une review ? What are the three rules for receiving a review well?
1) Ce n'est pas personnel : on review le code, pas la personne. 2) Répondre à tout : chaque commentaire reçoit un fix, une réponse ou un ticket, jamais un silence. 3) Le désaccord s'argumente : « je garde cette approche parce que X » est légitime ; appliquer en silence un changement qu'on juge mauvais ne l'est pas. 1) It's not personal: the code is reviewed, not the person. 2) Respond to everything: each comment gets a fix, an answer or a ticket, never silence. 3) Disagreement comes with arguments: "I'm keeping this approach because X" is legitimate; silently applying a change you believe is wrong is not.
Qu'est-ce que l'auto-review et pourquoi la faire ? What is a self-review and why do it?
Relire son propre diff dans l'interface de PR avant de demander une review, comme si on était le reviewer : on attrape le console.log oublié, le fichier commité par erreur, le code mort. Avec une bonne description (quoi, pourquoi, comment tester), chaque minute d'auto-review économise un aller-retour de review, donc des heures de latence. Re-reading your own diff in the PR interface before requesting a review, as if you were the reviewer: you catch the forgotten console.log, the file committed by mistake, the dead code. With a good description (what, why, how to test), every minute of self-review saves a review round-trip, hence hours of latency.
QCM Quiz
Quel est l'apport principal d'une code review dans une équipe ? What is the main contribution of code review in a team?
Le style est le travail des linters en CI, les tests restent indispensables, et utiliser la review pour évaluer les gens détruit la confiance. La vraie valeur : connaissance partagée, cohérence, meilleure conception. Style is the linters' job in CI, tests remain essential, and using reviews to evaluate people destroys trust. The real value: shared knowledge, consistency, better design.
Que signifie le préfixe `nit:` dans un commentaire de review ? What does the `nit:` prefix mean in a review comment?
`nit:` (nitpick) signale un détail mineur — nommage, micro-style non couvert par le linter — que l'auteur est libre d'appliquer ou non. Ce qui bloque le merge porte le préfixe `blocking:`. `nit:` (nitpick) flags a minor detail — naming, micro-style not covered by the linter — that the author is free to apply or not. What blocks the merge carries the `blocking:` prefix.
Pourquoi limiter la taille d'une PR à environ 200 lignes ? Why limit a PR's size to roughly 200 lines?
C'est l'effet LGTM : plus le diff est gros, moins il est vraiment lu, plus l'approbation devient un tampon. Les études SmartBear situent le décrochage vers 400 lignes ; viser 200 garde de la marge. That's the LGTM effect: the bigger the diff, the less it's actually read, the more the approval becomes a rubber stamp. The SmartBear studies place the drop-off around 400 lines; aiming for 200 keeps a margin.
Le code d'une PR fonctionne et respecte les conventions, mais le reviewer aurait choisi une autre approche. Que doit-il faire selon le guide Google ? The code in a PR works and follows conventions, but the reviewer would have chosen a different approach. What should they do according to Google's guide?
Le standard de merge du guide Google : on approuve dès que le changement améliore la santé globale du code, même imparfait. « Moi j'aurais fait autrement » n'est pas un motif de blocage — au mieux une `suggestion:`. Google's merge standard: approve as soon as the change improves the overall health of the code, even if imperfect. "I would have done it differently" is not grounds for blocking — at best a `suggestion:`.
Un reviewer demande un changement que tu juges injustifié. Quelle est la bonne réaction ? A reviewer requests a change you believe is unjustified. What is the right reaction?
Le désaccord argumenté est légitime et attendu : on expose sa contrainte ou son contexte, et la discussion tranche (ou un tiers si elle s'enlise). Ignorer détruit la confiance ; appliquer en silence un changement qu'on juge mauvais est aussi une faute. Argued disagreement is legitimate and expected: you state your constraint or context, and the discussion settles it (or a third party if it stalls). Ignoring destroys trust; silently applying a change you believe is wrong is also a mistake.
Que doit faire l'auteur d'une PR juste avant de demander une review ? What should a PR author do right before requesting a review?
L'auto-review attrape le debug oublié, les fichiers parasites et le code mort ; la description donne le contexte (quoi, pourquoi, comment tester). Chaque aller-retour de review évité économise des heures de latence. Self-review catches forgotten debug code, stray files and dead code; the description gives context (what, why, how to test). Every avoided review round-trip saves hours of latency.
Jour 24 Day 24 Comment marche un LLM How an LLM works
Flashcards Flashcards
Que fait fondamentalement un LLM ? What does an LLM fundamentally do?
Il prédit le token suivant : à partir du texte déjà présent, il produit une distribution de probabilités sur tout son vocabulaire, un token est tiré (sampling), ajouté au texte, et le processus recommence. Toute la génération est autorégressive. It predicts the next token: from the text so far, it produces a probability distribution over its whole vocabulary, one token is drawn (sampling), appended to the text, and the process repeats. All generation is autoregressive.
Qu'est-ce qu'un token et pourquoi « strawberry » piège-t-il les modèles ? What is a token and why does "strawberry" trap models?
Un token est un fragment de texte fréquent (mot, morceau de mot, ponctuation) converti en entier par le tokenizer (BPE). Le modèle ne voit jamais les lettres : « strawberry » arrive en fragments comme `straw`+`berry`, donc compter les « r » demande une information qu'il n'a jamais observée directement. A token is a frequent text fragment (word, word piece, punctuation) converted to an integer by the tokenizer (BPE). The model never sees letters: "strawberry" arrives as fragments like `straw`+`berry`, so counting the "r"s requires information it never directly observed.
Qu'est-ce qu'un embedding, en une phrase ? What is an embedding, in one sentence?
Un vecteur de nombres représentant un token (ou un texte) tel que la proximité géométrique entre vecteurs reflète la proximité de sens — « roi » et « reine » sont voisins dans cet espace. A vector of numbers representing a token (or a text) such that geometric closeness between vectors reflects closeness in meaning — "king" and "queen" are neighbors in that space.
Explique le mécanisme d'attention sans maths. Explain the attention mechanism without math.
À chaque couche, chaque token « regarde » tous les tokens précédents et pondère leur influence selon leur pertinence pour lui : dans « le chien dort parce qu'il est fatigué », « il » donne un poids fort à « chien ». C'est un contexte pondéré, calculé dynamiquement et en parallèle sur toute la séquence — ce qui a remplacé les RNN. At each layer, every token "looks at" all previous tokens and weights their influence by relevance to itself: in "the dog sleeps because it is tired", "it" gives a strong weight to "dog". It's a weighted context, computed dynamically and in parallel over the whole sequence — which is what replaced RNNs.
Pré-entraînement vs fine-tuning vs RLHF : quelle différence ? Pre-training vs fine-tuning vs RLHF: what's the difference?
Pré-entraînement : prédire le token suivant sur des trillions de tokens → un base model qui complète du texte (99 % du coût). Fine-tuning (SFT) : apprendre le format instruction → réponse sur des dialogues choisis. RLHF : aligner sur les préférences humaines via un modèle de récompense entraîné sur des classements de réponses. Pre-training: predict the next token on trillions of tokens → a base model that completes text (99% of the cost). Fine-tuning (SFT): learn the instruction → answer format on curated dialogues. RLHF: align with human preferences via a reward model trained on ranked answers.
À quoi servent la température et le top-p ? What are temperature and top-p for?
Ils contrôlent le sampling : la température aplatit (haut = créatif/aléatoire) ou accentue (0 = quasi déterministe, toujours le token le plus probable) la distribution ; le top-p restreint le tirage au noyau de tokens couvrant p % de probabilité, coupant la longue traîne absurde. They control sampling: temperature flattens (high = creative/random) or sharpens (0 = near deterministic, always the most probable token) the distribution; top-p restricts drawing to the nucleus of tokens covering p% of probability, cutting the absurd long tail.
Qu'est-ce que la fenêtre de contexte et quelles sont ses limites ? What is the context window and what are its limits?
La quantité maximale de tokens que le modèle peut traiter en un appel (system + historique + documents + réponse). Limites : tout est re-traité à chaque appel (coût, latence), l'API est stateless (rien n'est mémorisé entre appels), et le milieu d'un long contexte est mal exploité (« lost in the middle »). The maximum number of tokens the model can process in one call (system + history + documents + answer). Limits: everything is reprocessed on every call (cost, latency), the API is stateless (nothing is remembered between calls), and the middle of a long context is poorly exploited ("lost in the middle").
Pourquoi les hallucinations sont-elles structurelles et non un simple bug ? Why are hallucinations structural rather than a mere bug?
L'objectif d'entraînement récompense la plausibilité de la continuation, pas sa vérité : le modèle n'a ni base de faits ni mécanisme natif du « je ne sais pas ». Une référence inventée est souvent la suite la plus probable d'une question pointue. On atténue (RAG, outils, citations) mais on ne « corrige » pas. The training objective rewards the plausibility of the continuation, not its truth: the model has no fact database and no native "I don't know" mechanism. An invented reference is often the most probable continuation of a niche question. You mitigate (RAG, tools, citations) but you don't "fix" it.
QCM Quiz
Que produit exactement un LLM à chaque étape de génération ? What exactly does an LLM produce at each generation step?
La sortie brute est une distribution de probabilités sur ~100k tokens ; c'est le sampling (température, top-p) qui en tire un. Rien n'est déterministe par défaut, et la réponse complète n'émerge que de la boucle autorégressive. The raw output is a probability distribution over ~100k tokens; sampling (temperature, top-p) draws one. Nothing is deterministic by default, and the full answer only emerges from the autoregressive loop.
Pourquoi un LLM se trompe-t-il souvent en comptant les « r » de « strawberry » ? Why does an LLM often miscount the "r"s in "strawberry"?
La tokenization découpe « strawberry » en fragments (`straw`+`berry`) convertis en entiers : le modèle n'a jamais accès aux caractères. Ni la fenêtre de contexte, ni la température, ni le RLHF ne sont en cause. Tokenization cuts "strawberry" into fragments (`straw`+`berry`) converted to integers: the model never has access to characters. Neither the context window, temperature, nor RLHF is to blame.
Quel est le rôle du RLHF dans la fabrication d'un assistant ? What is RLHF's role in building an assistant?
Grammaire et faits viennent du pré-entraînement. Le RLHF entraîne un modèle de récompense sur des classements humains de réponses, puis optimise le LLM contre lui : c'est ce qui rend le modèle utile, poli, et capable de refuser. Grammar and facts come from pre-training. RLHF trains a reward model on human rankings of answers, then optimizes the LLM against it: that's what makes the model helpful, polite, and able to refuse.
Que garantit `temperature: 0` ? What does `temperature: 0` guarantee?
Température 0 réduit la variance : le modèle prend (quasi) toujours le token le plus probable. Mais le plus probable peut être une hallucination confiante — déterminisme ≠ exactitude, et la longueur n'a rien à voir. Temperature 0 reduces variance: the model (almost) always takes the most probable token. But the most probable can be a confident hallucination — determinism ≠ accuracy, and length has nothing to do with it.
Pourquoi faut-il renvoyer tout l'historique de conversation à chaque appel API ? Why must the whole conversation history be resent on every API call?
Le modèle est figé (poids constants) et l'API sans état : la « mémoire » d'une conversation n'est que le contexte que votre code renvoie à chaque requête. Rien n'est ré-entraîné, et le system prompt n'« expire » pas. The model is frozen (constant weights) and the API stateless: a conversation's "memory" is just the context your code resends with each request. Nothing is retrained, and the system prompt doesn't "expire".
Qu'est-ce qui a permis au transformer de détrôner les RNN pour le langage ? What allowed the transformer to dethrone RNNs for language?
L'attention laisse chaque token pondérer tous les précédents selon leur pertinence, et se calcule en parallèle (contrairement au traitement séquentiel des RNN) : entraînement massivement scalable. Les transformers sont au contraire devenus énormes, et hallucinent toujours. Attention lets each token weight all previous ones by relevance, and is computed in parallel (unlike RNNs' sequential processing): massively scalable training. Transformers actually got huge, and still hallucinate.
Jour 23 Day 23 React : Virtual DOM, hooks & reconciliation React: Virtual DOM, hooks & reconciliation
Flashcards Flashcards
Qu'est-ce que le Virtual DOM et quel problème résout-il ? What is the Virtual DOM and what problem does it solve?
Une représentation légère de l'UI sous forme d'objets JavaScript. À chaque changement d'état, React reconstruit cet arbre (peu coûteux), le compare à l'ancien (diffing) et n'applique au DOM réel — la partie lente — que les différences. Il rend le modèle déclaratif UI = f(state) viable sans re-render complet du DOM. A lightweight representation of the UI as JavaScript objects. On every state change, React rebuilds this tree (cheap), compares it to the old one (diffing) and applies only the differences to the real DOM — the slow part. It makes the declarative UI = f(state) model viable without a full DOM re-render.
Quelles sont les deux phases d'une mise à jour React ? What are the two phases of a React update?
Render : React appelle les composants et produit un nouveau Virtual DOM ; phase pure et interruptible (StrictMode la double en dev pour détecter les impuretés). Commit : React applique la liste minimale de mutations au DOM réel, de façon synchrone. Ensuite le navigateur paint, puis les useEffect s'exécutent. Render: React calls the components and produces a new Virtual DOM; a pure, interruptible phase (StrictMode double-renders in dev to detect impurities). Commit: React applies the minimal list of mutations to the real DOM, synchronously. Then the browser paints, then the useEffects run.
Quelles heuristiques permettent à React de differ deux arbres en O(n) ? Which heuristics let React diff two trees in O(n)?
Deux règles : si le type d'un élément change à une position donnée, tout le sous-arbre est démonté et recréé (état local perdu) ; si le type est identique, React garde le nœud, met à jour les props modifiées et descend récursivement. Dans les listes, les keys complètent le diff en donnant une identité stable aux éléments. Two rules: if an element's type changes at a given position, the whole subtree is unmounted and recreated (local state lost); if the type is the same, React keeps the node, updates the changed props and recurses down. In lists, keys complete the diff by giving elements a stable identity.
À quoi servent les keys dans une liste React ? What are keys for in a React list?
Elles donnent une identité stable à chaque élément pour que la reconciliation détecte déplacements, insertions et suppressions au lieu de comparer position par position. React peut alors déplacer le nœud DOM en conservant son état (input, focus). Key correcte : un id stable issu des données, pas l'index. They give each element a stable identity so reconciliation can detect moves, insertions and deletions instead of comparing position by position. React can then move the DOM node while preserving its state (input, focus). Correct key: a stable id from the data, not the index.
Quelles sont les règles des hooks et pourquoi existent-elles ? What are the rules of hooks and why do they exist?
Appeler les hooks uniquement au niveau supérieur du composant (jamais dans un if, une boucle, une fonction imbriquée) et uniquement depuis un composant React ou un hook custom. Raison : React associe chaque hook à sa valeur par ordre d'appel entre deux renders ; un hook conditionnel décale la liste et corrompt tout l'état. Call hooks only at the top level of the component (never in an if, a loop or a nested function) and only from a React component or a custom hook. Reason: React matches each hook to its value by call order between renders; a conditional hook shifts the list and corrupts all the state.
useEffect : à quoi servent le tableau de dépendances et le cleanup ? useEffect: what are the dependency array and the cleanup for?
Les deps disent quand relancer l'effet : à chaque render si absentes, au montage seulement si [], quand une valeur listée change sinon — toute valeur réactive lue dans l'effet doit y figurer (sinon stale closure). Le cleanup retourné s'exécute avant chaque relance et au démontage : c'est là qu'on annule fetchs, timers et subscriptions. The deps say when to re-run the effect: every render if absent, only on mount if [], whenever a listed value changes otherwise — every reactive value read inside must be listed (else stale closure). The returned cleanup runs before each re-run and on unmount: that's where you cancel fetches, timers and subscriptions.
Pourquoi ne faut-il jamais muter le state directement ? Why must you never mutate state directly?
React compare l'ancienne et la nouvelle valeur avec Object.is : muter un objet ou un tableau garde la même référence, donc React ne voit aucun changement et ne re-rend pas. Il faut créer une nouvelle valeur : setItems([...items, x]), setUser({ ...user, name }). React compares old and new values with Object.is: mutating an object or array keeps the same reference, so React sees no change and doesn't re-render. You must create a new value: setItems([...items, x]), setUser({ ...user, name }).
Lifting state up, Context, state manager : quand choisir quoi ? Lifting state up, Context, state manager: when to pick which?
Dans l'ordre : lifting state up (remonter l'état dans le parent commun, passé en props) couvre la plupart des cas ; Context pour une valeur globale et peu changeante (thème, utilisateur, langue) en sachant que chaque changement re-rend tous les consommateurs ; state manager (Redux Toolkit, Zustand) ou TanStack Query quand l'état global devient complexe ou vient du serveur. In order: lifting state up (move state into the common parent, passed as props) covers most cases; Context for a global, rarely changing value (theme, user, language), knowing every change re-renders all consumers; a state manager (Redux Toolkit, Zustand) or TanStack Query when global state gets complex or comes from the server.
QCM Quiz
Que se passe-t-il après `items.push(x); setItems(items)` ? What happens after `items.push(x); setItems(items)`?
React compare l'ancienne et la nouvelle valeur avec Object.is : même référence → rien n'a changé à ses yeux. Créer un nouveau tableau : setItems([...items, x]). React compares old and new values with Object.is: same reference → nothing changed as far as it's concerned. Create a new array: setItems([...items, x]).
Quand un `useEffect` avec un tableau de dépendances vide `[]` s'exécute-t-il ? When does a `useEffect` with an empty dependency array `[]` run?
Un tableau vide = aucune dépendance → l'effet ne se relance jamais : il s'exécute une fois après le premier commit, et son cleanup au démontage. An empty array = no dependencies → the effect never re-runs: it executes once after the first commit, and its cleanup on unmount.
Lors de la reconciliation, que fait React si un élément change de type au même endroit (`<div>` → `<span>`) ? During reconciliation, what does React do if an element changes type at the same position (`<div>` → `<span>`)?
C'est l'heuristique clé du diff O(n) : type différent = sous-arbre jeté et recréé, y compris l'état des composants enfants. Même type = mise à jour des props seulement. That's the key heuristic of the O(n) diff: different type = subtree thrown away and recreated, including child components' state. Same type = props update only.
Quand la fonction de cleanup retournée par un `useEffect` est-elle exécutée ? When is the cleanup function returned by a `useEffect` executed?
React nettoie l'effet précédent avant de relancer le suivant, et au démontage. C'est ce qui évite requêtes obsolètes, doubles subscriptions et fuites de timers. React cleans up the previous effect before re-running the next one, and on unmount. That's what prevents stale requests, duplicate subscriptions and timer leaks.
Dans quel cas `useCallback` est-il réellement utile ? In which case is `useCallback` actually useful?
useCallback ne fait que stabiliser la référence entre deux renders. Sans consommateur sensible à cette référence (React.memo, deps d'un hook), il ajoute du coût pour rien. useCallback only stabilizes the reference between renders. Without a consumer sensitive to that reference (React.memo, a hook's deps), it adds cost for nothing.
Pourquoi `key={index}` pose-t-il problème sur une liste modifiable ? Why is `key={index}` a problem on a list that can change?
React suit l'identité via la key. Si les index se décalent, l'état local et DOM reste accroché à la position — d'où des inputs qui « sautent » de ligne. Key stable = id issu des données. React tracks identity through the key. If indexes shift, local and DOM state stays attached to the position — hence inputs that "jump" rows. Stable key = an id from the data.
Jour 22 Day 22 DNS : de l'URL à l'IP DNS: from URL to IP
Flashcards Flashcards
Déroulez la résolution DNS complète quand aucun cache n'a la réponse. Walk through full DNS resolution when no cache has the answer.
Cache navigateur → cache OS → resolver récursif (FAI, 1.1.1.1…). S'il n'a rien en cache, il interroge : 1) la racine « . » qui indique les serveurs du TLD, 2) le TLD (.com) qui indique les serveurs autoritaires du domaine, 3) l'autoritaire qui donne l'enregistrement final. La réponse remonte et est mise en cache partout pour TTL secondes. Browser cache → OS cache → recursive resolver (ISP, 1.1.1.1…). If it has nothing cached, it queries: 1) the root "." which points to the TLD servers, 2) the TLD (.com) which points to the domain's authoritative servers, 3) the authoritative server which returns the final record. The answer flows back and is cached everywhere for TTL seconds.
Quelle différence entre un resolver récursif et un serveur autoritaire ? What's the difference between a recursive resolver and an authoritative server?
Le récursif enquête pour le compte du client : il parcourt la hiérarchie (racine → TLD → autoritaire) et met les réponses en cache. L'autoritaire détient la vérité pour sa zone et répond directement, sans interroger personne. 8.8.8.8 est récursif ; les serveurs NS de votre domaine sont autoritaires. The recursive one investigates on the client's behalf: it walks the hierarchy (root → TLD → authoritative) and caches answers. The authoritative one holds the truth for its zone and answers directly, querying no one. 8.8.8.8 is recursive; your domain's NS servers are authoritative.
Pourquoi dit-on que « la propagation DNS n'existe pas » ? Why do we say "DNS propagation doesn't exist"?
Le DNS ne pousse rien : après un changement, chaque cache sert l'ancienne valeur jusqu'à expiration de son TTL, puis va chercher la nouvelle. « Attendre la propagation » = attendre l'expiration des caches. D'où la pratique : baisser le TTL avant une migration, le remonter après. DNS pushes nothing: after a change, each cache serves the old value until its TTL expires, then fetches the new one. "Waiting for propagation" = waiting for cache expiration. Hence the practice: lower the TTL before a migration, raise it back afterwards.
A, AAAA, CNAME : quelles différences ? A, AAAA, CNAME: what are the differences?
A : nom → adresse IPv4. AAAA : nom → adresse IPv6. CNAME : alias d'un nom vers un autre nom, résolu ensuite (indirection supplémentaire). Un nom portant un CNAME ne peut porter aucun autre enregistrement, d'où l'impossibilité du CNAME à l'apex du domaine. A: name → IPv4 address. AAAA: name → IPv6 address. CNAME: alias from one name to another, resolved next (extra indirection). A name carrying a CNAME can carry no other record, hence CNAME being impossible at the domain apex.
À quoi servent les enregistrements MX, TXT et NS ? What are MX, TXT and NS records for?
MX : désigne les serveurs de mail du domaine, avec une priorité. TXT : texte libre — vérifications de propriété (Google, Let's Encrypt DNS-01) et anti-usurpation email (SPF, DKIM, DMARC). NS : délègue la zone à ses serveurs autoritaires. MX: designates the domain's mail servers, with a priority. TXT: free text — ownership verifications (Google, Let's Encrypt DNS-01) and email anti-spoofing (SPF, DKIM, DMARC). NS: delegates the zone to its authoritative servers.
Qu'est-ce qu'un enregistrement wildcard et quel workflow de déploiement permet-il ? What is a wildcard record and what deployment workflow does it enable?
`*.domaine.tld` attrape tous les sous-domaines non définis explicitement et les pointe vers une même cible (ex. un VPS). Combiné à un reverse proxy (Traefik, nginx), chaque nouvelle app = un nouveau sous-domaine sans toucher à la zone DNS : le pattern « un sous-domaine par app ». `*.domain.tld` catches every subdomain not explicitly defined and points them to one target (e.g. a VPS). Combined with a reverse proxy (Traefik, nginx), each new app = a new subdomain without touching the DNS zone: the "one subdomain per app" pattern.
Que fait `dig +trace` et en quoi diffère-t-il d'un `dig` normal ? What does `dig +trace` do and how does it differ from a normal `dig`?
`dig domaine` interroge votre resolver récursif, caches compris. `dig +trace` court-circuite les caches et rejoue toute la hiérarchie depuis la racine : NS de la racine → NS du TLD → réponse de l'autoritaire. Idéal pour vérifier ce que les serveurs autoritaires servent vraiment, indépendamment des caches. `dig domain` queries your recursive resolver, caches included. `dig +trace` bypasses the caches and replays the whole hierarchy from the root: root NS → TLD NS → authoritative answer. Ideal for checking what the authoritative servers really serve, independently of caches.
Que sont DoH et DoT ? What are DoH and DoT?
DNS-over-HTTPS et DNS-over-TLS : ils chiffrent les requêtes DNS entre le client et le resolver, alors que le DNS historique circule en clair sur le port 53, lisible (et modifiable) par tout intermédiaire sur le chemin. DNS-over-HTTPS and DNS-over-TLS: they encrypt DNS queries between the client and the resolver, whereas historical DNS travels in cleartext on port 53, readable (and modifiable) by any intermediary on the path.
QCM Quiz
Dans quel ordre un resolver récursif sans cache interroge-t-il la hiérarchie DNS ? In what order does a cache-less recursive resolver query the DNS hierarchy?
La hiérarchie se descend : la racine indique les serveurs du TLD (.com), le TLD indique les autoritaires du domaine, l'autoritaire donne l'enregistrement final. Chaque niveau ne sait que déléguer au suivant. You walk down the hierarchy: the root points to the TLD servers (.com), the TLD points to the domain's authoritative servers, the authoritative returns the final record. Each level only knows how to delegate to the next.
Vous changez l'IP d'un enregistrement A (TTL 3600). Un utilisateur voit encore l'ancienne IP 30 minutes après. Pourquoi ? You change an A record's IP (TTL 3600). A user still sees the old IP 30 minutes later. Why?
Aucune propagation : le resolver de l'utilisateur a mis la réponse en cache pour 3600 s et la sert jusqu'à expiration. Rien n'est « poussé » — c'est de l'expiration de cache. D'où le TTL baissé avant migration. No propagation: the user's resolver cached the answer for 3600s and serves it until expiry. Nothing is "pushed" — it's cache expiration. Hence lowering the TTL before a migration.
Pourquoi ne peut-on pas mettre un CNAME sur l'apex du domaine (example.com) ? Why can't you put a CNAME on the domain apex (example.com)?
Règle du protocole : CNAME est exclusif de tout autre enregistrement sur le même nom. L'apex portant obligatoirement les NS de la zone, le CNAME y est impossible — d'où les ALIAS/ANAME propriétaires de certains hébergeurs. Protocol rule: CNAME is exclusive of any other record on the same name. Since the apex must carry the zone's NS records, a CNAME there is impossible — hence some providers' proprietary ALIAS/ANAME.
Quel enregistrement utilisez-vous pour prouver la propriété d'un domaine (vérification Google, Let's Encrypt DNS-01) ? Which record do you use to prove domain ownership (Google verification, Let's Encrypt DNS-01)?
Le TXT porte du texte libre : le service fournit une chaîne à publier, et sa présence prouve le contrôle de la zone. Même mécanisme pour SPF/DKIM/DMARC côté email. TXT carries free text: the service provides a string to publish, and its presence proves control of the zone. Same mechanism for SPF/DKIM/DMARC on the email side.
Que teste `dig @8.8.8.8 monsite.com` par rapport à `dig monsite.com` ? What does `dig @8.8.8.8 mysite.com` test compared to `dig mysite.com`?
`@serveur` désigne le serveur DNS à interroger. Comparer son resolver local, 1.1.1.1 et 8.8.8.8 permet de diagnostiquer des caches expirant à des moments différents après un changement. `@server` selects which DNS server to query. Comparing your local resolver, 1.1.1.1 and 8.8.8.8 helps diagnose caches expiring at different times after a change.
Dans « que se passe-t-il quand tu tapes une URL ? », où se place la résolution DNS ? In "what happens when you type a URL?", where does DNS resolution fit?
L'ordre canonique : DNS (nom → IP) → connexion TCP → handshake TLS si HTTPS → requête/réponse HTTP → parsing et rendu. Sans IP, impossible d'ouvrir la moindre connexion. The canonical order: DNS (name → IP) → TCP connection → TLS handshake if HTTPS → HTTP request/response → parsing and rendering. Without the IP, no connection can be opened.
Actu News Nvidia s'offre Hugging Face pour 12,9 milliards : le GitHub de l'IA change de mains Nvidia buys Hugging Face for $12.9 billion: the GitHub of AI changes hands
Flashcards Flashcards
Qu'a révélé The Information le 27 août 2026 à propos de Hugging Face, et quelle nuance faut-il connaître ? What did The Information reveal on August 27, 2026 about Hugging Face, and what nuance should you know?
Nvidia aurait accepté de racheter Hugging Face pour 12,9 milliards de dollars, presque le triple de sa dernière valorisation (4,5 Md$ en 2023). Nuance essentielle : aucun accord n'est signé, le deal peut encore capoter, et ni Nvidia ni Hugging Face n'ont commenté. Toute l'info repose sur une source anonyme « ayant une connaissance directe des discussions ». Nvidia reportedly agreed to acquire Hugging Face for $12.9 billion, almost triple its last valuation ($4.5B in 2023). Essential nuance: no agreement has been signed, the deal could still fall apart, and neither Nvidia nor Hugging Face commented. The whole story rests on an anonymous source 'with direct knowledge of the talks'.
Pourquoi un rachat de Hugging Face par Nvidia inquiète-t-il la communauté des développeurs ? Why does an Nvidia acquisition of Hugging Face worry the developer community?
Hugging Face doit sa position à sa neutralité : plus de 13 millions de développeurs y publient et consomment les modèles ouverts de Meta, Google, Mistral, Qwen ou DeepSeek. Racheté par le fournisseur dominant du compute, le hub poserait un problème de conflit d'intérêts : mise en avant des modèles optimisés CUDA, traitement des alternatives AMD ou des puces maison des clouds. C'est la question de la neutralité d'une infrastructure critique. Hugging Face owes its position to its neutrality: more than 13 million developers publish and consume open models from Meta, Google, Mistral, Qwen or DeepSeek there. Owned by the dominant compute supplier, the hub would raise a conflict of interest problem: promotion of CUDA-optimized models, treatment of AMD alternatives or the clouds' custom chips. It is the question of critical infrastructure neutrality.
Quelles sont les deux failles critiques corrigées par Next.js le 25 août 2026, et quelle leçon en tirer ? What are the two critical flaws Next.js patched on August 25, 2026, and what is the lesson?
Deux RCE non authentifiées : une faille dans libheif (utilisée par sharp pour optimiser les images AVIF, une image piégée suffit, l'optimisation AVIF est désactivée en attendant le correctif amont) et CVE-2026-75604 (RCE sur les serveurs Next.js hébergés sous Windows). Correctifs : 16.3.3 et 15.5.24. Leçon : la surface d'attaque inclut les dépendances transitives, ici Next.js utilise sharp qui utilise libheif. Two unauthenticated RCEs: a flaw in libheif (used by sharp for AVIF image optimization, one crafted image is enough, AVIF optimization is disabled until the upstream fix) and CVE-2026-75604 (RCE on Windows-hosted Next.js servers). Fixes: 16.3.3 and 15.5.24. Lesson: the attack surface includes transitive dependencies, here Next.js uses sharp which uses libheif.
Que symbolise la fermeture de Mechanical Turk le 30 septembre 2026 ? What does the September 30, 2026 shutdown of Mechanical Turk symbolize?
La fin du micro-étiquetage de masse. Lancée en 2005, la place de marché d'Amazon (plus de 500 000 workers au pic, surnommée « artificial artificial intelligence » par Bezos) a étiqueté les datasets de l'ère du machine learning. Les modèles font désormais ces tâches simples, et le travail humain s'est déplacé vers l'annotation experte, l'évaluation de réponses et le RLHF, chez Scale AI, Mercor ou Prolific. Amazon ferme aussi SageMaker Ground Truth et Augmented AI. The end of mass micro-labeling. Launched in 2005, Amazon's marketplace (over 500,000 workers at its peak, dubbed 'artificial artificial intelligence' by Bezos) labeled the datasets of the machine learning era. Models now handle those simple tasks, and human work moved to expert annotation, answer evaluation and RLHF, at Scale AI, Mercor or Prolific. Amazon is also closing SageMaker Ground Truth and Augmented AI.
QCM Quiz
Selon la presse du 27 août 2026, combien Nvidia paierait-il pour racheter Hugging Face ? According to press reports on August 27, 2026, how much would Nvidia pay to acquire Hugging Face?
12,9 Md$ selon The Information, repris par CNBC, Bloomberg et Fortune, soit presque le triple de la valorisation de 2023 (4,5 Md$). Mais rien n'est signé : le deal peut encore capoter et aucune des deux entreprises n'a commenté. Les 105 Md$ correspondent au financement Nvidia du datacenter OpenAI de la semaine précédente. $12.9B according to The Information, picked up by CNBC, Bloomberg and Fortune, almost triple the 2023 valuation ($4.5B). But nothing is signed: the deal could still fall apart and neither company commented. The $105B figure is Nvidia's OpenAI data center financing from the previous week.
Pourquoi la faille AVIF corrigée par Next.js le 25 août est-elle un cas d'école de sécurité des dépendances ? Why is the AVIF flaw patched by Next.js on August 25 a textbook dependency security case?
La chaîne est Next.js → sharp → libheif : la faille se trouve deux étages plus bas que le framework que vous installez. Une image AVIF piégée soumise à l'optimisation d'images suffit, sans authentification. En attendant le correctif amont de libheif, Next.js 16.3.3 et 15.5.24 désactivent l'optimisation AVIF : couper la fonctionnalité est une mitigation légitime. The chain is Next.js → sharp → libheif: the flaw sits two floors below the framework you install. A crafted AVIF image submitted to image optimization is enough, with no authentication. While waiting for the upstream libheif fix, Next.js 16.3.3 and 15.5.24 disable AVIF optimization: turning off the feature is a legitimate mitigation.
Quel chiffre résume les résultats trimestriels de Nvidia publiés le 26 août 2026 ? Which figure sums up Nvidia's quarterly results published on August 26, 2026?
96,2 Md$ sur le trimestre clos le 26 juillet, +106 % sur un an, dont 89 Md$ de datacenter (+117 %) portés par Blackwell Ultra, avec une guidance à 108 Md$. L'action a pourtant reculé : quand le marché price la perfection, même un record déçoit. Les 12,9 Md$ sont le prix rapporté du rachat de Hugging Face, et 421 est le nombre de CVE du Patch Tuesday d'août. $96.2B for the quarter ended July 26, up 106% year over year, including $89B from data center (up 117%) driven by Blackwell Ultra, with $108B guidance. The stock still slipped: when the market prices in perfection, even a record disappoints. $12.9B is the reported Hugging Face price, and 421 is the August Patch Tuesday CVE count.
Jour 21 Day 21 OWASP Top 10 & les injections OWASP Top 10 & injections
Flashcards Flashcards
Quelle est la règle de sécurité qui traverse presque tout l'OWASP Top 10 ? What security rule runs through almost the entire OWASP Top 10?
Ne jamais faire confiance à l'entrée utilisateur : toute donnée venant du client (paramètres, body, headers, cookies) est potentiellement hostile et doit être validée côté serveur. La validation front n'est que de l'UX, contournable avec curl ou les DevTools. Never trust user input: any data from the client (parameters, body, headers, cookies) is potentially hostile and must be validated server-side. Front-end validation is just UX, bypassable with curl or DevTools.
Comment fonctionne une injection SQL et quelle est LA parade ? How does SQL injection work and what is THE countermeasure?
L'entrée utilisateur concaténée dans la requête est interprétée comme du code SQL (ex. ' OR '1'='1' -- rend la condition toujours vraie). Parade : les requêtes préparées — la requête part figée, les valeurs sont transmises séparément et ne sont jamais interprétées. L'échappement manuel n'est pas fiable. User input concatenated into the query is interpreted as SQL code (e.g. ' OR '1'='1' -- makes the condition always true). Countermeasure: prepared statements — the query is sent frozen, values travel separately and are never interpreted. Manual escaping is not reliable.
Qu'est-ce qu'un IDOR et quel principe viole-t-il ? What is an IDOR and which principle does it violate?
Insecure Direct Object Reference : changer un identifiant dans l'URL (/invoices/1042 → 1043) donne accès à la ressource d'un autre utilisateur. C'est du broken access control (A01) : l'authentification est vérifiée mais pas l'autorisation. Parade : vérifier à chaque requête que la ressource appartient à l'utilisateur courant. Insecure Direct Object Reference: changing an identifier in the URL (/invoices/1042 → 1043) grants access to another user's resource. It's broken access control (A01): authentication is checked but not authorization. Defense: on every request, verify the resource belongs to the current user.
Quelle est la différence entre authentification et autorisation ? What is the difference between authentication and authorization?
Authentification : prouver qui vous êtes (login, session, token). Autorisation : vérifier ce à quoi vous avez droit (cette facture est-elle à vous ?). L'IDOR est l'exemple type d'une autorisation oubliée alors que l'authentification est en place. Authentication: proving who you are (login, session, token). Authorization: checking what you're entitled to (is this invoice yours?). IDOR is the textbook example of authorization forgotten while authentication is in place.
Qu'est-ce qu'une faille XSS et comment s'en protéger ? What is an XSS flaw and how do you defend against it?
L'injection côté client : du contenu utilisateur rendu comme HTML/JS s'exécute dans le navigateur des autres utilisateurs (vol de session, actions à leur insu). Parades : échapper à l'affichage (défaut de React/Vue — ne pas contourner avec innerHTML/dangerouslySetInnerHTML sur de la donnée utilisateur) et une Content Security Policy en défense en profondeur. Client-side injection: user content rendered as HTML/JS executes in other users' browsers (session theft, actions on their behalf). Defenses: escape on output (React/Vue default — don't bypass with innerHTML/dangerouslySetInnerHTML on user data) and a Content Security Policy as defense in depth.
Qu'est-ce qu'une SSRF et pourquoi est-ce dangereux ? What is SSRF and why is it dangerous?
Server-Side Request Forgery : l'attaquant fait faire au serveur une requête vers une cible que lui seul peut atteindre — services internes, localhost, métadonnées cloud (169.254.169.254, credentials AWS). Parade : allowlist de destinations et blocage des plages IP privées. Server-Side Request Forgery: the attacker makes the server issue a request to a target only the server can reach — internal services, localhost, cloud metadata (169.254.169.254, AWS credentials). Defense: destination allowlist and blocking private IP ranges.
Comment stocker correctement des mots de passe ? How do you store passwords correctly?
Les hasher (jamais les chiffrer, jamais en clair) avec un algorithme lent par conception : bcrypt ou argon2, avec sel. MD5 et SHA1 sont proscrits car trop rapides (brute force facile). Un hash est irréversible : on ne « décrypte » pas un mot de passe, on compare des hashes. Hash them (never encrypt, never cleartext) with an algorithm slow by design: bcrypt or argon2, with a salt. MD5 and SHA1 are banned because they're too fast (easy brute force). A hash is irreversible: you don't "decrypt" a password, you compare hashes.
Donnez trois exemples de security misconfiguration (A05). Give three examples of security misconfiguration (A05).
Credentials par défaut sur une console d'admin ; stack traces détaillées renvoyées au client en production ; ports/services de debug exposés ; bucket S3 public ; CORS trop permissif. Parade générale : durcir les défauts, fermer ce qui n'est pas utilisé, headers de sécurité. Default credentials on an admin console; detailed stack traces returned to the client in production; exposed debug ports/services; public S3 bucket; overly permissive CORS. General defense: harden defaults, close what isn't used, security headers.
QCM Quiz
Pourquoi les requêtes préparées empêchent-elles l'injection SQL ? Why do prepared statements prevent SQL injection?
La requête (le code) est transmise figée, les valeurs à part : quoi que contienne l'entrée, elle reste une donnée. C'est structurel, contrairement à l'échappement manuel qui est fragile. The query (the code) is sent frozen, the values separately: whatever the input contains, it stays data. It's structural, unlike manual escaping which is fragile.
Un utilisateur connecté change /api/orders/512 en /api/orders/513 et voit la commande d'un autre client. De quelle faille s'agit-il ? A logged-in user changes /api/orders/512 to /api/orders/513 and sees another customer's order. Which flaw is this?
Insecure Direct Object Reference : le serveur vérifie l'authentification mais pas l'autorisation sur la ressource. Parade : vérifier la propriété de la ressource à chaque requête, côté serveur. Insecure Direct Object Reference: the server checks authentication but not authorization on the resource. Defense: verify resource ownership on every request, server-side.
Quelle affirmation sur la validation côté client (HTML5, JavaScript) est correcte ? Which statement about client-side validation (HTML5, JavaScript) is correct?
Le client est sous le contrôle de l'attaquant : curl, proxy, DevTools contournent tout. HTTPS chiffre le transport, il ne valide rien. La sécurité se joue exclusivement côté serveur. The client is under the attacker's control: curl, proxies and DevTools bypass everything. HTTPS encrypts transport, it validates nothing. Security happens exclusively server-side.
Une feature « importer depuis une URL » est détournée pour requêter http://169.254.169.254/ et voler des credentials cloud. Quelle attaque ? An "import from URL" feature is abused to request http://169.254.169.254/ and steal cloud credentials. Which attack?
Server-Side Request Forgery : le serveur est manipulé pour requêter une cible interne que l'attaquant ne peut pas atteindre directement — ici l'endpoint de métadonnées cloud. Parade : allowlist + blocage des IP privées. Server-Side Request Forgery: the server is manipulated into requesting an internal target the attacker cannot reach directly — here the cloud metadata endpoint. Defense: allowlist + blocking private IPs.
Quel algorithme faut-il utiliser pour stocker des mots de passe ? Which algorithm should you use to store passwords?
Un mot de passe se hashe avec un algorithme volontairement lent (anti brute force) et salé. MD5 est trop rapide, AES est réversible (on ne doit PAS pouvoir retrouver le mot de passe), Base64 n'est qu'un encodage. A password is hashed with a deliberately slow (anti brute force), salted algorithm. MD5 is too fast, AES is reversible (you must NOT be able to recover the password), Base64 is just an encoding.
Pourquoi le XSS est-il classé parmi les injections dans le Top 10 2021 ? Why is XSS classified under injection in the 2021 Top 10?
SQL injection, command injection et XSS partagent le même défaut racine : l'interpréteur (SQL, shell, navigateur) ne distingue pas données et code. La parade est toujours de préserver cette frontière : requêtes préparées, échappement à l'affichage. SQL injection, command injection and XSS share the same root flaw: the interpreter (SQL, shell, browser) can't tell data from code. The defense is always preserving that boundary: prepared statements, output escaping.
Jour 20 Day 20 Index, modélisation & optimisation SQL Indexes, modeling & SQL optimization
Flashcards Flashcards
Pourquoi une recherche via un index B-tree est-elle en O(log n) ? Why is a lookup through a B-tree index O(log n)?
Le B-tree est un arbre équilibré à nœuds très larges : une page de 8 Ko contient des centaines de clés, donc l'arbre a une hauteur de 3-4 même pour des millions de lignes. Une recherche descend simplement l'arbre nœud par nœud au lieu de lire toute la table (O(n)). A B-tree is a balanced tree with very wide nodes: an 8 KB page holds hundreds of keys, so the tree is only 3-4 levels tall even for millions of rows. A lookup just walks down the tree node by node instead of reading the whole table (O(n)).
Qu'est-ce que la règle du « leftmost prefix » pour un index composite ? What is the "leftmost prefix" rule for a composite index?
Un index sur (a, b) est trié par a puis b, comme un annuaire (nom, prénom). Il sert pour les requêtes filtrant sur a, ou sur a et b — mais pas sur b seul : sans le préfixe gauche, l'ordre de tri de l'index est inutilisable. An index on (a, b) is sorted by a then b, like a phone book (last name, first name). It serves queries filtering on a, or on a and b — but not on b alone: without the left prefix, the index's sort order is unusable.
Qu'est-ce qu'un index couvrant et pourquoi est-il si rapide ? What is a covering index and why is it so fast?
Un index qui contient toutes les colonnes demandées par la requête (clause INCLUDE en PostgreSQL). La base répond en lisant uniquement l'index, sans jamais toucher la table : c'est l'Index Only Scan, le scan le plus rapide. An index containing every column the query asks for (INCLUDE clause in PostgreSQL). The database answers by reading only the index, never touching the table: that's the Index Only Scan, the fastest scan there is.
Cite trois situations où un index existant n'est pas utilisé. Name three situations where an existing index is not used.
1) Une fonction appliquée à la colonne (WHERE lower(email) = …) sans index fonctionnel. 2) LIKE '%terme' : pas de préfixe fixe, l'arbre trié ne sert à rien. 3) Faible sélectivité (booléen à 50/50) : le planner préfère lire la table. Aussi : types incompatibles, statistiques périmées. 1) A function applied to the column (WHERE lower(email) = …) without a functional index. 2) LIKE '%term': no fixed prefix, the sorted tree is useless. 3) Low selectivity (a 50/50 boolean): the planner prefers reading the table. Also: incompatible types, stale statistics.
Quel est le coût caché d'un index ? What is the hidden cost of an index?
Chaque INSERT/UPDATE/DELETE doit mettre à jour tous les index de la table : les écritures ralentissent, les pages se scindent, l'index se fragmente, et chaque index consomme disque et cache. Un index jamais interrogé est une taxe pure. Every INSERT/UPDATE/DELETE must update all the table's indexes: writes slow down, pages split, the index fragments, and each index consumes disk and cache. An index nobody queries is a pure tax.
Quelle différence entre EXPLAIN et EXPLAIN ANALYZE ? What's the difference between EXPLAIN and EXPLAIN ANALYZE?
EXPLAIN montre le plan choisi par le planner avec des coûts estimés, sans exécuter. EXPLAIN ANALYZE exécute réellement la requête et ajoute temps et nombres de lignes réels. L'écart estimé/réel révèle des statistiques périmées. Attention : ANALYZE exécute vraiment un UPDATE/DELETE (→ BEGIN/ROLLBACK). EXPLAIN shows the planner's chosen plan with estimated costs, without executing. EXPLAIN ANALYZE actually runs the query and adds real times and row counts. The estimated/actual gap reveals stale statistics. Careful: ANALYZE really executes an UPDATE/DELETE (→ BEGIN/ROLLBACK).
Résume 1NF, 2NF et 3NF en une phrase chacune. Summarize 1NF, 2NF and 3NF in one sentence each.
1NF : valeurs atomiques, pas de listes dans une colonne. 2NF : aucune colonne ne dépend d'une partie seulement d'une clé composite. 3NF : aucune dépendance transitive — une colonne non-clé ne dépend pas d'une autre colonne non-clé (ex. customer_city stockée dans orders). 1NF: atomic values, no lists inside a column. 2NF: no column depends on only part of a composite key. 3NF: no transitive dependency — a non-key column doesn't depend on another non-key column (e.g. customer_city stored in orders).
Qu'est-ce que le problème N+1 et comment le corriger ? What is the N+1 problem and how do you fix it?
1 requête charge N lignes (100 commandes), puis 1 requête part pour chaque ligne (100 clients) : N+1 allers-retours au lieu de 2. Classique avec les ORM et le lazy loading. Correction : un JOIN ou l'eager loading (select_related, includes, JOIN FETCH). Détection : les logs SQL. 1 query loads N rows (100 orders), then 1 query fires for each row (100 customers): N+1 round trips instead of 2. Classic with ORMs and lazy loading. Fix: a JOIN or eager loading (select_related, includes, JOIN FETCH). Detection: SQL logs.
QCM Quiz
Avec un index sur (last_name, first_name), quelle requête NE PEUT PAS l'utiliser ? With an index on (last_name, first_name), which query CANNOT use it?
Leftmost prefix : l'index est trié par last_name d'abord. Filtrer sur first_name seul revient à chercher tous les « Alice » dans un annuaire — il faut tout lire. Leftmost prefix: the index is sorted by last_name first. Filtering on first_name alone is like finding every "Alice" in a phone book — you have to read everything.
La colonne email est indexée, mais `WHERE lower(email) = 'a@b.fr'` fait un seq scan. Pourquoi ? The email column is indexed, but `WHERE lower(email) = 'a@b.fr'` does a seq scan. Why?
L'index trie les valeurs brutes de email ; le planner ne peut pas s'en servir pour une expression transformée. Solution : un index fonctionnel CREATE INDEX ON users (lower(email)). The index sorts raw email values; the planner can't use it for a transformed expression. Fix: a functional index CREATE INDEX ON users (lower(email)).
Dans un plan, que signifie « Seq Scan … Rows Removed by Filter: 4999952 » ? In a plan, what does "Seq Scan … Rows Removed by Filter: 4999952" mean?
Un Seq Scan qui jette des millions de lignes pour en garder quelques-unes est le symptôme classique d'un index manquant (ou inutilisable) sur la colonne filtrée. A Seq Scan discarding millions of rows to keep a few is the classic symptom of a missing (or unusable) index on the filtered column.
La table orders contient customer_id ET customer_city. Quelle forme normale est violée ? The orders table contains customer_id AND customer_city. Which normal form is violated?
customer_city dépend du client, pas de la commande : c'est une dépendance transitive (order → customer_id → city). Si le client déménage, il faut mettre à jour toutes ses commandes — anomalie typique. customer_city depends on the customer, not the order: a transitive dependency (order → customer_id → city). If the customer moves, every order must be updated — a typical anomaly.
Lequel de ces LIKE peut s'appuyer sur un index B-tree classique ? Which of these LIKE patterns can leverage a regular B-tree index?
Un préfixe fixe ('dupont%') se traduit en range scan sur l'arbre trié. Un joker en tête rend le tri inutilisable — pour la recherche « contient », utiliser pg_trgm + index GIN. A fixed prefix ('dupont%') translates to a range scan over the sorted tree. A leading wildcard makes the ordering useless — for "contains" search, use pg_trgm + a GIN index.
Quel est l'effet principal d'ajouter 5 index à une table qui reçoit beaucoup d'écritures ? What is the main effect of adding 5 indexes to a write-heavy table?
C'est l'arbitrage fondamental : chaque index accélère certaines lectures mais taxe toutes les écritures (mise à jour des B-trees, scission de pages, espace disque). That's the fundamental trade-off: each index speeds up some reads but taxes every write (B-tree updates, page splits, disk space).
Jour 19 Day 19 JavaScript : event loop & async JavaScript: event loop & async
Flashcards Flashcards
JavaScript est single-threaded : comment gère-t-il des opérations longues sans bloquer ? JavaScript is single-threaded: how does it handle long operations without blocking?
Les opérations lentes (réseau, timers, disque) sont déléguées à l'environnement (Web APIs du navigateur, libuv en Node) qui travaille en coulisses. À la fin, le callback est mis en file d'attente et l'event loop l'exécute quand la call stack est vide. Le thread JS ne fait qu'entrelacer du code court. Slow operations (network, timers, disk) are delegated to the environment (browser Web APIs, libuv in Node) working behind the scenes. On completion, the callback is queued and the event loop runs it when the call stack is empty. The JS thread only interleaves short pieces of code.
Quel est l'ordre exact d'un tour d'event loop ? What is the exact order of one event loop turn?
1) Exécuter le code synchrone jusqu'à vider la call stack. 2) Vider ENTIÈREMENT la file des microtasks (promises, await), y compris celles créées en route. 3) Prendre UNE macrotask (setTimeout, I/O, événement). 4) Recommencer. 1) Run synchronous code until the call stack is empty. 2) Drain the microtask queue ENTIRELY (promises, await), including microtasks created along the way. 3) Take ONE macrotask (setTimeout, I/O, event). 4) Repeat.
Pourquoi setTimeout(fn, 0) n'exécute-t-il pas fn immédiatement ? Why doesn't setTimeout(fn, 0) run fn immediately?
fn devient une macrotask : elle attend la fin de tout le code synchrone en cours ET le vidage complet des microtasks. Le délai passé à setTimeout est un minimum avant mise en file, jamais une garantie d'exécution à l'heure dite. fn becomes a macrotask: it waits for all current synchronous code to finish AND the microtask queue to fully drain. The delay passed to setTimeout is a minimum before queueing, never a guarantee of on-time execution.
Quels sont les états d'une promise ? What are the states of a promise?
pending (en attente), puis une seule fois fulfilled (résolue avec une valeur) ou rejected (rejetée avec une raison). Une fois settled, l'état est définitif. .then/.catch retournent une nouvelle promise, ce qui permet le chaînage. pending, then exactly once fulfilled (resolved with a value) or rejected (with a reason). Once settled, the state is final. .then/.catch return a new promise, which enables chaining.
Promise.all vs Promise.allSettled vs Promise.race ? Promise.all vs Promise.allSettled vs Promise.race?
all : tout en parallèle, rejette dès le premier échec (fail-fast). allSettled : attend toutes les promises et retourne {status, value|reason} pour chacune, échecs compris. race : la première promise settled (résolue OU rejetée) l'emporte — utile pour implémenter un timeout. all: everything in parallel, rejects on the first failure (fail-fast). allSettled: waits for all promises and returns {status, value|reason} for each, failures included. race: the first settled promise (resolved OR rejected) wins — useful to implement a timeout.
Que fait exactement await ? What exactly does await do?
await suspend la fonction async (pas le thread !) jusqu'au règlement de la promise, et rend la main à l'event loop. La suite de la fonction est planifiée comme microtask. Si la promise rejette, await lève l'erreur, capturable par try/catch. await suspends the async function (not the thread!) until the promise settles, and yields to the event loop. The rest of the function is scheduled as a microtask. If the promise rejects, await throws the error, catchable with try/catch.
Que signifie « bloquer l'event loop » en Node.js et comment traiter le CPU-bound ? What does "blocking the event loop" mean in Node.js, and how do you handle CPU-bound work?
Une tâche synchrone longue (gros JSON.parse, boucle de calcul, crypto) monopolise l'unique thread : plus AUCUNE requête n'est servie pendant ce temps. Solutions : worker_threads pour déporter le calcul sur de vrais threads, découper le travail (setImmediate), ou déléguer à un service dédié. A long synchronous task (big JSON.parse, compute loop, crypto) monopolizes the single thread: NO request is served in the meantime. Solutions: worker_threads to offload computation to real threads, splitting the work (setImmediate), or delegating to a dedicated service.
Pourquoi try { maFonctionAsync() } catch (e) {} sans await ne capture-t-il rien ? Why does try { myAsyncFn() } catch (e) {} without await catch nothing?
L'appel retourne immédiatement une promise pending ; le bloc try se termine avant que la promise ne rejette. L'erreur devient une unhandledRejection. Il faut await l'appel dans le try (ou chaîner un .catch sur la promise). The call immediately returns a pending promise; the try block exits before the promise rejects. The error becomes an unhandledRejection. You must await the call inside the try (or chain a .catch on the promise).
QCM Quiz
console.log('A'); setTimeout(() => console.log('B'), 0); Promise.resolve().then(() => console.log('C')); console.log('D'); — quel ordre ? console.log('A'); setTimeout(() => console.log('B'), 0); Promise.resolve().then(() => console.log('C')); console.log('D'); — what order?
Synchrone d'abord (A, D), puis toutes les microtasks (C, le .then), puis la macrotask setTimeout (B). Le .then passe toujours avant un setTimeout(0) armé au même moment. Synchronous first (A, D), then all microtasks (C, the .then), then the setTimeout macrotask (B). A .then always runs before a setTimeout(0) armed at the same moment.
Combien de macrotasks l'event loop traite-t-il avant de re-vérifier la file des microtasks ? How many macrotasks does the event loop process before re-checking the microtask queue?
Une macrotask par tour de boucle, puis vidage complet des microtasks avant la suivante. C'est l'asymétrie clé : microtasks en bloc, macrotasks une par une. One macrotask per loop turn, then a full microtask drain before the next one. That's the key asymmetry: microtasks in bulk, macrotasks one at a time.
Dans une fonction async, quand le code AVANT le premier await s'exécute-t-il ? In an async function, when does the code BEFORE the first await run?
Une fonction async démarre en synchrone comme n'importe quelle fonction ; c'est seulement au premier await qu'elle se suspend et que la suite devient une microtask. Piège classique des exercices d'ordre. An async function starts synchronously like any function; only at the first await does it suspend, the rest becoming a microtask. A classic trap in ordering exercises.
Vous devez appeler 5 APIs indépendantes le plus vite possible. Quelle approche ? You must call 5 independent APIs as fast as possible. Which approach?
Promise.all lance les 5 requêtes en parallèle et attend le tout. Le for…of+await est séquentiel (5× plus lent) ; le forEach async n'attend rien du tout. Promise.all fires all 5 requests in parallel and awaits them together. for…of+await is sequential (5× slower); async forEach waits for nothing at all.
Une requête met un serveur Express à genoux : toutes les autres requêtes gèlent pendant 10 secondes. Cause la plus probable ? One request brings an Express server to its knees: all other requests freeze for 10 seconds. Most likely cause?
Node sert toutes les requêtes sur un seul thread : une tâche synchrone longue bloque tout le monde. Remède : worker_threads pour le CPU-bound, ou découper le travail. Node serves all requests on a single thread: one long synchronous task blocks everyone. Remedy: worker_threads for CPU-bound work, or splitting the task.
Quelle affirmation sur Promise.all est correcte ? Which statement about Promise.all is correct?
Promise.all est fail-fast : premier rejet = rejet global (les autres promises continuent mais leur résultat est ignoré). Pour un bilan complet malgré les échecs : Promise.allSettled. Pour la première réglée : race. Promise.all is fail-fast: first rejection = global rejection (other promises keep running but their results are ignored). For a full report despite failures: Promise.allSettled. For the first settled: race.
Jour 18 Day 18 SOLID, design patterns & architecture propre SOLID, design patterns & clean architecture
Flashcards Flashcards
Que signifie le S de SOLID, avec un exemple de violation ? What does the S in SOLID mean, with an example violation?
Single Responsibility : une classe n'a qu'une seule raison de changer. Violation : une classe `Invoice` qui calcule le total, génère le PDF et envoie l'email. Correction : trois classes, chacune ne changeant que pour une raison (règles de calcul, format PDF, envoi). Single Responsibility: a class has only one reason to change. Violation: an `Invoice` class that computes the total, generates the PDF and sends the email. Fix: three classes, each changing for only one reason (calculation rules, PDF format, sending).
Qu'est-ce que le principe Open/Closed et comment le respecter concrètement ? What is the Open/Closed principle and how do you apply it concretely?
Ouvert à l'extension, fermé à la modification : ajouter un comportement sans modifier le code existant. Concrètement : remplacer un `switch` qui grossit par une interface (ex. `PaymentMethod`) et une implémentation par cas — ajouter un cas = ajouter une classe. Open for extension, closed for modification: add behavior without modifying existing code. Concretely: replace a growing `switch` with an interface (e.g. `PaymentMethod`) and one implementation per case — adding a case = adding a class.
Pourquoi `Square extends Rectangle` viole-t-il le principe de Liskov ? Why does `Square extends Rectangle` violate the Liskov principle?
Un sous-type doit être substituable à son parent sans surprise. Or `setWidth` sur un carré modifie aussi la hauteur : du code écrit pour `Rectangle` (poser largeur puis hauteur indépendamment) casse. La hiérarchie mathématique ne fait pas une bonne hiérarchie d'objets mutables. A subtype must be substitutable for its parent without surprises. But `setWidth` on a square also changes the height: code written for `Rectangle` (setting width then height independently) breaks. The mathematical hierarchy doesn't make a good hierarchy of mutable objects.
Qu'est-ce que l'inversion de dépendances (le D de SOLID) ? What is dependency inversion (the D in SOLID)?
Dépendre d'abstractions plutôt que d'implémentations concrètes : `OrderService` reçoit un `OrderRepository` (interface) au lieu de faire `new MySqlOrderRepository()` en dur. Bénéfices : testable avec un faux repo, et on change d'implémentation sans toucher au service. Depend on abstractions rather than concrete implementations: `OrderService` receives an `OrderRepository` (interface) instead of a hardcoded `new MySqlOrderRepository()`. Benefits: testable with a fake repo, and you can swap implementations without touching the service.
Quelle est l'intention du pattern strategy et un exemple concret ? What is the intent of the strategy pattern and a concrete example?
Rendre un algorithme interchangeable derrière une interface commune : le code appelant choisit une implémentation sans connaître les détails. Exemple : calcul des frais de port (standard / express / retrait), chaque mode étant une classe implémentant `ShippingStrategy`. Make an algorithm interchangeable behind a common interface: the calling code picks an implementation without knowing the details. Example: shipping cost computation (standard / express / pickup), each mode being a class implementing `ShippingStrategy`.
Pourquoi se méfier du singleton ? Why be wary of the singleton?
C'est un état global déguisé : couplage fort de tout le code qui l'appelle, tests interdépendants (l'état fuit entre tests), dépendances cachées (invisibles dans les signatures). Alternative : créer l'instance unique au démarrage et l'injecter. It's global state in disguise: tight coupling of all calling code, interdependent tests (state leaks between tests), hidden dependencies (invisible in signatures). Alternative: create the single instance at startup and inject it.
Qu'est-ce que l'architecture hexagonale (ports & adapters) ? What is hexagonal architecture (ports & adapters)?
Le domaine métier au centre, sans dépendance technique ; il définit des ports (interfaces) ; l'infrastructure fournit des adapters qui les implémentent (Postgres, Stripe, HTTP). Règle : les dépendances pointent vers le centre. Bénéfice : tester le métier sans DB, changer d'infra sans toucher aux règles. The business domain at the center, with no technical dependency; it defines ports (interfaces); infrastructure provides adapters implementing them (Postgres, Stripe, HTTP). Rule: dependencies point toward the center. Benefit: test the business logic without a DB, swap infrastructure without touching the rules.
Qu'est-ce que YAGNI et quand faut-il abstraire ? What is YAGNI and when should you abstract?
You Aren't Gonna Need It : ne pas construire pour un besoin hypothétique. Une abstraction se paie comptant (indirection, complexité) ; la bonne heuristique est d'abstraire à la deuxième ou troisième occurrence réelle, car une abstraction prématurée fausse coûte plus cher qu'une duplication temporaire. You Aren't Gonna Need It: don't build for a hypothetical need. An abstraction is paid for upfront (indirection, complexity); the good heuristic is to abstract at the second or third real occurrence, because a wrong premature abstraction costs more than temporary duplication.
QCM Quiz
Une classe `ReportService` calcule des statistiques, les formate en HTML et les envoie par email. Quel principe SOLID est violé ? A `ReportService` class computes statistics, formats them as HTML and emails them. Which SOLID principle is violated?
Trois raisons de changer (règles de calcul, format, canal d'envoi) dans une seule classe : violation du Single Responsibility Principle. On découpe en trois classes. Three reasons to change (calculation rules, format, delivery channel) in one class: a Single Responsibility Principle violation. Split into three classes.
Quel est le principal bénéfice de l'injection de dépendances pour les tests ? What is the main benefit of dependency injection for testing?
La classe dépend d'une interface reçue de l'extérieur : en test, on injecte un faux repo en mémoire au lieu de la vraie base. C'est le bénéfice le plus cité en entretien. The class depends on an interface received from outside: in tests you inject a fake in-memory repo instead of the real database. It's the most cited benefit in interviews.
Dans l'architecture hexagonale, dans quel sens pointent les dépendances ? In hexagonal architecture, which way do dependencies point?
La règle de dépendance : tout pointe vers le domaine. Le domaine définit des ports (interfaces), les adapters les implémentent. Le métier ne connaît ni Postgres ni Express. The dependency rule: everything points toward the domain. The domain defines ports (interfaces), adapters implement them. The business logic knows neither Postgres nor Express.
Vous remplacez un `switch (shippingMode)` grandissant par une interface `ShippingStrategy` et trois implémentations. Quel pattern appliquez-vous ? You replace a growing `switch (shippingMode)` with a `ShippingStrategy` interface and three implementations. Which pattern are you applying?
Strategy : un algorithme interchangeable derrière une interface commune. C'est aussi une application directe du principe Open/Closed — ajouter un mode = ajouter une classe. Strategy: an interchangeable algorithm behind a common interface. It's also a direct application of the Open/Closed principle — adding a mode = adding a class.
Quel pattern reconnaissez-vous dans `button.addEventListener('click', handler)` ? Which pattern do you recognize in `button.addEventListener('click', handler)`?
Observer : des abonnés (handlers) sont notifiés quand un événement survient, sans que l'émetteur les connaisse. Savoir nommer les patterns dans les APIs du quotidien est très apprécié en entretien. Observer: subscribers (handlers) get notified when an event occurs, without the emitter knowing them. Naming patterns inside everyday APIs is highly valued in interviews.
Quand une abstraction (interface, couche) est-elle généralement justifiée ? When is an abstraction (interface, layer) generally justified?
YAGNI : l'abstraction se paie comptant pour un bénéfice hypothétique. On abstrait à la deuxième occurrence réelle ou pour un besoin concret (tests), pas « au cas où ». YAGNI: abstraction is paid upfront for a hypothetical benefit. Abstract at the second real occurrence or for a concrete need (tests), not "just in case".
Actu News GitHub à genoux pendant 8 heures : les agents IA ont doublé le trafic, l'infra n'a pas suivi GitHub down for 8 hours: AI agents doubled the traffic, the infrastructure gave way
Flashcards Flashcards
Quelle a été la cause racine de la panne GitHub du 17 août 2026 ? What was the root cause of the GitHub outage on August 17, 2026?
Ni un bug ni un changement de configuration : un pur manque de capacité. Un composant d'infrastructure critique du datacenter Central US n'a pas suivi un pic de trafic record et la pression s'est propagée en cascade, en commençant par l'authentification. Les proxys sidecar saturés étaient invisibles pour l'auto-scaling, qui ne comptait pas leur capacité. Résultat : 7h47 de dégradation mondiale (Actions, API, Copilot, auth). Neither a bug nor a configuration change: a pure capacity shortage. A critical infrastructure component in the Central US data center failed to keep up with record traffic and the pressure cascaded, starting with authentication. The saturated sidecar proxies were invisible to auto-scaling, which did not account for their capacity. Result: 7h47 of global degradation (Actions, APIs, Copilot, auth).
D'où venait le trafic record qui a fait tomber GitHub, et quels chiffres le prouvent ? Where did the record traffic that brought GitHub down come from, and which numbers prove it?
Des agents IA qui committent en masse : les commits mensuels sont passés de 1,4 milliard en avril 2026 à 2,9 milliards en août, un doublement en quatre mois qu'aucune croissance humaine n'explique. S'y ajoutent environ 130 millions de PR fusionnées et plus de 115 millions de runs Actions par mois. From AI agents committing at scale: monthly commits went from 1.4 billion in April 2026 to 2.9 billion in August, a doubling in four months that no human growth explains. Add roughly 130 million merged PRs and over 115 million Actions runs per month.
Quels sont les quatre ingrédients d'un retry bien conçu ? What are the four ingredients of a well-designed retry?
Le backoff exponentiel (attendre de plus en plus longtemps entre les tentatives), le jitter (un aléa pour que tous les clients ne réessaient pas à la même seconde), le budget de retry (au-delà d'un certain taux d'échec, arrêter d'insister et dégrader proprement) et l'idempotence (rejouer la requête ne crée pas de doublon). Pendant la panne GitHub, les boucles de retry des clients Copilot ont augmenté le trafic en pleine récupération. Exponential backoff (wait longer and longer between attempts), jitter (randomness so clients do not all retry in the same second), a retry budget (past a certain failure rate, stop insisting and degrade gracefully) and idempotency (replaying the request creates no duplicate). During the GitHub outage, Copilot client retry loops increased traffic in the middle of recovery.
Pourquoi dit-on que la fenêtre de patch se compte désormais en heures ? Why do we say the patch window is now measured in hours?
Exemples de la semaine du 18 août 2026 : le contournement d'authentification SharePoint (CVE-2026-55040) a été exploité quelques heures après la publication du PoC public, et la traversée de chemin vCenter (CVE-2026-59310) a compromis 361 serveurs dans 47 pays cinq jours après le correctif. La vraie défense n'est plus seulement de patcher vite, mais de ne pas exposer ces outils internes sur Internet. Examples from the week of August 18, 2026: the SharePoint auth bypass (CVE-2026-55040) was exploited within hours of the public PoC, and the vCenter path traversal (CVE-2026-59310) compromised 361 servers across 47 countries five days after the fix. The real defense is no longer just patching fast, but not exposing these internal tools to the Internet.
QCM Quiz
Qu'est-ce qui a causé la panne mondiale de GitHub du 17 août 2026 ? What caused GitHub's global outage on August 17, 2026?
Le postmortem est explicite : ni code ni configuration. Un composant critique du datacenter Central US a saturé sous un trafic record (commits doublés par les agents IA), et l'auto-scaling ne mesurait pas la capacité des proxys sidecar concernés. The postmortem is explicit: neither code nor configuration. A critical Central US data center component saturated under record traffic (commits doubled by AI agents), and auto-scaling did not measure the capacity of the affected sidecar proxies.
Pendant la récupération de la panne, qu'est-ce qui a aggravé la situation ? During recovery from the outage, what made things worse?
Les boucles de retry des services Copilot ont amplifié le trafic pendant la reprise : c'est la « retry storm ». D'où les remédiations annoncées : limites et budgets de retry cohérents entre services, en plus des 3 millions de cœurs CPU déployés. Retry loops in Copilot services amplified traffic during recovery: the classic retry storm. Hence the announced remediations: consistent retry limits and budgets across services, on top of 3 million CPU cores deployed.
Que révèle le dépôt SEC de Nvidia du 17 août 2026 ? What does Nvidia's August 17, 2026 SEC filing reveal?
Nvidia garantit jusqu'à 105 Md$ pour la première phase d'un campus de 8 gigawatts dans l'Ohio, construit et exploité par SB Energy avec un bail de 20 ans pour OpenAI, mise en service à partir de 2028. Le fournisseur de puces finance son propre client : un exemple type de la circularité de l'économie IA. Nvidia backs up to $105B for the first phase of an 8 gigawatt campus in Ohio, built and operated by SB Energy under a 20-year lease to OpenAI, coming online from 2028. The chip supplier financing its own customer: a textbook example of the AI economy's circularity.
Jour 17 Day 17 Complexité & Big O Complexity & Big O
Flashcards Flashcards
Que décrit exactement la notation Big O ? What exactly does Big O notation describe?
La croissance du coût (temps ou mémoire) d'un algorithme en fonction de la taille de l'entrée n, en gardant le terme dominant et en jetant les constantes. Elle prédit le passage à l'échelle, pas la vitesse absolue en secondes. How an algorithm's cost (time or memory) grows with the input size n, keeping the dominant term and dropping constants. It predicts scaling, not absolute speed in seconds.
Pourquoi la recherche dichotomique est-elle O(log n) et quelle est sa précondition ? Why is binary search O(log n) and what is its precondition?
Chaque comparaison élimine la moitié de l'espace de recherche restant : il faut log₂(n) étapes pour tomber à un seul élément (~20 pour un million). Précondition indispensable : le tableau doit être trié. Each comparison eliminates half of the remaining search space: it takes log₂(n) steps to reach a single element (~20 for a million). Non-negotiable precondition: the array must be sorted.
Quelle est la complexité moyenne et pire cas d'un lookup dans une hash map, et pourquoi ? What is the average and worst-case complexity of a hash map lookup, and why?
O(1) en moyenne : la fonction de hachage donne directement l'index du bucket. O(n) au pire : si toutes les clés collisionnent dans le même bucket, on parcourt une liste. Les bonnes implémentations redimensionnent pour maintenir le O(1) moyen. O(1) on average: the hash function directly yields the bucket index. O(n) worst case: if all keys collide into the same bucket, you traverse a list. Good implementations resize to keep the O(1) average.
Qu'est-ce que la complexité amortie ? Donnez l'exemple canonique. What is amortized complexity? Give the canonical example.
Le coût moyen garanti sur une séquence d'opérations, même si certaines sont chères. Exemple : le push d'un tableau dynamique est O(1) amorti — les réallocations O(n) existent, mais le doublement de capacité les rend exponentiellement rares. The guaranteed average cost over a sequence of operations, even if some are expensive. Example: a dynamic array push is amortized O(1) — O(n) reallocations happen, but capacity doubling makes them exponentially rare.
Quelle différence entre complexité en temps et en espace ? Exemple avec les tris. What's the difference between time and space complexity? Example with sorts.
Le temps compte les opérations, l'espace compte la mémoire supplémentaire allouée (pile de récursion incluse). Merge sort : O(n log n) temps mais O(n) espace (tableaux temporaires) ; heapsort : O(n log n) temps et O(1) espace (tri en place). Time counts operations, space counts extra allocated memory (recursion stack included). Merge sort: O(n log n) time but O(n) space (temporary arrays); heapsort: O(n log n) time and O(1) space (in-place sort).
Pourquoi `a.filter(x => b.includes(x))` est-il un piège de performance ? Why is `a.filter(x => b.includes(x))` a performance trap?
includes() est un scan linéaire O(m) caché dans une boucle O(n) : total O(n × m). Le remplacer par un Set (construction O(m), lookup O(1)) ramène le tout à O(n + m) — on échange de la mémoire contre du temps. includes() is an O(m) linear scan hidden inside an O(n) loop: O(n × m) total. Replacing it with a Set (O(m) build, O(1) lookup) brings it down to O(n + m) — trading memory for time.
Pourquoi ne peut-on pas trier par comparaison plus vite que O(n log n) ? Why can't comparison-based sorting beat O(n log n)?
Il y a n! permutations possibles et chaque comparaison n'apporte qu'un bit d'information : il faut au moins log₂(n!) ≈ n log n comparaisons pour les distinguer. Les tris non comparatifs (counting sort, radix sort) contournent la borne quand les clés s'y prêtent. There are n! possible permutations and each comparison yields only one bit of information: you need at least log₂(n!) ≈ n log n comparisons to distinguish them. Non-comparison sorts (counting sort, radix sort) sidestep the bound when the keys allow it.
Quicksort est O(n²) au pire cas : pourquoi reste-t-il le tri de référence ? Quicksort is O(n²) worst case: why is it still the go-to sort?
Le pire cas (pivot systématiquement mauvais) est rarissime avec un pivot aléatoire ou médian ; ses constantes sont excellentes (en place, cache-friendly). Les libs réelles se protègent : introsort bascule sur heapsort si la récursion dégénère. The worst case (systematically bad pivot) is vanishingly rare with a random or median pivot; its constants are excellent (in place, cache-friendly). Real libraries protect themselves: introsort switches to heapsort if recursion degenerates.
QCM Quiz
Quelle est la complexité de deux boucles successives (non imbriquées) sur un tableau de taille n ? What is the complexity of two successive (non-nested) loops over an array of size n?
O(n) + O(n) = O(2n) = O(n) : les constantes disparaissent. Seule l'imbrication multiplie les coûts et donne du O(n²). O(n) + O(n) = O(2n) = O(n): constants vanish. Only nesting multiplies costs and yields O(n²).
Quelle est la complexité en temps du Fibonacci récursif naïf (sans mémoïsation) ? What is the time complexity of naive recursive Fibonacci (no memoization)?
Chaque appel en déclenche deux : l'arbre d'appels double à chaque niveau, croissance exponentielle. La mémoïsation ramène à O(n) en calculant chaque valeur une seule fois. Each call spawns two more: the call tree doubles at every level, exponential growth. Memoization brings it to O(n) by computing each value once.
Pourquoi le push en fin de tableau dynamique est-il dit « O(1) amorti » et pas simplement O(1) ? Why is a push at the end of a dynamic array called "amortized O(1)" rather than plain O(1)?
C'est la définition de l'analyse amortie : un coût O(n) occasionnel, étalé sur les N opérations qui l'ont précédé, donne un coût moyen constant garanti. That's the definition of amortized analysis: an occasional O(n) cost, spread over the N operations before it, yields a guaranteed constant average cost.
Sur un tableau TRIÉ, quelle approche trouve si une paire somme à une cible en O(n) temps et O(1) espace ? On a SORTED array, which approach finds whether a pair sums to a target in O(n) time and O(1) space?
Les deux pointeurs exploitent le tri : somme trop petite → avancer la gauche, trop grande → reculer la droite. O(n) temps, O(1) espace. La hash map fait O(n) temps mais O(n) espace ; la dichotomie par élément fait O(n log n). Two pointers exploit the sorting: sum too small → move left up, too big → move right down. O(n) time, O(1) space. The hash map is O(n) time but O(n) space; per-element binary search is O(n log n).
Quelle est la complexité de l'insertion d'un élément au MILIEU d'un tableau dynamique ? What is the complexity of inserting an element in the MIDDLE of a dynamic array?
Insérer au milieu force le décalage de tous les éléments à droite : O(n). Le O(1) amorti ne vaut que pour l'ajout en fin. C'est la force de la liste chaînée (O(1) si on tient déjà le nœud) — au prix de l'accès O(n). Inserting in the middle forces shifting every element to the right: O(n). Amortized O(1) only holds for appending at the end. That's the linked list's strength (O(1) if you already hold the node) — at the price of O(n) access.
Un merge sort suivi d'un parcours linéaire : quelle est la complexité globale ? A merge sort followed by a linear traversal: what is the overall complexity?
O(n log n) + O(n) = O(n log n) : le terme dominant absorbe le reste. Réflexe à avoir dès qu'on ajoute un tri « pour simplifier » : il met un plancher O(n log n) à toute la solution. O(n log n) + O(n) = O(n log n): the dominant term absorbs the rest. A reflex to have whenever you add a sort "to simplify": it puts an O(n log n) floor under the whole solution.
Jour 16 Day 16 HTTP de A à Z HTTP from A to Z
Flashcards Flashcards
Quelle est la différence entre 401 et 403 ? What's the difference between 401 and 403?
401 Unauthorized = non authentifié (le serveur ne sait pas qui vous êtes : token absent ou expiré). 403 Forbidden = authentifié mais sans les droits nécessaires. Se réauthentifier corrige un 401, jamais un 403. 401 Unauthorized = not authenticated (the server doesn't know who you are: missing or expired token). 403 Forbidden = authenticated but lacking permission. Re-authenticating fixes a 401, never a 403.
Qu'est-ce qu'une méthode HTTP idempotente ? Citez celles qui le sont. What is an idempotent HTTP method? Which ones are?
Une méthode qu'on peut rejouer N fois avec le même état final qu'une seule exécution : GET, HEAD, PUT, DELETE (et OPTIONS). POST ne l'est pas — le rejouer crée des doublons, d'où les clés d'idempotence des API de paiement. A method you can replay N times with the same final state as one execution: GET, HEAD, PUT, DELETE (and OPTIONS). POST is not — replaying it creates duplicates, hence the idempotency keys of payment APIs.
PUT vs PATCH : quelle différence ? PUT vs PATCH: what's the difference?
PUT remplace la ressource entière (ce qui n'est pas envoyé disparaît) et est idempotent par définition. PATCH applique une modification partielle et n'est pas idempotent par contrat. PUT peut aussi créer la ressource à une URL connue du client. PUT replaces the entire resource (anything not sent is wiped) and is idempotent by definition. PATCH applies a partial modification and is not idempotent by contract. PUT can also create the resource at a URL the client knows.
Comment fonctionne la négociation de contenu ? How does content negotiation work?
Le client annonce ses préférences via les headers Accept (format), Accept-Language (langue) et Accept-Encoding (compression) ; le serveur choisit et répond avec Content-Type / Content-Encoding, ou 406 Not Acceptable s'il ne peut pas satisfaire la demande. The client announces its preferences via the Accept (format), Accept-Language (language) and Accept-Encoding (compression) headers; the server picks and answers with Content-Type / Content-Encoding, or 406 Not Acceptable if it can't satisfy the request.
À quoi servent les attributs HttpOnly, Secure et SameSite d'un cookie ? What are a cookie's HttpOnly, Secure and SameSite attributes for?
HttpOnly rend le cookie invisible à JavaScript (protège contre le vol par XSS), Secure limite son envoi au HTTPS, SameSite contrôle son envoi sur les requêtes cross-site (protection CSRF, valeur Lax par défaut dans les navigateurs). HttpOnly makes the cookie invisible to JavaScript (protects against theft via XSS), Secure restricts it to HTTPS, SameSite controls whether it's sent on cross-site requests (CSRF protection, Lax by default in browsers).
Qu'est-ce que le head-of-line blocking en HTTP/1.1 et comment HTTP/2 puis HTTP/3 le traitent-ils ? What is head-of-line blocking in HTTP/1.1 and how do HTTP/2 then HTTP/3 address it?
En 1.1, les requêtes d'une connexion sont séquentielles : une réponse lente bloque les suivantes. HTTP/2 multiplexe des streams sur une connexion TCP (fini le HOL au niveau HTTP), mais un paquet TCP perdu bloque encore tous les streams. HTTP/3/QUIC (UDP) rend chaque stream indépendant face à la perte. In 1.1, requests on a connection are sequential: a slow response blocks the next ones. HTTP/2 multiplexes streams over one TCP connection (no more HTTP-level HOL), but one lost TCP packet still stalls all streams. HTTP/3/QUIC (UDP) makes each stream independent under loss.
Résumez le handshake TLS en deux phrases. Summarize the TLS handshake in two sentences.
Client et serveur négocient les algorithmes, le serveur prouve son identité avec un certificat signé par une autorité de confiance, et un échange Diffie-Hellman éphémère établit une clé de session symétrique. Tout le trafic HTTP est ensuite chiffré avec cette clé — en TLS 1.3, un seul aller-retour suffit. Client and server negotiate algorithms, the server proves its identity with a certificate signed by a trusted authority, and an ephemeral Diffie-Hellman exchange establishes a symmetric session key. All HTTP traffic is then encrypted with that key — in TLS 1.3 a single round trip is enough.
Que signifient 502 et 503, et qui les émet en général ? What do 502 and 503 mean, and who typically emits them?
502 Bad Gateway : le reverse proxy (nginx, Traefik) n'a pas obtenu de réponse valide du backend (crashé, injoignable). 503 Service Unavailable : le service est surchargé ou en maintenance, souvent avec un Retry-After. Les deux viennent typiquement de la couche proxy/load balancer. 502 Bad Gateway: the reverse proxy (nginx, Traefik) got no valid response from the backend (crashed, unreachable). 503 Service Unavailable: the service is overloaded or in maintenance, often with a Retry-After. Both typically come from the proxy/load-balancer layer.
QCM Quiz
Votre API reçoit un JSON syntaxiquement valide mais dont l'email est déjà utilisé par un autre compte. Quel code renvoyer ? Your API receives syntactically valid JSON but the email is already used by another account. Which code should you return?
409 Conflict exprime un conflit avec l'état actuel de la ressource (unicité violée). 400 = requête malformée, 500 = bug serveur ; ici la requête est correcte, c'est l'état qui coince. 422 serait défendable pour une validation métier. 409 Conflict expresses a conflict with the resource's current state (uniqueness violated). 400 = malformed request, 500 = server bug; here the request is fine, the state is the problem. 422 would be defensible for business validation.
Pourquoi un client HTTP peut-il retenter automatiquement un GET ou un DELETE, mais pas un POST ? Why can an HTTP client automatically retry a GET or DELETE, but not a POST?
L'idempotence est le contrat qui rend le retry sûr. Pour retenter un POST sans risque, les API fournissent une clé d'idempotence (header Idempotency-Key). Idempotence is the contract that makes retries safe. To retry a POST safely, APIs provide an idempotency key (Idempotency-Key header).
Que signifie une réponse 304 Not Modified ? What does a 304 Not Modified response mean?
Le client revalide avec If-None-Match (ETag) ou If-Modified-Since ; si rien n'a changé, le serveur répond 304 sans body et le client réutilise son cache. Économie de bande passante majeure. The client revalidates with If-None-Match (ETag) or If-Modified-Since; if nothing changed, the server answers 304 with no body and the client reuses its cache. Major bandwidth savings.
Quelle est LA nouveauté d'HTTP/2 qui supprime le head-of-line blocking au niveau HTTP ? What is THE HTTP/2 feature that removes HTTP-level head-of-line blocking?
HTTP/2 entrelace des dizaines de streams binaires sur un seul TCP : une réponse lente ne bloque plus les autres. Le keep-alive existait déjà en 1.1, et c'est HTTP/3 qui passe à UDP (QUIC). HTTP/2 interleaves dozens of binary streams over one TCP connection: a slow response no longer blocks the others. Keep-alive already existed in 1.1, and it's HTTP/3 that moves to UDP (QUIC).
Pourquoi HTTP/3 utilise-t-il QUIC sur UDP plutôt que TCP ? Why does HTTP/3 use QUIC over UDP rather than TCP?
C'est le HOL blocking résiduel de TCP qui motive QUIC. Bonus de QUIC : TLS 1.3 intégré au handshake et migration de connexion (Wi-Fi → 4G) sans couper. TCP's residual HOL blocking is what motivates QUIC. QUIC bonuses: TLS 1.3 built into the handshake and connection migration (Wi-Fi → 4G) without dropping.
Une API renvoie 200 OK avec {"error":"user not found"} dans le body. Quel est le vrai problème ? An API returns 200 OK with {"error":"user not found"} in the body. What's the real problem?
Tout l'écosystème HTTP (caches, proxies, SDK générés, alerting) raisonne sur le code de statut. Un « 200 d'erreur » casse le cache, fausse les métriques et masque les pannes : ici, un 404 s'impose. The whole HTTP ecosystem (caches, proxies, generated SDKs, alerting) reasons on the status code. An 'error 200' breaks caching, skews metrics and hides failures: a 404 is the right answer here.
Jour 15 Day 15 Observabilité : logs, metrics & traces Observability: logs, metrics & traces
Flashcards Flashcards
Quelle est la différence entre monitoring et observabilité ? What is the difference between monitoring and observability?
Le monitoring vérifie des conditions connues d'avance (seuils, dashboards prédéfinis) et dit QUE ça casse. L'observabilité est la capacité à répondre à des questions non anticipées à partir des données émises par le système (logs, metrics, traces) : elle permet de comprendre POURQUOI. Monitoring checks conditions known in advance (thresholds, predefined dashboards) and tells you THAT something broke. Observability is the ability to answer unanticipated questions from the data the system emits (logs, metrics, traces): it lets you understand WHY.
Quels sont les trois piliers de l'observabilité et leurs forces/faiblesses ? What are the three pillars of observability and their strengths/weaknesses?
Logs : événements discrets riches en contexte, chers en volume. Metrics : agrégats numériques pas chers, parfaits pour alerter, pauvres en contexte. Traces : parcours d'une requête à travers les services en spans. Leur vraie force : la corrélation par trace ID. Logs: discrete events rich in context, expensive in volume. Metrics: cheap numeric aggregates, perfect for alerting, poor in context. Traces: a request's journey across services in spans. Their real power: correlation via trace ID.
Pourquoi des logs structurés en JSON plutôt que du texte libre ? Why structured JSON logs rather than free text?
On peut filtrer, agréger et chercher par champ (level, route, user_id, duration_ms) au lieu de grepper du texte. Avec un identifiant de corrélation (request/trace ID) propagé entre services, on reconstitue le parcours complet d'une requête dans toute la stack. You can filter, aggregate and search by field (level, route, user_id, duration_ms) instead of grepping text. With a correlation identifier (request/trace ID) propagated between services, you can reconstruct a request's full journey through the stack.
Que sont les méthodes RED et USE ? What are the RED and USE methods?
RED, pour les services : Rate (requêtes/s), Errors (taux d'erreur), Duration (latence en percentiles p50/p95/p99). USE, pour les ressources : Utilization, Saturation, Errors. Deux grilles standard pour construire dashboards et alertes. RED, for services: Rate (requests/s), Errors (error rate), Duration (latency in p50/p95/p99 percentiles). USE, for resources: Utilization, Saturation, Errors. Two standard grids for building dashboards and alerts.
Comment fonctionne une trace distribuée ? How does a distributed trace work?
Une trace est un arbre de spans, chacun représentant une opération (appel HTTP, requête SQL) avec durée, attributs et parent. La context propagation transporte le trace ID et le span ID parent dans les headers HTTP (W3C traceparent) de service en service, permettant de reconstituer l'arbre complet. A trace is a tree of spans, each representing an operation (HTTP call, SQL query) with duration, attributes and a parent. Context propagation carries the trace ID and parent span ID in HTTP headers (W3C traceparent) from service to service, allowing the full tree to be reconstructed.
Qu'est-ce qu'OpenTelemetry et son argument clé ? What is OpenTelemetry and its key argument?
Le standard CNCF vendor-neutral pour générer et exporter logs, metrics et traces : SDK par langage, auto-instrumentation, et un Collector qui reçoit, transforme et exporte. On instrumente une fois et on change de backend (Jaeger, Prometheus, Datadog…) sans toucher au code : pas de lock-in. The vendor-neutral CNCF standard for generating and exporting logs, metrics and traces: per-language SDKs, auto-instrumentation, and a Collector that receives, transforms and exports. Instrument once and switch backends (Jaeger, Prometheus, Datadog…) without touching the code: no lock-in.
SLI et SLO : définis-les en deux phrases. SLI and SLO: define them in two sentences.
Un SLI est une mesure de ce que vivent les utilisateurs (ex. proportion de requêtes servies en moins de 300 ms). Un SLO est l'objectif qu'on s'engage à tenir sur ce SLI (ex. 99,9 % sur 30 jours) — le budget d'erreur qui en découle arbitre entre fiabilité et vitesse de déploiement. An SLI is a measurement of what users experience (e.g. proportion of requests served under 300 ms). An SLO is the target you commit to on that SLI (e.g. 99.9% over 30 days) — the resulting error budget arbitrates between reliability and deployment speed.
Pourquoi alerter sur les symptômes plutôt que sur les causes ? Why alert on symptoms rather than causes?
Les utilisateurs subissent les symptômes (erreurs, latence), pas les causes (CPU haut). Un CPU à 95 % avec des utilisateurs heureux ne justifie pas de réveiller quelqu'un ; un taux d'erreur à 5 % si. Alerter sur les causes génère de l'alert fatigue ; les causes se consultent dans les dashboards après l'alerte. Users suffer symptoms (errors, latency), not causes (high CPU). A CPU at 95% with happy users doesn't justify waking someone up; a 5% error rate does. Alerting on causes generates alert fatigue; causes get consulted in dashboards after the alert.
QCM Quiz
Quel pilier est le moins cher à stocker et le plus adapté aux alertes ? Which pillar is the cheapest to store and best suited for alerting?
Une metric est une série de nombres agrégés : quelques octets par point, évaluable en continu par le moteur d'alerting. Logs et traces sont riches mais volumineux — ils servent au diagnostic, pas au déclenchement. A metric is a series of aggregated numbers: a few bytes per point, continuously evaluable by the alerting engine. Logs and traces are rich but bulky — they serve diagnosis, not triggering.
Pourquoi ne jamais mettre user_id en label d'une metric Prometheus ? Why should you never put user_id as a Prometheus metric label?
Chaque combinaison de valeurs de labels est une série distincte en mémoire : un million d'utilisateurs = un million de séries par metric. Les labels doivent avoir des valeurs bornées (status code, endpoint) ; les IDs uniques vont dans les logs et traces. Each combination of label values is a distinct series in memory: a million users = a million series per metric. Labels must have bounded values (status code, endpoint); unique IDs belong in logs and traces.
Comment le contexte d'une trace se propage-t-il entre deux services HTTP ? How does trace context propagate between two HTTP services?
La context propagation est faite par l'instrumentation : le client injecte le header traceparent, le serveur suivant le lit et crée ses spans comme enfants. Le Collector reçoit les spans exportés, il n'intercepte pas le trafic. Context propagation is done by the instrumentation: the client injects the traceparent header, the next server reads it and creates its spans as children. The Collector receives exported spans; it doesn't intercept traffic.
Latence moyenne à 80 ms mais des plaintes d'utilisateurs : que regarder d'abord ? Average latency at 80 ms but users are complaining: what do you look at first?
99 requêtes à 50 ms + 1 à 5 s donnent une moyenne correcte et 1 % d'utilisateurs furieux — souvent les plus actifs. Les percentiles décrivent l'expérience réelle ; c'est pour ça que les SLO se définissent sur des percentiles. 99 requests at 50 ms + 1 at 5 s give a decent average and 1% of furious users — often the most active. Percentiles describe the real experience; that's why SLOs are defined on percentiles.
Quel est le principal argument d'OpenTelemetry face aux SDK propriétaires (Datadog, New Relic…) ? What is OpenTelemetry's main argument versus proprietary SDKs (Datadog, New Relic…)?
OTel standardise l'instrumentation et l'export (via le Collector) : le backend devient interchangeable, fini le lock-in par le code instrumenté. OTel ne stocke rien lui-même : il génère et transporte les signaux vers un backend. OTel standardizes instrumentation and export (via the Collector): the backend becomes interchangeable, ending lock-in through instrumented code. OTel stores nothing itself: it generates and transports signals to a backend.
Une équipe reçoit 40 alertes par jour et les acquitte sans agir. Quel est le vrai problème ? A team receives 40 alerts a day and acknowledges them without acting. What is the real problem?
Une alerte acquittée sans action est une alerte inutile qui entraîne l'équipe à ignorer les notifications. Remède : alerter sur les symptômes (SLI/SLO), supprimer ou revoir chaque alerte non actionnable — pas ajouter du monde ni des seuils plus fins. An alert acknowledged without action is a useless alert training the team to ignore notifications. Remedy: alert on symptoms (SLI/SLO), delete or rework every non-actionable alert — not adding people or tighter thresholds.
Jour 14 Day 14 MCP : le Model Context Protocol MCP: the Model Context Protocol
Flashcards Flashcards
Quel problème MCP résout-il ? What problem does MCP solve?
L'intégration N×M : chaque application LLM devait écrire un connecteur custom pour chaque service. MCP standardise le protocole entre les deux : un serveur écrit une fois fonctionne avec tous les hosts compatibles — on passe de N×M à N+M connecteurs. N×M integration: every LLM application had to write a custom connector for every service. MCP standardizes the protocol between the two: a server written once works with every compatible host — going from N×M to N+M connectors.
Quels sont les trois rôles de l'architecture MCP ? What are the three roles in the MCP architecture?
Le host (l'application LLM : Claude Desktop, un IDE), qui orchestre ; le client (la connexion 1-à-1 vers un serveur, à l'intérieur du host) ; le serveur (le programme qui expose tools, resources et prompts). Un host connecté à trois serveurs maintient trois clients. The host (the LLM application: Claude Desktop, an IDE), which orchestrates; the client (the 1-to-1 connection to a server, inside the host); the server (the program exposing tools, resources and prompts). A host connected to three servers maintains three clients.
Tools, resources, prompts : qui contrôle quoi ? Tools, resources, prompts: who controls what?
Tools : le modèle décide de les appeler (avec approbation utilisateur) — ex. create_issue. Resources : l'application choisit les données à attacher au contexte — ex. contenu de fichier. Prompts : templates déclenchés explicitement par l'utilisateur — ex. slash commands. Tools: the model decides to call them (with user approval) — e.g. create_issue. Resources: the application chooses the data to attach to the context — e.g. file contents. Prompts: templates explicitly triggered by the user — e.g. slash commands.
Sur quoi repose la communication MCP et quels sont les deux transports standard ? What does MCP communication run on, and what are the two standard transports?
Sur JSON-RPC 2.0, avec une poignée de main initialize qui négocie version et capacités. Transports : stdio (le host lance le serveur en sous-processus, communication stdin/stdout, idéal en local) et HTTP streamable (endpoint distant avec streaming, qui remplace l'ancien HTTP+SSE). On JSON-RPC 2.0, with an initialize handshake negotiating version and capabilities. Transports: stdio (the host launches the server as a subprocess, stdin/stdout communication, ideal locally) and streamable HTTP (a remote endpoint with streaming, replacing the older HTTP+SSE).
Quelle différence entre MCP et le function calling classique ? What's the difference between MCP and classic function calling?
Le function calling est le mécanisme par lequel le modèle génère des appels de fonctions, mais chaque intégration reste du code custom dans une seule app. MCP standardise la couche au-dessus : découverte dynamique (tools/list), transport, cycle de vie — un serveur MCP est réutilisable par n'importe quel host. Function calling is the mechanism by which the model generates function calls, but each integration remains custom code inside a single app. MCP standardizes the layer above: dynamic discovery (tools/list), transport, lifecycle — an MCP server is reusable by any host.
Qu'est-ce que la prompt injection indirecte via un outil MCP ? What is indirect prompt injection through an MCP tool?
Du contenu externe rapporté par un outil (page web, issue GitHub, email) contient des instructions malveillantes que le modèle risque de suivre — ex. exfiltrer des secrets via un autre outil. Le trio dangereux : données privées + contenu non fiable + canal de sortie externe. External content brought back by a tool (web page, GitHub issue, email) contains malicious instructions the model may follow — e.g. exfiltrating secrets through another tool. The dangerous trio: private data + untrusted content + an external output channel.
Quelles parades de sécurité citer pour un déploiement MCP ? Which security countermeasures should you cite for an MCP deployment?
Principe du moindre privilège (tokens à permissions minimales, serveurs read-only si possible), human-in-the-loop pour les actions sensibles, audit des serveurs tiers avant installation (ils exécutent du code localement), et isolation des serveurs à risque. Principle of least privilege (minimally-scoped tokens, read-only servers when possible), human-in-the-loop for sensitive actions, auditing third-party servers before installing them (they run code locally), and isolating risky servers.
Pourquoi MCP est-il un bon sujet d'entretien en 2026, et comment en parler intelligemment ? Why is MCP a good interview topic in 2026, and how do you discuss it intelligently?
Adopté au-delà d'Anthropic (OpenAI, Google DeepMind, Microsoft, les IDE), c'est le standard de facto des agents. Un stagiaire marque des points en citant un usage concret (serveur GitHub/Postgres dans un IDE) ou un mini-serveur écrit avec le SDK, plus les limites : coût en tokens, risques d'injection. Adopted beyond Anthropic (OpenAI, Google DeepMind, Microsoft, IDEs), it's the de facto agent standard. An intern scores points by citing concrete usage (a GitHub/Postgres server in an IDE) or a mini-server written with the SDK, plus the limits: token cost, injection risks.
QCM Quiz
MCP transforme le problème d'intégration N×M en : MCP turns the N×M integration problem into:
Chaque application implémente le protocole une fois (côté client), chaque service est encapsulé une fois (côté serveur) : N+M composants au lieu de N×M intégrations custom. C'est l'analogie USB-C. Each application implements the protocol once (client side), each service is wrapped once (server side): N+M components instead of N×M custom integrations. That's the USB-C analogy.
Dans MCP, qui décide d'appeler un tool ? In MCP, who decides to call a tool?
Les tools sont contrôlés par le modèle (avec garde-fou humain). Ce sont les resources qui sont contrôlées par l'application, et les prompts par l'utilisateur — la séparation des trois est un choix de design du protocole. Tools are model-controlled (with a human guardrail). Resources are application-controlled and prompts user-controlled — the three-way separation is a deliberate protocol design choice.
Quel transport utilise un serveur MCP lancé localement par Claude Desktop ? Which transport does an MCP server launched locally by Claude Desktop use?
En local, le host lance le serveur comme sous-processus et échange des messages JSON-RPC sur stdin/stdout : simple, pas de port réseau. Pour les serveurs distants ou partagés, c'est le transport HTTP streamable. Locally, the host launches the server as a subprocess and exchanges JSON-RPC messages over stdin/stdout: simple, no network port. For remote or shared servers, it's the streamable HTTP transport.
Quelle est LA différence clé entre un serveur MCP et du function calling codé dans une app ? What is THE key difference between an MCP server and function calling coded into an app?
C'est la standardisation qui change tout : découverte dynamique, transport commun, réutilisabilité entre apps. MCP n'améliore pas le raisonnement du modèle, et un serveur MCP wrappe généralement une API existante. Standardization is what changes everything: dynamic discovery, common transport, reusability across apps. MCP doesn't improve the model's reasoning, and an MCP server usually wraps an existing API.
Un serveur MCP de lecture d'emails + un outil d'envoi de messages + accès à des documents privés. Quel est le risque principal ? An email-reading MCP server + a message-sending tool + access to private documents. What is the main risk?
C'est le trio dangereux : contenu non fiable (emails entrants) + données privées + canal de sortie (envoi). Un email piégé contenant des instructions peut détourner le modèle. Parades : moindre privilège et approbation humaine des envois. That's the dangerous trio: untrusted content (incoming emails) + private data + an output channel (sending). A booby-trapped email containing instructions can hijack the model. Countermeasures: least privilege and human approval of sends.
Pourquoi éviter de brancher 15 serveurs MCP « au cas où » ? Why avoid plugging in 15 MCP servers "just in case"?
Les définitions d'outils s'ajoutent au contexte à chaque requête, et un choix parmi 50 outils est moins fiable qu'un choix parmi 5. Pas de limite protocolaire ni de « port stdio » : c'est un arbitrage coût/pertinence. Tool definitions are added to the context on every request, and choosing among 50 tools is less reliable than among 5. No protocol limit and no "stdio port": it's a cost/relevance trade-off.
Actu News Claude signe désormais tout ce qu'il écrit : le filigrane invisible débarque dans vos copier-coller Claude now signs everything it writes: invisible watermarks land in your copy-paste
Flashcards Flashcards
Comment fonctionne le filigrane invisible qu'Anthropic a annoncé le 11 août 2026 pour le texte de Claude ? How does the invisible watermark Anthropic announced on August 11, 2026 for Claude's text work?
Le modèle biaise légèrement ses choix de mots selon une clé secrète : indétectable sur un mot, le motif ressort d'une analyse statistique sur quelques centaines de mots. La marque voyage avec le copier-coller et survit à des retouches légères, mais s'efface sous une réécriture lourde. Pour les fichiers, Anthropic ajoute des métadonnées de provenance signées au standard C2PA. The model slightly biases its word choices using a secret key: undetectable on one word, the pattern emerges from statistical analysis over a few hundred words. The mark travels with copy-paste and survives light edits, but fades under heavy rewriting. For files, Anthropic adds signed provenance metadata using the C2PA standard.
Quelle différence entre un filigrane, une provenance C2PA et un détecteur d'IA ? What is the difference between a watermark, C2PA provenance and an AI detector?
Le filigrane est posé à la source par le fournisseur du modèle, avec une clé, et se vérifie statistiquement. La provenance C2PA est une signature cryptographique attachée au fichier, qui disparaît si on recopie le contenu ailleurs. Le détecteur (type GPTZero) devine après coup à partir de la perplexité et du style, avec des faux positifs documentés. Seuls les deux premiers relèvent de la provenance, le troisième de la stylométrie. A watermark is placed at the source by the model provider, with a key, and is verified statistically. C2PA provenance is a cryptographic signature attached to the file, which disappears if the content is copied elsewhere. A detector (like GPTZero) guesses after the fact from perplexity and style, with documented false positives. Only the first two are provenance; the third is stylometry.
Qu'impose l'article 50 du règlement européen sur l'IA, applicable depuis le 2 août 2026 ? What does Article 50 of the EU AI Act, applicable since August 2, 2026, require?
La transparence : informer l'utilisateur qu'il interagit avec une IA, et marquer les contenus synthétiques (texte, image, audio, vidéo) dans un format lisible par machine et détectable. Sanctions jusqu'à 15 millions d'euros ou 3 % du chiffre d'affaires mondial, le plus élevé des deux. Les systèmes déjà sur le marché ont jusqu'au 2 décembre 2026 pour se conformer au marquage. Transparency: tell users they are interacting with an AI, and mark synthetic content (text, image, audio, video) in a machine-readable and detectable format. Penalties up to 15 million euros or 3% of worldwide annual turnover, whichever is higher. Systems already on the market have until December 2, 2026 to meet the marking requirement.
Pourquoi une estimation de coût d'une feature IA doit-elle porter une date ? Why should a cost estimate for an AI feature carry a date?
Parce que les tarifs bougent vite et dans les deux sens. Exemple de la semaine : Gemini 3.7 Flash est facturé 0,75 $ / 3,75 $ le million de tokens jusqu'au 31 décembre 2026, puis le prix double au 1er janvier 2027. Un budget calculé sur le tarif de lancement peut être faux six mois plus tard. Because prices move fast, and in both directions. This week's example: Gemini 3.7 Flash is billed at $0.75 / $3.75 per million tokens through December 31, 2026, then the price doubles on January 1, 2027. A budget built on the launch price can be wrong six months later.
QCM Quiz
Que devient le filigrane de Claude quand on copie-colle son texte dans un autre document ? What happens to Claude's watermark when you copy-paste its text into another document?
Le filigrane textuel est encodé dans le choix des mots lui-même, donc il suit le texte partout. Ce sont les métadonnées C2PA, utilisées pour les fichiers, qui disparaissent quand on recopie le contenu ailleurs. The text watermark is encoded in the word choices themselves, so it follows the text anywhere. It is the C2PA metadata, used for files, that disappears when content is copied elsewhere.
Quelle réglementation a poussé Anthropic à marquer le texte généré par Claude ? Which regulation pushed Anthropic to watermark Claude's generated text?
L'article 50 du règlement européen sur l'IA est applicable depuis le 2 août 2026 : les sorties des systèmes génératifs doivent être marquées dans un format lisible par machine et détectables comme générées par une IA, sous peine de 15 M€ ou 3 % du CA mondial. Article 50 of the EU AI Act applies as of August 2, 2026: generative systems' outputs must be marked in a machine-readable format and detectable as AI-generated, on pain of 15M euros or 3% of worldwide turnover.
Quel point commun entre les failles TeamCity (CVE-2026-63077) et IBM Langflow (CVE-2026-9198) de la semaine du 10 août 2026 ? What do the TeamCity (CVE-2026-63077) and IBM Langflow (CVE-2026-9198) flaws of the week of August 10, 2026 have in common?
Les deux permettent d'exécuter du code à distance sans aucune authentification, et étaient exploitées dans la nature. La cible est l'outillage interne (CI, plateformes de dev), qui donne accès aux secrets de build : il doit être protégé comme la production. Both allow remote code execution with no authentication at all, and were exploited in the wild. The target is internal tooling (CI, dev platforms), which holds build secrets: it must be protected like production.
Jour 13 Day 13 Kubernetes : l'orchestration expliquée Kubernetes: orchestration explained
Flashcards Flashcards
Qu'apporte Kubernetes par rapport à Docker Compose ? What does Kubernetes bring over Docker Compose?
Compose démarre une stack sur une seule machine. K8s ajoute le multi-machines, la boucle de réconciliation (self-healing automatique), le scaling déclaratif, les rolling updates avec rollback, et le service discovery/load balancing intégrés — au prix d'une complexité opérationnelle bien supérieure. Compose starts a stack on a single machine. K8s adds multi-machine support, the reconciliation loop (automatic self-healing), declarative scaling, rolling updates with rollback, and built-in service discovery/load balancing — at the cost of far greater operational complexity.
Quels sont les composants du control plane et leur rôle ? What are the control plane components and their roles?
kube-apiserver (point d'entrée unique, valide et persiste les objets), etcd (base clé-valeur stockant tout l'état du cluster), kube-scheduler (choisit le node de chaque nouveau Pod), controller manager (fait tourner les boucles de réconciliation). kube-apiserver (single entry point, validates and persists objects), etcd (key-value store holding the entire cluster state), kube-scheduler (picks the node for each new Pod), controller manager (runs the reconciliation loops).
Que font kubelet et kube-proxy sur un worker node ? What do kubelet and kube-proxy do on a worker node?
kubelet surveille l'API server, lance les conteneurs des Pods assignés au node via le container runtime (containerd) et remonte leur état. kube-proxy programme les règles réseau (iptables/IPVS) pour que les Services routent vers les bons Pods. kubelet watches the API server, starts the containers of Pods assigned to the node through the container runtime (containerd) and reports their status. kube-proxy programs the network rules (iptables/IPVS) so Services route to the right Pods.
Explique la chaîne Deployment → ReplicaSet → Pod. Explain the Deployment → ReplicaSet → Pod chain.
Le Deployment gère les versions et les rolling updates (nouveau ReplicaSet monté progressivement, ancien descendu, rollback possible). Le ReplicaSet maintient le nombre de réplicas demandé. Le Pod est la plus petite unité : un ou plusieurs conteneurs partageant IP et volumes, éphémère par conception. The Deployment manages versions and rolling updates (new ReplicaSet scaled up progressively, old one scaled down, rollback possible). The ReplicaSet maintains the requested replica count. The Pod is the smallest unit: one or more containers sharing IP and volumes, ephemeral by design.
Quels sont les trois types de Service principaux et leurs usages ? What are the three main Service types and their uses?
ClusterIP : IP virtuelle interne au cluster (le défaut, pour le trafic entre services). NodePort : ouvre un port sur chaque node (tests, on-prem sans LB). LoadBalancer : provisionne un load balancer cloud avec IP publique — en pratique un seul, devant un Ingress qui route vers N services ClusterIP. ClusterIP: cluster-internal virtual IP (the default, for service-to-service traffic). NodePort: opens a port on every node (testing, on-prem without a LB). LoadBalancer: provisions a cloud load balancer with a public IP — in practice just one, in front of an Ingress routing to N ClusterIP services.
Liveness vs readiness probe : quelle différence et quel piège ? Liveness vs readiness probe: what's the difference and the trap?
Liveness : le process est-il vivant ? Échec → restart du conteneur. Readiness : peut-il recevoir du trafic ? Échec → retiré des endpoints du Service, sans restart. Piège : tester une dépendance externe (DB) dans la liveness → restarts en boucle quand la dépendance a un souci. Liveness: is the process alive? Failure → container restart. Readiness: can it receive traffic? Failure → removed from the Service's endpoints, no restart. Trap: testing an external dependency (DB) in the liveness probe → restart loops whenever the dependency has an issue.
À quoi servent requests et limits ? What are requests and limits for?
requests = ressources garanties, utilisées par le scheduler pour placer le Pod. limits = plafond : CPU throttlé au-delà, dépassement mémoire → OOMKilled. Sans requests le scheduling est aveugle ; sans limits un Pod peut affamer le node. requests = guaranteed resources, used by the scheduler to place the Pod. limits = ceiling: CPU is throttled beyond it, exceeding memory → OOMKilled. Without requests scheduling is blind; without limits one Pod can starve the node.
Quand Kubernetes est-il overkill ? When is Kubernetes overkill?
Pour un projet à un ou deux services sur un seul serveur : un VPS avec Docker Compose ou un PaaS suffit, avec une fraction de la complexité. K8s se justifie avec plusieurs machines, des besoins réels de scaling/haute dispo, et une équipe capable de l'opérer. For a project with one or two services on a single server: a VPS with Docker Compose or a PaaS is enough, at a fraction of the complexity. K8s is justified with multiple machines, real scaling/high-availability needs, and a team able to operate it.
QCM Quiz
Où est stocké tout l'état du cluster Kubernetes ? Where is the entire Kubernetes cluster state stored?
etcd est la base clé-valeur distribuée du control plane : tous les objets (Deployments, Services, Secrets…) y sont persistés via l'API server. La perdre sans backup, c'est perdre le cluster. etcd is the control plane's distributed key-value store: every object (Deployments, Services, Secrets…) is persisted there through the API server. Losing it without a backup means losing the cluster.
Un Pod crashe. Qui le recrée ? A Pod crashes. Who recreates it?
Le ReplicaSet controller compare en permanence réplicas observés et désirés : 2 au lieu de 3 → il crée un Pod. Le scheduler intervient ensuite seulement pour placer ce nouveau Pod sur un node. The ReplicaSet controller continuously compares observed and desired replicas: 2 instead of 3 → it creates a Pod. The scheduler only steps in afterwards to place that new Pod on a node.
Pourquoi les Secrets Kubernetes ne sont-ils pas sécurisés par défaut ? Why aren't Kubernetes Secrets secure by default?
base64 est un encodage réversible en une commande, pas du chiffrement. Il faut activer l'encryption at rest d'etcd, restreindre l'accès par RBAC, et idéalement utiliser un gestionnaire externe (Vault, secrets du cloud). base64 is an encoding reversible in one command, not encryption. You need etcd encryption at rest, RBAC-restricted access, and ideally an external manager (Vault, cloud secrets).
Que se passe-t-il quand un conteneur dépasse sa limit mémoire ? What happens when a container exceeds its memory limit?
Contrairement au CPU (compressible, donc throttlé), la mémoire ne se throttle pas : dépassement = OOMKilled par le noyau, puis restart selon la restartPolicy. D'où l'importance de dimensionner les limits avec de vraies mesures. Unlike CPU (compressible, therefore throttled), memory can't be throttled: exceeding it = OOMKilled by the kernel, then restarted per the restartPolicy. Hence the importance of sizing limits from real measurements.
Quel objet permet de router api.exemple.com et www.exemple.com vers deux services différents avec une seule IP publique ? Which object routes api.example.com and www.example.com to two different services with a single public IP?
L'Ingress fait du routage HTTP par host/path et de la terminaison TLS derrière un seul point d'entrée. Deux LoadBalancer fonctionneraient mais coûteraient une IP publique chacun. The Ingress does HTTP host/path routing and TLS termination behind a single entry point. Two LoadBalancers would work but would each cost a public IP.
Une readiness probe échoue sur un Pod. Que fait Kubernetes ? A readiness probe fails on a Pod. What does Kubernetes do?
Readiness = aptitude à recevoir du trafic : en échec, le Pod est simplement sorti du load balancing jusqu'à ce que la probe repasse au vert. C'est la liveness qui déclenche un restart. Readiness = ability to receive traffic: on failure, the Pod is simply pulled out of load balancing until the probe goes green again. It's the liveness probe that triggers a restart.
Jour 12 Day 12 TypeScript : le typage qui change tout TypeScript: typing that changes everything
Flashcards Flashcards
Que devient le typage TypeScript à l'exécution ? What happens to TypeScript's typing at runtime?
Il disparaît entièrement : `tsc` efface les annotations et émet du JavaScript pur. La vérification est uniquement statique — aucune donnée n'est validée au runtime, d'où le besoin de validation aux frontières (zod) pour les entrées externes. It disappears entirely: `tsc` erases the annotations and emits plain JavaScript. Checking is static only — no data is validated at runtime, hence the need for boundary validation (zod) on external input.
Qu'est-ce que le typage structurel de TypeScript ? What is TypeScript's structural typing?
Deux types sont compatibles si leurs structures le sont, peu importe leur nom (duck typing vérifié statiquement). Un objet avec les bonnes propriétés est assignable à une interface même s'il n'a jamais été déclaré comme telle — contrairement au typage nominal de Java/C#. Two types are compatible if their structures are, regardless of their names (statically checked duck typing). An object with the right properties is assignable to an interface even if it was never declared as one — unlike Java/C#'s nominal typing.
Quelle est la différence entre `any` et `unknown` ? What's the difference between `any` and `unknown`?
`any` désactive toute vérification et se propage à tout ce qu'il touche. `unknown` accepte n'importe quelle valeur mais interdit tout usage tant qu'on n'a pas rétréci le type (typeof, type guard, validation). Aux frontières : `unknown`, jamais `any`. `any` disables all checking and spreads to everything it touches. `unknown` accepts any value but forbids any use until the type has been narrowed (typeof, type guard, validation). At the boundaries: `unknown`, never `any`.
Qu'est-ce que le narrowing ? What is narrowing?
Le rétrécissement d'un type union au fil du contrôle de flot : après `if (typeof x === "string")`, `x` est un `string` dans la branche. Outils : `typeof`, `instanceof`, `in`, champ discriminant d'une discriminated union, type guards personnalisés (`x is User`). Shrinking a union type through control flow: after `if (typeof x === "string")`, `x` is a `string` inside the branch. Tools: `typeof`, `instanceof`, `in`, the discriminant field of a discriminated union, custom type guards (`x is User`).
Interface vs type : quand utiliser quoi ? Interface vs type: when to use which?
Quasi interchangeables pour un objet. `interface` : declaration merging et `extends`, bien pour les formes d'objets publiques. `type` : unions, intersections, tuples, mapped types. Le choix relève surtout de la convention d'équipe. Nearly interchangeable for an object. `interface`: declaration merging and `extends`, good for public object shapes. `type`: unions, intersections, tuples, mapped types. The choice is mostly team convention.
Donne un exemple de générique avec contrainte et explique ce qu'il garantit. Give an example of a constrained generic and explain what it guarantees.
`function getProp<T, K extends keyof T>(obj: T, key: K): T[K]` : `K` doit être une clé existante de `T`, donc demander une propriété inexistante est une erreur de compilation, et le type de retour est exactement celui de la propriété demandée. `function getProp<T, K extends keyof T>(obj: T, key: K): T[K]`: `K` must be an existing key of `T`, so asking for a nonexistent property is a compile error, and the return type is exactly that of the requested property.
Cite quatre utility types et leur usage typique. Name four utility types and their typical use.
`Partial<T>` : tout optionnel (payload PATCH). `Pick<T, K>` : ne garder que certaines clés. `Omit<T, K>` : tout sauf certaines clés (DTO sans `password`). `Record<K, V>` : dictionnaire typé (`Record<string, number>`). `Partial<T>`: everything optional (PATCH payload). `Pick<T, K>`: keep only certain keys. `Omit<T, K>`: everything except certain keys (DTO without `password`). `Record<K, V>`: typed dictionary (`Record<string, number>`).
Pourquoi valider une réponse d'API avec zod alors qu'elle est déjà typée ? Why validate an API response with zod when it's already typed?
Parce que le type est une annotation de compilation, pas une garantie : le serveur peut renvoyer n'importe quoi. `schema.parse(data)` valide réellement au runtime, et `z.infer<typeof schema>` dérive le type statique du schéma — une seule source de vérité pour les deux niveaux. Because the type is a compile-time annotation, not a guarantee: the server can return anything. `schema.parse(data)` actually validates at runtime, and `z.infer<typeof schema>` derives the static type from the schema — one source of truth for both levels.
QCM Quiz
Quel est le principal danger de `any` ? What is the main danger of `any`?
`any` court-circuite le compilateur silencieusement et contamine la chaîne d'appels. Aucun impact runtime : les types sont effacés. `noImplicitAny` (strict mode) aide à le traquer. `any` silently bypasses the compiler and contaminates the call chain. No runtime impact: types are erased. `noImplicitAny` (strict mode) helps track it down.
Pourquoi un objet `{ name: "Ana", age: 30 }` est-il assignable à `interface Person { name: string }` ? Why is an object `{ name: "Ana", age: 30 }` assignable to `interface Person { name: string }`?
Typage structurel : la compatibilité se juge sur la forme, pas sur une déclaration `implements`. Nuance : un littéral d'objet passé directement subit l'excess property check, qui refuse les propriétés inconnues. Structural typing: compatibility is judged on shape, not on an `implements` declaration. Nuance: an object literal passed directly triggers the excess property check, which rejects unknown properties.
Que fait `strictNullChecks` ? What does `strictNullChecks` do?
Sans strictNullChecks, `null`/`undefined` sont assignables partout et les erreurs "cannot read property of undefined" passent. Avec, un `string | null` force le narrowing avant usage. Aucune vérification runtime : tout est statique. Without strictNullChecks, `null`/`undefined` are assignable everywhere and "cannot read property of undefined" errors slip through. With it, a `string | null` forces narrowing before use. No runtime checks: it's all static.
Quel utility type pour un DTO utilisateur sans le champ password ? Which utility type for a user DTO without the password field?
`Omit` retire des clés d'un type. `Pick<User, "password">` ferait l'inverse (ne garder que password), `Partial` rendrait tout optionnel sans rien retirer, et `Record` construit un dictionnaire. `Omit` removes keys from a type. `Pick<User, "password">` would do the opposite (keep only password), `Partial` would make everything optional without removing anything, and `Record` builds a dictionary.
Que signifie `data as User` sur une réponse d'API ? What does `data as User` mean on an API response?
`as` ne convertit ni ne valide rien : c'est une promesse faite au compilateur. Si le serveur renvoie autre chose, le bug explosera plus loin. La validation réelle passe par un schéma runtime comme zod. `as` neither converts nor validates anything: it's a promise made to the compiler. If the server returns something else, the bug blows up later. Real validation goes through a runtime schema like zod.
Après `if (typeof x === "string")` sur un `x: string | number`, quel est le type de x dans la branche else ? After `if (typeof x === "string")` on an `x: string | number`, what is the type of x in the else branch?
Le narrowing fonctionne dans les deux sens : la branche if élimine `number`, donc la branche else élimine `string`. Le compilateur suit le contrôle de flot pour rétrécir l'union des deux côtés. Narrowing works both ways: the if branch eliminates `number`, so the else branch eliminates `string`. The compiler follows control flow to shrink the union on both sides.
Jour 11 Day 11 Microservices vs monolithe Microservices vs monolith
Flashcards Flashcards
Pourquoi le monolithe est-il souvent le bon choix en début de projet ? Why is the monolith often the right choice early in a project?
Un appel de fonction est infiniment plus simple qu'un appel réseau : pas de latence ni de panne partielle, une transaction ACID couvre tout, un seul déploiement, une stack trace pour debugger. En début de projet, la vitesse d'itération prime et les frontières de domaines sont encore inconnues — les microservices les figeraient trop tôt. A function call is infinitely simpler than a network call: no latency or partial failure, one ACID transaction covers everything, one deployment, one stack trace for debugging. Early on, iteration speed rules and domain boundaries are still unknown — microservices would freeze them too early.
Qu'est-ce qu'un monolithe modulaire ? What is a modular monolith?
Un seul déployable, mais des modules internes aux frontières nettes : chaque module n'est accessible que par son interface publique (billing ne touche pas aux tables de users). On garde la simplicité opérationnelle du monolithe tout en préparant une éventuelle extraction future — un déménagement plutôt qu'une réécriture. A single deployable, but internal modules with clean boundaries: each module is only reachable through its public interface (billing never touches users' tables). You keep the monolith's operational simplicity while preparing a possible future extraction — a move rather than a rewrite.
Quelles sont les trois vraies promesses des microservices ? What are the three real promises of microservices?
1) Déploiement indépendant : chaque équipe déploie sans attendre les autres — la promesse centrale. 2) Scaling ciblé : répliquer un seul service sous charge (surtout utile pour des besoins asymétriques : GPU, mémoire, langage). 3) Ownership d'équipe : chaque équipe possède ses services de bout en bout — la loi de Conway appliquée volontairement. 1) Independent deployment: each team deploys without waiting for the others — the central promise. 2) Targeted scaling: replicating one service under load (mostly useful for asymmetric needs: GPU, memory, language). 3) Team ownership: each team owns its services end to end — Conway's law applied deliberately.
Qu'est-ce qu'un distributed monolith ? What is a distributed monolith?
L'anti-pattern n°1 : des services séparés par le réseau mais couplés au point de devoir se déployer ensemble (base partagée, API fragiles, chaînes d'appels synchrones). On paie tous les coûts du distribué — latence, pannes partielles, complexité ops — sans le bénéfice central du déploiement indépendant. The number one anti-pattern: services separated by the network but so coupled they must deploy together (shared database, fragile APIs, chains of synchronous calls). You pay every cost of distribution — latency, partial failures, ops complexity — without the central benefit of independent deployment.
Pourquoi le pattern database-per-service est-il une condition de l'indépendance ? Why is the database-per-service pattern a condition for independence?
Deux services qui partagent une base sont couplés par le schéma : un ALTER TABLE de l'un casse l'autre, et les déploiements redeviennent coordonnés. Chaque service possède sa base ; les autres n'y accèdent que via son API. Le prix : plus de JOIN cross-services ni de transaction ACID globale. Two services sharing a database are coupled through the schema: one's ALTER TABLE breaks the other, and deployments become coordinated again. Each service owns its database; others only access it through its API. The price: no more cross-service JOINs or global ACID transactions.
Explique le pattern saga en deux phrases. Explain the saga pattern in two sentences.
Une saga remplace la transaction distribuée impossible par une séquence de transactions locales, une par service. Si une étape échoue, des transactions de compensation défont les étapes précédentes (annuler la réservation, rembourser le paiement) — orchestrées par un coordinateur ou chorégraphiées par une chaîne d'événements. A saga replaces the impossible distributed transaction with a sequence of local transactions, one per service. If a step fails, compensating transactions undo the previous steps (cancel the reservation, refund the payment) — orchestrated by a coordinator or choreographed through a chain of events.
Communication synchrone vs asynchrone entre services : les compromis ? Synchronous vs asynchronous communication between services: the trade-offs?
Synchrone (REST, gRPC) : simple à raisonner, réponse immédiate, mais couplage temporel — les latences s'additionnent et les pannes se propagent en cascade. Asynchrone (événements via Kafka/RabbitMQ) : découplage, absorption des pics, mais cohérence à terme et debugging plus difficile. Règle pratique : synchrone pour les queries client, asynchrone entre services quand c'est possible. Synchronous (REST, gRPC): easy to reason about, immediate answer, but temporal coupling — latencies add up and failures cascade. Asynchronous (events via Kafka/RabbitMQ): decoupling, burst absorption, but eventual consistency and harder debugging. Practical rule: synchronous for client-facing queries, asynchronous between services whenever possible.
Qu'est-ce que la stratégie strangler fig ? What is the strangler fig strategy?
La migration progressive d'un monolithe : on extrait une capacité à la fois, un proxy ou une gateway route progressivement le trafic vers le nouveau service, et le monolithe rétrécit petit à petit. À l'opposé du big bang rewrite. Chaque extraction doit se justifier seule — commencer par le meilleur ratio douleur/risque. Progressive migration of a monolith: extract one capability at a time, a proxy or gateway gradually routes traffic to the new service, and the monolith shrinks bit by bit. The opposite of a big-bang rewrite. Each extraction must justify itself — start with the best pain-to-risk ratio.
QCM Quiz
Quelle est la promesse CENTRALE des microservices, celle sans laquelle le découpage perd son sens ? What is the CENTRAL promise of microservices, without which the split loses its meaning?
Si les services doivent se déployer ensemble, on a un distributed monolith. Le réseau dégrade les performances (latence), il ne les améliore pas, et le code total augmente (gestion des pannes, sérialisation, ops). If services must deploy together, you have a distributed monolith. The network degrades performance (latency), it doesn't improve it, and total code increases (failure handling, serialization, ops).
Une équipe de 3 développeurs lance un produit avec 8 microservices. Quel est le problème principal ? A 3-developer team launches a product with 8 microservices. What is the main problem?
Trois devs n'ont pas de problème de coordination inter-équipes à résoudre : ils héritent du réseau, de l'observabilité et des N pipelines sans aucun gain de déploiement indépendant. Un monolithe modulaire irait plus vite. Three devs have no inter-team coordination problem to solve: they inherit the network, observability and N pipelines with zero independent-deployment gain. A modular monolith would move faster.
Deux microservices lisent et écrivent directement dans la même base PostgreSQL. Quelle en est la conséquence ? Two microservices read and write directly to the same PostgreSQL database. What is the consequence?
C'est le chemin le plus court vers le distributed monolith : le schéma devient une API implicite entre les deux services. Database-per-service existe précisément pour préserver le déploiement indépendant. (Au contraire, la base partagée PERMET les transactions ACID communes — c'est l'indépendance qu'elle détruit.) It's the shortest road to the distributed monolith: the schema becomes an implicit API between the two services. Database-per-service exists precisely to preserve independent deployment. (If anything, a shared database ENABLES common ACID transactions — what it destroys is independence.)
Dans une saga, que se passe-t-il quand une étape intermédiaire échoue ? In a saga, what happens when an intermediate step fails?
Il n'existe pas de rollback global : chaque transaction locale est déjà commitée dans sa base. La saga définit donc pour chaque étape une compensation métier (annuler la réservation, rembourser) exécutée en cas d'échec en aval. There is no global rollback: each local transaction is already committed in its own database. The saga therefore defines a business compensation for each step (cancel the reservation, refund) executed when a later step fails.
Quel symptôme indique le mieux qu'il est temps d'envisager d'extraire des services d'un monolithe ? Which symptom best indicates it's time to consider extracting services from a monolith?
Le signal pertinent est organisationnel (loi de Conway) : des équipes couplées par le déployable unique. La taille du code ou de la base ne dit rien en soi, et la mode des concurrents encore moins. La douleur d'abord, le découpage ensuite — via strangler fig. The relevant signal is organizational (Conway's law): teams coupled by the single deployable. Code or database size says nothing by itself, and competitors' fashion even less. Pain first, split second — via strangler fig.
Quel est le rôle d'une API gateway dans une architecture microservices ? What is the role of an API gateway in a microservices architecture?
La gateway découple les clients de la topologie interne : ils appellent un point unique qui route, authentifie, limite le débit et agrège. Elle ne gère ni transactions (saga), ni schémas (database-per-service), ni messaging (broker). The gateway decouples clients from the internal topology: they call a single point that routes, authenticates, rate-limits and aggregates. It handles neither transactions (saga), nor schemas (database-per-service), nor messaging (broker).
Jour 10 Day 10 Tester son code : de l'unitaire au E2E Testing your code: from unit to E2E
Flashcards Flashcards
Décris la pyramide de tests et sa logique. Describe the test pyramid and its logic.
Beaucoup de tests unitaires (rapides, isolés, précis dans leur diagnostic), moins de tests d'intégration (plusieurs composants avec de vraies dépendances), très peu de E2E (l'application pilotée comme un utilisateur). Plus on monte, plus le test est réaliste mais lent, cher à maintenir et vague quand il échoue. Many unit tests (fast, isolated, precise in their diagnosis), fewer integration tests (several components with real dependencies), very few E2E tests (the app driven like a user). The higher you climb, the more realistic the test but the slower, more expensive to maintain and vaguer when it fails.
Qu'est-ce que le pattern AAA dans un test unitaire ? What is the AAA pattern in a unit test?
Arrange : préparer les données et l'objet testé. Act : appeler la fonction testée. Assert : vérifier le résultat observable. Cette structure en trois blocs rend le test lisible et garantit qu'il vérifie un comportement précis, avec idéalement une seule raison d'échouer. Arrange: prepare the data and the object under test. Act: call the function being tested. Assert: verify the observable result. This three-block structure keeps the test readable and ensures it verifies one precise behavior, ideally with a single reason to fail.
Différencie stub, mock, spy et fake. Differentiate stub, mock, spy and fake.
Stub : renvoie des réponses préprogrammées (fournit un état au test). Mock : porte des attentes sur les interactions, le test échoue si l'appel attendu ne se produit pas (vérifie un comportement). Spy : enregistre les appels reçus sans changer le comportement. Fake : implémentation réelle mais simplifiée, comme un repository en mémoire. Stub: returns pre-programmed answers (provides state to the test). Mock: carries expectations about interactions, the test fails if the expected call doesn't happen (verifies behavior). Spy: records received calls without changing behavior. Fake: a real but simplified implementation, like an in-memory repository.
Qu'est-ce que le cycle TDD et qu'apporte-t-il concrètement ? What is the TDD cycle and what does it concretely bring?
Red : écrire un test qui échoue. Green : écrire le code minimal qui le fait passer. Refactor : nettoyer avec les tests au vert. Apports : l'API se conçoit du point de vue de l'appelant, le code est testable par construction, et chaque refactoring est protégé par le filet de tests existant. Red: write a failing test. Green: write the minimal code that makes it pass. Refactor: clean up with tests green. Benefits: the API is designed from the caller's point of view, the code is testable by construction, and every refactoring is protected by the existing safety net.
Pourquoi un test unitaire doit-il être déterministe, et quels sont les ennemis classiques ? Why must a unit test be deterministic, and what are the classic enemies?
Un test non déterministe (flaky) détruit la confiance dans la suite : on relance sans lire, un vrai bug finit par passer. Ennemis classiques : Date.now() et l'horloge, Math.random(), les timeouts et sleeps, l'ordre d'itération non garanti, les dépendances entre tests. Solution : injecter le temps et l'aléa comme des dépendances. A non-deterministic (flaky) test destroys trust in the suite: people re-run without reading, and a real bug eventually slips through. Classic enemies: Date.now() and the clock, Math.random(), timeouts and sleeps, unspecified iteration order, inter-test dependencies. Solution: inject time and randomness as dependencies.
À quoi sert Testcontainers ? What is Testcontainers for?
À lancer de vraies dépendances (Postgres, Redis, Kafka…) dans des conteneurs Docker jetables le temps d'une suite de tests d'intégration. On teste les vraies requêtes SQL, contraintes et transactions au lieu de mocker le driver — quelques secondes de démarrage contre un réalisme incomparable. Starting real dependencies (Postgres, Redis, Kafka…) in throwaway Docker containers for the duration of an integration test suite. You test real SQL queries, constraints and transactions instead of mocking the driver — a few seconds of startup for incomparable realism.
Pourquoi la couverture de code est-elle une métrique piégeuse ? Why is code coverage a treacherous metric?
Elle mesure les lignes exécutées, pas les comportements vérifiés : un test sans assertion donne 100 % de couverture et 0 % de valeur. Loi de Goodhart : en cible, elle pousse à écrire des tests pour couvrir plutôt que pour vérifier. Utile en tendance et pour repérer les zones mortes ; le mutation testing mesure mieux la qualité des assertions. It measures executed lines, not verified behaviors: an assertion-free test yields 100% coverage and 0% value. Goodhart's law: as a target, it pushes people to write tests to cover rather than to verify. Useful as a trend and to spot dead zones; mutation testing measures assertion quality better.
Comment réduire la flakiness des tests E2E ? How do you reduce E2E test flakiness?
Attendre des conditions, jamais des durées (auto-waiting de Playwright, attentes explicites sur l'état) ; isoler les données de chaque test ; utiliser des sélecteurs stables (data-testid plutôt que des classes CSS) ; limiter le E2E aux parcours critiques. Un sleep(2000) est presque toujours un futur test flaky. Wait for conditions, never durations (Playwright's auto-waiting, explicit waits on state); isolate each test's data; use stable selectors (data-testid rather than CSS classes); limit E2E to critical journeys. A sleep(2000) is almost always a future flaky test.
QCM Quiz
Quelle est la différence fondamentale entre un mock et un stub ? What is the fundamental difference between a mock and a stub?
Stub = état (alimenter le test en données), mock = comportement (le test échoue si l'appel attendu manque). La « vraie implémentation simplifiée », c'est le fake. Stub = state (feeding the test data), mock = behavior (the test fails if the expected call is missing). The "real simplified implementation" is the fake.
Dans le cycle TDD, que signifie l'étape « red » ? In the TDD cycle, what does the "red" step mean?
Red-green-refactor : le test écrit avant le code doit échouer — sinon il ne prouve rien. On écrit ensuite le code minimal qui le fait passer (green), puis on nettoie (refactor). Red-green-refactor: the test written before the code must fail — otherwise it proves nothing. Then you write the minimal code to pass it (green), then clean up (refactor).
Un refactoring interne (sans changement de comportement) casse 15 tests unitaires. Qu'est-ce que ça révèle ? An internal refactoring (no behavior change) breaks 15 unit tests. What does that reveal?
Si le comportement observable n'a pas changé, des tests qui cassent testaient le « comment » (appels internes, état privé) et non le « quoi ». Symptôme fréquent de l'abus de mocks — en ajouter aggraverait le problème. If observable behavior hasn't changed, breaking tests were testing the "how" (internal calls, private state) rather than the "what". A frequent symptom of mock overuse — adding more would make it worse.
Pour tester une requête SQL complexe avec jointures et contraintes, quelle approche est la plus fiable ? To test a complex SQL query with joins and constraints, which approach is most reliable?
Mocker le driver ou stubber les résultats teste votre imagination : le test passe même si la requête est fausse. Un vrai Postgres jetable valide la syntaxe, les jointures et les contraintes. Le E2E le ferait aussi, mais lentement et avec un diagnostic vague. Mocking the driver or stubbing results tests your imagination: the test passes even if the query is wrong. A real throwaway Postgres validates syntax, joins and constraints. E2E would too, but slowly and with vague diagnosis.
Pourquoi un test sans assertion est-il dangereux ? Why is an assertion-free test dangerous?
Exécuter du code n'est pas le vérifier : le test passe toujours, la couverture monte, et l'équipe croit la zone testée. C'est le cœur du piège de la couverture comme objectif. Executing code is not verifying it: the test always passes, coverage rises, and the team believes the area is tested. That's the heart of the coverage-as-target trap.
Quel remplacement corrige le mieux un `sleep(2000)` dans un test Playwright flaky ? Which replacement best fixes a `sleep(2000)` in a flaky Playwright test?
Une durée fixe est soit trop courte (flaky) soit trop longue (suite lente) — et souvent les deux selon la machine. On attend l'état attendu : Playwright fait ce polling nativement via ses assertions et son auto-waiting. Le retry masque le problème. A fixed duration is either too short (flaky) or too long (slow suite) — often both depending on the machine. Wait for the expected state: Playwright polls natively through its assertions and auto-waiting. Retries mask the problem.
Jour 9 Day 9 WebSockets & le temps réel WebSockets & real-time
Flashcards Flashcards
Quelle limite fondamentale de HTTP les WebSockets résolvent-elles ? What fundamental HTTP limitation do WebSockets solve?
HTTP est requête/réponse : le serveur ne peut pas envoyer de données de sa propre initiative. Le WebSocket établit une connexion TCP persistante et full-duplex : les deux côtés émettent quand ils veulent, avec quelques octets d'overhead par message. HTTP is request/response: the server cannot send data on its own initiative. WebSocket establishes a persistent, full-duplex TCP connection: both sides send whenever they want, with a few bytes of overhead per message.
Décris le handshake WebSocket. Describe the WebSocket handshake.
Le client envoie un GET HTTP avec `Upgrade: websocket`, `Connection: Upgrade` et un nonce `Sec-WebSocket-Key`. Le serveur répond `101 Switching Protocols` avec `Sec-WebSocket-Accept` (SHA-1 du nonce + GUID fixe). La connexion TCP est ensuite réutilisée pour des frames full-duplex. Démarrer en HTTP permet de traverser les proxies et de partager le port 443. The client sends an HTTP GET with `Upgrade: websocket`, `Connection: Upgrade` and a `Sec-WebSocket-Key` nonce. The server answers `101 Switching Protocols` with `Sec-WebSocket-Accept` (SHA-1 of the nonce + a fixed GUID). The TCP connection is then reused for full-duplex frames. Starting as HTTP gets through proxies and shares port 443.
Compare short polling, long polling et SSE. Compare short polling, long polling and SSE.
Short polling : requête toutes les X secondes, simple mais latence moyenne X/2 et requêtes vides. Long polling : le serveur garde la requête ouverte jusqu'à avoir une donnée, latence quasi nulle mais une reconnexion par message. SSE : flux HTTP `text/event-stream` unidirectionnel serveur → client, avec reconnexion automatique native via EventSource — souvent suffisant pour notifications et dashboards. Short polling: a request every X seconds, simple but average latency of X/2 and empty requests. Long polling: the server holds the request open until it has data, near-zero latency but one reconnection per message. SSE: a unidirectional server → client `text/event-stream` HTTP flow, with native automatic reconnection via EventSource — often enough for notifications and dashboards.
À quoi servent les frames ping/pong ? What are ping/pong frames for?
De heartbeat : proxies, NAT et firewalls coupent silencieusement les connexions TCP inactives (souvent après 30-60 s). Le serveur envoie un ping périodique ; sans pong en retour, la connexion est considérée morte et nettoyée. Sans heartbeat, on accumule des connexions zombies et le client croit être connecté à tort. Heartbeat: proxies, NAT and firewalls silently drop idle TCP connections (often after 30-60 s). The server sends a periodic ping; without a pong back, the connection is considered dead and cleaned up. Without a heartbeat you accumulate zombie connections and the client wrongly believes it's connected.
Comment scaler des WebSockets sur plusieurs instances ? How do you scale WebSockets across several instances?
Deux briques : des sticky sessions au load balancer (la connexion, stateful, doit vivre sur une instance stable) et un pub/sub type Redis entre les instances — celle qui reçoit un message le publie sur un channel, toutes les instances abonnées le relaient à leurs propres clients connectés. C'est ce qu'implémente l'adapter Redis de socket.io. Two building blocks: sticky sessions at the load balancer (the connection is stateful and must live on a stable instance) and a Redis-style pub/sub between instances — the one receiving a message publishes it on a channel, and every subscribed instance relays it to its own connected clients. That's what socket.io's Redis adapter implements.
Qu'apporte socket.io par rapport au WebSocket natif, et à quel prix ? What does socket.io add over native WebSocket, and at what cost?
Apports : reconnexion automatique, rooms, namespaces, acknowledgements, fallback en long polling et adapter Redis pour le multi-instance. Prix : un protocole propriétaire (incompatible avec un client ou serveur WebSocket brut) et une dépendance des deux côtés. Aujourd'hui, ce sont surtout les rooms et l'adapter qui le justifient, plus le fallback. Additions: automatic reconnection, rooms, namespaces, acknowledgements, long-polling fallback and a Redis adapter for multi-instance. Cost: a proprietary protocol (incompatible with a raw WebSocket client or server) and a dependency on both sides. Today, rooms and the adapter justify it more than the fallback does.
Comment authentifier une connexion WebSocket depuis un navigateur ? How do you authenticate a WebSocket connection from a browser?
L'API WebSocket du navigateur n'autorise pas de headers custom. Options : cookie de session envoyé au handshake (en vérifiant impérativement le header Origin), token court-vécu en query string (attention aux logs serveur) ou message d'authentification juste après l'ouverture. L'identité est ensuite attachée à la connexion. The browser's WebSocket API doesn't allow custom headers. Options: session cookie sent at the handshake (imperatively checking the Origin header), a short-lived token in the query string (beware server logs) or an authentication message right after opening. Identity is then attached to the connection.
Qu'est-ce que le cross-site WebSocket hijacking et comment s'en protéger ? What is cross-site WebSocket hijacking and how do you defend against it?
Les WebSockets ne sont pas soumis au CORS : un site malveillant peut ouvrir une connexion vers votre serveur, et le navigateur y joint les cookies de session. Si le serveur ne vérifie pas le header Origin contre une allowlist, l'attaquant obtient une connexion authentifiée au nom de la victime. Protection : valider Origin au handshake (et/ou utiliser des tokens plutôt que le cookie seul). WebSockets are not subject to CORS: a malicious site can open a connection to your server, and the browser attaches the session cookies. If the server doesn't check the Origin header against an allowlist, the attacker gets an authenticated connection on the victim's behalf. Defense: validate Origin at the handshake (and/or use tokens rather than the cookie alone).
QCM Quiz
Quel code de statut HTTP conclut un handshake WebSocket réussi ? Which HTTP status code concludes a successful WebSocket handshake?
Le serveur accepte l'upgrade avec 101 Switching Protocols et le header Sec-WebSocket-Accept. 426 est au contraire l'erreur renvoyée quand le serveur exige un upgrade que le client n'a pas proposé. The server accepts the upgrade with 101 Switching Protocols and the Sec-WebSocket-Accept header. 426 is the opposite: the error returned when the server requires an upgrade the client didn't offer.
Pour pousser des notifications serveur → client sans que le client n'émette, quel est le choix le plus simple et suffisant ? To push server → client notifications with no client-side sending, what is the simplest sufficient choice?
Le flux est unidirectionnel : SSE suffit, avec EventSource qui gère reconnexion et reprise (Last-Event-ID) sans code. Le WebSocket ajouterait heartbeat et reconnexion manuelle pour rien. The flow is unidirectional: SSE is enough, with EventSource handling reconnection and resumption (Last-Event-ID) without code. A WebSocket would add heartbeat and manual reconnection for nothing.
Sur un chat à 3 instances derrière un load balancer, pourquoi faut-il un pub/sub Redis ? In a chat running on 3 instances behind a load balancer, why do you need a Redis pub/sub?
Le WebSocket est stateful : l'instance A ne connaît que ses propres connexions. Elle publie le message sur un channel Redis, et B et C le relaient à leurs clients. La persistance de l'historique est un problème séparé (base de données). WebSocket is stateful: instance A only knows its own connections. It publishes the message on a Redis channel, and B and C relay it to their clients. Persisting history is a separate problem (database).
Pourquoi la reconnexion client doit-elle utiliser un backoff exponentiel avec jitter ? Why must client reconnection use exponential backoff with jitter?
Une reconnexion immédiate en boucle transforme chaque incident en auto-DDoS : des milliers de clients synchronisés reviennent au même instant. Le backoff espace les tentatives, le jitter les désynchronise. La RFC ne dit rien du comportement de reconnexion. Immediate reconnection in a loop turns every incident into a self-inflicted DDoS: thousands of synchronized clients return at the same instant. Backoff spaces the attempts, jitter desynchronizes them. The RFC says nothing about reconnection behavior.
Un client WebSocket natif (API du navigateur) peut-il se connecter à un serveur socket.io ? Can a native WebSocket client (browser API) connect to a socket.io server?
socket.io encapsule ses messages (Engine.IO + son propre framing) : un client brut recevra des données incompréhensibles et échouera au handshake applicatif. Client et serveur doivent parler socket.io tous les deux. socket.io wraps its messages (Engine.IO + its own framing): a raw client receives unintelligible data and fails the application-level handshake. Client and server must both speak socket.io.
Pourquoi un serveur WebSocket doit-il vérifier le header Origin au handshake ? Why must a WebSocket server check the Origin header at the handshake?
C'est le cross-site WebSocket hijacking : le navigateur joint les cookies au handshake quel que soit le site qui l'initie. Seule la validation d'Origin côté serveur (ou une auth par token) bloque l'attaque. Hors navigateur, Origin est falsifiable, mais ce n'est pas le scénario visé. That's cross-site WebSocket hijacking: the browser attaches cookies to the handshake regardless of which site initiates it. Only server-side Origin validation (or token auth) blocks the attack. Outside browsers Origin can be forged, but that's not the targeted scenario.
Jour 8 Day 8 CI/CD & l'automatisation des déploiements CI/CD & deployment automation
Flashcards Flashcards
Quelle est la différence entre continuous delivery et continuous deployment ? What is the difference between continuous delivery and continuous deployment?
Delivery : chaque commit vert produit un artefact déployable, mais un humain décide quand déployer en prod. Deployment : tout commit vert sur la branche principale part en prod automatiquement, sans intervention. La différence tient en une phrase : qui appuie sur le bouton. Delivery: every green commit produces a deployable artifact, but a human decides when to ship to production. Deployment: every green commit on the main branch ships to production automatically, no intervention. The difference fits in one sentence: who presses the button.
Pourquoi met-on le lint et l'analyse statique en premier dans un pipeline ? Why do lint and static analysis come first in a pipeline?
Principe du fail-fast : ce sont les vérifications les moins chères (quelques secondes). Autant échouer en 30 secondes sur un problème de formatage ou de typage qu'attendre 10 minutes de tests pour le découvrir. On ordonne le pipeline du moins cher au plus cher. Fail-fast principle: they are the cheapest checks (a few seconds). Better to fail in 30 seconds on a formatting or typing issue than to wait through 10 minutes of tests to find out. You order the pipeline from cheapest to most expensive.
Qu'est-ce qu'un runner dans GitHub Actions ou GitLab CI ? What is a runner in GitHub Actions or GitLab CI?
La machine qui exécute les jobs : hébergée par la plateforme (VM éphémère et vierge à chaque job) ou auto-hébergée (self-hosted) quand on a besoin de GPU, d'un réseau privé ou de matériel spécifique. Comme l'environnement repart de zéro, le cache est essentiel pour la vitesse. The machine that executes jobs: hosted by the platform (ephemeral, clean VM per job) or self-hosted when you need GPUs, a private network or specific hardware. Since the environment starts from scratch, caching is essential for speed.
Pourquoi ne faut-il pas rebuilder l'artefact entre staging et prod ? Why should you not rebuild the artifact between staging and production?
Deux builds ne sont jamais garantis identiques : une dépendance peut avoir été mise à jour entre-temps, ce qui invalide tout ce qui a été testé en staging. On construit une seule fois (image taguée par SHA de commit) et on promeut ce même artefact immuable d'un environnement à l'autre. Two builds are never guaranteed identical: a dependency may have been updated in between, invalidating everything tested in staging. You build once (image tagged with the commit SHA) and promote that same immutable artifact from one environment to the next.
Rolling, blue-green, canary : résume les trois stratégies de déploiement. Rolling, blue-green, canary: summarize the three deployment strategies.
Rolling : on remplace les instances une par une, zéro interruption mais deux versions coexistent (rétro-compatibilité obligatoire). Blue-green : deux environnements complets, bascule totale du trafic, rollback instantané mais infra doublée. Canary : la nouvelle version reçoit 1-5 % du trafic, on surveille les métriques avant d'élargir — le meilleur contrôle du rayon d'impact. Rolling: replace instances one by one, zero downtime but two versions coexist (backward compatibility required). Blue-green: two full environments, full traffic switch, instant rollback but doubled infrastructure. Canary: the new version gets 1-5% of traffic, you watch metrics before widening — the best blast-radius control.
Qu'est-ce que le trunk-based development et quel rôle jouent les feature flags ? What is trunk-based development and what role do feature flags play?
Tout le monde merge fréquemment sur main via des branches très courtes (moins de 1-2 jours). Le code inachevé part en prod désactivé derrière un feature flag, ce qui sépare le déploiement (le code est sur les serveurs) de la release (il est activé pour les utilisateurs). Couper un flag prend des secondes. Everyone merges to main frequently through very short-lived branches (under 1-2 days). Unfinished code ships to production disabled behind a feature flag, separating deployment (code is on the servers) from release (it's enabled for users). Killing a flag takes seconds.
Pourquoi les migrations de base de données compliquent-elles le rollback ? Why do database migrations complicate rollbacks?
Redéployer l'artefact précédent est trivial, mais une migration qui a supprimé ou transformé des données ne se rejoue pas à l'envers. D'où le pattern expand/contract : ajouter la nouvelle colonne, faire cohabiter les deux versions, puis supprimer l'ancienne colonne dans un déploiement ultérieur — chaque version du code fonctionne avec le schéma d'avant et d'après. Redeploying the previous artifact is trivial, but a migration that dropped or transformed data cannot be replayed backwards. Hence the expand/contract pattern: add the new column, let both versions coexist, then drop the old column in a later deployment — each code version works with the schema before and after.
Comment une plateforme CI protège-t-elle les secrets, et quelle est la limite ? How does a CI platform protect secrets, and what is the limit?
Secrets stockés chiffrés, scopés par environnement, injectés en variables à l'exécution et masqués dans les logs. Limite : le masquage ne reconnaît pas un secret transformé (base64, URL-encodé, concaténé) — un echo de debug peut le faire fuiter. Un secret leaké se révoque, il ne se supprime pas des logs archivés. Secrets stored encrypted, scoped per environment, injected as variables at runtime and masked in logs. Limit: masking doesn't recognize a transformed secret (base64, URL-encoded, concatenated) — a debugging echo can leak it. A leaked secret gets revoked, not deleted from archived logs.
QCM Quiz
Dans une équipe en continuous delivery (pas deployment), que se passe-t-il après un pipeline vert sur main ? In a team doing continuous delivery (not deployment), what happens after a green pipeline on main?
C'est toute la différence avec le continuous deployment : en delivery, chaque commit vert est déployable mais le déploiement prod reste une décision humaine. That's the whole difference with continuous deployment: in delivery, every green commit is deployable but the production deploy remains a human decision.
Quelle stratégie de déploiement limite le mieux le rayon d'impact d'un bug en prod ? Which deployment strategy best limits the blast radius of a production bug?
Le canary n'expose qu'une petite fraction des utilisateurs au bug, le temps de vérifier les métriques. Blue-green offre un rollback instantané mais expose 100 % du trafic dès la bascule. Canary exposes only a small fraction of users to the bug while metrics are checked. Blue-green offers instant rollback but exposes 100% of traffic at switch time.
Pourquoi le cache est-il crucial dans un pipeline CI ? Why is caching crucial in a CI pipeline?
Les runners sont éphémères : node_modules, les couches Docker ou ~/.cargo disparaissent après chaque job. Le cache les restaure et fait la différence entre 3 et 15 minutes de pipeline. Runners are ephemeral: node_modules, Docker layers or ~/.cargo vanish after each job. The cache restores them and makes the difference between a 3- and a 15-minute pipeline.
Un test échoue aléatoirement dans la CI (flaky). Quelle est la bonne réponse d'équipe ? A test fails randomly in CI (flaky). What is the right team response?
Le retry et la relance masquent le symptôme : l'équipe finit par ignorer les échecs et un vrai bug passe. Supprimer le test perd la couverture. On corrige la cause (course condition, dépendance au temps, ordre des tests) ou on quarantaine en attendant. Retries and re-runs mask the symptom: the team ends up ignoring failures and a real bug slips through. Deleting the test loses coverage. Fix the cause (race condition, time dependency, test ordering) or quarantine it meanwhile.
Pourquoi un rolling deployment exige-t-il des migrations DB rétro-compatibles ? Why does a rolling deployment require backward-compatible DB migrations?
Les instances sont remplacées une par une : si la migration supprime une colonne que l'ancienne version lit encore, les instances pas encore mises à jour crashent. D'où expand/contract. Instances are replaced one by one: if the migration drops a column the old version still reads, the not-yet-updated instances crash. Hence expand/contract.
Quel avantage principal apportent les feature flags par rapport à un rollback classique ? What main advantage do feature flags offer over a classic rollback?
Le flag découple release et déploiement : couper un flag est instantané, alors qu'un rollback implique de redéployer un artefact (et de gérer les migrations). Le code derrière un flag doit quand même être testé. Flags decouple release from deployment: killing a flag is instant, while a rollback means redeploying an artifact (and dealing with migrations). Code behind a flag still needs tests.
Jour 7 Day 7 Redis & le caching Redis & caching
Flashcards Flashcards
Pourquoi Redis est-il si rapide ? (réponse complète attendue en entretien) Why is Redis so fast? (full answer expected in an interview)
Quatre raisons : données servies depuis la RAM (aucune I/O disque sur le chemin des requêtes), event loop mono-thread (zéro lock, zéro context switch), structures de données optimisées en C, protocole minimal (RESP). Dire seulement « parce que c'est de la RAM » est insuffisant. Four reasons: data served from RAM (no disk I/O on the request path), single-threaded event loop (zero locks, zero context switches), data structures optimized in C, minimal protocol (RESP). Saying only 'because it's RAM' is not enough.
Quelle structure Redis pour un leaderboard, et avec quelles commandes ? Which Redis structure for a leaderboard, and with which commands?
Le sorted set : chaque membre a un score, maintenu trié en permanence. ZADD pour insérer/mettre à jour un score, ZINCRBY pour l'incrémenter, ZRANGE (ou ZREVRANGE) pour le top N, ZRANK pour la position d'un joueur. Tout est en O(log n). The sorted set: each member has a score, kept permanently ordered. ZADD to insert/update a score, ZINCRBY to increment it, ZRANGE (or ZREVRANGE) for the top N, ZRANK for a player's position. Everything is O(log n).
Décris le pattern cache-aside, avec son défaut principal. Describe the cache-aside pattern, including its main flaw.
Lecture : l'app interroge le cache ; sur un miss, elle lit la DB puis peuple le cache avec un TTL. Écriture : DB puis invalidation de la clé. Défauts : premier accès lent (cache froid) et fenêtre d'incohérence — entre l'écriture DB et l'invalidation, ou pendant le TTL, on sert l'ancienne valeur. Read: the app queries the cache; on a miss, it reads the DB then populates the cache with a TTL. Write: DB then key invalidation. Flaws: slow first access (cold cache) and an inconsistency window — between the DB write and the invalidation, or during the TTL, the old value is served.
Write-through vs write-behind : quel trade-off ? Write-through vs write-behind: what's the trade-off?
Write-through : chaque écriture passe par le cache qui écrit dans la DB de façon synchrone — cache toujours frais mais écritures plus lentes. Write-behind : on écrit dans le cache, flush asynchrone vers la DB — écritures ultra-rapides mais perte possible de données si crash avant le flush. Write-through: every write goes through the cache, which writes to the DB synchronously — cache always fresh but slower writes. Write-behind: you write to the cache, with an asynchronous flush to the DB — ultra-fast writes but possible data loss if a crash occurs before the flush.
Qu'est-ce qu'un cache stampede et quelles sont les parades ? What is a cache stampede and what are the countermeasures?
Une clé chaude expire et des centaines de requêtes font miss simultanément : toutes frappent la DB, qui s'écroule (dogpile). Parades : lock distribué (SET NX EX — un seul client recalcule, les autres attendent ou servent le stale), TTL jitter (TTL ± aléa pour désynchroniser les expirations), recalcul anticipé avant expiration. A hot key expires and hundreds of requests miss simultaneously: they all hit the DB, which collapses (dogpile). Countermeasures: a distributed lock (SET NX EX — a single client recomputes, the others wait or serve stale), TTL jitter (TTL ± random to desynchronize expirations), early recomputation before expiry.
RDB vs AOF : quelles différences ? RDB vs AOF: what are the differences?
RDB : snapshots binaires périodiques (fork + copy-on-write), compacts, restart rapide, mais perte de tout ce qui suit le dernier snapshot. AOF : journal de chaque écriture avec fsync configurable (everysec ≈ 1 s de perte max), fichier plus gros, restart plus lent. On les combine souvent ; un pur cache peut désactiver les deux. RDB: periodic binary snapshots (fork + copy-on-write), compact, fast restart, but everything after the last snapshot is lost. AOF: a journal of every write with configurable fsync (everysec ≈ at most 1 s of loss), bigger file, slower restart. They're often combined; a pure cache can disable both.
Que se passe-t-il quand Redis atteint maxmemory, selon la politique d'éviction ? What happens when Redis reaches maxmemory, depending on the eviction policy?
noeviction (le défaut) : les écritures échouent avec une erreur. allkeys-lru : éviction des clés les moins récemment utilisées, TTL ou pas. volatile-lru : éviction uniquement parmi les clés à TTL. allkeys-lfu : par fréquence d'accès, souvent le meilleur choix pour un vrai cache. noeviction (the default): writes fail with an error. allkeys-lru: evicts the least recently used keys, TTL or not. volatile-lru: evicts only among keys with a TTL. allkeys-lfu: by access frequency, often the best choice for a real cache.
Pourquoi le pub/sub de Redis n'est-il pas une vraie message queue ? Why is Redis pub/sub not a real message queue?
C'est du fire-and-forget : aucune persistance, un abonné déconnecté perd définitivement les messages émis pendant son absence, pas d'acquittement ni de redélivrance. Les streams comblent une partie du manque (consumer groups, acks, relecture) ; pour du routage riche, des DLQ et des garanties fortes, il faut une vraie MQ (RabbitMQ, Kafka). It's fire-and-forget: no persistence, a disconnected subscriber permanently loses messages published while away, no acknowledgment or redelivery. Streams fill part of the gap (consumer groups, acks, replay); for rich routing, DLQs and strong guarantees, you need a real MQ (RabbitMQ, Kafka).
QCM Quiz
Un développeur lance `KEYS *` sur un Redis de production contenant 50 millions de clés. Conséquence ? A developer runs `KEYS *` on a production Redis holding 50 million keys. Consequence?
L'exécution des commandes est mono-thread : une commande O(n) sur 50 M de clés monopolise l'event loop et fige tout le serveur. En prod, on itère avec SCAN, qui parcourt par petits lots sans bloquer. Command execution is single-threaded: an O(n) command over 50M keys monopolizes the event loop and freezes the whole server. In production, iterate with SCAN, which walks in small batches without blocking.
Quelle structure Redis pour un rate limiter en fenêtre glissante (100 requêtes / 60 s) ? Which Redis structure for a sliding-window rate limiter (100 requests / 60 s)?
Le sorted set scoré par timestamp permet de purger les entrées hors fenêtre (ZREMRANGEBYSCORE) puis de compter ce qui reste (ZCARD) — le tout idéalement dans un script Lua pour l'atomicité. INCR+EXPIRE ne donne qu'une fenêtre fixe. A sorted set scored by timestamp lets you purge out-of-window entries (ZREMRANGEBYSCORE) then count what remains (ZCARD) — ideally inside a Lua script for atomicity. INCR+EXPIRE only gives a fixed window.
Un cache Redis sans TTL atteint maxmemory avec la politique par défaut. Que se passe-t-il ? A Redis cache without TTLs reaches maxmemory with the default policy. What happens?
Contrairement à l'intuition, Redis n'évince rien par défaut : noeviction fait échouer les écritures une fois la mémoire pleine. Pour un cache, il faut configurer explicitement allkeys-lru ou allkeys-lfu — et mettre des TTL. Counter-intuitively, Redis evicts nothing by default: noeviction makes writes fail once memory is full. For a cache, you must explicitly configure allkeys-lru or allkeys-lfu — and set TTLs.
À quoi sert le « TTL jitter » (TTL ± aléa) sur les clés d'un cache ? What is "TTL jitter" (TTL ± random) on cache keys for?
Des clés remplies en masse (déploiement, warm-up) avec le même TTL expirent en même temps : vague de miss synchronisée sur la DB. Un aléa de ±10-20 % étale les expirations dans le temps. Keys populated in bulk (deploy, warm-up) with the same TTL expire at the same time: a synchronized wave of misses hits the DB. A ±10-20% random offset spreads expirations over time.
Comment supprimer un hash de plusieurs millions de champs sans figer Redis ? How do you delete a hash with several million fields without freezing Redis?
DEL sur une big key libère la mémoire de façon synchrone dans l'event loop : tout le serveur attend. UNLINK détache la clé immédiatement et libère la mémoire en arrière-plan. FLUSHDB viderait toute la base. DEL on a big key reclaims memory synchronously inside the event loop: the whole server waits. UNLINK detaches the key immediately and frees memory in the background. FLUSHDB would wipe the entire database.
Redis persiste en RDB avec un snapshot toutes les 5 minutes, sans AOF. Le serveur crashe. Que perd-on ? Redis persists with RDB snapshots every 5 minutes, no AOF. The server crashes. What is lost?
RDB est un instantané périodique : tout ce qui suit le dernier snapshot disparaît au crash. C'est l'AOF (fsync everysec) qui borne la perte à ~1 s. D'où le combo RDB + AOF quand les données comptent — ou aucun des deux pour un pur cache. RDB is a periodic snapshot: everything after the last one vanishes on a crash. AOF (fsync everysec) is what bounds the loss to ~1 s. Hence the RDB + AOF combo when data matters — or neither for a pure cache.
Jour 6 Day 6 SQL vs NoSQL SQL vs NoSQL
Flashcards Flashcards
Que signifie ACID ? Illustre avec un virement bancaire. What does ACID stand for? Illustrate with a bank transfer.
Atomicity : débit et crédit passent ensemble ou pas du tout. Consistency : les contraintes (solde, clés étrangères) restent vraies. Isolation : deux virements concurrents ne se voient pas à moitié faits. Durability : après commit, un crash ne perd rien (write-ahead log). Atomicity: debit and credit happen together or not at all. Consistency: constraints (balance, foreign keys) remain true. Isolation: two concurrent transfers don't see each other half-done. Durability: after commit, a crash loses nothing (write-ahead log).
Cite les quatre familles NoSQL avec un exemple chacune. Name the four NoSQL families with one example each.
Document (MongoDB) : JSON imbriqués, agrégats dénormalisés. Clé-valeur (Redis, DynamoDB) : GET/PUT par clé, latence minimale. Colonnes larges (Cassandra) : écritures massives distribuées, modélisation par requête. Graphe (Neo4j) : nœuds et relations de première classe, traversées efficaces. Document (MongoDB): nested JSON, denormalized aggregates. Key-value (Redis, DynamoDB): GET/PUT by key, minimal latency. Wide-column (Cassandra): massive distributed writes, query-driven modeling. Graph (Neo4j): first-class nodes and relationships, efficient traversals.
Énonce correctement le théorème CAP. State the CAP theorem correctly.
Dans un système distribué, PENDANT une partition réseau (P, subie, pas choisie), il faut trancher entre cohérence (refuser de répondre plutôt que répondre faux) et disponibilité (répondre au risque de diverger). Hors partition, le vrai trade-off est latence vs cohérence (PACELC). CAP ne s'applique pas à une base mono-nœud. In a distributed system, DURING a network partition (P, endured, not chosen), you must choose between consistency (refusing to answer rather than answering wrong) and availability (answering at the risk of diverging). Outside a partition, the real trade-off is latency vs consistency (PACELC). CAP doesn't apply to a single-node database.
Qu'est-ce que la cohérence éventuelle (eventual consistency) ? What is eventual consistency?
Les répliques convergent vers la même valeur « à terme » : entre-temps, une lecture peut renvoyer une donnée périmée. Des garanties intermédiaires existent (read-your-writes, cohérence de session), et certains systèmes règlent la cohérence par requête (Cassandra : ONE vs QUORUM). Replicas converge to the same value 'eventually': in the meantime, a read can return stale data. Intermediate guarantees exist (read-your-writes, session consistency), and some systems tune consistency per request (Cassandra: ONE vs QUORUM).
Quelle différence entre réplication et sharding ? What's the difference between replication and sharding?
Réplication : copier les mêmes données sur plusieurs nœuds (leader-follower) → scale les lectures, tolère les pannes ; attention au replica lag. Sharding : partitionner des données différentes sur plusieurs nœuds selon une shard key → scale aussi les écritures ; mauvaise clé = hot shard, et les requêtes cross-shard coûtent cher. Replication: copying the same data to several nodes (leader-follower) → scales reads, tolerates failures; beware of replica lag. Sharding: partitioning different data across nodes according to a shard key → also scales writes; a bad key = hot shard, and cross-shard queries are expensive.
Dans quels cas un index B-tree ne sert-il à rien ? In which cases is a B-tree index useless?
Colonne à faible sélectivité (booléen : le planner préfère un scan complet), fonction appliquée à la colonne (lower(email) sans index d'expression), LIKE avec wildcard en tête ('%foo'), colonnes hors du préfixe d'un index composite, table minuscule. Vérifier avec EXPLAIN ANALYZE. Low-selectivity column (a boolean: the planner prefers a full scan), a function applied to the column (lower(email) without an expression index), LIKE with a leading wildcard ('%foo'), columns outside a composite index's prefix, a tiny table. Check with EXPLAIN ANALYZE.
Qu'est-ce que le problème N+1 et comment le corriger ? What is the N+1 problem and how do you fix it?
L'ORM charge une liste (1 requête) puis, en lazy loading, exécute 1 requête par élément pour la relation accédée dans une boucle : 1+N requêtes, page lente, log rempli de requêtes identiques. Correction : eager loading (JOIN FETCH, include, select_related/prefetch_related). The ORM loads a list (1 query) then, via lazy loading, runs 1 query per item for the relation accessed in a loop: 1+N queries, slow page, log full of identical queries. Fix: eager loading (JOIN FETCH, include, select_related/prefetch_related).
Pourquoi Postgres + JSONB est-il souvent la réponse pragmatique au débat SQL vs NoSQL ? Why is Postgres + JSONB often the pragmatic answer to the SQL vs NoSQL debate?
JSONB stocke du JSON binaire indexable (GIN) et requêtable dans un moteur ACID : on garde les colonnes relationnelles et les contraintes pour le structuré, et la flexibilité documentaire pour la partie variable — sans ajouter une deuxième base à opérer. JSONB stores binary JSON that is indexable (GIN) and queryable inside an ACID engine: you keep relational columns and constraints for the structured part, and document-style flexibility for the variable part — without adding a second database to operate.
QCM Quiz
Un virement débite un compte et en crédite un autre : soit les deux opérations passent, soit aucune. Quelle propriété ACID est en jeu ? A transfer debits one account and credits another: either both operations happen, or neither. Which ACID property is at play?
Tout ou rien = atomicité. La cohérence porte sur les contraintes, l'isolation sur la concurrence, la durabilité sur la survie au crash après commit. All or nothing = atomicity. Consistency is about constraints, isolation about concurrency, durability about surviving a crash after commit.
Pendant une partition réseau, que fait un système qui privilégie la disponibilité (AP) ? During a network partition, what does a system favoring availability (AP) do?
AP = rester disponible pendant la partition, quitte à diverger, puis converger après (cohérence éventuelle). Refuser de répondre serait le choix CP. « AP » ne signifie pas perdre des données. AP = staying available during the partition, even if it diverges, then converging afterwards (eventual consistency). Refusing to answer would be the CP choice. AP does not mean losing data.
Quel type de base est le plus adapté pour « les amis des amis de mes amis qui aiment le même jeu » ? Which database type fits best for 'friends of friends of my friends who like the same game'?
Une traversée à 3 niveaux avec filtre est le cas d'école du graphe : les relations sont des citoyens de première classe. En SQL, ce serait une cascade de self-joins de plus en plus coûteuse. A 3-level traversal with a filter is the textbook graph case: relationships are first-class citizens. In SQL, it would be an increasingly expensive cascade of self-joins.
La requête `WHERE lower(email) = 'a@b.fr'` est lente malgré un index sur `email`. Pourquoi ? The query `WHERE lower(email) = 'a@b.fr'` is slow despite an index on `email`. Why?
L'index B-tree stocke les valeurs de `email`, pas de `lower(email)` : le moteur ne peut pas s'en servir. Solution : `CREATE INDEX ON users (lower(email))` — ou une colonne citext. The B-tree index stores values of `email`, not `lower(email)`: the engine can't use it. Solution: `CREATE INDEX ON users (lower(email))` — or a citext column.
Une page affiche 50 articles avec leur auteur ; le log montre 51 requêtes SQL. Quelle est la bonne correction ? A page displays 50 articles with their author; the log shows 51 SQL queries. What is the right fix?
C'est le problème N+1 : le lazy loading de l'ORM déclenche une requête par article. L'eager loading ramène tout en 1-2 requêtes. L'index n'aide pas (les requêtes sont déjà rapides individuellement) et le cache masquerait le problème. This is the N+1 problem: the ORM's lazy loading fires one query per article. Eager loading brings everything back in 1-2 queries. An index doesn't help (each query is already fast individually) and caching would only mask the problem.
Un utilisateur modifie son profil, recharge la page et voit l'ancienne version pendant quelques secondes. Cause la plus probable dans une architecture leader-follower ? A user edits their profile, reloads the page and sees the old version for a few seconds. Most likely cause in a leader-follower architecture?
L'écriture va au leader, la lecture part sur un follower pas encore synchronisé : c'est le replica lag. La garantie qui manque s'appelle read-your-writes (ex. lire depuis le leader juste après une écriture). CAP n'interdit rien de tel. The write goes to the leader, the read hits a follower not yet caught up: that's replica lag. The missing guarantee is called read-your-writes (e.g. read from the leader right after a write). CAP forbids no such thing.
Actu News La guerre des prix a commencé : OpenAI casse Luna de 80 %, Anthropic sort Opus 5 The price war is on: OpenAI cuts Luna by 80%, Anthropic ships Opus 5
Flashcards Flashcards
Qu'a fait OpenAI le 30 juillet 2026 sur les prix de GPT-5.6 ? What did OpenAI do to GPT-5.6 pricing on July 30, 2026?
Baisse de 80 % sur Luna (1 $ / 6 $ → 0,20 $ / 1,20 $ par million de tokens entrée/sortie) et de 20 % sur Terra (2,50 $ / 15 $ → 2 $ / 12 $). Le flagship Sol reste à 5 $ / 30 $. Le tout 21 jours seulement après le lancement de la famille GPT-5.6. An 80% cut on Luna ($1 / $6 → $0.20 / $1.20 per million input/output tokens) and 20% on Terra ($2.50 / $15 → $2 / $12). Flagship Sol stayed at $5 / $30. All of it just 21 days after the GPT-5.6 family launched.
Pourquoi parle-t-on de « coût par tâche » plutôt que de « prix par token » ? Why talk about "cost per task" rather than "price per token"?
Parce qu'un modèle plus cher au token peut revenir moins cher au total s'il résout le problème en un appel au lieu de cinq. Le prix affiché ne dit rien du nombre d'allers-retours, de tokens de raisonnement ou de reprises nécessaires — seul le coût par tâche résolue est comparable. Because a model that costs more per token can be cheaper overall if it solves the problem in one call instead of five. The sticker price says nothing about round trips, reasoning tokens or retries — only cost per solved task is comparable.
Quels leviers concrets permettent de maîtriser le coût d'une fonctionnalité IA en production ? What concrete levers keep an AI feature's cost under control in production?
Router par tier (petit modèle pour l'extraction/classification, flagship pour le raisonnement dur), mettre en cache les prompts systèmes répétés, passer en batch tout ce qui n'est pas temps réel, mesurer le coût par tâche résolue, et poser un plafond de dépense avec alerte. Route by tier (small model for extraction/classification, flagship for hard reasoning), cache repeated system prompts, batch anything non-real-time, measure cost per solved task, and set a spend cap with an alert.
Que s'est-il passé fin juillet 2026 avec les conversations Claude partagées, et quelle leçon en tirer ? What happened in late July 2026 with shared Claude conversations, and what's the lesson?
Le 25 juillet, des centaines de chats et Artifacts publics ont été retrouvés dans Google (CV, clés d'API, tableurs financiers) : les pages de partage n'avaient pas de balise noindex. Anthropic a corrigé via robots.txt le 28. Leçon : une URL non devinable n'est pas un contrôle d'accès — il faut une autorisation vérifiée côté serveur. On July 25, hundreds of public chats and Artifacts turned up in Google (resumes, API keys, financial spreadsheets): the share pages had no noindex tag. Anthropic fixed it via robots.txt on July 28. Lesson: an unguessable URL is not access control — you need verified server-side authorization.
QCM Quiz
De combien OpenAI a-t-il baissé le prix de GPT-5.6 Luna le 30 juillet 2026 ? By how much did OpenAI cut the price of GPT-5.6 Luna on July 30, 2026?
Luna est passé de 1 $ / 6 $ à 0,20 $ / 1,20 $ par million de tokens, soit −80 %. Terra a baissé de 20 % et le flagship Sol est resté inchangé. Luna went from $1 / $6 to $0.20 / $1.20 per million tokens, a 80% cut. Terra dropped 20% and flagship Sol stayed unchanged.
Pourquoi les conversations Claude partagées se sont-elles retrouvées dans Google ? Why did shared Claude conversations end up in Google?
Aucun piratage : les pages de partage étaient publiques par conception et sans noindex. Dès qu'un lien circulait sur un forum ou un réseau social, les crawlers le suivaient et indexaient le contenu. No hack involved: the share pages were public by design and lacked noindex. As soon as a link circulated on a forum or social network, crawlers followed it and indexed the content.
Quel modèle a pris la tête de l'Artificial Analysis Intelligence Index fin juillet 2026 ? Which model topped the Artificial Analysis Intelligence Index in late July 2026?
Claude Opus 5, sorti le 24 juillet, prend la première place avec 61 points — au même tarif qu'Opus 4.8 (5 $ / 25 $ par million de tokens), soit environ la moitié du coût par tâche de Fable 5. Claude Opus 5, released July 24, took first place with 61 points — at the same price as Opus 4.8 ($5 / $25 per million tokens), roughly half Fable 5's cost per task.
Jour 5 Day 5 OAuth 2.0, OIDC & JWT OAuth 2.0, OIDC & JWT
Flashcards Flashcards
Quelle est la différence entre authentification et autorisation, et où se placent OAuth 2.0 et OIDC ? What is the difference between authentication and authorization, and where do OAuth 2.0 and OIDC fit?
L'authentification prouve l'identité (login, MFA) ; l'autorisation détermine les droits. OAuth 2.0 est un framework d'autorisation déléguée : il ne dit pas qui est l'utilisateur. C'est OIDC qui ajoute la couche d'identité (id_token, endpoint /userinfo) au-dessus d'OAuth. Authentication proves identity (login, MFA); authorization determines rights. OAuth 2.0 is a delegated authorization framework: it doesn't say who the user is. OIDC is what adds the identity layer (id_token, /userinfo endpoint) on top of OAuth.
De quoi est composé un JWT ? What is a JWT made of?
Trois parties encodées en base64url, séparées par des points : header (algorithme de signature), payload (claims : sub, iss, aud, exp, iat + claims métier), signature calculée sur les deux premières. Le token est signé mais PAS chiffré : lisible par tous, infalsifiable sans la clé. Three base64url-encoded parts separated by dots: header (signing algorithm), payload (claims: sub, iss, aud, exp, iat + business claims), and a signature computed over the first two. The token is signed but NOT encrypted: anyone can read it, nobody can forge it without the key.
HS256 vs RS256 : quelle différence et quand choisir l'un ou l'autre ? HS256 vs RS256: what's the difference and when do you pick one over the other?
HS256 = HMAC symétrique : le même secret signe et vérifie, donc tout service qui vérifie peut aussi forger. RS256 = RSA asymétrique : la clé privée signe, la clé publique (publiée via JWKS) vérifie. En microservices, RS256 : les services valident les tokens sans jamais détenir la clé de signature. HS256 = symmetric HMAC: the same secret signs and verifies, so any verifying service can also forge. RS256 = asymmetric RSA: the private key signs, the public key (published via JWKS) verifies. In microservices, RS256: services validate tokens without ever holding the signing key.
Pourquoi un JWT est-il difficile à révoquer, et quelle est la parade standard ? Why is a JWT hard to revoke, and what is the standard countermeasure?
Il est auto-porteur : valide jusqu'à son exp, sans consultation du serveur — un logout ne l'invalide pas. Parade : access token court (5-15 min) + refresh token long stocké côté serveur, donc révocable, avec rotation (chaque usage émet un nouveau refresh token, la réutilisation d'un ancien signale un vol). It's self-contained: valid until its exp without asking the server — a logout doesn't invalidate it. Countermeasure: short-lived access token (5-15 min) + long-lived refresh token stored server-side, hence revocable, with rotation (each use issues a new refresh token; reusing an old one signals theft).
Qu'est-ce que PKCE et contre quoi protège-t-il ? What is PKCE and what does it protect against?
Une extension du flow authorization code : le client génère un code_verifier aléatoire, envoie son hash SHA-256 (code_challenge) au début, et présente le verifier à l'échange du code. Un code intercepté est donc inexploitable. Conçu pour les clients publics (mobile, SPA) sans client_secret ; recommandé partout, obligatoire en OAuth 2.1. An extension of the authorization code flow: the client generates a random code_verifier, sends its SHA-256 hash (code_challenge) upfront, and presents the verifier when exchanging the code. An intercepted code is therefore unusable. Designed for public clients (mobile, SPA) without a client_secret; recommended everywhere, mandatory in OAuth 2.1.
Quelle différence entre l'access token et l'id_token d'OIDC ? What's the difference between the access token and OIDC's id_token?
L'access token sert à appeler l'API (resource server) : c'est de l'autorisation, son contenu est destiné à l'API. L'id_token est un JWT destiné au client, qui décrit QUI est connecté (claims sub, email, name…) : c'est de l'authentification. Ne jamais utiliser l'un à la place de l'autre. The access token is for calling the API (resource server): it's authorization, and its content is meant for the API. The id_token is a JWT meant for the client, describing WHO is logged in (sub, email, name claims…): that's authentication. Never use one in place of the other.
localStorage vs cookie httpOnly pour stocker un token : quels risques respectifs ? localStorage vs httpOnly cookie for storing a token: what are the respective risks?
localStorage est lisible par tout JS de la page : une XSS exfiltre le token. Un cookie httpOnly + Secure + SameSite est invisible pour JS (protégé XSS) mais envoyé automatiquement : surface CSRF, atténuée par SameSite=Lax/Strict et un token anti-CSRF. Pattern robuste : access token en mémoire + refresh token en cookie httpOnly. localStorage is readable by any JS on the page: an XSS exfiltrates the token. An httpOnly + Secure + SameSite cookie is invisible to JS (XSS-safe) but sent automatically: CSRF surface, mitigated by SameSite=Lax/Strict and an anti-CSRF token. Robust pattern: access token in memory + refresh token in an httpOnly cookie.
Que doit vérifier le serveur quand il reçoit un JWT ? What must the server check when it receives a JWT?
La signature avec l'algorithme ATTENDU (configuré côté serveur, jamais lu aveuglément dans le header), puis les claims : exp (avec une tolérance de clock skew), iss (bon émetteur), aud (token bien destiné à ce service), et les scopes/rôles pour l'autorisation. Le tout via une lib éprouvée, pas de crypto maison. The signature with the EXPECTED algorithm (configured server-side, never blindly read from the header), then the claims: exp (with clock-skew tolerance), iss (right issuer), aud (token really meant for this service), and scopes/roles for authorization. All through a battle-tested library, no home-made crypto.
QCM Quiz
Que garantit la signature d'un JWT ? What does a JWT's signature guarantee?
La signature prouve que le token n'a pas été modifié et qu'il vient bien du détenteur de la clé. Le payload reste lisible par tous : base64url n'est pas du chiffrement. The signature proves the token wasn't modified and really comes from the key holder. The payload stays readable by anyone: base64url is not encryption.
Quel flow OAuth 2.0 pour un batch nocturne qui appelle une API interne sans utilisateur ? Which OAuth 2.0 flow for a nightly batch calling an internal API with no user involved?
Sans resource owner, pas de redirection ni de consentement : le client s'authentifie directement avec ses credentials (client credentials). Authorization code implique un utilisateur ; implicit et ROPC sont dépréciés. With no resource owner, there's no redirect or consent: the client authenticates directly with its credentials (client credentials). Authorization code involves a user; implicit and ROPC are deprecated.
En quoi consiste l'attaque par « confusion d'algorithme » sur les JWT ? What is the JWT "algorithm confusion" attack?
Si la lib lit l'alg du header sans le vérifier, un attaquant forge un token HS256 signé avec la clé publique RSA (connue de tous) : le serveur, croyant faire du HMAC, valide. Parade : imposer l'algorithme attendu côté serveur. If the library reads the header's alg without enforcing it, an attacker forges an HS256 token signed with the (publicly known) RSA public key: the server, believing it's doing HMAC, validates it. Defense: enforce the expected algorithm server-side.
Pourquoi donne-t-on une durée de vie courte (5-15 min) aux access tokens JWT ? Why are JWT access tokens given a short lifetime (5-15 min)?
Le token étant valide jusqu'à exp sans consultation du serveur, on borne le risque par une durée courte ; le refresh token, révocable côté serveur, renouvelle la session sans re-login. Since the token is valid until exp without asking the server, the risk is bounded by a short lifetime; the refresh token, revocable server-side, renews the session without re-login.
Contre quoi un cookie httpOnly protège-t-il le token qu'il contient ? What does an httpOnly cookie protect its token against?
httpOnly rend le cookie invisible à document.cookie et à tout JS : une XSS ne peut plus l'exfiltrer. Mais le cookie part automatiquement avec les requêtes → il faut traiter le CSRF séparément (SameSite, token anti-CSRF). L'interception réseau, c'est le rôle de Secure/TLS. httpOnly makes the cookie invisible to document.cookie and any JS: an XSS can no longer exfiltrate it. But the cookie is sent automatically with requests → CSRF must be handled separately (SameSite, anti-CSRF token). Network interception is the job of Secure/TLS.
Dans une intégration « Login with Google » (OIDC), quel token le front doit-il envoyer à votre API backend pour agir au nom de l'utilisateur ? In a "Login with Google" (OIDC) integration, which token should the front end send to your backend API to act on the user's behalf?
L'access token est fait pour être présenté à l'API (resource server). L'id_token est destiné au client pour savoir qui est connecté ; le code ne sert qu'à l'échange initial ; le refresh token ne quitte jamais le stockage sécurisé du client. The access token is made to be presented to the API (resource server). The id_token is meant for the client to know who's logged in; the code is only for the initial exchange; the refresh token never leaves the client's secure storage.
Jour 4 Day 4 RabbitMQ & les files de messages RabbitMQ & message queues
Flashcards Flashcards
Quels sont les trois bénéfices principaux d'une message queue entre deux services ? What are the three main benefits of a message queue between two services?
Découplage (le producteur ignore qui consomme, le consommateur peut être down sans casser le producteur), lissage de charge (un pic s'empile dans la queue au lieu d'écrouler le consommateur), résilience (le message persiste jusqu'à son traitement, avec retry natif via la redélivrance). Decoupling (the producer doesn't know who consumes, the consumer can be down without breaking the producer), load smoothing (a spike piles up in the queue instead of crushing the consumer), resilience (the message persists until processed, with native retry through redelivery).
Dans le modèle AMQP, où un producteur publie-t-il ses messages ? In the AMQP model, where does a producer publish its messages?
Jamais directement dans une queue : dans un exchange, avec une routing key. L'exchange route ensuite le message vers zéro, une ou plusieurs queues selon ses bindings (les règles de liaison exchange → queue). Never directly to a queue: to an exchange, with a routing key. The exchange then routes the message to zero, one or several queues according to its bindings (the exchange → queue link rules).
Quels sont les trois types d'exchange principaux et leur logique de routage ? What are the three main exchange types and their routing logic?
Direct : correspondance exacte entre routing key et binding. Fanout : diffusion à toutes les queues liées, routing key ignorée (pub/sub pur). Topic : pattern matching sur la clé segmentée par des points, avec `*` = exactement un mot et `#` = zéro ou plusieurs mots. Direct: exact match between routing key and binding. Fanout: broadcast to all bound queues, routing key ignored (pure pub/sub). Topic: pattern matching on the dot-separated key, with `*` = exactly one word and `#` = zero or more words.
Que se passe-t-il si un consumer meurt avant d'avoir acquitté un message ? What happens if a consumer dies before acknowledging a message?
Le broker détecte la fermeture du canal et remet le message en queue avec le flag redelivered ; un autre consumer le reprend. Rien n'est perdu (at-least-once), mais le traitement a pu être partiellement appliqué — d'où l'exigence d'idempotence côté consumer. The broker detects the channel closing and requeues the message with the redelivered flag; another consumer picks it up. Nothing is lost (at-least-once), but processing may have been partially applied — hence the idempotence requirement on the consumer side.
At-most-once vs at-least-once : quelle différence et quel réglage les produit ? At-most-once vs at-least-once: what's the difference and which setting produces each?
Auto-ack = at-most-once : le message est considéré livré dès l'envoi, un crash du consumer le perd. Ack manuel après traitement = at-least-once : rien n'est perdu, mais un crash entre traitement et ack produit un doublon. L'exactly-once de bout en bout n'existe pas sans coopération applicative. Auto-ack = at-most-once: the message is considered delivered as soon as it's sent, a consumer crash loses it. Manual ack after processing = at-least-once: nothing is lost, but a crash between processing and ack produces a duplicate. End-to-end exactly-once doesn't exist without application-level cooperation.
Pourquoi et comment rendre un consumer idempotent ? Why and how do you make a consumer idempotent?
Parce que le at-least-once produit des doublons lors des redélivrances. Techniques : déduplication par message id (stocké en base avec contrainte unique, le doublon échoue proprement) ou opérations naturellement idempotentes (upsert, `SET status = 'paid'` plutôt que `balance += x`). Because at-least-once produces duplicates on redeliveries. Techniques: deduplication by message id (stored in the database with a unique constraint, the duplicate fails cleanly) or naturally idempotent operations (upsert, `SET status = 'paid'` rather than `balance += x`).
Qu'est-ce qu'une dead letter queue (DLQ) et pourquoi est-elle indispensable ? What is a dead letter queue (DLQ) and why is it essential?
Une queue vers laquelle un dead-letter exchange (DLX) route les messages rejetés sans requeue, expirés (TTL) ou en dépassement de longueur max. Sans elle, un message empoisonné qui fait crasher le consumer revient en boucle et bloque la queue ; avec elle, on l'isole, on l'inspecte et on le rejoue. A queue to which a dead-letter exchange (DLX) routes messages rejected without requeue, expired (TTL) or overflowing the max length. Without it, a poison message that crashes the consumer loops forever and blocks the queue; with it, you isolate, inspect and replay it.
RabbitMQ vs Kafka : quelle différence de modèle et quand choisir l'un ou l'autre ? RabbitMQ vs Kafka: what's the model difference and when do you choose which?
Rabbit est une queue : broker intelligent qui route finement, message supprimé après ack — idéal pour la distribution de tâches, le routage riche, la latence faible. Kafka est un log append-only : les messages restent, chaque consumer avance son offset — replay possible, lectures indépendantes du même flux, très haut débit via les partitions. Event streaming → Kafka ; task queues → Rabbit. Rabbit is a queue: a smart broker with fine-grained routing, messages deleted after ack — ideal for task distribution, rich routing, low latency. Kafka is an append-only log: messages stay, each consumer advances its offset — replay possible, independent reads of the same stream, very high throughput via partitions. Event streaming → Kafka; task queues → Rabbit.
QCM Quiz
Dans RabbitMQ, vers quoi un producteur publie-t-il un message ? In RabbitMQ, what does a producer publish a message to?
En AMQP, le producteur ne connaît que l'exchange et la routing key ; le routage vers les queues est déclaré par les bindings. Les partitions par hash de clé, c'est le modèle Kafka. In AMQP, the producer only knows the exchange and the routing key; routing to queues is declared through bindings. Partitions chosen by key hash are the Kafka model.
Avec un topic exchange, quelle routing key matche le binding `logs.*.error` ? With a topic exchange, which routing key matches the binding `logs.*.error`?
`*` matche exactement un mot entre deux points : `logs.api.error` colle. `logs.api.db.error` a deux mots au milieu (il faudrait `#`), `logs.error` n'en a aucun, et `api.logs.error` ne commence pas par `logs`. `*` matches exactly one word between dots: `logs.api.error` fits. `logs.api.db.error` has two words in the middle (you'd need `#`), `logs.error` has none, and `api.logs.error` doesn't start with `logs`.
Quelle garantie de livraison obtient-on avec l'auto-ack activé ? Which delivery guarantee do you get with auto-ack enabled?
En auto-ack, le message est considéré livré dès l'envoi au consumer : s'il crashe en plein traitement, le broker ne redélivre rien. L'at-least-once exige l'ack manuel après traitement. With auto-ack, the message is considered delivered as soon as it's sent to the consumer: if it crashes mid-processing, the broker redelivers nothing. At-least-once requires a manual ack after processing.
Quels messages sont routés vers un dead-letter exchange (DLX) ? Which messages are routed to a dead-letter exchange (DLX)?
Trois causes de dead-lettering : reject/nack avec requeue=false, expiration TTL, dépassement de max-length. Le broker n'inspecte jamais le contenu du message — un JSON invalide ne l'intéresse pas. Three causes of dead-lettering: reject/nack with requeue=false, TTL expiry, max-length overflow. The broker never inspects message content — invalid JSON means nothing to it.
À quoi sert le prefetch (QoS) côté consumer ? What is prefetch (QoS) for on the consumer side?
Sans prefetch, le broker déverse tous les messages disponibles sur le premier consumer connecté, même s'il est lent. `prefetch=N` borne les messages en vol non acquittés : les consumers rapides en reçoivent plus. L'ordre entre consumers, lui, n'est jamais garanti. Without prefetch, the broker dumps every available message on the first connected consumer, even a slow one. `prefetch=N` caps unacked in-flight messages: fast consumers receive more. Order across consumers is never guaranteed.
Quelle différence fondamentale entre le modèle de Kafka et celui de RabbitMQ ? What is the fundamental difference between Kafka's model and RabbitMQ's?
Dans Kafka, les messages restent dans le log (rétention configurable) et chaque consumer group lit à son propre offset — d'où le replay et les lectures indépendantes. Dans Rabbit, un message acquitté est supprimé de la queue. Les deux sont asynchrones et offrent des garanties de livraison. In Kafka, messages stay in the log (configurable retention) and each consumer group reads at its own offset — hence replay and independent reads. In Rabbit, an acknowledged message is deleted from the queue. Both are asynchronous and offer delivery guarantees.
Jour 3 Day 3 REST vs GraphQL vs gRPC REST vs GraphQL vs gRPC
Flashcards Flashcards
Quelles sont les principales contraintes de REST ? What are REST's main constraints?
Ressources identifiées par des URLs, interface uniforme HTTP (verbes GET/POST/PUT/PATCH/DELETE + codes de statut), statelessness (chaque requête porte tout son contexte), réponses cacheables. HATEOAS (liens vers les actions possibles dans les réponses) complète le modèle « pur », rarement implémenté. Resources identified by URLs, the uniform HTTP interface (GET/POST/PUT/PATCH/DELETE verbs + status codes), statelessness (each request carries its full context), cacheable responses. HATEOAS (links to possible actions inside responses) completes the "pure" model, rarely implemented.
Quelle différence entre un 401 et un 403 ? What's the difference between a 401 and a 403?
401 Unauthorized = non authentifié : le serveur ne sait pas qui vous êtes (token absent, invalide ou expiré). 403 Forbidden = authentifié mais non autorisé : identité connue, droits insuffisants. Réessayer avec les mêmes credentials ne changera rien à un 403. 401 Unauthorized = not authenticated: the server doesn't know who you are (missing, invalid or expired token). 403 Forbidden = authenticated but not authorized: known identity, insufficient rights. Retrying with the same credentials won't change a 403.
Qu'appelle-t-on over-fetching et under-fetching, et comment GraphQL les résout-il ? What are over-fetching and under-fetching, and how does GraphQL solve them?
Over-fetching : l'API renvoie plus de champs que nécessaire (40 champs pour en afficher 3). Under-fetching : un écran nécessite plusieurs appels enchaînés. GraphQL laisse le client décrire exactement les champs voulus, relations comprises, en un seul aller-retour sur un endpoint unique. Over-fetching: the API returns more fields than needed (40 fields to display 3). Under-fetching: one screen requires several chained calls. GraphQL lets the client describe exactly the fields it wants, relations included, in a single round trip on a single endpoint.
Qu'est-ce que le problème N+1 en GraphQL et comment le résout-on ? What is the N+1 problem in GraphQL and how is it solved?
Avec des resolvers naïfs, une liste de N éléments dont chacun résout une relation (ex. l'auteur d'un post) déclenche 1 requête pour la liste + N requêtes pour les relations. Solution : le batching avec le pattern DataLoader, qui regroupe les chargements d'un même tick en une seule requête (WHERE id IN (...)) et déduplique. With naive resolvers, a list of N items each resolving a relation (e.g. a post's author) triggers 1 query for the list + N queries for the relations. Solution: batching with the DataLoader pattern, which groups same-tick loads into a single query (WHERE id IN (...)) and deduplicates.
Pourquoi gRPC est-il plus performant que REST/JSON ? Why is gRPC faster than REST/JSON?
Sérialisation protobuf binaire (champs numérotés, payloads compacts, parsing rapide), transport HTTP/2 (multiplexage sur une connexion persistante, compression d'en-têtes), code client/serveur généré depuis le contrat .proto, et streaming natif (server, client, bidirectionnel). Binary protobuf serialization (numbered fields, compact payloads, fast parsing), HTTP/2 transport (multiplexing over a persistent connection, header compression), client/server code generated from the .proto contract, and native streaming (server, client, bidirectional).
Qu'est-ce que l'idempotence et quels verbes HTTP le sont ? What is idempotence and which HTTP verbs are idempotent?
Une opération est idempotente si la rejouer produit le même état final qu'une seule exécution. GET, PUT et DELETE sont idempotents ; POST ne l'est pas. C'est crucial pour les retries : rejouer un POST de paiement sans idempotency key peut débiter deux fois. An operation is idempotent if replaying it produces the same final state as a single execution. GET, PUT and DELETE are idempotent; POST is not. This is crucial for retries: replaying a payment POST without an idempotency key can charge twice.
Pagination offset vs cursor : quelle différence et laquelle préférer ? Offset vs cursor pagination: what's the difference and which should you prefer?
Offset (`?page=3&limit=20`) : simple, mais les éléments se décalent si la liste change entre deux pages, et OFFSET profond force la base à parcourir puis jeter des milliers de lignes. Cursor : un pointeur opaque après le dernier élément vu — stable et performant. À préférer par défaut pour les listes qui bougent. Offset (`?page=3&limit=20`): simple, but items shift if the list changes between pages, and a deep OFFSET forces the database to scan then discard thousands of rows. Cursor: an opaque pointer after the last seen item — stable and fast. Prefer it by default for lists that change.
REST, GraphQL ou gRPC : quelle grille de choix rapide ? REST, GraphQL or gRPC: what's the quick decision grid?
API publique → REST (universel, cacheable, testable au curl). BFF ou client mobile agrégeant plusieurs sources → GraphQL (composition des données en un aller-retour). Microservices internes à fort trafic → gRPC (contrats stricts, perfs, streaming ; mais navigateur seulement via grpc-web + proxy). Public API → REST (universal, cacheable, curl-testable). BFF or mobile client aggregating several sources → GraphQL (data composition in one round trip). High-traffic internal microservices → gRPC (strict contracts, performance, streaming; but browsers only via grpc-web + proxy).
QCM Quiz
Quel verbe HTTP n'est PAS idempotent ? Which HTTP verb is NOT idempotent?
Deux POST identiques créent deux ressources. Rejouer un PUT (remplacement complet), un DELETE ou un GET produit le même état final — c'est ce qui rend leurs retries sûrs. Two identical POSTs create two resources. Replaying a PUT (full replacement), a DELETE or a GET produces the same final state — which is what makes their retries safe.
Une app mobile n'affiche que 3 champs mais l'API REST en renvoie 40. Comment s'appelle ce problème ? A mobile app displays only 3 fields but the REST API returns 40. What is this problem called?
Over-fetching = recevoir plus de données que nécessaire. Under-fetching = devoir enchaîner plusieurs appels pour un écran. GraphQL résout les deux en laissant le client sélectionner ses champs. Over-fetching = receiving more data than needed. Under-fetching = having to chain several calls for one screen. GraphQL solves both by letting the client select its fields.
Sur quoi repose gRPC pour la sérialisation et le transport ? What does gRPC rely on for serialization and transport?
gRPC sérialise en protobuf (binaire, compact, typé) et transporte sur HTTP/2, ce qui apporte multiplexage, compression d'en-têtes et streaming bidirectionnel. gRPC serializes with protobuf (binary, compact, typed) and transports over HTTP/2, which brings multiplexing, header compression and bidirectional streaming.
En protobuf, quelle règle garantit la compatibilité ascendante d'un message ? In protobuf, which rule guarantees a message's backward compatibility?
Le wire format protobuf identifie les champs par leur numéro, pas par leur nom. Réutiliser un numéro pour un autre champ corrompt silencieusement le décodage des anciens messages ; on ajoute des numéros, on ne recycle jamais (mot-clé reserved). The protobuf wire format identifies fields by number, not name. Reusing a number for another field silently corrupts decoding of old messages; you add numbers, never recycle them (the reserved keyword).
Une requête arrive avec un token expiré. Quel code de statut renvoyer ? A request arrives with an expired token. Which status code should you return?
Token expiré = le serveur ne peut plus authentifier le client → 401 (avec en général un header WWW-Authenticate). 403 signifierait « identité connue mais droits insuffisants ». 419 n'est pas un code standard. Expired token = the server can no longer authenticate the client → 401 (usually with a WWW-Authenticate header). 403 would mean "known identity but insufficient rights". 419 is not a standard code.
Pourquoi le cache HTTP classique fonctionne-t-il mal avec GraphQL ? Why does standard HTTP caching work poorly with GraphQL?
Les caches HTTP (navigateur, CDN) travaillent sur des GET avec des URLs distinctes. En GraphQL, chaque requête est un POST vers /graphql avec un body différent : il faut du caching applicatif (client normalisé type Apollo, persisted queries). HTTP caches (browser, CDN) work on GETs with distinct URLs. In GraphQL, every request is a POST to /graphql with a different body: you need application-level caching (a normalized client like Apollo, persisted queries).
Jour 2 Day 2 Git avancé : rebase, cherry-pick & bisect Advanced Git: rebase, cherry-pick & bisect
Flashcards Flashcards
Qu'est-ce qu'une branche pour Git, concrètement ? What is a branch to Git, concretely?
Un simple pointeur mutable vers un commit : un fichier de 41 octets dans `.git/refs/heads/` contenant un hash. L'historique est le graphe (DAG) des commits ; la branche n'est qu'une étiquette qui avance à chaque commit. D'où des branches instantanées et gratuites. Just a mutable pointer to a commit: a 41-byte file in `.git/refs/heads/` containing a hash. History is the graph (DAG) of commits; the branch is only a label that advances with each commit. Hence instant, free branching.
Quelle est la différence fondamentale entre merge et rebase ? What is the fundamental difference between merge and rebase?
Merge crée un commit de fusion à deux parents et préserve l'historique tel qu'il s'est passé. Rebase rejoue chaque commit de la branche par-dessus la cible : nouveaux commits, nouveaux hashes, historique linéaire mais réécrit. Le résultat du code est le même, l'historique non. Merge creates a two-parent merge commit and preserves history as it happened. Rebase replays each commit of the branch on top of the target: new commits, new hashes, a linear but rewritten history. The resulting code is the same, the history is not.
Que permet le rebase interactif (`git rebase -i`) ? What does interactive rebase (`git rebase -i`) let you do?
Réécrire une série de commits avant de la partager : réordonner, fusionner (`squash`/`fixup`), reformuler (`reword`), modifier (`edit`) ou supprimer (`drop`) des commits. C'est l'outil standard pour nettoyer une branche avant d'ouvrir la PR. Rewrite a series of commits before sharing it: reorder, combine (`squash`/`fixup`), reword (`reword`), amend (`edit`) or delete (`drop`) commits. It's the standard tool for cleaning up a branch before opening the PR.
À quoi sert `git cherry-pick` et quel est son cas d'usage typique ? What is `git cherry-pick` for, and what is its typical use case?
Il rejoue un commit précis sur la branche courante, en créant un nouveau commit (nouveau hash). Cas typique : reporter un hotfix de `main` vers une branche de release. Attention : le même changement existe alors deux fois dans l'historique si les branches sont mergées ensuite. It replays one specific commit onto the current branch, creating a new commit (new hash). Typical case: backporting a hotfix from `main` to a release branch. Beware: the same change then exists twice in history if the branches are later merged.
Comment fonctionne `git bisect` ? How does `git bisect` work?
Recherche dichotomique du commit fautif : on marque un commit `bad` et un commit `good`, Git checkout le commit du milieu, on teste et on répond good/bad, jusqu'à isoler le coupable en log₂(n) étapes (1000 commits ≈ 10 tests). `git bisect run ./script.sh` automatise tout. Binary search for the offending commit: you mark one `bad` and one `good` commit, Git checks out the middle commit, you test and answer good/bad, until the culprit is isolated in log₂(n) steps (1000 commits ≈ 10 tests). `git bisect run ./script.sh` automates the whole thing.
Qu'est-ce que le reflog et pourquoi est-ce un filet de sécurité ? What is the reflog and why is it a safety net?
`git reflog` journalise localement tous les déplacements de HEAD et des branches (~90 jours). Après un rebase raté ou un `reset --hard` malheureux, on retrouve le hash d'avant l'erreur et on restaure avec `git reset --hard HEAD@{n}`. Un commit non référencé n'est perdu qu'après passage du garbage collector. `git reflog` locally journals every move of HEAD and branches (~90 days). After a botched rebase or an unfortunate `reset --hard`, you find the hash from before the mistake and restore with `git reset --hard HEAD@{n}`. An unreferenced commit is only lost once the garbage collector runs.
Quelle est la règle d'or du rebase ? What is the golden rule of rebase?
Ne jamais rebaser des commits déjà poussés et partagés. Le rebase crée de nouveaux hashes : les collègues qui ont basé leur travail sur les anciens commits se retrouvent avec des historiques divergents pénibles à réconcilier. Rebase = uniquement sur ses commits locaux. Never rebase commits that have already been pushed and shared. Rebase creates new hashes: colleagues who based their work on the old commits end up with painfully diverged histories. Rebase = only on your local commits.
`git push --force` vs `--force-with-lease` : quelle différence ? `git push --force` vs `--force-with-lease`: what's the difference?
`--force` écrase la branche distante aveuglément, même si un collègue a poussé entre-temps (travail perdu). `--force-with-lease` échoue si la branche distante a bougé depuis le dernier fetch : même usage (pousser après un rebase), sans le risque. C'est le seul force push acceptable en équipe. `--force` blindly overwrites the remote branch, even if a colleague pushed in the meantime (lost work). `--force-with-lease` fails if the remote branch moved since your last fetch: same use (pushing after a rebase), without the risk. It's the only acceptable force push on a team.
QCM Quiz
Que fait `git rebase main` aux commits de la branche courante ? What does `git rebase main` do to the commits of the current branch?
Le hash d'un commit couvre son contenu, son parent et ses métadonnées : rejouer un commit sur un autre parent crée forcément un nouveau commit. Les anciens restent dans .git/objects, non référencés. A commit's hash covers its content, parent and metadata: replaying a commit on a different parent necessarily creates a new commit. The old ones remain in .git/objects, unreferenced.
Après un `git reset --hard` sur le mauvais commit, comment récupérer son travail commité ? After a `git reset --hard` on the wrong commit, how do you recover your committed work?
Le reflog journalise tous les déplacements de HEAD : `git reset --hard HEAD@{n}` restaure la position d'avant. Seul le travail jamais commité est réellement perdu. Revert, lui, crée un commit inverse — autre usage. The reflog journals every move of HEAD: `git reset --hard HEAD@{n}` restores the previous position. Only work that was never committed is truly lost. Revert creates an inverse commit — a different use case.
Avec `git bisect`, combien de tests faut-il environ pour isoler un bug dans 1000 commits ? With `git bisect`, about how many tests does it take to isolate a bug in 1000 commits?
Bisect fait une recherche dichotomique : log₂(1000) ≈ 10 étapes. C'est tout l'intérêt par rapport à un parcours linéaire de l'historique. Bisect performs a binary search: log₂(1000) ≈ 10 steps. That's the whole point compared to walking the history linearly.
Quelle commande rejoue un commit précis d'une autre branche sur la branche courante ? Which command replays one specific commit from another branch onto the current branch?
cherry-pick applique le diff d'un commit unique et crée un nouveau commit. Merge intègre toute la branche jusqu'à ce commit, rebase rejoue la branche courante ailleurs, checkout ne fait que se déplacer. cherry-pick applies the diff of a single commit and creates a new commit. Merge integrates the whole branch up to that commit, rebase replays the current branch elsewhere, checkout only moves you around.
Pourquoi ne faut-il pas rebaser une branche déjà poussée et utilisée par des collègues ? Why shouldn't you rebase a branch that's already pushed and used by colleagues?
Les collègues ont basé leur travail sur les anciens commits ; après votre rebase (et force push), leurs branches pointent sur un historique qui n'existe plus en amont — réconciliation pénible. Les anciens commits, eux, ne sont pas supprimés immédiatement. Colleagues based their work on the old commits; after your rebase (and force push), their branches point to a history that no longer exists upstream — painful reconciliation. The old commits themselves are not immediately deleted.
À quoi `git pull` est-il équivalent par défaut ? What is `git pull` equivalent to by default?
Par défaut, pull = fetch + merge, d'où les commits de merge parasites quand l'historique local a divergé. `git pull --rebase` (ou `pull.rebase=true`) rejoue vos commits locaux par-dessus le remote à la place. By default, pull = fetch + merge, hence the noisy merge commits when local history has diverged. `git pull --rebase` (or `pull.rebase=true`) replays your local commits on top of the remote instead.
Actu News La déferlante open-weight : Kimi K3, DeepSeek V4 et la semaine où tout s'est accéléré The open-weight wave: Kimi K3, DeepSeek V4 and the week everything sped up
Flashcards Flashcards
Quelle est la différence entre un modèle open-weight et un modèle open source ? What's the difference between an open-weight model and an open-source model?
Open-weight : les poids sont publiés — on peut télécharger, exécuter et fine-tuner le modèle. Open source au sens strict exigerait aussi le code et les données d'entraînement, souvent gardés fermés, et une licence sans restriction d'usage. Open-weight: the weights are published — you can download, run and fine-tune the model. Strict open source would also require the training code and data, which usually stay closed, and an unrestricted license.
Qu'est-ce qui a rendu la semaine du 20-27 juillet 2026 historique côté modèles ? What made the week of July 20-27, 2026 historic on the model front?
La plus grosse concentration de sorties open-weight jamais vue : Kimi K3 de Moonshot AI (2 800 milliards de paramètres, promis en poids ouverts, nº1 d'un leaderboard de code) et la version stable de DeepSeek V4 le 24 juillet. The largest concentration of open-weight releases ever seen: Moonshot AI's Kimi K3 (2.8 trillion parameters, open weights promised, #1 on a coding leaderboard) and DeepSeek V4's stable release on July 24.
Quand choisir un modèle open-weight plutôt qu'une API fermée en production ? When should you pick an open-weight model over a closed API in production?
Quand le volume rend l'API coûteuse, quand les données ne doivent pas sortir de l'infra (confidentialité, souveraineté), ou quand on veut fine-tuner. L'API fermée reste le choix rapide pour démarrer avec l'état de l'art sans infra. When volume makes the API expensive, when data must not leave your infra (confidentiality, sovereignty), or when you want to fine-tune. The closed API remains the fast path to state-of-the-art with zero infra.
Qu'est-ce que l'Open Secure AI Alliance annoncée cette semaine ? What is the Open Secure AI Alliance announced this week?
Une coalition de 37 acteurs menée par Nvidia (avec CrowdStrike, Hugging Face, Dell…) pour développer et partager des outils de sécurité des systèmes IA, avec le framework open source NOOA. Signe que la sécurité IA devient un enjeu d'industrie. A 37-member coalition led by Nvidia (with CrowdStrike, Hugging Face, Dell…) to build and share AI security tooling, alongside the open-source NOOA framework. A sign AI security is becoming an industry-wide concern.
QCM Quiz
Kimi K3, le modèle qui a pris la tête d'un leaderboard de code cette semaine, est développé par… Kimi K3, the model that topped a coding leaderboard this week, is built by…
Kimi K3 (2 800 milliards de paramètres) est le modèle du labo chinois Moonshot AI, dont les poids ouverts ont été promis pour le 27 juillet. Kimi K3 (2.8 trillion parameters) comes from Chinese lab Moonshot AI, with open weights promised for July 27.
Un modèle « open-weight » garantit que… An "open-weight" model guarantees that…
Seuls les poids sont garantis publics. Données, code d'entraînement et conditions d'usage commercial dépendent de chaque labo et de sa licence. Only the weights are guaranteed public. Data, training code and commercial terms depend on each lab and its license.
Quel chercheur célèbre a rejoint Anthropic cette semaine ? Which famous researcher joined Anthropic this week?
Andrej Karpathy (ex-OpenAI, ex-Tesla, connu pour ses cours) a annoncé rejoindre Anthropic pour travailler sur la frontière des LLM. Andrej Karpathy (ex-OpenAI, ex-Tesla, famous for his lectures) announced he's joining Anthropic to work on the LLM frontier.
Jour 1 Day 1 Docker & la conteneurisation Docker & containerization
Flashcards Flashcards
Quelle est la différence fondamentale entre un conteneur et une machine virtuelle ? What is the fundamental difference between a container and a virtual machine?
La VM virtualise du matériel et embarque un OS complet avec son propre noyau via un hyperviseur. Le conteneur est un simple processus isolé (namespaces + cgroups) qui partage le noyau de l'hôte : démarrage en millisecondes et overhead de quelques Mo, contre minutes et Go pour la VM. A VM virtualizes hardware and ships a full OS with its own kernel via a hypervisor. A container is just an isolated process (namespaces + cgroups) sharing the host kernel: millisecond startup and a few MB of overhead, versus minutes and GBs for a VM.
Quels mécanismes du noyau Linux rendent les conteneurs possibles ? Which Linux kernel mechanisms make containers possible?
Les namespaces (isolent ce que le processus voit : PID, réseau, montages, hostname…), les cgroups (limitent CPU/RAM/I/O) et un union filesystem comme OverlayFS (couches d'image en lecture seule + couche d'écriture éphémère). Namespaces (isolate what the process sees: PID, network, mounts, hostname…), cgroups (limit CPU/RAM/I/O) and a union filesystem like OverlayFS (read-only image layers + an ephemeral writable layer).
Quelle différence entre une image et un conteneur ? What's the difference between an image and a container?
L'image est le modèle immuable construit depuis un Dockerfile (comme une classe) ; le conteneur est une instance en cours d'exécution de cette image (comme un objet), avec sa couche d'écriture propre et éphémère. The image is the immutable template built from a Dockerfile (like a class); the container is a running instance of that image (like an object), with its own ephemeral writable layer.
Pourquoi et comment persister les données d'une base de données conteneurisée ? Why and how do you persist a containerized database's data?
La couche d'écriture du conteneur disparaît avec lui. On monte donc un volume nommé (ou un bind mount) sur le répertoire de données, ex. `-v pgdata:/var/lib/postgresql/data` : le volume survit aux recréations du conteneur et se sauvegarde indépendamment. The container's writable layer disappears with it. You mount a named volume (or bind mount) on the data directory, e.g. `-v pgdata:/var/lib/postgresql/data`: the volume outlives container recreations and can be backed up independently.
Qu'est-ce qu'un multi-stage build et pourquoi l'utiliser ? What is a multi-stage build and why use it?
Un Dockerfile avec plusieurs `FROM` : on compile dans une image lourde (SDK, outils de build) puis on copie uniquement l'artefact final dans une image runtime minimale. Résultat : image plus petite, plus rapide à distribuer, sans outils de build donc surface d'attaque réduite. A Dockerfile with several `FROM` stages: you compile in a heavy image (SDK, build tools) then copy only the final artifact into a minimal runtime image. Result: smaller image, faster to ship, no build tools inside so a reduced attack surface.
CMD vs ENTRYPOINT : quelle différence ? CMD vs ENTRYPOINT: what's the difference?
`ENTRYPOINT` définit l'exécutable fixe du conteneur ; `CMD` fournit ses arguments par défaut, remplaçables à l'exécution (`docker run image autre-arg`). Combinés : `ENTRYPOINT ["node"]` + `CMD ["server.js"]` lance `node server.js` par défaut. `ENTRYPOINT` sets the container's fixed executable; `CMD` provides its default arguments, overridable at run time (`docker run image other-arg`). Combined: `ENTRYPOINT ["node"]` + `CMD ["server.js"]` runs `node server.js` by default.
Comment deux conteneurs d'une même stack Compose communiquent-ils ? How do two containers in the same Compose stack communicate?
Ils sont placés sur un même réseau bridge dédié et se joignent par leur nom de service via le DNS interne de Docker (ex. `postgres:5432` depuis le conteneur applicatif). Pas besoin de publier les ports sur l'hôte pour la communication interne. They're placed on a dedicated bridge network and reach each other by service name through Docker's internal DNS (e.g. `postgres:5432` from the app container). No need to publish ports on the host for internal communication.
Pourquoi l'ordre des instructions dans un Dockerfile est-il important ? Why does the order of instructions in a Dockerfile matter?
Chaque instruction crée une couche mise en cache ; modifier une instruction invalide toutes les couches suivantes. On place donc les étapes stables en premier (installation des dépendances) et le code source en dernier, pour que `docker build` ne réinstalle pas tout à chaque changement de code. Each instruction creates a cached layer; changing one invalidates all subsequent layers. Put stable steps first (dependency installation) and source code last, so `docker build` doesn't reinstall everything on every code change.
QCM Quiz
Que partagent tous les conteneurs Docker tournant sur un même hôte Linux ? What do all Docker containers running on the same Linux host share?
Les conteneurs partagent le noyau de l'hôte — c'est ce qui les rend légers. Filesystem et espace PID sont isolés par conteneur, et il n'y a pas d'hyperviseur. Containers share the host kernel — that's what makes them lightweight. Filesystem and PID space are isolated per container, and there is no hypervisor.
Où finissent les données écrites dans un conteneur sans volume monté ? Where does data written in a container without a mounted volume end up?
Sans volume, tout va dans la couche d'écriture éphémère du conteneur : elle disparaît avec lui. L'image, elle, reste immuable. Without a volume, everything goes to the container's ephemeral writable layer, which disappears with it. The image itself stays immutable.
Que fait exactement `docker run -p 8080:80 nginx` ? What exactly does `docker run -p 8080:80 nginx` do?
La syntaxe est `-p <port-hôte>:<port-conteneur>`. Attention : par défaut c'est bindé sur 0.0.0.0, donc joignable depuis l'extérieur, en contournant UFW. The syntax is `-p <host-port>:<container-port>`. Careful: it binds to 0.0.0.0 by default, reachable from outside and bypassing UFW.
Quel est le risque principal du tag `latest` en production ? What is the main risk of the `latest` tag in production?
`latest` n'est qu'un tag par défaut que l'éditeur peut réécrire à tout moment : déploiements non reproductibles. En prod, on épingle une version, idéalement un digest. `latest` is just a default tag the publisher can rewrite at any time: non-reproducible deployments. In production, pin a version, ideally a digest.
Dans quel ordre le CLI Docker délègue-t-il l'exécution d'un conteneur ? In what order does the Docker CLI delegate container execution?
Le CLI parle au démon dockerd (API REST), qui délègue à containerd, qui invoque runc (runtime OCI) pour créer le processus isolé. D'où Kubernetes utilisant containerd sans Docker. The CLI talks to the dockerd daemon (REST API), which delegates to containerd, which invokes runc (OCI runtime) to create the isolated process. Hence Kubernetes using containerd without Docker.
Pourquoi copie-t-on package.json et lance-t-on `npm install` AVANT de copier le reste du code dans un Dockerfile Node ? Why copy package.json and run `npm install` BEFORE copying the rest of the code in a Node Dockerfile?
Le cache est invalidé couche par couche : si seul le code change, la couche `npm install` reste en cache et le build est quasi instantané. La taille finale, elle, ne change pas. The cache is invalidated layer by layer: if only the code changes, the `npm install` layer stays cached and the build is nearly instant. Final size is unchanged.