26屆進大廠計劃——小紅書后端實習面經(jīng)

作者介紹

?? 浙江大學軟件工程碩士生

?? 淘天后端研發(fā)工程師

?? 秋招斬獲阿里、字節(jié)、快手、京東、美團等多個大廠研發(fā)ssp/sp

?? 持續(xù)分享秋招經(jīng)驗分享、高頻八股問題、最新大廠面經(jīng)、硬核技術(shù)干貨……

?? 全網(wǎng)同號,歡迎關(guān)注

1、【實習經(jīng)歷】在實習過程中是否遇到過技術(shù)難題?如果有,是如何分析和解決的?

  • 技術(shù)難題
    在高并發(fā)場景下,系統(tǒng)接口響應(yīng)時間變長,數(shù)據(jù)庫查詢效率低下。

  • 分析與解決過程

    • 定位問題:通過日志分析和性能監(jiān)控工具(如 Arthas 或 JProfiler)發(fā)現(xiàn)數(shù)據(jù)庫慢查詢是主要瓶頸。
    • 數(shù)據(jù)庫優(yōu)化:對慢查詢進行索引優(yōu)化,并引入 Redis 緩存熱點數(shù)據(jù),減少數(shù)據(jù)庫直接訪問。
    • 線程池調(diào)優(yōu):調(diào)整線程池的核心線程數(shù)和最大線程數(shù),避免線程過多導致上下文切換開銷過大。
    • 異步化處理:使用 CompletableFuture 對耗時操作進行異步化處理,提升系統(tǒng)吞吐量。
    • 結(jié)果:經(jīng)過優(yōu)化,系統(tǒng)響應(yīng)時間顯著降低,性能得到明顯提升。

2、【并發(fā)編程】請談?wù)剬潭ň€程池的理解,它的使用場景是什么?有哪些優(yōu)缺點?使用線程池時可能存在哪些限制?常見的線程池拒絕策略有哪些?

  • 固定線程池的理解
    固定線程池通過 Executors.newFixedThreadPool(int nThreads) 創(chuàng)建,核心線程數(shù)和最大線程數(shù)相同,且線程數(shù)量固定。

  • 使用場景
    適用于任務(wù)量穩(wěn)定、執(zhí)行時間較短的任務(wù),例如批量數(shù)據(jù)處理或定時任務(wù)調(diào)度。

  • 優(yōu)點

    • 性能優(yōu)化:線程數(shù)量固定,避免頻繁創(chuàng)建和銷毀線程的開銷。
    • 資源控制:能夠有效控制并發(fā)線程數(shù),防止資源耗盡。
  • 缺點

    • 內(nèi)存風險:如果任務(wù)隊列無界,可能導致內(nèi)存溢出(OOM)。
    • 阻塞問題:不適合執(zhí)行耗時較長的任務(wù),容易造成線程阻塞。
  • 限制
    動態(tài)擴展不足:線程池大小固定,無法動態(tài)擴展,可能不適合任務(wù)量波動較大的場景。

  • 常見拒絕策略

    • AbortPolicy:直接拋出異常,拒絕新任務(wù)。
    • CallerRunsPolicy:由調(diào)用線程執(zhí)行被拒絕的任務(wù)。
    • DiscardPolicy:直接丟棄新任務(wù),不拋異常。
    • DiscardOldestPolicy:丟棄隊列中最老的任務(wù),嘗試重新提交新任務(wù)。

3、【項目經(jīng)驗】針對黑馬點評項目中的秒殺功能,請詳細描述其實現(xiàn)邏輯。

  • 實現(xiàn)邏輯

    • 庫存預(yù)熱:將商品庫存加載到 Redis 中,利用 Redis 的原子操作(如 decr)進行庫存扣減。
    • 限流與排隊:通過分布式限流工具(如 Redis 的計數(shù)器或令牌桶算法)限制請求流量,避免系統(tǒng)過載。
    • 分布式鎖:使用 Redisson 分布式鎖確保同一商品不會被超賣。
    • 訂單生成:庫存扣減成功后,將訂單信息寫入消息隊列(如 RabbitMQ),由后臺消費者異步處理訂單入庫。
    • 冪等性控制:通過唯一標識(如用戶 ID + 商品 ID)確保用戶不會重復(fù)下單。
  • 優(yōu)化點

    • 緩存熱點數(shù)據(jù):使用 Redis 緩存熱點數(shù)據(jù),減少數(shù)據(jù)庫壓力。
    • 異步處理:異步處理訂單生成,提升系統(tǒng)吞吐量。

4、【Redis】Redis 支持哪些數(shù)據(jù)結(jié)構(gòu)?RDB 和 AOF 備份機制的主要區(qū)別是什么?Redis 的過期鍵刪除策略和內(nèi)存淘汰策略分別有哪些?

  • 支持的數(shù)據(jù)結(jié)構(gòu)

    • 基礎(chǔ)結(jié)構(gòu):String、List、Set、Hash、ZSet(有序集合)。
    • 高級結(jié)構(gòu):Bitmap、HyperLogLog、Geo。
  • RDB 和 AOF 的區(qū)別

    • RDB:定期生成快照文件,恢復(fù)速度快,但可能丟失最后一次快照后的數(shù)據(jù)。
    • AOF:記錄每個寫操作命令,數(shù)據(jù)更完整,但文件體積較大,恢復(fù)速度較慢。
  • 過期鍵刪除策略

    • 惰性刪除:只有在訪問鍵時檢查是否過期,過期則刪除。
    • 定期刪除:定時隨機檢查并刪除過期鍵。
  • 內(nèi)存淘汰策略

    • noeviction:不淘汰數(shù)據(jù),返回錯誤。
    • allkeys-lru:淘汰最近最少使用的鍵。
    • volatile-lru:僅淘汰設(shè)置了過期時間的鍵中最近最少使用的鍵。
    • allkeys-random:隨機淘汰任意鍵。
    • volatile-random:隨機淘汰設(shè)置了過期時間的鍵。
    • volatile-ttl:優(yōu)先淘汰剩余生存時間最短的鍵。

5、【Redis】Redisson 分布式鎖的實現(xiàn)原理是什么?其看門狗機制是如何工作的?

  • 分布式鎖實現(xiàn)原理
    Redisson 使用 Redis 的 SETNX 命令實現(xiàn)分布式鎖,確保同一時間只有一個客戶端能夠獲取鎖。

  • 看門狗機制

    • 工作原理:當客戶端成功獲取鎖后,Redisson 會啟動一個后臺線程(看門狗),定期刷新鎖的過期時間,防止因業(yè)務(wù)邏輯執(zhí)行時間過長而導致鎖提前釋放。
    • 默認行為:看門狗會每隔 1/3 的鎖過期時間自動續(xù)期。

6、【并發(fā)編程】ThreadLocal 的工作原理是什么?如何避免其引發(fā)的內(nèi)存泄漏問題?在線程池中使用 ThreadLocal 時需要注意哪些事項?

  • 工作原理
    每個線程都有一個獨立的 ThreadLocalMap,用于存儲線程本地變量。ThreadLocal 通過 setget 方法操作線程的 ThreadLocalMap,確保變量在線程間隔離。

  • 避免內(nèi)存泄漏

    • 清理變量:在使用完 ThreadLocal 后,調(diào)用 remove 方法清除變量。
    • 避免強引用:避免將大對象存儲在 ThreadLocal 中,減少內(nèi)存占用。
  • 線程池注意事項

    • 顯式清理:線程池中的線程是復(fù)用的,必須在任務(wù)結(jié)束時顯式調(diào)用 remove 方法清理 ThreadLocal。
    • 數(shù)據(jù)污染:如果未清理,ThreadLocal 變量可能會殘留到下一個任務(wù)中,導致數(shù)據(jù)污染。

7、【Java集合】HashMap 是否是線程安全的?請描述其 get 方法的執(zhí)行流程以及底層數(shù)據(jù)結(jié)構(gòu)。在高并發(fā)場景下,HashMap 可能會出現(xiàn)哪些問題?有哪些線程安全的替代方案?它們之間有何區(qū)別?

  • 線程安全性
    HashMap 是非線程安全的,在多線程環(huán)境下可能出現(xiàn)死循環(huán)或數(shù)據(jù)丟失。

  • get 方法流程

    • 哈希計算:根據(jù) key 的哈希值計算數(shù)組索引。
    • 查找節(jié)點:遍歷鏈表或紅黑樹,找到匹配的 key 并返回對應(yīng)的 value。
  • 底層數(shù)據(jù)結(jié)構(gòu)
    JDK 1.8 中,HashMap 底層采用數(shù)組 + 鏈表/紅黑樹的結(jié)構(gòu)。

  • 高并發(fā)問題

    • 死循環(huán):多線程同時擴容時可能導致鏈表成環(huán),造成死循環(huán)。
    • 數(shù)據(jù)覆蓋:多線程同時寫入可能導致數(shù)據(jù)覆蓋或丟失。
  • 線程安全替代方案

    • Hashtable:通過 synchronized 實現(xiàn)線程安全,性能較差。
    • ConcurrentHashMap:基于分段鎖或 CAS 實現(xiàn)高效并發(fā)訪問。
    • Collections.synchronizedMap:對 HashMap 進行包裝,性能較低。
  • 區(qū)別

    • 性能:ConcurrentHashMap 性能最優(yōu),適合高并發(fā)場景。
    • 鎖粒度:HashtablesynchronizedMap 鎖粒度較大,性能較差。

8、【MySQL】MySQL 支持哪些存儲引擎?InnoDB 引擎的索引結(jié)構(gòu)是什么?為什么選擇 B+ 樹作為索引結(jié)構(gòu)?在實際場景中如何合理創(chuàng)建索引?請解釋聯(lián)合索引的作用,并分享實習過程中進行 MySQL 性能優(yōu)化的經(jīng)驗。

  • 支持的存儲引擎

    • InnoDB:支持事務(wù),適合高并發(fā)場景。
    • MyISAM:不支持事務(wù),適合讀多寫少的場景。
    • Memory:數(shù)據(jù)存儲在內(nèi)存中,適合臨時數(shù)據(jù)處理。
  • InnoDB 索引結(jié)構(gòu)

    • 主鍵索引:B+ 樹,葉子節(jié)點存儲數(shù)據(jù)行。
    • 輔助索引:B+ 樹,葉子節(jié)點存儲主鍵值。
  • 選擇 B+ 樹的原因

    • 查詢效率:B+ 樹的高度較低,查詢效率高。
    • 范圍查詢:所有數(shù)據(jù)都在葉子節(jié)點,范圍查詢效率更高。
  • 合理創(chuàng)建索引的原則

    • 查詢頻率:對查詢頻率高的字段創(chuàng)建索引。
    • 更新頻率:避免對更新頻繁的字段創(chuàng)建索引。
    • 最左前綴原則:使用聯(lián)合索引時遵循最左前綴原則。
  • 聯(lián)合索引作用
    聯(lián)合索引可以加速多條件查詢,減少單字段索引的數(shù)量。

  • 性能優(yōu)化經(jīng)驗

    • 添加索引:添加合適的索引,避免全表掃描。
    • 分析 SQL:使用 EXPLAIN 分析 SQL 執(zhí)行計劃。
    • 減少字段:避免 SELECT *,只查詢需要的字段。

9、【JVM】JVM 中堆和棧的主要區(qū)別是什么?對象的生命周期是如何管理的?垃圾回收機制的工作原理是什么?對于未被回收的對象,JVM 會如何處理?

  • 堆和棧的區(qū)別

    • 堆:存放對象實例,所有線程共享,GC 的主要區(qū)域。
    • 棧:存放局部變量和方法調(diào)用,線程私有,隨方法調(diào)用和返回自動分配和釋放。
  • 對象生命周期

    • 創(chuàng)建:通過 new 關(guān)鍵字分配內(nèi)存。
    • 使用:對象被引用并參與業(yè)務(wù)邏輯。
    • 回收:當對象不再被引用時,由 GC 回收。
  • 垃圾回收機制

    • 標記-清除:標記存活對象,清除未標記對象。
    • 復(fù)制算法:將存活對象復(fù)制到另一塊內(nèi)存。
    • 標記-整理:標記存活對象并整理內(nèi)存。
  • 未被回收的對象
    如果對象仍有引用或處于 GC Roots 可達路徑中,JVM 不會回收。

10、【Java基礎(chǔ)】volatile 關(guān)鍵字的作用是什么?其底層實現(xiàn)原理是什么?

  • 作用

    • 可見性:當一個線程修改了 volatile 變量,其他線程可以立即感知。
    • 禁止重排序:確保程序執(zhí)行順序符合預(yù)期。
  • 底層實現(xiàn)原理

    • 內(nèi)存屏障:通過內(nèi)存屏障(Memory Barrier)實現(xiàn):
      • 寫操作后插入 Store 屏障,強制刷新到主內(nèi)存。
      • 讀操作前插入 Load 屏障,強制從主內(nèi)存加載最新值。

?? 關(guān)注【碼間煙火錄】,解鎖秋招通關(guān)秘籍! ??

?? 這里有你想要的一切:

? 超全秋招經(jīng)驗分享

? 高頻八股問題解析

? 最新大廠面經(jīng)合集

? 海量技術(shù)干貨

本文由mdnice多平臺發(fā)布

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容