Parfois, je vois des questions sur les cas Edge et d'autres bizarreries sur Stack Overflow auxquelles répondent facilement des personnes comme Jon Skeet et Eric Lippert, démontrant une connaissance approfondie de la langue et de ses nombreuses subtilités, comme celui-ci:
Vous pourriez penser que pour utiliser une boucle
foreach
, la collection que vous parcourez doit implémenterIEnumerable
ouIEnumerable<T>
. Mais il s'avère que ce n'est pas réellement une exigence. Ce qui est requis est que le type de la collection doit avoir une méthode publique appeléeGetEnumerator
, et qui doit retourner un type qui a un getter de propriété publique appeléCurrent
et une méthode publiqueMoveNext
qui renvoie unbool
. Si le compilateur peut déterminer que toutes ces exigences sont remplies, le code est généré pour utiliser ces méthodes. Ce n'est que si ces conditions ne sont pas remplies que nous vérifions si l'objet implémenteIEnumerable
ouIEnumerable<T>
.
C'est cool à savoir. Je peux comprendre pourquoi Eric le sait; il fait partie de l'équipe du compilateur, il doit donc le savoir. Mais qu'en est-il de ceux qui démontrent une connaissance si profonde qui ne sont pas des initiés?
Comment les simples mortels (qui ne font pas partie de l'équipe du compilateur C #) découvrent-ils des trucs comme ça?
Plus précisément, y a-t-il des méthodes que ces gens utilisent pour extirper systématiquement ces connaissances, les explorer et les internaliser (les faire siennes)?
Tout d'abord, merci pour les aimables paroles.
Si vous voulez avoir une connaissance approfondie de C #, c'est sans aucun doute un avantage d'avoir la spécification du langage, dix ans de notes de conception, le code source, la base de données de bogues, et Anders, Mads, Scott et Peter juste en bas du couloir. J'ai certainement de la chance, cela ne fait aucun doute.
Cependant, même sans ces avantages, il est toujours possible d'acquérir une connaissance approfondie du sujet.
À l'époque où j'ai commencé chez Microsoft, je travaillais sur l'interpréteur JScript fourni avec Internet Explorer 3. Mon responsable à l'époque m'a dit quelque chose qui était l'un des meilleurs conseils que j'aie jamais reçus. Il a dit qu'il voulait que je devienne l'expert reconnu de Microsoft sur la syntaxe et la sémantique du langage JScript, et que je devrais y aller en cherchant des questions sur ces aspects de JScript et en y répondant. Répondant particulièrement aux questions dont je ne connaissais pas les réponses, car ce sont celles-là que j'apprendrais.
De toute évidence, StackOverflow et d'autres forums de questions-réponses publics sont comme boire dans un tuyau d'incendie pour ce genre de chose. À l'époque, j'ai lu religieusement comp.lang.javascript et nos forums internes Microsoft "JS User" et j'ai suivi les conseils de mon manager: quand j'ai vu une question qui concernait la sémantique du langage que je ne connaissais pas la réponse à, je me suis fait un devoir de le découvrir.
Si vous voulez faire une "plongée profonde" comme ça, vous devez choisir avec soin. À ce jour, je suis remarquablement ignorant comment fonctionne le modèle d'objet du navigateur. Depuis que je me suis concentré sur devenir l'expert du langage C # ces dernières années, je suis remarquablement ignorant du fonctionnement des différentes classes dans les bibliothèques de classes de base. J'ai la chance d'avoir un travail qui valorise des connaissances approfondies spécifiques; si votre travail ou vos talents correspondent davantage à ceux de généraliste, approfondir pourrait ne pas fonctionner pour vous.
La rédaction d'un blog est également extrêmement utile; en m'obligeant à expliquer des sujets complexes à d'autres personnes, je suis constamment confronté à ma propre compréhension insuffisante de divers sujets.
Ayant été du côté "gourou" de la conversation une ou deux fois, je peux vous dire que bien des fois ce que vous percevez comme une "connaissance approfondie" d'un langage ou d'un système de programmation est souvent le résultat du "gourou" qui a récemment lutté pour un mois pour résoudre exactement le même problème. Cela est particulièrement vrai sur un forum où les gens peuvent choisir les questions auxquelles ils répondront. Même les goûts de Jon Skeet et Eric Lippert ont dû apprendre le monde bonjour à un moment donné. Ils acquièrent leurs connaissances un concept à la fois, comme n'importe qui d'autre.
Paraphrasant Yogi Bhajan:
"Si vous voulez apprendre quelque chose, lisez-le; si vous voulez comprendre quelque chose, écrivez à ce sujet; si vous voulez maîtriser quelque chose, programme."
La programmation est comme le défi pédagogique ultime. Apprendre à faire quelque chose en informatique exige que vous connaissiez très bien vos affaires - ou que vous appreniez à les maîtriser.
Par exemple, si vous voulez apprendre la physique, écrivez un moteur physique. Si vous voulez apprendre les échecs, programmez une partie d'échecs. Si vous souhaitez acquérir des connaissances approfondies en C #, écrivez un compilateur C # (ou un autre outil).
Pour autant que je sache, les moyens d'apprendre ceci sont:
La deuxième voie peut prendre beaucoup plus de temps mais se traduira probablement par une compréhension plus profonde (mais pas toujours).
Je dirais:
Après avoir appris une pile de langues relativement utiles (celles dont vous avez besoin pour un vrai travail) au niveau où vous pouvez effectuer les tâches les plus courantes, arrêtez d'apprendre d'autres langues jusqu'à ce que vous en ayez étudié au moins une en profondeur. Une partie du problème dans notre industrie en ce moment, à mon avis, est que les gens n'apprennent que les 5 à 10% de la langue avant de passer à une autre langue. Une fois que vous avez la capacité d'effectuer les tâches les plus courantes dans un travail, commencez à regarder une chose en profondeur. (Vous pouvez revenir à l'étendue après avoir acquis de la profondeur, puis faire des allers-retours entre les deux.)
Bénévole pour les tâches les plus complexes et les plus difficiles, celles qui vous obligent à aller en profondeur pour résoudre les problèmes. S'il n'y en a pas où vous travaillez, recherchez des tâches open source à faire ou commencez à travailler sur un projet personnel qui vous obligera à approfondir. Si votre travail ne présente aucun problème intéressant, envisagez de chercher un emploi plus difficile.
Lisez les livres avancés dans une langue (pour SQl Server, par exemple, cela comprend la lecture sur l'optimisation des performances et les internes de la base de données) au lieu du livre Learn X en 30 jours.
Lisez les questions intéressantes ici et d'autres endroits où elles sont posées et essayez de résoudre vous-même certaines. Si vous voulez apprendre, essayez de résoudre certains sans lire d'abord les autres réponses. Même si la question a déjà été répondue, vous en apprendrez plus si vous trouvez la réponse vous-même. Vous pourriez même trouver une meilleure réponse que celle de la question.
Posez quelques-unes des questions les plus difficiles. Évaluez les réponses qui vous sont données, ne vous contentez pas de les utiliser. Assurez-vous de comprendre pourquoi la réponse fonctionnera ou non. Utilisez ces réponses comme point de départ pour la recherche.
Trouvez de bons blogs techniques d'experts connus dans le domaine et lisez-les.
Arrêtez de jeter vos connaissances une fois que vous en avez terminé. Apprenez à retenir. La plupart des experts n'ont pas à rechercher la syntaxe commune. Ils n'ont pas à réinventer la roue à chaque fois qu'ils rencontrent un problème, car ils se souviennent de la façon dont ils ont abordé un problème similaire auparavant. Ils peuvent relier les points et voir comment le problème X qu'ils ont fait il y a deux ans est similaire au problème Y qu'ils ont en ce moment (cela m'étonne du peu de gens qui semblent capables de faire des connexions comme ça). Par conséquent, ils disposent de plus de temps pour rechercher des sujets plus intéressants.
Obtenez Reflector ou tout autre décompilateur (car il paie maintenant), et commencez à ouvrir certaines des bibliothèques .NET les plus utilisées pour apprendre comment fonctionnent les internes. Combiné avec un livre comme CLR via C # vous obtiendrez assez profond (plus profond que la plupart d'entre nous iront à leur travail régulier).
J'ai développé ce genre de connaissances en C++ en passant du temps dans comp.lang.c++.moderated
pendant quelques années, même si je ne travaillais pas vraiment si fort pour le coder à ce moment-là. Je ne sais pas vraiment comment je peux dire que je suis gourou.
Je pense qu'il y a deux types de connaissances que l'on peut acquérir sur un langage de programmation:
Le numéro 2 ne peut être atteint qu'en programmant dans la langue et en regardant le code des autres, mais le numéro 1 peut être atteint en prenant beaucoup de temps pour lire sur la langue sur ses forums de discussion, voir quels types de questions les gens posent et ce que le les réponses sont. StackOverflow est également un bon endroit pour cela.
Une connaissance approfondie et une expertise en programmation signifie être à l'aise à tous les niveaux d'abstraction. C'est à dire.
Tout ce que j'ai vu au cours des 15 dernières années a montré que ce n'est que si vous pouvez vraiment entrer dans le compilateur et l'exécution que vous avez une chance de devenir profondément compétent. Vous devrez peut-être vous forcer à franchir le pas et à commencer à raisonner (et à construire) un logiciel au niveau d'abstraction suivant plus bas dans la pile, mais c'est le seul moyen d'expertise.
Tout ce que nous avons, c'est un langage pour l'abstraction. Vous devez comprendre comment les langages de programmation sont conçus et construits pour vraiment savoir ce que fait la machine.
Lire le manuel fin Ce n'est pas une connaissance particulièrement approfondie. Il est publié dans la spécification du langage C # section 8.6.4. Vous devriez prendre l'habitude au moins de parcourir les spécifications des langues que vous utilisez, ainsi que de parcourir la documentation de toutes les bibliothèques intégrées.
Quoi qu'il en soit, ce n'est pas mon idée de la connaissance profonde; c'est juste un détail d'implémentation sans intérêt. Cela pourrait être plus intéressant si le concepteur expliquait pourquoi cela avait été fait de cette manière plus dynamique, au lieu de simplement vérifier que l'objet implémente Iterable.