技术
文章平均质量分 89
大臭太臭
迷茫的java程序员,希望有人指导,坚持一定会有结果
展开
-
字节码:第二篇
字节码的指令集:https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.1例如:aload_<n>指令,从局部变量表中加载第n个槽的引用到当前方法栈帧的栈顶。栈帧是用于支持虚拟机进行方法调用和方法执行的数据结构,他是虚拟机运行时数据区中的虚拟机栈的栈元素。栈帧存储了方法的局部变量表、操作数栈、动态链接和方法返回地址等信息。每一个方法从运行开始到执行结束,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程原创 2021-04-08 21:31:20 · 213 阅读 · 0 评论 -
用ASM玩字节码第一天
基本概念AMS库的目标是生成、转换和解析已经编译好的Java类,表现为byte数组(存储在磁盘上,被JVM加载)。为此,ASM提供了比字节更高级的概念来读取、写入和转换此类字节数组的工具,例如:数字常亮,字符串,Java标识符,Java类型,Java类结构元素。特别需要注意的是,ASM库的作用范围仅限于读、写、转换、分析类,类加载过程是超出了这个范围的。ASM库提供了两种API用来生成和转换编译的class:core API提供了基于事件的类表示,tree API提供了基于对象的类表示。在基于事原创 2021-02-03 23:11:11 · 340 阅读 · 0 评论 -
TinyLFU: A Highly Efficient Cache Admission Policy
缓存是计算机科学中可以提高系统性能的最基本、最有效的一种方法之一。当完整的数据不适合全部缓存时,通过将一小部分数据存放到更快、更接近应用程序的内存中来提高性能。缓存可以提高性能的最直观原因在于数据的访问都表现出相当程度的“局部性”。更正式的表征这种“局部性”的方式,是通过概率分布来描述所有可能的数据项访问频率,在许多计算机科学的领域内,这种概率都表现出高度偏斜,也就是说少数的数据项会比其他数据项更可能被访问。并且在非常多的场景中,访问模式和概率分布会随着时间而变化,这种现象被称为“时间局部性”。当访问一原创 2021-01-16 22:39:09 · 1038 阅读 · 0 评论 -
堆外KV存储
有大量数据要存储,堆内放不下,只能选择放堆外。那高性能、线程安全的堆外kv存储怎么做?以下是我实际做的过程。最原始、最容易的,搞一个ConcurrentHashMap,每次写数据时先计算好value的大小,然后申请相应大小的DirectBuffer,写入数据后,插入Map中,value就是这个DirectBuffer。可想而知这性能会有多差,申请DirectBuffer是一个非常耗时的操作,而且大量的DirectBuffer会产生大量的虚引用,在一定程度上影响GC。那么先做池化处理,预先申请一大原创 2020-10-17 14:58:16 · 391 阅读 · 0 评论 -
R树
先搞明白R树搜索、插入、删除过程。R树是平衡树,可以理解为B树在N维空间上的扩展。R树一定要满足一下要求:1.根节点若非叶子节点,则至少有两个子节点;2.每个非根叶节点和非叶节点包含的实体个数均介于m和M之间;3.所有叶子节点在同一层次;其中m表示拥有子节点的下限,目的是为了提高磁盘利用率,提高搜索效率。如果m=1,所有节点都只有一个子节点,那树就退化为了普通链表。当节点的子节点数量少于m时,则会删除该节点,把该节点的子节点分配到其他节点中;M表示拥有子节点的上限,因为一般情况下,出原创 2020-08-13 22:34:08 · 1324 阅读 · 1 评论 -
怎么查你附近的餐厅
最近在看Martin大神的一本书,叫《Designing Data-Intensive Application》(《设计数据密集型应用》)。里面提到一个概念,叫做多维索引。书中给了一个例子:餐厅搜索网站可能有一个数据库,其中包含每个餐厅的精度和维度。当用户在地图上查看餐厅时,网站需要搜索用户查看的矩形地图区域内的所有餐厅。这就需要一个二维的查询,如下:SELECT * FROM restaurants WHERE latitude > 51.4946 AND latitude < 51原创 2020-08-10 22:32:20 · 4685 阅读 · 0 评论 -
消息队列之消息过滤
众所周知,RocketMQ是支持消息过滤的,即发送消息时,可以给消息设置一个TAG。订阅主题的时候,可以设置只消费携带某些TAG的消息,起到消息过滤的作用。RocketMQ中是把消息TAG通过哈希转换成了的long型,保存在了消息索引中。在订阅客户端拉取消息时,为了减少协议大小,减低报文长度,拉取协议中也只携带指定的若干TAG的哈希值,服务端接收到拉取请求时,在查找索引时,就直接过滤了不符合条件的索引。这里就会有一个问题,如果出现哈希冲突了,就会有错误的消息被客户端消费到。RocketMQ为了提高性能,原创 2020-07-18 22:40:23 · 827 阅读 · 0 评论 -
进程调度-1
最近特别有感触,各层面的设计似乎都可以从操作系统中找出相似的设计,操作系统几乎是设计集大成者,所以重新又开始看操作系统相关的书籍。最近可能都是一些记录性的文章,操作系统原理因为是教学课程,所以不会另做笔记。从重读Linux内核开始,记录学习过程。本文均摘自《Linux内核与实现》。因为硬件资源总是有限的,而我们哪个进程可以占用资源投入运行,何时运行以及要运行多长时间,就是调度程序要做的事情。进程调度程序就是可运行态进程之间分配有限的处理器时间资源的内核子系统。首先我们要明确几个概念,多任务系统可原创 2020-07-04 22:48:33 · 284 阅读 · 0 评论 -
开源框架WPaxos源码浅析
最近WPaxos框架已经开源,WPaxos开源地址。作为旁观者之一,大致简单的梳理一下整体的代码结构,做一个源码浅析,后面有时间再对每一部分做深入的分析。Paxos算法是一个强一致性的算法,最精简的描述应当是Paxos原作者在《Paxos Made Simple》中的描述:Phase 1(a) A proposer selects a proposal number n and sends a prepare request with number n to a majority of acc原创 2020-06-02 16:41:21 · 682 阅读 · 3 评论 -
负载均衡-粘性分配与平滑加权轮询
说到负载均衡,我个人习惯分为两种,一种是静态负载均衡,也就是把确定好的、有限的负载按照一定规则分配到不同的工作单元上,这种负载均衡算法只需要计算一次最终分配状态即可。一种是动态负载均衡,即每次把新到来的负载按照一定规则分配到不同的工作单元上,这种负载均衡算法需要实时动态计算,并且大部分需要保留上一次分配的状态。比如说,kafka中一个topic有多个consumer,那每个consumer需要消费哪些partition都是提前计算好的。这里负载就是这个topic的所有partition,是一个确定好的、原创 2020-06-01 23:30:25 · 804 阅读 · 0 评论 -
一个小伙伴的问题
下午休息的时候,小伙伴突然扔给我一段代码public class GCTest { public static void main(String[] args) { List<GCTest> aa = new ArrayList<>(); for (; ; ) { aa.add(new GCTest()); System.gc(); } }}然后问到:为什么不加System.gc()这一行就会OOM,加上System.gc()就不再OOM了。原创 2020-05-26 23:06:58 · 302 阅读 · 0 评论 -
work steal and overpartition
工作窃取和超额切分,第一次听到这个概念是从ZGC的Stripe Mark技术,它为了提高垃圾回收的效率,把多个region划分到不同的条纹,然后再把GC线程隔离到自己的条纹内进行垃圾回收。如果有线程处理完了自己的任务,则会加入到其他的条纹上帮助其他的线程来处理任务。这就是和工作窃取是同一种思想。工作窃取,一种分治的思想,最初是一种多指令流多数据流(MIMD)计算任务的线程调度方法,需要工作的处理器需要从其他的处理器上窃取工作任务。一般上层应用层也会用来做多线程任务的调度,来保证线程的活跃来提高任务处理的原创 2020-05-23 22:47:02 · 393 阅读 · 0 评论 -
怎么做配置下发
配置下发我们做开发,无论是做中间件还是业务都会面临一个问题,我们的客户端或者APP发版本后,需要运行中动态加载一些配置,比如负载均衡、服务发现等,这些配置需要从服务端来获取,并且在配置变更后,客户端可以及时或非及时的得到最新的配置。把问题抽象化,即我们客户端如何获取最新的配置,也就是配置下发的问题。少量用户最开始,配置下发可能会比较简单,无论是采用TCP长连接或者是HTTP短连接等等,我们客户端定时的与服务端进行通信,每次从服务端拉取最新的配置,客户端进行本地更新即可。这是最基.原创 2020-05-14 23:34:28 · 4465 阅读 · 0 评论 -
调整敏感度
目录一个功能Netty高低水位Java8的Map调整敏感度一个功能最近在做一个功能,消息队列的消费端负载均衡,像kafka、RocketMQ等都可以做到全局消费的负载均衡,但是他们都需要一个中心节点来做统一分配与调整。我们做到了不用集中节点的全局负载均衡,并且模仿kafka的StickAssignor做到了粘性分配,即每次变动最少(纯属为了炫耀,与本文无关)。回归正题,每次对消费端做负载均衡是一个代价很大的操作,因为要停止受影响消费端的消费,收集消费offset,重新分配,所以这原创 2020-05-13 23:15:39 · 639290 阅读 · 0 评论 -
java并发编程(二)-volatile写操作前为什么不加LoadStore屏障
只要说到并发编程,volatile是永远绕不开的一个点。理解了volatile,基本上也就理解了JMM。Java内存模型中的happens-before、as-if-serial等在前文介绍过,这里只介绍volatile的内存语义实现。在JSR-133之后,volatile可以实现线程之间的通信,加强了volatile的内存语义,即禁止volatile变量与普通变量的重排序,使得volatile的写-读与锁的释放-获取有相同的语义。对于volatile内存语义的描述,几乎都出自于http://gee原创 2020-05-12 15:17:31 · 3244 阅读 · 23 评论 -
java并发编程(一)
目录为什么有并发编程并发涉及的问题锁CAS对象头synchronizedAQSReentrantLocksemaphore未完待续......并发编程发展到如今几乎已经成为了开发人员的必备技能。很多高级工程师、专家,甚至于架构师都站在“山顶”聊并发,讲怎么并发编程。作为一个以Java为主语言的低级开发人员,我也想尝试从“山脚”的角度,仰望一下并发。为...原创 2020-05-03 10:46:23 · 343 阅读 · 0 评论 -
RocketMQ事务消息
之前提到过,我们自研的消息队列中间件参考了RocketMQ的实现,但是有的细节上考虑得不是很全面。所以最近又拿我们的消息队列与RocketMQ做一些对比,看看有哪些点是当时没理解透,而做出的一些不恰当改动。恰好想到我们还不支持事务消息,而RocletMQ在2018年4.3版本发布时,就已经支持了事务消息。详细可以参考文章:https://mp.weixin.qq.com/s/43wwC4l...原创 2020-04-27 23:59:42 · 284 阅读 · 0 评论 -
再谈时间轮
时间轮很早前就很流行了,在很多优秀开源框架中都有用到,像kafka、netty。也算是现在工程师基本都了解的一个知识储备了。有幸在工作中造过两次轮子,所以今天聊聊时间轮。时间轮是一种高性能定时器。时间轮,顾名思义,就是一个基于时间的轮子,轮子划分为多个槽,每个槽代表一个时间跨度,槽的数量*时间跨度等于时间轮可以支持的最大延迟时间。在每个槽上挂载若干同一时间跨度内需要执行的任务。随着时间...原创 2020-04-19 00:27:38 · 2336 阅读 · 3 评论 -
再谈MappedByteBuffer与DirectBuffer
去年年底的时候,为我们的分布式消息队列中间件写源码分析系列文章的时候,看到我们的存储部分是参考了RocketMQ的实现。这部分有一个很有意思的内容public AppendMessageResult appendMessage(final Object msg, final AppendMessageCallback cb) throws IOException { ...原创 2020-04-11 17:35:08 · 1814 阅读 · 0 评论 -
由DCL引发的一次思考
上次群里面试的小伙伴在看完对逃逸分析的说明后,下功夫好好学了HotSpot即时编译的相关知识,信心十足的又去面试了,结果又让回家等消息。看了看他分享的面试题,又在各种高大上的题目里发现了一道有意思的题:请看一个DCL单例模式,并简单说明一下是否正确。这题目过于简单,不像是这种级别的面试题,所以这道题大有深意,很有意思。先上代码:/** * @author liuyan * @...原创 2020-04-05 00:18:55 · 306 阅读 · 2 评论 -
Java对象在堆上分配吗
昨天有个技术群里一个小伙伴分享了一次被虐的面试经历,其中一道题很有意思:Java中对象都会分配在堆上吗?大部分小伙伴都在讨论类似:redis为什么快?怎么设计弹性伸缩的缓存系统?服务降级、服务熔断等等非常高大上的问题。但是在如此高大上的问题里,掺杂了这么看似简单的一道题,说明还是有点意思。问了下小伙伴们,不为少数的小伙伴都会很简单的回答,对象分配在堆上啊,上学没认真听讲吗?但是真的如此...原创 2020-04-02 22:21:17 · 318 阅读 · 0 评论 -
关于i++与++i的一道题
前几天刷LettCode题,看到评论区有人问了一个有意思的问题,代码如下:public static void main(String[] args) { int a[] = {1, 2, 3, 4, 5}; int num = 3; a[num - 1] = a[num-- - 1]; for (int i : a) { System.out.println(i); }}...原创 2020-04-01 12:27:28 · 850 阅读 · 0 评论 -
线程模型优化
先说背景,抽象后线程模型为:如上图线程模型,说明解释一下。多个线程接受请求,并发把请求提交到一个合并线程的队列中。提交请求伪代码表示为:request.inTime = nowlock.lockput queueif(check) list = take top 20 require from queue doSomething(list) for require in ...原创 2019-11-22 22:39:39 · 202 阅读 · 0 评论 -
paxos算法中master有效期与续约依赖机器时间的解决办法
对于paxos算法,一般工程化时,为了提高paxos算法效率,会引入master角色,并且要遵循在同一时刻,paxos集群有且只有一个节点是master角色,或者没有master角色;且只有master角色的节点可以发起propose,这两个原则。这就涉及到了maste的选举与续约。一般的master选举如下图所示:那么master节点认为master的任期为从beMaster操...原创 2019-11-07 22:07:32 · 336 阅读 · 0 评论 -
一次Java空指针异常排查经历
同理先说背景:我们的一个注册中心服务,多节点部署,客户端会hash到一个节点,启动定时任务与之通信拉取配置。突然有业务线说客户端大量报超时异常。首先当然赶紧让业务线把异常日志发给我。先分析了一下日志,找到了对应的超时异常,根据堆栈信息分析出是拉取配置任务大量连续超时,再定位到是哪一台服务。因为之前线上出现过超时情况,是因为代码效率太低,每个拉取配置的请求要处理将近750ms,导致了请求队列...原创 2018-12-05 20:53:17 · 1797 阅读 · 1 评论 -
记一次线上FGC排查经历
背景:线上服务,启动后很快必定FGC一次,随后GC变正常。服务器上JDK版本为jdk1.8.0_66。启动参数为:-Xms8g -Xmx8g -Xmn3g -Xss1024K -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+UseCMSCompactAtFullCollection -...原创 2018-12-09 22:13:14 · 3224 阅读 · 2 评论 -
我的理解阻塞\非阻塞,同步\异步
要解释I\O的阻塞\非阻塞,同步\异步,实在难以下笔。涉及内容太多,很多知识点我也没有搞清楚,很怕误导别人。算是把看到的认为好的内容搬运过来,整合一下,再把自己不理解的内容抛出来,做个记录,日后想着学懂。说I/O模型,不得不提《UNINX网络编程》这本书,“第六章:I/O复用”中把Uninx可用的I/O模型分为了5种:阻塞式I/O 非阻塞式I/O I/O复用 信号驱动式I/O 异步...原创 2019-03-16 15:31:10 · 360 阅读 · 0 评论 -
jvm之虚拟机字节码执行引擎(续)
之前学习了静态分派和动态分派,静态分派典型的应用是方法重载,动态分派典型的应用的方法重写。静态分派在编译阶段就确定,也就是在编译阶段就确定了invokeviryual指令,也就是确定了方法的签名。在动态分派的过程中,也就是当执行到这条invokevirtual指令时候,方法的实际接收者确定步骤有以下几步:1.找到操作数栈顶的第一个元素所指向的对象的实例类型2.如果在类型C中找到方法原创 2017-12-09 16:01:17 · 216 阅读 · 0 评论 -
springCloud(三续)
接着上一篇,继续学习springCloud上回晚上太困了,写了一半,学习到了FallBackFactory,用途就是当feignclient出现任何错误时的fallback,并且可以给出错误信息。看一下具体的接口只有一个泛型方法: T create(Throwable cause);返回一个继承该@feignclient注解的接口的实例。cause即错误信息。可以根据错误信息做不同原创 2017-08-06 22:11:00 · 1476 阅读 · 0 评论 -
记一次重构经历
背景:最近新接触一个web项目,要求新增加一个审批流程。简化抽象模型,订单分为三种A\B\C。其中AB的审批流程完全一致,简化为审批1->审批2->审批后动作。C的审批流程略有不同,简化为审批0->审批1->审批2->审批后动作。现在要做的一个功能是要在订单C上增加一个审批流程变为:审批0->审批3->审批1->审批2->审批后动作。很简单...原创 2018-11-25 17:30:45 · 372 阅读 · 0 评论 -
数据库主键生成方案
问题产生的背景:数据量到达一定程度时,需要做数据的分库分表(这又是一个很值得讨论的问题,什么量级的数据做分库分表),此时我们需要保证数据库主键的唯一性、单调递增。并且获取唯一主键的服务要保证高可用、高吞吐率。一般常用的方法有snowflake算法、UUID、数据库自增主键等等。因为MySql是聚集存储方式,其存储是按照主键顺序存放的,所以实际生产环境会要求主键递增,所以UUID一般用的比较少。sn...原创 2018-04-19 22:23:48 · 1659 阅读 · 0 评论 -
springcloud(十)
springcloud继续学习,记录了mybatis collection使用过程中的一个问题原创 2017-10-11 21:28:15 · 422 阅读 · 0 评论 -
springCloud(八)
主要是简单的过了一遍Ribbon的源码,分析了一下主要的类原创 2017-09-20 21:27:37 · 1957 阅读 · 0 评论 -
springCloud(七)
zuul的简单源码调试原创 2017-09-11 22:16:04 · 344 阅读 · 0 评论 -
springCloud(六)
zuul原创 2017-09-02 13:19:01 · 729 阅读 · 0 评论 -
springCloud(九)
学习负载均衡的策略原创 2017-09-26 20:12:50 · 332 阅读 · 0 评论 -
springCloud(五)
Hystrix与feign源码学习原创 2017-08-28 00:17:43 · 442 阅读 · 0 评论 -
springcloud(二)
接上一篇,继续学习服务注册和服务发现。利用eureka客户端和feign进行服务注册和服务间发现。原创 2017-07-26 22:05:37 · 2269 阅读 · 0 评论 -
springcloud(三)
继续上一篇,学习一下断路器。/** * Created by liuyan9 on 2017/7/26. */@FeignClient(value = "feign",fallback = CallBackFeign.class)public interface CallFeignService { @RequestMapping(value = "call", metho原创 2017-08-03 23:42:58 · 333 阅读 · 0 评论 -
springCloud(四)
接上一篇,上次学习到了feign到底是如何构造request和发送请求的,最后的时候想看一下异常情况的时候到底是怎么调用fallback的,但是一直没进断点,今天又重新试了一个,原来是会进入断点的。继续学习。在HardCodeTarget中创建request的时候,只会设置url,所以会有一个问题,多服务间调用的时候,一些上下文信息怎么传递,比如用户信息。之前我们是把用户信息存储到zookee原创 2017-08-09 23:17:07 · 456 阅读 · 0 评论