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.
- Draw every object variable in
main()and every object it refers to, including sub-objects: aStringfield is its own object, so draw an arrow to a box holding"...". - Object box = fields only, never methods (
next(),toString()don't go in the box). - A variable holds a reference (arrow), not the object.
int/char/doublehold the value directly. - Array of objects = one array box with
nslots, each slot an arrow to its own object.new Day[n]creates slots holdingnull; objects only exist afterarr[i] = new Day(..). - No arrow pointing at it → garbage (eligible for GC). Mark it crossed out if asked.
- Don't waste time on annotations (types, field names) unless the question asks. Spellings don't exist in memory.
- Method call: parameter
xis a new variable holding a copy of the reference, so it points to the same object as the argument.
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;
}
}
d1.advance();changes d1.d1.next();alone does nothing to d1; you needd1 = d1.next();System.out.println(d1)callsd1.toString()automatically.- Static method = called on the class (
Day.valid(y,m,d)), nothis, can't touchyear/month/day. - Overloading = same name, different parameter list; the compiler picks by the arguments.
Quick traps
| Thing | Answer |
|---|---|
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 types | syntax (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 strings | compares 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 backslash | System.out.print("\\"); |
printf("%5d", x) | width 5, right-aligned integer |
| Constructor return type | none, 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
- Method: draw the call tree, left child first. The print happens on entry, so output = pre-order.
- f(0)=1 f(1)=1 f(2)=2 f(3)=3 f(4)=5 f(5)=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)
in.next()pauses for input, skips leading white-space, reads one word (up to the next space). Input" Today is a good day.⏎"→ s1 ="Today".- The rest
" is a good day.⏎"stays in the input stream. in.nextLine()then doesn't pause: takes the remaining contents up to ⏎, and ⏎ is discarded → s2 =" is a good day."(leading spaces kept).- Same trap:
nextInt()thennextLine()→ the nextLine gets the leftover empty line.
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)
int[HEIGHT][WIDTH] A→int[][] A; declaration →int[][] values = new int[HEIGHT][WIDTH];for(int y=0, y<H, y+1)→for(int y=0; y<H; y++)(semicolons, andy+1doesn't change y)0 <= x <= 100→0 <= x && x <= 100count+1;→count++;"The count is: " count→ missing+- Unicode minus
‐pasted from PDF → real-; check braces of nested loops
OO: pass-by-value and Group (Lab01 Q6, Lec03 Q13)
- Why Mary's C++ is wrong:
earn(Customer c, int v)takes a copy of the customer, soc.spend(v)changes the copy and the real c1/c2 keep $200. Fix in C++:Customer &c(or a pointer). - In Java object variables are references, so the parameter refers to the same object and it works.
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
Task: name ·Student: name + staticcreateListFromFile→Student[]·Team: name +Student[]of references ·Assignment: (Team, Task) pair + static print-by-task ·Main: private static helpers.- Students are not copied into teams. Team arrays hold references to the same Student objects.
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 |
|---|---|
| 1 | class = implementation of the blueprint; object = specific instance |
| 2 | name, gender are instance fields |
| 3 | new returns a reference to the object |
| 4 | constructor has no return type, not even void |
| 5 | object variable stores the reference |
| 6 | p = null, no other refs → eligible for garbage collection |
| 7 | no refs → program cannot use it; Java does automatic garbage collection, reclaiming memory space |
| 8 | this = currently executing object |
| 9 | several refs to one object = aliases |
| 10 | p1 == p2 true iff they are aliases (same object) |
| 11 | equals redefined for equality of data of 2 objects |
| 12 | root class: java.lang.Object |
| 13 | inherited by all: toString, equals |
| 14 | has 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
- Draw: variables, arrows, objects with fields only, Strings as sub-objects, no methods.
next()returns new;advance()mutates. Unusednew= garbage.- One Scanner for System.in.
throws FileNotFoundExceptionon file code. - Bracket
(age+1)in string concatenation. - Read the whole paper first; do drawing questions early, they're quick marks.