极客时间王争老师跳表SkipList学习 刚开始看王争老师的代码有点不知所措,再看完JDK中的跳表实现后恍然大悟,还是自己太笨,没有找到关键问题之所在。王争老师的代码和JDK中的代码中所使用的数据结构不相同,但是大致思路是一致的。jdk中维护索引节点之间的关系使用指针right, down ,而王政老师使用的是数组,个人认为指针比数组更好理解更清晰。王争老师的代码只用了一种对象Node 就实现了跳表,非常巧妙。
docker 搭建zk 集群 Docker默认提供了3种网络模式,生成容器时不指定网络模式下默认使用bridge桥接模式。每次容器启动时ip会发生变更,无法达到我们集群的效果。创建自定义网络模式,指定网段。
RocketMQ消息发送 RocketMQ消息发送RocketMQ 支持3 种消息发送方式: 同步 (sync)、异步(async)、单向(oneway)。同步:发送者向 MQ 执行发送消息API 时,同步等待,直到消息服务器返回发送结果。异步:发送者向MQ 执行发送消息API 时,指定消息发送成功后的回调函数,然后调用消息发送API 后,立即返回,消息发送者线程不阻塞,直到运行结束,消息发送成功或失败的回调任务在一个新的线程中返回。单向:消息发送者向MQ 执行发送消息API 时,直接返回,不等待消息服务器的结果
二、dubbo spi 源码分析 二、dubbo spi 源码分析1、ExtensionLoaderExtensionLoader 是dubbo spi 主要实现类,从字面意思可以看出是扩展加载器,是将配置文件与java的对应关系进行组装处理,从而得到我们需要的实际扩展处理类ExtensionLoader 类中有两个静态属性 EXTENSION_LOADERS (缓存所有的ExtensionLoader) 和 EXTENSION_INSTANCES (缓存扩展实现) private static final Concurren
一 、dubbo 源码分析之 dubbo spi dubbo spiJDK SPIspi全称英文是service provider Interface,翻译成中文也就是服务提供接口,在jdk 1.6开始,就已经提供了SPI.它的使用比较简单。即在项目的类路径下提供一个META/services/xx文件,配置一个文件,文件名为接口的全路径的名称,内容为具体的实现类全路径名。jdk将会使用ServiceLoader.load()方法去解析和加载接口和其中的实现类,按需执行不同的方法。缺点:1.无法按需加载。虽然 ServiceLoader 做了延迟载
StampedLock 锁 StampedLock锁StampedLock 锁概述StampedLock 锁概述StampedLock 是并发包里JDK8新增的一个锁,该锁提供了三种模式的读写控制,当调用获取锁的系列函数式,会返回一个long 型的变量,我们称之为戳记(stamp),这个戳记代表了锁的状态。其中try系列获取锁的函数,当获取锁失败后会返回标记为0的stamp值。当调用释放锁和转换锁的方法时需要传入获取锁时返回的stamp值。写锁 writeLock : 是一个排它锁 或 独占锁,某时只有一个线程可以获取该锁,
IO 基本概念 IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。一、BIO在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒绝请求,如果有的...
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。解题思路:1. 后序遍历则数组最后一个元素就是根节点。2. 从左向右遍历,查找第一个大于根节点的元素,这个元素为根节点下的第一个右子数。找到根节点的右子数后,该元素的左边第一个元素为根节点的左子树。3. 遍历左子树是否有大于根节点的元素,如果有则是...
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应 【思路】借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然1≠4,所以我们继续压栈,直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。举例:入栈1,2,3,4,5出栈4,5,3,2,1首先1入辅助栈,此时栈顶1≠4,...
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。 解决思路:定义两个栈,一个为正常的存储数据,另一个为最小值栈。代码思路:a. 如果最小值栈内为空,则正常pushb.如果最小值栈不为空,则比较将要push的值 与 最小值栈中栈顶元素,如果 将要入栈的值小于或者等于最小值栈 中的栈顶元 素,则将该元素压入正常的栈 并且 将该元素雅茹最小值栈中。c. pop 出栈时,将出栈元素与 最小值栈顶元素进行比较,如果相等,则最小值栈也进行出栈...
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构) 本题玩儿的就是递归思想,本人太菜忽略了 B 数根节点的值可能会重复出现在A数中,以下代码摘自牛客上的一位大神。 public static boolean HasSubtree(TreeNode root1, TreeNode root2) { boolean result = false; //当Tree1和Tree2都不为零的时候,才进行比较。否则直接返回f...
经典的青蛙跳台阶问题 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果):分析: 当 n = 1 时,有 1 种跳法。当 n = 2 时,有 2 种跳法。当n = 3 时,有3种跳法 [1,2] 、[2,1] 、[1,1,1]当n = 4 时 ,有5种跳法 [1,1,1,1] [2,2] [1,2,1] [2,1,1] [1,1,2]当n ...
java最大公约数,最小公倍数 一 .最大公约数:如果有两个数A、B ,求最大公约数?step1: 判断A,B 是否想等,如果想等,最大公约数就是A或 B;step2: 用A,B中较大的数除以较小的数,如果余数为0 ,那么最大公约数就是较小的那个数。如果余数不为0,到第三步。step3: 用A,B 中较小的那个数除以第二步所得的余数,如果为0,那么第二部所得的余数就是最大公约数,如不是到第四步。step4:经过step...
java - ThreadPoolExecutor源码解析 ThreadPoolExecutor源码解析一、构造方法参数1.构造方法就不在此赘述,重点关注构造方法种的参数。参数名作用corePoolSize核心线程池大小maximumPoolSize最大线程池大小keepAliveTime线程池中超过corePoolSize数目的空闲线程最大存活时间;可以allowCoreThreadTimeOut(true)使...
Java内存模型 && JVM 内存模型 Java 内存模型是通过各种操作来定义的,包括对变量的读/写操作,监视器的加锁喝释放操作,以及线程的启动和合并操作。JMM为程序中的所有操作定义了一个偏序关系,称之为Happens-Before。线程内的代码能够按先后顺序执行,这被称为程序次序规则。对于同一个锁,一个解锁操作一定要发生在时间上后发生的另一个锁定操作之前,也叫做管程锁定规则。前一个对volatile的写操作在后一个volat...
关于对象序列化与反序列化的那些事 java 自带的 serializable 序列化接口在这里就不再多说,下面介绍MessagePack ,与json的序列化对比,首先创建我们需要序列化的beanpublic class UserInfo implements Serializable { private String name; private String gender; private Integer
BIO 实例代码 BIO 典型的一请求,一应答通信模型缺点:该模型最大的问题就是,当客户端数量增加时,服务端的线程数与客户端并发的数量是 1:1 关系,我们知道在jvm 中线程是非常宝贵的资源,当线程数不断上升时,系统性能将不断下降,可能会出现堆栈溢出,创建线程失败等问题,并最终导致宕机或者僵死,不对外提供服务,下面就进行演示BIO编程模型。1.TimeServerpublic class TimeServer
Netty入门之 TimeServer && TimeClient 1.TimeServer/** * Created by ju on 2017-06-09. */public class TimeServer { public void bind(int port) { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup worker