it-swarm.com.de

Wie kann ich vermeiden, Fehler in der Software zu verursachen, wenn ich nicht verwandte Fehler behebe?

Ich bin ein Software-Praktikant und habe Fehler behoben, die behoben werden müssen, sowie Funktionen, die der Software hinzugefügt werden müssen. Wenn ich Funktionen hinzufüge, funktioniert alles gut. Mein Problem ist eher die Behebung von Fehlern. Ich arbeite an einer extrem großen Codebasis (Spannweite von Millionen von Zeilen) mit schlechter Dokumentation (Es gibt keine Kommentare, Tonnen von magischen Zahlen, enge Kopplung zwischen verschiedenen Klassen usw.). Die einzige bereitgestellte Dokumentation ist ein Word-Dokument mit etwa 8 Seiten. Aber ich habe immer noch das Gefühl, dass ich mit der Fehlerbehebung einen besseren Job machen kann.

Ich werde ein Beispiel für eine Situation geben, die ich erlebt habe und in der ich das Gefühl hätte besser machen können:

  • Mir wurde ein Fehler zugewiesen, der bezüglich der Berechnung der Ausmaße für einen bestimmten Objekttyp (Computergrafik) behoben werden musste.
  • Ich habe das Problem mit dem Fehler gefunden und warum er verursacht wurde. Da das Programm eine Datenstruktur (zusammenhängendes Array) mit Speicher füllte, der einen kartesischen 3D-Punkt darstellt, sollte es anscheinend nicht vorhanden sein (daher würde dieser Punkt für Ausdehnungsberechnungen verwendet).
  • Der Fehler wurde tatsächlich dadurch verursacht. Ein anderer Code (in einer anderen Klasse) verwendete jedoch eine Zeigerarithmetik, um diesen Punkt abzurufen und für eine andere Funktion zu verwenden, damit die Maus in der Nähe dieses Punkts einrastet, wenn eine bestimmte Funktion in der Software aktiviert wurde. Da ich den Punkt entfernt habe, habe ich den mir zugewiesenen Fehler behoben und dennoch einen weiteren Fehler in der Software verursacht.

Was kann ich tun, damit solche Dinge nicht auftreten? Wie kann ich mich verbessern? Gibt es einen Prozess, den ich vermisse?

49
Jason

Sie können nicht allein für diese Art von Mängeln verantwortlich gemacht werden. Sie sind Menschen und es ist unmöglich, an große Systeme als Ganzes zu denken.

Um "Regressionsfehler" zu vermeiden - Fehler, die beim Ändern des Systems unbeabsichtigt auftreten, können Sie Folgendes tun:

  • Entwickeln Sie eine umfassende Suite automatisierter Regressionstests. Hoffentlich hat Ihr System eine große Reihe von Tests. Jedes Mal, wenn ein Fehler in Ihrem System entdeckt wird, sollten Sie einen automatisierten Test schreiben, der den Fehler reproduziert. Dann beheben Sie den Fehler. Sollte sich das System jemals zurückbilden, wird Ihr "Regressionstest" unterbrochen und der Entwickler benachrichtigt.
  • Überprüfen Sie den Code. Wenn Sie einen Fehler beheben, sollten Sie die Verwendung der von Ihnen geänderten Funktion überprüfen, um festzustellen, welche Änderungen Sie vorgenommen haben
  • Schreiben Sie weitere Tests. Wenn Sie bei der Überprüfung des Codes Code identifizieren, der nicht durch automatisierte Tests abgedeckt ist, ist dies eine gute Gelegenheit, einige hinzuzufügen.
  • Machen Sie sich mit dem System vertraut und arbeiten Sie lange mit Software. Übung macht den Meister. Niemand erwartet von einem Entwickler, dass er keine Fehler in ein brandneues System einführt oder Praktikant ist. Wir haben es alle geschafft.
73
Samuel

Sie können dies nicht in vollem Umfang beseitigen. Hier sind einige Schritte, um die Auswirkungen und die Wahrscheinlichkeit zu verringern:

  1. Fügen Sie einen Komponententest und einen Regressionstest für die Funktionalität oder den Fehler hinzu, den Sie ändern oder beheben. Wenn Sie kein Testframework oder -geschirr für Ihr Projekt eingerichtet haben, richten Sie es so ein, dass es Teil Ihres Prozesses ist. Dies wird die Dinge im Laufe der Zeit verbessern.
  2. Verbessern Sie Ihr Code-Design, damit der Code lockerer gekoppelt wird. Das bedeutet, der SRP zu folgen, auch wenn man etwas DRY opfert. Insbesondere in OOP - Systemen sollten sich Code und Daten in derselben Klasse befinden und die Daten sollten immer privat sein. Wenn dies keinen Sinn ergibt, besteht eine Impedanzfehlanpassung zwischen der Problemdomäne und Es sollte nicht möglich sein, dass eine Änderung der Datenstruktur in einer Klasse das Verhalten einer anderen Klasse beeinflusst.
  3. Sprechen Sie mit Ihren Mitarbeitern über Ihre vorgeschlagene Lösung. Dies kann in Form von Codeüberprüfungen erfolgen, aber manchmal werden die Regressionen dadurch nicht erfasst. Codeüberprüfungen sind normalerweise nicht dazu gedacht, Fehler zu erkennen. Stellen Sie daher sicher, dass der Rest des Teams über die von Ihnen vorgenommenen Änderungen informiert ist, und geben Sie ihm Zeit, um Ihnen Feedback zu geben, welche anderen Teile des Systems möglicherweise auf den Code angewiesen sind. Tun Sie dies auch, wenn Sie die leitende Person im Team sind.

Hoffe das hilft.

10
RibaldEddie

Es gibt viele gute Vorschläge in anderen Antworten. Ich würde ihnen hinzufügen: Ihre Organisation hat wahrscheinlich ein Problem auf Managementebene.

  • Das Management priorisiert möglicherweise die Arbeit mit neuen Funktionen gegenüber der Adressierung von Schulden. Der von Ihnen erwähnte Fehler ist ein Beweis dafür, dass die Entwicklung fehlerfreier Software heute durch schlechte Praktiken in der Vergangenheit teurer wird. Sammeln Sie Datenpunkte wie diese, um das Management darüber zu informieren, dass ein anhaltendes Problem durch nicht adressierte Schulden besteht und dass es ratsam ist, einen "Qualitätsmeilenstein" zu planen, bei dem keine neuen Funktionen hinzugefügt werden, die bestehenden Schulden jedoch verringert werden.

  • Das Management kennt den Umfang des Problems wahrscheinlich nicht. Statische Analysetools, die echte Fehler finden, sind teuer, aber viel billiger als das Versagen auf dem Markt, da Sie Software ausgeliefert haben, die Benutzerdaten verliert. Ein guter statischer Analysator zeigt Ihnen, dass Sie Zehntausende von nicht adressierten Fehlern haben, wo sie sich befinden und wie Sie sie beheben können. Auf diese Weise können Sie die Größe des Problems und die Geschwindigkeit, mit der Sie es beheben, in den Griff bekommen.

9
Eric Lippert

In Bezug auf die Reform der Dinge gibt es im Gegensatz zur Verformung ein einfaches Prinzip. ein Prinzip, das wahrscheinlich als Paradox bezeichnet wird. In einem solchen Fall gibt es eine bestimmte Institution oder ein bestimmtes Gesetz; Nehmen wir der Einfachheit halber einen Zaun oder ein Tor an, das über eine Straße errichtet wurde. Die modernere Art von Reformer geht fröhlich darauf ein und sagt: "Ich sehe keine Verwendung davon; Lassen Sie es uns beseitigen. "Worauf der intelligentere Reformer gut antworten kann:" Wenn Sie die Verwendung nicht sehen, werde ich Sie mit Sicherheit nicht beseitigen lassen. Geh weg und denk nach. Wenn Sie dann zurückkommen und mir sagen können, dass Sie die Verwendung sehen, kann ich Ihnen erlauben, es zu zerstören. "

- G.K. Chesterson

Neben all den anderen hier angesprochenen Ideen ist es auch wertvoll herauszufinden, wie und warum ein Fehler wurde eingeführt. Angenommen, Ihr Team verwendet Git oder ein ähnliches Versionsverwaltungssystem, Tools wie git blame oder GitHubs Schuld Schaltfläche kann dabei helfen. Wenn Sie die fehlerhafte oder die fehlerhaften Codezeilen identifiziert haben, die den Fehler verursacht haben, können Sie mithilfe Ihrer Versionsverwaltungs-Tools herausfinden, wann sie von wem hinzugefügt wurden und als Teil welcher umfassenderen Änderung.

Immer wenn ich einen Fehler behebe, versuche ich, auf dem Bug-Tracker der Organisation eine Erzählung zu schreiben, wie der Fehler meiner Meinung nach entstanden ist. Manchmal ist das eine dumme und etwas peinliche Geschichte wie "Es sieht so aus, als hätte Bob Zeile 96 zu Testzwecken auskommentiert, sie versehentlich in Commit 5ab314c festgeschrieben und sie wurde zusammengeführt, weil wir uns beeilten, den Frobnicator bereitzustellen, und nicht Überprüfen Sie die Dinge in dieser Woche richtig. " Immer noch lernen, dass gut, an dem Punkt, an dem Sie den Fehler beheben, weil es Ihnen versichert, dass es wahrscheinlich keinen guten Grund dafür gibt Der fehlerhafte Code soll so sein, wie er ist, und Sie können ihn sicherer beheben. Aber manchmal taucht man in die git blame, und Sie stellen fest, dass die "offensichtlich defekte" Codezeile, die Sie ändern wollten, in einem Commit eingeführt wurde, das vorgibt, einen anderen Fehler zu beheben, an den Sie nicht gedacht hatten, und plötzlich Sie erkennen, dass Ihr "Fix" etwas Schaden anrichten wird und dass Sie etwas Klügeres tun müssen.

Wie viele andere Antworten hier bemerken, wäre es natürlich schön, wenn der vorherige Entwickler einen Test hinterlassen hätte, der fehlschlagen würde, wenn Sie naiv einen alten Fehler wieder einführen würden - eine Art automatisierte Warnung, die der Zaun, den Sie abreißen möchten, hat Ein Zweck, den Sie nicht sehen können. Sie können jedoch nicht steuern, wie viele Tests die früheren Entwickler Ihrer Codebasis geschrieben haben, da dies die Vergangenheit ist. Das Eintauchen in den Verlauf des Codes ist eine der wenigen Techniken, die Ihnen zur Verfügung stehen zum Zeitpunkt der Behebung eines vorhandenen Fehlers, um das Risiko zu verringern, dass Dinge kaputt gehen.

5
Mark Amery

Ich arbeite auch an einer fragilen Legacy-Anwendung. Mein oberstes Ziel für jede Änderung ist "Mach nichts kaputt, was vorher funktioniert hat". (Ziel Nummer zwei ist, dass der Benutzer in der Lage sein muss, seinen Job zu beenden, auch wenn es etwas klobig wird oder Sie eine Problemumgehung aufrufen müssen, er kann zu keinem Zeitpunkt absolut stecken bleiben.)

  1. Es gibt ein Buch von Michael Feathers, "Effektiv mit Legacy-Code arbeiten". Es ist sehr nützlich, aber ich werde Sie warnen, dass es zu 100% darum geht, automatisierte Tests hinzuzufügen. Es ist technisch immer möglich (und er erklärt, wie man es in vielen schwierigen Situationen macht), aber aus geschäftlicher Sicht ist es nicht immer praktikabel. Das Buch ist auch nützlich, weil es amüsante kleine Seitenleisten darüber enthält, wie schlimm die Dinge werden können.
  2. Mühsame manuelle Inspektion von allem, was den Punkt der Veränderung berührt. Wenn Sie zwei Funktionen geändert haben, foo und bar, führen Sie eine Volltextsuche in Ihrer gesamten Codebasis (Sie haben ALLES ausgecheckt, oder?) Nach den Wörtern foo und bar durch. (Beachten Sie, dass Sie ein Hauptbenutzer eines Suchwerkzeugs wie grep werden möchten.) Es ist wichtig, diese Suche nicht zu vereinfachen. Suchen Sie nicht nur in Java -Dateien) , weil Ihre Funktion möglicherweise mithilfe der Reflexion von etwas aufgerufen wird, das in einem Front-End-JavaScript ausgelöst wurde ... nur ein Beispiel. Verfolgen Sie die Rückverfolgung, bis Sie alles vollständig getestet haben, was Ihre Änderung aufruft.
  3. Kehren Sie Ihre Suchtechnik um und versuchen Sie, Punkte in Ihrer Anwendung zu finden, die dasselbe tun, ohne Ihren Änderungspunkt aufzurufen. Suchen Sie nach kopiertem und eingefügtem Code oder nach zwei Methoden und stellen Sie sicher, dass Sie alle Punkte geändert haben, die geändert werden mussten. (Wiederholen Sie dann den vorherigen Schritt.)

Es klingt irgendwie schrecklich, aber diese schwer zu wartenden Legacy-Anwendungen gibt es normalerweise nur noch und werden aktualisiert, weil sie etwas Wichtiges tun und jemand sie wirklich braucht, um zu arbeiten. Versuchen Sie, etwas Befriedigung daraus zu ziehen.

1
user3067860

"Ein anderer Code (in einer anderen Klasse) verwendete Zeigerarithmetik, um diesen Punkt abzurufen und für eine andere Funktion zu verwenden, damit die Maus in der Nähe dieses Punkts einrastet, wenn eine bestimmte Funktion in der Software aktiviert wurde."

Ja, Sie haben eine wartungsintensive Codebasis erhalten. Es klingt so, als ob in diesem Fall anstelle einer regelmäßigen Kopplung zwischen Objekten mit offensichtlichen Schnittstellen etwas "Magie" vor sich ging, die natürlich aufhörte zu funktionieren, sobald sie geändert wurde.

Es gibt keinen Zaubertrick. Viele Softwareentwicklungstechniken konzentrieren sich auf das Management der Komplexität, um zu erkennen, welche Auswirkungen eine Änderung haben wird - diese wurden hier jedoch nicht befolgt. Dies ist die Schuld der früheren Entwickler und der Senioren, die das Projekt überwachen.

1
pjc50

Sie können den Code umgestalten, um den direkten Zugriff auf dieses bestimmte Mitglied zu verbergen und einen Accessor hinzuzufügen. Dadurch wird jeder Code beschädigt, der auf dem direkten Zugriff auf das Mitglied beruht, sodass Sie jeden Ort kennen, an dem er verwendet wird.

Verschieben Sie als Bonus das Mitglied und füllen Sie seinen vorherigen Platz mit Müll - dies bricht den Code, der über Zeigerarithmetik darauf zugreift.

Als Entwickler möchten Sie, dass Ihr Code früh und häufig unterbrochen wird. "Funktioniert zu 99,99% oder zu der Zeit" ist für die Fehlerbehebung viel schlechter als "funktioniert überhaupt nicht". (Natürlich möchten Sie für Produktionscode nicht "früh brechen, oft pausieren")

0
Calin Ceteras