Free for students · Ad-free · WCAG 2.1 AA Compliant · Accessibility
Settings & Accessibility
AP Computer Science A — Pattern-Matched Mock
A full-length mock exam focusing on core data structures (Arrays, ArrayLists, 2D Arrays) and class design, mirroring the official College Board FRQ style.
--:--:--
Section 1 — Multiple Choice (40 questions)
Question 1 of 40 · EASY
What is the value of the expression (double) (7 / 2) + 7 / 2.0?
A6.5
B7.0
C7.5
D8.0
Answer: A —
Let's break this down! The first part is (7 / 2). Since both 7 and 2 are integers, Java performs integer division, which truncates any remainder. So, 7 / 2 evaluates to 3, not 3.5. Then, (double) 3 casts this result to 3.0. The second part is 7 / 2.0. Because 2.0 is a double, Java promotes the 7 to 7.0 and performs floating-point division, resulting in 3.5. Finally, 3.0 + 3.5 gives us 6.5. A common mistake is to think the cast (double) applies to the division itself, but it only applies after the integer division has already happened!
What is printed as a result of executing the code segment?
ACS-A-ROCKS-AP
BC-AP
CCS-A-ROCKS-AP-CS-A-ROCKS
DC-A
Answer: A —
This question tests your understanding of substring and indexOf. Let's trace it. str.indexOf("C") finds the index of 'C', which is 3. str.substring(3) will give you the rest of the string from that index onward, so part1 becomes "CS-A-ROCKS". Next, str.indexOf("-") finds the first hyphen at index 2. str.substring(0, 2) gives you the characters from index 0 up to (but not including) index 2. So, part2 becomes "AP". Finally, the println statement concatenates these with a hyphen in between: "CS-A-ROCKS" + "-" + "AP", which results in "CS-A-ROCKS-AP".
Question 3 of 40 · EASY
A student is writing a program to calculate the total cost of an online order. The shippingCost should be $5.99 unless the orderTotal is $50.00 or more, in which case shipping is free. Which of the following code segments correctly calculates shippingCost?
This is a classic if-else scenario. We need to handle both conditions. Choice B correctly sets shippingCost to 0.0 if the orderTotal is greater than or equal to 50.00, and to 5.99 otherwise. Choice A is a common mistake; it sets shippingCost to 0.0 but then immediately overwrites it with 5.99 in all cases. Choice C doesn't handle the case where orderTotal is 50.00 or more, leaving shippingCost uninitialized. Choice D is very close, but the condition > 50.00 misses the case where the total is exactly $50.00, which should get free shipping.
Question 4 of 40 · HARD
Consider the following method.
public void loopMystery(int n) {
int x = 0;
for (int i = 1; i < n; i *= 2) {
for (int j = 0; j < i; j++) {
x++;
}
}
System.out.println(x);
}
What is printed by the call loopMystery(10)?
A7
B10
C15
D16
Answer: C —
Let's trace the nested loops carefully. The outer loop variable i starts at 1 and doubles each time, as long as it's less than n (which is 10).
When i is 1: The inner loop runs from j = 0 to j < 1 (1 time). x becomes 1.
When i is 2: The inner loop runs from j = 0 to j < 2 (2 times). x becomes 1 + 2 = 3.
When i is 4: The inner loop runs from j = 0 to j < 4 (4 times). x becomes 3 + 4 = 7.
When i is 8: The inner loop runs from j = 0 to j < 8 (8 times). x becomes 7 + 8 = 15.
The next value for i would be 16, which is not less than 10, so the outer loop terminates. The final value of x is 15.
Question 5 of 40 · EASY
Which of the following best describes the purpose of a constructor in a Java class?
ATo create a copy of an existing object.
BTo initialize the state of a newly created object.
CTo define the behavior that an object can perform.
DTo return the memory address of an object.
Answer: B —
This is a core concept of object-oriented programming! A constructor's job is to run when you create a new object (using the new keyword) and set up its initial state. This means assigning starting values to its instance variables. Choice A describes a copy constructor or clone method, not a general constructor. Choice C describes the purpose of methods, not constructors. Choice D is an implementation detail handled by the Java Virtual Machine, not the purpose of a constructor.
Question 6 of 40 · MEDIUM
Consider the following class definition.
public class Gadget {
private static int count = 0;
private int id;
public Gadget() {
id = count;
count++;
}
public int getId() {
return id;
}
public static int getCount() {
return count;
}
}
And the following code segment in another class:
Gadget g1 = new Gadget();
Gadget g2 = new Gadget();
Gadget g3 = new Gadget();
System.out.println(g2.getId() + " " + Gadget.getCount());
What is printed when the code segment is executed?
A1 3
B2 3
C1 2
D2 2
Answer: A —
This question tests the difference between static and instance variables. The count variable is static, meaning it's shared across all Gadget objects. The id variable is an instance variable, so each Gadget gets its own copy.
new Gadget() (for g1): id is set to the current count (0), then count becomes 1. So, g1.id is 0.
new Gadget() (for g2): id is set to the current count (1), then count becomes 2. So, g2.id is 1.
new Gadget() (for g3): id is set to the current count (2), then count becomes 3. So, g3.id is 2.
The print statement asks for g2.getId(), which returns g2's personal id value: 1. Then it asks for Gadget.getCount(), which returns the final value of the shared static variable count: 3. So, the output is 1 3.
Question 7 of 40 · HARD
A program uses an ArrayList of Integer objects called scores. Which of the following code segments will cause a compile-time error?
A```java
for (int i = 0; i < scores.size(); i++) {
if (scores.get(i) == 100) {
System.out.println("Perfect score!");
}
}
```
B```java
for (Integer score : scores) {
if (score < 60) {
scores.remove(score);
}
}
```
C```java
int sum = 0;
for (int score : scores) {
sum += score;
}
```
D```java
scores.add(0, 50);
```
Answer: B —
This is a very important rule to remember! You cannot modify the structure of an ArrayList (by adding or removing elements) while you are iterating over it using an enhanced for-each loop. Doing so will throw a ConcurrentModificationException at runtime, and many compilers will flag this as a potential error. Choice B attempts to remove an element during a for-each loop, which is forbidden. Choices A, C, and D are all valid ways to interact with an ArrayList. To correctly remove elements while iterating, you must use a standard for loop and carefully manage the index, usually by iterating backward.
Question 8 of 40 · MEDIUM
Consider the following code segment.
int[] arr = {10, 20, 30, 40, 50};
for (int i = 0; i < arr.length / 2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
What are the contents of arr after the code has been executed?
A{50, 40, 30, 20, 10}
B{50, 40, 30, 40, 50}
C{30, 40, 10, 20, 50}
D{10, 20, 30, 40, 50}
Answer: A —
This code segment is a classic algorithm for reversing an array in place. Let's trace it. The loop runs for i from 0 up to arr.length / 2, which is 5 / 2 = 2. So i will be 0 and 1.
When i = 0: It swaps arr[0] (value 10) with arr[5 - 1 - 0] which is arr[4] (value 50). The array becomes {50, 20, 30, 40, 10}.
When i = 1: It swaps arr[1] (value 20) with arr[5 - 1 - 1] which is arr[3] (value 40). The array becomes {50, 40, 30, 20, 10}.
The loop then terminates. The middle element arr[2] (value 30) is never touched, which is correct for reversing an array with an odd number of elements. The final result is the reversed array.
Question 9 of 40 · EASY
A two-dimensional array matrix is created as follows: int[][] matrix = new int[4][5];. What is the total number of elements in matrix?
A4
B5
C9
D20
Answer: D —
When you create a 2D array like new int[rows][cols], you are creating a grid. The first number specifies the number of rows, and the second number specifies the number of columns. The total number of elements is simply the number of rows multiplied by the number of columns. In this case, it's 4 rows * 5 columns = 20 elements.
Question 10 of 40 · MEDIUM
Consider the following incomplete recursive method intended to compute the sum of the digits of a non-negative integer n.
public int sumDigits(int n) {
if (n < 10) {
return n;
} else {
// MISSING CODE
}
}
Which of the following can be used to replace // MISSING CODE so that the method works as intended?
Areturn n % 10 + sumDigits(n / 10);
Breturn n / 10 + sumDigits(n % 10);
Creturn sumDigits(n / 10);
Dreturn n % 10 + sumDigits(n - 1);
Answer: A —
This is a classic recursion problem. The base case, n < 10, correctly handles single-digit numbers by returning the number itself. For the recursive step, we need to break the problem down. The sum of the digits of a number (like 123) is the last digit (3) plus the sum of the digits of the rest of the number (12). In Java, we get the last digit with the modulo operator: n % 10. We get the rest of the number by using integer division: n / 10. Therefore, the recursive step should be to return the last digit (n % 10) plus the result of calling the function on the rest of the number (sumDigits(n / 10)). Choice A correctly implements this logic.
Question 11 of 40 · MEDIUM
Which of the following boolean expressions is equivalent to !(a && b) || c?
A(!a || !b) || c
B(!a && !b) || c
C(!a || !b) && c
Da || b || c
Answer: A —
This question tests your knowledge of De Morgan's laws. De Morgan's laws state that !(A && B) is equivalent to (!A || !B), and !(A || B) is equivalent to (!A && !B). In our expression, we have !(a && b). Applying the first law, this part becomes (!a || !b). So the entire expression !(a && b) || c becomes (!a || !b) || c. Since the || operator is associative, the parentheses are not strictly necessary, but choice A shows the direct substitution.
Question 12 of 40 · EASY
Consider the Robot class which has a method move() that moves a robot one step forward. A programmer wants to make a robot move n steps. Which of the following is the most appropriate control structure to use?
AAn `if` statement
BA `for` loop
CA `switch` statement
DA `try-catch` block
Answer: B —
When you need to repeat an action a specific, known number of times, a for loop is the perfect tool. In this case, we want to call the move() method exactly n times. A for loop like for (int i = 0; i < n; i++) { robot.move(); } is the standard and most readable way to accomplish this. An if statement only executes once. A switch statement is for choosing one path out of many based on a value. A try-catch block is for handling errors (exceptions).
Question 13 of 40 · EASY
What is the result of Math.pow(2, 3) + Math.sqrt(16)?
A12.0
B10.0
C14.0
D8.0
Answer: A —
This question checks your familiarity with the Math class. Math.pow(base, exponent) calculates the base raised to the power of the exponent. So, Math.pow(2, 3) is 2³, which is 8.0. Math.sqrt(number) calculates the square root of a number. So, Math.sqrt(16) is 4.0. Both methods return a double. The final calculation is 8.0 + 4.0, which equals 12.0.
Question 14 of 40 · EASY
Given int x = 5, y = 10;, which of the following expressions evaluates to true?
A`x > 5 && y < 10`
B`x >= 5 && y <= 10`
C`x > 5 || y > 10`
D`!(x == 5)`
Answer: B —
Let's evaluate each choice with x = 5 and y = 10.
A: 5 > 5 is false. Since it's an && (AND), the whole expression is false immediately.
B: 5 >= 5 is true. 10 <= 10 is true. true && true is true. This is our answer.
C: 5 > 5 is false. 10 > 10 is false. false || false is false.
D: x == 5 is true. !(true) is false.
This question highlights the importance of understanding the difference between > (greater than) and >= (greater than or equal to).
Question 15 of 40 · MEDIUM
Consider the following code segment.
ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add(1, "X");
list.set(3, "Y");
list.remove(0);
System.out.println(list);
What is printed as a result of executing the code segment?
A[X, C, Y]
B[X, B, Y]
C[B, C, Y]
D[A, X, Y]
Answer: B —
This is a great exercise in tracing ArrayList modifications. Let's go step-by-step:
list is [A, B, C]
list.add(1, "X"): This inserts "X" at index 1, shifting everything else to the right. list becomes [A, X, B, C].
list.set(3, "Y"): This replaces the element at index 3 with "Y". list becomes [A, X, B, Y].
list.remove(0): This removes the element at index 0. list becomes [X, B, Y].
Finally, printing the list gives us [X, B, Y].
Question 16 of 40 · EASY
Which of the following is NOT a primitive data type in Java?
Aint
Bboolean
CString
Ddouble
Answer: C —
This is a fundamental concept in Java. The primitive types are the basic building blocks of data: int, double, char, boolean, long, short, byte, and float. String, on the other hand, is an object type. You can tell because it's capitalized (by convention) and you can call methods on it (like .length() or .substring()). Primitive types are just simple values and don't have methods.
Question 17 of 40 · MEDIUM
Consider the following method.
public static int mystery(int[] arr) {
int result = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
result += arr[i];
} else {
result -= arr[i];
}
}
return result;
}
What is returned by the call mystery(new int[]{1, 2, 3, 4, 5})?
A-3
B15
C6
D-1
Answer: A —
Let's trace the method with the given array {1, 2, 3, 4, 5}. The method adds even numbers and subtracts odd numbers.
result starts at 0.
arr[0] is 1 (odd): result becomes 0 - 1 = -1.
arr[1] is 2 (even): result becomes -1 + 2 = 1.
arr[2] is 3 (odd): result becomes 1 - 3 = -2.
arr[3] is 4 (even): result becomes -2 + 4 = 2.
arr[4] is 5 (odd): result becomes 2 - 5 = -3.
The loop finishes, and the method returns the final value of result, which is -3.
Question 18 of 40 · HARD
Which of the following statements about interfaces and abstract classes in Java is true for the AP Computer Science A subset?
AA class can implement multiple interfaces but can only extend one abstract class.
BAn interface can contain instance variables.
CAn abstract class cannot have a constructor.
DA class can extend multiple abstract classes.
Answer: A —
While interfaces and abstract classes are not a major topic on the exam, understanding their basic properties is helpful. The key difference is that Java supports multiple inheritance of type (through interfaces) but not multiple inheritance of state (through classes). Therefore, a class can implement many interfaces, but it can only extend one parent class (whether abstract or concrete). Choice B is incorrect; interfaces can only have public static final constants, not instance variables. Choice C is incorrect; abstract classes can and often do have constructors to initialize their fields, which are called by subclass constructors. Choice D is incorrect for the reason mentioned above.
Question 19 of 40 · MEDIUM
What is the purpose of the this keyword in Java?
AIt refers to the superclass of the current object.
BIt is used to create a new instance of a class.
CIt refers to the current object instance.
DIt refers to a static method in the class.
Answer: C —
The this keyword is a reference to the current object—the object whose method or constructor is being called. It's most commonly used to distinguish between an instance variable and a parameter with the same name. For example, in a constructor public Student(String name) { this.name = name; }, this.name refers to the instance variable, while name refers to the parameter. It's a way for an object to talk about itself.
What are the values of b1 and b2 after this code executes?
A`b1` is true, `b2` is true
B`b1` is true, `b2` is false
C`b1` is false, `b2` is true
D`b1` is false, `b2` is false
Answer: B —
This is a crucial and often tricky concept! When you use == with objects like String, you are comparing their memory addresses, not their content. Because Java is efficient, string literals like "hello" are often pooled. This means s1 and s2 point to the exact same object in memory, so s1 == s2 is true. However, when you use new String("hello"), you are explicitly telling Java to create a brand new object in a different memory location, even though it contains the same characters. Therefore, s1 and s3 point to different objects, and s1 == s3 is false. To compare the actual content of strings, you should always use the .equals() method, e.g., s1.equals(s3) would be true.
Question 21 of 40 · MEDIUM
A binary search algorithm is used to find a value in a sorted array. Which of the following is a necessary precondition for the algorithm to work correctly?
AThe array must not contain any duplicate values.
BThe array must be sorted.
CThe array must have an odd number of elements.
DThe array must only contain positive integers.
Answer: B —
The single most important requirement for a binary search is that the data must be sorted. The entire algorithm is based on the ability to eliminate half of the remaining search space with each comparison by knowing whether to look in the lower half or the upper half. If the array isn't sorted, this logic completely breaks down. While implementations might vary in how they handle duplicates (choice A), they can still function. The number of elements (choice C) and the type of values (choice D) do not affect the fundamental requirement of the algorithm.
Question 22 of 40 · EASY
Consider the following 2D array grid.
{ {1, 2, 3},
{4, 5, 6},
{7, 8, 9} }
What is the value of grid[1][2]?
A2
B4
C6
D8
Answer: C —
Accessing elements in a 2D array uses the format array[row][column], and remember that indices are 0-based! The first index, 1, refers to the row number. Row 0 is {1, 2, 3}, so row 1 is {4, 5, 6}. The second index, 2, refers to the column number within that row. In row 1, column 0 is 4, column 1 is 5, and column 2 is 6. Therefore, grid[1][2] is 6.
Question 23 of 40 · MEDIUM
What is the process of hiding implementation details from the user and only exposing functionality called?
AInheritance
BPolymorphism
CEncapsulation
DRecursion
Answer: C —
This is the definition of encapsulation! Think of it like a car. You, the driver, are given a simple interface (steering wheel, pedals, gear shift) to use the car. You don't need to know the complex details of how the engine, transmission, or electronics work. In programming, we achieve this by making instance variables private (hiding the details) and providing public methods (exposing the functionality) to interact with them. This protects the data and makes the class easier to use.
Question 24 of 40 · MEDIUM
Consider the following code segment.
int count = 0;
for (int r = 0; r < matrix.length; r++) {
for (int c = 0; c < matrix[0].length; c++) {
if (matrix[r][c] < 0) {
count++;
}
}
}
Assuming matrix is a rectangular 2D array, what does this code segment compute?
AThe number of rows with at least one negative number.
BThe total number of elements in the matrix.
CThe number of negative numbers in the matrix.
DThe sum of all negative numbers in the matrix.
Answer: C —
This code uses a standard nested loop to traverse every element in a 2D array. This is often called a row-major traversal. The outer loop iterates through the rows (r), and the inner loop iterates through the columns (c) of each row. Inside the inner loop, it checks if the current element matrix[r][c] is less than 0 (i.e., negative). If it is, it increments the count variable. It doesn't sum the values (like in D) or just check for the presence in a row (like in A). It simply counts every single negative number, so C is the correct answer.
Question 25 of 40 · MEDIUM
Which sorting algorithm works by repeatedly finding the minimum element from the unsorted part of an array and putting it at the beginning of the unsorted part?
AInsertion Sort
BSelection Sort
CMerge Sort
DBinary Sort
Answer: B —
This is the definition of Selection Sort. Think of it as 'selecting' the smallest remaining item in each pass. In the first pass, it finds the smallest element in the entire array and swaps it with the first element. In the second pass, it finds the smallest element in the rest of the array (from the second element onward) and swaps it with the second element, and so on. 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 Sort isn't a standard sorting algorithm name; it's likely a confusion with binary search.
Question 26 of 40 · MEDIUM
A while loop is most appropriate for which of the following situations?
AIterating through all elements of an `ArrayList`.
BRepeating a block of code a fixed number of times, say 100.
CRepeating a block of code until a certain condition, which is not based on a counter, becomes false.
DChoosing between two different blocks of code to execute.
Answer: C —
While you can use a while loop for situations A and B, they are better suited for for loops (a for-each loop for A, and a standard for loop for B). The true strength of a while loop is when the number of iterations is not known beforehand. For example, reading user input until they type 'quit', or processing items from a queue until it's empty. The loop continues as long as a condition is met, making it perfect for event-driven or condition-driven repetition. Choice D describes an if-else statement.
Question 27 of 40 · EASY
What is the value of x after the following code executes?
int x = 10;
x += 5;
x /= 3;
A3
B5
C5.0
D6
Answer: B —
This question tests compound assignment operators and integer division.
int x = 10; : x is 10.
x += 5; : This is shorthand for x = x + 5;. So x becomes 10 + 5 = 15.
x /= 3; : This is shorthand for x = x / 3;. Since x is an integer, this is integer division. 15 / 3 is 5. So x becomes 5.
The final value of x is 5.
Question 28 of 40 · MEDIUM
Consider the following method call: Integer.parseInt("123"). What is the type of the returned value?
AString
BInteger
Cint
Ddouble
Answer: C —
This is a very useful method from the Integer wrapper class. Its job is to take a String that represents a number and convert it into the primitive data type int. While the method belongs to the Integer class, its return type is the primitive int. This is a common point of confusion. The method Integer.valueOf("123") would return an Integer object.
Question 29 of 40 · EASY
If word is a String object, what does word.length() return?
AThe number of characters in the string.
BThe number of bytes the string occupies in memory.
CThe last character of the string.
DThe index of the last character of the string.
Answer: A —
The length() method of the String class returns the total number of characters in the string. Don't confuse this with the lengthproperty of an array (arr.length), which is not a method call. Also, remember that the index of the last character is word.length() - 1 because strings (and arrays) are 0-indexed.
Question 30 of 40 · MEDIUM
Consider the following recursive method.
public static int rec(int n) {
if (n <= 1) {
return 1;
} else {
return n * rec(n - 2);
}
}
What is returned by the call rec(5)?
A15
B120
C5
DThe code results in an infinite recursion.
Answer: A —
Let's trace the recursive calls:
rec(5) is called. Since 5 > 1, it returns 5 * rec(3).
rec(3) is called. Since 3 > 1, it returns 3 * rec(1).
rec(1) is called. Since 1 <= 1, it hits the base case and returns 1.
Now, let's substitute the values back up the call stack:
The rec(3) call becomes 3 * 1, which is 3.
The original rec(5) call becomes 5 * 3, which is 15.
The final result is 15.
Question 31 of 40 · HARD
A programmer has two boolean variables, isMember and hasCoupon. A discount applies if the person is a member OR has a coupon, but not if they are a member AND have a coupon. Which expression correctly represents this condition?
This logic describes the exclusive OR (XOR) operation. The customer gets a discount if one condition is true, but not both. Let's break down choice B: (isMember || hasCoupon) checks if they are a member OR have a coupon (or both). This part is true if they qualify for any discount. !(isMember && hasCoupon) checks if they are NOT both a member AND have a coupon. By combining these with &&, we enforce that the first part is true AND the second part is true, which perfectly matches the requirement. Choice A is a simple OR, which would include the case where both are true.
Question 32 of 40 · MEDIUM
Which of the following code segments correctly creates an ArrayList named names and adds the string "Alice" to it?
A```java
ArrayList names = new ArrayList();
names.add("Alice");
```
B```java
ArrayList<String> names = new ArrayList<String>();
names.add("Alice");
```
C```java
ArrayList<String> names = new ArrayList<String>();
names[0] = "Alice";
```
D```java
ArrayList<String> names = new ArrayList();
names.add("Alice");
```
Answer: B —
Choice B shows the complete and correct syntax for creating a generic ArrayList. The <String> part specifies that this list will only hold String objects, which is a good practice called using generics. Choice A creates a raw, non-generic ArrayList, which is outdated and less safe, but it would compile with warnings. Choice C tries to use array syntax ([]) to add an element, which is incorrect for an ArrayList; you must use the .add() method. Choice D is also correct in modern Java (Java 7+), as the type can be inferred on the right side (this is called the 'diamond operator'). However, Choice B is the most explicit and universally correct syntax taught in AP CS A.
Question 33 of 40 · EASY
What is the output of the following code?
System.out.println(15 % 4);
A3
B3.75
C4
D1
Answer: A —
The % symbol is the modulo operator, which gives you the remainder of a division. When you divide 15 by 4, it goes in 3 times (3 * 4 = 12), and there is a remainder of 3 (15 - 12 = 3). So, 15 % 4 evaluates to 3.
Question 34 of 40 · EASY
Consider the Book class which has a constructor public Book(String title). Which of the following is a valid way to create a Book object?
A`Book myBook = Book("The Great Gatsby");`
B`Book myBook = new Book();`
C`Book myBook = new Book("The Great Gatsby");`
D`new Book myBook = ("The Great Gatsby");`
Answer: C —
To create an object (instantiate a class), you must use the new keyword, followed by a call to one of the class's constructors. The Book class has a constructor that takes a String argument. Choice C correctly uses the new keyword and passes the required string to the constructor. Choice A is missing new. Choice B is trying to call a no-argument constructor, which hasn't been defined in this case. Choice D has incorrect syntax.
Question 35 of 40 · HARD
An algorithm's efficiency is described as O(n²). How does the runtime of the algorithm typically change if the input size n is doubled?
AIt stays the same.
BIt doubles.
CIt quadruples.
DIt increases by 2.
Answer: C —
This question is about informal run-time analysis (Big O notation). O(n²) means the runtime is proportional to the square of the input size n. Let the original runtime be T ≈ k n². If we double the input size to 2n, the new runtime T' will be T' ≈ k (2n)² = k (4n²) = 4 (k n²) = 4 T. So, the runtime quadruples (increases by a factor of 4). This is characteristic of algorithms with nested loops that both iterate over the input, like a basic selection sort.
String s = "Hi";
int[] a = {1, 2, 3};
changeUp(s, a);
System.out.println(s + " " + a[0]);
What is printed when the code segment is executed?
AHi!!! 99
BHi 99
CHi!!! 1
DHi 1
Answer: B —
This question tests the crucial difference between how primitive types/Strings (pass-by-value) and arrays/objects (pass-by-reference-value) behave as parameters. When a (an array) is passed to the method, the method receives a copy of the reference, which still points to the original array in memory. Therefore, changing arr[0] inside the method changes the original array. However, String objects are immutable. When s is passed, the line str += "!!!" does not change the original string s. Instead, it creates a new string "Hi!!!" and makes the local variable str point to it. The original s in the calling code remains unchanged. So, s is still "Hi" and a[0] is 99.
Question 37 of 40 · MEDIUM
Which of the following loops will execute its body exactly 5 times?
A`for (int i = 1; i < 5; i++)`
B`for (int i = 0; i <= 5; i++)`
C`for (int i = 5; i > 0; i--)`
D`for (int i = 1; i < 6; i += 2)`
Answer: C —
Let's count the iterations for each loop:
A: i will be 1, 2, 3, 4. That's 4 times.
B: i will be 0, 1, 2, 3, 4, 5. That's 6 times.
C: i will be 5, 4, 3, 2, 1. That's 5 times. This is the correct answer.
D: i will be 1, 3, 5. That's 3 times.
This is a good reminder to be very careful with your loop bounds (< vs <=) and starting/ending values.
Question 38 of 40 · HARD
A Food class and a Fruit class are defined, where Fruit is a subclass of Food. Given the declarations Food f = new Food(); and Fruit a = new Fruit();, which of the following statements will cause a compile-time error?
A`f = a;`
B`a = f;`
C`Object o = a;`
D`System.out.println(a);`
Answer: B —
This question tests polymorphism and casting. You can always assign a subclass object to a superclass variable (this is called upcasting), because a Fruitis aFood. So, f = a; (Choice A) is perfectly fine. However, you cannot assign a superclass object to a subclass variable directly. The object f is just a Food, it might not be a Fruit (it could be a Vegetable). The compiler prevents this with an error, so a = f; (Choice B) is illegal. To make it work, you would need an explicit cast a = (Fruit)f;, which would then risk a ClassCastException at runtime if f wasn't actually a Fruit.
Question 39 of 40 · EASY
Which of the following is a primary ethical concern related to the collection and analysis of large data sets, as discussed in the AP CS A framework?
AThe computational cost of processing the data.
BThe difficulty of choosing the right sorting algorithm.
CThe potential for revealing personally identifiable information (PII) and violating privacy.
DThe limited storage capacity of modern computers.
Answer: C —
While computational cost and algorithm choice are technical challenges, the primary ethical concern is about the impact on people. Large data sets, even when anonymized, can often be 'de-anonymized' by cross-referencing with other data sets, potentially exposing sensitive personal information. This raises significant privacy issues that programmers and data scientists must consider. The AP curriculum emphasizes the importance of being responsible with the data we handle.
This is a clever way to count occurrences of a character. Let's trace the while loop:
Initial:str is "banana", count is 0. str.indexOf("a") is 1, which is not -1. Loop enters.
Iteration 1:count becomes 1. str.indexOf("a") is 1. str becomes str.substring(1 + 1), which is str.substring(2), so str is now "nana".
Loop check:str is "nana". str.indexOf("a") is 1, not -1. Loop enters.
Iteration 2:count becomes 2. str.indexOf("a") is 1. str becomes str.substring(1 + 1), which is str.substring(2), so str is now "na".
Loop check:str is "na". str.indexOf("a") is 1, not -1. Loop enters.
Iteration 3:count becomes 3. str.indexOf("a") is 1. str becomes str.substring(1 + 1), which is str.substring(2), so str is now "".
Loop check:str is "". str.indexOf("a") is -1. The loop condition is false, and the loop terminates.
The final value of count, 3, is printed.
Section 2 — Free Response (4 questions)
FRQ #1: Vending Machine
FRQ #1 · Max 9 points
This question involves a VendingMachine class that manages a collection of Snack items. You will write two methods of the VendingMachine class.
A Snack class is defined to represent an item in the vending machine. You do not need to write the Snack class, but you should assume it has the following methods:
public double getPrice(): Returns the price of the snack.
public int getQuantity(): Returns the number of this snack available.
public void setQuantity(int q): Updates the quantity of this snack.
public class VendingMachine {
/** A list of all snacks in the machine; initialized in the constructor */
private ArrayList<Snack> slots;
/**
* Simulates a user selecting a snack from a given slot number.
* Updates the quantity of the snack and returns its price.
* @param slotNumber the index of the selected snack in slots
* @return the price of the snack if it is available (quantity > 0);
* otherwise, returns -1.0
* Precondition: 0 <= slotNumber < slots.size()
*/
public double selectSnack(int slotNumber) {
/* to be implemented in part (a) */
}
/**
* Simulates a user attempting to purchase multiple snacks.
* @param selections an array of slot numbers for the desired snacks
* @return the total number of snacks successfully purchased
* Postcondition: The quantity of each successfully purchased snack is decremented.
*/
public int purchaseSnacks(int[] selections) {
/* to be implemented in part (b) */
}
// There may be instance variables, constructors, or methods that are not shown.
}
Part A
Write the selectSnack method. This method simulates a user selecting a single snack from the vending machine. It should check if the snack at the given slotNumber is in stock (i.e., its quantity is greater than 0).
If the snack is in stock, the method should decrease its quantity by one and return the snack's price.
If the snack is out of stock (quantity is 0), the method should do nothing to the quantity and return -1.0.
For example, if slots.get(3) refers to a snack with price $1.50 and quantity 2, a call to selectSnack(3) would update that snack's quantity to 1 and return 1.50. A subsequent call to selectSnack(3) would update the quantity to 0 and return 1.50. A third call would return -1.0.
Part B
Write the purchaseSnacks method. This method takes an array of integers, where each integer is a slotNumber the user wants to purchase. The method should iterate through the selections array and, for each slotNumber, attempt to select that snack by calling the selectSnack method you wrote in part (a). The purchaseSnacks method should count and return the total number of snacks that were successfully purchased (i.e., the number of times selectSnack did not return -1.0).
Assume that the selectSnack method works as specified, regardless of what you wrote in part (a). You must use selectSnack appropriately to receive full credit.
Reveal sample answer + rubric
Sample answer
// Part (a)
public double selectSnack(int slotNumber) {
Snack s = slots.get(slotNumber);
if (s.getQuantity() > 0) {
s.setQuantity(s.getQuantity() - 1);
return s.getPrice();
} else {
return -1.0;
}
}
// Part (b)
public int purchaseSnacks(int[] selections) {
int purchasedCount = 0;
for (int slot : selections) {
if (selectSnack(slot) != -1.0) {
purchasedCount++;
}
}
return purchasedCount;
}
Rubric
Part (a): selectSnack (5 points)
1 pt: Accesses the correct Snack object from slots using slotNumber.
1 pt: Correctly calls getQuantity() on the Snack object.
1 pt: Correctly checks if quantity is greater than 0.
1 pt: In the true case, correctly decrements the quantity (using getQuantity and setQuantity) and returns the price (using getPrice).
1 pt: In the false case (out of stock), returns -1.0 and does not modify quantity.
Part (b): purchaseSnacks (4 points)
1 pt: Initializes a counter variable to 0.
1 pt: Correctly iterates through all elements of the selections array. (for or for-each loop is acceptable).
1 pt: Calls selectSnack for each element in the selections array.
1 pt: Correctly checks the return value of selectSnack, increments the counter if the value is not -1.0, and returns the final count.
FRQ #2: Playlist
FRQ #2 · Max 9 points
This question involves writing a complete class to model a music playlist. The Playlist class keeps track of a playlist's name, its creator, and a list of song titles.
Write the complete Playlist class. Your implementation must meet all specifications and conform to the examples shown in the table below.
Sample Execution Sequence:
Statement
Explanation
Playlist rock = new Playlist("Rock Anthems", "Carlos");
Creates a new playlist named "Rock Anthems" by "Carlos".
rock.addSong("Bohemian Rhapsody");
Adds a song to the playlist.
rock.addSong("Stairway to Heaven");
Adds another song.
System.out.println(rock.getPlaylistInfo());
Prints: Rock Anthems by Carlos (2 songs)
rock.addSong("Hotel California");
Adds a third song.
System.out.println(rock.getSong(1));
Prints: Stairway to Heaven
rock.removeSong("Bohemian Rhapsody");
Removes the specified song.
System.out.println(rock.getPlaylistInfo());
Prints: Rock Anthems by Carlos (2 songs)
Part A
Part (a): Write the Playlist class.
The Playlist class must contain:
Instance Variables: Appropriate private instance variables to store the playlist's name (a String), the creator's name (a String), and the list of song titles (an ArrayList of String objects).
Constructor: A public constructor that takes the playlist name and creator name as parameters and initializes the instance variables. The list of songs should be initialized to be empty.
addSong method: A public void method that takes a String parameter for a song title and adds it to the end of the playlist.
removeSong method: A public void method that takes a String parameter for a song title and removes the first occurrence of that title from the playlist.
getSong method: A public String method that takes an int index and returns the song title at that index.
getPlaylistInfo method: A public String method that takes no parameters and returns a formatted string in the format "[PlaylistName] by [CreatorName] ([num] songs)", where [num] is the current number of songs in the playlist.
Reveal sample answer + rubric
Sample answer
import java.util.ArrayList;
public class Playlist {
private String playlistName;
private String creatorName;
private ArrayList<String> songTitles;
public Playlist(String pName, String cName) {
this.playlistName = pName;
this.creatorName = cName;
this.songTitles = new ArrayList<String>();
}
public void addSong(String title) {
this.songTitles.add(title);
}
public void removeSong(String title) {
this.songTitles.remove(title);
}
public String getSong(int index) {
return this.songTitles.get(index);
}
public String getPlaylistInfo() {
return this.playlistName + " by " + this.creatorName + " (" + this.songTitles.size() + " songs)";
}
}
Rubric
Complete Class (9 points)
Instance Variables (1 pt):
1 pt: Declares appropriate private instance variables for name, creator, and a list of songs (must be an ArrayList<String>).
Constructor (2 pts):
1 pt: Correctly implements the constructor signature public Playlist(String, String).
1 pt: Correctly initializes all instance variables. The ArrayList must be instantiated.
addSong and removeSong methods (2 pts):
1 pt: Correctly implements addSong to add a string to the ArrayList.
1 pt: Correctly implements removeSong to remove a string from the ArrayList.
getSong method (1 pt):
1 pt: Correctly implements getSong to return the element at a given index.
getPlaylistInfo method (3 pts):
1 pt: Correctly accesses the playlist name and creator name.
1 pt: Correctly accesses the size of the songTitles list.
1 pt: Constructs and returns the string in the exact specified format.
FRQ #3: Student Records
FRQ #3 · Max 9 points
This question involves processing an ArrayList of Student objects. You will write two methods in a School class that contains a list of all students.
The Student class is defined as follows:
public class Student {
private String name;
private int gradYear;
private double gpa;
public Student(String name, int gradYear, double gpa) { /* implementation not shown */ }
public String getName() { /* implementation not shown */ }
public int getGradYear() { /* implementation not shown */ }
public double getGPA() { /* implementation not shown */ }
// There may be other methods not shown.
}
The School class is defined in part as follows:
public class School {
private ArrayList<Student> studentList;
// constructor and other methods not shown
/**
* Returns a list of the names of all students on the honor roll (GPA >= 3.5)
* for a specific graduation year.
*/
public ArrayList<String> getHonorRoll(int year) {
/* to be implemented in part (a) */
}
/**
* Calculates and returns the average GPA of all students in the school.
* If there are no students, it should return 0.0.
*/
public double calculateAverageGPA() {
/* to be implemented in part (b) */
}
}
Part A
Write the getHonorRoll method. This method should create and return a new ArrayList<String> containing the names of all students in studentList who have a GPA of 3.5 or greater and whose graduation year matches the year parameter. The names in the returned list should appear in the same order as the corresponding Student objects appear in studentList.
Part B
Write the calculateAverageGPA method. This method should calculate the average GPA of all students in the studentList. The method should return the calculated average. If the studentList is empty, the method should return 0.0 to avoid division by zero.
Reveal sample answer + rubric
Sample answer
// Part (a)
public ArrayList<String> getHonorRoll(int year) {
ArrayList<String> honorRollNames = new ArrayList<String>();
for (Student s : studentList) {
if (s.getGradYear() == year && s.getGPA() >= 3.5) {
honorRollNames.add(s.getName());
}
}
return honorRollNames;
}
// Part (b)
public double calculateAverageGPA() {
if (studentList.size() == 0) {
return 0.0;
}
double totalGPA = 0.0;
for (Student s : studentList) {
totalGPA += s.getGPA();
}
return totalGPA / studentList.size();
}
Rubric
Part (a): getHonorRoll (5 points)
1 pt: Creates a new ArrayList<String> to store names.
1 pt: Traverses all Student objects in studentList.
1 pt: For each student, correctly accesses their graduation year and GPA.
1 pt: Correctly checks both conditions (year matches AND GPA is >= 3.5).
1 pt: If both conditions are met, adds the student's name to the new list and returns the list after the loop.
Part (b): calculateAverageGPA (4 points)
1 pt: Handles the special case where studentList is empty and returns 0.0.
1 pt: Initializes a sum variable (e.g., totalGPA) to 0.
1 pt: Traverses all Student objects in studentList, summing their GPAs.
1 pt: After the loop, correctly calculates and returns the average (sum / size).
FRQ #4: Image Processor
FRQ #4 · Max 9 points
This question involves processing a 2D array of integers that represents a grayscale image. Each integer in the array is a pixel value from 0 (black) to 255 (white).
You will write two methods for the ImageProcessor class, which is defined in part as follows:
public class ImageProcessor {
private int[][] pixels;
// constructor initializes the pixels array
/**
* Finds and returns the brightest pixel value (the maximum value)
* in a specified rectangular region of the image.
* Preconditions: 0 <= r1 <= r2 < pixels.length
* 0 <= c1 <= c2 < pixels[0].length
*/
public int findBrightestInRegion(int r1, int c1, int r2, int c2) {
/* to be implemented in part (a) */
}
/**
* Inverts the colors of the entire image.
* Each pixel's new value should be 255 minus its old value.
* Postcondition: All values in the pixels array are modified.
*/
public void invertImage() {
/* to be implemented in part (b) */
}
}
Part A
Write the findBrightestInRegion method. This method takes four integer parameters: r1, c1, r2, and c2, which define the top-left and bottom-right corners of a rectangular region in the image, inclusive. The method should traverse only the pixels within this specified region and return the highest pixel value found.
Part B
Write the invertImage method. This method should traverse the entire pixels array. For each pixel, it should update its value to 255 minus its original value. For example, a pixel with a value of 50 would become 255 - 50 = 205, and a pixel with a value of 240 would become 255 - 240 = 15.
Reveal sample answer + rubric
Sample answer
// Part (a)
public int findBrightestInRegion(int r1, int c1, int r2, int c2) {
int maxVal = pixels[r1][c1]; // Or 0, since pixel values are non-negative
for (int r = r1; r <= r2; r++) {
for (int c = c1; c <= c2; c++) {
if (pixels[r][c] > maxVal) {
maxVal = pixels[r][c];
}
}
}
return maxVal;
}
// Part (b)
public void invertImage() {
for (int r = 0; r < pixels.length; r++) {
for (int c = 0; c < pixels[0].length; c++) {
pixels[r][c] = 255 - pixels[r][c];
}
}
}
Rubric
Part (a): findBrightestInRegion (5 points)
1 pt: Initializes a max variable correctly (e.g., to 0 or the value of the first pixel in the region).
1 pt: Sets up a nested loop to traverse the 2D array.
1 pt: The loop bounds must correctly correspond to the region (r from r1 to r2, c from c1 to c2, inclusive).
1 pt: Correctly compares the current pixel's value with the current max value.
1 pt: Updates max if a larger value is found and returns the final max after the loops.
Part (b): invertImage (4 points)
1 pt: Sets up a nested loop to traverse the entire 2D array.
1 pt: The loop bounds must be correct for the entire array (e.g., r < pixels.length, c < pixels[0].length).
1 pt: For each element, correctly calculates the inverted value (255 - original_value).
1 pt: Assigns the new calculated value back to the same position in the pixels array.