Zur Entwicklung tiefer Programmierkenntnisse


136

Gelegentlich stelle ich beim Stack Overflow Fragen zu Randfällen und anderen Verrücktheiten fest, die leicht von Leuten wie Jon Skeet und Eric Lippert beantwortet werden können und die ein tiefes Wissen über die Sprache und ihre vielen Feinheiten aufweisen, wie diese:

Sie könnten denken, um eine foreachSchleife zu verwenden, muss die Sammlung, über die Sie iterieren, IEnumerableoder implementieren IEnumerable<T>. Aber wie sich herausstellt, ist das eigentlich keine Voraussetzung. Erforderlich ist, dass der Typ der Auflistung eine öffentliche Methode hat, die aufgerufen wird GetEnumerator, und dass ein Typ zurückgegeben wird, der einen öffentlichen Eigenschafts-Getter hat, der aufgerufen wird, Currentund eine öffentliche Methode MoveNext, die a zurückgibt bool. Wenn der Compiler feststellen kann, dass alle diese Anforderungen erfüllt sind, wird der Code zur Verwendung dieser Methoden generiert. Nur wenn diese Anforderungen nicht erfüllt sind, prüfen wir, ob das Objekt IEnumerableoder implementiert IEnumerable<T>.

Das ist cool zu wissen. Ich kann verstehen, warum Eric das weiß; Er ist im Compiler-Team, also muss er es wissen. Aber was ist mit denen, die solch tiefes Wissen demonstrieren und keine Insider sind?

Wie finden bloße Sterbliche (die nicht im C # -Compilerteam sind) über solche Dinge Bescheid?

Gibt es Methoden, mit denen diese Leute dieses Wissen systematisch ausgraben, erforschen und verinnerlichen (es zu ihrem eigenen machen)?


10
Ich denke, dies ist besonders dort, wo Open Source-Software glänzt. Es ist schön, in das Framework / System / die Bibliotheken hineingehen zu können. Früher hatte ich ein besseres Verständnis der Framework-Interna, als ich mit Qt gearbeitet habe, als als ich mit WinForms gearbeitet habe.
Vitor Py

2
Wann müssten Sie dieses spezielle Beispiel kennen, wenn Sie nicht vor einer besonderen Menschenmenge stumm aussehen möchten? Sie haben das idiotensicher gemacht. Abgesehen davon könnte die Effective C # -, Java-, C ++ - usw.-Reihe einige coole Dinge enthalten. Eric Lipperts Blog ist ebenfalls eine gute Quelle. Im Allgemeinen wissen wir oft nicht, was wir nicht wissen, und so heißt es: "Lebe 100 Jahre, lerne 100 Jahre und sterbe ein Narr."
Job

26
Lohnt sich die Mühe? Ich bin zweisprachig und versuche, ein paar andere gesprochene Sprachen zu lernen. Ich habe Matheunterricht genommen, aber nicht genug. Ich möchte lernen, wie man Tennis halbwegs anständig spielt und wie man mit einem Schmetterlingsschlag schwimmt. Ich würde gerne mehr reisen. Ich möchte etwas über Clojure lernen. Was ich nicht möchte, ist Experte in einer Sprache zu sein, einen Doktortitel in Mathematik zu haben, 30 Stunden pro Woche in einem Pool wie Michael Phelps usw. zu verbringen Bemühen Sie sich um eine (oder einige) Dinge, während Sie andere Erfahrungen verpassen. Vielleicht den Job wechseln?
Job

10
"Ich kann verstehen, warum Eric das weiß; er ist im Compiler-Team, also muss er es wissen." - Wahrscheinlich weiß er das, weil er es sich überhaupt ausgedacht hat . Ich bezweifle, dass er herausfinden musste, dass es so funktioniert :)
Alex ten Brink

10
@Alex: Ich habe eigentlich nur an C # gearbeitet, seit wir damit begonnen haben, die Implementierung von C # 3 zu erstellen. Die "foreach" -Spezifikation wurde über sechs Jahre zuvor geschrieben. Ich finde immer noch jeden Tag verrückte historische Dinge über die Sprache heraus. Zum Beispiel habe ich heute erfahren, dass für Delegierte ((A + B) + C) - (A + C) = A + B + C, aber ((A + B) + C) - (B + C) = A . Seltsam!
Eric Lippert

Antworten:


167

Zunächst einmal danke für die freundlichen Worte.

Wenn Sie sich eingehend mit C # auskennen möchten, ist es zweifellos von Vorteil , die Sprachspezifikation, zehn Jahre Design-Notizen, den Quellcode, die Bug-Datenbank und Anders, Mads, Scott und Peter im Hintergrund zu haben. Ich bin auf jeden Fall glücklich, keine Frage.

Aber auch ohne diese Vorteile ist es immer noch möglich, ein tiefes Wissen über das Thema zu erlangen.

Als ich bei Microsoft anfing, arbeitete ich an dem JScript-Interpreter, der im Lieferumfang von Internet Explorer 3 enthalten war. Mein damaliger Manager gab mir einige der besten Ratschläge, die ich je erhalten habe. Er wollte, dass ich der anerkannte Experte für die Syntax und Semantik der JScript-Sprache bei Microsoft werde und dass ich dazu Fragen zu diesen Aspekten von JScript suche und beantworte. Besonders die Fragen zu beantworten, auf die ich keine Antworten kannte, weil das die sind, von denen ich lernen würde.

Offensichtlich sind StackOverflow und andere öffentliche Q & A-Foren wie das Trinken aus einem Feuerlöschschlauch für solche Dinge. Damals las ich comp.lang.javascript und unsere internen Microsoft "JS User" -Foren religiös und befolgte den Rat meines Managers: Als ich eine Frage über die Sprachsemantik sah , auf die ich keine Antwort wusste, habe ich sie gemacht mein Geschäft, um herauszufinden.

Wenn Sie so einen "tiefen Tauchgang" machen wollen, müssen Sie sorgfältig auswählen. Ich bin bis heute bemerkenswert unwissend, wie das Browser-Objektmodell funktioniert. Da ich mich in den letzten Jahren darauf konzentriert habe, C # -Sprachenexperte zu werden, kenne ich die Funktionsweise der verschiedenen Klassen in den Basisklassenbibliotheken bemerkenswert wenig. Ich habe das Glück, einen Job zu haben, der spezifisches tiefes Wissen auszeichnet. Wenn Ihr Job oder Ihre Talente eher dazu passen, ein Generalist zu sein, kann es sein, dass Sie nicht in die Tiefe gehen.

Das Schreiben eines Blogs ist ebenfalls sehr hilfreich. Indem ich anderen Menschen komplexe Themen erklären muss, muss ich mich ständig mit meinem eigenen unzureichenden Verständnis verschiedener Themen auseinandersetzen.


14
Um dieses Off-Topic nicht in die Länge zu ziehen, aber nachdem ich diese Antwort gelesen habe, bin ich gespannt, warum Sie hier oder bei Stack Overflow keine Fragen gestellt haben. Reichen Ihnen an dieser Stelle Ihre Kollegen, Blogs usw. aus? Gibt es bessere Ressourcen als SO, über die wir Bescheid wissen sollten?
Matthew Read

6
Vielleicht haben Sie falsch verstanden, was er sagt. Gegen die Intuition stellte er keine Fragen, um etwas zu lernen, er beantwortete Fragen.
jhocking

65

Nachdem ich ein oder zwei Mal auf der "Guru" -Seite des Gesprächs war, kann ich Ihnen sagen, dass das, was Sie als "tiefes Wissen" über eine Programmiersprache oder ein System empfinden, oft das Ergebnis des "Guru" ist, um das es in letzter Zeit gekämpft hat ein Monat, um genau das gleiche Problem zu lösen. Dies gilt insbesondere für ein Forum, in dem die Benutzer auswählen können, welche Fragen sie beantworten möchten. Sogar Leute wie Jon Skeet und Eric Lippert mussten einmal Hallo Welt lernen. Sie erwerben ihr Wissen wie jeder andere auch konzeptionell.


1
Ein sehr guter Punkt. Ich stelle oft fest, dass ich zu Beginn langer Forschungsaufenthalte Fragen finde, die ich aufgrund der Dinge, die ich früher am Tag gelernt habe, jetzt beantworten kann.
Matthew Read

47

Umschreibung von Yogi Bhajan:

"Wenn Sie etwas lernen wollen, lesen Sie darüber; wenn Sie etwas verstehen wollen, schreiben Sie darüber; wenn Sie etwas beherrschen wollen, programmieren Sie es."

Programmieren ist wie die ultimative Herausforderung für den Unterricht. Das Unterrichten von Computern erfordert, dass Sie sich mit Ihren Dingen wirklich gut auskennen - oder Sie werden lernen, sie zu beherrschen.

Wenn Sie beispielsweise Physik lernen möchten, schreiben Sie eine Physik-Engine. Wenn Sie Schach lernen möchten, programmieren Sie ein Schachspiel. Wenn Sie tiefgreifende C # -Kenntnisse erlernen möchten, schreiben Sie einen C # -Compiler (oder ein anderes Tool).


2
Das Programmieren ist auch ein bescheidener Versuch, auf eindeutigste Weise zu schreiben (von Menschen natürlich zu lesen).
vpit3833

4
Dieses Zitat klang wirklich tief, bis ich das Schachbeispiel las. Leider macht das Programmieren einer Schach-KI Sie nicht zu einem besseren Schachspieler (im Grunde handelt es sich um eine Suche in einem Min-Max-Baum). Noch +1
bughi

1
@bughi Vielleicht kannst du die Regeln beherrschen: D
Julio Rodrigues

@ bughi, 'program it' ist ein sehr weit gefasster Begriff, der nicht immer mit dem Schreiben von Code zusammenhängt !! Denken Sie einfach ein wenig über den Tellerrand hinaus.
Nitesh Verma

25

Soweit ich weiß, gibt es folgende Möglichkeiten, dies zu lernen:

  • Lesen Sie darüber von jemandem wie Eric Lippert
  • Erleben und lösen Sie die Probleme aus erster Hand.

Der zweite Weg kann viel länger dauern, wird aber wahrscheinlich zu einem tieferen Verständnis führen (aber nicht immer).


17
Oder beides. [15 Zeichen]
Michael K

23

Ich würde sagen, mache folgendes:

Nachdem Sie einen relativ nützlichen Stapel von Sprachen gelernt haben (die Sie für einen echten Job benötigen), hören Sie auf, mehr Sprachen zu lernen, bis Sie mindestens eine Sprache gründlich gelernt haben. Ein Teil des Problems in unserer Branche besteht meiner Meinung nach derzeit darin, dass die Menschen nur die ersten 5 bis 10% der Sprache lernen, bevor sie zu einer anderen Sprache übergehen. Sobald Sie die Fähigkeit haben, die häufigsten Aufgaben in einem Job zu erledigen, sollten Sie sich mit einer Sache befassen. (Sie können zurückgehen, um Breite zu bekommen, nachdem Sie etwas Tiefe bekommen haben, und dann zwischen den beiden hin und her gehen.)

Helfen Sie mit bei den komplexeren und schwierigeren Aufgaben, bei denen Sie sich eingehend mit der Lösung der Probleme befassen müssen. Wenn Sie dort, wo Sie arbeiten, keine finden, suchen Sie nach Open-Source-Aufgaben, oder beginnen Sie mit der Arbeit an einem persönlichen Projekt, bei dem Sie sich eingehender mit dem Thema befassen müssen. Wenn Ihr Job keine interessanten Probleme hat, suchen Sie nach einem herausfordernden Job.

Lesen Sie die Bücher für Fortgeschrittene in einer Sprache (für SQl Server würde dies beispielsweise das Lesen von Informationen zur Leistungsoptimierung und zu Datenbankinternen beinhalten), anstatt die Bücher des Typs "X in 30 Tagen lernen".

Lesen Sie die interessanten Fragen hier und an anderen Stellen, an denen sie gestellt werden, und versuchen Sie, einige selbst zu lösen. Wenn Sie lernen möchten, versuchen Sie, einige zu lösen, ohne vorher die anderen Antworten zu lesen. Auch wenn die Frage bereits beantwortet wurde, erfahren Sie mehr, wenn Sie die Antwort selbst finden. Vielleicht finden Sie sogar eine bessere Antwort als die Frage.

Stellen Sie einige der schwierigeren Fragen. Bewerten Sie die Antworten, die Sie erhalten, und verwenden Sie sie nicht nur. Stellen Sie sicher, dass Sie verstehen, warum die Antwort funktionieren würde oder nicht. Nutzen Sie diese Antworten als Ausgangspunkt für Ihre Recherchen.

Finden Sie einige gute technische Blogs von bekannten Experten auf dem Gebiet und lesen Sie sie.

Hören Sie auf, Ihr Wissen wegzuwerfen, wenn Sie damit fertig sind. Lernen Sie zu behalten. Die meisten Experten müssen die gängige Syntax nicht nachschlagen. Sie müssen das Rad nicht jedes Mal neu erfinden, wenn sie auf ein Problem stoßen, weil sie sich daran erinnern, wie sie zuvor an ein ähnliches Problem herangegangen sind. Sie können die Punkte verbinden und sehen, wie das Problem X, das sie vor zwei Jahren gemacht haben, dem Problem Y ähnelt, das sie gerade haben (es erstaunt mich, wie wenige Leute in der Lage zu sein scheinen, solche Verbindungen herzustellen). Infolgedessen haben sie mehr Zeit für die Erforschung interessanterer Themen.


Eine schöne Antwort. Aber ich frage mich, wie ich das Wissen besser behalten und die Punkte verbinden kann.

Ich schlage vor, Sie machen sich Notizen darüber, was Sie lernen. Ich begann dies in meinem Evernote zu tun und über ein paar Jahre hinweg stellte ich fest, dass ich von meinen Notizen leben kann. Langsam bin ich auch zu dem Punkt gekommen, an dem meine Notizen in Präsentationen umgewandelt werden können, die ich jederzeit präsentieren kann.
Shivasubramanian A

9

Sie können beginnen tief das Studium der Sprache Spezifikationen von denen , die Sie suchen einen Experten aus sein. Zum Beispiel:


3
Gute Antwort - In Abschnitt 15.8.4 der verknüpften C # -Spezifikation wird beispielsweise die Implementierung von behandelt foreachund das in dem zitierten Blogbeitrag von Eric Lippert beschriebene Verhalten erläutert . Wenn sich jemals jemand denkt, dass etwas wie "Ich frage mich, wie foreach wirklich funktioniert", dann ist dies ein guter Ort, um nach etwas Ausschau zu halten.
Carson63000

6

Holen Sie sich Reflector oder einen anderen Decompiler (da er jetzt bezahlt wird) und öffnen Sie einige der am häufigsten verwendeten .NET-Bibliotheken, um zu erfahren, wie die internen Funktionen funktionieren. In Kombination mit einem Buch wie CLR über C # werden Sie ziemlich tiefgreifend (tiefer, als die meisten von uns ihren regulären Job machen werden).


5
Ich habe das tatsächlich mit den BitConverterKlassen gemacht und die IsLittleEndiansystemspezifische Flagge entdeckt.
Robert Harvey

LOL. +1 für isLittleEndian
Rudy

4

Ich habe diese Art von Wissen in C ++ entwickelt, indem comp.lang.c++.moderatedich mich ein paar Jahre hingegeben habe, obwohl ich zu diesem Zeitpunkt nicht wirklich so hart daran gearbeitet habe, darin zu programmieren . Ich bin mir jedoch nicht sicher, wie Guru ich sagen kann.

Ich denke, es gibt zwei Arten von Kenntnissen, die man über eine Programmiersprache erwerben kann:

  1. Wissenswertes über die Sprache und wissen, wie man Fallstricke vermeidet.
  2. Wissen, wie man Probleme effektiv löst.

Nummer 2 kann nur erreicht werden, indem Sie in der Sprache programmieren und sich den Code anderer ansehen. Nummer 1 kann jedoch erreicht werden, indem Sie sich viel Zeit nehmen, um in den Diskussionsforen über die Sprache zu lesen und zu sehen, welche Fragen und welche Fragen gestellt werden Antworten sind. Auch dafür ist StackOverflow ein guter Ort.


4

Umfassende Kenntnisse und Programmierkenntnisse bedeuten, dass Sie sich auf allen Abstraktionsstufen wohlfühlen. Dh

  • Bibliotheken und APIs
  • Sprachsemantik
  • Compiler-Optimierungen
  • Compiler-Interna und Code-Generierung
  • Laufzeit- und Garbage Collector-Verhalten
  • Architektur- und Befehlssatzprobleme

Alles, was ich in den letzten 15 Jahren gesehen habe, hat gezeigt, dass Sie nur dann eine Chance haben, tiefgreifende Kenntnisse zu erlangen, wenn Sie wirklich mit dem Compiler und der Laufzeit vertraut sind. Möglicherweise müssen Sie sich dazu zwingen, den Schritt zu wagen und mit dem Überlegen (und Erstellen) von Software auf der nächsthöheren Abstraktionsebene im Stapel zu beginnen , aber dies ist der einzige Weg zu Fachwissen.

Alles, was wir haben, ist Sprache für die Abstraktion. Sie müssen verstehen, wie Programmiersprachen entworfen und gebaut werden, um wirklich zu wissen, was die Maschine tut.


3

Lesen Sie das feine Handbuch Dies ist kein besonders tiefes Wissen. Es ist in Abschnitt 8.6.4 der C # -Sprachenspezifikation veröffentlicht. Sie sollten sich angewöhnen, zumindest die Spezifikationen für die von Ihnen verwendeten Sprachen zu überfliegen und die Dokumentation für alle integrierten Bibliotheken zu überfliegen.

Jedenfalls ist das nicht meine Vorstellung von tiefem Wissen; Es ist nur ein uninteressantes Implementierungsdetail. Es könnte interessanter sein, wenn der Designer erklärt, warum dies auf dynamischere Weise geschehen ist, anstatt nur zu überprüfen, ob das Objekt Iterable implementiert.


1
Ich glaube nicht, dass es so etwas wie das "Überfliegen" der C # -Sprachenspezifikation gibt.
Robert Harvey

@RobertHarvey: Sie können einen Großteil der formalen Sprache durchgehen, die bereits bekannte Dinge wie die Priorität von Operatoren und die Deklarationssyntax abdeckt, und sich auf unerwartete, aber nützliche Details wie das genaue Verhalten von C # foreach- oder Java-Enum-Konstruktoren konzentrieren.
Kevin Cline

Sie können eine kommentierte Version des Standards kaufen. Es ist etwas veraltet, aber die Kommentare sind für die behandelten Teile der Sprache immer noch sehr interessant.
Jørgen Fogh
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.