Wie verbringe ich weniger Zeit mit dem Debuggen? [geschlossen]

15

Nach der Pareto-Regel verbringt ein Programmierer nur 20% seiner Zeit mit wirklich nützlichen Dingen.

Ich verbringe 80% meiner Zeit mit dem Debuggen und dem Reparieren kleiner Dinge, um alles zum Laufen zu bringen.

Gibt es eine Möglichkeit, weniger Zeit mit dem Debuggen zu verbringen?

uhbif19
quelle
9
Ich bin mir nicht sicher, wie ich das Pareto-Prinzip interpretieren würde.
c_maker
6
<meme> Sehen Sie sich TDD an. </ meme>
StuperUser
1
Was tun Sie eigentlich tun , wenn das Debuggen?
3
Sie müssen mehr Zeit auf Ihre Liebe zum Detail verbringen
1
Es gibt viel zu gewinnen, wenn Sie ab und zu einfach Ihren Code durchsehen. Schreiben Sie noch besser Kommentare, wenn Sie den Drang verspüren, damit Sie später leichter Fehler bemerken.
Joey Adams

Antworten:

5

Code in Agda oder Coq . Sobald Ihr Code kompiliert ist, funktioniert er. Wenn es zu hardcore ist, wählen Sie eine Sprache mit einem schwächeren Typsystem, z. B. Haskell oder F #.

In den meisten Fällen sind Sie jedoch produktiver, wenn Sie 20% Ihrer Zeit für das Codieren und 80% für das Testen und Debuggen aufwenden. 100% einer Woche sind viel mehr als 20% einer Stunde. Wenn das Debuggen das ist, was Sie brauchen, um Dinge zu erledigen, dann ist das Debuggen keine Zeitverschwendung und Sie sollten sich nicht die Mühe machen, diesen Anteil zu "verbessern".

SK-Logik
quelle
1
Nur weil etwas läuft, heißt das nicht, dass es keine Bugs hat. Fehler sind oft das Ergebnis von Code, der das Falsche tut.
HLGEM
3
@HLGEM, bevor du abstimmst, solltest du mehr über Agda und Coq lesen. Wenn Ihr Code kompiliert, wird es garantiert und bewies genau das zu tun , was seine Spezifikation sagt. Natürlich kann es auch einen Fehler in der Spezifikation geben, aber ich würde das Beheben solcher Probleme nicht als "Debugging" bezeichnen.
SK-logic
2
@HLGEM, dann ist Ihre Vorstellung von "Debugging" ziemlich kreativ und weit vom Mainstream entfernt. Und bei diesem Ansatz wäre das Verhältnis zwischen Codierung und "Debugging" bei weitem nicht 20/80. Erläutern Sie also bitte Ihre Ablehnung.
SK-logic
1
@HLGEM, es war nicht in einer Liste der OP-Anforderungen. Es ist nicht bekannt, wie viele Entwickler es gibt, wer verantwortlich ist usw. Die einzige Frage war, "wie das Verhältnis 20/80 einzuschätzen ist", und die Verwendung einer statisch verifizierten Sprache ist eindeutig die naheliegendste Antwort darauf. Aber wie ich bereits sagte, ist diese Antwort nur in sehr seltenen Fällen anwendbar, und im Allgemeinen ist es eine viel bessere Option, sich an die 20/80-Regel zu halten.
SK-logic
1
@ uhbif19 Knuth meinte das humorvoll zu sagen. Weißt du was er wirklich meinte?
Phil
44

Unit-Test.

Nachdem ich angefangen hatte, Komponententests durchzuführen, stellte ich fest, dass der von mir geschriebene Code besser strukturiert war. Es war dann einfacher, Fehler zu vermeiden und zu erkennen. Ich habe weniger Zeit für das Debuggen aufgewendet, aber mehr Zeit für das Schreiben von Unit-Tests.

Ich denke auch, dass die in Unit-Tests investierte Zeit eine bessere Rendite als das Debuggen hat. Nach einer Debugsitzung habe ich den Code gerade korrigiert. Der gleiche Fehler kann Wochen später auftreten und ich muss erneut debuggen. Wenn ich einen Komponententest schreibe, wird der Fehler als Komponententest dokumentiert und fungiert später als Regressionstest. Wenn der Fehler erneut auftritt, zeigen mir die Unit-Tests dies.

Theo Lenndorff
quelle
Ich benutze Unit-Tests und stimme Ihnen voll und ganz zu. Aber ich kann nicht alles testen.
uhbif19
5
Sicher kannst du. Nun, nicht alles , aber alles, was zählt. Durch die Verwendung von Interfaces, Dependency Injection, Faking und Mocking Klassen / Methoden können Sie Tests für nahezu Ihren gesamten Code schreiben.
Fredrik
8
@Fredrik, Sie können nicht einmal den a + bCode in einer Einheit richtig testen (es sei denn, Ihr Test deckt den gesamten Bereich Ihres arithmetischen Datentyps ab).
SK-logic
"Nach einer Debugsitzung habe ich den Code gerade korrigiert." -- Ja wirklich? Ich denke, nach einer Debugging-Sitzung habe ich nur mehr Bugs eingeführt - ich weiß nur nicht, wo sie sind.
B Seven
35
  • Unit-Test, damit Sie wissen, ob Ihr Code überhaupt funktioniert.
  • Zumindest ein gewisses Maß an Upfront-Design, damit Sie wissen, was Sie codieren.
  • Codeüberprüfungen, da zwei Köpfe besser als einer sind und vier Augen besser als zwei. Ganz zu schweigen davon, dass selbst der Versuch, Ihren Code jemand anderem zu erklären, viele Probleme aufzeigt.
  • Versionskontrolle, damit Sie schnell herausfinden können, welche Änderungen den Fehler verursacht haben.
  • Refactoring, damit Ihr Code nicht zu einem fürchterlichen, unverständlichen Durcheinander wird.
  • Lesen Sie "Clean Code" von Robert C. Martin und tun Sie, was er Ihnen sagt. Sie werden von den Ergebnissen begeistert sein.
Dima
quelle
5
Genau - keine einzelne Übung (z. B. Komponententest) wird eine Größenordnung verbessern, aber eine Kombination von Übungen kann dies. Mit anderen Worten ... es gibt keine Silberkugel.
Michael
Ich würde TDD hinzufügen (wo möglich).
Tom
1
Ich würde den sauberen Code sortieren und zuerst umgestalten. Unit-Tests eignen sich gut, um Fehler frühzeitig zu finden und zu beheben, sie verringern jedoch nicht deren Anzahl (sie verkürzen die Zeit ein wenig, da Sie Fehler beheben, wenn Sie alles neu im Speicher haben, aber immer noch). Das Schreiben von sauberem Code verringert andererseits die tatsächliche Anzahl von Fehlern.
Jan Hudec
1
@ JanHudec Refactoring + sauberer Code + Tests = TDD
Tom
1
@Tom: Ja, aber die verschiedenen Teile davon haben unterschiedliche Auswirkungen. Wenn Sie lernen, sauberen Code zu schreiben, können Sie die Debug-Zeit ohne Tests verkürzen. Es gibt Tests, mit denen Sie Module testen können, bevor ihre Verwendung implementiert wird, und mit denen Sie überprüfen können, ob Sie das Verhalten beim Refactor nicht geändert haben. Dies ist erforderlich, um alten Code zu bereinigen.
Jan Hudec
8

Unit-Tests helfen, denn wenn Sie Bugs einführen, brechen diese hoffentlich vor Ihrem Produktionscode. Gut geschriebene Unit-Tests zeigen Ihnen auch genau, was gebrochen ist.

Das wird Ihnen den größten Teil des Weges erleichtern, aber für 99,999% der Projekte müssen Sie immer noch die Dinge von Zeit zu Zeit debuggen. Das Beste, was ich hier tun kann, ist, 4 Dinge zu tun:

  1. Verwenden Sie nach Möglichkeit unveränderliche Typen. Wenn ein Wert falsch ist, wissen Sie sofort genau, wo Sie suchen müssen (wo er erstellt wird).
  2. Erzwingen Sie Invarianten im Code. Wenn Sie wissen, dass ein Wert definitiv nicht zulässig ist, überprüfen Sie ihn und lösen Sie eine Ausnahme in den Einstiegspunkten für Methoden und Konstruktoren aus. Wenn Sie dies mit unveränderlichen Typen kombinieren, können Sie auch bestimmte Annahmen darüber treffen, was gültig ist oder nicht.
  3. Stellen Sie sicher, dass Sie über eine ausreichende Protokollierung verfügen. Melden Sie sich frühzeitig an, und Sie erhalten viele wichtige Informationen darüber, wann Probleme auftreten. AOP funktioniert hier wirklich gut. Nachträgliches Protokollieren ist in der Regel ein wenig Müll - holen Sie es sich frühzeitig im Rahmen des Projektaufbaus.
  4. Wenn Ihre Codebasis groß / komplex genug ist, vermeiden Sie die Verwendung von Primitiven - z. B. haben Sie einen Typ namens "Age", anstatt nur einen Int. Zunächst scheint es ein bisschen sinnlos zu sein, aber in der Lage zu sein, alle Verwendungen von etwas in einem Augenblick aufzuspüren, ist ein großer Gewinn beim Debuggen.
FinnNk
quelle
6

Meine 80% sind debuggen. Ich behebe einfache Fehler und versuche, alles zum Laufen zu bringen.

Beginnen Sie mit dem Schreiben von Komponententests und versuchen Sie, eine möglichst hohe Abdeckung zu erzielen. Jemand erwähnte TDD, aber ich würde mit BDD gehen .

Am Ende werden Sie höchstwahrscheinlich 80% für das Debuggen komplexer Fehler ausgeben.

BЈовић
quelle
6

Wie verbringe ich weniger Zeit mit dem Debuggen? Schreiben Sie weniger Code.

Im Ernst, solange Sie Code schreiben, müssen Sie ihn debuggen. Unit-Tests usw. helfen immens, aber denken Sie nicht, dass Sie jemals die Notwendigkeit dafür ganz aufheben werden.

Daniel Roseman
quelle
4

Verstehen Sie das Was und Warum, bevor Sie mit dem Schreiben von Code beginnen. Dann wenden Sie konsequent eine Methodik an. Welche Methodik Sie wählen, ist bei weitem nicht so wichtig wie die konsequente wiederholte Anwendung der Methodik. Wenn Sie konstant gute Ergebnisse erzielen möchten, müssen Sie konstant gute Arbeit leisten, und eine "Methode für Ihren Wahnsinn" ist der erste Schritt, um diese Ergebnisse zu erzielen. Wenn Sie Probleme identifizieren, können Sie Ihre Methodik nach Bedarf anpassen und im Laufe der Zeit Ihren Entwicklungsprozess verbessern, und hoffentlich weniger Bugs und mehr neue, aussagekräftige Entwicklungen.

cdkMoose
quelle
3

Lesen Sie Ihren Code sorgfältig durch, bevor Sie ihn kompilieren. Eine sehr sorgfältige Lektüre für Syntax und Funktionalität. Es kann überraschend informativ sein und ist auch ein guter Indikator, wenn ein Codeabschnitt zu kompliziert ist.

anon
quelle
Ich bin völlig einverstanden. Wenn Sie Ihren Code unmittelbar nach dem Schreiben lesen, können sehr schnell einige offensichtliche Fehler aufgedeckt werden, z. B. Tippfehler beim Kopieren und Einfügen (die manchmal schwer zu finden sind).
Jirkamat
3

Die meisten Antworten scheinen sich darauf zu konzentrieren, wie Sie die Anzahl der zu debuggenden Probleme reduzieren können, und das ist wertvoll. Das Debuggen ist jedoch immer erforderlich, daher ist es hilfreich, Möglichkeiten zu prüfen, wie das Debuggen beschleunigt werden kann.

  • Wissen, wie Sie Ihre Versionskontrollsoftware verwenden.

    • Mithilfe von Zweigen können Sie Entwicklungsbereiche herausfiltern und feststellen, in welchem ​​Entwicklungsbereich der Fehler auftritt und in welchem ​​nicht.
    • Wenn Sie ein anderes VCS verwenden, in dem keine Halbierung integriert ist, suchen Sie nach einem Tool, das wie git bisect funktioniert, aber für Ihr VCS (ich weiß, dass es dieses für SVN und SVN gibt) sollte für andere VCSs nicht zu schwer zu erstellen sein). Auf diese Weise können Sie sich auf die Codeänderung beschränken, die den Fehler verursacht hat, und wissen, wo Sie auf Ihren Debugger verweisen müssen. Dieser Teilungsprozess ist schneller, wenn Sie Tests auf den Fehler durchgeführt haben und wissen, welches Commit die anstößige Änderung enthält, wenn Sie atomare Commits ausführen.
  • Verbessern Sie Ihr Verständnis der von Ihnen verwendeten Programmiersprache.

    • Lesen Sie Bücher, Blogs und Code über die Programmiersprache.
    • Stellen Sie jedes Mal, wenn Sie einen Fehler beheben, sicher, dass Sie genau verstehen, warum der Code nicht funktioniert hat und warum Ihr Fix funktioniert. Mit der Zeit werden Sie viele Fallstricke in Ihrer Sprache lernen, die Ihnen helfen, ihre Probleme zu vermeiden und die Symptome von ihnen zu erkennen, falls sie erneut auftreten.
  • Sei logisch

    • Ändern Sie sonst nicht mehr als eine Sache auf einmal, wenn sich das Verhalten ändert, wissen Sie nicht, welche Änderung die Änderung des Verhaltens verursacht hat.
    • Überprüfen Sie Ihre Annahmen.
Stephen Paulger
quelle
2

Das Hinzufügen zu den Kommentaren für Unit Testing ist aber nur dann wirklich gut, wenn Ihr Code zur Unterstützung separiert wurde (zB MVC). Wenn Sie MVC (oder ähnliches) (Legacy-Projekt) nicht implementieren können, funktionieren Unit-Tests für Ihre Benutzeroberfläche überhaupt nicht. Ich würde dann automatisierte UI-Tests (Microsoft Coded UI Tests, WaitN) hinzufügen, da dies die Fehler in diesem Teil Ihres Codes verringert.

Ich würde auch empfehlen, statische Analyse-Tools (z. B. FxCop / Microsoft Code Analysis, Resharper, JustCode für die MS-Welt) auszuführen. Diese können alle Arten von allgemeinen Codierungsproblemen finden, die die albernen Debugging-Aufgaben reduzieren und sich mehr auf das Debuggen von Geschäftslogik konzentrieren können.

Scott Wylie
quelle
2

Lass es funktionieren, dann mach es schnell, dann mach es hübsch. Die meisten Fehler stammen aus frühen Optimierungen oder Re-Factoring bei Codezeilen, die völlig in Ordnung waren. Wenn Sie sich für die Objektorientierung entscheiden, wiederholen Sie sich nicht, halten Sie es einfach und überprüfen Sie die Wertebereiche immer auf ihre Richtigkeit, insbesondere, wenn Ihre Methoden bei Einschränkungen noch funktionieren. Es wird Ihnen nicht helfen, weniger Fehler zu machen, aber es wird Ihnen wahrscheinlich helfen, Fehler schneller zu erkennen, und daher dauert das Debuggen weniger Zeit.

Kibotu
quelle
1
Ihre Behauptung "Die meisten Fehler kommen von ..." klingt gut, aber haben Sie Beweise, die dies belegen? Ich denke, dass es genauso überzeugend klingt, wenn ich sage, dass "die meisten Fehler von schlecht spezifizierten Anforderungen oder dem Fehlen eines klaren Designs herrühren". Sie sollten der Recherche einen Link oder ein Zitat hinzufügen, das Ihre Aussage unterstützt.
Caleb
2

Ich habe in letzter Zeit viel über dieses Problem nachgedacht. Die einfache Antwort lautet: Lesen Sie Don Normans Das Design alltäglicher Dinge. Schreiben Sie Code, als würden Sie ein Produkt entwerfen.

Gutes Design minimiert Fehler. Das heißt, ein paar Dinge, von denen die meisten Sie bereits tun (obwohl Sie möglicherweise nicht genau wissen, warum ).

-Name funktioniert intuitiv. Dies ist formal als Erschwinglichkeit bekannt. Das heißt, ein Knopf kann gedrückt werden, ein Hebel kann geschaltet werden, ein Griff kann gezogen werden usw.

- Mach es dir schwer, schlechten Code zu schreiben. Suchen Sie lieber früher als später nach schlechten Eingaben und werfen Sie Fehler, verwenden Sie gegebenenfalls ungarische Apps usw. Diese werden als Sperrfunktionen bezeichnet.

-Verwenden Sie gegebenenfalls die Abstraktion. Das Kurzzeitgedächtnis ist schwach.

-Dokumentation ist natürlich wichtig, aber am wenigsten effektiv, um sicherzustellen, dass der Code ordnungsgemäß verwendet wird. Kurz gesagt, gut gestaltete Produkte benötigen keine Dokumentation. (Der offensichtlichste Weg, dies zu sehen, sind schlechte Beispiele: Türen mit Griffen, die man schieben sollte.)

-Einheitentests. Diese verhindern Fehler nicht wirklich, sondern machen deutlich, wo sich die Fehler befinden, und sorgen für geistige Gesundheit.

Ich bin mir sicher, dass ich noch viel mehr Prinzipien vermisse, aber der springende Punkt ist, lesen Sie mehr über das Entwerfen für Fehler.

Ceasar Bautista
quelle
1

Die beste Möglichkeit, das Debugging zu verringern, besteht darin, sich beim Codieren zu konzentrieren und zu verlangsamen. Dies zwingt Sie dazu, Fehler zu sehen, die Sie möglicherweise gemacht haben!

Dynamisch
quelle
1

Obwohl ich den oben vorgeschlagenen Komponententest voll und ganz unterstütze, ist TDD oder BDD von großem Wert, da Sie zuerst über das Problem und die Lösung nachdenken müssen.

Aber für mich persönlich ist es ein Wunder, wenn ich mir ein paar Minuten Zeit nehme, um ruhig zu sitzen und über das Problem nachzudenken und wie ich mit jedem Ansatz und den Vor- und Nachteilen umzugehen habe.

Manchmal hilft ein schnelles Kritzeln auf einem Blatt Papier, die größeren zusammenhängenden Teile des Puzzles zu erkennen.

Ich schreibe den schlechtesten Code, wenn ich nur mit dem Kopf voran eintauche und auf die Tastatur klopfe. Ein bisschen Nachdenken und Kontemplation macht einen großen Unterschied.

PS. Ich meine 5 vielleicht 10 Minuten, nicht Stunden, um eine riesige Spezifikation zu schreiben.

SetiSeeker
quelle
1

Einige gute Antworten schon, nur ein paar mehr als das, was andere gesagt haben.

Lerne aus deinen Fehlern. Machen Sie nicht immer wieder dieselben.

Achten Sie beim Programmieren darauf, Randfälle abzudecken - dies sind Stellen, an denen häufig Fehler auftreten.

Beachten Sie die Anforderung. Selbst wenn es funktioniert, aber nicht den Anforderungen entspricht, ist das ein Fehler.

Ausnahmeprotokolle können eine echte Hilfe sein, wenn in sechs Monaten etwas schief geht. Machen Sie es sich zur Gewohnheit, Ausnahmen aufzuzeichnen.

HLGEM
quelle
0

Meine beiden wichtigsten Gedanken sind: 1) Schreiben Sie besseren Code, der fehlschlägt, wenn Sie etwas Unerwartetes tun. 2) Verbessern Sie das Debuggen

Mein Code ist übersät mit

if(value!=null) throw new NotImplementedException();
if(obj.v>0) throw new Exception(); //sometimes i dont write NotImplementedException
if(value=="thing") throw ...;

Jedes Mal, wenn ich diesen Code ausführe, wird eine Ausnahme ausgelöst, die den Debugger zum Stoppen bringt. Dadurch kann ich die neuen Funktionen programmieren oder die Bedingungen umgehen, anstatt mich darüber zu wundern, was gerade passiert oder einen Fehler aufweist

Um das Debuggen von Problemen mit dem Aufrufstapel, Haltepunkten (mit Bedingungen), dem Sofortfenster (auch als Eingabeaufforderungs- oder Replikationsfenster bezeichnet), Beobachtungsvariablen und was auch immer zu verbessern.

user2528
quelle