TOC

编程基础

    计算机语言也是一种语言,只不过人类的语言是人类之间互相交互的,计算机语言是人类与计算机之间交互的语言,要让计算机,按照我们的意愿去工作,就需要一种语言,让计算机能够懂得我们的意愿;
    计算机发展初期,使用的语言是机器语言,机器语言实际上是非常难懂的,因为当时计算机属于野蛮发展的过程,各自都在研发,没有什么标准,这是个新生事物,后来所有人都按照冯诺依曼体系的二进制,使用二进制作为计算机的逻辑处理,那么这个时候,以二进制为基础的技术就发展起来了;
    那么如何能够让计算机通过我们的意愿来工作呢,那么我们需要对其发生指令,假设我们要让计算机做加法 (add A,B),但是如何让计算机读懂这个指令呢;

汇编语言

    那么后来就出现了编码,比如我们要让计算机做加法,那么我们就规定了001是加法,002是减法,我们用一张表来记录了,这些所有的0和1组合的公式,所以后来人们写程序就采用这些0和1的编码来写,每次写加法程序、减法程序等,我们都需要先查表,但是这个查表只适用于一种CPU、换一种CPU就可能不是这一套逻辑了,需要重新建立一张表,这个表代表了这个CPU支持的指令;
    太麻烦了,没法记,也不通用,那个时候,就没有说写一个程序,各个计算机都能运行的程序,没法通用,因为每家制造CPU的程序员都各自发展,他们各自搞一张表来记录这个CPU所支持的指令,非常难记,它需要对应我们0和1的组合与我们的加法减法等运算公式的对应表;
    后来就慢慢发展出一个助记符,程序员不需要记0和1了,我们只需要记住加减乘除所对应的自然语言就可以了,比如说,以后加法就叫做add,减法就叫sub等,我们通过这些助记符来编程,编程完成之后,由一个专门的汇编器,汇编器负责将我们的助记符转成这个CPU型号所对应的机器指令码;
    这个转的过程,我们就称之为,编译的过程,或者汇编的编译过程,助记符其实就接近了人类的自然语言,但是它比我们现在所使用的高级语言还是差了很多,它不过就是把机器指令改成了助记符而已,改成了助记符实际上就是改成了字符串,得把这些字符串改成机器指令0和1的组合,其实内部还是查表,根据指定的型号的CPU查询对应的机器指令表,然后映射成对应的0和1的组合,就可以了;
    这个汇编器,就大大的减轻了,写机器指令的负担,因为如果直接编写机器指令的话,因为机器指令都是0和1的组成,只要敲错了一位指令就变了,这个时候,我们要找错误就太难了,满眼看过去全是0和1,但是我们如果使用助记符的方式,就一眼能够看到了,因为它是自然语言的助记符;
    有了助记符之后,我们就可以类似(ADD A,B)、(SUB C,D)这样的方式来进行编程了,我们也一眼能够看懂,虽然这个指令与我们所想的加法减法还比较远,但是已经比机器语言的0和1已经好很多了,目前汇编在很多领域中使用,尤其是底层编程,我们不得不使用汇编语言;
    助记符是好了一点,但是还是没解决问题,依旧还是很麻烦,但这个与当年的编程也有关系,因为当年写汇编的时候,计算机的算力是很差的,内存都是以M计算的,那个时候还是软盘的时代;
    那么随着计算机的算力增加,我们就需要更高效的编程,那么机器语言和汇编语言就都不能成为高效编程的语言了,那么这个时候就分了低级语言和高级语言;

低级语言

    低级语言是面向机器的,机器就能直接识别,但是人看得就别扭了,这东西和人类的自然语言相差太大了,这个时候得根据不同的CPU来单独学习,包括对寄存器的操作,非常的难学;

高级语言

    由于低级语言的低效,所以科学家们就在想解决办法,寻找一种与人类相近的一种计算机语言,既然都有了汇编器了,那么也可以有更高级的东西,让人类语言用来编程,这个时候就出现了高级语言;
    高级语言要么很像人类语言,要么很像数学语言,其实计算机的诞生最初就是为了解决数据处理的问题,所以它也能够更像数学语言,也就是说这种编程语言编程写完之后,就像数学公式一样;
    后来经过不断努力,1954年Fortran语言正式诞生,Fortran的本意就是公式翻译,翻译就是写数学,我们用人类自然语言写一段数学公式,然后,这个时候就就有编译器出来了,由编译器将你写的人类自然语言转换程机器指令,也就是机器语言,因为CPU到今天为止还是只认识0和1,我们必须使用这种编译器将我们这种语言,转换成机器能够识别的机器指令;
    那么以后程序员只需要使用自然语言写一段程序即可,然后直接交给编译器,由它来转换成机器语言就可以了,大大的提高了生产力,所以高级语言也是比较容易学习的一门语言;

低级语言到高级语言

    下图说明了,高级语言就是人类的可以理解的自然语言,然后中间通过一个编译器或者解释器,解释成机器语言,供机器使用,或者,使用低级语言,是使用低级语言是机器可以识别的,最低级的就是机器指令,但是机器指令千差万别,有的机器支持指令A,有的机器支持指令B,所以我们在买CPU的时候,可能有时候看到了,支持什么指令集;
    是X86系统的还是什么系统的,这就是指令集的差异,还好,因为现代计算机发展到今天,大多数企业都采用了廉价的计算机,不约而同的选择了,英特尔坚持下来的X86系统,都称之为X86指令的指令集,所以我们就没必要去考虑指令集的问题了,因为他们指令集都是兼容下来的;

机器语言:机器能够直接识别的0和1的语言;
低级语言:通过某种特定的CPU支持的指令集编译成机器语言的代码,不同平台的CPU无法共用;
高级语言:需要通过编译器来转换到机器指令的语言,大部分都兼容平台;
    低级语言是要通过编译器将源代码转化成本地能够直接运行的机器代码,就是0和1的机器指令,针对某种特性型号的CPU指令集来做的编译器,如果能够针对这个指令集编程的话就能够直接使用到机器支持的指令集,这样可以大大的提高效率;
    这就是为什么在人工智能时代大家都去研究芯片的原因,专为它生产的芯片,这样可以使用专用指令集,大大的提高效率,因为AI是大量计算的,这个时候我们要专门设计芯片,指令集非常重要,指令集就能把硬件发挥到极致;
    像目前所使用的JAVA、Python他们都是使用虚拟机运行的,他们并不会直接将源代码转义成机器指令,它会给我们转义成中间代码,中间代码就是与CPU无关的,这个代码和虚拟机配合,由虚拟机编译成本机支持的CPU指令集的机器指令,所以中间隔离一层,这一层也就是我们锁说的JAVA虚拟机、Python解释器;
    所以我们才能实现跨平台,因为平台的差异,就被虚拟机自己解决了,我们只需要写Python代码就行了,因为我们能够把Python安装在当前这个CPU之上,说明了Python就可以支撑当前CPU的指令集了,这就是虚拟机的好处,但是恰恰因为有了虚拟机,中间隔了一层,它确实比C++、C直接编译,性能要低得多得多;

解释性语言

    解释性语言,实际上就是就是先将其编译成中间代码,由解释器,来解释执行,解释执行也是执行,执行的时候也是转行成机器代码;

编译性语言

    编译性语言,就是直接将程序编译成当前操作系统CPU能够支持的二进制的可执行文件;

高级语言的发展

    计算机高级语言的发展,主要分为几个部分,非结构化语言、结构化语言、面向对象语言以及函数式语言;

非结构化语言

    非结构化语言,现在应该非常少了,这种语言和汇编有点像,有的非结构化语言是有循环和分支的,但是它内部的子程序或者函数这样的程序和现在的高级语言不太一样,他们可以随意进出,函数可以有多个出口或者入口,总之这些程序写完了就是一团乱麻,随着软件工业的发展如果还是这种编程模式的话,那基本上没法开发了,多人协作就更别提了,同时还支持GOTO语句;

结构化语言

    就是因为非结构化语言带来的弊端,也导致了结构化语言的诞生,结构化语言对一些基本结构进行了约束,比如程序入口必须要规范下来,出口也必须规范下来,就例如像函数一样,同时将顺序、分支、子程序这种结构也固定下来了,并且GOTO语言不准使用了,将语言中的一些不安全技术全部去除,比如JAVA还舍弃了C++中的指针,不允许随便直接操作内存,因为大多数人无法掌握底层原理,也不能要求每个人对内存都了如指掌,所以将底层细节用语言层面包装起来,让我们不能直接接触到底层,这是结构化语言;

面向对象语言

    结构化语言只能像类似函数一样写,像C语言一样,第一件事干什么,第二件事干什么,遵从步骤去解决问题,这个是没问题的,但是随着计算机工业的发展,这样去解决一个大问题的时候,非常的麻烦,因为大的问题是一个大系统,大系统内有很多子系统,这些子系统相互依赖,相互干扰,如果第一步干什么第二步干什么这样的顺序结构去解决问题,慢慢会发现无法描述,这个时候就会发展成了现在的面向对象;
    面向对象将世间万物,都理解成不同的类,类里面有对象,比如说人类,人类里面有具体的个体,那么人就是人类的一个实体,这种方法论就可以解决结构化语言的问题,并且能够将一个复杂的系统,通过语言去描绘出来,基本上大部分的高级语言都支持面向对象;

函数式语言

    函数式语言,在现在也用得不少,尤其是在大量的数学计算中,函数式语言很早就出现了,现在是数据为中心的处理时代了,这个时候对我们来讲,能够有一个像函数一样的处理方式就非常好,函数就像数学公式一样,在这种语言当中,它的函数就和有的语言不一样了,在其他语言中,参数是不允许有函数的,在这种语言中就允许函数作为参数或者返回值,函数和个体是一样的,所以这种语言在Python中也可以简单,比如高阶函数;

程序

    计算机原本就是用来写程序的,程序实际上就是能让计算机根据我们编写好的流程来进行数字运算的一个工具,这就是程序,它能够与计算机交互,说到底,就是指令,早起的计算机是非常庞大的,算力不比现代计算机强,但是在当时已经是很了不起的东西了;
    随着大规模的集成电路的发展,到后来的超大规模的集成电路的发展,到今天,计算机的制造工艺不断提高,就容纳的晶体管就越来越多了,它的算力也就越来越强,直到现在,计算机已经做很多的事情了,甚至模拟大千世界;
    程序说到底就是算法加数据结构,算法就是解决问题的办法,算法解决问题需要物料,这个物料在计算机领域就是数据,所以数据+解决问题的办法,就是程序;
    数据毕竟是要放在计算机体系当中的,这个数据最后还得放在内存当中,那么在内存中存放,内存是线性编址的,如何存放最合适,最高效的去使用它,这个就是数据结构的问题了,也就是数据在内存中如何摆放,它的存储方式不懂,我们去读取的方式也不同,效率也是有差异的;
    数据结构已经处理了,那么我们用什么算法去高效的解决问题呢,这个时候就要看算法的优劣了;

面向对象(OOP)

    面向对象是一个认识世界和分析时间的方法论,它是观察世界的一种方式,抽象世界的一种方式,它将世间的万事万物都可以抽象为各种对象。
    对于面向对象语言而讲,我们认为一栋楼是一个独立的对象,现实中的每一个人也可以认为是一个独立的对象,这些对象之间可以有相互的作用,比如人可以走路、可以喝水、可以说话,比如楼可以有大门、可以有房间、可以有物品,人是一个单独的系统,楼也是一个单独的系统,人可以在这栋楼里,也可以不在这栋楼里面,进了这栋楼他们之间就有相互作用,这样我们就可以描述整个大千世界,将所有的东西都抽象为所谓的对象,对象和对象之间也可以有相互的作用,由此就诞生了这种面相对象的思想。
    面向对象,也可以像C语言一样第一步做什么,第二步做什么,但是有点大材小用,但是如果要描述一个非常复杂的系统,整个时候就不一样了,它更加适用于解决较为复杂的一些问题,把这个问题抽象成一个个系统,而这个系统里面有一个个对象,然后用面向对象的方式来理解它,所以说,面向对象是比较适合解决那种比较大的复杂的问题。

类(Class)

    在面向对象里面又分为两个概念,一个是类,一个是对象,类是抽象的概念,对象是具体化的一个东西,类是对万事万物抽象出来的一个概念,它是一类事物的共同特征的集合,它是属性和方法的集合。
    比如人类,我们将人抽象成一个人的类,这个人类可以说话,可以走路,人有手、有头、有脚,这个手、脚、头就是属性,可以跑,这个说话、走路、跑就是这个类的方法,一种是它具有数据性的东西,一种是它具备的能力,即属性和方法。

属性

    属性是对象状态的抽象,用数据来描述;

方法

    它是对象行为的抽象,用操作名和实现该操作方法来描述;

对象(Object)/实例(Instance)

    对象是类的实体,比如上面提到的人类,我们可以通过人类生成一个实体,这个实体就是对象,也就是人,类是抽象的,对象是具体化的,类是对一类事务共同特征的抽象概念,而对象则是类具体的某一个物体。
    对象是数据和操作的封装,每个对象都是单独的实例,哪怕是克隆体也是,人类,有身高、有体重,可以走、可以跑,但是具体到每个人的时候这些所谓抽象出来的共同特种属性,在每个具体的人都是不一样的,这些属性也没必要记录在人类当中,因为不可能说人的类的名字叫张三,人类可以有名字这个属性,但人的类的名字属性不可以叫张三。
    当通过人类实例出一个具体的人对象时,它就有人类上面所说的走、跑和身高、体重这些方法和属性,因为它属于人类,换句话说,对象产自于类,人类有名字属性,但只有具体的人的对象得到这个属性时,才会真正存储这个属性值,如这个人对象的名字属性叫张三,身高是170、体重是120。对象才会真正存储数据,而类不会。

面向对象哲学

    面向对象哲学就是一切皆对象,比如数字1、2、3它是int类型的实例,它属于int类,它是int类具体化之后得到的一个数字,int代表所有的整形,只有具体化之后才能得到具体的1、2、3。
    对象是数据和操作的封装,对象是独立的,但是对象之间是可以相互作用的,换句话说,比如一个男人对象是男人类的实例,一个女人对象是女人类的实例,男人对象和女人对象之间是可以发挥相互作用的,比如男人可以和女人牵手、接吻...所以对象之间是可以发生相互作用的。
    到目前为止面向对象OOP这种面向对象编程是最接近人类认知的编程范式。

面向对象三要素

    面向对象对象三要素,是学习面向对象必须知道的三个知识点,即,封装、继承和多态,但凡是面向对象语言,必定有这三个东西,封装就是事物抽象为类,把对外接口暴露,将实现和内部数据隐藏。

封装

    封装,即组装,将数据和操作组装到一起,将数据进行隐藏,对外只暴露一些接口,通过接口访问对象,比如驾驶员使用汽车,不需要了解汽车的构造细节,只需要使用什么不见怎么驾驶就行,只需要知道踩了油门能走就行,可以不需要知道其中的激动原理。

继承

    面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展,通过继承创建的新类称为“子类”或“派生类”。
    继承就是可复用的意思,还可多级复用,在父类继承到子类来的属性和方法就不需要在子类当中重复写了,如果重复写相同的属性或者方法就会覆盖。比如人类就是封装,人类继承自动物类,孩子继承父目特征,可分为单一继承、多继承。

多态

    多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话,允许将子类类型的指针赋值给父类类型的指针,面向对象编程最灵活的地方就是多态,能够进行动态绑定。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注