Java中高級面試題及答案收集(一)

(一)Java基礎

1、線程池的原理

預先啓動一些線程,線程無限循環從任務隊列中獲取一個任務進行執行,直到線程池被關閉。如果某個線程因爲執行某個任務發生異常而終止,那麼重新創建一個新的線程而已。如此反覆。

2、爲什麼要創建線程池?

線程池爲線程生命週期開銷問題和資源不足問題提供瞭解決方案。

(1)通過對多個任務重用線程,線程創建的開銷被分攤到了多個任務上。其好處是,因爲在請求到達時線程已經存在,所以無意中也消除了線程創建所帶來的延遲。這樣,就可以立即爲請求服務,使應用程序響應更快。

(2)而且,通過適當地調整線程池中的線程數目,也就是當請求的數目超過某個閾值時,就強制其它任何新到的請求一直等待,直到獲得一個線程來處理爲止,從而可以防止資源不足。

3、線程的生命週期

(1)新建 New

當創建Thread類的一個實例(對象)時,此線程進入新建狀態(未被啓動)。例如:Thread t1=new Thread();

(2)就緒 Runnable

調用Thread類的start方法,線程已經被啓動,進入就緒狀態,正在等待被分配給CPU時間片,也就是說此時線程正在就緒隊列中排隊等候得到CPU資源。

(3)運行 Running

線程獲得CPU資源正在執行任務(執行run()方法),此時除非此線程自動放棄CPU資源或者有優先級更高的線程進入,線程將一直運行到結束或者時間片結束。

(4)阻塞 Blocked

由於某種原因導致正在運行的線程讓出CPU並暫停自己的執行,即進入堵塞狀態。阻塞結束後線程進入就緒狀態。
堵塞的情況分三種:

(一)等待堵塞:執行的線程執行wait()方法,JVM會把該線程放入等待池中。

(二)同步堵塞:執行的線程在獲取對象的同步鎖時,若該同步鎖被別的線程佔用。則JVM會把該線程放入鎖池中。

(三)其它堵塞:執行的線程執行sleep()或join()方法,或者發出了I/O請求時。JVM會把該線程置爲堵塞狀態。
當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完成時。線程又一次轉入就緒狀態。

(5)死亡 Dead

當線程執行完畢(run方法運行結束)或被其它線程殺死,線程就進入死亡狀態,這時線程不可能再進入就緒狀態等待執行。

4、什麼是線程安全,如何實現線程安全?

(1)當多個線程訪問某個方法時,不管你通過怎樣的調用方式或者說這些線程如何交替的執行,我們在主程序中不需要去做任何的同步,這個類的結果行爲都是我們設想的正確行爲,那麼我們就可以說這個類時線程安全的。

 (2)一般來說,基本上所有的併發模式在解決線程安全問題時,採用的操作都是序列化訪問共享資源。在java中,提供了兩種方式,synchronized和Lock。

9、wait()與 sleep()的區別?
sleep()來自 Thread 類,wait()來自 Object 類;

調用 sleep()方法,線程不會釋放對象鎖。而調用 wait 方法線程會釋放對象鎖;

sleep()睡眠後不出讓系統資源,wait 讓其他線程可以佔用 CPU;

sleep(milliseconds)需要指定一個睡眠時間,時間一到會自動喚醒。而 wait()需要配合 notify()

或者 notifyAll()使用。

5、synchronized、volatile區別

  1. volatile本質是在告訴jvm當前變量在寄存器(工作內存)中的值是不確定的,需要從主存中讀取; synchronized則是鎖定當前變量,只有當前線程可以訪問該變量,其他線程被阻塞住。
  2. volatile僅能使用在變量級別;synchronized則可以使用在變量、方法、和類級別的
  3. volatile僅能實現變量的修改可見性,不能保證原子性;而synchronized則可以保證變量的修改可見性和原子性
  4. volatile不會造成線程的阻塞;synchronized可能會造成線程的阻塞。
  5. volatile標記的變量不會被編譯器優化;synchronized標記的變量可以被編譯器優化

6、Java9比Java8改進了什麼;

modularity System 模塊系統、HTTP/2、JShell、不可變集合工廠方法、私有接口方法、HTML5風格的Java幫助文檔、多版本兼容 JAR、統一 JVM 日誌、I/O 流新特性

7、HashMap內部的數據結構是什麼?底層是怎麼實現的?

8、說說反射的用途及實現,反射是不是很慢,我們在項目中是否要避免使用反射;

9、說說自定義註解的場景及實現;

10、List和Map區別,Arraylist與LinkedList區別,ArrayList與Vector 區別;

(1)List,Set都是繼承自Collection接口,Map則不是

(2)ArrayList和LinkedList的大致區別如下:

  1. ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構。 
  2. 對於隨機訪問get和set,ArrayList覺得優於LinkedList,因爲LinkedList要移動指針。 
  3. 對於新增和刪除操作add和remove,LinedList比較佔優勢,因爲ArrayList要移動數據。

(3)ArrayList與Vector 區別:

  1. Vector的方法都是同步的(Synchronized),是線程安全的(thread-safe),而ArrayList的方法不是,由於線程的同步必然要影響性能,因此,ArrayList的性能比Vector好。  
  2. 當Vector或ArrayList中的元素超過它的初始大小時,Vector會將它的容量翻倍,而ArrayList只增加50%的大小,這樣,ArrayList就有利於節約內存空間。

(二)JVM相關

1、JVM內存模型,GC機制和原理;GC分哪兩種;什麼時候會觸發Full GC?

2、JVM裏的有幾種classloader,爲什麼會有多種?

3、什麼是雙親委派機制?介紹一些運作過程,雙親委派模型的好處;(這個我真的不會…)

4、什麼情況下我們需要破壞雙親委派模型;

5、常見的JVM調優方法有哪些?可以具體到調整哪個參數,調成什麼值?

6、JVM虛擬機內存劃分、類加載器、垃圾收集算法、垃圾收集器、class文件結構是如何解析的;
 

(三)Java多線程

1、什麼是 ThreadLocal?ThreadLocal 和 Synchonized 的區別?
線程局部變量。是侷限於線程內部的變量,屬於線程自身所有,不在多個線程間共享。Java提供 ThreadLocal 類來支持線程局部變量,是一種實現線程安全的方式。

synchronized 是利用鎖的機制,使變量或代碼塊在某一時該只能被一個線程訪問。而 ThreadLocal 爲每一個線程都提供了變量的副本,使得每個線程在某一時間訪問到的並不是同一個對象,這樣就隔離了多個線程對數據的數據共享。

2、創建線程的方式?

繼承 Thread 類、實現 Runnable 接口、使用 Executor 框架

(四)Spring專欄

1、Spring AOP的實現原理和場景;(應用場景很重要)

實現AOP的技術,主要分爲兩大類:一是採用動態代理技術,利用截取消息的方式,對該消息進行裝飾,以取代原有對象行爲的執行;二是採用靜態織入的方式,引入特定的語法創建“方面”,從而使得編譯器可以在編譯期間織入有關“方面”的代碼。

具體可以在下面的場景中使用:

  • Authentication 權限
  • Caching 緩存
  • Context passing 內容傳遞
  • Error handling 錯誤處理
  • Lazy loading 懶加載
  • Debugging  調試
  • logging, tracing, profiling and monitoring 記錄 跟蹤 優化 校準
  • Performance optimization 性能優化
  • Persistence  持久化
  • Resource pooling 資源池
  • Synchronization 同步
  • Transactions 事務

2、Spring bean的作用域和生命週期

SpringBean的作用域

  • scope:設置bean的作用範圍
  • singleton:單例(創建只有一個實例)
  • prototype:原型(創建多個實例)
  • request:對request請求創建新的bean
  • session:一次會話中創建同一個bean
  • global-session:所有會話共享一個bean

Bean實例生命週期的執行過程如下:

  1. Spring對bean進行實例化,默認bean是單例;
  2. Spring對bean進行依賴注入;
  3. 如果bean實現了BeanNameAware接口,spring將bean的id傳給setBeanName()方法;
  4. 如果bean實現了BeanFactoryAware接口,spring將調用setBeanFactory方法,將BeanFactory實例傳進來;
  5. 如果bean實現了ApplicationContextAware接口,它的setApplicationContext()方法將被調用,將應用上下文的引用傳入到bean中;
  6. 如果bean實現了BeanPostProcessor接口,它的postProcessBeforeInitialization方法將被調用;
  7. 如果bean實現了InitializingBean接口,spring將調用它的afterPropertiesSet接口方法,類似的如果bean使用了init-method屬性聲明瞭初始化方法,該方法也會被調用;
  8. 如果bean實現了BeanPostProcessor接口,它的postProcessAfterInitialization接口方法將被調用;
  9. 此時bean已經準備就緒,可以被應用程序使用了,他們將一直駐留在應用上下文中,直到該應用上下文被銷燬;
  10. 若bean實現了DisposableBean接口,spring將調用它的distroy()接口方法。同樣的,如果bean使用了destroy-method屬性聲明瞭銷燬方法,則該方法被調用;

3、Spring Boot比Spring做了哪些改進?

Spring Boot 基本上是 Spring 框架的擴展,它消除了設置 Spring 應用程序所需的 XML配置,爲更快,更高效的開發生態系統鋪平了道路。以下是 Spring Boot 中的一些特點:

  1. 創建獨立的 spring 應用。
  2. 嵌入 Tomcat , Jetty Undertow 而且不需要部署他們。
  3. 提供的“starters” poms來簡化 Maven 配置
  4. 儘可能自動配置 spring 應用。
  5. 提供生產指標,健壯檢查和外部化配置
  6. 絕對沒有代碼生成和 XML 配置要求

4、Spring IOC是什麼?優點是什麼?

 

5、SpringMVC、動態代理、反射、AOP原理、事務隔離級別;
 

(五)Java框架技術

(六)中間件

1、瞭解幾種消息中間件產品?各產品的優缺點介紹;

2、消息中間件如何保證消息的一致性和如何進行消息的重試機制(冪等性)?

產生消息的業務動作和消息發送的一致: 如果業務動作執行成功了,那麼這個動作產生的消息一定要發送出去。另一方面,如果這個業務沒有發生或者失敗,就不應該把消息發送出去。

3、怎麼避免消息隊列中的消息丟失和消息重複?

消息重複:

(1)在發送端和消費端都建立消息記錄表,當發送端操作成功後,在發送端的消息記錄表中建立一條記錄,狀態標識成uncomfirm(未確認),將消息投遞到消息隊列

(2)消費端從消息隊列中獲取消息後,根據消息操作成功後,在消費端的記錄表中建立一條記錄,狀態標識爲confirmed

在支付寶端和餘額寶端同時建立消息表

(3)消費端將響應消息投遞到響應隊列, 發送端獲得響應後, 查詢發送端的消息表, 如果其中沒有消費記錄, 則插入新的消息。如果查詢有消費的消息, 就停止插入, 並返回已經消費的消息。這樣可以避免消息重複消費的問題。

(4)發送端端會有一個定時任務, 相隔一段時間就從消息表中將unconfirm的消息拉取並重新發送, 這樣可以避免消息丟失的問題 

4、RabbitMQ 工作模式
簡單模式:一個生產者發送消息到隊列,一個消費者接收。

工作隊列模式:一個生產者,多個消費者,每個消費者獲取到的消息唯一,多個消費者只有一個隊列。

發佈/訂閱模式:一個生產者發送的消息會被多個消費者獲取,每個消費者只能從自己訂閱的隊列中獲取。

路由模式:生產者發佈消息的時候添加路由鍵,消費者綁定隊列到交換機時添加鍵值,這樣就可以接收到需要接收的消息。

通配符模式:基本思想和路由模式是一樣的,只不過路由鍵支持模糊匹配,符號“#”匹配一個或多個詞,符號“*”只匹配一個詞。

(七)關係型數據庫

1、鎖機制介紹:行鎖、表鎖、排他鎖、共享鎖;

2、樂觀鎖的業務場景及實現方式;

3、事務介紹,分佈式事物的理解,常見的解決方案有哪些,什麼事兩階段提交、三階段提交;

4、MySQL記錄binlog的方式主要包括三種模式?每種模式的優缺點是什麼?

5、MySQL鎖,悲觀鎖、樂觀鎖、排它鎖、共享鎖、表級鎖、行級鎖;

6、分佈式事務的原理2階段提交,同步異步阻塞非阻塞;

7、數據庫事務隔離級別,MySQL默認的隔離級別、Spring如何實現事務、

8、JDBC如何實現事務、嵌套事務實現、分佈式事務實現;

9、SQL的整個解析、執行過程原理、SQL行轉列;

(八)非關係型數據庫

1、Redis爲什麼這麼快?redis採用多線程會有哪些問題?

2、Redis支持哪幾種數據結構;

3、Redis跳躍表的問題;

4、Redis單進程單線程的Redis如何能夠高併發?

5、Redis如何使用Redis實現分佈式鎖?

6、Redis分佈式鎖操作的原子性,Redis內部是如何實現的?

(九)分佈式和微服務

1、Dubbo完整的一次調用鏈路介紹;

2、Dubbo支持幾種負載均衡策略?

3、Dubbo Provider服務提供者要控制執行併發請求上限,具體怎麼做?

4、Dubbo啓動的時候支持幾種配置方式?

5、瞭解幾種消息中間件產品?各產品的優缺點介紹;

6、消息中間件如何保證消息的一致性和如何進行消息的重試機制?

7、Spring Cloud熔斷機制介紹;

8、Spring Cloud對比下Dubbo,什麼場景下該使用Spring Cloud?

(十)拓展或算法

1、紅黑樹的實現原理和應用場景;

2、NIO是什麼?適用於何種場景?

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