基于ThreadLocal的无锁并发发号器实现 ThreadLocal是一个线程级别的变量副本,它是对于线程隔离的,各个线程之间不能访问非自己的ThreadLocal变量。我们先来分析一下一个优秀的ID应该具备哪些特点?全局唯一性有序性能够包含一些信息(比如说时间信息、生成机器信息等)为了保证ID的全局唯一,在生成的时候我们应该对其做一些并发安全的处理,不然很可能就会出现重复ID,比如说ID的序列号是递增的,那么如何去保证在多线程...
.equals()、.hashcode()和==之间的联系与差异 在说这个问题之前,我先说一下几个概念内存地址:存放对象的物理地址hashcode: hashcode是jdk为对象生成的一个int类型的数,并且保证在同一个jvm中,对于同一个对象每次返回的都是同一个hashcode(具体生成方式请看hashcode详解)hash冲突:hashcode发生重复我们先看看在Object中是怎样定义.equals()和.hashcode()的publi...
HashCode详解 HashCode详解起初的时候我一直认为hashcode是内存地址的一个映射,但是今天仔细研究了一下hashcode,以往的认识就这样无情的被颠覆了。起初我把对象的内存地址和hashcode一起输出,由于java是不建议用户之间操作内存的,所以一般情况下是不能够拿到对象的内存地址,但是Java留了一个后门:Unsafe,通过Unsafe类我们可以访问到对象的内存地址public class ...
kafka消息的批量发送 生产者发送多个消息到同一个分区的时候,为了减少网络带来的系能开销,kafka会对消息进行批量发送batch.size 通过这个参数来设置批量提交的数据大小,默认是16k,当积压的消息达到这个值的时候就会统一发送(发往同一分区的消息) linger.ms 这个设置是为发送设置一定是延迟来收集更多的消息,默认大小是0ms(就是有消息就立即发送)当这两个参数同时设置的时候,只要两个条件中满...
kafka的副本机制 partition的副本被称为replica,每个分区可以有多个副本,并且在副本集中会存在一个leader副本,所有的读写请求都会通过leader完成,follower复制只负责备份数据。副本会均匀分配到多台broker上,当leader节点挂掉之后,会从副本集中重新选出一个副本作为leader继续提供服务副本分配算法:n个broker 将第i个partition的第j个副本分配...
kafka的消息存储 消息的保存路径:默认情况下是保存在 /temp/kafka-log中存储方式使用日志文件+索引的方式消息写入使用了顺序写入和零拷贝来提升写入性能,consumer和producer都是使用的二进制数据,避免了格式的转化日志的分片当日志文件过大的时候,会严重影响性能,于是当日志文件达到一定的大小的时候会对日志文件进行分片,这个大小默认是1GB,可以通过 long.seg...
kafka的offset offset是什么?每一条消息在进入partition的时候都会为其分配一个编号,这个编号被称为offset,offset是一个64位long类型的,是递增的,在partition中,offset是唯一存在的,kafka能够保证在同一个partition中消息是有序的offset维护在哪里?kafka提供了一个__consumer_offsets的一个Topic,offset信息会写入...
kafka的分区分配策略 分区在集群中的分配策略将所有broker(n个)和partition排序将第i个Partition分配到第(i mode n)个broker上Producer如何把消息发送给对应分区当key为空时,消息随机发送到各个分区(各个版本会有不同,有的是采用轮询的方式,有的是随机,有的是一定时间内只发送给固定partition,隔一段时间后随机换一个)用key的ha’sh值对pa...
Topic和Partition Topic是一个逻辑上的概念,可以看成是一类消息的聚合。从物理上来说,一个Topic是由分散在各个服务节点上的Partition组成的,每个Topic可以有多个Producer向他发送消息,也可以有多个Consumer消费其中的消息。如图所示,一个Topic是由分散在多台broker上的Pratition组成的,多台Produer按照一定的算法把消息发送给各个Partition上,cons...
vue .sysc 初学vue,今天看代码的时候看见了.sysc,刚刚开始有点不理解这是干什么的,后来查阅了下资料,发现sysc能够实现子组件给父组件传值,非常简单,在复用组件的时候非常好用,下面我用一个demo来说明.sysc的用法定义一个组件<template> <div> <input type="text" v-model="
什么是面向对象? 什么是面向对象?你真的理解了吗?可能大家听过很多关于面向对象的描述,各种各样的,很抽象很难以理解,面向对象其实并不复杂,每一个人的面向对象都是不同的。我先来说说我对面向过程以及面向对象的理解:面向过程:关注点在于做了什么,描述的是发展的过程面向对象:关注点在于能做什么,描述的是对象与对象之间的关系。那么什么对象到底是什么呢?下面我来举一个简单的例子:小明要去吃饭,把这句话用代...
JDK1.8接口的默认实现 很多时候,别人问我接口和类的区别的时候,我都会回答接口里面只能有抽象方法,而不能够有具体方法,但是今天看Mybatis源码的时候,发现了有一段代码是判断接口里面的默认方法的,于是我发现原来对接口的认识太过于肤浅了。JDK1.8之后,在接口里面可以定义default方法,default方法里面是可以具备方法体的,当子类实现该接口之后,不需要重写该方法即可以调用该方法。ok,看看代码/...
Mapped Statements collection does not contain value for XXXX 今天用Mybatis踩到一个比较有意思的坑,找了一天没发现问题在哪儿,我先给大家说说常规的解决方案。mybatis的映射文件的命令空间与接口的全限定名不一致;有可能mybatis的映射文件名字与接口的类名字不一致;还有一种情况就是接口声明的方法在映射文件里面没有。但是我检查了n遍!n遍!没有一点问题,相当完美,可是就是报错!结果是因为xml文件没有编译!编译的时候,放xml...
线程安全的登记式单例 有的时候,我们不希望在一开始的时候就把一个类写成单例模式,但是在运用的时候,我们却可以像单例一样使用他最典型的例子就是spring,他的默认类型就是单例,spring是如何做到把不是单例的类变成单例呢?这就用到了登记式单例其实登记式单例并没有去改变类,他所做的就是起到一个登记的作用,如果没有登记,他就给你登记,并把生成的实例保存起来,下次你要用的时候直接给你。IOC容器就是做的这个...
代理模式 代理模式是一个非常常见的模式,他有非常多的变种。比如说远程代理,他可以让操作远程对象像操作本地对象一样的容易还有虚拟代理,他主要是代理一些加载特别缓慢的对象,先展示给用户的是一个代理对象,然后异步加载真正的对象,来提高系统的响应速度代理模式的变种是在是太多了,今天我主要给大家介绍的是保护代理,我分别用静态代理和动态代理两种方式去实现保护代理我们都知道,对于系统的升级最好要对原先的代...
状态模式 有时候,我们会遇见一些场景,里面有非常多的状态变化,各个状态下又有不同的行为,在这种情况下,如果用if-else去写程序的话,会让代码的可读性非常差,编写会非常容易出错,也不容易维护和拓展。在这种情况下,我们就要用到状态模式。我们拿女孩多变的心情来举例吧,下面看看状态的变化图 假设女孩的心情在这四种之间自由转化(天知道有几种- -),如果我们用if-else去做,估计复杂的关系会把人逼疯...
模板模式 模板模式的核心是定义一个算法的骨架,把一些可能变化的实现延迟到子类中去。工厂方法可以看成是一种特殊的模板模式。模板模式还与策略模式有点相似,但是他们的侧重点不同,模板模式的侧重点是规定算法模板,让别人按照他的意图去做事,策略模式的侧重点是定义一系列的方法簇,让使用者自己去选择。他们一个占据着主导权,一个交出了主导权下面我们通过一个榨汁机的例子来看看模板模式是如何实现的public ab...
外观模式 外观模式的核心是把复杂的调用关系封装起来,提供简单的接口我们拿电脑举例,电脑的启动是复杂的,要启动CPU,显示器,风扇等等,假如没有外观模式,需要我们手动的去启动各个组件,这实在是太可怕了。当我们用了外观模式,把这些操作全部封装在一个方法里面,那么我们启动电脑就轻松愉快了,下面我们来看看代码public class AirFan { public void AirFanSt...
适配器模式 我们经常会遇到这样的场景:别人提供的接口和我们需要的接口不兼容的情况,这个时候我们就需要用到适配器了,把别人的接口转化成我们需要的接口。我们看看是如何做到的先看看类图: 我们有三孔和两孔两种接口,三孔适配器的作用是把三孔适配为两孔,我们来看看代码public interface ThreeHole { void provideThreeHole();}publ...