diff --git a/gen.pl b/gen.pl
index 846f41dd253d78c3bf99e198de3c0734086476e0..66747b653f9655bc8e6ce2870bbfa0ee3e61d580 100755
--- a/gen.pl
+++ b/gen.pl
@@ -80,7 +80,7 @@ while (<>) {
     $question = $2;
     chomp $question;
 
-    if ($question =~ /\(([^()]*)\)/) {
+    if ($question =~ /\(([[0-9]{4}-[0-9]{2})\)/) {
       $source = $1;
       $question =~ s/\Q($source)\E//;
       chomp $source;
diff --git a/ss16.q b/ss16.q
index de0f92ddc3f71d93a274b899239971fbce2c6d70..2aa84e4a5f359b90228a359854abdffd1f90a0c2 100644
--- a/ss16.q
+++ b/ss16.q
@@ -1,6 +1,6 @@
 # https://sys.cs.fau.de/extern/lehre/ws23/sp2/pruefung/klausuren/2016s-SP-Klausur-www.pdf
 
-0 Welche Aussage zum Thema Speicherzuteilung ist richtig? (Juli 2016)
+0 Welche Aussage zum Thema Speicherzuteilung ist richtig? (2016-06)
 - Beim Halbierungsverfahren (buddy-Verfahren) kann keine interne Fragmentierung auftreten.
   Doch, weil der Speicher intern in Zweier-Potenzen aufgeteilt wird, und wenn man weniger braucht, hat man Speicher-Verschließ.
 - Speicherbereiche, die vor Beendigung eines Prozesses nicht mit free freigegeben wurden, sind bis zum Neustart des Systems unwiederbringlich verloren.
@@ -11,7 +11,7 @@
   Nein, das versucht nur den Verschnitt zu minimieren, und opfert dafür Laufzeit, weshalb es nicht "in jedem Fall" das beste sein kann.
 .
 
-0 Welche Aussage zum Thema Adressräume ist richtig? (Juli 2016)
+0 Welche Aussage zum Thema Adressräume ist richtig? (2016-06)
 - Im realen Adressraum sind alle theoretisch möglichen Adressen auch gültig.
   Nein, weil der reale Addressraum lücken haben kann, bedingt durch den Speicher.
 + Der Zugriff auf eine virtuelle Adresse, die zum Zeitpunkt des Zugriffs nicht im Hauptspeicher abgebildet ist, führt zu einem Trap.
@@ -22,7 +22,7 @@
   Nein, alle Seiten haben die gleiche Größe (ausnahme Huge-Pages, welche ein Vielfaches größer sind), damit diese leichter ein- und ausgelagert werden können.
 .
 
-0 Ein laufender Prozess wird in den Zustand blockiert überführt. Welche Aussage passt zu diesem Vorgang? (Juli 2016)
+0 Ein laufender Prozess wird in den Zustand blockiert überführt. Welche Aussage passt zu diesem Vorgang? (2016-06)
 - Der Prozess terminiert.
   Nein, weil ein blokierter Prozess kann später weiter laufen, sobald die Ursache, d.h. eine fehlende Ressource, behoben wurde.
 - Es ist kein direkter Übergang von laufend nach blockiert möglich.
@@ -33,7 +33,7 @@
   Nein, der Prozess muss nicht (sofort) auf einer anderen CPU eingelastet werden.
 .
 
-0 Welche Aussage zum Aufbau einer Kommunikationsverbindung zwischen einem Client und Server über eine Socket-Schnittstelle ist richtig? (Juli 2016)
+0 Welche Aussage zum Aufbau einer Kommunikationsverbindung zwischen einem Client und Server über eine Socket-Schnittstelle ist richtig? (2016-06)
 
 - Der Server signalisiert durch einen Aufruf von `connect()`, dass er zur Annahme von Verbindungen bereit ist; ein Client kann dies durch `accept()` annehmen.
 
@@ -49,7 +49,7 @@
   `listen()` für den Client möglich auf zukünftige Dienstleistungen zu
   warten.
 
-- Nach der Erzeugung eines Sockets mittels `socket()` kann ohne weitere System- oder Funktionsaufrufe sofort eine Verbindung von einem Client durch einen Aufruf von `connect()` angenommen werden. (Juli 2016)
+- Nach der Erzeugung eines Sockets mittels `socket()` kann ohne weitere System- oder Funktionsaufrufe sofort eine Verbindung von einem Client durch einen Aufruf von `connect()` angenommen werden. (2016-06)
 
   Falsch, man kann mit `connect()` keine Verbindung *annehmen*, dazu
   benutzt man `accept()`.  In dem Fall muss aber zuvor `bind()` und
@@ -58,7 +58,7 @@
 + Der Server richtet an einem Socket mittels `listen()` eine Warteschlange für ankommende Verbindungen ein und kann danach mit `accept()` eine konkrete Verbindung annehmen. `accept()` blockiert so lange die Warteschlange leer ist.
 .
 
-0 Wozu dient der Maschinenbefehl _cas_ (compare-and-swap)? (Juli 2016)
+0 Wozu dient der Maschinenbefehl _cas_ (compare-and-swap)? (2016-06)
 - Um bei Monoprozessorsystemen Interrupts zu sperren.
   Nein, das wäre auf x86 ein Befehl wie `cli`.
 + Um auf einem Multiprozessorsystem einfache Modifikationen an Variablen ohne Sperren implementieren zu können.
@@ -69,7 +69,7 @@
   Nein, das wird nicht mit einem Maschinenbefehl umgesetzt, sondern braucht eine MMU.
 .
 
-0 Welche Aussage zu Seitenersetzungsstrategien ist richtig? (Juli 2016)
+0 Welche Aussage zu Seitenersetzungsstrategien ist richtig? (2016-06)
 - Bei der Seitenersetzungsstrategie FIFO wird immer die zuletzt eingelagerte Seite ersetzt.
   Nein, _First In, First Out_ wird die älteste Seite ausgelagert.
 - Beim Auslagern einer Speicherseite muss der zugehörige Seitendeskriptor angepasst werden, beim Einlagern einer Seite ist das jedoch nicht nötig.
diff --git a/ss18.q b/ss18.q
index 495bdfdfbafeeea79eaf1b3b4c4d1dd3d26be9d3..a30706441ae81dd38612612ade7cd0c201520545 100644
--- a/ss18.q
+++ b/ss18.q
@@ -1,4 +1,4 @@
-0 Welche Aussage über Funktionen der `exec()`-Familie ist richtig? (Juli 2018)
+0 Welche Aussage über Funktionen der `exec()`-Familie ist richtig? (2018-07)
 
 - Dem Vater-Prozess wird die Prozess-ID des Kind-Prozesses zurückgeliefert.
 
@@ -17,7 +17,7 @@
   Nein, weil `exec` keine neuen Prozesse erstellt.
 .
 
-0 Welche Aussage über den Rückgabewert von fork() ist richtig? (Juli 2018)
+0 Welche Aussage über den Rückgabewert von fork() ist richtig? (2018-07)
 + Dem Vater-Prozess wird die Prozess-ID des Kind-Prozesses zurückgeliefert.
 - Der Kind-Prozess bekommt die Prozess-ID des Vater-Prozesses.
   Nein, es bekommt den festen Wert 0; der Eltern-Prozess kann mit `getppid` (eindeutig) bestimmt werden.
@@ -27,7 +27,7 @@
   Nein, Kind bekommt 0, damit es weiß es ist das Kind und Vater bekommt die PID vom Kind.
 .
 
-0 Welche Aussage über das aktuelle Arbeitsverzeichnis (Current Working Directory) trifft zu? (Juli 2018)
+0 Welche Aussage über das aktuelle Arbeitsverzeichnis (Current Working Directory) trifft zu? (2018-07)
 - Jedem UNIX-Benutzer ist zu jeder Zeit ein aktuelles Verzeichnis zugeordnet.
   Nein, weil ein aktuelles Verzeichnis wird einem Prozess zugeordnet.
 + Pfadnamen, die nicht mit dem Zeichen `/` beginnen, werden relativ zu dem aktuellen Arbeitsverzeichnis interpretiert.
@@ -36,7 +36,7 @@
 - Besitzt ein UNIX-Prozess kein Current Working Directory, so beendet sich der Prozess mit einem Segmentation Fault.
 .
 
-0 Welche der folgenden Aussagen zum Thema Threads ist richtig? (Juli 2018)
+0 Welche der folgenden Aussagen zum Thema Threads ist richtig? (2018-07)
 + Bei User-Threads ist die Scheduling-Strategie nicht durch das Betriebssystem vorgegeben.
   Ja, weil das Scheduling innerhalb vom Prozess stattfindet, und damit unabhängig vom Betriebsystem ist.
 - Kernel-Threads können Multiprozessoren nicht ausnutzen.
diff --git a/ss19.q b/ss19.q
index bf77792253381a7d3c8bc8c3f89ec18cf7058bf7..5ad5a7dc28b746d06ee3dc1fdb30a705f49c6057 100644
--- a/ss19.q
+++ b/ss19.q
@@ -1,4 +1,4 @@
-0 Gegeben sei folgendes Szenario: zwei Fäden werden auf einem Monoprozessorsystem mit der Strategie "First Come First Served" verwaltet. In jedem Faden wird die Anweisung `i++;` auf der gemeinsamen, globalen volatile Variablen i ausgeführt. Welche der folgenden Aussagen ist richtig? (Juli 2019)
+0 Gegeben sei folgendes Szenario: zwei Fäden werden auf einem Monoprozessorsystem mit der Strategie "First Come First Served" verwaltet. In jedem Faden wird die Anweisung `i++;` auf der gemeinsamen, globalen volatile Variablen i ausgeführt. Welche der folgenden Aussagen ist richtig? (2019-06)
 + In einem Monoprozessorsystem ohne Verdrängung ist keinerlei Synchronisation erforderlich.
   Ja, weil der Befehl immer ganz ausgeführt wird, und weil es keine unvorhergesehenen Unterbrechungen gibt, muss man diese auch nicht verhindern oder dagen vorbeugen.
 - Während der Inkrementoperation müssen Interrupts vorübergehend unterbunden werden.
@@ -9,7 +9,7 @@
   Nein, das hängt von der Recherarchitektur ab, und kann aber muss nicht atomar übersetzt werden.
 .
 
-1 Der Speicher eines UNIX-Prozesses ist in Text-, Daten- und Stack-Segment untergliedert. Welche Aussagen bezogen auf C-Programme sind richtig? (Juli 2019)
+1 Der Speicher eines UNIX-Prozesses ist in Text-, Daten- und Stack-Segment untergliedert. Welche Aussagen bezogen auf C-Programme sind richtig? (2019-06)
 + Die Sichtbarkeit globaler `static`-Variablen ist auf das jeweilige Modul beschränkt.
   Ja, damit verindert man auch Namenskonflikte zwischen Modulen.
 + Funktionspointer werden nicht immer im Text-Segment gespeichert.
@@ -28,7 +28,7 @@
   Nein, diese behalten den gleichen Wert unabhängig vom Funktionsaufruf.  Ihre Sichtbarkeit ist nur auf eine Funktion beschränkt.
 .
 
-0 Was passiert, wenn Sie in einem C-Programm versuchen über einen Zeiger auf ungültigen Speicher zuzugreifen? (Juli 2019)
+0 Was passiert, wenn Sie in einem C-Programm versuchen über einen Zeiger auf ungültigen Speicher zuzugreifen? (2019-06)
 - Das Betriebssystem erkennt die ungültige Adresse bei der Weitergabe des Befehls an die CPU (partielle Interpretation) und leitet eine Ausnahmebehandlung ein.
   Das Betriebsystem interpretiert die Befehle des Programms nicht selbst.  Diese werden direkt von der CPU interpretiert, welches sich in einem unpriviligiertem Modus befindet.  Für priviligierte Befehle, muss man mit einem Systemaufruf sich an das Betriebsystem wenden.
 - Der Compiler erkennt die problematische Code-Stelle und generiert Code, der zur Laufzeit bei dem Zugriff einen entsprechenden Fehler auslöst.
@@ -39,7 +39,7 @@
   Ja; die CPU kann dann je nach Betriebsystem sich entscheiden diesen Trap weiter zu leiten an einen Prozess in Form eines Signals o.Ä.
 .
 
-0 Welche der folgenden Aussagen zum Thema Synchronisation ist richtig? (Juli 2019)
+0 Welche der folgenden Aussagen zum Thema Synchronisation ist richtig? (2019-06)
 
 - Der Einsatz von nicht-blockierenden Synchronisationsmechanismen kann zu Verklemmungen (deadlocks) führen.
   Nein, bei einer Verklemmung müssen mehere Fäden passiv aufeinander warten, was bei nicht-blockierendeer Syncrhonisation nicht passieren kann.
diff --git a/ss22.q b/ss22.q
index 3efcade50ea952c36137e714b374d8e2776f4fea..9031e326d550b76a9745f6565b3c8d7824dd79c2 100644
--- a/ss22.q
+++ b/ss22.q
@@ -1,4 +1,4 @@
-0 In einem UNIX-UFS-Dateisystem gibt es symbolische Namen/Verweise (Symbolic Links) und feste Links (Hard Links) auf Dateien. Welche Aussage ist richtig? (Juli 2022)
+0 In einem UNIX-UFS-Dateisystem gibt es symbolische Namen/Verweise (Symbolic Links) und feste Links (Hard Links) auf Dateien. Welche Aussage ist richtig? (2022-07)
 
 + Für jede reguläre Datei existiert mindestens ein Hard-Link im selben Dateisystem.
 
@@ -31,7 +31,7 @@
 
 .
 
-0 Ausnahmesituationen bei einer Programmausführung werden in die beiden Kategorien Trap und Interrupt unterteilt. Welche der folgenden Aussagen ist zutreffend? (Juli 2022)
+0 Ausnahmesituationen bei einer Programmausführung werden in die beiden Kategorien Trap und Interrupt unterteilt. Welche der folgenden Aussagen ist zutreffend? (2022-07)
 - Ein Trap signalisiert einen schwerwiegenden Fehler und führt deshalb immer zur Beendigung des unterbrochenen Programms.
 
   Nein, ein Trap kann auch durch eine nicht eingelagerte Seite (wo
diff --git a/ss23.q b/ss23.q
index e81f77cf4700ad6c51ebdb81597eb6dc4a1052ec..b4eed789febed354cdfcd37991d0eeb00ea85aad 100644
--- a/ss23.q
+++ b/ss23.q
@@ -1,6 +1,6 @@
 # https://sys.cs.fau.de/extern/lehre/ws23/sp2/pruefung/klausuren/2023s-SP-Klausur_www.pdf
 
-0 Man unterscheidet zwischen privilegierten und nicht-privilegierten Maschinenbefehlen. Welche Aussage ist richtig? (Juli 2023)
+0 Man unterscheidet zwischen privilegierten und nicht-privilegierten Maschinenbefehlen. Welche Aussage ist richtig? (2023-07)
 ? Privilegierte Maschinenbefehle dürfen in Anwendungsprogrammen grundsätzlich nicht verwendet werden.
   Abhängig davon, was man unter "grundsätzlich" versteht, sollte es eigentlich heißen, dass man Privilegierte Maschinenbefehle nicht verwenden darf.
 - Die Benutzung eines privilegierten Maschinenbefehls in einem Anwendungsprogramm führt zu einer asynchronen Programmunterbrechung.
@@ -11,7 +11,7 @@
   Nein, diese werden nicht durch das Betriebsystem(programme) implementiert, sondern werden von der CPU ausführt, angenommen es befindet sich im richtigen Privilegienmodus.
 .
 
-0 Was passiert, wenn Sie in einem C-Programm über einen ungültigen Zeiger versuchen auf Speicher zuzugreifen? (Juli 2023)
+0 Was passiert, wenn Sie in einem C-Programm über einen ungültigen Zeiger versuchen auf Speicher zuzugreifen? (2023-07)
 - Das Betriebssystem erkennt die ungültige Adresse bei der Weitergabe des Befehls an die CPU (partielle Interpretation) und leitet eine Ausnahmebehandlung ein.
   Nein, das Betriebssystem gibt den Befehl selbst nicht an die CPU weiter, und überprüft daher auch nicht ob die Addressen gültig seien.
 - Der Compiler erkennt die problematische Code-Stelle und generiert Code, der zur Laufzeit bei dem Zugriff einen entsprechenden Fehler auslöst.
@@ -22,7 +22,7 @@
   Da der Fehler direkt bedingt ist durch das Verhalten des Programms, würde es sich hier um ein "Trap" und kein "Interrupt" (unvorhersebar) handeln.
 .
 
-0 Welche der folgenden Aussagen zum Thema Dateispeicherung sind richtig? (Juli 2023)
+0 Welche der folgenden Aussagen zum Thema Dateispeicherung sind richtig? (2023-07)
 - Bei indizierter Speicherung von Dateien ensteht externer Verschnitt auf der Platte.
   Nein, weil für Dateien ganze Blöcke vergeben und herumgeschoben werden können, womit externer Verschnitt vermieden wird, weil es nicht dazu kommen kann, dass es lücken gibt die "zu klein" wären für eine Datei.
 + Festplatten eignen sich besser für sequentielle als für wahlfreie Zugriffsmuster.
@@ -33,7 +33,7 @@
   Nein, Verschleis hat nichts mit der technischen Umsetzung des Speichermediums zu tun.
 .
 
-0 Welches Signal wird bei einer Speicherschutzverletzung versendet? (Juli 2023)
+0 Welches Signal wird bei einer Speicherschutzverletzung versendet? (2023-07)
 - SIGKILL
   `signal.h(7p)` sagt "Kill (cannot be caught or ignored)".
 + SIGSEGV
diff --git a/ws19.q b/ws19.q
index a4c6f12bb9b8a7b315a0557cc9dfaf84c3e10042..f9d603088443a4db00feb1d7321d9de4254a96da 100644
--- a/ws19.q
+++ b/ws19.q
@@ -1,5 +1,5 @@
 # https://sys.cs.fau.de/extern/lehre/ws23/sp2/pruefung/klausuren/2019w-SP-Klausur_www.pdf
-0 Wozu dient die CAS (Compare-And-Swap) Instruktion? (Februar 2020)
+0 Wozu dient die CAS (Compare-And-Swap) Instruktion? (2020-02)
 - Zur Realisierung einer effizienten Verdrängungssteuerung bei einseitiger Synchronisation.
   Nein. Dies wird je nach Art der einseitigen Synchronisation (z. B. Blockieren der Signalbehandlung) unterschiedlich, jedoch nicht mit CAS, gelöst.
 - Um in einem System mit Seitennummerierung (Paging) Speicherseiten in die Auslagerungspartition (swap area) schreiben zu können.
@@ -13,7 +13,7 @@
   Stattdessen müsste für passives Warten der wartende Prozess in den Zustand blockiert übergehen, bis er von einem anderen Prozess "geweckt" wird. Hierfür ist Betriebssystemunterstützung in Form eines Schedulers nötig.
 .
 
-0 Was versteht man unter RAID 0? (Februar 2020)
+0 Was versteht man unter RAID 0? (2020-02)
 - Ein auf Flash-Speicher basierendes, extrem schnelles Speicherverfahren.
   Nein, RAID 0 und andere RAID *level* bezeichnen, wie Daten auf mehrere Speichermedien (ein *redundant array of independent disks*) aufgeteilt werden
   und nicht, wie der Speicher auf der physikalischen Ebene implementiert ist.
@@ -25,7 +25,7 @@
   Nein, RAID 0 sorgt nicht für Redundanz, sondern dient nur zur Beschleunigung von Speicherzugriffen. Es werden keine Replikate von Datenblöcken angelegt.
 .
 
-0 Welche der folgenden Aussagen zum Thema Adressräume ist richtig? (Februar 2020)
+0 Welche der folgenden Aussagen zum Thema Adressräume ist richtig? (2020-02)
 - Virtuelle Adressräume sind Voraussetzung für die Realisierung logischer Adressräume.
   Nein, andersherum. Ein logischer Adressraum ist ein zusammenhängender Adressbereich. Der virtuelle Adressbereich setzt auf diesen auf, indem Adressen, die nicht auf den Speicher abgebildet werden können, beim Zugriff einen Adressübersetzungsfehler auslösen. Die Zuordnung vom logischen zum realen Adressraum kann somit als totale Funktion betrachtet werden, im Gegensatz dazu kann die Zuordnung vom virtuellen zum realen Adressraum als partielle Funktion auf den logischen Adressen betrachtet werden (vgl. SP1 B Vl. 2 S. 12 ff., 27).
 - Der virtuelle Adressraum kann nie größer sein als der im Rechner vorhandene Hauptspeicher.
@@ -36,7 +36,7 @@
   Ja, jede physikalische Adresse korrespondiert zu einer tatsächlichen Stelle im Hauptspeicher, von dem eine bestimmte Menge in einem System verbaut ist.
 .
 
-0 Welche Aussage zu Zeigern in C-Programmen ist richtig? (Februar 2020)
+0 Welche Aussage zu Zeigern in C-Programmen ist richtig? (2020-02)
 + Zeiger können verwendet werden, um in C eine call-by-reference Übergabesemantik nachzubilden.
   Ja. C ist *call-by-value*, da Funktionsparameter als Kopie und nicht als Referenz weitergegeben werden.
   Zeiger sind jedoch Referenzen auf Speicherstellen im Adressraum. Erhält eine Funktion also einen Zeiger als Wert,
@@ -68,7 +68,7 @@
   ```
 .
 
-0 Welche Aussage zu Programmbibliotheken ist richtig? (Februar 2020)
+0 Welche Aussage zu Programmbibliotheken ist richtig? (2020-02)
 - Eine statische Bibliothek, die in ein Programm eingebunden wurde, muss zum Ladezeitpunkt dieses Programms im Dateisystem vorhanden sein.
   Nein, das wäre bei einer dynamischen Bibliothek der Fall.
   Bei statischen Binden wird bereits zur *link time* der Objektcode der Bibliothek in das Programm kopiert.
@@ -82,7 +82,7 @@
   nur die statische Bibliothek zu ändern, da das Programm immer noch den ursprünglichen Objektcode enthält.
 .
 
-0 Welche der folgenden Aussagen über Einplanungsverfahren ist richtig? (Februar 2020)
+0 Welche der folgenden Aussagen über Einplanungsverfahren ist richtig? (2020-02)
 -  Beim Einsatz präemptiver Einplanungsverfahren kann laufenden Prozessen die CPU nicht entzogen werden.
   Nein, das wäre kooperative Einplanung. Bei präemptiver Einplanung kann einem Prozess durch einen Timer-Interrupt die CPU entzogen werden (Präemption).
 - Probabilistische Einplanungsverfahren müssen die exakten CPU-Stoßlängen aller im System vorhandenen Prozesse kennen.
diff --git a/ws21.q b/ws21.q
index fdd239cd8568e134d99b0eb18e81eb996abc43d1..17fdf53d1d618ce0103db4f68f3dd9899cfc556a 100644
--- a/ws21.q
+++ b/ws21.q
@@ -1,6 +1,6 @@
 # https://sys.cs.fau.de/extern/lehre/ws23/sp2/pruefung/klausuren/2022w-SP-Klausur_www.pdf
 
-0 Welche der folgenden Aussagen zu statischem bzw. dynamischem Binden ist richtig? (Februar 2022)
+0 Welche der folgenden Aussagen zu statischem bzw. dynamischem Binden ist richtig? (2022-02)
 
 - Statisch gebundene Programmdateien sind kleiner als dynamisch gebundene, da mehrfach genutzte Funktionen in einer shared library abgelegt werden und nicht in die ausführbare Datei kopiert werden
 
@@ -27,7 +27,7 @@
   bereits aufgelöst geworden sein.
 .
 
-0 Welche Antwort trifft für die Eigenschaften eines UNIX/Linux-Dateideskriptor zu? (Februar 2022)
+0 Welche Antwort trifft für die Eigenschaften eines UNIX/Linux-Dateideskriptor zu? (2022-02)
 
 - Ein Dateideskriptor ist eine Integerzahl, die über gemeinsamen Speicher an einen anderen Prozess übergeben werden kann, und von letzterem zum Zugriff auf eine geöffnete Datei verwendet werden kann.
 
@@ -60,7 +60,7 @@
   ~~~
 .
 
-1 Man unterschiedet zwei Kategorien von Ausnahmesituationen bei einer Programmausführung: Traps und Interrupts. Welche der folgenden Aussagen sind zutreffend? (Februar 2022)
+1 Man unterschiedet zwei Kategorien von Ausnahmesituationen bei einer Programmausführung: Traps und Interrupts. Welche der folgenden Aussagen sind zutreffend? (2022-02)
 
 + Ein Programm darf im Rahmen einer Trapbehandlung abgebrochen werden.
 
@@ -100,7 +100,7 @@
   Nein, weil diese deterministisch immer dann auftreten, wenn ein Programm ein Systemaufruf absetzen will.
 .
 
-0 In welcher der folgenden Situationen wird ein Prozess vom Zustand laufend in den Zustand bereit übeführt? (Februar 2022)
+0 In welcher der folgenden Situationen wird ein Prozess vom Zustand laufend in den Zustand bereit übeführt? (2022-02)
 
 - Der Prozess ruft die Bibliotheksfunktion `exit(3)` auf.
 
@@ -119,51 +119,7 @@
   Nein, weil dann der Prozess blokiert wird, und nicht mehr laufen kann, bis an einer anderen Stelle eine entsprechende V-Operation ausgeführt wird.
 .
 
-0 Sie kennen den Translation-Lookaside-Buffer (TLB). Welche Aussage ist richtig? (Februar 2023)
-+ Verändert sich die Speicherabbildung von logischen auf physikalische Adressen aufgrund einer Adressraumumschaltung, so werden auch die Daten im TLB ungültig.
-  Ja, weil die zwischengespeicherten Seitenaddressen nicht mehr mit dem neuem logischem Addressraum zusammenhängen würden.
-- Der TLB verkürzt die Zugriffszeit auf den physikalischen Speicher da ein Teil des möglichen Speichers in einem schnellen Pufferspeicher vorgehalten wird.
-  Nein, im TLB werden nur die Addressen der Seiten gespeichert, um das Nachschlagen in der MMU zu vermeiden, und nicht den Speicher selbst. 
-- Der TLB puffert Daten bei der Ein-/Ausgabebehandlung und beschleunigt diese damit.
-  Nein, der TLB hat nichts mit den Daten per se zu tun, sondern beschleundigt nur den Zugriff auf häufig benutzte Seiten.
-- Wird eine Speicherabbildung im TLB nicht gefunden, wird der auf den Speicher zugreifende Prozess mit einer Schutzraumverletzung (Segmentation Fault) abgebrochen.
-  Nein, ist kein Eintrag im TLB zu finden, wird die Addresse von der MMU aufgelöst.
-.
-
-0 Welche Aussage zu Prozessen und Threads ist richtig? (Februar 2023)
-- Mittels `fork()` erzeugte Kindprozesse können in einem Multiprozessor-System nur auf dem Prozessor ausgeführt werden, auf dem auch der Elternprozess ausgeführt wird.
-  Nein, es ist dem Scheduler ganz überlassen zu entscheiden, auf welchen Prozessoren ein Prozess laufen soll.  Ein Prozess muss auch nicht ganz auf einem Kern oder nur auf einem Kern laufen
-+ Der Aufruf von `fork()` gibt im Elternprozess die Prozess-ID des Kindprozesses zurück, im Kindprozess hingegen den Wert 0.
-  Ja, das steht auch so in der Man Page.  Die Annahme ist hier, dass kein Fehler aufgetreten ist.
-- Threads, die mittels `pthread_create()` erzeugt wurden, besitzen jeweils einen eigenen Adressraum.
-  Nein, Kind-Threads (im Kontext von der Pthread Bibliothek.) teilen den Addressraum mit dem Eltern-Thread.  Prozesse haben eigene Addressräume.
-- Die Veränderung von Variablen und Datenstrukturen in einem mittels `fork()` erzeugten Kindprozess beeinflusst auch die Datenstrukturen im Elternprozess.
-  Nein, allgemein nicht, außer der Benutzer richtet dieses spezifisch ein (Siehe `shm_open(3)`), was aber ohne weiteres nicht der Fall ist.
-.
-
-0 Was ist ein Stack-Frame? (Februar 2023)
-- Der Speicherbereich, in dem der Programmcode einer Funktion abgelegt ist.
-  Nein, ein Stack-Frame liegt im Stack Segment, und der Programmcode liegt im Text-Segment.
-- Ein Fehler, der bei unberechtigten Zugriffen auf den Stack-Speicher entsteht.
-  Nein, es gibt keinen gesonderten Namen für Fehlerhaften Zugriff auf den Stack-Namen.
-+ Ein Bereich des Speichers, in dem u.a. lokale automatic-Variablen einer Funktion abgelegt sind.
-  Ja, ein Stack-Frame wird beim betreten einer Funktion angelegt für alle Metadaten und Daten welche zur ausführung benötigt werden und aufgeräumt sobald die Funktion verlassen wird.
-- Ein spezieller Registersatz des Prozessors zur Bearbeitung von Funktionen.
-  Nein, es ist kein Registersatz.
-.
-
-0 Welche der folgenden Informationen wird typischerweise in dem Seitendeskriptor einer Seite eines virtuellen Adressraums gehalten?
-+ Die Zugriffsrechte auf die jeweilige Seite (z. B. lesen, schreiben, ausführen).
-  Ja, so setzt das Betriebsystem bspw. um, dass ein Text Segment ausführbar aber nicht schreibbar ist.
-- Die Identifikation des Prozesses, dem die Seite zugeordnet ist.
-  Nein, das Seiten existieren unabhängig von Prozessen und müssten per se nicht dafür benutzt werden, um logische Speicherräume auf Betriebsystemen mit unabhängigen Prozessen umzusetzen.
-- Die Zuordnung zu einem Segment (Text, Daten, ...).
-  Nein, dieses wird muss man sich nicht in dem Seitendeskriptor merken, weil es nur wichtig ist, dass die Seite sich gemäß dem Verständniss von diesen Segmenten verhällt (lesbar, ausfübar, ...).
-- Die Position der Seite im virtuellen Adressraum.
-  Nein, diese Zuordnung findet nicht im Seitendeskriptor statt, sondern im Betriebsystem.
-.
-
-0 Welche Aussage zum Thema Adressraumverwaltung ist richtig? (Februar 2022)
+0 Welche Aussage zum Thema Adressraumverwaltung ist richtig? (2022-02)
 + Ein Speicherbereich, der mit Hilfe der Funktion free() freigegeben wurde, verbleibt im logischen Adressraum des zugehörigen Prozesses.
   Ja. Der **logische** Adressraum Aₗ = [n, m] ist der gesamte Adressbereich ohne Lücken, der einem Prozess zugeordnet wird. Dieser wird nicht verkleinert, wenn `free` aufgerufen wird. Im Gegensatz dazu ist der virtuelle Adressraum Aᵥ jener, der nur partiell auf den Hauptspeicher abgebildet wird, bei dem also Adressen ungültig sein können. (vgl. SP1 B Vl. 2 S. 12 ff., 27) (Bin mir hier nicht zu 100 % sicher, dass meine Interpretation korrekt ist)
 - Mit malloc() angeforderter Speicher, welcher vor Programmende nicht freigegeben wurde, kann vom Betriebssystem nicht mehr an andere Prozesse herausgegeben werden und ist damit bis zum Neustart des Systems verloren.
@@ -174,7 +130,7 @@
   Nein, `malloc` kann als Teil des Laufzeitsystems den grobgranular vom Betriebssystem angeforderten Speicher feingranular aufteilen und zurückgeben.
 .
 
-0 Sie kennen den Translation-Lookaside-Buffer (TLB). Welche Aussage ist richtig? (Februar 2022)
+0 Sie kennen den Translation-Lookaside-Buffer (TLB). Welche Aussage ist richtig? (2022-02)
 - Der TLB puffert die Ergebnisse der Abbildung von physikalische auf logische Adressen, sodass eine erneute Anfrage sofort beantwortet werden kann.
   Nein, andersherum. Logische müssen in physikalische Adressen übersetzt werden.
 + Verändert sich die Speicherabbildung von logischen auf physikalische Addressen aufgrund einer Adressraumumschaltung, so werden auch die Daten im TLB ungültig.
@@ -185,7 +141,8 @@
   Nein, ist kein Eintrag im TLB zu finden, wird die Addresse von der MMU aufgelöst. Der TLB agiert nur als *cache* für Adressübersetzungen.
 .
 
-0 Welche Aussage zu den verschiedenen Gewichtsklassen von Prozessen trifft zu? (Februar 2022)
+
+0 Welche Aussage zu den verschiedenen Gewichtsklassen von Prozessen trifft zu? (2022-02)
 - Schwergewichtige Prozesse sind die einzige Klasse von Prozessen, die auf einem Multiprozessorsystem echt parallel ausgeführt werden kann, da nur hier jeder Benutzerfaden einem eigenen Kernfaden zugeordnet ist.
   Nein. Auch leichtgewichtigen Prozessen (*kernel-level threads*) ist ein *kernel thread* zugeordnet.
 + Federgewichtige Prozesse (*user-level threads*) blockieren sich bei blockierenden Systemaufrufen gegenseitig.
@@ -196,7 +153,7 @@
   Falsch, das wären schwergewichtige Prozesse. Leichtgewichtige Prozesse wie `pthread`s teilen sich einen Adressraum.
 .
 
-0 Wie wird erkannt, dass eine Seite eines virtuellen Adressraums, auf die ein Maschinenbefehl zugreift, gerade ausgelagert ist? (Februar 2022)
+0 Wie wird erkannt, dass eine Seite eines virtuellen Adressraums, auf die ein Maschinenbefehl zugreift, gerade ausgelagert ist? (2022-02)
 + Im Seitendeskriptor wird ein spezielles Bit geführt, das der MMU zeigt, ob eine Seite eingelagert ist oder nicht. Falls die Seite nicht eingelagert ist, löst die MMU einen Trap aus.
   Ja, die *page descriptor table* enthält für jeden Seitendeskriptor ein *valid*-Bit. Ist dieses nicht gesetzt, so wird ein *Trap* ausgelöst.
 - Im Seitendeskriptor steht bei ausgelagerten Seiten eine Adresse des Hintergrundspeichers und der Speichercontroller leitet den Zugriff auf den Hintergrundspeicher um.
@@ -207,7 +164,7 @@
   Nein, der Compiler fügt nicht in jedes Programm eine Implementation der Speichervirtualisierung ein. Diese ist eine Aufgabe des Betriebssystems und nicht der einzelnen Benutzerprogramme.
 .
 
-0 Welche der folgenden Aussagen zum Thema Seitenfehler (*Page Fault*) ist richtig? (Februar 2022)
+0 Welche der folgenden Aussagen zum Thema Seitenfehler (*Page Fault*) ist richtig? (2022-02)
 - Wenn der gleiche Seitenrahmen in zwei verschiedenen Seitendeskriptoren eingetragen wird, löst dies einen Seitenfehler aus (Gefahr von Zugriffskonflikten!).
   Nein, das würde z. B. zwischen Prozessen geteilten Speicher verhindern.
 - Ein Seitenfehler wird ausgelöst, wenn der Offset in einer logischen Adresse größer als die Länge der Seite ist.
diff --git a/ws22.q b/ws22.q
index 1fb4b5435c729aaf9c9679edd91de286d06ee5d4..b66c3cdb8b8d6b7ea197e2e50eb3ce6a4c12c4d5 100644
--- a/ws22.q
+++ b/ws22.q
@@ -1,6 +1,6 @@
 # https://sys.cs.fau.de/extern/lehre/ws23/sp2/pruefung/klausuren/2022w-SP-Klausur_www.pdf
 
-0 Beim Blockieren in einem Monitor muss der Monitor freigegeben werden. Warum? (Februar 2023)
+0 Beim Blockieren in einem Monitor muss der Monitor freigegeben werden. Warum? (2023-02)
 - Weil kritische Abschnitte immer nur kurz belegt sein dürfen.
   Für die Performanz eines Programms ist das sicher vorteilhaft, jedoch hat das nichts mit der Frage zu tun.
 - Weil sonst die Monitordaten inkonsistent sind.
@@ -11,7 +11,7 @@
   Nein, der Thread wartet passiv auf den Monitor.
 .
 
-0 Welche Aussage zum Thema Synchronisation ist richtig? (Februar 2023)
+0 Welche Aussage zum Thema Synchronisation ist richtig? (2023-02)
 - Die V-Operation kann auf einem Semaphor nur von dem Thread aufgerufen werden, der zuvor auch die P-Operation aufgerufen hat.
   Nein, P und V können von beliebigen, auch unterschiedlichen, Threads aus aufgerufen werden.
 + Durch den Einsatz von Semaphoren kann ein wechselseitiger Ausschluss erzielt werden.
@@ -22,7 +22,7 @@
   Nein, diese kann zum Beispiel ohne Betriebssystemaufrufe durch ein *spin lock* realisiert werden.
 .
 
-0 Welche der folgenden Aussagen zu statischem bzw. dynamischem Binden ist richtig? (Februar 2023)
+0 Welche der folgenden Aussagen zu statischem bzw. dynamischem Binden ist richtig? (2023-02)
 - Änderungen am Code einer dynamischen Bibliothek (z. B. Bugfixes) erfordern immer das erneute Binden aller Programme, die diese Bibliothek benutzen.
   Ja. Programme, die eine dynamische Bibliothek einbinden müssen (zumindest in der Theorie) nur neugestartet werden, nachdem diese ausgetauscht wurde, wonach sie durch den dynamischen Binder neu gebunden werden.
 - Beim statischen Binden werden alle Adressen zum Ladezeitpunkt aufgelöst.
@@ -31,4 +31,48 @@
   Ja, beim Laden werden die Adressen der verwendeten Symbole durch den *dynamic linker* aufgelöst. Zur Laufzeit können jedoch noch Bibliotheken nachgeladen werden (`dlopen(3)`).
 - Statisch gebundene Programme können zum Ladezeitpunkt an beliebige virtuelle Speicheradressen platziert werden.
   Nein. Das kann, muss aber nicht so sein. Dynamische Bibliotheken müssen hingegen *position-independent-code* enthalten, um in den Adressbereich des Zielprogramms geladen werden zu können.
-.
\ No newline at end of file
+.
+
+0 Sie kennen den Translation-Lookaside-Buffer (TLB). Welche Aussage ist richtig? (2023-02)
++ Verändert sich die Speicherabbildung von logischen auf physikalische Adressen aufgrund einer Adressraumumschaltung, so werden auch die Daten im TLB ungültig.
+  Ja, weil die zwischengespeicherten Seitenaddressen nicht mehr mit dem neuem logischem Addressraum zusammenhängen würden.
+- Der TLB verkürzt die Zugriffszeit auf den physikalischen Speicher da ein Teil des möglichen Speichers in einem schnellen Pufferspeicher vorgehalten wird.
+  Nein, im TLB werden nur die Addressen der Seiten gespeichert, um das Nachschlagen in der MMU zu vermeiden, und nicht den Speicher selbst. 
+- Der TLB puffert Daten bei der Ein-/Ausgabebehandlung und beschleunigt diese damit.
+  Nein, der TLB hat nichts mit den Daten per se zu tun, sondern beschleundigt nur den Zugriff auf häufig benutzte Seiten.
+- Wird eine Speicherabbildung im TLB nicht gefunden, wird der auf den Speicher zugreifende Prozess mit einer Schutzraumverletzung (Segmentation Fault) abgebrochen.
+  Nein, ist kein Eintrag im TLB zu finden, wird die Addresse von der MMU aufgelöst.
+.
+
+0 Welche Aussage zu Prozessen und Threads ist richtig? (2023-02)
+- Mittels `fork()` erzeugte Kindprozesse können in einem Multiprozessor-System nur auf dem Prozessor ausgeführt werden, auf dem auch der Elternprozess ausgeführt wird.
+  Nein, es ist dem Scheduler ganz überlassen zu entscheiden, auf welchen Prozessoren ein Prozess laufen soll.  Ein Prozess muss auch nicht ganz auf einem Kern oder nur auf einem Kern laufen
++ Der Aufruf von `fork()` gibt im Elternprozess die Prozess-ID des Kindprozesses zurück, im Kindprozess hingegen den Wert 0.
+  Ja, das steht auch so in der Man Page.  Die Annahme ist hier, dass kein Fehler aufgetreten ist.
+- Threads, die mittels `pthread_create()` erzeugt wurden, besitzen jeweils einen eigenen Adressraum.
+  Nein, Kind-Threads (im Kontext von der Pthread Bibliothek.) teilen den Addressraum mit dem Eltern-Thread.  Prozesse haben eigene Addressräume.
+- Die Veränderung von Variablen und Datenstrukturen in einem mittels `fork()` erzeugten Kindprozess beeinflusst auch die Datenstrukturen im Elternprozess.
+  Nein, allgemein nicht, außer der Benutzer richtet dieses spezifisch ein (Siehe `shm_open(3)`), was aber ohne weiteres nicht der Fall ist.
+.
+
+0 Was ist ein Stack-Frame? (2023-02)
+- Der Speicherbereich, in dem der Programmcode einer Funktion abgelegt ist.
+  Nein, ein Stack-Frame liegt im Stack Segment, und der Programmcode liegt im Text-Segment.
+- Ein Fehler, der bei unberechtigten Zugriffen auf den Stack-Speicher entsteht.
+  Nein, es gibt keinen gesonderten Namen für Fehlerhaften Zugriff auf den Stack-Namen.
++ Ein Bereich des Speichers, in dem u.a. lokale automatic-Variablen einer Funktion abgelegt sind.
+  Ja, ein Stack-Frame wird beim betreten einer Funktion angelegt für alle Metadaten und Daten welche zur ausführung benötigt werden und aufgeräumt sobald die Funktion verlassen wird.
+- Ein spezieller Registersatz des Prozessors zur Bearbeitung von Funktionen.
+  Nein, es ist kein Registersatz.
+.
+
+0 Welche der folgenden Informationen wird typischerweise in dem Seitendeskriptor einer Seite eines virtuellen Adressraums gehalten? (2023-02)
++ Die Zugriffsrechte auf die jeweilige Seite (z. B. lesen, schreiben, ausführen).
+  Ja, so setzt das Betriebsystem bspw. um, dass ein Text Segment ausführbar aber nicht schreibbar ist.
+- Die Identifikation des Prozesses, dem die Seite zugeordnet ist.
+  Nein, das Seiten existieren unabhängig von Prozessen und müssten per se nicht dafür benutzt werden, um logische Speicherräume auf Betriebsystemen mit unabhängigen Prozessen umzusetzen.
+- Die Zuordnung zu einem Segment (Text, Daten, ...).
+  Nein, dieses wird muss man sich nicht in dem Seitendeskriptor merken, weil es nur wichtig ist, dass die Seite sich gemäß dem Verständniss von diesen Segmenten verhällt (lesbar, ausfübar, ...).
+- Die Position der Seite im virtuellen Adressraum.
+  Nein, diese Zuordnung findet nicht im Seitendeskriptor statt, sondern im Betriebsystem.
+.