一線互聯網常見的Java面試題,你顫抖了嗎程式員

来源:https://www.cnblogs.com/Ti1077/archive/2018/08/25/9535398.html
-Advertisement-
Play Games

跳槽不算頻繁,但參加過不少面試(電話面試、face to face面試),面過大/小公司、互聯網/傳統軟體公司,麵糊過(眼高手低,缺乏實戰經驗,掛掉),也面過人,所幸未因失敗而氣餒,在此過程中不斷查缺補漏,養成了踏實、追本溯源、持續改進的習慣,特此將自己經歷過、構思過的一些面試題記錄下來,如果答案有 ...


跳槽不算頻繁,但參加過不少面試(電話面試、face to face面試),面過大/小公司、互聯網/傳統軟體公司,麵糊過(眼高手低,缺乏實戰經驗,掛掉),也面過人,所幸未因失敗而氣餒,在此過程中不斷查缺補漏,養成了踏實、追本溯源、持續改進的習慣,特此將自己經歷過、構思過的一些面試題記錄下來,如果答案有問題,歡迎拍磚討論,希望能對找工作或者感興趣的同學有所幫助,陸續整理中。

一. synchronized和reentrantlock異同

相同點

都實現了多線程同步和記憶體可見性語義

都是可重入鎖

不同點

實現機制不同 synchronized通過java對象頭鎖標記和Monitor對象實現 reentrantlock通過CAS、ASQ(AbstractQueuedSynchronizer)和locksupport(用於阻塞和解除阻塞)實現 synchronized依賴jvm記憶體模型保證包含共用變數的多線程記憶體可見性 reentrantlock通過ASQ的volatile state保證包含共用變數的多線程記憶體可見性

使用方式不同 synchronized可以修飾實例方法(鎖住實例對象)、靜態方法(鎖住類對象)、代碼塊(顯示指定鎖對象) reentrantlock顯示調用trylock()/lock()方法,需要在finally塊中釋放鎖

功能豐富程度不同 reentrantlock提供有限時間等候鎖(設置過期時間)、可中斷鎖(lockInterruptibly)、condition(提供await、signal等方法)等豐富語義 reentrantlock提供公平鎖和非公平鎖實現 synchronized不可設置等待時間、不可被中斷(interrupted)

二. concurrenthashmap為何讀不用加鎖

jdk1.7

  1. HashEntry中的key、hash、next 均為final 型,只能表頭插入、刪除結點
  2. HashEntry類的value域被聲明為volatile型
  3. 不允許用null作為鍵和值,當讀線程讀到某個HashEntry的 value域的值為null時,便知道產生了衝突——發生了重排序現象(put設置新value對象的位元組碼指令重排序),需要加鎖後重新讀入這個value值
  4. volatile變數count協調讀寫線程之間的記憶體可見性,寫操作後修改count,讀操作先讀count,根據happen-before傳遞性原則寫操作的修改讀操作能夠看到

jdk1.8

  1. Node的val和next均為volatile型
  2. tabAt和casTabAt對應的unsafe操作實現了volatile語義

三. ContextClassLoader(線程上下文類載入器)的作用

越過類載入器的雙親委派機制去載入類,如serviceloader實現

使用線程上下文類載入器載入類,要註意保證多個需要通信的線程間的類載入器應該是同一個,防止因為不同的類載入器導致類型轉換異常(ClassCastException)

四. tomcat 類載入機制

 

 

 

 

不同應用使用不同的 webapp類載入器,實現應用隔離的效果,webapp類載入器下麵是jsp類載入器

不同應用共用的jar包可以放到Shared類載入器/shared目錄下

五. osgi類載入機制

osgi類載入模型是網狀的,可以在模塊(Bundle)間互相委托

osgi實現模塊化熱部署的關鍵是自定義類載入器機制的實現,每個Bundle都有一個自己的類載入器,當需要更換一個Bundle時,就把Bundle連同類載入器一起換掉以實現代碼的熱替換

當收到類載入請求時,osgi將按照下麵的順序進行類搜索:

  1. 將以java.*開頭的類委派給父類載入器載入
  2. 否則,將委派列表名單(配置文件org.osgi.framework.bootdelegation中定義)內的類委派給父類載入器載入
  3. 否則,檢查是否在Import-Package中聲明,如果是,則委派給Export這個類的Bundle的類載入器載入
  4. 否則,檢查是否在Require-Bundle中聲明,如果是,則將類載入請求委托給required bundle的類載入器
  5. 否則,查找當前Bundle的ClassPath,使用自己的類載入器載入
  6. 否則,查找類是否在自己的Fragment Bundle中,如果在,則委派給Fragment Bundle的類載入器載入
  7. 否則,查找Dynamic Import-Package(Dynamic Import只有在真正用到此Package的時候才進行載入)的Bundle,委派給對應Bundle的類載入器載入
  8. 否則,類查找失敗

六. 如何結束一個一直運行的線程

使用退出標誌,這個flag變數要多線程可見

使用interrupt,結合isInterrupted()使用

七. threadlocal使用場景及問題

threadlocal並不能解決多線程共用變數的問題,同一個 threadlocal所包含的對象,在不同的thread中有不同的副本,互不幹擾

用於存放線程上下文變數,方便同一線程對變數的前後多次讀取,如事務、資料庫connection連接,在web編程中使用的更多

問題: 註意線程池場景使用threadlocal,因為實際變數值存放在了thread的threadlocalmap類型變數中,如果該值沒有remove,也沒有先set的話,可能會得到以前的舊值

問題: 註意線程池場景下的記憶體泄露,雖然threadlocal的get/set會清除key(key為threadlocal的弱引用,value是強引用,導致value不釋放)為null的entry,但是最好remove

八. 線程池從啟動到工作的流程

剛創建時,裡面沒有線程

調用 execute() 添加任務時:

  1. 如果正在運行的線程數量小於核心參數corePoolSize,繼續創建線程運行這個任務
  2. 否則,如果正在運行的線程數量大於或等於corePoolSize,將任務加入到阻塞隊列中
  3. 否則,如果隊列已滿,同時正在運行的線程數量小於核心參數maximumPoolSize,繼續創建線程運行這個任務
  4. 否則,如果隊列已滿,同時正在運行的線程數量大於或等於 maximumPoolSize,根據設置的拒絕策略處理
  5. 完成一個任務,繼續取下一個任務處理
  6. 沒有任務繼續處理,線程被中斷或者線程池被關閉時,線程退出執行,如果線程池被關閉,線程結束
  7. 否則,判斷線程池正在運行的線程數量是否大於核心線程數,如果是,線程結束,否則線程阻塞。因此線程池任務全部執行完成後,繼續留存的線程池大小為corePoolSize

九. 阻塞隊列BlockingQueue take和poll區別

poll(time):取走BlockingQueue里排在首位的對象,若不能立即取出,則可以等time參數規定的時間,取不到時返回null

take():取走BlockingQueue里排在首位的對象,若BlockingQueue為空,阻塞直到BlockingQueue有新的對象被加入

十. 如何從FutureTask不阻塞獲取結果

get(long timeout,TimeUnit unit),超時則返回

輪詢,先通過isDone()判斷是否結束,然後調用get()

十一. blockingqueue如果存放了比較關鍵的數據,系統宕機該如何處理

開放性問題,歡迎討論

將隊列持久化,比較麻煩,需要將生產數據持久化到磁碟,持久化成功才返回,消費者線程從磁碟載入數據到記憶體阻塞隊列中,維護消費offset,啟動時,根據消費offset從磁碟載入數據

加入消息隊列,保證消息不丟失,生成序列號,消費冪等,根據消費進程決定系統重啟後的生產狀態

十二. NIO與傳統I/O的區別

節約線程,NIO由原來的每個線程都需要阻塞讀寫變成了由單線程(即Selector)負責處理多個channel註冊(register)的興趣事件(SelectionKey)集合(底層藉助操作系統提供的epoll()),netty bossgroup處理accept連接(沒看明白為什麼bossgroup設置多個thread的必要性),workergroup處理具體業務流程和數據讀寫

NIO提供非阻塞操作

傳統I/O 以流的方式處理數據,而 NIO 以塊的方式處理數據,NIO提供bytebuffer,分為堆內和堆外緩衝區,讀寫時均先放到該緩衝區中,然後由內核通過channel傳輸到對端,堆外緩衝區不走內核,提升了性能

十三. list中存放可重覆字元串,如何刪除某個字元串

調用iterator相關方法刪除

倒刪,防止正序刪除導致的數組重排,index跳過數組元素問題

十四. 有哪些GC ROOTS(跟日常開發比較相關的是和此相關的記憶體泄露)

所有Java線程當前活躍的棧幀里指向GC堆里的對象的引用,因此用不到的對象及時置null,提升記憶體回收效率

靜態變數引用的對象,因此減少靜態變數特別是靜態集合變數的大小,集合存放的對象覆寫euqls()和hashcode(),防止持續增長

本地方法JNI引用的對象

方法區中的常量引用的對象,因此減少在長字元串上調用String.intern()

classloader載入的class對象,因此自定義classloader無效時及時置null並且註意類載入器載入對象之間的隔離

jvm里的一些靜態數據結構里指向GC堆里的對象的引用

 

寫在最後:歡迎留言討論,加關註,持續更新!!!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 上文已經總結了AQS的前世今生,有了這個基礎我們就可以來進一步學習併發工具類。首先我們要學習的就是ReentrantLock,本文將從ReentrantLock的產生背景、源碼原理解析和應用來學習ReentrantLock這個併發工具類。 1、 產生背景 前面我們已經學習過了synchronized ...
  • 1、繼承 2、抽象類 3、綜合案例---員工類系列定義 ...
  • Python中的For迴圈 1.For迴圈語句 1.Python for迴圈可以遍歷任何序列類型,如一個列表或者一個字元串。如下代碼應該能理解,依次輸出序列元素。 2.for else語句(就是在迴圈結束後,執行else的內容) 3.for迴圈中的break語句與countinue語句(條件達成時, ...
  • 一、三元表達式的使用 name = 'alex' age = 20 if name == 'alex' else 22 print(age) 二、列表推導式(聲明式編程) l = ['alex%s' %i for i in range(10) if i > 5] print(l) 三、生成器表達式 ...
  • 前言 Python 是一種極具可讀性和通用性的編程語言。Python 這個名字的靈感來自於英國喜劇團體 Monty Python,它的開發團隊有一個重要的基礎目標,就是使語言使用起來很有趣。Python 易於設置,並且是用相對直接的風格來編寫,對錯誤會提供即時反饋,對初學者而言是個很好的選擇。 Py ...
  • 我們在coding的時候,會經常遇到要求我們處理InterruptedException的情況,本文將解釋如何正確處理此異常以及背後的原因。 ...
  • 相信很多微信用戶在使用微信給朋友,同事發送相冊中的文件時,微信會顯示你手機中的視頻文件,這樣很不方便. 如果要完全不顯示視頻文件: 隨便在手機中建立一個文件夾,名字叫 ".nomedia",把視頻文件丟進去就行了. 如何隱藏你希望隱藏的視頻文件: 隨便在手機中建立一個文件夾,名字叫 ".nomedi ...
  • Python序列內置類型之元組類型詳解 1.元祖的概念 Python中的元組與列表類似,都是一個序列,不同的是元組的元素不能修改而已。 2.元組的創建 元組使用小括弧,列表使用方括弧。 註意:元組中只包含一個元素時,需要在元素後面添加逗號,否則括弧會被當作運算符使用。 3.Python元組操作 1. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...