Tentamen 15 juni 2005 met uitwerking

advertisement
T ENTAMEN
PROGRAMMEREN 2
vakcode:
datum:
tijd:
213505
15 juni 2005
9.00–12.30 uur
UITWERKING
Algemeen
Bij dit tentamen mag alleen gebruik worden gemaakt van de boeken van Niño/Hosch en van der
Linden en één ander Java-leerboek naar keuze, van de practicumhandleiding van Programmeren 2 (in
het bijzonder bijlage B), en van uitgeprinte kopieën van de hoorcollegesheets.
Het aantal punten voor het tentamen wordt meegenomen in de berekening van het eindcijfer, op de
manier zoals aangegeven in de handleiding.
Dit tentamen bestaat uit 5 opgaven, waarvoor in het totaal 100 punten behaald kunnen worden. Het
minimaal aantal punten per opgave bedraagt 0 punten.
Ter indicatie staat in onderstaande tabel een schatting van de moeilijkheidsgraad van de opgaven (+ is
eenvoudig, + + + + + is zeer moeilijk), samen met de verwachte tijd die nodig is om de desbetreffende
opgave op te lossen.
opg.
1
2
3
4
5
onderwerp
recursie
excepties
collecties
MVC
threads
punten
20 pnt.
15 pnt.
25 pnt.
20 pnt.
20 pnt.
moeilijkheid
+++
++
+++
++
+++
tijd
30 min
20 min
40 min
40 min
30 min
Uiteraard kunnen aan bovenstaande tabel géén rechten worden ontleend.
H ERHALERS . In dit tentamen wordt gebruik gemaakt van generics, die sinds versie 5 (aka 1.5) in Java
ondersteund worden. Het is toegestaan om de opgaven uit te werken zonder gebruik te maken van generics.
Een List<T> moet dan gelezen worden als List, een Set<T> is een Set, en een Map<K,V> is dan gewoon
een Map. Geef echter wel duidelijk aan dat Java versie 1.4 verondersteld wordt. De Java programmatuur zal
in dat geval nagekeken worden als ware het geschreven voor Java 1.4.
JAVA D OC . Bij enkele opgaven van dit tentamen wordt gevraagd om, gegeven een javadoc-specificatie
van een methode, de implementatie van die betreffende methode te schrijven. Bij het beantwoorden van
een dergelijke opgave is het uiteraard niet nodig om het javadoc-commentaar te herhalen. Voeg alleen
javadoc-commentaar toe als daar expliciet om gevraagd wordt.
D EJA V U . Wegens tijdgebrek bestaat dit tentamen van P2 vrijwel geheel uit opgaven die al eerder in een
tentamen van P2 voorkwamen. Voor studenten die veel tentamens geoefend hebben zou het tentamen dan
ook niet al te moeilijk behoren te zijn.
Tentamen Programmeren 2 – 15 juni 2005 (U ITWERKING)
Opgave 1
2
(20 punten)
Een permutatie van een aantal elementen (bv. karakters, getallen, voorwerpen) is een mogelijke manier om
deze elementen te rangschikken. In deze opgave wordt u gevraagd een recursieve methode te schrijven die
alle mogelijke permutaties van een String van karakters afdrukt.
Voorbeeld. Gegeven de String van karakters "abc". De verzameling van alle permutaties van "abc" is
{ "abc", "acb", "bac", "bca", "cab", "cba" }.
Beschouw onderstaande klasse Permutaties met daarin de methoden main en uniekeChars en de heading van de methode permuteer.
public class Permutaties {
/** Levert true op als de String s uit verschillende karakters bestaat. */
public static boolean uniekeChars(String s) {
for (int i=0; i < s.length()-1; i++) {
if (s.indexOf(s.charAt(i), i+1) > 0)
return false;
}
return true;
}
/** Schrijft alle mogelijke permutaties van de String s
* regel voor regel naar de standaard uitvoer.
* @requires uniekeChars(s)
*/
public static void permuteer(String s) {
// ... body nog toe te voegen ...
}
public static void main(String[] args) {
String s = args[0];
if (uniekeChars(s))
permuteer(s);
else
System.out.println("String ’" + s + "’ bevat dezelfde karakters.");
}
}
Een voorbeeld van de executie van het programma Permutaties is het volgende:
#java Permutaties xyz
xyz
xzy
yxz
yzx
zxy
zyx
Gevraagd wordt de body van de methode permuteer te schrijven die alle permutaties van een String s
(één per regel) op de standaard uitvoer afdrukt.
Aanwijzingen:
Een schets van een dergelijk recursief algoritme is de volgende:
Doe voor elk karakter c uit de string s het volgende:
Schrijf alle permutaties waar dat karakter c vooraan staat, naar de standaard uitvoer.
(M.a.w. schrijf alle permutaties van de overige karakters, voorafgegaan door c.)
U zult waarschijnlijk een hulpmethode moeten gebruiken. Bijvoorbeeld: permuteer(String prefix,
String s), die alle permutaties van s afdrukt voorafgegaan door de String prefix.
Tentamen Programmeren 2 – 15 juni 2005 (U ITWERKING)
3
De volgende methoden van de klasse String kunnen nuttig blijken.
public class String {
...
/** Levert het karakter op positie i in de String. */
public char charAt(int i)
/** Levert de substring beginnend op positie i en tot positie j. */
public String substring(int i, int j)
/** Levert het achterste gedeelte van de String beginnend op positie i. */
public String substring(int i)
}
Antwoord op opgave 1
Deze opgave kwam ook voor in de toets van 18 augustus 2003.
Dit keer een wat lastiger recursie-opgave. Maar met de aanwijzingen moet de opgave te doen zijn. Hieronder volgt de beide methoden permuteer.
public static void permuteer(String s) {
permuteer("", s);
}
/** Schrijft alle mogelijke permutaties van de String s naar
* de standaard uitvoer. Elke permutatie wordt voorafgegaan
* door de String prefix.
*/
public static void permuteer(String prefix, String s) {
if (s.length() == 0)
System.out.println(prefix);
else {
for (int i=0; i< s.length(); i++) {
String remaining = s.substring(0, i) + s.substring(i+1);
permuteer(prefix+s.charAt(i), remaining);
}
}
}
Aandachtspunten:
Voor deze opgave zijn relatief veel punten te behalen. Alleen punten toekennen als het recursieve idee
te herkennen is.
Bij het ontbreken van de iteratie over de karakters van s, 12 punten aftrekken.
Als het basisgeval (s.length() == 0) niet goed geimplementeerd is, dan 4 punten aftrekken.
Java fouten (zoals: aanroep van methoden zonder object, haakjes vergeten bij aanroep van methoden,
break bij een if-statement, etc.) ook aanrekenen.
Opgave 2
(15 punten)
Beschouw de klasse FooBar:
public class FooBar {
/* @require s1 != null && s2 != null && s1.length() == s2.length() */
public static String foobar(String s1, String s2) {
// implementatie van foobar is niet relevant
}
Tentamen Programmeren 2 – 15 juni 2005 (U ITWERKING)
4
public static void error(String msg) {
System.out.println(msg);
System.exit(1);
}
public static void main(String[] args) {
if (args.length != 2)
error("error: aanroepen met 2 String-argumenten");
else if (args[0].length() != args[1].length())
error("error: lengte van de twee Strings ongelijk");
else
System.out.println(foobar(args[0], args[1]));
}
}
Om de methode foobar van de klasse FooBar te kunnen gebruiken moet altijd eerst gecontroleerd worden
of aan de preconditie van deze methode voldaan wordt. In deze opgave definiëren we een wrapper-methode
foobarE die de methode foobar aanroept. De methode foobarE heeft zelf geen preconditie maar gooit
inplaats daarvan een FooBarException als niet aan de preconditie van foobar voldaan wordt.
a. (8 pnt.) Definieer een Exception-klasse FooBarException. Implementeer een methode foobarE
die foobar aanroept als aan de preconditie van foobar voldaan wordt, maar die een FooBarException gooit als niet aan deze preconditie voldaan wordt.
b. (7 pnt.) Pas de methode main van de klasse FooBar zodanig aan dat nu de methode foobarE
gebruikt wordt. De uitvoer van main moet wel precies hetzelfde blijven.
Antwoord op opgave 2
Deze opgave kwam ook voor in de toets van 4 november 2004.
Deze Exception-opgave behoort geen problemen op te leveren voor de studenten.
a. (8 pnt., waarvan 3 voor de exceptie-klasse, 3 voor het correct werpen en 2 voor de throws-clause
bij de methode) De exceptie-klasse:
public class FooBarException extends Exception {
public FooBarException()
{ super(); }
public FooBarException(String msg) { super(msg); }
}
De gevraagde methode foobarE:
public static String foobarE(String s1, String s2) throws FooBarException {
if (s1 == null || s2 == null)
throw new FooBarException("een van beide strings is null");
else if (s1.length() != s2.length())
throw new FooBarException("lengte van de strings ongelijk");
else
return foobar(s1, s2);
}
b. (7 pnt.) Het programmastuk van main wordt dan:
if (args.length != 2)
error("error: aanroepen met 2 String-argumenten");
else
try { System.out.println(foobarE(args[0], args[1])); }
Tentamen Programmeren 2 – 15 juni 2005 (U ITWERKING)
5
catch (FooBarException e) {
error("error: lengte van de twee Strings ongelijk");
}
Aandachtspunten:
Bij de gevraagde methode van a. hoeft géén javadoc-commentaar gegeven te worden.
Als bij b. de uitvoer niet overeenkomt met de oorspronkelijke methode main, dan hier 3 punten
aftrekken.
Opgave 3
(25 punten)
Een kleine ondernemer wil zijn voorraad bijhouden en bewerken met behulp van een Java-programma. Per
artikel wil hij alleen de prijs en het aantal bijhouden. Hieronder staat een eerste aanzet van een klasse
Voorraad waarmee hij zijn artikelen wil opslaan.
public class Voorraad {
private Map<String, Pair<Double,Integer>> artikelen;
public Voorraad() {
// vraag a.
}
/** Voegt een artikel toe aan deze Voorraad. */
public void voegToe(String naam, double prijs, int aantal) {
artikelen.put(naam, new Pair<Double,Integer>(prijs, aantal));
}
}
De artikelen worden in een Map van Strings naar Pair-objecten opgeslagen. Een Pair-object kan
referenties naar twee objecten bevatten, in dit geval een Double (voor de prijs) en een Integer (voor het
aantal). Hieronder staat de klasse Pair.
public class Pair<X,Y> {
public X first;
public Y second;
public Pair(X first, Y second) {
this.first = first;
this.second = second;
}
}
Let bij de implementaties van onderstaande methoden ook op de efficiëntie van de algoritmen. Met name
teveel (impliciete) iteraties en/of (onnodige) cast-operaties worden aangerekend.
a. (3 pnt.) Geef de body van de constructor van de klasse Voorraad.
b. (6 pnt.) Definieer de volgende methode binnen de klasse Voorraad:
/** Levert het totaalbedrag van alle artikelen op voorraad. */
public double totaalInVoorraad()
c. (12 pnt.) Definieer de volgende methode binnen de klasse Voorraad:
/**
* Levert een Map op die gegeven een Integer n (de key) een Set
* (de value) oplevert met daarin alle artikelen (d.w.z. Strings)
* waarvan er precies n exemplaren op voorraad zijn.
*/
public Map<Integer, Set<String>> aantallenMap()
Tentamen Programmeren 2 – 15 juni 2005 (U ITWERKING)
6
d. (4 pnt.) Definieer de volgende methode binnen de klasse Voorraad:
/**
* Levert een Set op met alle artikelen (Strings) waar er maar een
* van op voorraad is. Levert null op als er geen enkel artikel is
* waarvan er maar een op voorraad is.
*/
public Set<String> eenlingen()
Hieronder staat een voorbeeld van het gebruik van de klasse Voorraad en de bovenstaande methoden.
public static void main(String[] args) {
Voorraad vv = new Voorraad();
vv.voegToe("pen",
vv.voegToe("potlood",
vv.voegToe("plakband",
vv.voegToe("schaar",
vv.voegToe("stift",
2.95,
1.45,
2.95,
4.25,
3.10,
3);
5);
1);
1);
3);
" + vv.totaalInVoorraad());
System.out.println("totaal:
System.out.println("aantallen: " + vv.aantallenMap());
System.out.println("eenlingen: " + vv.eenlingen());
}
Het voorbeeld zou de volgende uitvoer (kunnen) genereren:
totaal:
32.6
aantallen: {1=[plakband, schaar], 3=[pen, stift], 5=[potlood]}
eenlingen: [plakband, schaar]
Antwoord op opgave 3
Deze opgave kwam (toen zonder de methode aantallenMap) ook voor in de toets van 8 oktober 2003 (toen
zonder generics uiteraard).
Een recht-toe-recht-aan opgave met een Map. Hieronder staan de implementaties van de gevraagde methoden.
public Voorraad() {
artikelen = new HashMap<String, Pair<Double,Integer>>();
}
public double totaalInVoorraad()
{
double sum = 0.0;
for (Pair<Double,Integer> p: artikelen.values()) {
double prijs = p.first;
int
aantal = p.second;
sum += prijs*aantal;
}
return sum;
}
public Map<Integer, Set<String>> aantallenMap()
{
Map<Integer, Set<String>> mm = new TreeMap<Integer, Set<String>>();
for (Map.Entry<String, Pair<Double, Integer>>
entry: artikelen.entrySet()) {
String art
= entry.getKey();
Tentamen Programmeren 2 – 15 juni 2005 (U ITWERKING)
7
int
aantal = entry.getValue().second;
Set<String> as = mm.get(aantal);
if (as == null) {
as = new TreeSet<String>();
mm.put(aantal, as);
}
as.add(art);
}
return mm;
}
public Set<String> eenlingen()
{
return aantallenMap().get(1);
}
Omdat met deze opgave 25 punten zijn te verdienen, kun je vrij streng zijn bij het nakijken. Enkele voorbeelden:
gebruik van artikelen = Map() o.i.d. bij a.: -3
foutief gebruik van de Iterator of for-lus bij b.: -4
fout bij het berekenen van het totaal bij b.: -3
foutief gebruik van de Iterator of for-lus bij c.: -5
gebruik van Map mm = new Map() o.i.d. bij c.: -4
als er niet via de entrySet maar via de keySet door de artikelen wordt gelopen bij c.: -4
Opgave 4
(20 punten)
Een politieagent en tevens liefhebber van de programmeertaal Java heeft een applicatie geschreven om de
functionaliteit van verkeerslichten beter te kunnen doorgronden:
public class VerkeersLichtJFrame extends JFrame implements ActionListener {
public static final int ROOD=0, ORANJE=1, GROEN=2;
5
10
15
private JPanel[] pLamp = { new JPanel(), new JPanel(), new JPanel() } ;
private JButton bVolgende = new JButton(">");
private int
huidigeKleur = ROOD;
public VerkeersLichtJFrame() {
super("VLicht");
init();
}
protected void init() {
Container cc = getContentPane();
cc.setLayout(new GridLayout(4,1));
cc.add(pLamp[ROOD]); cc.add(pLamp[ORANJE]); cc.add(pLamp[GROEN]);
lampAan(huidigeKleur);
cc.add(bVolgende);
bVolgende.addActionListener(this);
20
setSize(10, 200);
setVisible(true);
25
}
Tentamen Programmeren 2 – 15 juni 2005 (U ITWERKING)
8
private void lampAan(int kleur) {
pLamp[ROOD] .setBackground(Color.BLACK);
pLamp[ORANJE].setBackground(Color.BLACK);
pLamp[GROEN] .setBackground(Color.BLACK);
switch (kleur) {
case ROOD
: pLamp[ROOD] .setBackground(Color.RED); break;
case ORANJE : pLamp[ORANJE].setBackground(Color.ORANGE); break;
case GROEN : pLamp[GROEN] .setBackground(Color.GREEN); break;
default
: break;
}
}
30
35
public void actionPerformed(ActionEvent ev) {
huidigeKleur = (huidigeKleur == ROOD) ? GROEN : huidigeKleur-1;
lampAan(huidigeKleur);
}
40
public static void main(String[] args) {
new VerkeersLichtJFrame();
}
45
}
De klasse VerkeersLichtJFrame is een JFrame met vier componenten. Er zijn drie JPanel-objecten die
corresponderen met de rode, oranje en groene lampen van een verkeerslicht. Daarnaast is er een JButton
met het opschrift “>” waarmee naar een volgende kleur ‘kan worden gesprongen’.
Hoewel een niet onaardige poging, is de klasse VerkeersLichtJFrame niet volgens het Model-ViewController principe ontworpen. In deze opgave moet de klasse VerkeersLichtJFrame opgesplitst worden
in drie public klassen: Vlicht, VlichtView en VlichtController en een interface VLichtKleuren,
zodat de ontstane applicatie wel volgens het Model-View-Controller patroon ontworpen is. De interface
VLichtKleuren wordt gegeven en bevat alleen de definitie van de constanten ROOD, ORANJE en GROEN:
interface VLichtKleuren {
public static final int ROOD=0, ORANJE=1, GROEN=2;
}
De klassen die deze constanten nodig hebben hoeven deze interface slechts te implementeren om de constanten zonder de prefix VLichtKleuren. te kunnen gebruiken.
De public klasse VLicht houdt de huidige kleur van het verkeerslicht bij. De klasse VLicht ondersteunt tenminste een methode naarVolgendeKleur (om naar de volgende kleur te gaan) en een methode
getHuidigeKleur (om de huidige kleur op te leveren, d.w.z. ROOD, ORANJE of GROEN). De public klasse VLichtController dient de interface ActionListener te implementeren. De klasse VLichtView,
tenslotte, bevat een methode main die er als volgt uit ziet:
public static void main(String[] args) {
VLicht model = new VLicht();
VLichtController controller = new VLichtController(model);
VLichtView view = new VLichtView(controller);
model.addObserver(view);
view.update(model, null);
}
Hint: Het nieuwe ontwerp komt er grotendeels op neer dat stukken van VerkeersLichtJFrame naar VLicht, VLichtView en VLichtController verhuizen. Het is niet nodig om alle code van VerkeersLichtJFrame over te schrijven.
U kunt volstaan met precies aan te geven welke gedeelten naar welke klasse verhuizen en wat er veranderd dient te worden.
Antwoord op opgave 4
Deze opgave kwam ook voor in de toets van 16 augustus 2004.
Tentamen Programmeren 2 – 15 juni 2005 (U ITWERKING)
9
Figuur 1: Screenshot van de klasse VerkeersLichtJFrame in actie: het licht ‘staat op oranje’.
Een min-of-meer standaard MVC-opgave. Het merendeel van de code is al beschikbaar in de klasse VerkeersLichtJFrame. Let verder erop dat de gegeven main van VLichtView correct verloopt; met andere
woorden: de klassen hebben de juiste constructoren.
Verdeel de 20 punten als volgt over de klassen:
klasse VLicht: 4 punten.
Aandachtspunten: (i) subklasse van Observable en (ii) aanroepen van de methoden setChanged en
notifyObservers in naarVolgendeKleur.
klasse VLichtView: 10 punten.
Aandachtspunten: (i) implementatie van Observer, (ii) koppeling aan een ActionListener in constructor, (iii) koppeling van controller als ActionListener aan de button, (iv) toevoeging van de
methode update, en (v) de cast naar een VLicht-object in update.
klasse VLichtController: 6 punten.
Aandachtspunten: (i) toevoeging van private instantie variabele voor het model (i.e. VLichtobject), (ii) koppeling aan het model in de constructor, en (iii) aanroep van de methode naarVolgendeKleur binnen actionPerformed.
De klasse VLicht zou er als volgt uit kunnen zien:
public class VLicht extends Observable implements VLichtKleuren {
private int huidigeKleur;
public VLicht() {
huidigeKleur = ROOD;
}
public int getHuidigeKleur() {
return huidigeKleur;
}
public void naarVolgendeKleur() {
huidigeKleur = (huidigeKleur == ROOD) ? GROEN : huidigeKleur-1;
setChanged();
notifyObservers();
}
}
De klasse VLichtView zou er als volgt uit kunnen zien:
public class VLichtView extends JFrame implements Observer, VLichtKleuren {
private JPanel[] pLamp = { new JPanel(), new JPanel(), new JPanel() } ;
Tentamen Programmeren 2 – 15 juni 2005 (U ITWERKING)
private JButton bVolgende = new JButton(">");
private ActionListener controller;
public VLichtView(ActionListener controller) {
super("VLicht");
this.controller = controller;
init();
}
protected void init() {
Container cc = getContentPane();
cc.setLayout(new GridLayout(4,1));
cc.add(pLamp[ROOD]); cc.add(pLamp[ORANJE]); cc.add(pLamp[GROEN]);
cc.add(bVolgende);
bVolgende.addActionListener(controller);
setSize(10, 200);
setVisible(true);
}
private void lampAan(int kleur) {
pLamp[ROOD] .setBackground(Color.BLACK);
pLamp[ORANJE].setBackground(Color.BLACK);
pLamp[GROEN] .setBackground(Color.BLACK);
switch (kleur) {
case ROOD
: pLamp[ROOD] .setBackground(Color.RED); break;
case ORANJE : pLamp[ORANJE].setBackground(Color.ORANGE); break;
case GROEN : pLamp[GROEN] .setBackground(Color.GREEN); break;
default
: break;
}
}
public void update(Observable model, Object arg) {
VLicht vlicht = (VLicht) model;
lampAan(vlicht.getHuidigeKleur());
}
public static void main(String[] args) {
VLicht model = new VLicht();
VLichtController controller = new VLichtController(model);
VLichtView view = new VLichtView(controller);
model.addObserver(view);
view.update(model, null);
}
}
De klasse VLichtController zou er als volgt uit kunnen zien:
public class VLichtController implements ActionListener {
private VLicht model;
public VLichtController(VLicht model) {
this.model = model;
}
public void actionPerformed(ActionEvent ev) {
model.naarVolgendeKleur();
}
10
Tentamen Programmeren 2 – 15 juni 2005 (U ITWERKING)
11
}
Opgave 5
(20 punten)
Bij deze opgave dient u de mogelijke uitkomsten van enkele programma’s te bepalen. Naast ‘normale
uitvoer’ zouden ook de volgende ‘uitkomsten’ kunnen optreden:
vertaalfout: het programma is geen correct Java programma;
runtime-fout: er wordt een Exception gegooid;
geen uitvoer: bijvoorbeeld vanwege een deadlock.
U hoeft uw antwoorden niet te motiveren.
Beschouw het Java-programma MyThreads.
public class MyThreads {
public static void main(String[] args) {
Value v1 = new Value(1);
Value v2 = new Value(2);
Thread t1 = new Task(v1, v2); t1.start();
Thread t2 = new Task(v2, v1); t2.start();
try { t1.join(); t2.join(); }
catch (InterruptedException e) {}
System.out.println(v1.get() + v2.get());
}
}
class Value {
private int x;
public Value(int x) {
this.x = x;
}
public synchronized void add(Value v) {
x = x + v.get();
}
public int get() {
return x;
}
}
class Task extends Thread {
private Value v1, v2;
public Task(Value v1, Value v2) {
this.v1 = v1;
this.v2 = v2;
}
public void run() {
v1.add(v2);
}
}
a. (3 pnt.) Wat zijn de mogelijke uitkomsten van het programma MyThreads?
Tentamen Programmeren 2 – 15 juni 2005 (U ITWERKING)
12
b. (3 pnt.) In het oorspronkelijke programma wordt het gehele try-catch-blok uit de methode main
verwijderd. Wat zijn nu de mogelijke uitkomsten van het programma?
c. (2 pnt.) In het oorspronkelijke programma wordt het gehele try-catch-blok uit de methode main
verwijderd. Daarnaast worden ook de aanroepen van t1.start() en t2.start() in de methode
main veranderd in respectievelijk t1.run() en t2.run(). Wat zijn nu de mogelijke uitkomsten van
het programma?
d. (2 pnt.) In het oorspronkelijke programma wordt de methode add van de klasse Value niet langer
als synchronized methode gedefinieerd. Wat zijn nu de mogelijke uitkomsten van het programma?
e. (2 pnt.) In het oorspronkelijke programma wordt de methode get van de klasse Value als synchronized methode gedefinieerd. Wat zijn nu de mogelijke uitkomsten van het programma?
f. (2 pnt.) In het oorspronkelijke programma wordt de methoden run van de klasse Task als synchronized methode gedefinieerd. Wat zijn nu de mogelijke uitkomsten van het programma?
g. (3 pnt.) In het oorspronkelijke programma wordt de methode add van de klasse Value als volgt
veranderd:
public synchronized void add(Value v) {
x = x + v.get();
v.notifyAll();
}
Wat zijn nu de mogelijke uitkomsten van het programma?
h. (3 pnt.) In het oorspronkelijke programma wordt de methode add als volgt veranderd:
public synchronized void add(Value v) {
if (x == 1)
try { this.wait(); }
catch (InterruptedException e) {}
x = x + v.get();
synchronized (v) { v.notify(); }
}
Wat zijn nu de mogelijke uitkomsten van het programma?
Antwoord op opgave 5
Deze opgave kwam ook voor in de toets van 13 april 2005 en is toen erg slecht gemaakt. Eens kijken hoeveel
studenten geprobeerd hebben om deze opgave thuis te maken.
Een multiple-choice Thread-opgave. Wellicht iets lastiger dan Thread-opgaven uit voorgaande toetsen
omdat er hier sprake is van twee gemeenschappelijke objecten.
a. Mogelijke waarden: 6-8.
b. Mogelijke waarden: 3-8.
c. Mogelijke waarde: 8.
d. Mogelijke waarden: 6-8 (als a.).
e. Mogelijke waarden: 6-8 (als a.) of geen uitvoer (vanwege een mogelijke deadlock).
f. Mogelijke waarden: 6-8 (als a.)
g. Mogelijke waarden: runtime-fout (nl. IllegalMonitorStateException)
Tentamen Programmeren 2 – 15 juni 2005 (U ITWERKING)
13
h. Mogelijke waarden: 7 of geen uitvoer (vanwege een mogelijke deadlock).
Enkele opmerkingen:
Alleen punten toekennen als het antwoord helemaal goed is.
Geen punten toekennen voor begeleidende teksten.
Uitzonderingen op bovenstaande ‘helemaal goed’-regel zijn de vragen e, g en h. Bij deze vragen is er
naast ‘normale’ uitvoer, in de vorm van een int-waarde, ook ‘andere’ uitvoer mogelijk. Als dit door
de studenten wordt geconstateerd, dan toch 1 punt per deelvraag toekennen.
Sommige vragen hebben dezelfde antwoord als bij a. omdat het programma door de aanpassing niet
wezenlijk veranderd is. Dit is aangegeven met “(als a.)”. Als studenten dit ook door hebben en dit
aangegeven met bijvoorbeeld “(als a.)” of “(zie a.)” dan het antwoord goed rekenen, ongeacht het
antwoord dat de studenten gaven bij a.
Na afloop van het tentamen van april 2005 bleek dat meerdere studenten de operator + in de expressie
van het System.out.println statement als String-concatenatie hebben opgevat. Deze studenten
geven dan ook antwoorden met twee cijfers inplaats van één. Trek in dit geval 2 punten af voor de
String-concatenatie fout.
De opgave verder nakijken volgens onderstaande tabel die het verband aangeeft tussen de int-waarde
en de bijbehorende twee cijferige String.
3
4
5
6
7
8
=
=
=
=
=
=
12
13
32
33
43
35
Download