Personne n'est parfait, et quoi que nous fassions, nous allons produire de temps en temps du code contenant des bogues. Quelles sont certaines méthodes/techniques pour réduire le nombre de bogues que vous produisez, à la fois lors de l'écriture de nouveaux logiciels et de la modification/maintenance du code existant?
Évitez le codage de fantaisie. Plus le code est compliqué, plus il y a de bogues. Habituellement, sur les systèmes modernes, un code clairement écrit sera rapide et assez petit.
Utilisez les bibliothèques disponibles. Le moyen le plus simple de ne pas avoir de bogues lors de l'écriture d'une routine utilitaire est de ne pas l'écrire.
Apprenez quelques techniques formelles pour les choses les plus compliquées. S'il y a des conditions compliquées, clouez-les avec un stylo et du papier. Idéalement, connaissez certaines techniques de preuve. Si je peux prouver que le code est correct, il est presque toujours bon, sauf pour les gros bugs, stupides et évidents, faciles à corriger. Évidemment, cela ne va que jusqu'à présent, mais parfois vous pouvez formellement raisonner sur des choses petites mais compliquées.
Pour le code existant, apprenez à refactoriser: comment apporter de petites modifications au code, souvent à l'aide d'un outil automatisé, qui rendent le code plus lisible sans changer le comportement.
Ne faites rien trop vite. Prendre un peu de temps à l'avance pour bien faire les choses, pour vérifier ce que vous avez fait et pour réfléchir à ce que vous faites peut porter ses fruits plus tard.
Une fois que vous avez écrit le code, utilisez ce que vous avez pour le rendre bon. Les tests unitaires sont excellents. Vous pouvez souvent écrire des tests à l'avance, ce qui peut être une excellente rétroaction (si cela est fait de manière cohérente, il s'agit d'un développement piloté par les tests). Compilez avec les options d'avertissement et faites attention aux avertissements.
Demandez à quelqu'un d'autre de regarder le code. Les révisions de code formelles sont bonnes, mais elles peuvent ne pas être à un moment opportun. Les requêtes Pull, ou similaire si votre scm ne les prend pas en charge, permettent des révisions asynchrones. La vérification des contacts peut être un examen moins formel. La programmation par paires garantit que deux paires d'yeux regardent tout.
Tests unitaires vous permet de réduire le nombre de bugs qui apparaissent une deuxième fois. Si vous trouvez un bogue dans votre code, l'écriture d'un test unitaire fera en sorte qu'il ne revienne pas plus tard. (De plus, il est parfois difficile de penser à tous les cas et d'écrire des milliers de tests unitaires à l'avance)
J'ai développé un style de programmation assez fonctionnel, bien que mes langages principaux soient C++ et Python. J'ai trouvé que si je transmettais tout le contexte à une fonction (ou méthode) dont cette fonction a besoin pour faire son travail et que je renvoie les données significatives que je recherche, mon code est devenu beaucoup plus robuste.
L'état implicite est l'ennemi et d'après mon expérience, c'est la source n ° 1 de bugs. Cet état peut être des variables globales ou des variables membres, mais si les résultats dépendent de quelque chose qui n'est pas transmis à la fonction que vous demandez des problèmes. Il est clair qu'il n'est pas possible d'éliminer l'état, mais sa minimisation a d'énormes effets positifs sur la fiabilité du programme.
J'aime aussi dire à mes collègues que chaque branche (si, pendant, alors? :) est un bug probable. Je ne peux pas dire quelle sera la manifestation du bogue, mais moins le comportement de votre code est conditionnel, plus il est probable qu'il soit exempt de bogues simplement parce que la couverture du code pendant l'exécution sera plus cohérente.
Allez comprendre, toutes ces choses ont également des effets positifs sur les performances. Gagner!
+1 sur les deux commentaires de test unitaire.
Au-delà de cela, définissez le niveau d'avertissement le plus élevé proposé par votre compilateur et assurez-vous que les avertissements sont traités comme des erreurs. Les bogues se cachent souvent dans ces erreurs "erronées".
De même, investissez dans des outils d'analyse statique qui s'exécutent au moment de la compilation (je les considère comme un niveau supplémentaire d'avertissements du compilateur).
En plus de ce qui a été mentionné:
Beaucoup d'autres choses que j'oublie en ce moment, mais les autres y penseront sûrement. :)
Une réponse un peu moins technique: ne programmez pas lorsque vous êtes fatigué (9h/jour suffisent), ivre ou "cuit". Quand je suis fatigué, je n'ai pas la patience requise pour écrire du code propre.
Écrivez tests unitaires et tests d'intégration.
Quelques bonnes réponses ici concernant les tests unitaires et les outils. La seule chose que je peux y ajouter est la suivante:
Impliquez vos testeurs le plus tôt possible
Si vous avez une équipe de test, ne tombez pas dans le piège de les traiter comme les gardiens de la qualité de votre code et d'attraper vos défauts pour vous. Au lieu de cela, travaillez avec eux et impliquez-les le plus tôt possible (sur les projets agiles, ce sera dès le début du projet, mais nous pouvons toujours trouver des moyens de les impliquer plus tôt si nous essayons vraiment).
Avoir une bonne relation de travail avec vos testeurs signifie que vous pouvez détecter très tôt les mauvaises hypothèses et les défauts avant qu'ils ne puissent endommager. Cela signifie également que les testeurs se sentent autorisés à aider à la conception du produit et à détecter les problèmes d'utilisation lorsqu'il est temps de les résoudre.
Outils d'analyse statique
Des plugins et des applications comme FindBugs explorez votre code et trouvez des endroits où il y a potentiel bugs. Les endroits où les variables ne sont pas initialisées et utilisées ou tout simplement des choses folles qui 9 fois sur 10, facilitent considérablement l'apparition de bogues. Des outils comme celui-ci m'aident à empêcher ma tête osseuse de se déplacer sur la route même si ce n'est pas encore un bug.
P.S .: N'oubliez pas de toujours rechercher pourquoi un outil vous dit que quelque chose ne va pas. Jamais mal à apprendre (et tout ne va pas bien dans toutes les situations).
Inspection de code ou autres formes d'examen par les pairs comme la programmation de paires.
Les revues de code structurées telles que l'inspection Fagan peuvent être au moins aussi efficaces et efficients que les tests unitaires et se sont même avérées meilleures que les tests unitaires dans certains cas. Les inspections peuvent également être utilisées plus tôt dans le cycle de vie du logiciel et avec des artefacts autres que le code.
Peer Reviews in Software by Karl Wiegers est un excellent livre sur ce sujet.
En plus de toutes les autres suggestions ici, activez tous les avertissements possibles au plus haut niveau de sensibilité, et traitez-les comme des erreurs. Utilisez également les outils de peluchage de la langue.
Vous seriez étonné à combien d'erreurs simples peuvent être détectées par les avertissements et combien de ces choses simples se traduisent en de vrais bugs dans votre code.
Beaucoup de bonnes réponses ici, mais quelques choses que je voulais ajouter. Assurez-vous de bien comprendre l'exigence. J'ai vu beaucoup de bogues lorsque l'utilisateur pensait que l'exigence signifiait X et que le programmeur pensait que cela signifiait Y. Repoussez pour obtenir des éclaircissements sur les exigences médiocres ou ambiguës. Je sais que nous aimons tous intervenir et coder, mais plus vous passerez de temps à assurer la compréhension, moins il y aura de retouches et de corrections de bogues.
Apprenez à connaître l'entreprise que vous soutenez, vous verrez souvent des choses dans les exigences qui manquent ou nécessitent des explications supplémentaires. Sachez que si vous effectuez la tâche Y comme indiqué, cela cassera la fonctionnalité Z existante.
Comprenez la structure de votre base de données. De nombreux bogues résultent d'une requête syntaxiquement correcte, mais qui renvoie des résultats incorrects. Apprenez à reconnaître quand vos résultats sont amusants. Si j'écris une requête de rapport complexe, je demande toujours à un spécialiste technique d'examiner mes résultats avant de le marquer comme prêt à l'emploi, ils verront inévitablement quelque chose dans les données que j'ai manquées. Ensuite, prenez note de ce qu'ils ont attrapé et rappelez-vous que la prochaine fois que vous ferez quelque chose de similaire.
Je suis la pratique de Test-Code-Test au lieu de Code-test-code-test. Cela m'aide à penser aux cas d'utilisation et à cadrer la logique de manière appropriée
Étonnamment, les trois points très importants suivants n'ont pas encore été mentionnés:
tilisez les assertions généreusement. La question que vous devriez toujours vous poser n'est pas "devrais-je affirmer cela?" mais "y a-t-il quelque chose que j'ai oublié d'affirmer?"
Optez pour l'immuabilité. (Utilisez libéralement final/en lecture seule.) Moins vous avez d'état mutable, moins les choses peuvent mal tourner.
N'optimisez pas prématurément. De nombreux programmeurs font l'objet d'un suivi secondaire avec des problèmes de performances, ce qui les oblige à compliquer inutilement leur code et à bâtarder leurs conceptions sans même savoir à l'avance si les performances vont être un problème. Tout d'abord, construisez votre produit logiciel de manière académique, sans tenir compte des performances; ensuite, voyez si cela fonctionne mal; (Ce ne sera probablement pas le cas.) S'il y a des problèmes de performances, allez trouver le ou les deux endroits où vous pouvez fournir des optimisations algorithmiques agréables et formelles qui permettront à votre produit de répondre à ses exigences de performances au lieu de modifier et de pirater l'intégralité de votre base de code pour presser des cycles d'horloge ici et là.
Utilisez des outils d'inspection de code comme ReSharper ou des IDE comme IntelliJ IDEA qui avertissent de nombreux - collez les bogues et autres par exemple soulignant les variables qui "sont écrites, mais jamais lues". Cela m'a fait gagner beaucoup de temps.
Je pense que la technique la plus importante est prenez votre temps . Si vous sentez que vous avez besoin de deux jours pour coder un nouveau module, mais que votre patron vous oblige à coder en une seule journée ... votre code sera probablement plus bogué.
Un des livres que j'ai lu il y a quelque temps, disait que vous ne devriez pas vivre avec des fenêtres cassées , parce que les gens ne se soucient pas si quelqu'un se casse. .. Le codage est le même, tout le monde se souciera d'être le premier à faire quelque chose mauvais mais rapide , mais personne ne se souciera d'un code infernal , avec beaucoup de bugs, et un design et un style très pauvres.