• 正文
    • 小米汽車二面
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

小米汽車薪資曝光了!

03/06 13:10
1739
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

圖解學(xué)習(xí)網(wǎng)站:https://xiaolincoding.com

大家好,我是小林。

雷總的小米 su7 ultra 一發(fā)布,直接賣爆了,2 小時(shí)就完成了全年的銷售目標(biāo),50 多萬的價(jià)格就有 1500+馬力,這馬力可是千萬級(jí)跑車的配置了,1.98 秒破百,誰看了不心動(dòng),要不是狠自己錢包太小,我都想下手了。。

于是我就好奇,小米汽車的薪資待遇如何?

正好,我在「OfferShow」那里看到了「小米汽車-校招薪資爆料」匯總數(shù)據(jù),分享給大家看看。

城市 崗位 校招薪資爆料
北京 自動(dòng)駕駛 39k*15
北京 軟開 24k*15
北京 測(cè)試 23k*15
北京 軟開 22k*15
上海 電池系統(tǒng)測(cè)試 18k*15
北京 服務(wù)端開發(fā)工程師 22*15+0.8*12
南京 機(jī)械崗 30w
上海 動(dòng)力集成測(cè)試 23k*15
上海 算法 23k*15
北京 產(chǎn)品經(jīng)理 16k*15
南京 熱管理 18.5k*16

關(guān)注我的同學(xué)們大部分都是程序員,我們就專注看軟開的校招薪資,小米年終獎(jiǎng)是 3 個(gè)月,所以是 15 薪資計(jì)算:

    22k x 15 = 33w,北京24k x 15 = 36w,北京

軟開的年包在 30-35w,是屬于大廠范疇的薪資了,雖然和互聯(lián)網(wǎng)一線大廠會(huì)有一點(diǎn)點(diǎn)差距,但是整體還是不錯(cuò)的。

那小米汽車軟開崗的面試難得如何呢?

一起瞧瞧小米汽車Java軟開崗面經(jīng),這次是二面的面經(jīng)了,問了Spring、MySQL、設(shè)計(jì)模式、網(wǎng)絡(luò)協(xié)議、分布式事務(wù)這些內(nèi)容,最后還是一樣有一個(gè)算法題。

小米汽車二面

SpringBoot的啟動(dòng)流程介紹一下

SpringBoot是一個(gè)服務(wù)Spring框架的框架,能夠簡(jiǎn)化配置文件,快速構(gòu)建web應(yīng)用,內(nèi)置tomcat,無需打包部署,直接運(yùn)行。 當(dāng)我們啟動(dòng)一個(gè)SpringBoot應(yīng)用的時(shí)候,都會(huì)用到如下的啟動(dòng)類:

@SpringBootApplication
public?class?Application?{
? ? ?public?static?void?main(String[] args)?{
? ? ? ? ?SpringApplication.run(Application.class,?args);
? ? ?}

只要加上@SpringBootApplication,然后執(zhí)行run()方法,就可以啟動(dòng)一個(gè)應(yīng)用程序,啟動(dòng)的流程如下:

    首先從main找到run()方法,在執(zhí)行run()方法之前new一個(gè)SpringApplication對(duì)象進(jìn)入run()方法,創(chuàng)建應(yīng)用監(jiān)聽器SpringApplicationRunListeners開始監(jiān)聽然后加載SpringBoot配置環(huán)境(ConfigurableEnvironment),然后把配置環(huán)境(Environment)加入監(jiān)聽對(duì)象中然后加載應(yīng)用上下文(ConfigurableApplicationContext),當(dāng)做run方法的返回對(duì)象最后創(chuàng)建Spring容器,refreshContext(context),實(shí)現(xiàn)starter自動(dòng)化配置和bean的實(shí)例化等工作。

Spring IOC、 AOP解決了什么問題?沒有IOC之前怎么做?

Spring IOC 解決的問題,主要是解耦對(duì)象之間的依賴關(guān)系。在傳統(tǒng)的編程中,對(duì)象之間的依賴關(guān)系通常是在代碼中硬編碼實(shí)現(xiàn)的,這使得代碼的可維護(hù)性和可擴(kuò)展性變差。IOC 通過將對(duì)象的創(chuàng)建和依賴關(guān)系的管理交給 Spring 容器,實(shí)現(xiàn)了對(duì)象之間的解耦。比如,一個(gè)業(yè)務(wù)邏輯類可能依賴于多個(gè)數(shù)據(jù)訪問類,使用 IOC 后,業(yè)務(wù)邏輯類不需要知道具體的數(shù)據(jù)訪問類是如何創(chuàng)建和獲取的,只需要聲明它的依賴關(guān)系,由 Spring 容器來負(fù)責(zé)注入。

也可以提高提高代碼的可維護(hù)性和可測(cè)試性。當(dāng)依賴關(guān)系被集中管理在 Spring 容器中時(shí),如果需要更換某個(gè)依賴對(duì)象,只需要在配置文件或注解中進(jìn)行修改,而不需要在大量的業(yè)務(wù)代碼中進(jìn)行查找和修改。在進(jìn)行單元測(cè)試時(shí),也可以很方便地通過 IOC 容器注入模擬的依賴對(duì)象,提高了測(cè)試的靈活性和可操作性。

在沒有 IOC 框架之前,開發(fā)人員通常需要在代碼中手動(dòng)創(chuàng)建對(duì)象及其依賴對(duì)象。例如,在一個(gè) Java 項(xiàng)目中,如果一個(gè)?UserService?類依賴于?UserDao?類,那么在?UserService?類中需要通過?new?關(guān)鍵字來創(chuàng)建?UserDao?的實(shí)例,如下所示:

public?class?UserService?{
? ??private?UserDao userDao =?new?UserDao();

? ??public?void?doSomething()?{
? ? ? ??// 使用userDao進(jìn)行業(yè)務(wù)操作
? ? ? ? userDao.saveUser();
? ? }
}

這樣的代碼存在著嚴(yán)重的耦合問題,如果需要更換?UserDao?的實(shí)現(xiàn)類或者對(duì)其進(jìn)行一些初始化配置,就需要在?UserService?類中進(jìn)行修改,隨著項(xiàng)目規(guī)模的增大,維護(hù)成本會(huì)越來越高。

Spring AOP 解決的問題,主要是可以分離業(yè)務(wù)邏輯和橫切關(guān)注點(diǎn),提高代碼的復(fù)用性。在企業(yè)級(jí)應(yīng)用開發(fā)中,往往存在一些橫切關(guān)注點(diǎn),如日志記錄、事務(wù)管理、權(quán)限控制等,這些功能會(huì)分散在各個(gè)業(yè)務(wù)邏輯代碼中,導(dǎo)致代碼的可讀性和可維護(hù)性變差。AOP 允許將這些橫切關(guān)注點(diǎn)從業(yè)務(wù)邏輯中分離出來,以切面的形式進(jìn)行統(tǒng)一管理和實(shí)現(xiàn)。通過 AOP,可以將通用的橫切邏輯封裝在切面中,然后在多個(gè)業(yè)務(wù)邏輯中進(jìn)行復(fù)用。例如,對(duì)于日志記錄功能,可以創(chuàng)建一個(gè)日志切面,在多個(gè)不同的業(yè)務(wù)方法上都可以應(yīng)用這個(gè)切面來記錄日志,而不需要在每個(gè)業(yè)務(wù)方法中都編寫重復(fù)的日志記錄代碼。

在沒有 AOP 之前,要實(shí)現(xiàn)日志記錄、事務(wù)管理等橫切功能,通常需要在每個(gè)需要這些功能的方法中手動(dòng)編寫相關(guān)代碼。以日志記錄為例,可能需要在每個(gè)業(yè)務(wù)方法的開始和結(jié)束位置都添加日志記錄代碼,如下所示:

public?class?UserService?{
? ??public?void?doSomething()?{
? ? ? ??// 記錄方法開始日志
? ? ? ? System.out.println("進(jìn)入doSomething方法");
? ? ? ??// 業(yè)務(wù)邏輯代碼
? ? ? ??// 記錄方法結(jié)束日志
? ? ? ? System.out.println("離開doSomething方法");
? ? }
}

這樣不僅會(huì)導(dǎo)致代碼大量重復(fù),而且當(dāng)需要修改日志記錄的格式或策略時(shí),需要在多個(gè)地方進(jìn)行修改,容易出現(xiàn)遺漏和不一致的情況。

自己項(xiàng)目中有用到AOP嗎?

有,主要用在了日志記錄功能,避免在每個(gè)業(yè)務(wù)方法里重復(fù)編寫日志記錄代碼。

看你也會(huì)golang,golang和java的區(qū)別?

Golang是由Google設(shè)計(jì)的靜態(tài)類型、編譯型語言,注重簡(jiǎn)潔和高效并發(fā)。而Java是一種面向?qū)ο蟮恼Z言,擁有成熟的生態(tài)系統(tǒng)和跨平臺(tái)能力,依賴JVM運(yùn)行。

在語法方面,Golang更簡(jiǎn)潔,沒有類和繼承,使用接口和結(jié)構(gòu)體,而Java是嚴(yán)格的面向?qū)ο?,需要更多的樣板代碼。并發(fā)模型方面,Golang有g(shù)oroutine和channel,輕量級(jí)且易于使用;Java使用線程和線程池,相對(duì)重量級(jí),但通過并發(fā)包提供豐富的工具。

性能方面,Golang作為編譯型語言,通常啟動(dòng)更快,內(nèi)存占用更低;Java雖然JIT優(yōu)化后性能強(qiáng)勁,但啟動(dòng)和內(nèi)存開銷較大。

內(nèi)存管理方面,兩者都有垃圾回收,但Golang的GC更注重低延遲,Java的GC調(diào)優(yōu)更復(fù)雜但靈活。 錯(cuò)誤處理機(jī)制也不同,Golang采用顯式錯(cuò)誤返回,而Java使用異常機(jī)制。這可能影響代碼的可讀性和錯(cuò)誤處理流程。

生態(tài)系統(tǒng)方面,Java有大量成熟的框架和庫,適合企業(yè)級(jí)應(yīng)用;Golang的生態(tài)在云原生和微服務(wù)領(lǐng)域發(fā)展迅速,但相對(duì)年輕。

應(yīng)用場(chǎng)景方面,Golang適合高并發(fā)、分布式系統(tǒng),云基礎(chǔ)設(shè)施,而Java在企業(yè)應(yīng)用、Android開發(fā)、大數(shù)據(jù)處理等方面占優(yōu)。

MySQL建表的時(shí)候有哪些優(yōu)化手段?

合理選擇數(shù)據(jù)類型:根據(jù)實(shí)際存儲(chǔ)的數(shù)據(jù)范圍選擇合適的數(shù)值類型,避免使用過大的數(shù)據(jù)類型造成空間浪費(fèi)。例如,如果存儲(chǔ)的整數(shù)范圍在 0 - 255 之間,使用?TINYINT 即可,而不是?INT。對(duì)于固定長(zhǎng)度的字符串,使用?CHAR 類型;對(duì)于可變長(zhǎng)度的字符串,使用?VARCHAR 類型。同時(shí),根據(jù)實(shí)際存儲(chǔ)的字符串長(zhǎng)度合理設(shè)置字段長(zhǎng)度。

控制字段數(shù)量:避免創(chuàng)建過多不必要的字段,過多的字段會(huì)增加表的復(fù)雜度和存儲(chǔ)開銷,同時(shí)也會(huì)影響查詢性能。可以將一些不常用的字段單獨(dú)存儲(chǔ)在其他表中,通過關(guān)聯(lián)查詢獲取數(shù)據(jù)。

反范式化設(shè)計(jì):可以適當(dāng)引入一些數(shù)據(jù)冗余,將相關(guān)聯(lián)的數(shù)據(jù)存儲(chǔ)在同一個(gè)表中,減少表之間的關(guān)聯(lián)查詢。需要在范式化和反范式化之間找到一個(gè)平衡點(diǎn)。

合理創(chuàng)建索引:在經(jīng)常用于?WHERE 子句、JOIN 子句和?ORDER BY 子句的字段上創(chuàng)建索引,以提高查詢效率。避免在重復(fù)值較多的字段上創(chuàng)建索引,因?yàn)檫@樣的索引效果不佳。例如,在一個(gè)性別字段上創(chuàng)建索引可能沒有太大意義。當(dāng)然,過多的索引會(huì)增加存儲(chǔ)開銷和寫操作的性能開銷,因此要根據(jù)實(shí)際查詢需求合理創(chuàng)建索引,避免創(chuàng)建過多不必要的索引。

MySQL索引怎么建?

主鍵索引是一種特殊的唯一索引,它不允許有空值。通常在創(chuàng)建表時(shí)指定主鍵,MySQL 會(huì)自動(dòng)創(chuàng)建主鍵索引。創(chuàng)建方式:

-- 在創(chuàng)建表時(shí)創(chuàng)建主鍵索引
CREATE TABLE?table_name?(
? ? column1 datatype PRIMARY KEY,
? ? column2 datatype,
? ? ...
);

-- 使用 ALTER TABLE 語句創(chuàng)建主鍵索引
ALTER TABLE table_name ADD PRIMARY?KEY?(column1, column2, ...);

創(chuàng)建普通索引的方式:

-- 在創(chuàng)建表時(shí)創(chuàng)建普通索引
CREATE TABLE?table_name?(
? ? column1 datatype,
? ? column2 datatype,
? ? ...
? ? INDEX index_name (column1, column2, ...)
);

-- 在已存在的表上創(chuàng)建普通索引
CREATE INDEX index_name ON?table_name?(column1, column2, ...);

-- 使用 ALTER TABLE 語句創(chuàng)建普通索引
ALTER TABLE table_name ADD INDEX?index_name?(column1, column2, ...);

創(chuàng)建唯一索引的方式,唯一索引要求索引列的值必須唯一,但允許有空值。

-- 在創(chuàng)建表時(shí)創(chuàng)建唯一索引
CREATE TABLE?table_name?(
? ? column1 datatype,
? ? column2 datatype,
? ? ...
? ? UNIQUE INDEX index_name (column1, column2, ...)
);

-- 在已存在的表上創(chuàng)建唯一索引
CREATE UNIQUE INDEX index_name ON?table_name?(column1, column2, ...);

-- 使用 ALTER TABLE 語句創(chuàng)建唯一索引
ALTER TABLE table_name ADD UNIQUE INDEX?index_name?(column1, column2, ...);

MySQL中的鎖機(jī)制你知道哪些?

在 MySQL 里,根據(jù)加鎖的范圍,可以分為全局鎖、表級(jí)鎖和行鎖三類。

鎖類型 加鎖范圍 加鎖語句 具體說明
全局鎖 整個(gè)數(shù)據(jù)庫 flush tables with read lock 執(zhí)行該語句后數(shù)據(jù)庫處于只讀狀態(tài),其他線程的增刪改或表結(jié)構(gòu)修改操作都會(huì)阻塞
表級(jí)鎖 lock tables 對(duì)表加表鎖,會(huì)限制別的線程的讀寫,也會(huì)限制本線程接下來的讀寫操作
表級(jí)鎖(元數(shù)據(jù)鎖) 自動(dòng)加鎖 對(duì)表進(jìn)行 CRUD 操作時(shí)加 MDL 讀鎖;對(duì)表做結(jié)構(gòu)變更操作時(shí)加 MDL 寫鎖
表級(jí)鎖(意向鎖) 執(zhí)行插入、更新、刪除操作時(shí)自動(dòng)加鎖 執(zhí)行插入、更新、刪除操作時(shí),先對(duì)表加上「意向獨(dú)占鎖」,然后對(duì)該記錄加獨(dú)占鎖
行級(jí)鎖(記錄鎖) 表中的一條記錄 InnoDB 引擎自動(dòng)加鎖 有 S 鎖(共享鎖)和 X 鎖(排他鎖)之分,滿足讀寫互斥,寫寫互斥
行級(jí)鎖(間隙鎖) 表中的記錄間隙 InnoDB 引擎自動(dòng)加鎖,只存在于可重復(fù)讀隔離級(jí)別 用于解決可重復(fù)讀隔離級(jí)別下幻讀的現(xiàn)象
行級(jí)鎖(Next-Key Lock) 表中的一個(gè)范圍及記錄本身 InnoDB 引擎自動(dòng)加鎖 是 Record Lock + Gap Lock 的組合,鎖定一個(gè)范圍,并且鎖定記錄本身

全局鎖:通過flush tables with read lock 語句會(huì)將整個(gè)數(shù)據(jù)庫就處于只讀狀態(tài)了,這時(shí)其他線程執(zhí)行以下操作,增刪改或者表結(jié)構(gòu)修改都會(huì)阻塞。全局鎖主要應(yīng)用于做

全庫邏輯備份,這樣在備份數(shù)據(jù)庫期間,不會(huì)因?yàn)閿?shù)據(jù)或表結(jié)構(gòu)的更新,而出現(xiàn)備份文件的數(shù)據(jù)與預(yù)期的不一樣。

表級(jí)鎖:MySQL 里面表級(jí)別的鎖有這幾種:

表鎖:通過lock tables 語句可以對(duì)表加表鎖,表鎖除了會(huì)限制別的線程的讀寫外,也會(huì)限制本線程接下來的讀寫操作。元數(shù)據(jù)鎖:當(dāng)我們對(duì)數(shù)據(jù)庫表進(jìn)行操作時(shí),會(huì)自動(dòng)給這個(gè)表加上 MDL,對(duì)一張表進(jìn)行 CRUD 操作時(shí),加的是?MDL 讀鎖;對(duì)一張表做結(jié)構(gòu)變更操作的時(shí)候,加的是?MDL 寫鎖;MDL 是為了保證當(dāng)用戶對(duì)表執(zhí)行 CRUD 操作時(shí),防止其他線程對(duì)這個(gè)表結(jié)構(gòu)做了變更。意向鎖:當(dāng)執(zhí)行插入、更新、刪除操作,需要先對(duì)表加上「意向獨(dú)占鎖」,然后對(duì)該記錄加獨(dú)占鎖。

意向鎖的目的是為了快速判斷表里是否有記錄被加鎖。

行級(jí)鎖:InnoDB 引擎是支持行級(jí)鎖的,而 MyISAM 引擎并不支持行級(jí)鎖。

    • 記錄鎖,鎖住的是一條記錄。而且記錄鎖是有 S 鎖和 X 鎖之分的,滿足讀寫互斥,寫寫互斥間隙鎖,只存在于可重復(fù)讀隔離級(jí)別,目的是為了解決可重復(fù)讀隔離級(jí)別下幻讀的現(xiàn)象。Next-Key Lock 稱為臨鍵鎖,是 Record Lock + Gap Lock 的組合,鎖定一個(gè)范圍,并且鎖定記錄本身。

最熟悉的設(shè)計(jì)模式有哪些?

單例模式、工廠模式、策略模式、裝飾器模式這些。

    單例模式:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。工廠模式:定義一個(gè)創(chuàng)建對(duì)象的接口,讓子類決定實(shí)例化哪個(gè)類。工廠方法使一個(gè)類的實(shí)例化延遲到其子類。策略模式:定義一系列的算法,把它們一個(gè)個(gè)封裝起來,并且使它們可以相互替換。該模式使得算法可以獨(dú)立于使用它的客戶而變化。裝飾器模式:動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來說,裝飾器模式相比生成子類更為靈活。

代理模式講一下

代理模式為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問。

在代理模式中,代理對(duì)象與目標(biāo)對(duì)象實(shí)現(xiàn)相同的接口,客戶端對(duì)目標(biāo)對(duì)象的訪問實(shí)際上是通過代理對(duì)象來進(jìn)行的,代理對(duì)象可以在調(diào)用目標(biāo)對(duì)象的方法前后進(jìn)行一些額外的操作,如權(quán)限驗(yàn)證、緩存處理、日志記錄等。

代理模式實(shí)現(xiàn)有這些:

    • 靜態(tài)代理:手動(dòng)編寫代理類,需實(shí)現(xiàn)與目標(biāo)對(duì)象相同的接口。優(yōu)點(diǎn)是簡(jiǎn)單直觀,缺點(diǎn)是每個(gè)目標(biāo)類需對(duì)應(yīng)一個(gè)代理類,代碼冗余。動(dòng)態(tài)代碼:運(yùn)行時(shí)動(dòng)態(tài)生成代理類,無需手動(dòng)編寫。JDK動(dòng)態(tài)代理是基于接口,使用

java.lang.reflect.Proxy

    ,CGLIB動(dòng)態(tài)代理:基于繼承,可代理無接口的類。

聊聊網(wǎng)絡(luò),交換機(jī)和路由器的區(qū)別?

交換機(jī):主要工作在數(shù)據(jù)鏈路層。它通過學(xué)習(xí)連接到其端口的設(shè)備的 MAC 地址,構(gòu)建 MAC 地址表。當(dāng)接收到數(shù)據(jù)幀時(shí),根據(jù)數(shù)據(jù)幀中的目的 MAC 地址在 MAC 地址表中查找對(duì)應(yīng)的端口,然后將數(shù)據(jù)幀從該端口轉(zhuǎn)發(fā)出去,實(shí)現(xiàn)本地網(wǎng)絡(luò)內(nèi)設(shè)備之間的數(shù)據(jù)交換。

路由器:主要工作在網(wǎng)絡(luò)層。它依據(jù) IP 地址進(jìn)行數(shù)據(jù)轉(zhuǎn)發(fā),路由器中保存著路由表,路由表包含了網(wǎng)絡(luò)地址與下一跳地址等信息。當(dāng)路由器接收到數(shù)據(jù)包時(shí),會(huì)根據(jù)數(shù)據(jù)包中的目的 IP 地址,在路由表中查找最佳路徑,然后將數(shù)據(jù)包沿著該路徑轉(zhuǎn)發(fā)到下一個(gè)路由器或目標(biāo)設(shè)備。

現(xiàn)在我們視頻聊天,涉及到的網(wǎng)絡(luò)協(xié)議是什么?

對(duì)于實(shí)時(shí)性要求極高的視頻和音頻數(shù)據(jù),會(huì)優(yōu)先使用 UDP 進(jìn)行傳輸,并通過一些額外的技術(shù)手段來彌補(bǔ) UDP 的不可靠性;而對(duì)于控制信息和一些對(duì)可靠性要求較高的數(shù)據(jù),則會(huì)使用 TCP 來傳輸,以確保視頻聊天的穩(wěn)定性和正確性。

分布式事務(wù)的解決方案你知道哪些?

方案 一致性 性能 復(fù)雜度 適用場(chǎng)景
2PC 強(qiáng)一致性 傳統(tǒng)數(shù)據(jù)庫、XA協(xié)議
3PC 強(qiáng)一致性 中低 需減少阻塞的強(qiáng)一致場(chǎng)景
TCC 最終一致性 高并發(fā)業(yè)務(wù)(支付、庫存)
Saga 最終一致性 長(zhǎng)事務(wù)、跨服務(wù)流程
消息隊(duì)列 最終一致性 事件驅(qū)動(dòng)架構(gòu)
本地消息表 最終一致性 異步通知(訂單-積分)
    兩階段提交協(xié)議(2PC):為準(zhǔn)備階段和提交階段。準(zhǔn)備階段,協(xié)調(diào)者向參與者發(fā)送準(zhǔn)備請(qǐng)求,參與者執(zhí)行事務(wù)操作并反饋結(jié)果。若所有參與者準(zhǔn)備就緒,協(xié)調(diào)者在提交階段發(fā)送提交請(qǐng)求,參與者執(zhí)行提交;否則發(fā)送回滾請(qǐng)求。實(shí)現(xiàn)簡(jiǎn)單,能保證事務(wù)強(qiáng)一致性。存在單點(diǎn)故障,協(xié)調(diào)者故障會(huì)影響事務(wù)流程;性能低,多次消息交互增加延遲;資源鎖導(dǎo)致資源長(zhǎng)時(shí)間占用,降低并發(fā)性能。適用于對(duì)數(shù)據(jù)一致性要求高、并發(fā)度低的場(chǎng)景,如金融系統(tǒng)轉(zhuǎn)賬業(yè)務(wù)。
    三階段提交協(xié)議(3PC):在 2PC 基礎(chǔ)上,將準(zhǔn)備階段拆分為詢問階段和準(zhǔn)備階段,形成詢問、準(zhǔn)備和提交三個(gè)階段。詢問階段協(xié)調(diào)者詢問參與者能否執(zhí)行事務(wù),后續(xù)階段與 2PC 類似。降低參與者阻塞時(shí)間,提高并發(fā)性能,引入超時(shí)機(jī)制一定程度解決單點(diǎn)故障問題。無法完全避免數(shù)據(jù)不一致,極端網(wǎng)絡(luò)情況下可能出現(xiàn)部分提交部分回滾。用于對(duì)并發(fā)性能有要求、對(duì)數(shù)據(jù)一致性要求相對(duì)較低的場(chǎng)景。
    TCC:將業(yè)務(wù)操作拆分為 Try、Confirm、Cancel 三個(gè)階段。Try 階段預(yù)留業(yè)務(wù)資源,Confirm 階段確認(rèn)資源完成業(yè)務(wù)操作,Cancel 階段在失敗時(shí)釋放資源回滾操作。可根據(jù)業(yè)務(wù)場(chǎng)景定制開發(fā),性能較高,減少資源占用時(shí)間。開發(fā)成本高,需實(shí)現(xiàn)三個(gè)方法,要處理異常和補(bǔ)償邏輯,實(shí)現(xiàn)復(fù)雜度大。適用于對(duì)性能要求高、業(yè)務(wù)邏輯復(fù)雜的場(chǎng)景,如電商系統(tǒng)訂單處理、庫存管理。
    Saga:將長(zhǎng)事務(wù)拆分為多個(gè)短事務(wù),每個(gè)短事務(wù)有對(duì)應(yīng)的補(bǔ)償事務(wù)。某個(gè)短事務(wù)失敗,按相反順序執(zhí)行補(bǔ)償事務(wù)回滾系統(tǒng)狀態(tài)。性能較高,短事務(wù)可并行執(zhí)行減少時(shí)間,對(duì)業(yè)務(wù)侵入性小,只需實(shí)現(xiàn)補(bǔ)償事務(wù)。只能保證最終一致性,部分補(bǔ)償事務(wù)失敗可能導(dǎo)致系統(tǒng)狀態(tài)不一致。適用于業(yè)務(wù)流程長(zhǎng)、對(duì)數(shù)據(jù)一致性要求為最終一致性的場(chǎng)景,如旅游系統(tǒng)訂單、航班、酒店預(yù)訂。
    可靠消息最終一致性方案:基于消息隊(duì)列,業(yè)務(wù)系統(tǒng)執(zhí)行本地事務(wù)時(shí)將業(yè)務(wù)操作封裝成消息發(fā)至消息隊(duì)列,下游系統(tǒng)消費(fèi)消息并執(zhí)行操作,失敗則消息隊(duì)列重試。實(shí)現(xiàn)簡(jiǎn)單,對(duì)業(yè)務(wù)代碼修改小,系統(tǒng)耦合度低,能保證數(shù)據(jù)最終一致性。消息隊(duì)列可靠性和性能影響大,可能出現(xiàn)消息丟失或延遲,需處理消息冪等性。適用于對(duì)數(shù)據(jù)一致性要求為最終一致性、系統(tǒng)耦合度低的場(chǎng)景,如電商訂單支付、庫存扣減。
    本地消息表:業(yè)務(wù)與消息存儲(chǔ)在同一個(gè)數(shù)據(jù)庫,利用本地事務(wù)保證一致性,后臺(tái)任務(wù)輪詢消息表,通過MQ通知下游服務(wù),下游服務(wù)消費(fèi)成功后確認(rèn)消息,失敗則重試。簡(jiǎn)單可靠,無外部依賴。消息可能重復(fù)消費(fèi),需冪等設(shè)計(jì)。適用場(chǎng)景是異步最終一致性(如訂單創(chuàng)建后通知積分服務(wù))。

阿里的seata框架了解過嗎?

Seata 是開源分布式事務(wù)解決方案,支持多種模式:

AT模式:是 Seata 默認(rèn)的模式,基于支持本地 ACID 事務(wù)的關(guān)系型數(shù)據(jù)庫。在 AT 模式下,Seata 會(huì)自動(dòng)生成回滾日志,在業(yè)務(wù) SQL 執(zhí)行前后分別記錄數(shù)據(jù)的快照。當(dāng)全局事務(wù)需要回滾時(shí),根據(jù)回滾日志將數(shù)據(jù)恢復(fù)到事務(wù)開始前的狀態(tài)。

TCC模式:需要開發(fā)者手動(dòng)編寫 Try、Confirm 和 Cancel 三個(gè)方法。Try 方法用于對(duì)業(yè)務(wù)資源進(jìn)行預(yù)留,Confirm 方法用于確認(rèn)資源并完成業(yè)務(wù)操作,Cancel 方法用于在業(yè)務(wù)執(zhí)行失敗時(shí)釋放預(yù)留的資源。

SAGA 模式:將一個(gè)長(zhǎng)事務(wù)拆分為多個(gè)短事務(wù),每個(gè)短事務(wù)都有一個(gè)對(duì)應(yīng)的補(bǔ)償事務(wù)。當(dāng)某個(gè)短事務(wù)執(zhí)行失敗時(shí),會(huì)按照相反的順序執(zhí)行之前所有短事務(wù)的補(bǔ)償事務(wù),將系統(tǒng)狀態(tài)回滾到初始狀態(tài)。

算法

    組合總和
小米

小米

小米是全球第四大智能手機(jī)制造商,在30余個(gè)國(guó)家和地區(qū)的手機(jī)市場(chǎng)進(jìn)入了前五名,特別是在印度,連續(xù)5個(gè)季度保持手機(jī)出貨量第一。通過獨(dú)特的“生態(tài)鏈模式”,小米投資、帶動(dòng)了更多志同道合的創(chuàng)業(yè)者,同時(shí)建成了連接超過1.3億臺(tái)智能設(shè)備的IoT平臺(tái)。

小米是全球第四大智能手機(jī)制造商,在30余個(gè)國(guó)家和地區(qū)的手機(jī)市場(chǎng)進(jìn)入了前五名,特別是在印度,連續(xù)5個(gè)季度保持手機(jī)出貨量第一。通過獨(dú)特的“生態(tài)鏈模式”,小米投資、帶動(dòng)了更多志同道合的創(chuàng)業(yè)者,同時(shí)建成了連接超過1.3億臺(tái)智能設(shè)備的IoT平臺(tái)。收起

查看更多

相關(guān)推薦