aus dem Netzwerk Insider September 2023
Der Computer-Nerd in Hollywood-Filmen ist ein stark verkürztes Klischee: Komplexe und komplizierte Software zu entwickeln erfordert ausgeprägte Kreativität und Virtuosität, die man als Persönlichkeitsmerkmale sicher eher Musikern oder Schauspielern zuschreiben würde. Dennoch: Wenn Sie Programme entwickeln, sind Sie Welten-Erschaffer, Drehbuchautor, Schauspieler, Regisseur und Cutter in einer Person! − Na, wenn das mal keinen Spaß macht!
Ausräumung eines hartnäckigen Missverständnisses
Heute ist die ganze Welt computergesteuert – und das ist erst der Anfang. Ohne Software jedoch sind Computer lediglich tote, nutzlose Materie. Die Geschichte der Programmierung ist spannend, Software-Erstellung selbst allerdings komplex, anspruchsvoll und, insbesondere von außen betrachtet, mehr als verwirrend. Tatsächlich?
Was wohl kaum ein User glauben mag: Auch der Prozess der Software-Entwicklung selbst ist heute tatsächlich eine sehr spannende, faszinierende und persönlich herausfordernde Tätigkeit, die höchste Anforderungen an die Fähigkeiten und das in gewisser Weise doch sehr „spezielle“ Wissen und Wesen der Entwickler stellt. Ja, ich weiß: „spannend“ ist relativ, doch glauben Sie mir: Mit „spannend“ meine ich auch „spannend“. Und ich bin seit jeher ein extrem interdisziplinärer Mensch, der weit über IT-Horizonte hinausblickt und hinausblicken kann. IT ist schließlich kein Selbstzweck!
Hinzu kommen geradezu die Eigenschaften solider Olympioniken: Hartnäckigkeit, Ausdauer, Frustrationstoleranz, Experimentierfreude, Selbstüberwindung und leider auch ganz viel Selbstdisziplin. Diese sind in fast allen Prozessphasen der Software-Entwicklung erforderlich und müssen stets abrufbar sein.
Heutige IT ist zu 50 % Psychologie – wirklich?
Die unerfreuliche Nachricht vorneweg, gerade auch aus User-Sicht: Die Komplexität heutiger Softwareprojekte ist parallel zu der von Software selbst enorm gestiegen, nicht zuletzt durch die riesige Auswahl an Plattformen, Endgeräten, Tools und Frameworks, den für User unsichtbaren Entwickler-Werkzeugkasten, dessen Komponenten und Inhalte ebenfalls ständig aktualisiert und funktional erweitert werden. Das Problem des Testens von Software sowie der Fehlerfindung und -beseitigung ist dadurch nicht gerade einfacher geworden, ganz im Gegenteil. Ein Grund von vielen ist darin zu sehen, dass die meisten erstellten bzw. zu erstellenden Softwareprodukte einerseits aus Zeitgründen stark „unter-dokumentiert“ sind, sich jedoch andererseits durch immer neue Updates und Upgrades (Releases) schnell ändern, da der User-Anspruch zu Recht ebenfalls stark angestiegen ist:
Aus puristischen Textein- bzw. -ausgaben und „plattem 2D“ früherer Jahre wurde im Laufe der Zeit ganz selbstverständlich eine ausdifferenzierte grafische Benutzeroberfläche (GUI) mit überbordenden 3D-Effekten, über die niemand mehr sprechen muss, sondern die schlicht vorausgesetzt werden, doch enorme Anforderungen an Hard- und Software stellen. Hierunter fallen zum Beispiel ruckelfrei scrollbare Listen bei inzwischen 90 Einzelbildern (Frames) pro Sekunde, wie sie heute nahezu jedes Smartphone problemlos realisiert. Zum Vergleich: Ab spätestens 25 Bildern pro Sekunde sieht unser Gehirn keine Einzelbilder-Sequenz mehr, sondern einen kontinuierlichen Film. Das war die zentrale Idee dieser genialen Erfindung im Jahr 1888, dem Erscheinungsjahr des allerersten Films. Doch das gilt noch heute: Für den User scrollt, also verschiebt sich die Liste auf dem Display, tatsächlich wird sie jedoch 90-mal pro Sekunde um wenige Pixel vertikal versetzt völlig neu(!) auf das Display gezeichnet. Selbst „Buttons“ z.B. sind reine Illusion, denn sie sind faktisch nur reaktionsfähige Pixelhaufen. Moderne IT besteht zu 50 % aus Psychologie im Sinne der Überlistung unserer menschlichen Wahrnehmungsfähigkeit.
Das ist uns als Dauer-IT-Nutzer seltsamerweise kaum bewusst.
Bugfixing ist für Entwickler wie atmen
Der Begriff „Bug“ kommt aus Zeiten, als noch mechanische Computer mit sich einnistenden Käfern zu kämpfen hatten: den Bugs eben. Dass er sich gerade im Softwarekontext etabliert hat und heute schlicht für Programmfehler steht, ist ein vielsagender Zusammenhang.
Zum Thema „Unterdokumentiertheit“: Entwickler stehen ständig unter Strom, müssen ihre Kapazitäten zu 80 % zur Programmierung selbst verwenden und haben somit kaum Zeit zur Dokumentation ihrer Software: wie genau sie funktioniert, welche Algorithmen (Lösungsverfahren) implementiert sind, welche Zusammenhänge es zwischen den Code-Blöcken gibt, welche Programmiertricks angewendet wurden etc. Dies stellt ein riesiges, nie vollständig lösbares Wissensmanagement-Problem dar. Anders ausgedrückt: Die ganz normale personelle Fluktuation, andernorts noch mit überschaubaren Aufwänden zu kompensieren, kann hier im echten Desaster und im finanziellen Fass ohne Boden enden! – Entwickler weg, Software tot. Um dies wirkungsvoll zu verhindern oder zumindest das Problem signifikant zu entschärfen, benötigt man auch auf den Führungsebenen solides IT-Basiswissen sowie eine funktionierende Personalführung und -entwicklung. Sonst führen Fehlentscheidungen und -vorgaben eher noch zu einer Dramatisierung der grundsätzlichen IT-Problematik. Ich spreche aus Erfahrung.
Infolge ist die Fehlersuche das täglich Brot des Software-Entwicklers. 20-30 % seiner Zeit darf er sich ihr widmen – mindestens. Fehler und deren Eliminierung sind in der Softwarebranche somit keine Ausnahme, sondern die Regel! Ach ja: Vor jeglicher Fehlerdetektion geschweige denn -beseitigung kommt stets das außerhalb der IT-Szene kaum bekannte, doch enorm zeitaufwändige Problem der Fehler-Rekonstruktion: Das möglichst exakte und mehrfach identische Nachstellen derjenigen Situation, in der ein User oder man selbst einen Fehler wahrgenommen bzw. berichtet hat. Nun ist es Usern nicht immer oder eigentlich fast nie möglich, den gesamten Kontext eines beobachteten Softwarefehlverhaltens präzise zu beschreiben. Das ist ihnen auch kaum zuzumuten.
Wie jedoch soll man die Ursache eines Phänomens ergründen, das man selbst gar nicht kennt, sieht und nachvollziehen kann? Um in diesem dynamischen Umfeld erfolgreich zu sein, ist ein präventives und praktikables, also hochprofessionelles Wissensmanagement unerlässlich. Dieses muss es den Entwicklern ermöglichen, sich schnell in neue Technologien einzuarbeiten, bestehende Lösungen zu verbessern und ihr Werk angemessen umfangreich und nachvollziehbar chronologisch zu beschreiben – wohlgemerkt für sich selbst und andere, vielleicht nachfolgende Entwickler. Wir sprechen hier nicht von der User-Dokumentation, dem sogenannten Manual. Überhaupt gilt (zumindest statistisch), dass Software-Entwickler am liebsten Software entwickeln und darüber hinaus relativ wenig tun wollen.
Grenzen des menschlichen Denkvermögens überschreiten
Merke: Wenn Entwickler – und IT-Leute generell – stundenlang in den Monitor starren, ohne ein einziges Mal auf die Tastatur zu hämmern, sind sie nicht hundemüde, sondern befinden sich vor ihrem geistigen Auge gerade inmitten hochkomplexer IT- oder eben speziell Softwarewelten. Ein Film läuft vor ihrem geistigen Auge ab, in dem sie ihr eigenes Programm in seinem Ablauf „virtuell“, sprich gedanklich nachvollziehen. Das ist für diese ganz besondere Arbeitnehmer-Spezies spannender als jeder Spielfilm. Da können noch so gewaltige Saurier den Kinosaal zum Beben bringen – Bits und Bytes, die man nach der eigenen Pfeife tanzen lassen kann, sind und bleiben unschlagbar.
Software-Entwickler sind eben nicht nur rational-nüchtern-technische Experten, sondern auch kreative, sensitive und psychologische
Wesen, die ihre Arbeit mit Leidenschaft und Engagement ausführen wollen. Gute Programme können geradezu ästhetisch, schön und anmutig sein, so wie klassische Musik! Entwickler brauchen im Idealfall also einen optimalen, im Realfall wenigstens praktikablen Projektrahmen, der ihnen sowohl klare Vorgaben als auch genügend Freiheiten bietet, um ihre Ideen wirkungsvoll umzusetzen. Eine der größten Herausforderungen für Software-Entwickler ist jedoch die Aufwandsschätzung, die oft zu optimistisch und realitätsfremd ausfällt. Zur Verteidigung: Der Mensch ist generell nicht dafür geschaffen, die exorbitante Komplexität von Software und damit auch Softwareprojekten zu erfassen und zu quantifizieren.
Ständig muss man sich zudem mit programmiertechnischen Nebenkriegsschauplätzen auseinandersetzen, die mit den Kernaufgaben gar nichts zu tun haben. Hinzu kommt abermals, dass die Softwareindustrie von immer kürzeren Innovationszyklen geprägt ist, die ständig neue Anforderungen und Möglichkeiten schaffen. Dies führte in der Vergangenheit zu einem unglaublichen Prozentsatz fehlgeschlagener IT- und dabei insbesondere Software-Projekte. Eine lange Lernkurve auf Basis inzwischen etablierter Projektmodelle führt heute mit bestimmten Mitteln und Methoden zu spürbar besseren Projektergebnissen.
Werkzeugkasten und Waffenarsenal von Software-Entwicklern
Um mit derartigen generischen Herausforderungen umzugehen und zugehörige Probleme zu umgehen, haben sich zahlreiche zeitsparende Automatisierungskonzepte wie DevOps und CI/CD etabliert, die den Entwicklungsprozess beschleunigen und vereinfachen sollen. DevOps – das Spannungsfeld zwischen Entwicklung und Betrieb von Software – und CI/CD – kontinuierliche Erstellung und Auslieferung von Software – sind zwei wichtige Konzepte für die moderne Software-Entwicklung. DevOps ist eine Kultur, die auf effizientere und schnellere Entwicklung und Bereitstellung von Software abzielt. CI/CD ist eine Methode, die auf Automatisierung und Überwachung von allen Phasen des Software-Lebenszyklus basiert. CI/CD ermöglicht es den Entwicklern, neue Code-Änderungen kontinuierlich zu integrieren, zu testen und zu verteilen. Mit DevOps und CI/CD können Software-Teams qualitativ hochwertige Produkte liefern, die den Kundenbedürfnissen entsprechen. Auf den Punkt gebracht: Entwickler und Anwender müssen sich als Akteure derselben komplexen Prozesse verstehen, die konsistent ablaufen müssen und die es permanent zu optimieren gilt. Zyklisch wiederkehrende Standardprozesse sind dabei (natürlich!) weitestgehend zu automatisieren. − Der CI/CD-Begriff ist übrigens nicht mit der gleichlautenden Abkürzung aus dem Marketing-Bereich zu verwechseln, die für die Identität, also das Selbstverständnis, und die daraus resultierende Außendarstellung einer Organisation steht.
Auch in der Software-Entwicklung gibt es zum Beispiel die sogenannte „Containerisierung“, durch die die Logik des Quellcodes in mundgerechte Happen portioniert wird, denn schon die alten Römer wussten: Divide et impera! Teile und herrsche! Mit anderen Worten: Wenn jedes Code-Fragment (jede Provinz) im Griff ist, ist auch das gesamte Programm (das Imperium) im Griff. Simpel, jedoch zutreffend. Scheinbar infantil wird es dann beim „Sandboxing“, also wörtlich beim Spielen im Sandkasten: Software muss bei jeder Testinstallation eine unberührte Hardware- und Betriebssystem-Umgebung vorfinden, da man sonst unerwünschte, verfälschende Nebeneffekte erhält. Leider hinterlässt jede Software-Installation per Definition kaum vollständig zu beseitigende Spuren auf der Ziel-Hardware, die insbesondere auch nach vermeintlich kompletter Deinstallation noch subtil vorhanden sind und Einfluss auf die durchzuspielenden Testszenarien nehmen. Der Test wird dadurch ad absurdum geführt. Daher verpasst man der Software im Entwicklungsprozess einen mittels diverser technischer Finessen realisierten und abgeschlossenen „virtuellen Sandkasten“, in dem sie sich ohne Seiteneffekte nach Herzenslust austoben kann. Da soll noch einer sagen, Software-Entwicklung sei nüchtern, langweilig und lebensfremd.
Die objektorientierte Programmierung (OOP) ist ebenfalls ein inzwischen zwar nicht mehr ganz junges, doch nach wie vor faszinierendes und zu seiner Entstehungszeit vor rund 30 Jahren letztlich revolutionäres Konzept, das sich am omnipräsenten Vererbungsprinzip der Natur orientiert und ebenso u.a. konsequent das Prinzip „Teile und herrsche“ anwendet. Man kann dabei als Entwickler in seinem Programm (sagen wir in einem zu programmierenden IT-Verkehrsleitsystem) beispielsweise festlegen, was ein „Fahrzeug“ ist und kann von diesem z.B. ein konkreteres Objekt „Kraftfahrzeug“ ableiten, das sich wiederum in LKWs und PKWs gliedert und somit immer weiter ausdifferenziert. Jeder „Bauplan“ erbt die Eigenschaften und Fähigkeiten des Mutterobjekts, wobei es spezifische Merkmale hinzudefiniert oder auch gezielt abändert. Anschließend werden die Objekte im laufenden Programm „zum Leben erweckt“, in dem ihnen dynamisch einige Bytes Hauptspeicher zugewiesen werden. Nun „leben sie“ gefühlt tatsächlich und kommunizieren munter untereinander, mit Tausenden von Botschaften pro Sekunde. Heutige Apps beherbergen zum Teil Hunderte solcher Objekte, genauer Objektklassen. − Ist das nicht beindruckend?
Qualitätsmerkmale von Unsichtbarem
Dennoch gilt auf der anderen Seite: Software ist zu 100 % immateriell (USB-Sticks z.B. sind nur beliebige Datenträger) und kann daher auf vielfältige Weise modelliert, strukturiert und wiederverwendet werden (Konzept der Re-Usability). Zugleich wird durch OOP die Programm-Übersichtlichkeit und damit -Beherrschbarkeit deutlich verbessert. Die Fortschritte in den Entwicklungsprozessen und auch bei den Programmier-Paradigmen selbst sind für Nicht-IT-ler kaum realistisch zu bewerten, da sie per se nicht sichtbar oder greifbar sind, so wie Software selbst auch. Das ist das Gemeine: Bei Gebäuden erkennt man am entstehenden Dachstuhl, dass das Haus bald fertig ist. Bei Software erkennt man von außen exakt gar nichts.
Auch der Begriff „Software-Qualität“ spricht sich leicht aus, ist jedoch ein vielschichtiges und teils subjektives Konzept, das von vielen Faktoren abhängt. Es gibt rund 50 Software-Qualitätsmerkmale, darunter Robustheit, Latenzen (Verzögerungszeiten jeglicher Art), Universalität, Anpassungsfähigkeit und Transaktionssicherheit. Letzteres bedeutet: Alle Operationen müssen im Fehlerfall, z. B. nach nur einer Hundertstelsekunde Internetausfall, vollständig und sozusagen rückstandslos rückabgewickelt werden, nach dem Motto: ganz oder gar nicht, ein bisschen schwanger darf es nicht geben. All diese Merkmale müssen je nach Kontext und Zielgruppe unterschiedlich gewichtet und erfüllt werden.
Software-Entwicklung ist daher tatsächlich eine Kunst und eine Wissenschaft zugleich, die ständige Lernbereitschaft, Flexibilität und Kommunikation erfordert. Von der heute selbstverständlich vorausgesetzten Fähigkeit einer jeden Software, sich bei Textausgaben an alle rund 7000 zwischenmenschlichen Sprachen dieser Welt anpassen zu können, wollen wir hier gar nicht erst anfangen zu reden – Stichwort Internationalisierung, oh ja, ein breites IT-Subthema für sich.
Programmiersprachen – unendliche Weiten …
Im Folgenden werde ich einige spannende Themen rund um die Welt der Programmiersprachen vorstellen und wichtige Aspekte anschneiden. Programmiersprachen sind bekanntlich die Werkzeuge, mit denen wir Software überhaupt erst formulieren können, die wiederum verschiedene Probleme lösen oder Bedürfnisse erfüllen. Es gibt viele unterschiedliche Arten sogenannter Hochsprachen, die sich in ihrer Evolution und Klassifizierung, ebenso in ihren Philosophien, Verwandtschaften und Anwendungsgebieten unterscheiden, und das teils massiv. In Hochsprachen verfasste Programme werden in die Sprache der ausführenden Mikroprozessoren übersetzt, die sogenannte Maschinensprache. Wussten Sie, dass es über 1000(!) Programmiersprachen gibt? Deren Stammbaum mutet wie der breite verschlungene Stammbaum eines alten ehrwürdigen Adelsgeschlechts an.
Einige davon sind sehr populär und weitverbreitet, wie zum Beispiel „Java“ (umgangssprachlicher Begriff für Kaffee, den laut Legende die Java-Entwickler inflationär tranken, daher das bekannte Logo der dampfenden Kaffeetasse), „Python“ (benannt nach der britischen 70er-Comedian-Truppe namens Monty Python, nicht etwa nach der gleichnamigen Schlangengattung) oder „C#“ (sprich: „see-sharp“), eine der wichtigsten modernen Universalsprachen der sogenannten C-Familie, (fort)entwickelt unter der Ägide von Microsoft. Andere Sprachen sind eher exotisch oder spezialisiert, wie zum Beispiel „R“ für statistische Berechnungen, „Prolog“ oder gar „Haskell“, eine geradezu faszinierende Sprache. Die Art ihrer Nutzung und Programmierung ist zum Teil enorm unterschiedlich, viel tiefgehender, als wenn Sie z. B. die italienische versus die koreanische Sprache erlernen möchten. Computersprachen weisen wie auch zwischenmenschliche Sprachen ein bestimmtes Vokabular und eine spezifische Grammatik auf. Überhaupt sind die Parallelen zu unserer menschlichen Sprachenwelt frappierend, sogar Dialekte gibt es. Informationstechnologie und Biologie sind verwandt!
Zudem weisen Computersprachen einen erheblichen Unterschied im für Entwickler so wichtigen Abstraktionsgrad auf, auch wenn Abstraktion selbst ein abstrakter Begriff ist: Die altgediente, jedoch immer noch vielgenutzte, universelle Sprache ‚C‘ beispielsweise ist und arbeitet extrem Hardware-nah, und daraus entstandene Programme sind extrem schnell und effizient. Sie ist perfekt zur Programmierung von Maus- oder Druckertreibern, also „schlanken“ Programmen zur Übersetzung der jeweiligen Geräte-Datenströme in ein Windows-kompatibles Format, sofern dies das gerade installierte Betriebssystem ist. Für große User-Apps heutigen Maßstabs und Anspruchs hingegen ist C völlig ungeeignet. Java zum Beispiel erlaubt es andererseits umfassende und komplexe „Harry-Potter“-artige Objektwelten zu definieren, um die reale Welt mit den Ihnen bekannten zahlreichen ausdifferenzierten Geschäftsprozessen adäquat abzubilden. Erstaunlich: Dies ist seit Jahrzehnten die Normalität! Software-Entwickler sind heute quasi Erschaffer von Harry-Potter-Welten mit Hunderten von Objekten (Subjekten?), die eng miteinander agieren und kommunizieren. Typische heutige Apps auf dieser Basis sind im Schnitt Zehntausende von Zeilen lang (LoC, lines of code), das ist der berühmt-berüchtigte Quellcode. Ein einziger kleiner Fehler in einer einzigen dieser Zeilen … und das Programm spuckt fehlerhafte Daten aus oder crasht sogar.
Ich werde Ihnen in meinen Seminaren näher erläutern, wie Software im Grunde funktioniert, wie sie aufgebaut ist, welche Strukturelemente sie hat, wie genau sie das Abstraktionsprinzip nutzt und umsetzt, und wie sie Syntax und Semantik definiert, also per se nichtssagende Zeichen samt ihrer kontextspezifischen Bedeutung. Nehmen Sie z. B. das Wort „Ball“. Meine ich den Ball zum Werfen oder den, auf dem ich tanzen kann? Nun, das hängt ganz von der jeweiligen Situation ab, vom Kontext also. Außerdem werde ich Ihnen zeigen, wie sich „Local Apps“ und „Web Apps“ unterscheiden und welche Vor- und Nachteile sie haben. Zusammengefasst: „Local Apps“ sind Programme, die auf einem lokalen Gerät installiert und ausgeführt werden, wie zum Beispiel ein Grafikprogramm oder ein ebenfalls lokal auf der Festplatte installiertes Word oder Excel. Es werden somit die Rechen- und Kapazitätsressourcen Ihres lokalen Smartphones oder PCs genutzt. Web-Apps hingegen sind Programme, die über das Internet zugänglich sind und in einem lokalen Browser laufen, wie zum Beispiel Facebook oder Word 365. Web-Apps und Cloud Computing sind dabei zwei Seiten derselben Medaille, das ist wichtig zu verstehen. Bei Web-Apps wird der lokale Rechner folglich massiv entlastet und letztlich zum Eingabe- und Anzeigegerät degradiert, das wird diese Endgeräte in Kürze deutlich günstiger machen: PCs für unter 100 Euro. Clouds revolutionieren derzeit die Welt, in ihrer Disruptionskraft aktuell nur übertroffen durch den KI-Hype, der wiederum allerdings ganz und gar nicht ungerechtfertigt ist.
Software: zunehmend besser als „Brain-Ware“!
Künstliche Intelligenz (KI, englisch AI) ist dabei die Welt grundlegend zu ändern … und wir sind mittendrin in diesem revolutionären Welt-Veränderungsprozess. Andererseits wird heute vieles auch aus Marketinggründen gern mit dem Label „KI“ versehen, selbst wenn es sich eigentlich um algorithmische, deterministische, klassische Programme handelt, die im Sinne von „Big Data“ mit den steigenden Datenmengen effizient hinsichtlich Selektion und Analyse umgehen müssen. Das genau ist der entscheidende Unterschied:
Auf KI basierende Software agiert lediglich auf Basis möglichst vieler „Lern-Beispiele“, und damit lernt sie schlicht aus Erfahrungen, so wie wir Lebewesen: Einem Kleinkind bringe ich schließlich den Unterschied zwischen Hund und Katze anhand von vielen Beispiel-Erlebnissen bei, und nicht algorithmisch: „Liebes Kleinkind, messe die Durchschnittslänge der Fellhaare, und bei weniger als 1,25 Zentimetern ist das Tier mit 55,6 %iger Wahrscheinlichkeit eine Katze …“ – So läuft das nicht. Wenn man jetzt noch den aktuellen mechanischen Stand heutiger Roboter kennt, die sich inzwischen geschmeidig fortbewegen, Hindernissen filigran ausweichen, so schnell wie ein Vogel Strauß laufen (60 km/h) und sogar problemlos perfekte Salti vorführen, und diesen Faktor mit den sich aktuell überschlagenden KI-Fortschritten kombiniert, so ahnt man, welche unvorstellbaren Herausforderungen unsere Gesellschaft in Kürze zu meistern haben wird. Bei Weitem geht nicht jeder Wissenschaftler und KI-Forscher davon aus, dass dies der Menschheit überhaupt gelingen wird. Namhafte KI-Experten bangen sogar ernsthaft um die gesamte Menschheit selbst.
Hinzu kommt: Noch vor drei Jahrzehnten, also „rein zufällig“ genau vor dem Internetzeitalter, war es noch der Zugang zu Informationen, der die größte Herausforderung darstellte. Von unseren Ur-Ur-Ur-…Urgroßeltern haben wir vielleicht noch das Wort „Bibliothek“ oder auch das Wort „Bücherei“ vernommen. Heute können wir alle öffentlichen Informationen dieser Welt in Sekundenschnelle zu uns ins Haus oder ins Büro holen, doch kaum mehr den Wert dieser Informationen gewichten, die relevantesten Daten selektieren, geschweige denn maximal konstruktiv und produktiv mit ihnen umgehen. Information ist heute inflationär und verliert an Wertschätzung − das ist fatal. Als der Mensch entstand, waren solche Fähigkeiten einfach nicht vorgesehen … ein humanes Software-Defizit, wenn man so möchte.
Softwareprojekte werden endlich kalkulierbarer
Ein weiterer zentraler Aspekt der Software-Entwicklung ist der steinige Prozess der Umsetzung einer Idee in ein lauffähiges Gesamtprogramm selbst. Dazu gehören die einzelnen Schritte und Architektur-Entscheidungen vom Algorithmen-Set zum fertigen Produkt. Dabei müssen wir die wichtigsten Software-Qualitätsmerkmale berücksichtigen, wie zum Beispiel Funktionalitätsbreite und -tiefe, Zuverlässigkeit, Benutzbarkeit, Effizienz, Wartbarkeit und Portabilität. Natürlich wollen wir nicht nur einfache Programme schreiben, sondern auch komplexe, robuste, performante, reaktive, skalierbare, fehlertolerante und zugleich maximal anpassungsfähige Programme. Das ist eine große Herausforderung, die viel fundiertes Wissen und noch viel mehr aktive Erfahrung erfordert. Ich werde Ihnen einige Tipps und Tricks verraten, wie man heute solche Programme entwerfen und implementieren kann. Und auch wenn Sie nicht selbst programmieren müssen, mutiert solches Hintergrundwissen immer mehr zu Allgemeinwissen. Seien Sie vorbereitet!
Schließlich ist auch ein Einblick zu empfehlen, wie genau Software die Hardware steuert, auf der sie stets operiert, wie IT-Komplexität durch geniale Entwickler-Tricks beherrschbar wird, was das essenzielle 3-Schichten-Modell ist, und welche User-Illusionen es gibt. Besagte Illusionen sind nicht die Schuld der User-Gemeinde selbst, sondern oft zumindest teilweise das Unvermögen von Entwicklern, User nachvollziehbar an ihre Welten heranzuführen und sie an diesen teilhaben zu lassen. Der Hintergrund und eine der zahlreichen Ursachen liegt bereits in der Hardware heutiger Computer und ist der erstaunliche Fakt, dass sogar jedes günstige Smartphone mittlerweile einen Mikroprozessor (Rechenkern, CPU) beheimatet, der Software in Milliarden(!) von Rechenschritten pro Sekunde abarbeitet, durch Interaktion von wiederum Milliarden(!) von Schaltelementen (den Halbleiter-Transistoren), auch wenn sich das manchmal für den User völlig anders anfühlt. Computer sind heute faszinierende Wundermaschinen, die interessanterweise umso fantastischer anmuten, je mehr man sie versucht zu verstehen und in diese Materie „eintaucht“.
Software-Erstellung ist eine spannende und herausfordernde Tätigkeit, die verschiedene Philosophien und Methoden erfordert. Je nach Art und Umfang des Software-Projekts kann man unterschiedliche Programmier-Paradigmen und -Methoden anwenden, wie z. B. prozedurale, mathematisch-funktionale, objektorientierte oder rekursive (selbstaufrufende) Programmierung. Diese haben jeweils ihre eigenen Merkmale und Einsatztechniken, die man kennen und beherrschen sollte. Dabei verläuft auch hier der Fortschritt immer schneller, genauer: exponentiell. Entwickler von Software sind damit unfreiwillig die perfekten Vertreter der bekannten Philosophie „learning by doing“. Anders geht es nicht. Auch die Wahl des Vorgehensmodells ist wichtig für den Erfolg der Software-Erstellung. Es gibt verschiedene Modelle, die sich in ihrer Struktur, Flexibilität und Iterativität unterscheiden, wie z.B. Scrum, agile Software-Entwicklung oder klassische iterative (wiederkehrende) Modelle. Diese beeinflussen auch die Lerneffekte, die man aus der Software-Erstellung ziehen kann. Hier hat sich in den vergangenen Jahren sehr viel getan.
Zusammenfassend lässt sich bis hierhin feststellen, dass Software-Entwickler in erster Linie abstraktes Denken, kreatives Gestalten und strukturiertes Konzipieren beherrschen müssen. Andere Menschen und Berufszweige können andere Dinge gut, Entwickler haben eben an dieser Stelle außerordentliche Fähigkeiten. Doch eines gilt in jedem Fall: Sie sind KEINE Nerds.
Vor dem Programm kommt der Algorithmus
Neben der Software-Programmierung selbst muss man auch die Leistungsparameter von Software berücksichtigen, die schon bei der Algorithmus-Wahl eine Rolle spielen, also bei der Ermittlung des groben, doch mit Einschränkungen optimalen Software-„Kochrezepts“. Dazu gehören diverse KPIs (nummerische Kenngrößen), die bei einer Software die Effizienz und Skalierbarkeit (Robustheit bei steigender Last) messen. Außerdem muss man sich mit den Möglichkeiten und Herausforderungen von asynchroner und paralleler Programmierung auseinandersetzen, die es erlauben, mehrere Programmstränge gleichzeitig oder zumindest unabhängig voneinander laufen zu lassen. Dies ist aufgrund massiver Hardware-Fortschritte erst seit rund 15 Jahren effektiv möglich (Stichwort: Multicore-Prozessoren) und erfordert als finale Konsequenz eine noch deutlich höhere „Resilienz“ der Software, d.h. ihre Fähigkeit, mit Fehlern oder Störungen umzugehen. Mit anderen Worten: Nicht einmal mehr die selbst geschriebenen Zehntausenden Codezeilen laufen sequenziell ab, was unter anderem die Fehlersuche und das Software-interne Timing abermals massiv erschwert, bei dem es oft um Millionstel Sekunden geht! Das übersteigt die Vorstellungskraft und ist dennoch Fakt und täglich Brot von Software-Entwicklern.
Ein Paradebeispiel für die Bedeutung der Algorithmus-Wahl sind Such- und Sortier-Algorithmen, die an zahlreichen Stellen in Software-Programmen fast jeden Typs zur Anwendung kommen. Je nach Anwendungsszenario kann sich die Skalierungsperformanz dieser Algorithmen um Zehnerpotenzen unterscheiden, was einen enormen Unterschied für die Nutzererfahrung und damit die Softwarequalität ausmacht. Unter Last müssen Algorithmen immer noch schnell genug arbeiten − darum geht es. Als Beispiel sei hier die Anzahl zu sortierender Datensätze genannt, oder auch die Anzahl der gleichzeitig agierenden und mit der zentralen Software kommunizierenden User. Software, die bei 100 Usern schnell und zuverlässig arbeitet, bei 1000 Usern jedoch unerträglich langsam wird oder gar abstürzt, ist letztlich unbrauchbar.
Software-Erstellung ist ein enorm vielfältiges und faszinierendes Gebiet, das ständig neue Erkenntnisse und Innovationen hervorbringt. Es lohnt sich, sich mit den verschiedenen Philosophien und Methoden der Software-Erstellung vertraut zu machen und sie je nach Bedarf anzuwenden. Dabei sind moderne Software-Problemstellungen manchmal ganz und gar nicht zum Lachen. Hier sind einige Beispiele für die Herausforderungen, die Software-Entwickler heutzutage meistern müssen:
- Wie konzipiert man ein Programm, das auf Windows, Android, iOS und allen möglichen sonstigen Geräten läuft, ohne dass es wie ein Flickenteppich aus verschiedenen Stilen und Funktionen aussieht? Man muss dazu wissen, dass eine App auf dem iPhone, das für den User praktisch genauso aussieht und sich so anfühlt wie ihr Android-Pendant, technisch gesehen ein völlig unterschiedliches Programm ist!
- Wie geht man mit den Besonderheiten mobiler Endgeräte um, wie z. B. den unterschiedlichen Bildschirmgrößen, den variierenden Akkulaufzeiten, den sensiblen multiplen Sensoren und den oftmals nervigen User-Benachrichtigungen? Und wie gestaltet man eine ergonomische und attraktive Benutzeroberfläche (UX, user experience), die nicht nur die Nutzer begeistert, sondern auch maximal tolerant gegenüber Fehlbedienung und Fehleingaben ist?
- Wie vermeidet man fatale Fehler und Missverständnisse bei der Software-Planung und -Erstellung, wie z.B. das Fehlpriorisieren letztlich wichtiger Anforderungen, das Überschätzen der eigenen Fähigkeiten, das Unterschätzen der Konkurrenz und das unbeabsichtigte, jedoch schleichende Relativieren so mancher Kundenwünsche?
- Wie löst man das Dokumentations-Dilemma, bei dem man faktisch nie genug schreiben kann, um die Funktionsweise seiner Software transparent zu machen? Wie hält man die Software wartbar, internationalisierbar und testbar? Und wie geht man mit Änderungsanfragen (CRs) um, die den Entwicklern oft den letzten Nerv rauben, doch aus Nutzer-Sicht absolut berechtigte und nachvollziehbare Wünsche darstellen?
Somit schlagen sich Software-Entwickler tagtäglich mit vielen lästigen Dingen herum, die oftmals völlig überraschend auftreten und zum großen Teil tatsächlich unvorhersehbar sind. Die restliche Zeit ist dann endlich für die eigentliche Kernaufgabe verfügbar.
Software-Phänomene aus Kundensicht
Kommen wir ohne Umschweife zur Thematik und oft auch Problematik der Auswahl von Softwareprodukten und Systempartnern. In diesem Zusammenhang stellen sich zahlreiche weitere Fragen von fundamentaler Bedeutung, die mit dem Komplex der Software-Entwicklung selbst eng verzahnt sind und ebenfalls großen Einfluss auf die resultierende Qualität einer Software ausüben. Beide Themen sind zwei Seiten einer Medaille, wir wechseln lediglich die Perspektive und drehen den sprichwörtlichen Spieß um. Einige davon möchte ich hier exemplarisch ansprechen und zugleich bereits erste Antworten geben:
FRAGE NUMMER 1: Auf welche Leistungs- und Qualitätskriterien muss ich bei Auswahl und Anschaffung entsprechender Softwarepakete besonders achten?
Oft wird der Fehler gemacht, sich auf nur wenige vordergründige Entscheidungskriterien zu stützen, was der natürlichen Komplexität der vorliegenden Herausforderung niemals gerecht werden kann. Zudem werden die zentralen Kriterien oftmals untergewichtet oder finden sogar überhaupt keinen Eingang ins Entscheidungsmodell. Dabei sind Aspekte wie technologische Zukunftssicherheit, System-Belastbarkeit, Skalierungseigenschaften, Performanz-Parameter, Latenzen, Software-Robustheit und -Resilienz bis hin zu Schnittstellen-Flexibilität und erwartbaren Migrationsaufwänden erst in ihrer Gesamtbetrachtung aussagekräftig. Nur so führen sie in Folge zu soliden, belastbaren und gut kommunizierbaren, also durch alle Beteiligten nachvollziehbaren Entscheidungen. Lassen Sie mich auf einige dieser Kriterien etwas näher eingehen.
IT-Systeme sind in ihrer Leistungsfähigkeit stets dynamisch zu betrachten: Software, die nach heutigen Maßstäben beeindruckt, kann sich unter zukünftig höherer Last schnell als praxisuntauglich herausstellen. Dies ist z.B. dann der Fall, wenn ein im Projektverlauf zentral in der Cloud installiertes SW-Paket nach Inbetriebnahme innerhalb weniger Jahre mit der potenziell 3- oder 5-fachen oder auch 100-fachen Userzahl umgehen muss. Die Last auf eine laufende Software bzw. generell auf ein technisches System schrittweise, doch signifikant zu erhöhen, ohne dass die User signifikante Leistungseinbußen verspüren, nennt man in der IT, und nicht nur in dieser Branche, Skalierbarkeit. Das Wort „Skala“ ist hier enthalten.
Ja, das hatten wir bereits. Dieser Artikel berichtete schon über dieses Thema. Interessant ist nun jedoch der Perspektivwechsel als solcher: Uns interessiert aus Sicht von Nutzern, Geldgebern oder Kunden nicht, wie man Software-Skalierbarkeit realisiert, sondern nur wie die jeweilige Software, die man eventuell anschaffen möchte, auf diesem Sektor abschneidet. Wie soll ich als Kunde das Verhalten von Hunderten von zeitgleichen Usern realistisch simulieren, um diesen Leistungswert zu ermitteln? Was davon konnte Entwickler-seitig bereits im Vorfeld zuverlässig getestet werden? Gibt es Belege? Und wie verlaufen solche Tests? Hier gibt es zum Glück inzwischen bewährte Lösungsansätze. Die steigende Userzahl ist jedoch nur eine von vielen Ursachen, die hier eine Rolle spielen und leider oft nicht zu Ende gedacht werden. Deshalb sind schon vor Projektbeginn fundierte und realistische(!) Szenarien zu entwickeln, welche Herausforderungen künftig auf die anzuschaffende Software zukommen können und wie man diese präventiv angemessen konzeptionell einbezieht.
Was verstehen wir unter Schnittstellen-Flexibilität? Nun, kein IT-System steht isoliert und als Selbstzweck, so wie etwa auf einer einsamen Insel. Vielmehr entfalten solche Systeme typischerweise erst im Zusammenspiel mit anderen, bereits vorhandenen, vielleicht auch schon sehr viel älteren Systemen ihre ganze Wirkung und Rationalisierungskraft. Als Beispiel sei hier das enge Zusammenwirken eines alten Kundenmanagementsystems einerseits mit einem neuen Projektmanagement- und andererseits mit einem Buchhaltungssystem aus einer anderen Betriebssystem-Welt genannt. Solche IT-Landschaften weisen oft eine unter vielen Gesichtspunkten extreme Heterogenität auf, die es intelligent und effizient zu überbrücken gilt. Dabei darf man sich keinesfalls nur auf die technologische Seite von Schnittstellen beschränken, sondern muss ebenso bereits vorhandene, teils gewohnte und lieb gewonnene Geschäftsprozesse angemessen einbeziehen. – Was nützt eine Schnittstelle, die mehr trennt als verbindet?
Warum verwendet man im Deutschen überhaupt den inhaltlich doch recht trennenden Begriff „Schnitt-Stelle“? Die englische Sprache löst dies viel besser mit dem Ausdruck „interface“, also „Zwischen-Gesicht“, das ist etwas eindeutig Verbindendes. Ähnlich verhält es sich mit dem deutschen „eine Fahrkarte ENT-werten“, was dem englischen „to VALIDATE a ticket“ entspricht, also dem Ticket erst einen Wert verleihen. Denken Briten und Amerikaner vielleicht generell etwas optimistischer? … zurück zur Schnittstelle.
Stellen Sie sich ein System vor, das für sich genommen zwar alle Merkmale aufweist, die man sich nur wünschen kann, doch einfach nicht in der Lage ist, reibungslos mit anderen Systemen zusammenzuarbeiten. Hier gilt: Auch Akzeptanzprobleme auf Nutzerseite können vermeintlich erfolgreiche IT-Projekte und damit die resultierenden Systeme schnell zu Fall bringen. Das ist wie ein Sportwagen auf einer holprigen Landstraße und letztlich verschwendetes Geld.
In eine ähnliche Kerbe schlägt das völlig separat zu betrachtende Kapitel Migrationsaufwände. In den meisten Fällen wird übersehen, dass eine neue Software-Installation eine ältere nicht von jetzt auf gleich ersetzen kann. Vielmehr handelt es sich um lange andauernde und auch riskante Übergangsphasen im Rahmen von IT-Change-Projekten, die diesen Namen mehr als verdienen: Die Datenbestände müssen ebenso in das neue System übertragen werden wie die Geschäftsprozesse auf meist neue Weise abzubilden sind. So können sich solche Übergangsphasen viel länger hinziehen als gewünscht, erhofft und projektiert.
Zudem sind sie frühzeitig und parallel zum Projektverlauf umzusetzen, um diese Transition als wohldurchdachtes Teilprojekt so kurz wie möglich zu halten. Darüber hinaus scheitern Übergangsphasen dieser Kategorie nicht selten ganz. Dann ist eine Rückabwicklung zu leisten, ein sogenannter „roll-back“. Auch dieser wird oft per „Prinzip Hoffnung“ nicht angemessen in mögliche Projektverläufe einbezogen. Die Folgen für „time & budget“ liegen auf der Hand.
Das Gefährliche ist die Kombination all dieser Faktoren und Risiken, die sich gegenseitig massiv verstärken – ein übergreifender Effekt, der als solcher ebenfalls stark unterschätzt wird.
Im Fokus steht immer der Nutzwert
FRAGE NUMMER 2: Welche verdeckten Kosten-Nutzen-Effekte sollte ich im Auge haben?
Hier gibt es eine Fülle von tatsächlich nicht nur verdeckten, sondern geradezu versteckten Faktoren. Mit Abstand muss das sogenannte „Customizing“ an erster Stelle erwähnt werden, also die Anpassung der Funktionalitäten großer Softwarepakete auf Quellcode-Ebene. Sonderwünsche werden hier gemäß individueller Kundenanforderung zu einem Standard-Softwareprodukt vom Anbieter „hinzuprogrammiert“. Bei großen Softwareprojekten ist das leider oft kaum vermeidbar.
Die Gefahr liegt v.a. darin, dass bei den gängigen Vertragsmodellen ein eventueller Mehraufwand, der in der anfänglichen Aufwandsschätzung nicht enthalten war oder sein konnte, kostenseitig vom Auftraggeber abzudecken ist, also vom Kunden. Dies führt schnell zum bekannten „Fass-ohne-Boden“-Effekt und kann viele Zehntausend Euro verschlingen, wohlgemerkt ohne jeden weiteren Gegenwert. Die Reißleine zu ziehen ist dabei meist keine Lösung und aus vertraglichen Gründen oft nicht einmal formal eine Option.
Eine zumindest partielle Lösung besteht in einer Vertragsgestaltung, die solche Anpassungskomponenten auf Werkvertragsbasis inkludiert, nicht auf Dienstvertragsgrundlage. In diesem Fall nimmt der Auftraggeber, also der Kunde, ein zuvor möglichst genau spezifiziertes Gewerk ab, eventuelle Mehraufwände trägt somit der Auftragnehmer, also der Dienstleister. Es ist ein weitverbreiteter Irrglaube, dass ein solches Vertragswerk nicht verhandelbar sei. Das ist es sehr wohl, zumindest an einigen entscheidenden Projekt-Stellen, was das beschriebene finanzielle sowie generelle Projektrisiko bereits deutlich reduzieren wird. Dieser Umstand ist das reinste Euro-Grab.
Ganz abgesehen von der weitläufig massiv unterschätzen Customizing-Problematik ist stets darauf zu achten, wie Aufwandsschätzungen per se durchzuführen sind und nach welchen für alle Beteiligten obligatorischen Prinzipien nachträgliche(!) Funktionswünsche in das laufende Projekt eingearbeitet werden müssen. Das ist das wichtige Kapitel „Change Requests“ oder CRs, bereits für sich genommen ein Stolperstein erster Güte für komplexe SW-Projekte.
Der Gesetzgeber macht es Entwicklern nicht leichter
Kommen wir zu einem Thema, das Software-Entwickler zumindest „gefühlt“, doch auch objektiv belegbar, immer mehr von der Lösung der Hauptaufgaben eines Entwicklers ablenkt:
Gesetzliche Datenschutz-Vorgaben werden immer restriktiver und stellen für Software-Entwickler eine immer größere Herausforderung dar. Sie müssen nicht nur die gesetzlichen Anforderungen der DSGVO beachten, sondern auch die technischen Möglichkeiten zur Umsetzung von Privacy by Design und Privacy by Default nutzen. Das bedeutet, dass sie die Datenminimierung, die datenschutzfreundlichen Voreinstellungen, die Betroffenenrechte und die Datenübertragbarkeit berücksichtigen müssen. Außerdem müssen sie die IT-Sicherheit gewährleisten, um sowohl den Datenschutz (Schutz vor Datenmissbrauch) als auch die Datensicherheit (Schutz vor Datenverlust) zu garantieren. Dabei wird die Verantwortung heute größtenteils oder zumindest teilweise an Cloud-Dienstleister (cloud service providers, CSP) delegiert, die ohnehin hohe Sicherheitsstandards erfüllen müssen. Der prozentuale Aufwand für die Software-Entwicklung steigt mit zunehmenden rechtlichen Vorgaben leider signifikant an. Die zugehörigen Umsetzungskonzepte selbst sind wiederum komplex und erfordern viel Fachwissen und leidvolle Erfahrung. Die Software-Entwicklung im Bereich Datenschutz ist bereits per se somit eine zunehmend anspruchsvolle Aufgabe, die viel Kreativität und Innovation erfordert – und viel Geld verschlingt.
Zu guter Letzt gönnen wir uns einen abschließenden Blick auf Web-Apps, die bekanntlich in der Cloud laufen und damit die entfernten Rechen- und Datenkapazitäts-Ressourcen mehr oder minder anonymer Webserver beanspruchen: Interessant ist dabei die übergreifende Tendenz − ein nicht mehr zu übersehender Metatrend − hin zur Geo- und Hardware-Abstraktion. Niemanden interessiert mehr, zumindest auf Kundenseite, wo genau auf der Welt die eigenen Daten welcher Cloud liegen und auf welchen physischen Computern dies letztendlich stattfindet. Hauptsache, die Daten sind zugänglich und dies durch konsequente Ende-zu-Ende-Verschlüsselung nur für Befugte. Datenverarbeitung mutiert zunehmend zum reinen Service, angeboten und wahrgenommen als ganz normales „Monatsabo“ mit bestimmten Garantien der Datensicherheit, der Zugriffszeiten, der Ausfallwahrscheinlichkeit usw. Mit anderen Worten: Wir haben es hier mit „Abstraktion par excellence“ zu tun, mit der Folge einer kundenseitig faktischen Entmaterialisierung von Computern. Sogar das Pentagon hat seine „Journey to Cloud“ (J2C) bereits hinter sich, brisantere Daten gibt es nicht. − Unsere Welt ist dabei, sich fundamental zu ändern.
Kommen wir zum Schluss …
Dies ist nur ein kleiner, sehr kleiner Einblick in die Tiefen moderner, komplexer Software sowie deren Entwicklung und die resultierenden Projekte. Software-Entwickler selbst sind im Gegensatz zur landläufigen medialen Darstellung eher zu bewundern als zu belächeln – gut begründbar und mit gutem Recht.
Ich hoffe, Sie sind neugierig geworden auf weitere spannende Details beim Einblick in die faszinierende Welt der Software-Erstellung und Software-Projekte.
Ihr Stefan Hable
Bildquellenangaben
Alle Abbildungen entstammen dem Portal Pixabay (www.pixabay.com)