Was ist der beste Weg, um sich mit einer großen Codebasis vertraut zu machen? [geschlossen]


75

Der Beitritt zu einem bestehenden Team mit einer bereits vorhandenen großen Codebasis kann entmutigend sein. Was ist der beste Ansatz?

  • Breit; Versuchen Sie, aus dem Code einen allgemeinen Überblick darüber zu erhalten, wie alles miteinander verknüpft ist
  • Eng; Konzentrieren Sie sich jeweils auf kleine Codeabschnitte und verstehen Sie, wie diese vollständig funktionieren
  • Wählen Sie eine Funktion aus, die Sie im Laufe der Zeit entwickeln und lernen möchten
  • Versuchen Sie, Einblicke in Klassendiagramme und uml zu gewinnen, falls verfügbar (und aktuell).
  • Etwas ganz anderes?

Ich arbeite an einer C ++ App und Bibliothek mit ca. 20.000 Zeilen (Bearbeiten: klein im großen Schema der Dinge!). In der Industrie kann ich mir vorstellen, dass Sie von einem erfahrenen Programmierer vorgestellt werden. Wenn dies jedoch nicht der Fall ist, was können Sie tun, um so schnell wie möglich mit der Wertschöpfung zu beginnen?

-
Zusammenfassung der Antworten:

  • Durchlaufen Sie den Code im Debug-Modus, um zu sehen, wie er funktioniert
  • Koppeln Sie sich mit jemandem, der mit der Codebasis besser vertraut ist als Sie, und wechseln Sie sich ab, indem Sie die Person codieren und beobachten / diskutieren. Rotieren Sie die Partner unter den Teammitgliedern, damit das Wissen verbreitet wird.
  • Schreiben Sie Unit-Tests. Beginnen Sie mit einer Aussage darüber, wie Code Ihrer Meinung nach funktionieren wird. Wenn sich herausstellt, wie Sie es erwartet haben, haben Sie den Code wahrscheinlich verstanden. Wenn nicht, müssen Sie ein Rätsel lösen oder eine Anfrage stellen. (Danke Donal, das ist eine großartige Antwort)
  • Führen Sie vorhandene Komponententests für Funktionscode auf ähnliche Weise wie oben durch
  • Lesen Sie UML, von Doxygen erstellte Klassendiagramme und andere Dokumentationen, um ein umfassendes Gefühl für den Code zu erhalten.
  • Nehmen Sie kleine Änderungen oder Fehlerbehebungen vor und bauen Sie diese dann schrittweise auf
  • Machen Sie sich Notizen und springen Sie nicht hinein und beginnen Sie mit der Entwicklung. Es ist wertvoller, Zeit mit Verständnis zu verbringen, als unordentlichen oder unangemessenen Code zu generieren.

Dieser Beitrag ist ein Teilduplikat der besten Methode, um sich mit einer geerbten Codebasis vertraut zu machen


4
20K-Zeilen sind keine sehr große Codebasis. Wenn es nur 20.000 Zeilen sind, würde ich es lesen. Eines der Dinge, die ich an der Universität nicht gelernt habe, ist die Arbeit mit großen Codebasen.
Paco

Tatsächlich. 20k scheint nicht viel zu sein. Wir haben C ++ - Dateien mit jeweils mehr als 10.000 Zeilen. Ich weiß, es ist schlecht, aber wir haben momentan keine Zeit für Aufräumarbeiten. (Stellen Sie sich vor, ich verdrehe die Augen und denke nur darüber nach.) Ein Großteil des Aufblähens stammt jedoch aus Kommentaren.
HS.

2
Heh, in der Tat! Ich wollte nicht implizieren, dass 20k eine riesige Codebasis ist (ich habe es nie gesagt), sondern suchte nur nach allgemeinen, skalierbaren Ratschlägen. Bisher großartige Antworten; viel zu denken.
RJFalconer

20k ist .. was, eine Datei? ;-)
user2864740

Ein Ort, an dem ich mich beraten habe, hatte eine 40-KB-Zeilendatei mit tief verschachtelten if / then-Anweisungen, die eine Art Geschäftsregel implementiert haben. Es war furchtbar.
Dave Newton

Antworten:


24

Beginnen Sie mit einer kleinen Aufgabe, wenn möglich, und debuggen Sie den Code um Ihr Problem herum. Das Durchlaufen von Code im Debug-Modus ist der einfachste Weg, um zu lernen, wie etwas funktioniert.


2
Es lohnt sich zu überlegen, wie eine Variable beim Debuggen aussehen soll. Wenn der Debugger andere Ergebnisse anzeigt, finden Sie heraus, warum. Ich persönlich mag keine Debugger, bevorzuge aber Print-Anweisungen, die Sie zum Vorausdenken zwingen.
extraneon

1
@extraneon Mit print-Anweisungen können Sie nicht nur im Voraus nachdenken, sondern auch große Mengen an Eingaben leichter erkennen. Wenn eine Variable beispielsweise normalerweise 2 ist und einmal in 100 Schleifen 10 wird, können Sie sie mit einer printf-Anweisung erkennen, aber es ist schwieriger, dies mit einem Debugger zu verfolgen.
Elazar Leibovich

18

Eine andere Möglichkeit besteht darin, Tests für die Funktionen zu schreiben, an denen Sie interessiert sind. Das Einrichten des Testkabels ist eine gute Möglichkeit, um festzustellen, welche Abhängigkeiten das System hat und wo sich sein Status befindet. Jeder Test beginnt mit einer Aussage darüber, wie das System Ihrer Meinung nach funktionieren sollte. Wenn sich herausstellt, dass dies so funktioniert, haben Sie etwas erreicht und einen funktionierenden Beispielcode, um es zu reproduzieren. Wenn es so nicht funktioniert, müssen Sie ein Rätsel lösen und eine Reihe von Nachforschungen anstellen.


Ich habe immer gedacht, dass dies der beste Weg ist, sich mit dem Code eines anderen vertraut zu machen.
Bill the Lizard

11

Eine Sache, die ich normalerweise Leuten vorschlage, die noch nicht erwähnt wurden, ist, dass es wichtig ist, ein kompetenter Benutzer der vorhandenen Codebasis zu werden, bevor Sie Entwickler werden können. Wenn neue Entwickler in unser großes Softwareprojekt eintreten, schlage ich vor, dass sie Zeit damit verbringen, erfahrene Benutzer zu werden, bevor sie versuchen, an dem Code zu arbeiten.

Vielleicht ist das offensichtlich, aber ich habe viele Leute gesehen, die versucht haben, zu schnell in den Code zu springen, weil sie eifrig sind, Fortschritte zu machen.


9

Dies hängt ganz davon ab, welche Art von Lernenden und welche Art von Programmierer Sie sind, aber:

  • Breit zuerst - Sie brauchen eine Vorstellung von Umfang und Größe. Dies kann das Überfliegen von docs / uml beinhalten, wenn sie gut sind. Wenn es sich um ein langfristiges Projekt handelt und Sie ein umfassendes Verständnis für alles benötigen, kann ich die Dokumente möglicherweise richtig lesen. Wieder, wenn sie gut sind.
  • Eng - wählen Sie etwas Verwaltbares aus und versuchen Sie es zu verstehen. Holen Sie sich einen "Geschmack" für den Code.
  • Wählen Sie eine Funktion aus - möglicherweise eine andere als die, die Sie gerade angesehen haben, wenn Sie sich sicher fühlen, und nehmen Sie einige kleine Änderungen vor.
  • Iterieren - beurteilen Sie, wie gut die Dinge gelaufen sind, und prüfen Sie, ob Sie davon profitieren können, einen frühen Schritt eingehender zu wiederholen.

7

Paarung mit strenger Rotation.

Wenn möglich, versuchen Sie beim Durchlaufen der Dokumentation / Codebasis, Pairing mit strikter Rotation zu verwenden. Das heißt, zwei von Ihnen sitzen für einen festgelegten Zeitraum zusammen (z. B. eine zweistündige Sitzung), dann wechseln Sie die Paare. Eine Person arbeitet weiter an dieser Aufgabe, während die andere mit einem anderen Partner zu einer anderen Aufgabe wechselt.

In Paaren sammeln Sie beide ein Stück Wissen, das dann bei Rotation an andere Mitglieder des Teams weitergegeben werden kann. Das Gute daran ist auch, dass derjenige, der an der Aufgabe gearbeitet hat (in diesem Fall den Code untersucht), die Konzepte auf eine leichter verständliche Weise zusammenfassen und erklären kann, wenn ein neues Paar zusammengebracht wird. Im Laufe der Zeit sollte jeder auf einem ähnlichen Verständnisniveau sein und hoffentlich das Syndrom "Oh, nur John kennt diesen Teil des Codes" vermeiden.

Nach allem, was ich über Ihr Szenario sagen kann, haben Sie eine gute Nummer dafür (3 Paare). Wenn Sie jedoch verteilt sind oder nicht auf derselben Zeitskala arbeiten, ist es unwahrscheinlich, dass dies möglich ist.


6

Ich würde vorschlagen, Doxygen darauf auszuführen, um ein aktuelles Klassendiagramm zu erhalten, und dann eine Weile breit zu arbeiten. Auf diese Weise erhalten Sie ein schnelles Gesamtbild, das Sie verwenden können, wenn Sie den Code aus nächster Nähe betrachten.


5

Ich stimme zu, dass es ganz davon abhängt, welche Art von Lernenden Sie sind. Trotzdem war ich bei zwei Unternehmen, die anfangs sehr große Codebasen hatten. Normalerweise arbeite ich so:

Wenn möglich, gehe ich vor dem Betrachten des Funktionscodes bereits geschriebene Komponententests durch. Diese können im Allgemeinen sehr hilfreich sein. Wenn sie nicht verfügbar sind, mache ich Folgendes.

Erstens ignoriere ich die Implementierung weitgehend und betrachte nur Header-Dateien oder nur die Klassenschnittstellen. Ich versuche eine Vorstellung davon zu bekommen, was der Zweck jeder Klasse ist. Zweitens gehe ich eine Ebene tief in die Implementierung ein und beginne mit dem Bereich, der am wichtigsten zu sein scheint. Dies ist schwer einzuschätzen, daher beginne ich gelegentlich ganz oben und arbeite mich in der Dateiliste nach unten. Ich nenne das Lernen zuerst. Nach diesem ersten Schritt gehe ich im Allgemeinen den Rest des Codes eingehend durch. Der erste Blick auf die Breite hilft dabei, alle Ideen zu festigen / zu korrigieren, die ich von der Schnittstellenebene erhalten habe, und dann zeigt mir der Tiefenblick die Muster, die zur Implementierung des Systems verwendet wurden, sowie die verschiedenen Entwurfsideen. Mit "Tiefe zuerst" meine ich, dass Sie das Programm im Grunde genommen mit dem Debugger durchlaufen und in jede Funktion eintreten, um zu sehen, wie es funktioniert. und so weiter. Dies ist mit wirklich großen Systemen offensichtlich nicht möglich, aber 20.000 LOC sind nicht so viele. :) :)


3

Arbeiten Sie mit einem anderen Programmierer zusammen, der mit dem System besser vertraut ist, um eine neue Funktion zu entwickeln oder einen Fehler zu beheben. Dies ist die Methode, die ich am besten gesehen habe.


2

Ich denke, Sie müssen dies an eine bestimmte Aufgabe binden. Wenn Sie Zeit haben, entscheiden Sie sich für den Ansatz, auf den Sie Lust haben.

Wenn Sie etwas haben, das erledigt werden muss, geben Sie sich einen engen Fokus und erledigen Sie es.


2

Lassen Sie sich vom Team zwei Wochen lang Fehler beheben (wenn Sie zwei Wochen Zeit haben). Sie werden sich freuen, jemanden dazu zu bringen, die Verantwortung dafür zu übernehmen, und am Ende des Zeitraums haben Sie so viel Zeit damit verbracht, Probleme mit der Bibliothek zu lösen, dass Sie es wahrscheinlich ziemlich gut kennen.


So neige ich dazu, Dinge zu tun. Es gibt keinen Ersatz dafür. Das einfache Lesen von Code / Dokumentation / Tests schneidet nie wirklich ab.
Stephen Darlington

2

Wenn es Unit-Tests hat (ich wette, tut es nicht). Fangen Sie klein an und stellen Sie sicher, dass die Komponententests nicht fehlschlagen. Wenn Sie auf einmal auf die gesamte Codebasis starren, werden Ihre Augen glasig und Sie fühlen sich überwältigt.

Wenn keine Komponententests vorhanden sind, müssen Sie sich auf die gewünschte Funktion konzentrieren. Führen Sie die App aus und sehen Sie sich die Ergebnisse der Dinge an, die Ihre Funktion beeinflussen sollte. Schauen Sie sich dann den Code an, um herauszufinden, wie die App die Dinge erstellt, die Sie ändern möchten. Ändern Sie es schließlich und überprüfen Sie, ob die Ergebnisse wie gewünscht angezeigt werden.

Sie haben erwähnt, dass es sich um eine App und eine Bibliothek handelt. Ändern Sie zuerst die App und bleiben Sie bei der Verwendung der Bibliothek als Benutzer. Nachdem Sie die Bibliothek kennengelernt haben, können Sie sie leichter ändern.

Von oben nach unten hat die App wahrscheinlich eine Hauptschleife oder eine Haupt-GUI, die die gesamte Aktion steuert. Es lohnt sich, den Hauptsteuerungsfluss der Anwendung zu verstehen. Es lohnt sich, den Code zu lesen, um sich einen umfassenden Überblick über den Hauptfluss der App zu verschaffen. Wenn es sich um eine GUI-App handelt, erstellen Sie ein Papier, in dem angezeigt wird, welche Bildschirme vorhanden sind und wie Sie von einem Bildschirm zum anderen gelangen. Wenn es sich um eine Befehlszeilen-App handelt, wie erfolgt die Verarbeitung?

Auch in Unternehmen ist dieser Ansatz nicht ungewöhnlich. Oft versteht niemand genau, wie eine Anwendung funktioniert. Und die Leute haben keine Zeit, dich herumzuführen. Sie bevorzugen bestimmte Fragen zu bestimmten Dingen, sodass Sie sich selbst vertiefen und experimentieren müssen. Sobald Sie Ihre spezifische Frage erhalten haben, können Sie versuchen, die Wissensquelle für diesen Teil der Anwendung zu isolieren und sie zu stellen.


2

Beginnen Sie mit dem Verständnis der 'Problemdomäne' (ist es ein Lohn- und Gehaltsabrechnungssystem? Inventar? Echtzeitkontrolle oder was auch immer). Wenn Sie den von den Benutzern verwendeten Jargon nicht verstehen, werden Sie den Code nie verstehen.

Schauen Sie sich dann das Objektmodell an. Möglicherweise ist bereits ein Diagramm vorhanden, oder Sie müssen eines zurückentwickeln (entweder manuell oder mithilfe eines von Doug vorgeschlagenen Tools). Zu diesem Zeitpunkt können Sie auch die Datenbank untersuchen (falls vorhanden), ob sie dem Objektmodell folgen soll, dies jedoch möglicherweise nicht. Dies ist wichtig zu wissen.

Werfen Sie einen Blick auf den Änderungsverlauf oder die Fehlerdatenbank. Wenn es einen Bereich gibt, der häufig vorkommt, schauen Sie sich zuerst dieses Bit an. Dies bedeutet nicht, dass es schlecht geschrieben ist, sondern dass es das Bit ist, das jeder verwendet.

Zum Schluss noch ein paar Notizen machen (ich bevorzuge ein Wiki).

  • Die vorhandenen Leute können es verwenden, um Ihre Annahmen zu überprüfen und Ihnen zu helfen.
  • Sie müssen später darauf zurückgreifen.
  • Der nächste neue Mann im Team wird sich wirklich bei Ihnen bedanken.

2

Ich hatte eine ähnliche Situation. Ich würde sagen, du gehst so:

  • Wenn es sich um eine datenbankgesteuerte Anwendung handelt, starten Sie von der Datenbank aus und versuchen Sie, jede Tabelle, ihre Felder und dann ihre Beziehung zu den anderen Tabellen zu verstehen.
  • Wenn Sie mit dem zugrunde liegenden Speicher fertig sind, wechseln Sie zur ORM-Ebene. Diese Tabelle muss eine Art Darstellung im Code haben.
  • Sobald Sie damit fertig sind, fahren Sie fort, wie und woher diese Objekte kommen. Schnittstelle? Welche Schnittstelle? Irgendwelche Validierungen? Welche Vorverarbeitung findet auf ihnen statt, bevor sie zum Datenspeicher gehen?

Dies würde Sie besser mit dem System vertraut machen. Denken Sie daran, dass der Versuch, Komponententests zu schreiben oder zu verstehen, nur möglich ist, wenn Sie genau wissen, was getestet wird und warum es nur auf diese Weise getestet werden muss.

Und im Falle einer großen Anwendung, die nicht auf Datenbanken ausgerichtet ist, würde ich einen anderen Ansatz empfehlen:

  • Was ist das Hauptziel des Systems?
  • Was sind dann die Hauptkomponenten des Systems, um dieses Problem zu lösen?
  • Welche Wechselwirkungen hat jede der Komponenten untereinander? Erstellen Sie ein Diagramm, das Komponentenabhängigkeiten darstellt. Fragen Sie jemanden, der bereits daran arbeitet. Diese Komponenten müssen etwas untereinander austauschen, also versuchen Sie auch, dies herauszufinden (wie IO das File-Objekt möglicherweise an die GUI zurückgibt und wie)
  • Sobald Sie sich damit vertraut gemacht haben, tauchen Sie in Komponenten ein, die unter anderem am wenigsten abhängig sind. Untersuchen Sie nun, wie diese Komponente weiter in Klassen unterteilt ist und wie sie miteinander interagieren. Auf diese Weise haben Sie insgesamt einen Hang zu einer einzelnen Komponente
  • Wechseln Sie zur nächstniedrigeren abhängigen Komponente
  • Wechseln Sie zum Schluss zu der Kernkomponente, die normalerweise von vielen anderen Komponenten abhängt, die Sie bereits in Angriff genommen haben
  • Wenn Sie sich die Kernkomponente ansehen, beziehen Sie sich möglicherweise auf die zuvor untersuchten Komponenten. Machen Sie sich also keine Sorgen, arbeiten Sie weiter hart!

Für die erste Strategie: Nehmen Sie zum Beispiel das Beispiel dieser Stackoverflow-Site. Untersuchen Sie den Datenspeicher, was gespeichert wird, wie gespeichert wird, welche Darstellungen diese Elemente im Code haben, wie und wo diese auf der Benutzeroberfläche dargestellt werden. Woher kommen sie und welche Verarbeitung findet auf ihnen statt, sobald sie zum Datenspeicher zurückkehren.

Für die zweite nehmen wir zum Beispiel das Beispiel eines Textverarbeitungsprogramms. Welche Komponenten gibt es? IO, UI, Page und Like. Wie interagieren diese miteinander? Gehen Sie weiter, während Sie weiter lernen.

Seien Sie entspannt. Geschriebener Code ist jemandes Denkweise, eingefrorene Logik und Denkstil, und es würde einige Zeit dauern, diese Gedanken zu lesen.


2

Wenn Sie Teammitglieder zur Verfügung haben, die Erfahrung mit dem Code haben, sollten Sie zunächst veranlassen, dass diese mit Ihnen einen Überblick über den Code geben. Jedes Teammitglied sollte Sie über sein Fachgebiet informieren. Es ist normalerweise wertvoll, mehrere Personen dazu zu bringen, Dinge zu erklären, da einige besser erklären können als andere und einige ein besseres Verständnis haben als andere.

Dann müssen Sie den Code für eine Weile ohne Druck lesen (ein paar Tage oder eine Woche, wenn Ihr Chef dies bereitstellt). Es ist oft hilfreich, das Projekt selbst zu kompilieren / zu erstellen und das Projekt im Debug-Modus auszuführen, damit Sie den Code schrittweise durchlaufen können. Dann fangen Sie an, Ihre Füße nass zu machen, kleine Fehler zu beheben und kleine Verbesserungen vorzunehmen. Sie werden hoffentlich bald bereit sein für ein mittelgroßes Projekt und später für ein großes Projekt. Lehnen Sie sich weiterhin auf Ihre Teamkollegen zurück - oft finden Sie einen, der bereit ist, Sie zu betreuen.

Sei nicht zu hart mit dir selbst, wenn du kämpfst - das ist normal. Es kann lange dauern, vielleicht Jahre, um eine große Codebasis zu verstehen. Tatsächlich ist es oft so, dass es auch nach Jahren noch einige Teile des Codes gibt, die noch ein bisschen beängstigend und undurchsichtig sind. Wenn zwischen den Projekten Ausfallzeiten auftreten, können Sie sich in diese Bereiche vertiefen, und Sie werden häufig feststellen, dass Sie nach einigen Versuchen sogar diese Teile herausfinden können.

Viel Glück!


2

Möglicherweise möchten Sie sich die Reverse Engineering- Tools für den Quellcode ansehen . Ich kenne zwei Tools:

Beide Tools bieten ähnliche Funktionen, einschließlich statischer Analysen, die Diagramme der Beziehungen zwischen Modulen in der Software erstellen.

Dies besteht hauptsächlich aus Anrufdiagrammen und Typ- / Klassenanständigkeiten. Wenn Sie diese Informationen anzeigen, erhalten Sie ein gutes Bild davon, wie sich die Teile des Codes zueinander verhalten. Mithilfe dieser Informationen können Sie in der tatsächlichen Quelle nach den Teilen suchen, die Sie am meisten interessieren und die Sie zuerst verstehen / ändern müssen.


1

Ich finde, dass es ein bisschen überwältigend sein kann, nur in den Code zu springen. Versuchen Sie, so viel Dokumentation wie möglich über das Design zu lesen. Dies wird hoffentlich den Zweck und die Struktur jeder Komponente erklären. Es ist am besten, wenn ein bestehender Entwickler Sie durch die Sache führen kann, aber das ist nicht immer möglich.

Versuchen Sie, ein oder zwei Fehler zu beheben, sobald Sie mit der Struktur des Codes auf hoher Ebene vertraut sind. Dies wird Ihnen helfen, den eigentlichen Code in den Griff zu bekommen.


1

Ich mag alle Antworten, die besagen, dass Sie ein Tool wie Doxygen verwenden sollten, um ein Klassendiagramm zu erhalten, und zuerst versuchen, das Gesamtbild zu verstehen. Dem stimme ich voll und ganz zu.

Dies hängt jedoch weitgehend davon ab, wie gut der Code zu Beginn berücksichtigt wird. Wenn es ein gigantisches Durcheinander ist, wird es schwer zu lernen sein. Wenn es sauber und richtig organisiert ist, sollte es nicht so schlecht sein.


1

In dieser Antwort erfahren Sie, wie Sie mithilfe von Testabdeckungstools den Code für ein Feature von Interesse finden, ohne zu wissen, wo sich dieses Feature befindet oder wie es auf viele Module verteilt ist.


1
Die Verbindung ist unterbrochen.
Rokit

0

(Schamloses Marketing voraus)

Sie sollten nWire auschecken . Es ist ein Eclipse-Plugin zum Navigieren und Visualisieren großer Codebasen. Viele unserer Kunden nutzen es, um neue Entwickler zu gewinnen, indem sie Visualisierungen der wichtigsten Abläufe ausdrucken.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.