AP5 FinalProtocol AP2-Ausbau: 10 Themen / 200 Fragen (FISI + FIAE)

Je Fachrichtung 5 neue Themen a 20 Fragen, nach dem bestehenden Skelett
(Lernfokus + Inhaltssektionen + Pruefungsmodus, data-questions-src) und JSON-
Schema {title, questions:[{category,hint,text,answers[3],correct,explanation}]}:

- FISI: netzwerkplanung, it-sicherheit, virtualisierung, monitoring-backup,
  skripting.
- FIAE: sql, uml, oop, algorithmen, testverfahren.

Jede Datei: 20 Fragen, 5 Kategorien a 4, correct ausgewogen rotierend (7/7/6),
Erklaerungen benennen die Distraktoren-Fallen, "du"-Ansprache, echte Umlaute
(UTF-8). Navigation in finalflux.html um je 5 Links erweitert (Bestand bleibt).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WFxcjtc9HNP4VECT6Ur1tE
This commit is contained in:
AliceDarkest
2026-07-21 00:09:02 +02:00
parent 0b3286af4c
commit 3a1bd759c7
21 changed files with 3571 additions and 0 deletions
@@ -0,0 +1,112 @@
<!DOCTYPE html>
<html lang="de" data-theme="dark">
<head>
<meta charset="UTF-8">
<title>Algorithmen - FinalProtocol AP2</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/theme.css?v=3">
<link rel="stylesheet" href="/css/finalflux.css">
<script src="/js/theme.js?v=3"></script>
</head>
<body class="finalflux-page">
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<main>
<a href="/finalflux" class="back-link">Zurück zu FinalProtocol</a>
<h1>Algorithmen</h1>
<section>
<h2>Lernfokus</h2>
<p>AP2 Anwendungsentwicklung: Abläufe strukturiert darstellen, Standardverfahren zum Sortieren und Suchen einordnen und ihren Aufwand mit der O-Notation bewerten.</p>
<ul class="key-list">
<li>Kontrollstrukturen im Struktogramm und Pseudocode sicher lesen und schreiben.</li>
<li>Sortier- und Suchverfahren nach Prinzip und Voraussetzung unterscheiden.</li>
<li>Laufzeitkomplexität in O-Notation einordnen und Rekursion sauber aufbauen.</li>
</ul>
</section>
<section>
<h2>Struktogramm &amp; Pseudocode</h2>
<p>Jeder Algorithmus lässt sich aus drei Grundstrukturen zusammensetzen, die im Struktogramm (Nassi-Shneiderman) als geschachtelte Blöcke ohne Sprünge gezeichnet werden.</p>
<ul class="key-list">
<li><strong>Sequenz:</strong> Anweisungen werden streng nacheinander abgearbeitet – ein einfaches Rechteck.</li>
<li><strong>Verzweigung:</strong> ein dreieckiger Bedingungskopf teilt in Ja- und Nein-Zweig (<code>if-else</code>).</li>
<li><strong>Schleife:</strong> <em>kopfgesteuert</em> (<code>while</code>) prüft vor dem Durchlauf – ggf. null Durchläufe; <em>fußgesteuert</em> (<code>do-while</code>) prüft danach – mindestens ein Durchlauf.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Sequenz, Verzweigung, Schleife – mit diesen drei Bausteinen kommt jeder strukturierte Algorithmus ohne GOTO aus.</p>
</section>
<section>
<h2>Sortier- &amp; Suchverfahren</h2>
<p>Sortier- und Suchverfahren unterscheiden sich in Vorgehen und Voraussetzung – genau das wird in der AP2 gern abgefragt.</p>
<ul class="key-list">
<li><strong>Einfache Sortierer:</strong> Bubblesort (Nachbarn tauschen), Selectionsort (Minimum suchen), Insertionsort (einsortieren) – meist O(n²).</li>
<li><strong>Effiziente Sortierer:</strong> Mergesort und Quicksort nach dem Prinzip „Teile und herrsche" – im Mittel O(n log n), Quicksort im schlechtesten Fall O(n²).</li>
<li><strong>Suche:</strong> lineare Suche geht der Reihe nach durch (O(n)); die binäre Suche halbiert den Bereich (O(log n)).</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Die binäre Suche funktioniert nur auf <em>sortierten</em> Daten – ohne Sortierung bleibt nur die lineare Suche.</p>
</section>
<section>
<h2>O-Notation</h2>
<p>Die O-Notation beschreibt, wie der Aufwand mit der Eingabegröße n wächst – unabhängig von Hardware und Konstanten.</p>
<ul class="key-list">
<li><strong>O(1):</strong> konstant, z. B. Array-Zugriff über den Index.</li>
<li><strong>O(log n):</strong> halbierend, z. B. binäre Suche; <strong>O(n):</strong> linear, z. B. lineare Suche.</li>
<li><strong>O(n log n):</strong> gute Sortierer (Merge-/Quicksort); <strong>O(n²):</strong> verschachtelte Schleifen, z. B. Bubblesort.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Nach steigendem Aufwand gilt O(1) &lt; O(log n) &lt; O(n) &lt; O(n log n) &lt; O(n²).</p>
</section>
<section>
<h2>Rekursion</h2>
<p>Eine rekursive Funktion löst ein Problem, indem sie sich mit einem verkleinerten Teilproblem selbst aufruft.</p>
<ul class="key-list">
<li><strong>Basisfall:</strong> Abbruchbedingung, die ein Ergebnis ohne weiteren Selbstaufruf liefert.</li>
<li><strong>Rekursionsschritt:</strong> Selbstaufruf mit kleinerem Teilproblem, das dem Basisfall näherkommt.</li>
<li><strong>Stack:</strong> jeder Aufruf belegt einen eigenen Stack-Frame – zu tiefe Rekursion führt zum Stack Overflow.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Ohne erreichbaren Basisfall wird jede Rekursion zur Endlosrekursion und läuft in den Stack Overflow.</p>
</section>
<section>
<h2>Prüfungsmodus</h2>
<p>Dieser ProtocolCheck führt dich durch die wichtigsten AP2-Aspekte dieses Themas. Du kannst Antworten prüfen, Fragen überspringen und bekommst am Ende eine Auswertung nach Kategorie.</p>
</section>
<section class="finalflux-test" data-finalflux-test aria-live="polite">
<div class="test-meta">
<span data-question-counter>Frage 1</span>
<span data-score-counter>0 richtig</span>
</div>
<div class="category-block">
<p class="eyebrow">Kategorie</p>
<h2 data-category-title>Algorithmen</h2>
<p data-category-hint>AP2-Training</p>
</div>
<div class="question-card">
<h3 data-question-text></h3>
<div data-answer-options class="answer-options"></div>
<div data-answer-feedback class="fluxcheck-result"></div>
</div>
<div class="test-actions">
<button type="button" data-check-answer>Antwort prüfen</button>
<button type="button" data-skip-question class="secondary">Überspringen</button>
<button type="button" data-next-question class="secondary" disabled>Weiter</button>
</div>
</section>
<section data-test-result class="finalflux-panel" hidden>
<h2>Auswertung</h2>
<p data-result-summary></p>
<ul data-category-summary class="key-list"></ul>
<div class="finalflux-actions">
<button type="button" data-restart-test>Test neu starten</button>
<a href="/finalflux">Zurück zur Übersicht</a>
</div>
</section>
</main>
<script src="/js/finalflux-test.js" data-questions-src="/finalflux/questions/ap2_fiae_algorithmen.json" defer></script>
</body>
</html>
@@ -0,0 +1,112 @@
<!DOCTYPE html>
<html lang="de" data-theme="dark">
<head>
<meta charset="UTF-8">
<title>OOP - FinalProtocol AP2</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/theme.css?v=3">
<link rel="stylesheet" href="/css/finalflux.css">
<script src="/js/theme.js?v=3"></script>
</head>
<body class="finalflux-page">
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<main>
<a href="/finalflux" class="back-link">Zurück zu FinalProtocol</a>
<h1>OOP</h1>
<section>
<h2>Lernfokus</h2>
<p>AP2 Anwendungsentwicklung: Objektorientierung sicher anwenden – Daten kapseln, Typen über Vererbung und Interfaces gliedern und Beziehungen bewusst als „ist-ein" oder „hat-ein" modellieren.</p>
<ul class="key-list">
<li>Kapselung mit Sichtbarkeiten sowie Getter/Setter richtig einsetzen.</li>
<li>Überschreiben und Überladen samt dynamischer Bindung sicher unterscheiden.</li>
<li>Interfaces, abstrakte Klassen und Komposition gezielt gegeneinander abwägen.</li>
</ul>
</section>
<section>
<h2>Kapselung</h2>
<p>Kapselung (Information Hiding) verbirgt die inneren Daten einer Klasse und gibt sie nur über kontrollierte Methoden frei.</p>
<ul class="key-list">
<li><strong>Sichtbarkeiten:</strong> <code>private</code> nur in der eigenen Klasse, <code>protected</code> zusätzlich für Unterklassen/Paket, <code>public</code> überall.</li>
<li><strong>Getter/Setter:</strong> steuern Lese- und Schreibzugriff; der Setter kann Werte <em>validieren</em>, bevor sie gesetzt werden.</li>
<li><strong>Nur lesbar:</strong> Attribut <code>private</code> lassen und nur einen Getter (keinen Setter) anbieten.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Attribute <code>private</code>, Zugriff über Methoden – so behält die Klasse die Kontrolle über ihre Daten.</p>
</section>
<section>
<h2>Vererbung</h2>
<p>Vererbung modelliert eine „ist-ein"-Beziehung: Die Unterklasse übernimmt Attribute und Methoden der Oberklasse und erweitert sie.</p>
<ul class="key-list">
<li><strong>Ober-/Unterklasse:</strong> die Subklasse erbt und darf geerbte Methoden <em>überschreiben</em>.</li>
<li><strong><code>super</code>:</strong> ruft Konstruktor bzw. Methode der Oberklasse auf, um deren Teil des Objekts zu initialisieren.</li>
<li><strong>Überschreiben (override):</strong> gleiche Signatur, neue Implementierung in der Unterklasse.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> „ist-ein" heißt Vererbung – ein Hund <em>ist ein</em> Tier, ein Auto <em>ist kein</em> Motor.</p>
</section>
<section>
<h2>Polymorphie: Überladen &amp; Überschreiben</h2>
<p>Polymorphie erlaubt, verschiedene Objekte einheitlich über einen gemeinsamen Obertyp zu behandeln.</p>
<ul class="key-list">
<li><strong>Überladen (overloading):</strong> gleicher Name, andere Parameterliste, gleiche Klasse – der Compiler wählt zur <em>Compilezeit</em>.</li>
<li><strong>Überschreiben (overriding):</strong> Unterklasse ersetzt geerbte Methode – der echte Objekttyp entscheidet zur <em>Laufzeit</em> (dynamische Bindung).</li>
<li><strong>Nutzen:</strong> eine Liste von <code>Form</code>-Objekten zeichnen, ohne den konkreten Typ zu kennen.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Überladen entscheidet der Compiler (Parameter), Überschreiben die Laufzeit (Objekttyp).</p>
</section>
<section>
<h2>Interfaces, abstrakte Klassen &amp; Komposition</h2>
<p>Für Struktur und Wiederverwendung stehen mehrere Werkzeuge bereit, die du bewusst wählst.</p>
<ul class="key-list">
<li><strong>Interface:</strong> reiner Vertrag; eine Klasse kann <em>mehrere</em> Interfaces implementieren (<code>implements Comparable, Serializable</code>).</li>
<li><strong>Abstrakte Klasse:</strong> nicht instanziierbar, bringt aber Zustand und fertige Methoden mit; nur <em>eine</em> Basisklasse.</li>
<li><strong>Komposition:</strong> „hat-ein" – ein Objekt enthält ein anderes als Attribut, lose gekoppelt und flexibel.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> „Favor composition over inheritance" – lieber ein Motor-Objekt <em>enthalten</em> als tief von einer fragilen Basisklasse erben.</p>
</section>
<section>
<h2>Prüfungsmodus</h2>
<p>Dieser ProtocolCheck führt dich durch die wichtigsten AP2-Aspekte dieses Themas. Du kannst Antworten prüfen, Fragen überspringen und bekommst am Ende eine Auswertung nach Kategorie.</p>
</section>
<section class="finalflux-test" data-finalflux-test aria-live="polite">
<div class="test-meta">
<span data-question-counter>Frage 1</span>
<span data-score-counter>0 richtig</span>
</div>
<div class="category-block">
<p class="eyebrow">Kategorie</p>
<h2 data-category-title>OOP</h2>
<p data-category-hint>AP2-Training</p>
</div>
<div class="question-card">
<h3 data-question-text></h3>
<div data-answer-options class="answer-options"></div>
<div data-answer-feedback class="fluxcheck-result"></div>
</div>
<div class="test-actions">
<button type="button" data-check-answer>Antwort prüfen</button>
<button type="button" data-skip-question class="secondary">Überspringen</button>
<button type="button" data-next-question class="secondary" disabled>Weiter</button>
</div>
</section>
<section data-test-result class="finalflux-panel" hidden>
<h2>Auswertung</h2>
<p data-result-summary></p>
<ul data-category-summary class="key-list"></ul>
<div class="finalflux-actions">
<button type="button" data-restart-test>Test neu starten</button>
<a href="/finalflux">Zurück zur Übersicht</a>
</div>
</section>
</main>
<script src="/js/finalflux-test.js" data-questions-src="/finalflux/questions/ap2_fiae_oop.json" defer></script>
</body>
</html>
@@ -0,0 +1,110 @@
<!DOCTYPE html>
<html lang="de" data-theme="dark">
<head>
<meta charset="UTF-8">
<title>SQL - FinalProtocol AP2</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/theme.css?v=3">
<link rel="stylesheet" href="/css/finalflux.css">
<script src="/js/theme.js?v=3"></script>
</head>
<body class="finalflux-page">
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<main>
<a href="/finalflux" class="back-link">Zurück zu FinalProtocol</a>
<h1>SQL</h1>
<section>
<h2>Lernfokus</h2>
<p>AP2 Anwendungsentwicklung: Daten über mehrere Tabellen verknüpfen, gruppieren, verändern und Tabellen sauber normalisieren.</p>
<ul class="key-list">
<li>Join-Typen sicher unterscheiden und passend wählen.</li>
<li>Mit GROUP BY/HAVING gruppieren und aggregieren.</li>
<li>DDL/DML einordnen und die Normalformen 1NF–3NF anwenden.</li>
</ul>
</section>
<section>
<h2>Joins</h2>
<p>Ein Join verknüpft Zeilen mehrerer Tabellen über eine Bedingung – meist Fremdschlüssel gleich Primärschlüssel.</p>
<ul class="key-list">
<li><strong>INNER JOIN:</strong> nur Zeilen mit Partner in <em>beiden</em> Tabellen.</li>
<li><strong>LEFT (OUTER) JOIN:</strong> alle Zeilen der linken Tabelle, fehlende Partner werden <code>NULL</code> – ideal, um „ohne Partner" zu finden (<code>IS NULL</code>).</li>
<li><strong>CROSS JOIN:</strong> kartesisches Produkt, jede Zeile mit jeder (5 × 4 = 20).</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Kunden ohne Bestellung findest du mit LEFT JOIN und <code>WHERE bestellung.id IS NULL</code>.</p>
</section>
<section>
<h2>GROUP BY &amp; HAVING</h2>
<p>GROUP BY fasst Zeilen zu Gruppen zusammen, über die Aggregatfunktionen (COUNT, SUM, AVG, MIN, MAX) rechnen.</p>
<ul class="key-list">
<li><strong>WHERE vs. HAVING:</strong> WHERE filtert einzelne Zeilen <em>vor</em> der Gruppierung, HAVING filtert Gruppen <em>nach</em> der Gruppierung (z. B. <code>HAVING COUNT(*) &gt; 3</code>).</li>
<li><strong>SELECT-Regel:</strong> ohne Aggregat dürfen nur die Gruppierungsspalten in der SELECT-Liste stehen.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Aggregate (COUNT, SUM …) gehören in HAVING, nie in WHERE.</p>
</section>
<section>
<h2>DDL &amp; DML</h2>
<p>SQL-Befehle werden nach ihrer Aufgabe gruppiert.</p>
<ul class="key-list">
<li><strong>DDL (Definition):</strong> CREATE, ALTER, DROP – definiert und ändert die Struktur.</li>
<li><strong>DML (Manipulation):</strong> INSERT, UPDATE, DELETE – ändert die Daten.</li>
<li><strong>FOREIGN KEY:</strong> sichert die referenzielle Integrität – erlaubt nur Werte, die als Primärschlüssel in der Zieltabelle existieren.</li>
</ul>
</section>
<section>
<h2>Normalisierung</h2>
<p>Normalisierung zerlegt Tabellen, um Redundanz und Anomalien zu vermeiden.</p>
<ul class="key-list">
<li><strong>1NF:</strong> atomare Werte, keine Mehrfachwerte oder Wiederholgruppen je Feld.</li>
<li><strong>2NF:</strong> 1NF und jedes Nichtschlüsselattribut hängt vom <em>gesamten</em> Schlüssel ab (keine Teilschlüssel-Abhängigkeit).</li>
<li><strong>3NF:</strong> 2NF und keine transitiven Abhängigkeiten (Nichtschlüssel → Nichtschlüssel, z. B. PLZ → Ort).</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> „Der Schlüssel, der ganze Schlüssel und nichts als der Schlüssel" – 1NF, 2NF, 3NF in einem Satz.</p>
</section>
<section>
<h2>Prüfungsmodus</h2>
<p>Dieser ProtocolCheck führt dich durch die wichtigsten AP2-Aspekte dieses Themas. Du kannst Antworten prüfen, Fragen überspringen und bekommst am Ende eine Auswertung nach Kategorie.</p>
</section>
<section class="finalflux-test" data-finalflux-test aria-live="polite">
<div class="test-meta">
<span data-question-counter>Frage 1</span>
<span data-score-counter>0 richtig</span>
</div>
<div class="category-block">
<p class="eyebrow">Kategorie</p>
<h2 data-category-title>SQL</h2>
<p data-category-hint>AP2-Training</p>
</div>
<div class="question-card">
<h3 data-question-text></h3>
<div data-answer-options class="answer-options"></div>
<div data-answer-feedback class="fluxcheck-result"></div>
</div>
<div class="test-actions">
<button type="button" data-check-answer>Antwort prüfen</button>
<button type="button" data-skip-question class="secondary">Überspringen</button>
<button type="button" data-next-question class="secondary" disabled>Weiter</button>
</div>
</section>
<section data-test-result class="finalflux-panel" hidden>
<h2>Auswertung</h2>
<p data-result-summary></p>
<ul data-category-summary class="key-list"></ul>
<div class="finalflux-actions">
<button type="button" data-restart-test>Test neu starten</button>
<a href="/finalflux">Zurück zur Übersicht</a>
</div>
</section>
</main>
<script src="/js/finalflux-test.js" data-questions-src="/finalflux/questions/ap2_fiae_sql.json" defer></script>
</body>
</html>
@@ -0,0 +1,114 @@
<!DOCTYPE html>
<html lang="de" data-theme="dark">
<head>
<meta charset="UTF-8">
<title>Testverfahren - FinalProtocol AP2</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/theme.css?v=3">
<link rel="stylesheet" href="/css/finalflux.css">
<script src="/js/theme.js?v=3"></script>
</head>
<body class="finalflux-page">
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<main>
<a href="/finalflux" class="back-link">Zurück zu FinalProtocol</a>
<h1>Testverfahren</h1>
<section>
<h2>Lernfokus</h2>
<p>AP2 Anwendungsentwicklung: Testfälle systematisch entwerfen, Tests auf der richtigen Ebene einordnen und Schnittstellen mit passenden HTTP-Statuscodes und Datenformaten prüfen.</p>
<ul class="key-list">
<li>Blackbox- und Whitebox-Test sicher voneinander unterscheiden.</li>
<li>Äquivalenzklassen bilden und mit der Grenzwertanalyse ergänzen.</li>
<li>Testebenen, Testarten und REST-Grundlagen einordnen.</li>
</ul>
</section>
<section>
<h2>Blackbox &amp; Whitebox</h2>
<p>Beide Verfahren unterscheiden sich vor allem darin, ob der Tester den inneren Quellcode kennt.</p>
<ul class="key-list">
<li><strong>Blackbox:</strong> ohne Kenntnis des Codes – getestet wird über Eingabe und Ausgabe gegen die Spezifikation (z. B. Äquivalenzklassen, Grenzwerte).</li>
<li><strong>Whitebox:</strong> mit Kenntnis des Codes – gezielte Abdeckung von Anweisungen, Zweigen und Pfaden im Programmablauf.</li>
<li><strong>Grenze:</strong> nur Whitebox findet nie durchlaufenen oder toten Code, nur Blackbox denkt konsequent aus Nutzersicht.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Blackbox schaut auf das Verhalten, Whitebox in den Code.</p>
</section>
<section>
<h2>Äquivalenzklassen &amp; Grenzwerte</h2>
<p>Statt jeden Wert einzeln zu testen, fasst man Eingaben zu Klassen zusammen und prüft je einen Repräsentanten.</p>
<ul class="key-list">
<li><strong>Gültige und ungültige Klassen:</strong> zu jedem Wertebereich gehören mindestens eine gültige Klasse und die ungültigen Bereiche darunter und darüber.</li>
<li><strong>Grenzwertanalyse:</strong> prüft die Ränder und ihre direkten Nachbarn – bei 1 bis 100 also 0, 1, 100 und 101.</li>
<li><strong>Warum:</strong> typische Fehler wie <code>&lt;</code> statt <code>&lt;=</code> zeigen sich genau an den Grenzen.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Ein Repräsentant je Klasse plus die Werte direkt an den Rändern.</p>
</section>
<section>
<h2>Testebenen</h2>
<p>Tests bauen von der kleinsten Einheit bis zum Gesamtsystem aufeinander auf.</p>
<ul class="key-list">
<li><strong>Unit-Test:</strong> einzelne Klasse oder Methode isoliert, oft mit Mocks.</li>
<li><strong>Integrationstest:</strong> Zusammenspiel mehrerer Module über ihre Schnittstellen.</li>
<li><strong>Systemtest:</strong> vollständig integriertes System in produktionsnaher Umgebung.</li>
<li><strong>Abnahmetest:</strong> Auftraggeber prüft gegen die vereinbarten Anforderungen und gibt frei.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Unit klein, Integration zwischen den Teilen, System als Ganzes, Abnahme für den Kunden.</p>
</section>
<section>
<h2>Testarten &amp; Schnittstellen</h2>
<p>Neben den Ebenen zählen das Vorgehen und die geprüften Schnittstellen.</p>
<ul class="key-list">
<li><strong>Regressionstest:</strong> stellt sicher, dass Bestehendes nach einer Änderung weiter funktioniert – ideal automatisiert für Continuous Integration.</li>
<li><strong>TDD:</strong> Red-Green-Refactor – erst der fehlschlagende Test, dann der Code, dann das Aufräumen.</li>
<li><strong>REST-Statuscodes:</strong> 200 OK, 201 Created (nach POST), 400 Bad Request, 404 Not Found, 500 Internal Server Error.</li>
<li><strong>JSON vs. XML:</strong> beide textbasiert und maschinenlesbar; JSON meist kompakter, XML mit Attributen, Namespaces und Schema.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Ein bestandener Test beweist keine Fehlerfreiheit, nur die Abwesenheit der geprüften Fehler.</p>
</section>
<section>
<h2>Prüfungsmodus</h2>
<p>Dieser ProtocolCheck führt dich durch die wichtigsten AP2-Aspekte dieses Themas. Du kannst Antworten prüfen, Fragen überspringen und bekommst am Ende eine Auswertung nach Kategorie.</p>
</section>
<section class="finalflux-test" data-finalflux-test aria-live="polite">
<div class="test-meta">
<span data-question-counter>Frage 1</span>
<span data-score-counter>0 richtig</span>
</div>
<div class="category-block">
<p class="eyebrow">Kategorie</p>
<h2 data-category-title>Testverfahren</h2>
<p data-category-hint>AP2-Training</p>
</div>
<div class="question-card">
<h3 data-question-text></h3>
<div data-answer-options class="answer-options"></div>
<div data-answer-feedback class="fluxcheck-result"></div>
</div>
<div class="test-actions">
<button type="button" data-check-answer>Antwort prüfen</button>
<button type="button" data-skip-question class="secondary">Überspringen</button>
<button type="button" data-next-question class="secondary" disabled>Weiter</button>
</div>
</section>
<section data-test-result class="finalflux-panel" hidden>
<h2>Auswertung</h2>
<p data-result-summary></p>
<ul data-category-summary class="key-list"></ul>
<div class="finalflux-actions">
<button type="button" data-restart-test>Test neu starten</button>
<a href="/finalflux">Zurück zur Übersicht</a>
</div>
</section>
</main>
<script src="/js/finalflux-test.js" data-questions-src="/finalflux/questions/ap2_fiae_testverfahren.json" defer></script>
</body>
</html>
@@ -0,0 +1,112 @@
<!DOCTYPE html>
<html lang="de" data-theme="dark">
<head>
<meta charset="UTF-8">
<title>UML - FinalProtocol AP2</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/theme.css?v=3">
<link rel="stylesheet" href="/css/finalflux.css">
<script src="/js/theme.js?v=3"></script>
</head>
<body class="finalflux-page">
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<main>
<a href="/finalflux" class="back-link">Zurück zu FinalProtocol</a>
<h1>UML</h1>
<section>
<h2>Lernfokus</h2>
<p>AP2 Anwendungsentwicklung: Systeme mit UML modellieren – Struktur im Klassendiagramm, Abläufe in Sequenz- und Aktivitätsdiagrammen und die Anforderungssicht im Use-Case-Diagramm.</p>
<ul class="key-list">
<li>Klassen mit Attributen, Methoden und Sichtbarkeiten +/-/# lesen und notieren.</li>
<li>Beziehungen sicher unterscheiden: Assoziation, Aggregation vs. Komposition, Vererbung samt Multiplizitäten.</li>
<li>Dynamik im Sequenz- und Aktivitätsdiagramm sowie Akteure und include/extend im Use-Case-Diagramm einordnen.</li>
</ul>
</section>
<section>
<h2>Klassendiagramm</h2>
<p>Eine Klasse wird als Rechteck mit drei Fächern gezeichnet: oben der Name, in der Mitte die Attribute, unten die Methoden.</p>
<ul class="key-list">
<li><strong>Sichtbarkeiten:</strong> <code>+</code> public (überall), <code>-</code> private (nur eigene Klasse), <code>#</code> protected (auch Unterklassen).</li>
<li><strong>Attribut-Notation:</strong> <code>name : Typ</code> – der Typ steht in UML <em>hinter</em> dem Namen, nicht davor wie in Java.</li>
<li><strong>Methode:</strong> erkennbar an den runden Klammern hinter dem Namen, z. B. <code>berechneSumme()</code>.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Minus heißt privat, Raute heißt protected – nie verwechseln.</p>
</section>
<section>
<h2>Beziehungen &amp; Multiplizitäten</h2>
<p>Linien zwischen Klassen zeigen, wie Objekte zusammenhängen; die Multiplizität sagt, wie viele Objekte je Ende beteiligt sind.</p>
<ul class="key-list">
<li><strong>Aggregation:</strong> schwache „hat"-Beziehung, <em>leere</em> Raute am Ganzen – die Teile bestehen auch allein.</li>
<li><strong>Komposition:</strong> starke Existenzabhängigkeit, <em>gefüllte</em> Raute am Ganzen – ohne das Ganze verschwinden die Teile.</li>
<li><strong>Vererbung:</strong> durchgezogene Linie mit hohlem Dreieckspfeil zur Oberklasse. <strong>Multiplizität:</strong> <code>1</code> genau eins, <code>0..1</code> optional, <code>1..*</code> mindestens eins.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Gefüllte Raute = Komposition (existenzabhängig), leere Raute = Aggregation (lose „hat").</p>
</section>
<section>
<h2>Sequenzdiagramm</h2>
<p>Das Sequenzdiagramm zeigt den zeitlichen Nachrichtenaustausch zwischen Objekten – die Zeit läuft von oben nach unten.</p>
<ul class="key-list">
<li><strong>Lebenslinie:</strong> gestrichelte Senkrechte unter dem Objekt, zeigt dessen Existenz über die Zeit.</li>
<li><strong>Aktivierungsbalken:</strong> schmales Rechteck auf der Lebenslinie – das Objekt führt gerade eine Operation aus.</li>
<li><strong>Nachrichten:</strong> synchron = durchgezogene Linie mit gefüllter Spitze (Sender wartet); asynchron = offene Spitze (Sender läuft weiter); Antwort = gestrichelt.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Gefüllte Pfeilspitze = synchron und warten, offene Spitze = asynchron und weiterlaufen.</p>
</section>
<section>
<h2>Aktivitäts- &amp; Use-Case-Diagramm</h2>
<p>Das Aktivitätsdiagramm modelliert Abläufe, das Use-Case-Diagramm die Anforderungen aus Sicht der Akteure.</p>
<ul class="key-list">
<li><strong>Aktivität:</strong> Start = gefüllter Kreis, Ende = Kreis mit Ring, Aktion = abgerundetes Rechteck, Entscheidung = Raute, Parallelität = fork/join-Balken.</li>
<li><strong>Use Case:</strong> Akteur = Strichmännchen außerhalb der Systemgrenze (Rahmen), Use Case = Ellipse innerhalb.</li>
<li><strong>include vs. extend:</strong> <code>&lt;&lt;include&gt;&gt;</code> bindet immer verpflichtend ein, <code>&lt;&lt;extend&gt;&gt;</code> ergänzt nur unter einer Bedingung (optional).</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Raute = Entscheidung (ein Zweig), Balken = Parallelität (mehrere Zweige gleichzeitig).</p>
</section>
<section>
<h2>Prüfungsmodus</h2>
<p>Dieser ProtocolCheck führt dich durch die wichtigsten AP2-Aspekte dieses Themas. Du kannst Antworten prüfen, Fragen überspringen und bekommst am Ende eine Auswertung nach Kategorie.</p>
</section>
<section class="finalflux-test" data-finalflux-test aria-live="polite">
<div class="test-meta">
<span data-question-counter>Frage 1</span>
<span data-score-counter>0 richtig</span>
</div>
<div class="category-block">
<p class="eyebrow">Kategorie</p>
<h2 data-category-title>UML</h2>
<p data-category-hint>AP2-Training</p>
</div>
<div class="question-card">
<h3 data-question-text></h3>
<div data-answer-options class="answer-options"></div>
<div data-answer-feedback class="fluxcheck-result"></div>
</div>
<div class="test-actions">
<button type="button" data-check-answer>Antwort prüfen</button>
<button type="button" data-skip-question class="secondary">Überspringen</button>
<button type="button" data-next-question class="secondary" disabled>Weiter</button>
</div>
</section>
<section data-test-result class="finalflux-panel" hidden>
<h2>Auswertung</h2>
<p data-result-summary></p>
<ul data-category-summary class="key-list"></ul>
<div class="finalflux-actions">
<button type="button" data-restart-test>Test neu starten</button>
<a href="/finalflux">Zurück zur Übersicht</a>
</div>
</section>
</main>
<script src="/js/finalflux-test.js" data-questions-src="/finalflux/questions/ap2_fiae_uml.json" defer></script>
</body>
</html>
@@ -0,0 +1,112 @@
<!DOCTYPE html>
<html lang="de" data-theme="dark">
<head>
<meta charset="UTF-8">
<title>IT-Sicherheit - FinalProtocol AP2</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/theme.css?v=3">
<link rel="stylesheet" href="/css/finalflux.css">
<script src="/js/theme.js?v=3"></script>
</head>
<body class="finalflux-page">
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<main>
<a href="/finalflux" class="back-link">Zurück zu FinalProtocol</a>
<h1>IT-Sicherheit</h1>
<section>
<h2>Lernfokus</h2>
<p>AP2 Systemintegration: Netzgrenzen mit Firewall und DMZ absichern, VPN- und Verschlüsselungsverfahren richtig auswählen sowie Zertifikate, Schutzziele und Authentisierung sauber begründen.</p>
<ul class="key-list">
<li>Firewall-Typen und DMZ-Konzepte unterscheiden und nach Default-Deny planen.</li>
<li>VPN-Modi sowie symmetrische, asymmetrische und hybride Verschlüsselung einordnen.</li>
<li>PKI, digitale Signatur, CIA-Triade und Mehr-Faktor-Authentisierung erklären.</li>
</ul>
</section>
<section>
<h2>Firewall &amp; DMZ</h2>
<p>Firewalls trennen Netze unterschiedlicher Vertrauensstufe. Eine DMZ (entmilitarisierte Zone) ist ein Zwischennetz für öffentlich erreichbare Dienste, das weder ganz außen noch im internen LAN liegt.</p>
<ul class="key-list">
<li><strong>Paketfilter vs. Stateful Inspection:</strong> der zustandslose Filter prüft jedes Paket einzeln, die Stateful-Firewall verfolgt den Verbindungszustand und lässt Antwortpakete gezielt zu.</li>
<li><strong>DMZ:</strong> öffentlich erreichbare Server (Web, Mail) werden isoliert, damit ein Einbruch dort nicht sofort das interne Netz öffnet.</li>
<li><strong>Screened Subnet:</strong> äußere und innere Firewall spannen die DMZ dazwischen auf – ein Angreifer muss beide überwinden.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Ein gutes Regelwerk arbeitet nach Default-Deny: alles verbieten und nur den ausdrücklich benötigten Verkehr freigeben.</p>
</section>
<section>
<h2>VPN &amp; Verschlüsselung</h2>
<p>Ein VPN baut über ein unsicheres Netz einen geschützten Tunnel auf. Die dahinterliegenden Verfahren kombinieren meist Geschwindigkeit und sicheren Schlüsselaustausch.</p>
<ul class="key-list">
<li><strong>IPsec:</strong> ESP verschlüsselt die Nutzdaten (Vertraulichkeit), AH sichert nur Integrität/Authentizität, IKE handelt die Schlüssel aus.</li>
<li><strong>Tunnel- vs. Transportmodus:</strong> der Tunnelmodus kapselt das ganze Original-Paket (Site-to-Site), der Transportmodus schützt nur die Nutzlast (Host-to-Host).</li>
<li><strong>Hybridverfahren:</strong> das asymmetrische Verfahren tauscht sicher den Sitzungsschlüssel aus, das schnelle symmetrische Verfahren (z. B. AES) verschlüsselt die Massendaten.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Vertraulichkeit heißt mit dem öffentlichen Schlüssel des Empfängers verschlüsseln – nur dessen privater Schlüssel öffnet die Nachricht.</p>
</section>
<section>
<h2>Zertifikate &amp; PKI</h2>
<p>Eine Public-Key-Infrastruktur schafft Vertrauen in öffentliche Schlüssel. Digitale Signaturen belegen Echtheit und Urheberschaft.</p>
<ul class="key-list">
<li><strong>CA &amp; Vertrauenskette:</strong> die Zertifizierungsstelle signiert Zertifikate; das Vertrauen reicht über Zwischenzertifikate bis zu einer im System hinterlegten Root-CA.</li>
<li><strong>Digitale Signatur:</strong> der Absender signiert mit seinem privaten Schlüssel, jeder prüft mit dem öffentlichen – das sichert Integrität und Nichtabstreitbarkeit.</li>
<li><strong>Widerruf:</strong> zurückgezogene Zertifikate erkennt man über eine Sperrliste (CRL) oder eine OCSP-Abfrage, nicht am Ablaufdatum.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Signieren mit dem privaten Schlüssel, verschlüsseln mit dem öffentlichen Schlüssel des Empfängers – Signatur und Vertraulichkeit nie verwechseln.</p>
</section>
<section>
<h2>Schutzziele &amp; Authentisierung</h2>
<p>Die CIA-Triade bündelt die drei zentralen Schutzziele der Informationssicherheit. Authentisierung und Autorisierung sind zwei getrennte Schritte der Zugriffskontrolle.</p>
<ul class="key-list">
<li><strong>CIA-Triade:</strong> Vertraulichkeit (kein unbefugtes Lesen), Integrität (keine unbemerkte Veränderung), Verfügbarkeit (erreichbar bei Bedarf).</li>
<li><strong>2FA/MFA:</strong> echte Mehr-Faktor-Authentisierung kombiniert verschiedene Faktorarten – Wissen, Besitz und Inhärenz (Biometrie).</li>
<li><strong>Authentisierung vs. Autorisierung:</strong> zuerst wird die Identität nachgewiesen, danach werden die Zugriffsrechte festgelegt.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Ein zweiter Faktor zählt nur, wenn er aus einer anderen Kategorie stammt – zwei Passwörter bleiben ein einziger Faktor Wissen.</p>
</section>
<section>
<h2>Prüfungsmodus</h2>
<p>Dieser ProtocolCheck führt dich durch die wichtigsten AP2-Aspekte dieses Themas. Du kannst Antworten prüfen, Fragen überspringen und bekommst am Ende eine Auswertung nach Kategorie.</p>
</section>
<section class="finalflux-test" data-finalflux-test aria-live="polite">
<div class="test-meta">
<span data-question-counter>Frage 1</span>
<span data-score-counter>0 richtig</span>
</div>
<div class="category-block">
<p class="eyebrow">Kategorie</p>
<h2 data-category-title>IT-Sicherheit</h2>
<p data-category-hint>AP2-Training</p>
</div>
<div class="question-card">
<h3 data-question-text></h3>
<div data-answer-options class="answer-options"></div>
<div data-answer-feedback class="fluxcheck-result"></div>
</div>
<div class="test-actions">
<button type="button" data-check-answer>Antwort prüfen</button>
<button type="button" data-skip-question class="secondary">Überspringen</button>
<button type="button" data-next-question class="secondary" disabled>Weiter</button>
</div>
</section>
<section data-test-result class="finalflux-panel" hidden>
<h2>Auswertung</h2>
<p data-result-summary></p>
<ul data-category-summary class="key-list"></ul>
<div class="finalflux-actions">
<button type="button" data-restart-test>Test neu starten</button>
<a href="/finalflux">Zurück zur Übersicht</a>
</div>
</section>
</main>
<script src="/js/finalflux-test.js" data-questions-src="/finalflux/questions/ap2_fisi_it-sicherheit.json" defer></script>
</body>
</html>
@@ -0,0 +1,114 @@
<!DOCTYPE html>
<html lang="de" data-theme="dark">
<head>
<meta charset="UTF-8">
<title>Monitoring &amp; Backup - FinalProtocol AP2</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/theme.css?v=3">
<link rel="stylesheet" href="/css/finalflux.css">
<script src="/js/theme.js?v=3"></script>
</head>
<body class="finalflux-page">
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<main>
<a href="/finalflux" class="back-link">Zurück zu FinalProtocol</a>
<h1>Monitoring &amp; Backup</h1>
<section>
<h2>Lernfokus</h2>
<p>AP2 Systemintegration: Systeme sinnvoll überwachen, Backup-Strategien auswählen und die Wiederherstellung samt Serverkapazität belastbar planen.</p>
<ul class="key-list">
<li>Monitoring mit SNMP, Schwellwerten und Alarmen ohne Fehlalarm-Flut aufbauen.</li>
<li>Backup-Arten und -Strategien (3-2-1, Voll/Inkrementell/Differenziell, Generationenprinzip) sicher unterscheiden.</li>
<li>Wiederherstellung über RTO/RPO und Restore-Tests bewerten und Server bedarfsgerecht dimensionieren.</li>
</ul>
</section>
<section>
<h2>Monitoring &amp; SNMP</h2>
<p>Monitoring überwacht Systeme fortlaufend und meldet Abweichungen, bevor daraus ein Ausfall wird. SNMP ist dafür das klassische Protokoll im Netzwerk.</p>
<ul class="key-list">
<li><strong>Rollen:</strong> der Agent läuft auf dem überwachten Gerät und hält seine Werte in der MIB bereit, der Manager (NMS) fragt sie ab und stellt sie dar.</li>
<li><strong>Polling vs. Trap:</strong> beim Polling fragt der Manager zyklisch ab, beim Trap meldet der Agent ein Ereignis von sich aus - das verkürzt die Reaktionszeit.</li>
<li><strong>Schwellwerte:</strong> abgestuft in Warning (frühe Warnung) und Critical (Notfall); eine Mindestdauer vermeidet Fehlalarme durch kurze Lastspitzen.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Der Agent hält die Daten, der Manager holt sie - und ein guter Schwellwert warnt früh genug, ohne bei jeder Spitze Alarm zu schlagen.</p>
</section>
<section>
<h2>Backup-Arten &amp; -Strategie</h2>
<p>Die Wahl der Backup-Art entscheidet über Sicherungsdauer, Speicherbedarf und den Aufwand beim Restore. Die 3-2-1-Regel gibt den strategischen Rahmen.</p>
<ul class="key-list">
<li><strong>3-2-1-Regel:</strong> drei Datenkopien, auf zwei verschiedenen Medientypen, davon eine an einem externen Standort (offsite).</li>
<li><strong>Vollbackup:</strong> sichert jedes Mal den gesamten Datenbestand - einfachster Restore, höchster Speicher- und Zeitbedarf.</li>
<li><strong>Inkrementell:</strong> sichert nur die Änderungen seit dem <em>letzten Backup</em> (egal welcher Art) - kleine Sicherungen, aber lange Restore-Kette.</li>
<li><strong>Differenziell:</strong> sichert alle Änderungen seit dem <em>letzten Vollbackup</em> - wachsende Sicherungen, aber Restore aus Vollbackup plus einer Sicherung.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Inkrementell misst ab dem letzten Backup, differenziell immer ab dem letzten Vollbackup - genau das entscheidet, wie viele Sicherungen du beim Restore brauchst.</p>
</section>
<section>
<h2>Generationenprinzip</h2>
<p>Das Großvater-Vater-Sohn-Prinzip staffelt Sicherungen zeitlich, damit man auch auf ältere Datenstände zurückgreifen kann.</p>
<ul class="key-list">
<li><strong>Sohn:</strong> tägliche Sicherung, wird schnell wieder überschrieben (jüngster Stand).</li>
<li><strong>Vater:</strong> wöchentliche Sicherung mit mittlerer Aufbewahrung.</li>
<li><strong>Großvater:</strong> monatliche Sicherung, wird am längsten aufbewahrt (Langzeitstand).</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Je höher die Generation, desto länger die Aufbewahrung - so bleibt auch ein spät entdeckter Fehler (z. B. Ransomware) reparierbar.</p>
</section>
<section>
<h2>Wiederherstellung &amp; Serverdimensionierung</h2>
<p>Ein Backup ist nur so gut wie sein Restore. RTO und RPO geben die Ziele vor, die Serverdimensionierung liefert die nötige Kapazität und Redundanz.</p>
<ul class="key-list">
<li><strong>RTO:</strong> maximal tolerierbare Zeit bis zur Wiederverfügbarkeit - wie lange darf der Ausfall dauern?</li>
<li><strong>RPO:</strong> maximal tolerierbarer Datenverlust - er bestimmt das Sicherungsintervall (RPO 1 h → mindestens stündlich sichern).</li>
<li><strong>Restore-Test:</strong> nur ein zurückgespieltes Backup beweist, dass Medien lesbar und Daten brauchbar sind - ein grünes Protokoll allein genügt nicht.</li>
<li><strong>Dimensionierung:</strong> Kapazitätsreserven für Wachstum einplanen, Redundanz über RAID und N+1 (eine Einheit mehr als nötig); IOPS zählen bei Datenbanken.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> RTO fragt nach der Zeit, RPO nach der Datenmenge - und RAID ist Redundanz für den laufenden Betrieb, aber niemals ein Ersatz für ein Backup.</p>
</section>
<section>
<h2>Prüfungsmodus</h2>
<p>Dieser ProtocolCheck führt dich durch die wichtigsten AP2-Aspekte dieses Themas. Du kannst Antworten prüfen, Fragen überspringen und bekommst am Ende eine Auswertung nach Kategorie.</p>
</section>
<section class="finalflux-test" data-finalflux-test aria-live="polite">
<div class="test-meta">
<span data-question-counter>Frage 1</span>
<span data-score-counter>0 richtig</span>
</div>
<div class="category-block">
<p class="eyebrow">Kategorie</p>
<h2 data-category-title>Monitoring &amp; Backup</h2>
<p data-category-hint>AP2-Training</p>
</div>
<div class="question-card">
<h3 data-question-text></h3>
<div data-answer-options class="answer-options"></div>
<div data-answer-feedback class="fluxcheck-result"></div>
</div>
<div class="test-actions">
<button type="button" data-check-answer>Antwort prüfen</button>
<button type="button" data-skip-question class="secondary">Überspringen</button>
<button type="button" data-next-question class="secondary" disabled>Weiter</button>
</div>
</section>
<section data-test-result class="finalflux-panel" hidden>
<h2>Auswertung</h2>
<p data-result-summary></p>
<ul data-category-summary class="key-list"></ul>
<div class="finalflux-actions">
<button type="button" data-restart-test>Test neu starten</button>
<a href="/finalflux">Zurück zur Übersicht</a>
</div>
</section>
</main>
<script src="/js/finalflux-test.js" data-questions-src="/finalflux/questions/ap2_fisi_monitoring-backup.json" defer></script>
</body>
</html>
@@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="de" data-theme="dark">
<head>
<meta charset="UTF-8">
<title>Netzwerkplanung - FinalProtocol AP2</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/theme.css?v=3">
<link rel="stylesheet" href="/css/finalflux.css">
<script src="/js/theme.js?v=3"></script>
</head>
<body class="finalflux-page">
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<main>
<a href="/finalflux" class="back-link">Zurück zu FinalProtocol</a>
<h1>Netzwerkplanung</h1>
<section>
<h2>Lernfokus</h2>
<p>AP2 Systemintegration: Adressräume berechnen, IPv6 lesen, WLAN sauber auslegen und Routing-Entscheidungen begründen.</p>
<ul class="key-list">
<li>Subnetze per VLSM bedarfsgerecht und sparsam dimensionieren.</li>
<li>IPv6-Adressen kürzen sowie Adresstypen und Präfixe einordnen.</li>
<li>WLAN-Kanäle und Sicherheitsverfahren planen, Routing-Wege nachvollziehen.</li>
</ul>
</section>
<section>
<h2>Subnetting &amp; VLSM</h2>
<p>Beim Subnetting teilst du einen Adressraum in kleinere Netze. VLSM (Variable Length Subnet Mask) erlaubt unterschiedlich große Subnetze im selben Netz – so verschwendest du keine Adressen.</p>
<ul class="key-list">
<li><strong>Host-Formel:</strong> nutzbare Hosts = 2^(Host-Bits) − 2 (Netz- und Broadcast-Adresse abgezogen).</li>
<li><strong>Blockgröße:</strong> 256 − Maskenwert des letzten Oktetts; sie legt die Netzgrenzen fest (z. B. /26 → Blöcke à 64).</li>
<li><strong>VLSM-Reihenfolge:</strong> größte Netze zuerst vergeben, damit der Restraum lückenlos für kleinere Netze reicht.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Erst den Bedarf (Hosts) bestimmen, daraus die Host-Bits, daraus die Maske – nie umgekehrt raten.</p>
</section>
<section>
<h2>IPv6-Grundlagen</h2>
<p>IPv6 nutzt 128 Bit und eine hexadezimale Schreibweise. Kürzungsregeln und Adresstypen werden in der AP2 gern abgefragt.</p>
<ul class="key-list">
<li><strong>Kürzen:</strong> führende Nullen je Gruppe streichen, eine zusammenhängende Nullfolge einmal durch <code>::</code> ersetzen (nur einmal erlaubt).</li>
<li><strong>Adresstypen:</strong> Global Unicast (2000::/3), Link-Local (fe80::/10, nur lokal), Multicast (ff00::/8) – Broadcast entfällt.</li>
<li><strong>Präfixe:</strong> /64 pro Segment (SLAAC), /48 typische Standort-Zuteilung, /128 einzelne Host-Adresse.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Das <code>::</code> darf pro Adresse nur einmal vorkommen, sonst ist die Anzahl der Nullgruppen nicht mehr eindeutig.</p>
</section>
<section>
<h2>WLAN-Planung</h2>
<p>Funknetze brauchen eine überlappungsfreie Kanalvergabe und ein zeitgemäßes Sicherheitsverfahren.</p>
<ul class="key-list">
<li><strong>2,4 GHz:</strong> nur die Kanäle 1, 6 und 11 überlappen sich nicht – ideal für benachbarte Access Points.</li>
<li><strong>5 GHz:</strong> mehr überlappungsfreie Kanäle und weniger Störungen, dafür geringere Reichweite und Wanddurchdringung.</li>
<li><strong>Sicherheit:</strong> WPA3-Enterprise mit RADIUS (802.1X) authentisiert jeden Nutzer einzeln; WEP und offene Netze meiden.</li>
</ul>
</section>
<section>
<h2>Routing</h2>
<p>Router entscheiden anhand ihrer Routing-Tabelle, wohin ein Paket geht.</p>
<ul class="key-list">
<li><strong>Longest-Prefix-Match:</strong> die spezifischste passende Route (längstes Präfix) gewinnt – unabhängig von der Reihenfolge.</li>
<li><strong>Statisch vs. dynamisch:</strong> manuell eingetragen gegenüber selbstlernend über OSPF, RIP oder BGP.</li>
<li><strong>Default-Route 0.0.0.0/0:</strong> Auffangbecken für alle Ziele ohne spezifischere Route (meist zum Gateway).</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> OSPF ist das Link-State-IGP im eigenen Netz, BGP das Protokoll zwischen autonomen Systemen im Internet.</p>
</section>
<section>
<h2>Prüfungsmodus</h2>
<p>Dieser ProtocolCheck führt dich durch die wichtigsten AP2-Aspekte dieses Themas. Du kannst Antworten prüfen, Fragen überspringen und bekommst am Ende eine Auswertung nach Kategorie.</p>
</section>
<section class="finalflux-test" data-finalflux-test aria-live="polite">
<div class="test-meta">
<span data-question-counter>Frage 1</span>
<span data-score-counter>0 richtig</span>
</div>
<div class="category-block">
<p class="eyebrow">Kategorie</p>
<h2 data-category-title>Netzwerkplanung</h2>
<p data-category-hint>AP2-Training</p>
</div>
<div class="question-card">
<h3 data-question-text></h3>
<div data-answer-options class="answer-options"></div>
<div data-answer-feedback class="fluxcheck-result"></div>
</div>
<div class="test-actions">
<button type="button" data-check-answer>Antwort prüfen</button>
<button type="button" data-skip-question class="secondary">Überspringen</button>
<button type="button" data-next-question class="secondary" disabled>Weiter</button>
</div>
</section>
<section data-test-result class="finalflux-panel" hidden>
<h2>Auswertung</h2>
<p data-result-summary></p>
<ul data-category-summary class="key-list"></ul>
<div class="finalflux-actions">
<button type="button" data-restart-test>Test neu starten</button>
<a href="/finalflux">Zurück zur Übersicht</a>
</div>
</section>
</main>
<script src="/js/finalflux-test.js" data-questions-src="/finalflux/questions/ap2_fisi_netzwerkplanung.json" defer></script>
</body>
</html>
@@ -0,0 +1,113 @@
<!DOCTYPE html>
<html lang="de" data-theme="dark">
<head>
<meta charset="UTF-8">
<title>Skripting - FinalProtocol AP2</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/theme.css?v=3">
<link rel="stylesheet" href="/css/finalflux.css">
<script src="/js/theme.js?v=3"></script>
</head>
<body class="finalflux-page">
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<main>
<a href="/finalflux" class="back-link">Zurück zu FinalProtocol</a>
<h1>Skripting</h1>
<section>
<h2>Lernfokus</h2>
<p>AP2 Systemintegration: Aufgaben in Bash und PowerShell automatisieren, Kontrollstrukturen sauber entwerfen und Skripte über Exit-Codes zuverlässig überwachen.</p>
<ul class="key-list">
<li>Bash-Grundlagen beherrschen: Variablen, Pipes und Umleitungen zielsicher einsetzen.</li>
<li>PowerShell verstehen: Cmdlets, Objekte und die objektbasierte Pipeline nutzen.</li>
<li>Abläufe automatisieren und über Exit-Codes, <code>$?</code> und Fehlerströme absichern.</li>
</ul>
</section>
<section>
<h2>Shell-Grundlagen (Bash)</h2>
<p>In der Bash steuerst du Programme über die Kommandozeile. Variablen, Pipes und Umleitungen sind die Bausteine jedes Skripts.</p>
<ul class="key-list">
<li><strong>Variablen:</strong> Zuweisung ohne Leerzeichen wie <code>NAME="wert"</code>, Auslesen mit Dollarzeichen als <code>$NAME</code>.</li>
<li><strong>Pipes:</strong> <code>|</code> reicht die Standardausgabe eines Kommandos als Standardeingabe an das nächste weiter (z. B. <code>ls -l | grep txt</code>).</li>
<li><strong>Umleitungen:</strong> <code>&gt;</code> überschreibt eine Datei, <code>&gt;&gt;</code> hängt an, <code>&lt;</code> liest eine Datei als Eingabe ein.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Ein einfaches <code>&gt;</code> überschreibt, der doppelte Pfeil <code>&gt;&gt;</code> hängt an – erst prüfen, dann umleiten.</p>
</section>
<section>
<h2>PowerShell</h2>
<p>PowerShell arbeitet objektorientiert: Cmdlets liefern keine reinen Textzeilen, sondern strukturierte Objekte mit Eigenschaften.</p>
<ul class="key-list">
<li><strong>Cmdlets:</strong> folgen dem Schema Verb-Nomen, etwa <code>Get-Service</code> oder <code>Stop-Process</code>.</li>
<li><strong>Objekt-Pipeline:</strong> zwischen den Cmdlets fließen ganze .NET-Objekte, sodass Folge-Cmdlets gezielt auf Felder zugreifen.</li>
<li><strong>Verarbeitung:</strong> <code>Where-Object</code> filtert nach Bedingung, <code>Select-Object</code> wählt Eigenschaften, <code>Sort-Object</code> sortiert.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Bash schiebt Text durch die Pipeline, PowerShell schiebt Objekte – deshalb kannst du in PowerShell direkt nach Eigenschaften filtern.</p>
</section>
<section>
<h2>Kontrollstrukturen &amp; Pseudocode</h2>
<p>Kontrollstrukturen steuern den Ablauf: Verzweigungen entscheiden, Schleifen wiederholen. Im Pseudocode planst du das sprachunabhängig.</p>
<ul class="key-list">
<li><strong>Verzweigung:</strong> <code>if</code>-<code>elseif</code>-<code>else</code> (oder <code>switch</code>) führt je nach Bedingung genau einen Zweig aus.</li>
<li><strong>Zählschleife:</strong> <code>for</code> nutzt du, wenn die Anzahl der Durchläufe von vornherein feststeht.</li>
<li><strong>Bedingte Schleife:</strong> die kopfgesteuerte <code>while</code> prüft vor jedem Durchlauf; die fußgesteuerte <code>do-while</code> läuft mindestens einmal.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Feste Anzahl bekannt? Nimm <code>for</code>. Nur eine Abbruchbedingung bekannt? Nimm <code>while</code>.</p>
</section>
<section>
<h2>Automatisierung, Exit-Codes &amp; Fehlerbehandlung</h2>
<p>Skripte laufen oft ohne Aufsicht. Zeitplaner starten sie, und Rückgabewerte verraten, ob sie erfolgreich waren.</p>
<ul class="key-list">
<li><strong>Cron (Linux):</strong> fünf Felder in der Reihenfolge Minute, Stunde, Tag des Monats, Monat, Wochentag; <code>30 2 * * *</code> läuft täglich um 02:30 Uhr, <code>*/15 * * * *</code> alle 15 Minuten.</li>
<li><strong>Aufgabenplanung (Windows):</strong> der Taskplaner bzw. <code>schtasks</code> startet Aufgaben zeitgesteuert, auch ohne angemeldeten Benutzer.</li>
<li><strong>Exit-Codes:</strong> <code>0</code> bedeutet Erfolg, jeder Wert ungleich 0 einen Fehler; in Bash liest <code>$?</code> den letzten Rückgabewert aus.</li>
<li><strong>Fehlerströme:</strong> <code>2&gt;</code> leitet die Standardfehlerausgabe (stderr, Deskriptor 2) um; in PowerShell fängt ein <code>try-catch</code>-Block Laufzeitfehler ab.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Exit-Code 0 heißt „alles gut", alles andere heißt „prüfen" – und stderr (Deskriptor 2) ist getrennt von stdout (Deskriptor 1).</p>
</section>
<section>
<h2>Prüfungsmodus</h2>
<p>Dieser ProtocolCheck führt dich durch die wichtigsten AP2-Aspekte dieses Themas. Du kannst Antworten prüfen, Fragen überspringen und bekommst am Ende eine Auswertung nach Kategorie.</p>
</section>
<section class="finalflux-test" data-finalflux-test aria-live="polite">
<div class="test-meta">
<span data-question-counter>Frage 1</span>
<span data-score-counter>0 richtig</span>
</div>
<div class="category-block">
<p class="eyebrow">Kategorie</p>
<h2 data-category-title>Skripting</h2>
<p data-category-hint>AP2-Training</p>
</div>
<div class="question-card">
<h3 data-question-text></h3>
<div data-answer-options class="answer-options"></div>
<div data-answer-feedback class="fluxcheck-result"></div>
</div>
<div class="test-actions">
<button type="button" data-check-answer>Antwort prüfen</button>
<button type="button" data-skip-question class="secondary">Überspringen</button>
<button type="button" data-next-question class="secondary" disabled>Weiter</button>
</div>
</section>
<section data-test-result class="finalflux-panel" hidden>
<h2>Auswertung</h2>
<p data-result-summary></p>
<ul data-category-summary class="key-list"></ul>
<div class="finalflux-actions">
<button type="button" data-restart-test>Test neu starten</button>
<a href="/finalflux">Zurück zur Übersicht</a>
</div>
</section>
</main>
<script src="/js/finalflux-test.js" data-questions-src="/finalflux/questions/ap2_fisi_skripting.json" defer></script>
</body>
</html>
@@ -0,0 +1,101 @@
<!DOCTYPE html>
<html lang="de" data-theme="dark">
<head>
<meta charset="UTF-8">
<title>Virtualisierung - FinalProtocol AP2</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/theme.css?v=3">
<link rel="stylesheet" href="/css/finalflux.css">
<script src="/js/theme.js?v=3"></script>
</head>
<body class="finalflux-page">
<div class="mf-theme-float"><button class="mf-theme"></button></div>
<main>
<a href="/finalflux" class="back-link">Zurück zu FinalProtocol</a>
<h1>Virtualisierung</h1>
<section>
<h2>Lernfokus</h2>
<p>AP2 Systemintegration: Hypervisor-Typen unterscheiden, Container gegen VMs abgrenzen, Snapshots und Cloud-Modelle sicher einordnen sowie Speicher und Ressourcen bewusst planen.</p>
<ul class="key-list">
<li>Typ-1- und Typ-2-Hypervisoren sowie Container und VMs nach Aufbau und Isolation unterscheiden.</li>
<li>Snapshots, Klone und die Grenzen zum Backup sauber einordnen.</li>
<li>Cloud-Servicemodelle mit Verantwortungsteilung sowie Provisioning, Overcommitment und Live-Migration begründen.</li>
</ul>
</section>
<section>
<h2>Hypervisoren &amp; Container</h2>
<p>Virtualisierung entkoppelt Betriebssysteme von der physischen Hardware. Hypervisoren betreiben vollständige VMs, Container teilen sich hingegen den Kernel des Hosts.</p>
<ul class="key-list">
<li><strong>Typ-1 (Bare-Metal):</strong> läuft direkt auf der Hardware (z. B. ESXi, Hyper-V) – geringer Overhead, Standard im Rechenzentrum.</li>
<li><strong>Typ-2 (Hosted):</strong> setzt als Anwendung auf einem Host-Betriebssystem auf (z. B. VirtualBox) – praktisch für Arbeitsplätze und Tests.</li>
<li><strong>Container:</strong> nutzen den Host-Kernel gemeinsam, starten schnell und sparen Ressourcen; ein Image ist die unveränderliche Vorlage, der Container die laufende Instanz.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Jede VM bringt ein eigenes Betriebssystem mit und ist durch den Hypervisor stark isoliert; Container teilen den Kernel und sind dafür leichtgewichtiger.</p>
</section>
<section>
<h2>Snapshots &amp; Klone</h2>
<p>Snapshots und Klone helfen beim Testen und Vervielfältigen von VMs – ersetzen aber keine Datensicherung.</p>
<ul class="key-list">
<li><strong>Snapshot:</strong> festgehaltener Zustand zu einem Zeitpunkt; Rückkehr möglich, liegt aber meist als Delta auf demselben Storage.</li>
<li><strong>Linked Clone:</strong> teilt die Basisplatten mit dem Original, spart Speicher, bleibt aber davon abhängig; ein Full Clone ist eigenständig und größer.</li>
<li><strong>Langlebige Snapshots:</strong> wachsende Delta-Dateien belegen Speicher und mindern die Leistung – deshalb nur kurz halten.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Ein Snapshot ist kein Backup – fällt der Speicher aus, ist auch der Snapshot verloren.</p>
</section>
<section>
<h2>Cloud-Modelle &amp; Ressourcen</h2>
<p>Cloud-Servicemodelle regeln, wie viel Betrieb der Anbieter übernimmt. Bei Speicher und Ressourcen entscheidet die Planung über Kosten und Stabilität.</p>
<ul class="key-list">
<li><strong>IaaS/PaaS/SaaS:</strong> von virtueller Infrastruktur über die Plattform bis zur fertigen Anwendung – je höher das Modell, desto mehr übernimmt der Anbieter.</li>
<li><strong>Shared Responsibility:</strong> die Verantwortung für eigene Daten und Zugriffsrechte bleibt in jedem Modell beim Kunden.</li>
<li><strong>Provisioning &amp; Overcommitment:</strong> Thin belegt Speicher erst bei Bedarf, Thick sofort; Überbuchung spart Ressourcen, riskiert aber Engpässe bei Spitzenlast.</li>
</ul>
<p class="merksatz"><strong>Merksatz:</strong> Eine Live-Migration verschiebt eine laufende VM ohne Downtime – setzt aber üblicherweise gemeinsamen Speicher und kompatible CPUs voraus.</p>
</section>
<section>
<h2>Prüfungsmodus</h2>
<p>Dieser ProtocolCheck führt dich durch die wichtigsten AP2-Aspekte dieses Themas. Du kannst Antworten prüfen, Fragen überspringen und bekommst am Ende eine Auswertung nach Kategorie.</p>
</section>
<section class="finalflux-test" data-finalflux-test aria-live="polite">
<div class="test-meta">
<span data-question-counter>Frage 1</span>
<span data-score-counter>0 richtig</span>
</div>
<div class="category-block">
<p class="eyebrow">Kategorie</p>
<h2 data-category-title>Virtualisierung</h2>
<p data-category-hint>AP2-Training</p>
</div>
<div class="question-card">
<h3 data-question-text></h3>
<div data-answer-options class="answer-options"></div>
<div data-answer-feedback class="fluxcheck-result"></div>
</div>
<div class="test-actions">
<button type="button" data-check-answer>Antwort prüfen</button>
<button type="button" data-skip-question class="secondary">Überspringen</button>
<button type="button" data-next-question class="secondary" disabled>Weiter</button>
</div>
</section>
<section data-test-result class="finalflux-panel" hidden>
<h2>Auswertung</h2>
<p data-result-summary></p>
<ul data-category-summary class="key-list"></ul>
<div class="finalflux-actions">
<button type="button" data-restart-test>Test neu starten</button>
<a href="/finalflux">Zurück zur Übersicht</a>
</div>
</section>
</main>
<script src="/js/finalflux-test.js" data-questions-src="/finalflux/questions/ap2_fisi_virtualisierung.json" defer></script>
</body>
</html>
@@ -0,0 +1,245 @@
{
"title": "Algorithmen",
"questions": [
{
"category": "Struktogramm & Pseudocode",
"hint": "Geschachtelte Blöcke ohne Sprünge.",
"text": "Was stellt ein Struktogramm (Nassi-Shneiderman-Diagramm) dar?",
"answers": [
"Den strukturierten Ablauf eines Algorithmus aus ineinander geschachtelten Blöcken ohne Sprünge.",
"Die Beziehungen zwischen Datenbanktabellen.",
"Den zeitlichen Ablauf von Nachrichten zwischen Objekten."
],
"correct": 0,
"explanation": "Ein Struktogramm nach Nassi-Shneiderman beschreibt den Kontrollfluss eines Algorithmus als lückenlos geschachtelte Blöcke; GOTO-Sprünge lassen sich damit gar nicht abbilden. Tabellenbeziehungen zeigt ein ER-Diagramm, den Nachrichtenaustausch von Objekten ein Sequenzdiagramm."
},
{
"category": "Struktogramm & Pseudocode",
"hint": "Bedingungskopf mit zwei Zweigen.",
"text": "Wie wird eine zweiseitige Verzweigung (if-else) im Struktogramm dargestellt?",
"answers": [
"Als schlichtes Rechteck, das nur von oben nach unten durchlaufen wird.",
"Als dreieckiger Bedingungskopf, unter dem sich der Ja- und der Nein-Zweig nebeneinander aufteilen.",
"Als umschließender Schleifenrahmen um den Innenblock."
],
"correct": 1,
"explanation": "Die Verzweigung wird als dreieckiger Bedingungskopf gezeichnet, unter dem sich der Weg in einen Ja- und einen Nein-Zweig nebeneinander teilt. Ein reines Rechteck steht für eine Sequenz, der umschließende Rahmen für eine Schleife."
},
{
"category": "Struktogramm & Pseudocode",
"hint": "Wann wird die Bedingung geprüft?",
"text": "Worin unterscheidet sich eine kopfgesteuerte (while) von einer fußgesteuerten (do-while) Schleife?",
"answers": [
"Die kopfgesteuerte Schleife läuft immer genau einmal mehr als die fußgesteuerte.",
"Beide prüfen die Bedingung grundsätzlich erst nach dem ersten Durchlauf.",
"Die kopfgesteuerte prüft die Bedingung vor dem ersten Durchlauf, die fußgesteuerte erst danach, weshalb die fußgesteuerte mindestens einmal läuft."
],
"correct": 2,
"explanation": "Die kopfgesteuerte while-Schleife prüft vor dem Eintritt und kann daher null Durchläufe haben; die fußgesteuerte do-while prüft am Ende und läuft mindestens einmal. Ein fester Unterschied von genau einem Durchlauf besteht nicht, und die Nachprüfung trifft nur auf die fußgesteuerte Variante zu."
},
{
"category": "Struktogramm & Pseudocode",
"hint": "Anweisungen streng nacheinander.",
"text": "Was bezeichnet man in einem Algorithmus als Sequenz?",
"answers": [
"Eine Folge von Anweisungen, die streng nacheinander in der angegebenen Reihenfolge abgearbeitet werden.",
"Eine Anweisung, die abhängig von einer Bedingung übersprungen wird.",
"Einen Block, der so lange wiederholt wird, bis eine Bedingung erfüllt ist."
],
"correct": 0,
"explanation": "Die Sequenz ist die einfachste Grundstruktur: Anweisungen werden strikt der Reihe nach ausgeführt. Das bedingte Überspringen ist eine Verzweigung, das wiederholte Ausführen eine Schleife; beides sind eigene Kontrollstrukturen."
},
{
"category": "Sortierverfahren",
"hint": "Benachbarte Elemente tauschen.",
"text": "Nach welchem Prinzip arbeitet Bubblesort?",
"answers": [
"Es sucht in jedem Durchlauf gezielt das kleinste Element und stellt es an den Anfang.",
"Es vergleicht wiederholt benachbarte Elemente und vertauscht sie bei falscher Reihenfolge, bis kein Tausch mehr nötig ist.",
"Es teilt die Liste an einem Pivot und sortiert die Teillisten getrennt."
],
"correct": 1,
"explanation": "Bubblesort vergleicht Nachbarpaare und vertauscht sie bei falscher Reihenfolge, sodass große Werte nach oben wandern. Das gezielte Suchen des Minimums je Durchlauf kennzeichnet Selectionsort, das Aufteilen am Pivot ist Quicksort."
},
{
"category": "Sortierverfahren",
"hint": "Wie beim Einsortieren von Spielkarten.",
"text": "Wie geht Insertionsort (Sortieren durch Einfügen) grundsätzlich vor?",
"answers": [
"Es tauscht ausschließlich benachbarte Elemente in mehreren vollständigen Durchläufen.",
"Es sucht in jeder Runde das Maximum und hängt es hinten an.",
"Es nimmt Element für Element und fügt es an der passenden Stelle in den bereits sortierten vorderen Teil ein."
],
"correct": 2,
"explanation": "Insertionsort hält einen sortierten Anfangsbereich und schiebt jedes neue Element an die richtige Position darin, ähnlich dem Einsortieren von Spielkarten. Das Suchen des Maximums je Runde ist Selectionsort, reine Nachbartausche kennzeichnen Bubblesort."
},
{
"category": "Sortierverfahren",
"hint": "Teile und herrsche.",
"text": "Auf welchem Prinzip beruht Mergesort?",
"answers": [
"Teile und herrsche: die Liste rekursiv halbieren, die Teillisten sortieren und anschließend geordnet zusammenführen (mergen).",
"Ein einziger Durchlauf, der alle Elemente gleichzeitig an ihren Platz setzt.",
"Wiederholtes Vertauschen benachbarter Elemente ohne jede Aufteilung."
],
"correct": 0,
"explanation": "Mergesort folgt dem Teile-und-herrsche-Prinzip: rekursiv halbieren, Teillisten sortieren und beim Verschmelzen sortiert zusammenfügen. Es braucht mehrere Ebenen statt eines einzigen Durchlaufs, und Nachbartausche ohne Aufteilung gehören zu Bubblesort."
},
{
"category": "Sortierverfahren",
"hint": "Pivot und Durchschnitts- versus Worst-Case.",
"text": "Welche Aussage über Quicksort trifft zu?",
"answers": [
"Quicksort hat immer eine Laufzeit von O(n log n), auch im schlechtesten Fall.",
"Quicksort teilt die Daten an einem Pivot und ist im Mittel O(n log n), im schlechtesten Fall aber O(n²).",
"Quicksort benötigt zwingend bereits sortierte Eingabedaten."
],
"correct": 1,
"explanation": "Quicksort partitioniert am Pivot und erreicht im Durchschnitt O(n log n); bei ungünstiger Pivotwahl, etwa bei schon sortierten Daten, entartet es zu O(n²). Sortierte Eingabedaten setzt es nicht voraus, das gilt für die binäre Suche."
},
{
"category": "Suchverfahren",
"hint": "Der Reihe nach von vorne durchgehen.",
"text": "Wie arbeitet die lineare Suche?",
"answers": [
"Sie halbiert den Suchbereich in jedem Schritt.",
"Sie springt über den Index direkt an die Position des Werts.",
"Sie prüft die Elemente der Reihe nach von vorne, bis der gesuchte Wert gefunden ist oder das Ende erreicht wird."
],
"correct": 2,
"explanation": "Die lineare Suche geht die Elemente einfach nacheinander durch, im schlechtesten Fall alle n. Das Halbieren des Bereichs ist die binäre Suche, der direkte Zugriff über den Index ist ein Array- oder Hashzugriff, keine Suche im eigentlichen Sinn."
},
{
"category": "Suchverfahren",
"hint": "Vergleich mit dem mittleren Element.",
"text": "Welche Voraussetzung muss für die binäre Suche zwingend erfüllt sein?",
"answers": [
"Die Daten müssen sortiert vorliegen.",
"Die Daten müssen in einer verketteten Liste gespeichert sein.",
"Alle Werte müssen eindeutig, also ohne Duplikate, sein."
],
"correct": 0,
"explanation": "Die binäre Suche vergleicht mit dem mittleren Element und entscheidet, in welcher Hälfte es weitergeht, was nur bei sortierten Daten funktioniert. Eine verkettete Liste ist für den Mittelzugriff sogar ungünstig, und Eindeutigkeit der Werte ist nicht erforderlich."
},
{
"category": "Suchverfahren",
"hint": "Suchbereich halbieren.",
"text": "Warum ist die binäre Suche bei großen sortierten Datenmengen deutlich schneller als die lineare Suche?",
"answers": [
"Weil sie alle Elemente gleichzeitig miteinander vergleicht.",
"Weil sie den Suchbereich in jedem Schritt halbiert und so nur etwa log₂(n) Vergleiche braucht.",
"Weil sie die Daten vorher automatisch in einen Index umwandelt."
],
"correct": 1,
"explanation": "Die binäre Suche halbiert den Suchraum bei jedem Vergleich, daher genügen rund log₂(n) Schritte, also O(log n). Sie vergleicht nicht alles gleichzeitig und baut auch keinen Index auf, sie setzt lediglich bereits sortierte Daten voraus."
},
{
"category": "Suchverfahren",
"hint": "Lohnt sich das Sortieren für eine einzige Suche?",
"text": "Eine unsortierte Liste soll einmalig nach einem einzigen Wert durchsucht werden. Welches Vorgehen ist sinnvoll?",
"answers": [
"Die binäre Suche direkt auf der unsortierten Liste anwenden.",
"Die Liste ist so grundsätzlich gar nicht durchsuchbar.",
"Die lineare Suche, da sich das vorherige Sortieren für eine einzige Suche meist nicht lohnt."
],
"correct": 2,
"explanation": "Für eine einmalige Suche in unsortierten Daten ist die lineare Suche mit O(n) sinnvoll, weil allein das Sortieren schon O(n log n) kostet. Die binäre Suche würde auf unsortierten Daten falsche Ergebnisse liefern, und durchsuchbar ist die Liste selbstverständlich."
},
{
"category": "O-Notation",
"hint": "Aufwand unabhängig von der Datenmenge.",
"text": "Wofür steht die Komplexität O(1)?",
"answers": [
"Konstante Laufzeit: der Aufwand bleibt unabhängig von der Eingabegröße gleich.",
"Der Aufwand wächst linear mit der Eingabegröße.",
"Der Aufwand verdoppelt sich mit jedem zusätzlichen Element."
],
"correct": 0,
"explanation": "O(1) bedeutet konstanten Aufwand, etwa der Zugriff auf ein Array-Element über den Index, bei dem die Datenmenge keine Rolle spielt. Linear wachsender Aufwand ist O(n), eine Verdopplung je Element beschreibt exponentielles Wachstum wie O(2ⁿ)."
},
{
"category": "O-Notation",
"hint": "Effiziente vergleichsbasierte Sortierer.",
"text": "Welche Komplexität haben effiziente vergleichsbasierte Sortierverfahren wie Mergesort im Normalfall?",
"answers": [
"O(n)",
"O(n log n)",
"O(n²)"
],
"correct": 1,
"explanation": "Gute vergleichsbasierte Sortierverfahren wie Mergesort und Quicksort im Mittel liegen bei O(n log n). O(n) ist für vergleichsbasiertes Sortieren nicht erreichbar, und O(n²) beschreibt die einfachen Verfahren wie Bubble- oder Insertionsort im schlechten Fall."
},
{
"category": "O-Notation",
"hint": "Zwei verschachtelte Schleifen über alle Elemente.",
"text": "Ein Algorithmus enthält eine Schleife, die für jedes Element eine weitere vollständige Schleife über alle Elemente durchläuft. Welche Komplexität liegt vor?",
"answers": [
"O(log n)",
"O(n)",
"O(n²)"
],
"correct": 2,
"explanation": "Zwei ineinander verschachtelte Schleifen über je n Elemente ergeben n mal n, also O(n²), typisch für Bubblesort. O(n) entspricht einer einzelnen Schleife, O(log n) einem Halbieren des Bereichs wie bei der binären Suche."
},
{
"category": "O-Notation",
"hint": "Rangfolge für große n.",
"text": "Wie ordnest du die Komplexitäten O(1), O(log n), O(n) und O(n²) nach steigendem Aufwand für große n?",
"answers": [
"O(1) < O(log n) < O(n) < O(n²)",
"O(1) < O(n) < O(log n) < O(n²)",
"O(log n) < O(1) < O(n²) < O(n)"
],
"correct": 0,
"explanation": "Mit wachsendem n gilt O(1) < O(log n) < O(n) < O(n²). O(log n) wächst langsamer als O(n) und steht daher davor, konstantes O(1) ist immer am günstigsten. Die übrigen Reihenfolgen vertauschen diese Rangfolge."
},
{
"category": "Rekursion",
"hint": "Abbruch ohne weiteren Selbstaufruf.",
"text": "Wozu dient der Basisfall (Abbruchbedingung) in einer rekursiven Funktion?",
"answers": [
"Er ruft die Funktion mit einem vergrößerten Problem erneut auf.",
"Er beendet die Rekursion ohne weiteren Selbstaufruf und verhindert so eine Endlosrekursion.",
"Er sorgt dafür, dass die Funktion niemals zurückkehrt."
],
"correct": 1,
"explanation": "Der Basisfall liefert ein Ergebnis ohne erneuten Selbstaufruf und stoppt damit die Rekursion. Der erneute Aufruf mit verkleinertem Problem ist der Rekursionsschritt; fehlt ein erreichbarer Basisfall, kehrt die Funktion nie zurück und es kommt zur Endlosrekursion."
},
{
"category": "Rekursion",
"hint": "Selbstaufruf mit kleinerem Teilproblem.",
"text": "Was kennzeichnet den Rekursionsschritt?",
"answers": [
"Die Funktion gibt sofort einen festen Wert ohne Selbstaufruf zurück.",
"Die Funktion iteriert mit einer Schleife über alle Elemente.",
"Die Funktion ruft sich selbst mit einem verkleinerten Teilproblem auf, das dem Basisfall näherkommt."
],
"correct": 2,
"explanation": "Im Rekursionsschritt ruft sich die Funktion mit einem kleineren Teilproblem selbst auf und nähert sich so dem Basisfall. Das sofortige Zurückgeben eines festen Werts ist der Basisfall, das Durchlaufen mit einer Schleife wäre eine iterative statt rekursive Lösung."
},
{
"category": "Rekursion",
"hint": "Eigener Speicher je Aufruf.",
"text": "Was passiert bei jedem rekursiven Aufruf mit dem Aufrufstapel (Call Stack)?",
"answers": [
"Für jeden Aufruf wird ein neuer Stack-Frame mit eigenen lokalen Daten abgelegt, der erst beim Zurückkehren wieder freigegeben wird.",
"Der Stack bleibt unverändert, weil alle Aufrufe denselben Speicherbereich teilen.",
"Ältere Aufrufe werden sofort gelöscht, sobald ein neuer Aufruf erfolgt."
],
"correct": 0,
"explanation": "Jeder rekursive Aufruf legt einen eigenen Stack-Frame mit seinen lokalen Variablen an, der erst beim Zurückkehren abgeräumt wird; zu tiefe Rekursion füllt den Stapel und führt zum Stack Overflow. Die Aufrufe teilen sich also nicht denselben Rahmen, und ältere Frames bleiben bis zur Rückkehr erhalten."
},
{
"category": "Rekursion",
"hint": "Basisfall fehlt oder wird nie erreicht.",
"text": "Wodurch entsteht eine Endlosrekursion, die typischerweise mit einem Stack Overflow abbricht?",
"answers": [
"Durch einen zu großzügig gewählten Basisfall, der die Funktion zu früh abbrechen lässt.",
"Durch einen fehlenden oder nie erreichbaren Basisfall, sodass sich die Funktion unbegrenzt selbst aufruft.",
"Durch die Verwendung von zu wenigen lokalen Variablen."
],
"correct": 1,
"explanation": "Eine Endlosrekursion entsteht, wenn der Basisfall fehlt oder nie erreicht wird, sodass sich die Funktion unbegrenzt selbst aufruft, bis der Stack überläuft. Ein zu früh abbrechender Basisfall liefert höchstens ein falsches Ergebnis, und die Anzahl lokaler Variablen ist nicht die Ursache."
}
]
}
@@ -0,0 +1,245 @@
{
"title": "OOP",
"questions": [
{
"category": "Kapselung",
"hint": "Interna verbergen, Zugriff steuern.",
"text": "Was bedeutet Kapselung (Information Hiding) in der OOP?",
"answers": [
"Attribute werden als private deklariert und nur über definierte öffentliche Methoden zugänglich gemacht.",
"Alle Attribute werden public gemacht, damit jeder Programmteil möglichst schnell darauf zugreifen kann.",
"Klassen werden lediglich in Pakete (packages) einsortiert."
],
"correct": 0,
"explanation": "Kapselung schützt die inneren Daten: Attribute sind private und werden nur über kontrollierte Methoden nach außen freigegeben. Alle Attribute public zu machen ist das Gegenteil von Information Hiding, und das Einsortieren in Pakete regelt nur die Namensräume, nicht den Zugriffsschutz."
},
{
"category": "Kapselung",
"hint": "Wozu die Methode statt des direkten Zugriffs?",
"text": "Warum greifst du auf ein privates Attribut über Getter und Setter zu statt direkt?",
"answers": [
"Weil private Attribute sonst gar nicht erst im Speicher angelegt würden.",
"Damit die Klasse die Kontrolle über Lese- und Schreibzugriffe behält und im Setter z. B. Werte prüfen (validieren) kann.",
"Weil Getter und Setter das Attribut automatisch dauerhaft in einer Datenbank speichern."
],
"correct": 1,
"explanation": "Getter und Setter erlauben es, Zugriffe zu steuern und ungültige Werte im Setter abzufangen. Private Attribute liegen sehr wohl im Speicher, sie sind nur von außen nicht direkt erreichbar, und mit Persistenz oder Datenbanken haben einfache Zugriffsmethoden nichts zu tun."
},
{
"category": "Kapselung",
"hint": "Sichtbarkeit auf die eigene Klasse beschränkt.",
"text": "Welcher Zugriffsmodifizierer schränkt die Sichtbarkeit am stärksten ein und lässt Zugriff nur innerhalb der eigenen Klasse zu?",
"answers": [
"public",
"protected",
"private"
],
"correct": 2,
"explanation": "private erlaubt Zugriff nur innerhalb der definierenden Klasse und ist damit am restriktivsten. public ist von überall sichtbar, und protected öffnet den Zugriff zusätzlich für Unterklassen und (in Java) das eigene Paket."
},
{
"category": "Kapselung",
"hint": "Von außen lesen erlaubt, schreiben nicht.",
"text": "Wie machst du ein Attribut nach außen nur lesbar, aber nicht änderbar?",
"answers": [
"Du machst das Attribut public und dokumentierst nur, dass niemand es überschreiben soll.",
"Du lässt das Attribut private und bietest nur einen Getter, aber keinen Setter an.",
"Du deklarierst das Attribut als static."
],
"correct": 1,
"explanation": "Ohne Setter bleibt das private Attribut von außen unveränderbar, während der Getter das Lesen erlaubt. Ein public-Attribut mit bloßer Bitte, es nicht zu ändern, schützt technisch nichts, und static macht das Feld nur klassenweit gemeinsam, nicht schreibgeschützt."
},
{
"category": "Vererbung",
"hint": "Was übernimmt die Subklasse von oben?",
"text": "Was gilt für eine Unterklasse (Subklasse) gegenüber ihrer Oberklasse?",
"answers": [
"Sie erbt Attribute und Methoden der Oberklasse und kann sie um eigene erweitern oder geerbte überschreiben.",
"Sie kann nur neue Methoden hinzufügen, geerbte Methoden aber niemals verändern.",
"Sie ist völlig unabhängig; extends übernimmt lediglich den Klassennamen."
],
"correct": 0,
"explanation": "Die Unterklasse übernimmt die sichtbaren Attribute und Methoden der Oberklasse und darf sie ergänzen oder überschreiben. Dass geerbte Methoden unveränderlich seien, widerspricht dem Überschreiben, und extends kopiert nicht nur einen Namen, sondern etabliert eine echte Typ- und Vererbungsbeziehung."
},
{
"category": "Vererbung",
"hint": "Aufruf nach oben in der Hierarchie.",
"text": "Wozu dient der Aufruf super(...) im Konstruktor einer Unterklasse?",
"answers": [
"super löscht die von der Oberklasse geerbten Attribute wieder.",
"super erzeugt ein zweites, vollständig unabhängiges Objekt der Oberklasse.",
"super ruft den Konstruktor der Oberklasse auf, damit deren Teil des Objekts initialisiert wird."
],
"correct": 2,
"explanation": "Mit super(...) startet die Unterklasse den Konstruktor der Oberklasse und initialisiert deren Anteil desselben Objekts. Es entsteht kein zweites Objekt, und geerbte Attribute werden nicht gelöscht, sondern gerade korrekt aufgesetzt."
},
{
"category": "Vererbung",
"hint": "Gleiche Signatur, neue Implementierung in der Subklasse.",
"text": "Was bedeutet es, eine geerbte Methode zu überschreiben (override)?",
"answers": [
"In derselben Klasse eine zweite Methode gleichen Namens mit anderer Parameterliste anzulegen.",
"Die Unterklasse ersetzt eine geerbte Methode mit gleicher Signatur durch eine eigene Implementierung.",
"Eine Methode aus einer Klasse dauerhaft zu entfernen."
],
"correct": 1,
"explanation": "Überschreiben heißt: Die Unterklasse liefert für eine geerbte Methode mit identischer Signatur eine eigene Umsetzung. Eine zweite Methode gleichen Namens mit anderen Parametern wäre Überladen, nicht Überschreiben, und ein echtes Entfernen geerbter Methoden ist nicht möglich."
},
{
"category": "Vererbung",
"hint": "Hund ist ein Tier.",
"text": "Welche Beziehung modelliert Vererbung typischerweise?",
"answers": [
"Eine ist-ein-Beziehung, zum Beispiel: Ein Hund ist ein Tier.",
"Eine hat-ein-Beziehung, zum Beispiel: Ein Auto hat einen Motor.",
"Eine benutzt-Beziehung ganz ohne gemeinsamen Obertyp."
],
"correct": 0,
"explanation": "Vererbung drückt eine ist-ein-Beziehung aus, bei der die Unterklasse ein Spezialfall der Oberklasse ist. Die hat-ein-Beziehung (Auto hat einen Motor) gehört zur Komposition, und eine reine Benutzt-Beziehung entsteht ohne gemeinsamen Typ etwa durch Methodenaufrufe."
},
{
"category": "Polymorphie",
"hint": "Welcher Objekttyp zählt zur Laufzeit?",
"text": "Eine Variable vom Typ Tier verweist auf ein Hund-Objekt. Welche Methode wird bei tier.laut() ausgeführt, wenn Hund laut() überschreibt?",
"answers": [
"Immer die Methode der Oberklasse Tier, weil die Variable den Typ Tier hat.",
"Es entsteht ein Compilerfehler, weil die Typen nicht zusammenpassen.",
"Die überschriebene Methode der tatsächlichen Objektklasse Hund, dank dynamischer Bindung zur Laufzeit."
],
"correct": 2,
"explanation": "Bei der dynamischen Bindung entscheidet der echte Objekttyp zur Laufzeit, also läuft die laut()-Methode von Hund. Der deklarierte Variablentyp Tier bestimmt nur, welche Methoden aufrufbar sind, nicht welche Implementierung greift, und der Aufruf ist typkonform, also kein Compilerfehler."
},
{
"category": "Polymorphie",
"hint": "Gleicher Name, andere Parameter, eine Klasse.",
"text": "Was versteht man unter dem Überladen (overloading) einer Methode?",
"answers": [
"Eine Unterklasse ersetzt eine geerbte Methode und das wird erst zur Laufzeit aufgelöst.",
"Mehrere Methoden mit gleichem Namen, aber unterschiedlicher Parameterliste innerhalb einer Klasse; die passende wählt der Compiler.",
"Eine Methode, die sich zur Wiederholung immer wieder selbst aufruft."
],
"correct": 1,
"explanation": "Überladen bedeutet mehrere gleichnamige Methoden mit verschiedenen Parameterlisten; welche gilt, entscheidet der Compiler anhand der Argumente. Das Ersetzen einer geerbten Methode ist Überschreiben, und der wiederholte Selbstaufruf ist Rekursion."
},
{
"category": "Polymorphie",
"hint": "Compilezeit gegen Laufzeit.",
"text": "Wann wird beim Überladen entschieden, welche Variante läuft, und wann beim Überschreiben?",
"answers": [
"Überladen wird zur Compilezeit anhand der Argumenttypen aufgelöst, Überschreiben zur Laufzeit anhand des tatsächlichen Objekttyps.",
"Beides wird ausschließlich zur Laufzeit entschieden.",
"Beides wird ausschließlich zur Compilezeit entschieden."
],
"correct": 0,
"explanation": "Überladen ist statische Bindung: der Compiler wählt die Methode nach den Argumenttypen. Überschreiben ist dynamische Bindung: erst zur Laufzeit steht der echte Objekttyp fest. Beide gemeinsam der Compilezeit oder der Laufzeit zuzuordnen vermischt gerade diesen Kernunterschied."
},
{
"category": "Polymorphie",
"hint": "Verschiedene Objekte über einen Obertyp behandeln.",
"text": "Welchen praktischen Vorteil bietet Polymorphie beim Programmieren?",
"answers": [
"Sie beschleunigt jede Methode, weil der Compiler den Code grundsätzlich inlinen kann.",
"Sie ermöglicht das Erben von Zustand aus mehreren Klassen gleichzeitig (Mehrfachvererbung).",
"Du kannst unterschiedliche Objekte einheitlich über einen gemeinsamen Obertyp behandeln, etwa eine Liste von Formen zeichnen, ohne den konkreten Typ zu kennen."
],
"correct": 2,
"explanation": "Polymorphie erlaubt es, verschiedene Objekte über einen gemeinsamen Obertyp gleich anzusprechen; jedes reagiert mit seiner eigenen Implementierung. Mit Mehrfachvererbung von Zustand hat das nichts zu tun, und ein Geschwindigkeitsgewinn ist nicht ihr Zweck, dynamische Bindung kostet eher etwas Aufwand."
},
{
"category": "Interfaces & abstrakte Klassen",
"hint": "Mehrere Verträge gegen eine Basisklasse mit Code.",
"text": "Worin unterscheiden sich ein Interface und eine abstrakte Klasse klassischerweise?",
"answers": [
"Ein Interface kann eigenen Instanzzustand (veränderliche Objektattribute) speichern, eine abstrakte Klasse nicht.",
"Eine Klasse kann mehrere Interfaces implementieren, aber (in Java) nur von einer abstrakten Klasse erben; die abstrakte Klasse kann zudem Zustand und fertige Methoden mitbringen.",
"Interface und abstrakte Klasse sind funktional identisch und unterscheiden sich nur im Schlüsselwort."
],
"correct": 1,
"explanation": "Interfaces lassen sich in beliebiger Zahl implementieren und legen vor allem einen Vertrag fest, während eine abstrakte Klasse als einzige Basisklasse gemeinsamen Zustand und fertigen Code vererbt. Ein Interface hält keinen veränderlichen Instanzzustand, und funktional gleich sind beide Konzepte nicht."
},
{
"category": "Interfaces & abstrakte Klassen",
"hint": "Unvollständiger Bauplan.",
"text": "Kannst du von einer abstrakten Klasse direkt mit new ein Objekt erzeugen?",
"answers": [
"Nein, eine abstrakte Klasse ist nicht instanziierbar; nur von ihr abgeleitete konkrete Klassen können Objekte bilden.",
"Ja, genauso wie von jeder gewöhnlichen Klasse.",
"Ja, aber nur ein einziges Objekt pro Programm (erzwungenes Singleton)."
],
"correct": 0,
"explanation": "Eine abstrakte Klasse ist ein unvollständiger Bauplan und kann selbst kein Objekt erzeugen; instanziierbar sind nur ihre konkreten Unterklassen. Sie verhält sich damit nicht wie eine normale Klasse und erzwingt auch kein Singleton, dieses Muster ist etwas völlig anderes."
},
{
"category": "Interfaces & abstrakte Klassen",
"hint": "Zwei Fähigkeiten gleichzeitig zusagen.",
"text": "Deine Klasse soll sowohl vergleichbar als auch serialisierbar sein. Wie löst du das sauber?",
"answers": [
"Durch Mehrfachvererbung, indem die Klasse von zwei Basisklassen gleichzeitig erbt.",
"Gar nicht, denn eine Klasse kann immer nur eine einzige Fähigkeit besitzen.",
"Die Klasse implementiert beide Interfaces gleichzeitig, etwa implements Comparable, Serializable."
],
"correct": 2,
"explanation": "Eine Klasse darf beliebig viele Interfaces zugleich implementieren und mehrere Verträge erfüllen. Mehrfachvererbung von Klassen ist in Java gerade nicht erlaubt, und die Annahme, eine Klasse könne nur eine Fähigkeit haben, ist falsch, dafür gibt es Interfaces."
},
{
"category": "Interfaces & abstrakte Klassen",
"hint": "Ein Vertrag ohne vorgegebene Umsetzung.",
"text": "Wofür setzt du ein Interface typischerweise ein?",
"answers": [
"Um fertigen Programmcode samt gemeinsamem Zustand an alle Unterklassen zu vererben.",
"Um einen Vertrag festzulegen, welche Methoden vorhanden sein müssen, den verschiedene Klassen unabhängig voneinander erfüllen können.",
"Um Objekte physisch an einer bestimmten Stelle im Arbeitsspeicher anzuordnen."
],
"correct": 1,
"explanation": "Ein Interface definiert einen Vertrag aus Methodensignaturen, den unabhängige Klassen jeweils eigenständig umsetzen. Das Vererben von fertigem Code und gemeinsamem Zustand ist eher Sache einer (abstrakten) Basisklasse, und mit der Speicheranordnung von Objekten hat ein Interface nichts zu tun."
},
{
"category": "Komposition vs. Vererbung",
"hint": "Auto hat einen Motor.",
"text": "Ein Auto besitzt einen Motor. Wie modellierst du diese Beziehung am besten?",
"answers": [
"Als Komposition: Die Klasse Auto enthält ein Motor-Objekt als Attribut (hat-ein).",
"Als Vererbung: Auto erbt von Motor (ist-ein).",
"Als Interface: Auto implementiert Motor."
],
"correct": 0,
"explanation": "Ein Auto hat einen Motor, das ist eine hat-ein-Beziehung und damit Komposition, also ein Motor-Attribut in Auto. Von Motor zu erben würde behaupten, ein Auto sei ein Motor, und ein Interface würde nur eine Fähigkeit zusagen, nicht das Enthalten eines Bauteils abbilden."
},
{
"category": "Komposition vs. Vererbung",
"hint": "Kopplung und Flexibilität.",
"text": "Warum lautet eine bekannte Empfehlung favor composition over inheritance?",
"answers": [
"Weil Vererbung in modernen Programmiersprachen technisch gar nicht mehr möglich ist.",
"Weil Komposition zur Laufzeit grundsätzlich schneller ist als Vererbung.",
"Weil Komposition lockerer koppelt und flexibler bleibt, während tiefe Vererbungshierarchien Änderungen an der Oberklasse riskant machen (fragile Basisklasse)."
],
"correct": 2,
"explanation": "Komposition koppelt Klassen loser und lässt sich leichter umbauen oder zur Laufzeit austauschen, während Änderungen in einer Oberklasse ungewollt viele Unterklassen brechen können. Vererbung ist keineswegs abgeschafft, und ein pauschaler Geschwindigkeitsvorteil der Komposition ist nicht der Grund für die Empfehlung."
},
{
"category": "Komposition vs. Vererbung",
"hint": "Passt die ist-ein-Beziehung und die Ersetzbarkeit?",
"text": "Woran erkennst du, dass Vererbung statt Komposition angebracht ist?",
"answers": [
"Immer dann, wenn du einfach Code sparen willst, unabhängig davon, wie die Objekte zusammenhängen.",
"Wenn die ist-ein-Beziehung inhaltlich wirklich stimmt und die Unterklasse überall dort einsetzbar ist, wo der Obertyp erwartet wird (Ersetzbarkeit).",
"Immer wenn zwei Klassen zufällig einige gleich benannte Methoden besitzen."
],
"correct": 1,
"explanation": "Vererbung ist richtig, wenn eine echte ist-ein-Beziehung besteht und die Unterklasse den Obertyp überall ersetzen kann (Ersetzbarkeitsprinzip). Vererbung nur zum Code-Sparen zu missbrauchen führt zu falschen Typbeziehungen, und gleich benannte Methoden allein begründen noch keine gemeinsame Klasse."
},
{
"category": "Komposition vs. Vererbung",
"hint": "Ungewollt Geerbtes und enge Bindung.",
"text": "Was ist ein typischer Nachteil, wenn du Vererbung nur zur Code-Wiederverwendung missbrauchst?",
"answers": [
"Die Unterklasse erbt auch unpassende oder ungewollte Methoden und ist eng an die Oberklasse gekoppelt.",
"Der Compiler verweigert danach grundsätzlich jeden Aufruf geerbter Methoden.",
"Objekte der Unterklasse benötigen anschließend gar keinen Speicher mehr."
],
"correct": 0,
"explanation": "Wer nur zum Wiederverwenden erbt, holt sich das ganze Verhalten der Oberklasse ins Boot, auch unpassende Methoden, und bindet sich fest an deren Struktur. Der Compiler sperrt geerbte Methoden nicht, und ein Objekt der Unterklasse braucht selbstverständlich weiterhin Speicher."
}
]
}
@@ -0,0 +1,245 @@
{
"title": "SQL",
"questions": [
{
"category": "Joins",
"hint": "Nur Zeilen mit Partner in beiden Tabellen.",
"text": "Was liefert ein INNER JOIN zwischen kunde und bestellung über die Kundennummer?",
"answers": [
"Nur die Kunden, zu denen es mindestens eine passende Bestellung gibt.",
"Alle Kunden, auch solche ganz ohne Bestellung.",
"Alle Bestellungen, auch solche ohne gültigen Kunden."
],
"correct": 0,
"explanation": "Der INNER JOIN gibt nur Zeilen zurück, für die in BEIDEN Tabellen ein Partner existiert. Kunden ohne Bestellung liefert erst ein LEFT JOIN, verwaiste Bestellungen ein RIGHT JOIN auf die Bestelltabelle."
},
{
"category": "Joins",
"hint": "Linke Tabelle vollständig behalten.",
"text": "Du willst ALLE Kunden auflisten und dazu – falls vorhanden – ihre Bestellungen. Welcher Join passt?",
"answers": [
"INNER JOIN",
"LEFT (OUTER) JOIN von kunde auf bestellung",
"CROSS JOIN"
],
"correct": 1,
"explanation": "Der LEFT JOIN behält alle Zeilen der linken Tabelle (kunde) und füllt fehlende Bestellungen mit NULL. Der INNER JOIN verliert Kunden ohne Bestellung, der CROSS JOIN bildet das kartesische Produkt aller Kombinationen."
},
{
"category": "Joins",
"hint": "Fehlende Partner werden zu NULL.",
"text": "Wie findest du mit einem LEFT JOIN gezielt die Kunden OHNE jede Bestellung?",
"answers": [
"Mit WHERE bestellung.id = 0.",
"Mit einem INNER JOIN und HAVING COUNT(*) = 0.",
"Mit WHERE bestellung.id IS NULL nach dem LEFT JOIN."
],
"correct": 2,
"explanation": "Nach dem LEFT JOIN stehen bei Kunden ohne Bestellung NULL-Werte in den Bestellspalten; WHERE ... IS NULL filtert genau diese heraus. Ein INNER JOIN würde sie gar nicht erst liefern, und = 0 trifft NULL nicht."
},
{
"category": "Joins",
"hint": "Kartesisches Produkt.",
"text": "Was ist das Ergebnis eines CROSS JOIN zweier Tabellen mit 5 und 4 Zeilen?",
"answers": [
"20 Zeilen – jede Zeile der einen mit jeder Zeile der anderen kombiniert.",
"9 Zeilen – die Summe beider Zeilenzahlen.",
"5 Zeilen – begrenzt durch die kleinere Tabelle."
],
"correct": 0,
"explanation": "Der CROSS JOIN bildet das kartesische Produkt: 5 × 4 = 20 Kombinationen, ganz ohne Join-Bedingung. Die Summe (9) oder die kleinere Zeilenzahl (5) entstehen bei keinem Join-Typ."
},
{
"category": "GROUP BY & HAVING",
"hint": "Gruppieren, dann je Gruppe rechnen.",
"text": "Du willst pro Kunde die Anzahl seiner Bestellungen zählen. Welche Klausel gruppiert die Zeilen dafür korrekt?",
"answers": [
"ORDER BY kunde_id mit COUNT(*).",
"GROUP BY kunde_id mit COUNT(*).",
"DISTINCT kunde_id mit COUNT(*)."
],
"correct": 1,
"explanation": "GROUP BY kunde_id fasst alle Zeilen je Kunde zu einer Gruppe zusammen, über die COUNT(*) rechnet. ORDER BY sortiert nur, DISTINCT entfernt Duplikate, aggregiert aber nicht pro Gruppe."
},
{
"category": "GROUP BY & HAVING",
"hint": "Bedingung auf das Gruppenergebnis.",
"text": "Worin unterscheiden sich WHERE und HAVING?",
"answers": [
"WHERE filtert vor der Gruppierung einzelne Zeilen, HAVING filtert nach der Gruppierung anhand von Aggregaten.",
"WHERE und HAVING sind gleichwertig und beliebig austauschbar.",
"HAVING filtert Zeilen vor der Gruppierung, WHERE die fertigen Gruppen."
],
"correct": 0,
"explanation": "WHERE wirkt auf einzelne Zeilen vor dem Gruppieren, HAVING auf die Gruppen danach (z. B. HAVING COUNT(*) > 3). Sie sind nicht austauschbar – die Vorstellung, HAVING filtere vor und WHERE nach der Gruppierung, vertauscht beide Rollen."
},
{
"category": "GROUP BY & HAVING",
"hint": "Was darf ohne Aggregat in die SELECT-Liste?",
"text": "Bei GROUP BY kunde_id – welche Spalten dürfen ohne Aggregatfunktion in der SELECT-Liste stehen?",
"answers": [
"Beliebige Spalten der Tabelle.",
"Nur die Gruppierungsspalten (hier kunde_id) sowie Aggregate wie COUNT oder SUM.",
"Nur der Primärschlüssel der Tabelle."
],
"correct": 1,
"explanation": "In der SELECT-Liste sind nur die Spalten aus GROUP BY und Aggregatfunktionen erlaubt – sonst wäre der Wert je Gruppe nicht eindeutig. Beliebige Spalten führen (in strengem SQL) zum Fehler."
},
{
"category": "GROUP BY & HAVING",
"hint": "Filter auf Summen.",
"text": "Welche Abfrage liefert Kunden mit mehr als 3 Bestellungen?",
"answers": [
"SELECT kunde_id FROM bestellung WHERE COUNT(*) > 3 GROUP BY kunde_id",
"SELECT kunde_id FROM bestellung GROUP BY kunde_id ORDER BY COUNT(*) > 3",
"SELECT kunde_id FROM bestellung GROUP BY kunde_id HAVING COUNT(*) > 3"
],
"correct": 2,
"explanation": "Die Bedingung über ein Aggregat (COUNT) gehört in HAVING nach dem GROUP BY. In WHERE ist COUNT nicht erlaubt, und ORDER BY sortiert nur, statt zu filtern."
},
{
"category": "DDL & DML",
"hint": "Struktur ändern vs. Daten ändern.",
"text": "Welche Anweisung gehört zur DDL (Data Definition Language)?",
"answers": [
"UPDATE",
"CREATE TABLE",
"SELECT"
],
"correct": 1,
"explanation": "DDL definiert die Struktur: CREATE, ALTER, DROP. UPDATE ist DML (Datenmanipulation), SELECT ist DQL/Abfrage. Die Trennung nach Aufgabenbereich wird in der AP2 gern geprüft."
},
{
"category": "DDL & DML",
"hint": "Struktur-Löschen ist nicht rückrollbar wie ein einfaches DELETE.",
"text": "Worin unterscheiden sich DELETE FROM t und TRUNCATE TABLE t?",
"answers": [
"DELETE entfernt Zeilen (mit WHERE filterbar, protokolliert, rollback-fähig); TRUNCATE leert die ganze Tabelle schnell und setzt sie zurück.",
"DELETE und TRUNCATE sind identisch, nur unterschiedlich geschrieben.",
"TRUNCATE löscht einzelne Spalten, DELETE ganze Zeilen."
],
"correct": 0,
"explanation": "DELETE arbeitet zeilenweise mit WHERE und lässt sich in einer Transaktion zurückrollen; TRUNCATE leert die gesamte Tabelle sehr schnell (DDL-nah) ohne WHERE. Spalten löscht keines von beiden – das wäre ALTER TABLE."
},
{
"category": "DDL & DML",
"hint": "Neue Zeile einfügen.",
"text": "Mit welcher DML-Anweisung fügst du einen neuen Datensatz in eine Tabelle ein?",
"answers": [
"INSERT INTO ... VALUES",
"ALTER TABLE ... ADD",
"CREATE ROW"
],
"correct": 0,
"explanation": "INSERT INTO ... VALUES fügt neue Zeilen ein (DML). ALTER TABLE ... ADD ändert die Struktur (fügt eine Spalte hinzu, DDL), und CREATE ROW gibt es in SQL nicht."
},
{
"category": "DDL & DML",
"hint": "Referenzielle Integrität.",
"text": "Wozu dient ein FOREIGN KEY?",
"answers": [
"Er nummeriert die Zeilen automatisch fortlaufend.",
"Er verschlüsselt den Spaltenwert in der Datenbank.",
"Er stellt sicher, dass ein Wert auf einen existierenden Primärschlüssel einer anderen Tabelle verweist."
],
"correct": 2,
"explanation": "Der FOREIGN KEY sichert die referenzielle Integrität: er erlaubt nur Werte, die als Primärschlüssel in der Zieltabelle existieren. Das automatische Nummerieren übernimmt AUTO_INCREMENT/IDENTITY; Verschlüsselung ist keine Aufgabe eines Schlüssels."
},
{
"category": "Normalisierung",
"hint": "Atomare Werte je Feld.",
"text": "Welche Bedingung erfüllt eine Tabelle in der ersten Normalform (1NF)?",
"answers": [
"Jedes Attribut enthält nur atomare (unteilbare) Werte, keine Mehrfachwerte je Feld.",
"Jedes Nichtschlüsselattribut hängt vom gesamten Schlüssel ab.",
"Es gibt keine transitiven Abhängigkeiten mehr."
],
"correct": 0,
"explanation": "Die 1NF verlangt atomare Werte (keine Listen/Wiederholgruppen in einem Feld). Die volle Abhängigkeit vom Gesamtschlüssel ist die 2NF, die Freiheit von transitiven Abhängigkeiten die 3NF."
},
{
"category": "Normalisierung",
"hint": "Teilschlüssel-Abhängigkeit.",
"text": "Eine Tabelle ist in 1NF, aber ein Attribut hängt nur von einem Teil des zusammengesetzten Primärschlüssels ab. Welche Normalform ist verletzt?",
"answers": [
"Die 3NF.",
"Die 2NF.",
"Die BCNF, aber 2NF und 3NF sind erfüllt."
],
"correct": 1,
"explanation": "Die 2NF fordert, dass jedes Nichtschlüsselattribut vom GESAMTEN Schlüssel abhängt, nicht nur von einem Teil – genau das ist hier verletzt. Die 3NF betrifft transitive Abhängigkeiten und setzt die 2NF bereits voraus."
},
{
"category": "Normalisierung",
"hint": "Nichtschlüssel hängt an Nichtschlüssel.",
"text": "Was beseitigt die dritte Normalform (3NF)?",
"answers": [
"Mehrfachwerte in einem einzelnen Feld.",
"Doppelte Primärschlüssel.",
"Transitive Abhängigkeiten, bei denen ein Nichtschlüsselattribut von einem anderen Nichtschlüsselattribut abhängt."
],
"correct": 2,
"explanation": "Die 3NF entfernt transitive Abhängigkeiten (Nichtschlüssel → Nichtschlüssel), z. B. PLZ → Ort in einer Kundentabelle. Mehrfachwerte klärt die 1NF; doppelte Primärschlüssel sind ohnehin unzulässig."
},
{
"category": "Normalisierung",
"hint": "Ziel der Normalisierung.",
"text": "Welches Ziel verfolgt die Normalisierung vor allem?",
"answers": [
"Redundanz und dadurch mögliche Anomalien beim Einfügen, Ändern und Löschen zu vermeiden.",
"Die Abfragen möglichst schnell zu machen, egal wie viele Tabellen entstehen.",
"Alle Daten in einer einzigen großen Tabelle zusammenzufassen."
],
"correct": 0,
"explanation": "Normalisierung reduziert Redundanz und verhindert Änderungs-, Einfüge- und Löschanomalien. Reine Geschwindigkeit ist kein Ziel (Denormalisierung kann sie sogar erhöhen), und eine einzige Riesentabelle ist das Gegenteil von normalisiert."
},
{
"category": "Abfragen & Constraints",
"hint": "Fehlender Wert ist nicht gleich 0 oder ''.",
"text": "Wie prüfst du in SQL korrekt auf einen fehlenden Wert (NULL)?",
"answers": [
"WHERE spalte = NULL",
"WHERE spalte IS NULL",
"WHERE spalte = ''"
],
"correct": 1,
"explanation": "NULL bedeutet „unbekannt\"; Vergleiche mit = NULL ergeben immer UNKNOWN und liefern nichts. Korrekt ist IS NULL. Der leere String '' ist ein eigener Wert und nicht dasselbe wie NULL."
},
{
"category": "Abfragen & Constraints",
"hint": "Eindeutig und nicht leer.",
"text": "Welche Eigenschaft garantiert ein PRIMARY KEY?",
"answers": [
"Die Werte dürfen sich wiederholen, müssen aber sortiert sein.",
"Die Spalte darf NULL enthalten, solange die Werte eindeutig sind.",
"Die Werte sind eindeutig und niemals NULL."
],
"correct": 2,
"explanation": "Ein PRIMARY KEY ist eindeutig UND NOT NULL – er identifiziert jede Zeile zweifelsfrei. NULL-Werte sind ausgeschlossen; eine bloß eindeutige, aber NULL-erlaubende Spalte wäre ein UNIQUE-Constraint."
},
{
"category": "Abfragen & Constraints",
"hint": "Ergebnis begrenzen und sortieren.",
"text": "Wie gibst du die drei teuersten Artikel aus (Standard-SQL bzw. gängige Dialekte)?",
"answers": [
"SELECT ... FROM artikel WHERE preis = MAX(preis) LIMIT 3",
"SELECT ... FROM artikel ORDER BY preis DESC LIMIT 3 (bzw. FETCH FIRST 3 ROWS ONLY)",
"SELECT TOP preis FROM artikel GROUP BY 3"
],
"correct": 1,
"explanation": "Erst absteigend nach Preis sortieren, dann auf drei Zeilen begrenzen (LIMIT bzw. FETCH FIRST). MAX in WHERE ist nicht erlaubt, und GROUP BY 3 gruppiert nur nach der dritten Spalte statt zu begrenzen."
},
{
"category": "Abfragen & Constraints",
"hint": "Fehlende Bedingung wirkt auf alles.",
"text": "Was passiert bei UPDATE artikel SET preis = preis * 1.1 ohne WHERE-Klausel?",
"answers": [
"Es passiert nichts, weil ohne WHERE keine Zeile ausgewählt ist.",
"Nur die zuletzt eingefügte Zeile wird geändert.",
"Der Preis wird in ALLEN Zeilen der Tabelle um 10 % erhöht."
],
"correct": 2,
"explanation": "Ohne WHERE gilt ein UPDATE für jede Zeile der Tabelle – hier steigt jeder Preis um 10 %. Ein fehlendes WHERE wählt also alles aus statt nichts und trifft nicht nur eine einzelne Zeile."
}
]
}
@@ -0,0 +1,245 @@
{
"title": "Testverfahren",
"questions": [
{
"category": "Blackbox vs. Whitebox",
"hint": "Ohne Blick in den Code.",
"text": "Aus welcher Perspektive betrachtest du das Testobjekt beim Blackbox-Test?",
"answers": [
"Nur über Eingaben und erwartete Ausgaben, ohne den internen Quellcode zu kennen.",
"Anhand des internen Quellcodes, um jeden Programmpfad gezielt abzudecken.",
"Ausschließlich über die Analyse der Datenbankstruktur im Hintergrund."
],
"correct": 0,
"explanation": "Der Blackbox-Test prüft das Verhalten allein über die Schnittstelle: Eingabe rein, Ausgabe mit der Spezifikation vergleichen, ohne die innere Struktur zu kennen. Das gezielte Abdecken von Programmpfaden anhand des Quellcodes ist der Whitebox-Ansatz, und die Datenbankstruktur allein ist kein Kriterium des Verfahrens."
},
{
"category": "Blackbox vs. Whitebox",
"hint": "Kenntnis des Codes nutzen.",
"text": "Welche Technik ist typisch für den Whitebox-Test?",
"answers": [
"Grenzwertanalyse rein anhand der fachlichen Spezifikation.",
"Zweig- und Pfadabdeckung anhand des Programmablaufs im Quellcode.",
"Abnahme durch den Kunden anhand der vereinbarten Anforderungen."
],
"correct": 1,
"explanation": "Whitebox nutzt die Kenntnis des Codes, um den Kontrollfluss abzudecken, etwa über Anweisungs-, Zweig- und Pfadüberdeckung. Die Grenzwertanalyse aus der Spezifikation gehört zum Blackbox-Test, und die Kundenabnahme ist eine Testebene und kein Verfahren der Codeüberdeckung."
},
{
"category": "Blackbox vs. Whitebox",
"hint": "Nicht erreichter Code.",
"text": "Warum kann ein reiner Blackbox-Test bestimmte Fehler übersehen?",
"answers": [
"Weil er den kompletten Quellcode Zeile für Zeile prüft und dabei ermüdet.",
"Weil er ausschließlich die Datenbank und nie die Programmlogik testet.",
"Weil nicht durchlaufener oder toter Code ohne Blick in die Struktur unentdeckt bleiben kann."
],
"correct": 2,
"explanation": "Ohne Kenntnis der inneren Struktur erkennt der Blackbox-Test nicht, ob es nie erreichten oder toten Code gibt; solche Lücken deckt erst eine Codeüberdeckung per Whitebox auf. Der Blackbox-Test liest den Quellcode gerade nicht und beschränkt sich auch nicht auf die Datenbank."
},
{
"category": "Blackbox vs. Whitebox",
"hint": "Nur die Spezifikation liegt vor.",
"text": "Ein Tester kennt nur die Anforderungsspezifikation, nicht die Implementierung, und leitet daraus die Testfälle ab. Um welches Verfahren handelt es sich?",
"answers": [
"Blackbox-Test.",
"Whitebox-Test.",
"Anweisungsüberdeckung."
],
"correct": 0,
"explanation": "Testfälle allein aus der Spezifikation ohne Blick in die Implementierung kennzeichnen den Blackbox-Test. Whitebox setzt gerade die Codekenntnis voraus, und die Anweisungsüberdeckung ist eine konkrete Whitebox-Metrik, die den Quellcode benötigt."
},
{
"category": "Äquivalenzklassen & Grenzwerte",
"hint": "Repräsentant je Klasse.",
"text": "Was ist die Grundidee der Äquivalenzklassenbildung?",
"answers": [
"Für jeden einzelnen möglichen Eingabewert genau einen Testfall zu schreiben.",
"Eingaben in Klassen zusammenzufassen, die vermutlich gleich behandelt werden, und je Klasse einen Repräsentanten zu testen.",
"Nur ungültige Eingaben zu testen, weil gültige ohnehin funktionieren."
],
"correct": 1,
"explanation": "Äquivalenzklassen fassen Eingaben zusammen, die das Programm voraussichtlich gleich verarbeitet; getestet wird ein Repräsentant je Klasse, was die Zahl der Testfälle stark senkt. Jeden Wert einzeln zu prüfen wäre unpraktikabel, und gültige Klassen müssen ebenso getestet werden wie ungültige."
},
{
"category": "Äquivalenzklassen & Grenzwerte",
"hint": "Gültige und ungültige Bereiche.",
"text": "Für ein Alter-Feld gilt: gültig ist 18 bis 65. Welche Aufteilung in Äquivalenzklassen ist korrekt?",
"answers": [
"Nur eine gültige Klasse von 18 bis 65, ungültige Werte sind irrelevant.",
"Drei gültige Klassen und gar keine ungültige Klasse.",
"Eine gültige Klasse 18 bis 65 sowie zwei ungültige Klassen: kleiner als 18 und größer als 65."
],
"correct": 2,
"explanation": "Neben der gültigen Klasse von 18 bis 65 gehören auch die ungültigen Bereiche darunter und darüber getestet, denn gerade dort treten Fehler auf. Die ungültigen Eingaben zu ignorieren würde das fehlerhafte Verhalten ungeprüft lassen."
},
{
"category": "Äquivalenzklassen & Grenzwerte",
"hint": "Direkt an den Rändern.",
"text": "Gültig ist ein Wert von 1 bis 100. Welche Werte prüft die Grenzwertanalyse besonders?",
"answers": [
"Die Ränder und ihre direkten Nachbarn, also 0, 1, 100 und 101.",
"Nur den Mittelwert 50, weil er die Klasse repräsentiert.",
"Ausschließlich weit entfernte Werte wie -1000 und 1000."
],
"correct": 0,
"explanation": "Fehler treten häufig an den Klassengrenzen auf, deshalb prüft die Grenzwertanalyse die Randwerte und ihre direkten Nachbarn, hier 0, 1, 100 und 101. Ein Wert aus der Mitte deckt typische Off-by-one-Fehler nicht ab, und sehr weit entfernte Werte liegen tief in der ungültigen Klasse statt an der Grenze."
},
{
"category": "Äquivalenzklassen & Grenzwerte",
"hint": "Off-by-one an den Rändern.",
"text": "Warum ergänzt man die Äquivalenzklassen sinnvollerweise um eine Grenzwertanalyse?",
"answers": [
"Weil die Grenzwertanalyse die Äquivalenzklassen vollständig ersetzt.",
"Weil Fehler besonders oft an den Klassengrenzen entstehen, etwa durch < statt <=.",
"Weil dadurch jeder einzelne Wert des gesamten Wertebereichs getestet wird."
],
"correct": 1,
"explanation": "Verwechslungen wie < statt <= führen zu typischen Fehlern genau an den Rändern, die ein Repräsentant aus der Klassenmitte übersieht; deshalb ergänzen Grenzwerte die Klassenbildung. Sie ersetzen die Klassen nicht und prüfen auch nicht jeden Einzelwert des Bereichs."
},
{
"category": "Testebenen",
"hint": "Kleinste Einheit isoliert.",
"text": "Welche Testebene prüft eine einzelne Klasse oder Methode isoliert?",
"answers": [
"Der Systemtest.",
"Der Abnahmetest.",
"Der Unit-Test (Modul- bzw. Komponententest)."
],
"correct": 2,
"explanation": "Der Unit-Test prüft die kleinste Einheit, also eine Methode oder Klasse, isoliert und ersetzt Abhängigkeiten oft durch Mocks. Der Systemtest betrachtet das Gesamtsystem, und der Abnahmetest richtet sich nach der Erfüllung der Kundenanforderungen."
},
{
"category": "Testebenen",
"hint": "Zusammenspiel über Schnittstellen.",
"text": "Worauf zielt der Integrationstest ab?",
"answers": [
"Auf das korrekte Zusammenspiel mehrerer Module über ihre Schnittstellen.",
"Auf die interne Verzweigungslogik einer einzelnen Methode.",
"Auf die formale Abnahme durch den Auftraggeber."
],
"correct": 0,
"explanation": "Der Integrationstest prüft, ob zuvor einzeln getestete Module über ihre Schnittstellen korrekt zusammenarbeiten. Die interne Logik einer einzelnen Methode ist Sache des Unit-Tests, und die formale Abnahme gehört zum Abnahmetest."
},
{
"category": "Testebenen",
"hint": "Vollständig integriert, produktionsnah.",
"text": "In welcher Umgebung wird der Systemtest typischerweise durchgeführt?",
"answers": [
"In der Entwicklungsumgebung gegen einzelne Klassen.",
"In einer produktionsnahen Umgebung gegen das vollständig integrierte Gesamtsystem.",
"Direkt auf dem Produktivsystem der Kunden ohne jede Testdaten."
],
"correct": 1,
"explanation": "Der Systemtest prüft das vollständig integrierte System gegen die Anforderungen, möglichst in einer produktionsähnlichen Umgebung mit realistischen Testdaten. Einzelne Klassen sind Gegenstand des Unit-Tests, und ungeprüft auf dem Produktivsystem zu testen wäre riskant und untypisch."
},
{
"category": "Testebenen",
"hint": "Sicht des Auftraggebers.",
"text": "Wer führt den Abnahmetest primär durch und wogegen wird geprüft?",
"answers": [
"Die Entwickler, gegen die interne Codestruktur.",
"Ein Automatisierungsserver, gegen die erreichte Testabdeckung.",
"Der Auftraggeber bzw. Fachbereich, gegen die vertraglich vereinbarten Anforderungen."
],
"correct": 2,
"explanation": "Der Abnahmetest wird aus Sicht des Auftraggebers gegen die vereinbarten Anforderungen durchgeführt und entscheidet über die Freigabe. Die interne Codestruktur prüfen Whitebox-Verfahren, und eine Kennzahl wie die Testabdeckung ist kein fachliches Abnahmekriterium."
},
{
"category": "Testarten & Vorgehen",
"hint": "Nach Änderung nichts kaputt?",
"text": "Was ist das Ziel eines Regressionstests?",
"answers": [
"Sicherzustellen, dass bereits funktionierende Features nach einer Änderung weiterhin korrekt arbeiten.",
"Ausschließlich neu geschriebene Funktionen zum ersten Mal zu testen.",
"Die Ausführungsgeschwindigkeit des Systems unter hoher Last zu messen."
],
"correct": 0,
"explanation": "Der Regressionstest wiederholt bestehende Testfälle nach Änderungen, um zu erkennen, ob zuvor korrekte Funktionen ungewollt beschädigt wurden. Das erstmalige Prüfen neuer Funktionen ist nicht sein Ziel, und die Messung von Geschwindigkeit unter Last ist ein eigener Last-/Performancetest."
},
{
"category": "Testarten & Vorgehen",
"hint": "Red, Green, Refactor.",
"text": "Welche Reihenfolge beschreibt Test-Driven Development (TDD) korrekt?",
"answers": [
"Erst die Funktion vollständig implementieren und ganz am Ende die Tests schreiben.",
"Erst einen fehlschlagenden Test schreiben, dann den Code bis zum grünen Test implementieren, danach refactoren.",
"Auf Tests verzichten und die Anwendung nur manuell durchklicken."
],
"correct": 1,
"explanation": "TDD folgt dem Zyklus Red-Green-Refactor: zuerst ein Test, der fehlschlägt, dann minimaler Code, der ihn erfüllt, danach das Aufräumen bei weiterhin grünen Tests. Tests erst nachträglich oder gar nicht zu schreiben widerspricht dem testgetriebenen Ansatz."
},
{
"category": "Testarten & Vorgehen",
"hint": "Ohne Soll kein Urteil.",
"text": "Was gehört zu einem vollständig beschriebenen Testfall zwingend dazu?",
"answers": [
"Nur eine kurze Beschreibung, was ungefähr getestet werden soll.",
"Ausschließlich die konkreten Eingabewerte.",
"Vorbedingung, Eingabe bzw. Aktion, erwartetes Ergebnis und der Vergleich mit dem Ist-Ergebnis."
],
"correct": 2,
"explanation": "Ein aussagekräftiger Testfall nennt die Vorbedingungen, die konkrete Eingabe oder Aktion und vor allem das erwartete Ergebnis, gegen das das tatsächliche Ergebnis geprüft wird. Ohne definiertes Soll-Ergebnis lässt sich nicht objektiv über Bestehen oder Fehlschlag entscheiden."
},
{
"category": "Testarten & Vorgehen",
"hint": "Schnell und reproduzierbar.",
"text": "Welcher Vorteil spricht besonders für automatisierte Tests?",
"answers": [
"Sie lassen sich schnell und reproduzierbar beliebig oft wiederholen, ideal für Regression und Continuous Integration.",
"Sie machen den fachlichen Testfallentwurf und das Nachdenken über Testfälle überflüssig.",
"Sie garantieren mathematisch, dass überhaupt keine Fehler mehr vorhanden sind."
],
"correct": 0,
"explanation": "Automatisierte Tests laufen schnell und immer gleich, sodass sie sich für häufige Regressionsläufe und Continuous Integration eignen. Sie ersetzen aber nicht den fachlichen Testentwurf und können Fehlerfreiheit nicht beweisen, denn ein bestandener Test zeigt nur die Abwesenheit der geprüften Fehler."
},
{
"category": "Schnittstellen & Datenformate",
"hint": "Neue Ressource erzeugen.",
"text": "Welche HTTP-Methode ist bei REST für das Anlegen einer neuen Ressource üblich?",
"answers": [
"GET",
"POST",
"DELETE"
],
"correct": 1,
"explanation": "POST legt bei REST typischerweise eine neue Ressource an und wird meist mit dem Statuscode 201 Created bestätigt. GET liest nur ohne Seiteneffekt, und DELETE entfernt eine bestehende Ressource."
},
{
"category": "Schnittstellen & Datenformate",
"hint": "Ressource existiert nicht.",
"text": "Ein REST-Client fragt eine Ressource ab, die es nicht gibt. Welcher HTTP-Statuscode ist korrekt?",
"answers": [
"200 OK",
"500 Internal Server Error",
"404 Not Found"
],
"correct": 2,
"explanation": "Der Code 404 Not Found signalisiert, dass die angeforderte Ressource nicht existiert. Der Code 200 OK meldet dagegen Erfolg, und 500 steht für einen unerwarteten Serverfehler und nicht für eine schlicht fehlende Ressource."
},
{
"category": "Schnittstellen & Datenformate",
"hint": "Ohne gespeicherten Sitzungszustand.",
"text": "Welche Aussage beschreibt ein zentrales REST-Prinzip korrekt?",
"answers": [
"Die Kommunikation ist zustandslos: jede Anfrage enthält alle nötigen Informationen, der Server hält keinen Sitzungszustand.",
"Der Server merkt sich zwischen den Anfragen automatisch den kompletten Zustand des Clients.",
"Jede Operation muss zwingend über die Methode GET laufen."
],
"correct": 0,
"explanation": "REST ist zustandslos: jede Anfrage trägt alle Informationen, die der Server zur Bearbeitung braucht, ohne gespeicherten Sitzungszustand. Serverseitig gehaltener Sitzungszustand widerspricht dem Prinzip, und je nach Operation kommen unterschiedliche Methoden wie GET, POST, PUT oder DELETE zum Einsatz."
},
{
"category": "Schnittstellen & Datenformate",
"hint": "Beide textbasiert.",
"text": "Worin unterscheiden sich JSON und XML als Datenformat?",
"answers": [
"JSON ist ein Bildformat, während XML ein reines Textformat ist.",
"Beide sind textbasiert; JSON ist meist kompakter, XML unterstützt zusätzlich Attribute, Namespaces und Schema-Validierung.",
"Nur XML ist maschinenlesbar, JSON kann ausschließlich ein Mensch lesen."
],
"correct": 1,
"explanation": "JSON und XML sind beide textbasiert und maschinenlesbar; JSON ist in der Regel kompakter und in Web-APIs verbreitet, während XML mit Attributen, Namespaces und Schemata wie XSD mehr Struktur bietet. JSON ist kein Bildformat, und maschinenlesbar sind beide Formate."
}
]
}
@@ -0,0 +1,245 @@
{
"title": "UML",
"questions": [
{
"category": "Klassendiagramm",
"hint": "Minus steht für die engste Sichtbarkeit.",
"text": "Welche Sichtbarkeit bedeutet das Zeichen - vor einem Attribut im Klassendiagramm?",
"answers": [
"public – von überall zugreifbar.",
"private – nur innerhalb der eigenen Klasse zugreifbar.",
"protected – auch für erbende Unterklassen zugreifbar."
],
"correct": 1,
"explanation": "Das Minus steht für private, also Zugriff nur innerhalb der eigenen Klasse. Das Pluszeichen kennzeichnet public (von überall), die Raute # steht für protected (auch für Unterklassen). Verwechsle das Minus nicht mit protected – dessen Zeichen ist ausdrücklich die Raute."
},
{
"category": "Klassendiagramm",
"hint": "Drei Fächer von oben nach unten.",
"text": "Wie ist eine Klasse im UML-Klassendiagramm typischerweise aufgebaut?",
"answers": [
"In drei Abschnitten: oben der Klassenname, in der Mitte die Attribute, unten die Methoden.",
"In zwei Abschnitten: oben die Methoden, unten die Attribute.",
"In einem einzigen Feld, das nur den Klassennamen enthält."
],
"correct": 0,
"explanation": "Eine Klasse wird als Rechteck mit drei Fächern gezeichnet: Name oben, Attribute in der Mitte, Methoden unten. Die Reihenfolge Attribute-über-Methoden ist fest; sie zu vertauschen oder alles in ein Feld zu packen widerspricht der UML-Notation."
},
{
"category": "Klassendiagramm",
"hint": "Achte auf die runden Klammern.",
"text": "Woran erkennst du im Klassendiagramm eine Methode (Operation) und nicht ein Attribut?",
"answers": [
"Sie steht immer im obersten Abschnitt der Klasse.",
"Sie beginnt stets mit einem Großbuchstaben.",
"An den runden Klammern hinter dem Namen, zum Beispiel berechneSumme()."
],
"correct": 2,
"explanation": "Methoden erkennst du an den runden Klammern hinter dem Namen, die die Parameterliste aufnehmen. Der oberste Abschnitt enthält dagegen den Klassennamen, und die Groß-/Kleinschreibung ist reine Namenskonvention und kein Unterscheidungsmerkmal."
},
{
"category": "Klassendiagramm",
"hint": "Erst der Name, dann der Typ nach dem Doppelpunkt.",
"text": "Wie notierst du im Klassendiagramm ein privates Attribut alter vom Typ Integer korrekt?",
"answers": [
"+ alter : Integer",
"- alter : Integer",
"# Integer alter"
],
"correct": 1,
"explanation": "Privat wird durch das Minus ausgedrückt, und in UML steht der Typ hinter dem Namen nach einem Doppelpunkt (name : Typ). Das Pluszeichen wäre public, und die Raute mit vorangestelltem Typ mischt protected mit der Java-Schreibweise Typ-vor-Name, die in UML nicht gilt."
},
{
"category": "Beziehungen & Multiplizitäten",
"hint": "Ohne das Ganze verschwinden die Teile.",
"text": "Ein Haus besteht aus Räumen; ohne das Haus existieren die Räume nicht. Welche Beziehung liegt vor und wie wird sie notiert?",
"answers": [
"Aggregation, dargestellt mit leerer Raute am Haus.",
"Assoziation, dargestellt mit einer einfachen Linie.",
"Komposition, dargestellt mit gefüllter Raute am Haus (dem Ganzen)."
],
"correct": 2,
"explanation": "Die Existenzabhängigkeit der Teile vom Ganzen ist das Kennzeichen der Komposition, notiert mit gefüllter Raute am Ganzen. Eine Aggregation (leere Raute) wäre nur eine lose hat-Beziehung ohne Existenzabhängigkeit, und eine schlichte Assoziation drückt gar kein Teil-Ganzes-Verhältnis aus."
},
{
"category": "Beziehungen & Multiplizitäten",
"hint": "Leere Raute gegen gefüllte Raute.",
"text": "Worin unterscheidet sich eine Aggregation von einer Komposition?",
"answers": [
"Die Aggregation ist eine schwache hat-Beziehung mit leerer Raute; bei der Komposition ist der Teil existenzabhängig vom Ganzen und wird mit gefüllter Raute gezeichnet.",
"Die Aggregation nutzt eine gefüllte Raute, die Komposition eine leere.",
"Beide sind identisch und nur zwei Namen für dieselbe Beziehung."
],
"correct": 0,
"explanation": "Aggregation ist die schwache hat-Beziehung mit leerer Raute; die Teile können auch ohne das Ganze bestehen. Komposition ist die starke Form mit gefüllter Raute und Existenzabhängigkeit. Die Zuordnung der Rauten wird gern vertauscht – gefüllt gehört zur starken Komposition."
},
{
"category": "Beziehungen & Multiplizitäten",
"hint": "Der Stern steht für unbegrenzt.",
"text": "Was bedeutet die Multiplizität 1..* an einem Assoziationsende?",
"answers": [
"Genau ein Objekt, nicht mehr und nicht weniger.",
"Mindestens ein Objekt, nach oben unbegrenzt viele.",
"Null oder ein Objekt, also optional."
],
"correct": 1,
"explanation": "1..* meint mindestens eins und nach oben beliebig viele, weil der Stern für unbegrenzt steht. Genau eins wäre schlicht 1, und die optionale Angabe null-oder-eins schreibt man 0..1 – beide Fallen lassen die Untergrenze von mindestens eins außer Acht."
},
{
"category": "Beziehungen & Multiplizitäten",
"hint": "Ein hohles Dreieck zeigt nach oben.",
"text": "Wie wird eine Vererbung (Generalisierung) zwischen Ober- und Unterklasse dargestellt?",
"answers": [
"Mit einer gestrichelten Linie ganz ohne Pfeilspitze.",
"Mit einer gefüllten Raute an der Oberklasse.",
"Mit einer durchgezogenen Linie und einem großen, nicht ausgefüllten Dreieckspfeil, der zur Oberklasse zeigt."
],
"correct": 2,
"explanation": "Vererbung zeichnest du mit durchgezogener Linie und hohlem Dreieckspfeil, der von der Unterklasse zur Oberklasse zeigt. Eine gefüllte Raute gehört zur Komposition, und eine gestrichelte Linie steht für Abhängigkeiten oder Realisierungen, nicht für Generalisierung."
},
{
"category": "Sequenzdiagramm",
"hint": "Sie hängt senkrecht unter dem Objekt.",
"text": "Was stellt die senkrechte gestrichelte Linie unterhalb eines Objekts im Sequenzdiagramm dar?",
"answers": [
"Die Lebenslinie – sie zeigt die Existenz des Objekts über die Zeit hinweg.",
"Eine asynchrone Nachricht des Objekts an sich selbst.",
"Die Vererbungsbeziehung zu einer Oberklasse."
],
"correct": 0,
"explanation": "Die gestrichelte Senkrechte ist die Lebenslinie und zeigt, dass das Objekt über die dargestellte Zeit existiert. Nachrichten laufen dagegen waagerecht zwischen Lebenslinien, und Vererbung kommt im Sequenzdiagramm gar nicht vor – sie gehört ins Klassendiagramm."
},
{
"category": "Sequenzdiagramm",
"hint": "Sender wartet auf die Antwort.",
"text": "Wie wird im Sequenzdiagramm eine synchrone Nachricht, etwa ein Methodenaufruf mit Warten auf die Antwort, dargestellt?",
"answers": [
"Mit einer gestrichelten Linie und offener Pfeilspitze.",
"Mit einer durchgezogenen Linie und ausgefüllter, geschlossener Pfeilspitze.",
"Mit einem großen, hohlen Dreieckspfeil."
],
"correct": 1,
"explanation": "Die synchrone Nachricht bekommt eine durchgezogene Linie mit gefüllter Pfeilspitze; der Sender wartet auf die Rückantwort. Die gestrichelte Linie mit offener Spitze ist die Antwort (Return) beziehungsweise die asynchrone Nachricht, und der hohle Dreieckspfeil gehört zur Vererbung im Klassendiagramm."
},
{
"category": "Sequenzdiagramm",
"hint": "Ein schmales Rechteck auf der Linie.",
"text": "Wofür steht der schmale Balken (das schmale Rechteck) auf der Lebenslinie im Sequenzdiagramm?",
"answers": [
"Für das endgültige Löschen des Objekts.",
"Für eine Bedingung oder Verzweigung im Ablauf.",
"Für den Aktivierungsbalken – die Zeitspanne, in der das Objekt gerade eine Operation ausführt."
],
"correct": 2,
"explanation": "Der schmale Balken ist der Aktivierungsbalken und markiert, wie lange das Objekt aktiv eine Operation bearbeitet. Das Löschen wird dagegen mit einem Kreuz am Ende der Lebenslinie gezeigt, und Bedingungen fasst man in kombinierte Fragmente (etwa alt oder opt) statt in den Balken."
},
{
"category": "Sequenzdiagramm",
"hint": "Der Sender läuft sofort weiter.",
"text": "Was kennzeichnet eine asynchrone Nachricht im Sequenzdiagramm gegenüber einer synchronen?",
"answers": [
"Der Sender wartet nicht auf eine Antwort und arbeitet sofort weiter; dargestellt mit offener Pfeilspitze.",
"Der Sender blockiert immer, bis die Antwort zurückkommt.",
"Sie wird durch eine gefüllte Raute an der Lebenslinie dargestellt."
],
"correct": 0,
"explanation": "Bei einer asynchronen Nachricht läuft der Sender ohne Warten weiter; sie erhält eine offene (strichförmige) Pfeilspitze. Das Blockieren bis zur Antwort beschreibt gerade die synchrone Nachricht, und eine gefüllte Raute gibt es im Sequenzdiagramm gar nicht – sie stammt aus dem Klassendiagramm."
},
{
"category": "Aktivitätsdiagramm",
"hint": "Ein Punkt startet, ein Punkt im Ring beendet.",
"text": "Wie werden Start- und Endknoten im Aktivitätsdiagramm dargestellt?",
"answers": [
"Start und Ende jeweils als Raute.",
"Start als gefüllter Kreis, Ende als gefüllter Kreis mit einem umgebenden Ring.",
"Start als abgerundetes Rechteck, Ende als Dreieck."
],
"correct": 1,
"explanation": "Der Startknoten ist ein gefüllter Kreis, der Endknoten ein gefüllter Kreis mit umgebendem Ring (wie eine Zielscheibe). Rauten stehen für Entscheidungen, und abgerundete Rechtecke sind die Aktionen selbst – beides sind keine Start- oder Endmarkierungen."
},
{
"category": "Aktivitätsdiagramm",
"hint": "Ein Eingang, mehrere bedingte Ausgänge.",
"text": "Wofür steht eine Raute mit einem eingehenden und mehreren ausgehenden Pfeilen im Aktivitätsdiagramm?",
"answers": [
"Für eine Aktion, die ausgeführt wird.",
"Für den Startknoten des Ablaufs.",
"Für eine Entscheidung (Verzweigung); die ausgehenden Kanten tragen Bedingungen (Guards)."
],
"correct": 2,
"explanation": "Die Raute ist der Entscheidungsknoten: Ein Ablauf kommt herein und verzweigt anhand der Bedingungen an den ausgehenden Kanten in genau einen Zweig. Eine Aktion wäre ein abgerundetes Rechteck, und der Startknoten ist ein gefüllter Kreis ohne eingehende Kante."
},
{
"category": "Aktivitätsdiagramm",
"hint": "Ein dicker Balken teilt und führt zusammen.",
"text": "Wie werden im Aktivitätsdiagramm parallele, also nebenläufige Abläufe modelliert?",
"answers": [
"Mit einem Synchronisationsbalken (fork/join) – ein dicker Balken spaltet den Ablauf in mehrere parallele Zweige auf und führt sie später wieder zusammen.",
"Mit einer Raute, die den Ablauf in sich ausschließende Alternativen aufteilt.",
"Mit einer gestrichelten Lebenslinie wie im Sequenzdiagramm."
],
"correct": 0,
"explanation": "Parallelität modellierst du mit dem Synchronisationsbalken: Ein fork spaltet in mehrere gleichzeitig laufende Zweige, ein join führt sie wieder zusammen. Die Raute erzeugt dagegen sich ausschließende Alternativen (nur ein Zweig wird durchlaufen), und Lebenslinien gehören ins Sequenzdiagramm."
},
{
"category": "Aktivitätsdiagramm",
"hint": "Abgerundete Ecken für einen Arbeitsschritt.",
"text": "Wie wird eine einzelne Aktion (ein Arbeitsschritt) im Aktivitätsdiagramm dargestellt?",
"answers": [
"Als Raute mit spitzen Ecken.",
"Als Rechteck mit abgerundeten Ecken.",
"Als gefüllter Kreis."
],
"correct": 1,
"explanation": "Eine Aktion zeichnest du als Rechteck mit abgerundeten Ecken. Die spitze Raute steht für Entscheidungen, und der gefüllte Kreis markiert den Startknoten – beide beschreiben keinen einzelnen Arbeitsschritt."
},
{
"category": "Use-Case-Diagramm",
"hint": "Er steht außerhalb des Systems.",
"text": "Was ist ein Akteur im Use-Case-Diagramm?",
"answers": [
"Ein einzelner Programmschritt innerhalb des Systems.",
"Eine Datenbanktabelle, auf die zugegriffen wird.",
"Eine Rolle außerhalb des Systems – Mensch oder Fremdsystem –, die mit dem System interagiert; dargestellt als Strichmännchen."
],
"correct": 2,
"explanation": "Ein Akteur ist eine Rolle außerhalb der Systemgrenze, also ein Mensch oder ein anderes System, das mit dem System interagiert, und wird als Strichmännchen gezeichnet. Ein Programmschritt liegt innerhalb des Systems, und eine Datenbanktabelle ist ein technisches Detail, kein Akteur."
},
{
"category": "Use-Case-Diagramm",
"hint": "Verpflichtend eingebundenes Verhalten.",
"text": "Was drückt die Beziehung <<include>> zwischen zwei Use Cases aus?",
"answers": [
"Der Basis-Use-Case bindet den eingebundenen Use Case immer verpflichtend ein – ausgelagertes, wiederverwendetes Verhalten.",
"Der eingebundene Use Case wird nur unter einer bestimmten Bedingung optional ergänzt.",
"Zwei Akteure erben voneinander ihre Rechte."
],
"correct": 0,
"explanation": "include steht für immer eingebundenes, wiederverwendetes Verhalten: Läuft der Basis-Use-Case, wird der eingebundene stets mit ausgeführt. Das nur bedingte, optionale Ergänzen beschreibt dagegen extend, und eine Vererbung zwischen Akteuren ist eine eigene Generalisierungsbeziehung."
},
{
"category": "Use-Case-Diagramm",
"hint": "Nur unter einer Bedingung ergänzt.",
"text": "Was bedeutet die Beziehung <<extend>> im Use-Case-Diagramm?",
"answers": [
"Der erweiternde Use Case wird immer zwingend mit ausgeführt.",
"Der erweiternde Use Case ergänzt das Verhalten des Basis-Use-Case nur unter einer bestimmten Bedingung (optional).",
"Es handelt sich um die Systemgrenze um alle Use Cases."
],
"correct": 1,
"explanation": "extend beschreibt eine optionale Erweiterung: Der erweiternde Use Case greift nur unter einer bestimmten Bedingung an einem Erweiterungspunkt ein. Das immer zwingende Einbinden ist gerade include, und die Systemgrenze ist der umschließende Rahmen, keine Beziehung zwischen Use Cases."
},
{
"category": "Use-Case-Diagramm",
"hint": "Der Rahmen trennt innen von außen.",
"text": "Wofür steht der Rahmen (das umschließende Rechteck) im Use-Case-Diagramm?",
"answers": [
"Für die Systemgrenze – er trennt das System mit seinen Use Cases (innen) von den Akteuren (außen).",
"Für eine parallele Verarbeitung mehrerer Use Cases.",
"Für eine Vererbungsbeziehung zwischen zwei Use Cases."
],
"correct": 0,
"explanation": "Der Rahmen ist die Systemgrenze: Innerhalb liegen die Use Cases des Systems, außerhalb stehen die Akteure. Parallele Verarbeitung modelliert man im Aktivitätsdiagramm, und Vererbung wird durch einen eigenen Generalisierungspfeil ausgedrückt, nicht durch den Rahmen."
}
]
}
@@ -0,0 +1,245 @@
{
"title": "IT-Sicherheit",
"questions": [
{
"category": "Firewall & DMZ",
"hint": "Verbindungszustand merken oder nicht.",
"text": "Worin unterscheidet sich eine Stateful-Inspection-Firewall von einem einfachen Paketfilter?",
"answers": [
"Sie verfolgt den Verbindungszustand und lässt Antwortpakete zu bereits aufgebauten Verbindungen automatisch zu.",
"Sie prüft ausschließlich einzelne Pakete ohne Bezug zueinander anhand starrer Regeln.",
"Sie arbeitet nur auf der Anwendungsschicht und ersetzt jede Verbindung durch eine eigene Sitzung."
],
"correct": 0,
"explanation": "Stateful Inspection führt eine Zustandstabelle und erkennt, welche Pakete zu einer bestehenden Verbindung gehören – Rückantworten müssen nicht einzeln freigegeben werden. Die reine Einzelpaketprüfung ohne Kontext beschreibt gerade den zustandslosen Paketfilter, und das vollständige Ersetzen jeder Verbindung ist Aufgabe eines Proxys bzw. Application-Gateways."
},
{
"category": "Firewall & DMZ",
"hint": "Wo steht ein öffentlich erreichbarer Server sicher?",
"text": "Ein aus dem Internet erreichbarer Webserver soll ins Firmennetz integriert werden. Wie platzierst du ihn sicher?",
"answers": [
"Direkt im internen LAN, damit er bequem auf die interne Datenbank zugreifen kann.",
"In einer DMZ, die per Firewall sowohl vom Internet als auch vom internen LAN getrennt ist.",
"Ohne Firewall direkt am Internet-Router, damit die Erreichbarkeit garantiert bleibt."
],
"correct": 1,
"explanation": "Eine DMZ isoliert öffentlich erreichbare Dienste, sodass ein kompromittierter Server nicht unmittelbar das interne Netz öffnet. Im internen LAN säße ein gekaperter Server sofort im vertrauenswürdigen Bereich, und ohne Firewall wäre er völlig ungeschützt exponiert."
},
{
"category": "Firewall & DMZ",
"hint": "Zwei Firewalls bilden einen Zwischenbereich.",
"text": "Was beschreibt das Konzept eines Screened Subnet (DMZ mit zwei Firewalls)?",
"answers": [
"Eine einzelne Firewall mit drei Schnittstellen für LAN, WAN und DMZ.",
"Zwei baugleiche Firewalls hintereinander, die nur der Lastverteilung dienen.",
"Eine äußere und eine innere Firewall, zwischen denen die DMZ liegt, sodass ein Angreifer beide überwinden muss."
],
"correct": 2,
"explanation": "Beim Screened Subnet spannen eine äußere und eine innere Firewall (idealerweise verschiedener Hersteller) die DMZ dazwischen auf – der Weg ins LAN führt nur durch beide. Die einzelne Firewall mit drei Schnittstellen ist die kollabierte Ein-Firewall-Variante, und Lastverteilung ist nicht der Zweck dieses Sicherheitskonzepts."
},
{
"category": "Firewall & DMZ",
"hint": "Was ist nicht erlaubt, ist verboten.",
"text": "Nach welchem Grundprinzip sollte ein Firewall-Regelwerk aufgebaut sein?",
"answers": [
"Default-Allow: grundsätzlich alles erlauben und nur bekannte Angriffe gezielt blockieren.",
"Default-Deny: grundsätzlich alles verbieten und nur den explizit benötigten Verkehr freigeben.",
"Die Reihenfolge der Regeln ist egal, weil die Firewall stets die am wenigsten restriktive Regel anwendet."
],
"correct": 1,
"explanation": "Default-Deny (Whitelist) lässt nur ausdrücklich freigegebenen Verkehr durch und hält die Angriffsfläche minimal. Default-Allow lässt unbekannten Verkehr offen, und die Reihenfolge ist keineswegs egal – die meisten Firewalls wenden die erste passende Regel an."
},
{
"category": "VPN",
"hint": "Welcher IPsec-Teil verschlüsselt die Nutzdaten?",
"text": "Welcher Bestandteil von IPsec sorgt durch Verschlüsselung der Nutzdaten für Vertraulichkeit?",
"answers": [
"ESP (Encapsulating Security Payload).",
"AH (Authentication Header).",
"IKE (Internet Key Exchange)."
],
"correct": 0,
"explanation": "ESP verschlüsselt die Nutzdaten und liefert damit Vertraulichkeit, optional zusätzlich Integrität und Authentizität. AH schützt nur Integrität und Herkunft, verschlüsselt aber nichts, und IKE handelt lediglich die Schlüssel aus, ohne den eigentlichen Datenverkehr zu verschlüsseln."
},
{
"category": "VPN",
"hint": "Ganzes Paket kapseln oder nur Nutzlast schützen?",
"text": "Ein Site-to-Site-VPN zwischen zwei Standorten soll die kompletten Original-IP-Pakete schützen und verbergen. Welcher IPsec-Modus ist dafür vorgesehen?",
"answers": [
"Der Transportmodus, weil er den ursprünglichen IP-Header unverändert lässt.",
"Der Transportmodus in Verbindung mit zusätzlichem NAT.",
"Der Tunnelmodus, der das gesamte Original-Paket verschlüsselt und in ein neues IP-Paket kapselt."
],
"correct": 2,
"explanation": "Der Tunnelmodus kapselt das vollständige Originalpaket samt Header in ein neues IP-Paket – Standard für die Kopplung ganzer Standorte über Gateways. Der Transportmodus lässt den ursprünglichen IP-Header sichtbar und schützt nur die Nutzlast, was eher für direkte Host-zu-Host-Verbindungen gedacht ist; NAT ändert daran nichts."
},
{
"category": "VPN",
"hint": "Zugriff nur über den Browser.",
"text": "Ein Außendienstmitarbeiter soll ohne installierten VPN-Client nur per Browser auf einzelne Webanwendungen zugreifen. Welche VPN-Variante passt am besten?",
"answers": [
"IPsec im Tunnelmodus mit vollständigem Zugriff auf das gesamte Firmennetz.",
"Ein clientloses SSL/TLS-VPN, das den Zugriff über HTTPS direkt im Browser ermöglicht.",
"Ein PPTP-VPN, weil es besonders starke Verschlüsselung bietet."
],
"correct": 1,
"explanation": "Clientlose SSL/TLS-VPNs laufen über HTTPS im Browser und eignen sich ideal für den gezielten Zugriff auf einzelne Webanwendungen ohne Softwareinstallation. IPsec benötigt einen Client und öffnet gleich das ganze Netz, und PPTP gilt als veraltet und kryptografisch gebrochen – keineswegs besonders stark."
},
{
"category": "VPN",
"hint": "Alte Aufzeichnungen bleiben geschützt.",
"text": "Was bewirkt Perfect Forward Secrecy (PFS) bei einem VPN?",
"answers": [
"Ein später kompromittierter Langzeitschlüssel erlaubt es nicht, zuvor aufgezeichnete Sitzungen nachträglich zu entschlüsseln.",
"Der Sitzungsschlüssel wird dauerhaft gespeichert, damit sich Verbindungen schneller wieder aufbauen lassen.",
"Alle Teilnehmer verwenden denselben statischen Schlüssel, um maximale Kompatibilität zu erreichen."
],
"correct": 0,
"explanation": "PFS erzeugt pro Sitzung flüchtige Schlüssel über einen frischen Diffie-Hellman-Austausch, sodass ein geknackter Langzeitschlüssel den mitgeschnittenen Altverkehr nicht offenlegt. Das dauerhafte Speichern von Sitzungsschlüsseln oder ein einziger statischer Schlüssel würden genau diesen Schutz aushebeln."
},
{
"category": "Verschlüsselung",
"hint": "Ein Schlüssel für beide Seiten.",
"text": "Welche Aussage über AES trifft zu?",
"answers": [
"AES ist ein asymmetrisches Verfahren mit öffentlichem und privatem Schlüssel.",
"AES ist ein Hashverfahren zur reinen Integritätsprüfung.",
"AES ist eine symmetrische Blockchiffre, bei der beide Seiten denselben geheimen Schlüssel nutzen."
],
"correct": 2,
"explanation": "AES ist eine symmetrische Blockchiffre: derselbe geheime Schlüssel ver- und entschlüsselt die Daten. Öffentlicher und privater Schlüssel gehören zu asymmetrischen Verfahren wie RSA, und eine Integritätsprüfung ohne Rückgewinnung der Daten leistet eine Hashfunktion wie SHA – beides andere Verfahrensklassen."
},
{
"category": "Verschlüsselung",
"hint": "Schnell und sicher zugleich kombinieren.",
"text": "Warum kombiniert man in der Praxis (etwa bei TLS) asymmetrische und symmetrische Verschlüsselung zu einem Hybridverfahren?",
"answers": [
"Weil asymmetrische Verfahren als unsicher gelten und nur zur Tarnung mitlaufen.",
"Weil der schnelle symmetrische Sitzungsschlüssel sicher über das langsame asymmetrische Verfahren ausgetauscht wird.",
"Weil symmetrische Verfahren überhaupt keinen gemeinsamen Schlüssel benötigen."
],
"correct": 1,
"explanation": "Beim Hybridverfahren transportiert das asymmetrische Verfahren sicher den symmetrischen Sitzungsschlüssel, mit dem anschließend die Massendaten schnell verschlüsselt werden. Asymmetrische Verfahren sind nicht unsicher, sondern nur rechenintensiv, und symmetrische Verschlüsselung braucht sehr wohl einen gemeinsamen Schlüssel – dessen Austausch ist ja gerade das Problem."
},
{
"category": "Verschlüsselung",
"hint": "Nur der Empfänger soll lesen können.",
"text": "Alice möchte Bob eine vertrauliche Nachricht asymmetrisch verschlüsselt senden. Welchen Schlüssel verwendet sie dafür?",
"answers": [
"Bobs öffentlichen Schlüssel.",
"Bobs privaten Schlüssel.",
"Ihren eigenen privaten Schlüssel."
],
"correct": 0,
"explanation": "Für Vertraulichkeit verschlüsselt Alice mit Bobs öffentlichem Schlüssel, denn nur Bobs privater Schlüssel kann das wieder entschlüsseln. Bobs privaten Schlüssel besitzt Alice gar nicht, und mit ihrem eigenen privaten Schlüssel würde sie signieren – lesbar für jeden mit ihrem öffentlichen Schlüssel."
},
{
"category": "Verschlüsselung",
"hint": "Fester Prüfwert, nicht umkehrbar.",
"text": "Wozu dient eine kryptografische Hashfunktion wie SHA-256?",
"answers": [
"Zum umkehrbaren Verschlüsseln, das sich mit dem passenden Schlüssel wieder entschlüsseln lässt.",
"Zum verlustfreien Komprimieren großer Dateien.",
"Zum Erzeugen eines festen, praktisch kollisionsfreien Prüfwerts zur Integritätssicherung."
],
"correct": 2,
"explanation": "Eine kryptografische Hashfunktion bildet Daten auf einen festen, praktisch kollisionsfreien Prüfwert ab und sichert so die Integrität. Sie ist eine Einwegfunktion – es gibt keinen Schlüssel zum Zurückrechnen – und dient auch nicht der verlustfreien Kompression, da sich die Originaldaten nicht rekonstruieren lassen."
},
{
"category": "Zertifikate & PKI",
"hint": "Wer bürgt für den öffentlichen Schlüssel?",
"text": "Welche Aufgabe hat eine Zertifizierungsstelle (CA) in einer PKI?",
"answers": [
"Sie verschlüsselt den gesamten Datenverkehr zwischen den Teilnehmern.",
"Sie bestätigt mit ihrer digitalen Signatur die Zuordnung eines öffentlichen Schlüssels zu einer Identität.",
"Sie speichert die privaten Schlüssel aller Teilnehmer zentral ab."
],
"correct": 1,
"explanation": "Die CA signiert Zertifikate und beglaubigt damit, dass ein öffentlicher Schlüssel wirklich zu einer bestimmten Identität gehört. Den eigentlichen Datenverkehr verschlüsselt nicht die CA, und private Schlüssel müssen beim jeweiligen Besitzer bleiben – eine zentrale Ablage würde das gesamte Vertrauensmodell zerstören."
},
{
"category": "Zertifikate & PKI",
"hint": "Signieren geschieht mit dem eigenen geheimen Schlüssel.",
"text": "Mit welchem Schlüssel erzeugt der Absender eine digitale Signatur für ein Dokument?",
"answers": [
"Mit seinem eigenen privaten Schlüssel.",
"Mit dem öffentlichen Schlüssel des Empfängers.",
"Mit einem zuvor ausgehandelten gemeinsamen symmetrischen Schlüssel."
],
"correct": 0,
"explanation": "Der Absender signiert mit seinem privaten Schlüssel; jeder kann die Signatur mit dessen öffentlichem Schlüssel prüfen und so Echtheit und Urheberschaft bestätigen. Mit dem öffentlichen Schlüssel des Empfängers würde man zur Vertraulichkeit verschlüsseln, und ein gemeinsamer symmetrischer Schlüssel kann keinen eindeutigen Urheber belegen (keine Nichtabstreitbarkeit)."
},
{
"category": "Zertifikate & PKI",
"hint": "Zurückgezogen trotz gültigem Datum.",
"text": "Wie prüft ein Client, ob ein vorgelegtes Zertifikat zwischenzeitlich vorzeitig zurückgezogen wurde?",
"answers": [
"Anhand des Ablaufdatums, das im Zertifikat eingetragen ist.",
"Durch erneutes Berechnen des Fingerprints des Zertifikats.",
"Über eine Sperrliste (CRL) oder eine OCSP-Abfrage bei der ausstellenden CA."
],
"correct": 2,
"explanation": "Den Sperrstatus liefern eine Zertifikatssperrliste (CRL) oder eine OCSP-Anfrage bei der CA. Das Ablaufdatum zeigt nur den regulären Gültigkeitszeitraum, nicht einen vorzeitigen Rückruf, und das Neuberechnen des Fingerprints prüft lediglich die Unverfälschtheit, nicht den Widerruf."
},
{
"category": "Zertifikate & PKI",
"hint": "Kette bis zu einer vertrauten Wurzel.",
"text": "Worauf beruht das Vertrauen in ein Serverzertifikat beim Aufruf einer HTTPS-Seite?",
"answers": [
"Darauf, dass das Zertifikat selbstsigniert und damit automatisch fälschungssicher ist.",
"Auf einer lückenlosen Vertrauenskette bis hinauf zu einer im System hinterlegten Root-CA.",
"Darauf, dass die Domain im Zertifikat mit irgendeiner beliebigen anderen CA übereinstimmt."
],
"correct": 1,
"explanation": "Das Vertrauen folgt der Kette vom Serverzertifikat über Zwischenzertifikate bis zu einer Root-CA, der Betriebssystem oder Browser bereits vertrauen. Ein selbstsigniertes Zertifikat hat keinen externen Vertrauensanker, und die ausstellende Stelle muss eine vertrauenswürdige CA sein, nicht eine beliebige."
},
{
"category": "Schutzziele & Authentisierung",
"hint": "Daten wurden unbemerkt verändert.",
"text": "Ein Angreifer verändert unbemerkt die Beträge in einer übertragenen Überweisungsdatei. Welches Schutzziel der CIA-Triade ist dadurch primär verletzt?",
"answers": [
"Integrität.",
"Vertraulichkeit.",
"Verfügbarkeit."
],
"correct": 0,
"explanation": "Die unbefugte, unbemerkte Veränderung von Daten verletzt die Integrität. Vertraulichkeit wäre erst bei unbefugtem Mitlesen betroffen und Verfügbarkeit erst, wenn die Daten oder das System nicht mehr erreichbar wären – beides ist hier nicht der Fall."
},
{
"category": "Schutzziele & Authentisierung",
"hint": "Der Dienst ist nicht mehr erreichbar.",
"text": "Ein DDoS-Angriff überlastet einen Webshop so stark, dass Kunden ihn nicht mehr erreichen. Welches Schutzziel ist primär betroffen?",
"answers": [
"Integrität.",
"Vertraulichkeit.",
"Verfügbarkeit."
],
"correct": 2,
"explanation": "Ein DDoS-Angriff verhindert den legitimen Zugriff und trifft damit die Verfügbarkeit. Die Daten werden dabei weder verändert (Integrität) noch ausgelesen (Vertraulichkeit) – der Dienst ist schlicht nicht erreichbar."
},
{
"category": "Schutzziele & Authentisierung",
"hint": "Zwei verschiedene Faktorarten.",
"text": "Eine Anmeldung verlangt ein Passwort und zusätzlich einen Einmalcode aus einer Authenticator-App. Warum gilt das als echte Zwei-Faktor-Authentisierung?",
"answers": [
"Weil zwei verschiedene Passwörter nacheinander abgefragt werden.",
"Weil zwei unterschiedliche Faktorarten kombiniert werden: Wissen (Passwort) und Besitz (Gerät mit App).",
"Weil dasselbe Passwort zur Sicherheit zweimal eingegeben werden muss."
],
"correct": 1,
"explanation": "Echte 2FA verbindet Faktoren aus verschiedenen Kategorien – hier Wissen (Passwort) und Besitz (das Gerät, das den Code erzeugt). Zwei Passwörter oder eine doppelte Eingabe bleiben im selben Faktor Wissen und fügen keinen zweiten, unabhängigen Faktor hinzu."
},
{
"category": "Schutzziele & Authentisierung",
"hint": "Erst wer bist du, dann was darfst du.",
"text": "Worin unterscheiden sich Authentisierung und Autorisierung?",
"answers": [
"Die Authentisierung weist die Identität nach, die Autorisierung legt danach fest, worauf der Nutzer zugreifen darf.",
"Die Authentisierung vergibt die Zugriffsrechte, die Autorisierung prüft das Passwort.",
"Beide Begriffe bezeichnen denselben Vorgang der reinen Passwortprüfung."
],
"correct": 0,
"explanation": "Die Authentisierung beantwortet, wer jemand ist, und erst die Autorisierung entscheidet, welche Ressourcen dieser Nutzer verwenden darf. Die vertauschte Definition dreht beide Schritte um, und sie als denselben Vorgang zu sehen ignoriert, dass Identitätsnachweis und Rechtevergabe getrennte Stufen sind."
}
]
}
@@ -0,0 +1,245 @@
{
"title": "Monitoring & Backup",
"questions": [
{
"category": "Monitoring & SNMP",
"hint": "Software auf dem überwachten Gerät.",
"text": "Welche Aufgabe hat ein SNMP-Agent in einer Monitoring-Umgebung?",
"answers": [
"Er läuft auf dem überwachten Gerät, sammelt dort Statuswerte in der MIB und liefert sie an das Monitoring-System.",
"Er ist die zentrale Software, die alle Geräte abfragt und die Messwerte grafisch darstellt.",
"Er verschlüsselt den gesamten Netzwerkverkehr zwischen den überwachten Geräten."
],
"correct": 0,
"explanation": "Der Agent sitzt auf dem Zielsystem (Switch, Server, Drucker), hält seine Werte in der MIB bereit und beantwortet Abfragen des Managers oder sendet Traps. Die zentrale Abfrage und Darstellung übernimmt der Manager beziehungsweise das NMS; mit Verschlüsselung des Nutzdatenverkehrs hat SNMP nichts zu tun (erst SNMPv3 sichert die Verwaltungsdaten selbst)."
},
{
"category": "Monitoring & SNMP",
"hint": "Zwei Stufen vor dem Ausfall.",
"text": "Warum definiert man beim Monitoring für eine Kennzahl wie die Festplattenbelegung typischerweise einen Warning- und einen Critical-Schwellwert?",
"answers": [
"Weil ein einzelner Schwellwert technisch nicht überwacht werden kann.",
"Damit man bei Annäherung an einen kritischen Zustand frühzeitig gewarnt wird und erst bei echter Gefahr Alarm ausgelöst wird.",
"Weil der Warning-Wert den Dienst automatisch neu startet und der Critical-Wert ihn abschaltet."
],
"correct": 1,
"explanation": "Abgestufte Schwellwerte trennen 'beobachten' von 'sofort handeln': Warning gibt Vorlaufzeit zum Reagieren, Critical meldet den akuten Notfall. Ein einzelner Schwellwert wäre technisch problemlos möglich, nur weniger aussagekräftig; Schwellwerte lösen Meldungen aus und starten oder stoppen nicht von sich aus Dienste."
},
{
"category": "Monitoring & SNMP",
"hint": "Das Gerät meldet sich von selbst.",
"text": "Worin unterscheidet sich ein SNMP-Trap vom klassischen Polling?",
"answers": [
"Ein Trap fragt die Geräte in kürzeren Intervallen ab als Polling.",
"Ein Trap überträgt die Daten grundsätzlich verschlüsselt, Polling immer im Klartext.",
"Beim Trap meldet der Agent ein Ereignis von sich aus an den Manager, während der Manager beim Polling die Geräte aktiv abfragt."
],
"correct": 2,
"explanation": "Polling ist ein aktives, zyklisches Abfragen durch den Manager; ein Trap ist eine ereignisgesteuerte Meldung, die der Agent ohne Aufforderung sendet und so die Reaktionszeit bei Störungen verkürzt. Ein Trap ist kein schnelleres Polling, und die Verschlüsselung hängt von der SNMP-Version ab, nicht von Trap gegenüber Polling."
},
{
"category": "Monitoring & SNMP",
"hint": "Zu viele Fehlalarme sind auch ein Problem.",
"text": "Du bekommst nachts ständig Alarme, weil die CPU-Last kurzzeitig den Schwellwert überschreitet. Wie gehst du sinnvoll vor?",
"answers": [
"Ich lege eine Mindestdauer beziehungsweise mehrere Prüfintervalle fest, sodass erst bei anhaltender Überschreitung alarmiert wird.",
"Ich schalte das Monitoring für die CPU-Last komplett ab, damit keine Meldungen mehr kommen.",
"Ich setze den Schwellwert auf 100 %, damit praktisch nie ein Alarm ausgelöst wird."
],
"correct": 0,
"explanation": "Kurze Lastspitzen sind normal; mit einer Mindestdauer (etwa 'über 5 Minuten') oder mehreren aufeinanderfolgenden Prüfungen vermeidest du Fehlalarme, ohne echte Probleme zu übersehen. Das Monitoring ganz abzuschalten oder den Schwellwert unerreichbar hoch zu setzen macht dich für tatsächliche Engpässe blind."
},
{
"category": "Backup-Strategie",
"hint": "Drei Kopien, zwei Medien, eine extern.",
"text": "Was besagt die 3-2-1-Backup-Regel?",
"answers": [
"Drei Vollbackups, zwei inkrementelle und ein differenzielles Backup pro Woche.",
"Drei Kopien der Daten auf zwei verschiedenen Medientypen, davon eine Kopie an einem externen Standort.",
"Drei Backup-Server, zwei Administratoren und eine Sicherung pro Tag."
],
"correct": 1,
"explanation": "Die 3-2-1-Regel meint: mindestens drei Datenkopien (Original plus zwei Backups) auf zwei unterschiedlichen Medientypen, und eine Kopie räumlich getrennt (offsite) - so übersteht man Hardware-, Standort- und Katastrophenschäden. Die anderen Deutungen mischen die Zahlen mit Backup-Arten oder Personal und treffen die Regel nicht."
},
{
"category": "Backup-Strategie",
"hint": "Immer der komplette Datenbestand.",
"text": "Wodurch ist ein Vollbackup gekennzeichnet?",
"answers": [
"Es sichert nur die seit gestern geänderten Dateien.",
"Es sichert alle Änderungen seit dem letzten Vollbackup.",
"Es sichert bei jedem Durchlauf den gesamten ausgewählten Datenbestand vollständig."
],
"correct": 2,
"explanation": "Ein Vollbackup kopiert jedes Mal alle ausgewählten Daten komplett - dadurch ist der Restore am einfachsten (nur ein Satz nötig), es braucht aber am meisten Speicher und Zeit. Nur geänderte Dateien seit dem letzten Backup sichert das inkrementelle Backup; Änderungen seit dem letzten Vollbackup sichert das differenzielle Backup."
},
{
"category": "Backup-Strategie",
"hint": "Bezugspunkt ist das jeweils letzte Backup.",
"text": "Was sichert ein inkrementelles Backup?",
"answers": [
"Alle Daten, die sich seit dem letzten Backup geändert haben - unabhängig davon, ob dieses ein Voll- oder ein inkrementelles Backup war.",
"Alle Daten, die sich seit dem letzten Vollbackup geändert haben.",
"Grundsätzlich den kompletten Datenbestand, nur stärker komprimiert."
],
"correct": 0,
"explanation": "Das inkrementelle Backup nimmt als Bezugspunkt das letzte Backup beliebigen Typs und sichert nur die seither geänderten Daten - das hält die einzelnen Sicherungen klein und schnell, verlängert aber die Restore-Kette. Der Bezug auf das letzte Vollbackup beschreibt dagegen das differenzielle Backup; ein Komplettbestand wäre ein Vollbackup."
},
{
"category": "Backup-Strategie",
"hint": "Bezugspunkt ist immer das Vollbackup.",
"text": "Ein differenzielles Backup läuft täglich, das Vollbackup lief am Sonntag. Was enthält die Sicherung von Mittwoch?",
"answers": [
"Nur die Änderungen gegenüber der Sicherung von Dienstag.",
"Alle Änderungen seit dem Vollbackup vom Sonntag.",
"Den vollständigen Datenbestand vom Mittwoch."
],
"correct": 1,
"explanation": "Differenzielle Backups beziehen sich stets auf das letzte Vollbackup, also enthält die Mittwoch-Sicherung alle Änderungen seit Sonntag - dadurch wachsen die täglichen Sicherungen bis zum nächsten Vollbackup an. Nur die Differenz zum Vortag zu sichern wäre inkrementell; ein Komplettbestand wäre ein erneutes Vollbackup. Der Restore-Vorteil: Vollbackup plus ein einziges differenzielles Backup genügen."
},
{
"category": "Generationenprinzip",
"hint": "Drei Sicherungsebenen mit verschiedenen Zyklen.",
"text": "Was beschreibt das Großvater-Vater-Sohn-Prinzip bei der Datensicherung?",
"answers": [
"Eine RAID-Konfiguration mit drei gespiegelten Festplatten.",
"Die Reihenfolge, in der Backups verschlüsselt werden.",
"Ein gestaffeltes Rotationsschema mit täglichen, wöchentlichen und monatlichen Sicherungen unterschiedlicher Aufbewahrungsdauer."
],
"correct": 2,
"explanation": "Großvater-Vater-Sohn ist ein Rotationsschema: 'Sohn'-Medien werden täglich, 'Vater' wöchentlich und 'Großvater' monatlich geschrieben und unterschiedlich lange aufbewahrt - so hat man kurz- und langfristige Wiederherstellungspunkte bei überschaubarer Medienzahl. Mit RAID (Redundanz im laufenden Betrieb) oder Verschlüsselung hat das Prinzip nichts zu tun."
},
{
"category": "Generationenprinzip",
"hint": "Sohn ist der kurzlebigste Stand.",
"text": "Welche Zuordnung von Generation und Zyklus ist beim Großvater-Vater-Sohn-Prinzip üblich?",
"answers": [
"Sohn = tägliche Sicherung, Vater = wöchentliche Sicherung, Großvater = monatliche Sicherung.",
"Sohn = monatliche Sicherung, Vater = wöchentliche Sicherung, Großvater = tägliche Sicherung.",
"Sohn = jährliche Sicherung, Vater = monatliche Sicherung, Großvater = tägliche Sicherung."
],
"correct": 0,
"explanation": "Der 'Sohn' ist der jüngste, am häufigsten überschriebene Stand (täglich), der 'Vater' fasst die Woche zusammen, der 'Großvater' den Monat und wird am längsten aufbewahrt. Die vertauschten Varianten drehen die Zyklen um - der jüngste Stand darf gerade nicht am seltensten geschrieben werden."
},
{
"category": "Generationenprinzip",
"hint": "Ältere Generationen leben länger.",
"text": "Wie werden die Medien im Generationenprinzip typischerweise aufbewahrt und wiederverwendet?",
"answers": [
"Alle Medien werden nach genau einem Tag gelöscht und sofort überschrieben.",
"Tägliche Medien werden schnell wieder überschrieben, wöchentliche und monatliche dagegen deutlich länger aufbewahrt.",
"Monatliche Sicherungen werden am schnellsten überschrieben, um Platz zu sparen."
],
"correct": 1,
"explanation": "Je höher die Generation, desto länger die Aufbewahrung: Tagesmedien rotieren schnell, Wochen- und Monatsmedien bleiben länger erhalten und liefern ältere Wiederherstellungspunkte. Alles nach einem Tag zu löschen zerstört die Langzeitstände, und ausgerechnet die Monatssicherung zuerst zu überschreiben widerspricht dem Zweck des Prinzips."
},
{
"category": "Generationenprinzip",
"hint": "Nicht nur der letzte Stand zählt.",
"text": "Welchen Vorteil bietet das Generationenprinzip gegenüber dem ständigen Überschreiben nur einer einzigen Sicherung?",
"answers": [
"Es benötigt grundsätzlich weniger Speicher als eine einzelne Sicherung.",
"Es macht ein externes Offsite-Backup vollständig überflüssig.",
"Es hält mehrere zeitlich gestaffelte Wiederherstellungspunkte vor, sodass man auch auf ältere Datenstände zurückgreifen kann."
],
"correct": 2,
"explanation": "Mit gestaffelten Generationen kann man einen Fehler auch dann noch beheben, wenn er erst nach Tagen oder Wochen auffällt - etwa bei spät entdeckter Datenkorruption oder Verschlüsselung durch Ransomware. Es braucht dafür mehr statt weniger Medien und ersetzt kein Offsite-Backup; beide Maßnahmen ergänzen sich."
},
{
"category": "Wiederherstellung",
"hint": "Wie lange darf der Ausfall dauern?",
"text": "Was gibt die Recovery Time Objective (RTO) an?",
"answers": [
"Die maximal tolerierbare Zeitspanne, bis ein System nach einem Ausfall wieder verfügbar sein muss.",
"Die maximal tolerierbare Menge an Daten, die bei einem Ausfall verloren gehen darf.",
"Den Zeitpunkt, zu dem das nächste Vollbackup geplant ist."
],
"correct": 0,
"explanation": "Die RTO ist die Zielvorgabe für die Wiederanlaufzeit - wie lange darf es maximal dauern, bis der Betrieb wieder läuft? Die maximal tolerierte Datenverlustmenge beschreibt dagegen die RPO; mit dem Zeitplan des nächsten Backups hat die RTO nichts zu tun."
},
{
"category": "Wiederherstellung",
"hint": "Wie viele Daten darf ich verlieren?",
"text": "Ein Kunde verlangt eine RPO von einer Stunde. Was bedeutet das für deine Backup-Planung?",
"answers": [
"Das System muss innerhalb einer Stunde nach dem Ausfall wieder laufen.",
"Es darf höchstens der Datenbestand einer Stunde verloren gehen, also musst du mindestens stündlich sichern.",
"Das Backup darf maximal eine Stunde lang laufen."
],
"correct": 1,
"explanation": "Die RPO (Recovery Point Objective) legt den maximal zulässigen Datenverlust fest; eine RPO von einer Stunde erzwingt Sicherungsintervalle von höchstens einer Stunde. Die Wiederanlaufzeit beschreibt die RTO, und die reine Laufzeit eines Backups ist damit nicht gemeint."
},
{
"category": "Wiederherstellung",
"hint": "Ein Backup, das man nie zurückspielt, ist wertlos.",
"text": "Warum sind regelmäßige Restore-Tests wichtig, obwohl die Backups laut Protokoll fehlerfrei durchlaufen?",
"answers": [
"Weil Restore-Tests die Backups automatisch verschlüsseln.",
"Weil ohne Restore-Test kein Vollbackup erstellt werden kann.",
"Weil ein erfolgreiches Backup-Protokoll nicht garantiert, dass sich die Daten auch tatsächlich vollständig und brauchbar wiederherstellen lassen."
],
"correct": 2,
"explanation": "Erst der Restore beweist, dass Medien lesbar, Datensätze konsistent und Abläufe dokumentiert sind - defekte Medien, fehlende Datenbank-Konsistenz oder unklare Prozesse fallen sonst erst im Ernstfall auf. Restore-Tests verschlüsseln nichts und sind keine Voraussetzung für ein Vollbackup; sie prüfen ausschließlich die Wiederherstellbarkeit."
},
{
"category": "Wiederherstellung",
"hint": "Vollbackup plus alle Zwischenschritte.",
"text": "Am Sonntag lief ein Vollbackup, Montag bis Freitag jeweils inkrementell. Freitagabend fällt die Platte aus. Welche Sicherungen brauchst du zur vollständigen Wiederherstellung?",
"answers": [
"Nur das inkrementelle Backup von Freitag.",
"Das Vollbackup vom Sonntag und alle inkrementellen Backups von Montag bis Freitag in Reihenfolge.",
"Nur das Vollbackup vom Sonntag."
],
"correct": 1,
"explanation": "Da jedes inkrementelle Backup nur die Änderungen seit dem vorherigen Backup enthält, brauchst du das Vollbackup als Basis und lückenlos alle inkrementellen Sicherungen in der richtigen Reihenfolge - fehlt eine, ist die Kette unterbrochen. Das ist der Preis der schnellen inkrementellen Sicherung; bei differenziellen Backups genügte das Vollbackup plus die letzte Sicherung."
},
{
"category": "Serverdimensionierung",
"hint": "Nicht auf Kante nähen.",
"text": "Warum plant man bei der Serverdimensionierung bewusst Kapazitätsreserven bei Speicher und Rechenleistung ein?",
"answers": [
"Um Lastspitzen und künftiges Wachstum abzufangen, ohne dass das System sofort an seine Grenzen stößt.",
"Weil ein Server ohne freie Reserve gar nicht startet.",
"Weil Reserven die Lizenzkosten der Software senken."
],
"correct": 0,
"explanation": "Reserven fangen Spitzenlasten, Datenwachstum und zusätzliche Dienste ab und verhindern, dass schon der normale Betrieb ein teures Upgrade erzwingt - üblich ist, nicht dauerhaft nahe 100 % Auslastung zu fahren. Ein Server startet auch ohne freie Reserve, und die Lizenzkosten sinken dadurch nicht, sie steigen mit mehr Ressourcen eher."
},
{
"category": "Serverdimensionierung",
"hint": "Verfügbarkeit trotz Plattenausfall.",
"text": "Welche Maßnahme erhöht die Verfügbarkeit der Datenspeicherung in einem Server durch Redundanz?",
"answers": [
"Der Einsatz einer einzelnen, besonders großen Festplatte.",
"Das Deaktivieren aller Hintergrunddienste.",
"Der Einsatz eines RAID-Verbundes, der den Ausfall einzelner Festplatten ohne Datenverlust überbrückt."
],
"correct": 2,
"explanation": "RAID-Level wie 1, 5, 6 oder 10 verteilen Daten redundant, sodass beim Ausfall einer (bei RAID 6 zweier) Platten weitergearbeitet werden kann - das erhöht die Ausfallsicherheit. Eine einzelne große Platte bündelt das Risiko, und das Abschalten von Diensten spart Last, schafft aber keine Redundanz. Wichtig: RAID ersetzt kein Backup."
},
{
"category": "Serverdimensionierung",
"hint": "Kennzahl für die Speicher-Leistung.",
"text": "Welche Kennzahl ist bei der Dimensionierung eines Storage-Systems für eine datenbanklastige Anwendung besonders relevant?",
"answers": [
"Die Gehäusefarbe des Servers.",
"Die IOPS (Ein-/Ausgabeoperationen pro Sekunde), da Datenbanken viele kleine, wahlfreie Zugriffe erzeugen.",
"Die Anzahl der USB-Anschlüsse am Server."
],
"correct": 1,
"explanation": "Datenbanken erzeugen viele kleine, wahlfreie Lese- und Schreibzugriffe; hier entscheiden die IOPS über die Leistung, weshalb oft SSDs statt klassischer HDDs gewählt werden. Gehäusefarbe und USB-Anzahl sind für die Leistungsdimensionierung völlig irrelevant."
},
{
"category": "Serverdimensionierung",
"hint": "Eine Komponente mehr als nötig.",
"text": "Was bedeutet eine N+1-Redundanz, etwa bei den Netzteilen eines Servers?",
"answers": [
"Es ist eine Komponente mehr vorhanden als für den Betrieb nötig, sodass der Ausfall einer einzelnen Komponente kompensiert wird.",
"Es sind genau so viele Komponenten vorhanden, wie für den Betrieb rechnerisch nötig sind.",
"Es ist die doppelte Anzahl aller Komponenten vorhanden, unabhängig vom tatsächlichen Bedarf."
],
"correct": 0,
"explanation": "N+1 heißt: zu den N benötigten Einheiten kommt eine zusätzliche Reserve, die bei Ausfall einer Einheit einspringt - etwa ein zweites Netzteil, das die Last allein trägt. Genau N Komponenten hätten keine Reserve, und die glatte Verdopplung entspräche eher 2N beziehungsweise voller Redundanz."
}
]
}
@@ -0,0 +1,245 @@
{
"title": "Netzwerkplanung",
"questions": [
{
"category": "Subnetting & VLSM",
"hint": "Host-Bits zählen.",
"text": "Du sollst 192.168.10.0/24 in Subnetze mit jeweils mindestens 50 nutzbaren Hosts aufteilen. Welche Maske ist passend und zugleich am sparsamsten?",
"answers": [
"/26 (255.255.255.192)",
"/25 (255.255.255.128)",
"/27 (255.255.255.224)"
],
"correct": 0,
"explanation": "6 Host-Bits ergeben 2^6−2 = 62 nutzbare Hosts – das reicht für 50 und ist am sparsamsten. /25 verschenkt Adressen (126 Hosts), /27 bietet nur 30 Hosts und ist zu klein."
},
{
"category": "Subnetting & VLSM",
"hint": "2 hoch Host-Bits, minus zwei.",
"text": "Wie viele nutzbare Host-Adressen bietet ein /29-Subnetz?",
"answers": [
"8",
"6",
"14"
],
"correct": 1,
"explanation": "/29 lässt 3 Host-Bits: 2^3 = 8 Adressen, abzüglich Netz- und Broadcast-Adresse bleiben 6 nutzbare. 8 ist die Gesamtzahl inklusive Netz und Broadcast, 14 gehört zu /28."
},
{
"category": "Subnetting & VLSM",
"hint": "Blockgröße der Maske bestimmen.",
"text": "Zu welchem Subnetz gehört die Host-Adresse 172.16.20.130/26?",
"answers": [
"172.16.20.0/26",
"172.16.20.64/26",
"172.16.20.128/26"
],
"correct": 2,
"explanation": "Bei /26 ist die Blockgröße 64, die Netzgrenzen liegen bei .0, .64, .128, .192. Die 130 fällt in den Block ab .128; die Blöcke .0 und .64 enden schon vor 130."
},
{
"category": "Subnetting & VLSM",
"hint": "Vom größten Bedarf her planen.",
"text": "Warum vergibt man bei VLSM die Subnetze in absteigender Reihenfolge der benötigten Host-Anzahl?",
"answers": [
"Weil so der Adressraum lückenlos genutzt wird und keine passenden Blöcke zerschnitten werden.",
"Weil größere Subnetze zwingend niedrigere Netzadressen brauchen.",
"Weil kleine Subnetze sonst keinen Broadcast bilden können."
],
"correct": 0,
"explanation": "Größte Netze zuerst zu vergeben verhindert Fragmentierung – kleine Netze passen danach genau in die Restblöcke. Die Adresslage folgt nicht der Größe, und der Broadcast hängt nicht von der Vergabereihenfolge ab."
},
{
"category": "Subnetting & VLSM",
"hint": "Broadcast ist die letzte Adresse im Block.",
"text": "Wie lautet die Broadcast-Adresse des Subnetzes 10.0.5.0/27?",
"answers": [
"10.0.5.32",
"10.0.5.31",
"10.0.5.63"
],
"correct": 1,
"explanation": "/27 hat die Blockgröße 32, das erste Subnetz reicht von .0 bis .31; der Broadcast ist die letzte Adresse .31. Die .32 ist bereits die Netzadresse des nächsten Subnetzes, die .63 der Broadcast des zweiten Blocks."
},
{
"category": "IPv6",
"hint": "Führende Nullen und eine Nullfolge kürzen.",
"text": "Wie lautet die korrekt gekürzte Schreibweise von 2001:0db8:0000:0000:0000:ff00:0042:8329?",
"answers": [
"2001:db8:0:0:0:ff00:42:8329::",
"2001::db8::ff00:42:8329",
"2001:db8::ff00:42:8329"
],
"correct": 2,
"explanation": "Führende Nullen jeder Gruppe entfallen, eine zusammenhängende Nullfolge wird einmal durch :: ersetzt. Ein zweites :: ist unzulässig, und ein zusätzliches :: am Ende ist hier überflüssig und falsch platziert."
},
{
"category": "IPv6",
"hint": "Gültigkeit nur auf dem lokalen Link.",
"text": "Wofür wird eine IPv6-Link-Local-Adresse (fe80::/10) verwendet?",
"answers": [
"Für die Kommunikation ausschließlich innerhalb desselben Netzsegments, z. B. für Neighbor Discovery.",
"Für die weltweit eindeutige Erreichbarkeit im Internet.",
"Als Ersatz für private IPv4-Adressen mit NAT ins Internet."
],
"correct": 0,
"explanation": "Link-Local-Adressen gelten nur auf dem lokalen Link und werden nicht geroutet – u. a. für Neighbor Discovery und Autokonfiguration. Global erreichbar sind Global-Unicast-Adressen (2000::/3); NAT ist typisch für IPv4."
},
{
"category": "IPv6",
"hint": "Standard-Präfix pro Segment.",
"text": "Welche Präfixlänge ist für ein einzelnes LAN-Segment in IPv6 üblich und für SLAAC vorgesehen?",
"answers": [
"/48",
"/64",
"/128"
],
"correct": 1,
"explanation": "/64 ist das Standardpräfix pro Segment; die unteren 64 Bit bilden den Interface-Identifier (SLAAC). /48 ist eine typische Standort-Zuteilung, /128 bezeichnet eine einzelne Host-Adresse."
},
{
"category": "IPv6",
"hint": "IPv6 kennt keinen Broadcast.",
"text": "Was übernimmt in IPv6 die Aufgaben der aus IPv4 bekannten Broadcast-Adresse?",
"answers": [
"Eine reservierte Broadcast-Adresse am Ende jedes /64-Netzes.",
"Anycast-Adressen an den jeweils nächstgelegenen Empfänger.",
"Multicast-Adressen (ff00::/8) an definierte Empfängergruppen."
],
"correct": 2,
"explanation": "IPv6 hat keinen Broadcast; seine Aufgaben übernehmen Multicast-Gruppen (ff00::/8), etwa all-nodes ff02::1. Anycast liefert an genau einen (den nächsten) von mehreren gleichen Zielen; eine Broadcast-Adresse gibt es nicht mehr."
},
{
"category": "WLAN-Planung",
"hint": "Überlappungsfreie Kanäle im 2,4-GHz-Band.",
"text": "Welche Kanäle im 2,4-GHz-Band überlappen sich in Europa nicht und eignen sich für benachbarte Access Points?",
"answers": [
"1, 6 und 11",
"1, 5 und 9",
"2, 7 und 12"
],
"correct": 0,
"explanation": "Wegen 20 MHz Kanalbreite bei nur 5 MHz Kanalabstand sind im 2,4-GHz-Band nur 1, 6 und 11 überlappungsfrei. Die anderen Kombinationen liegen zu dicht beieinander und stören sich."
},
{
"category": "WLAN-Planung",
"hint": "Gleiche SSID, mehrere Sender.",
"text": "Mehrere Access Points sollen dieselbe SSID ausstrahlen, damit Clients nahtlos wechseln. Worauf ist bei der Planung besonders zu achten?",
"answers": [
"Alle APs müssen denselben Funkkanal verwenden, damit Roaming funktioniert.",
"Benachbarte APs sollten überlappungsfreie Kanäle nutzen und sich in der Ausleuchtung leicht überlappen.",
"Jeder AP braucht ein eigenes VLAN, sonst ist Roaming nicht möglich."
],
"correct": 1,
"explanation": "Für sauberes Roaming überlappen sich die Funkzellen leicht, benachbarte APs funken aber auf verschiedenen, überlappungsfreien Kanälen (Co-Channel-Interference vermeiden). Gleicher Kanal überall stört; ein eigenes VLAN je AP ist für Roaming nicht nötig."
},
{
"category": "WLAN-Planung",
"hint": "Aktueller Standard mit Benutzer-Authentisierung.",
"text": "Welches Verfahren solltest du für ein neu geplantes Firmen-WLAN vorsehen?",
"answers": [
"WEP mit 128-Bit-Schlüssel für maximale Kompatibilität.",
"WPA2-Personal mit einem gemeinsamen Passwort für alle.",
"WPA3-Enterprise mit Authentisierung pro Benutzer über einen RADIUS-Server."
],
"correct": 2,
"explanation": "WPA3-Enterprise mit RADIUS (802.1X) authentisiert jeden Benutzer einzeln und ist der aktuelle Stand für Firmennetze. WPA2-Personal teilt ein Passwort für alle (schlecht sperrbar), WEP gilt seit Langem als gebrochen."
},
{
"category": "WLAN-Planung",
"hint": "Mehr Kanäle, aber kürzere Reichweite.",
"text": "Ein Kunde klagt über volle 2,4-GHz-Kanäle. Welcher Vorteil spricht für den Einsatz des 5-GHz-Bandes?",
"answers": [
"Es bietet mehr überlappungsfreie Kanäle und weniger Störungen, hat aber geringere Reichweite und Wanddurchdringung.",
"Es hat eine deutlich größere Reichweite als 2,4 GHz bei gleicher Sendeleistung.",
"Es benötigt keine Kanalplanung, weil sich 5-GHz-Kanäle nie überlappen."
],
"correct": 0,
"explanation": "5 GHz stellt viele überlappungsfreie Kanäle bereit und ist weniger überlastet, wird von Wänden aber stärker gedämpft. Die Reichweite ist geringer statt größer; wegen DFS bleibt eine Kanalplanung nötig."
},
{
"category": "Routing",
"hint": "Längste Übereinstimmung gewinnt.",
"text": "Ein Router kennt Routen zu 10.0.0.0/8, 10.1.0.0/16 und 10.1.5.0/24. An welche stellt er ein Paket an 10.1.5.20 zu?",
"answers": [
"An 10.0.0.0/8, weil es die erste passende Route ist.",
"An 10.1.5.0/24 nach dem Longest-Prefix-Match.",
"An 10.1.0.0/16, weil sie in der Mitte liegt."
],
"correct": 1,
"explanation": "Router wählen immer die spezifischste passende Route (längstes Präfix). /24 passt genauer als /16 oder /8. Die Reihenfolge in der Tabelle spielt beim Longest-Prefix-Match keine Rolle."
},
{
"category": "Routing",
"hint": "Von Hand eingetragen vs. selbstlernend.",
"text": "Worin unterscheidet sich statisches von dynamischem Routing?",
"answers": [
"Statisches Routing funktioniert nur mit IPv6, dynamisches nur mit IPv4.",
"Dynamisches Routing kommt ohne Router aus, statisches braucht immer Router.",
"Statische Routen trägt der Administrator manuell ein; dynamische lernen die Router über Protokolle wie OSPF selbst und passen sich an."
],
"correct": 2,
"explanation": "Statische Routen sind fest konfiguriert, dynamische werden per Routing-Protokoll (OSPF, RIP, BGP) ausgetauscht und reagieren auf Ausfälle. Die Protokollwahl ist unabhängig von IPv4/IPv6, und beide Varianten laufen auf Routern."
},
{
"category": "Routing",
"hint": "Auffangbecken für unbekannte Ziele.",
"text": "Wofür dient die Default-Route 0.0.0.0/0 in einer Routing-Tabelle?",
"answers": [
"Sie legt fest, wohin Pakete gehen, für die keine spezifischere Route existiert – meist zum Internet-Gateway.",
"Sie blockiert alle Pakete an unbekannte Ziele.",
"Sie beschreibt ausschließlich das direkt angeschlossene lokale Netz."
],
"correct": 0,
"explanation": "Passt keine spezifischere Route, geht das Paket über die Default-Route (meist zum Gateway/Provider). Sie blockiert nichts und meint nicht das lokale Netz – das steht als direkt verbundene Route in der Tabelle."
},
{
"category": "Routing",
"hint": "Link-State-Protokoll im eigenen Netz.",
"text": "Welches Routing-Protokoll ist ein Link-State-Protokoll und als Interior Gateway innerhalb eines Unternehmensnetzes typisch?",
"answers": [
"BGP",
"OSPF",
"RIPv1"
],
"correct": 1,
"explanation": "OSPF ist ein Link-State-IGP, das per Dijkstra kürzeste Pfade berechnet und schnell konvergiert. BGP verbindet autonome Systeme (Internet), RIPv1 ist ein veraltetes Distanzvektor-Protokoll mit 15-Hop-Grenze."
},
{
"category": "Adressierung & Planung",
"hint": "RFC 1918 – private Bereiche.",
"text": "Welcher Adressbereich ist laut RFC 1918 für private Netze reserviert?",
"answers": [
"169.254.0.0 – 169.254.255.255",
"100.64.0.0 – 100.127.255.255",
"172.16.0.0 – 172.31.255.255"
],
"correct": 2,
"explanation": "Zu den privaten Bereichen zählt 172.16.0.0/12 (172.16.–172.31.). 169.254.0.0/16 ist APIPA/Link-Local, 100.64.0.0/10 der Carrier-Grade-NAT-Bereich – beide sind keine RFC-1918-Netze."
},
{
"category": "Adressierung & Planung",
"hint": "Wachstum von Anfang an einplanen.",
"text": "Warum plant man bei der Adressvergabe für Subnetze bewusst Reserve-Hosts ein?",
"answers": [
"Damit spätere Erweiterungen möglich sind, ohne das Netz neu segmentieren zu müssen.",
"Weil sonst der Broadcast nicht funktioniert.",
"Weil DHCP mindestens die Hälfte aller Adressen frei benötigt."
],
"correct": 0,
"explanation": "Reserven fangen künftiges Wachstum ab und ersparen ein Re-Design bei neuen Geräten. Der Broadcast funktioniert unabhängig von Reserven, und DHCP braucht keine feste 50-%-Freiquote."
},
{
"category": "Adressierung & Planung",
"hint": "Gleiches Netz oder über das Gateway?",
"text": "Ein Host hat 192.168.1.10/24, sein Gateway ist 192.168.1.1. Warum erreicht er 10.0.0.5 nicht direkt, sondern nur über das Gateway?",
"answers": [
"Weil 10.0.0.5 eine öffentliche Adresse ist und darum immer per NAT übersetzt werden muss.",
"Weil 10.0.0.5 in einem anderen Netz liegt und Pakete in fremde Netze über das Gateway geroutet werden.",
"Weil /24-Netze grundsätzlich keine direkte Kommunikation erlauben."
],
"correct": 1,
"explanation": "Der Host vergleicht Ziel-IP und eigene Maske: 10.0.0.5 liegt außerhalb von 192.168.1.0/24, also schickt er das Paket an das Gateway. 10.0.0.0/8 ist zudem privat (kein Zwang zu NAT), und innerhalb eines /24 ist direkte Kommunikation gerade möglich."
}
]
}
@@ -0,0 +1,245 @@
{
"title": "Skripting",
"questions": [
{
"category": "Shell-Grundlagen",
"hint": "Leerzeichen und Dollarzeichen beachten.",
"text": "Wie weist du in Bash der Variablen NAME korrekt den Wert server01 zu?",
"answers": [
"NAME=\"server01\" (ohne Leerzeichen um das Gleichheitszeichen)",
"NAME = \"server01\"",
"$NAME = \"server01\""
],
"correct": 0,
"explanation": "In Bash darf um das Gleichheitszeichen kein Leerzeichen stehen, sonst deutet die Shell NAME als Kommando. Beim Zuweisen schreibst du den Variablennamen ohne Dollarzeichen; das Dollarzeichen dient nur dem späteren Auslesen mit $NAME."
},
{
"category": "Shell-Grundlagen",
"hint": "Ausgabe wird zur Eingabe.",
"text": "Was bewirkt der Pipe-Operator | in einer Bash-Zeile wie ls -l | grep txt?",
"answers": [
"Er führt beide Kommandos vollkommen unabhängig nacheinander aus.",
"Er leitet die Ausgabe in eine Datei namens grep um.",
"Er verbindet die Standardausgabe des ersten Kommandos mit der Standardeingabe des zweiten."
],
"correct": 2,
"explanation": "Eine Pipe reicht die Standardausgabe (stdout) des linken Kommandos direkt als Standardeingabe (stdin) an das rechte weiter, ganz ohne Zwischendatei. Ein Semikolon würde Kommandos nur nacheinander ausführen, und für eine Umleitung in eine Datei wäre > mit einem Dateinamen nötig."
},
{
"category": "Shell-Grundlagen",
"hint": "Anhängen statt überschreiben.",
"text": "Womit hängst du die Ausgabe eines Kommandos an die bestehende Datei log.txt an, ohne deren Inhalt zu löschen?",
"answers": [
"kommando > log.txt",
"kommando >> log.txt",
"kommando < log.txt"
],
"correct": 1,
"explanation": "Der doppelte Pfeil >> hängt die Ausgabe an das Dateiende an und erhält den bisherigen Inhalt. Ein einfaches > überschreibt die Datei vollständig, und < ist eine Eingabeumleitung, die den Dateiinhalt als stdin in das Kommando einliest."
},
{
"category": "Shell-Grundlagen",
"hint": "Kommandosubstitution.",
"text": "Wie speicherst du in Bash die Ausgabe des Kommandos date in der Variablen JETZT?",
"answers": [
"JETZT=$(date)",
"JETZT=date",
"JETZT=|date|"
],
"correct": 0,
"explanation": "Mit der Kommandosubstitution $(date) wird das Kommando ausgeführt und sein Ergebnis in die Variable geschrieben; die ältere Schreibweise mit Backticks leistet dasselbe. JETZT=date würde nur die Zeichenkette date speichern, und |date| ist keine gültige Syntax."
},
{
"category": "PowerShell",
"hint": "Tätigkeit und Objekt.",
"text": "Nach welchem Namensschema sind PowerShell-Cmdlets aufgebaut?",
"answers": [
"Nomen-Verb, zum Beispiel Service-Get",
"Verb-Nomen, zum Beispiel Get-Service",
"nur ein Verb, zum Beispiel Get"
],
"correct": 1,
"explanation": "PowerShell-Cmdlets folgen dem Muster Verb-Nomen (Verb-Noun) wie Get-Service oder Stop-Process und nutzen anerkannte Verben wie Get, Set oder New. Die Reihenfolge Nomen-Verb ist falsch, und ein Cmdlet besteht nie nur aus dem Verb allein."
},
{
"category": "PowerShell",
"hint": "Objekte statt Text.",
"text": "Worin unterscheidet sich die PowerShell-Pipeline grundlegend von einer klassischen Bash-Pipe?",
"answers": [
"PowerShell übergibt ausschließlich reinen Text Zeile für Zeile.",
"PowerShell kann gar keine Kommandos verketten.",
"PowerShell reicht strukturierte Objekte mit Eigenschaften weiter statt reinen Text."
],
"correct": 2,
"explanation": "In der PowerShell-Pipeline fließen vollständige .NET-Objekte mit Eigenschaften und Methoden, sodass nachfolgende Cmdlets gezielt auf einzelne Felder zugreifen können. Die reine Textübergabe Zeile für Zeile ist typisch für Bash, und Verkettung ist in PowerShell selbstverständlich möglich."
},
{
"category": "PowerShell",
"hint": "Nach Bedingung filtern.",
"text": "Mit welchem Cmdlet filterst du in einer PowerShell-Pipeline Objekte nach einer Bedingung, etwa nur laufende Dienste?",
"answers": [
"Where-Object",
"ForEach-Object",
"Select-Object"
],
"correct": 0,
"explanation": "Where-Object filtert die Objekte anhand einer Bedingung und lässt nur die passenden passieren, etwa Where-Object Status -eq 'Running'. ForEach-Object führt für jedes Objekt eine Aktion aus, und Select-Object wählt Eigenschaften aus oder begrenzt die Anzahl, prüft aber keine Bedingung."
},
{
"category": "PowerShell",
"hint": "Eigenschaften auswählen.",
"text": "Was bewirkt Get-Process | Select-Object Name, CPU in PowerShell?",
"answers": [
"Es beendet die Prozesse mit den Namen Name und CPU.",
"Es gibt von jedem Prozess nur die Eigenschaften Name und CPU aus.",
"Es sortiert die Prozesse nach Name und CPU."
],
"correct": 1,
"explanation": "Select-Object mit einer Eigenschaftsliste reduziert die Ausgabe auf genau diese Felder jedes Objekts, hier Name und CPU. Das Sortieren übernimmt Sort-Object, und zum Beenden von Prozessen dient Stop-Process."
},
{
"category": "Kontrollstrukturen & Pseudocode",
"hint": "Grenzen der Zählschleife durchgehen.",
"text": "Wie oft wird die Schleife for (i = 1; i <= 5; i = i + 1) durchlaufen?",
"answers": [
"unendlich oft",
"4-mal",
"5-mal"
],
"correct": 2,
"explanation": "Die Zählschleife startet bei 1 und läuft, solange i kleiner oder gleich 5 ist, also für die Werte 1, 2, 3, 4 und 5 – das sind fünf Durchläufe. Weil i bei jedem Schritt erhöht wird, endet die Schleife und läuft nicht unendlich; vier Durchläufe ergäben sich erst bei der Bedingung i < 5."
},
{
"category": "Kontrollstrukturen & Pseudocode",
"hint": "Wann wird die Bedingung geprüft?",
"text": "Was ist charakteristisch für eine kopfgesteuerte while-Schleife?",
"answers": [
"Die Bedingung wird vor jedem Durchlauf geprüft, daher kann der Rumpf auch gar nicht ausgeführt werden.",
"Der Rumpf wird immer mindestens einmal ausgeführt, weil die Bedingung erst am Ende geprüft wird.",
"Sie zählt automatisch eine Schleifenvariable hoch."
],
"correct": 0,
"explanation": "Bei der kopfgesteuerten while-Schleife steht die Bedingungsprüfung am Anfang; ist sie schon zu Beginn falsch, wird der Rumpf keinmal durchlaufen. Die garantierte mindestens einmalige Ausführung ist Merkmal der fußgesteuerten do-while-Schleife, und ein automatisches Hochzählen leistet nur eine Zählschleife wie for."
},
{
"category": "Kontrollstrukturen & Pseudocode",
"hint": "Fallunterscheidung, keine Wiederholung.",
"text": "Welche Kontrollstruktur wählst du im Pseudocode, um abhängig vom Wert einer Variablen zwischen mehreren Fällen zu verzweigen?",
"answers": [
"eine while-Schleife",
"eine if-elseif-else-Verzweigung",
"eine for-Schleife"
],
"correct": 1,
"explanation": "Fallunterscheidungen bildest du mit if-elseif-else (oder alternativ einer switch-Anweisung) ab, die je nach Bedingung genau einen Zweig ausführt. Schleifen wie while oder for dienen dem Wiederholen von Anweisungen, nicht der einmaligen Verzweigung."
},
{
"category": "Kontrollstrukturen & Pseudocode",
"hint": "Ist die Anzahl bekannt?",
"text": "Wann setzt du sinnvollerweise eine Zählschleife (for) statt einer while-Schleife ein?",
"answers": [
"Wenn die Anzahl der Durchläufe von vornherein bekannt ist.",
"Wenn die Schleife auf jeden Fall unendlich laufen soll.",
"Wenn die Bedingung niemals geprüft werden darf."
],
"correct": 0,
"explanation": "Die for-Schleife eignet sich, wenn die Zahl der Wiederholungen vorab feststeht, etwa für jedes Element von 1 bis n. Eine while-Schleife passt besser, wenn nur eine Abbruchbedingung, aber keine feste Anzahl bekannt ist; eine bewusst endlose Schleife oder gar keine Prüfung ist kein Auswahlkriterium für for."
},
{
"category": "Automatisierung",
"hint": "Fünf Felder vor dem Befehl.",
"text": "In welcher Reihenfolge stehen die fünf Zeitfelder eines klassischen Cron-Eintrags?",
"answers": [
"Stunde, Minute, Monat, Tag, Wochentag",
"Tag, Monat, Wochentag, Stunde, Minute",
"Minute, Stunde, Tag des Monats, Monat, Wochentag"
],
"correct": 2,
"explanation": "Ein Cron-Eintrag ordnet die Felder als Minute, Stunde, Tag des Monats, Monat und Wochentag, gefolgt vom auszuführenden Befehl. Die anderen Reihenfolgen vertauschen die Felder und würden zu völlig falschen Ausführungszeiten führen."
},
{
"category": "Automatisierung",
"hint": "Minute und Stunde lesen.",
"text": "Zu welcher Zeit führt der Cron-Ausdruck 30 2 * * * ein Backup-Skript aus?",
"answers": [
"alle 30 Sekunden rund um die Uhr",
"täglich um 02:30 Uhr",
"jeden 30. Tag des Monats um 2 Uhr"
],
"correct": 1,
"explanation": "Die Felder bedeuten Minute 30 und Stunde 2, während die drei Sterne für jeden Tag, jeden Monat und jeden Wochentag stehen – das Skript läuft also täglich um 02:30 Uhr. Cron kennt keine Sekunden, und der Tag des Monats steht hier auf *, nicht auf 30."
},
{
"category": "Automatisierung",
"hint": "Windows-Bordmittel.",
"text": "Womit richtest du unter Windows eine zeitgesteuerte Aufgabe ein, die auch ohne angemeldeten Benutzer läuft?",
"answers": [
"mit der Aufgabenplanung (Taskplaner) bzw. dem Kommando schtasks",
"mit dem crontab-Editor",
"mit dem Kommando systemctl für einen systemd-Timer"
],
"correct": 0,
"explanation": "Unter Windows übernimmt die Aufgabenplanung (Task Scheduler), bedienbar per GUI oder dem Kommando schtasks, das zeitgesteuerte Ausführen von Aufgaben auch ohne angemeldeten Benutzer. crontab gehört zu Unix/Linux, und systemd-Timer über systemctl sind ebenfalls eine Linux-Lösung."
},
{
"category": "Automatisierung",
"hint": "Schrittwert im Minutenfeld.",
"text": "Wie gibst du in Cron an, dass ein Skript alle 15 Minuten laufen soll?",
"answers": [
"15 * * * *",
"* 15 * * *",
"*/15 * * * *"
],
"correct": 2,
"explanation": "Der Schrittwert */15 im Minutenfeld startet die Ausführung zu den Minuten 0, 15, 30 und 45 jeder Stunde. Der Ausdruck 15 * * * * würde nur einmal pro Stunde zur Minute 15 laufen, und * 15 * * * bezöge sich auf die Stunde 15, also 15 Uhr."
},
{
"category": "Exit-Codes & Fehlerbehandlung",
"hint": "Erfolg hat einen festen Wert.",
"text": "Welchen Exit-Code (Rückgabewert) liefert ein Programm üblicherweise, wenn es fehlerfrei durchgelaufen ist?",
"answers": [
"0",
"1",
"-1"
],
"correct": 0,
"explanation": "Nach Konvention steht der Exit-Code 0 für einen erfolgreichen Ablauf, während jeder Wert ungleich 0 einen Fehler oder eine besondere Bedingung signalisiert. Der Wert 1 ist ein typischer allgemeiner Fehlercode, und negative Werte sind als reguläre Exit-Codes (Bereich 0 bis 255) nicht vorgesehen."
},
{
"category": "Exit-Codes & Fehlerbehandlung",
"hint": "Rückgabewert des letzten Kommandos.",
"text": "Was liest du in Bash mit der Variablen $? aus?",
"answers": [
"den Namen des zuletzt ausgeführten Kommandos",
"den Exit-Code des zuletzt beendeten Kommandos",
"die Prozess-ID der aktuellen Shell"
],
"correct": 1,
"explanation": "$? enthält den Exit-Code des zuletzt beendeten Kommandos und erlaubt es, dessen Erfolg unmittelbar danach zu prüfen. Die Prozess-ID der aktuellen Shell steht in $$, und den Kommandonamen liefert $? nicht."
},
{
"category": "Exit-Codes & Fehlerbehandlung",
"hint": "Deskriptor 2.",
"text": "Wie leitest du in Bash nur die Fehlermeldungen (Standardfehlerausgabe) eines Kommandos in die Datei fehler.log um?",
"answers": [
"kommando > fehler.log",
"kommando 1> fehler.log",
"kommando 2> fehler.log"
],
"correct": 2,
"explanation": "Der Standardfehlerkanal (stderr) hat den Dateideskriptor 2, daher schreibt 2> ausschließlich die Fehlermeldungen in die Datei. Ein einfaches > oder 1> bezieht sich auf die Standardausgabe (stdout, Deskriptor 1) und lässt Fehlermeldungen weiterhin auf dem Bildschirm erscheinen."
},
{
"category": "Exit-Codes & Fehlerbehandlung",
"hint": "Fehler abfangen.",
"text": "Mit welchem Mittel behandelst du in einem PowerShell-Skript Laufzeitfehler gezielt, um bei einem Problem eigene Schritte auszuführen?",
"answers": [
"mit dem Kommentarzeichen #",
"mit einem try-catch-Block",
"mit dem Cmdlet Write-Host"
],
"correct": 1,
"explanation": "Ein try-catch-Block fängt auftretende (terminierende) Fehler ab und führt im catch-Zweig eine eigene Fehlerbehandlung aus. Das Zeichen # leitet nur einen Kommentar ein, und Write-Host gibt lediglich Text aus, ohne Fehler abzufangen."
}
]
}
@@ -0,0 +1,245 @@
{
"title": "Virtualisierung",
"questions": [
{
"category": "Hypervisoren",
"hint": "Läuft direkt auf der Hardware?",
"text": "Was kennzeichnet einen Typ-1-Hypervisor?",
"answers": [
"Er läuft direkt auf der Hardware (Bare-Metal), ohne ein darunterliegendes Host-Betriebssystem.",
"Er wird als gewöhnliche Anwendung innerhalb eines vorhandenen Host-Betriebssystems installiert.",
"Er kann ausschließlich Linux-Gastsysteme betreiben."
],
"correct": 0,
"explanation": "Ein Typ-1-Hypervisor setzt direkt auf der Hardware auf und verwaltet die VMs selbst. Auf einem Host-Betriebssystem aufzusetzen ist das Merkmal eines Typ-2-Hypervisors, und die möglichen Gastsysteme sind unabhängig vom Hypervisor-Typ."
},
{
"category": "Hypervisoren",
"hint": "Welches Produkt braucht ein Host-Betriebssystem?",
"text": "Welches Produkt ist ein typischer Typ-2-Hypervisor?",
"answers": [
"VMware ESXi",
"Oracle VirtualBox",
"Microsoft Hyper-V als Server-Rolle"
],
"correct": 1,
"explanation": "VirtualBox wird als Anwendung auf einem bestehenden Betriebssystem installiert und ist damit ein Typ-2-Hypervisor. ESXi und Hyper-V arbeiten dagegen als Bare-Metal-Lösungen direkt auf der Hardware und zählen zu Typ 1."
},
{
"category": "Hypervisoren",
"hint": "Denk an Overhead im Rechenzentrum.",
"text": "Warum werden im Rechenzentrum meist Typ-1-Hypervisoren eingesetzt?",
"answers": [
"Weil sie eine vollständige grafische Desktop-Oberfläche für die Nutzer mitbringen.",
"Weil sie im Gegensatz zu Typ-2 keine Hardwaretreiber benötigen.",
"Weil sie ohne Umweg über ein Host-Betriebssystem geringeren Overhead und dadurch bessere Performance und Stabilität bieten."
],
"correct": 2,
"explanation": "Ohne dazwischenliegendes Host-OS entfällt eine ganze Software-Schicht, was Overhead senkt und die Leistung erhöht. Treiber für die Hardware braucht auch ein Typ-1-Hypervisor, und eine Desktop-Oberfläche ist im Serverbetrieb kein Vorteil."
},
{
"category": "Hypervisoren",
"hint": "Aufgabe des Virtual Machine Monitors.",
"text": "Welche Kernaufgabe erfüllt ein Hypervisor (Virtual Machine Monitor)?",
"answers": [
"Er teilt die physischen Ressourcen wie CPU, RAM und I/O auf mehrere virtuelle Maschinen auf und isoliert diese voneinander.",
"Er ersetzt die physische CPU vollständig durch eine reine Software-Emulation für jede VM.",
"Er verschmilzt mehrere physische Server zu einer einzigen großen CPU."
],
"correct": 0,
"explanation": "Der Hypervisor verwaltet die Hardware und weist den VMs isolierte Anteile der Ressourcen zu. Moderne Virtualisierung nutzt Hardware-Unterstützung statt reiner Emulation, und das Zusammenfassen mehrerer Server zu einem System beschreibt eher Clustering, nicht die Aufgabe eines Hypervisors."
},
{
"category": "Container vs. VM",
"hint": "Wer bringt einen eigenen Kernel mit?",
"text": "Worin liegt der grundlegende Unterschied zwischen einem Container und einer virtuellen Maschine?",
"answers": [
"Container bringen jeweils ein vollständiges eigenes Gast-Betriebssystem samt Kernel mit.",
"Container teilen sich den Kernel des Host-Betriebssystems, während jede VM ein eigenes Betriebssystem samt Kernel betreibt.",
"VMs sind grundsätzlich unsicherer als Container, weil sie ohne Hypervisor laufen."
],
"correct": 1,
"explanation": "Container nutzen gemeinsam den Kernel des Hosts und kapseln nur die Anwendung samt Abhängigkeiten, während eine VM ein komplettes eigenes Betriebssystem fährt. Ein eigenes Gast-OS haben Container gerade nicht, und VMs laufen sehr wohl auf einem Hypervisor."
},
{
"category": "Container vs. VM",
"hint": "Vorlage oder laufende Instanz?",
"text": "Wie unterscheiden sich ein Docker-Image und ein Docker-Container?",
"answers": [
"Das Image ist die laufende Instanz, der Container ist die unveränderliche Vorlage.",
"Image und Container bezeichnen denselben Zustand mit zwei Namen.",
"Das Image ist die unveränderliche, schichtweise aufgebaute Vorlage; der Container ist eine daraus gestartete, laufende Instanz mit eigener beschreibbarer Schicht."
],
"correct": 2,
"explanation": "Ein Image ist ein schreibgeschütztes, aus Layern bestehendes Abbild, aus dem zur Laufzeit ein Container mit eigener beschreibbarer Schicht entsteht. Die Rollen von Vorlage und Instanz werden dabei gern vertauscht, und beide sind keineswegs derselbe Zustand."
},
{
"category": "Container vs. VM",
"hint": "Was muss beim Start nicht booten?",
"text": "Warum starten Container in der Regel schneller und verbrauchen weniger Ressourcen als VMs?",
"answers": [
"Weil sie keinen eigenen Kernel und kein komplettes Betriebssystem booten müssen, sondern den Host-Kernel mitnutzen.",
"Weil sie ihre Daten grundsätzlich nur flüchtig im Arbeitsspeicher halten.",
"Weil ein Container immer nur einen einzigen CPU-Kern belegen darf."
],
"correct": 0,
"explanation": "Da kein vollständiges Betriebssystem hochgefahren wird, entfällt der Boot-Vorgang und der RAM-Bedarf sinkt. Container können sehr wohl persistente Daten über Volumes ablegen, und sie sind nicht auf einen einzelnen CPU-Kern beschränkt."
},
{
"category": "Container vs. VM",
"hint": "Gemeinsamer Kernel als Angriffsfläche.",
"text": "Wie unterscheidet sich die Isolation von Containern und VMs sicherheitstechnisch?",
"answers": [
"Container isolieren stärker, weil jeder Container einen eigenen Hardware-Ring der CPU belegt.",
"VMs bieten durch die Hardware-Virtualisierung eine stärkere Isolation, während Container sich einen gemeinsamen Kernel teilen und dort eine größere Angriffsfläche haben.",
"Zwischen Containern und VMs besteht sicherheitstechnisch kein Unterschied."
],
"correct": 1,
"explanation": "Jede VM ist durch den Hypervisor auf Hardwareebene abgeschottet, während ein Fehler im gemeinsam genutzten Kernel bei Containern zu einem Ausbruch führen kann. Container belegen keine eigenen CPU-Ringe, und der Isolationsgrad unterscheidet sich deutlich."
},
{
"category": "Snapshots & Klone",
"hint": "Zustand zu einem Zeitpunkt.",
"text": "Was ist ein Snapshot einer virtuellen Maschine?",
"answers": [
"Eine dauerhafte Vollsicherung, die ein reguläres Backup ersetzt.",
"Eine zweite, eigenständige VM mit eigener Identität und eigener MAC-Adresse.",
"Ein festgehaltener Zustand der VM zu einem bestimmten Zeitpunkt, zu dem man später zurückkehren kann."
],
"correct": 2,
"explanation": "Ein Snapshot friert den Zustand einer VM ein, sodass man Änderungen rückgängig machen kann. Er ersetzt kein Backup, weil er meist als Delta auf demselben Speicher liegt, und er erzeugt auch keine neue, eigenständige VM."
},
{
"category": "Snapshots & Klone",
"hint": "Wo liegen die Delta-Dateien?",
"text": "Warum darf ein Snapshot nicht als vollwertiges Backup betrachtet werden?",
"answers": [
"Weil ein Snapshot meist als Delta auf demselben Storage wie die VM liegt und bei einem Ausfall dieses Speichers mit verloren geht.",
"Weil ein Snapshot die VM dauerhaft anhält und erst durch ein Backup wieder startet.",
"Weil ein Snapshot ausschließlich den Arbeitsspeicher, aber niemals den Festplattenzustand erfasst."
],
"correct": 0,
"explanation": "Ein Snapshot schützt nicht vor Storage-Ausfall oder -Zerstörung, weil er auf demselben Datenträger abgelegt wird. Die VM läuft während eines Snapshots normal weiter, und der Festplattenzustand wird gerade festgehalten, der RAM-Zustand nur optional."
},
{
"category": "Snapshots & Klone",
"hint": "Geteilte Basisplatten sparen Platz.",
"text": "Worin unterscheidet sich ein Linked Clone von einem Full Clone?",
"answers": [
"Ein Linked Clone ist vollständig unabhängig vom Ausgangs-Image und belegt den vollen Speicher.",
"Ein Linked Clone teilt sich die Basisplatten mit einem Snapshot des Originals und spart dadurch Speicher, bleibt aber von diesem abhängig.",
"Ein Full Clone benötigt weniger Speicher als ein Linked Clone."
],
"correct": 1,
"explanation": "Ein Linked Clone verweist auf die gemeinsame Basisplatte des Originals und schreibt nur Änderungen in eigene Delta-Dateien, was Platz spart, aber eine Abhängigkeit schafft. Vollständig unabhängig und dafür speicherintensiver ist der Full Clone."
},
{
"category": "Snapshots & Klone",
"hint": "Was passiert mit den Delta-Dateien über die Zeit?",
"text": "Welche Gefahr besteht, wenn Snapshots über lange Zeit bestehen bleiben?",
"answers": [
"Die VM wird mit jedem Tag automatisch schneller.",
"Der Snapshot wandelt sich nach 24 Stunden selbstständig in ein Backup um.",
"Die Delta-Dateien wachsen fortlaufend, belegen immer mehr Speicher und können die Leistung der VM spürbar mindern."
],
"correct": 2,
"explanation": "Solange ein Snapshot besteht, sammeln sich alle Änderungen in wachsenden Delta-Dateien, was Speicher frisst und I/O-Leistung kostet. Deshalb sollte man Snapshots nur kurz halten. Ein Snapshot wird weder von selbst zum Backup noch beschleunigt er die VM."
},
{
"category": "Cloud-Servicemodelle",
"hint": "Nackte Infrastruktur zum Selbstverwalten.",
"text": "Was stellt der Anbieter beim Servicemodell IaaS (Infrastructure as a Service) bereit?",
"answers": [
"Virtuelle Infrastruktur wie Rechenleistung, Speicher und Netzwerk; Betriebssystem und Anwendungen verwaltest du selbst.",
"Eine fertige Endanwendung, die du nur noch im Browser nutzt.",
"Eine Entwicklungsplattform, bei der du dich weder um Laufzeitumgebung noch um Middleware kümmerst."
],
"correct": 0,
"explanation": "IaaS liefert die virtualisierte Basis-Infrastruktur, während Betriebssystem, Middleware und Anwendungen in deiner Verantwortung bleiben. Eine fertige Anwendung beschreibt SaaS, eine bereitgestellte Plattform mit Laufzeitumgebung beschreibt PaaS."
},
{
"category": "Cloud-Servicemodelle",
"hint": "Fertige Anwendung aus dem Browser.",
"text": "Wie verteilt sich die Verantwortung bei SaaS (Software as a Service)?",
"answers": [
"Du bist für das Einspielen der Betriebssystem-Patches auf den Servern des Anbieters verantwortlich.",
"Du nutzt eine fertige Anwendung, während der Anbieter die gesamte darunterliegende Infrastruktur samt Betriebssystem und Anwendung betreibt und wartet.",
"Du setzt eigene virtuelle Maschinen auf und administrierst sie vollständig selbst."
],
"correct": 1,
"explanation": "Bei SaaS betreibt der Anbieter die komplette Kette von Hardware über Betriebssystem bis zur Anwendung, du nutzt nur den Dienst. Patches des OS und der Betrieb eigener VMs fallen in andere Modelle wie IaaS und sind hier nicht deine Aufgabe."
},
{
"category": "Cloud-Servicemodelle",
"hint": "Denk an Shared Responsibility.",
"text": "Wer trägt bei den Cloud-Servicemodellen die Verantwortung für die eigenen Daten und die Zugriffsberechtigungen?",
"answers": [
"In jedem Modell trägt allein der Anbieter die Verantwortung für die Daten und deren Zugriffsrechte.",
"Die Verantwortung für Daten wechselt mit jedem Software-Update automatisch zum Anbieter.",
"Für die eigenen Daten und die Verwaltung der Zugriffsberechtigungen bleibt in allen Modellen der Kunde verantwortlich (Shared Responsibility)."
],
"correct": 2,
"explanation": "Nach dem Modell der geteilten Verantwortung sichert der Anbieter die Infrastruktur, doch die Hoheit über Daten und Identitäten bleibt beim Kunden. Diese Verantwortung geht weder pauschal auf den Anbieter über noch wechselt sie durch Updates."
},
{
"category": "Cloud-Servicemodelle",
"hint": "Plattform, auf der nur dein Code fehlt.",
"text": "Was ist charakteristisch für das Servicemodell PaaS (Platform as a Service)?",
"answers": [
"Der Anbieter stellt eine Plattform mit Laufzeitumgebung, Middleware und Datenbank bereit; du bringst nur deinen Anwendungscode ein.",
"Du erhältst nackte virtuelle Maschinen und installierst Betriebssystem und Middleware selbst.",
"Du erhältst nur eine fertige Endanwendung ohne jede Möglichkeit, eigenen Code auszuführen."
],
"correct": 0,
"explanation": "PaaS nimmt dir Betrieb und Wartung der Plattform ab, sodass du dich auf die Entwicklung deiner Anwendung konzentrierst. Nackte VMs sind IaaS, eine reine Endanwendung ohne eigenen Code ist SaaS."
},
{
"category": "Speicher & Ressourcen",
"hint": "Wann wird der Speicher physisch belegt?",
"text": "Wie unterscheiden sich Thin Provisioning und Thick Provisioning bei virtuellen Festplatten?",
"answers": [
"Thin Provisioning reserviert sofort den vollen konfigurierten Speicher auf dem Datenträger.",
"Thin Provisioning belegt physischen Speicher erst bei tatsächlichem Bedarf, während Thick Provisioning die volle Kapazität von Anfang an reserviert.",
"Thick Provisioning wächst dynamisch mit den geschriebenen Daten mit."
],
"correct": 1,
"explanation": "Thin belegt nur den wirklich genutzten Speicher und wächst mit den Daten, Thick reserviert die volle Größe sofort. Die Beschreibungen dürfen nicht vertauscht werden: das dynamische Wachstum gehört zu Thin, nicht zu Thick."
},
{
"category": "Speicher & Ressourcen",
"hint": "Summe der Zuweisungen über das Physische hinaus.",
"text": "Was bedeutet Ressourcen-Overcommitment in einer Virtualisierungsumgebung und welches Risiko birgt es?",
"answers": [
"Overcommitment ist unmöglich, weil ein Hypervisor nie mehr Ressourcen zuweisen kann, als physisch vorhanden sind.",
"Overcommitment verdoppelt die physisch vorhandene Hardware automatisch.",
"Du weist den VMs in Summe mehr Ressourcen zu, als physisch vorhanden sind; bei gleichzeitiger Spitzenlast drohen Engpässe und Leistungseinbrüche, etwa durch Swapping."
],
"correct": 2,
"explanation": "Weil selten alle VMs gleichzeitig ihre volle Zuweisung nutzen, kann man mehr zuteilen als vorhanden ist, riskiert aber Engpässe bei gleichzeitiger Spitzenlast. Der Hypervisor kann sehr wohl überbuchen, und physische Hardware entsteht dadurch nicht."
},
{
"category": "Speicher & Ressourcen",
"hint": "Laufende VM ohne Downtime verschieben.",
"text": "Was versteht man unter einer Live-Migration einer virtuellen Maschine?",
"answers": [
"Das Verschieben einer laufenden VM von einem Host auf einen anderen, ohne sie herunterzufahren (nahezu unterbrechungsfrei).",
"Das dauerhafte Löschen einer VM, um deren Speicher freizugeben.",
"Das Umwandeln einer laufenden VM in einen Container zur Laufzeit."
],
"correct": 0,
"explanation": "Bei der Live-Migration wechselt eine aktive VM den Host, während sie weiterläuft, etwa für Wartungsarbeiten am Original-Host. Ein Löschen der VM oder eine Umwandlung in einen Container hat damit nichts zu tun."
},
{
"category": "Speicher & Ressourcen",
"hint": "Wo liegen die Plattendateien der VM?",
"text": "Welche Voraussetzung muss für eine klassische Live-Migration zwischen zwei Hosts in der Regel erfüllt sein?",
"answers": [
"Die beiden Hosts müssen zwingend unterschiedliche CPU-Architekturen besitzen.",
"Beide Hosts brauchen üblicherweise Zugriff auf denselben gemeinsamen Speicher (Shared Storage) und ein gemeinsames Netzsegment.",
"Die VM muss vor der Migration gelöscht und auf dem Zielhost neu erstellt werden."
],
"correct": 1,
"explanation": "Über Shared Storage bleibt die virtuelle Platte am selben Ort erreichbar, sodass nur der Arbeitsspeicher-Zustand übertragen werden muss; ein gemeinsames Netz sichert die Erreichbarkeit. Die CPUs müssen kompatibel sein statt verschieden, und die VM wird gerade nicht gelöscht."
}
]
}
@@ -61,11 +61,21 @@
<section> <section>
<h2>AP2 Anwendungsentwicklung</h2> <h2>AP2 Anwendungsentwicklung</h2>
<a href="/finalflux/ap2-fiae/oop.html">Objektorientierung (OOP)</a>
<a href="/finalflux/ap2-fiae/uml.html">UML-Diagramme</a>
<a href="/finalflux/ap2-fiae/sql.html">SQL & Datenbanken</a>
<a href="/finalflux/ap2-fiae/algorithmen.html">Algorithmen</a>
<a href="/finalflux/ap2-fiae/testverfahren.html">Testverfahren</a>
<a href="/finalflux/ap2-fiae/entwurfsmuster.html">Entwurfsmuster</a> <a href="/finalflux/ap2-fiae/entwurfsmuster.html">Entwurfsmuster</a>
</section> </section>
<section> <section>
<h2>AP2 Systemintegration</h2> <h2>AP2 Systemintegration</h2>
<a href="/finalflux/ap2-fisi/netzwerkplanung.html">Netzwerkplanung</a>
<a href="/finalflux/ap2-fisi/it-sicherheit.html">IT-Sicherheit</a>
<a href="/finalflux/ap2-fisi/virtualisierung.html">Virtualisierung</a>
<a href="/finalflux/ap2-fisi/monitoring-backup.html">Monitoring & Backup</a>
<a href="/finalflux/ap2-fisi/skripting.html">Skripting</a>
<a href="/finalflux/ap2-fisi/hochverfuegbarkeit.html">Hochverfügbarkeit</a> <a href="/finalflux/ap2-fisi/hochverfuegbarkeit.html">Hochverfügbarkeit</a>
</section> </section>
</nav> </nav>