3W+字長文深度總結|Java程序員面試題精華版集合(內附思惟導圖)!

一、在JAVA中如何跳出當前的多重嵌套循環?
在Java中,要想跳出多重循環,能夠在外面的循環語句前定義一個標號,而後在裏層循環體的代碼中使用帶有標號的break語句,便可跳出外層循環。例如,前端

ok: for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println("i=" + i + ",j=" + j);
if (j == 5)
break ok;  
}
}

另外,我我的一般並不使用標號這種方式,而是讓外層的循環條件表達式的結果能夠受到裏層循環體代碼的控制,例如,要在二維數組中查找到某個數字。java

int arr[][] = { { 1, 2, 3 }, { 4, 5, 6, 7 }, { 9 } };
boolean found = false;
for (int i = 0; i < arr.length && !found; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.println("i=" + i + ",j=" + j);
if (arr[i][j] == 5) 
{
found = true;
break;
}
}
}

二、請說出做用域public,private,protected,以及不寫時的區別。nginx

  • private修飾的成員變量和函數只能在類自己和內部類中被訪問。
  • protected 修飾的成員變量和函數能被類自己、子類及同一個包中的類訪問。
  • public修飾的成員變量和函數能夠被類、子類、同一個包中的類以及任意其餘類訪問。

默認狀況(不寫)下,屬於一種包訪問,即能被類自己以及同一個包中的類訪問。
下面這個表能清楚的說明java中做用域操做符的做用:
image.png程序員

三、說說對javaee中的session的理解,你是怎麼用session的?
在servlet 的api中,session表示的是瀏覽器和web服務器的一次會話。在web服務器中是經過session來區別不一樣的瀏覽器的,由於web 服務器採用的是http協議進行通信,web 服務器根本不知道正在請求的瀏覽器是誰,它不會記錄瀏覽器的訪問信息,因此須要session來記錄發出請求的瀏覽器是誰,session 和瀏覽器之間是怎麼保持通訊的呢? 當瀏覽器第一次對一個web站點發出請求後,web服務器按照請求路徑查找資源,並生成一個session,web服務器將查找到的資源做爲響應返回給瀏覽器,在這個響應中會附帶上一個特殊名稱的cookie信息,這個cookie 就是session的id。以後瀏覽器再次發出請求時,會在請求信息中帶上這個cookie信息,這個cookie 的做用就是用來告訴web服務器,我這個瀏覽器已經訪問過你了,你不須要再生成session了。web

Session 的應用有不少面試

  • 1.過濾未登陸用戶
    能夠用於存放用戶信息,當用戶登陸後,就將用戶信息放入session,若是沒有登陸,在session中就不會有用戶信息,這樣就能夠防止未登陸用戶查看一些信息。
  • 2.防止表單重複提交
  • 3.網上商城中的購物車

四、分層設計的好處?
把各個功能按調用流程進行了模塊化,模塊化帶來的好處就是能夠隨意組合。分層的好處:ajax

  • 1.實現了軟件之間的解耦
  • 2.便於進行分工
  • 3.便於維護
  • 4.提升軟件組件的重用
  • 5.便於替換某種產品,好比持久層用的是hibernate,須要更換產品爲mybatis,就不用改其餘業務的代碼,直接把配置一改便可
  • 6.便於產品功能的擴展
  • 7.便於適用用戶需求的不斷變化

五、java中實現多態的機制是什麼?redis

靠的是父類或接口定義的引用變量能夠指向子類或具體實現類的實例對象,而程序調用的方法在運行期才動態綁定,就是引用變量所指向的具體實例對象的方法,也就是內存里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法。spring

六、abstract(抽象類)和interface(接口)有什麼區別?
含有abstract修飾符的class即爲抽象類,abstract 類不能建立的實例對象。含有abstract方法的類必須定義爲abstract class,abstract class類中的方法沒必要是抽象的。abstract class類中定義抽象方法必須在具體(Concrete)子類中實現,因此,不能有抽象構造方法或抽象靜態方法。若是子類沒有實現抽象父類中的全部抽象方法,那麼子類也必須定義爲abstract類型。sql

接口(interface)能夠說成是抽象類的一種特例,接口中的全部方法都必須是抽象的。接口中的方法定義默認爲public abstract類型,接口中的成員變量類型默認爲public static final。
下面比較一下二者的語法區別:

  • 1.抽象類能夠有構造方法,接口中不能有構造方法。
  • 2.抽象類中能夠有普通成員變量,接口中沒有普通成員變量
  • 3.抽象類中能夠包含非抽象的普通方法,接口中的全部方法必須都是抽象的,不能有非抽象的普通方法。
  • 4.抽象類中的抽象方法的訪問類型能夠是public,protected和默認類型,但接口中的抽象方法只能是public類型的,而且默認即爲public abstract類型。
  • 5.抽象類中能夠包含靜態方法,接口中不能包含靜態方法
  • 6.抽象類和接口中均可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型能夠任意,但接口中定義的變量只能是public static final類型,而且默認即爲public static final類型。
  • 7.一個類能夠實現多個接口,但只能繼承一個抽象類。

七、構造方法Constructor是否可被override(重寫)?
構造方法Constructor不能被繼承,所以不能重寫Override,但能夠被重載Overload。

八、面向對象的特徵有哪些方面?
面向對象的三大特徵:

  • 封裝:保證對象自身數據的完整性和安全性。
  • 繼承:創建類之間的關係,實現代碼複用,方便系統的擴展。
  • 多態:相同的方法調用,能夠實現不一樣的實現方式。

九、String是最基本的數據類型嗎,是否能夠繼承String類?
java的基本數據類型有如下8種:

  • 整型: byte short int long
  • 浮點型: float double
  • 字符型: char
  • 布爾: boolean

java.lang.String類是final類型的,所以不能夠繼承這個類、也不能修改這個類 。爲了提升效率節省空間,對於要常常修改的字符串,建議使用StringBuffer類。

十、數組有沒有length()這個方法? String有沒有length()這個方法?
數組沒有length()這個方法,有length的屬性。
String有length()這個方法。

十一、String s = new String("abc");建立了幾個String Object? 兩者之間有什麼區別?
答案:一個或者兩個
解析:

  • 1.若是String緩衝區中,已經建立"abc",則不會繼續建立,此時只建立了一個對象new String("abc");
  • 2.若是String緩衝區中,沒有建立"abc",則會建立兩個對象,一個對象的值是"abc",一個對象new String("abc")。

十二、下面這條語句一共建立了多少個對象:String s="a"+"b"+"c"+"d"
只建立了一個String對象,由於這行代碼被編譯器編譯時進行了優化,至關於直接定義了一個」abcd」的字符串,因此只建立了一個String對象。

1三、try {}裏有一個return語句,那麼緊跟在這個try後的finally {}裏的code會不會被執行,何時被執行,在return前仍是後?
finally中的代碼確定會執行,可是會先執行try中的代碼,若是try中有return,那麼return的東西會先放到函數棧中,而後再執行finally中的代碼。

  • ①、若是finally中也有return,則會直接返回並終止程序,函數棧中的return不會被完成;
  • ②、若是finally中沒有return,則在執行完finally中的代碼以後,會將函數棧中的try中的return的內容返回並終止程序;

1四、final, finally, finalize的區別

  • Final:是全局變量聲明的時候使用,意思是這個變量不可被修改,不可被override,通常用於聲明常量,或者系統設置的值。
  • finally:是在異常處理時提供finally塊來執行任何清除操做。無論有沒有異常被拋出、捕獲,finally塊都會被執行。
  • finalize:是方法名。java技術容許使用finalize()方法在垃圾收集器將對象從內存中清除出去以前作必要的清理工做。

1五、運行時異常與通常異常有何異同?
Java提供了兩類主要的異常:運行時異常runtime exception和通常異常checked exception

  • 運行時異常runtime exception,咱們能夠不處理。這樣的異常由虛擬機接管。出現運行時異常後,系統會把異常一直往上層拋,一直遇處處理代碼。若是不對運行時異常進行處理,那麼出現運行時異常以後,要麼是線程停止,要麼是主程序終止。
  • 通常異常checked exception,JAVA要求程序員對其進行try catch處理。因此,面對這種異常無論咱們是否願意,只能本身去寫一大堆catch塊去處理可能的異常。

1六、error和exception有什麼區別?

  • Error(錯誤)表示系統級的錯誤和程序沒必要處理的異常,是java運行環境中的內部錯誤或者硬件問題。好比:內存資源不足等。對於這種錯誤,程序基本無能爲力,除了退出運行外別無選擇,它是由Java虛擬機拋出的。
  • Exception(違例)表示須要捕捉或者須要程序進行處理的異常,它處理的是由於程序設計的瑕疵而引發的問題或者在外的輸入等引發的通常性問題,是程序必須處理的。Exception又細分爲運行時異常runtime exception,受檢查異常checked exception(通常異常)。

1七、請寫出你最多見到的5個運行時異常 runtime exception

  • ClassCastException 類型強制轉換異常
  • ClassNotFoundException 類沒找到時,拋出該異常
  • FileNotFoundException 文件未找到異常
  • NullPointerException 空指針異常
  • SQLException 操做數據庫異常
  • ArithmeticException 算術異常
  • IllegalArgumentException 傳遞非法參數異常
  • IndexOutOfBoundsException 下標越界異常
  • NoSuchElementException 方法未找到異常

1八、Java語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally分別表明什麼意義?在try塊中能夠拋出異常嗎?

  • try{}語句塊 中放的是要檢測的java代碼,可能有會拋出異常,也可能會正常執行;
  • catch(異常類型){}塊 是當Java運行時系統接收到try塊中所拋出的異常對象時,會尋找能處理這一異常的catch塊來進行處理(能夠有多個catch塊);
  • finally{}塊 無論系統有沒有拋出異常都會去執行,通常用來釋放資源。除了在以前執行了System.exit(0);
  • throw 用於手動拋出異常。做爲程序員能夠在任意位置手動拋出異常;
  • throws 用於在方法上標識要拋出的異常,拋出的異常交由調用者處理;

1九、ArrayList和Vector、LinkedList的區別?

  • (1)Vector是線程安全的,而ArrayList不是。
  • (2)當存儲空間不足的時候,ArrayList默認增長爲原來的50%,Vector默認增長爲原來的一倍。
  • (3)Vector能夠設置容量增長的參數,而ArrayList不能夠。
  • (4)LinkedList使用雙向鏈表實現存儲,按序號索引數據須要進行前向或後向遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入速度較快。

20、List 和 Map 區別?

  • (1)、List是存儲單列數據的集合,List中存儲的數據是有順序,而且容許重複;
  • (2)、Map是存儲鍵和值這樣的雙列數據的集合,Map中存儲的數據是沒有順序的,其鍵是不能重複的,它的值是能夠有重複的。

2一、List、Map、Set三個接口,存取元素時,各有什麼特色?
List與Set都是單列元素的集合,它們有一個共同的父接口Collection。

  • (1)List表示有前後順序的集合
    存元素:屢次調用add(Object)方法時,每次加入的對象按先來後到的順序排序,也能夠插隊,即調用add(int index,Object)方法,就能夠指定當前對象在集合中的存放位置。
    取元素:
方法1:Iterator接口取得全部,逐一遍歷各個元素
方法2:調用get(index i)來明確說明取第幾個。
  • (2)Set裏面不容許有重複的元素
    存元素:add方法有一個boolean的返回值,當集合中沒有某個元素,此時add方法可成功加入該元素時,則返回true;當集合含有與某個元素equals相等的元素時,此時add方法沒法加入該元素,返回結果爲false。
    取元素:無法說取第幾個,只能以Iterator接口取得全部的元素,再逐一遍歷各個元素。
  • (3)Map是雙列的集合,存放用put方法:put(obj key,obj value),每次存儲時,要存儲一對key/value,不能存儲重複的key,這個重複的規則也是按equals比較相等。
    取元素:用get(Object key)方法根據key得到相應的value。

2二、說出一些經常使用的類,包,接口,請各舉例5個

  • 經常使用的類:
    Object
    Date
    File
    Exception
    Random
    String
    integer
  • 經常使用的包:
    java.io
    java.lang
    java.util
    java.sql
    java.net
  • 經常使用的接口:
    Set
    List
    Map
    Collection
    Runnable
    Session
    Servlet

2三、java中有幾種類型的流?JDK爲每種類型的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?

  • 基於流方向:
    InputStream
    OutputStream
  • 基於字符:
    Reader
    Writer
  • 流和字符之間的配接:
    InputStreamReader
    OutputStreamWriter

2四、字節流與字符流的區別?

  • (1)字節流在操做時自己不會用到緩衝區(內存),是文件自己直接操做的,而字符流在操做時使用了緩衝區,經過緩衝區再操做文件。
  • (2)字節流中,中文可能會亂碼,字符流不會。

2五、什麼是java序列化,如何實現java序列化?或者請解釋Serializable接口的做用。
序列化就是一種用來處理對象流的機制,所謂對象流也就是將對象的內容進行流化。能夠對流化後的對象進行讀寫操做,也可將流化後的對象傳輸於網絡之間。序列化是爲了解決在對對象流進行讀寫操做時所引起的問題。

序列化的實現:將須要被序列化的類實現Serializable接口,而後使用一個輸出流(如:FileOutputStream)來構造一個ObjectOutputStream(對象流)對象,接着,使用ObjectOutputStream對象的writeObject(Object obj)方法就能夠將參數爲obj的對象寫出(即保存其狀態),要恢復的話則用輸入流;

Serializable.只有實現了 serializable和Externalizable接口的類的對象才能被序列化

Java 序列化技術能夠使你將一個對象的狀態寫入一個Byte 流裏,而且能夠從其它地方把該Byte 流裏的數據讀出來,從新構造一個相同的對象。這種機制容許你將對象經過網絡進行傳播,並能夠隨時把對象持久化到數據庫、文件等系統裏。Java的序列化機制是RMI、EJB等技術的技術基礎。用途:利用對象的序列化實現保存應用程序的當前工做狀態,下次再啓動的時候將自動地恢復到上次執行的狀態。

2六、GC是什麼? 爲何要有GC?
GC是垃圾收集的意思,內存處理是編程人員容易出現問題的地方,忘記或者錯誤的內存會致使程序或系統的不穩定甚至崩潰,Java提供的GC功能能夠自動監測對象是否超過做用域從而達到自動回收內存的目的,Java語言沒有提供釋放已分配內存的顯示操做方法。Java程序員不用擔憂內存管理,由於垃圾收集器會自動進行管理。

2七、排序都有哪幾種方法?請用JAVA實現一個冒泡排序。
排序的方法有:

  • 插入排序(直接插入排序、希爾排序)
  • 交換排序(冒泡排序、快速排序)
  • 選擇排序(直接選擇排序、堆排序)
  • 歸併排序
  • 分配排序(箱排序、基數排序)
  • 冒泡排序:
for(int i=0;i<arr.length-1;i++){ //外層循環控制排序趟數  
for(int j=0;j<arr.length-1-i;j++){ //內層循環控制每一趟排序多少次  
if(arr[j]>arr[j+1]){  
int temp=arr[j];  
arr[j]=arr[j+1];  
arr[j+1]=temp;  
}  
}  
}

冒泡排序口訣:

  • 1. N個數字來排隊,兩兩相比小靠前。
  • 2. 外層循環N-1,內層循環N-1-i
  • 3. 若是要降序,只要把程序中的大於號換成小於號。

2八、說一說Servlet的生命週期?
servlet的生命週期分爲如下幾個步驟:

  • 第1、加載並實例化
  • 第2、初始化
  • 第3、服務
  • 第4、銷燬

容器啓動的時候,會加載servlet的class,並new出這個對象,而後,當用戶請求這個servlet的時候,容器會調用init方法初始化這個servlet,這也是整個生命週期中只會調用一次的方法,而後,會調用service方法,由這個方法調用doGet或doPost方法來響應用戶,而後,容器在可用資源緊張或是長期沒有對Servlet發出請求的狀況下,會銷燬這個servlet。

2九、servlet api中forward() 與redirect()的區別?

  • (1)forward僅是容器中控制權的轉向,在客戶端瀏覽器地址欄中不會顯示出轉向後的地址;
  • (2)redirect則是徹底的跳轉,瀏覽器將會獲得跳轉的地址,並從新發送請求連接。這樣,從瀏覽器的地址欄中能夠看到跳轉後的連接地址。因此,forward更加高效,在forward能夠知足須要時,儘可能使用forward()方法,而且,這樣也有助於隱藏實際的連接。但在某些狀況下(好比須要跳轉到另外一個服務器上的資源),則必須使用sendRedirect()方法。
  • (3)forward:轉發頁面和轉發到的頁面能夠共享request裏面的數據.
  • (4)redirect:不能共享數據

30、request.getAttribute() 和 request.getParameter() 有何區別?

  • (1)request.getParameter 是用來接收post、get方法傳遞過來的參數值
  • (2)request.getAttribute 是獲取對象容器(session)的值
  • (3)request.getParameter()方法返回String類型的數據。
  • (4)request.getAttribute()方法返回的是request範圍內存在的對象。

3一、jsp有哪些經常使用內置對象?

  • <1>、request
  • <2>、response
  • <3>、session
  • <4>、out
  • <5>、page
  • <6>、application
  • <7>、exception
  • <8>、pageContext
  • <9>、config

3二、JSP和Servlet有哪些相同點和不一樣點,他們之間的聯繫是什麼?

  • ①、JSP是Servlet技術的擴展,本質上是Servlet的簡易方式,更強調應用的外表表達,JSP編譯後是」類servlet」。
  • ②、JSP是Java和HTML組合成的一個擴展名爲.jsp的文件。JSP側重於視圖,Servlet主要用於控制邏輯。
  • ③、Servlet和JSP最主要的不一樣點在於,Servlet的應用邏輯是在Java文件中,而且徹底從表示層中的HTML裏分離開來。

3三、MVC的各個部分都有哪些技術來實現?
MVC 是 Model-View-Controller 的簡寫,經過這種設計模型把應用邏輯、處理過程和顯示邏輯分紅不一樣的組件實現。

  • (1)模型(Model)表明的是應用的業務邏輯( 經過JavaBean, EJB 組件實現)
  • (2)視圖(View)是應用的表示面( 由 JSP 頁面產生)
  • (3)控制器(controller) 是提供應用的處理過程控制( 通常是一個 Servlet)

3四、數據庫三範式是什麼?

  • 第一範式:確保每一列的原子性
    (原子性字段不可再分,不然就不是關係型數據庫)
  • 第二範式:在第一範式的基礎上更進一層,確保表中的每列都和主鍵相關
    (惟一性,一個表只說明一個事物)
  • 第三範式:在第二範式的基礎上更進一層,確保每列都和主鍵列直接相關,而不是間接相關
    (每列都與主鍵有直接關係,不存在傳遞依賴)

3五、說出一些數據庫優化方面的經驗?

  • 1.用索引提升效率,避免在索引列上使用計算。
  • 2.SELECT子句中避免使用‘ * ‘
  • 3.減小訪問數據庫的次數
  • 4.儘可能多使用COMMIT
  • 5.用Where子句替換HAVING子句
  • 6.用EXISTS替代IN、用NOT EXISTS替代NOT IN
  • 7.使用表的別名(Alias)
  • 8.避免使用耗費資源的操做
  • 9.用 PreparedStatement 通常來講比 Statement 性能高
  • 10.有外鍵約束會影響插入和刪除性能, 若是程序可以保證數據的完整性, 那在設計數據庫時就去掉外鍵
  • 11.要查詢的數據多時,使用分頁進行查詢
  • 12.儘可能不用ORDER BY RAND()
  • 13.利用查詢緩存來優化查詢
  • 14.儘可能不使用NOT IN和like語句操做

3六、Class.forName的做用是什麼?

  • Class.forName(xxx.xx.xx) 返回的是一個類,Java裏面任何class都要裝載在虛擬機上才能運行,這句話就是裝載類用的。
  • Class.forName(xxx.xx.xx)的做用是要求JVM查找並加載指定的類,也就是說JVM會執行該類的靜態代碼段,動態加載和建立Class對象,最熟悉的就是JDBC鏈接數據庫的時候加載驅動類。

3七、說說數據鏈接池的工做機制是什麼?
J2EE服務器啓動時會創建必定數量的池鏈接,並一直維持很多於此數目的池鏈接。客戶端程序須要鏈接時,池驅動程序會返回一個未使用的池鏈接並將其標記爲忙。若是當前沒有空閒鏈接,池驅動程序就新建必定數量的鏈接,新建鏈接的數量由配置參數決定。當使用的池鏈接調用完成後,池驅動程序將此鏈接標記爲空閒,其餘調用就能夠使用這個鏈接。

3八、爲何要用ORM? 和JDBC有何不同?

  • 對象關係映射(Object Relational Mapping,簡稱ORM)模式是一種爲了解決面向對象與關係數據庫存在的互不匹配現象的技術。簡單的說,ORM是經過使用描述對象和數據庫之間映射的元數據,將程序中的對象自動持久化到關係數據庫中。
  • ORM是一種思想,就是把object轉變成數據庫中的記錄,或者把數據庫中的記錄轉變成object,咱們能夠用jdbc來實現這種思想,其實,若是咱們的項目是嚴格按照oop方式編寫的話,咱們的jdbc程序無論是有意仍是無心,就已經在實現ORM的工做了。
  • 如今有許多ORM工具,它們底層調用jdbc來實現了ORM工做,咱們直接使用這些工具,就省去了直接使用jdbc的繁瑣細節,提升了開發效率,如今用的較多的ORM工具是hibernate。

3九、xml有哪些解析技術?區別是什麼?

xml有如下2種解析技術:
  • (1)DOM(Document Object Model)文檔對象模型
  • (2)SAX(Simple API for XML)

二者的區別:DOM是一次性將整個文檔讀入內存操做,若是是文檔比較小,讀入內存,能夠極大提升操做的速度,但若是文檔比較大,那麼DOM就比較吃力了。因此此時SAX應用而生,它不是一次性的將整個文檔讀入內存,這對於處理大型文檔就比較給力了。

40、談談你對Struts的理解。

  • Struts框架是對MVC模式的封裝,爲開發者提供了MVC的3個邏輯組成部分,主要由ActionServlet、Action和struts-config.xml配置文件組成控制層,由ActionForm來承擔模型層的功能,而struts 的視圖層主要由jsp完成;
  • 它處理一次請求的流程:由ActionServlet接受一個請求,而後依據配置文件來判斷由哪一個Action來處理和由哪一個ActionForm來保存數據,再經過Action的返回值來判斷應該由哪一個jsp來展現數據。

4一、Struts優缺點
優勢:

  • (1) 實現了MVC模式,層次結構清晰,使程序員只需關注業務邏輯的實現。
  • (2) 豐富的標籤庫,大大提升了開發的效率。
  • (3) Struts2提供豐富的攔截器實現。
  • (4) 經過配置文件,就能夠掌握整個系統各個部分之間的關係。
  • (5) 異常處理機制,只需在配置文件中配置異常的映射,便可對異常作相應的處理。
  • (6) Struts2的可擴展性高。Struts2的核心jar包中由一個struts-default.xml文件,在該文件中設置了一些默認的bean,resultType類型,默認攔截器棧等,全部這些默認設置,用戶均可以利用配置文件更改,能夠更改成本身開發的bean,resulttype等。所以用戶開發了插件的話只要很簡單的配置就能夠很容易的和Struts2框架融合,這實現了框架對插件的可插拔的特性。
  • (7) 面向切面編程的思想在Strut2中也有了很好的體現,最重要的體現就是攔截器的使用。攔截器就是一個一個的小功能單位,用戶能夠將這些攔截器合併成一個大的攔截器,這個合成的攔截器就像單獨的攔截器同樣,只要將它配置到一個、Action中就能夠

缺點:

  • (1) Struts2中Action中取得從jsp中傳過來的參數時仍是有點麻煩。能夠爲Struts2的Action中的屬性配置上Getter和Setter方法,經過默認攔截器,就能夠將請求參數設置到這些屬性中。若是用這種方式,當請求參數不少時,Action類就會被這些表單屬性弄的很臃腫,讓人感受會很亂。還有Action中的屬性不但能夠用來得到請求參數還能夠輸出到Jsp中,這樣就會更亂。假設從JSP1中得到了參數money=100000,可是這個Action還要輸出到JSP2中,可是輸出的格式卻不一樣,money=100,000,這樣這個Action中的money中的值就變了。
  • (2) 校驗仍是感受比較繁瑣,太煩亂,也太細化了,若是校驗出錯的只能給用戶提示一些信息。若是有多個字段,每一個字段出錯時返回到不一樣的畫面,這個功能在Strut2框架下藉助框架提供的校驗邏輯就不容易實現。
  • (3) 安全性有待提升。Struts2曝出2個高危安全漏洞,一個是使用縮寫的導航參數前綴時的遠程代碼執行漏洞,另外一個是使用縮寫的重定向參數前綴時的開放式重定向漏洞。這些漏洞可以使黑客取得網站服務器的「最高權限」,從而使企業服務器變成黑客手中的「肉雞」

4二、談談你對Spring的理解。
首先Spring是一個開源的框架,Spring爲簡化企業級應用開發而生,使用Spring能夠使簡單的JavaBean實現之前只有EJB才能實現的功能。Spring是一個IOC和AOP容器框架。

在java開發領域,Spring相對於EJB來講是一種輕量級的,非侵入性的Java開發框架。

Spring主要核心是:

  • (1).控制反轉(IOC):之前傳統的java開發模式中,當須要一個對象時咱們,咱們會本身使用new或者getInstance等直接或者間接調用構造方法建立一個對象,而在Spring開發模式中,Spring容器使用了工廠模式爲咱們建立了所須要的對象,咱們使用時不須要本身去建立,直接調用Spring爲咱們提供的對象便可,這就是控制反轉的思想。實例化一個java對象有三種方式:使用類構造器,使用靜態工廠方法,使用實例工廠方法,當使用spring時咱們就不須要關心經過何種方式實例化一個對象,spring經過控制反起色制自動爲咱們實例化一個對象。
  • (2).依賴注入(DI):Spring使用java Bean對象的Set方法或者帶參數的構造方法爲咱們在建立所需對象時將其屬性自動設置所須要的值的過程就是依賴注入的基本思想。
  • (3).面向切面編程(AOP):在面向對象編程(OOP)思想中,咱們將事物縱向抽象成一個個的對象。而在面向切面編程中,咱們將一個個對象某些相似的方面橫向抽象成一個切面,對這個切面進行一些如權限驗證,事物管理,記錄日誌等公用操做處理的過程就是面向切面編程的思想。

4三、AOP的做用是什麼?
AOP(面向切面編程)是一種編程範式,用於提供從另外一角度來考慮程序結構以完善面向對象編程。

主要做用:

  • 1.下降模塊之間的耦合度。
  • 2.使系統容易擴展。
  • 3.更好的代碼複用

4四、談談你對Hibernate的理解。
Hibernate是一個開放源代碼的對象關係映射(ORM)框架,它對JDBC進行了很是輕量級的對象封裝,使得java程序員能夠爲所欲爲的使用對象編程思惟來操縱數據庫。

Hibernate的優勢:

  • 1. 對JDBC訪問數據庫的代碼作了封裝,大大簡化了數據訪問層繁瑣的重複性代碼。
  • 2. Hibernate是一個基於JDBC的主流持久化框架,是一個優秀的ORM實現。他很大程度的簡化DAO層的編碼工做
  • 三、 Hibernate使用Java反射機制而不是字節碼加強程序來實現透明性。
  • 四、 Hibernate的性能好,映射的靈活性比較出色。它支持各類關係數據庫,從一對一到多對多的各類複雜關係。

hibernate的核心類:
Configuration、SessionFactory 、Session

4五、hibernate中的update()和saveOrUpdate()的區別

  • update() 若是是對一個已經存在的託管對象進行更新那麼確定是要使用update()方法了,數據中有這個對象。
  • saveOrUpdate() 這個方法是更新或者插入,有主鍵就執行更新,若是沒有主鍵就執行插入。

4六、簡述 Hibernate 和 JDBC 的優缺點?

  • (1)JDBC與Hibernate在性能上相比,JDBC靈活性有優點。
  • (2)而Hibernate在易學性,易用性上有優點。
  • (3)當用到不少複雜的多表聯查和複雜的數據庫操做時,JDBC有優點。

4七、Hibernate中,如何書寫一個 one to many 配置文件?
one to many 配置文件的方法:
在一方添加集合對象,並封裝。而後在對應的映射文件追加標籤,設置外檢,以及經過one-to-many標籤設置集合對象所對應的類型便可。

4八、MyBatis與Hibernate有什麼不一樣?
Mybatis優點:

  • (1)MyBatis能夠進行更爲細緻的SQL優化,能夠減小查詢字段。
  • (2)MyBatis容易掌握,而Hibernate門檻較高。

Hibernate優點:

  • <1>、Hibernate的DAO層開發比MyBatis簡單,Mybatis須要維護SQL和結果映射。
  • <2>、Hibernate對對象的維護和緩存要比MyBatis好,對增刪改查的對象的維護要方便。
  • <3>、Hibernate數據庫移植性很好,MyBatis的數據庫移植性很差,不一樣的數據庫須要寫不一樣SQL。
  • <4>、Hibernate有更好的二級緩存機制,能夠使用第三方緩存。MyBatis自己提供的緩存機制不佳。

4九、hibernate的inverse屬性有什麼做用?

  • 用來指定關聯的控制方的,inverse屬性默認是false:
  • 若爲false,則關聯由本身控制
  • 若爲true,則關聯由對方控制

50、介紹一下Hibernate的二級緩存
內置緩存:Hibernate自帶的,不可卸載,一般在Hibernate的初始化階段,Hibernate會把映射元數據和預約義的SQL語句放置到SessionFactory的緩存中。該內置緩存是隻讀的。

外置緩存:一般說的二級緩存也就是外置緩存,在默認狀況下SessionFactory不會啓用這個緩存插件,外置緩存中的數據是數據庫數據的複製,外置緩存的物理介質能夠是內存或者硬盤。

適合放入二級緩存中數據:
  • 不多被修改
  • 不是很重要的數據,容許出現偶爾的併發問題
  • 不適合放入二級緩存中的數據
  • 常常被修改
  • 財務數據,絕對不容許出現併發問題
  • 與其餘應用數據共享的數據

5一、session中load()和get()的區別

  • (1)load方法支持延遲加載,而get方法則不支持。
  • (2)load方法在沒找到數據的時候會拋出ObjectNotFoundException,而get方法則會返回null。

5二、B/S與C/S的聯繫與區別

(1)c/s(client/server)客戶端/服務器

概念:指的是客戶端和服務端之間的通訊方式,客戶端提供用戶請求接口,服務端響應請求進行對應的處理,並返回給客戶端,客戶端來顯示這些內容
協議:任何通用協議
優點:下降系統開銷,充分利用兩端硬件環境的優點
缺點:維護成本高

(2)B/S(browser/server) 瀏覽器/服務器

概念:這種結構用戶界面是徹底經過www瀏覽器來實現,一部分事務在前端實現,主要事務邏輯在服務器端實現
協議:http協議
優點:節約開發成本

二者區別:

硬件環境不一樣:

  • c/s:專用網絡、小型局域網
  • b/s:廣域網,只有要操做系統和瀏覽器就行

對安全要求不一樣:

  • c/s:通常面向固定用戶羣,安全性高
  • b/s:用b/s發佈部分可公開信息

對程序架構不一樣:

  • c/s:注重流程,對權限屢次校驗,少考慮系統運行速度
  • b/s:對安全和訪問速度多重考慮

軟件重用不一樣:

  • c/s:須要總體考慮,構建重用性沒有b/s好
  • b/s:構件獨立,重用性好

系統維護不一樣:

  • c/s:要從總體考察,維護困難
  • b/s:構件個別替換,維護升級簡單

處理問題不一樣:

  • c/s:用戶面固定,安全性高,操做系統相同
  • b/s:用戶不固定,與操做平臺關係小

用戶接口不一樣:

  • c/s:Windows平臺上,表現方法有限
  • b/s:瀏覽器,表現方式生動,難度減低,減低開發成本

信息流不一樣:

  • c/s:中央集權機械式管理,交互低
  • b/s:信息流可變化,更像交易中心

5三、Spring MVC Framework有那些特色?

  • 1.它是基於組件技術的,所有的應用對象,不管控制器和視圖,仍是業務對象之類的都是java組件,而且和Spring提供的其餘基礎結構緊密集成。
  • 2.不依賴於Servlet API(目標雖是如此,可是在實現的時候確實是依賴於Servlet的)
  • 3.能夠任意使用各類視圖技術,而不只僅侷限於JSP
  • 4.支持各類請求資源的映射策略
  • 5.它應是易於擴展的

5四、SpringMVC的工做流程?

  • 1. 用戶發送請求至前端控制器DispatcherServlet
  • 2. DispatcherServlet收到請求調用HandlerMapping處理器映射器。
  • 3. 處理器映射器根據請求url找到具體的處理器,生成處理器對象及處理器攔截器(若是有則生成)一併返回給DispatcherServlet。
  • 4. DispatcherServlet經過HandlerAdapter處理器適配器調用處理器
  • 5. 執行處理器(Controller,也叫後端控制器)。
  • 6. Controller執行完成返回ModelAndView
  • 7. HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet
  • 8. DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器
  • 9. ViewReslover解析後返回具體View
  1. DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中)。
  1. DispatcherServlet響應用戶

5五、簡單介紹下springMVC和struts2的區別有哪些?

  • 1. springmvc的入口是一個servlet即前端控制器,而struts2入口是一個filter過慮器。
  • 2. springmvc是基於方法開發(一個url對應一個方法),請求參數傳遞到方法的形參,能夠設計爲單例或多例(建議單例),struts2是基於類開發,傳遞參數是經過類的屬性,只能設計爲多例。
  • 3. Struts採用值棧存儲請求和響應的數據,經過OGNL存取數據,springmvc經過參數解析器是將request請求內容解析,並給方法形參賦值,將數據和視圖封裝成ModelAndView對象,最後又將ModelAndView中的模型數據經過reques域傳輸到頁面。Jsp視圖解析器默認使用jstl。

5六、請介紹線程的五種狀態

  • 第1、建立狀態。在生成線程對象,並無調用該對象的start方法,這是線程處於建立狀態手寫字符串反轉和冒泡排序;
  • 第2、就緒狀態。當調用了線程對象的start方法以後,該線程就進入了就緒狀態,可是此時線程調度程序尚未把該線程設置爲當前線程,此時處於就緒狀態。在線程運行以後,從等待或者睡眠中回來以後,也會處於就緒狀態。
  • 第3、運行狀態。線程調度程序將處於就緒狀態的線程設置爲當前線程,此時線程就進入了運行狀態,開始運行run函數當中的代碼。
  • 第4、阻塞狀態。線程正在運行的時候,被暫停,一般是爲了等待某個時間的發生(好比說某項資源就緒)以後再繼續運行。sleep,suspend,wait等方法均可以致使線程阻塞。
  • 第5、死亡狀態。若是一個線程的run方法執行結束或者調用stop方法後,該線程就會死亡。對於已經死亡的線程,沒法再使用start方法令其進入就緒

5七、post提交方式和get提交方式的區別

Get 方法經過 URL 請求來傳遞用戶的數據,將表單內各字段名稱與其內容,以成對的字符串鏈接,以URL字串自己傳遞數據參數,在服務器端能夠從'QUERY_STRING'這個變量中直接讀取,效率較高,但缺少安全性,也沒法來處理複雜的數據(只能是字符串,好比在servlet/jsp中就沒法處理髮揮java的好比vector之類的功能,輸的數據量很是小,通常限制在 2 KB 左右);

Post 方法經過 HTTP post 機制,將表單內各字段名稱與其內容放置在 HTML 表頭(header)內一塊兒傳送給服務器端交由 action 屬性能所指的程序處理,該程序會經過標準輸入(stdin)方式,將表單的數據讀出並加以處理post方式:就傳輸方式講參數會被打包在數據報中傳輸,從CONTENT_LENGTH這個環境變量中讀取,便於傳送較大一些的數據,同時由於不暴露數據在瀏覽器的地址欄中,安全性相對較高,但這樣的處理效率會受到影響。

建議:除非你確定你提交的數據能夠一次性提交,不然請儘可能用 Post方法;Get方式提交數據,會帶來安全問題;經過 Get 方式提交數據時,用戶名和密碼將出如今 URL 上;因此表單提交建議使用Post。

5八、什麼是數據庫髒讀,不可重複讀,幻覺讀
髒讀又稱無效數據讀出。一個事務讀取另一個事務尚未提交的數據叫髒讀。
例如:事務T1修改了一行數據,可是尚未提交,這時候事務T2讀取了被事務T1修改後的數據,以後事務T1由於某種緣由Rollback了,那麼事務T2讀取的數據就是髒的不可重複讀是指在同一個事務內,兩個相同的查詢返回了不一樣的結果。
例如:事務T1讀取某一數據,事務T2讀取並修改了該數據,T1爲了對讀取值進行檢驗而再次讀取該數據,便獲得了不一樣的結果。

幻覺讀是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的所有數據行,同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼,之後就會發生操做第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺同樣。例如:系統管理員A將數據庫中全部學生的成績從具體分數改成ABCDE等級,可是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺同樣,這就叫幻讀。

5九、請介紹spring的事務隔離級別

  • (1)Default默認的事務隔離級別
  • (2)READ_UNCOMMITTED(read_uncommitted)讀未提交,一個事務能夠操做另一個未提交的事務,不能避免髒讀,不可重複讀,幻覺讀,隔離級別最低,併發性能最高
  • (3)READ_COMMITTED(read_committed)讀已提交,一個事務不能夠操做另一個未提交的事務, 能防止髒讀,不能避免不可重複讀,幻覺讀。
  • (4)REPEATABLE_READ(repeatable_read)可以避免髒讀,不可重複讀,不能避免幻讀
  • (5)SERIALIZABLE(serializable)隔離級別最高,消耗資源最低,代價最高,可以防止髒讀, 不可重複讀,幻覺讀

60、默寫選擇排序

public static void selectSort(int[] a) {  
int minIndex = 0;  
int temp = 0;  
if ((a == null) || (a.length == 0))  
return;  
for (int i = 0; i < a.length - 1; i++) {  
minIndex = i;// 無序區的最小數據數組下標  
for (int j = i + 1; j < a.length; j++) {  
// 在無序區中找到最小數據並保存其數組下標  
if (a[j] < a[minIndex]) {  
minIndex = j;  
        }  
     }  
// 將最小元素放到本次循環的前端  
temp = a[i];  
a[i] = a[minIndex];  
a[minIndex] = temp;  
   }  
}

6一、session和cooie的區別
具體來講cookie機制採用的是在客戶端保持狀態的方案,而session 機制採用的是在服務器端保持狀態的方案。因爲服務器端保持狀態的方案在客戶端也須要保存一個標識,因此session機制須要藉助於cookie機制來達到保存標識的目的 。

6二、什麼是Spring IOC 容器?
Spring IOC 負責建立對象,管理對象(經過依賴注入(DI),裝配對象,配置對象,而且管理這些對象的整個生命週期。

6三、spring有哪些不一樣類型的IOC(依賴注入)方式?
構造器依賴注入:構造器依賴注入經過容器觸發一個類的構造器來實現的,該類有一系列參數,每一個參數表明一個對其餘類的依賴。
Setter方法注入:Setter方法注入是容器經過調用無參構造器或無參static工廠 方法實例化bean以後,調用該bean的setter方法,即實現了基於setter的依賴注入

6四、 Spring支持哪幾種bean的做用域?

  • singleton :bean在每一個Spring ioc 容器中只有一個實例。
  • prototype:一個bean的定義能夠有多個實例。
  • request:每次http請求都會建立一個bean,該做用域僅在基於web的Spring ApplicationContext情形下有效。
  • session:在一個HTTP Session中,一個bean定義對應一個實例。該做用域僅在基於web的Spring ApplicationContext情形下有效。
  • global-session:在一個全局的HTTP Session中,一個bean定義對應一個實例。該做用域僅在基於web的Spring ApplicationContext情形下有效。

6五、j2ee經常使用的設計模式有哪些,簡單說一下工廠模式
Java中的23種設計模式:
Factory(工廠模式), Builder(建造模式), Factory Method(工廠方法模式),Prototype(原始模型模式),Singleton(單例模式), Facade(門面模式),Adapter(適配器模式), Bridge(橋樑模式), Composite(合成模式),Decorator(裝飾模式), Flyweight(享元模式), Proxy(代理模式),Command(命令模式), Interpreter(解釋器模式), Visitor(訪問者模式),Iterator(迭代子模式), Mediator(調停者模式), Memento(備忘錄模式),Observer(觀察者模式), State(狀態模式), Strategy(策略模式),Template Method(模板方法模式), Chain Of Responsibleity(責任鏈模式)

工廠模式:工廠模式是一種常常被使用到的模式,根據工廠模式實現的類能夠根據提供的數據生成一組類中某一個類的實例,一般這一組類有一個公共的抽象父類而且實現了相同的方法,可是這些方法針對不一樣的數據進行了不一樣的操做。首先須要定義一個基類,該類的子類經過不一樣的方法實現了基類中的方法。而後須要定義一個工廠類,工廠類能夠根據條件生成不一樣的子類實例。當獲得子類的實例後,開發人員能夠調用基類中的方法而沒必要考慮到底返回的是哪個子類的實例

6六、談談你對數據庫事務的理解?
在數據庫中,所謂事務是指一組邏輯操做單元即一組sql語句。當這個單元中的一部分操做失敗,整個事務回滾,只有所有正確才完成提交。判斷事務是否配置成功的關鍵點在於出現異常時事務是否會回滾,在JDBC中,事務默認是自動提交的,每次執行一個SQL語句時,若是執行成功,就會向數據庫自動提交,而不能回滾。
事務的特徵(ACID屬性):

  • 1.原子性(Atomicity)
    原子性是指事務是一個不可分割的工做單位,事務中的操做要麼都發生,要麼都不發生。
  • 2.一致性(Consistency)
    事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態。(數據不被破壞)
  • 3.隔離性(Isolation)
    事務的隔離性是指一個事務的執行不能被其餘事務干擾.
  • 4.持久性(Durability)
    持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的.即便系統重啓也不會丟失.

6七、談談你對數據庫索引的理解
一、索引的概念
索引就是爲了提升數據的檢索速度。數據庫的索引相似於書籍的索引。在書籍中,索引容許用戶沒必要翻閱完整個書就能迅速地找到所須要的信息。在數據庫中,索引也容許數據庫程序迅速地找到表中的數據,而沒必要掃描整個數據庫.
二、索引的優勢

a.建立惟一性索引,保證數據庫表中每一行數據的惟一性
b.大大加快數據的檢索速度,這也是建立索引的最主要的緣由
c.減小磁盤IO(向字典同樣能夠直接定位)

三、索引的缺點

a.建立索引和維護索引要耗費時間,這種時間隨着數據量的增長而增長
b.索引須要佔用額外的物理空間
c.當對錶中的數據進行增長、刪除和修改的時候,索引也要動態的維護,下降了數據的維護速度

6八、jdbc操做數據庫的步驟
①、加載數據庫驅動程序 Class.forName("數據庫驅動類");
②、鏈接數據庫 Connection con = DriverManager.getConnection();
③、操做數據庫 PreparedStatement stat = con.prepareStatement(sql);stat.executeQuery();
④、關閉數據庫,釋放鏈接 con.close();

6九、介紹下樂觀鎖,悲觀鎖

  • 樂觀鎖(Optimistic Lock), 每次去查詢數據的時候都認爲別人不會修改,因此不會上鎖,可是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,能夠使用版本號,時間戳等機制。樂觀鎖適用於多讀的應用類型,這樣能夠提升吞吐量
  • 悲觀鎖(Pessimistic Lock), 每次去查詢數據的時候都認爲別人會修改,因此每次在查詢數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖。傳統的關係型數據庫裏邊就用到了這種鎖機制,好比經過select ….for update進行數據鎖定。

70、你對ajax是怎麼理解的

  • AJAX全稱爲「Asynchronous JavaScript and XML」(異步JavaScript和XML),是一種建立交互式網頁應用的網頁開發技術。
  • 使用ajax能夠提升用戶的體驗度,進行異步數據傳輸從而提升性能。ajax不能跨域,所謂不能跨域就是不能跨多個網站(多個域名),或者多個項目。
  • 能夠經過jsonp來解決ajax跨域的問題,而jsonp的實質就是經過動態添加script標籤來實現的。

7一、你對負載均衡這塊有認識嗎?
負載均衡(Load Balance)是分佈式系統架構設計中必須考慮的因素之一,它一般是指,將請求數據均勻分攤到多個操做單元上執行,負載均衡的關鍵在於「均勻」。常見互聯網分佈式架構上,分爲客戶端層、反向代理nginx層、站點層、服務層、數據層。
負載均衡有兩方面的含義:

  • 一、大量的併發訪問或數據流量分擔到多臺節點設備上分別處理,減小用戶等待響應的時間;
  • 二、單個重負載的運算分擔到多臺節點設備上作並行處理,每一個節點設備處理結束後,將結果彙總,返回給用戶,系統處理能力獲得大幅度提升。

7二、請說說你熟悉的Linux指令

ls 列出目錄下的文件
cd 到某個目錄裏
cp 複製
mv 移動
rm 刪除
pwd 查看當前位置
tar 解壓tar.gz文件
mkdir 建立文件夾
touch 建立文件
vi 編輯(vim)
cat 查看
chmod 設置文件權限

7三、簡單介紹項目的生命週期

  • 1.需求分析
  • 2.概要設計
  • 3.詳細設計(用例圖,流程圖,類圖)
  • 4.數據庫設計(powerdesigner)
  • 5.代碼開發(編寫)
  • 6.單元測試(junit 白盒測試)(開發人員)
    svn版本管理工具(提交,更新代碼,文檔)
  • 7.集成測試 (黑盒測試,loadrunner(編寫測試腳本)(高級測試))
  • 8.上線試運行 (用戶本身檢查)
  • 9.壓力測試(loadrunner)
  • 10.正式上線
  • 11.維護

7四、說說你理解中的線程死鎖
死鎖是由於多線程訪問共享資源,因爲訪問的順序不當所形成的,一般是一個線程鎖定了一個資源A,而又想去鎖定資源B;在另外一個線程中,鎖定了資源B,而又想去鎖定資源A以完成自身的操做,兩個線程都想獲得對方的資源,而不肯釋放本身的資源,形成兩個線程都在等待,而沒法執行的狀況。
死鎖產生的緣由:是由訪問共享資源順序不當所形成的
簡單的說:所謂死鎖,是指兩個或兩個以上的線程在執行過程當中,因爭奪資源而形成的一種互相等待的現象,若無外力做用,它們都將沒法推動下去。

7五、 介紹下守護線程
在Java中有兩類線程:User Thread(用戶線程)、Daemon Thread(守護線程)

  • (1)用個比較通俗的說法,任何一個守護線程都是整個JVM中全部非守護線程的保姆:只要當前JVM實例中尚存在任何一個非守護線程沒有結束,守護線程就所有工做;只有當最後一個非守護線程結束時,守護線程才隨着JVM一同結束工做。
  • (2)守護線程最典型的應用就是 GC (垃圾回收器),它就是一個很稱職的守護者。
  • (3)守護線程與普通線程的惟一區別是:當JVM中全部的線程都是守護線程的時候,JVM就能夠退出了;若是還有一個或以上的非守護線程則不會退出。(以上是針對正常退出,調用System.exit則一定會退出)

文章全部內容均收集於網絡,若有錯誤或其它問題,歡迎小夥伴留言評論、指正。若有幫助,歡迎點贊+轉發分享。

如下是Java面試要點集合彙總:

反模式設計
簡單的來講,反模式是指在對常常面對的問題常用的低效,不良,或者有待優化的設計模式/方法。甚至,反模式也能夠是一種錯誤的開發思想/理念。在這裏我舉一個最簡單的例子:在面向對象設計/編程中,有一條很重要的原則, 單一責任原則(Single responsibility principle)。其中心思想就是對於一個模塊,或者一個類來講,這個模塊或者這個類應該只對系統/軟件的一個功能負責,並且該責任應該被該類徹底封裝起來。當開發人員須要修改系統的某個功能,這個模塊/類是最主要的修改地方。相對應的一個反模式就是上帝類(God Class),一般來講,這個類裏面控制了不少其餘的類,同時也依賴其餘不少類。整個類不光負責本身的主要單一功能,並且還負責了其餘不少功能,包括一些輔助功能。不少維護老程序的開發人員們可能都遇過這種類,一個類裏有幾千行的代碼,有不少功能,可是責任不明確單一。單元測試程序也變複雜無比。維護/修改這個類的時間要遠遠超出其餘類的時間。不少時候,造成這種狀況並非開發人員故意的。不少狀況下主要是因爲隨着系統的年限,需求的變化,項目的資源壓力,項目組人員流動,系統結構的變化而致使某些原先小型的,符合單一原則類慢慢的變的臃腫起來。最後當這個類變成了維護的噩夢(特別是原先熟悉的開發人員離職後),重構該類就變成了一個不容易的工程。

分庫與分表設計
垂直分表在平常開發和設計中比較常見,通俗的說法叫作「大表拆小表」,拆分是基於關係型數據庫中的「列」(字段)進行的。一般狀況,某個表中的字段比較多,能夠新創建一張「擴展表」,將不常用或者長度較大的字段拆分出去放到「擴展表」中。在字段不少的狀況下,拆分開確實更便於開發和維護(筆者曾見過某個遺留系統中,一個大表中包含100多列的)。某種意義上也能避免「跨頁」的問題(MySQL、MSSQL底層都是經過「數據頁」來存儲的,「跨頁」問題可能會形成額外的性能開銷,拆分字段的操做建議在數據庫設計階段就作好。若是是在發展過程當中拆分,則須要改寫之前的查詢語句,會額外帶來必定的成本和風險,建議謹慎。

垂直分庫在「微服務」盛行的今天已經很是普及了。基本的思路就是按照業務模塊來劃分出不一樣的數據庫,而不是像早期同樣將全部的數據表都放到同一個數據庫中。系統層面的「服務化」拆分操做,可以解決業務系統層面的耦合和性能瓶頸,有利於系統的擴展維護。而數據庫層面的拆分,道理也是相通的。與服務的「治理」和「降級」機制相似,咱們也能對不一樣業務類型的數據進行「分級」管理、維護、監控、擴展等。

衆所周知,數據庫每每最容易成爲應用系統的瓶頸,而數據庫自己屬於「有狀態」的,相對於Web和應用服務器來說,是比較難實現「橫向擴展」的。數據庫的鏈接資源比較寶貴且單機處理能力也有限,在高併發場景下,垂直分庫必定程度上可以突破IO、鏈接數及單機硬件資源的瓶頸,是大型分佈式系統中優化數據庫架構的重要手段。

而後,不少人並無從根本上搞清楚爲何要拆分,也沒有掌握拆分的原則和技巧,只是一味的模仿大廠的作法。致使拆分後遇到不少問題(例如:跨庫join,分佈式事務等)。

水平分表也稱爲橫向分表,比較容易理解,就是將表中不一樣的數據行按照必定規律分佈到不一樣的數據庫表中(這些表保存在同一個數據庫中),這樣來下降單表數據量,優化查詢性能。最多見的方式就是經過主鍵或者時間等字段進行Hash和取模後拆分。水平分表,可以下降單表的數據量,必定程度上能夠緩解查詢性能瓶頸。但本質上這些表還保存在同一個庫中,因此庫級別仍是會有IO瓶頸。因此,通常不建議採用這種作法。

水平分庫分表與上面講到的水平分表的思想相同,惟一不一樣的就是將這些拆分出來的表保存在不一樣的數據中。這也是不少大型互聯網公司所選擇的作法。某種意義上來說,有些系統中使用的「冷熱數據分離」(將一些使用較少的歷史數據遷移到其餘的數據庫中。而在業務功能上,一般默認只提供熱點數據的查詢),也是相似的實踐。在高併發和海量數據的場景下,分庫分表可以有效緩解單機和單庫的性能瓶頸和壓力,突破IO、鏈接數、硬件資源的瓶頸。固然,投入的硬件成本也會更高。同時,這也會帶來一些複雜的技術問題和挑戰(例如:跨分片的複雜查詢,跨分片事務等)。

分佈式困境與應對之策

  • 數據遷移與擴容問題
    前面介紹到水平分表策略概括總結爲隨機分表和連續分表兩種狀況。連續分表有可能存在數據熱點的問題,有些表可能會被頻繁地查詢從而形成較大壓力,熱數據的表就成爲了整個庫的瓶頸,而有些表可能存的是歷史數據,不多須要被查詢到。連續分表的另一個好處在於比較容易,不須要考慮遷移舊的數據,只須要添加分表就能夠自動擴容。隨機分表的數據相對比較均勻,不容易出現熱點和併發訪問的瓶頸。可是,分表擴展須要遷移舊的數據。
    若是想學習Java工程化、高性能及分佈式、深刻淺出。微服務、Spring,MyBatis,Netty源碼分析、雙十一實戰或者是面試難題的朋友能夠加582505643裏面的羣主感受蠢萌蠢萌的能夠到她那騙資料,都是乾貨。
    針對於水平分表的設計相當重要,須要評估中短時間內業務的增加速度,對當前的數據量進行容量規劃,綜合成本因素,推算出大概須要多少分片。對於數據遷移的問題,通常作法是經過程序先讀出數據,而後按照指定的分表策略再將數據寫入到各個分表中。
  • 表關聯問題
    在單庫單表的狀況下,聯合查詢是很是容易的。可是,隨着分庫與分表的演變,聯合查詢就遇到跨庫關聯和跨表關係問題。在設計之初就應該儘可能避免聯合查詢,能夠經過程序中進行拼裝,或者經過反範式化設計進行規避。
  • 分頁與排序問題
    通常狀況下,列表分頁時須要按照指定字段進行排序。在單庫單表的狀況下,分頁和排序也是很是容易的。可是,隨着分庫與分表的演變,也會遇到跨庫排序和跨表排序問題。爲了最終結果的準確性,須要在不一樣的分表中將數據進行排序並返回,並將不一樣分表返回的結果集進行彙總和再次排序,最後再返回給用戶。
  • 分佈式事務問題
    隨着分庫與分表的演變,必定會遇到分佈式事務問題,那麼如何保證數據的一致性就成爲一個必須面對的問題。目前,分佈式事務並無很好的解決方案,難以知足數據強一致性,通常狀況下,使存儲數據儘量達到用戶一致,保證系統通過一段較短的時間的自我恢復和修正,數據最終達到一致。
  • 分佈式全局惟一ID
    在單庫單表的狀況下,直接使用數據庫自增特性來生成主鍵ID,這樣確實比較簡單。在分庫分表的環境中,數據分佈在不一樣的分表上,不能再借助數據庫自增加特性。須要使用全局惟一 ID,例如 UUID、GUID等。

MySQL 遇到的死鎖問題

產生死鎖的四個必要條件:

(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已得到的資源保持不放。
(3) 不剝奪條件:進程已得到的資源,在末使用完以前,不能強行剝奪。
(4) 循環等待條件:若干進程之間造成一種頭尾相接的循環等待資源關係。

這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不知足,就不會發生死鎖。下列方法有助於最大限度地下降死鎖:
(1)按同一順序訪問對象。
(2)避免事務中的用戶交互。
(3)保持事務簡短並在一個批處理中。
(4)使用低隔離級別。
(5)使用綁定鏈接。

數據庫索引的原理
數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現一般使用B樹及其變種B+樹。

彙集索引與非彙集索引的區別

  • 1).彙集索引一個表只能有一個,而非彙集索引一個表能夠存在多個
  • 2).彙集索引存儲記錄是物理上連續存在,而非彙集索引是邏輯上的連續,物理存儲並不連續
  • 3).彙集索引:物理存儲按照索引排序;彙集索引是一種索引組織形式,索引的鍵值邏輯順序決定了表數據行的物理存儲順序
    非彙集索引:物理存儲不按照索引排序;非彙集索引則就是普通索引了,僅僅只是對數據列建立相應的索引,不影響整個表的物理存儲順序.
  • 4).索引是經過二叉樹的數據結構來描述的,咱們能夠這麼理解聚簇索引:索引的葉節點就是數據節點。而非聚簇索引的葉節點仍然是索引節點,只不過有一個指針指向對應的數據塊。

Redis 持久化機制和如何實現
redis有兩種持久化機制RDB與AOF。

  • RDB持久化方式會在一個特定的間隔保存那個時間點的一個數據快照。
  • AOF持久化方式則會記錄每個服務器收到的寫操做。在服務啓動時,這些記錄的操做會逐條執行從而重建出原來的數據。寫操做命令記錄的格式跟Redis協議一致,以追加的方式進行保存。
  • Redis的持久化是能夠禁用的,就是說你可讓數據的生命週期只存在於服務器的運行時間裏。

兩種方式的持久化是能夠同時存在的,可是當Redis重啓時,AOF文件會被優先用於重建數據。

緩存降級

  • 頁面降級:在大促或者某些特殊狀況下,某些頁面佔用了一些稀缺服務資源,在緊急狀況下能夠對其整個降級,以達到丟卒保帥;
  • 頁面片斷降級:好比商品詳情頁中的商家部分由於數據錯誤了,此時須要對其進行降級;
  • 頁面異步請求降級:好比商品詳情頁上有推薦信息/配送至等異步加載的請求,若是這些信息響應慢或者後端服務有問題,能夠進行降級;
  • 服務功能降級:好比渲染商品詳情頁時須要調用一些不過重要的服務:相關分類、熱銷榜等,而這些服務在異常狀況下直接不獲取,即降級便可;
  • 讀降級:好比多級緩存模式,若是後端服務有問題,能夠降級爲只讀緩存,這種方式適用於對讀一致性要求不高的場景;若是想學習Java工程化、高性能及分佈式、深刻淺出。微服務、Spring,MyBatis,Netty源碼分析、雙十一實戰或者是面試難題的朋友能夠加582505643裏面的羣主感受蠢萌蠢萌的能夠到她那騙資料,都是乾貨。
  • 寫降級:好比秒殺搶購,咱們能夠只進行Cache的更新,而後異步同步扣減庫存到DB,保證最終一致性便可,此時能夠將DB降級爲Cache。
  • 爬蟲降級:在大促活動時,能夠將爬蟲流量導向靜態頁或者返回空數據,從而保護後端稀缺資源。
  • 自動開關降級
    自動降級是根據系統負載、資源使用狀況、SLA等指標進行降級。
  • 超時降級
    當訪問的數據庫/http服務/遠程調用響應慢或者長時間響應慢,且該服務不是核心服務的話能夠在超時後自動降級;好比商品詳情頁上有推薦內容/評價,可是推薦內容/評價暫時不展現對用戶購物流程不會產生很大的影響;對於這種服務是能夠超時降級的。若是是調用別人的遠程服務,和對方定義一個服務響應最大時間,若是超時了則自動降級。
Java Web學習路徑

============

Java編程所需的工具及知識

==============

JVM的基本結構

========

SSH框架

=====

設計模式之間的關係

=========

JAVA知識結構體系圖

JAVA知識學習計劃圖

學習須要知道:

一、是什麼
二、解決了什麼問題
三、怎麼實現的

文章全部內容均收集於網絡,若有錯誤或其它問題,歡迎小夥伴留言評論、指正。若有幫助,歡迎點贊+轉發分享。

歡迎你們關注民工哥的公衆號:民工哥技術之路
image.png

相關文章
相關標籤/搜索