Skip to content
Snippets Groups Projects
Commit f46b4042 authored by Philip Kaluđerčić's avatar Philip Kaluđerčić :u7121:
Browse files

Add some questions

parent 61fcd195
No related branches found
No related tags found
No related merge requests found
ss16.q 0 → 100644
0 Welche Aussage zum Thema Speicherzuteilung ist richtig? (Juli 2016)
- 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.
Nein, weil diese bereits dann "unwiederbringlich" verloren gehen, sobald der Prozess sich beendet.
+ Beim Halbierungsverfahren (buddy-Verfahren) kann es vorkommen, dass zwei nebeneinander liegende freie Speicherbereiche nicht miteinander verschmolzen werden können.
Nur "echte nachbaren", d.h. Speicherbereiche welche intern nicht weiter getrennt sind, und aus einem Speicherbereich entstanden sind, können verschmolzen werden. Es ist möglich, dass zwei Speicherbereiche zwar neben einander liegen, aber nicht gleich groß sind.
- best-t ist in jedem Fall das beste Verfahren.
Nein, das versucht nur den Verschnitt zu minimieren, und opfert dafür Laufzeit, weshalb es nicht "in jedem Fall" das beste sein kann.
.
ss18.q 0 → 100644
0 Welche Aussage über Funktionen der `exec()`-Familie ist richtig? (Juli 2018)
- Dem Vater-Prozess wird die Prozess-ID des Kind-Prozesses zurückgeliefert.
Nein, bei `exec` wird ein Programm innerhalb von einem Prozess ersetzt. Die Funktion kehrt nur im Fehlerfall zurück, und kommuniziert nichts direkt an den Vater-Prozess.
- Der an `exec()` übergebene Funktionszeiger wird durch einen neuen Thread im aktuellen Prozess ausgeführt.
Nein, weil `exec` Funktionen keine Funktionszeiger nehmen, sondern ein Verweis auf eine Datei, in welchem das auszuführende Programm drin steht.
+ Falls kein Fehler auftritt, kehrt der Aufruf von `exec()` nicht zurück
Ja, weil dann das alte Programm im Prozess ersetzt wurde, und nicht mehr weiter laufen könnte.
- `exec()` erzeugt einen neuen Kind-Prozess und startet darin das angegebene Programm.
Nein, weil `exec` keine neuen Prozesse erstellt.
.
0 Welche Aussage über den Rückgabewert von fork() ist richtig? (Juli 2018)
+ 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.
- Im Fehlerfall wird im Kind-Prozess -1 zurückgeliefert.
Nein, im Fehlerfall (d.h. es konnte kein Kind erstellt werden) bekommt der Eltern-Prozess eine Fehler mit.
- Der Rückgabewert ist in jedem Prozess (Kind und Vater) jeweils die eigene Prozess-ID.
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)
- 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.
- Mit dem Systemaufruf `chdir()` kann das aktuelle Arbeitsverzeichnis eines Prozesses durch seinen Vaterprozess verändert werden.
Nein, das ändert den CWD von dem aufrufendem Prozess.
- 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)
+ 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.
Doch, weil das Betriebsystem diese kennt und in der Lage ist diese auf verschiedene Kerne einzulagern.
- Die Umschaltung von User-Threads ist eine privilegierte Operation und muss deshalb im Systemkern erfolgen.
Nein, weil dieses Umschalten keine privilegierte Operation ist.
- Zu jedem Kernel-Thread gehört ein eigener, geschützter Adressraum.
Nein, ein Kernel-Thread kann auch den gleichen Speicherraum mit anderen Threads teilen (bspw. im kontext von echtem Multi-Threading, siehe Pthread).
.
ss19.q 0 → 100644
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)
+ 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.
Nein, weil ein Interrupt keinen Einfluss haben muss auf diese Operation.
- Die Inkrementoperation muss mit einer CAS-Anweisung synchronisiert werden.
Nein, wenn notwenig, wäre es auch erlaubt es mit anderen mitteln zu sychronisieren.
- Die Operation i++ ist auf einem Monoprozessorsystem immer atomar.
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)
+ 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.
Ja, es kann auch direkt auf dem Stack gespeichert werden.
? Globale schreibbare Variablen liegen im Daten-Segment.
Ja-ish; diese können nicht im Text-Segment liegen, weil die dann nicht schreibbar währen; diese können nicht auf der Halde liegen, weil das zur laufzeit dynamisch verwaltet wird; diese können nicht auf dem Stack liegen, weil die gültigkeit unabhängig vom Kontrollfluss und dem Aufrufbaum ist.
- Dynamisch allozierte Zeichenketten liegen im Text-Segment.
Nein, weil das Text Segment üblicherweise nicht zur laufzeit verändert wird.
- Bei einem Aufruf von `malloc(3)` wird das Stack-Segment dynamisch erweitert.
Nein, dynamische Speicherverwaltung, würde wenn überhaupt die Halde (Heap) erweitern.
- Der Code von Funktionen wird zusammen mit den Variablen der Funktion im Stack-Segment abgelegt.
Nein, der Code von Funktionen liegt im Text Segment.
? Variablen der Speicherklasse `static` liegen im Daten-Segment.
Eigentlich ja, aber man kann dann diskutieren ob eine nicht-initialsierte `static` Variable, welche im BSS Segment liegt auch teil vom Daten-Segment ist oder nicht.
- Lokale `static`-Variablen werden bei jedem Betreten der zugehörigen Funktion neu initialisiert.
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)
- 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.
Zwar möglich, aber das ist nicht der Fall in C, wo Fehlerbehandlung händisch gemacht wird.
- Der Speicher schickt an die CPU einen Interrupt. Hierdurch wird das Betriebssystem angesprungen, das dem gerade laufenden Prozess das Signal `SIGSEGV` (Segmentation Violation) zustellt.
Der "Speicher" würde in diesem Fall keinen Interrupt schicken, weil der Zugriff auf den ungültigen Speicher bewusst und deterministisch aufgetreten ist, und daher als ein "Trap" angesehen werden sollte.
- Beim Zugriff muss die MMU, soweit vorhanden, die erforderliche Adressumsetzung vornehmen, erkennt die ungültige Adresse und löst einen Trap aus.
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)
- 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.
- Ein Anwendungsprozess muss bei der Verwendung von Semaphoren Interrupts sperren, um Probleme durch Nebenläugkeit zu verhindern.
Nein, wenn nur weil ein Anwendungsprozess keine Interrupts selbst sperren kann.
+ Gibt ein Faden einen Mutex frei, den er selbst zuvor nicht angefordert hatte, stellt dies einen Programmierfehler dar; eine Fehlerbehandlung sollte eingeleitet werden.
Ja, weil ein Mutex immer von dem gleichem Faden freigegeben werden sollte, wer es auch beansprucht hat (im Gegensatz zur binären Semaphore, wo diese Bedingung nicht gilt).
- Zur Synchronisation eines kritischen Abschnitts ist passives Warten immer besser geeignet als aktives Warten.
Je nach Situation ist es nicht möglich (bspw. im Kern selbst, wo die mechanismen Fehlen um "passiv").
.
ss22.q 0 → 100644
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)
+ Für jede reguläre Datei existiert mindestens ein Hard-Link im selben Dateisystem.
Wenn kein "Hardlink" auf eine Datei existiert, dann löscht das
Dateisystem die Datei. Daher muss auf jede existierende Datei
mindestens ein Verweis existieren.
- Wird der letzte Symbolic Link auf eine Datei gelöscht, so wird auch die Datei selbst gelöscht.
Symbolic Links sind nur verweise auf Dateipfade, wobei die Datei
hinter dem Dateipfad nichts von diesem Verweis wissen muss. Es ist
ja auch möglich auf eine nicht-existierende Datei zu verweisen.
- Ein Symbolic Link kann nicht auf Dateien anderer Dateisysteme verweisen.
Nein, weil Symbolic Links nur Pfade sind, welche das Betriebsystem
transparent auflöst, wenn man versucht auf die Datei zuzugreifen,
aber diese nichts über das tatsächliche System wissen. Bei
Hard-Links ist das hingengen nicht der fall, weil diese die gleiche
Inode-Nummer teilen müssen, was von Datei-System abhängig ist.
- Ein Hard Link kann nur auf Verzeichnisse verweisen, nicht jedoch auf Dateien.
Hard-Links können auf beides verweisen, nur ist es mit dem `link`
(bzw. dem `ln` Befehl) Systemaufruf dem Benutzer nicht erlaubt
selbst Verweise auf Verzeichnisse zu erstellen. Damit wird
sichergestellt, dass der Datei-Baum, der durch Hard-Link aufgespannt
wird, nicht zu einem graphen degeneriert, was Probleme bereiten
würde für Werkzeuge wie `find`.
.
0 Ausnahmesituationen bei einer Programmausführung werden in die beiden Kategorien Trap und Interrupt unterteilt. Welche der folgenden Aussagen ist zutreffend? (Juli 2022)
- 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
dann mit der MMU versucht wird diese einzulagern, und dann das
Programm weiter läuft) oder durch einen Systemaufruf ausgelöst
werden.
- Ein durch einen Interrupt unterbrochenes Programm darf je nach der Interruptursache entweder abgebrochen oder fortgesetzt werden.
Nein, weil ein Interrupt nichts mit dem Programm zu tun hat, und
daher dieses nicht (direkt) abbrechen sollte.
+ Obwohl Traps immer synchron auftreten, kann es im Rahmen ihrer Behandlung zu Wettlaufsituationen mit dem unterbrochenen Programm kommen.
Ja. Dazu muss man sich an die definition vom Programm erinnern:
> Festlegung einer Folge von Anweisungen für einen Prozessor, nach der die zur Bearbeitung einer (durch einen Algorithmus wohldefinierten) Handlungsvorschrift erforderlichen Aktionen stattfinden sollen
darunter kann auch das "Hauptprogramm" vom Betriebsystem verstanden
werden, welches von einem Trap-Handler unterbrochen wird. Sollten
beide (möglicherweise auf verschiedenen Kernen) versuchen
synchronisierte Operationen auszuführen, können diese sich
gleichzeitig verklemmen.
- Ein Systemaufruf im Anwendungsprogramm ist der Kategorie Interrupt zuzuordnen.
Nein, ein Systemaufruf ist ein Trap, weil diese deterministisch bei
der Ausführung auftreten, bspw. wenn je nach Rechenarchitektur ein
[`syscall`](https://www.felixcloutier.com/x86/syscall) (x86_64)
Befehl ausgeführt wird.
.
ws21.q 0 → 100644
ws22.q 0 → 100644
0 Welche der folgenden Aussagen zu statischem bzw. dynamischem Binden ist richtig? (Februar 2022)
- 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
Die Beschreibung trifft auf dynamisch gebundene Programmdateien,
weil Bibliotheksfunktionen zur Laufzeit auf `.so` Dateien laden, im
gegensatz zu statisch gebundenen Programmen, wo diese jedes mal zum
Bindezeitpunkt in die ausführbare Datei kopiert werden.
- Bei dynamischem Binden können Fehlerkorrekturen in Bibliotheken leichter übernommen werden, da nur die Bibliothek selbst neu erzeugt werden muss. Programme, die die Bibliothek verwenden, müssen nicht neu kompiliert und gebunden werden.
Ja. Im Gegensatz dazu, müsste man bei einem statischen Bibliothek
alle Programme nochmal neu, gegen die aktualisierte Bibliothek
bauen, damit diese die neuste Version benutzen.
- Beim statischen Binden werden alle Adressen zum Ladezeitpunkt aufgelöst
Nein, Adressen werden alle beim Binden aufgelöst, und sind somit
unabhängig von der Ausführung -- *statisch* -- bekannt.
- Bei dynamischem Binden müssen zum Übersetzungszeitpunkt alle Adressbezüge vollständig aufgelöst werden
Nein, Bibliotheksfunktionen welche aus *Shared Object* Dateien
geladen werden können zur Laufzeit, müssen nicht beim Übersetzen
bereits aufgelöst geworden sein.
.
0 Welche Antwort trifft für die Eigenschaften eines UNIX/Linux-Dateideskriptor zu? (Februar 2022)
- 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.
Nein, es ist zwar eine Ganzzahl, aber diese kann nicht beliebig hin und her gereicht werden, zumindest ohne dass das Betriebsystem entsprechend informiert wird (siehe `sendmsg(2)`).
- Dateideskriptoren sind Zeiger auf Betriebssystemstrukturen, die von den Systemaufrufen ausgewertet werden, um auf Dateien zuzugreifen.
Nein, es handelt sich nicht um einen Zeiger im gewöhnlichen Sinne (eine Adresse auf eine Speicherstelle), auch wenn es üblicherweise dazu benutzt wird um eine Prozess-Lokale Datei Tabelle zu Adressieren. Es stimmt aber, dass es dazu benutzt wird, einem Systemaufruf eine Datei anzudeuten, auf dem dieses arbeiten soll.
+ Ein Dateideskriptor ist eine prozesslokale Integerzahl, die der Prozess zum Zugriff auf eine Datei, ein Gerät, einen Socket oder eine Pipe benutzen kann.
Ja, ein Dateideskriptor muss nicht nur auf "gewöhnlichen" Dateien arbeiten, sondern kann verschieden "Datei-Ähnlichen" Objekten (d.h. Datenströmen) abstrahieren. Wichtig ist auch der Punkt "prozesslokal", weil die Zahl nur eine Bedeutung hat, wenn das Betriebsystem dem Prozess diese Zahl zuvor explizit vergeben hat.
- Beim Öffnen ein und derselben Datei erhält ein Prozess jeweils die gleiche Integerzahl als Dateideskriptor zum Zugriff zurück.
Nein, es ist möglich eine Datei Mehrfach zu öffnen, und dabei mehrere Dateideskriptoren zu bekommen. Versuche
~~~
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
int fd1 = open("/etc/passwd", O_RDONLY);
int fd2 = open("/etc/passwd", O_RDONLY);
printf("fd1: %d, fd2: %d\n", fd1, fd2);
}
~~~
.
1 Man unterschiedet zwei Kategorien von Ausnahmesituationen bei einer Programmausführung: Traps und Interrupts. Welche der folgenden Aussagen sind zutreffend? (Februar 2022)
+ Ein Programm darf im Rahmen einer Trapbehandlung abgebrochen werden.
Ja, Beispielsweise bei einem ungültigem Speicherzugriff.
+ Ein durch einen Interrupt unterbrochenes Programm darf je nach der Interruptursache entweder abgebrochen oder fortgesetzt werden.
Ja, so ist ein _Timer Interrupt_ nicht fatal, und aktiviert nur den
Scheduler, während ein _Tastatur Interrupt_ so konfiguriert werden
kann, dass ein Prozess unterbrochen wird (denke an `Ctrl-C`).
- Bei einem Trap wird der gerade in Bearbeitung bendliche Maschinenbefehl immer noch vollständig zu Ende bearbeitet, bevor mit der Trapbehandlung begonnen wird.
Nein, bspw. wenn man versucht auf nicht lesbaren Speicher versucht
zuzugreifen, muss es abgebrochen werden, bevor auf den Speicher
zuggegriffen wurde.
+ Die CPU sichert bei einem Interrupt einen Teil des Prozessorzustands.
Ja, genau wie bei einer Signal-Behandlung unterbricht ein Interrupt
das "Hauptprogramm" vom Betriebsystem. Der Prozessorzustand muss
dafür vermerkt worden sein, damit es danach wieder restauriert
werden kann.
+ Die Ausführung einer Ganzzahl-Rechenoperation (z. B. Addition, Division) kann zu einem Trap führen.
Ja, eine Rechnerarchitektur kann beim Teilen durch 0 ein Trap auslösen.
- Da Traps immer synchron auftreten, kann es im Rahmen ihrer Behandlung nicht zu Wettlaufsituationen mit dem unterbrochenen Programm kommen.
Nein, weil Traps eben immer syncrhron auftreten, gibt es keine
Nebenläufigkeit welche Probleme bereitet.
? Wenn ein Interrupt ein schwerwiegendes Ereignis signalisiert, wird das unterbrochene Programm im Rahmen der Interruptbearbeitung immer abgebrochen.
- Ein Systemaufruf im Anwendungsprogramm ist der Kategorie Interrupt zuzuordnen.
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)
- Der Prozess ruft die Bibliotheksfunktion `exit(3)` auf.
Nein, weil danach der Prozess nicht mehr "bereit" ist (d.h. wieder eingelagert werden kann).
+ Der Scheduler bewirkt, dass der Prozess durch einen anderen Prozess verdrängt wird.
Ja, weil die einzige Ressource welche dem Prozess fehlt ist die CPU, welche der Scheduler später wieder "vergeben" kann, und damit der Prozess auch die ganze Zeit bereit ist wieder weiter zu laufen.
- Der Prozess greift lesend auf eine Datei zu und der entsprechende Datenblock ist noch nicht im Hauptspeicher vorhanden.
Nein, weil dann idr. der Prozess beendet wird mit einem Sigal wie `SIGSEVG`, und nicht mehr laufen darf.
- Der Prozess ruft eine P-Operation auf einen Semaphor auf, welcher den Wert 0 hat.
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% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment