web-dev-qa-db-fra.com

Aide à la compréhension de l'informatique, de la programmation et de l'abstraction

Jusqu'à présent, j'ai toujours cru que vous devriez apprendre des langages de programmation qui vous font faire des choses de bas niveau (par exemple C) pour comprendre ce qui se passe vraiment sous le capot et comment l'ordinateur fonctionne vraiment. cette question , cette question et un réponse à cette question ont renforcé cette croyance:

Plus je programme dans les langues abstraites, plus je manque ce qui m'a amené dans les ordinateurs en premier lieu: fouiner autour de l'ordinateur et voir ce qui se tord. Assembleur et C sont très bien adaptés pour piquer :)

Finalement, je pensais que vous deviendriez un meilleur programmeur sachant cela, parce que vous saurez ce qui se passe plutôt que de supposer que tout est magique. Et savoir/écrire des trucs de bas niveau est beaucoup plus intéressant que d'écrire des programmes d'affaires, je pense.

Mais il y a un mois, je suis tombé sur ce livre intitulé Structure et interprétation des programmes informatiques . Tout sur le Web suggère que c'est l'un des meilleurs livres d'informatique, et vous vous améliorerez en tant que programmeur en le lisant.

J'apprécie vraiment beaucoup les concepts. Mais je trouve que le livre donne à penser que l'abstraction est le meilleur concept en informatique tout en ne consacrant qu'un chapitre à la partie de bas niveau.

Mon objectif est de devenir un meilleur programmeur, de mieux comprendre l'informatique et cela m'a vraiment dérouté. Ne devrions-nous surtout pas éviter toutes les abstractions et observer ce qui se passe vraiment à très bas niveau? Je sais pourquoi l'abstraction est excellente, mais cela ne vous empêche-t-il pas d'apprendre comment fonctionnent les ordinateurs?

31
morbidCode

Non, les abstractions ne vous empêchent pas de comprendre comment les choses fonctionnent. Les abstractions vous permettent de comprendre pourquoi (à quelle fin) les choses fonctionnent comme elles le font.

Tout d'abord, clarifions une chose: à peu près tout ce que vous avez jamais connu est à un niveau d'abstraction. Java est une abstraction, C++ est une abstraction, C est une abstraction, x86 est une abstraction, les uns et les zéros sont une abstraction, les circuits numériques sont une abstraction, les circuits intégrés sont une abstraction, les amplificateurs sont une abstraction, les transistors sont une abstraction, les circuits sont une abstraction, les semi-conducteurs sont une abstraction, les atomes sont une abstraction, les bandes d'électrons sont une abstraction, les électrons sont une abstraction (et pour tout ce que nous savons, cela pourrait être des abstractions tout le long). la logique selon laquelle des connaissances de bas niveau sont nécessaires pour comprendre comment quelque chose fonctionne vraiment, si vous voulez comprendre comment les ordinateurs fonctionnent vraiment, vous devez étudier la physique, puis le génie électrique, puis le génie informatique, puis l'informatique, et essentiellement progresser dans termes d'abstraction. (J'ai pris la liberté de ne pas mentionner que vous devez aussi d'abord étudier les mathématiques , pour vraiment comprendre la physique.)

Maintenant, de façon réaliste, les jours où vous pouviez donner un sens aux ordinateurs et à la programmation en construisant votre chemin à partir des détails les plus bas étaient les premiers jours des ordinateurs. À ce jour, ce domaine a trop avancé, au point qu'il ne peut plus être redécouvert de toutes pièces par une seule personne. Il y a des centaines de milliers de personnes très qualifiées se spécialisant à tous les niveaux d'abstraction, travaillant dur quotidiennement pour faire des progrès que vous ne pouvez pas espérer comprendre sans passer des années à étudier une partie spécifique à fond et à vous engager à suivre les dernières avancées.

Considérez ceci Java snippet:

public void Example() { 
    Object obj = new String("...");
    // ...
}

Vous pouvez facilement comprendre ce que cet extrait promet (et ce qu'il ne promet pas), au niveau du langage Java. Mais à moins que vous ne connaissiez bien des sujets tels que les cadres de pile, les données de tas structures, récupération de place du traçage générationnel simultané, compactage de la mémoire, analyse statique, analyse d'échappement, machines virtuelles, analyse dynamique, langage d'assemblage et protection de l'espace exécutable, vous vous trompez si vous pensez que vous connaissez vraiment tous les détails de bas niveau qui sont réellement impliqués l'exécuter sur un vrai ordinateur.

Vous pouvez également considérer cet extrait C:

void example(int i) {
    int j;
    if(i == 0) {
        j = i * 2;
        printf("Received zero, printing %d", j);
    } else {
        printf("Received non-zero, printing %d", j);
    }
}

Si vous le montrez à un débutant, ils vous diront que lorsque l'argument est différent de zéro, le contenu résiduel d'un emplacement mémoire sera imprimé, car "les variables ne sont en fait que des adresses mémoire en arrière-plan" et "lorsque vous ne ne les initialisez pas, cela signifie simplement que vous ne déplacez rien vers leur adresse "et" il n'y a rien de magique en eux ". Si vous le montrez à un non-débutant, ils vous diront que le comportement de ce programme n'est pas défini pour les valeurs non nulles du paramètre de cette fonction et que le compilateur pourrait potentiellement supprimer le conditionnel, traiter tous les arguments de cette fonction comme zéro, remplacer tous des taches d'appel de la fonction avec des appels qui passent à zéro comme argument, définissez toutes les variables qui sont jamais passées comme arguments à cette fonction à zéro, ou faites autres choses apparemment paradoxales .

Il est important de réaliser que vous travaillez toujours à un niveau d'abstraction. Le débutant dans cet exemple a pris tout ce qu'il sait en compte et est arrivé avec élégance à une réponse complètement fausse parce que (a) il/elle n'a pas lu la spécification de la langue (qui est une abstraction exprès , pas parce que les programmeurs C ne sont pas assez intelligents pour comprendre l'architecture informatique) et (b) ont essayé de raisonner sur les détails de l'implémentation qu'il/elle n'a pas complètement compris et qui ont évolué bien au-delà de son modèle mental maintenant. Cet exemple est fictif, mais il s'inspire d'idées fausses du quotidien - le genre qui mène parfois à des bogues dangereux et à des failles de sécurité parfois célèbres.

Il est également important de voir la situation dans son ensemble. Par exemple, si vous ne comprenez pas assez bien les abstractions supérieures, vous découvrirez peut-être que C a des structures, des pointeurs de structure de tailles égales, des déclarations de type incomplètes et des pointeurs de fonction, et vous les verrez probablement comme un tas de fonctionnalités non liées qui pourrait parfois être utile. Mais si vous comprenez une abstraction plus élevée comme OOP assez bien, vous reconnaîtrez les fonctionnalités susmentionnées comme les blocs de construction pour OOP concepts: les structures peuvent contenir d'autres structures) (réutilisation de code), les pointeurs de données peuvent passer quelque chose comme référence (comme les classes), le fait que ces pointeurs ont la même taille leur permet d'être substitués (sous-typage), les déclarations de type incomplètes vous permettent d'avoir des pointeurs opaques vers des structures (membres privés ) et les pointeurs de fonction vous permettent de construire des tables de répartition (polymorphisme).

Dans cet exemple fictif, la connaissance d'un langage OOP non seulement ne vous a pas empêché de comprendre C, mais il vous a en fait enseigné des concepts que vous pouvez appliquer à C. Ces concepts peuvent être appliqués de manière sélective lorsque vous en avez besoin pour rendre votre code plus facile à gérer même lorsque le langage ne vous pousse pas activement vers lui. (Je dirais qu'il existe une relation similaire entre OOP et FP, mais disons ne vous laissez pas emporter.)

Certains des meilleurs programmeurs que j'ai rencontrés sont ce qu'ils sont parce qu'ils comprennent les abstractions et qu'ils peuvent transmettre leurs connaissances à n'importe quelle langue et l'adapter à tout problème qu'ils doivent résoudre, à n'importe quel niveau où ils travaillent. Certains des pires programmeurs que j'ai rencontrés sont ce qu'ils sont parce qu'ils insistent pour se concentrer sur des détails et des anecdotes qu'ils ne comprennent pas vraiment et qui, la plupart du temps, ne sont pas exactement à jour ou pertinents pour le problème, ou applicable dans le contexte dans lequel ils tentent de les utiliser, ou n'ont jamais été vrais en premier lieu.

Tout ce que vous devez comprendre, c'est qu'il n'y a pas un seul niveau d'abstraction à un moment donné et qu'une personne n'est pas limitée à un seul niveau d'abstraction à un moment donné. Vous pouvez en comprendre un, puis passer à un autre. Vous pouvez en utiliser un, puis passer à un autre - à tout moment.

22

Finalement, je pensais que vous deviendriez un meilleur programmeur sachant cela parce que vous saurez ce qui se passe plutôt que de supposer que tout est magique.

Ce ne sont pas des choses contradictoires. Je ne sais pas comment paver une route, mais je sais que ce n'est pas magique.

Mais il y a un mois, je suis tombé sur ce livre intitulé Structure et interprétation des programmes informatiques et tout ce qui se trouve sur le Web suggère que c'est l'un des meilleurs livres d'informatique et vous vous améliorerez en tant que programmeur en le lisant.

Oui, c'est absolument vrai.

Ne devrions-nous surtout pas éviter toutes les abstractions et observer ce qui se passe vraiment à très bas niveau?

Peut-être une ou deux fois, mais le faire à chaque fois vous empêchera d'être un bon programmeur. Vous n'avez pas besoin de regarder les électrons passer à travers une porte pour savoir que ce n'est pas magique. Vous n'avez pas besoin de voir le processeur traduire ces électrons en représentation bit à bit d'un nombre pour savoir que ce n'est pas magique. Vous n'avez pas besoin de voir ces morceaux descendre le fil pour savoir que ce n'est pas magique. Il y a quelques dizaines d'abstractions nécessaires juste pour mettre ces lettres côte à côte. Quelques centaines probablement pour les obtenir sur votre ordinateur à partir des serveurs de SE.

Personne les connaît tous - pas en profondeur.

Il s'agit d'un problème très courant avec les débutants en programmation. Ils veulent savoir comment les choses fonctionnent. Ils pensent que le bas niveau est le meilleur niveau, car il leur donne le plus de pouvoir, de contrôle ou de connaissances. Ce ne est pas.

Ouais, tu ne peux pas le traiter comme de la magie. Mais vous n'avez vraiment pas besoin de savoir ce genre de choses non plus. Concaténer des cordes à la main n'est pas intéressant. Rouler votre propre algorithme de tri n'est pas intéressant. Parce que n'importe quel programmeur peut obtenir le même résultat en quelques ordres de grandeur en moins de temps en utilisant quelque chose écrit par de meilleurs programmeurs il y a des décennies.

40
Telastyn

Je sais pourquoi l'abstraction est excellente, mais cela ne vous empêche-t-il pas d'apprendre comment fonctionnent les ordinateurs?

Certainement pas. Si vous voulez comprendre les abstractions au travail, étudiez ces abstractions. Si vous voulez comprendre les détails techniques de bas niveau d'un véritable ordinateur physique, étudiez ces détails. Si vous voulez comprendre les deux, étudiez les deux. (À mon avis, un bon programmeur fera cela.)

Vous semblez vous être coincé dans une fausse dichotomie, comme si vous ne pouviez comprendre qu'un seul niveau d'abstraction à la fois (ou, pire, comme si un seul niveau d'abstraction existe à la fois). C'est un peu comme suggérer qu'il est fondamentalement impossible pour quelqu'un d'avoir une compréhension à la fois de la physique et des mathématiques.

Un bon début serait de découvrir la distinction entre l'informatique et la programmation.

32

Une compétence clé en programmation consiste à penser simultanément à plusieurs niveaux d'abstraction. Une autre compétence clé est la construction d'abstractions; cette compétence utilise la précédente. La programmation de bas niveau est précieuse en partie parce qu'elle exerce et étend ces deux compétences.

SICP modélise et implémente des interprètes, des simulateurs pour un modèle de machine et un compilateur pour ce modèle de machine (dont la sortie peut ensuite être exécutée sur le simulateur). Le modèle de machine, bien que très simple, n'est pas intrinsèquement moins bas niveau que x86_64. Franchement, une bonne partie de la programmation de bas niveau traite des interfaces matérielles/firmware arbitraires et obscures qui ne sont pas meilleures que les règles arbitraires de la logique métier.

16

Je sais pourquoi l'abstraction est excellente, mais cela ne vous empêche-t-il pas d'apprendre comment fonctionnent les ordinateurs? Suis-je en train de manquer quelque chose?

Allez à un spectacle de magie et vous serez diverti mais vous ne comprendrez pas comment fonctionnent les astuces. Lisez un livre sur la magie et vous apprendrez comment fonctionnent les tours, mais vous ne serez toujours pas divertissant.

Faire les deux. Travailler dur. Et vous pourriez être les deux.

J'avais travaillé à des niveaux élevés SOLID, bash, UML. J'ai travaillé à des niveaux bas, TASM, unités logiques arithmétiques, circuits analogiques. Je peux vous dire, il n'y a aucun niveau auquel vous pouvez travailler qu'il n'y a pas de magie abstraite loin de vous.

La clé n'est certainement pas de comprendre tous les niveaux d'abstraction à la fois. C'est de comprendre un niveau suffisamment bien pour l'utiliser correctement et de savoir quand il est temps de passer à un autre.

Toute technologie suffisamment avancée est indiscernable de la magie.

Arthur C Clark

5
candied_orange

L'ingénierie logicielle comporte plusieurs niveaux de détails. Votre question est "quel est le niveau le plus gratifiant, le plus digne et le plus intéressant?"

Cela dépend de votre tâche ou de ce que vous voulez être, de ce qui vous intéresse. Pour les grands systèmes, vous ne devez pas vous soucier du décalage des bits et des cycles d'horloge. Pour les logiciels intégrés fonctionnant sur un micro-contrôleur simple, vous voudrez probablement garder un œil sur la quantité de mémoire que vous utilisez et vous devrez peut-être écrire des routines de synchronisation primitives.

Parfois, un choix fait à un niveau d'abstraction élevé peut avoir un impact sur les performances ou l'utilisation des ressources de votre système. Reconnaître cela et comprendre pourquoi et comment aidera à faire le meilleur choix ou à trouver un moyen de rendre un système existant plus efficace. Cela fonctionne dans les deux sens: sachant qu'il existe un utilitaire de haut niveau vous empêchera d'inventer votre propre roue dans votre domaine de bas niveau. Donc, avoir une certaine compréhension d'autres niveaux que celui sur lequel vous travaillez peut vous aider à être plus efficace.

Sur un plan personnel, vous voudrez peut-être vous demander "Est-ce que j'aime poser des briques ou est-ce que je veux concevoir des maisons?" Ou peut-être faire des plans de villes. Ou améliorer la science qui fait une brique plus solide, plus légère et moins chère?

3
Martin Maat

Les abstractions que nous enseignons en informatique sont les choses qui, historiquement, ont été jugées les plus bénéfiques pour la plupart des gens qui écrivent la plupart des programmes. Vous ne pouvez pas écrire un programme moderne dans Assembly, simplement en raison de la taille des programmes modernes et des contraintes de temps imposées aux développeurs. Vous devez être prêt à atteindre vos objectifs sans comprendre à 100% ce qui se passe. Les abstractions sont de puissants outils pour vous aider à faire exactement cela.

Maintenant, dans ma première phrase, j'ai eu beaucoup de "mâts". Dans votre carrière, vous allez vous retrouver dans des situations, de temps en temps, où les abstractions que vous avez apprises vous égareront. À ces moments, vous devrez creuser d'autres connaissances. Parfois, c'est aussi simple que d'apprendre la bonne abstraction pour le travail. D'autres fois, cela nécessite exactement ce que vous avez fait: essayer de comprendre ce que fait le système sous-jacent lorsque vous utilisez ces abstractions.

Pour prendre un exemple, regardez le multithreading. Le multithreading traditionnel utilisant des mutex, des sections critiques, des variables de condition, etc., est très bien compris à un niveau abstrait. Vous n'avez pas besoin de comprendre comment le noyau échange et interrompt les threads, ou comment les interruptions pilotées par minuterie volent le contrôle à vos threads utilisateur pour laisser le noyau faire sa magie. Vous n'aurez peut-être jamais besoin d'apprendre ce qu'est un RCU, ou pourquoi à un moment donné au plus profond des entrailles du noyau, vous êtes obligé d'arrêter d'utiliser des mutex. En fait, si vous essayez de le comprendre au niveau du noyau, vous pouvez faire des erreurs dangereuses. Je ne peux pas compter le nombre de cas de course que j'ai dû résoudre parce que quelqu'un pensait qu'une opération était "suffisamment atomique" et ne la protégeait pas correctement avec des mutex. Vous devez vraiment comprendre les noyaux (et les compilateurs) avant que ces connaissances puissent vous aider à écrire du code mutlithread sûr. Il est beaucoup plus efficace de tout faire dans la couche abstraite des mutex.

Permet maintenant de pousser un peu. Au lieu d'écrire "la plupart" des programmes multithread, qui conviennent parfaitement aux abstractions, permet de commencer à écrire le code Edge qui saigne vraiment, en utilisant des opérations atomiques. Vous pouvez maintenant apprendre les opérations atomiques en tant que concept abstrait et les utiliser avec succès, mais vous vous laisserez gratter la tête en vous demandant ce qu'ils fumaient lorsqu'ils ont assemblé l'API. Il y a toutes sortes de choses qui apparaissent dans les détails de synchronisation de la mémoire des opérations atomiques qui vous font mal à la tête. Dans ce cas, apprendre des choses à partir de zéro, comme vous l'avez mentionné, est très utile pour comprendre pourquoi les abstractions font ce qu'elles font. Une fois que vous comprenez ce que font les caches et comment ils se regardent et se poussent pour maintenir la synchronisation, vous pouvez voir pourquoi l'absurdité de l'API de l'opération atomique est survenue - c'était une nécessité matérielle. Une fois que vous les comprendrez, vous serez en meilleure position pour comprendre comment extraire ces dernières millisecondes de votre précieux algorithme en temps réel et sauver la journée!

Les deux approches ont donc leur valeur. Vous pourrez produire plus rapidement du code plus précieux si vous êtes prêt à accepter des abstractions sans les lier jusqu'au matériel. Cependant, il y aura des cas où une compréhension du matériel vous permettra de repousser les limites des abstractions d'une manière que d'autres développeurs n'auraient jamais cru possible. Un juste milieu, dis-je. Trouvez un équilibre entre les deux!

3
Cort Ammon

Quelle heure est-il?

Est-il temps de devenir un programmeur qui sait tout ou est-il temps de devenir un programmeur productif?

Connaître les couches d'abstraction qui existent en dessous de celles parmi lesquelles vous travaillez est une bonne chose, cela vous permet de mieux comprendre la structure de votre travail et cela permettra même de créer de meilleures solutions.

Pourtant, vous faites cela, vous étudiez quand ce n'est pas le moment d'être productif. Quand il est temps d'être productif, vous prenez des outils de haut niveau et vous construisez avec eux. Utiliser toutes les connaissances que vous avez sur le fonctionnement des choses et exprimer la solution en termes qui ont du sens pour l'espace du problème.

Bien sûr, vous seriez obligé de savoir utiliser de tels outils, il y a le compromis du temps qu'il faut pour construire avec un mauvais outil vs le temps d'apprendre à utiliser un outil plus approprié. Cela dépasse la portée de cette question. Pourtant, vous comprenez qu'il y a un avantage à connaître divers outils.


Jusqu'à présent, j'ai toujours cru que vous devriez apprendre des langages de programmation qui vous font faire des choses de bas niveau (par exemple C)

Ce n'est pas que vous devriez , c'est que c'est une bonne chose de connaître des choses de bas niveau.

pour comprendre ce qui se passe réellement sous le capot et comment l'ordinateur fonctionne vraiment.

Tout d'abord, vous n'avez pas besoin d'un langage de programmation pour apprécier le fonctionnement de l'ordinateur. Deuxièmement ... je crains que C ne soit trop élevé et un peu étroit. C est une bonne cartographie d'une ancienne version de l'architecture matérielle, suffisamment abstraite pour être portable à la source sur différents systèmes. Si vous voulez une compréhension approfondie, vous devez viser le langage d'assemblage (notez que le langage d'assemblage est une abstraction du langage machine).

Finalement, je pensais que vous deviendriez un meilleur programmeur sachant cela

Oui, vous deviendrez un meilleur programmeur en sachant cela.

Parce que vous saurez ce qui se passe plutôt que de supposer que tout est magique.

Vous n'avez pas besoin de savoir comment les choses fonctionnent pour savoir qu'elles ne sont pas magiques. Tout ce dont vous avez besoin est une appréciation de leur fonctionnement, de ses coûts et de ce que vous pouvez en attendre.

Et savoir des choses de bas niveau est beaucoup plus intéressant que d'écrire des programmes d'affaires, je pense.

Eh bien ... les trucs de bas niveau sont intéressants dans le sens où ils suscitent la réflexion et inspirent la curiosité. Les programmes commerciaux peuvent avoir un autre sens d'intérêt, celui lié à l'argent.

En outre, vous pouvez avoir l'impression que tous les programmes d'entreprise sont à peu près les mêmes: certaines bases de données, certaines classes de modèles, certains CRUD, etc. Ce sont les ennuyeux. Mais regardez la diversité des logiciels et la diversité des entreprises qui les entourent. Ne vous contraignez pas.

Mon objectif est de devenir un meilleur programmeur, de mieux comprendre l'informatique et cela m'a vraiment dérouté.

Si vous voulez devenir un meilleur programmeur, vous apprendrez à écrire du code réutilisable. Parce que le fait d'avoir du code sur lequel vous pouvez faire confiance et que vous n'avez pas à réécrire à chaque fois vous rendra plus productif (comme dans: faire la même tâche en moins de temps, mais aussi comme: avoir moins de bugs). Si vous faites cela, vous pourriez être intéressé à placer votre code réutilisable dans un format réutilisable et partageable ... et peut-être même le partager avec d'autres développeurs. Si au moins vous envisagez de le faire, j'espère que cela développera une appréciation du code réutilisable partagé par d'autres, une appréciation de l'utilité des outils de développement et une appréciation des langages de niveau supérieur. Ces choses font de vous un meilleur programmeur.

D'autre part, si vous voulez apprendre l'informatique, vous devrez ignorer les spécificités. Par exemple, quand il s'agit de voir si un algorithme est plus efficace qu'un autre, les résultats ne devraient pas être limités par le processeur particulier que vous avez. L'informatique s'apparente davantage aux mathématiques, elle est abstraite.

Ne devrions-nous surtout pas éviter toutes les abstractions et observer ce qui se passe vraiment à très bas niveau?

Non, vous ne devez pas éviter les abstractions. Et oui, vous pouvez observer ce qui se passe à des niveaux assez bas.

Quelle heure est-il? Est-il temps d'apprendre comment les choses fonctionnent ou est-il temps d'être productif?

S'il est temps d'apprendre comment les choses fonctionnent, alors n'évitez pas les abstractions ... observez-les en action depuis le niveau inférieur, vous les créez même vous-même! Découvrez comment et pourquoi ils fonctionnent comme ils le font.

S'il est temps d'être productif, alors n'évitez pas les abstractions ... Sélectionnez les bonnes pour la tâche à accomplir et tirez-en profit.

Si vous êtes intéressé à apprendre à être plus productif, considérez que les outils sont là pour être utilisés. Pourquoi voudriez-vous essayer de percer le bois en poussant un clou à mains nues alors qu'il y a des marteaux disponibles? Pourquoi utiliseriez-vous une aiguille aimantée et une main stable pour retourner les bits sur un disque dur quand il y a des éditeurs de texte à portée de main?

N'évitez pas les abstractions, ce sont des outils.

Je sais pourquoi l'abstraction est excellente, mais cela ne vous empêche-t-il pas d'apprendre comment fonctionnent les ordinateurs? Suis-je en train de manquer quelque chose?

Vous oubliez que vous pouvez apprendre plusieurs choses. Apprentissage Java ne vous empêche pas d'apprendre C, Learning C ne vous empêche pas d'apprendre C #. Learning OOP ne vous empêche pas d'apprendre des données l'apprentissage des structures de données ne vous empêche pas d'apprendre AOP. L'apprentissage du langage d'assemblage ne vous empêche pas d'apprendre l'électronique; l'apprentissage de l'électronique ne vous empêche pas d'apprendre les portes logiques.


Personne ne sait tout ce qu'il y a pour faire fonctionner votre ordinateur. Mais cela ne signifie pas que vous pouvez atteindre un niveau de connaissance confortable partout. En commençant par la physique nucléaire et jusqu'à l'expérience utilisateur, vous pouvez trouver des cours en ligne et des communautés avec des gens prêts à aider.

Edit: celui ci-dessus peut être une opinion impopulaire. J'ai trois choses à dire à ce sujet: 1) J'ai dit à l'aise - je veux dire, avec vous-même. Je n'ai jamais dit que vous seriez un expert sur le terrain. 2) Je mentionne les cours en ligne comme point de départ - et oui, il y a des cours en ligne sur la physique nucléaire (payés si vous voulez quelque chose de bien, mais en ligne). Il y a aussi des cours qui vous mènent de portes logiques aux jeux vidéo primitifs 3) Je comprends qu'il y a de la valeur dans la spécialisation, et je ne voulais pas encourager à tout apprendre.

Encore une fois, demandez-vous si c'est la meilleure utilisation de votre temps ... lorsque le client vous embauchera pour créer une nouvelle application mobile, arrêterez-vous le projet parce que vous ne savez pas encore comment fonctionnent les semi-conducteurs? Non, bien sûr que non.

Le pourquoi est le détail. Vous pouvez dire "non" parce que vous n'êtes pas intéressé par la physique ou les matériaux ... pourtant, vous devez dire "non", car il est temps d'être productif. Quoi qu'il en soit, nous convenons que vous pouvez choisir les niveaux d'abstraction que vous apprenez.

Vous pouvez prétendre avoir évité les abstractions en général, vous n'en avez évité que quelques-unes.


L'approche consistant à tout comprendre en le divisant en ses composantes échoue, elle a échoué dans de nombreuses disciplines. En effet, il existe des comportements émergents qui ne sont visibles - et ne peuvent donc être étudiés - que lorsque les composants sont intégrés.

Les ingénieurs civils se soucient-ils de la position des atomes individuels? non, ils ne le font pas. Ils ne prennent même pas la peine d'essayer de créer de nouveaux matériaux (ce travail est pour un ingénieur des matériaux) - pour l'ingénieur civil, les matériaux sont une abstraction pratique. Ils n'ont pas besoin de savoir comment les atomes sont arrangés, ils ont besoin de combien ils coûtent et comment ils se comportent (comment ils réagissent au stress, à l'humidité, etc.), et néanmoins ils savent que les matériaux ne sont pas magiques.

Il y a peu de choses que vous pouvez apprendre sur la biologie si vous insistez pour tout casser en atomes. Il y a peu de choses que vous pouvez apprendre sur la psychologie si vous insistez pour tout casser en neurones.

Vous avez eu l'idée.

3
Theraot

À l'autre extrémité du spectre se trouve un autre livre qui est souvent salué comme un classique de la façon d'enseigner les algorithmes: l'art de la programmation informatique de Donald E. Knuth . DEK a donné tous ses algorithmes dans un langage machine (faux, abstrait), car selon lui, les programmeurs auront tendance à écrire du code simple et efficace dans le langage qu'ils utilisent, et la taille et les performances du code machine sont ce qui est vraiment importe.

Ce livre est vraiment un classique, et il a fait une excellente remarque - surtout. Afin d'éviter une abstraction qui cache le coût réel de ce que faisait le programme, ses premières éditions n'avaient pas de système d'exploitation et la convention d'appel de ses programmes d'exemple utilisait du code auto-modifiable. Sur un processeur de bureau moderne, de tels programmes ne fonctionneraient même pas, car le processeur et le système d'exploitation ne permettront pas au code d'application de communiquer directement avec le matériel, et les processeurs modernes ont des caches d'instructions que l'auto-modification invaliderait.

De même, si vous voulez écrire du code rapide, vous profilerez et verrez que les sections les plus critiques pour les performances sont des boucles qui sont appelées fréquemment. Qu'est-ce qu'une boucle? Il offre les garanties suivantes: chaque itération s'exécutera séquentiellement, sur la base d'instructions arbitraires, mais généralement la valeur d'un index de boucle qui peut être modifié arbitrairement et qui a une adresse en mémoire que vous pouvez récupérer avec &. Seulement, il s'avère que, sur le matériel moderne, vous obtenez des accélérations avec parallélisme: soit en vectorisant la boucle, soit en partageant le travail entre les threads. Et il s'avère que la construction C de bas niveau, qui correspondait très étroitement à ce que les machines PDP pour lesquelles elle était écrite à l'origine étaient capables de faire, brise un certain nombre de garanties qui seraient très utiles à un optimiseur moderne.

Certaines des abstractions du langage de programmation que C n'a pas, telles que foreach, les conteneurs et les itérateurs, ou même la programmation fonctionnelle, peuvent compiler la plupart de ces boucles de manière plus efficace et plus sûre aujourd'hui que la plupart des optimisations qui jadis rendu le code C efficace, comme l'arithmétique des pointeurs et le périphérique de Duff. De même, les jeux DOS étaient extrêmement efficaces car ils fonctionnaient si près du métal, jusqu'à ce que les gens ne les exécutent que sur des émulateurs tels que DOSBox. Personne ne s’inquiète de la taille du code aujourd’hui, et les programmeurs ne gardent pas un tas de compteurs pour chronométrer leur jeu car c’est tellement plus simple de garder un horodatage et de faire la division et le reste. Tout comme personne ne multiplie et ne divise en convertissant vers et depuis des tables de logarithmes.

Une chose que vous voulez comprendre est la performance de vos opérations lorsque vous les implémentez aujourd'hui. Qu'est-ce qui fonctionne rapidement sur du matériel moderne? Mais il est également important que l'élégance mathématique soit intemporelle. Vous voulez être en mesure d'exprimer votre conception de manière claire et compréhensible, vous voulez être en mesure de l'optimiser efficacement et vous voulez être en mesure de comprendre quelles parties du projet doivent être refactorisées à un niveau d'abstraction inférieur.

1
Davislor

Vous aimerez peut-être lire Zen et l'art de l'entretien des motos qui répond à cette question. La conclusion à laquelle il arrive est que vous devez viser à générer la plus grande "qualité" au (x) niveau (x) d'abstraction que vous choisissez. Parfois, cela signifie mieux comprendre les niveaux au-dessus et en dessous de vous, mais généralement vous ne pourrez pas maîtriser tous les niveaux.

1
DrMcCleod

Des abstractions sont nécessaires pour gérer la complexité , qui est le Némésis de tous les programmeurs. Il est tout aussi important d'apprendre à utiliser les abstractions que d'en connaître les détails.

Une solution à un problème du monde réel doit avoir une représentation qui ressemble étroitement au modèle du problème. C'est pourquoi un jeu de dés a une classe appelée Die avec une méthode appelée roll(), et pas un bloc de code avec 011100110000001110101000100001010101000100 (en supposant que ces abstractions de chiffres binaires avaient du sens sur une plate-forme). Cela a été appelé écart de représentation par Larman. Les abstractions permettent de maintenir cet écart plus petit - une stratégie connue sous le nom de Low Representaitonal Gap (LRG). Il rend le code plus facile à suivre selon les exigences et à comprendre. L'approche Domain-Driven Design (DDD) est similaire.


UML class diagram of DiceGame

En tant que programmeurs, nous sommes naturellement attirés par des puzzles complexes. Nous sommes fiers d'avoir résolu un problème complexe. Mais le paradoxe est que nous, en tant qu'humains, ne faisons pas beaucoup de travail lorsque les choses sont trop complexes tout le temps. Rester simple (via des abstractions) est préférable, si nous avons le choix.

1
Fuhrmanator

Comme indiqué dans réponse de philipxy , tout ce qui est numérique est une abstraction. Même la vue de l'ingénierie électrique des courants et des tensions est une abstraction.

J'ai travaillé en tant qu'architecte informatique, rédacteur de compilateur et développeur de systèmes d'exploitation. J'ai eu l'expérience d'écrire des programmes Java que j'avais l'intention d'exécuter sur un serveur que j'ai aidé à concevoir.

La connaissance cycle par cycle de la façon exacte dont un cache manquerait fonctionnerait si les données devaient être modifiées et était actuellement dans le cache en mode lecture seule dans un processeur différent était beaucoup trop détaillée pour être utile lors de l'écriture d'un Java. D'un autre côté, lorsque j'analysais les effets sur les performances de l'ajout d'un cycle de latence à certains cas de cache manquant, j'avais besoin de ce niveau de détail.

Un élément clé de l'art de la programmation est de choisir le bon modèle pour le problème que vous résolvez.

0
Patricia Shanahan

Comme d'autres l'ont souligné, tout est à la fois une abstraction et un détail. Les abstractions vous permettent de vous concentrer sur la compréhension et la manipulation des concepts impliqués tandis que la connaissance des détails vous permet de les mettre en œuvre. Pour un architecte de solution, le langage de programmation n'est qu'un détail, pour un codeur optimisant un algorithme de tri, un type de données n'est qu'une abstraction. Je recommande toujours au moins une connaissance des détails au niveau inférieur à ceux requis, ce qui vous aidera à éviter de faire des choix d'implémentation pauvres ou coûteux, mais je recommande également une connaissance des concepts au niveau supérieur à ceux requis pour comprendre le contexte de votre solution. attend dans.

0
Paul Smith