web-dev-qa-db-fra.com

Comment l'augmentation de la complexité des systèmes a-t-elle affecté les générations successives de programmeurs?

En tant que "nouveau" programmeur (j'ai écrit une première ligne de code en 2009), j'ai remarqué qu'il est relativement facile de créer un programme qui présente des éléments assez complexes aujourd'hui avec des choses comme le framework .NET par exemple. La création d'une interface visuelle ou le tri d'une liste peut être fait avec très peu de commandes maintenant.

Lorsque j'apprenais à programmer, j'apprenais également la théorie informatique en parallèle. Des choses comme les algorithmes de tri, les principes de fonctionnement du matériel ensemble, l'algèbre booléenne et les machines à états finis. Mais j'ai remarqué que si je voulais tester un principe très basique que j'avais appris en théorie, il était toujours beaucoup plus difficile de commencer parce que tant de technologies étaient obscurcies par des choses comme les bibliothèques, les cadres et le système d'exploitation.

Créer un programme efficace en mémoire était nécessaire il y a 40/50 ans car il n'y avait pas assez de mémoire et c'était cher, donc la plupart des programmeurs accordaient une attention particulière aux types de données et à la façon dont les instructions seraient traitées par le processeur. De nos jours, certains pourraient faire valoir qu'en raison de l'augmentation de la puissance de traitement et de la mémoire disponible, ces préoccupations ne sont pas une priorité.

Ma question est de savoir si les programmeurs plus âgés voient des innovations comme celles-ci comme une aubaine ou une couche supplémentaire à analyser, et pourquoi pourraient-ils le penser? Et les programmeurs plus jeunes bénéficient-ils de plus d'apprentissage de la programmation de bas niveau AVANT d'explorer les domaines des bibliothèques étendues? Si oui, pourquoi?

130
Adam

il n'est tout simplement pas nécessaire en raison de l'augmentation de la puissance de traitement et de la mémoire disponibles.

Avoir une mémoire bon marché, d'énormes disques et des processeurs rapides n'est pas la seule chose qui a libéré les gens de la nécessité d'obséder à chaque octet et cycle. Les compilateurs sont maintenant bien, bien mieux que les humains à produire du code hautement optimisé lorsque cela est important.

De plus, n'oublions pas ce que nous essayons réellement d'optimiser, c'est-à-dire la valeur produite pour un coût donné. Les programmeurs sont bien plus chers que les machines. Tout ce que nous faisons qui fait que les programmeurs produisent des programmes fonctionnels, corrects, robustes et complets plus rapidement et à moindre coût conduit à la création de plus de valeur dans le monde.

Ma question est cependant de savoir ce que les gens pensent de cette "dissimulation" d'éléments de niveau inférieur. Les programmeurs plus âgés y voient-ils une aubaine ou une couche inutile à franchir?

Il est absolument nécessaire de faire tout travail. J'écris des analyseurs de code pour vivre; si je devais m'inquiéter de l'allocation des registres ou de la planification du processeur ou de l'un de ces millions d'autres détails, je ne passerais pas mon temps à corriger les bogues, à examiner les rapports de performances, à ajouter des fonctionnalités, etc.

Toute la programmation concerne l'abstraction de la couche en dessous de vous afin de créer une couche plus précieuse par-dessus. Si vous faites un "diagramme de couches" montrant tous les sous-systèmes et comment ils sont construits les uns sur les autres, vous constaterez qu'il existe littéralement des dizaines de couches entre le matériel et l'expérience utilisateur. Je pense que dans le diagramme de gâteau de couche Windows, il y a quelque chose comme 60 niveaux de sous-systèmes nécessaires entre le matériel brut et la possibilité d'exécuter "hello world" en C #.

Pensez-vous que les programmeurs plus jeunes bénéficieraient de plus d'apprentissage de la programmation de bas niveau AVANT d'explorer les domaines des bibliothèques étendues?

Vous mettez l'accent sur AVANT, je dois donc répondre à votre question par la négative. J'aide un ami de 12 ans à apprendre à programmer en ce moment et vous feriez mieux de croire que je les démarre dans Processing.js et non dans l'assembleur x86. Si vous démarrez un jeune programmeur dans quelque chose comme Processing.js ils écriront leurs propres jeux de shoot-em-up dans environ huit heures. Si vous les démarrez dans l'assembleur, ils multiplieront trois nombres ensemble en huit heures environ. Selon vous, lequel est le plus susceptible de susciter l'intérêt d'un jeune programmeur?

Maintenant, si la question est "les programmeurs qui comprennent la couche n du gâteau bénéficient-ils de la compréhension de la couche n-1?" la réponse est oui, mais cela est indépendant de l'âge ou de l'expérience; il est toujours possible d'améliorer votre programmation de niveau supérieur en comprenant mieux les abstractions sous-jacentes.

174
Eric Lippert

J'avais des idées à ce sujet, et je les ai mises dans un livre il y a 20 ans . Il est épuisé depuis longtemps, mais vous pouvez toujours obtenir des copies utilisées sur Amazon .

Une réponse simple à votre question est aussi vieille qu'Aristote: La nature a horreur du vide . Autant les machines sont devenues plus rapides et plus grandes, plus les logiciels sont devenus plus lents et plus gros.

Pour être plus constructif, j'ai proposé que la théorie de l'information et sa pertinence directe pour les logiciels fassent partie de l'enseignement de l'informatique. Il n'est enseigné que maintenant, voire pas du tout, de manière très tangentielle.

Par exemple, le comportement big-O des algorithmes peut être très bien et intuitivement compris si vous considérez un programme comme un canal d'information de type Shannon, avec des symboles d'entrée, des symboles de sortie, du bruit, une redondance et une bande passante.

D'un autre côté, la productivité d'un programmeur peut être comprise en termes similaires en utilisant la théorie de l'information de Kolmogorov. L'entrée est une structure conceptuelle symbolique dans votre tête, et la sortie est le texte du programme qui sort du bout des doigts. Le processus de programmation est le canal entre les deux. Lorsque du bruit entre dans le processus, il crée des programmes incohérents (bogues). Si le texte du programme de sortie a une redondance suffisante, il peut permettre de détecter et de corriger les bogues (détection et correction des erreurs). Cependant, s'il est trop redondant, il est trop grand et sa taille même, combinée au taux d'erreur, provoque l'introduction de bugs. À la suite de ce raisonnement, j'ai passé une bonne partie du livre à montrer comment traiter la programmation comme un processus de conception de langage , dans le but d'être capable de définir les langages spécifiques au domaine appropriés à un besoin. Nous rendons hommage aux langages spécifiques au domaine dans l'éducation CS, mais, encore une fois, c'est tangentiel.

Construire des langues est facile. Chaque fois que vous définissez une fonction, une classe ou une variable, vous ajoutez du vocabulaire à la langue avec laquelle vous avez commencé, créant ainsi une nouvelle langue avec laquelle travailler. Ce qui n'est généralement pas apprécié, c'est que le but devrait être de faire correspondre le nouveau langage à la structure conceptuelle du problème. Si cela est fait, cela a pour effet de raccourcir le code et le rendre moins bogué simplement parce que, idéalement, il y a une correspondance 1-1 entre concepts et code. Si le mappage est 1-1, vous pouvez faire une erreur et coder un concept de manière incorrecte en tant que concept différent, mais le programme ne se bloquera jamais, ce qui se produit lorsqu'il encode aucune exigence cohérente .

Nous n'obtenons pas cela. Pour tous nos courageux discours sur la conception de systèmes logiciels, le rapport du code aux exigences devient de plus en plus grand.

C'est vrai, nous avons des bibliothèques très utiles. Cependant, je pense que nous devons être très circonspects au sujet de l'abstraction. Nous ne devons pas supposer que si B s'appuie sur A et c'est bien, que si C s'appuie sur B, c'est encore mieux. Je l'appelle le phénomène "princesse et pois". Empiler des couches sur quelque chose de gênant ne le résout pas nécessairement.

Pour terminer un long post, j'ai développé un style de programmation (qui me pose parfois des problèmes) où

  • L'invention n'est pas une mauvaise chose. C'est une bonne chose, comme c'est le cas dans d'autres branches de l'ingénierie. Bien sûr, cela peut créer une courbe d'apprentissage pour les autres, mais si le résultat global est une meilleure productivité, cela en vaut la peine.
  • Code minimaliste de style haiku. Cela en particulier vaut pour la conception de la structure des données. D'après mon expérience, le plus gros problème des logiciels de nos jours est la structure de données gonflée.
50
Mike Dunlavey

L'abstraction de haut niveau est essentielle pour réaliser des progrès continus en informatique.

Pourquoi? Parce que les humains ne peuvent avoir autant de connaissances dans leur tête qu'à un moment donné. Les systèmes modernes à grande échelle ne sont possibles qu'aujourd'hui car vous pouvez exploiter ces abstractions. Sans ces abstractions, les systèmes logiciels s'effondreraient simplement sous leur propre poids.

Chaque fois que vous écrivez une méthode, vous créez une abstraction. Vous créez un peu de fonctionnalités cachées derrière un appel de méthode. Pourquoi les écrivez-vous? Parce que vous pouvez tester la méthode, prouver qu'elle fonctionne, puis invoquer cette fonctionnalité à tout moment en appelant la méthode, et vous n'avez plus à penser au code qui se trouve à l'intérieur de cette méthode.

Au tout début de l'informatique, nous utilisions le langage machine. Nous avons écrit de très petits programmes bare metal avec une connaissance intime du matériel pour lequel nous les écrivions. Ce fut un processus minutieux. Il n'y avait aucun débogueur; votre programme a généralement fonctionné ou s'est écrasé. Il n'y avait pas d'interface graphique; tout était en ligne de commande ou en batch. Le code que vous avez écrit ne fonctionnerait que sur cette machine particulière; cela ne fonctionnerait pas sur une machine avec un processeur ou un système d'exploitation différent.

Nous avons donc écrit des langages de haut niveau pour résumer tous ces détails. Nous avons créé des machines virtuelles afin que nos programmes puissent être portables sur d'autres machines. Nous avons créé un garbage collection afin que les programmeurs n'aient pas à être aussi diligents dans la gestion de la mémoire, ce qui a éliminé toute une classe de bogues difficiles. Nous avons ajouté la vérification des limites à nos langues afin que les pirates ne puissent pas les exploiter avec des dépassements de tampon. Nous avons inventé la programmation fonctionnelle afin de pouvoir raisonner différemment sur nos programmes, et l'avons redécouvert récemment pour mieux tirer parti de la concurrence.

Toute cette abstraction vous isole-t-elle du matériel? Bien sûr. Vivre dans une maison au lieu de planter une tente vous isole-t-il de la nature? Absolument. Mais tout le monde sait pourquoi ils vivent dans une maison au lieu d'une tente, et construire une maison est un jeu de balle complètement différent de la mise en place d'une tente.

Pourtant, vous pouvez toujours planter une tente quand cela est nécessaire, et dans la programmation, vous pouvez (si vous êtes si enclin) toujours descendre à un niveau plus proche du matériel pour obtenir des performances ou des avantages de mémoire que vous pourriez ne pas sinon réalisez dans votre langue de haut niveau.


Pouvez-vous trop abstraire? "Dépasser la plomberie", comme Scotty dirait? Bien sûr vous pouvez. Écrire de bonnes API est difficile. Il est encore plus difficile d'écrire de bonnes API qui incarnent correctement et complètement le domaine problématique, d'une manière intuitive et découvrable. Empiler de nouvelles couches de logiciels n'est pas toujours la meilleure solution. Software Design Patterns ont, dans une certaine mesure, aggravé cette situation, car les développeurs inexpérimentés les recherchent parfois lorsqu'un outil plus pointu et plus léger est plus approprié.

35
Robert Harvey

Un très bon entraînement implique les deux extrêmes, ainsi qu'un pont entre les deux.

Côté bas niveau: comment un ordinateur exécute le code à partir de zéro *, y compris la connaissance du langage d'assemblage et ce que fait un compilateur.

Côté haut niveau: concepts généraux, par ex. utiliser des tableaux associatifs, des fermetures, etc. sans perdre de temps à vous soucier de son fonctionnement sous le capot.

À mon humble avis, tout le monde devrait avoir une expérience des deux, y compris leurs inconvénients, et un avant-goût de la manière de passer de concepts de bas niveau à des concepts de haut niveau. Vous aimez les tableaux associatifs? Génial, essayez maintenant de les utiliser sur un processeur intégré à 50 cents avec 1 Ko de RAM. Comme écrire du code rapide en utilisant C? Très bien, vous avez maintenant trois semaines pour écrire une application Web; vous pouvez passer votre temps à traiter les structures de données et la gestion de la mémoire à l'aide de C, ou vous pouvez passer votre temps à apprendre un nouveau cadre Web, puis à mettre en œuvre l'application Web en quelques jours.

Pour ce qui est de la complexité: je pense que il est trop facile de nos jours de créer des systèmes complexes sans comprendre clairement le coût de le faire . En conséquence, nous avons, en tant que société, accumulé une énorme quantité de dette technique qui nous mord de temps en temps. C'est comme des tremblements de terre (juste le coût de la vie près d'une faille géologique, non?), Mais ça s'aggrave progressivement. Et je ne sais pas quoi faire à ce sujet. Idéalement, nous apprendrions et nous améliorerions dans la gestion de la complexité, mais je ne pense pas que cela se produira. Une formation d'ingénieur responsable doit inclure beaucoup plus de discussions sur les conséquences de la complexité que la plupart de nos universités n'en offrent actuellement.


* et, de toute façon, où est le "terrain" dans la façon dont un ordinateur exécute le code? S'agit-il d'un langage d'assemblage? Ou l'architecture informatique? Ou la logique numérique? Ou des transistors? Ou la physique des appareils?

9
Jason S

Je pense que la programmation de haut niveau présente de nombreux avantages et est un élément essentiel d'un langage de programmation. L'une des raisons pour lesquelles Java a réussi, c'est qu'il possède une bibliothèque complète. Vous obtenez plus avec moins de code - il suffit d'appeler une fonction prédéfinie.

Nous pouvons maintenant distinguer les utilisateurs de langage de programmation des auteurs de langage de programmation (auteurs de compilateurs). Nous laissons les optimisations aux rédacteurs du compilateur. Nous nous concentrons davantage sur la maintenabilité, la réutilisation, etc.

7
Ali

L'augmentation de la complexité des systèmes est implacable, oppressante et finalement paralysante. Pour moi, en tant que programmeur de génération plus âgée, c'est aussi amèrement décevant.

Je programme depuis plus de 40 ans, ayant écrit du code dans 50 à 100 langues ou dialectes différents, et je suis devenu expert en 5-10. La raison pour laquelle je peux en affirmer autant est que la plupart du temps, ils sont juste la même langue, avec des ajustements. Les ajustements ajoutent de la complexité, rendant chaque langue un peu différente.

J'ai implémenté les mêmes algorithmes d'innombrables fois: collections, conversions, tri et recherche, encodage/décodage, formatage/analyse, tampons et chaînes, arithmétique, mémoire, E/S. Chaque nouvelle implémentation ajoute de la complexité, car chacune est juste un peu différente.

Je m'interroge sur la magie opérée par les trapézistes de haut vol des frameworks Web et des applications mobiles, sur la façon dont ils peuvent produire quelque chose de si beau en si peu de temps. Ensuite, je me rends compte à quel point ils ne savent pas, combien ils auront besoin d'apprendre sur les données ou les communications ou les tests ou les threads ou quoi que ce soit avant que ce qu'ils font ne devienne utile.

J'ai appris mon métier à l'ère des langues de quatrième génération, où nous pensions vraiment que nous produirions une succession de langues de plus en plus élevées pour capturer progressivement de plus en plus les parties répétitives des logiciels d'écriture. Alors, comment cela s'est-il passé exactement?

Microsoft et IBM ont tué cette idée en revenant à C pour écrire des applications pour Windows et OS/2, tandis que dBase/Foxpro et même Delphi languissaient. Puis le web l'a fait à nouveau avec son trio ultime de langages d'assemblage: HTML, CSS et JavaScript/DOM. Tout a été en descente à partir de là. Toujours plus de langues et plus de bibliothèques et plus de frameworks et plus de complexité.

Nous savons que nous devrions procéder différemment. Nous connaissons CoffeeScript et Dart, Less et Sass, les modèles pour éviter d'avoir à écrire du HTML. Nous le savons et nous le faisons de toute façon. Nous avons nos cadres, pleins d'abstractions qui fuient, et nous voyons quelles merveilles peuvent être faites par ces quelques élus qui apprennent les incantations obscures, mais nous et nos programmes sommes piégés par les décisions prises dans le passé. C'est trop compliqué de changer ou de recommencer.

Le résultat est que les choses qui devraient être faciles ne sont pas faciles, et les choses qui devraient être possibles sont presque impossibles, en raison de la complexité. Je peux estimer le coût des modifications apportées pour implémenter une nouvelle fonctionnalité dans une base de code établie et être sûr que j'aurai raison. Je peux estimer, mais je ne peux pas le justifier ou l'expliquer. C'est trop compliqué.

En réponse à votre dernière question, je conseillerais fortement aux programmeurs plus jeunes de commencer aussi haut que possible sur le gâteau des couches, et de ne plonger que dans les couches inférieures selon les besoins et le désir. Ma préférence va aux langues sans boucles, avec peu ou pas de branchement et un état explicite. LISP et Haskell me viennent à l'esprit. Dans la pratique, je termine toujours avec C #/Java, Ruby, Javascript, Python et SQL parce que c'est là que se trouvent les communautés.

Derniers mots: la complexité est l'ennemi ultime! Battez cela et la vie devient simple.

7
david.pfx

Ma question est cependant de savoir ce que les gens pensent de cette "dissimulation" d'éléments de niveau inférieur. Les programmeurs plus âgés y voient-ils une aubaine ou une couche inutile à franchir?

Ni vraiment.

La superposition est nécessaire car sans elle, vous atteignez un point où votre système devient des spaghettis incontrôlables. C'est également l'un des principes de la réutilisabilité: si le développeur d'une bibliothèque a fait du bon travail, les personnes qui l'utilisent ne devraient pas avoir à se soucier des détails de la mise en œuvre. La quantité de code en conserve que nous utilisons dans nos systèmes a augmenté par ordre de manœuvre par rapport à ce qu'elle était lorsque j'ai écrit mon premier programme il y a 35 ans. Cette croissance signifie que nous pouvons faire des choses plus puissantes au fil du temps. C'est bon.

L'endroit où cela a été un problème pour moi est entièrement culturel. Ma moitié pragmatique comprend qu'il n'est plus possible de me concentrer sur chaque détail et de pouvoir terminer les choses que je veux faire. (Vieillir n'aide pas non plus.) Ma moitié de barbe grise acariâtre a eu du mal à abandonner de nombreuses années à avoir une compréhension aussi fine de tout ce sur quoi j'ai travaillé.

Pensez-vous que les programmeurs plus jeunes bénéficieraient de plus d'apprentissage de la programmation de bas niveau AVANT d'explorer les domaines des bibliothèques étendues?

Comme cela a été souligné dans d'autres réponses, il y a un équilibre à trouver entre attirer et maintenir l'attention des néophytes et leur donner une éducation idéale de bas en haut. Si vous ne pouvez pas faire le premier, le second ne peut pas arriver.

Je vois des choses dans notre industrie qui ressemblent au reste de la société. Auparavant, presque tout le monde cultivait sa propre nourriture et y consacrait beaucoup de temps. Depuis lors, nous avons fait germer des spécialistes appelés agriculteurs qui font ce travail, libérant les autres pour faire d'autres choses qui contribuent à la société. J'achète ma nourriture dans une épicerie et je ne serais pas en mesure d'en produire la majeure partie si je le devais. Nous avons une situation similaire, quoique sur une échelle de temps beaucoup plus compressée. Les programmeurs sont spécialisés dans certains ensembles de couches et pas dans d'autres. Le gars moyen qui écrit des interfaces graphiques peut savoir qu'il y a une telle chose que l'espace d'échange, mais ne sait probablement pas ou ne se soucie pas beaucoup de la façon dont le système d'exploitation le gère.

Le résultat de tout cela est qu'il ne s'agit plus uniquement de développement. La spécialisation continue signifie que les développeurs devront continuer d'améliorer leurs compétences en communication et en intégration.

4
Blrfl

Comme pour tout, un peu vous fait du bien, mais trop mal. Le problème est que trop de systèmes ne savent pas quand s'arrêter - juste 1 abstraction de plus, pour vous aider à programmer plus rapidement ... mais vous finissez par coder dans le monde réel où les choses ne sont jamais aussi simples que vous le souhaitez, et vous passer plus de temps à travailler sur les bords que vous auriez passé avec une abstraction moins en vedette.

Son habilement décrit ici

ou ici - "avec une seule ligne de code vous pouvez ajouter 500 utilisateurs au domaine" ...

Vos abstractions essaient de vous cacher la complexité, mais tout ce qu'elles font est de cacher cette complexité. La complexité est toujours là, c'est juste que vous avez beaucoup moins de contrôle sur elle - et c'est pourquoi vous vous retrouvez avec ce genre de situation.

3
gbjbaanb

Les programmeurs plus jeunes bénéficient-ils de plus d'apprentissage de la programmation de bas niveau AVANT d'explorer les domaines des bibliothèques étendues? Si oui, pourquoi?

Je ne pense pas. Il y a encore beaucoup de situations dans lesquelles il est avantageux d'être conscient du faible fonctionnement de la `` couche ci-dessous '', par exemple.

  • Lors du débogage d'un problème sur la couche n, il peut souvent être expliqué en considérant ce qui se passe sur la couche n-1 (c'est-à-dire le calque ci-dessous). Je suppose que la couche 0 serait des "transistors" mais si vous voulez expliquer un problème avec les transistors, vous parleriez probablement de physique (par exemple la chaleur), alors peut-être que la physique est vraiment au niveau 0.

  • Lors de l'optimisation du code, cela (malheureusement) aide parfois à abaisser le niveau d'abstraction, c'est-à-dire à implémenter un algorithme en termes de couche de niveau inférieur. Cependant, les compilateurs sont devenus vraiment bons pour le faire pour vous si ils voir tout le code impliqué. Cette raison est devenue plus populaire récemment avec l'essor des appareils mobiles et embarqués, qui ont tendance à avoir des processeurs plus faibles et où la "performance par Watt" est beaucoup plus pertinente que, disons, sur les systèmes de bureau.

En général, cependant, il est devenu beaucoup plus facile de faire faire des choses aux ordinateurs (même de manière légèrement inefficace), ce qui signifie qu'il y a beaucoup plus de programmeurs qu'auparavant. Cela a à son tour rendu le facteur "humain" beaucoup plus important: réponse de Robert Harvey a déjà mentionné que "les humains ne peuvent avoir autant de connaissances dans leur tête à un moment donné", et je pense que c'est un élément très pertinent aspect de nos jours.

Une motivation majeure dans la conception d'un langage de programmation et d'une bibliothèque (c'est-à-dire une API) est de faciliter les choses pour le cerveau humain. À ce jour, tout est encore compilé en code machine. Cependant, ce n'est pas seulement sujet aux erreurs, il est aussi notoirement difficile à comprendre. Il est donc très souhaitable de

  • Demandez à l'ordinateur de vous aider à trouver des erreurs logiques dans les programmes que vous écrivez. Des choses comme les systèmes de type statique ou les analyseurs de code source (j'entends Eric Lippert fonctionne sur un assez populaire ces jours-ci) aident à cela.

  • Avoir un langage qui peut être traité efficacement par un compilateur et qui communique l'intention du programmeur à d'autres programmeurs pour faciliter le travail sur le programme. Comme un extrême absurde, imaginez que l'écriture de programmes en anglais simple était possible. Les autres programmeurs pourraient avoir plus de facilité à imaginer ce qui se passe, mais la description serait très difficile à compiler en instructeurs de machine, et c'est notoirement ambigu. Vous avez donc besoin d'un langage qu'un compilateur peut comprendre mais qui est également compréhensible.

Étant donné que de nombreux compilateurs (la plupart?) Sont encore très polyvalents, ils disposent d'un jeu d'instructions très générique. Il n'y a aucune instruction "dessiner un bouton" ou "lire ce film". Par conséquent, en déplaçant vers le bas la hiérarchie d'abstraction vous fait vous retrouver avec des programmes qui sont très difficiles à comprendre et à maintenir (bien que triviaux à compiler). La seule alternative est de déplacer vers le haut la hiérarchie, conduisant à de plus en plus de langages et de bibliothèques abstraites.

2
Frerich Raabe

"Si les programmeurs plus âgés voient des innovations comme celles-ci comme une aubaine ou une couche supplémentaire à analyser, et pourquoi pourraient-ils le penser?"

Je programme depuis que je suis au lycée, environ 34 ans, en commençant par l'assembleur de base et Z80, en passant au C, à divers langages 4GL, Scheme, SQL et maintenant divers langages Web. L'ampleur, l'ampleur et la profondeur des problèmes traités par la profession ont connu une période d'inflation au cours de cette période, en particulier dans les années 1990. Les constructions telles que les bibliothèques, les frameworks et les services OS sont tous des dispositifs destinés à répondre à la complexité qui accompagne l'espace élargi des problèmes. Ils ne sont pas une aubaine ni un fardeau en soi - juste une exploration continue d'un vaste espace de solution.

Mais, à mon humble avis, "l'innovation" est mieux comprise en termes de formes nouvelles, et ne pas être confondue avec un mouvement latéral - réintroduisant des formes que nous avons déjà vu introduites. À certains égards, la fécondité d'un écosystème souffre lorsque les formes primitives ne se composent pas, lorsqu'elles fixent les décisions prises tôt dans l'évolution, ou ne peuvent pas retraiter leurs propres détritus. Certaines, sinon la plupart, des concepts sur lesquels nous restons concentrés ne donnent pas la priorité au maintien à long terme de la valeur comme préoccupation. Cela a commencé à changer - des approches comme l'orientation des services et la conception pilotée par domaine, sans parler des modèles hypertextes et basés sur des graphiques, par exemple, modifient le paysage. Comme tout écosystème, les formes dominantes finiront par céder la place à de nouvelles formes; nous sommes mieux servis en permettant la diversité, largement et par petits incréments plutôt que la standardisation descendante à grande échelle suivie d'un effondrement tout à la fois.

"Et les jeunes programmeurs bénéficient-ils de plus d'apprentissage de la programmation de bas niveau AVANT d'explorer les domaines des bibliothèques étendues? Si oui, pourquoi?"

Je dirais que la plupart du langage humain est basé sur des métaphores depuis longtemps oubliées, alors même si je soutiendrais l'apprentissage de la programmation de bas niveau du point de vue de l'alphabétisation scientifique/numérique, il est plus important que nous recherchions des primitives qui prendront en charge l'échelle et la portée de les problèmes que nous abordons d'une manière que nous pouvons ignorer en toute sécurité le niveau de détail inférieur. Un framework n'est pas une primitive, pas plus qu'un OS ou une bibliothèque - ils sont assez pauvres pour faire le genre d'abstraction dont nous avons vraiment besoin. Un réel progrès amènera des personnes qui (a) savent ce qui s'est passé auparavant et (b) peuvent penser d'une manière suffisamment nouvelle pour trouver quelque chose d'assez différent pour explorer un espace de solution qui n'a pas été exploré auparavant ou a été exploré et oublié.

OTOH, même si votre objectif est de travailler en tant que technicien/niveau mécanique, un certain niveau d'exposition à la programmation de bas niveau sera toujours utile pour développer vos compétences en résolution de problèmes.

1
jerseyboy

Mon premier programme (en tant qu'adolescent de 15 ans) était en 1974 en PL/1 sur des cartes perforées pour un ordinateur central IBM 370/168. Mon père travaillait chez IBM et j'ai eu la chance de pouvoir aller au datacenter le dimanche.

À cette époque, un programme de plusieurs milliers de relevés (c'est-à-dire des cartes perforées) était un gros programme (et un programme lourd aussi, car plusieurs milliers de cartes perforées pesaient plusieurs kilogrammes). Les interfaces visuelles n'existaient pas (un programme typique lu à partir de son "entrée standard" en utilisant une commande de carte perforée commençant par //GO.SYSIN DD * IIRC, mais je n'ai pas maîtrisé JCL ). L'algorithmique était importante et l'IIRC la bibliothèque standard était assez petite par rapport à la norme actuelle.

Aujourd'hui, les programmes de plusieurs milliers de lignes sont généralement considérés comme petits. Par exemple, le compilateur GCC a plus de dix millions de lignes de code source et personne les comprend parfaitement.

Mon sentiment est que la programmation d'aujourd'hui est très différente des années 1970, car vous devez utiliser beaucoup plus de ressources (en particulier, les bibliothèques et les frameworks logiciels existants). Cependant, je suppose que les développeurs de logiciels de centre de données (par exemple, les moteurs de recherche de Google) ou certains logiciels intégrés se soucient autant des algorithmes et de l'efficacité que le programmeur moyen des années 1970.

Je pense toujours que la compréhension de la programmation de bas niveau est importante même aujourd'hui (même si la plupart des programmeurs ne se coderont pas eux-mêmes des algorithmes de conteneur de base comme des arbres équilibrés, des tableaux triés à accès dichotomique, etc.) car la compréhension de l'image dans son ensemble est toujours importante.

Une différence majeure entre les années 1970 et aujourd'hui est le rapport des coûts entre les efforts (humains) du développeur et la puissance de l'ordinateur.

1