Fragen zur Zusammenarbeit

Bei den ersten Gesprächen zur Zusammenarbeit werden Themen und Fragen ausgetauscht, die sich auf meine Arbeit und die strukturierung von Projekten beziehen. Hier einige wiederkehrende Fragen und Informationen.

Einzelperson oder Team

Kannst du mir mehr über deine Firma und dein Team erzählen? Arbeitest du alleine oder hast du ein Team, dass dich bei Projekten unterstützt?

Diese Frage hilft mir zu verstehen, ob du als Einzelperson oder in einem Team arbeitest, und ob zusätzliche Ressourcen zur Verfügung stehen, falls das Projekt eine größere Kapazität erfordert.

Antwort

Ich führe meine Firma als Einzelperson, arbeite jedoch häufig in Teams, insbesondere bei größeren Produktentwicklungen, die weltweit in großen Stückzahlen eingesetzt werden. Solche Projekte erfordern eine enge Zusammenarbeit im Team. Gleichzeitig übernehme ich auch spezielle Aufgaben in Einzelarbeit, wie die Entwicklung von Prototypen zur Erprobung neuer Konzepte. Sobald ein Prototyp fertiggestellt ist, erfolgt die Übergabe und Weiterentwicklung natürlich wieder in Zusammenarbeit mit dem Team. Diese Mischung aus Teamarbeit und Einzelprojekten ermöglicht es mir, flexibel auf unterschiedliche Anforderungen zu reagieren.

C++ und Performanceoptimierungen

Was hat dich dazu bewogen, sich auf C++ und Performanceoptimierungen zu spezialisieren?

Ich möchte etwas über die Motivation und Leidenschaft für die Arbeit erfahren. Es gibt mir einen Einblick in deinen beruflichen Hintergrund und was dich antreibt.

Antwort

Meine Spezialisierung auf C++ begann historisch, als wir in den frühen Tagen der PCs von Cobol auf Großrechnern zu C und später auf C++ auf den PCs wechselten. Diese Sprache hat mich seitdem begleitet und ist heute eine bewusste Entscheidung. Ich habe in meiner Karriere auch mit anderen Sprachen gearbeitet (Java, C#) und weitere Sprachen aus Interesse untersucht (Ada, Kotlin, F#, Python und Swift), um die Stärken und Schwächen verschiedener Ansätze zu verstehen.

Letztlich habe ich mich jedoch bewusst für C++ entschieden. Die Sprache bietet alle Freiheiten, um Performance und Skalierbarkeit präzise zu steuern, verlangt aber gleichzeitig Genauigkeit bei der Implementierung. Seit C++11 hat sich die Sprache enorm weiterentwickelt und gleichzeitig ihre ursprünglichen Stärken beibehalten. Die kontinuierliche Modernisierung von C++ geht in eine vielversprechende Richtung und wird in den nächsten Jahren weiter an Akzeptanz und Leistungsfähigkeit gewinnen.

Die Performanceoptimierung ist für mich ebenfalls eine bewusste Entscheidung. Unnötig langsame Funktionen betrachte ich als Fehler. Dabei achte ich jedoch darauf, dass die Optimierungen in einem sinnvollen Verhältnis zum Nutzen stehen. In einem aktuellen Projekt konnte ich die Laufzeit von 150 Minuten auf 5 Minuten reduzieren, was für den Kunden einen großen Mehrwert darstellte. Weitere Optimierungen hätten nur marginale Verbesserungen gebracht. Für mich ist Performance ein Qualitätsmerkmal – aber stets im Zusammenhang mit anderen wichtigen Aspekten wie Lesbarkeit, Wartbarkeit und einer soliden Dokumentation.

Art von Projekten

Welche Art von Projekten bearbeitest du typischerweise, und wie passt unser Auftrag in diese Kategorie?

Ich möchte verstehen, ob das aktuelle Projekt gut zu deinem typischen Arbeitsfeld passt und welche Erfahrungen du aus ähnlichen Projekten mitbringst.

Antwort

Typischerweise arbeite ich auf Windows-Systemen und entwickle gemeinsam mit den Teams meiner Auftraggeber Produkte für die Windows-Plattform. Die Implementierung erfolgt hauptsächlich in C++20 oder C#. Meine besondere Stärke liegt in der Entwicklung von Bibliotheken und der Business-Logik. Dazu gehört der Datenbankzugriff mittels SQL (Microsoft SQL Server und PostgreSQL), die Entwicklung von User-Interfaces mit MFC und Qt, sowie die Arbeit mit Active Directory, COM und Windows-Diensten.

In aktuellen Projekten liegt der Schwerpunkt auf Sicherheitslösungen, wie z.B. Single Sign-On, Verschlüsselung und Credential Provider für die hardware-unterstützte Anmeldung an Windows-Systemen.

Für die Zusammenarbeit verwenden wir Tools wie git, GitLab, TeamCity, YouTrack und Gitea, Microsoft Teams und Chatsystem Zulip.

In meiner Arbeit begleite ich die Produktentwicklung von der ersten Konzeptdiskussion bis hin zu automatisierten Tests und der Übergabe an die QA zur Freigabe. Dabei entwickle ich sowohl neue Funktionen und Produkte als auch Lösungen zur Fehlerbehebung in bestehenden Systemen. Mein Ziel ist es, stets eine saubere, wartbare und performante Implementierung zu gewährleisten, die den Anforderungen des Kunden gerecht wird.

Kommunikation

Wie sehen deine typischen Arbeits- und Kommunikationsprozesse aus, besonders bei langfristigen Projekten?

Diese Frage ist mir wichtig, um zu verstehen, wie du mit Kunden kommunizierst, wie regelmäßig Updates zu Projekten gegeben werden, und welche Erwartungen wir in Bezug auf die Zusammenarbeit haben können.

Antwort

Wir müssen bei der Antwort die Realisierung zum Festpreis und die begleitende Softwareentwicklung als Dienstleistung unterscheiden.

Bei Festpreisprojekten erfolgt die Dokumentation von Zielsetzung und Leistungsumfang im Vorfeld. Aufgrund der vertrauensvollen Zusammenarbeit mit meinen Kunden kann dieser erste Schritt so genau gestaltet werden, dass ein Festpreis kalkuliert werden kann, ohne dass ein starreres Vertragswerk nötig ist. Es bleibt jedoch immer genug Spielraum, um während der Entwicklung gemeinsam mit dem Kunden Änderungen zu vereinbaren. Solche Projekte dauern in der Regel wenige Tage bis zu zwei Monate. Regelmäßige Statusupdates, z.B. wöchentlich oder nach wichtigen Meilensteinen, sichern dem Kunden eine kontinuierliche Einschätzung des Projektfortschritts.

Bei Dienstleistungen bin ich als Teil des Kundenteams in die normalen Arbeitsabläufe eingebunden und nehme an den regelmäßigen Meetings teil. Die Prioritäten und Ziele werden in enger Absprache mit dem Kunden festgelegt und angepasst.

Die Kommunikation erfolgt flexibel über Präsenz-Meetings im Büro des Kunden oder per Videocall. Seit Corona arbeite ich fast ausschließlich remote, was auch in der Zusammenarbeit mit internationalen Teams, z.B. Entwicklern aus Afrika und Indien, problemlos funktioniert. In den Projekten werden gängige Tools wie GitLab, YouTrack und Chatsysteme zur Projektsteuerung und Kommunikation verwendet.

Nachbetreuung eines Projekts

Wie handhabst du die Nachbetreuung eines Projekts? Bietest du auch Support oder weitere Dienstleistungen nach dem Abschluss an?

Ich möchte die langfristige Zusammenarbeit klären. Es ist wichtig zu wissen, ob du auch nach Abschluss des Projekts für Support oder Weiterentwicklungen zur Verfügung stehst.

Antwort

Wir müssen zwischen Festpreisprojekten und der begleitenden Softwareentwicklung als Dienstleistung unterscheiden.

Bei Festpreisprojekten liefere ich die vereinbarte Software und betreue die Entwicklung bis zur erfolgreichen Abnahme durch den Kunden. Nach der Übergabe übernimmt der Kunde die Software in seine Betriebs- und Entwicklungsumgebung. Nachfolgende Wünsche werden als separate Folgeprojekte vereinbart. Fehler in der übergebenen Version werden von mir auch langfristig ohne zusätzliche Kosten behoben. Selbst nach längeren Pausen können Kunden auf meine Unterstützung zählen, und ich biete bei Bedarf weitere Entwicklungen an.

Bei Dienstleistungen wird ein Projektrahmen vereinbart, der dem Kunden über einen längeren Zeitraum eine ausreichende Kapazität von meiner Seite sichert. Dieser Rahmen beinhaltet ein monatliches Stundenkontingent und eine feste Projektlaufzeit – entweder bis zu einem bestimmten Stichtag oder bis zur Freigabe der neuen Version. Vor Ende des Projektrahmens prüfe ich gemeinsam mit dem Kunden, ob weitere Kapazitäten benötigt werden und wie diese sich mit meiner freien Verfügbarkeit decken. In den letzten Monaten betrug die Dauer der Projektarbeit in der Regel zwischen 6 und 15 Monaten.

Erfahrung mit C++20 und Templates

Welche Erfahrungen hast du mit C++20 und den damit eingeführten neuen Features, insbesondere im Bereich von Templates?

Da das neue Projekt stark auf C++20 und Templates basiert, möchte ich sicherstellen, dass du fundierte Kenntnisse und praktische Erfahrung mit diesen spezifischen C++20-Features hast.

Antwort

Als freier Entwickler ist Weiterbildung ein wichtiger Bestandteil meiner monatlichen Arbeit. Derzeit verfolge ich die Entwicklungen von C++26, wobei mich besonders die Themen Contracts und Pattern Matching interessieren, die zur Verbesserung der Codequalität beitragen können.

In meiner Entwicklungsumgebung nutze ich immer den Sprachstandard „C++ latest“, um frühzeitig mit neuen Features zu experimentieren. Ich setze C++20 bereits seit einigen Jahren ein und habe umfangreiche Erfahrungen mit den neuen Features gesammelt, z.B. den Ranges, die ich besonders schätze. Aktuell beginnen wir im Projekt die Implementierung von Concepts und Modules, um die Code-Basis noch wartbarer zu gestalten und Buildzeiten zu reduzieren.

Bei Kundenprojekten wird natürlich vorgegeben, welcher Standard verwendet wird. Meine Kunden wechselten 2024 von C++17 auf C++20, sodass ich auch in realen Projekten verstärkt mit den neuen Möglichkeiten arbeite.

In Bezug auf Templates unterscheide ich drei Anwendungsbereiche: erstens, die tägliche Nutzung von Template Libraries wie der STL und third-party Libraries. Zweitens, die Entwicklung eigener Template-basierter Funktionen, Klassen und Bibliotheken, die ich maßgeblich für Kundenprojekte entwickelt habe. Ein Beispiel dafür ist die Erweiterung der alten Logging Funktionalität auf eine felexiblere Lösung. Drittens, die Entwicklung von komplett Template-basierten Bibliotheken wie „fmtlib“ ist nicht mein Schwerpunkt, jedoch kenne ich deren Funktionsweise und Prinzipien.

Auftrag für Code Review

Wenn du einen Auftrag zum Review einer Funktionalität oder eines bestehenden Frameworks erhältst: wie näherst du dich sich typischerweise dem Review? Welche Schritte unternimmst du zuerst?

Ich möchte deine Arbeitsweise und deinen Ansatz zur Analyse von bestehendem Code kennenlernen. Es ist wichtig zu verstehen, wie strukturiert du an einen Review herangehst.

Antwort

Analyse

  • Wenn möglich: Kunde erläutert Idee, Arbeitsweise, Zielsetzung und geht auf offene Fragen und Probleme ein (Tickets, Anforderungen)
  • Wenn vorhanden: Sichtung der Dokumentation
  • Sichtung vorhandener Dateien, um über die Namen der Dateien eine Struktur zu erkennen
  • Wenn möglich: Laden des Projekts in Visual Studio, sodass mit Intellisense und Codelens ein überblick erreicht werden kann
  • Wenn vorhanden: Sichtung der Tests
  • Verstehen der Logik und Zusammenhänge
  • Analyse Source Code um über Häufung von Warnungen Problembereiche zu erkennen (Viele Warnungen in einem Bereich deuten auf schlechten Code)
  • Abgleich der Anforderungen mit der tatsächlichen Implementierung, um Lücken oder Abweichungen zu identifizieren.
  • Prüfung jeder Funktion auf Logik, Struktur und Probleme
  • Prüfung auf erkennbare Gesamtstruktur
  • Klärung offener Fragen mit dem Kunden für ein besseres Verständnis des Projekts

Review

  • Deckt die Implementierung die Anforderung?
  • Gibt es ernste Fehler und Probleme?
  • Gibt es strukturelle Verbesserungen?
  • Gibt es vermutete Verbesserungen in der Performance?
  • Welche Fragen wurden während des Reviews nicht durch Source und Dokumentation beantwortet?

Kundenwünsche

  • Messung und Analyse Performance

Ergebnis

  • Darstellung des Gesamteindrucks
  • Positive Eindrücke, besondere Highlights
  • Strukturelle Schwächen
  • Implementierungsprobleme
  • Performanceprobleme

Code Qualität

Wie bewertest du die Qualität von Code, insbesondere in Bezug auf Lesbarkeit, Wartbarkeit und Performance?

Da das Review wahrscheinlich auch eine Beurteilung der Codequalität beinhaltet, ist es wichtig zu wissen, welche Kriterien du bei der Bewertung von Code anwendest.

Antwort

Codequalität lässt sich sowohl durch objektive als auch durch subjektive Merkmale bewerten. Zu den objektiven Kriterien zählen z.B. Warnungen vom Compiler oder aus statischen Analysewerkzeugen sowie eindeutige Performanceprobleme. Subjektive Merkmale umfassen den Stil, die Lesbarkeit und die Struktur der internen Kommunikation zwischen Modulen.

Da es für viele Aspekte der Softwareentwicklung unterschiedliche Ansätze gibt, um guten Code zu schreiben, ist es wichtig, die Vorgaben des Kunden, die Geschichte des Projekts und die Ideen hinter den gewählten Ansätzen zu verstehen. In vielen bestehenden Projekten sieht man oft, wie sich der Code im Laufe der Zeit verändert hat, sei es durch neue Sprachmittel oder durch Änderungen im Team. Manchmal sind Teile des Codes bereits modernisiert, während andere noch veraltete Muster verwenden.

Die Bewertung der Codequalität umfasst grundsätzlich die Lesbarkeit und Wartbarkeit. Dazu gehören unter anderem:

  • Problematische Warnungen bei der statischen Source Analyse (Visual Studio, ReSharper, Sonar, CppDepends)
  • Konsistente Benennung von Variablen und Funktionen
  • Klare Strukturierung des Codes
  • Verwendung von Kommentaren, um komplexe Abschnitte verständlich zu machen
  • Modularität, um den Code einfach zu erweitern oder anzupassen.

Besonderen Wert lege ich auf die Art und Vollständigkeit der Fehlerbehandlung, da dies direkte Auswirkungen auf den Kunden und den Betrieb des Systems haben kann. Eine unzureichende Fehlerbehandlung kann zu Ausfällen oder schwerwiegenden Problemen im laufenden Betrieb führen. Daher beurteile ich nicht nur die aktuelle Qualität des Codes, sondern auch, wie gut er langfristig gewartet und erweitert werden kann.

Große und komplexe Codebasen

Wie gehst du mit großen und komplexen Codebasen um?

Es ist wichtig zu wissen, wie du dich in komplexen Codebasen bewegst und effizient analysierst.

Antwort

Bei der Arbeit an Codebasen setze ich klare Abgrenzungen hinsichtlich der Projektgrößen: Codebasen von etwa 30.000 Zeilen sehe ich als kleinere Projekte an, während Projekte mit rund 1,5 Millionen Zeilen in den Bereich mittelgroßer Projekte fallen. Projekte, die darüber hinausgehen, bearbeite ich aktuell nicht. Mein Ansatz bleibt jedoch unabhängig von der Größe der Codebasis strukturiert und zielorientiert.

Wenn ich in ein neues Projekt einsteige, sehe ich mir zuerst die Gesamtstruktur an, konzentriere mich jedoch darauf, mir eine konkrete Aufgabe zuzuweisen oder zu erarbeiten. Diese Aufgabe dient als Zielsetzung für meine erste Analyse, sodass ich die Struktur mit einer klaren Richtung untersuchen kann. Ein wesentlicher Teil meiner Arbeit ist es auch, die Anforderungen des Kunden zu berücksichtigen: Möchte der Kunde, dass ich lediglich eine minimale Änderung vornehme, um ein spezifisches Problem zu lösen? Oder ist eine umfassendere Umstrukturierung gewünscht, um die Codequalität langfristig zu verbessern?

Bei der Analyse stelle ich mir folgende Fragen:

  • Wo beginnt der relevante Use-Case? Ich verfolge den Fluss des Codes, um die betroffenen Komponenten zu identifizieren.
  • Welche Transformationen oder Outputs werden erzeugt? Ich analysiere die Datenverarbeitung und wie die Daten durch das System fließen.
  • Sind Tests vorhanden? Tests helfen mir, den Funktionsumfang schneller zu verstehen und potenzielle Schwächen zu erkennen.
  • Gibt es potenzielle Nebenwirkungen? Ich prüfe, ob globale Variablen oder Zustände die Anwendung beeinflussen und zu unvorhergesehenen Fehlern führen könnten.
  • Welche Konfigurationsmöglichkeiten gibt es? Ich achte darauf, ob Schalter oder Parameter das Verhalten der Anwendung beeinflussen, insbesondere wenn mehrere Use-Cases abgedeckt werden müssen.
  • Wie sichere ich Änderungen ab? Bevor ich den Code modifiziere, prüfe ich, wie ich bestehende oder neue Tests zur Absicherung nutzen kann, um Regressionen zu vermeiden.

Durch diesen zielgerichteten Ansatz gelingt es mir, mich schnell in Codebasen unterschiedlicher Größe zurechtzufinden. Unabhängig von der Projektgröße konzentriere ich mich darauf, die Anforderungen des Kunden zu erfüllen – sei es durch minimale Änderungen oder durch größere Umstrukturierungen zur Verbesserung der Codequalität. Mein Fokus liegt dabei stets darauf, die Funktionalität genau zu verstehen und sicherzustellen, dass Änderungen sauber integriert und abgesichert werden.

Priorisierung Performance und Wartbarkeit

Wie priorisierst du Optimierungen, wenn es sowohl um Performance als auch um die Wartbarkeit des Codes geht?

Manchmal müssen Kompromisse zwischen Performance und Wartbarkeit gemacht werden. Diese Frage zeigt, wie du in diesen Situationen entscheidest und priorisierst.

Antwort

In meinen Projekten stehen Business Use Cases und eine vernünftige Performance im Mittelpunkt. Es handelt sich dabei nicht um Echtzeitanwendungen oder extrem optimierte Lösungen, sondern um Systeme, die eine solide Leistung erbringen und gleichzeitig gut wartbar bleiben müssen.

Bei Optimierungen ist für mich entscheidend, dass die Lesbarkeit und Wartbarkeit des Codes nicht darunter leiden. Typischerweise konzentriere ich mich auf Bereiche, in denen unnötige Speicheroperationen, ineffiziente Schleifen oder schlecht optimierte SQL-Abfragen die Performance beeinträchtigen. Auch die Parallelisierung von Aufgaben, um die Auslastung mehrerer CPU-Kerne zu verbessern, ist ein wichtiger Ansatz – allerdings nur, wenn der daraus resultierende Komplexitätszuwachs einen messbaren Mehrwert bringt.

Ein Beispiel aus meiner jüngsten Erfahrung: In einem Projekt verursachten ineffiziente SQL-Abfragen eine Laufzeit von 20 Minuten für einen bestimmten Use Case. Durch eine gezielte Optimierung der Abfragen konnte die Laufzeit auf 10 Sekunden reduziert werden – ohne die Lesbarkeit des Codes zu beeinträchtigen.

Für mich gilt, dass Optimierung kein Selbstzweck ist. Jede Verbesserung muss im Verhältnis zur steigenden Komplexität und dem erzielten Nutzen stehen. Besonders bei der Einführung von Parallelität achte ich darauf, dass sie nicht unnötig die Wartbarkeit erschwert. In der Regel handelt es sich bei Performanceproblemen nicht um eine einzelne Funktion, die den Engpass verursacht, sondern um ein Zusammenspiel mehrerer kleinerer Optimierungen, die gemeinsam eine signifikante Verbesserung bewirken.

Review Sicherheitsaspekte

Hast du in der Vergangenheit Sicherheitsaspekte in Ihren Code-Reviews berücksichtigt? Wenn ja, wie gehst du dabei vor?

Sicherheit ist ein wichtiger Aspekt in modernen Frameworks. Es ist wichtig zu wissen, ob du auch potenzielle Sicherheitslücken im Code erkennen und beheben kannst.

Antwort

Der Begriff Sicherheitsaspekte kann viele Bereiche umfassen. In meinen Code-Reviews konzentriere ich mich primär auf die Sicherheit innerhalb des Codes, insbesondere auf Schwachstellen, die durch unsichere Programmierpraktiken entstehen. Dabei geht es weniger um den Schutz des Systems vor externen Angriffen, sondern darum, die Sicherheit und Robustheit der internen Logik zu gewährleisten.

Zur Unterstützung nutze ich häufig statische Codeanalyse-Tools, die helfen, typische Sicherheitsprobleme frühzeitig zu identifizieren. Besonders achte ich auf:

  • Unsichere Sprachkonstrukte und veraltete Funktionen, die anfällig für Sicherheitslücken sind.
  • Buffer Overflows und Speicherzugriffsprobleme, wie Zugriffe auf bereits freigegebenen Speicher oder Null-Pointer-Dereferenzen.

Ein besonderer Fokus meiner Arbeit liegt auf der Prüfung des Codes, der externe Datenquellen oder Benutzereingaben verarbeitet. Ich achte darauf, dass alle externen Daten korrekt validiert werden, bevor sie in die interne Businesslogik einfließen. Dies stellt sicher, dass die innere Logik immer mit verlässlichen und geprüften Daten arbeitet, um ungewollte Effekte oder Sicherheitslücken zu verhindern.

Meine Reviews zielen darauf ab, sicherzustellen, dass die interne Logik sicher bleibt und nicht durch fehlerhafte oder unvalidierte Eingaben von außen beeinträchtigt wird.

Dokumentation eines Review

Wie dokumentierst du deine Erkenntnisse und Empfehlungen während eines Reviews, damit sie für das Team verständlich und umsetzbar sind?

Gute Kommunikation und klare Dokumentation sind entscheidend, um sicherzustellen, dass das Team deine Empfehlungen versteht und umsetzen kann. Diese Frage zielt darauf ab, deine Kommunikationsfähigkeiten zu beurteilen.

Antwort

Bei einem Review dokumentiere ich alle relevanten Erkenntnisse und Empfehlungen strukturiert, um sicherzustellen, dass sie für das Team verständlich und umsetzbar sind. Jede Problembeschreibung in meiner Dokumentation umfasst folgende Punkte:

  • Problembeschreibung: Eine klare und präzise Darstellung des identifizierten Problems, sodass das Team auf einen Blick versteht, worum es geht.
  • Lösungsansatz: Ein konkreter Vorschlag, wie das Problem behoben werden kann, inklusive technischer Details.
  • Begründung: Eine Erklärung, warum diese Lösung die beste ist, wobei ich sowohl auf technische als auch auf geschäftliche Anforderungen eingehe.
  • Code-Beispiel: Wo möglich, liefere ich einen konkreten Code-Ausschnitt, der die vorgeschlagene Lösung verdeutlicht. Dies hilft dem Team, die Umsetzung schneller und effizienter zu gestalten.

Ich passe den Detaillierungsgrad meiner Dokumentation an das Erfahrungsniveau des Teams an. Wenn das Team bereits viel Erfahrung mit der entsprechenden Technologie oder dem Problem hat, konzentriere ich mich auf die Kernpunkte und Lösungen. Ist das Team weniger erfahren, füge ich zusätzliche Erklärungen und Beispiele hinzu, um sicherzustellen, dass die Empfehlungen nachvollziehbar und umsetzbar sind.

Darüber hinaus dokumentiere ich, ob ich bereits beispielhafte Code-Änderungen vorgenommen habe, oder ob das Team die Umsetzung noch vornehmen muss. Dies sorgt für Transparenz und klare Verantwortlichkeiten.