Main Problem & Solution

I had a song stuck in my head the whole time. I was pretty jittery when doing the test and was not able to entirely focus. While this is something I’ve had while taking a lot of other tests, it is something that I think I can improve upon. My goal is to whittle down my question times to at least 2:25, because if I have one hour and thirty minutes to complete 40 MCQ’s, then that is the maximum time that I shall grant myself on each question. To solve this, I shall employ deep work strategies to remove distractions at least 8 hours prior to the test to make it as authentic as I can in these circumstances.

Question 2:

Consider the following code segment.

for (int r = 3; r > 0; r--) {
    int c;

    for (c = 1; c < r; c++) {
        System.out.println("-");
    }

    for (c = r; c <= 3; c++) {
        System.out.println("*");
    }

    System.out.println();
}

What is printed as a result of executing the code segment?

My choice was A, and it was correct. The problem was that I did it very inefficiently and messy, and I had a good chance of messing up. It was partly by luck that I didn’t. I am currently looking for a time-efficient strategy to mentally or on-paper traverse through nested loops to visualize and make sense of them.

Question 3:

Consider the following two classes:

public class A {
    public void show() {
        System.out.println("A");
    }
}

public class B extends A {
    public void show() {
        System.out.println("B");
    }
}

What is printed as a result of executing the following code segment?

A obj = new B();
obj.show();

Although I again got the correct answer, I was confused at first on how inheritance worked with instantiation. Although I cleared this up to get the right answer, I was originally stumped, and think I need more practice on these sorts of questions.

Question 4:

Consider the following instance variable and method:

private int[] arr;

public int findMax() {
    int maxVal = 0;

    for (int val : arr) {
        if (val > maxVal) {
            maxVal = val;
        }
    }

    return maxVal;
}

Method findMax is intended to return the largest value in the array arr. Which of the following best describes the conditions under which the method findMax will not work as intended?

Although I did get the correct answer, it was hard. I originally didn’t pay attention to what the comment said about the value always being greater than 0.

Question 5:

Assume that x and y are boolean variables and have been properly initialized.

if ((x || y) && x) {
    
}

Which of the following always evaluates to the same value as the expression above?

Although I got the right answer this time, I was mistaken at first. 5. At first I thought it was x && y. But then, I realized that the value of (x && y) is true only when x is true and y is true, however, the value of (x   y) && x could be true if x is true and y is false. Therefore, these statements are not equivalent. Similarly, for the expression to evaluate to true, the expressions on either side of the && operator must be true. If x is true then x   y is true regardless of the value of y, meaning (x   y) && x evaluates to true. If x is false, the expression evaluates to false regardless of the value of (x   y).

Question 6

Consider the following method, which is intended to return true if at least one of the three strings s1, s2, or s3 contains the substring “art”. Otherwise, the method should return false.

public static boolean containsArt(String s1, String s2, String s3) {
    String all = s1 + s2 + s3;

    return (all.indexOf("art") != -1);
}

At first, I ruled out the correct answer because it had the intended substring in it. After rereading, I decided that it was in a combination of two words, which, compared with the other choices, didn’t seem very correct.

Question 7:

Consider the following code segment:

for (int outer = 1; outer <= 6; outer++) {
    for (int inner = outer; inner <= 6; inner++) {
        if (inner % 2 == 0) {
            System.out.print(inner + " ");
        }
    }
    System.out.println();
}

What will be printed as a result of executing the code segment?

Although I got the right answer, my work was messy and this was more of an educated guess than it was a confident right answer. I need a lot of practice with nested loops.

Question 8:

Consider the following method:

public static int[] operation(int[][] matrix, int r, int c) {
    int[] result = new int[matrix.length];

    for (int j = 0; j < matrix.length; j++) {
        result[j] = matrix[r][j] * matrix[j][c];
    }
    return result;
}

// The following code segment appears in another method in the same class:

int[][] mat = {3, 2, 1, 4},
               {1, 2, 3, 4},
               {2, 2, 1, 2},
               {1, 1, 1, 1};

// Which of the following represents the contents of an arr as a result of executing the code segment?

My choice was A, which was incorrect. This would be the result if the call was operation(mat, 0, 1); Recall that arrays in Java are indexed beginning at 0 not 1. The correct answer was B. In the first iteration of the for loop, j is 0. The value of result[0] is assigned the product of row 1, column 0, which is 1 and row 0, column 2, which is 1. Therefore, result[0] is assigned the value 1. The second iteration of the for loop, when j is 1, result[1] is assigned the product of row 1, column 1, which is 2, and row 1, column 2, which is 3. Therefore, result[1] is assigned the value 6. The third iteration of the for loop, when j is 2, result[2] is assigned the product of row 1, column 2, which is 3, and row 2, column 2, which is 1. Therefore, result[2] is assigned the value 3. The final iteration of the for loop, when j is 3, result[3] is assigned the product of row 1, column 3, which is 4, and row 3, column 2, which is 1. Therefore, result[3] is assigned the value 4.

Question 9:

A pair of number cubes is used in a game of chance. Each number cube has six sides, numbered from 1 to 6, inclusive, and there is an equal probability for each of the numbers to appear on the top side (indicating the cube’s value) when the number cube is rolled. The following incomplete statement appears in a program that computes the sum of the values produced by rolling two number cubes.

int sum = / * missing code * / ;

Which of the following replacements for /* missing code */ would best simulate the value produced as a result of rolling two number cubes?

My choice was C, which was incorrect. This would result in an integer between 0 and 10 inclusive, since (int)(Math.random() *6) generates an integer between 0 and 5 inclusive. While it does represent two independent random numbers being generated, to simulate the rolling of two number cubes, the value of each number should be between 1 and 6 inclusive to produce a sum in the range of 2 to 12. The correct choice was E. The call Math.random() will produce a double between 0 and 1, not including 1. To generate a random number in the range of 1 to 6, the call Math.random() needs to be multiplied by the number of integers you want to generate, in this case 6, giving us Math.random() * 6. This will result in a double between 0 and 6, not including 6. If we type cast this to an int, as in (int)(Math.random() * 6), the result will be an integer between 0 and 5 inclusive. Adding 1 will adjust the range to 1 to 6 inclusive, as in (int)(Math.random() * 6) + 1. This expression will simulate the rolling of one number cube. Since each roll is independent, to simulate rolling two number cubes, we need to use this expression twice which simplifies to 2 + (int)(Math.random() * 6) + (int)(Math.random() * 6).

Question 18:

// What is printed as a result of executing the following statement?

System.out.println(404 / 10 * 10 + 1);

My choice was E, which was incorrect. This would be the result if the division used was floating point division instead of integer division and the result was cast to an int, as in (int)(404.0 / 10 * 10 + 1). The correct answer was D, because the first operation that is executed is 404 / 10. Since both 404 and 10 are integers, integer division is used resulting in 40. The value 40 is then multiplied by 10, resulting in 400, and finally 1 is added, meaning 401 is printed.

Question 22:

Consider the following definition:

int[][] numbers = {1, 2, 3, 4, 5, 6};

Which of the following code segments produces the output 123456 ?

My choice was E. This is incorrect, because in this case, the nested for loop iterate over numbers in column major order and 142536 will be printed. The correct answer was A, because the outer for loop iterates over every row of numbers and assigns each row to the array row. The inner loop iterates over the array row accessing each element and assigning it to n. Then n is printed to the screen. In the first iteration of the outer loop, row is equal to {1, 2, 3}, and the inner loop will assign each successive value in row to n and print it to the screen, meaning 123 will be printed. For the second iteration of the outer loop, row is equal to {4, 5, 6}, and the inner loop will assign each successive value in row to n and print it to the screen, meaning 456 will be printed after 123, giving us the output 123456.

Question 26:

Consider the following two methods, which appear within a single class.

public static void changeIt(int[] arr, int val, String word) {
    arr = new int[5];
    val = 0;
    word = word.substring(0, 5);

    for (int k = 0; k < arr.length; k++) {
        arr[k] = 0;
    }
}

public static void start() {
    int[] nums = {1, 2, 3, 4, 5};
    int vlaue = 6;
    String name = "blackboard";

    changeIt(nums, value, name);

    for (int k = 0; k < nums.length; k++) {
        System.out.print(nums[k] + " ");
    }

    System.out.print(value + " ");
    System.out.print(name);
}

What is printed as a result of the call start() ?

My choice was A, which was incorrect. This would be the result if the first line in changeIt (arr = new int[5];) was removed. Parameters are passed using call by value. Call by value initializes the formal parameters (arr, val, word) with copies of the actual parameters (nums, value, name). When the parameter is a reference variable, the method receives a reference and can mutate the object being referenced but cannot alter the reference itself. Changing the reference stored in arr in changeIt does not affect the reference stored in nums in start so subsequent changes to the elements in arr are made in the new array not in nums. Updating val to 0 will not affect value. Since String objects are immutable, the substring call would need to be made in method start if we wanted name to be “black” instead of “blackboard”. Assigning a new value to word in changeIt does not affect name in start.

The correct choice was E. Parameters are passed using call by value. Call by value initializes the formal parameters (arr, val, word) with copies of the actual parameters (nums, value, name). When the parameter is a reference variable, the method receives a reference and can mutate the object being referenced but cannot alter the reference itself. Passing an object reference as a parameter will result in the formal parameter and the actual parameter being aliases. They both refer to the same object. When we call changeIt and pass the objects num and name, the formal parameters arr and word will reference these same objects. A copy of the object is not made. However, the first part of the method assigns new objects to arr and word, which means that any changes made to arr and word do not affect the actual parameters num and name. They remain unchanged. Updating val to 0 will not affect value. Therefore, the original values for num, value and name are printed.

Question 39 (5-Minute Lesson):

Problem:

Consider the following code segment:

List<String> students = new ArrayList<String>();

students.add("Alex");
students.add("Bob");
students.add("Carl");

for (int k = 0; k < students.size(); k++) {
    System.out.println(students.set(k, "Alex") + " ");
}

System.out.println();

for (String str : students) {
    System.out.print(str + " ");
}

I got this one correct. It is a matter of ArrayLists, understanding their methods, and visualizing how loops work. At this point in the test, I was able to do so pretty well. Let’s now go over each of the wrong choices and explain why they were wrong:

A: This would be the case if the set method returned the value that was stored in the element after it was assigned “Alex” instead of returning the value being replaced “Alex”.

B: In this case the lines of output are reversed.

D: This would the result if the first for loop used the get method instead of the set method.

E: The set method can be used in the System.out.print() method, because it returns the value that was at this index before it was updated to “Alex”.

Finally, choice C was correct. This is because the first for loop uses the set method to change the value of each element in students to “Alex”. When the set method is called, it returns the value that was originally at this index. So, the first loop will print Alex Bob Carl. At this point all elements have been set to “Alex”. The second for loop uses an enhanced for loop to access every element and will print Alex Alex Alex.

If you got this wrong, I would suggest going back to ArrayList methods and how to traverse an ArrayList through different methods and algorithms. Since this was the student lesson I taught, I didn’t struggle with these questions, and I also know how to help those who might be struggling.

Reflection:

Reflecting on my experience practicing the 2015 APCSA (AP Computer Science A) Multiple-Choice Questions (MCQ), I found that it provided valuable insights into my strengths and areas for improvement, particularly in the context of nested for loops, test-driven development, and visualizing 2D array problems.

Firstly, tackling nested for loops revealed both my ability to understand their syntax and structure, as well as areas where I could enhance my efficiency. It became apparent that I should prioritize clarity and readability in my code. To improve, I plan to break down complex nested loops into smaller, more manageable components. Additionally, I will focus on understanding the logic and purpose of each loop, ensuring that the code is not only correct but also easy to follow for both myself and others.

The practice test emphasized the significance of incorporating test-driven development (TDD) principles into my coding process. By constructing meaningful test cases before implementing the actual code, I can create a clear roadmap for the solution. This approach not only helps catch potential errors early but also provides a structured approach to problem-solving. Moving forward, I intend to integrate TDD more consistently into my practice sessions to reinforce this beneficial habit.

Visualizing 2D array problems emerged as a key challenge during the practice test. Enhancing my ability to mentally represent and manipulate arrays in two dimensions is crucial for solving such problems efficiently. To address this, I plan to engage in more hands-on exercises, such as drawing diagrams or using online tools to visualize arrays. This practice will not only improve my understanding of array structures but also enhance my problem-solving skills in the context of 2D arrays.

In summary, the 2015 APCSA MCQ practice served as a valuable learning experience, shedding light on specific areas for improvement. I am committed to refining my skills in nested for loops by prioritizing readability, embracing test-driven development to enhance my coding process, and investing time in visualizing 2D array problems. Through focused practice and continuous learning, I aim to strengthen my foundation in these crucial aspects of computer science.