字節跳動二面覆盤

感覺面試官挺不友好的,說不上來的怪。依舊沒有問項目。

這次其實挺虧的,很多問題都會,但是回答好像沒有get到面試官的點,然後算法當時太緊張也沒寫出來,面試完立刻就寫出來了c

Web

1. Nginx和Redis的網絡模型

Nginx採用Master-Worker多進程模型(易於管理,各個Worker不相互影響),多路複用

Redis基於內存和多路複用,同時採用單線程模型

2. Nginx反向代理使用TCP還是HTTP

看見這個題,我第一個反應是 ?HTTP不是基於TCP的嗎???,我說了nginx反向代理的Tomcat,Tomcat使用HTTP,所以是HTTP

3. TCP和HTTP的區別

  1. TCP屬於運輸層,HTTP屬於應用層
  2. TCP基於Socket,即IP+端口,而HTTP則是基於相對的url
  3. HTTP的長連接和多路複用基於TCP的長連接

4. Nginx緩存的方式

三種方式,基於文件,基於內存,通過lua腳本

5. 多個緩存失效時間不一樣怎麼辦

我回答的是採用hash,這樣一臺client就會鎖定一個緩存

6. 多路複用模型

多個IO請求註冊到select中,然後select負責阻塞,如果內核數據準備好了之後則會返回Select

多路複用分爲三種,分別是selector,poll,epoll

對於selector來說,使用數組,限制1024,selector需要把數據從用戶態拷貝到內核態,然後當selector中某個時間準備好之後就會重新把selector中的事件從用戶態拷貝到內核態,此時IO線程則在遍歷整個selector

對於poll來說,使用鏈表,沒有1024限制

對於epoll來說,使用map,每個請求都通過epoll_create()封裝爲一個epoll對象,然後通過epoll_ctl將epoll對象加入到內核態,有內核對事件進行準備,如果準備好則放入list中,epoll_wait相當於之前的select/poll的調用,只不過不需要遍歷整個事件

7. Epoll的邊緣觸發和水平觸發

水平觸發:當被監控的文件描述符上有可讀寫事件發生時,epoll_wait()會通知處理程序去讀寫。如果這次沒有把數據一次性全部讀寫完(如讀寫緩衝區太小),那麼下次調用 epoll_wait()時,它還會通知你在上沒讀寫完的文件描述符上繼續讀寫,當然如果你一直不去讀寫,它會一直通知你!!!如果系統中有大量你不需要讀寫的就緒文件描述符,而它們每次都會返回,這樣會大大降低處理程序檢索自己關心的就緒文件描述符的效率

邊緣觸發:當被監控的文件描述符上有可讀寫事件發生時,epoll_wait()會通知處理程序去讀寫。如果這次沒有把數據全部讀寫完(如讀寫緩衝區太小),那麼下次調用epoll_wait()時,它不會通知你,也就是它只會通知你一次,直到該文件描述符上出現第二次可讀寫事件纔會通知你!!!這種模式比水平觸發效率高,系統不會充斥大量你不關心的就緒文件描述符

代碼

8. 寫SQL

table A

Id Name
1 abc
2 bcd

table B

Id Age
1 15

寫出id,name,age

select A.id, name,
       (IF(B.age IS NULL, 0, B.age)) AS age
from A left outer join B
    on A.id = B.id;

9. 拷貝帶有random和next指針的鏈表

Leetcode 138

Node copyList(Node head) {
    Node p = head;
    Map<Node, Node> map = new HashMap<>();
    while (p != null) {
        map.put(p, new Node(p.val));
        p = p.next;
    }
    p = head;
    Node out = map.get(p);
    while (p != null) {
        map.get(p).next = map.get(p.next);
        map.get(p).random = map.get(p.random);
        p = p.next;
    }
    return out;
}

10. 找到數組中每個元素右邊最大的第一個元素

public int[] getMax(int[] arr) {
    int len = arr.length;
    Map<Integer, Integer> map = new HashMap<>(len);
    int[] out = new int[len];
    out[len - 1] = -1;
    map.put(out[len - 1], -1);
    for (int i = len - 1; i >= 0; i ++) {
		if (arr[i] < arr[i + 1]) {
            out[i] = arr[i + 1];
        } else {
            int temp = map.get(arr[i + 1]);
            whlie (temp != -1) {
				if (temp > arr[i]) {
					out[i] = temp;
                    break;
                }
            }
            out[i] = -1;
        }
        map.put(arr[i], out[i]);
    }
    return out;
}

11. 計算1000億個32位正整數重複度top100個元素所需的空間複雜度

1000億 / 100 = 10億 ≈ 2^30;

2^32*30 = 120G

我回答的是120G,但是面試官說是64G

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章