CS2312 Test 1: Prep Book
Fri 9 Oct 09:30 · BOC R4057 · 50 min · closed book, pen + paper · 0% or 5% · up to Week 5 lecture + Lab 03 · ≥15 min late = not let in
How to use it: cover the answer, write yours on paper, then open answer. Anything you got wrong goes on one sheet you re-read tomorrow at breakfast. The Day class, traps table, Scanner and Lab 3 code are on the mock notes page. This book only adds what the mock skipped plus practice.
Tonight (TickTick blocks)
| When | Do | Uses |
|---|---|---|
| 17:10–17:55 | Topics 01–03 lecture exercises, closed book | §Week 5 below + mock notes |
| 18:00–18:50 | Lab03 by hand + redo what you lost on the mock | P1, P2 |
| 19:30–20:20 | Timed 50-min run, pen only | P1 (25 min) → P2–P4 (25 min) |
| after | 5 min on the traps, pack bag, check seating plan, sleep | §Morning of |
What the paper looks like
From the 2016-17 Quiz 1 (Lab02 Q5 given files) + Helena's drawing instructions; this year's mock had the same shape
- Coding (most marks): complete a class from a given
main()and sample rundowns: read files into arrays in the constructor, then search / list methods. "Avoid hardcoding" except the size they give you. No sorting, no ArrayList, no input-error handling. - Memory drawing: all object variables in
main()and every object they refer to, sub-objects included (Strings as"..."). Fields only, no annotations. They may say "draw at least two" of an array; do exactly that. - Short questions: output traces, what's wrong with this line, static vs instance, MC concept checks.
- Marks also go to code design, naming, formatting. Private fields, small helper methods, indentation.
Week 5 lecture: the part the mock didn't cover
Lecture Exercise (Handout_LecWk05Ex), Topic 03 p7–p16; written answers = Writing_LecWk06_Q0*.jpg
Q1 · toString through a chain
class X { private int xValue; private X xChild;
public X(int v, X c) { xValue = v; xChild = c; }
public String toString() { return xChild + " " + xValue; } }
X obj = new X(99, new X(88, new X(77, null)));
System.out.println(obj);
answer
null 77 88 99. xChild + " " calls the child's toString() first (recursion), innermost child is null which prints as null. Built inside-out, printed innermost-first.
Q2 · implicit vs explicit parameter
class X { private int data;
public X(int d) { data = d * 2; }
public void doSomething(X r) {
X s = new X(8);
System.out.println(this.data); System.out.println(r.data); System.out.println(s.data); } }
X a = new X(1); X b = new X(15); a.doSomething(b);
answer
- Output
2 / 30 / 16(one per line). - Implicit parameter =
this(the calling object,a). Explicit =r. Local =s. doSomethingcan readr.dataeven thoughrisn'tthis:privatemeans private to the class, not to the object.
Q3 · does setName change the String?
Employee e = new Employee("Carl Cracker", 75000, 1987, 12, 15);
e.setName("Helena");
answer
No. Strings are immutable. setName does name = n;, which re-points the name field at a different String object "Helena". Drawing: e → Employee{ name ─╳→ "Carl Cracker", name → "Helena", salary 75000, hireDay → Day{1987,12,15} }. The old "Carl Cracker" has no arrow → garbage.
Q4 · static vs instance
class A { public int x1; public static int x2;
public void m1() { m2(); }
public static void m2() {
//x1 += 100; // line X1
x2 += 100;
//m1(); // line X2
} }
(new A()).m1(); (new A()).m1();
answer
- Runs, prints nothing.
x2is one shared variable for the class → ends at 200, not 100 per object. - X1 wrong: a static method has no
this, so there is no object whosex1it could mean. - X2 wrong:
m1()is an instance method, it needs a calling object; staticm2doesn't have one. - Rule: instance → can use static. Static → can't use instance (without an object reference like
obj.x1).
Q5 · "The constructor RandomNumber() is undefined"
public class RandomNumber {
private int r = (int)(Math.random() * 100);
public RandomNumber(int n) { r = (int)(Math.random() * n); }
...
new RandomNumber(); // ERROR
answer
Java only generates the no-argument default constructor if you write no constructor. Writing RandomNumber(int n) removes it. Fix: add public RandomNumber() { } (the field initialiser already gives 0..99), or public RandomNumber() { this(100); }.
Q6 · casting
int i = 97; char c; c = (char)i; // println(i) → 97, println(c) → a
answer
(i) Does i's type change? No, a variable's type is fixed at declaration. (ii) Accurate: (b), (c), (d). (a) "convert i to char" is the wrong one: i itself isn't converted, its value is used to produce a char value.
P1 · File + arrays (≈25 min, the big one)
2016-17 Quiz 1 Q1, 25 marks. Source PDF: Labs/Lab02_GivenFiles/Lab02_Q5(201617AQuiz1Q1)/
StudentList.txt has 20 student IDs. AttendanceLog.txt has 20 numbers: an ID of someone present, or 0 = empty seat. Some attendees are walk-ins (not on the list). Avoid hardcoding except the size 20.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
Attendance at = new Attendance();
System.out.print("Type the student ID to search: ");
int id = s.nextInt();
if (at.belongToClass(id) == false) System.out.println("Result: Not belong to the class.\n");
else if (at.isPresent(id)) System.out.println("Result: The student is present.\n");
else System.out.println("Result: No show!\n");
s.close();
}
// (b) second main: at.listAbsentees(); at.listWalkIn();
// List of absentees: / 52608757 / ... / Total count: 5
// List of walk-in students: / 54756947 / ...
Write: (i) constructor reading both files, (ii) isPresent, (iii) belongToClass, (iv) listAbsentees, (v) listWalkIn.
answer
import java.io.*;
import java.util.Scanner;
public class Attendance {
private int[] students;
private int[] attendees;
public Attendance() throws FileNotFoundException { // ← new File(..) needs this (and main too)
students = new int[20];
attendees = new int[20];
Scanner sStudents = new Scanner(new File("StudentList.txt"));
Scanner sAttendees = new Scanner(new File("AttendanceLog.txt"));
for (int i = 0; i < students.length; i++) students[i] = sStudents.nextInt();
for (int i = 0; i < attendees.length; i++) attendees[i] = sAttendees.nextInt();
sStudents.close();
sAttendees.close();
}
public boolean isPresent(int id) {
for (int i = 0; i < attendees.length; i++)
if (attendees[i] == id) return true;
return false; // after the loop, NOT in an else inside it
}
public boolean belongToClass(int id) {
for (int i = 0; i < students.length; i++)
if (students[i] == id) return true;
return false;
}
public void listAbsentees() {
System.out.println("List of absentees:");
int count = 0;
for (int i = 0; i < students.length; i++)
if (!isPresent(students[i])) { // reuse (ii), don't re-write the search
System.out.println(students[i]);
count++;
}
System.out.println("Total count: " + count);
}
public void listWalkIn() {
System.out.println("List of walk-in students:");
for (int i = 0; i < attendees.length; i++)
if (attendees[i] != 0 && !belongToClass(attendees[i])) // 0 = nobody, skip it
System.out.println(attendees[i]);
}
}
Where marks go: throws FileNotFoundException; loop bound .length not 20; return false after the loop; reusing isPresent/belongToClass; skipping the 0s in walk-ins; closing both Scanners.
P2 · Memory drawing (≈7 min)
class Student { private String name; public Student(String n) { name = n; } }
class Team { private String name; private Student[] members;
public Team(String n, Student[] m) { name = n; members = m; } }
public static void main(String[] args) {
Student s1 = new Student("Ada");
Student s2 = new Student("Bob");
Student[] mem = new Student[3];
mem[0] = s1;
mem[1] = s2;
Team t = new Team("Team " + (char)('A' + 0), mem);
s2 = new Student("Cy");
}
Draw all variables in main() and every object at the end. Which objects are garbage?
answer
s1 →Student{ name →"Ada"}s2 →Student{ name →"Cy"} (new object)mem →array [ • → the Ada Student, • → the Bob Student,null]t →Team{ name →"Team A", members → the same array asmem(no copy) }- Nothing is garbage. The Bob Student lost
s2butmem[1]still points to it. (Trap: crossing it out loses marks.) - Slot 3 is
null, draw it as an empty slot / "null", not an object. Total: 3 Students + 1 array + 1 Team, plus 4 Strings ("Ada","Bob","Cy","Team A").
P3 · Traces (≈8 min, write the exact output)
// (a) uses the Day class
Day a = new Day(2024, 2, 28);
Day b = a;
a.advance();
b = b.next();
a.next();
System.out.println(a + " / " + b);
// (b)
System.out.println(1 + 2 + "3" + 4 + 5);
// (c)
class C { static int n = 0; int id; C() { n++; id = n; } }
C x = new C(), y = new C(), z = x;
System.out.println(x.id + " " + y.id + " " + z.id + " " + C.n);
// (d) input typed: 12 Ada Lee⏎
int k = in.nextInt();
String s = in.nextLine();
System.out.println("[" + s + "]");
// (e)
static void swap(Day p, Day q) { Day t = p; p = q; q = t; }
Day d1 = new Day(2025,1,1), d2 = new Day(2026,1,1);
swap(d1, d2);
System.out.println(d1);
// (f)
int i = 5, cnt = 0;
while (i > 0) { i -= 2; cnt++; }
System.out.println(i + " " + cnt);
answer
| # | Output | Why |
|---|---|---|
| a | 29 Feb 2024 / 1 Mar 2024 | 2024 is leap; advance moves the shared object (a and b both 29 Feb); b = b.next() gives b a new object; bare a.next() is thrown away (garbage) |
| b | 3345 | left to right: 1+2=3 (int), then string concat "3"+"3"+"4"+"5" |
| c | 1 2 1 2 | n is shared (static), z is an alias of x, no third object |
| d | [ Ada Lee] | nextLine takes the rest of the line incl. the leading space |
| e | 1 Jan 2025 | p, q are copies of the references; swapping copies doesn't touch d1/d2 |
| f | -1 3 | 5→3→1→-1, three iterations |
P4 · Find the bugs (≈5 min)
public class Point {
private int x, y;
public void Point(int x, int y) { x = x; y = y; } // (1)
public static double dist(Point p) {
return Math.sqrt(x * x + y * y); // (2)
}
public boolean same(Point o) { return this == o; } // (3)
public String toString() { "(" + x + "," + y + ")"; } // (4)
}
Point p = new Point(3, 4); // (5)
String s1 = "ab", s2 = new String("ab");
if (s1 == s2) System.out.println("same"); // (6)
answer
voidmakes it a method named Point, not a constructor. Andx = xassigns the parameter to itself → usethis.x = x; this.y = y;- Static method has no object:
x/ydon't exist here →p.x,p.y. - Compiles, but it's a logic bug if "same" means same coordinates:
==checks alias. Usex == o.x && y == o.y. - Missing
return→ compile error (also "not a statement"). - Because of (1) there is no
Point(int,int)constructor → "constructor Point(int, int) is undefined". - Prints nothing: different objects. Use
s1.equals(s2).
P5 · Day class from a blank page (≈12 min, do it once tonight)
Without looking: fields, Day(y,m,d), Day(y) via this(...), static isLeapYear, static valid(y,m,d) + instance valid(), next() (new object), advance() (mutates), toString() as 28 Jan 2014. Then check against the mock notes Day class. Count every difference.
Lab 03 variant: static Day[] createDayListFromFile(String path): first number = n, then n lines of y m d; list valid ones, then invalid ones, reading the file once. Answer on the mock notes.
Morning of
- Bag: 2 pens, pencil + eraser (drawings), student card, water. Phone off in the bag.
- Check the seating plan (posted 24 h before). Be at BOC R4057 by 09:15. 09:45 = barred.
- Breakfast read: your wrong-answers sheet + the traps table. Nothing new.
- In the room: read the whole paper first. Drawing and short questions first (quick marks), then the coding question with the remaining time.
- Coding: write
throws FileNotFoundExceptionas soon as you typenew File. Loops use.length.return falseafter the loop. - Drawing: fields only, Strings as their own boxes, arrays as slot boxes,
nullslots empty. Don't cross out anything still referenced from an array. - Last 3 min: scan for missing semicolons,
"x" + (a+b)brackets,==on Strings.