<< Hide Menu
14 min readβ’june 18, 2024
Avanish Gupta
Avanish Gupta
It's finally time. You've mastered creating classes, excel at arrays and ArrayLists, and dance around every control structure type. Now, you're ready for the AP CSA test! The first part of the test is theΒ multiple choice section. This multiple choice section isΒ 40 questionsΒ inΒ 90 minutesΒ withΒ 5 choices each (A-E). Here are the distributions of the units on the multiple choice section:
Unit Number | Unit Name | Percent | Number of Questions |
1 | Primitive Types | 2.5-5% | 1-2 |
2 | Using Objects | 5-7.5% | 2-3 |
3 | Boolean Expressions and If Statements | 15-17.5% | 6-7 |
4 | Iteration | 17.5-22.5% | 7-9 |
5 | Writing Classes | 5-7.5% | 2-3 |
6 | Array | 10-15% | 4-6 |
7 | ArrayList | 2.5-7.5% | 1-3 |
8 | 2D Array | 7.5-10% | 3-4 |
9 | Inheritance | 5-10% | 2-4 |
10 | Recursion | 5-7.5% | 2-3 |
There are two tips that are very useful for AP CSA Multiple Choice Questions:
Tracing the code means following the code line by line, iteration by iteration to see what happens in the program. While doing this, take note of the values of variables so that you don't lose track of what is happening by annotating, writing these values down on your test booklet. Although this may take some time, you have over 2 minutes a question, and this should be more than enough time to trace the code as you go.
Process of elimination is one of the most useful tools for AP CSA. You can get rid of many answer choices by paying attention to the types and classes of the methods and objects in question. Sometimes the answer choices will have types or logic that will make no sense which will allow us to cross them out and eliminate them! For example, you will be able to eliminate A, C, and D because they don't make sense, leaving us with only B and E! Now, instead of having a 20% of guessing the correct answer, you now have a 50% chance of doing so! This is a significant increase! Sometimes, you may even be able to narrow it down to one answer, and this will be your correct answer!
Below are the multiple-choice example questions from theΒ College Board Course and Exam DescriptionΒ with detailed explanations.
Here, we are going to evaluate the expression in the print statement step-by-step
Thus C is the correct answer.
Since we are printing an indexOf method result, the answer will be an integer, so we can eliminate D and E. Now we just trace the code as follows:
Line 1: gets the first 2 letters of word1 and saves it as str1
Line 2: gets the last letter of word2 and saves it as str2
Line 3: makes a new string result by putting str2 at the beginning and str1 after
Line 4: Finds where str2 is in result, because it is at the beginning, the integer that is printed isΒ
0
A is the correct answer
The Math.random() method returns a random number that is greater than or equal to 0.0 and less than 1. There are 36 integers between 25 and 60 inclusive is 36, which we multiply by Math.random() in the line of code to give this range. This eliminates choices A, B, C, and E. From process of elimination, that leaves us with choice D.
This method sorts Large and Mid-Size vehicles correctly because their if-statement conditionals correctly distinguish these types, but for all other categories, since their volume is less than 120 for the second if-statement conditional, this method will incorrectly classify them as Mid-Size. The only choice that are in the correct classifications is E.
This statement is true when either a is true (a) AND the inverse of (b OR a) (!(b || a)) is true. Let's do a truth table to represent this as follows:
Truth Table
Value of a | Value of b | Value of (b or a) | Value of !(b or a) | Value of (a and !(b or a)) |
false | false | false | true | false |
false | true | true | false | false |
true | false | true | false | false |
true | true | true | false | false |
Recall that for the OR operator, only one of the two values on each side has to be true and for the AND operator, both sides have to evaluate to true. From the truth table, we can see that the final expression always evaluates to false with all possible inputs. Thus the correct answer is B.
To answer this question, we trace the code and annotate as shown below.
val = 48, div = 6, 48 % 2 == 0, 6 > 0, 48 % 6 == 0
"48 " is printed
val = 24, div = 5, 24 % 2 == 0, 5 > 0, 24 % 5 != 0
val = 12, div = 4, 12 % 2 == 0, 4 > 0, 12 % 4 == 0
"48 12 " is printed
val = 6, div = 3, 6 % 2 == 0, 3 > 0, 6 % 3 == 0
For the result to be used in another class, we need public access, and to even use the integer, we need the method to return an int. The only choice that achieves this is C.
The error here is in the loop header where the Boolean expression is. The way it is right now, it allows i = animals.length, which will throw an ArrayIndexOutOfBounds exception since the last index is animals.length - 1. The fix to this is to remove the equality, which matches A.
I will not work because k is not incremented, creating an infinite loop. II works as the loop header is correct so that the loop actually traverses through the array and the array values are actually updated. III will not work because even though n is updated, Java is pass-by-value, so the array value is not updated. Only II works, so the answer is A.
This will require some code tracing. Here, I have written the code line by line with the contents of the array after each line. On the actual test on the test booklet, I would make an array and add elements as we go as well as cross out removed elements and add arrows to elements added in the middle of the array.
After Line 2: ["one"]
After Line 3: ["one", "two"]
After Line 4: ["three", "one", "two"]
After Line 5: ["three", "one", "four"]
After Line 6: ["three", "one", "four", "five"]
After Line 7:
So what happens to the list?Β When there is an even element, the item that would be next would now be in the previous index, but sinceΒ iΒ is incremented, the method skips that next item, which corresponds with E. Here is an example of what would happen:
// Suppose we have an ArrayList myList = [1, 2, 3, 5] and let's call
// removeEvens on this ArrayList.
// When i = 0, the element myList.get(0) = 1 is not even, so the array is
// untouched.
// When i = 1, the element myList.get(1) = 2 is even, so the 2 is removed
// and all the elements will shift to the left, so myList is now [1, 3, 5]
// When i = 2, the element myList.get(2) = 5, but we have skipped 3 because
// it is now at index 1 but i is looking for the new element at index 2!
We will need to trace some code here.
points.length = 4, points[0].length = 5;
row = 0
col = 4, 4 >= 0, "15 " printed
col = 3, 3 >= 0, "15 14 " printed
col = 2, 2 >= 0, "15 14 13 " printed
col = 1, 1 >= 0, "15 14 13 12 " printed
col = 0, 1 >= 0,
This question requires some more code tracing.
sum = 0
x = {1, 2, 3, 4} (x.length - 1 will always be 3)
y = 0, sum = 1, y = 1, sum = 3, y = 2, sum = 6, y = 3, 3 !< 3
We now move to a new row and repeat.
The method adds every number in the 2D array except from the last
column, which will turn out to be 54,
The static type of t is Thing1, while the dynamic type of t is Thing2. Since calc() is not a static method, the Thing2 version of calc() is used. Now we code trace.
IN THING2 CALC:
n = 2 -> 4
super.calc() -> use the calc method in the parent class, which is Thing1
THING1 CALC IS CALLED, IN THING1 CALC:
n = 4 -> 12, "12" is printed
BACK IN THING2:
n = 4,
TheΒ recursive codeΒ mystery1 with its call to itself adds 5 to the sum if n is greater than 1, and then adds 1 when n = 1, which is the base case. Remember that we can To achieve this with the looped code, mystery2, we need to initialize total to be 1, which is A.
You've finished the multiple-choice section of the exam, and after a short break, it's time for the second half of the test: the FRQ section. The FRQ section hasΒ 4 different FRQsΒ inΒ 90 minutes, the same amount of time as the multiple-choice portion.
The AP CSA test has 4 FRQs, each of which is different in style. Here's a little bit about them:
Methods and Control Structures
This FRQ asks you to write methods and master control structures such as loops and branching (if/else if/else).
Class Writing
This FRQ asks you to write an entire class, given specifications of what the class should do, and including any variables and methods the class should include.
Array/ArrayList
This FRQ asks you to write methods that use an array or ArrayList, including filtering and traversal. In recent years, the questions tend to be more about ArrayLists than standard arrays.
2D Arrays
This FRQ asks you to write methods that use a 2D array, including traversal of arrays.
Here are some tips that you should follow to ace the AP CSA FRQs.
Skip Parts You Don't Know
For all the multi-part questions on the FRQ, the later parts always state to refer to a past method that you have coded in an earlier part. Even though you may not know how to code this earlier method, you can still answer this question because you can assume that prior code works. This will prevent you from losing points twice because the earlier method is incorrect, thus preventingΒ double jeopardy. It saves a lot of time and you can jump back to the earlier part if you have time left!
Write Pseudocode Before Starting to Write the Final Solution
Before jumping to the actual question, write pseudocode as a multi-line comment so you can plan what you are going to do and what is needed for the code. It will also keep you from missing necessary components and keeps your future code organized when finally answering the question and writing real Java code.
Make Up Some Test Cases
If you are unsure of whether your solution is correct, make up some test cases and test the code that you have written on these different test cases. If you get the expected result for all the test cases, then your code is most likely correct. If not, then go back to the point where the code did not work as expected and see how you can correct it.
TheΒ 2019 AP CSA FRQsΒ are the most recent set that matches the format set by the Course and Exam Description. They are solved below with the rationale and pseudocode included.
/** Returns the number of leap years between year1 and year 2 inclusive
*
Precondition
: 0 <= year1 <= year2
*/
public static int numberOfLeapYears(int year1, int year2) {
/*
Pseudocode:
start looping from year 1 to year 2 inclusive, set a counter and add
to the counter if isLeapYear(year) is true
*/
int counter = 0;
for (int i = year1; i <= year2; i++) {
if isLeapYear(i) {
counter++;
}
}
return counter;
}
/** Returns the value representing the day of the week for the given date
* (month, day, year), where 0 denotes Sunday, 1 denotes Monday, ..., and 6 denotes Saturday
*
Precondition
: The date is a valid date.
*/
public static int dayOfWeek(int month, int day, int year) {
/*
Pseudocode first attempt
: Use dayOfYear to figure out how many days of the year it has been
in the year, and then modulo 7 to figure out how many days it has been,
then subtract 1 because January 1st is 1 and not 0 and add firstDayOfYear()
However, this may return a value larger than 6, which is outside our
desired range for the output so we should add firstDayOfYear()
and subtract 1 first before doing modulo to get the correct answer
*/
return (dayOfYear(month, day, year) - 1 + firstDayOfYear(year)) % 7;
}
/** Tracks steps walked
*/
public class StepTracker {
private int totalDays;
private final int ACTIVESTEPS;
private int activeDayCount;
private int totalSteps;
/** Creates a StepTracker with activeSteps specified and other necessary instance
* variables, including total steps, active days, and total days.
*/
public StepTracker(int activeSteps) {
ACTIVESTEPS = activeSteps;
totalDays = 0;
activeDayCount = 0;
totalSteps = 0;
}
/** Adds a day of steps to total steps and also checks if there is an active
* day. Also increments the total number of days
*/
public void addDailySteps(int stepsInDay) {
totalDays++;
totalSteps += stepsInDay;
if (stepsInDay >= ACTIVESTEPS) {
activeDayCount++;
}
}
/** Returns the number of active days
*/
public int activeDays() {
return activeDayCount;
}
/** Returns the average steps a day
*/
public double averageSteps() {
return (double) totalSteps / totalDays;
}
/** Returns an ArrayList of delimiters from the array tokens
*/
public ArrayList<String> getDelimitersList(String[] tokens) {
/* Traverse through the array, if a token is a delimiter, add it to the ArrayList
*/
ArrayList<String> delimiterList = new ArrayList<String>()
for (String token: tokens) {
if (token.equals(openDel) || token.equals(closeDel)) {
delimiterList.add(token);
}
}
return delimiterList;
}
/** Returns true if the delimiters are balanced and false otherwise
Precondition
: delimiters contains only valid open and close delimiters.
*/
public boolean isBalanced(ArrayList<String> delimiters) {
/*
Pseudocode
: Set a counter, which represents the number of unpaired
delimiters to 0 and for every open delimiter, add 1,
for every close delimiter, subtract 1, representing an open
delimiter has been paired return false if there is a close
delimiter when the counter is 0 (no open to pair with) or the counter
is not 0 in the end (not equal), else, return true
*/
int openCount = 0;
for (String delimiter: delimiters) {
if (delimiter.equals(openDel)) {
openCount++;
} else {
if (openCount == 0) {
return false;
} else {
openCount--;
}
}
}
return openCount == 0;
}
/** Constructs a LightBoard object having numRows rows and numCols columns.
*
Precondition
: numRows > 0, numCols > 0
*
Postcondition
: each light has a 40% probability of being set to on.
*/
public LightBoard(int numRows, int numCols) {
/* Traverse through each cell in the 2D array, for each cell, generate a random
integer from 0 to 9, if this integer < 4, set to true, else set to false
*/
import java.util.Random;
Random rand = new Random();
lights = new boolean[numRows][numCols];
for (int i = 0; i < numRows, i++) {
for (int j = 0; j < numCols; j++) {
if (rand.nextInt(10) < 4) {
lights[i][j] = true;
}
}
}
}
/** Evaluates a light in row index row and column index col and returns a status
*
Precondition
: row and col are valid indexes in lights.
*/
public boolean evaluateLight(int row, int col) {
/* First count the ons on the column, then check the status of the light in question
and proceed from there as in the instructions
*/
int columnCount = 0;
for (boolean[] row: lights) {
if (row[col]) {
columnCount++;
}
if (lights[row][col] && columnCount % 2 == 0) {
return false;
} else if (!lights[row][col] && columnCount % 3 == 0) {
return true;
}
return lights[row][col];
}
Β© 2024 Fiveable Inc. All rights reserved.