330 Home |
Syllabus |
Projects |
Lectures |
Homeworks |
Readings |
Resources |
Exams
Handout 1:
Other stuff:
- A basic closure example from the lecture
on closures. Shows how to emulate a static variable in Perl using a
closure.
Handout 2:
Handout 3:
- Basic usage of exceptions. Shows how to
create your own exception and throw it. Show how a method may
propagate a declared exception. Also shows how to catch an exception
with a try {} catch {} statement.
- What finally can always do.
- Comparing strings. The difference
between the == operator and the equals() method from
Object. Also covers interning strings.
- A String is immutable, if you need to selectively change characters,
use a StringBuffer. E.g, reversing a
string.
- Reading from standard input in Java
is a bit intricate due to the interaction between 8-bit (byte) and
16-bit (character) streams.
- StringTokenizer may come
in handy if you need to break a string into tokens. The example demonstrates
two modes of operation of this class.
- Hashtable is one of the most
often used data structures in Java. This is a basic example; it shows
how to insert, search, and remove elements. It also shows how to
iterate over keys and values.
- HashMap is the Collections Framework
replacement for Hashtable. This example shows how to iterate over
key-value pairs using an iterator.
Handout 4:
- The lack of copy constructor in Java is offset by the general
purpose clone() method implemented by Object. Using
it is a bit tricky. This example
demonstrates that assignment does not achieve cloning because
references point to the same object. The problem is solved in by cloning; the fully recipe is given, it
may be applied to any object where field-by-field assignment is the
desired semantic for cloning.
- Inner classes are a powerful tool in
Java. This example plays with the idea that multiple inheritance may
be emulated in Java by taking advantage of the enclosing
instance feature of inner classes. Other specialties related to
inner classes are exhibited: qualified this and qualified
new.
Handout 5:
- Using threads in Java; a
non-deterministic program. Demonstrates how to create and start/join a
thread. Also featuring daemon threads and the use of sleep.
- Implementation of a semaphore that
observes a certain interface. This
is a simple solution for a monitor problem that requires a single
condition variable. The class that tests the implementation uses a factory to resolve the name of
the implementation class at runtime.
- A Java solution for the
bounded buffer problem (also known as the producer/consumer
problem). The solution is a port of an SR
solution (you may see it as monitor pseudocode) that makes use of
multiple condition variables.
- An extended semaphore that
additionally implements the Z
operation. This is another problem that may be easily solved using
multiple condition variables. A somewhat
equivalent SR solution that uses daisy-chaining of signals() to
simulate signalAll() also works for SW policy. The behavior of the two
solutions is not exactly the same for the Z() operation though. A test class and the corresponding factory are also provided.
Handout 6:
- Deadlock may easily occur in Java when
multiple monitors are used. In this example, thread 1 acquires the
locks for objects a and b, and then call
wait() on b. Thus thread 1 releases the lock on
b, but it still holds the lock on a. When thread two
tries to obtain the lock on a deadlock occurs.
- A FIFO semaphore implementation
requires that threads be released in a specific order. The solution
herein uses at most N+2 monitors for N threads. One monitor is used
solely to create a critical region and it is share by all
threads. Each thread blocked at P() locks its own monitor. Finally,
there is another monitor used to block all threads at Z(). Note that
exactly one monitor lock is held when a thread calls wait(). This
restriction need not apply to notify() due to the signal &
continue policy employed by Java. Also note the race condition
introduced when one monitor is released before the next is acquired;
the fix was to introduce a boolean flag that prevents a thread from
calling wait() after a notify() was sent; effectively this is a mutex.
Additional files: interface,
factory, and test program.
Other stuff:
- Actual code for parsing
integer/reals discussed during the review. The code provided is for 32
bit integers and reals. You need to up it to 64 bits.
Waiting for the whistles to finish...
Handout 7:
- Partial applications of functions in
Perl. Actually, subroutines that return subroutines. Note the
syntactic imperfection in Perl: one cannot really return subroutines
but only references to subroutines. This doesn't occur in most
functional programming languages: ML, Scheme, etc.
- A attempt to provide a more useful example for partial applications:
a subroutine that validates strings
against regular expressions is rewritten
using partial applications. The new subroutine works like a template;
it can be instantiated to provide matches against various regular
expressions.
- Function composition is basic example of
a higher-order function.
- The equivalence between curried and uncurried versions of the
same function may be demonstrated constructively: two higher-order
functions (curry and uncurry) may be used to
generate the curried/uncurried versions of a function.
- Writing an interpreter in terms of
itself. This is a lame cheat in Perl, but it introduces the useful
function eval.
Note: Due to the compressed schedule of the summer
semester and the relatively high volume of emails on programming topics
(caused in part by lack of recitations), I find little time to post
material here. It is unlikely that all the lecture material
will be posted here. Therefore, I strongly advise students to
come to class.
gaburici@cs.umd.edu
Last modified: Tue Jul 24 08:39:14 EDT 2001