溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript如何讓雪花算法成為空氣

發(fā)布時(shí)間:2021-09-30 11:48:34 來(lái)源:億速云 閱讀:116 作者:柒染 欄目:web開(kāi)發(fā)

這篇文章給大家介紹JavaScript如何讓雪花算法成為空氣,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

我也只能在這里,發(fā)表這樣無(wú)恥的言論。因?yàn)閤jjdog的修為主要體現(xiàn)在后端上,所以愛(ài)屋及烏。這體現(xiàn)了斗爭(zhēng)是人類(lèi)的基本屬性:程序員除了要干產(chǎn)品經(jīng)理、項(xiàng)目經(jīng)理,內(nèi)部也并不是鐵板一塊。

1. 事出有因

就如標(biāo)題所說(shuō),這個(gè)會(huì)和雪花算法有關(guān)。

我們有個(gè)系統(tǒng),使用的是MySQL數(shù)據(jù)庫(kù),所以在數(shù)據(jù)庫(kù)的主鍵選擇上,使用的是自增ID。

ID INT  PRIMARY KEY AUTO_INCREMENT

這樣的ID簡(jiǎn)單流暢,但有一系列的弊端,不過(guò)用在一般的系統(tǒng)上,夠用了。

在臨上線之前,項(xiàng)目組邀請(qǐng)公司里最牛x的架構(gòu)師,對(duì)項(xiàng)目進(jìn)行了一次集中體檢。其中的一項(xiàng)重要舉措,就是針對(duì)于ID生成器的。

“不知道現(xiàn)在的開(kāi)發(fā)系統(tǒng),都至少要使用Snowflake作為ID生成器么?” 架構(gòu)師對(duì)自增ID的方案非常的不滿意。

它指出,哪怕你使用UUID,在遇到系統(tǒng)擴(kuò)容、分庫(kù)分表、數(shù)據(jù)遷移等場(chǎng)景的時(shí)候,也比自增ID強(qiáng)。

大家伙一討論,覺(jué)得非常合理。UUID太無(wú)序,美團(tuán)Leaf這種又太復(fù)雜,還不如直接使用老掉牙的Snowflake,直接生成最簡(jiǎn)單的ID即可。

類(lèi)似于這種。

527574217068392807 527574217068392808

為了讓你有個(gè)直觀的認(rèn)識(shí),我們看一下Java中Long的最大值。

9223372036854775807

再看一下Int的最大值。

2147483647

可以看到生成的Snowflake ID,是比Int大,比Long小的數(shù)值(和最大的比較),所以在數(shù)據(jù)庫(kù)中使用bigint存儲(chǔ),再好不過(guò)了。

說(shuō)干就干,批量腳本一改,主鍵就變大變長(zhǎng)了~~~

2. 問(wèn)題發(fā)生

別說(shuō),這樣子的ID,看起來(lái)還比較順眼。ID在URL里傳遞,在formdata里傳遞,一看就比較的專(zhuān)業(yè)!

/edit.do?id=527574217068392810

系統(tǒng)按照建議改完之后,單元測(cè)試很流暢。黑盒測(cè)試草草的點(diǎn)了一下,就算通過(guò)了。

靈異事件是被客戶發(fā)現(xiàn)的。

客戶說(shuō),很多記錄,無(wú)法編輯、無(wú)法刪除。提示找不到記錄。

很多公司的尿性你也是知道的,和客戶交流的,通常不太懂技術(shù)。對(duì)著客戶的屏幕用牛x的手機(jī)拍照,原圖發(fā)過(guò)來(lái)就有十幾MB。但靈異的是圖片大,內(nèi)容卻模模糊糊。

后端程序員,瞇著眼睛打開(kāi)圖片,把里面顯示的ID給摳出來(lái),放在系統(tǒng)里一查。

沒(méi)有此記錄。

肯定是瞇眼的姿勢(shì)有問(wèn)題。后端程序員不得不再錄一遍??上У氖牵廊粵](méi)有這條記錄。

沒(méi)辦法,只好把客戶的數(shù)據(jù)庫(kù)拷貝一份過(guò)來(lái)。頁(yè)面上一點(diǎn)擊,果然有問(wèn)題!

瀏覽器response里返回的數(shù)據(jù)竟然和preview里的不一樣

3. 問(wèn)題驗(yàn)證

也就是說(shuō),一個(gè)好好的數(shù)字:527183991665594368,經(jīng)過(guò)瀏覽器一翻譯,變成了527183991665594400。

我們?cè)跒g覽器的devtools里面調(diào)試一下。

JavaScript如何讓雪花算法成為空氣

為了進(jìn)一步驗(yàn)證,我們從typescript到j(luò)s,都試驗(yàn)一下。

 # cat test.ts let a = 527183991665594368; console.log(a);  # tsc test.ts  # cat test.js var a = 527183991665594368; console.log(a);  # node test.js 527183991665594400

可以看到,在整個(gè)js的生態(tài)里,都存在這個(gè)問(wèn)題,真是坑壞了后端。

4. Why?

這是因?yàn)?。在JavaScript中,存在兩種數(shù)字。Number和BigInt。最常用的,就是number。

最大的Number,叫做Number.MAX_SAFE_INTEGER,它的值為:

2^53-1 或者

+/- 9,007,199,254,740,991

眾所周知,Java中的Long,是64位的。Js中的這個(gè)安全I(xiàn)nteger,完全達(dá)不到Java中定義的長(zhǎng)度。

這就是萬(wàn)惡的IEEE_754規(guī)范,它在Long長(zhǎng)度大于17位時(shí)會(huì)出現(xiàn)精度丟失的問(wèn)題。

在最新的TypeScript3.2中,可是直接使用BigInt這個(gè)類(lèi)型進(jìn)行編碼,或者使用long.js這種封裝后的苦,但還是太麻煩了,需要編碼太多,而且還可能漏掉。

使用數(shù)字類(lèi)型,傳輸數(shù)據(jù),實(shí)在是不太靠譜,轉(zhuǎn)來(lái)轉(zhuǎn)去,就物是人非了。

最好的方式,就是使用string進(jìn)行傳遞。哪怕以后后臺(tái)ID的長(zhǎng)度變成了128位的,也不懼怕這種轉(zhuǎn)換。

在Java中,如果你用的是jackson,直接通過(guò)注解,就可以完成字符串更改,不需要再改動(dòng)數(shù)據(jù)庫(kù)。

@JsonSerialize(using=ToStringSerializer.class) private Long id;

這問(wèn)題,明顯不是后端的鍋。后端傳遞了正確的數(shù)據(jù)到前端,能不能處理、處理的正確不正確,根本和后端一點(diǎn)關(guān)系都沒(méi)有。JS的這種按照規(guī)范的不規(guī)范處理,已經(jīng)讓很多人踩坑。不管是萌新,還是老鳥(niǎo),依然前赴后繼的掉到坑里,不得不說(shuō)這個(gè)特性是非常反人類(lèi)的。

關(guān)于JavaScript如何讓雪花算法成為空氣就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI