自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

Crazy.Mark

记录自己的学习,见证自己的进步

  • 博客(43)
  • 收藏
  • 关注

原创 能自适应令牌生成速率的令牌桶实现

为了

2019-06-28 16:47:35 1031 1

原创 基于ThreadLocal的无锁并发发号器实现

ThreadLocal是一个线程级别的变量副本,它是对于线程隔离的,各个线程之间不能访问非自己的ThreadLocal变量。我们先来分析一下一个优秀的ID应该具备哪些特点?全局唯一性有序性能够包含一些信息(比如说时间信息、生成机器信息等)为了保证ID的全局唯一,在生成的时候我们应该对其做一些并发安全的处理,不然很可能就会出现重复ID,比如说ID的序列号是递增的,那么如何去保证在多线程...

2018-09-29 10:04:32 435 2

原创 .equals()、.hashcode()和==之间的联系与差异

在说这个问题之前,我先说一下几个概念内存地址:存放对象的物理地址hashcode: hashcode是jdk为对象生成的一个int类型的数,并且保证在同一个jvm中,对于同一个对象每次返回的都是同一个hashcode(具体生成方式请看hashcode详解)hash冲突:hashcode发生重复我们先看看在Object中是怎样定义.equals()和.hashcode()的publi...

2018-09-28 14:34:26 983

原创 HashCode详解

HashCode详解起初的时候我一直认为hashcode是内存地址的一个映射,但是今天仔细研究了一下hashcode,以往的认识就这样无情的被颠覆了。起初我把对象的内存地址和hashcode一起输出,由于java是不建议用户之间操作内存的,所以一般情况下是不能够拿到对象的内存地址,但是Java留了一个后门:Unsafe,通过Unsafe类我们可以访问到对象的内存地址public class ...

2018-09-27 17:51:09 4451 10

原创 kafka消息的批量发送

生产者发送多个消息到同一个分区的时候,为了减少网络带来的系能开销,kafka会对消息进行批量发送batch.size 通过这个参数来设置批量提交的数据大小,默认是16k,当积压的消息达到这个值的时候就会统一发送(发往同一分区的消息) linger.ms 这个设置是为发送设置一定是延迟来收集更多的消息,默认大小是0ms(就是有消息就立即发送)当这两个参数同时设置的时候,只要两个条件中满...

2018-09-14 09:31:33 29615 3

原创 kafka的副本机制

partition的副本被称为replica,每个分区可以有多个副本,并且在副本集中会存在一个leader副本,所有的读写请求都会通过leader完成,follower复制只负责备份数据。副本会均匀分配到多台broker上,当leader节点挂掉之后,会从副本集中重新选出一个副本作为leader继续提供服务副本分配算法:n个broker 将第i个partition的第j个副本分配...

2018-09-14 09:29:54 9101 2

原创 kafka的消息存储

消息的保存路径:默认情况下是保存在 /temp/kafka-log中存储方式使用日志文件+索引的方式消息写入使用了顺序写入和零拷贝来提升写入性能,consumer和producer都是使用的二进制数据,避免了格式的转化日志的分片当日志文件过大的时候,会严重影响性能,于是当日志文件达到一定的大小的时候会对日志文件进行分片,这个大小默认是1GB,可以通过 long.seg...

2018-09-14 09:24:50 3413 2

原创 kafka的offset

offset是什么?每一条消息在进入partition的时候都会为其分配一个编号,这个编号被称为offset,offset是一个64位long类型的,是递增的,在partition中,offset是唯一存在的,kafka能够保证在同一个partition中消息是有序的offset维护在哪里?kafka提供了一个__consumer_offsets的一个Topic,offset信息会写入...

2018-09-14 09:20:43 1043

原创 kafka的分区分配策略

分区在集群中的分配策略将所有broker(n个)和partition排序将第i个Partition分配到第(i mode n)个broker上Producer如何把消息发送给对应分区当key为空时,消息随机发送到各个分区(各个版本会有不同,有的是采用轮询的方式,有的是随机,有的是一定时间内只发送给固定partition,隔一段时间后随机换一个)用key的ha’sh值对pa...

2018-09-14 09:15:38 21588 5

原创 Topic和Partition

Topic是一个逻辑上的概念,可以看成是一类消息的聚合。从物理上来说,一个Topic是由分散在各个服务节点上的Partition组成的,每个Topic可以有多个Producer向他发送消息,也可以有多个Consumer消费其中的消息。如图所示,一个Topic是由分散在多台broker上的Pratition组成的,多台Produer按照一定的算法把消息发送给各个Partition上,cons...

2018-09-14 08:59:11 3019

原创 vue .sysc

初学vue,今天看代码的时候看见了.sysc,刚刚开始有点不理解这是干什么的,后来查阅了下资料,发现sysc能够实现子组件给父组件传值,非常简单,在复用组件的时候非常好用,下面我用一个demo来说明.sysc的用法定义一个组件<template> <div> <input type="text" v-model="

2018-08-13 16:25:18 301

原创 什么是面向对象?

什么是面向对象?你真的理解了吗?可能大家听过很多关于面向对象的描述,各种各样的,很抽象很难以理解,面向对象其实并不复杂,每一个人的面向对象都是不同的。我先来说说我对面向过程以及面向对象的理解:面向过程:关注点在于做了什么,描述的是发展的过程面向对象:关注点在于能做什么,描述的是对象与对象之间的关系。那么什么对象到底是什么呢?下面我来举一个简单的例子:小明要去吃饭,把这句话用代...

2018-04-03 11:32:35 2215

原创 JDK1.8接口的默认实现

很多时候,别人问我接口和类的区别的时候,我都会回答接口里面只能有抽象方法,而不能够有具体方法,但是今天看Mybatis源码的时候,发现了有一段代码是判断接口里面的默认方法的,于是我发现原来对接口的认识太过于肤浅了。JDK1.8之后,在接口里面可以定义default方法,default方法里面是可以具备方法体的,当子类实现该接口之后,不需要重写该方法即可以调用该方法。ok,看看代码/...

2018-03-31 16:47:20 12031 4

原创 Mapped Statements collection does not contain value for XXXX

今天用Mybatis踩到一个比较有意思的坑,找了一天没发现问题在哪儿,我先给大家说说常规的解决方案。mybatis的映射文件的命令空间与接口的全限定名不一致;有可能mybatis的映射文件名字与接口的类名字不一致;还有一种情况就是接口声明的方法在映射文件里面没有。但是我检查了n遍!n遍!没有一点问题,相当完美,可是就是报错!结果是因为xml文件没有编译!编译的时候,放xml...

2018-03-14 14:59:11 231

原创 线程安全的登记式单例

有的时候,我们不希望在一开始的时候就把一个类写成单例模式,但是在运用的时候,我们却可以像单例一样使用他最典型的例子就是spring,他的默认类型就是单例,spring是如何做到把不是单例的类变成单例呢?这就用到了登记式单例其实登记式单例并没有去改变类,他所做的就是起到一个登记的作用,如果没有登记,他就给你登记,并把生成的实例保存起来,下次你要用的时候直接给你。IOC容器就是做的这个...

2018-03-08 10:41:28 1231 1

原创 代理模式

代理模式是一个非常常见的模式,他有非常多的变种。比如说远程代理,他可以让操作远程对象像操作本地对象一样的容易还有虚拟代理,他主要是代理一些加载特别缓慢的对象,先展示给用户的是一个代理对象,然后异步加载真正的对象,来提高系统的响应速度代理模式的变种是在是太多了,今天我主要给大家介绍的是保护代理,我分别用静态代理和动态代理两种方式去实现保护代理我们都知道,对于系统的升级最好要对原先的代...

2018-03-07 13:44:42 159

原创 状态模式

有时候,我们会遇见一些场景,里面有非常多的状态变化,各个状态下又有不同的行为,在这种情况下,如果用if-else去写程序的话,会让代码的可读性非常差,编写会非常容易出错,也不容易维护和拓展。在这种情况下,我们就要用到状态模式。我们拿女孩多变的心情来举例吧,下面看看状态的变化图 假设女孩的心情在这四种之间自由转化(天知道有几种- -),如果我们用if-else去做,估计复杂的关系会把人逼疯...

2018-03-05 14:04:26 181

原创 模板模式

模板模式的核心是定义一个算法的骨架,把一些可能变化的实现延迟到子类中去。工厂方法可以看成是一种特殊的模板模式。模板模式还与策略模式有点相似,但是他们的侧重点不同,模板模式的侧重点是规定算法模板,让别人按照他的意图去做事,策略模式的侧重点是定义一系列的方法簇,让使用者自己去选择。他们一个占据着主导权,一个交出了主导权下面我们通过一个榨汁机的例子来看看模板模式是如何实现的public ab...

2018-03-04 10:41:55 218

原创 外观模式

外观模式的核心是把复杂的调用关系封装起来,提供简单的接口我们拿电脑举例,电脑的启动是复杂的,要启动CPU,显示器,风扇等等,假如没有外观模式,需要我们手动的去启动各个组件,这实在是太可怕了。当我们用了外观模式,把这些操作全部封装在一个方法里面,那么我们启动电脑就轻松愉快了,下面我们来看看代码public class AirFan { public void AirFanSt...

2018-03-03 11:19:19 195

原创 适配器模式

我们经常会遇到这样的场景:别人提供的接口和我们需要的接口不兼容的情况,这个时候我们就需要用到适配器了,把别人的接口转化成我们需要的接口。我们看看是如何做到的先看看类图: 我们有三孔和两孔两种接口,三孔适配器的作用是把三孔适配为两孔,我们来看看代码public interface ThreeHole { void provideThreeHole();}publ...

2018-03-03 11:05:33 191

原创 CMS收集器

CMS收集器是基于标记清除算法的一种并发的,低停顿的收集器,值得注意的一点是,CMS只是低停顿而不是没有停顿CMS分为以下四步:初始标记并发标记重新标记并发清除初始标记和重新标记都是需要Stop the world的初始标记仅仅是记录CG root关联的对象,因此停顿时间比较短,并发标记是进行GC RootTracing,重新标记是修正并发标记期间标记的改动(时间比初始标...

2018-03-02 15:58:50 426

原创 Stop the world

我们都知道,在虚拟机进行GC的时候会需要让所用的线程都停止工作,等待他GC完成,那么他是如何保证所有线程全部都停止工作的呢?只有当所有线程都跑到了安全点,或者进入安全区域之后,才会进行GC安全点在安全点,虚拟机会生成OopMap用来记录引用关系(这也是不能在任何地方停下的原因,如果每一条指令都生成OopMap那么效率会非常低,也会占用大量的空间)一般安全点设置在以下位置:方法...

2018-03-02 14:53:16 5286

原创 垃圾收集算法

常见的垃圾回收算法有如下几种:标记清除算法复制回收算法标记整理算法分代回收算法其它的一些算法都是根据这几个算法演变而来的,我们来一个一个的看准备知识:如何判断一个对象是否应该被回收标记清除算法标记回收算法分为标记和清除两个部分,把需要回收的对象标记,在标记完成之后把标记对象清除(一般而言,只有连续标记几次之后,对象才会被清除)标记清除算法实现简单,但是效率比较低,...

2018-03-02 14:25:53 171

翻译 Java虚拟机的类卸载

如何判断类已经死亡:该类的所有实例都已经被回收,即堆中不存在该类的实例加载该类的ClassLoader已经被回收该类的Java.lang.Class对象没有在任何地方被引用,即在任何地方都无法通过反射调用该类的方法当满足以上三个条件时,类才有可能被回收,具体的回收策略需要自己设定。...

2018-03-02 14:00:13 595

原创 Java是如何判断对象是否需要回收的?

常见的两种判断的算法:引用计数算法可达性分析算法(Java使用的这一种)引用计数算法引用计数算法是在对象中加入一个计数器,当对象被引用,计数器+1,当引用失效,计数器-1这种算法实现简单,效率高,但是有一个严重的问题会导致内存泄漏,那就是对象之间循环引用,比如说A对象持有B对象的引用,B对象持有A对象的引用,那么A和B的计数器值永远>=1,也就是说这两个对象永远不会被回...

2018-03-02 13:43:49 1822

原创 命令模式

今天我来讲一下命令模式,命令模式的运用,以及命令模式的优势和不足。我先用例子说明什么是命令模式假设以下场景:有一个控制门和灯的遥控,我们要用遥控来控制他们的行为,并且要实现命令的撤销。 看看类图: 所有的命令类都实现Command接口,有执行和撤销两个操作 Invoker是命令的调用者 Door 和 Light是具体的命令执行者下面我们来看看代码:public cl...

2018-03-02 12:22:03 204

原创 scrapy爬虫实战

前几天写了一个爬虫,现在放出来,希望大家在学习爬虫的时候可以少走一点弯路项目的需求如下:爬取起点网上所有作者的所有作品的链接先说明一点,这个项目的主要目的是练习,因此会有一些不合理的地方,请大家不要在意这些细节我们来看一下主要的架构图: 整个架构使用了生产者-消费者模式,AuthorSpider负责爬作者的链接,BookSpider负责爬取该作者的所有作品。在本项目中,由于只...

2018-02-28 16:45:15 1098

原创 单例模式

在设计架构的时候,我们经常会遇到有一些组件,我们希望整个项目中,它只有一个存在,比如说全局的配置文件、维护映射关系的列表、一些共享的容器等等,这个时候我们就要用到单例模式,不然的话,你能想象出一个程序加载多个全局配置文件的美妙画面的。我主要介绍三种常用的线程安全的单例模式,单例模式没有别的模式复杂的类关系,代码也很简单,但是要完全弄懂它真的不容易,下面我通过下面三种实现方式,给大家剖析一下他们...

2018-02-28 13:58:42 157 1

原创 抽象工厂

如果没有看简单工厂和工厂方法的建议先看一下,因为我使用的是一个例子来进行演进讲解的!传送门ok,下面进入正题。前面我们已经开了连锁店,并且随着规模的越来越大,市场反映越来越好,伴随而来的麻烦事也变多了,比如说客户的需求越来越多,我们的产品需要变得更加的多元化,慢慢的发现,使用现有的系统来管理越来越力不从心。于是,对于系统的升级势在必行我们决定采用抽象工厂来重构系统,我们来看看类图:...

2018-02-27 19:16:12 140

原创 简单工厂和工厂方法

当我们在实际开发的过程中,经常会用到new这个关键字,需要用到什么类,就new什么类,非常的方便,但是我们在享受这种便利的同时,这种便利也给我们带来了一些麻烦:使用new关键字之后,会让类之间的耦合度变高,比如说:Fruit fruit=new Apple(),这样就写死了,如果想把fruit修改成别的什么水果,就必须去改代码,这不符合我们的开闭原则(不了解的可以看这里)于是我们引入了简单...

2018-02-27 17:29:42 275

原创 装饰者模式

在谈装饰这模式之前,我想让大家思考一下,我们开发的时候为什么要遵守开闭原则(对拓展开放,对修改关闭)?这看起来是一个非常矛盾的事情,又要拓展功能,又不能够修改已有的代码。其实,这样做最主要的原因是防止因为修改已有代码引入新的BUG,已有的代码一般都是经过检测的,很少有BUG,如果直接在上面修改的话,很可能导致未知的错误,可能引起别的组件的故障,甚至瘫痪整个系统。在明白上述这一点之后,我们就比较...

2018-02-25 13:48:14 277

原创 观察者模式

和以前一样,在介绍观察者模式之前,我们先看看如果不用观察者模式会是怎样的首先我们假定以下情景:有一个数据源DataSource,要分别在三个地方Place1,Place2,Place3这三个地方展示,我们来看看传统的硬编码会怎么做?(因为比较容易,直接给类图,就不上代码了) 这里定义了Datasource,他是这样工作的:调用setData改变数据调用updata,其实是调用里面...

2018-02-24 15:56:44 133

原创 AttributeError: 'UserPool' object has no attribute 'user_agent'

今天在用Scrapy的时候踩到一个坑,就是在使用用户池模拟浏览器的时候,初始化的时候参数名问题 下面是错误的代码class UserPool(UserAgentMiddleware): def __init__(self,user=''): self.user=user def process_request(self, request, spider):...

2018-02-23 20:53:30 1192

原创 策略模式

我们在讲策略模式之前,先看看为什么要使用策略模式,用策略模式有什么好处假定,我们面对着以下的需求:我们需要管理很多种类的汽车,需要用程序去描述他们很自然的,我们会想到使用继承来复用代码,关系继承关系如下:汽车能够跑,能够发出声音,roadster和bicycle通过继承Car,可以实现代码的复用但是随着管理的车渐渐变多,我们发现,有的车有不同的行为方式,有不同的声音,甚至还有不...

2018-02-23 14:29:51 289

转载 Netty是如何实现高性能的?

采用异步非阻塞I/O类库,基于Reactor模式实现,解决了传统同步阻塞I/O模式下一个服务端无法平滑地处理线性增长的客户端问题(解决了过去用户数量不可控导致资源分配不可控的问题)TCP接收和发送缓冲区使用直接内存代替堆内存,避免了内存复制,提升了I/O读取和写入的性能(零拷贝)支持通过内存池的方式循环利用ByteBuf,避免了频繁创建和销毁ByteBuf带来的性能损耗可配置的I/O线程数...

2018-02-18 11:23:09 1176

原创 原码反码与补码

原码反码补码的计算原码:数字的二进制表示即为源码 反码:反码就是在源码的基础上,符号位不变,其它位取反 补码:正数的补码就是他的原码,负数的补码就是反码+110的源码:0000 0000 0000 0000 0000 0000 0000 1010 -10的源码:1000 0000 0000 0000 0000 0000 0000 1010 -10的反码:1111 1111 1111...

2018-02-17 22:02:04 223

原创 重建二叉树

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。先序遍历是先遍历父节点,再遍历左子节点,最后是右子节点 中序遍历是先遍历左子节点,再遍历父节点,最后再遍历右子节点首先我们先看先序遍历,知道根节点是...

2018-02-11 20:46:10 126

原创 跳台阶问题

在看这个问题之前,我们先来看看斐波那契数列斐波那契数列f(0)=0,f(1)=1,f(2)=f(1)+f(0),f(n)=f(n-1)+f(n-2) 求他n项的程序如下public int Fibonacci(int n) { if(n==0){ return 0; } if(n==1){ ...

2018-02-11 20:33:39 113

原创 二进制中1的个数

题目是这样的:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。可能大部分人看到这个题的第一反应就是把数字的二进制表示换成字符串,然后去找里面1的个数。这种思维是人正常的思维,但不是计算机的思维,这种方式是对计算机不友好的,因为计算机只认识0和1,那有办法通过0和1的计算来得到结果吗?答案是肯定的 public int NumberOf1(int n) { ...

2018-02-11 14:32:17 164

原创 为什么要学习算法?

在我学习JVM的时候,有一个5~6年开发经验的coder说:学习这个有什么用啊,在工作中又用不到,还这么难。这句话引起了我的思考,这个问题和我今天想说的,为什么要学习算法其实是同一个问题,也是不少IT从业者不解的问题。对于很多程序员来说,可能在工作中不会写出比冒泡排序更复杂的算法了,还有必要去花时间去学习吗?先不急着回答这个问题,我们继续看看那个coder是怎么学习的。他说:他在工作的时候...

2018-02-11 09:58:53 3980

空空如也

空空如也

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

TA关注的人

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