Java常见面试题(121

阅读: 评论:0

Java常见面试题(121

Java常见面试题(121

121. mybatis 是否支持延迟加载?延迟加载的原理是什么?

Mybatis仅支持assaciation关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载LazyLoadingEnabled = true | false。

它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的SQL,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。

当然了,不光是Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的。

122. 说一下 mybatis 的一级缓存和二级缓存?

一级缓存:基于PerpetualCache 的HashMap 本地缓存,其存储作用域为Session,当Session flush 或close 之后,该Session中的所有Cache就将清空,默认打开一级缓存。

二级缓存与一级缓存其机制相同,默认也是采用PerpetualCache,HashMap存储,不同在于其存储作用域为Mapper(Namespace),并且可自定义存储源,如Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/>;

对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)进行了C/U/D操作后,默认该作用域下所有select中的缓存将被clear。

123. mybatis 和 hibernate 的区别有哪些?

  1. Mybatis和Hibernate不同,它不完全是一个ORM框架,因为Mybatis需要程序员自己编写SQL语句。
  2. Mybatis直接编写原生态SQL,可以颜色控制SQL执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一旦需求变化,要求迅速输出成果。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套SQL映射文件,工作量大。
  3. Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用Hibernate开发可以节省很多代码,提高效率。

124. mybatis 有哪些执行器(Executor)?

Mybatis有三种基本的执行器(Executor):

SimpleExecutor:

每执行一次update或select,就开启一个statement对象,用完立刻关闭statement对象。

ReuseExecutor:

执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map内,供下一次使用。简而言之,就是重复读Statement对象。

BatchExecutor:

执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch(),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDCB批处理相同。

125. mybatis 分页插件的实现原理是什么?

分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

126. mybatis 如何编写一个自定义插件?

转自:blog.csdn/qq_30051265/article/details/80266434

Mybatis自定义插件针对Mybatis四大对象(Executor,StatementHandler,ParamenterHandler,ResultSetHandler)进行拦截,具体拦截方式为:

  • Executor:拦截执行器的方法(log记录)
  • StatementHandler:拦截Sql语法构建的处理
  • ParameterHandler:拦截参数的数理
  • ResultSetHandler:拦截结果集的处理

Mybatis自定义插件必须实现Interceptor接口:

public interface Interceptor {Object intercept(Invocation invocation) throws Throwable;Object plugin(Object target);void setProperties(Properties properties);
}
  • Intercept方法:拦截器具体处理逻辑方法
  • plugin方法:根据签名signatureMap生成动态代理对象
  • setProperties方法:设置Properties属性

自定义插件demo:

// ExamplePlugin.java
@Intercepts({@Signature(type= Executor.class,method = "update",args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {public Object intercept(Invocation invocation) throws Throwable {Object target = Target(); //被代理对象Method method = Method(); //代理方法Object[] args = Args(); //方法参数// do something ...... 方法拦截前执行代码块Object result = invocation.proceed();// do something .......方法拦截后执行代码块return result;}public Object plugin(Object target) {return Plugin.wrap(target, this);}public void setProperties(Properties properties) {}
}

一个@Intercepts可以配置多个@Signatur,@Signature中的参数定义如下:

  • type:表示拦截的类,这里是Executor的实现类;
  • method:表示拦截的方法,这里是拦截Executor的update方法;
  • args:表示方法参数。

RabbitMQ

127. rabbitmq 的使用场景有哪些?

  1. 跨系统的异步通信,所有需要异步交互的地方都可以使用消息队列。就像我们除了打电话(同步)以外,还需要发短信,发电子邮件(异步)的通讯方式。
  2. 多个应用之间的耦合,由于消息是平台无关和语言无关的,而且语义上也不再是函数调用,因此更适合作为多个应用之间的松耦合的接口。基于消息队列的耦合,不需要发送方和接收方同时在线。在企业应用集成(EAI)中,文件传输,共享数据库,消息队列,远程过程调用都可以作为集成的方法。
  3. 应用内的同步变异步,比如订单处理,就可以由前端应用将订单信息放到队列,后端应用从队列里依次获得消息处理,高峰时的大量订单可以积压在队列里慢慢处理掉。由于同步通常意味着阻塞,而大量线程的阻塞会降低计算机的性能。
  4. 消息驱动的架构(EDA),系统分解为消息队列,消息制造者和消息消费者,一个处理流程可以根据需要拆成多个阶段(Stage),阶段之间用队列连接起来,前一个阶段处理的结果放入队列,后一个阶段从队列中获取消息继续处理。
  5. 应用需要更灵活的耦合方式,如发布订阅,比如可以指定路由规则。
  6. 跨局域网,甚至跨城市的通讯(CDN行业),比如北京机房与广州机房的应用程序的通信。

128. rabbitmq 有哪些重要的角色?

RabbitMQ中重要的角色有:生产者,消费者和代理:

  • 生产者:消息的创建者,负责创建和推送数据到消息服务器;
  • 消费者:消息的接收方,用于处理数据和确认消息;
  • 代理:就是RabbitMQ本身,用于扮演“快递”的橘色,本身不生产消息,只是扮演“快递”的角色

129. rabbitmq 有哪些重要的组件?

  • ConnectionFactory(连接管理器):应用程序与Rabbit之间建立连接的管理器,程序代码中使用。
  • Channel(信道):消息推送使用的通道。
  • Exchange(交换器):用于接受、分配消息。
  • Queue(队列):用于存储生产者的消息。
  • RoutiongKey(路由键):用于把生成者的数据分配到交换器上。
  • BindingKey(绑定键):用于把交换器的消息绑定到队列上。

130. rabbitmq 中 vhost 的作用是什么?

vhost可以理解为虚拟broker,即mini-RabbitMQ server。其内部均含有独立的queue、exchange和binding等,但最最重要的是,其拥有独立的权限系统,可以做到vhost范围的用户控制。当然,从RabbitMQ的全局角度,vhost可以作为不同权限隔离的手段(一个典型的例子就是不同的应用可以跑在不同的vhost中)。

131. rabbitmq 的消息是怎么发送的?

首先客户端必须连接到RabbitMQ 服务器才能发布和消费消息,客户端和rabbit server 之间会创建一个 tcp 连接, 一旦tcp打开并通过了认证(认证就是你发送给rabbit服务器的用户名和密码),你的客户端和RabbitMQ就创建了一条amqp信道(channel),信道是创建在“真实”tcp上的虚拟连接,amqp命令都是通过信道发送出去的,每个信道都会有一个唯一的id,不论是发布消息,订阅队列都是通过这个信道完成的。

132. rabbitmq 怎么保证消息的稳定性?

  • 提供了事务的功能。
  • 通过将channel设置为confirm(确认)模式。

133. rabbitmq 怎么避免消息丢失?

  1. 消息持久化
  2. ACK确认机制
  3. 设置集群镜像模式
  4. 消息补偿机制

134. 要保证消息持久化成功的条件有哪些?

  1. 声明队列必须设置持久化 durable 设置为true。
  2. 消息推送透底模式必须设置持久化,deliveryMode设置为2(持久)。
  3. 消息已经到达持久化交换器。
  4. 消息已经到达持久化队列。

以上四个条件都满足才能保证消息持久化成功。

135. rabbitmq 持久化有什么缺点?

持久化的缺点就是降低了服务器的吞吐量,因为使用的是磁盘而非内存存储,从而降低了吞吐量。可尽量使用ssd硬盘来缓解吞吐量的问题。

136. rabbitmq 有几种广播类型?

三种广播模式:

  • fanout:所有bind到此exchange的queue都可以接受消息(纯广播,绑定到RabbitMQ的接受者都能收到消息);
  • direct:通过routingKey和exchange决定的那个唯一的queue可以接收消息;
  • topic:所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息。

137. rabbitmq 怎么实现延迟消息队列?

  • 通过消息过期后进入死信交换器,再由交换器转发到延迟消费队列,实现延迟功能;
  • 使用 RabbitMQ-delayed-message-exchange 插件实现延迟功能。

138. rabbitmq 集群有什么用?

集群主要有以下两个用途:

  • 高可用:某个服务器出现问题,整个RabbitMQ还可以继续使用;
  • 高容量:集群可以承载更多的消息量。

139. rabbitmq 节点的类型有哪些?

  • 磁盘节点:消息会存储到磁盘。
  • 内存节点:消息都存储在内存中,重启服务器消息丢失,性能高于磁盘类型。

140. rabbitmq 集群搭建需要注意哪些问题?

  • 各节点之间使用“--link”连接,此属性不能忽略。
  • 各节点使用的 erlang cookie 值必须相同,此值相当于“秘钥”的功能,用于各节点的认证。
  • 整个集群中必须包含一个磁盘节点。

下一篇点击这里

本文发布于:2024-02-03 06:31:07,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170691306649260.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:面试题   常见   Java
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23