您好,登錄后才能下訂單哦!
List:元素是有順序的,元素可以重復因為每個元素有自己的角標(索引)
? |-- ArrayList:底層是數組結構,特點是:查詢很快,增刪稍微慢點,線程不同步:A線程將元素放在索引0位置,CPU調度線程A停止,B運行,也將元素放在索引0位置,當A和B同時運行的時候Size就編程了2.
? |-- LinkedList:底層使用的是鏈表數據結構,特點是:增刪很快,查詢慢。線程不安全,線程安全問題是由多個線程同時寫或同時讀寫同一個資源造成的。
? |--Vector:底層是數組數據結構,線程同步,Vector的方法前面加了synchronized關鍵字,被ArrayList代替了,現在用的只有他的枚舉。
Set:元素是無序的,且不可以重復(存入和取出的順序不一定一致),線程不同步。set底層是使用Map實現的,故可以通過ConcurrentHashMap的方式變通實現線程安全的Set。
|--HashSet:底層是哈希表數據結構。根據hashCode和equals方法來確定元素的唯一性。
hashCode和equals:作用一樣,都是用來比較兩個對象是否相等一致。
equals比較的比較全面,而利用hashCode()進行對比,則只要生成一個hash值進行比較久可以了,效率高。
equal()相等的兩個對象他們的hashCode()肯定相等,也就是equal()是絕對可靠的。
hashCode()相等的兩個對象他們的equal()不一定相等,hashCode()不是絕對可靠的。
Map:這個集合是存儲鍵值對的,一對一對往里存,而且要確保鍵的唯一性(01,張三)這樣的形式打印出來就是 ?01=張三
|--HashTable:底層是哈希表數據結構,不可以存入null鍵和null值,該集合線程是同步的,效率比較低。出現于JDK1.0。線程安全,使用synchronized鎖住整張Hash表實現線程安全,即每次鎖住整張表讓線程獨占。
|--HashMap:底層是哈希表數據結構,可以存入null鍵和null值,線程不同步,效率較高,代替了HashTable,出現于JDK 1.2
|--TreeMap:底層是二叉樹數據結構,線程不同步,可以用于對map集合中的鍵進行排序
ConcurrentHashMap:線程安全,允許多個修改操作并發進行,其關鍵在于使用了鎖分離技術,它使用了多個鎖來控制對hash表的不同部分進行的修改。ConcurrentHashMap內部使用段(Segment)來表示這些不同的部分,每個段其實就是一個小的Hashtable,它們有自己的鎖。只要多個修改操作發生在不同的段上,它們就可以并發進行。
當兩個對象需要對比的時候,首先用hashCode()去對比,如果不一樣,則表示這兩個對象肯定不相等(也就不用再比較equal(0)了),如果hashCode()相同,再比較equal(),如果equal()相同,那兩個對象就是相同的。
|--TreeSet:可以對Set集合中的元素進行排序(自然循序),底層的數據結構是二叉樹,
HashMap實際上是一個“鏈表散列”的數據結構,即數組和鏈表的結合體。允許使用null值和null鍵。
HashMap底層就是一個數組結構,數組中的每一項又是一個鏈表。當新建一個HashMap的時候,就會初始化一個數組。
HashMap是基于hash算法實現的,通過put(key,value)存儲對象到HashMap中,也可以通過get(key)從HashMap中獲取對象。
當我們使用put的時候,首先HashMap會對key的hashCode()的值進行hash計算,根據hash值得到這個元素在數組中的位置,將元素存儲在該位置的鏈表上。
當我們使用get的時候,首先HashMap會對key的hashCode()的值進行hash計算,根據hash值得到這個元素在數組中的位置,將元素從該位置上的鏈表中取出
當多線程的情況下,可能產生條件競爭。當重新調整HashMap大小的時候,確實存在條件競爭,如果兩個線程都發現HashMap需要重新調整大小了,
它們會同時試著調整大小。在調整大小的過程中,存儲在鏈表中的元素的次序會反過來,因為移動到新的數組位置的時候,
HashMap并不會將元素放在LinkedList的尾部,而是放在頭部,這是為了避免尾部遍歷(tail traversing)。如果條件競爭發生了,那么就死循環了
為什么使用ConcurrentHashMap:
我們都知道HashMap是非線程安全的,當我們只有一個線程在使用HashMap的時候,自然不會有問題,但如果涉及到多個線程,并且有讀有寫的過程中,HashMap就會fail-fast。要解決HashMap同步的問題,我們的解決方案有:Hashtable 、Collections.synchronizedMap(hashMap)?
這兩種方式基本都是對整個hash表結構加上同步鎖,這樣在鎖表的期間,別的線程就需要等待了,無疑性能不高,所以我們引入ConcurrentHashMap,既能同步又能多線程訪問
ConcurrentHashMap的數據結構:
ConcurrentHashMap的數據結構為一個Segment數組,Segment的數據結構為HashEntry的數組,而HashEntry存的是我們的鍵值對,可以構成鏈表。可以簡單的理解為數組里裝的是HashMap
LinkedHashMap底層使用哈希表與雙向鏈表來保存所有元素,它維護著一個運行于所有條目的雙向鏈表(如果學過雙向鏈表的同學會更好的理解它的源代碼),此鏈表定義了迭代順序,該迭代順序可以是插入順序或者是訪問順序?
運行速度快慢為:StringBuilder > StringBuffer > String
String最慢的原因:
String為字符串常量,而StringBuilder和StringBuffer均為字符串變量,即String對象一旦創建之后該對象是不可更改的,但后兩者的對象是變量,是可以更改的。
sleep方法屬于線程,wait方法屬于對象
sleep休眠當前線程,不會釋放對象鎖,wait使當前線程進入等待狀態,釋放對象鎖,只有針對此對象調用notify()方法(且共享對象資源釋放)后本線程才會繼續執行
JVM內存結構主要有三大塊:堆內存、方法區和棧,幾乎所有的對象實例都存放在堆里,如果在堆中沒有內存完成實例分配,并且堆也無法再擴展時,將會拋出OutOfMemoryError異常。
方法區用于存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據,當方法區無法滿足內存分配需求時,將拋出OutOfMemoryError異常。
每個方法被執行的時候都會同時創建一個棧幀(Stack Frame)用于存儲局部變量表、操作棧、動態鏈接、方法出口等信息。
每一個方法被調用直至執行完成的過程,就對應著一個棧幀在虛擬機棧中從入棧到出棧的過程。?
如果線程請求的棧深度大于虛擬機所允許的深度,將拋出StackOverflowError異常。
強引用:
以前我們使用的大部分引用實際上都是強引用,這是使用最普遍的引用。如果一個對象具有強引用,那就類似于必不可少的生活用品,垃圾回收器絕不會回收它。
當內存空間不足,Java虛擬機寧愿拋出OutOfMemoryError錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足問題。?
軟引用:
如果一個對象只具有軟引用,那就類似于可有可物的生活用品。如果內存空間足夠,垃圾回收器就不會回收它,如果內存空間不足了,就會回收這些對象的內存
弱引用:
弱引用與軟引用的區別在于:只具有弱引用的對象擁有更短暫的生命周期。
在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存
總結:
當一個對象使用關鍵字“new”創建時,會在堆上分配內存空間,然后返回對象的引用,這對數組來說也是一樣的,因為數組也是一個對象
簡單的值類型的數組,每個數組成員是一個引用(指針),引用到棧上的空間
1.懶漢模式
public class SingletonDemo {
private static SingletonDemo instance;
private SingletonDemo(){}
public static SingletonDemo getInstance(){
if(instance==null){
instance=new SingletonDemo();
}
return instance;
}
}
2.餓漢模式
public class SingletonDemo {
private static SingletonDemo instance=new SingletonDemo();
private SingletonDemo(){}
public static SingletonDemo getInstance(){
return instance;
}
}
3.簡單工廠模式
面條工廠:
public abstract class INoodles {
/**
* 描述每種面條啥樣的
*/
public abstract void desc();
}
先來一份蘭州拉面(具體的產品類):
public class LzNoodles extends INoodles {
@Override
public void desc() {
System.out.println("蘭州拉面 上海的好貴 家里才5 6塊錢一碗");
}
}
程序員加班必備也要吃泡面(具體的產品類):
public class PaoNoodles extends INoodles {
@Override
public void desc() {
System.out.println("泡面好吃 可不要貪杯");
}
}
準備工作做完了,我們來到一家“簡單面館”(簡單工廠類),菜單如下:
public class SimpleNoodlesFactory {
public static final int TYPE_LZ = 1;//蘭州拉面
public static final int TYPE_PM = 2;//泡面
public static INoodles createNoodles(int type) {
switch (type) {
case TYPE_LZ:
return new LzNoodles();
case TYPE_PM:
return new PaoNoodles();
default:
return new PaoNoodles();
}
}
/**
* 簡單工廠模式
*/
void creat(){
INoodles noodles = SimpleNoodlesFactory.createNoodles(SimpleNoodlesFactory.TYPE_PM);
noodles.desc();
}
}
流程:用戶發送請求給服務器。url:user.do--->Dispatchservlet處理-->DispatchServlet通過HandleMapping調用這個url對應的Controller
Controller執行完畢后,如果返回字符串,則ViewResolver將字符串轉化成相應的視圖對象;如果返回ModelAndView對象,該對象本身就包含了視圖對象信息。
DispatchServlet將執視圖對象中的數據,輸出給服務器并呈現給客戶
IOC控制反轉:典型的工廠模式,就是具有依賴注入功能的容器,是可以創建對象的容器,IOC容器負責實例化、定位、配置應用程序中的對象及建立這些對象間的依賴。
通常new一個實例,控制權由程序員控制,而"控制反轉"是指new實例工作不由程序員來做而是交給Spring容器來做。。在Spring中BeanFactory是IOC容器的實際代表者
AOP依賴注入:典型的代理模式,面向切面編程將程序中的交叉業務邏輯(比如安全,日志,事務),封裝成一個切面,然后注入到目標業務邏輯中去。
aop框架具有的兩個特征:
通過在mapper配置文件里配置的屬性對照反射進對象里
多態是同一個行為具有多個不同表現形式或形態的能力。
多態就是同一個接口,使用不同的實例而執行不同操作
比如同一個打印機,可以打印黑白的紙張也可以打印彩色的,同樣是人,卻有黑人白人之分
接口是一種規范,在這里舉兩個例子
http是一種超文本協議,默認端口80,以明文傳輸。
https是http協議的安全版,安全基礎是SSL,以密文傳輸
cookie存在客戶端,session存在服務端
分布式Session的幾種實現方式
Git是分布式的,而Svn不是分布的
Git下載下來后,在OffLine狀態下可以看到所有的Log,SVN不可以
SVN的特點是簡單,只是需要一個放代碼的地方時用是OK的,Git的特點版本控制可以不依賴網絡做任何事情,對分支和合并有更好的支持
堆溢出,死循環存值,JVM就會拋出OutOfMemoryError:java heap space異常
public static void main(String[] args) {
List<byte[]> list = new ArrayList<>();
int i=0;
while(true){
list.add(new byte[5*1024*1024]);
System.out.println("分配次數:"+(++i));
}
}
棧溢出,棧空間不足——StackOverflowError實例
public class StackSOFTest {
int depth = 0;
public void sofMethod(){
depth ++ ;
sofMethod();
}
public static void main(String[] args) {
StackSOFTest test = null;
try {
test = new StackSOFTest();
test.sofMethod();
} finally {
System.out.println("遞歸次數:"+test.depth);
}
}
}
可以
ThreadLocal使用場合主要解決多線程中數據數據因并發產生不一致問題。ThreadLocal為每個線程的中并發訪問的數據提供一個副本,通過訪問副本來運行業務,這樣的結果是耗費了內存,單大大減少了線程同步所帶來性能消耗,也減少了線程并發控制的復雜度。
ThreadLocal和Synchonized都用于解決多線程并發訪問。但是ThreadLocal與synchronized有本質的區別。synchronized是利用鎖的機制,使變量或代碼塊在某一時該只能被一個線程訪問。而ThreadLocal為每一個線程都提供了變量的副本,使得每個線程在某一時間訪問到的并不是同一個對象,這樣就隔離了多個線程對數據的數據共享。而Synchronized卻正好相反,它用于在多個線程間通信時能夠獲得數據共享。
Synchronized用于線程間的數據共享,而ThreadLocal則用于線程間的數據隔離。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。