# 计算机如何存储数据
## 简介
之前完全不明白如 **Unicode**,**UTF-8**等名词,加上 Java 中又有 **char** 类型,一直没有搞明白**字符**的概念,刚好看到知乎免费视频教程-[方应杭的科普视频],觉得非常通俗易懂,有必要用文字记录一下。
## 为什么要学编程基础
因为你首先要是一个程序员,其次才是一个前端,或是一个 Android 开发者。
一个程序员需要知道
* 硬件与软件:计算机的运行原理,推荐阅读 [编码]
* 最大的软件:操作系统,因为是 Android ,可以阅读 Linux 知识[鸟哥的私房菜]
* 自己写软件:[数据结构与算法分析Java],[算法第4版]
* 多人写软件:[代码大全]
* 个人补充(网络):[图解HTTP],[图解TCP/IP]
## 计算机:二进制的世界
1110 0100 1011 1101 1010 0000 1110 0101 1010 0101 1011 1101
上面一行数字就是“你好”在计算机里的表达方式
### 先从计算机能明白的东西开始:内存如何存储 0 和 1 ?

内存条中间有一块块方块,每个方块上就有很多存“0”和“1”的机关,可以把一个机关想象成一个圆点,一个圆点就是一个电池,那么就有了下面几个环节
假设我们每个方块都是一个小电池,当我们要存储时,先选定一列方块,开始每行充电,如果是“1”就充电,是“0”就不充电

由于这样是无法存储电量的,充电的速度是几纳秒,耗电的速度是几毫秒,计算机采取的做法是在耗完电之前再充一次,这里就依赖 CPU 的赫兹数值,CPU 的多少赫兹就代表每秒可以充多少次电。
### 如何存储数字
我们平时说的数字一般都是指十进制,那么十进制变成计算机懂的二进制是非常方便的。
但也有一些特殊情况,如果想存 `-37` 就需要使用**补码**(计算机无法存储负号);如果想存 `0.75` 就需要使用**浮点数**(计算机无法存储小数点)。
### 如何存储字符
为每个字符编号,使用**ASCII美国信息交换标准代码**,如果你想存储 a,那么就存储 97 对应的二进制:`a -> 0110 0001 `

### 如何存储中文
上述的表中并没有设定中文,所以国家推出了**GB2312中国国家标准简体中文字符集**,共收录 6763 个汉字,同时收录了包括拉丁字母,希腊字母,日文平假名及片假名字母,俄语西里尔字母在内的 682 个字符。

如果我们现在需要“丁”,那就先把 `B6A0` 转换为二进制 `1011 0110 1010 0000`,再加上 1 ,`1011 0110 1010 0001`,这样我们就为 6763 个汉字都编上了号。
但由于收录的文字都是常用字,所以微软退出了**GBK 字符集**,包含了生僻字、繁体字、日语、朝鲜语等,可以这样理解**GBK 字符集**与**GB2312**的使用方法完全一致,只是前者所支持的字符更多。(字符采用的是双字节)
### 如何存储所有字符
将全球字符编号,**Unicode字符集**(Unicode:统一编码),包括中日韩文字、藏文、盲文、楔形文字、颜文字、绘文字。2016年6月时,Unicode 总共有 128237 个字符。因为要存储非常多的字符,所以 Unicode 使用了 4 个字节来存储一个字符。
### 如何将 Unicode 存储到计算机中
因为 Unicode 需要使用 32 位(4字节)来存储字符,那么假设我们现在要存储一个“a”,
~~~
//低性价比
a -> 0000 0000 0000 0000 0000 0000 0110 0001 = 0061
你 -> 0000 0000 0000 0000 0100 1111 0110 0000 = 4F60
~~~
~~~
//高性价比
a -> 01100001
你 -> 11100100 10111101 10100000
~~~
这种算法就叫 **UTF-8**,**UTF-8**是**Unicode**存到计算机的一种编码方式,它不是字符集。
~~~
00000000 00000000 00000000 01111111 即小于 0000007F
0XXXXXXX
00000000 00000000 00000111 11111111 即小于 000007FF
110XXXXX 10XXXXXX
00000000 00000000 11111111 11111111 即小于 0000FFFF
1110XXXX 10XXXXXX 10XXXXXX
00000000 00011111 11111111 11111111 即小于 001FFFFF
11110XXX 10XXXXXX 10XXXXXX 10XXXXXX
~~~
## 总结
学习了几个名词的概念:**ASCII标准**、**GB2312**、**Unicode**、**UTF-8**.
[图解TCP/IP]:https://book.douban.com/subject/24737674/
[图解HTTP]:https://book.douban.com/subject/25863515/
[算法第4版]:https://book.douban.com/subject/19952400/
[数据结构与算法分析Java]:https://book.douban.com/subject/3351237/
[代码大全]:https://book.douban.com/subject/1477390/
[鸟哥的私房菜]:https://wizardforcel.gitbooks.io/vbird-linux-basic-4e/content/index.html
[编码]:https://book.douban.com/subject/4822685/
[方应杭的科普视频]:https://zhuanlan.zhihu.com/p/27580929
