2020求職筆記(一)

引子

人生已經如此地艱難,我卻還要找工作,我真的好難。一個工作不到兩年的渣渣要在這個時候去找工作,這是何等的無所畏懼與狂妄!年輕人,加油!

前幾天投了一些簡歷,經歷了一些筆試、面試,這裏就記錄一下自己求職的心路歷程,並且記錄一下自己在筆試、面試中碰到的題目。

題目

1、線程的六種狀態?

線程的六種狀態在 Thread.State 枚舉中定義:

public enum State {
    NEW,
    RUNNABLE,
    BLOCKED,
    WAITING,
    TIMED_WAITING,
    TERMINATED;
}
  • 當線程剛創建的時候,處於 NEW 狀態,此時線程還沒開始執行。
  • 當線程的start()方法被調用後,線程開始執行任務,進入 RUNNABLE 狀態。
  • 當線程在執行任務的過程中 遇到了 synchronized 同步塊,線程就會進入 BLOCKED 狀態。
  • 如果線程在執行的過程中,碰到一些特殊的事件,線程就會進入 WAITING、TIMED_WAITING 狀態。比如同步塊中的對象調用 wait() 方法,那當前線程就要等待該對象調用 notify()/notifyAll()方法;通過join()方法等待的線程則會等待目標線程的終止。一旦等到了期望的事件,線程就會繼續執行,進入 RUNNABLE 狀態。
  • 當線程執行完畢,進入 TERMINATED 狀態。

在有的書籍、文檔中,將這裏描述爲“線程的五種狀態”。比如,在阿里出品的《碼處高效》這本書的第七章中,就將這裏描述爲“線程的五種狀態”,如下圖:

實際上,就是將 WAITING 和 TIMED_WAITING 也劃入到了 BLOCKED 狀態中,TERMINATED 換成了 DEAD 狀態。不管怎麼分,原理都是一樣的。

2、Object.wait() 和 Thread.sleep() 的區別?

相同點:兩者都可以讓線程等待一定時間。

不同點:

  • 無論是 wait()方法還是 notify() 方法,在調用前必須先獲得目標對象的一個監視器。在wait()方法執行完後,會釋放掉這個監視器。也就是說,wait()方法和notify()方法必須包含在調用對象的 synchronized 塊中。
  • wait()方法可以被主動喚醒,而Thread.sleep() 只能等待時間走完。
  • wait()方法會釋放掉目標對象的鎖,而Thread.sleep()不會釋放任何資源。

3、Redis持久化,RDB與AOF,聊一下?

RDB的工作方式:

默認情況下,Redis將數據集的快照保存在一個 .rdb 文件中。一般情況下,我們有三種方式開啓RDB持久化:

  1. SAVE命令:一般不用,原因是這是一個同步操作,在寫文件期間,服務端將阻塞客戶端的讀寫請求。
  2. BGSAVE命令:客戶端執行 BGSAVE命令後,服務端將會 fork() 一個子進程去進行持久化操作,父進程仍然爲客戶端服務。子進程持久化完畢後會自己退出。需要注意的是,fork() 子進程 這個操作本身仍然是同步的,如果Redis中的數據集太大,fork()操作可能也會耗時。
  3. 通過配置,自動持久化。我們可以通過在Redis.conf中配置,比如【SAVE 300 1】,這就表示在 300 秒內,只要有 1 次寫入操作,服務端就會自動持久化一次。其工作方式和 BGSAVE 類似。

AOF的工作方式:

每次Redis執行數據集修改的命令,都會被異步追加到AOF文件的末尾。默認情況下,AOF這種持久化方式是關閉的。

AOF有三種持久化策略:

  1. always:每一次寫入命令,都追加到AOF文件的末尾。
  2. everysec:每一秒將前一秒新增的數據追加到AOF文件的末尾。
  3. no:操作系統決定何時追加緩衝區的數據。

AOF日誌重寫:

有兩種方式可以進行AOF日誌重寫:

  1. BGREWRITEAOF命令:當客戶端執行該命令時,服務端將開啓一個AOF重寫進程,重寫一個 包含重建當前內存中數據集所需的最短命令序列 的臨時文件。
  2. 服務端自動重寫。這裏不多加介紹了,詳情請參閱我的另一篇專門講Redis持久化的文章。

默認情況下,只有在後臺沒有進程正在進行持久化操作時,AOF重寫纔會被觸發。

AOF日誌重寫,RDB前導:

在重寫AOF文件時,Redis能夠在AOF文件中使用RDB文件作爲前導,以便更快地重寫和恢復。

RDB和AOF的優缺點對比:

  • RDB文件非常緊湊,而數據集相同的情況下,AOF文件往往更大,不利於網絡傳輸;
  • 與AOF相比,在恢復一些大數據集的時候,RDB一般都會快一些;
  • 根據使用的策略不同,RDB可能會丟失一小段時間的數據,AOF保存的數據往往更加完整;
  • AOF文件更容易被人讀懂,而RDB則對人工閱讀不友好。

詳情參考:Redis學習筆記(一):Redis持久化——RDB與AOF

4、MySQL事務隔離級別有哪些?分別解決什麼問題?

參考:《MySQL事務的特性與隔離級別》

5、JavaGC機制,簡單聊一下?

參考:《JVM學習筆記(二):JVM GC機制與垃圾收集器》

6、緩存穿透、緩存擊穿、緩存雪崩,是怎麼回事呢?如何解決這些問題?

緩存穿透:訪問一個原本不存在的Key,就會穿透緩存。流量大時,數據庫會掛掉。

解決方案:

  1. 布隆過濾器很好地解決了緩存穿透的問題;
  2. 使用key進入數據庫查詢時,即使沒有查到值,也將空值寫入數據庫;

緩存擊穿:一個存在的Key,在過期的一瞬間,大量的請求過來,這些請求都會擊穿到數據庫,造成數據庫瞬間壓力大增。

解決方案:

  1. 在訪問Key之前,使用 SETNX 來設置一個短期的Key來鎖定當前Key的訪問,訪問結束再刪掉該短期Key。
  2. 給獲取緩存的方法加鎖,這樣在高併發時大大降低了吞吐量。
  3. 定時刷新緩存。

緩存雪崩:大量的Key設置了同樣的過期時間,導致大量的緩存在同一時間全部過期,造成數據庫壓力瞬間增大,引起雪崩。

解決方案:

  1. 在給Key設置過期時間時,加上一個隨機值,使Key的過期時間分佈開來,不會集中在同一時刻失效。

總結

這公司的面試,現在就記得問了這些了。面試的問題不多,大概也就面了半個小時左右。正在整理這篇文章的時候,才發現,原來自己當時回答JVM垃圾回收算法的時候,回答的不完整,只回答了對象生存判定的兩個方式。嗯,溫故而知新~加油!

參考文檔

1、《實戰·Java高併發程序設計》第二版,葛一鳴 著,第二章。

2、《碼出高效》,孤盡、鳴沙 著,第七章。

3、https://blog.csdn.net/Zereao/article/details/99471588

4、https://blog.csdn.net/Zereao/article/details/103564297

5、https://blog.csdn.net/Zereao/article/details/103563850

6、https://www.jianshu.com/p/b57d0773ee96

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