Hilft ein geeigneter Algorithmus wirklich, die Qualität und letztendlich die Effizienz eines Programms zu verbessern?
Können wir ohne den Algorithmus immer noch ein Programm von guter Qualität produzieren?
Ist ein geeigneter Algorithmus ein MUSS in der modernen Programmierung?
algorithms
Jervis
quelle
quelle
Antworten:
Ich denke, diese Frage wirft eine historische Perspektive auf.
Zurück in den "alten Tagen" (von denen ich kein persönlicher Zeuge bin, dies ist also nur meine Rekonstruktion dieser Ära - zögern Sie nicht, mich zu korrigieren, wenn Sie Dinge anders erlebt haben). Also musste alles, was die Leute damals schrieben, sehr effizient sein. Daher mussten sie viel darüber nachdenken und nachforschen, um die besten Algorithmen zu erfinden, um die erforderliche Raum-Zeit-Leistung zu erzielen, um die Aufgabe zu erledigen. Ein weiterer Grund dafür war, dass die Entwickler hauptsächlich an der so genannten Infrastruktur arbeiteten : Betriebssysteme, Protokollstacks, Compiler, Gerätetreiber, Editoren usw. All dies wird von vielen Menschen genutzt, sodass die Leistung wirklich einen Unterschied macht .
Heutzutage haben wir die Qual der unglaublichen Hardware mit Multicore-Prozessoren und Gigabyte Arbeitsspeicher in einem einfachen Laptop (zum Teufel sogar in einem Mobiltelefon). Dies bedeutet natürlich, dass in vielen Fällen die Leistung - also der Algorithmus - nicht mehr das zentrale Thema ist und es wichtiger ist, eine schnelle Lösung bereitzustellen, als eine schnelle Lösung. OTOH, wir haben jede Menge Frameworks, die uns helfen, Probleme zu lösen und gleichzeitig eine große Anzahl von Algorithmen zu kapseln . Selbst wenn wir nicht über Algorithmen nachdenken, verwenden wir möglicherweise viele davon im Hintergrund.
Es gibt jedoch noch Bereiche, in denen es auf die Leistung ankommt. In diesen Bereichen müssen Sie noch viel über Ihre Algorithmen nachdenken, bevor Sie Code schreiben. Der Grund ist, dass der Algorithmus das Zentrum des Entwurfs ist und viele Datenstrukturen und Beziehungen im umgebenden Code bestimmt. Und wenn Sie zu spät feststellen, dass Ihr Algorithmus nicht gut skaliert (z. B. 0 (n 3 )), hat er beim Testen von 10 Elementen gut und schnell ausgesehen, aber im echten Leben werden Sie Millionen haben), ist er sehr gut Es ist schwierig, fehleranfällig und zeitaufwendig, es im Produktionscode zu ersetzen. Und Mikrooptimierungen helfen Ihnen nicht, wenn der grundlegende Algorithmus nicht für den Job geeignet ist.
quelle
Um nur auf etwas hinzuweisen:
Ein Algorithmus ist selbst eine allgemeine schrittweise Lösung Ihres Problems. Wenn Sie das Problem gelöst haben, haben Sie tatsächlich einen Algorithmus verwendet.
Der wichtigste Punkt hierbei ist, dass Sie Algorithmen verwenden müssen, um das Problem auf die eine oder andere Weise zu lösen. Meistens ist es besser, über Ihr Problem nachzudenken, bevor Sie mit dem Codieren beginnen - diese Phase wird oft als Design bezeichnet. Aber wie viel und auf welche Weise Sie dies tun werden, hängt von Ihnen ab.
Außerdem sollten Sie das Konzept des Algorithmus nicht mit Flussdiagrammen mischen (ich vermute, dass dies hier vor sich geht). Flussdiagramme sind nur eine grafische Darstellung, die verwendet werden kann und früher zur Veranschaulichung eines Algorithmus verwendet wurde. Es ist heutzutage ziemlich veraltet.
BEARBEITEN:
Es gibt in der Tat viele Möglichkeiten, einen Algorithmus darzustellen, und der Programmiersprachencode selbst ist einer davon. Oft ist es jedoch viel besser oder einfacher, nicht das gesamte Problem auf einmal zu lösen, sondern nur einen Überblick zu geben und dann die Lücken zu füllen, während Sie gehen.
Mein persönlicher Favorit hier ist Pseudocode, und nur um einen allgemeinen abstrakten Überblick über den fraglichen Algorithmus zu geben - es ist lächerlich, mit Pseudocode auf Details einzugehen , dafür ist echter Code da.
Für die Gliederung kann jedoch echter Code verwendet werden. Zum Beispiel entwerfen TDD-Leute den Algorithmus gerne so, wie sie ihn codieren, und da sie ihn auch nicht auf einmal lösen können, entwerfen sie einen Umriss der Programmausführung in echtem Code und verwenden Scheinobjekte (oder Funktionen, Methoden). .) als Lücken, die später ausgefüllt werden sollen.
UML-Aktivitätsdiagramme scheinen eine moderne Inkarnation von Flussdiagrammen alten Stils mit zusätzlicher Notation für neue Elemente wie Polymorphismus und Multithreading zu sein. Ich kann nicht wirklich sagen, wie nützlich das ist, da ich sie nicht wirklich oft benutzt habe - ich erwähne es nur der Vollständigkeit halber.
Wenn Sie Ihren Algorithmus auf das Umschalten zwischen Zuständen stützen, ist ein Zustandsdiagramm sehr hilfreich.
Im Allgemeinen ist jedes Mittel, das Sie brauchen, um die Idee hinter einem bestimmten Algorithmus zu skizzieren, ein guter Weg.
quelle
Eine gute Analogie ist, dass Sie ein Rezept kennen müssen, bevor Sie mit dem Kochen beginnen. Ok, Sie können es jederzeit anpassen, aber Sie müssen immer noch wissen, was Sie machen möchten, bevor Sie anfangen. Wenn ich einen Lammeintopf machen will, mache ich ganz andere Dinge als wenn ich einen Laib Brot backen will.
quelle
Code implementiert Algorithmen. Der Versuch, Code zu schreiben, ohne den Algorithmus entworfen zu haben, ist wie der Versuch, ein Haus zu malen, bevor die Wände gebaut werden. Algorithmen sind seit Beginn der Programmierung ein "MUSS".
quelle
Fließendes Sprechen trägt zur Verbesserung von Qualität und Produktivität bei. Und das Lösen kleiner algorithmischer Probleme ist weitaus nützlicher, als dass Sie dieselben MVC-Aufgaben 100 Mal wiederholen müssen.
Es gibt aber auch andere Möglichkeiten, um flüssig zu werden.
Wird der Algorithmus in der modernen Programmierung zum MUSS?
Es ist bereits ein "Muss", es sei denn, Sie sind ein "PHP-Ninja", der "coole Codez" schreibt. Alle "besten" Unternehmen (Google, Amazon usw.) testen Ihre algorithmischen Erfahrungen im Interview, und ich kann mir vorstellen, dass sie dies nicht ohne Grund tun würden.
Wenn Sie jedoch zum ursprünglichen Punkt zurückkehren, sollten Sie sich ständig selbst herausfordern, wenn Sie sich verbessern möchten. Und da normale Jobs (alias "Jetzt CRUD-Manager für 100 weitere Objekte schreiben") nicht immer eine gute Herausforderung darstellen, kompensieren Algorithmen dies.
quelle
Ich würde sagen, Sie benötigen mindestens eine erste Vorstellung von einem Algorithmus, bevor Sie mit dem Codieren beginnen. Sie werden Ihre Idee wahrscheinlich überarbeiten, während Sie auf der Grundlage von Datenstrukturen usw. codieren.
Sie können den Code später möglicherweise erneut überarbeiten, wenn die Profilerstellung auf ein Leistungsproblem in diesem Bereich hinweist.
quelle
Der Grund ist, dass Sie Fehler schneller beheben können, bevor Sie den fehlerhaften Code geschrieben haben.
Genauer gesagt gibt es routinemäßig gemessene Produktivitätsunterschiede von 10 zu 1 zwischen verschiedenen Programmierern. Wenn Sie sich die Programmierer ansehen, die die 10-fache Produktivität aufweisen, verbringen sie den kleinsten Teil ihrer Zeit mit dem eigentlichen Programmieren . Die Zeit zum Eingeben von Code sollte nicht der Engpass sein. Stattdessen verbringen sie einen größeren Teil ihrer Zeit damit, sicherzustellen, dass die Anforderungen klar definiert sind, zu planen, zu testen usw.
Umgekehrt müssen Programmierer, die ohne Pause in das Codieren eintauchen, den Code zwangsläufig immer wieder schreiben, da sie auf völlig vorhersehbare Probleme stoßen und das Endergebnis weniger wartbar und fehlerhafter ist. (Übrigens wussten Sie, dass sich durchschnittlich 80% der Ausgaben für die Softwareentwicklung in der Wartungsphase befinden? Dinge wartbar zu machen, ist wichtig. Vieles.)
quelle
Generell Algorithmen und Datenstrukturen zuerst, Code später. Aber es hängt sehr von der Programmierdomäne ab. Früher habe ich viel mit angewandter Mathematik gearbeitet und mir das damals vorherrschende Wasserfallmodell angesehen. Dies lag daran, dass die niedrigen bis mittleren Algorithmen selten als selbstverständlich angesehen werden konnten. Entwerfen Sie eine große Struktur um das Vorhandensein von ungeschriebenen Subsystemen und stellen Sie später im Spiel fest, dass die Mathematik für eines dieser entscheidenden Subsysteme nicht funktioniert (instabil oder was auch immer). Also habe ich immer zuerst über die herausforderndsten Subsysteme nachgedacht, und wenn es einen Grund für Zweifel gab, habe ich diese zuerst geschrieben und in der Einheit getestet. Für einige Problembereiche können Sie jedoch ohne viel Planung voranschreiten.
quelle
Entwerfen Sie einen Algorithmus in Abschnitten, teilen Sie diese Abschnitte dann auf und codieren Sie jeden von ihnen einzeln. Auf diese Weise können Sie beide Sichtweisen mischen:
quelle
Für mich ist es so ziemlich alles Code. Ich denke, das gilt für die meisten hochproduktiven Programmierer. Ich kann Code so einfach schreiben, wie ich Text schreibe.
Nach Möglichkeit versuche ich, Anforderungen als ausführbare Tests (Code) zu erfassen. Design ist nur High-Level-Codierung. Es ist schneller und präziser, das Design in der Zielsprache zu erfassen, als es in einer anderen Form zu erfassen und dann zu übersetzen.
Ich habe festgestellt, dass die meisten Benutzer die Textanforderungen nicht effektiv überprüfen können. Bei sequenziellen Anwendungsfällen ist dies in Ordnung, die Anwendungsfälle können jedoch nicht alle Aspekte der Benutzeroberfläche erfassen. Bei weitem das Beste ist, einen ersten Schnitt bei der Implementierung zu machen, es den Benutzern zu überlassen, ihre Kommentare abzurufen und den Code entsprechend zu ändern.
quelle
Wenn Sie sich hinsetzen und mit dem Codieren beginnen, denken Sie an einen Algorithmus, ob er nun "entworfen" ist oder nicht.
Wenn Sie sich hinsetzen und mit dem Codieren beginnen, ohne den vollständigen Algorithmus zu berücksichtigen, haben Sie folgende Möglichkeiten:
1) Schlüssel zufällig zerdrücken. Dies wird wahrscheinlich einen Compilerfehler erzeugen
2) kompilierbaren Code schreiben, der wahrscheinlich alles außer dem tut, was Sie wollen
3) Schreiben Sie Code, um kleine Teile des Problems zu lösen, und bauen Sie auf diesen auf, wenn Sie aggregiert vorgehen, aber denken Sie nicht wirklich voraus - schließlich ist das Problem gelöst -, aber der Code ist nicht sehr effizient Möglichkeit des Zurückverfolgens und Verschwenden von Zeit auf dem Weg
Daher programmieren die Leute normalerweise mit einem Algorithmus im Kopf. Es kann auf Papier oder einem anderen Medium ausgearbeitet oder begründet worden sein.
Es kann eine gute Disziplin sein, über Ihren Angriff auf ein Problem außerhalb der Tastatur nachzudenken, insbesondere in Ihren früheren Tagen als Programmierer. Wie andere Antworten festgestellt haben, können Sie mit zunehmender Erfahrung einige überschaubare Problemblöcke besser "on the fly" codieren. Bei schwierigen oder großen Problemen ist es jedoch hilfreich, nicht auf der Tastatur zu denken und zu entwerfen: Wenn Sie sich mit Code beschäftigen, denken Sie mit größerer Wahrscheinlichkeit an Konstrukte der Sprache und wie Sie sich der unmittelbarsten Aufgabe in der Sprache nähern Problem. Während das Nachdenken über das Problem mit beispielsweise Stift und Papier Sie mehr vom Sprachaspekt des Codes befreit und Sie auf einer abstrakteren Ebene denken lässt.
quelle
Sie müssen aufhören, Software-Konstruktion als etwas zu betrachten, das sich grundlegend aus der Konstruktion von etwas anderem von Wert ergibt. Es ist nicht. Also, wie alles andere, ist immer ein gut durchdachter Plan oder Entwurf, wie auch immer, erforderlich.
Hilft ein geeigneter Bauplan / eine entsprechende Skizze beim effizienten Bau eines Qualitätshauses?
Können Sie ein Haus von guter Qualität ohne einen geeigneten Bauplan effizient bauen? Nach dem Infinite Monkey Theorem , wahrscheinlich, ja (genau wie eine Million Affen, die für die Ewigkeit nach dem Zufallsprinzip tippen, irgendwann die vollständigen Werke von Shakespeare tippen werden).
Wenn Sie kein Code-Affe sein möchten und sicherstellen möchten, dass Sie keine Software liefern, die wie Scheiße aussieht und funktioniert, dann ist dies ein Muss. Jedes Projekt, das ich retten musste (weil der Code wie eine bleibende Scheiße aussah), hat ausnahmslos mit einer negativen Antwort auf diese Frage begonnen.
In der Tat war die moderne Programmierung die Abkehr vom Cowboy-Programmiersoftware-Ingenieur, bei dem eine Art von Planung ein Muss war.
Selbst wenn Sie über eine Bibliothek mit Algorithmen und Datenstrukturen verfügen (z. B. Boost in C ++ oder die Java-Objektgruppenbibliothek), müssen Sie wissen, wie das Zeug funktioniert, um es angemessen zu verwenden und in vernünftige, höhere Klassen zu unterteilen. Level-Algorithmen.
quelle
Es ist nicht besser Es ist besser, nichts zu "entwerfen". Das ist für Leute, die keine Programme schreiben. Sie wissen, die Menschen mit der realen Erfahrung des Problems zur Hand. Wenn Sie Mathematiker, Ingenieur oder Logistiker sind, müssen Sie den Prozess woanders bearbeiten. Das ist aber nicht "Programmieren".
Stellen Sie zuerst eine Art Test und Benchmark auf.
Dann schreib etwas, irgendetwas. Refactor-Rewrite-Loop ausführen, bis die Zeit abgelaufen ist oder sich nicht mehr verbessern lässt.
Während viele zu glauben scheinen, man könne Dinge mit einem Computer erledigen, ohne irgendetwas am Computer zu tun, denke ich, dass dies einer der häufigsten Mythen da draußen ist. Architektur-Astronautismen.
Sie können Ihr Algo auch nicht optimieren, bevor es geschrieben wurde.
IOW, "bleib nah am Metall".
quelle