JAVA程序猿3000问第2日

JAVA程序猿3000问第2日

第六问 介绍下一致性hash算法
第七问 Spring如何实现(保证)事务的一致性,完整性
第八问 Spring中的事务转播机制类型
第九问 接口和抽象类的区别
第十问 sleep()和wait()的区别

第六问 介绍下一致性hash算法

描述

  1. hash值是整数(非负),非负整数的值的范围(0-2^32 -1)做成一个圆环。
  2. 对集群节点的某个属性(节点名称)求hash值,根据hash值,放到环上,确定它的位置。
  3. 对数据的key求hash值,确定在环上的位置,然后按顺时针方向找离它最近的节点,数据就放到这个节点上。

优点

风险均摊,同时避免缓存雪崩,一个缓存节点出现问题移出环即可,只影响一段hash范围覆盖到的缓存,其他缓存节点和数据不受到影响。
同时引入虚拟节点连接物理机器分配数据存储地址,保障新增服务器后数据处理压力均摊。

第七问 Spring如何实现(保证)事务的一致性,完整性

Spring的事务机制包括声明式事务和编程式事务。

编程式事务

显式的使用TransactionTemplate声明事务。

声明式事务

声明式事务管理使用了AOP面向切面编程实现的,本质就是在目标方法执行前后进行拦截。在目标方法执行前加入或创建一个事务,在执行方法执行后,根据实际情况选择提交或是回滚事务。

声明式事务的优缺点:

优点

不需要在业务逻辑代码中编写事务相关代码,只需要在配置文件配置或使用注解(@Transaction),这种方式没有侵入性。

缺点

声明式事务的最细粒度作用于方法上,如果像代码块也有事务需求,只能变通下,将代码块变为方法。(这样算不上什么太大的缺点吧)

第八问 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类似的操作。

    这个后面要仔细看看

第九问 接口和抽象类的区别

抽象类和接口的对比

参数 抽象类 接口
默认的方法实现 它可以有默认的方法实现 接口完全是抽象的,它根本不存在方法的实现
实现 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现
构造器 抽象类可以有构造器 接口不能有构造器
与正常Java类的区别 除了你不能实例化抽象类之外,它和普通Java类没有任何区别 接口是完全不同的类型
访问修饰符 抽象方法可以有public、protected和default这些修饰符 接口方法默认修饰符是public。你不可以使用其它修饰符。
main方法 抽象方法可以有main方法并且我们可以运行它 接口没有main方法,因此我们不能运行它。
多继承 抽象方法可以继承一个类和实现多个接口 接口只可以继承一个或多个其它接口
速度 它比接口速度要快 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。
添加新方法 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 如果你往接口中添加方法,那么你必须改变实现该接口的类。

什么时候使用抽象类和接口

  • 如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。
  • 如果你想实现多重继承,那么你必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。
  • 如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。

第十问 sleep()和wait()的区别

对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。
sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。
在调用sleep()方法的过程中,线程不会释放对象锁。
而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备
获取对象锁进入运行状态。
(这里可能需要和notify,notifyall讲讲锁池和等待池的关系,这一内容放到明天讲解)

ps:这个系列,很多解答并不是自己写的,因为网上说的可能比我说的更好,写这个系列的最大目的还是自我提升,参考的博客都会在最下面列出,不要过多的纠结于原创。

参考

https://www.jianshu.com/p/366108da5bed
https://blog.csdn.net/jie_liang/article/details/77600742
http://www.importnew.com/12399.html
https://www.cnblogs.com/hongten/p/hongten_java_sleep_wait.html

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×