III-A-1. Comment rester motivé▲

Il est merveilleux et surprenant que les programmeurs soient si motivés par le désir de créer des artefacts beaux, utiles ou astucieux. Ce désir n'est pas propre aux programmeurs, ni universel, mais il est si fort et commun chez les programmeurs qu'il les distingue des autres. Cela a des conséquences pratiques et importantes. Si on demande aux programmeurs de faire quelque chose qui n’est pas beau, utile ou astucieux, ils auront le moral en berne. Il y a beaucoup d'argent à gagner en faisant des choses laides, stupides et ennuyeuses. Mais finalement, le plaisir rapportera davantage d’argent à la société. Il y a évidemment des industries entières organisées autour de techniques de motivation, dont certaines s'appliquent ici. Les éléments spécifiques à la programmation que je peux identifier sont : utiliser le meilleur langage pour le travail ;

chercher les opportunités pour appliquer de nouvelles techniques, langages et technologies ;

essayer d’apprendre ou d’enseigner quelque chose, aussi petite soit-elle, dans chaque projet. Enfin, si possible, mesurez l’impact de votre travail sur quelque chose de personnellement motivant. Par exemple, lors de la correction de bogues, compter le nombre de ceux-ci que j’ai corrigés et qui ne me motivent pas du tout, car cela est indépendant du nombre de problèmes pouvant encore exister et affecte faiblement la valeur totale ajoutée pour les clients de mon entreprise. Relier chaque bogue à un client heureux est toutefois pour moi une motivation personnelle.

III-A-2. Comment être digne de confiance▲

Pour être cru, vous devez être digne de confiance. Vous devez aussi être visible. Si personne ne vous connaît, aucune confiance ne vous sera faite. Avec vos proches, tels que vos coéquipiers, cela ne devrait pas être un problème. Vous établissez une relation de confiance en étant réactif et informatif envers les personnes extérieures à votre département ou à votre équipe. Parfois, quelqu'un abusera de cette confiance et demandera des faveurs déraisonnables. N'ayez pas peur de cela, expliquez simplement ce que vous devez abandonner pour rendre le service. Ne prétendez pas savoir quelque chose que vous ne savez pas. Avec des personnes qui ne sont pas de votre équipe, vous devrez peut-être faire une distinction claire entre « ne pas savoir tout de suite » et « ne pas être capable de le comprendre, jamais ».

III-A-3. Comment concilier temps et espace▲

Vous pouvez être un bon programmeur sans être allé à l’université, mais vous ne pouvez pas être un bon programmeur intermédiaire sans connaître la théorie de base de la complexité informatique. Vous n’avez pas besoin de connaître la notation « Big O » (comparaison asymptotique), mais je pense personnellement que vous devriez comprendre la différence entre « temps constant », « n log n » et « kitxmlcodeinlinelatexdvpn^2finkitxmlcodeinlinelatexdvp ». Vous pourrez peut-être concilier le temps et l’espace sans cette connaissance, mais en son absence, vous ne disposerez pas d’une base solide pour communiquer avec vos collègues. Lors de la conception ou de la compréhension d’un algorithme, le temps nécessaire à son exécution dépend parfois de la taille de l’entrée. Quand cela est vrai, nous pouvons dire que la durée d'exécution la plus défavorable, attendue, dans le meilleur des cas, d'un algorithme est « n log n » si elle est proportionnelle à la taille ($ n $) fois le logarithme de la taille. La notation et la manière de l’évoquer peuvent également être appliquées à l’espace occupé par une structure de données. Pour moi, la théorie de la complexité informatique est belle et aussi profonde que la physique, et va un peu plus loin. Le temps (en cycles du processeur) et l’espace (mémoire) peuvent être échangés l’un contre l’autre. L'ingénierie est un compromis, et c'est un bon exemple. Ce n’est pas toujours systématique. En général, on peut gagner de la place en encodant les choses plus finement, au détriment du temps de calcul lors du décodage. Vous pouvez gagner du temps en mettant en cache, c’est-à-dire en prenant de l’espace pour stocker une copie locale de quelque chose, au détriment de la nécessité de maintenir la cohérence de celui-ci. Vous pouvez parfois gagner du temps en conservant plus d’informations dans une structure de données. Cela coûte généralement peu d’espace, mais peut compliquer l’algorithme. L’amélioration du compromis espace/temps peut souvent modifier l’un ou l’autre dramatiquement. Néanmoins, avant de travailler dessus, vous devriez vous demander si ce que vous améliorez est vraiment l’élément qui nécessite le plus d’amélioration. Il est amusant de travailler sur un algorithme, mais vous ne pouvez pas vous laisser aveugler par le fait que l'amélioration de quelque chose qui ne pose pas de problème ne fera aucune différence notable et créera une charge de test. La mémoire des ordinateurs modernes semble bon marché, car contrairement au temps de traitement du processeur, vous ne pouvez pas la voir être utilisée tant que vous n’avez pas heurté le mur, mais alors l'échec est catastrophique. L’utilisation de la mémoire entraîne également d'autres coûts cachés, comme les effets sur les autres programmes qui doivent rester résidents, ainsi que le temps pour l’allouer et la désallouer. Considérez ceci avec précaution avant d’échanger de l’espace pour gagner de la vitesse.

III-A-4. Comment faire des tests de stress▲

Le test de stress est amusant. Il semble en premier lieu que l’objectif est de vérifier si le système fonctionne sous une charge donnée. En réalité, il est courant que le système fonctionne sous une charge donnée, mais défaille d’une manière ou d’une autre lorsque la charge est suffisamment importante. J’appelle cela « aller dans le mur » ou « faire du bonking (1)». Il peut y avoir des exceptions, mais il y a presque toujours un « mur ». L’objectif de ces tests de stress est de cibler où se trouve le mur, puis alors de déterminer comment le repousser plus loin. Un plan de test de stress devrait être élaboré tôt dans le projet, car cela aide souvent à clarifier les attentes. Deux secondes pour une requête de page web, est-ce un échec misérable ou un succès fracassant ? 500 utilisateurs simultanés suffisent-ils ? Cela dépend, bien entendu, mais il faut connaître la réponse lors de la conception du système qui répond à la demande. Le test de stress doit être assez conforme à la réalité pour être utile. Il n’est pas vraiment possible de simuler facilement 500 humains erratiques et imprévisibles utilisant un système simultanément, mais on peut au moins créer 500 simulations et essayer de modéliser une partie de ce que ces humains pourraient faire. Lors d’un test de stress, commencez avec une charge légère et chargez selon certaines dimensions, comme un taux d’entrée ou une taille d’entrée, jusqu’à ce que vous « heurtiez le mur ». Si le mur est trop proche pour répondre à vos besoins, ciblez la ressource qui constitue le goulot d’étranglement (il y en a généralement une dominante). Est-ce la mémoire, le processeur, les E/S, le réseau, la bande passante, ou une contention des données ? Ensuite, déterminez comment vous pouvez déplacer le mur. Notez que le déplacement du mur, c’est-à-dire l’augmentation de la charge maximale que le système peut supporter, peut ne pas aider ou pourrait nuire aux performances d’un système peu chargé. Habituellement, la performance sous charge lourde est plus importante que la performance sous charge légère. Vous devrez peut-être avoir de la visibilité dans différentes dimensions pour en construire un modèle mental, aucune technique n’est suffisante. Par exemple, la journalisation donne souvent une bonne idée du temps entre deux événements dans le système, mais si elle n'est pas soigneusement construite, elle ne donne aucune visibilité sur l’utilisation de la mémoire ni même la taille de la structure de données. De même, dans un système moderne, plusieurs ordinateurs et de nombreux systèmes logiciels peuvent coopérer. En particulier lorsque vous frappez le mur (c’est-à-dire que les performances ne sont pas linéaires en termes de taille de l’entrée), ces autres systèmes logiciels peuvent constituer un goulot d’étranglement. La visibilité dans ces systèmes, même si vous ne mesurez que la charge du processeur sur toutes les machines participantes, peut être très utile. Savoir où se trouve le mur est essentiel, pas seulement pour le déplacer, mais aussi pour assurer la prévisibilité afin que le travail puisse être géré efficacement.

III-A-5. Comment équilibrer la brièveté et l'abstraction▲

L’abstraction est la clé de la programmation. Vous devez choisir avec soin le degré d’abstraction dont vous avez besoin. Les programmeurs débutants, avec leur enthousiasme, créent souvent plus d’abstraction qu’il n’en est vraiment utile. Un signe de cela est si vous créez des classes qui ne contiennent pas vraiment de code et ne font vraiment rien sauf servir à abstraire quelque chose. Cette attraction est compréhensible, mais la valeur de la brièveté du code doit être comparée à la valeur de l’abstraction. De temps en temps, on constate une erreur commise par des idéalistes enthousiastes : au début du projet, de nombreuses classes sont définies, ce qui semble merveilleusement abstrait, et on peut penser qu’elles géreront toutes les éventualités qui pourraient survenir. Au fur et à mesure que le projet progresse et que la fatigue s’installe, le code lui-même devient désordonné. Les corps des fonctions deviennent plus longs qu’ils ne devraient l’être. Les classes vides sont un fardeau à documenter, ce qui est ignoré lorsqu’on est sous pression. Le résultat final aurait été meilleur si l’énergie dépensée pour l’abstraction avait été dépensée pour conserver les choses courtes et simples. C'est une forme de programmation spéculative. Je recommande fortement cet article : Succinctness is Power par Paul Graham. Il existe un certain dogme associé à des techniques utiles comme la dissimulation de l’information et la programmation orientée objet qui sont parfois poussées trop loin. Ces techniques permettent de coder de manière abstraite et d’anticiper les changements. Cependant, je pense personnellement que vous ne devriez pas produire beaucoup de code spéculatif. Par exemple, il est un style accepté de cacher une variable de type entier sur un objet derrière des mutateurs et accesseurs, de sorte que la variable elle-même ne soit pas exposée, mais uniquement l’interface pour y accéder. Ceci permet le changement de l’implémentation de cette variable sans affecter le code d’appel, et est peut-être approprié à un programmeur de bibliothèques qui doit publier une API très stable. Mais je ne pense pas que le bénéfice de cette opération l'emporte sur le coût de la verbosité quand mon équipe détient le code d’appel et peut de ce fait recoder l’appelant aussi facilement que l’appelé. Quatre ou cinq lignes de code supplémentaires sont un lourd poids à payer pour ce bénéfice hypothétique. La portabilité pose un problème similaire. Le code doit-il être portable sur un autre ordinateur, compilateur, système applicatif ou plate-forme, ou simplement être facilement porté ? Je pense qu’un morceau de code non portable, court et facile à porter est meilleur qu’un long code portable. Il est relativement facile et certainement une bonne idée de confiner le code non portable dans un emplacement spécifique, comme une classe qui effectue des requêtes de base de données spécifiques à un SGBD donné.

III-A-6. Comment apprendre de nouvelles compétences▲

Apprendre de nouvelles compétences, en particulier non techniques, est le plus amusant de tout. La plupart des entreprises auraient une meilleure ambiance si elles comprenaient à quel point ceci motive les programmeurs. Les humains apprennent en faisant. La lecture de livre et les cours sont utiles. Mais pourriez-vous avoir du respect pour un programmeur qui n‘avait jamais écrit un programme ? Pour apprendre une compétence, vous devez vous mettre dans une position indulgente où vous pourrez exercer cette compétence. Quand vous apprenez un nouveau langage de programmation, essayez de faire un petit projet dans ce langage avant de devoir faire un grand projet. Lorsque vous apprenez à gérer un projet logiciel, essayez d’abord d’en gérer un petit. Un bon mentor n’est pas un substitut pour faire les choses soi-même, mais c’est beaucoup mieux qu’un livre. Que pouvez-vous offrir à un mentor potentiel en échange de son savoir ? Au minimum, vous devriez proposer d’étudier durement de sorte que son temps ne soit pas gaspillé. Essayez de demander à votre chef de vous laisser suivre une formation formelle, mais comprenez que ce n'est souvent pas mieux que le même temps passé à jouer simplement avec la nouvelle compétence que vous voulez apprendre. Dans notre monde imparfait, il est cependant plus facile de demander une formation que du temps pour jouer, même si une quantité de formations ne sont que somnolences lors des conférences, en attendant le dîner. Si vous dirigez des personnes, comprenez comment elles apprennent et aidez-les en leur donnant des projets de la bonne taille et qui font appel à des compétences qui les intéressent. N’oubliez pas que les compétences les plus importantes pour un programmeur ne sont pas les compétences techniques. Donnez à vos collègues une chance de jouer, de faire preuve de courage, d’honnêteté et de communiquer.

III-A-7. Apprenez à taper au clavier▲

Apprenez à taper au clavier. Ceci est une compétence intermédiaire, car écrire du code est si difficile que la vitesse à laquelle vous pouvez taper n’a plus d’importance et qu’il est impossible de réduire considérablement le temps nécessaire pour écrire du code, quel que soit votre niveau. Cependant, à partir du moment où vous êtes un programmeur intermédiaire, vous passerez probablement beaucoup de temps à écrire en langage naturel à vos collègues et à d’autres. Ceci est un test amusant de votre engagement ; il faut du temps et ce n’est pas très amusant d’apprendre quelque chose comme ça. La légende veut que, lorsque Michael Tiemann était chez MCC, les gens se tenaient devant sa porte pour écouter le ronflement généré par ses frappes au clavier, qui étaient si rapides qu'il était impossible de les distinguer.

III-A-8. Comment faire des tests d'intégration▲

Les tests d’intégration sont des tests de l’intégration de différents composants qui ont été testés unitairement. L’intégration est coûteuse et cela ressort des tests. Vous devez inclure du temps pour cela dans vos estimations et votre planification. Idéalement, vous devriez organiser un projet de sorte qu’il n’y ait pas une phase à la fin où l’intégration doit explicitement avoir lieu. Il est de loin préférable d’intégrer progressivement les éléments au fur et à mesure de leur réalisation au cours du projet. Si c’est inévitable, faites une estimation avec soins.

III-A-9. Les langages de communication▲

Certains langages, qui sont des systèmes syntaxiques formellement définis, ne sont pas des langages de programmation, mais des langages de communication. Ils sont spécifiquement conçus pour faciliter la communication à travers la normalisation. En 2003, les plus importants sont UML, XML et SQL. Vous devriez être familier avec eux pour pouvoir bien communiquer et décider quand les utiliser. UML est un système formel riche pour effectuer des schémas représentant la conception. Sa beauté réside dans le fait qu’il est à la fois visuel et formel, capable de transmettre beaucoup d’informations si l’auteur et le public connaissent UML. Vous devez le connaître, car les conceptions sont parfois communiquées par son biais. Il existe des outils très utiles pour réaliser des dessins UML qui ont un aspect très professionnel. Dans de nombreuses situations, UML est trop formel, et je me retrouve à utiliser un style plus simple de cases et de flèches pour les dessins de conception. Mais je reste persuadé qu’UML est au moins aussi bon pour vous qu’étudier le latin. XML est un standard pour définir de nouveaux standards. Ce n’est pas une solution aux problèmes d’échange de données, bien qu’il soit parfois présenté comme tel. Il s’agit plutôt d’une automatisation bienvenue de la partie la plus ennuyeuse de l’échange de données, à savoir la structuration de la représentation en une séquence linéaire et la parser dans une structure. Il fournit de bonnes vérifications de type et de correction, bien qu’à nouveau ce soit une fraction de ce dont vous aurez probablement besoin dans la pratique. SQL est un langage de requête et de manipulation de données très puissant et riche, qui n’est pas tout à fait un langage de programmation. Il comporte de nombreuses variantes, généralement très dépendantes du produit, qui sont moins importantes que le noyau standardisé. SQL est la « lingua franca » des bases de données relationnelles. Vous pouvez travailler ou non dans n'importe quel domaine pouvant tirer parti d'une compréhension des bases de données relationnelles, mais vous devriez en avoir une compréhension de base, ainsi que de la syntaxe et du sens de SQL.

III-A-10. Les outils importants▲

Au fur et à mesure que notre culture technologique progresse, la technologie logicielle passe de l’inconcevable à la recherche, puis à de nouveaux produits, et enfin à des produits standardisés, largement disponibles et bon marché. Ces outils lourds peuvent supporter des charges importantes, mais peuvent être intimidants et nécessitent un investissement important dans la compréhension. Le programmeur intermédiaire doit savoir comment les gérer et quand ils doivent être utilisés ou considérés. à mon avis, actuellement, certains des meilleurs outils sont : les bases de données relationnelles ;

les moteurs de recherche de texte intégral full-text ;

les bibliothèques mathématiques ;

OpenGL ;

Les parsers XML ;

les feuilles de calcul.

III-A-11. Comment analyser les données▲