Entwicklung & Code
Die oberste Direktive und ihre praktischen Konsequenzen für Softwareteams
Moin.
(Bild: Stefan Mintert )
Stefan Mintert arbeitet mit seinen Kunden daran, die Unternehmenskultur in der Softwareentwicklung zu verbessern. Das derzeit größte Potenzial sieht er in der Leadership; unabhängig von einer Hierarchieebene.
Die Aufgabe, dieses Potenzial zu heben, hat er sich nach einem beruflichen Weg mit einigen Kurswechseln gegeben. Ursprünglich aus der Informatik kommend, mit mehreren Jahren Consulting-Erfahrung, hatte er zunächst eine eigene Softwareentwicklungsfirma gegründet. Dabei stellte er fest, dass Führung gelernt sein will und gute Vorbilder selten sind.
Es zeichnete sich ab, dass der größte Unterstützungsbedarf bei seinen Kunden in der Softwareentwicklung nicht im Produzieren von Code liegt, sondern in der Führung. So war es für ihn klar, wohin die Reise mit seiner Firma Kutura geht: Führung verbessern, damit die Menschen, die die Produkte entwickeln, sich selbst entwickeln und wachsen können.
Für Heise schreibt Stefan als langjähriger, freier Mitarbeiter der iX seit 1994.
Die oberste Direktive für Retrospektiven hat Norman Kerth 2001 in seinem Buch „Project Retrospectives“ formuliert:
„Regardless of what we discover, we must understand and truly believe that everyone did the best job he or she could, given what was known at the time, his or her skills and abilities, the resources available, and the situation at hand.“
„Unabhängig davon, was wir herausfinden, müssen wir verstehen und wirklich glauben, dass jeder das Beste getan hat, was er oder sie in Anbetracht der damaligen Kenntnisse, seiner oder ihrer Fähigkeiten und Fertigkeiten, der verfügbaren Ressourcen und der gegebenen Situation tun konnte.“
Die oberste Direktive ist insbesondere im Bereich agiler Softwareentwicklung bekannt geworden. Das ist bemerkenswert, weil in Kerths Buch die Worte „agil“ oder „Scrum“ nicht vorkommen.
Ich habe die Direktive oftmals in eine erste Retrospektive eingebracht, die ich mit einem neuen Team durchgeführt habe. Die Reaktionen fielen in den Teams sehr unterschiedlich aus. Da war auch schon einmal jemand dabei, der verächtlich schnaubte. Darauf angesprochen bekam ich manchmal als Antwort eine rhetorische Frage der Art: „Das meinst Du doch nicht ernst, oder?“ Darin schwingt eine klare Aussage mit: Die Leistung einer anderen Person ist nicht ausreichend.
In so einem Moment lasse ich mich nicht auf eine Diskussion über die Leistung anderer ein. Vielmehr halte ich folgende Fragen mit entgegengesetzten Aussagen für weiterführend:
- Angenommen, die fragliche Person hat ihre beste Leistung geliefert, und ich bin mit dem Ergebnis nicht zufrieden. Was folgt für mich daraus?
- Angenommen, die fragliche Person hat nicht ihre beste Leistung geliefert. Wie gehe ich damit um?
Fangen wir mit dem zweiten Punkt an: Jemand bringt nicht seine beste Leistung. Welche Gründe fallen mir ein?
Erstens: Die Kollegin oder der Kollege ist krank, hat irgendwelche persönlichen Probleme oder ist aus einem anderen Grund nicht in der Lage, seinen Fertigkeiten entsprechend zu arbeiten. In einem „gesunden“ Team ist die eigene Reaktion ganz einfach: Ich spreche die Person an und biete ggf. Hilfe an.
Zweitens: Die Kollegin oder der Kollege arbeitet absichtlich schlecht. Dafür gibt es ein Wort: Sabotage. Das ist einer der äußerst seltenen Fälle, in denen ich disziplinarische Maßnahmen für sinnvoll halte.
Damit komme ich zurück zum ersten Punkt: Wer seine beste Leistung liefert, kann dafür nicht kritisiert werden. Worin sollte die Kritik bestehen? Wenn ein Kleinkind nicht Rad fahren kann, gibt es daran nichts zu beanstanden. Wenn ein 95-jähriger Mensch keinen Marathon laufen kann, wer will es ihm verübeln (am Rande: wie viele 20-Jährige schaffen die Strecke?). Wer krank ist oder private Probleme hat, wird nicht seine (theoretischen) 100 Prozent leisten können.
Wenn sich das negativ auf das Teamergebnis auswirkt, sehe ich alle Mitglieder gemeinsam in der Verantwortung – und in der Pflicht, konstruktiv dagegen vorzugehen. Teaminterne Kritik an einzelnen Personen gehört nicht dazu. Stattdessen sehe ich Folgendes als vernünftige Leitlinie an:
- Wenn ich als Entwickler feststelle, dass ein anvisiertes Ziel wie das Sprintziel in Gefahr gerät, spreche ich es offen an, sobald ich es erkenne.
- Ich vermeide Schuldzuweisungen (Blaming and Finger-Pointing).
- Wenn ich selbst nicht über die Fertigkeiten verfüge, das Defizit zu behandeln, weil es beispielsweise Probleme in einer Komponente gibt, die in einer Programmiersprache geschrieben ist, die ich nicht beherrsche, geht eins immer: Ich biete Hilfe an. Dabei kann es sich um Pair Programming handeln, oder ich stelle mich als Sparringspartner zur Verfügung.
Im Endeffekt kann man alles auf zwei Punkte zurückführen. Aus der obersten Direktive folgt für die Zusammenarbeit im Team:
- Ich verzichte auf Schuldzuweisungen. Die Suche nach Problemursachen ist natürlich notwendig, sowohl um eine geeignete Lösung zu finden, als auch um zukünftige Probleme der gleichen Art zu vermeiden oder früher behandeln zu können.
- Ich biete Hilfe an, um Lösungen zu finden. Dabei spielen Zuständigkeiten keine Rolle. Ein Team erreicht oder verfehlt Ergebnisse und Ziele gemeinsam.
Nach einem Problem oder Scheitern die handelnde Person zu benennen und das nicht als Blaming oder Finger-Pointing zu verstehen, ist für die meisten Teams schwierig. Genau in solchen Fällen hilft es, im Team offen über die oberste Direktive zu sprechen.
Erst lesen, dann hören
Im Podcast Escape the Feature Factory greife ich ausgewählte Themen des Blogs auf und diskutiere sie (meist) mit einem Gast. Durch den Austausch lerne ich eine zweite Perspektive kennen. Zur obersten Direktive habe ich gleich zwei Podcast-Folgen im Angebot; im ersten Beitrag gehe ich kurz darauf ein, was jeder selbst tun kann, wenn es an anderer Stelle im Team klemmt; im zweiten Beitrag gehe ich mit einem Gast in die Tiefen der obersten Direktive. Wer auch daran interessiert ist, findet den Podcast bei Spotify, Deezer, Amazon Music, Apple Podcasts und auf kutura.digital. Dort finden sich auch Workshops, die sich den Themen des Blogs widmen.
(rme)
Entwicklung & Code
programmier.bar: CTO-Special mit Peyman Pouryekta – Interim CTO und Berater
Peyman Pouryekta berät heute als selbstständiger Experte CTOs, Firmen und Venture Funds – doch sein Weg dorthin war alles andere als geradlinig. Geboren 1982 in Teheran, kam er als Kind nach Deutschland, machte später eine Elektriker-Ausbildung, brach ein Studium ab und fand schließlich über einen weiteren Ausbildungsweg zur Softwareentwicklung. In den 2010er Jahren arbeitete er in Berlin schon früh mit neuronalen Netzen, KI und skalierbaren Produkten.
Im Gespräch mit Jan Gregor Emge-Triebel und Dennis Becker geht es um Peymans Ausbildungsweg, seine ersten Leadership-Rollen und seine Entscheidung für die Selbstständigkeit. Außerdem diskutieren die drei, welche Fehler Führungskräfte sowie Gründerinnen und Gründer häufig machen – und welche Rolle künstlliche Intelligenz in Zukunft spielen wird.
Empfohlener redaktioneller Inhalt
Mit Ihrer Zustimmung wird hier ein externer Inhalt geladen.
Die aktuelle Ausgabe des Podcasts steht auch im Blog der programmier.bar bereit: „Peyman Pouryekta – Interim CTO und Berater„. Fragen und Anregungen gerne per Mail oder via Mastodon, Bluesky, LinkedIn oder Instagram.
(mai)
Entwicklung & Code
Neuerungen in C++26: Datenparallele Datentypen (SIMD)
Die SIMD-Bibliothek bietet in C++26 portable Typen zur expliziten Angabe von Datenparallelität und zur Strukturierung von Daten für einen effizienteren SIMD-Zugriff. Bevor wir uns im Detail mit der neuen Bibliothek befassen, möchte ich kurz ein paar allgemeine Anmerkungen zu SIMD (Single Instruction, Multiple Data) voranschicken.
Rainer Grimm ist seit vielen Jahren als Softwarearchitekt, Team- und Schulungsleiter tätig. Er schreibt gerne Artikel zu den Programmiersprachen C++, Python und Haskell, spricht aber auch gerne und häufig auf Fachkonferenzen. Auf seinem Blog Modernes C++ beschäftigt er sich intensiv mit seiner Leidenschaft C++.
SIMD – Single Instruction, Multiple Data
Vektorisierung bezieht sich auf die SIMD-Erweiterungen (Single Instruction, Multiple Data) des Befehlssatzes moderner Prozessoren. SIMD ermöglicht es dem Prozessor, eine Operation parallel auf mehrere Daten anzuwenden.
Ein einfaches Beispiel: Ob ein Algorithmus parallel und vektorisiert ausgeführt wird, hängt von vielen Faktoren ab – unter anderem davon, ob die CPU und das Betriebssystem SIMD-Befehle unterstützen. Außerdem kommt es auf den Compiler und den Optimierungsgrad an, der zum Kompilieren des Codes eingesetzt wird.
// SIMD.cpp
const int SIZE= 8;
int vec[]={1,2,3,4,5,6,7,8};
int res[SIZE]={0,};
int main(){
for (int i= 0; i < SIZE; ++i) {
res[i]= vec[i]+5; // (1)
}
}
Zeile 1 ist die Schlüsselzeile in dem kleinen Programm. Dank des Compiler Explorers ist es recht einfach, die Assemblerbefehle für Clang 3.6 mit und ohne maximale Optimierung (-O3) zu generieren.
Ohne Optimierung
Obwohl meine Zeit, in der ich mit Assemblerbefehlen herumgespielt habe, lange vorbei ist, ist es offensichtlich, dass alles sequenziell ausgeführt wird:
(Bild: Rainer Grimm)
Mit maximaler Optimierung
Durch die Verwendung der maximalen Optimierung erhalte ich Befehle, die parallel auf mehreren Datensätzen ausgeführt werden:
(Bild: Rainer Grimm)
Die Move-Operation (movdqa
) und die Add-Operation (paddd
) verwenden die speziellen Register xmm0
und xmm1
. Beide Register sind sogenannte SSE-Register mit einer Breite von 128 Bit. Damit können 4 ints
auf einmal verarbeitet werden. SSE steht für Streaming SIMD Extensions. Leider sind Vektorbefehle stark von der eingesetzten Architektur abhängig. Weder die Befehle noch die Registerbreiten sind einheitlich.
Moderne Intel-Architekturen unterstützen meist AVX2 oder sogar AVX-512. Dies ermöglicht 256-Bit- oder 512-Bit-Operationen. Damit können 8 oder 16 ints
parallel verarbeitet werden. AVX steht für Advanced Vector Extension.
Genau hier kommen die neuen datenparallelen Datentypen der Bibliothek ins Spiel, die eine einheitliche Schnittstelle zu Vektorbefehlen bieten.
Datenparallele Typen (SIMD)
Bevor ich mich mit der neuen Bibliothek beschäftige, sind einige Definitionen erforderlich. Diese Definitionen beziehen sich auf den Proposal P1928R15. Insgesamt umfasst die neue Bibliothek sechs Proposals.
(Bild: Rainer Grimm)
Die Menge der vektorisierbaren Typen umfasst alle Standard-Ganzzahltypen, Zeichentypen sowie die Typen float
und double
. Darüber hinaus sind std::float16_t
, std::float32_t
und std::float64_t
vektorisierbare Typen, sofern sie definiert sind.
Der Begriff datenparallel bezieht sich auf alle aktivierten Spezialisierungen der Klassen-Templates basic_simd
und basic_simd_mask
. Ein datenparalleles Objekt ist ein Objekt vom datenparallelen Typ.
Ein datenparalleler Typ besteht aus einem oder mehreren Elementen eines zugrunde liegenden vektorisierbaren Typs, der als Elementtyp bezeichnet wird. Die Anzahl der Elemente ist für jeden datenparallelen Typ eine Konstante und wird als Breite dieses Typs bezeichnet. Die Elemente in einem datenparallelen Typ werden von 0 bis Breite −1 indiziert.
Eine elementweise Operation wendet eine bestimmte Operation auf die Elemente eines oder mehrerer datenparalleler Objekte an. Jede solche Anwendung ist in Bezug auf die anderen nicht sequenziell. Eine unäre elementweise Operation ist eine elementweise Operation, die eine unäre Operation auf jedes Element eines datenparallelen Objekts anwendet. Eine binäre elementweise Operation ist eine elementweise Operation, die eine binäre Operation auf entsprechende Elemente zweier datenparallelisierter Objekte anwendet.
Nach so viel Theorie möchte ich nun ein kleines Beispiel zeigen. Es stammt von Matthias Kretz, Autor des Proposals P1928R15. Das Beispiel aus seiner Präsentation auf der CppCon 2023 zeigt eine Funktion f
, die einen Vektor entgegennimmt und dessen Elemente auf ihre Sinuswerte abbildet:
void f(std::vector& data) {
using floatv = std::simd;
for (auto it = data.begin(); it < data.end(); it += floatv::size()) {
floatv v(it);
v = std::sin(v);
v.copy_to(it);
}
}
Die Funktion f
nimmt einen Vektor von Floats (data) als Referenz. Sie definiert floatv
als SIMD-Vektor von Floats unter Verwendung von std::simd
. f
durchläuft den Vektor in Blöcken, wobei jeder Block die Größe des SIMD-Vektors hat.
Für jeden Block gilt:
- Lädt den Block in einen SIMD-Vektor (
floatv v(it);
). - Wendet die Sinusfunktion gleichzeitig auf alle Elemente im SIMD-Vektor an (
v = std::sin(v);
). - Schreibt die Ergebnisse zurück in den ursprünglichen Vektor (
v.copy_to(it);
).
Die Behandlung von SIMD-Anweisungen wird besonders elegant, wenn der Proposal P0350R4 in C++26 implementiert wird. SIMD kann dann beispielsweise als neue Execution Policy in Algorithmen verwendet werden:
void f(std::vector& data) {
std::for_each(std::execution::simd, data.begin(), data.end(), [](auto& v) {
v = std::sin(v);
});
}
Wie geht es weiter?
In meinem nächsten Artikel werde ich mich näher mit der neuen SIMD-Bibliothek befassen.
(map)
Entwicklung & Code
Die Produktwerker: Scrum-Werte für Product Owner – ein Kompass für den Alltag
Die fünf Scrum-Werte stehen etwas unscheinbar im Scrum Guide – nur ein kurzer Absatz, gefühlt kaum mehr als eine Randnotiz. Und doch bilden sie die Grundlage dafür, dass iteratives Arbeiten, gemäß dem Prinzip empirischer Prozesssteuerung, in Scrum überhaupt möglich ist.
In dieser Folge sprechen Oliver Winter und Tim Klein darüber, wie Product Owner diese Scrum-Werte im Alltag konkret leben können. Nicht abstrakt und theoretisch, sondern ganz praktisch – im Spannungsfeld von Verantwortung, Kommunikation und Produktführung.
Die fünf Scrum-Werte reflektieren
Viele Teams und Organisationen arbeiten mit Scrum, ohne die Bedeutung der Scrum-Werte wirklich zu reflektieren. Dabei hängt vieles genau davon ab: Wie offen geht man mit Feedback um? Wie mutig spricht man Konflikte an? Wie sehr helfen Fokus, Commitment und Respekt dabei, Klarheit zu schaffen und wirkungsvoll zusammenzuarbeiten?
Tim und Oliver nehmen sich alle fünf Scrum-Werte vor – Commitment, Fokus, Mut, Offenheit und Respekt – und beleuchten sie aus der Sicht eines Product Owners. Sie zeigen, dass es nicht um perfekte Haltung oder moralische Überlegenheit geht, sondern um gelebte Verantwortung. Und um die Wirkung, die entsteht, wenn ein Product Owner diese Werte nicht nur benennt, sondern im täglichen Handeln sichtbar macht.
Ob in der Priorisierung, im Stakeholder-Dialog oder im Sprint Review: Die Scrum-Werte zeigen sich überall. Wer als Product Owner mutig ist, kann klare Entscheidungen treffen, statt es allen recht machen zu wollen. Wer respektvoll kommuniziert, schafft Vertrauen – gerade auch in schwierigen Situationen. Und nur wer offen bleibt, kann Feedback wirklich annehmen, ohne die eigene Position zu verlieren.
Scrum-Werte in die Praxis umsetzen
Oft stehen diese Werte in Spannung zueinander – oder im Widerspruch zu dem, was das Umfeld verlangt. Hierzu hatten die Produktwerker letzte Woche die Episode mit Johannes Schartau („Wenn Strukturen die Produktentwicklung behindern“). Gerade unter Druck fällt es schwer, Respekt zu zeigen, mutig zu bleiben oder sich zu fokussieren. Und genau deshalb braucht es Reflexion: ein klares Gespür dafür, welchen Wert ich in meinem Kontext gerade besonders stärken will. Und die Bereitschaft, kleine Schritte zu gehen, statt alles auf einmal verändern zu wollen.
Diese Folge ist eine Einladung, den Scrum-Werten mehr Raum zu geben – nicht als Theorie, sondern als Kompass im Alltag. Wer sie ernst nimmt, stärkt nicht nur die eigene Wirksamkeit als Product Owner, sondern auch das Vertrauen im Team und in die eigene Produktverantwortung.
Weitere erwähnte Podcastfolgen
Diese weiteren Episoden werden im Gespräch genannt:
Die aktuelle Ausgabe des Podcasts steht auch im Blog der Produktwerker bereit: „Was bedeuten die Scrum Werte für Product Owner – und wie lebst du sie im Alltag„.
(Bild: deagreez/123rf.com)
So geht Produktmanagement: Die Online-Konferenz Product Owner Day von dpunkt.verlag und iX geht in die achte Runde. Am 13. November 2025 können Product Owner, Produktmanagerinnen und Service Request Manager dort ihren Methodenkoffer erweitern, sich vernetzen und von den Good Practices anderer Unternehmen inspirieren lassen.
Vergünstigte Blind-Bird-Tickets sind bis zur Programmveröffentlichung erhältlich. In der Rückschau finden Interessierte das Programm des Vorjahres.
(mai)
-
Online Marketing & SEOvor 6 Tagen
Aus Marketing, Medien, Agenturen & Tech: Diese 40 klugen Köpfe unter 40 müssen Sie kennen
-
Digital Business & Startupsvor 5 Tagen
Von Peter Thiel finanziertes Krypto-Startup Bullish will an die Börse
-
Künstliche Intelligenzvor 6 Tagen
Amazon soll Werbung bei Prime Video verdoppelt haben
-
Social Mediavor 2 Tagen
LinkedIn Feature-Update 2025: Aktuelle Neuigkeiten
-
Künstliche Intelligenzvor 5 Tagen
Telemedizin: Patientenversorgung braucht einfach zugängliche Kommunikationswege
-
Apps & Mobile Entwicklungvor 3 Tagen
So gut ist Dune: Awakening: Dune sehen und durch Sandwürmer sterben
-
Datenschutz & Sicherheitvor 6 Tagen
CCC: Gesammelte Ausweisdaten von Übernachtungsdienstleister Numa gefunden
-
UX/UI & Webdesignvor 5 Tagen
Kunst & KI begleitet die Münchner Standort-Eröffnung › PAGE online