Java基础
1.JAVA中有哪些基本类型
类型名称 | 字节空间 | 取值范围 | |
整数型 | byte | 1 | -2的7次方到2的7次方-1 |
short | 2 | -2的15次方到2的15次方-1 | |
int | 4 | -2的31次方到2的31次方-1 | |
long | 8 | -2的63次方到2的63次方-1 | |
浮点型 | float | 4 | 单精度,对小数部分的精度要求不高 |
double | 8 | 双精度,精确的小数部分并操作值很大时 | |
字符 | char | 2 | 0-65535 |
布尔 | boolean | 1 | 真ture,假false |
因为Java程序编译之后的代码不是能被硬件系统直接运行的代码,而是一种“中间码”—字节码。然后不同的硬件平台上安装不同的java虚拟机(jvm),由JVM来把字节码再翻译成对应硬件平台能够执行的代码,对于JAVA编程者来说,不需要考虑硬件平台是什么。
3.String是基本数据类型吗?我可不可以写个类继承于String?
不是基本数据类型,String是引用类型;String是final的类,是不可以被继承的。
&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式结果都为true时,结果为true,否则,只要有一方为false,则结果为false。
&&还具有短路的功能,如果第一个表达式为false,则不再计算第二个表达式
&还可以当作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作。
5.Switch语句里面的条件可不可以是byte、long、String?使用时候还应注意什么?
switch里面的条件必须是能隐式的转化为int的,故long和string不行(JDK7以前是不行的,JDK8之后可以;不能使用long的根本原因是长时间转换为int将失去精度,导致数据不准确),byte可以,使用Switch时候还应注意它的穿透,即每个case后要跟break
6.short s1=1;s1 = s1 +1有什么错? short s1 = 1;s1+=1有什么错?
对于short s1 = 1;s1 = s1 +1;由于S1 +1运算时自动提升表达式类型,所以结果为int类型,再赋值给short类型S1时,编译器将报告需要强制转换类型的错误。
对于short s1 = 1;s1 += 1;由于+=是JAVA语言规定的运算符,JAVA编译器会对它进行特殊处理,因此可以正确编译。
char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了全世界所有的字体
8.final修饰变量时,该变量是对象时,对象的值可以不可改变?
静态变量也称为类变量,归全类共有,它不依赖于某个对象,可以通过类名直接访问;而实例变量必须依存于某一实例,只能通过对象才能访问到它。
1、抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面,抽象并不打算了解全部问题,而是只选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。
3、封装private:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面,面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
11.作用域public、private、protected,以及不写时的区别?
作用域 | 当前类 | 同包 | 子孙类 | 其他 |
public | √ | √ | √ | √ |
protected | √ | √ | √ | |
default | √ | √ | ||
private | √ | |||
不写是默认default |
(Overload)重载:发生在同一个类之中,方法名相同,参数列表不同,与返回值无关,与final无关,与修饰符无关,与异常无关。
(Override)重写:发生在子类和父类之间,方法名相同,参数列表相同,返回值相同,不能是final的方法、重写的方法不能有比父类方法更为严格的修饰符权限,重写的方法所抛出的异常不能比父类的更大;如果父类私有的方法,子类拥有方法签名相同的方法,子类不属于重写父类的方法,该方法数据子类的新方法。
java中没有多继承,但是可以多实现,即一个类实现多个接口。
虽然没有多继承,但是Java中接口可以近似的实现多继承,那就是接口;接口和接口之间可以进行多继承。
c.抽象类中可以有普通成员变量和常量,接口中只能有常量,而且只能是public static final 不写默认。
d.抽象类中可以有抽象方法,也可以由普通的方法,接口中只能有抽象的方法而且修饰符只能是public abstract 不写默认。
e.抽象类中可以有final的方法,接口中不能有final的方法。
f.抽象类只能是单继承,多实现,接口是可以多继承其他接口,但是不能实现接口,和不能继承其他类。
int是java的基本数据类型,integer是1.4版本后提供的基本类型包装类,当两者作为成员变量时,初始值分别为:int是0,integer是null;其中Integer提供了一些对整数操作的方法,还定义了integer型数值的最值,其他基本类型也有对应的包装类,基本类型包装类的出现,使得java完全面向对象
18.String s = new String("xyz");创建了几个String Object?
19.数组中有没有length()方法,string中有没有length()方法
数组中没有length()方法,但是有length属性,string中有length()方法
20.try{}里有一个return语句,那么紧跟在这个try后的finall{}里的code会不会被执行,什么时候被执行,在return前还是后?
会先执行try里面的,return会执行但是没有真正的return,此时会去执行finally里面的,然后再返回来执行return。
b.finally中有return的时候(不符合编程规范,会报黄线警告):
会先执行try里面的,return会执行但没有正真的return,此时去执行finally里面的,然后执行finally里面的return,直接返回。
final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可覆盖
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的方法,可以覆盖此方法提供垃圾收集的其他资源回收,例如关闭文件。JVM不保证此方法总被调用。
‘==’比较的是两个变量的内容在内存中的地址是是否全都相等,如果要比较两个、基本数据类型那必须要用'=='
equals如果没有重写,则和‘==’的意义一样,如果重写了,则会按照重写的方法进行比较,JavaBean规定当重写equals时候必须重写hashCode,如果不重写会出现对象相同但hashCode不同,这样会出现问题。
eg:HashSet存储原色时候是按hashCode,如果重写equals不重写HashCode会导致同一个对象,存贮了两次。
error表示恢复不是不可能但是很困难的情况下的一种严重问题,例如程序书写错误,虚拟机错误等等。
exception是一种设计和实现问题,如果程序运行正常,从不会发生的情况,error是可以避免的,exception是不可以避免的。
----------------------------------------------------------------------------------------------------------------------
一个程序中可以有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每个线程上都关联有要执行的代码,即可以有多段程序代码同时运行,每个程序至少都有一个线程,即main方法执行的那个线程。如果只是一个cpu,它怎么能够同时执行多段程序呢?这是从宏观上来看的,cpu一会执行A线索,一会执行B线索,切换时间很快,给人的感觉是a,b同时在执行,好比大家在一个办公室上网,只有一条链接到外部的网线,其实这条网线一会为a穿数据,一会为b传数据,由于切换的时间很短暂,所以,大家感觉都在同时上网。
状态:就绪,运行,synchronize阻塞,wait和sleep挂起,结束。wait必须在synchronized内部调用。
调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转化为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当syncahronized获得锁后,由阻塞转为运行,在这种情况可以调用wait方法转为挂起状态,当线程关联的代码执行完后。线程变为结束。
a.List和Set是Collection的子接口,map不是
b.List的底层是数组的方式实现,Set是散列表的方式实现,map是键值对的方式
c.List是有序可重复的,Set是无须不可重复的,map是有序的,key不重复,Value可重复、
d.List和Set可直接使用itertator来进行遍历,map只能通过先遍历Key在遍历Value。
Collection是集合类的上级接口,继承与他的接口主要有Set和List
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种几个的搜索、排序、线程安全化等操作。
27.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?使用==还是equals()?他们有何区别?
Set里的元素是不能重复的,元素重复与否是否使用equals()方法进行判断的、
equals()和==方法决定引用的值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相匹配的话,返回值真。
通俗的说,就是可以将内存中Java对象可以写在硬盘上(序列化到硬盘上),反序列化就是将硬盘的内容读取到内存中去;java是通过实现serializable接口,实现的序列化,serializable接口里面没有任何的方法,只是个标示接口。
java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。
堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所有,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。
GC是垃圾回收的异地,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动检测随想是否超过作用域从而达到自动回收内存的目的,java语言没有提供释放已分配内存的显示操作方法。
内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,并且依附于外部类而存在的。
内部类可为静态的,可用peotected和private修饰(而外部类只能使用public和缺省的包访问权限)
内部类主要有以下几类:成员内部类,局部内部类,静态内部类,匿名内部类。
33.Java中有几种类型的流,JDK为每种类型的流提供了一些抽象类以提供继承,请说出他们分别是哪些类?
字节流、字符流。字节流继承于InputStream OutputSteam,字符流继承与InputStreamReader OutputStreamWriter。在java.io保重还有许多其他的流,主要是为了提高性能和使用方便。
a.字节流操作的基本单元为字节;字符流操作的基本单元为Unicode码元。
c.字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。
d.底层设备永远只接受字节数据,有时候要写字符串到底层设备,需要将字符串转成字节再进行写入。字符流是字节流的包装,字符流则是直接接受字符串,它内部将串转成字节,再写入底层设备,这为我们向IO设别写入或读取字符串提供了一点点方便。
a)静态属性:也可以叫类变量,需要使用类名.属性名来访问,共有的类变量域对象无关,只和类有关。
注意:类中的实例变量是在创建对象时被初始化的,被static修饰的属性,也就是类变量,实在类加载时被创建并进行初始化,类加载的过程只进行一次,也就是类变量只会被创建一次。
注意:static修饰的方法,不能直接访问本类中的非静态(static)成员(包括方法和属性),本类的非静态方法可以访问本类的静态成员(包括方法和属性),可以调用静态方法。
修饰变量:被final修饰的成员变量就是常量(常量名通常大写),一旦赋值不能改变
封装性:类的封装性为类的成员提供公有、缺省、保护和私有等访问权限,目的是隐藏类中的私有变量和类中方法的实现细节。
继承性:允许通过继承原有类的某些特性或全部特性而产生全新的类,原有的累称为父类,产生的新类称为子类。子类不仅可以直接继承父类的共性,而且也可以创建它特有的个性。
多态性:是指在基类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同行为,多态性有两种表现形式:重载和覆盖。
37.Error和Exception有什么区别? 列出你见过的Exception并简要说明
error表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情况下的一种严重问题;比如内存溢出,不可能指望程序能处理这样的情况;
exception表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题;也就是说,它表示如果程序运行正常,从不会发生的情况。
NullPointerException:当操作一个空引用时会出现此错误。
NumberFormatException:数据格式转换出现问题时出现此异常。
ClassCastException:强制类型转换类型不匹配时出现此异常。
ArrayIndexOutOfBoundsException:数组下标越界,当使用一个不存在的数组下标时出现此异常。
内存泄露是指系统中存在无法回收的内存,有时候会造成内存不足或系统崩溃。Java存在内存泄露。
Java中的内存泄露当然是指:存在无用但是垃圾回收器无法回收的对象。而且即使有内存泄露问题存在,也不一定会表现出来。
39.多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?
多线程有两种实现方法:继承Thread类或者实现Runnable接口。实现同步也有两种方法:一种是同步方法,另一种是同步代码块。同步方法是在方法返回类型前面加上synchronized关键字
同步代码块是synchronized (这里写需要同步的对象){...}
----------------------------------------------------------------------------------------------------------------------
我们知道Java是一个面相对象的编程语言,基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装类型(如我们在使用集合类型Collection时就一定要使用包装类型而非基本类型),它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。
另外,当需要往ArrayList,HashMap中放东西时,像int,double这种基本类型是放不进去的,因为容器都是装object的,这是就需要这些基本类型的包装器类了。
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。
equals 方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。
区别:HashMap只有key和value值对应的。set是可以自动清楚相同的元素
list是其对象以线性方式存储,没有特定顺序,只有一个开头和一个结尾,当然,它与根本没有顺序的集是不同的。
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据。
List和Set继承了Collection接口,而map不是;
46.Collection 和 Collections的区别?
Collection是java.util下的接口,它是各种集合的父接口,继承于它的接口主要有Set 和List;Collections是个java.util下的类,是针对集合的帮助类,提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
47.String、StringBuffer和StringBuilder的区别?
1.首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String
2.再来说线程安全,在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
第一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法,然后在run方法里填写相应的逻辑代码。
第二种方法是实现Runnable接口,并编写run方法,相比继承Thread类创建线程的好处是以实现接口的方式创建线程可以对类进行更好的扩展,该类可以继承其他类来扩展自身需求,相比第一种方式更加灵活,扩展性强。
实现Callable接口创建线程与Runnable接口的不同之处在于:如果你想要在线程执行完毕之后得到带有返回值的线程则实现Callable接口
静态变量也叫类变量,这种变量前加了static修饰符。可以直接用类名调用,也可以用对象调用,而且所有对象的同一个类变量 都是共享同一块内存空间。
实例变量也叫对象变量,这种变量没有加static修饰符。只能通过对象调用, 而且所有对象的同一个实例变量是共享不同的内存空间的。
静态变量是所有对象共有的,某一个对象将它的值改变了,其他对象再去获取它的值,得到的是改变后的值;
实例变量则是每一个对象私有的,某一个对象将它的值改变了,不影响其他对象取值的结果,其他对象仍会得到实例变量一开始就被赋予的值。
51.try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
会执行try{}中的return执行后在没有返回数据时先去执行finally{}中的代码,然后再返回。所以说finally{}在return中间执行
52.同步和异步有何异同,在什么情况下分别使用他们?举例说明。
如果数据将在线程间共享.例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取.
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率.
53.java 中有几种类型的流?JDK 为每种类型的流提供了一些抽象类以供继承, 请说出他们分别是哪些类?
Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包括输入和输出两种所以一共四个):InputStream,OutputStream,Reader,Writer。Java中其他多种多样变化的流均是由它们派生出来的.
54.构造器Constructor是否可被override?
构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload。
Constructor不能被继承,所以Constructor也就不能被override。每一个类必须有自己的构造函数,负责构造自己这部分的构造。子类不会覆盖父类的构造函数,相反必须负责在一开始调用父类的构造函数。
1、分配对象空间,并将对象中成员初始化为0或者空,java不允许用户操纵一个不定值的对象。
1、super()主要是对父类构造函数的调用,this()是对重载构造函数的调用
2、super()主要是在继承了父类的子类的构造函数中使用,是在不同类中的使用;this()主要是在同一类的不同构造函数中的使用
1、super()和this()都必须在构造函数的第一行进行调用,否则就是错误的
GC是垃圾回收的异地,内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动检测随想是否超过作用域从而达到自动回收内存的目的,java语言没有提供释放已分配内存的显示操作方法。
58.接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类?
接口可以继承接口。抽象类可以实现(implements)接口,抽象类可继承实体类,但前提是实体类必须有明确的构造函数.
如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员.
----------------------------------------------------------------------------------------------------------------------
61.在Java中,如何跳出当前的多重嵌套循环?
在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环。
62.内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制?
一个内部类对象可以访问创建它的外部类对象的成员,包括私有成员。
63.Java 中的final关键字有哪些用法?
修饰类:表示该类不能被继承;(2)修饰方法:表示方法不能被重写;(3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。
64.写出常见的5个RuntimeException
(1)java.lang.NullPointerException空指针异常,出现原因:调用了未经初始化的对性爱那个或者不存在的对象。
(2)ClassNoFoundException 指定类找不到,出现原因:类的名称和路径加载错误,通常是试图通过字符串来加载某个类时可能引发异常。 (3)NumberFormatException字符串转换为数字异常,出现原因:字符串数据中包含非数字型字符。
(4)IndexOutOfBoundsException数组下标越界异常
(5)IllegalArgumentException 方法传递参数错误
(6)ClassCastException数据类型转换异常
(7)NoClassDefFoundExcetion 未找到类定义错误
(8)SQLException SQL异常
(9)InstantiationException实例化异常
(10)NoSuchMethodExceptioin 方法不存在异常
65.阐述final、finally、finalize的区别。
final:修饰符(关键字)有三种用法:如果一个类被声明为final,意味着它不能再派生出新的子类,即不能被继承,因此它和abstract是反义词。将变量声明为final,可以保证它们在使用中不被改变,被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取不可修改。被声明为final的方法也同样只能使用,不能在子类中被重写。
finally:通常放在try…catch…的后面构造总是执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要JVM不关闭都能执行,可以将释放外部资源的代码写在finally块中。
finalize:Object类中定义的方法,Java中允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写finalize()方法可以整理系统资源或者执行其他清理工作。
66.List、Map、Set三个接口存取元素时,各有什么特点?
List以特定索引来存取元素,可以有重复元素。Set不能存放重复元素(用对象的equals()方法来区分元素是否重复)。Map保存键值对(key-value pair)映射,映射关系可以是一对一或多对一。Set和Map容器都有基于哈希存储和排序树的两种实现版本,基于哈希存储的版本理论存取时间复杂度为O(1),而基于排序树版本的实现在插入或删除元素时会按照元素或元素的键(key)构成排序树从而达到排序和去重的效果。
67.当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法B?
不能。其它线程只能访问该对象的非同步方法,同步方法则不能进入。因为非静态方法上的synchronized修饰符要求执行方法时要获得对象的锁,如果已经进入A方法说明对象锁已经被取走,那么试图进入B方法的线程就只能在等锁池(注意不是等待池哦)中等待对象的锁。
68.请说出与线程同步以及线程调度相关的方法。
- wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;
- sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常;
- notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关;
- notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态;
69.Java中如何实现序列化,有什么意义?
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题(如果不进行序列化可能会存在数据乱序的问题)。
要实现序列化,需要让一个类实现Serializable接口,该接口是一个标识性接口,标注该类对象是可被序列化的,然后使用一个输出流来构造一个对象输出流并通过writeObject(Object)方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立对象输入流,然后通过readObject方法从流中读取对象。序列化除了能够实现对象的持久化之外,还能够用于对象的深度克隆.
70.如何通过反射创建对象?
方法1:通过类对象调用newInstance()方法,例如:String.class.newInstance()
方法2:通过类对象的getConstructor()或getDeclaredConstructor()方法获得构造器(Constructor)对象并调用其newInstance()方法创建对象,例如:String.class.getConstructor(String.class).newInstance(“Hello”);
71.Static 关键字有哪些作用?
Static 有两种作用:第一, 为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。第二, 实现某个方法或属性与类而不是对象关联在一起。
72.什么是不可变类?
不可变类是指当创建了这个类的实例后,就不允许修改它的值了,也就是说,一个对象一旦被 创建出来,在其整个生命周期中,它的成员变量就不能被修改了。
73.强制类型转换的注意事项有哪些?
Java在涉及 byte、short 和 char 类型的运算时,首先会把这些类型的变量值强制转换为 int 类型, 然后对 int 类型的值进行计算,最后得到的值也是 int 类型。因此,如果把两个 short 类型的值相 加,最后得到的结果是 int 型;如果把两个 byte 类型的值相加,最后也会得到一个 int 类型的值。 如果需要得到 short 类型的结果,就必须显示地把运算结果转换为 short 类型。
74.++i与 i++的区别?
++i 先运算后赋值,i++先赋值后运算。
SSM框架
1.何为Spring Bean容器?Spring Bean容器与Spring IOC 容器有什么不同吗?
用于创建bean对象,管理bean对象的那个容器Spring IOC 容器本质上指的的就是Spring Bean容器,
Spring Bean容器中最核心一个机制是IOC机制(控制反转),所以有时候又将springbean容器称之为Spring IOC 容器.
IOC 是Spring中提供一种控制反转机制,目的是将我们项目中对象的依赖管理交给Spring实现,这样可以更好实现对象关系的解耦,提高程序的可扩展性.
DI 是Spring中的依赖注入机制,IOC的实现需要借助这种机制.我们通常会这样理解,Spring Bean容器中的IOC思想一种目标,DI是实现这种思想的目标的手段.
4.Spring 工厂底层构建Bean对象借助什么机制?当对象不使用了要释放资源,目的是什么?何为内存泄漏?
借助反射机制,防止内存泄漏,对象已经不使用了但占用着内存,这种现 象称之为内存泄漏,内存泄漏不是内存溢出,但是它是内存溢出的一个导火索. 内存溢出直接就导致系统崩溃了.
1、客户端发出一个http请求给web服务器,web服务器对http请求进行解析,如果匹配前端控制器(或分发器/DispatcherServlet)的请求映射路径,web容器将请求转交给DispatcherServlet.
2、DipatcherServlet接收到这个请求之后将根据请求的信息以及处理器映射器(HandlerMapping)的配置找到处理请求的处理器(Handler)。
3、由具体的处理器适配器(HandlerAdapter)对Handler进行具体的调用。
4、Handler对数据处理完成以后将返回一个ModelAndView()对象给 DispatcherServlet。
5、DispatcherSevlet通过视图解析器(ViewResolver)将ModelAndView()转化为真正的视图View。
6、Dispatcher通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端。
有时候,固定的sql语句不能够满足我们的应用需求。这个时候需要在 标准的基础上建立动态的查询语句。
比如说在开发的时候,遇到这样的场景,界面提供了多种查询,但是都是非 必填写,在选择查询条件时可以选中任意几种组合作为查询条件,如果在使用jdbc的时候,需要判断参数为空,自己组装sql,但是mybatis提供动态sql机制,依靠标签。
7.BeanFactory和ApplicationContext有什么区别?
BeanFactory 可以理解为含有bean集合的工厂类。BeanFactory 包含了种bean的定义,以便在接收到客户端请求时将对应的bean实例化。
BeanFactory还能在实例化对象的时生成协作类之间的关系。此举将bean自身与bean客户端的配置中解放出来。BeanFactory还包含了bean生命周期的控制,调用客户端的初始化方法(initialization methods)和销毁方法(destruction methods)。
从表面上看,application context如同bean factory一样具有bean定义、bean关联关系的设置,根据请求分发bean的功能。但application context在此基础上还提供了其他的功能。
Spring对bean进行依赖注入;
此时bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中,直到该应用上下文被销毁;
控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。
Spring框架中使用到了大量的设计模式,下面列举了比较有代表性的:
单例模式—在spring配置文件中定义的bean默认为单例模式。
模板方法—用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
回调–Spring ResourceLoaderAware回调接口
11.Spring 如何保证 Controller 并发的安全?
Spring 多线程请求过来调用的Controller对象都是一个,而不是一个请求过来就创建一个Controller对象。
并发的安全? 原因就在于Controller对象是单例的,那么如果不小心在类中定义了类变量,那么这个类变量是被所有请求共享的,这可能会造成多个请求修改该变量的值,出现与预期结果不符合的异常
那有没有办法让Controller不以单例而以每次请求都重新创建的形式存在呢?
答案是当然可以,只需要在类上添加注解@Scope(“prototype”)即可,这样每次请求调用的类都是重新生成的(每次生成会影响效率)
虽然这样可以解决问题,但增加了时间成本,总让人不爽,还有其他方法么?答案是肯定的!
使用ThreadLocal来保存类变量,将类变量保存在线程的变量域中,让不同的请求隔离开来。
<map> 类型用于注入一组键值对,键和值都可以为任意类型。
<props>类型用于注入一组键值对,键和值都只能为String类型
它为不同的事务API(如JTA, JDBC, Hibernate, JPA, 和JDO)提供了统一的编程模型。
它为编程式事务管理提供了一个简单的API而非一系列复杂的事务API(如JTA).
(1)前端控制器 DispatcherServlet(不需要程序员开发)
作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。
(2)处理器映射器HandlerMapping(不需要程序员开发)
注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。
(5)视图解析器 ViewResolver(不需要程序员开发)
作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)
View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)
通过Jackson框架就可以把Java里面的对象直接转化成Js可以识别的Json对象。具体步骤如下 :
(3)在接受Ajax方法里面可以直接返回Object,List等,但方法前面要加上
2. Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
3. Mybatis在处理${}时,就是把${}替换成变量的值,相当于字符串拼接
SqlSession级别的缓存,实现在同一个会话中数据的共享
当有多个SqlSession或者分布式环境下,数据库写操作会引起脏数据。
SqlSessionFactory级别的缓存,实现不同会话中数据的共享,是一个全局变量
当开启缓存后,数据查询的执行的流程是:二级缓存>一级缓存>数据库
通过SqlSessionFactory创建SqlSession
19.JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?
数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。
对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。
在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。
将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
由于xml里面标签id必须唯一,导致DAO中方法不支持方法重载。所以dao层必须是接口
21.使用MyBatis的mapper接口调用时有哪些要求?
Mapper接口方法名和mapper.xml中定义的每个sql的id相同
Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
Mapper.xml文件中的namespace即是mapper接口的类路径
2. SpringMVC是Spring的一个模块,是Spring的子容器,子容器可以拿父容器的东西,但是父容器不能拿子容器的东西
3. SpringMVC的前端控制器DispatcherServlet,用于分发请求,使开发变得简单
4. SpringMVC流程(重点). SpringMVC三大组件
根据handler(controlelr类)的开发方式(注解开发/其他开发) 方式的不同去寻找不同的处理器适配器
23.Mybatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?
1)Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。
2)Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind。
3)其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。
24.Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
第一种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系。
第二种是使用sql列的别名功能,将列别名书写为对象属性名,比如T_NAME AS NAME,对象属性名一般是name,小写,但是列名不区分大小写,Mybatis会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成T_NAME AS NaMe,Mybatis一样可以正常工作。
25.MyBatis里面的动态Sql是怎么设定的?用什么语法?
MyBatis里面的动态Sql一般是通过if节点来实现,通过OGNL语法来实现,但是如果要写的完整,必须配合where、trim节点,where节点是判断包含节点有内容就插入where,否则不插入,trim节点是用来判断如果动态语句是以and 或or开始,那么会自动把这个and或者or取掉 。
事务就是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么一起成功,如果中间有一条出现异常,那么回滚之前的所有操作。这样可以防止出现脏数据,防止数据库数据出现问题。
开发中为了避免这种情况一般都会进行事务管理。Spring中也有自己的事务管理机制,一般是使用TransactionMananger进行管 理,可以通过Spring的注入来完成此功能。
编程式事务管理:这意味着你可以通过编程的方式管理事务,这种方式带来了很大的灵活性,但很难维护。
声明式事务管理:这种方式意味着你可以将事务管理和业务代码分离。你只需要通过注解或者XML配置管理事务。
1. Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。
2. Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。
28.怎么样把数据放入Session里面
可以声明一个request,或者session先拿到session,然后就可以放入数据,或者可以在类上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key
系统启动的时候根据配置文件创建spring的容器, 首先是发送http请求到核心控制器DispatcherServlet,spring容器通过映射器去寻找业务控制器, 使用适配器找到相应的业务类,在进业务类时进行数据封装,在封装前可能会涉及到类型转换,执行完业务类后使用ModelAndView进行视图转发, 数据放在model中,用map传递数据进行页面显示。
30.Bean 工厂和 Application contexts 有什么区别?
Application contexts提供一种方法处理文本消息,一个通常的做法是加载文件资源(比如镜像),它们可以向注册为监听器的bean发布事件。另外,在容器或容器内的对象上执行的那些不得不由bean工厂以程序化方式处理的操作,可以在Application contexts中以声明的方式处理。Application contexts实现了MessageSource接口,该接口的实现以可插拔的方式提供获取本地化消息的方法。
singleton : bean在每个Spring ioc 容器中只有一个实例。
request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
缺省的Spring bean 的作用域是Singleton。
Spring 容器能够自动装配相互合作的bean,这意味着容器不需要<constructor-arg>和<property>配置,能通过Bean工厂自动处理bean之间的协作。
33.什么是基于Java的Spring注解配置? 给一些注解的例子。
基于Java的配置,允许你在少量的Java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。
以@Configuration 注解为例,它用来标记类可以当做一个bean的定义,被Spring IOC容器使用。另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。
控制反转 Hibernate Template和 Callback。
继承 HibernateDAOSupport提供一个AOP 拦截器。
它为不同的事务API 如 JTA,JDBC,Hibernate,JPA 和JDO,提供一个不变的编程模式。
它为编程式事务管理提供了一套简单的API而不是一些复杂的事务API如
36.在Spring AOP 中,关注点和横切关注的区别是什么?
关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。
横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。
AOP:面向切面编程:将一个系统中共同的业务逻辑提取出来,进行单独的封装成一个组件(切面),然后以配置的方式作用于系统中,实现程序的可插拔性,提高代码的复用性,提升系统的灵活性和性能
38.Spring中AutoWired和,Resource之间区别是什么
AutoWried:按照类型进行匹配—spring框架自带的,查看当前Spring容器中那个bean类型和引用类型一致,就进行注入,如果有多个匹配类型就会报错.
Resource:默认按照名称进行注入,如果找不到对应的名称按照bean类型进行注入
web服务器
1.描述Servlet调用过程?
(1)在浏览器输入地址,浏览器先去查找hosts文件,将主机名翻译为ip地址,如果找不到就再去查询dns服务器将主机名翻译成ip地址。
(2)浏览器根据ip地址和端口号访问服务器,组织http请求信息发送给服务器。
(3)服务器收到请求后首先根据Host请求头判断当前访问的是哪台虚拟主机。
(4)服务器根据http请求头中的请求URI判断当前访问的是哪个web应用。
(5)服务器根据http请求头中的请求URI判断当前访问的是web应用中的哪个web资源。
(6)检查web应用的web.xml文件,如果根据路径找到具体的servlet处理类的全路径名交给该servlet处理,如果找不到就交给缺省servlet处理。
(7)这个过程中浏览器只知道自己发出来http请求,不久就收到了http响应,浏览器不知道也不关心服务器内部是如何处理的。浏览器和服务器之间的关系是非常单纯的,只有HTTP协议。
(8)解析请求、封装RequestResponse对象、创建Servlet、调用Service方法都是服务器自动进行的,开发人员只需要写好Servlet配置进容器中即可,无需操心具体的底层实现。
(1)Servlet第一次被访问到时创建对象,创建出来后立即执行init方法执行初始化的操作。
(2)从此以后该对象一直驻留在内存中为后续的对这个Servlet的请求进行服务。
(3)直到服务器关闭或web应用移除出容器时,随着web应用的销毁Servlet对象销毁掉,在销毁之前调用destory方法执行善后工作。
(4)在存活期间,每次对Servlet 的调用都会导致Service方法的执行。
HTTP协议就是一套基于tcp/ip协议的应用层协议 。简单来说,就是一个基于应用层的通信规范,双方要进行通信,大家都要遵守一个规范,这个规范就是HTTP协议。它规定了客户端(通常是浏览器)和服务器之间的通信方式。
首先客户端发送一个请求(request)给服务器,服务器在接收到这个请求后将生成一个响应(response)返回给客户端。
1.它是一个无状态的协议,服务器端在处理相应请求后不会保留任何客户端的信息,每次请求都是独立的
2.客户端与服务器端的每一次数据交互,都要经过一次请求/响应的过程。
4.一个典型的HTTP请求分为 一个请求行 若干请求头 一个空行实体内容。
1.get请求用来从服务器上获得资源,而post是用来向服务器提交数据;
2.get将表单中数据按照name=value的形式,添加到action 所指向的URL 后面,并且两者使用?连接,而各个变量之间使用&连接;post是将表单中的数据放在HTTP协议的请求头或消息体中,传递到action所指向URL;
3.get传输的数据要受到URL长度限制(1024字节);而post可以传输大量的数据, POST数据是没有限制的,上传文件通常要使用post方式;
4.使用get时参数会显示在地址栏上,如果这些数据不是敏感数据,那么可以使用get;对于敏感数据还是应用使用post;
5.get使用MIME类型application/x-www-form-urlencoded的URL编码(也叫百分号编码)文本的格式传递参数,保证被传送的参数由遵循规范的文本组成,例如一个空格的编码是%20。
6.Jsp页面中的FORM标签里的method属性为get时调用doGet(),为post时调用doPost()。
浏览器用什么码表来打开表单页面就用什么编码来发送数据。当前我们的注册页面指定了用utf-8来打开。
这就决定了浏览器是用utf-8打开的页面,浏览器在提交表单时是用utf-8编码的。
而tomcat默认情况下会使用iso8859-1来进行解码。
我们知道全世界的码表都兼容iso8859-1,所以英文处理是没有问题的。
但是iso8859-1中并没有中文,iso8859-1对于无法处理的字节都使用?替代,所以我们看到的都是?。
由于客户端发送时使用的是utf-8编码而服务器用iso8859-1解码造成了乱码,虽然字符已经乱掉了,但底层的字节仍然是正确的,我们只要将乱码字符getBytes(“iso8859-1”)转换为字节,就是正确的字节,再将这些字节new String(bytes,“utf-8”)按照正确的码表编码,就可以转换回正确的字符了。从而解决了乱码。
request对象的生命周期是针对一个客户端(一个浏览器应用程序)的一次请求,当请求完毕之后,request里边的内容也将被释放,一个请求开始时创建,请求结束后销毁。
通过response.setHeader(Content-Type, text/html;charset=utf-8)方法,通知服务器发送数据时的码表;通过response.setCharacterEncoding(utf-8)方法,通知浏览器解析时使用的码表。两码相同就不会有乱码了。
response提供了setContentType(text/html;charset=UTF-8)快捷方法,在它的底层,会同时做上面两件事,所以可以一行代码解决response产生的乱码问题。
ServletContext对象代表当前web应用。当服务器启动时,服务器在启动时会依次加载web应用,每一个web应用加载完成后都会创建一个ServletContext对象唯一代表该web应用,这个对象一直存活,直到web应用移除出容器或服务器关闭时,随着应用销毁,ServletContext对象跟着销毁。
转发是服务器内部资源跳转,重定向是通过302+Location实现浏览器跳转访问。
转发之前和转发之后request是一个,重定向之前和之后不是一个request。
当程序第一次调用到request.getSession()代码时,服务器明确的知道了需要用到session了,此时创建session。
如果session超过30分钟(可以在web.xml中配置的)没人使用,服务器认为这个session超时了,销毁session。
明确的调用session.invalidate(),session立即销毁。
服务器被非正常关闭或web应用被移除出容器,此时随着web应用的销毁session销毁.如果是正常关闭,session会被钝化.当下次服务器正常启动时,没有超时的session还会被活化回来。
session的原理:在服务器第一次调用request.getSession()方法的时候,会在内存中创建一个session对象,此对象具有一个独一无二的id值,此id值将会以cookie(JSESSIONID)的形式发送给浏览器,浏览器以后每次访问都会带着此cookie,服务器就利用此cookie区分浏览器找到对应的session空间。
cookie数据存放在客户的浏览器上,session数据放在服务器上
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE
其实这个问题在上面已经阐述过了,Servlet是一个特殊的Java程序,它运行于服务器的JVM中,能够依靠服务器的支持向浏览器提供显示内容。JSP本质上是Servlet的一种简易形式,JSP会被服务器处理成一个类似于Servlet的Java程序,可以简化页面内容的生成。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。有人说,Servlet就是在Java中写HTML,而JSP就是在HTML中写Java代码,当然这个说法是很片面且不够准确的。JSP侧重于视图,Servlet更侧重于控制逻辑。
1:request: 请求对象 在javax.servlet.ServletRequest 作用域为Request来自客服端的请求,如:FORM表单中填写的信息,常用的方法有getParameter,getParamterName 和getParamterValue通过表用获取请求对象中包含的参数值。
3:pageContext对象为页面的上下文对象,代表当请运行页面的一些属性。
4:session:对象代码服务器与客服端所建立的会话,比如在写购物,客服轨迹跟踪,session”是建立在cookie的基础之上的。常用方法有getId,getValues等。
5:application对象负责提供应用程序在服务端运行时的一些全局信息,方法有getMimeType等。
6:out:与response不同,通过out对象发送的内容是浏览器需要的显示内容,还可以直接想客服端编写一个有程序动态生成的HTML的文件。
7:page:page里的变量没法从index.jsp传递到test.jsp。只要页面跳转了,就不见了。
8: exception:他是一个列外的对象,当页面发生了列外,就会会创建该对象。
9:config:是在servlet初始化Servlet的时候,JSP引擎向他传递信息用的,此消息包括Servlet初始化时所需要的参数。
SQL注入:就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。
1.永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双-进行转换等。
2.永远不要使用动态拼装SQL,可以使用参数化的SQL或者直接使用存储过程进行数据查询存取。
3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
4.不要把机密信息明文存放,请加密或者hash掉密码和敏感的信息。
5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装,把异常信息存放在独立的表中。
(2)索引不是越多越好,每个表控制在6个索引以内。范围where条件的情况下,索引不起作用,比如where value<100
(3)大部分情况连接效率远大于子查询,但是有例外。当你对连接查询的效率都感到不能接受的时候可以试试用子查询,虽然大部分情况下你会更失望,但总有碰到惊喜的时候不是么...
(5)有时候可以1条大的SQL可以分成几个小SQL顺序执行,分了吧,速度会快很多。
(6)每隔一段时间用alter table table_name engine=innodb;优化表
(8)学会用explain 和 profile判断是什么原因使你的SQL慢
(11)因为where子句后面的条件是执行顺序是从右到左,所以尽量把能过滤掉大部分数据的条件放在最后
init为初始化方法,在Filter对象被创建出来时,Servlet容器会调用该方法对filter进行初始化。
destory为销毁的方法,在过滤器对象被销毁之前,服务器会调用这个方法执行善后工作。
doFilter为过滤器中最核心的方法,对访问的请求和响应进行拦截,当过滤器拦截到对资源的访问时,服务器会自动调用该方法执行过滤代码。 我们只需要在这个方法中设计过滤器的逻辑代码即可。
当服务器启动,web应用加载后,立即创建出这个web应用中的所有过滤器对象,创建出来后立即调用过滤器的init方法执行初始化操作.从此这些过滤器对象驻留在内存中为后续的拦截进行服务.每当拦截到资源时,都会导致dofilter方法执行.最终直到服务器关闭或web应用移除出容器时,随着web应用的销毁,过滤器对象销毁,销毁之前调用destory方法执行善后工作。
对于共享资源,有一个很著名的设计模式:资源池(resource pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。
HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
Servlet是一个供其他java程序调用的类,它不能独立运行,针对客户端的多次请求,通常状况下,Servlet只会创建一个Servlet实例对象,一旦创建它就会驻留在内存中,为后续的请求提供服务,直至退出web应用为止,也就是当我们关闭了浏览器之后我们的Servlet就终止了。当Servlet第一次访问的时候,就被加载到内存中,以后该实例对各个请求服务,没次情况会调用一次service方法。这样会出现什么问题:因为Servlet是单例的,所以会出现线程安全问题。
如果说str是null,那么内存根本没创建字符串对像,并由str引用。不能调用object的方法。
如果说str是空串,那么确实存在一个由str引用的字符串对像,只不过这个字符串的值是。长度为0;
if(null==str || .equals(str)){
如果我们在表单中填“”,接受到的字符串是“”,但是存入数据库后,查询出来的就是null;
Servlet本身是单实例的,这样当有多个用户同时访问某个Servlet时,会访问该唯一的Servlet实例中的成员变量,如果对成员变量进行写入操作,那就会导致Servlet的多线程问题,即数据不一致。
1.解决Servlet多线程同步问题的最好方式:去除实例变量,使用局部变量。不使用成员变量,而使用局部变量,因为局部变量在每个线程中都有各自的实例。
所以对Servlet来说,如果要对某个变量做写入操作,一定不要使用成员变量,而要使用局部变量。
3.Servlet实现 javax.serlvet.SingleThreadModel,Servlet2.4中已经废弃了该接口,此时Servlet容器将保证Servlet实例以单线程方式运行,也就是说,同一时刻,只会有一个线程执行Servlet的service()方法。
27.request.getParameter()和request.getAttribute()的区别?
a、request.getParameter()获取的类型是String;
request.getAttribute()获取的类型是Object
b、request.getPrameter()获取的是POST/GET传递的参数值和URL中的参数;
request.getAttribute()获取的是对象容器中的数据值/对象
c、request.setAttribute()和request.getAttribute()可以发送、接收对象;
request.getParamter()只能接收字符串,官方不开放request.setParamter()(也就是没有这个方法)
setAttribute()和getAttribute()的传参原理:
setAttribute()是应用服务器把这个对象放在该页面所对应的一块内存中去,当你的页面服务器重定向到另外一个页面时,
应用服务器会把这块内存拷贝到另一个页面所对应的那块内存中。这个就可以通过getAttribute()获取到相应的参数值或者对象。
28.JSP中动态include和静态include的区别?
a、静态include:语法:<%@ include file=文件名 %>,相当于复制,编辑时将对应的文件包含进来,当内容变化时,不会再一次对其编译,不易维护。
b、动态include:语法:<jsp:include page=文件名>,能够自动检查被包含文件,当客户端对JSP文件进行请求时,会重新将对应的文件包含进来,进行实时的更新。
基于java的web应用系统采用MVC设计模型,即用Model(模型)、View(视图)和Controller(控制)分离设计,这是目前web应用服务系统的主流设置方向。
View:负责页面显示,显示Model的处理结果给用户,主要实现数据到页面的转换过程。
Controller:负责每个请求的分发,把Form数据传递给Model进行处理,处理完成后,把处理结果返回给相应的View显示给用户。
30.EL表达式的功能,为什么要用EL表达式?(Expression Language)
a、在regist.jsp页面中生成一个为一个随机值,将其保存到session中,同时将其保存为表单的隐藏域的值。
b、在处理注册的请求时,获取session中的值,获取请求参数的值,比较两者是否相同,如果相同说明不是重复提交,请求通过同时删除session中保存的的值,如果不相同则是重复提交,不能通过。
给处于其中的应用程序组件(JSP、Servlet)提供一个环境,是JSP、Servlet直接跟容器中的变量交互,不必关注其他系统问题。
主要有web服务器来实现。例如:tomcat、weblogic、sphere、JBoss等。该容器提供的接口严格遵守J2EE规范中的web application标准。
Java中一共有23中设计模式:Factory(工厂模式)、Builder(建造模式)、Factory Method(工厂方法模式)、ProtoType(原始模型模式)、Singleton(单例模式)、Facade(门面模式)、Adapter(适配器模式)、Bridge(桥梁模式)、Composite(合成模式)、Decorator(装饰模式)、FlyWeight(享元模式)、Proxy(代理模式)、Command(命令模式)、Interpreter(解释器模式)、Visitor(访问者模式)、Iterator(迭代子模式)、Mediator(调停者模式)、Memento(备忘录模式)、Observer(观察者模式)、State(状态模式)、Strategy(策略模式)、Template Method(模板方法模式)、Chain Of Responsibility(责任链模式)、
工厂模式:工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以根据提供的数据生成一组类中某个类的实例,通常一组类中有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法。然后定义一个工厂类,工厂类可以根据条件生成不同的子类实例。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。
事务是作为一个逻辑单元执行的一系列操作,一个逻辑工作单元必须有四个属性,称为ACID(原子性、一致性、隔离性和持久性)属性,
原子性:事务必须是原子工作单元,对于其数据修改,要么全都执行,要么全都不执行。
一致性:事务在完成时,必须使所有的数据保持一致的状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如B树索引或双向链表)都必须是正确的。
隔离性:由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一并发事务修改它之后的状态,事务不会查看中间状态的数据。这称为可串行性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。
持久性:事务完成后,它对于系统的影响是永久性的。该修改即使出现系统故障也将一直保持。
1、Serializable (串行化):可避免脏读、不可重复读、幻读的发生
2、Repeatable read (可重复读):可避免脏读、不可重复读的发生。
3、Read committed (读已提交):可避免脏读的发生。
4、Read uncommitted (读未提交):最低级别,任何情况都无法保证
属于部署描述符,在整个JAVA中只要是容器都会存在部署描述符,此部署描述符可以控制整个WEB中各个组件的运行状态,也可以配置整个窗口的状态
第一范式(确保每列保持原子性)最基本范式。数据库表中所有字段值都是不可分解的原子值,就满足了第一范式。
第二范式(确保表中的每列都和主键相关)在第一范式上更近一层。确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关,也就是说一个表中只能保存一种数据,不可以吧多种数据保存在一张表中。
避免对索引字段进行计算、避免索引在字段上使用not、<>、!=、避免在索引上使用IS NULL和NOT NULL、避免在索引列上出现数据类型转换、避免索引字段使用函数、避免建立索引的列出现空值。
Ajax的工作原理相当于在用户和服务器之间加了—个中间层,使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器,像—些数据验证和数据处理等都交给Ajax引擎自己来做, 只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。
Ajax其核心只有JavaScript、XMLHTTPRequest和DOM,在旧的交互方式中,由用户触发一个HTTP请求到服务器,服务器对其进行处理后再返回一个新的HTHL页到客户端, 每当服务器处理客户端提交的请求时,客户都只能空闲等待,并且哪怕只是一次很小的交互、只需从服务器端得到很简单的一个数据,都要返回一个完整的HTML页,而用户每次都要浪费时间和带宽去重新读取整个页面。而使用Ajax后用户从感觉上几乎所有的操作都会很快响应没有页面重载(白屏)的等待。
SQL注入是一种将SQL代码添加到输入参数中,传递到服务器解析并执行的一种攻击手法。
SQL注入攻击是输入参数未经过滤,然后直接拼接到SQL语句当中解析,执行达到预想之外的一种行为,称之为SQL注入攻击。
利用新对象PreparedStatement对象完成,先将SQL骨架发送给数据库服务器,然后再将参数单独发给服务器,并将参数中的关键字当做一个普通字符串来处理,进而起到防止SQL注入的问题。
用来提高程序的效率,创建一个容器,容器中存放已经获取到了的数据库连接对象,对外提供获取连接和还回连接的方法,外界需要时就从容器中获取,用完就还回容器中。
XML是可扩展标记语言,而HTML超文本标记语言。不同之处:
1、语法有所不同。XML语法比较严谨而HTML语法比较松散。
2、用途不同。XML主要用于数据格式化存储而HTML主要用于网页的编辑。
简单来说: == 代表相同, ===代表严格相同, 为啥这么说呢,
这么理解: 当进行双等号比较时候: 先检查两个操作数数据类型,如果相同, 则进行===比较, 如果不同, 则愿意为你进行一次类型转换, 转换成相同类型后再进行比较, 而===比较时, 如果类型不同,直接就是false.
5.尽量减少子查询,使用关联查询(left join,right join,inner join)替代
6.减少使用IN或者NOT IN ,使用exists,not exists或者关联查询语句替代
7.or 的查询尽量用 union或者union all 代替
1.内存优化:Tomcat依赖于JVM,可以配置JVM的内存配置
2.最大连接数配置(并发能力)。通常搭配Nginx提升Tomcat的并发性能
自动刷新不仅可以实现一段时间之后自动跳转到另一个页面,还可以实现一段时间之后自动刷新本页面。Servlet中通过HttpServletResponse对象设置Header属性实现自动刷新例如:
Response.setHeader(Refresh,1000;URL=http://localhost:8080/servlet/example.htm);
其中1000为时间,单位为毫秒。URL指定就是要跳转的页面(如果设置自己的路径,就会实现没过一秒自动刷新本页面一次)
1.C/S用户固定,并且处于相同区域,要求拥有相同的操作系统。B/S要有操作系统和浏览器就行。与操作系统平台无关。
2.C/S客户端的计算机电脑配置要求较高。B/S客户端的计算机电脑配置要求较低。
3.C/S每一个客户端都必须安装和配置软件,客户端不必安装,使用浏览器访问,易推广。B/S最大的优点就是可以在任何地方进行操作而不用安装任何专门的软件。
4.C/S每一个客户端都要升级程序。可以采用自动升级。BS客户端不必安装及维护。
5.C/S一般面向相对固定的用户群,程序更加注重流程,它可以对权限进行多层次校验,提供了更安全的存取模式,对信息安全的控制能力很强。一般高度机密的信息系统采用C/S结构适宜。
事务没有提交之前,数据操作只保存在日志文件中提交事务之后,数据持久生效
HTML(Hypertext Markup Language)文本标记语言,它是静态页面,和JavaScript一样解释性语言,为什么说是解释性语言呢?因为,只要你有一个浏览器那么它就可以正常显示出来,而不需要指定的编译工具,只需在TXT文档中写上HTML标记就OK。
JSP(Java Server Page)看这个意思就知道是Java服务端的页面,所以它是动态的,它是需要经过JDK编译后把内容发给客户端去显示,我们都知道,Java文件编译后会产生一个class文件,最终执行的就是这个class文件,JSP也一样,它也要编译成class文件!JSP不止要编译,它还得要转译,首先把JSP转译成一个Servlet文件,然后在编译成class文件。当用户访问JSP时就执行了class文件,最 终......
1.最简单的区别就是,HTML能直接打开,jsp只能发布到Tomact等服务器上才能打开
2.定义上HTML页面是静态页面可以直接运行,JSP页面是动态页它运行时需要转换成servlet
3.他们的表头不同,这个是JSP的头“ <%@ page language=java import=java.util.* pageEncoding=gbk%>”在表头中有编码格式和导入包等
4.也是很好区分的在jsp中用<%%>就可以写Java代码了,而html没有<%%>
不同: Html是静态,servlet是动态 html页面由服务器直接返回, servlet是用来处理客户请求,并返回html页面 ,Servlet需要服务器调用servlet方法生成动态html页面,且需要在web.xml中配置url路径.
51.request ,response,session 和 application是怎么用的
3、Session在servlet中不能直接使用,需要通过getSession()创建,如果没有设定它的生命周期,或者通过invildate()方法销毁,关闭浏览器session就会消失
4、Application不能直接创建,存在于服务器的内存中,由服务器创建和销毁
52.Request和Session的取值区别,以及出现乱码的解决方式(不能在java代码中设置)
1、Request可以通过getAttribute()方法直接取值,也可通过getParameter()取值
2、Session需要通过request.getSession().getAttribute()才能取值
3、Request是针对一次请求,Session是针对整个会话
4、在页面通过contentType,pageEncoding,content设置编码格式,必须要一致
53.说明一下jsp中<jsp: include page..>和<%@ include file%>的区别
动态导入是行为元素、是在请求处理阶段引入的,引入执行页面或servlet所生成的应答文本
先编译,后包含,就是将每个jsp页面都单独转化成html页面,最后再将所有的html页面相加,如果有相同变量不会冲突<%@ include file= %> 静态导入是指令元素,是编译时包含,引入静态文本(html,jsp),在JSP页面被转化成servlet之前和它融和到一起。先包含,后编译
1、IOC/DI(控制反转/依赖注入) :把dao依赖注入到service层,service层反转给action层,Spring顶层容器为BeanFactory。
Struts2:基于类开发,传递参数通过类的属性,只能设置为多例
SpringMvc:基于方法开发(一个url对应一个方法),请求参数传递到方法形参,可以为单例也可以为多例(建议单例)
Struts2:值栈村塾请求和响应的数据,通过OGNL存取数据
SpringMvc:通过参数解析器将request请求内容解析,给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过request域传输到页面,jsp视图解析器默认使用的是jstl。
封装了底层的JDBC,API的调用,并且能够将结果集自动转换成JavaBean对象,简化了Java数据库编程的重复工作。
数据库
1.触发器的作用?
触发器是一种特殊的存储过程,主要是通过事件来触发而被执行的。它可以强化约束,来维护数据的完整性和一致性,可以跟踪数据库内的操作从而不允许未经许可的更新和变化。可以联级运算,如:3某表上的触发器包含对另一个表的数据操作,而该操作又会导致该表的触发器被触发。
存储过程是一个预编译的SQL语句,优点是允许模块化的设计,就是说只需要创建一次,以后在该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯的SQL语句执行要快。可以用一个命令对象来调用存储过程。
索引就是一种特殊的表查询,数据库的搜索引擎可以利用它加速对数据的检索,它很类似与现实生活中书的目录,不需要查询整本书内容就可以找到想要的数据,索引可以是唯一的,创建索引允许指定单个列或者多个列。缺点是它减慢了数据录入的速度,同时也增加了数据库的尺寸大小。
事务就是绑定在一起作为一个逻辑工作单元的SQL语句分组,如果任何一个语句操作失败,以后操作就会回滚到操作前状态,或者是上个节点。为了确保要么执行,要么不执行,就可以使用事务。要将某组语句作为事务考虑,就需要通多ACID测试,即原子性,一致性,隔离性和持久性。
锁:在索引的DBMS中,所示实现事务的关键,锁可以保证事务的完整性和并发性,与现实生活中的锁一样,它可以使某些数据的拥有者,在某段时间内不能使用某些数据或者数据结构,当然锁还分级别的。
视图是一种虚拟的表,具有和物理表相同的功能。可以对试图进行增、改、查操作,视图通常是一个表或者多个表的行和列的子集。对试图的修改不 影响基本表。它使得我们获取数据更容易,相比多表查询。
游标:是对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行,从结果集的当前行检索一行或者多行。可以对结果集当前行做修改。一般不使用游标,但是需要逐条处理数据的时候,游标显得十分重要。
c.左外连接:左边为驱动表,驱动表的数据全部显示,匹配表中不匹配的内容不会显示
d.右外连接:右边为驱动表,驱动表的数据全部显示,匹配表中不匹配的内容不会显示
主键在本表中是唯一的,不可为空的,外键可以重复为空;外键和另一张表的主键关联,不能创建对应表中不存在的外键。
c.优化sql,尽量让sql很快定位数据,不要让sql做全表查询,应该走索引,把数据量大的表排在前面
d.简化查询字段,没用的字段不要,已经对返回结果的控制,尽量返回少量数据
e.尽量用PreparedStatement来查询,不要用Statement。
第一范式:字段具有原子性,不可再分,所有关系型数据库系统都满足第一范式
数据可表中字段都是单一属性,不可再分。例如,姓名字段,其中的姓和名必须作为一个整体,无法区分哪个部分是姓,哪个部分是名,如果要区分出姓和名,必须设计成两个独立的字段。
第二范式:是在第一范式的基础上建立起来的,即满足第二范式必须满足第一范式。
要求数据库表中的每个实例或行必须被唯一的区分,通常需要为表加上一个列,以储存各个实例的唯一标识,这个唯一属性列被称为主关键字或主键。
要求实例的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。简而言之,第二范式就是非主属性非不等依赖于主关键字。
第三范式:满足第三范式必须满足第二范式,简而言之,第三范式要求一个数据库表中不包含已在其他表中已包含的非主关键字信息。
eg:帖子表中只能出现发帖人的ID,而不能出现发帖的ID还同时出现发帖人姓名,否则,只要出现同一发帖人id的所有记录,它们中的姓名部分都必须严格保持一致,这就是数据冗余
union在进行表连接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表union。
union all只是简单的将两个结果合并就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。
从效率上说,union all要比union快很多,所以,如果可以确定合并的两个结果集中不包含重复的数据的话,那么就使用union all
11.JDBC中的PreparedStatement相比Statement的好处
c.显示当前所有的表、用户、改变连接用户、显示当前连接用户、执行外部脚本的语句的不同。
d.分页查询时候,mysql用limt;oracle用rownum
a.Char的长度是固定的,而varchar2的长度是可以变化的,比如,储存字符串“abc”对于char(20),标识你存储的字符将占20个字节,包含17个空,而童谣的varchar2(20)只占了三个字节,20只是最大值,当你存储的字符小于20是,按实际长度存储。
c.目前varchar是varchar2的同义词,工业标准的varchar类型可以存储空字符串,但是oracle不能这样做,尽管它保留以后这样做的权力。Oracle自己开发了一个数据类型varchar2,这个类型不是一个标准的varchar,他将在数据库中varchar列可以存储空字符串的特性改为存储null值,如果你想有向后兼容的能力,oracle建议使用varchar2而不是varchar
14.Statement和proraredStatement有什么区别?
后者的效率比前者高,在使用preparedStatment对象执行sql时候,命令被数据库编译和解析,然后被放到命令缓存区,然后每当执行同一个preparedStatement,他就被再解析一次,但不会再编译,再缓冲区中可以发现预编译的命令,并且可以重新使用
如果你要写Insert、update、delete 最好使用preparedStatement,在有大量用户的企业级应用软件中,经常会执行相同的SQL,使用preparedStatement会增加整体的性能。