Die Themen dieses Blocks kamen bisher nur in den ersten beiden Prüfungen nach neuer Ausbildungsordnung vor (W21 und W22), dort aber jeweils mit rund 20 Punkten in Teil 1. Jedes Unterthema wurde genau einmal gefragt – meist mit kurzen Wissensfragen („Nennen Sie …“, „Beschreiben Sie den Unterschied …“) oder einer Bewertung („Entscheiden Sie, ob Sie dem Vorschlag zustimmen“). Es ist Grundlagenwissen aus dem Ausbildungsalltag und kann jederzeit wiederkommen, z. B. als Einstieg in Aufgabe 1 oder 2 von Teil 1.
| Unterthema | Kategorie | Original | Wichtigste Fähigkeit |
|---|---|---|---|
| WZ-01 Versionsverwaltung (Git) | Sonstige | W21 T1 A1c (4 P) | Nutzen begründen, Begriffe, Commit-Graph, Team-Workflow bewerten |
| WZ-02 CI/CD & Deployment | Sonstige | W22 T1 A1c (6 P) | Pipeline beschreiben, Vorteile der Automatisierung |
| WZ-03 Softwarearchitektur | Sonstige | W22 T1 A2a (6 P) | 3 Schichten und ihr Zusammenspiel, MVC, Skizze |
| WZ-04 Compiler vs. Interpreter | Sonstige | W21 T1 A1a (6 P) | Unterschied, Beispiele, Vor-/Nachteile |
| WZ-05 Bibliotheken, Frameworks, Doku | Sonstige | W21 T1 A1b (10 P) | Vor-/Nachteile, Dokumentation einer Erweiterung |
| WZ-06 Open Source & Lizenzen | Sonstige | W22 T1 A2c (9 P) | Begriff, Lizenzpflichten (Copyleft), Vor-/Nachteile |
Vorkommen: 1/9 · Prüfung: W21 T1 A1c (4 P: Ein Entwicklungsteam aus zehn Personen schlägt vor, mit einer Versionsverwaltung zu arbeiten – zustimmen oder ablehnen und fachlich begründen)
Eine Versionsverwaltung (Version Control System, VCS) speichert jede Änderung an Dateien – meist Quellcode – als neue Version in einem Repository. Zu jeder Version werden Autor, Zeitpunkt und eine Beschreibung festgehalten. Dadurch kann ein Team gleichzeitig an denselben Dateien arbeiten, Änderungen zusammenführen und jederzeit auf einen früheren Stand zurückgehen.
git log, git blame).git revert).Gegen eine Versionsverwaltung spricht praktisch nur der Einarbeitungs- und Einrichtungsaufwand. In der Prüfung lautet die erwartete Antwort daher fast immer: zustimmen – und mit zwei konkreten Vorteilen für dieses Team begründen.
| Zentral (CVS, Subversion/SVN, Perforce) | Verteilt (Git, Mercurial) | |
|---|---|---|
| Repository | nur auf dem Server; Entwickler haben nur eine Arbeitskopie | jeder Klon ist ein vollständiges Repository mit gesamter Historie |
| Commit | direkt auf den Server – nur mit Netzverbindung | lokal, offline möglich; Austausch später per push/pull |
| Geschwindigkeit | Log, Vergleich, Commit brauchen den Server | fast alles lokal und daher schnell |
| Ausfallsicherheit | Server ist Single Point of Failure | jede Kopie kann den Server wiederherstellen |
| Branches | möglich, aber eher schwerfällig | billig und schnell – Grundlage moderner Workflows |
| Stärken | einfaches Modell, feine Rechtevergabe je Verzeichnis, Sperren (Locking) großer Binärdateien | flexibel, offline, Pull-Request-Workflows; heute Standard |
| Begriff | Bedeutung |
|---|---|
| Repository | Datenbank aller Versionen eines Projekts (bei Git der Ordner .git). Remote = entferntes Repository auf einem Server, Standardname origin. |
| Arbeitsverzeichnis, Staging-Bereich | Arbeitsverzeichnis = die Dateien, an denen man arbeitet. Mit git add werden Änderungen in den Staging-Bereich (Index) vorgemerkt; nur diese landen im nächsten Commit. |
| Commit | gespeicherter Stand (Schnappschuss) mit eindeutiger ID (Hash, z. B. 4f2a9c1), Autor, Zeitpunkt, Nachricht und Verweis auf den/die Vorgänger-Commit(s). |
| Branch | Entwicklungszweig; technisch ein beweglicher Zeiger auf den letzten Commit des Zweigs. Ein neuer Commit verschiebt den Zeiger mit. Standard-Branch heute meist main (früher master). |
| HEAD | Zeiger auf den aktuell ausgecheckten Branch bzw. Commit („wo stehe ich gerade?“). |
| Merge | Zusammenführen eines Branches in einen anderen. Fast-Forward: Der Ziel-Branch hat sich nicht weiterentwickelt – sein Zeiger wird einfach vorgeschoben, es entsteht kein neuer Commit. Merge-Commit: Beide haben neue Commits – Git erzeugt einen Commit mit zwei Vorgängern. |
| Merge-Konflikt | Beide Branches haben dieselbe Stelle einer Datei unterschiedlich geändert; Git kann nicht automatisch entscheiden, ein Mensch muss den Konflikt auflösen. |
| clone, fetch, pull, push | clone: Remote-Repository erstmals vollständig kopieren. fetch: neue Commits vom Remote holen, ohne die eigenen Branches zu verändern (nur origin/main wird aktualisiert). pull = fetch + merge (bzw. rebase) in den aktuellen Branch. push: eigene Commits zum Remote hochladen. |
| Tag | fester Name für einen bestimmten Commit, z. B. v2.1.0 für ein Release. Im Gegensatz zum Branch bewegt sich ein Tag nicht. |
| Rebase | Commits eines Branches auf einen neuen Ausgangspunkt „umsetzen“ → lineare Historie. Keine bereits veröffentlichten (gepushten) Commits rebasen. |
| Pull Request / Merge Request | Anfrage auf der Plattform (GitHub: Pull Request, GitLab: Merge Request), einen Branch in main zu übernehmen. Dort finden Code-Review, Diskussion und automatische Prüfungen (CI) statt, bevor gemergt wird. |
| Befehl | Wirkung |
|---|---|
| git clone <url> | Remote-Repository erstmals vollständig kopieren |
| git status | anzeigen, was geändert bzw. vorgemerkt ist |
| git add <datei> | Änderung für den nächsten Commit vormerken |
| git commit -m "Nachricht" | Commit aus den vorgemerkten Änderungen erstellen |
| git commit -am "Nachricht" | alle geänderten, bereits versionierten Dateien vormerken und committen |
| git log --oneline --graph | Historie als Graph anzeigen |
| git switch -c <branch> (älter: git checkout -b) | Branch anlegen und dorthin wechseln |
| git switch <branch> | Branch wechseln |
| git merge <branch> | angegebenen Branch in den aktuellen Branch mergen |
| git fetch | neue Commits vom Remote holen (eigener Branch bleibt unverändert) |
| git pull | fetch + merge in den aktuellen Branch |
| git push origin <branch> | eigene Commits zum Remote hochladen |
| git tag -a v1.0.0 -m "…" | annotierten Tag auf den aktuellen Commit setzen |
| git revert <commit> | Commit durch einen Gegen-Commit rückgängig machen |
Beispiel: Projekt „Kassenbuch“. main steht auf Commit C2. Dann werden diese Befehle ausgeführt:
git switch -c feature/csv-export git commit -m "…" # E1 git commit -m "…" # E2 git switch main git commit -m "…" # C3 (dringender Fix direkt auf main) git merge feature/csv-export # M git tag -a v2.0.0 -m "Version 2.0.0"
Weil main mit C3 einen eigenen neuen Commit hat, ist kein Fast-Forward möglich: Es entsteht der Merge-Commit M mit den Vorgängern C3 und E2. (Hätte es C3 nicht gegeben, wäre main beim Merge einfach auf E2 vorgerückt.)
Zeichenregeln für Commit-Graphen: Commits als Kreise in zeitlicher Reihenfolge, Linien zum Vorgänger, Branch-Namen und Tags als beschriftete Zeiger auf „ihren“ Commit, HEAD beim aktuell ausgecheckten Branch. (In Git zeigt jeder Commit auf seinen Vorgänger; Pfeile sind daher korrekt in Richtung Vergangenheit. Ohne Pfeile mit Zeitachse ist es ebenso eindeutig.)
Git führt Änderungen automatisch zusammen, solange sie unterschiedliche Stellen betreffen. Ändern beide Seiten dieselben Zeilen (oder löscht eine Seite eine Datei, die die andere ändert), stoppt der Merge und markiert die Stelle in der Datei:
timeout.sekunden= <<<<<<< HEAD 30 ======= 120 >>>>>>> feature/langsame-drucker
Oberhalb von ======= steht der Stand des aktuellen Branches (HEAD), darunter der des einzumergenden Branches. So gehst du vor: (1) Konfliktdateien mit git status ermitteln, (2) fachlich entscheiden, welcher Inhalt richtig ist – eine Seite, die andere oder eine Kombination, bei Unklarheit mit dem Autor der anderen Änderung sprechen, (3) Konfliktmarker entfernen, (4) kompilieren und testen, (5) mit git add als gelöst markieren und mit git commit den Merge abschließen. Alternativ bricht git merge --abort den Merge ab.
main holt.| Strategie | Ablauf | Geeignet für / Bewertung |
|---|---|---|
| Feature-Branch-Workflow | main ist immer lauffähig. Für jede Aufgabe (Ticket) ein kurzer Branch, z. B. feature/123-login; Abschluss über Pull Request mit Review und CI-Prüfung, dann Merge in main. | sehr verbreitet, einfach, gut für kleine und mittlere Teams; Reviews und Tests vor jedem Merge |
| Git-Flow | dauerhafte Branches main (nur Releases) und develop (Integration); dazu feature/*, release/* (Release vorbereiten), hotfix/* (Fehler im Release). | für geplante, versionierte Releases und mehrere gepflegte Versionen; relativ aufwendig, viele Merges, eher langsam |
| Trunk-based Development | Alle integrieren sehr häufig (mind. täglich) in den Hauptzweig („Trunk“), Branches leben nur Stunden; Unfertiges wird per Feature-Toggle verborgen. | passt zu Continuous Integration/Deployment; setzt gute automatische Tests und Disziplin voraus |
Ergänzend: Branch-Schutz auf main (kein direkter Push, Merge nur per Pull Request mit mindestens einem Review und grüner Pipeline).
Vorteile: Vier-Augen-Prinzip (Fehler, Sicherheitslücken und unklarer Code werden vor dem Merge gefunden), Wissensverteilung im Team (mehr als eine Person kennt jeden Codeteil), einheitlicher Stil und Einhaltung von Konventionen, dokumentierte Diskussion zu jeder Änderung, automatische Prüfungen (Build, Tests, statische Analyse) laufen vor dem Merge. Nachteile: Zeitaufwand, Wartezeiten, wenn Reviews liegen bleiben – deshalb kleine Pull Requests.
Versioniert wird alles, was man braucht, um das Projekt aus dem Quellcode zu bauen: Quellcode, Tests, Build-Konfiguration (pom.xml, package.json, build.gradle), Datenbank-Migrationsskripte, Dokumentation, die .gitignore selbst.
Nicht versioniert werden: erzeugte Dateien (Build-Ausgaben, kompilierte Klassen, heruntergeladene Abhängigkeiten), persönliche Einstellungen (IDE-Ordner), Logdateien, Betriebssystem-Dateien und vor allem Geheimnisse (Passwörter, API-Schlüssel, Zertifikate).
Beispiel .gitignore (Python-Projekt)
# erzeugte Dateien __pycache__/ *.pyc dist/ # virtuelle Umgebung .venv/ # Editor / Betriebssystem .vscode/ Thumbs.db # Geheimnisse .env *.log
.gitignore wirkt nur für noch nicht versionierte Dateien.feat:, fix:, docs:, refactor:, test:.| Schlecht | Besser |
|---|---|
update, ., zwischenstand, Freitag | KB-57: Export der Buchungen als CSV ergänzt |
bugfix | fix: Rundungsfehler bei Beträgen mit 3 Nachkommastellen behoben |
reset oder rebase umschreiben, sondern mit revert korrigieren.Vorkommen: 1/9 · Prüfung: W22 T1 A1c (6 P: Durch manuelles Kompilieren und Bereitstellen gab es Probleme mit der Verfügbarkeit – ca) beschreiben, wie automatisierte Kompilierung und Bereitstellung umgesetzt werden können (2 P), cb) zwei Vorteile gegenüber der manuellen Bereitstellung nennen (4 P))
Deployment (Bereitstellung) bezeichnet alle Schritte, mit denen eine neue Softwareversion auf eine Zielumgebung gebracht und dort in Betrieb genommen wird. Manuell heißt das oft: Ein Administrator baut die Software auf seinem Rechner, kopiert Dateien auf den Server, passt Konfigurationen von Hand an und startet Dienste neu. Jeder dieser Schritte kann vergessen oder falsch ausgeführt werden – typische Folgen sind Ausfälle, „bei mir lief es aber“ und Abhängigkeit von einer einzelnen Person.
| Begriff | Bedeutung |
|---|---|
| Continuous Integration (CI) | Entwickler integrieren ihre Änderungen häufig (mindestens täglich) in den gemeinsamen Hauptzweig. Jede Integration (jeder Push/Pull Request) wird von einem CI-Server automatisch gebaut und getestet. Fehler fallen Minuten nach der Änderung auf, nicht erst Wochen später beim Release. Ein „roter“ Build wird sofort repariert. |
| Continuous Delivery (CD) | Erweitert CI: Jede Änderung, die alle Prüfungen besteht, wird automatisch zu einem auslieferbaren Artefakt verpackt und automatisch in Test-/Staging-Umgebungen installiert. Die Software ist jederzeit releasefähig; die Übernahme in die Produktion erfolgt per manueller Freigabe („auf Knopfdruck“), dann aber ebenfalls automatisiert. |
| Continuous Deployment | Wie Continuous Delivery, aber ohne manuelle Freigabe: Jede Änderung, die die Pipeline besteht, geht automatisch in Produktion. Setzt sehr gute automatisierte Tests und Überwachung voraus. |
| Stufe | Was passiert? | Werkzeuge (Beispiele) |
|---|---|---|
| Auslöser | Push, Pull Request, Tag oder Zeitplan startet die Pipeline auf dem CI-Server; Code kommt immer aus der Versionsverwaltung. | GitLab CI/CD, GitHub Actions, Jenkins, Azure DevOps |
| Build | Abhängigkeiten laden, Quellcode kompilieren – in einer sauberen, immer gleichen Umgebung. | Maven, Gradle, npm, dotnet |
| Test | Unit-Tests, Integrationstests (z. B. gegen eine Test-Datenbank), ggf. Testabdeckung messen. | JUnit, pytest, Jest |
| Statische Analyse | Code prüfen, ohne ihn auszuführen: Stil, typische Fehlermuster, Sicherheitslücken, bekannte Schwachstellen in Abhängigkeiten. | SonarQube, Checkstyle, SpotBugs, ESLint, Dependency-Check |
| Packaging | Auslieferbares Artefakt erzeugen (JAR, App-Bundle, Container-Image), versionieren und in einem Repository/Registry ablegen. | Docker, Nexus, Container-Registry |
| Deploy | Artefakt per Skript in Test-, Staging- und Produktionsumgebung installieren, Datenbank migrieren, Smoke-Test. | Skripte, Kubernetes, Ansible, Flyway/Liquibase |
Schlägt eine Stufe fehl, stoppt die Pipeline: Nachfolgende Stufen laufen nicht, das Team wird benachrichtigt. Die Pipeline wird als Datei im Repository beschrieben („Pipeline as Code“) und damit selbst versioniert. Beispiel für ein Node.js-Projekt mit GitHub Actions:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request] # Auslöser
jobs:
pruefen:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # Code aus dem Repository holen
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci # Abhängigkeiten exakt nach Lock-Datei
- run: npm run lint # statische Analyse
- run: npm test # Unit-Tests
Ein Build-Tool automatisiert alles, was nötig ist, um aus Quellcode ein lauffähiges Produkt zu machen: Abhängigkeiten auflösen und herunterladen (inkl. transitiver Abhängigkeiten), kompilieren, Tests ausführen, Artefakte packen (JAR/WAR, APK), Dokumentation erzeugen, Versionen veröffentlichen. Weil der Ablauf in einer Datei beschrieben ist, baut jeder Rechner und der CI-Server das Projekt gleich (reproduzierbarer Build).
| Werkzeug | Konfiguration | Merkmale |
|---|---|---|
| Maven (Java) | pom.xml (XML) | „Konvention vor Konfiguration“ (feste Ordnerstruktur src/main/java, src/test/java); fester Lebenszyklus validate → compile → test → package → verify → install → deploy: mvn package führt alle vorherigen Phasen mit aus. Bibliotheken aus Maven Central. |
| Gradle (Java, Kotlin, Android) | build.gradle(.kts) (Groovy/Kotlin-DSL) | flexibel programmierbar, inkrementelle Builds und Build-Cache (schnell), Standard bei Android; Aufruf über den Wrapper ./gradlew build. |
| npm (JavaScript/TypeScript) | package.json + package-lock.json | Paketverwaltung und Skripte (npm run build, npm test). |
Entwicklung (lokal) → Test/Integration (automatische Tests) → Staging → Produktion. Die Staging-Umgebung ist eine möglichst exakte Kopie der Produktion (gleiche Betriebssystem- und Laufzeitversionen, gleiche Konfiguration, realistische, aber anonymisierte Daten). Dort werden Installation, Datenbankmigration und Abnahme (z. B. durch Fachbereich oder Kunden) geprüft, ohne echte Nutzer zu gefährden. Grundsatz „Build once, deploy many“: Dasselbe, einmal gebaute Artefakt wandert durch alle Umgebungen; nur die Konfiguration (Umgebungsvariablen, Secrets) unterscheidet sich.
Nachteile/Aufwand: Einrichtung und Pflege der Pipeline und der Infrastruktur, Know-how, aussagekräftige automatische Tests sind Voraussetzung (eine Pipeline ohne gute Tests liefert Fehler nur schneller aus).
Weitere Begriffe: Rollback = Zurück auf die letzte funktionierende Version. Blue-Green-Deployment = neue Version parallel aufbauen und dann umschalten. Canary Release = neue Version zuerst nur für einen kleinen Teil der Nutzer. Secrets (Passwörter, Schlüssel) gehören nie in die Pipeline-Datei oder das Repository, sondern in geschützte Variablen des CI-Systems bzw. einen Secret-Speicher.
Ein Container-Image enthält die Anwendung samt Laufzeitumgebung (z. B. Java 21), Bibliotheken und Konfigurationsvorgaben. Aus dem Image werden Container gestartet – auf dem Entwicklerrechner, im Test und in der Produktion identisch. Damit verschwinden Fehler durch abweichende Umgebungen. Images werden in einer Registry abgelegt; viele Container werden mit Kubernetes orchestriert (verteilen, skalieren, neu starten). Beschrieben wird ein Image in einem Dockerfile:
# Dockerfile für das Projekt „Kassenbuch“ # Basis-Image mit Java-21-Laufzeit FROM eclipse-temurin:21-jre WORKDIR /app # gebaute Anwendung in das Image kopieren COPY target/kassenbuch.jar app.jar EXPOSE 8080 # Startbefehl des Containers ENTRYPOINT ["java", "-jar", "app.jar"]
Kommentare stehen im Dockerfile immer in einer eigenen Zeile.
| Container | Virtuelle Maschine (VM) | |
|---|---|---|
| Inhalt | Anwendung + Bibliotheken; nutzt den Kernel des Host-Betriebssystems mit | komplettes Gast-Betriebssystem auf virtueller Hardware (Hypervisor) |
| Größe, Start | Megabytes, Start in Sekunden | Gigabytes, Start in Minuten |
| Isolation | Prozess-Isolation, geringer als bei VMs | stärker (eigener Kernel) |
DevOps (Development + Operations) ist eine Kultur bzw. Arbeitsweise, in der Entwicklung und Betrieb nicht getrennt „über den Zaun werfen“, sondern gemeinsam Verantwortung für die laufende Software übernehmen. Kernelemente: Automatisierung (CI/CD, Infrastructure as Code), kurze Feedbackschleifen, Messen und Überwachen im Betrieb (Monitoring, Logging), kleine und häufige Releases, „You build it, you run it“. CI/CD ist das wichtigste Werkzeug von DevOps.
allow_failure: true), sind wertlos. · Passwörter im Klartext in der Pipeline-Datei.Vorkommen: 1/9 · Prüfung: W22 T1 A2a (6 P: beschreiben, wie die 3-Schichten-Architektur bei einer Webanwendung typischerweise aussieht und wie die Komponenten zusammenarbeiten)
Die Softwarearchitektur beschreibt die grundlegende Struktur eines Systems: aus welchen Komponenten es besteht, welche Aufgabe jede hat und wie sie miteinander kommunizieren. Gute Architektur trennt Verantwortlichkeiten („Separation of Concerns“), damit Teile unabhängig geändert, getestet und ausgetauscht werden können.
Beim Client-Server-Modell bietet ein Server Dienste an (Daten, Berechnungen), Clients fordern sie an (Anfrage → Antwort, z. B. per HTTP). Wie viel Logik auf dem Client liegt, unterscheidet Thin und Fat Client:
| Thin Client | Fat (Rich) Client | |
|---|---|---|
| Prinzip | Client zeigt nur an und nimmt Eingaben entgegen; Logik und Daten liegen auf dem Server | Client enthält einen großen Teil der Logik, oft auch lokale Daten |
| Beispiele | klassische Webanwendung im Browser, Terminal-Server | Desktop-Anwendung, App mit Offline-Modus und lokaler Datenbank |
| Vorteile | geringe Anforderungen an das Endgerät, Updates nur zentral auf dem Server, Daten zentral und sicher | offline nutzbar, schnelle Reaktion, entlastet Server und Netz, volle Nutzung der Gerätefunktionen |
| Nachteile | ohne Netz/Server nicht nutzbar, Serverlast, Latenz | Installation und Updates auf jedem Gerät, Daten müssen synchronisiert werden (Konflikte), höhere Geräteanforderungen |
In einer Schichtenarchitektur wird die Software in übereinanderliegende Schichten mit klaren Aufgaben zerlegt. Jede Schicht nutzt nur die Dienste der Schicht direkt darunter über definierte Schnittstellen und kennt die Schichten darüber nicht. Die klassische Aufteilung ist die 3-Schichten-Architektur:
| Schicht | Aufgabe | Typische Technik |
|---|---|---|
| Präsentationsschicht (Presentation Layer) | Benutzeroberfläche: Daten darstellen, Eingaben entgegennehmen, einfache Eingabeprüfung (Format, Pflichtfelder), Anfragen an die Logikschicht senden | Browser mit HTML/CSS/JavaScript, App-Oberfläche, Desktop-GUI |
| Logikschicht (Business/Application Layer) | Geschäftsregeln und Abläufe: Berechnungen, fachliche Prüfungen, Rechte, Transaktionen steuern, Schnittstellen zu Fremdsystemen | Anwendungsserver, REST-API (Java/Spring, C#/ASP.NET, PHP, Node.js) |
| Datenhaltungsschicht (Data Layer) | Daten dauerhaft und konsistent speichern, lesen, ändern, löschen; Integrität, Datensicherung | Datenbankserver (MySQL, PostgreSQL), Dateisystem; Zugriff per SQL |
Zusammenspiel (Beispiel „Platz buchen“): Der Nutzer wählt im Browser einen Platz; die Präsentationsschicht schickt eine HTTPS-Anfrage an den Anwendungsserver. Die Logikschicht prüft, ob der Platz frei ist, berechnet den Preis (Ermäßigung) und veranlasst die Speicherung: Sie sendet SQL-Befehle an die Datenhaltungsschicht, die die Buchung in der Datenbank speichert und das Ergebnis zurückmeldet. Die Logikschicht gibt eine Antwort (z. B. JSON mit Buchungsnummer) an die Präsentationsschicht, die sie dem Nutzer anzeigt. Die Präsentationsschicht greift nie direkt auf die Datenbank zu.
Schicht (Layer) vs. Stufe (Tier): Layer ist die logische Aufteilung des Codes, Tier die physische Verteilung auf Rechner. Drei Schichten können auf einem Rechner laufen; bei einer Webanwendung sind sie meist auf drei Stufen verteilt (Client-Rechner, Anwendungsserver, Datenbankserver) – deshalb auch „3-Tier“ bzw. allgemein n-Tier.
| Vorteile der Schichtenarchitektur | Nachteile |
|---|---|
|
|
MVC ist ein Architektur- bzw. Entwurfsmuster für Anwendungen mit Benutzeroberfläche. Es trennt drei Verantwortlichkeiten:
Medium, Dienste wie MedienKatalog, Datenzugriff). Kennt weder View noch Controller.Vorteile von MVC: Darstellung lässt sich ändern oder ergänzen (z. B. zusätzliche Smartphone-Ansicht), ohne Geschäftslogik anzufassen; mehrere Views für dasselbe Model; Logik ist ohne Oberfläche testbar; Designer und Entwickler können parallel arbeiten. Im klassischen Desktop-MVC benachrichtigt das Model die View über Änderungen (Beobachter-Muster); in Web-Frameworks (Spring MVC, ASP.NET Core MVC, Laravel) übergibt der Controller die Daten an die View. Verwandte Muster: MVP, MVVM (z. B. bei Android, WPF, Angular).
| Monolith | Microservices | |
|---|---|---|
| Aufbau | eine Anwendung, ein Deployment (intern ggf. in Module/Schichten gegliedert) | viele kleine, eigenständige Dienste je Fachbereich (z. B. Bestellung, Zahlung, Versand), jeder mit eigener Datenhaltung; Kommunikation über das Netz (REST, Messaging) |
| Vorteile | einfach zu entwickeln, testen, deployen und debuggen; keine Netzwerkkommunikation zwischen Teilen; Transaktionen einfach; ideal für kleine Teams und den Start | Dienste unabhängig deploy- und skalierbar; Ausfall eines Dienstes legt nicht alles lahm; Teams arbeiten unabhängig; Technologie je Dienst wählbar |
| Nachteile | wird groß und unübersichtlich; jede Änderung erfordert neues Deployment des Ganzen; nur als Ganzes skalierbar; Technologiewechsel schwer | hohe Komplexität: verteiltes System (Netzwerkfehler, Latenz), Datenkonsistenz über Dienste hinweg, aufwendiges Monitoring, Tests und Betrieb (Container, Orchestrierung); lohnt sich erst bei großen Systemen/Teams |
Ein guter Mittelweg ist der modulare Monolith: ein Deployment, intern aber streng in fachliche Module getrennt – bei Bedarf lassen sich einzelne Module später als Microservice herauslösen.
Vorkommen: 1/9 · Prüfung: W21 T1 A1a (6 P: aa) je eine Programmiersprache für Compiler- und Interpretersprachen nennen, ab) Unterschied beschreiben, ac) je einen Vor- und Nachteil eines Interpreters gegenüber einem Compiler nennen – je 2 P)
Ein Prozessor versteht nur Maschinencode (Befehle seines Befehlssatzes, z. B. x86-64 oder ARM). Programme in Hochsprachen müssen deshalb übersetzt werden. Dafür gibt es zwei Grundprinzipien – und Mischformen.
| Merkmal | Compiler | Interpreter |
|---|---|---|
| Zeitpunkt | einmal vor der Ausführung (Übersetzungszeit) | bei jeder Ausführung (Laufzeit) |
| Ergebnis | ausführbare Datei in Maschinencode | keine Datei, direkte Ausführung |
| Geschwindigkeit | schnelle Ausführung, Optimierung beim Übersetzen | langsamer, da während der Ausführung übersetzt wird |
| Fehlererkennung | Syntax- und Typfehler vor dem Start für das ganze Programm | Fehler erst, wenn die Zeile ausgeführt wird (ggf. erst nach Wochen in einem selten genutzten Zweig) |
| Entwicklung | nach jeder Änderung neu übersetzen | schneller Test-Zyklus: ändern und sofort ausführen, interaktive Konsole (REPL) |
| Plattform | ausführbare Datei ist an Betriebssystem und Prozessor gebunden → je Plattform eigene Übersetzung | Quellcode plattformunabhängig, sofern ein Interpreter für die Plattform existiert |
| Weitergabe | nur die ausführbare Datei, Quellcode bleibt geschützt; Zielrechner braucht keinen Compiler | Quellcode wird weitergegeben (einsehbar); Interpreter muss auf dem Zielrechner installiert sein |
Java wird vom Compiler javac nicht in Maschinencode, sondern in plattformunabhängigen Bytecode (.class-Dateien, gebündelt als .jar) übersetzt. Diesen führt die Java Virtual Machine (JVM) aus: Sie interpretiert den Bytecode zunächst und übersetzt häufig genutzte Programmteile („Hotspots“) zur Laufzeit mit dem Just-in-time-Compiler (JIT) in optimierten Maschinencode. Ergebnis: „Write once, run anywhere“ (dieselbe .jar läuft auf jedem System mit passender JVM) bei fast nativer Geschwindigkeit. Genauso arbeiten C# und andere .NET-Sprachen (Zwischencode IL, Laufzeitumgebung CLR) und Kotlin. Auch Python erzeugt intern Bytecode (.pyc), gilt aber als interpretierte Sprache; JavaScript-Engines im Browser kombinieren Interpreter und JIT.
Ein Transpiler (Source-to-Source-Compiler) übersetzt eine Hochsprache in eine andere, z. B. TypeScript → JavaScript (tsc). Vorteil: Die strengere Ausgangssprache (statische Typen) findet Fehler beim Übersetzen; ausgeführt wird das erzeugte JavaScript.
#include), ersetzt Makros.| Statisches Linken | Dynamisches Linken | |
|---|---|---|
| Wie? | Bibliothekscode wird in die ausführbare Datei kopiert | Bibliothek (.dll, .so) wird erst beim Start/zur Laufzeit geladen |
| Vorteil | eigenständige Datei, keine fehlenden Bibliotheken auf dem Zielsystem | kleinere Programme, Bibliothek von mehreren Programmen gemeinsam genutzt, Sicherheitsupdate der Bibliothek wirkt ohne Neukompilierung |
| Nachteil | größere Datei; Fehler in der Bibliothek erfordern Neukompilierung | Bibliothek muss in passender Version vorhanden sein („DLL-Hölle“) |
| Fehlerart | Beschreibung | Beispiel (Java) | Erkannt … |
|---|---|---|---|
| Syntaxfehler | Verstoß gegen die Grammatik der Sprache | int x = 5 (Semikolon fehlt) | vom Compiler; beim Interpreter beim Einlesen |
| Semantischer Fehler / Typfehler | syntaktisch korrekt, aber unzulässig (falscher Typ, unbekannte Variable) | boolean ok = "ja"; | bei statischer Typisierung vom Compiler; bei dynamischer Typisierung (Python) erst zur Laufzeit |
| Laufzeitfehler | Programm stürzt bei der Ausführung ab bzw. wirft eine Exception | int q = 10 / 0; → ArithmeticException; null-Zugriff → NullPointerException | erst zur Laufzeit, nur wenn die Stelle erreicht wird |
| Logischer Fehler | Programm läuft, liefert aber falsche Ergebnisse | i < n - 1 statt i < n (letztes Element fehlt) | gar nicht automatisch – nur durch Tests, Debugging, Code-Review |
Eine IDE (Integrated Development Environment, z. B. IntelliJ IDEA, Eclipse, Visual Studio, Android Studio; VS Code als erweiterbarer Editor) vereint die Werkzeuge der Entwicklung unter einer Oberfläche: Editor mit Syntaxhervorhebung und Autovervollständigung, Fehleranzeige schon beim Tippen, Compiler/Build-Integration (Maven, Gradle), Debugger, Test-Runner (JUnit), Refactoring-Funktionen (z. B. Methode umbenennen in allen Dateien), Code-Formatierung, Git-Integration, Navigation (zur Definition springen, Aufrufe finden), Profiler.
Mit dem Debugger wird ein Programm kontrolliert ausgeführt, um logische Fehler zu finden:
i == 99).Vorkommen: 1/9 · Prüfung: W21 T1 A1b (10 P: ba) einen Vorteil und einen Nachteil des Einsatzes einer umfassenden Klassenbibliothek beschreiben (4 P), bb) drei Aspekte beschreiben, die bei der Dokumentation einer eigenen Erweiterung der Bibliothek zu beachten sind (6 P))
Eine Klassenbibliothek ist eine Sammlung wiederverwendbarer, bereits getesteter Klassen und Methoden für wiederkehrende Aufgaben, z. B. die Java-Standardbibliothek (java.util, java.time), Bibliotheken für JSON, PDF-Erzeugung, Logging oder Diagramme. Die öffentlich nutzbaren Klassen und Methoden bilden die API (Application Programming Interface) der Bibliothek – nur auf sie darf sich der eigene Code verlassen; interne Details können sich ändern.
Ein Framework ist ein Rahmengerüst, das den Ablauf und die Struktur der Anwendung vorgibt. Der Entwickler ergänzt nur fachlichen Code an vorgesehenen Stellen (Klassen ableiten, Interfaces implementieren, Annotationen wie @GetMapping oder @Test), und das Framework ruft diesen Code zur richtigen Zeit auf. Diese Umkehr der Steuerung heißt Inversion of Control („Hollywood-Prinzip: Don’t call us, we call you“). Beispiele: Spring/Spring Boot, Jakarta EE, ASP.NET Core, Angular, Django, Laravel, Android-SDK, JUnit.
| Vorteile | Nachteile |
|---|---|
|
|
Paketmanager bzw. Build-Tools mit Abhängigkeitsverwaltung (Maven/Gradle für Java, npm für JavaScript, pip für Python, NuGet für .NET) erledigen: Bibliotheken in der angegebenen Version aus einem zentralen Repository (Maven Central, npm-Registry, PyPI) herunterladen, transitive Abhängigkeiten (Abhängigkeiten der Abhängigkeiten) automatisch mitladen, Versionskonflikte auflösen, Gültigkeitsbereiche trennen (z. B. Testbibliotheken nur zum Testen) und den Stand reproduzierbar machen (Lock-Datei wie package-lock.json hält die exakt verwendeten Versionen fest). Abhängigkeiten werden deklariert statt als JAR-Dateien ins Repository kopiert.
Beispiel package.json (npm)
"dependencies": {
"express": "^4.19.2",
"dayjs": "~1.11.10"
},
"devDependencies": {
"jest": "^29.7.0"
}
^4.19.2: kompatible Updates erlaubt, also ≥ 4.19.2 und < 5.0.0.~1.11.10: nur Patch-Updates, also ≥ 1.11.10 und < 1.12.0.devDependencies: nur für Entwicklung/Test, nicht im ausgelieferten Produkt.
Versionsnummern der Form MAJOR.MINOR.PATCH (z. B. 4.19.2) mit festen Regeln:
| Teil erhöht | Bedeutung | Für Nutzer der Bibliothek |
|---|---|---|
| PATCH (4.19.3) | abwärtskompatible Fehlerbehebung | gefahrlos aktualisieren, keine Codeänderung |
| MINOR (4.20.0) | neue Funktionen, abwärtskompatibel; auch: Funktionen als veraltet (deprecated) markiert | ohne Codeänderung möglich; Deprecation-Warnungen beachten |
| MAJOR (5.0.0) | inkompatible Änderungen der API (Breaking Changes): Methoden entfernt/umbenannt, Verhalten geändert, neue Mindestvoraussetzungen | Änderungen am eigenen Code wahrscheinlich; Migrationshinweise lesen, gründlich testen |
Versionen 0.y.z gelten als Anfangsentwicklung – dort kann sich alles jederzeit ändern. Vorabversionen werden angehängt: 2.0.0-beta.1. Übliche Praxis: Veraltetes erst in einer MINOR-Version als deprecated markieren und frühestens in der nächsten MAJOR-Version entfernen.
| Risiko | Gegenmaßnahme |
|---|---|
| bekannte Sicherheitslücke in einer (auch transitiven) Abhängigkeit | automatischer Schwachstellen-Scan in der Pipeline (z. B. OWASP Dependency-Check, npm audit, Dependabot/Renovate), zügig aktualisieren, SBOM führen (→ WZ-06) |
| Projekt wird nicht mehr gepflegt / verschwindet (npm „left-pad“, 2016) | vor dem Einsatz Aktivität, Verbreitung, Maintainer prüfen; eigenes Artefakt-Repository als Zwischenspeicher (Nexus, Artifactory) |
| Breaking Change beim Update | Versionen festlegen bzw. Lock-Datei, SemVer beachten, Release Notes lesen, automatisierte Tests vor dem Update |
| Schadcode in Paketen (Lieferkettenangriff, Tippfehler-Pakete) | nur vertrauenswürdige Quellen, Prüfsummen/Signaturen, wenige und bekannte Abhängigkeiten |
| Lizenzpflichten (z. B. Copyleft) | Lizenz vor dem Einsatz prüfen (→ WZ-06) |
Wer eine Bibliothek um eigene Klassen erweitert, muss so dokumentieren, dass andere Entwickler (Zielgruppe!) die Erweiterung ohne Rückfrage korrekt einsetzen und später warten können. Worauf zu achten ist:
null erlaubt ist), Rückgabewert, mögliche Exceptions und wann sie auftreten, Seiteneffekte, ggf. Thread-Sicherheit.@deprecated mit Alternative), @since.Beispiel: Javadoc-Kommentar
/**
* Berechnet den Bruttobetrag aus einem Nettobetrag.
* Das Ergebnis wird kaufmännisch auf zwei Nachkommastellen gerundet.
*
* <p>Beispiel: {@code berechneBrutto(new BigDecimal("100.00"), Steuersatz.ERMAESSIGT)}
* liefert {@code 107.00}.</p>
*
* @param netto Nettobetrag in Euro; nicht {@code null} und nicht negativ
* @param satz anzuwendender Steuersatz; nicht {@code null}
* @return Bruttobetrag in Euro mit zwei Nachkommastellen
* @throws IllegalArgumentException wenn {@code netto} negativ ist
* @since 1.4
* @see Steuersatz
*/
public static BigDecimal berechneBrutto(BigDecimal netto, Steuersatz satz) { … }
Wichtige Javadoc-Tags: @param, @return, @throws, @since, @deprecated, @see, {@code …}, {@link …}. Daraus erzeugt das Werkzeug javadoc eine HTML-Referenz (entsprechend: XML-Kommentare in C#, Docstrings in Python, JSDoc).
Erweitern statt ändern: Eine Bibliothek erweitert man über ihre vorgesehenen Erweiterungspunkte – eigene Unterklassen, Implementierung von Interfaces, Komposition/Wrapper (eigene Klasse benutzt die Bibliotheksklasse) – und nicht durch Ändern ihres Quellcodes. Sonst gehen die eigenen Änderungen beim nächsten Update der Bibliothek verloren oder Updates (auch Sicherheitsupdates) werden praktisch unmöglich (Open-Closed-Prinzip: offen für Erweiterung, geschlossen für Änderung).
Vorkommen: 1/9 · Prüfung: W22 T1 A2c (9 P: ca) Begriff Open Source erläutern (3 P), cb) begründen, ob jede Open-Source-Bibliothek ohne Einschränkungen eingesetzt werden darf (2 P), cc) einen Vor- und einen Nachteil von Open-Source-Bibliotheken beschreiben (4 P))
Open-Source-Software ist Software, deren Quellcode öffentlich zugänglich ist und deren Lizenz jedem erlaubt, sie für beliebige Zwecke zu nutzen, den Code zu untersuchen, zu verändern und – verändert oder unverändert – weiterzugeben. Welche Lizenzen das erfüllen, legt die Open Source Initiative (OSI) anhand der Open Source Definition fest. Deren zehn Kriterien zusammengefasst:
Die Free Software Foundation spricht von Freier Software mit vier Freiheiten (benutzen, untersuchen, weitergeben, verbessern). Gemeint sind praktisch dieselben Lizenzen, die Begründung ist eher ethisch; zusammengefasst oft „FOSS“.
| Art | Beschreibung | Beispiel |
|---|---|---|
| Open Source | Quellcode offen; nutzen, ändern, weitergeben erlaubt (unter Lizenzbedingungen); meist kostenlos, kommerzielle Nutzung erlaubt | Linux, LibreOffice, Firefox, PostgreSQL |
| Freeware | kostenlos nutzbar, aber Quellcode nicht verfügbar, Veränderung verboten; Nutzung oft eingeschränkt (z. B. nur privat) | viele kostenlose Tools und Viewer |
| Shareware | darf zum Testen kostenlos genutzt und weitergegeben werden; nach Testzeitraum oder für den vollen Funktionsumfang kostenpflichtig; Quellcode nicht verfügbar | Testversionen von Packprogrammen, Tools |
| Proprietär / kommerziell | Hersteller behält alle Rechte, Nutzung nur gegen Lizenz (Kauf, Abo), Quellcode geheim, Weitergabe verboten | Microsoft Office, Adobe Photoshop |
| „Source available“ | Quellcode einsehbar, aber Lizenz schränkt Nutzung ein (z. B. kein konkurrierendes Cloud-Angebot) – keine Open Source im Sinne der OSI | SSPL, Business Source License (BSL) |
Kern der Unterscheidung ist die Frage, ob die Lizenz auf abgeleitete Werke „vererbt“ wird. Copyleft bedeutet: Wer die Software verändert oder in eigene Software einbaut und weitergibt, muss das Ergebnis unter derselben Lizenz und mit Quellcode weitergeben.
| Lizenz | Typ | Wichtigste Bedingungen | Bekannte Beispiele |
|---|---|---|---|
| MIT | permissiv | Copyright- und Lizenzhinweis in allen Kopien beibehalten; Haftungsausschluss. Sonst praktisch keine Pflichten. | React, jQuery |
| BSD (2-/3-Clause) | permissiv | wie MIT; 3-Clause zusätzlich: Namen der Autoren nicht ohne Erlaubnis für Werbung nutzen. | Programmiersprache Go |
| Apache 2.0 | permissiv | Lizenztext beilegen, NOTICE-Datei weitergeben, Änderungen kennzeichnen; enthält ausdrückliche Patentlizenz. | Spring Framework, Kotlin, Android (AOSP) |
| LGPL (2.1/3.0) | schwaches Copyleft | Bibliothek darf von proprietärer Software genutzt (gelinkt) werden. Änderungen an der Bibliothek selbst müssen unter LGPL offengelegt werden; Nutzer müssen die Bibliothek gegen eine andere Version austauschen können (üblich: dynamisches Linken); Lizenztext und Bezugsquelle des Bibliotheks-Quellcodes mitliefern. | Qt (auch GPL/kommerziell), FFmpeg (Grundkonfiguration) |
| MPL 2.0 | schwaches Copyleft (dateibezogen) | geänderte MPL-Dateien bleiben MPL und müssen offengelegt werden; eigene neue Dateien frei lizenzierbar. | Firefox |
| GPL (2.0/3.0) | starkes Copyleft | Wer das Programm oder ein darauf basierendes Werk (auch durch Einbinden einer GPL-Bibliothek) weitergibt, muss es als Ganzes unter GPL lizenzieren und den vollständigen Quellcode mitliefern oder anbieten. Verkaufen ist erlaubt, zusätzliche Einschränkungen nicht. | Linux-Kernel (GPL-2.0), WordPress, MySQL Community |
| AGPL-3.0 | Netzwerk-Copyleft | wie GPL-3.0; zusätzlich gilt das Bereitstellen eines (veränderten bzw. darauf aufbauenden) Programms über ein Netzwerk als Auslöser: Den Nutzern des Dienstes muss der Quellcode angeboten werden. Schließt die „SaaS-Lücke“ der GPL. | Nextcloud, Grafana; iText (AGPL oder kommerziell) |
Dual Licensing: Manche Hersteller bieten dieselbe Software unter einer Copyleft-Lizenz (GPL/AGPL) und gegen Gebühr unter einer kommerziellen Lizenz an. Wer den Quellcode nicht offenlegen will, kauft die kommerzielle Lizenz.
Lizenzkompatibilität: Code unter permissiver Lizenz darf in GPL-Projekte übernommen werden (MIT → GPL: ja; Apache 2.0 → GPL-3.0: ja, aber nicht in „GPL-2.0-only“-Projekte). Umgekehrt nicht: GPL-Code darf nicht in ein MIT- oder proprietäres Projekt kopiert werden, weil die Lizenz des Ergebnisses dann GPL sein muss. GPL-2.0-only und GPL-3.0 sind untereinander nicht kompatibel („or later“-Klausel beachten).
| Vorteile | Nachteile |
|---|---|
|
|
Eine SBOM („Stückliste“ der Software) ist eine maschinenlesbare, vollständige Liste aller Komponenten eines Softwareprodukts – einschließlich transitiver Abhängigkeiten – mit Name, Version, Hersteller/Herkunft, Lizenz und Prüfsumme. Gängige Formate sind SPDX und CycloneDX; Build-Werkzeuge erzeugen sie automatisch in der Pipeline. Nutzen: Wird eine Sicherheitslücke in einer Bibliothek bekannt, sieht man sofort, welche Produkte und Versionen betroffen sind; Lizenzprüfung und Weitergabe von Lizenzinformationen an Kunden; Transparenz in der Lieferkette. Der EU Cyber Resilience Act (Verordnung (EU) 2024/2847) verpflichtet Hersteller von Produkten mit digitalen Elementen u. a. dazu, die enthaltenen Komponenten und Schwachstellen zu dokumentieren und dafür eine SBOM in einem gängigen, maschinenlesbaren Format zu erstellen. Die Meldepflichten für aktiv ausgenutzte Schwachstellen gelten seit 11. September 2026, die übrigen Pflichten ab 11. Dezember 2027.
Enthält nur, was dir auch die IHK beilegen würde: die Ausgangssituation und die Anlagen, auf die sich die Aufgaben beziehen. Notationshilfen legt die IHK für diese Themen nicht bei (die Belegsätze W21 und W22 enthielten nur UML, Pseudocode/Struktogramm und SQL). Alle Firmen, Personen und Bibliotheken sind frei erfunden; Lizenzen, Werkzeuge und Befehle sind real.
Die Aufgaben dieses Blocks beziehen sich auf die folgende Ausgangssituation:
Die Lindner Digital GmbH in Kassel ist ein Softwarehaus mit 45 Mitarbeitenden. Sie sind Auszubildende/r zum Fachinformatiker/zur Fachinformatikerin Anwendungsentwicklung im Team „Field Service“ (acht Entwicklerinnen und Entwickler, eine Testerin, ein Administrator; Teamleiter Markus Feld).
Das Team entwickelt für die Haustechnik Albers GmbH & Co. KG (Heizung, Sanitär, Lüftung; sechs Niederlassungen in Nordhessen, 140 Monteurinnen und Monteure) die Software „MonteurPlus“:
Lindner Digital betreibt den Server im eigenen Rechenzentrum; Albers nutzt MonteurPlus über das Internet. Ab 2027 will Lindner Digital MonteurPlus auch anderen Handwerksbetrieben als Mietsoftware (Software as a Service) anbieten; die Monteur-App wird dann über den Google Play Store verteilt. Quellcode und Rechte an MonteurPlus sollen bei Lindner Digital bleiben (proprietäre Software).
Bisherige Arbeitsweise: Der Quellcode lag bisher auf dem Netzlaufwerk \\fs01\projekte\monteurplus. Seit September 2026 liegt der Server-Code testweise in einem Git-Repository auf dem GitLab-Server von Lindner Digital (Anlage 3). Erstellung und Auslieferung neuer Versionen erledigt der Administrator von Hand (Anlage 4).
Hallo zusammen,
nach dem Ärger letzte Woche (Lukas hat beim Kopieren auf das Netzlaufwerk Sarahs Änderungen am AuftragService überschrieben – zwei Tage Arbeit waren weg) stellen wir ab 1. Oktober komplett auf Git um. Damit es einfach bleibt, gelten folgende Regeln:
main und pushen, sobald etwas fertig ist. Branches brauchen wir bei acht Leuten nicht.target/, die IDE-Einstellungen (.idea/) und die application-local.properties mit den Zugangsdaten zur Testdatenbank.monteurplus_v1.3_final2.zip.Viele Grüße
Markus
$ git log --oneline --graph --all
* 7d2e4b1 (HEAD -> main, origin/main) MP-118: Auftragsliste nach Termin sortieren
* 3c9a0f5 MP-112: REST-Endpunkt GET /auftraege/{id} ergänzt
* e58b3d7 asdf
* d0c4417 Zwischenstand Freitag
* a41c9e2 fix
* 19be7d0 Projektgerüst angelegt
$ git show --stat a41c9e2
commit a41c9e2b7f3d8e1c0a59b6d2f4e7c8a1b3d5e6f7
Author: Lukas Brandt <l.brandt@lindner-digital.example>
Date: Tue Sep 15 16:42:10 2026 +0200
fix
src/main/java/de/lindner/monteurplus/auftrag/AuftragService.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
Inhalt der Änderung a41c9e2 laut Ticket MP-109: Beim Speichern eines Auftrags ohne Kundenadresse trat eine NullPointerException auf. Jetzt prüft der AuftragService die Adresse und meldet „Kundenadresse fehlt“.
Alle zwei Wochen freitags ab 18 Uhr stellt der Administrator Herr Okafor eine neue Version bereit:
| Datum | Störung | Ursache (laut Nachbetrachtung) |
|---|---|---|
| 05.06.2026 | Server startet nach dem Update nicht (UnsupportedClassVersionError) | auf dem Rechner des Administrators war Java 21 installiert, auf dem Produktivserver Java 17 |
| 19.06.2026 | Auftragsliste in der App bleibt leer | SQL-Skript für eine neue Spalte wurde nicht eingespielt |
| 03.07.2026 | Fotos können nicht gespeichert werden | ein unfertiger, ungetesteter Stand eines Entwicklers lag mit auf dem Netzlaufwerk und wurde ausgeliefert |
| 17.07.2026 | 3 Stunden Ausfall am Freitagabend | Administrator krank; die Vertretung kannte den Ablauf nicht und vergaß, den Dienst neu zu starten |
.gitlab-ci.yml, seit Oktober 2026 im Einsatz)# .gitlab-ci.yml – MonteurPlus Server (Spring Boot, Java 21)
stages:
- build
- test
- analyse
- package
- staging
- production
default:
image: maven:3.9-eclipse-temurin-21
build:
stage: build
script:
- mvn -B compile
unit-tests:
stage: test
script:
- mvn -B test
artifacts:
reports:
junit: target/surefire-reports/TEST-*.xml
integration-tests:
stage: test
services:
- postgres:16
variables:
POSTGRES_DB: monteurplus_test
POSTGRES_USER: ci
POSTGRES_PASSWORD: $TEST_DB_PASSWORT # geschützte CI/CD-Variable
script:
- mvn -B verify -P integrationstest
code-analyse:
stage: analyse
script:
- mvn -B compile checkstyle:check spotbugs:check
package:
stage: package
image: docker:27
services:
- docker:27-dind
script:
# Das Dockerfile baut die JAR-Datei und verpackt sie mit Java 21 in ein Image
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
- docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
rules:
- if: $CI_COMMIT_BRANCH == "main"
deploy-staging:
stage: staging
script:
- ./deploy.sh staging "$CI_COMMIT_SHORT_SHA"
environment: staging
rules:
- if: $CI_COMMIT_BRANCH == "main"
deploy-production:
stage: production
script:
- ./deploy.sh production "$CI_COMMIT_SHORT_SHA"
environment: production
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
| Element | Bedeutung |
|---|---|
stages | Reihenfolge der Stufen. Alle Jobs einer Stage laufen parallel; die nächste Stage startet erst, wenn alle Jobs der vorherigen Stage erfolgreich waren. Schlägt ein Job fehl, gilt die Pipeline als fehlgeschlagen. |
script | Befehle, die der Job nacheinander ausführt |
image, services | Container-Image, in dem der Job läuft, bzw. zusätzlich gestartete Container (z. B. Datenbank) |
rules: - if: … | Job wird nur in die Pipeline aufgenommen, wenn die Bedingung erfüllt ist. Jobs ohne rules laufen bei jedem Push auf jeden Branch. |
when: manual | Job startet erst, wenn ihn eine berechtigte Person in GitLab per Klick auslöst |
allow_failure: true | ein Fehlschlag dieses Jobs hält die Pipeline nicht an |
$CI_COMMIT_BRANCH, $CI_COMMIT_SHORT_SHA | vordefinierte Variablen: Branch der Pipeline, Kurz-ID des Commits |
environment | Zielumgebung, in GitLab mit Versionshistorie angezeigt |
# .gitlab-ci.yml – Monteur-App (Android) – Entwurf J. Weber
image: registry.lindner.example/android-build:35
variables:
KEYSTORE_PASSWORT: "Albers2026!" # Passwort des App-Signaturschlüssels
PLAY_STORE_ZUGANG: "pl4y-st0re-7731-mp" # Zugang zum Play-Store-Konto
stages:
- build
- test
- deploy
build-app:
stage: build
script:
- ./gradlew assembleRelease
unit-tests:
stage: test
script:
- ./gradlew testReleaseUnitTest
allow_failure: true # damit die Pipeline nicht so oft rot ist
deploy-playstore:
stage: deploy
script:
- ./gradlew publishReleaseBundle --track production
Die Datei liegt im Repository der Monteur-App, auf das alle 45 Mitarbeitenden Lesezugriff haben. publishReleaseBundle --track production baut das App-Bundle und veröffentlicht es im Google Play Store für alle Nutzer.
| Komponente | Beschreibung |
|---|---|
| Web-Disposition | läuft im Browser der Disponenten (Windows-PCs). Die Seiten (z. B. Auftragsübersicht) erzeugt der Server mit Spring MVC und HTML-Templates; die Plantafel ist ein TypeScript-Modul im Browser, das Daten über die REST-API lädt und speichert. |
| Monteur-App | Android-App (Kotlin) mit lokaler SQLite-Datenbank für den Offline-Betrieb (Aufträge der Woche, Material, Berichte, Fotos). Sobald eine Verbindung besteht, gleicht die App ihre Daten über die REST-API ab (HTTPS, JSON). |
| Anwendungsserver | Spring-Boot-Anwendung (Java 21) als Container auf einem Linux-Server im Rechenzentrum von Lindner Digital. Enthält: REST-API für App und Plantafel; Web-Controller und Templates der Web-Disposition; Dienste (Services) Auftragsverwaltung, Einsatzplanung, Synchronisation und Berichtserstellung (PDF); Datenzugriffsklassen (Repositories), die per SQL auf die Datenbank zugreifen. |
| Datenbankserver | PostgreSQL 16: Kunden, Wartungsverträge, Aufträge, Monteure, Material, Arbeitsberichte. Nur vom Anwendungsserver erreichbar. |
| Kartendienst (extern) | Geokodierung von Adressen und Berechnung von Fahrzeiten; Zugriff des Servers über eine HTTPS-API (JSON). |
| ERP-System Albers (extern) | erhält jede Nacht die abgeschlossenen Aufträge als XML-Datei per SFTP. |
| Bestandteil | Beschreibung |
|---|---|
auftragsliste.html | HTML-Template; erzeugt die Tabelle der Aufträge und das Filterformular (Status, Niederlassung) |
auftragsliste.css | Gestaltung der Tabelle, z. B. rote Zeilen für Notdienst-Aufträge |
AuftragController | nimmt die Anfrage GET /auftraege?status=OFFEN&niederlassung=Kassel entgegen, ruft den AuftragService auf und übergibt die Ergebnisliste an das Template |
AuftragService | fachliche Logik: Aufträge filtern, nach Termin und Priorität sortieren, überfällige Aufträge kennzeichnen |
Auftrag | Klasse mit den Auftragsdaten (Auftragsnummer, Kunde, Termin, Status, Priorität, zugewiesener Monteur) |
AuftragRepository | liest und speichert Aufträge per SQL in der Datenbank |
| Teil | Sprache | Werkzeuge / Laufzeitumgebung |
|---|---|---|
| Server | Java 21 | IntelliJ IDEA, Maven, javac; Ausführung auf der JVM (Eclipse Temurin 21) im Container |
| Plantafel der Web-Disposition | TypeScript 5 | VS Code, npm, TypeScript-Compiler tsc; Ausführung im Browser |
| Monteur-App | Kotlin | Android Studio, Gradle |
| Datenübernahme (einmalig, ca. 60 000 Datensätze aus CSV-Dateien; Laufzeit unkritisch, wird über Nacht ausgeführt) | noch offen: Python oder C++ | – |
Kommandozeilenprogramm mp-export: wandelt die Lagerbestandsdateien der Niederlassungen in das Importformat von MonteurPlus um; läuft auf den Windows-PCs der Lager und auf einem Linux-Server | Go | Go-Compiler (go build); Ergebnis soll eine einzelne ausführbare Datei ohne weitere Installation sein |
Entwicklerrechner: Windows 11 · Server: Linux (Ubuntu) mit Container-Laufzeit
pom.xml (Auszug)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>de.example.terminkern</groupId>
<artifactId>terminkern</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>com.example.pdf</groupId>
<artifactId>pdfmaker-core</artifactId>
<version>7.1.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Ausgabe von mvn dependency:tree (gekürzt)
[INFO] de.lindner:monteurplus-server:jar:1.3.0 [INFO] +- org.springframework.boot:spring-boot-starter-web:jar:3.5.6:compile [INFO] | \- (… 27 weitere Bibliotheken …) [INFO] +- de.example.terminkern:terminkern:jar:2.4.1:compile [INFO] | +- org.example.kalender:feiertage-de:jar:1.8.0:compile [INFO] | \- org.example.json:json-mini:jar:0.9.2:compile [INFO] +- com.example.pdf:pdfmaker-core:jar:7.1.0:compile [INFO] \- org.junit.jupiter:junit-jupiter:jar:5.12.2:test
Der Server-Code verwendet die Methode Kalender.feiertage(int jahr) von TerminKern an 14 Stellen.
TerminKern – Release Notes (excerpt)
TerminKern follows Semantic Versioning 2.0.0.
3.0.0 (2026-10-01)
de.example.terminkern has been renamed to de.example.termin.Kalender.feiertage(int jahr) has been removed.2.5.0 (2026-09-01)
Kalender.istBrueckentag(LocalDate) detects bridge days between a public holiday and a weekend.Kalender.feiertage(int jahr). Use Kalender.feiertage(Year jahr, Bundesland land) instead. The old method will be removed in the next major release.2.4.2 (2026-08-12)
package de.lindner.monteurplus.termin;
import de.example.terminkern.Bundesland;
import de.example.terminkern.Kalender;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Optional;
// Erweiterung von TerminKern 2.4.1 für MonteurPlus
public class EinsatzKalender extends Kalender {
private static final int MAX_TAGE = 30;
private final Arbeitszeitmodell modell;
public EinsatzKalender(Bundesland land, Arbeitszeitmodell modell) {
super(land);
this.modell = modell;
}
// sucht termin
public Optional<LocalDateTime> naechsterFreierTermin(
Monteur m, LocalDate ab, Duration dauer, boolean notdienst) {
if (dauer.isNegative() || dauer.isZero()) {
throw new IllegalArgumentException("dauer");
}
LocalDate tag = ab;
for (int i = 0; i < MAX_TAGE; i++) {
if (notdienst || (!istFeiertag(tag) && modell.istArbeitstag(tag))) {
Optional<LocalDateTime> slot =
m.getEinsatzplan().freierSlot(tag, dauer);
if (slot.isPresent()) {
return slot;
}
}
tag = tag.plusDays(1);
}
return Optional.empty();
}
}
istFeiertag(LocalDate) ist eine Methode der Basisklasse Kalender aus TerminKern. freierSlot(tag, dauer) liefert den frühesten freien Zeitraum der Länge dauer im Einsatzplan des Monteurs an diesem Tag oder ein leeres Optional. Die Klasse soll künftig auch von zwei anderen Teams genutzt werden.
| Nr. | Bibliothek | Einsatz in MonteurPlus | Lizenz | Anmerkung |
|---|---|---|---|---|
| 1 | ChartLite 4.2 | Diagramme in der Web-Disposition (JavaScript, wird an die Browser ausgeliefert) | MIT | – |
| 2 | JsonFast 2.17 | JSON-Verarbeitung im Server | Apache License 2.0 | enthält eine NOTICE-Datei |
| 3 | GeoKit 3.1 | Kartenanzeige in der Monteur-App; unverändert, als eigenständige Bibliothek eingebunden | LGPL-3.0 | – |
| 4 | SignPad 1.4 | Unterschriftenfeld in der Monteur-App | GPL-3.0 | – |
| 5 | PdfMaker Core 7.1 | Erzeugung der Arbeitsberichte (PDF) auf dem Server | AGPL-3.0 oder kommerzielle Lizenz (Dual Licensing) | kommerzielle Lizenz: 2 400 € pro Jahr |
| 6 | RouteOpt SDK 5 | Tourenoptimierung auf dem Server | proprietär | 3 € je Monteur und Monat; Lizenzvertrag: „Nutzung nur für eigene interne Zwecke des Lizenznehmers“ |
| 7 | csv-quick 0.3 | Einlesen der CSV-Altdaten (einmalige Datenübernahme) | keine Angabe | öffentliches Repository einer Privatperson ohne LICENSE-Datei |
| 8 | DbMigrate 2.0 | spielt Datenbankänderungen ein; läuft nur in der eigenen Pipeline, wird nicht ausgeliefert | GPL-2.0 | – |
| 9 | FeiertageDE 1.8 (feiertage-de) | transitive Abhängigkeit von TerminKern (Feiertagsberechnung) | BSD-3-Clause | – |
| 10 | TerminKern 2.4.1 | Kalenderfunktionen im Server (Anlage 9) | Apache License 2.0 | – |
| 11 | json-mini 0.9.2 | transitive Abhängigkeit von TerminKern | MIT | – |
Alle Aufgaben beziehen sich auf die Ausgangssituation in Anlage 1. Antworten Sie – wie in der Prüfung – in ganzen Sätzen und mit Bezug auf die Situation, sofern nicht ausdrücklich nur „nennen“ verlangt ist.
Zwei neue Kolleginnen haben bisher nur mit Subversion gearbeitet. Sie sollen ihnen die Grundlagen von Git erklären.
| Begriff | Erläuterung |
|---|---|
| Repository | |
| Commit | |
| Branch | |
| Merge | |
| Push | |
| Tag |
Angelehnt an: W21 Teil 1, Aufgabe 1c (Versionsverwaltung im Team)
Sie übernehmen das Ticket MP-130 (Fotos zu Aufträgen hochladen). Ihr lokales Repository entspricht dem Stand in Anlage 3; den neuesten Commit 7d2e4b1 bezeichnen wir im Folgenden mit C. Sie führen nacheinander diese Befehle aus. Während Sie an Ihrem Branch arbeiten, pusht ein Kollege den Commit „MP-125: Notdienst-Kennzeichen“ (im Folgenden N) auf origin/main.
(1) git switch -c feature/MP-130-fotos (2) git add FotoController.java # neue Datei (3) git commit -m "MP-130: Upload von Auftragsfotos" # F1 (4) git commit -am "MP-130: Fotos vor dem Upload verkleinern" # F2 (5) git switch main (6) git pull (7) git merge feature/MP-130-fotos # M, kein Konflikt (8) git tag -a v1.3.0 -m "Release 1.3.0" (9) git push origin main (10) git push origin v1.3.0
main und feature/MP-130-fotos, den Tag und HEAD.feature/MP-131-anfahrt (Anfahrtspauschale abhängig von der Entfernung) in main. Git meldet:$ git merge feature/MP-131-anfahrt Auto-merging src/main/java/de/lindner/monteurplus/auftrag/AuftragService.java CONFLICT (content): Merge conflict in src/main/java/de/lindner/monteurplus/auftrag/AuftragService.java Automatic merge failed; fix conflicts and then commit the result.
public double anfahrtspauschale(Auftrag a) {
<<<<<<< HEAD
return a.isNotdienst() ? 89.00 : 39.00;
=======
return a.isNotdienst() ? 79.00 : 35.00 + 0.50 * a.getEntfernungKm();
>>>>>>> feature/MP-131-anfahrt
}
Erläutern Sie, wie es zu dieser Meldung kam (1 P), und beschreiben Sie, wie Sie den Konflikt auflösen und den Merge abschließen (2 P).
origin/main liegen, ohne seinen lokalen Branch zu verändern. Nennen Sie den passenden Befehl und grenzen Sie ihn von git pull ab.Teamleiter Markus Feld hat die Regeln für die Arbeit mit Git per E-Mail verschickt (Anlage 2). Er bittet Sie, die Regeln vor dem 1. Oktober fachlich zu prüfen.
| Punkt | Problem | Verbesserungsvorschlag |
|---|---|---|
| 2 | ||
| 3 | ||
| 4 |
main bearbeitet.a41c9e2 eine aussagekräftige Commit-Nachricht.Angelehnt an: W21 Teil 1, Aufgabe 1c (Vorschlag des Teams zur Versionsverwaltung bewerten), erweitert um Team-Workflow
In einer Teamsitzung fallen immer wieder die Begriffe CI und CD. Sie sollen sie für die Projektdokumentation klären.
Seit Oktober baut und verteilt eine GitLab-Pipeline den Server automatisch (Anlage 5).
main als Diagramm dar. Berücksichtigen Sie die Reihenfolge der Stages, parallel laufende Jobs und den manuellen Schritt.feature/MP-140-material. Nennen Sie die Jobs, die dabei ausgeführt werden, und beschreiben Sie, was geschieht, wenn der Job unit-tests fehlschlägt.Durch die manuelle Bereitstellung kam es in den letzten Monaten mehrfach zu Ausfällen von MonteurPlus (Anlage 4). Die Geschäftsführung von Albers droht mit einer Vertragsstrafe. Sie sollen die Automatisierung vorbereiten.
| Nr. | Schwachstelle | Verbesserung |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 |
package). Erläutern Sie, wie dadurch eine Störung wie die vom 05.06.2026 verhindert wird, und nennen Sie einen Unterschied zwischen einem Container und einer virtuellen Maschine.Angelehnt an: W22 Teil 1, Aufgabe 1c (automatisierte Kompilierung und Bereitstellung, Vorteile gegenüber manueller Bereitstellung)
MonteurPlus wird als 3-Schichten-Architektur umgesetzt (Anlage 7).
| Schicht | Aufgabe |
|---|---|
Die Auftragsübersicht der Web-Disposition ist nach dem MVC-Muster aufgebaut (Anlage 7, untere Tabelle).
| Bestandteil | Rolle (Model / View / Controller) |
|---|---|
auftragsliste.html | |
auftragsliste.css | |
AuftragController | |
AuftragService | |
Auftrag | |
AuftragRepository |
Für das Angebot an weitere Handwerksbetriebe soll die Architektur von MonteurPlus dokumentiert und überprüft werden. Grundlage ist der Entwurf in Anlage 7.
Angelehnt an: W22 Teil 1, Aufgabe 2a (3-Schichten-Architektur einer Webanwendung und Zusammenarbeit der Komponenten)
In MonteurPlus werden mehrere Programmiersprachen eingesetzt (Anlage 8). Die Projektleitung möchte die grundlegenden Unterschiede der Übersetzungsverfahren verstehen.
| Sprache | Compiler → Maschinencode | Interpreter | Compiler → Bytecode → virtuelle Maschine |
|---|---|---|---|
| C++ | |||
| Python | |||
| Java | |||
| Go | |||
| PHP | |||
| C# |
Angelehnt an: W21 Teil 1, Aufgabe 1a
Bei der Entwicklung des Servers (Java) und des Importskripts (Python) treten die folgenden Fehler auf.
| Nr. | Java-Ausschnitt | Fehlerart | Wann/wodurch bemerkt? |
|---|---|---|---|
| (1) | String plz = 34117; | ||
| (2) | for (int i = 0; i < auftraege.size(); i++ { | ||
| (3) | Auftrag letzter = auftraege.get(auftraege.size()); | ||
| (4) | int summeMinuten = 250;Anzeige: Ø Einsatzdauer 62,0 min |
plz = 34117 und in Zeile 87 plz_text = plz.zfill(5) (zfill füllt einen Text links mit Nullen auf). Erläutern Sie, wann und warum dieser Fehler bemerkt wird, und vergleichen Sie mit Ausschnitt (1).Vor der Ausweitung des Projekts sollen die eingesetzten Sprachen und Übersetzungswege dokumentiert und offene Entscheidungen getroffen werden (Anlage 8).
tsc übersetzt. Erläutern Sie, was dabei geschieht, und beschreiben Sie einen Vorteil gegenüber direkt in JavaScript geschriebenem Code.mp-export wird in Go entwickelt (Anlage 8).mp-export.exe und erläutern Sie dabei die Aufgabe des Linkers. (3 P)Angelehnt an: W21 Teil 1, Aufgabe 1a (Compiler- und Interpretersprachen), vertieft um Bytecode, Transpiler und Linker
Der Server nutzt das Framework Spring Boot und mehrere Bibliotheken (Anlagen 1 und 9).
Angelehnt an: W21 Teil 1, Aufgabe 1ba
Die Abhängigkeiten des Servers werden mit Maven verwaltet (Anlage 9).
| Version | Aussage der Versionsnummer / Inhalt | Update ohne Codeänderung? |
|---|---|---|
| 2.4.2 | ||
| 2.5.0 | ||
| 3.0.0 |
json-mini für MonteurPlus ergibt, und zwei Maßnahmen, mit denen solche Risiken künftig früh erkannt oder begrenzt werden.Das Team hat die Bibliothek TerminKern um die Klasse EinsatzKalender erweitert (Anlage 10). Die Erweiterung soll künftig auch von zwei anderen Teams genutzt werden und muss deshalb dokumentiert werden.
naechsterFreierTermin einen vollständigen Javadoc-Kommentar.Kalender im Quellcode von TerminKern einzufügen. Begründen Sie, warum die Erweiterung stattdessen als eigene Unterklasse umgesetzt wurde.Angelehnt an: W21 Teil 1, Aufgabe 1bb (Dokumentation einer eigenen Bibliothekserweiterung)
In einer Projektbesprechung wird darüber gesprochen, welche Bibliotheken in MonteurPlus verwendet werden dürfen.
Angelehnt an: W22 Teil 1, Aufgabe 2ca und 2cb
Für die Lizenzprüfung von MonteurPlus sollen Sie Software-Arten abgrenzen und erste Bibliotheken aus Anlage 11 prüfen.
| Software-Art | Quellcode verfügbar | Verändern erlaubt | Weitergabe erlaubt | kostenlos nutzbar |
|---|---|---|---|---|
| Open Source | ||||
| Freeware | ||||
| Shareware | ||||
| Proprietäre Software |
| Nr. | Einsatz zulässig? | Begründung und Pflichten |
|---|---|---|
| 1 | ||
| 3 | ||
| 4 |
Bevor MonteurPlus ab 2027 als Mietsoftware an weitere Handwerksbetriebe angeboten wird, bittet Sie die Geschäftsführung um eine Lizenzprüfung (Anlagen 1 und 11).
| Nr. | Einsatz? | Begründung / Maßnahme |
|---|---|---|
| 5 | ||
| 6 | ||
| 7 | ||
| 8 |
lindner-utils kopieren, die Lindner Digital unter der MIT-Lizenz auf GitHub veröffentlichen will. Beurteilen Sie dieses Vorhaben.Angelehnt an: W22 Teil 1, Aufgabe 2c (Open Source, Lizenzbedingungen, Vor- und Nachteile von Open-Source-Bibliotheken)
Diese echten Prüfungsaufgaben passen zu diesem Block (Dateien im Ordner Prüfungsvorbereitung). Für W21 und W22 gibt es keine Lösungsdateien; Lösungen liegen nur für 2023 Sommer, 2023 Winter, 2024 Sommer und 2025 Winter vor (dort vom u-form-Verlag). Vergleiche deine Antworten zu W21/W22 mit den Lösungen der entsprechenden Übungsaufgaben in diesem Block.
| Prüfung | Aufgabe | Thema | Datei · Lösung |
|---|---|---|---|
| Winter 2021 | T1 A1a (6 P) | Compiler- und Interpretersprachen: Beispiele, Unterschied, Vor-/Nachteil Interpreter | 2021/winter/AE 2021 Winter Teil 1.pdf · keine Lösung |
| Winter 2021 | T1 A1b (10 P) | umfassende Klassenbibliothek: Vor-/Nachteil; Dokumentation einer eigenen Erweiterung | wie oben · keine Lösung |
| Winter 2021 | T1 A1c (4 P) | Vorschlag des Teams zur Versionsverwaltung bewerten | wie oben · keine Lösung |
| Winter 2021 | T1 A4cb (5 P) | verwandt: nur automatische Code-Reviews und Unit-Tests als QS – bewerten | wie oben · keine Lösung |
| Winter 2022 | T1 A1c (6 P) | automatisierte Kompilierung und Bereitstellung (CI/CD), Vorteile gegenüber manueller Bereitstellung | 2022/winter/AE 2022 Winter Teil 1.pdf · keine Lösung |
| Winter 2022 | T1 A2a (6 P) | 3-Schichten-Architektur einer Webanwendung, Zusammenarbeit der Komponenten | wie oben · keine Lösung |
| Winter 2022 | T1 A2c (9 P) | Open Source erläutern, Lizenzbedingungen, Vor-/Nachteil von OSS-Bibliotheken | wie oben · keine Lösung |
| Winter 2022 | T1 A1a (4 P) | verwandt: Schwachstellen veralteter IT-Infrastruktur (Verfügbarkeit) | wie oben · keine Lösung |
| Sommer 2024 | T1 A1b (6 P) | verwandt: drei qualitätssichernde Maßnahmen (z. B. Code-Review, CI) | 2024/sommer/AE Sommer 2024 Teil 1+2+3.pdf · Lösung: AE Sommer 2024 Teil 1 Lösungen.pdf |