Klausur zum Kurs 1618

Werbung
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
Kurs 01618
Einführung in die
objektorientierte Programmierung
_________________________________________________________
(Name, Vorname)
_________________________________________________________
(Kursdurchführung des Sommersemester 2017)
_________________________________________________________
(Straße, Nr.)
______________
(PLZ)
Klausur am 16.09.2017
________________________________________
(Wohnort)
Zweistündige Klausur
(10.00 – 12.00 Uhr)
_________________________________________________________
(Land, falls außerhalb Deutschlands)
Lesen Sie zuerst die Hinweise auf der folgenden Seite!
Matrikelnummer:
Geburtsdatum:
.
.
Klausurort: _________________________
Aufgabe
1
2
3
4
5
6
7
8
Summe
10
10
10
10
10
10
10
10
80
habe bearbeitet
maximal
erreicht
Korrektur
○
○
Herzlichen Glückwunsch, Sie haben die Klausur bestanden. Note: ..........
Sie haben die Klausur leider nicht bestanden. Für den nächsten Versuch wünschen wir Ihnen
viel Erfolg. Die nächste Klausur findet im Wintersemester 2017 / 2018 statt.
MUSTERLÖSUNG
Hagen, den 27.09.2017
Im Auftrag
© 2017 FernUniversität in Hagen
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
Klausur zum Kurs 01618 im Sommersemester 2017
Aufgabe 1: Klassenimplementierung
(10 Punkte)
Gegeben sei das folgende Programmfragment:
public class HeimkinoDemo {
public static void main(String[] args) {
TonSystem m = new TonSystem(2);
BluRayPlayer t = new BluRayPlayer();
TvGerät c = new TvGerät(t, m);
c.bluRayPlayer.einlegen(new BluRayMedium("Star Wars"));
try {
c.tonSystem.erwarteKanäle(6);
System.out.println("Surround-Sound-Tonsystem.");
} catch (Exception e) {
System.out.println("Kein Surround-Sound Tonsystem.");
}
try {
c.tonSystem.erwarteKanäle(2);
System.out.println("Stereo-Tonsystem.");
} catch (Exception e) {
System.out.println("Kein Stereo-Tonsystem.");
}
}
}
Geben Sie Implementierungen für die Klassen TonSystem, BluRayPlayer, BluRayMedium und TvGerät
an, sodass dieses Programmfragment kompiliert werden kann und bei Terminierung der main-Methode
die folgenden Zeilen auf der Konsole ausgegeben werden.
Tonsystem mit 2 Kanälen erzeugt.
Film 'Star Wars' eingelegt.
Kein Surround-Sound Tonsystem.
Stereo-Tonsystem.
Diese Zeichenketten sollen selbstverständlich durch die jeweiligen Anweisungen zusammengesetzt und
ausgegeben werden.
(Fortsetzung der Aufgabe auf der folgenden Seite)
Seite 1
Klausur zum Kurs 01618 im Sommersemester 2017
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
(Fortsetzung von Aufgabe 1)
class TvGerät {
BluRayPlayer bluRayPlayer;
TonSystem tonSystem;
public TvGerät(BluRayPlayer bluRayPlayer, TonSystem hiFiSystem) {
this.bluRayPlayer = bluRayPlayer;
this.tonSystem = hiFiSystem;
}
}
class BluRayPlayer {
public void einlegen(BluRayMedium medium) {
System.out.println("Film '" + medium.titel + "' eingelegt.");
}
}
class BluRayMedium {
String titel;
public BluRayMedium(String titel) {
this.titel = titel;
}
}
class TonSystem {
private int kanäle;
public TonSystem(int kanäle) {
this.kanäle = kanäle;
System.out.println("Tonsystem mit " + kanäle + " Kanälen erzeugt.");
}
public void erwarteKanäle(int erwarteteKanäle) throws Exception {
if (kanäle != erwarteteKanäle)
throw new Exception();
}
}
Seite 2
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
Klausur zum Kurs 01618 im Sommersemester 2017
Aufgabe 2: (Beschränkt) param. Polymorphie
(10 Punkte)
Gegeben sei das folgende Programmfragment:
public class Wohnzimmer {
public static void main(String[] args) {
Kiste kiste = new Kiste();
Regal regal = new Regal();
Brettspiel schach = new Brettspiel(kiste);
Buch herrDerRinge = new Buch(regal);
Gegenstand<?> einGegenstand = schach;
Möbelstück möbel = einGegenstand.lagerort();
Kiste spieleKiste = schach.lagerort();
Regal bücherRegal = herrDerRinge.lagerort();
/* [1] */
// Fehler in Aufgabe:
// schach statt spiel
// schach statt spiel
// herrDerRinge statt buch
}
}
class Möbelstück { }
class Kiste extends Möbelstück { }
class Regal extends Möbelstück { }
Geben Sie eine Implementierung für die Klassen Gegenstand, Brettspiel und Buch an, sodass dieses
Programmfragment kompiliert. Die Methode lagerort() soll insgesamt nur ein einziges Mal implementiert werden.
(5 Punkte)
Hinweis: In der Aufgabenstellung haben sich zwei kleine Fehler eingeschlichen (s.o.). Obwohl sich der
nachfolgende Lösungsvorschlag hierdurch nicht ändert, wurde das bei der Korrektur Ihrer Lösungen
berücksichtigt.
abstract class Gegenstand<T extends Möbelstück> {
T lagerort;
public Gegenstand(T lagerort) {
this.lagerort = lagerort;
}
T lagerort() {
return lagerort;
}
}
class Brettspiel extends Gegenstand<Kiste> {
public Brettspiel(Kiste lagerort) {
super(lagerort);
}
}
class Buch extends Gegenstand<Regal> {
public Buch(Regal lagerort) {
super(lagerort);
}
}
(Fortsetzung der Aufgabe auf der folgenden Seite)
Seite 3
Klausur zum Kurs 01618 im Sommersemester 2017
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
(Fortsetzung von Aufgabe 2)
Die main-Methode wird nun an der mit /* [1] */ markierten Stelle um die folgenden Zeilen ergänzt:
Kiste andereKiste = new Kiste();
Brettspiel dame = new Brettspiel(andereKiste);
schach.tauschePlatz(dame);
Regal anderesRegal = new Regal();
Buch harryPotter = new Buch(anderesRegal);
herrDerRinge.tauschePlatz(harryPotter);
Während diese zwei Aufrufe von tauschePlatz(.) durch den Compiler akzeptiert werden sollen, soll
der Aufruf von
herrDerRinge.tauschePlatz(schach);
zurückgewiesen werden.
Geben Sie eine (einzige) Implementierung der Methode tauschePlatz(.) an, die diese Kriterien erfüllt.
In welcher Klasse steht diese?
(2,5 Punkte)
abstract class Gegenstand<T extends Möbelstück> {
…
public void tauschePlatz(Gegenstand<T> andererGegenstand) {
T andererLagerort = andererGegenstand.lagerort();
andererGegenstand.lagerort = this.lagerort;
this.lagerort = andererLagerort;
}
}
Erklären Sie, warum der Compiler den letztgenannten Aufruf zurückweist.
(2,5 Punkte)
Das durch herrDerRinge referenzierte Objekt ist vom Typ Gegenstand<Regal> - der Typparameter T der
Klasse Gegenstand ist also mit dem Typen Regal belegt. Die Implementierung der Methode
tauschePlatz erwartet ein Objekt vom Typ Gegenstand, bei dem der Typparameter mit dem gleichen
Typen belegt ist wie in dem Empfängerobjekt; in diesem Fall also ebenfalls Regal.
Das durch schach referenzierte Objekt hingegen ist vom Typ Gegenstand<Kiste>, der Typparameter T
von Gegenstand ist also mit Kiste belegt. Zwischen Gegenstand<Regal> und Gegenstand<Kiste> besteht
jedoch keine Subtypbeziehung. Der aktuelle Parameter schach kann also nicht dem formalen Parameter andererRegenstand zugewiesen werden, wenn das Empfängerobjekt herrDerRinge ist.
Hinweis: Das bedeutet nicht, dass der Gegenstand, welcher der Methode tauschePlatz übergeben
wird, vom gleichen Typ sein muss wie der, auf dem sie aufgerufen wird. Gleich sein müssen nur die
Möbelstücke, mit denen die beiden Gegenstände parametrisiert wurden. Wenn es beispielsweise eine
Klasse "Vase extends Gegenstand<Regal>" gäbe, könnte eine Vase problemlos ihren Platz mit einem
Buch tauschen.
Seite 4
Klausur zum Kurs 01618 im Sommersemester 2017
Aufgabe 3: Subtyping
Was besagt die Grundregel des Subtyping?
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
(10 Punkte)
(2 Punkte)
(Abs. 3.2.2.2) „Die Grundregel für Subtyping besagt, dass ein Objekt von einem Subtyp an allen Programmstellen vorkommen kann, an denen Supertyp-Objekte zulässig sind.“
Welche syntaktischen Voraussetzungen müssen erfüllt sein, wenn in einer Subklasse eine geerbte Methode überschrieben werden soll?
(3 Punkte)
(vgl. Abs. 3.2.2.2) Um eine Methode zu überschreiben, muss in der Subklasse eine Methode gleichen
Namens deklariert werden. Weiterhin müssen die Typen von Parametern, Rückgabeparametern und
Ausnahmen der überschreibenden Methode zu denen der überschriebenen passen; d.h.:
 Theoretisch: Kontravarianz bei Parametertypen; Kovarianz bei Rückgabe- und Ausnahmetypen.
 für Java >= 5: Gleichheit der Parametertypen, Kovarianz bei Rückgabe- und Ausnahmetypen.
(Kontravarianz der Parametertypen wird in Java nicht unterstützt, da es andernfalls bei überladenen Methoden zu Konstellationen kommen kann, in denen der Compiler einen Methodenaufruf nicht eindeutig an eine Deklaration binden kann.)
 für Java < 5: Gleichheit von Parameter- und Rückgabetypen
Ist es ausreichend, die syntaktischen Voraussetzungen zu überprüfen, um sicherzustellen, dass ein Typ
ein Subtyp ist? Welche besondere Herausforderung liegt hierin für den Programmierer / die Programmiererin?
(5 Punkte)
(vgl. Abs. 3.2.2.2) Nein, das Konzept des Subtyping beschränkt sich nicht auf syntaktischer Konformität von Methodendeklarationen. Die Eigenschaft, dass ein Objekt eines Subtyps überall dort eingesetzt
werden kann, wo ein Objekt eines Supertyps erwartet wird, stellt vielmehr auch die Forderung an das
Verhalten des Objektes, dass es den Erwartungen genügen muss, die an den Supertypen gestellt werden. Nur, wenn diese Erwartungen durch den Subtyp nicht verletzt werden, verhält dieser sich konform und ist damit ein Subtyp. Dies sicher zu stellen ist Aufgabe des Programmierers / der Programmiererin, da in der Regel keine formale Verhaltensspezifikation vorliegt bzw. geprüft werden kann.
Seite 5
Klausur zum Kurs 01618 im Sommersemester 2017
Aufgabe 4: Polymorphie
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
(10 Punkte)
Welche vier Arten von Polymorphie kennen Sie?




(2 Punkte)
Subtyp-Polymorphie
parametrische Polymorphie
beschränkt parametrische Polymorphie
(hierbei handelt es sich um eine spezielle Form der parametrischen Polymorphie)
Ad-hoc Polymorphie
Charakterisieren Sie jede Art kurz!
(jeweils 2 Punkte)
Subtyp-Polymorphie wird durch Subtyping erreicht. Das bedeutet, dass an den Stellen, an denen ein
Objekt vom Typ Typ erwartet wird, auch Objekte beliebiger Typen Subtyp stehen dürfen, sofern diese
Subtypen von Typ sind.
Parametrische Polymorphie wird dadurch realisiert, dass bestimmte Konstrukte einer Programmiersprache – z.B. Methoden oder Klassen – durch Typparameter parametrisiert werden. Bei der Verwendung
eines so parametrisierten Konstrukts wird der Typparameter durch einen konkreten Typen ersetzt. So ist
es möglich, eine generische Implementierung einer Funktionalität anzugeben, die in verschiedenen Kontexten typsicher genutzt werden kann.
Die beschränkt parametrische Polymorphie begegnet dem Problem der (einfachen) parametrischen
Polymorphie, dass innerhalb der generischen Klasse keine Informationen über den Typen, mit dem der
Typparameter belegt wird, zur Verfügung stehen. Hierin können so ohne eine explizite Typkonvertierung
(Type Casts) keine spezifischen Methoden verwendet werden. Durch die Angabe einer Schranke zu dem
Typparameter kann nun hingegen festgelegt werden, dass dieser lediglich durch Subtypen der Schranke
belegt werden kann. So kann auch ohne Typkonvertierung (Type Cast) innerhalb der generischen Implementierung auf die durch die Schranke deklarierte Schnittstelle zugegriffen werden.
Als Ad-hoc Polymorphie wird das Überladen von Operatoren bzw. Methodennamen bezeichnet. Für
identifizierte Operationen können so für unterschiedliche Argumenttypen jeweils optimierte Implementierungen angegeben werden.
Seite 6
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
Klausur zum Kurs 01618 im Sommersemester 2017
Aufgabe 5: Arrays
(10 Punkte)
Gegeben sei das folgende Programmfragment, welches die Zahlen 𝑛 mit 1 ≤ 𝑛 ≤ 𝑚𝑎𝑥 in Hexadezimalnotation konvertieren, in ein Array speichern und ausgeben soll:
public class ArrayDemo {
public static void main(String[] args) {
int max = Integer.parseInt(args[0]);
/* [1] */
/* [2] */
/* [3] */
}
}
Teilaufgabe a: Erste Implementierung
(4 Punkte)
Hinweis:
Die statische Bibliotheksfunktion Integer.toHexString(int) konvertiert die per Parameter angegebene
Zahl in Hexadezimalnotation. So liefert Integer.toHexString(11) etwa die Zeichenkette “b“.
Wodurch muss /* [1] */ ersetzt werden, um das (eindimensionale) Array mit dem Namen zahlen zu
initialisieren?
(1 Punkt)
String[] zahlen = new String[max];
Wodurch muss /* [2] */ ersetzt werden, um die Hexadezimalnotationen aller 𝑛 mit 1 ≤ 𝑛 ≤ 𝑚𝑎𝑥 in
dieses Array zu schreiben? Bitte verwenden Sie eine Schleife!
(2 Punkte)
for (int i = 1; i <= max; i++) {
zahlen[i - 1] = Integer.toHexString(i);
}
Wodurch muss /* [3] */ ersetzt werden, um den Inhalt des Arrays auf die Konsole zu
schreiben? Bitte verwenden Sie eine Schleife – und zwar eine Schleife einer anderen Art als die, die Sie
in Ihrer Implementierung zur Ersetzung von /* [2] */ verwendet haben!
(1 Punkt)
for (String i : zahlen){
System.out.println(i);
}
(Fortsetzung der Aufgabe auf der folgenden Seite)
Seite 7
Klausur zum Kurs 01618 im Sommersemester 2017
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
(Fortsetzung von Aufgabe 5)
Teilaufgabe b: Zweite Implementierung
(6 Punkte)
In der zweiten Implementierung soll nun nicht nur die Hexadezimalnotation einer Zahl gespeichert
werden, sondern auch ihre Binärnotation. Dazu soll ein zweidimensionales Array (also ein Array von
Arrays) verwendet werden.
Hinweis:
Analog zu Integer.toHexString(int) existiert auch eine Methode Integer.toBinaryString(int), die
der Konvertierung einer Zahl in Binärnotation dient; so liefert Integer.toBinaryString(73) etwa die
Binärnotation von 73, also die Zeichenkette „1001001“.
Wodurch muss /* [1] */ ersetzt werden, um das Array mit dem Namen zahlen zu initialisieren, welches aus Arrays der Dimension 2 besteht?
(2 Punkt)
String[][] zahlen = new
String[max][2];
Wodurch muss /* [2] */ ersetzt werden, um die Paare Binär- und Hexadezimalnotation in dieses Array zu schreiben? Bitte verwenden Sie eine Schleife!
(2 Punkte)
for (int i = 1; i <= max; i++) {
zahlen[i - 1][0] = Integer.toBinaryString(i);
zahlen[i - 1][1] = Integer.toHexString(i);
}
Wodurch muss /* [3] */ ersetzt werden, um die Zahlen in Binär- und Hexadezimalnotation (genauer:
in dem Format „x : y“, wobei x die Binär- und y die Hexadezimanotation ist) auf die Konsole zu
schreiben? Bitte verwenden Sie eine Schleife – und zwar eine Schleife einer anderen Art als die, die Sie
in Ihrer Implementierung zur Ersetzung von /* [2] */ verwendet haben.
(2 Punkt)
for (String[] i : zahlen){
System.out.println(i[0] + " : " + i[1]);
}
Seite 8
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
Klausur zum Kurs 01618 im Sommersemester 2017
Aufgabe 6: Kontrollfluss und der this-Parameter
(10 Punkte)
Gegeben sei folgendes Java-Programm:
public class EineNeueKlasse {
String tier = "Pinguin";
public static void main(String[] args) {
new EineNeueKlasse("Biene").m(42L);
}
EineNeueKlasse(String tier) {
System.out.println(this.tier);
}
void m(Number n){
System.out.println("Esel");
new WeitereInnereKlasse().methode(new SubInnereKlasse("Giraffe"));
}
void m(Long l) {
System.out.println("Löwe");
new WeitereInnereKlasse().methode(new SubInnereKlasse("Giraffe"));
}
class InnereKlasse {
String tier = "Elefant";
InnereKlasse(String tier) {
System.out.println(this.tier);
}
void n(WeitereInnereKlasse weitereInnere) {
System.out.println("Hund");
}
void n(EineNeueKlasse eineNeue) {
System.out.println("Hamster");
}
}
class SubInnereKlasse extends InnereKlasse{
String tier = "Adler";
public SubInnereKlasse(String tier) {
super("Hase");
System.out.println(tier);
}
}
static class WeitereInnereKlasse {
{
System.out.println("Bär");
/* [2] */
}
void methode(InnereKlasse innereKlasse) {
innereKlasse.n(this);
}
}
static void andereMethode() {
/* [1] */
}
}
(Fortsetzung der Aufgabe auf der folgenden Seite)
Seite 9
Klausur zum Kurs 01618 im Sommersemester 2017
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
(Fortsetzung von Aufgabe 6)
Welche Zeilen wurden nach Terminierung der main(.)-Methode auf der Konsole ausgegeben?
(6 Punkte)
Pinguin
Löwe
Bär
Elefant
Giraffe
Hund
An der mit /* [1] */ markierten Stelle wird die folgende Anweisung eingefügt. Warum weist der
Compiler sie zurück?
System.out.println(this.tier);
(2 Punkte)
Die mit andereMethode bezeichnete Methode, in deren Rumpf diese Anweisung eingefügt wird, ist
statisch. Sie ist damit keinem Objekt zugeordnet und hat insbesondere keinen impliziten thisParameter, welcher ja immer ein Objekt als Instanz einer Klasse referenziert. In der Konsequenz kann
auch tier nicht referenziert werden, da es ein Objekt- und kein Klassenattribut ist. Das Programm ist
somit ungültig.
An der mit /* [2] */ markierten Stelle wird die folgende Anweisung eingefügt. Warum weist der
Compiler sie zurück?
System.out.println(EineNeueKlasse.this.tier);
(2 Punkte)
Der Initialisierungsblock, in den diese Anweisung eingefügt werden soll, gehört zu der inneren Klasse
WeitereInnereKlasse, welche static deklariert ist. Als solche ist sie – wie auch statische Methoden –
nicht einem Objekt der umschließenden Klasse EineNeueKlasse zugeordnet, sondern der Klasse selbst.
Eine Instanz der umschließenden Klasse EineNeueKlasse, welche mit EineNeueKlasse.this referenziert
werden könnte, existiert somit gar nicht und das Programm ist ungültig.
Seite 10
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
Klausur zum Kurs 01618 im Sommersemester 2017
Aufgabe 7: Aufzählungstypen
(10 Punkte)
Die Monate der Freibadsaison (Mai bis September) sollen als Aufzählungstyp SaisonMonat implementiert werden. Die Werte des Aufzählungstypen sollen über die folgenden vier Methoden verfügen:




boolean istNach(SaisonMonat monat): Liefert true, wenn der durch das Empfängerobjekt bezeichnete Monat nach dem Monat liegt, der durch das Objekt bezeichnet wird, welches durch
den Parameter monat referenziert wird; ansonsten false. (Wobei angenommen wird, dass beide
Objekte für Monate des gleichen Jahres stehen.)
boolean istVor(SaisonMonat monat): Liefert true, wenn der durch das Empfängerobjekt bezeichnete Monat vor dem Monat liegt, der durch das Objekt bezeichnet wird, welches durch
den Parameter monat referenziert wird; ansonsten false. (Wobei angenommen wird, dass beide
Objekte für Monate des gleichen Jahres stehen.)
SainsonMonat naechsterSaisonMonat(): Liefert das Element der Aufzählung, welches den Monat beschreibt, der unmittelbar nach dem durch das Empfängerobjekt bezeichneten Monat
liegt; wobei dies auch der erste Monat des folgenden Jahres sein kann.
SainsonMonat vorherigerSaisonMonat(): Liefert das Element der Aufzählung, welches den Monat beschreibt, der unmittelbar vor dem durch das Empfängerobjekt bezeichneten Monat liegt;
wobei dies auch der letzte Monat der vorherigen Saison sein kann.
Die main-Methode der Klasse FreibadSaisonDemo verdeutlicht die Bedeutung der Methoden anhand
einiger Beispiele. Der in jeder Zeile hinten angefügte Kommentar gibt dabei jeweils den Wert an, zu
dem der Ausdruck dieser Zeile auswerten soll.
public class FreibadSaisonDemo {
public static void main(String[] args) {
SaisonMonat.JULI.istVor(SaisonMonat.MAI);
SaisonMonat.JULI.istVor(SaisonMonat.JUNI);
SaisonMonat.JULI.istVor(SaisonMonat.JULI);
SaisonMonat.JULI.istVor(SaisonMonat.AUGUST);
SaisonMonat.JULI.istVor(SaisonMonat.SEPTEMBER);
//
//
//
//
//
false
false
false
true
true
SaisonMonat.JULI.istNach(SaisonMonat.JUNI);
SaisonMonat.JULI.istNach(SaisonMonat.JULI);
SaisonMonat.JULI.istNach(SaisonMonat.AUGUST);
// true
// false
// false
SaisonMonat.JULI.naechsterSaisonmonat();
SaisonMonat.JULI.vorherigerSaisonmonat();
// SaisonMonat.AUGUST
// SaisonMonat.JUNI
SaisonMonat.SEPTEMBER.naechsterSaisonmonat();
SaisonMonat.MAI.vorherigerSaisonmonat();
// SaisonMonat.MAI
// SaisonMonat.SEPTEMBER
}
}
Da das Freibad in Kürze in der Lage ist, das Wasser der Becken zu beheizen, zieht der Betreiber in Erwägung, die Saison auf die angrenzenden Monate April und Oktober auszudehnen. Vervollständigen
Sie folgende Implementierung der Klasse FreibadSaison derart, dass die Methodenimplementierungen
bei einer Erweiterung des Aufzählungstyps um die Elemente APRIL und OKTOBER nicht verändert werden
müssen.
(Fortsetzung der Aufgabe auf folgender Seite)
Seite 11
Klausur zum Kurs 01618 im Sommersemester 2017
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
(Fortsetzung von Aufgabe 7)
enum SaisonMonat {
MAI, JUNI, JULI, AUGUST, SEPTEMBER;
(1 Punkt)
boolean istNach(SaisonMonat monat) {
// Hinweis: In der Methodenbeschreibung muss es korrekterweise heißen:
// … Liefert true, wenn der durch das Empfängerobjekt bezeichnete Monat
//
nach dem Monat liegt, der …
return this.ordinal() > monat.ordinal();
}
(1 Punkt)
boolean istVor(SaisonMonat monat) {
// Hinweis: In der Methodenbeschreibung muss es korrekterweise heißen:
// … Liefert true, wenn der durch das Empfängerobjekt bezeichnete Monat
//
vor dem Monat liegt, der …
return this.ordinal() < monat.ordinal();
}
(4 Punkte)
SaisonMonat naechsterSaisonmonat() {
int nächsterIndex = this.ordinal() + 1;
if ( nächsterIndex == SaisonMonat.values().length)
nächsterIndex = 0;
return SaisonMonat.values()[ nächsterIndex ];
}
(4 Punkte)
SaisonMonat vorherigerSaisonmonat() {
int vorherigerIndex = this.ordinal() - 1;
if ( vorherigerIndex < 0)
vorherigerIndex = SaisonMonat.values().length - 1;
return SaisonMonat.values()[ vorherigerIndex ];
}
}
Seite 12
Klausur zum Kurs 01618 im Sommersemester 2017
Lehrgebiet Programmiersysteme
Prof. Dr. Friedrich Steimann
Aufgabe 8: Parallelität
Welche Varianten lokaler Parallelität lassen sich unterscheiden? Erklären Sie sie!
(10 Punkte)
(3 Punkte)
Reale Parallelität bedeutet, dass in einem einzigen System verschiedene Aktionen tatsächlich parallel
ablaufen können. Virtuelle Parallelität (oder auch Quasi-Parallelität) hingegen bedeutet, dass Aktionen, die zwar echt parallel laufen könnten, zunächst sequentialisiert werden und nacheinander ausgeführt werden. So kann ein Softwaresystem auch auf einem Einprozessorsystem scheinbar parallel ausgeführt werden.
Warum ist es auch dann von Vorteil, ein Softwaresystem so zu implementieren, dass es parallel ausgeführt werden kann, wenn es nur auf einem Einprozessorsystem laufen soll?
(3 Punkte)
Häufig ist es nicht notwendig, die Ausführungsreihenfolge zweier Aktionen a und b festzulegen;
d.h. für die Funktionalität des Programms ist es äquivalent, ob zuerst a oder b ausgeführt wird. In
diesem Fall erlaubt die Berücksichtigung der Parallelität, auf eine künstliche Sequentialisierung einer
Implementierung zu verzichten und überlässt es einem Scheduler, zwischen verschiedenen Ausführungssträngen zu wechseln. Eine solche verschränkte Ausführung ist insbesondere dann von Vorteil,
wenn ein Strang gerade nichts „Sinnvolles“ tun kann, da er z.B. auf eine Antwort aus dem Netzwerk
oder einem Gerät (z.B. der Festplatte) wartet.
Welche Aufgabe hat der Scheduler? Welche Arten des Schedulings können unterschieden werden?
Wann ist das Scheduling fair?
(4 Punkte)
Der Scheduler hat die Aufgabe, die für die Programmausführung zur Verfügung stehenden Prozessoren den verschiedenen Ausführungssträngen zuzuteilen.
Beim preemptiven Scheduling entscheidet der Scheduler darüber, wie lange ein Ausführungsstrang
rechnen darf. So kann er dem Strang z.B. nach Ablauf eines bestimmten Zeitfensters den Prozessor
entziehen und ihn einem anderen Strang zuweisen.
Beim nicht-preemptiven Scheduling entscheidet ein Ausführungsstrang selbstständig darüber,
wann er einen Prozessor wieder freigibt. Bei unvorsichtiger Implementierung kann dies dazu führen,
dass ein Ausführungsstrang alle anderen blockiert.
Das Scheduling ist dann fair, wenn der Scheduler garantiert, dass jeder Ausführungsstrang nach einer endlichen Wartezeit einen Prozessor zugeteilt bekommt.
Seite 13
Herunterladen