Je suis un programmeur autodidacte, juste au cas où cette question trouverait une réponse dans CS 101. J'ai appris et utilisé beaucoup de langues, principalement pour mon usage personnel, mais parfois pour des choses professionnelles.
Il semble que je rencontre toujours le même mur lorsque je rencontre des problèmes de programmation. Par exemple, je viens de poser une question sur un autre forum sur la façon de gérer un pointeur vers un tableau renvoyé par une fonction. Au départ, je pense que je ne connais tout simplement pas la technique appropriée que les concepteurs de C ++ ont mise en place pour gérer la situation. Mais à partir des réponses et des discussions qui suivent, je vois que je ne comprends pas vraiment ce qui se passe quand quelque chose est «retourné».
Jusqu'à quel niveau de compréhension du processus de programmation un bon programmeur doit-il atteindre?
Réponses:
Non, personne ne comprend ce qui se passe au niveau matériel.
Les systèmes informatiques sont comme des oignons - il existe de nombreuses couches, et chacune dépend de la couche en dessous pour le support. Si vous êtes le gars qui travaille sur l'une des couches externes, vous ne devriez pas trop vous soucier de ce qui se passe au milieu de l'oignon. Et c'est une bonne chose, car le milieu de l'oignon change toujours. Tant que le ou les calques qui prennent en charge votre calque particulier restent identiques et prennent en charge votre calque, vous êtes bon.
Mais encore une fois...
Oui. Je veux dire, vous n'avez pas besoin de comprendre ce qui se passe vraiment à l'intérieur de l'oignon, mais cela aide beaucoup d'avoir un modèle mental de ce à quoi ressemble l'intérieur d'un oignon typique. Peut-être pas la partie la plus profonde, où vous avez des portes composées de transistors et autres, ou la couche suivante ou deux, où vous avez un microcode, une horloge, des unités de décodage d'instructions, etc. Les couches suivantes, cependant, sont là où vous 'ai des registres, la pile et le tas. Ce sont les couches les plus profondes où vous avez beaucoup d'influence sur ce qui se passe - le compilateur traduit votre code en instructions qui s'exécutent à ce niveau, et si vous le souhaitez, vous pouvez généralement parcourir ces instructions et découvrir ce qui se passe "vraiment".
La plupart des programmeurs expérimentés ont une version légèrement féerique de ces couches dans leur tête. Ils vous aident à comprendre de quoi parle le compilateur lorsqu'il vous indique qu'il y a eu une "exception d'adresse non valide" ou une "erreur de débordement de pile" ou quelque chose du genre.
Si vous êtes intéressé, lisez un livre sur l'architecture informatique. Il n'a même pas besoin d'être un livre particulièrement nouveau - les ordinateurs numériques fonctionnent à peu près de la même manière depuis longtemps. Plus vous en apprendrez sur l'intérieur de l'oignon, plus vous serez étonné que tout cela fonctionne! Apprendre (approximativement) ce qui se passe dans les couches inférieures rend la programmation à la fois moins mystérieuse et, en quelque sorte, plus magique. Et vraiment, plus amusant.
Une autre chose que vous pourriez examiner est les oignons incorporés. Euh, je veux dire des systèmes embarqués. Il existe un certain nombre de plates-formes intégrées assez faciles à utiliser: Arduino et BASIC Stamp en sont deux exemples. Ce sont essentiellement de petits microprocesseurs avec de nombreuses fonctionnalités intégrées. Vous pouvez les considérer comme des oignons avec moins de couches que votre ordinateur de bureau typique, il est donc possible d'avoir une compréhension assez approfondie de ce qui se passe dans l'ensemble du système, du matériel au logiciel.
la source
Vous ne parlez pas du niveau matériel, vous parlez de ce que le compilateur fait vraiment avec ce que vous lui demandez de faire.
Vous avez très certainement besoin de ce niveau de compréhension afin de comprendre ce qui s'est mal passé quand ce n'est pas évident, en particulier lorsqu'il s'agit d'une situation de mémoire stomp.
la source
Comprendre la mémoire du programme! = Comprendre le matériel
Comprendre la hiérarchie de la mémoire == Comprendre le matériel
Pour répondre à votre question générique: cela dépend. Cela ne peut pas nuire à la compréhension du matériel, mais le comprendre n'aidera pas dans tous les cas.
Sur la base de votre exemple, il vous suffit de mieux comprendre comment la mémoire est divisée et comment elle est organisée lorsque vous exécutez un programme. Comprendre le matériel ne vous aidera pas à cet égard, car la mémoire (visible par un programme) ne représente même pas vraiment le matériel grâce à la magie de la mémoire virtuelle.
Si vous étiez curieux de connaître les problèmes de performances en fonction de l'ordre dans lequel vous accédez à la mémoire, MAINTENANT, vous bénéficieriez de la compréhension du matériel, de la hiérarchie de la mémoire, des échecs de cache, des défauts de page et de toute la splendeur merveilleuse du matériel.
la source
Si vous ne décidez d'apprendre un peu d'assembleur, vous devriez probablement apprendre quelque chose comme 6502 assembleur sur un Commodore 64 (émulé, bien sûr), ou 68000 sur un Amiga.
Vous pouvez vous faire une idée du Commodore 64 ici ...
http://thepiratebay.org/torrent/4609238/Tag3-Saal2-Slot16_00--ID2874-the_ultimate_commodore_64_talk-Main
Le livre classique sur tout ce que vous devez savoir est celui décrit ici ...
http://reprog.wordpress.com/2010/03/12/programming-books-part-3-programming-the-commodore-64/
Vous pouvez probablement trouver une analyse PDF si vous regardez autour de vous.
IMO, 6502 est plus facile que Z80, et 68000 est plus facile que 8086 - jeux d'instructions plus réguliers, etc.
Mais le CPU n'est qu'un aspect du matériel. En outre, un processeur moderne est une bête très différente, et il fait des choses qui sont transparentes même du point de vue des compilateurs - comme présenter un espace d'adressage virtuel.
Un avantage particulier du 6502 sur le C64 est que non seulement le processeur est simple, mais il y a aussi du matériel très simple à pirater. J'ai eu beaucoup de plaisir à jouer avec la puce de musique SID.
Donc - c'est probablement un exercice intéressant si vous n'y passez pas trop de temps. J'ai appris l'assembleur 6502 comme deuxième langue quand j'avais environ 14 ans, juste après Commodore Basic. Mais surtout, il s'agit d'obtenir ce modèle de travail très simple afin que vous puissiez y ajouter des idées plus sophistiquées avec un minimum de malentendus.
Quelques choses utiles que vous pouvez apprendre en travaillant dans l'assembleur ...
Une raison particulière que je recommanderais est d'avoir une meilleure intuition de la façon dont les étapes simples fonctionnent de manière entièrement déterministe et mécanique et totalement sans intelligence ni bon sens. S'habituer fondamentalement au modèle d'exécution impérative sous sa forme la plus pure et la plus obstinément ignorante.
Précisément comment il est utile de connaître la plupart de ces choses maintenant, cependant, est une question difficile.
Une chose que vous n'apprendrez pas est de bien jouer avec une hiérarchie de mémoire. Ces vieilles machines avaient pour la plupart un modèle de mémoire simple sans couches de cache et sans mémoire virtuelle. Vous n'aurez pas non plus beaucoup d'informations sur la concurrence - ils étaient certainement des moyens de gérer cela, mais cela signifiait principalement des interruptions. Vous n'avez pas besoin de vous soucier des mutex, etc.
Parfois, un modèle mental de la façon dont ces choses fonctionnaient autrefois ou du fonctionnement de l'assembleur peut même induire en erreur. Par exemple, penser à un pointeur C comme une adresse peut conduire à des problèmes de comportement indéfinis. Le pointeur AC est normalement implémenté comme un entier contenant une adresse, mais il n'y a aucune garantie que cela soit strictement vrai. Par exemple, sur certaines plateformes bizarres, différents pointeurs peuvent pointer vers différents espaces d'adressage. Cela devient important lorsque vous voulez faire de l'arithmétique ou de la logique au niveau du bit avec deux pointeurs.
À moins que vous n'ayez une de ces plates-formes bizarres, vous ne pensez peut-être pas que cela vous intéresse - mais les compilateurs de nos jours sont de plus en plus susceptibles d'exploiter un comportement non défini pour l'optimisation.
Un modèle mental de l'architecture du système peut donc être utile, mais il est toujours important de coder en fonction de la spécification de la langue, pas d'un modèle hypothétique que votre langue et votre plate-forme peuvent ne pas respecter.
Enfin, beaucoup de choses utiles sur les modèles mentaux proviennent de la façon dont les compilateurs génèrent du code - et la génération de code pour les langages modernes est très différente des compilateurs assez triviaux disponibles à l'époque.
C'est un de mes livres préférés pour ça ...
http://dickgrune.com/Books/MCD_1st_Edition/
Outre les informations sur l'analyse syntaxique et les AST, etc., il couvre la génération de code pour une gamme de paradigmes de langage - impératif, POO, fonctionnel, logique, parallèle et distribué - et également pour la gestion de la mémoire. Si vous voulez savoir comment fonctionnent les appels de méthodes polymorphes sans vous enliser dans les détails du jeu d'instructions CPU, un livre comme celui-ci est votre ami - et une nouvelle édition devrait bientôt sortir.
la source
Il y a vingt ans, c'était important, mais pas tellement maintenant - il y a beaucoup plus de couches d'abstraction entre le logiciel et le matériel moderne.
Il est utile de savoir des choses comme avoir besoin de plusieurs threads pour tirer parti de plusieurs cœurs ou qu'utiliser plus de mémoire qu'il n'en existe sur le système est une mauvaise chose, mais au-delà, vous n'en avez pas vraiment besoin à moins que ce soit votre travail d'écrire ces abstractions couches.
Le reste de votre question suggère que vous pouvez être plus concerné par le compilateur que par le matériel, ce qui est un peu différent. Vous pouvez rencontrer des cas où cela est important, mais ceux-ci ont tendance à être triviaux (la récursion infinie ne fonctionne pas très bien) ou le type de cas marginaux où vous pouvez vous sentir à l'aise pour le résoudre mais ne rencontrerez probablement jamais le même problème encore.
la source
Il aide beaucoup à connaître et comprendre l'abstraction présentée par le matériel, et un peu de l'idée générale sur la façon dont cette illusion est créée - mais en essayant de comprendre vraiment comment le matériel moderne vraiment fonctionne est une énorme quantité de travail à partir de laquelle vous » re ne verra probablement qu'un rendement minimal.
Si vous pardonnez une diversion mineure: cela me rappelle quelque chose que j'ai remarqué il y a quelques années. Il y a des décennies (jusqu'à la fin des années 1970 environ), la plupart des gens pensaient que les ordinateurs étaient à un pas de la magie - à peine affectés par les lois de la physique, capables de toutes sortes de choses qui n'avaient pas vraiment de sens, etc. À l'époque, j'ai passé pas mal de temps à essayer (surtout sans succès) de convaincre les gens que non, ils n'étaient pas magiques. C'étaient vraiment des machines assez ordinaires qui faisaient un nombre limité de choses très rapidement et de manière fiable, mais étaient par ailleurs extrêmement banales.
De nos jours, la vue de la plupart des gens sur les ordinateurs a changé. Ils sont maintenant assez ordinaires - au point que pas mal de gens très ordinaires les comprennent. Par exemple, il y a quelque temps, alors que je dînais, j'ai vu / entendu un serveur et une serveuse pendant leur pause discuter de ce qu'elle devrait obtenir dans son nouvel ordinateur. Les conseils qu'il donnait étaient tout à fait raisonnables et réalistes.
Ma vision des ordinateurs a également changé. Je suis allé à Hot Chips, et avant cela, le Microprocessor Forum remonte au milieu des années 1990. J'en sais probablement plus sur le matériel des microprocesseurs qu'au moins 99% des programmeurs - et sachant ce que je fais, je dirai ceci: ils ne sont plus ordinaires. Ils ne cassent presque les lois de la physique. J'ai fait beaucoup de tests de bas niveau et je peux le dire avec certitude: dépasser l'illusion créée par le CPU et montrer comment le matériel fonctionne vraiment est souvent incroyablement difficile. J'aimerais pouvoir poster une photo de l'une de nos configurations avec un ordinateur enfoui sous les câbles de pas moins de 4 analyseurs logiques juste pour mesurer correctement un aspect du fonctionnement de la mise en cache sur un processeur moderne (sans parler d'une programmation vraiment fastidieuse pour garantir que ce que nous avons mesuré était exactement ce que le processeur faisait, et rien d'autre).
la source
Différentes langues fonctionnent à différents niveaux d'abstraction du matériel. C et C ++ sont de très bas niveau. Les langages de script, d'autre part, nécessitent que vous en sachiez moins sur les détails sous-jacents.
Cependant, je dirais toujours que dans tous les cas, plus vous en savez, mieux vous serez un programmeur. Une partie de la programmation consiste à jongler avec plusieurs niveaux d'abstraction en même temps.
Si vous programmez en C ++, vous devez avoir une assez bonne compréhension du fonctionnement d'un processeur moderne, au moins au niveau d'abstraction auquel le compilateur fonctionne. (Il se passe aussi des choses à l'intérieur du CPU qui sont transparentes pour le compilateur).
la source
Je voudrais ajouter un point sur la conception globale des langages de niveau supérieur comme C.
En général, je pense qu'il est prudent de dire que de tels langages peuvent être considérés comme implémentant une machine abstraite, et c'est d'ailleurs ainsi que Dennis Ritchie lui-même a décrit le fonctionnement de C et comment la conception particulière de la machine abstraite de C en a fait un langage plus portable. En tant que tel, avoir une certaine compréhension de l'architecture informatique et du fonctionnement au niveau de la machine peut être extrêmement utile pour comprendre également la machine abstraite d'un langage.
L'article de DMR, Portabilité des programmes C et du système UNIX, est le premier dont je me souviens avoir discuté du modèle de machine (abstraite) pour C.
Je pense que l'article de DMR sur l'histoire et le développement de C est également extrêmement utile pour montrer comment le matériel réel affecte la conception du langage, et est peut-être aussi un exemple de conception de langage de programmation précoce: Le développement du langage C
la source