1. 程式人生 > >Java面試題及回答集錦(基礎篇)

Java面試題及回答集錦(基礎篇)

1、問題:如果A和B物件迴圈引用,是否可以被GC?

回答:可以,現在的虛擬機器基本都是通過可達性分析演算法來判斷物件是否存活的,而不是通過簡單的引用計數法來判斷物件是否存活。可達性分析演算法使用一系列的“GC Roots”物件(虛擬機器棧中引用的物件、靜態屬性引用物件)作為起始點,這些節點向下搜尋的路徑稱為引用鏈,當一個物件到GC Roots沒有任何引用鏈連線,則證明物件是不可用的。

2、Java中的記憶體溢位是如何造成的?

OutOfMemoryError:

(1)PerGern Space 程式中使用了大量jar或class,使Java虛擬機器裝載類空間不夠。

解決方案:調參XX:PermSize 和 XX:MaxPermSize 、減少jar包,減少類的重複載入

(2)Java Heap Space Java虛擬機器建立了太多的物件。

解決方案:調參Xms(初始堆大小)Xmx(最大堆大小)、檢查死迴圈或不必要建立的重複物件

(3)unable to create new native Thread  JVM佔用了太多記憶體空間,而在JVM中建立執行緒還要再作業系統中也建立執行緒。

解決方案:調整JVM中執行緒大小。

3、String s = “123”;這個語句有幾個物件產生?

若字串池中沒有"123",則產生一個物件,並且放入常量池中,若有"123",則產生0個物件。

若是String s = new String("123"),若常量池中沒有,則在常量池中建立一個,然後在堆記憶體中建立一個。

4、Error、Exception和RuntimeException的區別,作用又是什麼?

Error和Exception都是Throwable的子類,RuntimeException是Exception的子類。

Error用於指示合理應用程式不應該試圖捕獲的錯誤。

Exception指出合理的應用程式需要捕獲的條件。分為已檢查異常和未檢查異常。

RuntimeException是未檢查異常,不需要try catch或在方法上宣告,主要子類:NullPointer、Arithmatic、ArrayIndexOutOfBounds、ClassCast。

5、Reader和InputStream區別?

都是抽象類,Reader用於讀取字元流(char或String),InputStream用於讀取位元組流(byte陣列)。

6、hashCode的作用?

hashCode主要是用於快速查詢,如HashMap結構中,用於定位鍵值對的位置。兩個物件相同,則hashCode一定相同,而hashCode相同的物件則不一定相同,就相當於放在同一個框裡。

7、HashMap和Hashtable的區別?

執行緒安全性、null值的key、效率、HashMap(Iterator快速失敗迭代器)、Hashtable(enumerator迭代器)、時間推移HashMap元素位置會變

8、HashMap中是否任何物件都可以做為key,使用者自定義物件做為key有沒有什麼要求?

可以、但是要key物件必須是不可變的物件,不然在Entry被插入Map中後,再改變key值,會導致當前key值與hash值不符合,即與陣列索引不符,將無法被查詢到。

9、 啟動一個執行緒是用run()還是start()? 多執行緒有幾種實現 同步和併發是如何解決的 什麼叫守護執行緒,用什麼方法實現守護執行緒(Thread.setDeamon()的含義) 如何停止一個執行緒? 解釋是一下什麼是執行緒安全?舉例說明一個執行緒不安全的例子。解釋Synchronized關鍵字的作用。 當一個執行緒進入一個物件的一個synchronized方法後,其它執行緒是否可進入此物件的其它方法?

(1)start 

(2)繼承Thread類、實現Runnable介面、使用ExectuorService、Future、Callable實現由返回值的執行緒。

(3)同步方法、同步程式碼塊、鎖

(4)Damon執行緒、為其他執行緒的執行提供服務,如GC,Thread。setDeamon(true)。

(5)Thread.stop()不推薦(不會正確釋放資源)、使用中斷來停止執行緒。

(6)當多個執行緒訪問一個物件時,如果不用考慮這些執行緒在執行時環境下的排程和交替執行,也不需要進行額外的同步,或者在呼叫方進行任何其他的協調操作,呼叫這個物件的行為都可以獲得正確的結果,那這個物件是執行緒安全的。

(7)車票被重複賣出。

(8)同步關鍵詞。修飾靜態方法,則以類作為鎖物件,同時只能有一個執行緒訪問此類同步的靜態方法;修飾普通方法,則以此物件作為鎖物件,同時只能有一個執行緒訪問此類同步的普通方法;也可以自定義鎖物件同步程式碼塊。

(9)synchronized方法不可以進入,非synchronized可以進入。

10、瞭解過哪些JDK8的新特性,舉例描述下相應的特性?

(1)lambda表示式:函數語言程式設計,方法引用

(2)Stream API

(3)介面的預設方法

(4)日期時間API的改進,新增DateTimeFormatter方法

11、對sql進行優化的原則有哪些?

詳情見我資料庫分類的的一篇部落格

12、Servlet的生命週期,Serlvet與CGI的區別?

生命週期:類載入、例項化(構造物件),初始化(init),服務(service),銷燬(destroy)。

CGI:common gateway interface,通用閘道器介面,Perl語言編寫,每個請求建立一個CGI物件。

Servlet:只需要例項化、初始化一次,多執行緒。

13、StringBuffer有什麼優勢?為什麼快?

因為StringBuffer不需要重複建立String物件,但是其實也不是這樣。

比如String s = "a" + "b" + "c"操作編譯器會優化,變成String s = "abc"

String s = s1 + s2 + s3編譯器也會優化,變成StringBuilder的append操作,但是如果不是一次性+操作拼接完,就會反覆生成String物件與StringBuilder物件,效率會很低。

14、加密解密演算法瞭解嗎?

摘要演算法:MD5(128位)、SHA1(160位),是一種不可逆的過程,無論多大的資料,經過摘要演算法後都生成相同長度的資料。只能通過字典進行破解。

對稱加密演算法:DES、AES,加密解密時使用相同的祕鑰。

非對稱加密演算法:RSA,加密解密時使用不同的祕鑰,對接支付寶使用RSA2。

15、解決高併發與高負載?

(1)靜態頁面消耗最小,儘可能的HTML靜態化,採用資訊釋出系統CMS實現資訊錄入自動生成靜態頁面、在前端快取不經常改變的動態資料。

(2)CDN,把CSS/JS等資源分佈在不同的伺服器上。

(3)負載均衡(Nginx)。

(4)快取不常改變的資料(Redis、memcache)。

(5)圖片伺服器與應用伺服器分離。

(6)叢集。

16、Integer內部快取?

Integer類內部有一個staitic 的Integer陣列,儲存的是一些已經完成初始化的Integer物件,一般值為(-128~127),若用==比較,則有時候會因為值不在快取中而返回false,所以應該用equals比較。

17、ArrayList的原理?

(1)ArrayList是執行緒不安全的,若要執行緒安全,則使用CopyOnWriteList。

(2)底層是Object[]陣列,內部有一個elementData引用指向陣列,剛開始預設指向一個快取空陣列(transient),當要進行擴容時,會重新new一個大小為1.5倍(x + (x >>1))的新陣列,然後將舊元素通過System.arraycopy這個native方法拷貝到新陣列中。

(3)隨機讀寫(get、set)方法的演算法複雜度為O(1)。

(4)增加操作分為兩種,add(index, value)的演算法複雜度為O(n),因為要通過元素複製進行移動;而add(value)操作的演算法複雜度為O(1)(若不發生擴容)。

(5)刪除操作的時間複雜度為O(n),因為不管是按index進行刪除還是按照object去刪除,都需要通過複製去實現移動操作,刪除後陣列大小不會變,靠size屬性來維護長度。按object進行刪除時不能用new出來的物件,要通過ArrayList內物件的引用刪除。

18、LinkedList的原理?

(1)底層是一個雙向連結串列,維護著一個first指標和一個last指標。

(2)隨機讀寫(get,set)的時間複雜度為O(n)。

(3)插入操作add(object)的時間複雜度為O(1);add(index, object)的時間複雜度為O(n)。

(4)刪除操作remove(object)的時間複雜度為O(1);remove(index)的時間複雜度為O(n)。

19、執行緒池使用的注意事項?

(1)防止死鎖。執行緒池中所有執行緒都在等待A事件發生,而沒有空閒執行緒去執行A。

(2)防止系統資源不足。要控制執行緒數量。

(3)防止併發錯誤。

(4)防止執行緒洩漏,某個執行緒因RuntimeException或Error沒有正常被捕獲導致該執行緒異常終止,執行緒池失去了一個執行緒。

(5)避免任務過載。

20、Spring中@Autowire與@Resource的區別?

@Autowire預設按照型別裝配,預設情況下它要求依賴物件必須存在如果允許為null,可以設定它required屬性為false,如果我們想使用按照名稱裝配,可以結合@Qualifier註解一起使用; 

@Resource預設按照名稱裝配,當找不到與名稱匹配的bean才會按照型別裝配,可以通過name屬性指定,如果沒有指定name屬性,當註解標註在欄位上,即預設取欄位的名稱作為bean名稱尋找依賴物件,當註解標註在屬性的setter方法上,即預設取屬性名作為bean名稱尋找依賴物件

21、執行緒狀態轉移圖。


22、Object類的方法?

(1)equals:判斷是否相等。

(2)hashCode:求hash值,若兩個物件hash值相等,不一定equals;若equals,則兩個物件hash值一定相等。

(3)toString:獲得物件的字串表達形式,一般要重寫。

(4)getClass:反射方法,獲得物件所屬的類。

(5)wait:只能在synchronized同步的程式碼段中使用,若不帶時間引數,則使得正在執行的執行緒放棄鎖進入等待狀態(等待池)。

(6)notify:只能在synchronized同步的程式碼段中使用,從等待池中取出一個執行緒放入鎖標誌池。

(7)notifyAll:只能在synchronized同步的程式碼段中使用,將等待池中取出所有執行緒放入鎖標誌池。

23、Java序列化的底層原理?

將物件資訊轉化為位元組碼資訊。

(1)儲存序列化的描述。(2)當前類描述資訊。(3)當前類屬性描述。(4)超類描述(5)超類屬性描述(6)超類屬性值描述(7)子類屬性值描述