首先還是安利時(shí)間:寫文時(shí)的歌單是
君に最後の口づけを
IxU
時(shí)間煮雨
我好想你
花に亡霊
あの夢(mèng)をなぞって
たふ?ん
群青
1.數(shù)據(jù)序列化的意義及必要性
??在開(kāi)發(fā)中時(shí)長(zhǎng)會(huì)遇到需要進(jìn)行跨進(jìn)程進(jìn)行數(shù)據(jù)傳輸灭袁,或者將數(shù)據(jù)持久化存儲(chǔ)到磁盤或別的什么介質(zhì)中,而數(shù)據(jù)在傳輸或存儲(chǔ)前需要進(jìn)行序列化的過(guò)程。
??那么派敷,為什么需要這個(gè)序列化的過(guò)程呢撰筷?它的意義是什么呢津畸?
??有些小伙伴可能會(huì)不理解绣张,為什么不能直接把數(shù)據(jù)在內(nèi)存中拿出來(lái)直接拿去進(jìn)行傳輸或者存儲(chǔ)呢惕蹄?
??雖然數(shù)據(jù)都是存在于內(nèi)存中這一點(diǎn)是沒(méi)有問(wèn)題的狂秦,但對(duì)于使用了不同編程語(yǔ)言而開(kāi)發(fā)出來(lái)的程序來(lái)說(shuō)灌侣,它們會(huì)在底層為了高效利用內(nèi)存與CPU而進(jìn)行不同的優(yōu)化,通常來(lái)說(shuō)它們都是指針變種或者升級(jí)版裂问,所以對(duì)于一個(gè)對(duì)象來(lái)說(shuō)侧啼,它對(duì)用戶所表現(xiàn)出來(lái)的外觀與它在內(nèi)存中的里相是不一樣的牛柒,舉例來(lái)說(shuō),假如說(shuō)有一個(gè)Object A痊乾,
它表現(xiàn)出來(lái)的外觀是這樣的:
{
??int a = 10;
??long b = 9527;
??String s = "鈴木愛(ài)理是我老婆";
??char[] carr = [新,垣,結(jié),衣,也,是,我,老,婆];
??Object B:{
????int innerA = 10086;
????long innerB = 1020;
??}
}
但實(shí)際上它在內(nèi)存里是這樣的:
{
??int a = 10;(基礎(chǔ)數(shù)據(jù)類型是被直接包著的)
??long b = 9527;
??String b -> 2134565(指向字符串對(duì)象地址的指針皮壁,數(shù)字是我亂寫的)
??int[] b -> 689461(指向int數(shù)組第0個(gè)元素所在地址的指針)
??Object B -> 98463165(指向ObjectB這個(gè)對(duì)象的指針)
}
所以如果你未經(jīng)任何處理,直接將ObjectA從內(nèi)存中復(fù)制出來(lái)哪审,那么對(duì)方最終可能只能接收到一堆無(wú)法識(shí)別的奇葩數(shù)字蛾魄。
??所以大概可以將序列化的過(guò)程簡(jiǎn)單地理解為【將不同編程語(yǔ)言為了優(yōu)化而魔改后的內(nèi)存中的數(shù)據(jù),轉(zhuǎn)換為可通過(guò)某種方法完整還原會(huì)內(nèi)存中的湿滓,用于跨進(jìn)程傳輸或持久化存儲(chǔ)的數(shù)據(jù)格式】滴须,而這種序列化的方法必須是在某種意義上通用的,與編程語(yǔ)言無(wú)關(guān)的叽奥。
2.常用的序列化格式
①目前互聯(lián)網(wǎng)比較流行的XML與JSON
??比較老資格的有XML扔水,以前在銀行里的時(shí)候也是經(jīng)常與XML報(bào)文打交道。
??JSON是最近幾年開(kāi)始流行起來(lái)的朝氓,似乎是因?yàn)榇蠹蚁訔塜ML冗余體積比較多魔市,浪費(fèi)了太多網(wǎng)絡(luò)帶寬,于是乎JSON出來(lái)了膀篮,體積更小嘹狞。
??這兩種格式都是具有很不錯(cuò)的可讀性的,受過(guò)訓(xùn)練的人類(指程序猿)也能輕易肉眼讀取誓竿,并且兼容性也不錯(cuò)磅网,因?yàn)榇蟛糠諮SON和XML的序列化工具都是根據(jù)報(bào)文中的變量名進(jìn)行1對(duì)1識(shí)別,因此除非是因?yàn)闃I(yè)務(wù)大規(guī)模變更而導(dǎo)致必填項(xiàng)發(fā)生變化筷屡,不然單純對(duì)于實(shí)體轉(zhuǎn)換來(lái)說(shuō)具有很好的向前/向后的兼容性涧偷。
??但是使用它們也有需要注意的問(wèn)題:
??數(shù)字編碼模糊。由于這兩種序列化格式中僅有變量名作為標(biāo)識(shí)毙死,因此如果發(fā)送方與接收方所定義的實(shí)體/數(shù)據(jù)結(jié)構(gòu)中的數(shù)字類型不一致——比如說(shuō)同為變量a燎潮,發(fā)送方是double,接收方是int扼倘,或者字符串确封,或者說(shuō)是所指定的精度不一致的double——這種情況中接收方反序列化時(shí)會(huì)產(chǎn)生問(wèn)題
②二進(jìn)制變種而來(lái)的序列化方式
??有部分開(kāi)發(fā)者可能是為了獲得更高的傳輸效率,節(jié)省帶寬再菊,而會(huì)選擇更緊湊或更快的解析格式爪喘。但這些方式一般偏小眾,難以在市場(chǎng)上普及纠拔,因此僅作為組織內(nèi)小范圍應(yīng)用秉剑。
目前比較有名的二進(jìn)制方式有facebook開(kāi)源的apache thrift和google開(kāi)源的protocol buffers,以及apache avro稠诲。其中apache avro的壓縮率是最高的侦鹏。這兩種方式應(yīng)用起來(lái)相對(duì)更復(fù)雜點(diǎn)(因?yàn)樾枰渲脤?shí)體信息等各種)
3.模式演化與兼容
??由于市場(chǎng)的發(fā)展與業(yè)務(wù)的變化诡曙,所以數(shù)據(jù)模式總是在發(fā)生變化,而對(duì)于開(kāi)發(fā)者來(lái)說(shuō)可能不是每一次都會(huì)兼顧去把所有的老程序進(jìn)行升級(jí)略水,因此考慮向前/向后兼容是有必要的价卤。
??對(duì)于序列化工具指導(dǎo)兼容性實(shí)現(xiàn)的方式有reader模式,writer模式聚请,數(shù)據(jù)流模式(好像對(duì)我來(lái)說(shuō)沒(méi)什么卵用荠雕,隨便記下來(lái)算了)。
神驅(qū)一夢(mèng)
2020.11.15