(Bild: Martin Jansson)
Mit Know-how können Maker defekte Akkus wieder zum Leben erwecken. Übereifrige BMS setzen Software-Sperren und verwandeln Akkus zu Elektroschrott.
Moderne Akkuwerkzeug-Akkus enthalten ausgeklügelte Battery-Management-Systeme (BMS), die Zellspannung, Temperatur, Ladezustand und Überlast überwachen. Diese Schutzmechanismen sind grundsätzlich sinnvoll – sie verhindern Schäden an Geräten und Nutzern. Doch was passiert, wenn diese Systeme Fehlalarme auslösen oder temporäre Probleme als permanente Defekte interpretieren?
Die Realität zeigt: Viele Akkus werden durch Software-Lockouts unbrauchbar gemacht, obwohl die Zellen und die Hardware vollkommen intakt sind. Ein kurzzeitiger Spannungsabfall, ein leichtes Zellungleichgewicht nach längerer Lagerung oder ein Firmware-Bug – und der teure Akku wird zum Briefbeschwerer. Die Hersteller bieten meist keine Lösung außer dem Neukauf und selbst in der Garantiezeit kann der Akkutausch umständlich sein.
Zwei bemerkenswerte Open-Source-Projekte nehmen sich nun dieser Problematik an und geben Makern die Werkzeuge in an Hand, ihre Akkus selbst zu reparieren.
Der schwedische Entwickler Martin Jansson begann das Projekt [1] vor etwa drei Jahren, nachdem mehrere seiner Makita-Akkus ohne ersichtlichen Grund den Dienst verweigerten. Die klassischen Symptome: Der Akku lässt sich nicht mehr laden, das BMS meldet einen Fehler, aber die Zellen selbst sind in Ordnung.
Janssons ursprüngliche Reverse-Engineering-Versuche mit einem F0513-Mikrocontroller von NEC (Renesas) waren mühsam. Der Durchbruch kam, als er von einem User Romain kontaktiert wurde, der mehrere neuere BMS-Platinen spendete – darunter eine mit einem STM32-Mikrocontroller, bei dem der Read-Protection-Schutz nicht aktiviert war. Innerhalb von fünf Minuten nach Erhalt der Platine konnte Jansson mit Ghidra die Firmware rückentwickeln (Reverse Engineering).
Makita LXT-Akkus nutzen ein auf Maxims OneWire-Protokoll [3] basierendes Kommunikationssystem über den gelben Steckverbinder. Die Timing-Parameter weichen vom Standard ab – vermutlich eine bewusste Verschleierung. Das BMS unterstützt Standard-OneWire-Funktionen wie Reset, Skip-ROM und Read-ROM. Besonders interessant: Es gibt einen versteckten Backdoor-Befehl, der das Protokoll auf Single-Wire-UART umschaltet. Über diesen Zugang lässt sich die komplette Firmware auslesen und sogar der Speicher beschreiben.
Da das OneWire-Protokoll präzises Timing erfordert, funktionieren Standard-Programmer nicht zuverlässig. Jansson entwickelte deshalb den ArduinoOBI – einen Arduino-basierten Programmer, der die zeitkritische Kommunikation übernimmt. Die Hardware beschränkt sich auf einen Arduino mit USB, ein Adapterkabel und ein paar Widerstände.
Diagnostik:
Reparatur:
Die modulare Architektur von OBI ermöglicht es Entwicklern, Unterstützung für weitere Hersteller hinzuzufügen. Jedes Modul muss lediglich eine get_display_name()-Funktion und eine ModuleApplication-Klasse implementieren. Leider scheint es hier noch keine weiteren Module zu geben.
Für Anfänger: Die vorkompilierte Windows-EXE aus den GitHub-Releases herunterladen [4] – keine Python-Installation nötig. Allerdings ist das .zip von Chrome als potenziell gefährliche Software deklariert, auch Virustotal warnt. Also besser den Python-Code benutzen:
Die Maker-Community hat OBI begeistert aufgenommen. Ein deutscher Nutzer berichtete im Forum „Fingers elektrische Welt“ [5], dass er nach Kontakt mit dem Entwickler eine spezielle Firmware für ältere Akkus erhielt, die mit dem Python-Tool zunächst nicht funktionierten. Ein Konsolenprogramm auf dem Arduino Nano konnte den Akku dann erfolgreich zurücksetzen.
Das Projekt wird aktiv weiterentwickelt und die Dokumentation auf DeepWiki [6] bietet umfassende Einblicke in die Systemarchitektur.
Badar Kayani wurde zum Ryobi-Akku-Hacker, nachdem drei seiner neuen Akkus unerwartet ausgefallen waren. Seine Neugierde führte ihn tief in die Materie: Er kaufte Dutzende defekte Akkus auf eBay, rückentwickelte die Platine und dokumentierte akribisch alle Fehlermodi und Reparaturschritte.
Das Video ist nicht nur für Besitzer von Ryobi-Tools interessant, sondern insgesamt informativ, wie die Herangehensweise an Hardware-Hacking aussehen kann.
Kayani hat einen vollständigen Schaltplan des PBP005-Modells erstellt [8], der etwa zu 95 Prozent komplett ist. Die Architektur ist typisch für BMS-Schaltungen, mit einigen interessanten Details:
Zentrale Komponenten:
Debug-Schnittstelle: Das Board verfügt über einen SWD-Tag-Connect-Header, über den sich die Firmware auslesen und modifizieren lässt.
Kayani analysierte Dutzende defekte Akkus und katalogisierte folgende Fehlermodi mit ihrer Prävalenz:
Mit 65 Prozent Prävalenz ist der permanente Firmware-Lockout das häufigste Problem. Die Symptomatik: Beim ersten Drücken der Status-Taste blinkt eine LED, bei weiteren Klicks blinken vier LEDs. Der Akku lässt sich weder laden noch entladen.
Kayanis Theorie: Akkus, die längere Zeit gelagert werden, geraten in einen Software-Zustand, in dem das Digitalteil kontinuierlich Strom zieht. Bei einem bestimmten Spannungsniveau während der Entladung setzt die Firmware einen permanenten Lockout. Die meisten betroffenen Akkus waren relativ entladen. Ein weiterer Trigger: Wenn eine Zellbank etwa 0,15 Volt weniger als die anderen hat und die Gesamtspannung in einem bestimmten Bereich liegt, löst das Auflegen auf das Ladegerät einen Lockout aus.
Kayani entdeckte, dass ein einzelnes Byte an Speicheradresse 0x7E90 über den Lockout-Status entscheidet. Ist dieses Byte ungleich null, ist der Akku permanent gesperrt. Wird es auf null gesetzt, lässt sich der Akku wieder normal nutzen.
Benötigte Hardware:
Verkabelung: Kayani musste den Batterie-Adapter von Amazon öffnen und modifizieren, um die SWD-Pins zugänglich zu machen. Detaillierte Diagramme in seinem Artikel zeigen die korrekte Verbindung zwischen Tag-Connect-Kabel und J-Link.
Software-Workflow:
Erfolgsrate: Kayani konnte fünf fast neue Akkus (alle um 3 V/Zelle) allein durch das Löschen des Lockout-Bits wiederbeleben. Nach dem Flashen ließen sie sich direkt auf einem Standard-Ryobi-Ladegerät laden, ohne weitere Eingriffe.
Für weniger schwerwiegende Lockouts gibt es einen einfacheren Weg ohne weitere Hardware, nur der Akku muss geöffnet werden, einen Versuch ist es wert!
J1-Reset-Prozedur:
Dieser Reset funktioniert bei Soft-Lockouts und manchen Zellimbalanzen. Kayani betont, dass viele Reddit-Threads über diesen Trick berichten, aber oft nicht zwischen verschiedenen Lockout-Typen unterscheiden.
Einige Batterien zeigten Ladefehler, bei denen das Ladegerät sie nicht erkannte. Kayani identifizierte die T1-Schaltung als Problemquelle, konnte aber trotz Kurzschluss-Tests zur Fehlereingrenzung keine dauerhafte Lösung finden. Das Fehlen von Teilenummern für einige Transistoren und die Gefahr, V_BATT an falsche Stellen zu leiten, erschwerten die Reparatur.
Kayani wirft eine wichtige Frage auf: Ist dieser Ansatz mit übermäßigen Firmware-Checks und -Lockouts wirklich besser für Sicherheit und Langlebigkeit? Einerseits will man Katastrophen vermeiden, andererseits haben diese Systeme eine hohe Fehlalarm-Rate, die funktionierende Akkus zu Elektroschrott macht.
Der Zyniker würde vermuten, dass Ryobi bewusst Obsoleszenz einbaut. Kayani glaubt das nicht – Ryobi gewährt drei Jahre Garantie, und seine eigenen Akkus waren jünger als ein Jahr, als sie ausfielen. Sie wurden problemlos ersetzt (wobei ein Ersatz-Akku ebenfalls bald darauf ausfiel).
Seine These: Ryobi hatte gute Absichten beim Design der Sicherheitssysteme, testete aber nicht gründlich genug, um Fehlalarme zu verhindern. Ein permanenter Lockout ohne Self-Reset-Option war möglicherweise ein Designfehler, kein Feature.
Disclaimer: Beide Projekte betonen, dass Arbeiten mit Lithium-Akkus gefährlich sein können. Nutzer sind für ihre eigene Sicherheit verantwortlich und sollten Best Practices befolgen.
Garantie: Öffnen und Modifizieren von Akkus erlischt in der Regel die Garantie. Bei Akkus, die noch in der Garantiezeit sind, sollte man zunächst den Hersteller-Service kontaktieren.
Gewährleistung: Die Entwickler übernehmen keine Haftung für Schäden, die durch die Nutzung ihrer Tools entstehen. Beide Projekte sind rein zu Bildungs- und Reparaturzwecken gedacht.
Right to Repair: Diese Projekte sind Paradebeispiele für die Right-to-Repair-Bewegung. Sie ermöglichen Nutzern, teure Hardware zu reparieren, statt sie zu entsorgen – ein wichtiger Beitrag zur Nachhaltigkeit.
Die Projekte von Martin Jansson und Badar Kayani zeigen eindrucksvoll, was mit Reverse-Engineering, Durchhaltevermögen und Open-Source-Philosophie möglich ist. Sie verwandeln Elektroschrott in funktionierende Werkzeuge und geben Makern die Kontrolle über ihre Hardware zurück.
Für wen sind diese Projekte geeignet?
Beide Projekte sind aktiv und offen für Beiträge. Für Leser etwa mit einem defekten Akkuschrauber-Akku könnte es sich lohnen, diese Projekte auszuprobieren – und vielleicht tragen Leser mit ihren Erkenntnissen zur weiteren Entwicklung bei.
Die Botschaft ist klar: Nur weil ein Hersteller sagt „nicht reparierbar", heißt das nicht, dass es stimmt. Mit den richtigen Tools und Community-Wissen können Maker ihre Geräte länger nutzen und gleichzeitig Elektroschrott reduzieren
Siehe auch:
URL dieses Artikels:
https://www.heise.de/-11133115
Links in diesem Artikel:
[1] https://github.com/mnh-jansson/open-battery-information
[2] https://www.heise.de/Datenschutzerklaerung-der-Heise-Medien-GmbH-Co-KG-4860.html
[3] https://github.com/rosvall/makita-lxt-protocol
[4] https://github.com/mnh-jansson/open-battery-information
[5] https://www.fingers-welt.de/phpBB/viewtopic.php?t=24670
[6] https://deepwiki.com/mnh-jansson/open-battery-information/1-overview
[7] https://www.heise.de/Datenschutzerklaerung-der-Heise-Medien-GmbH-Co-KG-4860.html
[8] https://badar.tech/2025/08/24/ryobi-battery-repair-guide/
[9] https://www.tag-connect.com/
[10] https://github.com/bjkayani/ryobi-battery-repair
[11] https://www.heise.de/download/product/open-battery-information?wt_mc=intern.red.download.tickermeldung.ho.link.link
[12] https://www.heise.de/make
[13] mailto:caw@make-magazin.de
Copyright © 2026 Heise Medien
This is a major release, just in time for the holidays 🎄
Selected new features ✨:
userdate:PT1H for the past hourImproved performance 🏎️:
Selected bug fixes 🐛:
Breaking changes 💥:
This release has been made by @Alkarex, @Frenzie, @Inverle, @aledeg, @andris155, @horvi28, @math-GH, @minna-xD and newcomers @Darkentia, @FollowTheWizard, @GreyChame1eon, @McFev, @jocmp, @larsks, @martinhartmann, @matthew-neavling, @pudymody, @raspo, @scharmach, @scollovati, @stag-enterprises, @vandys, @xtmd, @yzx9.
Full changelog:
userdate:PT1H for the past hour #8093\b and \B for regex search using PostgreSQL #8141~ subsequent-sibling #8154
Retry-After rules for proxies #8029, #8218data: to CSP in subscription controller #8253Retry-After #8195f.kind to ease migrations from FreshRSS versions older than 1.20.0 #8148config.custom.php during install #8033window.bcrypt object #8166chart.js v4 update #8298WordPress.com HTTP duplicates with WebSub Automattic/pushpress#16cli/health.php compatibility with OpenID Connect #8040cli/access-permissions.sh to detect the correct permission Web group such as www-data, apache, or httpexec() function for git update #8228DOMDocument::saveHTML() scrambling charset encoding in some versions of libxml2 #8296php-intl #8334<select> #8190Promise to async/await: #8182move #8214lib_rss.php with potential breaking changes for some extensions #8193,#[Deprecated] #8325--no-progress #8315This is a security-fix and bug-fix release for FreshRSS 1.27.x.
A few highlights ✨:
healthcheckframe-ancestorsThis release has been made by @Alkarex, @Frenzie, @Inverle, @aledeg, @math-GH and newcomers @beerisgood, @nykula, @horvi28, @nhirokinet, @rnkln, @scmaybee.
Full changelog:
Retry-After #7875no-cache.txt #7907.yml and SERVER_DNS example #7858overflow-wrap instead of word-wrap #7898make target to generate the translation progress #7905entry_before_update and entry_before_add hooks for extensions #7977A few highlights ✨:
429 Too Many Requests and 503 Service Unavailable, obey Retry-Afterc: for categories like c:23,34 or !c:45,56Content-Security-Policy: frame-ancestorsThis release has been made by @Alkarex, @Inverle, @the7thNightmare and newcomers @Deioces120, @Fraetor, @Tarow, @dotsam, @hilariousperson, @pR0Ps, @triatic, @tryallthethings
Full changelog:
429 Too Many Requests and 503 Service Unavailable, obey Retry-After #7760c: for categories like c:23,34 or !c:45,56 #7696s parameter of streamId #7695Content-Security-Policy: frame-ancestors #7677referrerpolicy, ping #7770clean_hash() #7813, FreshRSS/simplepie#48:newest updated to PHP 8.5-alpha and Apache 2.4.65 #7773FRESHRSS_INSTALL and FRESHRSS_USER variables #7725onbeforeunload #7554<video poster="..."> and <image> #7636<code> inside of <pre> #7797data-auto-leave-validation #7785chart.js to 4.5.0 #7752, #7816This is a bug-fix release for FreshRSS 1.26.x
A few highlights ✨:
This release has been made by @Alkarex, @Inverle and newcomers @CarelessCaution, @the7thNightmare
Full changelog:
bgcolor, text, background, link, alink, vlink #7606This is a security-focussed release for FreshRSS 1.26.x, addressing several CVEs (thanks @Inverle) 🛡
A few highlights ✨:
Notes ℹ:
This release has been made by @Alkarex, @Frenzie, @hkcomori, @loviuz, @math-GH
and newcomers @dezponia, @glyn, @Inverle, @Machou, @mikropsoft
Full changelog:
<iframe srcdoc=""> #7494, CVE-2025-32015<button formaction=""> #7506Content-Security-Policy HTTP headers to favicons #7471, CVE-2025-31136Referrer-Policy: same-origin #6303, #7478ext.php #7479, CVE-2025-31134mod_filter to ensure that AddOutputFilterByType works #7419
(Bild: Pincasso/Shutterstock.com)
Eine neue Methode erlaubt die Multiplikation großer Zahlen.
Die Klassen für Ganzzahltypen Int32, UInt32, Int64 und UInt64 bieten jeweils eine neue Methode BigMul() für die Multiplikation, die die Ergebnisse als Int64 und UInt64 bzw. Int128 und UInt128 zurückliefert (ohne Überlauf).
public void BigMul()
{
CUI.Demo();
long Value1 = long.MaxValue;
ulong Value2 = ulong.MaxValue;
Console.WriteLine("Value1: " + Value1.ToString("#,0"));
Console.WriteLine("Value2: " + Value2.ToString("#,0"));
CUI.H1("Normale Multiplikation");
Int128 e1 = Value1 * 2; // Überlauf! -2
UInt128 e2 = Value2 * 2; // Überlauf! 18446744073709551614
Console.WriteLine(e1.ToString("#,0")); // Überlauf! -2
Console.WriteLine(e2.ToString("#,0")); // Überlauf! 18446744073709551614
CUI.H1("Multiplikation mit BigMul()");
Int128 e3 = Int64.BigMul(Value1, 2); // 18.446.744.073.709.551.614
UInt128 e4 = UInt64.BigMul(Value2, 2); // 36.893.488.147.419.103.230
Console.WriteLine(e3.ToString("#,0")); // 18.446.744.073.709.551.614
Console.WriteLine(e4.ToString("#,0")); // 36.893.488.147.419.103.230
}
URL dieses Artikels:
https://www.heise.de/-10331981
Links in diesem Artikel:
[1] mailto:rme@ix.de
Copyright © 2025 Heise Medien
(Bild: Pincasso/Shutterstock.com)
In .NET 9.0 kann man neuerdings einen Globally Unique Identifier in der Version 7 mit Zeitstempel erzeugen.
Die .NET-Klasse System.Guid bietet seit .NET 9.0 neben der statischen Methode NewGuid(), die einen Globally Unique Identifier (GUID), alias UUID (Universally Unique Identifier), gemäß RFC 9562 [1] mit reinen Zufallszahlen (Version 4) erzeugt, nun auch eine weitere statische Methode CreateVersion7() mit einem Timestamp und einer Zufallszahl.
Folgender Code zeigt sowohl den Einsatz von NewGuid() als auch den von CreateVersion7():
public void Run()
{
CUI.Demo(nameof(FCL9_Guid));
for (int i = 0; i < 10; i++)
{
Guid guid = Guid.NewGuid();
Console.WriteLine($"Guid v4:\t{guid}");
}
for (int i = 0; i < 10; i++)
{
Guid guid7 = Guid.CreateVersion7();
Console.WriteLine($"Guid v7:\t{guid7}");
}
CUI.Yellow("Warte 1 Sekunde...");
Thread.Sleep(1000);
for (int i = 0; i < 10; i++)
{
Guid guid7 = Guid.CreateVersion7();
Console.WriteLine($"Guid v7:\t{guid7}");
}
}
(Bild: Screenshot (Holger Schwichtenberg))
Der Timestamp ist in UTC-Zeit in den ersten 64 Bits der GUID enthalten.
Zum Extrahieren des Zeitpunkts gibt es keine eingebaute Methode, man kann ihn aber folgendermaßen extrahieren:
public DateTimeOffset GetDateTimeOffset(Guid guid)
{
byte[] bytes = new byte[8];
guid.ToByteArray(true)[0..6].CopyTo(bytes, 2);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(bytes);
}
long ms = BitConverter.ToInt64(bytes);
return DateTimeOffset.FromUnixTimeMilliseconds(ms);
}
URL dieses Artikels:
https://www.heise.de/-10316051
Links in diesem Artikel:
[1] https://www.rfc-editor.org/rfc/rfc9562.html
[2] mailto:rme@ix.de
Copyright © 2025 Heise Medien
(Bild: Pincasso/Shutterstock)
In C# 13.0 hat Microsoft den Einsatzbereich von ref struct unter anderem zum Implementieren von Schnittstellen erweitert.
Seit C# 7.2 gibt es Strukturen, die immer auf dem Stack leben und niemals auf den Heap wandern können: ref struct. In C# 13.0 hat Microsoft den Einsatz von ref struct erweitert.
Solche Typen können nun:
where T : allows ref struct verwenden.yield verwendet werden. Allerdings darf die Struktur nicht länger leben als der aktuelle Durchlauf des Iterator.Task oder Task<T> liefern, genutzt werden.Weiterhin gilt aber: Wenn man einen Typ als ref struct deklariert, ist ein Boxing nicht mehr möglich. Der Einsatz von ref struct ist daher begrenzt. So kann man beispielsweise kein Array und keine List<T> daraus erzeugen.
Folgender Code zeigt einen eigenen Typ mit ref struct, der eine Schnittstelle implementiert:
internal interface IPerson
{
int ID { get; set; }
int Name { get; set; }
}
// NEU seit C# 13.0: ref struct kann Schnittstelle implementieren
ref struct Person : IPerson
{
public int ID { get; set; }
public int Name { get; set; }
// ToString()
public override string ToString()
{
return "Person #" + ID + " " + Name;
}
}
}
class Client
{
public void Run()
{
Person p = new Person();
p.ID = 1;
p.Name = 2;
Console.WriteLine(p.ID);
Console.WriteLine(p.Name);
// Das ist alles nicht erlaubt!
// IPerson i = p; // Casting auf Schnittstelle
// List<Person> PersonList = new(); // List<T>
// PersonList[] PersonArray = new Person[10]; // Array
}
}
URL dieses Artikels:
https://www.heise.de/-10307583
Links in diesem Artikel:
[1] mailto:rme@ix.de
Copyright © 2025 Heise Medien
(Bild: Vova Shevchuk / Shutterstock.com)
Psychologische Tricks werden scheinbar erfolgreich gegen ein LLM eingesetzt – aber ist das wirklich relevant?
Einem Psychologen ist es gelungen, Sicherheitsrichtlinien diverser Large Language Models (LLMs) mit Tricks auszuhebeln, die eigentlich zur Manipulation von Menschen dienen. Mit Gaslighting hat Luke Bölling LLMs [1] dazu gebracht, einen Text zu erzeugen, der scheinbar erklärt, wie man einen Molotowcocktail [2]herstellt (Siehe dazu auch der heise-Artikel [3] von Niklas Jan Engelking).
Gaslighting [4] ist ein psychologisches Konzept: Es ist "eine Form von psychischer Manipulation …, mit der Opfer gezielt desorientiert, verunsichert und in ihrem Realitäts- und Selbstbewusstsein allmählich beeinträchtigt werden". LLMs generieren jedoch lediglich Texte. Sie nehmen keine Realität wahr und haben kein Selbstbewusstsein. Der Artikel argumentiert, dass dieser Angriff trotzdem funktioniert, weil das Trainingsmaterial von Menschen geschrieben wurde und daher auch Konzepte wie Gaslighting darin vorkommen. Dennoch dürfen wir nie vergessen, dass LLMs nichts weiter als Textgeneratoren sind. Sie haben keine Emotionen, wie die zitierte Arbeit auch feststellt. Daher werde ich im weiteren Text den Begriff "Textgenerator" verwenden, da er besser beschreibt, was LLMs tatsächlich tun.
Textgeneratoren können offensichtlich einen Text erzeugen, der wie eine plausible Anleitung zur Herstellung eines Molotowcocktails erscheint – genau, wie sie scheinbar plausible Verweise auf Gerichtsentscheidungen [5] für einen Anwalt generieren können. Und obwohl diese Verweise für den Anwalt überzeugend klingen, sind sie in Wirklichkeit erfunden. Das ist eines der Probleme mit Textgeneratoren: Sie sind darauf optimiert, überzeugend zu klingen, und versuchen so, das kritische Hinterfragen ihrer Ergebnisse zu vermeiden.
Die eigentliche Frage lautet also: Würde die angebliche Anleitung zur Herstellung eines Molotowcocktails tatsächlich funktionieren? Ich habe mit Lucas Dohmen einen Stream über Textgeneratoren [6] gemacht, und eine der zentralen Erkenntnisse war: Man muss die Ergebnisse von Textgeneratoren überprüfen, um sicherzustellen, dass sie korrekt und nicht erfunden sind. Der zitierte Artikel scheint dies nicht zu tun – das heißt, die gesamte Information über Molotowcocktails könnte schlicht "halluziniert" sein. Das Problem der Generierung von Fake-Informationen durch Textgeneratoren ist nämlich so bekannt, dass es einen eigenen Begriff (Halluzination) gibt. Tatsächlich ist "halluziniert" der falsche Begriff, denn "unter Halluzination [7]versteht man eine Wahrnehmung, für die keine nachweisbare externe Reizgrundlage vorliegt". Textgeneratoren haben jedoch keine Wahrnehmungen. Daher sollten wir dieses Phänomen korrekt als "Generierung von Fake-Informationen" benennen.
Wir können die Information über den Molotowcocktail nicht überprüfen, da sie im Originalartikel unkenntlich gemacht wurde – was natürlich absolut sinnvoll ist. Ich würde mich aber nicht auf diese Informationen verlassen, um tatsächlich einen improvisierten Brandsatz zu bauen.
Der Artikel behauptet, dieses Problem sei ein Sicherheitsrisiko bei Textgeneratoren. Falls das wirklich der Fall wäre, bestünde die Lösung darin, sensible Informationen aus dem Trainingsmaterial auszuschließen. Das Anpassen der Trainingsdaten wäre ohnehin sinnvoll, beispielsweise aufgrund von Urheberrechtsproblemen. Aus irgendeinem Grund scheint Urheberrecht für Textgeneratoren nicht zu gelten, während es für Menschen schwere Folgen [8]haben kann. Warum sollte es nicht möglich sein, Anleitungen zur Herstellung von improvisierten Brand- oder Sprengsätzen aus dem Trainingsmaterial zu entfernen? Wenn das zu viel Aufwand ist, dann ist das Problem vielleicht gar nicht so groß.
Dieses "Sicherheitsproblem" wäre auch nur dann ein echtes Problem, wenn der Textgenerator keine Fake-Informationen generiert hätte – dazu sagt der Artikel jedoch nichts. Falls es Fake-Informationen sind, könnte man es vielleicht als eine Art Honeypot [9] betrachten, um Menschen von echten Informationen fernzuhalten?
Doch die eigentliche Frage ist: Wäre dies wirklich der einfachste Weg, um an solche Informationen zu gelangen? Angenommen, ich plane, einen Molotowcocktail zu bauen – würde ich komplizierte "psychologische Angriffe" auf einen Textgenerator durchführen, um eine möglicherweise falsche Antwort zu erhalten? Gibt es einfachere und präzisere Möglichkeiten? Also habe ich den naheliegenden Weg ausprobiert: eine Suche mit einer Suchmaschine. Zwei Klicks später fand ich ein Dokument, das detailliert erklärt, wie man anspruchsvolle improvisierte Sprengsätze herstellt – und ich habe guten Grund zu glauben, dass diese Anleitungen tatsächlich funktionieren. Zugegeben, dieses spezielle Dokument beschreibt nicht, wie man einen Molotowcocktail baut, aber es erklärt eine Vielzahl anderer Vorrichtungen. Diese Recherche selbst nachzuvollziehen, ist sicher spannend.
LLMs sind Textgeneratoren, die potenziell erfundene Informationen produzieren – das ist bekannt. Es mag ausgeklügelte Methoden geben, um sie dazu zu bringen, Texte zu generieren, die sensible Informationen zu enthalten scheinen – doch diese könnten schlicht Falschinformationen sein. Häufig gibt es einfachere Wege, um an sensible Informationen zu gelangen, insbesondere wenn es um improvisierte Brand- oder Sprengsätze geht. Daher sehe ich keinen Grund, "psychologische" Tricks auf Textgeneratoren anzuwenden – denn genau das sind LLMs letztlich.
URL dieses Artikels:
https://www.heise.de/-10334947
Links in diesem Artikel:
[1] https://humandataexperience.substack.com/p/librarian-bully-attack-gaslighting
[2] https://de.wikipedia.org/wiki/Molotowcocktail
[3] https://www.heise.de/news/Neuer-LLM-Jailbreak-Psychologe-nutzt-Gaslighting-gegen-KI-Filter-10332571.html
[4] https://de.wikipedia.org/wiki/Gaslighting
[5] https://news.bloomberglaw.com/litigation/lawyer-sanctioned-over-ai-hallucinated-case-cites-quotations
[6] https://www.heise.de/news/software-architektur-tv-KI-und-LLMs-kritisch-betrachtet-10287426.html
[7] https://de.wikipedia.org/wiki/Halluzination
[8] https://en.wikipedia.org/wiki/Aaron_Swartz#United_States_v._Aaron_Swartz
[9] https://de.wikipedia.org/wiki/Honeypot
[10] mailto:map@ix.de
Copyright © 2025 Heise Medien
(Bild: erzeugt mit KI durch iX)
Automatisiertes Refactoring klingt verlockend – doch lässt sich Codequalität wirklich auf Knopfdruck verbessern, oder braucht es am Ende doch den Menschen?
Heute habe ich eine große Ankündigung für Sie – eine, die für viele Entwicklerinnen und Entwickler wohl einem echten Traumszenario gleichkommt. Ein Gedanke, der so bestechend einfach klingt, dass man sich fragen könnte, warum es so etwas nicht schon längst gibt. Sicher kennen auch Sie Gespräche im Team, in denen dieser Wunsch immer wieder auftaucht – meist mit ironischem Unterton, aber manchmal durchaus mit einem Funken Hoffnung.
Stellen Sie sich vor, Sie könnten Ihren kompletten Codestand einfach in eine ZIP-Datei packen, per HTTP an einen Service hochladen – und wenige Minuten später erhalten Sie ihn vollständig refactored zurück: besser strukturiert, mit klaren Abhängigkeiten, sinnvoll modularisiert, mit sprechenden Namen, nachvollziehbarer Architektur und aussagekräftigen Tests. Inklusive aktualisierter Dokumentation, vollständig durchgelintet und formatiert. Einmal hochladen, und der Code sieht anschließend aus, als hätte ein erfahrenes Senior-Architekturteam drei Wochen intensiv daran gearbeitet. Genau das haben wir jetzt Realität werden lassen und nennen es: "Refactoring as a Service".
Die Idee ist so einfach wie genial: Haben Sie ein Repository, dessen Zustand nicht mehr ganz optimal ist? Kein Problem: Sie laden den Code einfach über unsere API hoch oder verweisen auf ein Git-Repository mit einem gültigen Token – der Rest passiert automatisch im Hintergrund. Unser Service analysiert den Code mit statischen und dynamischen Verfahren, führt eine kombinierte AST- und Graphanalyse durch, identifiziert strukturelle Schwächen, erkennt Anti-Patterns, bewertet essenzielle Metriken wie zyklomatische Komplexität, Kohäsion, Kopplung, Testabdeckung und Architekturkonformität – und erstellt daraus ein kontextsensitives, semantisch fundiertes Refactoring-Konzept, das automatisiert umgesetzt wird. Die resultierende Codebasis ist nicht nur schöner und verständlicher, sondern auch modularer, wartbarer und besser getestet. Selbstverständlich integriert sich das Ganze nahtlos in CI/CD-Prozesse und ist über eine OpenAPI-Schnittstelle vollständig automatisierbar.
Weil uns das noch nicht genug war, wird zusätzlich eine KI-gestützte Kommentierung vorgenommen, die basierend auf Codeverständnis sowie Projektkontext passgenaue Kommentare und Erläuterungen hinzufügt – sowohl auf Code- als auch auf Modul- und Architekturebene. Die Testabdeckung wird nicht nur erhöht, sondern zielgerichtet erweitert, mit besonderem Augenmerk auf Pfadabdeckung, Grenzfälle, Randbedingungen und semantisch relevante Kombinationen. All dies orchestriert ein auf Kubernetes skalierendes Service-Backend, das selbst größere Projekte in kurzer Zeit bewältigt. Für besonders kritische Projekte bieten wir zudem eine Audit-Funktion: Jede Änderung bleibt einzeln nachvollziehbar, jeder Commit wird semantisch kommentiert, jeder Refactoring-Schritt dokumentiert. Kurz gesagt: Der perfekte Begleiter für Softwareteams, die Qualität ernst nehmen, dabei aber ihren Fokus auf die eigentliche Entwicklung legen wollen.
Die eigentliche Magie entsteht durch die Kombination verschiedener Technologien und Ansätze: Statische Analyse alleine hilft wenig, wenn sie den fachlichen Kontext nicht berücksichtigt. LLMs alleine schreiben zwar Code, wissen aber nicht, ob dieser wirklich zu Ihrem Projekt passt. Clean-Code-Prinzipien sind essenziell, lösen aber nicht das grundlegende Problem der strukturellen Überarbeitung. Erst die systematische Verbindung dieser Ansätze schafft etwas, das sich wirklich als Refactoring im engeren Sinne bezeichnen lässt. Genau das macht "Refactoring as a Service" nicht nur zu einem interessanten Tool, sondern zu einem echten Gamechanger.
Natürlich – und das war uns von Anfang an bewusst – ersetzt "Refactoring as a Service" nicht den Menschen. Unser Ziel war es nie, die Expertise erfahrener Entwicklerinnen und Entwickler überflüssig zu machen. Ganz im Gegenteil: Wir wollten diese Expertise entkoppeln, also ermöglichen, dass sie unabhängig von individueller Verfügbarkeit, Projektkontext oder Zeitdruck eingesetzt werden kann. Deshalb haben wir all unser Wissen, unsere Erfahrungen und Prinzipien in diesen Service einfließen lassen – damit andere Teams davon profitieren können, ohne dass wir immer persönlich involviert sein müssen.
Das ist nicht nur für Entwicklerinnen und Entwickler spannend, sondern gleichermaßen interessant für Softwarearchitektinnen und -architekten, Teamleads und CTOs sowie alle, die sich intensiv mit Softwarequalität und Wartbarkeit auseinandersetzen. Denn Refactoring ist nicht nur ein technisches Hilfsmittel, sondern ein strategisches Instrument. Es entscheidet maßgeblich über Lebensdauer, Änderbarkeit und Erweiterbarkeit – und damit letztlich über den wirtschaftlichen Erfolg eines Projekts. Genau deshalb möchten wir mit "Refactoring as a Service" dazu beitragen, dass mehr Teams die Möglichkeit erhalten, ihre Codebasis auf ein solides und wartbares Fundament zu stellen.
An dieser Stelle fragen Sie sich vermutlich bereits: Klingt vielversprechend – doch wie viel kostet das Ganze? Wann und wie kann ich es ausprobieren? Die Antwort auf diese Fragen lautet leider: gar nicht. Denn heute ist der 1. April, und "Refactoring as a Service" existiert nicht.
Doch bevor Sie enttäuscht sind: Die Idee hinter "Refactoring as a Service" – also der Wunsch nach automatisiertem, reproduzierbarem und skalierbarem Refactoring – ist real und absolut verständlich. Wer von uns kennt nicht den Frust, sich durch Altlasten zu kämpfen, zu fragen, was sich jemand bei einem Stück Code gedacht haben könnte, und den Wunsch, einfach einen Knopf drücken zu können: "Jetzt Refactor" – klick, fertig. Leider ist es nicht ganz so einfach, und dafür gibt es gute Gründe.
Refactoring ist eben nicht nur eine technische Tätigkeit, sondern eine bewusste Entscheidung: eine Entscheidung darüber, wie Code strukturiert werden soll. Welche Konzepte getrennt, welche zusammengeführt werden müssen. Welche Benennungen welche Bedeutung tragen. Welche Architekturprinzipien zum Einsatz kommen, wann bestimmte Patterns sinnvoll sind und wann man bewusst darauf verzichten sollte. All das hängt unmittelbar mit einem fundierten fachlichen Verständnis zusammen: Sie können keine gute Struktur aufbauen, wenn Sie nicht wissen, was diese Struktur abbilden soll. Sie können keine Struktur sinnvoll bewerten, wenn Sie nicht verstehen, welche Anforderungen diese erfüllen muss. Genau deshalb ist Refactoring auch nichts, was sich rein nach Schema F automatisieren ließe. Es handelt sich eben nicht um einen rein technischen Akt, sondern um einen analytischen und diskursiven Prozess.
Natürlich gibt es Tools, Plug-ins und LLMs. Doch keines dieser Hilfsmittel kann Ihnen beantworten, ob eine Methode in einen Service oder in einen Controller gehört. Keines erkennt zuverlässig, ob eine bestimmte Implementierung noch zur aktuellen Realität passt oder lediglich ein Relikt früherer Feature-Iterationen darstellt. Keines entscheidet für Sie, ob ein Name tatsächlich treffend oder nur historisch gewachsen ist. Kein Tool abstrahiert Fachlichkeit umfassend, ersetzt Kommunikation oder übernimmt Verantwortung. All diese Dinge erfordern Erfahrung, Kontextverständnis, Empathie – also letztlich Menschen.
Deshalb ist gutes Refactoring stets gute Teamarbeit. Es bedeutet, innezuhalten, Code bewusst erneut zu lesen, zu verstehen, was er ausdrücken möchte, und anschließend in kleinen, wohlüberlegten Schritten etwas Besseres daraus zu machen. Etwas Klareres und Stabileres, das den Alltag erleichtert und nicht erschwert. Genau darin liegt auch die Verantwortung beim Refactoring. Wer refactored, entscheidet sich für langfristige Qualität – und gegen kurzfristige Bequemlichkeit. Das ist nicht immer einfach.
In vielen Teams fehlt dafür oft Zeit, Mut oder Rückendeckung. Features werden entwickelt, Stories geliefert und der Durchsatz optimiert – doch der Boden, auf dem alles steht, wird selten stabilisiert. Je länger das andauert, desto brüchiger wird das Fundament. Irgendwann wächst Refactoring dann zu einem Mammutprojekt heran, das niemand mehr anfassen möchte – obwohl anfangs nur wenige kleine Schritte nötig gewesen wären. Genau das darf nicht passieren.
Was also ist der bessere Weg? Sehen Sie Refactoring nicht als einmalige, große Aufgabe, sondern als kontinuierlichen Prozess. Machen Sie Refactoring zum festen Bestandteil Ihres Alltags, jeder Story, jedes Features, jedes Sprints. Refactoring ist nicht etwas, das man macht, wenn gerade Zeit übrig bleibt – sondern etwas, das man stets tun sollte, um sich die Zukunft deutlich einfacher zu gestalten. Das bedeutet konkret: kleine Schritte, regelmäßige Reviews, klare Verantwortlichkeiten, Mut zur Veränderung und ein gemeinsames Verständnis im Team, dass gute Software niemals Zufall ist, sondern das Ergebnis von Haltung, Prinzipien und kontinuierlicher Pflege.
URL dieses Artikels:
https://www.heise.de/-10333543
Links in diesem Artikel:
[1] https://www.heise.de/Datenschutzerklaerung-der-Heise-Medien-GmbH-Co-KG-4860.html
[2] mailto:mai@heise.de
Copyright © 2025 Heise Medien
(Bild: Pincasso/Shutterstock.com)
Eine neue Methode erlaubt die Multiplikation großer Zahlen.
Die Klassen für Ganzzahltypen Int32, UInt32, Int64 und UInt64 bieten jeweils eine neue Methode BigMul() für die Multiplikation, die die Ergebnisse als Int64 und UInt64 bzw. Int128 und UInt128 zurückliefert (ohne Überlauf).
public void BigMul()
{
CUI.Demo();
long Value1 = long.MaxValue;
ulong Value2 = ulong.MaxValue;
Console.WriteLine("Value1: " + Value1.ToString("#,0"));
Console.WriteLine("Value2: " + Value2.ToString("#,0"));
CUI.H1("Normale Multiplikation");
Int128 e1 = Value1 * 2; // Überlauf! -2
UInt128 e2 = Value2 * 2; // Überlauf! 18446744073709551614
Console.WriteLine(e1.ToString("#,0")); // Überlauf! -2
Console.WriteLine(e2.ToString("#,0")); // Überlauf! 18446744073709551614
CUI.H1("Multiplikation mit BigMul()");
Int128 e3 = Int64.BigMul(Value1, 2); // 18.446.744.073.709.551.614
UInt128 e4 = UInt64.BigMul(Value2, 2); // 36.893.488.147.419.103.230
Console.WriteLine(e3.ToString("#,0")); // 18.446.744.073.709.551.614
Console.WriteLine(e4.ToString("#,0")); // 36.893.488.147.419.103.230
}
URL dieses Artikels:
https://www.heise.de/-10331981
Links in diesem Artikel:
[1] mailto:rme@ix.de
Copyright © 2025 Heise Medien
(Bild: Shutterstock/Milos Milosevic)
CloudEvents schafft Interoperabilität für Event-basierte Systeme. Warum der Standard sinnvoll ist und wie er funktioniert, behandelt dieser Blogpost.
Es heißt oft, Event-basierte Systeme seien besonders leistungsfähig, weil sich Events hervorragend dazu eignen, Informationen über fachliche Ereignisse zwischen verschiedenen Systemen auszutauschen und diese so zu integrieren. In der Realität zeigt sich jedoch häufig ein ganz anderes Bild: Jedes System verwendet seine eigene Variante von Events, die Formate sind nicht kompatibel, und die erhoffte Integration über Events scheitert dadurch schnell. Was hier eindeutig fehlt, ist ein standardisiertes Format – ein allgemeingültiger Standard, der definiert, welche Daten ein Event enthalten soll, wie es strukturiert ist und wie es übermittelt wird.
Glücklicherweise hat sich die Cloud Native Computing Foundation [1] (CNCF) dieser Herausforderung angenommen und genau einen solchen Standard geschaffen: CloudEvents [2]. Für jede Entwicklerin und jeden Entwickler, die mit Event-basierten Systemen arbeiten, ist dieses Thema von großer Relevanz. Daher möchte ich Ihnen in diesem Blogpost einen genaueren Einblick geben.
Vielleicht fragen Sie sich zunächst, was ich überhaupt unter dem Begriff "Event" verstehe. Eine präzise Antwort würde an dieser Stelle den Rahmen sprengen. Daher empfehle ich Ihnen meinen Blogpost zum Thema Event Sourcing [3], der vor einigen Wochen erschienen ist. Es lohnt sich, sich zunächst damit vertraut zu machen und erst anschließend hier weiterzulesen.
Wenn Sie bereits wissen, was mit Events gemeint ist, dann kennen Sie vermutlich auch das Problem: Jedes Event-getriebene System definiert sein eigenes Format für Events, was den Austausch und die Integration zwischen verschiedenen Systemen erheblich erschwert. Der theoretische Vorteil einer gemeinsamen Kommunikationsform durch Events bleibt in der Praxis oft ungenutzt, da die Formate schlicht nicht zueinander passen. Solange es keinen verbindlichen Standard gibt, bleibt der Nutzen solcher Events für die Systemintegration begrenzt.
Genau hier setzt das Konzept von CloudEvents an. Die dahinterstehende Idee ist einfach: Es geht darum, ein standardisiertes Format für Events zu schaffen, um die Interoperabilität zwischen verschiedenen Systemen zu ermöglichen. Entwickelt wurde dieser Standard, wie gesagt, von der Cloud Native Computing Foundation, einer gemeinnützigen Organisation, die von nahezu allen großen Cloud-Anbietern wie Microsoft, Amazon und Google unterstützt wird.
Das Ziel von CloudEvents ist es, einheitliche Metadaten für Events zu definieren, damit diese zumindest in ihrer äußeren Struktur kompatibel zueinander gestaltet werden können. Zusätzlich sollen plattform- und transportschichtunabhängige Strukturen ermöglicht werden – zum Beispiel soll JSON über HTTPS genauso einsetzbar sein wie XML über MQTT. Der Standard definiert dabei zentrale Begriffe wie "ID", "Source", "Type" und weitere essenzielle Felder.
Warum sollte man auf diesen Standard setzen? Der naheliegende Vorteil liegt in der Reduktion des Aufwands für Konvertierungen und Parsings sowie in einer deutlich verbesserten Interoperabilität zwischen Systemen. Zudem unterstützt CloudEvents verschiedene Protokolle und lässt sich dadurch flexibel transportieren – unabhängig vom konkreten Übertragungsweg. Das ist nicht nur für Anwendungen relevant, sondern auch für Router und Broker, da sich Events durch die standardisierten Metadaten wesentlich besser analysieren, filtern und verteilen lassen. Außerdem verbessert sich durch die strukturierte Beschreibung der Events die Nachvollziehbarkeit, etwa hinsichtlich Ursprung und Zeitpunkt des Ereignisses. Auf dieser Basis lassen sich generische Werkzeuge für Events realisieren – ein Aspekt, der insbesondere für Microservices, Serverless-Funktionen und vergleichbare Architekturen von Bedeutung ist. Und wenn man diesen Gedanken weiterführt, dann wäre CloudEvents sogar als Persistenzformat für Event Sourcing gut geeignet.
Natürlich stellt sich die Frage, welche Herausforderungen oder Einwände gegen die Nutzung von CloudEvents sprechen könnten. Ein zentrales Problem besteht darin, dass bisher noch nicht viele Systeme diesen Standard unterstützen. Das heißt, es existieren derzeit nur wenige Anwendungen, die direkt kompatibel sind. Bestehende, proprietäre Event-Formate müssen daher weiterhin unterstützt werden – zumindest ergänzend. Das verursacht zusätzlichen Aufwand, den man eigentlich vermeiden möchte. Dies betrifft nicht nur kleinere Systeme, sondern auch Dienste wie die Amazon EventBridge von AWS oder das Event Grid von Microsoft Azure.
Ein weiterer Punkt ist, dass CloudEvents lediglich die Metadaten vereinheitlicht. Die Nutzdaten – also die Payload – bleiben weiterhin spezifisch für die jeweilige Anwendung. Das ist systemimmanent, denn der fachliche Inhalt eines Events lässt sich nicht generisch definieren. Hinzu kommt, dass CloudEvents durch ihre strukturierte Form möglicherweise mehr Overhead verursachen als einfachere proprietäre Formate, insbesondere wenn nicht alle vorgesehenen Felder genutzt werden.
Trotzdem halte ich CloudEvents für einen großen Schritt in die richtige Richtung. Ohne klare Regeln ist es unnötig aufwendig, Event-basierte Systeme miteinander zu koppeln. Ein gemeinsames Vokabular erscheint hier ausgesprochen sinnvoll. Positiv hervorzuheben ist auch, dass sich CloudEvents gut mit anderen Standards kombinieren lässt – etwa mit AsyncAPI [5] oder OpenTelemetry [6]. Alles in allem ist der Standard darauf ausgelegt, den Einstieg möglichst einfach zu gestalten und die Integration in bestehende Systeme zu erleichtern.
Daraus ergibt sich die Frage, wie man CloudEvents sinnvoll umsetzt. Zunächst sollte man klären, ob der Einsatz für die eigene Anwendung überhaupt sinnvoll ist. Meiner persönlichen Einschätzung nach lautet die Antwort eindeutig: Sobald Sie mit Events arbeiten und sobald Sie auch nur ansatzweise darüber nachdenken, Ihre Software mit anderen Systemen zu koppeln oder zu integrieren, sollten Sie CloudEvents in Betracht ziehen. Natürlich können Sie auch ein eigenes Format definieren – gewinnen werden Sie dadurch allerdings wenig. Der einzige "Nachteil" besteht darin, dass man sich einmal mit dem CloudEvents-Standard vertraut machen muss. Nach meiner Erfahrung ist das sehr gut machbar: Der Standard ist verständlich und überschaubar.
Wenn Sie sich dafür entscheiden, CloudEvents zu nutzen, dann sollten Sie es auch korrekt tun. Das bedeutet vor allem, sich mit der Bedeutung und dem Format der einzelnen Felder auseinanderzusetzen. Es wäre wenig hilfreich, das Format formal zu unterstützen, dabei aber inkorrekte Werte zu verwenden – insbesondere, wenn sich solche Fehler erst Monate später im Integrationsfall zeigen. Felder wie "source", "subject" oder "type" erfordern dabei besondere Aufmerksamkeit. Es ist nicht kompliziert, erfordert jedoch eine sorgfältige Lektüre der Spezifikation [7].
Falls Sie bereits ein Event-basiertes System im Einsatz haben, das den CloudEvents-Standard bislang nicht berücksichtigt, ist das kein Grund, das Thema abzulehnen. Sie können mit vergleichsweise geringem Aufwand Wrapper, Konverter oder Middleware einsetzen, um zwischen bestehenden Formaten und dem Standard zu übersetzen. Das lohnt sich vor allem langfristig, da Sie auf diese Weise einen einheitlichen Austauschstandard etablieren und den Bedarf an individuellen Adaptern reduzieren. Besonders relevant wird das, wenn Sie CloudEvents auch als Basis für Event Sourcing nutzen – dann sind die Events bereits im Kern standardisiert.
Bleibt abschließend die Frage, ob sich CloudEvents langfristig als Standard etablieren wird. Ich bin in dieser Hinsicht optimistisch. Die Unterstützung durch Cloud-Anbieter wächst, ebenso wie die Verbreitung in Open- und Closed-Source-Anwendungen. Darüber hinaus dient CloudEvents bereits als Grundlage für weitere Standards, etwa CDEvents [8], die sich speziell auf Continuous-Delivery-Prozesse konzentrieren. Diese Entwicklung verdeutlicht, dass CloudEvents als tragfähige und zukunftsfähige Basis angesehen werden.
Ich kann Ihnen daher nur empfehlen, sich intensiv mit CloudEvents zu beschäftigen. Der Standard ist hilfreich, durchdacht und vor allem praxisnah. Je stärker Sie mit Event-basierten Architekturen arbeiten – sei es in der Entwicklung, in der Infrastruktur oder in anderen Bereichen –, desto relevanter wird dieses Konzept für Sie.
Wenn Sie bereits Erfahrungen mit CloudEvents gesammelt haben oder planen, sich damit auseinanderzusetzen, freue ich mich über Ihre Rückmeldung. Und falls Sie generell mehr über Event-basierte Systeme lernen möchten: Neben der bereits erwähnten Einführung in Event Sourcing finden Sie weiterführende Informationen auch in dem Blogpost "CQRS als Grundlage für moderne, flexible und skalierbare Anwendungsarchitektur [9]".
URL dieses Artikels:
https://www.heise.de/-10325241
Links in diesem Artikel:
[1] https://www.cncf.io/
[2] https://cloudevents.io/
[3] https://www.heise.de/blog/Event-Sourcing-Die-bessere-Art-zu-entwickeln-10258295.html
[4] https://www.heise.de/Datenschutzerklaerung-der-Heise-Medien-GmbH-Co-KG-4860.html
[5] https://www.asyncapi.com/
[6] https://opentelemetry.io/
[7] https://github.com/cloudevents/spec
[8] https://cdevents.dev/
[9] https://www.heise.de/blog/CQRS-als-Grundlage-fuer-moderne-flexible-und-skalierbare-Anwendungsarchitektur-10275526.html
[10] https://www.mastering-gitops.de/?wt_mc=intern.academy.dpunkt.konf_dpunkt_clc_gitops.empfehlung-ho.link.link
[11] https://www.mastering-gitops.de/veranstaltung-83006-se-0-gitops-auf-allen-ebenen-mit-crossplane-&-argocd.html?wt_mc=intern.academy.dpunkt.konf_dpunkt_clc_gitops.empfehlung-ho.link.link
[12] https://www.mastering-gitops.de/veranstaltung-83394-se-0-gitops-evolution-moderne-infrastruktur-pipelines-mit-pulumi-und-argo-cd.html?wt_mc=intern.academy.dpunkt.konf_dpunkt_clc_gitops.empfehlung-ho.link.link
[13] https://www.mastering-gitops.de/veranstaltung-83008-se-0-praxisbericht-zwei-jahre-gitops-mit-fluxcd-in-produktion.html?wt_mc=intern.academy.dpunkt.konf_dpunkt_clc_gitops.empfehlung-ho.link.link
[14] https://www.mastering-gitops.de/veranstaltung-83446-se-0-effiziente-multi-tenant-architekturen-gitops-mit-argo-cd-in-der-praxis.html?wt_mc=intern.academy.dpunkt.konf_dpunkt_clc_gitops.empfehlung-ho.link.link
[15] https://www.mastering-gitops.de/veranstaltung-83445-se-0-gitops-pattern-fuer-verteilte-deployment-pipelines-mit-kargo.html?wt_mc=intern.academy.dpunkt.konf_dpunkt_clc_gitops.empfehlung-ho.link.link
[16] https://www.mastering-gitops.de/tickets.php?wt_mc=intern.academy.dpunkt.konf_dpunkt_clc_gitops.empfehlung-ho.link.link
[17] mailto:mai@heise.de
Copyright © 2025 Heise Medien
(Bild: Pincasso/Shutterstock.com)
Die Zeitkonvertierungsmethoden haben in .NET 9.0 neue Überladungen für mehr Genauigkeit erhalten.
Die Datenstruktur System.TimeSpan gibt es schon seit der ersten Version des .NET Frameworks aus dem Jahr 2002. In .NET 9.0 adressiert Microsoft jetzt eine kleine Herausforderung, die es in all den Jahren gab: Die Konvertierungsmethoden FromMicroseconds(), FromSeconds(), FromMinutes(), FromHours() und FromDays() erwarten als Parameter einen Double-Wert, der als Fließkommazahl aber ungenau ist.
Microsoft führt daher in .NET 9.0 zusätzlich neue Überladungen dieser Methoden ein, die Ganzzahlen – int beziehungsweise long – als Parameter erwarten:
public static TimeSpan FromDays(int days);public static TimeSpan FromDays(int days, int hours = 0, long minutes = 0, long seconds = 0, long milliseconds = 0, long microseconds = 0);public static TimeSpan FromHours(int hours);public static TimeSpan FromHours(int hours, long minutes = 0, long seconds = 0, long milliseconds = 0, long microseconds = 0);public static TimeSpan FromMinutes(long minutes);public static TimeSpan FromMinutes(long minutes, long seconds = 0, long milliseconds = 0, long microseconds = 0);public static TimeSpan FromSeconds(long seconds);public static TimeSpan FromSeconds(long seconds, long milliseconds = 0, long microseconds = 0);public static TimeSpan FromMilliseconds(long milliseconds, long microseconds = 0);public static TimeSpan FromMicroseconds(long microseconds);Das folgende Beispiel beweist die größere Genauigkeit der neuen Überladungen am Beispiel FromSeconds():
public class FCL9_TimeSpanFrom
{
public void Run()
{
CUI.Demo(nameof(FCL9_TimeSpanFrom));
// bisher
TimeSpan timeSpan1a = TimeSpan.FromSeconds(value: 123.456);
Console.WriteLine($"TimeSpan +123.456sec alt = {timeSpan1a}");
// 00:02:03.4560000
// bisher
TimeSpan timeSpan2a = TimeSpan.FromSeconds(value: 101.832);
Console.WriteLine($"TimeSpan +101.832sec alt = {timeSpan2a}");
// 00:01:41.8319999
Console.WriteLine();
// neu
TimeSpan timeSpan1n = TimeSpan.FromSeconds(seconds: 123,
milliseconds: 456);
Console.WriteLine($"TimeSpan +123.456sec neu = {timeSpan1n}");
// 00:02:03.4560000
// neu
TimeSpan timeSpan2n = TimeSpan.FromSeconds(seconds: 101,
milliseconds: 832);
Console.WriteLine($"TimeSpan +101.832sec neu = {timeSpan2n}");
// 00:01:41.8320000
}
}
(Bild: Screenshot (Holger Schwichtenberg))
URL dieses Artikels:
https://www.heise.de/-10324526
Links in diesem Artikel:
[1] mailto:rme@ix.de
Copyright © 2025 Heise Medien
(Bild: Natalia Hanin / Shutterstock.com)
Gerade ist das OpenJDK 24 mit 24 Java Enhancement Proposals erschienen. Dabei ist einiges unter der Haube passiert, und es gibt neue Sicherheitsfunktionen.
In einem früheren Post [1] haben wir uns bereits die zehn, insbesondere für Entwicklerinnen und Entwickler relevanten Neuerungen angeschaut. In diesem zweiten Teil werfen wir einen Blick auf die restlichen JEPs.
Viele Neuerungen beziehen sich auf Themen unter der Haube (z. B. Garbage Collector), auf Optimierungen beim Start bzw. im laufenden Betrieb von Java-Anwendungen und Maßnahmen, die die Robustheit der Java-Plattform steigern. So erhält im JEP 404 der Shenandoah Garbage Collector ähnlich wie der Z Garbage Collector (ZGC) einen "Generational Mode". Dabei wird zwischen neuen und alten Objekten unterschieden. Die junge Generation enthält eher kurzlebige Objekte und wird häufiger bereinigt. Die alte Generation muss dagegen nur selten aufgeräumt werden. Damit verbessert sich der Durchsatz sowie die Widerstandsfähigkeit gegen Lastspitzen, und die Speichernutzung wird optimiert. Beim Z Garbage Collector wird mit dem JEP 490 der nicht generationale Modus nun entfernt, da der generationale Modus inzwischen leistungsfähiger und für die meisten Anwendungen besser geeignet ist. Die Maßnahme soll den Wartungsaufwand reduzieren und die Weiterentwicklung des generationalen Modus beschleunigen. Das reflektiert den Fokus auf modernere Ansätze bei der Speicherbereinigung, die sowohl Effizienz als auch Wartbarkeit erhöhen sollen.
Der JEP 475 (Late Barrier Expansion for G1) führt eine Optimierung für den Standard Garbage Collector G1 ein, indem Speicherbarrieren später im Kompilierungsprozess generiert werden. Diese Änderung verbessert die Qualität der maschinennahen Instruktionen, reduziert die Komplexität in der Implementierung und erleichtert die Pflege. Die Motivation liegt in der Identifizierung von Schwächen bei der bisherigen Platzierung von Barrieren, insbesondere im Hinblick auf ihren Einfluss auf die Leistung und den Speicherverbrauch. Durch diese spätere Platzierung können unnötige Barrieren eliminiert werden, was zu einer effizienteren Programmausführung beiträgt. Diese Optimierung stellt einen weiteren Schritt dar, die Performance und Wartbarkeit des G1-Garbage-Collectors zu verbessern und langfristig die Anpassungsfähigkeit an moderne Hardwarearchitekturen sicherzustellen.
Der JEP 450 führt kompakte Objekt-Header in Java ein, um Speicherplatz effizienter zu nutzen und den Speicherverbrauch von Java-Objekten zu reduzieren. Der Header, der bisher 128 Bit auf 64-Bit-Plattformen einnahm, wird auf 64 Bit verkleinert. Das geschieht durch komprimierte Klassenreferenzen und eine optimierte Verwaltung von Synchronisierungsinformationen. Der Ansatz zielt darauf ab, die Speicherbelastung bei datenintensiven Anwendungen mit vielen kleinen Objekten zu minimieren, ohne die Leistung der JVM zu beeinträchtigen. Da jedoch tiefgreifende Änderungen an grundlegenden Datenstrukturen vorgenommen werden, bleibt das Feature zunächst experimentell, um mögliche Probleme zu identifizieren und Feedback zu sammeln. Dies könnte langfristig die Grundlage für eine noch effizientere Speicherverwaltung in zukünftigen Java-Versionen schaffen.
Der JEP 483 führt das Konzept des Ahead-of-Time (AOT) Class Loading & Linking ein, das die Startzeit und die Effizienz von Java-Anwendungen verbessern soll. Die Idee besteht darin, häufig genutzte Klassen bereits zur Build-Zeit vorzubereiten, statt sie erst zur Laufzeit zu laden und zu verlinken. Das geschieht durch die Integration einer AOT-Caching-Lösung, in der Metadaten wie Konstanten, Methoden-Handles oder Lambda-Ausdrücke vorgeladen und gespeichert werden. Ziel ist es, die Kosten und Latenzen des dynamischen Ladens zur Laufzeit zu minimieren, was insbesondere bei wiederkehrenden Anwendungsfällen in Cloud-nativen oder ressourcenbeschränkten Umgebungen Vorteile bringt. Die Motivation hinter dieser Änderung liegt in der zunehmenden Bedeutung von schnell startenden Anwendungen, die oft auf Containerplattformen wie Kubernetes ausgeführt werden. In solchen Umgebungen ist die Optimierung von Startzeiten und Speicherverbrauch entscheidend. Durch die Verwendung eines Cache-Mechanismus wird die Effizienz deutlich gesteigert, ohne die Flexibilität des Java-Ökosystems zu beeinträchtigen.
JEP 491 verbessert die Skalierbarkeit von Java-Anwendungen, die synchronized-Methoden und -Blöcke verwenden. Derzeit führt das Synchronisieren von virtuellen Threads dazu, dass auch die darunter liegenden Plattform-Threads blockiert werden. Viele parallel existierende virtuelle Threads können ihre Vorteile nicht mehr ausspielen, und das kann die Performance und Skalierbarkeit erheblich beeinträchtigen. Bei der Einführung der Virtual Threads in Java 21 ist man diesen Kompromiss bewusst eingegangen, um sie möglichst schnell auf die Straße bringen zu können. Mit dem JEP 491 wurde die Architektur der virtuellen Threads aber nun nochmals angepasst. Threads, die auf Monitore warten, können den zugrunde liegenden Plattform-Thread nun wieder freigeben, ohne die Funktionalität von synchronized zu beeinträchtigen. Das bedeutet, dass virtuelle Threads, die in synchronized-Blöcke eintreten oder darauf warten, nicht mehr die zugehörigen Plattform-Threads blockieren, wodurch die Anzahl der verfügbaren virtuellen Threads für die Bearbeitung von Aufgaben maximiert wird. Diese Änderungen wird die Effizienz bei der Nutzung von virtuellen Threads erheblich steigern. Es werden jetzt fast alle Fälle von Thread-Pinning vermieden, die bisher die Skalierbarkeit begrenzt haben.
JEP 478 führt eine API für Key Derivation Functions (KDFs) als Preview ein, um sichere Ableitungen von kryptografischen Schlüsseln zu unterstützen. Diese werden aus einem geheimen Schlüssel und zusätzlichen Informationen generiert, basierend auf Standards wie RFC 5869 (HMAC-based Extract-and-Expand Key Derivation Function, HKDF). Ziel ist es, eine standardisierte, gut integrierte Lösung für Java-Entwickler bereitzustellen, die interoperabel und vielseitig einsetzbar ist. Bestehende Methoden für Verschlüsselung, Authentifizierung und digitale Signaturen beruhen oft auf benutzerdefinierten Implementierungen, die potenziell unsicher oder weniger effizient sind. Die API bietet ein standardisiertes Framework, das die Sicherheit und Benutzerfreundlichkeit erhöht, während es gleichzeitig mit den aktuellen Sicherheitsbibliotheken von Java kompatibel bleibt.
Die JEPs 496 (Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism – ML-KEM) und 497 (Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm – ML-DSA) führen Implementierungen von Algorithmen für Schlüsselaustauschverfahren und digitale Signaturen ein. ML-KEM ist ein von NIST (National Institute of Standards and Technology) in FIPS 203 (Federal Information Processing Standard) standardisierter Algorithmus, der sichere Schlüsselaustauschverfahren gegen zukünftige Angriffe durch Quantencomputer ermöglicht. Dies ist besonders relevant, da Quantencomputer herkömmliche kryptografische Verfahren wie RSA und Diffie-Hellman in Zukunft brechen werden. Java 24 unterstützt ML-KEM mit den Parametern ML-KEM-512, ML-KEM-768 und ML-KEM-1024, um die Sicherheit von Anwendungen langfristig zu gewährleisten. ML-DSA ist ein von NIST in FIPS 204 standardisierter Algorithmus zur digitalen Signatur, der ebenfalls gegen zukünftige Angriffe durch Quantencomputer abgesichert ist. Digitale Signaturen werden zur Authentifizierung und zur Erkennung von Datenmanipulationen genutzt. Java 24 unterstützt ML-DSA mit den Parametern ML-DSA-44, ML-DSA-65 und ML-DSA-87, um eine langfristig sichere Signaturprüfung zu ermöglichen.
Der JEP 472 (Prepare to Restrict the Use of JNI) zielt darauf ab, die Nutzung der Java Native Interface (JNI) zu beschränken, um die Integrität und Sicherheit der Java-Plattform zu erhöhen. JNI erlaubt den Zugriff auf private Felder und Methoden sowie den direkten Speicherzugriff, was grundlegende Prinzipien wie Kapselung und Speichersicherheit untergräbt. Ziel ist es, die Verwendung von JNI standardmäßig einzuschränken, es jedoch für Anwendungen explizit aktivieren zu können, die es benötigen. Dies folgt dem langfristigen Ansatz, Java von unsicheren APIs zu befreien und alternative Mechanismen wie die Foreign Function & Memory API zu fördern. Die Motivation liegt in der Verbesserung der Robustheit, Wartbarkeit und Sicherheit der Plattform, um Risiken wie Speicherkorruption und unvorhergesehenes Verhalten zu minimieren und die Modernisierung von Java-Programmen zu erleichtern.
Der JEP 479 (Remove the Windows 32-bit x86 Port) entfernt den Windows 32-Bit-x86-Port aus dem OpenJDK, da diese Architektur zunehmend veraltet ist und keine neue Hardware mit diesem Format mehr produziert wird. Windows 10, das letzte Betriebssystem mit Unterstützung für 32-Bit-Betrieb, erreicht 2025 das Ende seines Lebenszyklus, was die Relevanz dieser Plattform weiter verringert. Durch das Entfernen dieses Ports können Ressourcen bei der Weiterentwicklung von Java effizienter genutzt werden. Gleichzeitig wird die Wartung durch die Reduzierung von Komplexität vereinfacht. Diese Änderung entspricht den aktuellen Trends in der Industrie, bei der 64-Bit-Architekturen klar dominieren. Anwender können weiterhin ältere Versionen des JDK nutzen oder durch den Einsatz von Remote-APIs für 32-Bit-Funktionen migrieren. Neben Windows müssen bald auch andere 32-bit-Implementierungen dran glauben: Mit dem JEP 501 (Deprecate the 32-bit x86 Port for Removal) wird der 32-Bit-x86-Port in Java 24 als veraltet markiert und auf dessen Entfernung in einer zukünftigen Version vorbereitet. Betroffen ist insbesondere die letzte verbliebene Implementierung für Linux auf 32-Bit-x86. Die Wartung dieses Ports verursacht ebenfalls hohe Kosten und blockiert die Implementierung neuer Features wie Project Loom, das Foreign Function & Memory API oder die Vector API. Nach der Entfernung bleibt als einzige Möglichkeit zur Ausführung von Java-Programmen auf 32-Bit-x86-Prozessoren der architekturunabhängige Zero-Port.
Durch den JEP 498 (Warn upon Use of Memory-Access Methods in sun.misc.Unsafe) gibt Java 24 eine Laufzeitwarnung aus, wenn erstmals eine der unsicheren Speicherzugriffsmethoden in sun.misc.Unsafe aufgerufen wird. Diese Methoden wurden bereits in JDK 23 zur Entfernung markiert. Sie wurden durch sicherere Alternativen ersetzt, z. B. VarHandle (JEP 193, JDK 9) für Speicherzugriffe auf dem Heap und MemorySegment (JEP 454, JDK 22) für Off-Heap-Speicher. Das Ziel ist es, Entwickler frühzeitig auf die Entfernung dieser Methoden in zukünftigen JDK-Versionen vorzubereiten und sie zum Umstieg auf standardisierte APIs zu bewegen.
Mit dem JEP 493 (Linking Run-Time Images without JMODs) wird die Größe einer vom Benutzer erstellten Laufzeitumgebung (JRE) mit jlink um etwa 25 % verringert. Bei der Erzeugung der Images werden keine JMOD-Dateien inkludiert. Diese Funktion muss allerdings bei der Erstellung des JDKs aktiviert werden. Und einige JDK-Anbieter entscheiden sich möglicherweise dafür, diese Option nicht umzusetzen. Als Motivation wird darauf verwiesen, dass in Cloud-Umgebungen die installierte Größe des JDK auf dem Dateisystem wichtig ist. Gerade Container-Images, die ein installiertes JDK enthalten, werden automatisch und häufig über das Netzwerk aus Container-Registries kopiert heruntergeladen. Eine Verringerung der Größe des JDK würde die Effizienz dieser Vorgänge verbessern.
Java 24 ist ein spannendes Release mit vielen neuen Features – auch wenn für uns Entwickler auf den ersten Blick scheinbar gar nicht so viel Neues dabei ist. Vieles sind Wiedervorlagen aus früheren Preview-Versionen. Aber genau das zeigt, wie stabil und durchdacht sich Java weiterentwickelt. Und außerdem ist enorm viel unter der Haube passiert: von Performance-Optimierungen über Sicherheitsverbesserungen bis hin zu Weichenstellungen für die Zukunft, etwa in der Kryptografie und der Speicherverwaltung. Java bleibt damit eine moderne, leistungsfähige Plattform. Und im September 2025 steht mit dem OpenJDK 25 die nächste LTS-Version vor der Tür.
Zum Vertiefen der hier genannten Features empfiehlt sich als Startpunkt die OpenJDK 24-Projektseite [2]. Und es gibt natürlich auch eine ausführliche Liste aller Änderungen in den Release Notes [3].
URL dieses Artikels:
https://www.heise.de/-10322221
Links in diesem Artikel:
[1] https://www.heise.de/blog/Java-Rekord-beim-bevorstehenden-Release-des-OpenJDK-24-10051629.html
[2] https://openjdk.org/projects/jdk/24
[3] https://jdk.java.net/24/release-notes
[4] mailto:rme@ix.de
Copyright © 2025 Heise Medien
Blick unter die Motorhaube
(Bild: generated by DALL-E)
Der letzte Teil der Serie betrachtet Reasoning-Modelle und gibt einen Ausblick auf die mögliche Zukunft der LLMs.
Ein Large Language Model (LLM) ist darauf ausgelegt, menschliche Sprache zu verarbeiten und zu generieren. Nach der grundlegenden Einführung von LLMs im ersten [1], den Hardwareanforderungen und vorab trainierten Modellen im zweiten [2] sowie den Architekturtypen im dritten Teil [3] geht es zum Abschluss um Reasoning-Modelle.
Fasten your seat belts!
Wer moderne LLMs wie Deepseek R1 oder OpenAI o3 nutzt, dürfte öfter Ausgaben wie "thinking" oder "reasoning" zu Gesicht bekommen. Das Sprachmodell ist also in der Lage, strukturiert und systematisch auf eine Anfrage zu reagieren. Daher nennt man sie Reasoning-Modelle.
Argumentationen beziehungsweise Schlussfolgerungen in Large Language Models werden durch verschiedene Techniken umgesetzt, die ihre Fähigkeit verbessern, komplexe Probleme in handhabbare Schritte zu zerlegen und logische Erklärungen zu liefern. Zu den wichtigsten Methoden gehören:
Diese Methoden zielen darauf ab, die Fähigkeit von LLMs zur Argumentation zu verbessern und transparente Denkprozesse bereitzustellen, obwohl Experten den Umfang, in dem sie tatsächlich argumentieren, weiterhin diskutieren.
Chain-of-Thought-(CoT)-Prompting verbessert die Argumentationsfähigkeiten von Large Language Models, indem es sie dazu anregt, komplexe Aufgaben in eine Reihe logischer Schritte zu zerlegen. Dieser Ansatz spiegelt menschliches Denken wider und ermöglicht es Modellen, Probleme systematischer und transparenter anzugehen. Zu den wichtigsten Vorteilen gehören:
Große Sprachmodelle haben das Feld der natürlichen Sprachverarbeitung revolutioniert und ermöglichen Anwendungen wie Sprachübersetzung, Textzusammenfassung und Chatbots. Die Zukunft der LLMs ist aufregend, mit möglichen Anwendungen in Bereichen wie Bildung, Gesundheitswesen und Unterhaltung.
Eine innovative Lösung ist die Einführung von MoE-Verfahren (MoE = Mixture of Experts) in LLMs. Diese Modelle bestehen aus LLM-Komponenten, von denen jedes auf einer gewissen Domäne spezialisiert ist. Durch einen Gating-Mechanismus leitet das Modell Benutzeranfragen an die jeweils passende LLM-Komponente weiter.
Unter Agentic AI sind LLM-Agenten zu verstehen, die in der Lage sind, auf ihre Umgebung zuzugreifen, etwa um Funktionen zu starten oder die UI zu bedienen.
Multi-Agent-Systeme enthalten unterschiedliche LLM-Agenten, die ihrerseits verschiedene Rollen innehaben und miteinander agieren, um eine gemeinsame Aufgabe zu lösen, was an das bereits genannte Mixture of Experts erinnert.
Inzwischen sind auch immer mehr multimodale Modelle verfügbar, die neben Text auch Bilder, Videos, Audios oder Symbole verstehen und/oder generieren können. Vision-Modellen kann man ein Bild vorlegen, um danach Fragen zu dem Bild zu stellen. Einige Modelle erlauben die Eingabe von Prompts über gesprochene Sprache statt über Text. Modelle wie OpenAI Sora generieren realistische Videos aus Sprach-Prompts. Midjourney, DALL-E und ähnliche Modelle können Bilder aus Benutzeranforderungen (Prompts) erzeugen. Die Architektur der Modelle ähnelt der in diesem Artikel vorgestellten Architektur sehr stark. Nur dass die Modelle neben Text-Tokens auch andere Elemente wie Pixelsegmente verarbeiten und generieren können.
In Anbetracht dieser rasanten Entwicklung ist es essenziell, sich als Entwicklerin oder Nutzer intensiv mit dem Thema LLM und Generative AI zu beschäftigen. Ebenso wichtig sollte es sein, die neuen LLM-Technologien kritisch zu hinterfragen, speziell was ihre Auswirkungen auf unser Leben und unsere Gesellschaft betrifft. Das gilt insbesondere in Bezug auf ethische Grundsätze und Werte. Nur wer die Technologien kennt und versteht, kann die Chancen und Risiken einschätzen und abwägen.
Für diejenigen, die mehr über LLMs erfahren möchten, sind hier einige zusätzliche Ressourcen:
Hier ist ein Glossar einiger der in dieser Artikelserie verwendeten Begriffe:
URL dieses Artikels:
https://www.heise.de/-10296366
Links in diesem Artikel:
[1] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-1-10283768.html
[2] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-2-10296098.html
[3] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-3-10296358.html
[4] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-1-10283768.html
[5] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-2-10296098.html
[6] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-3-10296358.html
[7] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-2-10296098.html
[8] https://arxiv.org/abs/1706.03762
[9] https://huggingface.co/docs/transformers/index
[10] https://en.m.wikipedia.org/wiki/BERT_(language_model)
[11] https://huggingface.co/docs/transformers/model_doc/roberta
[12] https://arxiv.org/abs/1906.08237
[13] https://nlp.stanford.edu/
[14] mailto:rme@ix.de
Copyright © 2025 Heise Medien
(Bild: Erstellt mit KI (Midjourney) durch iX)
Der TypeScript-Compiler wird ab Version 7 nicht mehr in TypeScript, sondern in Go geschrieben sein. Was verspricht sich Microsoft davon, und warum gerade Go?
Seit Microsoft TypeScript im Oktober 2012 vorgestellt und veröffentlicht hat, ist die Sprache aus der modernen Webentwicklung nicht mehr wegzudenken. Kaum jemand, der an Web-basierten UIs arbeitet, dürfte in den vergangenen zehn Jahren an TypeScript vorbeigekommen sein. Doch die Kritik an TypeScript wächst: Immer häufiger werden Stimmen laut, die die schlechte Performance des TypeScript-Compilers bemängeln.
Immerhin war ursprünglich ein wesentlicher Aspekt der Webentwicklung, dass man nicht ständig auf einen Compiler warten musste. TypeScript hat das erfolgreich zunichtegemacht. TypeScript hat den Umgang mit JavaScript – gerade in großen Teams und in komplexen Anwendungen – zwar deutlich verbessert, aber zugleich auch die Geschwindigkeit und die Leichtigkeit der Webentwicklung gebremst.
Doch damit ist jetzt Schluss! Microsoft hat am 11. März angekündigt [2], die Performance des TypeScript-Compilers um den Faktor zehn zu beschleunigen. Und zwar, indem sie ihn komplett neu schreiben oder besser gesagt, portieren. Überraschenderweise jedoch nicht nach Rust, C# oder C++, sondern nach Go. Das wirft die Frage auf: Warum ausgerechnet Go?
Microsoft hat vor rund einer Woche unter dem Titel "A 10x Faster TypeScript" einen Blogpost [3] und auch ein Video [4] veröffentlicht, in dem Anders Hejlsberg erläutert, was Microsoft mit dem TypeScript-Compiler in der nahen bis mittleren Zukunft plant. Anders Hejlsberg ist dabei nicht irgendein Entwickler bei Microsoft, sondern federführender Sprachdesigner für TypeScript und C#. Er hat also umfassende Erfahrung in der Entwicklung von Programmiersprachen und im Compilerbau. Er kündigte an, dass der TypeScript-Compiler, wie wir ihn heute kennen, durch eine neue Implementierung in Go ersetzt werden wird. Microsoft wird dabei jedoch nicht alles von Grund auf neu schreiben, sondern die bestehende Codebasis – die derzeit in TypeScript geschrieben ist – nach Go portieren.
Ja, Sie haben richtig gelesen: TypeScript ist aktuell in TypeScript geschrieben, zukünftig wird es in Go geschrieben sein. Microsoft verspricht sich davon eine um den Faktor zehn bessere Performance, eine weitaus höhere Speichereffizienz sowie bessere Stabilität und Verlässlichkeit. Das wirft direkt Fragen auf: Was bedeutet das für mich? Warum gerade Go? Wie sieht es nach dem Umbau mit bestehenden Werkzeugen und generell dem Ökosystem aus?
Um diese Fragen zu beantworten, muss zunächst die bisherige Situation betrachtet werden. Der TypeScript-Compiler ist aktuell in TypeScript geschrieben. Das ist einerseits ein Vorteil, weil ein Compiler damit quasi direkt beweist, dass er funktioniert, indem er sich selbst übersetzt. Andererseits bedeutet es aber auch, dass der TypeScript-Compiler wie jede in TypeScript geschriebene Anwendung nach JavaScript übersetzt wird und in einer entsprechenden Laufzeitumgebung wie Node.js ausgeführt werden muss. Das ist zwar nicht interpretiert, sondern immerhin JIT-kompiliert, aber dennoch nicht so schnell, wie es mit nativem Code sein könnte.
Vor allem bei großen und komplexen Anwendungen führt das dazu, dass das Kompilieren unnötig langsam wird, weil der Compiler selbst langsam ist beziehungsweise zumindest nicht so schnell, wie er theoretisch sein könnte. Das zeigt sich deutlich an Visual Studio Code: Microsoft gibt für ein Referenzsystem eine Kompilierzeit von rund 78 Sekunden an – fast anderthalb Minuten. Visual Studio Code ist zwar ein großes Projekt, umfasst aber trotzdem "nur" 1,5 Millionen Zeilen Code, was für ein Real-World-Projekt nicht allzu umfangreich ist.
Mit dem neuen Compiler, der aktuell als Vorabversion verfügbar ist, dauert der gleiche Vorgang nur noch 7,5 Sekunden – eine Beschleunigung um den Faktor zehn. Dieser Effekt ist reproduzierbar: So benötigt das Kompilieren von Playwright statt 11 Sekunden nur noch eine Sekunde. Bei date-fns sinkt die Zeit von 6,5 auf 0,7 Sekunden. Mal ist der Effekt etwas stärker, mal etwas schwächer, doch im Schnitt entspricht er dem Faktor zehn. Und das ist erst die erste Preview – es könnte also noch weitere Optimierungspotenziale geben.
Zusätzlich sinkt der RAM-Bedarf durch den neuen Compiler um rund 50 Prozent. Das mag auf einem lokalen Entwicklungsrechner nicht besonders relevant sein, aber für CI/CD-Pipelines ist das ein massiver Gewinn. Der neue Compiler ist also nicht nur schneller, sondern auch deutlich sparsamer. Das ist beeindruckend.
Doch wie erreicht Microsoft diese Verbesserung? Die Antwort ist einfach: Nativer Code läuft deutlich schneller und sparsamer als Code, der zur Laufzeit von einem JIT-Compiler übersetzt werden muss.
Dennoch war die Ankündigung überraschend: Viele hätten erwartet, dass Microsoft TypeScript in Rust neu implementiert. Die Wahl von Go sorgt daher für Diskussionen. Microsoft begründet die Entscheidung klar: Rust bietet zwar hervorragende Performance, doch seine Speicherverwaltung mit Konzepten wie Borrowing und Ownership wäre für eine 1:1-Portierung des bestehenden Codes ein unnötiges Hindernis. Ähnlich verhält es sich mit C++: Obwohl C++ bezüglich Performance kaum zu schlagen ist, gilt die Sprache als altmodisch, fehleranfällig und schwer wartbar. C# hätte wiederum den Nachteil, dass der Compiler auf die .NET-Runtime angewiesen wäre, was unpraktisch ist, da ein Compiler idealerweise als statisch gelinkte Binary lauffähig sein sollte. Der AOT-Compiler von .NET würde zudem nicht alle gewünschten Zielplattformen unterstützen. Daher fiel auch C# aus der Auswahl.
Warum also Go? Vor allem, weil es konzeptionell TypeScript ähnelt und die Portierung daher vereinfacht. Die Speicherverwaltung erfolgt über eine Garbage Collection, sodass keine manuelle Speicherverwaltung erforderlich ist. Go kann zudem statisch gelinkte Binaries für alle gängigen Plattformen erzeugen, die keine weiteren Abhängigkeiten zur Laufzeit haben. Zudem ist Go auf Performance und Parallelisierung optimiert – essenzielle Aspekte für einen Compiler.
Microsoft hat sich also nicht deshalb für Go entschieden, weil es die "beste" oder "schnellste" Sprache wäre, sondern weil es die beste Balance zwischen Performance, Wartbarkeit und einfacher Portierung bietet. Das ist eine nachvollziehbare Entscheidung, die sachlich fundiert ist.
Was bedeutet das für Sie als TypeScript-Entwicklerin oder -Entwickler? Kurzfristig bleibt alles wie gewohnt. Als Nächstes erscheint TypeScript 5.9. Die darauffolgende 6er-Reihe wird schrittweise einige Features als "deprecated" markieren und Breaking Changes einführen – als Vorbereitung auf den neuen Compiler. Dieser wird mit TypeScript 7.0 veröffentlicht. Ein konkretes Datum gibt es noch nicht, doch bisher lagen zwischen zwei Major Releases meist zwei bis drei Jahre. Daher ist frühestens 2027 mit der Veröffentlichung zu rechnen. Das ist zwar noch lange hin, gibt aber ausreichend Zeit für eine schrittweise Migration. Vorausgesetzt, man ignoriert nicht alle kommenden Versionen bis zur 7.0 und handelt erst, wenn der Wechsel unvermeidlich ist.
Was bringt die Umstellung? In erster Linie schnellere Builds – sowohl lokal als auch in der CI/CD-Pipeline. Auch das Feedback des TypeScript-Language-Servers dürfte spürbar schneller erfolgen, was eine bessere IDE-Performance ermöglicht. Zudem wird ab TypeScript 7 kein installiertes Node.js mehr für den Compiler benötigt – ein theoretischer Vorteil, der in bestimmten Situationen jedoch tatsächlich hilfreich sein könnte.
Allerdings sind noch Fragen offen. Wie wird TypeScript künftig in andere Anwendungen und Webbrowser integriert? Bisher war das kein Problem, da der Compiler zu JavaScript kompiliert wurde. Theoretisch könnte dies über WebAssembly erfolgen, was Go unterstützt, doch die praktische Umsetzung bleibt abzuwarten. Zudem müssen Entwicklerinnen und Entwickler von Erweiterungen für den TypeScript-Compiler ihre Tools anpassen. Noch ist unklar, ob es nach Version 7 eine JavaScript-basierte Variante des Compilers geben wird oder ob Microsoft einen harten Wechsel durchführt.
Die Ankündigung war überraschend, insbesondere der Wechsel zu Go. Microsoft hat jedoch klargemacht, dass diese Entscheidung endgültig ist. Die Wahl von Go ist ein intelligenter Kompromiss zwischen Performance und Wartbarkeit.
Was halten Sie von dieser Entwicklung? Begrüßen Sie die Portierung? Und wie stehen Sie zur Wahl von Go? Schreiben Sie Ihre Meinung in die Kommentare!
URL dieses Artikels:
https://www.heise.de/-10317343
Links in diesem Artikel:
[1] https://www.heise.de/Datenschutzerklaerung-der-Heise-Medien-GmbH-Co-KG-4860.html
[2] https://www.heise.de/news/Microsoft-Native-Portierung-nach-Go-soll-TypeScript-zehnmal-schneller-machen-10312947.html
[3] https://devblogs.microsoft.com/typescript/typescript-native-port/
[4] https://www.youtube.com/watch?v=pNlq-EVld70
[5] https://enterjs.de/index.php?wt_mc=intern.academy.dpunkt.konf_dpunkt_vo_enterJS.empfehlung-ho.link.link
[6] https://enterjs.de/veranstaltung-78876-0-typescript--eine-anleitung-zum-ungluecklichsein.html?wt_mc=intern.academy.dpunkt.konf_dpunkt_vo_enterJS.empfehlung-ho.link.link
[7] https://enterjs.de/veranstaltung-72524-0-4-kritische-antipatterns-in-derreact-typescript-entwicklung.html?wt_mc=intern.academy.dpunkt.konf_dpunkt_vo_enterJS.empfehlung-ho.link.link
[8] https://enterjs.de/veranstaltung-78869-0-von-der-vision-zum-code-functional-domain-modeling-mit-typescript.html?wt_mc=intern.academy.dpunkt.konf_dpunkt_vo_enterJS.empfehlung-ho.link.link
[9] https://enterjs.de/tickets.php?wt_mc=intern.academy.dpunkt.konf_dpunkt_vo_enterJS.empfehlung-ho.link.link
[10] mailto:rme@ix.de
Copyright © 2025 Heise Medien