JAVA编程思想学习手账初整理
redis:
緩存擊穿:對于訪問過期的key查詢數據時,加鎖,保證只有一個線程去底層獲取數據,并返回結果緩存
緩存穿透:對于訪問不存在的key時給出空結果并緩存,或引入布隆過濾器將數據提前緩存在布隆過濾器中
緩存雪崩:對于key采用隨機過期時間,避免大量的key在同一時間失效導致數據庫承載過高
持久化機制:
AOF:以追加 命令行記錄的方式記錄完整的日志? 優點:能夠完整恢復數據? 缺點:恢復備份效率低
RDB:以二進制的方式定時本分數據? 優點:恢復備份效率高 缺點:存在備份時間臨界區有丟失數據的可能
AOF + RDB:定時備份數據以二進制的方式寫入文件,增量以命令行的記錄方式追加到文件當中
數據類型:
string : 字符串(操作命令:set get append setrange getrange strlen)
? ? ? ? ? ? ?數值(操作命令:incr)? ?理解待加深
? ? ? ? ? ? ?bitmap?
list:? ? ? ?理解待加深
hash:? ?理解待加深
set:? ? ??理解待加深
sorted_set? ?理解待加深
?
并發編程:
synchronized (悲觀鎖,非公平鎖 ) 與 lock(reetrantLock,readwriteLock)(非公平鎖、樂觀鎖)
synchronized:1.6之前為重型鎖:線程獲取不到鎖會直接進入(鎖池)隊列等待直到上一個線程釋放鎖之后才可以爭取鎖
? ? ? ? ? ? ? ? ? ? ? ? 1.6之后引入了鎖升級概念:JAVA對象頭部(MarkWord)包含鎖的信息,鎖升級狀態由無鎖到第一次加鎖升級為偏向鎖,第二次加鎖發生鎖競爭則升級為輕量級鎖,輕量級鎖通過CAS自旋嘗試獲取鎖,如仍然獲取不到鎖則升級為重量級鎖進入鎖池等待即1.6之前的方式
reetrantLock:底層采用CAS+AQS方式實現的鎖機制,當一個線程想要獲取鎖先通過CAS自旋方式嘗試獲取鎖;如獲取不到則將當前線程封裝為Node對象并存入AQS雙向隊列中,
? ? ? ? ? ? ? ? ? ? ? ? ? 1:AQS雙向隊列中已有線程在等待則將當前線程掛接在已有線程后面并將指針互相連接上,且掛接成功后會將上一個Node節點的狀態(waitStatus)更新為-1表示上一個Node節點后面掛接的Node節點可被喚醒,處于AQS隊列的頭部Node節點會通過CAS方式嘗試獲取鎖資源
? ? ? ? ? ? ? ? ? ? ? ? ? 2:AQS雙向隊列中沒有線程在等待,則會創建一個虛擬的頭部節點(head)并將當前Node節點掛接在虛擬節點之后,且將虛擬頭部節點(head)的狀態(waitStatus)設置為-1,以便更高效率的喚醒后面的線程節點
readwriteLock:讀讀不互斥,讀寫互斥,寫寫互斥;與reetranLock的區別在于更在細化的對鎖的顆粒度做了區別,以適用讀、寫的不同場景下的效率提升
concurrentHashMap:多線程并發的線程安全集合類;采用數組+單向鏈接+紅黑樹的數據結構?,當數組長度大于64(實則為了優化效率,數組的查詢時間復雜度為O(1))且單向鏈表長度大于8(優化效率,單向鏈接的查詢時間復雜度為O(n))時單向鏈接將轉化成紅黑樹結構(時間復雜度Ologn)
CAS:比較并交換;程序運行時會先從內存中獲取數據到CPU進行計算,再將計算完的結果寫入到內存
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1:如果多個線程同一時間從內存中獲取同一份的數據進行計算則會引發數據不一致性的問題(其他線程不能及時拿到某一線程計算完寫入的內存中的數據)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2:因此CAS的方式就是數據在CPU計算完之后寫入到內存時,會比較此時內存中的值與當前CPU中獲取的值是否一致,如一致則認為沒有其它的線程修改過值正常寫入,反之就認為值被其它線程篡改過則寫入失敗,再次通過CAS自旋方式直到寫入成功為止
?Executors創建線程池的幾種方式:
? newFixedThreadPool:固定線程數的線程池,當添加的線程數超過定義的線程數時則進入阻塞隊列(LinkedBlockingQueue),遵循FIFO(先進先出)原則等待線程池中有空閑的線程數時再 進行工作
? newScheduledThreadPool:固定線程數的定時任務線程池,底層采用延遲隊列(DelayedWorkQueue),可按固定的周期或者延遲多久的時間執行任務
newCachedThreadPool:創建存活時間為60秒的線程池,當前第一次有任務進來會直接創建新線程,如60秒內再次有任務進入會復用已創建的存活線程執行任務,如60秒內無任務進入則會結束當前線程池。如60秒外有任務進入則會創建新的線程執行;因為任務只要提交線程池中,就必然會有線程處理
newSingleThreadExecutor:單例線程池,線程池中只有一個線程在工作,后續進來的任務會進入到阻塞對列中等待,遵循FIFO(先進先出)原則,因此單例線程池適合按順序執行的一系列任務
?newWorkStealingPool:并行計算底層使用ForkJoinPool;核心思想分而治之,線程竊取;使用場景,將一個大的任務按照一定的規則拆分(需手動編寫拆分邏輯)?并放到當前線程的阻塞隊列當中,其它的空閑線程可以去處理有任務的線程的阻塞列隊中的任務?,優點:線程池中空閑線程可以被充分利用? ? ? ? ? ? ? ? ? ? ?
線程數計算:
核心線程數=cpu核數 * cpu利用率 * (1 + w/c)=cpu核數 * (1-阻塞系數)
分布式
CAP:Consistency(一致性)? ?Availability(可用性)? ? Partition Tolerance(分區容錯性)
微服務規定原則:CP?/??AP? ?三選二挑一?
C:保證微服務之間的數據強一致性,如zookeeper 發送消息必須等待其它節點都有反饋結果才可成功
A:保證微服務之間的可用,如某個節點掉線(需返回錯誤響應結果)但其他節點可正常使用則不影響整體的服務調用流程
P:保證由于網絡故障原因(網絡不可靠運行)引起的服務波動不影響整體的系統運行,分布式系統的基石
nacos:阿里開源的微服務注冊中心
服務注冊:微服務調用注冊中心客服端服務發送微服務實例信息完成注冊
服務心跳:客戶端會以默認5秒的頻率向服務端發送心跳,告知注冊中心當前服務的健康狀態
服務健康檢查:服務端啟用定時任務默認每15秒檢查一次注冊服務列表的健康狀態如超過25秒未響應則將服務置不健康狀態并下線
服務發現:注冊中心的服務能被其它服務檢測到且可調用
服務同步:CP
Mysql
b+tree:矮胖形的樹狀結構;
? ? ? ? ? ? ? 1:非子葉節點存儲子葉節點的分區指針信息不存儲數據
? ? ? ? ? ? ? 2:子葉節點存儲主鍵信息(如有主鍵存儲主鍵列信息,否則存儲唯一索引列信息,兩者都未生成則會存儲生成隱式的rowid)
? 聯合索引:多列組合創建的索引;
? ? ? ? ? ? ? ?1:最左前綴原則:where 條件中必須包第一列的字段才會生效且需正確命中索引? ?
? ? ? ? ? ? ? ?2:原理:多列聯合索引先按第一列構建b+tree結構,第二列基于第一列再構建b+tree索引以此類推,因此第一列未命中索引,第二例自然不會命中索引
? ? ? ? ? ? ? ?3:回表查詢:對于普通索引(二級索引,非聚簇索引),構建b+tree不會存儲該列數據,而是存儲主鍵對應的指針引用,所以普通索引查詢時先從主鍵索引中找到對應的主鍵再根據主鍵查詢返回完整數據? ? 待加深理解
?InnoDB行級鎖:只有當檢索條件中包含索引才使用行鎖,否則使用表鎖
?ACID:Atomicity(原子性),Consistency(一致性),Isolation(隔離性),持久性(durability)
?原子性:事務具有不可分割的性,一個事務被視為不可分割最小單元,在事務中的操作要么全部成功,要么全部失敗。意思就是不能只執行事務中的一部分。
一致性: 事務將數據由一種一致性的狀態轉換到另一種一致性的狀態,保證了事務開始之前和結束后的數據完整性
隔離性:一個事務的執行不能被其它的干擾,即一個事務內部中操作及使用的數據對其它事務是隔離的,并發執行的各個事務之間不能互相干擾
持久性:一旦事務提交,事務中操作修改的數據會永久的保存到數據庫中,此時即使系統崩潰已提交的數據已不會丟失
?事務隔離級別:臟讀,幻讀,不可重復讀;理論上事務的隔離性可以保證事務之前的操作互不干擾,多個事務操作同一份數據必須等待上一個事務結束才可,這樣就成了串行,但效率極低。因此需要舍棄事務原本的隔離性,由此出現了事務隔離級別的概念
臟讀:一個事務讀到了另一個事務的已修改但未提交的數據
幻讀:一個事務執行中,另一個事務將新紀錄添加到了正在讀取的事務中
不可重復度:當事務內相同的記錄被檢索兩次,且兩次的檢索結果不一樣
? ? ? ? ? ? ? ? ? ??
JVM
內存結構(運行時數據區):堆(Heap),方法區(Method area),棧(本地方法棧(Native Method Stacks),虛擬機方法棧(Java? Virtual Machine Stacks)),程序計數器(The pc Register)
堆:java虛擬機所管理的內存中最大的一塊;在虛擬機啟動時創建,被所有線程共享,java對象實例及數組都在堆上分配
方法區:Java虛擬機規范把方法區描述為堆的一個邏輯部分,別名Non-Heap,目的是與java堆區分開來,在java虛擬機啟動時創建,被所有線程共享;用于存儲已被虛擬機加載的類信息,常量,靜態變量,即時編譯后的代碼等數據;當方法區無法滿足內存要求時拋出OutOfMemoryError異常
虛擬機棧:是一個線程執行的區域,保存著一個線程中方法的調用狀態;
? ? ? ? ? ? ? 1:一個JAVA線程的運行狀態由一個虛擬機棧保存,所以虛擬機棧是線程私有的,隨著線程的創建而創建
? ? ? ? ? ? ? 2:每一個被線程執行的方法為該棧中的棧幀,即每個方法對應一個棧幀;調用一個方法就會向棧中壓入一個棧幀,一個方法調用完成,就會把該棧幀從棧中彈出(FILO先壓入的棧幀后彈出)
程序計數器:線程的執行權由CPU時間分片輪換調度,當一個線程執行過程中失去了執行權時由程序計數器記錄當前線程執行的位置,待線程再次獲得執行權時由程序計數器記錄的位置處開始執行
? ? ? ? ? ? ? ?1:如果線程正在執行的是JAVA方法,則計數器記錄的是正在執行的虛擬機字節碼指令的地址
? ? ? ? ? ? ? ?2:如果線程正在執行的是native方法,則這個計數器為空
本地方法棧:如果線程執行的是native方法,這些方法就會在本地方法棧中執行;如果在JAVA方法中調用native方法,則以動態鏈接的方式執行調用
內存結構(概念):老年代(old),新生代(Eden,survive0,survice1)
垃圾回收(GC):
? ? Eden:1:在JAVA對象的頭部(markWord)中會存儲當前的對象GC次數,當一個對象GC次數大于18時會將此對象從新生代轉移到老年代
? ? ? ? ? ? ? ? 2:當有較大的對象進入Eden區時,首先會將Eden存在的不連續空間的對象轉移到survive0區;當survive0區中的對象總內存超過survive0區的一半時,將survive0區中對象復制到survive1區中以便在survive0區中空出連續的完整空間
? ? ? ? ? ??? ? 3:當占有超過Eden區內存一半的對象時,會直接存放到老年代
? 什么時候會進行垃圾回收:
? ? ? ? ? ? ? ? ?1:當Eden區或S區內存不夠用了
? ? ? ? ? ? ? ? ?2:老年代空間不夠用了
? ? ? ? ? ? ? ? ?3:方法區空間不夠用了
? ? ? ? ? ? ? ? 4:System.gc()
垃圾回收算法:標記-清除,標記復制
? ?可達性分析算法:通過GC Root對象(能作為GC Root:類加載器,Thread,虛擬機棧的本地變量表,static成員,常量引用,本地方法棧的變量等)開始向下尋找,看某個對象是否可達,不可達的對象標記回收
標記-清除(Mark? Sweep)
? ? 標記:找出內存中需要回收的對象,并且把它們標記出來。此時堆中的所有對象都要被掃描一遍,才能確定需要被回收的對象,比較耗時。
? ? 清除: 清除掉被標記需要回收的對象,釋放出對應的內存空間。
? ? 缺點:? 標記清除之后會產生大量不連續的內存碎片,空間碎片太多可能會導致以后在程序運行過程中需要分配較大對象時,無法找到足夠的連續內存而不得不提前觸發另一次垃圾收集動作。
標記-復制(Mark Copying)
? ? ? 將內存劃分為兩塊相等的區域,每次只使用其中一塊,當其中一塊使用完了,就將還存活的對象復制到另外一塊內存上,然后把已使用過的內存空間一次清除掉。
? ? ?缺點:空間利用率降低
標記-整理(Mark Compact)
? ? ?標記過程與“標記清除算法”一致,但后續步驟不是直接對可回收對象進行清理,而是讓存活對象都向一端移動,然后直接清理掉端邊界以外的內存。 相較于“標記復制算法”來說少了一個“保留區”。
?Young區:復制算法(對象在被分配之后,可能生命周期比較短,Young區復制率較高)
?Old區:標記清除或整理(Old區對象存活時間比較長,復制來復制去沒有必要,不如做個標記再整理)
?垃圾收集器分類:
? ? ? ? 串行收集器:Serial、Serial Old
? ? ? ? 只能有一個垃圾回收線程執行,用戶線程暫停;適用于內存比較小的嵌入式設備
? ? ? ? 并行收集器(吞吐量優先):Parallel Scanvenge、 Parallel Old
? ? ? ? ?多條垃圾回收線程并行工作,但此時用戶線程仍然處理等待狀態;適用于科學計算,后臺處理等交互場景
? ? ? ? 并發收集器(停頓時間優先):CMS、G!
? ? ? ? 用戶線程和垃圾收集線程同時執行(可能是交替執行),垃圾收集線程在執行的時候不會停頓用戶線程的運行;適用于相對時間有要求的場景,比如Web
JVM查看參數
java -XX:+PrintFlagsFinal -version > flags.txt
常用參數含義
?
總結
以上是生活随笔為你收集整理的JAVA编程思想学习手账初整理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电商零售业怎么做数据分析?这10篇作品看
- 下一篇: 阿里云短信验证码签名模板创建方法