概述#

本書的解答大多以 Java 實作,因此本章只聚焦在 Java 語言特性與語法本身的問題。這類題目在大公司(如 Google、Facebook)較少見,因為大公司更重視能力而非語言知識;但在其他公司可能相當常見。


如何應對語言知識題(How to Approach)#

這類題目雖然以知識為主,但若遇到記不起來的情況,可以嘗試以下方法:

  1. 建立一個具體的情境範例,思考應該如何運作
  2. 問自己:其他語言是如何處理這個情境的?
  3. 思考:如果你是這門語言的設計者,你會怎麼設計?每種選擇的意涵是什麼?

面試官可能對「推導出答案」的過程印象更深刻,而不只是「記住了答案」。若真的不確定,坦白說「我不確定是否記得答案,但讓我試著推導看看…」往往比亂猜更好。


Overloading vs. Overriding#

Overloading(多載)#

兩個方法同名,但參數的型別或數量不同

public double computeArea(Circle c) { ... }
public double computeArea(Square s) { ... }

Overriding(覆寫)#

子類別的方法與父類別的方法具有相同的名稱和簽章(function signature)

public abstract class Shape {
    public void printMe() {
        System.out.println("I am a shape.");
    }
    public abstract double computeArea();
}

public class Circle extends Shape {
    private double rad = 5;
    public void printMe() {
        System.out.println("I am a circle.");
    }
    public double computeArea() {
        return rad * rad * 3.15;
    }
}

public class Ambiguous extends Shape {
    private double area = 10;
    public double computeArea() {
        return area;
    }
}

public class IntroductionOverriding {
    public static void main(String[] args) {
        Shape[] shapes = new Shape[2];
        Circle circle = new Circle();
        Ambiguous ambiguous = new Ambiguous();

        shapes[0] = circle;
        shapes[1] = ambiguous;

        for (Shape s : shapes) {
            s.printMe();
            System.out.println(s.computeArea());
        }
    }
}

上述程式碼的輸出:

I am a circle.
78.75
I am a shape.
10.0

注意:Circle 覆寫了 printMe(),而 Ambiguous 沒有,因此使用父類別的預設實作。


Collection Framework#

Java 的 Collection Framework 非常實用,在面試和實際開發中廣泛使用。

ArrayList#

動態調整大小的陣列,隨著元素新增自動擴展:

ArrayList<String> myArr = new ArrayList<String>();
myArr.add("one");
myArr.add("two");
System.out.println(myArr.get(0)); // prints <one>

Vector#

ArrayList 非常類似,但 Vector同步的(synchronized),適用於多執行緒環境:

Vector<String> myVect = new Vector<String>();
myVect.add("one");
myVect.add("two");
System.out.println(myVect.get(0));

LinkedList#

Java 內建的 LinkedList 類別。雖然在面試中不常直接用到,但它的 iterator 語法很有參考價值:

LinkedList<String> myLinkedList = new LinkedList<String>();
myLinkedList.add("two");
myLinkedList.addFirst("one");
Iterator<String> iter = myLinkedList.iterator();
while (iter.hasNext()) {
    System.out.println(iter.next());
}

HashMap#

廣泛使用的 key-value 資料結構,在面試中十分常見:

HashMap<String, String> map = new HashMap<String, String>();
map.put("one", "uno");
map.put("two", "dos");
System.out.println(map.get("one")); // prints "uno"

在面試前,確保你對以上語法非常熟悉,因為這些結構會在各種題目中反覆用到。


面試題目列表#

題號題目
13.1Private Constructor:就繼承而言,將建構子設為 private 有什麼影響?
13.2Return from Finally:在 try-catch-finally 的 try 區塊中加入 returnfinally 區塊還會執行嗎?
13.3Final, etc.:finalfinallyfinalize 的差異是什麼?
13.4Generics vs. Templates:解釋 C++ 的模板和 Java 的泛型(Generics)的差異
13.5TreeMap, HashMap, LinkedHashMap:三者的差異,以及各自最適合的使用情境
13.6Object Reflection:解釋 Java 中的物件反射(Object Reflection)及其用途
13.7Lambda Expressions:使用 Lambda 計算特定大陸的總人口
13.8Lambda Random:使用 Lambda 回傳一個隨機子集合