AP CSA 错题本

Barron 书 Practice Test 1

14【Java 语法】

for (Clock[] row : allClocks)
    for (Clock c : row)
        /* more code */

Assuming the Clock class works as specified, which replacement for /* more code */ will cause an error?

  • System.out.print(c)
  • c.setTime(0, 0, 0);
  • c = new Clock(0, 0, 0);

III only.

You should not use an enhanced for loop to replace elements, only to access (as in segment I) or modify using a mutator method (as in segment II). Note that segment III will compile and execute, but won’t replace the clocks in allClocks as intended.

这个选项不会报错,但是逻辑有误。和 C++ 一样,循环中修改的是元素的副本,无法修改到 allClocks 中的元素。

类似的还有 Practice Test 2 第 6 题。

18【算法】

有一个严格升序的数组 \(a_{[0,63]}\)

哪几句话是对的:

  • 二分查找 \(a_0\) 要花 \(7\) 次迭代。
  • 二分查找判断一个比 \(a_0\) 小的数(即判断出它不存在)要花 \(7\) 次迭代。
  • 二分查找 \(a_{62}\) 要花 \(<7\) 次迭代。

II and III only.

I:6 次

Iteration 1: [0,63]
Iteration 2: [0,30]
Iteration 3: [0,14]
Iteration 4: [0,6]
Iteration 5: [0,2]
Iteration 6: [0,0]

II:7 次

Iteration 1: [0,63]
Iteration 2: [0,30]
Iteration 3: [0,14]
Iteration 4: [0,6]
Iteration 5: [0,2]
Iteration 6: [0,0]
Iteration 7: [0,-1]

III:6 次

Iteration 1: [0,63]
Iteration 2: [32,63]
Iteration 3: [48,63]
Iteration 4: [56,63]
Iteration 5: [60,63]
Iteration 6: [62,63]

21【CS 常识】

Precondition: a[0]...a[n-1] 是一堆整数。
代码会按顺序挑出 a 中的所有自然数(有 c 个),并将 n 设为 c。

Which is the best postcondition for the segment?

(排除了离谱选项后:)

  • (B) a[0]...a[n-1] contains no negative integers.
  • (E) The updated value of n is less than or equal to the value of n before execution of the segment.

(B).

The postcondition should be a true assertion about the major action of the segment.

Note that even though choice E is a correct assertion about the program segment, it’s not a good postcondition because it doesn’t describe the main modification to array a (namely, all negative integers have been removed)

总之 postcondition 就是要选一个能描述代码功能的选项,而不是仅仅是一个正确的 assertion。

23【CS 常识】

你要测试以下的代码:

\[f(w) = \begin{cases} \$4.00 & 0 < w \le 2 \\ \$8.00 & 2 < w \le 5 \\ \$15.00 & 5 < w \le 20 \\ \text{Does not accept} & \text{otherwise} \\ \end{cases}\]

你应该选择的测试数据集是:

  • (A) \(0,2,5,20\)
  • (B) \(1,4,16\)
  • (C) \(-1,1,2,3,5,16,20\)
  • (D) \(-1,0,1,2,3,5,16,20,22\)
  • (E) All integers from \(-1\) through \(22\)

(D).

  1. Test data should always include a value from each range in addition to all boundary values.

  2. 不合法数据也要有。
  3. 在满足以上两条时,尽可能减少数据。

根据 1 可以排除 (A)(B),根据 2 可以排除 (C)(不合法数据不够完整),根据 3 排除 (E)。

31【Java 语法】

ThreeDigitInteger 是一个 class,有一个子类叫 ThreeDigitCode。

ThreeDigitCode 有一个 ThreeDigitInteger 没有的方法,叫做 isValid。
ThreeDigitInteger code = new ThreeDigitCode(127); // I
ThreeDigitInteger num = new ThreeDigitInteger(456); // II
ThreeDigitCode newCode = new ThreeDigitCode(241); // III

上述三个对象哪一个调用 isValid 时不会报错?


III only.

I 和 II 都是 ThreeDigitInteger,没有 isValid 方法,即使其中 code 实际上指向了一个 ThreeDigitCode

37【Java 语法】

Banner 是一个类,其中含有 BlockLetter 的对象。

BlockLetter 有 26 个子类,分别叫做 LetterA ... LetterZ。

BlockLetter 有一个 public void draw() 的方法。

Each of the subclasses shown implements the draw method in a unique way to draw its particular letter.

下面这个 statement 对吗:

Each of the subclasses LetterA, ...LetterZ has an overridden draw method.


对的。Override 的意思是重写,就是说对父类已有的方法进行了重新实现。

自己写代码的时候,@Override 标识可以在代码中明示这一点。

Barron 书 Practice Test 2

4【Java 语法】

int num = 0, score = 10;
if (num != 0 && score / num > SOME_CONSTANT)
    statement1();
else
    statement2();

以下哪个会发生:

  • (A) ArithmeticException
  • (B) Syntax Error
  • (C) 执行 statement1
  • (D) 执行 statement2

(D). Java 与 C++ 一样,&& 在前一项是 false 时会短路(Short-circuit evaluation)。

同理,|| 在前一项是 true 时也会短路。

6【Java 语法】

for (int[] row : mat)
    for (int num : row)
        num = 100;

这段代码能否把 mat 的所有元素赋值为 100


否。虽然这段代码不会报错,但是和 C++ 一样,这样并不能成功改到 mat 内部的值。

类似的还有 Practice Test 1 第 14 题。

16【Java 语法】

public class Main {
    public static void main(String[] args) {
        Performer p = new Singer();
        p.act();
    }
}

class Performer {
    public void act() {
        System.out.print(" bow");
        perform();
    }
    public void perform() {
        System.out.print(" act");
    }
}

class Singer extends Performer {
    public void act() {
        System.out.print(" rise");
        super.act();
        System.out.print(" encore");
    }

    public void perform() {
        System.out.print(" aria");
    }
}

这个代码的输出是?


rise bow aria encore

  1. 首先 p 虽然是个 Performer 但是其实是个 Singer 对象,所以调用 act 时根据动态绑定,进 Singeract,输出 rise
  2. super.act() 调用 Performeract。输出 bow
  3. Performeract 中的 perform 根据动态绑定调用 Singerperform。输出 aria
  4. 回到第一步,输出 encore

24【Java 语法】

Employee 是一个类,有一个子类 PartTimeEmployee。
PartTimeEmployee 有一个方法 getPayFraction 是父类没有的。
Employee p = new PartTimeEmployee("Rafael Frongillo", 287, 40000, 7000, 0.8);
double g = p.getPayFraction();

会报错吗?


Yes. 动态绑定只能用于在编译时已知的方法,对于子类特有的方法,必须要向下转型才能访问。

31【算法】

A sorted list of 120 integers is to be searched to determine whether the value 100 is in the list. Assuming that the most efficient searching algorithm is used, what is the maximum number of elements that must be examined?


\(7\) 个。

首先不难猜到是二分查找,结论是:

\(n\) 个元素的序列找一个数(或判断不存在),最坏情况最少要看 \(\lceil \log_2 (n+1) \rceil\) 个数。

套进去:\(\lceil \log_2 (120+1) \rceil = 7\) 完事。

接下来论述一下正确性。

TODO:

37【Java 语法】

TennisPlayer 类有一个子类 WeakPlayer,WeakPlayer 类有一个子类 Beginner。
public static void giveEncouragement(WeakPlayer t) {
    /* implementation not shown */
}
public static void main(String[] args) {
    TennisPlayer w = new WeakPlayer();
    TennisPlayer b = new Beginner();
    Beginner bp = new Beginner();

    giveEncouragement(w); // I
    giveEncouragement(b); // II
    giveEncouragement(bp); // III
}

I II III 中哪些会报错?


I and II only.

错误: 不兼容的类型: TennisPlayer无法转换为WeakPlayer

编译器只看编译时类型,所以和上面 24 题一样,需要向下转型才不会报错。

Barron 书 Diagnostic Test

3【Java 语法】

// list 是一个 ArrayList<Integer>
for (Integer num : list) {
    if (/* condition */)
        list.add(0);
}

这个程序会报什么错误?


ConcurrentModificationException

这个题和 Practice Test 1 第 14 题 & Practice Test 2 第 6 题不一样。这个题的容器是 ArrayList 而不是数组,在遍历这种容器时修改内部东西是会报错的!

类似 C++ 中的迭代器机制,你乱动容器会让迭代器寄掉。

5【Java 语法】

Card 有一个 toString 方法。
// II
for (Card card : deck)
    System.out.println(card);

// III
for (Card card : deck)
    System.out.println((String) card);

哪个可以正常运行?


II only.

toString 不能提供 CardString 的隐式转换。实在要写的话,也应该写 card.toString()

8【CS 常识】

A method is to be written to search an array for a value that is larger than a given item and return its index. The problem specification does not indicate what should be returned if there are several such values in the array. Which of the following actions would be best?

  • (A) The method should be written on the assumption that there is only one value in the array that is larger than the given item.
  • (B) The method should be written so as to return the index of every occurrence of a larger value.
  • (C) The specification should be modified to indicate what should be done if there is more than one index of larger values.
  • (D) The method should be written to output a message if more than one larger value is found.
  • (E) The method should be written to delete all subsequent larger items after a suitable index is returned.

C.

Here is one of the golden rules of programming: Don’t start planning the program until every aspect of the specification is crystal clear. A programmer should never make unilateral decisions about ambiguities in a specification.

24【Java 语法】【冷门】

// I
String s = null;
String t = "";
if (s.equals(t))
    System.out.println("empty Strings?");
// III
String s = "holy";
String t = s.substring(4);
System.out.println(s + t);

哪个会报错?


I only.

I 报 NullPointerException,非常合理。

III 不会报错。很让人惊讶的是,Deepseek 在这题给了我错误的回答。

具体技术细节:String (Java Platform SE 8 )

public String substring(int beginIndex)
Returns a string that is a substring of this string. The substring begins with the character at the specified index and extends to the end of this string.

Examples:

"unhappy".substring(2) returns "happy"
"Harbison".substring(3) returns "bison"
"emptiness".substring(9) returns "" (an empty string)

Parameters:

beginIndex - the beginning index, inclusive.

Returns:

the specified substring.

Throws:

IndexOutOfBoundsException - if beginIndex is negative or larger than the length of this String object.

总之,s.substring(s.length()) 不会因为越界报错,但是只会得到空串。

34【Java 语法】【困难】

public class Caller {
    private ArrayList<Integer> numbers;

    public Caller() {
        numbers = getList();
        shuffleNumbers();
    }

    /** Returns the numbers 0...90 in order. */
    private ArrayList<Integer> getList() {
        /* implementation not shown */
    }

    /** Shuffle the numbers. */
    private void shuffleNumbers() {
        /* implementation not shown */
    }
}

When the programmer tests the constructor of the Caller class, she gets a NullPointerException. Which could be the cause of this error?

  • (A) The Caller object in the driver class was not created with new.
  • (B) The programmer forgot the return statement in getList that returns the list of Integers.
  • (C) The declaration of numbers is incorrect. It needed to be private ArrayList<Integer> numbers = null;
  • (D) In the getList method, an attempt was made to add an Integer to an ArrayList that had not been created with new.
  • (E) The shuffleNumbers algorithm went out of range, causing a null Integer to be shuffled into the ArrayList.

(D).

首先排除 (C),因为加不加 = null 都是一样的。

然后排除 (A),因为不 new 的话根本不会到 constructor 那里,也就不会发生异常。

然后排除 (B),因为这个是 CE 而非空指针异常;排除 (E),因为这个是 IndexOutOfBoundsException 而非空指针异常。

(D) 是正确的,ArrayList 创建出来之后不 new 一个给它的话,默认是 null,一操作就寄了。

posted @ 2025-04-02 19:43  August_Light  阅读(29)  评论(0)    收藏  举报