自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

张哈希的博客

曾任职于顺丰,华为,网易等公司,从Java小白,成长为资深开发与项目组首席架构师。喜欢源码与开源,曾贡献 MyCat1.6 与 JFRUnit 核心源码,贡献过Spring Cloud,Apache RocketMQ,Apache Bookeeper,Du

  • 博客(35)
  • 论坛 (1)
  • 收藏
  • 关注

原创 Spring Cloud系列之Commons - 2. 服务发现 - 如何通过配置文件配置服务实例?

Spring Cloud Commons 主要包括如下模块的接口和默认实现:其中的限流策略以及重试策略是没有天然带的,但是其他模块的实现一般会带上这些功能。我们先从服务发现相关接口开始分析服务发现相关核心接口DiscoveryClientDiscoveryClientpublic interface DiscoveryClient extends Ordered { int DEFAULT_ORDER = 0; //描述 String description(); //通过

2021-01-27 08:58:49 11876

原创 Spring Cloud系列之Commons - 1. 背景与基础知识准备

本文基于 Spring Cloud 2020.0 发布版的依赖本系列会深入分析 Spring Cloud 的每一个组件,从Spring Cloud Commons这个 Spring Cloud 所有元素的抽象说起,深入设计思路与源码,并结合实际使用例子深入理解。本系列适合有一定 Spring 或者 Spring Boot 使用经验的人阅读。什么是Spring Cloud CommonsSpring Cloud框架包括如下功能:分布式多版本配置管理服务注册与发现路由微服务调用负载均衡断.

2021-01-18 10:30:26 15912

原创 通过 JFR 与日志深入探索 JVM - TLAB JFR 相关事件与日志详解

全系列目录:通过 JFR 与日志深入探索 JVM - 总览篇上一篇我们详细的分析了 TLAB 的原理以及生命周期,并且提出 JFR 相关的两个事件:在线程分配对象时,如果 TLAB 不够,则根据最大允许浪费空间,决定是回收当前 TLAB 还是重新获取一个 TLAB 进行分配还是直接在堆上分配。jdk.ObjectAllocationOutsideTLAB 代表直接在堆上分配,jdk.ObjectAllocationInNewTLAB 代表回收+重新获取 TLAB 进行分配。我们也提到了,jdk.Ob.

2021-01-06 21:22:10 32900

原创 请你尽量全面的说一个对象在 JVM 内存中的结构?

从 Java 14 开始,Project Valhala引入了 Value Type(或者称为 inline type),参考: Valhalla: https://openjdk.java.net/projects/valhalla/ ,这里不讨论 Value Type 也就是 record 类型。首先,Java 对象在堆内存内存中结构包括:类型指针: 一个指向类信息的指针,描述了对象的类型。标记字(Mark Word): 一组标记,描述了对象的状态,包括对象散列码(如果有)、对象的形状(是否是

2021-01-31 09:02:20 10872

原创 请你谈谈为什么分布式系统需要限流器

什么是限流器?限流器是一种限制某种操作在一定时间内的执行次数(例如每秒钟5次)或者执行量(例如每秒钟1G大小的数据)的机制。限流器是一种防御性的编程实现方式,在大数据量高并发访问时,经常会出现服务或接口面对暴涨的请求而不可用的情况,甚至引发连锁反映导致整个系统崩溃。此时你需要使用的技术手段之一就是限流,当请求达到一定的并发数或速率,就进行等待、排队、降级、拒绝服务等。为什么需要限流器在一个大型的分布式系统,系统设计要考虑很多很多方面:系统动态扩容缩容,总会有滞后性。业务总会有高峰有低谷。集群大小

2021-01-30 08:08:32 10708

原创 急~为啥我指定的的maven依赖版本没有生效?不是最短路径原则吗?

女朋友他们项目用了 spring-boot,以 spring-boot-parent 作为 parent:<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.9</version></parent>女

2021-01-29 11:58:43 12072 1

原创 90% 的 Java 程序员都说不上来的为何 Java 代码越执行越快(1)- JIT编译优化

麻烦大家帮我投一票哈,谢谢经常听到 Java 性能不如 C/C++ 的言论,也经常听说 Java 程序需要预热,那么其中主要原因是啥呢?面试的时候谈到 JVM,也有很多面试官喜欢问,为啥 Java 程序越执行越快呢?一般人都能回答上来,类加载,缓存预热等等,但是深入下去,最重要的一点却没有答上来,今天本篇文章就来帮助大家理解这个问题的关键。首先,我们从一个简单的例子看起,来感受下程序是否越来越快:package com.test;import java.util.concurrent.Ti.

2021-01-28 07:57:48 11285

原创 每日一面 - 下面这个 maven 依赖,我们有两个一样的依赖,但是不同的版本,最后项目会依赖哪个版本呢?

下面这个 maven 依赖,我们有两个一样的依赖,但是不同的版本,最后项目会依赖哪个版本呢答案是 28.2-jre,相同依赖不同版本,以最后的为准,依赖会被替换。验证:

2021-01-27 07:58:06 12015

原创 每日一面 - 假设 Redis 基本可靠,如何用单进程 Redis 实现分布式悲观锁

麻烦大家帮我投一票哈,谢谢什么是分布式锁针对共享内存模型的程序(例如JAVA程序),锁就是一个非常常用的机制。一般简单分为悲观锁和乐观锁。悲观锁就是你获取这块数据的锁之后,别人就无法访问或操作这块数据,直到你释放这个锁。乐观锁一般就是CAS更新。在单进程内内存的锁,只控制进程内数据的,就是非分布式锁。相反的,跨进程,需要锁住多个进程访问数据的锁就是分布式锁。悲观锁一般由Redis的SETNXEX实现,Key 为资源名,EX 设置一个合理的超时时间, Value 设置为一个客户端生成的在超时时间.

2021-01-26 08:10:53 12506

原创 每日一面 - 聊一聊Java为何需要平衡方法调用与内联

在 Java 中,方法调用一般通过 Virtual Call 还有 Classic Call。Classic Call 就是直接指向方法的地址,需要一次寻址到方法的地址,比直接执行代码慢。Virtual Call 需要通过 VMT(Virtual Method Table)。这个VMT存储的是该class对象中所有的Virtual Method,程序运行的时候首先加载实例对象,然后通过实例对象找到VMT,通过VMT再找到对应的方法地址,再执行代码。所以比 Classic Call 更慢。Java 中除

2021-01-25 08:16:06 12509

原创 每日一面 - java里的wait()和sleep()的区别有哪些?

一句话总结:sleep方法是当前线程休眠,让出cpu,不释放锁,这是Thread的静态方法;wait方法是当前线程等待,释放锁,这是Object的方法。同时要注意,Java 14 之后引入的 inline class 是没有 wait 方法的Sleep()原理public static native void sleep(long millis) throws InterruptedException;sleep()是Thread中的static方法,也是native实现。就是调用底层的 sleep

2021-01-24 08:18:00 12763

原创 每日一面 - 求与数字最接近的 2 的 N 次方

对于 2 的 N 次方取余,相当于对 2 的 N 次方减一取与运算,这对于高并发分片计算的时候,很有用。为了对用户友好,我们让用户设置分片数量的时候可能不限制必须是 2 的 N 次方,但是内部我们设置分片的时候,将其设置为最近用户输入数字的 2 的 N 次方的值即可。那么如何计算呢?抽象为比较直观的理解就是,找一个数字最左边的 1 的左边一个 1 (大于 N 的最小的 2 的 N 次方),或者是最左边的1(小于N的最大的2的N次方),前提是这个数字本身不是2的n次方。那么,如何找呢?一种思路是,将这个

2021-01-23 07:38:52 12696

原创 每日一面 - 为何我们经常使用 2 的 N 次方作为分片数量?

分片算法经常是计算一个值之后,对于分片个数取模,计算到底使用哪个分片。我们经常看到很多地方高性能的代码设计,都是将分片数量设置为 2 的 N 次方。例如 ForkJoinPool 的任务队列 WorkQueue 的大小,MyCat 的某些分片算法在计算分片的时候对于分片数量如果是 2 的 N 次方也有优化,那么为什么呢?对于 2 的 N 次方取余,相当于对 2 的 N 次方减一取与运算, N 为正整数。为什么呢?通过下图就能很容易理解:十进制中,对于 10 的 N 次方取余,直观来看就是:其实就是将

2021-01-22 07:53:20 12951

原创 每日一面 - Spring Boot 中的 ApplicationContext 的分层是什么意思?

ApplicationContext 是 spring 用来容纳管理 beans 以及其生命周期的容器。ApplicationContext 的分层规定了bean的界限以及可以复用的 bean。关于 ApplicationContext 层级可以参考官方文档(http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-build-an-application-context-hierarchy),这里我们通过一个简单的

2021-01-21 00:47:54 12614

原创 每日一面 - MySQL 大表添加一列

问题参考自: https://www.zhihu.com/question/440231149 ,mysql中,一张表里有3亿数据,未分表,要求是在这个大表里添加一列数据。数据库不能停,并且还有增删改操作。请问如何操作?答案为个人原创以前老版本 MySQL 添加一列的方式:ALTER TABLE 你的表 ADD COLUMN 新列 char(128);会造成锁表,简易过程如下:新建一个和 Table1 完全同构的 Table2对表 Table1 加写锁在表 Table2 上执行 ALTE.

2021-01-20 09:24:20 12449

原创 每日一面 - mysql 大表批量删除大量数据

问题参考自:https://www.zhihu.com/question/440066129/answer/1685329456 ,mysql中,一张表里有3亿数据,未分表,其中一个字段是企业类型,企业类型是一般企业和个体户,个体户的数据量差不多占50%,根据条件把个体户的行都删掉。请问如何操作?答案为个人原创假设表的引擎是 Innodb, MySQL 5.7+删除一条记录,首先锁住这条记录,数据原有的被废弃,记录头发生变化,主要是打上了删除标记。也就是原有的数据 deleted_flag 变成 1.

2021-01-19 08:13:26 12257

原创 每日一面 - 什么是 Safepoint?

我们先来设想下如下场景:当需要 GC 时,需要知道哪些对象还被使用,或者已经不被使用可以回收了,这样就需要每个线程的对象使用情况。对于偏向锁(Biased Lock),在高并发时想要解除偏置,需要线程状态还有获取锁的线程的精确信息。对方法进行即时编译优化(OSR栈上替换),或者反优化(bailout栈上反优化),这需要线程究竟运行到方法的哪里的信息。对于这些操作,都需要线程的各种信息,例如寄存器中到底有啥,堆使用信息以及栈方法代码信息等等等等,并且做这些操作的时候,线程需要暂停,等到这些操作完成

2021-01-18 08:04:30 12221

原创 每日一面 - JVM 何时会 Stop the world

定时进入 SafePoint:每经过-XX:GuaranteedSafepointInterval 配置的时间,都会让所有线程进入 Safepoint,一旦所有线程都进入,立刻从 Safepoint 恢复。这个定时主要是为了一些没必要立刻 Stop the world 的任务执行,可以设置-XX:GuaranteedSafepointInterval=0关闭这个定时,我推荐是关闭。由于 jstack,jmap 和 jstat 等命令,也就是 Signal Dispatcher 线程要处理的大部分命令,都.

2021-01-17 08:22:49 12229

原创 每日一面 - 限制用户设备

问题参考自:https://www.zhihu.com/question/439438146 ,答案为个人原创用户登录,保存30天的免登,只允许两个设备登录,如果有第三个设备登录,踢掉第一个。改密码的时候,所有设备需要下线。这个逻辑怎么实现呢?使用 Redis 存储用户 ,登录的设备实现,利用 ZSET。存储结构如下:每个用户一个 ZSET(假设就是以用户 id 作为 ZSET 的 KEY),里面的 KEY 为设备 id,value 为登录时间戳。当用户登录时,使用 lua 脚本(防止并发导.

2021-01-16 08:30:01 12201

原创 每日一面 - Spring 的 @Import 注解的作用与用法

@Import注解@Import是Spring基于 Java 注解配置的主要组成部分。@Import注解提供了@Bean注解的功能,同时还有原来Spring基于 xml 配置文件里的<import>标签组织多个分散的xml文件的功能,当然在这里是组织多个分散的@Configuration的类。下面将分别说明@Import注解的功能。1. 引入其他的@Configuration假设有如下接口和两个实现类:package com.testinterface ServiceInterfac

2021-01-15 08:08:20 12204

原创 每日一面 - JVM 类型字压缩指针与 JVM 最大内存有何关系?

压缩指针这个属性默认是打开的,可以通过-XX:-UseCompressedOops关闭。首先说一下为何需要压缩指针呢?32 位的存储,可以描述多大的内存呢?假设每一个1代表1字节,那么可以描述 0~2^32-1 这 2^32 字节也就是 4 GB 的内存。但是呢,Java 默认是 8 字节对齐的内存,也就是一个对象占用的空间,必须是 8 字节的整数倍,不足的话会填充到 8 字节的整数倍。也就是其实描述内存的时候,不用从 0 开始描述到 8(就是根本不需要定位到之间的1,2,3,4,5,6,7)因为对象

2021-01-14 10:27:27 12181

原创 每日一面 - MySQL 的双一设置是什么?

问题参考自:https://www.zhihu.com/question/425704691/answer/1524724367 ,答案为个人原创其实就是innodb_flush_log_at_trx_commit和sync_binlog两个参数设置,都设置为 1 就是双 1 设置。MySQL 默认配置就是双 1 配置。innodb_flush_log_at_trx_commit 是 innodb 引擎的配置,sync_binlog 是 MySQL 引擎上层的配置,都是控制磁盘写入策略。MySQL.

2021-01-13 08:23:32 13994

原创 每日一面 - JVM 内存一般包括什么?

我们一般通过两个工具 pmap 还有 jcmd 中的 VM.native_memory 命令去查看 Java 进程内存占用,由于 pmap 命令有点复杂而且很多内存映射是 anon 的,这里采用 jcmd 中的 VM.native_memory 命令,去看一下 JVM 内存的每一部分。Native Memory Tracking:Total: reserved=6308603KB, committed=4822083KB- Java Heap (reserved=41

2021-01-12 07:54:39 12196

原创 每日一面 - sqrt (2)约等于 1.414,如何求sqrt (2)小数点后 10 位

本问题参考自:https://www.zhihu.com/question/410210858/answer/1365984008 答案为个人原创1.从 1.414 向下一位开始,二分法查找平方最接近2的数字。效率比较差。2.使用牛顿迭代法:x初始等于1.414不断令x等于x和2/x的平均数,然后求每次x的平方,看与2的差距这样比之前的二分法要精简很多次运算。这种算法的原理很简单,我们仅仅是不断用(x,f(x))的切线来逼近方程x^2-a=0的根。根号a实际上就是x^2-a=0的一个正.

2021-01-11 09:45:42 12269

原创 每日一面 - 为何hashmap默认的负载因子是0.75?应该是空间和时间的折中,背后的统计原理是什么呢?

1. 为啥需要 负载因子(defaultLoadFactor)现在主流的 HashMap,一般的实现思路都是开放地址法+链地址法的方式来实现。即数组 + 链表的实现方式,通过计算哈希值,找到数组对应的位置,如果已存在元素,就加到这个位置的链表上。在 Java 8 之后,链表过长还会转化为红黑树。红黑树相较于原来的链表,多占用了一倍的空间,但是查询速度快乐一个数量级,属于空间换时间。 同时,链表转换红黑树也是一个耗时的操作。并且,一个效率高的哈希表,这个链表不应该过长。所以,如果数组的很多元素上面已经

2021-01-10 14:08:50 12157

原创 每日一面 - 从 innodb 的索引结构分析,为什么索引的 key 长度不能太长?

本问题参考: https://www.zhihu.com/question/410506694/answer/1368215298 ,答案为个人原创MySQL innoDB引擎索引基于 B+树,B+树有以下特点:图片参考自:链接每个节点中子节点的个数不能超过 N,也不能小于 N/2(不然会造成页分裂或页合并)根节点的子节点个数可以不超过 m/2,这是一个例外m 叉树只存储索引,并不真正存储数据,只有最后一行的叶子节点存储行数据。通过链表将叶子节点串联在一起,这样可以方便按区间查找同时,.

2021-01-09 08:29:44 17522 1

原创 每日一面 - mysql中,innodb表里,某一条数据删除了之后,这条数据会被真实的擦掉吗,还是删除了关系?

以 Compact 行格式为例:总结删除一条记录,数据原有的被废弃,记录头发生变化,主要是打上了删除标记。也就是原有的数据 deleted_flag 变成 1,代表数据被删除。但是数据没有被清空,在新一行数据大小小于这一行的时候,可能会占用这一行。这样其实就是存储碎片,要想减少存储碎片,可以通过重建表来实现(例如对于高并发大数据量表,除了归档,还可以通过利用无锁算法Alter修改字段来重建表增加表性能)。Compact 行格式存储我们来创建一个包含几乎所有基本数据类型的表,其他的例如 geometr

2021-01-08 08:42:17 12467

原创 每日一面 - Java OOM都有哪些,说出几种?

Key TakeAwaysStackOverflowError: 调用栈过深,导致线程栈占用大小超过-Xss(或者是-XX:ThreadStackSize)的限制OutOfMemoryError: Java heap space:堆内存不够用,无法分配更多内存,就会抛出这个异常。OutOfMemoryError: unable to create native thread:这个在创建太多的线程,超过系统配置的极限。如Linux默认允许单个进程可以创建的线程数是1024个。OutOfMemoryE

2021-01-07 07:28:55 12395

原创 通过 JFR 与日志深入探索 JVM - 调试 JVM 的工具 WhiteBox API

在之后的 JFR 事件学习以及调试的过程中,我们会经常用到 WhiteBox API 来触发 JVM 的一些机制或者临界点。例如强制 JVM 现在立刻进行 FullGC 等等。什么是 WhiteBox APIWhiteBox API 是 HotSpot VM 自带的白盒测试工具,将内部的很多核心机制的 API 暴露出来,用于白盒测试 JVM,压测 JVM 特性,以及辅助学习理解 JVM 并调优参数。WhiteBox API 是 Java 7 引入的,目前 Java 8 LTS 以及 Java 11 LT

2021-01-06 21:34:34 33295 1

原创 每日一面 - mysql中,我存十亿个手机号码,考虑存储空间和查询效率,怎么设计?

问题参考自:https://www.zhihu.com/question/438078173,以下解答思路为个人原创首先提出假设:手机号码不会更新,只会插入和删除。查询包括精确查询某个手机号是否存在,以及获取某一号码段的所有手机号假设表只有一个字段,就是手机号 phone,并且设置为主键。如果不设置主键并且没有唯一索引,InnoDB 会给我们自动生成一个隐藏主键列,浪费空间。MyISAM or InnoDB如果插入和删除并不频繁,手机号是提前载入的字典表,而不是用户主动注册而产生的,则 .

2021-01-06 08:08:25 12470

原创 每日一面 - mysql 的自增 id 的实现逻辑是什么样子的?

本问题参考自: https://www.zhihu.com/question/437916819/answer/1661679374, 解答为个人原创Key TakeAwaysInnoDB 引擎中 有三种 AutoIncrement 锁模式:innodb_autoinc_lock_mode=0(traditional lock mode):获取表锁,语句执行结束后释放innodb_autoinc_lock_mode=1(consecutive lock mode,MySQL 8.0 之前默认.

2021-01-05 12:03:38 12283

原创 每日一面 - Redis程序设计中,上百万的新闻,如何实时展示最热点的top10条呢

假设可以使用 MySQL,redis,本地缓存以及MQ。用户量级千万,新闻数据百万,用户数比新闻数还多。用户的操作包括:关注某个新闻获取某个新闻的关注数量获取 top10 热点新闻查询自己关注的新闻。可以推测,获取 top10 热点新闻请求会远大于关注某个新闻的请求。这些请求都不能直接压入数据库,数据库受不了。首先想到的是 Redis 中的 Zset,所有的新闻id作为key放入同一个zset中,用户关注某个新闻,使用 zincrby 给这个新闻分数 +1。读取 top 10的时候,用zr

2021-01-04 09:51:38 12603

原创 每日一面 - java中LinkedTransferQueue和SynchronousQueue有什么区别?

LinkedTransferQueue 是一种 TransferQueue,SynchronousQueue 是一种 BlockingQueue。TransferQueue和BlockingQueueBlockingQueue 是一种阻塞队列,队列是有大小的。队列满的时候,生产者会阻塞。队列空的时候,消费者会阻塞。TransferQueue在BlockingQueue提供的方法基础上,增加了 transfer 方法,就是只有生产者的消息被消费之后,才返回,否则继续阻塞。SynchronousQueu

2021-01-04 09:38:43 12201

原创 每日一面 - java中,描述一下什么情况下,对象会从年轻代进入老年代?

本问题参考自: https://www.zhihu.com/question/437632685, 解答为个人原创Key TakeawayJava 默认启用了分代 GC启用分代 GC 的,在发生 Young GC,更准确地说是在 Survivor 区复制的时候,存活的对象的分代年龄会加1。当分代年龄 = -XX:MaxTenuringThreshold 指定的大小时,对象进入老年代还有动态晋升到老年代的机制,首先根据 -XX:TargetSurvivorRatio (默认 50,也就是 50.

2021-01-03 09:04:05 17027

原创 每日一面 - java中,MinorGC、MajorGC、FullGC 什么时候发生?

引用自: https://www.zhihu.com/question/437493648/answer/1656737915MinorGC 一般指清理 Young space (Eden and Survivor spaces) 的 GC。例如 G1GC 还有 ShenandoahGC 中的 YoungGC. 触发一般是:Allocation Failure: 分配对象失败,空间不足. 内存分配流程,涉及到了 bump-the-pointer, TLAB,Allocation Prematch.

2021-01-02 13:06:50 33624 1

空空如也

张哈希的留言板

发表于 2020-01-02 最后回复 2020-01-17

空空如也

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

TA关注的人 TA的粉丝

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