Sharvil SaxenaStudy / CS 180

Purdue · CS 18000 · Problem Solving & Object-Oriented Programming

The CS 180
Machine Shop

Eighteen modules of Java, built as machines you can grab and turn. Every idea gets one sentence, one analogy a third grader would get, one rig you can break, and the exact syntax Purdue grades you on. No word walls.

Scope check: module order is a learning order, but every module is badged with the week it maps to in Purdue's official CS 18000 module list (cs.purdue.edu/homes/bxd/180/lectures). All 14 weeks are covered, including Network I/O, GUIs and dynamic data structures.

Java 17 22 modules · 14 course weeks Drag any diagram to orbit Stack · Heap · Threads Exam 1: 20 MCQ + 3 coding Test-out: 75 MCQ · 85% Timed mock · 110 MCQ · 88 written
01

How Java Actually Runs

Week 1javac · .class · bytecode · JVM

Java is written twice: once by you in English-ish text, once by the compiler into a robot language — and only the robot version ever runs.

🏭

Shop floorYou write the work order (Main.java). javac is the shop foreman who reads it, screams if a word is misspelled, and stamps out a metal punch card (Main.class). The JVM is the machine that eats punch cards. The machine never reads your handwriting — only the card.

Compile & Run Pipeline drag to orbit
Press Compile & Run to send the work order through the shop.
Main.java
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, Boilermakers!");
    }
}
terminal
javac Main.java     // makes Main.class
java Main           // runs it — NO .class on the end
Trap

The file name must exactly match the public class name, capital letters and all. public class Main must live in Main.java. And main must be spelled public static void main(String[] args) — miss static and it compiles fine, then dies at runtime with "Main method not static".

02

Variables & The Eight Primitives

Week 2int · double · boolean · char · casting · overflow

A variable is a box of a fixed size with a fixed shape — the type decides both, and Java checks the shape before it lets anything in.

🧰

Shop floorA parts bin labeled int is exactly 32 slots wide and only holds whole numbers. Pour in a number too big and it doesn't overflow onto the floor — it wraps around the odometer and comes out negative. That's not a bug in Java; that's the bin being honest about its size.

Bin Widths & Odometer Wrap
7
drag to orbit
TypeBitsHoldsLiteral you write
byte8−128 … 127(byte) 100
short16−32,768 … 32,767(short) 5000
int32±2.1 billion42
long64±9.2 quintillion42L
float32~7 decimal digits3.14f
double64~15 decimal digits3.14
char16one character'A' (single quotes!)
boolean1*true / falsetrue
declaring & casting
int    count   = 42;          // whole number
double gpa     = 3.87;        // decimal
char   grade   = 'A';         // ONE char, single quotes
boolean passed = true;

// widening: safe, automatic (small bin -> big bin)
double d = count;             // 42.0

// narrowing: dangerous, needs a CAST (big bin -> small bin)
int chopped = (int) 3.99;     // 3   <- truncates, never rounds
byte wrapped = (byte) 130;    // -126 <- odometer wrapped

final int MAX_STUDENTS = 300; // final = welded shut, cannot reassign
Trap

(int) 3.99 is 3, not 4. Casting to int chops the decimal off — it never rounds. If you want rounding, Math.round(3.99) gives 4.

Also: 'A' is a char. "A" is a String. They are not the same thing and swapping the quotes is a compile error.

03

Operators & The Integer Division Trap

Week 2precedence · / vs % · ++ · compound assignmenthigh-yield

Java evaluates an expression in a fixed order, innermost first — and if both sides of a / are whole numbers, the answer is forced to be a whole number too.

🍕

Shop floor5 / 2 is 2, not 2.5. Java is a machine that only outputs whole crates when both inputs are whole crates — the leftover half is swept into the bin. % (modulo) is the sweeper: it hands you exactly what was left over. 5 % 2 == 1.

Evaluation Order
the ones that bite
int a = 5 / 2;          // 2      <- integer division
double b = 5 / 2;       // 2.0    <- STILL 2! divided before converting
double c = 5.0 / 2;     // 2.5    <- one double makes it all double
double d = (double) 5 / 2;  // 2.5 <- cast one side first

int rem = 17 % 5;       // 2      <- remainder
boolean even = (n % 2 == 0);

int i = 5;
System.out.println(i++);   // prints 5, THEN i becomes 6
System.out.println(++i);   // i becomes 7, THEN prints 7

int x = 10;
x += 3;   // x = x + 3  -> 13
x /= 2;   // x = x / 2  -> 6   (integer division again!)
bitwise — named on the test-out list, skipped by most notes
int a = 12;      // 1100
int b = 10;      // 1010

a & b            // 8   1000   AND  — 1 only where BOTH are 1
a | b            // 14  1110   OR   — 1 where EITHER is 1
a ^ b            // 6   0110   XOR  — 1 where they DIFFER
~a               // -13        NOT  — flips every bit
a << 2           // 48         shift left  = multiply by 2 each place
a >> 2           // 3          shift right = divide by 2 each place
-8 >> 1          // -4         keeps the sign
-8 >>> 1         // huge       >>> fills with 0, so negatives go positive

// & and | are BITWISE. && and || are logical AND short-circuit.
if (x != null & x.size() > 0)   // evaluates BOTH sides -> can throw
if (x != null && x.size() > 0)  // stops if the left is false -> safe
Precedence, short version: ()++ --* / %+ -< > <= >=== !=&&||=. When in doubt, put parentheses. Nobody has ever lost points for extra parentheses.
Trap

double avg = sum / count; where both are int gives you a truncated answer even though the box is a double. The division already happened in int-land before the value was copied over. Fix: (double) sum / count.

04

Strings Are Frozen

Week 2immutability · == vs .equals() · the string pool

A String can never be edited — every "change" secretly builds a brand-new String and quietly abandons the old one.

🔨

Shop floorA String is a name stamped into a steel plate. You cannot un-stamp a letter. To get "CS18" from "CS1" the shop stamps a whole new plate and throws the old one in the scrap bin. That's why building a String inside a big loop is slow — you're stamping thousands of plates.

The Scrap Bin drag to orbit
the methods you will use every week
String s = "Boilermaker";

s.length()             // 11
s.charAt(0)            // 'B'          <- char, not String
s.substring(0, 5)      // "Boile"      <- start inclusive, end EXCLUSIVE
s.indexOf("maker")     // 6            <- -1 if not found
s.toUpperCase()        // "BOILERMAKER" <- returns NEW string, s unchanged
s.trim()               // strips whitespace off both ends
s.equals("boilermaker")        // false — case matters
s.equalsIgnoreCase("BOILER..") // true
s.split(",")           // String[] pieces
s.contains("make")     // true
s.isEmpty()            // false

// s is STILL "Boilermaker" — none of those changed it.
s = s.toUpperCase();   // you must catch the return value
== vs .equals() — the #1 exam question
String a = "Purdue";
String b = "Purdue";
String c = new String("Purdue");

a == b        // true  — both point to the SAME pooled plate
a == c        // false — 'new' forces a fresh plate
a.equals(c)   // true  — compares the LETTERS

// Rule: == compares addresses. .equals() compares contents.
// For Strings, ALWAYS use .equals().
Trap

s.toUpperCase(); on a line by itself does nothing. It computes a new String and throws it away. You must write s = s.toUpperCase();.

substring(2, 5) gives characters at index 2, 3, 4 — the end index is not included. Length of the result is always end - start.

05

Conditionals

Week 3if / else if / else · switch · short-circuit · && ||high-yield

An if/else if chain is a row of gates the value falls through — the first gate that opens is the only one that ever runs.

🚦

Shop floorParts roll down a chute past a line of trapdoors. The first trapdoor whose test says yes swallows the part. Nothing below it is even checked. That's why order matters: if you test score >= 60 first, an A student falls through the D door and never reaches the A door.

Grade Chute
87
the correct order
if (score >= 90) {
    grade = 'A';
} else if (score >= 80) {      // only reached if score < 90
    grade = 'B';
} else if (score >= 70) {
    grade = 'C';
} else {
    grade = 'F';
}

// switch — good for exact matches, not ranges
switch (day) {
    case 1:
    case 2:
        System.out.println("Lecture");
        break;              // WITHOUT break it falls into the next case
    case 3:
        System.out.println("Lab");
        break;
    default:
        System.out.println("No class");
}

// short circuit: if arr is null, Java never evaluates the right half
if (arr != null && arr.length > 0) { ... }   // safe
if (arr.length > 0 && arr != null) { ... }   // NullPointerException
Trap

if (x = 5) is assignment, not comparison — for int it won't even compile in Java (good), but for boolean flags if (done = true) compiles and silently sets it. Use ==, or just if (done).

A missing break in a switch makes every case below it run too. Purdue exams love this.

06

Loops

Week 4for · while · do-while · off-by-one · nested

A for loop is three separate promises on one line: where to start, when to quit, how to move — and the quit test is checked before every single pass.

🚂

Shop floorA fence with 5 posts has 4 gaps. Loops break because people count posts when they meant gaps. i < n runs n times (0…n−1). i <= n runs n+1 times — one post too many, and on an array that's a crash.

Loop Stepper
drag to orbit
all four shapes
// 1. counting for-loop: start; test; update
for (int i = 0; i < 5; i++) {
    System.out.println(i);       // 0 1 2 3 4  -> five passes
}

// 2. while: test first, may run ZERO times
int n = 0;
while (n < 5) { n++; }

// 3. do-while: body first, ALWAYS runs at least once
int tries = 0;
do {
    tries++;
} while (tries < 5);

// 4. for-each: every element, no index, cannot modify the array slot
for (int score : scores) {
    total += score;
}

// nested: the inner loop finishes completely on every outer pass
for (int r = 0; r < 3; r++) {
    for (int c = 0; c < 4; c++) {   // runs 3 x 4 = 12 times total
        System.out.print(r + "," + c + " ");
    }
    System.out.println();
}

break;      // leave the loop entirely, right now
continue;   // skip to the next pass
Trap

for (int i = 0; i <= arr.length; i++) — the last pass uses index arr.length, which does not exist. Instant ArrayIndexOutOfBoundsException. The valid indices are 0 through length - 1.

Forgetting i++ inside a while gives you an infinite loop and a very quiet terminal.

07

Arrays

Week 5fixed length · index 0 · .length · out of boundshigh-yield

An array is a row of identical boxes, numbered from zero, whose length is welded shut the moment it is built.

📬

Shop floorA wall of mailboxes bolted in place. Numbering starts at 0, so 5 mailboxes are numbered 0, 1, 2, 3, 4 — there is no box 5. Reaching for box 5 doesn't get you nothing; it gets you thrown out of the post office (an exception).

Mailbox Wall
2
drag to orbit
every way to make one
int[] nums = new int[5];              // 5 boxes, all 0 by default
int[] primes = {2, 3, 5, 7, 11};      // literal, length locked at 5
String[] names = new String[3];       // 3 boxes, all null by default

nums[0] = 42;                 // first box
nums[nums.length - 1] = 9;    // LAST box, always this expression
int len = nums.length;        // FIELD, no parentheses (String uses length())

// walk it
for (int i = 0; i < nums.length; i++) {
    System.out.println(i + ": " + nums[i]);
}

// for-each: read-only view of the values
for (int v : nums) {
    total += v;               // v is a COPY; v = 0 does not clear the array
}

// defaults: int 0 | double 0.0 | boolean false | char '' | objects null

Arrays.sort(nums);                          // import java.util.Arrays;
System.out.println(Arrays.toString(nums));  // [2, 3, 5, 7, 11]
Trap

arr.length has no parentheses. str.length() has them. Mixing these up is the most common compile error in the course.

Arrays cannot grow. arr[5] = x on a length-5 array throws ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5. If you need it to grow, you need module 17.

08

2D Arrays

Week 5grid[row][col] · row-major · jagged arrays

A 2D array is not really a grid — it is an array whose boxes each hold another array, which is why the first index is the row.

🗄️

Shop floorA filing cabinet. grid[2][3] means "open drawer 2, then take folder 3". Drawer first, always. That's why grid.length is the number of drawers (rows) and grid[0].length is the folders in the first drawer (columns).

Filing Cabinet
drag to orbit
declare, fill, walk
int[][] grid = new int[3][4];      // 3 rows, 4 columns

int[][] seats = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

seats[1][2]            // 7   -> row 1, column 2
seats.length           // 3   -> number of ROWS
seats[0].length        // 4   -> columns in row 0

// the standard nested walk
for (int r = 0; r < seats.length; r++) {
    for (int c = 0; c < seats[r].length; c++) {   // seats[r], not seats[0]
        System.out.print(seats[r][c] + " ");
    }
    System.out.println();
}

// jagged: rows may have different lengths
int[][] tri = new int[3][];
tri[0] = new int[1];
tri[1] = new int[2];
tri[2] = new int[3];
Trap

Use seats[r].length for the inner loop, not seats[0].length. On a jagged array the hard-coded row 0 will run off the end of a shorter row.

new int[3][4] is 3 rows of 4, not 4 rows of 3. Rows first.

09

Methods & The Call Stack

Week 6parameters · return · pass-by-value · overloading · scopehigh-yield

Calling a method stacks a fresh tray of local variables on top, and that tray — with everything on it — is thrown away the instant the method returns.

🍽️

Shop floorThe stack is a cafeteria tray dispenser. Every call drops a new tray on top holding its own copy of the arguments. When the method finishes, the top tray is yanked out and burned. Last in, first out. That's why a variable declared inside a method vanishes when it ends, and why main is always the tray at the very bottom.

Tray Dispenser drag to orbit
anatomy of a method
//  modifier  return-type  name  (parameter list)
    public static int  triple(int n) {
        return n * 3;              // must return an int on EVERY path
    }

    public static void greet(String who) {   // void = returns nothing
        System.out.println("Hi " + who);
    }

// OVERLOADING: same name, DIFFERENT parameter list
public static int    add(int a, int b)          { return a + b; }
public static double add(double a, double b)    { return a + b; }
public static int    add(int a, int b, int c)   { return a + b + c; }
// changing ONLY the return type is not overloading -- it will not compile
Pass-By-Value Proof
Java is ALWAYS pass-by-value
public static void bump(int x) {
    x = x + 100;             // changes only the local COPY
}
int a = 5;
bump(a);
System.out.println(a);       // 5   <- unchanged!

public static void bump(int[] arr) {
    arr[0] = 999;            // follows the ticket to the SAME array
}
int[] nums = {5};
bump(nums);
System.out.println(nums[0]); // 999 <- changed!

public static void swap(int[] arr) {
    arr = new int[]{0, 0};   // repoints the local COPY of the ticket
}                            // caller's array is untouched
Trap

Java passes a copy of the value. For an int that's a copy of the number. For an object it's a copy of the address — so you can change what's inside the object, but reassigning the parameter itself changes nothing for the caller.

A static method cannot call an instance method directly. If main is static and helper() is not, you need an object: new Main().helper().

10

Classes & Objects

Week 6constructor · this · fields · static vs instance · encapsulation

A class is a blueprint; an object is one machine built from it — every machine gets its own copy of the fields, except the ones marked static, which are bolted to the wall and shared.

📐

Shop floorThe blueprint for a boiler is not a boiler. new Boiler() is the moment the shop actually welds one. Each boiler has its own pressure gauge (instance field). But the shop's single serial-number counter on the wall belongs to the blueprint, not to any one boiler — that's static.

Blueprint to Machines click a machine · drag to orbit
Boiler.java — the full shape Purdue expects
public class Boiler {
    // 1. FIELDS -- private, always
    private String name;
    private int psi;
    private static int builtCount = 0;   // ONE copy, shared by all boilers

    // 2. CONSTRUCTOR -- same name as the class, NO return type
    public Boiler(String name, int psi) {
        this.name = name;      // this.name is the field, name is the parameter
        this.psi = psi;
        builtCount++;
    }

    public Boiler(String name) {         // overloaded constructor
        this(name, 0);                   // calls the other one; must be line 1
    }

    // 3. GETTERS / SETTERS -- the only doors into a private field
    public String getName()      { return name; }
    public int    getPsi()       { return psi; }
    public void   setPsi(int psi){ this.psi = psi; }

    // 4. BEHAVIOR
    public void raise(int amount) { psi += amount; }

    public static int getBuiltCount() { return builtCount; }  // static: no 'this'

    // 5. toString -- what println prints for this object
    @Override
    public String toString() {
        return name + " @ " + psi + " psi";
    }
}
using it
Boiler a = new Boiler("Old Gold", 120);
Boiler b = new Boiler("Special");

a.raise(30);
System.out.println(a);                      // Old Gold @ 150 psi  (toString)
System.out.println(a.getPsi());             // 150
System.out.println(Boiler.getBuiltCount()); // 2  <- called on the CLASS
Trap

A constructor has no return type. Writing public void Boiler(...) makes it an ordinary method, Java hands you a default constructor instead, and your fields are never set.

Inside a static method there is no this — no object exists yet. That is the real reason main can't touch instance fields directly.

11

References & Memory

Week 6stack vs heap · aliasing · null · == vs equals · garbage collection

A variable of object type never holds the object — it holds a ticket, and two tickets can point at the same crate.

🎟️

Shop floorCoat check. Your pocket (the stack) holds a small paper ticket. The coat hangs in the back room (the heap). Copy the ticket to a friend and there is still exactly one coat — if they cut a sleeve off, your coat is missing a sleeve. == asks "same ticket number?" .equals() asks "same coat?"

The Memory Theater
aliasing, null, and equality
Boiler a = new Boiler("A");   // heap: one crate. stack: ticket 'a'
Boiler b = a;                 // COPY OF THE TICKET -- still one crate
b.setName("Z");
System.out.println(a.getName());   // "Z"  <- same crate!

Boiler c = new Boiler("Z");   // a SECOND crate that happens to match
a == c        // false  -- different ticket numbers
a.equals(c)   // false too, UNLESS you override equals()

a = null;     // ticket torn up; crate unreachable -> garbage collected
a.getName();  // NullPointerException: Cannot invoke ... because "a" is null
overriding equals — how you make .equals() mean something
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Boiler other = (Boiler) o;
    return psi == other.psi && name.equals(other.name);
}
Lives on the stackLives on the heap
Local variables, parameters, the 8 primitives, and ticket numbers (references)Every new — objects, arrays, Strings — plus each object's instance fields
Popped automatically when the method returnsFreed by the garbage collector, once nothing points at it
Trap

NullPointerException means you called a method on a ticket pointing at nothing. It almost always comes from an uninitialized object field, or from an array of objects — new String[3] gives you three nulls, not three empty Strings.

12

Inheritance & Polymorphism

Week 8 · 12extends · super · @Override · dynamic dispatch · casting

A subclass is everything the parent had, plus extras — and when you call a method, Java searches upward from the object's real class until it finds one.

🚂

Shop floorA Locomotive is a Vehicle with a boiler welded on. Shout "MOVE!" at a yard full of vehicles and each one moves its own way — the locomotive hauls, the handcar pumps. You gave one order; the object picked the behavior. That's polymorphism.

Dynamic Dispatch — who answers the call? click a class · drag to orbit
Vehicle.java / Locomotive.java
public class Vehicle {
    protected String id;                 // protected = visible to subclasses

    public Vehicle(String id) { this.id = id; }

    public void move() { System.out.println(id + " rolls."); }
    public void horn() { System.out.println("beep"); }
}

public class Locomotive extends Vehicle {
    private int cars;

    public Locomotive(String id, int cars) {
        super(id);              // MUST be first -- builds the parent part
        this.cars = cars;
    }

    @Override                   // optional keyword, but it catches typos
    public void move() {
        super.move();           // run the parent version first (optional)
        System.out.println("...hauling " + cars + " cars.");
    }

    public int getCars() { return cars; }
}
the exam question
Vehicle v = new Locomotive("Boiler Special", 12);

v.move();     // Locomotive's move() runs  <- decided at RUNTIME by the object
v.horn();     // Vehicle's horn() runs     <- inherited, not overridden
// v.getCars();  COMPILE ERROR -- the ticket says Vehicle, so only
//               Vehicle's methods are visible

((Locomotive) v).getCars();   // downcast to reach the extras

if (v instanceof Locomotive loco) {   // safe check + cast in one
    loco.getCars();
}
The two-rule summary: the reference type (left of the =) decides which methods you're allowed to call. The object type (right of new) decides which version actually runs. Compile-time vs run-time.
Trap

Overriding means an identical name and parameter list. Change the parameters and you've silently written an overload instead — the parent version keeps running and nothing warns you. That is exactly why you write @Override.

Every constructor calls super() first, whether you write it or not. If the parent has no no-arg constructor, you must call super(...) yourself.

13

Interfaces & Abstract Classes

Week 8implements · abstract · contracts · why both existhigh-yield

An interface is a list of promises with no bodies; anything that signs it must implement every one, and can then be used anywhere that interface is accepted.

🔩

Shop floorAn interface is a bolt pattern. Any part with those four holes in those four spots can mount on the machine — the machine doesn't care what the part is. An abstract class is different: it's a half-built chassis. It already has wheels welded on, but no engine, so you can't drive it — you must extend it and finish the job.

Bolt Pattern Test toggle a method off to break the contract
interface
public interface Shape {
    double area();            // no body, implicitly public abstract
    double perimeter();

    default String describe() {          // default method HAS a body (Java 8+)
        return "area " + area();
    }
}

public class Circle implements Shape {
    private double r;
    public Circle(double r) { this.r = r; }

    @Override public double area()      { return Math.PI * r * r; }
    @Override public double perimeter() { return 2 * Math.PI * r; }
}

// a class may implement MANY interfaces, but extend only ONE class
public class Rect extends Polygon implements Shape, Comparable { ... }
abstract class
public abstract class Vehicle {
    protected String id;
    public Vehicle(String id) { this.id = id; }   // abstract classes DO have constructors

    public abstract void move();      // no body -- subclass MUST write it

    public void horn() {              // concrete -- inherited as-is
        System.out.println("beep");
    }
}

// Vehicle v = new Vehicle("x");   COMPILE ERROR: cannot instantiate
Vehicle v = new Locomotive("Special", 12);   // legal: a finished subclass
interfaceabstract class
Keyword to joinimplementsextends
How many?manyexactly one
Can hold state (fields)?constants onlyyes, any fields
Can be instantiated?nono
Use it whenunrelated classes share an abilityrelated classes share code plus a gap
Trap

If a class implements an interface and misses even one method, it will not compile — unless you mark the class abstract too and pass the obligation down to its subclass.

14

Exceptions

Week 7try / catch / finally · checked vs unchecked · throw · stack unwindinghigh-yield

When something breaks, Java abandons the rest of the method immediately and climbs back down the stack looking for someone who agreed to catch this kind of problem.

🕳️

Shop floorThe try block is a chute. When a part jams, a trapdoor opens under it — everything below in the chute is skipped, and the part drops into the first basket (catch) labeled for that kind of jam. finally is the janitor who sweeps up either way, jam or no jam.

Trapdoor & Basket
drag to orbit
the full shape
try {
    int result = 10 / divisor;            // may throw
    System.out.println(result);           // SKIPPED if it throws
} catch (ArithmeticException e) {         // most specific FIRST
    System.out.println("Divide by zero: " + e.getMessage());
} catch (Exception e) {                   // catch-all LAST
    System.out.println("Something else: " + e);
} finally {
    System.out.println("always runs");    // even after a return
}

// throwing your own
if (psi < 0) {
    throw new IllegalArgumentException("psi cannot be negative");
}

// checked exception: the compiler forces you to handle OR declare it
public static void read(String path) throws FileNotFoundException {
    Scanner in = new Scanner(new File(path));
}
KindExamplesCompiler forces handling?
Unchecked (RuntimeException)NullPointerException, ArrayIndexOutOfBounds, ArithmeticException, NumberFormatExceptionNo — these are bugs you should prevent
CheckedFileNotFoundException, IOException, InterruptedExceptionYes — try/catch it or add throws
Trap

Order your catches most specific first. Putting catch (Exception e) above catch (ArithmeticException e) is a compile error — the second one is unreachable.

A variable declared inside the try block does not exist inside the catch block. Declare it above the try if both need it.

15

File I/O

Week 7Scanner · BufferedReader · PrintWriter · close() · flush

Reading and writing files happens one line at a time through a buffer — and if you never close the stream, the last things you wrote may never reach the disk.

📦

Shop floorWriting is a loading dock: boxes pile up on the dock (the buffer) and only get on the truck when the dock is full or you shout "GO" (close() / flush()). Forget to shout, and the last few boxes are still sitting on the dock when the shop closes — your file ends up empty or truncated.

Loading Dock drag to orbit
reading — Scanner (easiest)
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public static void main(String[] args) throws FileNotFoundException {
    Scanner in = new Scanner(new File("data.txt"));

    while (in.hasNextLine()) {          // ask BEFORE you read
        String line = in.nextLine();
        System.out.println(line);
    }
    in.close();
}

// keyboard input is the same class
Scanner kb = new Scanner(System.in);
int n = kb.nextInt();
kb.nextLine();          // <- eats the leftover newline. ALWAYS needed
String name = kb.nextLine();
reading — BufferedReader (faster, checked exception)
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
    String line;
    while ((line = br.readLine()) != null) {   // null means end of file
        System.out.println(line);
    }
} catch (IOException e) {
    System.out.println("Could not read: " + e.getMessage());
}
// try-with-resources: the ( ) closes it for you, even if it throws
writing — PrintWriter
import java.io.PrintWriter;

PrintWriter out = new PrintWriter("out.txt");        // overwrites the file
out.println("Boiler up");
out.printf("%s scored %.2f%n", name, gpa);
out.close();          // <- WITHOUT THIS THE FILE MAY BE EMPTY

// append instead of overwrite
PrintWriter app = new PrintWriter(new FileWriter("out.txt", true));
Trap

nextInt() leaves the newline sitting in the pipe, so the very next nextLine() returns an empty string. Fix: an extra kb.nextLine(); right after the number, or read everything with nextLine() and use Integer.parseInt(...).

new PrintWriter("out.txt") erases the file the second it opens. Pass new FileWriter(path, true) to append.

16

Recursion

Week 14base case · recursive case · the stack · StackOverflowError

A recursive method solves a big problem by calling itself on a smaller one, and it only ever stops because of the base case.

🪆

Shop floorRussian dolls. To count them you open one and ask the doll inside "how many are you?" — then add one. The smallest doll doesn't open; it just says "1". That's the base case. No smallest doll = you open forever = StackOverflowError, the stack of trays hits the ceiling.

Doll Tower — factorial(n)
4
drag to orbit
the two-part recipe
public static int factorial(int n) {
    if (n <= 1) {                 // 1. BASE CASE -- stops the recursion
        return 1;
    }
    return n * factorial(n - 1);  // 2. RECURSIVE CASE -- must shrink n
}
// factorial(4) -> 4 * factorial(3) -> 4*3*factorial(2) -> 4*3*2*factorial(1)
//              -> 4*3*2*1 = 24

public static int fib(int n) {
    if (n <= 1) return n;                     // base: fib(0)=0, fib(1)=1
    return fib(n - 1) + fib(n - 2);           // two calls -> a TREE, not a line
}

public static String reverse(String s) {
    if (s.isEmpty()) return "";
    return reverse(s.substring(1)) + s.charAt(0);
}

public static int sum(int[] arr, int i) {
    if (i == arr.length) return 0;            // walked off the end
    return arr[i] + sum(arr, i + 1);
}
Trap

Every recursive call must move toward the base case. factorial(n) calling factorial(n) — or forgetting the - 1 — piles trays until the JVM throws StackOverflowError.

A negative n skips the base case entirely. if (n <= 1) is safer than if (n == 1).

17

ArrayList

Week 12–13generics · autoboxing · resize · remove-while-loopinghigh-yield

An ArrayList is an array that quietly moves house — when it fills up, it allocates a bigger array and copies everything over.

🚚

Shop floorA shelf with 10 slots. Add an 11th part and the shop doesn't stretch the shelf — it builds a shelf half again as long, carries every part over, and scraps the old one. You never see it happen, which is why adding is usually instant and occasionally slow.

Moving House drag to orbit
array vs ArrayList
import java.util.ArrayList;

ArrayList names = new ArrayList<>();   // <> must hold an OBJECT type
ArrayList nums = new ArrayList<>();   // Integer, NOT int

names.add("Sharvil");        // append
names.add(0, "First");       // insert at index, shifts everything right
names.get(1);                // read           (arrays use names[1])
names.set(1, "Other");       // overwrite
names.remove(0);             // delete + shift left
names.size();                // count          (arrays use .length)
names.contains("Sharvil");   // true / false
names.indexOf("Sharvil");    // -1 if absent
names.isEmpty();
names.clear();

for (String n : names) { System.out.println(n); }

nums.add(5);                 // autoboxing: int 5 -> Integer.valueOf(5)
int first = nums.get(0);     // unboxing back to int
remove(int) vs remove(Object) — a real bug
ArrayList nums = new ArrayList<>();
nums.add(10); nums.add(20); nums.add(30);

nums.remove(1);                      // removes INDEX 1  -> [10, 30]
nums.remove(Integer.valueOf(10));    // removes the VALUE 10 -> [30]

// removing while looping forward SKIPS elements:
for (int i = 0; i < list.size(); i++) {
    if (bad(list.get(i))) list.remove(i);     // BUG: shifts under you
}
// loop BACKWARD instead:
for (int i = list.size() - 1; i >= 0; i--) {
    if (bad(list.get(i))) list.remove(i);     // safe
}
Trap

ArrayList<int> does not compile. Generics only take object types: Integer, Double, Character, Boolean.

Size vs length vs length(): list.size(), arr.length, str.length(). Three different spellings for the same idea, and Java will not forgive you.

18

Threads & Race Conditions

Week 9Thread · Runnable · start vs run · synchronized · joinhigh-yield

Two threads sharing one variable will interleave in a different order every run, and count++ is not one step — it is read, add, write.

🔑

Shop floorTwo workers, one clipboard. Worker A reads "17", and before A can write "18", worker B also reads "17". Both write 18. One count vanished. synchronized is a single key to the clipboard room — only the worker holding the key may go in.

Two Workers, One Clipboard
two ways to make a thread
// A. implement Runnable (preferred -- leaves you free to extend something else)
public class Counter implements Runnable {
    private Shared s;
    public Counter(Shared s) { this.s = s; }

    @Override
    public void run() {                 // the work
        for (int i = 0; i < 200; i++) s.bump();
    }
}

Thread t1 = new Thread(new Counter(shared));
Thread t2 = new Thread(new Counter(shared));

t1.start();      // start() spawns a NEW thread and calls run() there
t2.start();
// t1.run();     <- calling run() directly just runs it on the CURRENT thread

t1.join();       // wait here until t1 finishes
t2.join();
System.out.println(shared.get());   // only now is the total trustworthy


// B. extend Thread
public class Worker extends Thread {
    @Override public void run() { ... }
}
new Worker().start();
the fix
public class Shared {
    private int count = 0;

    public synchronized void bump() {   // one thread at a time in this method
        count++;                        // read, add, write -- now atomic
    }

    public int get() { return count; }
}

// or lock a smaller region:
synchronized (this) {
    count++;
}
Trap

t.run() compiles and does the work — on the current thread. Nothing runs in parallel and no bug appears in testing. Only t.start() creates a thread.

Without join(), main races ahead and prints the counter before the workers finish. The answer will be wrong and different every run.

19

Network I/O

Week 10ServerSocket · Socket · streams · accept() blockshigh-yield

A socket is a pipe with a program on each end — and once it is open, you read and write it with the exact same Scanner and PrintWriter you already use on files.

☎️

Shop floorA ServerSocket is a phone that can only ring. accept() is picking up the receiver — and it waits there forever until someone calls. What you get back is the actual call (a Socket), and both sides can talk on it at once.

Switchboard drag to orbit
Server.java
import java.io.*;
import java.net.*;

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket listener = new ServerSocket(4242);   // claim the port
        System.out.println("waiting...");

        Socket client = listener.accept();   // BLOCKS here until someone connects

        BufferedReader in  = new BufferedReader(
                                 new InputStreamReader(client.getInputStream()));
        PrintWriter    out = new PrintWriter(client.getOutputStream(), true);
        //                                                            ^^^^ autoflush

        String line;
        while ((line = in.readLine()) != null) {   // null = the other side hung up
            out.println("echo: " + line);
        }

        client.close();
        listener.close();
    }
}
Client.java
Socket s = new Socket("localhost", 4242);      // dial

PrintWriter    out = new PrintWriter(s.getOutputStream(), true);
BufferedReader in  = new BufferedReader(
                         new InputStreamReader(s.getInputStream()));

out.println("Boiler up");
System.out.println(in.readLine());     // "echo: Boiler up"

s.close();
Trap

accept() and readLine() both block. A single-threaded server can serve exactly one client and then sits there — which is why this topic comes right after threads: real servers hand each accepted socket to its own Thread.

Without true for autoflush (or an explicit out.flush()) your message sits in the buffer and the other side waits forever. Same loading-dock bug as module 15.

20

GUIs & The Event Loop

Week 10–11JFrame · JButton · ActionListener · the EDThigh-yield

A GUI program never runs top to bottom — it builds the window, then sits in a loop doing nothing, and your code only runs when a user does something.

🔔

Shop floorYou don't stand at the door waiting for visitors. You wire up a doorbell and go do something else. addActionListener is wiring the bell; the method inside it is what happens when it rings. Nobody rings it in your code — the user does.

Wire The Doorbell click the button in the window · drag to orbit
Counter.java — the whole shape of a Swing app
import javax.swing.*;
import java.awt.*;

public class Counter {
    private int count = 0;

    public Counter() {
        JFrame frame = new JFrame("Boiler Counter");   // the window
        JPanel panel = new JPanel();                   // holds components
        JLabel label = new JLabel("count: 0");
        JButton button = new JButton("Press me");

        // wire the doorbell: this runs LATER, only when clicked
        button.addActionListener(e -> {
            count++;
            label.setText("count: " + count);
        });

        panel.add(label);
        panel.add(button);
        frame.add(panel);                       // add BEFORE showing

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 120);
        frame.setVisible(true);                 // must be LAST
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Counter());  // build on the EDT
    }
}
LayoutHow it places thingsThe exam detail
FlowLayoutleft to right in a row, wrapping to the next rowthe default for a JPanel
BorderLayoutfive regions: NORTH, SOUTH, EAST, WEST, CENTERadd(c) with no constraint goes to CENTER; one component per region
GridLayoutnew GridLayout(2, 3) = 6 equally sized cells, 2 rows × 3 colsfills row by row; every cell is the same size
Layout, in one line each: FlowLayout puts things in a row and wraps. BorderLayout gives you NORTH/SOUTH/EAST/WEST/CENTER. GridLayout(r, c) makes equal cells. A JPanel inside a JPanel is how you nest layouts.
Trap

The listener body runs on the Event Dispatch Thread. Put a long loop or a blocking readLine() in there and the entire window freezes — no repaint, no clicks. Long work belongs on its own thread (module 18).

setVisible(true) goes last. Components added after it may not appear until the window is resized.

21

Linked Structures

Week 12–13Node · next · head · null terminator · O(n) walk

A linked list has no indices at all — each node knows only the one thing that comes after it, and the list is nothing more than a reference to the first node.

🧭

Shop floorA scavenger hunt. An array is a wall of numbered mailboxes — you can jump straight to box 400. A linked list is a chain of clues: each box holds a slip of paper with the address of the next box. To reach the 400th you must open all 399 before it. The last slip says null: stop.

Chain Of Clues drag to orbit
the node — a class that contains one of itself
public class Node {
    int data;
    Node next;          // a Node that holds a Node. this is the whole trick.

    public Node(int data) {
        this.data = data;
        this.next = null;
    }
}
the three operations you will be asked to write
Node head = null;               // an empty list IS just null

// 1. add to the front -- O(1), no walking
public void addFirst(int v) {
    Node n = new Node(v);
    n.next = head;              // point the new node at the old front
    head = n;                   // then move head. THIS ORDER, or you lose the list.
}

// 2. walk it -- O(n), the pattern for every linked-list question
public void print() {
    Node cur = head;            // never move head itself
    while (cur != null) {       // null is the stop sign
        System.out.println(cur.data);
        cur = cur.next;
    }
}

// 3. add to the end -- O(n), you must walk to the last node
public void addLast(int v) {
    Node n = new Node(v);
    if (head == null) { head = n; return; }   // empty-list case FIRST
    Node cur = head;
    while (cur.next != null) {  // stop ON the last node, not past it
        cur = cur.next;
    }
    cur.next = n;
}
Array / ArrayListLinked list
Get the i-th iteminstant — arr[i]walk i nodes
Insert at the frontshift everything rightinstant
Growcopy to a bigger arrayjust make a node
Memory per itemthe valuethe value + a reference
Trap

Write n.next = head; before head = n;. Reverse those two lines and the new node points at itself — every other node becomes unreachable and the whole list is garbage collected.

Walk with cur.next != null when you need the last node, and cur != null when you need to visit every node. Using the wrong one is either a NullPointerException or an off-by-one.

22

Searching & Sorting

Week 5 · 12–13bubble · selection · insertion · linear vs binary searchhigh-yield

Every sort in this course is the same two moves — compare a pair, then swap or shift — and the only thing that differs is which pair you look at next.

🃏

Shop floorSorting a hand of cards. Bubble keeps sweeping left to right swapping neighbours until a whole sweep changes nothing — the biggest card "bubbles" to the end each pass. Selection scans for the smallest card and puts it in slot 0, then the next smallest in slot 1. Insertion is how people actually do it: pick up the next card and slide it back into place among the ones already sorted.

Compare, Then Swap
drag to orbit
the three sorts, written the way they are graded
// BUBBLE -- sweep, swapping neighbours, until a clean pass
public static void bubbleSort(int[] a) {
    boolean swapped = true;
    while (swapped) {
        swapped = false;
        for (int i = 0; i < a.length - 1; i++) {     // note length - 1
            if (a[i] > a[i + 1]) {
                int t = a[i]; a[i] = a[i + 1]; a[i + 1] = t;
                swapped = true;
            }
        }
    }
}

// SELECTION -- find the smallest remaining, put it in place
public static void selectionSort(int[] a) {
    for (int i = 0; i < a.length - 1; i++) {
        int min = i;
        for (int j = i + 1; j < a.length; j++) {
            if (a[j] < a[min]) min = j;
        }
        int t = a[i]; a[i] = a[min]; a[min] = t;      // one swap per pass
    }
}

// INSERTION -- slide each card back into the sorted part
public static void insertionSort(int[] a) {
    for (int i = 1; i < a.length; i++) {             // starts at 1, not 0
        int key = a[i], j = i - 1;
        while (j >= 0 && a[j] > key) {               // j >= 0 FIRST, or you fall off
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = key;
    }
}
searching
// LINEAR -- works on ANY array. O(n).
public static int linearSearch(int[] a, int target) {
    for (int i = 0; i < a.length; i++) {
        if (a[i] == target) return i;
    }
    return -1;                       // the standard "not found" answer
}

// BINARY -- only valid on a SORTED array. O(log n).
public static int binarySearch(int[] a, int target) {
    int lo = 0, hi = a.length - 1;
    while (lo <= hi) {               // <= , not < : the last window is one element
        int mid = (lo + hi) / 2;
        if (a[mid] == target) return mid;
        else if (a[mid] < target) lo = mid + 1;
        else hi = mid - 1;
    }
    return -1;
}
AlgorithmCostWhat it needsSwaps
BubbleO(n²)nothingmany
SelectionO(n²)nothingexactly n−1
InsertionO(n²), fast when nearly sortednothingshifts, not swaps
Linear searchO(n)nothing
Binary searchO(log n)a sorted array
Trap

Binary search on an unsorted array does not throw — it quietly returns a wrong answer. Arrays.binarySearch(new int[]{4,1,3}, 3) returns 2 on a JDK 26 run, which happens to look plausible and is meaningless. Sort first, always.

Insertion's inner test must be j >= 0 && a[j] > key in that order. Flip it and you read a[-1] before the bounds check and crash.

The Test Out

75 questions · 2 hours · 85% to pass

The proficiency exam is a different animal from the course exams — pure multiple choice, no partial credit, and you may miss only 11 of 75.

75questions
120minutes
96sper question
64to pass · 85%
11misses allowed
1attempt, ever
~10%pass rate
You write a Java program. This is the official word.

Purdue CS states it directly on the proficiency exam page:

“The exam is a combination of multiple choice questions and writing a Java program. It is based on CS 18000 final exams.”

A Fall 2025 first-hand report (below) describes that sitting as pure multiple choice, 75 questions. One student, one sitting — worth reading, but it does not outrank the department's own page. The asymmetry decides it: preparing for a program you never face costs you nothing; meeting one you never practised burns your single attempt.

“Based on CS 18000 final exams” is a measurable pointer. The Final is 4 programming questions worth 110 of its 200 points — more than half. Weight your prep accordingly: Written Practice and the programming questions are the main event, not the supplement.

Stakes

One attempt, ever — roughly a 10% pass rate, and it is a waiver, not credit: CS majors still make up the hours with an additional 300-level course. The value is sequencing — it unlocks the CS 180 → 182 → 240 → 250 → 251 chain a full semester early.

It runs the week before or the first week of classes, your advisor must release the Qualtrics request form, and anyone already enrolled in CS 18000 past Week 4 is ineligible.

Source: a first-hand write-up by someone who sat and passed it in Fall 2025 (the CS 180 test-out guide), building on Optimizing Purdue CS. That is one sitting, reported by one student — the format can change, so confirm before you commit. Past papers: cs.purdue.edu/homes/cs180/exams.html.

Also on that page, worth knowing before you commit: one attempt only — fail it and you take CS 18000 for credit. A W in CS 18000 still leaves you eligible. And if you are CODOing into CS, Data Science or AI, passing the proficiency exam does not satisfy the “grade of at least a B in CS 18000 at Purdue” requirement — the waiver and the CODO requirement are different things.
Their read on the split: about two thirds is straightforward if you genuinely know Java, and the other third decides it — obscure language features and deliberately misleading code. With an 85% bar, you cannot pass on the easy two thirds alone. Every module below marked high-yield is on their list.
What they said to knowWhere it is here
Threads and synchronized18 · Threads
Networking19 · Network I/O
GUIs, and Swing layouts (border / flow / grid)20 · GUIs & Events
switch without break falls through05 · Conditionals
Checked vs unchecked, throws, extraneous throws14 · Exceptions
Interfaces vs abstract classes13 · Interfaces & Abstract
length vs size(); negative indices; array init syntax07 · Arrays · 17 · ArrayList
Overloading09 · Methods
Bitwise operations03 · Operators

Their four sample questions

Written by the author to resemble what they saw. I compiled and ran all four on JDK 26 — three match, and one published answer is wrong. That one is the most instructive question here, so read its explanation even if you get it right.

Score: 0 / 4

Exam Simulator

75 questions · 2:00:00 on the clock · 85% to pass

Knowing the material and passing at 85% with 96 seconds a question are two different skills. This drills the second one.

This is the multiple-choice half only. Purdue's proficiency page says the exam also requires writing a Java program — for that, work Written Practice on paper and the programming questions. Do not let a good mock score here read as ready.

Question bank: questions. 64 are verbatim from Purdue's own archived CS 180 papers (Exam 1, Exam 2 and the Final, Fall 2008), graded against the official answer keys published alongside them (exam archive). The rest are written to cover what those 2008 papers barely touch but the test-out leans on — threads, networking, GUIs and bitwise — with every code-output answer compiled and run on JDK 26. Those papers are old: treat them as style and coverage, not as a promise about your sitting.

Written Practice

88 real exam questions · with Purdue's own solutions and marking rubrics

These are not my questions. Every one is lifted verbatim from a Purdue CS 180 paper, and most carry the marking rubric the graders actually used.

Source: the six Spring 2010 / Spring 2011 papers published "with solutions" in Purdue's exam archive (Prof. Chris Clifton). 88 questions, 262 points in total. Each card shows the paper, section number, the recommended time and the point value. Unlike the multiple-choice bank these could not be split reliably into question and answer, so they are reproduced whole — question, official solution, and where present the Scoring: rubric. Read the question, cover the rest of the card, and write it out on paper before you scroll.

The rubric lines are the point of this section. They tell you exactly where marks come from — "1 for calling the constructor, 1 for the syntax, 1 for getting everything correct" — which is information no study guide can invent.
2 ptMethod Signatures and OverloadingExam 1 · Spring 2010 · 1 · 3 min
Given the following class:
public class BaseClass
{
  double add(int a, int b) { return a + b; }
  int add(int a, int b) { return a + b; } // I.
  double add(double a, double b) { return a + b; } // II.
  float add(int a, int b) { return a + b; } // III.
  int add(int a, int b, int c) { return a + b + c; } // IV.
  int add(double a, double b, double c) { return (int)(a + b + c); } // V.
}
Not all of the methods are acceptable - some are proper overloading of the add routine, but others are not
compatible and will result in an error. Which of I., II., III., IV., and V. must be removed for the above
class to compile and be usable.

    A III, V
    B IV, V
    C I, III
    D I, II, III
    E I, II, III, IV

The signature of a method is based on the name and the number and type of the parameters (but not the type
of the result). Two methods of the same name, but with different number or type of parameters, are different
methods (overloaded).
2 ptInheritanceExam 1 · Spring 2010 · 2 · 2 min
What is the output of the following code:

public class BaseClass
{
   public void TheMethod() { System.out.println("In base class"); }
}

public class ChildClass extends BaseClass
{
   public void TheMethod() { System.out.println("In child class"); }
}

public class Driver
{
   public static void main(String[] args)
   {
      BaseClass c = new ChildClass();
      c.TheMethod();
   }
}

    A In base class
    B In child class
    C In base class
      In child class
    D In child class
      In base class
    E "BaseClass c = new ChildClass();" will cause a compile error because the type is different.

The (non-static) method in the child class overrides the one in the parent class; any use of that instance uses
the method from the child class.
1 ptInheritance/interfacesExam 1 · Spring 2010 · 3 · 3 min
Which of the following is true:
    A A child class can access all public, protected and private variables and methods of the base class.

    B Let "Queue" be an interface, "Queue q = new Queue();" creates an instance of the Queue interface.
    C The "super" keyword is used to access variables and methods of the base class.
    D The "this" keyword can be used in a static method.
    E A static method cannot access an instance variable.
A static method can be called without an instance being created. In such case, accessing the instance variable
wouldn't make sense.

4      Primitive Types (1 minute, 1 point)
Which of the following is NOT a primitive type:
     A double
     B String
     C int
     D byte
     E All are primitive types.
A primitive type is held directly in the variable; it is small and of fixed size. Strings are variable size and
thus not primitive.
1 ptConcurrencyExam 1 · Spring 2010 · 5 · 2 min
To create and use a new thread in a program we:
     A Create a class that inherits from the Thread class.
     B Override the run() method of the Thread class.
     C Use the start() method to start the thread.
     D Use the join() method to wait for the thread to exit.
     E All of the above.
2 ptInterfacesExam 1 · Spring 2010 · 6 · 4 min
The following definition of an abstract "light switch" data type will be used for questions 6 and 7.
    interface LightSwitch {
     boolean ON = true;
     boolean OFF = false;

    void turnOn();       // Turn the light on.
    void turnOff();      // Turn the light off.
    boolean isOn();      // return ON if the light is on, OFF if it is off.
}
The following variables have also been declared:
    LightSwitch light;
    boolean status;
    At some later point in the code (after variables have been instantiated, some method calls have been
made, etc.), you see the following statements. Which one can you be certain will not work (will always cause
either a compile or run-time error):
     A light.turnOn();
     B if (status == light.ON) { System.out.println("status is ON."); }
     C light = new LightSwitch();
     D LightSwitch l = light;
It is not possible to create an instance of an interface - this wouldn't make sense, since it isn't implemented.

7        Implementing Interfaces (4 minutes, 3 points)
The following class is a special light switch that supports dimming the light; full on is intensity 1, off is
intensity 0.

class DimmerSwitch implements LightSwitch {
  double intensity = 0.0; // Invariant: 0.0 <= intensity <= 1.0

    public void dim(double intensity) {
      // If the given intensity is legal, set the intensity to the given value.
      if (0.0 <= intensity && intensity <= 1.0)
        this.intensity = intensity;
    }

    public void turnOn() { // Turn the light on.
      intensity = 1.0;
    }

    public boolean isOn() { // return ON if the light is on, OFF if it is off.
      if (intensity == 0) return OFF;
      else return ON;
    }
}

    The above code will not compile. This is because:
    A There is no constructor defined for the class.
    B The method dim is not part of the interface.
    C The method turnOff has not been defined.
    D The method turnOn is not needed, we could just use dim(0.).
    E This is a trick question, the code will compile.
To implement an interface, you must implement all of the methods included in the interface.
2 ptClass/Instance VariablesExam 1 · Spring 2010 · 8 · 3 min
Given the following code:
public class MyClass
{
   private int time = 1;

     public static void main(String[] args)
     {

     }
}
Which of the following code is correct to put in the main() method.

    A System.out.println(time);

    B System.out.println(MyClass.time);
    C MyClass inst = new MyClass();
      System.out.println(time);
    D MyClass inst = new MyClass();
      System.out.println(inst.time);
    E MyClass inst = new MyClass();
      System.out.println(MyClass.time);

Static functions cannot access instance variables. Instance variables don't exist until the instance is created.

Short Answer
Write your answers in the space provided.

9     Programming with Generics, Inheritance (16 minutes)
This builds on the Boolean Circuits class hierarchy we discussed in lecture. (Concurrent Programming
sections 7.1 and 7.4). Hint: If you think you need to look at the book to solve this, you are missing the point
of data abstraction. The only thing you need to know is the inheritance hierarchy:

                                                     Gate

                       UnaryOperator                             BinaryOperator

                            Not                          And                          Or

   A QuadOperator is like a BinaryOperator, but it takes four inputs. Four-input AND and OR gates can
be built (schematically) as follows:

                           Quad−Input AND gate                   Quad−Input OR gate
                      a                                      a

                      b                                      b

                                                     o                                     o

                      c                                      c

                      d                                      d

    A partial implementation of QuadOperator is:
class QuadOperator<T extends BinaryOperator> extends Gate {
  // Builds a four-input gate corresponding to the gate type T.

    T top, bottom, right;     // Upper, lower, and right gates as in preceding diagram.

    public QuadOperator () {
      super("Quad");
      // Additional code to instantiate top, bottom, right --
      // don't worry about how this is done.
      right.setOperand1(top);
      right.setOperand2(bottom);
    }

    public void setOperands(Gate a, Gate b, Gate c, Gate d) {
      top.setOperand1(a);
      // Code for the rest
    }

    public boolean getValue() {
      return right.getValue();
    }
}
    You will need to perform some operations involving QuadOperators. If you aren't sure, give your best
guess - there will be partial credit. Note that even if you get one part wrong, you can get the other parts
right.
    Hint: You really don't need to understand boolean circuits to answer these questions.
3 ptVariable DeclarationExam 1 · Spring 2010 · 9.1 · 3 min
Write the code to declare (e.g., int i; a variable qand that is a four-input AND gate, and a variable qor that
is a four-input OR gate.

QuadOperator<AND> qand;
QuadOperator<OR> qor;
  Scoring: 1 for QuadOperator, 1 for <AND> / <OR>, 1 for syntactically correct.
3 ptInstance CreationExam 1 · Spring 2010 · 9.2 · 3 min
Write the code to create an instance of a four-input AND gate and assign it to the variable qand.

qand = new QuadOperator<AND>();
   Scoring: 1 for calling constructor, 1 for <AND>, 1 for getting everything correct.
3 ptUse of an instanceExam 1 · Spring 2010 · 9.3 · 4 min
You are given four gates a, b, c, and d:
    Gate a,b,c,d;
    a = new // ... Assume a, b, c, and d have been instantiated, don't worry about how.

Write code that uses the four-input AND gate qand to compute a && b && c && d, and assign the result
to a boolean variable o. You should assume that the Gate, AND, and QuadOperator classes are completely
implemented and work properly.

qand.setOperands(a,b,c,d);
boolean o = qand.getValue();
   Scoring: 1 for calling setOperands, 1 for calling getValue, 1 for getting all details right (boolean o = , ...)

10      Fields and Inheritance (12 minutes)
Given the following code:
class Parent {                                              class Child extends Parent {
  private String s = "ParentString";                          private String s = "ChildString";

    public void printS () {                                     // Several methods implemented, but there is
      System.out.println(s);                                    // NO implementation of printS().
    }                                                       }

    // Several other method implemented as well.
}
2 ptInheritance and fieldsExam 1 · Spring 2010 · 10.1 · 3 min
Does the statement Parent p = new Child(); result in one string or two? Explain.
   Two. Instantiating a child class creates the fields (and enables methods) of both child and
parent classes. While methods can be overridden, fields are not.
   Scoring: One point for getting it right (two), one for explaining that this creates an instance that has
both parent and child fields. Possibly one point for the wrong answer but solid description of overriding.
2 ptInheritance and fieldsExam 1 · Spring 2010 · 10.2 · 3 min
What would be the output of the following? Explain what is happening.
    Parent p = new Child();
    p.printS();
    ParentString . Since the child class does not override the printS() method, this uses the
parent's printS() method. Since fields are not overridden, it uses the string s from the parent.
    Scoring: 1 for correct answer (ParentString), 1 for explanation either noting that fields are not overridden,
or (incorrectly) describing the mechanism of overriding.
3 ptField accessExam 1 · Spring 2010 · 10.3 · 3 min
Suppose that in a method in class Child, you would like to change the value of the String s in class Parent.
Either describe a way this could be done, or explain why it cannot be done.
   Since the field is is private, we can't use super.s to access the field. Instead, we would need
to call methods in Parent that would modify s (if such exist.)
   Scoring: 1 for (improper) use of super, 2 for noting that because is private, it can't be accessed directly,
2-3 for suggesting use of methods in Parent.
2 ptTypesExam 1 · Spring 2011 · 1 · 1 min
Which of the following is not a legal statement (or sequence of statements). Circle only one.
    A boolean b;
      b = true;
    B String s;
      s = true;
    C int i = 3;

    D String s = "3";
    E double f;
      f = 3;
    Only B is not legal - the boolean value true cannot be assigned to a String.
2 ptCalling a MethodExam 1 · Spring 2011 · 2.1 · 2 min
Assume you are calling it from another method in the same class. One of the following statements might
not compile; all the others do.
   Circle the one that might be incorrect.
    A if ( longerThan ("abc", 3) > 0 )
        System.out.println("The String abc is longer than 3");
    B System.out.println(longerThan(abc, 3));

    C int a = 2 * longerThan("abc", 2);

    D longerThan("a", 4);
   B is correct. If you showed evidence that you noticed the argument wasn't a String, then
any answer consistent with your answer to 2.2 is acceptable.
2 ptCalling a Method part 2Exam 1 · Spring 2011 · 2.2 · 2 min
Explain your answer to 2.1. For full credit, describe conditions under which it would compile.
    B will only compile if abc is declared as a variable of type String (String abc = "";)
    If you noted that longerThan takes a string, not a String, there are many other acceptable answers.
    Scoring: 1 point for showing evidence you knew why it might not compile, 1 for conditions under which
it would.
2 ptCalling a Method part 3Exam 1 · Spring 2011 · 2.3 · 3 min
Assume that you had a main method in the same class as the longerThan method. I claim that none of the
statements in question 2.1 could be used in the main method. Explain why.
    You cannot call a non-static method without having an object.
    Main is static, so it is not running in an object. Hence a call to longerThan would not have
an object.
    Again, if you noted that longerThan takes a string, not a String, there are many other acceptable answers.
2 ptCode ExecutionExam 1 · Spring 2011 · 3.1 · 3 min
What is the value of sum after executing the above code (circle only one)?
    A 0
    B 4

    C 5
    D 9
    E 10
2 ptProper Use of LoopsExam 1 · Spring 2011 · 3.2 · 2 min
The above for loop is a poor style for using a for loop. Explain why (briefly).
   The variable modified in the third part of the for should be the variable that is checked for
termination (1 point), the variable i should not be modified elsewhere (otherwise a while loop
would be more appropriate) (1 point), variables other than that used to check termination of
the loop should not be modified in the for statement (1 point), and the variable modified in the
for statement should not be used after the loop (1 point).
3 ptBetter StyleExam 1 · Spring 2011 · 3.3 · 3 min
Rewrite the above loop (you may use a for, while, or do-while) in a better style. sum should have the same
value when the loop is complete as the above code.

sum = 0;
int i = 0;
while ( i < 10 ) {
  i = i + 2;
  sum++;
}

    or

sum = 0;
for ( int i = 0; i < 10; i = i + 2)
  sum++;

   Scoring: One point for having the same outcome using a loop to increment sum; one point each for
correcting style errors mentioned part 3.2.

4        Data Abstraction (2 minutes)
Which of the following statements are true regarding interfaces and data abstraction (circle all that are
true)? You will receive one point for each correct answer circled, and lose one point for each incorrect answer
circled.
    A An interface can define the body of the functions within it.

    B An interface can be used to provide an abstraction of some functionality.
    C Defining a class which describes the attributes and behavior of a student is an example
      of data abstraction.
    D Data abstraction requires an interface to be designed and implemented.

5        Classes and Interfaces (5 minutes)
Consider the following interface and class signatures:
public interface I                                           public class A implements J
{                                                            {
  public void f();                                             //
  public void g();                                           }
}
                                                             public class B implements I
public interface J                                           {
{                                                              //
  public void p();                                           }
  public void q();
}
2 ptShort Answer: Implementing an InterfaceExam 1 · Spring 2011 · 5.1 · 2 min
Minimally, how many methods must be written inside class A? Name the methods.
   2 methods (1 point), p and q (1 point).

5.2    Multiple Choice: Creating Objects with Classes and Interfaces (2 minutes)
Which of the following declaration, object instantiation, and assignments are valid. (Circle all that are legal;
you get one point for each correct, and lose one point for each wrong one.)
    A I i = new I();
    B I i = new B();
    C J j = new A();
    D A a = new J();
    E B b = new B();
    B, C, and E are correct.
16 ptChess ProgramExam 1 · Spring 2011 · 6 · 25 min
For the next few questions, you will work with the following program that
simulates a chess board. You don't have to know how to play chess to do
this (and if you do, forget what you know, as our chess will have simplified
rules.)
A chessboard has rows and columns. The columns are named with letters.
(e.g., 'a' or 'b'). The rows are numbered starting with 1.

public interface ChessPiece
{

    boolean move(char toColumn, int toRow);
      /* If toColumn and toRow is a legal place
       * for this piece to move to, move it there
       * and return true. Otherwise don't move,
       * and return false. */

    void showPosition();
      // Print the current position on System.out
}

public class Pawn implements ChessPiece
{
  private char atColumn;
  private int atRow;

    public Pawn(char startingColumn)
    {
      atRow = 2; // Pawns always start in row 2.
      atColumn = startingColumn;
    }

    public void showPosition()
    {
      System.out.println("Pawn is at " + atColumn + atRow);
    }
}

public class PlayChess
{
  public static void main( String args[] )
  {
    ChessPiece qp = new Pawn('d');
    if ( qp.move('d', 3) )
      System.out.println("You made a legal move");
    else
      System.out.println("Bad move");
    // Done
  }
}
2 ptMultiple Choice: CompilationExam 1 · Spring 2011 · 6.1 · 2 min
When you try to compile the above code, it gives the following error:
  A variable qp might not have been initialized
   B incompatible types. found: int, required: boolean
  C Pawn is not abstract and does not override abstract method

  D move(char,int) in ChessPiece cannot be applied to (int,int)
   E cannot find symbol : constructor Pawn(char,int)
   All are plausible errors, but only C occurs in the given code. For example, the constructor "Pawn(char,int)"
doesn't exist, but since nobody tries to call such a constructor, it doesn't matter.
   A: 1; B, C: 0
2 ptMultiple Choice: ObjectsExam 1 · Spring 2011 · 6.2 · 2 min
Assume the error in Question 6.1 has been fixed, and the program compiles and runs without errors. When
the program reaches the line "// Done" in the main method, what objects are there in the system?

  A No objects have been created.

   B 1: a ChessPiece object.
  C 1: a Pawn object.
  D 2: a ChessPiece object and a Pawn object.
   E 3: a ChessPiece object, a PlayChess object, and a Pawn object.

   ChessPiece is an interface, you can't create an object for an interface.
3 ptShort Answer: Using InterfacesExam 1 · Spring 2011 · 6.3 · 3 min
Assume that I have written a Knight class that implements the ChessPiece interface. I have also created a
knight object kk. Write a statement that will move the object kk to column f row 3. Hint: You do not write
any code that goes in the Knight class - that is already written, and you just have to use it. For full credit,
you should also check if this was a legal move and print a message if it was not.
   if (! kk.move('f ',3) ) System.out.println("Not a legal move.");
   Scoring: 1 for using the kk object, 1 for correct arguments, 1 for checking result.
9 ptCode: Implementing InterfacesExam 1 · Spring 2011 · 6.4 · 10 min
The Pawn class does not have the move method that is required by the ChessPiece interface. Write that
method. Assume that a pawn only moves one space forward at a time; that is, it always stays in the same
column, and moves to the next row (e.g., if a pawn is at column d row 2, it can only move to column d row
3 ; an attempt to move it anywhere else is not allowed.) Everything else you need to know is contained in
the code above.

  public boolean move(char toColumn, int toRow)
  {
    if ( toColumn == atColumn && toRow == atRow + 1 ) {
      atRow = toRow;
      return true;
    }
    else
      return false;
  }

    Scoring: 1 for a "move" method, 1 for public, 1 for correct return type, 1 for correct arguments, 1 for
check on column, 1 for check on row, 1 for returning boolean, 1 for updating row, 1 for logically correct.
    A common error was to use "toColumn.equals(atColumn)". Since a char is a primitive type, and not an
object, you cannot call a method on it.
2 ptExceptions and InheritanceExam 2 · Spring 2010 · 1 · 5 min
Assume we have defined the following exceptions:

public class AException extends Exception { }
public class BException extends AException { }
public class CException extends BException { }
and we use them in the following program:
public static void main(String[] args)                   static void FuncA(boolean x) throws AException
{                                                        {
  try {                                                    try {
    FuncA(true);                                             if ( x ) throw new CException();
    System.out.print("1");                                   System.out.print("4");
  }                                                        } catch(BException ex) {
  catch(AException ex) {                                     System.out.print("5");
    System.out.print("2");                                   throw new AException();
  }                                                        } catch(AException ex) {
                                                             System.out.print("6");
    System.out.print("3");                                 }
}
                                                             System.out.print("7");
                                                         }
    What should the output of the program be?
    A 413

    B 523
    C 5673
    D 54213
    E 564713
Remember that after an exception is thrown, the first matching catch is executed. Once that block is done,
processing continues outside the try/catch context - it never returns to the try block.

2     Constructing Windows (3 minutes, 2 points)
When constructing a window using a JFrame, you add objects to a JPanel. Which two of the following are
true statements (you get one point for each true statement you mark, but lose a point for each false statement
you mark):
    A Each object added must be a different class.
    B Multiple components in a window can share the same instance implementing ActionLis-
      tener.

    C You must create an instance of a component before adding it to the JPanel.
    D Each object added must have its own event handler (ActionListener).
    E There can only be one instance of an object for each class that implements the ActionListener interface.
1 ptThreadsExam 2 · Spring 2010 · 3 · 2 min
Which of the following statements about programming with threads is true?
    A After a call to start() a thread, the next statement must be a call to join() that thread or the thread
      will not execute.
    B Threads can only be used on multiprocessor machines.
    C Different threads can call methods of the same object at the same time.
    D Once a program starts a thread, it cannot do anything else until that thread has finished running.
2 ptSynchronizationExam 2 · Spring 2010 · 4 · 4 min
Given the following code:
public class Vertical {

    private int alt;

    public synchronized void up() {
      ++alt;
    }

    public void down() {
      --alt;
    }

    public synchronized void jump() {
      up();
      down();
    }
}
    Which two of the following are correct (you get one point for each one you get right, but you lose a point
for each incorrect one you mark):

    A The code will fail to compile.
    B Separate threads can execute the up() method concurrently on the same object.
    C Separate threads can execute the down() method concurrently on the same object.
    D One thread can execute up() on an object concurrently with another executing down()
      on the same object.
    E Two threads can both execute up() at the same time on the same object, both execute down() at the
      same time on the same object, and one can execute up() while the other executes down() on the same
      object.

Registration System
Questions 5 through 9 concern a hypothetical "registration kiosk": A computer with multiple screens and
keyboards. Each screen starts up with a "Register for CS18000" window:

When a student walks up and clicks "Register for CS18000", the program brings up an "Enter name" window:

When the student clicks "OK", the registration is complete. This means that an instance of class Student
has been created, and the number of students registered (the class variable totalStudents in class Student)
has been updated.
    If a student walks up to the kiosk and clicks "Register for CS18000", but the class is full (totalStudents
≥ MAXSTUDENTS), the student instead sees a "Class full" message.
    Code fragments covering the following questions are given at the end of the test (Appendix A). However,
you should read the questions first. The questions concern basic design principles of graphical user interfaces
and concurrent systems; you may be able to answer them without looking at the code at the end of the test.
It is best if you read the question and answer choices first, then if you are unsure, look at the code.
1 ptEvent handlingExam 2 · Spring 2010 · 5 · 5 min
When we run the program, the "Register for CS18000' window pops up on each screen (we see the button
shown above), but when users click on "Register for CS18000" nothing happens. Which of the following is
a likely fix for the problem?

    A Create an instance of Student for each kiosk screen.
    B Call the RegisterAction.actionPerformed() method.
    C Add the RegisterAction listener to the "Register for CS18000" button.

    D Add a try/catch block with "join" statements at the end of the main method, as the program now
      ends as soon as the screens are set up.                     Name:                            4
    E Add the "Register for CS18000" button to a JPanel.
1 ptConcurrencyExam 2 · Spring 2010 · 6 · 3 min
Assume we have fixed the preceding problem. We now get all the screens set up properly, and if one person
walks up and registers, it works. But if a second person clicks "Register for CS18000" while the first person
is registering, nothing happens until the first student clicks "OK". This is happening because:

    A ActionListeners are not concurrent; the next action is not performed until the previous
      action has completed.
    B The class variable totalStudents is shared by all Student instances, so once one starts, no other can
      run.
    C Even though we have multiple screens, there is only one processor, so it isn't possible for the program
      to handle inputs from two users.
    D The JFrames have to be used in the same order they were created in the main method.
    E The try-catch block in actionPerformed only allows one thread to execute at one time.
2 ptThreadsExam 2 · Spring 2010 · 7 · 4 min
Realizing we need concurrency, we make class Student extend class Thread. This requires we implement a
run method; since the other methods already do everything we need, we simply make it:
    public void run() { return; }
    We then rewrite the event handler for the "Register for CS18000" button (method actionPerformed() )
to include:
    Student s = new Student(screen);
    s.start();
    try { s.join(); }
    catch ( InterruptedException ie ) { }
    // Save s into appropriate variables
Running this gives the same behavior as before - nothing seems to have changed. In hindsight, we realize
this couldn't have worked because:

    A It won't compile, we haven't defined a start() and join() method for Student.
    B The only thing executed concurrently is the run() method; the hangup is in the construc-
      tor for Student.
    C When another user clicks a button, it causes an InterruptedException; we need to create a new Student
      in the catch block.
    D The only place we can start a new thread is in the main method.
8     Managing Concurrency (5 minutes, 2 points)
                                                                   Name:                               5
We manage to fix all of the above problems - we now have multiple threads running so that several people
can use the kiosk at once, and all get a quick response. Unfortunately, we seem to be ending up with too
many students in class (i.e., we end up with totalStudents > MAXSTUDENTS.) This is because:
    A After we throw the ClassFull exception, we continue to register the student. We need to put a return
      after the throw.
    B Each thread has its own copy of totalStudents, so each can have MAXSTUDENTS.

    C The value of totalStudents is initialized to 0 every time we create a new instance of Student, so
      totalStudents is always 0 when it is checked.
    D We have a race condition: The check if there is room happens before we update the
      number of students, and this can happen concurrently.

Short Answer
Write your answers in the space provided. The space provided should be sufficient, but if you need more,
use the back of the sheet.
5 ptSynchronizationExam 2 · Spring 2010 · 9 · 12 min
If you are unsure about your answer to Question 8, you should make sure you have done
everything else before you do this one. We fix the "too many students" problem of the preceding
question with a simple (one word) change to class Student. However, in doing this fix we lose concurrency:
only one person is able to register at a time.

Part 1 (1 point): What did we do to fix the problem? Make Student a synchronized method. Technically
this isn't possible in Java 1.5, as Constructors can't be synchronized - there were other acceptable answers,
as long as you got across the point that the entire method was synchronized.

Part 2 (4 points): Rewrite the Student method to fix this. (It is okay if you don't rewrite everything, as
long as it is quite clear what your solution does.)
   One solution:
synchronized(totalStudents) {
  if ( totalStudents >= MAXSTUDENTS ) throw new ClassFull();
  else totalStudents++; // Reserve a place for us before unsynchronizing.
}
  name = JOptionPane.showInputDialog(
//... as before.
  if ( name == null ) { // User pressed cancel button
    synchronized(totalStudents) {
      totalStudents--; // Free up the space we reserved.
    }
    throw new StudentCancelled();
  }
Scoring: 1 point for synchronizing check on totalStudents, 1 for synchronize on a class variable (totalStudents
or other), 1 point for moving check and update together, 1 point for making sure that totalStudents isn't
increased if the student cancels / class is full. Alternate credit for pointing out that this wouldn't solve the
problem, since the handler still isn't concurrent: 2 for pointing out the problem, 1 for a reasonable start at
a fix, 1 for noting need for synchronization, up to a total of five points.
2 ptException processingExam 2 · Spring 2010 · 10 · 4 min
The following code will fail to compile. You can assume that all methods and variables in this fragment are
properly defined; the error is entirely in the code block below.
int i;
try {
  i = divide(a, b); // May throw a DivideByZeroException
} catch (DivideByZeroException dbz) {
  System.err.println("Divide by zero attempted.");
}
System.out.println(i);
Explain briefly why it fails (1 point) and a way to fix it (1 point).
    If divide throws an exception, then the System.out.println(i) would have i uninitialized. The compiler will
not allow this to happen. The solution is to move the System.out.println(i) into the try block.
    Initializing i is not a good solution. While it fixes the compile error, it means that dividing a number by
0 gives a valid output - a logical error in the program.
9 ptInheritanceExam 2 · Spring 2011 · 1 · 8 min
Given the following classes:

class Person {
  public Person() {
    System.out.println("Person constructor");
  }

    public void showClassName() {
      System.out.println("Person");
    }

    public void printSomething() {
      System.out.println("In printSomething");
    }
}

class Employee extends Person {
  public Employee() {
    this("Calling this");
    System.out.println("Employee constructor");
  }

    public Employee(String s) {
      System.out.println(s);
    }

    public void showClassName() {
      System.out.println("Employee");
    }
}

    For each of the following statements, show the output. Assume the statements are executed in the order
given (note that you should be able to figure out the later ones even if you aren't sure about the earlier
ones.)
    Scoring: 1 point each

Person p1 = new Person();

    Person constructor

p1.showClassName();

    Person

Employee e1 = new Employee();

    Person constructor
    Calling this
    Employee constructor

e1.showClassName();

    Employee

e1.printSomething();

    In printSomething

p1 = e1;

    Nothing (one point for stating "nothing" or for leaving it blank.)

p1.showClassName();

    Employee

Person e2 = new Employee("e2");

    Person constructor
    e2

e2.showClassName();

    Employee
2 ptGenericsExam 2 · Spring 2011 · 2 · 4 min
Given a Set class (partially shown below):

public class Set<E> {
  // Fields and other methods here...
  void insert(E value) {
    // Code to do insert here
  }
}

Using the Person and Employee classes from question 1, we do the following:

Set<Person> ps = new Set<Person>();
Employee e1 = new Employee();
ps.insert(e1);

Is the last statement ( ps.insert(e1); ) legal? (that is, will it compile and run?) Briefly explain your
answer. You may assume that Set is implemented correctly and that the first two statements compile and
run.
    Yes, it will. since e1 is an Employee, and Employee extends Person, e1 can be used anyplace
a Person object is needed. Since ps is a set of Person, e1 can be inserted into the set.
    Scoring: 1 point for "yes", 1 for showing understanding of inheritance.
2 ptRecursionExam 2 · Spring 2011 · 3 · 4 min
Given the following class:
public class Recurse
{
  public static int fun(int n)
  {
    if (n <= 1)
      return 1;
    else
      return fun(n - 1) + n ;
  }
}
What is returned by Recurse.fun(3) ?
  Scoring: (2 points)
5 ptExceptionsExam 2 · Spring 2011 · 4 · 5 min
The sqrt function in the java Math class takes a double value as an argument, and returns the special double
value "NaN" (Not a Number) if the argument is negative. We'd like to instead use a NegativeSqrtException
exception to handle this case:
public class NegativeSqrtException extends Exception
{
}
    Without using exceptions, your function looks like:
public static double mySqrt(double n)
{
  return Math.sqrt(n);
}
2 ptProper use of exceptionsExam 2 · Spring 2011 · 4.1 · 3 min
Should the NegativeSqrtException be thrown by mySqrt, or should mySqrt contain a try/catch block?
Explain.
    As a "library method", it's better to throw the exception to notify the caller of the method
that he has supplied an illegal argument. Try/catching would be forced to return an ambiguous
value (probably an arbitrary negative number) which still has to be interpreted.
    Scoring: 1 point for correct answer, 1 point for explanation. If explanation was unclear, looked to answer
to question 4.2 for clarification.
3 ptWriting the codeExam 2 · Spring 2011 · 4.2 · 2 min
Write the mySqrt function that makes proper use of the NegativeSqrtException.
   Solution:
public static double mySqrt(double n) throws NegativeSqrtException
{
    if (n < 0)
        throw new NegativeSqrtException();
    return Math.sqrt(n);
}

    Scoring: -1 if the method signature does not contain "throws". -2 if the "conditional + throw" is incorrect.
If previous section was incorrect, combined partial credit was given based on overall validity of the answer.
2 ptArray vs. Linked ListExam 2 · Spring 2011 · 5.1 · 4 min
An instructor using this class should have the ability to add students (when they sign up for the class) and
remove students (if they drop the course) as necessary. Should the gradebook hold the collection of students
using an array-based implementation or a linked list implementation? Justify your choice.
    Either is acceptable. If you assume all students are added to the book at once and
there is minimal students dropping the course, then an array-based implementation (e.g.,
java.util.Vector) may be preferred for easy indexing and fast iteration. If you assume the
size of the gradebook is very fluid, then a linked list implementation may be preferred for
fast addition/subtraction from the gradebook. It is not correct to say that the linked list
implementation is resizable and the array is not (it is only easier to be resized).
    Scoring: 1 point for making a choice or saying either, 1 point for a justification that correctly supports
the answer given.
3 ptSuperclasses/SubclassesExam 2 · Spring 2011 · 5.2 · 4 min
All students must be either an UndergradStudent or GradStudent; we would never actually create an object
that was just a Student. However, we do need a Student class, since this is what the gradebook holds;
UndergradStudent and GradStudent will be subclasses of Student.
    Note that while undergrads and grad students have much in common, there are some differences. For
example, a GradStudent should have a "thesisTitle" field; and UnderGrad should have a "classYear". How-
ever, both have common attributes and methods such as "transcript", "addCourseGrade()", and "com-
puteGPA()".
    Should the Student class be (choose one):
    A an Interface,
    B an Abstract class, or
    C a regular class .
   Briefly justify your answer
   Student should be an abstract superclass. There's no point in a Student object being made,
so it should be abstract. Student should be a class instead of an interface in order to declare
similar fields and accessors/mutators which can be inherited.
   Scoring: 0 points for interface, 1 point for regular class and noting that this allows you to share common
methods, 3 points for saying abstract class and noting that this allows you share common methods (we
assumed by selecting abstract class that you understand an instantiation won't be possible.
11 ptLinked Data StructuresExam 2 · Spring 2011 · 6 · 20 min
class OrderedList {
  private int value;
  private OrderedList next;
  // Invariant: value < next's value. That is, !next.lessThan(value);

    public OrderedList(int data, OrderedList next) {

         value = data;
         this.next = next;
    }

    private boolean lessThan (int val) {
      // True if val < my value
      // Note that another object of the same class may use an object's private method.
      if (val < value) return true;
      else return false;
    }

    public void insert(int val) {
      // Put val at it's proper place in the list
            /* Line A (for parts 3 and 4) */
      if ( next.lessThan(val) ) {
            /* Line B (for parts 3 and 4) */
        OrderedList temp = new OrderedList(val, next);
        next = temp;
      } else {
            /* Line C (for parts 3 and 4) */
        next.insert(val);
            /* Line D (for parts 3 and 4) */
      }
            /* Line E (for parts 3 and 4) */
    }
}
5 ptSuccessful InsertExam 2 · Spring 2011 · 6.1 · 2 min
Assume OrderedList ol; is the following list:

             ol

                        −22             −7               7                17               42
Show what the above list will look like after running the statement:
  ol.insert(4);
   Solution:

    ol

                  −22          −7                4                7               17               42
   Scoring: Minus one point for each of not having a new node, not having 4, not correctly pointing to the
next node, not correctly pointing the previous to the next, not having ol pointing to the right place, and not
null-terminating the list. But at least one point for having one of these things right.
2 ptFailed InsertExam 2 · Spring 2011 · 6.2 · 3 min
If you do an ol.insert(78); the code will fail to do what it should. This is because:

     A There is no base case for val > value.

   B There is no base case for next == null.

   C There is no recursive case for val > value.

  D There is no recursive case for next == null.

   Scoring: 1 point for A or D, 2 points for B.
2 ptCorrecting insert of large itemsExam 2 · Spring 2011 · 6.3 · 5 min
Fix the code so that an insert of a large item (e.g., ol.insert(78); will work correctly. You can do this by
writing two or three lines of code that go at A, B, C, D, or E above - just give the code and state where it
goes. (You can also fix it by changing one line of the code - either answer is acceptable.)
   One solution (at A):

if ( next == null )
  next = new OrderedList(val, null);
else

    Scoring: One point for null check, one for creating new node. Putting this at a location other than A
will result in a null pointer exception in the first if ( next.lessThan(val) ), although you still received credit
as long as everything else was right.
    Another common answer was to replace the if with if ( next == null || next.lessThan(val) ) {
. This is correct. If you put them the other way around, it would try next.lessThan(val) before checking
if next==null, resulting in a null pointer exception (again, you still received full credit for getting this the
wrong way, but you should remember that the order matters.)
2 ptRemaining problemExam 2 · Spring 2011 · 6.4 · 5 min
Insert will still fail to work properly in some cases. Explain briefly or give an example where it fails (1 point)
and provide code to fix the problem (1 point).
   If an item belongs at the beginning of the list (e.g., ol.insert(-30)), it will instead be placed
after the first item. (1 point) This will result in an out-of-order list.
   Fixing this is a bit tricky, as we can't change the node ol points to. Instead, we have to
change the value in that node. Put the following at line A, at the beginning.

if ( lessThan(val) ) { // If the new value goes in front of me,
  next = new OrderedList(value, next); // put my value in a new node,
  value = val; // And put the new value in me.
} else

1 point. Minor mistakes allowed, as long as you have it basically correct.

6.5    Non-Bonus question (0 points)
I claim the OrderedList class, even after fixing the insert method, is useless. Why? This won't count for
anything - don't answer this unless you are done with the exam and want to show off...
    Since we can't see what is in the list, or even check if an item is there, it won't have any
value. The only public method or field is insert, which doesn't return a value or change the
value of its arguments, so no matter what it does, we don't see anything. Assuming, of course,
you've fixed things so it doesn't end up giving a null pointer exception.
2 ptConstructors and InheritanceFinal · Spring 2010 · 1 · 4 min
Given the following classes:
class A {                                           class C extends B {
  public A() {                                        public C() {
    System.out.print("1");                              System.out.print("3");
  }                                                   }
}                                                   }

class B extends A {                                 public class TestOne{
  public B() {                                        public static void main(String args[]){
    System.out.print("2");                              C c = new C();
  }                                                   }
}                                                   }
   What is the result when TestOne is executed?
    A 3
    B 1
    C 321
    D 123
2 ptInheritance and overridingFinal · Spring 2010 · 2 · 5 min
Given the following code:
public class SimpleCalc {
  public int value = 0;
  public void calculate() { value += 7; }
}

public class MultiCalc extends SimpleCalc {
  public int value = 0;

    public void calculate(){ value = value - 3; }

    public void calculate(int multiplier) {
      calculate();
      super.calculate();
      value = value * multiplier;
    }

    public static void main(String args[]) {
      MultiCalc calculator = new MultiCalc();
      calculator.calculate(2);
      System.out.println("Value is: " + calculator.value);
    }
}
    What is the result when the above is run (that is, the main method is called)?
    A Compilation fails
    B Value is: -6
    C Value is: 12
    D Value is: -12
    E The code runs with no output
3 ptThreadsFinal · Spring 2010 · 3 · 4 min
public class TestOne implements Runnable {
  public static void main(String args[]) throws Exception {
    Thread t = new Thread(new TestOne());
    t.start();
    System.out.print("Started");
    t.join();
    System.out.print("Complete");
  }

    public void run() {
      for(int i = 0; i < 4; i++){
        System.out.print(i);
      }
    }
}

Given the above code, which of the following is a possible result?
    A Compilation fails
    B An exception is thrown at runtime
    C The code executes and prints "StartedComplete"
    D The code executes and prints "StartedComplete0123"
    E The code executes and prints "Started0123Complete"

4     Overloading / signatures (4 minutes, 1 point)
Which of the following would overload this method:
double add(int a, int b) { return a + b; }

I.   int add(int a, int b) { return a + b; }
II. double add(double a, double b) { return a + b; }
III. int add(double a, double b) { return (int)(a + b); }
IV. double add(int a, int b) { return a + b; } in a child class.
V.   int add(int a, int b) { return a + b; } in a child class.

    A I, II
    B I, III
    C II, III
    D IV, V

    E IV only
2 ptArraysFinal · Spring 2010 · 5 · 6 min
What is the output of the following program:
public class MyProgram2 {
  public static int id;
  public MyProgram2(int d) {
    id = d;
  }

    public int getID() {
      return id;
    }

    public static void main(String[] args) {
      MyProgram2[] prog = new MyProgram2[5];
      for(int i = 0; i < prog.length; i++) prog[i] = new MyProgram2(i);
      for(int i = 0; i < prog.length; i++) System.out.print(prog[i].getID());
    }
}

    A 01234
    B 55555
    C 44444
    D 43210
    E 00000

6       Arrays vs. Linked Lists (3 minutes, 2 points)
Which of the following operations would be faster with an array than with a linked-list data structure:
    A Adding an element in between existing elements.
    B Changing the value of the first element.
    C Getting the value of an element in the middle.
    D Removing an element from the middle.
    E None of these would be faster using arrays.
1 ptLayout ManagersFinal · Spring 2010 · 7 · 5 min
Which of the following will create the Window shown above?

    A     setLayout(new FlowLayout());
          add(new JLabel("a"));
          add(new JLabel("b"));
          JPanel j = new JPanel();
          j.setLayout(new GridLayout(2,2));
          j.add(new JLabel("c"));
          j.add(new JLabel("d"));
          j.add(new JLabel("e"));
          add(j);
    B The following is the correct answer. This was pretty easy for people who put a lot of
      extra work in Project 4 (for which they didn't get much credit.)

          setLayout(new GridLayout(2,4));
          add(new JLabel("a"));
          add(new JLabel("b"));
          add(new JLabel("c"));
          add(new JLabel("d"));
          add(new JLabel(""));
          add(new JLabel(""));
          add(new JLabel("e"));

    C     setLayout(new BorderLayout());
          JPanel i = new JPanel();
          i.add(new JLabel("a"));
          i.add(new JLabel("b"));
          JPanel j = new JPanel();
          j.setLayout(new GridLayout(2,2));
          j.add(new JLabel("c"));

            j.add(new JLabel("d"));
            j.add(new JLabel("e"));
            i.add(j);
            add(i, BorderLayout.CENTER);
    D Both A and C
    E A, B, and C would all create the window as shown.
2 ptExceptionsFinal · Spring 2010 · 8 · 3 min
Assume we have defined the following exceptions:
public class AException extends Exception {}
public class BException extends AException {}
public class CException extends BException {}
and we use them in the following program:
public static void main(String[] args)                static void FuncA(boolean x) throws Exception
{                                                     {
   try {                                                 try {
      FuncA(true);                                          if(x) throw new BException();
      System.out.print("1");                             }
   }                                                     catch(CException ex) {
   catch(AException ex) {                                   System.out.print("5");
      System.out.print("2");                                throw new AException();
   }                                                     }
   catch(Exception ex) {                                 System.out.print("6");
      System.out.print("3");                          }
   }
   System.out.print("4");
}
What should the output of the program be?
    A 24
    B 134
    C 524

    D 5124
    E None of the above.
1 ptUsing exceptionsFinal · Spring 2010 · 9 · 3 min
The exceptions in question 8 give no information other than the class of the exception. However, it is possible
to put more information in an exception. Which of the following would NOT be an appropriate use of an
exception carrying extra information:
    A To write a function that always returns two values (since "return" only lets us return
      one.)
    B To give a message about what caused an error.

  C When in an unusual situation, we want to return an item of a different type from the normal return.
  D When the object to be returned has a problem that prevents it from being used normally, but we still
    want to give it to the calling method.
3 ptRecursionFinal · Spring 2010 · 10 · 8 min
What does method recur do, when called as recur(x, x.length) ?
//Precondition: x is an array of n integers
public static int recur (int[] x, int n) {
  if (n == 1) return x[0];
  else {
    int t = recur(x, n - 1);
    if(x[n-1] > t) return x[n-1];
    else return t;
  }
}

  A It finds the largest value in x and leaves x unchanged.
  B It finds the smallest value in x and leaves x unchanged.
  C It sorts x in ascending order and returns the largest value in x.
  D It sorts x in descending order and returns the largest value in x.
  E It returns x[0] or x[n-1], whichever is larger.
2 ptRecursion basicsFinal · Spring 2010 · 11 · 2 min
A recursive program must have:
  A An Array to operate on.
  B At least one base case and at least one recursive case.
  C A Linked-List data structure to operate on.
  D A counter to decide how many times to recurse.
  E At least one for loop.
4 ptThreadsFinal · Spring 2010 · 12 · 15 min
class MyProgram extends Thread {
  static Object lock = new Object();
  int id;
  boolean pause;

  public MyProgram(int d) {
    this.id = d;
    this.pause = false;
  }

    public void setPause(boolean newPause) {
      this.pause = newPause;
    }

    public void run() {
      for(int i = 0; i < 4; i++) {
        synchronized(lock) {
          try {
            System.out.print(id);
            if(pause) lock.wait();
          } catch(InterruptedException ex) { }
        }
        sleep(500);
      }
    }

    public static void main(String[] args) {
      MyProgram[] prog = new MyProgram[3];
      for(int i = 0; i < prog.length; i++)
        (prog[i] = new MyProgram(i)).start();
      sleep(500);
      for(int i = 0; i < prog.length; i++)
        prog[i].setPause(true);
      System.out.print("@");
      synchronized(lock) {
        prog[0].setPause(false);
        lock.notifyAll();
      }
      try {
        for(int i = 0; i < prog.length; i++) prog[i].join();
      } catch(InterruptedException ex) {
        System.out.print("$");
      }
    }

    static void sleep(int time) {
      try {
        Thread.sleep(time);
      } catch(InterruptedException ex) {
        System.out.print("#");
      }
    }
}
Which of the following is a possible output of the above program
    A 0120@12020121
    B 02112@20100
    C 012012@012#012
    D 012#000$

  E 2012@01201201$
2 ptFailure to TerminateFinal · Spring 2010 · 13 · 5 min
When the code in Question 12 is run, it does produce output, but it never completes. This is because:
  A The for loop at the beginning of main() starts the first thread, then waits for it to finish and is unable
    to start the next.
  B When a thread executes lock.wait(), it is in the synchronized block on lock, and so main() cannot enter
    the synchronized block to run notifyAll().
  C When notifyAll() is called, threads other than prog[0] will call lock.wait() again.
  D When notifyAll() is called, it picks only one thread to leave the wait().
  E Trick question, the program will complete normally.
2 ptErrorsFinal · Spring 2010 · 14 · 5 min
Other than the problem in question 13, which of the following type of error would be most likely to occur
with the code of question 12?
  A Equivalence testing errors
  B Out-of-bounds errors
  C Scope errors
  D Precision errors

Doubly Linked List
Questions 15 through 18 make use of the following code:

public class DLLNode<E> {
  // Single node of a doubly-linked list.
  private DLLNode previous;
  private E value;
  private DLLNode next;

  public DLLNode(E value) {
    previous = null;
    this.value = value;
    next = null;
  }

  private DLLNode(DLLNode previous, E value, DLLNode next) {
    this.previous = previous;
    this.value = value;
    this.next = next;
  }

    public DLLNode insertBefore(E value) {
      DLLNode newNode = new DLLNode<E>(previous, value, this);
      previous = newNode;
      return newNode;
    }

    public DLLNode insertAfter(E value) {
      DLLNode newNode = new DLLNode<E>(this, value, next);
      next = newNode;
      return newNode;
    }

    public DLLNode deleteGetAfter() {
      if (previous != null) previous.next = next;
      if (next != null) next.previous = previous;
      return next;
    }

    public DLLNode deleteGetBefore() {
      if (previous != null) previous.next = next;
      if (next != null) next.previous = previous;
      return previous;
    }

    public E getValue() {
      return value;
    }
}

public class Stack<E> {
  DLLNode top = null;

    public void push(E value) {
      if (top == null) top = new DLLNode<E>(value);
      else top = top.insertBefore(value);
    }

    public E pop() throws NullPointerException {
      if (top == null) throw new NullPointerException();
      else {
        E result = (E)top.getValue();
        top = top.deleteGetAfter();
        return result;
      }
    }
}
and the following code fragment (assume that variables exam1-5 are declared and instantiated; i.e., they are
not null.)
    Stack<Exam> s = new Stack<Exam>();
    s.push(exam1);
    s.push(exam2);

  s.pop().gradeIt();
  s.push(exam3);                                                     Name:                                 10
  s.push(exam4);
  s.push(exam5);
  s.pop().gradeIt();
  s.pop().gradeIt();
3 ptStack OperationsFinal · Spring 2010 · 15 · 5 min
In what order will the exams be graded given the above code fragment? (I.e., the order calls to .gradeIt()
will occur)
  A exam1 exam2 exam3 exam4 exam5
   B exam5 exam4 exam3 exam2 exam1
  C exam1 exam2 exam3
  D exam2 exam4 exam3
   E exam2 exam5 exam4

Short Answer
Write your answers in the space provided. The space provided should be sufficient, but if you need more,
use the back of the sheet.
5 ptBox and Pointer DiagramsFinal · Spring 2010 · 16 · 5 min
Below find a box-and-pointer diagram for the state of the data structure after the first two lines of the code
fragment on page 9 (s has been created, s.push(exam1).) Complete the diagram showing the state of the
data structure after the end of the code fragment (after the final s.pop().gradeIt();).
   top

                prev     value   next

   exam1               (exam1)

   Added to the above diagram will be a second prev/value/next box, and an exam3 box. Top
will point to the box pointing to exam 3, next will point to the box pointing to exam1, prev
from that will point back to the exam 1.
     Scoring: 1 for exam3, 1 for exam3 only, 1 for pointer 1 to 3, 1 for pointer 3 to 1, 1 for appropriate
nulls
17      Stack Search (8 minutes, 4 points)
                                                                   Name:                                    11
We would like to be able to search the stack, i.e., we want a method for Stacks as follows:
boolean search(E item); // Return true if and only if item is in the stack
Please write such a method for the class Stack on page 9. Note that it should not make any changes to the
stack, only return true/false as appropriate.
    Solution code:
class SearchableStack<E> extends Stack<E> {

    public boolean search(E item) {
      return recursiveSearch(item, top)
    }
    private boolean recursiveSearch(E item, DLLNode position) {
      if (position == null) return false;
      else if (position.getValue().equals(item)) return true;
      else return recursiveSearch(item, position.getNext());
    }
}
     Scoring: 1 point for true if found, 1 for false if not found, 1 for getting termination right, 1 for false
if empty list, 1 for recursive solution, 1 point for noting difficulty given lack of access to previous/next in
DLLNode, 1 for writing as a class extending stack (up to 4).
6 ptQueueFinal · Spring 2010 · 18 · 10 min
We would like a queue similar to stack, except that the first item put in should be the first item to come
out. It should have operations:
void enQueue(E item); // Put item at the end of the queue
E deQueue() throws NullPointerException(); // Get the first item in the queue.
Please give the code for such a class, using the DLLNode data structure.
   A possible solution is:
public class Queue<E> {
  DLLNode head, tail;

    public void enQueue(E item) {
      if (tail == null) {
        DLLNode newNode = new DLLNode<E>(item);
        tail = newNode;
        head = newNode;
      } else
        tail.insertAfter(item);
    }

    public E deQueue() throws NullPointerException {
      if (head == null) throw new NullPointerException();
      else {
        E result = (E)head.getValue();
        head = head.deleteGetAfter();
        return result;
        }                                                           Name:                                 12
    }
}
    Scoring: 1 for correct class definition and methods, 1 for enQueue inserts, 1 for enQueue sets point-
ers correctly, 1 for deQueue gets right result, 1 for deQueue sets pointers correctly, 1 for proper deQueue
exception.
3 ptI/OFinal · Spring 2010 · 19 · 4 min
A programmer wrote the following code to read an array of integers from a file.
String filename = "mydata";
DataInputStream stream = new DataInputStream(new FileInputStream(filename));
int[] data = new int[10000];
for(int i = 0; i < data.length; i++)
    data[i] = stream.readInt();
You notice it takes a long time to read the data from the file. Explain why it slow, and suggest a way to
make it faster (for full credit, give the code to solve the problem.)
    Data reading is not buffered, every read goes to the disk. Fix: change the first line to
use BufferedInputStream, i.e., new DataInputStream(new BufferedInputStream(new FileIn-
putStream(filename)));
    Scoring: 1 point for buffered, 1 point for start at solution, 1 point for coded solution.
4 ptPointersFinal · Spring 2010 · 20 · 10 min
class Node {
  public int value;
  public Node next;
}

Given a linked list of integers defined using the above class, write a recursive function that returns the
maximum value in the linked-list. (A non-recursive solution will receive at most two points.)
   The following is a possible solution:

int Max(Node head) {
  if(head == null)
    throw new NullPointerException("head is a null pointer.");
  else if(head.next == null)
    return head.value;
  else {
    int t = Max(head.next);
    if(t > head.value) return t;
    else return head.value;
  }
}
     Scoring: 1 for proper base case, 1 for recursive case, 1 for proper calculation in recursive case, 1 for
dealing with null head.
21        Synchronization (5 minutes, 2 points)
                                                                       Name:                                   13
public class Chess extends Thread {

    private long id;

    public Chess(long id){
      this.id = id;
    }

    public void run(){
      move(id);
    }

        // INSERT FRAGMENT HERE
        System.out.print(id + " ");
        System.out.print(id + " ");
    }

    public static void main(String[] args) {
      Chess ch1 = new Chess(2);
      Chess ch2 = new Chess(4);
      ch1.start();
      ch2.start();
    }
}

Given the above and the following two code fragments:
1)      void move(long id) {
2)      synchronized void move(long id) {
Either give an example of output that is possible with fragment 1 but not possible with fragment 2, or
explain why any possible result of fragment 1 is also possible with fragment 2.
     A synchronized method will ensure that no other process is using the current object. In
other words, when thread ch1 is started, no other thread can run the move method for object
ch1. But since the second thread is running move for object ch2, any interleaving is possible
- the synchronization has no effect on these two threads, so fragments 1 and 2 are essentially
the same.
    Scoring: 1 point for any result that interleaves 2s and 4s (good idea, but not correct), 2 points for pointing
out that they synchronize on different objects, so synchronization has no effect.
2 ptLooping ConstructsFinal · Spring 2011 · 1 · 4 min
Given the following for loop:

int sum = 0;
for ( int i=1; i<4; i++ ) {
  if ( i != 3 )
    sum += i;
}

A programmer has converted the above for loop into the following while loop:

int i = 1;
int sum = 0;

while ( i < 4 ) {
  if ( i != 3 ) {
    sum += i;
    i++;
  }
}

Does the converted while loop produce the same result as the for loop? Explain your answer.
  No. The result of sum after for loop is 3. However, the while loop enters an infinite loop
when i increases to 3.
  Scoring: 1 for No, 1 for reasonable explanation matching answer.
3 ptOverridingFinal · Spring 2011 · 2.1 · 3 min
Given the following two objects:

Parent p = new Parent();
Child c = new Child();
For each of the following code fragments, which of the fun() methods are executed, the one in the class
Child, the one in the class Parent, or both (and in which order)?

   • Part 1:           p.fun();

        A fun() in Parent is executed.
        B fun() in Child is executed.
        C fun() in Child is called, then fun() in Parent.
        D fun() in Parent is called, then fun() in Child.

   • Part 2:           c.fun();

        A fun() in Parent is executed.
        B fun() in Child is executed.
        C fun() in Child is called, then fun() in Parent.
        D fun() in Parent is called, then fun() in Child.

   • Part 3:           p = c;      p.fun();

        A fun() in Parent is executed.
        B fun() in Child is executed.
        C fun() in Child is called, then fun() in Parent.
        D fun() in Parent is called, then fun() in Child.
2 ptCalling Parent classFinal · Spring 2011 · 2.2 · 1 min
In writing the method disneyland in class Child, you want to call the fun() methods in class Child and
class Parent. Show both calls.
fun();
super.fun();
    Scoring: 1 point for each as long as reasonably close.
2 ptAbstract ClassesFinal · Spring 2011 · 2.3 · 2 min
Assume Parent is an abstract class (and at least one of its methods is abstract). What changes would need
to be made to Child and why?
   The Child class must implement any methods declared as abstract in the Parent class.
   Scoring: 1 point for "none", 2 for "implement any abstract methods" or "none because all abstract
methods implemented".
1 ptErrorsFinal · Spring 2011 · 3.1 · 2 min
The above code will lead to a compilation error. Why?
   methodA throws an exception that methodB doesn't throw or catch.
   Scoring: 1 for missed exception.
2 ptCorrect UseFinal · Spring 2011 · 3.2 · 3 min
Rewrite methodB() in two different ways so that the code compiles.
    A public void methodB() throws CS180Exception {
    B try {
        methodA();
      } catch (CS180Exception e) { }
    Scoring: 1 point for getting a try/catch, 1 for throwing.
1 ptInheritanceFinal · Spring 2011 · 4 · 5 min
Consider the following class definitions:
public class A {
  public A() { System.out.println("A"); }
  public A( String str ) { System.out.println(str); }
}

public class B extends A {
  public B() { System.out.println("B"); }
  public B( String str ) { System.out.println(str); }
}
Which code segment would produce output different from the rest:
    A new B(); new A();
    B new B("B"); new A();
    C new A(); new B("B");
    D new B("B"); new A("A");
    Answer: C (A,B,D produces ABA while C produces AAB)
2 ptPart 1Final · Spring 2011 · 5.1 · 4 min
public class Point {
  public int x, y;
  public Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
}

public class Q1 {

    public static void increasePoint(Point p, String str) {
      str = "new point is :";
      p.x = p.x+1;
      p.y = p.y+1;
    }

    public static void main(String[] args) {
      String str = "old point is";
      Point p = new Point(1,1);
      System.out.println(str+"("+p.x+","+p.y+")");
      increasePoint(p,str);
      System.out.println(str+"("+p.x+","+p.y+")");
    }
}

old point is(1,1)
old point is(2,2)
   Scoring: 1 for "old point is" for both, 1 for 1,1 followed by 2,2.
2 ptPart 2Final · Spring 2011 · 5.2 · 4 min
public class Q2 {
  public static void increment(int x) {
    x=x+1;
  }

    public static void main(String[] args) {
      int x = 0;
      while(x<5) {
        increment(x);
        System.out.println(x);
      }
    }
}

This enteres an infinite loop printing 0.
  Scoring: 1 for 0, 1 for infinite loop.
2 ptPart 3Final · Spring 2011 · 5.3 · 2 min
public class Q3 {
  static int x = 0;
  static int y = 0;

    public static void increment(int x)
    {
      x = x+1;
      y = y+1;
    }

    public static void main(String[] args)
    {
      increment(x);
      System.out.println(x);
      System.out.println(y);
    }
}

    Scoring: 1 for 0, 1 for 1.
2 ptLinked Data StructuresFinal · Spring 2011 · 6 · 6 min
import java.util.LinkedList;

public class Element {
  public int value;

    public void addToList( LinkedList<Element> linkList ) {
      Element e = new Element();
      for ( int i=0; i<10; i++ ) {
        e.setValue(i);
        linkList.add(e);
      }
    }

    public void setValue( int value ) {
      this.value = value;
    }
}

    If addToList is invoked, I claim that all 10 'Elements' in linkList will have the same 'value' 9. True
or False? Explain. (Answer valid only with correct explanation) Hint: You don't have to worry about how
java.util.LinkedList works - the answer is the same with any reasonable implementation of a LinkeList, such
as those shown in class. And yes, this does compile.
    Only a single Element object is created, and it is inserted into the list multiple times. Since
the setValue is operating on that one object, each time it sets the value, it essentially changes
the value of everything in the list.
    Scoring: 2 for catching idea that only one element, 1 for showing reasonable understanding of linked list
in another way.
1 ptUse of Inherited classesFinal · Spring 2011 · 7 · 5 min
What will be the result of attempting to compile and run the following program?
public class Polymorphism {
  public static void main(String[] args) {
    A ref1 = new C();
    B ref2 = (B) ref1;
    System.out.println(ref2.f());
  }
}

class A { int f() { return 0; } }
class B extends A { int f() { return 1; } }
class C extends B { int f() { return 2; } }
Select the one correct answer:
    A The program will fail to compile.
    B The program will compile without error, but will throw a ClassCastException when run.
    C The program will compile without error and print 1 when run.
    D The program will compile without error and print 2 when run.
10 ptCreating a Data AbstractionFinal · Spring 2011 · 8 · 12 min
In this question, you will create parts of a GradeBook class and methods. A GradeBook contains assignments,
for each assignment there is a score for each student. You will have to decide what data types / data structures
to use. Note: There is a lot of partial credit available for even getting small pieces right, so try to write even
a partial answer every part even if you know your entire answer isn't correct.
3 ptClass DefinitionFinal · Spring 2011 · 8.1 · 4 min
Write the basic class definition, with fields to hold the assignments. For full credit, your definition should
not limit how many assignments a GradeBook can have. If you want to define multiple classes, that is okay
- but you should at least have a GradeBook class.

public class GradeBook {
  float grades[][];

}

    Scoring: 1 for basic definition, 1 for field(s) for assignments, 1 for holding students.
4 ptConstructorFinal · Spring 2011 · 8.2 · 4 min
Create a constructor that takes the number of assignments and number of students as arguments, and creates
the objects needed for your GradeBook to store the assignment grades. (Note that it would be nice if the
GradeBook wasn't limited to the provided number of assignments, but it is okay if it is.)

    public GradeBook(int asn, int stud) {
      grades = new float[asn][stud];
    }

   Scoring: 1 for proper constructor, 1 for arguments, 2 for instantiating fields as appropriate (1 if partially
done.)
3 ptCalculationFinal · Spring 2011 · 8.3 · 4 min
Create a method mean in your GradeBook class that takes an assignment number as an argument, and
returns the average (mean) score on that assignment.

    public float mean(int asn) {
      float sum = 0.0f;
      for ( int i=0; i<grades[asn].length; i++ )
        sum += grades[asn][i];
      return sum / grades[asn].length;
    }

    Scoring: 1 for method with proper argument, 1 for proper return type, 1 for use of objects.
5 ptRecursionFinal · Spring 2011 · 9 · 10 min
Given the following recursive methods:
public int f( int x )                        public int g( int x )
{                                            {
  if ( x == 1 )                                if ( x == 0 )
    return 1;                                    return 0;
  else                                         else
    return x * f(x-1);                           return f(x) + g(x-1);
}                                            }
3 ptUnderstanding the codeFinal · Spring 2011 · 9.1 · 4 min
What is returned by g(4); ? If you aren't certain, showing your work may get you partial credit even if you
get the wrong answer.
    This is a sum of factorials, 4! + 3! + 2! + 1! = 24 + 6 + 2 + 1 = 33.
    Scoring: 3 for correct (or clearly understands but arithmetic error), 2 for showing correct understanding
of one method, 1 for showing some understanding of recursion.
1 ptIdentifying code problemsFinal · Spring 2011 · 9.2 · 3 min
The above code will fail with some inputs. Give an example input x where g(x) will fail.
   g applied to a negative number does not terminate.
   Scoring: 1 for any negative example.
1 ptFixing problemsFinal · Spring 2011 · 9.3 · 3 min
Revise the code of method f or g to prevent the failure you identified in 9.2.
   The first line of g should be changed to: if ( x <= 0 )
   Scoring: 1 for any legal check for < 0 in g, or if they came up with a different issue in previous question,
a solution to their issue.
6 ptLinked Data StructuresFinal · Spring 2011 · 10 · 15 min
A circular linked list is a list in which the link field of the last node is made to point to the start/first node
of the list. The diagram at the right shows a CircularLinkedList with nodes added in the order E0, E1, E2,
E3. To help you to implement this class, we provide you the following class definitions:

class Node<E> {
  public E info;
  public Node<E> next;                                                                  E2
  public Node (E info, Node<E> next)                     startNode
  {
    this.info = info;                                                  E3                                E1
    this.next = next;
  }
}
                                                                                        E0

public class CircularLinkedList<E> {
  private Node<E> startNode;
  public CircularLinkedList () {
    startNode = null;
  }
  public void insert(E item) {
    /* item E is inserted at the position of the startNode and becomes
       the new start of the circular linked list. This new start
       node's next attribute should point to the original startNode.
       Be sure that after inserting, the list still a valid circular list. */

// Solution below.

Node<E> temp = new Node<E>(item, startNode);

if ( startNode == null )
  temp.next = temp;
else {
  temp.next = startNode;
  Node<E> current = startNode;
  while ( current.next != startNode ) current = current.next;
    current.next = temp;
}
startNode = temp;

// Solution ends here.

    }
}

    Your task is to implement the insert method of the CircularLinkedList class (fill in the insert method.)
Hint: You should consider two possible cases: when the list is empty and when it has at least one element.
    Scoring: For each case (empty list, non-empty list), you can get 1 point for creating a new node with the
correct value, 1 for having startNode point to the new node, and 1 for the tail pointing to this new node. If
this doesn't add up to six, you may receive up to two points for a generally correct structure that shows an
understanding of linked lists.
3 ptFactorButtonListenerFinal · Spring 2011 · 11.1 · 6 min
At Part 1, finish the implementation of FactorButtonListener, which will be the ActionListener when the
factorsButton JButton is pressed. When the button is pressed, the number can be retrieved from the
numberField JTextField with the getText method of JTextField (you'll have to convert the text to the
integer yourself). For simplicity, you may assume that the text will always contain an integer.
    Scoring: 1 point for defining ActionPerformed, 1 for getting text and performing any attempt at converting
to integer, 1 for starting thread.
2 ptRegister ListenerFinal · Spring 2011 · 11.2 · 4 min
At Part 2, add code which registers an instance of your FactorButtonListener as the ActionListener to
factorsButton.

    Scoring: 1 for adding listener, 1 for creating instance of FactorButtonListener.
2 ptConcurrencyFinal · Spring 2011 · 11.3 · 10 min
Write a thread class ConcurrentFactorsThread which computes the factors of its given number and prints
them out on the console.
   Solution:

public class ConcurrentFactorsThread extends Thread
{
    private int num;

     public ConcurrentFactorsThread(int num)
     {
         this.num = num;
     }

     @Override
     public void run()
     {
         for (int i=1; i<=num; i++)
         {
             if (num % i == 0)
                 System.out.printf("%d is a factor of %d\n", i, num);
             try
             {
                 Thread.sleep(1000);
             }
             catch (InterruptedException e)
             {
                 e.printStackTrace();
             }
         }
     }
}

    Scoring: 1 each for reasonable definition of class/constructor, 1 for reasonable definition of run method.
9 ptFile I/OFinal · Spring 2011 · 12 · 20 min
Write a program that reads in lines from the file "input.txt", and writes the lines to the file "output.txt" in
the opposite order (last line in input.txt is the first in output.txt, 2nd to last in input.txt is 2nd in output.txt,
etc.)
    For example, if the file "input.txt" contains:

CS180 is awesome
CS180 is very awesome
CS180 is very very awesome

    then your program should create a file "output.txt" containing:

CS180 is very very awesome
CS180 is very awesome
CS180 is awesome

   For full credit (worth one point), you should have a class with a method
void reverse(Scanner in, PrintWriter out) . You can ignore exception handling - it is okay to assume
that none of the methods you call throw exceptions.
   Hints: Scanner has a method String nextLine() and boolean hasNextLine(), PrintWriter has a
method
void println(String x). Both have constructors that take a File or InputStream object as an argument;
a File can be constructed with a String argument (the name of the file.) Given this information, there is
a very simple recursive solution.
   Solution follows:

import java.util.*;
import java.io.*;

public class Reverse {

    public static void reverse(Scanner in, PrintWriter out) {
      if ( in.hasNextLine() ) {
        String line = in.nextLine();
        reverse(in, out);
        out.println(line);
      }
    }

    public static void main(String args[]) {
      try {
        PrintWriter out = new PrintWriter(new File("output.txt"));
        reverse(new Scanner(new File("input.txt")), out);
        out.close();
      } catch (FileNotFoundException e) { }
    }
}
    Scoring: 1 for reverse method, 1 for constructing Scanner/Printwriter (or InputStream/OutputStream)
objects, 1 for constructing properly from given file names, 1 for appropriate reading and/or writing, 1-3 for
quality of "reverse" logic (1 for idea, 2 for workable idea, 3 for correct), 1 for having class, 1 for main()

The Trap Sheet

the errors that actually cost points

If you read nothing else the night before the exam, read this.

You wroteJava heardFix
5 / 22 — integer division5.0 / 2 or (double) 5 / 2
(int) 3.993 — chops, never roundsMath.round(3.99)
s1 == s2same address? usually falses1.equals(s2)
s.toUpperCase();computed, thrown aways = s.toUpperCase();
arr.length()compile errorarr.length (no parens)
str.lengthcompile errorstr.length()
list.length()compile errorlist.size()
i <= arr.lengthone pass too manyi < arr.length
substring(2, 5)indices 2,3,4 — end excludedlength is end - start
case 3: no break;falls into every case belowbreak; on every case
public void Boiler()a method, not a constructorpublic Boiler()
ArrayList<int>compile errorArrayList<Integer>
nextInt() then nextLine()empty stringextra kb.nextLine();
PrintWriter without close()empty / truncated fileout.close();
t.run()runs on the current threadt.start();
catch (Exception) firstunreachable catch, compile errorspecific to general
bump(x) on an intcaller unchanged — copyreturn the new value
new String[3]three nulls, not ""fill before use
super(...) not firstcompile errorsuper(...) on line 1
overriding with new paramssilent overload@Override catches it

Programming Questions

the other 60 points · hand-written, no compiler

The multiple choice is 40 of the 100 points. The rest is you writing Java on paper — so practise it on paper.

Format, from Purdue's own published papers: Exam 1 is 20 MCQ at 2 points (40) plus 3 programming questions worth 60. The final is 30 MCQ at 3 points (90) plus 4 programming questions worth 110. Sources: Exam 1 key · Final key. These are the archived papers; some semesters add fill-in-the-blank and short answer, so confirm with your instructor.

Write it out before opening the answer. The mistakes you make with a pen are the ones you'll make in the exam.
20 pts Write countVowels(String s) — return how many vowels the string contains, ignoring case.
model answer
public static int countVowels(String s) {
    int count = 0;
    String vowels = "aeiou";

    for (int i = 0; i < s.length(); i++) {
        char c = Character.toLowerCase(s.charAt(i));
        if (vowels.indexOf(c) != -1) {     // -1 means "not found"
            count++;
        }
    }
    return count;
}

Marks come from: using s.length() with parentheses, charAt returning a char (not a String), handling case, and returning on every path. The indexOf trick avoids a five-way || chain.

20 pts Write secondLargest(int[] a) — return the second largest value. Assume the array has at least two elements.
model answer
public static int secondLargest(int[] a) {
    int first  = Integer.MIN_VALUE;
    int second = Integer.MIN_VALUE;

    for (int i = 0; i < a.length; i++) {
        if (a[i] > first) {
            second = first;      // the old champion slides down
            first  = a[i];
        } else if (a[i] > second && a[i] != first) {
            second = a[i];
        }
    }
    return second;
}

Marks come from: one pass, not sorting; seeding with Integer.MIN_VALUE rather than 0 (negative arrays); and demoting first into second in the right order. Sorting a copy also earns full marks unless the question forbids it.

20 pts Given the Node class from module 21, write sum(Node head) — total of every value in the list.
model answer — iterative
public static int sum(Node head) {
    int total = 0;
    Node cur = head;

    while (cur != null) {        // null is the stop sign
        total += cur.data;
        cur = cur.next;
    }
    return total;
}
model answer — recursive
public static int sum(Node head) {
    if (head == null) return 0;             // base case: empty list
    return head.data + sum(head.next);      // shrink toward the base case
}

Marks come from: never moving head itself, stopping on null rather than on cur.next == null, and handling the empty list. Either version is full marks.

30 pts Write a class Account with a private balance, a constructor, deposit, a withdraw that refuses to overdraw, and toString.
model answer
public class Account {
    private String owner;
    private double balance;

    public Account(String owner, double balance) {
        this.owner = owner;
        this.balance = balance;
    }

    public double getBalance() { return balance; }

    public void deposit(double amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("deposit must be positive");
        }
        balance += amount;
    }

    public void withdraw(double amount) {
        if (amount > balance) {
            throw new IllegalArgumentException("insufficient funds");
        }
        balance -= amount;
    }

    @Override
    public String toString() {
        return owner + ": $" + balance;
    }
}

Marks come from: private fields with public accessors, a constructor with no return type using this. to disambiguate, validating before mutating, and @Override on toString. Losing marks here is almost always public void Account(...) or public fields.

?

Trace Quiz

20 questions · 2 points each · exactly the Exam 1 MCQ section

Read the code, commit to an answer, then click. Guessing and checking teaches nothing.

Worth 40 of Exam 1's 100 points. The other 60 are hand-written code — see Programming Questions.
Score: 0 / 20 · 0 of 40 points