Thema: java
-
Einen Unit-Test in JUnit 5 und xUnit.net schreiben: Annotationen, Lifecycle und parametrisierte Fälle im Vergleich
JUnit Jupiter markiert Tests mit @Test, führt standardmässig @BeforeEach und @AfterEach um jeden Test auf einer frischen Instanz aus und steuert datengetriebene Fälle mit @ParameterizedTest plus einer Source-Annotation; xUnit.net verwendet [Fact], den Konstruktor und IDisposable für das Setup je Test auf einer frischen Instanz, [Theory] mit [InlineData] für Fälle sowie Fixtures für geteilten, teuren Kontext. Tests in beiden mit derselben Form zu schreiben, hält die Konventionen eines mehrsprachigen Teams im Gleichlauf.
-
Eine JVM in einem Container dimensionieren: Heap-Prozentsatz, Non-Heap-Speicher und CPU-Anzahl
Die JVM liest standardmässig cgroup-Grenzen (UseContainerSupport) und bemisst den Heap als Prozentsatz des Container-Speichers, nicht des Host-Speichers; der Heap ist nur ein Teil des Speicherbedarfs, daher MaxRAMPercentage so setzen, dass Platz für Metaspace, Thread-Stacks, Direct Buffers und Code-Cache bleibt, die von der JVM gesehene CPU-Anzahl prüfen und mit -Xlog:os+container sowie Native Memory Tracking verifizieren, bevor einer Grenze vertraut wird.
-
Maven gegen Gradle: was Einsteiger brauchen, um das JVM-Projekt einer anderen Person zu bauen
Maven beschreibt ein Projekt deklarativ in pom.xml und durchläuft feste Lebenszyklusphasen (validate, compile, test, package, verify, install, deploy), an die Plugin-Goals gebunden sind; Gradle führt einen Graphen von Tasks aus, die durch build.gradle(.kts)-Skripte und Plugins konfiguriert werden. Beide lösen transitive Abhängigkeiten auf, aber mit unterschiedlichen Konfliktregeln (Maven: nächstgelegene Definition; Gradle: höchste Version), und beide liefern ein Wrapper-Skript, das die Version des Build-Tools festlegt.
-
Java Records, Sealed Types und Pattern Matching für switch
Records (JDK 16) sind transparente, unveränderliche Datenträger mit generiertem kanonischem Konstruktor, Zugriffsmethoden, equals, hashCode und toString; Sealed Types (JDK 17) schränken ein, welche Klassen sie erweitern oder implementieren dürfen, sodass ein Pattern-Switch (JDK 21) über die Hierarchie auf Vollständigkeit geprüft werden kann. Zusammen ergeben sie für Java einen leichtgewichtigen Summentyp.
-
Garbage Collection in der JVM: die Collectors, die Standardwerte und die wenigen Flags, die sich zu setzen lohnen
HotSpot liefert Serial, Parallel, G1 und ZGC; auf Maschinen, die es als server-class einstuft (zwei oder mehr Prozessoren und mindestens 1792 MB), wählt es G1, sonst Serial, mit einem maximalen Heap von standardmässig einem Viertel des Speichers. Für die meisten Dienste lohnt es sich, den maximalen Heap, das GC-Logging und erst nach dem Lesen der Logs einen Collector oder ein Pausenzeit-Ziel zu setzen.
-
Deserialisierung nicht vertrauenswürdiger Daten: pickle und Java-Serialisierung
Native Objektserialisierungsformate weisen den Empfänger an, beliebige Objekte zu konstruieren, und das Konstruieren von Objekten führt Code aus; die Python-Dokumentation zu pickle sagt unumwunden, dass das Modul nicht sicher ist. Diese Formate niemals aus nicht vertrauenswürdiger Eingabe deserialisieren; wo eine Altschnittstelle es erzwingt, die Klassen einschränken, die der Datenstrom benennen darf, und die Nutzlast signieren.
-
Was änderte sich bei Durchsatz, Speicher und Pinning-Vorfällen, nachdem ein JVM-Dienst auf virtuelle Threads umgestellt wurde, und was musste neu geschrieben werden?
Offene Frage: JEP 444 hält fest, dass Pinning eine Anwendung nicht fehlerhaft macht, aber ihre Skalierbarkeit behindern kann, und JEP 491, ausgeliefert in JDK 24, entfernt das Pinning für synchronized-Blöcke; was bewirkte die Umstellung der Anfragebehandlung auf virtuelle Threads bei Diensten, die diesen Schritt gegangen sind, für Durchsatz und Speicher, welche Pinning- oder Pool-Erschöpfungs-Vorfälle traten auf, und welcher Code und welche Bibliotheken mussten geändert werden?
-
Virtuelle Threads in Java im Überblick: was sich ändert und was nicht
JEP 444 (JDK 21) führt virtuelle Threads ein: günstige Threads, die vom JDK auf einen kleinen Pool von Carrier-Platform-Threads eingeplant werden und die bei den meisten JDK-I/O-Operationen beim Blockieren aushängen, sodass Thread-pro-Anfrage-Code ohne asynchronen Stil skaliert. Sie sind nicht schneller, dürfen nie gepoolt werden, und bis JEP 491 (JDK 24) pinnte ein Blockieren innerhalb von synchronized den Carrier.
-
Java streams versus loops: when a pipeline is clearer and when it is not
A stream is a lazy pipeline of intermediate operations closed by one terminal operation; it reads well for filter, map and collect over a collection, but the package documentation discourages side effects in the lambdas, a stream cannot be reused, checked exceptions do not fit, and a loop is clearer for early exit with state, index-based work and mutation.
Maschinenlesbar: JSON