前言
时光飞逝,一年的工作转瞬又将成为历史,2020年即将过去,2021年即将来临。新的一年意味着新的点新的机遇新的挑战、“决心再接再厉,更上一层楼”,一定努力打开一个工作新局面。在2021年,更好地完成工作,扬长避短,在此我们为大家年后金三银四的面试提供一些资料总结如下:
一、JavaEE
(1)、 spring
Eureka怎么实现高可用?
集群:
注册多台 Eureka,把 SpringCloud服务互相注册,客户端从 Eureka获取信息时,按照 Eureka的顺序来访问。
ZuulFilter常用有哪些方法?
run():过滤器的具体业务逻辑
shouldFilter():判断过滤器是否有效
filterOrder():过滤器执行顺序
filterType():过滤器拦截位置
如何实现动态Zuul网关路由转发?
通过path配置拦截请求,通过 Serviceld到配置中心获取转发的服务列表,zuul内部使用 Ribbon实现本地负载均衡和转发。
Zuul网关如何搭建集群?
使用Nginx的 upstream设置Zuul服务集群,通过location拦截请求并转发到 upstream,默认使用轮询机制对Zuul集群发送请求。
负载平衡的意义什么?
通俗易懂的理解:
集群:是把一个的事情交给多个人去做,假如要做1000个产品给一个人做要10天,叫10个人做就是一天;
负载均衡:用来控制集群,他把做的最多的人让他慢慢做休息会,把做的最少的人让他加量让他做多点。
在计算中:
负载平衡可以改善跨计算机计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源的工作负载分布,负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源的过载,使用多个组件进行负载平衡,而不是单个组件,可能会通过冗余来提高可靠性和可用性,负载平衡通常及专用软件或硬件,例如多层交换机或域名系统服务器进程。
服务降级底层是如何实现的?
Hystrix实现服务降级的功能是通过重写 HystrixCommand中的 getFallback()方法,当 Hystrix的run方法或 construct执行发生误时转而执行 getFallback()方法。
什么是 Spring Cloud Bus?
Spring Cloud Bus就像个分布式执行器,用于扩展的 Spring Boot应用程序的配置文件,但也可以用作应用程序之间的通信通道。
Spring Cloud Bus不能单独完成通信,需要配合MQ支持
Spring Cloud Bus一般是配合Spring Cloud Config做配置中心的
Spring Cloud config实时刷新也必须采用 SpringCloud Bus消息总线
Spring Cloud Bus 原理?
发送端(endpoint)构造事件event,将其publish到context上下文中(spring cloud bus有一个父上下文,bootstrap),然后将事件发送到channel中(json串message),接收端从channel中获取到message,将message转为事件event,然后将event事件publish到context上下文中,最后接收端(Listener)收到event,调用服务进行处理。
整个流程中,只有发送/接收端从context上下文中取事件和发送事件是需要我们在代码中明确写出来的,其它部分都由框架封装完成。
SpringCloud Config可以实现实时刷新吗?
springcloud config实时刷新采用 SpringCloud Bus消息总线
什么是服务熔断?什么是服务降级?
熔断机制:
是应对雪崩效应的一种微服务链路保护机制。
当某个微服务不可用或者响应时间太长时,会进行服务降级,进而熔断该节点微服务的调用,快速返回“错误”的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。
在SpringCloud框架里熔断机制通过Hystrix实现,Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内调用20次,如果失败,就会启动熔断机制。
服务降级:
一般是从整体负荷考虑。就是当某个服务熔断之后,服务器将不再被调用,此时客户端可以自己准备一个本地的fallback回调,返回一个缺省值
什么是服务雪崩效应?
雪崩效应是在大型互联网项目中,当某个服务发生宕机时,调用这个服务的其他服务也会发生宕机,大型项目的微服务之间的调用是互通的,这样就会将服务的不可用逐步扩大到各个其他服务中,从而使整个项目的服务宕机崩溃
谈谈你对 Spring 的理解?
Spring 是一个开源框架,为简化企业级应用开发而生。Spring 可以是使简单的 JavaBean 实现以前只有 EJB 才能实现的功能。Spring 是一个 IOC 和 AOP 容器框架。
Spring 容器的主要核心是:
控制反转(IOC),传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new 或者 getInstance 等直接或者间接调用构造方法创建一个对象。而在 spring 开发模式中,spring 容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用 spring 提供的对象就可以了,这是控制反转的思想。
依赖注入(DI),spring 使用 javaBean 对象的 set 方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。
面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等。公用操作处理的过程就是面向切面编程的思想。AOP 底层是动态代理,如果是接口采用 JDK 动态代理,如果是类采用CGLIB 方式实现动态代理。
Spring 中的设计模式有哪些?
工厂模式:
BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
单例模式:
Bean默认为单例模式。
代理模式:
Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
模板方法:
用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
观察者模式:
定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现ApplicationListener。
Spring 的常用注解?
@Required:该注解应用于设值方法
@Autowired:该注解应用于有值设值方法、非设值方法、构造方法和变量。
@Qualifier:该注解和@Autowired 搭配使用,用于消除特定 bean 自动装配的歧义
Spring bean 的生命周期?
Bean 定义:在配置文件里面用
来进行定义。
Bean 初始化:有两种方式初始化:
①在配置文件中通过指定 init-method 属性来完成
②实现 org.springframwork.beans.factory.InitializingBean 接口
Bean 调用:有三种方式可以得到 bean 实例,并进行调用
Bean 销毁:销毁有两种方式
①使用配置文件指定的 destroy-method 属性
②实现 org.springframwork.bean.factory.DisposeableBean 接口
Spring 管理事务的方式?
编程式事务:在代码中硬编码。
声明式事务:在配置文件中配置
声明式事务又分为:
①基于XML的声明式事务
②基于注解的声明式事务
Spring的事务传播行为有哪些?
1、PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
2、PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。
3、PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
4、PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
5、PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
6、PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
7、PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。
Spring事务的隔离级别?
1、ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。
2、ISOLATION_READ_UNCOMMITTED:读未提交,允许另外一个事务可以看到这个事务未提交的数据。
3、ISOLATION_READ_COMMITTED:读已提交,保证一个事务修改的数据提交后才能被另一事务读取,而且能看到该事务对已有记录的更新。
4、ISOLATION_REPEATABLE_READ:可重复读,保证一个事务修改的数据提交后才能被另一事务读取,但是不能看到该事务对已有记录的更新。
5、ISOLATION_SERIALIZABLE:一个事务在执行的过程中完全看不到其他事务对数据库所做的更新。
Spring 的通知是什么?有哪几种类型?
通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过 SpringAOP 框架触发的代码段。
Spring 切面可以应用五种类型的通知:
before:前置通知,在一个方法执行前被调用。
after: 在方法执行之后调用的通知,无论方法执行是否成功。
after-returning: 仅当方法成功完成后执行的通知。
after-throwing: 在方法抛出异常退出时执行的通知。
around: 在方法执行之前和之后调用的通知。
(二)SpringBoot
什么是SpringBoot?
用来简化spring应用的初始搭建以及开发过程,使用特定的方式来进行配置(properties或yml文件)创建独立的spring引用程序 main方法运行,嵌入的Tomcat 无需部署war文件,简化maven配置,自动配置spring添加对应功能starter自动化配置。
Spring Boot、Spring MVC 和 Spring 有什么区别?
1、SpringSpring最重要的特征是依赖注入。所有 SpringModules 不是依赖注入就是 IOC 控制反转。当我们恰当的使用 DI 或者是 IOC 的时候,我们可以开发松耦合应用。松耦合应用的单元测试可以很容易的进行。
2、Spring MVC提供了一种分离式的方法来开发 Web 应用。通过运用像 DispatcherServelet,MoudlAndView 和ViewResolver 等一些简单的概念,开发 Web 应用将会变的非常简单。
3、Spring 和 SpringMVC 的问题在于需要配置大量的参数。
4、Spring Boot 通过一个自动配置和启动的项来目解决这个问题。为了更快的构建产品就绪应用程序,Spring Boot 提供了一些非功能性特征。
Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?
1、@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。
2、@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能。
3、@ComponentScan:Spring组件扫描。
什么是 JavaConfig?
1、面向对象的配置。由于配置被定义为 JavaConfig 中的类,因此用户可以充分利用 Java 中的面向对象功能。一个配置类可以继承另一个,重写它的@Bean 方法等。
2、减少或消除 XML 配置。基于依赖注入原则的外化配置的好处已被证明。但是,许多开发人员不希望在 XML 和 Java 之间来回切换。JavaConfig 为开发人员提供了一种纯 Java 方法来配置与 XML 配置概念相似的 Spring 容器。从技术角度来讲,只使用 JavaConfig 配置类来配置容器是可行的,但实际上很多人认为将JavaConfig 与 XML 混合匹配是理想的。
3、类型安全和重构友好。JavaConfig 提供了一种类型安全的方法来配置 Spring容器。由于 Java 5.0 对泛型的支持,现在可以按类型而不是按名称检索 bean,不需要任何强制转换或基于字符串的查找。
什么是YAML?
YAML是一种人类可读的数据序列化语言。它通常用于配置文件。
与属性文件相比,如果我们想要在配置文件中添加复杂的属性,YAML文件就更加结构化,而且更少混淆。可以看出YAML具有分层配置数据。
bootstrap.yml和application.yml有什么区别?
1、Spring Cloud 构建于 Spring Boot 之上,在 Spring Boot 中有两种上下文,一种是 bootstrap,另外一种是 application。
2、application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置。
3、bootstrap 是应用程序的父上下文,也就是说 bootstrap 加载优先于 applicaton。
4、bootstrap 主要用于从额外的资源来加载配置信息,还可以在本地外部配置文件中解密属性。
5、这两个上下文共用一个环境,它是任何Spring应用程序的外部属性的来源。
6、bootstrap 里面的属性会优先加载,它们默认也不能被本地相同配置覆盖。
7、boostrap 由父 ApplicationContext 加载,比 applicaton 优先加载
8、boostrap 里面的属性不能被覆盖
springboot常用的starter有哪些?
1、spring-boot-starter-web (嵌入tomcat和web开发需要servlet与jsp支持)
2、spring-boot-starter-data-jpa (数据库支持)
3、spring-boot-starter-data-redis (redis数据库支持)
4、spring-boot-starter-data-solr (solr搜索应用框架支持)
5、mybatis-spring-boot-starter (第三方的mybatis集成starter)
Spring Boot 配置加载顺序?
1、properties文件
2、YAML文件
3、系统环境变量
4、命令行参数
Spring Boot 有哪几种读取配置的方式?
@PropertySource
@Value
@Environment
@ConfigurationPropertie
如何使用Spring Boot实现异常处理?
SpringControllerAdvice提供了一种使用处理异常的非常有用的方法。通过实现一个 ControllerAdvice类,来处理控制器类抛出的所有异常。
如何重新加载 Spring Boot上的更改,而无需重新启动服务器?
使用DEV工具来实现。
通过这种依赖关系,可以节省任何更改,嵌入式 tomcat将重新启动。
使用Spring Boot有一个开发工具Dev Tools模块,可以重新加载 Spring Boot上的更改,而无需重新启动服务器。消除每次手动部署更改的需要。Spring Boot在发布它的第一个版本时没有这个功能。该模块将在生产环境中被禁用。它还提供H2数据库控制台以更好地测试应用程序。
Spring Boot中的监视器是什么?
Spring boot actuatorspring是启动框架中的重要功能之一。Spring boot监视器可访问生产环境中正在运行的应用程序的当前状态。有几个指标必须在生产环境中进行检查和监控。即使一些外部应用程序可能正在使用这些服务来向相关人员触发警报消息。监视器模块公开了一组可直接作为 http url rest访问的REST端点来检查状态。
如何在自定义端口上运行 Spring Boot应用程序?
在 application.properties中指定端口serverport=8090。
Spring Boot监听器流程?
1、通过app.addListeners注册进入
2、初始化一个SpringApplicationRunListeners进行处理
3、从spring.factories中读取监听器处理类EventPublishingRunListener
4、通过createSpringFactoriesInstances创建监听器处理类实例
5、调用监听器listeners.starting()的方法来启动。
6、底层把事件处理交给线程池去处理
Spring Boot初始化环境变量流程?
1、调用prepareEnvironment方法去设置环境变量
2、接下来有三个方法getOrCreateEnvironment,configureEnvironment,environmentPrepared
3、getOrCreateEnvironment去初始化系统环境变量
4、configureEnvironment去初始化命令行参数
5、environmentPrepared当广播到来的时候调用onApplicationEnvironmentPreparedEvent方法去使用postProcessEnvironment方法load yml和properties变量
Spring Boot扫描流程?
1、调用run方法中的refreshContext方法
2、用AbstractApplicationContext中的refresh方法
3、委托给invokeBeanFactoryPostProcessors去处理调用链
4、其中一个方法postProcessBeanDefinitionRegistry会去调用processConfigBeanDefinitions解析beandefinitions
5、在processConfigBeanDefinitions中有一个parse方法,其中有componentScanParser.parse的方法,这个方法会扫描当前路径下所有Component组件
如何在 Spring Boot中禁用 Actuator端点安全性?
默认情况下,所有敏感的HTTP端点都是安全的,只有具有 http ACTUATOR角色的用户才能访问它们。安全性是使用标准的 httpservletrequest. isuserinrole..isusernrole方法实施的。可以使用 management. security. enabled= false来禁用安全性。只有在执行机构端点在防火墙后访问时,才建议禁用安全性。
如何实现 Spring Boot应用程序的安全性?
使用 spring--startersecurityboot--依赖项,并且必须添加安全配置。配置类将必须扩展 WebSecurityConfigurerAdapter并覆盖其方法。
什么是 Spring Batch?
Spring Boot Batch提供可重用的函数,这些函数在处理大量记录时非常重要;包括日志/跟踪,事务管理,作业处理统计信息,作业重新启动,跳过和资源管理。它还提供了更先进的技术服务和功能,通过优化和分区技术,可以实现极高批量和高性能批处理作业。简单以及复杂的大批量批处理作业可以高度可扩展的方式利用框架处理重要大量的信息。
(3)springMVC
什么是Spring MVC?
Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。
SpringMVC 的工作原理?
①用户向服务器发送请求,请求被 springMVC 前端控制器 DispatchServlet 捕获;
②DispatcherServle 对请求 URL 进行解析,得到请求资源标识符(URL),然后根据该 URL 调用 HandlerMapping,将请求映射到处理器 HandlerExcutionChain;
③DispatchServlet 根据获得 Handler 选择一个合适的 HandlerAdapter 适配器处理;
④Handler 对数据处理完成以后将返回一个 ModelAndView()对象给 DisPatchServlet;
⑤Handler 返回的 ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet 通过
ViewResolver 试图解析器将逻辑视图转化为真正的视图 View;
⑥DispatcherServle 通过 model 解析出 ModelAndView()中的参数进行解析最终展现出完整的 view 并返回给客户端;
说说Spring MVC的几个重要组件?
1.前端控制器 DispatcherServlet
作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。
2.处理器映射器HandlerMapping
作用:根据请求的URL来查找Handler
3.处理器适配器HandlerAdapter
注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。
4.处理器Handler
5.视图解析器 ViewResolver
作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)
6.视图View
View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)
SpringMVC 常用注解都有哪些?
@requestMapping 用于请求 url 映射。
@RequestBody 注解实现接收 http 请求的 json 数据,将 json 数据转换为 java 对象。
@ResponseBody 注解实现将 controller 方法返回对象转化为 json 响应给客户。
@PathVariable URL 中占位符参数绑定到控制器处理方法的入参中
如何开启注解处理器和适配器?
在 springmvc.xml 中通过开启
如何解决 get 和 post 乱码问题?
post 请求乱码:
在 web.xml 里边配置一个 CharacterEncodingFilter 过滤器。设置为 utf-8。
get 请求的乱码:
两种方法:
①修改 tomcat 配置文件添加编码与工程编码一致。
②对参数进行重新编码 String userName = New String(Request.getParameter("userName").getBytes("ISO8859-1"),"utf-8");
SpringMVC怎么样设定重定向和转发的?
1、转发:在返回值前面加"forward:"
2、重定向:在返回值前面加"redirect:"
Spring MVC是如何进行异常处理?
将异常抛给Spring框架,由Spring框架来处理;我们只需要配置简单的异常处理器
Spring MVC的优点?
基于View框架的无缝集成,采用IOC便于测试
典型的纯MVC架构,Struts是不完全基于MVC框架的
(4)Web应用服务器
Tomcat是什么?
tomcat是一个web应用服务器。比如,我们写的项目打包成war包以后需要放到tomcat指定的目录下。在启动tomcat就可以访问。
Tomcat缺省端口是多少,如何修改?
Tomcat缺省端口是8080;
修改tomcat 端口:
1、找到tomcat目录下的conf文件夹;
2、进入conf文件夹找到server.xml文件
3、在server.xml文件里面找到Connector 标签,把port="8080",改成需求端口即可。
Tomcat 有那几种Connector 运行模式?
bio
nio
aio
什么是Servlet?
Servlet(Servlet Applet),全称Java Servlert 。是用Java编写的服务器端程序。其主要功能在与交互式的浏览和修改数据,生成动态Web内容。狭义的servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet的类,一般情况下,人们将Servlet理解为后者。比如HttpServlet类继承自Servlet类,可以利用继承Http Servlet 来实现Http请求,当不是Http请求的时候,也可以定义其他形式的Servlet。
Servlet请求过程?
Tomcat容器中通过web.xml加载所有的Servlet。
用户在浏览器输入不同的地址,向Tomcat容器请求资源。
Tomcat容器根据地址首先在容器内找到应用ServletTest。
Tomcat容器再根据地址去web.xml找到相应的servlet地址。
Tomcat容器根据找到的servlet地址去web.xml找到相应的Servlet类,并实例化。
Tomcat容器实例化相应的Servlet,首先调用init方法。
Tomcat容器实例化相应的Servlet,首先调用service方法处理用户请求,比如post或者是get。
Servlet处理完成之后,先将数据给Tomcat容器,Tomcat容器再把处理结果给浏览器客户端。
Tomcat容器调用servlet实例的destory方法销毁这个实例。
Tomcat执行流程?
1.请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
2.Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
3.Engine获得请求localhost/项目/页面.jsp,匹配它所拥有的所有虚拟主机Host
4.Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
5.localhost Host获得请求/项目/页面.jsp,匹配它所拥有的所有Context
6.Host匹配到路径为/项目的Context(如果匹配不到就把该请求交给路径名为””的Context去处理)
7.path="/项目"的Context获得请求/页面.jsp,在它的mapping table中寻找对应的servlet
8.Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
9.构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
10.Context把执行完了之后的HttpServletResponse对象返回给Host
11.Host把HttpServletResponse对象返回给Engine
12.Engine把HttpServletResponse对象返回给Connector
13.Connector把HttpServletResponse对象返回给客户browser
Tomcat部署方式?
1.直接把Web项目放在webapps下,Tomcat会自动将其部署
2.在server.xml文件上配置\节点,设置相关的属性即可
3.通过Catalina来进行配置:进入到conf\Catalina\localhost文件下,创建一个xml文件,该文件的名字就是站点的名字。
什么是JBoss ?
JBoss 是一个基于J2EE的开放源代码的应用服务器
在JBoss 7中访问管理控制台的默认端口是什么?
默认端口为9990
独立模式和域模式有什么区别?
独立模式是单个JVM进程, 其中每个JBoss服务器都有其配置。如果你只需要一个JVM或开发环境, 那么独立运行将是完美的选择。
域模式可能具有多个服务器, 其中所有配置都集中管理, 并且经常在生产环境中使用。
每次都验证数据库连接, 如果连接无效, 它将在日志中写警告。
配置”匹配时验证”可能会给数据库带来一些高负载, 因为它可能会创建很多请求。
根据为"background-validation-millis"配置的频率定期验证连接。默认配置设置为零表示禁用。
将"background-validation"设置为true将会创建更少的数据库连接, 并且如果连接失效, 它的副作用将无法立即检测到。
可用于标记文件部署的重要类型有哪些?
.dodeploy –指示部署
.deployed –表示文件已部署
.pending –部署仍在等待中
.undeployed-确认应用程序已取消部署
.failed –由于某种原因部署失败
.skipdeploy –指示JBoss忽略文件以进行自动部署
JBoss中可以部署哪些文件类型?
WAR – Web应用程序档案
SAR –服务档案
JAR – Java存档
EAR –企业应用程序档案
什么是Jetty?
Jetty是一个提供HTTP服务器、HTTP客户端和javax.servlet容器的开源项目
Jetty启动过程?
首先启动设置到Server的Handler
这些Handler将组成一个Handler链
Server会启动链上所有的Handler
启动Connector,打开端口,接受客户端请求。
Jetty和Tomcat的区别?
架构
Jetty的架构比Tomcat的更为简单 Jetty的架构是基于Handler来实现的,主要的扩展功能都可以用Handler来实现,扩展简单。Tomcat的架构是基于容器设计的,进行扩展是需要了解Tomcat的整体设计结构,不易扩展。
性能
Jetty和Tomcat性能方面差异不大 Jetty可以同时处理大量连接而且可以长时间保持连接,适合于web聊天应用等等。Jetty的架构简单,因此作为服务器,Jetty可以按需加载组件,减少不需要的组件,减少了服务器内存开销,从而提高服务器性能。Jetty默认采用NIO结束在处理I/O请求上更占优势,在处理静态资源时,性能较高
处理能力
Tomcat适合处理少数非常繁忙的链接,也就是说链接生命周期短的话,Tomcat的总体性能更高。Tomcat默认采用BIO处理I/O请求,在处理静态资源时,性能较差。
其它
Jetty的应用更加快速,修改简单,对新的Servlet规范的支持较好。Tomcat目前应用比较广泛,对JavaEE和Servlet的支持更加全面,很多特性会直接集成进来。
(五)Hibernate
Hibernate执行流程?
读取并解析配置文件
读取并解析映射信息,创建SessionFactory
打开Sesssion
创建事务Transation
持久化操作
提交事务
关闭Session
关闭SesstionFactory
什么是Hibernate的并发机制?怎么去处理并发问题?
Hibernate并发机制:
1、Hibernate的Session对象是非线程安全的,对于单个请求,单个会话,单个的工作单元(即单个事务,单个线程),它通常只使用一次, 然后就丢弃。
如果一个Session 实例允许共享的话,那些支持并发运行的,例如Http request,session beans将会导致出现资源争用。
如果在Http Session中有hibernate的Session的话,就可能会出现同步访问Http Session。只要用户足够快的点击浏览器的“刷新”, 就会导致两个并发运行的线程使用同一个Session。
2、多个事务并发访问同一块资源,可能会引发第一类丢失更新,脏读,幻读,不可重复读,第二类丢失更新一系列的问题。
解决方案:
①设置事务隔离级别
Serializable:串行化。隔离级别最高
Repeatable Read:可重复读
Read Committed:已提交数据读
Read Uncommitted:未提交数据读。隔离级别最差
②设置锁:乐观锁和悲观锁
乐观锁:使用版本号或时间戳来检测更新丢失,在的映射中设置 optimistic-lock=”all”可以在没有版本或者时间戳属性映射的情况下实现 版本检查,此时Hibernate将比较一行记录的每个字段的状态 行级悲观锁:Hibernate总是使用数据库的锁定机制,从不在内存中锁定对象!只要为JDBC连接指定一下隔 离级别,然后让数据库去搞定一切就够了。类LockMode 定义了Hibernate所需的不同的锁定级别:
LockMode.UPGRADE
LockMode.UPGRADE_NOWAIT
LockMode.READ
Hibernate中的三种数据状态?
临时态(瞬时态/Transient)
不存在于session中,也不存在于数据库中的数据,被称为临时态。
比如:刚刚使用new关键字创建出的对象。
持久态(Persistent)
存在于session中,事务还未提交,提交之后最终会进入数据库的数据,被称为持久态。
比如:刚刚使用session.save()操作的对象。
游离态(脱管态/Detached)
存在于数据库中,但不存在于session中的数据,被称为游离态。
比如:使用了session.save(),并且事务已经提交之后,对象进入数据库,就变成了游离态。
Hibernate 的三种状态之间如何转换?
当对象由瞬时状态(Transient)一save()时,就变成了持久化状态;
当我们在Session里存储对象的时候,实际是在Session的Map里存了一份, 也就是它的缓存里放了一份,然后,又到数据库里存了一份,在缓存里这一份叫持久对象(Persistent)。Session 一 Close()了,它的缓存也都关闭了,整个Session也就失效了,这个时候,这个对象变成了游离状态(Detached),但数据库中还是存在的。
当游离状态(Detached)update()时,又变为了持久状态(Persistent)。
当持久状态(Persistent)delete()时,又变为了瞬时状态(Transient), 此时,数据库中没有与之对应的记录。
介绍一下Hibernate 的缓存机制?
hibernate分为2级缓存
一级缓存又叫session缓存,又叫事务级缓存,生命周期从事务开始到事务结束,一级缓存是hibernate自带的,暴力使用,当我们一创建session就已有这个缓存了。数据库就会自动往缓存存放,
二级缓存是hibernate提供的一组开放的接口方式实现的,都是通过整合第三方的缓存框架来实现的,二级缓存又叫sessionFactory的缓存,可以跨session访问。常用的EHcache、OScache,这个需要一些配置。
当我们每次 查询数据的时候,首先是到一级缓存查看是否存在该对象,如果有直接返回,如果没有就去二级缓存进行查看,如果有直接返回,如果没有在发送SQL到数据库查询数据,
当SQL发送查询回该数据的时候,hibernate会把该对象以主键为标记的形式存储到二级缓存和一级缓存,如果返回的是集合,会把集合打散然后以主键的形式存储到缓存。一级缓存和二级缓存只针对以ID查询的方式生效,get、load方法。
说一下Hibernate的几个核心接口?
Configuration 接口:配置Hibernate,根据其启动hibernate,创建SessionFactory 对象
SessionFactory 接口:初始化Hibernate,充当数据存储源的代理,创建session 对象,sessionFactory 是线程安全的,意味着它的同一个实例可以被应 用的多个线程共享,是重量级、二级缓存
Session 接口:负责保存、更新、删除、加载和查询对象,是线程不安全的, 避免多个线程共享同一个session,是轻量级、一级缓存
Transaction 接口:管理事务
Query 和Criteria 接口:执行数据库的查询。
get 和 load 的区别?
get 是立即加载,load 是延时加载。
get 会先查一级缓存,再查二级缓存,然后查数据库;
load 会先查一级缓存,如果没有找到,就创建代理对象,等需要的时候去查询二级缓存和数据库。(这里就体现 load 的延迟加载的特性。)
get 如果没有找到会返回 null,load 如果没有找到会抛出异常。
当我们使用 session.load()方法来加载一个对象时,此时并不会发出 sql 语句,当前得到的这个对象其实是一个代理对象,这个代理对象只保存了实体对象的 id 值,只有当我们要使用这个对象,得到其它属性时,这个时候才会发出 sql 语句,从数据库中去查询我们的对象;
相对于 load 的延迟加载方式,get 就直接的多,当我们使用session.get()方法来得到一个对象时,不管我们使不使用这个对象,此时都会发出 sql 语句去从数据库中查询出来。
Hibernate 有几种查询方式?
4种:
HQL 通过Hibernate提供的查询语言进行查询。Hibernate Query lanague
EJBQL(JPQL 1.0) 是EJB提供的查询语言
QBC(query by cretira)通过Cretira接口进行查询
QBE(query by Example) 通过Example编程接口进行查询
从功能强弱上排序:
NativeSQL > HQL > EJBQL(JPQL 1.0) >QBC(query by cretira) >QBE(query by Example)
QBC(Query By Criteria)查询方式是 Hibernate 提供的“ 更加面向对象”的一种检索方式。QBC 在条件查询上比 HQL 查询更为灵活,而且支持运行时动态天生查询语句。
Hibernate中save、update和saveOrUpdate方法的不同之处?
save:
执行保存操作的,对一个新new出来的对象进行保存,数据库中没有这个对象,如果数据库中有,会报错说有重复的记录
update:
如果是对一个已经存在的托管对象进行更新,要使用update方法了,数据中有这个对象
saveOrUpdate:
这个方法是更新或者插入,有主键就执行更新,如果没有主键就执行插入。是根据实体类对象的状态做的不同操作
在数据库中条件查询速度很慢的时候,如何优化?
建索引
减少表之间的关联
优化sql,尽量让sql很快定位数据,不要让sql做全表查询,应该走索引,把数据量大的表排在前面
简化查询字段,没用的字段不要,已经对返回结果的控制,尽量返回少量数据
什么是 Hibernate 延迟加载?
延迟加载机制:
延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。在 Hibernate 中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在 Hibernate3 中还提供了对属性的延迟加载。
延迟加载的过程:
通过代理(Proxy)机制来实现延迟加载。Hibernate 从数据库获取某一个对象数据时、获取某一个对象的集合属性值时,或获取某一个对象所关联的另一个对象时,由于没有使用该对象的数据(除标识符外),Hibernate 并不从数据库加载真正的数据,而只是为该对象创建一个代理对象来代表这个对象,这个对象上的所有属性都为默认值;只有在真正需要使用该对象的数据时才创建这个真正的对象,真正从数据库中加载它的数据。
我们会定期不定时更新更多的面试题,大家可以多多关注!!!
大家多多关注收藏转发喔~(=^▽^=)!!!