Direkt zum Inhalt | Direkt zur Navigation

solving complex IT problems!

Benutzerspezifische Werkzeuge

Sie sind hier: Startseite / Blog / Agile Work

Agile Work

Software-Reviews – rechtfertigt hochwertige Software höhere Kosten?

Über unseren gesamten Software-Entwicklungsprozess hinweg finden immer wieder Reviews statt, angefangen bei der Analyse von Anforderungen über die passende Software-Architektur bis hin zu Code- und Testing-Analysen. Wir führen für unsere Kunden jedoch auch Audits ihrer Software damit sie eine Einschätzung für Weiterentwicklung und Betrieb ihrer Software erhalten.

Welchen Nutzen haben Software-Reviews?

Software-Reviews führen zu deutlich weniger Fehlern. Laut einer Untersuchung an 12-Tsd. Projekten durch Capers Jones [1] reduzieren sich diese

  • bei Requirements Reviews um 20–50%
  • bei Top-level Design Reviews um 30–60%
  • bei detaillierten funktionellen Design Reviews um 30–65%
  • bei detaillierten logischen Design Reviews um 35–75%

Die Studie kommt zu dem Ergebnis:

Schlechte Code-Qualität ist bis zum Ende der Code-Phase billiger; danach ist hohe Qualität billiger.
Kosten über die Entwicklungsphasen Anforderung, Design, coding, Testing und Betrieb hinweg

Dabei geht die Studie noch von einem klassischen Wasserfall-Modell aus von Anforderungen über Software-Architektur zunächst zu Code, dann zu Tests und Betrieb. Bei agiler Software-Entwicklung wiederholt sich dieser Prozess jedoch in vielen Zyklen, sodass wir beim Entwickeln der Software die meiste Zeit damit verbringen, die vorhandene Code-Basis zu ändern oder zu ergänzen. Daher müssen wir nicht nur die Änderungsanforderungen verstehen sondern auch den bereits vorhandenen Code. EIne bessere Code-Qualität erleichtert uns, die Funktionen unserer Anwendung zu verstehen und zu erkennen, wie die Änderungen sinnvoll umgesetzt werden. Wenn Code gut in separate Module unterteilt ist, kann ich mir viel schneller einen Überblick verschaffen als bei einer großen monolithischen Code-Basis. Weiter kann ich bei einer klaren Benennung schneller verstehen, was verschiedene Teile des Codes bewirken ohne ins Detail gehen zu müssen. Je schneller ich den Code verstehe und die gewünschte Änderung umsetzen kann, umso weniger Zeit benötige ich für die Umsetzung. Verschärfend kommt hinzu, dass sich die Wahrscheinlichkeit erhöht, dass ich einen Fehler mache. Um solche Fehler zu finden und zu beheben geht weitere Zeit verloren. Diese zusätzlichen Zeitaufwände werden üblicherweise als technische Schulden verbucht.

Umgekehrt kann ich vielleicht einen schnellen Weg finden, um eine gewünschte Funktion bereitzustellen, die jedoch den über die vorhandenen Modulgrenzen hinausgeht. Eine solche quick and dirty-Implementierung erschwert jedoch in den kommenden Wochen und Monaten die Weiterentwicklung. Auch bei agiler Software-Entwicklung ohne angemessene Code-Qualität können die Fortschritte nur am Anfang schnell sein, je länger kein Review stattfindet umso zäher wird die Weiterentwicklung sein. In vielen Diskussionen mit erfahrenen Kolleg*innen war die Einschätzung, dass bereits nach wenigen Wochen regelmäßige Reviews und Refactorings zu einer höheren Produktivitiät führen.

Welche Review-Arten lösen welche Probleme?

Es gibt unterschiedliche Möglichkeiten ein Review durchzuführen. Diese sind abhängig vom Zeitpunkt und den Zielen des Reviews.

Die Norm IEEE 1028 [2] legt die folgenden fünf Review-Arten fest:

Walkthroughs
Mit dieser statischen Analysetechnik entwickeln wir Szenarien und machen Probeläufe um z.B. Anomalien in den Anforderungen sowie alternative Implementierungsmöglichkeiten zu finden. Sie dienen uns zum besseren Verständnis des Problems, sie müssen jedoch nicht zu einer Entscheidung führen.
Technische Reviews
Diese fachlichen Prüfungen führen wir durch, um z.B. in Diskussionen alternative Software-Architekturen zu bewerten, Fehler zu finden oder technische Probleme zu lösen und zu einer (Konsens-)Entscheidung zu kommen.
Inspektionen
Diese formale Review-Technik nutzen wir z.B. um schnell Widersprüche in den Anforderungen, falsche Modulzuordnungen, ähnliche Funktionen o.ä. zu finden und diese möglichst frühzeitig beseitigen zu können. Häufig führen wir solche Inspektionen beim Pair-Programming durch wodurch zusätzlich noch weniger erfahrene Entwickler*innen schnell und praktisch geschult werden.
Audits
Häufig erstellen wir vor der Inbetriebnahme einer Kundensoftware in den Betrieb eine Bewertung ihres Software-Produkts in Bezug auf Kriterien wie Walk-Through-Berichte, Software-Architektur, Code- und Security-Analyse sowie Testverfahren.
Management-Reviews
Diese systematische Bewertung von Entwicklungs- oder Beschaffungsprozessen verwenden wir um einen Überblick über den Projektfortschritt zu erhalten und mit etwaigen Zeitplänen abzugleichen.

Kundenstimmen

Vielen Dank für die gute Arbeit. Wir sind sehr zufrieden mit dem Ergebnis!

– Niklas Kohlgraf, Projektmanagement, pooliestudios GmbH

Lasst Euch noch heute zu Software-Reviews von Cusy beraten:

Veit Schiele

Veit Schiele
Telefon: +49 30 22430082

Wir rufen Sie auch gerne an!

Jetzt anfragen


[1]Capers Jones: Software Quality in 2002: A Survey of the State of the Art
[2]IEEE Standard for Software Reviews and Audits 1028–2008

Leuphana-Universität Lüneburg: IT-Infrastruktur für Hackathons

Was ist ein Hackathon?

Das Wort Hackathon setzt sich zusammen aus den beiden Worten Hack und Marathon. Es ist eine kollaborative IT-Veranstaltung mit dem Ziel, gemeinsam Prototypen zu spezifischen Themen oder Problemen herzustellen.

Über die thematische Ausrichtung eines Hackathons können Bezüge zu den Lebenswelten der Teilnehmer*innen hergestellt werden. Sie erfahren, wie Probleme gemeinsam mit technischen Mitteln gelöst werden können. Häufig wurden Hackathons jedoch auch veranstaltet um kreativ Lösungswege zu finden. Schließlich führen sie auch zu einer Vernetzung der Teilnehmer*innen, auch wenn diese aktuell nur online möglich ist.

Nach dem erfolgreichen Hackathon der Bundesregierung WirVsVirus u.a. zusammen mit Code for Germany und Prototype Fund haben auch andere für sich Hackathons als geeignetes Veranstaltungsformat gefunden, so beispielsweise auch das Hochschulforum Digitalisierung mit ihrem SemesterHack.

Für den Lüneburg Hackathon 2020 mit bis zu 500 Teilnehmer*innen konzipierten wir nicht nur die IT-Infrastruktur sondern auch die Event-Begleitung mit folgenden Phasen:

  1. Setup mit 24h
  2. 14-tägiger Vorlauf mit 9h
  3. 3-tägiger Event mit 36h
  4. 14-tägiger Nachlauf mit 5h

Im Wesentlichen sahen wir die drei große Herausforderungen:

  • in kurzer Zeit uns eng mit den Veranstalter*innen der Leuphana-Universität Lüneburg abzustimmen
  • eine einfache Integration der verwendeten IT-Komponenten:
  • Jitsi als hochverfügbaren Cluster-Service bereitzustellen, mit dem die 500 Teilnehmer*innen gleichzeitig kommunizieren können

Wie läuft ein Hackathon ab?

Der typische Ablauf eines Online-Hackathons kann dann z.B. so aussehen:

  1. Begrüßung der Teilnehmer*innen und Kennenlernen im Mattermost Chat
  2. Vorstellung des Formats und Agenda des Hackathons mit Jitsi-Videokonferenz und Screensharing
  3. Kurze Impulsvorträge zu den wichtigsten Tools, Daten und thematischen Schwerpunkten
  4. Brainstorming mit GitLab Kanban-Boards
  5. Gruppenbildung mit jeweils eigenen Kanban-Boards, Git-Repositories, Mattermost-Channels und ggf. Entwicklungsumgebungen auf Basis von Jupyter Notebooks.
  6. Präsentationen mit Jitsi-Videokonferenzen und ggf. Jupyter Notebooks im Präsentationsmodus

Welche Hackathons gibt es in Deutschland?

Jugend hackt
Ihr Motto ist Mit Code die Welt verbessern und soll einen verantwortungsbewussten Umgang mit Technik fördern um Lösungen für gesellschaftspolitische Fragen zu finden. Es ist ein nicht-gwinnorientiertes Programm der gemeinnützigen Vereine Open Knowledge Foundation Deutschland e.V. und mediale pfade.org.
Coding da Vinci
Seit 2014 vernetzt Coding da Vinci technikaffine und kulturbegeisterte Communities mit deutschen Kulturinstitutionen, um offene Kulturdaten zu erhalten.
Science Hack Day Berlin
Der Science Hack Day Berlin wird von Freiwilligen aus den Bereichen Wissenschaft, Design, IT, Ingenieurwesen und Kommunikation organisiert.
Wikimedia Hackathon
Die Wikimedia Hackathons werden veranstaltet um um die technologische Infrastruktur von Wikipedia und anderen Wikimedia-Projekten, insbesondere der ihnen zugrunde liegenden MediaWiki-Plattform zu verbessern.

Falls Ihr nun selbst einen Hackathon veranstalten möchtet, so kann Cusy auch Euch mit der passenden IT-Infrastruktur und Support unterstützen.

Lasst Euch beraten

Ich berate Euch gerne und erstelle ein passgenaues Angebot für IT-Infrastruktur und Support bei einem Hackathon.

Veit Schiele

Veit Schiele
Telefon: +49 30 22430082

Wir rufen Sie auch gerne an!

Jetzt anfragen

Sind Jupyter Notebooks produktionsreif?

Sind Jupyter Notebooks produktionsreif?

Jupyter Notebook

In den letzten Jahren gab es einen rasanten Anstieg in der Verwendung von Jupyter Notebooks festgestellt, s.a. Octoverse: Growth of Jupyter Notebooks, 2016-2019. Hierbei handelt es sich um eine von Mathematica inspirierte Anwendung, die Text, Visualisierung und Code in einem Dokument kombiniert. Jupyter-Notebooks werden von unseren Kunden häufig für das Prototyping und die Erforschung von Analysen und maschinellem Lernen verwendet. Wir haben jedoch auch gesehen, dass die wachsende Popularität auch dazu beigetragen hat, dass Jupyter-Notebooks in anderen Bereichen der Datenanalyse verwendet wird und zusätzliche Werkzeuge genutzt wurden, um mit ihnen auch umfangreiche Berechnungen durchzuführen.

Zum Erstellen von skalierbarem, wartbarem und langlebigem Produktionscode erscheinen uns Jupyter Notebooks jedoch meist ungeeignet. Zwar lassen sich mit einigen Tricks Notebooks sinnvoll versionieren und es lassen sich auch automatisierte Tests ausführen, bei komplexeren Projekten wird die Vermischung von Code, Kommentaren und Tests jedoch zum Hindernis: Jupyter Notebooks lassen sich nur unzureichend modularisieren. Zwar können Notebooks als Module importiert werden, diese Möglichkeiten sind jedoch äußerst beschränkt: so müssen die Notebooks zunächst vollständig in den Speicher geladen und ein neues Modul erstellt werden, bevor jede Zelle in diesem ausgeführt werden kann.

In der Folge kam es zum ersten Notebook-Krieg, s. The First Notebook War, der im Wesentlichen ein Konflikt zwischen Data Scientists und Software Engineers war.

Wie können die Gräben überwunden werden?

Notebooks erfreuen sich bei Data Scientists rasch wachsender Beliebtheit und werden zum De-facto-Standard für rapid Prototyping und explorative Analysen. Vor allem Netflix hat jedoch ein umfangreiches Ökosystem von zusätzlichen Tools und Services erstellt, wie z.B. Genie und Metacat. Diese Tools vereinfachen die Komplexität und unterstützen einen breiteren Anwenderkreis von Analysten über Wissenschaftler bis hin zu Informatikern. Im Allgemeinen hängt jede dieser Rollen von verschiedenen Tools und Sprachen ab. Oberflächlich betrachtet scheinen die Workflows unterschiedlich, wenn nicht komplementär zu sein. Auf einer abstrakteren Ebene jedoch haben diese Workflows mehrere überlappende Aufgaben:

Datenexploration

tritt früh in einem Projekt auf

Dies kann das Anzeigen von Beispieldaten, die statistische Profilerstellung sowie die Datenvisualisierung umfassen

Datenaufbereitung

iterative Aufgabe

kann das Bereinigen, Standardisieren, Transformieren, Denormalisieren und Aggregieren von Daten umfassen

Datenvalidierung

wiederkehrende Aufgabe

kann das Anzeigen von Beispieldaten, das Ausführen von Abfragen zur statistischen Profilerstellung und aggregierten Analyse sowie das Visualisieren von Daten umfassen

Produkterstellung

tritt spät in einem Projekt auf

Dies kann das Bereitstellen von Code für die Produktion, Schulungsmodelle und das Planen von Workflows umfassen

Ein JupyterHub kann hier schon gute Dienste leisten um diese Aufgaben möglichst einfach und überschaubar zu gestalten. Dabei ist es skalierbar und reduziert die Anzahl der Tools erheblich.

Um zu verstehen, warum Jupyter-Notebooks für uns so überzeugend sind, heben wir noch einmal ihre Kernfunktionalitäten hervor:

  • Ein Messaging-Protokoll zum Prüfen und Ausführen von sprachunabhängigem Code
  • Ein bearbeitbares Dateiformat zum Beschreiben und Erfassen von Code, Code-Ausgabe und Markdown-Notes
  • Eine webbasierte Benutzeroberfläche zum interaktiven Schreiben und Ausführen von Code sowie zur Datenvisualisierung

Use Cases

Von unseren zahlreichen Anwendungsfällen verwenden wir Notebooks heute am häufigsten für Datenzugriffe, Parametrisierung und Workflow-Planung.

Datenzugriffe

Notebooks wurden von uns erstmals eingeführt, um Data-Science-Workflows zu unterstützen. Als die Akzeptanz zunahm, sahen wir die Möglichkeit, die Vielseitigkeit und Architektur von Jupyter-Notebooks auch für den allgemeinen Datenzugriff nutzen zu können. Mitte 2018 begannen wir damit, die Notebooks von einem Nischenprodukt zu einer universellen Datenplattform auszubauen.

Aus Sicht der Benutzer bieten Notebooks eine komfortable Oberfläche für die iterative Ausführung von Code, das Durchsuchen und Visualisieren von Daten – alles in einer einzigen Entwicklungsplattform. Aufgrund dieser Kombination aus Vielseitigkeit, Leistung und Benutzerfreundlichkeit haben wir eine schnelle Akzeptanz für viele Benutzergruppen auf der gesamten Plattform festgestellt.

Paremtrisierte Notebooks

Einhergehend mit der zunehmenden Akzeptanz haben wir weitere Funktionen für weitere Anwendungsfälle eingeführt. Aus dieser Arbeit gingen einfach parametrisierbare Notebooks hervor. Dies bot unseren Nutzern einen einfachen Mechanismus um Notizbücher als wiederverwendbare Vorlagen zu definieren.

Workflow-Planung

Als weiteren Einsatzbereich von Notebooks haben wir die Planung von Workflows entdeckt. Sie haben u.a. folgende Vorteile:

  • Notebooks erlauben einerseits interaktives Arbeiten und rapid Prototyping, um anschließend fast reibungslos in den Produktivbetrieb überführt werden zu können. Evtl. werden die Notebooks modularisiert und als vertrauenswürdig gekennzeichnet.
  • Ein weiterer Vorteil von Notebooks sind die unterschiedlichen Kernel, sodass die sich Benutzer die jeweils passende Ausführungsumgebung auswählen können.
  • Zudem sind Fehler in Notebooks einfacher nachzuvollziehen da sie bestimmten Zellen zugeordnet sind und die Ausgaben gespeichert werden können.

Logging

Um Notebooks nicht nur für Rapid Prototyping sondern auch dauerhaft produktiv verwenden zu können, müssen bestimmte Prozesseereignisse protokolliert werden, sodass z.B. Fehler einfacher diagnostiziert und der Gesamtprozess überwacht werden kann. Hierfür kann in IPython Notebboks das logging-Modul der Python-Standardbibliothek oder loguru verwendet werden, s.a. Jupyter-Tutorial: Logging.

Tests

Es gab schon früher einige Ansätze, mit denen sich Notebooks automatisiert testen ließen, z.B. nbval, aber erst mit ipytest wurde das Schreiben von Tests für Notebooks deutlich vereinfacht, siehe auch Jupyter-Tutorial: ipytest.

Re­sü­mee

In den letzten Jahren förderten wir die enge Zusammenarbeit von Software Engineers mit Data Scientists um zu skalierbarem, wartbarem und produktionsfähigem Code zu gelangen. Gemeinsam haben wir Lösungen gefunden, die produktionsreife Modelle auch für Machine Learning-Projekte bereitstellen können.

Microservices – Definition

Der Begriff »Microservice-Architektur« ist in den letzten Jahren entstanden um Softwareanwendungen, die in eigenständig einsetzbare Dienste unterteilt sind, zu beschreiben. Obwohl es keine exakte Definition des Begriffs gibt, so sind doch einige Organisationsmerkmale, wie automatisierte Bereitstellung und dezentrale Datenhaltung allen gemeinsam.

Microservices, wie wir sie verstehen, unterteilt eine einzelne Anwendung in eine Reihe von kleinen Diensten, die jeweils als eigenständiger Prozess laufen und leichtgewichtig miteinander kommunizieren, oft über eine HTTP-Resource-API. Diese Dienste implementieren Geschäftsprozesse, die unabhängig und automatisiert einsetzbar sind. Die zentrale Verwaltung dieser Dienste wird auf ein Minimum reduziert und kann in unterschiedlichen Programmiersprachen geschrieben sein und unterschiedliche Speichertechnologien nutzen.

Abgrenzung gegen Monolithen

Die Idee der Microservices ist entstanden aus der Abgrenzung zu monolithischer Software, die verschiedene Geschäftsprozesse in einer Anwendung zusammenfasst. Genauer gesagt werden diese Monolithen üblicherweise in einer Schichtenarchitektur mit drei oder vier Schichten konzipiert:

  1. eine Benutzeroberfläche bestehend aus HTML-Seiten und Javascript, die in einem Browser dargestellt wird
  2. einer meist relationalen Datenbank bestehend aus vielen Tabellen
  3. und einer serverseitigen Anwendung die HTTP-Anfragen beantwortet, dazu fachdomänspezifische Logik ausführt und Daten aus der Datenbank aufruft und aktualisiert.

Bei einer solchen monolithischen Anwendung läuft die Logik für die Bearbeitung einer Anforderung meist in einem einzigen Prozess und für die grundlegenden Funktionen wird nur eine Programmiersprache verwendet. Die Anwendung wird dann durch Klassen, Funktionen und Namespaces aufgeteilt. Meist kann eine solche Anwendung auf dem Laptop des Entwicklers ausgeführt und getestet und eine Deployment-Pipeline verwendet werden, um sicherzustellen, dass Änderungen ordnungsgemäß getestet und in die Produktion überführt wurden. Sie können die Monolithen horizontal skalieren indem Sie viele Instanzen hinter einem Load Balancer laufen lassen.

Solche monolithischen Anwendungen wurden jahrelang von uns erfolgreich betrieben, aber sie fingen zunehmend an, uns zu frustrieren, und zwar bei den folgenden Szenarien:

  • Änderungszyklen müssen aufwändig koordiniert werden, d.h. selbst wenn nur ein kleiner Teil der Anwendung geändert werden soll, muss meist der gesamte Monolith neu gebaut und in Betrieb genommen werden.
  • Zudem wird es im Laufe der Zeit immer schwerer, eine gute modulare Struktur aufrechtzuerhalten, so dass bei Änderungen wirklich nur ein Modul betroffen ist.
  • Schließlich führt Skalierung immer dazu, dass die gesamte Anwendung repliziert werden muss, anstatt nur diejenigen Teile zu replizieren, die tatsächlich unter Last stehen und mehr Ressourcen erfordern.
Microservices

Eine monolithische Anwendung liefert alle Funktionalität in einem Prozess …

Skalierung von Microservices

… und skaliert durch Replikation des Monolithen auf mehreren Maschinen.

Um solche Frustrationen zu vermeiden, setzen wir seit vielen Jahren Microservices-Architekturen ein, die Anwendungen in einzelne Dienste unterteilt. Diese Services sind nicht nur unabhängig voneinander implementierbar und skalierbar, sondern bieten auch feste Kontextgrenzen, so dass unterschiedliche Dienste auch in der jeweils geeigneten Programmiersprache geschrieben und von verschiedenen Teams entwickelt und betreut werden können.

Monolith

Bei einer Microservices-Architektur wird jedes Funktionselement in einem separaten Service ausgeliefert …

Skalierung von Monolithen

… und skaliert durch die Verteilung dieser Dienste über Server, repliziert nach Bedarf.

Dabei erschienen uns Microservices gar nicht besonders neuartig oder innovativ – sie erinnerten uns vielmehr an eines der Designprinzipien von Unix:

Mache nur eine Sache und mache sie gut.

Dieses Designprinzip ist jedoch in monolithischen Anwendungen nicht berücksichtigt worden.

Technische Schulden

Wir entwickeln meist in kurzen Zyklen die von unseren Kunden angefragte Funktionalität. Meistens räumen wir unseren Code auch nach mehreren Zyklen auf wenn sich die Anforderungen kaum noch ändern. Manchmal jedoch muss auch der schnell entwickelte Code in die Produktion übernommen werden. Technische Schulden ist diesbezüglich eine wunderbare Metapher, die von Ward Cunningham eingeführt wurde um über solche Probleme nachzudenken. Ähnlich wie finanzielle Schulden können technische Schulden zur Überbrückung von Schwierigkeiten verwendet werden. Und ähnlich wie bei finanziellen Schulden sind bei technischen Schulden Zinsen zu bezahlen, nämlich in Form von zusätzlichen Anstrengungen um die Software weiterzuentwickeln.

Im Gegensatz zu finanziellen Schulden lassen sich technische Schulden jedoch sehr schwer beziffern. Wir wissen zwar, dass sie die Produktivität eines Teams bei der Weiterentwicklung der Software behindern, aber wir uns fehlen die Berechnungsgrundlagen, auf denen diese Schuld beziffert werden könnte.

Um technische Schulden zu beschreiben, wird meist unterschieden zwischen bewussten und versehentlich eingegangenen technischen Schulden sowie zwischen umsichtigen oder waghalsigen Schulden. Daraus ergibt sich der folgende Quadrant:

  versehentlich überlegt
umsichtig »Nun wissen wir, wie wir es machen sollten!« »Wir müssen jetzt liefern und mit den Konsequenzen umgehen.«
waghalsig »Was ist Software-Design?« »Wir haben keine Zeit für Software-Design!«

Zum Weiterlesen