不甘示弱,我們也新招6000人!
共 8844字,需瀏覽 18分鐘
·
2024-07-28 14:04
大家好,我是二哥呀。
25 屆秋招正式批是說來就來啊,這不京東官宣要招聘 16000 人,美團這邊也不甘示弱,表示要新招 6000 人,于 7 月 29 日正式開啟,比京東還早 2 天。
美團去年就招了 6000 人,今年人數(shù)雖然沒有上漲,但也算是穩(wěn)打穩(wěn)扎了。并且美團的薪資待遇也不錯。人才們,請抓緊時間沖吧(??)。
大家可以先瞅一眼 24 屆美團的薪資待遇,211 本也能拿到 21k 的白菜,一年 33 萬朝上的年包很香了(15.5 個月)。星球里去年有球友拿到團子的 SSP offer,薪資就可觀到只能保密。
應該有不少小伙伴對美團很感興趣,那接下來我們就以《Java 面試指南》里收錄的《美團面經(jīng)同學3 Java 一面》為例,來看看開水團的面試官都喜歡問哪些問題,好為今年的秋招做個模擬。
1、二哥修訂版《30天速通Java.pdf》下載 2、三分惡面渣逆襲在線版:https://javabetter.cn/sidebar/sanfene/nixi.html
美團同學3 Java 一面面經(jīng)
一些常見的八股這里就不貼答案了,大家直接去看《面渣逆襲》在線版,我在每道題下面都會標記清楚。
java的反射機制,反射的應用場景AOP的實現(xiàn)原理是什么,與動態(tài)代理和反射有什么區(qū)別
反射允許 Java 在運行時檢查和操作類的方法和字段。通過反射,可以動態(tài)地獲取類的字段、方法、構(gòu)造方法等信息,并在運行時調(diào)用方法或訪問字段。
反射有哪些應用場景?
①、Spring 框架就大量使用了反射來動態(tài)加載和管理 Bean。
Class<?> clazz = Class.forName("com.example.MyClass");
Object instance = clazz.newInstance();
②、Java 的動態(tài)代理(Dynamic Proxy)機制就使用了反射來創(chuàng)建代理類。代理類可以在運行時動態(tài)處理方法調(diào)用,這在實現(xiàn) AOP 和攔截器時非常有用。
InvocationHandler handler = new MyInvocationHandler();
MyInterface proxyInstance = (MyInterface) Proxy.newProxyInstance(
MyInterface.class.getClassLoader(),
new Class<?>[] { MyInterface.class },
handler
);
AOP 的實現(xiàn)原理是什么?
Spring 的 AOP 是通過動態(tài)代理來實現(xiàn)的,動態(tài)代理主要有兩種方式:JDK 動態(tài)代理和 CGLIB 代理。
①、JDK 動態(tài)代理是基于接口的代理,只能代理實現(xiàn)了接口的類。使用 JDK 動態(tài)代理時,Spring AOP 會創(chuàng)建一個代理對象,該代理對象實現(xiàn)了目標對象所實現(xiàn)的接口,并在方法調(diào)用前后插入橫切邏輯。
②、CGLIB 動態(tài)代理是基于繼承的代理,可以代理沒有實現(xiàn)接口的類。使用 CGLIB 動態(tài)代理時,Spring AOP 會生成目標類的子類,并在方法調(diào)用前后插入橫切邏輯。
說說 AOP 和反射的區(qū)別?
-
反射:用于檢查和操作類的方法和字段,動態(tài)調(diào)用方法或訪問字段。反射是 Java 提供的內(nèi)置機制,直接操作類對象。 -
動態(tài)代理:通過生成代理類來攔截方法調(diào)用,通常用于 AOP 實現(xiàn)。動態(tài)代理使用反射來調(diào)用被代理的方法。
object有哪些方法 hashcode和equals為什么需要一起重寫 不重寫會導致哪些問題 什么時候會用到重寫hashcode的場景
Object 主要提供了 11 個方法,大致可以分為六類:
為什么重寫 equals 時必須重寫 hashCode ?法?
因為基于哈希的集合類(如 HashMap)需要基于這一點來正確存儲和查找對象。
具體地說,HashMap 通過對象的哈希碼將其存儲在不同的“桶”中,當查找對象時,它需要使用 key 的哈希碼來確定對象在哪個桶中,然后再通過 equals() 方法找到對應的對象。
如果重寫了 equals()方法而沒有重寫 hashCode()方法,那么被認為相等的對象可能會有不同的哈希碼,從而導致無法在HashMap 中正確處理這些對象。
最左匹配原則 索引失效
最左前綴原則,也叫最左匹配原則,或者最左前綴匹配原則。
最左匹配原則是指在使用聯(lián)合索引(即包含多列的索引)時,查詢條件從索引的最左列開始并且不跳過中間的列。
如果一個復合索引包含(col1, col2, col3),那么它可以支持 col1、col1,col2 和 col1, col2, col3 的查詢優(yōu)化,但不會優(yōu)化只有 col2 或 col3 的查詢。
也就說,在進行查詢時,如果沒有遵循最左前綴,那么索引可能不會被利用,導致查詢效率降低。
索引失效的場景
-
在索引列上使用函數(shù)或表達式:如果在查詢中對索引列使用了函數(shù)或表達式,那么索引可能無法使用,因為數(shù)據(jù)庫無法預先計算出函數(shù)或表達式的結(jié)果。例如: SELECT * FROM table WHERE YEAR(date_column) = 2021。 -
使用不等于( <>)或者 NOT 操作符:這些操作符通常會使索引失效,因為它們會掃描全表。 -
使用 LIKE 操作符,但是通配符在最前面:如果 LIKE 的模式串是以“%”或者“_”開頭的,那么索引也無法使用。例如: SELECT * FROM table WHERE column LIKE '%abc'。 -
OR 操作符:如果查詢條件中使用了 OR,并且 OR 兩邊的條件分別涉及不同的索引,那么這些索引可能都無法使用。 -
聯(lián)合索引不滿足最左前綴原則時,索引會失效。
線程池怎么設(shè)計,拒絕策略有哪些,如何選擇
線程池的設(shè)計需要考慮這幾個關(guān)鍵因素:
-
核心線程池類:包含核心線程數(shù)、最大線程數(shù)。 -
工作線程:線程池中實際工作的線程,從任務隊列中獲取任務并執(zhí)行。 -
任務隊列:存放待執(zhí)行任務的隊列,可以使用阻塞隊列實現(xiàn)。 -
拒絕策略:當任務隊列滿時,處理新任務的策略。
小二去銀行辦理業(yè)務,被經(jīng)理“薄紗”了:“我們系統(tǒng)癱瘓了”、“誰叫你來辦的你找誰去”、“看你比較急,去隊里加個塞”、“今天沒辦法,不行你看改一天”。
分別對應線程池中的四種拒絕策略:
-
AbortPolicy:這是默認的拒絕策略。該策略會拋出一個 RejectedExecutionException 異常。也就對應著“我們系統(tǒng)癱瘓了”。 -
CallerRunsPolicy:該策略不會拋出異常,而是會讓提交任務的線程(即調(diào)用 execute 方法的線程)自己來執(zhí)行這個任務。也就對應著“誰叫你來辦的你找誰去”。 -
DiscardOldestPolicy:策略會丟棄隊列中最老的一個任務(即隊列中等待最久的任務),然后嘗試重新提交被拒絕的任務。也就對應著“看你比較急,去隊里加個塞”。 -
DiscardPolicy:策略會默默地丟棄被拒絕的任務,不做任何處理也不拋出異常。也就對應著“今天沒辦法,不行你看改一天”。
jmm內(nèi)存模型 棧 方法區(qū)存放的是什么
Java 內(nèi)存模型(Java Memory Model)是一種抽象的模型,簡稱 JMM,主要用來定義多線程中變量的訪問規(guī)則,用來解決變量的可見性、有序性和原子性問題,確保在并發(fā)環(huán)境中安全地訪問共享變量。
JMM 定義了線程內(nèi)存和主內(nèi)存之間的抽象關(guān)系:線程之間的共享變量存儲在主內(nèi)存(Main Memory)中,每個線程都有一個私有的本地內(nèi)存(Local Memory),本地內(nèi)存中存儲了共享變量的副本,用來進行線程內(nèi)部的讀寫操作。
-
當一個線程更改了本地內(nèi)存中共享變量的副本后,它需要將這些更改刷新到主內(nèi)存中,以確保其他線程可以看到這些更改。 -
當一個線程需要讀取共享變量時,它可能首先從本地內(nèi)存中讀取。如果本地內(nèi)存中的副本是過時的,線程將從主內(nèi)存中重新加載共享變量的最新值到本地內(nèi)存中。
介紹一下 Java 虛擬機棧?
Java 虛擬機棧(Java Virtual Machine Stack),通常指的就是“棧”,它的生命周期與線程相同。
當線程執(zhí)行一個方法時,會創(chuàng)建一個對應的棧幀,用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息,然后棧幀會被壓入棧中。當方法執(zhí)行完畢后,棧幀會從棧中移除。
介紹一下方法區(qū)?
方法區(qū)并不真實存在,屬于 Java 虛擬機規(guī)范中的一個邏輯概念,用于存儲已被 JVM 加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼緩存等。
在 HotSpot 虛擬機中,方法區(qū)的實現(xiàn)稱為永久代(PermGen),但在 Java 8 及之后的版本中,已經(jīng)被元空間(Metaspace)所替代。
如何判斷sql的效率,怎樣排查效率比較低的sql
排查 SQL 效率主要通過兩種手段:
-
慢查詢?nèi)罩?/strong>:開啟 MySQL 慢查詢?nèi)罩?,再通過一些工具比如 mysqldumpslow 去分析對應的慢查詢?nèi)罩荆页鰡栴}的根源。 -
服務監(jiān)控:可以在業(yè)務的基建中加入對慢 SQL 的監(jiān)控,常見的方案有字節(jié)碼插樁、連接池擴展、ORM 框架過程,對服務運行中的慢 SQL 進行監(jiān)控和告警。
也可以使用 show processlist; 查看當前正在執(zhí)行的 SQL 語句,找出執(zhí)行時間較長的 SQL。
找到對應的慢 SQL 后,使用 EXPLAIN 命令查看 MySQL 是如何執(zhí)行 SQL 語句的,再根據(jù)執(zhí)行計劃對 SQL 進行優(yōu)化。
EXPLAIN SELECT * FROM your_table WHERE conditions;
如何保證redis緩存與數(shù)據(jù)庫的一致性,為什么這么設(shè)計
在技術(shù)派實戰(zhàn)項目中,我采用的是先寫 MySQL,再刪除 Redis 的方式來保證緩存和數(shù)據(jù)庫的數(shù)據(jù)一致性。
對于第一次查詢,請求 B 查詢到的緩存數(shù)據(jù)是 10,但 MySQL 被請求 A 更新為了 11,此時數(shù)據(jù)庫和緩存不一致。
但也只存在這一次不一致的情況,對于不是強一致性的業(yè)務,可以容忍。
當請求 B 第二次查詢時,因為請求 A 更新完數(shù)據(jù)庫把緩存刪除了,所以請求 B 這次不會命中緩存,會重新查一次 MySQL,然后回寫到 Redis。
緩存和數(shù)據(jù)庫又一致了。
java的類加載機制 雙親委派機制 這樣設(shè)計的原因是什么
JVM 的操作對象是 Class 文件,JVM 把 Class 文件中描述類的數(shù)據(jù)結(jié)構(gòu)加載到內(nèi)存中,并對數(shù)據(jù)進行校驗、解析和初始化,最終形成可以被 JVM 直接使用的類型,這個過程被稱為類加載機制。
其中最重要的三個概念就是:類加載器、類加載過程和類加載器的雙親委派模型。
-
類加載器:負責加載類文件,將類文件加載到內(nèi)存中,生成 Class 對象。 -
類加載過程:加載、驗證、準備、解析和初始化。 -
雙親委派模型:當一個類加載器收到類加載請求時,它首先不會自己去嘗試加載這個類,而是把請求委派給父類加載器去完成,依次遞歸,直到最頂層的類加載器,如果父類加載器無法完成加載請求,子類加載器才會嘗試自己去加載。
為什么要用雙親委派模型?
可以為 Java 應用程序的運行提供一致性和安全性的保障。
①、保證 Java 核心類庫的類型安全
如果自定義類加載器優(yōu)先加載一個類,比如說自定義的 Object,那在 Java 運行時環(huán)境中就存在多個版本的 java.lang.Object,雙親委派模型確保了 Java 核心類庫的類加載工作由啟動類加載器統(tǒng)一完成,從而保證了 Java 應用程序都是使用的同一份核心類庫。
②、避免類的重復加載
在雙親委派模型中,類加載器會先委托給父加載器嘗試加載類,這樣同一個類不會被加載多次。如果沒有這種模型,可能會導致同一個類被不同的類加載器重復加載到內(nèi)存中,造成浪費和沖突。
https相比http有什么區(qū)別 對稱加密和非對稱加密 ca證書驗證
使用 HTTPS 主要是為了解決 HTTP 傳輸過程中的一些安全問題,因為 HTTP 是明文傳輸,所以 HTTPS 在 HTTP 的基礎(chǔ)上加入了 SSL/TLS 協(xié)議。
SSL(安全套接字)/TLS(傳輸層安全)協(xié)議可以用來加密通信內(nèi)容,保證通信過程中的數(shù)據(jù)不被竊取和篡改。整個加密過程主要涉及兩種類型的加密方法:
-
非對稱加密:服務器向客戶端發(fā)送公鑰,然后客戶端用公鑰加密自己的隨機密鑰,也就是會話密鑰,發(fā)送給服務器,服務器用私鑰解密,得到會話密鑰。 -
然后雙方用會話密鑰加密通信內(nèi)容。
客戶端會通過數(shù)字證書來驗證服務器的身份,數(shù)字證書由 CA(證書權(quán)威機構(gòu))簽發(fā),包含了服務器的公鑰、證書的頒發(fā)機構(gòu)、證書的有效期等信息。
數(shù)據(jù)庫中的全局鎖 表鎖 行級鎖 每種鎖的應用場景有哪些
全局鎖就是對整個數(shù)據(jù)庫實例進行加鎖,在 MySQL 中,可以使用 FLUSH TABLES WITH READ LOCK 命令來獲取全局讀鎖。
全局鎖的作用是保證在備份數(shù)據(jù)庫時,數(shù)據(jù)不會發(fā)生變化【數(shù)據(jù)更新語句(增刪改)、數(shù)據(jù)定義語句(建表、修改表結(jié)構(gòu)等)和更新事務的提交語句】。當我們需要備份數(shù)據(jù)庫時,可以先獲取全局讀鎖,然后再執(zhí)行備份操作。
表鎖(Table Lock)就是鎖住整個表。在 MySQL 中,可以使用 LOCK TABLES 命令來鎖定表。
表鎖可以分為讀鎖(共享鎖)和寫鎖(排他鎖)。
LOCK TABLES your_table READ;
-- 執(zhí)行讀操作
UNLOCK TABLES;
讀鎖允許多個事務同時讀取被鎖定的表,但不允許任何事務進行寫操作。
LOCK TABLES your_table WRITE;
-- 執(zhí)行寫操作
UNLOCK TABLES;
寫鎖允許一個事務對表進行讀寫操作,其他事務不能對該表進行任何操作(讀或?qū)懀?/p>
在進行大規(guī)模的數(shù)據(jù)導入、導出或刪除操作時,為了防止其他事務對數(shù)據(jù)進行并發(fā)操作,可以使用表鎖。
或者在進行表結(jié)構(gòu)變更(如添加列、修改列類型)時,為了確保變更期間沒有其他事務訪問或修改該表,可以使用表鎖。
說說 MySQL 的行鎖?
行級鎖(Row Lock)是數(shù)據(jù)庫鎖機制中最細粒度的鎖,主要用于對單行數(shù)據(jù)進行加鎖,以確保數(shù)據(jù)的一致性和完整性。
在 MySQL 中,InnoDB 存儲引擎支持行級鎖。通過 SELECT ... FOR UPDATE 可以加排他鎖,通過 LOCK IN SHARE MODE 可以加共享鎖。
比如說:
START TRANSACTION;
-- 加排他鎖,鎖定某一行
SELECT * FROM your_table WHERE id = 1 FOR UPDATE;
-- 對該行進行操作
UPDATE your_table SET column1 = 'new_value' WHERE id = 1;
COMMIT;
START TRANSACTION;
-- 加共享鎖,鎖定某一行
SELECT * FROM your_table WHERE id = 1 LOCK IN SHARE MODE;
-- 只能讀取該行,不能修改
COMMIT;
在高并發(fā)環(huán)境中,行級鎖能夠提高系統(tǒng)的并發(fā)性能,因為鎖定的粒度較小,只會鎖住特定的行,不會影響其他行的操作。
內(nèi)容來源
-
星球嘉賓三分惡的面渣逆襲:https://javabetter.cn/sidebar/sanfene/nixi.html -
二哥的 Java 進階之路(GitHub 已有 12000+star):https://javabetter.cn
ending
一個人可以走得很快,但一群人才能走得更遠。二哥的編程星球已經(jīng)有 5800 多名球友加入了,如果你也需要一個良好的學習環(huán)境,戳鏈接 ?? 加入我們吧。這是一個編程學習指南 + Java 項目實戰(zhàn) + LeetCode 刷題的私密圈子,你可以閱讀星球?qū)?、向二哥提問、幫你制定學習計劃、和球友一起打卡成長。
兩個置頂帖「球友必看」和「知識圖譜」里已經(jīng)沉淀了非常多優(yōu)質(zhì)的學習資源,相信能幫助你走的更快、更穩(wěn)、更遠。
歡迎點擊左下角閱讀原文了解二哥的編程星球,這可能是你學習求職路上最有含金量的一次點擊。
最后,把二哥的座右銘送給大家:沒有什么使我停留——除了目的,縱然岸旁有玫瑰、有綠蔭、有寧靜的港灣,我是不系之舟。共勉 ??。
