框架前的总结

1:JDK开发环境搭建

Java的开发环境(JDK):
JDK里面包含了Java提供给我们的一些常用开发工具,以及Java的运行环境。

Java的运行环境(JRE):
JRE是Java的运行环境,我们编写的代码都在JRE里面的Java虚拟机运行

Java的虚拟机(JVM):
JVM是Java的虚拟机,我们写的代码都运行在虚拟机之中。

JDK包含有 JRE 而 JRE 包含有 JVM

编程语言的种类:
1:解释型语言
2:编译+解释型语言
3:编译型语言
Java属于编译+解释型语言,我们调用Javac 工具对我们的源代码进行编译,然后由JVM虚拟机根据操作系统的不同来进行不同的解释。

Java最主要的两个命令:
java 解释程序的命令
javac 编译程序的命令
配置环境变量:
首先是新建一个环境变量JAVA_HOME
变量的值就是你jdk的安装目录
在这里插入图片描述
其次就是修改path,在后面加上 ;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;.
;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;.

2:标识符命名规则

标识符的命名规则:
通用规则:
1:由字母、数字、下划线_ 以及美元符号 $组成
2:不能以数字开头
3:区分大小写
4:不能是Java中的关键字和保留字
细致规则:
项目名:每个单词的首字母都要大写
包 名:所有字母全部小写,反域名形式,多个单词用.分割(每个.实际上就是一层文件夹)
正域名: www.baidu.com
反域名: com.baidu.www
类 名: 与项目名相同
变量名:首字母小写,其余单词首字母大写 baiDu
方法名:相同于变量名
常量名:所有字母全部大写,多个单词使用_分割

3:变量的声明,以及赋值

1、什么是变量:
我们可以将变量看成是一个盒子,盒子里面用来存放我们的数据,我们可以直接通过变量来操控里面的值。

2、为什么用变量:
变量的重点在于变字,我们可以对变量进行对此的赋值(初始化),让其在不同地方的代码有不同的值。

3、变量的创建:
3.1、声明变量:类型 变量的名称;
3.2、初始化变量:变量名 = 值;
上面的两步可以合成一步: 类型 变量名 = 值

常量:我们可以将常量量看成一个特殊的盒子,里面存放的也是数据,但是这个数据是长久不变的。
被final关键字修饰的变量就是常量。

4:基本数据类型之间的转换

基本数据类型之间的转换分为两种,1、自动转换 2、强制转换
其中,强制类型转换需要注意精度损失和数据溢出。
注意:布尔型的数据不参与数据之间的转换。

转换为byte:所有的基本数据类型不能自转为byte,所以需要强制转换。

转换为short:只有一个字节的byte可以转换为short,其他都需要强制转换。

转换为int:byte,short,char都可以自动转换为int,其他需要强制转换。

转换为long:byte,short,char,int都可以自动转换为long,其他需要强制转换。

转换为float:只有double不能自动转换为float,需要强制转换。

转换为double:都可以自动转换为double。

转换为char:所有基本数据类型都不能自动转换为char。

注意:当为char赋值为数字的时候,会根据字符编码表自动转换为对应的字符
1
总结:
1、布尔类型不能参与数据类型的转换。
2、自动转换的时候浮点类型的优先级最高,char的优先级最低。
3、相同类型的数据(单纯的整数和单纯的浮点型)字节数较小的可以自动转换为字节数较大的类型。
4、强制转换类型容易造成精度损失和数据溢出。

5:运算符的使用

运算符分为数字运算符、字符串连接符、赋值运算符、关系运算符、逻辑运算符、三目运算符、位运算符。

数字运算符:+,-,/,*,%,++,–。

其中++如果放在后面,代表先使用变量本身的值,然后在进行自增1的操作,++放在前面,代表自增1的操作。然后在使用值。

字符串连接符:

是连接字符串时使用的,当字符串拼接到数字的时候,数字也会变成字符串。

赋值运算符

有=,+=,-=,=,/+,%=。
使用变量进行+=,-=,=,/+,%=赋值的时候会在变量本身值的基础上进行+,-,/%的操作,然后赋值给变量本身。

关系运算符

有>,<,>=,<=,==,!=。
其中使用关系运算符对比基本数据类型的时候对比的是值本身,与类型无关。

逻辑运算符

有&&,&,||,|.。
&&:用于多条件并行使用,只有所有条件都为true,返回结果才为true,当左侧条件不成立的时候,不执行右侧代码
&:用于多条件并行使用,只有所有条件都为true,返回结果才为ture,当左侧条件不成立的时候,依然执行右侧代码
||:用于多条件选一的时候,只要有一个条件为true,返回结果就为true,当左侧条件成立的时候,不执行右侧代码。
|:用于多条件选一的时候,只要有一个条件为true,返回结果就为true,当左侧条件成立的时候,依然执行右侧代码、

三目运算符

三目运算符: ? :
三目运算符?前面放一个布尔表达式,?后面放当前面的表达式为true和false的时候的代码,两者之间用:分割。
三目运算符可以嵌套使用,但是不建以嵌套层数过多。

位运算符

&: 按位与

只有对应的两个二进位均为1时,结果才为1,否则为0。参与运算的数以补码的方式出现。
例如:9&5可写算式如下: 00001001 (9的二进制补码)&00000101 (5的二进制补码) 00000001 (1的二进制补码)可见9&5=1。
按位与运算通常用来对某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 运算 ( 255 的二进制数为11111111)。

|: 按位或

其功能是参与运算的两数各对应的二进位相或。只有对应的两个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。

^ : 按位异或

其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。参与运算数仍以补码出现。
: 取反

求反运算符为单目运算符 ,具有右结合性。其功能是对参与运算的数的各个二进位按位去反。

<<: 左移

左移运算符<<是双目运算符。左移n位就是乘以2的n次方。其功能是把<<左边的运算数的各二进位全部左移若干位,由<<右边的数指定移动的位数,高位丢弃,低位补0.
例如 a<<4 指把a的各二进位向左移动4位。如a=00000011(十进制3),左移4位后为00110000(十进制48)。

:右移
右移运算符“>>”是双目运算符。右移n位就是除以2的n次方。
其功能是把“>>”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数

6:流程控制语句之选择分支语句

选择分支语句if

if的语法:

if(布尔表达式){
表达式为true时执行的代码
}else{
表达式为false时执行的代码
}

其中if是可以嵌套使用的,与三目运算符一样。

选择分支语句switch

switch的语法:

switch(值){
case 值1::
当前case中的值与switch小括号中的一致的话,则执行这里的代码。
break;
case 值:
同上;
default:
当所有case中的值都没有雨switch中的值匹配成功的话,则执行这里的代码。
break;

7:流程控制语句之循环分支语句和 break和continue的区别

流程控制语句之for循环

for语法:
for(声明一个变量(声明一个计数器);循环条件;改变计数器的值){
符合循环条件的时候执行的代码
}
for循环执行顺序:
for(int i = 1;i < 11;i++){}
1:int i = 1; 第一步执行创建变量的操作,并且这一步不进入本身的循环。
2:i<11; 第二步执行判断循环条件的操作,并且每一次循环都会执行此步骤直到循环结束。
3:代码 第三步执行循环作用域中的代码,每次循环都会执行一次。
4:i++ 第四步执行改变初始变量值的操作,每一次都会执行一次。
注意:for循环的小括号内可以不写任何东西,但是必须有;,虽然语法上支持大家这样写,可是不支持大家使用。
如:int i=1;
for(;i<10;){
System.out.println(i);
}
例子:乘法口诀表

	for (int i =1; i <10; i++) {  //外层for循环控制的是行数
		for (int j =1; j <=i; j++) {	//内层for循环控制输出,外层for循环每次迭代的时候,内层for循环中的J都会重新初始化
			System.out.print(j+"*"+i+"="+(j*i)+"\t");
		}
		System.out.println();
	}	
流程控制语句之while循环

while循环语法:

while(循环条件){ 条件为true 则循环,条件为false则停止循环。
循环的代码
}

注意:while循环小括号内不能声明变量,所以我们需要把循环条件的变量定义在循环上面。然后在循环体内改变变量的值,号用于控制循环。
do while循环语法:

do{
循环的代码
}while(循环的条件);

注意:do while循环是最少执行一次的循环体,因为do while是先执行循环体,然后在执行判断条件。

总结:
for循环一般用于明确循环次数的时候使用。
while循环一般用于不明确循环次数的时候,一般用于io流,分析结果集等。
for循环与while循环都是可能不执行的循环体,因为两者在执行的时候都会先判断条件是否成立,如果不成立,则不循环。
break用于打断当前作用域,可以用标记指定打断指定作用域
contiue用户结束本次循环继续下一次循环。

8:数组的声明以及使用

1、数组的定义:

数组(Array)是有序的元素序列(?我还不理解什么是有序的元素序列)。数组是在程序设计中,为了设计方便,把具有相同类型的若干元素按有序的形式组织起来的一种形式,这些有序排列的同类数据元素的集合称为数组。

2.数组的创建:

动态初始化:
声明:类型 [] = 变量名;
初始化: 变量名 = new 类型[长度];
上面两步可以合成一步:类型 [] 变量名 = new 类型[长度];

int [] array = new int [5];//定义一个整型数组,长度为5.

静态初始化:
类型 [] 变量名 = {值1,值2,…}
静态初始化在声明数组的同时对其进行了赋值,里面有多少值,就代表数组长度是多少。

String string = {“张三”,“李四”,…};//声明一个字符串数组。

3、数组的操作:

1、声明一个数组
2、初始化一个数组
3、给数组赋值
4、取值

int [] num;//声明一个数组
num = new int [5];//初始化一个数组
for(int i=0;i<num.length;i++){
num[i] = i;//给数组赋值
}
System.out.println(“数组的第一个元素:”+num[0]);//取值

4、数组的属性;

1:数组名,数组的名称,我们可以在代码中定义多个数组,在使用的时候根据数组名进行区分。
2:元素,数组里面的每一个值(数据)都叫做元素。
3:长度,数组的长度决定了数组里面可以存放多少个元素,数组名.length可以获取数组的长度。
4:索引,数组里面是一个一个的格子,索引代表了格子的位置,索引从0开始计算,永远比长度小一位,通过索引可以对数组进行取值和赋值。

注意 数组的默认值:数组在没有赋值的情况下里面所有的元素都为该类型的默认值。整数:0,浮点:0.0,引用数据类型:null

9:数组的排序

数组排序可以使用工具类Array中的sort进行排序

Array数组工作类
方法 实现的功能
toString(需要输出的数组) 可以让我们的数组转换为字符串
sort(需要排序的数组) 可以让我们的数组进行升序排序
binarySeach(查询的数组,查询的值) 可以返回查询的值在数组中的下标
Fill(数组,值) 可以把数组中的值都替换为括号内的值
copyOf(数组,新数组的长度) 复制老数组的元素到新数组中
tcopyOfRange(数组,开始,结束) 从指定元素开始赋值
注意:
使用binarySearch时,由于底层使用的是二分查找法,所以要求数组必须是排序之后的数组。如果在数组中找不到的话会返回负数。
使用copyOf时,底层会根据新数组的长度创建一个新数组,并将老数组的值都放进新数组中,如果新创建的数组长度超过老数组,超出的下标的数组内,会填入默认值。
使用copyOfRange时,底层会创建一个新数组,然后从开始进行赋值,到结束停止(不包括结束本身的索引,如(array,2,5)就是赋值array的下标为2,3,4)

冒泡排序和选择排序

冒泡排序
定义:冒泡排序是相邻的两个元素进行比较,如果左边大于或小于右边,交换值。
具体实例:

		int [] array = {4,8,6,2,5,88};
		int temp;
		for (int j = 0;j < array.length-1;j++) {//控制次数
			for (int i = 0; i < array.length-1-j; i++) {//由于代码内会用到i+1,所以用i-1反正数组越界
				if(array[i]<array[i+1]){//假如下标i的值小于下标i+1的值
					temp = array[i];    
					array[i] = array[i+1];
					array[i+1] = temp;
				}
			}
			System.out.println("第"+j+"次冒泡排序:");
			for(int m:array){
				System.out.print(m+"\t");
			}
			System.out.println();
		}

选择排序
选择排序的思想是:它的工作原理是第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余未排序的元素中寻找到最小(或最大)的元素,然后放在已排序的序列的末尾。以此类推,直到全部未排序的数组的元素的个数为0.选择排序是不稳定的排序方法。
具体代码示例:

		int [] array = {4,8,6,2,5,88};
		int temp;
		for (int i = 0; i < array.length-1; i++) {
			int key = i;//记录初始对比的下标
			for (int j = i+1; j < array.length; j++) {		
				if(array[j]>array[key]){	//代表array[i]的值更大
					key = j;				//记录值更大的下标
				}
			}
			if(key !=i){	//如果key等于i,那代表i下标就是最大的值,不需要替换
				temp = array[i];
				array[i] = array[key];
				array[key] = temp;
			}                                    https://blog.csdn.net/weixin_43260288/article/details/107870549                
			System.out.println("第"+(i+1)+"次选择排序:");
			for(int m:array){
				System.out.print(m+"\t");
			}
			System.out.println();
		}	
		System.out.println("选择排序");
		for(int m:array){//增强循环输出
		System.out.print(m+"\t");
		}

八大排序算法

10:常用Api

1、格式化日期

利用java.text.DataFormat 的子类(如SimpleDateFormat类)中的format(Date)方法可将日期格式化。

SimpleDateFormat oldFormatter = new SimpleDateFormat("yyyy/MM/dd");
        Date date1 = new Date();
        System.out.println(oldFormatter.format(date1));

        // Java 8
        DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        LocalDate date2 = LocalDate.now();
        System.out.println(date2.format(newFormatter));

具体介绍在以下链接
日期API

11:变量的划分

一:全局变量(如果没有赋值的话,有默认值)
	1:实例变量
		直接定义在类之中,一般都是对象的属性,通过对象才能调用,作用域为 类中的所有实例方法,每个对象
		都有自己的实例变量,互相之间互不影响。
	2:类变量
		直接定义在类中,被static修饰,类的变量在整个类中只有一份,被所有的对象共用,作用域为整个类中。
		可以通过 类名.属性名 来使用,也可以通过对象名.属性名使用。
		类变量经常被工具类定义成常量使用。
二:局部变量
	一般是指定义在方法之内,或作用域之内,作用域为其本身的作用域(例如:if作用域,for作用域,while作用域..)
	局部变量没有默认值,所以不初始化是不能使用的。

12:方法的划分(有参,无参,有返回,无返回)

一:实例方法(对象方法)

方法的组成: [访问修饰符],返回值类型,方法名([形参列表]){方法的代码}
实例方法是属于对象的,所以通过对象才能调用。

二:静态方法(类方法)

被static 修饰的方法就叫做类方法(静态方法),类方法是属于类的 可以使用类名.方法名直接调用,也可以使用
对象名.方法名来调用。

方法根据参数与返回值可以分为4种:
1:无参无返回值
2:有参无返回值
3:有参有返回值
4:无参有返回值。
注意:如果方法中没有返回值的话,需要使用 void 关键字修饰。
如果方法中有返回值的话,使用return关键字将数据返回,返回的数据类型必须与方法规定的返回值类型相同。
方法解析:

一:访问修饰符(用来控制,属性以及方法的被访问权限)
	1:public		公开的,被public修饰的可以被任何类访问(公交车,谁都能上)。
	2:protected		受保护的,只有在同一个包下或者子类才能访问(校车,只有学校的学生,职工能上)。
	3:无访问修饰符	同一个包下才能访问(职工班车,只有教学职工能上)
	4:private		只有在自己的类中能访问(私家车,只有自己能开)。	

二:返回值类型:当你的方法在执行完成之后,需要返回给调用者什么数据就将方法的返回值写成什么类型,然后
	在方法的代码体结束之后,使用return关键字来讲数据返回给方法的调用者,如果方法不需要返回任何数据的话
	可以使用void 关键字来修饰 代表这个方法执行完成后不会返回任何的数据
	注意:返回值的类型可以是任何的数据类型(包括我们自己写的类)。
三:方法名:方法的制定者自己起的名字,只要符合命名规则即可,一般要求见名之意。

四:形参列表:当我们的方法被别人调用的时候,需要传递方法什么数据就定义对应的形参即可。
			 例如:我们定义的方法需要求出 x的y次方,那么方法的形参列表中就需要定义 int x与int y,
			 然后在方法中我们才能根据使用者传递的x与y的值来求出次方。
	注意:形参可以是多个,并且类型可以不相同。
		   在方法中,如果不确定需要的参数具体个数,可以使用 类型 ...来表示参数的个数可以是0个或无数个。
		   在方法体中,可以将其当成数组使用。
五:方法体: 当调用者调用方法的时候,会执行的代码。	

1:实例方法可以调用,类变量以及类方法,但是类方法不能调用实例方法和实例变量。
2:我们在main方法中使用其他类的时候,JVM虚拟机会先将对应的字节码文件加载进来,当加载的过程中发现静态代码块的话,就会先执行静态代码块中的内容。

13:面向对象的概念

不正规的解释:
OOP面向对象:
假如给我一个汽车设计图,那么我就能生产处无限辆汽车,在这里汽车设计图只是一个抽象的概念,并不能当产品使用
,而根据汽车设计图生产出来的汽车才是实际的产品。
汽车设计图 == 等同于我们的类
汽车 == 等同于我们的对象。
按照上面的说法一个类可以产生无数个对象,并且每一个对象都是不同的。
类:实际上类是一个比较抽象的概念,将所有对象的共有属性,以及共有行为抽离出来形成了类。
对象:对象实际上是类的实例化体现。
抽象:可以简单的理解成想象,将有一系列相同属性以及行为抽离出来。
Java说万物皆对象,代表生活中我们的一切都能被抽象成类。
什么是面向对象以及面向过程:
面向过程:当我们想吃饭的时候,我们需要先去市场买菜,洗菜,切菜,炒菜,盛盘,端上桌,吃饭,刷碗这些所有的一切
都需要我们自己动手。
面向对象: 当我们想吃饭的时候,我们去饭店面向服务员,然后由配菜负责买菜,洗菜,切菜,厨师负责炒菜,盛盘,服务
员端菜,而我们只负责吃。

正规的解释:
在百度百科中的解释是:面向对象是相对于面向过程来讲的,面向对象方法,把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式。
具体看下面链接:
面向对象

14:封装,继承,多态的概念以及使用

什么是封装;

1:将具有共同属性以及行为的对象抽象成类。
2:将类中的属性使用private私有化,不让别类访问。
3:将需要循环使用的代码封装成方法,便于重复调用
为什么要使用封装;
1:因为Java是面向对象的语言,而对象产生于我们封装的类
2:为了提高数据安全性,不可以直接访问类中的成员变量
3:为了提高代码的复用性,方便程序的开发
4:语法规范。

继承

1:每个类都会有一个父类,每个类都会继承父类的一些功能(属性和方法)
2:extends 可以让我们的一个类去继承其他类
3:Java之中每个类都只能有一个直接的父类

为什么要使用继承
1:子类继承父类后就可以继承父类非私有的属性以及方法。
2:为了实现多态

什么是多态,如何实现多态;

1:多态是在继承的前提下产生的一个观念,多态是指父类的声明指向了子类的实例化对象。
2:运行时多态发生在继承父类或实现接口后方法重写的前提下,我们声明父类或接口对象,但是指向的却是子类的实例化对象。
3:编译期多态发生在方法重载的前提下,调用同一个方法根据传入的参数不同返回不同的结果。

为什么要使用多态

1:灵活性 实现了参数的统一化(方法可以接收任意的子类对象)。
2:在声明的时候我们不需要去考虑具体实例化的对象是哪一个(框架讲解)
3:可扩展性 新增子类或实现类不影响之前的子类以及实现类
4:可替换性 若将子类对象A替换成子类对象B不影响程序的运行

15:方法的重载以及重写

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或两者都不同)则视为重载。
重写发生在父类和子类中,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类重写更好访问,不能比父类被重写方法声明更多的异常。
重载对放回类型没有特殊的要求。

16:this,super,static,final的区别

this:代表的是当前对象,一个类可以有很多个对象,如果我们代码中使用了this,在调用对象n的时候this就会自动变成
对象n。
this.属性 可以调用当前对象的属性
this.方法 可以调用当前对象的方法

super:代表父类的对象,可以使用其调用父类的属性以及方法,构造方法。
super(); ------ 代表是调用父类的无参构造
super(值); ------ 代表是调用父类的有参构造
super.属性名 ------ 代表是调用父类的属性
super.方法名 ------ 代表是调用父类的方法
如果在子类中使用super调用父类的构造方法,那么必须在子类构造方法中的第一句。
如果子类重写了父类方法以及属性的话,默认调用的都是子类自身的内容,想调用父类的必须通过
super关键字调用。

final: 被final修饰的不能被继承,修改,重写
final修饰在类前面,代表这个类不能被继承。
final修饰在方法上,代表这个方法不能被重写。
final修饰在常量上,代表常量的值不能被修改。

static:静态的
1:修饰在变量上,代表这个变量属于类,在内存中永远值存在一份,可以通过类名直接调用。
2:修饰在方法上,代表这个方法属于类,可以通过类名直接调用
3: 修饰在类中的普通代码块上,叫做静态代码块,静态代码块中的代码只有在类被加载的时候才会执行一次。

abstract:如果修饰在类上,代表这个类是抽象类,可以有抽象方法。
abstract:如果修饰在方法上,代表这个方法是抽象方法,没有方法体(自己不写方法的功能,留给子类去写)
重点:抽象类还是一个类,抽象类有构造方法,但是抽象类不能实例化对象(因为里面的方法没有方法体,无法调用)。
子抽象类可以不用实现父类的方法,交给自己的子类去实现。
祖抽象类有3个抽象方法,父抽象类实现了2个,子类只需要实现1个即可。

17:抽象类以及接口的区别

1:接口是被实现,而抽象类是被继承。
2:接口中的抽象方法默认被public abstract修饰不需要我们手写,而抽象类需要写出abstract。
3:接口中只能声明常量,抽象类中则没有限制。
4:一个类只能继承一个抽象类,但是一个类可以实现多个接口,并且一个接口可以继承多个接口
5:接口中没有构造方法,抽象类中有构造方法。
6:接口中实例方法必须被default修饰,抽象类中则无限制。

18:异常体系,异常的结构

什么是异常,什么是错误?

错误:
表示非常严重的问题,并且程序员无法解决 例如:内存溢出,或JVM内部错误,这些问题程序员不需要关心。
异常:
什么是异常,指我们写代码的过程中,或程序运行的过程中发生了一些问题,这些问题如果不去处理我们的代码无法正常执行。
这些问题是我们程序员通过代码可以解决或避免的。

异常的分类

一:运行期异常
在代码编译的时候,不会出现问题,但是在代码执行的时候可能出现一些异常信息所有的运行期异常都继承与RuntimeException。
二:编译期异常
在代码编译期间出现的问题,如果不去处理的话则无法编译成功所有的编译其异常都直接或间接继承与Exception。

异常的处理流程:

1:当程序运行的期间出现异常之后,那么就会由JVM虚拟机自动根据异常的类型实例化了一个异常对象(这个过程由系统自动完成
与我们无关)
2:当对象产生之后,系统会检查我们的代码判断我们的代码中是否存在异常处理,如果不存在则交给JVM虚拟机去进行处理,JVM
处理异常的方式为:打印异常信息到控制台,然后关闭虚拟机。
3:如果存在异常处理代码,则会由try语句去捕获异常的实例对象,然后交给try后面的每一个catch去进行匹配,如果匹配成功
则执行对应catch中的代码,如果没有匹配成功则继续向下进行匹配。
4:不管最后catch是否匹配成功,都会继续执行finally之中的代码,当finally执行完成之后会根据之前catch匹配的结果继续
执行,如果catch匹配成功则继续执行finally之后的所有代码,如果匹配不成功则将捕获到的异常交给JVM虚拟机处理。

19:集合的继承体系,以及使用

集合:用来表示一组被称为元素的对象,有些集合允许重复,一些集合不允许重复。
集合与数组的区别:
1、数组长度固定,而集合的长度可变
2、数组的存储类型单一,而集合并不单一。

Collection:是所有集合的根元素,继承与Iterable
Iterable:是一个迭代器,里面有默认增强循环for循环的实现,也可以返回Iterator迭代器
Iterator:就是一个最原生的迭代器

List接口:集合的一种

ArrayList:使用动态数组实现,初始容量是10,每次扩容1.5,有序,元素可重复,线程不安全。由于数组是java底层实现的数据
结构,有下标的存在,所以查询的速度快,对修改以及删除速度较慢

LinkedList:双向链表的结构,里面有一个Node类用来充当节点,由于链表不牵扯扩容,所以不牵扯到长度限制以及扩容,
链表中不存在真实的下标,每一次操作几乎都要通过迭代,所以查询速度较慢,但是由于不需要维护下标,所以修改和删除较快。
线程不安全

Vector:底层使用动态数组实现,线程是安全的(由于大部分方法都被synchronized实现),但是速度较慢

Map:虽然map是我们集合框架的一部分,但是其并没有继承我们的collection接口,map里面需要传入两个泛型,是一个key value
键值对存在。
HashMap与HashTable的区别:
1、作者不同
2、诞生时间不一样,HashTable诞生于JDK1.0,HashMap诞生于JDK1.2
3、继承父类不同,HashTable继承于Dictionary,HashMap继承于AbstractMap
4、对外提供的方法不一样,HashTable比HashMap多了elements和contains两个方法。
5、key和value对于null的支持不一样,HashTable不支持,HashMap支持
6、线程安全不同,HashTable安全,HashMap不安全
7、计算哈希值的方式不同
8、初始容量不同,HashTable的初始容量是11,每次扩容是2*n+1,HashMap是16,每次扩容是2n。
如何解决HashMap的线程安全问题
1、ConcurrentHashMap 是HashMap的代替品,由于里面使用了同步代码块,所以是线程安全的。
2、使用同步代码块对map加锁

set :继承于COllection接口,但是底层是使用map的key实现的,所以没有下标的存在,并且值无序不能重复。
由于set需要使用hashCode算法与equals方法来对比元素是否重复,所以我们写的类需要重写这两个方法。
set如何保证value不重复:
1、对比value的hash值(是否发生了hash碰撞)是否相同,如果hash值相同,调用equals方法对比值是否相同。
因为两个对象的hash值相同的话,有可能值是不同的,如果hash值不同,代表值肯定不同
TreeSet与HashSet的区别:
1、Hashset无序,TreeSet有序
2、hashSet可以存null(底层是使用的hashmap),TreeSet不能存null

Compareable 接口,用来定义排序的接口,实现这个接口需要重写compareTo方法,我们可以在方法内对比对象的属性,如果返回
1代表排后面,如果返回-1代表排在起前面,当我们的类实现了这个接口后,就需要使用TreeSet自然排序以及使用Collections.
sort(list)方法对集合排序。

Compatator接口:用来定义排序的接口,实现这个接口需要重写compare方法,我们可以在方法内对比对象的属性,如果返回1代表
排后面,如果返回-1代表排前面,当我们的类实现了这个接口后,就可以使用Collections.sort(list,接口实现类对象)
方法对集合排序(它还可以进行逆序,直接在类对象.reverse).

20:泛型

当我们在类中需要声明成员变量的时候,一般我们都是在开始就指定了成员变量的类型,如果这个成员变量类型我们在编译期间
无法确定的时候,我们可以使用泛型来将类型的确定延迟到使用的时候在确定,注意:泛型只能声明引用数据类型。
注意,下面这个实例,根据传入的类型返回相同的类型

再练习IOC时使用的,根据传入的类型,返回对应类型的对象

public static <T>T getBean(Class<T> c) {
		//获取容器中的所有对象集合
		Collection<Object> collection = map.values();
		//获得一个集合的迭代器对象
		Iterator<Object> iterator = collection.iterator();
		//遍历这个集合
		while(iterator.hasNext()){
			//一次取出集合中的对象
			Object next = iterator.next();
			//判断当前对象的类名是否和传入的一致
			if (next.getClass().getName().equals(c.getName())) {
				return (T)next;
			}
		}
		return null;
		
	}

21:反射

是Java的两大核心机制之一(俗称框架的灵魂)
想要比较好的了解反射,必须要先理解一句话:万物皆对象。
由于Java之中万物皆对象,所以我们写的.class文件在Java中也可以是一个实例化对象,.class文件是属于Class类的实例
对象既然Class的实例对象包含了对应.class文件的所有信息那么我们可以通过Class类的实例对象来操控类中的所有属性
,方法,以及构造器。
简单点说: 通过反射我们可以操控类中的一切内容,并且可以破坏对应的访问修饰符

22:HTML,CSS,JS,jquery

【一】HTML——Hypertext Markup Language
HTML:超文本标记语言,是静态网页。“超文本”就是指页面内可以包含图片、链接,甚至音乐、程序等非文字元素。该文档本身有页面结构,显示页面内容;可以理解为网页中的标签,比如div、ul、p等等这些。浏览器按顺序阅读网页文件,然后根据标记符解释和显示其标记的内容。 HTML文本中包含了所谓的“链接点”HTML利用超链接的方法,将各种不同空间的文字信息组织在一起的网状文本。HTML就是整合网页结构和内容显示的一种语言。

【二】CSS——Cascading Style Sheet
CSS:层叠样式表,通过设置对应的样式属性可以修改html文档内各元素的显示、位置等样式;如修改颜色、字体、字号、宽高、位置、背景等。层叠样式表单是将样式信息与网页内容分离的一种标记语言。我们使用CSS为每个HTML元素定义样式,也可以用于多个界面。css:美化html页面,也是html的一部分。

【三】JS——JavaScript
动态脚本语言,使用JavaScript代码可以让前台变的有交互(点击事件)。广泛应用于web应用的功能开发以及丰富页面体验,可以动态控制页面内容;如修改页面文字、图片、各种效果、功能等;常用来为网页添加各式各样的动态功能(比如:轮播图、tab切换等等),为用户提供更流畅美观的浏览效果。通常JavaScript脚本是通过嵌入在HTML中来实现自身的功能的。

【四】jQuery
jQuery是一个封装好的文件,就是指已经编写好了供他人重复使用的JS代码。

区别:

    HTML定义了网页的内容

    CSS装饰了网页的布局

    JavaScript网页的行为

    jQuery 是一个JavaScript 库

比喻式区别:

    html是人的四肢,

    css是人的衣服装饰,

    js是人的思想和行为,

    jQuery是人使用工具箱。

23:WEB的发展史

http:超文本传输协议
特点:无状态
用处:实际上就是指在与服务器进行一问一答的时候必须要遵守的协议
请求:浏览器向服务器发送数据
响应:服务器向浏览器发送数据

http的版本:
91年诞生0.9的版本,只有get命令只能向服务器请求一个静态的网页
96年诞生1.0的版本,除了静态页面之外,增加了文件,图片,二进制数据等并新增了post,head命令
97年诞生1.1版本,
15年诞生了2.0版本

https在http的基础上增加了ssl/tls加密处理

24:tomcat的结构目录,访问流程

tomcat 的目录结构:
bin:		命令目录
conf:		 配置文件
lib:		里面存放的都是tomcat运行时需要的jar包
logs:		日志信息
temp:		存放临时文件
webapps:	部署项目的目录
work:		里面存放编译后的.java,.calss文件。
src:		里面存放的是源码
访问流程

解析访问地址:http://localhost:8080/week4Webdemo01/
DNS:把域名解析成ip地址,然后才能找到对应的服务器。
例如:输入www.baidu.com(域名),需要使用dns才能解析成IP地址。
localhost:代表本地主机
8080:代表tomcat应用的端口号(web端口默认全部都是80)
我们的电脑上可以同时打开很多的应用,如何找到对应的应用呢,需要通过IP找到那一台电脑,端口确定了访问了哪一个应用
我们只有通过ip+端口号(套接字)才能确定要访问那个电脑上的那个应用。
week4Webdemo01:上下文路径,一般都是我们的项目路径(自动生成的,可以在server.xml中取消掉)。
1.html:我们的项目中有多个页面,根据这个来确定具体访问的哪里

25:servlet的执行流程,生命周期,初始化策略,初始化设置参数

servlet的介绍:

虽然现在我们的tomcat服务器可以去接收请求了,但是请求现在无法与我们的java代码相关联,所以我们需要使用servlet来处理
请求。
servlet:是一个规范,由sun公司在97年提供的一组接口,这一组接口有tomcat等各种服务器来实现。
servlet本质上也是java的类,只是这个类需要遵守一些规范,可以用来处理我们的请求以及返回响应的信息
servlet与tomcat的关系
我们可以将servlet看成一个处理请求的小型服务器,tomcat就是这些服务器的容器,tomcat是一个servlet/jsp
的容器,tomcat负责接收客户端的确

执行流程

http://localhost:8080/WebDemo02/login
1:解析请求信息,http://localhost代表先找到本地电脑,然后根据80端口号
找到本机上端口号为80的程序—>tomcat。
2:找到server.xml文件然后解析这个文件找到文件中的

解析其中的path找到项目的上下文路径,如果找不到会出现404错误
3:找到项目路径后会找到我们项目中的WEB-INF下的web.xml文件并解析
如果其中没有的文本内容为/login的话会出现404,如果找到了
则可以获取到对应的,然后根据name获取到对应的servlet
全限定名继续下一步。
4:判断servlet缓存池中是否有com.zhiyou100.controller.DeptControlle
的对象
5:使用反射调用构造器
obj=Class.froName(“com.zhiyou100.controller.DeptControlle”).newInstance();
把对象放到servlet缓存池中。
cache.put(“com.zhiyou100.controller.DeptControlle”,obj);
(如果缓存池中有对象的话直接在第4步返回跳过次步骤)
6:创建servletConfig对象,并调用init()方法。
obj.init(config);
7:创建ServletRequest和ServletResponse对象并调用service()方法
8:在service方法中对浏览器(客户端)做出响应操作。
如果不是第一次访问,那么跳过5,6,7步骤会在第4步直接返回servlet对象
然后调用service方法。

生命周期

servlet的生命周期:
构造器----->init方法----->循环调用service方法------>destory方法
1、构造方法先执行,因为servlet中的所有方法都是非静态的,全部需要创建对象后才能使用
2、一个servlet类在程序运行期间只会诞生一个对象,默认是在第一次访问的时候才创建。
3、init方法在创建对象后立马调用,一个servlet对象之后执行一次。
4、service方法会在每次请求的时候都执行。
5、destory方法会在tomcat正常关闭的时候执行。

初始化策略,初始化设置参数

servlet的初始化策略(什么时候创建的对象):
默认在tomcat容器启动的时候不创建servlet对象,而是在首次被调用的时候创建
可以使用来指定servlet在什么时候初始化其值分为3种:
load-on-startup<0 代表走的是默认策略。
load-on-startup>0 代表在web容器启动的时候创建Servlet对象,顺序正整数
从小到大最小是0。

如何给servlet中的属性赋值:
方式一:在servlet标签中加入如下代码:

name
张三

方式二:当有100个servlet,所需要的的属性和值都一样的情况下,使用上面的代码需要些100次,这个时候可以使用下面的代码
给所有的servlet属性赋值:

name
上下文的张三

26:servlet的Api

//给请求中的数据设置字符编码
		req.setCharacterEncoding("UTF-8");
		//设置响应的编码
		resp.setCharacterEncoding("utf-8");		
		//根据name接收前台传递过来的参数,接收到的参数都是字符串。
		String string = req.getParameter("username");
		System.out.println("suername:"+string);
		//用来接收复选框的值(因为复选框可能会有多个值)
		String[] values = req.getParameterValues("hobby");
		//循环遍历输出
		for (String string2 : values) {
			System.out.println("hobby:"+string2);
		}			
		//接收前台参数所有的name
		System.out.println("***********接收前台所有的name*******************");
		Enumeration<String> names = req.getParameterNames();
		while(names.hasMoreElements()){
			System.out.println(":"+names.nextElement());
		}
		//将前台的表单的中name以及值封装成map 对象
		Map<String, String[]> map = req.getParameterMap();
		System.out.println("**************将前台的表单的中name以及值封装成map 对象***********************");
		Set<String> keySet = map.keySet();
		for (String string2 : keySet) {
			System.out.println("key:"+string2+"\tvalue:"+map.get(string2));
		}
		
		//返回当前项目的上下文路径
		System.out.println("返回当前项目的上下文路径"+req.getContextPath());
		//根据请求头中key  获得请求头的对应信息
		System.out.println(req.getHeader("Accept-Encoding"));
		//当前请求的地址(资源名称)   http://localhost:8080/Week4Webdemo02/show.html
		System.out.println("当前请求的地址(资源名称)"+req.getRequestURL());
		//获得是上下文之后的地址         	Week4Webdemo02/show.html
		System.out.println("获得是上下文之后的地址 "+req.getRequestURI());
		//获得是访问服务器的客户端地址
		System.out.println("获得是访问服务器的客户端地址"+req.getRemoteAddr());
		
		//从请求之中中根据key获取  setAttribute传递  的数据
		System.out.println("   "+req.getAttribute("xxx"));
		
		//将数据存到请求之中
		req.setAttribute("xxx", "王佳琪今天很高兴");
		
		//设置响应的类型
		resp.setContentType("text/html");
		//获得字符输出流,可以使用它向页面写内容
		PrintWriter writer = resp.getWriter();
		
		//由响应来决定重定向
//		resp.sendRedirect("show.html");
		//重定向到 userservlet
//		resp.sendRedirect("user");
		//重定向到web-inf下的html
//		resp.sendRedirect("WEB-INF/add.html");
		//通过重定向访问其他项目
		resp.sendRedirect("https://www.baidu.com/");

27:请求与响应的区别

请求是浏览器对服务器发出的,响应是服务器端想浏览器端发出的。
请求

28:servlet的作用域

Servlet 的作用域(实现看web组件之间的数据共享):

名称:			类型						描述
1、request		httpServletRequest		代表一次请求
req.setAttribute("xxx", "王佳琪好开心");    代表数据放在请求域之内,至于相同的请求才能去除数据

2、session		HttpSession				代表一次会话
浏览器的一次开启就代表一次会话。
req.getSeeion.setAttribute("xxx","今天中午吃啥吗?");//将数据放入会话中,同一个会话
都能取出对应的数据。多个请求会共享这些数据。
req.getSeeion.getAttribute("xxx"); 		取出会话中的内容。

3、application	ServletContext			代表应用
服务器开启的,就有了应用域对象,服务器关闭销毁应用域对象。
req.getSession.getServletContext.setAttribute("xxx","吃土去吧");
将数据存放在应用域之内,多个session会共享这个数据。

29:重定向与请求转发的区别

1: 请求转发
先获取请求分发器 参数为:需要跳转的资源路径 然后使用forward把对应的
请求与响应对象交给跳转的路径。
req.getRequestDispatcher(“Show.html”).forward(req, resp);
1:url不会随之改变
2:只有一个请求
3:两个servlet可以共享请求中的数据
4:最后的响应结果由最后一个servlet来决定
5:可以访问到WEB-INF下的资源。
6:请求转发不能跨域访问。
2:重定向
1:url会随之改变
2:多个请求
3:两个servlet不可以共享请求中的数据
4:最后的响应结果由最后一个servlet来决定
5:不可以访问到WEB-INF下的资源。
6:重定向可以跨域访问

30:jstl,jsp(四大作用域,九大内置对象),EL表达式

Jsp中的九大内置对象与四大作用域:

1、pageContext		代表当前页面
2、request			代表一次请求
3、session			代表一次会话
4、application		代表应用

5、page
6、config
7、exception
8、out
9、response

El表达式:

1、用来从作用域之内取出值。语法:${变量名}
2、el表达式取值的时候,会先从当前页面取,如果没有则从请求中取,如果还没有则从会话中取
如果还没有则从应用域中取

31:cookie与session

Http的特点:无状态,代表没有记忆力,每次都是不同的请求,无法记住用户是否登录。
会话跟踪技术:专门解决HTTP没有记忆力的问题。

一、cookie:
特点:是一个客户端技术,存储在客户端,通过响应来完成操作,我们可以在响应的时候想客户端添加cookie
	,然后让客户端在每次访问的时候都携带cookie过来,我们通过判断cookie来确定用户是否登录。

问题:1、cookie只能存储一个字符串
	2、cookie存储中文会乱码(新版本支持中文)
	3、每次获取cookie的时候都需要获取一个cookie数组(麻烦)
	4、cookie的数据存储在客户端,容易泄露。
	5、cookie的存储数量有限制

二、session(会话):
特点:是服务器技术,数据存储在服务器上,实际上session的底层就是cookie,session是cookie的升级版。
	可以称呼session为会话cookie。
使用session来完成登录:
当用户登录成功的时候,我们向session对象存一个值,然后每次用户请求的时候我们都判断session对象是否存在该值,
如果存在代表用户登录过,如果不存在代表用户没有登录。
1、session可以存储我们的对象
2、session存储中文不乱码
3、session是自动创建的,可以直接通过请求获取。
4、session数据存储在服务器,较为安全
5、session的存储量没有cookie那么大的限制

32:三层架构,dao设计模式

三层架构:我们将一个应用分为下面的三层

1、视图层
我们的页面以及控制页面跳转的代码和接收页面的参数等等统一叫做视图层。
M:model 简单理解为接收所有前台页面传递过来的对象
V:view 我们所有的页面
C:controller 控制层,用来控制页面的跳转,接收参数等。
2、业务层
写业务逻辑的地方,调用持久层获得数据之后,可以对数据进行一些处理。
3、持久层(数据层)
就是我们的jdbc,是直接访问数据库的地方,这里面只放跟数据库相关的代码。

dao设计模式

实际上就是一个数据库接口,主要负责与数据看打交道,而不会牵扯到业务逻辑。在javaEE介绍的dao设计模式主要是为了创建一个健壮的javaee应用,所以把对数据库的所有操作抽离出来形成了一个接口,然后编写实现类实现接口。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值