下面是針對一系列模擬面試后的情況進行面試題的總結和梳理,希望對大家有所幫助:
1、SpringBoot的啟動類?
@SpringBootApplication{@SpringBootConfiguration(標識配置類)、@EnableAutoConfiguration(自動配置基于@import)、@ComponentScan (掃描路徑設定)}
啟動流程:
第一部分進行SpringApplication的初始化模塊,配置一些基本的環境變數、資源、構造器、監聽器,第二部分實作了應用具體的啟動方案,包括啟動流程的監聽模塊、加載配置環境模塊、及核心的創建背景關系環境模塊,第三部分是自動化配置模塊,該模塊作為springboot自動配置核心
<span style="background-color:#f8f8f8"><span style="color:#333333"> @SpringBootApplication
public class SpringTestApplication {
public static void main(String[] args)
SpringApplication.run(SpringTestApplication.class, args);
}
}</span></span>
SpringTestApplication類執行main方法,main方法呼叫SpringApplication的run方法,
run方法干了兩件事:
創建SpringApplication物件
利用創建好的SpringApplication物件呼叫run方法
2、資料庫的底層結構是?是如何實作存盤的?
B+樹;
3、Mybatis是如何防止Sql注入的?
#{}是經過預編譯的,是安全的;${}是未經過預編譯的,僅僅是取變數的值,是非安全的,存在SQL注入
4、HashMap的容量長度? 擴充機制? 容量必須是2的冪
默認值 16;當我們不斷的向HashMap中添加元素時,它會判斷HashMap當前的容量值(當前元素的個數)是否超過了它的臨界值(在沒有指定其初始化大小時,默認16*0.75=12),如果添加的元素個數超過了臨界值,它就會開始進行擴容,
5、多執行緒的實作方式
繼承Thread類創建執行緒、實作Runnable介面創建執行緒、實作Callable介面通過FutureTask包裝器來創建Thread執行緒
6、Redis Sentinel(哨兵機制)是怎么作業的?重點描述一下故障轉移的程序?
1)每個Sentinel以每秒鐘一次的頻率向它所知的Master,Slave以及其他 Sentinel 實體發送一個 PING 命令,
2)如果一個實體(instance)距離最后一次有效回復 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個實體會被當前 Sentinel 標記為主觀下線,
3)如果一個Master被標記為主觀下線,則正在監視這個Master的所有 Sentinel 要以每秒一次的頻率確認Master的確進入了主觀下線狀態,
4)當有足夠數量的 Sentinel(大于等于組態檔指定的值)在指定的時間范圍內確認Master的確進入了主觀下線狀態, 則Master會被標記為客觀下線 ,
5)當Master被 Sentinel 標記為客觀下線時,Sentinel 向下線的 Master 的所有 Slave 發送 INFO 命令的頻率會從 10 秒一次改為每秒一次 (在一般情況下, 每個 Sentinel 會以每 10 秒一次的頻率向它已知的所有Master,Slave發送 INFO 命令 ),
6)若沒有足夠數量的 Sentinel 同意 Master 已經下線, Master 的客觀下線狀態就會變成主觀下線,若 Master 重新向 Sentinel 的 PING 命令回傳有效回復, Master 的主觀下線狀態就會被移除,
7)sentinel節點會與其他sentinel節點進行“溝通”,投票選舉一個sentinel節點進行故障處理,在從節點中選取一個主節點,其他從節點掛載到新的主節點上自動復制新主節點的資料,
7、Redis的持久化機制?
AOF和RDB;
AOF:記錄每次寫請求的命令,以追加的方式在檔案尾部追加,直接在尾部追加,效率比較高, 對于作業系統來說,不是每次寫都直接寫到磁盤,作業系統自己會有一層cache,redis寫磁盤的資料會先快取在os cache里,redis每隔1秒呼叫一次作業系統的fsync操作,強制將os cache中的資料刷入AOF檔案中,
當redis重啟的時候,就把AOF中記錄的命令重新執行一遍就可以了,但是如果檔案很大的話,執行會耗費較多的時間,對于資料恢復來說耗時會多一點,
RDB:是快照檔案,每隔一定時間將redis記憶體中的資料生成一份完整的RDB快照檔案,當redis重啟的時候直接加載資料即可,同樣的資料比AOF恢復的要快,
RDB的優點:第一點就是他會生成多個資料檔案,每個資料檔案都代表了某一時刻redis中的資料,非常適合做冷備, 第二點,RDB持久化機制對redis對外提供的讀寫服務影響非常小,可以讓redis保持高性能,因為redis主行程只需要fork一個子行程,讓子行程執行磁盤IO操作來進行RDB持久化即可, 第三點,相對于AOF持久化機制來說,直接基于RDB資料檔案來重啟和恢復redis行程,更加快速,
AOF,存放的指令日志,做資料恢復的時候,其實是要回放和執行所有的指令日志,來恢復出來記憶體中的所有資料的,
RDB,就是一份資料檔案,恢復的時候,直接加載到記憶體中即可,
RBD的缺點:
1)故障時可能資料丟失的比AOF要多, 一般來說,RDB資料快照檔案,都是每隔5分鐘或者更長時間生成一次,這個時候一旦redis行程宕機,那么會丟失最近5分鐘的資料,
這個問題,也是rdb最大的缺點,就是不適合做第一優先的恢復方案,如果你依賴RDB做第一優先恢復方案,會導致資料丟失的比較多
2)RDB每次在fork子行程來執行RDB快照資料檔案生成的時候,如果資料檔案特別大,可能會導致對客戶端提供的服務暫停數毫秒,或者甚至數秒,
所以一般不要讓RDB的間隔太長,否則每次生成的RDB檔案太大了,對redis本身的性能可能會有影響的,
AOF的優點:
1)AOF可以更好的保護資料不丟失 一般AOF會每隔1秒,通過一個后臺執行緒執行一次fsync操作,最多丟失1秒鐘的資料,
每隔1秒,就執行一次fsync操作,保證os cache中的資料寫入磁盤中, redis行程掛了,最多丟掉1秒鐘的資料.
2)AOF持久化性能高 AOF日志檔案以append-only模式寫入,所以沒有任何磁盤尋址的開銷,寫入性能非常高,而且檔案不容易破損,即使檔案尾部破損,也很容易修復,
3)AOF日志檔案即使過大的時候,出現后臺重寫操作,也不會影響客戶端的讀寫, 因為在rewrite log的時候,會對其中的指令進行壓縮,創建出一份需要恢復資料的最小日志出來,在創建新日志檔案的時候,老的日志檔案還是照常寫入,當新的merge后的日志檔案ready的時候,再交換新老日志檔案即可,
4)AOF日志檔案的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤洗掉的緊急恢復,
比如某人不小心用flushall命令清空了所有資料,只要這個時候后臺rewrite還沒有發生,那么就可以立即拷貝AOF檔案,將最后一條flushall命令給刪了,然后再將該AOF檔案放回去,就可以通過恢復機制,自動恢復所有資料,
AOF的缺點:
(1)對于同一份資料來說,AOF日志檔案通常比RDB資料快照檔案更大
(2)AOF開啟后,支持的寫QPS會比RDB支持的寫QPS低,因為AOF一般會配置成每秒fsync一次日志檔案,當然,每秒一次fsync,性能也還是很高的,
如果你要保證一條資料都不丟,也是可以的,AOF的fsync設定成沒寫入一條資料,fsync一次,但是那樣導致redis的QPS大幅度下降,
(3)以前AOF發生過bug,就是通過AOF記錄的日志,進行資料恢復的時候,沒有恢復一模一樣的資料出來,
所以說,類似AOF這種較為復雜的基于命令日志/merge/回放的方式,比基于RDB每次持久化一份完整的資料快照檔案的方式,更加脆弱一些,容易有bug,不過AOF就是為了避免rewrite程序導致的bug,因此每次rewrite并不是基于舊的指令日志進行merge的,而是基于當時記憶體中的資料進行指令的重新構建,這樣健壯性會好很多,
(4)唯一的比較大的缺點,其實就是做資料恢復的時候,會比較慢,做冷備不太合適,
你剛才提到冷備,那你具體說說為啥AOF不適合RDB適合?
其實兩個都可以做,只不過RDB更適合,
RDB可以做冷備,是因為它會生成多個檔案,每個檔案都代表了某一個時刻的完整的資料快照,我們可以將這種完整的資料檔案發送到一些遠程的安全存盤上去,比如可以是阿里云的ODPS分布式存盤上,以預定好的備份策略來定期備份redis中的資料,
AOF也可以做冷備,只不過它只有一個檔案,但是我們可以去自己寫程式,每隔一定時間,去copy一份這個檔案出來,
RDB做冷備,優勢在于由redis去控制固定時長生成快照檔案的事情,比較方便,而 AOF,還需要我們自己寫一些腳本去做這個事情,各種定時,比較麻煩,
RDB資料做冷備,在最壞的情況下,提供資料恢復的時候,速度比AOF快,
8、Spring MVC的主要組件?
(1)前端控制器 DispatcherServlet(不需要程式員開發)
作用:接收請求、回應結果,相當于轉發器,有了DispatcherServlet 就減少了其它組件之間的耦合度,
(2)處理器映射器HandlerMapping(不需要程式員開發)
作用:根據請求的URL來查找Handler
(3)處理器配接器HandlerAdapter
注意:在撰寫Handler的時候要按照HandlerAdapter要求的規則去撰寫,這樣配接器HandlerAdapter才可以正確的去執行Handler,
(4)處理器Handler(需要程式員開發)
(5)視圖決議器 ViewResolver(不需要程式員開發)
作用:進行視圖的決議,根據視圖邏輯名決議成真正的視圖(view)
(6)視圖View(需要程式員開發jsp)
View是一個介面, 它的實作類支持不同的視圖型別(jsp,freemarker,pdf等等)
9、23種設計模式
三大類 :創建型模式、結構型模式、行為型模式;
創建型模式:共5種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式
結構型模式:共七種:配接器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式,
行為型模式:共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式,
10、Spring MVC的作業流程
(1)用戶發送請求至前端控制器DispatcherServlet; (2) DispatcherServlet收到請求后,呼叫HandlerMapping處理器映射器,請求獲取Handle; (3)處理器映射器根據請求url找到具體的處理器,生成處理器物件及處理器攔截器(如果有則生成)一并回傳給DispatcherServlet; (4)DispatcherServlet 呼叫 HandlerAdapter處理器配接器; (5)HandlerAdapter 經過適配呼叫 具體處理器(Handler,也叫后端控制器); (6)Handler執行完成回傳ModelAndView; (7)HandlerAdapter將Handler執行結果ModelAndView回傳給DispatcherServlet; (8)DispatcherServlet將ModelAndView傳給ViewResolver視圖決議器進行決議; (9)ViewResolver決議后回傳具體View; (10)DispatcherServlet對View進行渲染視圖(即將模型資料填充至視圖中) (11)DispatcherServlet回應用戶
11、MySQL優化
主要從4個方面
設計:存盤引擎,欄位型別,范式與逆范式
功能:索引,快取,分庫分表,
架構:主從復制,讀寫分離,負載均衡,
合理SQL:測驗,經驗
12、SpringBoot整合
-
創建工程環境,
-
配置資料庫連接資訊,這里使用yml方式,spring: datasource: username: root url: …
-
撰寫物體類,
-
撰寫Mapper介面類
13、Redis如何使用?
啟動redis 、配置redis的資料庫連接、撰寫redis操作工具類、測驗
14、Redis是什么?應用場景?如何實作同步?
非關系型資料庫,C撰寫的, key,value鍵值對資料庫 資料存盤在記憶體中 讀寫快,
優點:讀寫快,支持資料持久化,資料結構豐富,
缺點:容易受到物理記憶體的限制,不能作為海量資料的高性能讀寫 ,不具備容錯和恢復功能,
適應場景在較小的資料量的高性能操作和運算上,
15、ES如何保證資料不丟失
16、SpringBean的生命周期
實體化 Instantiation、屬性賦值 Populate、初始化 Initialization、銷毀 Destruction
17、Mybatis的一級二級快取
-
一級快取默認開啟,查詢時先從快取中查詢,快取中沒有對應資料時再進行資料庫查詢,
-
二級快取即查詢快取,他的作用于是mapper和namespace,二級快取可以跨SqlSession
18、SpringBoot注解?
@RestController表示該方法的回傳結果直接寫入HTTP response body中 @RequestMapping 注解 處理請求地址映射
@EnableAutoConfiguration 注解允許 Spring Boot 自動配置注解
@Configuration用于定義配置類
@SpringBootApplication用在 Spring Boot的主類上,標識這是一個 Spring Boot 應用,用來開啟 Spring Boot 的各項能力, @ComponentScan 組件掃描,讓spring Boot掃描到Configuration類并把它加入到程式背景關系,
@ResponseBody
@Component
@AutoWired
@RequestParam用在方法的引數前面:
@PathVariable 路徑變數,引數與大括號里的名字一樣要相同 @ResponseBody表示該方法的回傳結果直接寫入HTTP response body 中
@Repository 用于標注資料訪問組件,即DAO組件
19、 Spring事務有哪些?
ACID 原子性、一致性、隔離性、持久性
20、 這些事務的特性有哪些?
原子性(要么全部成功要么全部失敗,不會結束在中間某個環節)
一致性(執行前和執行后資料庫保持在一致性狀態)
隔離性(資料所處的狀態要么是更改之前的狀態要么是更改之后的狀態 不會看到中間的狀態資料)
持久性(只要事務成功結束,那么資料庫的資料就會永久保存下來,即使資料庫崩潰 重新啟動后資料庫還能恢復到事務成功結束的狀態)
21、資料庫的事務隔離?怎么實作的
不考慮事務的隔離性會出現幾種:臟讀(在一個事務里讀取到領另一個未提交事務的資料)、不可重復讀(在一個事務范圍內多次查詢回傳的資料不同的資料, 發生在修改)、幻讀( 前后兩次讀取的資料在第二次查詢的時候能查到都第一次看不到的行資料,發生在插入和洗掉 )
事務的ACID是通過InnoDB的日志和鎖來保證的,事務的隔離性通
過資料鎖的機制實作的
22、RESTful是一種設計風格而不是規范,比如介面的命名不以動詞命名(如findById deleteById等),不同的請求方式代表了相應的動作 比如 /user介面 crud操作只需要更換不同的請求方式即可 一個介面即可搞定 而不需要定義多個介面
23、MySQL常用的存盤引擎:
InnoDB、MyISAM、MEMORY、ARCHIVE
MyISAM索引與InnoDB索引的區別?
InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引,
InnoDB的主鍵索引的葉子節點存盤著行資料,因此主鍵索引非常高效,
MyISAM索引的葉子節點存盤的是行資料地址,需要再尋址一次才能得到資料,
InnoDB非主鍵索引的葉子節點存盤的是主鍵和其他帶索引的列資料,因此查詢時做到覆寫索引會非常高效,
23.1、InnoDB引擎的4大特性
插入緩沖(insert buffer)、二次寫(double write)、自適應哈希索引(ahi)、預讀(read ahead)
23.2、引擎的選擇?
如果要提供提交、回滾、崩潰恢復能力的事物安全(ACID兼容)能力,并要求實作并發控制,InnoDB是一個好的選擇,
如果資料表主要用來插入和查詢記錄,則MyISAM引擎能提供較高的處理效率,
如果只是臨時存放資料,資料量不大,并且不需要較高的資料安全性,可以選擇將資料保存在記憶體中的Memory引擎,MySQL中使用該引擎作為臨時表,存放查詢的中間結果,
如果只有INSERT和SELECT操作,可以選擇Archive,Archive支持高并發的插入操作,但是本身不是事務安全的,Archive非常適合存盤歸檔資料,如記錄日志資訊可以使 Archive,
24、@ResquestBody 和@ResponseBody的區別?
@ResponseBody注解表示該方法的回傳的結果直接寫入 HTTP 回應正文中,一般在異步獲取資料時使用,通常是在使用 @RequestMapping 后,回傳值通常決議為跳轉路徑,加上 @Responsebody 后回傳結果不會被決議為跳轉路徑,而是直接寫入HTTP 回應正文中,
@RequestBody是作用在形參串列上,用于將前臺發送過來固定格式的資料(xml 格式或者 json等)封裝為對應的 JavaBean 物件,封裝時使用到的一個物件是系統默認配置的 HttpMessageConverter進行決議,然后封裝到形參上,
在GET請求中,不能使用@RequestBody,在POST請求,可以使用@RequestBody和@RequestParam,但是如果使用@RequestBody,對于引數轉化的配置必須統一,
25、為什么使用資料庫?三大范式了解嗎?
1.存取的速度快,資料永久保存
2.第一范式:每個列都不可以再拆分,
第二范式:在第一范式的基礎上,非主鍵列完全依賴于主鍵,而不能是依賴于主鍵的一部分,
第三范式:在第二范式的基礎上,非主鍵列只依賴于主鍵,不依賴于其他非主鍵,
25.1、資料庫中為什么要用索引?這么多優點怎么不在每一個表中的列都使用索引呢 ?
1、可以大大加快資料的檢索速度,使用索引,提高系統的性能,
2、時間上:在每一列上使用索引耗費時間,在使用時會降低執行效率,
空間上:會占用物理空間
25.2、你在開發的時候用到索引了嗎 應用場景是?
資料量的時候查詢欄位較多的時候
當資料多且欄位值有相同的值得時候用普通索引,當欄位多且欄位值沒有重復的時候用唯一索引,當有多個欄位名都經常被查詢的話用復合索引,
26、rabbitmq 的使用場景有哪些?(你公司生產環境用的那個訊息中間件)
好處:異步處理、流量削峰、訊息通訊、應用解耦;
缺點:可用性降低、復雜度提高、一致性問題
Rabbit :支持高并發高吞吐、支持集群化、功能較為完善
使用場景:順序消費、服務間異步通信、定時任務、請求削峰
27、zookeeper的部署模式? 應用場景?
三種 :單機部署,集群部署,偽集群部署,
資料發布/訂閱、負載均衡、命名服務、分布式協調/通知、集群管理、Master 選舉、分布式鎖、分布式佇列
28、log4j有什么用?
在開發階段寫下的這些判斷僅為了除錯的陳述句,在開發完成時需要查找并移除,部署運行后,尤其是在一些企業應用系統中,還經常需要進一步除錯,這時就遇到了更大的麻煩,所以,我們需要一套完備的、靈活的、可配置的日志工具log4J就是優秀的選擇,
28.1、Log4j主要由哪三部分組成?每部分的主要作用是什么?
Log4j 由 logger、appender 和 layout 三個組件組成,可以通過同名的 Java 類訪問 Log4j 的這三個組件,
Logger 在執行應用程式時,接收日志陳述句生成的日志請求,它是一種重要的日志處理組件, 可以通過 log4j API 的 logger 類對其進行訪問,它的方法有:debug、info、warn、error、fatal 和 log,這些方法用于記錄訊息, Appender - 管理日志陳述句的輸出結果,執行日志陳述句時,Logger 物件將接收來自日志陳述句的記錄請求,此請求是通過 logger 發送至 appender 的,然后,Appender 將輸出結果寫入到用戶選擇的目的地,對于不同的日志目的地,提供不同的 appender 型別,這些 appender 包括:用于檔案的 file appender、用于資料庫的 JDBC appender 和用于 SMTP 服務器的 SMTP appender, Layout - 用于指定 appender 將日志陳述句寫入日志目的地所采用的格式,appender 可以用來格式化輸出結果的各種布局包括:簡單布局、模式布局和 HTML 布局,
29、執行緒池的作用?
執行緒池作用就是限制系統中執行執行緒的數量,
1、提高效率 創建好一定數量的執行緒放在池中,等需要使用的時候就從池中拿一個,這要比需要的時候創建一個執行緒物件要快的多,
2、方便管理 可以撰寫執行緒池管理代碼對池中的執行緒同一進行管理
3、降低資源消耗
29.1、執行緒池都有哪幾種作業佇列
1、ArrayBlockingQueue
是一個基于陣列結構的有界阻塞佇列,此佇列按 FIFO(先進先出)原則對元素進行排序,
2、LinkedBlockingQueue
一個基于鏈表結構的阻塞佇列,此佇列按FIFO (先進先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue,靜態工廠方法Executors.newFixedThreadPool()使用了這個佇列
3、SynchronousQueue
一個不存盤元素的阻塞佇列,每個插入操作必須等到另一個執行緒呼叫移除操作,否則插入操作一直處于阻塞狀態,吞吐量通常要高于LinkedBlockingQueue,靜態工廠方法Executors.newCachedThreadPool使用了這個佇列,
4、PriorityBlockingQueue
一個具有優先級的無限阻塞佇列,
30、Nginx?
Nginx是一個輕量級/高性能的反向代理Web服務器,他實作非常高效的反向代理、負載平衡
30.1、為什么要用Nginx?
-
跨平臺、配置簡單、方向代理、高并發連接:處理2-3萬并發連接數,官方監測能支持5萬并發,記憶體消耗小:開啟10個nginx才占150M記憶體 ,nginx處理靜態檔案好,耗費記憶體少,
-
而且Nginx內置的健康檢查功能:如果有一個服務器宕機,會做一個健康檢查,再發送的請求就不會發送到宕機的服務器了,重新將請求提交到其他的節點上,
使用Nginx的話還能:
-
節省寬帶:支持GZIP壓縮,可以添加瀏覽器本地快取
-
穩定性高:宕機的概率非常小
-
接收用戶請求是異步的
30.2、Nginx的優缺點?
-
優點:
-
占記憶體小,可實作高并發連接,處理回應快
-
可實作http服務器、虛擬主機、方向代理、負載均衡
-
Nginx配置簡單
-
可以不暴露正式的服務器IP地址
-
-
缺點: 動態處理差:nginx處理靜態檔案好,耗費記憶體少,但是處理動態頁面則很雞肋,現在一般前端用nginx作為反向代理抗住壓力,
30.3、Nginx應用場景?
-
http服務器,Nginx是一個http服務可以獨立提供http服務,可以做網頁靜態服務器,
-
虛擬主機,可以實作在一臺服務器虛擬出多個網站,例如個人網站使用的虛擬機,
-
反向代理,負載均衡,當網站的訪問量達到一定程度后,單臺服務器不能滿足用戶的請求時,需要用多臺服務器集群可以使用nginx做反向代理,并且多臺服務器可以平均分擔負載,不會應為某臺服務器負載高宕機而某臺服務器閑置的情況,
-
nginz 中也可以配置安全管理、比如可以使用Nginx搭建API介面網關,對每個介面服務進行攔截,
30.4、Nginx 是如何實作高并發的?
異步,非阻塞,使用了epoll 和大量的底層代碼優化,
如果一個server采用一個行程負責一個request的方式,那么行程數就是并發數,正常情況下,會有很多行程一直在等待中,
而nginx采用一個master行程,多個woker行程的模式,
-
master行程主要負責收集、分發請求,每當一個請求過來時,master就拉起一個worker行程負責處理這個請求,
-
同時master行程也負責監控woker的狀態,保證高可靠性
-
woker行程一般設定為跟cpu核心數一致,nginx的woker行程在同一時間可以處理的請求數只受記憶體限制,可以處理多個請求,
Nginx 的異步非阻塞作業方式正把當中的等待時間利用起來了,在需要等待的時候,這些行程就空閑出來待命了,因此表現為少數幾個行程就解決了大量的并發問題,
31、多執行緒 執行緒安全 高并發?
https://yq.aliyun.com/articles/659726
https://developer.aliyun.com/article/711990
32、Dubbo?
https://www.jianshu.com/p/a66b83c450b2
33、Redis優化?
https://www.cnblogs.com/zhangyfr/p/10459346.html
https://www.jianshu.com/p/a66b83c450b2
33.1、Redis的佇列如何異步使用?
Redis 的 list 結構可以作為佇列使用,rpush 生產訊息,lpop 消費訊息,lpop 沒有取到訊息時,可以讓執行緒休眠一會再獲取訊息
blpop 指令,在佇列沒有訊息時,會阻塞執行緒直到訊息被生產,獲取訊息
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/287359.html
標籤:其他
