EXAMEN SOFTWAREONTWIKKELING 1STE PROEF BURG. IR. COMPUTERWETENSCHAPPEN EERSTE EXAMENPERIODE ACADEMIEJAAR 2004 - 2005 Naam :
Deel 1 : Gesloten Boek 1. Testen Geef een overzicht van de verschillende testen die in het ontwikkelproces aan bod kunnen komen. Testen kunnen op veschillende manieren onderverdeeld worden, o.a. volgens - Het doel van de testen - De techniek die bij het testen gebruikt werd Geef voor beide indelingen de voornaamste categorieën en bespreek ze kort. Testdoel
Bespreking
Testtechniek
Bespreking
Vraag 2 : Multithreading I.
Geeft onderstaande code aanleiding tot een deadlock ? Leg uit waarom (niet).
class A { private B b=new B(); public synchronized void f() { System.out.println("Before"); b.registerA(this); b.h(); System.out.println("After"); } public synchronized void g() { System.out.println("Inside g()"); } public static void main(String[] args) { A a=new A(); a.f(); System.out.println("Finished"); } } class B extends Thread { A a=null; public void registerA(A aa) { a=aa; start(); } public synchronized void h() { System.out.println("Inside h()"); } public synchronized void run() { a.g(); } }
II.
Een object van de klasse Buffer (code hieronder gegeven) wordt met object van de klasse Item opgevuld. Dit opvullen gebeurt door objecten van de klasse Input (via de methode add), die elk overerven van de klasse Thread. Anderzijds worden Items uit de Buffer gehaald door objecten van de klasse Processor (via de methode remove), die eveneens overerven van de klasse Thread. Objecten van de klasse Item fungeren dus als generatoren van werk, terwijl de Processors dit werk uitvoeren. Een Buffer dient als tijdelijke opslagruimte om het werk in op te slaan. Een derde soort objecten, van de klasse Monitor (opnieuw overervend van de klasse Thread), vraagt op geregelde tijdstippen de belasting van de Buffer op (via de methode load).
De initiële code voor de klassen Buffer en Item is hieronder weergegeven : class Item {
private int i=0; public Item(int ii) { i=ii; } public String toString() { return "
"; } } public class Buffer { private ArrayList l=new ArrayList(); public void add(Item i) {l.add(i);} public Item remove() { Item i= (Item)l.get(l.size()-1);l.remove(l.size()-1);return i;} public int load() {return l.size();} } a. Geef aan welke methoden van de klasse Buffer moeten gesynchroniseerd worden, als je weet dat er slechts 1 object van de klasse Input, 1 object van de klasse Processor en 1 object van de klasse Monitor aanwezig is. Motiveer dit afdoend !
b. Wijzigen deze conclusies indien meerdere objectje van de klassen Input, Processor en Monitor is het spel zijn ? Motiveer !
Vraag 3 : het Proxy patroon Gegeven de klassen A en B, en de interface I zoals gespecificeerd via onderstaand UMLdiagram.
Men beschikt over een klassenhiërarchie die start bij de interface I, en die men NIET wenst te wijzigen. Anderzijds wil men ervan verzekerd zijn dat bij toegang tot methoden van de klassen A en B, de clientcode over de correcte credentials beschikt. Via het proxy-ontwerpspatroon wordt hiervoor een oplossing gezocht. Men zal ook pogen de client code (uit de klasse ClientClass) zo weinig mogelijk te wijzigen.
a. Teken hieronder een UML-diagram van de geplande oplossing :
b. Geef de code van je proxy-klasse(n) :
c. De originele code van de ClientClass luidt : class ClientOld { public static void main(String[] args) { I[] i={new A(),new A(),new B(),new B()}; for(int j=0;j
Vraag 4 : Terminologie Leg telkens kort (<10 regels) onderstaande begrippen uit (met voor gevallen b en c uiteraard de klemtoon op de conceptuele verschillen tussen de geciteerde begrippen) . a. Use case
b.
Persistentie versus serializatie
c.
Beans property versus gegevensveld van een klasse
Vraag 5 : Uitvoer Van onderstaande programma’s is gegeven dat ze foutloos compileren, met uitzondering van het tweede en het laatste. Leg voor het tweede en laatste programma uit waarom het niet compileert, en voorspel voor de overige programma’s telkens de uitvoer. a. Exception handling class E extends Exception { } class Q1 { public static void f(int i) throws E { System.out.print("a"); throw new E(); } public static void g(int i) throws E { System.out.print("b"); throw new E(); } public static void main(String[] args) { try { g(10); try { f(10); } catch(E e) {} finally { System.out.print("c");
} } catch(E e) {System.out.print("d");} } } Uitvoer : b. Exception handling class E1 extends Exception { } class E2 extends E1 { } class Q2 { public static void f(int i) throws E1 { System.out.print("a"); throw new E1(); } public static void g(int i) throws E2 { System.out.print("b"); throw new E2(); } public static void main(String[] args) { try { f(10); g(10); } catch(E1 e) {System.out.print("c"); } catch(E2 e) {System.out.println("d");} } } Motivatie : c. Serialisatie import java.io.*; class A implements Serializable { private int a=0; public A(int aa) {a=aa;} public A(A aa) {a=aa.a;} public void setA(int aa) {a=aa;} public String toString() {return ""+a;} } class Q3 { public static void main (String[] args) throws Exception { ObjectOutputStream out=new ObjectOutputStream( new BufferedOutputStream(new FileOutputStream("obj.dat"))); A a1=new A(1); A a2=a1; A a3=new A(a1); out.writeObject(a1); a1.setA(10); out.writeObject(a2); out.writeObject(a3); out.close(); ObjectInputStream in=new ObjectInputStream( new BufferedInputStream(new FileInputStream("obj.dat"))); for(int i=0;i<3;i++) { A a=(A)(in.readObject()); System.out.println(a); } in.close(); } }
Uitvoer :
d. Generics class Person { protected String s; public Person(String ss) {s=ss;} public void print() {System.out.print(s.charAt(0));} } class Student extends Person { public Student(String ss) {super(ss);} public void print() {System.out.print(s.charAt(1));} } public class Q4 { public static void main(String[] args) { List l=new ArrayList(); l.add(new Person("Albert")); l.add(new Person("Bertrand")); l.add(new Person("Cyril")); l.add(new Student("Dimitri")); printList(l); } public static void printList(List l) { for(Person p:l) p.print(); } } Uitvoer : e.
Generics
class Person { protected String s; public Person(String ss) {s=ss;} public void print() {System.out.print(s.charAt(0));} } class Student extends Person { public Student(String ss) {super(ss);} public void print() {System.out.print(s.charAt(1));} } public class Q5 { public static void main(String[] args) { List<Student> l=new ArrayList<Student>(); l.add(new Student("Albert")); l.add(new Student("Bertrand")); l.add(new Student("Cyril")); l.add(new Student("Dimitri")); printList(l); } public static void printList(List l) { for(Person p:l) p.print(); } } Motivatie :
Wat zou je aanpassen in de code opdat ze toch naar behoren zou werken ?
EXAMEN SOFTWAREONTWIKKELING 1STE PROEF BURG. IR. COMPUTERWETENSCHAPPEN EERSTE EXAMENPERIODE ACADEMIEJAAR 2004 - 2005 Naam :
Deel 2 : Open Boek Een klassetester In deze oefening is het de bedoeling een klassetester te maken. Hierbij wordt aan een grafische toepassing dynamisch een klasse toegeleverd. De tool zal deze klasse bekijken, toelaten een object van deze klasse aan te maken, de toestand van een dergelijk object zichtbaar te maken, en het bovendien mogelijk maken om methoden op dit object uit te voeren. Hierbij worden volgende conventies in acht genomen : •
De toestand van het object in kwestie is toegankelijk via publieke methoden die starten met “get”.
•
Enkel methoden zonder argumenten worden dynamisch opgeroepen vanuit de tool.
•
Instantiatie gebeurt door oproepen van de no-arg constructor.
I.
De GUI
Bouw een grafische user interface, zoals op onderstaande figuur weergegeven. Hierbij bevat het menu File vogende items : - Open - Set package - Exit Het menu Action bevat : - Instantiate - View state - Invoke Dit laatste item is opnieuw een menu waaruit de op te roepen methode kan gekozen worden (deze kan vanzelfsprekend bij opstarten van de applicatie niet ingevuld worden). Het is niet de bedoeling een “production grade” product te ontwikkelen. Daarom mag bij het optreden van een exceptie de applicatie afgesloten worden, na afdrukken van de fout naar de standaard error stream.
II. Het menu “File” a. Open Wanneer hierop geklikt wordt, opent een JFileChooser object, door middel waarvan een file kan gekozen worden waarin de byte-codes voor de te testen klasse steken. Het bestand wordt geladen. Wanneer je hier blijvende problemen mee ondervindt, voorzie dan een String-variabele waarin de naam van een .class file hard gecodeerd is. b. Set package Wanneer deze optie aangeklikt wordt, wordt een dialoogvenster geopend. Dit venster toont een tekstveld waarin de packagenaam van de te testen klasse door de gebruiker opgegeven wordt. Wanneer dit niet lukt, voorzie een String-variabele waarin een packenaam hard gecodeerd wordt. c. Exit Deze optie kiezen, sluit gewoon het programma af.
III. Het menu “Action” a. Instantiate Hier wordt de constructor zonder argumenten opgeroepen van de analyseren klasse (m.a.w. een object wordt aangemaakt). b. View state Bedoeling is dat de publiek observeerbare toestand van het aangemaakte object getoond wordt. Dit gebeurt in de ruimte, getiteld Voor elke methode die start met “get” aanwezig in de klasse, wordt :
-
-
een JLabel aangemaakt, die de naam van de eigenschap van het object toont. Deze naam wordt gevormd door van de corresponderende “get”-methode het prefix “get” weg te laten (getX() zal resulteren in eigenschap “X”) een tekstveld waarin de huidige waarde van de eigenschap getoond wordt (via toString() als het om een eigenschap van het type Object gaat).
Dit vergt dat de layout van de GUI dynamisch aangepast wordt. Als dit niet onmiddellijk lukt, kijk dan na of vergroten of verkleinen van het GUI-venster niet het gewenste resultaat geeft. c.
Invoke
Hier is het de bedoeling dat een willekeurige methode, zonder parameters, kan opgeroepen worden. Hiertoe wordt voor elke dergelijke methode een keuze-selectie in het menu Invoke toegevoegd. Zorg ervoor dat dit gebeurt bij het laden van de .class file (dus bij aanklikken van Open in het menu File). Aanklikken van een dergelijke methode resulteert in het oproepen van de desgewenste methode, waarbij de toestand automatisch aangepast wordt.