CMSC 433: Exam Questions & Code Samples for Programming Languages - Prof. Michael W. Hicks, Exams of Programming Languages

The final exam questions for cmsc 433, a university course on programming language technologies and paradigms, held in fall 2002. The exam covers various topics such as treemap methods, rmi, java security, and design patterns. Code samples and instructions for implementing certain methods and classes.

Typology: Exams

Pre 2010

Uploaded on 02/13/2009

koofers-user-akh
koofers-user-akh 🇺🇸

9 documents

1 / 9

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Final Exam
CMSC 433
Programming Language Technologies and Paradigms
Fall 2002
December 16, 2002
Guidelines
Put your name and class account number on each page before starting the exam. Write your answers
directly on the exam sheets, using the back of the page as necessary. I will not accept exams until I ask
for them. If you finish early use the time to recheck your answers. Please be as quiet as possible.
I will not take any questions during the exam. Errors on the exam will be posted on the board as
they are discovered. If you feel an exam question assumes something that is not written, write it down
on your exam sheet. Barring some unforeseen error on the exam, however, you shouldn’t need to do this
at all, so be careful when making assumptions.
Question Points Score
1 15
2 15
3 15
4 10
5 15
6 10
7 20
Total 100
pf3
pf4
pf5
pf8
pf9

Partial preview of the text

Download CMSC 433: Exam Questions & Code Samples for Programming Languages - Prof. Michael W. Hicks and more Exams Programming Languages in PDF only on Docsity!

Final Exam

CMSC 433

Programming Language Technologies and Paradigms

Fall 2002

December 16, 2002

Guidelines

Put your name and class account number on each page before starting the exam. Write your answers

directly on the exam sheets, using the back of the page as necessary. I will not accept exams until I ask

for them. If you finish early use the time to recheck your answers. Please be as quiet as possible.

I will not take any questions during the exam. Errors on the exam will be posted on the board as

they are discovered. If you feel an exam question assumes something that is not written, write it down

on your exam sheet. Barring some unforeseen error on the exam, however, you shouldn’t need to do this

at all, so be careful when making assumptions.

Question Points Score

Total 100

1. (Junit) 15 points. Some methods for java.util.TreeMap are described below. Write a class called

TreeMapTest that contains three Junit “reasonable” tests of this java.util.TreeMap. Your tests

should not use any java.util.TreeMap methods that are not described below. Include comments in

each test that describe what the purpose of each test is.

TreeMap() Constructs a new, empty map, sorted according to the keys’ natural order. void clear() Removes all mappings from this TreeMap. Object clone() Returns a shallow copy of this TreeMap instance. boolean containsKey(Object key) Returns true if this map contains a mapping for the specified key. boolean containsValue(Object value) Returns true if this map maps one or more keys to the specified value. Set entrySet() Returns a set view of the mappings contained in this map. Object firstKey() Returns the first (lowest) key currently in this sorted map. Object get(Object key) Returns the value to which this map maps the specified key. Set keySet() Returns a Set view of the keys contained in this map. Object lastKey() Returns the last (highest) key currently in this sorted map. Object put(Object key, Object value) Associates the specified value with the specified key in this map. void putAll(Map map) Copies all of the mappings from the specified map to this map. Object remove(Object key) Removes the mapping for this key from this TreeMap if present. int size() Returns the number of key-value mappings in this map. Collection values() Returns a collection view of the values contained in this map.

import junit.framework.*;

public class TreeMapTest extends TestCase { public TreeMapTest( String name ) { super( name ); }

// YOUR TESTS GO HERE ...

public static Test suite() { return new TestSuite( TreeMapTest.class ); }

public static void main(String args[]) { junit.textui.TestRunner.run(suite()); } }

The UseLock class is an abstract class that uses a LockerI instance to make doOp() method atomic. Write the code necessary to acquire and use the LockerI instance via RMI.

import java.rmi.; import java.rmi.registry.;

public abstract class UseLock { private static void doOp() { // to be overridden by subclass}

public static void main(String[] args) throws Exception {

// WRITE THIS CODE

for(;;) { t.getLock(); doOp(); t.releaseLock(); } } }

The inserted code is

System.setSecurityManager(new RMISecurityManager()); LockerI t = (LockerI)Naming.lookup("rmi://milano.cs.umd.edu:2005/Locker");

  1. (RMI - short answer 15 points).

(a) Explain what information the java.rmi.server.codebase property conveys to a JVM and how that information is used when running RMI applications.

java.rmi.server.codebase indicates the codebase URL of classes originating from the VM. The codebase property is used to annotate class descriptors of classes originating from a VM so that the class for an object sent as a parameter or return value in a remote method call can be loaded at the receiver.

(b) Explain the design issues that should be considered when deciding whether to make an object imple- ment Serializable or Remote in a java RMI application.

Serializable implements call by value while Remote implements call by reference semantics. That is, when an object is serializable it is copied before being sent, while for a Remote object, a stub is sent and all interactions are forwarded back to the object owner. The two results are: (1) changes to serializable objects are not reflected to all copies, but all execution happens on the local object; (2) changes to Remote objects are reflected to all copies, but all execution happens on the host owning the original object, requiring messages to be sent.

  1. (Design Patterns) 15 points. You are faced with the following design problem. You have already written an abstract class called Resource. Resource has two methods initialize() and cleanup() that encapsulate application-specific setUp and tearDown procedures for Resources. Resource subclasses inherit these methods, overriding them as desired. These subclasses also implement the singleton pattern, so at runtime there is only one instance of each subclass. Users of these subclasses are expected to call initialize() and cleanup before and after using a Resource subclass instance. Currently, your Resource subclass instances are NOT thread safe. In particular, it’s no longer clear how and when to call initialize() and cleanup(). For example, if two threads start up, create an instance of ResourceSubclass1, and call initialize(), then the ResourceSubclass1 instance will be initialized twice, when it should only have been initialized once. The same goes for cleanup(). Sketch a solution to this problem (using diagrams and psuedocode as necessary) that allows you Resource subclasses to be used by multiple threads. What design pattern(s) can you use to minimize changes to existing classes?

Use a decorator, proxy, or adapter to wrap each Resource subclass with code that adds reference counts. That is, users call initialize() and cleanup() as normal. The proxy checks to see if the caller is the first to call initialize(); if so it calls the wrapped class’s initialize() method, and increments the count. Subsequent calls to initialize just result in the count being increased. Conversely, when a user calls cleanup(), the count is decreased; when the count reaches 0, the underlying Resource class’s cleanup() method is called. To work in a concurrent setting, you may need to synchronize initialize() and cleanup() in the proxy/adaptor.

  1. (Design Patterns) 10 points

PartFactory’s instantiate part objects, with the following interface:

interface PartFactory { public Car createCar(); public Wheel createWheel(String size); public Engine createEngine(int horsePower); }

(a) (2 points) Using the Abstract Factory design pattern, show the declarations of Java classes that are Factories for two different car models: ChevyPartFactory and FordPartFactory.

class ChevyPartFactory implements PartFactory { public Car createCar(); public Wheel createWheel(String size); public Engine createEngine(int horsePower); } class FordPartFactory implements PartFactory { public Car createCar(); public Wheel createWheel(String size); public Engine createEngine(int horsePower); }

Alternatively, you might have specialized Car to be ChevyCar for the ChevyPartFactory and FordCar for FordPartFactory, and made similar changes to the other base types.

(b) (2 points) Provide code for a client that uses the ChevyPartFactory to create a Car, a Wheel of size “R15”, and an Engine of horsePower 6000.

/* note the use of base types in all declarations, making the code completely generic, only depending on which CarFactory is instantiated */ ChevyPartFactory f = new ChevyPartFactory(); Car c = f.createCar(); Wheel w = f.createWheel("R15"); Engine e = f.createEngine(6000);

(c) (6 points) What restrictions/requirements are there on the types of the objects returned from the methods in the ChevyPartFactory and FordPartFactory classes?

The return value objects have to be subclasses of the return values of the methods in interface CarFactory (e.g., if CarFactory.createCar() returns an ChevyCar object, then ChevyCar must be a subclass of Car).