常見面試題

java虛擬機

何時會觸發full gcjava

  1. System.gc()方法的調用
  2. 老年代空間不足
  3. 永生區空間不足(JVM規範中運行時數據區域中的方法區,在HotSpot虛擬機中又被習慣稱爲永生代或者永生區,Permanet Generation中存放的爲一些class的信息、常量、靜態變量等數據)
  4. GC時出現promotion failed和concurrent mode failure
  5. 統計獲得的Minor GC晉升到舊生代平均大小大於老年代剩餘空間
  6. 堆中分配很大的對象

能夠做爲root的對象:mysql

  1. 類中的靜態變量,當它持有一個指向一個對象的引用時,它就做爲root
  2. 活動着的線程,能夠做爲root
  3. 一個Java方法的參數或者該方法中的局部變量,這兩種對象能夠做爲root
  4. JNI方法中的局部變量或者參數,這兩種對象能夠做爲root

例子:下述的Something和Apple均可以做爲root對象。面試

解析一些java複雜面試題的簡單操做

Java方法的參數和方法中的局部變量,能夠做爲root.redis

解析一些java複雜面試題的簡單操做

新生代轉移到老年代的觸發條件算法

  1. 長期存活的對象
  2. 大對象直接進入老年代
  3. minor gc後,survivor仍然放不下
  4. 動態年齡判斷 ,大於等於某個年齡的對象超過了survivor空間一半 ,大於等於某個年齡的對象直接進入老年代

redis

redis單線程問題sql

單線程指的是網絡請求模塊使用了一個線程(因此不需考慮併發安全性),即一個線程處理全部網絡請求,其餘模塊仍用了多個線程。數據庫

爲何說redis可以快速執行緩存

  1. 絕大部分請求是純粹的內存操做(很是快速)
  2. 採用單線程,避免了沒必要要的上下文切換和競爭條件
  3. 非阻塞IO - IO多路複用

redis的內部實現安全

內部實現採用epoll,採用了epoll+本身實現的簡單的事件框架。epoll中的讀、寫、關閉、鏈接都轉化成了事件,而後利用epoll的多路複用特性,毫不在io上浪費一點時間 這3個條件不是相互獨立的,特別是第一條,若是請求都是耗時的,採用單線程吞吐量及性能可想而知了。應該說redis爲特殊的場景選擇了合適的技術方案。網絡

Redis關於線程安全問題

redis其實是採用了線程封閉的觀念,把任務封閉在一個線程,天然避免了線程安全問題,不過對於須要依賴多個redis操做的複合操做來講,依然須要鎖,並且有多是分佈式鎖。

使用redis有哪些好處?

  1. 速度快,由於數據存在內存中,相似於HashMap,HashMap的優點就是查找和操做的時間複雜度都是O(1)
  2. 支持豐富數據類型,支持string,list,set,sorted set,hash
  3. 支持事務,操做都是原子性,所謂的原子性就是對數據的更改要麼所有執行,要麼所有不執行
  4. 豐富的特性:可用於緩存,消息,按key設置過時時間,過時後將會自動刪除

redis相比memcached有哪些優點?

  1. memcached全部的值均是簡單的字符串,redis做爲其替代者,支持更爲豐富的數據類型
  2. redis的速度比memcached快不少
  3. redis能夠持久化其數據

數據庫

B樹和B+樹的區別

  1. B樹,每一個節點都存儲key和data,全部節點組成這棵樹,而且葉子節點指針爲nul,葉子結點不包含任何關鍵字信息。
解析一些java複雜面試題的簡單操做

  1. B+樹,全部的葉子結點中包含了所有關鍵字的信息,及指向含有這些關鍵字記錄的指針,且葉子結點自己依關鍵字的大小自小而大的順序連接,全部的非終端結點能夠當作是索引部分,結點中僅含有其子樹根結點中最大(或最小)關鍵字。 (而B 樹的非終節點也包含須要查找的有效信息)
解析一些java複雜面試題的簡單操做

爲何說B+比B樹更適合實際應用中操做系統的文件索引和數據庫索引?

  1. B+的磁盤讀寫代價更低 B+的內部結點並無指向關鍵字具體信息的指針。所以其內部結點相對B樹更小。若是把全部同一內部結點的關鍵字存放在同一盤塊中,那麼盤塊所能容納的關鍵字數量也越多。一次性讀入內存中的須要查找的關鍵字也就越多。相對來講IO讀寫次數也就下降了。
  2. B+-tree的查詢效率更加穩定 因爲非終結點並非最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。因此任何關鍵字的查找必須走一條從根結點到葉子結點的路。全部關鍵字查詢的路徑長度相同,致使每個數據的查詢效率至關。

爲何使用數據索引能提升效率

  1. 數據索引的存儲是有序的
  2. 在有序的狀況下,經過索引查詢一個數據是無需遍歷索引記錄的
  3. 極端狀況下,數據索引的查詢效率爲二分法查詢效率,趨近於 log2(N)

mysql聯合索引

  1. 聯合索引是兩個或更多個列上的索引。對於聯合索引:Mysql從左到右的使用索引中的字段,一個查詢能夠只使用索引中的一部份,但只能是最左側部分。例如索引是key index (a,b,c). 能夠支持a 、 a,b 、 a,b,c 3種組合進行查找,但不支持 b,c進行查找 .當最左側字段是常量引用時,索引就十分有效。
  2. 利用索引中的附加列,您能夠縮小搜索的範圍,但使用一個具備兩列的索引 不一樣於使用兩個單獨的索引。複合索引的結構與電話簿相似,人名由姓和名構成,電話簿首先按姓氏對進行排序,而後按名字對有相同姓氏的人進行排序。若是您知 道姓,電話簿將很是有用;若是您知道姓和名,電話簿則更爲有用,但若是您只知道名不姓,電話簿將沒有用處。

什麼狀況下應不建或少建索引

  1. 表記錄太少
  2. 常常插入、刪除、修改的表
  3. 數據重複且分佈平均的表字段,假如一個表有10萬行記錄,有一個字段A只有T和F兩種值,且每一個值的分佈機率大約爲50%,那麼對這種表A字段建索引通常不會提升數據庫的查詢速度。
  4. 常常和主字段一塊查詢但主字段索引值比較多的表字段

爲何要分區?

  1. 咱們都知道mysql數據庫的數據以文件的形式存儲在磁盤,默認是放在/mysql/data下面,一張表對應着三個文件,一個是frm存放表結構,一個是myd存放表數據的,一個是myi存表索引的。
  2. 假設有一張表的數據量很是大,那麼myd,myi就會變得很大,查找數據就會變得很慢,那麼咱們的解決方法是什麼?就是分區,在物理上將這一張表對應的三個文件,分割成許多個小塊,而後咱們查找一條數據時,就不用所有查找了,只需知道這條數據在哪一塊,而後在那一塊找就行,若是表的數據太大,一個磁盤也放不下,咱們能夠把數據分配到不一樣的磁盤裏面

四種隔離級別

  1. Serializable (串行化):可避免髒讀、不可重複讀、幻讀的發生。
  2. Repeatable read (可重複讀):可避免髒讀、不可重複讀的發生。
  3. Read committed (讀已提交):可避免髒讀的發生。
  4. Read uncommitted (讀未提交):最低級別,任何狀況都沒法保證。

行級鎖定的優勢:

  1. 當在許多線程中訪問不一樣的行時只存在少許鎖定衝突。
  2. 回滾時只有少許的更改
  3. 能夠長時間鎖定單一的行。

行級鎖定的缺點:

  1. 比頁級或表級鎖定佔用更多的內存。
  2. 當在表的大部分中使用時,比頁級或表級鎖定速度慢,由於你必須獲取更多的鎖。
  3. 若是你在大部分數據上常常進行GROUP BY操做或者必須常常掃描整個表,比其它鎖定明顯慢不少。
  4. 用高級別鎖定,經過支持不一樣的類型鎖定,你也能夠很容易地調節應用程序,由於其鎖成本小於行級鎖定。

MySQL 觸發器簡單實例

  1. CREATE TRIGGER <觸發器名稱> --觸發器必須有名字,最多64個字符,可能後面會附有分隔符.它和MySQL中其餘對象的命名方式基本相象.
  2. { BEFORE | AFTER } --觸發器有執行的時間設置:能夠設置爲事件發生前或後。
  3. { INSERT | UPDATE | DELETE } --一樣也能設定觸發的事件:它們能夠在執行insert、update或delete的過程當中觸發。
  4. ON <表名稱> --觸發器是屬於某一個表的:當在這個表上執行插入、 更新或刪除操做的時候就致使觸發器的激活. 咱們不能給同一張表的同一個事件安排兩個觸發器。
  5. FOR EACH ROW --觸發器的執行間隔:FOR EACH ROW子句通知觸發器 每隔一行執行一次動做,而不是對整個表執行一次。
  6. <觸發器SQL語句> --觸發器包含所要觸發的SQL語句:這裏的語句能夠是任何合法的語句, 包括複合語句,可是這裏的語句受的限制和函數的同樣。

B+樹索引和哈希索引的區別

B+樹是一個平衡的多叉樹,從根節點到每一個葉子節點的高度差值不超過1,並且同層級的節點間有指針相互連接,是有序的

複雜面試題的簡單操做續集

哈希索引就是採用必定的哈希算法,把鍵值換算成新的哈希值,檢索時不須要相似B+樹那樣從根節點到葉子節點逐級查找,只需一次哈希算法便可,是無序的

複雜面試題的簡單操做續集

哈希索引的優點:

  1. 等值查詢。哈希索引具備絕對優點(前提是:沒有大量重複鍵值,若是大量重複鍵值時,哈希索引的效率很低,由於存在所謂的哈希碰撞問題。)

哈希索引不適用的場景:

  1. 不支持範圍查詢
  2. 不支持索引完成排序
  3. 不支持聯合索引的最左前綴匹配規則

一般,B+樹索引結構適用於絕大多數場景,像下面這種場景用哈希索引才更有優點:

在HEAP表中,若是存儲的數據重複度很低(也就是說基數很大),對該列數據以等值查詢爲主,沒有範圍查詢、沒有排序的時候,特別適合採用哈希索引,例如這種SQL:

select id,name from table where name='李明'; — 僅等值查詢

而經常使用的InnoDB引擎中默認使用的是B+樹索引,它會實時監控表上索引的使用狀況,若是認爲創建哈希索引能夠提升查詢效率,則自動在內存中的「自適應哈希索引緩衝區」創建哈希索引(在InnoDB中默認開啓自適應哈希索引),經過觀察搜索模式,MySQL會利用index key的前綴創建哈希索引,若是一個表幾乎大部分都在緩衝池中,那麼創建一個哈希索引可以加快等值查詢。

注意:在某些工做負載下,經過哈希索引查找帶來的性能提高遠大於額外的監控索引搜索狀況和保持這個哈希表結構所帶來的開銷。但某些時候,在負載高的狀況下,自適應哈希索引中添加的read/write鎖也會帶來競爭,好比高併發的join操做。like操做和%的通配符操做也不適用於自適應哈希索引,可能要關閉自適應哈希索引。

數據庫表建立注意事項

1、字段名及字段配製合理性

  1. 剔除關係不密切的字段
  2. 字段命名要有規則及相對應的含義(不要一部分英文,一部分拼音,還有相似a.b.c這樣不明含義的字段)
  3. 字段命名儘可能不要使用縮寫(大多數縮寫都不能明確字段含義)
  4. 字段不要大小寫混用(想要具備可讀性,多個英文單詞可以使用下劃線形式鏈接)
  5. 字段名不要使用保留字或者關鍵字
  6. 保持字段名和類型的一致性
  7. 慎重選擇數字類型
  8. 給文本字段留足餘量

2、系統特殊字段處理及建成後建議

  1. 添加刪除標記(例如操做人、刪除時間)
  2. 創建版本機制

3、表結構合理性配置

  1. 多型字段的處理,就是表中是否存在字段可以分解成更小獨立的幾部分(例如:人能夠分爲男人和女人)
  2. 多值字段的處理,能夠將表分爲三張表,這樣使得檢索和排序更加有調理,且保證數據的完整性!

4、其它建議

  1. 對於大數據字段,獨立表進行存儲,以便影響性能(例如:簡介字段)
  2. 使用varchar類型代替char,由於varchar會動態分配長度,char指定長度是固定的。
  3. 給表建立主鍵,對於沒有主鍵的表,在查詢和索引定義上有必定的影響。
  4. 避免表字段運行爲null,建議設置默認值(例如:int類型設置默認值爲0)在索引查詢上,效率立顯!
  5. 創建索引,最好創建在惟一和非空的字段上,創建太多的索引對後期插入、更新都存在必定的影響(考慮實際狀況來建立)。

java高併發

JAVA 線程狀態轉換圖示

解析一些java複雜面試題的簡單操做

synchronized 的底層怎麼實現

  1. 同步代碼塊(Synchronization)基於進入和退出管程(Monitor)對象實現。每一個對象有一個監視器鎖(monitor)。當monitor被佔用時就會處於鎖定狀態,線程執行monitorenter指令時嘗試獲取monitor的全部權,過程以下:
  • 若是monitor的進入數爲0,則該線程進入monitor,而後將進入數設置爲1,該線程即爲monitor的全部者。
  • 若是線程已經佔有該monitor,只是從新進入,則進入monitor的進入數加1.
  • 若是其餘線程已經佔用了monitor,則該線程進入阻塞狀態,直到monitor的進入數爲0,再從新嘗試獲取monitor的全部權。
    1. 被 synchronized 修飾的同步方法並無經過指令monitorenter和monitorexit來完成(理論上其實也能夠經過這兩條指令來實現),不過相對於普通方法,其常量池中多了ACC_SYNCHRONIZED標示符。JVM就是根據該標示符來實現方法的同步的:當方法調用時,調用指令將會檢查方法的 ACC_SYNCHRONIZED 訪問標誌是否被設置,若是設置了,執行線程將先獲取monitor,獲取成功以後才能執行方法體,方法執行完後再釋放monitor。在方法執行期間,其餘任何線程都沒法再得到同一個monitor對象。 其實本質上沒有區別,只是方法的同步是一種隱式的方式來實現,無需經過字節碼來完成
相關文章
相關標籤/搜索