最近一直在面試。面試了大約有10來家公司,有1000人以上的大公司,也有50左右的小公司。時間倉促沒有準備充分,面試的機會雖然不少,可是面試時表現的通常。經過這10來場的面試,我對本身的知識體系薄弱環節有了較爲清楚的認識。這裏記錄一些我在面試中遇到的比較常見的面試題。這只是其中的小小一部分。java
0. 數據庫
很久沒寫代碼了,SQL語句很生疏,致使我面試的時候簡單的語法都忘了,吃了很大虧。這裏推薦一篇大佬的博客。該博客中收錄了常見的MySQL面試題和筆試題。SQL複習面試
1. 基本數據類型和引用數據類型的區別
問題分析:這個問題不是說有多難,只是咱們平時專一於代碼邏輯,很容易忽視代碼的底層原理。redis
示例答案:算法
- 基本數據類型在建立時,在棧上給其劃分一塊內存,將數值直接存儲在棧上。
- 引用數據類型在被建立時,首先要在棧上給其引用(句柄)分配一塊內存,而對象的具體信息都存儲在堆內存中,而後由棧上的引用指向堆中的對象的地址。
這道題主要考察JVM中內存模型,這塊須要重點理解。spring
JVM區域劃分爲:程序計數器,虛擬機棧,堆,方法區,本地方法棧五個區域。sql
①程序計數器: Java代碼會被翻譯成字節碼,不一樣字節碼指令指揮計算機幹不一樣的事。程序計數器是用來記錄每一個線程當前執行的指令的位置。由於程序能夠是多線程的,因此每一個線程都有本身的程序計數器。數據庫
②Java虛擬機棧:Java代碼執行時,必定是線程執行某個方法中的代碼。JVM中有一塊區域用來保存每一個方法內的局部變量等數據,這個區域就是Java虛擬機棧。爲何須要這個區域?由於每一個線程都會去執行各類方法的代碼,方法內還會嵌套調用其餘的方法,因此每一個線程都要有本身的Java虛擬機棧。編程
調用執行任何方法時,都會給方法建立棧幀,而後入棧。數組
③Java堆內存:用來存放Java中的建立的實例對象。好比Student對象。那麼Java虛擬機棧中的變量student就會存放該對象的地址,或者說student指向了該對象。
④Java方法區:主要仍是存放咱們本身寫的各類類相關的信息。
⑤本地方法棧:Java執行時會調用非Java代碼,執行native方法,本地方法棧用來存放native方法的局部變量表等信息。
2. 檢查時異常和運行時異常的區別
這個問題容易忽略。
Java中把全部的非正常狀況分爲兩種:異常(Exception)和錯誤(Error),他們都繼承Throwable父類。
Java的非正常狀況能夠分爲檢查異常
和非檢查異常
。
其中Exception異常分爲運行時異常
和非運行時異常
。
- 檢查異常:
- 概念:就是編譯器要求你必需要處理的異常。你的代碼尚未運行時,編譯器就會檢查你的代碼,對於可能出現的異常你必須使用try...catch...或者throws exception。
- 處理:①使用throws exception往上拋出,一直能夠拋到Java虛擬機來處理。②使用try...catch...
- 範圍:除了RuntimeException與其子類,錯誤Error之外的,差很少都是檢查異常。
- 非檢查異常:
- 概念:編譯器不要求強制處置的異常,雖然可能出錯,可是不會在編譯時檢查。
- 處理:①try..catch...②繼續拋出③不處理
- 範圍:RuntimeException與其子類,Error錯誤。
- 運行時異常:RuntimeException及其子類
- 非運行時異常:異常中除了RuntimeException及其子類之外都是非運行時異常。
3. Spring相關
若是你使用SSM框架,基本Spring一上來就問這幾個問題,必須很是熟悉。
IOC:控制反轉,傳統的Java開發模式中,當須要一個對象時,咱們會本身使用new或者getInstance等直接或者間接調用構造方法建立一個對象。而在Spring中,Spring容器使用了工廠模式爲咱們建立了所須要的對象,不須要咱們本身建立了,直接調用Spring提供的對象就能夠了。
DI:依賴注入,Spring使用JavaBean對象的set方法或者帶參數的構造方法爲咱們在建立對象時將其屬性自動設置所須要的值的過程,就是依賴注入的思想。
AOP面向切面編程:在面向對象編程思想中,咱們將事物縱向抽取成一個個的對象。而在面向切面編程中,咱們將一個個的對象某些相似的方面橫向抽成一個切面,對這個切面進行一些如權限控制,事物管理,記錄日誌等公用操做處理的過程就是面向切面編程的思想。AOP的底層是動態代理,若是目標對象是接口採用JDK動態代理,若是是類採用Cglib方式實現動態代理。
動態代理的原理能夠看看我以前寫的一篇:動態代理
4. Java 中的 HashMap 的工做原理是什麼?
面試官開始問你基礎的時候,不少都從HashMap開始。
- Java 中的 HashMap 是以鍵值對(key-value)的形式存儲元素的。HashMap 須要一個 hash 函數,它使用 hashCode()和 equals()方法來向集合/從集合添加和檢索元素。當調用 put()方法的時候,HashMap 會計算 key 的 hash 值,而後把鍵值對存儲在集合中合適的索引上。若是 key已經存在了,value 會被更新成新值。HashMap 的一些重要的特性是它的容量(capacity),負 載因子(load factor)和擴容極限(threshold resizing)。
5. HashMap 和 Hashtable 有什麼區別?
HashMap 和 Hashtable 都實現了Map 接口,所以不少特性很是類似。可是,他們有如下不一樣點:
- HashMap 容許鍵和值是 null,而Hashtable 不容許鍵或者值是 null。
- Hashtable 是同步的,而 HashMap 不是。所以,HashMap 更適合於單線程環境,而 Hashtable適合於多線程環境。
- HashMap 提供了可供應用迭代的鍵的集合,所以,HashMap 是快速失敗的。另外一方面,Hashtable 提供了對鍵的列舉(Enumeration)。通常認爲 Hashtable 是一個遺留的類。
6. SQL優化
這裏只是一些SQL優化的思路,遠遠不止這些。
- 使用JOIN的時候,應該用小的結果驅動大的結果『left join左邊表結果儘可能小,若是有條件應該放到左邊先處理』
- 儘可能把牽涉到多表聯合查詢拆分多個query,由於連表查詢效率低,容易到以後鎖表和阻塞。
- limit的基數比較大時使用between
- 儘可能避免在列上作運算,這樣致使索引失效。
select * from admin where year(admin_time)>2014
優化爲:
select * from admin where admin_time>'2014-01-01'
7. Redis
談到Redis的話能夠從如下幾個方面簡單說說。
8. RabbitMQ
明白MQ的概念、原理、使用場景。
- 概念:MQ全稱是Message Queue,能夠理解爲消息隊列的意思,簡單來講就是消息以管道的方式進行傳遞。RabbitMQ是一個實現了高級消息隊列協議的消息隊列服務,用Erlang語言的。
- 使用場景:好比秒殺系統中,當用戶訪問量很大時系統會提示咱們排隊結算。這種排隊結算就使用到了消息隊列,生產者生產的消息放入通道中一個個地被消費,而不是某個時間內忽然出現大批量的查詢新增把數據庫給搞宕機了。因此RabbitMQ的做用是削峯填谷。
- 工做機制:
- 生產者:建立消息,發送消息到服務器
- 消費者:接受確認消息
- 代理:RabbitMQ自己,不產生消息,只是傳遞消息。
- 發送原理:首先要鏈接RabbitMQ。應用程序和RabbitMQ服務器之間會建立一個TCP鏈接,一旦TCP打開鏈接,而且經過了認證(認證就是嘗試鏈接RabbitMQ服務器以前發送給服務器的鏈接信息,用戶名和密碼),應用程序和和Rabbit就建立了一條AMQP的信道。信道是建立在「真實」TCP上的虛擬鏈接,AMQP命令都是經過信道發送出去的,每一個信道都會有一個惟一的ID,不管是發佈消息,訂閱隊列或者介紹消息都是經過信道完成的。
- 爲何不經過TCP直接發送命令?
- 對於操做系統來講建立和銷燬TCP會話是很是昂貴的開銷,假設高峯期每秒有成千上萬條鏈接,每一個鏈接都要建立一條TCP會話,這就形成了TCP鏈接的巨大浪費,並且操做系統每秒能建立的TCP也是有限的,所以很快就會遇到系統瓶頸。
- 若是咱們每一個請求都使用一條TCP鏈接,既知足了性能的須要,又能確保每一個鏈接的私密性,這就是引入信道概念的緣由。
- 持久化工做原理:Rabbit會將你的持久化消息寫入磁盤上的持久化日誌文件,等消息被消費以後,Rabbit會把這條消息標識爲等待垃圾回收
- RabbitMQ防止消息丟失?
- 客戶端丟失消息確認:RabbitMQ引入了消息確認機制,當消息處理完成後,給Server端發送一個確認消息,來告訴服務端能夠刪除該消息了,若是鏈接斷開的時候,Server端沒有收到消費者發出的確認信息,則會把消息轉發給其餘保持在線的消費者。
9. Collection
- List接口:
- arrayList:底層實現基於動態數組,隨機的訪問查詢比較快,插入,刪除,修改比較慢,線程不安全。
- LinkedList 底層實現基於鏈表,因此查詢慢,修改,刪除,插入快,線程不安全。
- Vector :也是基於數組實現的,和arrayList的區別是線程安全,效率低。
- Set接口:不可重複
- HashSet: 使用哈希算法去重複, 效率高
- LinkedHashSet: HashSet的子類, 去重複而且保留存儲順序
- TreeSet: 能夠用指定的比較方法進行排序