Android第四次面試總結之Java基礎篇(補充)

一、設計原則高頻面試題(附大廠真題解析)

1. 單一職責原則(SRP)在 Android 開發中的應用(字節跳動真題)
  • 真題:“你在項目中如何體現單一職責原則?舉例說明。”
  • 考點:結合實際場景說明職責拆分,避免貧血模型。
  • 滿分答案
    在開發網絡模塊時,原代碼將 “網絡請求邏輯”“數據解析”“錯誤處理” 耦合在一個NetworkManager類中,違反 SRP。
    重構方案
    1. 拆分為OkHttpHelper(負責底層網絡請求)、DataParser(解析 JSON/Proto 數據)、ErrorHandler(統一處理網絡異常);
    2. 高層模塊(如UserRepository)依賴這三個抽象組件,通過構造器注入協作。
      優勢:每個類僅一個修改原因(如網絡庫升級只需改OkHttpHelper),降低維護成本。
2. 里氏替換原則(LSP)的經典反例及修正(騰訊真題)
  • 真題:“為什么 Square 不能直接繼承 Rectangle?如何正確設計?”
  • 考點:理解繼承的約束條件,區分 “Is-a” 與 “Can-do”。
  • 滿分答案
    反例分析
    • Rectangle定義setWidth(int w)setHeight(int h),允許寬高獨立變化;
    • Square重寫這兩個方法時,強制寬高相等,破壞父類 “寬高可獨立設置” 的契約,違反 LSP(子類不能替換父類)。
      修正方案
    1. 放棄繼承,讓SquareRectangle實現共同接口Quadrilateral,提供getWidth()getHeight(),但不強制寬高可獨立設置;
    2. 或引入MutableRectangle接口,明確 “可修改寬高” 的能力,Square不實現該接口。
3. 依賴倒置原則(DIP)在 MVP 中的應用(阿里真題)
  • 真題:“MVP 架構如何體現依賴倒置原則?”
  • 考點:區分高層模塊與低層模塊,抽象接口解耦。
  • 滿分答案
    MVP 分層
    • 高層模塊(Presenter):依賴抽象接口View(如UserView)和Repository(如UserRepository),而非具體實現(ActivityRetrofitImpl);
    • 低層模塊(Model/View 實現):實現這些抽象接口,如UserActivity implements UserViewUserRetrofit implements UserRepository
      依賴關系
      Presenter 與具體 Activity / 網絡庫解耦,可通過依賴注入(如 Dagger)切換實現(如單元測試時用 MockView),符合 “高層模塊依賴抽象” 的 DIP 原則。

二、DCL 單例模式大廠真題解析

1. 為什么 DCL 單例需要 volatile?(美團真題)
  • 考點:理解指令重排對單例的影響,volatile 的內存語義。
  • 滿分答案
    指令重排風險
    instance = new DCLSingleton()可分解為:
    1. 分配內存空間(memory = allocate());
    2. 初始化對象(ctorInstance(memory));
    3. 將內存地址賦給instanceinstance = memory)。
      JVM 可能重排為 1→3→2,若線程 A 執行到 3 時(instance非空但未初始化),線程 B 調用getInstance()返回未初始化的對象,導致 NPE。
      volatile 作用
    • 禁止指令重排,確保 1→2→3 的順序;
    • 保證可見性,線程 A 修改instance后,線程 B 立即看到最新值。
      JDK 版本關鍵:JDK 1.5 + 修復了 volatile 的語義,此前版本 DCL 可能失效,因此現代 Java 必須使用 volatile。
2. 單例模式的線程安全實現有哪些?對比優缺點(百度真題)
  • 考點:掌握不同單例實現的適用場景,反序列化安全。
  • 滿分答案
實現方式線程安全優點缺點大廠應用場景
DCL延遲初始化,性能高需 volatile,實現較復雜高并發且內存敏感場景
靜態內部類簡潔,利用類加載機制安全類加載后立即初始化通用場景(推薦)
枚舉單例反序列化安全,防止反射攻擊不支持延遲初始化需嚴格防止實例化場景
  • 反序列化安全
    枚舉單例天然支持(Java 規范保證反序列化返回枚舉常量),其他方式需重寫readResolve()返回單例實例:
    protected Object readResolve() { return instance; }  
    

三、HashMap 高頻面試題(附大廠真題解析)

1. JDK8 HashMap 為什么引入紅黑樹?鏈表轉紅黑樹的條件?(字節跳動真題)
  • 考點:理解哈希沖突優化,閾值設計原理。

  • 滿分答案
    引入紅黑樹原因
    JDK7 及以前用鏈表處理哈希沖突,當鏈表長度為 n 時,查找時間復雜度 O (n)。數據傾斜時(如大量鍵哈希值相同),鏈表可能很長,性能下降。
    紅黑樹將查找、插入、刪除的時間復雜度降至 O (logn),提升極端場景下的性能。

    轉換條件(兩個同時滿足)

    1. 鏈表長度≥8(TREEIFY_THRESHOLD=8);
    2. 數組容量≥64(MIN_TREEIFY_CAPACITY=64)。
      原因
    • 鏈表長度 8 的概率極低(泊松分布計算,概率僅 0.0000006),若出現則認為是哈希沖突嚴重;
    • 若數組容量小(如 16),直接擴容比轉紅黑樹更高效(減少樹節點維護開銷)。
2. 自定義類作為 HashMap 的 Key 需要注意什么?(阿里真題)
  • 考點:正確重寫 hashCode 和 equals,不可變性。
  • 滿分答案
    1. 必須重寫hashCode()equals()
      • 若只重寫equals,不同對象可能哈希值相同,導致存入 HashMap 后無法正確查找;
      • 示例:
        class Person {  String id;  @Override public boolean equals(Object o) { ... }  // 必須同時重寫hashCode,保證相等對象哈希值相同  @Override public int hashCode() { return Objects.hash(id); }  
        }  
        
    2. Key 建議為不可變類
      • 若 Key 可變,修改后哈希值變化,導致存入的鍵值對無法通過新值查找(如String是不可變類,推薦作為 Key);
      • 若必須用可變類,修改前先從 HashMap 中刪除舊 Key。

四、ConcurrentHashMap 大廠真題解析

1. JDK7 與 JDK8 的 ConcurrentHashMap 實現有何區別?(騰訊真題)
  • 考點:分段鎖 vs 細粒度鎖,數據結構演進。
  • 滿分答案
特性JDK7(分段鎖)JDK8(CAS + 細粒度鎖)
數據結構Segment 數組(每個 Segment 是小 HashMap)數組 + 鏈表 + 紅黑樹(同 HashMap 結構)
鎖機制對 Segment 加 ReentrantLock(鎖粒度大)對鏈表頭節點或紅黑樹根節點加 synchronized(鎖粒度小)
插入邏輯鎖 Segment 后遍歷鏈表先 CAS 無鎖插入,失敗后加鎖
并發度受限于 Segment 數量(默認 16)理論并發度更高(鎖競爭更小)
內存效率每個 Segment 有獨立數組,內存占用略高共享數組,內存更緊湊
  • 典型場景
    JDK8 在高并發寫入場景(如秒殺系統的計數器)性能提升顯著,因鎖粒度從 “段” 細化到 “節點”,減少線程競爭。
2. ConcurrentHashMap 為什么不允許 Key 和 Value 為 null?(美團真題)
  • 考點:線程安全與 null 值的歧義性。
  • 滿分答案
    歷史原因
    • HashMap 允許 null Key(唯一)和 null Value,ConcurrentHashMap 為避免與 Hashtable(不允許 null)行為不一致,選擇不允許 null;
    • 更重要的是,null 值在多線程場景下存在歧義:
      • get(key)返回 null 時,無法區分 “Key 不存在” 和 “Value 為 null”;
      • 若允許 null Value,多線程插入時可能出現 “Key 存在但 Value 為 null” 的中間狀態,導致后續讀取誤判。
        對比 HashMap
        HashMap 單線程下可明確處理 null(Key 只能有一個 null,Value 可為多個 null),但 ConcurrentHashMap 作為線程安全類,需避免這種歧義性,保證語義清晰。

五、面試真題陷阱與避坑指南

1. 設計原則陷阱題:“所有類都應該遵守單一職責原則嗎?”(字節跳動)
  • 陷阱:考察對原則的靈活應用,而非教條主義。
  • 正確回答
    不是。單一職責原則的 “職責” 是 “變化的原因”,若多個職責不會同時變化(如 “用戶校驗” 和 “日志記錄” 在項目中始終一起修改),可暫時合并以減少類數量。原則需結合項目規模和變化頻率權衡,避免過度設計。
2. HashMap 擴容陷阱:“初始容量設為 10,實際數組長度是多少?”(阿里)
  • 陷阱:HashMap 會將容量自動調整為≥給定值的最小 2 的冪(10→16)。
  • 正確回答
    實際長度為 16。HashMap 的構造函數會調用tableSizeFor(int cap)方法,將容量向上取整為 2 的冪,確保(n-1)&hash的計算正確性。

面試擴展:

1. 設計原則綜合題:“MVC 架構是否符合開閉原則?為什么?”
  • 考點:架構與設計原則的結合,擴展性分析。
  • 預測答案
    部分符合
    • View 層(如 Activity)常因 UI 變化直接修改,違反 “對修改關閉”;
    • Model 層(數據模型)和 Controller 層(邏輯處理)可通過抽象接口擴展(如新增數據源時實現新 Model 接口),符合 “對擴展開放”。
      改進建議
      引入接口隔離,讓 View 依賴抽象(如 MVP 中的 View 接口),減少對具體實現的修改,更貼近開閉原則。
2. HashMap 深度陷阱題:“鍵的 hashCode () 返回 0,會發生什么?如何優化?”
  • 考點:極端哈希沖突處理,紅黑樹閾值。
  • 預測答案
    • 所有鍵存入數組的 0 號位置,形成長鏈表(或紅黑樹);
    • 若數組容量≥64 且鏈表長度≥8,轉為紅黑樹,查詢時間復雜度 O (logn);
    • 優化:重寫 hashCode (),讓鍵的哈希值更分散(如結合多個字段計算哈希)。

六、總結

知識點高頻問題示例核心考點滿分答案關鍵要素
單一職責原則如何拆分 Android 中的網絡模塊?職責定義(變化原因)、實際案例拆分前后對比,說明每個類的獨立變化原因
DCL 單例為什么需要兩次檢查和 volatile?線程安全、指令重排、可見性結合源碼解釋兩次檢查的作用,volatile 的必要性
HashMap 紅黑樹鏈表轉紅黑樹的條件是什么?閾值設計、概率分析、性能權衡同時滿足長度≥8 和容量≥64,避免小樹維護開銷
ConcurrentHashMap與 Hashtable 的區別?鎖機制、null 支持、并發度細粒度鎖 vs 全表鎖,弱一致性設計
設計原則與集合類核心考點  
├─ 設計原則(6大原則)  
│  ├─ SRP:職責=變化原因,拆分類/模塊  
│  ├─ OCP:通過抽象擴展,避免修改原有代碼  
│  ├─ LSP:子類可替換父類,不破壞契約  
│  ├─ ISP:接口細化,客戶端不依賴無用方法  
│  ├─ DIP:高層模塊依賴抽象,而非具體實現  
│  └─ LoD:僅與直接朋友交互,減少耦合  
├─ DCL單例  
│  ├─ 雙重檢查+volatile:防指令重排,線程安全  
│  ├─ 防御反射/反序列化:構造函數檢查+readResolve  
│  └─ 最佳實踐:枚舉單例(最簡、最安全)  
├─ HashMap  
│  ├─ 底層:數組+鏈表(≥8轉紅黑樹,容量≥64)  
│  ├─ 哈希計算:高位異或,減少沖突  
│  ├─ 擴容:容量翻倍,重新哈希(初始容量設為2的冪)  
│  └─ Key要求:重寫hashCode/equals,不可變類最佳  
└─ ConcurrentHashMap  ├─ 線程安全:JDK8細粒度synchronized+CAS  ├─ 與HashMap區別:不允許null,弱一致性  └─ 適用場景:高并發讀寫,替代Hashtable/同步HashMap  

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/81892.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/81892.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/81892.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenHarmony GPIO應用開發-LED

學習于: https://docs.openharmony.cn/pages/v5.0/zh-cn/device-dev/driver/driver-platform-gpio-develop.md https://docs.openharmony.cn/pages/v5.0/zh-cn/device-dev/driver/driver-platform-gpio-des.md 通過OpenHarmony官方文檔指導可獲知:芯片廠…

XILINX原語之——xpm_fifo_async(異步FIFO靈活設置位寬、深度)

目錄 一、"fwft"模式(First-Word-Fall-Through read mode) 1、寫FIFO 2、讀FIFO 二、"std"模式(standard read mode) 1、寫FIFO 2、讀FIFO 調用方式和xpm_fifo_sync基本一致: XILINX原語之…

系統學習算法:動態規劃(斐波那契+路徑問題)

題目一: 思路: 作為動態規劃的第一道題,這個題很有代表性且很簡單,適合入門 先理解題意,很簡單,就是斐波那契數列的加強版,從前兩個數變為前三個數 算法原理: 這五步可以說是所有…

《讓內容“活”起來:Flutter社交應用瀑布流布局的破界實踐》

用戶動態的展示方式如同舞臺的布景,直接影響著觀眾——用戶的體驗。而瀑布流布局,以其獨特的美感和高效的信息展示能力,成為眾多社交應用的心頭好。當我們滑動著Instagram、Pinterest,或是國內熱門的小紅書,那種內容如…

微機控制技術復習【一】

填空題: 簡答題: 1、什么是計算機控制系統?其典型形式有哪些? 2、給出 DDC (直接數字控制)控制系統結構框圖,并說明各組成部分的作用? 3、采樣周期選擇的理論依據是什么?工程應用中應如何選擇?選擇采樣…

前端學習基礎—VScode環境配置及html基礎知識

作為初學者,一個好的開發環境能極大地提高理解與學習的效率,本文分享我的VScode環境配置方法,涵蓋插件、主題、快捷鍵等,希望能助你快速搭建舒適邊界的前端學習環境。 一、VSCode環境配置 首先找到vscode插件商店,在這…

【一】 基本概念與應用領域【830數字圖像處理】

考綱 文章目錄 1 概念2005甄題【名詞解釋】2008、2012甄題【名詞解釋】可考題【簡答題】可考題【簡答題】 2 應用領域【了解】2.1 伽馬射線成像【核醫學影像】☆2.2 X射線成像2.3 紫外波段成像2.4 可見光和紅外波段成像2.5 微波波段成像2.6 無線電波段成像2.7 電子顯微鏡成像2…

QuecPython錯誤碼匯總

QuecPython中定義的各種錯誤代碼常量 錯誤碼常量錯誤碼釋義QUEC_PY_FAIL-1Generic failure codesQUEC_PY_OK0Quec_py value indicating success (no error)QUEC_PY_EPERM1Operation not permittedQUEC_PY_ENOENT2No such file or directoryQUEC_PY_ESRCH3No such processQUEC_…

C++學習-入門到精通-【4】函數與遞歸入門

C學習-入門到精通-【4】函數與遞歸入門 函數與遞歸入門 C學習-入門到精通-【4】函數與遞歸入門一、 數學庫函數sqrt()ceil()cos()exp()fabs()floor()fmod()log()log10()pow()sin()tan()總結 二、具有多個形參的函數定義三、函數原型、函數簽名和實參的強制類型轉換函數原型函數…

天線測試報告解讀學習

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 前言一、無源測試和有源測試二、無源測試報告1.駐波2.回損3.史密斯圓圖4.效率5.增益6.天線方向圖7.天線隔離度8.無源測試總結 三、有源測試報告1.TRP與TIS2.測試指標…

GEC6818蜂鳴器驅動開發

相關知識&#xff1a;Linux設備驅動開發 insmod 編譯好的.ko文件后再運行beep_app.c編譯完成的可執行文件即可使板子蜂鳴。 beep_drv.c: #include <linux/module.h> //包含了加載模塊時需要使用的大量符號和函數聲明 #include <linux/kernel.h> //包含了printk內…

電腦定時管家!Wise Auto Shutdown 深度測評:多任務執行 + 靈活定時

各位電腦小達人&#xff0c;今天給大家介紹一款超厲害的Windows系統定時任務管理工具——Wise Auto Shutdown&#xff01;這玩意兒就像電腦的貼心小管家&#xff0c;能自動執行關機、重啟這些操作&#xff0c;時間設定靈活得很&#xff0c;還有提醒機制呢。下面我給大家好好嘮嘮…

vscode 配置qt

工具&#xff1a;vscode、qttools、qtconfigure Search Mode改成基于cmake的。 # 在項目中指定Qt的路徑 set(Qt5_DIR "/home/jp/qt-everywhere-src-5.12.9/arm-qt/lib/cmake/Qt5") # 用于指定 Qt5 的安裝路徑 find_package(Qt5 REQUIRED COMPONENTS Widgets)這樣就…

基于Boost庫、Jsoncpp、cppjieba、cpp-httplib等構建Boost搜索引擎

??個人主頁&#xff1a;小羊 ??所屬專欄&#xff1a;項目 很榮幸您能閱讀我的文章&#xff0c;誠請評論指點&#xff0c;歡迎歡迎 ~ 目錄 項目背景技術棧和項目環境正排索引和倒排索引數據去標簽與清洗下載數據源去標簽 建立索引構建正排索引構建倒排索引 建立搜索引擎h…

QMK機械鍵盤固件開發指南:從源碼到實踐

QMK機械鍵盤固件開發指南&#xff1a;從源碼到實踐 前言 QMK&#xff08;Quantum Mechanical Keyboard&#xff09;是一款開源的鍵盤固件&#xff0c;支持眾多自定義鍵盤的功能配置。通過QMK&#xff0c;您可以完全掌控鍵盤的每一個按鍵&#xff0c;實現復雜的宏指令、多層按…

WPF 導航

WPF 導航相關控件/機制 控件 / 類說明常用屬性/方法Frame用來承載不同的頁面 (Page) 并在它們之間切換的容器。Source&#xff08;導航到的 URI&#xff09; Navigate()&#xff08;導航方法&#xff09; CanGoBack / GoBack() CanGoForward / GoForward()Page表示一個單獨的可…

時序建模演進之路:從 MLP、RNN 到 LSTM 與 GRU

時序建模演進之路&#xff1a;從 MLP、RNN 到 LSTM 與 GRU 您是否好奇機器如何能像人類一樣理解、生成流暢的文本&#xff0c;甚至是從海量代碼中自動生成文檔&#xff1f;這些自然語言處理 (NLP) 領域的迷人挑戰&#xff0c;其核心在于模型處理和記憶 序列數據 的能力。 然而…

【Redis——數據類型和內部編碼和Redis使用單線程模型的分析】

文章目錄 Redis的數據類型和內部編碼單線程模型的工作過程Redis在處理命令時雖然是一個單線程模型&#xff0c;為啥效率那么高&#xff0c;速度快呢&#xff1f; 總而言之&#xff0c;Redis提供的哈希表容器并不一定真的是真的哈希表&#xff0c;而是在特點的場景下&#xff0c…

鴻蒙NEXT開發動畫(風格的旋轉加載動畫組件)

1.創建空白項目 2.Page文件夾下面新建Spin.ets文件&#xff0c;代碼如下&#xff1a; /*** SpinKit 風格的旋轉加載動畫組件。** component* param spinSize - 動畫容器大小&#xff08;必須為正數&#xff09;* param spinColor - 動畫顏色&#xff08;支持資源引用&#xf…

后端接口請求http改為https

1、使用 OpenSSL 生成自簽名證書 在Linxu服務器上執行如下命令&#xff1a; openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes 運行此命令后&#xff0c;會提示輸入一些信息&#xff08;如國家、省份、城市、組織名稱等&#xff09;&…