AP CSA Practice Exam – Section I: 42 Multiple Choice Questions

AP Computer Science A — 2025–2026

Practice Exam — Section I

Multiple Choice • 4-Unit Curriculum • College Board Level Difficulty

42Questions
90Minutes
50%of Score
Time 90:00
0 of 42 answered
Section I — Complete
Estimated AP Score Based on historical score distributions. Actual cutoffs vary by exam year.

Finished? Continue to the free response section. Section II: Free Response → 4 FRQ questions • 90 minutes • 50% of exam score
Section I: Multiple Choice — Directions

42 questions across all 4 AP CSA units — Unit 1: 10 • Unit 2: 12 • Unit 3: 7 • Unit 4: 13.

90 minutes. Timer starts when you click “Start Exam.”

• You may return to and change any answer before submitting.

• The Java Quick Reference (PDF) → is permitted, just as on the real exam. Open it in a separate tab.

• Unless stated otherwise, assume parameters are not null and all preconditions are satisfied.

No penalty for guessing — answer every question before submitting.

• After submitting, your score and estimated AP score (1–5) will appear above, then continue to Section II: Free Response →

Unit 1 — Objects, Methods & Expressions — Q1–10
1
Unit 1 integer division & casting

What is the value of result after executing the following code segment?

int a = 13;
int b = 5;
double result = (double)(a / b) + a % b;
Correct Answer: B
Parentheses force a / b to evaluate first as integer division: 13 / 5 = 2. The (double) cast then converts 2 to 2.0. Next, a % b = 13 % 5 = 3. Finally, 2.0 + 3 = 5.0. The common mistake is thinking the cast makes the division decimal (which would give 2.6), but the cast applies after division completes.
2
Unit 1 String methods

What is the value of result after executing the following code segment?

String msg = "AP Computer Science";
int idx = msg.indexOf("Computer");
String result = msg.substring(idx, idx + 4);
Correct Answer: A
indexOf("Computer") returns 3 (the index where "Computer" starts). Then substring(3, 7) extracts indices 3, 4, 5, 6 — which is "Comp". Remember: substring(start, end) includes start but excludes end.
3
Unit 1 Math.random()

Which expression produces a random integer from 25 to 75, inclusive?

Correct Answer: C
Formula: (int)(Math.random() * range) + offset where range = number of values and offset = starting value. From 25 to 75 inclusive: range = 75 − 25 + 1 = 51, offset = 25. Option A generates 25–99. Option B generates 25–74 (misses 75). Option D generates 26–75 (misses 25).
4
Unit 1 == vs .equals()

Consider the following code segment.

String x = new String("hello");
String y = new String("hello");
System.out.println(x.equals(y));
System.out.println(x == y);

What is printed?

Correct Answer: D
.equals() compares content and returns true since both contain "hello". The == operator compares references (memory addresses). Using new String() creates two separate objects, so == returns false. Always use .equals() to compare String content.
5
Unit 1 operator precedence

What is printed by the following code segment?

int x = 11;
int y = 4;
System.out.println(x / y * y + x % y);
Correct Answer: A
Evaluate left to right: x / y = 11 / 4 = 2. Then 2 * y = 8. Then x % y = 3. Finally 8 + 3 = 11. This always reconstructs the original dividend: (x/y)*y + x%y == x for positive integers.
6
Unit 1 spot-the-error: static vs instance

Consider the following class.

public class Widget {
    private int val;

    public Widget(int v) {
        val = v;
    }

    public int getVal() {
        return val;
    }

    public static int doubleIt(int n) {
        return n * 2;
    }
}

The following code appears in another class.

Widget w = new Widget(5);

Which of the following will cause a compile-time error?

Correct Answer: C
getVal() is an instance method — it requires an object. Calling Widget.getVal() attempts to call it on the class itself, which is only valid for static methods. Options A and D correctly call the static method. Option B correctly calls an instance method on an object.
7
Unit 1 String concatenation

What is the value of result after executing the following?

int x = 3;
int y = 4;
String result = x + y + " total " + x + y;
Correct Answer: B
Evaluates left to right. x + y = 7 (both ints → arithmetic). 7 + " total " = "7 total " (int + String → String). From here all + is concatenation: "7 total " + 3 = "7 total 3", then + 4 = "7 total 34".
8
Unit 1 missing code

Consider the following method.

/** Returns a random integer between low and high, inclusive */
public static int randRange(int low, int high) {
    return /* missing code */ ;
}

Which of the following should replace /* missing code */ so the method works as intended?

Correct Answer: C
Range = high - low + 1 values; offset = low. Option B misses the highest value. Option D starts one too high, missing low.
9
Unit 1 autoboxing / unboxing

Consider the following code segment.

ArrayList nums = new ArrayList();
nums.add(5);
nums.add(10);
int total = nums.get(0) + nums.get(1);

Which of the following is true about this code?

Correct Answer: C
Java automatically converts int to Integer (autoboxing) for add(), and Integer back to int (unboxing) for arithmetic. This allows seamless use of primitives with ArrayList.
10
Unit 1 String immutability

What is printed by the following code segment?

String a = "test";
String b = a;
a = a.toUpperCase();
System.out.println(a + " " + b);
Correct Answer: B
Strings are immutable. a.toUpperCase() creates a new String object "TEST" and assigns it to a. b still references the original "test". String methods never modify the original — they always return new objects.
Unit 2 — Selection & Iteration — Q11–22
11
Unit 2 short-circuit evaluation

What is printed by the following code segment?

int[] arr = {2, 4, 6};
int idx = 5;
if (idx < arr.length && arr[idx] > 0) {
    System.out.print("A");
} else {
    System.out.print("B");
}
Correct Answer: D
Short-circuit evaluation prevents the error. idx < arr.length5 < 3false. With &&, Java stops immediately — arr[idx] is never evaluated. The else branch executes and prints "B".
12
Unit 2 De Morgan's Law

Which of the following expressions is equivalent to !(a > 0 && b <= 10)?

Correct Answer: C
De Morgan's Law: !(A && B) = !A || !B. Negate each part: !(a > 0)a <= 0, and !(b <= 10)b > 10. Flip && to ||. Option B uses && instead of ||. Option D negates incorrectly (> should become <=, not <).
13
Unit 2 nested loop tracing

What is the value of result after executing the following code segment?

int result = 0;
for (int j = 1; j <= 4; j++) {
    for (int k = j; k <= 4; k++) {
        result++;
    }
}
Correct Answer: D
The inner loop starts at k = j. j=1: 4 iterations. j=2: 3 iterations. j=3: 2 iterations. j=4: 1 iteration. Total: 4 + 3 + 2 + 1 = 10.
14
Unit 2 loop trace with String build

What is the value of result after executing the following code segment?

String result = "";
for (int k = 0; k < 4; k++) {
    if (k % 2 == 0) {
        result += k;
    } else {
        result += "-";
    }
}
Correct Answer: A
k=0 (even → "0"), k=1 (odd → "-"), k=2 (even → "2"), k=3 (odd → "-"). Result: "0-2-". The loop runs 4 times (0 through 3), appending a digit or dash each iteration.
15
Unit 2 equivalent loops

Consider the following code segment.

for (int k = 0; k < 20; k++) {
    if (k % 4 == 0) {
        System.out.print(k + " ");
    }
}

Which of the following code segments produces the same output?

Correct Answer: A
Original outputs: 0 4 8 12 16. Option A: starts at 0, increments by 4, stops before 20 → same output. Option B misses 0. Option C includes 20. Option D prints 4 8 12 16 20 (misses 0, includes 20).
16
Unit 2 I / II / III — boolean range check

Consider the boolean variable inRange that should be true when x is between 1 and 100 inclusive, and false otherwise. Which of the following correctly assigns inRange?

  • I. inRange = (x >= 1) && (x <= 100);
  • II. inRange = !(x < 1) && !(x > 100);
  • III. inRange = !(x < 1 || x > 100);
Correct Answer: D
All three are logically equivalent. I is the direct range check. II negates each boundary: !(x < 1)x >= 1. III applies De Morgan's: !(A || B) = !A && !B, expanding to the same result as II.
17
Unit 2 while loop trace

What is printed by the following code segment?

int a = 1;
int b = 10;
while (a < b) {
    a++;
    b--;
}
System.out.println(a + " " + b);
Correct Answer: B
Trace: (1,10) → (2,9) → (3,8) → (4,7) → (5,6) → (6,5). Now a < b is 6 < 5 → false, loop exits. Both update in the same iteration, so they cross each other rather than meeting at 5,5.
18
Unit 2 spot-the-error: off-by-one

The following method is intended to return the index of the last occurrence of target in arr, or -1 if not found. Which best describes the error?

public static int findLast(int[] arr, int target) {
    for (int k = arr.length; k >= 0; k--) {
        if (arr[k] == target) {
            return k;
        }
    }
    return -1;
}
Correct Answer: A
Valid indices are 0 to arr.length - 1. Starting at arr.length means the first access is arr[arr.length], which throws ArrayIndexOutOfBoundsException. Fix: int k = arr.length - 1. Right-to-left traversal is correct for finding the last occurrence.
19
Unit 2 missing code: String processing

Consider the following method intended to return the input string with all vowels removed.

public static String removeVowels(String str) {
    String result = "";
    for (int k = 0; k < str.length(); k++) {
        String ch = str.substring(k, k + 1);
        /* missing code */
    }
    return result;
}

Which of the following should replace /* missing code */?

Correct Answer: B
We keep characters that are not vowels. indexOf(ch) returns -1 when not found. Option A keeps vowels (wrong direction). Option C compares one character to a 5-character string — always unequal, keeps everything. Option D fails for 'a' since indexOf("a") == 0, and 0 > 0 is false, so 'a' is incorrectly kept.
20
Unit 2 output pattern: nested loops

What is printed by the following code segment?

for (int r = 1; r <= 3; r++) {
    for (int c = r; c <= 3; c++) {
        System.out.print("*");
    }
    System.out.println();
}
Correct Answer: A
Inner loop starts at c = r. r=1: c goes 1,2,3 (3 stars). r=2: c goes 2,3 (2 stars). r=3: c goes 3 (1 star). Decreasing triangle.
21
Unit 2 loop trace: doubling

What is printed by the following code segment?

int x = 1;
for (int k = 0; k < 4; k++) {
    x = x + x;
}
System.out.println(x);
Correct Answer: C
x = x + x doubles x each pass. 1 → 2 → 4 → 8 → 16. After 4 iterations x = 24 = 16.
22
Unit 2 spot-the-error: infinite loop

What happens when the following code segment is executed?

int n = 100;
while (n > 0) {
    if (n % 2 == 0) {
        n -= 3;
    }
}
System.out.println(n);
Correct Answer: C
n=100 (even) → n=97 (odd). Now n % 2 == 0 is false, so the if-body never executes again — but n > 0 is still true. The loop runs forever with n stuck at 97.
Unit 3 — Class Creation — Q23–29
23
Unit 3 I / II / III — constructor signatures

Consider the following class.

public class Item {
    private String name;
    private double price;

    public Item() {
        name = "Unknown";
        price = 0.0;
    }

    public Item(String n, double p) {
        name = n;
        price = p;
    }
}

Which of the following declarations will compile without error?

  • I. Item a = new Item();
  • II. Item b = new Item("Widget", 9.99);
  • III. Item c = new Item("Widget");
Correct Answer: C
I matches the no-arg constructor. II matches the two-arg constructor (String, double). III passes only one String — no constructor with that signature exists, so it does not compile.
24
Unit 3 spot-the-error: encapsulation

Consider the following class.

public class Account {
    private double balance;

    public Account(double initial) {
        balance = initial;
    }

    public double getBalance() {
        return balance;
    }

    public void deposit(double amt) {
        balance += amt;
    }
}

The following code appears in a different class: Account acct = new Account(100.0);
Which of the following will cause a compile-time error?

Correct Answer: C
balance is private and cannot be accessed directly outside the class. acct.balance will not compile. This is encapsulation: access is controlled through public methods only.
25
Unit 3 multi-class: object composition

Consider the following two classes.

public class Point {
    private int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
}

public class Rectangle {
    private Point corner;
    private int width, height;
    public Rectangle(Point p, int w, int h) {
        corner = p; width = w; height = h;
    }
    public boolean contains(Point p) {
        return p.getX() >= corner.getX() &&
               p.getX() <= corner.getX() + width &&
               p.getY() >= corner.getY() &&
               p.getY() <= corner.getY() + height;
    }
}

What is printed?

Point p1 = new Point(2, 3);
Rectangle rect = new Rectangle(p1, 5, 4);
Point p2 = new Point(7, 8);
System.out.println(rect.contains(p2));
Correct Answer: A
Rectangle: corner (2,3), width 5, height 4. x-range [2,7], y-range [3,7]. p2 = (7,8). Check: 72 ✓, 77 ✓, 83 ✓, but 87 is false. One false with && makes the whole expression false.
26
Unit 3 static vs instance variables

Consider the following class.

public class Counter {
    private static int total = 0;
    private int value;

    public Counter(int v) {
        value = v;
        total += v;
    }

    public static int getTotal() {
        return total;
    }
    public int getValue() {
        return value;
    }
}

What is printed by the following code segment?

Counter c1 = new Counter(5);
Counter c2 = new Counter(3);
Counter c3 = new Counter(7);
System.out.println(Counter.getTotal() + " " + c2.getValue());
Correct Answer: D
total is static — shared across all objects. Constructors add: 0+5=5, 5+3=8, 8+7=15. getTotal() = 15. c2.getValue() = 3 (c2's own instance variable). Static = shared; instance = per-object.
27
Unit 3 spot-the-error: missing this

Consider the following class.

public class Pair {
    private int x;
    private int y;

    public Pair(int x, int y) {
        x = x;
        y = y;
    }

    public int getSum() {
        return x + y;
    }
}

What is printed by the following code segment?

Pair p = new Pair(3, 7);
System.out.println(p.getSum());
Correct Answer: B
The constructor uses x = x and y = y, assigning each parameter to itself — the instance variables are never set. They retain their default value of 0. Fix: use this.x = x; this.y = y;. This is a common bug when parameter names shadow instance variable names.
28
Unit 3 multi-step object trace

Consider the following class.

public class Tracker {
    private int val;
    public Tracker(int initial) {
        val = initial;
    }
    public void step() {
        if (val % 2 == 0) {
            val = val / 2;
        }
        else {
            val = val * 3 + 1;
        }
    }
    public int getVal() {
        return val;
    }
}

What is printed by the following code segment?

Tracker t = new Tracker(6);
t.step();
t.step();
t.step();
System.out.println(t.getVal());
Correct Answer: B
val=6 (even) → 3. val=3 (odd) → 3×3+1=10. val=10 (even) → 5. getVal() returns 5. (This is the Collatz sequence.)
29
Unit 3 spot-the-error: mutating accessor

Consider the following class.

public class Temperature {
    private double degrees;

    public Temperature(double d) {
        degrees = d;
    }

    public double getDegrees() {
        return degrees;
    }

    public double toFahrenheit() {
        degrees = degrees * 9.0 / 5.0 + 32;
        return degrees;
    }
}

A programmer stores a Celsius value and calls toFahrenheit() multiple times. Which best describes the problem?

Correct Answer: B
toFahrenheit() overwrites degrees with the converted value. A second call applies the formula to an already-converted Fahrenheit number, giving a wrong result. Fix: use a local variable — return degrees * 9.0 / 5.0 + 32; — without modifying the instance variable.
Unit 4 — Data Collections — Q30–42
30
Unit 4 find-minimum algorithm

What is printed by the following code segment?

int[] arr = {5, 3, 8, 1, 9, 2};
int x = arr[0];
for (int k = 1; k < arr.length; k++) {
    if (arr[k] < x) {
        x = arr[k];
    }
}
System.out.println(x);
Correct Answer: C
Find-minimum: x starts at arr[0]=5. 3<5 → x=3. 1<3 → x=1. No subsequent value beats 1. Final: 1.
31
Unit 4 algorithm analysis: skip-index loop

Consider the following method.

public static int mystery(int[] arr) {
    int x = 0;
    for (int k = 0; k < arr.length; k = k + 2) {
        x = x + arr[k];
    }
    return x;
}

Given int[] vals = {3, 6, 1, 0, 1, 4, 2};, what value is returned by mystery(vals)?

Correct Answer: D
Visits indices 0, 2, 4, 6: values 3, 1, 1, 2. Sum = 7. The method sums elements at even-numbered indices only.
32
Unit 4 2D array: diagonal

Consider the following code segment.

int[][] grid = {{1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}};
int result = 0;
for (int r = 0; r < grid.length; r++) {
    result += grid[r][r];
}
System.out.println(result);
Correct Answer: B
grid[r][r] accesses the main diagonal: grid[0][0]=1, grid[1][1]=5, grid[2][2]=9. Sum = 15.
33
Unit 4 missing code: array filtering

The following method is intended to return a new array containing only the positive values from data, in order.

public static int[] getPositives(int[] data) {
    int count = 0;
    for (int val : data) {
        if (val > 0) {
            count++;
        }
    }
    int[] result = new int[count];
    int idx = 0;
    for (int val : data) {
        if (val > 0) {
            /* missing code */
        }
    }
    return result;
}

Which of the following should replace /* missing code */?

Correct Answer: A
Place val at result[idx] then increment idx. Option B uses count which already equals the full size — immediate out-of-bounds. Option C never increments, overwriting index 0 every time. Option D treats val as an index rather than a value.
34
Unit 4 I / II / III — spot-the-error: bounds

Consider a method hasDuplicates that returns true if a sorted array contains any duplicate adjacent values. Which of the following implementations work correctly?

  • I.
    for (int k = 0; k < arr.length - 1; k++) {
        if (arr[k] == arr[k+1]) {
            return true;
        }
    }
    return false;
  • II.
    for (int k = 1; k < arr.length; k++) {
        if (arr[k] == arr[k-1]) {
            return true;
        }
    }
    return false;
  • III.
    for (int k = 0; k < arr.length; k++) {
        if (arr[k] == arr[k+1]) {
            return true;
        }
    }
    return false;
Correct Answer: B
I safely accesses arr[k+1] by stopping at length - 1. II safely accesses arr[k-1] by starting at 1. III uses k < arr.length starting at 0 with arr[k+1] — when k = length-1, it accesses arr[length]ArrayIndexOutOfBoundsException.
35
Unit 4 2D array: last-row sum

Consider the following code segment.

int[][] mat = {{1, 2, 3, 4},
               {5, 6, 7, 8},
               {9, 10, 11, 12}};
int result = 0;
for (int c = 0; c < mat[0].length; c++) {
    result += mat[mat.length - 1][c];
}
System.out.println(result);
Correct Answer: C
mat.length - 1 = 2 (last row index). mat[0].length = 4 (columns). Sums row 2: 9+10+11+12 = 42. Key: mat.length = rows; mat[r].length = columns.
36
Unit 4 ArrayList removal: backward traversal

Consider the following code segment.

ArrayList words = new ArrayList();
words.add("cat");
words.add("dog");
words.add("bird");
words.add("cat");
words.add("fish");

for (int k = words.size() - 1; k >= 0; k--) {
    if (words.get(k).equals("cat")) {
        words.remove(k);
    }
}
System.out.println(words);
Correct Answer: D
Backward traversal safely removes all matches. Both "cat" entries are removed. Result: [dog, bird, fish]. Forward traversal would skip elements when indices shift after each removal.
37
Unit 4 running cumulative sum

Consider the following method.

public static void mystery(int[] arr) {
    for (int k = 0; k < arr.length - 1; k++) {
        arr[k + 1] = arr[k] + arr[k + 1];
    }
}

Given int[] vals = {5, 2, 1, 3, 8};, what are the contents of vals after the call?

Correct Answer: C
Each step uses the already-modified value. k=0: arr[1]=5+2=7. k=1: arr[2]=7+1=8. k=2: arr[3]=8+3=11. k=3: arr[4]=11+8=19. Running cumulative sum. Option B incorrectly uses the original unmodified values.
38
Unit 4 multi-class: ArrayList find-max

Consider the following classes.

public class Student {
    private String name;
    private int score;
    public Student(String n, int s) {
        name = n; score = s;
    }
    public int getScore() {
        return score;
    }
    public String getName() {
        return name;
    }
}

public class Gradebook {
    private ArrayList roster;
    public Gradebook() {
        roster = new ArrayList();
    }
    public void addStudent(Student s) {
        roster.add(s);
    }
    public String topStudent() {
        Student best = roster.get(0);
        for (Student s : roster) {
            if (s.getScore() {
                > best.getScore()) { best = s;
            } }
        }
        return best.getName();
    }
}

What is printed?

Gradebook gb = new Gradebook();
gb.addStudent(new Student("Jo", 88));
gb.addStudent(new Student("Al", 95));
gb.addStudent(new Student("Mo", 91));
System.out.println(gb.topStudent());
Correct Answer: B
Find-max: best starts as Jo (88). Al has 95>88 → best=Al. Mo has 91, not >95. Returns Al. Option D is a trap — return type is String (name), not int (score).
39
Unit 4 binary search: iteration count

Consider the following binary search method and sorted array.

public static int bSearch(int[] arr, int target) {
    int lo = 0, hi = arr.length - 1;
    while (lo <= hi) {
        int mid = (lo + hi) / 2;
        if      (arr[mid] == target) {
            return mid;
        }
        else if (arr[mid] < target) {
     lo = mid + 1;
 }
        else {
            hi = mid - 1;
        }
    }
    return -1;
}

int[] data = {2, 5, 8, 12, 16, 23, 38, 56, 72, 91};

How many iterations of the while loop execute during bSearch(data, 23)?

Correct Answer: A
Iter 1: lo=0, hi=9, mid=4, arr[4]=16<23 → lo=5. Iter 2: lo=5, hi=9, mid=7, arr[7]=56>23 → hi=6. Iter 3: lo=5, hi=6, mid=5, arr[5]=23 → found! Returns 5 after 3 iterations.
40
Unit 4 missing code: 2D array column bound

The following method is intended to return the sum of all elements in a 2D array.

public static int totalSum(int[][] mat) {
    int total = 0;
    for (int r = 0; r < mat.length; r++) {
        for (int c = 0; c < /* missing code */; c++) {
            total += mat[r][c];
        }
    }
    return total;
}

Which of the following should replace /* missing code */?

Correct Answer: D
The inner loop iterates over columns of the current row r. mat[r].length gives the number of columns in that row. Option A gives the number of rows. Option B uses c (column counter) as a row index — incorrect. Rule: mat.length = rows; mat[r].length = columns in row r.
41
Unit 4 I / II / III — ArrayList traversal

An ArrayList named nums contains [3, 7, 2, 9, 4]. Which of the following code segments will correctly print all elements?

  • I. for (int val : nums) System.out.print(val + " ");
  • II. for (int k = 0; k < nums.size(); k++) System.out.print(nums.get(k) + " ");
  • III. for (int k = 0; k < nums.size(); k++) System.out.print(nums[k] + " ");
Correct Answer: C
I uses enhanced for with unboxing — correct. II uses .get(k) — the proper ArrayList accessor. III uses nums[k] bracket notation, which only works for arrays, not ArrayLists — compile-time error. Remember: arrays use arr[k]; ArrayLists use list.get(k).
42
Unit 4 array element shift / deletion

Consider the following code segment.

int[] arr = {1, 2, 3, 4, 5, 6, 7, 8};
for (int k = 3; k < arr.length - 1; k++) {
    arr[k] = arr[k + 1];
}
System.out.println(Arrays.toString(arr));

What is printed?

Correct Answer: A
Loop shifts left starting at index 3: arr[3]=5, arr[4]=6, arr[5]=7, arr[6]=8. The last element (8) is never overwritten, leaving a duplicate at the end. Arrays have fixed size, so length stays 8. Option B is wrong — the array still has 8 elements.
AP CSA FRQ Archive — Practice Free Response
Back to blog

Leave a comment

Please note, comments need to be approved before they are published.