Free for students · Ad-free · WCAG 2.1 AA Compliant · Accessibility

AP Computer Science A — Pattern-Matched Mock

A full-length mock exam focusing on class implementation, array/ArrayList algorithms, and 2D array traversals, mirroring recent AP exam trends.

--:--:--

Section 1 — Multiple Choice (41 questions)

Question 1 of 41 · EASY

Which of the following statements best describes the purpose of a constructor in Java?

A To create a copy of an existing object.
B To initialize the state of a newly created object.
C To define the behavior and methods of a class.
D To return a value to the code that called it.
Answer: B

The primary role of a constructor is to initialize the instance variables of an object when it is created with the new keyword. Choice A describes a copy constructor, which is a specific type, not the general purpose. Choice C is incorrect; methods define behavior, not the constructor itself. Choice D is incorrect because constructors do not have a return type, not even void.

Question 2 of 41 · EASY

Consider the following code segment.

int x = 10;
double y = 3.0;
int result = (int) (x / y);
System.out.println(result);

What is printed to the console?

A 3.333
B 3.0
C 3
D A compile-time error occurs.
Answer: C

The expression x / y involves an int and a double, so Java performs floating-point division, resulting in 3.333.... The (int) cast then truncates this double value, removing the decimal part, which results in 3. Choice A is incorrect because the value is cast to an int before printing. Choice B is incorrect because the cast changes the type to int. Choice D is incorrect because the code is valid.

Question 3 of 41 · MEDIUM

Consider the following code segment.

String str1 = "apple";
String str2 = new String("apple");
String str3 = "apple";

System.out.println(str1 == str2);
System.out.println(str1 == str3);

What is the output?

A true true
B false true
C false false
D true false
Answer: B

The == operator compares memory addresses for objects. str1 and str3 are string literals, and Java's string pool optimization means they point to the same object in memory, so str1 == str3 is true. str2 was created with the new keyword, which explicitly creates a new object in a different memory location, so str1 == str2 is false. This is a classic example of why you should use .equals() to compare String content.

Question 4 of 41 · MEDIUM

The Math.random() method returns a double value d such that 0.0 <= d < 1.0. Which expression generates a random integer between 50 and 100, inclusive?

A (int) (Math.random() * 50) + 51
B (int) (Math.random() * 51) + 50
C (int) (Math.random() * 100) + 50
D (int) (Math.random() * 50) + 50
Answer: B

To generate a random integer in the range [min, max], the general formula is (int) (Math.random() * (max - min + 1)) + min. In this case, max = 100 and min = 50. The number of values in the range is 100 - 50 + 1 = 51. So the expression is (int) (Math.random() * 51) + 50. Choice A has the range and offset mixed up. Choice C would generate numbers from 50 to 149. Choice D would generate numbers from 50 to 99.

Question 5 of 41 · EASY

Consider the boolean expressions below.

I. !(a && b) II. !a && !b III. !a || !b

Which of the expressions are logically equivalent?

A I and II only
B I and III only
C II and III only
D I, II, and III
Answer: B

This question tests De Morgan's laws. The law states that !(a && b) is equivalent to !a || !b. Therefore, expressions I and III are equivalent. Expression II, !a && !b, is the negation of (a || b), not (a && b). This is a common point of confusion for students.

Question 6 of 41 · EASY

Consider the following method.

public void checkValue(int val) {
  if (val > 10) {
    System.out.print("A");
  } else if (val > 5) {
    System.out.print("B");
  } else {
    System.out.print("C");
  }
}

Which of the following calls will cause "B" to be printed?

A checkValue(12)
B checkValue(10)
C checkValue(5)
D checkValue(3)
Answer: B

The code prints "B" if val is not greater than 10, but is greater than 5. Let's test the choices. A: checkValue(12) prints "A" because 12 > 10. B: checkValue(10) fails the first if (10 is not > 10), but passes the else if (10 > 5), so it prints "B". C: checkValue(5) fails both if and else if (5 is not > 5), so it prints "C". D: checkValue(3) also prints "C".

Question 7 of 41 · EASY

Consider the following code segment.

int k = 0;
int total = 0;
while (k < 5) {
  total += k;
  k++;
}
System.out.println(total);

What is printed to the console?

A 15
B 10
C 6
D 5
Answer: B

This code calculates the sum of integers from 0 up to, but not including, 5. Let's trace it:

  • k=0, total=0
  • k=1, total=0+1=1
  • k=2, total=1+2=3
  • k=3, total=3+3=6
  • k=4, total=6+4=10
  • k=5, the loop condition k < 5 is false, and the loop terminates. The final value of total is 10. A common mistake is to include 5 in the sum (0+1+2+3+4+5=15) or to make an off-by-one error in the loop boundary.
Question 8 of 41 · MEDIUM

What is the primary difference between a while loop and a for loop in Java?

A A `for` loop can run infinitely, but a `while` loop cannot.
B A `while` loop is used for iteration, while a `for` loop is used for selection.
C A `for` loop is typically used when the number of iterations is known, whereas a `while` loop is used when the loop should continue as long as a condition is true.
D Only `for` loops can have their own local variables.
Answer: C

While for and while loops are often interchangeable, their conventional use differs. for loops are ideal when you know the start, end, and increment of your iteration (e.g., iterating through an array). while loops are better suited for situations where the loop's continuation depends on a condition that might not be related to a simple counter (e.g., waiting for user input). Choice A is false; both can be infinite. Choice B is false; both are for iteration. Choice D is false; both can have local variables.

Question 9 of 41 · MEDIUM

Consider the following code segment.

String message = "AP-CS-A";
String result = "";
for (int i = 0; i < message.length(); i++) {
  if (!message.substring(i, i + 1).equals("-")) {
    result += message.substring(i, i + 1);
  }
}
System.out.println(result);

What is printed to the console?

A APCSA
B AP-CS-A
C AP CS A
D A StringIndexOutOfBoundsException is thrown.
Answer: A

The code iterates through the message string character by character. The if statement checks if the current character is NOT a hyphen. If it's not a hyphen, it's appended to the result string. This effectively removes all hyphens from the original string. A, P, C, S, A are all appended, while the two - characters are skipped.

Question 10 of 41 · MEDIUM

Consider the following code segment.

for (int i = 1; i <= 3; i++) {
  for (int j = 1; j <= i; j++) {
    System.out.print("*");
  }
  System.out.println();
}

What is the output of this code?

A * ** ***
B *** ** *
C 1 22 333
D * * * * * *
Answer: A

This is a classic nested loop pattern. The outer loop controls the number of rows (it runs for i=1, 2, 3). The inner loop controls the number of stars printed in each row. The inner loop runs from j=1 up to the current value of i.

  • When i=1, j runs once, printing *.
  • When i=2, j runs twice, printing **.
  • When i=3, j runs three times, printing ***. The System.out.println() moves to the next line after each row is complete.
Question 11 of 41 · EASY

A programmer is designing a Car class. Which of the following would be best represented as an instance variable of the Car class?

A The total number of cars manufactured.
B A method to calculate the car's fuel efficiency.
C The current speed of a specific car.
D The maximum legal speed limit on a highway.
Answer: C

Instance variables define the state or attributes of a specific object (an instance). The current speed is a property that is unique to each individual Car object. Choice A would be better as a static (class) variable, as it's a property of the class as a whole, not one instance. Choice B is a behavior, which would be a method. Choice D is external data and does not belong to the Car class at all.

Question 12 of 41 · MEDIUM

Consider the following class definition.

public class Book {
  private String title;
  private int pages;

  public Book(String aTitle, int numPages) {
    title = aTitle;
    pages = numPages;
  }

  public void adjustPages(int change) {
    pages += change;
  }

  public String getTitle() {
    return title;
  }
}

Which of the following changes would be necessary to allow code in another class to find out the number of pages in a Book object?

A Add the method `public int getPages() { return pages; }`
B Change `private int pages;` to `public int pages;`
C Add a new constructor `public Book(int numPages) { pages = numPages; }`
D Change `adjustPages` to `public int adjustPages(int change) { return pages; }`
Answer: A

The pages instance variable is private, meaning it cannot be accessed directly from outside the Book class. The standard and best practice for providing read-only access to a private field is to create a public "getter" method (also called an accessor method). Choice A does exactly this. Choice B violates the principle of encapsulation by making the data public, which is poor design. Choices C and D modify other parts of the class but do not provide a direct way to query the current page count.

Question 13 of 41 · MEDIUM

What is the purpose of the this keyword in Java?

A It refers to the superclass of the current object.
B It is used to create a new instance of a class.
C It refers to the current object instance itself.
D It is used to declare a static method.
Answer: C

The this keyword is a reference to the current object—the object whose method or constructor is being called. It is most often used to disambiguate between instance variables and parameters with the same name (e.g., this.name = name;) or to call another constructor from within a constructor (this(defaultName);). Choice A describes the super keyword. Choice B describes the new keyword. Choice D is incorrect; this cannot be used in a static context.

Question 14 of 41 · HARD

Consider the following code segment.

public class Item {
  private int value;

  public Item(int v) { value = v; }

  public void setValue(int v) { value = v; }

  public int getValue() { return value; }
}

// In another class's method
Item item1 = new Item(10);
Item item2 = item1;
item2.setValue(20);

System.out.println(item1.getValue());

What is printed?

A 10
B 20
C A NullPointerException is thrown.
D A compile-time error occurs.
Answer: B

This question tests the concept of object references. The line Item item2 = item1; does not create a new Item object. Instead, it creates a new reference, item2, that points to the same object in memory that item1 points to. Therefore, when item2.setValue(20) is called, it modifies the one and only Item object. When item1.getValue() is called, it retrieves the value from that same modified object, which is now 20.

Question 15 of 41 · MEDIUM

Which of the following is a key reason for using static variables in a class?

A To ensure that each instance of the class has its own unique copy of the variable.
B To create a variable that can only be accessed by methods within the same class.
C To create a single variable that is shared among all instances of a class.
D To allow the variable's value to be changed after it is initialized.
Answer: C

A static variable, also known as a class variable, belongs to the class itself, not to any individual instance. There is only one copy of a static variable, and all objects of that class share it. This is useful for things like counters (e.g., numberOfAccountsCreated) or constants (public static final double PI = 3.14159). Choice A describes an instance variable. Choice B describes private access. Choice D is true for non-final variables in general, not specific to static.

Question 16 of 41 · EASY

Consider the following array declaration.

int[] arr = {10, 20, 30, 40, 50};

What is the value of arr[2]?

A 20
B 30
C 40
D An ArrayIndexOutOfBoundsException is thrown.
Answer: B

Arrays in Java are zero-indexed. This means the first element is at index 0, the second at index 1, and so on. In the array arr, arr[0] is 10, arr[1] is 20, and arr[2] is 30. A common mistake for beginners is to think arrays are 1-indexed.

Question 17 of 41 · MEDIUM

Consider the following method mystery.

public int mystery(int[] arr) {
  int x = 0;
  for (int i = 0; i < arr.length; i++) {
    if (arr[i] > x) {
      x = arr[i];
    }
  }
  return x;
}

Which of the following best describes what the mystery method does, assuming all elements of arr are non-negative?

A It returns the first element of the array.
B It returns the sum of the elements in the array.
C It returns the largest value in the array.
D It returns the index of the largest value in the array.
Answer: C

This method implements a standard algorithm to find the maximum value in an array. It initializes a variable x to 0. It then iterates through the array. If the current element arr[i] is greater than the largest value seen so far (x), it updates x to be this new larger value. At the end of the loop, x will hold the largest value from the entire array. Choice D is a common mistake; the code returns the value itself, not its index.

Question 18 of 41 · EASY

Which of the following is a primary advantage of using an ArrayList over a standard array in Java?

A An `ArrayList` can store primitive types like `int` and `double` directly.
B An `ArrayList` has a fixed size, which prevents runtime errors.
C An `ArrayList` can dynamically change its size to accommodate more or fewer elements.
D Accessing an element in an `ArrayList` by its index is faster than in a standard array.
Answer: C

The main reason to choose an ArrayList is its dynamic resizing capability. You can add or remove elements, and the ArrayList manages the underlying array for you. Standard arrays have a fixed size that is set at creation and cannot be changed. Choice A is incorrect; ArrayLists can only store objects, so you must use wrapper classes (Integer, Double) for primitive types. Choice B is the opposite of the truth. Choice D is false; indexed access is approximately O(1) for both.

Question 19 of 41 · MEDIUM

Consider the following code segment.

ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add(1, "C");
list.remove(0);
System.out.println(list);

What is printed to the console?

A [A, C, B]
B [C, B]
C [B, C]
D [C]
Answer: B

Let's trace the state of the ArrayList:

  1. list.add("A"); -> [A]
  2. list.add("B"); -> [A, B]
  3. list.add(1, "C"); -> Inserts "C" at index 1, shifting "B" to the right. The list becomes [A, C, B].
  4. list.remove(0); -> Removes the element at index 0, which is "A". The list becomes [C, B]. The final output is the string representation of this list.
Question 20 of 41 · EASY

A program needs to store a grid of game pieces, where each piece can be identified by its row and column. Which data structure is most appropriate for this task?

A A one-dimensional array of integers.
B An `ArrayList` of `String` objects.
C A two-dimensional array, such as `Piece[][]`.
D A `for` loop.
Answer: C

A two-dimensional array is the natural and most direct way to represent a grid or a table of data that has rows and columns. Each element can be accessed using two indices, grid[row][col], which maps perfectly to the problem. The other choices are not suitable for representing a grid structure. A for loop is a control structure, not a data structure.

Question 21 of 41 · MEDIUM

Consider the following code segment for traversing a 2D array mat.

for (int c = 0; c < mat[0].length; c++) {
  for (int r = 0; r < mat.length; r++) {
    // process mat[r][c]
  }
}

This code processes the elements of the array in which order?

A Row-major order (across the first row, then second, etc.)
B Column-major order (down the first column, then second, etc.)
C Diagonal order
D Random order
Answer: B

The outer loop iterates through the columns (c from 0 to the number of columns). The inner loop iterates through the rows (r from 0 to the number of rows). For a fixed column c=0, the inner loop processes mat[0][0], mat[1][0], mat[2][0], etc. This is a column-by-column traversal, known as column-major order. The more common row-major order would have the row loop on the outside.

Question 22 of 41 · MEDIUM

Which of the following is true about the linear search and binary search algorithms?

A Binary search can be performed on any array, while linear search requires the array to be sorted.
B Linear search is generally more efficient than binary search for large arrays.
C Linear search requires the array to be sorted, while binary search can be performed on any array.
D Binary search requires the array to be sorted, while linear search can be performed on any array.
Answer: D

Linear search works by checking every element one by one, so it does not require the data to be in any particular order. Binary search works by repeatedly dividing the search interval in half. This process relies on the array being sorted to know whether to continue searching in the upper or lower half. Therefore, binary search is much more efficient for large, sorted arrays, but it cannot be used on unsorted data.

Question 23 of 41 · MEDIUM

Which of the following sorting algorithms works by repeatedly finding the minimum element from the unsorted part of the array and putting it at the beginning?

A Insertion Sort
B Selection Sort
C Merge Sort
D Binary Search
Answer: B

This description perfectly matches Selection Sort. In each pass, it selects the smallest remaining element and swaps it into its correct sorted position. Insertion Sort works by building the sorted array one element at a time, inserting each new element into its proper place. Merge Sort is a recursive, divide-and-conquer algorithm. Binary Search is a searching algorithm, not a sorting algorithm.

Question 24 of 41 · EASY

What is a necessary component of any recursive method to prevent infinite recursion?

A A recursive call
B A loop
C A base case
D A parameter
Answer: C

A recursive method must have a base case: a condition under which the method does not call itself again, allowing the chain of calls to terminate. Without a base case, the method would call itself indefinitely, leading to a StackOverflowError. The recursive call is what makes it recursive, but it doesn't prevent the infinite loop. Loops are generally an alternative to recursion, not a necessary part of it.

Question 25 of 41 · MEDIUM

Consider the following recursive method.

public int mystery(int n) {
  if (n <= 1) {
    return 1;
  } else {
    return n * mystery(n - 1);
  }
}

What is the value of mystery(4)?

A 4
B 10
C 24
D A StackOverflowError occurs.
Answer: C

This method calculates the factorial of n. Let's trace the call mystery(4):

  • mystery(4) returns 4 * mystery(3)
  • mystery(3) returns 3 * mystery(2)
  • mystery(2) returns 2 * mystery(1)
  • mystery(1) hits the base case and returns 1. Now, substitute back: 2 * 1 = 2. Then 3 * 2 = 6. Then 4 * 6 = 24. The final result is 24.
Question 26 of 41 · HARD

Consider the following code segment.

Integer num1 = new Integer(10);
Integer num2 = new Integer(10);
int num3 = 10;

System.out.println(num1 == num2);
System.out.println(num1.equals(num2));
System.out.println(num1 == num3);

What is the output?

A false true true
B true true true
C false true false
D The code does not compile.
Answer: A

This question tests understanding of wrapper classes, == vs .equals(), and autoboxing/unboxing.

  1. num1 == num2: num1 and num2 are two distinct objects created with new, so they have different memory addresses. == compares addresses, so this is false.
  2. num1.equals(num2): The equals method for Integer compares the wrapped int values. Since both are 10, this is true.
  3. num1 == num3: Here, num1 (an Integer object) is compared to num3 (a primitive int). Java unboxes num1 to its primitive int value (10) before the comparison. 10 == 10 is true. Therefore, the output is false, true, true.
Question 27 of 41 · HARD

Consider the following code segment.

ArrayList<Integer> nums = new ArrayList<Integer>();
nums.add(5);
nums.add(10);
nums.add(15);
nums.add(20);

for (int i = 0; i < nums.size(); i++) {
  if (nums.get(i) == 10) {
    nums.remove(i);
  }
}
System.out.println(nums);

What is printed?

A [5, 15, 20]
B [5, 10, 15, 20]
C A ConcurrentModificationException is thrown.
D An IndexOutOfBoundsException is thrown.
Answer: A

This is a classic pitfall. When you remove an element from an ArrayList while iterating forward with a standard for loop, you change the size of the list and shift subsequent elements.

  • i=0: get(0) is 5. No removal.
  • i=1: get(1) is 10. remove(1) is called. The list is now [5, 15, 20]. The element that was at index 2 (15) is now at index 1.
  • The loop increments i to 2. It now checks get(2), which is 20. The element 15 at the new index 1 was skipped.
  • i=2: get(2) is 20. No removal. Loop ends. The correct way to remove during iteration is to iterate backward or use an Iterator. The code as written produces [5, 15, 20]. A ConcurrentModificationException is typically thrown with enhanced for-loops, not this indexed loop.
Question 28 of 41 · MEDIUM

Consider the following code segment.

int[][] matrix = new int[3][4];
System.out.println(matrix.length);
System.out.println(matrix[0].length);

What is the output?

A 3 4
B 4 3
C 12 4
D 3 12
Answer: A

In a 2D array type[][] arr = new type[rows][cols], arr.length gives the number of rows. arr[0].length (or arr[i].length for any valid row i) gives the number of columns. In this case, matrix is declared with 3 rows and 4 columns. Therefore, matrix.length is 3, and matrix[0].length is 4.

Question 29 of 41 · HARD

Consider the following method.

public boolean check(String s) {
  return s.substring(0, 1).equals("A") && s.length() > 5;
}

Which of the following calls will result in a StringIndexOutOfBoundsException?

A check("Apple")
B check("Banana")
C check("August")
D check("")
Answer: D

The expression s.substring(0, 1) is evaluated first. If the string s is empty, attempting to get a substring from index 0 to 1 will result in a StringIndexOutOfBoundsException because the string has no characters. This happens in check(""). For all other options, the string has at least one character, so the substring call is valid, and the && expression is evaluated (or short-circuited) without error.

Question 30 of 41 · MEDIUM

What will be the value of x after the following code executes?

int x = 10;
x += 5;
x /= 2;
x *= 3;
x -= 1;
A 21.5
B 22
C 21
D 20
Answer: D

This traces the use of compound assignment operators with integer arithmetic.

  1. x = 10; (x is 10)
  2. x += 5; (x becomes 10 + 5 = 15)
  3. x /= 2; (x becomes 15 / 2. This is integer division, so the result is 7, not 7.5)
  4. x *= 3; (x becomes 7 * 3 = 21)
  5. x -= 1; (x becomes 21 - 1 = 20) The final value of x is 20. The key is remembering that division of two integers results in an integer.
Question 31 of 41 · HARD

Consider the following code segment.

int count = 0;
for (int i = 0; i < 10; i++) {
  for (int j = i; j < 10; j++) {
    count++;
  }
}

What is the value of count after this code executes?

A 100
B 90
C 55
D 45
Answer: C

This nested loop's inner part depends on the outer loop's variable. Let's trace the number of inner loop iterations:

  • i=0: j goes from 0 to 9 (10 iterations)
  • i=1: j goes from 1 to 9 (9 iterations)
  • i=2: j goes from 2 to 9 (8 iterations)
  • ...
  • i=9: j goes from 9 to 9 (1 iteration) The total is the sum 10 + 9 + 8 + ... + 1. This is the sum of the first 10 integers, which is (10 * 11) / 2 = 55. Choice A (100) would be correct if the inner loop was j < 10. Choice D (45) is the sum from 1 to 9.
Question 32 of 41 · MEDIUM

A method signature is defined by which of the following?

A The method name and its parameter list.
B The method name, parameter list, and return type.
C The `public` or `private` access modifier.
D The code inside the method's curly braces.
Answer: A

In Java, the method signature consists of the method's name and the types and order of its parameters. This is what the compiler uses to distinguish between different methods, especially for overloading. The return type is NOT part of the method signature. The access modifier and the method body are also separate from the signature.

Question 33 of 41 · EASY

Which statement correctly creates a new ArrayList named names that can store String objects?

A ArrayList<String> names = new ArrayList<String>();
B ArrayList<String> names = new ArrayList();
C ArrayList names = new ArrayList<String>();
D String[] names = new ArrayList<String>();
Answer: A

The standard and most explicit way to declare and instantiate an ArrayList is shown in choice A. Choice B is also valid due to type inference (the 'diamond operator'), but A is the full form. Choice C uses a raw type, which is bad practice and generates a compiler warning. Choice D is incorrect because it tries to assign an ArrayList object to an array reference (String[]), which is a type mismatch.

Question 34 of 41 · EASY

What is the result of (15 % 4) and (15 / 4) in Java?

A Result of % is 3, result of / is 3
B Result of % is 1, result of / is 3
C Result of % is 3, result of / is 3.75
D Result of % is 1, result of / is 4
Answer: A

The modulus operator % gives the remainder of a division. 15 divided by 4 is 3 with a remainder of 3. So, 15 % 4 is 3. The division operator / with two integers performs integer division. 15 divided by 4 is 3.75, but the decimal part is truncated, so 15 / 4 is 3. Choice C is wrong because integer division truncates.

Question 35 of 41 · MEDIUM

Consider the following method.

public static void change(int[] data) {
  data[0] = 100;
}

// In main method
int[] arr = {1, 2, 3};
change(arr);
System.out.println(arr[0]);

What is printed?

A 1
B 100
C A NullPointerException is thrown.
D The code does not compile.
Answer: B

In Java, arrays are objects. When an array is passed as a parameter to a method, the reference to the array is passed by value. This means the method receives a copy of the reference, but that new reference still points to the original array object in memory. Therefore, any changes made to the contents of the array inside the method (like data[0] = 100;) will persist after the method returns, because the original array object itself was modified.

Question 36 of 41 · EASY

Consider the following code segment.

String s = "abcde";
System.out.println(s.indexOf("c"));
System.out.println(s.indexOf("f"));

What is the output?

A 3 -1
B 2 -1
C 2 An exception is thrown.
D 3 0
Answer: B

The indexOf method returns the index of the first occurrence of the specified character or substring. String indices are 0-based. The character 'c' is at index 2 in "abcde". If the specified character or substring is not found, indexOf returns -1. The character 'f' is not in the string, so s.indexOf("f") returns -1.

Question 37 of 41 · MEDIUM

Which of the following represents the correct hierarchy of concepts from most abstract to most concrete?

A Object -> Class -> Method
B Class -> Object -> Instance Variable
C Method -> Class -> Object
D Class -> Instance Variable -> Object
Answer: B

A Class is a blueprint or template. It is an abstract concept. An Object is a concrete instance created from that class blueprint. An Instance Variable is a piece of data that belongs to a specific object, making it part of the concrete implementation. So, the order from abstract to concrete is Class, then Object, then the details of the object like its instance variables.

Question 38 of 41 · MEDIUM

Consider the following code segment.

boolean a = true;
boolean b = false;
boolean c = false;

if (a || (b && c)) {
  System.out.print("1");
}
if (a && (b || c)) {
  System.out.print("2");
}

What is printed?

A 1
B 2
C 12
D Nothing is printed.
Answer: A

Let's evaluate the two if conditions. First if: a || (b && c) is true || (false && false). Because the first operand of || is true, the expression short-circuits and evaluates to true immediately. So, "1" is printed. Second if: a && (b || c) is true && (false || false). The expression in the parentheses (false || false) evaluates to false. The overall expression becomes true && false, which is false. The if block is not entered, and "2" is not printed. The final output is just "1".

Question 39 of 41 · HARD

A programmer wants to write a method that swaps the values of two integer primitive variables. Consider the following attempt:

public void swap(int a, int b) {
  int temp = a;
  a = b;
  b = temp;
}

// In another method:
int x = 5;
int y = 10;
swap(x, y);
// What are the values of x and y here?

Why does this swap method fail to change the values of x and y in the calling method?

A Because integers are objects and their references are swapped, not the objects themselves.
B Because primitive types are passed by value, so the method only receives copies of the original values.
C Because the `temp` variable goes out of scope before the method finishes.
D Because the method should have a `return` type to send the new values back.
Answer: B

This is a fundamental concept in Java. Primitive data types (int, double, boolean, etc.) are passed by value. This means that when swap(x, y) is called, the method receives copies of the values of x and y. The swap method successfully swaps its local copies (a and b), but this has no effect on the original variables (x and y) in the calling scope. Choice A is incorrect; integers are primitives, not objects. Choice C is incorrect; temp is used correctly within its scope. Choice D describes one way to work around this (e.g., return an array with the swapped values), but it doesn't explain why the original attempt failed.

Question 40 of 41 · HARD

Merge sort is a recursive sorting algorithm. What is the approximate time complexity of merge sort on an array of n elements in the average and worst cases?

A O(n)
B O(log n)
C O(n log n)
D O(n^2)
Answer: C

Merge sort is a highly efficient, comparison-based sorting algorithm. Its divide-and-conquer approach consistently gives it a time complexity of O(n log n) for all cases: best, average, and worst. This is a significant advantage over algorithms like quicksort (which has a worst-case of O(n^2)) and simple sorts like selection or insertion sort (which are O(n^2) on average).

Question 41 of 41 · EASY

Which of the following is NOT a valid way to comment in Java?

A // This is a comment.
B /* This is a comment. */
C /** This is a Javadoc comment. */
D # This is a comment.
Answer: D

Java has two main types of comments. Single-line comments start with //. Multi-line (or block) comments start with /* and end with */. A special form of block comment, starting with /**, is used for generating Javadoc documentation. The # symbol is used for comments in other languages like Python and shell scripts, but not in Java.

Section 2 — Free Response (4 questions)

FRQ #1: Vending Machine Simulation

FRQ #1 · Max 9 points

This question involves a VendingMachine class that simulates stocking and selling a single type of item.

You will write two methods for the VendingMachine class.

public class VendingMachine {
  private int itemsAvailable;
  private double revenue;
  private static final double ITEM_PRICE = 1.50;

  /**
   * Initializes a VendingMachine with a starting number of items.
   * @param initialItems the number of items to stock initially; initialItems >= 0
   */
  public VendingMachine(int initialItems) {
    itemsAvailable = initialItems;
    revenue = 0.0;
  }

  /**
   * Returns the number of items currently available in the machine.
   */
  public int getItemsAvailable() {
    return itemsAvailable;
  }

  /**
   * Returns the total revenue collected by the machine.
   */
  public double getRevenue() {
    return revenue;
  }

  /**
   * Attempts to sell a requested number of items.
   * @param requestedAmount the number of items a customer wants to buy; requestedAmount > 0
   * @return the number of items actually sold
   * to be implemented in part (a)
   */
  public int sellItems(int requestedAmount) {
    /* to be implemented in part (a) */
    return 0; // placeholder
  }

  /**
   * Simulates a day of sales by processing a given number of potential buyers.
   * @param numBuyers the number of buyers to simulate; numBuyers > 0
   * @return the total number of items sold during the simulation
   * to be implemented in part (b)
   */
  public int simulateDay(int numBuyers) {
    /* to be implemented in part (b) */
    return 0; // placeholder
  }

  // There may be other methods not shown.
}

Part A

Write the sellItems method. This method simulates a customer attempting to purchase requestedAmount items.

  • If the machine has enough items (i.e., itemsAvailable is greater than or equal to requestedAmount), the sale is successful. The method should decrease itemsAvailable by requestedAmount, increase revenue by the cost of the sold items, and return requestedAmount.
  • If the machine has fewer items than requestedAmount (but has at least one item), it sells all of its remaining items. The method should update itemsAvailable to 0, increase revenue by the cost of the items sold, and return the number of items that were sold (the original value of itemsAvailable).
  • If the machine is empty (itemsAvailable is 0), no sale can occur. The method should return 0, and no instance variables should be changed.

The cost of a single item is defined by the constant ITEM_PRICE.

Examples:

  • If itemsAvailable is 20 and revenue is 10.0, a call to sellItems(5) should return 5. After the call, itemsAvailable will be 15 and revenue will be 17.50 (10.0 + 5 * 1.50).
  • If itemsAvailable is 3 and revenue is 17.50, a call to sellItems(10) should return 3. After the call, itemsAvailable will be 0 and revenue will be 22.00 (17.50 + 3 * 1.50).
  • If itemsAvailable is 0, a call to sellItems(2) should return 0, and itemsAvailable remains 0.

Part B

Write the simulateDay method. This method simulates a day of sales with a specified number of numBuyers.

The simulation proceeds as follows:

  • The method should loop numBuyers times.
  • In each iteration of the loop, a single buyer attempts to purchase a random number of items between 1 and 4, inclusive. You can assume a method (int)(Math.random() * 4) + 1 correctly generates this random number.
  • You must call the sellItems method written in part (a) to handle each buyer's purchase attempt.
  • The simulateDay method should keep track of the total number of items sold across all buyers in the simulation.
  • After the loop finishes, the method should return the total number of items sold during the day.

Example: Suppose a VendingMachine object has 10 items. A call to simulateDay(3) might proceed as follows:

  1. Buyer 1 wants 3 items. sellItems(3) is called, 3 items are sold. Total sold so far: 3. Items left: 7.
  2. Buyer 2 wants 4 items. sellItems(4) is called, 4 items are sold. Total sold so far: 7. Items left: 3.
  3. Buyer 3 wants 2 items. sellItems(2) is called, 2 items are sold. Total sold so far: 9. Items left: 1. In this scenario, the call to simulateDay(3) would return 9.
Reveal sample answer + rubric
Sample answer
// Part (a)
public int sellItems(int requestedAmount) {
  int itemsSold = 0;
  if (itemsAvailable >= requestedAmount) {
    itemsSold = requestedAmount;
  } else {
    itemsSold = itemsAvailable;
  }

  if (itemsSold > 0) {
    itemsAvailable -= itemsSold;
    revenue += itemsSold * ITEM_PRICE;
  }

  return itemsSold;
}

// Part (b)
public int simulateDay(int numBuyers) {
  int totalItemsSoldToday = 0;
  for (int i = 0; i < numBuyers; i++) {
    int requested = (int) (Math.random() * 4) + 1;
    int soldThisTransaction = sellItems(requested);
    totalItemsSoldToday += soldThisTransaction;
  }
  return totalItemsSoldToday;
}
Rubric

Part (a) - sellItems (5 points)

  • 1 pt: Correctly determines the number of items to sell (handles both sufficient and insufficient stock cases).
  • 1 pt: Correctly updates itemsAvailable based on the number of items sold.
  • 1 pt: Corrects updates revenue using ITEM_PRICE and the number of items sold.
  • 1 pt: Returns the correct number of items sold.
  • 1 pt: Correctly handles the case where no items are sold (e.g., machine is empty or an invalid request), ensuring no change to instance variables and returning 0.

Part (b) - simulateDay (4 points)

  • 1 pt: Initializes a counter for total items sold to 0.
  • 1 pt: Implements a loop that iterates numBuyers times.
  • 1 pt: Correctly calls sellItems within the loop with a randomly generated amount.
  • 1 pt: Accumulates the result from sellItems and returns the final total.

FRQ #2: Social Media Profile

FRQ #2 · Max 9 points

In this question, you will write an entire class to model a simple social media profile. The Profile class keeps track of a user's name, their current status, and a list of their friends.

Your implementation must meet all specifications described below.

Part A

Class Definition and Instance Variables

Define the Profile class with the following private instance variables:

  • A String to store the user's name.
  • A String to store the user's current status message.
  • An ArrayList of String objects to store the names of the user's friends.

Part B

Constructor

Write a constructor for the Profile class that takes one String parameter for the username.

  • It should initialize the username instance variable with the value of the parameter.
  • It should initialize the status instance variable to the string "New user!".
  • It should initialize the friends list to a new, empty ArrayList of String objects.

Part C

Methods

Write the following three public methods for the Profile class.

  1. public void setStatus(String newStatus)

    • This method takes a String parameter and updates the user's status to this new value.
  2. public boolean addFriend(String friendName)

    • This method attempts to add a new friend to the user's friends list.
    • It should first check if the friendName is already in the friends list. To avoid duplicate entries, a name should only be added if it is not already present.
    • The method should return true if the friend was successfully added, and false otherwise (i.e., if the friend was already in the list).
  3. public String getProfileDisplay()

    • This method returns a formatted String representing the user's profile. The string should be in the following format: "Username: [username]\nStatus: [status]\nFriends ([count]): [friend1, friend2, ...]"
    • [username] is the user's name.
    • [status] is the user's current status.
    • [count] is the number of friends in the list.
    • [friend1, friend2, ...] is the string representation of the ArrayList of friends (the default toString() method of ArrayList is acceptable).

Example Execution:

Profile user1 = new Profile("alex_p");
user1.setStatus("Studying for APs!");
user1.addFriend("maya_g"); // returns true
user1.addFriend("carlos_r"); // returns true
user1.addFriend("maya_g"); // returns false

String display = user1.getProfileDisplay();
// display would be:
// "Username: alex_p
// Status: Studying for APs!
// Friends (2): [maya_g, carlos_r]"
Reveal sample answer + rubric
Sample answer
import java.util.ArrayList;

public class Profile {

  // Part (a)
  private String username;
  private String status;
  private ArrayList<String> friends;

  // Part (b)
  public Profile(String user) {
    this.username = user;
    this.status = "New user!";
    this.friends = new ArrayList<String>();
  }

  // Part (c)
  public void setStatus(String newStatus) {
    this.status = newStatus;
  }

  public boolean addFriend(String friendName) {
    if (!friends.contains(friendName)) {
      friends.add(friendName);
      return true;
    }
    return false;
  }

  public String getProfileDisplay() {
    String displayString = "Username: " + this.username + "\n";
    displayString += "Status: " + this.status + "\n";
    displayString += "Friends (" + friends.size() + "): " + friends.toString();
    return displayString;
  }
}
Rubric

Total 9 points

  • 1 pt: Correctly declares all three private instance variables with the correct types (String, String, ArrayList<String>).

Constructor (2 points)

  • 1 pt: Correctly defines a public constructor with one String parameter. Initializes username and status to the specified values.
  • 1 pt: Correctly instantiates the friends ArrayList as a new, empty list.

setStatus method (1 point)

  • 1 pt: Correctly implements the setStatus method to update the status instance variable.

addFriend method (2 points)

  • 1 pt: Correctly checks if the friendName is already contained in the friends list before adding.
  • 1 pt: Correctly adds the friend if not present and returns the appropriate boolean value in all cases (true on add, false on duplicate).

getProfileDisplay method (3 points)

  • 1 pt: Correctly includes the username and status in the returned string with proper labels and a newline character.
  • 1 pt: Correctly includes the friend count (using .size()) in the returned string.
  • 1 pt: Correctly includes the string representation of the friends list in the final output.

FRQ #3: Student Roster Analysis

FRQ #3 · Max 9 points

This question involves analyzing a roster of students stored in an array. A Student class is provided for you.

public class Student {
  private String name;
  private double gpa;

  /** Constructor and other methods are not shown. */

  public String getName() { /* implementation not shown */ }
  public double getGPA() { /* implementation not shown */ }
}

You will write two methods for the Roster class, which is partially defined below.

import java.util.ArrayList;

public class Roster {
  private Student[] students;

  /**
   * The students array is initialized in the constructor.
   * It contains no null elements and is sorted alphabetically by student name.
   */
  public Roster(Student[] studentArray) {
    students = studentArray;
  }

  /**
   * Finds the name of the first student in the roster with a specific GPA.
   * to be implemented in part (a)
   */
  public String findStudentWithGPA(double gpa) {
    /* to be implemented in part (a) */
    return null; // placeholder
  }

  /**
   * Returns a list of names of students who are on the honor roll.
   * to be implemented in part (b)
   */
  public ArrayList<String> getHonorRoll(double minGPA) {
    /* to be implemented in part (b) */
    return null; // placeholder
  }
}

Part A

Write the findStudentWithGPA method.

This method searches through the students array for the first student whose GPA is exactly equal to the gpa parameter. If such a student is found, the method should return that student's name. If the loop completes without finding any student with the matching GPA, the method should return null.

Example: If the students array contains Student objects with the following data: [{name:"Aaliyah", gpa:3.8}, {name:"Carlos", gpa:4.0}, {name:"Priya", gpa:3.8}]

A call to findStudentWithGPA(3.8) should return "Aaliyah", because she is the first student in the array with a 3.8 GPA. A call to findStudentWithGPA(3.9) should return null.

Part B

Write the getHonorRoll method.

This method creates and returns a new ArrayList<String> containing the names of all students in the students array whose GPA is greater than or equal to minGPA. The names in the returned ArrayList should appear in the same order as they appear in the students array.

If no students meet the minGPA requirement, the method should return an empty ArrayList.

Example: Using the same students array as in part (a): [{name:"Aaliyah", gpa:3.8}, {name:"Carlos", gpa:4.0}, {name:"Priya", gpa:3.8}]

A call to getHonorRoll(3.8) should return an ArrayList containing ["Aaliyah", "Carlos", "Priya"]. A call to getHonorRoll(4.0) should return an ArrayList containing ["Carlos"]. A call to getHonorRoll(4.1) should return an empty ArrayList [].

Reveal sample answer + rubric
Sample answer
import java.util.ArrayList;

public class Roster {
  private Student[] students;

  public Roster(Student[] studentArray) {
    students = studentArray;
  }

  // Part (a)
  public String findStudentWithGPA(double gpa) {
    for (int i = 0; i < students.length; i++) {
      if (students[i].getGPA() == gpa) {
        return students[i].getName();
      }
    }
    return null;
  }

  // Part (b)
  public ArrayList<String> getHonorRoll(double minGPA) {
    ArrayList<String> honorRollNames = new ArrayList<String>();
    for (Student s : students) {
      if (s.getGPA() >= minGPA) {
        honorRollNames.add(s.getName());
      }
    }
    return honorRollNames;
  }
}
Rubric

Part (a) - findStudentWithGPA (4 points)

  • 1 pt: Implements a loop that traverses the students array (either for or enhanced for).
  • 1 pt: Within the loop, correctly accesses a Student object and calls the getGPA method for comparison.
  • 1 pt: Correctly compares the student's GPA with the gpa parameter.
  • 1 pt: Returns the student's name upon finding the first match and returns null if the loop completes without a match.

Part (b) - getHonorRoll (5 points)

  • 1 pt: Initializes a new, empty ArrayList<String>.
  • 1 pt: Implements a loop that traverses the entire students array.
  • 1 pt: Within the loop, correctly accesses a Student object and calls the getGPA method.
  • 1 pt: Correctly compares the student's GPA to minGPA (using >=).
  • 1 pt: If the condition is met, adds the student's name (obtained via getName) to the ArrayList. Returns the created list after the loop.

FRQ #4: Image Processor

FRQ #4 · Max 9 points

This question involves manipulating a 2D array of integers that represents a grayscale image. You will write two methods for the Image class, which is partially defined below.

public class Image {
  private int[][] pixels;

  /**
   * The pixels array is initialized in the constructor with integer values
   * from 0 (black) to 255 (white), inclusive. The array is rectangular
   * (all rows have the same length) and has at least one row and one column.
   */
  public Image(int[][] pixelData) {
    pixels = pixelData;
  }

  /**
   * Brightens every pixel in the image.
   * to be implemented in part (a)
   */
  public void brighten(int amount) {
    /* to be implemented in part (a) */
  }

  /**
   * Calculates the average pixel value in a specified square region.
   * to be implemented in part (b)
   */
  public double getRegionAverage(int row, int col) {
    /* to be implemented in part (b) */
    return 0.0; // placeholder
  }

  // Other methods not shown.
}

Part A

Write the brighten method.

This method increases the value of every pixel in the pixels grid by the given amount. There is an upper limit for pixel values: a pixel's value cannot exceed 255. If adding amount to a pixel's value would cause it to exceed 255, its new value should be set to 255.

Example: If pixels is {{10, 250}, {100, 200}} and brighten(20) is called, the pixels array should be modified to become {{30, 255}, {120, 220}}.

Part B

Write the getRegionAverage method.

This method calculates and returns the average value of all pixels in the 3x3 square region centered at the given row and col. The 3x3 region includes the center pixel at (row, col) and its eight immediate neighbors.

The method must correctly handle edge cases where the 3x3 region extends beyond the boundaries of the pixels grid. In such cases, only the pixels that are actually within the grid's bounds should be included in the calculation of the average. The average is the sum of the values of the valid pixels in the region divided by the number of valid pixels in that region.

Example: Consider the following pixels grid:

{{10, 20, 30},
 {40, 50, 60},
 {70, 80, 90}}
  • A call to getRegionAverage(1, 1) should consider all 9 pixels, and the average is (10+20+30+40+50+60+70+80+90)/9 = 50.0.
  • A call to getRegionAverage(0, 0) should consider the 4 pixels in the top-left corner (10, 20, 40, 50), and the average is (10+20+40+50)/4 = 30.0.
  • A call to getRegionAverage(2, 1) should consider the 6 pixels in the bottom-middle region, and the average is (40+50+60+70+80+90)/6 = 65.0.
Reveal sample answer + rubric
Sample answer
public class Image {
  private int[][] pixels;

  public Image(int[][] pixelData) {
    pixels = pixelData;
  }

  // Part (a)
  public void brighten(int amount) {
    for (int r = 0; r < pixels.length; r++) {
      for (int c = 0; c < pixels[0].length; c++) {
        int newValue = pixels[r][c] + amount;
        if (newValue > 255) {
          pixels[r][c] = 255;
        } else {
          pixels[r][c] = newValue;
        }
        // A more concise way: pixels[r][c] = Math.min(255, pixels[r][c] + amount);
      }
    }
  }

  // Part (b)
  public double getRegionAverage(int row, int col) {
    int sum = 0;
    int count = 0;

    for (int r = row - 1; r <= row + 1; r++) {
      for (int c = col - 1; c <= col + 1; c++) {
        // Check if the coordinates are within the grid bounds
        if (r >= 0 && r < pixels.length && c >= 0 && c < pixels[0].length) {
          sum += pixels[r][c];
          count++;
        }
      }
    }

    if (count == 0) {
        return 0.0; // Avoid division by zero, though problem implies this won't happen.
    }

    return (double) sum / count;
  }
}
Rubric

Part (a) - brighten (4 points)

  • 1 pt: Implements a nested loop to traverse every element of the pixels 2D array.
  • 1 pt: Correctly accesses each pixel's value inside the loop.
  • 1 pt: Adds the amount to the pixel value.
  • 1 pt: Correctly handles the upper bound, setting the value to 255 if it exceeds 255 and updating the array element.

Part (b) - getRegionAverage (5 points)

  • 1 pt: Initializes accumulator variables for sum and count.
  • 1 pt: Implements a nested loop that correctly defines the 3x3 region around the given (row, col) (e.g., iterating from row-1 to row+1).
  • 1 pt: Includes a check within the loop to ensure that the row and column indices being accessed are valid (within the bounds of the pixels array).
  • 1 pt: Correctly accumulates the sum and increments the count for valid pixels only.
  • 1 pt: Calculates and returns the correct average ((double) sum / count). Handles the cast to double for floating-point division.