Est-il normal qu'un programmeur n'ait pas parfois une clarté à 100% sur son propre code? [fermé]

19

Je ne suis pas un programmeur expert, c'est peut-être la raison, mais j'ai remarqué que chaque fois que je crée du code complexe (comme un jeu d'échecs que j'ai fait récemment), je suis capable d'écrire le bon code pour faire fonctionner le programme, bien que je trouve cela plus tard - ou même quelques secondes après! - Je dois souvent faire une pause et réfléchir, comment cela fonctionne-t-il?

Non seulement cela, mais j'ai également tendance à ne pas penser au code, et au lieu de cela, je tape simplement. Par exemple, dans mon jeu d'échecs, j'ai décidé d'utiliser un tableau à cinq dimensions pour traiter les mouvements, et j'ai trouvé que je pouvais le faire sans trop réfléchir. Cependant, lorsque je me suis arrêté et l'ai relu, j'ai trouvé difficile de me familiariser avec tout le concept à cinq dimensions, et cela m'a pris quelques minutes pour bien comprendre ce que j'ai fait et comment le code lui-même fonctionne.

Est-il normal que les programmeurs qui écrivent du code complexe ne comprennent pas ce qu'ils font la moitié du temps?

83457
la source
13
C'est un signe que vous essayez trop fort d'être intelligent. Vous devez écrire du code plus simple et plus modulaire si vous avez du mal à le lire vous-même.
SHODAN
3
Pour ajouter à d'autres réponses (perspicaces) dans le sens où cela sent le code trop compliqué ou mal conçu (ne vous inquiétez pas, la plupart d'entre nous ont dû passer cette phase): Document . À la fois en donnant des noms propres aux variables / méthodes / classes / modules, en ajoutant une description appropriée à chaque fonction, et en (quand vous ne voyez pas d'autre moyen) d'écrire un commentaire en ligne simple expliquant pourquoi et comment utilisez-vous un extrait complexe de code.
SJuan76
4
Je n'ai jamais 100% de clarté sur mon propre code.
CodesInChaos
2
Ce tableau 5D sonne vraiment comme s'il pouvait utiliser une certaine abstraction.
3
Est-ce qu'un développeur a une clarté à 100% sur son code à tout moment?
Johan

Réponses:

30

Non, ce n'est pas normal 1 . Au moins, ce n'est pas normal pour de bons programmeurs. Il est probablement normal que quelqu'un apprenne à programmer.

L'écriture de logiciels ne consiste pas seulement à regrouper des lignes de code jusqu'à ce qu'elles fonctionnent. Vous devez consciemment travailler à rendre le code facile à comprendre. Un programmeur que je respecte énormément m'a dit "le code est lu beaucoup plus de fois qu'il n'est écrit" . Bien que cela devrait être complètement évident, c'était un fait que je n'avais pas connu jusqu'à ce qu'il me le dise. Une grande partie de votre code n'est écrit qu'une seule fois, peut-être réécrit une ou deux fois de plus, mais vous finirez par lire le code souvent pendant la durée de vie du logiciel.

Si vous trouvez le code difficile à comprendre quelques minutes après l'avoir écrit, c'est un signal que votre code est trop complexe. Arrêtez d'ajouter du code et trouvez une meilleure façon. Par exemple, un tableau à cinq dimensions n'est presque jamais une bonne idée. Même les programmeurs vraiment très intelligents ont du mal à comprendre une structure de données aussi complexe.

Le même programmeur qui m'a parlé de la lisibilité du code a également dit "montrez-moi vos structures de données et je peux vous dire comment fonctionne votre code" . Cela signifie qu'un bon code commence par des structures de données propres et compréhensibles. Si vous concevez correctement vos données, le code est presque une préoccupation secondaire. Certes, cette affirmation est un peu hyperbole car le logiciel est évidemment plus que des données, mais il commence par des données. Donc, travaillez sur la création de structures de données propres et faciles à saisir et le code sera considérablement plus facile à comprendre.


1 Il existe certainement du code très complexe et difficile à comprendre même par les programmeurs les plus intelligents. Certains problèmes sont intrinsèquement complexes. Cependant, j'oserais dire que la grande majorité du code écrit par la grande majorité des programmeurs n'est pas ce type de code.

Bryan Oakley
la source
8
[1] D'un point de vue plus pessimiste, c'est normal mais ce n'est pas bon.
Dan
1
Si le "tableau à cinq dimensions" est simplement une carte à partir d'un quadruple ou d'un 5uple vers une stratégie, l'auteur aurait pu utiliser une table de hachage ou une fonction de recherche d'aide. Cependant, si l'auteur passe la plupart de son temps à coder les mécanismes d'initialisation du tableau (boucles imbriquées), la véritable "vision de l'algorithme" va se noyer dans la pile de "code mécanique". Les programmeurs cherchent à séparer ce dernier type de bruit. Ainsi, les bons programmeurs doivent savoir écrire des bibliothèques principalement pour héberger ces codes mécaniques.
rwong
Le tableau 1-D est une ligne, 2-d est une grille, 3-d est un cube, 4-d est une ligne de cubes, 5-d est une grille de cubes, etc. mais je ne vois pas d'utilisation pour une structure de données aussi complexe en ce qui concerne les échecs.
user2785724
15

Il y a deux sortes de ceci: 1.) confusion 2.) ignorance béat

Le premier est mauvais et peut disparaître avec le temps et l'expérience.

La seconde est bonne si les projets deviennent plus grands: si vous devez vous souvenir de chaque détail d'implémentation juste pour pouvoir travailler avec votre code, il y a quelque chose qui ne va pas (voir "masquage des informations").

Chaque développeur va oublier comment le code fonctionnait, alors il l'écrit de manière à ce qu'un autre nouveau développeur le comprenne et puisse le maintenir sans casser d'autres parties du programme qui lui sont également inconnues.

Donc «ne pas savoir» est en fait une constante dans le développement de logiciels - c'est juste comment ou si vous le gérez.

telep
la source
1
Vous touchez à quelque chose d'important ici, à savoir à quel point il est essentiel de programmer en utilisant des modèles et des conventions de bon sens , car les détails de mise en œuvre sont effectivement oubliés. Mais si les modèles et les conventions du code sont raisonnables, il est assez facile de récupérer les détails du contexte lorsque cela est nécessaire. D'un autre côté, si le code est tout monolithique, impénétrable et trop intelligent, non seulement vous finirez par oublier les détails, mais d'autres programmeurs essayant de maintenir le code auront beaucoup plus de mal.
Craig
12

Je dirais que c'est plus courant que les gens ne veulent l'admettre. Même Brian Kernighan y a fait allusion:

Le débogage est deux fois plus difficile que d'écrire le code en premier lieu. Par conséquent, si vous écrivez le code aussi intelligemment que possible, vous n'êtes, par définition, pas assez intelligent pour le déboguer.

Lorsque nous conduisons au magasin, nous effectuons une séquence de réglages détaillés de la position des pédales et du volant. C'est très facile pour le moment. Maintenant, imaginez si vous avez enregistré ces ajustements sur du papier et les avez donnés à un ami qui avait besoin d'un itinéraire vers le magasin.

De même, nous aimons écrire du code à un niveau d'abstraction, mais nous aimons le lire dans plusieurs couches d'abstraction supérieures. Notre manière préférée d'écrire et de lire du code est donc en conflit. Cela signifie que rendre le code facile à lire est généralement une étape distincte et consciente, avec un ensemble différent de compétences.

Ce qui fait un bon programmeur, c'est quand ils ont du mal à lire ce qu'ils viennent d'écrire, ils créent une abstraction à ce point. Un meilleur programmeur fait cela plusieurs fois, devenant plus difficile à chaque fois. Finalement, les programmeurs expérimentés commencent plus loin dans le processus, mais ils peuvent souvent encore voir des améliorations à faire après avoir lu ce qu'ils viennent d'écrire.

Karl Bielefeldt
la source
Je dois être en désaccord avec Brian à ce sujet, j'adore le débogage, je suis l'une des rares personnes que je connaisse dans l'industrie à le faire, mais je n'accorde pas une grande importance au code que j'écris.
James Snell
@JamesSnell Il n'a pas dit que le débogage est mauvais ou désagréable, mais simplement qu'il est difficile, et que le débogage de code compliqué est encore plus difficile.
cbojar
5

Je pense que c'est quelque chose qui disparaîtra avec l'expérience.

Si vous écrivez des systèmes complexes, vous devez avoir la capacité d'écrire du code propre et maintenable que vous-même à l'avenir, et quelqu'un d'autre à l'avenir, pouvez comprendre. Donc, en substance, la chose que vous faites maintenant n'est pas évolutive.

Vous aurez beaucoup de moments où vous regardez du code que vous avez écrit il y a 6 mois et pensez "qu'est-ce qui se passe ici?", Mais si cela se produit un jour après avoir écrit le code, vous devez penser 'propre' code 'plus.

Source: jamais utilisé de tableau à 5 dimensions :)

Erez Eshkol
la source
3
@ 83457 - car un tableau 5d est un mauvais modèle d'un problème 2d. Si vous pensez vraiment que c'est un bon code, déposez-le sur codereview.stackexchange.com et voyez quelles réponses vous obtenez.
James Snell
2
@ 83457 - Si c'est "déroutant comme l'enfer", vous vous êtes répondu. Il est possible qu'un tableau 5-D ne soit pas déroutant, mais probablement pas pour la plupart d'entre nous, quel que soit notre niveau de compétence.
dbasnett
2
@ 83457 être confus comme l'enfer devrait déjà être une très bonne motivation pour ne pas l'utiliser.
Fabio Marcolini
3
Tant que vous avez une bonne raison pour chaque dimension, je ne vois pas de raison d'éviter un tableau 5D. Il existe peut-être une meilleure solution, comme un dictionnaire avec une clé complexe ou plusieurs tableaux de dimension inférieure, mais je peux très bien imaginer qu'un tableau 5D soit approprié pour un problème délicat comme une IA d'échecs.
CodesInChaos
2
@CodesInChaos Sauf que ce ne sont pas que des tableaux, ils représentent des séquences significatives (par exemple des arbres de décision imbriqués). En les nommant de manière appropriée et en leur donnant des types afin qu'ils ne puissent pas être utilisés abusivement (même si ces types sont des wrappers thon sur des tableaux), vous rendez le code plus clair et moins susceptible de contenir des bogues, pour à peine n'importe quel coût.
deworde
5

"Normal" est très subjectif, donc je dis: c'est très courant, mais il faut éviter.

L'une des caractéristiques du «bon code» (j'ai entendu dire qu'une telle chose existe) est la clarté: elle devrait être aussi claire que les problèmes sous-jacents le permettent. Si le problème est complexe, le code serait également complexe, mais c'est une complexité inhérente , par opposition à une complexité accidentelle (j'ai entendu parler de cette distinction pour la première fois dans le discours de Rich Hickey ) introduite en utilisant ou en n'utilisant pas les bons outils, modèles, techniques et les pratiques.

Il y a des cas où le manque de clarté est acceptable même lorsque le problème n'est pas très complexe, par exemple si vous écrivez un site promotionnel dont vous savez qu'il durera aussi longtemps que la campagne de marketing se poursuivra. C'est un code jetable qui ne doit pas être maintenable. Pour d'autres (et la plupart des) cas, cela n'est pas acceptable, car le maintien d'un tel code coûtera cher. Pourtant, c'est courant.

En relation:

  • Quand comprendre signifie réécrire - article sur le problème de la compréhension du code.
  • ML efficace - une longue discussion sur, parmi ML / OCaml, comment écrire le code pour les "lecteurs" (c'est-à-dire les mainteneurs): "Privilégiez les lecteurs aux écrivains." Je recommande de regarder cela, peu importe la langue que vous utilisez.
scriptin
la source
2

Je ne pense pas que ce soit normal, mais pour des programmes très complexes, comme le programme d'échecs que vous mentionnez, je pense que c'est certainement possible.

Il y a de nombreuses années, alors que je venais juste de terminer mes études (donc j'étais encore relativement inexpérimenté pour écrire de gros programmes), j'ai écrit mon premier vrai compilateur. L'analyse a été simple, mais j'ai ensuite dû la cibler pour quatre jeux d'instructions de microprocesseur différents. J'avais l'intention d'écrire le compilateur dans son propre langage, j'ai donc d'abord utilisé uniquement les fonctionnalités du langage dont j'avais absolument besoin, j'ai écrit le premier générateur de code en langage assembleur et j'ai testé qu'il générait le code correct pour le sous-ensemble du langage. J'ai ensuite pu utiliser le compilateur pour se compiler à partir de là, et ajouter les fonctionnalités restantes et les utiliser également dans le compilateur lui-même

J'ai ensuite écrit les générateurs de code backend pour chaque microprocesseur et testé qu'ils généraient tous du code correct, mais bien que ce ne soit pas très optimal. J'ai donc commencé à écrire des optimiseurs pour chaque générateur de code.

Lorsque je testais la sortie des générateurs de code après avoir ajouté toute l'optimisation, j'ai été souvent surpris par le code généré par le compilateur. Ce n'était souvent pas la façon dont j'aurais écrit le code à la main, mais c'était correct et assez concis.

Quand il n'était pas évident pour moi comment le générateur de code a produit une partie du code qu'il a fait, j'ai essayé de suivre la logique à la main, mais il y avait des moments où je venais de renoncer. Si j'avais ajouté beaucoup de sortie de trace, j'aurais pu la suivre, mais je n'ai pas pris la peine car le code généré était satisfaisant et j'avais besoin de passer à d'autres projets.

tcrosley
la source
Il me semble que vous avez une très bonne éducation avec une base solide et que vous avez internalisé les connaissances à un niveau très élevé. Je suppose que c'est quelque peu rare chez les programmeurs typiques. La plupart des programmeurs (dont moi) doivent lutter pour suivre les connaissances nécessaires à la tâche d'aujourd'hui, car la technologie évolue si rapidement.
rwong
@rwong Merci. La plupart sont de l'expérience - j'écris des programmes depuis 46 ans et je n'ai pas l'intention d'arrêter de sitôt.
tcrosley
2

Il y a beaucoup de réponses décentes ici.

J'ai quelques points de vue à ce sujet.

La première est que si vous ne comprenez pas pourquoi votre code semble fonctionner, alors a) il ne le fait probablement pas (il semble que cela ne fonctionne que probablement ), et b) soit vous n'avez pas assez bien compris le domaine problématique lorsque vous a commencé à coder ou n'a pas divisé le domaine problématique en unités plus petites et simplifiées avant de commencer.

Mon autre point de vue est que la vraie clé est d'utiliser des modèles et des conventions de bon sens dans votre code. C'est un sujet beaucoup plus vaste qu'un petit article ne peut aborder. Mais recherchez de la bonne littérature sur le sujet, y compris certains des anciens standbys comme les livres "Code Complete" et "Writing Solid Code".

Les détails de la mise en œuvre changent. La seule vraie constante est l'objectif fonctionnel du code. Si vous écrivez plus d'une fonction, vous allez oublier des détails d'implémentation précis et granulaires au fil du temps. Mais vous devez certainement comprendre comment les pièces fonctionnent lorsque vous les construisez, et vous devriez pouvoir dessiner un diagramme de l'ensemble et comprendre comment les pièces fonctionnent ensemble.

Si vous utilisez des modèles et suivez les conventions de bon sens, il sera beaucoup plus facile de sauvegarder les détails d'implémentation spécifiques lorsque vous examinerez à nouveau le code. Ou quand quelqu'un qui n'a jamais vu le code le regarde pour la première fois. En outre, le respect de ces conventions et modèles au fil du temps signifie que les détails d'implémentation se démarqueront des conventions et des modèles eux-mêmes, ce qui est un autre facteur qui rendra le code plus facile à comprendre.

La plupart des problèmes que nous abordons avec les logiciels sont par nature complexes. La conception de logiciels est un exercice de gestion de la complexité.

Craig
la source
1

Je ne dirais pas que c'est normal , mais cela peut certainement arriver. Si cela vous arrive peu de temps après avoir écrit le morceau de code en question, je suppose que soit votre code est inutilement complexe et devrait être simplifié, soit vous êtes simplement facilement distrait. :)

Mais si vous rangez votre code, vous concentrez sur d'autres projets et y revenez après des semaines, des mois ou même des années, ce n'est pas vraiment une surprise que vous deviez tout comprendre à nouveau.

Mais vous pouvez faire quelque chose à ce sujet. D'après ce que vous dites, il semble que vous ne pensiez pas assez à votre code pendant que vous l'écrivez, et donc vous empêchez votre futur de comprendre ce qui se passe. Utilisez ces connaissances à votre avantage: c'est la meilleure motivation pour produire du code bien structuré, bien documenté et compréhensible. Vous savez par expérience directe ce qui se passe lorsque vous ne vous souciez pas de la qualité de votre code. Le savoir devrait faire de vous un meilleur programmeur à long terme. Lorsque vous collaborez sur des projets logiciels, vos collègues vous remercieront d'avoir produit un code compréhensible. Et le taux de défauts de votre code s'améliorera également.

mindriot
la source