自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(72)
  • 收藏
  • 关注

原创 happen-before原则解读

目录1.基本概述1.1 为什么要happen-before原则1.2 happen-before原则定义2.规则解读2.1 程序顺序规则2.2 监视器锁规则2.3 volatile变量规则2.4 传递性规则2.5 线程启动规则2.6 线程中断规则1.基本概述1.1 为什么要happen-before原则由于多线程编程时,线程并不直接操作主内存,所以会存在缓存不一致的问题(可见性问题)。为了解决这个问题,想要我们在编写程序的时候非常小心,而编写多线程程序时我们需要注意的地方就非常多。java设计者也考虑

2021-06-11 22:22:52 1616

原创 JUC-CopyOnWriteArrayList

jdk版本: 1.8更多数据结构,算法,设计模式,源码分析等请关注我的微信公众号[技术寨],每周至少两篇优质文章目录1.设计思想解决方式1.基本概述1.1 继承关系1.2 主要属性1.3 主要方法2. 核心方法图解2.1 添加元素2.2 获取元素2.3 删除元素2.4 特殊方法-不存在添加addIfAbsent3.简单的迭代器4.优点和缺点4.1 优点4.2 缺点5.面试必知5.1 CopyOnWriteArrayList是如何扩容的5.2 CopyOnWriteArraySet实现方法1.设计思.

2021-06-09 22:23:54 233 2

原创 CAS机制

1.引入为了说明CAS机制,需要先介绍一下悲观锁和乐观锁。1.1 悲观锁总是假设最坏的情况,每次操作数据之前都会先上锁,后面想要取数据就会被阻塞。在java中通过synchronized同步原语来实现悲观锁。悲观锁存在的问题:在多线程环境下,在等待锁,释放锁时会存在线程的上下文切换导致性能下降。1.2 乐观锁总是假设最好的情况,每次操作数据之前都不会上锁,在更新时判断数据是否已经是否已经被更新。其常见的一种实现方式就是今天的主角:CAS。2.CAS2.1 三个操作数内存地址 V旧的预期

2021-06-02 08:53:46 311 1

原创 JUC-atomic

jdk版本: 1.81.概念juc的atomic是jdk1.5引入的,完整的包名是:java.util.concurrent.atomic,通过这些类可以帮助我们完成一些原子性的操作。不过它没有像synchronizd那样保证一段代码的原子性,它只能保证一个变量的原子性操作。synchronizd也能保证一个变量的原子性,为什么不用它呢?当然是性能问题,通过使用atomic包下的类来替代synchronizd,可以保证更好的性能。口说无凭,我们来测试一下:@BenchmarkMode(Mode.

2021-05-31 23:11:24 207

原创 ArrayList图解

1.主要属性1.1 elementDataObject[] elementDataArrayList是基于数组的,底层数据就是存储在elementData中1.2 sizearrayList的真实大小2. 常见操作2.1 添加元素2.1.1 往数组最后添加元素 public boolean add(E e) { // 容量不够,扩容 ensureCapacityInternal(size + 1); // 添加元素 e

2021-05-21 22:21:56 402 3

原创 zookeeper源码解析-四字命令

1.引入zookeeper支持通过命令获取其服务的运行状态,这就是传说中的“四字命令”。由于这些命令是通过TCP/UDP协议传输的,所以不能在zookeeper的cli命令下使用,常用的使用方式是用工具nc,比如:echo stat | nc 127.0.0.1 2181。(如果报命令不存在,需要使用yum install nc安装)2. 命令介绍ZooKeeper四字命令功能描述...

2020-03-22 12:11:24 554

原创 zookeeper源码解析-节点清理

zk版本:3.5.61. 引入在3.5.6版本中,有两种节点需要清理:临时节点(会话结束,会被清除)和容器节点(如果没有子节点,会被清理)。2. 节点清理清理节点的操作是通过ContainerManager类完成,在单机启动的博客中其他可以看到它的身影。ZooKeeperServerMain.java------------------------public void runF...

2020-03-21 23:09:26 1131

原创 zookeeper原理-一致性

1. 不得不说的CAP原理要介绍分布式中的一致性,肯定会关联出CAP原理,那什么是CAP呢?一致性(C):分布式系统更新操作之后,所有的节点数据一致。可用性(A):每一个非故障的节点必须对每一个请求作出响应。分区容错性(P):分区容错性。以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择,也就是说无...

2019-12-29 18:03:28 335

原创 zookeeper源码解析-单机处理客户端请求

1.引入zk单机服务端虽然在实际生产使用中不可能碰到,但是用于接下来分析zk集群服务端有很大用处,我们秉承循序渐进的方式,先介绍一下单机服务端的启动和处理流程2.单机服务器启动在单机启动过程中,会创建服务端连接对象,用于处理客户端的请求。其处理过程,可以从以下代码开始介绍。ZooKeeperServerMain.java------------------------- publ...

2019-12-29 16:34:39 246

原创 zookeeper源码解析-客户端请求流程

1.引入前面介绍了客户端创建流程,最终调用了ClientCnxn.start方法启动了两个重要的线程SendThread和eventThread,这两个就是客户端处理请求的关键所在,所以在本篇中会逐一介绍这两个线程的作用。为了方便介绍客户端请求处理过程,我们接着前面介绍的cli解析分析,当前以delete操作为例,最终介绍到了 DeleteRequest request = n...

2019-12-27 23:30:22 361

原创 zookeeper源码解析-zk集群启动

1.引入在前面我们已经介绍了zk的单机启动,其过程也是比较简单,主要是启动zk服务,zk admin服务,创建管理快照和事务日志的FileTxnSnapLog对象等。现在我们来说一下zk集群启动过程,这也是zk生产环境启动服务的方式。2.从QuorumPeerMain.main说起单机启动和集群启动的都是从QuorumPeerMain.main这个方法开始,只是由于配置文件不同,最终会运行在...

2019-12-16 23:23:41 330

原创 zookeeper源码解析目录

zookeeper源码解析-单机启动zookeeper源码解析-定时清理zk数据zookeeper源码解析-admin服务zookeeper源码解析-客户端创建流程zookeeper源码解析-命令行解析

2019-12-15 13:27:17 194

原创 zookeeper源码解析-命令行解析

zk版本:3.5.61.引入在单机模式下zk服务启动前面已经介绍了,现在将介绍如何通过客户端的形式访问zk服务。其实访问zk服务有很多方式,可以通过java api等,但是这种方式稍微有点复杂,我们现在通过最简单的一种方式实现zk的客户端,即zk自带的cli。2.命令行使用在安装zookeeper之后,我们会使用zkStart.sh的命令启动zk服务,接着会使用zkCli.sh -se...

2019-12-12 21:45:50 227

原创 zookeeper源码解析-客户端创建流程

zk版本:3.5.61.引入前面在介绍命令行解析时,提到创建zk客户端,现在我们来看看创建zk客户端要注意什么。2. zk客户端创建在ZookeeperMain.connectZk方法中会创建zk客户端,我们就由此左右分析的起点.ZooKeeperMain.java------------------- connectToZK(cl.getOption("server")...

2019-12-12 18:54:00 167

原创 zookeeper源码解析-admin服务

zk版本:3.5.61.引入在单机启动时会创建admin对象 adminServer = AdminServerFactory.createAdminServer(); // 设置zookeeper服务 adminServer.setZooKeeperServer(zkServer); // 服务启动,监听客户端请...

2019-12-12 14:53:42 2928

原创 zookeeper源码解析-日志快照清理过程

1.引入在前面介绍单机启动zk服务时,我们提到过启动时会创建DatadirCleanupManager对象,用于清理多余的zk数据,现在我们来看一下它是如何实现的。2.清理数据QuorumPeerMain.java-------------------------- DatadirCleanupManager purgeMgr = new DatadirCleanupManager(c...

2019-12-12 12:39:15 540

原创 zookeeper源码解析-单机启动主要流程

zk版本:3.5.6根据zkStart.sh脚本可知,QuorumPeerMain.main方法是启动zk的唯一位置。但是这个启动zk可以分为两种模式:单机模式与集群模式。由于集群模式比较复杂,会在后面一一介绍,现在我们先看看单机模式zk的启动。public static void main(String[] args) { QuorumPeerMain main = ne...

2019-12-12 11:29:16 294

原创 spark源码解析-作业执行过程

1. 引入通过前一篇介绍spark submit的文章,我们知道如果以客户端模式最终运行的是–class指定类的main方法,这也是执行作业的入口。接下来,我们就以一个简单的例子,说明作业是如何执行的。2.作业执行过程val sparkConf = new SparkConf().setAppName("earthquake").setMaster("local[2]")val sc = ...

2019-11-28 15:26:59 290

原创 spark源码解析目录

spark版本: 2.0.01. spark源码解析-master流程分析2. spark源码解析-rpc原理3.spark源码解析-worker启动4.spark源码解析-分析一次完整的远程请求过程5.spark源码解析-sparkSubmit分析...

2019-11-28 15:01:20 229

原创 spark源码解析-sparkSubmit分析

1.引入为了简单测试项目功能,我们可能只需要使用spark-shell就可以完成,但是企业级项目我们都是先打包好之后使用spark-submit脚本完成线上的spark项目部署。./bin/spark-submit \--class com.example.spark.Test \--master yarn \--deploy-mode client \/home/hadoop/dat...

2019-11-25 22:48:25 285

原创 spark源码解析-分析一次完整的远程请求过程

spark版本: 2.0.01.概念1.引入前面已经介绍了master启动,worker启动和rpc原理,现在结合这些,来探究一下一次完整的远程请求到底是咋样的?就以worker启动后注册到master为例,我们来细细品味一下其远程服务调用过程。2.远程服务请求过程worker注册到master的方法是masterEndpoint.ask[RegisterWorkerResponse...

2019-11-25 21:17:35 253

原创 spark源码解析-worker启动

1.概念worker是执行任务的真正服务,它可以管理多个executors,并向master汇报任务的执行情况,现在让我们看看它的启动过程。由于worker启动过程和master启动过程有一定相通之处,所以在阅读本文之前,请先阅读master的启动过程。2.worker启动在启动spark时,需要执行脚本sh start-slaves.sh,其最终是调用org.apache.spark.d...

2019-11-25 15:54:02 339

原创 spark源码解析-rpc原理

1.概念spark是分布式服务,需要涉及到大量的网络通信以及远程服务调用(rpc),在1.6前spark使用的是akka实现,但是考虑到akka兼容性问题,最后舍弃,改为netty。这篇文章就将介绍基于netty的rpc服务是如何运作的。在前一篇文章中介绍了master的启动过程,但是其中对rpcEnv这部分介绍的很少,所以我将从上篇文章创建rpcEnv位置说明spark中的服务是如何通信的。...

2019-11-22 23:25:40 302

原创 spark源码解析-master流程分析

1. 引入master负责管理spark的元数据,实现spark任务监控,调度等,现在就来介绍一下master启动过程。2. Master流程在start-master.sh脚本中可以发现最终调用的是org.apache.spark.deploy.master.Master的main方法。现在来看一下这个方法有什么? def main(argStrings: Array[String]) ...

2019-11-22 15:56:38 321

转载 九大排序算法-归并排序

1. 图示过程(1) 归并排序的流程(2) 合并两个有序数组的流程2. 动图展示3. Java代码实现public static void mergeSort(int[] arr) { sort(arr, 0, arr.length - 1);}public static void sort(int[] arr, int L, int R) { ...

2019-11-19 10:58:36 195

原创 九大排序算法-插入排序

插入排序是通过保证前n位是有序的,当第n+1位需要插入时,反向扫描前n位的大小,碰到大于该数的就向后移动一位,直到小于该数停止,即需要插入的位置。示意图:代码实现: public static void insert(int[] arr) { for (int i = 1; i < arr.length; i++) { int tmp =...

2019-11-19 09:37:06 76

原创 九大排序算法-冒泡排序

冒泡排序是一种通过后面相邻两个元素依次比较大小,并将最大(最小)值往后移动,从而实现排序的一种方式。代码实现: public static void bubble(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { for (int j = 0; j < arr.length...

2019-11-18 23:22:12 141

原创 九大排序算法-选择排序

选择排序是先选定一个数据元素,然后依次和后面的元素进行比较,找到最大(最小)值,然后交换两个元素的位置。示意图: public static void select(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { int minIndex = i; fo...

2019-11-18 22:45:33 357

原创 九大排序算法-快速排序

冒泡排序是一种前后依次比较大小,将最大(最小)值依次移动到最后的一种方式。示意图: public static void bubble(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { for (int j = 0; j < arr.length - i - 1; j++)...

2019-11-18 22:44:23 150

原创 数据结构-队列

1. 概念前面一个篇博客介绍了栈,现在来介绍一下队列,它和栈有一定的相似度,可以看完两个之后对比记忆。队列是一个先进先出的数据结构,允许插入的一端称为队尾,允许删除的一端称为对首,示意图如下。和栈一样,可以基于数组和链表实现队列。2. 队列的实现2.1 基于数组示意图:代码实现:public class ArrayQueue { private Object[] da...

2019-11-18 20:12:48 126

原创 数据结构-栈

1.概念栈是一种先进先出的数据结构,其中有两个关键的位置:栈顶和栈底。当需要出栈时,只需将栈顶元素取出并将原来的栈顶元素指针向前移动。压栈时,只需将栈顶位置指向新的元素。具体的示意图如下:栈的实现可以基于两种常见的数据结构:数组和链表2. 栈的实现2.1 基于数组示意图:代码实现(java版):public class ArrayStack { private Objec...

2019-11-17 13:01:56 230

原创 数据结构-链表

1.概念在前面的博客数据结构-数组中,可以看到数组虽然查询比较快,但是插入和删除元素的效率并不高,而且创建一个数组之后不能修改其长度,有什么数据结构可以解决数组的这些缺点吗?有,这个就是本篇需要介绍的数据结构-链表,不过它的查询效率并不高,在后面我们会介绍。链表也是一种常见的数据结构,它不是线性存储数据,而是通过前一个元素保存后一元素的引用从而形成一条链。不过链表可以分为多种类型链表,常见的有...

2019-11-16 23:51:35 332

原创 数据结构-数组

1. 概念数组是一种线性表数据结构,它用一组连续的内存空间,来存储一组具有相同类型的数据。数组是最常见的数据结构,表示方式比较简单int[] arr = {12,1,-9,90};2. 基本操作2.1 查询元素 int[] arr = {12, 1, -9, 90}; // -9 System.out.println(arr[2]);...

2019-11-16 21:27:57 194

原创 guava使用(2)-字符串操作

前面一篇文章guava使用(1)-集合中,已经简单介绍了guava中的集合操作,现在将看看它的字符串操作。1. Joiner //1、将list字符串集合,以,形式转为字符串 List<String> list = new ArrayList<String>(); list.add("1"); list.add(...

2019-08-02 21:11:02 179

原创 guava使用(1)-集合

1. 为什么要使用guavaGuava是一种基于开源的Java库,谷歌很多项目使用它的很多核心库。这个库是为了方便编码,并减少编码错误。这个库提供用于集合,缓存,支持原语,并发性,常见注解,字符串处理,I/O和验证的实用方法。2. 集合2.1 普通集合创建 List<String> list = Lists.newArrayList(); Set...

2019-08-01 22:13:48 144

原创 zuul1源码解析-请求处理流程

1.zuul是什么Zuul 是 Netflix 开源的微服务网关,可以将非服务核心功能移至到网关中,比如:鉴权,请求日志等2.zuul1系统架构图请求经过ZuulServlet,然后执行各种类型的过滤器链处理完毕之后,将处理后的结果响应出去。而且Zuul强化了其过滤器功能,支持热加载过滤器。源码解析此次源码分析的版本是1.x,如果你看的是2.0版本以上的请忽略本文章。3.1 ser...

2019-06-13 08:42:38 767

原创 1.mockito源码解析-创建mock对象的过程

mockito创建mock对象的方式:List list = mock(List.class);现在我们来看看,这行代码到底在干什么?(1)Mockito.java /** * 创建一个mock实例 * * @param classToMock 需要mock的接口或者类 */ public static <T> T mock(Class<T>...

2019-06-12 08:05:15 2566

转载 git使用脑图

2019-05-22 20:31:08 170

原创 Unsafe

1. 介绍Unsafe顾名思义它是一个“不安全”的类,但是仍有很多框架(比如:Netty、Hadoop、Kafka等)喜欢使用它,为什么呢?因为它是直接和系统打交道,执行效率会比较高。但是它的很多方法都是很偏向底层的,一般人使用可能会对系统造成不好的影响,所以java官方不推荐使用这个类。但是不影响我们分析这个类,并且它也是分析并发的基础。2. 源码分析public final class ...

2019-04-11 21:58:08 184

原创 设计模式目录

1.概念设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我...

2019-04-03 22:21:57 134

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除