第一课:计算机早期历史
0、课程目标:从高层次总览一系列计算机话题,快速入门计算机科学。
1、计算机技术的影响——进入信息时代
- 出现自动化农业设备与医疗设备
- 全球通信和全球教育机会变得普遍
- 出现意想不到的虚拟现实/无人驾驶/人工智能等新领域
2、计算机的实质:
极其简单的组件,通过一层层的抽象,来做出复杂的操作。
计算机中的很多东西,底层其实都很简单,让人难以理解的,是一层层精妙的抽象。像一个越来越小的俄罗斯套娃。3、关于计算的历史:
- 公元前2500年,算盘出现,为十进制,功能类似一个计数器。
- 公元前2500年-公元1500年:星盘、计算尺等依靠机械运动的计算设备出现
- 公元1613年:computer的概念出现,当时指的是专门做计算的职业,
- 1694年:步进计算器出现,是世界上第一台能自动完成加减乘除的计算器。
- 1694-1900年:计算表兴起,类似于字典,可用于查找各种庞大的计算值。
- 1823年:差分机的设想出现,可以做函数计算,但计划最后失败。
- 19世纪中期:分析机的设想出现,设想存在可计算一切的通用计算机。
1890年:打孔卡片制表机。原理:在纸上打孔→孔穿过针→针泡入汞→电路连通→齿轮使计数+1。
第二课:电子计算机的发展史
1、电子计算机元器件变化:
2、计算机的出现背景:
20世纪人口暴增,科学与工程进步迅速,航天计划成形。以上导致数据的复杂度急剧上升、计算量暴增,对于计算的自动化、高速有迫切的需求。
3、电子计算机的发展:
1945年 哈佛马克1:使用继电器,用电磁效应,控制机械开关,缺点为有磨损和延迟。
*最早还因为有虫子飞进去导致故障,引申出bug=故障的意思。
1943年 巨人1号:使用真空管(三极管),制造出世界上第一个可编程的计算机。
1946年 ENIAC:第一个电子数值积分计算机,为第一台通用计算机。
1947年 晶体管出现,使用的是固态的半导体材料,相对真空管更可靠。
1950s 空军ANFSQ-7: 真空管到达计算极限。
1957年 IBM 608: 第一个消费者可购买的晶体管计算机出现。第三课:布尔逻辑与逻辑门
1、计算机为什么使用二进制:
计算机的元器件晶体管只有2种状态,通电(1)&断电(0),用二进制可直接根据元器件的状态来设计计算机。
- 而且,数学中的“布尔代数”分支,可以用True和False(可用1代表True,0代表False)进行逻辑运算,代替实数进行计算。
计算的状态越多,信号越容易混淆,影响计算。对于当时每秒运算百万次以上的晶体管,信号混淆是特别让人头疼的的。
2、布尔代数&布尔代数在计算机中的实现
变量:没有常数,仅True和False这两个变量。
- 三个基本操作:
-
0)基本操作:
当input打开true,则output为true,打开开关,通电,通水
当input关闭false,则output为false,关闭开关,断电,没啥意思1)NOT操作:
1命名:称为NOT门/非门。
2作用:将输入布尔值反转。输入的True或False,输出为False或True。
3晶体管的实现方式: 半导体通电True,则线路接地,无输出电流,为False。
- 半导体不通电False,则输出电流从右边输出,为True。
个人笔记:自己接一个线在上面作为输出,
打开input(true),接地,上面没电了.输出false
关闭input(false),没法接地,上面就有点了,输出true
2)AND操作
1命名:AND门/与门
2作用:由2个输入控制输出,仅当2个输入input1和input2都为True时,输出才为True,2个输入的其余情况,输出均为False。*可以理解为,2句话(输入)完全没有假的,整件事(输出)才是真的。
3用晶体管实现的方式:
串联两个晶体管,仅当2个晶体管都通电,输出才有电流(True)
3)OR操作
1命名:OR门/或门
2作用:由2个输入控制输出,只要其中一个输入为True,则输出True。
3用晶体管实现的方式:
使用2个晶体管,将它们并联到电路中,只要有一个晶体管通电,则输出有电流(True)。
总结抽象123
1.not:三角形前一个点
2.and:D
3.or:ship飞船
3、特殊的逻辑运算——异或
1命名:XOR门/异或门
2作用:2个输入控制一个输出。当2个输入均为True时,输出False,其余情况与OR门相同。
3图示:
先用一个OR门,将其与AND门并联,AND门与NOT门串联,最后让NOT与AND门并联,获得输出。
笔记:异或实现还挺牛逼的
尝试用java来实现
public class YiHuo {
public static void main(String[] args) {
System.out.println(yihuo(true, true));
System.out.println(yihuo(true, false));
System.out.println(yihuo(false, true));
System.out.println(yihuo(false, false));
}
public static Boolean andGate(Boolean arg1,Boolean arg2){
return arg1 && arg2;
}
public static Boolean orGate(Boolean arg1,Boolean arg2){
return arg1 || arg2;
}
public static Boolean yihuo(Boolean arg1,Boolean arg2){
Boolean temp1 = !andGate(arg1, arg2);
Boolean temp2 = orGate(arg1, arg2);
return andGate(temp1, temp2);
}
}
输出:
false
true
true
false
其实java已经有了
public static Boolean yhGate(Boolean arg1,Boolean arg2){
return arg1 ^ arg2;
}
4、逻辑门的符号表示
1作用:将逻辑门简化,将逻辑门用于构建更大的组件,而不至于太复杂。
2图示:
- 非门:用三角形+圆圈表示
- 与门:用D型图案表示
- 或门:用类似D向右弯曲的图案表示
- 异或门:用或门+一个圆弧表示
5、抽象的好处
使得分工明确,不同职业的工程师各司其职,而不用担心其他细节。
笔记:类似抽象成组件,可以复用,设计更复杂的东西吧
第四课:二进制
1、二进制的原理,存储单元MB/GB/TB解释
0计算机中的二进制表示:
单个数字1或0,1位二进制数字命名为位(bit),也称1比特。
1字节(byte)的概念:
1byte=8bit,即1byte代表8位数字。最早期的电脑为八位的,即以八位为单位处理数据。为了方便,将八位数字命名为1字节(1byte).
2十进制与二进制的区别:
- 十进制有10个数字,0-9,逢10进1(不存在10这个数字),则每向左进一位,数字大10倍。
- 二进制有2个数字,0-1,逢2进1,(不存在2这个数字),则每向左进一位,数字大2倍。
2如何进行二进制与十进制联系起来:
- 将十进制与二进制的位数提取出来,编上单位:
eg.二进制的1011=12^0 + 12^1 + 02^2 + 12^3= 11(从右往左数)
eg.十进制的1045= 110^3 + 010^2 + 410^1 + 510^0
3十进制与二进制的图示:
十进制的263
二进制的10110111
这里相当于是一个8bits,可以表示的范围0-255,代表256个值就是2的8次方
256色游戏图片
4二进制的运算:
相同的位数相加,逢2进1
基本单位:bit
常用单位:byte=8*bit
5 byte在电脑中的单位换算:
1kb=2^10bit = 1024byte =1000b
1TB=1000GB
1GB=十亿字节=1000MB=10^6KB
6 32位与64位电脑的区别
32位的最大数为43亿左右
64位的最大数为9.2*10^18
2、正数、负数、正数、浮点数的表示
1)计算机中表示数字的方法
1整数:
表示方法:
- 第1位:表示正负 1是负,0是正(补码)
- 其余31位/63位: 表示实数
2浮点数(Floating Point Numbers):
定义:小数点可在数字间浮动的数(非整数)
表示方法:IEEE 754标准下
用类似科学计数法的方式,存储十进制数值
- 浮点数=有效位数*指数
- 32位数字中:第1位表示正负,第2-9位存指数。剩下23位存有效位数
eg.625.9=0.6259(有效位数)*10^3(指数)
3、美国信息交换标准代码-ASCⅡ,用来表示字符
1全称:美国信息交换标准代码
2作用:用数字给英文字母及符号编号
3内容:7位代码,可存放128个不同的值。
4图示:
4、UNICODE,统一所有字符编码的标准
1诞生背景:1992诞生,随着计算机在亚洲兴起,需要解决ASCⅡ不够表达所有语言的问题。
为提高代码的互用性,而诞生的编码标准。
2内容:UNICODE为17组的16位数字,有超过100万个位置,可满足所有语言的字符需求。
5,mp3,图片,视频
用二进制编码声音,颜色,照片,视频
包括系统,软件
底层都是bit
第五课:算术逻辑单元
1、什么是算术逻辑单元
1命名:简称ALU,Arithmetic&Logic Unit
2组成:ALU有2个单元,1个算术单元和1个逻辑单元(Arithmetic Unit和Logic Unit)
3作用:计算机中负责运算的组件,处理数字/逻辑运算的最基本单元。
2、算术单元
1)基本组件:
- 由半加器、全加器组成
- 半加器、全加器由AND、OR、NOT、XOR门组成
2)加法运算
1组件:AND、OR、NOT、XOR门
2元素:输入A,输入B,输出(均为1个bit,即0或1)
3半加器:
- 作用:用于计算个位的数字加减。
- 输入:A,B
- 输出:总和,进位
- 抽象:
笔记:把sum看成最右边那一位,把carry看成十位.就可以得到答案,半加器作用在于表达2位的数字
4全加器:
作用:用于计算超过1位的加法,由于涉及进位,因此有3个输入(C充当进位)。
原理图示:
3)如何用半加器与全加器做8位数的加法
1说明:以8位行波加法器为例
- 用半加器处理第1位数(个位)的加法,得到的和为结果的第1位。
- 将输出的进位,输入到第2位用的全加器的输入C中。
- 将第2位的2个数用全加器计算,得到的和为结果的第2位(sum)。
- 将第2位计算的进位连接到百位的全加器输入C中。
- 在第3-8位上,循环第3-4步的操作。
*现在电脑使用的加法器叫“超前进位加法器”
4)算术单元支持的其他运算
这些运算也是通过逻辑门组成的
3、溢出的概念
内容:在有限的空间内,无法存储位数过大的数,则称为溢出。
说明:第8位的进位如果为1,则无法存储,此时容易引发错误,所以应该尽量避免溢出。
4、逻辑单元
作用:执行逻辑操作,如NOT、AND、OR等操作,以及做简单的数值测试。
5、ALU的抽象
1)作用:ALU的抽象让工程师不再考虑逻辑门层面的组成,简化工作。
2)图示:
像一个大“V”。
3)说明:
图示内容包括:
- 输入A,B
- 输出
- 标志:溢出、零、负数
笔记:这里比较有意思,就用java代码实现了8bit加法
public static TwoBit halfAdder(Boolean arg1, Boolean arg2) {
Boolean sum = xorGate(arg1, arg2);//个位等同于异或
Boolean carry = andGate(arg1, arg2);//进位要求同时为true才是true
TwoBit twoBit = new TwoBit();
twoBit.setCarry(carry);
twoBit.setSum(sum);
return twoBit;
}
public static TwoBit fullAdder(Boolean arg1, Boolean arg2, Boolean arg3) {
TwoBit result1 = halfAdder(arg1, arg2);
TwoBit result2 = halfAdder(result1.getSum(), arg3);
TwoBit twoBit = new TwoBit();
Boolean sum = result2.getSum();//个位数 参数1和参数2半加,结果的sum和参数3半加取sum
Boolean carry = orGate(result1.getCarry(), result2.getCarry());//十位数 两次相加,只要任意一次得到1就是1
twoBit.setCarry(carry);
twoBit.setSum(sum);
return twoBit;
}
public static List<Boolean> bit8For(Boolean[] a, Boolean[] b) {
Assert.isTrue(a.length==8);
Assert.isTrue(a.length==8);
List<Boolean> list = new ArrayList<>();
TwoBit result = halfAdder(a[7], b[7]);
list.add(result.getSum());
for (int i = 6; i >=0 ; i--) {
result = fullAdder(result.getCarry(),a[i], b[i]);
list.add(result.getSum());
}
list.add(result.getCarry());
Collections.reverse(list);
System.out.println("位数"+list.size());
return list;
}
测试代码
List<Boolean> booleans = bit8For( new Boolean[]{false, true, true, false, false, true, false, false},
new Boolean[]{true, true, true, false, false, true, false, true});
for (Boolean b : booleans) {
System.out.print(BooleanUtil.toInt(b));
}
//101001001
第六课 寄存器与内存
0、课程导入
当玩游戏、写文档时如果断电,进度会丢失,这是为什么?
- 原因是这是电脑使用的是RAM(随机存取存储器),俗称内存,内存只能在通电情况下存储数据。
- 本节课程将讲述内存的工作原理。
1、概念梳理
锁存器:锁存器是利用AND、OR、NOT逻辑门,实现存储1位数字的器件。
寄存器:1组并排的锁存器
矩阵:以矩阵的方式来存放锁存器的组合件,nn门锁矩阵可存放n^2个锁存器,但同一时间只能写入/读取1个数字。(早期为1616矩阵)
位址:锁存器在矩阵中的行数与列数。eg.12行 8列
多路复用器:一组电线,输入2进制的行址&列址,可启用矩阵中某个锁存器
内存(RAM):随机存取存储器,由一系列矩阵以及电路组成的器件,可根据地址来写入、读取数据。类似于人类的短期记忆,记录当前在做什么事情。2、锁存器
OR锁:
OR门B输入和输出连接。
INIT为初始状态A=B=0;
当A=1,B=0时,OUTPUT变为1同时将B变为1;
此时,当A变回0,OUTPUT仍为1(被锁住)。
AND锁:
AND门B输入和输出连接。
INIT为初始状态A=B=1;
当A=0,B=1时,OUTPUT变为0同时将B变为0;
此时,当A变回1,OUTPUT仍为0(被锁住)。
AND-OR锁存器:英文latch
锁存器有两个输入SET和RESET,其电路如上图连接。
INIT为初始状态SET=RESET=0,最终输出OUTPUT=0;
当SET=1,RESET=0(SET激活、RESET未激活)时,将输出变为1,锁住(可看出SET变为0,结果不变)
此时RESET激活(SET=1,RESET=1),将输出重新变为0,即为重置。
作用:存储1位的信息。
图示:
2.5、门锁:
锁存器需要同时输入2个数字,不太方便。
为了使用更方便,只用1根电线控制数据输入,发展了门锁这个器件。另外,用另一根电线来控制整个结构的开关。(和复位作用不同)
不管细节,直接看功能
允许写入线为0,则数据输入无法改变输出,一直输出同样的内容
允许写入线为1,则数据输入可以改变数据输出,并且保存下来,一直输出3、寄存器
定义:一组锁存器叫做寄存器,寄存器只能存1个数字,这个数字有多少位,叫做位宽,现在计算机多半都是64位宽的寄存器了
作用:并排使用门锁,存储多位数字
图示:
4、门锁矩阵
作用:
nn的矩阵有n^2个位址,则可以存储n^2个数。但1个矩阵只可记录1位数字,n个矩阵组合在一起,才可记录n位数。如1个8位数,会按位数分成8个数,分别存储在8个矩阵的同一个位址中。
8个矩阵,则可以记录256个8位数字。
通俗理解:
1616的门锁矩阵,可理解为1个公寓,1个公寓256个房间。
8个门锁矩阵并排放,则有了8个公寓。
规定每一个公寓同一个编号的房间,都有一样的标记(地址),共同组成8位数字。
那么8个公寓就能存 (8256 / 8)个数字。
原因:
1616的门锁矩阵虽然有256个位置,但每次只能存/取其中1个位置的数字。因此,要表示8位数字,就需要同时调用8个门锁矩阵。
好处:
现在用16行+16列+1数据线+1允许写入线+1允许读取线就可以了.原先要256+3个线
图示:
多路复用器
使用方法:
在多路复用器中输入位址,x行x列(2进制),即可点亮x行x列的锁存器。
举例:
行列数 | 矩阵1 | 矩阵2 | 矩阵3 | 矩阵4 | 矩阵5 | 矩阵6 | 矩阵7 | 矩阵8 |
---|---|---|---|---|---|---|---|---|
1行5列 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 |
2行3列 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
5、内存
粗略定义:将一堆独立的存储模块和电路看做1个单元,组成内存方块,n个内存方块组成内存模块。在一个电路板上所有的内存方块统称为内存(RAM)。
图示:
用锁存器制作了SRAM 静态随机存取存储器,内存技术原理都是矩阵层层嵌套,来存储大量信息
第七课 中央处理器(CPU)
1、概念梳理
- CPU(Central Processing Unit):中央处理单元,负责执行程序。通常由寄存器/控制单元/ALU/时钟组成。与RAM配合,执行计算机程序。CPU和RAM之间用“地址线”、“数据线”和“允许读/写线”进行通信。
- 指令:指示计算机要做什么,多条指令共同组成程序。如数学指令,内存指令。
- 时钟:负责管理CPU运行的节奏,以精确地间隔,触发电信号,控制单元用这个信号,推动CPU的内部操作。
- 时钟速度:CPU执行“取指令→解码→执行”中每一步的速度叫做“时钟速度”,单位赫兹Hz,表示频率。
- 超频/降频:
- 超频,修改时钟速度,加快CPU的速度,超频过多会让CPU过热或产生乱码。
- 降频,降低时钟速度,达到省电的效果,对笔记本/手机很重要。
- 微体系框架:以高层次视角看计算机,如当我们用一条线链接2个组件时,这条线只是所有必须线路的抽象。
动态调整频率 dynamic frequency scaling:现代处理器可以按照需求加快或减慢时钟速度
2、CPU工作原理
1)必要组件:
指令表:给CPU支持的所有指令分配ID
- 控制单元:像指挥部,有序的控制指令的读取、运行与写入。
- 指令地址寄存器:类似于银行取号。该器件只按顺序通报地址,让RAM按顺序将指令交给指令寄存器。
- 指令寄存器:存储具体的指令代码。
2)过程
基本构成,16位的内存,4个存放数据的寄存器,1个指令寄存器,1个地址寄存器
基本阶段
1.取指令:
指令地址寄存器发地址给RAM→RAM发该地址内的数据给指令寄存器→指令寄存器接受数据
2.解码
指令寄存器根据数据发送指令给控制单元 →控制单元解码(逻辑门确认操作码)
涉及计算的执行(add指令),寄存器输入到ALU,相加,结果暂存在ALU,算完以后再放回寄存器A,指令+1结束
3.执行阶段
控制单元执行指令(→涉及计算时→调用所需寄存器→传输入&操作码给ALU执行)→调用RAM特定地址的数据→RAM将结果传入寄存器→指令地址寄存器+1
继续抽象
3)图示:
第一个CPU
4)时钟速度
第八课 指令和程序
1、概念梳理
- 指令:指示计算机要做什么的代码(机器码),多条指令共同组成程序。如数学指令,内存指令。
- 注:指令和数据都是存在同一个内存里的。
- 指令集:记录指令名称、用法、操作码以及所需RAM地址位数的表格。
2、指令的执行
- 原则:
- RAM每一个地址中,都存放0或1个数据。
- 特定的数字组合,就表示为一个指令,否则表示一个值。
- LOAD指令:
- 计算机会按地址的顺序,读取RAM中所记录的指令/数据。
- 计算机接受到指令后,如LOAD_A,则通过数据线将数据传至寄存器A。
- ADD指令:
- ADD B A指令告诉ALU,把寄存器B和寄存器中的数字加起来,存到寄存器A中。
- JUMP指令: