類加載html
類加載過程:加載-驗證-準備-解析-初始化
雙親委派過程java
雙親委派模式的工做原理的是: 若是一個類加載器收到了類加載請求,它並不會本身先去加載,而是把這個請求委託給父類的加載器去執行,若是父類加載器還存在其父類加載器,則進一步向上委託,依次遞歸,請求最終將到達頂層的啓動類加載器,若是父類加載器能夠完成類加載任務,就成功返回,假若父類加載器沒法完成此加載任務,子加載器纔會嘗試本身去加載,這就是雙親委派模式 好處: 類加載具備層級關係,避免重複加載,當父類已經加載了該類時,就沒有必要子ClassLoader再加載一次;並且能夠防止api核心庫rt.jar被隨意篡改
BIO/NIO/AIO 區別react
BIO(blocking input output):同步阻塞io
NIO(new input output/non blocking input outpue):非阻塞io,採用reactor模式
AIO:異步非阻塞io,設置監聽器主動去監聽請求,觸發worker主動處理
select/poll/epoll模型 git
線程池github
多線程實現方式: 1.繼承Thread 2.實現runnable接口 3.實現callable接口和futureTask 4.線程池 線程池: 1.固定線程池newFixedThreadPool 核心線程數 = 最大線程數 2.單個線程池、newSingleThreadExecutor 核心線程數 = 最大線程數 =0 3.無限大線程池newCachedThreadPool 核心線程數0 最大線程數Integer.MAX_VALUE keepAliveTime 60L 秒 隊列已滿而且超過最大線程數,會觸發rejectExecutorHandle拒絕策略 4.定時任務ScheduledThreadPoolExecutor, 核心線程數設置 最大線程數Integer.MAX_VALUE 關鍵核心參數: corePoolSize:核心線程數,當前線程數小於核心線程數,有新的任務進來會建立新的線程 maximumPoolSize: 最大線程數,當前線程數小於最大線程數,當前核心線程數已滿而且隊列已滿,有新的任務進來會建立新的線程 keepAliveTime:線程空閒時間,核心線程池之外的線程最大空閒時間 workQueue 用於存聽任務,添加任務的時候,若是當前線程數超過了 corePoolSize,那麼往該隊列中插入任務,線程池中的線程會負責到隊列中拉取任務。 threadFactory:線程工廠 allowCoreThreadTimeOut:容許核心線程超時 rejectedExecutionHandler:任務拒絕處理器 好處: 下降線程的建立銷燬消耗,提升線程的管理性,當任務到達時,任務能夠不須要等到線程建立就能當即執行,提升響應速度 提交任務: exector:用於提交不須要返回值的任務,因此沒法判斷任務是否被線程池執行成功 submit:用於提交須要返回值的任務.線程池會返回一個future類型對象,經過此對象能夠判斷任務是否執行成功 線程數的配置: IO密集型 : cup數目 *2 Cpu密集型: cpu數目 拒絕策略執行: workers 的數量達到了 corePoolSize,任務入隊成功,以此同時線程池被關閉了,並且關閉線程池並無將這個任務出隊,那麼執行拒絕策略。 workers 的數量大於等於 corePoolSize,準備入隊,但是隊列滿了,任務入隊失敗,那麼準備開啓新的線程,但是線程數已經達到 maximumPoolSize,那麼執行拒絕策略。
4種緩衝隊列BlockingQueue: workQueue = new ArrayBlockingQueue<>(5);//基於數組的先進先出隊列,有界 workQueue = new LinkedBlockingQueue<>();//基於鏈表的先進先出隊列,無界 workQueue = new SynchronousQueue<>();//無緩衝的等待隊列,無界 workQueue = new PriorityBlockingQueue<>();//一個支持線程優先級排序的無界隊列,默認天然序進行排序,也能夠自定義實現compareTo()方法來指定元素排序規則,不能保證同優先級元素的順序。 四種拒絕策略: RejectedExecutionHandler rejected = null; rejected = new ThreadPoolExecutor.AbortPolicy();//默認,隊列滿了丟任務拋出異常 rejected = new ThreadPoolExecutor.DiscardPolicy();//隊列滿了丟任務不異常 rejected = new ThreadPoolExecutor.DiscardOldestPolicy();//將最先進入隊列的任務刪,以後再嘗試加入隊列 rejected = new ThreadPoolExecutor.CallerRunsPolicy();//若是添加到線程池失敗,那麼主線程會本身去執行該任務
避免死鎖的幾種方法redis
1.設置加鎖順序 A-B-C 加鎖順序,必須等到A和B獲取鎖後,才能輪到C獲取 2.設置加鎖時限 獲取鎖的時候設置一個超時時間,超時不須要再獲取鎖,放棄操做 3.死鎖檢測 避免一個線程同時獲取多個鎖 避免一個線程在鎖內同時佔用多個資源,保證每一個鎖只佔用一個資源 嘗試使用定時鎖,使用lock.trylock(timeout)來代替內部鎖機制 對於數據庫鎖,加鎖和解鎖必須在一個數據庫鏈接中,不然會出現解鎖失敗
new Thread(new Runnable() { @Override public void run() { synchronized (object1){ Thread.sleep(3000); System.out.println("線程1未完成,等待線程2"); synchronized (object2){ System.out.println("線程1完成"); } } } }).start(); new Thread(new Runnable() { @Override public void run() { synchronized (object2){ Thread.sleep(3000); System.out.println("線程2未完成,等待線程1"); synchronized (object1){ System.out.println("線程2完成"); } } } }).start();
synchronized和reentrantLock區別: 2者均是可重入鎖 1.synchronized是非公平鎖 ;reentrantLock 可公平可非公平 2.synchronized基於jvm ;reentrantLock基於jdk 3.在資源競爭不是很激烈的狀況下,Synchronized的性能要優於ReetrantLock,可是在資源競爭很激烈的狀況下,Synchronized的性能會降低幾十倍,可是ReetrantLock的性能能維持常態; 4.synchronized未獲取到鎖會一直等待; reentrantLock 能夠被中斷: a)lock(), 若是獲取了鎖當即返回,若是別的線程持有鎖,當前線程則一直處於休眠狀態,直到獲取鎖 b)tryLock(), 若是獲取了鎖當即返回true,若是別的線程正持有鎖,當即返回false; c)tryLock (long timeout, TimeUnit unit), 若是獲取了鎖定當即返回true,若是別的線程正持有鎖,會等待參數給定的時間,在等待的過程當中,若是獲取了鎖定,就返回true,若是等待超時,返回false; d)lockInterruptibly:若是獲取了鎖定當即返回,若是沒有獲取鎖定,當前線程處於休眠狀態,直到或者鎖定,或者當前線程被別的線程中斷
LRU算法:最少使用算法,redis底層實現相似於lru算法spring
java中的樂觀鎖和悲觀鎖json
什麼狀況下分表?什麼狀況下分庫?
1.垂直分表:字段太多,字段長度太大,不常常用的字段,拆字段;垂直分庫:根據不一樣業務進行庫的拆分,一個微服務對應一個數據庫 2.水平分庫分表:數量量大,進行水平數據的分庫分表 優勢:服務,業務解耦,業務清晰;提升系統穩定性和可用性,提高io 缺點:多表聯合查詢join,group by,排序;字段冗餘;分佈式事務處理複雜;全局主鍵避重問題(雪花算法)
Volatile
1.保證可見性,避免指令重排,一種比sychronized更輕量的同步機制,volatile並非保證原子性 2.可見性是經過load和store指令完成,也就是對volatile變量進行寫操做的時候,會在寫操做加store指令,將數據刷新到主內存 執行讀操做時,會在讀操做加load指令,從主內存讀取數據 volatile不能保證原子性: 由於從主存的拿的值而後再修改後寫回主存的過程可能有其餘線程已經做過這個操做了,因此致使數據會不對
ThreadLocal
ThreadLocal提供了get與set等訪問接口或方法,這些方法爲每一個使用該變量的線程都存有一份獨立的副本,由於get老是返回當前執行線程在調用set時設置的最新值。 ThreadLocal<T>視爲包含了Map<Thread,T>對象,其中保存了特定於該線程的值,但ThreadLocal的實現並不是如此。這些特定於現場的值保存在Thread對象中,當線程終止後,這些值會做爲垃圾回收。
三次握手和四次揮手,5層協議, 在瀏覽器中輸入url地址 ->> 顯示主頁的過程
三種常見異常:
NullPointerException - 空指針引用異常 ClassCastException - 類型強制轉換異常。 IllegalArgumentException - 傳遞非法參數異常 ArithmeticException - 算術運算異常 IndexOutOfBoundsException - 下標越界異常 NumberFormatException - 數字格式異常 SecurityException - 安全異常 IOException--輸入輸出異常 NoSuchMethodException--方法未找到異常 FileNotFoundException--文件未找到異常 ArrayIndexOutOfBoundsException --數組下標越界異常 SQLException OutOfMemoryError
Spring事務,數據庫事務,隔離級別,傳播性
1.事務的特性(ACID) A:原子性;在一個事務中,要麼所有成功,要麼所有失敗 C:一致性;在一個事務中,執行以前和執行以後數據保持一致 I:隔離性;事務直接相互隔離,互不影響 D:持久性;事務提交後,對數據庫的操做不可更改,不能進行回滾 2.事務的隔離級別 讀未提交:會形成髒讀,不可重複讀,幻讀;能夠讀取都其餘事務未提交的數據,主要針對查詢操做 讀已提交:會形成不可重複讀,幻讀;讀取其餘事務已經提交的數據,先後讀取的數據內容不一樣,主要針對更新操做 可重複讀:會形成幻讀;解決不可重複讀應該是採用行鎖的形式(現實生活中,for update或者version cas)先後讀取的數據條數不一樣,主要針對插入刪除操做 串行化:無問題,採用鎖表的形式,效率低 3.spring 傳播行爲 (1)Require:支持當前事務,若是沒有事務,就建一個新的,這是最多見的 (2)Supports:支持當前事務,若是當前沒有事務,就以非事務方式執行 (3)Mandatory:支持當前事務,若是當前沒有事務,就拋出異常 (4)RequiresNew:新建事務,若是當前存在事務,把當前事務掛起 (5)NotSupported:以非事務方式執行操做,若是當前存在事務,就把事務掛起 (6)Never:以非事務方式執行,若是當前存在事務,則拋出異常 (7)Nested:新建事務,若是當前存在事務,把當前事務掛起。與RequireNew的區別是與父事務相關,且有一個savepoint
hashMap原理:
hashmap 容量爲何必定要是2的次冪:主要是爲了分佈均衡,增長碰撞的概率 若是length爲2的次冪 則length-1 轉化爲二進制一定是11111……的形式,在於h的二進制與操做效率會很是的快, 並且空間不浪費;若是length不是2的次冪,好比length爲15,則length-1爲14,對應的二進制爲1110,在於h與操做, 最後一位都爲0,而0001,0011,0101,1001,1011,0111,1101這幾個位置永遠都不能存放元素了,空間浪費至關大,更糟的是這種狀況中,數組可使用的位置比數組長度小了不少,這意味着進一步增長了碰撞的概率,減慢了查詢的效率!這樣就會形成空間的浪費
使用new關鍵字 | } → 調用了構造函數 |
使用Class類的newInstance方法 | } → 調用了構造函數 |
使用Constructor類的newInstance方法 | } → 調用了構造函數 |
使用clone方法 | } → 沒有調用構造函數 |
使用反序列化 | } → 沒有調用構造函數 |
ArrayList基於數組實現,LinkedList是基於雙鏈表實現的;ArrayList多用於隨機訪問,查詢,LinkedList多用於更新和刪除
Minor GC觸發條件:當Eden區滿時,觸發Minor GC Full GC觸發條件: (1)調用System.gc時,系統建議執行Full GC,可是沒必要然執行 (2)老年代空間不足 (3)方法區空間不足 (4)經過Minor GC後進入老年代的平均大小大於老年代的可用內存 (5)由Eden區、From Space區向To Space區複製時,對象大小大於To Space可用內存,則把該對象轉存到老年代,且老年代的可用內存小於該對象大小。
數據交換格式:json,xml,yaml