<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[A14997的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/A14997</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; A14997]]></copyright><item><title><![CDATA[JAVA－最透彻的AQS原理讲解]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/163973943</link><guid>https://blog.youkuaiyun.com/A14997/article/details/163973943</guid><author>A14997</author><pubDate>Sun, 23 Aug 2026 16:39:16 +0800</pubDate><description><![CDATA[通过上面的讲解，应该可以了解到AQS可以很好地管理锁资源抢占，那么它对比synchronized一定更好吗？不一定，synchronized有偏向锁、轻量级锁和重量级锁三个等级，synchronized的性能在无竞争的情况下性能是最好的，只需要对比mark word，AQS的话则是检查state，性能也很快，但是AQS的性能还是略低于synchronized。而synchronized的轻量级锁和AQS的自旋获取线程性能差不多，轻量级锁也是自旋CAS实现的。]]></description><category></category></item><item><title><![CDATA[真正理解Java中volatile的作用和原理]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/163799355</link><guid>https://blog.youkuaiyun.com/A14997/article/details/163799355</guid><author>A14997</author><pubDate>Sun, 16 Aug 2026 17:44:24 +0800</pubDate><description><![CDATA[Volatile关键字的作用不只是实现变量的可见性，它的作用是保证变量的可见性和上下文准确性，以实现多线程操作的可靠性。Volatile的两个特性都是通过内存屏障指令实现的，StoreStore保证了Volatile之前的变量写操作和Volatile变量写操作顺序不会被指令重排破坏，StoreLoad保证了Volatile变量写操作之后马上对其它线程可见，LoadStore和LoadLoad通过禁止指令重排保证了先读取Volatile再进行其它读写操作。]]></description><category></category></item><item><title><![CDATA[史上最细Synchronized实现原理]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/163594032</link><guid>https://blog.youkuaiyun.com/A14997/article/details/163594032</guid><author>A14997</author><pubDate>Sun, 09 Aug 2026 19:03:05 +0800</pubDate><description><![CDATA[synchronized实际上有三种实现状态，在锁升级过程中，会依次从偏向锁、轻量级锁到重量级锁演进。下面会介绍这三种锁状态的实现方式。]]></description><category></category></item><item><title><![CDATA[Java事务传播－派系之争]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/163591547</link><guid>https://blog.youkuaiyun.com/A14997/article/details/163591547</guid><author>A14997</author><pubDate>Sat, 08 Aug 2026 16:09:39 +0800</pubDate><description><![CDATA[调坏了（异常）只把你小碗里的倒掉（回滚到保存点），大锅继续炖；但如果主厨心情不好，把整锅佛跳墙都泼了（主事务回滚），你那碗酱汁就算调好了也得跟着倒进下水道。你还在死记硬背Java事务传播方式吗，你是否为事务传播特性差异难以理解而苦恼吗，下面我将通过一个简单的事务行为分类，让你彻底理解和记住Java的七种事务传播行为。：你看到主厨在炖佛跳墙，嫌油烟大，直接摔围裙走人（报错），要求必须关火你才进厨房。：你端走一口新锅，去旁边单独炒个青菜，炒糊了只倒自己这盘。：你进来帮主厨切菜，切坏了（异常）整锅倒掉。]]></description><category></category></item><item><title><![CDATA[快速理解Java多线程]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/132655227</link><guid>https://blog.youkuaiyun.com/A14997/article/details/132655227</guid><author>A14997</author><pubDate>Sun, 02 Aug 2026 17:34:12 +0800</pubDate><description><![CDATA[答案是，虽然我们需要等待异步线程处理后的返回值，但不意味着我们每提交一个线程任务就要一直等待其执行结束，实际上，我们可以一次性提交十个任务，这十个任务可能会启动十个独立的线程运行，然后，调用者只需要遍历获取这些线程的运行结果即可。然后在需要的时候，去创建这个类并执行start方法以启动一个线程，然后就会在这个线程中运行run方法的内容。实际上Runnable接口实现的方式，是定义了一个线程执行任务，这个实现了runnable接口的类的实例，可以作为new Thread的入参，也可以提供线程池执行。]]></description><category></category></item><item><title><![CDATA[kafka急速入门]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/159576698</link><guid>https://blog.youkuaiyun.com/A14997/article/details/159576698</guid><author>A14997</author><pubDate>Sat, 28 Mar 2026 12:28:58 +0800</pubDate><description><![CDATA[先说结论，kafka是持久化的消息队列框架。接下来，我会以kafka设计者的角色，带你理解其文件目录结构的设计初衷。]]></description><category></category></item><item><title><![CDATA[Redis急速入门]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/159323607</link><guid>https://blog.youkuaiyun.com/A14997/article/details/159323607</guid><author>A14997</author><pubDate>Sun, 22 Mar 2026 16:51:05 +0800</pubDate><description><![CDATA[redis独特的数据结构，不直接使用，是一种基础数据类型。没有指针，但是同时有变长编码（数组不具备的动态节点数据类型和节点长度）的特性。相当于把链表去掉指针，压缩放进一段连续内存中，通过编码的偏移量关联，节省了内存开销。具体结构如下。zlbytes：记录整个压缩列表占用的字节数。zltail：记录尾节点到起始地址的偏移量，便于快速从尾部操作。zllen：记录节点数量（小于 65535 时准确，超过时需遍历）。]]></description><category></category></item><item><title><![CDATA[Zookeeper急速入门-必看核心思想]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/158037586</link><guid>https://blog.youkuaiyun.com/A14997/article/details/158037586</guid><author>A14997</author><pubDate>Fri, 13 Feb 2026 13:13:59 +0800</pubDate><description><![CDATA[假设任意成功就提交，甚至只要leader写入就提交，则可能出现节点宕机，写请求未实施而丢失。leader收到写请求后广播给follower节点，节点先持久化写日志，日志成功写入后即向leader发出ack，此时并未真正实施该写请求，但因为已经持久化日志以用于真正实施，故可以认为发出ack时，节点可以向leader承诺在需要时实施该写操作。节点并不是单纯的数据保存和被动接收命令的角色，节点在收到写请求时，需要判断zxid是否有缺漏，如果出现缺漏则会一直阻塞直到当前zxid之前的所有zxid写请求都已提交。]]></description><category></category></item><item><title><![CDATA[spring三级缓存核心思想]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/157096941</link><guid>https://blog.youkuaiyun.com/A14997/article/details/157096941</guid><author>A14997</author><pubDate>Sun, 18 Jan 2026 13:40:53 +0800</pubDate><description><![CDATA[中间状态可被引用的前提下，初始化A时注入B，发现无法找到B，然后初始化B，此时B要注入A，则此时直接使用A的中间状态作为引用注入即可，然后B就可以完成创建。后续，顺利成章地，A此时便能注入B完成自己的创建。过头去看，三级缓存用来存放工厂方法，方便当你需要时获取其中间状态单例，二级缓存用来存放中间状态的单例，一级缓存用来存放最终使用的单例池。spring三级缓存的工作原理都见过很多了，但是为什么要这么做，这么做为什么就能解决循环依赖问题，还是很少有人能说清楚，笔者今天学习过后分享一点个人的想法。]]></description><category></category></item><item><title><![CDATA[通俗易懂说java设计模式-代理模式]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/125123350</link><guid>https://blog.youkuaiyun.com/A14997/article/details/125123350</guid><author>A14997</author><pubDate>Sat, 04 Jun 2022 19:06:13 +0800</pubDate><description><![CDATA[用通俗简短的语言说清楚什么是代理模式，什么是静态代理和动态代理。简单明了地讲清楚动态代理各部分代码的具体作用，知其然而知其所以然。]]></description><category></category></item><item><title><![CDATA[通俗易懂说java设计模式-装饰器模式]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/125074465</link><guid>https://blog.youkuaiyun.com/A14997/article/details/125074465</guid><author>A14997</author><pubDate>Wed, 01 Jun 2022 13:14:52 +0800</pubDate><description><![CDATA[一个装饰器之所以要继承food类，是要保证装饰器通过装饰food而构造的新对象也是一个food。这么做的原因是什么呢？首先从字面理解，装饰是很轻的动作，一个food装饰完当然应该还是food，其次这么做可以方便对food类的多态使用，并且是实现嵌套调用的关键。装饰器从代码层面来看，首先它要继承被装饰对象的抽象类或接口。继承food类后，我们还需要调用原food的方法和属性，才能够加以装饰，构造出装饰后的food方法和属性。这就是为什么我们要把整个被装饰对象传进来，装饰不是无中生有，而是在原先的基础上进行。.]]></description><category></category></item><item><title><![CDATA[通俗易懂说java设计模式-工厂模式]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/125020729</link><guid>https://blog.youkuaiyun.com/A14997/article/details/125020729</guid><author>A14997</author><pubDate>Tue, 31 May 2022 17:05:56 +0800</pubDate><description><![CDATA[工厂模式，就是将创建对象的过程交给“工厂”，需要创建对象时调用对应工厂类的对象创建方法即可。为什么要使用工厂模式？有些时候我们不能简单地通过“new()”来创建一个对象，我们需要对对象创建进行权限控制、装饰和日志输出等操作，从而灵活地控制对象生产过程。工厂模式一般可分为简单生产模式、工厂方法模式和抽象工厂模式。]]></description><category></category></item><item><title><![CDATA[通俗易懂说java设计模式-策略模式]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/125007755</link><guid>https://blog.youkuaiyun.com/A14997/article/details/125007755</guid><author>A14997</author><pubDate>Fri, 27 May 2022 18:01:48 +0800</pubDate><description><![CDATA[策略模式指的是将策略（完成特定行为的方法）从主业务逻辑中抽离出来的思想。比如一个人早上起床上学的过程，首先刷牙洗脸，然后吃饭，前往学校，到校后上课。前往学校的过程就是一种可以从主业务逻辑中抽离出来的策略。我们既可以选择走路上学，也可以骑单车、父母接送或搭乘网约车，如果不使用策略模式，则主业务逻辑将臃肿不堪，且不利于实现拓展。如果我们将前往学校的行为策略抽象出来作为接口，用不同的策略实现类去实现这个接口，在具体业务逻辑中根据需要选择具体的策略实现类，这样便很好地实现了策略和主业务逻辑地解耦。]]></description><category></category></item><item><title><![CDATA[史上最通俗易懂-什么是泛型]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/125000289</link><guid>https://blog.youkuaiyun.com/A14997/article/details/125000289</guid><author>A14997</author><pubDate>Fri, 27 May 2022 12:44:06 +0800</pubDate><description><![CDATA[不使用泛型的情况下，在定义一个ArrayList类型时，我们可以指定其add方法中接收某种特定类型的参数。但是，如果指定了add只接收特定类型参数，比如String类型，那这个ArraList类的数组对象就只能添加String类型的元素。如果需要存放整型数就需要再定义一个存放整型数的ArrayList类，这降低了代码重用性。所以，我们干脆在定义ArayList类型的时候就不指定add方法接收参数的具体类型，然后在使用的过程中，由用户根据需要指定参数的类型。用一句话来说，“泛型”就是允许一个类中的参数类泛化。]]></description><category></category></item><item><title><![CDATA[通俗易懂说java设计模式-单例模式的实现]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/124914622</link><guid>https://blog.youkuaiyun.com/A14997/article/details/124914622</guid><author>A14997</author><pubDate>Tue, 24 May 2022 21:59:57 +0800</pubDate><description><![CDATA[对某些类来说，其对象在内存中只需要一个，或者必须保证其被访问到的对象始终是同一个，拥有固定的属性和方法，用来完成某些固定而统一的操作。而在开发这些类的时候，如果不加以设计，则仍然可能被使用者多次创建产生多余的或不统一的对象，无意义地在内存中产生多个副本或产生多个不一致的对象。因此我们需要对类进行设计，实现单例模式，即保证某类只有单个实例的模式，实现单例模式有八种方式。

一、饿汉式

为什么叫饿汉式？饿汉式从字面理解就是一有食物就迫不及待地吃东西的状态。实际上，饿汉式的单例模式实现便是在类的加载中便马上莫不]]></description><category></category></item><item><title><![CDATA[类图关系中关联关系和依赖关系的区别]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/124908824</link><guid>https://blog.youkuaiyun.com/A14997/article/details/124908824</guid><author>A14997</author><pubDate>Sun, 22 May 2022 11:58:24 +0800</pubDate><description><![CDATA[类图关系中关联关系和依赖关系的区别]]></description><category></category></item><item><title><![CDATA[Java抽象类有什么用]]></title><link>https://blog.youkuaiyun.com/A14997/article/details/124894998</link><guid>https://blog.youkuaiyun.com/A14997/article/details/124894998</guid><author>A14997</author><pubDate>Sat, 21 May 2022 10:39:23 +0800</pubDate><description><![CDATA[假设“猫”、“狗”和“鸟”等类各自实现其吃饭、喝水、玩耍和洗澡等方法，虽然不同动物吃的饭、喝的水、玩耍项目和洗澡水热度等要求不尽相同，但养这些动物的人每天对待这些动物的业务逻辑是完全一致的。比如喂猫吃饭、喝水，和猫一起玩和给猫洗澡，对狗和鸟实现的也是这些操作。如果不考虑代码可读性和可维护性的话，可能会得到下面的代码。......]]></description><category></category></item></channel></rss>