2019年4月份

4月1日

        为什么要使用 hibernate?

               使用Hibernate很大程度上取决于2点优势。 

               (1)Hibernate对jdbc进行了封装,简化了我们操作Dao层的编码工作。

               (2)Hibernate提供了优秀的缓存机制,可以帮助我们的程序跑得更快。

        什么是ORM

                 ORM是对象关系映射。就是把数据库中的字段,映射到Java实体的属性里面。

                 常用的ORM框架有Mybatis与Hibernate。

         Hibernate与Mybatis的区别

                  我就个人经历过的项目而言,我对下面的几点很有体会。

                  (1)速度。如果一个项目没有复杂的SQL语句,那么使用Hibernate显得很容易。Hibernate因为封装了基本的增删改查的SQL语句,所以速度很快。而Mybatis对于开发者更加灵活,它是自己编写的SQL语句,所以可以适应一些复杂的SQL场景。因此,看项目。如果项目不复杂,使用Hibernate。如果项目较为复杂,使用Mybatis。

                  (2)难度。Hibernate有一套很成熟的HQL语句,而且Hibernate还有其它非常多的配置,学习难度比Mybatis大许多。

          hibernate 中如何在控制台查看打印的 SQL 语句?

                    在配置文件里面,把hibernate.show_SQL设置为true就行了,但是可能会降低一定的性能。

          hibernate 有几种查询方式?

                     原生SQL、HQL、条件查询。

          hibernate 实体类可以被定义为 final 吗?

                     可以加上final,以前我试过。不过被final修饰的类不能被继承,那么cglib动态代理就不能创建这个类的子类。所以相关的性能优化,延迟加载,将被舍弃掉。

           在 hibernate 中使用 Integer 和 int 做映射有什么区别?

                     Integer可以映射为null,但是int不能映射为null

           hibernate 是如何工作的?

                     读取配置文件

                     创建SesssionFactory

                     创建Session

                     创建事务

                     持久化

                     提交事务

                     关闭session

                     关闭sessionFactory


            get()和 load()的区别?

                     get不支持延迟加载,而load支持延迟加载。

           说一下 hibernate 的缓存机制?

                     一级缓存是session缓存。session缓存是事务级别的缓存,因为session对象的生命周期通常对应着数据库中的一个事务。举个例子,如果我们调用get方法查询并返回了一个对象,第二次查询这个对象的时候就会返回session缓存中已经存在的这个对象,而不用在去数据库中查询。一级缓存是由Hibernate直接管理的,因此我们不能手动关闭一级缓存。

                     二级缓存是SessionFactory缓存。SessionFactory缓存是进程级别的缓存,因为sessionFactory对象的生命周期与项目相同。二级缓存中的缓存对象可以被整个应用程序中的任何Session对象共享,即使关闭当前Session对象,新建的Session对象仍可使用。

           hibernate 对象有哪些状态?

                     瞬时状态:直接 new 出来的对象,该对象还没被持久化(没保存在数据库中)

                     持久化状态:当调用 Session 的 save/get/load 等方法的时候,对象就是持久化状态。

                     游离状态:Session 关闭之后对象就是游离状态。

           hibernate 实体类必须要有无参构造函数吗?为什么?

                     因为Hibernate需要调用反射的相关API,所以会调用对象的无参构造函数创建对象。所以要求实体要提供一个无参的构造函数。

4月2日

          MyBatis 中 #{}和 ${}的区别是什么?

                      井号是预编译的SQL语句,解析后的SQL语句的参数会带上引号

                      美元符号的相当于是拼接SQL语句,所以不会带上引号

                      一般来说,在动态排序中,使用美元符号才能达到要求。比如   select * from 表  order by ${id}

                      另外值得一提的是,美元符号的因为是SQL语句的拼接,可能会导致一些SQL注入的风险。所以要对用户的输入进行正则表达式的校验。 

            MyBatis的分页

                       第一种是自己手动编写分页,在MySQL中使用limit关键字。

                       第二种是使用PageHelper分页插件,调用startPage()方法来开启分页。分页插件的办法,我在毕业设计中使用过。

                       第三种是逻辑分页,它是一次性查询很多数据,然后在数据中再进行检索。这种办法效率低,占用内存大。

            MyBatis 是否支持延迟加载?

                        MyBatis 支持延迟加载,设置 lazyLoadingEnabled=true 即可。

            懒加载原理

                        一个对象里面持有另外一个对象。比如A对象持有B对象。我们查询出来了A对象,但是会发现B对象是一个null。只有调用B对象的时候,才会去数据库查询出B对象。这就是懒加载。

                         一言以蔽之:什么时候调用,什么时候查询。

             MyBatis 的一级缓存和二级缓存

                         Mybatis的一级缓存是基于同一个SqlSession的缓存。就是会把查询出来的数据保存下来,下次再查询的时候,先看看缓存里面有没有,如果有的话,就不查询数据库了。如果没有,才需要查询数据库。

                         Mybatis的二级缓存是基于同一个namespace下的所有SqlSession。同一个namespace下的SqlSession查询到的数据将会共享。同样的,获取数据的时候,先从缓存中获取,如果没有,才查询数据库。

4月2日  

 从RabbitMQ 结构图来看,有如下几个 过程:

1. 消息从生产者Producer发送到交换机Exchange

2.交换机根据路由规则将消息转发到相应队列

3. 队列将消息进行存储

4.消费者订阅队列消息,并进行消费

             RabbitMQ 的使用场景有哪些?

                         (1)异步处理。一般的注册流程中,可能会有把注册信息插入数据库、发送注册邮件、发送注册短信这三个步骤。而发送注册邮件和发送注册信息可以使用RabbitMQ进行异步处理。这样可以减少客户端等待的时间。客户端实际等待的时间只有数据写入数据库的时间。剩下的交给消息中间件异步处理即可。

                         (2)流量削峰。比如在抢购系统中,如果一瞬间有大量的用户请求,先把这些用户请求写入到消息中间件中,然后再进行处理。如果请求数量超过消息中间件的最大队列,那么就提示用户再等一会再来操作。这样可以防止我们的系统因为过大的负载而崩溃的情况。

              RabbitMQ 有哪些重要的角色?

                         生产者,用于创建消息并把消息发送给消息队列。

                         代理:用来保存消息,并把消息投递给指定的接收者。 

                         消费者:用来接收消息,并根据消息进行进一步业务处理。

              RabbitMQ 有哪些重要的组件?

è¿éåå¾çæè¿°

                         连接管理器ConnectionFactory,我们的应用程序与RabbitMQ建立连接的管理器。

                         Exchange(交换器):用于接受、分配消息。

                         Channel(信道):消息推送使用的通道。

                         Queue(队列):用于存储生产者的消息。      

--------------------------------------------------------------------------------------------------------------------------

                         RoutingKey(路由键):用于把生成者的数据分配到交换器上。

                         BindingKey(绑定键):用于把交换器的消息绑定到队列上。

              RabbitMQ 中 vhost 的作用是什么?

                         每一个RabbitMQ都能创建很多vhost。这个vhost可以理解为虚拟主机。就是一个 mini版本的RabbitMQ,拥有自己的交换器与队列。

              RabbitMQ 的消息是怎么发送的?

                           客户端必须连接到 RabbitMQ 服务器才能发布和消费消息。

                           首先客户端和 rabbit server 之间会创建一个 tcp 连接。

                           一旦 tcp 打开并通过了认证,你的客户端和 RabbitMQ 就创建了一条符合标准协议的信道(channel)

                           后来的发消息和接收消息都是由这信道完成的。

              RabbitMQ 怎么保证消息的稳定性(中间网络断开怎么办? )?

                           提供了事务的功能。缺点是 事务模式会极大的消耗RabbitMQ的性能。

                           通过将 channel 设置为 confirm(确认)模式。类似于TCP三次握手一样,消息发送方与消息接收方互相发送确认报文。只有接收方确认了已经接收到消息,那么才认为数据成功发送。否则认为发送失败,需要重新发送消息。

              RabbitMQ 怎么避免消息丢失?

                           把消息持久化磁盘,保证服务器重启消息或者意外宕机不丢失。

                           ACK确认机制,消费端消费完成要通知服务端,服务端才把消息从内存删除。

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

                           1) Exchange 设置持久化

                           2)Queue 设置持久化

                           3)Message持久化发送

              RabbitMQ 持久化有什么缺点?

                           因为使用的是磁盘而非内存存储,从而降低了吞吐量。

              RabbitMQ 有几种广播类型?             

                           topic:路由器根据正则,把消息投递到指定的队列中。

                           direct(默认方式):就是根据路由键的Key进行发送。如果Key一致,路由器就把数据投递到这个队列中。

                           fanout:直接把队列绑定到路由器。路由器在收到消息后,直接把消息投递到队列中,不需要路由键。

 

posted @ 2022-07-17 12:14  小大宇  阅读(38)  评论(0编辑  收藏  举报