6.096 Fall 1997
Introduction to Interactive Programming

Quiz II Review

Quiz Topics

We've provided a brief overview of the central topics in the second part of this class. It is in a sample quiz format, with six negative multiple choice questions. Be sure to read the Quiz II Handout for additional details about the quiz.

Animacies, Interactive Control Loops, and Threads of Control

We say an object in Java is self-animating when a new thread of control comes into being with every new instance of that object. We should expect animated objects to have a run method, which contains an interactive control loop. Here is a class that should be familar from the Design Project:

public class Beeper implements Runnable {
   private Thread spirit;
   private boolean beeping = false;

   public class Beeper () {
      this.spirit = new Thread(this);
      this.spirit.start();
   }

   public void alarm() {
      this.beeping = true;
   }

   public void snooze() {
      this.beeping = false;
   }

   public void beep() {
      // code to cause the system bell to go off.
   }

   public void run() {
      while (this.beeping) {
         this.beep();
      }
   }
}
Which one of the following statements is true?
  1. The run method will be called infinitely many times.
  2. The while statement will loop infinitely many times.
  3. The beeper will go off when you call alarm(), but it will die and never work again when you call snooze().
  4. The beeper will die without ever beeping.
  5. Each call to beep() represents a new thread of control.
  6. Each pass through the while loop represents a new thread of control.

Event-Driven Programming, Systems of Objects

Though there is a subtle difference between interactive control loops and event-driven programming, it is still useful to recognize the difference. Which of the following statements about the Documentation Project is true?

    1. The entire Documentation Project system of objects was written in event-driven style.
    2. Because the ButtonHandler is animate, the ButtonObj that it calls cannot be event-driven.
    3. The Calculator gui delivered button presses to the ButtonHandler.
    4. The ButtonHandler actively queried the Calculator gui for button presses.
    5. The CalculatorState actively queried the ButtonObj for state changes.
    6. You can't mix event-driven classes with interactive control loops in the same system of objects.

Polymorphic Dispatch

In the Documentation Project, you saw that the ButtonHandler viewed all of its buttons as instances of ButtonObj, when in actuality they were subclasses of ButtonObj. This ability to view a object as having several different types is called polymorphism. The code exploited polymorphism by making each button override the handleButton() method of their superclass. This permits very different operations to occur with a single method call; so that the ButtonHandler dispatch code was kept very simple, and each button took responsibility to handle the events.

Procedural Abstraction and Interfaces

When you find yourself writing pieces of code that are very similar, are of general usefulness, or see a design pattern crop up in several places, perhaps it is time to harness the power of abstraction. It is also a good idea when you want to abstract away the details of your code so that people using your code are presented with a simple and intuitive view of your work.

Static, Final, and Abstract Modifiers

There are some Java keywords that can supplement our existing universe of objects: static, final, and abstract. Let us see an example that uses all three:

public class Library {

   // different sections of a library
   private static final int PERIODICALS = 0,
                            REFERENCE   = 1,
                            NONFICTION  = 2,
                            FICTION     = 3;

   // every library has a librarian
   public static final Librarian libby = new Librarian();

   // Some libraries use Dewey Decimal, some allow more advanced searching
   // External classes need to provide the section they want to search.
   public abstract Book[] lookup(int section, String identifier);
   
   // get help
   public String askForHelp(String topic) {
      return libby.getAdvice(topic);
   }
   
   // just in case our librarian needs to retire
   public void setLibrarian(Librarian libby2) {
      this.libby = libby2;
   }
}
Which one of the following is false?
  1. Class Library should be abstract so that lookup can be abstract.
  2. All Library instances we create will share the same librarian.
  3. If we make class Library abstract, only its subclasses can be instantiated.
  4. The setLibrarian method will only work if the librarian was no longer static.
  5. The setLibrarian method will only work if the librarian was no longer final.
  6. The four "section" constants should be made public in order to be useful.

Finite State Machines

Finite state machines are a powerful tool when used correctly. However, it is easy to miss a few states or transitions when translating a design from paper into Java code. Here is a code fragment from a state machine:

switch (state) {
   case 0:  state = 3; break; 
   case 1:  state = 0; break;
   case 2:  state = 1; break;
   case 3:  state = 2; break;
   default: // do nothing
}

Which one of the following is equivalent? Assume that state is an integer field; and remember that integers can take on any value in the range [-2^32, +2^32-1]

    1. state = (state+3) % 4;
    2. if (state == 0) { state = 3; }
      else { state = state - 1; }
    3. if (state == 0) { state = 3; }
      else if (state <= 3) { state = state - 1; }
    4. if (state < 4) {
      if (state == 0) { state = 3; }
      else if (state > 0) { state = state - 1; }
      }
    5. switch (state) {
      case 0: state = 3;
      case 1: state = 0;
      case 2: state = 1;
      case 3: state = 2:
      }
    6. switch (state) {
      case 0: state = 3; break;
      default: state = state - 1;
      }

Inheritance and Overriding

Inheritance refers to the relationships between superclasses and their subclasses. Overriding means replacing a method with a more specific method for a particular subclass. When overriding constructors, note that super(...) must always be the first line of active code. Be sure you know how to override methods. Work from the bottom up when figuring out which method will get called (start with the subclass, if no method by that name, look in the superclass, in no method by that name, look in its superclass...).

Control Structures

For loops, while loops, switch/case statements.

Main Classes, Arrays

Here's an interesting class:

public class Mirror {
   public static void main(String[] args) {
         System.out.println(args[args.length]);
   }
}

When we type at the command line:

javac Mirror.java
java Mirror "hello world" "goodbye"

Which one of the following happens?

  1. Doesn't compile, the class must be called Main.
  2. Compiles but does not run; you need to create an instance of the class.
  3. Compiles, runs, and prints "hello world"
  4. Compiles, runs, and prints "goodbye"
  5. Compiles, runs, and gets a ArrayIndexOutOfBoundsException.
  6. Compiles, runs, and prints out pure garbage.

Documentation

The ideal way to document your code is to provide an overview at the beginning of each class, and then comment each field and method, and those parts of the code that warrant an explanation. However, comments can sometimes be a source of trouble! Here is a story:

There was once a company that produced military-grade flight simulators. The day before a major demo, one of the engineers modified one of the many programs that constituted the demo software. When the night shift arrived, they fortunately had the foresight to check the demo one more time, and found that it crashed catastrophically. Gleefully, the night shift woke up the engineer for an explanation:

The members of the night shift laughed at this and decided to let the poor man sleep; they knew where the bug was now.

Here might be such a piece of code (messy on purpose):

import java.awt.*;

// this is supposed to be an animate object that knows how to render polygons 
public class StealthGraphicsEngine implements Runnable {

   public Thread spirit;                   // thread object  
   public Polygon[] polyList;           // a list of polygons
   public String demoData /* ; hardcoded for now */
                          = "DEMO.3DS";   
   // public Graphics doubleBuffer;        // we don't need this for the demo

   /* The constructor.
   // hey, should the constructor take a string which is the filename to load?
   */
   public class StealthGraphicsEngine() {
      polyList = new PolygonList[1000]; // the demo only handles 1000 polygons //
      fill(polyList, demoData);              /* this fills the array with demo data
      */
      this.spirit = new Thread(       // do I need to cast this to a Runnable?
                               this);      /* create a new thread of control and
      this.spirit.start();                  * make sure that run() gets called */
   }

   public void fill(Polygon[] plist, String filename) {
      // more code here
   }

   public void render(Polygon p) {
      // more code here
   } 

   // this is the interactive control loop
   public void run() {
      while (true) {                                // infinite loop
         for (int i=0; i<polygonList.length; i++) { /* for every polygon */
            render(polygonList[i]);                 // render it 
         }
      }
   }
}

Which line of code has been disabled, causing the catastrophe?

    1. render(polygonList[i]);
    2. public String demoData;
    3. public Graphics doubleBuffer;
    4. this.spirit.start();
    5. fill(polyList, demoData);
    6. this.spirit = new Thread(this);

Solutions

You can see how well you did on this sample quiz. Below are listed the correct answers. If you have questions, you can send us mail. Remember that eliminating a wrong answer gives you +2 points, and eliminating the correct answer gives you -10 points.

  1. Animacies : 4
  2. Event-Driven Programming : 4
  3. Static/Final/Abstract : 4
  4. FSMs: 4
  5. Main Classes, Arrays: 5
  6. Documentation: 4

Since there are only six questions on this sample quiz, the absolute maximum score would be +60 and the absolute minimum would be -60. There will be fifteen questions on the actual quiz.


This course is a part of Lynn Andrea Stein's Rethinking CS101 project at the MIT AI Lab and the Department of Electrical Engineering and Computer Science at the Massachusetts Institute of Technology.

Questions or comments:
<cs101-webmaster@ai.mit.edu>

Last modified: Thu Jul 10 13:01:20 1997