(计算机的数据都是以二进制的补码存储的)
https://m.toutiao.com/is/2TCgfoN/?=计算机组成原理
从现在开始大家跟着我学习软件开发,这样也就意味着我们以后每天都要和计算机打交道,例如使用台式机、笔记本电脑来学Java开发相关的技术,学完以后去公司使用笔记本、台式机来开发Java项目,使用服务器部署Java项目。因此我们需要对整个计算机系统有个基本的了解。
计算机(Computer)俗称电脑,是一种高速计算的电子机器,可以进行数值运算,逻辑判断,能够接收或者是存储信息数据(文本、图片、音频、视频),并且可以按照存储在其内部的程序对海量的数据进行高速、自动化的处理,然后将处理的结果输出的一种现代化的智能电子设备。
日常生产和生活中常见的计算机有手机、平板电脑、笔记本电脑、台式机都是属于计算机,
除此以外还有提供各种应用(电商、支付、物流、金融)的大型服务器集群(Server Cluster),服务器就是一台高配的电脑,服务器一般放在机房,所以一般人是接触不到的,互联网公司一般都会安排Linux运维工程师管理这些服务器,服务器集群就是成千上万台(甚至几十万台,上百万台)高配的电脑。
服务器
计算机几乎无所不在,几乎无所不能
计算机的软硬件的结合实现了生活中的常见需求
计算机系统是由计算机硬件系统和计算机软件系统两部分组成
计算机硬件(Hardware)就是各种客观存在的计算机相关的硬件设备,例如CPU、内存、硬盘、网卡、主板等等。
计算机软件(Software)就是利用计算机相关的硬件设备来完成日常生活中常见的需求,例如听歌、看电影、上网、购物、上网课等等。这些需求都是需要通过计算机的软硬件的协作来共同完成的。
计算机系统组成
CPU(Central Processing Unit) 中文是中央处理器,CPU是计算机中最核心的部件,类似于人的大脑
CPU是由运算器和控制器组成,运算器是负责数据的运算,控制器是用于控制其他设备协同工作。
CPU主要是用来执行计算机指令以及处理计算机软件的数据
内存是计算机的存储部件,内存也被称为内部存储器,内存的作用就是用于暂时存储CPU运算的数据和指令以及和硬盘等外部设备进行数据交换。
CPU可以直接访问内存中的数据,而且读写效率比较高
但是内存的容量一般比较小(16GB-256GB),不能永久存储数据,一旦断电之后就会丢失数据,如果你之前使用过台式机开发程序那么就应该深有感触,台式机关机之后,如果之前的数据没有保留就会丢失,因为台式机没有电池,因此我们以后在使用电脑的使用经常使用快捷键Ctrl+s/Command+s 将数据保存到磁盘,从而实现永久存储数据。
内存的厂商有三星、金斯顿、美商海盗船、威刚等等
硬盘是计算机的存储部件,主要是用于永久存储数据(断电之后数据不会丢失),容量比较大,通常都是TB级,例如1TB,2TB,4TB,8TB,其中1TB=1024GB
CPU不能直接访问硬盘中的数据,如果想要访问硬盘中的数据,需要使用程序将硬盘中的数据加载到内存中再提供给CPU访问。
硬盘分为机械硬盘和固态硬盘
机械硬盘容量大(TB级),价格便宜,读写速度慢,目前主要机械硬盘厂商有希捷、西部数据
固态硬盘容量大(TB级),价格贵,读写速度高,目前主要的固态硬盘厂商有三星、金斯顿
在选配硬盘的时候为了考虑性价比,通常都是机械硬盘和固态硬盘混合使用,例如系统盘都是固态的,数据盘使用机械硬盘,这样开机快,软件运行速度快,节省时间就是挣钱(时间就是金钱)。如果不考虑性价比那么推荐全部使用固态硬盘。
网卡是用于网络上的数据收发,网卡分为有线网卡和无线网卡,日常家用的电脑网卡一般是千兆网卡,而服务器的网卡是万兆网卡。
假如没有软件,普通人(不懂计算机的人)是没有办法利用计算机硬件资源来实现日常生活中常见的需求,例如订外卖、上网、听歌、上网课、看电影、购物等等。
软件出现的目的就是为了让普通人更好地利用计算机硬件的资源来实现日常生活中常见的需求。
软件实现了更好的人机交互
计算机软件的价值大于计算机硬件价值,例如微信的市值价值几千亿RMB
软件是程序员/软件工程师/开发工程师/码农/新型农民工采用某种编程语言(C/C++
/Java/Python/Go/JavaScript/Scala/Kotlin)编写一系列的指令以及不同业务场景产生的数据组成,软件=指令+数据。例如微信聊天的聊天内容就是数据,而发送微信聊天消息就是指令。
软件分为系统软件和应用软件两大类
计算机系统组成
运行在不同操作系统的软件交互方式是不一样的
软件是运行在硬件之上的
应用软件/系统软件都是运行在操作系统上的
操作系统是由操作系统内核(OS Kernel)和操作系统外壳( OS Shell)组成
计算机体系结构
互联网公司的岗位:运营、产品经理、开发、测试、运维、项目经理
开发环境使用的操作系统是Windows或者macOS
Windows11
macOS12
测试环境、生产环境使用的系统是Linux(CentOS、Ubuntu Server)
CentOS7
CentOS8
Ubuntu Server 20.04
在测试环境、生产环境中一个服务可能会有多个实例,比如MySQL服务一般会部署三台服务器
Java工程师的计算机硬件配置只需要重点关注CPU、内存、硬盘即可
学习Java相关的技术用到几十个工具,而且为了有接近真实的项目经验,还要模拟公司的测试环境、生产环境。
大型的分布式系统架构设计
因此我们需要配置非常高(价格贵)的电脑,但是如果以后你的电脑不能满足需求(如果低于32G内存,32G内存对于开发够用),大家可以去购买阿里云或者是腾讯云的云服务器用来模拟公司的测试环境、生产环境。
选笔记本还是台式机?
如果你没有移动办公的需求,那么推荐台式机,因为台式机的性能高于笔记本
如果你有移动办公的需求,那么推荐使用笔记本电脑
MacBookPro
虽然Windows和macOS都可以做Java开发,但是还是推荐初学者选择Windows ,至于理由就是Windows生态相比macOS系统的生态更加完善
计算机常用单位指的是计算机的核心组件(CPU,内存,硬盘,网卡)相关的单位,例如容量单位、速度单位
我们需要了解计算机常用单位,因为它们属于计算机相关的基本常识
在购买电脑的时候,通常都会选择高配置的CPU、内存、硬盘等等,例如Mac Studio已经可以选配128GB内存、8TB固态硬盘
Mac Studio
这里的128GB、8TB就是常见的容量单位
在物理层面,我们使用高低电平来记录信息,通常都是使用高电平表示1,低电平表示0,因此在计算机底层只能识别0和1两种状态。但是0和1能够表示的内容太少了,因此需要更大容量的表示方法,所以出现了如下列表所示的容量单位
它们的换算关系如下所示
1EB=1024PB1PB=1024TB1TB=1024GB1GB=1024MB1MB=1024KB1KB=1024Byte1Byte=8bit
生活中遇到的一个疑问:为什么我买的4T硬盘的实际可用容量大约是3.63TB
因为计算机容量单位是以1024进行换的,但是硬盘厂商是以1000进行换算的
计算机中4TB硬盘换算成字节
4TB=4*1024*1024*1024*1024
硬盘厂商4TB硬盘换算成字节
4TB=4*1000*1000*1000*1000
4T硬盘的实际可用容量
4*1000*1000*1000*1000/1024/1024/1024/1024≈3.63TB
4T硬盘的实际可用容量
网络常用的速度单位是Mbps
网络带宽提供商(长城、电信等等)声称百兆带宽实际上就是100Mbps,但是100M带宽的峰值下载速度也就10MB左右,它们之间的换算关系是100Mbit/s=(100/8)MB/s=12.5MB/s
CPU的速度一般是由CPU的时钟频率所体现的,时钟频率的单位是赫兹(Hz),目前主流的CPU一般都是2GHz以上,而赫兹(Hz)就是秒分之一,也就是每秒钟的周期性变动重复次数的计量。
GHz、MHz和Hz的换算关系如下所示
1KHz=1000Hz1MHz=1000KHz1GHz=1000MHz
假如你的计算机CPU的速度是5GHz
5GHz=5*1000*1000*1000=50 0000 0000
也就是说5GHz的CPU每秒钟的变化次数是50亿次
Windows系统可以在任务管理器的性能栏目中看到CPU的基准速度
我们讲解计算机原码、反码、补码和进制的的目的就是为了后面讲解位运算符的运算原理
生活中的整数分为正整数和负整数,例如+15和-15
计算机如何表示负数?
计算机内部都是采用二进制来存储数据,例如0000 1111和1000 1111
整数分为有符号数和无符号数
有符号数的二进制位由符号位和数据位组成
有符号数的符号位是1,表示这个二进制数是负数
有符号数的符号位是0,表示这个二进制数是正数
无符号数的二进制位都是数据位,不能表示负数,最小值是0
C语言中变量可以使用signed和unsigned来表示有符号数的变量和无符号数的变量
Java语言中没有signed和unsigned这两个关键字
但是Java语言有两个基本数据类型:short和char,它们都是占据2个字节
short的表示范围 -32768 - +32767 有符号数
char的表示范围 0-65535 无符号数
原码、反码、补码都是数据二进制的表示方式
十进制 +15 二进制原码 0000 1111 (一个字节)
十进制 -15 二进制原码 1000 1111 (一个字节)
正数的反码就是原码
十进制 +15 二进制原码 0000 1111 (一个字节) 二进制反码 0000 1111 (一个字节)
负数的反码就是原码的符号位不变,其他位(数据位)按位取反(0变1 1变0)
十进制 -15 二进制原码 1000 1111 (一个字节) 二进制反码 1111 0000 (一个字节)
正数的补码就是原码
十进制 +15 二进制原码 0000 1111 (一个字节) 二进制反码 0000 1111 (一个字节)
二进制补码 0000 1111 (一个字节)
负数的补码是反码+1
十进制 -15 二进制原码 1000 1111 (一个字节) 二进制反码 1111 0000 (一个字节)
二进制补码 1111 0001(一个字节)
关于原码、反码、补码的转换规则
为什么原码、反码、补码需要相互转换
计算机的数据都是以二进制的补码存储的
数据 | 原码表示(一个字节) |
1 | 00000001 |
-1 | 10000001 |
+0 | 00000000 |
-0 | 10000000 |
需求1:使用原码计算1-1
CPU内部只有加法器
十进制1-1
1 - 1 = 1 + -1
1+ -1 转换成二进制原码
0000 0001 + 1000 0001= 1000 0010
1000 0010 转换成十进制结果是-2
为什么不使用原码来存储和计算数据?
需求2:使用反码计算 1-1
数据 | 原码(一个字节) | 反码(一个字节) |
+1 | 0000 0001 | 0000 0001 |
-1 | 1000 0001 | 11111 1110 |
+0 | 0000 0000 | 0000 0000 |
-0 | 1000 0000 | 1111 1111 |
CPU内部只有加法器
十进制1-1
1 - 1 = 1 + -1
1+ -1转换成二进制反码
0000 0001 + 1111 1110=1111 1111
1111 1111 转换成十进制 -127
为什么不使用原码来存储和计算数据
需求3:使用补码来计算1-1
数据 | 原码 | 反码 | 补码 |
+1 | 0000 0001 | 0000 0001 | 0000 0001 |
-1 | 1000 0001 | 1111 1110 | 1111 1111 |
+0 | 0000 0000 | 0000 0000 | 0000 0000 |
-0 | 1000 0000 | 1111 1111 | 0000 0000 |
CPU内部只有加法器
十进制1-1
1 - 1 = 1 + -1
转换成二进制的补码
0000 0001 + 1111 1111 =0000 0000
因为补码解决了原码、反码的两个问题,因此计算机会使用补码来存储和运算数据。
进制是一种计数的方式,也称为进位计数法或者位值计数法,进制使用有限的数字符号表示无限的数值,使用的数字符号的数量称为这种进制的基数或者是底数,例如十进制就是由0-9之间的十个数字组成的。
相同进制类型的数据在进行运算的时候会遵守:加法:逢R进1,减法:借1当R,这里的R表示进制
计算机常用的进制有十进制、二进制、八进制、十六进制四种。
1234=1000+200+30+4=1*10^3 + 2*10^2 + 3*10^1+ 4*10^0
进制名称 | 组成 | 数值示例 | 应用场景 |
二进制 | 0,1 | 1010 | 内存的数据存储 |
八进制 | 0,1,2,3,4,5,6,7 | 017(0开头) | Linux权限系统 |
十进制 | 0,1,2,3,4,5,6,7,8,9 | 10 | 整数默认进制 |
十六进制 | 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f | 0x1F | 数据的内存地址、MAC地址、IPV6地址 |
由于计算机底层只能识别二进制数据,但是生活中使用的是十进制居多,因此会产生十进制和二进制之间的相互转换
除2取余法:使用十进制正整数不断除以2取数余数,直到商为0时将余数逆序排序
需求:将正整数89使用除2取余法转换为二进制
转换过程
使用Windows自带的计算器验证结果
使用Windows自带的计算器验证结果
拆分法:将十进制整数拆分为若干个二进制权重的和,有权重下面写1,没有就写0
但是使用拆分法的时候需要提前了解二进制权重和十进制对应关系关系
二进制权重 | 二进制 | 十进制 |
2^0 | 1 | 1 |
2^1 | 10 | 2 |
2^2 | 100 | 4 |
2^3 | 1000 | 8 |
2^4 | 10000 | 16 |
2^5 | 100000 | 32 |
2^6 | 1000000 | 64 |
2^7 | 10000000 | 128 |
2^8 | 100000000 | 256 |
2^9 | 1000000000 | 512 |
2^10 | 10000000000 | 1024 |
需求:使用拆分法实现将正整数89转换成二进制
89=64+16+8+1
64 32 16 8 4 2 11 0 1 1 0 0 1
加权法:使用二进制中的每个数字乘以当前位的权重再累加起来
需求:将二进制整数 1011001 转成十进制
1011001=1*2^0 + 1*2^3 + 1*2^4 + 1*2^6= 1+8 +16+ 64=89
负整数的十进制转换二进制:求十进制负整数的补码
关于原码、反码、补码的转换规则
正数的原码、反码、补码都一样负数的原码求补码:原码的最高位(符号位)不变,其他位数取反得到反码,反码加1得到补码负数的补码求原码:补码减1得到反码,反码的最高位不变,其他位数取反得到原码
需求:将十进制的负整数-89转换成二进制补码
实现步骤:
因此通过以上的步骤计算机出来负整数-89转换成二进制的结果是1010 0111(一个字节)
如何验证这个结果是正确的?
89+ -89=0
89的二进制 0101 1001
-89的二进制 1010 0111
相加的结果 1 0000 0000
这里的结果产生了高位溢出,最后的结果是0
还可以使用Windows的计算器验证结果
这里的结果默认是64位,从右往左截取8位的结果就是1010 0111
验证结果
负整数的二进制转换为十进制:根据补码求原码
负数的补码求原码:补码减1得到反码,反码的最高位不变,其他位数取反得到原码
需求:将二进制的负整数1010 0111转换成十进制
实现步骤:
101 1001=1*2^0+1*2^3+1*2^4+1*2^5=1+8+16+64=89
上面说到计算机底层只能识别二进制,而我们在计算机中看到的数字、英文、中文等字符都是二进制转换之后的结果。
按照某种规则将字符存储到计算机中称为编码,编码的本质就是将字符转换为字节存储,而反过来将存储在计算机中的二进制数按照某种规则解析显示出来称为解码,解码的本质就是将存储的的字节转换为字符。
字符编码(Character Encoding)就是一套自然语言的字符与二进制数之间的对应规则,例如ASCII字符编码中 字符a对应的二进制是01100001,转换为十进制就是97
如果编码和解码的规则一样就不会出现乱码
例如在Visual Studio Code中以UTF-8编码保存一个文本文件,然后通过GBK编码打开时则会出现中文乱码,而英文部分没有乱码的原因是因为GBK和UTF-8编码处理英文的方式相同。
字符集(Charset)也叫作编码表,是一个系统支持的所有字符的集合,包括各个国家的文字、标点符号、图形符号,数学符号、数字等等。
计算机要准确的存储和识别各种字符集符号,需要进行字符编码,一套字符集必然至少有一套字符集编码。常见字符集有ASCII字符集、GBK字符集、Unicode字符集等。
常用的字符集和字符编码
从上图可知当指定了字符集编码后,它所对应的字符集自然就指定了,因此字符集编码才是我们真正应该关心的。
常用的中文字符集有GB2312,GBK,GB18030
GB2312:简体中文码表。一个小于127的字符的意义与原来相同。但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含7000多个简体汉字,此外数学符号、罗马希腊的字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的'全角'字符,而原来在127号以下的那些就叫'半角'字符了。
GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等。
GB18030:最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字等。
它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,UTF-8、UTF-16和UTF-32,最为常用的UTF-8编码。
UTF-8编码,可以用来表示Unicode标准中任何字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。所以,我们开发Web应用,也要使用UTF-8编码。它使用一至四个字节(可变长度)为每个字符编码,编码规则:
字符集规定了字符对应存储的二进制数,字符集编码规定了字符存储时对应占据的存储空间。
同一段文本内容,使用不同的编码存储所占据的内存大小也是不相同的
测试文本内容
我是中国人 I am Chinese
使用UTF-8编码保存时占据28个字节
UTF-8编码文件大小
使用GBK编码保存时占据23个字节
GBK编码文件大小
因为中文内容'我是中国人'使用GBK编码保存时每个中文字符占据2个字节,而使用UTF-8编码保存时每个中文占据3个字节
语言是人和人之间进行沟通交流的一种表达方式,例如中国人和中国人之间使用汉语进行交流,中国人和美国人之间使用汉语或者是英语进行交流,沟通交流的前提就是要使用双方都能够理解的语言。
计算机语言也叫编程语言,因为学习计算机语言的目的就是为了开发程序(编程)
计算机语言是人(程序员、开发者、软件工程师)和计算机之间进行沟通交流的一种表达方式,该语言有很多种,主流的语言有20多种,我们学习Java开发时会学习Java、SQL、JavaScript、Scala等等
任何事物都是从无到有逐渐发展壮大起来的,计算机语言也是一样的。
计算机语言经历了机器语言、汇编语言、高级语言(高级程序设计语言、高级编程语言)三个阶段,其特点就是让程序的开发、测试、部署变得越来越高效、简单、方便。不过是以牺牲运行效率(性能)为代价的,但是随着计算机硬件的光速发展,在绝大多数应用场景下的性能损失可以忽略不计。
计算机发展的早期,程序员采用二进制(01010101)的机器指令来编写程序,而每种CPU都有各自不同的指令系统(Ultra SPARC/Intel X86/ARM),这样导致在不同的机器上同一套程序需要使用不同的机器语言,机器语言的特点是运行效率最高的,不过面向机器编程的程序是不能移植的,需要手动处理底层硬件的差异性,而且二进制机器指令编写的程序难以理解和维护。
随着时代和计算机技术的发展,后来就出现了汇编语言,汇编语言和汇编器(编译器)的出现解决了机器语言需要记住非常多的机器指令,但是没有从根本上解决程序的移植性问题,只是将机器语言的指令转换成了人类更佳容易理解的英文单词,然后由汇编器编译成机器能够识别的机器指令,因为计算机最终只能够识别二进制的机器指令,而且汇编语言是面向机器的,不同机器的汇编指令是不一样的。尽管如此汇编语言在工业电子编程、软件的加密解密以及计算机病毒分析等等场景使用。
高级语言的高级之处体现在开发人员在编写程序的时候不需要关注计算机底层硬件的差异性,只需要关注实现的业务模块即可。
高级语言需要通过编译器编译程序后执行或者是解释器边解释边运行,而且相比机器语言、汇编语言而言,高级语言更佳容易学,因此会有更佳充足的人力资源来开发大型的商业系统(软件),例如Windows、macOS、Linux、Android、iOS、鸿蒙OS等等操作系统都是使用C/C++以及少量的汇编实现,国内的阿里巴巴在电商、金融、物流、支付 后台等等领域大量使用了Java实现
高级语言按照编程思想分类分成面向过程和面向对象两大类,例如C语言就是面向过程的,Java、Python就是面向对象
高级语言按照运行机制分成编译型和解释型两类
C语言就是编译型,编译型的语言通常不能跨平台,但是效率高于解释型的语言。
Python就是解释型的语言,解释型的语言都是可以跨平台的,但是效率比编译型的语言要低
目前主流的编程语言有哪些?
我们可以访问Tiobe编程排行榜查看当前编程语言的排行榜
Tiobe编程语言排行榜
https://www.tiobe.com/tiobe-index/
Tiobe编程语言排行版
目前(2022年7月份)Python、C和Java排在前三名,紧随其后的是C++、JavaScript、Go等等
Tiobe还提供了编程语言走势图,从历史趋势可以看出Java和C语言是常年霸榜
每种编程语言都是自己擅长的应用场景(开发方向),大家可以根据自己的喜好(市场需求)选择对应的编程语言。
编程语言(高级语言) | 应用场景 |
C | 硬件驱动、操作系统(Linux)、中间件(Redis) |
C++ | 应用软件(PhotoShop、Office、Chrome)、网络通讯、科学计算、游戏 |
C# | Windows应用、Web应用、游戏开发 |
Java | 大型分布式系统(淘宝、天猫、菜鸟物流、顺丰等等)、Android应用、大数据开发、中间件(RocketMQ) |
Go | 云计算(Docker、Kubernates)、大数据、高并发 |
Kotlin | Android应用开发 |
Swift | iOS应用、iPadOS应用、macOS应用 |
Python | 机器学习、自动化运维、自动化测试、Web应用、爬虫 |
JavaScript | 浏览器端、服务端、PC桌面端 |
Scala | 大数据 |
那么如果你作为一名初学者,面对如此之多的编程语言,到底从哪一门语言开始上车
如果你想要深入学习其他语言、框架、中间件、架构的知识之前建议深入掌握Java,因为Java语言上手容易、功能强大,无论是中间件、大数据、大型分布式系统、Android App都可以使用Java开发,目前在招聘市场中需求旺盛,大家可以去招聘网站(Boss直聘、拉勾)搜索了解详细的招聘要求。
Java招聘要求
但是无论学习哪种编程语言,都是实现目标的工具,而不是目标本身。
联系客服