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,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."
}
]
}