關(guān)于序列化的認(rèn)識(一)

本篇主要就序列化的認(rèn)識進(jìn)行說明,不就某種序列化方式進(jìn)行深入。

什么是序列化?

??????序列化對于大部分開發(fā)人員是一個熟悉又遙遠(yuǎn)的詞,我們經(jīng)常要用到序列化,但是又不清楚為什么要序列化。我們以Java提供的序列化機(jī)制為例,它可以將對象的狀態(tài)信息轉(zhuǎn)變?yōu)槎M(jìn)制數(shù)據(jù),實(shí)際上這個過程就是將內(nèi)存中的數(shù)據(jù)轉(zhuǎn)換為某種可持久化或者可傳輸?shù)母袷降倪^程。這也是序列化的過程,反之反序列化則是將數(shù)據(jù)重新讀入內(nèi)存的過程。

為什么需要序列化?

??????這個問題也是大多數(shù)人最想知道的一個問題,同樣我還是以Java為例,我們知道,Java程序的運(yùn)行時(shí)依賴于JVM的,只有jvmJVM的時(shí)候,對象才可能存在(這里說的對象是內(nèi)存中的對象,而非以某種形式持久化存在的),也就是說對象的生命周期是不會超過JVM生命周期的,但是我們往往需要希望能夠在JVM停止運(yùn)行后保存對象的狀態(tài),以便在別的地方使用。這也是序列化的第一個作用,將對象字節(jié)序列持久化。
??????對于現(xiàn)在的大多數(shù)應(yīng)用來說,都是網(wǎng)絡(luò)應(yīng)用,那么這就需要進(jìn)行網(wǎng)絡(luò)傳輸,我們知道,對象是存在于內(nèi)存中的,顯然是無法進(jìn)行網(wǎng)絡(luò)傳輸?shù)模晕覀冃枰砸环N方式來傳輸對象,這也是序列化的第二個作用。
總結(jié):序列化實(shí)際上是為了讓內(nèi)存中的對象或者數(shù)據(jù)結(jié)構(gòu)以一種可以存儲和傳輸?shù)母袷酱嬖凇?/em>

序列化的方式

序列化的方式主要是兩種,文本方式與二進(jìn)制方式,如何進(jìn)行選擇也是很重要的一點(diǎn),我主要考慮以下方面,

  • 通用性
    序列化機(jī)制在一定程度上要能夠彌補(bǔ)OS之間的差異,方便進(jìn)行傳輸,所以在選擇序列化協(xié)議的時(shí)候,我們會考慮是否支持跨平臺、跨語言。如果不支持,在技術(shù)層面上的通用性就大大降低了。例如Java本身提供的serialization機(jī)制無法在非JVM平臺上使用,限制了它的通用性。如果我們要在不同的編程語言之間傳遞對象,就必須把對象序列化為標(biāo)準(zhǔn)格式,比如XML,但更好的方法是序列化為JSON,因?yàn)镴SON表示出來就是一個字符串,可以被所有語言讀取,也可以方便地存儲到磁盤或者通過網(wǎng)絡(luò)傳輸。
  • 安全性 / 訪問限制
    考慮到對外提供接口的兼容性,我們通常會采用REST+JSON的方案,用于內(nèi)網(wǎng)通信的RPC通常使用二進(jìn)制方式序列化,因?yàn)榫W(wǎng)絡(luò)中只有字符串可以穿透防火墻,HTTP位于應(yīng)用層,跨防火墻,可以在不同的局域網(wǎng)之間通信,而HTTP本身是一個文本協(xié)議,雖然可以傳輸二進(jìn)制數(shù)據(jù),但是通常需要經(jīng)過BASE64或者M(jìn)IME編碼(HTTP2支持二進(jìn)制流),所以會選擇兼容性更好以及本身就是文本格式的JSON或者XML。對于RPC來說,RPC 使用TCP協(xié)議位于傳輸層,TCP是一種二進(jìn)制協(xié)議,對二進(jìn)制數(shù)據(jù)提供天然的支持,并且大多是用于內(nèi)網(wǎng)通信,所以會選擇效率更好的二進(jìn)制序列化方式(關(guān)于傳輸協(xié)議:不同之處在于協(xié)議是圍繞數(shù)據(jù)結(jié)構(gòu)還是圍繞文本字符串)。
    從安全性的角度考慮,二進(jìn)制協(xié)議很方便進(jìn)行加密,防止協(xié)議被破解,從而保護(hù)了傳遞的信息,增加協(xié)議破解的難度,而文本協(xié)議方便解讀,并不適合進(jìn)行加密。
  • 可擴(kuò)展性/兼容性
    以JSON和XML為主的文本格式,如果需要增加一些條件,直接添加Key和Value就可以了,擴(kuò)展方便,而二進(jìn)制數(shù)據(jù)如果修改已有字段的順序就會造成消息無法正確解析。

二進(jìn)制序列化的數(shù)據(jù)因?yàn)槭菄?yán)格的內(nèi)存到對象的轉(zhuǎn)換,所以要求發(fā)送方與接收方的的機(jī)器字節(jié)序保持一致,否則無法正確解析。而文本格式的數(shù)據(jù)對于消息的發(fā)送方和接收方的采用的編程語言沒有嚴(yán)格的限制,對于多語言編寫提供了便利。

  • 性能
    空間開銷(Verbosity), 序列化需要在原有的數(shù)據(jù)上加上描述字段,以為反序列化解析之用。二進(jìn)制數(shù)據(jù)只保存了必須的信息,在需要傳遞大量信息的時(shí)候,對于磁盤和帶寬的節(jié)省是非常明顯的。而對于JSON和XML而言,因?yàn)榇嬖诖罅棵枋鲂缘男畔?,進(jìn)行序列化的額外空間開銷比較大,對于大數(shù)據(jù)量服務(wù)或持久化,這意味著巨大的內(nèi)存和磁盤開銷。

時(shí)間開銷(Complexity),以Java為例,某些序列化方式需要依賴反射,往往會導(dǎo)致比較長時(shí)間的解析時(shí)間,這可能會成為應(yīng)用的瓶頸。

  • 可讀性
    序列化后的二進(jìn)制數(shù)據(jù)往往不具備人眼可讀性,為了驗(yàn)證序列化結(jié)果的正確性,寫入方不得同時(shí)撰寫反序列化程序,如果序列化后的數(shù)據(jù)人眼可讀,這將大大提高調(diào)試效率, XML 和 JSON 就具有人眼可讀的優(yōu)點(diǎn)。

參考文獻(xiàn):
https://www.infoq.cn/article/serialization-and-deserialization
http://cn.voidcc.com/question/p-prmzkbxa-mb.html
https://www.liaoxuefeng.com/wiki/1016959663602400/1017624706151424
https://studygolang.com/articles/7855
https://hhbbz.github.io/2017/06/25/%E4%BB%8EDubbo%E6%B5%85%E8%B0%88RPC%E5%92%8CHTTP/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,626評論 1 32
  • JAVA序列化機(jī)制的深入研究 對象序列化的最主要的用處就是在傳遞,和保存對象(object)的時(shí)候,保證對象的完整...
    時(shí)待吾閱讀 11,176評論 0 24
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 12,332評論 6 13
  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當(dāng)在唯一索引所對應(yīng)的列上鍵入重復(fù)值時(shí),會觸發(fā)此異常。 O...
    我想起個好名字閱讀 5,943評論 0 9
  • [toc] 定義#### 序列化:將對象或數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換成約定格式數(shù)據(jù)的過程。反序列化:將約定格式的數(shù)據(jù)轉(zhuǎn)換成對象或...
    yswwpp閱讀 1,478評論 0 1

友情鏈接更多精彩內(nèi)容