<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[phaeton_lai的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/phaeton_lai</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; phaeton_lai]]></copyright><item><title><![CDATA[JVM 类加过程及类加载器简介]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/125470824</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/125470824</guid><author>phaeton_lai</author><pubDate>Sun, 26 Jun 2022 17:33:08 +0800</pubDate><description><![CDATA[简单了解类加载过程，详细介绍类加载器的双亲委派模型]]></description><category></category></item><item><title><![CDATA[Redis 系列--高可用&集群方案]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/119669451</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/119669451</guid><author>phaeton_lai</author><pubDate>Tue, 17 Aug 2021 15:14:56 +0800</pubDate><description><![CDATA[一般我们在使用 Redis 时，鉴于单机存在的单点故障，容量有限，高并发压力问题，都不会采用单机模式，那么该如何设计 Redis 的部署方式来解决诸如单点故障，容量有限，高并发压力这样的问题呢？
首先来看下单点故障的问题，单点故障一般就是指提供服务的节点或实例只有一个，当这个节点出现故障就导致这个服务不可用。解决这种问题一般会引入主备或主从的概念。主备模式就是主机向外提供服务，备机从主机同步数据，只有当主机出现故障时，备机才代替主机向外提供服务。主从模式下，从节点从主节点同步数据，同时也提供部分服务（对于主]]></description><category></category></item><item><title><![CDATA[Redis 系列--缓存问题（缓存更新以及缓存穿透/缓存击穿/缓存雪崩）]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/119033063</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/119033063</guid><author>phaeton_lai</author><pubDate>Fri, 23 Jul 2021 15:33:01 +0800</pubDate><description><![CDATA[使用 Redis 作为缓存时，一般的设计方案是：用户发起查询请求时，先从缓存中进行查询，如果数据存在则直接返回，否则查询数据库后更新缓存并返回。

这种设计可以满足并发量较小的系统要求，当并发量增大或者遇到恶意攻击时，则可能导致大量请求达到数据库导致数据库压力增大甚至不可用。为了最大可能的减小数据库压力，在使用 Redis 做缓存时，就需要做周全的设计，其中要解决的比较典型的问题就是缓存穿透，缓存击穿，缓存雪崩。
1. 缓存穿透
缓存穿透是指用户不断请求缓存和数据库中都没有的数据。这时的用户很可能是攻击者，]]></description><category></category></item><item><title><![CDATA[转载《高性能网关设计实践》]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/107385233</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/107385233</guid><author>phaeton_lai</author><pubDate>Thu, 16 Jul 2020 16:05:06 +0800</pubDate><description><![CDATA[原文地址：https://mp.weixin.qq.com/s/oAh5IojX_iz01nbf8mJMSQ

]]></description><category></category></item><item><title><![CDATA[转载《分布式ID生成方案总结》]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/107377408</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/107377408</guid><author>phaeton_lai</author><pubDate>Thu, 16 Jul 2020 10:26:23 +0800</pubDate><description><![CDATA[原文地址：https://www.cnblogs.com/yuandengta/p/12697595.html

]]></description><category></category></item><item><title><![CDATA[转载《高性能短链接设计》]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/107375590</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/107375590</guid><author>phaeton_lai</author><pubDate>Thu, 16 Jul 2020 09:17:48 +0800</pubDate><description><![CDATA[文章地址：https://mp.weixin.qq.com/s/YTrBaERcyjvw7A0Fg2Iegw

]]></description><category></category></item><item><title><![CDATA[Redis 系列--Jedis 源码解读]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/107338686</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/107338686</guid><author>phaeton_lai</author><pubDate>Wed, 15 Jul 2020 16:55:10 +0800</pubDate><description><![CDATA[Jedis 作为 Redis 官方推荐的三个客户端之一，相比于其他两个（Lettuce，Redisson）而言，它提供最基本的客户端功能，也因此使得它具备简单和轻量的特性。此外，它也是线程不安全的客户端，因此不适用在多线程场景中。本篇我们通过对其源码的阅读来了解 Redis 的客户端是如何进行工作的，同时也去找出它线程不安全的原因。


版本说明：本片源码解读基于 Jedis-3.3.0，请注意区分。

1. 初始化
首先我们从 Jedis 的基本使用说起，最简单的使用方式如下：
Jedis jedis .]]></description><category></category></item><item><title><![CDATA[Redis 系列--持久化]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/107110919</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/107110919</guid><author>phaeton_lai</author><pubDate>Fri, 03 Jul 2020 19:34:33 +0800</pubDate><description><![CDATA[Redis 持久化是面试中的热门，重要性不言而喻。对开发者来说，掌握 Redis 的持久化不仅可以从容应对面试，在实际工作中对 Redis 的使用也有重要的指导意义。

Redis 的持久化大体上可以分为三种：RDB，AOF 和混合持久化。RDB 和 AOF 持久化机制各有千秋，混合持久化将两者结合取其精华。
1. RDB
RDB 的持久化方式是对 Redis 内存数据快照进行序列化，因此当 Redis 缓存的数据比较大时，这将是一个很耗时的操作，耗时一方面是在对数据的序列化上，另一方面是在数据的刷盘上。.]]></description><category></category></item><item><title><![CDATA[Redis 系列--布隆过滤器]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/106963364</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/106963364</guid><author>phaeton_lai</author><pubDate>Sat, 27 Jun 2020 14:26:33 +0800</pubDate><description><![CDATA[当我们在使用 Redis 作为缓存时，一个需要考虑的问题就是缓存穿透，缓存穿透有多种类型，不同的类型也有不同的解决方案，布隆过滤器作为一种解决方案之一。布隆过滤器主要用于判断某个元素是否包含在某个超大的元素集合之中。当元素的集合大到一定程度时，我们将元素一一存储再通过查找判断，是非常消耗存储资源，同时性能也是非常低下的，这种场景正是布隆过滤器的用武之地。


版本说明：本篇基于 Redis-5.0.8 以及 RedisBloom-2.0.0。

1. 准备
Redis-5.0.8 官方地址：Redis-5.]]></description><category></category></item><item><title><![CDATA[设计模式系列--代理篇]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/106892768</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/106892768</guid><author>phaeton_lai</author><pubDate>Mon, 22 Jun 2020 11:01:07 +0800</pubDate><description><![CDATA[代理模式属于 GoF 中的结构型设计模式。也是我们最常见到的设计模式之一，典型的 Controller、Service、Dao 分层设计中，上层就是对下层的静态代理；Spring 中 AOP 的实现是基于动态代理。

代理模式起到保护被代理对象的目的，同时对被代理功能进行增强，同时由于代理对象的引入，增加了系统的复杂度，也使类的调用变得复杂。代理模式分为静态代理和动态代理两种。
1. 静态代理
静态代理适合对固定功能的代理，实现也比较简单，只需要代理对象持有被代理对象的引用，在被代理对象现有功能的基础上进.]]></description><category></category></item><item><title><![CDATA[MyBatis 工作原理解析]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/106861066</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/106861066</guid><author>phaeton_lai</author><pubDate>Sat, 20 Jun 2020 19:59:54 +0800</pubDate><description><![CDATA[MyBatis 作为一个轻量的 ORM 框架，与 Hibernate 相比，它的学习成本相对较低，尤其适合初级开发使用。本篇我们将介绍原生 MyBatis 的工作原理，并从设计模式的角度去分析其设计。


版本说明：本次源码解读基于 3.5.1 版本，请注意区分版本差异。

1. 原生 API 的基本使用
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getRe.]]></description><category></category></item><item><title><![CDATA[计算机网络系列--TCP 篇]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/106341984</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/106341984</guid><author>phaeton_lai</author><pubDate>Tue, 26 May 2020 16:44:59 +0800</pubDate><description><![CDATA[TCP 是因特网协议栈中运输层（传输层）常用的协议，该协议的全称为 Transmission Control Protocol（传输控制协议），它提供了一种可靠的数据传输，而因特网协议栈中运输层的另一种常用的协议则不提供可靠的数据传输，它在网络层提供的服务基础上不提供不必要的服务。本篇我们将从 TCP 的流量控制和拥塞控制两个方面简单介绍 TCP 可靠数据传输的实现原理，顺便简单介绍一下 TCP 的连接管理。

0. TCP 报文段（Segment）结构

源端口：发送方应用程序所在的端口；
目的端口：接.]]></description><category></category></item><item><title><![CDATA[设计模式系列--原型&建造者]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/106303583</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/106303583</guid><author>phaeton_lai</author><pubDate>Sat, 23 May 2020 18:46:39 +0800</pubDate><description><![CDATA[原型模式与建造者模式都属于创建型的模式，也是比较常见的模式。

1. 原型模式
原型模式常常用于复杂对象的复制，常常将需要用到原型模式的类设计成 Cloneable，这种方式实现的事浅克隆。如果需要实现深克隆，则需要将其成员对应的类也设计成 Cloneable，并进行递归，这种方式比较繁琐，通常我们使用一种简便的方式——序列化和反序列化，采用这种方式要求我们将需要序列化的类及其成员对应的类设计成 Seriable。
public class PrototypeBean implements Cloneab.]]></description><category></category></item><item><title><![CDATA[JUC 源码解读系列--ThreadLocal 篇]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/106109499</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/106109499</guid><author>phaeton_lai</author><pubDate>Thu, 14 May 2020 17:09:03 +0800</pubDate><description><![CDATA[ThreadLocal 一般被用作变量在单个线程中的副本。每个线程都持有同一个变量的副本，并且可以对这个副本进行修改而不影响其他线程对此变量的使用。

我们使用 ThreadLocal 时，一般都是采用匿名内部类的形式，通过覆盖 initValue() 方法进行副本的初始化。在使用过程中可以对副本进行删改查操作，分别对应 remove()、set()、get() 方法。
1. initValue()
// 默认的初始值为 null，此方法一般被子类覆盖
protected T initialValue().]]></description><category></category></item><item><title><![CDATA[设计模式系列--单例篇]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/106103325</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/106103325</guid><author>phaeton_lai</author><pubDate>Wed, 13 May 2020 19:07:02 +0800</pubDate><description><![CDATA[单例模式是我们日常接触的最常见的一种创建型设计模式，spring IoC 容器中的 bean 实例默认就是单例的。采用单例模式可以降低对象的内存开销。本篇主要从单例的常见实现方式及各种方式存在的问题进行分析。

单例的特点：

私有化构造方法；
全局唯一的实例；
对外提供唯一实例的访问点。

1. 懒汉式单例
懒汉是单例顾名思义就是延迟实例化，只在使用的时候才进行实例化。
下面这种方式的懒汉式单例是懒汉式单例的常见实现方式，这种方式需要我们自己编码来保证线程安全，同时还要防止暴力反射对单例的破坏。
pub.]]></description><category></category></item><item><title><![CDATA[设计模式系列--工厂方法&抽象工厂篇]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/106087032</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/106087032</guid><author>phaeton_lai</author><pubDate>Wed, 13 May 2020 15:19:20 +0800</pubDate><description><![CDATA[工厂方法模式和抽象工厂模式都属于创建型的设计模式。我们主要在对象的创建逻辑比较复杂的情况下使用这两种模式来隐藏创建的细节，这两种模式针对的产品的复杂度不同，但又有很大的相似，因此本篇将两者放到一起来加深对二者的理解。

在介绍这两种设计模式之前，我们先了解一下简单工厂模式，这种模式不在 GoF 23 种设计模式之列。
1. 简单工厂模式
简单工厂模式适用于产品等级比较简单的系列对象的创建。
这里需要先了解两个重要的概念，产品等级结构和产品族。
产品等级结构可以看作是同一类型的产品的集合，比如手机，有华为品.]]></description><category></category></item><item><title><![CDATA[设计模式系列--软件设计原则篇]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/106029135</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/106029135</guid><author>phaeton_lai</author><pubDate>Mon, 11 May 2020 19:30:40 +0800</pubDate><description><![CDATA[七大软件设计原则是设计模式的指导思想，也是我们编程时需要权衡并遵循的准则，在这些准则的约束下，使得我们的程序更加的健壮。

1. 开闭原则
定义：一个软件实体如类、模块和函数应该对扩展开放，对修改关闭。
定义补充：用抽象构建框架，用实现扩展细节。
优点：提高软件系统的可复用性以及维护性。
2. 依赖倒置原则
定义：高层模块不应该依赖低层模块，二者都应该依赖其抽象。
定义补充：抽象不应该依赖细节，细节应该依赖抽象。
针对接口编程，不要针对实现编程。
优点：可以减少类间的耦合性、提高系统稳定性，提高代码可读性.]]></description><category></category></item><item><title><![CDATA[Java 集合框架源码解读系列--Stack 篇]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/106008037</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/106008037</guid><author>phaeton_lai</author><pubDate>Fri, 08 May 2020 22:57:50 +0800</pubDate><description><![CDATA[Stack 继承了 Vector，其中的压栈及弹栈操作也只是复用了父类中既有的方法。

public
class Stack&lt;E&gt; extends Vector&lt;E&gt; {
    /**
     * Creates an empty Stack.
     */
    public Stack() {
    }

    /**
     * Pushes an item onto the top of this stack. This has exactly
     * .]]></description><category></category></item><item><title><![CDATA[Java 集合框架源码解读系列--Vector 篇]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/105961448</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/105961448</guid><author>phaeton_lai</author><pubDate>Wed, 06 May 2020 23:43:33 +0800</pubDate><description><![CDATA[Vector 作为一款古老的集合工具（since JDK1.0），从 JDK1.2 开始被改造成 List 的实现加入集合框架。它的实现基本与ArrayList相同，主要区别在于它是一个线程安全的集合。

1. 属性及构造
/**
 * The array buffer into which the components of the vector are
 * stored. The capa...]]></description><category></category></item><item><title><![CDATA[Java 集合框架源码解读系列--LinkedList 篇]]></title><link>https://blog.youkuaiyun.com/phaeton_lai/article/details/105957392</link><guid>https://blog.youkuaiyun.com/phaeton_lai/article/details/105957392</guid><author>phaeton_lai</author><pubDate>Wed, 06 May 2020 20:44:20 +0800</pubDate><description><![CDATA[1. 简介
LinkedList 实现了 List 和 Deque 接口，Deque 是 Double Ended Queue 的缩写，从名字就可以看出，Deque 是支持对其两端进行操作的队列，它继承了 Queue 接口，在普通队列的基础上进行了扩展，增加了一些对队列首尾进行操作的方法。


2. 属性及构造
// 链表中节点的数量
transient int size = 0;

/**
 *...]]></description><category></category></item></channel></rss>