it-swarm.com.de

Hilfe beim Verständnis von Informatik, Programmierung und Abstraktion

Bis jetzt war ich immer der Meinung, dass Sie Programmiersprachen lernen sollten, die Sie dazu bringen, einfache Dinge (z. B. C) zu tun, um zu verstehen, was wirklich unter der Haube passiert und wie der Computer wirklich funktioniert. diese Frage , diese Frage und ein Antwort von dieser Frage verstärkten diesen Glauben:

Je mehr ich in den abstrakten Sprachen programmiere, desto mehr vermisse ich, was mich überhaupt in Computer gebracht hat: am Computer herumstöbern und sehen, was zuckt. Assembler und C eignen sich sehr gut zum Stöbern :)

Schließlich dachte ich, Sie werden ein besserer Programmierer, wenn Sie das wissen, weil Sie wissen, was passiert, anstatt davon auszugehen, dass alles magisch ist. Und Low-Level-Sachen zu kennen/zu schreiben ist viel interessanter als Business-Programme zu schreiben, denke ich.

Aber vor einem Monat bin ich auf dieses Buch mit dem Titel Struktur und Interpretation von Computerprogrammen gestoßen. Alles im Web deutet darauf hin, dass dies eines der besten Informatikbücher ist, und Sie werden als Programmierer besser, wenn Sie es lesen.

Ich mag die Konzepte sehr. Aber ich finde, dass das Buch den Anschein erweckt, dass Abstraktion das beste Konzept in der Informatik ist, während nur ein Kapitel auf der unteren Ebene verbracht wird.

Mein Ziel ist es, ein besserer Programmierer zu werden, die Informatik besser zu verstehen, und das hat mich wirklich verwirrt. Sollten wir nicht hauptsächlich alle Abstraktionen vermeiden und beobachten, was wirklich auf sehr niedriger Ebene passiert? Ich weiß, warum Abstraktion großartig ist, aber hindert Sie das nicht daran, die Funktionsweise von Computern zu lernen?

31
morbidCode

Nein, Abstraktionen hindern Sie nicht daran zu verstehen, wie die Dinge funktionieren. Mit Abstraktionen können Sie verstehen, warum (zu welchem ​​Zweck) Dinge so funktionieren, wie sie funktionieren.

Lassen Sie uns zunächst eines klarstellen: So ziemlich alles, was Sie jemals gekannt haben, befindet sich auf einer Abstraktionsebene. Java ist eine Abstraktion, C++ ist eine Abstraktion, C ist eine Abstraktion, x86 ist eine Abstraktion, Einsen und Nullen sind eine Abstraktion, digitale Schaltungen sind eine Abstraktion, integrierte Schaltungen sind eine Abstraktion, Verstärker sind eine Abstraktion, Transistoren sind eine Abstraktion, Schaltkreise sind eine Abstraktion, Halbleiter sind eine Abstraktion, Atome sind eine Abstraktion, Elektronenbänder sind eine Abstraktion, Elektronen sind eine Abstraktion (und soweit wir wissen, könnten es Abstraktionen sein) Die Logik, dass Wissen auf niedrigem Niveau erforderlich ist, um zu verstehen, wie etwas wirklich funktioniert. Wenn Sie verstehen möchten, wie Computer wirklich funktionieren, müssen Sie Physik, dann Elektrotechnik, dann Computertechnik und dann Informatik studieren und sich im Wesentlichen nach oben arbeiten Begriffe der Abstraktion. (Ich habe mir erlaubt, das nicht zu erwähnen Sie müssen auch zuerst Mathematik studieren , um die Physik wirklich zu verstehen.)

Realistisch gesehen waren die Tage, an denen Sie Computer und Programmierung verstehen konnten, indem Sie sich von den Details der untersten Ebene aufbauten, die frühesten Tage der Computer. Inzwischen ist dieses Feld zu weit fortgeschritten, bis es möglicherweise nicht mehr von einer einzelnen Person von Grund auf neu entdeckt werden kann. Es gibt Hunderttausende von sehr qualifizierten Leuten, die sich auf jeder Abstraktionsebene spezialisiert haben und täglich hart daran arbeiten, Fortschritte zu erzielen, die Sie nicht verstehen können, ohne jahrelang einen bestimmten Teil gründlich zu studieren und sich dazu zu verpflichten, mit den neuesten Fortschritten dort Schritt zu halten.

Betrachten Sie dieses Java Snippet:

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

Sie können leicht verstehen, was dieses Snippet verspricht (und was es nicht verspricht), auf der Ebene der Sprache Java). Es sei denn, Sie sind mit Themen wie Stapelrahmen und Heap-Daten vertraut Strukturen, gleichzeitige Speicherbereinigung der Generationsverfolgung, Speicherkomprimierung, statische Analyse, Escape-Analyse, virtuelle Maschinen, dynamische Analyse, Assemblersprache und Schutz des ausführbaren Speicherplatzes. Sie liegen falsch, wenn Sie der Meinung sind, dass Sie wirklich alle Details auf niedriger Ebene kennen, die tatsächlich beteiligt sind Laufen auf einem echten Computer.

Alternativ können Sie dieses C-Snippet betrachten:

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);
    }
}

Wenn Sie es einem Anfänger zeigen, werden Sie darauf hingewiesen, dass bei einem Argument ungleich Null der Restinhalt eines Speicherorts gedruckt wird, da "Variablen eigentlich nur Speicheradressen hinter den Kulissen sind" und "wenn Sie dies nicht tun" Wenn Sie sie nicht initialisieren, bedeutet dies einfach, dass Sie nichts an ihre Adresse verschieben "und" sie haben nichts Magisches ". Wenn Sie es einem Nicht-Anfänger zeigen, werden Sie darauf hingewiesen, dass das Verhalten dieses Programms für Werte ungleich Null des Parameters dieser Funktion undefiniert ist und der Compiler möglicherweise die Bedingung entfernen, alle Argumente für diese Funktion als Null behandeln und alle ersetzen kann Setzen Sie von den Aufrufpunkten der Funktion mit Aufrufen, die als Argument Null übergeben, alle Variablen, die jemals als Argumente an diese Funktion übergeben wurden, auf Null oder tun Sie andere scheinbar paradoxe Dinge .

Es ist wichtig zu wissen, dass Sie immer auf einer Abstraktionsebene arbeiten. Der Anfänger in diesem Beispiel hat alles berücksichtigt, was er/sie weiß, und ist elegant zu einer völlig falschen Antwort gekommen, weil (a) er/sie die Spezifikation der Sprache (die eine Abstraktion ist nicht gelesen hat ) absichtlich , nicht weil C-Programmierer nicht klug genug sind, um die Computerarchitektur zu verstehen) und (b) versucht haben, über Implementierungsdetails nachzudenken, die er/sie nicht vollständig verstanden hat und die sich weiterentwickelt haben weit über sein/ihr mentales Modell hinaus. Dieses Beispiel ist fiktiv, basiert jedoch auf alltäglichen Missverständnissen in der realen Welt, die manchmal zu gefährlichen Fehlern und gelegentlich berühmten Sicherheitslücken führen.

Es ist auch wichtig, das Gesamtbild zu sehen. Wenn Sie beispielsweise höhere Abstraktionen nicht gut genug verstehen, stellen Sie möglicherweise fest, dass C Strukturen, Strukturzeiger gleicher Größe, unvollständige Typdeklarationen und Funktionszeiger enthält, und Sie werden sie wahrscheinlich als eine Reihe von nicht verwandten Merkmalen sehen, die könnte gelegentlich nützlich sein. Wenn Sie jedoch eine höhere Abstraktion wie OOP gut genug verstehen), erkennen Sie die oben genannten Funktionen als Bausteine ​​für OOP Konzepte: Strukturen können andere Strukturen enthalten (Code-Wiederverwendung), Datenzeiger können etwas als Referenz übergeben (wie Klassen), die Tatsache, dass diese Zeiger dieselbe Größe haben, ermöglicht das Ersetzen (Untertypisierung), unvollständige Typdeklarationen ermöglichen Ihnen undurchsichtige Zeiger auf Strukturen (private Mitglieder) ) und Funktionszeiger ermöglichen es Ihnen, Versandtabellen zu erstellen (Polymorphismus).

In diesem fiktiven Beispiel hat die Kenntnis einer Sprache OOP] Sie nicht nur daran gehindert, C zu verstehen, sondern Ihnen auch Konzepte beigebracht, die Sie auf C übertragen können. Diese Konzepte können selektiv angewendet werden wenn Sie sie benötigen, um die Verwaltung Ihres Codes zu vereinfachen, auch wenn die Sprache Sie nicht aktiv dazu drängt. (Ich würde argumentieren, dass es eine ähnliche Beziehung zwischen OOP und FP) gibt, aber lassen Sie uns nicht mitreißen lassen.)

Einige der besten Programmierer, die ich getroffen habe, sind so, wie sie sind, weil sie Abstraktionen verstehen und ihr Wissen auf jede Sprache übertragen und an jedes Problem anpassen können, das sie lösen müssen, auf jeder Ebene, auf der sie gerade arbeiten. Einige der schlechtesten Programmierer, die ich getroffen habe, sind so, wie sie sind, weil sie darauf bestehen, sich auf Details und Wissenswertes zu konzentrieren, die sie nicht wirklich verstehen und die oft nicht genau aktuell oder relevant sind das Problem oder anwendbar in dem Kontext, in dem sie versuchen, sie zu verwenden, oder waren überhaupt nicht wahr.

Alles, was Sie wissen müssen, ist, dass es zu einem bestimmten Zeitpunkt keine einzige Abstraktionsebene gibt und eine Person zu einem bestimmten Zeitpunkt nicht auf eine einzige Abstraktionsebene beschränkt ist. Sie können einen verstehen und dann zu einem anderen übergehen. Sie können einen beschäftigen und dann zu einem anderen wechseln - wann immer Sie möchten.

Schließlich dachte ich, Sie werden ein besserer Programmierer, wenn Sie das wissen, weil Sie wissen, was passiert, anstatt davon auszugehen, dass alles magisch ist.

Dies sind keine widersprüchlichen Dinge. Ich habe keine Ahnung, wie ich eine Straße pflastern soll, aber ich weiß, dass es keine Magie ist.

Aber vor einem Monat bin ich auf dieses Buch mit dem Titel Struktur und Interpretation von Computerprogrammen gestoßen, und alles im Internet deutet darauf hin, dass dies eines der besten Informatikbücher ist und Sie als Programmierer beim Lesen besser werden.

Ja, das ist absolut wahr.

Sollten wir nicht hauptsächlich alle Abstraktionen vermeiden und beobachten, was wirklich auf sehr niedriger Ebene passiert?

Vielleicht ein- oder zweimal, aber wenn Sie dies jedes Mal tun, werden Sie kein guter Programmierer. Sie müssen nicht zusehen, wie die Elektronen durch ein Tor fließen, um zu wissen, dass es keine Magie ist. Sie müssen nicht sehen, wie die CPU diese Elektronen in die bitweise Darstellung einer Zahl übersetzt, um zu wissen, dass es keine Magie ist. Sie müssen nicht sehen, wie diese Teile den Draht hinuntergehen, um zu wissen, dass es keine Magie ist. Es sind ein paar Dutzend Abstraktionen erforderlich, um diese Buchstaben nebeneinander zu platzieren. Ein paar hundert wahrscheinlich, um sie von den Servern von SE auf Ihren Computer zu bringen.

Niemand kennt sie alle - nicht in der Tiefe.

Dies ist ein sehr häufiges Problem bei Anfängern in der Programmierung. Sie wollen wissen, wie die Dinge funktionieren. Sie denken, dass ein niedriges Level das beste Level ist, weil es ihnen die meiste Macht, Kontrolle oder das meiste Wissen gibt. Es tut nicht.

Ja, du kannst es nicht als Magie behandeln. Aber das Zeug muss man auch wirklich nicht wissen. Das Verketten von Strings von Hand ist nicht interessant. Das Rollen Ihres eigenen Sortieralgorithmus ist nicht interessant. Weil jeder Programmierer das gleiche Ergebnis in wenigen Größenordnungen weniger Zeit erzielen kann, wenn er etwas verwendet, das vor Jahrzehnten von weitaus besseren Programmierern geschrieben wurde.

40
Telastyn

Ich weiß, warum Abstraktion großartig ist, aber hindert Sie das nicht daran, die Funktionsweise von Computern zu lernen?

Sicherlich nicht. Wenn Sie die Abstraktionen bei der Arbeit verstehen möchten, studieren Sie diese Abstraktionen. Wenn Sie die technischen Details eines realen, physischen Computers auf niedriger Ebene verstehen möchten, studieren Sie diese Details. Wenn Sie beide verstehen wollen, studieren Sie beide. (Meiner Meinung nach wird das ein guter Programmierer tun.)

Sie scheinen in eine falsche Zweiteilung geraten zu sein, als ob Sie jeweils nur eine Abstraktionsebene verstehen können (oder, schlimmer noch, als ob jeweils nur eine Abstraktionsebene existiert). Das ist eher so, als würde man behaupten, dass es für jemanden grundsätzlich unmöglich ist, sowohl Physik als auch Mathematik zu verstehen.

Ein guter Anfang wäre, die Unterscheidung zwischen Informatik und Programmierung zu entdecken.

Eine Schlüsselkompetenz in der Programmierung ist das gleichzeitige Denken auf mehreren Abstraktionsebenen. Eine weitere Schlüsselkompetenz ist das Erstellen von Abstraktionen. Diese Fertigkeit verwendet die vorherige. Low-Level-Programmierung ist zum Teil deshalb wertvoll, weil sie beide Fähigkeiten trainiert und erweitert.

SICP modelliert und implementiert Interpreter, Simulatoren für ein Maschinenmodell und einen Compiler für dieses Maschinenmodell (dessen Ausgabe dann auf dem Simulator ausgeführt werden kann). Das Maschinenmodell ist zwar sehr einfach, aber nicht von Natur aus weniger niedrig als x86_64. Ehrlich gesagt handelt es sich bei einer guten Menge an Low-Level-Programmierung um willkürliche und arkane Hardware-/Firmware-Schnittstellen, die nicht besser sind als die willkürlichen Regeln der Geschäftslogik.

16

Ich weiß, warum Abstraktion großartig ist, aber hindert Sie das nicht daran, die Funktionsweise von Computern zu lernen? Vermisse ich etwas

Wenn Sie zu einer Zaubershow gehen, werden Sie unterhalten, aber Sie werden nicht verstehen, wie die Tricks funktionieren. Wenn Sie ein Buch über Magie lesen, werden Sie lernen, wie Tricks funktionieren, aber Sie werden trotzdem nicht unterhaltsam sein.

Tue beides. Hart arbeiten. Und Sie könnten beide sein.

Ich habe auf hohem Niveau gearbeitet SOLID, Bash, UML. Ich habe auf niedrigen Ebenen gearbeitet, TASM, Arithmetische Logikeinheiten, Analoge Schaltungen. Ich kann Ihnen sagen, es gibt keine Ebene, auf der Sie arbeiten können, auf der keine Magie von Ihnen abstrahiert ist.

Der Schlüssel ist sicherlich nicht, jede Abstraktionsebene gleichzeitig zu verstehen. Es ist wichtig, eine Ebene gut genug zu verstehen, um sie richtig zu verwenden, und gut genug, um zu wissen, wann es Zeit ist, zu einer anderen zu wechseln.

Jede ausreichend fortschrittliche Technologie ist von Magie nicht zu unterscheiden.

Arthur C Clark

5
candied_orange

Software-Engineering hat mehrere Detailebenen. Ihre Frage lautet: "Was ist das lohnendste, würdigste und interessanteste Level?"

Es hängt von Ihrer Aufgabe ab oder davon, was Sie sein möchten, was Sie interessiert. Bei großen Systemen sollten Sie sich nicht viel um Bitverschiebung und Taktzyklen kümmern. Bei eingebetteter Software, die auf einem einfachen Mikrocontroller ausgeführt wird, sollten Sie wahrscheinlich die Menge des von Ihnen verwendeten Speichers im Auge behalten und müssen möglicherweise einige primitive Timing-Routinen schreiben.

Manchmal kann eine auf einer hohen Abstraktionsebene getroffene Auswahl die Leistung oder die Ressourcennutzung Ihres Systems beeinträchtigen. Das zu erkennen und zu verstehen, warum und wie es hilft, die bessere Wahl zu treffen oder einen Weg zu finden, ein bestehendes System effizienter zu machen. Dies funktioniert in beide Richtungen: Wenn Sie wissen, dass ein Dienstprogramm auf hoher Ebene verfügbar ist, können Sie Ihr eigenes Rad in Ihrer Domäne auf niedriger Ebene nicht erfinden. Ein gewisses Verständnis für andere Ebenen als die, an der Sie arbeiten, kann Ihnen helfen, effektiver zu sein.

Auf persönlicher Ebene möchten Sie sich vielleicht fragen: "Lege ich gerne Ziegel oder möchte ich Häuser entwerfen?" Oder vielleicht Layouts von Städten machen. Oder die Wissenschaft verbessern, die einen stärkeren, leichteren und billigeren Stein macht?

3
Martin Maat

Die Abstraktionen, die wir in der Informatik unterrichten, sind die Dinge, die sich historisch für die meisten Leute, die die meisten Programme schreiben, als am vorteilhaftesten erwiesen haben. Sie können in Assembly kein modernes Programm schreiben, nur aufgrund der Größe moderner Programme und der zeitlichen Einschränkungen, die das Geschäft einem Entwickler auferlegt. Sie müssen bereit sein, Ihre Ziele zu erreichen, ohne zu 100% zu verstehen, was vor sich geht. Die Abstraktionen sind leistungsstarke Tools, mit denen Sie genau das tun können.

Jetzt in meinem ersten Satz hatte ich viele "Meisten". In Ihrer Karriere werden Sie von Zeit zu Zeit in Situationen geraten, in denen die von Ihnen erlernten Abstraktionen Sie in die Irre führen. Zu diesen Zeiten müssen Sie anderes Wissen ausgraben. Manchmal ist das so einfach wie das Erlernen der richtigen Abstraktion für den Job. In anderen Fällen ist genau das erforderlich, was Sie getan haben: Sie müssen versuchen zu verstehen, was das zugrunde liegende System tut, wenn Sie diese Abstraktionen verwenden.

Schauen Sie sich zum Beispiel Multithreading an. Traditionelles Multithreading mit Mutexen, kritischen Abschnitten, Bedingungsvariablen usw. ist auf abstrakter Ebene sehr gut verstanden. Sie müssen nicht verstehen, wie der Kernel Threads ein- und auslagert oder wie die vom Timer gesteuerten Interrupts Ihren Benutzer-Threads die Kontrolle entziehen, damit der Kernel seine Magie entfalten kann. Möglicherweise müssen Sie nie erfahren, was RCU ist oder warum Sie irgendwann tief im Darm des Kernels die Verwendung von Mutexen einstellen müssen. Wenn Sie versuchen, es von der Kernel-Ebene aus zu verstehen, können Sie gefährliche Fehler machen. Ich kann die Anzahl der Rennfälle, die ich beheben musste, nicht zählen, weil jemand eine Operation für "ausreichend atomar" hielt und sie nicht richtig mit Mutexen bewachte. Sie müssen wirklich Kernel (und Compiler) verstehen, bevor dieses Wissen Ihnen helfen kann, sicheren, mutlithreaded Code zu schreiben. Es ist weitaus effektiver, alles auf der abstrakten Ebene der Mutexe zu tun.

Jetzt lass es uns ein wenig schieben. Anstatt "die meisten" mutlithreaded-Programme zu schreiben, die mit den Abstraktionen gut zurechtkommen, können Sie den wirklich blutenden Edge-Code mithilfe atomarer Operationen schreiben. Jetzt können Sie atomare Operationen als abstraktes Konzept lernen und sie erfolgreich anwenden, aber Sie werden sich am Kopf kratzen und sich fragen, was sie geraucht haben, als sie die API zusammengestellt haben. Es gibt alle möglichen Dinge, die in den Details der Speichersynchronisation von atomaren Operationen auftauchen, die Ihren Kopf verletzen. In diesem Fall ist es sehr hilfreich, Dinge von Grund auf zu lernen, wie Sie bereits erwähnt haben, um zu verstehen , warum die Abstraktionen das tun, was sie tun. Wenn Sie erst einmal verstanden haben, was Caches tun und wie sie sich gegenseitig beobachten, um die Synchronisation aufrechtzuerhalten, können Sie sehen, warum die Absurdität der API für atomare Operationen entstanden ist - es war eine Hardware-Notwendigkeit. Sobald Sie sie verstanden haben, können Sie besser verstehen, wie Sie die letzten Millisekunden aus Ihrem wertvollen Echtzeitalgorithmus herausholen und den Tag retten können!

Beide Ansätze haben also ihren Wert. Sie können wertvolleren Code schneller produzieren, wenn Sie bereit sind, Abstraktionen zu akzeptieren, ohne sie vollständig an die Hardware zu binden. Es wird jedoch Fälle geben, in denen Sie durch ein Verständnis der Hardware die Grenzen der Abstraktionen auf eine Weise verschieben können, die andere Entwickler nie für möglich gehalten hätten. Ein fröhliches Medium, sage ich. Finde ein Gleichgewicht zwischen beiden!

3
Cort Ammon

Wie spät ist es?

Ist es Zeit, ein Besserwisser zu werden, oder ist es Zeit, ein produktiver Programmierer zu werden?

Wenn Sie die Abstraktionsschichten kennen, die unter denen liegen, unter denen Sie arbeiten, ist dies eine gute Sache. Dadurch erhalten Sie ein besseres Verständnis für die Struktur Ihrer Arbeit und können sogar bessere Lösungen erstellen.

Aber Sie tun das, Sie lernen, wenn es nicht Zeit ist, produktiv zu sein. Wenn es an der Zeit ist, produktiv zu sein, nehmen Sie hochrangige Tools und bauen mit ihnen. Verwenden Sie Ihr gesamtes Wissen über die Funktionsweise der Dinge und drücken Sie die Lösung in Begriffen aus, die für den Problembereich sinnvoll sind.

Natürlich müssten Sie wissen, wie man solche Tools verwendet. Es gibt einen Kompromiss zwischen der Zeit, die zum Erstellen mit einem schlechten Tool benötigt wird vs der Zeit, um zu lernen, wie man ein geeigneteres Tool verwendet. Das geht über den Rahmen dieser Frage hinaus. Sie verstehen jedoch, dass es von Vorteil ist, verschiedene Tools zu kennen.


Bis jetzt war ich immer der Meinung, dass Sie Programmiersprachen lernen sollten, die Sie dazu bringen, einfache Dinge zu tun (z. B. C).

Es ist nicht so, dass Sie sollten , es ist so, dass es eine gute Sache ist, Low-Level-Sachen zu kennen.

um zu verstehen, was wirklich unter der Haube passiert und wie der Computer wirklich funktioniert.

Zunächst einmal benötigen Sie keine Programmiersprache, um die Funktionsweise des Computers zu verstehen. Zweitens ... Ich befürchte, dass C zu hoch und etwas schmal ist. C ist eine gute Abbildung einer alten Version der Hardwarearchitektur, die abstrakt genug ist, um als Quelle auf verschiedene Systeme portierbar zu sein. Wenn Sie ein tiefgreifendes Verständnis wünschen, sollten Sie die Assemblersprache anstreben (beachten Sie, dass die Assemblersprache eine Abstraktion der Maschinensprache ist).

Schließlich dachte ich, dass Sie ein besserer Programmierer werden, wenn Sie das wissen

Ja, Sie werden ein besserer Programmierer, wenn Sie das wissen.

Weil Sie wissen, was passiert, anstatt davon auszugehen, dass alles magisch ist.

Sie müssen nicht wissen, wie Dinge funktionieren, um zu wissen, dass sie keine Magie sind. Alles, was Sie brauchen, ist ein Verständnis dafür, wie sie funktionieren, wie hoch ihre Kosten sind und was Sie davon erwarten können.

Und Low-Level-Sachen zu kennen ist viel interessanter als Business-Programme zu schreiben, denke ich.

Naja ... Low-Level-Sachen sind insofern interessant, als sie zum Nachdenken anregen und Neugier wecken. Business-Programme können sich mit einer anderen Bedeutung von Zinsen befassen, die sich auf Geld bezieht.

Außerdem haben Sie möglicherweise den Eindruck, dass alle Business-Programme ziemlich gleich sind: einige Datenbanken, einige Modellklassen, einige CRUD usw. Das sind die langweiligen. Aber schauen Sie, wie vielfältig Software ist und wie vielfältig das Geschäft um sie herum ist. Beschränken Sie sich nicht.

Mein Ziel ist es, ein besserer Programmierer zu werden, die Informatik besser zu verstehen, und das hat mich wirklich verwirrt.

Wenn Sie ein besserer Programmierer werden möchten, lernen Sie, wiederverwendbaren Code zu schreiben. Denn wenn Sie Code haben, dem Sie vertrauen können, dass Sie funktionieren und den Sie nicht jedes Mal neu schreiben müssen, werden Sie produktiver (wie in: dieselbe Aufgabe in kürzerer Zeit erledigen, aber auch wie in: weniger Fehler haben). Wenn Sie dies tun, könnten Sie daran interessiert sein, Ihren wiederverwendbaren Code in einem wiederverwendbaren und gemeinsam nutzbaren Format zu platzieren ... und ihn möglicherweise sogar mit anderen Entwicklern zu teilen. Wenn Sie dies zumindest in Betracht ziehen, hoffe ich, dass sich daraus eine Wertschätzung für wiederverwendbaren Code ergibt, die von anderen geteilt wird, eine Wertschätzung für die Nützlichkeit von Entwicklungswerkzeugen und eine Wertschätzung für übergeordnete Sprachen. Diese Dinge machen Sie zu einem besseren Programmierer.

Wenn Sie dagegen Informatik lernen möchten, müssen Sie die Besonderheiten außer Acht lassen. Wenn Sie beispielsweise feststellen möchten, ob ein Algorithmus effizienter als ein anderer ist, sollten die Ergebnisse nicht durch die jeweilige CPU eingeschränkt werden. Die Informatik ähnelt eher der Mathematik, sie ist abstrakt.

Sollten wir nicht hauptsächlich alle Abstraktionen vermeiden und beobachten, was wirklich auf sehr niedriger Ebene passiert?

Nein, Abstraktionen sollten Sie nicht vermeiden. Und ja, Sie können beobachten, was auf relativ niedrigen Ebenen passiert.

Wie spät ist es? Ist es Zeit zu lernen, wie Dinge funktionieren, oder ist es Zeit, produktiv zu sein?

Wenn es Zeit ist zu lernen, wie Dinge funktionieren, dann vermeiden Sie nicht die Abstraktionen ... beobachten Sie sie in Aktion von der unteren Ebene aus, Sie erstellen sie sogar selbst! Erleben Sie, wie und warum sie so arbeiten, wie sie es tun.

Wenn es Zeit ist, produktiv zu sein, vermeiden Sie nicht die Abstraktionen ... Wählen Sie die richtigen für die jeweilige Aufgabe aus und nutzen Sie sie.

Wenn Sie überhaupt lernen möchten, wie Sie produktiver arbeiten können, denken Sie daran, dass die Tools verwendet werden können. Warum sollten Sie versuchen, das Holz mit bloßen Händen in einen Nagel zu stechen, wenn Hämmer verfügbar sind? Warum sollten Sie eine magnetisierte Nadel und eine ruhige Hand verwenden, um Bits auf einer Festplatte umzudrehen, wenn Texteditoren verfügbar sind ?

Vermeiden Sie nicht die Abstraktionen, sie sind Werkzeuge.

Ich weiß, warum Abstraktion großartig ist, aber hindert Sie das nicht daran, die Funktionsweise von Computern zu lernen? Vermisse ich etwas

Sie vergessen, dass Sie mehrere Dinge lernen können. Lernen Java hindert Sie nicht daran, C zu lernen, Lernen C hindert Sie nicht daran, C # zu lernen. Lernen OOP hindert Sie nicht daran, Daten zu lernen Strukturen, das Lernen von Datenstrukturen hindert Sie nicht daran, AOP zu lernen. Das Lernen der Assemblersprache hindert Sie nicht daran, Elektronik zu lernen, und das Lernen von Elektronik hindert Sie nicht daran, Logikgatter zu lernen.


Niemand weiß alles, was es gibt, damit Ihr Computer funktioniert. Dies bedeutet jedoch nicht, dass Sie überall einen komfortablen Wissensstand erreichen können. Angefangen bei der Kernphysik bis hin zur Benutzererfahrung finden Sie Online-Kurse und Communitys mit Menschen, die bereit sind zu helfen.

Bearbeiten: Die obige kann eine unpopuläre Meinung sein. Ich habe drei Dinge zu sagen: 1) Ich sagte bequem - ich meine, mit dir. Ich habe nie gesagt, dass Sie ein Feldexperte sein werden. 2) Ich erwähne Online-Kurse als Ausgangspunkt - und ja, es gibt Online-Kurse zur Kernphysik (bezahlt, wenn Sie etwas Gutes wollen, aber online). Es gibt auch Kurse, die Sie von Logikgattern zu primitiven Videospielen 3) Ich verstehe, dass Spezialisierung einen Wert hat, und ich wollte nicht ermutigen, alles zu lernen.

Überlegen Sie noch einmal, ob dies die beste Nutzung Ihrer Zeit ist. Wenn der Kunde Sie mit der Erstellung einer neuen mobilen App beauftragt, werden Sie das Projekt dann stoppen, weil Sie noch nicht verstehen, wie Halbleiter funktionieren? Nein, natürlich nicht.

Das Warum ist das Detail. Sie können "Nein" sagen, weil Sie sich nicht für Physik oder Materialien interessieren ... dennoch sollten Sie "Nein" sagen, weil es Zeit ist, produktiv zu sein. Unabhängig davon sind wir uns einig, dass Sie auswählen können, welche Abstraktionsebenen Sie lernen.

Sie können so tun, als hätten Sie Abstraktionen im Allgemeinen vermieden, Sie haben nur einige von ihnen vermieden.


Der Ansatz, alles zu verstehen, indem man es in seine Bestandteile aufteilt, ist in vielen Disziplinen unzureichend. Das liegt daran, dass es neue Verhaltensweisen gibt, die nur sichtbar sind - und daher nur untersucht werden können -, wenn die Komponenten integriert sind.

Kümmern sich Bauingenieure um die Position einzelner Atome? Nein, das tun sie nicht. Sie machen sich nicht einmal die Mühe, neue Materialien zu erstellen (diese Aufgabe ist für einen Materialingenieur) - für den Bauingenieur sind die Materialien eine bequeme Abstraktion. Sie müssen nicht wissen, wie Atome angeordnet sind, sie müssen wissen, wie viel sie kosten und wie sie sich verhalten (wie sie auf Stress, Feuchtigkeit usw. reagieren), und dennoch wissen sie, dass die Materialien keine Magie sind.

Es gibt wenig, was Sie über Biologie lernen können, wenn Sie darauf bestehen, alles in Atome zu zerlegen. Es gibt wenig, was Sie über Psychologie lernen können, wenn Sie darauf bestehen, alles in Neuronen zu zerlegen.

Du hast die Idee.

3
Theraot

Am anderen Ende des Spektrums befindet sich ein weiteres Buch, das oft als Klassiker des Lehrens von Algorithmen gelobt wird: Donald E. Knuths Kunst der Computerprogrammierung . DEK gab alle seine Algorithmen in einer (gefälschten, abstrahierten) Maschinensprache an, da Programmierer seiner Ansicht nach dazu neigen, Code zu schreiben, der in der von ihnen verwendeten Sprache einfach und effizient ist, und die Größe und Leistung des Maschinencodes ist das, was wirklich ist Angelegenheiten.

Dieses Buch ist wirklich ein Klassiker, und er hat einen großen Punkt gemacht - meistens. Um eine Abstraktion zu vermeiden, die die tatsächlichen Kosten des Programms verbirgt, hatten seine ersten Ausgaben kein Betriebssystem, und die Aufrufkonvention seiner Beispielprogramme verwendete selbstmodifizierenden Code. Auf einem modernen Desktop-Prozessor würden solche Programme buchstäblich nicht einmal ausgeführt, da die CPU und das Betriebssystem nicht zulassen, dass Anwendungscode direkt mit der Hardware kommuniziert, und moderne CPUs über Anweisungs-Caches verfügen, die durch Selbstmodifikation ungültig werden.

Wenn Sie schnellen Code schreiben möchten, werden Sie ein Profil erstellen und feststellen, dass die leistungskritischsten Abschnitte Schleifen sind, die häufig aufgerufen werden. Was ist eine Schleife? Es werden folgende Garantien gegeben: Jede Iteration wird nacheinander ausgeführt, basierend auf beliebigen Anweisungen, aber normalerweise dem Wert eines Schleifenindex, der beliebig geändert werden kann und eine Adresse im Speicher hat, die Sie mit & Abrufen können. Nur stellt sich heraus, dass Sie auf moderner Hardware Beschleunigungen mit Parallelität erhalten: entweder die Schleife vektorisieren oder die Arbeit zwischen Threads teilen. Und es stellt sich heraus, dass das Low-Level-C-Konstrukt, das sehr genau den Fähigkeiten der PDP-Maschinen entspricht, für die es ursprünglich geschrieben wurde, eine Reihe von Garantien verletzt, die für einen modernen Optimierer sehr nützlich wären.

Einige der Programmiersprachenabstraktionen, die C nicht hat, wie foreach, Container und Iteratoren oder sogar funktionale Programmierung, können die meisten dieser Schleifen heute effizienter und sicherer kompilieren als viele der Optimierungen, die es früher gab C-Code effizient gemacht, wie Zeigerarithmetik und Duff's Device. In ähnlicher Weise waren DOS-Spiele äußerst effizient, weil sie so nahe am Metall liefen, bis die Leute sie nur auf Emulatoren wie DOSBox liefen. Niemand macht sich heute Sorgen um die Codegröße, und Programmierer behalten nicht viele Zähler, um ihr Spiel zeitlich zu steuern, da es jetzt so viel einfacher ist, einen Zeitstempel beizubehalten und eine Teilung und einen Rest darauf vorzunehmen. Ähnlich wie niemand Multiplikation und Division durch Konvertieren in und aus Logarithmentabellen.

Eine Sache, die Sie verstehen möchten, ist, wie Ihre Operationen ausgeführt werden, wenn Sie sie implementieren heute. Was läuft schnell auf moderner Hardware? Wichtig ist aber auch, dass mathematische Eleganz zeitlos ist. Sie möchten Ihr Design klar und verständlich ausdrücken können, Sie möchten es effizient optimieren können und Sie möchten verstehen, welche Teile des Projekts auf einer niedrigeren Abstraktionsebene umgestaltet werden müssen.

1
Davislor

Vielleicht möchten Sie Zen und die Kunst der Motorradpflege lesen, das genau diese Frage anspricht. Die Schlussfolgerung, zu der es gelangt, ist, dass Sie darauf abzielen sollten, die höchste "Qualität" auf der von Ihnen gewählten Abstraktionsebene (n) zu erzielen. Manchmal bedeutet dies, mehr über die Ebenen über und unter Ihnen zu verstehen, aber im Allgemeinen können Sie nicht alle Ebenen beherrschen.

1
DrMcCleod

Abstraktionen sind notwendig, um die Komplexität zu verwalten, die die Nemesis aller Programmierer ist. Es ist genauso wichtig, mit Abstraktionen zu lernen, wie die Details dahinter zu lernen.

Eine Lösung für ein reales Problem muss eine Darstellung haben, die dem Modell des Problems sehr ähnlich ist. Aus diesem Grund hat ein Würfelspiel eine Klasse namens Die mit einer Methode namens roll() und keinen Codeblock mit 011100110000001110101000100001010101000100 (vorausgesetzt, diese Abstraktionen von Binärziffern waren auf einer Plattform sinnvoll). Dies wurde von Larman als Repräsentationslücke bezeichnet. Abstraktionen ermöglichen es, diese Lücke kleiner zu halten - eine Strategie, die als Low Representaitonal Gap (LRG) bekannt ist. Es erleichtert das Nachverfolgen und Verstehen von Code. Der Ansatz Domain-Driven Design (DDD) ist ähnlich.


(UML class diagram of DiceGame

Als Programmierer fühlen wir uns natürlich zu komplexen Rätseln hingezogen. Wir sind stolz, wenn wir ein komplexes Problem gelöst haben. Das Paradoxe ist jedoch, dass wir als Menschen nicht viel Arbeit erledigen, wenn die Dinge ständig zu komplex sind. Halten Sie es einfach (über Abstraktionen) ist besser, wenn wir eine Wahl haben.

1
Fuhrmanator

Wie in philipxys Antwort angegeben, ist alles Digitale eine Abstraktion. Auch die elektrotechnische Sicht auf Ströme und Spannungen ist eine Abstraktion.

Ich habe als Computerarchitekt, Compilerautor und Betriebssystementwickler gearbeitet. Ich habe die Erfahrung gemacht, Java Programme zu schreiben, die ich auf einem Server ausführen wollte, den ich mitgestaltet habe.

Das zyklische Wissen darüber, wie ein Cache-Fehler genau funktionieren würde, wenn die Daten geändert würden und sich derzeit im schreibgeschützten Modus in einem anderen Prozessor im Cache befinden, war viel zu detailliert, um beim Schreiben eines Java Programm. Andererseits brauchte ich diese Detailstufe, als ich die Auswirkungen des Hinzufügens eines Latenzzyklus zu bestimmten Cache-Fehlfällen auf die Leistung analysierte.

Ein wesentlicher Teil der Programmierkunst besteht darin, das richtige Modell für das zu lösende Problem auszuwählen.

0

Wie andere betont haben, ist alles sowohl eine Abstraktion als auch ein Detail. Mit den Abstraktionen können Sie sich darauf konzentrieren, die beteiligten Konzepte zu verstehen und zu manipulieren, während Sie mit Kenntnis der Details diese implementieren können. Für einen Lösungsarchitekten ist die Programmiersprache nur ein Detail, für einen Codierer, der einen Sortieralgorithmus optimiert, ist ein Datentyp nur eine Abstraktion. Ich empfehle immer, mindestens die Details auf der Ebene unterhalb der erforderlichen zu kennen, um zu vermeiden, dass schlechte oder teure Implementierungsentscheidungen getroffen werden. Ebenso empfehle ich jedoch, die Konzepte auf der Ebene über denen zu kennen, die erforderlich sind, um den Kontext zu verstehen, in dem sich Ihre Lösung befindet erwartet passt in.

0
Paul Smith