JavaRush /Java Blog /Random-TW /一次採訪的故事:有趣的問題
GuitarFactor
等級 30
Санкт-Петербург

一次採訪的故事:有趣的問題

在 Random-TW 群組發布
最近我有機會參加一家大型IT公司實習生的面試。 一次訪談的故事:有趣的問題 - 1這是我的第一次 IT 面試,在我看來,它很有趣。總共,我被「審問」了3個多小時(之前有作業和在辦公室電腦上進行的測試)。我要向面試官致敬,當我回答錯誤的時候,他並沒有放棄,而是在他的引導性問題的幫助下迫使我思考並得出正確的答案。以下我將提出幾個「草圖」——在我看來,相當有趣的問題,其中一些讓我對 Java 的某些方面有了更深入的了解。也許這些事情對某些人來說似乎是顯而易見的,但我認為這對某些人來說是有用的。下面的短語以下列字體突出顯示: 訪談者 - 粗體 畫外音解釋和我的想法 - 斜體 我的答案 - 採用常規字體 我們已經完成了背景知識,讓我們開始討論正題吧)

草圖 1.“看似簡單的方法”

寫下如何實現一個返回數字 a 除以數字 b 的結果的方法。 面試官寫在一張紙上
int divide(int a, int b) {
}
*我難以置信地看了一眼帶有方法簽名的紙。有什麼問題?*我寫道:
int divide(int a, int b) {
    return a/b;
}
這個方法有什麼問題嗎? *我抓住了一個非常愚蠢的笨蛋* 顯然不是.. 接下來是一個合理的問題: 如果b=0怎麼辦? *哇哦,如果我再這樣下去,我就要被趕出這個辦公室了!* 哦,是的,當然。這裡我們有 int 型別的參數,因此會拋出算術異常。如果參數的類型為 float 或 double,則結果將為 Infinity。 對此我們該怎麼辦? 我開始寫try/catch
int divide(int a, int b) {
    try {
        return a/b;
    } catch (Exception e) {
        e.printStackTrace();
        return ... // ??? what the hack?
    }
}
*我要返回並凍結:如果出現錯誤,需要返回一些東西。但如何才能將這個「東西」與計算結果區分開來呢?* 我們會回傳什麼? 嗯...我會將返回變數的類型更改為 Integer,如果出現異常,我將返回 null。 假設我們無法更改類型。我們能以某種方式出去嗎?也許除了例外我們還可以做點別的事? *來了* 我們也可以將它轉發給呼叫方法! 正確的。它會是什麼樣子?
int divide(int a, int b) throws ArithmeticException{
    return a/b;
}

void callDivide(int a, int b) {
    try {
        divide(a, b);
    } catch (ArithmeticException e) {
        e.printStackTrace();
    }
}
是否需要處理異常? 是的,因為我們明確地從divide方法中轉發它。(*我錯了!接下來是面試官提出​​的引導性問題,以得出正確答案*) 算術異常 - 它是什麼樣的異常 - 檢查或未檢查? 這是一個運行時異常,這意味著未經檢查。 *殺手問題來了* 所以,用你的話來說,如果我們在方法簽名中指定 throws Arithmetic Exception,那麼它就變成了檢查異常? *呃!* 可能...不。 是的,它消失了。如果我們在簽章中指明 throws /unchecked exception/ ,我們只是警告該方法可以拋出異常,但不需要在呼叫方法中處理它。就這麼解決了 我們還能做些什麼來避免錯誤嗎? *經過一番思考* 是的,我們還可以檢查 if (b==0)。並執行一些邏輯。 正確的。所以我們可以採取三種方式:
  • 試著抓
  • throws – 轉送到呼叫方法
  • 參數檢查
在這種情況下,divide您認為哪種方法較可取?
我會選擇將異常轉發給呼叫方法,因為...... 在divide方法中,尚不清楚如何處理此異常以及int發生錯誤時傳回哪種類型的結果。在呼叫方法中,我將使用參數 b 來檢查它是否等於零。 看來這個答案讓受訪者滿意了,但說實話,我不確定這個答案是否明確))

草圖 2.“誰更快?”

在標準問題「ArrayList 與 LinkedList 有何不同」之後,出現了這樣的問題: 會發生什麼更快 - 將元素插入到中間ArrayList還是插入到中間LinkedList *我跳到這裡,我記得我到處都讀到過類似“用於LinkedList在列表中間插入或刪除元素”之類的內容。在家裡我甚至仔細檢查了JavaRush講座,有這樣一句話:「如果你要在集合中間插入(或刪除)許多元素,那麼你最好使用LinkedList. 在所有其他情況下—— ArrayList” 自動應答* 使用 會更快LinkedList請澄清一下
  1. 為了在中間插入一個元素ArrayList,我們需要在常數時間內找到清單中的元素,然後在線性時間內重新計算插入元素右側元素的索引。
  2. 對於LinkedList..我們首先在線性時間內到達中間,然後在恆定時間內插入一個元素,改變相鄰元素的連結。
事實證明,哪個比較快? 嗯……結果是一樣的。 但什麼時候LinkedList更快呢? 事實證明,當我們將它插入到列表的前半部分時。例如,如果您將其插入到最開頭,則ArrayList必須重新計算直到最尾部的所有索引,但只需LinkedList更改第一個元素的參考。 寓意:不要相信字面上所寫的所有內容,即使是 JavaRush 中的內容!)

草圖 3:“如果沒有 equals 和 hashcode,我們會怎麼樣!”

關於 equals 和 hashcode 的對話非常長 - 如何覆蓋它、 中的實現是什麼Object、幕後發生了什麼、何時將元素插入HashMap等。我只會給出一些我認為有趣的觀點* 想像一下我們創建了一個類
public class A {
    int id;

    public A(int id) {
        this.id = id;
    }
}
他們並沒有覆蓋equalshashcode。描述程式碼執行時會發生什麼
A a1 = new A(1);
A a2 = new A(1);
Map<A, String> hash = new HashMap<>();
hash.put(a1, "1");
hash.get(a2);
*很好的是,在面試之前我專門花了幾天時間了解基本演算法、它們的複雜性和資料結構 - 這很有幫助,感謝 CS50!*
  1. 建立 A 類別的兩個實例

  2. 我們創建一個空地圖,預設有 16 個籃子。關鍵在於 A 類的對象,其中 和equals方法未被重寫hashcode

  3. 把它a1放在地圖上。為此,我們首先計算哈希值a1

    哈希值等於什麼?

    記憶體中單元的位址是類別方法的實現Object

  4. 根據哈希值,我們計算籃子指數。

    我們如何計算呢?

    *不幸的是,我在這裡沒有給出明確的答案。你有一個很長的數字——一個哈希值,並且有16個桶——如何定義一個索引,使得具有不同哈希值的物件均勻分佈在桶中?我可以想像該指數是這樣計算的:

    int index = hash % buckets.length

    我已經在家裡看到原始程式碼中的原始實作略有不同:

    static int indexFor(int h, int length)
    {
        return h & (length - 1);
    }
  5. 我們檢查沒有衝突並插入 a1。

  6. 讓我們繼續討論方法get。實例 a1 和 a2 保證具有不同的hash(記憶體中不同的位址),因此我們不會找到該鍵的任何內容

    如果我們只hashcode在 A 類中重新定義它,並嘗試先將一對鍵值是 a1,然後將 a2 的鍵值對插入到 hashmap 中,會怎麼樣?

    然後首先我們將透過以下方式找到所需的籃子hashcode- 此操作將正確執行。接下來,讓我們開始瀏覽Entry附加到購物車的 LinkedList 中的對象,並透過 比較鍵equals。因為 equals不被覆蓋,則從類別中獲取基本實現Object- 通過引用進行比較。a1和a2保證有不同的鏈接,因此我們會「錯過」插入的元素a1,而a2將作為新節點放入LinkedList中。

    結論是什麼?是否可以用作HashMap非重寫物件中的鍵equalshashcode

    你不能。

草圖4:“我們故意打破它!”

在有關錯誤和異常的問題之後,接下來的問題如下: 編寫一個簡單的範例,其中函數將拋出 StackOverflow。 *然後我記得當我嘗試編寫一些遞歸函數時,這個錯誤如何困擾我* 如果錯誤地指定了退出遞歸的條件,則在遞歸調用的情況下,可能會發生這種情況。 *然後我開始嘗試一些聰明的事情,最後面試官幫忙了,一切變得簡單*
void sof() {
    sof();
}
這個錯誤與 有何不同OutOfMemory *這裡我沒有回答,後來才知道這是一道關於Java記憶體知識Stack的問題Heap(物件的呼叫和引用都儲存在Stack中,物件本身儲存在Heap記憶體中)。因此,當記憶體中沒有更多空間可供Stack下一個方法調用,且OutOfMemory記憶體中物件的空間已用完時,StackOverflow 就會被拋出Heap*
這些都是我記得的採訪時刻。最後,我被接受了實習,所以我還有2.5個月的培訓時間,如果一切順利的話,我會在公司找到一份工作)如果有興趣,我可以再寫一篇文章,這次較小,對我在另一家公司面試時遇到的一個簡單但具有說明性的問題進行了分析。這就是我的全部內容,我希望這篇文章能幫助人們加深或組織他們的知識。大家學習愉快!
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION