V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
x97bgt
V2EX  ›  程序员

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

  •  
  •   x97bgt · 2022-03-07 13:30:48 +08:00 · 3997 次点击
    这是一个创建于 1022 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    现在我的理解是这样

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

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

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

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

    25 条回复    2022-03-08 16:05:23 +08:00
    sutra
        1
    sutra  
       2022-03-07 13:41:03 +08:00   ❤️ 1
    序列化是目标,编码是方法。我们可以通过方法是实现目标。
    maichael
        2
    maichael  
       2022-03-07 13:45:01 +08:00   ❤️ 2
    按照维基的定义来说,“编码是信息从一种形式或格式转换为另一种形式的过程”。

    而“序列化”其实本身也是“信息从一种形式或格式转换为另一种形式的过程”,所以有人称”序列化“是”编码“的一个示例或者是”编码“的子集。
    masterclock
        3
    masterclock  
       2022-03-07 13:51:53 +08:00
    编码 不是 表示将文本转化成字节流
    编码 跟 文本、字节流 等没有关系,比如 “高电平代表 1”、曼切斯特编码、ASCII 、Unicode
    x97bgt
        4
    x97bgt  
    OP
       2022-03-07 14:13:13 +08:00
    @masterclock 那定义是什么?
    1423
        5
    1423  
       2022-03-07 14:21:10 +08:00
    一个对象 encode 成 json 。这个 json 可能也是以树状数据结构保存在内存中的,要想传输或者保存成文件,仍然需要讲 json serialize 成字节流
    darknoll
        6
    darknoll  
       2022-03-07 14:45:55 +08:00   ❤️ 1
    从内存中表示到字节序列的转换称为 编码( Encoding ) (也称为 序列化( serialization ) 或 编组( marshalling )),反过来称为 解码( Decoding )(解析( Parsing ),反序列化( deserialization ),反编组 (unmarshalling ))
    hbdh5
        7
    hbdh5  
       2022-03-07 15:03:08 +08:00
    的确有很多东西混在了一起,说说我的理解把

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

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

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

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

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

    大佬可以解释下,将 object 序列化成 json ,再传输到网络中,这里面进行了哪些编码 /序列化么?有人说这里就 1 个序列化有人说这里有 2 个。
    fallingg
        9
    fallingg  
       2022-03-07 15:20:30 +08:00 via iPhone   ❤️ 1
    serialization 表示将某种程序里的对象(对象元信息例如字段、类)转换为字节流进行传输、存储。deserialization 表示将字节流转换成程序里的对象。json 是一种高层编码格式,目的是将不同的对象统一成同一种模型,不同的对象指的是 java 里的对象,python 里的对象,go 里的对象(字段+对应内存偏移的数据),那么 json 到字节的映射则使用更底层的编码,如 ascii 或者 utf-8 。
    fallingg
        10
    fallingg  
       2022-03-07 15:22:22 +08:00 via iPhone
    @fallingg 对象包含元信息+存储在内存里的数据。
    Cielsky
        11
    Cielsky  
       2022-03-07 15:32:20 +08:00 via Android
    @x97bgt 简陋的说,编码就是把人能理解的自然语言变成机器可以理解的语言,解码就是逆过程
    icyalala
        12
    icyalala  
       2022-03-07 15:33:57 +08:00
    so 有同样问题: https://stackoverflow.com/questions/3784143/what-is-the-difference-between-serializing-and-encoding

    楼主不妨再把音视频编解码的概念也加进来看看
    x97bgt
        13
    x97bgt  
    OP
       2022-03-07 15:34:06 +08:00
    @fallingg 对。我的想法跟你一样,json 是对象和字节流的中间层。
    GSNote
        14
    GSNote  
       2022-03-07 15:54:37 +08:00
    序列化过程除了使用编码,应该还需要做一些其他工作。个人的浅显认知。
    hbdh5
        15
    hbdh5  
       2022-03-07 16:06:22 +08:00
    @x97bgt 你能问出这样的问题代表你根本都没细看我的回答,让我把你的提问换一个形式类似的表述把。3 究竟是等于 2+1 还是 1+1+1 ?
    guyuesh2
        16
    guyuesh2  
       2022-03-07 16:25:50 +08:00
    @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
        17
    shyling  
       2022-03-07 16:34:56 +08:00
    个人觉得编码定义包含序列化。。。序列化特殊在编码的目标是一个“序列”。
    w4n9hu1
        18
    w4n9hu1  
       2022-03-07 17:20:31 +08:00 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
        19
    cnuser002  
       2022-03-07 17:47:30 +08:00
    我的理解

    编码 = 一切 -> 二进制 ,

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

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

    但后来 灵活 > 效率

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

    所以具体实现变成

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


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


    protobuf 则又变回去了,

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

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

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

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

    关于数字视频编码为什么不叫视频序列化,我个人认为这可能是从模拟设备时代继承的说法,视频的编码确实是通过电路编码并调制;另一方面可能是因为序列化这个词更强调对程序对象的操作,而视频不太像是一种程序的对象。
    cheng6563
        21
    cheng6563  
       2022-03-07 17:58:28 +08:00
    程序里的原始数据,比如 c 语言不含指针的 struct ,其他语言也能根据顺序按 byte 凑合读,所以无需编码序列化就可以直接丢给其他语言。

    Java 对象的原始数据,只有 jvm 认,甚至里面一定有一堆指针之类关系到运行时的东西,丢给另一个 JVM 进程也没法读。所以必须要先把指针什么的都转成值,这就是序列化。编码指的就是序列化之后的数据是怎么存的,是存成 json 或者 xml 。
    Protobuf 可以看做跨平台优化的 struct
    3dwelcome
        22
    3dwelcome  
       2022-03-07 18:10:49 +08:00
    以前的 word 存盘文档就是序列化,直接把内存对象输出到磁盘。

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

    在 web 领域很少用这些,你真的序列化后,就没办法和别人交换数据了。web api 大多被设计成 json ,因为不只是自己公司同事要读取,也要让别人也能方便读取。
    zvl0reqglvd
        23
    zvl0reqglvd  
       2022-03-07 19:25:40 +08:00
    编码是写代码,将数据按规律编写,
    序列化是将对象转换成字节流,
    反序列化是将字节流重新组装成对象。
    wqhyw
        24
    wqhyw  
       2022-03-08 14:47:06 +08:00
    kilasuelika
        25
    kilasuelika  
       2022-03-08 16:05:23 +08:00 via Android
    序列化一般特指计算机编程中对象的持久化。
    编码的含义就广泛得多了,比如 DNA“编码”了遗传信息。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1001 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 21:13 · PVG 05:13 · LAX 13:13 · JFK 16:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.