java面试常见问题

一.  Hibernate和MyBatis的区别:

1. Hibernate是全自动的,MyBatis是半自动的。

Hibernate完全可以通过对象关系模型实现对数据库的操作,同时对象的属性和数据库中的字段可以通过对象关系映射一一对应,从而通过hql语句来生成sql语句。而MyBatis仅有基本的字段映射,数据库表和对象关系仍然需要手动拼写sql来实现和管理。

2. Hibernate数据库移植性远大于MyBatis。

Hibernate通过自身的对象映射结构和hql语言,很大程度上降低了java对象和数据库之间的耦合性,而MyBatis虽然是xml配置方式,当时其中的sql语句需要自行编写,而不同数据库的sql规则不尽相同,因此移植性比较差。

3. Hibernate拥有完整的日志系统,MyBatis差一些。

Hibernate日志系统非常健全,设计广泛,且日志配置属性可以写入hibernate.cfg.xml和spring配置文件以及log4j.properties中,包括:sql记录、优化警告、缓存提示、脏数据警告等;而MyBatis除了基本记录功能外,其他功能薄弱很多。

4. sql优化和扩展方面,MyBatis比Hibernate方便许多。

因为MyBatis的sql都是写在xml里,且是原生的,因此sql优化和扩展都方便许多。而Hibernate的sql大部分是自动生成的,无法直接维护,即便有hql,功能也不及sql强大;当然,Hibernate也支持sql,但是开发模式与ORM不同,需要转换思维,使用不是很方便。因此在sql优化和扩展性方面,Hibernate不及MyBatis。

二. SpringMVC工作流程:

1. 客户端的http请求提交到DispatcherServlet;

2. DispatcherServlet收到请求调用HandlerMapping处理器映射器;

3. 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;

4. DispatcherServlet调用HandlerAdapter处理器适配器;

5. HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器);

6. Controller执行完成返回ModelAndView;

7. HandlerAdapter将Controller执行结果返回给DispatcherServlet;

8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器;

9. ViewReslover解析后具体返回View。

10. DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中);

11. DispatcherServlet响应用户。

三. Spring的ioc和aop:

1. IOC(Invenstion Of Control)指的是控制反转,也可以理解为依赖注入(Dependecy Of Injection),它并不是一种技术实现,而是一种设计思想。

    在传统开发过程中,当需要另外一个角色协助的时候,通常需要调用者创建(New)被调用者的实例。然而在Spring中,相互依赖对象的创建、协调工作交给Spring容器来处理,每个对象只需要关注其自身的业务逻辑关系就可以了,一定程度上促进了松耦合。从这个角度看,获取依赖对象的方式变成了由Spring容器控制对象如何获取外部资源,即控制反转。

2. AOP(Aspect-OrientedProgramming)指的是面向切面编程,往往被定义为促进软件系统实现关注点分离的技术。主要表现在两个方面:面向切面编程提供声明式事务管理;支持用户自定义的切面。

    应用系统是由许多不同的组件所组成的,每一个组件各自负责一个特定功能,除了实现自身核心功能之外,这些组件还需要承担额外的职责。例如日志、事务管理和安全等核心服务经常融入到自身具有核心业务逻辑的组件当中去。这些系统服务通常被称为横切关注点。因为他们会跨越系统的多个组件。如下例子:

    AOP名词解释:

   连接点:是在应用执行过程中能够插入页面的一个点;

   切点:切点定义了切面在何处要织入的一个或多个连接点;

   切面:是通知和切点的结合,通知和切点共同定义了切面的全部内容;

   引入:引入允许我们向现有类添加新方法和属性;

   织入:是把切面应用到目标对象,并创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。在目标对象的生命周期中(编译器、类加载期、运行期)有多个点可以进行织入;

四. Spring事务:

1. Spring事务执行过程中出现的几种情况:

(1) 脏读:修改数据的同时可以读取数据,

    说明:当事务B对data进行了修改但是未提交事务,此时事务A对data进行读取,并使用事务B修改的数据进行业务处理。

(2) 不可重复读:读取数据的同时可以进行修改,

    说明:事务A,事务B同时对data进行访问,事务A对data进行读取,事务B对data进行修改,当事务A对一次对data进行读取完后事务B提交,此时当事务A第二次读取的数据与第一次不同,这种情况就是不可重复读。

(3) 幻读:读取和修改数据的时候可以新增数据,

    说明:data表有一条数据,事务A对data进行读取,此时事务B对data进行数据新增,此时事务A读取只有一条数据,而最后实际data却有两条数据,就好像出现幻觉一样,称作幻读。

2. Spring事务的四种隔离级别:

(1) READ_UNCOMMITTED(读未提交):可读取未提交事务的操作数据,这种情况会出现脏读;

(2) READ_COMMITTED(读已提交):一个事务需要等另一个事务提交之后才可以进行读取,解决了脏读的问题,但是会出现重复读的问题;

(3) REPEATABLE_READ(重复读):读取事务开启的时候不能对数据进行修改,解决了重复读的问题,但是会出现幻读的问题;

(4) SERIALIZABLE(序列化):这是最高级别的事务隔离级别,此时事务串行按顺序执行,可以避免脏读、不可重复读和幻读问题,但是效率低下,数据库性能降低,一般不推荐使用。
3. Spring事务的七种传播方式:

(1) TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务,如果当前没有事务,则创建一个新的事务,这是默认值;

(2) TransactionDefinition.PROPAGATION_REQUIRED_NEW:不管当时是否存在事务都创建一个新的事务,而把当前事务挂起;

(3) TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务,如果当前没有事务,则以非事务方式继续运行;

(4) TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起;

(5) TransactionDefinition.PROPAGATION_NEVER:非事务方式运行,如果当前存在事务,则抛出异常; 

(6) TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务,如果当前没有事务,则抛出异常;

(7) TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行,如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

4. Spring事务管理分类:

(1) 编程式事务管理:对基于POJO的应用来说,编程式事务管理是唯一选择。用过Hibernate的程序员都知道,我们需要在代码中显示调用beginTransaction()、commit()、rollback()等事务管理方法,这就是编程式事务管理。通过Spring提供的事务管理API,我们可以在代码中灵活控制事务执行。当然,在底层,Spring仍然将事务委托给持久层框架去执行。

(2) 声明式事务管理:这是建立在AOP的基础之上的,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。其优点是去除了繁杂的编程式代码,只需要在配置文件中做好事务规则声明。因为声明式事务管理本身就是一个典型的横切逻辑,正式AOP的用武之地。

四. git和svn的区别:

(1)git是分布式的,svn是集中式的。

(2)git是每个历史版本都存储完整的文件,便于恢复,svn是存储差异文件,历史版本不可恢复。

(3)git可离线完成大部分操作,svn则不能。

(4)git有着更优雅的分支和合并实现。

(5)git有着更强大的撤销修改和修改历史版本的能力。

(6)git速度更快,效率更高。

猜你喜欢

转载自blog.csdn.net/weixin_42669555/article/details/81049417