偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試官:詳細(xì)說說你對(duì)序列化的理解

開發(fā) 前端
為什么我們要序列化?因?yàn)槲覀冃枰獙?nèi)存中的對(duì)象存儲(chǔ)到媒介中,或者我們需要將一個(gè)對(duì)象通過網(wǎng)絡(luò)傳輸?shù)搅硗庖粋€(gè)系統(tǒng)中。

本文轉(zhuǎn)載自微信公眾號(hào)「愛笑的架構(gòu)師」,作者雷小帥。轉(zhuǎn)載本文請(qǐng)聯(lián)系愛笑的架構(gòu)師公眾號(hào)。

凡事都要問為什么,在講解序列化概念和原理前,我們先來了解一下為什么需要序列化。

為什么要序列化?

如果光看定義我想你很難一下子理解序列化的意義,那么我們可以從另一個(gè)角度來感受一下什么是序列化。

都玩過游戲么?玩過的同學(xué)應(yīng)該知道游戲里有一個(gè)叫『存檔』的功能,每次不想玩的時(shí)候可以把當(dāng)前進(jìn)度存檔,下次有時(shí)間想玩的時(shí)候,直接載入存檔就可以接著玩了,這樣的好處是之前的游戲進(jìn)度不會(huì)丟失,要是每次打開都重新玩估計(jì)大家也沒什么耐心了。

如果把面向?qū)ο蟮乃枷霂У接螒虻氖澜纾窃谖覀冄壑胁还苁怯螒蚪巧€是游戲中的怪獸、裝備等等都可以看成是一個(gè)個(gè)對(duì)象:

  • 角色對(duì)象(包含性別、等級(jí)、經(jīng)驗(yàn)值、血量、傷害值、護(hù)甲值等屬性)
  • 怪獸對(duì)象(包含類型、血量、等級(jí)等等屬性)
  • 裝備對(duì)象(包含類型、傷害值、附加值等等屬性)

在玩游戲的過程中創(chuàng)建一個(gè)游戲角色就好像是創(chuàng)建了一個(gè)角色對(duì)象,拿到一套裝備就好像創(chuàng)建了一個(gè)裝備對(duì)象,路上遇到的怪獸等等也都是對(duì)象了。

我們?cè)儆糜?jì)算機(jī)的思維去思考,創(chuàng)建的這些對(duì)象都是保存在內(nèi)存中的,大家都知道內(nèi)存的數(shù)據(jù)是短暫保留的,斷電之后是會(huì)消失的,但是游戲經(jīng)過手動(dòng)存檔之后就算你關(guān)機(jī)幾天了,再次進(jìn)入游戲讀取存檔,你會(huì)發(fā)現(xiàn)之前在游戲中創(chuàng)建的角色和裝備都還在呢,這就很奇怪了,明明內(nèi)存的數(shù)據(jù)斷電就消失了,這是為什么?

稍加思考就知道,我們?cè)诖鏅n的過程中就是將內(nèi)存中的數(shù)據(jù)存儲(chǔ)到電腦的硬盤中,硬盤的數(shù)據(jù)在關(guān)機(jī)斷電后是不會(huì)丟失的(別杠,硬盤損壞數(shù)據(jù)丟失先不考慮)。這個(gè)過程就是對(duì)象的持久化,也就是我們今天要講的對(duì)象序列化。對(duì)象的序列化逆過程就叫做反序列化,反序列化也很好理解就是將硬盤中的信息讀取出來形成對(duì)象。

什么是序列化?

前面引入游戲的例子是為了讓大家生動(dòng)地理解什么是序列化和反序列化。簡(jiǎn)單總結(jié)一下就是:

  • 序列化是指將對(duì)象實(shí)例的狀態(tài)存到存儲(chǔ)媒體的過程
  • 反序列化是指將存儲(chǔ)在存儲(chǔ)媒體中的對(duì)象狀態(tài)裝換成對(duì)象的過程

用更為抽象的概念來講:

序列化:把對(duì)象轉(zhuǎn)化為可傳輸?shù)淖止?jié)序列過程

反序列化:把字節(jié)序列還原為對(duì)象的過程

序列化的機(jī)制

序列化最終的目的是為了對(duì)象可以跨平臺(tái)存儲(chǔ)和進(jìn)行網(wǎng)絡(luò)傳輸,而我們進(jìn)行跨平臺(tái)存儲(chǔ)和網(wǎng)絡(luò)傳輸?shù)姆绞骄褪?IO,而 IO 支持的數(shù)據(jù)格式就是字節(jié)數(shù)組。

那現(xiàn)在的問題就是如何把對(duì)象轉(zhuǎn)換成字節(jié)數(shù)組?這個(gè)很好辦,一般的編程語言都有這個(gè)能力,可以很容易將對(duì)象轉(zhuǎn)成字節(jié)數(shù)組。

仔細(xì)一想,我們單方面的把對(duì)象轉(zhuǎn)成字節(jié)數(shù)組還不行,因?yàn)闆]有規(guī)則的字節(jié)數(shù)組我們是沒辦法把對(duì)象的本來面目還原回來的,簡(jiǎn)單說就是將對(duì)象轉(zhuǎn)成字節(jié)數(shù)組容易但是將字節(jié)數(shù)組還原成對(duì)象就難了,所以我們必須在把對(duì)象轉(zhuǎn)成字節(jié)數(shù)組的時(shí)候就制定一種規(guī)則(序列化),那么我們從 IO 流里面讀出數(shù)據(jù)的時(shí)候再以這種規(guī)則把對(duì)象還原回來(反序列化)。

還是拿上面游戲那個(gè)例子,我們將正在玩的游戲存檔到硬盤,序列化就是將一個(gè)個(gè)角色對(duì)象和裝備對(duì)象存儲(chǔ)到硬盤,然后留下一張?jiān)瓉韺?duì)象的結(jié)構(gòu)圖紙,反序列化就是將硬盤里一個(gè)個(gè)對(duì)象讀出來照著圖紙逐個(gè)還原恢復(fù)。

常見序列化的方式

序列化只是定義了拆解對(duì)象的具體規(guī)則,那這種規(guī)則肯定也是多種多樣的,比如現(xiàn)在常見的序列化方式有:JDK 原生、JSON、ProtoBuf、Hessian、Kryo等。

(1)JDK 原生

作為一個(gè)成熟的編程語言,JDK自帶了序列化方法。只需要類實(shí)現(xiàn)了Serializable接口,就可以通過ObjectOutputStream類將對(duì)象變成byte[]字節(jié)數(shù)組。

JDK 序列化會(huì)把對(duì)象類的描述信息和所有的屬性以及繼承的元數(shù)據(jù)都序列化為字節(jié)流,所以會(huì)導(dǎo)致生成的字節(jié)流相對(duì)比較大。

另外,這種序列化方式是 JDK 自帶的,因此不支持跨語言。

簡(jiǎn)單總結(jié)一下:JDK 原生的序列化方式生成的字節(jié)流比較大,也不支持跨語言,因此在實(shí)際項(xiàng)目和框架中用的都比較少。

(2)ProtoBuf

谷歌推出的,是一種語言無關(guān)、平臺(tái)無關(guān)、可擴(kuò)展的序列化結(jié)構(gòu)數(shù)據(jù)的方法,它可用于通信協(xié)議、數(shù)據(jù)存儲(chǔ)等。序列化后體積小,一般用于對(duì)傳輸性能有較高要求的系統(tǒng)。

(4)Hessian

Hessian 是一個(gè)輕量級(jí)的二進(jìn)制 web service 協(xié)議,主要用于傳輸二進(jìn)制數(shù)據(jù)。

在傳輸數(shù)據(jù)前 Hessian 支持將對(duì)象序列化成二進(jìn)制流,相對(duì)于 JDK 原生序列化,Hessian序列化之后體積更小,性能更優(yōu)。

(5)Kryo

Kryo 是一個(gè) Java 序列化框架,號(hào)稱 Java 最快的序列化框架。Kryo 在序列化速度上很有優(yōu)勢(shì),底層依賴于字節(jié)碼生成機(jī)制。

由于只能限定在 JVM 語言上,所以 Kryo 不支持跨語言使用。

(6)JSON

上面講的幾種序列化方式都是直接將對(duì)象變成二進(jìn)制,也就是byte[]字節(jié)數(shù)組,這些方式都可以叫二進(jìn)制方式。

JSON 序列化方式生成的是一串有規(guī)則的字符串,在可讀性上要優(yōu)于上面幾種方式,但是在體積上就沒什么優(yōu)勢(shì)了。

另外 JSON 是有規(guī)則的字符串,不跟任何編程語言綁定,天然上就具備了跨平臺(tái)。

總結(jié)一下:JSON 可讀性強(qiáng),支持跨平臺(tái),體積稍微遜色。

JSON 序列化常見的框架有:

fastJSON、Jackson、Gson 等。

序列化技術(shù)的選型

上面列舉的這些序列化技術(shù)各有優(yōu)缺點(diǎn),不能簡(jiǎn)單地說哪一種就是最好的,不然也不會(huì)有這么多序列化技術(shù)共存了。

既然有這么多序列化技術(shù)可供選擇,那在實(shí)際項(xiàng)目中如何選型呢?

我認(rèn)為需要結(jié)合具體的項(xiàng)目來看,比較技術(shù)是服務(wù)于業(yè)務(wù)的。你可以從下面這幾個(gè)因素來考慮:

(1)協(xié)議是否支持跨平臺(tái)

如果一個(gè)大的系統(tǒng)有好多種語言進(jìn)行混合開發(fā),那么就肯定不適合用有語言局限性的序列化協(xié)議,比如 JDK 原生、Kryo 這些只能用在 Java 語言范圍下,你用 JDK 原生方式進(jìn)行序列化,用其他語言是無法反序列化的。

(2)序列化的速度

如果序列化的頻率非常高,那么選擇序列化速度快的協(xié)議會(huì)為你的系統(tǒng)性能提升不少。

(3)序列化生成的體積

如果頻繁的在網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù)那就需要數(shù)據(jù)越小越好,小的數(shù)據(jù)傳輸快,也不占帶寬,也能整體提升系統(tǒng)的性能,因此序列化生成的體積就很關(guān)鍵了。

小結(jié)

(1)為什么我們要序列化?

因?yàn)槲覀冃枰獙?nèi)存中的對(duì)象存儲(chǔ)到媒介中,或者我們需要將一個(gè)對(duì)象通過網(wǎng)絡(luò)傳輸?shù)搅硗庖粋€(gè)系統(tǒng)中。

(2)什么是序列化?

序列化就是把對(duì)象轉(zhuǎn)化為可傳輸?shù)淖止?jié)序列過程;反序列化就是把字節(jié)序列還原為對(duì)象的過程。

(3)序列化的機(jī)制

序列化最終的目的是為了對(duì)象可以跨平臺(tái)存儲(chǔ)和進(jìn)行網(wǎng)絡(luò)傳輸,而我們進(jìn)行跨平臺(tái)存儲(chǔ)和網(wǎng)絡(luò)傳輸?shù)姆绞骄褪?IO,而 IO 支持的數(shù)據(jù)格式就是字節(jié)數(shù)組。

將對(duì)象轉(zhuǎn)成字節(jié)數(shù)組的時(shí)候需要制定一種規(guī)則,這種規(guī)則就是序列化機(jī)制。

(4)常見序列化的方式

現(xiàn)在常見的序列化方式有:JDK 原生、JSON、ProtoBuf、Hessian、Kryo等。

(5)序列化技術(shù)的選型

選型最重要的就是要考慮這三個(gè)方面:協(xié)議是否支持跨平臺(tái)、序列化的速度、序列化生成的體積。


責(zé)任編輯:武曉燕 來源: 愛笑的架構(gòu)師
相關(guān)推薦

2020-12-04 06:27:04

序列化面試官Java

2021-11-25 10:18:42

RESTfulJava互聯(lián)網(wǎng)

2021-08-09 07:47:40

Git面試版本

2020-12-01 08:47:36

Java異常開發(fā)

2020-06-12 15:50:56

options前端服務(wù)器

2022-11-08 11:26:13

Go逃逸代碼

2021-09-16 07:52:18

算法應(yīng)用場(chǎng)景

2021-11-09 14:08:45

DockerDockerfileJava

2019-05-10 10:50:04

Spring AOPJDK動(dòng)態(tài)代理CGLIB動(dòng)態(tài)代理

2021-05-28 11:18:50

MySQLbin logredo log

2021-11-09 08:51:13

模式命令面試

2021-11-05 07:47:56

代理模式對(duì)象

2021-11-02 22:04:58

模式

2021-11-10 07:47:49

組合模式場(chǎng)景

2021-11-03 14:10:28

工廠模式場(chǎng)景

2021-08-16 08:33:26

git

2021-09-26 10:57:16

集合操作場(chǎng)景

2021-09-27 06:50:04

非線性數(shù)據(jù)

2021-09-06 10:51:27

TypeScriptJavaScript

2021-09-28 07:12:09

測(cè)試路徑
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)