66 points par GN⁺ 2025-08-18 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Répertorie les pièges contre-intuitifs dans lesquels les développeurs tombent souvent, en présentant les causes de bugs susceptibles de se produire facilement
  • Traite des problèmes fréquents dans diverses technologies comme HTML, CSS, Unicode/l’encodage de texte, les nombres à virgule flottante et le temps
  • Souligne que des malentendus ou des erreurs peuvent naître de différences subtiles de syntaxe et de comportement selon les langages et les frameworks
  • Explique, à l’aide d’exemples, les pièges pouvant survenir en environnement réel dans des domaines clés du backend comme la concurrence, le réseau et les bases de données
  • À travers divers exemples et liens de référence, présente les situations problématiques, leurs solutions et des améliorations face à des comportements inattendus

HTML et CSS

  • Valeur par défaut de min-width dans Flexbox/Grid

    • min-width vaut par défaut auto
    • min-width: auto est déterminé par la taille du contenu et prévaut sur flex-shrink, overflow: hidden, width: 0, max-width: 100%
    • Recommandation : définir explicitement min-width: 0
  • Différence entre l’horizontal et le vertical en CSS

    • width: auto tente de remplir l’espace du parent, tandis que height: auto s’adapte au contenu
    • Pour les éléments inline, inline-block et float, width: auto ne s’étend pas
    • margin: 0 auto centre horizontalement, margin: auto 0 ne permet pas le centrage vertical (sauf avec flex-direction: column, où le centrage vertical est possible)
    • La fusion des marges ne se produit qu’à la verticale
    • Si la direction de mise en page change avec writing-mode: vertical-rl, par exemple, le comportement s’inverse également
  • Block Formatting Context (BFC)

    • Création d’un BFC avec display: flow-root (d’autres options existent aussi, comme overflow: hidden/auto/scroll ou display: table, mais avec des effets de bord)
    • Un BFC permet d’éviter le chevauchement des marges verticales entre éléments frères adjacents ou les marges des enfants qui débordent du parent
    • Si un parent ne contient que des enfants flottants, sa hauteur s’effondre à 0 → cela peut être corrigé avec un BFC
    • S’il y a une border ou un padding, la fusion des marges ne se produit pas
  • Stacking Context

    • Conditions qui créent un nouveau stacking context
      • Propriétés de rendu comme transform, filter, perspective, mask, opacity, etc.
      • position: fixed ou sticky
      • z-index défini + positionnement absolute/relative
      • z-index défini + élément à l’intérieur d’un conteneur flexbox/grid
      • isolation: isolate
    • Caractéristiques
      • z-index ne s’applique qu’à l’intérieur du stacking context
      • Les coordonnées de position: absolute/fixed sont calculées par rapport à l’ancêtre positionné le plus proche
      • sticky ne fonctionne pas au-delà d’un stacking context
      • Même avec overflow: visible, le contenu peut être rogné par un stacking context
      • background-attachment: fixed est positionné par rapport au stacking context
  • Unités de viewport

    • Sur les navigateurs mobiles, quand la barre d’adresse/la barre de navigation disparaît au défilement, la valeur de 100vh change
    • Solution moderne : utiliser 100dvh
  • Référence pour le positionnement absolu

    • position: absolute se base non pas sur le parent, mais sur l’ancêtre relative/absolute ou le stacking context le plus proche
  • Fonctionnement du blur

    • backdrop-filter: blur ne tient pas compte des éléments environnants
  • Annulation du float

    • Si le parent est en flex ou grid, le float des enfants n’a aucun effet
  • Unités en pourcentage pour width/height

    • Elles ne fonctionnent pas si la taille du parent n’est pas déterminée à l’avance (pour éviter les références circulaires)
  • Caractéristiques des éléments inline

    • display: inline ignore width, height, margin-top et margin-bottom
  • Gestion des espaces

    • Par défaut, les retours à la ligne en HTML sont traités comme des espaces, et les espaces consécutifs sont réduits à un seul
    • <pre> empêche cette réduction des espaces, mais son comportement au début et à la fin est particulier
    • Dans la plupart des cas, les espaces au début et à la fin du contenu sont ignorés, sauf pour <a>
    • Les espaces/retours à la ligne entre éléments inline-block sont affichés comme un espacement réel (ce qui n’arrive pas en flex/grid)
  • text-align

    • S’applique à l’alignement du texte et des éléments inline, mais pas à celui des éléments block
  • box-sizing

    • La valeur par défaut est content-boxpadding et border ne sont pas inclus
    • Avec width: 100% + padding, l’élément peut déborder de la zone du parent
    • Solution : box-sizing: border-box
  • Cumulative Layout Shift

    • Si les attributs width et height ne sont pas définis sur <img>, le chargement différé de l’image peut provoquer des décalages de mise en page
    • Recommandation : définir ces attributs pour éviter le CLS
  • Requêtes réseau de téléchargement de fichier dans Chrome

    • Elles n’apparaissent pas dans le panneau réseau de DevTools (elles sont traitées dans un autre onglet)
    • Si une analyse est nécessaire, utiliser chrome://net-export/
  • Problème d’analyse de JavaScript dans le HTML

    • Dans un cas comme <script>console.log('</script>')</script>, le premier </script> est interprété comme une balise de fermeture
    • Référence : Safe JSON in script tags

Unicode et encodage de texte

  • Points de code et clusters de graphèmes

    • Un cluster de graphèmes correspond à l’« unité de caractère » dans une interface graphique
    • Un caractère ASCII visible correspond à 1 point de code = 1 cluster de graphèmes
    • Un emoji peut être un seul cluster de graphèmes composé de plusieurs points de code
    • En UTF-8, un point de code occupe 1 à 4 octets, et le nombre d’octets ne correspond pas au nombre de points de code
    • En UTF-16, un point de code occupe 2 ou 4 octets (paire de substituts / surrogate pair)
    • La norme ne fixe pas de limite au nombre de points de code dans un cluster, mais les implémentations imposent souvent des limites pour des raisons de performance
  • Différences de comportement des chaînes selon les langages

    • Rust : les chaînes internes utilisent l’UTF-8, len() renvoie le nombre d’octets, l’indexation directe est impossible, chars().count() donne le nombre de points de code, la validité UTF-8 est vérifiée strictement
    • Golang : une chaîne est en pratique un tableau d’octets, la longueur et l’indexation se font en octets, l’UTF-8 est généralement utilisé
    • Java, C#, JS : basés sur l’UTF-16, la longueur est mesurée en unités de 2 octets et l’indexation se fait aussi sur cette base, avec présence de paires de substituts
    • Python : len() renvoie le nombre de points de code, et l’indexation renvoie une chaîne contenant un seul point de code
    • C++ : std::string n’impose aucune contrainte d’encodage, se comporte comme un vecteur d’octets, et la longueur/l’indexation se font en octets
    • Parmi les langages mentionnés, aucun ne mesure la longueur ni n’indexe au niveau des clusters de graphèmes
  • BOM (Byte Order Mark)

    • Certains fichiers texte contiennent un BOM, par exemple EF BB BF pour indiquer un encodage UTF-8
    • Il est principalement utilisé sous Windows, et des logiciels non-Windows peuvent ne pas le gérer correctement
  • Autres points d’attention

    • Lors de la conversion de données binaires en chaîne de caractères, les parties invalides sont remplacées par � (U+FFFD)
    • Existence de confusable characters (caractères qui se ressemblent)
    • Normalisation (Normalization) : par ex. é peut être représenté par U+00E9 (un seul point de code) ou U+0065+U+0301 (deux points de code)
    • Existence de zero-width characters et de invisible characters
    • Différences de fin de ligne : Windows utilise CRLF \r\n, Linux/MacOS utilise LF \n
    • Unification des Han (Han unification) : des caractères dont la forme diffère légèrement selon la langue utilisent le même point de code
      • Les polices intègrent des variantes par langue pour effectuer un rendu approprié
      • En internationalisation, il faut sélectionner la bonne variante de police

Virgule flottante (Floating point)

  • Propriétés de NaN

    • NaN n’est égal à aucune valeur, y compris lui-même (NaN == NaN est toujours false)
    • NaN != NaN est toujours true
    • Le résultat d’une opération impliquant NaN se propage le plus souvent en NaN
  • Valeurs spéciales

    • Existence de +Inf et -Inf, distincts de NaN
    • -0.0 est une valeur distincte de +0.0
      • Elles sont identiques dans les comparaisons, mais se comportent différemment dans certains calculs
      • Exemple : 1.0 / +0.0 == +Inf, 1.0 / -0.0 == -Inf
  • Compatibilité avec JSON

    • Le standard JSON n’autorise ni NaN ni Inf
      • En JS, JSON.stringify convertit NaN et Inf en null
      • En Python, json.dumps(...) affiche NaN et Infinity tels quels (non conforme au standard)
        • Avec l’option allow_nan=False, la présence de NaN/Inf provoque une ValueError
      • En Golang, json.Marshal renvoie une erreur si NaN/Inf sont présents
  • Problèmes de précision

    • Une comparaison directe de nombres à virgule flottante peut échouer → forme recommandée : abs(a - b) < ε
    • En JS, tous les nombres sont traités comme des nombres à virgule flottante
      • La plage des entiers sûrs est -(2^53 - 1) à 2^53 - 1
      • En dehors de cette plage, la représentation des entiers devient imprécise
      • Pour les grands entiers, l’usage de BigInt est recommandé
      • Si JSON contient des entiers au-delà de la plage sûre, les valeurs renvoyées par JSON.parse peuvent être imprécises
      • Les timestamps en millisecondes sont sûrs jusqu’en l’an 287396, ceux en nanosecondes posent problème
  • Lois de calcul non applicables

    • Selon l’ordre des opérations, la perte de précision fait que l’associativité et la distributivité ne sont pas rigoureusement vérifiées
    • Les calculs parallèles (multiplication de matrices, sommes, etc.) peuvent produire des résultats non déterministes
  • Performances

    • La division est bien plus lente que la multiplication
    • Lorsqu’on divise plusieurs fois par la même valeur, on peut optimiser en calculant d’abord l’inverse puis en multipliant
  • Différences selon le matériel

    • Prise en charge de FMA (Fused Multiply-Add) : certains matériels effectuent les calculs intermédiaires avec une précision plus élevée
    • Traitement de la plage subnormale : pris en charge par le matériel récent, mais parfois traité comme 0 sur certains anciens systèmes
    • Différences de mode d’arrondi
      • Il existe notamment RNTE (arrondi au pair le plus proche), RTZ (troncature vers 0), etc.
      • Sur x86/ARM, cela peut être configuré comme un état mutable local au thread
      • Sur GPU, le mode d’arrondi varie selon l’instruction
    • Différences de comportement des fonctions mathématiques comme les fonctions trigonométriques ou les logarithmes
    • x86 dispose d’un FPU historique en 80 bits et d’un rounding mode par cœur → utilisation déconseillée
    • De nombreux autres facteurs peuvent aussi faire varier les résultats en virgule flottante selon le matériel
  • Méthodes pour améliorer la précision

    • Garder un graphe de calcul peu profond (réduire les chaînes successives de multiplications)
    • Éviter les cas où les valeurs intermédiaires deviennent extrêmement grandes ou extrêmement petites
    • Exploiter des opérations matérielles comme FMA

Temps (Time)

  • Seconde intercalaire (Leap second)

    • Les timestamps Unix ignorent les secondes intercalaires
    • Lorsqu’une seconde intercalaire survient, le temps peut être allongé ou raccourci dans la zone voisine (Leap smear)
  • Fuseau horaire (Time zone)

    • UTC et les timestamps Unix sont communs à l’échelle mondiale
    • L’heure lisible par les humains dépend du fuseau horaire local
    • Il est recommandé de stocker les timestamps en base de données et d’effectuer la conversion dans l’UI
  • Heure d’été (DST)

    • Dans certaines régions, l’horloge est avancée d’une heure en été
  • Synchronisation NTP

    • Pendant la synchronisation, il est possible que le temps « recule »
  • Configuration du fuseau horaire du serveur

    • Il est recommandé de configurer les serveurs en UTC
    • Dans un système distribué, des fuseaux horaires différents entre nœuds peuvent poser problème
    • Après avoir modifié le fuseau horaire du système, il faut réinitialiser ou redémarrer la base de données
  • Horloge matérielle vs horloge système

    • L’horloge matérielle n’a pas de notion de fuseau horaire
    • Linux : traite l’horloge matérielle en UTC
    • Windows : traite l’horloge matérielle comme une heure locale

Java

  • == compare les références d’objet ; pour comparer le contenu d’un objet, il faut utiliser .equals
  • Si equals et hashcode ne sont pas redéfinis, l’identité des objets dans une map/set est évaluée sur la base de la référence
  • Si l’on modifie le contenu d’un objet servant de clé dans une map ou d’élément dans un set, le comportement du conteneur est cassé
  • Une méthode qui retourne List<T> peut, selon le cas, renvoyer un ArrayList mutable ou un Collections.emptyList() immutable ; modifier le second provoque une UnsupportedOperationException
  • Certaines méthodes censées retourner Optional<T> renvoient parfois null (ce qui n’est pas recommandé)
  • Si un return se trouve dans un bloc finally, l’exception survenue dans try ou catch est ignorée et c’est la valeur de retour du finally qui s’applique
  • Certaines bibliothèques ignorent les interruptions, et l’initialisation de classes, y compris avec des E/S, peut être perturbée par une interruption
  • Dans un thread pool, les exceptions d’une tâche passée via .submit() ne sont par défaut pas affichées dans les logs et ne sont consultables qu’au travers de la future ; si la future est ignorée, l’exception l’est aussi
    • Une tâche scheduleAtFixedRate s’arrête silencieusement si une exception se produit
  • Si un littéral numérique commence par 0, il est interprété en octal (0123 → 83)
  • Le débogueur appelle .toString() sur les variables locales ; certaines classes ont un toString() avec effets de bord, ce qui peut modifier le comportement du code pendant le débogage (désactivable dans l’IDE)

Golang

  • append() réutilise la mémoire si la capacité restante le permet ; un append sur un subslice peut donc écraser jusqu’à la mémoire du parent
  • defer s’exécute au retour de la fonction, pas à la fin d’un bloc de portée
  • defer capture les variables mutables
  • À propos de nil
    • un nil slice et un empty slice sont différents
    • une string ne peut pas être nil, seule la chaîne vide existe
    • une nil map peut être lue mais pas modifiée
    • comportement particulier de interface nil : si le pointeur de données est nul mais que les informations de type ne le sont pas, ce n’est pas égal à nil
  • Dead wait : il existe de vrais cas de bugs de concurrence en Go
  • Il existe de nombreux types de timeout, traités en détail dans net/http

C/C++

  • Si vous stockez un pointeur vers un élément de std::vector puis que le vector grandit, une réallocation peut se produire et invalider le pointeur
  • Un std::string créé à partir d’une chaîne littérale peut être un objet temporaire ; appeler c_str() peut alors être dangereux
  • Modifier un conteneur pendant son parcours peut invalider les itérateurs
  • std::remove ne supprime pas réellement les éléments ; il les réorganise, et il faut erase pour les supprimer
  • Si un littéral numérique commence par 0, il est traité comme un octal (0123 → 83)
  • Undefined behavior (UB) : pendant l’optimisation, un UB peut être transformé librement, il est donc dangereux d’en dépendre
    • Accéder à une mémoire non initialisée provoque un UB
    • Convertir un char* en pointeur de struct puis y accéder avant le début de vie de l’objet provoque un UB ; il est recommandé d’initialiser avec memcpy
    • Un accès mémoire invalide (pointeur null, etc.) provoque un UB
    • Un overflow/underflow entier provoque un UB (pour les types unsigned, un underflow en dessous de 0 est possible)
    • Aliasing : si des pointeurs de types différents référencent la même mémoire, la strict aliasing rule peut provoquer un UB
      • Exceptions : 1) types en relation d’héritage 2) conversion via char*, unsigned char*, std::byte* (la conversion inverse n’est pas concernée)
      • Pour les conversions forcées, memcpy ou std::bit_cast sont recommandés
    • Un accès à une mémoire non alignée provoque un UB
  • Alignment mémoire
    • Un entier 64 bits doit se trouver à une adresse divisible par 8
    • Sur ARM, un accès non aligné peut provoquer un crash
    • Interpréter directement un buffer d’octets comme une struct peut créer des problèmes d’alignement
    • L’alignement peut introduire du padding dans une struct et gaspiller de la mémoire
    • Certaines instructions SIMD (AVX, etc.) ne peuvent traiter que des données alignées ; un alignement de 32 octets est généralement nécessaire

Python

  • Les arguments par défaut d’une fonction ne sont pas recréés à chaque appel ; la valeur initiale est conservée telle quelle

SQL Databases

  • Gestion de Null

    • x = null ne fonctionne pas ; il faut utiliser x is null
    • Null n’est pas égal à lui-même (comme NaN)
    • Un index unique autorise les doublons de Null (sauf dans Microsoft SQL Server)
    • Dans select distinct, la manière de traiter Null varie selon la base de données
    • count(x) et count(distinct x) ignorent les lignes où la valeur est Null
  • Comportement général

    • Les conversions implicites de dates peuvent dépendre du fuseau horaire
    • Un join complexe avec distinct peut être plus lent qu’une requête imbriquée
    • Dans MySQL(InnoDB), si un champ texte n’est pas en utf8mb4, l’insertion d’un caractère UTF-8 sur 4 octets provoque une erreur
    • MySQL(InnoDB) est par défaut insensible à la casse
    • MySQL(InnoDB) autorise les conversions implicites : select '123abc' + 1; → 124
    • Les gap locks de MySQL(InnoDB) peuvent provoquer des deadlocks
    • Dans MySQL(InnoDB), si group by et les colonnes de select ne correspondent pas, le résultat peut être non déterministe
    • Dans SQLite, sauf en mode strict, le type des champs a peu d’importance
    • Les foreign keys peuvent créer des verrous implicites et provoquer des deadlocks
    • Le locking peut, selon la base, rompre l’isolation repeatable read
    • Les bases SQL distribuées peuvent ne pas prendre en charge le locking ou avoir un comportement particulier (variable selon la base)
  • Performance / exploitation

    • Le problème des requêtes N+1 n’apparaît pas dans les slow query logs, car chaque requête individuelle est rapide
    • Les transactions longues peuvent provoquer des problèmes de verrouillage ; il est donc recommandé de les terminer rapidement
    • Cas de verrouillage de table entière
      • Dans MySQL 8.0+, l’ajout d’un index unique ou d’une foreign key peut généralement se faire de manière concurrente
      • Les anciennes versions de MySQL peuvent verrouiller la table entière
      • Si mysqldump est utilisé sans l’option --single-transaction, un verrou de lecture sur la table entière est pris
      • Dans PostgreSQL, create unique index ou alter table ... add foreign key provoquent un verrou de lecture sur la table entière
        • Évitement : utiliser create unique index concurrently
        • Pour les foreign keys : utiliser ... not valid puis validate constraint
  • Requêtes par intervalle

    • Intervalles non chevauchants :
      • La condition simple p &gt;= start and p &lt;= end est inefficace (même avec un index composite)
      • Méthode efficace :
        select *   
        from (select ... from ranges where start &lt;= p order by start desc limit 1)   
        where end &gt;= p  
        
        (seul un index sur la colonne start est nécessaire)
    • Intervalles pouvant se chevaucher :
      • Inefficace avec un index B-tree classique
      • MySQL : index spatial recommandé ; PostgreSQL : GiST recommandé

Concurrency and Parallelism

  • volatile

    • volatile ne peut pas remplacer un lock et ne fournit pas l’atomicité
    • Les données protégées par un lock n’ont pas besoin de volatile (le lock garantit l’ordre mémoire)
    • En C/C++ : volatile empêche seulement certaines optimisations, sans ajouter de memory barrier
    • En Java : les accès volatile fournissent un sequentially-consistent ordering (la JVM insère si besoin des memory barriers)
    • En C# : les accès volatile fournissent un release-acquire ordering (le CLR insère si besoin des memory barriers)
    • Peut éviter certaines optimisations erronées liées au réordonnancement des lectures/écritures mémoire
  • Problème TOCTOU (Time-of-check to time-of-use)

  • Gestion des contraintes au niveau applicatif dans une base SQL

    • Lorsqu’une contrainte impossible à exprimer avec un simple index unique (par ex. unicité entre deux tables, unicité conditionnelle, unicité sur une période) est imposée par l’application :
      • MySQL(InnoDB) : au niveau repeatable read, faire select ... for update puis insert, et si la colonne unique est indexée, cela fonctionne grâce aux gap locks (mais les gap locks peuvent provoquer des deadlocks sous forte charge → détection de deadlock et retry nécessaires)
      • PostgreSQL : au niveau repeatable read, cette même logique est insuffisante en situation de concurrence (problème de write skew)
        • Solutions :
          • utiliser le niveau d’isolation serializable
          • utiliser des contraintes de base de données plutôt que l’application
            • unicité conditionnelle → partial unique index
            • unicité entre deux tables → insérer les données dupliquées dans une table séparée avec un unique index
            • exclusivité sur une période → range type + exclude constraint
  • Comptage de références atomique

    • Avec Arc, shared_ptr et similaires, si de nombreux threads modifient fréquemment le même compteur, les performances se dégradent
  • Read-write lock

    • Certaines implémentations ne prennent pas en charge l’upgrade d’un read lock en write lock
    • Tenter de prendre un write lock tout en détenant un read lock peut provoquer un deadlock

Common in many languages

  • L’oubli des vérifications Null/None/nil est une cause fréquente d’erreurs
  • Modifier un conteneur pendant une boucle peut provoquer une condition de concurrence sur les données en mono-thread
  • Erreur de partage de données mutables : ex. en Python, [[0] * 10] * 10 ne crée pas correctement un tableau 2D
  • (low + high) / 2 peut provoquer un overflow → la méthode sûre est low + (high - low) / 2
  • Évaluation courte (short circuit) : a() || b() n’exécute pas b si a vaut true, a() && b() n’exécute pas b si a vaut false
  • Par défaut, le profiler n’inclut que le temps CPU → les attentes DB, etc., n’apparaissent pas dans le flamegraph, ce qui peut induire en erreur
  • Le dialecte des expressions régulières diffère selon les langages → une regex qui fonctionne en JS peut ne pas fonctionner en Java

Linux and bash

  • Après un changement de répertoire, pwd peut afficher le chemin d’origine ; pour le chemin réel, utiliser pwd -P
  • cmd > file 2>&1 → stdout+stderr vont tous deux dans le fichier, cmd 2>&1 > file → seul stdout va dans le fichier, stderr reste inchangé
  • Les noms de fichiers sont sensibles à la casse (contrairement à Windows)
  • Les exécutables disposent d’un système de capabilities (vérifiable avec getcap)
  • Danger des variables non définies : si DIR n’est pas défini, rm -rf $DIR/ risque d’exécuter rm -rf / → on peut s’en prémunir avec set -u
  • Application de l’environnement : pour appliquer un script au shell courant, utiliser source script.sh → pour l’appliquer de façon permanente, l’ajouter à ~/.bashrc
  • Bash met les commandes en cache : si un fichier est déplacé dans $PATH, une erreur ENOENT peut se produire → rafraîchir le cache avec hash -r
  • Quand une variable non quotée est utilisée, les retours à la ligne sont traités comme des espaces
  • set -e : quitte immédiatement en cas d’erreur dans un script, mais ne fonctionne pas à l’intérieur des conditions (||, &&, if)
  • Conflit entre livenessProbe K8s et débogueur : un débogueur à points d’arrêt peut stopper toute l’application, empêchant les réponses aux health checks → le Pod peut être tué

React

  • Modifier directement le state dans le code de rendu
  • Utiliser un Hook dans un if/une boucle → violation des règles
  • Oublier des valeurs nécessaires dans le dependency array de useEffect
  • Oublier le code de nettoyage (clean up) dans useEffect
  • Piège des closures : des bugs apparaissent à cause de la capture d’un state obsolète
  • Modifier les données au mauvais endroit → composant impur
  • Oublier d’utiliser useCallback → provoque des rerenders inutiles
  • Passer une valeur non mémorisée à un composant mémorisé annule l’optimisation de memo

Git

  • Rebase réécrit l’historique

    • après un rebase, un push normal entre en conflit → il faut absolument faire un force push
    • si l’historique de la branche distante change, utiliser aussi --rebase pour le pull
    • --force-with-lease peut, dans certains cas, éviter d’écraser les commits d’un autre développeur, mais si on fait seulement fetch sans pull, cette protection ne fonctionne pas
  • Problème du revert de merge

    • un revert de merge a un effet incomplet → si on merge à nouveau la même branche, il n’y a aucun changement
    • solution : faire le revert du revert, ou employer une méthode propre (backup → reset → cherry-pick → force push)
  • Points d’attention liés à GitHub

    • même si un secret comme une clé API est écrasé par un force push après commit, GitHub en conserve une trace
    • si B est un fork privé du dépôt privé A, et que A devient public, le contenu de B devient lui aussi public (et peut rester accessible même après suppression)
  • git stash pop : en cas de conflit, le stash n’est pas supprimé

  • .DS_Store est créé automatiquement par macOS → il est recommandé d’ajouter **/.DS_Store à .gitignore

Networking

  • Certains routeurs et pare-feu coupent silencieusement les connexions TCP inactives → cela peut invalider les pools de connexions des clients HTTP et DB → solution : configurer TCP keepalive
  • Le résultat de traceroute est peu fiable → selon les cas, tcptraceroute peut être plus utile
  • Le TCP slow start peut augmenter la latence → on peut y remédier en désactivant tcp_slow_start_after_idle
  • Problème de sticky packets TCP : l’algorithme de Nagle retarde l’envoi des paquets → on peut y remédier en activant TCP_NODELAY
  • Quand un backend est placé derrière Nginx, il faut configurer la réutilisation des connexions → sinon, en forte charge, l’épuisement des ports internes peut provoquer des échecs de connexion
  • Nginx bufferise les paquets par défaut → cela peut retarder les SSE (EventSource)
  • Le standard HTTP n’interdit pas le body des requêtes GET et DELETE → certains l’utilisent, mais beaucoup de bibliothèques et serveurs ne le prennent pas en charge
  • Il est possible d’héberger plusieurs sites web sur une seule IP → la distinction est assurée par l’en-tête HTTP Host et le SNI de TLS → certains sites ne sont donc pas accessibles via une simple connexion par IP
  • CORS : lors d’une requête vers une autre origin, le navigateur bloque l’accès à la réponse → le serveur doit définir l’en-tête Access-Control-Allow-Origin
    • des réglages supplémentaires sont nécessaires si les cookies doivent être transmis
    • si le frontend et le backend utilisent le même domaine et le même port, il n’y a pas de problème de CORS

Other

  • Points d’attention YAML

    • YAML est sensible aux espaceskey:value est incorrect, key: value est correct
    • le code pays NO, écrit sans guillemets, peut être interprété comme false
    • un hash de commit Git écrit sans guillemets peut être converti en nombre
  • Problèmes de CSV avec Excel

    • Excel effectue des conversions automatiques à l’ouverture d’un CSV
      • conversion de date : 1/2, 1-22-Jan
      • conversion imprécise des grands nombres : 1234567890123456789012345678901234500000
    • la cause est qu’Excel traite les nombres en floating point en interne
    • ce problème a déjà conduit à une modification erronée du nom de gène SEPT1

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.