1. 程式人生 > 程式設計 >杭-某某車被虐之旅

杭-某某車被虐之旅

經過了一波洗禮,讓我不得不總結下我身上的傷疤與痛處。果然還是資質太淺了!!

1.MySQL中的Hash索引如何解決衝突

說實話,剛聽這個題目,我只想到了HashMap中的索引是如何解決衝突的(利用拉鍊法解決衝突以及利用擾亂函式降低hash衝突),對於技術棧只有使用過MySQL中innodb中的B+樹,對於未使用過Hash索引,我只能乖乖的說不知道。事後通過查詢才發現也應該是類似於HashMap一樣去解決的,如果發生了衝突也是將衝突的元素放在衝突的Hash連結串列中。

2.如何確定類唯一性

這個問題很是吃虧,在此問題之前已經問了一些有關於這個問題答案的前置問題(類載入器)。但是到了這個問題有點沒想起來。類載入器 + 類路徑

才唯一確定一個 Java 類。如果僅僅包路徑一樣,是不能夠確定這是唯一的一個類。

3.MySQL什麼情況下不走索引

對於目前技術棧使用hibernate框架來說,sql我是真的很少寫的。然後這邊目前我只知滿足最左匹配是會走的,那麼其他的索引上面的模糊查詢就不會走。剩下的我就不清楚了呀!!

1. like '%abc' 或者 like‘%abc%’(不滿足最左匹配,同時他不是覆蓋索引查詢)
2.where num/2=100 或者 subString(a,1,3)='ab'(索引參與表示式)
3.關聯查詢的時候,主鍵型別與外來鍵型別不一致
4.OR查詢條件中存在沒有索引的列
5.資料量過少
複製程式碼

這上面是我簡單查詢以及總結的不走索引的情況(情況可能暫時還是不夠全面的,後期再繼續補充)。當然走索引的話,其中要注意的是覆蓋索引這種情況。以及(5.7?)版本出現的索引下推等情況。

4.JAVA中全克隆的幾種方式

  1. 實現克隆介面並重寫clone()方法
  2. 物件實現序列化,利用反序列化進行。

這塊我記得當時好像不止這兩種方式。。。暫時還沒有想起來(後期想到補充上去)

5.MySQL為什麼是最左匹配

mysql建立複合索引的規則是首先會對複合索引的最左邊的,也就是第一個欄位的資料進行排序,在第一個欄位的排序基礎上,然後再對後面第二個欄位進行排序。其實就相當於實現了類似 order by 第一個欄位 第二個欄位這樣一種排序規則。

這種問題在之前的學習過程中,沒有思考過。平時也只是知道哪種條件下會走索引,以及給哪些欄位上面適合新增索引,當然的我是懵的。。這上面也是自己感覺出來的答案,有大佬的話可以再給我點回復。

6.Explain中各個列屬性以及Type值有哪些

這些東西在網上一搜一大把,但是面對我們很少手寫sql的情況,我也是隻是瞭解一些資料,對於大多數的沒有操作過也不是很清楚。

table:顯示這一行的資料是關於哪張表的

type:這是重要的列,顯示連線使用了何種型別。從最好到最差的連線型別為const、eq_reg、ref、range、indexhe和ALL

possible_keys:顯示可能應用在這張表中的索引。如果為空,沒有可能的索引。可以為相關的域從WHERE語句中選擇一個合適的語句。這個列表是在優化過程的早期建立的,因此有些列出來的索引可能對於後續優化過程是沒有用的。

key: 實際使用的索引。如果為NULL,則沒有使用索引。很少的情況下,MYSQL會選擇優化不足的索引。這種情況下,可以在SELECT語句中使用USE INDEX(indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制MYSQL忽略索引

如果該索引沒有出現在possible_keys中,那麼mysql選用的是出於另外的原因——例如,他可能選擇了一個覆蓋索引,哪怕沒有where字句,換句話說,possible_keys揭示了哪一個索引能有助於提高查詢效率,而key顯示的是優化採用哪一個索引可以最小化查詢成本。

key_len:使用的索引的長度。在不損失精確性的情況下,長度越短越好

ref:顯示索引的哪一列被使用了,如果可能的話,是一個常數

rows:MYSQL認為必須檢查的用來返回請求資料的行數

extra:關於MYSQL如何解析查詢的額外資訊

其中Type列主要告訴我們對錶使用的訪問方式,主要包含如下集中型別:

all:全表掃描。

const:讀常量,最多隻會有一條記錄匹配,由於是常量,實際上只須要讀一次。

eq_ref:最多隻會有一條匹配結果,一般是通過主鍵或唯一鍵索引來訪問。

fulltext:進行全文索引檢索。

index:全索引掃描。

index_merge:查詢中同時使用兩個(或更多)索引,然後對索引結果進行合併(merge),再讀取表資料。

index_subquery:子查詢中的返回結果欄位組合是一個索引(或索引組合),但不是一個主鍵或唯一索引。

rang:索引範圍掃描。

ref:Join語句中被驅動表索引引用的查詢。

ref_or_null:與ref的唯一區別就是在使用索引引用的查詢之外再增加一個空值的查詢。

system:系統表,表中只有一行資料;

unique_subquery:子查詢中的返回結果欄位組合是主鍵或唯一約束。

7.Spring Bean 的生命週期

  1. 例項化一個Bean--也就是我們常說的new;

  2. 按照Spring上下文對例項化的Bean進行配置--也就是IOC注入;

  3. 如果這個Bean已經實現了BeanNameAware介面,會呼叫它實現的setBeanName(String)方法,此處傳遞的就是Spring配置檔案中Bean的id值

  4. 如果這個Bean已經實現了BeanFactoryAware介面,會呼叫它實現的setBeanFactory(setBeanFactory(BeanFactory)傳遞的是Spring工廠自身(可以用這個方式來獲取其它Bean,只需在Spring配置檔案中配置一個普通的Bean就可以);

  5. 如果這個Bean已經實現了ApplicationContextAware介面,會呼叫setApplicationContext(ApplicationContext)方法,傳入Spring上下文(同樣這個方式也可以實現步驟4的內容,但比4更好,因為ApplicationContext是BeanFactory的子介面,有更多的實現方法);

  6. 如果這個Bean關聯了BeanPostProcessor介面,將會呼叫postProcessBeforeInitialization(Object obj,String s)方法,BeanPostProcessor經常被用作是Bean內容的更改,並且由於這個是在Bean初始化結束時呼叫那個的方法,也可以被應用於記憶體或快取技術;

  7. 如果Bean在Spring配置檔案中配置了init-method屬性會自動呼叫其配置的初始化方法。

  8. 如果這個Bean關聯了BeanPostProcessor介面,將會呼叫postProcessAfterInitialization(Object obj,String s)方法;

注:以上工作完成以後就可以應用這個Bean了,那這個Bean是一個Singleton的,所以一般情況下我們呼叫同一個id的Bean會是在內容地址相同的例項,當然在Spring配置檔案中也可以配置非Singleton,這裡我們不做贅述。

  1. 當Bean不再需要時,會經過清理階段,如果Bean實現了DisposableBean這個介面,會呼叫那個其實現的destroy()方法;

  2. 最後,如果這個Bean的Spring配置中配置了destroy-method屬性,會自動呼叫其配置的銷燬方法。

這上面描述的是Spring上下文的Bean週期,如果是工廠Bean的話,除去第五步操作即可。

8.B+樹的優點

  1. 從儲存上面來說的話,在資料量大的情況下,B+樹的設計可以允許資料分批載入。從查詢上面來說,如果只是針對於一條查詢,當然是hash比較快,但是我們大多數業務場景下面是多條查詢,並且還是要進行排序返回的。此時如果範圍查詢的話就顯得他是比較快的(因為節點是排序的,這時候就進行區域性的中序遍歷,可能要跨層訪問。就能將資料查詢返回出去)。

  2. 因為他是B+樹,多路分支可以降低樹的高度,提高查詢效率問題,減少磁碟io次數。

  3. 它的葉子節點上面儲存的是對應的聚簇索引地址以及資料本身,你在進行查詢的時候,如果是利用的是主鍵等情況,則不需要進行回表操作,直接可以查詢返回。

這上面是我印象中最深的幾個問題,當然還有一些其他的問題。例如如何設計一個分散式鎖、執行緒池的相關(這塊我沒回答好,感覺這裡面需要考慮許多問題,不僅僅是原始碼中的程式碼)、Map中的key的hash是如何取值並且如果降低hash衝突(擾亂函式)等等。這些問題感覺最重要的還是資料庫以及多執行緒,學習之路還長著呢。

評論裡面的大佬給出了 IS NOT NULL 以及!=IS NULL的情況的解釋,小夥伴們可以看下貼出來的連結