【備戰春招/秋招系列】美團面經總結基礎篇 (附詳解答案)

該文已加入開源文檔:JavaGuide(一份涵蓋大部分Java程序員所須要掌握的核心知識)。地址:github.com/Snailclimb/….php

騰訊雲熱門雲產品1折起,送13000元續費/升級大禮包:cloud.tencent.com/redirect.ph…前端

騰訊雲新用戶大額代金券:cloud.tencent.com/redirect.ph…java

系列文章:git

這是我總結的美團面經的基礎篇,後面還有進階和終結篇哦!下面只是我從不少份美團面經中總結的在面試中一些常見的問題。不一樣於我的面經,這份面經具備普適性。每次面試必備的自我介紹、項目介紹這些東西,你們能夠本身私下好好思考。我在前面的文章中也提到了應該怎麼作自我介紹與項目介紹,詳情能夠查看這篇文章:【備戰春招/秋招系列2】初出茅廬的程序員該如何準備面試?程序員

1. System.out.println(3 | 9);輸出什麼?

正確答案:11.github

考察知識點:邏輯運算符與(&和&&)或(|和||)面試

&和&&:spring

共同點:它們都表示運算符的兩邊都是true時,結果爲true;sql

不一樣點: & 表示在運算時兩邊都會計算,而後再判斷;&&表示先運算符號左邊的東西,而後判斷是否爲true,是true就繼續運算右邊的而後判斷並輸出,是false就停下來直接輸出不會再運行後面的東西。數據庫

|和||:

共同點:它們都表示運算符的兩邊任意一邊爲true,結果爲true,兩邊都不是true,結果就爲false;

不一樣點:| 表示兩邊都會運算,而後再判斷結果;|| 表示先運算符號左邊的東西,而後判斷是否爲true,是true就停下來直接輸出不會再運行後面的東西,是false就繼續運算右邊的而後判斷並輸出。

回到本題:

3 | 9=0011(二進制) | 1001(二進制)=1011(二進制)=11(十進制)

2. 說一下轉發(Forward)和重定向(Redirect)的區別

轉發是服務器行爲,重定向是客戶端行爲。

轉發(Forword) 經過RequestDispatcher對象的forward(HttpServletRequest request,HttpServletResponse response)方法實現的。RequestDispatcher 能夠經過HttpServletRequestgetRequestDispatcher()方法得到。例以下面的代碼就是跳轉到 login_success.jsp 頁面。

request.getRequestDispatcher("login_success.jsp").forward(request, response);
複製代碼

重定向(Redirect) 是利用服務器返回的狀態嗎來實現的。客戶端瀏覽器請求服務器的時候,服務器會返回一個狀態碼。服務器經過HttpServletRequestResponse的setStatus(int status)方法設置狀態碼。若是服務器返回301或者302,則瀏覽器會到新的網址從新請求該資源。

  1. 從地址欄顯示來講: forward是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,而後把這些內容再發給瀏覽器.瀏覽器根本不知道服務器發送的內容從哪裏來的,因此它的地址欄仍是原來的地址. redirect是服務端根據邏輯,發送一個狀態碼,告訴瀏覽器從新去請求那個地址.因此地址欄顯示的是新的URL.
  2. 從數據共享來講: forward:轉發頁面和轉發到的頁面能夠共享request裏面的數據. redirect:不能共享數據.
  3. 從運用地方來講: forward:通常用於用戶登錄的時候,根據角色轉發到相應的模塊. redirect:通常用於用戶註銷登錄時返回主頁面和跳轉到其它的網站等
  4. 從效率來講: forward:高. redirect:低.

3. 在瀏覽器中輸入url地址 ->> 顯示主頁的過程,整個過程會使用哪些協議

圖解(圖片來源:《圖解HTTP》):

狀態碼

整體來講分爲如下幾個過程:

  1. DNS解析
  2. TCP鏈接
  3. 發送HTTP請求
  4. 服務器處理請求並返回HTTP報文
  5. 瀏覽器解析渲染頁面
  6. 鏈接結束

具體能夠參考下面這篇文章:

4. TCP 三次握手和四次揮手

爲了準確無誤地把數據送達目標處,TCP協議採用了三次握手策略。

漫畫圖解:

圖片來源:《圖解HTTP》

TCP三次握手

簡單示意圖:

TCP三次握手

  • 客戶端–發送帶有 SYN 標誌的數據包–一次握手–服務端
  • 服務端–發送帶有 SYN/ACK 標誌的數據包–二次握手–客戶端
  • 客戶端–發送帶有帶有 ACK 標誌的數據包–三次握手–服務端

爲何要三次握手

三次握手的目的是創建可靠的通訊信道,說到通信,簡單來講就是數據的發送與接收,而三次握手最主要的目的就是雙方確認本身與對方的發送與接收是正常的。

第一次握手:Client 什麼都不能確認;Server 確認了對方發送正常,本身接收正常。

第二次握手:Client 確認了:本身發送、接收正常,對方發送、接收正常;Server 確認了:本身接收正常,對方發送正常

第三次握手:Client 確認了:本身發送、接收正常,對方發送、接收正常;Server 確認了:本身發送、接收正常,對方發送接收正常

因此三次握手就能確認雙發收發功能都正常,缺一不可。

爲何要傳回 SYN

接收端傳回發送端所發送的 SYN 是爲了告訴發送端,我接收到的信息確實就是你所發送的信號了。

SYN 是 TCP/IP 創建鏈接時使用的握手信號。在客戶機和服務器之間創建正常的 TCP 網絡鏈接時,客戶機首先發出一個 SYN 消息,服務器使用 SYN-ACK 應答表示接收到了這個消息,最後客戶機再以 ACK(Acknowledgement[漢譯:確認字符 ,在數據通訊傳輸中,接收站發給發送站的一種傳輸控制字符。它表示確認發來的數據已經接受無誤。 ])消息響應。這樣在客戶機和服務器之間才能創建起可靠的TCP鏈接,數據才能夠在客戶機和服務器之間傳遞。

傳了 SYN,爲啥還要傳 ACK

雙方通訊無誤必須是二者互相發送信息都無誤。傳了 SYN,證實發送方(主動關閉方)到接收方(被動關閉方)的通道沒有問題,可是接收方到發送方的通道還須要 ACK 信號來進行驗證。

TCP四次揮手

斷開一個 TCP 鏈接則須要「四次揮手」:

  • 客戶端-發送一個 FIN,用來關閉客戶端到服務器的數據傳送
  • 服務器-收到這個 FIN,它發回一 個 ACK,確認序號爲收到的序號加1 。和 SYN 同樣,一個 FIN 將佔用一個序號
  • 服務器-關閉與客戶端的鏈接,發送一個FIN給客戶端
  • 客戶端-發回 ACK 報文確認,並將確認序號設置爲收到序號加1

爲何要四次揮手

任何一方均可以在數據傳送結束後發出鏈接釋放的通知,待對方確認後進入半關閉狀態。當另外一方也沒有數據再發送的時候,則發出鏈接釋放通知,對方確認後就徹底關閉了TCP鏈接。

舉個例子:A 和 B 打電話,通話即將結束後,A 說「我沒啥要說的了」,B回答「我知道了」,可是 B 可能還會有要說的話,A 不能要求 B 跟着本身的節奏結束通話,因而 B 可能又巴拉巴拉說了一通,最後 B 說「我說完了」,A 回答「知道了」,這樣通話纔算結束。

上面講的比較歸納,推薦一篇講的比較細緻的文章:blog.csdn.net/qzcsu/artic…

5. IP地址與MAC地址的區別

參考:blog.csdn.net/guoweimelon…

IP地址是指互聯網協議地址(Internet Protocol Address)IP Address的縮寫。IP地址是IP協議提供的一種統一的地址格式,它爲互聯網上的每個網絡和每一臺主機分配一個邏輯地址,以此來屏蔽物理地址的差別。

MAC 地址又稱爲物理地址、硬件地址,用來定義網絡設備的位置。網卡的物理地址一般是由網卡生產廠家寫入網卡的,具備全球惟一性。MAC地址用於在網絡中惟一標示一個網卡,一臺電腦會有一或多個網卡,每一個網卡都須要有一個惟一的MAC地址。

6. HTTP請求、響應報文格式

HTTP請求報文主要由請求行、請求頭部、請求正文3部分組成

HTTP響應報文主要由狀態行、響應頭部、響應正文3部分組成

詳細內容能夠參考:blog.csdn.net/a19881029/a…

7. 爲何要使用索引?索引這麼多優勢,爲何不對錶中的每個列建立一個索引呢?索引是如何提升查詢速度的?說一下使用索引的注意事項?Mysql索引主要使用的兩種數據結構?什麼是覆蓋索引?

爲何要使用索引?

  1. 經過建立惟一性索引,能夠保證數據庫表中每一行數據的惟一性。
  2. 能夠大大加快 數據的檢索速度(大大減小的檢索的數據量), 這也是建立索引的最主要的緣由。
  3. 幫助服務器避免排序和臨時表
  4. 將隨機IO變爲順序IO
  5. 能夠加速表和表之間的鏈接,特別是在實現數據的參考完整性方面特別有意義。

索引這麼多優勢,爲何不對錶中的每個列建立一個索引呢?

  1. 當對錶中的數據進行增長、刪除和修改的時候,索引也要動態的維護,這樣就下降了數據的維護速度。
  2. 索引須要佔物理空間,除了數據表佔數據空間以外,每個索引還要佔必定的物理空間,若是要創建聚簇索引,那麼須要的空間就會更大。
  3. 建立索引和維護索引要耗費時間,這種時間隨着數據量的增長而增長。

索引是如何提升查詢速度的?

將無序的數據變成相對有序的數據(就像查目錄同樣)

說一下使用索引的注意事項

  1. 避免 where 子句中對宇段施加函數,這會形成沒法命中索引。
  2. 在使用InnoDB時使用與業務無關的自增主鍵做爲主鍵,即便用邏輯主鍵,而不要使用業務主鍵。
  3. 將打算加索引的列設置爲 NOT NULL ,不然將致使引擎放棄使用索引而進行全表掃描
  4. 刪除長期未使用的索引,不用的索引的存在會形成沒必要要的性能損耗 MySQL 5.7 能夠經過查詢 sys 庫的 chema_unused_indexes 視圖來查詢哪些索引從未被使用
  5. 在使用 limit offset 查詢緩慢時,能夠藉助索引來提升性能

Mysql索引主要使用的哪兩種數據結構?

  • 哈希索引:對於哈希索引來講,底層的數據結構就是哈希表,所以在絕大多數需求爲單條記錄查詢的時候,能夠選擇哈希索引,查詢性能最快;其他大部分場景,建議選擇BTree索引。
  • BTree索引:Mysql的BTree索引使用的是B樹中的B+Tree。但對於主要的兩種存儲引擎(MyISAM和InnoDB)的實現方式是不一樣的。

更多關於索引的內容能夠查看個人這篇文章:【思惟導圖-索引篇】搞定數據庫索引就是這麼簡單

什麼是覆蓋索引?

若是一個索引包含(或者說覆蓋)全部須要查詢的字段的值,咱們就稱 之爲「覆蓋索引」。咱們知道在InnoDB存儲引擎中,若是不是主鍵索引,葉子節點存儲的是主鍵+列值。最終仍是要「回表」,也就是要經過主鍵再查找一次,這樣就會比較慢。覆蓋索引就是把要查詢出的列和索引是對應的,不作回表操做!

8. 進程與線程的區別是什麼?進程間的幾種通訊方式說一下?線程間的幾種通訊方式知道不?

進程與線程的區別是什麼?

線程與進程類似,但線程是一個比進程更小的執行單位。一個進程在其執行的過程當中能夠產生多個線程。與進程不一樣的是同類的多個線程共享同一塊內存空間和一組系統資源,因此係統在產生一個線程,或是在各個線程之間做切換工做時,負擔要比進程小得多,也正由於如此,線程也被稱爲輕量級進程。另外,也正是由於共享資源,因此線程中執行時通常都要進行同步和互斥。總的來講,進程和線程的主要差異在於它們是不一樣的操做系統資源管理方式。

進程間的幾種通訊方式說一下?

  1. 管道(pipe):管道是一種半雙工的通訊方式,數據只能單向流動,並且只能在具備血緣關係的進程間使用。進程的血緣關係一般指父子進程關係。管道分爲pipe(無名管道)和fifo(命名管道)兩種,有名管道也是半雙工的通訊方式,可是它容許無親緣關係進程間通訊。
  2. 信號量(semophore):信號量是一個計數器,能夠用來控制多個進程對共享資源的訪問。它一般做爲一種鎖機制,防止某進程正在訪問共享資源時,其餘進程也訪問該資源。所以,主要做爲進程間以及同一進程內不一樣線程之間的同步手段。
  3. 消息隊列(message queue):消息隊列是由消息組成的鏈表,存放在內核中 並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少,管道只能承載無格式字節流以及緩衝區大小受限等缺點。消息隊列與管道通訊相比,其優點是對每一個消息指定特定的消息類型,接收的時候不須要按照隊列次序,而是能夠根據自定義條件接收特定類型的消息。
  4. 信號(signal):信號是一種比較複雜的通訊方式,用於通知接收進程某一事件已經發生。
  5. 共享內存(shared memory):共享內存就是映射一段能被其餘進程所訪問的內存,這段共享內存由一個進程建立,但多個進程均可以訪問,共享內存是最快的IPC方式,它是針對其餘進程間的通訊方式運行效率低而專門設計的。它每每與其餘通訊機制,如信號量配合使用,來實現進程間的同步和通訊。
  6. 套接字(socket):套接口也是一種進程間的通訊機制,與其餘通訊機制不一樣的是它能夠用於不一樣及其間的進程通訊。

線程間的幾種通訊方式知道不?

一、鎖機制

  • 互斥鎖:提供了以排它方式阻止數據結構被併發修改的方法。
  • 讀寫鎖:容許多個線程同時讀共享數據,而對寫操做互斥。
  • 條件變量:能夠以原子的方式阻塞進程,直到某個特定條件爲真爲止。對條件測試是在互斥鎖的保護下進行的。條件變量始終與互斥鎖一塊兒使用。

二、信號量機制:包括無名線程信號量與有名線程信號量

三、信號機制:相似於進程間的信號處理。

線程間通訊的主要目的是用於線程同步,因此線程沒有象進程通訊中用於數據交換的通訊機制。

9. 爲何要用單例模式?手寫幾種線程安全的單例模式?

簡單來講使用單例模式能夠帶來下面幾個好處:

  • 對於頻繁使用的對象,能夠省略建立對象所花費的時間,這對於那些重量級對象而言,是很是可觀的一筆系統開銷;
  • 因爲 new 操做的次數減小,於是對系統內存的使用頻率也會下降,這將減輕 GC 壓力,縮短 GC 停頓時間。

懶漢式(雙重檢查加鎖版本)

public class Singleton {

    //volatile保證,當uniqueInstance變量被初始化成Singleton實例時,多個線程能夠正確處理uniqueInstance變量
    private volatile static Singleton uniqueInstance;
    private Singleton() {
    }
    public static Singleton getInstance() {
       //檢查實例,若是不存在,就進入同步代碼塊
        if (uniqueInstance == null) {
            //只有第一次才完全執行這裏的代碼
            synchronized(Singleton.class) {
               //進入同步代碼塊後,再檢查一次,若是還是null,才建立實例
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}
複製代碼

靜態內部類方式

靜態內部實現的單例是懶加載的且線程安全。

只有經過顯式調用 getInstance 方法時,纔會顯式裝載 SingletonHolder 類,從而實例化 instance(只有第一次使用這個單例的實例的時候才加載,同時不會有線程安全問題)。

public class Singleton {  
    private static class SingletonHolder {  
    private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
    return SingletonHolder.INSTANCE;  
    }  
}   
複製代碼

10. 簡單介紹一下bean。知道Spring的bean的做用域與生命週期嗎?

在 Spring 中,那些組成應用程序的主體及由 Spring IOC 容器所管理的對象,被稱之爲 bean。簡單地講,bean 就是由 IOC 容器初始化、裝配及管理的對象,除此以外,bean 就與應用程序中的其餘對象沒有什麼區別了。而 bean 的定義以及 bean 相互間的依賴關係將經過配置元數據來描述。

Spring中的bean默認都是單例的,這些單例Bean在多線程程序下如何保證線程安全呢? 例如對於Web應用來講,Web容器對於每一個用戶請求都建立一個單獨的Sevlet線程來處理請求,引入Spring框架以後,每一個Action都是單例的,那麼對於Spring託管的單例Service Bean,如何保證其安全呢? Spring的單例是基於BeanFactory也就是Spring容器的,單例Bean在此容器內只有一個,Java的單例是基於 JVM,每一個 JVM 內只有一個實例。

pring的bean的做用域

Spring的bean的生命週期以及更多內容能夠查看:一文輕鬆搞懂Spring中bean的做用域與生命週期

11. Spring 中的事務傳播行爲了解嗎?TransactionDefinition 接口中哪五個表示隔離級別的常量?

事務傳播行爲

事務傳播行爲(爲了解決業務層方法之間互相調用的事務問題): 當事務方法被另外一個事務方法調用時,必須指定事務應該如何傳播。例如:方法可能繼續在現有事務中運行,也可能開啓一個新事務,並在本身的事務中運行。在TransactionDefinition定義中包括了以下幾個表示傳播行爲的常量:

支持當前事務的狀況:

  • TransactionDefinition.PROPAGATION_REQUIRED: 若是當前存在事務,則加入該事務;若是當前沒有事務,則建立一個新的事務。
  • TransactionDefinition.PROPAGATION_SUPPORTS: 若是當前存在事務,則加入該事務;若是當前沒有事務,則以非事務的方式繼續運行。
  • TransactionDefinition.PROPAGATION_MANDATORY: 若是當前存在事務,則加入該事務;若是當前沒有事務,則拋出異常。(mandatory:強制性)

不支持當前事務的狀況:

  • TransactionDefinition.PROPAGATION_REQUIRES_NEW: 建立一個新的事務,若是當前存在事務,則把當前事務掛起。
  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事務方式運行,若是當前存在事務,則把當前事務掛起。
  • TransactionDefinition.PROPAGATION_NEVER: 以非事務方式運行,若是當前存在事務,則拋出異常。

其餘狀況:

  • TransactionDefinition.PROPAGATION_NESTED: 若是當前存在事務,則建立一個事務做爲當前事務的嵌套事務來運行;若是當前沒有事務,則該取值等價於TransactionDefinition.PROPAGATION_REQUIRED。

隔離級別

TransactionDefinition 接口中定義了五個表示隔離級別的常量:

  • TransactionDefinition.ISOLATION_DEFAULT: 使用後端數據庫默認的隔離級別,Mysql 默認採用的 REPEATABLE_READ隔離級別 Oracle 默認採用的 READ_COMMITTED隔離級別.
  • TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔離級別,容許讀取還沒有提交的數據變動,可能會致使髒讀、幻讀或不可重複讀
  • TransactionDefinition.ISOLATION_READ_COMMITTED: 容許讀取併發事務已經提交的數據,能夠阻止髒讀,可是幻讀或不可重複讀仍有可能發生
  • TransactionDefinition.ISOLATION_REPEATABLE_READ: 對同一字段的屢次讀取結果都是一致的,除非數據是被自己事務本身所修改,能夠阻止髒讀和不可重複讀,但幻讀仍有可能發生。
  • TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔離級別,徹底服從ACID的隔離級別。全部的事務依次逐個執行,這樣事務之間就徹底不可能產生干擾,也就是說,該級別能夠防止髒讀、不可重複讀以及幻讀。可是這將嚴重影響程序的性能。一般狀況下也不會用到該級別。

12. SpringMVC 原理了解嗎?

SpringMVC 原理

客戶端發送請求-> 前端控制器 DispatcherServlet 接受客戶端請求 -> 找處處理器映射 HandlerMapping 解析請求對應的 Handler-> HandlerAdapter 會根據 Handler 來調用真正的處理器開處理請求,並處理相應的業務邏輯 -> 處理器返回一個模型視圖 ModelAndView -> 視圖解析器進行解析 -> 返回一個視圖對象->前端控制器 DispatcherServlet 渲染數據(Moder)->將獲得視圖對象返回給用戶

關於 SpringMVC 原理更多內容能夠查看個人這篇文章:SpringMVC 工做原理詳解

13. Spring AOP IOC 實現原理

過了秋招挺長一段時間了,說實話我本身也忘了如何簡要歸納 Spring AOP IOC 實現原理,就在網上找了一個較爲簡潔的答案,下面分享給各位。

IOC: 控制反轉也叫依賴注入。IOC利用java反射機制,AOP利用代理模式。IOC 概念看似很抽象,可是很容易理解。說簡單點就是將對象交給容器管理,你只須要在spring配置文件中配置對應的bean以及設置相關的屬性,讓spring容器來生成類的實例對象以及管理對象。在spring容器啓動的時候,spring會把你在配置文件中配置的bean都初始化好,而後在你須要調用的時候,就把它已經初始化好的那些bean分配給你須要調用這些bean的類。

AOP: 面向切面編程。(Aspect-Oriented Programming) 。AOP能夠說是對OOP的補充和完善。OOP引入封裝、繼承和多態性等概念來創建一種對象層次結構,用以模擬公共行爲的一個集合。實現AOP的技術,主要分爲兩大類:一是採用動態代理技術,利用截取消息的方式,對該消息進行裝飾,以取代原有對象行爲的執行;二是採用靜態織入的方式,引入特定的語法建立「方面」,從而使得編譯器能夠在編譯期間織入有關「方面」的代碼,屬於靜態代理。

你若怒放,清風自來。 歡迎關注個人微信公衆號:「Java面試通關手冊」,一個有溫度的微信公衆號。公衆號後臺回覆關鍵字「1」,能夠免費獲取一份我精心準備的小禮物哦!

相關文章
相關標籤/搜索