十7、MySqljava
164.數據庫的三範式是什麼?node
第一範式要求確保表中每列的原子性,也就是不可拆分;第二範式要求確保表中每列與主鍵相關,而不能只與主鍵的某部分相關(主要針對聯合主鍵),主鍵列與非主鍵列遵循徹底函數依賴關係,也就是徹底依賴;第三範式確保主鍵列之間沒有傳遞函數依賴關係,也就是消除傳遞依賴。mysql
165.一張自增表裏面總共有 7 條數據,刪除了最後 2 條數據,重啓 mysql 數據庫,又插入了一條數據,此時 id 是幾?nginx
默認表類型InnoDB,新增一條記錄(不重啓),記錄id是8;重啓的話,id爲6;若是表類型是MyISAM,無論是否重啓,記錄ID都爲8web
166.如何獲取當前數據庫版本?redis
SELECT VERSION()算法
167.說一下 ACID 是什麼?sql
一、Atomicity原子性,指整個事務是一個獨立的單元,是不可分割的工做單元;二、Consistency一致性,指數據庫事務不能破壞關係數據的完整性以及業務邏輯上的一致性。三、Isolation隔離性,指在併發環境中,當不一樣事務同時操做相同數據時,每一個事務都有各自的完整數據空間;四、Durability持久性,指事務成功結束,數據庫所作的更新就必須是永久保存下來。即便發生系統崩潰,重啓數據庫系統,還能恢復到事務成功結束的狀態。數據庫
168.char 和 varchar 的區別是什麼?緩存
char:定長,效率高,通常用於固定長度的表單提交數據存儲(沒達到定義的位數,空格補全,取數據時,後面的空格丟棄掉);varchar:不定長,效率偏低;
169.float 和 double 的區別是什麼?
double精度高,有效數字16位,float精度7位,double消耗內存是float兩倍,運算速度比float慢得多
170.mysql 的內鏈接、左鏈接、右鏈接有什麼區別?
內鏈接:顯示兩個表中有聯繫的全部數據;左鏈接:以左表爲參照,顯示全部數據;右鏈接:以右表爲參照顯示全部數據
171.mysql 索引是怎麼實現的?
索引是知足某種特定查找算法的數據結構,而這些數據結構會以某種方式指向數據,從而實現高效查找數據。
具體來講 MySQL 中的索引,不一樣的數據引擎實現有所不一樣,但目前主流的數據庫引擎的索引都是 B+ 樹實現的,B+ 樹的搜索效率,能夠到達二分法的性能,找到數據區域以後就找到了完整的數據結構了,全部索引的性能也是更好的。
172.怎麼驗證 mysql 的索引是否知足需求?
使用 explain 查看 SQL 是如何執行查詢語句的,從而分析你的索引是否知足需求。
explain 語法:explain select * from table where type=1。
173.說一下數據庫的事務隔離?
MySQL 的事務隔離是在 MySQL. ini 配置文件裏添加的,在文件的最後添加:transaction-isolation = REPEATABLE-READ
可用的配置值:READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。
READ-UNCOMMITTED:未提交讀,最低隔離級別、事務未提交前,就可被其餘事務讀取(會出現幻讀、髒讀、不可重複讀)。
READ-COMMITTED:提交讀,一個事務提交後才能被其餘事務讀取到(會形成幻讀、不可重複讀)。
REPEATABLE-READ:可重複讀,默認級別,保證屢次讀取同一個數據時,其值都和事務開始時候的內容是一致,禁止讀取到別的事務未提交的數據(會形成幻讀)。
SERIALIZABLE:序列化,代價最高最可靠的隔離級別,該隔離級別能防止髒讀、不可重複讀、幻讀。
髒讀 :表示一個事務可以讀取另外一個事務中還未提交的數據。好比,某個事務嘗試插入記錄 A,此時該事務還未提交,而後另外一個事務嘗試讀取到了記錄 A。
不可重複讀 :是指在一個事務內,屢次讀同一數據。
幻讀 :指同一個事務內屢次查詢返回的結果集不同。好比同一個事務 A 第一次查詢時候有 n 條記錄,可是第二次同等條件下查詢卻有 n+1 條記錄,這就好像產生了幻覺。發生幻讀的緣由也是另一個事務新增或者刪除或者修改了第一個事務結果集裏面的數據,同一個記錄的數據內容被修改了,全部數據行的記錄就變多或者變少了。
174.說一下 mysql 經常使用的引擎?
InnoDB 引擎:InnoDB 引擎提供了對數據庫 acid 事務的支持,而且還提供了行級鎖和外鍵的約束,它的設計的目標就是處理大數據容量的數據庫系統。MySQL 運行的時候,InnoDB 會在內存中創建緩衝池,用於緩衝數據和索引。可是該引擎是不支持全文搜索,同時啓動也比較的慢,它是不會保存表的行數的,因此當進行 select count(*) from table 指令的時候,須要進行掃描全表。因爲鎖的粒度小,寫操做是不會鎖定全表的,因此在併發度較高的場景下使用會提高效率的。
MyIASM 引擎:MySQL 的默認引擎,但不提供事務的支持,也不支持行級鎖和外鍵。所以當執行插入和更新語句時,即執行寫操做的時候須要鎖定這個表,因此會致使效率會下降。不過和 InnoDB 不一樣的是,MyIASM 引擎是保存了表的行數,因而當進行 select count(*) from table 語句時,能夠直接的讀取已經保存的值而不須要進行掃描全表。因此,若是表的讀操做遠遠多於寫操做時,而且不須要事務的支持的,能夠將 MyIASM 做爲數據庫引擎的首選。
175.說一下 mysql 的行鎖和表鎖?
MyISAM 只支持表鎖,InnoDB 支持表鎖和行鎖,默認爲行鎖。
表級鎖:開銷小,加鎖快,不會出現死鎖。鎖定粒度大,發生鎖衝突的機率最高,併發量最低。
行級鎖:開銷大,加鎖慢,會出現死鎖。鎖力度小,發生鎖衝突的機率小,併發度最高。
176.說一下樂觀鎖和悲觀鎖?
樂觀鎖:每次去拿數據的時候都認爲別人不會修改,因此不會上鎖,可是在提交更新的時候會判斷一下在此期間別人有沒有去更新這個數據。
悲觀鎖:每次去拿數據的時候都認爲別人會修改,因此每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻止,直到這個鎖被釋放。
數據庫的樂觀鎖須要本身實現,在表裏面添加一個 version 字段,每次修改爲功值加 1,這樣每次修改的時候先對比一下,本身擁有的 version 和數據庫如今的 version 是否一致,若是不一致就不修改,這樣就實現了樂觀鎖。
177.mysql 問題排查都有哪些手段?
使用 show processlist 命令查看當前全部鏈接信息。
使用 explain 命令查詢 SQL 語句執行計劃。
開啓慢查詢日誌,查看慢查詢的 SQL。
178.如何作 mysql 的性能優化?
爲搜索字段建立索引。
避免使用 select *,列出須要查詢的字段。
垂直分割分表。
選擇正確的存儲引擎。
十8、Redis
179.redis 是什麼?都有哪些使用場景?
Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。
Redis 使用場景:
數據高併發的讀寫
海量數據的讀寫
對擴展性要求高的數據
180.redis 有哪些功能?
數據緩存功能
分佈式鎖的功能
支持數據持久化
支持事務
支持消息隊列
181.redis 和 memecache 有什麼區別?
memcached全部的值均是簡單的字符串,redis做爲其替代者,支持更爲豐富的數據類型
redis的速度比memcached快不少
redis能夠持久化其數據
182.redis 爲何是單線程的?
由於 cpu 不是 Redis 的瓶頸,Redis 的瓶頸最有多是機器內存或者網絡帶寬。既然單線程容易實現,並且 cpu 又不會成爲瓶頸,那就瓜熟蒂落地採用單線程的方案了。
關於 Redis 的性能,官方網站也有,普通筆記本輕鬆處理每秒幾十萬的請求。
並且單線程並不表明就慢 nginx 和 nodejs 也都是高性能單線程的表明。
183.什麼是緩存穿透?怎麼解決?
緩存穿透:指查詢一個必定不存在的數據,因爲緩存是不命中時須要從數據庫查詢,查不到數據則不寫入緩存,這將致使這個不存在的數據每次請求都要到數據庫去查詢,形成緩存穿透。
解決方案:最簡單粗暴的方法若是一個查詢返回的數據爲空(無論是數據不存在,仍是系統故障),咱們就把這個空結果進行緩存,但它的過時時間會很短,最長不超過五分鐘。
184.redis 支持的數據類型有哪些?
string、list、hash、set、zset。
185.redis 支持的 java 客戶端都有哪些?
Redisson、Jedis、lettuce等等,官方推薦使用Redisson。
186.jedis 和 redisson 有哪些區別?
Jedis是Redis的Java實現的客戶端,其API提供了比較全面的Redis命令的支持。
Redisson實現了分佈式和可擴展的Java數據結構,和Jedis相比,功能較爲簡單,不支持字符串操做,不支持排序、事務、管道、分區等Redis特性。Redisson的宗旨是促進使用者對Redis的關注分離,從而讓使用者可以將精力更集中地放在處理業務邏輯上。
187.怎麼保證緩存和數據庫數據的一致性?
合理設置緩存的過時時間。
新增、更改、刪除數據庫操做時同步更新 Redis,可使用事務機制來保證數據的一致性。
188.redis 持久化有幾種方式?
Redis 的持久化有兩種方式,或者說有兩種策略:
RDB(Redis Database):指定的時間間隔能對你的數據進行快照存儲。
AOF(Append Only File):每個收到的寫命令都經過write函數追加到文件中。
189.redis 怎麼實現分佈式鎖?
Redis 分佈式鎖其實就是在系統裏面佔一個「坑」,其餘程序也要佔「坑」的時候,佔用成功了就能夠繼續執行,失敗了就只能放棄或稍後重試。
佔坑通常使用 setnx(set if not exists)指令,只容許被一個程序佔有,使用完調用 del 釋放鎖。
190.redis 分佈式鎖有什麼缺陷?
Redis 分佈式鎖不能解決超時的問題,分佈式鎖有一個超時時間,程序的執行若是超出了鎖的超時時間就會出現問題。
191.redis 如何作內存優化?
儘量使用散列表(hashes),散列表(是說散列表裏面存儲的數少)使用的內存很是小,因此你應該儘量的將你的數據模型抽象到一個散列表裏面。
好比你的web系統中有一個用戶對象,不要爲這個用戶的名稱,姓氏,郵箱,密碼設置單獨的key,而是應該把這個用戶的全部信息存儲到一張散列表裏面。
192.redis 淘汰策略有哪些?
volatile-lru:從已設置過時時間的數據集(server. db[i]. expires)中挑選最近最少使用的數據淘汰。
volatile-ttl:從已設置過時時間的數據集(server. db[i]. expires)中挑選將要過時的數據淘汰。
volatile-random:從已設置過時時間的數據集(server. db[i]. expires)中任意選擇數據淘汰。
allkeys-lru:從數據集(server. db[i]. dict)中挑選最近最少使用的數據淘汰。
allkeys-random:從數據集(server. db[i]. dict)中任意選擇數據淘汰。
no-enviction(驅逐):禁止驅逐數據。
193.redis 常見的性能問題有哪些?該如何解決?
主服務器寫內存快照,會阻塞主線程的工做,當快照比較大時對性能影響是很是大的,會間斷性暫停服務,因此主服務器最好不要寫內存快照。
Redis 主從複製的性能問題,爲了主從複製的速度和鏈接的穩定性,主從庫最好在同一個局域網內。
十9、JVM
194.說一下 jvm 的主要組成部分?及其做用?
類加載器(ClassLoader)
運行時數據區(Runtime Data Area)
執行引擎(Execution Engine)
本地庫接口(Native Interface)
組件的做用: 首先經過類加載器(ClassLoader)會把 Java 代碼轉換成字節碼,運行時數據區(Runtime Data Area)再把字節碼加載到內存中,而字節碼文件只是 JVM 的一套指令集規範,並不能直接交個底層操做系統去執行,所以須要特定的命令解析器執行引擎(Execution Engine),將字節碼翻譯成底層系統指令,再交由 CPU 去執行,而這個過程當中須要調用其餘語言的本地庫接口(Native Interface)來實現整個程序的功能。
195.說一下 jvm 運行時數據區?
程序計數器、虛擬機棧、本地方法棧、堆、方法區
196.說一下堆棧的區別?
1. 棧內存存儲的是局部變量,而堆內存存儲的是實體;
2. 棧內存的更新速度要快於堆內存,由於局部變量的生命週期很短;
3. 棧內存存放的變量生命週期一旦結束就會被釋放,而堆內存存放的實體會被垃圾回收機制不定時的回收。
197.隊列和棧是什麼?有什麼區別?
隊列和棧都是被用來預存儲數據的。
隊列容許先進先出檢索元素,但也有例外的狀況,Deque 接口容許從兩端檢索元素。
棧和隊列很類似,但它運行對元素進行後進先出進行檢索。
198.什麼是雙親委派模型?
在介紹雙親委派模型以前先說下類加載器。對於任意一個類,都須要由加載它的類加載器和這個類自己一同確立在 JVM 中的惟一性,每個類加載器,都有一個獨立的類名稱空間。類加載器就是根據指定全限定名稱將 class 文件加載到 JVM 內存,而後再轉化爲 class 對象。 類加載器分類: 啓動類加載器(Bootstrap ClassLoader),是虛擬機自身的一部分,用來加載Java_HOME/lib/目錄中的,或者被 -Xbootclasspath 參數所指定的路徑中而且被虛擬機識別的類庫; 其餘類加載器: 擴展類加載器(Extension ClassLoader):負責加載<java_home >\lib\ext目錄或Java. ext. dirs系統變量指定的路徑中的全部類庫;</java_home> 應用程序類加載器(Application ClassLoader)。負責加載用戶類路徑(classpath)上的指定類庫,咱們能夠直接使用這個類加載器。通常狀況,若是咱們沒有自定義類加載器默認就是用這個加載器。 雙親委派模型:若是一個類加載器收到了類加載的請求,它首先不會本身去加載這個類,而是把這個請求委派給父類加載器去完成,每一層的類加載器都是如此,這樣全部的加載請求都會被傳送到頂層的啓動類加載器中,只有當父加載沒法完成加載請求(它的搜索範圍中沒找到所需的類)時,子加載器纔會嘗試去加載類。
199.說一下類加載的執行過程?
類加載分爲如下 5 個步驟: 加載:根據查找路徑找到相應的 class 文件而後導入; 檢查:檢查加載的 class 文件的正確性; 準備:給類中的靜態變量分配內存空間; 解析:虛擬機將常量池中的符號引用替換成直接引用的過程。符號引用就理解爲一個標示,而在直接引用直接指向內存中的地址; 初始化:對靜態變量和靜態代碼塊執行初始化工做。
200.怎麼判斷對象是否能夠被回收?
通常有兩種方法來判斷:
引用計數器:爲每一個對象建立一個引用計數,有對象引用時計數器 +1,引用被釋放時計數 -1,當計數器爲 0 時就能夠被回收。它有一個缺點不能解決循環引用的問題;
可達性分析:從 GC Roots 開始向下搜索,搜索所走過的路徑稱爲引用鏈。當一個對象到 GC Roots 沒有任何引用鏈相連時,則證實此對象是能夠被回收的。
201.java 中都有哪些引用類型?
強引用、軟引用、弱引用、虛引用(幽靈引用/幻影引用)
202.說一下 jvm 有哪些垃圾回收算法?
標記-清除算法、標記-整理算法、複製算法、分代算法
203.說一下 jvm 有哪些垃圾回收器?
Serial:最先的單線程串行垃圾回收器。 Serial Old:Serial 垃圾回收器的老年版本,一樣也是單線程的,能夠做爲 CMS 垃圾回收器的備選預案。 ParNew:是 Serial 的多線程版本。 Parallel 和 ParNew 收集器相似是多線程的,但 Parallel 是吞吐量優先的收集器,能夠犧牲等待時間換取系統的吞吐量。 Parallel Old 是 Parallel 老生代版本,Parallel 使用的是複製的內存回收算法,Parallel Old 使用的是標記-整理的內存回收算法。 CMS:一種以得到最短停頓時間爲目標的收集器,很是適用 B/S 系統。 G1:一種兼顧吞吐量和停頓時間的 GC 實現,是 JDK 9 之後的默認 GC 選項。
204.詳細介紹一下 CMS 垃圾回收器?
CMS 是英文 Concurrent Mark-Sweep(同步標記掃描) 的簡稱,是以犧牲吞吐量爲代價來得到最短回收停頓時間的垃圾回收器。對於要求服務器響應速度的應用上,這種垃圾回收器很是適合。在啓動 JVM 的參數加上「-XX:+UseConcMarkSweepGC」來指定使用 CMS 垃圾回收器。
CMS 使用的是標記-清除的算法實現的,因此在 gc 的時候回產生大量的內存碎片,當剩餘內存不能知足程序運行要求時,系統將會出現 Concurrent Mode Failure,臨時 CMS 會採用 Serial Old 回收器進行垃圾清除,此時的性能將會被下降。
205.新生代垃圾回收器和老生代垃圾回收器都有哪些?有什麼區別?
新生代回收器:Serial、ParNew、Parallel Scavenge
老年代回收器:Serial Old、Parallel Old、CMS
整堆回收器:G1
新生代垃圾回收器通常採用的是複製算法,複製算法的優勢是效率高,缺點是內存利用率低;老年代回收器通常採用的是標記-整理的算法進行垃圾回收。
206.簡述分代垃圾回收器是怎麼工做的?
分代回收器有兩個分區:老生代和新生代,新生代默認的空間佔比總空間的 1/3,老生代的默認佔比是 2/3。
新生代使用的是複製算法,新生代裏有 3 個分區:Eden、To Survivor、From Survivor,它們的默認佔比是 8:1:1,它的執行流程以下:
把 Eden + From Survivor 存活的對象放入 To Survivor 區;
清空 Eden 和 From Survivor 分區;
From Survivor 和 To Survivor 分區交換,From Survivor 變 To Survivor,To Survivor 變 From Survivor。
每次在 From Survivor 到 To Survivor 移動時都存活的對象,年齡就 +1,當年齡到達 15(默認配置是 15)時,升級爲老生代。大對象也會直接進入老生代。
老生代當空間佔用到達某個值以後就會觸發全局垃圾收回,通常使用標記整理的執行算法。以上這些循環往復就構成了整個分代垃圾回收的總體執行流程。
207.說一下 jvm 調優的工具?
JDK 自帶了不少監控工具,都位於 JDK 的 bin 目錄下,其中最經常使用的是 jconsole 和 jvisualvm 這兩款視圖監控工具。
jconsole:用於對 JVM 中的內存、線程和類等進行監控;
jvisualvm:JDK 自帶的全能分析工具,能夠分析:內存快照、線程快照、程序死鎖、監控內存的變化、gc 變化等。
208.經常使用的 jvm 調優的參數都有哪些?
-Xms2g:初始化推大小爲 2g;
-Xmx2g:堆最大內存爲 2g;
-XX:NewRatio=4:設置年輕的和老年代的內存比例爲 1:4;
-XX:SurvivorRatio=8:設置新生代 Eden 和 Survivor 比例爲 8:2;
–XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器組合;
-XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器組合;
-XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器組合;
-XX:+PrintGC:開啓打印 gc 信息;
-XX:+PrintGCDetails:打印 gc 詳細信息。