J2EE技术常见的面试题

J2EE技术常见的面试题

1.Spring都有哪些特点?为什么要使用Spring?

Spring的特定如下:

// 1. Srping不同于其他的Framework,它要提供的是一种管理你业务对象的方法。

// 2. Spring有分层的体系结构,意味着你能选择仅仅使用它的任何一个独立的部分,而其他的仍然使用你的相关实现。

// 3. 它的设计从一开始就是要帮助你编写易于测试的代码,Spring是使用测试驱动开发(TDD)工程的理想框架。

// 4. Spring不会给你的工程添加对其他的框架依赖,同时Spring又可以称得上是一个一揽子解决方案,提供了一个典型应用所需要的大部分基础架构。

之所以要使用Spring,是因为:

// 1. Spring能有效地组织你的中间层对象。

// 2. Spring能消除在许多工程中常见的对Singleton的过多使用。

// 3. 通过一种在不同应用程序和项目间一致的方法来处理配置文件,消除各种自定义格式的属性文件的需要,仅仅需要看看类的JavaBean属性。Inversion of Control的使用帮助完成了这种简化。

// 4. 能够很容易培养你面向接口而不是面向类的编程习惯。

// 5. Spring的设计会让使用它创建的应用尽可能少地依赖于它的API,在Spring应用中的大多数业务对象没有依赖于Spring。

// 6. 使用Spring构建的应用程序易于单元测试。

// 7. Spring使EJB成为一个实现选择,而不是必需的选择。你可以用POJOs或local EJBs来实现业务接口,却不会影响到调用代码。

// 8. Spring提供一些Web应用上的EJB的替代方案,比如用AOP提供声明性事务管理。

// 9. Spring为数据存取提供了一个一致的框架,不论是使用JDBC还是O/R mapping的产品。

需要注意的要点:

// 1. 控制反转(Inverse of Control ,IOC)。 依赖注入(Dependency Injection, DI)。 

// 2. 控制反转是对组件对象控制权的转移,从程序代码本身转移到了外部容器,通过容器来实现对象组件的装配和管理

// 3. 注入类型:接口注入、设置注入、构建子注入。而Spring则是IOC的一个容器。

// 4. 在Spring中,所谓依赖注入,即在运行期由容器将依赖关系注入到组件之中,就是在运行期,由Spring根据配置文件,将其他对象的引用通过组件提供的Setter方法进行设定。

// 5. 从核心而言,Spring是一个DI容器,其设计哲学是提供一种无侵入式的高扩展性框架,即无需代码中涉及Spring专有类,即可将其纳入Spring容器进行管理。

// 6. 作为对比,EJB是一种高度侵入性的框架规范,它制定了众多的接口和编码规范,要求实现者必须遵从。为了实现无侵入性目标,Spring大量引入了Java的Reflection机制,通过动态调用的方式避免硬编码方式的约束,并在此基础上建立了其核心组件BeanFactory,以此作为其依赖注入机制的实现基础。

// 7. org.springframework.beans包中包括了这些核心组件的实现类,核心中的核心为BeanWrapper和BeanFactory类。

// 8. Spring的主要目的就是使J2EE易用和促进良好的编程习惯。

// 9. Spring是让已有的技术更加易用。比如,它没有底层事务协调处理,但是提供了一个抽象层覆盖了JTA和任何其他事务策略。Spring并没有和其他的开源项目竞争,不过还是在一些领域有新的方案提供,比如它的Web Framework、轻量级的IoC容器和AOP框架。

2.Hibernate的工作原理是什么?为什么要使用Hibernate?

Hibernate工作原理如下:

// 1. 读取并解析配置文件。

// 2. 读取并解析映射信息,创建SessionFactory。

// 3. 打开Session。

// 4. 创建事务Transaction。

// 5. 持久化操作。

// 6. 提交事务。

// 7. 关闭Session。

// 8. 关闭SessionFactory。

使用hibernate的原因如下:

// 1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层烦琐的重复性代码。

// 2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,它在很大程度上简化了DAO层的编码工作。

// 3. Hibernate使用Java反射机制,而不是字节码增强程序类实现透明性。

// 4. Hibernate的性能非常好,以为它是一个轻量级框架,映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。

3.Hibernate中使用二级缓存时要注意什么?

Hibernate中使用二级缓存时要注意的几点如下。

// 1. 二级缓存能够明显提高系统的性能,当然,如果数据量特别巨大,此时不适合于二级缓存,原因是缓存的数据量过大可能会引起内存资源紧张,反而降低性能。

// 2. 对于数据更新频率过高的数据,频繁地同步缓存中数据的代码可能和查询缓存中的数据从中获得的好处相当,坏处和益处相抵消,此时缓存的意义也不大。

// 3. 财务数据等非常重要的数据,绝对不允许出现或使用无效的数据,所以此时为了安全起见,最好不要使用二级缓存。以为此时“正确性”的重要性远远大于“高性能”的重要性。

// 4. 因为数据表中的数据量虽然大,但经常使用的往往只是较新的那部分数据,此时,也可为其配置二级缓存。但是必须单独配置其持久化类的缓存策略,比如最大缓存数、缓存过期时间等,将这些参数降低至一个合理的范围(太高会引起内存资源紧张,太低了则缓存的意义不大),同时也会消耗更多的内存,可以通过配置文件来指定内存中能够加载的最多元素,这有利于消耗过多的内存。

Hibernate二级缓存的注意要点:

// 1. Hibernate中对于Cache有一级缓存和二级缓存的概念,一级缓存是必需的,位于Session部分,二级缓存则不是必需的,是由SessionFactory控制的进行级缓存,由开发人员制定。

// 2. 二级缓存可指定使用何种开源的Cache工具,Hibernate 3以后的版本默认使用的是Ehcache,也可以切换为Oscache、JbossCache.

// 3. Hibernate查询时使用的还行过程如下:1>. 查询一级缓存中是否具有需要的数据;2>. 如果没有,查询二级缓存;3>. 如果二级缓存中也没有,此时再执行查询数据库的工作。此三种方式的查询速度依次降低。

// 4. Hibernate会自行维护缓存中的数据,以保证缓存中的数据和数据库中的真实数据的一致性。

// 5. 无论何时,当你调用方法传递或获得一个对象时,该对象都将被加入到Session的内部缓存中。当flush()方法随后被调用时,对象的状态会和数据库取得同步。也就是说,删除、更新、增加数据的时候,同时更新换成。

4.Hibernate有哪些主键?

// Hibernate有如下主键,Hilo,IncrementIdentitySequence,Native,UUID,Foreign GUID。

// Hibernate主键的注意要点如下:

// 1. Hilo。Hilo使用高低位算法生成主键。Hilo方式需要额外的数据库表和字段提供高位值来源。Hilo方式与底层数据库无关,但不应该手动修改hilo算法使用的表值,否则会引起主键重复的异常。

// 2. IncrementIncrement方式对主键值采取自动增长的方式生成新的主键值,但要求底层数据库支持Sequence方式,如Orcale、DB2等。特定是由Hibernate本身维护,适用于所有的数据库,不适合多进行并发更新数据库,适合单一进程访问数据库,不能用于群集环境。

// 3. IdentityIdentity根据底层数据库来支持自动增长,不同的数据库用不同的主键增长方式。特点是与底层数据库有关,要求数据库支持identity,如MySQL中的auto_increment,SQL Server中的Identity,支持的数据库有MySQL、SQL Server、DB2、Sybase和HypersonicSQL。Identity无效Hibernate和用户的干涉,使用较为方便,但不便于在不同的数据库之间移植程序。

// 4. SequenceSequence需要底层数据库支持Sequence方式,例如Orcale数据库等。特点是需要底层数据库支持序列,支持序列的数据库有DB2,PostgreSql、Orcale、SAPDb等。

// 5. Native。Native主键生成方式会根据不同的底层数据库自动选择IdentitySequence、Hilo主键生成方式。特点是根据不同的底层数据库采用各不同的主键生成方式。因此,便于程序移植,项目中如果用到多个数据库时,可以使用这种方式。

// 6. UUID。UUID使用128位UUID算法生成主键,能够保证网络环境下的主键唯一性。特点是能够保证数据库中主键的唯一性,生成的注解占用比较多的存储空间。

// 7. Foreign GUID。Foreign用于一对一关系中。GUID主键生成方式使用了一种特殊算法,保证主键的唯一性,支持SQL Server和MySQL。

5.Hibernate有几种查询数据的方式?

// Hibernate有3中查询方式。

// 1. HQL: Hibernate Query Language,它根SQL非常类似

// 2. Criteria Query,以对象的方式添加查询条件

// 3. SQL,直接使用SQL语句操作数据库。
6.如果让你设计一个数据库连接池,你可能会考虑到哪些方面的问题?

// 可以考虑如下方面的问题:

// 1. 连接池需要实现javax.sql.DataSource接口,以适应于不同的场合。

// 2. Connection#close 问题,使用者使用连接池与不使用连接池,除了从哪获得Connection对象不一样之外,其他JDBC的代码是完全相同的,并不能因为使用连接池而改变既有的JDBC代码。如果不能改变JDBC代码,就带来了一个Connection close问题,大家都知道这个调用是关闭数据库连接,如果在连接池中这么做的话就会关闭连接,使用连接得不到重用。

// 3. 连接被动关闭问题。为了保证连接的复用性,将连接一直保存在池中。有些数据库服务器会将已经连接很久的客户端连接主动踢掉,如果碰到这种情况,在池中的这个连接池就会变为不可用状态,如果客户端使用的话将会抛出连接被关闭的SQLException。

// 4. 连接回收问题。假如我们的连接池最大设为50个,在某一并发很高的时段达到了50个,但是过后并发率就降下去了,对于连接池来说池中还是50个连接,实际上后面根本不需要那么多连接。这时连接池白白地浪费了几十个数据库宝贵的连接(数据库对于客户端的连接数是有限制的),如果连接池占用了很多的连接,那么可能会导致其他应用程序因为数据库客户端的连接到了限制而无法再获得连接。我们应该及时地将不需要使用的连接关闭还给数据库服务器,保留一些基本连接数。

// 5. 网络中断重连问题。连接池中的连接在网络中断时,池中连接会全部断开,数据库服务器也会回收断开的连接。但是网络中断后,过了一些时间又连上了,这时池中的连接依然是断开的,如果取出来用的话,不用说就会抛出异常的。一个可用的连接需要有实现自动重连的功能,否则就没有可用的价值。

7.在JDK1.4中引入了一个NIO的类库,使得Java涉及IO的操作拥有阻塞式和非阻塞式两种,问一下阻塞IO与非阻塞IO有什么区别?有什么优缺点?

// 答案如下:

// 1. 在阻塞模式下,若从网络中读取不到指定大小的数据量,阻塞IO就在那里阻塞着。比如,后面已经有10个字节的数据发过来,但是假如现在只收到8个字节,那么当前线程就在那傻傻地等待下一个字节的到来,直到把这10个字节读取完,这才将阻塞放开通行。

// 2. 在非阻塞模式下,若从网络流中读取不到指定大小的数据量,非阻塞IO就立即通行。比如,后面已经有10个字节的数据发过来,但是我现在只收到8个字节,那么当前线程就读取这8个字节的数据,读完后就立即返回,等另外两个字节来的时候再去读取。

// 3. 从上面可以看出,阻塞IO在性能方面是很低下的,如果要使用阻塞IO完成一个Web服务器的话,那么对于每一个请求都必须启用一个线程进行处理。而使用非阻塞IO的话,一到两个线程基本上就够了,因为线程不会产生阻塞,好比一下接收A请求的数据,另一下接收B请求的数据,等等,就是不停的东奔西跑,直接到把数据接收完了。

// 4. 虽然说,非阻塞IO比阻塞IO有更高的性能,但是对于开发来说,难度就成数倍递增了。由于是有多少数据就读取多少数据,这样在读取完整之前需要将已经读取到的数据保存起来,而且需要与其他地方来的数据隔离开来不能混在一起,否则就不知道这数据是谁的了。

你可能感兴趣的:(Web开发,JAVA技术提高)