跳转至

2.0 T2

Q1

static Double mystery(Double[] values) {
    if (values.length < 1) throw new IllegalArgumentException();
    Double result = values[0];
    for (Double value : values) {
        if (result.compareTo(value) > 0) {
            result = value;
        }
    }
    return result
}

What is the best description for what this method returns?

Hint: The Java Documentation for x.compareTo(y) for Double says: This method returns the value 0 if y is numerically equal to x; a value less than 0 if x is numerically less than y; and a value greater than 0 if x is numerically greater than y.

Select the single most correct answer.

  • The minimum value in the array
  • The maximum value in the array
  • The median value in the array
  • The last value less than the first element in the array
  • The last value greater than the first element in the array

这道题正确答案是加粗行但是我选的是斜体行

这道题的核心在于 compareTo 这个方法,相等 0, x 小返回 -1, x 大返回 1

  • 5 - 6 行的核心逻辑在于从列表的第一个元素开始,只要其大于后续的元素,那么结果就是后续元素
  • 这个时候范围已经缩小到了正确以及我选的答案之间,由于对取最小算法的不熟悉怀疑其无法正确识别最小数,实际上找最大值也是如此:
if (result.compareTo(value) > 0) { // 如果 result 大于 value
    result = value; // 将 result 更新为更小的值 value
}

Q3

Which of the following statements about method overriding are true?

There may be multiple correct answers. Select all of them.

  • An overriding method will run the code in its body and then will automatically call the original version of the method.s
  • An overriding method must have the same name as the original.
  • An overriding method must have the same parameter types as the original.
  • An overriding method must be marked using the @Override annotation or it will fail to compile.

这道题错的很可惜,只选了第二个,第三个当时犹豫了,把 overloadoveride 搞混了,第四个是编译器不会报错不代表编译失败当时识别出来了。第六周的 Slide 11 中结合问答:

  • 除了 Covariant Return Types 也就是返回子类类型是合法的外,其他返回的类型、参数以及名称都必须与父类相同

Q6

public class Exceptional {
    public static int counter = 0;

    public static void go() throws Exception {
        counter++;
        try {
            counter++;
            if (counter > 0) throw new Exception("Uh-oh!");
            counter++;
        } catch (Exception e) {
            counter += 10;
        }
        if (counter > 0) throw new Exception("Not again!");
        counter++;
    }

    public static void main(String[] args) {
        Exceptional ex = new Exceptional();
        try {
            ex.go();
            counter++;
        } catch (Exception e) {
            counter += 10;
        }
        System.out.println(counter);
    }
}

这道题问最后 print 的是啥,直接运行代码跑出来是 22

考试的时候当时对 throw 异常后的机制不了解,实际上 throw 错误后会寻找最近能 catch 的地方。第五七行执行后为 2,第八行抛出后到了 catch 这里被抓住加了 10 变成了 12,十三行由于没有写 catch 只是抛出,因此直接进入 main 函数中的 catch 行再加 10 最终变成 22.

throw 语句会立即中断当前执行流,并寻找最近的匹配 catch 块,如果当前方法没有匹配的 catch,异常会向上层方法传播。


Q11

这题给了一半分数,说我 Missing <T> return type

// Picks the specified indices from `data` and returns a list of them
static ArrayList<Object> select(ArrayList<Object> data, int[] indices) {
    ArrayList<Object> result = new ArrayList<>();
    for (int index : indices) {
        try {
            result.add(data.get(index));
        } catch (IndexOutOfBoundsException e) {
            // Ignore invalid indices, do nothing
        }
    }
    return result;
}

Rewrite this as a generic method instead of using the Object type.

Object 类来创建可储存任意数据类型的类,但是实例化的时候需要类型转换并丢失类型检查

int three = (Integer) ss.pop();

改成 generics 实例化后是这样

GenericStack<Integer> intStack = new GenericStack<Integer>(5); 

Java 7 及之后: 引入了菱形运算符 <>。如果你在左侧显式声明了类型 RunningMaximum<Integer> runningMax,编译器就可以从左侧推断出右侧的泛型类型,所以你可以写成 RunningMaximum<Integer> runningMax = new RunningMaximum<>(1);,右侧 <> 中无需重复类型。

Java 10 及之后: 引入了 var。如果你在右侧的初始化表达式中提供了足够的信息让编译器推断出类型例如 new RunningMaximum<>(1),其中 1Integer如果构造函数接受 T 类型参数,编译器就能推断出 T 是 Integer,你就可以结合 var 和菱形运算符写成 var runningMax = new RunningMaximum<>(1);

可以看到这道题的核心问题就是出在案例里是有 1 作为参数的所以可以 <> 直接传再加上 var,但是这道题 Object 中就没指定 Arrarylist 大小,因此要么 <> 要么 var 选一种不能融合,属于理解不够透彻。在 Java 中,当你使用 new 关键字创建一个对象实例时,紧跟在类名后面的括号 () 用来调用类的构造器(Constructor)。当你使用 new ArrayList<>();创建 ArrayList 对象时,Java 会为它自动处理容量的分配

static ArrayList<T> select(ArrayList<T> data, int[] indices) {
    var result = new ArrayList<>();
    for (int index : indices) {
        try {
            result.add(data.get(index));
        } catch (IndexOutOfBoundsException e) {
            // Ignore invalid indices, do nothing
        }
    }
    return result;
}

因此考试时第二行错误就在少了个 T:

// 方式 1:使用 var,但提供右侧类型信息
var result = new ArrayList<T>(); 
// 编译器根据右边的 ArrayList<T> 推断 result 是 ArrayList<T>

// 方式 2:不使用 var,显式声明类型
ArrayList<T> result = new ArrayList<>(); 
// 左侧已经指定了类型,右边的 <> 可以使用类型推断(Java 7+)

Q12

Write the following:

  • An enum called Step with values LEFT and RIGHT.
  • A static method int displacement(Step[] steps) that, given an array of steps, computes how many steps to the right of your starting point you would be if you took those steps in that sequence (negative indicates left of starting point).

For example:

Step[] steps = new Step[]{Step.LEFT, Step.LEFT, Step.RIGHT, Step.LEFT};
System.out.println(displacement(steps));  // Should print -2
enum Step {
    LEFT(-1), RIGHT(1);

    int moveValue;

    Step(int moveValue){
        this moveValue = moveValue;
    }

    public int getValue(){
        return moveValue;
    }
}

static int displacement(Step[] steps){
    int counter = 0;
    for (step: steps){
        counter = counter + step.getValue();
    }
    return counter;
}

我直接按照笔记写的,反馈提到说

- Valid enum type

- Line 17: Missing Step type for step

第七行可以看到应该是 this.moveValue 第十七行没有声明 step 类型应该加上 Step


Q13

abstract class Student extends Person {
    public boolean isStudent() { return true; }
}

Write the following:

  • An abstract class called Person (from which Student inherits) that declares isStudent() as an abstract method.
  • An interface called Coder that declares a boolean canCode() method.
  • A non-abstract class called ComputingStudent that is a subclass of Student, inherits isStudent() from Student, and implements the Coder interface.

下面是我的代码:

public interface Coder {
    boolean canCode();
}

abstract class Person {
    abstract boolean isStudent();
}

class ComputingStudent extends Student implements Coder{

}

评论提示在 ComputingStudent 类中写 canCode 方法

  • 接口在概念上就是抽象的。显式地在接口声明前添加 abstract 关键字是多余的,编译器会自动将其视为抽象的。接口方法的默认属性 (Implicitly public abstract),所以第一行多余了 public
  • implements Coder必须实现 Coder 接口中的方法 canCode()

Q14

这道题来不及做

A substring of a string is any chunk of characters starting at some index and running for some length. For example, "TS20" is a substring of "CITS2005" starting at index 3 and of length 4.

We say a string contains a repeated substring if the same non-empty substring appears more than once in the string. For example, "banana" has several repeated substrings, including "ana", which appears at both indices 1 and 3.

Write a class RepeatChecker which has:

  • A static method boolean hasRep(String str, int len) that returns true if str contains a repeated substring of length len, and false otherwise.
  • A static method boolean hasRep(String str) that returns true if str contains any repeated substring, and false otherwise.

The efficiency of your algorithm is not important, but for full marks, you should avoid repeating code unnecessarily.

Hint: Recall that String has a .charAt(i) method that gets the character at a specific index, and that it also has a .length() method that returns the number of characters in the string.

写一个类可以返回这个字符串是不是有重复字符,第一个方法能自定义重复字段的长度

class RepeatChecker {
    private static boolean eqSubs(String str, int i, int j, int len) {
        for (int o = 0; o < len; o++) {
            if (str.charAt(i + o) != str.charAt(j + o)) return false;
        }
        return true;
    }
    public static boolean hasRep(String str, int len) {
        for (int i = 0; i + len <= str.length(); i++) {
            for (int j = i + 1; j + len <= str.length(); j++) {
                if (eqSubs(str, i, j, len)) return true;
            }
        }
        return false;
    }
    public static boolean hasRep(String str) {
        for (int len = 1; len < str.length(); len++) {
            if (hasRep(str, len)) return true;
        }
        return false;
    }
}