4-6学习

  1. 学习kafka消息队列,zookeeper
  2. 复习数据库MySQL
  3. 复习Redis,特别关注集群部分,主从复制部分
  4. 准备明天美团面试

一:消息队列的作用/优点

  1. 解耦

接触消费者与生产者之间复杂的调用关系
2. 异步

a系统查询完成之后调用b系统,只有等b系统返回才能继续这是同步。a系统查询完成之后直接把消息放入消息队列,然后就不用管了,这是同步。
3. 削峰

A 系统调用 B 系统处理数据,每天 0 点到 12 点,A 系统风平浪静,每秒并发请求数量就 100 个。结果每次一到 12 点 ~ 13 点,每秒并发请求数量突然会暴增到 1 万条。但是 B 系统最大的处理能力就只能是每秒钟处理 1000 个请求,这样系统很容易就会崩掉。这种情况可以引入消息队列,把请求数据先存入消息队列中,消费系统再根据自己的消费能力拉取消费。

二:kafka如何保证高可用?

三:如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?

要保证消息不被重复消费,其实就是要保证消息消费时的幂等性。幂等性:无论你重复请求多少次,得到的结果都是一样的。例如:一条数据重复出现两次,数据库里就只有一条数据,这就保证了系统的幂等性。幂等性问题只有在修改的操作时才会产生。

写MySQL

  1. 写之前先查询这条消息是否依旧存在,如果存在,那么update
  2. 将MySQL列设置唯一索引

写Redis

Redis本身就是set的操作,因此可以确保幂等性。

四:如何处理消息丢失问题?

五:如何保证消息传输的顺序?

什么是分布式?

分布式是指通过网络连接的多个组件,通过交换信息协作而形成的系统。

而集群,是指同一种组件的多个实例,形成的逻辑上的整体。

CAP理论

分布式系统不可能同时满足一致性,可用性,分区容忍性。

  1. 一致性
    多个数据副本保证数据一致
  2. 可用性 每一次请求都能在有限的时间内正确的返回
  3. 分区容忍性
    网络分区是指由于网络故障,分布式的系统划分为多个区域,每个系统内部可以进行通讯但是区域之间无法进行通讯

如何权衡
分区容忍性实际上是不可缺少的。因此我们只能在一致性和可用性之间抉择。如果是涉及钱等敏感资源的我们当然需要保证其一致性。

BASE理论

https://juejin.im/post/5b2663fcf265da59a401e6f8

  1. 基本可用
  2. 软状态
  3. 最终一致性

分布式事务

  1. 什么是分布式事务?

事务是一系列小操作的集合。分布式事务的本质是为了确保分 布在不同计算机的数据库保持数据的一致性。

  1. 实现方法
两阶段提交

阶段1:协调者询问所有参与者事务是否执行成功

阶段2:如果所有事务均执行成功那么向所有参与者发送commit事务命令

缺点:

  1. 整个过程同步阻塞,需要等所有的节点全部完成才能释放资源
  2. 单点问题。过于依赖协调者,如果协调者出现问题,那么影响很严重
  3. 没有数据强一致性,如果commit阶段出现网络故障,那么将导致某些节点commit,而某些节点未commit,会使得数据不一致。
  4. 过于保守。任一节点失败则判断为整个系统失败,没有完整的容错机制。
三阶段提交

针对两阶段提交,3阶段提交进行了一下的改进:

  1. 将准备阶段拆分为canCommit与preCommit阶段。加入canCommit阶段的目的是为了在不锁资源的情况下,先确定是否所有节点都具有执行事务的能力
  2. 引入了超时机制,体现在a. precommit后协调者如果超时未收到参与者的ack,那么他会发送要求所有参与者回滚的命令。precommit之后如果参与者未收到协调着的commit命令,那么他会默认直接commit(这里当然也存在数据不一致的问题,但是没办法,情况很极端,无法严格实现)

阶段1: canCommit

阶段2: preCommit

阶段3: doCommit

本地消息表+消息队列

在本地数据库中存在一个消息表,由于是在同一个数据库,因此利用本地的事务就可以确保消息被放到消息表,后将消息传到消息队列,消息队列再到另一个系统的消息表。整个过程利用本地数据库的事务+消息队列。

分布式锁

锁的作用在于实现资源的互斥访问。在单机,锁可以通过语言的内置功能实现,而在分布式领域我们的实现方式有:

  1. Redis setNX
  2. Redis RedLock
  3. 数据库唯一索引
  4. zookeeper有序节点

分布式一致性算法

  1. paxos算法
  2. raft算法

zookeeper

  1. 什么是zookeeper
  2. zookeeper提供哪些功能
  3. 说说zab协议

参考:
https://juejin.im/post/5b26648e5188257494641b9f

2pc 3pc 好文 https://www.zhihu.com/search?type=content&q=%E4%B8%89%E9%98%B6%E6%AE%B5%E6%8F%90%E4%BA%A4

wiki paxos算法 https://zh.wikipedia.org/wiki/Paxos%E7%AE%97%E6%B3%95

从我个人目前的情况出发,Mybatis等等框架已经不适合再去看源码了,就看看以前的总结,然后一些面经吧

Mybatis是什么?

Mybatis是一个半ORM框架,他的内部封装了JDBC,在开发的时候我们只需要写sql语句(并且支持动态sql),就可以得到一个数据对象,而不需要像是使用jdbc一样,处理 加载驱动,建立连接, 获取statement等于业务逻辑无关的操作了。半ORM框架在于他是sql获取对象,而不是对象查询得到对象(如 Hibernate )

Hibernate与Mybatis的区别?

Mybatis中 #{} 与 ${} 的区别是什么?

  • {} 在处理时,是基于静态文本替换的。就是把 {}里的值替换成了变量的值
  • #{} 在处理时,会将#{} 替换为? ,再通过preparestatement的set方法进行赋值。使用#{}可以有效的防止sql注入式攻击。

分页

分页可大致分为2种实现,

  1. 物理分页:利于MySQL的limit语句实现
  2. 逻辑分页:先将数据全部查询的内存中,然后再过滤

在MyBatis中有4中具体的实现:

  1. 基于数组
  2. 基于RowBounds
  3. 基于sql语句
  4. 基于拦截器(插件)

查看详情:
https://blog.csdn.net/chenbaige/article/details/70846902?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

一级缓存二级缓存

  • 一级缓存:
    基于sqlsession级别的。在进行数据查询时,先优先查询此sqlsession拥有的一个cache,这是一个基于
    HashMap的数据结构。生命周期为在同一个sqlsession会话内生效
  • 二级缓存:
    基于Mapper级别的。和一级缓存的流程一样,也是默认基于一个cache的数据结构,不过区别在于,他也可以使用外部的缓存应用进行缓存。如Redis。

一级缓存是默认开启的。二级缓存可通过配置进行开启。对于任何的增删改的操作,都会导致缓存被清空。

三种执行器

  1. SimpleExecutor
    每次执行一次update或者select就开启一个statement对象,用完之后立即关闭。
  2. ReuseExecutor
    重复使用statement对象。
  3. BatchExecutor
    执行update(jdbc批处理不支持select)时,一次处理一批。

动态SQL

Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能,Mybatis 提供了 9 种动态 sql 标签

trim|where|set|foreach|if|choose|when|otherwise|bind

Mybatis逆向工程

通过数据库的表结构,自动的生成单表相关的所有mapper.xml,mapper.java,以及POJO(java bean)文件,这样我们就只需要关注自身的业务逻辑了。

Mybatis延迟加载

延迟加载,也就是懒加载,更加直白的说,就是 按需加载

Mybatis支持association关联对象与collection关联集合的延迟加载。association是指如

class student {
    int id;
    String name;
    Teacher teacher;
}
class teacher {
    int id;
}

其中一个student对应一个teacher,这就被称为assocation,这个时候我们可以先差student的数据,等到用到teacher时再延迟加载teacher。
参考:
https://blog.csdn.net/eson_15/article/details/51668523
https://blog.csdn.net/hbtj_1216/article/details/52876201

实现原理

是基于CGLIB动态代理模式实现的。当调用获取到的student.getTeacher.getId()方法时,在getTeacher这一步检测teacher是否为空,如果为空,则查询数据库。这就实现了 延迟加载了。

发布了40 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41332728/article/details/105354152
4-6