java的面試題總結

2020-08-11 16:55:30

List, Set, Map的區別
1、List中的元素,有序、可重複、可爲空;
2、Set中的元素,無序、不重複、只有一個空元素;
3、Map中的元素,無序、鍵不重,值可重、可一個空鍵、多個空值;
ArrayList和LinkedList的區別
ArrayList:底層實現就是陣列,且ArrayList實現了(/ˈrændəm/)RandomAccess( /ˈækses/ ),表示它能快速隨機存取儲存的元素,通過下標 index 存取,只是我們需要用 get() 方法的形式, 陣列支援隨機存取, 查詢速度快, 增刪元素慢。
LinkedList:底層實現是鏈表, (/lɪŋkt/)LinkedList 沒有實現 RandomAccess 介面,鏈表支援順序存取, 查詢速度慢, 增刪元素快。
HashMap和Hashtable的區別是什麼
HashMap是基於雜湊表實現的,每一個元素是一個key-value對,其內部通過單鏈表解決衝突問題,容量不足(超過了閥值)時,同樣會自動增長。
HashMap是非執行緒安全的,只是用於單執行緒環境下,多執行緒環境下可以採用concurrent併發包下的( /kənˈkɜːrənt/ )concurrentHashMap。
HashMap 實現了Serializable( /ˈsɪŋkrənaɪz)介面,因此它支援序列化,實現了Cloneable介面,能被克隆。
Hashtable 中的方法是Synchronize的,在多執行緒併發的環境下,可以直接使用Hashtable,不需要自己爲它的方法實現同步,但使用HashMap時就必須要自己增加同步處理。
HashMap由陣列和鏈表來實現對數據的儲存
HashMap採用Entry陣列來儲存key-value對,每一個鍵值對組成了一個Entry實體,Entry類實際上是一個單向的鏈表結構,它具有Next指針,可以連線下一個Entry實體,以此來解決Hash衝突的問題。
陣列儲存區間是連續的,佔用記憶體嚴重,故空間複雜的很大。但陣列的二分查詢時間複雜度小,爲O(1);陣列的特點是:定址容易,插入和刪除困難;
鏈表儲存區間離散,佔用記憶體比較寬鬆,故空間複雜度很小,但時間複雜度很大,達O(N)。鏈表的特點是:定址困難,插入和刪除容易。
HashMap結構及原理
HashMap是基於雜湊表的Map介面的非同步實現。實現HashMap對數據的操作,允許有一個null鍵,多個null值。
HashMap底層就是一個數組結構,陣列中的每一項又是一個鏈表。陣列+鏈表結構,新建一個HashMap的時候,就會初始化一個數組。Entry就是陣列中的元素,每個Entry(/ˈentri/ )其實就是一個key-value的鍵值對,它持有一個指向下一個元素的參照,這就構成了鏈表,HashMap底層將key-value當成一個整體來處理,這個整體就是一個Entry物件。HashMap底層採用一個Entry【】陣列來儲存所有的key-value鍵值對,當需要儲存一個Entry物件時,會根據hash演算法來決定在其陣列中的位置,在根據equals方法決定其在該陣列位置上的鏈表中的儲存位置;當需要取出一個Entry物件時,也會根據hash演算法找到其在陣列中的儲存位置, 在根據equals方法從該位置上的鏈表中取出Entry。
TreeSet 和 HashSet 區別
HashSet 是採用 hash 表來實現的。其中的元素沒有按順序排列,add()、remove()以及contains()等方法都是複雜度爲 O(1)的方法。
TreeSet 是採用樹結構實現(紅黑樹演算法)。元素是按順序進行排列,但是 add()、
remove()以及 contains()等方法都是複雜度爲 O(log (n))的方法。它還提供了一些方法來處理排序的 set,如 first(),last(),headSet(),tailSet()等等。
final的用法:
修飾數據:final修飾的數據的值是不可改變的
修飾方法參數:可以在參數前面新增final關鍵字,它表示在整個方法中,我們不會(實際上是不能)改變參數的值:
修飾方法:該方法不能被覆蓋
修飾類:那就是用final修飾的類是無法被繼承的。
static的用法:
被static所修飾的變數或者方法會儲存在數據共用區;
被static修飾後的成員變數只有一份!
當成員被static修飾之後,就多了一種存取方式,除了可以被物件呼叫之外,還可以直接被類名呼叫,(類名.靜態成員);
1、優點:
隨着類的載入而被載入;
優先於物件存在;
被所有物件共用;
被static修飾的變數成爲靜態變數(類變數)或者範例變數;
2、存放位置:
類變數隨着類的載入而存在於date記憶體區;
範例變數隨着物件的建立而存在於堆記憶體;
3、方法注意事項:
靜態的方法只能存取靜態的成員;
非靜態得方法即能存取靜態得成員(成員變數,成員方法)又能存取非靜態得成員;
區域性變數不能被static修飾;
靜態得方法中是不可以定義this、super關鍵字的,因爲靜態優先於物件存在,所以靜態方法不可以出this;
4、什麼時候使用static修成員:
當屬於同一個類的所有物件出現共用數據時,就需要將儲存這個共用數據的成員用static修飾;
多執行緒(併發執行緒)
進程和執行緒的區別:執行緒是進程的子集一個進程可以有多個執行緒,每條執行緒並行執行多個任務
start和run啓動執行緒的區別:start是啓動一個新的執行緒run方法是內部啓動的但是run只是在原有的執行緒上啓動不會啓動新的執行緒
thread和runnable的區別:如果你知道Java不支援類的多重繼承,但允許你呼叫多個介面。所以如果你要繼承其他類,當然是呼叫Runnable介面好了。、
編寫多執行緒程式的幾種實現方式(換個問法:建立多執行緒的方式)?
(1)通過繼承Thread類
(2)通過實現Runnable介面(推薦使用,因爲Java中是單繼承,一個類只有一個父類別,若繼承了Thread類,就無法在繼承其它類,顯然實現Runnable介面更爲靈活)
(3)通過實現Callable介面(Java 5之後)。
sleep()和wait()的區別?
1.sleep()方法,屬於Thread類的。;wait()方法,則是屬於Object類的;
2.sleep方法不會釋放鎖,而wait方法會釋放鎖
3.wait,notify和notifyAll只能在同步控制方法或者同步控制塊裏面使用,而sleep可以在任何地方使用
4.sleep需要接收時間參數,wait不需要接收時間參數;
5.sleep可以自然醒,wait必須等待別人喚醒;
Spring+SpringMVC:
Spring是一個容器,因爲它包含並且管理應用物件的生命週期。
string和stringbuff和stringbuild區別
String類是不可變類,任何對String的改變都會引發新的String物件的生成;
StringBuffer是可變類,任何對它所指代的字串的改變都不會產生新的物件,執行緒安全的。
StringBuilder是可變類,線性不安全的,不支援併發操作,不適合多執行緒中使用,但其在單執行緒中的效能比StringBuffer高。
談談你理解的spring的工作流程的理解?
建立組態檔applicationContext.xml
編寫組態檔(加入一些物件的設定資訊)
Spring內部採用工廠模式,配合xml解析+反射技術,根據使用者的設定,生成相應的物件
工廠提供一個getBean方法,從工廠中獲取物件
操作物件的方法,屬性。
說說spring物件建立的三種方式。
1.無參構造2.範例工廠 3.靜態工廠

SpringMVC的執行流程是什麼?
第一步:發起請求到前端控制器(DispatcherServlet)
第二步:前端控制器請求HandlerMapping查詢 Handler
可以根據xml設定、註解進行查詢
第三步:處理器對映器HandlerMapping向前端控制器返回Handler
第四步:前端控制器呼叫處理器適配器去執行Handler
第五步:處理器適配器去執行Handler
第六步:Handler執行完成給適配器返回ModelAndView
第七步:處理器適配器向前端控制器返回ModelAndView
ModelAndView是springmvc框架的一個底層物件,包括Model和view
第八步:前端控制器請求檢視解析器去進行檢視解析
根據邏輯檢視名解析成真正的檢視(jsp)
第九步:檢視解析器向前端控制器返回View
第十步:前端控制器進行檢視渲染
檢視渲染將模型數據(在ModelAndView物件中)填充到request域
第十一步:前端控制器向使用者響應結果。
使用springMVC框架的時候,如何解決post和get的亂碼問題?
解決post請求亂碼:我們可以在web.xml裏邊設定一個CharacterEncodingFilter過濾器。設定爲utf-8.
解決get請求的亂碼:有兩種方法。對於get請求中文參數出現亂碼解決方法有兩個:
1.修改tomcat組態檔新增編碼與工程編碼一致。
2.另外一種方法對參數進行重新編碼 String userName = New String(Request.getParameter(「userName」).getBytes(「ISO8859-1」), 「utf-8」);

IOC(DI)和AOP容器框架:
IOC控制反轉,我們不再手動建立物件 而是將物件的建立權交給IOC容器,需要獲取物件時直接從IOC容器中獲取,IOC開發中實現的兩種方式xml和註解通過設定Spring.xml檔案或者註解 ClassPathXmlApplicationContext。
IOC建立多個範例:在bean標籤中加入屬性scope(「prototype」)
AOP面向切面程式設計:利用AOP程式設計實現日誌記錄功能
TCP和UDP的區別
1、TCP(面向連接如打電話要先撥號建立連線),建立TCP連線需經過三次握手,釋放TCP連線需經過四次揮手;UDP是無連線的,即發送數據之前不需要建立連線
2、TCP提供可靠的服務。也就是說,通過TCP連線傳送的數據,無差錯,不丟失,不重複,且按序到達;UDP盡最大努力交付,即不保證可靠交付
Tcp通過校驗和,重傳控制,序號標識,滑動視窗、確認應答實現可靠傳輸。如丟包時的重發控制,還可以對次序亂掉的分包進行順序控制。
3、UDP具有較好的實時性,工作效率比TCP高,適用於對高速傳輸和實時性有較高的通訊或廣播通訊。
4.每一條TCP連線只能是點到點的;UDP支援一對一,一對多,多對一和多對多的互動通訊
5、TCP對系統資源要求較多,UDP對系統資源要求較少。
樂觀鎖和悲觀鎖
悲觀鎖:總是假設最壞的情況。
每次去拿數據的時候都認爲別人會修改,所以每次在拿數據的時候都會上鎖。
傳統的關係型數據庫裏邊就用到了很多這種鎖機制 機製,比如讀鎖,寫鎖等,都是在做操作之前先上鎖。
樂觀鎖
總是假設最好的情況,每次去拿數據的時候都認爲別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據。
樂觀鎖適用於寫比較少的情況,即衝突真的很少發生,這樣可以省去鎖的開銷,從而提高系統的吞吐量。
悲觀鎖使用於寫比較頻繁的情況,即經常產生衝突,上層參照會不斷的進行重試,這樣反倒降低了效能,所以使用鎖比較合適。
SSM:
SpringBoot整合Mybatis+SpringMVC
SpringBoot極大的簡化的SSM整合過程,只需要加入相關依賴和少量設定即可。
Spring Boot 是 Spring 開源組織下的一個子專案,也是 Spring 元件一站式解決方案,主要是爲了簡化使用 Spring 框架的難度,簡省繁重的設定。
Spring Boot提供了各種元件的啓動器(starters),開發者只要能設定好對應元件參數,Spring Boot 就會自動設定,讓開發者能快速搭建依賴於 Spring 元件的 Java 專案。
分佈式開發經驗:
架構
分佈式的系統架構,主要從以下幾個方面來考慮:分層、面向服務以及分佈式數據庫。
分層模型
一般地,我們將應用程式功能分爲三個方面,對應3層架構模式。它們是數據層、中間層(業務邏輯層)和表示層,如下圖所示。

  1.    數據層:儲存數據以及從數據庫中獲得較爲原始的數據。
    
  2.    業務邏輯層:介於數據層和表示層之間,負責處理來自數據儲存或發送給數據儲存的數據,把數據轉換成符合商務規則的有意義的資訊。
    
  3.    表示層:從業務邏輯層獲得資訊並顯示給使用者,負責與使用者的互動。
    

針對大型的網站應用,分佈式部署策略可以從以下幾個方面考慮:

  1.    代理伺服器實現請求的分離 。
    
  2.    快取的分佈式部署,提高系統效能。
    
  3.    拆分網站的對外功能,例如不同域名前、後綴,URL 重寫。
    
  4.    面向服務,每個服務分佈到一臺伺服器上 。
    
  5.    數據庫的分佈式叢集部署。
    

SQL優化經驗:
要提高SQL語句的執行效率,最常見的方法就是建立索引,以及儘量避免全表掃描。在本章MySQL教學中,UncleToo給大家整理一些常見的SQL優化技巧,避免全表掃描。一個簡單的優化,也許能讓你的SQL執行效率提高幾倍,甚至幾十倍。
1、避免在where子句中使用 is null 或 is not null 對欄位進行判斷。
如:select id from table where name is null
在這個查詢中,就算我們爲 name 欄位設定了索引,查詢分析器也不會使用,因此查詢效率底下。爲了避免這樣的查詢,在數據庫設計的時候,儘量將可能會出現 null 值的欄位設定預設值,這裏如果我們將 name 欄位的預設值設定爲0,那麼我們就可以這樣查詢:
select id from table where name = 0
2、避免在 where 子句中使用 != 或 <> 操作符。
如:select name from table where id <> 0
數據庫在查詢時,對 != 或 <> 操作符不會使用索引,而對於 < 、 <= 、 = 、 > 、 >= 、 BETWEEN AND,數據庫纔會使用索引。因此對於上面的查詢,正確寫法應該是:
select name from table where id < 0
union all
select name from table where id > 0
這裏我們爲什麼沒有使用 or 來鏈接 where 後的兩個條件呢?這就是我們下面 下麪要說的第3個優化技巧。
3、避免在 where 子句中使用 or來鏈接條件。
如:select id from tabel where name = ‘UncleToo’ or name = ‘PHP’
這種情況,我們可以這樣寫:
select id from tabel where name = ‘UncleToo’
union all
select id from tabel where name = ‘PHP’
4、少用 in 或 not in。
雖然對於 in 的條件會使用索引,不會全表掃描,但是在某些特定的情況,使用其他方法也許效果更好。如:select name from tabel where id in(1,2,3,4,5)
像這種連續的數值,我們可以使用 BETWEEN AND,如:
select name from tabel where id between 1 and 5
5、注意 like 中萬用字元的使用。
下面 下麪的語句會導致全表掃描,儘量少用。如:select id from tabel where name like’%UncleToo%’
或者select id from tabel where name like’%UncleToo’
而下面 下麪的語句執行效率要快的多,因爲它使用了索引:
select id from tabel where name like’UncleToo%’
6、避免在 where 子句中對欄位進行表達式操作。
如:select name from table where id/2 = 100
正確的寫法應該是:select name from table where id = 100*2
7、避免在 where 子句中對欄位進行函數操作。
如:select id from table where substring(name,1,8) = ‘UncleToo’
或select id from table where datediff(day,datefield,‘2014-07-17’) >= 0
這兩條語句中都對欄位進行了函數處理,這樣就是的查詢分析器放棄了索引的使用。正確的寫法是這樣的:select id from table where name like’UncleToo%’
或select id from table where datefield <= ‘2014-07-17’
也就是說,不要在 where 子句中的 = 左邊進行函數、算術運算或其他表達式運算。
8、在子查詢中,用 exists 代替 in 是一個好的選擇。
如:select name from a where id in(select id from b)
如果我們將這條語句換成下面 下麪的寫法:
select name from a where exists(select 1 from b where id = a.id)
這樣,查詢出來的結果一樣,但是下面 下麪這條語句查詢的速度要快的多。
Spring MVC(檢視框架)
Spring MVC 是一個 MVC 開源框架,用來代替 Struts。它是 Spring 專案裏面的一個重要組成部分,能與 Spring IOC 容器緊密結合,以及擁有松耦合、方便設定、程式碼分離等特點,讓 JAVA 程式設計師開發 WEB 專案變得更加容易。
SpringMVC 的工作原理
a. 使用者向伺服器發送請求,請求被 springMVC 前端控制器 DispatchServlet 捕獲;
b. DispatcherServle 對請求 URL 進行解析,得到請求資源識別符號(URL),然後根據該 URL 呼叫 HandlerMapping
將請求對映到處理器 HandlerExcutionChain;
c. DispatchServlet 根據獲得 Handler 選擇一個合適的 HandlerAdapter 適配器處理;
d. Handler 對數據處理完成以後將返回一個 ModelAndView()物件給 DisPatchServlet;
e. Handler 返回的 ModelAndView()只是一個邏輯檢視並不是一個正式的檢視,DispatcherSevlet 通過
ViewResolver 試圖解析器將邏輯檢視轉化爲真正的檢視 View;
h. DispatcherServle 通過 model 解析出 ModelAndView()中的參數進行解析最終展現出完整的 view 並返回給用戶端;
SpringMVC 常用註解都有哪些?
@requestMapping 用於請求 url 對映。
@RequestBody 註解實現接收 http 請求的 json 數據,將 json 數據轉換爲 java 物件。
@ResponseBody 註解實現將 controller 方法返回物件轉化爲 json 響應給客戶。

Spring Boot(是一個簡化Spring開發的框架)
SpringBoot整合Mybatis+SpringMVC
SpringBoot極大的簡化的SSM整合過程,只需要加入相關依賴和少量設定即可。
Spring Boot 是 Spring 開源組織下的一個子專案,也是 Spring 元件一站式解決方案,主要是爲了簡化使用 Spring 框架的難度,簡省繁重的設定。
Spring Boot提供了各種元件的啓動器(starters),開發者只要能設定好對應元件參數,Spring Boot 就會自動設定,讓開發者能快速搭建依賴於 Spring 元件的 Java 專案。
Spring boot執行流程
1、 使用者發送請求至前端控制器DispatcherServlet。
2、 DispatcherServlet收到請求呼叫HandlerMapping處理器對映器。
3、 處理器對映器找到具體的處理器(可以根據xml設定、註解進行查詢),生成處理器物件及處理器攔截器(如果有則生成)一併返回給DispatcherServlet。
4、 DispatcherServlet呼叫HandlerAdapter處理器適配器。
5、 HandlerAdapter經過適配呼叫具體的處理器(Controller,也叫後端控制器)。
6、 Controller執行完成返回ModelAndView。
7、 HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet。
8、 DispatcherServlet將ModelAndView傳給ViewReslover檢視解析器。
9、 ViewReslover解析後返回具體View。
10、DispatcherServlet根據View進行渲染檢視(即將模型數據填充至檢視中)。
11、 DispatcherServlet響應使用者。

SpringBoot核心原理
基於SpringMVC無組態檔(純Java)完全註解化+內建tomcat-embed-core實現SpringBoot框架,Main函數啓動。
SpringBoot核心快速整合第三方框架原理:Maven繼承依賴關係。
Mybatis/ iBatis(持久層框架)
MyBatis 是支援定製化 SQL、儲存過程以及高階對映的優秀的持久層框架。MyBatis 避免了幾乎所有的 JDBC 程式碼和手動設定參數以及獲取結果集。MyBatis 可以對設定和原生Map使用簡單的 XML 或註解,將介面和 Java 的 POJOs(Plain Old Java Objects,普通的 Java物件)對映成數據庫中的記錄。
1.Mybatis 的程式設計步驟是什麼樣的?
1、建立 SqlSessionFactory
2、通過 SqlSessionFactory 建立 SqlSession
3、通過 sqlsession 執行數據庫操作
4、呼叫 session.commit()提交事務
5、呼叫 session.close()關閉對談
Mybatis #{}和KaTeX parse error: Expected 'EOF', got '#' at position 11: {}的區別是什麼? #̲{}是預編譯處理,{}是字串替換。
Mybatis在處理#{}時,會將sql中的#{}替換爲?號,呼叫PreparedStatement的set方法來賦值;
Mybatis在處理{}時,就是把{}替換成變數的值。
使用#{}可以有效的防止SQL隱碼攻擊,提高系統安全性。
MySQL:
MySQL是一種關係數據庫管理系統,關係數據庫將數據儲存在不同的表中,而不是將所有數據放在一個大倉庫內,這樣就增加了速度並提高了靈活性。
MySQL索引型別:
Mysql目前主要有以下幾種索引型別:FULLTEXT,HASH,BTREE,RTREE。

  1. FULLTEXT fulltext
    即爲全文索引,目前只有MyISAM引擎支援。其可以在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不過目前只有 CHAR、VARCHAR ,TEXT 列上可以建立全文索引。
    全文索引並不是和MyISAM一起誕生的,它的出現是爲了解決WHERE name LIKE 「%word%"這類針對文字的模糊查詢效率較低的問題。
  2. HASH
    由於HASH的唯一(幾乎100%的唯一)及類似鍵值對的形式,很適合作爲索引。
    HASH索引可以一次定位,不需要像樹形索引那樣逐層查詢,因此具有極高的效率。但是,這種高效是有條件的,即只在「=」和「in」條件下高效,對於範圍查詢、排序及組合索引仍然效率不高。
  3. BTREE btree
    BTREE索引就是一種將索引值按一定的演算法,存入一個樹形的數據結構中(二元樹),每次查詢都是從樹的入口root開始,依次遍歷node,獲取leaf。這是MySQL裡預設和最常用的索引型別。
  4. RTREE rtree
    RTREE在MySQL很少使用,僅支援geometry數據型別,支援該型別的儲存引擎只有MyISAM、BDb、InnoDb、NDb、Archive幾種。
    相對於BTREE,RTREE的優勢在於範圍查詢。
    MySQL索引種類:
    普通索引:僅加速查詢
    唯一索引:加速查詢 + 列值唯一(可以有null)
    主鍵索引:加速查詢 + 列值唯一(不可以有null)+ 表中只有一個
    組合索引:多列值組成一個索引,專門用於組合搜尋,其效率大於索引合併
    全文索引:對文字的內容進行分詞,進行搜尋MySQL所使用的 SQL 語言是用於存取數據庫的最常用標準化語言。
    Spring(核心框架)

Spring 框架現在是 Java 後端框架家族裏面最強大的一個,其擁有 IOC 和 AOP 兩大利器,大大簡化了軟件開發複雜性。並且,Spring 現在能與所有主流開發框架整合,可謂是一個萬能框架,Spring 讓 JAVA 開發變得更多簡單。
Spring 容器的主要核心是:
控制反轉(IOC),傳統的 java 開發模式中,當需要一個物件時,我們會自己使用 new 或者 getInstance 等直接
或者間接呼叫構造方法建立一個物件。而在 spring 開發模式中,spring 容器使用了工廠模式爲我們建立了所需要的物件,不需要我們自己建立了,直接呼叫 spring 提供的物件就可以了,這是控制反轉的思想。
依賴注入(DI),spring 使用 javaBean 物件的 set 方法或者帶參數的構造方法爲我們在建立所需物件時將其屬性自動設定所需要的值的過程,就是依賴注入的思想。
面向切面程式設計(AOP),在物件導向程式設計(oop)思想中,我們將事物縱向抽成一個個的物件。而在面向切面程式設計中,我們將一個個的物件某些類似的方面橫向抽成一個切面,對這個切面進行一些如許可權控制、事物管理,記錄日誌等。公用操作處理的過程就是面向切面程式設計的思想。AOP 底層是動態代理,如果是介面採用 JDK 動態代理,如果是類採用CGLIB 方式實現動態代理。
Spring 的常用註解
@Required:該註解應用於設值方法
@Autowired:該註解應用於有值設值方法、非設值方法、構造方法和變數。
@Qualifier:該註解和@Autowired 搭配使用,用於消除特定 bean 自動裝配的歧義。
簡單介紹一下 Spring bean 的生命週期
bean 定義:在組態檔裏面用來進行定義。
bean 初始化:有兩種方式初始化:
1.在組態檔中通過指定 init-method 屬性來完成
2.實現 org.springframwork.beans.factory.InitializingBean 介面
bean 呼叫:有三種方式可以得到 bean 範例,並進行呼叫
bean 銷燬:銷燬有兩種方式
1.使用組態檔指定的 destroy-method 屬性
2.實現 org.springframwork.bean.factory.DisposeableBean 介面
有哪些不同類型的 IOC(依賴注入)方式?
Spring 提供了多種依賴注入的方式:
1.Set 注入
2.構造器注入
3.靜態工廠的方法注入
4.範例工廠的方法注入

Spring Cloud(微服務架構)

Spring Cloud 是一系列框架的有序集合,是目前最火熱的微服務架構首選,它利用Spring Boot 的開發便利性巧妙地簡化了分佈式系統基礎設施的開發,如服務發現註冊、設定中心、訊息匯流排、負載均衡、斷路器、數據監控等,都可以用 Spring Boot 的開發風格做到一鍵啓動和部署。

Spring Cloud常用元件
服務發現——Netflix Eureka
客服端負載均衡——Netflix Ribbon
斷路器——Netflix Hystrix
服務閘道器——Netflix Zuul
分佈式設定——Spring Cloud Config。

Hibernate(伺服器端驗證)

Hibernate 是一個開放原始碼的物件關係對映框架,它對 JDBC 進行了非常輕量級的物件封裝,它將 POJO 與數據庫表建立對映關係,是一個全自動的 orm 框架。Hibernate 可以自動生成 SQL 語句,自動執行,使得 Java 程式設計師可以隨心所欲的使用物件程式設計思維來操作數據庫。
簡述一下 hibernate 的開發流程
第一步:載入 hibernate 的組態檔,讀取組態檔的參數(jdbc 連線參數,數據 庫方言,hbm 表與物件關係對映檔案)
第二步:建立 SessionFactory 對談工廠(內部有連線池)
第三步:開啓 session 獲取連線,構造 session 物件(一次對談維持一個數據連線, 也是一級快取)
第四步:開啓事務
第五步:進行操作
第六步:提交事務
第七步:關閉 session(對談)將連線釋放
第八步:關閉連線池
hibernate 中物件的三種狀態
瞬時態(臨時態、自由態):不存在持久化標識 OID,尚未與 Hibernate Session 關聯物件, 被認爲處於瞬時態,失去參照將被 JVM 回收
持久態:存在持久化標識 OID,與當前 session 有關聯,並且相關聯的 session 沒有關閉 , 並且事務未提交
脫管態(離線態、遊離態):存在持久化標識 OID,但沒有與當前 session 關聯,脫管狀態 改變 hibernate 不能檢測到。
Hibernate 的查詢方式有哪些
Hibernate 的查詢方式常見的主要分爲三種: HQL, QBC(命名查詢), 以及使用原生 SQL 查詢(SqlQuery) 。
Hibernate 和 Mybatis 的區別?
兩者相同點:
1)Hibernate 與 MyBatis 都可以是通過 SessionFactoryBuider 由 XML 組態檔生成 SessionFactory,然後由SessionFactory 生成 Session,最後由 Session 來開啓執行事務和 SQL 語句。其中 SessionFactoryBuider,SessionFactory,Session 的生命週期都是差不多的。
2)Hibernate 和 MyBatis 都支援 JDBC 和 JTA 事務處理。
Mybatis 優勢:
1)MyBatis 可以進行更爲細緻的 SQL 優化,可以減少查詢欄位。
2)MyBatis 容易掌握,而 Hibernate 門檻較高。
Hibernate 優勢:
1)Hibernate 的 DAO 層開發比 MyBatis 簡單,Mybatis 需要維護 SQL 和結果對映。
2)Hibernate 對物件的維護和快取要比 MyBatis 好,對增刪改查的物件的維護要方便。
3)Hibernate 數據庫移植性很好,MyBatis 的數據庫移植性不好,不同的數據庫需要寫不同 SQL。
4)Hibernate 有更好的二級快取機制 機製,可以使用第三方快取。MyBatis 本身提供的快取機制 機製不佳。
關於 Hibernate 的 orm 思想你瞭解多少?
ORM 指的是物件關係型對映(Object RelationShip Mapping ),指的就是我們通過建立實體類物件和數據庫中的表關係進行一一對應,來實現通過操作實體類物件來更改數據庫裏邊的數據資訊。這裏邊起到關鍵作用的是通過Hibernate 的對映檔案+Hibernate 的核心組態檔。
如何進行 Hibernate 的優化?
(1)數據庫設計調整。
(2)HQL 優化。
(3)API 的正確使用(如根據不同的業務型別選用不同的集合及查詢 API)。
(4)主設定參數(日誌,查詢快取,fetch_size, batch_size 等)。
(5)對映檔案優化(ID 生成策略,二級快取,延遲載入,關聯優化)。
(6)一級快取的管理。
(7)針對二級快取,還有許多特有的策略。
(8)事務控制策略。
Dubbo(高效能Java RPC框架)
Dubbo是阿裡巴巴開源的基於 Java 的高效能 RPC 分佈式服務架構,現已成爲 Apache 基金會孵化專案。使用 Dubbo 可以將核心業務抽取出來,作爲獨立的服務,逐漸形成穩定的服務中心,可用於提高業務複用靈活擴充套件,使前端應用能更快速的響應多變的市場需求。
Dubbo 的容錯機制 機製有哪些。
Dubbo 官網提出總共有六種容錯策略:
1)Failover Cluster 模式
失敗自動切換,當出現失敗,重試其它伺服器。(預設)
2)Failfast Cluster
快速失敗,只發起一次呼叫,失敗立即報錯。 通常用於非冪等性的寫操作,比如新增記錄。
3)Failsafe Cluster
失敗安全,出現異常時,直接忽略。 通常用於寫入審計日誌等操作。
4)Failback Cluster
失敗自動恢復,後臺記錄失敗請求,定時重發。 通常用於訊息通知操作。
5)Forking Cluster
並行呼叫多個伺服器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過 forks=」2」來設定最大並行數。
6)Broadcast Cluster
廣播呼叫所有提供者,逐個呼叫,任意一臺報錯則報錯。(2.1.0 開始支援) 通常用於通知所有提供者更新快取或日誌等本地資源資訊。
總結: 在實際應用中查詢語句容錯策略建議使用預設 Failover Cluster ,而增刪改建議使用 Failfast Cluster 或 者 使用 Failover Cluster(retries=」0」) 策略 防止出現數據 重複新增等等其它問題!建議在設計介面時候把查詢介面方法單獨做一個介面提供查詢。
Dubbo 的連線方式有哪些?
Dubbo 的用戶端和伺服器端有三種連線方式,分別是:廣播,直連和使用 zookeeper 註冊中心。
Netty(Netty是由JBOSS提供的一個java開源框架)
Netty 是由 JBOSS 提供的一個開源的、非同步的、基於事件驅動的網路通訊框架,用 Netty 可以快速開發高效能、高可靠性的網路伺服器和用戶端程式,Netty 簡化了網路應用的程式設計開發過程,使開發網路程式設計變得異常簡單。
Shiro(安全框架)
Apache Shiro是一個強大而靈活的開源安全框架,它乾淨利落地處理身份認證,授權,企業對談管理和加密。
三個核心元件:Subject, SecurityManager 和 Realms。
Subject:即「當前操作使用者」。但是,在 Shiro 中,Subject 這一概念並不僅僅指人,也可以是第三方進程、後臺帳戶(Daemon Account)或其他類似事物。它僅僅意味着「當前跟軟體互動的東西」。但考慮到大多數目的和用途,你可以把它認爲是 Shiro 的「使用者」概念。
Subject 代表了當前使用者的安全操作,SecurityManager 則管理所有使用者的安全操作。
SecurityManager:它是 Shiro 框架的核心,典型的 Facade 模式,Shiro 通過 SecurityManager 來管理內部元件範例,並通過它來提供安全管理的各種服務。
Realm: Realm 充當了 Shiro 與應用安全數據間的「橋樑」或者「聯結器」。也就是說,當對使用者執行認證(登錄)和授權(存取控制)驗證時,Shiro 會從應用設定的 Realm 中查詢使用者及其許可權資訊。
Shiro 主要的四個元件
1)SecurityManager
典型的 Facade,Shiro 通過它對外提供安全管理的各種服務。
2)Authenticator
對「Who are you ?」進行覈實。通常涉及使用者名稱和密碼。 這個元件負責收集 principals 和 credentials,並將它們提交給應用系統。如果提交的 credentials 跟應用系統中提供的 credentials 吻合,就能夠繼續存取,否則需要重新提交 principals 和 credentials, 或者直接終止存取。
3)Authorizer
身份份驗證通過後,由這個元件對登錄人員進行存取控制的篩查,比如「who can do what」, 或者「who can do which actions」。 Shiro 採用「基於 Realm」的方法,即使用者(又稱 Subject)、 使用者組、角 色和permission 的聚合體。 感恩於心,回報於行。 面試寶典系列-Java
4)Session Manager
這個元件保證了異構用戶端的存取,設定簡單。它是基於 POJO/J2SE 的,不跟任何的客戶 端或者協定系結。
Shiro 執行原理
1、Application Code:應用程式程式碼,就是我們自己的編碼,如果在程式中需要進 行許可權控制,需要呼叫Subject 的 API。
2、Subject:主體,代表的了當前使用者。所有的 Subject 都系結到 SecurityManager, 與 Subject 的所有互動都會委託給 SecurityManager,可以將 Subject 當成一個 門面,而真正執行者是 SecurityManager 。
3、SecurityManage:安全管理器,所有與安全有關的操作都會與 SecurityManager 互動,並且它管理所有的 Subject 。
4、Realm:域 shiro 是從 Realm 來獲取安全數據(使用者,角色,許可權)。就是說 SecurityManager 要驗證使用者身份, 那麼它需要從 Realm 獲取相應的使用者進行比較以確定使用者 身份是否合法;也需要從Realm 得到使用者相應的角色/許可權進行驗證使用者是否 能進行操作; 可以把 Realm 看成 DataSource,即安全數據源 。
Ehcache(快取框架)
EhCache 是一個純Java的進程內快取框架,具有快速、精幹等特點,是 Hibernate 中預設的CacheProvider。它使用的是 JVM 的堆記憶體,超過記憶體可以設定快取到磁碟,企業版的可以使用 JVM 堆外的實體記憶體。
Shiro 的四種許可權控制方式
1)url 級別許可權控制
2)方法註解許可權控制
3)程式碼級別許可權控制
4)頁面標籤許可權控制
Quartz(定時任務排程框架)
Quartz 是一個基於 Java 的廣泛使用的開源的任務排程框架,做過定時任務的沒有沒用過這個框架的吧。
組態檔 applicationContext_job.xml 各個屬性作用
(1)、Job:表示一個任務(工作),要執行的具體內容。
(2)、JobDetail:表示一個具體的可執行的排程程式,Job 是這個可執行程排程程式所要執行的內容,另外
JobDetail 還包含了這個任務排程的方案和策略。
(3)、Trigger:代表一個排程參數的設定,什麼時候去調。
(4)、Scheduler:代表一個排程容器,一個排程容器中可以註冊多個 JobDetail 和 Trigger。當 Trigger 與JobDetail 組合,就可以被 Scheduler 容器排程了。
.如何監控 Quartz 的 job 執行狀態:執行中,暫停中,等待中?
通過往表(新建一個操作日誌表)裡插入日誌的形式:
1)執行中:通過 JobListener 監聽器來實現執行時更改表資訊。
2)暫停中:呼叫 scheduler.pauseTrigger()方法時,更改表中 job 資訊。
3)等待中:新新增的 job 預設給其等待中的狀態,也是更改表中的 job 資訊 但是上面這種形式的麻煩之處是得頻繁的往表裏插入數據。
Velocity( Velocity是一個基於Java的模板引擎)
Velocity 是一個基於 Java 的模板引擎,簡單而強大的模板語言爲各種 Web 框架提供模板服務,來適配 MVC 模型。
jQuery(jQuery是一個快速、簡潔的JavaScript框架)
jQuery是一個快速、簡潔的 JavaScript 框架,它封裝 JavaScript 常用的功能程式碼,提供一種簡便的 JavaScript 設計模式,極大地簡化了 JavaScript 程式設計。
JUnit(是一個Java語言的單元測試框架)
JUnit 是一個 Java 語言的單元測試框架,絕大多數 Java 的開發環境都已經整合了 JUnit 作爲其單元測試的工具。
Log4j(日誌)
Log4j 是 Apache 的一個開源日誌框架,通過 Log4j 我們可以將程式中的日誌資訊輸出到控制檯、檔案等來記錄日誌。作爲一個最老牌的日誌框架,它現在的主流版本是 Log4j2。Log4j2是重新架構的一款日誌框架,拋棄了之前 Log4j 的不足,以及吸取了優秀日誌框架 Logback 的設計。
什麼是中介軟體:非底層操作系統軟體,非業務應用軟體,不是直接給終端使用者使用的,不能直接給客戶帶來價值的軟體統稱爲中介軟體。
什麼是訊息中介軟體:關注於數據的發送和接受,利用高效可靠的非同步訊息傳遞機制 機製整合分佈式系統

爲什麼使用訊息中介軟體
訊息中介軟體作用:解耦服務呼叫。松耦合。 使用中介軟體,不用等呼叫的服務處理完才返回結果。提高效率。
 kafka  是一個高吞吐量的分佈式發佈訂閱訊息系統,是一個分佈式的,分割區的,可靠的分佈式日誌儲存服務。(不是一個嚴格訊息中介軟體 ) 
 1)高吞吐量:即使非常普通的硬體kafka也可以支援每秒數百萬的訊息
訊息中介軟體帶來的好處
解耦
非同步
橫向擴充套件
安全可靠
順序保證
等等。。。
什麼是JMS:Java訊息服務(Java Message Service)即JMS,是一個Java平臺中關於訊息導向中介軟體的API,用於在兩個應用程式之間,或分佈式系統中發送訊息,進行非同步通訊。
什麼是AMQP:AMQP(advanced message queuing protocol)是一個提供統一訊息服務的應用層標準協定,基於此協定的用戶端與訊息中介軟體可傳遞訊息,並不接受用戶端/中介軟體不同產品,不同開發語言等條件的限制。
Redis 的特點?
Redis 是由意大利人 Salvatore Sanfilippo(網名:antirez)開發的一款記憶體快取記憶體數據庫。Redis 全稱爲:Remote Dictionary Server(遠端數據服務),該軟體使用 C 語言編寫,典型的 NoSQL 數據庫伺服器,Redis 是一 個 key-value 儲存系統,它支援豐富的數據型別,如:string、list、set、zset(sorted set)、hash。 Redis 本質上是一個 Key-Value 型別的記憶體數據庫,很像 memcached,整個 數據庫統統載入在記憶體當中進 行操作,定期通過非同步操作把數據庫數據 flush 到硬碟 上進行儲存。因爲是純記憶體操作,Redis 的效能非常出色,每秒 可以處理超過 10 萬次讀寫操作,是已知效能最快的 Key-Value DB。
Redis 的出色之處不僅僅是效能,Redis 最大的魅力是支援儲存多種數據結構,此外單 個 value 的最大限制是 1GB,不像 memcached 只能儲存 1MB 的數據,另外 Redis 也可以對存入的 Key-Value 設定 expire 時間。
Redis 的主要缺點是數據庫容量受到實體記憶體的限制,不能用作海量數據的高效能讀寫,因此 Redis 適合的場景主要 侷限在較小數據量的高效能操作和運算上。
爲什麼 redis 需要把所有數據放到記憶體中?
Redis 爲了達到最快的讀寫速度將數據都讀到記憶體中,並通過非同步的方式將數據寫入磁碟。所以 redis 具有快速和 數據持久化的特徵。如果不將數據放在記憶體中,磁碟 I/O 速度爲嚴重影響 redis 的效能。在記憶體越來越便宜的今天, redis 將會越來越受歡迎。如果設定了最大使用的記憶體,則數據已有記錄數達到記憶體限值後不能繼續插入新值。
Redis 最適合的場景有哪些?
(1)、對談快取(Session Cache)
(2)、全頁快取(FPC)
(3)、佇列
(4)、排行榜/計數器
(5)、發佈/訂閱
Redis 有哪幾種數據結構?
Redis 的數據結構有五種,分別是:
String——字串
String 數據結構是簡單的 key-value 型別,value 不僅可以是 String,也可以是數位(當數位型別用 Long 可
以表示的時候 encoding 就是整型,其他都儲存在 sdshdr 當做字串)。
Hash——字典
在 Memcached 中,我們經常將一些結構化的資訊打包成 hashmap,在用戶端序列化後儲存爲一個字串的值
(一般是 JSON 格式),比如使用者的暱稱、年齡、性別、積分等。
List——列表
List 說白了就是鏈表(redis 使用雙端鏈表實現的 List),相信學過數據結構知識的人都應該能理解其結構。
Set——集合
Set 就是一個集合,集合的概念就是一堆不重複值的組合。利用 Redis 提供的 Set 數據結構,可以儲存一些集
合性的數據。
Sorted Set——有序集合
和 Sets 相比,Sorted Sets 是將 Set 中的元素增加了一個權重參數 score,使得集閤中的元素能夠按 score 進
行有序排列,

  1. 帶有權重的元素,比如一個遊戲的使用者得分排行榜
    2.比較複雜的數據結構,一般用到的場景不算太多
    簡單介紹一下 zookeeper
    ZooKeeper 是一個分佈式的,開放原始碼的分佈式應用程式協調服務,是 Google 的 Chubby 一個開源的實現,是 Hadoop 和 Hbase 的重要元件。
    zookeeper 的原理。
    ZooKeeper 是以 Fast Paxos 演算法爲基礎的,Paxos 演算法存在活鎖的問題,即當有多個 proposer 交錯提交時,有可能互相排斥導致沒有一個 proposer 能提交成功,而 Fast Paxos 作了一些優化,通過選舉產生一個 leader (領導者),只有leader 才能 纔能提交 proposer,具體 演算法可見 Fast Paxos。因此,要想弄懂 ZooKeeper 首先得對 Fast Paxos 有所瞭解。

ZooKeeper 的基本運轉流程:
1、選舉 Leader。2、同步數據。3、選舉 Leader 過程中演算法有很多,但要達到的選舉標準是一致的。 4、Leader 要具有最高的執行 ID,類似 root 許可權。 5、叢集中大多數的機器得到響應並 follow 。
選出的 Leader。
簡單介紹一下 solr
Solr 是一個獨立的企業級搜尋應用伺服器,它對外提供類似於 Web-service 的 API 介面。 使用者可以通過 http 請求,向搜尋引擎伺服器提交一定格式的 XML 檔案,生成索引;也可以 通過 Http Get 操作提出查詢請求,並得到XML 格式的返回結果。
solr 特點:
Solr 是一個高效能,採用 Java5 開發,基於 Lucene 的全文搜尋伺服器。同時對其進行 了擴充套件,提供了比Lucene 更爲豐富的查詢語言,同時實現了可設定、可延伸並對查詢效能 進行了優化,並且提供了一個完善的功能管
理介面,是一款非常優秀的全文搜尋引擎。
solr 工作方式:
文件通過 Http 利用 XML 加到一個搜尋集閤中。查詢該集合也是通過 http 收到一個 XML/JSON 響應來實現。它的主要特性包括:高效、靈活的快取功能,垂直搜尋功能,高亮 顯示搜尋結果,通過索引複製來提高可用性,提供一套強大 Data Schema 來定義欄位,類 型和設定文字分析,提供基於 Web 的管理介面等。
solr 怎麼設定搜尋結果排名靠前?
可以設定文件中域的 boost 值,boost 值越高,計算出來的相關度得分就越高,排名也就越靠前。此方法可以把熱點商品或者推廣商品的排名提高。
solr 中 IK 分詞器原理是什麼?
Ik 分詞器的分詞原理本質上是詞典分詞。先在記憶體中初始化一個詞典,然後在分詞過程中挨個讀取字元,和字典中的字元相匹配,把文件中的所有的詞語拆分出來的過程。
Activity 工作流
Activity 什麼是工作流?
現在大多數公司的請假流程是這樣的:員工打電話(或網聊)向上級提出請假申請——上級口頭同 意——上級將請假記錄下來——月底將請假記錄上交公司——公司將請假錄入電腦。採用工作流技術的公司的請假流 程是這樣的:員工使用賬戶登錄系統——點選請假——上級登錄系統點選允許。就這樣,一個請假流程就結束了。有
人會問,那上級不用向公司提交請假記錄?公司不用將記錄錄入電腦?答案是,用的。但是這一切的工作都會在上級 點選允許後自動執行!這就是工作流技術。
Georgakopoulos 給出的工作流定義是: 工作流是將一組任務組織起來以完成某個經營過程:定義了任務的觸 發順序和觸發條件,每個任務可以由一個或多個軟件系統完成,也可以由一個或一組人完成,還可以由一個或多個人 與軟件系統共同作業完。
Activity 工作流技術的優點
從上面的例子,很容易看出,工作流系統實現了工作流程的自動化,提高了企業運營效率、改善企業資源利
用、提高企業運作的靈活性和適應性、提高量化考覈業務處理的效率、減少浪費(時間就是金錢)。而手工處理工
作流程,一方面無法對整個流程狀況進行有效跟蹤、瞭解,另一方面難免會出現人爲的失誤和時間上的延時導致
效率低下,特別是無法進行量化統計,不利於查詢、報表及績效評估。
Activity 工作流生命週期
除了我們自行啓動(start)或者結束(finish)一個 Activity,我們並不能直接控制一個 Activity 的生 命狀態,我們只能通過實現 Activity 生命狀態的表現——即回撥方法來達到管理 Activity 生命週期的變化。
Git
Git是一個開源的分佈式版本控制系統,用於敏捷高效地處理任何或小或大的專案。
Git 是 Linus Torvalds 爲了幫助管理 Linux 內核開發而開發的一個開放原始碼的版本控制軟體。
Git 與常用的版本控制工具 CVS, Subversion 等不同,它採用了分佈式版本庫的方式,不必伺服器端軟體支援。
Git 與 SVN 區別
GIT不僅僅是個版本控制系統,它也是個內容管理系統(CMS),工作管理系統等。
如果你是一個具有使用SVN背景的人,你需要做一定的思想轉換,來適應GIT提供的一些概念和特徵。
Git 與 SVN 區別點:
1、GIT是分佈式的,SVN不是:這是GIT和其它非分佈式的版本控制系統,例如SVN,CVS等,最核心的區別。
2、GIT把內容按元數據方式儲存,而SVN是按檔案:所有的資源控制系統都是把檔案的元資訊隱藏在一個類似.svn,.cvs等的資料夾裡。
3、GIT分支和SVN的分支不同:分支在SVN中一點不特別,就是版本庫中的另外的一個目錄。
4、GIT沒有一個全域性的版本號,而SVN有:目前爲止這是跟SVN相比GIT缺少的最大的一個特徵。
5、GIT的內容完整性要優於SVN:GIT的內容儲存使用的是SHA-1雜湊演算法。這能確保程式碼內容的完整性,確保在遇到磁碟故障和網路問題時降低對版本庫的破壞。