前言
只有光頭才能變強,
文末思維腦圖將會打開你的新世界
1、在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;
}
}
另外,我個人通常并不使用標號這種方式,而是讓外層的回圈條件運算式的結果可以受到里層回圈體代碼的控制,例如,要在二維陣列中查找到某個數字,
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;
}
}
}
2、請說出作用域public,private,protected,以及不寫時的區別,
- private修飾的成員變數和函式只能在類本身和內部類中被訪問,
- protected 修飾的成員變數和函式能被類本身、子類及同一個包中的類訪問,
- public修飾的成員變數和函式可以被類、子類、同一個包中的類以及任意其他類訪問,
默認情況(不寫)下,屬于一種包訪問,即能被類本身以及同一個包中的類訪問,
下面這個表能清楚的說明java中作用域運算子的作用:

3、說說對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了,
Session 的應用有很多
- 1.過濾未登錄用戶
可以用于存放用戶資訊,當用戶登錄后,就將用戶資訊放入session,如果沒有登錄,在session中就不會有用戶資訊,這樣就可以防止未登錄用戶查看一些資訊, - 2.防止表單重復提交
- 3.網上商城中的購物車
4、分層設計的好處?
把各個功能按呼叫流程進行了模塊化,模塊化帶來的好處就是可以隨意組合,分層的好處:
- 1.實作了軟體之間的解耦
- 2.便于進行分工
- 3.便于維護
- 4.提高軟體組件的重用
- 5.便于替換某種產品,比如持久層用的是hibernate,需要更換產品為mybatis,就不用改其他業務的代碼,直接把配置一改即可
- 6.便于產品功能的擴展
- 7.便于適用用戶需求的不斷變化
5、java中實作多型的機制是什么?
靠的是父類或介面定義的參考變數可以指向子類或具體實作類的實體物件,而程式呼叫的方法在運行期才動態系結,就是參考變數所指向的具體實體物件的方法,也就是記憶體里正在運行的那個物件的方法,而不是參考變數的型別中定義的方法,
6、abstract(抽象類)和interface(介面)有什么區別?
含有abstract修飾符的class即為抽象類,abstract 類不能創建的實體物件,含有abstract方法的類必須定義為abstract class,abstract class類中的方法不必是抽象的,abstract class類中定義抽象方法必須在具體(Concrete)子類中實作,所以,不能有抽象構造方法或抽象靜態方法,如果子類沒有實作抽象父類中的所有抽象方法,那么子類也必須定義為abstract型別,
介面(interface)可以說成是抽象類的一種特例,介面中的所有方法都必須是抽象的,介面中的方法定義默認為public abstract型別,介面中的成員變數型別默認為public static final,
下面比較一下兩者的語法區別:
- 1.抽象類可以有構造方法,介面中不能有構造方法,
- 2.抽象類中可以有普通成員變數,介面中沒有普通成員變數
- 3.抽象類中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法,
- 4.抽象類中的抽象方法的訪問型別可以是public,protected和默認型別,但介面中的抽象方法只能是public型別的,并且默認即為public abstract型別,
- 5.抽象類中可以包含靜態方法,介面中不能包含靜態方法
- 6.抽象類和介面中都可以包含靜態成員變數,抽象類中的靜態成員變數的訪問型別可以任意,但介面中定義的變數只能是public static final型別,并且默認即為public static final型別,
- 7.一個類可以實作多個介面,但只能繼承一個抽象類,
7、構造方法Constructor是否可被override(重寫)?
構造方法Constructor不能被繼承,因此不能重寫Override,但可以被多載Overload,
8、面向物件的特征有哪些方面?
面向物件的三大特征:
- 封裝:保證物件自身資料的完整性和安全性,
- 繼承:建立類之間的關系,實作代碼復用,方便系統的擴展,
- 多型:相同的方法呼叫,可以實作不同的實作方式,
9、String是最基本的資料型別嗎,是否可以繼承String類?
java的基本資料型別有以下8種:
- 整型: byte short int long
- 浮點型: float double
- 字符型: char
- 布爾: boolean
java.lang.String類是final型別的,因此不可以繼承這個類、也不能修改這個類 ,為了提高效率節省空間,對于要經常修改的字串,建議使用StringBuffer類,
10、陣列有沒有length()這個方法? String有沒有length()這個方法?
陣列沒有length()這個方法,有length的屬性,
String有length()這個方法,
需要更多學習資料和面試真題資料的朋友可以在文末獲取免費領取方式,還有本文中分享的思維腦圖都可獲取,

11、String s = new String(“abc”);創建了幾個String Object? 二者之間有什么區別?
答案:一個或者兩個
決議:
- 1.如果String緩沖區中,已經創建"abc",則不會繼續創建,此時只創建了一個物件new String(“abc”);
- 2.如果String緩沖區中,沒有創建"abc",則會創建兩個物件,一個物件的值是"abc",一個物件new String(“abc”),
12、下面這條陳述句一共創建了多少個物件:String s=“a”+“b”+“c”+“d”
只創建了一個String物件,因為這行代碼被編譯器編譯時進行了優化,相當于直接定義了一個”abcd”的字串,所以只創建了一個String物件,
13、try {}里有一個return陳述句,那么緊跟在這個try后的finally {}里的code會不會被執行,什么時候被執行,在return前還是后?
finally中的代碼肯定會執行,但是會先執行try中的代碼,如果try中有return,那么return的東西會先放到函式堆疊中,然后再執行finally中的代碼,
- ①、如果finally中也有return,則會直接回傳并終止程式,函式堆疊中的return不會被完成;
- ②、如果finally中沒有return,則在執行完finally中的代碼之后,會將函式堆疊中的try中的return的內容回傳并終止程式;
14、final, finally, finalize的區別
- Final:是全域變數宣告的時候使用,意思是這個變數不可被修改,不可被override,一般用于宣告常量,或者系統設定的值,
- finally:是在例外處理時提供finally塊來執行任何清除操作,不管有沒有例外被拋出、捕獲,finally塊都會被執行,
- finalize:是方法名,java技術允許使用finalize()方法在垃圾收集器將物件從記憶體中清除出去之前做必要的清理作業,
15、運行時例外與一般例外有何異同?
Java提供了兩類主要的例外:運行時例外runtime exception和一般例外checked exception
- 運行時例外runtime exception,我們可以不處理,這樣的例外由虛擬機接管,出現運行時例外后,系統會把例外一直往上層拋,一直遇到處理代碼,如果不對運行時例外進行處理,那么出現運行時例外之后,要么是執行緒中止,要么是主程式終止,
- 一般例外checked exception,JAVA要求程式員對其進行try catch處理,所以,面對這種例外不管我們是否愿意,只能自己去寫一大堆catch塊去處理可能的例外,
16、error和exception有什么區別?
- Error(錯誤)表示系統級的錯誤和程式不必處理的例外,是java運行環境中的內部錯誤或者硬體問題,比如:記憶體資源不足等,對于這種錯誤,程式基本無能為力,除了退出運行外別無選擇,它是由Java虛擬機拋出的,
- Exception(違例)表示需要捕捉或者需要程式進行處理的例外,它處理的是因為程式設計的瑕疵而引起的問題或者在外的輸入等引起的一般性問題,是程式必須處理的,Exception又細分為運行時例外runtime exception,受檢查例外checked exception(一般例外),
17、請寫出你最常見到的5個運行時例外 runtime exception
- ClassCastException 型別強制轉換例外
- ClassNotFoundException 類沒找到時,拋出該例外
- FileNotFoundException 檔案未找到例外
- NullPointerException 空指標例外
- SQLException 操作資料庫例外
- ArithmeticException 算術例外
- IllegalArgumentException 傳遞非法引數例外
- IndexOutOfBoundsException 下標越界例外
- NoSuchElementException 方法未找到例外
18、Java語言如何進行例外處理,關鍵字:throws,throw,try,catch,finally分別代表什么意義?在try塊中可以拋出例外嗎?
- try{}陳述句塊 中放的是要檢測的java代碼,可能有會拋出例外,也可能會正常執行;
- catch(例外型別){}塊 是當Java運行時系統接收到try塊中所拋出的例外物件時,會尋找能處理這一例外的catch塊來進行處理(可以有多個catch塊);
- finally{}塊 不管系統有沒有拋出例外都會去執行,一般用來釋放資源,除了在之前執行了System.exit(0);
- throw 用于手動拋出例外,作為程式員可以在任意位置手動拋出例外;
- throws 用于在方法上標識要拋出的例外,拋出的例外交由呼叫者處理;
19、ArrayList和Vector、LinkedList的區別?
- (1)Vector是執行緒安全的,而ArrayList不是,
- (2)當存盤空間不足的時候,ArrayList默認增加為原來的50%,Vector默認增加為原來的一倍,
- (3)Vector可以設定容量增加的引數,而ArrayList不可以,
- (4)LinkedList使用雙向鏈表實作存盤,按序號索引資料需要進行前向或后向遍歷,但是插入資料時只需要記錄本項的前后項即可,所以插入速度較快,
20、List 和 Map 區別?
- (1)、List是存盤單列資料的集合,List中存盤的資料是有順序,并且允許重復;
- (2)、Map是存盤鍵和值這樣的雙列資料的集合,Map中存盤的資料是沒有順序的,其鍵是不能重復的,它的值是可以有重復的,
21、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,
22、說出一些常用的類,包,介面,請各舉例5個
- 常用的類:
Object
Date
File
Exception
Random
String
integer - 常用的包:
http://java.io
java.lang
java.util
java.sql
http://java.net - 常用的介面:
Set
List
Map
Collection
Runnable
Session
Servlet
23、java中有幾種型別的流?JDK為每種型別的流提供了一些抽象類以供繼承,請說出他們分別是哪些類?
- 基于流方向:
InputStream
OutputStream - 基于字符:
Reader
Writer - 流和字符之間的配接:
InputStreamReader
OutputStreamWriter

24、位元組流與字符流的區別?
- (1)位元組流在操作時本身不會用到緩沖區(記憶體),是檔案本身直接操作的,而字符流在操作時使用了緩沖區,通過緩沖區再操作檔案,
- (2)位元組流中,中文可能會亂碼,字符流不會,
25、什么是java序列化,如何實作java序列化?或者請解釋Serializable介面的作用,
序列化就是一種用來處理物件流的機制,所謂物件流也就是將物件的內容進行流化,可以對流化后的物件進行讀寫操作,也可將流化后的物件傳輸于網路之間,序列化是為了解決在對物件流進行讀寫操作時所引發的問題,
序列化的實作:將需要被序列化的類實作Serializable介面,然后使用一個輸出流(如:FileOutputStream)來構造一個ObjectOutputStream(物件流)物件,接著,使用ObjectOutputStream物件的writeObject(Object obj)方法就可以將引數為obj的物件寫出(即保存其狀態),要恢復的話則用輸入流;
Serializable.只有實作了 serializable和Externalizable介面的類的物件才能被序列化
Java 序列化技術可以使你將一個物件的狀態寫入一個Byte 流里,并且可以從其它地方把該Byte 流里的資料讀出來,重新構造一個相同的物件,這種機制允許你將物件通過網路進行傳播,并可以隨時把物件持久化到資料庫、檔案等系統里,Java的序列化機制是RMI、EJB等技術的技識訓礎,用途:利用物件的序列化實作保存應用程式的當前作業狀態,下次再啟動的時候將自動地恢復到上次執行的狀態,
26、GC是什么? 為什么要有GC?
GC是垃圾收集的意思,記憶體處理是編程人員容易出現問題的地方,忘記或者錯誤的記憶體會導致程式或系統的不穩定甚至崩潰,Java提供的GC功能可以自動監測物件是否超過作用域從而達到自動回收記憶體的目的,Java語言沒有提供釋放已分配記憶體的顯示操作方法,Java程式員不用擔心記憶體管理,因為垃圾收集器會自動進行管理,

27、排序都有哪幾種方法?請用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.如果要降序,只要把程式中的大于號換成小于號,
28、說一說Servlet的生命周期?
servlet的生命周期分為以下幾個步驟:
- 第一、加載并實體化
- 第二、初始化
- 第三、服務
- 第四、銷毀
容器啟動的時候,會加載servlet的class,并new出這個物件,然后,當用戶請求這個servlet的時候,容器會呼叫init方法初始化這個servlet,這也是整個生命周期中只會呼叫一次的方法,然后,會呼叫service方法,由這個方法呼叫doGet或doPost方法來回應用戶,然后,容器在可用資源緊張或是長期沒有對Servlet發出請求的情況下,會銷毀這個servlet,
29、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范圍記憶體在的物件,
31、jsp有哪些常用內置物件?
- <1>、request
- <2>、response
- <3>、session
- <4>、out
- <5>、page
- <6>、application
- <7>、exception
- <8>、pageContext
- <9>、config
32、JSP和Servlet有哪些相同點和不同點,他們之間的聯系是什么?
- ①、JSP是Servlet技術的擴展,本質上是Servlet的簡易方式,更強調應用的外表表達,JSP編譯后是”類servlet”,
- ②、JSP是Java和HTML組合成的一個擴展名為.jsp的檔案,JSP側重于視圖,Servlet主要用于控制邏輯,
- ③、Servlet和JSP最主要的不同點在于,Servlet的應用邏輯是在Java檔案中,并且完全從表示層中的HTML里分離開來,
33、MVC的各個部分都有哪些技術來實作?
MVC 是 Model-View-Controller 的簡寫,通過這種設計模型把應用邏輯、處理程序和顯示邏輯分成不同的組件實作,
- (1)模型(Model)代表的是應用的業務邏輯( 通過JavaBean, EJB 組件實作)
- (2)視圖(View)是應用的表示面( 由 JSP 頁面產生)
- (3)控制器(controller) 是提供應用的處理程序控制( 一般是一個 Servlet)
34、資料庫三范式是什么?
- 第一范式:確保每一列的原子性
(原子性欄位不可再分,否則就不是關系型資料庫) - 第二范式:在第一范式的基礎上更進一層,確保表中的每列都和主鍵相關
(唯一性,一個表只說明一個事物) - 第三范式:在第二范式的基礎上更進一層,確保每列都和主鍵列直接相關,而不是間接相關
(每列都與主鍵有直接關系,不存在傳遞依賴)

35、說出一些資料庫優化方面的經驗?
- 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陳述句操作
36、Class.forName的作用是什么?
- Class.forName(xxx.xx.xx) 回傳的是一個類,Java里面任何class都要裝載在虛擬機上才能運行,這句話就是裝載類用的,
- Class.forName(xxx.xx.xx)的作用是要求JVM查找并加載指定的類,也就是說JVM會執行該類的靜態代碼段,動態加載和創建Class物件,最熟悉的就是JDBC連接資料庫的時候加載驅動類,
37、說說資料連接池的作業機制是什么?
J2EE服務器啟動時會建立一定數量的池連接,并一直維持不少于此數目的池連接,客戶端程式需要連接時,池驅動程式會回傳一個未使用的池連接并將其標記為忙,如果當前沒有空閑連接,池驅動程式就新建一定數量的連接,新建連接的數量由配置引數決定,當使用的池連接呼叫完成后,池驅動程式將此連接標記為空閑,其他呼叫就可以使用這個連接,

38、為什么要用ORM? 和JDBC有何不一樣?
- 物件關系映射(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向物件與關系資料庫存在的互不匹配現象的技術,簡單的說,ORM是通過使用描述物件和資料庫之間映射的元資料,將程式中的物件自動持久化到關系資料庫中,
- ORM是一種思想,就是把object轉變成資料庫中的記錄,或者把資料庫中的記錄轉變成object,我們可以用jdbc來實作這種思想,其實,如果我們的專案是嚴格按照oop方式撰寫的話,我們的jdbc程式不管是有意還是無意,就已經在實作ORM的作業了,
- 現在有許多ORM工具,它們底層呼叫jdbc來實作了ORM作業,我們直接使用這些工具,就省去了直接使用jdbc的繁瑣細節,提高了開發效率,現在用的較多的ORM工具是hibernate,
39、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來展示資料,
41、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個高危安全漏洞,一個是使用縮寫的導航引數前綴時的遠程代碼執行漏洞,另一個是使用縮寫的重定向引數前綴時的開放式重定向漏洞,這些漏洞可使黑客取得網站服務器的“最高權限”,從而使企業服務器變成黑客手中的“肉雞”
42、談談你對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)思想中,我們將事物縱向抽象成一個個的物件,而在面向切面編程中,我們將一個個物件某些類似的方面橫向抽象成一個切面,對這個切面進行一些如權限驗證,事物管理,記錄日志等公用操作處理的程序就是面向切面編程的思想,
43、AOP的作用是什么?
AOP(面向切面編程)是一種編程范式,用于提供從另一角度來考慮程式結構以完善面向物件編程,
主要作用:
- 1.降低模塊之間的耦合度,
- 2.使系統容易擴展,
- 3.更好的代碼復用

44、談談你對Hibernate的理解,
Hibernate是一個開放源代碼的物件關系映射(ORM)框架,它對JDBC進行了非常輕量級的物件封裝,使得java程式員可以隨心所欲的使用物件編程思維來操縱資料庫,
Hibernate的優點:
- 1.對JDBC訪問資料庫的代碼做了封裝,大大簡化了資料訪問層繁瑣的重復性代碼,
- 2.Hibernate是一個基于JDBC的主流持久化框架,是一個優秀的ORM實作,他很大程度的簡化DAO層的編碼作業
- 3、 Hibernate使用Java反射機制而不是位元組碼增強程式來實作透明性,
- 4、 Hibernate的性能好,映射的靈活性比較出色,它支持各種關系資料庫,從一對一到多對多的各種復雜關系,
hibernate的核心類:
Configuration、SessionFactory 、Session
45、hibernate中的update()和saveOrUpdate()的區別
- update() 如果是對一個已經存在的托管物件進行更新那么肯定是要使用update()方法了,資料中有這個物件,
- saveOrUpdate() 這個方法是更新或者插入,有主鍵就執行更新,如果沒有主鍵就執行插入,
46、簡述 Hibernate 和 JDBC 的優缺點?
- (1)JDBC與Hibernate在性能上相比,JDBC靈活性有優勢,
- (2)而Hibernate在易學性,易用性上有優勢,
- (3)當用到很多復雜的多表聯查和復雜的資料庫操作時,JDBC有優勢,
47、Hibernate中,如何書寫一個 one to many 組態檔?
one to many 組態檔的方法:
在一方添加集合物件,并封裝,然后在對應的映射檔案追加標簽,設定外檢,以及通過one-to-many標簽設定集合物件所對應的型別即可,
48、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本身提供的快取機制不佳,
49、hibernate的inverse屬性有什么作用?
- 用來指定關聯的控制方的,inverse屬性默認是false:
- 若為false,則關聯由自己控制
- 若為true,則關聯由對方控制
50、介紹一下Hibernate的二級快取
內置快取:Hibernate自帶的,不可卸載,通常在Hibernate的初始化階段,Hibernate會把映射元資料和預定義的SQL陳述句放置到SessionFactory的快取中,該內置快取是只讀的,
外置快取:通常說的二級快取也就是外置快取,在默認情況下SessionFactory不會啟用這個快取插件,外置快取中的資料是資料庫資料的復制,外置快取的物理介質可以是記憶體或者硬碟,
適合放入二級快取中資料:
- 很少被修改
- 不是很重要的資料,允許出現偶爾的并發問題
- 不適合放入二級快取中的資料
- 經常被修改
- 財務資料,絕對不允許出現并發問題
- 與其他應用資料共享的資料
51、session中load()和get()的區別
- (1)load方法支持延遲加載,而get方法則不支持,
- (2)load方法在沒找到資料的時候會拋出ObjectNotFoundException,而get方法則會回傳null,
52、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:資訊流可變化,更像交易中心
53、Spring MVC Framework有那些特點?
- 1.它是基于組件技術的,全部的應用物件,無論控制器和視圖,還是業務物件之類的都是java組件,并且和Spring提供的其他基礎結構緊密集成,
- 2.不依賴于Servlet API(目標雖是如此,但是在實作的時候確實是依賴于Servlet的)
- 3.可以任意使用各種視圖技術,而不僅僅局限于JSP
- 4.支持各種請求資源的映射策略
- 5.它應是易于擴展的
54、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
DispatcherServlet對View進行渲染視圖(即將模型資料填充至視圖中),
DispatcherServlet回應用戶
55、簡單介紹下springMVC和struts2的區別有哪些?
- 1.springmvc的入口是一個servlet即前端控制器,而struts2入口是一個filter過慮器,
- 2.springmvc是基于方法開發(一個url對應一個方法),請求引數傳遞到方法的形參,可以設計為單例或多例(建議單例),struts2是基于類開發,傳遞引數是通過類的屬性,只能設計為多例,
- 3.Struts采用值堆疊存盤請求和回應的資料,通過OGNL存取資料,springmvc通過引數決議器是將request請求內容決議,并給方法形參賦值,將資料和視圖封裝成ModelAndView物件,最后又將ModelAndView中的模型資料通過reques域傳輸到頁面,Jsp視圖決議器默認使用jstl,
56、請介紹執行緒的五種狀態
- 第一、創建狀態,在生成執行緒物件,并沒有呼叫該物件的start方法,這是執行緒處于創建狀態手寫字串反轉和冒泡排序;
- 第二、就緒狀態,當呼叫了執行緒物件的start方法之后,該執行緒就進入了就緒狀態,但是此時執行緒調度程式還沒有把該執行緒設定為當前執行緒,此時處于就緒狀態,在執行緒運行之后,從等待或者睡眠中回來之后,也會處于就緒狀態,
- 第三、運行狀態,執行緒調度程式將處于就緒狀態的執行緒設定為當前執行緒,此時執行緒就進入了運行狀態,開始運行run函式當中的代碼,
- 第四、阻塞狀態,執行緒正在運行的時候,被暫停,通常是為了等待某個時間的發生(比如說某項資源就緒)之后再繼續運行,sleep,suspend,wait等方法都可以導致執行緒阻塞,
- 第五、死亡狀態,如果一個執行緒的run方法執行結束或者呼叫stop方法后,該執行緒就會死亡,對于已經死亡的執行緒,無法再使用start方法令其進入就緒
57、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,
58、什么是資料庫臟讀,不可重復讀,幻覺讀
臟讀又稱無效資料讀出,一個事務讀取另外一個事務還沒有提交的資料叫臟讀,
例如:事務T1修改了一行資料,但是還沒有提交,這時候事務T2讀取了被事務T1修改后的資料,之后事務T1因為某種原因Rollback了,那么事務T2讀取的資料就是臟的不可重復讀是指在同一個事務內,兩個相同的查詢回傳了不同的結果,
例如:事務T1讀取某一資料,事務T2讀取并修改了該資料,T1為了對讀取值進行檢驗而再次讀取該資料,便得到了不同的結果,
幻覺讀是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的資料進行了修改,這種修改涉及到表中的全部資料行,同時,第二個事務也修改這個表中的資料,這種修改是向表中插入一行新資料,那么,以后就會發生操作第一個事務的用戶發現表中還有沒有修改的資料行,就好象發生了幻覺一樣,例如:系統管理員A將資料庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束后發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀,
59、請介紹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;
}
}
61、session和cooie的區別
具體來說cookie機制采用的是在客戶端保持狀態的方案,而session 機制采用的是在服務器端保持狀態的方案,由于服務器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制需要借助于cookie機制來達到保存標識的目的 ,
62、什么是Spring IOC 容器?
Spring IOC 負責創建物件,管理物件(通過依賴注入(DI),裝配物件,配置物件,并且管理這些物件的整個生命周期,
63、spring有哪些不同型別的IOC(依賴注入)方式?
構造器依賴注入:構造器依賴注入通過容器觸發一個類的構造器來實作的,該類有一系列引數,每個引數代表一個對其他類的依賴,
Setter方法注入:Setter方法注入是容器通過呼叫無參構造器或無參static工廠 方法實體化bean之后,呼叫該bean的setter方法,即實作了基于setter的依賴注入
64、 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情形下有效,
65、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(責任鏈模式)
工廠模式:工廠模式是一種經常被使用到的模式,根據工廠模式實作的類可以根據提供的資料生成一組類中某一個類的實體,通常這一組類有一個公共的抽象父類并且實作了相同的方法,但是這些方法針對不同的資料進行了不同的操作,首先需要定義一個基類,該類的子類通過不同的方法實作了基類中的方法,然后需要定義一個工廠類,工廠類可以根據條件生成不同的子類實體,當得到子類的實體后,開發人員可以呼叫基類中的方法而不必考慮到底回傳的是哪一個子類的實體
66、談談你對資料庫事務的理解?
在資料庫中,所謂事務是指一組邏輯操作單元即一組sql陳述句,當這個單元中的一部分操作失敗,整個事務回滾,只有全部正確才完成提交,判斷事務是否配置成功的關鍵點在于出現例外時事務是否會回滾,在JDBC中,事務默認是自動提交的,每次執行一個SQL陳述句時,如果執行成功,就會向資料庫自動提交,而不能回滾,
事務的特征(ACID屬性):
- 1.原子性(Atomicity)
原子性是指事務是一個不可分割的作業單位,事務中的操作要么都發生,要么都不發生, - 2.一致性(Consistency)
事務必須使資料庫從一個一致性狀態變換到另外一個一致性狀態,(資料不被破壞) - 3.隔離性(Isolation)
事務的隔離性是指一個事務的執行不能被其他事務干擾. - 4.持久性(Durability)
持久性是指一個事務一旦被提交,它對資料庫中資料的改變就是永久性的.即使系統重啟也不會丟失.
67、談談你對資料庫索引的理解
1、索引的概念
索引就是為了提高資料的檢索速度,資料庫的索引類似于書籍的索引,在書籍中,索引允許用戶不必翻閱完整個書就能迅速地找到所需要的資訊,在資料庫中,索引也允許資料庫程式迅速地找到表中的資料,而不必掃描整個資料庫.
2、索引的優點
a.創建唯一性索引,保證資料庫表中每一行資料的唯一性
b.大大加快資料的檢索速度,這也是創建索引的最主要的原因
c.減少磁盤IO(向字典一樣可以直接定位)
3、索引的缺點
a.創建索引和維護索引要耗費時間,這種時間隨著資料量的增加而增加
b.索引需要占用額外的物理空間
c.當對表中的資料進行增加、洗掉和修改的時候,索引也要動態的維護,降低了資料的維護速度
68、jdbc操作資料庫的步驟
①、加載資料庫驅動程式 Class.forName(“資料庫驅動類”);
②、連接資料庫 Connection con = DriverManager.getConnection();
③、操作資料庫 PreparedStatement stat = con.prepareStatement(sql);stat.executeQuery();
④、關閉資料庫,釋放連接 con.close();
69、介紹下樂觀鎖,悲觀鎖
- 樂觀鎖(Optimistic Lock), 每次去查詢資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,可以使用版本號,時間戳等機制,樂觀鎖適用于多讀的應用型別,這樣可以提高吞吐量
- 悲觀鎖(Pessimistic Lock), 每次去查詢資料的時候都認為別人會修改,所以每次在查詢資料的時候都會上鎖,這樣別人想拿這個資料就會阻塞直到它拿到鎖,傳統的關系型資料庫里邊就用到了這種鎖機制,比如通過select ….for update進行資料鎖定,
70、你對ajax是怎么理解的
- AJAX全稱為“Asynchronous JavaScript and XML”(異步JavaScript和XML),是一種創建互動式網頁應用的網頁開發技術,
- 使用ajax可以提高用戶的體驗度,進行異步資料傳輸從而提高性能,ajax不能跨域,所謂不能跨域就是不能跨多個網站(多個域名),或者多個專案,
- 可以通過jsonp來解決ajax跨域的問題,而jsonp的實質就是通過動態添加script標簽來實作的,
71、你對負載均衡這塊有認識嗎?
負載均衡(Load Balance)是分布式系統架構設計中必須考慮的因素之一,它通常是指,將請求資料均勻分攤到多個操作單元上執行,負載均衡的關鍵在于“均勻”,常見互聯網分布式架構上,分為客戶端層、反向代理nginx層、站點層、服務層、資料層,
負載均衡有兩方面的含義:
- 1、大量的并發訪問或資料流量分擔到多臺節點設備上分別處理,減少用戶等待回應的時間;
- 2、單個重負載的運算分擔到多臺節點設備上做并行處理,每個節點設備處理結束后,將結果匯總,回傳給用戶,系統處理能力得到大幅度提高。
72、請說說你熟悉的Linux指令
- ls 列出目錄下的檔案
- cd 到某個目錄里
- cp 復制
- mv 移動
- rm 洗掉
- pwd 查看當前位置
- tar 解壓tar.gz檔案
- mkdir 創建檔案夾
- touch 創建檔案
- vi 編輯(vim)
- cat 查看
- chmod 設定檔案權限
73、簡單介紹專案的生命周期
- 1.需求分析
- 2.概要設計
- 3.詳細設計(用例圖,流程圖,類圖)
- 4.資料庫設計(powerdesigner)
- 5.代碼開發(撰寫)
- 6.單元測驗(junit 白盒測驗)(開發人員)
svn版本管理工具(提交,更新代碼,檔案) - 7.集成測驗 (黑盒測驗,loadrunner(撰寫測驗腳本)(高級測驗))
- 8.上線試運行 (用戶自己檢查)
- 9.壓力測驗(loadrunner)
- 10.正式上線
- 11.維護
74、說說你理解中的執行緒死鎖
死鎖是因為多執行緒訪問共享資源,由于訪問的順序不當所造成的,通常是一個執行緒鎖定了一個資源A,而又想去鎖定資源B;在另一個執行緒中,鎖定了資源B,而又想去鎖定資源A以完成自身的操作,兩個執行緒都想得到對方的資源,而不愿釋放自己的資源,造成兩個執行緒都在等待,而無法執行的情況,
死鎖產生的原因:是由訪問共享資源順序不當所造成的
簡單的說:所謂死鎖,是指兩個或兩個以上的執行緒在執行程序中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去,
75、 介紹下守護執行緒
在Java中有兩類執行緒:User Thread(用戶執行緒)、Daemon Thread(守護執行緒)
- (1)用個比較通俗的說法,任何一個守護執行緒都是整個JVM中所有非守護執行緒的保姆:只要當前JVM實體中尚存在任何一個非守護執行緒沒有結束,守護執行緒就全部作業;只有當最后一個非守護執行緒結束時,守護執行緒才隨著JVM一同結束作業,
- (2)守護執行緒最典型的應用就是 GC (垃圾回收器),它就是一個很稱職的守護者,
- (3)守護執行緒與普通執行緒的唯一區別是:當JVM中所有的執行緒都是守護執行緒的時候,JVM就可以退出了;如果還有一個或以上的非守護執行緒則不會退出,(以上是針對正常退出,呼叫System.exit則必定會退出)
如需更多資料的小伙伴可以在文末獲取免費領取方式!!
以下是Java面試要點集合匯總:
1、反模式設計
簡單的來說,反模式是指在對經常面對的問題經常使用的低效,不良,或者有待優化的設計模式/方法,甚至,反模式也可以是一種錯誤的開發思想/理念,在這里我舉一個最簡單的例子:在面向物件設計/編程中,有一條很重要的原則, 單一責任原則(Single responsibility principle),其中心思想就是對于一個模塊,或者一個類來說,這個模塊或者這個類應該只對系統/軟體的一個功能負責,而且該責任應該被該類完全封裝起來,當開發人員需要修改系統的某個功能,這個模塊/類是最主要的修改地方,相對應的一個反模式就是上帝類(God Class),通常來說,這個類里面控制了很多其他的類,同時也依賴其他很多類,整個類不光負責自己的主要單一功能,而且還負責了其他很多功能,包括一些輔助功能,很多維護老程式的開發人員們可能都遇過這種類,一個類里有幾千行的代碼,有很多功能,但是責任不明確單一,單元測驗程式也變復雜無比,維護/修改這個類的時間要遠遠超出其他類的時間,很多時候,形成這種情況并不是開發人員故意的,很多情況下主要是由于隨著系統的年限,需求的變化,專案的資源壓力,專案組人員流動,系統結構的變化而導致某些原先小型的,符合單一原則類慢慢的變的臃腫起來,最后當這個類變成了維護的噩夢(特別是原先熟悉的開發人員離職后),重構該類就變成了一個不容易的工程,
2、分庫與分表設計
垂直分表在日常開發和設計中比較常見,通俗的說法叫做“大表拆小表”,拆分是基于關系型資料庫中的“列”(欄位)進行的,通常情況,某個表中的欄位比較多,可以新建立一張“擴展表”,將不經常使用或者長度較大的欄位拆分出去放到“擴展表”中,在欄位很多的情況下,拆分開確實更便于開發和維護(筆者曾見過某個遺留系統中,一個大表中包含100多列的),某種意義上也能避免“跨頁”的問題(MySQL、MSSQL底層都是通過“資料頁”來存盤的,“跨頁”問題可能會造成額外的性能開銷,拆分欄位的操作建議在資料庫設計階段就做好,如果是在發展程序中拆分,則需要改寫以前的查詢陳述句,會額外帶來一定的成本和風險,建議謹慎,
垂直分庫在“微服務”盛行的今天已經非常普及了,基本的思路就是按照業務模塊來劃分出不同的資料庫,而不是像早期一樣將所有的資料表都放到同一個資料庫中,系統層面的“服務化”拆分操作,能夠解決業務系統層面的耦合和性能瓶頸,有利于系統的擴展維護,而資料庫層面的拆分,道理也是相通的,與服務的“治理”和“降級”機制類似,我們也能對不同業務型別的資料進行“分級”管理、維護、監控、擴展等,
眾所周知,資料庫往往最容易成為應用系統的瓶頸,而資料庫本身屬于“有狀態”的,相對于Web和應用服務器來講,是比較難實作“橫向擴展”的,資料庫的連接資源比較寶貴且單機處理能力也有限,在高并發場景下,垂直分庫一定程度上能夠突破IO、連接數及單機硬體資源的瓶頸,是大型分布式系統中優化資料庫架構的重要手段,
然后,很多人并沒有從根本上搞清楚為什么要拆分,也沒有掌握拆分的原則和技巧,只是一味的模仿大廠的做法,導致拆分后遇到很多問題(例如:跨庫join,分布式事務等),
水平分表也稱為橫向分表,比較容易理解,就是將表中不同的資料行按照一定規律分布到不同的資料庫表中(這些表保存在同一個資料庫中),這樣來降低單表資料量,優化查詢性能,最常見的方式就是通過主鍵或者時間等欄位進行Hash和取模后拆分,水平分表,能夠降低單表的資料量,一定程度上可以緩解查詢性能瓶頸,但本質上這些表還保存在同一個庫中,所以庫級別還是會有IO瓶頸,所以,一般不建議采用這種做法,
水平分庫分表與上面講到的水平分表的思想相同,唯一不同的就是將這些拆分出來的表保存在不同的資料中,這也是很多大型互聯網公司所選擇的做法,某種意義上來講,有些系統中使用的“冷熱資料分離”(將一些使用較少的歷史資料遷移到其他的資料庫中,而在業務功能上,通常默認只提供熱點資料的查詢),也是類似的實踐,在高并發和海量資料的場景下,分庫分表能夠有效緩解單機和單庫的性能瓶頸和壓力,突破IO、連接數、硬體資源的瓶頸,當然,投入的硬體成本也會更高,同時,這也會帶來一些復雜的技術問題和挑戰(例如:跨分片的復雜查詢,跨分片事務等),
3、分布式困境與應對之策
- 資料遷移與擴容問題
前面介紹到水平分表策略歸納總結為隨機分表和連續分表兩種情況,連續分表有可能存在資料熱點的問題,有些表可能會被頻繁地查詢從而造成較大壓力,熱資料的表就成為了整個庫的瓶頸,而有些表可能存的是歷史資料,很少需要被查詢到,連續分表的另外一個好處在于比較容易,不需要考慮遷移舊的資料,只需要添加分表就可以自動擴容,隨機分表的資料相對比較均勻,不容易出現熱點和并發訪問的瓶頸,但是,分表擴展需要遷移舊的資料,
如果想學習Java工程化、高性能及分布式、深入淺出,微服務、Spring,MyBatis,Netty原始碼分析、雙十一實戰或者是面試難題的朋友可以加1507153110這個小姐姐感覺蠢萌蠢萌的可以到她那騙資料,都是干貨,
針對于水平分表的設計至關重要,需要評估中短期內業務的增長速度,對當前的資料量進行容量規劃,綜合成本因素,推算出大概需要多少分片,對于資料遷移的問題,一般做法是通程序式先讀出資料,然后按照指定的分表策略再將資料寫入到各個分表中, - 表關聯問題
在單庫單表的情況下,聯合查詢是非常容易的,但是,隨著分庫與分表的演變,聯合查詢就遇到跨庫關聯和跨表關系問題,在設計之初就應該盡量避免聯合查詢,可以通程序式中進行拼裝,或者通過反范式化設計進行規避, - 分頁與排序問題
一般情況下,串列分頁時需要按照指定欄位進行排序,在單庫單表的情況下,分頁和排序也是非常容易的,但是,隨著分庫與分表的演變,也會遇到跨庫排序和跨表排序問題,為了最終結果的準確性,需要在不同的分表中將資料進行排序并回傳,并將不同分表回傳的結果集進行匯總和再次排序,最后再回傳給用戶, - 分布式事務問題
隨著分庫與分表的演變,一定會遇到分布式事務問題,那么如何保證資料的一致性就成為一個必須面對的問題,目前,分布式事務并沒有很好的解決方案,難以滿足資料強一致性,一般情況下,使存盤資料盡可能達到用戶一致,保證系統經過一段較短的時間的自我恢復和修正,資料最終達到一致, - 分布式全域唯一ID
在單庫單表的情況下,直接使用資料庫自增特性來生成主鍵ID,這樣確實比較簡單,在分庫分表的環境中,資料分布在不同的分表上,不能再借助資料庫自增長特性,需要使用全域唯一 ID,例如 UUID、GUID等,
4、MySQL 遇到的死鎖問題
產生死鎖的四個必要條件:
(1) 互斥條件:一個資源每次只能被一個行程使用,
(2) 請求與保持條件:一個行程因請求資源而阻塞時,對已獲得的資源保持不放,
(3) 不剝奪條件:行程已獲得的資源,在末使用完之前,不能強行剝奪,
(4) 回圈等待條件:若干行程之間形成一種頭尾相接的回圈等待資源關系,
這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生死鎖,下列方法有助于最大限度地降低死鎖:
(1)按同一順序訪問物件,
(2)避免事務中的用戶互動,
(3)保持事務簡短并在一個批處理中,
(4)使用低隔離級別,
(5)使用系結連接,
5、資料庫索引的原理
資料庫索引,是資料庫管理系統中一個排序的資料結構,以協助快速查詢、更新資料庫表中資料,索引的實作通常使用B樹及其變種B+樹,
聚集索引與非聚集索引的區別
- 1).聚集索引一個表只能有一個,而非聚集索引一個表可以存在多個
- 2).聚集索引存盤記錄是物理上連續存在,而非聚集索引是邏輯上的連續,物理存盤并不連續
- 3).聚集索引:物理存盤按照索引排序;聚集索引是一種索引組織形式,索引的鍵值邏輯順序決定了表資料行的物理存盤順序
非聚集索引:物理存盤不按照索引排序;非聚集索引則就是普通索引了,僅僅只是對資料列創建相應的索引,不影響整個表的物理存盤順序. - 4).索引是通過二叉樹的資料結構來描述的,我們可以這么理解聚簇索引:索引的葉節點就是資料節點,而非聚簇索引的葉節點仍然是索引節點,只不過有一個指標指向對應的資料塊,
6、Redis 持久化機制和如何實作
redis有兩種持久化機制RDB與AOF,
- RDB持久化方式會在一個特定的間隔保存那個時間點的一個資料快照,
- AOF持久化方式則會記錄每一個服務器收到的寫操作,在服務啟動時,這些記錄的操作會逐條執行從而重建出原來的資料,寫操作命令記錄的格式跟Redis協議一致,以追加的方式進行保存,
- Redis的持久化是可以禁用的,就是說你可以讓資料的生命周期只存在于服務器的運行時間里,
兩種方式的持久化是可以同時存在的,但是當Redis重啟時,AOF檔案會被優先用于重建資料,
7、快取降級
- 頁面降級:在大促或者某些特殊情況下,某些頁面占用了一些稀缺服務資源,在緊急情況下可以對其整個降級,以達到丟卒保帥;
- 頁面片段降級:比如商品詳情頁中的商家部分因為資料錯誤了,此時需要對其進行降級;
- 頁面異步請求降級:比如商品詳情頁上有推薦資訊/配送至等異步加載的請求,如果這些資訊回應慢或者后端服務有問題,可以進行降級;
- 服務功能降級:比如渲染商品詳情頁時需要呼叫一些不太重要的服務:相關分類、熱銷榜等,而這些服務在例外情況下直接不獲取,即降級即可;
- 讀降級:比如多級快取模式,如果后端服務有問題,可以降級為只讀快取,這種方式適用于對讀一致性要求不高的場景;如果想學習Java工程化、高性能及分布式、深入淺出,微服務、Spring,MyBatis,Netty原始碼分析、雙十一實戰或者是面試難題的朋友可以看向文末,
- 寫降級:比如秒殺搶購,我們可以只進行Cache的更新,然后異步同步扣減庫存到DB,保證最終一致性即可,此時可以將DB降級為Cache,
- 爬蟲降級:在大促活動時,可以將爬蟲流量導向靜態頁或者回傳空資料,從而保護后端稀缺資源,
- 自動開關降級
自動降級是根據系統負載、資源使用情況、SLA等指標進行降級, - 超時降級
當訪問的資料庫/http服務/遠程呼叫回應慢或者長時間回應慢,且該服務不是核心服務的話可以在超時后自動降級;比如商品詳情頁上有推薦內容/評價,但是推薦內容/評價暫時不展示對用戶購物流程不會產生很大的影響;對于這種服務是可以超時降級的,如果是呼叫別人的遠程服務,和對方定義一個服務回應最大時間,如果超時了則自動降級,
8、Java Web學習路徑

9、Java編程所需的工具及知識

10、JVM的基本結構

11、SSH框架

12、設計模式之間的關系

13、JAVA知識結構體系圖

14、JAVA知識學習計劃圖

最后
需要更多學習資料和面試真題資料的小伙伴可以在文末獲取免費領取方式!!
1、Java核心知識點全解

2、1000道高頻知識點全面決議

3、Java高級架構面試知識點整理

說實話,作為一 名 Java 程式員,不論你需不需要面試都應該好好看下這份資料,我大概擼了一遍,真的是堪稱典范,拿到手總是不虧的~
以上《JAVA核心知識點總結》我已經全部為大家打包準備好了,希望對正在學習的你有所幫助!我的不少粉絲也因此拿到騰訊位元組快手offer~
需要以上全部資料的小伙伴,可以一鍵三連,下方獲取免費領取方式!
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/286639.html
標籤:其他

