一 .Java基礎php
抽象類:
含有abstract修飾符的class即爲抽象類。
特色:
1.不能建立的實例對象
2.能夠有抽象方法
3.能夠有構造方法,但構造方法不能是抽象的
4.抽象方法必須子類進行實現,若是子類只實現部分方法,該子類必須是抽象的。
接口:
含有interface修飾符的就是 。
特色:
1.接口中的全部方法都必須是抽象的
2.接口中的方法定義默認爲public abstract類型
3.接口中的成員變量類型默認爲public static final
區別:
1.單繼承多實現:一個類能夠實現多個接口,但只能繼承一個抽象類。
2.構造方法:抽象類能夠有構造方法,接口中不能有構造方法。(JDK7以前)
3.變量:抽象類中能夠有普通成員變量,接口中只有常量。
4.方法:抽象類中能夠包含非抽象的普通方法,接口中的全部方法必須都是抽象的,不能有非抽象的普通方法。
5.修飾符:抽象類中的抽象方法能夠使用public和protected進行修飾,但接口中的抽象方法只能使用public abstract修飾。
6.靜態方法:抽象類中能夠包含靜態方法,接口中不能包含靜態方法
7.抽象類和接口中均可以包含靜態成員變量,抽象類中的靜態成員變量的訪問類型能夠任意,但接口中定義的變量只能是public static final類型,而且默認即爲public static final類型。css
子類繼承抽象類時,構造函數不會被覆蓋。
並且,在實例化子類對象時首先調用的是抽象類中的構造函數再調用子類中的。
在這個階段初始化抽象類字段或執行其它與子類相關的代碼html
經常使用的集合有:
單列集合:List、Set
雙列集合:Map
一、List(有序、可重複)
List接口:比較經常使用的實現類是LinkedList與ArrayList+
LinkedList:基於鏈表實現,(鏈表實現,查詢慢,增刪快)
ArrayList:非線程安全的,效率高;(數組實現,查詢快,增刪慢)
二、Set(無序、不能重複)
Set接口:有兩個實現類(HashSet(底層由HashMap實現),LinkedHashSet)
HashSet特色:哈希表數據結構,查詢速度塊,HashSet底層使用HashMap,僅使用key。
LinkedHashSet繼承自HashSet,LinkedHashSet中的元素順序是能夠保證的,也就是說遍歷序和插入序是一致的。
三、Map(鍵值對、鍵惟1、值不惟一)
若是要向Map集合中存放兩個相同的key,後賦值給key的value的會把先賦值給key的value覆蓋掉。
Map接口:有三個實現類(HashMap,HashTable,LinkedHashMap)
HashMap:HashMap最多隻容許一條記錄的鍵爲Null;容許多條記錄的值爲 Null,不是線程安全的
LinkedHashMap:LinkedHashMap簡單來講是一個有序的HashMap,其是HashMap的子類,HashMap是無序的。
HashTable:Hashtable既不支持Null key也不支持Null value,是線程安全的
常見集合 描述 實現類
List 有序、可重複 LinkedList:基於鏈表實現,查詢慢,增刪快
ArrayList:數組實現,查詢快,增刪慢
Set 無序、不能重複 HashSet:哈希表數據結構,查詢速度塊
LinkedHashSet繼承自HashSet,LinkedHashSet中的元素順序是能夠保證的,也就是說遍歷序和插入序是一致的
Map 鍵值對、鍵惟1、值不惟一。
若是要向Map集合中存放兩個相同的key,後賦值給key的value的會把先賦值給key的value覆蓋掉。 HashMap:HashMap最多隻容許一條記錄的鍵爲Null;容許多條記錄的值爲 Null,不是線程安全的
LinkedHashMap:LinkedHashMap簡單來講是一個有序的HashMap,其是HashMap的子類,HashMap是無序的
HashTable:Hashtable既不支持Null key也不支持Null value,是線程安全的
前端
HashSet保存數據底層使用的是HashMap,保存元素時,保存的值爲key,而value值爲null。經過計算key值的hash值,
若是hash相同,再採用equals()方法比較倆值是否相同,若是相同,則覆蓋舊元素。
TreeSet:
1.若是指定了比較器Comparator,添加元素時會調用compare(T o1, T o2)方法進行比較倆個對象是否相同;
2.或TreeSet中保存的對象實現了Comparable接口,會使用Comparable接口的compareTo()方法判斷倆個對象是否相同;相同則覆蓋舊元素。
3.若是倆種方式都沒有使用,則會報錯html5
1.ArrayList的底層是動態數組;LinkedList的底層是雙向鏈表
2.增長元素:
ArrayList將元素追加至最後,ArrayList數組的默認初始大小爲10,若是新增元素後大小超過數組的容量,則會對數組進行擴容,默認擴容大小爲1.5倍;同時須要講舊數組中的元素copy到新數組中
LinkedList將元素添加到鏈表的末尾,新增的元素做爲最後一個節點
3.刪除元素
ArrayList根據index刪除元素,index索引上的元素被刪除,index索引後的元素向前平移一個單位,所以效率不高
LinkedList根據index刪除元素,改變index先後元素的指向,效率高;
4.插入元素
ArrayList在index位置上插入元素,需將原先index及日後的元素向後平移一個單位,效率不高
LinkedList在index位置插入元素,只需改變先後元素指向,效率高
5.查詢
ArrayList根據index可以直接定位到元素所在位置,效率高
LinkedList查詢時,須要從首個元素沿着鏈表進行查找,直到找到index索引處的元素,而後返回,效率不高java
1.藉助set集合
2.利用List的contains方法循環遍歷mysql
1.數組:
查詢多,增刪少;
由於數組必須事先定義固定的長度(元素個數),不能適應數據動態地增減的狀況,所以增刪少,查詢效率高;
2.鏈表:
查詢少,增刪多;
由於鏈表動態地進行存儲分配,能夠適應數據動態地增減的狀況,所以鏈表結構增刪多,查詢少;ios
HashMap底層數據結構爲數組+鏈表;在JDK1.8中當鏈表的長度超過8時,鏈表會轉換爲紅黑樹;
數組的默認數組長度爲16,數組的長度老是爲2的冪;當數組的某一個鏈表的長度超出擴容條件:數組長度*負載因子(默認0.75),如:數組長度16*0.75=12,那麼當鏈表(JDK1.7)或紅黑樹(JDK1.8)大小超過12,就會進行自動擴容;c++
一、若是數組尚未初始化(數組長度是0),則先初始化,默認16
二、經過hash方法計算key的hash值,hash值對數組長度進行取餘操做,進而計算獲得應該放置到數組的位置
三、若是該位置爲空,則直接放置此處
四、若是該位置不爲空,並且元素是紅黑樹,則插入到其中
五、若是是鏈表,則遍歷鏈表,若是找到相等的元素則替換,不然插入到鏈表尾部
六、若是鏈表的長度大於或等於8,則將鏈表轉成紅黑樹程序員
一、1.8中引入了紅黑樹,而1.7中沒有
二、1.8中元素是插在鏈表的尾部,而1.7中新元素是插在鏈表的頭部
三、擴容的時候,1.8中不會出現死循環,而1.7中容易出現死循環
(1)HashMap是非線程安全的,HashTable是線程安全的,內部的方法基本都通過synchronized修飾。
(2)由於同步、哈希性能等緣由,性能確定是HashMap更佳,所以HashTable已被淘汰。
(3) HashMap容許有null值的存在,而在HashTable中put進的鍵值只要有一個null,直接拋出NullPointerException。
(4)HashMap默認初始化數組的大小爲16,HashTable爲11。前者擴容時乘2,使用位運算取得哈希,效率高於取模。然後者爲乘2加1,都是素數和奇數,這樣取模哈希結果更均勻。
方法重寫(overriding):子類對父類的重寫。
方法重載(overloading):同一個類中重載已有的方法。
1)重寫的特色:
一、簽名一致:子類重寫的方法,必須與父類的方法,返回值、方法名和參數列表都相同。
二、異常窄化:子類拋出的異常要麼與父類方法拋出的異常相同,要麼拋出的異常是父類方法異常的子類或不拋出。(優生:父類有病,子類沒有病)
三、修飾符寬化:子類方法的的訪問級別不能低於父類相應方法的訪問級別(子類訪問級別不能低於父類訪問級別)
2)重載特色
擁有相同的方法名,可是參數列表不一樣(類型、個數、順序)
與返回值無關
與參數變量名無關
throw和throws都於異常有關。
throw:用於拋出異常。由方法體內的語句處理。
throws:用於聲明異常。由該方法的調用者來處理。
throw出如今方法體中,在不一樣的語句中可能有多處throw。每throw一次只能拋出一個異常。throw拋出異常後能夠當即try,也能夠在方法上使用throws進行聲明。
throws在方法上進行聲明,表示一個方法可能出現的異常,須要方法的調用者進行處理。一個方法能夠聲明多個異常
(1)java.lang.NullPointerException 【空指針異常】
(2)java.lang.ClassNotFoundException 【類找不到異常】
(3)java.lang.NumberFormatException 【數字格式化異常】
(4)java.lang.IndexOutOfBoundsException 【數組角標越界異常】或 【數組索引越界異常】
(5)java.lang.IllegalArgumentException 【非法參數異常】
(6)java.lang.ClassCastException 【類型轉換異常】數據類型轉換異常
(7)java.lang.NoClassDefFoundException 【類未定義異常】
(8)SQLException 操做數據庫異常 【SQL異常】
(9)java.io.IOException 【IO異常】
(10)java.lang.NoSuchMethodException 【沒有匹配方法異常】
(1)final:修飾符。
A).被聲明爲final的類,不能被繼承。
B).被聲明final的變量或者方法,不能被改變。
C).被聲明final的方法只能使用,不能被重載。
(2)finally:異常處理機制的一部分
A).finally結構使代碼總會執行,而無論有無無異常發生。
B).使用finally經常使用於釋放資源。
(3)finalize:Java中垃圾回收器執行的方法。
A).它是一個方法,屬於java.lang.Object類。
B).在垃圾收集器執行的時候會調用的此方法,進行對象的回收,但在調用垃圾回收gc()後,並不能當即執行回收,JVM根據算法定時執行。
1.從運行速度來看:
StringBuilder > StringBuffer > String
String爲字符串常量,而StringBuilder和StringBuffer均爲字符串變量,由於String對象一旦建立以後該對象是不可更改的,只會從新賦值,
然後二者的對象是變量,是能夠更改的,因此String運行速度最慢,而StringBuilder比StringBuffer 效率高,因此StringBuilder運行速度最快,其次StringBuffer 。
2.字符修改上的區別:
String:不可變字符串;顯然訪問權限 線程安全
StringBuffer:可變字符串、效率低、線程安全;
StringBuilder:可變字符序列、效率高、線程不安全;
3.關於單線程和多線程的推薦
若是程序不是多線程的,那麼使用StringBuilder效率高於StringBuffer。
4.總結:
String:適用於少許的字符串操做的狀況
StringBuilder:適用於單線程下在字符緩衝區進行大量操做的狀況
StringBuffer:適用多線程下在字符緩衝區進行大量操做的狀況
讀寫操做,咱們一般稱爲輸入/輸入(IO)操做。Java經過流進行IO操做的。
Java 中的流,能夠從不一樣的角度進行分類。
按流的方向分:輸入流和輸出流。
按處理數據單位分:字節流和字符流。
按實現功能分:節點流和處理流。
1.字節流: 字節輸入輸出流,處理二進制數據,它是按字節來處理的
InputStream是全部字節輸入流的祖先,
OutputStream是全部字節輸出流的祖先。
2.字符流: 字符輸入輸出流,處理字符數據
Reader是全部讀取字符串輸入流的祖先
writer是全部輸出字符串的祖先
字節高效流:
BufferedOutputStream 、BufferedInputStream
字符高效流:
BufferedWriter、BufferedReader
3.轉換流: 將字節流轉換爲字符流
OutputStreamWriter、InputStreamReader
4.緩衝流:讀入/寫出數據時,原理是現將數據緩衝起來,而後一塊兒寫入或者讀取出來;下降了對文件或者其餘目標頻繁的操做
5.對象流:用於寫入對象 的信息和讀取對象的信息。 使得對象持久化。須要被持久化的類須要實現接口 Serializable
InputStream -> BufferedInputStream -> InputStreamReader -> Reader -> BufferedReader
1.字符流主要是讀取文本文件內容的,能夠一個字符一個字符的讀取,也能夠一行一行的讀取文本文件內容,處理的單元爲 2 個字節的 Unicode 字符,分別操做字符、字符數組或字符串。
2.而字節流讀取單位爲字節(byte),字節做爲計算機存儲最基本單位,能夠用字節流來讀取不少其餘格式的文件,好比圖片歌曲視頻等等,處理單元爲 1 個字節,操做字節和字節數組。
字符流(一次能夠處理一個緩衝區)一次操做比字節流(一次一個字節)效率高。
只要是處理純文本數據(只是讀寫文件,和文件內容無關的),就要優先考慮使用字符流,除此以外都用字節流。
字符流的底層就是字節流(注:除了字符和字節流以外,java還有一種叫對象流。)
(1)break:
經常使用於循環中,含義:結束循環,跳出循環體
其餘應用場景:switch語句中,結束語句。
(2)continue:
結束本次循環,進行下一次循環;(注意:若是,循環進行到最後一次,continue執行,結束本次循環, 繼續進行循環邏輯判斷結束循環。循環結束與continue無關)
擴展:在循環嵌套中,能夠經過「循環標號」使內層循環結束外層循環,如:
out : for(......){
for(...){
break out; //結束外層out循環
}
}
1. ==比較的是值
1.1== 若是比較的是基本數據類型,比較的則是變量值
1.2 == 若是比較的爲引用數據類型,比較的則是地址值
2. equals比較的是引用數據類型
2.1若是沒有重寫hashCode和equals方法,比較的是地址值。由於Object的equals方法中使用是==。
2.2若是重寫hashCode和equals方法,則比較的重寫後的規則。
例如:兩個String字符串比較時:比較的是內容。由於String底層重寫了equals方法進行內容的比較。
& 位運算,求2個二進制數的與。也能夠進行邏輯運算,表達式左邊爲false,表達式右邊繼續執行。
&& 邏輯運算符,表達式左邊爲false,整個表達式結果爲false,所以表達式右邊不執行。此現象稱爲邏輯短路。
表達式1 & 表達式2 true & true == true
表達式1 && 表達式2 false && …. == false
表達式1 || 表達式2 true || …. == true
1. 區別:
i++ 是先賦值,後加減;
++i 是先加減,後賦值。
2.效率:
++i的效率高些,++i在運算過程當中不產生臨時對象,返回的就是i,是個左值,相似++i=1這樣的表達式是合法的,而i++在運算的過程當中會產生臨時對象,返回的是零時對象的值,是個右值,像i++=1這樣的表達式是非法的
對於內置類型,單獨的i++和++i語句,如今的編譯器基本上都會優化成++i,因此就沒什麼區別了xxxxxxxxxx java中的內存泄露的狀況:長生命週期的對象持有短生命週期對象的引用就極可能發生內存泄露,儘管短生命週期對象已經再也不須要,可是由於長生命週期對象持有它的引用而致使不能被回收,這就是java中內存泄露的發生場景Java中有垃圾回收機制,它能夠保證一對象再也不被引用的時候,對象將自動被垃圾回收器從內存中清除掉
"++i":先自增,後賦值
"i++":先賦值,後自增
"+=": 自身值相加 a+=b -> a = a+b
運算符的概念:
運算符是用來進行數據 計算/運算的指令
常量和變量均可以參與運算
被運算符操做的數據又稱操做數
注意:運算符通常只操做基本數據類型,不操做引用數據類型(String除外)
種類:
算術運算符、位運算符、賦值運算符、關係運算符、邏輯運算符、三目運算符、類型相關運算符
char型變量是用來存儲Unicode編碼的字符的,unicode編碼字符集中包含了漢字,因此,char型變量中固然能夠存儲漢字啦。不過,若是某個特殊的漢字沒有被包含在unicode編碼字符集中,那麼,這個char型變量中就不能存儲這個特殊漢字。補充說明:unicode編碼佔用兩個字節,因此,char類型的變量也是佔用兩個字節。
一個或兩個。
第一次執行 new String("xyz") ,"xyz"將在字符串常量池中建立一個對象。new String() 又在堆內存中建立一個對象,因此建立了兩個對象。
執行第二個語句new String("xyz") ,"xyz"第一次已經在常量池中建立,直接使用不用再建立。每new一次都會在堆內存中建立一個對象,new String() 再次在堆內存中建立對象,因此建立了一個對象。
collection:
1. 單列集合的頂級父接口
Collections:
1. 操做集合的工具類
2. 經常使用於:集合排序、集合不可修改限制等
GC是垃圾收集的意思。
Java中沒有提供手動分配內存的方式,也沒有提供手動釋放內存的方式。
分配和釋放所有采用自動完成。GC就用於自動回收內存
System.gc() 或Runtime.getRuntime().gc() 。
通常狀況下java中對象可被回收的前提是:該對象再也不被引用。而後垃圾回收器在回收的時候便會把這個對象清理掉
一、靜態集合類引發內存泄漏;
二、當集合裏面的對象屬性被修改後,再調用remove()方法時不起做用;
三、監聽器
四、各類鏈接
五、內部類和外部模塊的引用
六、單例模式( 一、死循環 二、遞歸)
https://blog.csdn.net/c_royi/article/details/79527518
若是使用迭代器遍歷,使用List提供的方法進行操做,將拋異常,異常是java.util.ConcurrentModificationException併發修改異常。
若是使用迭代器遍歷,使用迭代器提供對應方法,將不會拋異常。
不正確;存在編譯時異常,3.4是屬於Double類型的,轉換爲float須要強轉
如:float f = (float)3.4 或 float f = 3.4f
思考:
short s = 1, s=s+1; 是否有錯誤?
有錯誤,s爲short類型,與int類型的1相加,s+1的返回值爲int型 ,int賦值給short就會出現精準度不夠的錯誤提示
思考
short s += 1; 是否有錯誤?
+= 計算結果就是short類型,不存在強制類型的問題。
傳遞值是不會改變對象的屬性的,而傳遞地址是會改變對象的屬性的。因此上面的狀況是引用傳遞。
數組中只有 length 屬性, 不是方法, 沒有後面的那對括號, 而String 類中,沒有length屬性, 只有方法, 也就是 length() 後面有對括號. 屬性你能夠當作是 數組類中的 變量, 而 length()方法能夠當作是 String 類中定義好的方法
數組沒有length()這個方法,只有length的屬性:
String[] arr = {「1」,」2」,」3」};
System.out.println(「數組長度:」+arr.length);
String只有length()這個方法,沒有length屬性:
String str = 「123」;
System.out.println(「字符串長度:」+str.length());
Error和Exception都繼承自Throwable
Exception:
1.能夠是可被控制(checked) 或不可控制的(unchecked)。 2.表示一個由程序員致使的錯誤。 3.應該在應用程序級被處理。
Error:
1.老是不可控制的(unchecked)。 2.常常用來用於表示系統錯誤或低層資源的錯誤。 3.如何可能的話,應該在系統級被捕捉。 (一組xqy)
1.檢查異常 : 編譯時被檢測的異常,checked 異常也就是咱們常常遇到的IO異常,以及SQL異常都是這種異常。對於這種異常,JAVA編譯器強制要求咱們必需對出現的這些異常進行catch。因此,面對這種異常無論咱們是否願意,只能本身去寫一大堆catch塊去處理可能的異常。
2.運行時異常:編譯時不被檢查的異常,在程序運行的時候出現。當出現運行時異常,系統會把異常一直往上層拋,直到遇到try-catch對拋出的異常進行處理。若是異常一直沒有被處理,到最上層被拋出,那麼當前線程就會就退出了;若是是主程序拋出的異常,那麼這整個程序也就退出了
若是想自定義檢查性異常類,則須要繼承 Exception 類。
若是想自定義運行時異常類,那麼須要繼承 RuntimeException 類。
(1)this表明本類對應的引用。
(2)super表明父類存儲空間的標識(能夠理解爲父類引用能夠操做父類的成員)
不一樣點:super從子類中調用父類的構造方法,this()在同一類內調用其它構造方法。
相同點:super()和this()都必須在構造函數的第一行進行調用,不然就是錯誤的
1.修飾的類不能被繼承
2.修飾的方法不能被重寫
3.修飾的變量是常量不能被改變
4.可是final關鍵字不能用來修飾構造方法:
// 緣由:final修飾普通方法,將致使子類沒法重寫該方法,而構造方法自己就不可以被子類重寫,故若是用final修飾,如同畫蛇添足
static關鍵字爲靜態的
1.用來修飾成員變量,將其變爲類的成員,從而實現全部對象對於該成員的共享;
2.用來修飾成員方法,將其變爲類方法,能夠直接使用「類名.方法名」的方式調用,經常使用於工具類;
3.靜態代碼塊,在類被加載的時候就會被執行的代碼塊;
final關鍵字
1.用來修飾數據,包括成員變量和局部變量,該變量只能被賦值一次且它的值沒法被改變。對於成員變量來說,必須在聲明時或者構造方法中對它賦值;
2.修飾方法,表示該方法沒法被重寫;
3.修飾類,表示該類沒法被繼承。
區別:static做用於成員變量用來表示只保存一份副本,而final的做用是用來保證變量不可變
1.同步方法使用synchronized修飾方法,在調用該方法前,須要得到內置鎖(java每一個對象都有一個內置鎖),不然就處於阻塞狀態
代碼如: public synchronized void save(){//內容}
2.同步代碼塊使用synchronized(object){}進行修飾,在調用該代碼塊時,須要得到內置鎖,不然就處於阻塞狀態
代碼如:
synchronized(object){
//內容
}
1. 棧:Java虛擬機內存中的一片區域
(1) 調用方法將在棧中開闢內存,稱爲入棧(壓棧)。
(2) 棧內存存放基本類型值和引用數據類型的地址。
(3) 棧內存中的數據,沒有默認初始化值,須要手動設置。
(4) 方法調用完成,棧內存當即釋放,稱爲出棧(彈棧)。
2. 堆:Java虛擬機內存中的另外一片區域。
(1) 用於存放使用new建立的對象或數組。
(2) 全部的對象都有內存地址值。
(3) 數據都有默認初始化值。
(4) 堆內存中的對象再也不被指向時,JVM啓動垃圾回收機制,自動清除。
1.堆:主要用於存儲實例化的對象,數組。由JVM動態分配內存空間。一個JVM只有一個堆內存,線程是能夠共享數據的。
2.棧:主要用於存儲局部變量和對象的引用變量,每一個線程都會有一個獨立的棧空間,因此線程之間是不共享數據的。
3.方法區:又叫靜態區,跟堆同樣,被全部的線程共享。方法區包含全部的class和static變量。方法區中包含的都是在整個程序中永遠惟一的元素,如class,static變量。
1.ArrayList使用普通for循環效率更高,由於對於數組結構的數據來講,for循環採用的是下標訪問;
2.可是LinkedList是經過鏈表實現的,for循環時每獲取第i個元素都必須從頭開始遍歷;foreach底層是用迭代器實現,是經過iterator實現的遍歷,而iterator遍歷就是從頭開始遍歷,遍歷完只須要一次;因此使用加強for循環效率更高。
結論:for和foreach循環效率差很少,for循環稍微好一點;可是對於鏈表來講,for循環效率明顯比foreach低
1.JDK是整個JAVA的核心,包括Java運行環境JRE,一堆Java工具和Java基礎的類庫。經過JDK開發人員將源文件(Java文件)編譯成字節碼文件(class文件) 。
2.JRE是Java運行環境,不含開發環境,即沒有編譯器和調試器。將class文件加載到內存準備運行
3.JVM就是java虛擬機,是java實現跨平臺的最核心的部分。class文件運行整個環境。
傳遞基本數據類型,意味着傳遞了對象的一個副本。所以,就算是改變了對象副本,也不會影響源對象的值。
傳遞引用數據類型(對象),意味着傳遞的並非實際的對象,而是對象的引用(即對象的地址)。所以,外部對引用對象所作的改變會反映到全部的對象上。
不管是否拋出異常,finally代碼塊老是會被執行。就算是沒有catch語句同時又拋出異常的狀況下,finally代碼塊仍然會被執行。最後要說的是,finally代碼塊主要用來釋放資源,好比:I/O緩衝區,數據庫鏈接。
實現多態主要有如下三種方式:
1. 接口實現
2. 繼承父類重寫方法
3. 同一類中進行方法重載
Java中,靠的是父類或接口定義的引用變量能夠指向子類或具體實現類的實例對象,而程序調用的方法在運行期才動態綁定,就是引用變量所指向的具體實例對象的方法,也就是內存里正在運行的那個對象的方法,而不是引用變量的類型中定義的方法。
在jdk 1.7以前,switch只能支持byte, short, char, int或者其對應的封裝類以及Enum類型。從jdk 1.7以後switch開始支持String。
1.基本數據類型:
1.1 數值型:
1)整數類型(byte,short,int,long)
2)浮點類型(float,double)
1.2 字符型(char)
1.3 布爾型(boolean)
2.引用數據類型
2.1類(class)
2.2接口(interface)
2.3數組
1. xxx類型轉換字符串:String o = Xxx.toString( obj );
①.整型轉換成字符型
String num = Integer.toString(int n);
②.Long型轉換成字符型
String num = Long.toString(long n);
③.Short型轉換成字符型
String num = Short.toString(Short n);
④.Float型轉換成字符型
String num = Float.toString(Float n);
⑤.Double型轉換成字符型
String num = Double.toString(Double n);
2. String類型轉換爲xxx:Xxx x = Xxx.parseXxx(String s);
①.轉換成Int型
int/Integer num = Integer.parseInt(String str);
②.轉換成long型
Long/long num = Long.parseLong(String str);
③.轉換成short型
short/Short num = Short.parseShort(String str);
④.轉換成float型
float/Float num = Float.parseFloat(String str);
⑤.轉換成double型
double/Double num = Double.parseDouble(String str);
Static能夠修飾內部類、方法、變量、代碼塊
Static修飾的類是靜態內部類
Static修飾的方法是靜態方法,表示該方法屬於當前類的,而不屬於某個對象的,靜態方法也不能被重寫,能夠直接使用類名來調用。在static方法中不能使用this或者super關鍵字。
Static修飾變量是靜態變量或者叫類變量,靜態變量被全部實例所共享,不會依賴於對象。靜態變量在內存中只有一份拷貝,在JVM加載類的時候,只爲靜態分配一次內存。
Static修飾的代碼塊叫靜態代碼塊,一般用來作程序優化的。靜態代碼塊中的代碼在整個類加載的時候只會執行一次。靜態代碼塊能夠有多個,若是有多個,按照前後順序依次執行。
A.抽象的來說,多態的意思就是同一消息能夠根據發送對象的不一樣而採用多種不一樣的行爲方式。(發送消息就是函數調用)
b.實現的原理是動態綁定,程序調用的方法在運行期才動態綁定,追溯源碼能夠發現,JVM 經過參數的自動轉型來找到合適的辦法
a) 內部類能夠直接調用外部類包括private的成員變量,使用外部類引用的this.關鍵字調用便可
b) 而外部類調用內部類須要創建內部類對象
拆箱:把包裝類型轉成基本數據類型
裝箱:把基本數據類型轉成包裝類型
順序結構
選擇結構
循環結構
Equals Hashcode toString wait notify clone getClass
不能,數組一旦實例化,它的長度就是固定的
不是必須。抽象類能夠沒有抽象方法
含有抽象方法的類必定是抽象類
1.語法區別:靜態變量須要static關鍵字修飾,實例變量不須要。
2.程序運行時的區別:靜態變量從屬於類,實例變量從屬於對象。
3.存儲區域不一樣:靜態變量存儲在靜態存儲區,普通變量存儲在堆中
不能夠。由於非static是要與對象關聯在一塊兒的,必須建立一個後,才能夠在該對象上進行方法調用,而static方法調用時不須要建立對象,能夠直接使用。
Integer是Java爲int提供的封裝類。Integer的默認爲null。
int是Java的基本數據類型之一。int的默認爲0。
Integer能夠區分出未賦值和值爲0的區別,int則沒法表達出未賦值的狀況。
靜態初始化只在Class對象首次被加載的時候進行一次。
成員變量初始化,在new對象的時候被初始化,在構造函數的隱式三步其中一步進行初始化,初始化完成以後纔會執行構造器中的代碼
調用屬性
(1)this能夠調用本類中的任何成員變量
調用方法(可省略)
(2)this調用本類中的成員方法(在main方法裏面沒有辦法經過this調用)
調用構造方法
(3)this調用構造方法只能在本構造方法中調用另外一個構造方法
(4)this 調用構造方法必須寫在第一行
1.首先在環境變量中建立JAVA_HOME,給其賦值爲jdk的安裝路徑
2.而後在編輯環境變量中的path值,添加%JAVA_HOME%\bin
3.最後cmd打開命令模式,輸入java -version 檢查jdk環境變量是否配置成功
JAVA_HOME與java相關的系統環境變量。用於配置JDK的安裝目錄。
1.抽象
將一些事物的共性抽離出來歸爲一個類。
如對於動物,具備生命體徵、活動能力等區別於其它事物的共同特徵
2.封裝
有選擇地隱藏和暴露數據和方法
好比有U盤這個類,我但願隱藏內部組成和實現,只暴露USB接口以供使用
3.繼承
子類能夠直接使用父類的部分數據和方法,能夠有選擇的擴展
好比鳥是動物,但鳥擴展了飛行的能力。
4.多態
同一類的對象調用相同方法能夠表現出不一樣的行爲
好比動物實現了say()方法,猴子、馬等動物重寫了say()方法來表現不一樣的交流語言。
在面向對象中封裝是指隱藏對象的屬性和實現的細節,僅對外提供公共訪問方式。在類定義中用private關鍵字來實現封裝。
封裝的好處:
1.提升了數據的安全性和模塊化
別人不可以經過 變量名.屬性名 的方式來修改某個私有的成員屬性
2.提升了代碼的重用性
封裝成工具類之後可以減小不少繁瑣的步驟
3.隱藏內部屬性和實現方式
實現過程對調用者是不可見的,只需調用方法便可,不知道具體實現過程,且保護內部狀態
4.操做簡單
封裝後,多個調用者在使用的時候,只需調用方法便可,調用者不須要再進行判斷
5.增長代碼的可維護性和可靠性
一個類能夠任意的改變存儲數據的方式,只要仍舊使用相同的方法操做數據,那麼其餘
類就不知道或者介意這種變化
Java NIO中提供一種技術,是特定基本類型數據的容器。
Buffer是緩衝區頂層抽象類,常見的子類有:ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer
每一個緩衝區都是可讀取的,但並不是每一個緩衝區都是可寫入的。
緩衝區常見的3個特性:容量、限制和位置。
容量(capacity):緩衝區可以容納元素的最大數量。
限制(limit):第一個不該該讀取或寫入的元素的索引。
位置(position):下一個要讀取或寫入的元素的索引
一共四種:private、default(通常省略)、public、protected
權限 類內 同包 不一樣包子類 不一樣包非子類
private √ × × ×
default √ √ × ×
protected √ √ √ ×
public √ √ √ √
不能夠,由於String類有final修飾符,而final不能被繼承的
會執行,在方法返回調用者前執行
接口能夠繼承接口。抽象類能夠實現(implements)接口;實體類必須有明確的構造函數,抽象類纔可繼承實體類
匿名的內部類是沒有名字的內部類。不能extends(繼承) 其它類,但一個內部類能夠做爲一個接口,由另外一個內部類實現。
在運行狀態中,對於任意一個類,都可以獲取到這個類的全部屬性和方法,對於任意一個對象,都可以調用它的任意一個方法和屬性(包括私有的方法和屬性),這種動態獲取的信息以及動態調用對象的方法的功能就稱爲java語言的反射機制。通俗點講,經過反射,該類對咱們來講是徹底透明的,想要獲取任何東西均可以。
基本反射功能的實現
一、Class clazz1 = Class.forName("全限定類名");
二、Class clazz2 = 類名.class;
三、Class clazz3 = 類名.getClass();
JAVA反射機制:
是在運行狀態中,對於任意一個實體類,都可以知道這個類的全部屬性和方法;
對於任意一個對象,都可以調用它的任意方法和屬性;
這種動態獲取信息以及動態調用對象方法的功能稱爲java語言的反射機制。
反射機制的應用:
在運行時判斷任意一個對象所屬的類;
在運行時構造任意一個類的對象;
在運行時判斷任意一個類所具備的成員變量和方法;
在運行時調用任意一個對象的方法;
生成動態代理。
while結構在循環的開始判斷下一個迭代是否應該繼續。do/while結構在循環的結尾來判斷是否將繼續下一輪迭代。do結構至少會執行一次循環體。
Java虛擬機是能移植到不一樣硬件平臺上的軟件系統。
向下轉換是指由一個通用類型轉換成一個具體的類型,在繼承結構上向下進行。(能夠理解成強轉)
Object
數值提高是指數據從一個較小的數據類型轉換成爲一個更大的數據類型,byte,char,short值會被轉化成int類型。須要的時候int類型也可能被提高成long。long和float則有可能會被轉換成double類型。
數組是空的,沒有任何元素。不像C或者C++,第一個元素默認是程序名。若是命令行沒有提供任何參數的話,main方法中的String數組爲空,但不是null。
輸出array.length的值,若是是0,說明數組爲空。若是是null的話,會拋出空指針異常。
靜態變量、靜態代碼塊、靜態方法都是在編譯期
能夠,但只能有一個main方法擁有如下簽名:
public static void main(String[] args) {}
不然程序將沒法經過編譯。編譯器會警告你main方法已經存在。
JVM是一臺抽象的計算機,就像真實的計算機那樣,它們會先將.java文件編譯成.class文件(.class文件就是字節碼文件),而後用它的解釋器來加載字節碼。
不能夠。由於非static方法是要與對象關聯在一塊兒的,必須建立一個對象後,才能夠在該對象上進行方法調用,而static方法調用時不須要建立對象,能夠直接調用。因此,一個static方法內部不能夠發出對非static方法的調用。
對於short s1 = 1; s1 = s1 + 1; 因爲s1+1運算時會自動提高表達式的類型,因此結果是int型,再賦值給short類型s1時,編譯器將報告,須要強制轉換類型的錯誤。對於short s1 = 1; s1 += 1;因爲 += 是java語言規定的運算符,java編譯器會對它進行特殊處理,所以能夠正確編譯。
構造器Constructor不能被繼承,所以不能重寫Override,但能夠被重載Overload。
面向對象編程
顯示轉換就是類型強轉,把一個大類型的數據強制賦值給小類型的數據;隱式轉換就是大範圍的變量可以接受小範圍的數據;隱式轉換和顯式轉換其實就是自動類型轉換和強制類型轉換。
Stringbuilder或者stringbuffer的reverse方法
Integer.parseInt()
有,log4j是用來日誌記錄的,記錄一些關鍵敏感的信息,一般會將日誌記錄到本地文件或者數據庫中。記錄在本地文件中,會有頻繁的io操做,會耗費一些系統資源。記錄在數據庫中,會頻繁地操做數據庫表,對系統性能也有必定的影響。可是爲了程序安全以及數據的恢復或者bug的跟蹤,這點資源消耗是能夠承受的。
由低到高:debug、info、wran、error
不會,在下一個垃圾回收週期中,這個對象將是可被回收的。
序列化:將java對象轉換爲可保持或可傳輸的格式,即轉換爲二進制字節序列(字節流)的形式的過程。
反序列化:將二進制字節序列(字節流)形式的java對象解析出來的過程。
序列化能夠實現數據的持久化,也就是說能夠將數據永久的保存在磁盤上。
序列化能夠實現遠程通信,即在網絡上以二進制字節序列的格式傳送對象。
序列化能夠將對象狀態保存,方便下次取出利用。
有了序列化,兩個進程就能夠在網絡上任性的交互數據了。
被transient關鍵字修飾的變量再也不能被序列化,一個靜態變量無論是否被transient修飾,均不能被序列化。
實現Serializable接口
會執行,若是有finally,在finally以後被執行,若是沒有finally,在catch以後被執行
https://www.cnblogs.com/Good-good-stady-day-day-up/p/9055698.html
java中的內存泄露的狀況:長生命週期的對象持有短生命週期對象的引用就極可能發生內存泄露,儘管短生命週期對象已經再也不須要,可是由於長生命週期對象持有它的引用而致使不能被回收,這就是java中內存泄露的發生場景
Java中有垃圾回收機制,它能夠保證一對象再也不被引用的時候,對象將自動被垃圾回收器從內存中清除掉
1.內存泄露:是指程序在申請內存後,沒法釋放已申請的內存空間。
2.常發性內存泄漏:發生內存泄漏的代碼被屢次執行到,每次執行都會致使一塊內存泄漏。
3.偶發性內存泄漏:發生內存泄漏的代碼只在某些特定環境或操做下才會發生。常發性和偶發性是相對的。對於特定的環境,偶發性的也許就變成了常發性的。
4.一次性內存泄漏:發生內存泄漏的代碼只會被執行一次,或者因爲算法上的缺陷,致使總會有一塊且只有一塊內存發生泄漏。
5.隱式內存泄漏:程序在運行過程當中不停的分配內存,可是直到結束的時候才釋放內存。
一次內存泄露危害能夠忽略,但內存泄露堆積後果很嚴重,不管多少內存,早晚會被佔光,最終致使內存溢出。
1.clone()不會調用構造方法;new會調用構造方法。
2.new 操做符的本意是分配內存。程序執行到 new 操做符時,首先去看 new 操做符後面的類型,由於知道了類型, 才能知道要分配多大的內存空間。分配完內存以後,再調用構造函數,填充對象的各個域,這一步叫作對象的初始化,構造方法返回後,一個對象建立完畢,能夠把他的引用(地址)發佈到外部,在外部就能夠使用這個引用操縱這個對象。
clone 在第一步是和 new 類似的,都是分配內存,調用 clone 方法時,分配的內存和原對象(即調用 clone 方法的對象)相同,而後再使用原對象中對應的各個域,填充新對象的域,填充完成以後,clone 方法返回,一個新的相同的對象被建立,一樣能夠把這個新對象的引用發佈到外部。
1.爲何要克隆?
①方便,克隆的對象可能包含一些已經修改過的屬性,而new出來的對象的屬性都仍是初始化時候的值,因此當須要一個新的對象來保存當前對象的「狀態」使用clone方式很方便;
②速度快,clone方法最終將調用JVM中的原生方法完成複製也就是調用底層的c++代碼,因此通常使用clone方法複製對象要比新建一個對象而後逐一進行元素複製效率要高。
2.實現clone
① 實現Cloneable接口並重寫Object類中的clone()方法;
② 實現Serializable接口,經過對象的序列化和反序列化實現克隆,能夠實現真正的深度克隆。
對象序列化後寫入流中,再從流中讀取,生成新的對象,新對象和原對象之間也是徹底互不影響的。
1.淺克隆:只複製基本類型的數據,引用類型的數據只複製了引用的地址,引用的對象並無複製,在新的對象中修改引用類型的數據會影響原對象中的引用。
2.深克隆:是在引用類型的類中也實現了clone,是clone的嵌套,複製後的對象與原對象之間徹底不會影響。
一、類是對象的模版,對象是類的實例;
二、一個類能夠建立N個對象,每一個對象都是獨一無二的。
OOP(object oriented programming),即面向對象編程,其中兩個最重要的概念就是類和對象
類:對現實世界事物的抽象表示,包括事物的狀態信息(成員變量)和行爲信息(成員方法)。
對象:對抽象事物的具體表示,使其具備自身的特色。對類進行實例化能夠獲得對象。
Static Nested Class是被聲明爲靜態(static)的內部類,它能夠不依賴於外部類實例被實例化。而一般的內部類須要在外部類實例化後才能實例化
都不能。抽象方法須要子類重寫,而靜態的方法是沒法被重寫的,所以兩者是矛盾的。本地方法是由本地代碼(如C代碼)實現的方法,而抽象方法是沒有實現的,也是矛盾的。synchronized和方法的實現細節有關,抽象方法不涉及實現細節,所以也是相互矛盾的。
徹底能夠。若是不是靜態內部類,那沒有什麼限制!
若是你把靜態嵌套類看成內部類的一種特例,那在這種狀況下不能夠訪問外部類的普通成員變量,而只能訪問外部類中的靜態成員
1).內省(Introspector)是Java 語言對Bean類屬性、事件的一種缺省處理方法。例如類 A 中有屬性 name, 那咱們能夠經過 getName,setName 來獲得其值或者設置新的值。經過 getName/setName 來訪問 name 屬性,這就是默認的規則。
Java 中提供了一套 API 用來訪問某個屬性的 getter/setter 方法,經過這些 API 能夠使你不須要了解這個規則(但你最好仍是要搞清楚),這些 API 存放於包 java.beans 中。
2).直接經過屬性的描述器java.beans.PropertyDescriptor類,來訪問屬性的getter/setter 方法;
String str = "sfds55d676455dfg32434eertre";
String longStr =new String(str.replaceAll("[^\\d]+", ""));
正則(擴展 如:s.replaceAll(「[^0-9]「,」"),這樣非數字就所有去除了,只保留數字了
System.out.println("字符串=========:" + longStr);
沒有。由於String是不可變類(immutable class),不可變類
分支語句(if語句,switch語句);
循環語句(for,while,do...while);
跳轉語句(break,continue,return)
break
java中的內存泄露的狀況:長生命週期的對象持有短生命週期對象的引用就極可能發生內存泄露,儘管短生命週期對象已經再也不須要,可是由於長生命週期對象持有它的引用而致使不能被回收
Java的類是單繼承的,即每一個類只能繼承一個類。可是,Java中也有多繼承,接口支持多繼承,即一個接口能夠繼承多個接口
第一種.class獲取對象 :類型.class
Class ForClass = **.**.ClassName.class;(類在包中的路徑加.class)
第二種:經過類自己來得到對象 :對象.getClass()
Class classname = this.getClass();
第三種方式:經過類名的字符串獲取對象 :Class.forName()
Class ForName = Class.forName("**.**.ClassName");
在jdbc中經常使用到。
第四種方式:經過子類的實例獲取父類的類對象,
User cn = new User();
Class userClass = cn.getClass();
Class subUserClass = userClass.getSuperclass();
` 1.使用new關鍵字
2.使用Class類的newInstance方法
3.使用Constructor類的newInstance方法
4.使用Clone的方法:不管什麼時候咱們調用一個對象的clone方法,JVM就會建立一個新的對象,將前面的對象的內容所有複製,返回一個新的對象,用clone方法建立對象並不會調用任何構造函數。
5.使用反序列化:當咱們序列化和反序列化一個對象,JVM會給咱們建立一個單獨的對象,在反序列化時,JVM建立對象並不會調用任何構造函數。
1)常見的三種方法,toString(),equals()和clone()
a)toString()方法是將對象中的內容轉換成字符串的形式
b)equals()方法是將兩個對象的內容進行比較,若是內容相同,則返回true,不然返回false
c)clone()方法是將一個存在的對象進行克隆
2) 要使用Object的clone()方法,得先繼承Cloneable接口,爲了達到真正的克隆效果 須要對clone()方法進行重寫
3) 在使用Object類的toString() equals() clone()方法時,一般會對這三個函數進行重寫後再使用
4)要使用clone()方法得先繼承Cloneable接口
1)什麼是線程:
在一個進程中,每一個獨立的功能都須要獨立的去運行,這時又須要把當前這個進程劃分紅多個運行區域,每一個獨立的小區域(小單元)稱爲一個線程。
例如:360殺毒軟件,同時既能夠安全體檢電腦又能夠清理電腦中的垃圾。那麼這裏的安全體檢是360殺毒軟件中的一個線程,清理電腦中的垃圾也是一個線程。
2)什麼是多線程:
一個進程若是隻有一條執行任務,則稱爲單線程程序。
一個進程若是有多條執行任務,也就是說在一個進程中,同時開啓多個線程,讓多個線程同時去完成某些任務(功能)。則稱爲多線程程序。
多線程環境中,且存在數據共享,一個線程訪問的共享數據被其它線程修改了,那麼就發生了線程安全問題;整個訪問過程當中,無一共享的數據被其餘線程修改,就是線程安全的
1.使用線程同步機制,使得在同一時間只能由一個線程修改共享數據;
2.消除共享數據:即多個線程數據不共享或者共享的數據不作修改,將全局數據轉換爲局部數據;
如在SpringMVC中,就採用的該種方式解決線程安全問題。在Controller中,service爲多個線程共享的數據,可是service爲單例的,且不會被修改;controller中的方法,接收請求數據方式爲局部變量,多個線程不共享數據。即不會產生線程安全問題
當有一個線程在對內存進行操做時,其餘線程都不能夠對這個內存地址進行操做,直到該線程完成操做, 其餘線程才能對該內存地址進行操做,而其餘線程又處於等待狀態
1)進程是一個具備獨立功能的程序,一個程序必須有一個進程,一個進程至少有一個線程。
2)線程是進程的一個實體 ,是進程中的一個方法功能。
舉例 : 一我的有一雙手,可是有十個手指,一雙手就比如是一個進程,十個手指就比如是十個線程。
有三種方式建立多線程
(1)經過繼承 Thread 類建立
(2)經過實現 Runnable 接口建立
*優先使用實現 Runnable 接口建立,由於 Java 中是單繼承,一個類只有一個父類,若繼承了 Thread 類,就沒法在繼承其它類,
①避免了Java單繼承的侷限性;
②把線程代碼和任務的代碼分離,解耦合(解除線程代碼和任務的代碼模塊之間的依賴關係)。代碼的擴展性很是好;
③方式二能夠更方便、靈活的實現數據的共享
(3)經過實現 Callable 接口建立(不經常使用)
1)wait():使一個線程處於等待(阻塞)狀態,而且釋放所持有的對象的鎖;
2)sleep(): 使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要處理InterruptedException 異常;
3)notify():喚醒一個處於等待狀態的線程,固然在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由 JVM 肯定喚醒哪一個線程,並且與優先級無關;
4)notityAll():喚醒全部處於等待狀態的線程,該方法並非將對象的鎖給全部線程,而是讓它們競爭,只有得到鎖的線程才能進入就緒狀態;
注意:java 5 經過 Lock 接口提供了顯示的鎖機制,Lock 接口中定義了加鎖(lock()方法)和解鎖(unLock()方法),加強了多線程編程的靈活性及對線程的協調
啓動一個線程是調用start()方法,使線程就緒狀態,之後能夠被調度爲運行狀態,能夠由JVM調度並執行,但不必定會當即運行。一個線程必須關聯一些具體的執行代碼,run()方法是該線程所關聯的執行代碼。
就是事先建立若干個可執行的線程放入一個池(容器)中,須要的時候從池中獲取線程
不用自行建立,使用完畢不須要銷燬線程而是放回池中,從而減小建立和銷燬線程對象的開
銷。
經常使用線程池:
(1)newSingleThreadExecutor:建立一個單線程的線程池,此線程池保證全部任務的執行順序按照任務的提交順序執行。
(2)newFixedThreadPool:建立固定大小的線程池,每次提交一個任務就建立一個線程,直到線程達到線程池的最大大小。
(3)newCachedThreadPool:建立一個可緩存的線程池,此線程池不會對線程池大小作限制,線程池大小徹底依賴於操做系統(或者說 JVM)可以建立的最大線程大小。
(4)newScheduledThreadPool:建立一個大小無限的線程池,此線程池支持定時以及週期性執行任務的需求。
(5)newSingleThreadExecutor:建立一個單線程的線程池。此線程池支持定時以及週期性執行任務的需求。
兩個進程都在等待對方執行完畢才能繼續往下執行的時候就發生了死鎖。結果就是兩個進程 都陷入了無限的等待中
死鎖是指每一個線程都在等待被其它線程佔用並堵塞了資源
例:若是線程A鎖住了記錄1並等待記錄2,而線程B鎖住了記錄2並等待記錄1,這樣兩個線程就發生了死鎖現象
死鎖分爲2種鎖:排它鎖和共享鎖
①系統資源的競爭
一般系統中擁有的不可剝奪資源,其數量不足以知足多個進程運行的須要,使得進程在 運行過程當中,會因爭奪資源而陷入僵局,如磁帶機、打印機等。只有對不可剝奪資源的競爭 纔可能產生死鎖,對可剝奪資源的競爭是不會引發死鎖的。
②進程推動順序非法
進程在運行過程當中,請求和釋放資源的順序不當,也一樣會致使死鎖。例如,併發進程 P一、P2分別保持了資源R一、R2,而進程P1申請資源R2,進程P2申請資源R1時,二者都 會由於所需資源被佔用而阻塞
產生死鎖必須同時知足如下四個條件,只要其中任一條件不成立,死鎖就不會發生。
①互斥條件(Mutual exclusion):資源不能被共享,只能由一個進程使用。
②請求與保持條件(Hold and wait):進程已得到了一些資源,但因請求其它資源被阻塞時,對已得到的資源保持不放。
③不可搶佔條件(No pre-emption) :有些系統資源是不可搶佔的,當某個進程已得到這種資源後,系統不能強行收回,只能由進程使用完時本身釋放。
④循環等待條件(Circular wait):若干個進程造成環形鏈,每一個都佔用對方申請的下一個資源。
①加鎖順序(線程按照必定的順序加鎖,只有得到了從順序上排在前面的鎖以後,才能獲取後面的鎖)
②加鎖時限(線程嘗試獲取鎖的時候加上必定的時限,超過期限則放棄對該鎖的請求,並釋放本身佔有的鎖)
③死鎖檢測 (判斷系統是否處於死鎖狀態)
④死鎖避免(指進程在每次申請資源時判斷這些操做是否安全。例如銀行家算法:在分配資源以前先看清楚,資源分配後是否會致使系統死鎖。若是會死鎖,則不分配,不然就分配。)
使用多線程的時候,一種很是簡單的避免死鎖的方式就是:指定獲取鎖的順序,並強制線程按照指定的順序獲取鎖。所以,若是全部的線程都是以一樣的順序加鎖和釋放鎖,就不會出現死鎖了。
有些業務邏輯在執行過程當中要求對數據進行排他性的訪問,因而須要經過一些機制保證在此過程當中數據被鎖住不會被外界修改,這就是所謂的鎖機制。
優勢:保證資源同步
缺點:有等待確定會慢
悲觀鎖
老是假設最壞的狀況,每次去拿數據的時候都認爲別人會修改,因此每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖(共享資源每次只給一個線程使用,其它線程阻塞,用完後再把資源轉讓給其它線程)。傳統的關係型數據庫裏邊就用到了不少這種鎖機制,好比行鎖,表鎖等,讀鎖,寫鎖等,都是在作操做以前先上鎖。Java中synchronized和ReentrantLock等獨佔鎖就是悲觀鎖思想的實現。
樂觀鎖
老是假設最好的狀況,每次去拿數據的時候都認爲別人不會修改,因此不會上鎖,可是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據。樂觀鎖適用於多讀的應用類型,這樣能夠提升吞吐量。能夠使用版本號機制和CAS算法實現(本身瞭解)
悲觀鎖:
悲觀鎖併發模式假定系統中存在足夠多的數據修改操做,以至於任何肯定的讀操做均可能會受到由個別的用戶所製造的數據修改的影響。也就是說悲觀鎖假定衝突總會發生,經過獨佔正在被讀取的數據來避免衝突。可是獨佔數據會致使其餘進程沒法修改該數據,進而產生阻塞,讀數據和寫數據會相互阻塞。
樂觀鎖:
樂觀鎖假定系統的數據修改只會產生很是少的衝突,也就是說任何進程都不大可能修改別的進程正在訪問的數據。樂觀併發模式下,讀數據和寫數據之間不會發生衝突,只有寫數據與寫數據之間會發生衝突。即讀數據不會產生阻塞,只有寫數據纔會產生阻塞。
1、設計模式的分類(瞭解)
整體來講設計模式分爲三大類:
建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。
結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。
行爲型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、 狀態模式、訪問者模式、中介者模式、解釋器模式。
2、單例模式
單例設計模式
單例模式的好處:
1.某些類的建立比較頻繁,對於一些大型的對象,這是一筆很大的開銷。
2.省去了new的操做,節省了內存的開銷,減輕了GC的壓力。
3.有些狀況只能用單例的設計模式,例如,一些交易核心,只能用一個對象,否則就會亂套了。
餓漢式:(線程安全的)
public class Singleton {
// 私有的構造方法
private Singleton(){
}
// 指向本身實例的私有靜態引用
private static Singleton singleton = new Singleton();
// 以本身實例爲返回值的靜態的公有的方法
public static Singleton getInstance() {
return singleton;
}
}
懶漢式(線程不安全)
public class Singleton {
// 私有的構造方法
private Singleton() {
}
// 不創建對象
private static Singleton singleton = null;
// 以本身實例爲返回值的靜態的公有的方法
public static Singleton getInstance() {
if (singleton == null) {// 先判斷是否爲空
singleton = new Singleton();// 若是爲空創建對象
}
return singleton;
}
}
注:能夠經過枚舉實現單例模式的絕對單例
3、工廠模式
1.意圖:定義一個建立對象的接口,讓其子類本身決定實例化哪個工廠類,工廠模式使其建立過程延遲到子類進行。
2.主要解決:主要解決接口選擇的問題。
3.什麼時候使用:咱們明確地計劃不一樣條件下建立不一樣實例時。
4.如何解決:讓其子類實現工廠接口,返回的也是一個抽象的產品。
5.關鍵代碼:建立過程在其子類執行
4、適配器模式
1.意圖:將一個類的接口轉換成客戶但願的另一個接口。適配器模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。
2.主要解決:主要解決在軟件系統中,經常要將一些"現存的對象"放到新的環境中,而新環境要求的接口是現對象不能知足的。
3.什麼時候使用:
1)系統須要使用現有的類,而此類的接口不符合系統的須要。
2)想要創建一個能夠重複使用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在未來引進的類一塊兒工做,這些源類不必定有一致的接口。
3)經過接口轉換,將一個類插入另外一個類系中。(好比老虎和飛禽,如今多了一個飛虎,在不增長實體的需求下,增長一個適配器,在裏面包容一個虎對象,實現飛的接口。)
4.如何解決:繼承或依賴(推薦)。
5.關鍵代碼:適配器繼承或依賴已有的對象,實現想要的目標接口。
一、這兩個方法來自不一樣的類分別是,sleep來自Thread類,和wait來自Object類。
sleep是Thread的靜態類方法,誰調用的誰去睡覺,即便在a線程裏調用了b的sleep方法,實際上仍是a去睡覺,要讓b線程睡覺要在b的代碼中調用sleep。
Java中可在方法名前加關鍵字syschronized來處理當有多個線程同時訪問共享資源時候的問題。syschronized至關於一把鎖,當有申請者申請該資源時,若是該資源沒有被佔用,那麼將資源交付給這個申請者使用,在此期間,其餘申請者只能申請而不能使用該資源,當該資源被使用完成後將釋放該資源上的鎖,其餘申請者可申請使用。併發控制主要是爲了多線程操做時帶來的資源讀寫問題。若是不加以空間可能會出現死鎖,讀髒數據、不可重複讀、丟失更新等異常。
併發操做能夠經過加鎖的方式進行控制,鎖又可分爲樂觀鎖和悲觀鎖。
新建(New)、就緒(Runnable)、運行(Running)、阻塞(Blocked)和死亡(Dead)5種狀態
一、TCP(面向鏈接如打電話要先撥號創建鏈接),創建TCP鏈接需通過三次握手,釋放TCP鏈接需通過四次揮手;UDP是無鏈接的,即發送數據以前不須要創建鏈接
二、TCP提供可靠的服務。也就是說,經過TCP鏈接傳送的數據,無差錯,不丟失,不重複,且按序到達;UDP盡最大努力交付,即不保證可靠交付
Tcp經過校驗和,重傳控制,序號標識,滑動窗口、確認應答實現可靠傳輸。如丟包時的重發控制,還能夠對次序亂掉的分包進行順序控制。
三、UDP具備較好的實時性,工做效率比TCP高,適用於對高速傳輸和實時性有較高的通訊或廣播通訊。
4.每一條TCP鏈接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通訊
五、TCP對系統資源要求較多,UDP對系統資源要求較少。
Servlet是服務器程序,可以響應客戶端請求,動態的響應給客戶端web內容。
(1)加載和實例化:當Servlet容器啓動或客戶端發送一個請求時,Servlet容器會查找內存中是否存在該Servlet實例,若存在,則直接讀取該實例響應請求;若是不存在,就建立一個Servlet實例。
(2) 初始化init():實例化後,Servlet容器將調用Servlet的init()方法進行初始化(一些準備工做或資源預加載工做)。
(3)服務service():初始化後,Servlet處於能響應請求的就緒狀態。當接收到客戶端請求時,調用service()的方法處理客戶端請求,HttpServlet的service()方法會根據不一樣的請求 轉調doGet()/doPost()方法。
(4)銷燬destroy():當Servlet容器關閉時,Servlet實例也隨時銷燬。其間,Servlet容器會調用Servlet 的destroy()方法去判斷該Servlet是否應當被釋放(或回收資源)。
init():Servlet實例化後,Servlet容器會調用init()方法來初始化該對象 service():容器調用service()方法來處理客戶端的請求
destroy():Servlet對象應該從服務中被移除的時候,容器會調用該對象的destroy()方法
getServletConfig():ServletConfig對象包含了Servlet的初始化參數
getServletInfo():返回一個String類型的字符串,其中包括了關於Servlet的信息
異步處理容許Servlet從新發起一條新線程去調用 耗時業務方法,這樣就能夠避免等待
一、request.getParameterValues("參數"); //得到指定參數名的一組參數值 (String[])
二、request.getParameter("參數"); //得到指定參數名的一個參數值(String) , UserServlet?username=jack , 經過username得到值jack
Servlet不是線程安全的。Servlet 默認是單例模式,在web 容器中只建立一個實例,因此多個線程同時訪問servlet的時候,Servlet是線程不安全的。
jsp是動態web頁面,其本質上就是一個Servlet,它是Servlet的一種特殊形式,咱們便可以在jsp頁面中書寫html、css、JavaScript等前臺代碼,也能夠書寫java代碼。
Servlet是服務器程序,可以響應客戶端請求,動態的響應給客戶端web內容。
jsp和servlet的區別:
jsp是html頁面中內嵌Java代碼,側重頁面顯示;Servlet是中書寫Java代碼,側重邏輯控制;
mvc設計思想中jsp位於視圖層,servlet位於控制層
1.page: 當前頁(this)
2.config: 配置對象ServletConfig
3.servletContext: servlet上下對象
4.request:請求對象ServletRequest
6.session:服務器會話對象,HTTPSession
5.response:響應對象 ServletResponse
7.out: 輸出對象 PrintWriter,response.getWriter()
8.exception: 異常對象,記錄service出現全部的錯誤
9.application:PageContext jsp頁面的上下文對象
request:是客戶端發送到服務器的請求,包含客戶端的請求信息,使用request進行數據的傳遞,一次請求之間的數據共享;
response:是服務器傳回客戶端的響應信息,使用response將服務器數據響應給客戶端;
session:一次會話,其中保存着一次會話須要共享的全部數據,如SessionID、用戶信息等;
pageContext:管理當前頁面的數據;
application:服務器啓動時建立,服務器關閉時中止,爲多個應用程序保存信息
out 用來傳送回應的輸出
config servlet的構架部件
page JSP網頁自己
exception 針對錯誤網頁,未捕捉的例外
application:在全部應用程序中有效 session:在當前會話中有效 request:在當前請求中有效 page:在當前頁面有效
經過page指令設置<%@ page isThreadSafe="false"%>,默認Servlet支持多線程模式
<% %>裏邊放的是java代碼 <%= %> 至關於 <%out.print();%> <% %>是腳本 <%= %>是表達式
1)查看jsp文件頭是否設置了編碼格式:
2)查看項目的編碼格式:設置爲UTF-8
3)在請求頭響應頭設置編碼:
//設置編碼格式
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
1. 過濾器是Servlet中對用戶請求服務器資源攔截的技術
2. 當客戶端請求服務器的web資源,如:Jsp,Servlet,靜態圖片文件或靜態HTML等時,經過Filter能夠對這些請求進行攔截,在執行真正請求以前作一些通用的工做,如統一編碼、統一用戶認證等工做。認證成功後,過濾器執行放行動做,再執行真正的請求。
3. 應用場景:統一編碼、統一用戶認證、屏蔽非法文字,進行響應數據壓縮,等等
1. 什麼是監聽器:所謂的監聽器是指對WEB環境中Request、Session和ServletContext等的監聽,當被監視的對象的建立、銷燬或者屬性發生變化時,便調用相應的方法進行處理。
2. 使用場景:網站在線人數統計、監聽用戶的行爲(管理員踢人),等等
3. 網站在線人數統計:使用監聽器監聽session的建立與銷燬,當session會話被建立時,在線用戶人數+1,當session會話被銷燬時,在線用戶人數-1
Cookie是web服務器發送給瀏覽器的一塊信息,瀏覽器會在本地一個文件中給每一個web服務器存儲cookie。瀏覽器再給特定的web服務器發送請求時,同時會發送全部該服務器存儲的cookie。
Session是存儲在web服務器的一塊信息。session對象存儲特定用戶會話所需的屬性及配置信息。當用戶在應用程序Web頁面之間跳轉時,存儲在Session對象中的變量將不會丟失,而是在整個會話中一直存在下去。
區別:
1.cookie存儲在客戶端(瀏覽器),session存儲在服務器端;
2.數據量:cookie只能存儲少許的數據,session能夠存放大量數據(服務器內存有多大,就能存儲多大的數據)
3.在存儲數據方面:session能存儲任意java對象,cookie只能存儲英文。
4.從生命週期方面:
session默認的生命週期時間間隔是30分鐘(session的生命週期是間隔的,從建立時,開始計時如在30分鐘,沒有訪問session,那麼session生命週期被銷燬,可是,若是在30分鐘內(如在第19分鐘時)訪問過session,那麼,將從新計算session的生命週期);
若是沒有設置cookie的存活時間,當瀏覽器關閉的時候,cookie便消失了。若是設置cookie有效時間,過時後,瀏覽器在發送請求前,將刪除對應的cookie。
session.setMaxInactiveInterval(設置時間/秒)
1.提示用戶不要禁用cookie;
2.使用URL重寫技術解決cookie被禁用問題:https://blog.csdn.net/m0_38039437/article/details/76718541
3.使用html5的localStorage替代cookie
token只是一個32位的UUID:SSSSSSSSUDUDUDUDUDUUDUDUDUD
session是瀏覽器與服務器的一次會話,在此次會話中包含屢次的request(請求)
在HTML5中,新加入了一個localStorage特性,這個特性主要是用來做爲本地存儲來使用的,解決了cookie存儲空間不足的問題(cookie中每條cookie的存儲空間爲4k),localStorage中通常瀏覽器支持的是5M大小,這個在不一樣的瀏覽器中localStorage會有所不一樣。
1xx(請求成功):用於表示臨時響應並須要請求者執行操做才能繼續的狀態代碼;
2xx:用於表示服務器已成功處理了請求的狀態代碼;
3xx(請求被重定向):一般這些狀態代碼是用於重定向的;
4xx(客戶端錯誤):用於指出客戶端的錯誤;
5xx(服務器錯誤):這些狀態代碼表示,服務器在嘗試處理請求時發生內部錯誤
常見狀態碼:
200,服務器已成功處理了請求。通常用於查詢
301/302,請求重定向
400,請求路徑語法錯誤
404,請求資源不存在
405,請求方式不正確,如:一個資源只支持GET方法,可是客戶端使用PUT方法訪問。
500,服務器遇到錯誤,沒法完成請求。
URL 重寫是攔截客戶端傳入 Web 請求URL,並獲取其URL從新寫成網站能處理的URL的過程。好比瀏覽器發來請求 http://blog.mocoder.com/hello.html ,服務器自動將這個請求中定向爲http://blog.mocoder.com/test.do?method=hello。
URL重寫的做用:
1.提供安全性:有些大網站採用不一樣的技術開發不一樣功能的頁面。而把拓展名改掉,讓黑客沒法確認此頁面用的技術是什麼,從而就無從下手。
2.方便訪問者使用。訪問者不是程序員,他們不明白什麼是.jsp,.php.aspx,他們只知道URL。因此統一把拓展名拿掉,或者贊成把拓展名換爲html,htm,有利於用戶的使用。
3.使用URL重寫技術能夠有效解決cookie被禁用問題。
1.是什麼:Ajax 是一種在無需從新加載整個網頁的狀況下,可以更新部分網頁的技術
2.使用ajax的好處有:
①經過異步模式,提高了用戶體驗;
②優化了瀏覽器和服務器之間的傳輸,減小沒必要要的數據往返,減小了帶寬佔用;
③Ajax引擎在客戶端運行,承擔了一部分原本由服務器承擔的工做,從而減小了大用戶量下的服務器負載
3.如何使用
①jQuery中發送ajax請求:$.ajax({type: "POST",url: "",data: "name=John",success: function(msg){}});
②Vue發送get請求:axios.get(url[,options]);發送post請求:axios.post(url,data,[options]);
ServletContext對象是上下文對象 Servlet直接調用getServletContext方法返回ServletContext對象
1.基於Servlet,在項目中加入Apache的commons-fileupload文件上傳組件的相關Jar包
文件上傳:修改表單請求爲enctype="multipart/form-data"方式,使用文件上傳解析器獲取上傳的文件數據;
文件下載:經過輸入流讀取文件,經過響應獲取輸出流response.getOutputStream(),經過輸出流將數據響應給瀏覽器;
須要經過設置不讓客戶端(瀏覽器)解析文件,而是以附件形式打開(下載):response.setHeader("Content-Disposition", "attachment;filename="+須要下載的文件名稱);
參考文檔:https://www.cnblogs.com/xdp-gacl/p/4200090.html
2.基於Spring MVC,在項目中加入Apache的commons-fileupload文件上傳組件的相關Jar包,配置文件上傳解析器
文件上傳:修改表單請求爲enctype="multipart/form-data"方式,使用MultipartFile類型接收數據並獲取輸入流,再寫入到對應地方完成文件上傳;
文件下載:經過輸入流讀取文件,經過響應獲取輸出流response.getOutputStream(),經過輸出流將數據響應給瀏覽器;
通知瀏覽器以attachment(下載方式)下載文件:headers.setContentDispositionFormData("attachment", downloadFielName);
設置響應類型爲application/octet-stream : 二進制流數據(最多見的文件下載)。headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
1. 常見用法:get通常用於從服務器上獲取數據,post通常用於向服務器傳送數據;
2. 表現形式:請求的時候參數的位置有區別,get的參數是拼接在url後面,用戶在瀏覽器地址欄能夠看到。post是放在http包的包體中;
3. 安全性:get請求的參數直接拼接在url後面,post發送的數據對客戶端是不可見的,get較post安全性低;
4. 數據大小:能提交的數據有區別,get方式能提交的數據只能是文本,且大小有限制,而post不只能夠提交文本還能夠二進制文件,理論上大小是沒有限制的,起限制做用的是服務器的處理程序的處理能力
1.從地址欄表現看:
forward是服務器內部的重定向,服務器直接訪問目標地址的 url網址,把裏面的東西讀取出來,可是客戶端並不知道,所以用forward的話,客戶端瀏覽器的網址是不會發生變化的;
redirect是客戶端的重定向,是徹底的跳轉。即服務器返回的一個url給客戶端瀏覽器,而後客戶端瀏覽器會從新發送一次請求,到新的url裏面,所以瀏覽器中顯示的url網址會發生變化;
2.從request數據共享角度看:
因爲在整個定向的過程當中用的是同一個request,所以forward會將request的信息帶到被重定向的jsp或者servlet中使用;
redirect是倆次請求,倆個request,數據不能共享
3.從應用層面上看(擴展)
forward通常用於相似用戶登錄的時候,根據角色轉發到相應的模塊等業務;
redirect通常用於用戶註銷登錄時返回主頁面和跳轉到其它的網站等
1. 是什麼:
json一種輕量級的數據交換格式,具備良好的可讀和便於快速編寫的特性。可在不一樣平臺之間進行數據交換。
xml是擴展標記語言 (Extensible Markup Language, XML) ,用於標記電子文件使其具備結構性的標記語言,能夠用來標記數據、定義數據類型,是一種容許用戶對本身的標記語言進行定義的源語言
2. 區別:
①可讀性:xml有不少標記性字符,json只是一個有用的數據塊而缺乏一些標記字符,xml的可讀性更高;
②數據傳輸:JSON相對於XML來說,數據的體積小,傳遞的速度更快些;
③數據描述:XML的語法格式統一,JSON對數據的描述性比XML較差
3. 適用場景:
json的體積小,較少包含除有用數據外的數據,比較適合用戶數據的傳輸:如JavaScript與後臺的數據交互,各個系統之間數據傳輸等;
xml的格式統一,並能夠爲xml文件提供約束文件,對xml數據進行預約義,適合用於標記文檔,在配置文件、webService(瞭解)等方面具備優點;
json對象:{"key":"value","key":"value",....}
JSON數組:[ obj , obj , obj , ....]
基於TCP的應用層協議,它不關心數據傳輸的細節,主要是用來規定客戶端和服務端的數據傳輸格式,最初是用來向客戶端傳輸HTML頁面的內容
HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer 或 Hypertext Transfer Protocol Secure,超文本傳輸安全協議),是以安全爲目標的HTTP通道,簡單講是HTTP的安全版。
Https工做原理:
客戶端在使用HTTPS方式與Web服務器通訊時有如下幾個步驟,如圖所示。
(1)客戶使用https的URL訪問Web服務器,要求與Web服務器創建SSL鏈接。
(2)Web服務器收到客戶端請求後,會將網站的證書信息(證書中包含公鑰)傳送一份給客戶端。
(3)客戶端的瀏覽器與Web服務器開始協商SSL鏈接的安全等級,也就是信息加密的等級。
(4)客戶端的瀏覽器根據雙方贊成的安全等級,創建會話密鑰,而後利用網站的公鑰將會話密鑰加密,並傳送給網站。
(5)Web服務器利用本身的私鑰解密出會話密鑰。
(6)Web服務器利用會話密鑰加密與客戶端之間的通訊。
常見的加密:RC五、RC四、SHA(信息摘要算法,同MD5同樣屬於不可逆算法)
HTTPS協議的主要做用能夠分爲兩種:一種是創建一個信息安全通道,來保證數據傳輸的安全;另外一種就是確認網站的真實性。https://www.cnblogs.com/wqhwe/p/5407468.html
HTTP:是互聯網上應用最爲普遍的一種網絡協議,是一個客戶端和服務器端請求和應答的標準(TCP),用於從WWW服務器傳輸超文本到本地瀏覽器的傳輸協議,它能夠使瀏覽器更加高效,使網絡傳輸減小。
HTTPS:是以安全爲目標的HTTP通道,簡單講是HTTP的安全版,即HTTP下加入SSL層,HTTPS的安全基礎是SSL,所以加密的詳細內容就須要SSL。
(1)對數據進行加密,並創建一個信息安全通道,來保證傳輸過程當中的數據安全;
(2)對網站服務器進行真實身份認證。
HTTPS協議的主要做用能夠分爲兩種:一種是創建一個信息安全通道,來保證數據傳輸的安全;另外一種就是確認網站的真實性。
區別:
一、https是加密傳輸協議,http是名文傳輸協議;
二、https須要到ca申請證書且須要必定費用,而http不用;
三、https標準端口443,http標準端口80(徹底不一樣的鏈接方式);
四、https協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全,而http的鏈接很簡單,是無狀態的;
五、https基於傳輸層,http基於應用層;
六、https比http更加安全,對搜索引擎更友好;
七、https在瀏覽器顯示綠色安全鎖,http沒有顯示;
連接:https://www.cnblogs.com/wudaoyongchang/p/6253451.html
短連接:客戶端和服務器每進行一次HTTP操做,就創建一次鏈接,任務結束就中斷鏈接。
長鏈接:用以保持鏈接特性。 長鏈接多用於操做頻繁,點對點的通信,並且鏈接數不能太多狀況。由於用短鏈接頻繁的通訊會形成socket錯誤 WEB網站的http服務通常都用短連接。由於長鏈接對於服務端來講會耗費必定的資源
每一條css樣式定義由兩部分組成,例: [code] 選擇器{樣式} [/code] 在{}以前的部分就是「選擇器」。
「選擇器」指明瞭{}中的「樣式」的做用對象,也就是「樣式」做用於網頁中的哪些元素。
主要的Css選擇器:
標籤選擇器
類選擇器
ID選擇器
全局選擇器
組合選擇器
字符串匹配的屬性選擇符
在平常開發中最經常使用的就是標籤選擇器、類選擇器和id選擇器。
標籤名選擇器:能夠爲整個XHTML文檔中的同一個標籤指定相同的CSS樣式。
類選擇器:能夠給相同的標籤賦予不一樣的CSS樣式。
id選擇器:id選擇器是惟一的,只能夠獲取獨一無二的一個元素。
三者都是刪除的意思,區別
一、drop (刪除表):刪除表結構 (刪除內容和定義,釋放空間。簡單來講就是把整個表去掉.之後要新增數據是不可能的,除非新增一個表)。
二、truncate (清空表中的數據):清空表中全部的數據,速度快,不可回滾;實質是刪除整張表包括數據再從新建立表,使自動增加列重置;
三、delete (刪除表中的數據):逐行刪除數據,每步刪除都是有日誌記錄的,能夠回滾數據;實質是逐行刪除表中的數據,但自動增加列沒有重置
四、執行速度上,通常來講: drop> truncate > delete。
五、保留表而想刪除全部的數據時用truncate。
6 想刪除部分數據時, delete 刪除時要帶上where語句,回滾段要足夠大
七、應用範圍上,truncate 只能對table;delete 能夠是table和view
(什麼是範式:範式是符合某一種級別的關係模式的集合。關係數據庫中的關係必須知足必定的要求,知足不一樣程度要求的爲不一樣範式。)
一、第一範式(1NF):數據表中的每一列(每一個字段)必須是不可拆分的最小單元,也就是確保每一列的原子性(原子性:指事務包含的全部操做要麼所有成功,要麼所有失敗回滾)
二、第二範式(2NF):知足1NF後,要求表中的全部列,都必須依賴於主鍵,而不能有任何一列與主鍵沒有關係,也就是說一個表只描述一件事情;
三、 第三範式(3NF):必須先知足第二範式(2NF),要求:表中的每一列只與主鍵直接相關而不是間接相關,(表中的每一列只能依賴於主鍵);
第一範式(1NF)、第二範式(2NF)、第三範式(3NF)、第四範式(4NF)、第五範式(5NF)和第六範式(6NF)
1. 主鍵是能肯定一條記錄的惟一標識,也是做爲一個能夠被外鍵有效引用的對象(好比,一條記錄包括身份正號,姓名,年齡)
2. 外鍵用於與另外一張表的關聯。是能肯定另外一張表記錄的字段,用於保持數據的一致性
1.建索引 (必要時創建多級索引,分析MySQL的執行計劃,經過表數據統計等方式協助數據庫走正確的查詢方式)
2.減小表之間的關聯
3.優化sql,儘可能讓sql很快定位數據,不要讓sql作全表查詢,應該走索引,把數據 量大的表排在前面
4.簡化查詢字段,沒用的字段不要,已經對返回結果的控制,儘可能返回少許數據
5.儘可能用PreparedStatement來查詢,不要用Statement
6. 從磁盤上作文章,數據存放的在磁盤的內、外磁道上,數據獲取的效率都是不同的;
七、數據庫表的大字段剝離(假如一個表的字段數有100多個,學會拆分字段,保證單條記錄的數據量很小)
都是將兩個結果集合併爲一個
1)union在進行表連接後會篩選掉重複的記錄;union all不會去掉重複記錄
2)union將會按照字段的順序進行排序;union all只是簡單的將兩個結果集合並後就返回
3)union all比union快不少
order by:
用來對數據庫的一組數據進行排序
desc:降序
asc:升序
group by:
「By」指定的規則對數據進行分組,所謂的分組就是將一個「數據集」劃分紅若干個「小區域」,而後針對若干個「小區域」進行數據處理。
1)根據(by)必定的規則對數據進行分組(Group)
2)就是將一個「數據集」劃分紅若干個「小區域」,而後針對若干個「小區域」進行數據處理。
1)在SELECT 列表中全部未包含在聚合函數中的列都應該包含在 GROUP BY 子句中,除非對這一列使用了聚合函數(avg/sum/count..)如:有部門表和員工表,員工表根據部門id進行分組查詢,那麼select 不能跟*,應該跟部門id或者聚合函數
2)不能Group By非標量基元類型的列,如不能Group By text,image或bit類型的列;
3)進行分組前能夠使用Where子句消除不知足條件的行;
4)使用Group By子句返回的組沒有特定的順序,能夠使用Order By子句指定次序。
1) distinct是將全部查詢的字段進行對比去重,全部字段都徹底相同纔會去重 distinct 必須放在查詢字段開頭進行查詢
2) group by 根據字段進行去重,字段相同就會去重 至於那個效率更高 這個我沒有研究過
1)使用decode函數
2)使用case when語句
PL/SQL是一種程序語言,叫作過程化SQL語言(Procedural Language/SQL)。PL/SQL是Oracle數據庫對SQL語句的擴展。在普通SQL語句的使用上增長了編程語言的特色,因此PL/SQL把數據操做和查詢語句組織在PL/SQL代碼的過程性單元中,經過邏輯判斷、循環等操做實現複雜的功能或者計算。PL/SQL 只有 Oracle 數據庫有。 MySQL 目前不支持 PL/SQL 的。
1)使用distinct關鍵字
2)藉助group by也能夠進去去重:GROUP BY [去除重複的字段名列表,....]
①資源重用
因爲數據庫鏈接獲得重用,避免了頻繁建立、釋放鏈接引發的大量性能開銷。在減小系統消耗的基礎上,增進了系統環境的平穩性(減小內存碎片以級數據庫臨時進程、線程的數量)
②更快的系統響應速度
數據庫鏈接池在初始化過程當中,每每已經建立了若干數據庫鏈接置於池內備用。此時鏈接池的初始化操做均已完成。對於業務請求處理而言,直接利用現有可用鏈接,避免了數據庫鏈接初始化和釋放過程的時間開銷,從而縮減了系統總體響應時間。
③新的資源分配手段
對於多應用共享同一數據庫的系統而言,可在應用層經過數據庫鏈接的配置,實現數據庫鏈接技術。
④統一的鏈接管理,避免數據庫鏈接泄露
在較爲完備的數據庫鏈接池實現中,可根據預先的鏈接佔用超時設定,強制收回被佔用的鏈接,從而避免了常規數據庫鏈接操做中可能出現的資源泄露
關係型數據庫mysql
一、關係型數據庫,是指採用了關係模型來組織數據的數據庫,
2.關係型數據庫的最大特色就是事務的一致性;
非關係型數據庫 特性
一、使用鍵值對存儲數據;
二、分佈式;
優勢
無需通過sql層的解析,讀寫性能很高
基於鍵值對,數據沒有耦合性,容易擴展
存儲數據的格式:nosql的存儲格式是key,value形式
缺點
不支持事務
不提供sql支持
1)內鏈接:顯示錶之間鏈接匹配的全部行
2)左鏈接(左外鏈接):以左表做爲基準進行查詢,左表數據會所有顯示出來,條件成立,右表數據顯示;條件不成立,顯示null
select * from 左表
left outer join 右表 on 條件
3)右鏈接(右外鏈接):以右表做爲基準進行查詢,右表數據會所有顯示出來,條件成立,左表數據顯示;條件不成立,顯示null
在斷定左表和右表時,要根據表名出如今Outer Join的左右位置關係。
1.交叉鏈接:沒有where條件的交叉鏈接將產生鏈接表所涉及的笛卡爾積
2.左右外鏈接:左鏈接以左表爲基表 右表爲從表 基表所有展現 從表數據對應匹配條件進行展現
3.內鏈接:是比較運算符比較要鏈接的列的值的鏈接 不匹配的行不會被顯示
4.全外鏈接:左表記錄所有展現,右表沒有則顯示爲null;右表記錄所有展現,左表沒有則顯示爲null
若是兩張表存在主外鍵關係,那麼在刪除主鍵表的記錄時,若是從表有相關聯的記錄,那麼將致使刪除失敗。
在定義外鍵約束時,能夠同時指定3種刪除策略:一是將從表記錄一併刪除(級聯刪除);二是將從表記錄外鍵字段設置爲NULL;三是將從表記錄外鍵字段設置爲默認值。
級聯刪除示例:
alter table 從表名
add constraint 外鍵名
foreign key(字段名) references 主表名(字段名)
on delete cascade
NOT NULL: 用於控制字段的內容必定不能爲空(NULL)。
UNIQUE: 控件字段內容不能重複,一個表容許有多個 Unique 約束。
PRIMARY KEY: 也是用於控件字段內容不能重複,但它在一個表只容許出現一個。
FOREIGN KEY: 用於預防破壞表之間鏈接的動做,也能防止非法數據插入外鍵列,由於它必須是它指向的那個表中的值之一。
CHECK: 用於控制字段的值範圍。
1. 主鍵約束(PRIMARY KEY):在主鍵上使用
2. 外鍵約束(FOREIGN KEY):創建倆個表之間的關係時使用
3. 惟一約束(UNIQUE):保證數據表中某個字段數據的惟一性時使用
4. 非空約束(NOT NULL):須要保證數據庫字段值不爲空時使用
5. 自動增加列:數據值自增,須要和用在主鍵列上
1)、表的主鍵、外鍵必須有索引;
2)、數據量超過300的表應該有索引;
3)、常常與其餘表進行鏈接的表,在鏈接字段上應該創建索引;
4)、常常出如今Where子句中的字段,特別是大表的字段,應該創建索引;
5)、索引應該建在選擇性高的字段上;
6)、索引應該建在小字段上,對於大的文本字段甚至超長字段,不要建索引;
7)、複合索引的創建須要進行仔細分析;儘可能考慮用單字段索引代替:
A、正確選擇複合索引中的主列字段,通常是選擇性較好的字段;
B、複合索引的幾個字段是否常常同時以AND方式出如今Where子句中?單字段查詢是否極少甚至沒有?若是是,則能夠創建複合索引;不然考慮單字段索引;
C、若是複合索引中包含的字段常常單獨出如今Where子句中,則分解爲多個單字段索引;
E、若是既有單字段索引,又有這幾個字段上的複合索引,通常能夠刪除複合索引;
8)、頻繁進行數據操做的表,不要創建太多的索引;
9)、刪除無用的索引,避免對執行計劃形成負面影響;
https://www.cnblogs.com/tangchuanyang/p/6013151.html
1) concat(string1,string2,...)
string1,string2表明字符串,concat函數在鏈接字符串的時候,只要其中一個是null,那麼就返回null
2)concat_ws(separator,str1,str2,...)
str1,str2表明字符串,concat_ws表明concat with separator,第一個參數是其它參數的分隔符。分隔符的位置放在要鏈接的兩個字符串之間。分隔符能夠是一個字符串,也能夠是其它參數。若是分隔符爲 NULL,則結果爲 NULL。函數會忽略任何分隔符參數後的 NULL 值。
1)having關鍵字一般是與group by關鍵字聯合使用
2)用於過濾group by語句返回的結果集
3)having關鍵字彌補了where關鍵字不能與聚合函數聯合使用的不足
1)就是一種虛擬的表 ,是一個邏輯表 ,自己不包含數據,做爲一個select語句存在數據字典中的
2)經過視圖 ,能夠展現基表的部分數據; 視圖數據來自定義視圖的查詢中使用的表
3)基表: 用來建立視圖的表叫作基表 base table
1)視圖是一種數據庫對象
2)是基於 SQL 語句的結果集的可視化的表
3)方便操做數據庫的
聯繫:
視圖(view)是在基本表之上創建的表,它的結構(即所定義的列)和內容(即全部數據行)都來自基本表,它依據基本表存在而存在。一個視圖能夠對應一個基本表,也能夠對應多個基本表。視圖是基本表的抽象和在邏輯意義上創建的新關係。
區別:
一、視圖是已經編譯好的sql語句;而表不是。
二、視圖沒有實際的物理記錄;而表有。
三、視圖是窗口;表是內容
四、標緻用物理空間而視圖不佔用物理空間,視圖只是邏輯概念的存在;表能夠即便對它修改,但視圖只能有建立的語句來修改。
五、表是內模式,視圖是外模式。
六、視圖是查看數據表的一種方法,能夠查詢數據表中某些字段構成的數據,只是一些sql語句的集合。從安全的角度來講,視圖能夠不給用戶接觸數據表,從而不知道表結構。
七、表屬於全局模式中的表,是實表;視圖屬於局部模式的表,是虛表。
八、視圖的創建和刪除隻影響視圖自己,不影響對應的基本表。
---------------------------------------------------------------------
1. 視圖 : 就是一種虛擬的表 ,是一個邏輯表 ,自己不包含數據,做爲一個select語句存在數據字典中的
2. 經過視圖 ,能夠展現基表的部分數據; 視圖數據來自定義視圖的查詢中使用的表
3. 基表: 用來建立視圖的表叫作基表 base table
1. 表中保存的是數據 而視圖中保存的是一個或者多個條件組合而成的結果集
2. 表是物理存在的 視圖是虛擬的內存表
事務是一組業務邏輯,要麼所有成功,要麼所有失敗,一種技術(機制)。
例如,銀行轉帳工做:從一個帳號扣款並使另外一個帳號增款,這兩個操做要麼都執行,要麼都不執行
1)開啓事務:程序開始時,必須先開啓事務
2)提交事務:程序正常執行完成後,必須提交事務
3)回滾事務:程序發生異常後,必須回滾事務
1)原子性:整個事務是一個總體,不可分割。
2)一致性:事務操做的先後數據保持一致(數據完整性)。
3)隔離性:兩個事務同時操做併發訪問問題
4)持久性:事務一旦提交,將不能再回滾。
1)髒讀:一個事務讀到了另外一個事務沒有提交的數據。
2)不可重複讀:一個事務讀到了另外一個事務已經提交的數據。(要求的是一個事務中屢次讀取時數據是一致的,這是事務update時引起的問題)
3)虛讀(幻讀):一個事務讀到了另外一個事務已經提交的數據。(要求在一個事務屢次讀取的數據的數量是一致的,這是insert或delete時引起的問題)
1)讀未提交:read uncommitted,一個事務讀到了另外一個事務沒有提交的數據。存在3個問題。
2)讀已提交:read committed,一個事務讀到另外一個事務已經提交的數據。解決:髒讀;存在2個問題。
3)可重複讀:repeatable read,在一個事務中,讀到的數據一致。解決:髒讀、不可重複讀;存在1個問題。
4)串行化:serializable,一個事務在操做時,另外一個事務必須等待。(單事務)。解決全部問題。
事務隔離級別 髒讀 不可重複讀 幻讀
讀未提交(read-uncommitted) 是 是 是
讀已提交(read-committed) 否 是 是
可重複讀(repeatable-read) 否 否 是
串行化(serializable) 否 否 否
MYSQL 事務處理主要有兩種方法:
一、用 BEGIN, ROLLBACK, COMMIT來實現
BEGIN 開始一個事務
ROLLBACK 事務回滾
COMMIT 事務確認
二、直接用 SET 來改變 MySQL 的自動提交模式:
SET AUTOCOMMIT=0 禁止自動提交
SET AUTOCOMMIT=1 開啓自動提交
在事務的處理過程當中,若是發生錯誤而且使用rollback進行回滾,那麼整個事務對數據庫的操做都將被撤銷,在一個龐大的事務中,這是很浪費資源的,好比事務前半部分是正確的,事務的後半部分是錯誤的,那麼我想回滾到前半部分結束位置,這時就能夠使用保存點。
事務的回滾點有什麼做用?相似於單機遊戲的存檔和讀檔:
一、若是沒有遊戲的存檔功能,每次玩單機遊戲都會從第一關從新開始。
二、若是使用了遊戲的存檔功能,下次在玩遊戲時,就會從存檔處開始。關係型數據庫中不存在直接多對多關係,採用將一個多對多拆分紅2個一對多。
(多對多其實就是:一對多 和 多對一 的一個組合。)
1) 兩個表若是是多對多關係,已經存在2個主表。
2) 提供一箇中間表
關係型數據庫中不存在直接多對多關係,採用將一個多對多拆分紅2個一對多。
(多對多其實就是:一對多 和 多對一 的一個組合。)
1) 兩個表若是是多對多關係,已經存在2個主表。
2) 提供一箇中間表
1)Sum()函數裏面的參數是列名的時候,是計算列名的值的相加,而不是有值項的總數
2)count()函數裏面的參數是列名的的時候,那麼會計算有值項的次數.(NULL 不計入, 可是''值計入)
記錄的列值爲NULL時,COUNT(列名)和SUM(列名)都不計 這條記錄。
count(*)和count(1)無任何差異,永遠優於其餘count,不管加不加任何索引
1)加索引顯著快於不加索引
2)主鍵索引快於普通索引
3)沒有索引時,與列含不含空值無關
同樣
1)avg():返回指定組中的平均值,空值被忽略;
2)count():返回指定組中的項目個數
3)max():返回指定數據中的最大值;
4)min():返回指定數據中的最小值;
5)sum():返回指定數據的和,只能用於數字列,空值忽略;
什麼是存儲過程:存儲過程能夠說是一個記錄集吧,它是由一些T-SQL語句組成的代碼塊,這些T-SQL語句代碼像一個方法同樣實現一些功能(對單表或多表的增刪改查),而後再給這個代碼塊取一個名字,在用到這個功能的時候調用他就好了
小結:總之存儲過程是好東西,在作項目時屬於必備利器,下面介紹存儲過程的基本語法。
①重複使用。存儲過程能夠重複使用,從而能夠減小數據庫開發人員的工做量。
②提升性能。存儲過程在建立的時候在進行了編譯,未來使用的時候再也不從新翻譯。通常的SQL語句每執行一次就須要編譯一次,因此使用存儲過程提升了效率。
③減小網絡流量。存儲過程位於服務器上,調用的時候只須要傳遞存儲過程的名稱以及參數就能夠了,所以下降了網絡傳輸的數據量。
④安全性。參數化的存儲過程能夠防止SQL注入式攻擊,並且能夠將Grant、Deny以及Revoke權限應用於存儲過程。
缺點
1:調試麻煩,可是用PL/SQL Developer 調試很方便!彌補這個缺點。
2:移植問題,數據庫端代碼固然是與數據庫相關的。可是若是是作工程型項目,基本不存在移植問題。
3:從新編譯問題,由於後端代碼是運行前編譯的,若是帶有引用關係的對象發生改變時,受影響的存儲過程、包將須要從新編譯(不過也能夠設置成運行時刻自動編譯)。
4:若是在一個程序系統中大量的使用存儲過程,到程序交付使用的時候隨着用戶需求的增長會致使數據結構的變化,接着就是系統的相關問題了,最後若是用戶想維護該系統能夠說是很難很難、並且代價是空前的,維護起來更麻煩
總結:
1. 適當的使用存儲過程,可以提升咱們SQL查詢的性能,
2. 存儲過程不該該大規模使用,濫用。
3. 隨着衆多ORM 的出現,存儲過程不少優點已經不明顯。
4. SQL最大的缺點仍是SQL語言自己的侷限性——SQL自己是一種結構化查詢語言,咱們不該該用存儲過程處理複雜的業務邏輯——讓SQL迴歸它「結構化查詢語言」的功用。複雜的業務邏輯,仍是交給代碼去處理吧。
1)超鍵:在關係模式中,能惟一標識元組的屬性集稱爲關係模式的超鍵。
2)候選鍵:若是一個屬性集能惟一標識元組,且有不包含多餘屬性,那麼這個屬性集稱爲候選鍵;也即:不含有多餘屬性的超鍵稱爲候選鍵。
3)主鍵:關係模式中用戶正在使用的候選鍵稱主鍵(primary key)
4)外鍵:在關係模式R中,若是某屬性集是其餘模式的候選鍵,那麼該屬性集對模式R來講就是外鍵。
主要:可能存在徹底相同的數據,沒法區分
若是設置優點:有助於提升數據的檢索速度
1)主鍵是能肯定一條記錄的惟一標識,也是做爲一個能夠被外鍵有效引用的對象,不能有重複的,不容許爲空
2)外鍵用於與另外一張表的關聯.是肯定另外一張表記錄的字段,用於保持數據的一致性,能夠有重複的, 能夠是空值
1)能夠直觀的操做數據 查看數據,
2)能夠藉助圖形化界面輕鬆完成對數據庫的各類操做
1)使用索引
2)使用鏈接(JOIN)來代替子查詢(Sub-Queries)
3)選取最適用的字段屬性
4)優化的查詢語句
5)使用聯合(UNION)來代替手動建立的臨時表
1)建索引
2)減小表之間的關聯
3)優化SQL語句,儘可能讓SQL很快定位數據,不讓SQL作全表查詢,應走索引,把數據量大的表排在前面
4)簡化查詢字段,只返回必要的字段
5)儘可能用PreparedStatement查詢,不要用Statement
6)從磁盤上作文章,數據存放在磁盤的內,外磁道上,數據獲取的效率是不一樣的
7)數據庫表的大字段剝離(拆分字段)
1).Sql Server 數據庫
select * into 新表名 from 原表名 Where [條件1,條件2];
2).Oracle 數據庫
--建立表結構
create table 新表名 as select * from 原表名 where 1=2;
--備份指定數據
insert into 新表名 select * from 原表名 Where [條件1,條件2]
使用DATE_FORMAT(date,format) 函數
1)date須要格式化字段名
2)format格式
select DATE_FORMAT( updated_at, '%Y-%m-%d' ) from tb_sku;
delimiter 自定義符號
create function 函數名(形參列表) returns 返回類型
begin 函數體
set @x = 1;
return
end
自定義符號
delimiter;
delimiter $$
create function myfun3(ia int, ib int) returns int
begin
return ia + ib;
end
$$
delimiter;
char是一種固定長度的字符串類型,varchar是一種可變長度的字符串類型;
適用場景:
char通常用來存儲長度固定字段,如:手機號,身份證號等
varchar通常用來存儲不固定長度的字段:如:用戶名,暱稱等
概念:
數據庫鏈接池是程序啓動時創建足夠的數據庫鏈接,並將這些鏈接組成一個鏈接池,由程序動態地對池中的鏈接進行申請,使用,釋放。
做用:
1.資源重用,避免了數據庫鏈接頻繁創建、關閉的開銷
2.更快的系統響應速度,直接從鏈接池中獲取鏈接,響應速度加快
3.控制資源的使用。若是不使用鏈接池,每次訪問數據庫都須要建立一個鏈接,這樣系統的穩定性受系統鏈接需求影響很大,很容易產生資源浪費和高負載異常。鏈接池可以使性能最大化,將資源利用控制在必定的水平之下。鏈接池能控制池中的鏈接數量,加強了系統在大量用戶應用時的穩定性。
經常使用的數據庫鏈接池:DBCP、C3P0、Druid
池化技術(擴展):
簡單點來講,就是提早保存大量的資源,以備不時之需。
對於線程,內存,數據庫的鏈接對象等等,這些都是資源,程序中當建立一個線程或者在堆上申請一塊內存時,都涉及到不少系統調用,也是很是消耗CPU的,若是程序須要不少相似的工做線程或者須要頻繁的申請釋放小塊內存,若是沒有在這方面進行優化,那頗有可能這部分代碼將會成爲影響整個程序性能的瓶頸。
池化技術主要有線程池,內存池,數據庫鏈接池,對象池等等,
對象池就是提早建立不少對象,將用過的對象保存起來,等下一次須要這種對象的時候,再拿出來使用,使用完成以後再交還保存,使得能夠被重複使用
索引是一種獨立於表的數據庫對象,能夠存儲在於表不一樣的磁盤中間或表空間;索引至關於字典的目錄,做用在於提高查詢效率,下降磁盤讀寫,提高數據庫性能。
1. 直接建立索引和間接建立索引:
自動建立--------即在建立主鍵 primarykey 或惟一性約束 unique 的時候,數據庫會自動在相應的列上建立惟一性索引
手動建立--------即在不惟一的列上建立非惟一的索引,加速查詢效率
2. 普通索引和惟一性索引
3. 單一索引和複合索引
參考:https://blog.csdn.net/csdn265/article/details/51889508
單一索引:即在單列上創建索引
複合索引:又叫組合索引,在索引創建語句中同時包含多列
4. 聚簇索引和非聚簇索引
參考:https://blog.csdn.net/zc474235918/article/details/50580639
索引的優勢:
1. 經過建立惟一性索引,能夠保證數據庫表中每一行數據的惟一性;
2. 能夠大大加快數據的檢索速度,這也是建立索引的最主要的緣由;
索引的缺點:
1. 建立索引和維護索引要耗費時間,這種時間隨着數據量的增長而增長;
2. 索引須要佔物理空間,除了數據表佔數據空間以外,每個索引還要佔必定的物理空間,若是要創建聚簇索引,那麼須要的空間就會更大;
3. 當對錶中的數據進行增長、刪除和修改的時候,索引也要動態的維護,這樣就下降了數據的維護速度
MySQL 的插件式存儲引擎主要包括MyISAM,Innodb,NDB Cluster,Maria,Falcon,Memory,Archive,Merge,Federated 等,其中最著名並且使用最爲普遍的MyISAM 和Innodb兩種存儲引擎。
MyISAM擁有較高的插入、查詢速度,但不支持事物;
InnoDB是事務型數據庫的首選引擎,支持事務安全表(ACID),支持行鎖定和外鍵,上圖也看到了,InnoDB是默認的MySQL引擎。
兩種類型最主要的差異就是Innodb 支持事務處理與外鍵和行級鎖。
https://blog.csdn.net/zhangyuan19880606/article/details/51217952
https://blog.csdn.net/xifeijian/article/details/20316775
MySQL默認使用InnoDB存儲引擎。
InnoDB是事務型數據庫的首選引擎,支持事務安全表(ACID),
其它存儲引擎都是非事務安全表,支持行鎖定和外鍵,
InnoDB主要特性
爲MySQL提供了具備提交、回滾和崩潰恢復能力的事務安全(ACID兼容)存儲引擎。
InnoDB鎖定在行級而且也在 SELECT語句中提供一個相似Oracle的非鎖定讀。這些功能增長了多用戶部署和性能。
在SQL查詢中,能夠自由地將InnoDB類型的表和其餘MySQL的表類型混合起來,甚至在同一個查詢中也能夠混合。
Redis 能夠存儲鍵與5種不一樣數據結構類型之間的映射,這5種數據結構類型分別爲String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zset(有序集合)。
mybatis是一個持久層ORM框架。它內部封裝了jdbc,使得開發更簡潔,更高效。
Mybatis使開發者只須要關注sql語句自己,簡化JDBC操做,不須要在關注加載驅動、建立鏈接、處理SQL語句等繁雜的過程。
MyBatis能夠經過xml或註解完成ORM映射關係配置。
JDBC是Java提供的一個操做數據庫的API; MyBatis是一個持久層ORM框架,底層是對JDBC的封裝。
MyBatis對JDBC操做數據庫作了一系列的優化:
(1) mybatis使用已有的鏈接池管理,避免浪費資源,提升程序可靠性。
(2) mybatis提供插件自動生成DAO層代碼,提升編碼效率和準確性。
(3)mybatis 提供了一級和二級緩存,提升了程序性能。
(4) mybatis使用動態SQL語句,提升了SQL維護。(此優點是基於XML配置)
(5) mybatis對數據庫操做結果進行自動映射
ORM的全稱是Object Relational Mapping,即對象關係映射。
描述的是對象和表之間的映射。操做Java對象,經過映射關係,就能夠自動操做數據庫。
在ORM關係中,數據庫表對應Java中的類,一條記錄對應一個對象,一個屬性對應一個列。
常見的ORM框架:Mybatis、Hibernate
註解、XML
1.#{}實現的是sql語句的預處理參數,以後再sql中用?號代替,使用時不須要關注數據類型,Mybatis自動實現數據類型的轉換,而且能夠防止SQL注入;
2.${}實現的是sql語句的直接拼接,不作數據類型轉換,須要自行判斷數據類型,不能防止SQL注入;
3.在某些特定狀況下必須使用${},如:在分表存儲的狀況下,對哪張表的查詢是不肯定的,也就是sql語句不能寫死,代表是動態的,查詢條件是固定的,此時代表只能使用${}方式進行字符串拼接,這樣:slect * from ${tableName} where id = #{id}
總結:#{}佔位符,用於參數傳遞; ${}用於SQL拼接
1. 經過在查詢的sql語句中定義字段名的別名,讓字段名的別名和實體類的屬性名一致
2.使用通用Mapper時,能夠經過@Column註解設置
3.若是進行自定義查詢,能夠經過@Result進行設置
【瞭解】4.若是使用的xml配置,經過<resultMap>進行配置
1.使用通用Mapper的Criteria進行like語句的拼湊
2.使用#{}佔位符方式,參數先後拼湊%。(select * from t_user where username like #{username} ,username數據爲"%jack%")
【瞭解】3.使用${}字符串拼接方式,可能引起sql注入問題:select * from t_user where username like '%${username}%'
Dao接口的工做原理是JDK動態代理,Mybatis運行時會使用JDK動態代理爲Dao接口生成代理proxy對象,代理對象proxy會攔截接口方法,轉而執行接口方法所對應的MappedStatement所表明的sql,而後將sql執行結果返回。
MappedStatement解釋:MappedStatement維護了一條<select|update|delete|insert>節點的封裝,包括了傳入參數映射配置、執行的SQL語句、結果映射配置等信息。如如下一個<select/>節點
<select id="selectAuthorLinkedHashMap" resultType="java.util.LinkedHashMap">
select id, username from author where id = #{value}
</select>
Dao接口在使用時,MyBatis建立接口對應的代理類。
在調用對應的方法時,執行的是代理類對應的方法。
代理類的方法進行方法上添加的註解完成增刪改查對應的操做,若是是查詢將結果封裝到方法返回值類型聲明的對象中。
不能重載的,
由於是全限定名+方法名的必須惟一。
使用第三方分頁助手:PageHelper
使用方式:
在將要執行查詢sql語句以前使用分頁助手:PageHelper.startPage(pageNum:頁碼, pageSize:每頁顯示數量);
使用MyBatis插件(也稱爲攔截器)機制,對須要使用分頁的功能進行加強。也就是重寫SQL,根據不一樣的數據庫生產不一樣的分頁語句。
Mysql生成limit語句,Oracle藉助rownum生產對應子查詢語句。
提供POJO和表之間的映射關係,查詢結果就能夠完成封裝。
1.使用通用Mapper,須要在POJO上字段上使用@Column註解
2.若是是自定義查詢,須要經過Dao接口裏使用@Result註解
3.若是是xml,須要使用<resultMap>配置映射關係
動態SQL標籤主要是基於XML進行配置的,在校主要學習的是註解,沒有使用過XML。
不過註解也支持部分動態標籤,@Select("<script> select * from user where 1=1 <if test='username != null '> and username = #{username} </if> </script>")
不一樣的Xml映射文件,若是配置了namespace,那麼id能夠重複;若是沒有配置namespace,那麼id不能重複。
MyBatis經過namespace+id來進行不一樣XML標識。
Hibernate是全自動的ORM框架,也就是使用hibernate不用編寫任何SQL語句。關聯對象直接調用對應方法,能夠自動完成數據的查詢。
MyBatis封裝了JDBC基本操做,但仍須要編寫SQL語句,也稱爲半自動ORM框架。使用經過Mapper能夠簡化MyBatis單表操做,多表仍須要本身編寫SQL語句。
namespace用於標識不一樣的XML配置文件。這樣不一樣xml文件中sql語句的id相同也不會有衝突。
註解開發沒有相似要求,只要保證接口全限定名不一樣便可(包+類名)
在xml配置文件,根據數據的不一樣,動態拼湊對應的SQL語句。
例如:
<if>用於處理條件成立時顯示部分SQL語句
<where> 若是有條件就顯示 where 子句,若是沒有條件則不顯示。
Mybatis的緩存機制分爲一級緩存和二級緩存
1.一級緩存:一級緩存的做用域是sqlSession會話級,至關於JDBC的Connection鏈接。一級緩存默認開啓,用戶不能手動配置。當在同一個sqlSession中執行兩次相同的sql語句時,第一次執行完畢會將數據庫中查詢的數據寫到緩存(內存),第二次查詢時會從緩存中獲取數據,再也不去底層數據庫查詢,從而提升查詢效率;
2.二級緩存:二級緩存的做用域爲同一個mapper的namespace,是跨sqlSession的,同一個namespace中不一樣的查詢SQL能夠從二級緩存中命中。二級緩存默認關閉,可是能夠經過配置進行開啓。
二級緩存的對象必須序列化,例如:User對象必須實現Serializable接口。
Mybatis中,執行select時,查詢數據會被緩存;當執行insert、update、delete等操做的時候,緩存則會被清除
Spring是一個分層的JavaSE/EEfull-stack(一站式)輕量級開源框架。
Spring爲不一樣的層都提供的企業級解決方案:
web層:spring mvc
service層:spring
dao層:JDBCTemplate
Spring的核心思想是IOC(控制反轉)和AOP(面向切面編程)
1.方便解耦,簡化開發 (高內聚低耦合)
Spring就是一個大工廠(容器),用於建立對象(bean)和維護對象間的依賴關係。
2.AOP編程的支持
Spring提供面向切面編程,方便實現對程序進行權限攔截、運行監控等功能.
聲明式事務的支持 ,只須要經過配置就能夠完成對事務的管理,而無需手動編程
3.方便程序的測試
Spring對Junit4支持,能夠經過註解的測試Spring程序
4.方便集成各類優秀框架
Spring支持各類優秀框架(如:Struts、Hibernate、MyBatis、Quartz等)
5.下降JavaEE API的使用難度
Spring 對JavaEE開發中很是難用的一些API(JDBC、JavaMail等),都提供了封裝,下降這些API應用難度
1.Spring Core:Spring框架的核心容器,提供了Spring框架的基本功能。這個模塊中最主要的一個組件爲BeanFactory,它使用工廠模式來建立所需的對象。同時BeanFactory使用IOC思想,經過讀取XML文件的方式來實例化對象,即BeanFactory提供了組件生命週期的管理,組件的建立,裝配以及銷燬等功能;
2.Spring AOP:採用了面向切面編程的思想,使Spring框架管理的對象支持AOP,並也提供事務管理,能夠不依賴具體的EJB組件,就能夠將事務管理集成到應用程序中;
3.Spring Web:提供Servlet監聽器的Context和Web應用的上下文。並集成一些現有的Web框架,例如Struts;
4.Spring Context:擴展核心容器,提供Spring上下文環境,給開發人員提供不少有用的服務,例如國際化,Email和JNDI訪問等;
5.Spring Web MVC:提供一個構建Web應用程序的MVC的實現
6.Spring ORM:提供對現有的ORM框架的支持,例如Hibernate等;
7.Spring DAO:提供對DAO(Data Access Object,數據訪問對象)模式和JDBC的支持。DAO能夠實現將業務邏輯與數據庫訪問的代碼分離,從而下降代碼的耦合度。經過對JDBC的抽象,簡化開發工做,並簡化對異常的處理(能夠很好的處理不一樣數據庫廠商拋出的異常);
1.基於XML配置
在XML文件中經過<bean>元素定義Bean,如:<bean class="com.czxy.UserService">
2.基於註解配置
在Bean實現類處經過標註@Component或衍型類(@Repository、@Service及@Controller)定義Bean
3.基於Java類配置
在標註了@Configuration的Java類中,經過在類方法上標註@Bean定義一個Bean。方法必須提供Bean的實例化邏輯
Spring Bean生命週期共分10個步驟,簡述以下:
1.實例化:實例化一個Bean
2.注入:按照Spring上下文對實例化的Bean進行依賴注入
7.初始化:自動調用init-method初始化方法
//此處就是項目中使用的bean
10.銷燬:當bean再也不須要時,執行銷燬方法destroy-method
專業解釋,參考文檔以下:
https://blog.csdn.net/fuzhongmin05/article/details/73389779
https://www.jianshu.com/p/3944792a5fff
1.singleton:單例,默認值,在Spring IOC容器只有一個Bean實例;
2.prototype:多例,每次從容器中得到Bean時,都返回一個新的實例;
3.request:一次請求,請求開始建立bean,請求結束銷燬bean。只有在Web應用中使用Spring時,該做用域纔有效
4.session:一次會話,同一個會話共享一個Bean實例,在session過時後,bean會隨之失效。且只有在Web應用中使用Spring時,該做用域纔有效
5.global-session:全局會話,在不一樣的portlet間共享session。(Portal是一個基於Web的應用)
線程安全產生的緣由是,多個線程對共享數據同時進行修改。
該問題分如下倆種狀況:
1.有問題:若是類中存在成員變量(即共享數據),且成員變量中的數據在方法中會被修改,此時可能會產生線程安全問題;
2.沒有問題:若是Bean沒有成員變量,或者成員變量數據在訪問的時候不會被修改,則不會產生線程安全問題。
1.Spring組件掃描:
在spring的配置類中使用@ComponentScan(basePackages = "com.czxy")能夠掃描com.czxy包以及子包下添加的指定註解的類。
常見的註解有:@Component、@Service、@Controller、@Repository
2.SpringBoot掃描機制
1)默認掃描規則,SpringBoot中會自動掃描啓動類所在包及其子包中的全部添加的指定註解類
2)使用@ComponentScan註解能夠覆蓋默認掃描規則。
自動裝配,自動完成各個bean之間的依賴關係裝配。
Spring提供了5個自動裝配模式:
1.no:默認值,沒有使用自動裝配
2.byName 按照屬性名自動裝配。
3.byType 按照屬性的數據類型自動裝配。若是存在多個這樣的bean,將拋出異常。
4.constructor 按照構造函數參數類型自動裝配。
5.autodetect 自動。先constructor自動裝配,若是不執行,再按照 byType 自動裝配
1. 顯示的依賴注入 @Resource 會重寫自動裝配
2. 不能自動裝配基本數據類型、字符串、數組等
3. 自動裝配不如顯示依賴注入精確
1.
@Autowired : 默認是以byType按類型自動注入。
@Autowired + @Qualifier("名稱"):將按照名稱自動注入
2.
@Resource() :
1)若是沒有指定name屬性:
① 當註解寫在字段上時,默認取字段名進行按照名稱注入,
② 若是註解寫在setter方法上默認取屬性名進行注入。
2)當找不到與名稱匹配的bean時才按照類型進行裝配。
3)若是指定了name屬性,就只會按照名稱進行裝配。 @Resource(name="") 將按照名稱自動注入
1.在指定類中添加指定註解,配置類添加@ComponentScan註解進行包掃描,就能夠完成bean的配置。
2.相關注解
@Component 通用組件類
@Controller 用於配置web層的controller類
@Service 用於配置service層的service類
@Repository 用於配置dao層dao類
@Bean 用於配置第三方實例,只能修飾方法。
1.經過ApplicationContext手動獲取:手動加載xml或配置類得到上下文對象,經過getBean()得到指定名稱的bean。
2.實現BeanFactoryAware接口:先得到BeanFactory,再getBean()得到指定名稱的bean。
3.實現ApplicationContextAware 接口 :先得到ApplicationContext,再getBean()得到指定名稱的bean。
https://www.aliyun.com/jiaocheng/812869.html
事務就是對一組邏輯進行操做,要麼所有成功,要麼所有失敗
Spring經過平臺事務管理器(PlatformTransactionManager)進行事務管理
事務管理器經過事務定義(TransactionDefinition)進行具體的事務操做。
事務定義經過4個方面對事務進行詳細描述:
1.readOnly:是否只讀
2.timeout:超時時間
3.isolationLevel:事務隔離級別,隔離級別4種:讀未提交、讀已提交、可重複讀、串行化
4.propagationBehavior:傳播行爲,共7種,常見的有:必須有事務 PROPAGATION_REQUIRED、每次必須新的 PROPAGATION_REQUIRES_NEW
Spring事務管理高層抽象主要包括3個接口,Spring的事務主要是由他們共同完成的:
PlatformTransactionManager:事務管理器—主要用於平臺相關事務的管理
TransactionDefinition: 事務定義信息(隔離、傳播、超時、只讀)—經過配置肯定如何進行事務管理。
TransactionStatus:事務具體運行狀態—事務管理過程當中,每一個時間點事務的狀態信息。
有異常就會回滾
能夠經過@Transactional(rollbackFor=Exception.class,notRollbackFor=RunTimeException.class)修改默認行爲
rollbackFor用於設置那些異常將發生回滾
notRollbackFor用於設置那些異常不會發生回滾
DEFAULT(默認):使用後端數據庫默認的隔離級別(spring中的的選擇項)
READ_UNCOMMITTED(讀未提交):容許讀取還未提交的改變了的數據。問題: 髒、幻、不可重複讀
READ_COMMITTED(讀已提交):容許在併發事務已經提交後讀取。解決: 髒讀,問題: 幻讀 , 不可重複讀
REPEATABLE_READ(可重複讀):對相同字段的屢次讀取是一致的,除非數據被事務自己改變。解決: 髒、不可重複讀,問題: 幻讀。
SERIALIZABLE(串行化):徹底服從ACID的隔離級別,解決: 髒、幻、不可重複讀。是隔離級別中最慢的,是典型的經過徹底鎖定在事務中涉及的數據表來完成的。
事務傳播行:多個事務方法相互調用時,事務如何在這些方法間傳播
做用:事務的傳播行爲就是一個個的事務策略,根據需求、設備等條件選擇對應的策略,從而完成需求或優化程序。
1.只開啓了一個事務,Spring默認的傳播行爲是PROPAGATION_REQUIRED,即若是當前存在事務,即加入該事務;若是當前沒有事務,則新建一個新的事務。所以只開啓了一個事務。
Spring事務的傳播行爲的7種類型
TransactionDefinition.PROPAGATION_REQUIRED:若是當前存在事務,則加入該事務;若是當前沒有事務,則建立一個新的事務。這是默認值。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:建立一個新的事務,若是當前存在事務,則把當前事務掛起。
TransactionDefinition.PROPAGATION_SUPPORTS:若是當前存在事務,則加入該事務;若是當前沒有事務,則以非事務的方式繼續運行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事務方式運行,若是當前存在事務,則把當前事務掛起。
TransactionDefinition.PROPAGATION_NEVER:以非事務方式運行,若是當前存在事務,則拋出異常。
TransactionDefinition.PROPAGATION_MANDATORY:若是當前存在事務,則加入該事務;若是當前沒有事務,則拋出異常。
TransactionDefinition.PROPAGATION_NESTED:若是當前存在事務,則建立一個事務做爲當前事務的嵌套事務來運行;若是當前沒有事務,則該取值等價於TransactionDefinition.PROPAGATION_REQUIRED。
IOC:Inversion of Control,即「控制反轉」,不是什麼技術,而是一種設計思想。IOC意味着將你設計好的對象交給容器控制,而不是new。
IOC 控制反轉,指將對象的建立權,反轉到Spring容器
IOC容器是具備依賴注入功能的容器,負責實例化、定位、配置應用程序中的對象及創建這些對象間的依賴。應用程序無需直接在代碼中new相關的對象,應用程序由IOC容器進行組裝。在Spring中BeanFactory是IOC容器的實際表明者。
1.減小代碼的耦合,能夠使應用更加模塊化
2.增長代碼的複用率
3.資源更加統一管理
4.維護代碼更加方便,通常只須要修改一下配置文件就ok了。
5.提高了程序的測試性
連接:https://www.imooc.com/article/35099
DI:Dependency Injection 依賴注入,在Spring框架建立Bean對象時,動態的將依賴對象注入到Bean組件
1.實例化Bean對象:服務器啓動時,初始化spring容器,建立由XML配置或添加了相應註解的類的實例,並將實例保存到Spring容器中;
2.完成ID操做:經過XML描述或對應註解,完成對象之間的依賴關係,此過程稱爲依賴注入,spring支持3種注入實現:
①註解注入:經過註解顯示注入。經常使用註解@Resource。
②XML注入:經過xml顯示注入。
③自動注入:隱式進行bean搜索並自動裝配
IOC 控制反轉,指將對象的建立權,反轉到Spring容器 ,
DI 依賴注入,指Spring建立對象的過程當中,將對象依賴屬性經過配置進行注入
DI依賴注入不能單獨存在,必須在IOC控制反轉的基礎上才能完成。
在web項目中配置Spring的IOC容器其實就是建立web應用的上下文(WebApplicationContext)
1.若是使用Spring Boot,默認掃描啓動類所在包以及子包,啓動完成上下文對象建立。
2.使用註解的普通web項目,須要在配置類中使用@ComponentScan肯定掃描包位置,啓動完成上下文對象建立。
3.使用xml的普通web項目,須要在web.xml配置初始化參數肯定xml文件位置,從而肯定加載的內容,啓動完成上下文對象建立。
參考:
http://www.cnblogs.com/qf123/p/8488404.html
1.單例設計模式:
Spring中Bean默認是單例的,底層採用的是單例設計模式;
2.工廠模式:
BeanFactory,做用就是配置、新建、管理 各類Bean
3.代理模式:
代理模式的定義是爲其它對象提供一種代理,以控制這個對象的訪問;在Spring AOP中就使用了代理模式,使用代理模式完成在不修改代碼的狀況下,實現對功能的加強;
4.適配器模式:
將一個類的接口變換成客戶所期待的另外一種接口,從而使本來不匹配而沒法一塊兒工做的倆個類可以在一塊兒工做;SpringMVC中的適配器HandlerAdatper,HandlerAdatper根據不一樣的handler規則執行不一樣的handler;
5.模板方法模式:
父類定義了骨架(調用哪些方法及順序),某些特定方法由子類實現;在Spring的 JdbcTemplate,RestTemplate, JmsTemplate等地方使用了模板方法模式;
連接:https://blog.csdn.net/z69183787/article/details/65628166;
AOP (Aspect Oriented Programing) 稱爲:面向切面編程,它是一種編程思想。在程序運行的時候,動態地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切面的編程。
基於代理思想,對原來目標對象,建立代理對象,在不修改原對象代碼狀況下,對原有業務方法進行加強 !
代理模式:分爲靜態代理、JDK動態代理、cglib代理
1.靜態代理
代理類和被代理類實現共同的接口(或繼承),代理類中存有指向被代理類的引用,實際執行時經過調用代理類的方法、實際執行的是被代理類的方法。
2.jdk動態代理:必須有接口和實現類(目標類),經過工具類Proxy生產接口對應的代理類,從而對目標類進行加強。
3.Cglib代理:Cglib代理生成的代理類是目標類的子類,因此目標類不能使用final修飾。
AOP
Spring AOP經過代理的方式,對目標類進行加強。
Spring AOP底層默認使用JDK動態代理,經過配置能夠修改爲cglib代理。
描述切面必須先了解如下幾個概念:
1.目標類:須要被加強的類。
2.鏈接點:可能被加強的點,目標類中的全部方法。
3.切入點:將會被加強的鏈接點,目標類中被加強的方法。
4.通知/加強:對切入點加強的內容。加強的內容一般以方法的形式體現的。加強執行的位置不一樣,稱呼不一樣。
(前置通知、後置通知、環繞通知、拋出異常通知、最終通知)
通知方法所在的類,一般稱爲切面類。
5.切面:通知和切入點的結合。一個通知對應一個切入點就造成一條線,多個通知對應多個切入點造成多條線,多條線造成了一個面,稱爲切面。
通知:對切入點加強的內容。加強的內容一般以方法的形式體現的。
在spring中根據加強執行位置的不一樣,將通知分紅如下5種:
1.前置通知(before):在一個方法執行前被調用。
2.後置通知(after-returning):僅當方法成功完成後執行。
3.環繞通知(around):在方法執行以前和以後調用。
4.拋出異常通知(after-throwing):在方法拋出異常退出時執行。
5.最終通知(after): 在方法執行以後調用,不管方法執行是否成功。
實現細節,方便理解
try{
//1 前置通知
// 目標方法
//2 後置通知
} catch(){
//4 拋出異常通知
} finally{
//5 最終通知
}
在說切入點前,須要先說鏈接點
鏈接點:可能被加強的點,目標類中的全部方法。
切入點:將會被加強的鏈接點,目標類中被加強的方法。
目標類:須要被加強的類。
AOP經過生成代理對象,對目標類進行加強。
在spring AOP中,代理對象,將通知和切入點鏈接起來,從而實現加強的過程。
使用"橫切"技術,AOP把軟件系統分爲兩個部分:核心關注點和橫切關注點。
業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。
橫切關注點的一個特色是,常常發生在覈心關注點的多處,而各處基本類似,好比權限認證、日誌、事物。
AOP的做用在於分離系統中的各類關注點,將核心關注點和橫切關注點分離開來。
參考:https://www.cnblogs.com/hongwz/p/5764917.html
1.目標類(target):須要被加強的類。
2.鏈接點(Joinpoint):可能被加強的點,目標類中的全部方法。
3.切入點(Pointcut):將會被加強的鏈接點,目標類中被加強的方法。
4.通知/加強(Advice):對切入點加強的內容。加強的內容一般以方法的形式體現的。加強執行的位置不一樣,稱呼不一樣。
(前置通知、後置通知、環繞通知、拋出異常通知、最終通知)
通知方法所在的類,一般稱爲切面類。
5.切面(Aspect):通知和切入點的結合。一個通知對應一個切入點就造成一條線,多個通知對應多個切入點造成多條線,多條線造成了一個面,稱爲切面。
6.織入(Weaving): 生成切面並建立代理對象的過程。(將通知和切入點的結合,並建立代理對象的過程)
f. 切面(Aspect):
切面是由切點和加強(引介)組成的,它包括了對橫切關注功能的定義,也包括了對鏈接點的定義。
參考:https://www.cnblogs.com/hongwz/p/5764917.html
1.事務 Transaction
2.日誌處理 logging, tracing, profiling and monitoring
3.緩存 Caching
4.權限控制 Authentication
5.錯誤處理 Error handling
6.懶加載 Lazy loading
連接:http://blog.sina.com.cn/s/blog_7045cb9e01010a9r.html
https://blog.csdn.net/qq513165077/article/details/78288999
IOC控制反轉:指將對象的建立權,反轉到Spring容器
方式1:建立工廠
建立一個工廠,用於建立目標對象,就是最簡單的IOC。但工廠和目標類耦合。
方式2:工廠 + 配置文件
1)配置文件中存放類的全限定名稱
2)編寫工廠,用於讀取配置文件中的內容,並經過反射建立對象。
問題:工廠只能生產一個對象
方式3:工廠 + properties文件
1)properties配置文件存放一組,key是標識,value是全限定名稱
2)編寫工廠類,讀取配置文件
3)提供getBean( name ) 用於生成實例:經過name得到對應的全限定名稱,再經過反射建立對應的實例。
MVC設計模式: Model-View-Controller簡寫。
MVC是軟件工程中的一種軟件架構模式,它是一種分離業務邏輯與顯示界面的設計方法。它把軟件系統分爲三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。
① 控制器Controller:對請求進行處理,負責選擇視圖;
② 視圖View:用戶與程序交互的界面;
③ 模型Model:用於業務處理
SpringMVC是一個MVC框架,springmvc的工做流程:
1. 發送請求:在瀏覽器輸入請求路徑,發送請求,前端控制器鏈接全部的請求。
2. 得到處理器:核心控制器(DispatcherServlet)接收到請求,經過處理器映射器(handlerMapping)得到對應的處理器(Handler)
即根據請求路徑得到對應的controller。
3. 執行處理器:經過處理器適配器(HandlerAdapter)執行處理器(Handler),並返回視圖模型對象(ModelAndView)
即執行controller方法。若是方法返回的字符串,底層也會轉換成ModelAndView。
4. 解析視圖:經過視圖解析器(ViewResolver)解析ModelAndView中的視圖,將邏輯視圖解析成真正的視圖。
5. 渲染視圖:將Model中的數據渲染到視圖(View)中
6. 響應結果
即將模型數據(查詢結果)渲染到jsp頁面中,並將處理結果響應給瀏覽器。
Spring框架的核心控制器(前端控制器)是DispatherServlet
他的核心功能就是分發請求,請求會被分發給對應處理的類handler。
使用@ResponseBody註解,將返回json數據。
1.若是在方法使用該註解,當前方法返回json數據。
2.若是在類上使用該註解,當前類中全部的方法,都將返回json數據。
springmvc默認用jackson對json數據進行轉換,但須要添加jackson的包
擴展閱讀:
消息轉換器原理解析:https://blog.csdn.net/shadabing/article/details/84664402
SpringBoot配置Fastjson:https://blog.csdn.net/cjq2013/article/details/76421101
SpringMVC配置Fastjson:https://blog.csdn.net/do_bset_yourself/article/details/51324186
優勢:
一、開發人員能夠只關注整個結構中的其中某一層;
二、容易用新的實現來替換原有層次的實現;
三、下降層與層之間的依賴;
四、有利於標準化;
五、有利於各層邏輯的複用
缺點:
一、下降了系統的性能。這是不言而喻的。若是不採用分層式結構,不少業務能夠直接造訪數據庫,以此獲取相應的數據,現在卻必須經過中間層來完成。
二、有時會致使級聯的修改。這種修改尤爲體如今自上而下的方向。若是在表示層中須要增長一個功能,爲保證其設計符合分層式結構,可能須要在相應的業務邏輯層和數據訪問層中都增長相應的代碼。
1.Spring相關注解
1.1)聲明bean的註解
@Component 通用註解,用於聲明bean。能夠配置任意組件。
@Repository 派生註解,與@Component等效,Dao實現類推薦使用的註解,不只能夠聲明bean,並且提升可讀性。
@Service 派生註解,與@Component等效,Service實現類推薦使用的註解,不只能夠聲明bean,並且提升可讀性。
@Controller 派生註解,與@Component等效,Controller實現類推薦使用的註解,不只能夠聲明bean,並且提升可讀性。
1.2)bean注入的相關注解
@Autowired:按類型注入,
@Resource(name=""):按名稱注入
@Resource():先按名稱注入,若是沒有再按照類型。
1.3)配置類相關注解
@Bean 在方法上,聲明當前方法的返回值爲一個bean。
@Configuration 聲明當前類爲配置類,內部常使用@Bean進行詳細配置。取代了xml文件配置。
@ComponentScan 用於對Component進行掃描,能夠配置掃描的包路徑
1.4)@Value:爲屬性注入簡單值
2.SpringMVC相關注解
@RequestMapping 修飾方法,將請求路徑映射到Controller對應的處理方法上。
修飾類,給請求路徑添加訪問前綴(二級路徑)
@ResponseBody 將返回值轉換成json數據,並響應給瀏覽器。
@RequestBody 將json格式的請求參數,封裝到指定的JavaBean中。
@PathVariable 用於接收路徑參數,好比@RequestMapping(「/hello/{name}」)申明的路徑,參數前使用註解@PathVariable("name"),就能夠獲取name對應的值。
@RestController 該註解爲一個組合註解,至關於@Controller和@ResponseBody的組合,註解在類上,意味着,該Controller的全部方法都響應JSON格式數據。
1.地址欄參數或普通表單請求,如:age=18&gender=man,SpringMVC方法參數須要使用@RequestParam("參數名")得到參數值。
2.提交json類型數據,SpringMVC 方法參數須要使用@RequestBody 將數據封裝到java對象中。
3.路徑佔位符:如 http://localhost:8080/user/findById/1,使用@RequestMapping("findById/{id}")匹配路徑,使用@PathVariable("id")得到對應的參數值。
4.文件上傳,修改表單請求爲"multipart/form-data"方式,SpringMVC採用MultipartFile參數類型接收數據
DispatcherServlet用來處理全部的HTTP請求和請求響應
回答SpringMVC的執行流程便可:
1. 用戶向服務器發送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲;
2. DispatcherServlet對請求URL進行解析,獲得請求資源標識符(URI)。而後根據該URI,調用HandlerMapping得到該Handler配置的全部相關的對象(包括Handler對象以及Handler對象對應的攔截器),最後以HandlerExecutionChain對象的形式返回;
3. DispatcherServlet 根據得到的Handler,選擇一個合適的HandlerAdapter。(附註:若是成功得到HandlerAdapter後,此時將開始執行攔截器的preHandler(...)方法)
4. 提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。 在填充Handler的入參過程當中,根據你的配置,Spring將幫你作一些額外的工做:
HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換爲指定的響應信息
數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等
數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等
數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中
5. Handler執行完成後,向DispatcherServlet 返回一個ModelAndView對象;
6. 根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經註冊到Spring容器中的ViewResolver)返回給DispatcherServlet ;
7. ViewResolver 結合Model和View,來渲染視圖
8. 將渲染結果返回給客戶端。
@Controller 是@Component的派生註解,功能就是將被修飾的類添加到spring容器。
用於修飾Controller層的組件,提升可讀性。
修飾方法,將請求路徑映射到Controller對應的處理方法上。
修飾類,給請求路徑添加訪問前綴(二級路徑)
使用 @ResponseBody 註解將Java集合轉換json數組,並將結果響應給瀏覽器。