<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[CringKong的博客]]></title><description><![CDATA[学习速度永远跟不上技术发展速度，更何况技术已经发展了几十年]]></description><link>https://blog.youkuaiyun.com/CringKong</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; CringKong]]></copyright><item><title><![CDATA[一次OpenJDK Bug导致线上问题的排查实践]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/126753875</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/126753875</guid><author>CringKong</author><pubDate>Wed, 07 Sep 2022 21:16:02 +0800</pubDate><description><![CDATA[本次问题排查过程中，遇到了一些超出平常接触到的问题，也出现了想重启服务器尝试“解决”问题的错误思路，同时也因为这些障碍，我萌发了更多思路、借助了更多的新工具，比如说UMP平台新提供的链路追踪功能，就是我破局的一个重要倚赖。出现了匪夷所思的问题，首先要保留好问题现场，比如说将VM堆和线程堆栈Dump保存，保存线上日志和GC信息等，特别是一些不能必现的问题，更需要问题现场才能进行排查，盲目的尝试重启解决问题，反而会掩盖存在的问题。]]></description><category></category></item><item><title><![CDATA[入侵JVM?Java Agent原理浅析和实践（下）]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/120841043</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/120841043</guid><author>CringKong</author><pubDate>Tue, 19 Oct 2021 10:28:49 +0800</pubDate><description><![CDATA[声明：本文首发于京东零售技术公众号，为博主本人撰写投稿。
运行时修改字节码
了解到上述机制以后，我们可以通过在目标JVM运行时对其中的类进行重新定义，做到运行时插桩代码。
我们知道ASM是一个字节码修改框架，因此就可以在类转换器中，对原本类的字节码进行修改，然后再对这个类进行重定义(retransform)。
首先我们实现ClassFileTransformer接口，前文中在transform方法中并没有对于字节码进行修改，只是单纯的打印了一些信息，既然需要对字目标类的节码进行修改，我们需要了解下Class]]></description><category></category></item><item><title><![CDATA[入侵JVM?Java Agent原理浅析和实践（中）]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/120840827</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/120840827</guid><author>CringKong</author><pubDate>Tue, 19 Oct 2021 10:18:41 +0800</pubDate><description><![CDATA[声明：本文首发于京东零售技术公众号，为博主本人撰写投稿。
JVM运行时Agent
在JDK1.6版本中，SUN更进一步，提供了可以在JVM运行时代理的能力，和启动时代理类似，只需要满足：

JAR包的MANIFEST.MF清单文件中定义Agent-Class属性，指定一个类，加入Can-Redefine-Classes 和 Can-Retransform-Classes 选项。
JAR包中包含清单文件中定义的这个类，类中包含agentmain方法，方法逻辑可以自己实现

运行时Agent可以在JVM运行时动]]></description><category></category></item><item><title><![CDATA[入侵JVM?Java Agent原理浅析和实践（上）]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/120840369</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/120840369</guid><author>CringKong</author><pubDate>Tue, 19 Oct 2021 10:11:42 +0800</pubDate><description><![CDATA[声明：本文首发于京东零售技术公众号，为博主本人撰写投稿。
前言：
在平时的开发中，我们不可避免的会使用到Debug工具，JVM作为一个单独的进程，我们使用的Debug工具可以获取JVM运行时的相关的信息，查看变量值，甚至加入断点控制，还有我们平时使用JDK自带的JMAP、JSTACK等工具，可以在JVM运行时动态的dump内存、查询线程信息，甚至一些第三方的工具，比如说京东内部使用的JEX、pfinder，阿里巴巴的Arthas，优秀的开源的框架skywalking等等，也可以做到这些，那么这些工具究竟是通]]></description><category></category></item><item><title><![CDATA[Log4j2异步日志不打印问题]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/120752591</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/120752591</guid><author>CringKong</author><pubDate>Wed, 13 Oct 2021 21:59:42 +0800</pubDate><description><![CDATA[今天在做项目maven依赖关系优化时，遇到一个问题，项目可以正常启动，但是线上的日志却完全消失了。
1、Log框架冲突？
根据以往踩坑经验，怀疑是因为maven依赖的调整，有第三方包中依赖的log框架被加载了，从而导致项目原本使用的log4j2包没有被加载，因此排查了一下，使用idea的maven helper插件排查发现，有个好兄弟的包里引入了：

这里不得不吐槽一句，提供给别人用的sdk包里，能别夹这种无用私货就别夹，一个slf4j-api包就够用了，乱引入依赖会导致别人的项目出问题嗷！
于是我心里暗暗]]></description><category></category></item><item><title><![CDATA[Spring集成ES客户端（7.5.2）]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/120227711</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/120227711</guid><author>CringKong</author><pubDate>Fri, 10 Sep 2021 18:33:50 +0800</pubDate><description><![CDATA[由于新版的ES逐渐放弃了对于Java TCP客户端的支持和维护，而是更推荐使用REST Client进行集群的操作，Springboot项目可以使用starter方便的集成使用，但是单纯的Spring项目并不能很优雅的直接使用RestHighLevelClient进行操作，因此需要手动封装一个FactoryBean进行集成。
1、封装Spring的FactoryBean
@Setter
@Slf4j
public class EsClientFactoryBean implements FactoryBea]]></description><category></category></item><item><title><![CDATA[ajax传输Json的正确方式]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/104541930</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/104541930</guid><author>CringKong</author><pubDate>Thu, 27 Feb 2020 18:42:12 +0800</pubDate><description><![CDATA[1.jquery的方式
let data = {
	"name" : "xxx",
	"age"  : 20
}
$.ajax({
    url: 'localhost:8080/api/xxxxx',
    dataType: 'json',
    type: 'post',
    data: JSON.stringify(data),
    contentType: 'applica...]]></description><category></category></item><item><title><![CDATA[Tomcat日志乱码解决]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/103922058</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/103922058</guid><author>CringKong</author><pubDate>Fri, 10 Jan 2020 15:58:06 +0800</pubDate><description><![CDATA[最近一直在用Springboot，很少再


]]></description><category></category></item><item><title><![CDATA[Redis实践-存储Java对象]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/103533394</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/103533394</guid><author>CringKong</author><pubDate>Mon, 16 Dec 2019 21:43:43 +0800</pubDate><description><![CDATA[Redis作为目前主流的缓存数据库，提供了丰富的数据结构，这次做的项目里我们大量使用了Redis作为数据缓存，甚至在某些场景下直接作为了数据库使用（当然这是建立在公司内部基础组件足够可靠的前提下），由于项目是从零开始，在使用Redis的过程中，遇到了一些设计上的挑战和问题，因此特别在博客里记录下来。
最基础的肯定就是Java对象的存储，使用SQL型数据库的时候，可以借助ORM框架直接进行把Java...]]></description><category></category></item><item><title><![CDATA[Log4j2配置以及滚动日志文件]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/103483043</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/103483043</guid><author>CringKong</author><pubDate>Thu, 12 Dec 2019 21:32:23 +0800</pubDate><description><![CDATA[最近项目里用到了Log4j2，在这里咱们就不谈Log4j2性能了，可以看一下官方给的测评图，真香。

但是使用时因为和Log4j配置上有很大区别，也踩了不少坑，这里总结一下。
1.包依赖
使用Log4j2首先要引入Log4j2的包依赖，这里以maven依赖为例。
            &lt;dependency&gt;
                &lt;groupId&gt;org.ap...]]></description><category></category></item><item><title><![CDATA[静态代理和动态代理]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/101108652</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/101108652</guid><author>CringKong</author><pubDate>Sat, 21 Sep 2019 15:29:35 +0800</pubDate><description><![CDATA[静态代理和动态代理，都是基于代理模式实现的一种对于类的方法的增强。
静态代理
所谓静态代理，其实就是在编译期完成代理（JAVA术语中喜欢把编译期完成的东西叫做静态XX），就是我们之前写的代理模式，被代理类和代理类实现同一个接口，然后代理类通过依赖被代理类，实现方法的增强。
public class StaticProxy {

	static interface Image{
		void dis...]]></description><category></category></item><item><title><![CDATA[HashMap扩容流程]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/101104354</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/101104354</guid><author>CringKong</author><pubDate>Sat, 21 Sep 2019 15:14:30 +0800</pubDate><description><![CDATA[文章目录为什么扩容？什么时候扩容？如何扩容？
今天在和同时讨论HashMap的时候，提到了扩容和冲哈希的事情，然后我发现大家都是一种半懂不懂的状态。于是回去做了一番功课，写下这篇文章。
HashMap的扩容，又被很多人叫rehash、重哈希，我本人是很反对这个叫法的，事实上HashMap扩容的时候，Node中存储的Key的hash值并没有发生变化，只是Node的位置发生了变化。
首先说为什么需要扩...]]></description><category></category></item><item><title><![CDATA[编译器重排序]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/99759216</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/99759216</guid><author>CringKong</author><pubDate>Tue, 20 Aug 2019 10:51:06 +0800</pubDate><description><![CDATA[在一些讲Java并发编程的书中，经常会出现JMM内存模型、volatile关键字、重排序、乱序执行等字眼，导致了有些刚开始学习Java并发编程的小伙伴一脸懵逼：这都是啥啊？
文章目录1. 什么是编译器重排序1.1 定义1.2 举个例子1.3 重排序原因1.4 不仅仅是重排序2. 如何禁止？2.1 编译器屏障2.2 禁止重排序2.3 禁止寄存器存/取值2.4 volatile(C/C++)3. 结束...]]></description><category></category></item><item><title><![CDATA[伪共享--多线程性能的破坏者]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/97960206</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/97960206</guid><author>CringKong</author><pubDate>Wed, 31 Jul 2019 21:06:30 +0800</pubDate><description><![CDATA[文章目录前言1.从CPU说起1.1 CPU缓存1.2 缓存行1.3 MESI协议2. 伪共享3. 解决方案4. 后记
前言
前几天看到了伪共享这个概念，但是并没有去做深入的了解，今天又看到了这个概念，才想起来要好好研究一下伪共享究竟是个什么东西，反而在学习的过程中又引发了我对JMM(Java内存模型)的思考，前几天有个同事分享了JMM相关内容，当时我感觉自己已经比较了解了，但是今天来看似乎并没有能...]]></description><category></category></item><item><title><![CDATA[关于equals和hashCode，看这一篇真的就够了]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/89429269</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/89429269</guid><author>CringKong</author><pubDate>Sun, 21 Apr 2019 14:27:54 +0800</pubDate><description><![CDATA[这几天在尝试手撸一个类似Lombok的注解式代码生成工具，用过Lombok的小伙伴知道，Lombok可以通过注解自动帮我们生产equals()和hashCode()方法，因此我也想实现这个功能，但是随着工作的深入，我发现其实自己对于equals()和hashCode()的理解，也处在一个很低级的阶段。
因此痛定思痛，进行了一番深入学习，才敢来写这篇博客。
文章目录1、equals在Java中含义2...]]></description><category></category></item><item><title><![CDATA[Quartz源码分析（下）]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/89423021</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/89423021</guid><author>CringKong</author><pubDate>Sat, 20 Apr 2019 20:34:30 +0800</pubDate><description><![CDATA[上一篇文章中，我们分析了Quartz框架的Job和Trigger的源码实现，上篇也说到，Quartz的核心代码是Scheduler，在本篇中，我们会分析一下Scheduler的源码实现。

文章目录1、核心入口类：QuartzScheduler2、调度线程类：QuartzSchedulerThread3、任务执行线程池：SimpleThreadPool4、任务执行线程类：WorkerThread5...]]></description><category></category></item><item><title><![CDATA[IDEA中Maven配置问题全解决]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/89414445</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/89414445</guid><author>CringKong</author><pubDate>Sat, 20 Apr 2019 11:04:16 +0800</pubDate><description><![CDATA[最近换了工作环境，以前的IDEA配置都没了，记得上次配置自己的IDEA还是在两年前？然后构建Maven项目时遇到了一些小插曲，记录下解决方案（PS:新手教程向）
1. idea中maven默认配置的坑
首先打开File-&gt;Settings

这里可以直接搜索maven，就可以进入idea的Maven配置选项。

我这里是idea默认的maven配置，可以看到默认的Maven目录是idea内置...]]></description><category></category></item><item><title><![CDATA[Quartz源码分析（上）]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/89290582</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/89290582</guid><author>CringKong</author><pubDate>Sat, 13 Apr 2019 23:06:13 +0800</pubDate><description><![CDATA[文章目录1.一个想法2.Quartz总体架构2.1 Job和JobDetail2.2 Trigger2.3 JobStore3.上篇小结
1.一个想法
最近项目中用到了Quartz框架，作为定时任务的调度框架，无论是和Spring的完美融合还是直接使用Java代码来进行使用，可以说都非常的简单且稳定，某天突然想到如果没有Quartz框架，我们应该如何实现一个纯Java代码的定时任务调度框架呢？

...]]></description><category></category></item><item><title><![CDATA[到北京好远]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/89062754</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/89062754</guid><author>CringKong</author><pubDate>Sun, 07 Apr 2019 00:28:45 +0800</pubDate><description><![CDATA[我不知道应该怎么表达现在的心情，是悲哀还是无奈。
两小时前，我在某社交软件上随机匹配到一个女孩子，语音连麦，刚开始我没有抱着任何想法，只是她说觉着我的声音特别好听，我就和她有一句没一句的聊着，她让我唱首歌，我尬唱了张国荣的《当爱已成往事》，没有特别的原因，只是因为我特别喜欢《霸王别姬》，没想到后来会和她继续聊下去。
我不知道她叫什么。她是一个十八岁的女孩子，是江西人。之前我对江西没有太多的印象，只...]]></description><category></category></item><item><title><![CDATA[Java线程池源码分析]]></title><link>https://blog.youkuaiyun.com/CringKong/article/details/88936953</link><guid>https://blog.youkuaiyun.com/CringKong/article/details/88936953</guid><author>CringKong</author><pubDate>Sun, 31 Mar 2019 22:17:35 +0800</pubDate><description><![CDATA[文章目录一.Java线程池原理分析二.Java线程池源码分析1.接口继承关系2.核心类ThreadPoolExecutor2.1 入口方法 execute -- 调度器2.2 添加线程方法 addWorker2.3 Worker 内部类2.4 核心方法 runWorker -- 发动机2.5 任务获取方法 getTask3.流程回顾
一.Java线程池原理分析
上一篇是 线程池原理分析，只是说明了...]]></description><category></category></item></channel></rss>