<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[zkp_java的专栏]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/zkp_java</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; zkp_java]]></copyright><item><title><![CDATA[redis系列六：压缩链表]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/88934529</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/88934529</guid><author>zkp_java</author><pubDate>Sun, 31 Mar 2019 20:14:22 +0800</pubDate><description><![CDATA[何时使用压缩链表
当一个哈希键只包含少量键值对，并且每个键值对的键和值要么就是小整数，要么就是长度比较短的字符串，那么Redis就会使用压缩列表来做哈希键的底层实现。
哈希键里面包含的所有键和值都是小整数值或者短字符串。


...]]></description><category></category></item><item><title><![CDATA[redis系列五：整数集合]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/88907647</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/88907647</guid><author>zkp_java</author><pubDate>Sat, 30 Mar 2019 09:53:30 +0800</pubDate><description><![CDATA[整数集合(intset)是Redis用于保存整数值的集合抽象数据结构，它可以保存的类型为int16_t、int32_t或者int64_t的整数值，并且保证集合中不会出现重复元素。
整数集合定义在intset.h文件中，具体定义如下：
typedef struct intset {
    uint32_t encoding;
    uint32_t length;
    int8_t cont...]]></description><category></category></item><item><title><![CDATA[[redis]redis系列四：跳跃表]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/88877248</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/88877248</guid><author>zkp_java</author><pubDate>Thu, 28 Mar 2019 20:20:30 +0800</pubDate><description><![CDATA[跳跃表通过在每个节点中维持多个指向其他节点的指针，从而达到快速访问节点的目的。跳跃表支持平均O(logN)、最坏O(N)复杂度的节点查找。
跳跃表的实现
跳跃表定义在server.h文件中，下图所示为一个跳跃表的示例：

上图中最左边的是zskiplist结构，右边四个是跳跃表节点(zskiplistNode结构)，跳跃表的结构定义如下：
// 跳跃表节点
typedef struct zskip...]]></description><category></category></item><item><title><![CDATA[[redis] redis系列三：字典]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/88833597</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/88833597</guid><author>zkp_java</author><pubDate>Tue, 26 Mar 2019 23:45:15 +0800</pubDate><description><![CDATA[redis中的字典使用哈希表作为底层实现，一个哈希表里面可以有多个哈希表节点，而每个哈希表节点就保存了字典中的一个键值对。
数据结构
哈希表节点结构
哈希表节点结构定义如下：
typedef struct dictEntry {
	// 键
    void *key;
    // 值是一个union，即值可以是一个指针，或者一个unit64_t整数，或者int64_t整数
    union ...]]></description><category></category></item><item><title><![CDATA[[redis] redis系列二：链表]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/88831326</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/88831326</guid><author>zkp_java</author><pubDate>Tue, 26 Mar 2019 21:50:47 +0800</pubDate><description><![CDATA[redis中链表的数据结构定义如下：
// 链表中的节点
typedef struct listNode {
	// 节点的前驱
    struct listNode *prev;
    // 节点的后继
    struct listNode *next;
    // 节点上保存的值
    void *value;
} listNode;

typedef struct listIter...]]></description><category></category></item><item><title><![CDATA[[redis] redis系列一：SDS字符串]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/88809923</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/88809923</guid><author>zkp_java</author><pubDate>Tue, 26 Mar 2019 00:19:41 +0800</pubDate><description><![CDATA[注：本系列文章来自于对《redis设计与实现》的总结，并结合redis 5.0.3的源码进行分析

redis没有直接使用C语言传统的字符串表示方式(以空字符串结尾的字符数组，以下简称C字符串)，而是自己构建了一种名为简单动态字符串(simple dynamic string, SDS)的抽象类型，并将SDS作为redis的默认字符串表示。在redis里，包含字符串值的键值对在底层都是有SDS实...]]></description><category></category></item><item><title><![CDATA[[Linux] Linux IO模式及 select、poll、epoll详解]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/88322938</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/88322938</guid><author>zkp_java</author><pubDate>Thu, 07 Mar 2019 22:32:32 +0800</pubDate><description><![CDATA[注：本文是对众多博客的学习和总结，可能存在理解错误。请带着怀疑的眼光，同时如果有错误希望能指出。

同步IO和异步IO，阻塞IO和非阻塞IO分别是什么，到底有什么区别？不同的人在不同的上下文下给出的答案是不同的。所以先限定一下本文的上下文。

本文讨论的背景是Linux环境下的network IO。

一、概念说明

用户空间和内核空间
进程切换
进程的阻塞
文件描述符
缓存 I/O

用户空间...]]></description><category></category></item><item><title><![CDATA[[JUC] AQS共享模式详解]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/87361974</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/87361974</guid><author>zkp_java</author><pubDate>Fri, 15 Feb 2019 14:50:53 +0800</pubDate><description><![CDATA[在[JUC] AQS独占模式详解中我们已经结合ReentrantLock分析了AQS独占模式的实现，本文将结合CountDownLatch分析共享模式的实现。
场景说明
如下图所示，有一个初始值为3的CountDownLatch，线程t1和t2在时间线1调用await等待latch的值变为0，线程t3在时间线2调用countDown()将latch值减1，线程t4在时间线3调用countDown(...]]></description><category></category></item><item><title><![CDATA[[JUC] AQS独占模式详解]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/87181667</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/87181667</guid><author>zkp_java</author><pubDate>Wed, 13 Feb 2019 14:45:15 +0800</pubDate><description><![CDATA[前言
AQS是指java.util.concurrent.locks.AbstractQueuedSynchronizer类，AQS并没有使用类似synchronized这样特殊的关键字，而是通过维护一个先进先出(FIFO)的等待队列和状态变量来实现锁和同步器功能。在JDK11中AbstractQueuedSynchronizer具有如下实现类：

可以看到常用的ReentrantLock、Cou...]]></description><category></category></item><item><title><![CDATA[[JUC] LockSupport浅析]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/87088757</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/87088757</guid><author>zkp_java</author><pubDate>Tue, 12 Feb 2019 14:37:48 +0800</pubDate><description><![CDATA[这里写自定义目录标题wait/notifyLockSupportwait/notify和LockSupport对比LockSupport注意事项参考文献
LockSupport是Java6引入的一个工具类，它简单灵活，应用广泛。在没有LockSupport之前，线程的挂起和唤醒咱们都是通过Object的wait和notify/notifyAll方法实现。
我们以例子来说明两者之间的区别
wait/...]]></description><category></category></item><item><title><![CDATA[[NIO与Netty] ThreadLocal详解]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/86565075</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/86565075</guid><author>zkp_java</author><pubDate>Sun, 20 Jan 2019 19:32:48 +0800</pubDate><description><![CDATA[目录ThreadLocal的基本使用ThreadLocal实现原理
ThreadLocal实现了Java中线程局部变量。所谓线程局部变量就是保存在每个线程中独有的一些数据，我们知道一个进程中的所有线程是共享该进程的资源的，线程对进程中的资源进行修改会反应到该进程中的其他线程上，如果我们希望一个线程对资源的修改不会影响到其他线程，那么就需要将该资源设为线程局部变量的形式。
ThreadLocal的基...]]></description><category></category></item><item><title><![CDATA[[mysql] ubuntu下如何干净的卸载mysql]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/85646917</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/85646917</guid><author>zkp_java</author><pubDate>Wed, 02 Jan 2019 22:54:25 +0800</pubDate><description><![CDATA[
dpkg --list|grep mysql查看mysql有哪些依赖：

peter@ubuntu:~/Study/MySql/mysql-8.0.13-linux-glibc2.12-x86_64$ dpkg --	list|grep mysql
ii  mysql-client-core-5.7                      5.7.24-0ubuntu0.18.04.1    ...]]></description><category></category></item><item><title><![CDATA[NIO和Netty系列(三): 堆外内存与零拷贝详解]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/85481005</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/85481005</guid><author>zkp_java</author><pubDate>Mon, 31 Dec 2018 19:22:30 +0800</pubDate><description><![CDATA[在之前的文章中我们了解到NIO中堆外内存的实现类是java.nio.DirectByteBuffer和java.nio.MappedByteBuffer。本文中我们也通过这两个类来分析NIO中堆外内存的实现。
如何从Java code获取堆外内存
我们都知道Java code是运行在JVM进程所管理的内存上的，而堆外内存是JVM进程所管控的内存之外的，那么如何从Java代码中获取对外内存呢？在Ja...]]></description><category></category></item><item><title><![CDATA[[NIO和Netty] NIO和Netty系列(二): Java Reference详解]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/85241026</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/85241026</guid><author>zkp_java</author><pubDate>Tue, 25 Dec 2018 00:14:08 +0800</pubDate><description><![CDATA[在分析DirectByteBuffer源码时发现使用到了java.lang.ref.Cleaner类，该类就是一个Reference，因此这里对Java中的Reference做个小结。
Reference系列的类定义在java.lang.ref包下：


...]]></description><category></category></item><item><title><![CDATA[[NIO和Netty] NIO和Netty系列(一): NIO中selector、channel和buffer]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/85057769</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/85057769</guid><author>zkp_java</author><pubDate>Mon, 17 Dec 2018 22:17:09 +0800</pubDate><description><![CDATA[最近看zookeeper源码，发现底层的通信使用到了NIO和netty，接下来的系列记录下NIO和Netty的学习，记录完接着zookeeper源码的学习。
NIO概述
java.io中最为核心的概念是流(stream)，是面向流的编程，一个流要么是输入流，要么是输出流，不可能同时即是输入流又是输出流；而java.nio是面向块(block)或面向缓冲区(buffer)编程，块或者缓冲区既可以作为...]]></description><category></category></item><item><title><![CDATA[[zookeeper]zookeeper系列八：zookeeper Leader选举源码分析]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/84930751</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/84930751</guid><author>zkp_java</author><pubDate>Sun, 09 Dec 2018 19:12:27 +0800</pubDate><description><![CDATA[Zookeeper启动的main方法是org.apache.zookeeper.server.quorum.QuorumPeerMain类的main方法：
public static void main(String[] args) {
        QuorumPeerMain main = new QuorumPeerMain();
        try {
            mai...]]></description><category></category></item><item><title><![CDATA[[zookeeper]zookeeper系列七：zookeeper选举及数据一致性]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/84521234</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/84521234</guid><author>zkp_java</author><pubDate>Mon, 26 Nov 2018 08:52:44 +0800</pubDate><description><![CDATA[ZAB协议
ZAB(Zookeeper Atomic Broadcast)协议，即Zookeeper原子消息广播协议，协议内容大致如下：

所有事物的请求必须由全局唯一的服务器来协调处理，这样的服务器被称为Leader服务器，而余下的其他服务器则称为Follower服务器，Leader服务器负责将一个客户端的事物请求转换成一个事物Proposal(提议)，并将该Proposal分发给集群中的所有F...]]></description><category></category></item><item><title><![CDATA[[zookeeper]zookeeper系列六：zookeeper开源客户端curator]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/84454752</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/84454752</guid><author>zkp_java</author><pubDate>Sat, 24 Nov 2018 22:52:45 +0800</pubDate><description><![CDATA[zookeeper原生api的不足
zookeeper原生api存在以下不足之处：

连接的创建是异步的，需要开发人员自行编码实现等待；
连接没有自动的超时重连机制；
Zk本身不提供序列化机制，需要开发人员自行指定，从而实现数据的序列化和反序列化；
Watcher注册一次只会生效一次，需要不断的重复注册；
Watcher本身的使用方式不符合java本身的术语，如果采用监听器的方式，更容易理解；
不...]]></description><category></category></item><item><title><![CDATA[[zookeeper]zookeeper系列五：zookeeper自带客户端原生api的使用]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/82751232</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/82751232</guid><author>zkp_java</author><pubDate>Tue, 18 Sep 2018 00:51:57 +0800</pubDate><description><![CDATA[引入依赖
zookeeper中自带一个客户端，只需要引入zookeeper，在build.gradle中添加以下依赖即可：
compile ('org.apache.zookeeper:zookeeper:3.4.13')

创建zookeeper会话
org.apache.zookeeper.ZooKeeper类的构造方法用于创建zookeeper客户端与服务端之间的会话。该类提供了如下几个构造...]]></description><category></category></item><item><title><![CDATA[[zookeeper]zookeeper系列四：分布式系统的理解]]></title><link>https://blog.youkuaiyun.com/zkp_java/article/details/82751134</link><guid>https://blog.youkuaiyun.com/zkp_java/article/details/82751134</guid><author>zkp_java</author><pubDate>Tue, 18 Sep 2018 00:25:37 +0800</pubDate><description><![CDATA[分布式系统集群的特点

集群中所有节点维护的数据要一致
所有节点都可以提供相同的业务功能(不一定是在同一时刻提供)
集群需要保障系统的高可用，某个节点宕机不会影响服务

集群环境下如何保障数据一致性
集群环境下有两张方式可以保障数据一致性：数据复制和集中存储。


数据复制：先向单节点写入，再复制到其他节点，zookeeper就是这样实现的；或者多节点同时写入，但只适合多节点写入的数据不是相同数据...]]></description><category></category></item></channel></rss>