![](https://img-blog.csdnimg.cn/20201014180756754.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
源码
一只积累鸭
这个作者很懒,什么都没留下…
展开
-
InitializingBean的使用方法、原理及实例增加时的同步问题
目录标题1、InitializingBean的使用方法2、InitializingBean的原理3、实例增加时的同步问题1、InitializingBean的使用方法InitializingBean接口定义了bean初始化的方式,它只包括afterPropertiesSet方法,如果一个类实现了InitializingBean 接口,则可以在初始化类的时候进行一些工作。下面的代码在初始化ActivityController的时候完成了写入redis的工作。public class ActivityCo原创 2020-12-31 17:00:53 · 607 阅读 · 0 评论 -
【leveldb源码】“读”流程及实现
文章目录step0. 加互斥锁,ReentrantLockstep1. 写logstep2. 更新memtablestep3. 根据option中的选项决定是否产生快照step4. 释放锁step0. 加互斥锁,ReentrantLockstep1. 写log实现批量写操作的接口如下,因为一条log的格式如上,因此在put方法里,除了k-v的长度,还需要3个int (type+key length+value length),也就是12位byte的长度,delete因为不需要添加value信息,因此原创 2020-11-29 22:21:58 · 362 阅读 · 0 评论 -
【leveldb源码】“写”流程及实现
文章目录step0. 加锁,ReentrantLockstep1. 写logstep2. 更新memtablestep3. 根据option中的选项决定是否产生快照step4. 释放锁step0. 加锁,ReentrantLockstep1. 写log实现批量写操作的接口如下,因为一条log的格式如上,因此在put方法里,除了k-v的长度,还需要3个int (type+key length+value length),也就是12位byte的长度,delete因为不需要添加value信息,因此需要k的原创 2020-11-29 21:35:31 · 315 阅读 · 0 评论 -
【源码系列】LinkedBlockingQueue源码分析
目录亮点数据结构入队方法1. put(E e)2. offer(E e)出队方法1. E take()2. E poll()LOCK的原理及使用已经在本文中进行了描述,感兴趣的同志请移步。在实现一个简单的ORM框架的时候,使用LinkedBlockingQueue来实现连接池的功能,这里分析下LinkedBlockingQueue的原理,以便记忆,顺便传播,哈哈哈亮点LinkedBlockingQueue实现的队列中的锁是分离的,其添加采用的是putLock,移除采用的则是takeLock,原创 2020-11-29 14:37:56 · 139 阅读 · 0 评论 -
【源码系列】Lock和AQS
在分析LinkedBlockingQueue源码的时候,里面用到了ReentrantLock,所以本篇我们分析下ReentrantLock的原理。目录一、Lock方法介绍二、实现Lock的类介绍(ReentrantLock、ReentrantReadWriteLock)1. ReentrantLock使用举例2. AbstractQueuedSynchronizer原理分析a). AbstractQueuedSynchronizer实现独占锁和共享锁b). 内部维护的是一个FIFO的双向链表3. Re.原创 2020-11-29 14:20:19 · 251 阅读 · 0 评论 -
AtomicInteger源码
题外话,在leveldb的实现中遇到了AtomicInteger,这里我们来好好学习下他的源码同步和互斥首先明确多线程的同步和互斥的概念:同步指在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。如果用对资源的访问来定义的话,同步是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。互斥.原创 2020-11-23 17:51:34 · 145 阅读 · 0 评论 -
【源码学习】GatheringByteChannel的write方法
镜像接口ScatteringByteChannelScatteringByteChannel的方法名是read,Scattering的意思是分散,把通道(Channel)的数据分散写入buffer中;GatheringByteChannel的方法名是write,Gathering的意思是聚集,把分散在buffer的数据读出来集中写到通道(Channel)中。这里的方法名很有意思,写行为的方法名是读,读行为的方法名是写,实际上,这里的read和write并不是针对最后的结果,而是针对Channel,原创 2020-10-11 16:14:37 · 370 阅读 · 0 评论 -
【MyBatis源码-1】JDBC
Connection是JDBC对数据连接的抽象,可以通过 DriverManager和DataSource获得Connection对象。Statement接口可以理解为JDBC API中提供的SQL语句执行器,定义了执行SQL语句的方法。通过Statement接口提供的getResultset()来获取查询结果集、通过getUpdateCount()获取更新操作影响的行数。PooledConnection表示与数据库建立的物理连接,当应用程序调用DataSource的getConnection()时.原创 2020-11-29 00:53:06 · 164 阅读 · 0 评论 -
ArrayListMultimap源码
总算明白了美悦苦心积虑让我看guava的良苦用心,真是太香了啊!!综述我们都知道,ArrayListMultimap的key允许重复,value可以append,类似于下面这样private final Multimap<Integer, String> newFiles = ArrayListMultimap.create();newFiles.put(1, "science");newFiles.put(1, "nature");newFiles.put(1, "nature.原创 2020-11-28 00:26:46 · 203 阅读 · 1 评论 -
MapMaker原理
今天做项目,碰到了使用MapMaker的场景,最近用了好多guava的东西,好多都是用作缓存的,真香啊!MapMaker其实是ConcurrentMap的实例,不过他还合并了很多特性,主要的特性有:key和value被自动包装成软引用或弱引用可以创建监听,可以在Entry被移除或者删除之前,对Entry做一些处理用来构造ConcurrentHashMap:得到线程安全的hashMap@Override public <K, V> ConcurrentMap<K.原创 2020-11-27 22:39:57 · 1439 阅读 · 1 评论 -
【leveldb源码】核心功能之LogReader
LogReader用于从文件中读出一个完整的log,并返回其中的data内容。一、一个log record的格式如下:| crc32 | length | log type | data |其中,crc32占4 byte,length占2byte,type占1byte,这三个作为log头,共占据7byte二、log record在文件中存储的格式如下:log在文件中的存储格式如下,我们从文件读的时候是一个block,一个block读出来的。可能多个log record构成了一个完整的log。原创 2020-11-25 15:49:54 · 620 阅读 · 0 评论 -
【leveldb源码】LogType
LogType作为log record的一部分,用于说明log record是完整的在一个block当中,还是分开在不同的block中。LogType有4种可取的值:FULL = 1、FIRST = 2、MIDDLE = 3、LAST = 4。FULL,说明该log record包含一个完整的user recordFIRST,说明是user record的第一条log recordMIDDLE,说明是user record中间的log recordLAST,说明是user record最后的一条原创 2020-11-24 20:17:32 · 478 阅读 · 0 评论 -
【leveldb源码】核心结构之SequenceNumber
SequenceNumbers是所有基于op log系统的关键数据,它唯一指定了不同操作的时间顺序,该类实现了利用7 byte的SequenceNumbers和1byte的valuetype构建完整的long,也实现了从long中拆出SequenceNumbers和valuetype的功能public final class SequenceNumber{ // SequenceNumber是Key的一部分,占 7 byte,ValueType占1byte,组合之后就是long // (原创 2020-11-23 15:09:41 · 678 阅读 · 0 评论 -
【leveldb源码】核心结构之InternalKey
InternalKey介绍InternalKey是由User key + SequenceNumber + ValueType组合而成的InternalKey的格式为:| User key (string) | sequence number (7 bytes) | value type (1 byte) |sequence number大小是7 bytes,sequence number是所有基于op log系统的关键数据,它唯一指定了不同操作的时间顺序。把user key放到前面的原因是,这原创 2020-11-23 14:54:28 · 492 阅读 · 0 评论 -
ArrayDeque原理
Deque 接口继承自 Queue接口,Queue 也是 Java 集合框架中定义的一种接口,直接继承自 Collection 接口。Deque 支持同时从两端添加或移除元素,因此又被成为双端队列。Deque 和 Queue 方法的的对应关系如下:Queue MethodDeque Methodadd(e)addLast(e)offer(e)offerLast(e)remove()removeFirst()poll()pollFirst()elemen原创 2020-11-18 21:12:51 · 216 阅读 · 0 评论 -
【leveldb源码】核心结构之BlockIterator
直接上代码,解释及逻辑都在注释里在 public void seek(Slice targetKey)函数中有一块非常精华的部分,因为有重启点的位置信息,且存储点是有序的,可以二分查找重启点,直到找到小于targetKey的最大key,在该重启点及后面的压缩key区域线性查找对应的key。源码这个二分思想太漂亮了!!int left = 0; int right = restartCount - 1; // 二分查找重启点和targetKey,直到找到大于targetke原创 2020-11-07 15:42:43 · 138 阅读 · 0 评论 -
【leveldb源码】核心结构之Block
深入理解Block下图是Block的图形化表示,从淡粉色到淡绿色是一个完整的k-v结构,各个色块代表什么在最下面进行了说明,注意的是Block中的key是有序存储的,每隔interval个k-v,就会有一个重启点(图中黑色边框的k-v),重启点的前缀不压缩。因为key是有序存储的,所以计算该key和前面一个key的公共最长前缀的长度,可以最大化的压缩key。因为Block的底层数据结构是Slice,Slice的底层数据结构是byte[],所以这里长度的统一单位是byte[]。说一些画图的题外原创 2020-11-07 14:58:21 · 322 阅读 · 2 评论 -
【leveldb源码】核心结构之BlockBuilder
BlockBuilder创建的核心步骤和代码回顾Block的结构成员变量成员函数构造函数重设内容,通常在Finish之后调用,来构建新的block返回正在构建block的未压缩大小(估计值)添加key-value计算公共前缀长度结束构建block,并返回指向block内容的指针BlockBuilder是用于创建Block的。回顾Block的结构block分为k/v存储区和后面的重启点存储区两部分,对于一个k/v对,其在block中的存储格式为:共享前缀长度 shared_bytes原创 2020-11-04 20:02:56 · 547 阅读 · 0 评论 -
long、int转为byte[]
很多数据类型的基本数据结构都是byte[],如何快速初始化byte[]的length位为0。1、 一位一位的赋值byte[] data = new byte[10000];for (int i = 0; i < length; i++){ data[i] = (byte)0;}2、转换为long的方式赋值现在要解决的问题是给length位byte赋值为0,我们可以拆分一个函数,就是把long写入byte[]中,代码如下,该函数每被调用一次,就解决了8个长度的赋值问题,这个函数不光可以解原创 2020-10-22 16:51:49 · 2562 阅读 · 5 评论 -
【源码学习】Java字符的编码和解码
java中与编码解码相关的类都在包java.nio.charset中,主要有Charset、CharsetDecoder、CharsetEncoder、CoderResult这几个类Charset:字符集CoderResult:状态集CharsetDecoder:编码器CharsetEncoder:解码器一、可通过Charset获得编码器(encoder)或解码器(decoder)```javaCharsetEncoder encoder = charset.newEncoder();C原创 2020-10-21 00:01:17 · 807 阅读 · 5 评论 -
【源码学习】ThreadLocal
大概介绍ThreadLocal通俗说法:线程的本地变量,通过为每个线程创建副本的方式解决线程隔离问题,实现线程中的变量传递比如:一个老项目,要从单线程的改为多线程实现了,那么对于一些变量,不是线程共享的,就要用ThreadLocal包装起来每个线程对应一个请求连接,在这个线程中的多个类、方法都要用到这个请求的用户信息,可见这个信息不是在线程间共享的,那么用ThreadLocal把用户信息包装起来ThreadLocalMapThreadLocalMap是ThreadLocal的一个内部静态类原创 2020-10-12 23:50:47 · 849 阅读 · 10 评论 -
【源码学习】ScatteringByteChannel的read方法
ScatteringByteChannel在java.nio.channels包中,继承了AutoCloseable, Channel,Closeable, ReadableByteChannel接口所有的实现类为:DatagramChannel, FileChannel, Pipe.SourceChannel, SocketChannelScatteringByteChannel是一个通道,可以将Channel中的数据写入Buffer数组中,在网络协议或者文件读写中非常有用。比如把数据按照seg.原创 2020-10-09 19:17:45 · 984 阅读 · 6 评论 -
HashMap的线程不安全是在说什么
Java程序员都曾被问到的一个问题是:为什么HashMap是线程不安全的?为什么ConcurrentHashMap是线程安全的?为什么HashMap是线程不安全的?Fail-Fast 机制如果在使用迭代器的过程中有其他线程修改了map,那么将抛出ConcurrentModificationException,这就是所谓fail-fast策略。看源码的时候我们会看到,在ArrayList,LinkedList,HashMap的内部,有一个int类型的modCount对象,对上述集合内容的修改原创 2020-09-25 13:02:21 · 1174 阅读 · 2 评论 -
【源码学习】之ConcurrentSkipListMap
ConcurrentSkipListMap的原理如下:在跳表中,基本的数据结构变为HeadIndex,有right、down两个指针,有node属性,node属性中记录的是节点的信息并指向下一个节点。通过volatile实现了并发操作。这里,附带介绍一下volatile的原理和实际使用场景static final class Node<K,V> { final K key; volatile Object value; volatile Node<K,V> next;}原创 2020-09-24 18:50:17 · 295 阅读 · 2 评论 -
【源码学习】之LinkedHashMap
这篇讲LinkedHashMap很不错LinkedHashMap之前,先说一点HashMap的原理,参考了这篇博文这是HashMap写数据的原理,为了减少冲突,hash算法是通过key的hashcode值与其hashcode右移16位后得到的值进行异或运算得到的。LinkedHashMap可以说是HashMap和LinkedList的集合体,既使用了HashMap的数据结构,又借用了LinkedList双向链表的结构,基本数据类型还是Entry静态内部类。其结构如下,before、after指向保证顺原创 2020-09-24 10:32:00 · 139 阅读 · 0 评论 -
【源码学习】之TreeMap
TreeMapd的底层实现是二叉查找树,左旋:逆时针旋转两个节点,让一个节点被其右子节点取代,而该节点成为右子节点的左子节点右旋:顺时针旋转两个节点,让一个节点被其左子节点取代,而该节点成为左子节点的右子节点TreeMap的节点数据结构,可以找到自己的父亲和左右孩子,TreeMap的成员变量modCount记录了TreeMap的调整次数。// 红黑树结构的调整次数private transient int modCount = 0;Entry<K,V> implements Map.原创 2020-09-24 10:25:52 · 109 阅读 · 0 评论 -
【leveldb源码】核心结构之memtable
这里写自定义目录标题欢迎使用Markdown编辑器欢迎使用Markdown编辑器leveldb的核心结构是MemTable,MemTable中存储的key是有序的为了解决key有序的问题,我们需要解决摸底一遍java的有序集合,在此之前,我们首先需要摸底一遍java的集合。这里为了不用画图,引用本篇博客中的图图,实线边框的是实现类,折线边框的是抽象类,而点线边框的是接口。Collection接口是集合类的跟接口,set和list继承了Collection接口,map和Collection接口没有关原创 2020-09-21 17:25:15 · 281 阅读 · 1 评论 -
【leveldb源码】数据结构之crc校验
源码中写在util文件夹下,crc校验主要问了校验SSTable中block内容的完整性,头文件crc32c.h中定义了mask、unmask、value三个方法,mask方法源码中的解释是 it is problematic to compute the CRC of a string that contains embedded CRCs. Therefore we recommend that CRCs stored somewhere (e.g., in files) should be mask原创 2020-09-19 18:07:27 · 547 阅读 · 1 评论 -
【leveldb源码】数据结构之Status
内部定义枚举类,对状态进行描述在源码中,对于状态函数的msg2都赋值了默认参数,如下所示。java中因为默认参数和方法重载同时出现的时候有二义性的问题,而且java本身就减少了很多特性,所以,我们此处通过重载来解决默认参数的问题。啊,翻译c++对我有难度,我的c++还给了老师,我对不起高老师,老师一定不希望我曝光他的名字,哭泣了 // Return error status of an appropriate type. static Status NotFound(const Slic.原创 2020-09-16 16:57:43 · 1559 阅读 · 4 评论 -
【leveldb源码】数据结构之Slice
leveldb的数据结构slice#ifndef STORAGE_LEVELDB_INCLUDE_SLICE_H_#define STORAGE_LEVELDB_INCLUDE_SLICE_H_原创 2020-09-14 18:14:53 · 519 阅读 · 1 评论 -
【源码系列-6】quartz源码学习
quartz分布式任务管理可以分布式的部署多个节点,quartz调度不同的节点做不同的事情配置job方式quartz支持两种方式配置job,MethodInvokingJobDetailFactoryBean和JobDetailFactoryBean,其中JobDetailFactoryBean可以通过datamap传递参数。配置触发器方式触发器通过两种方式配置,SimpleTriggerFactoryBean和CronTriggerFactoryBean,后者通过cron表达式配置出发逻辑分布原创 2020-06-10 16:47:15 · 255 阅读 · 0 评论 -
【源码-6】JDK二分查找
长叹一句啊!自古真情留不住,总是套路的人心啊,我什么时候才能成为套路王啊!!心碎????成为套路王第一步之找到组织github大牛hub主(labuladong先生)手写的生动形象的套路,OMG,Star他!!!成为套路王第二步之看JDK源码现在的我已经掌握了初步的套路,已经学会了怎么写二分查找,但是每次手撸也挺没意思的,调用Arrays.binarySearch也很香,但是得知道Arrays.binarySearch的原理,下面上价(yuan)值(li)private static int原创 2020-05-16 17:13:14 · 268 阅读 · 0 评论 -
【源码-6】redis的数据结构及编码
涉及到大佬文章的链接在此https://blog.csdn.net/csdnlijingran/article/details/89116126https://www.jianshu.com/p/c2841d65df4credis是一个kye value存储的内存数据库,key永远为string,value可能是redis对象中的任意一种。redis可以保存的数据类型为String、L...原创 2020-04-29 16:06:15 · 162 阅读 · 0 评论 -
【源码-5】rehash
rehash是为了迁移redis的数据,redis在内存中是类似于java的hashmap形式存储的,相当于一个链表数组,数据是存放在dict里面的,也就是下面rehash的入口参数,dict里面存放两张hash表,rehash就是实现数据在这两张表之间进行迁移的。rehash的源码在此,入口参数为dict和intdictIsRehashing返回1代表仍然有key需要从老表迁移到新表,0代表...原创 2020-04-29 15:58:49 · 262 阅读 · 0 评论 -
【源码系列-4】【fastdfs系列-1】初始化客户端
fastdfs系列——初始化客户端事前声明解析配置文件、创建tracker group获取tracker事前声明本文使用的是100只(Mr / Miss)快乐鱼的开源代码,附上源码链接:https://github.com/happyfish100/从一个测试用例入手分析若想对fastdfs中的文件进行操作,分为下面几步:解析配置文件根据配置文件中的数据生成tracker serv...原创 2020-03-12 22:02:46 · 813 阅读 · 0 评论 -
【JAVA基础查漏补缺】对,就是查漏补缺
实例变量:变量声明在类中;局部变量:变量声明在方法中;实例变量都有默认值,boolean的默认值是false;局部变量没有默认值,在初始化之前使用会报错;...原创 2020-02-27 10:10:34 · 426 阅读 · 0 评论 -
【源码系列-2】PriorityQueue
PriorityQueue,我用过的场景是用来构建大小堆。PriorityQueue的排序是在创建时就制定的Comparable或Comparator。PriorityQueue不允许添加null元素。如果队列中插入Comparable或Comparator无法比较的元素时,会抛出ClassCastException异常。队列头是队列的最后一个元素。如果最后一个值有多个元素的话,队列头是任...原创 2020-02-19 16:26:41 · 180 阅读 · 0 评论 -
【源码系列-1】Serializable
序列化:序列化是指把对象转换为字节序列的过程,我们称之为对象的序列化,就是把内存中的这些对象变成一连串的字节(bytes)描述的过程。反序列化:就是把持久化的字节文件数据恢复为对象的过程。那么什么情况下需要序列化呢?大概有这样两类比较常见的场景:1)、需要把内存中的对象状态数据保存到一个文件或者数据库中的时候,这个场景是比较常见的,例如我们利用mybatis框架编写持久层insert...原创 2020-02-18 11:46:55 · 171 阅读 · 0 评论