Java
文章平均质量分 90
小一明日记
刷题,看源码,人生很短,时间不多
展开
-
记一次生产事故-消息积压分析
在5月20日这天,出了一个生产事故,导致消息队列中积压了大量消息,峰值时期达到 200w+。 下面主要就这个生产事故,顺带梳理一下消息积压问题以及常见的解决方案。原创 2022-06-08 08:45:54 · 303 阅读 · 1 评论 -
Redis高级功能-Lua脚本实现原理
Lua 是一个简洁、轻量、可扩展的脚本语言,它有着相对简单的API 因此很容易嵌入应用中,Redis 从 2.6 版本开始支持 Lua 脚本。原创 2022-05-07 13:18:55 · 1552 阅读 · 0 评论 -
系统了解Mysql-MVCC并发控制机制
大概两年前因为排查一个数据可见性的问题也了解过 Mysql 的 MVCC,当时觉得自己都懂了,但始终没有将这块知识串联起来,所以总感觉印象不深刻,其实本质上还是因为没有搞清楚这个东西的来龙去脉,没有真正地理解它。原创 2022-02-21 17:35:36 · 659 阅读 · 0 评论 -
分布式唯一ID-雪花算法
雪花算法满足分布式唯一ID对于唯一性,单调递增性,安全性的要求,无论在实现复杂度,还是性能方面都有很大的优势,且,能适用于大部分业务场景。原创 2022-02-10 22:35:40 · 1644 阅读 · 0 评论 -
一致性hash
概述一致性 hash 是传统 hash 算法的增强版。多用于分布式数据存储场景,在集群节点数量发生变化时,提升集群适应变化的能力。传统hash假设当前服务集群中存在 3 个节点:Node-A,Node-B, Node-C;而客户端存在 Key1,Key2,Key3 需要映射到对应的服务节点。传统 hash 算法思路:先计算 key 对应的 hash 值将 hash 值和服务节点的数量取模,算出对应节点的下标,即 Hash(Key) % NodeSize如下图,通过传统 hash 计算出的原创 2021-10-17 20:57:18 · 5405 阅读 · 1 评论 -
RocketMQ原理-消息消费流程
概述本文目的在于将消息消费的流程梳理完毕,使自己包括读者能够对 RocketMQ 的消息消费流程有清晰的认识。主要包含以下内容:相关概念介绍消费端的队列分配,即负载均衡机制消息拉取的实现机制并发消费,顺序消费的实现机制消费模式消费者类型注意:在最新发布的 RocketMQ 中,已将 DefaultMQPullConsumer 类标记为弃用,预计在 2022 会将这个类移除,对应的替代类为 DefaultLitePullConsumer。消费方式分为并发消费和顺序消费。并原创 2021-10-07 20:16:12 · 2370 阅读 · 0 评论 -
RocketMQ原理-消息发送流程
RocketMQ 源码版本 4.9.1概述整体架构各角色说明:NameServer,负责提供路由服务Producer,生产者,负责发送消息Broker,消息队列,负责存储消息并提供相关的API操作Consumer,消费者,负责消费消息生产-消费模型消息发送方式:同步,异步,单向消息类型:普通消息(包含延迟消息),顺序消息(全局顺序与局部顺序),事务消息本文通过同步发送普通消息的Demo,来了解消息发送的主要流程。生产者下面看到一个生产者发送消息的 demo主要做了几.原创 2021-09-19 14:06:35 · 239 阅读 · 0 评论 -
hashmap源码-扩容机制
前言注意,本系列文章都是基于 jdk 1.8这是 hashmap 源码系列文章的第三篇,前面文章讲解了 hash 算法,以及元素 put, get 的流程,相信大家对 hashmap 容器已经有了大体上的认识,今天要讲的内容可谓是 hashmap 的重头戏——扩容机制。内容主要涉及:容器扩容负载因子扩容机制容器扩容jdk 中很多容器的底层实现使用的是数组,比如 ArrayList,还有今天要说的 Hashmap。数组的容量是一开始指定好的,为一组连续的内存空间。在实际的开发过程中原创 2020-05-10 18:09:04 · 332 阅读 · 0 评论 -
hashmap源码-元素put,get
前言注意,本系列文章都是基于 jdk 1.8这是 hashmap 源码系列文章的第二篇,前面我们主要讲解了 hashmap 中 hash 算法的实现,本文则是带大家了解元素 get, put 的相关实现,这样一来 hashmap 的大体框架就描绘完毕了。内容主要涉及:hashmap 初始化时机元素 put 流程元素 get 流程初始化时机还记得前面我们提到 hashmap ...原创 2020-04-25 22:30:59 · 154 阅读 · 0 评论 -
hashmap源码-hash算法
前言注意,本系列文章都是基于 jdk 1.8这是 hashmap 源码系列文章的第一篇,主要带大家初步了解 hashmap 几个重要的知识点,在后续的文章中会深入讲解框架中各个部分的实现细节。内容主要涉及:基础结构hashmap 初始化hash 算法扰动函数基础结构hashmap 的基础结构涉及几部分:数组链表红黑树正常情况下 hashmap 元素存取的时间复...原创 2020-04-24 20:48:59 · 371 阅读 · 0 评论 -
一则小坑:java.io.FileNotFoundException Too many open files
前言最近项目准备上线,在测试环境测试通过,准备把项目部署到『预发布环境』,可以把它理解为我们上线前的最后一个验证环境。在部署的过程中,发现涉及的几个项目都部署失败了,jenkins 集成平台上『一片报红』,把我给整懵逼了。这里再交代一下项目部署的方式:通过 jenkins 进行一系列 build 相关的操作之后,将构建产物(war包形式)传输到指定环境机器的 tomcat 容器中,启动运行。...原创 2020-04-12 08:42:26 · 3248 阅读 · 1 评论 -
redis-基础数据结构一
前言Redis 作为基于键值对的 NoSQL 数据库,具有高性能,丰富的数据结构,持久化,高可用,分布式等特性,这些特性使得 Redis 从同等竞品中脱颖而出,现如今已成为互联网公司软件架构的标配。因此作为一名后端开发人员,有必要也有责任去搞清楚 Redis 的正确使用方式,了解其底层原理有助于工作中问题的排查。基础数据结构Redis 与 Memcached 同为内存数据库,并且数据存储都...原创 2020-04-05 14:33:41 · 122 阅读 · 0 评论 -
jdk容器-安全失败机制
在上篇文章 jdk容器-快速失败机制中,我们提到 jdk 为非同步容器建立的一种安全警报机制,通过 fail-fast 通知用户可能存在线程安全问题,本质上是因为不同线程并发访问同一集合对象导致的。在主题开始前,我们先来看一段测试代码,和昨天模拟快速迭代失败的代码大体一致,只不过替换了容器。 public static void main(String[] args) { ...原创 2020-04-04 18:09:51 · 181 阅读 · 0 评论 -
jdk容器-快速失败机制
前两天小伙伴问我关于集合快速失败的问题,勾起了我对快速失败机制 fail-fast 的回忆,这两天也仔细看了一下相关内容,在此做一下总结。先放出小伙伴提的问题,以及对应的测试代码,我稍后会细讲这个话题——为什么没有快速迭代失败?fail-fast先来讲一下 fail-fast,它实际上是一种编程思想,即快速反馈系统错误,防止发生更严重的问题。我们在平时的开发中肯定写过类似的代码,提前判空也...原创 2020-04-03 22:13:30 · 189 阅读 · 0 评论 -
mysql-请求包大小限制
问题今天在开发环境测试即将要上线的一个功能,其中有一个步骤会往 mysql 数据库批量插入大量数据。在测试的过程发现流程失败了,查看日志发现了这么一个错误。### Error updating database. Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (6034195 > 4...原创 2020-04-02 22:43:27 · 1565 阅读 · 0 评论 -
leetcode刷题-重建二叉树
题目描述输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如,给出前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7]返回如下的二叉树: 3 / \ 9 20 / \ 15 7重建二叉树上午在学习广度遍历优先的算法...原创 2020-03-25 20:18:49 · 229 阅读 · 0 评论 -
leetcode刷题-反转链表
题目反转一个单链表。示例:输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL题目链接:https://leetcode-cn.com/problems/reverse-linked-list/迭代迭代的思路比较简单,反转一个链表,只需要让每个节点指向上一个节点算法思路...原创 2020-03-25 20:16:00 · 94 阅读 · 0 评论 -
jvm探索之路-基于栈的方法执行机制
起因这周例会上,在进行 code review 时,有同事对其中一个方法变量的定义位置提出疑问 // 为了方便,对代码进行了简化 public static void main(String[] args) { for (int i = 0; i < 100; i++) { int a = 1; int b = 2...原创 2020-03-25 20:10:45 · 155 阅读 · 0 评论 -
线程池源码-异常处理
在线程池源码系列文章 线程池源码-线程被全部关闭了吗 中有提到,线程池在结束 worker 线程时会有一个标识 completedAbruptly,用来判断线程是否为异常退出。那什么时候线程会异常退出呢?答案很明显,在执行任务的过程中抛出了异常,且没有进行 try catch 处理。本篇文章主要探索下面的问题线程池默认的异常处理方式,存在的问题关于异常处理的解决方案默认处理想知道...原创 2020-03-25 09:23:28 · 149 阅读 · 0 评论 -
leetcode刷题-验证二叉搜索树
题目描述给定一个二叉树,判断其是否是一个有效的二叉搜索树。假设一个二叉搜索树具有如下特征:节点的左子树只包含小于当前节点的数。节点的右子树只包含大于当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。示例 1:输入: 2 / \ 1 3输出: true示例 2:输入: 5 / \ 1 4 / \ ...原创 2020-03-22 14:46:00 · 127 阅读 · 0 评论 -
单例模式-序列化问题
在前面文章 单例模式-双检锁就稳了?,提到了对象序列化会破坏单例模式,同时也做了试验,今天我们来借着这个问题了解一下序列化的过程。序列化的作用起源这里就不详细赘述了,本文主要解决序列化破坏单例的问题。如果想详细了解序列化,反序列化过程,推荐一篇文章,写得清清楚楚,包括底层实现流程。https://cloud.tencent.com/developer/article/1125165)问题...原创 2020-03-19 21:36:32 · 468 阅读 · 0 评论 -
单例模式-双检锁就稳了?
前言前两天和一位朋友聊到单例模式的双检锁,相信了解过线程并发的朋友对双检锁不陌生,也可以看我之前分享的文章 并发编程-可见性,原子性,有序性问题。这位朋友问我:双检锁能解决反射攻击和序列化问题吗?说实话,正好碰到我的知识盲区了,恰逢今天同事也提到单例,简单了解一下相关知识。双检锁我们先来回顾一下双检锁的经典写法。public class Singleton { private ...原创 2020-03-17 21:57:39 · 154 阅读 · 0 评论 -
并发编程-可见性,原子性,有序性问题
前言传统计算机以单核为主,多个调度任务通过『分时』策略共享同一个处理器的资源。在之后的时间里计算机设备快速发展,随着多核处理器的出现,计算机的运算能力得到了大幅度的提升,在程序的编写方面,出现了并发编程,为的是能够最大程度地提高对处理器的利用率,与此同时,也带来了众多程序并发相关的问题,大致可以概括为以下三个问题。可见性在计算机发展的过程中,面临的一个大问题就是——cpu,内存,外存之间的速...原创 2020-03-17 21:54:43 · 144 阅读 · 0 评论 -
并发编程-线程中断机制
在前面的线程池系列文章 线程池源码-线程全部被关闭了吗 ,提到了线程池 shutdown 过程会使用线程的中断机制去关闭线程,试着问自己一个问题——调用线程的中断方法 interrupt() 就能中断线程吗?起源试想一下,你的电脑开着杀毒软件正杀着毒呢,你不耐烦地点击停止按钮企图停止这一过程,本质上来说就是一个线程想终止另外一个线程,这就要求线程间提供一种中断机制,传递中断信号。而中断的...原创 2020-03-12 22:09:37 · 131 阅读 · 0 评论 -
线程池源码-线程全部关闭了吗
在前面的文章线程池源码-线程池状态,我们提到线程池的各种状态,以及线程池 shutdown 的流程,但始终有个疑问:shutdown 操作最终能否关闭所有线程?疑问起源为什么会有这个问题呢?回顾前面提到的 shutdown 流程。检查是否有终止线程池的权限,会挨个检查每个线程修改线程池状态为 SHUTDOWN终止空闲线程,怎么判断线程是否空闲,通过 tryLock() 尝试获取它的锁,...原创 2020-03-12 08:45:12 · 369 阅读 · 0 评论 -
线程池源码-线程池状态
在前面的文章中,主要讲解了线程池的任务执行机制,顺带提了一下 ctl 变量的工作原理。线程池源码-伟大而渺小的ctl线程池源码-任务提交线程池源码-任务执行本文主要带大家了解一下,线程池都有哪些状态,以及这些状态之间是如何切换的。线程池状态RUNNING运行状态,这个时候线程池就像一个年轻力壮的小伙子,能扛能打,既能接受新的任务,同时也会处理任务队列中已经堆积的任务,这也是线程池...原创 2020-03-11 08:59:17 · 170 阅读 · 0 评论 -
线程池源码-任务执行
在上一篇文章 线程池源码-任务提交 中,我主要讲解了:线程池初始化参数线程池处理任务的整体流程worker 线程的创建小伙伴们可能对线程池任务执行机制有疑问,今天我们就来探索以下几个问题:worker 线程的启动方式线程池如何区分核心线程,非核心线程线程池中的线程如何复用worker 对象前面提到,在任务提交之后,线程池可能会创建 worker 对象去处理该任务。pri...原创 2020-03-09 22:29:14 · 114 阅读 · 0 评论 -
线程池源码-任务提交
线程池在工程中扮演着不可或缺的角色,话不多说,今天我们就来看看它底层的运行原理。初始化参数关于这个问题也经常被问到,线程池创建都有哪些参数,它们都有什么含义,今天我们就从构造参数开始入手public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,Bloc...原创 2020-03-08 18:12:42 · 115 阅读 · 0 评论