Java技术栈知识点总结

知识点总结

    • 一、Spring bean的生命周期
    • 二、Spring bean的加载过程
    • 三、XmlBeanFactory与ApplicationContext的区别
    • 四、Spring其他相关知识点
      • 4.1 配置到应用开发中三种方式
      • 4.2 Spring AOP相关
      • 4.3 Spring 的事务传播机制
      • 4.4 Spring 中BeanFactory和FactoryBean
    • 五、Spring 循环依赖处理
    • 六、操作JDBC
    • 七、SpringMVC工作原理
    • 七、Servlet生命周期
    • 八、SpringBoot自动配置原理
    • 九、Mybatis工作原理
    • 十、Mybatis一级缓存、二级缓存
    • 十一、Mybatis #{}和${}的区别是什么?
    • 十二、Mybatis接口绑定有几种实现方式,分别是怎么实现的?
    • 十二、CPU100%排查命令
    • 十三、Redis
    • 十四、Zookeeper
      • Zookeeper服务状态
      • ZAB(Zookeeper Atomic Broadcast 原子消息广播协议)
      • ZAB协议模式
      • Zookeeper如何保证集群中数据的一致性
      • ZAB协议4阶段
    • 十五、Dubbo
      • 15.1、dubbo 线程分配模型
      • 15.2、
    • 十六 、MySQL分库分表
    • 十七、消息中间件
    • 十八、数据库的三大范式

一、Spring bean的生命周期

  1. 执行实现了BeanFactoryPostProcessor的postProcessBeanFactory中的方法,可以修改Bean中元数据中的信息。
  2. 执行实现了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,那么在实例化Bean对象之前会调用postProcessBeforeInstantiation方法,如果返回的bean不为null则直接调用BeanPostProcessor的postProcessAfterInitialization方法,然后直接返回该bean。
  3. bean的实例化
  4. 执行实现了InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法。
  5. 属性注入populateBean方法
  6. 实现了Aware相关的接口的set方法,如ApplicationContextAware、BeanNameAware、BeanFactoryAware。
  7. 实现了BeanPostProcessor接口,执行postProcessBeforeInitialization方法。
  8. 执行指定了init-method属性的方法
  9. 实现了BeanPostProcessor接口,执行postProcessAfterInitialization方法。
  10. 执行指定了destroy-method属性的方法。

二、Spring bean的加载过程

  1. 转换对应beanName(去除FactoryBean的修饰符 &)
  2. 尝试从缓存中加载单例
  3. bean的实例化(缓存中记录的是最原始的bean,如果在缓存中获取到了bean,则需要getObjectForBeanInstance进行处理获得工程bean中定义的factory-method方法中返回的bean),在获取FactoryBean中对应的getObejct方法之后,会执行后处理器BeanPostProcessor的操作
  4. 原型模式的依赖检查(只有单例处理循环依赖)
  5. 检测如果当前加载的XML配置文件中不包含beanName所对应的配置,就到parentBeanFactory中进行检测,然后再去递归调用getBean方法。
  6. 将加载得到的GenericBeanDefinition转换为RootBeanDefinition(所有的bean处理都是针对该类所有要转化)。
  7. 寻找依赖
  8. 针对不同的scope进行bean的创建。
  9. 类型转化

三、XmlBeanFactory与ApplicationContext的区别

  1. ApplicationContext是BeanFactory的扩展
  2. 加载配置文件方法不同,BeanFactory使用XmlBeanFactory(new ClasssPathResource(“xx.xml”)),ApplicationContext使用ClassPathXmlApplicationContext(“hello.xml”)
  3. 提供了支持国际化的文本消息
  4. 增加了@Qualifier与@Autowired注解的支持
  5. 注册拦截bean创建的bean处理器。

四、Spring其他相关知识点

4.1 配置到应用开发中三种方式

  1. 基于 XML 的配置
  2. 基于注解的配置
  3. 基于 Java 的配置(@Configuration @Bean)

4.2 Spring AOP相关

  1. 切面(Aspect):通知和切点的结合,通知和切点共同定义了切面的全部内容。
  2. 切入点(Pointcut):切入点定义了切面在何处要织入的一个或者多个连接点(Spring默认使用AspectJ作为切入点语法)。
  3. 通知(Advice): 在切面的某个特定的连接点上执行的动作,即何时使用,包括前置通知、环绕通知、后置通知、返回通知、异常通知。
  4. 织入:是把切面应用到目标对象,并创建新的代理对象的过程。(就是将切面跟对象关联并创建该对象的代理对象的过程)
  5. 连接点:是在应用执行过程中能够插入切面的一个点,即AOP拦截到的方法就是一个连接点。
  6. 引用: 引入允许我们向现有类添加新方法或属性。

4.3 Spring 的事务传播机制

  1. PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
  2. PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
  3. PROPAGATION_MANDATORY:使用当前的事务,如果当前没有事务,就抛异常。
  4. PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
  5. PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  6. PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
  7. PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执⾏。如果当前没有事务,则执⾏与PROPAGATION_REQUIRED类似的操作。
    Java技术栈知识点总结_第1张图片

4.4 Spring 中BeanFactory和FactoryBean

插曲:BeanFactory:是spring中比较原始的Factory,是一个接口,是IOC容器或对象工厂,管理着Spring中的所有Bean。
FactoryBean: 是在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,getObjeact()方法返回的是实际需要的Bean。
注: 当调用getBean(“beanName”)时,Spring通过反射机制发现当前Bean实现了FactoryBean的接口,这时Spring容器就调用接口方法getObject()方法返回的对象。如果希望获取当前Bean的实例,则需要显示的加上"&“前缀,即getBean(”&beanName")

五、Spring 循环依赖处理

spring循环依赖包括如下两种:

构造器循环依赖: 此依赖无法解决,只能抛出异常表示循环依赖。因为使用构造器产生的循环依赖会造成一个环,比如创建A,A构造器需要B,那么创建B,B构造器又需要C,那么创建C,C构造器又需要A,从而导致死循环构造对象。

setter循环依赖:Spring通过提前暴露一个单例工厂方法(只能解决作用域为单例的循环依赖,因为Spring只对单例做了缓存)。

Spring解决循环依赖步骤:
在创建A时,通过addSingletonFactory()方法将ObjectFactory信息存放在了singletonFactories缓存中,当执行到populateBean时,检测到要填充属性B时则转向去创建B,当执行到B的populateBean时检测要填充属性对象A,而A已经在singletonFactories缓存中,因此B通过getBean(beanName)获取到A未填充属性的缓存数据,因为B持有的A对象的地址与A对象地址一致,所以在A继续执行populateBean后B中持有的也是一致的。这就解决了循环依赖的问题。

六、操作JDBC

1.	Class.forName("数据库驱动");
2.	通过DriverManager创建数据库连接对象Connection。
3.	创建Statement对象,通过Connection.createStatement()获得
4.	通过Statement对象执行相应的SQL语句,如executeQuery()
5.	通过Statement对象的executeQuery()获得ResultSet对象,该对象标识执行查询数据库后返回的数据的集合。

七、SpringMVC工作原理

  1. 客户端发送请求到DispatcherServlet,DispatcherServlet的doService()接收请求。
  2. 通过循环HandlerMapping寻找处理请求的Controller,将Handler对象以及对象的拦截器包装成HandlerExecutionChain对象统一返回给Dispatcherservlet
  3. 根据HandlerExecutionChain寻找合适的HandlerAdapter,处理业务逻辑,返回ModelAndView
  4. DispatcherServlet将ModelAndView传给ViewReslover视图解析器。ViewReslover解析后返回具体的View
  5. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
  6. DispatcherServlet响应用户。

客户端请求 -> DispatcherServlet进行接收 -> 循环HandlerMapping -> 封装成HandlerExecutionChain -> 找到合适的 HandlerAdapt -> 处理业务逻辑返回ModelAndView -> 传递给 ViewReslover -> 解析获得 View ->渲染视图 ->响应用户
自定义原理:DispatcherServlet继承HttpServlet,在web容器初始化时扫描Controller包,将加上了Controller注解的类保存进map中,循环map对象,通过类的反射机制找到类和方法上注解的RequestMapping的url地址,将url地址和类关联信息保存进urlMap中。将url地址和方法名称保存进methodMap中。然后当客户端请求doGet或者doPost的时候通过urlMap找到类对象,通过methodMap找到方法名就可以通过类的反射invoke方法进行调用。最后调用视图转换器渲染给页面展示。

七、Servlet生命周期

  1. 初始化:加载Servlet类,将class文件中的数据读到内存中,创建包含了servlet初始化配置信息的ServletConfig对象。调用servlet对象的init方法进行初始化。
  2. 运行:针对请求创建servletRequest和serletResponse对象,调用service方法,通过sercice方法判断是调用doget、doPost请求、还是其他HTTP请求。
  3. 销毁:用于释放资源、如关闭数据库连接,关闭文件输入输出流。

八、SpringBoot自动配置原理

  1. Springboot应用启动时加载@SpringBootApplication注解配置类,@SpringBootApplication
    注解 中包含@EnableAutoConfiguration, 该注解的作用是找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类。
  2. AutoConfiguration配置类通过以Properties结尾命名的类中取得在全局配置文件中配置的属性如server.port,而以Properties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。

九、Mybatis工作原理

十、Mybatis一级缓存、二级缓存

MyBatis 的缓存分为一级缓存和二级缓存:

  1. 一级缓存放在 session 里面,默认开启。
  2. 二级缓存放在它的命名空间里,默认是不打开的,使用二级缓存属性类需要实现 Serializable 序列化
    接口(可用来保存对象的状态),可在它的映射文件中配置

十一、Mybatis #{}和${}的区别是什么?

  1. #{}是预编译处理,${}是字符串替换。
  2. Mybatis 在处理 时,就是把 {}时,就是把 时,就是把{}替换成变量的值,处理#{}时,会将 sql 中的#{}替换为?,调用 PreparedStatement 的 set 方法来赋值。
  3. 使用#{}可以有效的防止 SQL 注入,提高系统安全性。

十二、Mybatis接口绑定有几种实现方式,分别是怎么实现的?

  1. 接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上
    @Select@Update 等注解里面包含 Sql 语句来绑定,另外一种就是通过 xml 里面写 SQL 来绑
    定,在这种情况下,要指定 xml 映射文件里面的 namespace 必须为接口的全路径名。
  2. 当 Sql 语句比较简单时候,用注解绑定;当 SQL 语句比较复杂时候,用 xml 绑定,一般用
    xml 绑定的比较多。

十二、CPU100%排查命令

  1. top -c 命令找出当前进程的运⾏列表,按下P按照CPU使用率进行排序
  2. top -Hp PID 进入这个进行下面的线程
  3. 导出进程快照 jstack -l PID > ./PID.stack
  4. 查看线程文件 cat PID.stack |grep ‘PID十进制值’ -C 8

十三、Redis

  1. Redis 数据结构:String、Hash、List、Set、SortedSet、HyperLogLog(是用来做基数统计的算法)、pub/sub、Geo(主要用于存储地理位置信息,并对存储的信息进行操作)

--------------------基本用法-----------------------
String: 字符串数据类型用于存储字符串值。应用场景: 缓存功能,计数器,共享用户Session。
Hash: string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储单一对象(也就是当前对象没有嵌套其他对象)
应用场景:可以用于实现购物车功能,每一个key对应一个商品id,value值对应的商品具体信息。
List: 按照插入顺序排序,简单的字符串列表。应用场景:
a. 存储收藏列表、评论列表
b.还可以根据lrange命令实现简单的分页。
c. 可实现简单的消息队列。rpush 将数据添加到List的右侧,lpop来获取。也可以使用lpush + rpop的方式实现先进入的先消费的结构。
Set :是String类型的无序且不重复数据的集合。应用场景:比如监控某个状态的交集,并集,差集操作。
sorted set :是排序的Set,去重可排序,通过写进去的时候给一个分数,自动根据分数排。应用场景:可以做排行榜,比如点击量,点赞数等排行。也可以做带有权重的消息队列,通过权重进行先消费执行。
--------------------高级用法-----------------------
HyperLogLog:是用来做基数统计
geo: 要用于存储地理位置信息。
pub/sub: 功能是订阅发布功能,可以⽤作简单的消息队列。缺点是如果消费者下线,生产的消息会消失。
Lua: 脚本使用 Lua 解释器来执行脚。
事务:不是严格的事务,只保证串行执行命令,并且能保证全部执行,但是执行命令失败时并不会回滚,而是会继续执行下去。
pipeline: 可以批量执⾏⼀组指令,⼀次性返回全部结果,可以减少频繁的请求应答

  1. 如果有大量的key需要设置同一时间过期,一般需要注意什么?
    需要在时间上加一个随机值,使得过期时间分散一些,避免时间过于集中,到过期时间那个时间点,Redis可能出现卡顿现象,严重会造成雪崩的发生。
  2. Redis分布式锁
    通过setnx来争抢锁,抢到锁了之后会给锁加一个过期时间防止锁忘记释放。
    实现原理:发送lua脚本到redis上,redis使用hash数据结构进行存储锁信息,lua脚本会判断这个锁是否存在,如果不存在,则进行加锁,key值是锁的key值,然后给这个key值设置过期时间。
    如果当前客户端已经持有这把锁,又执行了加锁操作,则会执行hincrby操作,给锁值加1,释放锁的时候将这个值减一,当这个值次数为0时,就会删除该key,从而达到释放锁的目的。
  3. JAVA可重入锁原理
    每一个锁关联一个线程持有者和计数器,当计数器为 0 时表示该锁没有被任何线程持有,那么任何线程都可能获得该锁而调用相应的方法;当某一线程请求成功后,JVM会记下锁的持有线程,并且将计数器置为 1;此时其它线程请求该锁,则必须等待;而该持有锁的线程如果再次请求这个锁,就可以再次拿到这个锁,同时计数器会递增;当线程退出同步代码块时,计数器会递减,如果计数器为 0,则释放该锁。
  4. 如果在setnx之后执行expire之前进程宕机或者重启了,那么这个锁就永远得不到释放了。使用set指令将setnx和过期时间设置在一起。
    在这里插入图片描述
  5. keys 前缀* 用来查找全部以前缀开头的键(如:获取以lin开头的键),不过Redis是单线程的,所以使用keys指令会导致线程阻塞,服务会停顿,直到指令执行完成才能恢复,可以使用scan指令(有重复)。
    Java技术栈知识点总结_第2张图片
  6. 缓存雪崩和缓存穿透
    缓存雪崩:批量增加的缓存在同一时间失效,导致大量请求访问DB,导致数据库崩溃。
    ——解决方案: 批量增加时给失效时间加上一个随机数,避免同一时间失效,或者热点数据不设置过期时间,等更新操作更新缓存即可。
    缓存穿透:指缓存和数据库中都没有的数据,比如:数据库的id是自增的,而用户不断发起id为-1的数据或id特别大,大量请求导致数据库压力过大而崩溃。
    ——解决方案:在接口层增加校验、参数校验、用户鉴权校验,不合法的直接return。 通过增加BloomFilte用来判断请求值是否存在于DB中。
    缓存击穿:指一个热点key,不停的扛着大并发,当这个key在失效的瞬间,持续的大并发直接请求数据库,导致数据库崩溃。
    ——解决方案:设置热点数据永不过期。
  7. Redis 持久化

| | RDB |AOF
|–|–|–|–|
|概述| 对redis中的数据执行周期性的持久化 |对每条写入命令作为日志,以append-only的模式写入一个日志文件中 |
|优点 | 1. RDB会生成多个数据文件,每个数据文件都代表了某一个时刻中redis的数据,适合做冷备。
2. 对Redis性能影响小,同步时fork一个子进程进行持久化,回复速度比AOF快| 1. AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据
2. AOF日志文件以append-only模式写入,所以没有任何磁盘寻址的开销,写入性能非常高,而且文件不容易破损,即使文件尾部破损,也很容易修复。
3.AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如不小心使用了flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据。|
|缺点| 默认5分钟生成一次,在这次同步到下次同步这5分钟如果redis进程宕机,则会丢失最近5分钟的数据 |1. 同一份数据,AOF⽂件⽐RDB⼤。
2. rewrite的QPS比RDB低, |
实际中要综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择; 用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复。

  1. Redis高可用(哨兵、Redis Cluster、主从复制,读写分离)
    哨兵功能:集群监控、消息通知、故障转移、配置中心(如果发生故障转移,通知client客户端新的 master地址)。
    哨兵至少需要3个实例才能保证自己的健壮性,因为如果只有两个哨兵的话,当放在同一台机器上的redis和哨兵都挂了,只剩一台机器则无法进行故障转移。(搭建一主二从三哨兵)。
    主从复制:slave会发送psync命令给master,如果slave第一次连接master会进行全量复制,master收到命令后,就会启动一个线程,生成RDB文件,然后发送给slave。
    读写分离:master节点负责全部的写操作,slave负责全部的读操作,redis.conf文件中replica-read-only,默认为yes,yes则会拒绝所有的写操作。
    Redis Cluster: 搭建Redis Cluster 默认用前3个实例作为Master,后3个作为Slave节点,Slave节点只读,Master负责写操作。

  2. Redis与Memcached区别

Redis比Memcached拥有更多的数据结构
Redis原生支持集群模式,而Memcached没有原生的集群模式。
Redis使用单核,Memcached可以使用多核。在存储小数据上Redis比Memcached性能高,相反则Memcached性能高于Redis(100K以上的数据)

十四、Zookeeper

Zookeeper服务状态

  1. LOOKING:当节点认为群集中没有Leader,服务器会进入LOOKING状态,目的是为了查找或者选举Leader。
  2. FOLLOWING:跟随者状态。当前服务器角色是 Follower。
  3. LEADING:领导者状态。当前服务器角色是 Leader。
  4. OBSERVING:观察者状态。当前服务器角色是 Observer。

ZAB(Zookeeper Atomic Broadcast 原子消息广播协议)

zxid : 协议的事务编号,分为计数器部分(针对客户端每一个事务请求,计数器加1)和epoch(当前集群所处的年代或周期)。
epoch 作用: 当旧的leader奔溃恢复,选举出新的leader之后,年代加1,那么follower只听从当前年代的leader的命令,旧leader的命令废弃。

ZAB协议模式

  1. 恢复模式(选主):当服务启动时或服务宕机、断电、网络延迟导致leader不再对外提供服务,其他节点通过心跳检测进入恢复模式。
  2. 广播模式(同步):集群经过leader选举之后进行连接leader和同步步骤,保证leader和server具有相同的系统状态。

Zookeeper如何保证集群中数据的一致性

zookeeper通过⼆阶段提交来保证集群中数据的⼀致性,因为只需要收到过半的ACK
就可以提交事务,所以zookeeper的数据并不是强⼀致性。
收到客户端有如下几个步骤:

  1. Leader收到客户端的写请求,⽣成⼀个事务(Proposal),其中包含了zxid;
  2. Leader开始⼴播该事务,需要注意的是所有节点的通讯都是由⼀个FIFO的队列维护的;
  3. Follower接受到事务之后,将事务写⼊本地磁盘,写⼊成功之后返回Leader⼀个ACK;
  4. Leader收到过半的ACK之后,开始提交本事务,并⼴播事务提交信息
  5. 从节点开始提交本事务。

ZAB协议4阶段

  1. Election(选举阶段)
  2. Discovery(发现阶段)
  3. synchronization(同步阶段)
  4. Broadcast(广播阶段)
    Java技术栈知识点总结_第3张图片

十五、Dubbo

Java技术栈知识点总结_第4张图片

节点 角色说明
Consumer 需要调⽤远程服务的服务消费⽅
Registry 注册中⼼
Provider 服务提供⽅
Container 服务运⾏的容器
Monitor 监控中⼼

大致流程为 :

  1. Provider启动,启动完成之后向Register注册自己所能提供的服务。
  2. Consumer启动,启动完成之后向Register订阅自己所需的服务,然后注册中心将提供者元信息通知给Consumer,之后Consumer通过负债均衡选择一个Provider直接调用,在此之后如果提供方元数据变更的话注册中心会把变更推送给Consumer。
  3. Provider和Cosumer会在内存中记录着调用的次数和时间,然后定时的发送统计数据到监控中心。

15.1、dubbo 线程分配模型

Java技术栈知识点总结_第5张图片

ThreadPool:
fixed: 固定大小线程池,启动时建立线程,不关闭,一直持有(客户端AbstractClient默认实现的是cached,服务端AbstractServer 默认实现是fixed )。
cached: 缓存线程池,空闲一分钟自动删除,需要时重建。
limited: 可伸缩线程池,但池中的线程数只会增长不会收缩。只增长不收缩的目的是为了避免收缩时突然来了大流量引起的性能问题。
eager:优先创建worker线程池。在任务数量大于corePoolSize但是小于maximumPoolSize时,优先创建Worker来处理任务。当任务数量大于maximumPoolSize时,将任务放入阻塞队列中。阻塞队列充满时抛出RejectedExecutionExceprion。(相比于cached:cached在任务数量超过maximumPoolSize时直接抛出异常而不是将任务放入阻塞队列。)

Dispatcher

  1. all 所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。
  2. direct 所有消息都不派发到线程池,全部在 IO 线程上直接执行。
  3. message 只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在 IO 线程上执行。
  4. execution 只请求消息派发到线程池,不含响应,响应和其它连接断开事件,心跳等消息,直接在 IO 线程上执行。
  5. connection 在 IO 线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。

15.2、

十六 、MySQL分库分表

  1. 垂直分表: 将一张表按照字段拆分成多表(将不经常使用的字段拆分出来)
    作用:为避免IO争抢并减少锁表的几率
  2. 垂直分库: 按照业务模块进行分类,分布到不同的数据库上。
    作用:解决业务层面的耦合,业务清晰。高并发场景下,垂直分库一定程度的提升IO、数据库连接数、降低单机硬件资源的瓶颈。
  3. 水平分表: 将数据按照一定规律(如Hash取模)拆分成不同表但在同一个数据库中。
    作用: 优化单一表数据量过大而产生的性能问题
  4. 水平分库: 是把同一个表的数据按照一定规则拆到不同的数据库中,每个库可以放到不同的服务器上。
    作用:解决单库大数据,高并发的性能瓶颈。

十七、消息中间件

消息中间件作用: 异步(接口业务逻辑过多,提升接口的响应时间)、削峰(高并发)、解耦(各个模块单独处理维护,比如下单之后的增加积分,增加优惠券,扣库存等)。

  1. 重复消费 : 通过使用幂等处理方式进行处理。
    强校验 : 用于处理重要场景,如金额相关,每次处理接收到的消息通过唯一标识(如订单号)去查流水表,如果有则说明处理过了,直接return即可。
    弱校验:用于处理业务场景可接受丢失的场景,比如发短信,通过redis进行缓存,下次处理时缓存存在则不处理。
  2. 顺序消费 : 可以使用Hash取模方法,将同一个标识相关的消息通知(比如同一个订单号的扣费、积分)发送到同一个队列中,在使用同步发送,就可以保证发送的有序性。

RokectMQ三种发送消息: 同步、异步、单向
同步发送:发送方发出数据后会在接收方发回响应后才发下一个数据包。一般用于重要通知消息。
异步发送:指发送方发出数据后,不等接收方发回响应,接着发送下一个数据包,一般用于可能链路耗时较长而响应时间敏感的业务场景。
单向发送:指负责发送消息而不等待服务器回应且没有回调函数触发,适用于某些耗时非常短但对可靠性要求并不高的场景。

十八、数据库的三大范式

第一范式: 数据库的每一个字段都是不可分割的(确保每列保持原子性)
第二范式: 数据库表中的非主属性只依赖于主键
第二范式: 不存在非主属性对关键字的传递函数依赖关系

你可能感兴趣的:(框架知识点,Spring,java,spring,开发语言)