開發與維運

2020這一年總結出來的Java面試題,常頻面試題大彙總~

面試就是大家身邊總是存在各種各樣的可能,而自身又具備這樣的能力,就忍不住想試一試,尤其是到了年關,是一個好的蓄勢並且認真積累的階段。當然面試套路眾多,但對於技術面試來說,主要是考察一個人的技術能力和溝通能力。不同類型的面試官根據自身的理解問的問題也不盡相同,沒有規律可循。

“面試造火箭,工作擰螺絲”首先咱得能擰,才有造火箭的可能啊,這一年整理很多面試的高頻問點也做了解析,今天在這分享給大家!

博主已將以下這些面試題整理成了一個Java面試手冊,是PDF版的。
需要本資料全部面試題的,可以關注公眾號:有故事的程序員!領取

Java語法基礎
1.面向對象和麵向過程的區別
面向過程

優點: 性能比面向對象高,因為類調用時需要實例化,開銷比較大,比較消耗 資源;比如單片機、嵌入式開發、Linux/Unix
等一般採用面向過程開發,性能是 最重要的因素。 缺點: 沒有面向對象易維護、易複用、易擴展
面向對象

優點: 易維護、易複用、易擴展,由於面向對象有封裝、繼承、多態性的特 性,可以設計出低耦合的系統,使系統更加靈活、更加易於維護 缺點:
性能比面向過程低
Java 語言有哪些特點

  1. 簡單易學;
  2. 面向對象(封裝,繼承,多態);
  3. 平臺無關性( Java 虛擬機實現平臺無關性);
  4. 可靠性;
  5. 安全性;
  6. 支持多線程( C++ 語言沒有內置的多線程機制,因此必須調用操作系統的多線程功能來進行多線程程序設計,而 Java 語言卻提供了多線程支持);
    7.支持網絡編程並且很方便( Java 語言誕生本身就是為簡化網絡編程設計的,因此 Java 語言不僅支持網絡編程而且很方便);
  1. 編譯與解釋並存;
    1

2
3
4
5
6
7
8
關於 JVM JDK 和 JRE 最詳細通俗的解答
JVM
Java 虛擬機(JVM)是運行 Java 字節碼的虛擬機。JVM 有針對不同系統的特定實現(Windows,Linux,macOS),目的是使用相同的字節碼,它們都會給出相同的結果。

什麼是字節碼?採用字節碼的好處是什麼?
在 Java 中,JVM 可以理解的代碼就叫做字節碼(即擴展名為 .class 的文件),它不面向任何特定的處理器,只面向虛擬機。Java 語言通過字節碼的方式,在一定程度上解決了傳統解釋型語言執行效率低的問題,同時又保留了解釋型語言可移植的特點。所以 Java 程序運行時比較高效,而且,由於字節碼並不專對一種特定的機器,因此,Java 程序無須重新編譯便可在多種不同的計算機上運行。

Java 程序從源代碼到運行一般有下面 3 步:
我們需要格外注意的是 .class->機器碼 這一步。在這一步 jvm 類加載器首先加載字節碼文件,然後通過解釋器逐行解釋執行,這種方式的執行速度會相對比較慢。而且,有些方法和代碼塊是經常需要被調用的,也就是所謂的熱點代碼,所以後面引進了 JIT 編譯器,JIT 屬於運行時編譯。當 JIT 編譯器完成第一次編譯後,其會將字節碼對應的機器碼保存下來,下次可以直接使用。而我們知道,機器碼的運行效率肯定是高於 Java 解釋器的。這也解釋了我們為什麼經常會說 Java 是編譯與解釋共存的語言。

HotSpot 採用了惰性評估(Lazy
Evaluation)的做法,根據二八定律,消耗大部分系統資源的只有那一小部分的代碼(熱點代碼),而這也就是 JIT
所需要編譯的部分。JVM 會根據代碼每次被執行的情況收集信息並相應地做出一些優化,因此執行的次數越多,它的速度就越快。JDK 9
引入了一種新的編譯模式AOT(Ahead of Time Compilation),它是直接將字節碼編譯成機器碼,這樣就避免了 JIT
預熱等各方面的開銷。JDK 支持分層編譯和 AOT 協作使用。但是 ,AOT 編譯器的編譯質量是肯定比不上 JIT 編譯器的。

總結:Java 虛擬機(JVM)是運行 Java 字節碼的虛擬機。JVM 有針對不同系統的特定實現(Windows,Linux,macOS),目的是使用相同的字節碼,它們都會給出相同的結果。字節碼和不同系統的 JVM 實現是 Java 語言“一次編譯,隨處可以運行”的關鍵所在。

JDK 和 JRE
JDK 是 Java Development Kit,它是功能齊全的 Java SDK。它擁有 JRE 所擁有的一切,還有編譯器(javac)和工具(如 javadoc 和 jdb)。它能夠創建和編譯程序。

JRE 是 Java 運行時環境。它是運行已編譯 Java 程序所需的所有內容的集合,包括 Java 虛擬機(JVM),Java 類庫,java 命令和其他的一些基礎構件。但是,它不能用於創建新程序。

如果你只是為了運行一下 Java 程序的話,那麼你只需要安裝 JRE 就可以了。如果你需要進行一些 Java 編程方面的工作,那麼你就需要安裝 JDK 了。但是,這不是絕對的。有時,即使您不打算在計算機上進行任何 Java 開發,仍然需要安裝 JDK。例如,如果要使用 JSP 部署 Web 應用程序,那麼從技術上講,您只是在應用程序服務器中運行 Java 程序。那你為什麼需要 JDK 呢?因為應用程序服務器會將 JSP 轉換為 Java servlet,並且需要使用 JDK 來編譯servlet。

Oracle JDK 和 OpenJDK 的對比
可能在看這個問題之前很多人和我一樣並沒有接觸和使用過 OpenJDK 。那麼Oracle 和 OpenJDK 之間是否存在重大差異?下面通過我通過我收集到一些資料對你解答這個被很多人忽視的問題。

對於 Java 7,沒什麼關鍵的地方。OpenJDK 項目主要基於 Sun 捐贈的 HotSpot源代碼。此外,OpenJDK 被選為 Java 7 的參考實現,由 Oracle 工程師維護。
關於 JVM,JDK,JRE 和 OpenJDK 之間的區別,Oracle 博客帖子在 2012 年有一個更詳細的答案:
問:OpenJDK 存儲庫中的源代碼與用於構建 Oracle JDK 的代碼之間有什麼區別?
答:非常接近 - 我們的 Oracle JDK 版本構建過程基於 OpenJDK 7 構建,只添加了幾個部分,例如部署代碼,其中包括 Oracle 的 Java 插件和 Java WebStart的實現,以及一些封閉的源代碼派對組件,如圖形光柵化器,一些開源的第三方組件,如 Rhino,以及一些零碎的東西,如附加文檔或第三方字體。展望未來,我們的目的是開源 Oracle JDK 的所有部分,除了我們考慮商業功能的部分。
總結:

Oracle JDK 版本將每三年發佈一次,而 OpenJDK 版本每三個月發佈一
次;
OpenJDK 是一個參考模型並且是完全開源的,而 Oracle JDK 是
OpenJDK 的一個實現,並不是完全開源的;
Oracle JDK 比 OpenJDK 更穩定。OpenJDK 和 Oracle JDK 的代碼幾乎相同,但 Oracle JDK 有更多的類和一些錯誤修復。因此,如果您想開發企業/商業軟件,我建議您選擇 Oracle JDK,因為它經過了徹底的測試和穩定。某些情況下,有些人提到在使用 OpenJDK 可能會遇到了許多應用程序崩潰的問題,但是,只需切換Oracle JDK 就可以解決問題;
頂級公司正在使用 Oracle JDK,例如 Android Studio,Minecraft 和IntelliJ IDEA 開發工具,其中 Open JDK 不太受歡迎;
在響應性和 JVM 性能方面,Oracle JDK 與 OpenJDK 相比提供了更好的性能;
Oracle JDK 不會為即將發佈的版本提供長期支持,用戶每次都必須通過更新到最新版本獲得支持來獲取最新版本;
Oracle JDK 根據二進制代碼許可協議獲得許可,而 OpenJDK 根據 GPL 許可獲得許可。
JVM
內存模型以及分區,需要詳細到每個區放什麼。
JVM 分為堆區和棧區,還有方法區,初始化的對象放在堆裡面,引用放在棧裡面,class 類信息常量池(static 常量和 static 變量)等放在方法區,new:
1 方法區:主要是存儲類信息,常量池(static 常量和 static 變量),編譯後的代碼(字節碼)等數據
2 堆:初始化的對象,成員變量 (那種非 static 的變量),所有的對象實例和數組都要在堆上分配
3 棧:棧的結構是棧幀組成的,調用一個方法就壓入一幀,幀上面存儲局部變量表,操作數棧,方法出口等信息,局部變量表存放的是 8 大基礎類型加上一個應用類型,所以還是一個指向地址的指針
1 本地方法棧:主要為 Native 方法服務
2 程序計數器:記錄當前線程執行的行號
堆裡面的分區:Eden,survival (from+ to),老年代,各自的特點。
堆裡面分為新生代和老生代(java8 取消了永久代,採用了 Metaspace),新生代包含 Eden+Survivor 區,survivor 區裡面分為 from 和 to 區,內存回收時,如果用的是複製算法,從 from 複製到 to,當經過一次或者多次 GC 之後,存活下來的對象會被移動到老年區,當 JVM 內存不夠用的時候,會觸發 Full GC,清理 JVM 老年區當新生區滿了之後會觸發 YGC,先把存活的對象放到其中一個 Survice區,然後進行垃圾清理。因為如果僅僅清理需要刪除的對象,這樣會導致內存碎片,因此一般會把 Eden 進行完全的清理,然後整理內存。那麼下次 GC 的時候,就會使用下一個 Survive,這樣循環使用。如果有特別大的對象,新生代放不下,就會使用老年代的擔保,直接放到老年代裡面。因為 JVM 認為,一般大對象的存活時間一般比較久遠。
對象創建方法,對象的內存分配,對象的訪問定位。
new 一個對象
GC 的兩種判定方法:
引用計數法:指的是如果某個地方引用了這個對象就+1,如果失效了就-1,當為 0 就會回收但是 JVM 沒有用這種方式,因為無法判定相互循環引用(A 引用 B,B 引用 A)的情況
引用鏈法: 通過一種 GC ROOT 的對象(方法區中靜態變量引用的對象等-static 變量)來判斷,如果有一條鏈能夠到達 GC ROOT 就說明,不能到達 GC ROOT 就說明可以回收
SafePoint 是什麼
比如 GC 的時候必須要等到 Java 線程都進入到 safepoint 的時候 VMThread 才能開始執行 GC,

循環的末尾 (防止大循環的時候一直不進入 safepoint,而其他線程在等待它進入safepoint)
方法返回前
調用方法的 call 之後
拋出異常的位置
GC 的三種收集方法:標記清除、標記整理、複製算法的原理與特點,分別用
在什麼地方,如果讓你優化收集方法,有什麼思路?
先標記,標記完畢之後再清除,效率不高,會產生碎片
複製算法:分為 8:1 的 Eden 區和 survivor 區,就是上面談到的 YGC
標記整理:標記完畢之後,讓所有存活的對象向一端移動

數據庫
請簡潔描述 MySQL 中 InnoDB 支持的四種事務隔離級別名稱,以及逐級之間的區別?
SQL 標準定義的四個隔離級別為:

read uncommited :讀到未提交數據
read committed:髒讀,不可重複讀
repeatable read:可重讀
serializable :串行事物

在 MySQL 中 ENUM 的用法是什麼?
ENUM 是一個字符串對象,用於指定一組預定義的值,並可在創建表時使用。
SQL 語法如下:
Create table size(name ENUM('Smail,‘Medium’,‘Large’);
CHAR 和 VARCHAR 的區別?
CHAR 和 VARCHAR 類型在存儲和檢索方面有所不同。
CHAR 列長度固定為創建表時聲明的長度,長度值範圍是 1 到 255。 當 CHAR 值被存儲時,它們被用空格填充到特定長度,檢索 CHAR 值時需刪除尾隨空格。
列的字符串類型可以是什麼?
字符串類型是:
SET
BLOB
ENUM
CHAR
TEXT
VARCHAR
MySQL 中使用什麼存儲引擎?
存儲引擎稱為表類型,數據使用各種技術存儲在文件中。
技術涉及:
Storage mechanism
Locking levels
Indexing
Capabilities and functions.

MySQL
數據庫三範式是什麼?

第一範式(1NF):字段具有原子性,不可再分。(所有關係型數據庫系統都滿足第一範式數據庫表中的字段都是單一屬性的,不可再分)
第二範式(2NF)是在第一範式(1NF)的基礎上建立起來的,即滿足第二範式(2NF)必須先滿足第一範式(1NF)。要求數據庫表中的每個實例或行必須可以被惟一地區分。通常需要為表加上一個列,以存儲各個實例的惟一標識。這個惟一屬性列被稱為主關鍵字或主鍵。
滿足第三範式(3NF)必須先滿足第二範式(2NF)。簡而言之,第三範式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。 >所以第三範式具有如下特徵: >>1. 每一列只有一個值 >>2. 每一行都能區分。 >>3. 每一個表都不包含其他表已經包含的非主關鍵字信息。
有哪些數據庫優化方面的經驗?
用 PreparedStatement, 一般來說比 Statement 性能高:一個 sql發給服務器去執行,涉及步驟:語法檢查、語義分析, 編譯,緩存。
有外鍵約束會影響插入和刪除性能,如果程序能夠保證數據的完整性,那在設計數據庫時就去掉外鍵。
表中允許適當冗餘,譬如,主題帖的回覆數量和最後回覆時間等
UNION ALL 要比 UNION 快很多,所以,如果可以確認合併的兩個結果集中不包含重複數據且不需要排序時的話,那麼就使用 UNIONALL。 >>UNION 和 UNION ALL 關鍵字都是將兩個結果集合併為一個,但這兩者從使用和效率上來說都有所不同。 >1. 對重複結果的處理:UNION 在進行錶鏈接後會篩選掉重複的記錄,Union All 不會去除重複記錄。 >2. 對排序的處理:Union 將會按照字段的順序進行排序;UNION ALL 只是簡單的將兩個結果合併後就返回。
請簡述常用的索引有哪些種類?
1.普通索引: 即針對數據庫表創建索引
2.索引: 與普通索引類似,不同的就是:MySQL 數據庫索引列的值必須唯一,但允許有空值
3.主鍵索引: 它是一種特殊的唯一索引,不允許有空值。一般是在建表的時候同時創建主鍵索引
4.組合索引: 為了進一步榨取 MySQL 的效率,就要考慮建立組合索引。即將數據庫表中的多個字段聯合起來作為一個組合索引。
以及在 mysql 數據庫中索引的工作機制是什麼?
數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現通常使用 B 樹及其變種 B+樹
MySQL 的基礎操作命令:
1.MySQL 是否處於運行狀態:Debian 上運行命令 service mysqlstatus,在 RedHat 上運行命令 service mysqld status
2.開啟或停止 MySQL 服務 :運行命令 service mysqld start 開啟服務;運行命令 service mysqld stop 停止服務
3.Shell 登入 MySQL: 運行命令 mysql -u root -p
4.列出所有數據庫:運行命令 show databases;
5.切換到某個數據庫並在上面工作:運行命令 use databasename; 進入名為 databasename 的數據庫
6.列出某個數據庫內所有表: show tables;
7.獲取表內所有 Field 對象的名稱和類型 :describe table_name;
mysql 的複製原理以及流程。
Mysql 內建的複製功能是構建大型,高性能應用程序的基礎。將 Mysql 的數據分佈到多個系統上去,這種分佈的機制,是通過將 Mysql 的某一臺主機的數據複製到其它主機(slaves)上,並重新執行一遍來實現的。 * 複製過程中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。主服務器將更新寫入二進制日誌文件,並維護文件的一個索引以跟蹤日誌循環。這些日誌可以記錄發送到從服務器的更新。 當一個從服務器連接主服務器時,它通知主服務器在日誌中讀取的最後一次成功更新的位置。從服務器接收從那時起發生的任何更新,然後封鎖並等待主服務器通知新的更新。
過程如下:
1.主服務器把更新記錄到二進制日誌文件中。
2.從服務器把主服務器的二進制日誌拷貝到自己的中繼日誌(replay log)中。
3.從服務器重做中繼日誌中的時間,把更新應用到自己的數據庫上。
Redis
什麼是 Redis?簡述它的優缺點?
Redis 的全稱是:Remote Dictionary.Server,本質上是一個 Key-Value 類型的內存數據庫,很像memcached,整個數據庫統統加載在內存當中進行操作,定期通過異步操作把數據庫數據 flush 到硬盤上進行保存。
因為是純內存操作,Redis 的性能非常出色,每秒可以處理超過 10 萬次讀寫操作,是已知性能最快的Key-Value DB。
Redis 的出色之處不僅僅是性能,Redis 最大的魅力是支持保存多種數據結構,此外單個 value 的最大限制是 1GB,不像 memcached 只能保存 1MB 的數據,因此 Redis 可以用來實現很多有用的功能。
比方說用他的 List 來做 FIFO 雙向鏈表,實現一個輕量級的高性 能消息隊列服務,用他的 Set 可以做高性能的 tag 系統等等。
另外 Redis 也可以對存入的 Key-Value 設置 expire 時間,因此也可以被當作一 個功能加強版的memcached 來用。 Redis 的主要缺點是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此 Redis 適合的場景主要侷限在較小數據量的高性能操作和運算上。
Redis 與 memcached 相比有哪些優勢?
1.memcached 所有的值均是簡單的字符串,redis 作為其替代者,支持更為豐富的數據類型
2.redis 的速度比 memcached 快很多 redis 的速度比 memcached 快很多
3.redis 可以持久化其數據 redis 可以持久化其數據
Redis 支持哪幾種數據類型?
String、List、Set、Sorted Set、hashes
Redis 主要消耗什麼物理資源?
內存。
Redis 有哪幾種數據淘汰策略?
1.noeviction:返回錯誤當內存限制達到,並且客戶端嘗試執行會讓更多內存被使用的命令。
2.allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新添加的數據有空間存放。
3.volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限於在過期集合的鍵,使得新添加的數據有空間存放。
4.allkeys-random: 回收隨機的鍵使得新添加的數據有空間存放。
5.volatile-random: 回收隨機的鍵使得新添加的數據有空間存放,但僅限於在過期集合的鍵。
6.volatile-ttl: 回收在過期集合的鍵,並且優先回收存活時間(TTL)較短的鍵,使得新添加的數據有空間
存放。
Redis 官方為什麼不提供 Windows 版本?
因為目前 Linux 版本已經相當穩定,而且用戶量很大,無需開發 windows 版本,反而會帶來兼容性等問題。
一個字符串類型的值能存儲最大容量是多少?512M
為什麼 Redis 需要把所有數據放到內存中?
Redis 為了達到最快的讀寫速度將數據都讀到內存中,並通過異步的方式將數據寫入磁盤。
所以 redis 具有快速和數據持久化的特徵,如果不將數據放在內存中,磁盤 I/O 速度為嚴重影響 redis 的
性能。
在內存越來越便宜的今天,redis 將會越來越受歡迎, 如果設置了最大使用的內存,則數據已有記錄數達到內存限值後不能繼續插入新值。
Redis 集群方案應該怎麼做?都有哪些方案?
1.codis
2.目前用的最多的集群方案,基本和 twemproxy 一致的效果,但它支持在節點數量改變情況下,舊節點數據可恢復到新 hash 節點。
redis cluster3.0 自帶的集群,特點在於他的分佈式算法不是一致性 hash,而是 hash 槽的概念,以及自身支持節點設置從節點。具體看官方文檔介紹。
3.在業務代碼層實現,起幾個毫無關聯的 redis 實例,在代碼層,對 key 進行 hash 計算,然後去對應的redis 實例操作數據。這種方式對 hash 層代碼要求比較高,考慮部分包括,節點失效後的替代算法方案,數據震盪後的自動腳本恢復,實例的監控,等等。

Spring
什麼是 spring?
Spring 是個 java 企業級應用的開源開發框架。Spring 主要用來開發 Java 應用, 但是有些擴展是針對構建 J2EE 平臺的 web 應用。Spring 框架目標是簡化 Java 企業級應用開發,並通過 POJO 為基礎的編程模型促進良好的編程習慣。
使用 Spring 框架的好處是什麼?
1 輕量:Spring 是輕量的,基本的版本大約 2MB。
2 控制反轉:Spring 通過控制反轉實現了鬆散耦合,對象們給出它們的依 賴,而不是創建或查找依賴的對象們。
3 面向切面的編程(AOP):Spring 支持面向切面的編程,並且把應用業務 邏輯和系統服務分開。
4 容器:Spring 包含並管理應用中對象的生命週期和配置。
5 MVC 框架:Spring 的 WEB 框架是個精心設計的框架,是 Web 框架的 一個很好的替代品。
6 事務管理:Spring 提供一個持續的事務管理接口,可以擴展到上至本地 事務下至全局事務(JTA)。
7 異常處理:Spring提供方便的 API 把具體技術相關的異常(比如由JDBC, HibernateorJDO 拋出的)轉化為一致的 unchecked 異常。
Spring 由哪些模塊組成?
以下是 Spring 框架的基本模塊:
 Coremodule
 Beanmodule
 Contextmodule
 ExpressionLanguagemodule
 JDBCmodule  ORMmodule
 OXMmodule  JavaMessagingService(JMS)module
 Transactionmodule
 Webmodule
 Web-Servletmodule
 Web-Strutsmodule
 Web-Portletmodule
核心容器(應用上下文)模塊。
這是基本的 Spring 模塊,提供 spring 框架的基礎功能,BeanFactory 是任何 以 spring 為基礎的應用的核心。Spring 框架建立在此模塊之上,它使 Spring 成為一個容器。
BeanFactory–BeanFactory 實現舉例。
Bean 工廠是工廠模式的一個實現,提供了控制反轉功能,用來把應用的配置和 依賴從正真的應用代碼中分離。 最常用的 BeanFactory 實現是 XmlBeanFactory 類。
XMLBeanFactory
最常用的就是 org.springframework.beans.factory.xml.XmlBeanFactory,它 根據 XML 文件中的定義加載 beans。該容器從 XML 文件讀取配置元數據並用 它去創建一個完全配置的系統或應用。
解釋 AOP 模塊
AOP 模塊用於發給我們的 Spring 應用做面向切面的開發,很多支持由 AOP 聯 盟提供,這樣就確保了 Spring 和其他 AOP 框架的共通性。這個模塊將元數據 編程引入 Spring。

SpringBoot
什麼是 Spring Boot?
多年來,隨著新功能的增加,spring 變得越來越複雜。只需訪問 https://spring.io/projects頁面,我們就會看到可以在我們的應用程序中使用的所有 Spring 項目的不同功能。如果必須啟動一個新的 Spring 項目,我們必須添加構建路徑或添加 Maven 依賴關係,配置應用程序服務器,添加 spring 配置。因此,開始一個新的 spring 項目需要很多努力,因為我們現在必須從頭開始做所有事情。
Spring Boot 是解決這個問題的方法。Spring Boot 已經建立在現有 spring 框架之上。使用spring 啟動,我們避免了之前我們必須做的所有樣板代碼和配置。因此,Spring Boot 可以幫助我們以最少的工作量,更加健壯地使用現有的 Spring 功能。
Spring Boot 有哪些優點?
Spring Boot 的優點有:
1.減少開發,測試時間和努力。
2.使用 JavaConfig 有助於避免使用 XML。
3.避免大量的 Maven 導入和各種版本衝突。
4.提供意見發展方法。
5.通過提供默認值快速開始開發。
沒有單獨的 Web 服務器需要。這意味著你不再需要啟動 Tomcat,Glassfish 或其他任何東
西。
需要更少的配置 因為沒有 web.xml 文件。只需添加用@ Configuration 註釋的類,然後添加
用@Bean 註釋的方法,Spring 將自動加載對象並像以前一樣對其進行管理。您甚至可以將
@Autowired 添加到 bean 方法中,以使 Spring 自動裝入需要的依賴關係中。
基於環境的配置 使用這些屬性,您可以將您正在使用的環境傳遞到應用程序:-Dspring.profiles.active = {enviornment}。在加載主應用程序屬性文件後,Spring 將在(application{environment} .properties)中加載後續的應用程序屬性文件。

什麼是 JavaConfig?
Spring JavaConfig 是 Spring 社區的產品,它提供了配置 Spring IoC 容器的純 Java 方法。因此它有助於避免使用 XML 配置。使用 JavaConfig 的優點在於:
面向對象的配置。由於配置被定義為 JavaConfig 中的類,因此用戶可以充分利用 Java 中的面向對象功能。一個配置類可以繼承另一個,重寫它的@Bean 方法等。
減少或消除 XML 配置。基於依賴注入原則的外化配置的好處已被證明。但是,許多開發人員不希望在 XML 和 Java 之間來回切換。JavaConfig 為開發人員提供了一種純 Java 方法來配置與 XML 配置概念相似的 Spring 容器。從技術角度來講,只使用 JavaConfig 配置類來配置容器是可行的,但實際上很多人認為將 JavaConfig 與 XML 混合匹配是理想的。
類型安全和重構友好。JavaConfig 提供了一種類型安全的方法來配置 Spring 容器。由於Java 5.0 對泛型的支持,現在可以按類型而不是按名稱檢索 bean,不需要任何強制轉換或基於字符串的查找。

如何重新加載 Spring Boot 上的更改,而無需重新啟動服務器?
這可以使用 DEV 工具來實現。通過這種依賴關係,您可以節省任何更改,嵌入式 tomcat將重新啟動。Spring Boot 有一個開發工具(DevTools)模塊,它有助於提高開發人員的生產力。Java 開發人員面臨的一個主要挑戰是將文件更改自動部署到服務器並自動重啟服務器。
開發人員可以重新加載 Spring Boot 上的更改,而無需重新啟動服務器。這將消除每次手動部署更改的需要。Spring Boot 在發佈它的第一個版本時沒有這個功能。這是開發人員最需要的功能。DevTools 模塊完全滿足開發人員的需求。該模塊將在生產環境中被禁用。它還提供 H2 數據庫控制檯以更好地測試應用程序。
org.springframework.boot spring-boot-devtools true

Spring Boot 中的監視器是什麼?
Spring boot actuator 是 spring 啟動框架中的重要功能之一。Spring boot 監視器可幫助您訪問生產環境中正在運行的應用程序的當前狀態。有幾個指標必須在生產環境中進行檢查和監控。即使一些外部應用程序可能正在使用這些服務來向相關人員觸發警報消息。監視器模塊公開了一組可直接作為 HTTP URL 訪問的 REST 端點來檢查狀態。

kafka
Kafka 的設計時什麼樣的呢?
Kafka 將消息以 topic 為單位進行歸納
將向 Kafka topic 發佈消息的程序成為 producers.
將預訂 topics 並消費消息的程序成為 consumer.
Kafka 以集群的方式運行,可以由一個或多個服務組成,每個服務叫做一個 broker.
producers 通過網絡將消息發送到 Kafka 集群,集群向消費者提供消息
數據傳輸的事物定義有哪三種?
數據傳輸的事務定義通常有以下三種級別:
(1)最多一次: 消息不會被重複發送,最多被傳輸一次,但也有可能一次不傳輸
(2)最少一次: 消息不會被漏發送,最少被傳輸一次,但也有可能被重複傳輸.
(3)精確的一次(Exactly once): 不會漏傳輸也不會重複傳輸,每個消息都傳輸被一次而且僅僅被傳輸一次,這是大家所期望的
Kafka 判斷一個節點是否還活著有那兩個條件?
(1)節點必須可以維護和 ZooKeeper 的連接,Zookeeper 通過心跳機制檢查每個節點的連接
(2)如果節點是個 follower,他必須能及時的同步 leader 的寫操作,延時不能太久
producer 是否直接將數據發送到 broker 的 leader(主節點)?
producer 直接將數據發送到 broker 的 leader(主節點),不需要在多個節點進行分發,為了
幫助 producer 做到這點,所有的 Kafka 節點都可以及時的告知:哪些節點是活動的,目標
topic 目標分區的 leader 在哪。這樣 producer 就可以直接將消息發送到目的地了
Kafa consumer 是否可以消費指定分區消息?
Kafa consumer 消費消息時,向 broker 發出"fetch"請求去消費特定分區的消息,consumer指定消息在日誌中的偏移量(offset),就可以消費從這個位置開始的消息,customer 擁有了 offset 的控制權,可以向後回滾去重新消費之前的消息,這是很有意義的
Kafka 消息是採用 Pull 模式,還是 Push 模式?
Kafka 最初考慮的問題是,customer 應該從 brokes 拉取消息還是 brokers 將消息推送到consumer,也就是 pull 還 push。在這方面,Kafka 遵循了一種大部分消息系統共同的傳統的設計:producer 將消息推送到 broker,consumer 從 broker 拉取消息

一些消息系統比如 Scribe 和 Apache Flume 採用了 push 模式,將消息推送到下游的consumer。這樣做有好處也有壞處:由 broker 決定消息推送的速率,對於不同消費速率的consumer 就不太好處理了。消息系統都致力於讓 consumer 以最大的速率最快速的消費消息,但不幸的是,push 模式下,當 broker 推送的速率遠大於 consumer 消費的速率時,consumer 恐怕就要崩潰了。最終 Kafka 還是選取了傳統的 pull 模式

Pull 模式的另外一個好處是 consumer 可以自主決定是否批量的從 broker 拉取數據。Push模式必須在不知道下游
consumer 消費能力和消費策略的情況下決定是立即推送每條消息還是緩存之後批量推送。如果為了避免 consumer
崩潰而採用較低的推送速率,將可能導致一次只推送較少的消息而造成浪費。Pull 模式下,consumer
就可以根據自己的消費能力去決定這些策略 Pull 有個缺點是,如果 broker 沒有可供消費的消息,將導致 consumer
不斷在循環中輪詢,直到新消息到 t 達。為了避免這點,Kafka 有個參數可以讓 consumer
阻塞知道新消息到達(當然也可以阻塞知道消息的數量達到某個特定的量這樣就可以批量發

歡迎工作一到五年的 Java 工程師朋友們加入 Java 進階架構學習交流:952124565,群內提供免費的
Java 架構學習資料(裡面有高可用、高併發、高性能及分佈式、Jvm 性能調優、Spring 源碼,
MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx 等多個知識點的架構資
料)合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶
惰!趁年輕,使勁拼,給未來的自己一個交代!

需要本資料全部面試題的,可以關注公眾號:有故事的程序員!領取
這篇文章裡面包括的面試題都有,還包括了高可用、高併發、高性能及分佈式、Jvm 性能調優、Spring 源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx 等多個知識點的架構資料)都可以來領取!合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!

Leave a Reply

Your email address will not be published. Required fields are marked *