Les erreurs les plus honteuses de ma carrière de programmeur (en ce moment)


Comme dit le proverbe, 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 divertissement il y a plus de 40 ans, et il y a 30 ans professionnellement, donc j'ai eu beaucoup d' erreurs. En tant que professeur d'informatique, j'enseigne à mes étudiants comment apprendre des erreurs - les leurs, les miennes, les inconnues. Je pense qu'il est temps de parler de mes erreurs pour ne pas perdre la modestie. J'espère que quelqu'un le trouvera utile.

Troisième place - compilateur Microsoft C


Mon professeur d'école croyait que «Roméo et Juliette» ne pouvait pas être considéré comme une tragédie, parce que les héros n'avaient pas de culpabilité tragique - ils se comportaient simplement stupidement, comme le devraient les adolescents. Ensuite, je n'étais pas d'accord avec lui, mais maintenant je vois à son avis un noyau rationnel - en particulier 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 que dans la programmation. L'été, j'ai fait un stage chez Microsoft, dans l'équipe du compilateur C. Au début, j'étais engagé dans une routine comme le support de profilage, puis on m'a confié le travail sur la partie la plus amusante (comme je le pensais) du compilateur - 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 précipité dans la piscine avec ma tête. Si la densité de distribution des valeurs était élevée, je les ai inscrites dans la table de transition . S'ils avaient un diviseur commun, je l'ai utilisé pour rendre la table plus dense (mais seulement si la division pouvait être effectuée en utilisant un décalage de bits ). Lorsque toutes les valeurs étaient des puissances de deux, j'ai effectué une autre optimisation. Si l'ensemble de valeurs ne satisfaisait pas à mes conditions, je l'ai divisé en plusieurs cas optimisables et utilisé le code déjà optimisé.

C'était un cauchemar. Après de nombreuses années, ils m'ont dit que le programmeur qui avait hérité de mon code me détestait.


Leçon apprise


Comme David Patterson et John Hennessy l'écrivent dans le livre Architecture informatique et conception de systèmes informatiques, l'un des grands principes de l'architecture et du développement est qu'en général, tout fonctionne le plus rapidement possible.

L'accélération des cas courants augmentera la productivité plus efficacement que l'optimisation des cas rares. Ironiquement, les cas courants sont souvent plus simples que rares. Ce conseil logique implique que vous sachiez quel cas considérer comme courant - et cela n'est possible que par des tests et des mesures minutieux.

Pour ma défense, je peux dire que j'ai essayé de comprendre à quoi ressemblaient les opérateurs de branchement dans la pratique (par exemple, combien de branches existaient 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 chaque fois que le compilateur actuel ne pouvait pas générer le code optimal pour l'exemple artificiel que j'ai trouvé.

J'avais besoin d'appeler un développeur expérimenté et de penser avec lui quels étaient les cas les plus courants, et de m'occuper spécifiquement d'eux. J'écrirais moins de code, mais c'est encore bien. Comme l’a écrit le fondateur de Stack Overflow, Jeff Atwood, le pire ennemi du programmeur est le programmeur:

Je sais que vous avez les meilleures intentions, comme nous tous. Nous créons des programmes et aimons écrire du code. Nous sommes donc arrangés. Nous pensons que tout problème peut être résolu avec du ruban adhésif, une béquille maison et une pincée de code. Peu importe combien il est douloureux pour les codeurs de l'admettre, le meilleur code est ce code qui n'existe pas. Chaque nouvelle ligne nécessite un débogage et un support, elle doit être comprise. Lorsque vous ajoutez un 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'écrivais du code plus simple couvrant des cas courants, il serait beaucoup plus facile de le mettre à jour si nécessaire. J'ai laissé un désordre avec lequel personne ne voulait jouer.


Deuxième place: publicité sur les médias sociaux


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

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é d'erreur, et mon critique ne l'a pas remarqué. Un 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.

Il ne s'est rien passé de terrible. Aucun d'entre eux ne s'est cassé, car avant le lancement mondial, le code a été testé dans le même centre de données. À moins que les ingénieurs de SRE arrêtent de jouer au billard pendant une courte période et fassent un petit retour en arrière. Le lendemain matin, j'ai reçu un e-mail avec un vidage sur incident, corrigé le code et ajouté des tests unitaires qui révéleraient une erreur. Depuis que j'ai suivi le protocole - sinon mon code n'aurait tout simplement pas fonctionné - il n'y a pas eu d'autres problèmes.


Leçon apprise


Beaucoup sont convaincus qu'une telle erreur majeure est nécessairement le coupable du licenciement, mais ce n'est pas le cas: premièrement, tous les programmeurs ont tort, et deuxièmement, ils font rarement une erreur deux fois.

En fait, j'ai un programmeur familier - un ingénieur brillant, qui a été licencié pour une seule erreur. Après cela, il a été embauché par Google (et bientôt promu) - il a honnêtement parlé de l'erreur commise lors de l'interview, et elle n'a pas été considérée comme fatale.

Voici ce que Thomas Watson, le chef légendaire d'IBM, a à dire:

Un décret du gouvernement d'une valeur d'environ un million de dollars a été annoncé. IBM Corporation - ou plutôt, personnellement Thomas Watson Sr. - voulait vraiment l'obtenir. Malheureusement, le représentant des ventes n'a pas pu le faire et IBM a perdu l'appel d'offres. Le lendemain, cet agent est venu au bureau de M. Watson et a mis une enveloppe sur son bureau. M. Watson ne l'a même pas examiné - 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 décrit en détail l'avancement de l'appel d'offres. Il a appelé les erreurs qui auraient pu être évitées. Enfin, il a déclaré: «Monsieur Watson, merci de m'avoir laissé m'expliquer. Je sais combien nous avions besoin de cette commande. Je sais à quel point il était important »et était sur le point de partir.

Watson s'approcha de lui à la porte, le regarda dans les yeux et retourna l'enveloppe avec les mots: «Comment puis-je te laisser partir? Je viens d'investir un million de dollars dans ton éducation.

J'ai un T-shirt qui dit: "Si vous apprenez vraiment des 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 effrayantes affectent un grand nombre d'utilisateurs, deviennent publiques, sont corrigées depuis longtemps et faites par ceux qui ne pouvaient pas les autoriser. Ma plus grosse erreur satisfait à tous ces critères.

Le pire c'est le mieux


J'ai lu l ' essai de Richard Gabriel sur cette approche dans les années 90 en tant qu'étudiant diplômé, et je l' aime tellement que je le pose à mes étudiants. Si vous ne vous en souvenez pas bien, rafraîchissez votre mémoire, c'est petit. Dans cet essai, le désir de «bien faire les choses» et l'approche «le pire est le mieux» sont contrastés à bien des égards, y compris la simplicité.

Comme il se doit: la conception doit être facile à mettre en œuvre et à interfacer. La simplicité de l'interface est plus importante que la simplicité de mise en œuvre.

Le pire, 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.

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

Inventeur d'applications


Pendant mon séjour chez Google, je faisais partie de l'équipe App Inventor , un environnement de développement en ligne avec prise en charge par glisser-déposer pour les développeurs Android débutants. C'était en 2009, et nous étions pressés de publier la version alpha à temps, afin qu'en été, nous puissions organiser des cours de maître pour les enseignants qui pourraient utiliser l'environnement d'apprentissage à l'automne. Je me suis porté volontaire pour implémenter des sprites, nostalgique de la façon dont j'écrivais des jeux sur TI-99/4. Pour ceux qui ne sont pas au courant: un sprite est un objet graphique bidimensionnel qui peut se déplacer et interagir avec d'autres éléments du programme. Des exemples de sprites sont les vaisseaux spatiaux, les astéroïdes, les balles et les raquettes.

Nous avons implémenté App Inventor orienté objet en Java, il n'y a donc qu'un tas d'objets. Comme les boules et les sprites se comportent de manière très similaire, j'ai créé une classe de sprites 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 la bordure de l'écran, etc.

La principale différence entre la balle et le sprite est exactement ce qui est dessiné - un cercle rempli ou une trame. Depuis que j'ai implémenté les sprites pour la première fois, il était logique de spécifier les coordonnées x et y du coin supérieur gauche de l'endroit où l'image était située.


Lorsque les sprites ont commencé à fonctionner, j'ai décidé que vous pouviez implémenter des objets ball avec très peu de code. Le seul problème était que je suis allé de la manière la plus simple (du point de vue de l'implémenteur), en indiquant les coordonnées x et y du coin supérieur gauche du contour entourant la balle.


En fait, il était nécessaire d'indiquer les coordonnées x et y du centre du cercle, comme l'enseignent tout manuel de mathématiques et toute autre source mentionnant les cercles.


Contrairement à mes erreurs passées, non seulement mes collègues, mais aussi des millions d'utilisateurs d'App Inventor en ont souffert. Beaucoup d'entre eux étaient des enfants ou complètement nouveaux en programmation. Ils devaient effectuer de nombreuses actions inutiles lorsqu'ils travaillaient sur chaque application dans laquelle la balle était présente. Si je me souviens du reste de mes erreurs en riant, cela me fait transpirer aujourd'hui.

J'ai finalement corrigé cette erreur récemment, dix ans plus tard. "Correctif", mais pas "corrigé", car comme le dit Joshua Bloch, les API sont éternelles. Impossible d'apporter des modifications qui pourraient affecter les programmes existants, nous avons ajouté la propriété OriginAtCenter avec false dans les anciens programmes et true dans tous les futurs. Les utilisateurs peuvent poser une question légitime à qui a pensé à quiconque de localiser un point de référence 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 une API (ce que presque tous les programmeurs doivent parfois faire), vous devez suivre les meilleurs conseils décrits dans la vidéo de Joshua Bloch « Comment créer une bonne API et pourquoi elle est si importante » ou dans cette courte liste :

  • L'API peut être très bénéfique pour vous, ainsi que de grands dommages . Une bonne API crée des clients fidèles. Le mal devient votre cauchemar éternel.
  • Les API publiques, comme les diamants, sont éternelles . Faites de votre mieux: il n'y a aucune autre chance de tout faire comme il se doit.
  • Les horaires de l'API doivent être courts - une page avec des signatures et des descriptions de classe et de méthode qui ne prennent pas plus d'une ligne. Cela vous permettra de restructurer facilement l'API, si la première fois elle sort pas parfaite.
  • Décrivez les scénarios d'utilisation avant d'implémenter l'API et travaillez même sur ses spécifications. De cette façon, vous évitez la mise en œuvre et la spécification d'une API entièrement non fonctionnelle.

Si j'avais écrit au moins un petit synopsis avec un script artificiel, j'aurais probablement identifié une erreur et corrigé. Sinon, un de mes collègues le ferait certainement. Toute décision qui a des conséquences profondes doit être considérée au moins une journée (cela ne s'applique pas seulement à la programmation).

Le titre de l'essai de Richard Gabriel, «Le pire, le meilleur», indique l'avantage qui vient en premier sur le marché - même avec un produit imparfait - tandis que quelqu'un d'autre poursuit l'idéal depuis des lustres. En pensant au code sprite, je comprends que je n'ai même pas eu à écrire plus de code pour tout faire comme il se doit. Qu'on le veuille ou non, je me suis grossièrement trompé.

Conclusion


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

Je rencontre constamment des étudiants qui pensent qu'ils font trop d'erreurs et ne sont donc pas conçus pour la programmation. Je sais à quel point le syndrome d'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 - honteux, drôle, effrayant. Je serai surpris et bouleversé si à l’avenir je n’ai pas assez de matériel pour continuer l’article.

Source: https://habr.com/ru/post/fr475662/


All Articles