Name:FinalCMSC 433Programming Language Technologies and ParadigmsSpring 2004May 19, 2004InstructionsThis exam contains 15 pages, including this one. Make sure you have all the pages. Writeyour name on the top of this page before starting the exam.Write your answers on the exam sheets. If you finish at least 15 minutes early, bring your exam to thefront when you are finished; otherwise, wait until the end of the exam to turn it in. Please be as quiet aspossible.If you have a question, raise your hand. If you feel an exam question assumes something that is notwritten, write it down on your exam sheet. Barring some unforeseen error on the exam, however, youshouldn’t need to do this at all, so be careful when making assumptions.You may avail yourself of the punt rule. If you write down punt for any numbered or lettered part of aquestion, your will earn 1/5 of the points for that question (rounded down).Question Score Max1 202 103 104 205 206 107 10Total 1001Question 1. Short A nswer (20 points).a. (4 points) Explain the difference between method overriding and method overloading.Answer: Overriding is when a subclass replaces code inherited from a superclass. Overloadingis when a class has multiple methods with the same name and return type but different numbersand/or typ e s of parameters.b. (4 points) What doe s the following program print? Does it always print the same thing? (Hint: Yes,this is a trick question.) Explain your answer.public class Foo extends Thread {public void run() {System.out.print("run ");}public static void main(String[] args) {Foo f = new Foo();f.run();System.out.print("main ");}}Answer: This program always prints “run main.” This is a single-threaded program; the callto f.run() is just a normal method invo cation. Separate threads are only started when theirstart() method is invoked, which we don’t do here.c. (4 points) Explain one advantage and one disadvantage of delegation as compared to inheritance.Answer: Delegation is more flexible than inheritance, because the inheritance hierarchy is fixedat compile time, whereas delegation relationships can change dynamically at run time. Delegationalso allows for some reuse that’s not easy with inheritance, such as the kind of recursion in thedecorator pattern. On the other hand, the dynamic reconfigurability of delegation can makeprograms harder to understand than inheritance, and it also increases the number of objectsin the system, adding further complication. Delegation can also affect performance, since itincreases the number of method calls.2d. (4 points) Draw a UML diagram for the adapter pattern and explain how the pattern works. If youforget the particular UML notation for something, just add a note to the side explaining what your linesand boxes mean. We’ve given you part of the digram to start.ClientTargetRequest()AdapteeSpecificRequest()Answer: See the lecture notes.e. (4 points) Describe the sequence of events that happens after a thread calls o.notifyAll() when severalother threads are waiting on o.Answer: When o.notifyAll() is called, all threads waiting on o are woken up. But theycannot resume executing until they reacquire the lock on o. And since the thread that just calledo.notifyAll() has that lock, they can’t make progress just yet. As the lock becomes available,each thread waiting on o will, in turn, unblock and continue executing.3Question 2. Multi-threading (10 points). For each of the following multi-threaded programs, statewhether the program has a problem related to synchronization. If there is a problem, explain what theproblem is, and give a sequence of actions that exhibits the problem.a. (5 points) The following code implements the observer pattern. Assume that the attach(), detach(),and notify() methods may be called arbitrarily by other threads.public interface Observer {void update();}public class SynchronizedList {private LinkedList l = new LinkedList();public synchronized void add(Object o) { l.add(o); }public synchronized void remove(Object o) { l.remove(o); }public synchronized int size() { return l.size(); }public synchronized Object get(int index) { return l.get(index); }}public class Subject {private SynchronizedList observers = new SynchronizedList();public void attach(Observer s) {observers.add(s);}public void detach(Observer s) {observers.remove(s);}public void notify() {for (int i = 0; i < observers.size(); i++) {Observer s = (Observer) o.get(i);s.update();}}}Answer: This program has a race condition. Each individual operation is synchronized, butthat is not sufficient. In particular, the following s equence of events could happen. Supposethere is one observer that has been attached. (1) One thread calls notify(), (2) the check i <observers.size() succeeds, (3) Another thread calls detach(), which removes the observerfrom the list, (4) The first thread calls o.get(0), which fails.4b. (5 points) In the following example, assume that foo() and bar() may both be called arbitrarily byother threads.public class Outer {private class Inner {private int counter = 0;public synchronized void incCounter() { counter++; }}private Inner myCount = new Inner();public synchronized void foo() {System.out.println("Foo!");myCount.incCounter();}public synchronized void bar() {System.out.println("Bar!");myCount.incCounter();}}Answer: This program does not have any synchronization problems. The extra synchronizationon the inner class object is redundant, but it doesn’t hurt anything: The inner class object lockis only acquired when the outer class lock is already held, so there’s no danger of deadlock.5Question 3. Refactoring (10 points). In class we showed an example of some code that could use somerefactoring. We ended with two of the classes, Rental and Movie, looking like the following:public class Rental {private Movie _movie;private int _daysRented;public Rental(Movie movie, int daysRented) {_movie = movie;_daysRented = daysRented;}public int getDaysRented() { return _daysRented; }public Movie getMovie() { return _movie; }public double amountFor() {double thisAmount = 0;//determine amounts for each lineswitch (getMovie().getPriceCode()) {case Movie.REGULAR:thisAmount += 2;if (getDaysRented() > 2)thisAmount += (getDaysRented() - 2) * 15;break;case Movie.NEW_RELEASE:thisAmount += getDaysRented() * 3;break;case Movie.CHILDRENS:thisAmount += 1.5;if (getDaysRented() > 3)thisAmount += (getDaysRented() - 3) * 1.5;break;}return thisAmount;} }public class Movie {public static
View Full Document