Overview
AP CSA FRQ 4 is the 2D array question, the last of the four free-response questions on the AP Computer Science A exam. It's worth 6 of the 25 free-response points, and the whole FRQ section gives you 90 minutes and counts for 45% of your exam score. You'll be given a class that stores a 2D array as an instance variable, and you'll write one method that uses, analyzes, or manipulates the data in that grid.
Here's the good news about FRQ 4: it's the most predictable question on the exam. The array almost always holds objects (not just ints), the problem almost always involves traversing rows or columns with nested loops, and the same handful of patterns shows up year after year. If you can write a clean nested loop and call methods on the elements inside it, you're most of the way there. For the big picture on all four FRQs, see the AP CSA exam prep hub.

How AP CSA FRQ 4 Is Scored
FRQ 4 is worth 6 points, scored against a question-specific rubric that rewards each piece of a working solution separately. That means partial credit is built in. A correct loop structure with broken logic inside still earns points.
The exact rubric changes with each year's problem, but for a typical counting or find-the-extreme problem, the points tend to split along these lines:
| Points | What typically earns them |
|---|---|
| 1 | Traversing all elements of the 2D array with correct loop bounds (no out-of-bounds access) |
| 1 | Calling methods on the objects stored in the array (e.g. getStatus(), not .status) |
| 1 | Comparing values correctly, including .equals() for Strings instead of == |
| 2 | Implementing the core algorithm: initializing, resetting, and accumulating counters or trackers correctly |
| 1 | Returning the correct result (the right value, in the right form, like an index vs. a count) |
This table is a pattern, not an official rubric, but it reflects how graders break solutions into independently scorable pieces. The takeaway: even if you can't finish the algorithm, correct traversal plus correct method calls can earn 2-3 points. Never leave FRQ 4 blank.
2D Array Traversal: What You Have to Know Cold
In Java, the first index is always the row and the second is always the column. Think array[row][col], every time. This feels backwards if you're used to (x, y) coordinates from math class, so drill it until it's automatic.
Java builds 2D arrays as arrays of arrays. When you write int[][] grid = new int[3][4], you're creating an array of 3 elements, where each element is itself an array of 4 ints. That's why:
grid.lengthis the number of rows (3)grid[0].lengthis the number of columns (4)
The prompt will usually say something like "assume the array has at least one row and one column." That's your green light to use arr[0].length safely. AP CSA 2D arrays are rectangular, so every row has the same length.
Row-by-row traversal (the default)
The outer loop walks rows, the inner loop walks columns:
</>Javafor (int row = 0; row < array.length; row++) { for (int col = 0; col < array[0].length; col++) { // Process array[row][col] } }
Column-by-column traversal (where points are lost)
FRQ 4 loves column processing precisely because it tests whether you understand traversal beyond the memorized default. To go column by column, flip which loop is on the outside. The index order inside the brackets does NOT change:
</>Javafor (int col = 0; col < array[0].length; col++) { for (int row = 0; row < array.length; row++) { // Process array[row][col] - still [row][col]! } }
Why this works: you're changing which dimension you hold constant. If you're counting something in each column, you want to finish all of column 0 before touching column 1. The outer loop fixes the column; the inner loop sweeps down the rows.
Calling methods on array elements
Unlike simpler array problems, FRQ 4 stores objects in the grid (think Appointment, Tile, or Card objects). Instance variables are private in AP CSA, so you must use getter methods:
</>Javaif (array[row][col].getStatus().equals(target)) { // count it, track it, etc. }
Note the chain: access the element, call a method on it, then compare with .equals() because the result is a String. Writing == target instead of .equals(target) for Strings is a guaranteed point loss.
How to Answer the 2D Array FRQ, Step by Step
You have 90 minutes for four FRQs, so budget roughly 22 minutes for FRQ 4. Here's a pacing plan that works.
Minutes 0-3: Read and understand
Identify what's stored in the 2D array and which methods you can call on those objects. FRQ 4 makes you juggle three things at once: the grid structure, the objects inside it, and the methods on those objects. Read the provided example carefully; it's specifically designed to expose edge cases. Don't rush this step. A misread here costs you the algorithm points later.
Minutes 3-5: Plan your traversal
Decide: row-wise or column-wise? This single decision shapes your whole solution. If the question says "for each column..." or "find the column with the fewest...", you need the column-outer loop. Sketch your approach in a comment or two before writing real code.
Minutes 5-15: Write the solution
Copy the method header exactly as given. Write your nested loop structure first, with correct bounds, then fill in the logic. If you blank on the algorithm, write the loops anyway. Correct traversal earns a point on its own.
Minutes 15-20: Trace the example
Walk your code through the provided example by hand and check that it produces the expected output. If it doesn't, you have a bug, and the example usually points right at it (counter not reset, wrong dimension, off-by-one).
Minutes 20-22: Final sweep
Check the classic point-killers: == on Strings, loop bounds using the wrong dimension, a missing return, or returning the count when the question asked for the index.
Worked Pattern: Counting in Each Column
Here's the most common FRQ 4 shape, shown as an editorial example. Imagine a Schedule class with a 2D array of Appointment objects, and you need to find the column (time slot) with the fewest appointments whose status equals some target String:
</>Javapublic int findLightestColumn(String target) { int minCount = appts.length + 1; // higher than any possible count int minCol = 0; for (int col = 0; col < appts[0].length; col++) { int count = 0; // reset for EACH column for (int row = 0; row < appts.length; row++) { if (appts[row][col].getStatus().equals(target)) { count++; } } if (count < minCount) { minCount = count; minCol = col; } } return minCol; // the INDEX, not the count }
Notice everything the rubric pattern rewards happening in one place:
- Column-outer traversal, because we want per-column counts
count = 0inside the outer loop, so it resets for every new column- A getter method called on each element, compared with
.equals() - Two trackers, one for the extreme value (
minCount) and one for its location (minCol) minCountinitialized to a value guaranteed to be beaten (more than the number of rows)- Returning the index the question asked for
Beyond counting, watch for these recurring FRQ 4 patterns: conditional counting (count elements meeting a criterion), finding the min/max row or column, and searching for a specific element or pattern across the grid. They all reduce to the same skeleton: nested loops, a method call, a comparison, and careful tracking variables.
Common Mistakes
- Using
==to compare Strings. Graders are trained to look for this. Always use.equals()when comparing String values, including results returned from getter methods. - Forgetting to reset the counter. If you're counting per row or per column,
count = 0must live inside the outer loop, before the inner loop runs. Putting it before both loops costs you the algorithm points. - Swapping rows and columns in bounds. Writing
row < array[0].lengthorcol < array.lengthwalks off the edge of a non-square array. Say it out loud:array.lengthis rows,array[0].lengthis columns. - Accessing fields directly. Writing
appts[row][col].statuswon't compile because instance variables are private. Call the getter:appts[row][col].getStatus(). - Returning the wrong thing. If the question asks for the column index, returning the count loses the final point. Reread the return type and the last line of the prompt before you finish.
- Leaving it blank when stuck. Partial credit is generous on FRQ 4. Even a correct nested loop with a plausible method call inside can earn 2-3 of the 6 points.
Practice and Next Steps
The 2D array patterns become automatic after 5-10 timed reps, and that's when the 22-minute budget starts feeling roomy. Work through real prompts in the AP CSA FRQ question bank, then get instant feedback on your code with FRQ practice with scoring. Official prompts from past AP CSA exams are the best source for full-length 2D array problems with real scoring guidelines.
FRQ 4 shares DNA with the other free-response questions, so round out your prep with the guides to FRQ 1: Methods and Control Structures and FRQ 3: Data Analysis with ArrayList, which tests similar traverse-and-analyze skills on a different data structure. When you're ready to simulate the real thing, take a full-length AP CSA practice exam and see where your score lands with the AP score calculator.
Frequently Asked Questions
How many points is FRQ 4 on the AP CSA exam?
FRQ 4, the 2D Array question, is worth 6 of the 25 free-response points. The full FRQ section has 4 questions, runs 90 minutes, and counts for 45% of your AP Computer Science A score, so budget roughly 22 minutes for this question.
What does AP CSA FRQ 4 ask you to do?
You're given a class that stores a 2D array as an instance variable, and you write one method that uses, analyzes, or manipulates that array. The array typically holds objects, so you'll traverse with nested loops, call getter methods on elements, and count, search, or find a min/max across rows or columns.
How do I traverse a 2D array by columns in Java?
Put the column loop on the outside and the row loop on the inside, but keep the index order as array[row][col]. The outer loop fixes one column while the inner loop sweeps every row in it, which is what you need when counting per column. Remember array.length is rows and array[0].length is columns.
Can I get partial credit on the AP CSA 2D array FRQ?
Yes, the rubric awards points for independent pieces of a solution. Correct nested loop bounds, calling getter methods on elements, and using .equals() for Strings can each earn points even if your algorithm is incomplete, so never leave FRQ 4 blank. You can practice with instant feedback using Fiveable's FRQ practice tool.
Why can't I use == to compare Strings on AP CSA FRQs?
Using == compares object references, not the text inside the Strings, so it can return false even when two Strings have the same characters. Always use .equals() to compare String values on the FRQs. Graders specifically check for this, and using == on Strings costs you the comparison point on FRQ 4.