Als leidenschaftlicher Java-Programmierer der ersten Stunde habe ich es mir zur Aufgabe gemacht, andere dabei zu unterstützen, ihre Programmierfähigkeiten zu verbessern.
Das mache ich mit Artikeln auf meinem Blog und in Fachzeitschriften, mit Videos auf meinem YouTube-Kanal und mit Vorträgen bei JUGs und auf Konferenzen wie der JavaLand.
Du triffst mich außerdem regelmäßig auf Unkonferenzen wie der JCrete, der JChateau und der JAlba.
Auf dieser Seite findest du Abstracts meiner Vorträge und Links zu Artikeln, Talks und Interviews, die in anderen Medien veröffentlicht wurden.
Die Links führen zu Abstracts weiter unten auf dieser Seite.
2024 + 2025:
2023:
In den folgenden Abschnitten findest du die Abstracts meiner Konferenz-Vorträge.
Die Java-Stream-API wurde mit Java 8 im März 2014 veröffentlicht und hat uns ein unverzichtbares Werkzeug an die Hand gegeben, um Daten zu verarbeiten.
Doch der begrenzte Satz an intermediären Operationen – filter, map, flatMap, mapMulti, distinct, sorted, peak, limit, skip, takeWhile und dropWhile – führt dazu, dass komplexere Datentransformationen durch die Stream-API nicht ausgedrückt werden können.
Es fehlen z. B. Operationen wie window und fold und zahlreiche mehr, wenn man sich die Feature-Requests der Community ansieht.
Anstatt nun all diese Operationen ins Stream-Interface zu integrieren, entwickelte das JDK-Team eine neue API, die zum einen im JDK selbst genutzt wird, um heiß begehrte intermediäre Operationen bereitzustellen, und mit der zum anderen Entwicklerinnen und Entwickler ihre eigenen Operationen implementieren können.
Diese neue API heißt „Stream Gatherers“ und wurde in Java 22 im März 2024, also genau zehn Jahre nach der Einführung der Stream-API, zum ersten mal als Preview-Feature (JEP 461) veröffentlicht. In Java 23 wurde die neue API ohne Änderungen in eine zweite Preview-Runde geschickt (JEP 473).
In diesem Talk erfahrt ihr in Theorie und Praxis (inklusive Live-Coding), was Stream Gatherers sind und wie sie funktionieren, welche Gatherer im JDK bereits verfügbar sind und wie ihr sie effektiv einsetzt, wie ihr selbst eigene Gatherer implementieren könnt und wo die Grenzen der neuen API liegen.
Dauer: 45 Minuten
Wir alle kennen diese Situation: Je älter und größer eine Anwendung wird, desto aufwendiger und teurer wird es, sie zu erweitern und zu warten. Die verbreitete Schichtenarchitektur ist als Lösungsansatz unzureichend: Direkte und indirekte Abhängigkeiten aller Schichten zur Datenbank und anderen Infrastrukturkomponenten führen oft zu einer Aufweichung der Schichtengrenzen und einer Verflechtung von technischem und fachlichem Code.
Hexagonale Architektur rückt die Geschäftslogik ins Zentrum, und technische Details werden als Adapter hinter Schnittstellen (Ports) isoliert. Fachlicher und technischer Code kann so unabhängig voneinander entwickelt und getestet werden.
Ausgehend von den Zielen einer Softwarearchitektur und einem kritischen Blick auf die Schichtenarchitektur, schauen wir uns die hexagonale Architektur im Detail an. Ihr erfahrt, wie die Dependency Rule sicherstellt, dass es keine Abhängigkeiten von fachlichem zu technischem Code gibt und wie der Anwendungskern trotzdem auf die Infrastruktur zugreifen kann. Erfüllt die hexagonale Architektur die Ziele einer Softwarearchitektur? Welche Herausforderungen bringt sie mit sich? Wie unterscheidet sie sich von Onion und Clean Architecture, und welche Synergien ergeben sich im Zusammenspiel mit Microservices und Domain-Driven Design?
Mit neuem Wissen gerüstet, könnt ihr die Qualität und Lebensdauer eurer Softwareprojekte steigern und in Zukunft schneller auf neue Anforderungen reagieren.
Dauer: 40 Minuten
Threads, seit jeher fester Bestandteil von Java, haben ihre Grenzen: Mehr als ein paar Tausend kann man nicht starten, ohne die Systemstabilität zu gefährden. Für hoch skalierbare Anwendungen mussten wir bisher auf asynchrone Programmierung zurückgreifen. Doch asynchroner Code ist schwer zu schreiben, zu lesen und zu debuggen.
Jahrelang wurde im Rahmen von Project Loom an einer zukunftsweisenden Lösung gearbeitet: Mit fast 100.000 geänderten Codezeilen erschien in Java 21 endlich die finale Version von virtuellen Threads.
Diese benötigen um Größenordnungen weniger Ressourcen als herkömmliche Threads, insbesondere bei blockierenden Operationen. Anstelle von Tausenden stehen uns nun Millionen von Threads zur Verfügung. Das ermöglicht es uns, im traditionellen Thread-pro-Request-Stil hoch skalierbare Anwendungen zu schreiben, die einfacher zu warten, zu testen und zu debuggen sind als asynchrone Anwendungen.
Anhand einer Beispielanwendung führe ich euch von den Limitierungen der klassischen nebenläufigen Programmierung über asynchrone Ansätze bis zu den Einsatzmöglichkeiten und der Funktionsweise von virtuellen Threads. Mit einem abschließenden Überblick über Grenzen und potenzielle Fallstricke sowie einigen Tipps zur Migration bestehender Anwendungen werdet ihr bestens gerüstet sein, um virtuelle Threads in eurer täglichen Arbeit einzusetzen.
Dauer: 40 Minuten
Die Koordination nebenläufiger, potenziell blockierender Teilaufgaben stößt mit klassischen Ansätzen wie CompletableFuture und ExecutorService schnell an ihre Grenzen. So führt z. B. das Abbrechen von Teilaufgaben, sei es nach Fehlersituationen oder wenn wir nur das Ergebnis einer Teilaufgabe benötigen, schnell zu unübersichtlichen Verflechtungen von Geschäftslogik und Zustandsbehandlung. Wir sprechen dann von „Unstructured Concurrency”.
Mit dem StructuredTaskScope gibt es jetzt ein API für „Structured Concurrency”, das es uns erlaubt, Teilaufgaben gemeinsam zu starten und zu beenden, die Ergebnisse zusammenzuführen und bei Bedarf Teilaufgaben sauber abzubrechen.
An praxisnahen Beispielen zeige ich euch, dass für die meisten Anwendungsfälle durch vordefinierte Strategien wie „alle Teilaufgaben müssen erfolgreich sein” und „Abbruch, wenn eine Teilaufgabe erfolgreich ist” nur wenige, leicht verständliche Codezeilen erforderlich sind.
Und auch individuelle Anforderungen könnt ihr mit StructuredTaskScope sauber bewältigen – dafür zeige ich euch beispielhaft, wie ihr eine Strategie implementiert, die auf eine bestimmte Anzahl von Teilergebnissen wartet und dann das beste Ergebnis zurückliefert.
Dauer: 40 Minuten