2

关于序列化和编码这两个概念的疑惑

 3 years ago
source link: https://www.v2ex.com/t/838587
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  程序员

关于序列化和编码这两个概念的疑惑

  x97bgt · 20 小时 43 分钟前 · 1432 次点击

一直搞不清序列化和编码这两个概念,感觉有很多东西混在了一起。。。

现在我的理解是这样

  • 编码表示将文本转化成字节流,以便放到内存或网络传输。最常见的是 Unicode 和 ASCII ,还有 GB2312 等等。
  • 序列化其实可以分成两类:
    • 将对象变成字节流,比如用 unicode 编码字符串,或用 Protobuf 编码对象。这里面只涉及编码这一步。
    • 将对象转换成公共的格式。比如,把对象变成 json 或 xml 。

而 json/xml 最后用 unicode 编码成字节流(可能有做一些压缩空格之类的预处理),才到网络中传输。

  • 我之前常常把 json 和 protobuf 划为对等,都认为是编码方式,但其实是 protobuf 和 Unicode 才是对等的。
  • json/xml 是数据交换格式,表示如何把对象变成文本,而 protobuf 并不是,因此不能以文本表示这个数据(只能用字节流表示)。json/xml 和 protobuf 不是同一个地位上的东西。
  • 数据交换格式也可以定义自己的转换成字节流的编码方式,但一般是用 Unicode ,因为运用最广泛。

不知道我这样理解对不对?

23 条回复    2022-03-07 19:25:40 +08:00

sutra

sutra      20 小时 33 分钟前   ❤️ 1

序列化是目标,编码是方法。我们可以通过方法是实现目标。

maichael

maichael      20 小时 29 分钟前   ❤️ 2

按照维基的定义来说,“编码是信息从一种形式或格式转换为另一种形式的过程”。

而“序列化”其实本身也是“信息从一种形式或格式转换为另一种形式的过程”,所以有人称”序列化“是”编码“的一个示例或者是”编码“的子集。

masterclock

masterclock      20 小时 22 分钟前

编码 不是 表示将文本转化成字节流
编码 跟 文本、字节流 等没有关系,比如 “高电平代表 1”、曼切斯特编码、ASCII 、Unicode

x97bgt

x97bgt      20 小时 1 分钟前

@masterclock 那定义是什么?

1423

1423      19 小时 53 分钟前

一个对象 encode 成 json 。这个 json 可能也是以树状数据结构保存在内存中的,要想传输或者保存成文件,仍然需要讲 json serialize 成字节流

darknoll

darknoll      19 小时 28 分钟前   ❤️ 1

从内存中表示到字节序列的转换称为 编码( Encoding ) (也称为 序列化( serialization ) 或 编组( marshalling )),反过来称为 解码( Decoding )(解析( Parsing ),反序列化( deserialization ),反编组 (unmarshalling ))

hbdh5

hbdh5      19 小时 11 分钟前

的确有很多东西混在了一起,说说我的理解把

首先序列化,先说广义的序列化,serialization ,serial 的变体,有使其可顺序排列的意思,任何图灵机的数据本来就是有序的。但从实践上讲,考虑到字节序、不同编程语言环境、乃至同一编程语言下不同运行环境上下文的不同,以及 deserialization 的需求,我们一般把运行时数据结构视为黑箱。

于是我们有 serialization ,deserialization.
侧重点是把黑箱的,不是那么 pure 的数据表示为 serial 的数据格式。

编码有也 encode, decode.
这两个概念很像,但他们的侧重点不同。

encode 表达数据的转换过程,从一种信息表示方式转换为另一种信息表示方式。

注意,encode 的过程并没有要求数据的两端有任何性质,而是广义的说一种信息表示方式,并且特别注重信息的转换过程,于是你经常能在密码学和信息论里看到这个词汇。
而 serialization 一般表示之前的数据是不是很 serial 的,经过这个过程变得 serial 了,而 serial 的数据天生就适合 FIFO 这种数据结构,因此一般你在和 serialization 的地方也一般能看到和 xxxStream 一起使用。

x97bgt

x97bgt      19 小时 4 分钟前

@sutra @maichael @masterclock @1423 @darknoll @hbdh5

大佬可以解释下,将 object 序列化成 json ,再传输到网络中,这里面进行了哪些编码 /序列化么?有人说这里就 1 个序列化有人说这里有 2 个。

fallingg

fallingg      18 小时 54 分钟前 via iPhone   ❤️ 1

serialization 表示将某种程序里的对象(对象元信息例如字段、类)转换为字节流进行传输、存储。deserialization 表示将字节流转换成程序里的对象。json 是一种高层编码格式,目的是将不同的对象统一成同一种模型,不同的对象指的是 java 里的对象,python 里的对象,go 里的对象(字段+对应内存偏移的数据),那么 json 到字节的映射则使用更底层的编码,如 ascii 或者 utf-8 。

fallingg

fallingg      18 小时 52 分钟前 via iPhone

@fallingg 对象包含元信息+存储在内存里的数据。

Cielsky

Cielsky      18 小时 42 分钟前 via Android

@x97bgt 简陋的说,编码就是把人能理解的自然语言变成机器可以理解的语言,解码就是逆过程

x97bgt

x97bgt      18 小时 40 分钟前

@fallingg 对。我的想法跟你一样,json 是对象和字节流的中间层。

GSNote

GSNote      18 小时 20 分钟前

序列化过程除了使用编码,应该还需要做一些其他工作。个人的浅显认知。

hbdh5

hbdh5      18 小时 8 分钟前

@x97bgt 你能问出这样的问题代表你根本都没细看我的回答,让我把你的提问换一个形式类似的表述把。3 究竟是等于 2+1 还是 1+1+1 ?

guyuesh2

guyuesh2      17 小时 48 分钟前

@maichael 赞成二楼的看法,总结的很巧妙。

编码更侧重的是信息的表示的方式,比如: 字符 '中国' 的 GBK ,UTF-8,UTF-16 ,UTF-32 编码下的二进制数据流 01 序列是不同的( hexdump 对应编码文件看)


再比如视频文件有 mp4,avi 等等编码方式。压缩文件又有 rar,7z 等编码方式。

之前遇到过一道题目:
1. 请阐述一下你所知道的  ttf,otf 等字体文件,u nicode 字符集,u tf-8 编码,utf-16 编码,ascii 字符集他们之间的相互联系,他们是怎么相互配合实现将 txt 文本文件展示成为人类可以识别的语言文字的?中国字符的 unicode 编码是什么?转换成为 utf-8 编码是多少?(请用二进制表示).如果给你一台计算机拥有基础的 vscode 文本编辑器如何利用 vscode 得到中国两个字的 utf-8 编码?

序列化 /反序列化:更侧重的是数据的内存结构,对于 java 就是怎么把内存中的对象保存到文件中?又是怎么从文件中重新读取到内存中。

shyling

shyling      17 小时 39 分钟前

个人觉得编码定义包含序列化。。。序列化特殊在编码的目标是一个“序列”。

w4n9hu1

w4n9hu1      16 小时 54 分钟前 via iPhone

The from the in-memory representation to a byte sequence is called encoding (also known as serialization or marshalling), and the reverse is called decoding (parsing, deserialization, unmarshalling).i

cnuser002

cnuser002      16 小时 27 分钟前

我的理解

编码 = 一切 -> 二进制 ,

序列化目的 = 对象 -> 二进制 -> 对象

所以序列化 用 二进制编码。

但后来 灵活 > 效率

使用 JSON / XML 这种带自描述的可读文本协议 , 可读性好,扩展性强。

所以具体实现变成

对象 -> 文本 ,文本 -> 对象。


在传和存的时候,直接按字符串走的字符编码 文本 -> 二进制 -> 文本。


protobuf 则又变回去了,

因为 RPC 通信里, 文本 -> 对象 显得效率低。

还是直接转二进制效率高,protobuf 实际上就是把这步做了。

对象 -> protobuf 二进制流 -> 对象

dousha99

dousha99      16 小时 18 分钟前

个人理解:编码将信息转换成码元符号,但码元符号不一定是二进制数字,也可以是幅值、频率、相位等可以承载二进制数字的物理量(或者,如果解码器输出是模拟值,则也可以承载模拟值);而序列化是将在内存中的比特流——通常是程序对象转换成字节流,便于将比特流保存在持久存储介质上以及在不同的计算机系统之间传输。

序列化是编码的一个实例。

关于数字视频编码为什么不叫视频序列化,我个人认为这可能是从模拟设备时代继承的说法,视频的编码确实是通过电路编码并调制;另一方面可能是因为序列化这个词更强调对程序对象的操作,而视频不太像是一种程序的对象。

cheng6563

cheng6563      16 小时 16 分钟前

程序里的原始数据,比如 c 语言不含指针的 struct ,其他语言也能根据顺序按 byte 凑合读,所以无需编码序列化就可以直接丢给其他语言。

Java 对象的原始数据,只有 jvm 认,甚至里面一定有一堆指针之类关系到运行时的东西,丢给另一个 JVM 进程也没法读。所以必须要先把指针什么的都转成值,这就是序列化。编码指的就是序列化之后的数据是怎么存的,是存成 json 或者 xml 。
Protobuf 可以看做跨平台优化的 struct

3dwelcome

3dwelcome      16 小时 3 分钟前

以前的 word 存盘文档就是序列化,直接把内存对象输出到磁盘。

等加载 doc 的时候,再反向序列化回来,变成内存对象。

在 web 领域很少用这些,你真的序列化后,就没办法和别人交换数据了。web api 大多被设计成 json ,因为不只是自己公司同事要读取,也要让别人也能方便读取。

zvl0reqglvd

zvl0reqglvd      14 小时 49 分钟前

编码是写代码,将数据按规律编写,
序列化是将对象转换成字节流,
反序列化是将字节流重新组装成对象。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK