目錄??
- 一.MySQL
- 1.執行一條SQL的過程
- (A)連接器
- (B)緩存
- (C)分析器
- (D)優化器
- (E)執行器
- 2.MySQL引擎的區別
- (A)MyISAM:不支持事務 操作表數據鎖表
- (B)InnoDB: 支持事務 操作表數據鎖行
- 3.數據庫優化思路
- (A)SQL語句優化
- (B)索引優化
- (C)數據庫結構優化
- (D)服務器硬件優化
- 1.執行一條SQL的過程
- 二.JVM
- Java類的加載過程
- (A)加載(將class文件轉換成class實例)
- (B)驗證 (驗證類數據信息是否符合JVM規范)
- (a)格式檢查:魔數驗證,版本檢查,長度檢查
- (b)語義檢查:是否繼承final,是否有父類,是否實現抽象方法
- (c)字節碼驗證:跳轉指令是否指向正確的位置,操作數類型是否合理
- (d)符號引用驗證:符號引用的直接引用是否存在
- (C)準備 (分配靜態變量的內存空間)
- (D)解析(將常量池中的符號引用轉為直接引用)
- (E)初始化 (加載start塊和給start變量賦值)
- Java類的加載過程
- Java運行時數據區結構
- (A)PC寄存器/程序計數器(每個線程有一個獨立的程序計數器,且互不影響,獨立儲存)
- (a)保存當前正在執行的程序的內存地址。
- (B)Java棧 Java Stack(每條線程對應一個棧,一個棧中對應多個棧幀,執行一個方法壓入一個棧幀,結束一個方法出一個棧幀)
- (a)棧幀是每個方法關聯起來的,每運行一個方法就創建一個棧幀,每個棧幀會含有一些局部變量,每當一個方法執行完成時,該棧幀就會彈出這個棧幀的元素作為這個方法的返回值,并清除這個棧幀。
- (b)Java棧頂的棧幀就是當前執行的活動棧,也就是正在執行的方法,
PC寄存器會指向該地址
。 - (c)棧幀的結構:
局部變量表,操作數棧,動態連接方法,返回的地址
- (C)堆 Heap(堆時JVM所管理的內存中最大的一塊,被所有的Java線程鎖共享,不是線程安全的,在JVM啟動時創建)
- (a)所有對象實例以及數組都要在堆上分配。
- (b)Java堆時GC管理的主要區域,現在GC基本都采用
分代收集算法
,所有堆還可以細分為:新生代和老年代
新生代再細致一點有Eden空間,From Survivor空間,To Survivor空間
等。
- (D)方法區Method Area(方法區存放了要加載類的信息(名稱,修飾符等)類中定義為靜態常量,類中的Field信息,類中的方法信息,
方法區是被Java線程共享的
)- (a)方法區數據雖然時被線程共享,但是不會像Java堆一樣被GC頻繁回收,它儲存的信息相對比較穩定,再一定條件下會被GC
- (E)常量池Constant Pool(
常量池本身是方法區的一個數據結構。
)- (a)常量池中儲存了如字符串,final變量值,類名和方法名變量值。常量池在編譯期間就被確定,并保存在已編譯的。class文件中。
- (F)本地方法棧Native Method Stack(本地方法棧和Java棧所發揮的作用非常相似,區別不過是Java棧為JVM執行Java方法服務,而本地方法棧為JVM執行Native方法服務。本地方法棧也會拋出StackOverflowError和OutOfMemoryError異常。)
- (A)PC寄存器/程序計數器(每個線程有一個獨立的程序計數器,且互不影響,獨立儲存)
- JMM
- 三.Hadoop
- 1.區分hdfs hbase hive 區別以及應用場景
- 四.Redis
- 五.MQ
- 六.微服務
??MySql
一,執行一條SQL的過程
1.連接器和客戶端建立連接
- 驗證賬號密碼 -> 賬號不對,報錯:“Access denied for user”
- 認證通過,在權限表中查詢擁有的權限
1.在連接過程才會從權限表中讀取權限信息,中途對權限更新不會影響已經建立的連接
2.若規定時間內無活動,則自動會斷開連接。規定時間由wait_timeout
控制,默認為8個小時
優化:防止數據庫中出現占用大量內存的情況,可以用:
1.定期斷開長連接或者占用內存過大的連接。
2.MySQL5.7以上的版本,每次執行一個較大的操作,可執行mysql_reset_connection
命令來初始化連接資源,該操作不會重連和重新獲取授權,只是恢復到剛建立連接的狀態。
2. 查詢緩存(MySQL8.0后將刪除該功能)
- 之前執行的過的語句,會以語句為Key,執行后的結果集為Value儲存在內存中。
- 如果緩存命中,則直接返回結果
- 如果緩存沒有命中,則繼續執行,并且將語句和結果集以key-value的形式存于內存。
1.只要更新表,將會把該表緩存全部清空(緩存適用于不常更新的靜態表)
優化:
1.設置默認為不適用緩存,只針對不常用的靜態表指定使用緩存(將query_cache_type 設置為 DEMAND,默認SQL不使用查詢緩存)
select SQL_CACHE * from T where ID = 10;
3.分析器
- 1.詞法分析
識別SQL關鍵字,提出主要成分。MySQL根據select
得出這是一條查詢語句,根據from T
識別表,將ID
識別為列名。 - 2.語法分析
根據語法規則判斷是否符合SQL的語法。如果出現錯誤,則提示:You have an error in your SQL syntax...
后面是錯誤的地方,需要你關注use naer
后的內容。
4.優化器
- 選取最優的執行方式:
1.當涉及到多個索引時,決定用哪個索引
2.多表關聯時,決定連接順序
select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
該步驟決定了先從t1表中取出`c=10`的ID值還是先查找出t2表中`d=20`的ID值。
5.執行器
- 1.根據連接器取到權限,判斷該用戶是否對T表有權限。
- 2.若有權限,繼續打開表繼續操作。
打開表后,根據表的引擎定義,使用提供的接口解析數據:- 表T中ID字段無索引:
1. 調用InnoDB提供的接口,取出第一行,ID=10
時,將該行數據放入結果集。不符合則再次調用引擎接口獲取下一行,再次判斷,直到執行完最后一行。
2. 將結果集存入緩存,返回給客戶端。 - 表T中的ID字段有索引:
1. 調用InnoDB的索引方法獲取滿足條件的第一行
接口,server層還會再判斷一次值是否正確,然后放入結果集,接著繼續訪問滿足條件的下一行
接口,這些結構時引擎已經定義好的。其原理是使用B+tree。
- 表T中ID字段無索引:
問題:
- 如果在查詢語句中的字段不存在,會在哪個階段報錯?
分析器階段。 - MySQL中解析器和預處理器有什么作用?
解析器:處理語法啊和解析查詢,生成一顆對應的解析樹。
預處理器:進一步檢查解析樹的合法性,比如:數據表和數據列是否存在,別名是否有歧義等。如果通過則生成新的解析樹,再提交給優化器。 - Connect_timeout和wait_timeout是指什么?
Connect_timeout :連接過程中的等待時間。
wait_timeout:連接完成后,使用過程中的等待時間。
二,MySQL引擎的區別
MySQL有四種引擎:ISAM , MyISAM,HEAP,InnoDB
ISAM :ISAM執行讀取操作的速度很快,不支持事務處理,也不能夠容錯。
MyISAM:MyISAM是MySQL的ISAM擴展格式和缺省的數據庫引擎。
HEAP:HEAP允許只駐留在內存里的臨時表格。駐留在內存里讓HEAP要比ISAM和MYISAM都快。
InnoDB:支持事務等高級操作。
- MySQL5.1之前默認引擎是MyISAM,MySQL5.1之后默認引擎改為InnoDB
InnoDB支持事務并且更新數據是行鎖,MyISAM不支持事務更新數據是表鎖
MyISAM數據文件比InnoDB多出一種索引文件,MyISAM比InnoDB的查詢速度塊很多。
三,數據庫優化思路
1.SQL語句優化:
- 盡量避免放棄使用索引而引起全表掃描,例如:
- where子句中使用!=
- where子句中使用<>
- where子句中改變=號左邊的值
- where子句中對字段進行null值判斷 is null
select id from user where num is null
- 優化建議:
- 將為null的值由0代替
select id from user where num = 0
- 很多時候使用exists代替in是一個好的選擇
- 用where子句替換having子句因為having只會在檢索出所有記錄之后才會對結果集進行過濾
- 將為null的值由0代替
2.索引優化
- 在具有這些性質的字段上建立索引:
- 經常搜索(可以加快搜索速度)
- 作為主鍵的列,強制該列的唯一性和組織表中的排序結構
- 在經常用于連接的列上(外鍵,可以加快連接速度)
- 在經常需要根據范圍進行搜索的列上(索引以及排序,指定范圍是連續的)
- 在經常需要排序的字段
- 在經常使用where的列上(加快條件的判斷速度)
- 不應該建立索引列的特征:
- 查詢中很少使用或者參考的列
- 數據值很少的列,例如:性別
- 類型定義為text,image和bit數據類型的列
- 修改遠遠大于檢索的列
3.數據庫結構優化
- 范式優化:
- 消除沉余(節省空間)
- 反范式優化:
- 適當加沉余(減少join)
- 拆分表:
- 分區將在物理硬盤上分割開,不同分區的數據可以制定保存在處于不同磁盤的數據文件里。當對這個表查詢時,只需要在表分區中進行掃描,而不必進行全表掃描,另外處于不同磁盤的分區也將對這個表的數據傳輸分散在不同的磁盤I/O,一個良好的分區可以將數據傳輸對磁盤I/O競爭均勻地分散開。對數據量大的時候可采用此方法。
- 例:1.產品表(數據量10萬,穩定),2.訂單表(數據量200萬,且有增長趨勢)3.用戶表(數據量100萬,且有增長趨勢)
- 垂直拆分
- 方案:吧產品表和用戶表放在一個server上訂單表單獨放到一個server上
- 解決問題:表于表之間的io競爭
- 不解決的問題:單表中數據量增加出現的壓力
- 水平拆分
- 方案:用戶表通過性別拆分男用戶和女用戶,訂單表通過已完成訂單和未完成訂單拆分,將未完成數據單獨放在一個server上,已完成訂單和男用戶放在一個server上
- 解決問題:單表中數據量增加出現的壓力
- 不解決的問題:表與表之間的io爭奪
4.服務器硬件的優化
- 花錢擴展服務器性能,搭建集群等等
??JVM
Java類的加載過程
- 類從被加載到JVM中開始,到卸載為止,整個生命周期包括:
加載
、驗證
、準備
、解析
、初始化
、使用
和卸載
七個階段。 - 其中類加載過程包括
加載
、驗證
、準備
、解析
和初始化
五個階段。
加載(將Class文件轉換成Class對象實例)
- 1.類加載器根據一個類的全限定名來讀取此類的二進制字節流到JVM中,然后轉換為一個與類目標對應的java.lang.Class對象實例。
- ①BootstrapClassLoader:負責加載$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++實現,不是ClassLoader子類。
- ②ExtClassLoader:負責加載java平臺中擴展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目錄下的jar包。
- ③AppClassLoader:負責加載ClassPath中指定的jar包及目錄中的class
- ④CustomClassLoader:屬于應用程序根據自身需要自定義的ClassLoader,如tomcat,Jboss都會根據j2ee規范自行實現ClassLoader。
- defineClass方法將字節碼的byte數組轉換為一個類的class對象實例,如果希望在類被加載到JVM時就被鏈接,可以在自定義類加載器中調用resolve'Class方法。
-
自定義類加載器需要繼承抽象類ClassLoader,實現findClass方法,該方法會在lodClass調用的時候被調用,findClass默認會拋出異常。
- findClass:表示根據類名查找類對象。
- loadClass:表示根據類名進行雙親委派模型進行類加載并返回類對象。
- defineClass:表示根據類的字節碼轉換為類對象。
-
自定義類加載器需要繼承抽象類ClassLoader,實現findClass方法,該方法會在lodClass調用的時候被調用,findClass默認會拋出異常。
驗證(驗證數信息是否符合JVM規范,是否是一個有效的字節碼文件)
- 驗證內容:
類數據信息的格式驗證,語義分析,操作驗證
等。- 格式驗證:
驗證是否符合class文件規范
- 語義驗證:
檢查一個被標記為final的類型是否包含子類;檢查一個類中的final方法視頻被子類進行重寫;確保父類和子類之間沒有不兼容的一些方法聲明(比如方法簽名相同,但方法的返回值不同)
- 操作驗證:
在操作數棧中的數據必須進行正確的操作,對常量池中的各種符號引用執行驗證(通常在解析階段執行,檢查是否通過富豪引用中描述的全局定名定位到指定類型上,以及類成員信息的訪問修飾符)
- 格式驗證:
準備(為類追蹤的所有靜態變量分配內存空間,并為其設置一個初始值(由于還沒產生對象,實例變量不在此操作范圍內))
- 被final修飾的靜態變量,會直接賦予原值。
- 類字段的字段屬性表中存在ConstantValue屬性,則在準備階段,其值就是ConstantValue的值。
解析(將常量池中的符號引用轉為直接引用(得到類或者字段,方法在內存中的指針或者偏移量,一遍直接調用該方法,這個可以在初始化之后再執行))
- 可以認為是一些靜態綁定的會被解析,動態綁定則只會在運行時進行解析。
- 靜態綁定包括一些final方法(不可重寫),static方法(只屬于當前類),構造器(不會被重寫)
初始化(將一個類中所有被static關鍵字表示得代碼統一執行一遍)
- 如果執行得是靜態變量,那么就會使用用戶指定得值覆蓋之前在準備階段設置得初始值
- 如果執行得是static代碼塊,那么在初始化階段,JVM就會執行static代碼塊中定義的所有操作。
- 所有類變量初始化語句和靜態代碼塊都會在編譯時被前端編譯器放在收集器里頭,存放到一個特殊的方法中,這個方法就是<clinit>方法,即類/接口初始化方法。該方法的作用就是初始化一個中的變量,使用用戶指定的值覆蓋之前在準備階段里設定的初始值,任何invoke之類的字節碼都無法調用<clinit>方法,由JVM負責保證一個類的<clinit>方法執行之前,它的父類<clinit>方法已經被執行。
- JVM必須確保一個類在初始化的過程中,如果多線程需要同時初始化它,僅僅只能允許其中一個線程對其執行操作,其余線程必須等待,只有在活動線程執行完對類的初始化操作之后,菜會通知正在等待的其他線程。
Java運行時數據區結構
- (A)PC寄存器/程序計數器(每個線程有一個獨立的程序計數器,且互不影響,獨立儲存)
- (a)保存當前正在執行的程序的內存地址。
- (B)Java棧 Java Stack(每條線程對應一個棧,一個棧中對應多個棧幀,執行一個方法壓入一個棧幀,結束一個方法出一個棧幀)
- 
- (a)棧幀是每個方法關聯起來的,每運行一個方法就創建一個棧幀,每個棧幀會含有一些局部變量,每當一個方法執行完成時,該棧幀就會彈出這個棧幀的元素作為這個方法的返回值,并清除這個棧幀。
- (b)Java棧頂的棧幀就是當前執行的活動棧,也就是正在執行的方法,`PC寄存器會指向該地址`。
- (c)棧幀的結構:`局部變量表,操作數棧,動態連接方法,返回的地址`
- (C)堆 Heap(堆時JVM所管理的內存中最大的一塊,被所有的Java線程鎖共享,不是線程安全的,在JVM啟動時創建)
- (a)所有對象實例以及數組都要在堆上分配。
- (b)Java堆時GC管理的主要區域,現在GC基本都采用`分代收集算法`,所有堆還可以細分為:`新生代和老年代`新生代再細致一點有`Eden空間,From Survivor空間,To Survivor空間`等。
- (D)方法區Method Area(方法區存放了要加載類的信息(名稱,修飾符等)類中定義為靜態常量,類中的Field信息,類中的方法信息,`方法區是被Java線程共享的`)
- (a)方法區數據雖然時被線程共享,但是不會像Java堆一樣被GC頻繁回收,它儲存的信息相對比較穩定,再一定條件下會被GC
- (E)常量池Constant Pool(`常量池本身是方法區的一個數據結構。`)
- (a)常量池中儲存了如字符串,final變量值,類名和方法名變量值。常量池在編譯期間就被確定,并保存在已編譯的。class文件中。
- (F)本地方法棧Native Method Stack(本地方法棧和Java棧所發揮的作用非常相似,區別不過是Java棧為JVM執行Java方法服務,而本地方法棧為JVM執行Native方法服務。本地方法棧也會拋出StackOverflowError和OutOfMemoryError異常。)
??Hadoop
區分hdfs hbase hive 區別以及應用場景
Hive
Hive在Hadoop中扮演數據倉庫的角色。建立在Hadoop集群的最頂層,對存儲在Hadoop群上的數據提供類SQL的接口進行操作。你可以用HiveQL進行selelct,join等等操作。
特點:支持SQL查詢
注意:Hive現在適合再離線下進行數據操作,不使用于在線查詢,因為一個字“慢”
適用場景:不想用程序語言開發MapReduce的朋友們,熟悉SQL的朋友可以使用Hive開離線進行數據處理分析工作。如果你有數據倉庫的需求并且你擅長寫SQL并且不想寫MapReduce jobs就可以用Hive代替。
HBase
HBase是一個數據庫,一個NoSql數據庫,像其他數據庫一樣提供隨即讀寫功能,Hadoop不能滿足于實時需要,HBase正可以滿足。
特點:即時讀寫
適用場景:需要實時訪問一些數據,就可以把它存入HBase,你也可以用Hadoop作為靜態數據倉庫,HBase作為數據存儲,放那些進行一些操作會改變的數據。
問題:
什么情況下應用HBase?
- 1.成熟的數據分析主題,查詢模式已經確立,并且不會輕易改變。
- 2.傳統的關系型數據庫已經無法承受負荷,高速插入,大量存取。
- 3.適合海量的,但同時也是簡單的操作(例如 key-value)。
官方解釋
Use Apache HBase? when you need random, realtime read/write access to your Big Data. This project's goal is the hosting of very large tables -- billions of rows X millions of columns -- atop clusters of commodity hardware. Apache HBase is an open-source, distributed, versioned, non-relational database modeled after Google's Bigtable: A Distributed Storage System for Structured Data by Chang et al. Just as Bigtable leverages the distributed data storage provided by the Google File System, Apache HBase provides Bigtable-like capabilities on top of Hadoop and HDFS.
Pig VS Hive
Hive更適合于數據倉庫的任務,Hive主要用于靜態的結構以及需要經常分析的工作,Hive于SQL相似促使其成為Hadoop與其他BI工具結合的理想交集。
Pig賦予開發人員在大數據集領域更多的靈活性,并允許開發簡介的腳本用于轉換數據流以便潛入到較大的應用程序。
Pig相比Hive輕量,它主要的優勢時相比于直接使用Hadoop Java APIs可大幅削減代碼量。正因如此,Pig仍然是吸引大量的軟件開發人員。
Hive和Pig都可以與HBase組合使用,Hive和Pig還為HBase提供了高層語言支持,使得在HBase上進行數據統計處理變的非常簡單。
Hive VS HBase
Hive 是建立在Hadoop之上為了減少MapReduce jobs編寫工作的批處理程序,HBases是為了支持彌補Hadoop對實時操作的缺陷彌補的項目。
想象你在操作RMDB數據庫,如果是全表掃描,就用Hive+Hadoop,如果索引訪問,就用HBase+Hadoop。
Hive query就是MapReduce jobs 可以從5分鐘到數小時不止,HBase是非常高效的,肯定比Hive高效的多。
JDBC
未完待續~
文中有錯誤希望大家在評論區指出,謝謝~~~~~~~~~