javaee面试题目

时间:2022-11-24 09:12:31 面试技巧 我要投稿
  • 相关推荐

2017javaee面试题目

  对于Javaee技术员来说,在面试中想要取得面试成功,了解面试题目很有必要,那么2017年的面试题目有哪些呢?以下是阳光网小编帮你们整理的2017javaee面试题目,一起来学习啦。

2017javaee面试题目

  2017javaee面试题目(一)

  1、什么是ORM?

  答:对象关系映射(Object-Relational Mapping,简称ORM)是一种为了解决程序的面向对象模型与数据库的关系模型互不匹配问题的技术;简单的说,ORM是通过使用描述对象和数据库之间映射的元数据(在Java中可以用XML或者是注解),将程序中的对象自动持久化到关系数据库中或者将关系数据库表中的行转换成Java对象,其本质上就是将数据从一种形式转换到另外一种形式。

  2、持久层设计要考虑的问题有哪些?你用过的持久层框架有哪些?

  答:所谓"持久"就是将数据保存到可掉电式存储设备中以便今后使用,简单的说,就是将内存中的数据保存到关系型数据库、文件系统、消息队列等提供持久化支持的设备中。持久层就是系统中专注于实现数据持久化的相对独立的层面。 持久层设计的目标包括:

  - 数据存储逻辑的分离,提供抽象化的数据访问接口。

  - 数据访问底层实现的分离,可以在不修改代码的情况下切换底层实现。

  - 资源管理和调度的分离,在数据访问层实现统一的资源调度(如缓存机制)。

  - 数据抽象,提供更面向对象的数据操作。

  持久层框架有:

  - Hibernate

  - MyBatis

  - TopLink

  - Guzz

  - jOOQ

  - Spring Data

  - ActiveJDBC

  3、Hibernate中SessionFactory是线程安全的吗?Session是线程安全的吗(两个线程能够共享同一个Session吗)?

  答:SessionFactory对应Hibernate的一个数据存储的概念,它是线程安全的,可以被多个线程并发访问。SessionFactory一般只会在启动的时候构建。对于应用程序,最好将SessionFactory通过单例模式进行封装以便于访问。

  Session是一个轻量级非线程安全的对象(线程间不能共享session),它表示与数据库进行交互的一个工作单元。Session是由SessionFactory创建的,在任务完成之后它会被关闭。Session是持久层服务对外提供的主要接口。Session会延迟获取数据库连接(也就是在需要的时候才会获取)。为了避免创建太多的session,可以使用ThreadLocal将session和当前线程绑定在一起,这样可以让同一个线程获得的总是同一个session。Hibernate 3中SessionFactory的getCurrentSession()方法就可以做到。

  4、Hibernate中Session的load和get方法的区别是什么?

  答:主要有以下三项区别:

  ① 如果没有找到符合条件的记录,get方法返回null,load方法抛出异常。

  ② get方法直接返回实体类对象,load方法返回实体类对象的代理。

  ③ 在Hibernate 3之前,get方法只在一级缓存中进行数据查找,如果没有找到对应的数据则越过二级缓存,直接发出SQL语句完成数据读取;load方法则可以从二级缓存中获取数据;从Hibernate 3开始,get方法不再是对二级缓存只写不读,它也是可以访问二级缓存的。

  说明:对于load()方法Hibernate认为该数据在数据库中一定存在可以放心的使用代理来实现延迟加载,如果没有数据就抛出异常,而通过get()方法获取的数据可以不存在。

  4、Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法分别是做什么的?有什么区别?

  答:Hibernate的对象有三种状态:瞬时态(transient)、持久态(persistent)和游离态(detached)。瞬时态的实例可以通过调用save()、persist()或者saveOrUpdate()方法变成持久态;游离态的`实例可以通过调用 update()、saveOrUpdate()、lock()或者replicate()变成持久态。save()和persist()将会引发SQL的INSERT语句,而update()或merge()会引发UPDATE语句。save()和update()的区别在于一个是将瞬时态对象变成持久态,一个是将游离态对象变为持久态。merge()方法可以完成save()和update()方法的功能,它的意图是将新的状态合并到已有的持久化对象上或创建新的持久化对象。

  对于persist()方法,按照官方文档的说明:① persist()方法把一个瞬时态的实例持久化,但是并不保证标识符被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时间;② persist()方法保证当它在一个事务外部被调用的时候并不触发一个INSERT语句,当需要封装一个长会话流程的时候,persist()方法是很有必要的;③ save()方法不保证第②条,它要返回标识符,所以它会立即执行INSERT语句,不管是在事务内部还是外部。至于lock()方法和update()方法的区别,update()方法是把一个已经更改过的脱管状态的对象变成持久状态;lock()方法是把一个没有更改过的脱管状态的对象变成持久状态。

  2017javaee面试题目(二)

  1、阐述Session加载实体对象的过程。

  答:Session加载实体对象的步骤是:

  ① Session在调用数据库查询功能之前,首先会在一级缓存中通过实体类型和主键进行查找,如果一级缓存查找命中且数据状态合法,则直接返回;

  ② 如果一级缓存没有命中,接下来Session会在当前NonExists记录(相当于一个查询黑名单,如果出现重复的无效查询可以迅速做出判断,从而提升性能)中进行查找,如果NonExists中存在同样的查询条件,则返回null;

  ③ 如果一级缓存查询失败则查询二级缓存,如果二级缓存命中则直接返回;

  ④ 如果之前的查询都未命中,则发出SQL语句,如果查询未发现对应记录则将此次查询添加到Session的NonExists中加以记录,并返回null;

  ⑤ 根据映射配置和SQL语句得到ResultSet,并创建对应的实体对象;

  ⑥ 将对象纳入Session(一级缓存)的管理;

  ⑦ 如果有对应的拦截器,则执行拦截器的onLoad方法;

  ⑧ 如果开启并设置了要使用二级缓存,则将数据对象纳入二级缓存; ⑨ 返回数据对象。

  2、Query接口的list方法和iterate方法有什么区别?

  答:

  ① list()方法无法利用一级缓存和二级缓存(对缓存只写不读),它只能在开启查询缓存的前提下使用查询缓存;iterate()方法可以充分利用缓存,如果目标数据只读或者读取频繁,使用iterate()方法可以减少性能开销。

  ② list()方法不会引起N+1查询问题,而iterate()方法可能引起N+1查询问题 说明:关于N+1查询问题,可以参考CSDN上的一篇文章《什么是N+1查询》

  3、Hibernate如何实现分页查询?

  答:通过Hibernate实现分页查询,开发人员只需要提供HQL语句(调用Session的createQuery()方法)或查询条件(调用Session的createCriteria()方法)、设置查询起始行数(调用Query或Criteria接口的setFirstResult()方法)和最大查询行数(调用Query或Criteria接口的setMaxResults()方法),并调用Query或Criteria接口的list()方法,Hibernate会自动生成分页查询的SQL语句。

  4、锁机制有什么用?简述Hibernate的悲观锁和乐观锁机制。

  答:有些业务逻辑在执行过程中要求对数据进行排他性的访问,于是需要通过一些机制保证在此过程中数据被锁住不会被外界修改,这就是所谓的锁机制。

  Hibernate支持悲观锁和乐观锁两种锁机制。悲观锁,顾名思义悲观的认为在数据处理过程中极有可能存在修改数据的并发事务(包括本系统的其他事务或来自外部系统的事务),于是将处理的数据设置为锁定状态。悲观锁必须依赖数据库本身的锁机制才能真正保证数据访问的排他性,关于数据库的锁机制和事务隔离级别在《Java面试题大全(上)》中已经讨论过了。

  乐观锁,顾名思义,对并发事务持乐观态度(认为对数据的并发操作不会经常性的发生),通过更加宽松的锁机制来解决由于悲观锁排他性的数据访问对系统性能造成的严重影响。最常见的乐观锁是通过数据版本标识来实现的`,读取数据时获得数据的版本号,更新数据时将此版本号加1,然后和数据库表对应记录的当前版本号进行比较,如果提交的数据版本号大于数据库中此记录的当前版本号则更新数据,否则认为是过期数据无法更新。Hibernate中通过Session的get()和load()方法从数据库中加载对象时可以通过参数指定使用悲观锁;而乐观锁可以通过给实体类加整型的版本字段再通过XML或@Version注解进行配置。

  提示:使用乐观锁会增加了一个版本字段,很明显这需要额外的空间来存储这个版本字段,浪费了空间,但是乐观锁会让系统具有更好的并发性,这是对时间的节省。因此乐观锁也是典型的空间换时间的策略。

  2017javaee面试题目(三)

  1、如何理解Hibernate的延迟加载机制?在实际应用中,延迟加载与Session关闭的矛盾是如何处理的?

  答:延迟加载就是并不是在读取的时候就把数据加载进来,而是等到使用时再加载。Hibernate使用了虚拟代理机制实现延迟加载,我们使用Session的load()方法加载数据或者一对多关联映射在使用延迟加载的情况下从一的一方加载多的一方,得到的都是虚拟代理,简单的说返回给用户的并不是实体本身,而是实体对象的代理。代理对象在用户调用getter方法时才会去数据库加载数据。但加载数据就需要数据库连接。而当我们把会话关闭时,数据库连接就同时关闭了。 延迟加载与session关闭的矛盾一般可以这样处理:

  ① 关闭延迟加载特性。这种方式操作起来比较简单,因为Hibernate的延迟加载特性是可以通过映射文件或者注解进行配置的,但这种解决方案存在明显的缺陷。首先,出现"no session or session was closed"通常说明系统中已经存在主外键关联,如果去掉延迟加载的话,每次查询的开销都会变得很大。

  ② 在session关闭之前先获取需要查询的数据,可以使用工具方法Hibernate.isInitialized()判断对象是否被加载,如果没有被加载则可以使用Hibernate.initialize()方法加载对象。

  ③ 使用拦截器或过滤器延长Session的`生命周期直到视图获得数据。Spring整合Hibernate提供的OpenSessionInViewFilter和OpenSessionInViewInterceptor就是这种做法。

  2、举一个多对多关联的例子,并说明如何实现多对多关联映射。

  答:例如:商品和订单、学生和课程都是典型的多对多关系。可以在实体类上通过@ManyToMany注解配置多对多关联或者通过映射文件中的和标签配置多对多关联,但是实际项目开发中,很多时候都是将多对多关联映射转换成两个多对一关联映射来实现的。

  3、谈一下你对继承映射的理解。

  答:继承关系的映射策略有三种:

  ① 每个继承结构一张表(table per class hierarchy),不管多少个子类都用一张表。

  ② 每个子类一张表(table per subclass),公共信息放一张表,特有信息放单独的表。

  ③ 每个具体类一张表(table per concrete class),有多少个子类就有多少张表。 第一种方式属于单表策略,其优点在于查询子类对象的时候无需表连接,查询速度快,适合多态查询;缺点是可能导致表很大。后两种方式属于多表策略,其优点在于数据存储紧凑,其缺点是需要进行连接查询,不适合多态查询。

【javaee面试题目】相关文章:

社工面试常见题目12-09

java面试常见题目04-03

面试案例题目04-04

精选面试题目12-09

java经典面试题目12-09

银行面试题目精选12-09

面试题目集锦12-09

测试面试题目11-25

软件面试题目04-07