推薦一家小而美的互聯(lián)網(wǎng)獨(dú)角獸
共 7160字,需瀏覽 15分鐘
·
2024-08-16 14:04
大家好,我是二哥呀。
今天給大家推薦一家小而美的互聯(lián)網(wǎng)獨(dú)角獸——收錢吧,之所以用“小”這個字,并不是因為企業(yè)規(guī)模小,而是相對于京東的 16000 人,收錢吧 25 屆只有 100+ HC。
之所以用“美”這個字,是因為據(jù)收錢吧的同學(xué) fish09 反饋,在收錢吧的工作壓力不大,算是個幸??鞓返牡胤剑?/p>
-
年輕人特別多,80% 都是 95 后,充滿活力和激情。隨便問一個收錢吧的人對公司的印象,10 個有 9 個說氛圍好。 -
收錢吧屬于行業(yè)獨(dú)角獸,是國內(nèi)領(lǐng)先的數(shù)字化門店綜合服務(wù)商,行業(yè)第一。
那就必須得推薦給大家試一試,畢竟好公司不多,最好提前上車然后把車門焊死(??),哦不,提前上車感受收錢吧辦公大廈的人性化,據(jù)說每一層的裝修風(fēng)格都不一樣:賽博朋克、盛唐、摩洛哥等。
“畢竟一個希望所有人都能一起賺錢的公司能有什么壞心思?!?from ??偷?fish09。
那今天我們就以《Java 面試指南》中收錄的《收錢吧面經(jīng)同學(xué) 1 技術(shù)一面》為例,來看看收錢吧的面試官都喜歡問哪些問題,好做到心中有數(shù),面試不慌(??)。
能看得出來,面試內(nèi)容仍然是圍繞著二哥一直強(qiáng)調(diào)的 Java 后端四大件展開,所以準(zhǔn)備面試的小伙伴一定要有的放矢,這樣才能事半功倍。(面上了記得來給我報喜哦,我想臉上貼貼金 dog)
1、《30天速通Java.pdf》下載 2、三分惡面渣逆襲在線版:https://javabetter.cn/sidebar/sanfene/nixi.html
收錢吧同學(xué)1 技術(shù)一面面經(jīng)
一些常見的八股這里就不貼答案了,大家直接去看《面渣逆襲》在線版,我在每道題下面都會標(biāo)記清楚。
系統(tǒng)里面分布式鎖是怎么做的?
主要通過 Redisson 框架實現(xiàn)的 RedLock 來完成的。
// 創(chuàng)建 Redisson 客戶端配置
Config config = new Config();
config.useClusterServers()
.addNodeAddress("redis://127.0.0.1:6379",
"redis://127.0.0.1:6380",
"redis://127.0.0.1:6381"); // 假設(shè)有三個 Redis 節(jié)點(diǎn)
// 創(chuàng)建 Redisson 客戶端實例
RedissonClient redissonClient = Redisson.create(config);
// 創(chuàng)建 RedLock 對象
RLock redLock = redissonClient.getLock("lock_key");
try {
// 嘗試獲取分布式鎖,最多嘗試 5 秒獲取鎖,并且鎖的有效期為 5000 毫秒
boolean lockAcquired = redLock.tryLock(5, 5000, TimeUnit.MILLISECONDS);
if (lockAcquired) {
// 加鎖成功,執(zhí)行業(yè)務(wù)代碼...
} else {
System.out.println("Failed to acquire the lock!");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("Interrupted while acquiring the lock");
} finally {
// 無論是否成功獲取到鎖,在業(yè)務(wù)邏輯結(jié)束后都要釋放鎖
if (redLock.isLocked()) {
redLock.unlock();
}
// 關(guān)閉 Redisson 客戶端連接
redissonClient.shutdown();
}
你提到了redlock,那它機(jī)制是怎么樣的?
Redlock 是 Redis 作者提出的一種分布式鎖實現(xiàn)方案,用于確保在分布式環(huán)境下安全可靠地獲取鎖。它的目標(biāo)是在分布式系統(tǒng)中提供一種高可用、高容錯的鎖機(jī)制,確保在同一時刻,只有一個客戶端能夠成功獲得鎖,從而實現(xiàn)對共享資源的互斥訪問。
Redisson 中的 RedLock 是基于 RedissonMultiLock(聯(lián)鎖)實現(xiàn)的。
RedissonMultiLock 的 tryLock 方法會在指定的 Redis 實例上逐一嘗試獲取鎖。
在獲取鎖的過程中,Redlock 會根據(jù)配置的 waitTime(最大等待時間)和 leaseTime(鎖的持有時間)進(jìn)行靈活控制。比如,如果獲取鎖的時間小于鎖的有效期(通過TTL命令獲取鎖的剩余時間),則表示獲取鎖成功。
通常,至少需要多數(shù)(如 5 個實例中的 3 個)實例成功獲取鎖,才能認(rèn)為整個鎖獲取成功。
如果指定了鎖的持有時間(leaseTime),在成功獲取鎖后,Redlock 會為鎖進(jìn)行續(xù)期,以防止鎖在操作完成之前意外失效。
紅鎖能不能保證百分百上鎖?
Redlock 不能保證百分百上鎖,因為在分布式系統(tǒng)中,網(wǎng)絡(luò)延遲、時鐘漂移、Redis 實例宕機(jī)等因素都可能導(dǎo)致鎖的獲取失敗。
Redis解決單點(diǎn)故障主要靠什么?
主從復(fù)制,當(dāng)主節(jié)點(diǎn)發(fā)生故障時,可以通過手動或自動方式將某個從節(jié)點(diǎn)提升為新的主節(jié)點(diǎn),繼續(xù)對外提供服務(wù),從而避免單點(diǎn)故障。
Redis 的哨兵機(jī)制(Sentinel)可以實現(xiàn)自動化的故障轉(zhuǎn)移,當(dāng)主節(jié)點(diǎn)宕機(jī)時,哨兵會自動將一個從節(jié)點(diǎn)升級為新的主節(jié)點(diǎn)。
另外,集群模式下,當(dāng)某個節(jié)點(diǎn)發(fā)生故障時,Redis Cluster 會自動將請求路由到其他節(jié)點(diǎn),并通過從節(jié)點(diǎn)進(jìn)行故障恢復(fù)。
主從模式用的是異步還是同步?
在 Redis 主從架構(gòu)中,主節(jié)點(diǎn)負(fù)責(zé)處理所有的寫操作,并將這些操作異步復(fù)制到從節(jié)點(diǎn)。從節(jié)點(diǎn)主要用于讀取操作,以分擔(dān)主節(jié)點(diǎn)的壓力和提高讀性能。
RocketMQ的順序消息?
RocketMQ 實現(xiàn)順序消息的關(guān)鍵在于保證消息生產(chǎn)和消費(fèi)過程中嚴(yán)格的順序控制,即確保同一業(yè)務(wù)的消息按順序發(fā)送到同一個隊列中,并由同一個消費(fèi)者線程按順序消費(fèi)。
局部順序消息如何實現(xiàn)?
局部順序消息保證在某個邏輯分區(qū)或業(yè)務(wù)邏輯下的消息順序,例如同一個訂單或用戶的消息按順序消費(fèi),而不同訂單或用戶之間的順序不做保證。
全局順序消息如何實現(xiàn)?
全局順序消息保證消息在整個系統(tǒng)范圍內(nèi)的嚴(yán)格順序,即消息按照生產(chǎn)的順序被消費(fèi)。
可以將所有消息發(fā)送到一個單獨(dú)的隊列中,確保所有消息按生產(chǎn)順序發(fā)送和消費(fèi)。
你提到了棧幀,那局部變量表除了棧幀還有什么?
Java 虛擬機(jī)棧(Java Virtual Machine Stack),通常指的就是“?!?,它的生命周期與線程相同。
當(dāng)線程執(zhí)行一個方法時,會創(chuàng)建一個對應(yīng)的棧幀,用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息,然后棧幀會被壓入棧中。當(dāng)方法執(zhí)行完畢后,棧幀會從棧中移除。
一個什么都沒有的空方法,完全空的參數(shù)什么都沒有,那局部變量表里有沒有變量?
對于靜態(tài)方法,由于不需要訪問實例對象(this),因此在局部變量表中不會有任何變量。
對于非靜態(tài)方法,即使是一個完全空的方法,局部變量表中也會有一個用于存儲 this 引用的變量。this 引用指向當(dāng)前實例對象,在方法調(diào)用時被隱式傳入。
比如說有這樣一段代碼:
public class VarDemo1 {
public void emptyMethod() {
// 什么都沒有
}
public static void staticEmptyMethod() {
// 什么都沒有
}
}
用 javap -v VarDemo1 命令查看編譯后的字節(jié)碼:
在非靜態(tài)方法 emptyMethod 的輸出中,你會看到類似這樣的內(nèi)容:
這里的 locals=1 表示局部變量表有一個變量,即 this,Slot 0 位置存儲了 this 引用。
而在靜態(tài)方法 staticEmptyMethod 的輸出中,你會看到類似這樣的內(nèi)容:
這里的 locals=0 表示局部變量表為空,因為靜態(tài)方法沒有 this 引用,也沒有其他局部變量。
所有對象都在堆上對不對?
在 Java 中,并不是所有對象都嚴(yán)格在堆上分配內(nèi)存,雖然堆(Heap)是 Java 對象內(nèi)存分配的主要區(qū)域。
在某些情況下,JVM 的即時編譯器(JIT)可能會將對象分配在棧上,這被稱為逃逸分析(Escape Analysis)。
也就是活,如果編譯器確定一個對象不會在方法外部使用(即對象不會逃逸出方法的作用域),那么該對象可以分配在棧上,而不是堆上。
CMS用了什么垃圾回收算法?
CMS(Concurrent Mark Sweep)主要使用了標(biāo)記-清除算法進(jìn)行垃圾收集,分 4 大步:
-
初始標(biāo)記(Initial Mark):標(biāo)記所有從 GC Roots 直接可達(dá)的對象,這個階段需要 STW,但速度很快。 -
并發(fā)標(biāo)記(Concurrent Mark):從初始標(biāo)記的對象出發(fā),遍歷所有對象,標(biāo)記所有可達(dá)的對象。這個階段是并發(fā)進(jìn)行的,STW。 -
重新標(biāo)記(Remark):完成剩余的標(biāo)記工作,包括處理并發(fā)階段遺留下來的少量變動,這個階段通常需要短暫的 STW 停頓。 -
并發(fā)清除(Concurrent Sweep):清除未被標(biāo)記的對象,回收它們占用的內(nèi)存空間。
你提到了remark,那它remark具體是怎么執(zhí)行的?三色標(biāo)記法?
是的,remark 階段通常會結(jié)合三色標(biāo)記法來執(zhí)行,確保在并發(fā)標(biāo)記期間所有存活對象都被正確標(biāo)記。目的是修正并發(fā)標(biāo)記階段中可能遺漏的對象引用變化。
在 remark 階段,垃圾收集器會停止應(yīng)用線程(STW),以確保在這個階段不會有引用關(guān)系的進(jìn)一步變化。這種暫停通常很短暫。remark 階段主要包括以下操作:
-
處理寫屏障記錄的引用變化:在并發(fā)標(biāo)記階段,應(yīng)用程序可能會更新對象的引用(比如一個黑色對象新增了對一個白色對象的引用),這些變化通過寫屏障記錄下來。在 remark 階段,GC 會處理這些記錄,確保所有可達(dá)對象都正確地標(biāo)記為灰色或黑色。 -
掃描灰色對象:再次遍歷灰色對象,處理它們的所有引用,確保引用的對象正確標(biāo)記為灰色或黑色。 -
清理:確保所有引用關(guān)系正確處理后,灰色對象標(biāo)記為黑色,白色對象保持不變。這一步完成后,所有存活對象都應(yīng)當(dāng)是黑色的。
內(nèi)容來源
-
星球嘉賓三分惡的面渣逆襲:https://javabetter.cn/sidebar/sanfene/nixi.html -
二哥的 Java 進(jìn)階之路(GitHub 已有 12000+star):https://javabetter.cn
ending
一個人可以走得很快,但一群人才能走得更遠(yuǎn)。二哥的編程星球已經(jīng)有 5900 多名球友加入了,如果你也需要一個良好的學(xué)習(xí)環(huán)境,戳鏈接 ?? 加入我們吧。這是一個編程學(xué)習(xí)指南 + Java 項目實戰(zhàn) + LeetCode 刷題的私密圈子,你可以閱讀星球?qū)?、向二哥提問、幫你制定學(xué)習(xí)計劃、和球友一起打卡成長。
兩個置頂帖「球友必看」和「知識圖譜」里已經(jīng)沉淀了非常多優(yōu)質(zhì)的學(xué)習(xí)資源,相信能幫助你走的更快、更穩(wěn)、更遠(yuǎn)。
歡迎點(diǎn)擊左下角閱讀原文了解二哥的編程星球,這可能是你學(xué)習(xí)求職路上最有含金量的一次點(diǎn)擊。
最后,把二哥的座右銘送給大家:沒有什么使我停留——除了目的,縱然岸旁有玫瑰、有綠蔭、有寧靜的港灣,我是不系之舟。共勉 ??。
