Java高频面试题(四)
Java高频面试题四
- 六、 框架部分
- 6.1、什么是框架?
- 6.2 、MVC模式
- 6.3、 MVC框架
- 6.4、 简单讲一下struts2的执行流程?
- 6.5、 Struts2中的拦截器,你都用它干什么?
- 6.6 、SpringMVC的执行流程?
- 2.2.6.1MVC的各个部分技术实现?
- 6.7、 struts2和springMVC有什么不同?
- 6.8、 Spring中的两大核心?
- 6.8.1、Spring是什么?
- 6.8.2、 AOP是什么?你都拿它做什么?
- 6.9、Spring几种Bean注入方式?
- 6.9.1、Spring Bean生命周期?
- 6.9.2、Spring对 Bean的管理?
- 6.10、讲一下Spring的事务传播特性
- 6.11 、Spring事务的隔离级别
- 6.11.1、脏读、不可重复读、幻读概念
- 6.11.2、可重复读为什么能够解决脏读?
- 6.11.3、 Spring Boot 与 Spring 的区别
- 6.11.4、SpringBoot 的自动配置是怎么做的?
- 6.11.5、SSM框架的优势
- 6.12、 什么是ORM?
- 6.13、MyBatis,Hibernate?
- 6.13.1、MyBatis怎么实现事务?
- 6.13.2、MyBatis 定义的接口,怎么找到实现的?
- 6.13.3、 mybatis实现动态sql标签
- 6.13.4、 iBatis(mybatis)与Hibernate有什么不同?
- 6.13.5、Hibernate映射对象的状态
- 6.13.6、 介绍一下Hibernate的缓存?
- 6.13.7、什么数据适合放到hibernate第二级缓存中?
- 6.14、 简单讲一下webservice使用的场景?
- 6.15、简单介绍一下activiti?
- 6.16、常用的消息中间件?
- 6.17、Redis介绍
- 6.17.1、使用场景:
- 6.17.2、 Redis和memche的比较?
- 6.17.3、 redis的使用场景?
- 6.17.4、 redis对象保存方式?
- 6.17.5、 Redis数据淘汰机制
- 6.17.6、Java访问Redis
- 6.17.7、 Redis集群
(根据自己的面试经验总结的知识点,内容比较浅显,有问题的地方欢迎指正呀)
六、 框架部分
6.1、什么是框架?
框架(Framework)是一个框子——指其约束性,也是一个架子——指其支撑性。
IT语境中的框架,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构。在此结构上可以根据具体问题扩展、安插更多的组成部分,从而更迅速和方便地构建完整的解决问题的方案。
- 框架本身一般不完整到可以解决特定问题,但是可以帮助您快速解决特定问题;没有框架所有的工作都从零开始做,有了框架,为我们提供了一定的功能,我们就可以在框架的基础上开发,极大的解放了生产力。不同的框架,是为了解决不同领域的问题。一定要为了解决问题才去学习框架。
- 框架天生就是为扩展而设计的;
- 框架里面可以为后续扩展的组件提供很多辅助性、支撑性的方便易用的实用工具(utilities),也就是说框架时常配套了一些帮助解决某类问题的库(libraries)或工具(tools)。 java中就是一系列的jar包,其本质就是对jdk功能的扩展.
6.2 、MVC模式
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。最简单的、最经典就是Jsp(view) +Servlet(controller) + JavaBean(model)
1、当控制器收到来自用户的请求
2、控制器调用JavaBean完成业务
3、完成业务后通过控制器跳转JSP页面的方式给用户反馈信息
4、Jsp个用户做出响应。
5、控制器都是核心
6.3、 MVC框架
- 什么是MVC框架?
是为了解决传统MVC模式(Jsp + Servlet + JavaBean)的一些问题而出现的框架。 - 传统MVC模式问题
(1)所有的Servlet和Servlet映射都要配置在web.xml中,如果项目太大,web.xml就太庞大,并且不能实现模块化管理。
(2)Servlet的主要功能就是接受参数、调用逻辑、跳转页面,比如像其他字符编码、文件上传等功能也要写在Servlet中,不能让Servlet主要功能而需要做处理一下特例。
(3)接受参数比较麻烦(String name = request.getParameter(“name”),User user=new User user.setName(name)),不能通过model接收,只能单个接收,接收完成后转换封装model.
(4)跳转页面方式比较单一(forword,redirect),并且当我的页面名称发生改变时需要修改Servlet源代码. - 现在比较常用的MVC框架有:
struts
webwork
Struts2
Spring MVC
6.4、 简单讲一下struts2的执行流程?
- 一个请求在Struts2框架中的处理大概分为以下几个步骤:
/*
1、客户端浏览器发出HTTP请求。
2、根据web.xml配置,该请求被FilterDispatcher(核心控制器,会过滤请求)接收。
3、根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton。
4、Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。
5、Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面。
6、返回HTTP响应到客户端浏览器。
*/ - 简化的步骤如下(面试时回答):
1、浏览器发送请求,经过一系列的过滤器后,到达核心过滤器(StrutsPrepareAndExecuteFilter).
2、StrutsPrepareAndExecuteFilter通过ActionMapper判断当前的请求是否需要某个Action处理,如果不需要,则走原来的流程。如果需要则把请求交给ActionProxy来处理
3、ActionProxy通过Configuration Manager询问框架的配置文件(Struts.xml),找到需要调用的Action类;
4、创建一个ActionInvocation实例,来调用Action的对应方法来获取结果集的name,在调用前后会执行相关拦截器。
5、通过结果集的Name知道对应的结果集来对浏览器进行响应。
6、拦截、判断、寻找、执行、响应
6.5、 Struts2中的拦截器,你都用它干什么?
java里的拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用部分的方式。
在AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。
简化的答案如下(面试时回答):
struts2中的的功能(参数处理、文件上传、字符编码等)都是通过系统拦截器实现的。
如果业务需要,当然我们也可以自定义拦截器,进行可插拔配置,在执行Action的方法前后、加入相关逻辑完成业务。
使用场景:
1、用户登录判断,在执行Action的前面判断是否已经登录,如果没有登录的跳转到登录页面。
2、用户权限判断,在执行Action的前面判断是否具有,如果没有权限就给出提示信息。
3、操作日志…
6.6 、SpringMVC的执行流程?
- 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;
- DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
- DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法)
- 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
(1)HttpMessageConveter:将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
(2)数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
(3)数据根式化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期等
(4)数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中 - Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
- 根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
- ViewResolver 结合Model和View,来渲染视图
- 将渲染结果返回给客户端。
快速记忆技巧:
核心控制器捕获请求、查找Handler、执行Handler、选择ViewResolver,通过ViewResolver渲染视图并返回
2.2.6.1MVC的各个部分技术实现?
M(Model) 模型 javabean
V(View) 视图 html jsp volicity freemaker
C(Control) 控制器 Servlet,Action
Jsp+Servlet+javabean 最经典mvc模式,实际上就是model2的实现方式,就是把视图和逻辑隔离开来
Model1的方式 jsp+service+dao
MOdel2的方式 jsp+servlet+service+dao
使用struts2和springmvc这样的mvc框架后,jsp+核心控制器+action+javabean
6.7、 struts2和springMVC有什么不同?
目前企业中使用SpringMvc的比例已经远远超过Struts2,那么两者到底有什么区别,是很多初学者比较关注的问题,下面我们就来对SpringMvc和Struts2进行各方面的比较:
核心控制器(前端控制器、预处理控制器):对于使用过mvc框架的人来说这个词应该不会陌生,核心控制器的主要用途是处理所有的请求,然后对那些特殊的请求 (控制器)统一的进行处理(字符编码、文件上传、参数接受、异常处理等等),spring mvc核心控制器是Servlet,而Struts2是Filter。
控制器实例:Spring Mvc会比Struts快一些(理论上)。Spring Mvc是基于方法设计,而Sturts是基于对象,每次发一次请求都会实例一个action,每个action都会被注入 属性,而Spring更像Servlet一样,只有一个实例,每次请求执行对应的方法即可(注意:由于是单例实例,所以应当避免全局变量的修改,这样会产生线程安全问题)。
管理方式:大部分的公司的核心架构中,就会使用到spring,而spring mvc又是spring中的一个模块,所以spring对于spring mvc的控制器管理更加简单方便,而且提供了全 注解方式进行管理,各种功能的注解都比较全面,使用简单,而struts2需要采用XML很多的配置参数来管理(虽然也可以采用注解,但是几乎没有公司那 样使用)。
参数传递:Struts2中自身提供多种参数接受,其实都是通过(ValueStack)进行传递和赋值,而SpringMvc是通过方法的参数进行接收。
学习难度:Struts更加很多新的技术点,比如拦截器、值栈及OGNL表达式,学习成本较高,springmvc 比较简单,很较少的时间都能上手。
处理ajax请求:spring mvc处理ajax请求,直接通过返回数据,方法中使用注解@ResponseBody,spring mvc自动帮我们对象转换为JSON数据。而struts2是通过插件的方式进行处理
两者地位:在SpringMVC流行起来之前,Struts2在MVC框架中占核心地位,随着SpringMVC的出现,SpringMVC慢慢的取代struts2,但是很多企业都是原来搭建的框架,使用Struts2较多。
6.8、 Spring中的两大核心?
6.8.1、Spring是什么?
spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架(相对于重量级的EJB),主要是针对javaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts框架,ibatis框架等组合使用。
- IOC或DI(Dependency Injection)
IOC控制权反转:控制反转,是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
原来:我的Service需要调用DAO,Service就需要创建DAO,控制权在我的手上
Spring:Spring发现你Service依赖于dao,就给你注入。核心原理:就是配置文件+反射(工厂也可以)+容器(map) ,控制权在Spring手上 - AOP:面向切面编程
核心原理:能够将那些与业务无关,却为业务模块所共同调用的逻辑或者责任(例如:事务处理、日志管理、权限控制等)封装起来,便于减少心态重复的代码,降低模块间的耦合度,并有利于未来的可扩展性和可维护性。(使用动态代理的设计模式在执行方法前后或出现异常做加入相关逻辑。)
6.8.2、 AOP是什么?你都拿它做什么?
1、AOP:面向切面编程
2、核心原理:使用动态代理的设计模式在执行方法前后或出现异常做加入相关逻辑。
我们主要使用AOP来做:
1、事务处理 执行方法前,开启事务、执行完成后关闭事务、出现异常后回滚事务
2、权限判断 在执行方法前,判断是否具有权限
3、日志 在执行前进行日志处理
6.9、Spring几种Bean注入方式?
- 构造器注入
构造器注入顾名思义就是在程序组件中实现构造器,构造器可以是一个也可以是多个 - 设值注入(setter方式注入)
设值注入就是通过setXxxx方法将bean注入到组件中 - Feild方式注入(注解方式注入)。
6.9.1、Spring Bean生命周期?
- 实例化一个Bean--也就是我们常说的new;
按照Spring上下文对实例化的Bean进行配置--也就是IOC注入;
如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值 - 按照Spring上下文对实例化的Bean进行配置--也就是IOC注入;
- 如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值
- 如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(setBeanFactory(BeanFactory)传递的是Spring工厂自身(可以用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就可以);
- 如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(同样这个方式也可以实现步骤4的内容,但比4更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法);
- 如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;
- 如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。
- 如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法、;
注:以上工作完成以后就可以应用这个Bean了,那这个Bean是一个Singleton的,所以一般情况下我们调用同一个id的Bean会是在内容地址相同的实例,当然在Spring配置文件中也可以配置非Singleton,这里我们不做赘述。 - 当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;
- 最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。
6.9.2、Spring对 Bean的管理?
- BeanFactory: BeanFactory采用了工厂设计模式,负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的生命周期。
- ApplicationContext:除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能:国际化支持、aop、事务等。
- BeanFactory在解析配置文件时并不会初始化对象,只有在使用对象getBean()才会对该对象进行初始化,而ApplicationContext在解析配置文件时对配置文件中的所有对象都初始化了,getBean()方法只是获取对象的过程。
6.10、讲一下Spring的事务传播特性
多个事务存在是怎么处理的策略
- Required 需要: 如果存在一个事务,则支持当前事务。如果没有事务则开启
- Supports 支持 :如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
- Mandatory 必要的 :如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
- required_new 总是开启一个新的事务:如果一个事务已经存在,则将这个存在的事务挂起。
- Not_support 不支持:总是非事务地执行,并挂起任何存在的事务。
- Never 绝不 :总是非事务地执行,如果存在一个活动事务,则抛出异常
- Nested 嵌套的 :如果有就嵌套、没有就开启事务
6.11 、Spring事务的隔离级别
- ISOLATION_DEFAULT:这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
- ISOLATION_READ_UNCOMMITTED读未提交:这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
- ISOLATION_READ_COMMITTED读已提交:保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
- ISOLATION_REPEATABLE_READ可重复读:这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。 它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
- ISOLATION_SERIALIZABLE 可串行:这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。
6.11.1、脏读、不可重复读、幻读概念
- 脏读: 读到了未提交的。指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据, 那么另外一 个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。
- 不可重复读: 读到了update的。指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。 那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
- 幻读: 读到了insert的。指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及 到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
6.11.2、可重复读为什么能够解决脏读?
这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。这种隔离级别可以防止除幻读外的其他问题。因为可重复读中有两个字断(1)版本号:每经过一次操作版本号+1,当读取版本号时,只能够读到比当前版本号小的(2)删除字段(不太准确)
6.11.3、 Spring Boot 与 Spring 的区别
Spring Boot可以建立独立的Spring应用程序;
内嵌了如Tomcat,Jetty和Undertow这样的容器,也就是说可以直接跑起来,用不着再做部署工作了。
无需再像Spring那样搞一堆繁琐的xml文件的配置;
可以自动配置Spring;
提供了一些现有的功能,如量度工具,表单数据验证以及一些外部配置这样的一些第三方功能;
提供的POM可以简化Maven的配置
6.11.4、SpringBoot 的自动配置是怎么做的?
- 先答为什么需要自动配置?
顾名思义,自动配置的意义是利用这种模式代替了配置 XML 繁琐模式。以前使用 Spring MVC ,需要进行配置组件扫描、调度器、视图解析器等,使用 Spring Boot 自动配置后,只需要添加 MVC 组件即可自动配置所需要的 Bean。所有自动配置的实现都在 spring-boot-autoconfigure 依赖中,包括 Spring MVC 、Data 和其它框架的自动配置。 - 接着答spring-boot-autoconfigure 依赖的工作原理?
spring-boot-autoconfigure 依赖的工作原理很简单,通过 @EnableAutoConfiguration 核心注解初始化,并扫描 ClassPath 目录中自动配置类对应依赖。比如工程中有木有添加 Thymeleaf 的 Starter 组件依赖。如果有,就按按一定规则获取默认配置并自动初始化所需要的 Bean。
6.11.5、SSM框架的优势
- Spring的优势:通过Spring的IOC特性,将对象之间的依赖关系交给了Spring控制,方便解耦,简化了开发。通过Spring的AOP特性,对重复模块进行集中,实现事务,日志,权限的控制,提供了对其他优秀开源框架的集成支持
- Spring MVC的优势:SpringMVC是使用了MVC设计思想的轻量级web框架,对web层进行解耦,使我们开发更简洁;与Spring无缝衔接;灵活的数据验证,格式化,数据绑定机制
- Mybatis的优势:数据库的操作(sql)采用xml文件配置,解除了sql和代码的耦合;提供映射标签,支持对象和和数据库orm字段关系的映射,支持对象关系映射标签,支持对象关系的组建提供了xml标签,支持动态的sql
6.12、 什么是ORM?
- 定义:
对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。那么,到底如何实现持久化呢?一种简单的方案是采用硬编码方式(jdbc操作sql方式),为每一种可能的数据库访问操作提供单独的方法。 - 方案存在的不足:
(1)持久化层缺乏弹性。一旦出现业务需求的变更,就必须修改持久化层的接口
(2)持久化层同时与域模型与关系数据库模型绑定,不管域模型还是关系数据库模型发生变化,都要修改持久化曾的相关程序代码,增加了软件的维护难度。
6.13、MyBatis,Hibernate?
- 什么是mybatis?
mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。
mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。 - 什么是hibernate?
hibernate是数据访问层的框架,对jdbc进行了封装,使用hibernate可以直接访问对象,hibernate自动将此访问转换为sql执行,从而达到间接访问数据库的目的,简化了数据访问层的代码开发。 - hibernate和mybatis对比:
共性:采用ORM思想解决了实体和数据库映射的问题,对jdbc进行了封装,屏蔽了jdbc api底层访问细节,使我们不用与jdbc api打交道,就可以完成对数据库的持久化操作。
Hibernate是全自动化ORM的映射工具,
6.13.1、MyBatis怎么实现事务?
- 使用JDBC的事务管理机制:即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())、关闭(close())等。
- 使用MANAGED的事务管理机制:这种机制MyBatis自身不会去实现事务管理,而是让程序的容器如(JBOSS,Weblogic)来实现对事务的管理。
6.13.2、MyBatis 定义的接口,怎么找到实现的?
一共五步
- Mapper 接口在初始SqlSessionFactory 注册的。
- Mapper 接口注册在了名为 MapperRegistry 类的 HashMap中, key = Mapper class value = 创建当前Mapper的工厂。
- Mapper 注册之后,可以从SqlSession中get
- SqlSession.getMapper 运用了 JDK动态代理,产生了目标Mapper接口的代理对象。
- 动态代理的 代理类是 MapperProxy ,这里边最终完成了增删改查方法的调用。
6.13.3、 mybatis实现动态sql标签
(1)if
(2)choose (when, otherwise)
(3)trim (where, set)
(1) foreach
(2) bind(了解即可)
(3) insert
6.13.4、 iBatis(mybatis)与Hibernate有什么不同?
- 相同点:
都是java中orm框架、屏蔽jdbc api的底层访问细节,使用我们不用与jdbc api打交道,就可以完成对数据库的持久化操作。jdbc api编程流程固定,还将sql语句与java代码混杂在了一起,经常需要拼凑sql语句,细节很繁琐。
ibatis的好处:屏蔽jdbc api的底层访问细节;将sql语句与java代码进行分离;提供了将结果集自动封装称为实体对象和对象的集合的功能.queryForList返回对象集合,用queryForObject返回单个对象;提供了自动将实体对象的属性传递给sql语句的参数。
Hibername的好处:Hibernate是一个全自动的orm映射工具,它可以自动生成sql语句,并执行并返回java结果。 - 不同点:
1、hibernate要比ibatis功能强大很多。因为hibernate自动生成sql语句。
2、ibatis需要我们自己在xml配置文件中写sql语句,hibernate我们无法直接控制该语句,我们就无法去写特定的高效率的sql。对于一些不太复杂的sql查询,hibernate可以很好帮我们完成,但是,对于特别复杂的查询,hibernate就很难适应了,这时候用ibatis就是不错的选择,因为ibatis还是由我们自己写sql语句。
ibatis可以出来复杂语句,而hibernate不能。
3、ibatis要比hibernate简单的多。ibatis是面向sql的,不同考虑对象间一些复杂的映射关系。
6.13.5、Hibernate映射对象的状态
- 临时状态/瞬时状态(transient):刚刚用new语句创建,没有被持久化,不处于session中(没有使用session的方法去操作临时对象)。该对象成为临时对象
- 持久化状态/托管状态(persistent):已经被持久化,加入到session的缓存中。session是没有关闭该状态的对象为持久化对象。
- 游离状态/脱管状态(detached):已经被持久化,但不处于session中。该状态的对象为游离对象。
- 删除状态(removed):对象有关联的ID,并且在Session管理下,但是已经被计划(事务提交的时候,commit())删除。
6.13.6、 介绍一下Hibernate的缓存?
一、why(为什么要用Hibernate缓存?)
Hibernate是一个持久层框架,经常访问物理数据库。为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。为了提供访问速度,把磁盘或数据库访问变成内存访问。
二、what(Hibernate缓存原理是怎样的?)Hibernate缓存包括两大类:Hibernate一级缓存和Hibernate二级缓存。
- Hibernate一级缓存又称为“Session的缓存”。
Session缓存内置不能被卸载,Session的缓存是事务范围的缓存(Session对象的生命周期通常对应一个数据库事务或者一个应用事务)。一级缓存中,持久化类的每个实例都具有唯一的OID。 - Hibernate二级缓存又称为“SessionFactory的缓存”。
由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。
第二级缓存是可选的,是一个可配置的插件,默认下SessionFactory不会启用这个插件。Hibernate提供了org.hibernate.cache.CacheProvider接口,它充当缓存插件与Hibernate之间的适配器。
面试时简化回答:
Hibernate中的缓存分一级缓存和二级缓存。
一级缓存就是Session级别的缓存,在事务范围内有效是,内置的不能被卸载。二级缓存是SesionFactory级别的缓存,从应用启动到应用结束有效。是可选的,默认没有二级缓存,需要手动开启。
保存数据库后,在内存中保存一份,如果更新了数据库就要同步更新。
6.13.7、什么数据适合放到hibernate第二级缓存中?
1、很少被修改的数据 帖子的最后回复时间
2、经常被查询的数据 电商的地点
3、不是很重要的数据,允许出现偶尔并发的数据
4、不会被并发访问的数据
5、常量数据
扩展:hibernate的二级缓存默认是不支持分布式缓存的。使用memcahe,redis等中央缓存来代替二级缓存。
6.14、 简单讲一下webservice使用的场景?
webservice是一个SOA(面向服务的编程)的架构,它是不依赖于语言,不依赖于平台,可以实现不同的语言间的相互调用,通过Internet进行基于Http协议的网络应用间的交互。
异构系统(不同语言)的整合
不同客户端的整合 浏览器、手机端(android,ios.塞班)、微信单、PC端等终端来访问
实实在在的列子:天气预报:可以通过实现webservice客户端调用远程天气服务实现的。单点登录:一个服务是所有系统的登录
6.15、简单介绍一下activiti?
Activiti是一个业务流程管理(BPM)和工作流系统,适用于开发人员和系统管理员。其核心是超快速,稳定的BPMN2流程引擎。它易于与 Spring集成使用。
主要要在OA中,把线下流程放到线上。把现实生活中一些流程固话定义到系统中,然后通过输入表单数据完成业务。
他可用在OA系统的流程管理中:
请假流程 小于三天,一级主管审批,大于三天二级才能审批。
报销流程 1000 2000 3000>…
6.16、常用的消息中间件?
- 定义:消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。对于消息中间件,常见的角色大致也就有Producer(生产者)、Consumer(消费者)。
- 常见的中间件类型
(1)ActiveMQ:ActiveMQ 是Apache出品,最流行的,能力强的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现。
(2)RabbitMQ:是一个消息代理:它接受并转发消息。你可以把它当成一个邮局AMQP协议的领导实现,支持多种场景。淘宝的MySQL集群内部有使用它进行通讯,OpenStack开源云平台的通信组件,最先在金融行业得到运用。
(3)ZeroMQ:史上最快的消息队列系统,这属于是一个类库,直接使用能不快吗!
(4)Kafka:Apache下的一个子项目 。特点:高吞吐,在一台普通的服务器上既可以达到10W/s的吞吐速率;完全的分布式系统。适合处理海量数据。
6.17、Redis介绍
- 定义:
Redis是一个key-value的nosql数据库,先存到内存中,会根据一定的策略持久化(AOF、RDB)到磁盘,即使断电也不会丢失数据,支持的数据类型比较多. - 用处:
主要用来做缓存数据库的数据和web集群时当做中央缓存存放session - Redis 与其他 key - value 缓存产品有以下三个特点:
(1)Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
(2)Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
(3)Redis支持数据的备份,即master-slave模式的数据备份。 - Redis 优势
(1)性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
(2)丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
(3)原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
(4)丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。 - Redis与其他key-value存储有什么不同?
Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
6.17.1、使用场景:
1、缓存:把经常需要查询很少修改的数据放到读速度很快的空间(内存),以便减少下次访问时间,减轻db压力,
2、 计数器:redis中的计数器是原子性的内存操作,可以解决库存溢出问题,进销存,系统存溢出
3、Session缓存服务器:web集群时作为session的缓存服务器
6.17.2、 Redis和memche的比较?
- Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等。
- Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。
- 虚拟内存–Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘
6.17.3、 redis的使用场景?
- 缓存:把经常需要查询的、很少修改数据,放到读速度很快的空间(内存),以便下次访问减少时间。减轻压力,减少访问时间。
- 计数器:redis中的计数器是原子性的内存操作。 可以解决库存溢出问题.进销存系统库存溢出。
- session缓存服务器:web集群时作为session缓存服务器、缓存队列等
6.17.4、 redis对象保存方式?
Json字符串:需要把对象转换为json字符串,当做字符串处理。直接使用set get来设置或者或。
优点:设置和获取比较简单
缺点:没有提供专门的方法,需要把把对象转换为json。(jsonlib)
字节:需要做序列号,就是把对象序列化为字节保存。
如果是担心JSON转对象会消耗资源的情况,这个问题需要考量几个地方,
第一点:就是使用的JSON转换lib是否就会存在性能问题。
第二点:就是数据的数据量级别,如果是存储百万级的大数据对象,建议采用存储序列化对象方式。如果是少量的数据级对象,或者是数据对象字段不多,还是建议采用JSON转换成String方式。
毕竟redis对存储字符类型这部分优化的非常好。具体采用的方式与方法,还要看你所使用的场景。
6.17.5、 Redis数据淘汰机制
在redis 中,允许用户设置最大使用内存大小 server.maxmemory,在内存限定的情况下是很有用的。譬如,在一台 8G 机子上部署了 4 个 redis 服务点,每一个服务点分配 1.5G 的内存大小,减少内存紧张的情况,由此获取更为稳健的服务。
内存大小有限,需要保存有效的数据?
redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。
redis 提供 6种数据淘汰策略:
- volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
- volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
- volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
- allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
- allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
- no-enviction(驱逐):禁止驱逐数据
6.17.6、Java访问Redis
- 使用jedis java客户端来访问redis服务器,有点类似通过jdbc访问mysql一样。
- 当然如果是spring进行集成时,可以使用spring data来访问redis,spring data只是对jedis的二次封装。jdbcTemplate jdbc关系一样
6.17.7、 Redis集群
当一台数据无法满足要求,可以使用reids集群来处理,类似于mysql的读写分离。
redis有三种集群方式:主从复制,哨兵模式和集群。
- 主从复制
(1)主从复制原理:
从服务器连接主服务器,发送SYNC命令;
主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;(从服务器初始化完成)
主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令(从服务器初始化完成后的操作)
(2)主从复制优缺点:
优点:
支持主从复制,主机会自动将数据同步到从机,可以进行读写分离
为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成
Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。
Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求。
Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据
缺点:
Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。 - 哨兵模式
(1)原理:
当主服务器中断服务后,可以将一个从服务器升级为主服务器,以便继续提供服务,但是这个过程需要人工手动来操作。 为此,Redis 2.8中提供了哨兵工具来实现自动化的系统监控和故障恢复功能。
(2)功能:
哨兵的作用就是监控Redis系统的运行状况。它的功能包括以下两个。
1)监控主服务器和从服务器是否正常运行。
2)主服务器出现故障时自动将从服务器转换为主服务器。
(3)工作方式:
每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器,Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING 命令。
如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)
如果一个Master主服务器被标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态
当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主服务器进入了主观下线状态(SDOWN), 则Master主服务器会被标记为客观下线(ODOWN)
在一般情况下, 每个 Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送 INFO 命令。
当Master主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主服务器的所有 Slave从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。
若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。若 Master主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master主服务器的主观下线状态就会被移除。
(4)哨兵模式的优缺点:
优点:
哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有。
主从可以自动切换,系统更健壮,可用性更高。
缺点:
Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。 - Redis-Cluster集群
redis的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台redis服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了cluster模式,实现的redis的分布式存储,也就是说每台redis节点上存储不同的内容。
(1)Redis-Cluster采用无中心结构,它的特点如下:
所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
节点的fail是通过集群中超过半数的节点检测失效时才生效。
客户端与redis节点直连,不需要中间代理层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
(2)工作方式:
在redis的每一个节点上,都有这么两个东西,一个是插槽(slot),它的的取值范围是:0-16383。还有一个就是cluster,可以理解为是一个集群管理的插件。当我们的存取的key到达的时候,redis会根据crc16的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。
为了保证高可用,redis-cluster集群引入了主从模式,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。当其它主节点ping一个主节点A时,如果半数以上的主节点与A通信超时,那么认为主节点A宕机了。如果主节点A和它的从节点A1都宕机了,那么该集群就无法再提供服务了。
Java高频面试题(四)相关推荐
- Java高频面试题(面向对象)
Java高频面试题(面向对象) 面向对象 2.1 类与对象的区别 类是一类事物的整体描述,是一个模板,是对象的抽象,是具有相同行为和特征的对象的描述 对象具体的一个事物,是类的实例化,万事万物皆对象 ...
- 【Java】Java 高频面试题英语版(1)
今天分享 Java 高频面试题英语版.音频文件放在下方,点击获取. [Java]Java 高频面试题英语版(1) [Java]Java 高频面试题英语版(2) [Java]Java 高频面试题英语 ...
- 100道Java高频面试题(阿里面试官整理)
我分享文章的时候,有个读者回复说他去年就关注了我的微信公众号,打算看完我的所有文章,然后去面试,结果我后来很长时间不更新了...所以为了弥补一直等我的娃儿们,给大家的金三银四准备了100道花时间准备的 ...
- java高频面试题(2023最新)
目录 一.java基础 1.八大基础类型 2.java三大特性 3.重载和重写的区别 4.pubilc.protected.(dafault)不写.private修饰符的作用范围 5.==和equal ...
- Java高频面试题汇总(2022)
Java 1. ArrayList和LinkedList的区别 Array(数组)是基于索引(index)的数据结构,它使用索引在数组中搜索和读取数据是很快的. Array获取数据的时间复杂度是O(1 ...
- Java高频面试题:四种经典限流算法,有哪四种?
前言 一.限流操作: 为什么限流一键获取最先java文档. 是防止用户恶意刷新接口,因为部署在外部服务器,并且我们采用websocket的接口实现的,公司没有对硬件升级,导致程序时长崩溃,为了解决这个 ...
- Java高频面试题解析,直戳面试官痛点,多家互联网大厂Offer等你拿
前言 回顾多灾多难的2021年,新冠疫情持续肆虐全球,疫情确诊曲线起伏跌宕,由此引发一系列事件:经济萎缩. 财政刺激.疫苗研发.经济复苏等等.无不牵动着市场的神经."后疫情时代"将 ...
- 5年大厂Java高频面试题及答案整理(二)
31.String s = new String("xyz");创建了几个字符串对象? 答:两个对象,一个是静态区的"xyz",一个是用new创建在堆上的对象. ...
- 5年大厂Java高频面试题及答案整理
1.面向对象的特征有哪些方面? 抽象:将同类对象的共同特征提取出来构造类. 继承:基于基类创建新类. 封装:将数据隐藏起来,对数据的访问只能通过特定接口. 多态性:不同子类型对象对相同消息作出不同响应 ...
最新文章
- 值类型 与引用的 copy
- [Python语音识别项目笔记] 3softmax函数
- 解决Webview加载不完全导致部分js无效
- 前端遮罩层实现_css遮罩层怎么做?
- Linux Bash Shell中的特殊参数含义
- 大型网站架构系列:负载均衡详解(4)
- 智能优化算法:阴阳对优化算法-附代码
- UE4 视频播放打包Pak内
- python ipo模型是指什么?
- PPT里面如何插入斜体文字
- 基于SSM框架的个人博客系统项目毕业设计(代码及论文)
- 北京科技大学计算机专业选课要求,北京科技大学2020年拟在北京招生专业选考科目要求...
- Commvault备份服务器硬件配置设计最佳实践
- ceph分布式存储-常见 PG 故障处理
- 量化投资之工具篇一:Backtrader从入门到精通(3)-Cerebro源代码解读
- 模拟科目二倒车入库训练
- 怎样用matlab做复数运算,MATLAB面向复数运算的设计.doc
- leetcode进行手机解绑与换绑
- python是什么?工作前景如何?怎么算有基础?爬数据违法嘛......
- 视频教程-Access2013数据库入门教程2窗体部分-MySQL