java面试题集整理

面试题汇总:

(资料整理于百度,个人文档,如有重复,请联系删除)

  1. 我们能将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将会出现什么现象?
    是的,我们可以做强制转换,但是 Java 中 int 是 32 位的,而 byte 是 8 位的,所以,如果强制转化是,int 类型的高 24 位将会被丢弃,byte 类型的范围是从 -128 到 128。

  2. Java语言中使用哪两个类封装大数据类型?分别有什么作用?
    答案:实际编程中,往往会由于数值超出长度范围而失去精度。Java语言中提供了大数据类型解决这个问题,程序员应该对此熟练掌握,在需要进行大数据运算时使用。
    参考答案:Java语言中有两个大数据类型,即BigInteger和BigDecimal,其中BigInteger可以封装任意精度的整形数值,而BigDecimal可以封装任意精度的有符号数,包括整数和浮点数。

  3. &和&&的区别?
    答案:&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
    &&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str != null && !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。If(x33 & ++y>0) y会增长,If(x33 && ++y>0)不会增长
    &还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。

  4. 队列和栈是什么,列出它们的区别?
    答案:
    队列(Queue)是限定只能在表的一端进行插入和在另一端进行删除操作的线性表。
    栈(Stack)是限定只能在表的一端进行插入和删除操作的线性表。
    1.队列先进先出,栈先进后出。
    2.对插入和删除操作的”限定”。 栈是限定只能在表的一端进行插入和删除操作的线性表。队列是限定只能在表的一端进行插入和在另一端进行删除操作的线性表。
    3.遍历数据速度不同。队列遍历数据的速度要快得多。

  5. continue和 break有什么区别?
    答案:break和continue都是用来控制循环结构的,主要是停止循环。
    1.break
    有时候我们想在某种条件出现的时候终止循环而不是等到循环条件为false才终止。
    这是我们可以使用break来完成。break用于完全结束一个循环,跳出循环体执行循环后面的语句。
    2.continue
    continue和break有点类似,区别在于continue只是终止本次循环,接着还执行后面的循环,break则完全终止循环。
    可以理解为continue是跳过当次循环中剩下的语句,执行下一次循环。

  6. String与StringBuilder的区别?
    答案:
    三者在执行速度方面的比较:StringBuilder > StringBuffer > String
    String类是不可变类,字符串一旦初始化后,就不能被改变。而StringBuffer类是可变类,字符串值可以被改变。常常在实际应用中看到类似这样的代码:String s=new(“hello”);s+=”world”,这两句代码首先创建一个字符hello,然后将world追加到hello结尾并重新赋 值给变量s。然后,这个过程实际上是这样的:首先创建一个StringBuffer对象,然后用StringBuffer类的append方法追加字符串,最后对StringBuffer对象调用toString方法合成字符串返回。可见,使用+号连接字符串时,本质上是使用了可变的StringBuffer类,经变动肯定性能效率受到影响,所以建议需要追加字符串时,可以考虑直接使用StringBuffer类。参考 :String类是不可变类,即字符串值一旦初始化后就不可能改变。StringBuffer是可变字符串类,类似String的缓冲区,可以修改字符串的值。
    StringBuffer是JDK5中增加的一个新类,在以前版本中不存在这个类。StringBuilder中的方法和StringBuffer中的方法基本相同,但是StringBuffer是线程安全的,而StringBuilder不是线程安全的,因此在不考虑同步的情况下,StringBuilder有更好的性能。

  7. 说出几点 Java 中使用 Collections 的最佳实践
    答案:
    这是我在使用 Java 中 Collectionc 类的一些最佳实践:
    a)使用正确的集合类,例如,如果不需要同步列表,使用 ArrayList 而不是 Vector。
    b)优先使用并发集合,而不是对集合进行同步。并发集合提供更好的可扩展性。
    c)使用接口代表和访问集合,如使用List存储 ArrayList,使用 Map 存储 HashMap 等等。
    d)使用迭代器来循环集合。
    e)使用集合的时候使用泛型。

  8. 介绍Collection框架的结构
    Collection 是单列集合,包含List列表,Set集
    Map:Hashtable,HashMap,TreeMap
    List 元素是有序的、可重复. Set(集) 元素无序的、不可重复。
    List接口中常用类
    Vector: 线程安全,但速度慢,已被ArrayList替代。
    底层数据结构是数组结构
    ArrayList:线程不安全,查询速度快。访问任意位置,效率高
    增删数据,效率可能降低
    底层数据结构是数组结构,内部数组默认的初始容量 10,放满后,1.5倍增长
    LinkedList:线程不安全。增删速度快。两端效率高
    底层数据结构是列表结构

Set接口中常用的类
HashSet:线程不安全,存取速度快。
它是如何保证元素唯一性的呢?依赖的是元素的hashCode方法和euqals方法。

TreeSet:线程不安全,可以对Set集合中的元素进行排序。
它的排序是如何进行的呢?通过compareTo或者compare方法中的来保证元素的唯一性。元素是以二叉树的形式存放的。

Map 是一个双列集合
–Hashtable:线程安全,速度快。底层是哈希表数据结构。是同步的。
不允许null作为键,null作为值。
–HashMap:线程不安全,速度慢。底层也是哈希表数据结构。是不同步的。不重复 无序
允许null作为键,null作为值。替代了Hashtable.
–LinkedHashMap: 可以保证HashMap集合有序。存入的顺序和取出的顺序一致。
–TreeMap:可以用来对Map集合中的键进行排序.
哈希运算过程
HashMap内部,使用 Entry[] 数组存放数据,数组默认初始容量 16,放满后容量翻倍+2

key.hashCode() 获得键的哈希值
用哈希值和数组长度,运算产生一个下标值 i
新建Entry 对象来封装键值对数据
Entry对象,放在 i 位置
如果是空位置,直接放入,有数据,依次equals()比较是否相等
找到相等的,覆盖旧值,没有相等的,链表连接在一起
负载率、加载因子 0.75
新建翻倍容量的新数组
所有数据,重新执行哈希运算,放入新数组
jdk1.8
链表长度到8,转成红黑树
树上的数据减少到6,转回成链表

  1. final, finally, finalize的区别。
    答案:
    1、性质不同
    (1)final为关键字;
    (2)finalize()为方法;
    (3)finally为为区块标志,用于try语句中;
    2、作用
    (1)final为用于标识常量的关键字,final标识的关键字存储在常量池中
    (2)finalize()方法在Object中进行了定义,用于在对象“消失”时,由JVM进行调用用于对对象进行垃圾回收,类似于C++中的析构函数;用户自定义时,用于释放对象占用的资源(比如进行I/0操作);
    (3)finally{}用于标识代码块,与try{}进行配合,不论try中的代码执行完或没有执行完(这里指有异常),该代码块之中的程序必定会进行;
    3、final详解
    (1)定义变量
    1.1 final定义基本类型变量时,要求变量初始化必须在声明时或者构造函数中,不能用于其它地方。该关键字定义的常量,除了初始化阶段,不能更改常量的值。
    1.2 final定义对象的引用,该引用的初始化与定义常量时的要求一致;该关键字定义的对象内容可以改变,但是引用指向的地址不能改变;
    (2)定义参数
    如果传入该参数定义的变量时,方法不能对该参数内容进行修改(错误),与定义变量的修改规则相同;java方法中传递基本类型时是传值的,java方法对于对象的传递是传参的;<归根结底,java中方法的传递是依靠传递“副本”:对于基本类型,首先建立一个Copy,并将传入的值赋值给Copy,然后对Copy进行操作;对于对象类型,首先建立一个引用Copy,并将传入的对象引用赋值给Copy>
    比如:method(final int test);
    有些书上说,这里final定义参数,尤其是对象的参数很有作用,不能在方法内对于对象的内容进行改变,这样的说法是错误的!原来我也认为这样有些函数式编程的特点,不能对于对象的内容进行修改该,这里依旧可以对对象的内容进行修改。
    定义该参数有什么用??
    String天生就是final类型的!
    (3)定义方法
    3.1使用final关键字定义的方法,不能被子类继承;
    3.2允许编译器将所有对此方法的调用转化为inline(行内)行为,即可以将此方法直接复制在调用处,而不是进行例行的方法调用(保存断点、压栈),这样会使程序的效率升高。但是————-如果过多的话,这样会造成代码膨胀,反而会影响效率,所以该方法要慎用。。
    (4)定义类
    一个任何final类无法被任何人继承,这也就意味着此类在一个继承树中是一个叶子类,并且此类被认为是很完美的,不需要进行任何修改(总之是不推荐使用)

  2. jdk、jre、jvm的区别?
    JDK : Java Development ToolKit(Java开发工具包)。JDK是整个JAVA的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。
    JRE:Java Runtime Enviromental(java运行时环境)。也就是我们说的JAVA平台,所有的Java程序都要在JRE下才能运行。包括JVM和JAVA核心类库和支持文件。与JDK相比,它不包含开发工具——编译器、调试器和其它工具。
    JVM:Java Virtual Mechinal(JAVA虚拟机)。JVM是JRE的一部分,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM 的主要工作是解释自己的指令集(即字节码)并映射到本地的 CPU 的指令集或 OS 的系统调用。

  3. 例举6种数据结构和它们的作用
    ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步
    LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
    Vector非常类似ArrayList,但是Vector是同步的。
    Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
    Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。
    Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。
    HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。
    WeakHashMap是一种改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC回收。

  4. 请描述冒泡排序算法的基本思想。
    1.冒泡排序的基本思想 冒泡排序是交换排序中一种简单的排序方法。它的基本思想是对所有相邻记录的关键字值进行比效,如果是逆顺(a[j]>a[j+1]),则将其交换,最终达到有序化。其处理过程为: (1)将整个待排序的记录序列划分成有序区和无序区,初始状态有序区为空,无序区包括所有待排序的记录。 (2)对无序区从前向后依次将相邻记录的关键字进行比较,若逆序将其交换,从而使得关键字值小的记录向上”飘浮”(左移),关键字值大的记录好像石块,向下“堕落”(右移)。 每经过一趟冒泡排序,都使无序区中关键字值最大的记录进入有序区,对于由n个记录组成的记录序列,最多经过n-1趟冒泡排序,就可以将这n个记录重新按关键字顺序排列。 2.原始的冒泡排序算法 对由n个记录组成的记录序列,最多经过(n-1)趟冒泡排序,就可以使记录序列成为 有序序列,第一趟定位第n个记录,此时有序区只有一个记录;第二趟定位第n-1个记录,此时有序区有两个记录;以此类推,算法框架为: for(i=n;i>1;i—) { 定位第i个记录; }
    若定位第i个记录,需要从前向后对无序区中的相邻记录进行关键字的比较,它可以用如下所示的语句实现。
    for(j=1;j< =i-1;j++)
    if (a[j].key>a.[j+1].key) {
    temp=a[j];
    a[j]=a[j+1];
    a[j+1]=temp;
    }
    下面给出完整的冒泡排序算法:
    void BubbleSort1 (DataType a,int n) {
    for (i=n;i>1;i–) {
    for (j=1;j<=i-1;j++) {
    if(a[j].key>a.[j+1].key) {
    temp=a[j];
    a[j]=a[j+1];
    a[j+1]=temp;
    }
    }
    }

  5. .&, &&, >, >>,>>>的区别
    &和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
    &&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str != null && !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。If(x33 & ++y>0) y会增长,If(x33 && ++y>0)不会增长
    &还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。
    表示大于,如:if(a>b)…结果是boolean类型
    表示带符号右移,如:int i=15; i>>2的结果是3,移出的部分将被抛弃。
    转为二进制的形式可能更好理解,0000 1111(15)右移2位的结果是0000 0011(3),0001 1010(18)右移3位的结果是0000 0011(3)。
    无符号右移:
    按二进制形式把所有的数字向右移动对应巍峨位数,低位移出(舍弃),高位的空位补零。对于正数来说和带符号右移相同,对于负数来说不同。
    其他结构和>>相似。

  6. 抽象类和接口的区别
    1).抽象类可以有构造方法,接口中不能有构造方法。
    2).抽象类中可以有普通成员变量,接口中没有普通成员变量
    3).抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
    4). 抽象类中的抽象方法的访问类型可以是public,protected 和(默认类型,虽然eclipse 下不报错,但应该也不行),但接口中的抽象方法只能是public 类型的,并且默认即为
    public abstract 类型。
    5). 抽象类中可以包含静态方法,接口中不能包含静态方法
    6). 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,
    但接口中定义的变量只能是public static final 类型,并且默认即为public static final 类型。
    7). 一个类可以实现多个接口,但只能继承一个抽象类。

  7. 面向对象的特征有哪些方面?
    三大特性是:封装,继承,多态
    所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。封装是面向对象的特征之一,是对象和类概念的主要特性。 简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。
    所谓继承是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;
    所谓多态就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。

  8. 静态变量和实例变量的区别?
    在语法定义上的区别:
    静态变量前要加static 关键字,而实例变量前则不加。
    在程序运行时的区别:
    实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。

  9. Overload(重载)和Override(重写)的区别?
    1.重写必须继承,重载不用。
    2.重写的方法名,参数数目相同,参数类型兼容,重载的方法名相同,参数列表不同。
    3.重写的方法修饰符大于等于父类的方法,重载和修饰符无关。
    4.重写不可以抛出父类没有抛出的一般异常,可以抛出运行时异常

  10. 多态的表现形式有哪些?
    答案:重写和重载。向上造型

  11. 构造器能不能重写,重载
    答案:能被重载,不能被重写

  12. 我们能不能声明main()方法为非静态?
    答案:
    不能,main()方法必须声明为静态的,这样JVM才可以调用main()方法而无需实例化它的类。
    如果从main()方法去掉“static”这个声明,虽然编译依然可以成功,但在运行时会导致程序失败。

  13. 使用final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
    使用final 关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。

  14. Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
    答案:Overload是重载的意思,Override是覆盖的意思,也就是重写。
    重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。
    重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能更小。如果父类的方法是private类型,那么,子类则不存在覆盖的限制,相当于子类中增加了一个全新的方法。
    至于Overloaded的方法是否可以改变返回值的类型这个问题,要看你倒底想问什么呢?这个题目很模糊。如果几个Overloaded的方法的参数列表不一样,它们的返回者类型当然也可以不一样。但我估计你想问的问题是:如果两个方法的参数列表完全一样,是否可以让它们的返回值不同来实现重载Overload。这是不行的,我们可以用反证法来说明这个问题,因为我们有时候调用一个方法时也可以不定义返回结果变量,即不要关心其返回结果,例如,我们调用map.remove(key)方法时,虽然remove方法有返回值,但是我们通常都不会定义接收返回结果的变量,这时候假设该类中有两个名称和参数列表完全相同的方法,仅仅是返回类型不同,java就无法确定编程者倒底是想调用哪个方法了,因为它无法通过返回结果类型来判断。
    override可以翻译为覆盖,从字面就可以知道,它是覆盖了一个方法并且对其重写,以求达到不同的作用。对我们来说在最熟悉的覆盖就是对接口方法的实现,接口中一般只是对方法进行了声明,而我们在实现时,就需要实现接口声明的所有方法。除了这个典型的用法以外,我们在继承中也可能会在子类覆盖父类中的方法。在覆盖要注意以下的几点:
    1、覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;
    2、覆盖的方法的返回值必须和被覆盖的方法的返回一致;
    3、覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;
    4、被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。
    overload对我们来说可能比较熟悉,可以翻译为重载,它是指我们可以定义一些名称相同的方法,通过定义不同的输入参数来区分这些方法,然后再调用时,VM就会根据不同的参数样式,来选择合适的方法执行。在使用重载要注意以下的几点:
    1、在使用重载时只能通过不同的参数样式。例如,不同的参数类型,不同的参数个数,不同的参数顺序(当然,同一方法内的几个参数类型必须不一样,例如可以是fun(int,float),但是不能为fun(int,int));
    2、不能通过访问权限、返回类型、抛出的异常进行重载;
    3、方法的异常类型和数目不会对重载造成影响;
    4、对于继承来说,如果某一方法在父类中是访问权限是priavte,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。

  15. Java 中的编译期常量是什么?使用它又什么风险?
    公共静态不可变(public static final )变量也就是我们所说的编译期常量,这里的 public 可选的。实际上这些变量在编译时会被替换掉,因为编译器知道这些变量的值,并且知道这些变量在运行时不能改变。这种方式存在的一个问题是你使用了一个内部的或第三方库中的公有编译时常量,但是这个值后面被其他人改变了,但是你的客户端仍然在使用老的值,甚至你已经部署了一个新的jar。为了避免这种情况,当你在更新依赖 JAR 文件时,确保重新编译你的程序。

  16. 请简述引用类型与原始类型的异同用法?
    引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值,
    那么调用这个方法是传入的变量的值也将改变.值类型表示复制一个当前变量传给方法,
    当你在这个方法中改变这个变量的值时,最初生命的变量的值不会变.通俗说法: 值类型就是现金,要用直接用;引用类型是存折,要用还得先去银行取现。
    除了四类八种基本类型外,所有的类型都称为引用类型(数组,类,接口,字符串)
    引用类型之间赋值属于引用传递。引用传递传递的是对象的引用地址,也就是它的本身。
    引用传递:传的是地址,就是将实参的地址传递给形参,形参改变了,实参当然被改变了,因为他们指向相同的地址。
    值类型也就是基本数据类型 基本数据类型常被称为四类八种
    基本数据类型赋值都属于值传递,值传递传递的是实实在在的变量值,是传递原参数的拷贝,值传递后,实参传递给形参的值,形参发生改变而不影响实参。

  17. 接口是否可以继承接口?抽象类是否可以实现(implements)接口? 抽象类是否可以继承实体类(concrete class)?
    接口可以继承接口,可以继承多个接口
    抽象类可以实现接口,可以实现多个接口
    抽象类可以继承类,但只能继承一个类

  18. 实例变量与静态变量的区别?
    在语法定义上的区别:
    静态变量前要加static 关键字,而实例变量前则不加。
    在程序运行时的区别:
    实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。

  19. 简述static final,finally的作用和区别
    final关键字
    1、final修饰类,表示该类不能被继承,因此,一个类不能同事被声明为abstract抽象类和final的类;
    2、final修饰变量,则该变量必须赋初值,而且它的取值在整个过程都不会改变;
    3、final修饰方法,称为最终方法。它不可被子类重新定义,即不可被覆盖,也不能被重载;
    static关键字
    (1)static定义的数据或方法,可以不用new出类的实例而让类直接调用;
    (2)static代码块;static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。
    finally:java的一种异常处理机制。
    (1) finally是对Java 异常处理模型的最佳补充。finally 结构使代码总会执行,而不管有无异常发生。
    (2)使用 finally 可以维护对象的内部状态,并可以清理非内存资源。
    (3)特别是在关闭数据库连接这方面,如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。
    finalize:Java中Object类中的一个方法名。
    ava技术使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。
    这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。
    它是在Object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。
    finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

  20. GC是什么?GC的作用
    GC是垃圾收集的意思,内存处理是编程人员容易出现问题的地方,
    忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,
    Java语言没有提供释放已分配内存的显示操作方法。Java程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:System.gc()或Runtime.getRuntime().gc(),但JVM可以屏蔽掉显示的垃圾回收调用。
    垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低优先级的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。

  21. 有没有了解过线程,它是怎么样的呢?
    答案:
    线程是进程中的实体,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程不拥有系统资源,只有运行必须的一些数据结构;它与父进程的其它线程共享该进程所拥有的全部资源。线程可以创建和撤消线程,从而实现程序的并发执行。一般,线程具有就绪、阻塞和运行三种基本状态。
    线程在一定条件下,状态会发生变化。线程一共有以下几种状态:
    1、新建状态(New):新创建了一个线程对象。
    2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取CPU的使用权。即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。
    3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
    4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。
    阻塞的情况分三种:
    (1)、等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒,
    (2)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。
    (3)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
    5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

  1. sleep() 和 wait() 有什么区别?
    (网上的答案:sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,将执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。)
    sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行

  2. 同步和异步有何异同,在什么情况下分别使用他们?举例说明。
    如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
    当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。

  3. 常用块级元素与行内元素
    一.块级元素:
    不废话,直接上图(div、p、h1~h6、ul、ol、dl、li、dd、table、hr、blockquote、address、table、menu、pre,HTML5新增的header、section、aside、footer等)

从浏览器的显示结果可以看出,块级元素新开启一行(即使是设置了width属性也是独占一行)、尽可能撑满父级元素的宽度,可以设置width和height属性;table元素浏览器默认的display属性为table。

二.行内元素
也直接上图(span、img、a、lable、input、abbr(缩写)、em(强调)、big、cite(引用)、i(斜体)、q(短引用)、textarea、select、small、sub、sup,strong、u(下划线)、button(默认display:inline-block))

  1. 表单标签
    表单标签
    表单的作用:用于向服务器发送数据/提交数据
    通过在超链接后面拼接参数的形式, 也可以向服务器发送数据.
action属性用于指定表单的提交地址 method属性用于指定提交方式.

表单项标签
1、input标签
(1)普通文本输入框

(2)密码输入框

(3)单选框 / 复选框


(4)普通按钮

(5)提交按钮

2、select、option标签
select 用于定义一个下拉选框
option 用于定义下拉选框中的选项

北京
上海
广州
深圳

3、textarea标签
用于实现多行文本输入框

  1. 事务及四大特性, 事务并发读问题, 事务隔离级别
    事务: 事务就是将一堆的SQL语句绑定在一起执行,要么全部执行成功,要么全部执行失败
    事务的四大特性
    原子性: 事务中的所有SQL语句是一个整体,不能再分割,要么全部执行成功,要么全部执行失败!
    一致性: 不管事务最终是失败还是成功,事务前后的业务数据之和是保持一致的。
    隔离性: 在隔离级别较高的前提下,事务之间是隔离开来的。一个事务看不到另外一个事务正在进行中的操作。要么是看到另外一个事务开始之前的状态,要么看到另外一个事务已经结束后的状态。
    持久性: 事务成功后,对数据的修改操作将会是永久的。
    MySQL中的事务
    在mysql中默认一条sql就是一个事务。
    如果要让多条SQL执行在一个事务中,可以手动开启事务,再手动关闭事务
    开启事务:start transaction;
    结束事务:提交:commit /回滚:rollback
    事务并发读问题
    1、脏读: 在一个事务中读取到了另外一个事务没有提交的数据, 就叫做脏读。
    2、不可重复读:
    在一个事务中,对同一个数据的两次查询结果不一致,是因为中间有人做了修改操作。
    3、幻读:
    在一个事务中,对同一个数据的两次查询结果不一致,是因为中间有人做了插入或者删除操作.
    事务隔离级别
    事务隔离级别分四个等级,在相同数据环境下,对数据执行相同的操作,设置不同的隔离级别,可能导致不同的结果。不同事务隔离级别能够解决的数据并发问题的能力也是不同的。
    set tx_isolation=‘read-uncommitted’;
    1、read uncommitted(读未提交数据)
    安全级别最低, 可能出现任何事务并发问题(比如脏读、不可以重复读、幻读等)
    性能最好(不使用!!)
    2、read committed(读已提交数据)(Oracle默认)
    防止脏读,没有处理不可重复读,也没有处理幻读;
    性能比REPEATABLE READ好
    3、repeatable read(可重复读)(MySQL默认)
    防止脏读和不可重复读,不能处理幻读问题;
    性能比SERIALIZABLE好
    4、serializable(串行化)
    不会出现任何并发问题,因为它是对同一数据的访问是串行的,非并发访问的;
    性能最差;
    MySQL的默认隔离级别为repeatable read,即可以防止脏读和不可重复读

  2. Java异常类型及处理
    一、java中异常的体系
    1.Java中的所有不正常类都继承于Throwable类。Throwable主要包括两个大类,一个是Error类,另一个是Exception类;
    2.其中Error类中包括虚拟机错误和线程死锁,一旦Error出现了,程序就彻底的挂了,被称为程序终结者;
    3.Exception类,也就是通常所说的“异常”。主要指编码、环境、用户操作输入出现问题,Exception主要包括两大类, RuntimeException和其他的一些异常

  3. RuntimeException异常会由java虚拟机自动抛出并自动捕获,此类异常的出现绝大数情况是代码本身有问题应该从逻辑上去解决并改进代码。RuntimeException异常主要包括以下四种异常:空指针异常、数组下标越界异常、类型转换异常、算术异常。
    5.检查异常,引起该异常的原因多种多样,比如说文件不存在、或者是连接错误等等。该异常我们必须手动在代码里添加捕获语句来处理该异常。

二、异常的处理

  1. 通过try…catch语句块来处理
    2.也可以在具体位置不处理,直接抛出,通过throws/throw到上层再进行处理

  2. finally关键字
    finally 关键字用来创建在 try 代码块后面执行的代码块。
    无论是否发生异常,finally 代码块中的代码总会被执行。
    在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。

  3. cookie和session的区别
    (1)Cookie是将会话中产生的数据保存在客户端,是客户端的技术
    (2)Session是将会话中产生的数据保存在服务器端,是服务器端的技术
    (3)Cookie保存的信息的时间比较长,但是安全性不高,可能随着用户的操作,Cookie会被清空,所以Cookie存储数据的稳定性比较差。因此Cookie适合存放要保存时间较长,但安全性要求不高的信息
    (4)Session通常保存信息的时间比较有限,但安全性比较高,因为是保存在服务器端,不会随着用户的操作而导致Session意外丢失,因此session适合存放安全性要求比较高,但是不需要长时间保存的数据。
    (5)在性能上,Cookie性能更高一些。Cookie是将数据保存在用户各自的客户端浏览器中,而Session是服务器端的对象,是将数据(在一定时间内)保存在服务器端,因此当访问量增多时,会降低服务器的性能。
    (6)在数据量上,单个Cookie保存的数据量不能超过4KB,而很多浏览器都限制一个站点给浏览器最多发送20个Cookie。而Session不存在此问题。

  4. JSP九大内置对象详解
    request 用户端请求,此请求会包含来自GET/POST请求的参数
    response 网页传回用户端的回应
    pageContext 网页的属性是在这里管理
    session 与请求有关的会话期
    application servlet 正在执行的内容
    out 用来传送回应的输出
    config servlet的构架部件
    page JSP网页本身
    exception 针对错误网页,未捕捉的例外
    四大域对象
    page域: 只能在当前jsp页面使用 (当前页面)
    request域: 只能在同一个请求中使用 (转发)
    session域: 只能在同一个会话(session对象)中使用 (私有的)
    context域: 只能在同一个web应用中使用 (全局的)

  5. 描述四大域对象的特征
    1、PageContext域
    (1)生命周期:开始访问JSP页面时创建PageContext对象,访问JSP页面结束时销毁PageContext对象
    (2)作用范围:在整个JSP页面中
    (3)主要功能:在整个JSP页面中实现数据的共享。
    2、request域
    (1)生命周期:一次请求开始时创建request对象,一次请求结束时销毁request对象。
    (2)作用范围:在整个请求链中
    (3)主要功能:在整个请求链中实现数据的共享
    3、session域
    (1)生命周期:
    创建: 当第一次调用request.getSession()方法时将会创建session对象.
    销毁:session分为三种情况:
    a)超时销毁: 如果超过30分钟不操作session,session将会超时销毁.
    b)自杀: 当调用session.invalidate()方法时会立即销毁session
    c)意外身亡: 当服务器非正常关闭时,session会销毁! 当服务器正常关闭时,session将会以文件的形式保存在tomcat服务器work目录下
    (2)作用范围:在整个会话范围内
    (3)主要功能:在整个会话范围内实现数据的共享
    4、ServletContext域
    (1)生命周期:服务器启动WEB应用被加载之后立即创建ServletContext对象,服务器关闭或WEB应用被移出容器,销毁ServletContext对象。
    (2)作用范围:在整个WEB应用中
    (3)主要功能:在整个WEB应用范围内实现数据的共享

  6. forward(转发)与redirect(重定向)的区别
    请求转发的特点:
    (1)请求转发前后是一次请求, 一次响应
    (2)请求转发前后地址栏地址不会发生变化
    (3)请求转发只能是同一个Web应用内部的两个资源进行转发, 不可以是不同的Web应用
    (4)请求转发前后是一次请求, 因此转发前后的request对象是同一个。可以利用request对象上的map集合带数据到目的地.
    重定向的特点:
    (1)重定向前后是两次请求,两次响应
    (2)重定向前后地址栏地址会发生变化
    (3)重定向前后的两个资源可以不是来自同一个Web应用
    (4)由于重定向是两次请求,所以重定向前后的request对象不是同一个, 也就不能通过request域带数据到目的地!

  7. getParameter和getAttribute区别
    两者区别:
    getParameter()获取的是客户端向服务器端发送的请求数据。
    getAttribute()获取的是服务器设置的数据,像用于服务器端进行跳转。
    ②getParameter()永远返回字符串
    getAttribute()返回值是任意类型

既然parameter和attribute都是传递参数,为什么不直接使用parameter呢?
①服务器端不能通过setParameter(key, value)来添加参数,因为没有这个函数
所以如果需要在服务器端进行跳转,并需要想下个页面发送新的参数时,则没法实现。但是Attribute可以,可以通过setAttribute(),将值放入到request对象,然后在其他页面使用getAttribute获取对应的值,这样就达到一次请求可以在多个页面共享一些对象信息
②parameter返回值是字符串,意味着不能传递其他的对象,如Map,List,但是attribute则可以存放任意类型的Java对象

  1. Servlet的生命周期?
    Servlet的生命周期包含了下面4个阶段:
    1.加载和实例化
      Servlet容器负责加载和实例化Servlet。当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一个请求时,由Servlet容器通过Java的反射API创建Servlet实例。
    2.初始化
      在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象。对于每一个Servlet实例,init()方法只被调用一次。初始化的目的是为了让Servlet对象在处理客户端请求前完成一些初始化的工作,如建立数据库的连接,获取配置信息等。
    3.请求处理
      在init()方法成功执行之后, Servlet容器调用Servlet的service()方法对请求进行处理。在service()方法中,Servlet实例通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置响应信息。
    service()方法的职责
    service()方法为Servlet的核心方法,客户端的业务逻辑应该在该方法内执行,典型的服务方法的开发流程为:
    解析客户端请求-〉执行业务逻辑-〉输出响应页面到客户端
    4.服务终止
      当容器检测到一个Servlet实例应该从服务中被移除的时候(需要释放内存或者容器关闭时),容器就会调用实例的destroy()方法。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收。如果再次需要这个Servlet处理请求,Servlet容器会创建一个新的Servlet实例。
      在整个Servlet的生命周期过程中,创建Servlet实例、调用实例的init()和destroy()方法都只进行一次。

  2. GET和POST两种基本请求方法的区别
    请求参数: 浏览器向服务器发送请求的过程中,在请求中携带给服务器的数据, 就叫做请求参数
    区别主要体现在请求参数传输过程的不相同
    GET提交: 通过在地址栏URL地址的后面拼接参数, 将数据提交给服务器
    (1)通过地址栏提交数据, 相对不安全
    (2)通过地址栏提交数据, 数据量不能太大, 一般不能超过1kb或者是4kb
    POST提交: 通过请求实体提交数据给服务器
    (1)POST提交没有将发送给服务器的数据显示在地址栏, 相对更加安全
    (2)POST提交通过请求实体(不是地址栏)发送数据, 数据量理论上没有限制!

由于GET提交更加方便(因为不需要通过表单), 所以在没有数据要提交的情况下, 或者有数据提交, 但不是隐私数据并且数据量不太大, 可以通过GET提交!!

  1. 有哪几种方法可以返回Class类的对象?
    答案:初级程序员对Class类往往容易混淆,Class是API中的一个类名,而不是关键字class。Class类是反射技术的核心,用来封装类的类型,通过Class实例,可以动态获得类的其他信息。
    参考答案:可以有三种方式返回Class类型对象:①使用Object类中的getclass方法;②使用Class类的forName方法;③使用“类名.class”形式返回Class实例。

  2. 什么是反射?反射有哪些作用?
    答案:Java语言对反射进行了支持,很多框架的底层也使用了反射技术,例如Spring框架的IoC技术就是基于反射技术。了解反射技术,对于程序员理解很多其他框架和技术都非常有必要。
    参考答案:反射是一种强大的工具,能够用来创建灵活的代码,这些代码可以在运行时装配,利用反射机制能够实现很多动态的功能,例如在运行期判断一个对象有哪些方法、动态为对象增加成员、运行期调用任意对象的任意方法等。

  3. JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计

  4. IO模型有哪些,讲讲你理解的nio ,他和bio,aio的区别是啥

  5. 反射中,Class.forName和ClassLoader区别

  6. 数组和链表数据结构描述,各自的时间复杂度。

  7. 泛型的存在是用来解决什么问题。

  8. java8的新特性

  9. 简单讲讲tomcat结构,以及其类加载器流程,线程模型等。

  10. 讲讲Spring加载流程

  11. Spring如何管理事务的。

  12. Spring怎么配置事务(具体说出一些关键的xml 元素)

  13. 多线程的几种实现方式,什么是线程安全

  14. volatile的原理,作用,能代替锁么。

  15. synchronized的原理是什么,一般用在什么地方(比如加在静态方法和非静态方法的区别,静态方法和非静态方法同时执行的时候会有影响吗)

  16. 解释以下名词:重排序,自旋锁,偏向锁,轻量级锁,可重入锁,公平锁,非公平锁,乐观锁,悲观锁

  17. 导致线程死锁的原因?怎么解除线程死锁

  18. 线程死锁的原因
    (1)互斥条件:一个资源每次只能被一个线程使用。
    (2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
    (3)不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
    (4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足, 就不会发生死锁。
死锁的解决方法:
a 撤消陷于死锁的全部进程;
b 逐个撤消陷于死锁的进程,直到死锁不存在;
c 从陷 于死锁的进程中逐个强迫放弃所占用的资源,直至死锁消失。
d 从另外一些进程那里强行剥夺足够数量的资源分配给死锁进程,以解除死锁状态

  1. 用过线程池吗,请说明原理,并说说newCache和newFixed有什么区别

  2. 构造函数的各个参数的含义是什么,比如coreSize,maxsize等

  3. ThreadLocal用过么,用途是什么,原理是什么,用的时候要注意什么

  4. .请谈谈你目前公司所采用的软件开发模型的看法。

  5. 请列出你最熟悉的三种Java设计模式。并谈谈你对这三种设计模式的看法。

  6. 存储过程的概念是什么,请列举存储过程的优点。

  7. HTTPS的加密方式是什么,讲讲整个加密解密流程。
    HTTPS和HTTP的区别主要如下:
    1、https协议需要CA机构的证书,一般免费证书较少,因而需要一定费用。
    2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
    3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
    4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
    以下是具体一些分析
    一、HTTP和HTTPS的基本概念
    HTTP:是用于规定浏览器和服务器之间通信的方式或者是通信的规则
    主要规定了浏览器如何给服务器发送请求信息
    也规定了服务器如何给浏览器做出回应信息.
    HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层。
    HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
    二 、HTTP和HTTPS的主要特点和工作流程
    HTTP特点
    1.支持客户/服务器模式。(C/S模式)
    2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
    3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
    4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
    5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快
    HTTP工作流程
    第一步:建立TCP/IP连接,客户端与服务器通过Socket三次握手进行连接
    第二步:客户端向服务端发起HTTP请求(例如:POST/login.html http/1.1)
    第三步:客户端发送请求头信息,请求内容,最后会发送一空白行,标示客户端请求完毕
    第四步:服务器做出应答,表示对于客户端请求的应答,例如:HTTP/1.1 200 OK
    第五步:服务器向客户端发送应答头信息
    第六步:服务器向客户端发送请求头信息后,也会发送一空白行,标示应答头信息发送完毕,接着就以Content-type要求的数据格式发送数据给客户端
    第七步:服务端关闭TCP连接,如果服务器或者客户端增Connection:keep-alive就表示客户端与服务器端继续保存连接,在下次请求时可以继续使用这次的连接
    HTTPS特点
    HTTPS是HTTP协议的修改,它加密数据并确保其机密性。其配置可保护用户在与网站交互时免于窃取个人信息和计费数据。
    1、优点
    相比于http,https可以提供更加优质保密的信息,保证了用户数据的安全性,此外https同时也一定程度上保护了服务端,使用恶意攻击和伪装数据的成本大大提高。
    2、缺点
    缺点也同样很明显,第一https的技术门槛较高,多数个人或者私人网站难以支撑,CA机构颁发的证书都是需要年费的,此外对接Https协议也需要额外的技术支持;其二,目前来说大多数网站并不关心数据的安全性和保密性,其https最大的优点对它来说并不适用;其三,https加重了服务端的负担,相比于http其需要更多的资源来支撑,同时也降低了用户的访问速度;第四,目前来说Http网站仍然大规模使用,在浏览器侧也没有特别大的差别,很多用户不关心的话根本不感知。
    HTTPS工作流程

第一步:客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。
第二步:Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
第三步:客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。
第四步:客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。
第五步:Web服务器利用自己的私钥解密出会话密钥。
第六步:Web服务器利用会话密钥加密与客户端之间的通信。

  1. IOC底层实现和执行流程
    答案:
    spring的核心是ioc容器和aop面向切面
    spring的ioc容器,就是将对象交给spring容器管理。
    ioc操作分两部分:ioc的配置文件方式、ioc的注解方式
    ioc底层原理使用技术:xml配置文件、dom4j解析xml、工厂设计模式、反射
    IOC是Inversion of Control的缩写,控制反转,就是将实例化对象的控制权交给spring的ioc容器来实例化对象
    DI是Dependency Injection的缩写,依赖注入,就是将spring容器中的对象取出来注入到需要的地方
    ioc容器的执行流程:
    a.应用程序的启动 main()
    b.创建IoC容器,实际上就是一个map的集合
    c.解析xml文件(可以为任意的名字,spring默认推荐为applicationContext.xml)
    d.初始化所有的singleten bean,也就是说,实例化配置文件中的bean节点的对象,存放到map集合中,如果有节点就做setter注入,如果有节点就做constructor注入
    e.在需要的地方获取bean实例,getBean(“…….”);
    f.根据实际的业务逻辑,做相应的业务
    g.销毁对象
    h.结束应用程序

  2. char和varchar的区别
    char(n):定长字符串,当存储数据的长度小于最大长度时,将会用空格补全,可能会存在空间浪费
    因此char类型适合存储长度固定的数据,这样既不会有空间浪费,效率还会比varchar略高一些;

varchar(n):不定长字符串,当存储数据的长度小于最大长度时,剩余的空间还可以留给别的数据使用,不会有空间浪费。
因此varchar类型适合存储长度不固定的数据(长度固定的使用char类型存储),虽然效率没有char类型高,但是不会有空间浪费;

  1. 如何通过JDBC访问数据库
    JDBC(Java数据库连接)即利用Java程序操作数据库的一门技术
    JDBC提供了连接数据库、执行sql语句及获取结果数据的各种访问数据库的方法。并为各种不同的数据库提供统一的访问接口。通过JDBC访问数据库一般需要如下步骤:
    1.注册数据库驱动
    Class.forName(“com.mysql.jdbc.Driver”);
    2.获取数据库连接
    Connection conn = DriverManager.getConnection(
    “jdbc:mysql://localhost:3306/jt_db”,
    “root”,
    “root”);
    3.获取传输器对象(Statement或PreparedStatement)
    Statement stat = conn.createStatement();
    4.利用传输器发送sql到数据库执行, 返回执行结果
    String sql = “select * from account”;
    ResultSet rs = stat.executeQuery(sql);
    5.处理结果
    while (rs.next()) {
    int id = rs.getInt(“id”);
    String name = rs.getString(“name”);
    double money = rs.getDouble(“money”);
    System.out.println(
    id+" : “+name+” : "+money);
    }
    6.释放资源(依次将ResultSet、Statement(或PreparedStatement)、Connection对象关闭)
    rs.close();
    stat.close();
    conn.close();

问:为什么要这么做呢?(1)这些对象使用完后后面几乎不会再用到,如果不释放会占用服务器的内存空间,容易造成内存溢出。(2)其中的Connection连接数是有限的,如不及时释放,别的用户可能会获取不到连接,将无法访问数据库。

  1. Statement对象和PreparedStatement对象的区别
    1、Statement传输器对象用于执行不带参数(提前将sql语句和参数拼接)的简单sql语句。如果每次执行的sql语句不同(即使sql骨架相同),数据库都要编译该sql语句。例如:
    Statement stat = conn.createStatement();
    stat.executeQuery(“select * from user where username=‘zhansan’ and password=123”);
    2、PreparedStatement对象表示预编译的sql语句的sql语句的对象,用于执行带参数的预编译sql语句:
    PreparedStatement ps = conn.prepareStatement(“select * from user where username=? and password=?”);
    ps.setString(“zhangsan”);
    ps.setString(“123”);
    ps.executeQuery();
    3、虽然Statement对象和PreparedStatement对象可以完成相同的功能。但是相比之下,PreparedStatement对象具有如下优点:
    (1)防止sql注入攻击
    PreparedStatement对象在执行sql时,提前将sql语句的骨架(骨干)发送给数据库编译并确定下来,由于sql语句的骨架已经确定,所以后面再传入的就只能是参数的值,如果参数值中包含了影响sql语句的关键字或者特殊字符,也只会当作普通文本来处理。因此不会产生sql注入攻击问题。
    (2)代码可读性好并且省去了拼接sql语句的麻烦。(见上↑)
    (3)可以提高程序执行的效率。
    不管使用哪一个传输器发送sql语句到数据库执行,都会先编译再执行,如果下次执行的sql语句和之前执行的完全相同,则会直接使用之前编译好的,将不会再次编译。
    在同一种操作中(例如根据用户名和密码查询用户),PreparedStatement对象执行的sql骨架每次都是相同的,因此只需要编译一次。效率较高。
    而Statement对象在执行sql时,每次都是将sql骨架和参数拼接好,只要参数不同,整条sql语句也就不同,因此每次都需要编译。

  2. 数据库优化及性能问题
    答案:
    数据库的优化可以从以下几个方面入手:
    1、减少数据访问(减少磁盘访问)
    2、返回更少数据(减少网络传输或磁盘访问)
    3、减少交互次数(减少网络传输)
    4、减少服务器CPU开销(减少CPU及内存开销)
    5、利用更多资源(增加资源)
    减少数据访问:正确创建索引,通过索引访问数据
    返回更少的数据:数据要分页处理,只查询返回必要的列
    减少交互次数:
     a.大量的dml操作用批处理实现,
     b.设置fetch size,一次多抓取一些数据,来减少交互次数
     c.使用存储过程,如果业务过于复杂,可以使用存储过程,可以减少网络交互次数
     d.使用ResultSet游标处理记录,设置游标ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY
    减少服务器CPU开销:
     a.使用PreparedStatement预编译,尽量减少执行计划,
     b.合理使用排序,排过序的数据现对来说查询速度会提升
     c.尽量减少比较操作
     d.如果有复杂的运算,可以放在客户端去处理,这样服务器的压力会小一些
    利用更多的资源:
     a.客户端可以通过多线程访问数据库,前提是数据库有足够的空闲处理客户端的线程
     b.提升数据库的并发处理
    熟悉sql语句的执行顺序,以此熟悉sql的优化:
    查询语句的执行顺序按照下列子句次序:
     a.from 子句:执行顺序为从后往前,从右到左
            数据量较少的表尽量放在后面
     b.where子句:执行顺序为自下而上,从右到左
            将能过滤掉最大数量的记录条件写在where子句的最右
     c.group by子句:执行顺序从左往右分组
            最好在group不用前使用where将不需要的的记录
            在group by之前过滤掉
     d.having子句:消耗资源
            尽量避免使用,having会在检索出所有的记录之后
            才对结果进行过滤,需要排序等操作,可以用where子句代替
     e.select 子句:少用号,尽量取字段名称,
            oracle在解析的过程中,通过查询数据字典将号,
            依次转换成所有的列名,消耗时间
     f.order by子句:执行顺序从左往右排序,消耗资源

  3. 在数据库中条件查询速度很慢的时候,如何优化?
    答案:
    1.建索引(a 提高查询检索的性能b 创建唯一索引c 创建主键d
    归类)
    2.减少表之间的关联
    3.优化sql,尽量让sql很快定位数据,不要让sql做全表查询,
    应该走索引,把数据量大的表排在前面
    4.简化查询字段,没用的字段不要,已经对返回结果的控制,尽
    量返回少量数据

  4. 索引的作用?和它的优点缺点是什么?
    答案:
    创建索引可以大大提高系统的性能。
    第一,通过创建唯一性索引,可以保证Oracle数据库表中每一行数据的唯一性。
    第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
    第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
    第四,在使用分组和排序子句进行数据检索时,同样可以显着减少查询中分组和排序的时间。
    第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
    索引的优点和缺点:
    优点:方便了查询,在数据量大时排序更易查询
    缺点:建立索引,系统要占用大约为表1.2倍的硬盘和内存空间来保存索引。更新数据的时候,系统必须要有额外的时间来同时对索引进行更新,以维持数据和索引的一致性。
    建立索引的原则:
    在大表上建立索引才有意义
    在where子句或是连接条件上经常引用的列上建立索引
    索引的层次不要超过4层
    很少或从不引用的字段和逻辑型的字段,如男或女(是或否)等不要建立索引

  5. 索引优化
    答案:
    索引是一种允许直接访问数据表中某一数据行的树形结构,
     为了提高查询效率引入,是独立表的对象,可以存放在与表
       不同的表空间中。
     索引记录中存有索引关键字和指向表中数据的指针(地址)
     对索引进行io操作要比对表的操作要少
     索引一旦被建立就将被oracle系统自动维护,查询语句中
     不用指定使用哪个索引
     索引是一种提高查询效率的机制
    合理使用索引提升查询效率
     为经常出现在where子句中列创建索引
     为经常出现在order by,distinct后面的字段建立索引
         如果建立的是符合索引,索引的字段顺序要和这些
         关键字后面的字段顺序一致
     为经常作为表的链接条件的列上创建索引
     不要在经常做dml操作的表上建立索引
     不要小表上建立索引
     限制表上的索引数据,索引并不是越多越好
     删除很少被使用,不合理的索引
    需要建索引的字段:
     主键:ID,PK
     外键:PRODUCT_ID,COMPANY_ID,MEMBER_ID,ORDER_ID,TRADE_ID,PAY_ID
     有对像或身份标识意义字段:HASH_CODE,USERNAME,IDCARD_NO,EMAIL,TEL_NO,IM_NO
    索引慎用字段,需要进行数据分布及使用场景详细评估:
     日期:GMT_CREATE,GMT_MODIFIED
     年月:YEAR,MONTH
     状态标志:PRODUCT_STATUS,ORDER_STATUS,IS_DELETE,VIP_FLAG
     类型:ORDER_TYPE,IMAGE_TYPE,GENDER,CURRENCY_TYPE
     区域:COUNTRY,PROVINCE,CITY
     操作人员:CREATOR,AUDITOR
     数值:LEVEL,AMOUNT,SCORE
     长字符:ADDRESS,COMPANY_NAME,SUMMARY,SUBJECT
    不适合建索引的字段:
     描述备注:DESCRIPTION,REMARK,MEMO,DETAIL
     大字段:FILE_CONTENT,EMAIL_CONTENT

  6. 如何防止表单重复提交
    答案:
    1.禁掉提交按钮。表单提交后使用JavaScript使提交按钮disable。这种方法防止心急的用户多次点击按钮。但有个问题,如果客户端把Javascript给禁止掉,这种方法就无效了。
    2.Post/Redirect/Get模式。在提交后执行页面重定向,这就是所谓的Post-Redirect-Get (PRG)模式。简言之,当用户提交了表单后,你去执行一个客户端的重定向,转到提交成功信息页面。这能避免用户按F5导致的重复提交,而其也不会出现浏览器表单重复提交的警告,也能消除按浏览器前进和后退按导致的同样问题。
    3.在session中存放一个特殊标志。当表单页面被请求时,生成一个特殊的字符标志串,存在session中,同时放在表单的隐藏域里。接受处理表单数据时,检查标识字串是否存在,并立即从session中删除它,然后正常处理数据。如果发现表单提交里没有有效的标志串,这说明表单已经被提交过了,忽略这次提交。
     
    4.在数据库里添加约束。在数据库里添加唯一约束或创建唯一索引,防止出现重复数据。这是最有效的防止重复提交数据的方法。

  7. 谈谈你对单例的理解,框架的action是不是单例,为什么?
    答案:
    单例就是指代的在内存中是一个对象
    spring mvc的action是单例对象,spring mvc是基于方法的设计,spring基于方法,粒度更细,但要小心把握像在servlet控制数据一样。spring3 mvc是方法级别的拦截,拦截到方法后根据参数上的注解,把request数据注入进去,在spring3 mvc中,一个方法对应一个request上下文。
    struts2的action不是单例对象,而sturts是基于类,每次发一次请求都会实例一个action,每个action都会被注入属性,而struts2框架是类级别的拦截,每次来了请求就创建一个Action,然后调用setter getter方法把request中的数据注入;struts2实际上是通 setter getter方法与request打交道的;struts2中,一个Action对象对应一个request上下文。

  8. 数据库中的存储过程一般在什么情况下使用
    答案:
    存储过程(Stored Procedure )是一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。
    存储过程是由流控制和SQL 语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,应用程序使用时只要调用即可。在ORACLE 中,若干个有联系的过程可以组合在一起构成程序包。
    优点:
    1.存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
    2.当对数据库进行复杂操作时(如对多个表进行Update、Insert、Query、Delete时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。
    3.存储过程可以重复使用,可减少数据库开发人员的工作量。
    4.安全性高,可设定只有某用户才具有对指定存储过程的使用权。

  9. 请描述c3p0、dhcp、proxool三种数据库连接池的区别。
    答案:
    C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。
    DBCP (Database Connection Pool)是一个依赖Jakarta commons-pool对象池机制的数据库连接池,Tomcat的数据源使用的就是DBCP。目前 DBCP 有两个版本分别是 1.3 和 1.4。1.3 版本对应的是 JDK 1.4-1.5 和 JDBC 3,而1.4 版本对应 JDK 1.6 和 JDBC 4。因此在选择版本的时候要看看你用的是什么 JDK 版本了,功能上倒是没有什么区别。
    Proxool是一个Java SQL Driver驱动程序,提供了对你选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中。完全可配置。快速,成熟,健壮。可以透明地为你现存的JDBC驱动程序增加连接池功能。

  10. 什么是数据库连接池
    所谓的池就是程序中用来共享资源的容器,比如线程池,常量池。
    而数据库连接池就是用来存放连接的容器,在开发JDBC程序时,可以将数据库连接存放在池子(其实就是一个容器,比如数组或者集合等)中,用于在整个程序中共享连接。

  11. 连接池的工作原理(即为什么要使用连接池?)
    通过传统JDBC操作数据库,需要连接时就创建一个连接,用完后需要将连接关闭还给数据库。当并发访问的用户非常多时,这种频繁开关连接的操作将会十分的耗费资源,并且效率低下。
    因此我们可以在程序中创建一个连接池,当程序启动时就初始化一批连接放在池中供整个程序共享。当需要连接时从连接池中获取一个连接进行使用,当用完连接后将连接还回连接池中。这样一来既可以减少连接开关的次数,也可以实现连接的复用,从而提高程序执行的效率。

  12. 数据库隔离级别有哪些,各自的含义是什么,MYSQL默认的隔离级别是是什么。
    事务隔离级别分四个等级,在相同数据环境下,对数据执行相同的操作,设置不同的隔离级别,可能导致不同的结果。不同事务隔离级别能够解决的数据并发问题的能力也是不同的。
    set tx_isolation=‘read-uncommitted’;
    1、READ UNCOMMITTED(读未提交数据)
    安全级别最低, 可能出现任何事务并发问题(比如脏读、不可以重复读、幻读等)
    性能最好(不使用!!)
    2、READ COMMITTED(读已提交数据)(Oracle默认)
    防止脏读,没有处理不可重复读,也没有处理幻读;
    性能比REPEATABLE READ好
    3、Repeatable READ(可重复读)(MySQL默认)
    防止脏读和不可重复读,不能处理幻读问题;
    性能比SERIALIZABLE好
    4、SERIALIZABLE(串行化)
    不会出现任何并发问题,因为它是对同一数据的访问是串行的,非并发访问的;
    性能最差;

MySQL的默认隔离级别为REPEATABLE READ,即可以防止脏读和不可重复读
82. 什么是幻读。
在一个事务中,对同一个数据的两次查询结果不一致,是因为中间有人做了插入或者删除操作.
83. MYSQL有哪些存储引擎,各自优缺点。
常见的存储引擎:MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)等,以及最常用的MyISAM与InnoDB两个引擎
☞ 重点介绍三个:MyISAM、InnoDB、MEMORY。
【1】MyISAM: ①、拥有较高的插入,查询速度。②、不支持事务,行级锁和外键约束的功能。③、使用表级锁,并发性能差。④、主机宕机后,MyISAM表易损坏,灾难恢复性不佳。⑤、可以配合锁,实现操作系统下数据的复制备份、迁移。⑥、只缓存索引,数据的缓存是通过操作系统缓存区来实现的,可能引发过多的系统调用且效率不佳。⑦、数据紧凑存储,因此可获得更小的索引和更快的全表扫描性能。
【2】InnoDB:5.5版本后Mysql的默认数据库,事务型数据库的首选引擎,①、支持ACID事务。②、支持行级锁定。③、灾难恢复性好。④、支持外键关联。⑤、支持热备份。⑥、对于InnoDB引擎中的表,其数据的物理组织是簇表(Cluster Table),主键索引和数据是在一起的,数据按主键的顺序物理分布。⑦、实现了缓冲管理,不仅能缓冲索引也能缓冲数据,并且能够自动创建散列索引以加快数据的获取。
【3】MEMORY:①、所有数据置于内存的存储引擎,拥有极高的插入,更新和查询效率。但是会占用和数据量成正比的内存空间。②、其内容会在Mysql重新启动时丢失,复制维护时需要小心。③、使用表级锁,虽然内存访问速度快,但是频繁的读写,表级锁会成为瓶颈。④、只支持固定大小的行,varchar类型的字段会存储为固定长度的Char类型,浪费空间。⑤、不支持TEXT、BLOB字段,当有些查询需要使用临时表时(因为是存在于内存中,所以这种类型常应用于临时表中),如果表中有TEXT、BLOB字段,那么会转换为基于磁盘的MyISAM表,严重降低性能。⑥、由于内存资源成本比较昂贵,一般不建议设置过大的内存表,如果内存表满了,可通过清除数据或调整内存表参数来避免报错。⑦、MEMORY表在所有客户端之间共享。

  1. 谈谈对 XML 的理解?说明 Web 应用中 Web.xml 文件的作用?
    答案:
      XML(Extensible Markup Language)即可扩展标记语言,它与 HTML 一样,都是 SGML(Standard Generalized Markup Language,标准通用标记语言)。Xml 是 Internet 环境中跨平台的,依赖于内容 的技术,是当前处理结构化文档信息的有力工具。扩展标记语言 XML 是一种简单的数据存储语言,使 用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然 XML 占用的空间比二进制数 据要占用更多的空间,但 XML 极其简单易于掌握和使用。
    web.xml 的作用是配置欢迎页,servlet,filter,listener 等的。

  2. 请简述html语言和xml语言的区别。
    答案:
    超文本标记语言(英文:HyperText MarkupLanguage,HTML)是为“网页创建和其它可在网页浏览器中看到的信息”设计的一种标记语言。HTML被用来结构化信息——例如标题、段落和列表等等,也可用来在一定程度上描述文档的外观和语义。
    XML即ExtentsibleMarkup Language(可扩展标记语言),是用来定义其它语言的一种元语言,其前身是SGML(标准通用标记语言)。它没有标签集(tagset),也没有语法规则(grammatical rule),但 是它有句法规则(syntax rule)。任何XML文档对任何类型的应用以及正确的解析都必须是良构的(well-formed),即每一个打开的标签都必须有匹配的结束标签,不得含有次序颠倒的标签,并且在语句构成上应符合技术规范的要求。XML文档可以是有效的(valid),但并非一定要求有效。所谓有效文档是指其符合其文档类型定义(DTD)的文档。如果一个文档符合一个模式(schema)的规定,那么这个文档是模式有效的(schema valid)。
    HTML与XML的区别:
    (一)、语法要求不同:
    在html中不区分大小写,在xml中严格区分。
    在HTML中,有时不严格,如果上下文清楚地显示出段落或者列表键在何处结尾,那么你可以省略
    或者
    之类的结束标记。在XML中,是严格的树状结构,绝对不能省略掉结束标记。
    在XML中,拥有单个标记而没有匹配的结束标记的元素必须用一个/ 字符作为结尾。这样分析器就知道不用查找结束标记了。
    在XML中,属性值必须分装在引号中。在HTML中,引号是可用可不用的。
    在HTML中,可以拥有不带值的属性名。在XML中,所有的属性都必须带有相应的值。
    在XML文档中,空白部分不会被解析器自动删除;但是html是过滤掉空格的。
    (二)、标记不同:
    1、html使用固有的标记;而xml没有固有的标记。
    2、Html标签是预定义的;XML标签是免费的、自定义的、可扩展的。
    (三)、作用不同:
    html是用来显示数据的;xml是用来描述数据、存放数据的,所以可以作为持久化的介质!Html将数据和显示结合在一起,在页面中把这数据显示出来;xml
    则将数据和显示分开。 XML被设计用来描述数据,其焦点是数据的内容。HTML被设计用来显示数据,其焦点是数据的外观。
    xml不是HTML的替代品,xml和html是两种不同用途的语言。 XML 不是要替换 HTML;实际上XML 可以视作对 HTML 的补充。XML 和HTML 的目标不同HTML 的设计目标是显示数据并集中于数据外观,而XML的设计目标是描述数据并集中于数据的内容。
    没有任何行为的XML。与HTML 相似,XML 不进行任何操作。(共同点)
    对于XML最好的形容可能是: XML是一种跨平台的,与软、硬件无关的,处理与传输信息的工具。
    XML未来将会无所不在。XML将成为最普遍的数据处理和数据传输的工具。

  3. XML和JSON各自的优缺点是什么?
    答案:
    (1).XML的优缺点
    <1>.XML的优点
      A.格式统一,符合标准;
      B.容易与其他系统进行远程交互,数据共享比较方便。
    <2>.XML的缺点
      A.XML文件庞大,文件格式复杂,传输占带宽;
      B.服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护;
      C.客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码;
      D.服务器端和客户端解析XML花费较多的资源和时间。
    (2).JSON的优缺点
    <1>.JSON的优点:
      A.数据格式比较简单,易于读写,格式都是压缩的,占用带宽小;
      B.易于解析,客户端JavaScript可以简单的通过eval()进行JSON数据的读取;
      C.支持多种语言,包括ActionScript, C, C#, ColdFusion, Java, JavaScript, Perl, PHP, Python, Ruby等服务器端语言,便于服务器端的解析;
      D.在PHP世界,已经有PHP-JSON和JSON-PHP出现了,偏于PHP序列化后的程序直接调用,PHP服务器端的对象、数组等能直接生成JSON格式,便于客户端的访问提取;
      E.因为JSON格式能直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,且完成任务不变,并且易于维护。
    <2>.JSON的缺点
      A.没有XML格式这么推广的深入人心和喜用广泛,没有XML那么通用性;
      B.JSON格式目前在Web Service中推广还属于初级阶段。
    3.XML和JSON的优缺点对比
    (1).可读性方面。
    JSON和XML的数据可读性基本相同,JSON和XML的可读性可谓不相上下,一边是建议的语法,一边是规范的标签形式,XML可读性较好些。
    (2).可扩展性方面。
    XML天生有很好的扩展性,JSON当然也有,没有什么是XML能扩展,JSON不能的。
    (3).编码难度方面。
    XML有丰富的编码工具,比如Dom4j、JDom等,JSON也有json.org提供的工具,但是JSON的编码明显比XML容易许多,即使不借助工具也能写出JSON的代码,可是要写好XML就不太容易了。
    (4).解码难度方面。
    XML的解析得考虑子节点父节点,让人头昏眼花,而JSON的解析难度几乎为0。这一点XML输的真是没话说。
    (5).流行度方面。
    XML已经被业界广泛的使用,而JSON才刚刚开始,但是在Ajax这个特定的领域,未来的发展一定是XML让位于JSON。到时Ajax应该变成Ajaj(Asynchronous Javascript and JSON)了。
    (6).解析手段方面。
    JSON和XML同样拥有丰富的解析手段。
    (7).数据体积方面。
    JSON相对于XML来讲,数据的体积小,传递的速度更快些。
    (8).数据交互方面。
    JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互。
    (9).数据描述方面。
    JSON对数据的描述性比XML较差。
    (10).传输速度方面。
    JSON的速度要远远快于XML。

  4. jsp有哪些动作?作用分别是什么?
    答案:
    JSP共有以下6种基本动作
    jsp:include:在页面被请求的时候引入一个文件。
    jsp:useBean:寻找或者实例化一个JavaBean。
    jsp:setProperty:设置JavaBean的属性。
    jsp:getProperty:输出某个JavaBean的属性。
    jsp:forward:把请求转到一个新的页面。
    jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记。

  5. Jsp是怎么转化为html的?
    答案:
    JSP(Java Server Page)看这个意思就知道是Java服务端的页面,所以它是动态的,它是需要经过JDK编译后把内容发给客户端去显 示,我们都知道,Java文件编译后会产生一个class文件,最终执行的就是这个class文件,JSP也一样,它也要编译成class文件!JSP不 止要编译,它还得要转译,首先把JSP转译成一个Servlet文件,然后在编译成class文件。当用户访问JSP时就执行了class文件
    在servlet文件中把要输出到浏览器的页面信息,通过,out.write方式写到浏览器端,而out对象就通过response对象获取的,其本质就是通过响应对象,把html的信息响应到浏览器端

  6. request 和session的区别?
    答案:
    request
    request范围较小一些,只是一个请求。
    request对象的生命周期是针对一个客户端(说确切点就是一个浏览器应用程序)的一次请求,当请求完毕之后,request里边的内容也将被释放点 。
    简单说就是你在页面上的一个操作,request.getParameter()就是从上一个页面中的url、form中获取参数。
    但如果一个request涉及多个类,后面还要取参数,可以用request.setAttribute()和request.getAttribute()。
    但是当结果输出之后,request就结束了。
    session
    session可以跨越很多页面。
    而session的生命周期也是针对一个客户端,但是却是在别人设置的会话周期内(一般是20-30分钟),session里边的内容将一直存在,即便关闭了这个客户端浏览器 session也不一定会马上释放掉的。
    可以理解是客户端同一个IE窗口发出的多个请求。
    这之间都可以传递参数,比如很多网站的用户登录都用到了。
    比较
    request占用资源比较少,安全性也比较高,可是相对来说缺乏持续性。
    session则相对来说对资源的消耗会大点,安全性相对来说也会稍微低点,可是它能实现比如会话跟踪技术。
    如果可以使用request的情况下,尽量使用request 因为相对于服务器来说资源的消耗还是比较重要的。
    在传递页面过程中request传递到下一页面就不能再传递了,而sesison却不如此,即request仅限于2个相邻的页面
    每按一个网页上的一个链接就是一个新的request,当服务器返回给浏览器一个response时,request就结束了,此时保存在request中的对象就不存在了,
    但是当你用一个浏器连到服务器上时application-server会新开一个session给你,当连接超时或浏览器关闭时session才销毁。
    所以说作用的范围是不一样,session也就可以跟踪用户的状态。
    session相当于是一个客户端的全局变量,
    比如A机与服务器第一次访问时设置session.setAttribute(“aaa”)=”ComputerA”.则在A机访问继续访问的任意一个页面都可以取的session.getAttribute(“aaa”)的值是ComputerA;
    request是某一次访问的局域变量,
    生命周期只是一次请求。因此login的变量应该放在session中

  7. 请介绍自己在WEB开发中用到的、知道的各种技术、架构、第三方控件,并逐一进行详细说明。
    答案:
    mvc,web开发结构
    jsp,java服务器页
    ajax,异步与服务器交互
    json,一种轻量级数据格式
    commonsfileupload,文件上传
    itext,pdf操作组件
    poi,office操作组件

  8. 讲一下mybaits的缓存
    答案:
    一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。
    一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。
    二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
    二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。
    如果缓存中有数据就不用从数据库中获取,大大提高系统性能。

  9. Mybatis工作原理是什么?他和hibernate有什么区别?
    答案:
    MyBatis应用程序根据XML配置文件创建SqlSessionFactory,SqlSessionFactory在根据配置,配置来源于两个地方,一处是配置文件,一处是Java代码的注解,获取一个SqlSession。SqlSession包含了执行sql所需要的所有方法,可以通过SqlSession实例直接运行映射的sql语句,完成对数据的增删改查和事务提交等,用完之后关闭SqlSession。
    Mybatis和hibernate区别:
    a.Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session来开启执行事务和SQL语句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。
    b.Hibernate和MyBatis都支持JDBC和JTA事务处理。
    c.MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
    d.MyBatis容易掌握,而Hibernate门槛较高。
    e.Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。
    f.Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
    g.Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。
    h.Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。

  10. 使用异常有如下几个原则
    答案:
    使用异常有如下几个原则:
    a、尽量避免使用异常,将异常情况提前检测出来。
    b、不要为每个可能会出现异常的语句都设置try和catch。
    c、避免在方法中抛出(throw)或者捕获(catch)运行时异常RuntimeException和Error。
    d、避免总是catch Exception或Throwable,而要catch具体的异常类。这样可以使程序更加清晰。
    e、不要压制、隐瞒异常。将不能处理的异常往外抛,而不是捕获之后随便处理。
    f、不要在循环中使用try…catch,尽量将try…catch放在循环外或者避免使用。
    g、在catch Exception中不只要处理异常,有时还要出栈、对前面的一些变量进行处理,否则可能出现bug

  11. JAVA有那些设计模式。
    答案:
    单例:spring ioc默认是singleton ,spring mvc的action也是singleton
    策略:spring的di,spring aop的jdk的动态代理,spring jdbc的RowMapper的结果集解析
    迭代:集合的遍历
    代理:spring的aop,spring mvc和struts2和servlet的拦截器
    具体的设计模式原理,自行解决。

  12. BIO和NIO的区别 怎么解决线程高并发的问题
    答案:
    BIO(Blocking IO)阻塞IO
    NIO(Non-Blocking IO)非阻塞IO
    共同点:两者都是同步操作。即必须先进行IO操作后才能进行下一步操作。
    不同点:BIO多线程对某资源进行IO操作时会出现阻塞,即一个线程进行IO操作完才会通知另外的IO操作线程,必须等待。
    NIO多线程对某资源进行IO操作时会把资源先操作至内存缓冲区。然后询问是否IO操作就绪,是则进行IO操作,否则进行下一步操作,然后不断的轮询是否IO操作就绪,直到IO操作就绪后进行相关操作。
    通过nio实现高并发:
    原来的 I/O 库(在 java.io.中) 与 NIO 最重要的区别是数据打包和传输的方式。正如前面提到的,原来的 I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。
    面向流 的 I/O 系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。为流式数据创建过滤器非常容易。链接几个过滤器,以便每个过滤器只负责单个复杂处理机制的一部分,这样也是相对简单的。不利的一面是,面向流的 I/O 通常相当慢。
    一个 面向块 的 I/O 系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。
    在 JDK 1.4 中原来的 I/O 包和 NIO 已经很好地集成了。 java.io. 已经以 NIO 为基础重新实现了,所以现在它可以利用 NIO 的一些特性。例如, java.io.* 包中的一些类包含以块的形式读写数据的方法,这使得即使在更面向流的系统中,处理速度也会更快。
    也可以用 NIO 库实现标准 I/O 功能。例如,可以容易地使用块 I/O 一次一个字节地移动数据。但是正如您会看到的,NIO 还提供了原 I/O 包中所没有的许多好处。
    通道 和 缓冲区 是 NIO 中的核心对象,几乎在每一个 I/O 操作中都要使用它们。
    通道是对原 I/O 包中的流的模拟。到任何目的地(或来自任何地方)的所有数据都必须通过一个 Channel 对象。一个 Buffer 实质上是一个容器对象。发送给一个通道的所有对象都必须首先放到缓冲区中;同样地,从通道中读取的任何数据都要读到缓冲区中。
    Buffer 是一个对象, 它包含一些要写入或者刚读出的数据。 在 NIO 中加入 Buffer 对象,体现了新库与原 I/O 的一个重要区别。在面向流的 I/O 中,您将数据直接写入或者将数据直接读到 Stream 对象中。
    在 NIO 库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的。在写入数据时,它是写入到缓冲区中的。任何时候访问 NIO 中的数据,您都是将它放到缓冲区中。
    缓冲区实质上是一个数组。通常它是一个字节数组,但是也可以使用其他种类的数组。但是一个缓冲区不 仅仅 是一个数组。缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程。
    Channel是一个对象,可以通过它读取和写入数据。拿 NIO 与原来的 I/O 做个比较,通道就像是流。
    正如前面提到的,所有数据都通过 Buffer 对象来处理。您永远不会将字节直接写入通道中,相反,您是将数据写入包含一个或者多个字节的缓冲区。同样,您不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。

  13. Spring框架的优点都有什么?
    答案:
    Spring是分层的架构,你可以选择使用你需要的层而不用管不需要的部分;
    Spring是POJO编程,POJO编程使得可持续构建和可测试能力提高;
    依赖注入和IoC使得JDBC操作简单化;
    Spring是开源的免费的;
    Spring使得对象管理集中化合简单化。

  14. 列出IOC的3种主要注入方式?
    答案:
    1.构造方法注入;
    2.设置属性注入;
    3.接口注入。

  15. 构造器注入和 setter 依赖注入,那种方式更好?
    答案:
    每种方式都有它的缺点和优点。构造器注入保证所有的注入都被初始化,但是 setter 注入提供更好的灵活性来设置可选依赖。如果使用 XML 来描述依赖,Setter 注入的可读写会更强。经验法则是强制依赖使用构造器注入,可选依赖使用 setter 注入。

  16. 简述MVC模式的含义,并用图表示web应用中MVC模式中每部分之间的关系。
    答案:
    V即View视图是指用户看到并与之交互的界面。比如由html元素组成的网页界面,或者软件的客户端界面。MVC的好处之一在于它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,它只是作为一种输出数据并允许用户操纵的方式。
    M即model模型是指模型表示业务规则。在MVC的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。
    C即controller控制器是指控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。

  17. 请描述一下spring MVC工作原理。
    答案:
    1、客户端发出一个http请求给web服务器,web服务器对http请求进行解析,如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),web容器将请求转交给DispatcherServlet.
    2、DipatcherServlet接收到这个请求之后将根据请求的信息(包括URL、Http方法、请求报文头和请求参数Cookie等)以及HandlerMapping的配置找到处理请求的处理器(Handler)。
    3-4、DispatcherServlet根据HandlerMapping找到对应的Handler,将处理权交给Handler(Handler将具体的处理进行封装),再由具体的HandlerAdapter对Handler进行具体的调用。
    5、Handler对数据处理完成以后将返回一个ModelAndView()对象给DispatcherServlet。
    6、Handler返回的ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet通过ViewResolver将逻辑视图转化为真正的视图View。
    7、Dispatcher通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端。

  18. 什么是 Ajax,优点是什么?
    答案:
    本质是浏览器的特殊对象,异步发出请求,服务器返回更新页面不用刷新页面
    优点:减轻服务器的负担,按需取数据,最大程度的减少冗余请求
    局部刷新页面,减少用户心理和实际的等待时间,带来更好的用户体验
    基于xml标准化,并被广泛支持,不需安装插件等
    进一步促进页面和数据的分离
    缺点:AJAX大量的使用了javascript和ajax引擎,这些取决于浏览器的支持.在编写的时候考虑对浏览器的兼容性.
    AJAX只是局部刷新,所以页面的后退按钮是没有用的.

  19. 高并发下,如何做到安全的修改同一行数据。
    1、使用悲观锁
    悲观锁本质是当前只有一个线程执行操作,排斥外部请求的修改。遇到加锁的状态,就必须等待。结束了唤醒其他线程进行处理。虽然此方案的确解决了数据安全的问题,但是,我们的场景是“高并发”。也就是说,会很多这样的修改请求,每个请求都需要等待“锁”,某些线程可能永远都没有机会抢到这个“锁”,这种请求就会死在那里。同时,这种请求会很多,瞬间增大系统的平均响应时间,结果是可用连接数被耗尽,系统陷入异常。

2、FIFO(First Input First Output,先进先出)缓存队列思路
直接将请求放入队列中,就不会导致某些请求永远获取不到锁。看到这里,是不是有点强行将多线程变成单线程的感觉哈。

然后,我们现在解决了锁的问题,全部请求采用“先进先出”的队列方式来处理。那么新的问题来了,高并发的场景下,因为请求很多,很可能一瞬间将队列内存“撑爆”,然后系统又陷入到了异常状态。或者设计一个极大的内存队列,也是一种方案,但是,系统处理完一个队列内请求的速度根本无法和疯狂涌入队列中的数目相比。也就是说,队列内的请求会越积累越多,最终Web系统平均响应时间还是会大幅下降,系统还是陷入异常。

3、使用乐观锁
这个时候,我们就可以讨论一下“乐观锁”的思路了。乐观锁,是相对于“悲观锁”采用更为宽松的加锁机制,大都是采用带版本号(Version)更新。实现就是,这个数据所有请求都有资格去修改,但会获得一个该数据的版本号,只有版本号符合的才能更新成功,其他的返回抢购失败。这样的话,我们就不需要考虑队列的问题,不过,它会增大CPU的计算开销。但是,综合来说,这是一个比较好的解决方案。

  1. 乐观锁和悲观锁是什么,INNODB的标准行级锁有哪2种,解释其含义。
    ♩ 乐观锁(Optimistic Concurrency Control,缩写”OCC”):是一种并发控制的方法。乐观的认为多用户并发的事务在处理时不会彼此互相影响,各事务能够在使用锁的情况下处理各自的数据。在提交更新数据之前,每个事务会先检查该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。不过,当需求多为更新数据时,就会增大数据之间的冲突,也就增大CPU的计算开销,此时不建议使用。
    ♪ 数据是否修改的标准是:在表中的数据进行操作时,先给数据表最新的数据加一个版本(version)字段,每操作一次,将那条记录的版本号加1。也就是先查询出那条记录,获取出version字段,修改完数据后准备提交之前,先判断此刻version的值是否与刚刚查询出来时的version的值相等,如果相等,则说明这段期间,没有其他程序对其进行操作,则可以执行更新,将version字段的值加1;如果更新时发现此刻的version值与刚刚获取出来的version的值不相等,则说明这段期间已经有其他程序对其进行操作了,则不进行更新操作。
  ♫ 悲观锁(Pessimistic Concurrency Control,缩写”PCC”):与乐观锁相对应的就是悲观锁了。悲观锁就是在操作数据时,认为此操作会出现数据冲突,所以在进行每次操作时都要通过获取锁才能进行对相同数据的操作,这点跟java中的synchronized很相似,所以悲观锁需要耗费较多的时间。所以悲观并发控制主要用于数据争用激烈的环境,以及发生并发冲突时使用锁保护数据的成本要低于回滚事务的成本的环境中。另外与乐观锁相对应的,悲观锁是由数据库自己实现了的,要用的时候,我们直接调用数据库的相关语句就可以了。说到这里,由悲观锁涉及到的另外两个锁概念就出来了,它们就是共享锁与排它锁。共享锁和排它锁是悲观锁的不同的实现,它俩都属于悲观锁的范畴。

要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。set autocommit=0;

InnoDB的标准行级锁有哪2种:
♬共享锁:共享锁指的就是对于多个不同的事务,对同一个资源共享同一个锁,在执行语句后面加上lock in share mode就代表对某些资源加上共享锁。
♬排它锁:排它锁与共享锁相对应,就是指对于多个不同的事务,对同一个资源只能有一把锁。在需要执行的语句后面加上for update就可以了。对于update,insert,delete语句会自动加排它锁。
总结:乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机智的其实都是提供的乐观锁。 相反,如果经常发生冲突,上层应用会不断进行 retry,这样反而降低了性能,所以这种情况下用悲观锁比较合适
104. 数据库会死锁吗,举一个死锁的例子,mysql怎么解决死锁。
会产生死锁
要解决死锁首先要了解产生死锁的原因:①、系统资源不足。②、进程运行推进的顺序不合适。③、资源分配不当等。
㊧、如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。
▶产生死锁的四个必要条件:①、互斥条件:一个资源每次只能被一个进程使用。
②、请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
③、不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
④、循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
▶这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
▶这里提供两个解决数据库死锁的方法:
1)重启数据库。
2)杀掉抢资源的进程:先查哪些进程在抢资源:

SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
☎、杀掉抢资源的进程:
105. MYsql的索引原理,索引的类型有哪些,如何创建合理的索引,索引如何优化。
MySql索引的原理:1)、通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。
2)、索引是通过复杂的算法,提高数据查询性能的手段。从磁盘io到内存io的转变。
MySql索引原理参考博客:https://blog.csdn.net/u013235478/article/details/50625677
MySql索引的类型:1)、普通索引index:加速查找
2)、唯一索引:①、主键索引:primary key:加速查找+主键唯一约束且不为空。
②、唯一索引:unique:加速查找+主键唯一约束。
3)、联合索引:①、primary key(id,name):联合主键索引。
②、unique(id,name):联合唯一索引。
③、unique(id,name):联合普通索引。
4)、全文索引fulltext:用于搜索很长一篇文章的时候,效果最好。
5)、空间索引spatial:了解就好,几乎不用
创建索引的原则:1)、最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
2)、=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。
3)、尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录。
4)、索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’)。
5)、尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可

  1. 什么是Servlet?
    HTML只能保存静态网页内容,而在实际开发中,往往需要给用户展示动态页面。Servlet就可以用来生成动态页面。
    (所谓的动态页面是指:能够根据不同时间、不同用户而显示不同内容的页面,比如:留言板、订单页面、购物车页面等)
    什么是Servlet呢?Servlet是SUN公司提供的动态Web资源开发技术,其本质上就是采用Java语言编写的服务器端程序。这段程序必须要放在Servlet容器中,由容器调用才可以执行。其主要作用是处理客户端的请求,处理结果由服务器响应给浏览器。例如:
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.getWriter().write(“Hello…”+new Date().toString());

  2. JSP 和 Servlet 有哪些相同点和不同点, 他们之间的联系是什么?
    1.相同点: JSP和Servlet都可以用于接收客户端请求、处理请求,并做出响应。
    2.不同点:
    (1) Servlet更适合处理逻辑,不适合作数据展示(即响应页面)
    (2) JSP更适合展示数据,不适合处理逻辑
    (3) Servlet没有内置对象、JSP中有内置对象
    (4) 在MVC设计模式中,Servlet属于控制器(Controller),JSP属于视图(View)
    3.两者之间的联系:
    JSP在一次被访问时,JSP引擎会对JSP进行编译,编译后就变成了Servlet,本质上就是一个Servlet。

  3. 你对Spring的理解。
    1.Spring实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式),这个类名为BeanFactory(实际上是一个接口),在程序中通常BeanFactory的子类ApplicationContext。Spring相当于一个大的工厂类,在其配置文件中通过元素配置用于创建实例对象的类名和实例对象的属性。

  4. Spring提供了对IOC良好支持,IOC是一种编程思想,是一种架构艺术,利用这种思想可以很好地实现模块之间的解耦。IOC也称为DI(Depency Injection),什么叫依赖注入呢?
    譬如,Class Programmer {
    Computer computer = null;
    public void code(){
    //Computer computer = new IBMComputer();
    //Computer computer = beanfacotry.getComputer();
    computer.write();
    } public void setComputer(Computer computer) {
    this.computer = computer;
    }
    }
    另外两种方式都由依赖,第一个直接依赖于目标类,第二个把依赖转移到工厂上,第三个彻底与目标和工厂解耦了。在spring的配置文件中配置片段如下:

另外两种方式都由依赖,第一个直接依赖于目标类,第二个把依赖转移到工厂上,第三个彻底与目标和工厂解耦了。在spring的配置文件中配置片段如下:

3. Spring提供了对AOP技术的良好封装, AOP称为面向切面编程,就是系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码,例如,加入日志,加入权限判断,加入异常处理,这种应用称为AOP。实现AOP功能采用的是代理技术,客户端程序不再调用目标,而调用代理类,代理类与目标类对外具有相同的方法声明,有两种方式可以实现相同的方法声明,一是实现相同的接口,二是作为目标的子类在,JDK中采用Proxy类产生动态代理的方式为某个接口生成实现类,如果要为某个类生成子类,则可以用CGLI B。在生成的代理类的方法中加入系统功能和调用目标类的相应方法,系统功能的代理以Advice对象进行提供,显然要创建出代理对象,至少需要目标类和Advice类。spring提供了这种支持,只需要在spring配置文件中配置这两个元素即可实现代理和aop功能,例如,
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值