Gestern habe ich ein v1.0-Release eines Webprojekts herausgebracht, an dem ich ungefähr 6 Wochen gearbeitet habe (also an und aus). Ich habe keine genauen Aufzeichnungen über meine Zeit gemacht, aber nach meinen Erfahrungen würde ich schätzen, dass die Hälfte der Zeit, die ich mit Programmieren verbracht habe, für das Debuggen aufgewendet wurde. Ich schätze, dass für das Debuggen gut 15 bis 20 Stunden aufgewendet werden, was für mich eine wertvolle Zeit ist, die man besser hätte verwenden können, um neuen Code zu schreiben oder das Projekt früher abzuschließen. Es hilft auch nicht besonders, dass ich in 5 Wochen ein Neuling am College sein werde.
Die Sache ist, ich fühle mich schlecht, wenn ich die ganze Zeit mit dem Debuggen verbringe. Die ganze Zeit, die ich mit dem Debuggen verbracht habe, lässt mich erkennen, dass ich während der Entwicklung meines Projekts einige ziemlich dumme Fehler gemacht habe. Fehler, deren Behebung mir verdammt viel Zeit gekostet hat.
Wie kann ich dies in Zukunft verhindern? Ich möchte nicht 50% meiner Zeit mit dem Debuggen verbringen, sondern lieber 10% mit dem Debuggen und dem Schreiben von neuem Code. Mit welchen Techniken kann ich versuchen, dieses Ziel zu erreichen?
Antworten:
Sie fragen nach dem Heiligen Gral der Softwareentwicklung, und noch hat niemand die Antwort auf diese Frage.
Entscheidend ist, dass Sie die von Ihnen gemachten Fehlertypen nachverfolgen und diese Fehler anschließend analysieren, um festzustellen, ob ein gemeinsamer Trend vorliegt. Die Ursachenanalyse ist die formale Bezeichnung für diese Art der Selbstbeobachtung, und im Internet gibt es viel Material dazu.
Profis verwenden ein Fehlerverfolgungssystem, damit sie (1) wissen, was behoben werden muss, aber auch (2) analysieren, was nachträglich behoben werden musste. Sie müssen nicht so förmlich sein - es kann für Sie in Ordnung sein, nur eine Liste in einem Notizbuch zu führen.
Design Stage Defects
Wenn Sie feststellen, dass die meisten Ihrer Fehler auf ein Missverständnis der Problemstellung zurückzuführen sind oder wenn Sie immer wieder feststellen, dass Sie den falschen Algorithmus oder Pfad für die Lösung Ihrer Probleme gewählt haben, treten Probleme in der Entwurfsphase auf.
Sie sollten sich zu Beginn des Projekts mehr Zeit nehmen und genau aufschreiben, was zu tun ist und wie es zu tun ist. Lesen Sie diese Arbeit sorgfältig durch und gehen Sie das ursprüngliche Problem noch einmal durch und stellen Sie fest, ob Sie es wirklich richtig angehen. Eine oder drei zusätzliche Stunden zu Beginn können Ihnen viele Stunden später ersparen.
Codierungsfehler
Wenn Ihr Design solide ist, Sie aber ständig gegen die Sprache kämpfen, mit der Sie programmieren, sollten Sie sich Tools besorgen, die Ihren Code analysieren und Sie frühzeitig und häufig warnen, dass Sie Fehler machen.
Wenn Sie in C programmieren, aktivieren Sie alle Compiler-Warnungen, verwenden Sie einen Semantik-Checker wie
lint
und verwenden Sie ein Tool wievalgrind
, um allgemeine Probleme im Zusammenhang mit dem dynamischen Speicher zu erkennen.Wenn Sie Perl programmieren, schalten Sie
strict
und einwarnings
und beachten Sie, was darin steht.Unabhängig davon, welche Sprache Sie verwenden, gibt es wahrscheinlich viele Tools, mit denen Sie häufig auftretende Fehler erkennen können, lange bevor Sie das Debugging-Stadium erreichen.
Integrationsstadiumsdefekte
Wenn Sie Ihren Code gemäß guter Modularitätspraktiken entwickeln, müssen Sie damit beginnen, die einzelnen Teile zusammenzukleben. Beispielsweise haben verschiedene Abschnitte Ihres Codes möglicherweise mit Benutzereingaben, Datenbankinteraktion, Datenanzeige, Algorithmen / Logik zu tun, und jeder dieser Abschnitte ist relativ unabhängig voneinander aufgebaut (dh Sie konzentrieren sich in der Regel auf den jeweiligen Abschnitt anstatt sich Gedanken über die Integration mit allem anderen zu machen).
Hier bietet sich die testgetriebene Entwicklung (TDD) an. In jedem Modul Ihres Codes können Tests durchgeführt werden, die überprüfen, ob sie gemäß ihrer Konzeption funktionieren. Diese Tests sollten entweder zuerst oder sehr früh im Prozess geschrieben werden, damit Sie eine Reihe von "Helfern" haben, um ehrlich zu bleiben. Wenn Sie damit beginnen, dass alles zusammenarbeitet und Sie feststellen, dass Sie ändern müssen, wie dieses oder jenes implementiert wird oder mit einem anderen Subsystem interagiert, können Sie auf Ihre Tests zurückgreifen, um sicherzustellen, dass das, was Sie getan haben, funktioniert Das Zusammenspiel beeinträchtigt nicht die Korrektheit des Codes.
Und so weiter...
Lernen Sie in Büchern über Software-Engineering und praktische Codierungstechniken viele verschiedene Methoden kennen, um die Entwicklung weniger chaotisch und zuverlässiger zu gestalten. Sie werden auch feststellen, dass Sie mit einer einfachen, alten Erfahrung, die Sie an der Schule für harte Schläge erworben haben, ebenfalls in Form gebracht werden.
Fast alles läuft darauf hinaus, dass sich ein wenig Zeit und Vorarbeit später im Entwicklungs- / Release-Prozess in gewaltigen Dividenden auszahlt.
Die Tatsache, dass Sie diese Probleme so früh in Ihrer Karriere bemerkt haben, spricht gut für Ihre Zukunft, und ich wünsche Ihnen viel Glück.
quelle
Unit Tests schreiben
Wenn Sie Komponententests für Ihren Code schreiben, müssen Sie über Ihre Architektur nachdenken und ermutigen, Ihren Code in kleinen, sorgfältig kontrollierten, testbaren Teilen zu schreiben. Dadurch wird der Aufwand für das Debuggen erheblich reduziert, und der geringe Umfang des durchgeführten Debugs beschränkt sich auf kleine, eng fokussierte Codeteile.
Darüber hinaus werden die von Ihnen geschriebenen Tests Ihren Code "abdecken". Sie können feststellen, wann eine Änderung, die Sie am Code vornehmen, zu Fehlern führt, da einer oder mehrere Ihrer vorhandenen Tests fehlschlagen. Dies verringert die Gesamtkomplexität Ihres Debugging-Aufwands und erhöht Ihr Vertrauen, dass der Code funktioniert.
Der Haken dabei ist natürlich, dass Ihre Zeit für das Debuggen jetzt damit verbracht wird, Tests zu schreiben. Sie müssen sie jedoch nur einmal schreiben und können nach dem Schreiben so oft wie nötig ausgeführt werden.
quelle
50% für das Debuggen (im weiteren Sinne) ist gar nicht so schlecht. Die Leute verbringen in der Regel viel mehr Zeit mit dem Entwerfen, Testen, Beheben von Fehlern, Umgestalten und Schreiben von Komponententests als mit dem Schreiben des eigentlichen Codes. Das gehört zum Job.
Und um ehrlich zu sein, ist es bei der Wartungsprogrammierung viel schlimmer - oft habe ich eine Stunde damit verbracht, herauszufinden, was genau schief geht, dann fünf Minuten, um den Code zu schreiben, um das Problem zu beheben, und dann eine halbe Stunde, um das Ganze zu testen. Das sind etwas mehr als 5% Codierung im Vergleich zu fast 95% Nicht-Codierung.
Es gibt jedoch ein paar Dinge, die Sie tun können, um die Debugging-Zeit zu verkürzen:
quelle
Mehr Planung
Es ist unvermeidlich, dass Sie ein gutes Stück Zeit mit dem Debuggen verbringen werden. 10% sind ein ziemlich ehrgeiziges Ziel. Obwohl eine der besten Möglichkeiten zur Reduzierung des Zeitaufwands für das Debuggen und Entwickeln darin besteht, mehr Zeit in der Planungsphase zu verbringen.
Dies kann von Diagrammen bis hin zu Pseudocodes auf einem Planungsblock reichen. In jedem Fall haben Sie mehr Zeit, um zu überlegen, was Sie vorhaben, anstatt diese Fehler während der Entwicklung zu begehen.
quelle
Arbeite vorsichtiger
Dies ist das Software-Äquivalent zu "zweimal schneiden":
Trotzdem werden Fehler durch nichts vollständig beseitigt. Sie müssen dies als eine Tatsache des Lebens akzeptieren. Ausgehend von diesem Sachverhalt Plan für Mängel, zB Unit Test. Verstehen Sie dies auch nicht als "für immer dauern" (aka Analyse-Lähmung). Es geht darum, ein Gleichgewicht zu finden.
quelle
Andere Antworten haben bereits das meiste abgedeckt, was ich sagen möchte, aber ich möchte Ihnen trotzdem meine (brutal ehrliche) Meinung mitteilen:
Grundsätzlich sollten Sie für nicht triviale Software-Arbeiten den überwiegenden Teil Ihrer Zeit für Wartung und Debugging aufwenden. Wenn Sie an einem ausgereiften Produktionssoftwaresystem arbeiten und weniger als 80-90% Ihrer Zeit für Wartung und Fehlerbehebung aufwenden, ist das eine gute Sache!
Nun ist die Unterscheidung zwischen "Wartung" und "Debugging" natürlich etwas subjektiv. Betrachten Sie "Bugs" nur als Probleme mit dem Code, der nach seiner Veröffentlichung gefunden wurde und von Benutzern beanstandet wurde? Oder ist es jede Kleinigkeit, die mit Ihrem Code schief geht, wenn Sie etwas hinzugefügt haben (das Sie in Ihren eigenen Testphasen vor der Veröffentlichung gefunden haben)? In einem nicht trivialen Softwaresystem (abhängig von den Verwendungsmustern) kann eines viel größer sein als das andere. Aber in jedem Fall ist dies das, was das Programmieren von etwas Größerem als einem Spielzeugprogramm "Hallo Welt" erfordert - viele, viele Wartungen und Fehlerbehebungen. Einige Leute sagen sogar so etwas wie "Von allem nach der ersten Codezeile sollte erwartet werden, dass es sich um den Wartungsmodus handelt."
TL; DR: Es hört sich für mich einfach so an, als hätten Sie ein etwas unrealistisches Bild davon, worum es bei der Programmierung von nicht trivialen Softwaresystemen geht. Die überwiegende Mehrheit der Anstrengungen besteht in der Feinabstimmung, Wartung, Überarbeitung, Behebung von Fehlern und im Allgemeinen in der Durchführung von Dingen, die - zumindest im allgemeinen Sinne - unter "Debugging" (Wartung) fallen, im Gegensatz zu völlig neuer Arbeit. neuen Code schreiben.
quelle
Es ist schwierig, bestimmte Techniken ohne genaue Angaben zu Ihren Tätigkeiten und zu den von Ihnen verwendeten Technologien anzugeben. Aber auch wirklich gute Programmierer verbringen viel Zeit mit Testen und Debuggen.
Es ist Erfahrung, guten Code ohne viele Bugs zu schreiben. Du machst Fehler, dann reparierst du sie, dann erinnerst du dich, was die Fehler waren und was du tun musstest, um sie richtig zu machen, und du machst beim nächsten Mal nicht den gleichen Fehler. Und wenn Sie noch nicht einmal auf dem College sind und bereits ernsthaft darüber nachdenken, wie Sie weniger Fehler machen können, würde ich sagen, dass Sie dem Spiel definitiv voraus sind.
quelle
CONTINUOUS INTEGRATION (CI) ist die Antwort.
Kontinuierliche Integration = Konfigurationsmanagementsystem (z. B. Git, Mercurial, SVN usw.) + CI-Tool + Unit-Tests + Rauch-Tests
Diese Formel sollte Sie dazu anregen, mehr über Continuous Integration (CI) zu lesen. Im Folgenden sind einige Ressourcen in diesem Bereich aufgeführt:
quelle
Um das Debuggen zu reduzieren, können Sie es vorab laden, indem Sie detaillierter planen. Warst du noch nicht auf dem College? Ich denke, Sie werden in Ihren mittleren bis späten College-Klassen Details des Software-Entwicklungs-Lebenszyklus behandeln, die sehr gut Ihre Torheiten beleuchten können.
Während ich versuche, meinen Arbeitgebern zu erklären, besteht die beste Möglichkeit, die Wartung des Codes und den technischen Support zu reduzieren, darin, sich die Zeit zu nehmen, um Ihren Code im Voraus umfassend zu planen.
quelle
Testgetriebene Entwicklung kann helfen, die Debugging-Zeit zu verkürzen, indem:
Auch wenn Sie TDD verwenden, haben Sie immer noch Zeiten, in denen Sie den Debugger verwenden müssen. In diesem Fall sollten Sie versuchen, einen Komponententest zu schreiben, um das Szenario zu reproduzieren, das die Debugsitzung verursacht hat. Dadurch wird sichergestellt, dass dieses Problem bei einem erneuten Auftreten schnell behoben wird, wenn der Test fehlschlägt, und der Test als Markierung für den Codebereich fungiert, der das Problem verursacht hat.
quelle
Das Debuggen ist bei der Programmierung unvermeidlich, aber der Schlüssel hier ist, ist Ihr Code einfach zu debuggen oder nicht? Wenn Sie Stunden damit verbringen müssen, einfache Fehler zu beheben, muss Ihre Codearchitektur wirklich fehlerhaft sein.
Sie sollten sich daran gewöhnen, sauberen Code zu schreiben und schlechte Angewohnheiten wie Kopieren, Einfügen von Code und Schreiben langer Methoden usw. zu beseitigen.
Außerdem sollten Sie Ihren Code von Zeit zu Zeit überarbeiten. Ich empfehle Ihnen, das Buch von Martin Fowler zu lesen: Refactoring: Verbessern des Designs von vorhandenem Code
quelle
Andere haben Tests und Codeüberprüfungen erwähnt. Beide sind äußerst nützlich, haben aber einen entscheidenden Unterschied: Wann ist die beste Zeit, um sie auszuführen? Das Testen erfolgt am besten sehr nahe am ursprünglichen Schreiben des Codes, sodass Sie sich leichter daran erinnern können, warum Sie bestimmte Dinge getan haben, und das Problem schneller finden können, wenn der Test fehlschlägt. Die Codeüberprüfung hingegen sollte etwas später durchgeführt werden. Sie möchten den Code ohne perfekte Erinnerung betrachten müssen, um nicht Details zu beschönigen, an die Sie sich erinnern, aber die Sie nicht eingefügt haben. Sie möchten Orte erkennen, an denen Ihr Code nicht klar ist. Sie möchten den kleinen zusätzlichen Aufwand, um herauszufinden, was der Code tut. Sie möchten in der Lage sein, neues Wissen, das Sie über das Problem oder die Wechselwirkungen mit anderem Code oder neuen Techniken erworben haben, anzuwenden. Grundsätzlich gilt,
All dies berührt jedoch immer noch Ihre Frage. Um weniger Zeit mit dem Debuggen zu verbringen, müssen Sie verstehen, warum Sie überhaupt debuggen mussten. Das Missverständnis des Problems, das unvollständige Wissen über Ihre Tools und Technologien und die Tatsache, dass die tatsächlichen Daten nicht mit den Beispieldaten übereinstimmen, werden sich alle auf unterschiedliche Weise manifestieren und erfordern unterschiedliche Techniken und Arten der Übung, um dies zu vermeiden in der Zukunft.
Der letzte Punkt, den ich ansprechen werde, ist Erfahrung. Es gibt keine einfache Möglichkeit, dies zu erreichen. Sie müssen nur die Zeit dafür eingeben. Wenn Sie Erfahrung sammeln, verbringen Sie weniger Zeit mit dem Debuggen, da Sie zunächst besseren Code schreiben, Probleme früher bemerken und eine bessere Intuition für die Ursache eines Problems entwickeln. Bleiben Sie dran und Sie werden dies im Laufe Ihrer Karriere stetig weiterentwickeln.
quelle
Großartige Antworten, aber niemand hat sie direkt erwähnt (obwohl die meisten dies angedeutet haben):
LESEN LESEN LESEN LESEN et at nauseam ...
Je mehr Sie wissen, desto weniger wissen Sie nicht. Ein bisschen Klischee, aber immer noch die grundlegende Wahrheit.
Nachdem Sie die obigen Tipps befolgt und die Fehler analytisch dokumentiert haben, versuchen Sie, sie zu klassifizieren, und lesen Sie dann die einschlägige Literatur.
War es eine Frage der Designentscheidung? Lesen Sie mehr über Design Patterns.
War es ein Mangel an Kenntnissen des Rahmens oder der Sprache? Machen Sie sich auf den Weg!
etc
Es gibt zwei Dinge, denen sich ein (Live-) Entwickler niemals entziehen kann: Veränderung (die einzige Konstante in der IT) und RTFMing ...
quelle
Unit-Tests und Behauptungen
Zerlegen Sie Ihren Code nach Möglichkeit in kleine Teile, die einzeln getestet werden können. Dies ist jedoch nicht immer praktisch. Einige Funktionen hängen von extrem komplizierten Eingaben ab. Einige tun etwas, was nicht einfach automatisiert überprüft werden kann, z. B. das Zeichnen von Inhalten auf dem Bildschirm. Manchmal geht es um Nichtdeterminismus usw.
Wenn Sie keine guten Komponententests schreiben können, ist es das nächstbeste, zu behaupten. Während bei Unit-Tests geprüft wird, ob Sie bei bestimmten Eingaben die richtige Antwort erhalten, wird bei Eingaben aus der realen Welt die Richtigkeit von Zwischenschritten überprüft. Wenn Ihr Code Fehler aufweist, wird er schnell fehlschlagen, nahe an der Problemwurzel und mit einer eindeutigen Fehlermeldung, und nicht weit entfernt von dem Problem mit einer mehrdeutigen Fehlermeldung. Darüber hinaus werden Dokumentannahmen bestätigt und der Code besser lesbar gemacht.
quelle
Wenn Sie ein Projekt starten, wie viele alternative Ansätze identifizieren Sie?
Haben Sie zwei bis vier verschiedene Ansätze mit Vor- und Nachteilen für jeden? Treffen Sie dann eine begründete Auswahl unter ihnen?
Wägen Sie dann, was am wichtigsten ist, die Einfachheit als sehr wichtig ab?
Der Grund, den ich frage, ist meiner Erfahrung nach, dass das Codevolumen und damit die Anzahl der Fehler (ganz zu schweigen von der Leistung) zwischen den verschiedenen Entwurfsansätzen um mehr als eine Größenordnung variieren kann. Ich sehe sehr erfahrene Leute, die ihre Arbeit mit nicht mehr Code als nötig erledigen.
Sie sind voll und ganz kompetent und kennen alle Datenstrukturalgorithmen, Funktionen objektorientierter Sprachen usw., aber ihr Code sieht so aus, als ob sie das nicht tun , weil sie diese Dinge sparsam oder gar nicht verwenden, wenn das Problem auftritt benötigen sie nicht.
quelle
Jedes Mal, wenn Sie einen Fehler beheben, möchten Sie vermeiden, den gleichen Fehler erneut zu machen. Dazu können Sie Folgendes tun:
Schreiben Sie es in ein Fehlerprotokoll , das Folgendes enthält:
Nehmen Sie einen Styleguide an, um den von Ihnen geschriebenen Codestil zu normalisieren
Integrieren Sie sichere Codierungsregeln in Ihren Codeüberprüfungsprozess
Visualisieren Sie den Kontrollfluss und die Daten
Verweise
Eine empirische Studie über die Auswirkungen von PSP auf einzelne Ingenieure (pdf)
Google CPP Style Guide
Bekennende Niederlage auf K & R in LCTHW - Zed A. Shaw
IDE-Plug-Ins - Eine Möglichkeit zum Testen der Sicherheit zur Automatisierung der Codeüberprüfung | TCS Cyber Security Community
Regelsatz für Sicherheitsregeln für verwalteten Code
Sichere Codierung in C ++ 11 und C ++ 14
Visualisieren Sie die Java-Codeausführung
SPARQL Visualisierung
WWW2012 Tutorial Visualisierung von SPARQL-Abfragen
quelle