CS2312 Mock: Key Notes

Mock Fri 2 Oct 09:00 · 50 min · closed book, handwritten, no devices · 0% · coverage: coding + drawing up to Week 4 lecture and Lab 3

Test 1 is Fri 9 Oct 09:30 (50 min, 0% or 5%), same coverage + Week 5 lecture. Late ≥15 min = not allowed in.

Memory drawing

Lec02 Q3, Lec03 Q1/Q2/Q9/Q10, Lab03 Q1. Rules from Helena's old quiz instructions.

Aliasing (Lec03 Q9)

birthday = new Day(2014,1,15);
deadline = birthday;          // ONE object, two arrows (aliases)
birthday.advance();           // birthday 16 Jan, deadline 16 Jan  (same object)
birthday.next();              // result thrown away → both still 16 Jan; new object = garbage
birthday = birthday.next();   // birthday 17 Jan (new object), deadline 16 Jan

Redundant object (Lec03 Q3)

Day d2 = new Day();   // ✗ this object becomes garbage on the next line
d2 = d1.next();
Day d2 = d1.next();   // ✓

Day class: write from blank

Lab01 Q1/Q5, Lab03 Q2, Lec03 Q6/Q8

public class Day {
    private int year, month, day;
    private static final String MonthNames = "JanFebMarAprMayJunJulAugSepOctNovDec";

    public Day(int y, int m, int d) { year = y; month = m; day = d; }
    // ✗ int year = y;  → declares a LOCAL, field stays 0
    // ✗ y = year;      → assigns the wrong way

    public Day(int y) { this(y, 1, 1); }               // 1 Jan y
    public Day(int y, int nth) {                       // nth day of year y
        this(y, 1, 1);
        for (int i = 1; i < nth; i++) advance();
    }

    static public boolean isLeapYear(int y) {
        return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
    }

    static public boolean valid(int y, int m, int d) {  // version 1: no object needed
        if (m < 1 || m > 12 || d < 1) return false;
        switch (m) {
            case 1: case 3: case 5: case 7: case 8: case 10: case 12: return d <= 31;
            case 4: case 6: case 9: case 11: return d <= 30;
            case 2: return isLeapYear(y) ? d <= 29 : d <= 28;
        }
        return false;
    }
    public boolean valid() { return valid(year, month, day); }   // version 2: overloading

    private boolean isEndOfAMonth() { return !valid(year, month, day + 1); }

    public Day next() {                                 // returns a NEW object
        if (isEndOfAMonth()) {
            if (month == 12) return new Day(year + 1, 1, 1);
            else return new Day(year, month + 1, 1);
        }
        return new Day(year, month, day + 1);
    }

    public void advance() {                             // changes THIS object
        if (isEndOfAMonth()) {
            if (month == 12) { year++; month = 1; day = 1; }
            else { month++; day = 1; }
        } else day++;
    }

    public Day previous() {
        if (day > 1) return new Day(year, month, day - 1);
        if (month == 1) return new Day(year - 1, 12, 31);
        int d = 31;
        while (!valid(year, month - 1, d)) d--;          // last valid day of prev month
        return new Day(year, month - 1, d);
    }

    public String toString() {                          // "28 Jan 2014"
        return day + " " + MonthNames.substring((month - 1) * 3, month * 3) + " " + year;
    }
}

Quick traps

ThingAnswer
i=10; while(i>0) i--;body 10×, condition checked 11×, ends i==0
a = b;change a's value by assigning b's value to a
syntax error ⇒ runtime error?No. Syntax error = won't compile, so it never runs
3 error typessyntax (compile) · runtime (crash) · logic (wrong output)
i after for(int i..)"cannot be resolved": out of scope
statement after return"unreachable code"
if(i>j) return i; if(i<=j) return j;"must return a result": compiler can't prove one fires. Use else
2.0-1.1 → 0.8999…1.1 has no exact binary representation (floating-point)
c = (char)i;i stays int; the cast makes a char value from i's value (97→'a')
(char)('A'+i)'A','B','C'… team letters
"x" + age + 1"x281"! Write "x" + (age+1)
s1 == s2 for stringscompares references. Use s1.equals(s2)
arr.length = 2;error: length is final
arr.length vs s.length()array = field, String = method
Java swap(Day a, Day b)can swap the fields of the two objects, not the caller's references (pass-by-value of references)
Print a backslashSystem.out.print("\\");
printf("%5d", x)width 5, right-aligned integer
Constructor return typenone, not even void

Recursion trace (Lec01 Q8)

int f(int n) { System.out.println(n); if (n==0||n==1) return 1; return f(n-1)+f(n-2); }
f(5) prints: 5 4 3 2 1 0 1 2 1 0 3 2 1 0 1   (15 calls, one per line)
Final result: 8

Scanner and File

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

Scanner in = new Scanner(System.in);         // ONLY ONE for System.in in the whole program
String name = in.nextLine();                  // whole line
int age = in.nextInt();                       // one int token

// file:
public static void main(String[] args) throws FileNotFoundException {
    File f = new File(path);                  // create File object
    Scanner inFile = new Scanner(f);          // Scanner reads that file
    int n = inFile.nextInt();                 // first line = count
    for (int i = 0; i < n; i++) { ... inFile.next() / nextInt() ... }
    inFile.close();
}

next() vs nextLine() (Lec03 Q4)

2D arrays (Lab02)

int[][] a = new int[ROWS][COLS];   // a.length = rows, a[0].length = cols
void f(int[][] A)                  // parameter: no sizes
f(values);                         // pass the array, NOT values[H][W]

private int getRowSum(int r) {
    int sum = 0;
    for (int c = 0; c < nums[r].length; c++) sum += nums[r][c];
    return sum;
}
public int getRowSumMax() {
    int max = getRowSum(0);
    for (int r = 1; r < nums.length; r++)
        if (getRowSum(r) > max) max = getRowSum(r);
    return max;
}
public void printAllRowsOfMax() {                  // "7,9"
    int max = getRowSumMax();
    boolean first = true;
    for (int r = 0; r < nums.length; r++)
        if (getRowSum(r) == max) {
            if (!first) System.out.print(",");
            System.out.print(r);
            first = false;
        }
}
// columns: same but loop rows inside, nums[r][c] with c fixed

Lab02 Q1 error list (fix-the-program questions)

OO: pass-by-value and Group (Lab01 Q6, Lec03 Q13)

public class Group {
    private Customer[] members = new Customer[10];   // at most 10
    private int count = 0;
    public void add(Customer c) { members[count++] = c; }
    public void pay(int total) {
        int each = total / count;
        for (int i = 0; i < count; i++) members[i].spend(each);
    }
}
// in Shop: overload earn
public void earn(Group g, int value) { totalProfit += value; g.pay(value); }

// main: c1,c2 = $200; g1.add(c1); g1.add(c2); s1.earn(g1,300); s1.earn(c1,30);
// s1.getProfit() → 330     c1.getAmount() → 200-150-30 = 20

Lab 3: array of objects and teams

Day[] arr = new Day[n];            // n slots of null
arr[i] = new Day(y, m, d);         // make slot i refer to a new object
static Day[] createDayListFromFile(String path)   // static: no object needed

// valid / invalid listing, file read once:
for (int i = 0; i < arr.length; i++) if (arr[i].valid())  System.out.println(arr[i]);
for (int i = 0; i < arr.length; i++) if (!arr[i].valid()) System.out.println(/* d/m/y form */);
// valid() here is the non-static version 2: it checks the calling object

Q3/Q4 design

if (students.length % numOfTeams != 0) { System.out.println("Wrong input - It is not a factor of " + students.length + "."); return; }
int per = students.length / numOfTeams;
Team[] teams = new Team[numOfTeams];
for (int i = 0; i < numOfTeams; i++) {
    Student[] mem = new Student[per];
    for (int j = 0; j < per; j++) mem[j] = students[i * per + j];
    teams[i] = new Team("Team " + (char)('A' + i), mem);
}
// listing by task without sorting: loop over task names in order,
// for each task find the team assigned to it and print.

Concept MCs (Lec04 Q1–Q2)

#Answer
1class = implementation of the blueprint; object = specific instance
2name, gender are instance fields
3new returns a reference to the object
4constructor has no return type, not even void
5object variable stores the reference
6p = null, no other refs → eligible for garbage collection
7no refs → program cannot use it; Java does automatic garbage collection, reclaiming memory space
8this = currently executing object
9several refs to one object = aliases
10p1 == p2 true iff they are aliases (same object)
11equals redefined for equality of data of 2 objects
12root class: java.lang.Object
13inherited by all: toString, equals
14has abstract method → abstract class, cannot create instances
Q2.equals for strings · length is final · static cannot use this.value · swap swaps fields

Last 5 minutes