面試題目補充

1.Spring 的 AOP 關於攔截 private 方法一些問題

用 java 反射機制可以獲取 private 修飾的方法,進行攔截。注意,私有構造函數需要設置使用權限conInt.setAccessible(true);否則報錯


2.項目中數據字典怎麼做的緩存,如何做的通信,有沒有用什麼模塊。


3. spring 事務傳播行爲的配置方法:

(1)spring 對事務傳播行爲和隔離級別的二次封裝。因爲不同項目可能在一個 mysql 的不同數據庫上,所以可以在項目中配置數據庫的傳播行爲和隔離級別

<property name="transactionAttributes"> 
<props> 
<prop key="save*">PROPAGATION_REQUIRED</prop> 
<prop key="update*">PROPAGATION_REQUIRED</prop> 
<prop key="delete*">PROPAGATION_REQUIRED</prop> 
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> 
<prop key="find*">PROPAGATION_REQUIRED,ISOLATION_READ_UNCOMMITTED</prop>
</props>

(2)另一種方式:

事務的傳播性:@Transactional (propagation=Propagation.REQUIRED)

事務的隔離級別:@Transactional (isolation = Isolation.READ_UNCOMMITTED)

(3)spring+mybatis 事務配置

        <!-- 定義事務管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
	<!--使用註釋事務 -->
	<tx:annotation-driven  transaction-manager="transactionManager" />

4.slf4j 的原理,和 log4j 的對比

SLF4J 不同於其他日誌類庫,與其它有很大的不同。SLF4J (Simple logging Facade for Java) 不是一個真正的日誌實現,而是一個抽象層( abstraction layer),它允許你在後臺使用任意一個日誌類庫。

如果一個項目已經使用了 log4j,而你加載了一個類庫,比方說 Apache Active MQ—— 它依賴於於另外一個日誌類庫 logback,那麼你就需要把它也加載進去。但如果 Apache Active MQ 使用了 SLF4J,你可以繼續使用你的日誌類庫而加載和維護一個新的日誌框架。

總的來說,SLF4J 使你的代碼獨立於任意一個特定的日誌 API,這是一個對於開發 API 的開發者很好的思想。雖然抽象日誌類庫的思想已經不是新鮮的事物而且 Apache commons logging 也已經在使用這種思想了,但現在 SLF4J 正迅速成爲 Java 世界的日誌標準。

  • 在你的開源或內部類庫中使用 SLF4J 會使得它獨立於任何一個特定的日誌實現,這意味着不需要管理多個日誌配置或者多個日誌類庫。

  • SLF4J 提供了基於佔位符的日誌方法,不需要檢查 isDebugEnabled (), isInfoEnabled () 等等,提高了代碼可讀性。

  • 通過使用 SLF4J 的日誌方法,你可以延遲構建日誌信息(Srting)的開銷,直到你真正需要,這對於內存和 CPU 都是高效的。


5.CMS產生的浮動垃圾

初始標記:標記 GC Roots 能直接到的對象。速度很快但是仍存在 Stop The World 問題。
併發標記:進行 GC Roots Tracing 的過程,找出存活對象且用戶線程可併發執行。
重新標記:爲了修正併發標記期間因用戶程序繼續運行而導致標記產生變動的那一部分對象的標記記錄。仍然存在 Stop The World 問題。
併發清除:對標記的對象進行清除回收。

重新標記(Remark) 的作用在於:
之前在併發標記時,因爲是 GC 和用戶程序是併發執行的,可能導致一部分已經標記爲 從 GC Roots 不可達 的對象,因爲用戶程序的(併發)運行,又可達 了,Remark 的作用就是將這部分對象又標記爲 可達對象。

至於 “浮動垃圾”,因爲 CMS 在 併發標記 時是併發的,GC 線程和用戶線程併發執行,這個過程當然可能會因爲線程的交替執行而導致新產生的垃圾(即浮動垃圾)沒有被標記到;而 重新標記 的作用只是修改之前 併發標記 所獲得的不可達對象,所以是沒有辦法處理 “浮動垃圾” 的。


6.tomcat的非雙親委派加載

在這裏插入圖片描述

雙親委派模型要求除了頂層的啓動類加載器之外,其餘的類加載器都應當由自己的父類加載器加載。

【違背雙親委派】: tomcat 爲了實現隔離性,沒有遵守這個約定,每個 webappClassLoader 加載自己的目錄下的 class 文件,不會傳遞給父類加載器。例如:如果 tomcat 的 Common ClassLoader 想加載 WebApp ClassLoader 中的類,該怎麼辦?我們可以使用線程上下文類加載器實現,使用線程上下文加載器,可以讓父類加載器請求子類加載器去完成類加載的動作。

tomcat 爲了實現隔離性和熱替換,沒有使用默認的類加載器,而是自己實現了類加載器: 一個 web 容器可能要部署兩個或者多個應用程序,不同的應用程序,可能會依賴同一個第三方類庫的不同版本,因此要保證每一個應用程序的類庫都是獨立、相互隔離的。

【違背雙親委派三個方面】:(1)向前兼容;(2)加載 SPI 接口實現類;(3)熱部署

【Tomcat 類加載過程】:

tomcat 的類加載機制是違反了雙親委託原則的,對於一些未加載的非基礎類 (Object,String 等),各個 web 應用自己的類加載器 (WebAppClassLoader) 會優先加載,加載不到時再交給 commonClassLoader 走雙親委託。具體的加載邏輯位於 WebAppClassLoaderBase.loadClass() 方法中,這裏以文字描述加載一個類過程:

先在本地緩存中查找是否已經加載過該類 (對於一些已經加載了的類,會被緩存在 resourceEntries 這個數據結構中),如果已經加載即返回,否則 繼續下一步。
讓系統類加載器 (AppClassLoader) 嘗試加載該類,主要是爲了防止一些基礎類會被 web 中的類覆蓋,如果加載到即返回,返回繼續。
前兩步均沒加載到目標類,那麼 web 應用的類加載器將自行加載,如果加載到則返回,否則繼續下一步。
最後還是加載不到的話,則委託父類加載器 (Common ClassLoader) 去加載。


7.線程上下文類加載器

Java 提供了很多服務提供者接口(Service Provider Interface,SPI),允許第三方爲這些接口提供實現。常見的 SPI 有 JDBC、JCE、JNDI、JAXP 和 JBI 等。而問題在於,SPI 的接口是 Java 核心庫的一部分,是由引導類加載器來加載的;SPI 實現的 Java 類一般是由系統類加載器來加載的。引導類加載器是無法找到 SPI 的實現類的,因爲它只加載 Java 的核心庫。它也不能代理給系統類加載器,因爲它是系統類加載器的祖先類加載器。也就是說,類加載器的代理模式無法解決這個問題。

線程上下文類加載器正好解決了這個問題。如果不做任何的設置,Java 應用的線程的上下文類加載器默認就是系統上下文類加載器。在 SPI 接口的代碼中使用線程上下文類加載器,就可以成功的加載到 SPI 實現的類。線程上下文類加載器在很多 SPI 的實現中都會用到。

使用線程上下文類加載器,可以在執行線程中拋棄雙親委派加載鏈模式,使用線程上下文裏的類加載器加載類。典型的例子有:通過線程上下文來加載第三方庫 jndi 實現,而不依賴於雙親委派。大部分 java application 服務器 (jboss, tomcat…) 也是採用 contextClassLoader 來處理 web 服務。還有一些採用 hot swap 特性的框架,也使用了線程上下文類加載器,比如 seasar (full stack framework in japenese)。線程上下文從根本解決了一般應用不能違背雙親委派模式的問題。


8.數據庫的MVVC是什麼?

MVCC 的全稱是 “多版本併發控制”。這項技術使得 InnoDB 的事務隔離級別下執行一致性讀操作有了保證,換言之,就是爲了查詢一些正在被另一個事務更新的行,並且可以看到它們被更新之前的值。這是一個可以用來增強併發性的強大的技術,因爲這樣的一來的話查詢就不用等待另一個事務釋放鎖。MVVC依靠的是數據庫的回滾日誌。

mysql 的 innodb 採用的是行鎖,而且採用了多版本併發控制來提高讀操作的性能。MVVC其實就是在每一行記錄的後面增加兩個隱藏列,記錄創建版本號和刪除版本號,而每一個事務在啓動的時候,都有一個唯一的遞增的版本號。 在 InnoDB 中,給每行增加兩個隱藏字段來實現 MVCC,兩個列都用來存儲事務的版本號,每開啓一個新事務,事務的版本號就會遞增。

讀取創建版本小於或等於當前事務版本號,並且刪除版本爲空或大於當前事務版本號的記錄。這樣可以保證在讀取之前記錄是存在的。

一致性非鎖定讀

consistent read (一致性讀),InnoDB 用多版本來提供查詢數據庫在某個時間點的快照。如果隔離級別是 REPEATABLE READ,那麼在同一個事務中的所有一致性讀都讀的是事務中第一個這樣的讀讀到的快照;如果是 READ COMMITTED,那麼一個事務中的每一個一致性讀都會讀到它自己刷新的快照版本。Consistent read(一致性讀)是 READ COMMITTED 和 REPEATABLE READ 隔離級別下普通 SELECT 語句默認的模式。一致性讀不會給它所訪問的表加任何形式的鎖,因此其它事務可以同時併發的修改它們。

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