Java软件工程师面试题汇总(持续更新)
##1、 GC
(1)jvm中一次完整的GC流程(從ygc到fgc)是怎樣的,重點講講對象如何晉升到老年代等
 答:對象優先在新生代區中分配,若沒有足夠空間,Minor GC;
 大對象(需要大量連續內存空間)直接進入老年態;長期存活的對象進入老年態。如果對象在新生代出生并經過第一次MGC后仍然存活,年齡+1,若年齡超過一定限制(15),則被晉升到老年態。
(2)JVM垃圾回收機制,何時觸發MinorGC等操作
 分代垃圾回收機制:不同的對象生命周期不同。把不同生命周期的對象放在不同代上,不同代上采用最合適它的垃圾回收方式進行回收。
 JVM中共劃分為三個代:年輕代、年老代和持久代。
- 年輕代:存放所有新生成的對象;
 - 年老代:在年輕代中經歷了N次垃圾回收仍然存活的對象,將被放到年老代中,故都是一些生命周期較長的對象;
 - 持久代:用于存放靜態文件,如Java類、方法等。
 
新生代的垃圾收集器命名為“minor gc”,老生代的GC命名為”Full Gc 或者Major GC”.其中用System.gc()強制執行的是Full GC.
判斷對象是否需要回收的方法有兩種:
- 引用計數 :當某對象的引用數為0時,便可以進行垃圾收集。
 - 對象引用遍歷 :果某對象不能從這些根對象的一個(至少一個)到達,則將它作為垃圾收集。在對象遍歷階段,gc必須記住哪些對象可以到達,以便刪除不可到達的對象,這稱為標記(marking)對象。
 
觸發GC(Garbage Collector)的條件:
- GC在優先級最低的線程中運行,一般在應用程序空閑即沒有應用線程在運行時被調用。
 - Java堆內存不足時,GC會被調用。
 
##實戰問題
 ###1、一個請求超過20秒了,你怎么排查和解決;
###2、說說你覺得做的比較不錯的項目,講一下項目結構和用到的框架,再說一下為什么要選擇這些框架;
###3、“商品秒殺”的解決方案;
 (1)秒殺架構設計理念
- 限流: 鑒于只有少部分用戶能夠秒殺成功,所以要限制大部分流量,只允許少部分流量進入服務后端。
 - 削峰:對于秒殺系統瞬時會有大量用戶涌入,所以在搶購一開始會有很高的瞬間峰值。高峰值流量是壓垮系統很重要的原因,所以如何把瞬間的高流量變成一段時間平穩的流量也是設計秒殺系統很重要的思路。實現削峰的常用的方法有利用緩存和消息中間件等技術。
 - 異步處理:秒殺系統是一個高并發系統,采用異步處理模式可以極大地提高系統并發量,其實異步處理就是削峰的一種實現方式。
 - 內存緩存:秒殺系統最大的瓶頸一般都是數據庫讀寫,由于數據庫讀寫屬于磁盤IO,性能很低,如果能夠把部分數據或業務邏輯轉移到內存緩存,效率會有極大地提升。
 - 可拓展:當然如果我們想支持更多用戶,更大的并發,最好就將系統設計成彈性可拓展的,如果流量來了,拓展機器就好了。像淘寶、京東等雙十一活動時會增加大量機器應對交易高峰。
 
(2)設計思路
 將請求攔截在系統上游,降低下游壓力:秒殺系統特點是并發量極大,但實際秒殺成功的請求數量卻很少,所以如果不在前端攔截很可能造成數據庫讀寫鎖沖突,甚至導致死鎖,最終請求超時。
- 充分利用緩存:利用緩存可極大提高系統讀寫速度。
 - 消息隊列:消息隊列可以削峰,將攔截大量并發請求,這也是一個異步處理過程,后臺業務根據自己的處理能力,從消息隊列中主動的拉取請求消息進行業務處理。
 
(3)前端方案
瀏覽器端(js):
 頁面靜態化:將活動頁面上的所有可以靜態的元素全部靜態化,并盡量減少動態元素。通過CDN來抗峰值。
 禁止重復提交:用戶提交之后按鈕置灰,禁止重復提交
 用戶限流:在某一時間段內只允許用戶提交一次請求,比如可以采取IP限流
(3)后端方案
-  
服務端控制器層(網關層)
限制uid(UserID)訪問頻率:我們上面攔截了瀏覽器訪問的請求,但針對某些惡意攻擊或其它插件,在服務端控制層需要針對同一個訪問uid,限制訪問頻率。 -  
服務層
上面只攔截了一部分訪問請求,當秒殺的用戶量很大時,即使每個用戶只有一個請求,到服務層的請求數量還是很大。比如我們有100W用戶同時搶100臺手機,服務層并發請求壓力至少為100W。
采用消息隊列緩存請求:既然服務層知道庫存只有100臺手機,那完全沒有必要把100W個請求都傳遞到數據庫啊,那么可以先把這些請求都寫到消息隊列緩存一下,數據庫層訂閱消息減庫存,減庫存成功的請求返回秒殺成功,失敗的返回秒殺結束。
利用緩存應對讀請求:對類似于12306等購票業務,是典型的讀多寫少業務,大部分請求是查詢請求,所以可以利用緩存分擔數據庫壓力。
利用緩存應對寫請求:緩存也是可以應對寫請求的,比如我們就可以把數據庫中的庫存數據轉移到Redis緩存中,所有減庫存操作都在Redis中進行,然后再通過后臺進程把Redis中的用戶秒殺請求同步到數據庫中。 -  
數據庫層
數據庫層是最脆弱的一層,一般在應用設計時在上游就需要把請求攔截掉,數據庫層只承擔“能力范圍內”的訪問請求。所以,上面通過在服務層引入隊列和緩存,讓最底層的數據庫高枕無憂。
###4、手寫個單例模式出來; 
###5、分布式鎖的解決方案
###6、分布式事務解決方案
###7、分布式環境下的定時任務管理
2020年3月5日更新
 Java進程4中通信方式
 Java線程同步與異步的不同
 Java線程發生死鎖,如何處理
總結
以上是生活随笔為你收集整理的Java软件工程师面试题汇总(持续更新)的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 博客小编风明姗姗来迟
 - 下一篇: 基于MATLAB的指纹对比识别系统