面試總結的問題

synchronized的用法

synchronized是Java中的一個關鍵字,是一種同步鎖,修飾的對象有以下幾種:
1、修飾一個代碼塊,被修飾的代碼塊稱爲同步語句塊,其作用範圍是括號括起來的代碼,作用的對象是調用這個代碼塊的對象。
2、修飾一個方法,被修飾的方法稱爲同步方法,其作用範圍是整個方法,作用的對象是調用這個方法的對象。
3、修飾一個靜態的方法,其作用範圍是整個靜態方法,作用的對象是這個類的所有對象。
4、修飾一個類,其作用範圍是synchronized後面括號括起來的部分,作用的對象是這個類的所有對象。

Redis哈希槽

https://blog.csdn.net/tianyeshiye/article/details/79600014

數據結構

https://blog.csdn.net/yeyazhishang/article/details/82353846
1、數組Array
2、棧 stack
3、隊列 queue
4、鏈表 linked list
5、樹 tree
6、散列表 hash
7、堆 heap
8、圖 graph

三次握手四次揮手

https://blog.csdn.net/qq_38950316/article/details/81087809

jsp與servlet區別

https://blog.csdn.net/forward__/article/details/57079115

重定向和轉發的區別,以及能到百度嗎

https://blog.csdn.net/liubin5620/article/details/79922692
區別:
轉發(forward)瀏覽器的地址欄不變,重定(Redirect)向瀏覽器的地址欄改變。
轉發是服務器行爲,重定向是客戶端行爲。
轉發是瀏覽器只做一次訪問請求。重定向瀏覽器至少做兩次訪問請求。
轉發兩次跳轉之間傳輸的信息不會丟失,重定向兩次跳轉之間傳遞的信息會丟失。
轉發和重定向的選擇:
1、重定向的速度比轉發慢,因爲瀏覽器還要發出一個新的請求,如果在使用轉發和重定向都無所謂的情況下,建議使用轉發。
2、因爲轉發只能訪問當前web的應用程序,所以不同web應用程序之間的訪問,特別是要訪問到另一個web站點上資源的情況,就只能使用重定向了。

MAP遍歷的方式

一、在鍵值都需要的時候使用

Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 
for (Map.Entry<Integer, Integer> entry : map.entrySet()) { 
  System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); 
}

二、在for each循環中遍歷keys和values
如果只需要map中的鍵或者值,可以通過keySet或values來實現遍歷。

Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 
//遍歷map中的鍵 
for (Integer key : map.keySet()) { 
  System.out.println("Key = " + key); 
} 
//遍歷map中的值 
for (Integer value : map.values()) { 
  System.out.println("Value = " + value); 
}

三、使用iterator遍歷。

Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator(); 
while (entries.hasNext()) { 
  Map.Entry<Integer, Integer> entry = entries.next(); 
  System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); 
}

這種方式看起來冗餘,卻有其優點所在,首先在老版本Java中這是唯一遍歷map的方式,同時可以在遍歷map的同時使用iterator.remove()來刪除數據。
四、通過鍵找值遍歷

Map<Integer, Integer> map = new HashMap<Integer, Integer>(); 
for (Integer key : map.keySet()) { 
  Integer value = map.get(key); 
  System.out.println("Key = " + key + ", Value = " + value);

dubbo(※)

下次再問dubbo,一定給他吹出花來。
https://blog.51cto.com/13732225/2295896
調用關係說明:
1、服務容器負責啓動、加載、運行服務提供者。
2、服務提供者在啓動時,向註冊中心註冊自己提供的服務。
3、服務消費者在啓動時,向註冊中心訂閱自己需要的服務。
4、註冊中心提供服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
5、服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選擇另一臺進行調用。
6、服務消費者和提供者,在內存中累計調用次數和調用時間,定時沒分組發送一次統計數據給監控中心。

官方推薦使用zookeeper註冊中心,註冊中心負責服務地址的註冊與查找,相當於目錄服務,服務提供者與消費者只在啓動時與註冊中心交互,註冊中心不轉發請求,壓力較小。
面試題:
1、dubbo中,zookeeper作爲註冊中心,當zookeeper掛掉時,發佈者和消費者之間還能互相通信嗎?
可以的,dubbo啓動時,消費者會總zk拉取生產者的地址接口等數據,緩存在本地,每次調用時,按照本地存儲的地址進行調用。註冊中心對等集羣,一臺掛掉之後,會自動切換到另一臺,註冊中心全部宕機,服務提供者和消費者仍可以通過本地緩存進行通訊。服務提供者無狀態,任一臺宕機後,不影響使用。服務提供者全部宕機,服務消費者會無法使用,並無限次重連等待服務提供者恢復。

zookeeper註冊中心:
流程說明:
1、服務提供者啓動時:向 /dubbo/com.foo.BarService/providers目錄寫下自己的URL地址。
2、服務消費者啓動時:訂閱/dubbo/com.foo.BarService/providers目錄下服務提供者的URL地址,並向/dubbo/com.foo.BarService/consumers 目錄寫下自己的URL地址
3、監控中心啓動時,訂閱/dubbo/com.foo.BarService目錄下所有的提供者和消費者URL地址。
支持以下功能:

  • 當提供者出現斷電等異常停機時,註冊中心能自動刪除提供者信息。
  • 當註冊中心重啓時,能自動恢復註冊數據,以及訂閱請求。
  • 當會話過期時,能自動恢復註冊數據,以及訂閱請求。
  • 當設置 <dubbo:registry check=“false” /> 時,記錄失敗註冊和訂閱請求,後臺定時重試
  • 可通過 <dubbo:registry username=“admin” password=“1234” /> 設置 zookeeper 登錄信息
  • 可通過 <dubbo:registry group=“dubbo” /> 設置 zookeeper 的根節點,不設置將使用無根樹
  • 支持 * 號通配符 <dubbo:reference group="" version="" />,可訂閱服務的所有分組和所有版本的提供者

Redis的優缺點

爲什麼使用Redis,主要考慮性能與併發。
Redis的缺點:
1、緩存與數據庫雙寫一致性問題。
一致性問題是分佈式常見的問題,還可以分爲最終一致性和強一致性。數據庫和緩存雙寫,必然會存在數據不一致的情形。首先前提:如果要保證數據有強一致性要求,數據不能放緩存中,我們只能保證最終一致性。另外,我們所做的方案,從根本上來說只能降低不一致發生的概率,不能完全避免。
2、緩存雪崩問題。
即緩存同一時間內大面積失效,這時候又來了一批請求,全部到數據庫上,從而導致數據庫連接異常。
解決:

  • 給緩存的失效時間加上一個隨機值,避免集體失效。

  • 使用互斥鎖,但是該方案的吞吐量明顯下降了。

  • 雙緩存。我們有兩個緩存,緩存A和緩存B。緩存A的失效時間爲20分鐘,緩存B不設失效時間。自己做緩存預熱操作。然後細分以下幾個小點

    I 從緩存A讀數據庫,有則直接返回
    II A沒有數據,直接從B讀數據,直接返回,並且異步啓動一個更新線程。
    III 更新線程同時更新緩存A和緩存B。

3、緩存擊穿問題。
即黑客故意去請求緩存中不存在的數據,導致所有的請求都到數據庫上,從而數據庫連接異常。
解決:

  • 採用互斥鎖,緩存失效時,先去獲得鎖,得到鎖之後再去請求數據庫,沒得到鎖則休眠一段時間後重試。
  • 採用異步更新策略,無論key是否取到值,都直接返回。value值中維護一個緩存失效的時間,緩存如果過期,異步起一個線程去讀數據庫,更新緩存。
  • 提供一個能迅速判斷請求是否有效的攔截機制。

4、緩存的併發競爭問題。
如果對這個key操作不要求順序,這種情況下準備一個分佈式鎖,大家去搶鎖,搶到鎖就做set操作。
如果對這個key的操作要求順序:
假設有一個key1,系統A需要將key1設置爲valueA,系統B需要將key1設置爲valueB,系統C需要將key1設置爲valueC。期望key1的value值按照valueA,valueB,valueC的順序去變化,這種時候在寫入數據的時候,需要保存一個時間戳,如下
| 系統A | key1 | valueA 3:00 |
| 系統B | key1 | valueB 3:05 |
| 系統C | key1 | valueC 3:10 |
那麼假設系統B先搶到鎖,將key1設置爲valueB 3:05,接下來系統A搶到鎖,發現自己的valueA中的時間戳小於緩存中的時間戳,那麼就不做set操作了。
其他方法,利用隊列,將set方法變成串行訪問也行。

單線程的Redis爲什麼這麼快?
1、純內存操作。
2、單線程操作,避免的頻繁的上下文切換。
3、採用了非阻塞I/O多路複用機制。
Redis的五種基本數據類型:
1、String
2、list
3、set
4、hash
5、sorted set

MySql默認的鎖,版本

數據庫事務

事務就是邏輯上的一組sql語句操作,組成這組操作的各個sql語句,執行時要麼全部成功要麼全部失敗。
事務的四大特性:
1、原子性
整個事務的所有操作,要麼全部成功,要麼全部不成功,不可能停滯在中間的某個環節。事務在執行過程中的某個環節出現錯誤會被回滾(rollback)到事務開始前的狀態,就像這個事務沒有執行過一樣。
2、一致性
事務發生前和發生後,數據的完整性必須保持一致。
3、隔離性
多個併發事務之間的數據是相互隔離的。
4、持久性
一個事務一旦被提交,對數據庫中數據的改變就是永久的,如果出現了錯誤,事務也不允許撤銷。

分佈式的優點

分表的優缺點

分佈式負載均衡

線程池的優缺點,是越多越好嗎?怎麼定義數量?

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