p2.第一章 Python基础入门 -- 冯诺依曼体系和计算机基础 (二)

1.2 核心基础

1.2.1 计算机基础知识

在这里插入图片描述
艾伦·麦席森·图灵(Alan Mathison Turing,1912年6月23日-1954年6月7日),英国数学家、逻辑学家,被称为计算机科学之父,人工智能之父。
图灵提出的著名的图灵机模型为现代计算机的逻辑工作方式奠定了基础。
图灵机已经有输入、输出和内部状态变化机制了。

计算机主要指的电子计算机,电子计算机主要诞生在从美国开始,但是理论从什么时候开始到,它是由英国科学家图灵,计算机界有个重要的奖项,也就是计算机界的诺贝尔奖就是图灵奖,这是一个非常重量级的奖,这个人的名字就叫图灵,有一部电影《模仿游戏》是讲他的,这个人是一个非常厉害的科学家,图灵最大的贡献是数学方面之外,他还提出了一个叫图灵机的这样一个计算机模型,这个计算机它是由输入和输出的,他以及设想了图灵机的模型机,它的一些工作原理他已经设计好了,只不过他没有想到该用什么样的电子产品来解决这样的一个问题,这个电子计算机在他去世的时候也就是1954年也就是二战后,二战之后他也饱受蹂躏一些原因导致他最后很不幸提前离开了人世,但是他做的这个贡献以及他在数学方面的贡献基础对计算机的未来奠定了基础,当然现代计算机跟电子计算机相关的电子工业是分不开的,比如说从电子管时代过度到晶体管时代,然后由硅谷实现了硅晶体制造这样一个过程过来的,有了硅晶体之后就诞生了这些像芯片类的东西,这样计算机才大规模推广开了,不然像早些年电子计算机的话,用的全是电子管,那个规模叫埃尼亚克,就是在美国跟一个足球场一样大这样一个电子计算机,它的计算能力其实跟我们现在个个人PC计算机的能力可能都要超过它了,但是在当时已经非常先进了,在当时它要经过大量的计算,但是这个计算机一旦开机可不得了,整个城市的电压都要往下降,它非常的耗电,占地也非常大,需要很多人协同工作,这是当时的计算机的情况;当出现了晶体管到来之后,尤其是叫硅基的晶体管诞生之后电子计算机随着科学的发展它的体积越来越小,耗电量也降低,而计算能力在逐步的增加,这里边就有个摩尔定律。

在这里插入图片描述
冯·诺依曼著名匈牙利裔美籍犹太人数学家、计算机科学家、物理学家和化学家 ,数字计算机之父。他提出了以二进制作为数字计算机的数制基础,计算机应该按照程序顺序执行,计算机应该有五大部件组成。

对计算机领域做出了很重要的贡献之一的人是冯·诺依曼,它是一个匈牙利裔美籍犹太科学家,但是它最后去了美国,这个人它是一个全面性选手,它在数学方面、计算机方面、物理和化学方面都做出了卓越的贡献,它提出来了以二进制为基础作为计算机数学的运算基础,为什么这么做呢,因为我们发现对于晶体管也罢,对于电子管也罢,它的亮和灭也就是0和1这两种状态这是它的基本状态,就用这样的状态来解决数制的问题,解决了数制的问题就解决了数字的问题,而计算机特别喜欢用开关电路,如果你学习了一些晶体管相关的知识其实这块其实就是开关电路,通过开关电路表示不同状态,然后状态组合在一起就形成了不同的数字,它是用这种方式,它解决了计算机真正的结构体的一些设计,比如说计算机他提出了著名的冯诺依曼体系结构,他说计算机应该由五大部件组成,到今天为止这5大部件依然是我们常见到的计算机体系用到的就是这5大部件,你现在正在用的各种PC,包括你用的手机等等它都是按照这5大部件的方式来设计和构造的。

2.1 冯诺依曼体系

在这里插入图片描述
五大核心部件

  • 中央处理器CPU

    • 运算器:用于完成各种算术运算、逻辑运算和数据传送等数据加工处理。

    • 控制器:用于控制程序的执行,是计算机的大脑。运算器和控制器组成计算机的中央处理器(CPU)。控制器根据存放在存储器中的指令序列(程序)进行工作,并由一个程序计数器控制指令的执行。控制器具有判断能力,能根据计算结果选择不同的工作流程。、

  • 存储器:用于记忆程序和数据,例如:内存。程序和数据以二进制代码形式不加区别地存放在存储器中,存放位置由地址确定。内存是掉电易失的设备。

  • 输入设备:用于将数据或程序输入到计算机中,例如:鼠标、键盘。

  • 输出设备:将数据或程序的处理结果展示给用户,例如:显示器、打印机。

CPU中还有寄存器和多级缓存Cache。

  • CPU并不直接从速度很慢的IO设备上直接读取数据,CPU可以从较慢的内存中读取数据到CPU的寄存器上运算
  • CPU计算的结果也会写入到内存,而不是写入到IO设备上

冯诺依曼体系的5大部件是哪5大部件,CPU一人独占2大部件,然后是存储器,存储器指的是memory,而这个memory翻译过来应该叫内存,还有I/0,CPU+memory+I/O这5大部件,CPU独占2大部件,CPU有哪两大部件呢,CPU是由运算器和控制器两大部件组成的,memory是内存,I/O分别代表两类设备,I是input设备就是输入设备,比如键盘、鼠标,输出设备比如说打印机、显示器这些设备都称为输出设备,这些设备都围绕着核心的CPU再加上内存就构成了一个基本计算机的框架结构,也就是它的硬件体系结构就已经搞好了,这个计算机经过一些其它方面的东西比如说主板、晶体振荡器,这些东西对于编程来讲可以不做更深的了解,但是CPU+memory+I/O这5大部件编程息息相关,CPU里独占两个这两个是什么东西呢,CPU当然要进行计算,其实CPU才是真正的大脑,如果要拿人来类比的话CPU就是大脑,那CPU里边应该有什么呢,那我们想想人的大脑能干什么,人的大脑能够进行计算,比如算一个1+1不是心里想是脑子在想,所以脑子里边是有运算单元的,那也就是说CPU当中其实应该有运算器,这个运算器干嘛呢,它是要进行逻辑运算、算数运算、数据的处理等等这些是运算器要做的,其实我们做的所有的计算机它做的事情它都是在做运算,对它来说就是数据加工和处理,这就是CPU的主要工作之一就是进行运算,大家也知道人的大脑除了进行运算之外,人的大脑还要对全身的各个器官,对我们的行、走都要进行控制,只是有些控制是有意识的,有些控制是无意识的,比如说你的内脏的运行是感觉不到的,像编程的时候你并不是每一次都要去想象原来CPU还在控制各种设备,你可以不用去关心它,就像我们心脏实际上是大脑在控制但是不是你有意识的控制它是自己在进行指挥着,那也就说我们实际上对自己的五脏六腑它实际上进行的控制,当然我们也有显式的控制就是我们直接控制的,你比如说我要让我的手动一动这也叫控制,那么大脑要对这个东西进行控制,CPU除了要做运算之外它也要对各个设备进行控制,确切的讲它是通过总线来控制的,CPU它就是要通过控制来保证整个计算机系统它能够有序的按照你所约定的你所规定的方式正常的运转,这是CPU要做的事情,第一个它要做数据的处理、数据的计算,再一个它要做整个计算机系统的控制,所以CPU还是比较忙的;

第二个部件称为叫存储器,这个存储器指的是内存,内存是有一个特点,比如说来不急存盘停电了数据就丢失了,为什么呢,对于memory来讲它所用的设备叫掉电易失设备,它这种芯片就是就是掉电易失芯片,但是它有一个好处就是它的运转频率高,就是你给它晶体振荡器的频率可以非常高,它可以运行的速度是非常高的,我们说整个计算机的控制它所谓的心跳都是靠晶体振荡器的,那么我们说它的频率有关,当然频率越高所以设备运行的频率也高,当然不同设备它的运行频率不一样,它需要分频它需要降频,CPU的运行频率是最高的,内存的要次之,但是内存的运行频率也是比较高的,也就是说它的处理速度还是比较高的,但是我们要知道存储器这个memory内存它是掉电丢失,它这种设备它运行速度高,但是掉电你再重新启动你会发现数据没了,这就是它的问题,那能不能让它的运算速度又高数据又不丢失,其实也有类似的但是造价太高,现在确实有这种掉电不丢失数据的内存,但是估计没有多少人用,造价非常高,因为你还要保证内存的运行速度要高,所以这就是个问题了;

下面就是I/O这两种设备,I/O这两种设备它叫输入设备和输出设备,输入设备和输出设备有一个显著的特点,可以看上图的数据流,数据流指的是数据总线,那么这个数据流是怎么样的,我们发现CPU里面的运算器虽然要用数据但是它并不直接跟输入、输出设备打交道,CPU虽然它需要数据但它根本不和输入、输出设备直接打交道,那么输入、输出设备它们的数据是跟谁相关呢,是跟memory相关跟内存相关,那也就是说CPU实际上真正访问的数据是问内存要的,它如果要把数据要存起来它并不直接放在CPU当中,CPU是一个临时加工场所,它需要数据的时候会问内存要,内存你有没有数据让我加工,内存说有,把这个数据拿到CPU当中来计算,计算完的结果再写回到内存当中,CPU直接跟数据打交道的时候它是跟内存要,它要写的时候说内存给我点地方我要把数据写回去,CPU只跟内存打交道,如果CPU要读取数据呢,那这个数据得从哪来呢,这个数据必需得先从输入设备把它放到内存的某个区域,然后再通过CPU去读取,当然这里边是存在地址总线要访问,但是我们不多说,我们说CPU如果需要数据必需把数据从输入设备上搬到内存当中,然后由CPU当中的运算器按照指令去从内存的指定区域去给它搬进来,搬到哪去呢,搬到CPU当中来,CPU里里边有寄存器,放到寄存器当中,然后CPU对数据进行计算,计算完之后因为还要做下面的指令的处理,它会将它计算的结果写回到内存当中去,至于写入内存当中去之后你到底存不存盘,到底通不通过网络发出去呢,这个就是你自己要做的事情,有的时候会把计算结果放在内存中并不存盘掉电了就丢失了,所以我们有的时候为了把内存中计算的结果给它持久化下来,让它真正的能够长期的存在,比如说我们可以写入到磁盘,那么磁盘在这个时候就作为了一个叫输出设备,我们将内存中的数据再给它写入到磁盘当中这样的话内存掉电数据丢失了,但是磁盘中写入成功之后磁盘中就有这样的数据了,掉电了不要紧,下一会把磁盘作为输入设备再从磁盘把数据读到内存中就可以了,那也就是说磁盘对我们来说它是一个输入、输出设备,它有的时候是作为数据源的,有的时候是作为数据的写入的目的地的,但是你要注意CPU并不把数据直接写入磁盘,CPU更多做的事情是将数据从内存中读取来,如果数据不在内存那你提前就应该把数据从输入设备上去读过来,CPU去那取就行了,CPU计算的结果放到内存当中如有必要发网络或者写入磁盘,CPU并不直接跟I/O设备进行数据交互,真正的CPU要计算的时候它实际是在内存中读取数据的,在内存中写出数据的,那么如果数据有必要再写入到磁盘或者网络等等这些设备上去;

CPU要对5大部件包括自己要协调工作,总线叫bus,总线其实说到底就是一根线大家是分时占用的,要么我占用要么你占用,那么控制总线、数据总线、地址总线这是计算机里边我们经常看到的总线,控制器它就不用数据总线了,它用的是控制总线来控制所有的设备协调工作,运算器的数据从哪来,运算器算出的结果往哪去,请你一定要记住;

在这里插入图片描述
CPU是计算机中的大脑,计算机中的心脏是谁呢,大家都知道你把计算机拆了里边有一块电路板,这个电路板习惯称为它叫电脑主机板简称主板,主板上是有两个芯片的,主板上会有一个插槽,插槽里面放CPU,但是这个插槽到底是个什么样子,现在用的是socket封装,CPU上面有风扇你并不能直接看到它,CPU旁边一般离的近一点的会有几个内存插槽,这个内存就是扩展,一根不够多来几根,反正CPU要数据就在内存当中,CPU写数据就写到内存当中,一掉点内存中的数据也就没有了,在这个主板上一般来讲还有几个非常重要的芯片,其中核心芯片比如说南北桥架构用的比较多,上北下南,把上面芯片称作北桥芯片,下面这个称为叫南桥芯片,现在看到的大多数主机板都是南北桥设计,可能在某个地方还有一个叫晶体振荡器,晶体振荡器产生频率然后所有的设备根据这种脉冲信号来工作,一般来讲晶体振荡器这个频率越高计算机的处理效率越高,但是这地方有一个问题,CPU它的频率是非常高的,大家可能知道现在CPU是多核心的,一个核心大概在比如是3GHz,它的每一个核心都在3GHz,因为到5GHz、6GHz它可能对硅基芯片来讲它超越了它之间的电隔离,频率继续往上走的话可能碰到了工艺的天花板,包括功耗和散热等,包括它的电磁干扰都无法控制了,可以做但是造价非常高,不划算怎么办呢,这个时候我们说能不能加多核,一个CPU里边给它分成几个核心,比如说4核、8核就这么来的,当然8核里边超线程搞成了假8核,但是一般来讲也会有个2核、4核,所谓的3核是屏蔽了一个不太稳定的核心,这是AMD搞的一套,它其实还是4核的,这样我们说2核、4核、8核,像这些东西包括64核都可以搞,就是个造价的问题了,那么CPU它的运行频率很高,内存的频率称为叫前端总线,它的频率是比CPU的频率要低一些的,北桥上面连的是高频设备比如说连内存、显卡,也就是说北桥连的都是高频的设备,南桥连比如说键盘等运行频率非常低的包括磁盘、网卡这些设备,它连的往往都是这些低速设备,那也就是说实际上CPU频率是最高的,然后显示设备的频率也比较高,甚至还有独立的GPU,内存的运行频率也是比较高的,但是它是低于CPU的,还有就是南桥上连的I/O设备的频率就更低了,简单的来说,CPU的运行频率是第一位的它是最高的,然后内存是运行频率较低的,输入、输出设备是最慢的设备就是它的运行频率是最低的,要降频、要分频,它是分频的方式降下来的,所以说这些输入、输出设备它的运行频率非常低,那么我们现在就可以知道计算机中的CPU它的运行频率这么高,你如果要在键盘上敲字母的话它要等这个键盘作为输入设备其实CPU大多数时候都是在浪费电它在等你,如果说要从磁盘上去读取数据,磁盘其实是很慢的,就算你换成固态硬盘它跟内存的频率也差的很远,这都是数量级的差异,都是成百上千倍的差异,所以磁盘就更慢了,CPU其实花大多时间是要等你的,所以会发现大多数时间都是在浪费CPU,但是你要记住一点对我们来讲运算器这里面速度运行频率是最高的,内存的运行频率次之,它们就已经差了好多倍了,磁盘、网卡它与内存的运行频率差的就更多了,计算机是这样一个所谓的运行频率的差异的一个梯度下降的一个模型,说这个运行频率有什么用呢,你就记住CPU最快,内存次之,I/O设备慢的要死,这就是以后我们写程序的时候大家要做的优化,优化什么,就根据CPU、内存以及I/O设备的运行特点我们要做优化,这就是冯诺依曼体系结构它要告诉我们这些东西;

在这里插入图片描述
在CPU当中它有一个东西叫寄存器,假如CPU只有一个核心,它上面运算器它里边有一些硅晶体电路形成的电路,它上面有很多寄存器,寄存器干什么呢,我们知道CPU要给你加工数据的,它要加工数据的时候这些数据必需放在寄存器里边,数据是从内存搬过来放到寄存器里边,然后通过计算器的运算将寄存器的数据进行加、减、乘除等运算,运算完之后它会放回到某个寄存器当中,然后再从寄存器可以将数据写回到内存,当然也可以直接写回到内存,但是你可以认为先进入到寄存器,然后从寄存器搬到慢一点的内存当中,也就是说它最后要把数据通过数据总线访问地址总线将数据,其实就是电频信号写到内存当中,就是把数据写过去了,你就这么认为把1写到内存当中去了,这么认为不会对整个模型产生太大的错误,我们只要搞一种模型能够让自己记得就行了,但是CPU当中还有一个非常重要的的区域,L1叫一级缓存,L2叫二级缓存,L3叫3级缓存,往往看到CPU它里边是有缓存,它到底有几级缓存就要看具体CPU了,但是以我们个人所使用的CPU来讲的话一般会有3级缓存,什么叫缓存呢,缓存就是比如说我这个数据从内存中读取出来我本来是要去到某个寄存器当中的,在读取到寄存器当中的时候也放到缓存里边放一份,下一次要去读取这个数据的时候看一看缓存有没有,如果缓存中有直接从缓存中拿就不要去内存中拿了,为什么这么做呢,CPU的运行频率是远远高于内存的,如果能从缓存中上拿比从很慢的内存中去拿了,就直接可以从缓存中去拿到,这样可以大大提高程序的运行效率,省的老去内存中搬数据,这样可以大大提高效率,这就是CPU亲缘性或者叫CPU粘性指的就是这个,或者叫CPU绑定,其实说的就是这个事,但是为什么要说1、2、3级缓存,应该说1级缓存几乎与CPU同频,2级缓存降一个数量级,3级缓存降一个数量级,也就是说如果我们在一级缓存,为什么不用一级缓存,一级缓存造价高它要跟CPU同频,它这个材料造价高,所以它比较小,都是按k算的,对于二级缓存来讲的话可以稍微大一点它的材料可以稍微降一些,它的制造工艺它的材料可以降一些它的运行频率要低一点,这个可以做大一点,我们说第一个是运行频率就是赫兹,一级缓存的Hz是大于二级缓存的,大于三级缓存,三级缓存又是大于内存的,而内存又是远远大于I/O设备的,也就是说你能从一级缓存读取那性能是最高的,能从二级缓存读取性能也不差,三级缓存读取性能也可以,3级缓存因为它的频率不高它的工艺就比较低造价就比较低,所以3级缓存一般都是按多少M,比如说16M的,如果有多核一般3级缓存它是多核共享,1、2级缓存是每个核心自己独享的,对于我们来讲原来有这么多优化的地方,也就是说我们实际上可以总结一句话,能放内存就放内存,为什么呢,因为CPU是直接跟内存打交道的,能放内存就不从I/O设备上去读取,因为从I/O设备上读取很慢,这就是我们写程序的时候大家要注意,我们为什么要把数据搬到内存当中去,因为CPU只跟内存打交道,为什么放在内存中而不放在磁盘上,因为磁盘太慢,为什么不从网络传输因为网络传输太慢了,即使你是万兆的网络也很慢,这就是从CPU到内存到I/O设备我们要了解的东西有这么多跟编程息息相关,一级缓存是大于二级缓存大于三级缓存的运行频率的,三级缓存又大于内存运行频率的,I/O设备的运行频率是极低的,大多数情况下很少有人会做CPU的亲缘性绑定,大多数是考虑在内存中能不能让数据能多放一会,这样的话我们去跟内存打交道可以显著的提升程序的性能;

CPU当中是有很多寄存器的,CPU要加工数据是要在寄存器里边读取数据的,并且把结果写入寄存器,然后从寄存器可以搬到内存当中;CPU当中还是有缓存的,缓存就是为了让它读取数据的时候不要从内存中读了,可以直接在缓存中读,假如从缓存中读,缓存中有你要的数据你就可以从缓存中读取,利用到了缓存我们把这个东西称为叫缓存命中,所有的缓存原理都是这样的要看命中率,如果一个缓存Cache它的命中率比如说只有1%那这个缓存几乎没什么用处,如果我们的命中率达到60%这还是有用的,所以你要读的数据都不在缓存中你要这个缓存干什么就浪费电么浪费内存空间;

CPU并不直接从速度很慢的I/O设备上直接读取数据,它为了解放CPU的话比如像硬盘操作可以加一个芯片叫DMA芯片等等,CPU可以从较慢的内存当中去读取数据,但是内存掉电数据丢失就没了不安全,好不容易算了一晚上算出来的数据还来不急存磁盘掉电了没了,多可惜啊,所以我们说CPU可以从较慢的内存中去读取数据到CPU的寄存器当中通过指令去运算的;CPU计算的结果也会写回到内存当中去,因为它还要让出寄存器还要给其它的程序运行,而不是写入I/O设备上。

1.2.1.2 计算机语言

语言是人与人沟通的表达方式。
计算机语言是人与计算机之间沟通交互的方式。
软件最早是有操作系统的,在操作系统之前还有一些使用计算机的方式慢慢演化出了操作系统,操作系统之上就要写程序,写程序的话就得用计算机语言,因为我们要跟计算机打交道,人与人之间要沟通要打交道我们可以通过语言,你不能说递一个眼色,递个眼色我也不知道是什么意思,所以发现我们可以发声,我们就可以通过语言然后进行交流进行交互,这就是我们的一种工具,人要与计算机之间要交流,你让计算机给你干活,干完活后它要告诉你结果,这样的话我们就跟计算机要沟通,那么怎么沟通呢,我们就发明了计算机的语言。

机器语言

  • 一定位数的二进制的0和1组成的序列,也称为机器指令
  • 机器指令的集合就是机器语言
  • 与自然语言差异太大,难学、难懂、难写、难记、难查错
    在这里插入图片描述计算机语言最早只有机器语言,什么是机器语言呢,比如说我建了一张表格,指令1代表做加法,当然这里边没这么简单,用指令1代表做加法什么意思呢,因为假如1它就要去A和B这两个寄存器读取数据它把这两个数据相加,寄存器的数据用加法电路完成加法,得到的结果再写到A里边去,A+B的结果再写到A寄存器里边去,这就是它要做的事情,用1就代表做加法,2代表做减法,A-B再把结果写到A里边去,就是通过1、2、3、4这种表来告诉你这能干什么,这能干什么,它用这张表来建成了所有指令的对应,以后我们怎么办呢,以后比如你要算A+B的话加法那你就直接写指令1就够了,这就是实际上最后我们要写的东西,但是你会发现它有一个问题,在计算机指令时代,这个时候各家比如像通用电气、IBM这些公司,它们每一家都有不同的CPU,每一家都有自己的CPU的设计,它们CPU设计是不通用的,包括intel有自己的廉价CPU,就我们现在所看到的CPU,这种廉价CPU实际上都是不通用的,它们都有不同的指令集,什么叫指令集呢,就是它们家1、2、3、4代表加、减、乘、除,另一家1代表乘法,2代表除法了,3才代表加法,就是每一家建的指令表是不一样的,我们把这个指令表的指令集合称为叫指令集,每一家的指令表、指令集都是不一样的,而且互不通用这是最大的问题,所以我们在是有的时候很不方便,这个东西根本没法记忆,也就是说你如果是一个计算机科学家如果你要来编程的话,那你就必需查表,你得很熟悉这个公司生产的这一种计算机型号,它不同的计算机型号都不一样,它这种型号的表什么样的,然后你要算加法你就抄指令,算减法抄指令,各种指令组合在一起这就是你写的程序,试想一下用这种0和1或者说你用数字指令写出的程序根本不要提什么可读性,根本没法读,这个编程不是一般人能完成的,在一个如果出错了根本无从查起,这需要非常细心的计算,曾经有一部电影是讲美国的纳桑一位黑人女科学家,前一段时间刚去世,当时它们没有地位,而且她还是黑人女性,当时的计算机我们的航天员上天的时候,它们不太相信计算机的演算结果,计算机的能力已经是很不错了,它需要这个女科学家重新计算,人工演算才相信,这个计算量也是非常大的,你想想计算机这些指令是不是非人类可以记忆的,你写完这个程序对还是不对啊,心里没底就这种感觉,所以说这个东西每一种CPU差异非常大,而且难学、难懂、难写、难记,还难查错,尤其是难差错,你难差错的话你说你这个运算结果到底是算原子弹模型,还是算什么,尤其是像现在这种核聚变这些东西,为什么现在可以不做这种实验了呢,其实都是用计算机模拟了,就是我们就可以用计算机就可以算出来了,不需要我们真的去放一个原子弹,所以计算机的准确性对我们来说非常重要,那你说你如果用这种数字来编程那你编出来的程序谁敢保证它没错,谁敢用,所以这种东西就会出大错了,而且不便于查错,非常难用,这就是我们说的其实你这些数字我们把它转成二进制就是0和1组成的指令,这个0和1的二进制指令非常难记,但是计算机喜欢,CPU喜欢,因为CPU就认二进制,就认0和1,它其它都不认,所以人不喜欢,但计算机喜欢,这就是机器指令,但是我们也知道机器指令不可能大规模的发展起来,因为大多数人搞不定这事,太难了,每一种CPU都不一样,每个厂家生产的不同型号它的CPU的指令也不一样,完全不通用的,那个时候也没有什么通用可说,因为每一家都在发展自己的市场,而且每一家都在占领自己的市场,都在发展自己的客户,你说是标准我才不信呢,我自己做我自己的,所以大家互不相让,各做各的,这是指令时代;

汇编语言

  • 用一些助记符号替代机器指令,称为汇编语言。ADD A,B 指的是将寄存器A的数与寄存器B的数相加得到的数放到寄存器A中
  • 汇编语言写好的程序需要汇编程序转换成机器指令
  • 汇编语言只是稍微好记了些,可以认为就是机器指令对应的助记符。只是符号本身接近自然语言
    在这里插入图片描述
    后来大家发现你张表的1太难记了,你这个1不是说是加法吗,能不能咱们把这个加法能不能搞成一种人能看懂,叫ADD A,B,就是我不用1了,咱们再建一张表,把ADD A,B这种指令称作叫做助记符,这个就称作叫汇编语言,我们用这些人可理解的就是这种汇编语言的这种汇编指令来表达A,B两个寄存器的的相加,以及最后算出结果放到A寄存器这件事我们用这个助记符来做,就不再去记忆这个指令了,至于它对于的不同CPU到底这个指令是1也好,还是说100也好,还是2也好这个我不关心了,这个事谁来做呢,你有了一大堆助记符这个转换成指令的这个事谁来做呢,这个时候就有一个叫汇编程序或者叫汇编器,由汇编器将你写好的汇编指令转化成对应机器对应的CPU所能够支持的指令,你比如说在这台机器上这种型号机器上它的这种加法,两个寄存器的加法它对应的指令是3,那就由汇编器来解决与这个CPU之间对应的关系,你只需要去写ADD A,B就可以了,那我们就可以用这种助记符写完这种汇编程序而且可以写的更多,而且人可以阅读,通过这种助记符就可以阅读这个代码,还是可以便于查出自己有没有逻辑上的问题,有没有逻辑上的错误,所以汇编语言后来就提出来了,然后就产生了很多的汇编器,大家慢慢会发现为了让大家解决一些问题,这个汇编语言慢慢也规范化了,但是注意不同CPU还是互不兼容,不同CPU它的ADD指令到底翻译成什么二进制不知道,你要通过汇编程序去查表,但是这个到底是什么大家也不用关心,只要对相应的平台,相应的CPU下载对应的汇编器就可以了,就可以用了,这个就进入了汇编时代,汇编时代比机器指令时代有了很大的改进,至少人可以读的懂了,也可以便于去发现一些问题,那么汇编指令本质上来讲它就是机器指令,它不过就是做了一个表映射,所以汇编指令本质上就是机器指令,因为CPU到今天为止包括你真正是有的手机、包括你正在使用的平板、包括你真正使用的PC,到今天为止这些CPU只认二进制,就是0和1组成的序列,它只认二进制不认其它,所以我们实际上现在所做的所有的事情最终都得转成二进制CPU才能处理,所以你就记住CPU只认二进制,我们所有程序都得转成二进制,这个二进制我们习惯称为叫机器指令;

低级语言

  • 机器语言、汇编语言都是面向机器的语言,都是低级语言
  • 不同机器是不能通用的,不同的机器需要不同的机器指令或者汇编程序
    到目前为止所有的程序都是如此,汇编本质上是机器指令,它与人类的自然语言差的非常多,所以我们把汇编语言和机器语言统称为面向机器的语言,它们都是低级叫low level,它们都是低级语言,它们不能称为叫高级编程语言,而且是不同机器不通用,不同机器需要不同的指令集、不同的汇编器,关键是它们之间太相似了,说到底都是机器指令;

高级语言

  • 接近自然语言和数学语言的计算机语言
  • 高级语言首先要书写源程序,通过编译程序把源程序转换成机器指令的程序
  • 1954年正式发布的Fortran语言是最早的高级语言,本意是公式翻译
  • 人们只需要关心怎么书写源程序,针对不同机器的编译的事交给编译器关心处理

在这里插入图片描述

  • 语言越高级,越接近人类的自然语言和数学语言
  • 语言越低级,越能让机器理解
  • 高级语言和低级语言之间需要一个转换的工具:编译器、解释器
    这个机器喜欢人不喜欢,这个时候人就考虑到底该怎么编程,这个时候就出现了很多东西,出现了很多慢慢想高级语言转化的东西,可能大家都知道的unix系统,我们说unix系统它最早实际上是来自于B语言写的一个小玩具,B语言谁写的呢,Ken Thompson就是Unix之父他写的,他写的B语言不好,怎么办呢,他的另一位搭档Dennis Ritchie将它进化成了C语言,然后Ken Thompson和Dennis Ritchie两个人合力用C语言重写了Unix,并且由此Unix就传播开来了,到后来有了兼容的Linux系统,甚至像Unix这种系统的话深远的影响了包括DOS、windows这样的操作系统,像现在大家用的Mac就是纯正的Unix系统,所以我们说不管怎么样这种操作系统诞生都跟我们的编程语言都是息息相关的,这种高级语言像C语言这种高级语言有什么好处呢,高级语言它的好处就在于接近人类的自然语言,比如说我们后面要学python发现跟我们再写大白话没什么区别,我们就是在写白话,说以说它接近于人类的自然语言,虽然它是用英文写的,但是实际上是接近于我们人类的认知的,在一个它有的语言你去写的话它优美的像一个数学公式一样漂亮,就是它用人类容易接受的数学语言或者自然语言来进行计算机的编程,有的同学说我们能不能用中文编程,当然可以,甚至有一些编程尝试但是目前来看都不是很成功,所以建议大家还是使用英文编程,高级语言大家首先得写源代码,就是我们要写的python程序,或者写C语言的程序,那么我们写的这些源代码之后我们要通过编译程序或者说叫解释器程序,我们以C语言为例,C语言有一个叫编译器叫Compiler,Compiler称为叫编译器,我们通过这个东西把它转化成你可以认为它转换成机器指令,我们写C语言就写纯文本,你写的都是纯文本把你要写的这种高级语言的东西写完,写完之后我们通过一个编译器然后针对当前操作系统和CPU编译成机器指令,你可以这么理解,你可以理解为它就是机器指令了,那么我们实际上真正运行的程序就是机器指令,可以在当前操作系统上直接运行的机器指令,那么这种语言最早是1954年发明的叫Fortran,Fortran什么意思呢,它就是我们说的公式翻译、公式转化语言,当然Fortran这两年在计算机考试当中已经不见了,它已经取消掉了,反而增加了一个python,实际上对我们来讲有了这个语言之后陆陆续续就出现了很多计算机高级语言,那么我们只要关心源代码怎么写,然后剩下事交给编译器编译就行了,我们其它事就不用关心,编译器会把它编译成我们当前操作系统能够运行起来,能支持运行的这样的一个二进制代码,这就是我们说的像C语言、Fortran语言或python它们要做的事情,但是python这个它不叫编译器,它叫解释器,高级语言只有人懂,越高级越只有人懂机器不懂,机器不喜欢,就是CPU不喜欢,但人类喜欢,那么低级语言呢,只有机器懂,纯粹0和1只有机器懂,机器喜欢人不喜欢,人看不懂,那么中间就得有个桥梁,这个桥梁呢或者是解释器或者是编译器,它的作用其实最终都是为了让你以二进制运行,因为机器指令都是二进制,我们不管高级语言怎么写,它最后都得给我们转化成可以运行的二进制代码才可以,但这里边事情非常多非常复杂,语言越高级人类越喜欢,语言越低级机器越喜欢,高级语言和低级语言之间要有编译器或者解释器;

编译语言

  • 把源代码转换成目标机器的CPU指令
  • C、C++等语言的源代码需要本地编译
    编译语言里有谁呢,编译语言里有C和C++这些语言,这些语言它得把源代码需要进行本地编译,要针对当前操作系统和当前的CPU要进行本地编译,编译以后会获得一个二进制代码,会获得一个二进制的一个可执行文件,这个二进制可执行文件就可以在当前操作系统中直接运行,你可以认为它转换成了编译后得到的二进制就是当前操作系统直接可以运行或者说当前CPU直接可以运行的机器指令,所以我们说把源代码转换成目标机器的CPU指令,它的主要工作就是这个;

解释语言

  • 解释后转换成字节码,运行在虚拟机上,解释器执行中间代码
  • Java、Python、C#的源代码需要被解释器编译成中间代码(Bytecode),在虚拟机上运行
    那么还有一种叫解释性执行,解释性语言它到底什么东西呢,就像我们说的java和python一样还有C#这种语言,它们都叫运行在虚拟机上运行的语言,那这个虚拟机运行的语言它是怎么做的,它并不会直接给你编译成当前操作系统直接可以运行的机器指令它不会这样做,它会把它们先用它自己的编译器把它们编译成一个中间代码,这个中间代码也叫字节码,也就是说java、python程序和C#程序它们会将你写的源代码不像C语言一样编译,它会先把它编译成为一个中间代码,那它的这个东西叫解释器来编译成中间代码,这个中间代码并不能直接我们拿来运行,它得怎么做呢,你得让这个字节码得在解释器,解释器它就变成了一个虚拟机,就把这个中间代码在这个解释器的虚拟机上去运行,为什么呢,因为这个中间代码就相当于是这个虚拟机的机器指令,那也就是说我们先把源代码通过解释器编译成一个中间代码这也是二进制的,但是这个二进制跟C语言编译不一样,C语言编译的你可以直接运行,这个不可以,这个是一个叫中间代码叫字节码的东西,这个字节码我们到时候可以加载运行在解释器的这个虚拟机上,可以把字节码加载过来,放在这个虚拟机上去跑,对这个虚拟机来跑的话,这个中间代码其实就是它的机器指令,是适合这个虚拟机的机器指令,那么这个虚拟机再把这个机器指令输出为解释或者翻译成当前机器的机器指令,那么当前CPU就认识了,它是这么一个过程,那应该说这个虚拟机实际上多做了一层,多做了一层其实就就有个性能上的损失,一般来讲应该来说本地编译的这种程序它的性能最高,当然这是从编译角度来看的,它并不是说这个人写的代码写的好,它不能说这个人写的代码一点效率都没有,你就是写C程序又能怎么样,所以我们说本地编译就编译这个角度来讲它的性能是最高的,那么Java、Python、C#它们都要运行在虚拟机上相对来说性能要略低一些,这是我们说的编译型语言和解释性语言就是在虚拟机上运行的语言它们的差异在什么地方,其实大家在后面要学的JavaScript它也叫做ES,这种东西它实际上也存在类似的问题,它也是在虚拟机上运行,所以它的性能也是要稍微差一些,就需要一个高级玩意,虚拟机能不能高级一点,这个虚拟机能不能性能高一点,它要想想办法了,这是我们说的语言分类,从这个语言分类里面我们已经知道了,其实我们发现现在百花齐放的是什么东西呢,全部都是这种解释器的这种语言,就是虚拟机上跑的语言,为什么呢,好用,你写的一个程序之后你你不要去关心哪个操作系统,哪个CPU了,由我们的解释器它来解决跨平台的问题,大家也知道java当时号称Write once, run anywhere,就是一次编写到处运行,python其实也是一样的,由解释器来给你解决平台差异问题,你只写一份源代码就够了,但是你用C语言就不是了,你用C语言的时候你会发现在windows下调windows的库,在linux下调linux的库,它是有差异的,编程有的时候差异还不小,所以用起来就稍微要麻烦一些,但是它确实性能高,包括像C++我们可以用面向对象的方式它的性能就高。

1.2.1.3 高级语言的发展

  • 非结构化语言

    • 编号或标签、GOTO,子程序可以有多个入口和出口
    • 有分支、循环
  • 结构化语言

    • 任何基本结构只允许是唯一入口和唯一出口
    • 顺序、分支、循环,废弃GOTO
  • 面向对象语言

    • 更加接近人类认知世界的方式,万事万物抽象成对象,对象间关系抽象成类和继承
    • 封装、继承、多态
  • 函数式语言

    • 古老的编程范式,应用在数学计算、并行处理的场景。引入到了很多现代高级语言中
    • 函数是“一等公民”,高阶函数

高级语言它的发展有几个阶段,最早是非结构化语言,就是你随便写,你想怎么写怎么写,这里边还用了一些标签、GOTO等等东西,GOTO能不能用其实可以用,但是这东西就相当于是个双刃剑,用的好了性能极高,用的差了性能极差,甚至你的程序就变成叫缠死的线团,程序变成这样就解不开了,所以说实际上非结构化时代的话像这种GOTO。子程序跳来跳去,加标签跳来跳去这种方式的话那就是早期的汇编程序就是这么写的,它也有分支、循环等等这些部件也在,但是这种程序没法看,不适合于软件工程,软件要写成千上万行代码,这时候用这种编程方式肯定是不行的;

那怎么办呢,结构化语言出来了,结构化语言出来以后咱们就要约法三章,顺序执行、分支执行、循环执行把这些东西都约定好,而且任意结构只许有一个入口一个出口,你不能有多入口多出口,不然就乱套了,就不知道你从哪进来从哪出了,就跟现在疫情期间有些你小区开上10个门,这不乱套了吗,开一个门,在这个门进来指定门出去都可以,就是我们要指定好不能让它乱就写,这个时候慢慢去废弃GOTO,GOTO这个东西废弃了有好处,虽然GOTO有些时候会性能极高,应该有一个编程大赛里面有一个人写的代码及其精简,它使用GOTO来实现的,但是要注意的是这个东西用的好的人它用的出神入化,用不好的人这就是灾难的后果,它会带来无穷无尽的烦恼,就是bug层出,到处都是bug,结构化语言就是开始要废弃GOTO,就是有些语言它就不允许你用GOTO了,它语法上支持但是不允许你用,在python中当然也不允许你用,你的这一点点性能提升架不住你写一个没有效率的,就是你不懂算法你写一个效率低下代码,也架不住你干这事,所以对于我们任何一个人来说我们用结构化编程等等这不是你极致追求性能的地方,我们在这种场景下应该遵从工业化编程规范,你写的代码应该符合一种规范,这种规范可以保证它少出bug,可以保证它可以稳定高效的运行,你应该遵从这种规范,所以结构化编程就做了这样一个事情,从C语言开始就做了这种事情;

后来也慢慢出现了另一种编程模式叫这种面向对象的语言,面向对象是一种方法论,它适合大型系统,在大系统里面我们很难去把它按照步骤像结构化编程以后,你顺序编程第一步做什么,第二步做什么,第三步做什么,这个我们很难做到,在这种情况下我们可以把一个大系统拆解成无数个对象,然后对象和对象之间产生作用,所以这是我们人类认识世界的方式,它是一种方法论,我们可以将万事万物抽象成对象,那么真正实现的时候就抽象成类,然后用类的继承来表示类与类之间的关系就是万物之间的关系,用这种方式就是面向对象,它里面有3要素,比如说封装怎么封装,如何做类的封装,我A封装和B封装这两种差异到底在哪,这两种封装到底哪种好,如何继承,什么东西是多态,这就是它的3要素,只要是个面向对象的语言它都支持这3要素,python也不例外;

还有一种就是函数式编程,函数式编程其实是很早就出现了,这些都称作范式,面向对象编程范式,面向过程编程范式,面向函数的编程范式,就是函数式编程,它是只要应用在数学计算,写一个函数跟数学语言很接近,然后并行计算也是大量的计算,这些场景下可以用这种面向于函数设计,我们写出来这种代码非常的精炼,符合这个领域里面的数学表达,非常的好,在这里面函数就非常重要了,甚至可以没有面向对象,它只要有函数式编程就可以了,函数是最重要的,函数是一等公民,当然我们遇到的python称为叫多范式,它支持结构化编程,也支持面向过程编程,它也支持面向对象编程,它也支持面向函数编程,它都支持,现在的语言基本上都支持,这是语言的新特性,其实就为了一个目的,让我们在开发的时候能够利用工程化的开发方式,快速的去搭建企业的各种系统,这是我们编程的目的。

程序Program

  • 算法 + 数据结构 = 程序
  • 数据是一切程序的核心
  • 数据结构是数据在计算机中的类型和组织方式
  • 算法是处理数据的方式,算法有优劣之分

只有选对了合理的数据结构,并采用合适的操作该数据结构的算法,才能写出高性能的程序。

数据是放在内存当中的,它是数据,那我们应该怎么办呢,我们要操作数据,我们要对数据进行加工,实际上我们把数据放在内存当中,这里面是内存,能行我们是按线性编制的,我们把内存化成区域,一段一段的区域,那你可以认为内存就是一小块一小块的,在这里边放数据,那么在内存中到底应该怎么放数据,你把内存当仓库看,你在仓库里面堆放货物的方式不同,你找一件货物的时候或者你在放一件货物的时候你的方式就应该不同,你在仓库里乱堆东西,那你找东西就很麻烦,你得遍历,我得扒开所有的货物去找,这就叫遍历,为什么,你是乱放的,这也是一种数据的排放方式,这就叫数据结构,就叫乱放,数据结构就叫乱放,你如果是乱放就决定了你的算法,什么意思,数据结构决定了其实我们怎么样去找东西,我们怎么样存东西就决定了,找东西怎么找呢,翻所谓的翻就是遍历,一个一个找,那么我能不能这样做,在仓库当中分类放,放的很整齐,排的整整齐齐,在仓库里边打货架,划格子,在格子里边分类,这格子分类在里边放东西,这种方式不错,就跟你家为什么要搞柜子,你们家不可能柜子里边不分层板,我们在柜子里边放层板,为什么呢,我们要分类放,便于我们查找,这就是数据结构,所以我们说数据结构它决定着在内存中的数据它是如何排放的,它是如何组织的,确切将应该是如何组织,这个如何排放就是分类放,你怎么分门别类这就是数据的类型,它的类型如果决定了它的组织结构也就决定了,你是码放在一起呢,还是把它们靠紧了,还是稍微做了一些其它的结构把它们放起来的,这就是我们说的它组织方式,你选定了类型也就选定了组织方式,这些数据在内存中的组织方式,它的排放方式就已经决定了,既然它的排放方式决定了,那你该如何去找呢,你比如说如果你按类型分的,我找的时候就分门别类了,我知道某一种类型,比如说货架里边的第一行是放的是A类型的,那我就在第一行里边找不就完了,如果放的是B类型在第二行里边找就行了,所以数据的码放方式就是数据的类型和组织方式决定了我们的算法,所以算法+数据结构就决定了程序,为什么,程序是用来处理数据的,程序里边得收集数据,收集完数据之后要处理它,你收集的数据放在内存中你是怎么放的这就叫数据结构,那么我们是怎么处理数据的这就叫算法,所以算法+数据结构其实就是程序;

写程序的难点

  • 理不清数据
  • 搞不清处理方法
  • 无法把数据设计转换成数据结构,无法把处理方法转换成算法
  • 无法用设计范式来进行程序设计

刚开始学习的时候会有哪些问题呢,比如说你会经常会问,我也预习了,我在写代码的时候经常会遇到搞不清楚数据,给你出个题,你都不知道这个题目里面应该有什么样的数据要收集,你不知道,第二个你知道该收集什么数据,你不知道该怎么处理它,就是有的数据仓库你不知道该怎么打理,就像仓库里面堆得东西你不知道该怎么打理,第一个不知道拿什么东西堆到仓库里边去,就是不知道数据是什么,第二个是不知道数据该怎么处理,第三个是我用生活中的例子我也想清楚了我得收集这个数据,我也知道用生活中怎么描述应该把这个数据该怎么处理,我也知道,但是我就是提起笔来或者说手放到键盘上我不知道该敲什么,我不知道这种想象的东西应该用什么数据结构,这是为什么,这是因为你对数据结构不了解,我们要通过数据结构的学习,然后通过练习你就了解了,所以有一个过程,刚开始用的不熟,后面就用熟了,后面还有什么问题,我知道用什么数据结构,但是我就是方法用的不好,这个其实也是一样,等我们把数据结构这块原理这块东西给大家讲清楚以后,大家这一块自然而然都不是个什么大问题,所以这块你别着急,这都有个过程,有些人数据结构也知道,脑子也想了该怎么做,就是不知道该敲第一句代码应该怎么写,这都有个过程,这个过程有多久,有些可能需要几天的时间,有些人可能需要半个月的时间,有些人可能真正的自己能够独立去写一个程序可能需要花一个月左右时间,但是基本上就在这段时间之内大家通过反复的练习,记也好,背也好,先生吞下来再慢慢消化也好,总之用各种各样的方法大家在一个月左右都陆陆续续,都能开始写一长段代码了,所以大家要通过练习,你也得去听理论,然后要勤加练习,只有反复使用你才能够掌握的很好,那么你在学习过程中一定会遇到这些问题,有些人就卡在这里边的某一个阶段,或者卡在某几个阶段上了,这个只能通过熟能生巧,没有什么好的办法,想不通先撂下来,看下一个问题,等这段我再回过头来再看这段逻辑我能不能看懂了,我们回过头再看,千万不要钻牛角尖,你一旦钻牛角尖你的学习时间就没法安排了,你为一个问题浪费了一天的时间,结果你还没搞懂,实际上你睡一觉第二天早上再去思考这个问题说不定就搞懂了,我经常有这种感觉,我前一天没想明白的问题,我有时间早上起来的时候我说反正在公交车上,在地铁上也是闲着,我昨天有一个问题我没想明白,我来想一想,我就脑子里边做各种模型,做各种的推断或许就想明白了,我就可以用它了,我就到公司我一试果然可以这样做,所以大家也是这样来,你不要钻牛角尖,你慢慢来,会有一个适应的过程。

猜你喜欢

转载自blog.csdn.net/qq_25599925/article/details/127152182
今日推荐