Welche konkreten Beispiele gibt es zu wissen, C machen Ihnen einen besseren hohes Niveau Programmierer?

StackOverflow https://stackoverflow.com/questions/2077913

  •  21-09-2019
  •  | 
  •  

Frage

Ich weiß um die Existenz Frage wie dieses und Back to Basics und viele ähnliche Fragen auf SO zu sehen, ich habe zu fragen, was begonnen konkrete Beispiele für Situationen, in denen Dinge wie C zu wissen, können Sie eine bessere hohem Niveau Programmierer machen.

Was ich möchte wissen, ist, wenn es viele Beispiele dafür sind. Viele Male, ist die Antwort auf diese Frage so etwas wie „ Knowing C gibt Ihnen ein besseres Gefühl von dem, was unter der Decke geschieht “ oder „ Sie benötigen ein solides Fundament für Ihr Programm “, und diese Antworten haben nicht viel Sinn. Ich mag die unterschiedliche spezifische Art und Weise, verstehen Sie aus dem Wissen niedrigen Niveau Konzepten profitieren,

gab Joel ein paar Beispiele: Binäre Datenbanken vs XML und Strings. Aber zwei Beispiele rechtfertigen nicht wirklich lernen, C und / oder Montage. Also meine Frage ist: Welche konkreten Beispiele geben es C zu wissen, Ihnen einen besseren hohes Niveau Programmierer macht

?
War es hilfreich?

Lösung

Meine Erfahrung mit Lehre Studenten und mit Leuten zu arbeiten, die nur Sprachen auf hohe Ebene untersucht ist, dass sie bei einem bestimmten hohen Abstraktionsniveau neigen dazu zu glauben, und sie gehen davon aus, dass „alles umsonst kommt“. Sie können sehr kompetente Programmierer geworden, aber schließlich müssen sie mit einigen Code beschäftigen, die Performance-Probleme hat und dann kommt es zu beißen.

Wenn Sie viel mit C arbeiten, müssen Sie darüber nachdenken, Speicherzuweisung. Sie denken oft über Speicherlayout (und Cache-Lokalität, wenn das ein Problem ist). Sie verstehen, wie und warum bestimmte Grafikoperationen nur eine Menge Geld kosten. Wie effizient oder ineffizient bestimmte Socket-Verhalten ist. Wie Puffer Arbeit, etc. Ich glaube, dass die Abstraktionen in einer Hochsprache zu verwenden, wenn Sie wissen, wie es manchmal unter den Abdeckungen realisiert wird, gibt Ihnen „dass zusätzliche geheime Zutat“, wenn man über die Leistung.

Zum Beispiel hat Java einen Garbage Collector und Sie können nicht direkt assign Dinge in den Speicher direkt. Und doch können Sie bestimmte Design-Entscheidungen treffen (zum Beispiel mit benutzerdefinierten Datenstrukturen) auf die Leistung auswirken, da aus den gleichen Gründen wäre dies in C ein Thema sein.

Auch und generell glaube ich, dass es für einen Leistungs Programmierer wichtig ist, nicht nur wissen, Big-O-Notation (die meisten Schulen lehren), aber die in realen Anwendungen ist die Konstante auch wichtig (die Schulen versuchen ignorieren). Meine anekdotische Erfahrung ist, dass Menschen mit Fähigkeiten in beiden Sprachebenen sind in der Regel ein besseres Verständnis für die Konstante haben, vielleicht wegen dem, was ich oben beschrieben.

Darüber hinaus sind viele übergeordnete Systeme, dass I-Schnittstelle mit niedriger Ebene Bibliotheken und Infrastrukturen gesehen haben. Zum Beispiel einige Kommunikation, Datenbanken oder Grafikbibliotheken. Einige Treiber für bestimmte Geräte, etc. Wenn Sie ein Power-Programmierer sind, können Sie eventially müssen es wagen, und es hilft, zumindest eine Vorstellung davon haben, was los ist.

Andere Tipps

Zu wissen Sachen niedrige Niveau kann viel helfen.

Um ein Rennfahrer zu werden, muss man die grundlegende Physik, wie Reifen Griff der Straße lernen und zu verstehen. Jeder kann lernen, ziemlich schnell zu fahren, aber man braucht einen guten die „low level“ Sachen zu verstehen (Kräfte und Reibung, Rennlinien, feine Gas- und Bremssteuerung, usw.) die letzten paar Prozent der Leistung zu erhalten, die es Ihnen erlaubt, gewinnt das Rennen.

Zum Beispiel, wenn Sie verstehen, wie die CPU-Architektur in Ihrem Computer funktioniert, können Sie Code schreiben, das funktioniert besser mit ihm (zB wenn Sie wissen, dass Sie eine bestimmte CPU-Cache-Größe oder eine bestimmte Anzahl von Bytes in jeder CPU-Cache-Zeile , können Sie Ihre Datenstrukturen und die Art und Weise anordnen, dass Sie sie Zugriff auf die bestmögliche Nutzung des Cache machen - zum Beispiel, viele Elemente eines Arrays, um die Verarbeitung ist oft schneller als zufällige Elemente der Verarbeitung aufgrund der CPU-Cache). Wenn Sie einen Multi-Core-Computer haben, dann verstehen, wie niedriges Niveau Techniken wie Threading arbeiten können gab enorme Vorteile (wie nicht das niedrige Niveau zu verstehen, in Einfädeln zu einer Katastrophe führen kann).

Wenn Sie verstehen, wie Disk I / O und das Caching funktioniert, können Sie Dateioperationen zu arbeiten gut mit ihm (zB ändern, wenn Sie von einer Datei und Schreiben in einer anderen zu lesen, auf große Chargen von Daten im RAM arbeiten können mich dazu beitragen, / O-Konflikte zwischen dem Lesen und Schreiben von Phasen des Codes und erheblich verbessern den Durchsatz)

Wenn Sie verstehen, wie virtuelle Funktionen arbeiten, können Sie entwerfen High-Level-Code, dass Anwendungen virtuelle Funktionen und . Wenn falsch verwendet können sie die Leistung erheblich beeinträchtigen.

Wenn Sie verstehen, wie Zeichnung behandelt wird, können Sie clevere Tricks verwenden, um Zeichengeschwindigkeit zu verbessern. z.B. Sie können durch abwechselnde Zeichnung 64 weiße und schwarze Quadrate ein Schachbrett ziehen. Aber es ist oft schneller 32 weiß sqares zu zeichnen und dann 32 schwarze (weil Sie nur die Zeichenfarbe ändern müssen zweimal statt 64 mal). Aber man kann tatsächlich das ganze Brett schwarz zeichnen, dann XOR 4 Streifen auf der ganzen Linie und 4 Streifen auf der Platine in weiß, und dies kann viel schneller noch (2 Farbwechsel, und nur 9 Rechtecke statt 64 zu ziehen) sein. Das Schachbrett Trick vermittelt Ihnen eine sehr wichtige Programmierkenntnisse: Querdenken. Durch die Gestaltung Ihres Algorithmus gut, können Sie oft einen großen Unterschied machen, wie gut Ihr Programm arbeitet.

Verstehen C, oder was das betrifft, jede niedrige Level-Programmiersprache, gibt Ihnen die Möglichkeit Dinge wie Speichernutzung zu verstehen (dh warum ist es eine schlechte Sache mehrere Millionen schwere Gegenstände zu schaffen), wie Zeiger / Objektreferenzen Arbeit, etc.

Das Problem ist, dass wir erstellt haben immer Abstraktionsebenen zu erhöhen, finden wir uns eine Menge ‚lego Block‘ Programmierung zu tun, ohne zu verstehen, wie die legos eigentlich funktionieren. Und fast unendliche Ressourcen, die wir Speicher und Ressourcen wie Wasser beginnen zu behandeln, und neigen dazu, Probleme zu lösen, indem sie mehr Eisen auf die Situation werfen.

Während auf C nicht beschränkt ist, ist es ein enormer Vorteil auf einem niedrigen Niveau mit vielen kleineren, wenig Speicher-Systemen wie der Arduino oder Old-School-8-Bit-Prozessoren zu arbeiten. Damit können Sie in der Nähe des Metalls in einem viel zugänglicher Paket Codierung erleben, und die Zeit, nachdem er apps in 512K quetschen, werden Sie sich die Anwendung dieser Fähigkeiten in einem größeren Ebene innerhalb Ihrer täglichen Programmierung finden.

So ist die Sprache selbst ist nicht wichtig, aber mit einem tieferen Verständnis dafür, wie alle Bits zusammen kommen, und wie man effektiv arbeiten auf einem Niveau näher an der Hardware ist eine Reihe von Fähigkeiten von Vorteil für jeden Software-Entwickler.

Zum einen C zu wissen, helfen Sie zu verstehen, wie das Gedächtnis in dem O arbeitet und in anderen Hochsprachen. Wenn Ihr C # oder Java-Programm Ballons auf die Speichernutzung, dass Verweise zu verstehen (die nur Zeiger im Grunde sind) zu Speicher nehmen und verstehen, wie viele der Datenstrukturen implementiert werden (was Sie davon ab, Ihre eigene in C erhalten) hilft Ihnen zu verstehen, dass Ihr Wörterbuch ist riesige Mengen an Speicher reserviert, die nicht tatsächlich verwendet werden.

Zum anderem C zu wissen, können Ihnen helfen, zu verstehen, wie die Verwendung von niedrigerem Niveau Betriebssystemfunktionen zu machen. Sie brauchen dies nicht oft, aber manchmal können Sie im Speicher abgebildeten Dateien benötigen, oder in C # Rangier zu verwenden, und C wird sehr helfen, verstehen, was Sie tun, wenn das passiert.

ich denke, C hat auch mein Verständnis von Netzwerkprotokollen geholfen, aber ich kann meine Finger nicht auf spezielle Beispiele setzen. Ich las eine andere Frage SO den anderen Tag, wo jemand beschwerte sich darüber, wie C der Bit-Felder sind ‚im Grunde nutzlos‘ und ich dachte, wie elegant C-Bit-Felder repräsentieren Low-Level-Netzwerkprotokolle. Hochsprachen mit Strukturen von Bits zu tun immer ein Chaos am Ende!

In der Regel, je mehr Sie wissen, desto besser Programmierer Sie werden.

Aber manchmal eine andere Sprache, wie C zu wissen, können Sie die falsche Sache machen zu tun, denn es könnte eine Annahme, die nicht wahr in einer höheren Programmiersprache (wie Python oder PHP) ist. Zum Beispiel könnte man annehmen, dass die Länge einer Liste zu finden sein könnte O (N), wobei N die Länge der Liste ist. Dies ist jedoch wahrscheinlich nicht der Fall in vielen High-Level-Sprache-Instanzen. In Python, für die meisten Listen wie die Dinge sind die Kosten O (1).

Mehr Wissen über die Besonderheiten einer Sprache helfen, aber im allgemeinen Macht zu wissen, man führte falsche Annahmen zu machen.

Just "Wissen" C nicht besser machen Sie.

Aber, wenn Sie das Ganze zu verstehen, wie nativer Binärdateien Arbeit, wie funktioniert CPU Arbeit mit ihm, was Architektur Einschränkungen sind, können Sie einen Code schreiben, die leichter für die CPU ist.

Zum Beispiel, wie L1 / L2-Caches beeinflussen Ihre Arbeit, und wie sollten Sie schreiben Ihren Code mehr Treffer in L1 / L2-Caches zu haben. Wenn Sie mit C / C ++ arbeiten und schweren Optimierungen zu tun, müssen Sie auf diese Art von Dingen nach unten gehen.

Es ist nicht so viel zu wissen, C, wie es ist, dass C näher an das blanke Metall ist als viele andere Sprachen. Sie müssen sich mehr bewusst sein, wie / Frei Speicher zuweisen, weil Sie es selbst zu tun haben. Tun Sie es selbst hilft Ihnen, die Auswirkungen vieler Entscheidungen verstehen, dass Sie zu machen.

Für mich jede Sprache ist akzeptabel, solange Sie verstehen, wie der Compiler / Interpreter (grundsätzlich) bildet den Code auf der Maschine. Es ist ein bisschen einfacher, in einer Sprache zu tun, dass diese direkt aussetzt, aber Sie sollten mit ein bisschen lesen, herauszufinden, wie Speicher reserviert und organisiert, was für die Indizierung Muster sind optimal als andere, welche Konstrukte, in der Lage sein werden effiziente für bestimmte Anwendungen, etc.

Noch wichtiger ist, glaube ich, ist ein gutes Verständnis der Betriebssysteme, Speicherarchitekturen und Algorithmen. Wenn Sie, wie Sie Ihren Algorithmus funktioniert verstehen, warum es besser wäre, einen Algorithmus oder Datenstruktur über eine andere zu wählen (zB HashSet vs. List), und wie Ihr Code abbildet auf die Maschine, sollte es keine Rolle, welche Sprache Sie verwenden .

Das ist meine Erfahrung, wie ich lernte und lehrte mich die Programmierung, und zwar Verständnis C, dies zu Anfang der 1990er Jahre geht zurück, so kann ein bisschen antik sein, aber die Leidenschaft und der Antrieb ist wichtig:

  • Lernen Sie die niedrigen Niveau Prinzipien des Computers, wie EGA / VGA-Programmierung zu verstehen, hier ist ein Link zum Simtel Archiv auf den Leitfaden des C-Programmierer an den PC.
  • Das Verständnis, wie TSR Arbeiten
  • Laden Sie das gesamte Archiv von Bob Stouts Schnipsel , die eine große Sammlung von C-Code, der eine Sache tut nur -. Studie sie und versteht es, nicht allein das, streben die Sammlung von Schnipseln tragbar sein
  • Durchsuchen auf der Internationalen Obfuscated C-Code-Wettbewerb ( IOCCC ) online und sehen, wie die C-Code kann missbraucht werden und die intracies der Sprache verstehen. Der schlimmste Code Missbrauch ist der Gewinner! Laden Sie das Archiv und studieren.
  • Wie mich, ich liebte das berüchtigte C Tutorial des Ponzo, die half mir enorm, leider das Archiv ist sehr schwer zu finden. Wenn jemand weiß, von wo sie zu erhalten, lassen Sie einen Kommentar und ich werde diese Antwort ändern, um den Link einzufügen. Es ist eine andere, dass ich mich erinnern kann - Coronados [? Allgemein] C-Tutorial, wieder, mein Gedächtnis auf diesem ist trüb ...
  • Schauen Sie sich Dr. Dobbs Journal und C Benutzer Journal hier - ich weiß nicht, ob Sie kann sie immer noch in gedruckter Form erhalten, aber sie waren ein klassisch, kann das Gefühl erinnern, ein gedrucktes Exemplar in der Hand zu halten und Abreißen nach Hause in dem Code eingeben, um zu sehen, was passiert!
  • Schnappen Sie eine alte Kopie von Turbo C v2 die ich glaube, Sie von borland zu bekommen. com und mit 16-Bit-C-Programmierung spielt nur ein Gefühl und Chaos mit den Zeigern zu bekommen ... sicher ist es altes und alt, aber mit Zeigern spielen auf es in Ordnung ist.
  • verstehen und lernen Pointers, Link hier auf das Erbe Simtel.net - eine entscheidende Verbindung C Guru'ship in Ermangelung eines besseren Wortes zu erreichen, auch Sie werden eine Vielzahl von Downloads im Zusammenhang mit der Programmiersprache C finden - ich erinnere mich, das Simtel CD-Archiv tatsächlich die Bestellung und die Suche nach der C stuff ...

Ein paar Dinge, die Sie direkt mit in C zu tun haben, dass andere Sprachen abstrahieren von Ihnen explizite Speicherverwaltung umfasst (malloc) und direkt mit Zeigern zu tun.

Meine Freundin ist ein Semester vom Abschluss am MIT (wo sie hauptsächlich verwenden Java, Schema und Python) mit einem Grad Informatik, und sie wird zur Zeit an einem Unternehmen, deren Code-Basis arbeitet, ist in C ++. Für die ersten paar Tage hatte sie eine schwierige Zeit zu verstehen, alle Zeiger / Referenzen / etc.

Auf der anderen Seite fand ich von C ++ auf Java bewegt sich sehr einfach, weil ich nie über Pass-Referenzen-by-value vs Pass-by-reference.

verwechselt wurde

Auch in C / C ++ ist es viel mehr offensichtlich, dass Primitive sind nur die Compiler die gleichen Sätze von Bits auf unterschiedliche Weise zu behandeln, wie zu einer Sprache wie Python oder Ruby Gegensatz wo alles ist ein Objekt mit seinen eigenen eindeutigen Eigenschaften.

Eine einfache (nicht ganz realistisch) Beispiel über einige der Ratschläge zu illustrieren. Betrachten wir die scheinbar harmlose

while(true)
   for(Iterator iter = foo.iterator(); iter.hasNext();)
       bar.doSomething( iter.next() )

oder die noch höheres Niveau

while(true)
    for(Baz b: foo)
        bar.doSomething(b)

Ein mögliches Problem hierbei ist, dass jedes Mal, um das , während Schleife eines neues Objekt (der Iterator) erstellt wird. Wenn alles, was Sie über Pflege Programmierer Bequemlichkeit ist, dann ist die letztere besser auf jeden Fall. Aber wenn die Schleife effizient sein muss, oder die Maschine ist ressourcenbeschränkten dann sind Sie ziemlich viel von der Gnade der Designer Ihrer Hochsprache.

Zum Beispiel kann eine typische Beschwerde zu tun High-Performance Java ist mit der Ausführung Stopp während Mülls (wie alle, die zugeteilten Iterator-Objekte) zurückgewonnen wird. Nicht sehr gut, wenn Sie Ihre Software mit Tracking anfliegenden Raketen, Auto-Steuerung ein Passagierflugzeug, oder einfach nicht verlassen den Benutzer fragen, warum die GUI reagiert aufgeladen wird.

Eine mögliche Lösung (noch in der Hochsprache) wäre die Bequemlichkeit des Iterators zu so etwas wie

zu schwächen
Iterator iter = new Iterator();
while(true)
    for(foo.initAlreadyAllocatedIterator(iter); iter.hasNext();)
       bar.doSomething(iter.next())

Dies würde aber nur dann Sinn machen, wenn Sie eine Vorstellung über die Speicherzuordnung haben ... sonst ist es sieht aus wie eine böse API. Convenience kostet immer irgendwo, und solche Sachen auf niedrigerer Ebene zu wissen, kann Ihnen helfen, zu identifizieren und mildern, diese Kosten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top