引言
每次坐下来写一篇博客总结的时候都会先长长的舒一口气,从被一个问题困扰开始,到最后搞清楚弄明白原理,其间经历的过程就像从窒息的环境中慢慢恢复呼吸。作为一个计算机专业的学生,大学四年的时间竟然从没仔细思考过编码与解码的细节是惭愧的,只记得当年老师讲过的一条真理:”遇到编码的问题统一选utf8就好了”。知其然不知其所以然,我曾无数次鄙视过我的灵魂,此时此刻就是无数次中的一次。
字符编码的由来
字符编码的历史网上有很多篇文章介绍,其实弄明白了这些关于编码的困惑也就解决一多半了,下面我试着看看能否可以解释清楚。
我们知道计算机的发明者是美国的大佬们,从计算机出现的那天起关于编码的问题也就伴随着出现了。因为计算机中只可以存储0-1形式的机器码,其实0-1对应的就是计算机硬件中一个开关的打开与闭合。对于编程人员来说,用0-1这种机器码去写程序显然是很不友好的,于是就出现了编程语言,编程语言是一些我们可以看懂的字符,它极大的解放了编程人员,但是另一方面对人类友好也就意味着对机器不友好,计算机是不认识这些字符的,所以自然而然编码和解码就登上了历史的舞台。
最先出现的编码格式是ASCII码,这种编码规则是美国人制定的,大致的规则是用一个字节(8个bit)去表示出现的字符,其实由于在老美的世界里中总共出现的字符也不超过128个,而一个字节能够表示256种字符,所以当时这种编码的方式是没有问题的。
后来计算机在全世界普及起来,不同国家的语言都面临着如何在计算机中表示的问题,比如我们的汉字常用的就有几千个,显然最开始一个字节的ASIIC码表示就不够用了,这个时候就出现了Unicode编码,确切的说它只是一种表示规则,并不对应具体的实现形式。Uni-这个前缀在英文中表示的是统一的含义,它试图把全世界的语言用一种统一的编码表示,但是Unicode只规定了字符对应的二进制数据,但是没有规定这种二进制数据在内存中具体用几个字节存储,然后就乱套了,各国在实现Unicode时都发挥了自己的聪明才智,出现了类似utf-16,utf-32等等的形式,在这种情况下,Unicode的理想并没有实现,直到互联网的普及,utf-8的出现,utf-8的出现真正实现了大一统,它在实现Unicode规范的同时,又扩展了自己的规则,utf-8规定了任意一种字符编码后的机器码都是占用6个字节。
关于Bytes
很多人在这里有个误会,就是容易把Bytes和编程语言里的其它数据类型混淆,其实Bytes才是计算机里真正的数据类型,也是网络数据传输中唯一的数据格式,什么Json,Xml这些格式的字符串最后想传输也都得转成Bytes的数据类型才能通过socket进行传输,而Bytes的数据与字符串类型数据的转换就是编码与解码的转换,utf-8是编解码时指定的格式。
这里再简单说一下序列化与反序列化,序列化可以分为本地和网络,对于本地序列化,往往就是将内存中的对象持久化到本地的硬盘,此时序列化做的工作就是将对象和一些对象的相关信息序列化成字符串,然后字符串以某种格式(比如utf-8)进行编码变成bytes类型,存储到硬盘。反序列化就是先将硬盘中的bytes类型中的数据读到内存经过解码变成字符串,然后对字符串进行反序列化解析生成对象。
网络中传输的数据一般为Json和Xml,此时序列化是指将对象变成Json类型的字符串,传输时同样需要将序列化后的字符串变成Bytes类型,反序列化是先将拿到的Bytes类型的数据变成Json类型的字符串(这一步框架往往会帮我们做),然后真正的反序列化是指将Json类型的字符串变成Json类型的对象。(这里注意区分Json类型的字符串和Json类型的对象)
最后
最后还是想再强调一下,不要把序列化和反序列化与编码和解码的问题混淆,这是两个不同维度的概念,如果暂时不太理解编解码的问题也不要着急,遇到程序中的编码问题时记得多思考一下就好了。
————————————————
版权声明:本文为CSDN博主「AlgoLin」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kobebryantlin0/article/details/77418358