java面试题

java面试题总结

1、java的平台版本

Java ME(J2ME,Java 2 Platform Micro Edition,微型版)
Java SE(J2SE,Java 2 Platform Standard Edition,标准版)
Java EE(J2EE,Java 2 Platform Enterprise Edition,企业版)

2、java的特点

简单性、面向对象、分布式、跨平台性、多线程、动态性、健壮性、安全性

3、java跨平台性实现原理

是什么:java跨平台行是指通过Java语言编写的应用程序在不同的系统平台上都可以运行
原理:只要在需要运行java应用程序的操作系统上安装一个Java虚拟机(JVM)即可。由JVM来负责Java程序在该系统中的运行,
这样同一个Java程序在不同的操作系统中就都可以执行,这样就实现了Java程序的可移植性(跨平台性)

4、jdk、jre、jvm区别

一、JDK(Java Development Kit) Java开发工具包:
JDK是提供给Java开发人员使用的,其中包含了java的开发工具,也包括了JRE;
二、JRE(Java Runtime Environment) Java运行环境:
包括Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等,如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可
三、JVM(Java Virtual Machine )Java虚拟机:
是java实现跨平台的最核心的部分,保证程序的跨平台性,以及编译执行写好的java程序
在这里插入图片描述

5、java环境变量配置

JAVA_HOME:配置jdk安装路径,用于提供第三方软件支持
CLASSPATH:用于配置源代码编译后生成位置,jdk1.5以后会默认配置
PATH:使bin下工具可以在任意路径下使用

6、java注释分类

定义:用于解释说明程序的文字
Java注释的分类
单行注释
格式: // 注释文字
多行注释
格式: /* 注释文字 /
文档注释
格式:/
* 注释文字 */
注意事项:多行和文档注释都不能嵌套使用

7、java关键字

关键字是指被java语言赋予了特殊含义的单词,其字母全部小写
常用的代码编辑器对关键字都有高亮显示,比如现在我们能看到的public、class、static等
常用的关键字51+2个,2个保留字const 、goto

8、常量、变量的概念

常量:在程序运行过程中,其值不可以发生改变的量
变量:在程序运行过程中,其值可以发生改变的量

9、标识符命名规则与规范

规则:标识符由数字、字母、下划线“_”、美元符号“$”组成,且不能以数字开头,不能是java中的关键字,并严格区分大小写
规范:
(1)见名知意:根据名字知道标识符对应功能
(2)驼峰命名法:如果标识符由多个单词组成除首个单词首字母外其余单词首字母大写 passWord

10、java数据类型的分类

在这里插入图片描述

在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/b7b15f3d53c3486c8d6f6c5c88290459.png#pic_center

11、如果快速计算2*8

用位运算将2左移三位

12、&&与&的区别

逻辑与&:无论左边真假,右边都要执行
短路与&&:如果左边为真,右边执行;如果左边为假,右边不执行

13、流程控制语句都有哪些?

顺序结构
分支结构(if, switch)
循环结构(for, while, do…while)

14、for循环与while循环的区别

变量作用域不同:
for循环声明的变量只有当前循环可用,while在外声明可以直接使用
使用场景不同:
已知次数的循环使用for循环,未知次数的循环使用while循环

15、break、continue、return的区别

Break:跳出循环,结束循环
Continue:跳过本次循环,继续下次循环
Return:结束当前方法返回数据

16、数组的特点

用于存储具有相同数据类型的容器称之为数组
特点:长度固定,存储类型相同

17、方法的语法

修饰符:public static固定写法
返回值类型:表示方法运行的结果的数据类型,方法执行后将结果返回到调用者
参数列表:方法在运算过程中的未知数据,调用者调用方法时传递
return:将方法执行后的结果带给调用者,方法执行到 return ,整体方法运行结束

18、面向对象编程思想

强调通过调用对象的行为来实现功能,而不是自己一步一步的去 操作实现

19、类与对象的关系

类是对一类事物的描述,是抽象的 类是大量对象共性的抽象
对象是一类事物的实例,是具体的 对象是类在客观世界中的具体表现
类是对象的模板,对象是类的实体 类是创建对象的模板

20、面向对象三大特性

封装:封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。要访问该类的数据,必须通过指定方式,封装可以让代码更容易理解与维护,也加强了代码的安全性
继承:多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可
多态:用同一对象调用同一方法但是做了不同的事情;
前提:- 要有继承或实现关系

  • 要有方法的重写
  • 要有父类引用指向子类对象

21、抽象类与接口的区别

·成员区别
抽象类
变量,常量;有构造方法;有抽象方法,也有非抽象方法
接口
常量;抽象方法
·关系区别
类与类
继承,单继承
类与接口
实现,可以单实现,也可以多实现
接口与接口
继承,单继承,多继承
·设计理念区别
抽象类
为了继承而来,让子类强制重写父类中的抽象方法
接口
对行为抽象,主要是行为,主要用于功能的扩展

22、super与this的区别

super:它引用当前对象的直接父类中的成员
this:它代表当前对象名
super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法
super()和this()均需放在构造方法内第一行。
尽管可以用this调用一个构造器,但却不能调用两个。
this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数, 其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语 句,就失去了语句的意义,编译器也不会通过。
this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变 量,static方法,static语句块。
从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

23、重写与重载的区别

一、重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载重载对返回类型没有特殊的要求;
二、重写发生在子类与父类之间,重写要求子类重写方法与父类有相同的返回类型,且方法的访问权限要高于父类

24、访问权限修饰符

在这里插入图片描述
在四大权限中,public是最大的权限,private是最小的权限;
在编写代码时,如果没有特殊的考虑,建议以下使用方式:
成员变量使用 private ,隐藏细节
构造方法使用 public ,方便创建对象
成员方法使用 public ,方便调用方法
类只能使用public或默认修饰

25、static关键字

当 static 修饰成员变量时,该变量称为类变量,被该类的每个对象共享;当 static 修饰成员方法时,该方法称为类方法 ,可以议使用类名来调用,而不需要创建类的对象
注:
静态方法可以直接访问类变量和静态方法
静态方法不能直接访问普通成员变量或成员方法;反之,成员方法可以直接访问类变量或静态方法
静态方法中,不能使用this关键字
被static修饰的内容:
是随着类的加载而加载的,且只加载一次
存储于一块固定的内存区域(静态区),所以,可以直接被类名调用
它优先于对象存在,所以,可以被所有对象共享

26、final、finally、finalized的区别

final:是修饰符,如果修饰类,此类不能被继承;如果修饰方法和变量,则表示此方法和此变量不能再被改变,只能使用。
finally:是 try{} catch{} finally{} 最后一部分,表示不论发生任何情况任何异常finally包裹的代码块都会执行
Finalize:是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法

27、为什么重写equals需要重写hashcode方法

如果equals方法相等,则他们hashcode的hash值必然相等,俩个对象必然相等
如果equals方法不等,则他们hashcode的hash值不一定不等,俩个对象必然不等
如果hashcode的hash值不等,则俩个对象必然不等
如果hashcode的hash值相等,俩个对象不一定相等,要在判断equals是否相等来比较俩个对象是否相等。
所以,需要同时重写equals方法和hashcode方法。

28、String类可不可以被继承

String类是final类,不可以被继承

29、String 和 StringBuffer,StringBuilder 的区别是

String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String;
StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer

30、equals与==的区别

对于基本类型来说是值比较,对于引用类型来说是比较的是引用;
而 equals 默认情况下是引用比较,但很多类重新了 equals 方法,所以一般情况下 equals 比较的是值是否相等

31、什么是包装类

Java提供了两大数据类型:基本类型与引用类型,使用基本类型在于效率,然而很多情况,会创建对象使用,因为对象可以做更多的功能,如果想要我们的基本类型像对象一样操作,就可以使用基本类型对应的包装类

32、什么是自动拆装箱

从JDK 5开始,基本类型与包装类的装箱、拆箱动作可以自动完成,也就是基本类型与包装类之间的自动互相转换

33、字符串工具类中常用方法有哪些

•indexof();返回指定字符的的索引。
•charAt();返回指定索引处的字符。
•replace();字符串替换。
•trim();去除字符串两端空格。
•splt();字符串分割,返回分割后的字符串数组。
•getBytes();返回字符串byte类型数组。
•length();返回字符串长度。
•toLowerCase();将字符串转换为小写字母。
•toUpperCase();将字符串转换为大写字母。
•substring();字符串截取。
•equals();比较字符串是否相等。

34、String str = “i” 和String str = new String(“1”)一样吗

不一样,内存的分配方式不一样,String str = "i"的方式,JVM会将其分配到常量池中,而 String str = new String(“i”),JVM会将其分配到堆内存中

35、String str=new String(“abc”)创建了几个对象

两个对象,一个是静态区的” abc”,一个是用 new 创建在堆上的对象

36、深克隆与浅克隆的区别

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址

37、异常的分类

编译时期异常:checked异常。在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)
运行时期异常:runtime异常。在运行时期,检查异常.在编译时期,运行异常不会编译器检测(不报错)。(如数学异常)

38、异常的处理方式

Java 的异常处理
是通过 5 个关键词来实现的: try、catch、throw、throws 和 finally。一般情况下是用 try 来执行一段程序, 如果系统会抛出(throw) 一个异常对象,可以通过它的类型来捕获(catch) 它, 或通过总是执行代码块(finally) 来处理; try 用来指定一块预防所有异常的程序;catch 子句紧跟在 try 块后面,用来指定你想要捕获的异常的类型; throw 语句用来明确地抛出一个异常; throws 用来声明一个方法可能抛出的各种异常(当然声明异常时允许无病呻吟);finally 为确保一段代码不管发生什么异常状况都要被执行;try 语句可以嵌套,每当遇到一个 try 语句,异常的结构就会被放入异常栈中,直到所有的 try 语句都完成。如果下一级的try 语句没有对某种异常进行处理,异常栈就会执行出栈操作,直到遇到有处理这种异常的 try 语句或者最终将异常抛给 JVM

39、float f=3.4;是否正确

不正确。3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(downcasting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写 成float f =3.4F;。

40、new一个对象的过程和clone一个对象的区别

new 操作符的本意是分配内存。程序执行到 new 操作符时,首先去看 new 操作符后面的类 型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数, 填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把 他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。 clone 在第一步是和 new 相似的,都是分配内存,调用 clone 方法时,分配的内存和原对象 (即调用 clone 方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域,填 充完成之后,clone方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发 布到外部。

41、switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在String上

switch可作用于char byte short int
switch可作用于char byte short int对应的包装类
switch不可作用于long double float boolean,包括他们的包装类

42、short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗

short s1 = 1; s1 = s1 + 1;
错! s1 + 1,s1是short类型,1是int型,s1会自动转换为int型的1,与1相加后,得到int型的2,要向左侧的short类型的s1看齐,即需要通过强制类型转换。正确写法:s1 = (short) (s1 + 1);
short s1 = 1; s1 += 1;
正确! 执行s1+=1;其实执行的是s1 = (short) (s1 + 1); 其中会有一个强制转换的过程。

43、增强for循环与普通for循环的区别

1 、增强型for循环书写简洁,遍历数组时不需要下标,主要用于数组或集合的遍历,数组或集合遍历完毕时循环会结束执行。
2 、普通for循环需要三个条件,包括循环变量、循环结束条件和循环变量的变化。

44、简述集合体系结构

集合可分为Collection和Map两种体系
Collection接口:
单列数据,定义了存储一组对象的方法的集合

List 接口:元素有序、可重复。(常被称为“动态”数组,自动扩容)
ArrayList、LinkedList、Vector
Set 接口: 元素无序、不可重复 。(高中时候讲过的集合。无序性、确定性、互异性)
Set的集合常常用于数据的过滤。
HashSet、LinkedHashSet、TreeSet

Map接口
双列数据,保存具有映射关系“key - value对”的集合。
Map集合是一个value可以对应不同的key,但是一个key不能对应多个value)
HashMap 、LinkedHashMap、TreeMap、HashTable、properties

45、length、length()、size()的区别

length ()是针对字符串来说的,要得到一个字符串的长度就要用它的 length ()方法;
length 属性是针对java数组来说的,求数组的长度就用它的 length 属性;
size ()方法是针对泛型集合的,调用此方法能知道这个泛型有几个元素。

46、List与Set区别

1.相同点:都属于Java中的集合
2.List的主要实现类为ArrayList和LinkList;Set的主要实现类为.HashSet和TreeSet
3.List可以允许有重复值;Set不可以有重复值
4.List可以插入多个null值;Set只允许插入一个null值
5.List集合内是有序的;Set集合是无序的,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序
6.List方法常用的实现类有ArrayList、LinkedList 和 Vector。其中ArrayList 最为流行,它提供了使用索引的随意访问,而LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适,Vector 表示底层数组,线程安全
7.Set方法中最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和compareTo() 的定义进行排序的有序容器

47、hashSet当链表阈值到达几转换为红黑树?到达几时转换回链表?为什么不一样?

当链表长度大于阈值(默认是8)的时候,将链表转换为红黑树,以减少搜索时间,提升检索效率;当红黑树节点小于阈值(默认为6)的时候,将红黑树转换为链表,这样做是为了节省维护红黑树这种数据结构的空间消耗。

48、hashSet存储数据的流程(删除数据的流程)

首先进行初始的桶扩容
调用元素a所在类的hashCode(),计算元素a的hash值,通过某种算法就算出底层数组存在的位置(即下标/索引)
判断数组此位置上是否已经有元素
如果没有其他元素,则元素a添加成功
如果有其他元素b(或以链表形式存在的多个元素),则需比较元素a与元素b的hash值
如果hash值不相同,则元素a添加成功
如果相同,进而调用元素a所在类的equals()
返回true,元素添加失败
返回false,则元素a添加成功(如果存在多个元素,需一一比对)
遍历判断链表长度是否大于8
小于8链表存入
大于8转换成红黑树存入

49、Map与Collection的区别

Map:是一个双列集合,常用语处理有对应关系的数据,key是不可以重复的。
Collection:是单列集合,Collection有不同的子体系,有的允许重复有索引有序(例如ArrayList),有的不允许重复而且无序(例如Set)

50、什么是递归?递归书写注意的事项有哪些?

方法的自身调用或者方法间的互相调用;
注意事项:
递归一定要有递归边界,保证递归能够停下来,否则会发生栈内存溢出;在递归中虽然有限定条件,但是递归次数依旧不能太多,否则还是会发生栈内存溢出;构造方法禁止递归

51、创建线程的方式有几种?分别是什么?

创建线程方式有四种:
1.继承Thread类,重写run方法
2.实现runnable接口,实现run方法,交由线程对象运行
3.实现callable接口,通过包装器FutrueTask创建线程(有返回值)
4.线程池创建

52、Thread与Runnable的区别?

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享
实现Runnable接口比继承Thread类所具有的优势:
1.适合多个相同的程序代码的线程去共享同一个资源
2.可以避免java中的单继承的局限性
3.增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立
4.线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类

53、start方法与run方法的区别(为什么重写run方法调用start方法启动线程)

1.调用方不同:start方法由开发人员调用开启线程,run方法由系统分配资源后自动调用
2.生命周期不同:start方法会将线程由初始态转换为就绪态,run方法会将线程由就绪态转换为运行态
3.执行方式不同:start方法由开发人员手动调用才能执行,run方法是系统存在资调度后自动执行,且run方法也可以直接执行,
但是直接执行就是在当前线程直接执行代码,不会创建新的线程
4.执行次数不同:start方法在线程创建后只能执行一次,run方法可能被执行多次

54、线程的生命周期

分为五种状态:新建态—>就绪态—>运行态—>阻塞态—>死亡态
新建:线程一旦创建即进入此状态
就绪:当调用start方法,线程就进入就绪态,但不意味着能立即调度执行(没有拿到CPU执行权)
运行:拿到CPU执行权、运行
阻塞:由于一些操作让线程处于阻塞状态,没有资格和执行权,但一些操作可以把它激活,激活后处于就绪状态等待CPU调度即可执行
死亡:由于一些不可修复的错误或其他原因线程不可运行,线程对象变成垃圾并等待回收,一旦进入此状态不可调用start方法重新启动此线程

wait与sleep的区别

(1)提供方不同sleep是Thread类提供的方法 wait是由Object提供的方法
(2)sleep方法是静态方法由Thread直接调用,wait方法由锁对象调用
(3)sleep方法可以在任意线程时使用,wait方法只能在线程同步中使用
(4)sleep方法不会释放锁资源,wait方法会释放锁资源
(5)sleep方法达到指定时间后自动唤醒,wait方法可以自动唤醒也可以手动唤醒

死锁

1,什么是死锁
死锁 是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。也就是两个线程拥有锁的情况下,又在尝试获取对方的锁,从而造成程序一直阻塞的情况。
2,死锁产生的原因
互斥条件:一个资源只能被⼀个线程占有,当这个资源被占用之后其他线程就只能等待。
不可被剥夺条件:当⼀个线程不主动释放资源时,此资源一直被拥有线程占有。
请求并持有条件:线程已经拥有了⼀个资源之后,还不满足,又尝试请求新的资源。
环路等待条件:多个线程在请求资源的情况下,形成了环路链。
3. 如何解决死锁问题
改变产生死锁原因中的任意⼀个或多个条件就可以解决死锁的问题,其中可以被修改的条件只有两个:请求并持有条件 和 环路等待条件。

55.数据库分类

1.关系型数据库(SQL)
传统的关系型数据库有着悠久的历史,从上世纪60年代开始就已经在航空领域发挥作用。因为其严谨的一致性以及通用的关系型数据模型接口,收获了很大一批的用户。
关系型数据库是把数据以表的形式进行储存,然后再各个表之间建立关系,通过这些表之间的关系来操作不同表之间的数据。
常见的关系型数据库有MySQL、Oracle、PostgreSQL等等。
• 关系型数据库是依据关系模型来创建的数据库,所谓的关系模型是指 “一对一、一对多、多对多”,通过关系模型来构建二维表格
• 一对一:身份证号、校园卡
• 一对多:班级-学生、部门-职员
• 多对多:课程-学生、书籍-作者
2.非关系型数据库(NoSQL)
1,键值数据库(key-value)
键值数据库类似于传统语言中使用的哈希表。可以通过key来添加、删除、查询数据,因为使用key主键来访问,所以键值数据库有很高的性能及拓展性。
例如现在很火的redis,由于其数据是储存于内存,读写速度非常快。Redis在一秒内读写可以超过十万个键值。它虽然是作为数据库来开发的,现在更广泛的应用于缓存、消息队列。
2,列存储数据库
不同于关系型数据库的以行为单位储存,列存储数据库将数据存储于列族中,一个列族存储经常被一起查询的相关数据。
先来说说行式数据库,行式数据库是一行一行进行存储的,我们进行查询的时候,也要一行一行进行扫描。例如,我们要从上面的课程表中查询 name 是线代的课程,还会同时查询到很多我们不需要的信息。即使我们需要的一列的数据,也要进行整行扫描。这在某些场景下是很浪费IO效率的。
3,文档型数据库
文档型数据库与键值数据库是类似的,只不过它将数据用文档的形式储存,数据存储可以是XML、JSON等多种形式。
4,图数据库
图数据库允许我们将数据以图的方式存储。实体会被作为顶点,而实体之间的关系则会被作为边。因为使用的是灵活的图模型,所以可以拓展到多个服务器上。图数据库没有标准的SQL查询语言。许多Graph DB都有restful式的数据接口或者查询API。
3.NewSQL 新型关系型数据库
NewSQL可以理解为是传统的关系型数据库与NoSQL结合的产物。它试图将传统关系数据库的数据一致性优势与NoSQL平台的可伸缩性结合起来。

56.myisanm与innoDB的区别

  1. InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;
  2. InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;
  3. InnoDB是聚集索引,使用B+Tree作为索引结构,数据文件是和(主键)索引绑在一起的(表数据文件本身就是按B+Tree组织的一个索引结构),必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。
    MyISAM是非聚集索引,也是使用B+Tree作为索引结构,索引和数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。
    也就是说:InnoDB的B+树主键索引的叶子节点就是数据文件,辅助索引的叶子节点是主键的值;而MyISAM的B+树主键索引和辅助索引的叶子节点都是数据文件的地址指针。
  4. InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
  5. Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高;5.7以后的InnoDB支持全文索引了
  6. MyISAM表格可以被压缩后进行查询操作
  7. InnoDB支持表、行(默认)级锁,而MyISAM支持表级锁
    InnoDB的行锁是实现在索引上的,而不是锁在物理行记录上。潜台词是,如果访问没有命中索引,也无法使用行锁,将要退化为表锁。
    8、InnoDB表必须有主键(用户没有指定的话会自己找或生产一个主键),而Myisam可以没有
    9、Innodb存储文件有frm、ibd,而Myisam是frm、MYD、MYI
    Innodb:frm是表定义文件,ibd是数据文件
    Myisam:frm是表定义文件,myd是数据文件,myi是索引文件

57.sql语句分类

SQL语句的五种分类分别是DQL、DML、DDL、TCL和TCL,下面对SQL语句的五种分类进行列举:

1、数据库查询语言(DQL)
数据查询语言DQL基本结构是由SELECT子句,FROM子句,WHERE 子句组成的查询块,简称DQL,Data Query Language。代表关键字为select。
2、数据库操作语言(DML)
用户通过它可以实现对数据库的基本操作。简称DML,Data Manipulation Language。代表关键字为insert、delete 、update。
3、数据库定义语言(DDL)
数据定义语言DDL用来创建数据库中的各种对象,创建、删除、修改表的结构,比如表、视图、索引、同义词、聚簇等,简称DDL,Data Denifition Language。代表关键字为create、drop、alter。和DML相比,DML是修改数据库表中的数据,而 DDL 是修改数据中表的结构。
4、事务控制语言(TCL)
TCL经常被用于快速原型开发、脚本编程、GUI和测试等方面,简称:TCL,Trasactional Control Languag。代表关键字为commit、rollback。
5、数据控制语言(DCL)
数据控制语言DCL用来授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等。简称:DCL,Data Control Language。代表关键字为grant、revoke。

58.sql语句执行顺序

顺序1:定位到表1,内部形成一个虚拟表1(其实就是表1)
顺序2:表1和表2连接,形成一个虚拟的大表2,而且是笛卡尔现象表
顺序3:留下大表2中满足连接条件的记录,去掉不满足连接条件的记录,形成一个新的虚拟表3
顺序4:留下虚拟表3中满足筛选条件的记录,去掉不满足筛选条件的记录,形成一个新的虚拟表4
顺序5:根据分组列表,将分组列表的值相同的记录归到一组,形成一个新的虚拟表5
顺序6:留下虚拟表5中满足筛选条件的记录,去掉不满足筛选条件的记录,形成一个新的虚拟表6
顺序7:根据查询列表,比如是字段1,字段2,将表6中字段1和字段2拼接在一个形成一个虚拟表7, 并输出表7
顺序8:根据排序列表将表7进行排序形成一个新的虚拟表
顺序9:根据offset和size将表8中从offset条开始,取出size条记录拼接成一个新的虚拟表8,并输出表8

59,varchar与char的区别

区别一,定长和变长
char 表示定长,长度固定,varchar表示变长,即长度可变。当所插入的字符串超出它们的长度时,视情况来处理,如果是严格模式,则会拒绝插入并提示错误信息,如果是宽松模式,则会截取然后插入。如果插入的字符串长度小于定义长度时,则会以不同的方式来处理,如char(10),表示存储的是10个字符,无论你插入的是多少,都是10个,如果少于10个,则用空格填满。而varchar(10),小于10个的话,则插入多少个字符就存多少个。
varchar怎么知道所存储字符串的长度呢?实际上,对于varchar字段来说,需要使用一个(如果字符串长度小于255)或两个字节(长度大于255)来存储字符串的长度。但是因为他需要有一个prefix来表示他具体bytes数是多少(因为varchar是变长的,没有这个长度值他不知道如何读取数据)。
区别之二,存储的容量不同
对 char 来说,最多能存放的字符个数 255,和编码无关。
而 varchar 呢,最多能存放 65532 个字符。VARCHAR 的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是 65,532字节

60,int(1)与int(10)的区别

INT[(M)] [UNSIGNED] [ZEROFILL]
普通大小的整数。带符号的范围是-2147483648到2147483647。无符号的范围是0到4294967295。
INT(1) 和 INT(10)本身没有区别,但是INT[(M)] 加上ZEROFILL值后,会对值有宽度的设置。
在创建表的时候将zerofill加上试一下。
我们看见数据12前面输出多了个0,是因为加了zerofilll后,是用于显示宽度的限制。而多出来的会照常显示出来。只是系统判定12显示宽度不足,会补0来补全显示宽度。
但是要注意插入负数的时候:
没有设置zerofill的时候负数正常显示
咱再来看看设置 zerofill的时候:
我们可以看出,插入的是-1234 而显示确是000。
添加zerofill的时候系统会给自动添加上unsigned(无符号整型)属性,就是非负数。而设置的显示宽度为3位。所以就会输出000,所以,在没有添加zerofill的时候int(1)和int(10)是没有区别的。

61,count(*)与count(字段)的区别

count(*) 和count(1) 都是统计行数,而count(字段) 是统计字段列非null的行数
在不同的存储引擎中,count(*)函数的执行是不同的

效率:
1、如果在开发中需要用到count()聚合,那么优先考虑count(),因为mysql本身对于count()做了特别的优化处理。
有主键或联合主键的情况下,count()略比count(1)快一些。
没有主键的情况下count(1)比count(
)快一些。
如果表只有一个字段,则count(*)是最快的。
2、使用count()聚合函数后,最好不要跟where age = 1;这样的条件,会导致不走索引,降低查询效率。除非该字段已经建立了索引。使用count()聚合函数后,若有where条件,且where条件的字段未建立索引,则查询不会走索引,直接扫描了全表。
3、count(字段),非主键字段,这样的使用方式最好不要出现,因为它不会走索引。

62, count(主键ID)比count(1)慢的原因?

对于 count(主键 ID) 来说,InnoDB 引擎会遍历主键索引树,把每一行的ID值取出来,返回给server层,server层拿到ID后,判断是不可能为空的,按行累加加1,最后返回累计值。
对于count(1),InnoDB引擎会扫描主键索引树,但不取值,server层对于返回的每一行,按行累计加1,判断不可能为NULL,返回累计值。
从InnoDB引擎层返回ID会涉及到解析数据行、拷贝字段值的操作,因此count(主键 ID)执行要比count(1)执行慢。

count(主键id)走主键索引的时候效率较count()差的原因?
平时我们检索一列的时候,基本上等值或范围查询,那么索引基数大的索引必然效率很高(符合走主键索引查找速度最快的原则)。
但是在做count(
)的时候并没有检索具体的一行或者一个范围,那么选择基数小的索引对count操作效率会更高。在做count操作的时候,mysql会遍历每个叶子节点,所以基数越小,效率越高。mysql非聚簇索引叶子节点保存指向主键ID的指针,所以需要检索两遍索引。但是这里相对于遍历主键索引,即使检索两遍索引效率也比单纯的检索主键索引快。
Innodb是索引组织表,主键索引树的叶子节点是数据,而普通索引树的叶子节点是主键值,所以普通索引树小很多,索引长度越小树的大小就越小。

63,索引失效的场景

(1)like 以%开头,索引无效;当like前缀没有%,后缀有%时,索引有效。
(2)or语句前后没有同时使用索引。当or左右查询字段只有一个是索引,该索引失效,只有当or左右查询字段均为索引时,才会生效
(3)组合索引,不是使用第一列索引,索引失效。
(4)数据类型出现隐式转化。如varchar不加单引号的话可能会自动转换为int型(用select查询时),使索引无效,产生全表扫描。
(5)在索引列上使用 IS NULL 或 IS NOT NULL操作(在 where 子句中对字段进行 null 值判断)
(6)在索引字段上使用not,<>,!=。不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。 优化方法: key<>0 改为 key>0 or key<0。
(7)对索引字段进行计算操作、字段上使用函数。
 (8)当全表扫描速度比索引速度快时,mysql会使用全表扫描,此时索引失效。

索引失效分析工具:
可以使用explain命令加在要分析的sql语句前面,在执行结果中查看key这一列的值,如果为NULL,说明没有使用索引。

64,视图的优缺点

视图的优点
1.第一个显著优点就是它简化了操作。此时我们完全不用关心视图是怎么处理数据的,我们只需要知道如何使用这个结果集即可,视图相当于一个中间层。
2.第二个显著优点就是它更加安全。比如我们可以让用户有权去访问某个视图,但是不能访问原表,这样就可以起到保护原表中某些数据的作用。
3.我们之后会接触到管理权限,权限是无法细致到某一个列的,通过视图,则很容易实现。
4.第三个显著优点就是降低耦合。假如我们以后要修改原表的结构,那么我们可以通过修改视图的定义即可,而不用修改应用程序,对访问者是不会造成影响的,一般来说,这样代价会更小。
视图的缺点
1.性能:从数据库视图查询数据可能会很慢,特别是如果视图是基于其他视图创建的。
2.表依赖关系:将根据数据库的基础表创建一个视图。每当更改与其相关联的表的结构时,都必须更改视图。

65,索引的优缺点

一、索引的优点
1)创建索引可以大幅提高系统性能,帮助用户提高查询的速度;
2)通过索引的唯一性,可以保证数据库表中的每一行数据的唯一性;
3)可以加速表与表之间的链接;
4)降低查询中分组和排序的时间。
二、索引的缺点
1)索引的存储需要占用磁盘空间;
2)当数据的量非常巨大时,索引的创建和维护所耗费的时间也是相当大的;
3)当每次执行CRU操作时,索引也需要动态维护,降低了数据的维护速度。

66,事务的ACID特性

原子性(atomic):事务具有原子性,事务要么全部执行,要么全部失败
一致性(consistency):数据库总是从一个一致性状态转换到另一个一致性状态,不会出现预期以外的结果。
隔离性(isolation):一个事务所做的修改在最终提交以前,对其他事务是不可见的。
持久性(durability):一旦事务提交,所做的修改就会永久的保存到数据库。

原子性的实现原理是通过undo log进行事务的回滚
undo log属于逻辑日志,当发生回滚时,InnoDB会根据undo log的内容做与之前相反的工作。(insert就执行delete,delete就执行insert,update就执行update)
持久性的实现原理是通过redo log

67,事务的隔离级别

四个隔离级别

  1. 读未提交(Read uncommitted)
    所有事务都可以看到其他未提交事务的执行结果。本隔离级别是最低的隔离级别,虽然拥有超高的并发处理能力及很低的系统开销,但很少用于实际应用。因为采用这种隔离级别只能防止更新丢失问题(这个问题现代关系型数据库已经不会发生),不能解决脏读,不可重复读及幻读问题。
  2. 读已提交(Read committed)
    这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别可以防止脏读问题,但会出现不可重复读及幻读问题。
  3. 可重复读(Repeatable read)
    这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。这种隔离级别可以防止除幻读外的其他问题。
  4. 串行化(Serializable )
    这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读、第二类更新丢失问题。在这个级别,可以解决上面提到的所有并发问题,但可能导致大量的超时现象和锁竞争,通常数据库不会用这个隔离级别,我们需要其他的机制来解决这些问题:乐观锁和悲观锁。

68,事务隔离级别参数的问题

  1. 脏读(Dirty Read)
    脏数据所指的就是未提交的数据,而脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。比如,一个事务正在对一条记录做修改,在这个事务完成并提交之前,这条数据是处于待定状态的(可能提交也可能回滚),这时,第二个事务来读取这条没有提交的数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被称为脏读。
  2. 不可重复读(Non-repeatable Read)
    一个事务先后读取同一条记录,而事务在两次读取之间该数据被其它事务所修改,则两次读取的数据不同,我们称之为不可重复读。例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。
    不可重复读和脏读的区别:脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是在同一事务内读取了前一事务提交的数据,即前一次读到的数据是另一个事务提交前,后一次读到的数据是提交后的。
  3. 幻读(Phantom Read)
    一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为幻读。幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行,就好象发生了幻觉一样。
    幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

69,数据库建库建表三范式

第一范式(1NF):要求数据库表的每一列都是不可分割的原子数据项。
概念:所谓第一范式(1NF)是指在关系模型中,对于添加的一个规范要求,所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。即实体中的某个属性有多个值时,必须拆分为不同的属性。在符合第一范式(1NF)表中的每个域值只能是实体的一个属性或一个属性的一部分。简而言之,第一范式就是无重复的域。
说明:在任何一个关系数据库中,第一范式(1NF)是对关系模式的设计基本要求,一般设计中都必须满足第一范式(1NF)。不过有些关系模型中突破了1NF的限制,这种称为非1NF的关系模型。换句话说,是否必须满足1NF的最低要求,主要依赖于所使用的关系模型。
第二范式(2NF):确保表中的每列都和主键相关
概念:第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或记录必须可以被唯一地区分。选取一个能区分每个实体的属性或属性组,作为实体的唯一标识。例如在员工表中的身份证号码即可实现每个一员工的区分,该身份证号码即为候选键,任何一个候选键都可以被选作主键。在找不到候选键时,可额外增加属性以实现区分,如果在员工关系中,没有对其身份证号进行存储,而姓名可能会在数据库运行的某个时间重复,无法区分出实体时,设计辟如ID等不重复的编号以实现区分,被添加的编号或ID选作主键。(该主键的添加是在ER设计时添加,不是建库时随意添加)
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。简而言之,第二范式就是在第一范式的基础上属性完全依赖于主键。(第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。)
第三范式(3NF):确保每列都和主键列直接相关,而不是间接相关
概念:在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
第三范式(3NF)是第二范式(2NF)的一个子集,即满足第三范式(3NF)必须满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个关系中不包含已在其它关系已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性,也就是在满足2NF的基础上,任何非主属性不得传递依赖于主属性。

70,索引的使用场景

适用场景:
在经常需要搜索的列上,可以加快搜索的速度;
在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;
在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;
在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。
不适用场景
同样,对于有些列不应该创建索引。一般来说,不应该创建索引的这些列具有下列特点:
第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
第三,对于那些定义为text,
image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少,不利于使用索引。
第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改操作远远多于检索操作时,不应该创建索引。

71,InnoDB如果没有设置主键的话,它内部会怎么处理?

如果定义了主键,那么InnoDB会使用主键作为聚簇索引。

如果没有定义主键,那么会使用第一非空的唯一索引(NOT NULL and UNIQUE INDEX)作为聚簇索引 - 如果既没有主键也找不到合适的非空索引,那么InnoDB会自动生成一个不可见的名为ROW_ID的列名为GEN_CLUST_INDEX的聚簇索引,该列是一个6字节的自增数值,随着插入而自增
很明显,缺少主键的表,InnoDB会内置一列用于聚簇索引来组织数据。而没有建立主键的话就没法通过主键来进行索引,查询的时候都是全表扫描,小数据量没问题,大数据量就会出现性能问题。

73,delete、truncate、drop区别

drop用于删除整个表,包括表结构和数据,而delete和truncate只删除表中的数据,保留表结构。
delete是DML语句,可以回滚,可以带有where子句,可以删除部分数据,而truncate和drop是DDL语句,不能回滚,不能带有where子句,一次性删除整个表中的数据。
drop和truncate删除数据的速度比delete快,因为它们不需要逐行删除数据,而是直接删除整个表或数据页。
drop删除数据后,表的结构和索引都会被删除,需要重新创建表和索引,truncate只删除数据,表的结构和索引不受影响。

74,搜索mysql检查约束

MySQL 检查约束(CHECK)可以通过 CREATE TABLE 或 ALTER TABLE 语句实现,根据用户实际的完整性要求来定义。
它可以分别对列或表实施 CHECK 约束。

1,选取设置检查约束的字段
检查约束使用 CHECK 关键字,具体的语法格式如下:
CHECK <表达式>
其中:<表达式>指的就是 SQL 表达式,用于指定需要检查的限定条件。
若将 CHECK 约束子句置于表中某个列的定义之后,则这种约束也称为基于列的 CHECK 约束。
在更新表数据的时候,系统会检查更新后的数据行是否满足 CHECK 约束中的限定条件。
MySQL 可以使用简单的表达式来实现 CHECK 约束,也允许使用复杂的表达式作为限定条件,例如在限定条件中加入子查询。
注意:若将 CHECK 约束子句置于所有列的定义以及主键约束和外键定义之后,则这种约束也称为基于表的 CHECK 约束。该约束可以同时对表中多个列设置限定条件。
2,在创建表时设置检查约束
创建表时设置检查约束的语法规则如下:
CHECK(<检查约束>)
3,在修改表时添加检查约束
修改表时设置检查约束的语法规则如下:
ALTER TABLE tb_emp7 ADD CONSTRAINT <检查约束名> CHECK(<检查约束>)
4,删除检查约束
修改表时删除检查约束的语法规则如下:
ALTER TABLE <数据表名> DROP CONSTRAINT <检查约束名>;

75,sql优化

统一SQL语句的格式
对查询进行优化,应尽量避免全表扫描
  1、查询 SQL 尽量不要使用 select *,而是 select 具体字段
  2、如果知道查询结果只有一条或者只要最大/最小一条记录,建议用 limit 1
  3、应尽量避免在 where 子句中使用 or 来连接条件
  4、优化 limit 分页
  5、优化你的 like 语句
  6、使用 where 条件限定要查询的数据,避免返回多余的行
  7、尽量避免在索引列上使用 MySQL 的内置函数
  8、应尽量避免在 where 子句中对字段进行表达式操作,这将导致系统放弃使用索引而进行全表扫
  9、Inner join 、left join、right join,优先使用 Inner join,如果是 left join,左边表结果尽量小
  10、应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描
  11、使用联合索引时,注意索引列的顺序,一般遵循最左匹配原则
  12、对查询进行优化,应考虑在 where 及 order by 涉及的列上建立索引,尽量避免全表扫描
  13、如果插入数据过多,考虑批量插入
  14、在适当的时候,使用覆盖索引
  15、慎用 distinct 关键字
  16、删除冗余和重复索引
  17、如果数据量较大,优化你的修改/删除语句
  18、6值代替 null
  19、不要有超过 5 个以上的表连接
  20、exist&in 的合理利用
  21、尽量用 union all 替换 union
  22、索引不宜太多,一般 5 个以内
  23、尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型
  24、索引不适合建在有大量重复数据的字段上,如性别这类型数据库字段
  25、尽量避免向客户端返回过多数据量
  26、当在 SQL 语句中连接多个表时,请使用表的别名,并把别名前缀于每一列上,这样语义更加清晰
  27、尽可能使用 varchar/nvarchar 代替 char/nchar
  28、为了提高 group by 语句的效率,可以在执行到该语句前,把不需要的记录过滤掉
  29、如果字段类型是字符串,where 时一定用引号括起来,否则索引失效
  30、使用 explain 分析你 SQL 的计划

76. Sql执行顺序(标号为执行顺序)

(8) SELECT
(9) DISTINCT column,…
选择字段 、去重
(6) AGG_FUNC(column or expression),…
聚合函数
(1) FROM [left_table]
选择表
(3) <join_type> JOIN <right_table>
链接
(2) ON <join_condition>
链接条件
(4) WHERE <where_condition>
条件过滤
(5) GROUP BY <group_by_list>
分组
(7) HAVING <having_condition>
分组过滤
(10) ORDER BY <order_by_list>
排序

(11) LIMIT count OFFSET count;
分页

77,双亲委派机制

当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载的类。每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回了。
当前classLoader的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载, 一直到bootstrp ClassLoader.
当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。
这样做的好处是什么?
1.避免重复加载。当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。
2.为了安全。避免核心类,比如String被替换。

78,主要有一下四种类加载器:

启动类加载器(Bootstrap ClassLoader)用来加载java核心类库,无法被java程序直接引用。
扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java类。一般来说,Java 应用的类都是由它来完成加载的。可以通过ClassLoader.getSystemClassLoader()来获取它。
用户自定义类加载器,通过继承 java.lang.ClassLoader类的方式实现。
三层架构与mvc的区别

79,Servlet生命周期

构造 servlet,然后使用 init 方法将其初始化。
第一次发送请求的时候。 执行一次(servlet可以看做是单例模式)
处理来自客户端的对 service 方法的所有调用。
客户端发送一次请求,调用service方法一次。执行多次
从服务中取出 servlet,然后使用 destroy 方法销毁它,最后进行垃圾回收并终止它。
tomcat服务器关闭的时候,销毁

80,转发与重定向区别

转发的地址栏不会发生改变,但是重定向会发生改变
转发是一次请求和一次响应,但是重定向是多次请求与响应
转发的状态码是2xx,重定向是3xx
转发可以使用request域对象传递数据,但是重定向不可以(必须将请求与响应对象传递)
转发本质请求转发指定服务执行后由当前服务进行返回,重定向当前服务结束客户端继续请求其他服务
转发发生在服务器内部,转发的资源不需要携带项目名,重定向可以重定到任何公开资源(需要带项目名)。
转发可以请求web-inf下的内部资源

81,get请求与post请求区别

get请求发送数据在url地址栏传输,post请求在请求体中传输
get请求相比post不安全
get请求可以被书签保存,但是post不可以(因为书签保存的是url可以保存请求的数据)
get请求在浏览器页面后退时无影响,post可能导致表单的重复提交
get请求浏览器会主动缓存相应的数据,post不会主动缓存
get请求页面编码与后台编码相同不会乱码,post可能会乱码
get请求根据不同浏览器设置请求数据上限不定(一般为2k),post请求可以看做无大小限制
get请求发送1次,post请求发送2次(请求会将数据同url一同发送,post则是请求地址响应后再次发送)
最后一条也可以理解为,get请求服务器被动接收(你服务器接不接受数据我数据都随着请求地址发送过去了)
post请求服务器主动接受,会在服务器响应后才将数据发生给服务器

82,cookie与session的区别

从存储方式上比较
Cookie只能存储字符串,如果要存储非ASCII字符串还要对其编码; Session可以存储任何类型的数据,可以把Session看成是一个容器 cookie数据存放在客户的浏览器上,session数据放在服务器上; 单个cookie在客户端的限制是4K,就是说一个站点在客户端存放的COOKIE不能超过4K(不同浏览器不同);
从隐私安全上比较
Cookie存储在浏览器中,对客户端是可见的。信息容易泄露出去。如果使用Cookie,最好将Cookie加密 ,Session存储在服务器上,对客户端是透明的。不存在敏感信息泄露问题。
从有效期上比较
Cookie保存在硬盘中,只需要设置maxAge属性为比较大的正整数,即使关闭浏览器,Cookie还是存在的 Session的保存在服务器中,设置maxInactiveInterval属性值来确定Session的有效期。并且Session依赖于名为JSESSIONID的Cookie,该Cookie默认的maxAge属性为-1。如果关闭了浏览器,该Session虽然没有从服务器中消亡,但也就失效了。
从对服务器的负担比较
Session是保存在服务器的,每个用户都会产生一个Session,如果是并发访问的用户非常多,是不能使用Session的,Session会消耗大量的内存。 Cookie是保存在客户端的。不占用服务器的资源。像baidu这样的大型网站,一般都是使用Cookie来进行会话跟踪。

83,jsp九大内置对象四大作用域

• request:一次请求
o HttpServletRequest
• session:一次会话
o HttpSession
• application:整个应用
o ServletContext
• pageContext:当前页面
o PageContext
• response:保存请求页面响应信息
o HttpServletResponse
• config:保存当前servlet对应的配置文件
o ServletConfig
• page:代码当前的jsp对应的servlet对象
o this
• out:可以直接在页面输出内容,内容会直接答应在页面中
o PrintWriter
• exception:用于存储当前页面异常信息,当页面发送异常时将异常信息存储至当前对象
o Throwable
九大内置对象分别代码对应数据的存储,其中最常用的四大作用域pageContext.request.session.application

84,什么是设计模式?设计模式的分类?常用的设计模式有哪些?

(1)设计模式本身是一种思想,用于解决某些简单常用需求的固定思路或代码,称之为设计模式
总体来说设计模式分为三大类:
(2)创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
(3)工厂模式、单例模式、代理模式、观察者模式、装饰模式、策略模式

85,TCP与UDP的区别

TCP是面向连接的;UDP是无连接的
TCP是可靠的;UDP是不可靠的
TCP是面向字节流的;UDP是面向数据报文的
TCP只支持点对点通信;UDP支持一对一,一对多,多对多的交互通信
TCP有拥塞控制机制,而UDP没有

86,三层架构与mvc的区别

MVC和三层架构的区别:
M 即Model(模型层),主要负责处理业务逻辑以及数据库的交互
V 即View(视图层),主要负责显示数据和提交数据
C 即Controller(控制层),主要是用作辅助捕获请求并控制请求转发
三层
UI界面层
BLL业务逻辑层
DAL数据访问层
三层是基于业务逻辑来分的,而mvc是基于页面来分的
MVC模式是一种复合设计模式,一种解决方案
三层是一种软件架构,通过接口实现编程
三层模式是体系结构模式,MVC是设计模式
三层模式又可归于部署模式,MVC可归于表示模式

87,mysql与oracle的区别

1、mysql与oracle都是关系型数据库,应用于各种平台。
mysql开源免费的,而oracle则是收费的,并且价格非常高。
2、管理工具上
mysql的管理工具较少,在Linux下的管理工具的安装有时需要安装额外的包(phpmyadmin,etc),有一定复杂性。
oracle有多重成熟命令行、图形界面、web管理工具,还有很多第三方的管理工具,管理极其方便高效。oracle支持大并发,大访问量,是OLTP最好的工具。
3、数据库的层次结构上
mysql:默认用户是root,用户下可以创建好多数据库,每个数据库下还有好多表,一般情况下都是使用默认用户,不会创建多个用户;
oracle:创建一个数据库,数据库下有好多用户:sys、system、scott等,不同用户下有好多表,一般情况下只创建一个数据库用。
4、数据库中表字段类型:
mysql:int、float、double等数值型,varchar、char字符型,date、datetime、time、year、timestamp等日期型。
oracle:number(数值型),varchar2、varchar、char(字符型),date(日期型)等…
5、主键
mysql一般使用自动增长类型,在创建表时只要指定表的主键auto increment,插入记录时,不需要再指定该记录的主键值,mysql将自动增长。
oracle没有自动增长类型,主键一般使用的序列,插入记录时将序列号的下一个值赋给该字段即可,只是ORM框架是只要是native主键生成策略即可。
6、单引号处理
mysql里可以用双引号包起字符串,oracle只可以用单引号包起字符串。
7、查询方式
mysql是直接在SQL语句中使用limit就可以实现分页
oracle则是需要用到伪劣ROWNUM和嵌套查询
8、对事务提交
mysql默认是自动提交,可以修改为手动提交
oracle默认不自动提交,需要手动提交,需要在写commit指令或点击commit按钮。
9、对事务的支持
mysql在innodb存储引擎的夯机所的情况下才支持事务
oracle则完全支持事务。
10、事务隔离级别:
oracle是read commited的隔离级别
而mysql是repeatable read的隔离级别
同时二者都支持serializable串行化事务隔离级别,可以实现最高级别的读一致性。每个session提交后其它session才能看到提交的更改;
11、并发性:
mysql以表级锁为主,对资源锁定的粒度很大,如果一个session对一个表加锁时间过长,会让其他session无法更新此表中的数据。
oracle使用行级锁,对资源锁定的粒度要小很多,只是锁定sql需要的资源,并且加锁是在数据库中的数据行上,不依赖于索引,所以oracle对并发性的支持要好很多。
12、逻辑备份
mysql逻辑备份时要锁定数据,才能保证备份的数据是一致的,影响业务正常的dml使用
oracle逻辑备份时不锁定数据,且备份的数据是一致的。
13、复制
mysql:复制服务器配置很简单,但主库出问题时,从库可能丢失一定的数据,且需要手工切换从库到主库;
oracle:既有堆或拉式的传统数据复制,也有dataguard的双机或多机容灾机制,主库出问题时,可以自动切换备库到主库,但配置管理较复杂。
14、性能诊断
mysql的诊断调优方法较少,主要有慢查询日志;
oracle有各种成熟的性能诊断调优工具,能实现很多自动分析、诊断功能。比如awr、addm、sqltrace、tkproof等。
15、日期转换
mysql中日期转换用dateformat()函数;
oracle用to_date()与to_char()两个函数。

88,maven的作用

Maven 的作用有3个:
(1)项目搭建;
项目构建是:编译、测试、成文(生成文档)、打包、部署等,或者是:除了编写源码之外其他工作。
(2)依赖管理;
Maven提供了中央仓库,能帮助我们自动下载构件( artifact)。
(3)项目信息管理
Maven能帮助我们管理原本分散在项目中各个角落的项目信息,包括项目描述、开发者列表、版本控制系统地址、许可证、缺陷管理系统地址等。

89,#{}与${}区别

都是对指定的参数进行获取填入,#{}使用的是占位符的形式进行填值 可以有效解决sql注入。${} 使用的是字符串拼接形式 需要注意sql语句的书写规则 不能防止sql注入

90,mybatis有没有二级缓存?怎么开启二级缓存?二级缓存使用注意事项?

MyBatis 具有二级缓存,可以减少数据库操作次数,提高系统性能。但要注意使用时的一些问题:
默认情况下,二级缓存是关闭的,需要手动开启。
二级缓存是全局的缓存,不能仅限制在某个作用域内,如同一个session。
二级缓存存储的是对象的副本,这些副本存储在 JVM 堆内存中,占用一定的空间。
对缓存中的数据进行修改时,需要注意同步缓存和数据库中的数据,避免脏数据和不一致。
对于一些表经常进行更新、插入、删除操作的应用,不宜开启二级缓存,因为缓存数据的更新会耗费较大的系统资源。
开启二级缓存的方式:
(1)在 XML 中配置:在 mapper.xml 文件中加入 标签即可开启。
(2)在 Java 代码中通过 Configuration 对象进行设置:configuration.setCacheEnabled(true)。
(3)通过注解方式:在 Mapper 接口上增加 @CacheNamespace 注解,并设置相应参数。
注意:在多线程环境下使用二级缓存,需要设置 appropriate 多线程加锁策略,避免数据不一致的情况产生。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值