自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

不能说的秘密的博客

求知若饥,虚心若愚

原创 每日反思

从事任何技术研究,不知道该干什么的时候,就问自己四个问题: •这个方向上最新进展是什么? 都知道吗? •这个方向上最著名的专家有哪些?他们的研究都看过吗? •这个方向上最著名的技术社区有哪些?精华帖都看过一遍吗? •这个方向上最重要的文章、工具有哪些?文章都看过吗?工具都分析过吗?

2016-12-22 21:37:24 1364

原创 Mysql(InnoDB)的SQL加锁分析
原力计划

一、背景工作经常遇到在编写并发场景sql时考虑欠缺,造成过一些bug和sql死锁。于是乎,笔者查阅了不少相关资料。 本文就MySQL/InnoDB的加锁问题,展开较为深入的分析与讨论,主要是介绍一种思路,运用此思路,拿到任何一条SQL语句,都能完整的分析出这条语句会加什么锁?会有什么样的使用风险?甚至是分析线上的一个死锁场景,了解死锁产生的原因。注:MySQL是一个支持插件式存储引擎的数据库系...

2020-03-17 18:19:01 227

原创 Mysql 调优记: INNER JOIN查询 Using temporary; Using filesort 问题优化
原力计划

近期笔者在生产环境中发现一条执行非常慢的sql。大概时间为5s左右,于是乎对改SQL场景进行EXPLAIN 分析,发现一个在执行过程中出现对“Using temporary; Using filesort ”。即在执行过程中产生了临时表来存储结果,并在排序时根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序。经过合理对优化,最终EXPLAIN后,没有再发现明细对SQL性能瓶颈,并且SQL...

2020-03-17 15:44:11 638 2

原创 Java为什么要将String设置为不可变对象?

在探讨为什么要将String设置为不可变对象前,先考虑不可变对象有什么好处,在什么情况下应该用。相对于可变对象,不可变对象有很多优势:不可变对象可以提高对象的效率和安全性。如果你知道一个对象是不可变的,那么需要拷贝这个对象的内容时,就不用复制它的本身而只是复制它的地址,复制地址(通常一个指针的大小)需要很小的内存效率也很高。对于同时引用这个对象的其他变量也不会造成影响。不可变对象对于...

2019-12-29 16:03:58 301

原创 美团开源分布式ID生成系统——Leaf源码阅读笔记(Leaf的号段模式)

Leaf 最早期需求是各个业务线的订单ID生成需求。在美团早期,有的业务直接通过DB自增的方式生成ID,有的业务通过redis缓存来生成ID,也有的业务直接用UUID这种方式来生成ID。以上的方式各自有各自的问题,因此我们决定实现一套分布式ID生成服务来满足需求。具体Leaf 设计文档见: leaf 美团分布式ID生成服务 。出于对该中间件的研究笔者建议下载源码阅读:github源码地址。L...

2019-10-31 22:14:51 741

原创 高性能的异步处理框架Disruptor(五)——Disruptor2.0的应用

前文讲了那么多理论,原理。现在通过实际的代码,来看看Disruptor2.0的几种实际应用代码。Event事件定义:/** * Event,RingBuffer的数据 * @author wangxi * @date 2019-10-16 16:31 */@Slf4jpublic class DisruptorEvent implements Serializable { ...

2019-10-18 15:33:21 501

原创 高性能的异步处理框架Disruptor(四)——Disruptor2.0的优化

现在读者应该能理解如下运行流程图了。如何还看不懂,则需要回顾上篇文章 Disruptor消费者的依赖关系Disruptor2.0主要变化有 3 点:更贴切的命名;把 producer barrier(生产者屏障)整合进了 ring buffer;将 Disruptor Wizard 加入了主代码库。对于上图的实现方案,在新版本的结构图大概如下:可以看到新版本更加简约,Pro...

2019-10-14 14:29:14 191

原创 高性能的异步处理框架Disruptor(三)——Disruptor消费者的依赖关系

前文解释了Disruptor的生产者,消费者的简单工作流程。接下来学习当Disruptor的多个消费者存在依赖关系时,Disruptor对RingBuffer中的消息如何按照消费者的依赖关系来处理。Disruptor系统的最初设计是为了支持需要按照特定的顺序发生的阶段性类似流水线事件,这种需求在企业应用系统开发中很常见。如上图所示,对于独立的一个生产者和三个消费者。一个比较常见的依赖结构是:...

2019-10-09 22:08:45 329

原创 高性能的异步处理框架Disruptor(二)——Disruptor对RingBuffer的读写策略

前文了解了Disruptor与RingBuffer的基础知识后,接下来了解Disruptor对 ringbuffer的访问控制策略。Disruptor对RingBuffer的读取策略假设消费者(Consumer)是一个想从 Ring Buffer 里读取数据的线程,它可以访问 ConsumerBarrier对象——这个 对象由 RingBuffer 创建并且代表消费者与 RingBuffer ...

2019-10-09 11:01:35 174

原创 高性能的异步处理框架Disruptor(一)——认识RingBuffer与Disruptor

Disruptor是什么Disruptor 是一个高性能的异步处理框架。可以认为是最快的消息框架(轻量的 JMS),也可以认为是一个观察者模式的实现,或者事件监听模式的实现。它允许开发者使用多线程技术去创建基于任务的工作流。Disruptor 能用来并行创建任务,同时保证多个处理过程的有序性。Disruptor 的目标就是快,高效。ArrayBlockingQueue也是一个非常优秀的有界队...

2019-10-09 10:31:51 231

原创 Redis官方分布式锁的实现-Redlock实现原理

前文笔者介绍了目前市面上见的比较多的Redis+lua分布式锁的实现,大概有如下三个要点:set命令要用 setkey value px milliseconds nx;保证原子性value要具有唯一性,释放锁时要验证value值,不能误解锁;解锁要使用lua脚本,也是为了保证原子性Redis官方也指出该方法有安全隐患就是在主从复制模式下会导致两个线程可能会同时持有一个锁,如果业务...

2019-09-05 23:22:46 4522

原创 《Rabbit MQ 实战》读书笔记 (二:事务与消息确认模式)

AMQP协议的一个亮点就是对消息的可靠性投递-事务。事务在AMQP-0-9-1中正式成为规范的一部分。虽然AMQP事务保证了在信道开启了事务模式后,全部命令的执行成功。但AMQP事务大大降低了Rabbit的吞吐量,性能极低。同时使用AMQP事务使得生产者与应用程序之间产生同步。为了解决这个可靠性投递和性能的兼容性问题。RabbitMQ提供了发送方确认模式。在客户端与Rabbit服务端的链接信...

2019-06-23 00:39:14 139

原创 《Rabbit MQ 实战》读书笔记 (一:认识AMQP模型)

最近在读RabbitMQ实战这本书,开个帖子。记录一下读书笔记吧。一、AMQP模型Advanced Message Queuing Protocol-高级消息队列协议是一个进程间传递异步消息的网络协议。AMQP模型描述了一套模块化的组件以及这些组件之间进行连接的标准规则。在服务器中,三个主要功能模块连接成一个处理链完成预期的功能:“exchange”接收发布应用程序发送的消息,并根据...

2019-06-22 17:15:54 125

原创 Redis原理(二) Redis的对象类型及其内部编码

Redis 支持 5 种对象类型,而每种结构都有至少两种编码。这样做的好处在于:一方面接口与实现分离,当需要增加或改变内部编码时,用户使用不受影响,另一方面可以根据不同的应用场景切换内部编码,提高效率。Redis 各种对象类型支持的内部编码官网描述:Strings can be encoded as raw (normal string encoding) or int (strings ...

2018-12-24 19:56:27 738

原创 Redis原理(一) redis的内存模型

Redis最为常用的数据类型主要有以下五种:String 字符串Hash 哈希List 列表Set 集合Sorted set 有序集合丰富的类型是 Redis 相对于 Memcached 等的一大优势redis 内部的存储结构如图示:在了解上文的基础上,进一步了解Redis 的内存模型,对 Redis 的使用有很大帮助。如:估算 Redis 内存使用量,选择合...

2018-12-24 16:31:37 2519 3

原创 从Spring AOP的原理理解@Transactional失效问题

在正确配置了Spring事务管理后,或许在某些场景下,你可以写出如下代码:class T { public int createFirst(){ //dosometing.... try { this.createSecond(); }catch (Exception e){ throw e; ...

2018-06-29 13:25:17 3545

原创 主流的hash算法概述及在JDK Map中的应用

hash算法的应用场景Java中的Map实际是一个“散列表”的数据结构,散列表是逻辑上由一系列可存放词条(或其引用)的单元组成,故这些单元也称作桶(bucket) —— 一般都使用线性表来实现。一组词条在散列表内部的具体分布,取决于所谓的散列(hashing)方案:事先在词条与桶地址之间约定的某种映射关系,可描述为从关键码空间到桶数组地址空间的函数: hash() 。这里的hash()...

2018-05-21 15:59:57 717

原创 Java NIO学习笔记(四) 使用JDK 1.7 NIO2.0 实现客户端与服务器的通信

JDK1.7 提供了全新的异步NIO模式。称为:NIO2.0或AIO。该模式引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。异步通道提供两种方式获取获取操作结果。分别是: 通过java.util.concurrent.Future类来表示异步操作的结果; CompletionHandler接口的实现类作为操作完成的回调。 NIO2.0的异步套接字通...

2018-05-19 19:28:53 1230 2

转载 索引使用策略及优化

MySQL的优化主要分为结构优化(Scheme optimization)和查询优化(Query optimization)。本文讨论的高性能索引策略主要属于结构优化范畴。本章的内容完全基于上文B+树在数据库索引中的应用的理论基础,一旦理解了索引背后的机制,那么选择高性能的策略就变成了纯粹的推理,并且可以理解这些策略背后的逻辑。示例数据库 为了讨论索引策略,需要一个数据量不算小的数据库作为示...

2018-05-06 19:45:22 1864

原创 B+树在数据库索引中的应用

目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构(更少的磁盘I/O操作次数的渐进复杂度)一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘I/O操作次数的渐进复...

2018-05-05 14:37:19 816

原创 红黑树的特性和实现

平衡二叉搜索树的形式多样,且各具特色。比如,伸展树实现简便、无需修改节点 结构、分摊复杂度低,但可惜最坏情况下的单次操作需要n时间,故难以适用于对可靠性和稳定性要求极高的场合。 反之,AVL树尽管可以保证最坏情况下的单次操作速度,但需在节点中嵌入平衡因子等标识;更重要的是,删除操作之后的重平衡可能需做多达logn次旋转,从而频繁地导致全树整体拓扑结构的大幅度变化。红黑树即是针对后一不足的改进...

2018-04-23 00:13:34 3577

原创 搜索树之B-/B+树的特性与实现

现代计算机中,在内存与外存(磁盘)组成的二级存储系统中, 数据全集往往存放于外存中,计算过程中则可将内存作为外存的高速缓存,存放最常用数据项的复本。借助高效的调度算法,如此便可将内存的“高速度”与外存的“大容量”结合起来。 两个相邻存储级别之间的数据传输,统称I/O操作。各级存储器的访问速度相差悬殊,故应 尽可能地减少I/O操作。仍以内存与磁盘为例,其单次访问延迟大致分别在纳秒(ns)和毫秒(m...

2018-04-19 00:59:21 2438 1

原创 伸展树的特性及实现

除了AVL树,本章将按照二叉搜索树的介绍,继续介绍平衡二叉搜索树家族中的另一个成员—Splay伸展树。相对于AVL,Splay的实现更为简捷。伸展树无需时刻都严格地保持全树的平衡,但却能够在任何足够长的真实操作序列中,保持分摊意义上的高效率。伸展树也不需要对基本的二叉树节点结构,做任何附加的要求或改动,更不需要记录平衡因子或高度之类的额外信息,故适用范围更广。通常在任意数据结构的生命期内,...

2018-04-16 23:59:17 4016 3

原创 使用redis+lua脚本实现分布式锁

分布式锁的应用场景当多个机器(多个进程)会对同一条数据进行修改时,并且要求这个修改是原子性的。这里有两个限定: 多个进程之间的竞争,意味着JDK自带的锁失效; 原子性修改,意味着数据是有状态的,修改前后有依赖。 本文将先介绍Redis的实现方式,后面笔者会介绍分布式锁的其他实现。在学习Redis实现分布式锁的过程中,笔者首先参考了Redis的官方文档实现Red...

2018-04-15 00:05:30 4441 3

原创 使用MongoDB实现消息队列的异步消息功能

一、消息队列概述消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。实现高性能,高可用,可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等。自己实现一个较完善的消息队列要考虑高可用、顺序和重复消息、可靠投递、消费关系解

2018-01-29 00:51:21 6172

原创 AVL树的实现

前面笔者介绍了二叉搜索树的一般实现和平衡二叉树的实现原理。 本篇文章将继续前文的平衡搜索树来介绍一种具体的平衡搜索树—AVL树。AVL树的特性AVL树中,对于任一节点V,其左右子树的高度差不能超过1。这个高度差定义为平衡因子。

2018-01-01 17:55:55 1742 2

原创 平衡二叉搜索树的实现原理

二叉搜索树的树高与性能前面笔者介绍了二叉搜索树的实现和性能分析,查询,插入和删除等操作均线性正比于二叉树的高度。在最坏的情况下,线性表退化为列表,二叉搜索树的性能会降低至O(n)。因此,如果能控制树高,则二叉搜索树的性能会明显提升理想平衡与适度平衡理想平衡既然二叉搜索树的性能主要影响与树高,则应该在节点数目固定的前提下,尽可能降低树高。也意味着,应尽可能地使兄弟子树的高度彼此接近,即全树尽可能的平衡

2017-12-31 22:08:21 677

原创 二叉搜索树基本操作的实现

对线性表比较熟悉的读者会很清楚线性表的查找性能。无论是链式存储或是顺序存储,在最坏情况或是平均情况下都查需要线性时间。另外,对于堆和栈两种特殊的线性表甚至不提供对任一元素的查找接口。因此,若需要对象集合的组成可以高效地动态调整,又能高效的查找,则线性表很难胜任。高效率的动态修改和高效率的静态查找,是否能够兼顾?如果能,需要采取什么样的数据结构。笔者接下来的几篇博文,将回答这个问题。即采用树...

2017-12-31 19:15:15 529

原创 从最小支撑树和最短路径树学习图的优先级搜索

前面笔者介绍了图的广度优先搜索算法和图的深度优先搜索。这两种搜索虽然各有特点,但基本结构却几乎相同。都需要通过迭代逐一发现各顶点,将其归纳到遍历树中做相应的处理。两种算法的唯一差别在于,如何选取下一个节点的问题。如果将选取下一节点的策略抽象为获取优先级最高的节点,则对于BFS或是DFS则可统一处理,他们的区别仅在于更新节点的优先级的策略不同而已。根据优先级来遍历,称为优先级搜索。

2017-12-17 16:02:11 2181

原创 图的拓扑排序及其应用

拓扑排序的定义对一个有向无环图G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。

2017-12-06 00:28:18 2371

原创 图的深度优先搜索算法并生成DFS树

前面一篇文章介绍了图的广度优先搜索算法和BFS树,这篇文件笔者将介绍另一种图的遍历算法-深度优先算法概述深度优先搜索(Depth-First Search,DFS)选取下一顶点的策略,可概括为:优先选取最后一个被访问到的顶点的邻居。以顶点 s 为基点的 DFS 搜索,将首先访问顶点 s;再从 s 所有尚未访问到的邻居中任取其一,并以之为基点,递归地执行 DFS 搜索。

2017-12-04 00:59:53 11701

原创 图的广度优先搜索算法并生成BFS树

笔者在前面的两篇文章中介绍了图的两种实现方法: 图的邻接表的实现 图的邻接矩阵的实现 接下来笔者将介绍图遍历算法

2017-12-04 00:11:24 8742

原创 图的邻接表的实现

上篇文章介绍了图的邻接矩阵的实现,本文即介绍图的另一种实现方法-邻接表

2017-12-03 22:08:01 1702

原创 图的邻接矩阵的实现

对于图的一些基本概率和术语的内容汗牛充栋,故本文不会做过多解释。仅仅总结下笔者学习图的邻接矩阵的相关知识邻接矩阵的实现原理邻接矩阵(adjacency matrix)是图ADT最基本的实现方式,使用二维数组A[n][n]来表示由n个顶点构成的图。

2017-12-03 19:01:51 11861

原创 二叉树的链式存储实现及遍历

关于二叉树链式存储和遍历

2017-11-18 21:38:59 3172

原创 二叉树的顺序存储实现及遍历

关于二叉树的实现,常见的大概有三种实现方法: 顺序存储:采用数组来记录二叉树的所有节点 二叉链表存储: 每个节点保留一个left,right域,指向左右孩子 三叉链表存储: 每个节点保留一个left, right, parent域,指向左右孩子和父亲 本文将实现顺序存储来实现一个二叉树并介绍其遍历方法

2017-11-08 00:57:50 9318

原创 CPU load过高产生的原因及排查

之前面试被问到,造成CPU load过高的原因有哪些?如何快速排查其原因? 开一贴,总结该相关知识

2017-09-24 20:01:33 30380 1

原创 理解HTTP缓存和304状态码

最近研究nginx日志的时候,对于304这个状态码产生了好奇。之前一直知道3XX系列的状态码表示重定向,但对于304的具体原理没有仔细研究过。304 的标准解释是:客户端有缓冲的文档并发出了一个条件性的请求。服务器告诉客户端,原来缓冲的文档还可以继续使用。完成这个几个动作包括服务器确认返回304给予客户端,主要包含几个http头信息,请求头If-None-Match、响应头ETag和响应头Cache

2017-07-30 00:40:42 28606 2

转载 一致性hash算法 - consistent hashing

consistent hashing 算法早在 1997 年就在论文 Consistent hashing and random trees 中被提出,目前在 cache 系统中应用越来越广泛

2017-07-09 17:49:24 479

原创 Redis常见的集群方案

前一段时间面试阿里巴巴,面试官问我除了Redis 3.0开发官方提供的Redis Cluster模式(http://www.redis.cn/topics/cluster-tutorial.html)外,你还知道哪些Redis集群方案。面试后便查询了相关资料,记录了一下Redis常见的各种集群方案。

2017-07-09 12:03:36 1065

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