面试题 / J2SE / J2SE JAVA 面试题
示例 1 : 面向对象的特征有哪些方面?
封装
最常见的是把属性私有化封装在一个类里面,只能通过方法去访问
继承
子类继承父类,从而继承了父类的方法和属性
抽象
比如一个英雄类,抽象出了name,hp这些属性,使得开发过程中更加易于理解
多态
多态分操作符的多态和类的多态。类的多态指父类引用指向子类对象,并且有继承,有重写。
示例 2 : String是最基本的数据类型吗?
String是类类型,不是基本类型
基本类型8种:byte short long float boolean double char int
示例 3 : int和Integer有什么区别?
int是基本类型32位长度的整数
integer是类类型,是int的封装类
int和Integer之间可以通过自动装箱 自动拆箱 互相转换
示例 4 : String和StringBuffer的区别?
String:长度给定不可变,当多个字符串联合时要先转为StringBuffer,再联合, 速度慢。StringBuffer:长度可变,可以将多个字符串值直接联合,效率高
示例 5 : 运行时异常与一般异常有何异同?
运行时异常又叫非可查异常,在编译中,不要求必须进行显示捕捉
一般异常又叫可查异常,在编译中必须进行处理,要么捕捉,要么通过throws抛出
示例 6 : 说出ArrayList,Vector, LinkedList的存储性能和特性。
先说ArrayList和Vector
两者都继承了抽象类AbstractList,但是Vector是线程安全的,而ArrayList是非线程安全的
再说ArrayList和LinkedList的区别
ArrayList 是数组结构,所以定位很快,但是插入和删除很慢
LinkedList 是双向链表结构,所以插入和删除很快,但是定位很慢
示例 7 : Collection和Collections的区别。
collection是接口,是List和set的父接口
collections是工具类,提供了排序,混淆等等很多使用方法
示例 8 : &和&&的区别
& 有两个作用,分别是 位与 和 逻辑与
&& 就是逻辑与
作为逻辑与, &和&&分别表示长路与和短路与
长路与 两侧,都会被运算
短路与 只要第一个是false,第二个就不进行运算了
示例 9 : HashMap和Hashtable的区别
都实现了Map接口,都是键值对保存数据的方式,其区别:
1)HashMap可以存放null,而Hashtable不能 ;
2)HashMap不是线性安全的类,而Hashtable是。
示例 10 : final, finally, finalize的区别
final
修饰类 表示该类不能被继承
修饰方法表示该方法不能被重写
修饰基本类型变量表示该变量只能被赋值一次
修饰引用表示该引用只能一次指向对象的机会
finally 是用于异常处理的场面,无论是否有异常抛出,都会执行
finalize是Object的方法,所有类都继承了该方法。 当一个对象满足垃圾回收的条件,并且被回收的时候,其finalize()方法就会被调用
示例 11 : Overload和Override的区别,即重载和重写的区别。Overloaded的方法是否可以改变返回值的类型?
1】Overload是方法的重载,指在同一个类中,方法名相同,参数类型不同。
2】Override是方法的重写,指子类继承了父类的某方法后,重新又写了一遍。
3】可以,重载其实本质上就是完全不同的方法,只是恰好取了相同的名字。
示例 12 : Error和Exception有什么区别?
1】都实现了Throwable接口
2】Error是JVM层面的错误,比如内存不足
3】Exception是代码逻辑的异常,如下标越界
示例 13 : abstract class和interface有什么区别?
abstract class 抽象类和interface接口的区别
使用方式:
抽象类只能够通过继承被使用
接口必须通过实现被使用
实现方法:
抽象类不仅可以提供抽象方法,也可以提供实现方法
接口只能提供抽象方法发,不能提供实现方法。但是在JAVA8版本开始,接口可以可以提供实现方法了,前提是要在方法前加一个default修饰符
示例 14 : heap和stack有什么区别
存放的内容不一样:
heap(堆):是存放对象的
stack(栈):是存放基本类型(int, float,等等)、引用(对象地址)、方法调用
存去方式不一样:
heap: 是自动增加大小的,所以不需要指定大小,但是存取相对较慢
stack: 是固定大小的,遵循先入后出的顺序,并且存取速度比较快
示例 15 : GC是什么?为什么要有GC?
GC是Garbage Collection的缩写,即垃圾回收
这里所谓的垃圾,指的是那些不再被使用的对象,JVM的垃圾回收机制使得开发人员从无聊、容易犯错的手动释放内存资源的过程中解放出来。
示例 16 : short s1 = 1; s1 = s1 + 1;有什么错?
short s1 = 1; 这一句没有错误,编译器会自动把1这个整数处理为short.
s1 = s1 + 1; 右侧的表达式会返回一个Int类型的整数,再把这个int类型的整数赋给short类型的s1的时候,就会出现强制转换错误
示例 17 : Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
Math.round 的意思是+0.5取整数
Math.round(11.5)即11.5+0.5 = 12
Math.round(-11.5) 即 -11.5+0.5 = -11
示例 18 : String s = new String("xyz");创建了几个String Object?
String s = new String("xyz");
首先构造方法 new String("xyz");中的"xyz"这本身就是一个字符串对象
然后 new关键字一定会创建一个对象
所以总共创建了两个String对象
示例 19 : Java有没有goto?
有,goto是关键字,但是是保留字,并不具备功能性
示例 20 : 接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承实体类(concrete class)?
可以,比如List就继承了接Collection
可以,比如 MouseAdapter鼠标监听适配器 是一个抽象类,并且实现了MouseListener接口
可以,所有抽象类,都继承了Object
示例 21 : List, Set, Map是否继承自Collection接口?
List 和 Set继承了Collection接口
但是Map和Collection之间没有继承关系,因为一个是键值对容器,一个是单值容器,无法兼容
示例 22 : abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
都不可以
示例 23 : 数组有没有length()这个方法? String有没有length()这个方法?
数组获取长度的手段是 .length属性
String获取长度的手段是length()方法
集合获取长度的手段是 size()方法
文件获取长度的手段是 length()方法
示例 24 : Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?
以HashSet为例,判断重复逻辑是:
1】先看hashcode是否相同,如果不同,则是不重复的。
2】如果hashcode一样,再比较equals,如果不同,则是不重复的,否则就是重复的
示例 25 : 构造器Constructor是否可被override?是否可以继承String类?
子类不能继承父类的构造方法,所以就不存在重写父类的构造方法。
String是final修饰的,则不能够被继承
示例 26 : swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
switch可以作用在 byte,short,int String,Enum(枚举)上,但是不能作用在long上面
注:switch作用在String上以前的版本是不支持的,最近几个版本的java开始支持
示例 27 : try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
前,try里的return和finally里的return都回支持,但是当前方法只会采纳fianly中return的值
示例 28 : 两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
如果对象要保存在HashSet或HashMap中,它们的equals相等,那么,它们的hashcode值就必须相等。
如果不是要保存在HashSet或HashMap,则与hashcode没有什么关系了,这时候hashcode不等是可以的,例如arrayList存储的对象就不用实现hashcode,当然,我们没有理由不实现,通常都会去实现的。
-----------------------------
1】因为hashCode()方法和equals()方法都可以通过自定义类重写,是可以做到equals相同,但是hashCode不同的
2】但是,在Object类的equals()方法中有这么一段换
通常来讲,在重写这个方法的时候,也需要对hashCode方法进行重写,
以此来保证这两个方法的一致性
当equals返回true的时候,这两个对象一定有相同的hashcode
示例 29 : 垃圾回收的优点和原理。并考虑2种回收机制。
与C语言开发人员需要手段进行内存资源的释放不同,Java提供垃圾回收机制,自动进行GC,将开发人员冲容易犯错的内存资源管理中解放出来。
原理:当某个一个对象,没有任何引用指向它的时候,那么它就满足垃圾回收的条件,在适当的时候,JVM虚拟机进行GC将其回收,释放空间,以供后续再利用。
两种常见的回收机制:
1. 定时回收
每隔30分钟进行一次回收,这种机制的弊端是如果垃圾产生的比较快,有可能30分钟之内垃圾已经把内存占用光了,导致性能变慢
2. 当垃圾占到某个百分比的时候,进行回收
比如,当垃圾占到70%的时候,进行回收。 这种机制的弊端是,如果垃圾产生的频率很快,那么JVM就必须高频率的进行垃圾回收。 而在垃圾回收的过程中,JVM会停顿下来,只做垃圾回收,而影响业务功能的正常运行。
一般说来 JVM会采用两种机制结合的方式进行垃圾回收。
示例 30 : 你所知道的集合类都有哪些?主要方法?
常见的集合
ArrayList ,LinkedList ,HashSet,
HashMap,TreeSet 等等
常见方法:size(),add(),remove()等等
示例 31 : char型变量中能不能存贮一个中文汉字?为什么?
char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,所以,char型变量中当然可以存储汉字啦。不过,如果某个特殊的汉字没有被包含在unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字。
补充说明:unicode编码占用两个字节,所以,char类型的变量也是占用两个字节。
示例 32 : 解析XML文档有哪几种方式?
主要是两种,SAX和DOM
SAX 就是逐行读取,直到找到目标数据为止
DOM 是先全文档加载,然后读取
示例33:关键字throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?
throws用于方法声明上面,表示该方法有可能抛出某个异常
throw抛出一个指定的异常
try catch在try中有可能会抛出某个异常,一旦某个异常抛出后,就会在catch中进行捕捉,他俩一般说来都是成对出现的。
final表示无论是否捕捉住异常,都会执行
示例 34 : 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?
可以包括多个类,但是只能出现一个public修饰的类,但是可以出现多个非public修饰的类。
示例 35 : java中有几种类型的流?
Java中所有的流都是基于字节流,所以最基本的流是
输入/输出字节流
InputStream |OutputStream
在字节流的基础上,封装了字符流
Reader |Writer
进一步,又封装了缓存流
BufferedReader |PrintWriter
以及数据流
DataInputStream |DataOutputStream
对象流
ObjectInputStream
ObjectOutputStream
以及一些其他的奇奇怪怪的流 ~~~
示例 36 : java中会存在内存泄漏吗,请简单描述。
因为Java是自动进行垃圾回收管理的,所以不存在C语言中同等概念的内存泄漏,但是存在Java特色的内存泄漏.
当某些对象不被使用,但是又有非直接引用指向的时候,那么就不满足垃圾回收的条件,而形成内存泄漏。
比如代码中的例子,每个Object创建的时候,有一个引用o指向,接着就被放进了集合al中。 下一个Object创建的时候,上一个Object就没有引用指向了。
这些Object都没有引用指向,但是却放在ArrayList中,而这个Arraylist忘记了回收,那么里面的所有对象,都会一直存活下去,虽然不再被使用了。
示例 37 : java中实现多态的机制是什么?
静态的多态:方法名相同,参数个数或类型不相同。(overloading)动态的多态:子类覆盖父类的方法,将子类的实例传与父类的引用调用的是子类的方法 实现接口的实例传与接口的引用调用的实现类的方法。
类的多态的条件:
1. 父类(接口)引用指向子类对象
2. 方法有重写
示例 38 : 静态变量和实例变量的区别?
静态变量:直接通过类名引用访问,无需示例
实例变量:属于某个对象的属性,必须创建对象后才可以通过该对象来使用
示例 39 : 什么是java序列化,如何实现java序列化?
序列化指的是把一个Java对象,通过某种介质进行传输,比如Socket输入输出流,或者保存在一个文件里
实现java序列化的手段是让该类实现接口Serializable,这个接口是一个标识性接口,没有任何需要实现的方法,仅仅用于表示该类可以序列化。
示例 40 : 是否可以从一个static方法内部发出对非static方法的调用?
不行,因为非static方法需要一个具体的实例才可以调用,而调用static方法的时候,不一定存在一个实例
示例 41 : 在JAVA中,如何跳出当前的多重嵌套循环?
在外部循环的前一行,加上标签
在break的时候使用该标签
即能达到结束多重嵌套循环的效果
示例 42 : List、Map、Set三个接口,存取元素时,各有什么特点?
List 是有顺序的,并且可以重复
Set 是无序的,不可以重复
Map 保存数据的方式是键值对
(参考如何判断Set中的对象是否重复?)
以HashSet为例,判断重复的逻辑是:
1. 首先看hashcode是否相同,如果不同,就是不重复的
2. 如果hashcode一样,再比较equals,如果不同,就是不重复的,否则就是重复的。
示例 43 : Anonymous Inner Class (匿名内部类)是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
匿名内部类本质上就是在继承其他类,实现其他接口
如例:
匿名类1,就是继承了Thread
匿名类2,就是实现了Runnable接口
示例 44 : 内部类可以引用他包含类的成员吗?有没有什么限制?
可以使用
如果是非静态内部类,可是使用外部类的所有成员
如果是静态内部类,只能使用外部类的静态成员
示例 45 : 多线程有几种实现方法,都是什么?
通常来讲,Java创建一个线程有三种方式
1. 继承一个Thread类
2. 实现Runnable接口
3. 匿名内部类
注: 启动线程是start()方法,run()并不能启动一个新的线程
(详见线程知识总结.docx文件)
示例 46 : sleep()和wait()有什么区别?
首先sleep和wait之间没有任何关系
sleep 是Thread类的方法,指的是当前线程暂停。
wait 是Object类的方法, 指的占用当前对象的线程临时释放对当前对象的占用,以使得其他线程有机会占用当前对象。 所以调用wait方法一定是在synchronized中进行
示例 47 : 说出数据连接池的工作机制是什么?
数据库连接池原理:
因为创建连接和关闭连接的行为是非常耗时的,会显著降低软件的性能表现。解决办法就是先创建n条数据库连接Connection,循环使用,但是不进行关闭,这样再执行SQL语句,就不需要额外创建连接了,直接使用现成的连接就可以了,从而节约了创建连接和关闭连接的时间开销。
示例 48 : 简述synchronized和java.util.concurrent.locks.Lock的异同 ?
1. Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现,Lock是代码层面的实现。
2. Lock可以选择性的获取锁,如果一段时间获取不到,可以放弃。synchronized不行,会一根筋一直获取下去。 借助Lock的这个特性,就能够规避死锁,synchronized必须通过谨慎和良好的设计,才能减少死锁的发生。
3. synchronized在发生异常和同步块结束的时候,会自动释放锁。而Lock必须手动释放, 所以如果忘记了释放锁,一样会造成死锁。
示例 49 : Class.forName的作用?为什么要用?
Class.forName常见的场景是在数据库驱动初始化的时候调用。
Class.forName本身的意义是加载类到JVM中。 一旦一个类被加载到JVM中,它的静态属性就会被初始化,在初始化的过程中就会执行相关代码,从而达到"加载驱动的效果"
示例 50 : 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法
这要看情况而定,如果该对象的其他方法也是有synchronized修饰的,那么其他线程就会被挡在外面。否则其他线程就可以进入其他方法。
示例 51 : 给我五个你最常见到的runtime exception。
NullPointerException 空指针异常
ArithmeticException 算术异常,比如除数为零
ClassCastException 类型转换异常
ConcurrentModificationException 同步修改异常,便利一个集合的时候,删除集合的元素,就会抛出该异常
IndexOutOfBoundsException 数组下标越界异常
NegativeArraySizeException 为数组分配的空间是负数异常
面试题 / J2EE / 前端面试题
示例 1 : 常见的选择器
元素选择器
id选择器 对应#符号
class选择器 对应.符号
示例 2 : 行内元素有哪些?块级元素有哪些?
块级元素:div p h1 h2 h3 h4 form ul
行内元素: a b br i span input select
示例 3 : 前端页面有哪三层构成,分别是什么?作用是什么?
结构(内容)层Html
表示层 CSS
行为层 js
示例 4 : 标签上title与alt属性的区别是什么?
Alt 当图片不显示是 用文字代表。
Title 为该属性提供信息
示例 5 : javascript的typeof返回哪些数据类型
Object number function boolean underfind
示例 6 : javascript中如何进行 数字和字符串转换
数字转换为字符串:
toString()
字符串转换为数字:
new Number()
示例 7 : 如何隐藏一个元素
CSS隐藏元素有两种方式
display:none; (不占位置)
visibility:hidden; (要占位置)
JQuery方式隐藏元素方式
$(selector).hide()
面试题 / J2EE / J2EE服务端面试题
示例 1 : 9种隐式对象,以及他们的用途
JSP一共有9个隐式对象,分别是
request,response,out
分别代表请求,响应和输出
pageContext 代表当前页面作用域
session 代表当会话作用域
application 代表当全局作用域
config可以获取一些在web.xml中初始化的参数
page表示当前对象
exception 表示异常对象
示例 2 : 3种JSP的指令
<%@page
JSP的基本设置,比如编码方式,import其他类,是否开启EL表达式
<%@include
包含其他的文件
<%@taglib
使用标签库
示例 3 : 2种JSP的动作
<jsp:foward
服务端跳转
<jsp:include
包含其他文件
示例 4 : doGet()和doPost的区别,分别在什么情况下调用
doGet和doPost都是在service()方法后调用的,分别来处理method="get"和method="post"的请求
示例 5 : servlet的init方法和service方法的区别
在Servlet的生命周期中,先调用init进行初始化,而且只调用一次。
接着再调用service,有多少次请求,就调用多少次service
示例 6 : servlet的生命周期
一个Servlet的生命周期由 实例化,初始化,提供服务,销毁,被回收 几个步骤组成
示例 7 : 页面间对象传递的方法
假设是a.jsp传递数据到b.jsp,那么页面间对象传递的方式有如下几种
1. 在a.jsp中request.setAttribute,然后服务端跳转到b.jsp
2. 在a.jsp中session.setAttribute,然后跳转到b.jsp,无所谓客户端还是服务端跳转
3. 在a.jsp中application.setAttribute,然后跳转到b.jsp,无所谓客户端还是服务端跳转
示例 8 : Request常见方法
request.getRequestURL(): 浏览器发出请求时的完整URL,包括协议 主机名 端口(如果有)" +
request.getRequestURI(): 浏览器发出请求的资源名部分,去掉了协议和主机名" +
request.getQueryString(): 请求行中的参数部分,只能显示以get方式发出的参数,post方式的看不到
request.getRemoteAddr(): 浏览器所处于的客户机的IP地址
request.getRemoteHost(): 浏览器所处于的客户机的主机名
request.getRemotePort(): 浏览器所处于的客户机使用的网络端口
request.getLocalAddr(): 服务器的IP地址
request.getLocalName(): 服务器的主机名
request.getMethod(): 得到客户机请求方式一般是GET或者POST
示例 9 : J2EE是技术,还是平台,还是框架
是平台,上面运行各种各样的技术(servlet,jsp,filter,listner)和框架(struts,hibernate,spring)
示例 10 : Servlet与JSP的关系
JSP就是Servlet
示例 11 : 编写JavaBean的注意事项
JavaBean就是实体类
无参构造方法
属性都有public的getter和setter
示例 12 : MVC的各个部分都有哪些技术来实现,分别如何实现
M 模型层代表数据,使用bean,dao等等
V 视图层代表展现,使用html,jsp,css
C 控制层代表控制,使用servlet
示例 13 : JSP中两种include的区别
一种是静态包含,一种是动态包含
如果是指令include
<%@include file="footer.jsp" %>
footer.jsp的内容会被插入到 hello.jsp转译 成的hello_jsp.java中,最后只会生成一个hello_jsp.java文件
如果是动作include
<jsp:include page="footer.jsp" />
footer.jsp的内容不会被插入到 hello.jsp转译 成的hello_jsp.java中,还会有一个footer_jsp.java独立存在。 hello_jsp.java 会在服务端访问footer_.jsp.java,然后把返回的结果,嵌入到响应中。
示例 14 : JSP中两种跳转的方式是什么,区别是什么
分别是服务端跳转和客户端跳转
1】jsp的客户端跳转和Servlet中是一样的。
response.sendRedirect("hello.jsp");
2】与Servlet的服务端跳转一样,也可以使用
request.getRequestDispatcher("hello.jsp").forward(request, response);
或者使用动作,简化代码
<jsp:forward page="hello.jsp"/>
示例 15 : 如何实现在Servlet中用正则表达式对e-mail格式进行验证
示例 16 : 如何处理中文问题
中文问题分几个部分
1. 提交数据的时候使用UTF-8编码
2. 接受数据的时候使用UTF-8解码
3. 显示数据的时候使用UTF-8编码
示例 17 : 简述你对简单Servlet、过滤器、监听器的理解
Servlet 作用是处理获取参数,处理业务,页面跳转
过滤器的作用是拦截请求,一般会用做编码处理,登陆权限验证
监听器的作用是监听Request,Session,Context等等的生命周期,以及其中数据的变化
面试题 / 框架 / HIBERNATE面试题
示例 1 : 什么是HIBERNATE
HIBERANTE是一种轻量级的ORM的实现,是对JDBC的一种封装。
ORM是意思是 对象与关系数据库之间的映射Object Relation Database Mapping.
示例 2 : POJO是什么
POJO的全称是plain old java object
相当于JAVA BEAN,又叫做实体类entity bean
示例 3 : HIBERNATE开发流程
一个完整的hibernate开发流程包含如下这些步骤
1. 配置Hibernate.cfg.xml
里面包含数据库连接信息,哪些HBM,是否使用2级缓存,是否显示SQL,方言等等
2. 配置 hbm 文件
大概是哪个类对应哪张表,属性对应什么字段,各种关系映射,比如ONE-MANY,MANY-ONE,MANY-MANY
3.使用HIBNERATE
通过Configuration拿到SessionFactory,接着拿到Session,然后进行一系列数据库相关的业务操作
示例 4 : one-many怎么配置
以Category和Product的一对多为举例
1. Category中要有一个set的products
2. 在Category.hbm.xml中要有一对多映射
<set name="products" lazy="false">
<key column="cid" not-null="false" />
<one-to-many class="Product" />
</set>
示例 5 : many-one怎么配置
还是以Product和Category为例
1. Product中要有一个category属性
2. 在Product.hbm.xml中 进行many-to-one配置
<many-to-one name="category" class="Category" column="cid" />
示例 6 : many-many怎么配置
以User和Product为例子
1. User中有products属性
2. Product中有users属性
3. 使用如下进行配置
<set name="products" table="user_product" lazy="false">
<key column="uid" />
<many-to-many column="pid" class="Product" />
</set>
示例 7 : get与load的区别
通过id获取Product对象有两种方式,分别是get和load
他们的区别分别在于
1. 延迟加载
2. 对于id不存在的时候的处理
load方式是延迟加载,只有属性被访问的时候才会调用sql语句
get方式是非延迟加载,无论后面的代码是否会访问到属性,马上执行sql语句
package com.how2java.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.how2java.pojo.Product;
public class TestHibernate {
public static void main(String[] args) {
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session s = sf.openSession();
s.beginTransaction();
System.out.println("log1");
Product p = (Product) s.get(Product.class, 1);
System.out.println("log2");
Product p2 = (Product) s.load(Product.class, 2);
System.out.println("log3");
System.out.println(p2.getName());
System.out.println("log4");
s.getTransaction().commit();
s.close();
sf.close();
}
}
示例 8 : 常见查询3种方式
这三种分别是HQL,Criteria和标准SQL
示例 9 : 三种状态
实体类对象在Hibernate中有3种状态
分别是瞬时,持久和脱管
瞬时 指的是没有和hibernate发生任何关系,在数据库中也没有对应的记录,一旦JVM结束,这个对象也就消失了
持久 指得是一个对象和hibernate发生联系,有对应的session,并且在数据库中有对应的一条记录
脱管 指的是一个对象虽然在数据库中有对应的一条记录,但是它所对应的session已经关闭了
步骤 1 :
代码演示3种状态
提问
new 了一个Product();,在数据库中还没有对应的记录,这个时候Product对象的状态是瞬时的。
通过Session的save把该对象保存在了数据库中,该对象也和Session之间产生了联系,此时状态是持久的。
最后把Session关闭了,这个对象在数据库中虽然有对应的数据,但是已经和Session失去了联系,相当于脱离了管理,状态就是脱管的
package com.how2java.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.how2java.pojo.Product;
public class TestHibernate {
/**
* @param args
*/
public static void main(String[] args) {
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session s = sf.openSession();
s.beginTransaction();
Product p = new Product();
p.setName("p1");
System.out.println("此时p是瞬时状态");
s.save(p);
System.out.println("此时p是持久状态");
s.getTransaction().commit();
s.close();
System.out.println("此时p是脱管状态");
sf.close();
}
}
示例 10 : openSession与getCurrentSession的区别
Hibetnate有两种方式获得session,分别是:
OpenSession和getCurrentSession
他们的区别在于
1. 获取的是否是同一个session对象
OpenSession每次都会得到一个新的Session对象
getCurrentSession在同一个线程中,每次都是获取想同的Session对象,但是在不同的线程中获取的是不同的Session对象
2. 事务提交的必要性
openSession只有在增加,删除,修改的时候需要事务,查询时不需要的
getCurrentSession是所有操作都必须放在事务中进行,并且提交事务后,session就自动关闭,不能够再进行关闭
-------------------------------------------------
步骤 1 : OpenSession每次都会得到一个新的Session对象
步骤 2 : 相同线程的getCurrentSession
步骤 3 : 不同线程的getCurrentSession
步骤 4 : openSession查询时候不需要事务
步骤 5 : getCurrentSession所有操作都必须放在事务中
步骤 6 : getCurrentSession在提交事务后,session自动关闭
package com.how2java.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.how2java.pojo.Product;
public class TestHibernate {
public static void main(String[] args) throws InterruptedException {
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session s1 = sf.getCurrentSession();
s1.beginTransaction();
s1.get(Product.class, 5);
s1.getTransaction().commit();
s1.close();
sf.close();
}
}
示例 11 : 1级缓存
hibernate默认是开启一级缓存的,一级缓存存放在session上
第一次通过id=1获取对象的时候,session中是没有对应缓存对象的,所以会在"log1"后出现sql查询语句。
第二次通过id=1获取对象的时候,session中有对应的缓存对象,所以在"log2"后不会出现sql查询语句
所以总共会看到一次SQL语句出现
package com.how2java.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import com.how2java.pojo.Category;
public class TestHibernate {
public static void main(String[] args) {
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session s = sf.openSession();
s.beginTransaction();
System.out.println("log1");
Category c1 = (Category)s.get(Category.class, 1);
System.out.println("log2");
Category c2= (Category)s.get(Category.class, 1);
System.out.println("log3");
s.getTransaction().commit();
s.close();
sf.close();
}
}
示例 12 : 2级缓存如何配置
Hibernate的一级缓存是在Session上,二级缓存是在SessionFactory上
步骤 1 : 先看没有开启二级缓存的情况
步骤 2 : hibernate.cfg.xml中增加对二级缓存的配置
步骤 3 : ehcache.xml
步骤 4 : 设置HBM
步骤 5 : 测试效果
配置方式:
要在hibernate.cfg.xml中开启
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
面试题 / 框架 / STRUTS面试题
示例 1 : 什么是struts
Struts2 是基于MVC的WEB框架
其中Action充当控制层C
模块层 M: dao,hiberante,jdbc
视图层 V: jsp
示例 2 : Struts开发流程
以addUser为例子
1.UserDAO用于保存User
2.addUser.jsp 页面用于提交数据
3.UserAction, 提供User的setter,getter,用于注入页面提交的user数据
4.Struts.xml 配置 addUser -> UserAction, 默认exexute方法,返回success.jsp页面
5. UserAction提供execute方法调用UserDAO保存数据
示例 3 : Action什么时候被调用
当该Action对应的路径被访问的时候,Struts通过struts.xml定位到该Action,实例化,并调用相应的方法
示例 4 : Action是一个实例还是多个?
多个实例,每次访问Action都会生成一个新的实例。
相比较的Servlet,只有一个实例
面试题 / 框架 / SPRING面试题
示例 1 : 什么是IOC
IOC: Inversion of control反转控制。 比如以前创建一个对象,需要自己主动new一个对象,通过IOC,对象的创建交由Spring框架 创建,开发人员直接使用已经创建好的对象。
--------------------------------------------
Spring是一个基于IOC和AOP的结构J2EE系统的框架
IOC 反转控制 是Spring的基础,Inversion Of Control
简单说就是创建对象由以前的程序员自己new构造方法来调用,变成了交由Spring创建对象
DI 依赖注入 Dependency Inject. 简单地说就是拿到的对象的属性,已经被注入好相关值了,直接使用即可
示例 2 : 什么是DI
DI 依赖注入 Dependency Inject. 简单地说就是拿到的对象的属性,已经被注入好相关值了,直接使用即可
DI: Dependency Injury依赖注入。 通过IOC创建对象的时候,可以注入字符串甚至其他对象。 比如DAO就会注入session factory.
通常IOC和DI是紧密结合,一起使用的
示例 3 : 什么是AOP
AOP: 面向切面编程。
把功能划分为核心业务功能和其他的周边辅助功能,比如日志,性能统计,事务等等。其他的周边辅助功能可以都看作切面功能。核心功能和切面功能分别独立开发,通过面向切面编程,可以有机的把核心业务功能和切面功能根据需求结合在一起。比如增加操作可以和事务切面结合在一起,查询操作可以和性能统计切面结合在一起。
在配置方面,要配置切面,切点,并且通过aspect:config把切面和切点结合起来。
面试题 / 框架 / SSH面试题
主体思路是:Action的创建,由本来的struts管理,交由Spring来进行管理。示例 1 : SSH整合思路,怎么实现
Spring在创建 Action的时候,就会注入DAO
而DAO又继承于HibernateTemplate,并且在被Spring创建的时候,注入了SessionFactory.
由此,Action在进行业务操作的时候,比如执行execute的时候,就可以使用已经和hibernate联系起来的dao了。
实现:
增加一个jar包:struts2-spring-plugin.xxx.jar
在Struts.xml添加struts.objectFactory=spring
在applicationContext.xml
进行action的管理,action注入DAO,DAO注入SESSIONFACTORY,SessionFacotry注入Datasource.
示例 2 : SSH整合的好处和优点
Action在注入dao后,只需要专注于业务操作
维护和扩展更容易
详情学习,请看http://how2j.cn/stage/30.html