Java軟件工程師面試題彙總(持續更新)

一、 GC

(1)jvm中一次完整的GC流程(從ygc到fgc)是怎樣的,重點講講對象如何晉升到老年代等
答:對象優先在新生代區中分配,若沒有足夠空間,Minor GC;
大對象(須要大量連續內存空間)直接進入老年態;長期存活的對象進入老年態。若是對象在新生代出生並通過第一次MGC後仍然存活,年齡+1,若年齡超過必定限制(15),則被晉升到老年態。前端

(2)JVM垃圾回收機制,什麼時候觸發MinorGC等操做
分代垃圾回收機制:不一樣的對象生命週期不一樣。把不一樣生命週期的對象放在不一樣代上,不一樣代上採用最合適它的垃圾回收方式進行回收。
JVM中共劃分爲三個代:年輕代、年老代和持久代。 web

  • 年輕代:存放全部新生成的對象;
  • 年老代:在年輕代中經歷了N次垃圾回收仍然存活的對象,將被放到年老代中,故都是一些生命週期較長的對象;
  • 持久代:用於存放靜態文件,如Java類、方法等。

新生代的垃圾收集器命名爲「minor gc」,老生代的GC命名爲」Full Gc 或者Major GC」.其中用System.gc()強制執行的是Full GC. 數據庫

判斷對象是否須要回收的方法有兩種: 後端

  • 引用計數 :當某對象的引用數爲0時,即可以進行垃圾收集。
  • 對象引用遍歷 :果某對象不能從這些根對象的一個(至少一個)到達,則將它做爲垃圾收集。在對象遍歷階段,gc必須記住哪些對象能夠到達,以便刪除不可到達的對象,這稱爲標記(marking)對象。

觸發GC(Garbage Collector)的條件: 瀏覽器

  • GC在優先級最低的線程中運行,通常在應用程序空閒即沒有應用線程在運行時被調用。
  • Java堆內存不足時,GC會被調用。

實戰問題

一、一個請求超過20秒了,你怎麼排查和解決;

二、說說你以爲作的比較不錯的項目,講一下項目結構和用到的框架,再說一下爲何要選擇這些框架;

三、「商品秒殺」的解決方案;

(1)秒殺架構設計理念緩存

  • 限流: 鑑於只有少部分用戶可以秒殺成功,因此要限制大部分流量,只容許少部分流量進入服務後端。
  • 削峯:對於秒殺系統瞬時會有大量用戶涌入,因此在搶購一開始會有很高的瞬間峯值。高峯值流量是壓垮系統很重要的緣由,因此如何把瞬間的高流量變成一段時間平穩的流量也是設計秒殺系統很重要的思路。實現削峯的經常使用的方法有利用緩存和消息中間件等技術。
  • 異步處理:秒殺系統是一個高併發系統,採用異步處理模式能夠極大地提升系統併發量,其實異步處理就是削峯的一種實現方式。
  • 內存緩存:秒殺系統最大的瓶頸通常都是數據庫讀寫,因爲數據庫讀寫屬於磁盤IO,性能很低,若是可以把部分數據或業務邏輯轉移到內存緩存,效率會有極大地提高。
  • 可拓展:固然若是咱們想支持更多用戶,更大的併發,最好就將系統設計成彈性可拓展的,若是流量來了,拓展機器就行了。像淘寶、京東等雙十一活動時會增長大量機器應對交易高峯。

(2)設計思路
將請求攔截在系統上游,下降下游壓力:秒殺系統特色是併發量極大,但實際秒殺成功的請求數量卻不多,因此若是不在前端攔截極可能形成數據庫讀寫鎖衝突,甚至致使死鎖,最終請求超時。 架構

  • 充分利用緩存:利用緩存可極大提升系統讀寫速度。
  • 消息隊列:消息隊列能夠削峯,將攔截大量併發請求,這也是一個異步處理過程,後臺業務根據本身的處理能力,從消息隊列中主動的拉取請求消息進行業務處理。

(3)前端方案併發

瀏覽器端(js):
頁面靜態化:將活動頁面上的全部能夠靜態的元素所有靜態化,並儘可能減小動態元素。經過CDN來抗峯值。
禁止重複提交:用戶提交以後按鈕置灰,禁止重複提交
用戶限流:在某一時間段內只容許用戶提交一次請求,好比能夠採起IP限流框架

(3)後端方案異步

  • 服務端控制器層(網關層)
    限制uid(UserID)訪問頻率:咱們上面攔截了瀏覽器訪問的請求,但針對某些惡意攻擊或其它插件,在服務端控制層須要針對同一個訪問uid,限制訪問頻率。

  • 服務層
    上面只攔截了一部分訪問請求,當秒殺的用戶量很大時,即便每一個用戶只有一個請求,到服務層的請求數量仍是很大。好比咱們有100W用戶同時搶100臺手機,服務層併發請求壓力至少爲100W。
    採用消息隊列緩存請求:既然服務層知道庫存只有100臺手機,那徹底沒有必要把100W個請求都傳遞到數據庫啊,那麼能夠先把這些請求都寫到消息隊列緩存一下,數據庫層訂閱消息減庫存,減庫存成功的請求返回秒殺成功,失敗的返回秒殺結束。
    利用緩存應對讀請求:對相似於12306等購票業務,是典型的讀多寫少業務,大部分請求是查詢請求,因此能夠利用緩存分擔數據庫壓力。
    利用緩存應對寫請求:緩存也是能夠應對寫請求的,好比咱們就能夠把數據庫中的庫存數據轉移到Redis緩存中,全部減庫存操做都在Redis中進行,而後再經過後臺進程把Redis中的用戶秒殺請求同步到數據庫中。

  • 數據庫層
    數據庫層是最脆弱的一層,通常在應用設計時在上游就須要把請求攔截掉,數據庫層只承擔「能力範圍內」的訪問請求。因此,上面經過在服務層引入隊列和緩存,讓最底層的數據庫高枕無憂。

四、手寫個單例模式出來;

五、分佈式鎖的解決方案

六、分佈式事務解決方案

七、分佈式環境下的定時任務管理