【大廠面試】美團二面面經,最後竟然有驚喜?

程式設計師大彬發表於2022-02-23

本期是【大廠面試】系列文章的第4期,題目出自美團到店二面。

面試現場

面試官首先你來講講程式和執行緒有什麼區別?

獨白:老八股文了哈哈

大彬:程式是系統進行資源分配和排程的獨立單位,每一個程式都有自己的記憶體空間和系統資源

大彬:執行緒是程式的一個實體,是CPU排程和分派的基本單位,它是比程式更小的能獨立執行的基本單位

大彬:多執行緒是實現併發機制的一個有效手段。程式和執行緒一樣都是實現併發的基本單位

面試官那為什麼要用多執行緒呢?

獨白:嘿嘿,這個簡單

大彬:使用多執行緒最主要的原因是提高系統的資源利用率。

大彬:多個執行緒同時執行,可以減少執行緒上下文切換的開銷,提高併發的能力和CPU的利用效率。

大彬:在平時工作中多執行緒也是常見的。比如Tomcat每處理一個請求都會從執行緒連線池裡取一個執行緒去處理。

面試官嗯,平時在使用多執行緒的時候,可能會遇到執行緒安全的問題吧。講講什麼是執行緒安全?

大彬:我是這麼理解的,當多個執行緒訪問一個物件時,如果不用考慮這些執行緒在執行時環境下的排程和交替執行,也不需要進行額外的同步,呼叫這個物件的行為都可以獲得正確的結果,那這個物件就是執行緒安全的。

面試官那你平時怎麼處理執行緒安全問題的?

大彬:這個還得具體問題具體分析。首先判斷有沒有執行緒安全問題,若有則根據具體的情況去處理執行緒安全的問題。

大彬:比如涉及到操作的原子性,可以考慮使用atomic包下的原子類。

大彬:如果涉及到對執行緒的控制,可以考慮執行緒工具類CountDownLatch/Semaphore等等。

大彬:集合類的話,考慮java.util.concurrent包下的集合類。

大彬:還有synchronizedlock包下的類,redis分散式鎖等。

面試官嗯哼,剛提到Redis分散式鎖,你覺得什麼場景下需要使用分散式鎖呢?

大彬:在單機環境下,執行緒安全問題可以通過ReentrantLocksynchronized 以及 concurrent 併發包下一些執行緒安全的類等來避免。

大彬:而在多機部署環境,需要在多程式下保證執行緒的安全性,Java提供的這些API僅能保證在單個JVM程式內對多執行緒訪問共享資源的執行緒安全,已經不滿足需求了。這時候就需要使用分散式鎖來保證執行緒安全。

大彬:Redis 2.6.12 之前的版本中採用 setnx + expire 方式實現分散式鎖。在 Redis 2.6.12 版本後 setnx 增加了過期時間引數,只需要使用setnx就可以實現分散式鎖了。

面試官那再講講Redis分散式鎖的原理?

獨白:面試造火箭,入職擰螺絲?

大彬:首先介紹下Redis的加鎖邏輯。

大彬setnx爭搶key的鎖,如果已有key存在,則不作操作,過段時間繼續重試,保證只有一個客戶端能持有鎖。

大彬:value設定為 requestId(可以使用機器ip拼接當前執行緒名稱),表示這把鎖是哪個請求加的,在解鎖的時候需要判斷當前請求是否持有鎖,防止誤解鎖。比如客戶端A加鎖,在執行解鎖之前,鎖過期了,此時客戶端B嘗試加鎖成功,然後客戶端A再執行del()方法,則將客戶端B的鎖給解除了。

大彬:再用expire給鎖加一個過期時間,防止異常導致鎖沒有釋放。

大彬:然後是解鎖邏輯。

大彬:首先獲取鎖對應的value值,檢查是否與requestId相等,如果相等則刪除鎖。使用lua指令碼實現原子操作,保證執行緒安全。

面試官不錯,看你簡歷上寫了熟悉TCP,來介紹下TCP四次揮手?

獨白:嗯,這個嘛,很熟悉

大彬:假設A是client端,B是server端。

  1. 首先A的應用程式先向其TCP發出連線釋放報文段(FIN=1,seq=u),並停止再傳送資料,主動關閉TCP連線,進入FIN-WAIT-1(終止等待1)狀態,等待B的確認。
  2. B收到連線釋放報文段後即發出確認報文段(ACK=1,ack=u+1,seq=v),B進入CLOSE-WAIT(關閉等待)狀態,此時的TCP處於半關閉狀態,A到B的連線釋放。
  3. A收到B的確認後,進入FIN-WAIT-2(終止等待2)狀態,等待B發出的連線釋放報文段。
  4. B傳送完資料,就會發出連線釋放報文段(FIN=1,ACK=1,seq=w,ack=u+1),B進入LAST-ACK(最後確認)狀態,等待A的確認。
  5. A收到B的連線釋放報文段後,對此發出確認報文段(ACK=1,seq=u+1,ack=w+1),A進入TIME-WAIT(時間等待)狀態。此時TCP未釋放掉,需要經過時間等待計時器設定的時間2MSL(最大報文段生存時間)後,A才進入CLOSED狀態。B收到A發出的確認報文段後關閉連線,若沒收到A發出的確認報文段,B就會重傳連線釋放報文段。

面試官建立連線時三次握手,為什麼連線釋放要四次揮手,三次不行嗎?

大彬:因為建立連線時,當Server端收到Client端的SYN連線請求報文後,可以直接傳送SYN+ACK報文。

大彬但是在關閉連線時,當Server端收到Client端發出的連線釋放報文時,很可能並不會立即關閉SOCKET,所以Server端先回復一個ACK報文,告訴Client端我收到你的連線釋放報文了。只有等到Server端所有的報文都傳送完了,這時Server端才能傳送連線釋放報文,之後兩邊才會真正的斷開連線。故需要四次揮手。

面試官嗯,你瞭解https嗎?https是為了解決什麼問題?

獨白:一點也不慌哈哈

大彬:HTTP是明文傳輸,容易被黑客竊聽或篡改,不安全。

大彬: HTTPS 主要解決了 HTTP 明文協議的缺陷,在 HTTP 的基礎上加入 SSL/TLS 協議,依靠 SSL 證照來驗證伺服器的身份,為客戶端和伺服器端之間建立SSL通道,確保資料傳輸安全。

面試官:那http跟https具體有什麼區別呢?

大彬:http和https的區別如下:

  1. HTTP是超文字傳輸協議,資訊是明文傳輸;HTTPS則是具有安全性的ssl加密傳輸協議。
  2. HTTP和HTTPS用的埠不一樣,HTTP埠是80,HTTPS是443。
  3. HTTPS協議需要到CA機構申請證照,一般需要一定的費用。
  4. HTTP執行在TCP協議之上;HTTPS執行在SSL協議之上,SSL執行在TCP協議之上。

面試官不錯,再來問點MySQL相關的

面試官什麼情況下索引會失效?

大彬:主要有這麼幾種情況會導致索引失效。

  • 對於組合索引,不是使用組合索引最左邊的欄位,則不會使用索引
  • 以%開頭的like查詢如%abc,無法使用索引;非%開頭的like查詢如abc%,相當於範圍查詢,會使用索引
  • 查詢條件中列型別是字串,沒有使用引號,可能會因為型別不同發生隱式轉換,使索引失效
  • 判斷索引列是否不等於某個值時
  • 對索引列進行運算
  • 查詢條件使用or連線,也會導致索引失效

面試官:很好,明天能入職嗎?

獨白:馬甲頭盔箱子三件套?

相關文章