常见Java面试题

        最近有以前的同事想从实施转开发,工作太忙让我帮他整理一些面试题,还好有一点底子,不然总结起来还就有点吃力。 

对自己以后想从事这方面也有一点帮助把。  


1.Mybatis和Hibernate的区别

第一方面:开发速度的对比

      就开发速度而言,Hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。

      比起两者的开发速度,不仅仅要考虑到两者的特性及性能,更要根据项目需求去考虑究竟哪一个更适合项目开发,比如:一个项目中用到的复杂查询基本没有,就是简单的增删改查,这样选择hibernate效率就很快了,因为基本的sql语句已经被封装好了,根本不需要你去写sql语句,这就节省了大量的时间,但是对于一个大型项目,复杂语句较多,这样再去选择hibernate就不是一个太好的选择,选择mybatis就会加快许多,而且语句的管理也比较方便。

第二方面:开发工作量的对比

     Hibernate和MyBatis都有相应的代码生成工具。可以生成简单基本的DAO层方法。针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。

第三方面:sql优化方面

      Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。而Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。

      Hibernate HQL语句的调优需要将SQL打印出来,而Hibernate的SQL被很多人嫌弃因为太丑了。MyBatis的SQL是自己手动写的所以调整方便。但Hibernate具有自己的日志统计。Mybatis本身不带日志统计,使用Log4j进行日志记录。

第四方面:对象管理的对比

      Hibernate 是完整的对象/关系映射解决方案,它提供了对象状态管理(state management)的功能,使开发者不再需要理会底层数据库系统的细节。也就是说,相对于常见的 JDBC/SQL 持久层方案中需要管理 SQL 语句,Hibernate采用了更自然的面向对象的视角来持久化 Java 应用中的数据。

      换句话说,使用 Hibernate 的开发者应该总是关注对象的状态(state),不必考虑 SQL 语句的执行。这部分细节已经由 Hibernate 掌管妥当,只有开发者在进行系统性能调优的时候才需要进行了解。而MyBatis在这一块没有文档说明,用户需要对对象自己进行详细的管理。
第五方面:缓存机制

Hibernate缓存

      Hibernate一级缓存是Session缓存,利用好一级缓存就需要对Session的生命周期进行管理好。建议在一个Action操作中使用一个Session。一级缓存需要对Session进行严格管理。

      Hibernate二级缓存是SessionFactory级的缓存。 SessionFactory的缓存分为内置缓存和外置缓存。内置缓存中存放的是SessionFactory对象的一些集合属性包含的数据(映射元素据及预定SQL语句等),对于应用程序来说,它是只读的。外置缓存中存放的是数据库数据的副本,其作用和一级缓存类似.二级缓存除了以内存作为存储介质外,还可以选用硬盘等外部存储设备。二级缓存称为进程级缓存或SessionFactory级缓存,它可以被所有session共享,它的生命周期伴随着SessionFactory的生命周期存在和消亡。

MyBatis缓存

      MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。

      默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:  <cache/>

字面上看就是这样。这个简单语句的效果如下:

  1. 映射语句文件中的所有 select 语句将会被缓存。
  2. 映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
  3. 缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
  4. 根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。
  5. 缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
  6. 缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而 且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

所有的这些属性都可以通过缓存元素的属性来修改。

比如: <cache  eviction=”FIFO”  flushInterval=”60000″  size=”512″  readOnly=”true”/>

这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会 导致冲突。可用的收回策略有, 默认的是 LRU:

  1. LRU – 最近最少使用的:移除最长时间不被使用的对象。
  2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
  3. SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
  4. WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒 形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。

size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的 可用内存资源数目。默认值是1024。

readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓 存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存 会返回缓存对象的拷贝(通过序列化) 。这会慢一些,但是安全,因此默认是 false。

相同点:Hibernate和Mybatis的二级缓存除了采用系统默认的缓存机制外,都可以通过实现你自己的缓存或为其他第三方缓存方案,创建适配器来完全覆盖缓存行为。

不同点:Hibernate的二级缓存配置在SessionFactory生成的配置文件中进行详细配置,然后再在具体的表-对象映射中配置是那种缓存。

MyBatis的二级缓存配置都是在每个具体的表-对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓存机制。并且Mybatis可以在命名空间中共享相同的缓存配置和实例,通过Cache-ref来实现。

两者比较:因为Hibernate对查询对象有着良好的管理机制,用户无需关心SQL。所以在使用二级缓存时如果出现脏数据,系统会报出错误并提示。

而MyBatis在这一方面,使用二级缓存时需要特别小心。如果不能完全确定数据更新操作的波及范围,避免Cache的盲目使用。否则,脏数据的出现会给系统的正常运行带来很大的隐患。

第六方面:总结

对于总结,大家可以到各大java论坛去看一看

相同点:Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session来开启执行事务和SQL语句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。

  • Hibernate和MyBatis都支持JDBC和JTA事务处理。

Mybatis优势

  • MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
  • MyBatis容易掌握,而Hibernate门槛较高。

Hibernate优势

  • Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。
  • Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
  • Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。
  • Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。

个人总结

  • Hibernate功能强大,数据库无关性好,O/R映射能力强,如果你对Hibernate相当精通,而且对Hibernate进行了适当的封装,那么你的项目整个持久层代码会相当简单,需要写的代码很少,开发速度很快,非常爽。
  • Hibernate的缺点就是学习门槛不低,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate方面需要你的经验和能力都很强才行。
  • iBATIS入门简单,即学即用,提供了数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美。
  • iBATIS的缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。

 

2.Spring MVC 与Struts2 的不同之处 ?

  1. 请求处理机制:spring mvc 是基于方法的设计,而 sturts2 是基于,每次发一次请求都会实例一个 action,每个 action 都会被注入属性,而 spring 基于方法,粒度更细。
  2. 参数传递:struts2 是在接受参数的时候,可以用属性来接受参数,这就说明参数是让多个方法共享的。
  3. 设计思想上:struts 2更加符合 oop 的编程思想, spring 就比较谨慎,在 servlet 上扩展
  4. intercepter 的实现机制:struts 2有以自己的 interceptor 机制,spring mvc 用的是独立的 AOP 方式。这样导致 struts 的配置文件量还是比 spring mvc 大,虽然 struts2 的配置能继承,所以我觉得论使用上来讲,spring mvc 使用更加简洁,开发效率 Spring MVC 确实比 struts2

   3. 说说&和&&的区别。

        &和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。

        &&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式

        &还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。

4.Integer与int的区别

        int是java提供的8种原始数据类型之一。Java为每个原始类型提供了封装类,Integer是java为int提供的封装类。int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况。

        例如:要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer。在JSP开发中,Integer的默认为null,所以用el表达式在文本框中显示时,值为空白字符串,而int默认的默认值为0,所以用el表达式在文本框中显示时,结果为0,所以,int不适合作为web层的表单数据的类型。

        在Hibernate中,如果将OID定义为Integer类型,那么Hibernate就可以根据其值是否为null而判断一个对象是否是临时的,如果将OID定义为了int类型,还需要在hbm映射文件中设置其unsaved-value属性为0。

        另外,Integer提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。

5.Overload和Override的区别?Overloaded的方法是否可以改变返回值的类型?

        Overload是重载的意思,Override是覆盖的意思,也就是重写。

        重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。

        重写Override表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。子类方法的访问权限只能比父类的更大,不能更小。如果父类的方法是private类型,那么,子类则不存在覆盖的限制,相当于子类中增加了一个全新的方法。

6.接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concreteclass)?抽象类中是否可以有静态的main方法?

        接口可以继承接口。抽象类可以实现(implements)接口,抽象类可以继承具体类。抽象类中可以有静态的main方法。

        备注:只要明白了接口和抽象类的本质和作用,这些问题都很好回答,你想想,如果你是java语言的设计者,你是否会提供这样的支持,如果不提供的话,有什么理由吗?如果你没有道理不提供,那答案就是肯定的了。

        只要记住抽象类与普通类的唯一区别就是不能创建实例对象和允许有abstract方法。     

7.abstractclass和interface语法上有什么区别?

      1.抽象类可以有构造方法,接口中不能有构造方法。

      2.抽象类中可以有普通成员变量,接口中没有普通成员变量

      3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。

      4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然

eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。

     5. 抽象类中可以包含静态方法,接口中不能包含静态方法

      6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是publicstatic final类型,并且默认即为publicstatic final类型。

     7. 一个类可以实现多个接口,但只能继承一个抽象类。

8.abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?

        abstract的method不可以是static的,因为抽象的方法是要被子类实现的,而static与子类扯不上关系!

        native方法表示该方法要用另外一种依赖平台的编程语言实现的,不存在着被子类实现的问题,所以,它也不能是抽象的,不能与abstract混用。

        关于synchronized与abstract合用的问题,我觉得也不行,因为在我几年的学习和开发中,从来没见到过这种情况,并且我觉得synchronized应该是作用在一个具体的方法上才有意义。

9.ArrayList和Vector的区别

        这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,并且其中的数据是允许重复的,这是与HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素。

         ArrayList与Vector的区别主要包括两个方面:.
(1)同步性:

       Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。

(2)数据增长:

       ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍)。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。

    总结:即Vector增长原来的一倍,ArrayList增加原来的0.5倍。

10.HashMap和Hashtable的区别

        HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。

        HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。

HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。

        Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。

        最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap就必须为之提供同步。

     就HashMap与HashTable主要从三方面来说。
        一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现
        二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
        三.值:只有HashMap可以让你将空值作为一个表的条目的key或value

11.List、Map、Set三个接口,存取元素时,各有什么特点?

        首先,List与Set具有相似性,它们都是单列元素的集合,所以,它们有一个共同的父接口,叫Collection。Set里面不允许有重复的元素,即不能有两个相等(注意,不是仅仅是相同)的对象,即假设Set集合中有了一个A对象,现在我要向Set集合再存入一个B对象,但B对象与A对象equals相等,则B对象存储不进去,所以,Set集合的add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true,当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为false。Set取元素时,不能细说要取第几个,只能以Iterator接口取得所有的元素,再逐一遍历各个元素。

       List是一个有序、可重复、可为NULL的集合,注意,不是那种按年龄、按大小、按价格之类的排序。当我们多次调用add(Obje)方法时,每次加入的对象就像火车站买票有排队顺序一样,按先来后到的顺序排序。有时候,也可以插队,即调用add(intindex,Obj e)方法,就可以指定当前对象在集合中的存放位置。一个对象可以被反复存储进List中,每调用一次add方法,这个对象就被插入进集合中一次,其实,并不是把这个对象本身存储进了集合中,而是在集合中用一个索引变量指向这个对象,当这个对象被add多次时,即相当于集合中有多个索引指向了这个对象,如图x所示。List除了可以用Iterator接口取得所有的元素,再逐一遍历各个元素之外,还可以调用get(index i)来明确说明取第几个。

       Map与List和Set不同,它是双列的集合,其中有put方法,定义如下:put(obj key,obj value),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则可以根据key获得相应的value,即get(Object key)返回值为key所对应的value。另外,也可以获得所有的key的结合,还可以获得所有的value的结合,还可以获得key和value组合成的Map.Entry对象的集合。

 List以特定次序来持有元素,可有重复元素。Set无法拥有重复元素,内部排序。Map保存key-value值,value可多值。

12.说出ArrayList,Vector,LinkedList的存储性能和特性

        ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差。而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,索引就变慢了,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

        LinkedList 基于双向链表实现的非线程安全的集合,它是一个链表结构,不能像数组一样随机访问,必须是每个元素依次遍历直到找到元素为止。其结构的特殊性导致它查询数据慢。

       (ArrayList、LinkedList线程不安全,Vector线程安全

13.你所知道的集合类都有哪些?主要方法?

        最常用的集合类是 List 和 Map。 List的具体实现包括 ArrayList和 Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。 List适用于按数值索引访问元素的情形。

        Map 提供了一个更通用的元素存储方法。 Map集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值。

        它们都有增删改查的方法。

        对于set,大概的方法是add,remove, contains等

        对于map,大概的方法就是put,remove,contains等

        List类会有get(int index)这样的方法,因为它可以按顺序取元素,而set类中没有get(int index)这样的方法。List和set都可以迭代出所有元素,迭代时先要得到一个iterator对象,所以,set和list类都有一个iterator方法,用于返回那个iterator对象。map可以返回三个集合,一个是返回所有的key的集合,另外一个返回的是所有value的集合,再一个返回的key和value组合成的EntrySet对象的集合,map也有get方法,参数是key,返回值是key对应的value,这个自由发挥,也不是考记方法的能力,这些编程过程中会有提示,结合他们三者的不同说一下用法就行。

14.final, finally, finalize的区别。 

1.简单区别:
    final用于声明属性,方法和类,分别表示属性不可交变,方法不可覆盖,类不可继承。
    finally是异常处理语句结构的一部分,表示总是执行。
    finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等。

2.中等区别:
虽然这个单词在Java中都存在,但是并没太多关联:
final:java中的关键字,修饰符。
A).如果一个类被声明为final,就意味着它不能再派生出新的子类,不能作为父类被继承。因此,一个类不能同时被声明为abstract抽象类的和final的类。
B).如果将变量或者方法声明为final,可以保证它们在使用中不被改变.
  1)被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。 
  2)被声明final的方法只能使用,不能重载。
finally:java的一种异常处理机制。
  finally是对Java异常处理模型的最佳补充。finally结构使代码总会执行,而不管无异常发生。使用finally可以维护对象的内部状态,并可以清理非内存资源。特别是在关闭数据库连接这方面,如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。
finalize:Java中的一个方法名。
Java技术使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没被引用时对这个对象调用的。它是在Object类中定义的,因此所的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

15.关于==和equals的区别和联系

1)对于==,比较的是值是否相等

            如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;

    如果作用于引用类型的变量,则比较的是所指向的对象的地址

2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量,equals继承Object类,比较的是是否是同一个对象

    如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;

    诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
 

16.字节流与字符流的区别

       要把一段二进制数据逐一输出到某个设备中,或者从某个设备中逐一读取一段二进制数据,不管输入输出设备是什么,我们要用统一的方式来完成这些操作,用一种抽象的方式进行描述,这个抽象描述方式起名为IO流,对应的抽象类为OutputStream和InputStream,不同的实现类就代表不同的输入和输出设备,它们都是针对字节进行操作的。

       计算机中的一切最终都是二进制的字节形式存在。对于经常用到的中文字符,首先要得到其对应的字节,然后将字节写入到输出流。读取时,首先读到的是字节,可是我们要把它显示为字符,我们需要将字节转换成字符。由于这样的需求很广泛,Java专门提供了字符流包装类。

      底层设备永远只接受字节数据,有时候要写字符串到底层设备,需要将字符串转成字节再进行写入。字符流是字节流的包装,字符流则是直接接受字符串,它内部将串转成字节,再写入底层设备,这为我们向IO设备写入或读取字符串提供了一点点方便。

      字符向字节转换时,要注意编码的问题,因为字符串转成字节数组,其实是转成该字符的某种编码的字节形式,读取也是反之的道理。

17.什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。

        我们有时候将一个java对象变成字节流的形式传出去或者从一个字节流中恢复成一个java对象,例如,要将java对象存储到硬盘或者传送给网络上的其他计算机,这个过程我们可以自己写代码去把一个java对象变成某个格式的字节流再传输

        但是,jre本身就提供了这种支持,我们可以调用OutputStream的writeObject方法来做,如果要让java帮我们做,要被传输的对象必须实现serializable接口,这样,javac编译时就会进行特殊处理,编译的类才可以被writeObject方法操作,这就是所谓的序列化。需要被序列化的类必须实现Serializable接口,该接口是一个mini接口,其中没有需要实现方法,implements Serializable只是为了标注该对象是可被序列化的。

        例如,在web开发中,如果对象被保存在了Session中,tomcat在重启时要把Session对象序列化到硬盘,这个对象就必须实现Serializable接口。如果对象要经过分布式系统进行网络传输,被传输的对象就必须实现Serializable接口。

18.heap和stack有什么区别。

        java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。

        堆是与栈作用不同的内存,一般用于存放不在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。

19.GC是什么?为什么要有GC?

        GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。

        垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。

        回收机制有分代复制垃圾回收标记垃圾回收增量垃圾回收

        程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。

20.说一说Servlet的生命周期?

        Servlet有良好的生存期的定义,包括加载和实例化初始化处理请求以及服务结束这个生存期由javax.servlet.Servlet接口的init(),service()destroy方法表达。

        Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。

web容器加载servlet,生命周期开始。通过调用servlet的init()方法进行servlet的初始化。通过调用service()方法实现,根据请求的不同调用不同的do***()方法。结束服务,web容器调用servlet的destroy()方法。

21.Servlet API中forward()与redirect()的区别?

    1.从地址栏显示来说
        forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
        redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.所以redirect等于客户端向服务器端发出两次request,同时也接受两次response。
    2.从数据共享来说
        forward:转发页面和转发到的页面可以共享request里面的数据.
        redirect:不能共享数据.

        redirect不仅可以重定向到当前应用程序的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源.
        forward方法只能在同一个Web应用程序内的资源之间转发请求.forward 是服务器内部的一种操作.
        redirect 是服务器通知客户端,让客户端重新发起请求.
   所以,你可以说 redirect 是一种间接的请求, 但是你不能说"一个请求是属于forward还是redirect "

 3.从运用地方来说
        forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
        redirect:一般用于用户注销登陆返回主页面跳转到其它的网站等.
    4.从效率来说
        forward:高.
        redirect:低.

22.request.getAttribute()和 request.getParameter()有何区别?

        1,request.getParameter()取得是通过容器的实现来取得通过类似post,get等方式传入的数据(比如表单提交)。

            request.setAttribute()和getAttribute()只是在web容器内部流转仅仅是请求处理阶段

        2,getAttribute是返回对象,getParameter返回字符串

        3,getAttribute()一向是和setAttribute()一起使用的,只有先用setAttribute()设置之后,才能够通过getAttribute()来获得值,它们传递的是Object类型的数据。而且必须在同一个request对象中使用才有效。,而getParameter()是接收表单的get或者post提交过来的参数。

23.Http中,get和post方法的区别

        1,Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求

        2,Get是获取信息,而不是修改信息,类似数据库查询功能一样,数据不会被修改

        3,Get请求的参数会跟在url后进行传递,请求的数据会附在URL之后,以?分割URL和传输数据,参数之间以&相连,%XX中的XX为该符号以16进制表示的ASCII,如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密。
        4,Get传输的数据有大小限制,因为GET是通过URL提交数据,那么GET可提交的数据量就跟URL的长度有直接关系了,不同的浏览器对URL的长度的限制是不同的。

        5,GET请求的数据会被浏览器缓存起来,用户名和密码将明文出现在URL上,其他人可以查到历史浏览记录,数据不太安全

  • GET 请求可被缓存
  • GET 请求保留在浏览器历史记录中
  • GET 请求可被收藏为书签
  • GET 请求不应在处理敏感数据时使用
  • GET 请求有长度限制
  • GET 请求只应当用于取回数据
  • POST 请求不会被缓存
  • POST 请求不会保留在浏览器历史记录中
  • POST 不能被收藏为书签
  • POST 请求对数据长度没有要求

  (个人参考)

24.什么是cookie?Session和cookie有什么区别?

    Cookie是会话技术,将用户的信息保存到浏览器的对象.

    区别:

        (1)cookie数据存放在客户的浏览器上,session数据放在服务器
        (2)cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,如果主要考虑到安全应当使用session
        (3)session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用COOKIE
        (4)单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能3K。

    结论:

        将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中。

25.数据库连接池的原理。为什么要使用连接池。


1,数据库连接是一件费时的操作,连接池可以使多个操作共享一个连接。
2,数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量、使用情况,为系统开发,测试及性能调整提供依据。
3,使用连接池是为了提高对数据库连接资源的管理

26.JDBC的脏读是什么?哪种数据库隔离级别能防止脏读?什么是幻读,哪种隔离级别可以防止幻读?

  当我们使用事务时,有可能会出现这样的情况,有一行数据刚更新,与此同时另一个查询读到了这个刚更新的值。这样就导致了脏读,因为更新的数据还没有进行持久化,更新这行数据的业务可能会进行回滚,这样这个数据就是无效的。数据库的TRANSACTIONREADCOMMITTEDTRANSACTIONREPEATABLEREAD,和TRANSACTION_SERIALIZABLE隔离级别可以防止脏读。

       幻读是指一个事务多次执行一条查询返回的却是不同的值。假设一个事务正根据某个条件进行数据查询,然后另一个事务插入了一行满足这个查询条件的数据。之后这个事务再次执行了这条查询,返回的结果集中会包含刚插入的那条新数据。这行新数据被称为幻行,而这种现象就叫做幻读。

  只有TRANSACTION_SERIALIZABLE隔离级别才能防止产生幻读。

27.JDBC的DriverManager是用来做什么的? 

      JDBC的DriverManager是一个工厂类,我们通过它来创建数据库连接。当JDBC的Driver类被加载进来时,它会自己注册到DriverManager类里面,然后我们会把数据库配置信息传成DriverManager.getConnection()方法,DriverManager会使用注册到它里面的驱动来获取数据库连接,并返回给调用的程序。

28.谈谈你对Hibernate的理解。

        1. 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象、建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程和操作怎么样,本质上都是要得到一个结果,程序上一个时刻和下一个时刻的运行结果的差异就表现在内存中的对象状态发生了变化。

        2.为了在关机和内存空间不够的状况下,保持程序的运行状态,需要将内存中的对象状态保存到持久化设备和从持久化设备中恢复出对象的状态,通常都是保存到关系数据库来保存大量对象信息。从Java程序的运行功能上来讲,保存对象状态的功能相比系统运行的其他功能来说,应该是一个很不起眼的附属功能,java采用jdbc来实现这个功能,这个不起眼的功能却要编写大量的代码,而做的事情仅仅是保存对象和恢复对象,并且那些大量的jdbc代码并没有什么技术含量,基本上是采用一套例行公事的标准代码模板来编写,是一种苦活和重复性的工作。

        3.通过数据库保存java程序运行时产生的对象和恢复对象,其实就是实现了java对象与关系数据库记录的映射关系,称为ORM(即Object RelationMapping),人们可以通过封装JDBC代码来实现了这种功能,封装出来的产品称之为ORM框架,Hibernate就是其中的一种流行ORM框架。使用Hibernate框架,不用写JDBC代码,仅仅是调用一个save方法,就可以将对象保存到关系数据库中,仅仅是调用一个get方法,就可以从数据库中加载出一个对象。

        4.使用Hibernate的基本流程是:配置Configuration对象、产生SessionFactory、创建session对象,启动事务,完成CRUD操作,提交事务,关闭session

        5.使用Hibernate时,先要配置hibernate.cfg.xml文件,其中配置数据库连接信息和方言等,还要为每个实体配置相应的hbm.xml文件,hibernate.cfg.xml文件中需要登记每个hbm.xml文件。

        6.在应用Hibernate时,重点要了解Session的缓存原理,级联,延迟加载和hql查询。

29.JDK 和 JRE 有什么区别?

1.jvm:Java虚拟机,保证Java跨平台特性

2.jre:Java运行环境,jvm + Java核心类库

3.jdk:Java的开发工具,jre + 开发工具 

      jdk之所以包含jre,有两方面原因,一是需要查看开发完成的程序的运行效果,二是jdk中的开发工具都是由Java语言编写的应用程序,为使用方便打包成exe文件,若是缺少jre,这些工具无法运行


30.String,StringBuffer,StringBuilder三者的使用方法和区别

String

      1.不可变性。是指String对象一旦生成,则不能再对它进行改变。

      2.针对常量池的优化。当两个String对象拥有相同的值时,他们只引用常量池中的同一个拷贝。当同一个字符串反复出现时,这个技术可以大幅度节省内存空间。

StringBuilder与StringBuffer

      StringBuilder:线程非安全的

      StringBuffer:线程安全的

对于三者的总结:1)如果操作少量的数据用String

                             2)单线程下操作大量的数据用StringBuilder

                             3)多线程下操作大量的数据用StringBuffer

31.String类的常用方法总结

常用方法

  1. equalsIgnoreCase();//无视大小写比较
  2. toLowerCase(); //变小写
  3. toUpperCase(); //变大写
  4. trim(); //去掉字符串两端的空格
  5. concat(); //连接字符串,和+一样(任何基本类型+""都是字符串类型)
  6. replaceAll("原子串","新子串") //把原内容全部替换成新内容


32.抽象类能使用 final 修饰吗?

不能,抽象类是被用于继承的,final修饰代表不可修改、不可继承的。

33.抽象类和接口有什么区别

抽象类

抽象类是用来捕捉子类的通用特性的 。它不能被实例化,只能被用作子类的超类。抽象类是被用来创建继承层级里子类的模板。

接口

接口是抽象方法的集合。如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法。

34.IO流的几种分类

1.IO流简介

1)IO流用来处理设备之间的数据传输
2)java对数据的操作是通过流的方式
3)根据不同的原则有不同的分类

2.按方向分类

简单理解就是:以内存为中,用来操作将硬盘已有的数据读取到内存的是输入流,用来操作将内存中的数据存储到硬盘中的是输出流.输入流进行读操作,输出流进行写操作.

输入流

InputStream

FileInputStream

ByteArrayInputStream

Reader

FileReader

所有字节输入流的超类

文件字节输入流

字节数组输入流

读取字符流的抽象类

文件字符输入流

输出流

OutputStream

FileOutputStream

ByteArrayOutputStream

Writer

FileWriter

所有字节输出流的超类

文件字节输出流

字节数组输出流

写入字符流的抽象类

文件字符输出流

3.按数据单元分类

以字节为单位的称为字节流,义字符为单位的称为字符流.字节流可以读写任意资源,字符流是为了更便捷的读写文字.

字节流

FileInputStream

ByteArrayOutputStream

文件字节输入流

字节数组输出流

字符流

BufferedReader

BufferedWriter

缓冲字符输入流

缓冲字符输出流

4.按功能分类

直接与底层文件资源连接的称为节点流,对节点流进行包装从而完成更高级功能的称为处理流,处理流在构造时须为其指定一个节点流.

节点流

FileInputStream

ByteArrayInputStream

PipedInputStream

文件流

字节数组流

管道流

处理流

InputStreamReader

BufferedReader

DataInputStream

ObjectInputStream

SequenceInputStream

桥梁流

缓冲流

数据流

对象流

合并流

35.BIO与NIO、AIO的区别

IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。

36.Java容器有哪些?

1.数组,String,java.util下的集合容器

2.List:存放有序,列表存储,元素可重复

3.Set:无序,元素不可重复

4.Map:无序,元素可重复

37.如何实现数组与List的相互转换

List转数组:toArray(arraylist.size()方法

数组转List:Arrays的asList(a)方法

38.什么是迭代器(Iterator)?

为了方便的处理集合中的元素,Java中出现了一个对象,该对象提供了一些方法专门处理集合中的元素.例如删除和获取集合中的元素.该对象就叫做迭代器(Iterator).

如何获取迭代器?

Collection接口中定义了获取集合类迭代器的方法(iterator()),所以所有的Collection体系集合都可以获取自身的迭代器。

39.并发和并行区别(举例)

你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。

你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。(不一定是同时的)

你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。

40.线程和进程的区别,同步怎么实现?

线程,有时被称为轻量级进程(Lightweight Process,LWP),是操作系统调度(CPU调度)执行的最小单位

【区别】:

  • 调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位;
  • 并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行;
  • 拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。进程所维护的是程序所包含的资源(静态资源), 如:地址空间,打开的文件句柄集,文件系统状态,信号处理handler等;线程所维护的运行相关的资源(动态资源),如:运行栈,调度相关的控制信息,待处理的信号集等;
  • 系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。但是进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个进程死掉就等于所有的线程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。

【联系】:

  • 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程;
  • 资源分配给进程,同一进程的所有线程共享该进程的所有资源;
  • 处理机分给线程,即真正在处理机上运行的是线程;
  • 线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

同步是synchronized关键字修饰的方法。

41.java创建线程有几种方式?

一、继承Thread类创建线程子类

二、建一个类去实现Runnable接口

三、通过Callable 接口和 RunnableFuture创建线程

线程的状态(创建、就绪、运行、阻塞、终止)

42.线程的 run()和 start()有什么区别?

      run()方法:在本线程内调用该Runnable对象的run()方法,可以重复多次调用, start()方法:启动一个线程,调用该Runnable对象的run()方法,不能多次启动一个线程。

      换句话说:start()是告诉线程准备完毕,可以运行了,然后run()就是运行状态方法,当thread.start()的时候会走thread(new Runnable(){public void run(){})异步去调用,但thread.run()方式可以直接调用匿名内部类run(),不需要start();


43.什么是死锁,死锁是怎样产生的?如何防止死锁?

死锁:所谓死锁是指多个进程因竞争资源而相互等待,若无外力作用,这些进程都无法向前推进。

产生死锁原因:

  1. 系统资源的竞争   当不可剥得资源的数量不足以满足进程的需要时,使得进程会因为争得资源而陷入僵局
  2. 进程推进顺序不当   进程在运行过程中,请求和释放资源的顺序不当,也会造成死锁。例如并发进程P1,P2

避免:  死锁避免方法中,允许进程动态的申请资源,但是系统进行资源分配之前,应该先计算此资源的安全性。若此次分配不会导致系统进入不安全状态,则将资源分配给进程,否则让进程等待。

44.什么是反射?

反射机制指的是程序在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。

45.jsp 和 servlet 有什么区别?

   jsp和servlet的区别和联系:
     1.jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)
     2.jsp更擅长表现于页面显示,servlet更擅长于逻辑控制.
     3.Servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象得到.

Jsp是Servlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,Jsp中的Java脚本如何镶嵌到一个类中,由Jsp容器完成。而Servlet则是个完整的Java类,这个类的Service方法用于生成对客户端的响应。
   联系: 

JSP是Servlet技术的扩展,本质上就是Servlet的简易方式。JSP编译后是“类servlet”。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑

46.JSP有哪些内置对象?作用分别是什么? 分别有什么方法?

JSP共有以下9个内置的对象:

request:表示HttpServletRequest对象,用户端请求。它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie, header, 和session数据的有用的方法。

response:表示HttpServletResponse对象,并提供了几个用于设置送回 浏览器的响应的方法(如cookies,头信息等),网页传回用户端的回应

out:对象是javax.jsp.JspWriter的一个实例,并提供了几个方法使你能用于向浏览器回送输出结果。

pageContext:表示一个javax.servlet.jsp.PageContext对象。该对象提供了对JSP页面内所有的对象及名字空间(就是四大作用域空间,如page空间、request空间、session空间、application空间)的访问,也就是说他可以访问到当前请求对应session中保存的信息,也可以取当前应用所在的application的某一属性值,它相当于页面中所有功能的集大成者,包装了通用的servlet相关功能的方法。

session:表示一个请求的javax.servlet.http.HttpSession对象。Session可以存贮用户的状态信息

applicaton:表示一个javax.servle.ServletContext对象。类似于系统的全局变量,用于实现Web应用中的资源共享。

config:表示一个javax.servlet.ServletConfig对象。用于存放JSP编译后的初始数据。

page:表示从该页面产生的一个servlet实例,JSP网页本身

exception:针对错误网页,未捕捉的例外。表示JSP页面运行时产生的异常和错误信息,该对象只有在错误页面(page指令中设定isErrorPage为true的页面)中才能够使用。


JSP的4种作用域

作用域描述
page代表页面上下文,范围是一个页面及其静态包含的内容
request代表请求上下文,范围是一个请求涉及的几个页面,通常是一个页面和其包含的内容以及forward动作转向的页面
session代表客户的一次会话上下文,范围是一个用户在会话有效期内多次请求所涉及的页面
application全局作用域,代表Web应用程序上下文,范围是整个Web应用中所有请求所涉及的页面

47.简述throw和throws的区别

throw是语句抛出一个异常,throws是方法抛出一个异常;

throw不能单独使用,不是和try-catch-finally配套使用,就是与throws配套使用,但throws可以单独使用,然后再由异常处理的方法捕获。

48.解释一下什么是 aop?ioc?

IOC称为控制反转,也叫依赖注入,ioc是Spring的核心组件,它通过配置文件,将需要创建的对象以池的方式管理,将实例注入

到需要的对象中区,是对象依赖于注入而不依赖于实现,解决了各个组件的耦合度,使得项目在后期的维护和扩展上非常方便。

AOP是Spring提供的关键特性之一。AOP即面向切面编程,是OOP编程的有效补充。

使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。

从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。

49.谈谈你对Spring的理解。

1.Spring相当于一个大的工厂类,在其配置文件中通过<bean>元素配置用于创建实例对象的类名和实例对象的属性。

2.Spring提供了对IOC良好支持,IOC是一种编程思想,是一种架构艺术,利用这种思想可以很好地实现模块之间的解耦。

3.Spring提供了对AOP技术的良好封装, AOP称为面向切面编程,就是系统中有很多各不相干的类的方法,在这些众多方法中要加入某种系统功能的代码,例如,加入日志,加入权限判断,加入异常处理,这种应用称为AOP。

50.简述 Hibernate 和 JDBC 的优缺点?

  • 封装了 jdbc,简化了很多重复性代码。

  • 简化了 DAO 层编码工作,使开发更对象化了。

  • 移植性好,支持各种数据库如果换个数据库只要在配置文件中变换配置就可以了,不用改变 hibernate 代码。

  • 支持透明持久化,因为 hibernate 操作的是纯粹的(pojo)java 类,没有实现任何接口,没有侵入性。

51.SSM框架的优势

从三个方面分析:

1.Spring的优势:

        通过Spring的IOC特性,将对象之间的依赖关系交给了Spring控制,方便解耦,简化了开发

        通过Spring的AOP特性,对重复模块进行集中,实现事务,日志,权限的控制

        提供了对其他优秀开源框架的集成支持

2.Spring MVC的优势:

        SpringMVC是使用了MVC设计思想的轻量级web框架,对web层进行解耦,使我们开发更简洁

        与Spring无缝衔接

        灵活的数据验证,格式化,数据绑定机制

3.Mybatis的优势:

        数据库的操作(sql)采用xml文件配置解除了sql和代码的耦合

        提供映射标签,支持对象和和数据库orm字段关系的映射,支持对象关系映射标签,支持对象关系的组建

      提供了xml标签支持动态的sql

52.spring框架有哪些主要模块?

Spring有七大功能模块,分别是Spring Core,AOP,ORM,DAO,MVC,WEB,Context
1,Spring Core
Core模块是Spring的核心类库,Spring的所有功能都依赖于该类库,Core主要实现IOC功能,Sprign的所有功能都是借助IOC实现的。
2,AOP
AOP模块是Spring的AOP库,提供了AOP(拦截器)机制,并提供常用的拦截器,供用户自定义和配置。
3,ORM
Spring 的ORM模块提供对常用的ORM框架的管理和辅助支持,Spring支持常用的Hibernate,ibtas,jdao等框架的支持,Spring本身并不对ORM进行实现,仅对常见的ORM框架进行封装,并对其进行管理
4,DAO模块
Spring 提供对JDBC的支持,对JDBC进行封装,允许JDBC使用Spring资源,并能统一管理JDBC事物,并不对JDBC进行实现。(执行sql语句)
5,WEB模块
WEB模块提供对常见框架如Struts1,WEBWORK(Struts 2),JSF的支持,Spring能够管理这些框架,将Spring的资源注入给框架,也能在这些框架的前后插入拦截器。
6,Context模块
Context模块提供框架式的Bean访问方式,其他程序可以通过Context访问Spring的Bean资源,相当于资源注入。
7,MVC模块
WEB MVC模块为Spring提供了一套轻量级的MVC实现,在Spring的开发中,我们既可以用Struts也可以用Spring自己的MVC框架,相对于Struts,Spring自己的MVC框架更加简洁和方便。

53.Spring三种依赖注入方式

 三种依赖注入方式,即构造方法注入(constructor injection),setter方法注入(setter injection)以及接口注入(interface injection).

54.Java中@Autowired注释的作用

spring可以自动帮你把Bean里面引用的对象的setter/getter方法省略,它会自动帮你set/get。

@Autowired注释进行自动注入时,spring容器中匹配的候选Bean数目必须有且仅有一个。

当找不到一个匹配的Bean时,spring容器将抛出BeanCreationException异常,并指出必须至少拥有一个匹配的Bean。

如果spring容器中拥有多个候选Bean,spring容器在启动时也会抛出BeanCreationException

这个时候就可以借助@Qualifier注释指定注入Bean的名称,这样@Autowired遇到多个候选Bean的问题也就解决了。

55.spring mvc 运行流程?

     1.客户端所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作。

2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller.

3.DispatcherServlet请请求提交到目标Controller

4.Controller进行业务逻辑处理后,会返回一个ModelAndView

5.Dispathcher查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象

6.视图对象负责渲染返回给客户端。

56.Mybatis的两种分页方式

    RowBounds:在mapper.java中的方法中传入RowBounds对象。

    PageHelper:在调用查询方法之前调用。PageHelper只对紧跟着的第一个SQL语句起作用.

57.说一下 mybatis 的一级缓存和二级缓存?

一级缓存
一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构用于存储缓存数据。不

同的sqlSession之间的缓存数据区域是互相不影响的。也就是他只能作用在同一个sqlSession中,不同的sqlSession中的缓存是

互相不能读取的。
二级缓存

二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存

是跨SqlSession的。

58.mybatis 有哪些执行器(Executor)?

SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。

ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map内,供下一次使用。简言之,就是重复使用Statement对象。

BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。

作用范围:Executor的这些特点,都严格限制在SqlSession生命周期范围内。

59.mybatis中的#和$的区别

#{}是预编译处理

${}是字符串替换。

Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

Mybatis在处理时,就是把{}替换成变量的值。

使用#{}可以有效的防止SQL注入,提高系统安全性。

60.Spring中的bean作用域有哪些

  • singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例

  • prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例

  • request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效

  • session:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效

  • globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效

       其中比较常用的是singleton和prototype两种作用域。对于singleton作用域的Bean,每次请求该Bean都将获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为;如果一个Bean被设置成prototype作用域,程序每次请求该id的Bean,Spring都会新建一个Bean实例,然后返回给程序。在这种情况下,Spring容器仅仅使用new 关键字创建Bean实例,一旦创建成功,容器不在跟踪实例,也不会维护Bean实例的状态。

  如果不指定Bean的作用域,Spring默认使用singleton作用域。Java在创建Java实例时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会导致系统开销的增加。因此,prototype作用域Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将Bean被设置成prototype作用域。

61.spring中自动装配的有哪些

1.  no:这是Spring框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在bean定义中用标签明确的设置依赖关系。

2.  byName:该选项可以根据bean名称设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的名称自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。

3.  byType:该选项可以根据bean类型设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的类型自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。

4.  constructor:造器的自动装配和byType模式类似,但是仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。

5.  autodetect:该模式自动探测使用构造器自动装配或者byType自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在bean内部没有找到相应的构造器或者是无参构造器,容器就会自动选择byTpe的自动装配方式。

62.Jsp有哪些动作?作用分别是什么?

  • jsp:include:在页面被请求的时候引入一个文件。
  • jsp:useBean:寻找或者实例化一个JavaBean。
  • jsp:setProperty:设置JavaBean的属性。
  • jsp:getProperty:输出某个JavaBean的属性。
  • jsp:forward:把请求转到一个新的页面。
  • jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记。

63.mvc设计模式是什么

    观察者模式、合成模式、策略模式

64.Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

     第一种是使用标签<resultMap>,逐一定义列名和对象属性名之间的映射关系。

     第二种是使用sql列的别名功能,将列别名书写为对象属性名,比如T_NAME AS NAME,对象属性名一般是name,小写,但是列名不区分大小写,Mybatis会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成T_NAME AS NaMe,  Mybatis一样可以正常工作。

有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。 

65.Spring的三大核心思想

Spring的三大核心思想:IOC(控制反转),DI(依赖注入),AOP(面向切面编程)。

DI是组件之间的依赖关系由容器在应用系统运行期来决定, 也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中

66.写一个单例模式(Singleton)出来

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值