首先還是安利時(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