1. 程式人生 > >一次阿里面試的總結

一次阿里面試的總結

SpringCloud

你用過springcloud,你知道它的實現原理嗎?

我目前使用到的就是Eureka做註冊中心,ribbon做負載均衡,feign做宣告式服務呼叫(原先是使用restTemplate,太過混亂)Hystrix的熔斷機制機制還沒有使用,zuul做路由處理,比如一些token校驗,客戶端呼叫哪個服務都得經過該層。

springcloud和dubbo的區別和優缺點能講一下嗎?就是當時你為什麼不選擇dubbo而選擇springcloud?

當時我選用的時候分析過這兩個的區別,主要區別我覺得是springcloud使用的restful的http協議,dubbo使用的RPC進行通訊,雖然http協議比較重,但是使用起來會簡單很多,跨平臺呼叫也比較輕鬆。其二就是看了很多人反饋dubbo的神坑是jar包依賴,對於當時剛接觸分散式的我來說肯定會選擇更為簡單的,容易上手,文件齊全的分散式框架來用,何況當時dubbo已經停止更新了。

springboot的引入第三方的starter有了解過嗎?能詳細講一下嗎?

這個我當時沒有答上來,雖然我一直在用,但是我不知道starter這個專業術語,所以當時是懵逼的。

下面是事後整理的理解:
例如我想要在SpringBoot專案中整合Redis,那麼我只需要加入spring-data-redis-starter的依賴,並簡單配置一下連線資訊以及Jedis連線池配置就可以。
其實這個starter主要就是帶有@Configuration註解的AutoConfigure類,用於自動載入application.yml裡面的引數配置。

springboot的啟動原理你可以講解一下嗎?比如如何載入上面說的starter?

@SpringBootApplication註解是Spring Boot的核心註解,它主要由@Configuration
,@EnableAutoConfiguration,@ComponentScan三個標籤組成:

@Configuration其實就是一個IOC容器的配置類,該註解宣告的類會被加到IOC容器中
@ComponentScan就是自動掃描並載入符合條件的元件(比如@Component和@Repository等)
@EnableAutoConfiguration這個最為重要,也是上面starter會被載入進來的原因,該註解中最為關鍵的就是@Import({EnableAutoConfigurationImportSelector.class}),藉助該類@EnableAutoConfiguration可以幫助SpringBoot應用將所有符合條件的@Configuration配置都載入到IoC容器,本質是藉助SpringFactoriesLoader從指定的配置檔案META-INF/spring.factories載入配置,通過反射例項化到IOC

後面我打算後面起一篇文章具體講講springboot的整個啟動過程。

mysql

資料庫表需要建立索引,一個業務需要用到AC聯合索引,一個業務需要用到ABC聯合索引,你會怎麼建立索引?為什麼需要這麼建立?

我會建立ACB索引,mysql的複合索引的建立以及最左字首原則,其實一個索引存在平衡樹的節點上就相當於一個存了一個String,比如ACB的內容分別為acb,儲存起來就像是a_c_b,當進來a_c,迴圈a_c_b只要前面不匹配就退出進行下一個比迴圈完整個a_c_b的效能要好很多。

你知道mysql建立索引的原理嗎?

索引主要分為兩種索引,聚集索引和非聚集索引,聚集索引是以主鍵建立的索引,每個樹節點都是資料庫表的一行資料,就相當於一棵樹就是一個表,非聚集索引是以其他欄位建立的索引,儲存了該欄位內容和主鍵之間的關係,查到這個欄位內容之後再去聚集索引裡找資料。

為什麼mysql要選用B+樹做索引的資料結構,而不用其他樹?

第一B樹能減少樹的層數,這就減少了磁碟IO查詢的次數。
第二B+樹相比於B樹,B+樹所有data域資料都是存在葉子節點上的,
但是B-樹的每個節點都有data域,這無疑增大了節點大小,也會增加了磁碟IO次數。
mysql還對B+樹做了一個優化,就是將所有葉子節點串起來,方便資料便利,畢竟遍歷樹拿到所有資料並不是那麼方便

能講講synchronized實現原理嗎?

看位元組碼檔案可以看到,被鎖住的程式碼操作前後有一個monitorenter和monitorexit包裹著
任何物件都有一個monitor與之相關聯,當且一個monitor被持有之後,他將處於鎖定狀態。執行緒執行到monitorenter指令時,
將會嘗試獲取物件所對應的monitor所有權,即嘗試獲取物件的鎖

JVM對synchronized做了哪些優化?

我只回答了自旋(其實還有適度自旋,控制自旋時間)

執行緒等待鎖的時候為什麼選擇自旋而不阻塞?

執行緒的阻塞和喚醒需要cpu從使用者態轉為核心態,這是一個負擔很重的操作,物件鎖一般只會持續極短的時間,為了這段時間頻繁阻塞喚醒執行緒不值得

多執行緒死鎖是如何形成的?

同步中嵌套了其他的同步

排查死鎖時,jstack生成的dump檔案你是怎麼分析的?

用mat進行分析,還能分析記憶體溢位的情況

注意

這次面試回答的並不是很好,以上部分答案是經過了後期優化防止誤人子弟。