seb4u Java Master - Workbook + Cheat-Sheets Vom Lesen zum Umsetzen: Aufgaben, Lösungen, Review-Fragen und kompakte Referenzen. CoreSprache I/ONIO.2 ConcurrentAsync EnterpriseSpring/Jakarta JobReady

seb4u Java Master Workbook

Aufgaben, Lösungen, Review-Fragen und Portfolio-Routine passend zur finalen Modulstruktur und zum Maven-Multi-Module-Projektpaket.

So benutzt du das Workbook

AufgabeAnforderungEntwurfAPI zuerstCodeTests dazuReview

1. Aufgabe zuerst

Lies die Aufgabe, schreibe API und Tests zuerst. Schaue nicht sofort in die Lösung.

2. Lösung vergleichen

Vergleiche nicht nur Syntax, sondern Invarianten, Fehlervertrag, Package und Modulgrenze.

3. Refactoring

Baue nach jeder Lösung eine kleine Verbesserung ein: bessere Namen, Test, Edge Case oder Performance.

Neu: Die erweiterten Aufgaben und Musterlösungen sind direkt in Modul A-K integriert. Es gibt keine separate Aufgabenbank mehr, damit du im Lernfluss bleibst.

Workbook

Modul A - Orientierung, Setup und Projektstandard

Du richtest dein Lernen sauber aus: Package-Regel, Maven-Struktur, Build-Checks und Lernroutine.

Aufgaben

  1. Package-Standard prüfen: Schreibe ein kleines Skript oder eine JUnit-Prüfung, die verbietet, dass eigene Klassen außerhalb von com.seb4u.demo, com.seb4u.demo.spring oder com.seb4u.demo.jakarta liegen.
  2. Lernroutine definieren: Plane pro Woche 3 Code-Sessions: Lesen, Nachbauen, Refactoring. Dokumentiere jeweils ein Fehlerbild.

Review-Fragen

  • Welche Invariante schützt diese Lösung?
  • Welche Fehler sind fachlich, welche technisch?
  • Welche Klasse kennt zu viel?
  • Welche Tests würden einen Regression-Bug sofort zeigen?
Musterlösung anzeigen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.seb4u.demo.workbook.core;

import java.nio.file.*;
import java.util.*;
import java.util.regex.Pattern;

public final class PackageGuardSolution {
    private static final Pattern ALLOWED = Pattern.compile(
            "package\\s+com\\.seb4u\\.demo(\\.(spring|jakarta))?(\\.[a-z0-9_]+)*\\s*;"
    );

    public static List<Path> findInvalidJavaFiles(Path root) throws Exception {
        try (var stream = Files.walk(root)) {
            return stream.filter(p -> p.toString().endsWith(".java"))
                    .filter(PackageGuardSolution::hasInvalidPackage)
                    .toList();
        }
    }

    private static boolean hasInvalidPackage(Path path) {
        try {
            String text = Files.readString(path);
            if (!text.contains("package ")) return false; // allowed for tiny snippets
            return !ALLOWED.matcher(text).find();
        } catch (Exception ex) {
            throw new IllegalStateException("Cannot read " + path, ex);
        }
    }
}

Zusätzliche Aufgaben und Musterlösungen

Diese Praxisaufgaben gehören direkt zu diesem Modul. Bearbeite sie nach den ersten Aufgaben und vergleiche anschließend deine Lösung mit der Musterlösung.

PraxisReviewMusterloesung

#AufgabeAbgabePrueffragen
A.1Erstelle eine Projekt-README mit Lernziel, Build-Befehl, Modulgrenzen und Package-Regel.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
A.2Schreibe ein Shell-Skript, das verbotene Packages wie com.example und com.acme findet.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
A.3Definiere Maven-Profile fuer local, ci und release-dry-run und beschreibe die Unterschiede.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
A.4Baue eine Checkliste fuer neue Codebeispiele: Package, Testbarkeit, Fehlervertrag, Imports, Run-Anweisung.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
A.5Lege eine Ordnerkonvention fuer Handbuch, Workbook, Assessment, Projekt und Delivery fest.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
Musterloesung zu Modul A

Vergleiche deine Loesung nicht zeilenweise, sondern pruefe Architektur, Fehlerfaelle, Naming, Package-Regel und Testbarkeit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.seb4u.demo.tooling;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.regex.Pattern;

public final class PackageGuard {
    private static final Pattern FORBIDDEN = Pattern.compile("package\s+(com\.example|com\.acme|org\.demo)\b");

    public static void main(String[] args) throws IOException {
        Path root = args.length == 0 ? Path.of(".") : Path.of(args[0]);
        List<Path> violations = Files.walk(root)
                .filter(p -> p.toString().endsWith(".java"))
                .filter(PackageGuard::hasForbiddenPackage)
                .toList();

        if (!violations.isEmpty()) {
            violations.forEach(p -> System.err.println("Forbidden package: " + p));
            System.exit(2);
        }
        System.out.println("Package guard OK: " + root.toAbsolutePath());
    }

    private static boolean hasForbiddenPackage(Path file) {
        try {
            return FORBIDDEN.matcher(Files.readString(file)).find();
        } catch (IOException ex) {
            throw new IllegalStateException("Cannot read " + file, ex);
        }
    }
}
Master-Challenge: Baue zur Musterloesung mindestens zwei Tests: einen Happy Path und einen Fehlerfall. Schreibe dazu eine kurze Code-Review-Notiz.

Workbook

Modul B - Core Java, Typsystem und Objektmodell

Du modellierst fachliche Regeln mit Records, sealed Types, Validierung und klaren Ergebnistypen.

Aufgaben

  1. Result-Typ erweitern: Baue Result<T> mit map, flatMap, recover und Fehlerliste.
  2. Value Object absichern: Implementiere Money so, dass Währung, Rundung und negative Beträge kontrolliert werden.

Review-Fragen

  • Welche Invariante schützt diese Lösung?
  • Welche Fehler sind fachlich, welche technisch?
  • Welche Klasse kennt zu viel?
  • Welche Tests würden einen Regression-Bug sofort zeigen?
Musterlösung anzeigen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.seb4u.demo.workbook.core;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Currency;
import java.util.Objects;
import java.util.function.Function;

public record Money(BigDecimal amount, Currency currency) implements Comparable<Money> {
    public Money {
        Objects.requireNonNull(amount, "amount");
        Objects.requireNonNull(currency, "currency");
        amount = amount.setScale(currency.getDefaultFractionDigits(), RoundingMode.HALF_UP);
        if (amount.signum() < 0) throw new IllegalArgumentException("Money must not be negative");
    }

    public Money add(Money other) {
        requireSameCurrency(other);
        return new Money(amount.add(other.amount), currency);
    }

    public Money multiply(int factor) {
        if (factor < 0) throw new IllegalArgumentException("factor must not be negative");
        return new Money(amount.multiply(BigDecimal.valueOf(factor)), currency);
    }

    private void requireSameCurrency(Money other) {
        if (!currency.equals(other.currency)) {
            throw new IllegalArgumentException("Currency mismatch: " + currency + " vs " + other.currency);
        }
    }

    @Override public int compareTo(Money other) {
        requireSameCurrency(other);
        return amount.compareTo(other.amount);
    }

    public static Money eur(String amount) {
        return new Money(new BigDecimal(amount), Currency.getInstance("EUR"));
    }
}

Zusätzliche Aufgaben und Musterlösungen

Diese Praxisaufgaben gehören direkt zu diesem Modul. Bearbeite sie nach den ersten Aufgaben und vergleiche anschließend deine Lösung mit der Musterlösung.

PraxisReviewMusterloesung

#AufgabeAbgabePrueffragen
B.1Modelliere Money als Value Object mit Waehrung, Rundung und Validierung.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
B.2Baue Typed IDs fuer CustomerId, OrderId und ProductId ohne String-Verwechslung.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
B.3Entwirf eine sealed State Machine fuer OrderStatus mit erlaubten Uebergaengen.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
B.4Vergleiche record, class und enum fuer fachliche Modelle und dokumentiere die Entscheidung.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
B.5Refactore eine mutierbare Anemic-Domain-Klasse zu einem invariantenreichen Domain Model.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
Musterloesung zu Modul B

Vergleiche deine Loesung nicht zeilenweise, sondern pruefe Architektur, Fehlerfaelle, Naming, Package-Regel und Testbarkeit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.seb4u.demo.domain;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Currency;
import java.util.Objects;

public record Money(BigDecimal amount, Currency currency) implements Comparable<Money> {
    public Money {
        Objects.requireNonNull(amount, "amount");
        Objects.requireNonNull(currency, "currency");
        amount = amount.setScale(currency.getDefaultFractionDigits(), RoundingMode.HALF_UP);
        if (amount.signum() < 0) throw new IllegalArgumentException("Money must not be negative");
    }

    public Money add(Money other) {
        requireSameCurrency(other);
        return new Money(amount.add(other.amount), currency);
    }

    public Money multiply(int quantity) {
        if (quantity < 0) throw new IllegalArgumentException("quantity must not be negative");
        return new Money(amount.multiply(BigDecimal.valueOf(quantity)), currency);
    }

    private void requireSameCurrency(Money other) {
        if (!currency.equals(other.currency)) {
            throw new IllegalArgumentException("Currency mismatch: " + currency + " != " + other.currency);
        }
    }

    @Override public int compareTo(Money other) {
        requireSameCurrency(other);
        return amount.compareTo(other.amount);
    }
}
Master-Challenge: Baue zur Musterloesung mindestens zwei Tests: einen Happy Path und einen Fehlerfall. Schreibe dazu eine kurze Code-Review-Notiz.

Workbook

Modul C - Runtime, I/O, NIO.2 und Concurrency

Du verarbeitest Dateien robust, vermeidest Path Traversal und steuerst Nebenläufigkeit mit Backpressure.

Aufgaben

  1. Atomarer CSV-Import: Lies eine große CSV streaming-basiert, schreibe das Ergebnis atomar in ein Zielverzeichnis und verschiebe fehlerhafte Dateien in quarantine/.
  2. Backpressure Pipeline: Baue Producer/Consumer mit begrenzter Queue, sauberer Cancellation und Fehleraggregation.

Review-Fragen

  • Welche Invariante schützt diese Lösung?
  • Welche Fehler sind fachlich, welche technisch?
  • Welche Klasse kennt zu viel?
  • Welche Tests würden einen Regression-Bug sofort zeigen?
Musterlösung anzeigen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.seb4u.demo.workbook.io;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.time.Instant;
import java.util.*;

public final class AtomicCsvImportSolution {
    private final Path inbox;
    private final Path processed;
    private final Path quarantine;

    public AtomicCsvImportSolution(Path root) throws IOException {
        this.inbox = root.resolve("inbox");
        this.processed = root.resolve("processed");
        this.quarantine = root.resolve("quarantine");
        Files.createDirectories(inbox);
        Files.createDirectories(processed);
        Files.createDirectories(quarantine);
    }

    public ImportReport importFile(Path input) throws IOException {
        Path safeInput = input.normalize().toAbsolutePath();
        if (!safeInput.startsWith(inbox.toAbsolutePath())) {
            throw new SecurityException("Path traversal attempt: " + input);
        }
        Path temp = Files.createTempFile(processed, "import-", ".tmp");
        int lines = 0;
        try (BufferedReader reader = Files.newBufferedReader(safeInput, StandardCharsets.UTF_8);
             BufferedWriter writer = Files.newBufferedWriter(temp, StandardCharsets.UTF_8)) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.isBlank()) continue;
                String[] columns = line.split(",");
                if (columns.length < 3) throw new IOException("Invalid CSV line: " + line);
                writer.write(columns[0].trim() + ";" + columns[1].trim() + ";" + columns[2].trim());
                writer.newLine();
                lines++;
            }
        } catch (Exception ex) {
            Files.move(safeInput, quarantine.resolve(safeInput.getFileName()), StandardCopyOption.REPLACE_EXISTING);
            Files.deleteIfExists(temp);
            throw ex;
        }
        Path target = processed.resolve(safeInput.getFileName().toString().replace(".csv", ".normalized.csv"));
        Files.move(temp, target, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
        return new ImportReport(target, lines, Instant.now());
    }

    public record ImportReport(Path target, int importedLines, Instant finishedAt) {}
}

Zusätzliche Aufgaben und Musterlösungen

Diese Praxisaufgaben gehören direkt zu diesem Modul. Bearbeite sie nach den ersten Aufgaben und vergleiche anschließend deine Lösung mit der Musterlösung.

PraxisReviewMusterloesung

#AufgabeAbgabePrueffragen
C.1Implementiere einen sicheren Importer, der Path Traversal verhindert und atomar schreibt.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
C.2Baue einen File Watcher mit Debounce und Fehler-Quarantaene.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
C.3Verarbeite 10.000 Dateien mit Virtual Threads und begrenztem Bulkhead.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
C.4Erklaere, wann Memory-Mapped I/O sinnvoll ist und wann Streaming besser ist.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
C.5Implementiere kooperative Cancellation fuer lang laufende Dateiimporte.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
Musterloesung zu Modul C

Vergleiche deine Loesung nicht zeilenweise, sondern pruefe Architektur, Fehlerfaelle, Naming, Package-Regel und Testbarkeit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.seb4u.demo.io;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.UUID;

public final class AtomicImportService {
    private final Path inbox;
    private final Path target;
    private final Path quarantine;

    public AtomicImportService(Path inbox, Path target, Path quarantine) {
        this.inbox = inbox.toAbsolutePath().normalize();
        this.target = target.toAbsolutePath().normalize();
        this.quarantine = quarantine.toAbsolutePath().normalize();
    }

    public Path importFile(String submittedName) throws IOException {
        Path source = inbox.resolve(submittedName).normalize();
        if (!source.startsWith(inbox)) throw new SecurityException("Path traversal blocked");
        if (!Files.isRegularFile(source)) throw new IOException("Not a file: " + source);

        Path temp = target.resolve("." + UUID.randomUUID() + ".tmp");
        Path finalFile = target.resolve(source.getFileName().toString()).normalize();
        if (!finalFile.startsWith(target)) throw new SecurityException("Target traversal blocked");

        try {
            Files.createDirectories(target);
            Files.copy(source, temp, StandardCopyOption.REPLACE_EXISTING);
            Files.move(temp, finalFile, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
            return finalFile;
        } catch (Exception ex) {
            Files.createDirectories(quarantine);
            Files.move(source, quarantine.resolve(source.getFileName()), StandardCopyOption.REPLACE_EXISTING);
            throw ex;
        } finally {
            Files.deleteIfExists(temp);
        }
    }
}
Master-Challenge: Baue zur Musterloesung mindestens zwei Tests: einen Happy Path und einen Fehlerfall. Schreibe dazu eine kurze Code-Review-Notiz.

Workbook

Modul D - Professional Backend und Architektur

Du trennst Domain, Use Cases und Adapter sauber und prüfst Architekturgrenzen.

Aufgaben

  1. Port zuerst: Definiere einen Port für Zahlungsfreigabe und implementiere einen Fake Adapter.
  2. Use-Case transaktional denken: Baue einen Use Case, der validiert, speichert und ein Outbox-Event erzeugt.

Review-Fragen

  • Welche Invariante schützt diese Lösung?
  • Welche Fehler sind fachlich, welche technisch?
  • Welche Klasse kennt zu viel?
  • Welche Tests würden einen Regression-Bug sofort zeigen?
Musterlösung anzeigen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.seb4u.demo.workbook.architecture;

import java.time.Instant;
import java.util.UUID;

public final class PlaceOrderWorkflowSolution {
    public Result<OrderId> place(PlaceOrderCommand command, OrderRepository repository, PaymentPort payment, OutboxPort outbox) {
        if (command.customerId().isBlank() || command.totalCents() <= 0) {
            return Result.error("Invalid order command");
        }
        OrderId id = new OrderId(UUID.randomUUID().toString());
        PaymentDecision decision = payment.authorize(command.customerId(), command.totalCents());
        if (!decision.approved()) return Result.error("Payment rejected: " + decision.reason());
        repository.save(new Order(id, command.customerId(), command.totalCents(), Instant.now()));
        outbox.publish("OrderPlaced", id.value());
        return Result.ok(id);
    }

    public record PlaceOrderCommand(String customerId, long totalCents) {}
    public record OrderId(String value) {}
    public record Order(OrderId id, String customerId, long totalCents, Instant placedAt) {}
    public record PaymentDecision(boolean approved, String reason) {}
    public interface OrderRepository { void save(Order order); }
    public interface PaymentPort { PaymentDecision authorize(String customerId, long totalCents); }
    public interface OutboxPort { void publish(String type, String aggregateId); }

    public sealed interface Result<T> {
        record Ok<T>(T value) implements Result<T> {}
        record Error<T>(String message) implements Result<T> {}
        static <T> Result<T> ok(T value) { return new Ok<>(value); }
        static <T> Result<T> error(String message) { return new Error<>(message); }
    }
}

Zusätzliche Aufgaben und Musterlösungen

Diese Praxisaufgaben gehören direkt zu diesem Modul. Bearbeite sie nach den ersten Aufgaben und vergleiche anschließend deine Lösung mit der Musterlösung.

PraxisReviewMusterloesung

#AufgabeAbgabePrueffragen
D.1Trenne Domain, Use Case und Adapter fuer einen Zahlungsprozess.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
D.2Erstelle ein Result-Pattern fuer erfolgreiche und fehlgeschlagene Use Cases.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
D.3Baue einen Port fuer Zeit/ID-Erzeugung, damit Tests deterministisch sind.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
D.4Dokumentiere Architekturregeln: Domain kennt keine Spring-, Jakarta- oder SQL-Klassen.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
D.5Implementiere ein Transaction Script und refactore es zu einem Use Case.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
Musterloesung zu Modul D

Vergleiche deine Loesung nicht zeilenweise, sondern pruefe Architektur, Fehlerfaelle, Naming, Package-Regel und Testbarkeit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.seb4u.demo.architecture;

import java.time.Instant;
import java.util.UUID;

public final class PlaceOrderUseCase {
    private final OrderRepository orders;
    private final PaymentPort payments;
    private final EventPublisher events;
    private final ClockPort clock;

    public PlaceOrderUseCase(OrderRepository orders, PaymentPort payments, EventPublisher events, ClockPort clock) {
        this.orders = orders;
        this.payments = payments;
        this.events = events;
        this.clock = clock;
    }

    public Result<OrderReceipt> handle(PlaceOrderCommand command) {
        var validation = command.validate();
        if (!validation.ok()) return Result.invalid(validation.message());

        Order order = Order.create(UUID.randomUUID(), command.lines(), clock.now());
        PaymentResult payment = payments.authorize(order.total());
        if (!payment.approved()) return Result.rejected("Payment rejected: " + payment.reason());

        orders.save(order);
        events.publish(new OrderPlaced(order.id(), order.total(), clock.now()));
        return Result.ok(new OrderReceipt(order.id(), order.total()));
    }

    public interface ClockPort { Instant now(); }
    public interface OrderRepository { void save(Order order); }
    public interface PaymentPort { PaymentResult authorize(Money total); }
    public interface EventPublisher { void publish(Object event); }
}
Master-Challenge: Baue zur Musterloesung mindestens zwei Tests: einen Happy Path und einen Fehlerfall. Schreibe dazu eine kurze Code-Review-Notiz.

Workbook

Modul E - CommerceFlow Master-Projekt

Du nutzt das Projektpaket als realistische Referenz für Domain, Application Layer, Adapter und Tests.

Aufgaben

  1. Domain-Regel ergänzen: Order darf nur bezahlt werden, wenn sie CREATED ist.
  2. Outbox idempotent machen: Verhindere doppelte Events bei Wiederholung desselben Kommandos.

Review-Fragen

  • Welche Invariante schützt diese Lösung?
  • Welche Fehler sind fachlich, welche technisch?
  • Welche Klasse kennt zu viel?
  • Welche Tests würden einen Regression-Bug sofort zeigen?
Musterlösung anzeigen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package com.seb4u.demo.workbook.commerceflow;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public final class IdempotentOutboxSolution {
    private final Map<String, OutboxEvent> eventsByKey = new ConcurrentHashMap<>();

    public boolean publishOnce(String idempotencyKey, String type, String aggregateId, String payload) {
        OutboxEvent event = new OutboxEvent(UUID.randomUUID().toString(), type, aggregateId, payload);
        return eventsByKey.putIfAbsent(idempotencyKey, event) == null;
    }

    public List<OutboxEvent> pending() {
        return List.copyOf(eventsByKey.values());
    }

    public record OutboxEvent(String id, String type, String aggregateId, String payload) {}
}

Zusätzliche Aufgaben und Musterlösungen

Diese Praxisaufgaben gehören direkt zu diesem Modul. Bearbeite sie nach den ersten Aufgaben und vergleiche anschließend deine Lösung mit der Musterlösung.

PraxisReviewMusterloesung

#AufgabeAbgabePrueffragen
E.1Erweitere CommerceFlow um OrderStatus: DRAFT, PLACED, PAID, SHIPPED, CANCELLED.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
E.2Baue eine Outbox-Tabelle oder Datei und erklaere, warum Events nicht direkt gesendet werden.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
E.3Implementiere Idempotenz fuer PlaceOrderCommand mit Idempotency-Key.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
E.4Schreibe eine Projection fuer Tagesumsatz und Anzahl bezahlter Bestellungen.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
E.5Erstelle einen Replay-Plan: Welche Events sind stabil, welche muessen migriert werden?Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
Musterloesung zu Modul E

Vergleiche deine Loesung nicht zeilenweise, sondern pruefe Architektur, Fehlerfaelle, Naming, Package-Regel und Testbarkeit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.seb4u.demo.commerceflow.application;

import java.time.Instant;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public final class IdempotencyService {
    private final Map<String, StoredResponse> responses = new ConcurrentHashMap<>();

    public StoredResponse executeOnce(String key, RequestFingerprint fingerprint, Operation operation) {
        return responses.compute(key, (ignored, existing) -> {
            if (existing != null && !existing.fingerprint().equals(fingerprint)) {
                throw new IllegalStateException("Idempotency key reused with different request");
            }
            if (existing != null) return existing;
            return new StoredResponse(fingerprint, operation.run(), Instant.now());
        });
    }

    public record RequestFingerprint(String method, String path, String bodyHash) {}
    public record StoredResponse(RequestFingerprint fingerprint, String body, Instant createdAt) {}
    public interface Operation { String run(); }
}
Master-Challenge: Baue zur Musterloesung mindestens zwei Tests: einen Happy Path und einen Fehlerfall. Schreibe dazu eine kurze Code-Review-Notiz.

Workbook

Modul F - Enterprise Java: Spring, Persistence, Testing, Security

Du baust produktionsnahe APIs mit Validierung, Fehlerverträgen, Tests und Security-Grundlagen.

Aufgaben

  1. Fehlervertrag: Baue eine Spring-Exception-Handler-Struktur mit Problem-Details.
  2. Repository-Grenze: Verhindere, dass JPA Entities in Domain-Use-Cases durchsickern.

Review-Fragen

  • Welche Invariante schützt diese Lösung?
  • Welche Fehler sind fachlich, welche technisch?
  • Welche Klasse kennt zu viel?
  • Welche Tests würden einen Regression-Bug sofort zeigen?
Musterlösung anzeigen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.seb4u.demo.spring.workbook;

import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public final class ApiExceptionHandlerSolution {
    @ExceptionHandler(MethodArgumentNotValidException.class)
    ProblemDetail validation(MethodArgumentNotValidException ex) {
        ProblemDetail detail = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
        detail.setTitle("Validation failed");
        detail.setDetail("Request body violates the API contract");
        detail.setProperty("fieldErrors", ex.getBindingResult().getFieldErrors().stream()
                .map(err -> err.getField() + ": " + err.getDefaultMessage())
                .toList());
        return detail;
    }

    @ExceptionHandler(IllegalArgumentException.class)
    ProblemDetail badRequest(IllegalArgumentException ex) {
        ProblemDetail detail = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
        detail.setTitle("Invalid request");
        detail.setDetail(ex.getMessage());
        return detail;
    }
}

Zusätzliche Aufgaben und Musterlösungen

Diese Praxisaufgaben gehören direkt zu diesem Modul. Bearbeite sie nach den ersten Aufgaben und vergleiche anschließend deine Lösung mit der Musterlösung.

PraxisReviewMusterloesung

#AufgabeAbgabePrueffragen
F.1Baue eine REST-Fehlerantwort mit code, message, traceId und fieldErrors.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
F.2Implementiere einen Spring Controller, der DTOs validiert und Domain-Fehler mappt.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
F.3Schreibe einen Repository-Test mit Testdatenaufbau und Rollback-Erwartung.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
F.4Vergleiche JDBC, JPA und jOOQ fuer CommerceFlow-Persistence.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
F.5Baue eine Security-Checkliste fuer Auth, Rollen, Logging und Secrets.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
Musterloesung zu Modul F

Vergleiche deine Loesung nicht zeilenweise, sondern pruefe Architektur, Fehlerfaelle, Naming, Package-Regel und Testbarkeit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.seb4u.demo.spring.api;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/orders")
public final class OrderResource {
    private final PlaceOrderService service;

    public OrderResource(PlaceOrderService service) {
        this.service = service;
    }

    @PostMapping
    ResponseEntity<?> place(@Valid @RequestBody PlaceOrderRequest request,
                            @RequestHeader("Idempotency-Key") @NotBlank String key) {
        return switch (service.place(request.toCommand(key))) {
            case PlaceOrderService.Result.Created created -> ResponseEntity.status(201).body(created.body());
            case PlaceOrderService.Result.Invalid invalid -> ResponseEntity.badRequest().body(invalid.problem());
            case PlaceOrderService.Result.Conflict conflict -> ResponseEntity.status(409).body(conflict.problem());
        };
    }

    public record PlaceOrderRequest(String customerId, java.util.List<String> productIds) {
        PlaceOrderCommand toCommand(String key) { return new PlaceOrderCommand(key, customerId, productIds); }
    }
}
Master-Challenge: Baue zur Musterloesung mindestens zwei Tests: einen Happy Path und einen Fehlerfall. Schreibe dazu eine kurze Code-Review-Notiz.

Workbook

Modul G - Job-Ready, Code Review und Interview

Du übst erklären, refactoren, begründen und typische Senior-Fallen erkennen.

Aufgaben

  1. Code Review: Finde Race Conditions in einem gemeinsam genutzten HashMap-Cache.
  2. Interview Antwort: Erkläre Unterschied zwischen checked Exception, RuntimeException und Fehlervertrag einer API.

Review-Fragen

  • Welche Invariante schützt diese Lösung?
  • Welche Fehler sind fachlich, welche technisch?
  • Welche Klasse kennt zu viel?
  • Welche Tests würden einen Regression-Bug sofort zeigen?
Musterlösung anzeigen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package com.seb4u.demo.workbook.interview;

import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;

public final class ThreadSafeMemoizerSolution<K, V> {
    private final ConcurrentHashMap<K, V> cache = new ConcurrentHashMap<>();

    public V getOrCompute(K key, Supplier<V> supplier) {
        return cache.computeIfAbsent(key, ignored -> supplier.get());
    }

    public int size() {
        return cache.size();
    }
}

Zusätzliche Aufgaben und Musterlösungen

Diese Praxisaufgaben gehören direkt zu diesem Modul. Bearbeite sie nach den ersten Aufgaben und vergleiche anschließend deine Lösung mit der Musterlösung.

PraxisReviewMusterloesung

#AufgabeAbgabePrueffragen
G.1Analysiere einen Codeblock auf Race Conditions, Ressourcenlecks und falsche Exceptions.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
G.2Bereite eine 3-Minuten-Erklaerung zu Virtual Threads vs Thread Pools vor.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
G.3Schreibe eine Senior-Antwort zu: Warum Hexagonal Architecture?Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
G.4Refactore einen God Service in Use Cases und Ports.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
G.5Erstelle ein Code-Review-Protokoll mit Befund, Risiko, Vorschlag und Test.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
Musterloesung zu Modul G

Vergleiche deine Loesung nicht zeilenweise, sondern pruefe Architektur, Fehlerfaelle, Naming, Package-Regel und Testbarkeit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.seb4u.demo.review;

import java.util.ArrayList;
import java.util.List;

public final class ReviewReport {
    private final List<Finding> findings = new ArrayList<>();

    public ReviewReport add(Severity severity, String location, String risk, String recommendation) {
        findings.add(new Finding(severity, location, risk, recommendation));
        return this;
    }

    public boolean blocksMerge() {
        return findings.stream().anyMatch(f -> f.severity == Severity.CRITICAL || f.severity == Severity.HIGH);
    }

    public String markdown() {
        StringBuilder out = new StringBuilder("# Code Review Report

");
        for (Finding f : findings) {
            out.append("- **").append(f.severity).append("** `").append(f.location).append("`: ")
               .append(f.risk).append(" -> ").append(f.recommendation).append('
');
        }
        return out.toString();
    }

    enum Severity { LOW, MEDIUM, HIGH, CRITICAL }
    record Finding(Severity severity, String location, String risk, String recommendation) {}
}
Master-Challenge: Baue zur Musterloesung mindestens zwei Tests: einen Happy Path und einen Fehlerfall. Schreibe dazu eine kurze Code-Review-Notiz.

Workbook

Modul H - Fullstack Java

Du verbindest Backend-API, Validierung, UI-Flows, Uploads und Exporte.

Aufgaben

  1. Pagination Contract: Definiere eine PageResponse<T> mit page, size, totalElements und items.
  2. Upload Flow: Prüfe Dateiname, Größe, MIME-Typ und Zielpfad, bevor gespeichert wird.

Review-Fragen

  • Welche Invariante schützt diese Lösung?
  • Welche Fehler sind fachlich, welche technisch?
  • Welche Klasse kennt zu viel?
  • Welche Tests würden einen Regression-Bug sofort zeigen?
Musterlösung anzeigen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package com.seb4u.demo.workbook.fullstack;

import java.util.List;

public record PageResponse<T>(
        int page,
        int size,
        long totalElements,
        List<T> items
) {
    public PageResponse {
        if (page < 0) throw new IllegalArgumentException("page must be >= 0");
        if (size <= 0 || size > 200) throw new IllegalArgumentException("size must be 1..200");
        if (totalElements < 0) throw new IllegalArgumentException("totalElements must be >= 0");
        items = List.copyOf(items);
    }

    public long totalPages() {
        return Math.max(1, (long) Math.ceil((double) totalElements / size));
    }
}

Zusätzliche Aufgaben und Musterlösungen

Diese Praxisaufgaben gehören direkt zu diesem Modul. Bearbeite sie nach den ersten Aufgaben und vergleiche anschließend deine Lösung mit der Musterlösung.

PraxisReviewMusterloesung

#AufgabeAbgabePrueffragen
H.1Entwerfe einen Login-/Register-Flow mit Backend-Fehlern und UI-Mapping.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
H.2Implementiere Pagination, Sorting und Filtering fuer eine Order-Tabelle.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
H.3Baue einen Upload-Flow mit MIME-Pruefung und Groessenlimit.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
H.4Dokumentiere Client-seitige und Server-seitige Validierung gemeinsam.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
H.5Erstelle eine Fehlerseite fuer 404, 409 und 500 mit Support-Code.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
Musterloesung zu Modul H

Vergleiche deine Loesung nicht zeilenweise, sondern pruefe Architektur, Fehlerfaelle, Naming, Package-Regel und Testbarkeit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package com.seb4u.demo.spring.fullstack;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;

public final class PageSpecFactory {
    private static final int MAX_SIZE = 100;

    public PageRequest from(int page, int size, String sortBy, String direction) {
        int safePage = Math.max(page, 0);
        int safeSize = Math.min(Math.max(size, 1), MAX_SIZE);
        String property = switch (sortBy == null ? "createdAt" : sortBy) {
            case "createdAt", "status", "total" -> sortBy == null ? "createdAt" : sortBy;
            default -> "createdAt";
        };
        Sort.Direction dir = "asc".equalsIgnoreCase(direction) ? Sort.Direction.ASC : Sort.Direction.DESC;
        return PageRequest.of(safePage, safeSize, Sort.by(dir, property));
    }
}
Master-Challenge: Baue zur Musterloesung mindestens zwei Tests: einen Happy Path und einen Fehlerfall. Schreibe dazu eine kurze Code-Review-Notiz.

Workbook

Modul I - Microservices, Messaging und Cloud

Du entwirfst Services mit Idempotenz, Outbox, Retry, Circuit Breaker und Observability.

Aufgaben

  1. Idempotency Store: Baue einen Store, der Request-Keys mit Response-Snapshots verbindet.
  2. Retry Policy: Unterscheide transient, permanent und poison message.

Review-Fragen

  • Welche Invariante schützt diese Lösung?
  • Welche Fehler sind fachlich, welche technisch?
  • Welche Klasse kennt zu viel?
  • Welche Tests würden einen Regression-Bug sofort zeigen?
Musterlösung anzeigen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.seb4u.demo.workbook.cloud;

import java.time.Duration;
import java.time.Instant;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

public final class IdempotencyStoreSolution {
    private final ConcurrentHashMap<String, Entry> entries = new ConcurrentHashMap<>();
    private final Duration ttl;

    public IdempotencyStoreSolution(Duration ttl) {
        this.ttl = ttl;
    }

    public Optional<String> getValidResponse(String key) {
        Entry entry = entries.get(key);
        if (entry == null) return Optional.empty();
        if (entry.createdAt().plus(ttl).isBefore(Instant.now())) {
            entries.remove(key, entry);
            return Optional.empty();
        }
        return Optional.of(entry.responseBody());
    }

    public boolean save(String key, String responseBody) {
        return entries.putIfAbsent(key, new Entry(responseBody, Instant.now())) == null;
    }

    private record Entry(String responseBody, Instant createdAt) {}
}

Zusätzliche Aufgaben und Musterlösungen

Diese Praxisaufgaben gehören direkt zu diesem Modul. Bearbeite sie nach den ersten Aufgaben und vergleiche anschließend deine Lösung mit der Musterlösung.

PraxisReviewMusterloesung

#AufgabeAbgabePrueffragen
I.1Erklaere, warum Exactly Once meist ein Systemziel und kein Broker-Schalter ist.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
I.2Implementiere Consumer-Idempotenz mit processed_message Tabelle oder In-Memory-Store.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
I.3Baue eine Saga fuer Payment -> Inventory -> Shipping mit Kompensationen.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
I.4Definiere Readiness- und Liveness-Probes fuer CommerceFlow.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
I.5Schreibe eine Entscheidungsmatrix: REST, Events, Batch oder Streaming.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
Musterloesung zu Modul I

Vergleiche deine Loesung nicht zeilenweise, sondern pruefe Architektur, Fehlerfaelle, Naming, Package-Regel und Testbarkeit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.seb4u.demo.cloud;

import java.time.Instant;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public final class IdempotentConsumer {
    private final Set<String> processedIds = ConcurrentHashMap.newKeySet();

    public ConsumptionResult consume(Message message, MessageHandler handler) {
        if (!processedIds.add(message.id())) {
            return new ConsumptionResult(message.id(), "duplicate-skipped", Instant.now());
        }
        try {
            handler.handle(message);
            return new ConsumptionResult(message.id(), "processed", Instant.now());
        } catch (RuntimeException ex) {
            processedIds.remove(message.id());
            throw ex;
        }
    }

    public record Message(String id, String type, String payload) {}
    public record ConsumptionResult(String id, String status, Instant at) {}
    public interface MessageHandler { void handle(Message message); }
}
Master-Challenge: Baue zur Musterloesung mindestens zwei Tests: einen Happy Path und einen Fehlerfall. Schreibe dazu eine kurze Code-Review-Notiz.

Workbook

Modul J - Algorithmen und Datenstrukturen

Du implementierst klassische Interview-Algorithmen sauber, generisch und testbar in Java.

Aufgaben

  1. Dijkstra: Implementiere kürzeste Wege mit PriorityQueue.
  2. Sliding Window: Finde das längste Teilarray mit Summe <= Limit.

Review-Fragen

  • Welche Invariante schützt diese Lösung?
  • Welche Fehler sind fachlich, welche technisch?
  • Welche Klasse kennt zu viel?
  • Welche Tests würden einen Regression-Bug sofort zeigen?
Musterlösung anzeigen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.seb4u.demo.workbook.algorithms;

import java.util.*;

public final class DijkstraSolution {
    public Map<String, Integer> shortestPaths(Map<String, List<Edge>> graph, String start) {
        Map<String, Integer> distance = new HashMap<>();
        PriorityQueue<Node> queue = new PriorityQueue<>(Comparator.comparingInt(Node::distance));
        distance.put(start, 0);
        queue.add(new Node(start, 0));
        while (!queue.isEmpty()) {
            Node current = queue.poll();
            if (current.distance() != distance.getOrDefault(current.name(), Integer.MAX_VALUE)) continue;
            for (Edge edge : graph.getOrDefault(current.name(), List.of())) {
                int nextDistance = current.distance() + edge.weight();
                if (nextDistance < distance.getOrDefault(edge.to(), Integer.MAX_VALUE)) {
                    distance.put(edge.to(), nextDistance);
                    queue.add(new Node(edge.to(), nextDistance));
                }
            }
        }
        return Map.copyOf(distance);
    }

    public record Edge(String to, int weight) {
        public Edge { if (weight < 0) throw new IllegalArgumentException("Dijkstra requires non-negative weights"); }
    }
    private record Node(String name, int distance) {}
}

Zusätzliche Aufgaben und Musterlösungen

Diese Praxisaufgaben gehören direkt zu diesem Modul. Bearbeite sie nach den ersten Aufgaben und vergleiche anschließend deine Lösung mit der Musterlösung.

PraxisReviewMusterloesung

#AufgabeAbgabePrueffragen
J.1Implementiere LRU Cache mit LinkedHashMap und erklaere die Komplexitaet.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
J.2Loese eine Sliding-Window-Aufgabe fuer laengste Teilfolge ohne Duplikate.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
J.3Implementiere Dijkstra mit PriorityQueue und Map.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
J.4Baue Union-Find mit Path Compression und Union by Rank.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
J.5Vergleiche DFS und BFS an einem konkreten Graphproblem.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
Musterloesung zu Modul J

Vergleiche deine Loesung nicht zeilenweise, sondern pruefe Architektur, Fehlerfaelle, Naming, Package-Regel und Testbarkeit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package com.seb4u.demo.algorithms;

import java.util.HashMap;
import java.util.Map;

public final class SlidingWindow {
    public int longestUniqueSubstring(String text) {
        Map<Character, Integer> lastSeen = new HashMap<>();
        int left = 0;
        int best = 0;
        for (int right = 0; right < text.length(); right++) {
            char c = text.charAt(right);
            Integer previous = lastSeen.put(c, right);
            if (previous != null && previous >= left) {
                left = previous + 1;
            }
            best = Math.max(best, right - left + 1);
        }
        return best;
    }
}
Master-Challenge: Baue zur Musterloesung mindestens zwei Tests: einen Happy Path und einen Fehlerfall. Schreibe dazu eine kurze Code-Review-Notiz.

Workbook

Modul K - Abschluss, Portfolio und Wiederholung

Du fasst dein Wissen in einem Portfolio zusammen und wiederholst mit Cheat-Sheets.

Aufgaben

  1. Portfolio README: Schreibe eine README mit Architekturentscheidung, Run-Anleitung, Teststrategie und bekannten Trade-offs.
  2. 30-Minuten Wiederholung: Nutze die Cheat-Sheets, um ein Thema laut zu erklären und danach ein Mini-Beispiel zu schreiben.

Review-Fragen

  • Welche Invariante schützt diese Lösung?
  • Welche Fehler sind fachlich, welche technisch?
  • Welche Klasse kennt zu viel?
  • Welche Tests würden einen Regression-Bug sofort zeigen?
Musterlösung anzeigen
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.seb4u.demo.workbook.portfolio;

public final class PortfolioReadmeTemplate {
    public static String render(String projectName) {
        return """
                # %s

                ## Ziel
                Kurze fachliche Beschreibung und Lernziel.

                ## Architektur
                - Domain ohne Framework-Abhängigkeit
                - Application Layer mit Ports
                - Adapter für File, Spring oder Jakarta

                ## Start
                ```bash
                mvn test
                mvn -pl commerceflow-adapter-file exec:java
                ```

                ## Tests
                Unit Tests für Domain, Integration Tests für Adapter, Acceptance Tests für Hauptflows.

                ## Trade-offs
                Bewusste Vereinfachungen, technische Schulden und nächste Verbesserungen.
                """.formatted(projectName);
    }
}

Zusätzliche Aufgaben und Musterlösungen

Diese Praxisaufgaben gehören direkt zu diesem Modul. Bearbeite sie nach den ersten Aufgaben und vergleiche anschließend deine Lösung mit der Musterlösung.

PraxisReviewMusterloesung

#AufgabeAbgabePrueffragen
K.1Baue eine Portfolio-Seite mit Problem, Architektur, Trade-offs, Tests und Screenshots.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
K.2Schreibe ein finales Runbook: Build, Test, Start, Smoke-Test, Troubleshooting.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
K.3Erstelle eine Lernmatrix: Was kann ich erklaeren, implementieren, testen und betreiben?Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
K.4Fuehre ein Mock-Interview mit 10 Fragen aus Core, Concurrency, Spring und Architektur durch.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
K.5Plane eine 30-Tage-Wiederholung mit Cheat-Sheets, Assessment und Projektaufgaben.Code + kurze BegruendungIst es testbar? Sind Fehlerfaelle klar? Passt das Package?
Musterloesung zu Modul K

Vergleiche deine Loesung nicht zeilenweise, sondern pruefe Architektur, Fehlerfaelle, Naming, Package-Regel und Testbarkeit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.seb4u.demo.portfolio;

import java.util.List;

public record PortfolioEvidence(
        String title,
        String problem,
        String architectureDecision,
        List<String> tests,
        List<String> productionConcerns,
        String demoCommand) {

    public String asMarkdown() {
        return """
                # %s

                ## Problem
                %s

                ## Architekturentscheidung
                %s

                ## Tests
                %s

                ## Production Concerns
                %s

                ## Demo
                ```bash
                %s
                ```
                """.formatted(
                title,
                problem,
                architectureDecision,
                String.join("
", tests.stream().map(t -> "- " + t).toList()),
                String.join("
", productionConcerns.stream().map(c -> "- " + c).toList()),
                demoCommand);
    }
}
Master-Challenge: Baue zur Musterloesung mindestens zwei Tests: einen Happy Path und einen Fehlerfall. Schreibe dazu eine kurze Code-Review-Notiz.