Les erreurs les plus embarrassantes de ma carrière de programmeur (jusqu'à présent)

Les erreurs les plus embarrassantes de ma carrière de programmeur (jusqu'à présent)
Comme on dit, si vous n'avez pas honte de votre ancien code, alors vous ne grandissez pas en tant que programmeur - et je suis d'accord avec cette opinion. J'ai commencé à programmer pour le plaisir il y a plus de 40 ans, et professionnellement il y a 30 ans, j'ai donc beaucoup d'erreurs. beaucoup. En tant que professeur d'informatique, j'apprends à mes étudiants à apprendre de leurs erreurs, les leurs, les miennes et celles des autres. Je pense qu'il est temps de parler de mes erreurs pour ne pas perdre ma pudeur. J'espère qu'ils seront utiles à quelqu'un.

Troisième place - Compilateur Microsoft C

Mon professeur d'école pensait que Roméo et Juliette ne pouvait pas être considéré comme une tragédie parce que les personnages n'avaient aucune culpabilité tragique - ils se comportaient simplement de manière stupide, comme devraient le faire les adolescents. Je n’étais pas d’accord avec lui à l’époque, mais maintenant je vois un grain de rationalité dans son opinion, notamment en ce qui concerne la programmation.

Au moment où j'ai terminé ma deuxième année au MIT, j'étais jeune et inexpérimenté, tant dans la vie qu'en programmation. Cet été, j'ai effectué un stage chez Microsoft, dans l'équipe du compilateur C. Au début, j'ai fait des choses de routine comme la prise en charge du profilage, puis on m'a chargé de travailler sur la partie la plus amusante du compilateur (comme je le pensais) : l'optimisation du backend. En particulier, j'ai dû améliorer le code x86 pour les instructions de branchement.

Déterminé à écrire le code machine optimal pour chaque cas possible, je me suis jeté tête baissée dans la piscine. Si la densité de distribution des valeurs était élevée, je les saisis table de transition. S'ils avaient un diviseur commun, je l'utilisais pour rendre le tableau plus serré (mais seulement si la division pouvait se faire en utilisant décalage de bits). Lorsque toutes les valeurs étaient des puissances de deux, j'ai fait une autre optimisation. Si un ensemble de valeurs ne satisfaisait pas à mes conditions, je le divisais en plusieurs cas optimisables et utilisais le code déjà optimisé.

C'était un cauchemar. Plusieurs années plus tard, on m'a dit que le programmeur qui avait hérité de mon code me détestait.

Les erreurs les plus embarrassantes de ma carrière de programmeur (jusqu'à présent)

Leçon apprise

Comme l'écrivent David Patterson et John Hennessy dans Computer Architecture and Computer Systems Design, l'un des principes fondamentaux de l'architecture et du design est de faire en sorte que les choses fonctionnent le plus rapidement possible.

L'accélération des cas courants améliorera les performances plus efficacement que l'optimisation des cas rares. Ironiquement, les cas courants sont souvent plus simples que les cas rares. Ce conseil logique suppose que vous sachiez quel cas est considéré comme courant – et cela n’est possible que grâce à un processus de tests et de mesures minutieux.

Pour ma défense, j'ai essayé de comprendre à quoi ressemblaient les instructions de branchement dans la pratique (par exemple, combien de branches il y avait et comment les constantes étaient distribuées), mais en 1988, cette information n'était pas disponible. Cependant, je n'aurais pas dû ajouter de cas particuliers lorsque le compilateur actuel ne pouvait pas générer de code optimal pour l'exemple artificiel que j'ai proposé.

J'avais besoin de faire appel à un développeur expérimenté et, avec lui, de réfléchir aux cas courants et de les traiter spécifiquement. J'écrirais moins de code, mais c'est une bonne chose. Comme l'a écrit Jeff Atwood, fondateur de Stack Overflow, le pire ennemi d'un programmeur est le programmeur lui-même :

Je sais que vous avez les meilleures intentions, comme nous tous. Nous créons des programmes et aimons écrire du code. C'est ainsi que nous sommes faits. Nous pensons que tout problème peut être résolu avec du ruban adhésif, une béquille faite maison et une pincée de code. Même si cela fait mal aux codeurs de l’admettre, le meilleur code est celui qui n’existe pas. Chaque nouvelle ligne a besoin d'être déboguée et supportée, elle doit être comprise. Lorsque vous ajoutez du nouveau code, vous devez le faire avec réticence et dégoût car toutes les autres options ont été épuisées. De nombreux programmeurs écrivent trop de code, ce qui en fait notre ennemi.

Si j'avais écrit un code plus simple couvrant les cas courants, il aurait été beaucoup plus facile de le mettre à jour si nécessaire. J’ai laissé derrière moi un désastre auquel personne ne voulait s’attaquer.

Les erreurs les plus embarrassantes de ma carrière de programmeur (jusqu'à présent)

Deuxième place : la publicité sur les réseaux sociaux

Lorsque je travaillais chez Google sur la publicité sur les réseaux sociaux (vous vous souvenez de Myspace ?), j'ai écrit quelque chose comme ceci en C++ :

for (int i = 0; i < user->interests->length(); i++) {
  for (int j = 0; j < user->interests(i)->keywords.length(); j++) {
      keywords->add(user->interests(i)->keywords(i)) {
  }
}

Les programmeurs peuvent immédiatement voir l'erreur : le dernier argument doit être j, pas i. Les tests unitaires n'ont pas révélé l'erreur, et mon critique non plus. Le lancement a été effectué et une nuit, mon code est allé sur le serveur et a fait planter tous les ordinateurs du centre de données.

Rien de grave n'est arrivé. Rien n'a été cassé pour personne, car avant le lancement mondial, le code a été testé dans un seul centre de données. À moins que les ingénieurs de SRE n'arrêtent de jouer au billard pendant un moment et fassent un petit retour en arrière. Le lendemain matin, j'ai reçu un e-mail avec un vidage sur incident, j'ai corrigé le code et ajouté des tests unitaires qui détecteraient l'erreur. Depuis que j'ai suivi le protocole - sinon mon code ne fonctionnerait tout simplement pas - il n'y a eu aucun autre problème.

Les erreurs les plus embarrassantes de ma carrière de programmeur (jusqu'à présent)

Leçon apprise

Beaucoup sont sûrs qu'une erreur aussi grave coûtera certainement le licenciement du coupable, mais ce n'est pas le cas : premièrement, tous les programmeurs font des erreurs, et deuxièmement, ils font rarement la même erreur deux fois.

En fait, j'ai un ami programmeur qui était un brillant ingénieur et qui a été licencié pour avoir commis une seule erreur. Après cela, il a été embauché chez Google (et bientôt promu) - il a honnêtement parlé de l'erreur qu'il a commise lors d'une interview, et cela n'a pas été considéré comme fatal.

Voilà ce que raconter à propos de Thomas Watson, le légendaire patron d'IBM :

Une commande gouvernementale d'une valeur d'environ un million de dollars a été annoncée. IBM Corporation - ou plutôt Thomas Watson Sr. personnellement - voulait vraiment l'obtenir. Malheureusement, le représentant commercial n'a pas pu le faire et IBM a perdu l'offre. Le lendemain, cet employé s'est présenté au bureau de M. Watson et a déposé une enveloppe sur son bureau. M. Watson n'a même pas pris la peine de la regarder : il attendait un employé et savait qu'il s'agissait d'une lettre de démission.

Watson a demandé ce qui n'allait pas.

Le représentant commercial a parlé en détail de l'avancement de l'appel d'offres. Il a cité des erreurs commises qui auraient pu être évitées. Finalement, il a dit : « M. Watson, merci de m'avoir laissé vous expliquer. Je sais à quel point nous avions besoin de cette commande. Je sais à quel point il était important », et il s'apprêtait à partir.

Watson s'est approché de lui à la porte, l'a regardé dans les yeux et lui a rendu l'enveloppe avec les mots : « Comment puis-je vous laisser partir ? Je viens d'investir un million de dollars dans ton éducation.

J’ai un T-shirt qui dit : « Si on apprend vraiment de ses erreurs, alors je suis déjà un maître. » En fait, en ce qui concerne les erreurs, je suis docteur en sciences.

Première place : API App Inventor

Des erreurs vraiment terribles affectent un grand nombre d'utilisateurs, deviennent publiques, prennent beaucoup de temps à être corrigées et sont commises par ceux qui n'auraient pas pu les commettre. Ma plus grosse erreur correspond à tous ces critères.

Le pire c'est le mieux

J'ai lu essai de Richard Gabriel J'ai parlé de cette approche dans les années XNUMX en tant qu'étudiant diplômé, et je l'aime tellement que je la pose à mes étudiants. Si vous ne vous en souvenez pas bien, rafraîchissez-vous la mémoire, c'est petit. Cet essai oppose le désir de « bien faire les choses » et l’approche « le pire est le mieux » de plusieurs manières, y compris la simplicité.

Comment cela devrait être : la conception doit être simple dans la mise en œuvre et l'interface. La simplicité de l'interface est plus importante que la simplicité de mise en œuvre.

Le pire sera le mieux : la conception doit être simple dans la mise en œuvre et l’interface. La simplicité de mise en œuvre est plus importante que la simplicité de l'interface.

Oublions ça un instant. Malheureusement, je l'ai oublié pendant de nombreuses années.

App Inventor

Lorsque je travaillais chez Google, je faisais partie de l'équipe App Inventor, un environnement de développement en ligne par glisser-déposer destiné aux futurs développeurs Android. C'était en 2009 et nous étions pressés de publier la version alpha à temps pour pouvoir organiser en été des master classes pour les enseignants qui pourraient utiliser l'environnement lorsqu'ils enseignent à l'automne. Je me suis porté volontaire pour implémenter des sprites, nostalgique de la façon dont j'écrivais des jeux sur la TI-99/4. Pour ceux qui ne le savent pas, un sprite est un objet graphique bidimensionnel qui peut se déplacer et interagir avec d'autres éléments logiciels. Des exemples de sprites incluent les vaisseaux spatiaux, les astéroïdes, les billes et les raquettes.

Nous avons implémenté App Inventor orienté objet en Java, il n'y a donc qu'un tas d'objets là-dedans. Étant donné que les balles et les sprites se comportent de manière très similaire, j'ai créé une classe de sprite abstraite avec les propriétés (champs) X, Y, Speed ​​​​(vitesse) et Heading (direction). Ils avaient les mêmes méthodes pour détecter les collisions, rebondir sur le bord de l'écran, etc.

La principale différence entre une balle et un sprite réside dans ce qui est exactement dessiné : un cercle rempli ou un raster. Depuis que j'ai d'abord implémenté les sprites, il était logique de spécifier les coordonnées x et y du coin supérieur gauche de l'endroit où se trouvait l'image.

Les erreurs les plus embarrassantes de ma carrière de programmeur (jusqu'à présent)
Une fois les sprites fonctionnels, j'ai décidé que je pouvais implémenter des objets boule avec très peu de code. Le seul problème était que j'ai choisi l'itinéraire le plus simple (du point de vue de l'exécutant), en indiquant les coordonnées x et y du coin supérieur gauche du contour encadrant la balle.

Les erreurs les plus embarrassantes de ma carrière de programmeur (jusqu'à présent)
En fait, il était nécessaire d’indiquer les coordonnées x et y du centre du cercle, comme l’enseigne tout manuel de mathématiques et toute autre source mentionnant les cercles.

Les erreurs les plus embarrassantes de ma carrière de programmeur (jusqu'à présent)
Contrairement à mes erreurs passées, celle-ci a affecté non seulement mes collègues, mais également des millions d'utilisateurs d'App Inventor. Beaucoup d’entre eux étaient des enfants ou complètement nouveaux dans la programmation. Ils ont dû effectuer de nombreuses étapes inutiles lors du travail sur chaque application dans laquelle la balle était présente. Si je me souviens de mes autres erreurs en riant, alors celle-ci me fait transpirer encore aujourd'hui.

J'ai finalement corrigé ce bug récemment, dix ans plus tard. « Patchées », et non « corrigées », car comme le dit Joshua Bloch, les API sont éternelles. Impossible d'apporter des modifications qui affecteraient les programmes existants, nous avons ajouté la propriété OriginAtCenter avec la valeur false dans les anciens programmes et true dans tous les futurs. Les utilisateurs peuvent se poser une question logique : qui a même pensé à placer le point de départ ailleurs que dans le centre ? À qui? À un programmeur qui était trop paresseux pour créer une API normale il y a dix ans.

Leçons apprises

Lorsque vous travaillez sur des API (ce que presque tous les programmeurs doivent faire parfois), vous devez suivre les meilleurs conseils décrits dans la vidéo de Joshua Bloch "Comment créer une bonne API et pourquoi c'est si important"Ou dans cette courte liste:

  • Une API peut vous apporter à la fois de grands avantages et de grands inconvénients.. Une bonne API crée des clients fidèles. Le mauvais devient votre éternel cauchemar.
  • Les API publiques, comme les diamants, durent éternellement. Donnez tout : vous n’aurez plus jamais l’occasion de tout faire correctement.
  • Les grandes lignes de l'API doivent être brèves — une page avec les signatures et descriptions des classes et des méthodes, n'occupant pas plus d'une ligne. Cela vous permettra de restructurer facilement l'API si elle ne s'avère pas parfaite du premier coup.
  • Décrire les cas d'utilisationavant d'implémenter l'API ou même de travailler sur sa spécification. De cette façon, vous éviterez d’implémenter et de spécifier une API totalement non fonctionnelle.

Si j'avais écrit ne serait-ce qu'un bref résumé avec un script artificiel, j'aurais probablement identifié l'erreur et l'aurais corrigée. Sinon, un de mes collègues le ferait certainement. Toute décision ayant des conséquences considérables doit être réfléchie pendant au moins une journée (cela ne s'applique pas seulement à la programmation).

Le titre de l'essai de Richard Gabriel, « Pire, c'est mieux », fait référence à l'avantage d'être le premier sur le marché, même avec un produit imparfait, pendant que quelqu'un d'autre passe une éternité à rechercher le produit parfait. En réfléchissant au code du sprite, je me rends compte que je n'ai même pas eu besoin d'écrire plus de code pour bien faire les choses. Quoi qu’on en dise, je me trompais lourdement.

Conclusion

Les programmeurs font des erreurs tous les jours, qu'il s'agisse d'écrire du code bogué ou de ne pas vouloir essayer quelque chose qui améliorerait leurs compétences et leur productivité. Bien sûr, vous pouvez être programmeur sans commettre d’erreurs aussi graves que moi. Mais il est impossible de devenir un bon programmeur sans reconnaître ses erreurs et en tirer des leçons.

Je rencontre constamment des étudiants qui ont l'impression de faire trop d'erreurs et qui ne sont donc pas faits pour la programmation. Je sais à quel point le syndrome de l’imposteur est courant en informatique. J'espère que vous apprendrez les leçons que j'ai énumérées - mais rappelez-vous la principale : chacun de nous fait des erreurs - embarrassantes, drôles, terribles. Je serai surpris et contrarié si à l'avenir je n'ai pas assez de matériel pour continuer l'article.

Source: habr.com

Ajouter un commentaire