簡歷改成這樣後,連續OC兩個。

大家好,我是二哥呀。

在牛客上看到,一個民辦三本的同學把自己的簡歷改成了下面這樣後,連續 OC 兩個,甚至一個月前投遞的簡歷 HR 也開始重新聯繫了。

圖片來源:牛客茅不易

不管大家信不信,反正我信了。這樣的描述至少看起來比那些光禿禿的,充滿着自卑的強多了。

  • 技術吊打 985
  • 有實習經歷
  • 懂分佈式
  • 超級抗壓
  • 不背八股只擼源碼

這是多少 HR 喜歡看到的一副“自信爆棚”的 diao 樣子,反正我就喜歡這樣的,與其自卑獲取別人的同情,不如自信贏得別人的青睞

形成鮮明對比的就是,一位球友,學歷還很不錯,可能是被暑期實習拷打得失去自信了,連續失眠,學不進去,處於一種焦慮、懷疑、煎熬的狀態,我好想安慰他,但這個世界上,沒有人會因爲同情而給你發 offer 的呀。

球友被暑期實習拷打麻了

emo 了,打一把遊戲、玩一次籃球、看一場電影、聚一次餐,歇斯底里地嗨一次,把負面的情緒全部排解掉,然後開始新一輪的學習。

無論是暑期實習還是即將到來的秋招提前批,準備的東西不外乎這幾樣,簡歷、算法、八股、項目,還有什麼,沒有了吧?

簡歷是爲了獲取筆試和麪試邀請,算法是爲了過筆試,八股是爲了應對大多數的面試題,除此之外,就是圍繞着項目展開的提問,內核其實還是一些八股,只要自己能夠串聯業務場景和面試官有來有回就好了。

這次我們就以《二哥的 Java 面試指南-美團面經》同學 18 爲例, 來看看大廠的面試官都喜歡問哪些問題,好做到知彼知己百戰不殆~

讓天下所有的面渣都能逆襲 😁

能看得出,仍然是圍繞着二哥一直強調的 Java 後端四大件展開,所以大家在學習的時候一定要有的放矢,效率就會高很多。

  • 1、二哥的 Linux 速查備忘手冊.pdf 下載
  • 2、三分惡面渣逆襲在線版:https://javabetter.cn/sidebar/sanfene/nixi.html

美團面經(經得起拷打)

mysql一條數據的查詢過程

二哥的 Java 進階之路:SQL 執行

第一步,客戶端發送 SQL 查詢語句到 MySQL 服務器。

第二步,MySQL 服務器的連接器開始處理這個請求,跟客戶端建立連接、獲取權限、管理連接。

第三步(MySQL 8.0 以後已經幹掉了),連接建立後,MySQL 服務器的查詢緩存組件會檢查是否有緩存的查詢結果。如果有,直接返回給客戶端;如果沒有,進入下一步

第三步,解析器開始對 SQL 語句進行解析,檢查語句是否符合 SQL 語法規則,確保引用的數據庫、表和列都存在,並處理 SQL 語句中的名稱解析和權限驗證。

第四步,優化器負責確定 SQL 語句的執行計劃,這包括選擇使用哪些索引,以及決定表之間的連接順序等。優化器會嘗試找出最高效的方式來執行查詢。

第五步,執行器會調用存儲引擎的 API 來進行數據的讀寫。

第六步,MySQL 的存儲引擎是插件式的,不同的存儲引擎在細節上面有很大不同。例如,InnoDB 是支持事務的,而 MyISAM 是不支持的。之後,會將執行結果返回給客戶端

第七步,客戶端接收到查詢結果,完成這次查詢請求。

數據的存儲形式(行頁區段)

MySQL 是以表的形式存儲數據的,而表空間的結構則由段、區、頁、行組成。

不要迷戀發哥:段、區、頁、行

①、段(Segment):表空間由多個段組成,常見的段有數據段、索引段、回滾段等。

創建索引時會創建兩個段,數據段和索引段,數據段用來存儲葉子階段中的數據;索引段用來存儲非葉子節點的數據。

回滾段包含了事務執行過程中用於數據回滾的舊數據。

②、區(Extent):段由一個或多個區組成,區是一組連續的頁,通常包含 64 個連續的頁,也就是 1M 的數據。

使用區而非單獨的頁進行數據分配可以優化磁盤操作,減少磁盤尋道時間,特別是在大量數據進行讀寫時。

③、頁(Page):頁是 InnoDB 存儲數據的基本單元,標準大小爲 16 KB,索引樹上的一個節點就是一個頁。

也就意味着數據庫每次讀寫都是以 16 KB 爲單位的,一次最少從磁盤中讀取 16KB 的數據到內存,一次最少寫入 16KB 的數據到磁盤。

④、行(Row):InnoDB 採用行存儲方式,意味着數據按照行進行組織和管理,行數據可能有多個格式,比如說 COMPACT、REDUNDANT、DYNAMIC 等。

MySQL 8.0 默認的行格式是 DYNAMIC,由COMPACT 演變而來,意味着這些數據如果超過了頁內聯存儲的限制,則會被存儲在溢出頁中。

可以通過 show table status like '%article%' 查看行格式。

二哥的 Java 進階之路:行格式

一張表最多存多少數據(我答得2kw,根據b+樹的三層高度計算)

三分惡面渣逆襲:B+樹存儲數據條數

可以通過 B+樹來進行推算。

假如我們的主鍵 ID 是 bigint 類型,長度爲 8 個字節。指針大小在 InnoDB 源碼中設置爲 6 字節,這樣一共 14 字節。所以非葉子節點(一頁)可以存儲 16384/14=1170 個這樣的單元(鍵值+指針)。

一個指針指向一個存放記錄的頁,一頁可以放 16 條數據,樹深度爲 2 的時候,可以存放 1170*16=18720 條數據。

同理,樹深度爲 3 的時候,可以存儲的數據爲 1170*1170*16=21902400條記錄。

理論上,在 InnoDB 存儲引擎中,B+樹的高度一般爲 2-4 層,就可以滿足千萬級數據的存儲。查找數據的時候,一次頁的查找代表一次 IO,當我們通過主鍵索引查詢的時候,最多只需要 2-4 次 IO 就可以了。

反射及其應用場景

創建一個對象是通過 new 關鍵字來實現的,比如:

Person person = new Person();

Person 類的信息在編譯時就確定了,那假如在編譯期無法確定類的信息,但又想在運行時獲取類的信息、創建類的實例、調用類的方法,這時候就要用到反射。

反射功能主要通過 java.lang.Class 類及 java.lang.reflect 包中的類如 Method, Field, Constructor 等來實現。

三分惡面渣逆襲:Java反射相關類

反射有哪些應用場景?

一般我們平時都是在在寫業務代碼,很少會接觸到直接使用反射機制的場景。

但是,這並不代表反射沒有用。相反,正是因爲反射,你才能這麼輕鬆地使用各種框架。像 Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射機制。

像 Spring 裏的很多 註解 ,它真正的功能實現就是利用反射。

就像爲什麼我們使用 Spring 的時候 ,一個@Component註解就聲明瞭一個類爲 Spring Bean 呢?爲什麼通過一個 @Value註解就讀取到配置文件中的值呢?究竟是怎麼起作用的呢?

這些都是因爲我們可以基於反射操作類,然後獲取到類/屬性/方法/方法的參數上的註解,註解這裏就有兩個作用,一是標記,我們對註解標記的類/屬性/方法進行對應的處理;二是註解本身有一些信息,可以參與到處理的邏輯中。

threadlocal及其應用場景

ThreadLocal 是 Java 中提供的一種用於實現線程局部變量的工具類。它允許每個線程都擁有自己的獨立副本,從而實現線程隔離,用於解決多線程中共享對象的線程安全問題。

三分惡面渣逆襲:ThreadLocal線程副本

類加載過程

類加載過程有:載入、驗證、準備、解析、初始化。這 5 個階段一般是順序發生的,但在動態綁定的情況下,解析階段會發生在初始化階段之後。

載入過程中,JVM 需要做三件事情:

三分惡面渣逆襲:載入
  • 1)通過一個類的全限定名來獲取定義此類的二進制字節流。
  • 2)將這個字節流所代表的靜態存儲結構轉化爲方法區的運行時數據結構。
  • 3)在內存中生成一個代表這個類的 java.lang.Class 對象,作爲方法區這個類的各種數據的訪問入口。

載入階段結束後,JVM 外部的二進制字節流就按照虛擬機所設定的格式存儲在方法區(邏輯概念)中了,方法區中的數據存儲格式完全由虛擬機自行實現。

JVM 會在驗證階段對二進制字節流進行校驗,只有符合 JVM 字節碼規範的才能被 JVM 正確執行。

JVM 會在準備階段對類變量(也稱爲靜態變量,static 關鍵字修飾的變量)分配內存並初始化,初始化爲數據類型的默認值,如 0、0L、null、false 等。

解析階段是虛擬機將常量池內的符號引用替換爲直接引用的過程。解析動作主要針對類或接口、字段、類方法、接口方法、成員方法等。

初始化階段是類加載過程的最後一步。在準備階段,類變量已經被賦過默認初始值了,而在初始化階段,類變量將被賦值爲代碼期望賦的值。

換句話說,初始化階段是執行類的構造方法(javap 中看到的 () 方法)的過程。

redis持久化

Redis 支持兩種主要的持久化方式:RDB(Redis DataBase)持久化和 AOF(Append Only File)持久化。這兩種方式可以單獨使用,也可以同時使用。

三分惡面渣逆襲:Redis持久化的兩種方式

什麼時候用rdb 什麼時候用aof

如果需要儘可能減少數據丟失,AOF 是更好的選擇。尤其是在頻繁寫入的環境下,設置 AOF 每秒同步可以最大限度減少數據丟失。

如果性能是首要考慮,RDB 可能更適合。RDB 的快照生成通常對性能影響較小,並且數據恢復速度快。

如果系統需要經常重啓,並且希望系統重啓後快速恢復,RDB 可能是更好的選擇。雖然 AOF 也提供了良好的恢復能力,但重寫 AOF 文件可能會比較慢。

在許多生產環境中,同時啓用 RDB 和 AOF 被認爲是最佳實踐:

  • 使用 RDB 進行快照備份。
  • 使用 AOF 保證崩潰後的最大數據完整性。

如何設置持久化模式

可以通過編輯 Redis 的配置文件 redis.conf 來進行設置,或者在運行時通過 Redis 命令行動態調整。

RDB 持久化通過在配置文件中設置快照(snapshotting)規則來啓用。這些規則定義了在多少秒內如果有多少個鍵被修改,則自動執行一次持久化操作。

save 900 1      # 如果至少有1個鍵被修改,900秒後自動保存一次
save 300 10     # 如果至少有10個鍵被修改,300秒後自動保存一次
save 60 10000   # 如果至少有10000個鍵被修改,60秒後自動保存一次

AOF 持久化是通過在配置文件中設置 appendonly 參數爲 yes 來啓用的:

appendonly yes

此外,還可以配置 AOF 文件的寫入頻率,這是通過 appendfsync 設置的:

appendfsync always    # 每次寫入數據都同步,保證數據不丟失,但性能較低
appendfsync everysec  # 每秒同步一次,折衷方案
appendfsync no        # 由操作系統決定何時同步,性能最好,但數據安全性最低

爲了優化 AOF 文件的大小,Redis 允許自動或手動重寫 AOF 文件。可以在配置文件中設置重寫的觸發條件:

auto-aof-rewrite-percentage 100  # 增長到原大小的100%時觸發重寫
auto-aof-rewrite-min-size 64mb   # AOF 文件至少達到64MB時才考慮重寫

手動執行 AOF 重寫的命令是:

redis-cli bgrewriteaof

如果決定同時使用 RDB 和 AOF,可以在配置文件中同時啓用兩者。

save 900 1
appendonly yes

還可以在運行時動態更改:

redis-cli config set save "900 1 300 10 60 10000"
redis-cli config set appendonly yes
redis-cli config set appendfsync everysec

參考鏈接

  • 三分惡的面渣逆襲:https://javabetter.cn/sidebar/sanfene/nixi.html
  • 二哥的 Java 進階之路:https://javabetter.cn

ending

一個人可以走得很快,但一羣人才能走得更遠。二哥的編程星球已經有 5300 多名球友加入了,如果你也需要一個良好的學習環境,戳鏈接 🔗 加入我們吧。這是一個編程學習指南 + Java 項目實戰 + LeetCode 刷題的私密圈子,你可以閱讀星球專欄、向二哥提問、幫你制定學習計劃、和球友一起打卡成長。

兩個置頂帖「球友必看」和「知識圖譜」裏已經沉澱了非常多優質的學習資源,相信能幫助你走的更快、更穩、更遠

  • 二哥的 Java 面試指南發佈了 ✌️
  • 二哥的實戰項目技術派上線啦 ✌️
  • 24 屆春招急救箱更新辣 ✌️

歡迎點擊左下角閱讀原文瞭解二哥的編程星球,這可能是你學習求職路上最有含金量的一次點擊。

最後,把二哥的座右銘送給大家:沒有什麼使我停留——除了目的,縱然岸旁有玫瑰、有綠蔭、有寧靜的港灣,我是不繫之舟。共勉 💪。