標籤:java 面試題
1、如何理解記憶體回收?
記憶體回收是Java語言的一大特性,方便了編程,是以消耗效能為代價的;在Java虛擬機器(JVM)中,有一個記憶體回收行程,它的作用就是尋找和回收沒用的對象,以便讓JVM更有效使用記憶體;儘可能保證可用記憶體的使用效率,讓可用記憶體得到高效的管理,程式員可以影響記憶體回收的執行,但是不能控制。
記憶體回收行程的已耗用時間程式員是無法決定的,由JVM決定,運行時也是間接執行的,雖然可以通過System.gc( )來強制回收垃圾,但是在該命令執行後無法保證JVM會立即響應執行,下達命令後,會在短期內執行程式員的請求,但是JVM會在感到記憶體緊缺的時候去執行記憶體回收操作。
記憶體回收過於頻繁會導致效能下降,過於稀疏會導致記憶體緊缺,但是這個問題JVM會自己控制好,不用程式員去控制,這也是Java語言的一個好處;但是有時候會在短期內使用掉大量記憶體,而且這些對象在短暫使用後就不用了,這時候有必要下達一條強制回收命令,以便有更多可用的實體記憶體。
JVM判斷一塊記憶體是否符合記憶體回收行程收集的標準:
1、給對象賦了空值null,而且後面沒有使用過;
2、給對象賦予了新值,即重新分配了記憶體空間。
2、如何理解安全執行緒?
安全執行緒就是在多線程訪問時,採用了加鎖機制,當一個線程訪問該類的資料時,其他線程不能進行訪問,直到這個線程訪問完畢,其他線程才可以繼續讀取,不會出現資料不一致或資料汙染。
如果代碼所在的進程中有多個線程同時在運行,而這些線程可能會同時訪問這段代碼,如果每次啟動並執行結果和單線程是一樣的,而且其他的值也和預期是一樣的,就是安全執行緒。
如:一個 ArrayList 類,在添加一個元素的時候,它可能會有兩步來完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。 在單線程啟動並執行情況下,如果 Size = 0,添加一個元素後,此元素在位置 0,而Size=1; 如果是在多線程情況下,比如有兩個線程,線程 A 先將元素存放在位置 0。但是此時 CPU 調度線程A暫停,線程 B 得到啟動並執行機會。線程B也向此 ArrayList 添加元素,因為此時 Size 仍然等於 0 ,所以線程B也將元素存放在位置0。然後線程A和線程B都繼續運行,都增加 Size 的值。看看ArrayList 的情況,元素實際上只有一個,存放在位置 0,而 Size 卻等於 2。這就是“線程不安全”了。
執行緒安全性不是一個非真即假的命題。比如: Vector 的方法都是同步的,並且 Vector 明確地設計為在多線程環境中工作。但是它的執行緒安全性是有限制的,即在某些方法之間有狀態依賴(類似地,如果在迭代過程中 Vector 被其他線程修改,那麼由 Vector.iterator() 返回的 iterator會拋出ConcurrentModifiicationException異常。對於 Java 類中常見的執行緒安全性層級,沒有一種分類系統可被廣泛接受,不過重要的是在編寫類時盡量記錄下它們的安全執行緒行為。
Bloch 給出了描述五類執行緒安全性的分類方法:不可變、安全執行緒、有條件安全執行緒、線程相容和線程對立。
3、使用者很多時,怎麼對伺服器進行最佳化?(servlet+jsp部分)
將在一段時間內不活躍的使用者進行鈍化,將使用者物件序列化到本地磁碟,這樣就緩解了記憶體壓力;當使用者再次活躍時,再活化就行了!
鈍化:是將session記憶體中的對象持久化(序列化)(實現序列化介面)到磁碟;
活化:就是將磁碟上的對象再次恢複到session記憶體中
(1)
鈍化與活化的監聽器HttpSessionActivationListener
可以通過設定檔 指定對象鈍化時間 --- 對象多長時間不用被鈍化
在META-INF下建立一個context.xml,內容如下:
<Context>
<!-- maxIdleSwap:session中的對象多長時間不使用就鈍化 -->
<!-- directory:鈍化後的對象的檔案寫到磁碟的哪個目錄下,配置鈍化的對象檔案在 work/catalina/localhost/鈍化檔案 -->
<Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
<Store className="org.apache.catalina.session.FileStore" directory="bonnie" />
</Manager>
</Context>
@Override
public void sessionWillPassivate(HttpSessionEvent se) {
System.out.println("被鈍化。。。");
}
@Override
public void sessionDidActivate(HttpSessionEvent se) {
System.out.println("被活化。。。");
}
當訪問指定的servlet工程時,在設定的時間到了以後,就會出現“被鈍化”;然後再訪問工程下的任意一個檔案,就可以被活化。
被鈍化到work/catalina/localhost/的檔案
本文出自 “Java學習” 部落格,請務必保留此出處http://12181171.blog.51cto.com/12171171/1958449
Java軟體開發常見面試題(一)