面試----exception和error

運行時異常與一般異常有什麼區別?以及exception和error的對比?

 

exception和error

一、相同點:

1.都繼承了throwable類,在java中只有繼承了該類纔可以被拋出並捕獲。

二、不同點:

1.exception和error體現了java平臺設計者對不同異常情況的分類。exception是程序正常運行中,可以預料的意外情況,可以捕獲並進行處理;而error則是正常情況下,不大可能出現的情況,絕大部分的error都會導致程序處於非正常的,不可恢復的狀態。既然是非正常狀態,則也不需要捕獲,常見的如OutOfMemoryError之類。

2.exception分爲可檢查異常和不可檢查異常,可檢查異常在源代碼中必須顯示的進行try-catch。這是編譯器檢查的一部分,不可檢查的比如空指針異常以及類轉換異常,越界異常等。

 

如何處理異常

1.捕獲異常不可一網打盡:

try{

//業務代碼

Thread.sleep(1000L);

}catch(Exception){

//Ignore it

}

第一、儘量不要捕獲Exception這樣的異常,而是應當捕獲特定異常,我們要讓我們的代碼表現出更多信息。exception這樣泛泛而談的概念會掩蓋真實的目的。如果要捕獲多個異常,將父類異常放在最後catch,子類異常放在之前catch

第二、不要生吞異常,這樣程序在出錯後我們不知道可能會很難診斷詭異的情況

 

2.儘量不要將異常打印到堆棧中

try{

//業務代碼

}catch(IOException e){

    e.printStachTrace();

}

這段代碼在實際產品中不允許這樣處理

  e.printStachTrace()不是一個合適的輸出選項,因爲你很難判斷到底輸出到哪裏去了。尤其是對於分佈式系統,如果發生異常,是無法找到堆棧軌跡,這蠢事是爲診斷設置障礙,所以最好使用產品日誌,詳細的輸出到日誌系統裏面。

 

 

自我構建異常

 

1.是否需要定義成checkedException,因爲這種類型設計的初衷更是爲了從異常情況回覆,作爲異常設計者,我們往往有足夠信息進行分類。

2.在保證診斷信息足夠的同時,也要考慮避免敏感信息,因爲這樣會導致潛在的安全問題。比如java.net.ConnectException,出錯信息是類似“Connection refused”,而不包含具體的機器名,IP,端口等。一個重要考量就是信息安全。類似情況在日誌中也有,比如,用戶數據一般是不可輸出到日誌裏面的。

 

異常處理的開銷

 

1.try-catch代碼會產生額外的性能開銷,或者換個角度說,它往往會影響JVM對代碼進行優化,所以建議僅捕獲有必要的代碼段,而不是全部try-catch。同時利用異常控制代碼流程也不是一個好主意,遠遠不如if else高效。

2.java每實例化一個Exception,都是對當時的棧進行快照【1】,這是一個相對比較繁重的操作。如果發生非常頻繁,這個開銷可就不能被忽略了。

所以對於部分追求極致性能的底層類庫,有種方式是嘗試創建不進行棧快照的Exception。這本身也存在爭議,因爲這樣做的假設在於,我創建異常時知道未來是否需要堆棧。問題是這樣可能嗎?在大型項目中,這樣做可能不是一個理智的選擇。如果需要堆棧,但有沒有收集這些信息,在複雜情況下,尤其是類似微服務這種分佈式系統,這會大大增加診斷的難度。

當我們的服務出現反應變慢,吞吐量下降的時候,檢查最頻繁發生的異常也是一種思路,關於診斷後臺變慢的問題,後面的java性能基礎模塊中系統探討。

 

【1】棧快照

 

 

存儲快照

全球網絡存儲工業協會SNIA(StorageNetworking Industry Association)對快照(Snapshot)的定義是:關於指定數據集合的一個完全可用拷貝,該拷貝包括相應數據在某個時間點(拷貝開始的時間點)的映像。快照可以是其所表示的數據的一個副本,也可以是數據的一個複製品。

快照的作用主要是能夠進行在線數據備份與恢復。當存儲設備發生應用故障或者文件損壞時可以進行快速的數據恢復,將數據恢復某個可用的時間點的狀態。快照的另一個作用是爲存儲用戶提供了另外一個數據訪問通道,當原數據進行在線應用處理時,用戶可以訪問快照數據,還可以利用快照進行測試等工作。所有存儲系統,不論高中低端,只要應用於在線系統,那麼快照就成爲一個不可或缺的功能。 [1] 

快照的實現方式

當前實現快照有主要有兩種技術,一種是第一次寫時複製(Copy OnFirst Write,COFW),有時簡稱爲寫時複製(CopyOn Write,COW)。即在數據第一次寫入到某個存儲位置時,首先將原有的內容讀取出來,寫到另一位置處(爲快照保留的存儲空間,此文中我們稱爲快照空間),然後再將數據寫入到存儲設備中。而下次針對這一位置的寫操作將不再執行寫時複製操作。這種技術常在計算機相關的技術中經常初使用,其基本原理大同小異,只是面向的對象不同,適用的場合不一樣。從COW 的執行過程我們可以知道,這種實現方式在第一次寫入某個存儲位置時需要完成一個讀操作(讀原位置的數據),兩個寫操作(寫原位置與寫快照空間),如果寫入頻繁,那麼這種方式將非常消耗IO時間。因此可推斷,如果預計某個捲上的I/O多數以讀操作爲主,寫操作較少,這種方式的快照實現技術是一個較理想的選擇,因爲快照的完成需要較少的時間。除此之外,如果一個應用易出現寫入熱點,即只針對某個有限範圍內的數據進行寫操作,那麼COW的快照實現方式也是較理想的選擇。因爲其數據更改都侷限在一個範圍內,對同一份數據的多次寫操作只會出現一次寫時複製操作。

寫時複製的示意

下圖是寫時複製的示意圖

寫時複製的示意圖寫時複製的示意圖

:但是這種方式的缺點也是非常明顯的。如果寫操作過於分散且頻繁,那麼 COW造成的開銷則是不可忽略的,有時甚至是無法接受的。因此在應用時,則需要綜合評估應用系統的使用場景,以判斷這種方式的快照是否適用。快照實現技術中的另一種技術是 I/O 重定向(I/O Redirect)。即將讀寫操作重新定向到另一個存儲空間中。在一個快照生成期間,所有的寫操作將被重定向到另一個介質,而讀操作是否需要讀重定向,則需要根據讀取的位置是否有過自上次快照以來的寫重定向,必須對有過寫重定向的位置進行讀重定向,否則不需要進行讀定向。當要創建一個快照時,則將自上次快照以來所有的重定向寫數據所對應在源介質中的數據複製出來生成這個時間點的快照,然後再將這些重定向寫數據寫回到源介質中的相應位置上,從而完成一個快照生成過程。

I/O 重定向示意

下圖中顯示了IO重定向的執行過程。

I/O 重定向示意圖I/O 重定向示意圖

從上面的過程來看,關鍵的性能影響在於快照生成時的四次I/O操作(一次讀源介質,一次寫快照數據,一次讀快照介質,一次寫源介質),另一個則是重定向的計算工作。這種方式雖然看起來最後生成快照時的I/O操作較多,但是考慮到這個操作是在生成快照時纔會發生,特別是快照生成時可以對I/O操作進行排序,可以使得對介質的讀寫得到較好的優化,因此使影響很小。而對於重定向的計算操作對於當下的計算能力來說,不會成爲一個性能的瓶頸問題。因此這種快照實現方式在非快照執行期間的影響甚小。因此這種方式比較適合Write-Intensive(寫密集)類型的存儲系統

快照生成

下圖是快照生成過程的示意圖:SNIA 將快照的實現方式表述爲:鏡像分離(split mirror)、改變塊(changed block)、併發(concurrent)三大類。後兩種在實現時其實質就是寫時複製及I/O重定向。對於 split mirror的方式,由於其靈活性以及開銷問題,在實際的存儲系統中,並不實用。

實現層次

編輯

概述

計算機的存儲結構是一個類似於 TCP/IP 一樣的棧結構。棧中包括硬件與軟件部分。棧中不同層爲上層提供服務,同時利用下層的接口(如下圖)。

存儲棧存儲棧

存儲棧

因此在實現上,快照可以在不同的棧層上實現。但是不同的層其效果及特點是不一樣的。一般來說,在應用層不太合適實現快照功能。因爲不同的應用是千差萬別的,因此需要針對不同的應用實現快照功能,這個代價也太高了。但在應用層實現快照也並不是說一無用處,如在應用層實現快照的一個典型的例子就是 vmWare 虛擬化軟件中的快照功能。只是這種快照功能應用在存儲系統中不現實。其次在文件系統層實現快照與應用也是具有同樣的缺點,就是需要針對不同的文件系統實現快照功能,這樣的代價也很大。

實現層次案例

實現的快照的功能的文件系統基本上都是一些專用系統或者專爲某個特定功能實現的文件系統。在這個層級上實現快照,缺乏靈活性和可擴展性。這個比較典型的例子就是ZFS。而較爲適宜實現快照功能的層應該爲卷管理層以及物理層。在這兩個層中都不與特定的應用及文件系統相關。這裏比較典型的例子有Linux 的LVM。而在硬件層次上實現快照又通常有許多種,在這個層次上實現的快照一般爲專用系統,好處是性能是各個方式中最好的。但是在這個層次上實現的快照也有一個不可避免的缺點,那就是由於不與特定的應用及文件系統關聯,因此其就無法理解上層的應用邏輯,也就無法保證每個快照都處於數據一致性狀態的。但是這個缺點是可以通過其他的方式減少或者解決的,比如在生成快照之前先對數據進行刷新操作,或者在恢復快照時對文件系統進行一致性檢查等。結束語計算技術不斷在進步,存儲技術同樣也在進行着日新月異的變化。不同的應用在不斷地更新着對存儲的需求。同時對於數據重要性的體現,各種容災技術也給用戶的數據加上了防護安全帽。

 

 

 

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