Java学习笔记 :2021年12月31日 上午
Java学习笔记 :2021年12月31日 上午
关于计算机语言
人们通过计算机语言来进行程序的编写,实际上任何系统都离不开语言,我们人类的社会系统需要语言,因为文明的构成是通过人与人沟通来形成的,文明就是传达,因此人类和计算机的沟通也是需要一些信号的,这些信号就叫做语言。
计算机自身的语言实际上就是高低电平,从逻辑上看是01代码,其中0通常代表低电平,1代表高电平,如果你学过数字电路就会更加明白这个原理,对于一串简单的逻辑电路,我们输入一个电平信号,就会得到一个电平信号的反馈,如果按照相应的时序输入一串高低电平信号,那么我们也会得到一串新的高低电平信号。而多个简单的逻辑电路进行复杂的集成,就可以封装成CPU、显卡、内存、网卡等等电子元器件,而这些电子元器件插在主板上,就形成了一个更复杂的电子集合体,也就是计算机,因此计算机实际上就是一个超大规模的集成逻辑电路,如今我们在使用电脑时干的事情,其实和人类在早期向逻辑电路中输入信号时干的事情一样,只不过我们现在完成的任务更加复杂而已。
通过上面的长篇大论我想说明的其实只是:由高低电平组成的机器语言是最原始的,计算机自身可以理解的语言,当然,用这种语言直接编写的程序是运行起来最快的,同时也是最为复杂的。首先由0和1构成的长篇大论并不适用于人类几千年所构建的语言系统,因此可读性差的很。机器语言的另一个缺点是效率低,因为一个很简单的功能都可能要由一长串01表示,更为糟糕的是你有可能需要重复的写多次这个功能,在此基础上,人们便想到了偷懒的办法,就是把重复次数高的01代码段封装成简单的字母,并对其进行功能上的标记,当系统中需要某功能时,就先写上这几个字母,然后再对照之前写好的机器语言对照表来翻译,这样一来在功能设计的时候就可以节省很多时间,久而久之,人们把几乎所有的机器代码都进行了封装,于是,汇编语言诞生了。
在汇编语言的封装思路的基础上,人们开始对汇编语言进行更进一步的封装,使其看起来更加接近人类说的语言,这样,C语言等低级语言诞生了,C语言是对汇编语言的封装,同时其翻译成汇编语言的速度是非常快的,有些IDE可以实时观察到你写好的C语言对应的汇编代码。由于人类的懒惰之欲望,更加简洁的语言正在出现,随着时间的推移,逐渐出现了C++语言,C++是对C语言的简单封装,添加了面向对象的功能,但只是简单封装,C++的编译器是完全支持C语言的,可以认为C++是对C语言的简单扩充。C++仍然很快,但是没有C语言快,代替的是有些功能实现起来更加方便了。
之后Java,PHP,Go等语言相继诞生,这些语言基本上都是在C语言等低级语言的基础上封装而成的,如Java就是对于C/C++的封装,Java的很多源代码都是C++,高级语言更容易被人理解,学起来更加方便,但相应的,其翻译成机器语言的时间开销也变得越来越大,速度也就更加缓慢。目前市面上的主流语言有:C,C++,Java,PHP,Js,C#,Go,Python,Object-C等,其中C和C++通常用于做一些性能要求高的程序,如游戏,驱动,系统软件等。Java和C#语言性能较为接近,同时C#的语句更加优美,符合人们的语言习惯,但是C#出现较晚,因此没能抢夺Java的霸主地位。C#的特点就是速度足够快,虽说性能接近,但实际上C#的速度更快,因为C#可以用来做游戏。使用范围越来越广的同样还有Go语言,Go语言的性能也是相当优越的,而且近些年来确实有取代Java语言的趋势。
一些更加高级的语言如Js,Php,python多以辅助性语言的角色出现,因为这些语言封窗程度太高,太容易学了,以至于门槛比较低,但是其性能又很高,这就导致其对硬件条件要求高,做网站的话需要性能更加优越的服务器,浏览它的话需要性能更高的主机才行,因此,他们只能说的上是辅助性语言。
不过Java程序员无需担心Java被取代的结局,没有任何一个事物是永恒的,但是在不断变化的事物之中总存在一个不变的核心,那就是编程思想,只要把一门语言学精,就可以透过语言学习编程思想,进而得到永恒不变的真理,这么说有点过了但是只要把一门语言学精,是可以做到触类旁通的,所以现在抓住一个东西不放就行了。
综上所述,我们可以总结为:C/C++语言很基础,值得学习,但是编码复杂,C#比Java好不少,但是使用的人不多,Go有取代Java的趋势,大家学好Java的话可以了解一下,Php,Python,Js是辅助性语言,专门学习的话路子可能不多,世界仍然需要更多的Java程序员,所以大家一起学吧!
1.关于语言的分类
代码总体上分为两种:托管代码,非托管代码。非托管代码指的是无需编译,写好后就可以直接被系统使用的代码,如C语言,因为系统软件大多都是C语言写的,因此它和C语言程序的契合度非常高,可以直接运行起来。托管代码多指高级语言,如Java语言,Java语言是运行在Java虚拟机上的,Java程序的编译运行需要Jdk,在写好Java文件之后需要进行初步编译,把Java文件编译成class文件,然后再进行多次编译,最后翻译成C语言文件,然后再翻译成汇编文件,机器代码,Java程序若想和操作系统打交道,首先是要收到虚拟机洗礼的,因此它不能直接被系统运行,类似的还有python,首先需要下载某个版本的python程序包,才可以写python运行python。大部分非托管代码都是高级语言。
非托管代码又分为脚本代码和非脚本代码,或者说非托管语言分为脚本语言和非脚本语言。脚本语言指的是虽然不能直接和系统软件打交道,但是系统内部自带它的编译程序,如VB,ASP,由这种语言书写的文件是可以直接被系统运行的,有种恶意行为被称为脚本攻击,说的就是这种脚本语言。用脚本语言写成恶意程序之后发给别人,如果这个人的计算机上面带有该语言的编译器,就可以直接运行并进行恶意攻击,当然,不同计算机上所带有的编译器是不同的,因此,某脚本攻击的对象并没有该脚本编译器时,脚本攻击并不能生效。
2.小结
C语言是最接近汇编语言的语言,它运行起来非常快,常被用于做游戏,写驱动。
C++是C语言的初步封装,速度有所下降但是写起来更方便一些,也被用来做游戏,如Unreal引擎由C++书写。
Java是基于C/C++封装而成的高级语言,性能相比于C/C++有所下降,但并不是特别慢,一般的网络平台搭建,并发机制都可以用Java实现,关键是免费,因此受众很广。
C#是微软开发的高级语言,其性能同样优异甚至快于Java,而且行文优美符合人类习惯,可惜的是生不逢时,出现的时间太晚了,市场已经被Java,Go等语言占领的差不多了。
Go语言是一种快读的高级语言,现在多用于大数据,人工智能领域,其书写简洁性,性能都和Java接近甚至优于Java,有代替Java的趋势。
Python语言,JS语言,Php语言是封装程度更高的语言,书写简单,功能实现起来更加简单,但代价是更慢的编译速度以及运行速度,多被用于辅助工作。
程序分为两种:托管程序和非托管程序,托管程序是以Java为代表的,需要虚拟机讲本身文件翻译成C语言文件之后才能执行的高级语言组成的种类群体,他们不能直接被系统识别,需要处理成C语言才行。
非托管程序是由C语言书写的,可以直接被系统识别并执行的程序。
托管程序所需要的语言又分为脚本语言和非脚本语言,脚本语言指的是系统中自带编译器的高级语言,使用相应的脚本书写恶意代码可以进行脚本攻击,因为这种程序可以直接在拥有脚本编译器的计算机中打开并执行。非脚本语言指的是系统中不会自带其编译器的高级语言。
关于Java语言的基础语法
1.主方法
在Java语言中,和C语言一样存在着函数,但是在Java中函数也叫方法,其实都是function的不同翻译。在Java中,如果要写一个简单的程序,那么首先至少要创建一个类,当然这个类是逻辑上的概念,在物理上,处于编写阶段的代码都存在于一个Java文件上,类的书写便是在这个Java文件上写的,而若想让一个程序得以运行,那么就要有主方法,主方法是一个程序得以运行的引擎,是所有程序得以展现的窗口,你可能在Java文件中写了很多个方法很多个类,但是他们若想运行起来的话,那必须要写在主方法里调用。
public class Test{
public static void main(String[] stg){
System.out.println("See you cowboy Bebop!");
}
}
如上代码所示,就是一个基本的主方法了,主方法要写在主类中,主类的名称(这里为Test)必须要和其所位于的Java文件同名,在这里运行这段代码便可以在屏幕上显示出“See you cowboy bebop!”的字样。
当然我们所要知道的还有:一个Java文件中允许存在多个类,如:
public class Test{
public static void main(String[] stg){
System.out.println("See you cowboy Bebop!");
}
}
class fair{
public static int flash(int x){
return x + 5;
}
}
然而在编译时,情况就有所不同了,在将Java文件进行编译后,我们会得到class文件,存在有多个class文件的java文件,会被编译成多个独立的class文件,但是除了含有主方法外的class文件,其他class文件并不能运行。
实际上,任何编程语言都是需要主方法作为运行接口的,主方法相比较与其他的方法也是与众不同的,主方法和其他方法的区别在于主方法可以接受外界刺激并且执行,也就是说主方法是整个程序和外界的接口,程序的运行需要主方法作为媒介和窗口,没有主方法的类就是一个等待使用的类。同时在我们构建项目的过程中会写很多程序,然而具有主方法的程序在其中也是独一无二的,具有主方法的程序可以独立运行,在独立运行起来时,就叫做进程,也就是说,一个带有主方法的程序可以自身变为进程。如果是其他进程调用的库,那它就是一个库,而不是进程。依靠自己的主方法启动的程序叫做进程,而被进程调用,自身并不存在主方法的程序在未运行时称为库,在开始运行之后会作为进程中的线程存在。
PS:在主方法的参数栏内,我们发现有一个字符型的数组,这其实是一个外部传参用的形参,他可以存储外部参数,存在数组内并可以在主函数内使用,在命令行中运行时,我们在类名之后可以写上一些参数,这样在运行时这些参数就可以被传入到主函数中去并加以使用,至于其名称,可以是任何字母,这里是stg,但实际上这里写成aaa,bbb都没问题,不影响参数的使用。
2.其他方法
方法存在于类中,按照面向对象的思维理解可以理解成为某一类事物所具备的能力,行为方式,如狗类就可以具备“咬”的方法。主方法通常位于主类,而其他方法则可以根据需求存在于任何位置,主类中也可以存在很多方法。
public class Test{
public static void main(String[] aaaa){
//System.out.println("See you cowboy Bebop!");
int x = 9;
int y = 2*x - 11;
int mm = f(4);
int ww = f(f(mm) - x);
int tt = f(y);
System.out.println(mm);
System.out.println(ww);
System.out.println(tt);
double aa = g(f(6),tt);
double dd = g(f(mm) + 7,6 - x);
double uu = g(f(4) + 1,3);
System.out.println(aa);
System.out.println(dd);
System.out.println(uu);
int ee = kk(10);
System.out.println(ee);
/*设函数kk(x),x属于N,x>=0,kk(x) = {
x, x<=1
kk(x - 1)+kk(x - 2) x > 1}使用递归实现*/
}
public static int f(int x){
return 2*x - 9;
}
public static double g(int x,int y){
if(x > 0){
return 2*x - y +5.6;
}
else if(x<0){
return f(x+5) - y;
}
else{
return f(2*y + 3) - 0.5;
}
}
public static int kk(int x){
if(x<2)
return x;
else{
return kk(x - 1)+kk(x-2);
}
}
}
如上文所示,在主方法之外也可以存在其他的方法,不同的是这些方法并不会自己运行,若想让它们运行,需要在主方法内调用它们。在最后一个函数kk中,这个函数发生了自身调用,这实际上就是方法的递归调用,Java语言同C语言一样也存在递归函数,但是Java语言的递归效率比C语言慢得多,而且更容易内存溢出,因此在使用时应该更加小心谨慎。
说到递归,我们不得不考虑到递归的终止条件,因为递归是函数不断调用自身,如果没个头,那么迟早会发生栈溢出,导致内存不够用,因此每一个递归函数中,都要有一个终止机制,同时终止机制和自身调用必需位于两个条件互斥的判断中,这样整个函数才能保证递归一定有尽头。任何递归方法里边必然有两个互斥条件,一个条件是调用自身,一个条件是终止自身调用,否则会导致栈溢出。斐波那契数列是典型的递归调用。
3.数据类型
在Java中存在很多不同类型的数据,如整数,小数,字符等,这些数据都占据不同的大小,也就是说占不同的内存容量,在计算机中,他们的存储都是用二进制表示的,因此他们的容量计数单位是比特位,一bit就是一个二进制位,整数中有byte,short,int,long几种常用类型,byte占8个比特位,short占16个比特位,int占32个比特位,long占64个比特位;小数通常有float,double两种常用类型,float占32个比特位,double占64个比特位;字符型根据编码决定占多少比特位,通常来说包含的字符类型越多的编码方式,占据的大小越大;布尔型数据仅有boolean型,占据32个比特位。
笔记重点
※数据类型
在Java中存在着八种基本类型,分别为byte类型,short类型,int类型,long类型,float类型,double类型,char类型,boolean类型,其余的类型都是引用类型,同类型的单个基本类型的变量所占的物理大小是一致的,也就是说,int类型的1234和int类型的12的站位大小一致,其物理内存大小仅和其类型有关,和其数值大小无关,这也是基本类型的一个特点。与之相对的是引用类型,引用类型的大小通常来说不固定,如字符串类型,它的占位大小通常和字符串长度以及编码方式有关。
byte类型占地为8比特位,short类型占地为16比特位,int类型占地为32比特位,long类型占地为64比特位,float类型占地为32比特位,double类型占地为64比特位,char类型占地和编码方式有关,大小不固定,boolean类型占地为32比特位。其中特殊的是boolean类型,boolean类型只有两个值,是true和false,在计算机的机器语言中,用0和1就可以代表错与对了,我们知道在C语言中0就代表false,因此在资源拮据的计算机中,我们为何要消耗32位来表示用1比特位就能表示的类型呢?这里是一个重点,在以后的笔记中我会重点提到并进行详细的解析。