【前言】别人都在你看不到的地方暗自努力,在你看得到的地方,他们也和你一样显得游手好闲,和你一样会抱怨,而只有你自己相信这些都是真的,最后,也只有你一个人继续不思进取 ……
【下载】个人结合诸多资料,总结的一些JavaEE常见面试题,主要针对初/中级程序员。想要word完整版下载的,评论里留言留下你的邮箱!
16.请写出hibernate中主键生成策略?
答:①increment:适用于short,int,long作为主键.不是使用的数据库自动增长机制。
* Hibernate中提供的一种增长机制;
* 先进行查询:select max(id) from user;
* 再进行插入:获得最大值+1作为新的记录的主键;
* 问题:不能在集群环境下或者有并发访问的情况下使用;
②identity:适用于short,int,long作为主键。必须使用底层带有自动增长机制的数据库。
* 底层使用的是数据库的自动增长(auto_increment).像Oracle数据库没有自动增长;
③sequence:适用于short,int,long作为主键.底层使用的是序列的增长方式。
* Oracle数据库底层没有自动增长,想自动增长需要使用序列;
④uuid:适用于char,varchar类型的作为主键.
* 使用随机的字符串作为主键;
⑤native:本地策略.根据底层的数据库不同,自动选择适用于该种数据库的生成策略.(short,int,long)。
* 如果底层使用的MySQL数据库:相当于identity;
* 如果底层使用Oracle数据库:相当于sequence;
⑥assigned:主键的生成不用Hibernate管理了.必须手动设置主键。
17.具有相同名称的一组值,struts2如何实现封装
答:①对于String类型,Struts2会采用“, ”方法进行字符串连接。
如:23ad, 43e4, 65ds.....
解决: String ids[] = model.getId().split(", ");
//调用业务方法,实现批量删除
deptService.delete(Dept.class, ids);
②对于Integer,Float,Date类型,Struts2默认接收的是最后一个值;
如:客户端给id传了三个值,id=3、id=4、id=5....服务器只能接受最后一个值,就是id=5
解决:private List<Integer> ids;//生成它的getter与setter
18.阐述实体对象的三种状态以及转换关系?
答:Hibernate中对象有三种状态:
①瞬时态(transient):没有持久化标识OID,没有被纳入到Session对象的管理;
②持久态(persistent):有持久化标识OID,已经被纳入到Session对象的管理;
③游离态(detached)有持久化标识OID,没有被纳入到Session对象的管理;
注意:处在持久态的对象,有自动更新数据库的能力。尤其快照机制引起的:
19.简述Hibernate中快照机制的原理?
20.简述Hibernate中常见的优化策略?
答:①指定合理的缓存策略;
②采用合理的Session管理机制;
③尽量使用延迟加载特性;
④设定合理的批量处理参数;
⑤如果可以,选用UUID作为主键生成器;
⑥如果可以, 选用基于version的乐观锁替代悲观锁;
⑦开发过程中, 开启hibernate.show_sql选项查看生成的SQL,从而了解底层的状况;开发完成后关闭此选项;
⑧数据库本身的优化(合理的索引,缓存,数据分区策略等)也会对持久层的性能带来可观的提升,这些需要专业的DBA提供支持;
21.谈一谈Hibernate的一级缓存、二级缓存和查询缓存?
答:①Hibernate的Session提供了一级缓存的功能,默认总是有效的,当应用程序保存持久化实体、修改持久化实体时,Session并不会立即把这种改变提交到数据库,而是缓存在当前的Session中,除非显示调用了Session的flush()方法或通过close()方法关闭Session。通过一级缓存,可以减少程序与数据库的交互,从而提高数据库访问性能。
②SessionFactory级别的二级缓存是全局性的,所有的Session可以共享这个二级缓存。不过二级缓存默认是关闭的,需要显示开启并指定需要使用哪种二级缓存实现类(可以使用第三方提供的实现)。一旦开启了二级缓存并设置了需要使用二级缓存的实体类,SessionFactory就会缓存访问过的该实体类的每个对象,除非缓存的数据超出了指定的缓存空间。
③一级缓存和二级缓存都是对整个实体进行缓存,不会缓存普通属性,如果希望对普通属性进行缓存,可以使用查询缓存。查询缓存是将HQL或SQL语句以及它们的查询结果作为键值对进行缓存,对于同样的查询可以直接从缓存中获取数据。查询缓存默认也是关闭的,需要显示开启。
22.说出Servlet的生命周期?
答:Servlet的生命周期:
①servlet是单实例多线程的
②默认第一次收到请求的时候,服务器创建servlet;
③与此同时调用init方法,实现初始化操作,并调用service方法;
④service方法会调用与请求对应的doGet或doPost等方法完成业务操作;
⑤以后每当收到请求的时候,都创建一个新的线程,同样服务器会调用service方法来处理业务逻辑;
⑥当服务器正常关闭或者servlet被移除的时候,服务器调用destroy方法,实现销毁操作。
23.请求转发(forward)和重定向(redirect)的区别?
答:① 请求转发是1次请求;重定向是2次请求;
② 请求转发地址栏不变;重定向地址栏改变;
③ 请求转发是request的方法;重定向是response的方法;
④ 请求转发的时候可以使用request域对象;而重定向不能使用;
⑤ 请求转发的路径是内部路径;重定向的路径是绝对路径;
⑥ 若访问站外资源,需要使用重定向;
24. get和post请求的区别?
答:① get请求用来从浏览器上获取资源,而post是用来向服务器提交数据;
② get会将表单中的数据,按照name=value的形式,添加到action所指向的URL后面,并且两者间使用“?”连接,各个变量之间使用“&”连接;post是将表单中的数据放在HTML头部(header),传递到action所指向URL,不会出现在地址栏中;
③ get传输的数据要受到URL长度限制(1024字节);而post可以传输大量的数据,上传文件只能使用post方式;
25.JSP和Servlet有有什么关系?
答:①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更侧重于控制逻辑,在MVC架构模式中,JSP适合充当视图(view)而Servlet适合充当控制器(controller);
26.JSP的9个内置对象和4个域对象?
答:(1)9个内置对象:
①request:封装客户端的请求,其中包含来自GET或POST请求的参数;
②application:封装服务器运行环境的对象;
③response:封装服务器对客户端的响应;
④session:封装用户会话的对象;
⑤page:JSP页面本身(相当于Java程序中的this);
⑥config:Web应用的配置对象;
⑦exception:封装页面抛出异常的对象;
⑧pageContext:通过该对象可以获取其他对象;
⑨out(滚吧):用来传送回应的输出;
(2)4个域对象
①page(当前页面)
②reques(一次请求)
③session( 一次会话)
④application(整个会话)
27.实现会话跟踪的技术有哪些?
答:由于HTTP协议本身是无状态的,服务器为了区分不同的用户,就需要对用户会话进行跟踪,简单的说就是为用户进行登记,为用户分配唯一的ID,下一次用户在请求中包含此ID,服务器根据此判断到底是哪一个用户。
①URL重写:在URL中添加会话信息作为请求的参数,或者将唯一的会话ID添加到URL结尾,以表示一个会话;
②设置表单隐藏域:将和会话跟踪相关的字段添加到隐藏域中,这些信息不会在浏览器显示,但是提交表单时会提交给服务器;
③cookie:cookie有两种,一种是基于窗口的,浏览器关闭后,cookie就没有了;另一种是将信息存储在一个临时文件中,并设置其有效路径和最大存活时间。当用户通过浏览器和服务器建立一次会话后,会话ID就会随相应信息储存在基于窗口的cookie中,那就意味着只要浏览器没有关闭,会话没有超时,下一次请求时这个会话ID又会提交给服务器,让服务器识别用户身份。在使用cookie时要注意几点:首先不要在cookie中存放敏感信息;其次cookie存储的数据量有限(4k),不能将过多的内容存储cookie中;再者浏览器通常只允许一个站点最多存放20个cookie。当然,和用户会话相关的其他信息(除了会话ID)也可以存在cookie方便进行会话跟踪;
④HttpSession:在所有会话跟踪技术中,HttpSession对象是最强大也是功能最多的。当一个用户第一次访问某个网站时会自动创建HttpSession,每个用户可以访问他自己的HttpSession。可以通过HttpServletRequest对象的getSession方法获得HttpSession,通过HttpSession的setAttribute方法可以将一个值放在HttpSession中,通过调用HttpSession对象的getAttribute方法,同时传入属性名就可以获取保存在HttpSession中的对象。与上面三种方式不同的是,HttpSession放在服务器的内存中,因此不要将过大的对象放在里面,即使目前的Servlet容器可以在内存将满时将HttpSession中的对象移到其他存储设备中,但是这样势必影响性能。添加到HttpSession中的值可以是任意Java对象,这个对象最好实现了Serializable接口,这样Servlet容器在必要的时候可以将其序列化到文件中,否则在序列化时就会出现异常。
28.你的项目中使用过哪些JSTL标签?
答:项目中主要使用了JSTL的核心标签库,包括<c:if>、<c:choose>、<c: when>、<c: otherwise>、<c:forEach>等,主要用于构造循环和分支结构,以控制显示逻辑。
29.使用标签库有什么好处?
答:使用标签库的好处包括以下几个方面:
①分离JSP页面的内容逻辑,简化Web开发;
②开发者可以创建自定义标签库来封装业务逻辑和显示逻辑;
③标签库具有很好的可移植性、可维护性和可重用性;
④避免了对Scriptlet(小脚本)的使用(很多公司的项目都不允许在JSP中书写小脚本)
30.表达式语言(EL)支持哪些运算符?
答:除了.和[]运算符,EL还提供了:
①算术运算符:+、-、*、/或div、%或mod
②关系运算符:==或eq、!=或ne、>或gt、>=或ge、<或lt、<=或le
③逻辑运算符:&&或and、||或or、!或not
④条件运算符:${statement? A : B}(跟Java的三元运算符类似)
⑤empty运算符:检查一个值是否为null或者空(数组长度为0或集合中没有元素也返回true)