<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[wenpan的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/Hellowenpan</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; Hellowenpan]]></copyright><item><title><![CDATA[Go 语言 GMP 调度模型深度解析]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/155674217</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/155674217</guid><author>Hellowenpan</author><pubDate>Sun, 07 Dec 2025 16:04:30 +0800</pubDate><description><![CDATA[本文深入解析Go语言的GMP调度模型，包括基础概念、核心数据结构、调度流程和优化机制。GMP模型通过Goroutine（协程）、Machine（线程）和Processor（逻辑处理器）的协同工作，实现高效并发调度。文章详细介绍了GMP三组件的定义与关系，从源码层面分析了关键结构体字段，并通过精简的Mermaid图表展示了Goroutine创建、调度执行、阻塞恢复和抢占式调度的完整流程。同时阐述了工作窃取、内存隔离和资源池化等核心优化机制，最后结合实际场景分析了协程池的使用决策，为理解Go语言高并发特性提供了]]></description><category></category></item><item><title><![CDATA[IDEA搭建JDK源码学习环境（可添加注释、修改、debug）]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/135893930</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/135893930</guid><author>Hellowenpan</author><pubDate>Sun, 28 Jan 2024 12:43:40 +0800</pubDate><description><![CDATA[IDEA搭建JDK源码学习环境（可添加注释、修改、debug） 
工程详情见：https://github.com/wenpanwenpan/study-source-jdk1.8.0_281]]></description><category></category></item><item><title><![CDATA[如何加速spring/springboot应用启动速度]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/132008595</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/132008595</guid><author>Hellowenpan</author><pubDate>Sun, 30 Jul 2023 16:43:48 +0800</pubDate><description><![CDATA[注解标注在某些需要在启动过程中异步初始化的方法上才能实现启动过程中异步执行。自动探测所有可异步初始化的功能待实现（因为要进行依赖关系分析，比如在执行异步初始化某个类时，该类依赖关系非常复杂，并且可能他所依赖的某些bean还为被spring 容器创建，那么此时就需要去创建依赖的bean，且分析依赖树。）使用单独线程异步执行的能力，加快 Spring 上下文加载过程，提高应用启动速度。注解标注到需要异步执行的初始化方法上即可实现应用启动过程中异步初始化。模块提供了通过配置的可选项，将 Bean 的初始化方法（]]></description><category></category></item><item><title><![CDATA[基于幂等表思想的幂等实践]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/128689685</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/128689685</guid><author>Hellowenpan</author><pubDate>Sat, 14 Jan 2023 21:38:44 +0800</pubDate><description><![CDATA[极端情况下，如果插入幂等记录成功，并且正常执行了业务流程，此时更新幂等状态为success时出现异常（比如存储幂等记录的存储介质宕机了），此时是否需要处理该异常，还是说抛出异常中断流程？是否需要设定【最大的处理时间】，比如我们期望接口最大处理时间为1小时（也就是说幂等记录处理processing状态的时间最大为1h），如果超过这个时间，那么认为这不是一种正常的case，下次重试请求时应该尝试恢复业务执行。获取指定的业务key作为唯一的幂等键，构建幂等记录（此时幂等记录status为处理中（]]></description><category></category></item><item><title><![CDATA[springboot1.x和2.x将配置属性绑定到对象上]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/128166638</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/128166638</guid><author>Hellowenpan</author><pubDate>Sat, 03 Dec 2022 21:18:29 +0800</pubDate><description><![CDATA[在基于springboot进行封装自定义框架或对某个开源框架进行二次改造时我们经常会涉及到将或者中配置的属性绑定到某个类对应的属性上]]></description><category></category></item><item><title><![CDATA[利用存储过程造测试数据]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/128166438</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/128166438</guid><author>Hellowenpan</author><pubDate>Sat, 03 Dec 2022 21:03:24 +0800</pubDate><description><![CDATA[开发过程中我们往往会遇到需要向数据库插入几千或几万条数据以测试某个功能，或者为了复现生产的某个bug而需要在测试环境造大量的数据的需求，此时便可以通过存储过程来直接向数据库某张表里生成指定条数的测试数据！！！
②、生成指定长度的随机数字的函数

按照入参和，生成该区间的随机数字


2.创建存储过程

该存储过程中会调用上面的函数生成指定长度的随机字符串
该存储过程在调用时根据传入的入参可以控制生成的数据条数


3. 查看存储过程

4. 调用存储过程

5.删除存储过程

6.问题
创建函数，假如报错：]]></description><category></category></item><item><title><![CDATA[一台服务器最大能支持多少条TCP连接]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/127717906</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/127717906</guid><author>Hellowenpan</author><pubDate>Sun, 06 Nov 2022 16:59:34 +0800</pubDate><description><![CDATA[来控制，默认大小是128，当两台机器离的非常近，但是建立连接的并发又非常高时，可能会导致半连接队列或全连接队列溢出，进而导致server端丢弃握手包。上面讨论的都是进建立连接的理想情况，在现实中如果有频繁的数据收发和处理（比如：压缩、加密等），那么一台服务器能支撑1000连接都算好的了，所以一台服务器能支撑多少连接还要结合具体的场景去分析，不能光靠理论值去算。，所以Linux系统基于安全角度考虑（比如：有用户进程恶意的打开无数的文件描述符，那不得把系统搞奔溃了），在多个位置都限制了可打开的。]]></description><category></category></item><item><title><![CDATA[从内核角度看网络包发送流程]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/127709641</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/127709641</guid><author>Hellowenpan</author><pubDate>Sat, 05 Nov 2022 21:46:44 +0800</pubDate><description><![CDATA[释放掉RingBuffer中的数组对skb的引用（注意：此时RingBuffer里的数组虽然放弃了对skb的引用，但是该skb并不会被立即清除，因为TCP有重传机制，必须要保证收到了对方的ack应答后再彻底删除该skb，如果没有收到对方的ack，那么传输层还可以重传该skb）通过上面的两种发送数据时拷贝的对比，可以看出sendfile相比与传统的方式，一次数据发送流程中，少了一次【CPU拷贝】，两次【态的切换】，在需要发送的数据较大的情况下，这里便是性能的提升点。能，sendfile就是这么干的。]]></description><category></category></item><item><title><![CDATA[从内核角度看TCP三次握手]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/127707580</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/127707580</guid><author>Hellowenpan</author><pubDate>Sat, 05 Nov 2022 19:35:37 +0800</pubDate><description><![CDATA[这里主要是介绍socket里的【全连接队列】和【半连接队列】结构，所以socket里的其他属性结构就不详细展示了（比如：发送队列，等待队列等），可以看到【全连接队列】和【半连接队列】在socket中的结构如下。如果在【第一次握手】的时候，server端收到client端的SYN包后，如果全连接队列满了或者半连接队列满了，那么该握手请求便会被server端【直接丢弃】，那么client端如何处理？理解了上面的listen和connect的作用后，我们便可以从内核角度整体的来看一下三次握手的过程了！]]></description><category></category></item><item><title><![CDATA[springboot中如何整合groovy实现一个轻量级规则引擎]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/127147132</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/127147132</guid><author>Hellowenpan</author><pubDate>Sun, 02 Oct 2022 22:23:02 +0800</pubDate><description><![CDATA[当然你也可以项目启动好后通过来注册脚本，这里采用预先加载好脚本到Redis来演示对应的脚本都在目录下，自己按需设定脚本key即可[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sz13Srxu-1664720376722)(images/redis导入脚本配置.png)]]]></description><category></category></item><item><title><![CDATA[用同一个GroovyClassLoader加载的Class真的无法回收吗]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/127145821</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/127145821</guid><author>Hellowenpan</author><pubDate>Sun, 02 Oct 2022 20:17:48 +0800</pubDate><description><![CDATA[通过上面测试结果来看，由同一个对象加载到方法区的Class其实是被回收了的，方法区的内存占用也不会持续上升那么是不是说明由一个ClassLoader加载到方法区的Class可以在加载他的ClassLoader未被卸载前，自身可以被从方法区卸载呢？结论是否定的！！!由上面的分析可以看到，由同一个对象加载的Class，在加载他的ClassLoader没有被卸载前，自己竟然可以被卸载出方法区？？？？这是啥原因呢？于是debug了一下源码！！！]]></description><category></category></item><item><title><![CDATA[spring的@Import注解会不会注入bean到容器]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/127029676</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/127029676</guid><author>Hellowenpan</author><pubDate>Sat, 24 Sep 2022 19:32:06 +0800</pubDate><description><![CDATA[结论：正常情况下是会的，但是在某些特定的情况下并不会导入类到容器！！！

然后在项目的主启动类或配置类上标注注解就可以实现某个功能的动态开关，看上去很优雅，但是有一次遇到一个问题，，比如上面的类
如下，该类实现了接口


二、问题解决

经过我的验证，如果不实现接口，那么是可以正常被导入容器的
所以问题出在实现接口上，我们只需要不实现该接口就行，如果非要实现接口，又想将自定义的类注入容器，那么可以在配置类中通过的方式来实现

目前我遇到的@Import注解不能导入的类仅仅只有一种情况，特此记录！！！]]></description><category></category></item><item><title><![CDATA[java实现环形数组]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/126071248</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/126071248</guid><author>Hellowenpan</author><pubDate>Sat, 30 Jul 2022 13:33:10 +0800</pubDate><description><![CDATA[java实现环形数组。]]></description><category></category></item><item><title><![CDATA[feign调用丢失请求头问题解决及原理分析]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/125978064</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/125978064</guid><author>Hellowenpan</author><pubDate>Mon, 25 Jul 2022 16:41:57 +0800</pubDate><description><![CDATA[注入一个自定义的接口的实现类到容器中openFeign发起调用前会先构建请求的Request，在构建request的时候就会拿到我们自定义的并执行，在自定义的RequestInterceptor实现类中便会从原有请求里拿到请求头信息，然后放入feign调用的request里注意如果是通过线程池或多线程进行发起feign调用，那么通过上述的添加实现类里通过获取原有请求里的请求头数据是获取不到的，这种情况怎么解决？其实也简单，最简单的方式就是在提交任务到线程池里的时候将请求头信息传递进去就可以了。.......]]></description><category></category></item><item><title><![CDATA[使用ngrok做内网穿透]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/125962739</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/125962739</guid><author>Hellowenpan</author><pubDate>Sun, 24 Jul 2022 19:08:11 +0800</pubDate><description><![CDATA[需要到刚才解压ngrok的目录下执行如下命令，后面的是官网上查看到的authtoken。然后你就可以在外网拿着这个域名来访问你本地的localhost8080端口了！由于这是免费的内网穿透，所以只允许同时绑定一个端口，无法同时绑定多个端口。需要到ngrok解压的目录下执行该命令，不然会无法识别ngrok命令。执行如下命令，建立一条和本机8080端口（可自己选择）的隧道。执行成功后，过1s钟便会出现如下界面。自己创建一个web工程，编写一个接口。先到官网查看你的authtoken。...]]></description><category></category></item><item><title><![CDATA[使用Redis + lua脚本实现分布式限流]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/125772906</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/125772906</guid><author>Hellowenpan</author><pubDate>Wed, 13 Jul 2022 21:18:09 +0800</pubDate><description><![CDATA[4、application.yml文件中配置

5、主启动类上开启限流功能

使用显示开启限流功能


三、使用测试
1、使用限流注解
直接在需要限流的接口上使用或便可以进行限流
2、使用redisLimitHelper进行限流

使用redisLimitHelper进行限流更加灵活


3、使用示例

具体使用详情见：基于lua脚本的分布式限流使用测试

四、核心原理
使用方式和原理都很简单，不过多赘述，这里贴出两个核心的lua脚本.........]]></description><category></category></item><item><title><![CDATA[java数据结构与算法之二叉树的最大宽度和最大深度问题]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/123687744</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/123687744</guid><author>Hellowenpan</author><pubDate>Wed, 23 Mar 2022 15:35:21 +0800</pubDate><description><![CDATA[①、最大深度问题

求二叉树的最大深度，最常见的无非两种方式
第一种是，以【宽度优先遍历】统计树的层数，树有多少层，那么树就有多高
第二种是，以【深度优先遍历】，以我们上面讲的【二叉树通用套路】，每个节点都可以向他的左右孩子要信息来求解

深度优先求树的最大高度解法
/**
 * 以深度优先，求二叉树的高度
 */
public static int height(TreeNode treeNode) {
    if (treeNode == null) {
        return 0;
    }]]></description><category></category></item><item><title><![CDATA[java数据结构与算法之翻转二叉树]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/123656657</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/123656657</guid><author>Hellowenpan</author><pubDate>Tue, 22 Mar 2022 11:42:34 +0800</pubDate><description><![CDATA[该题本来不是一个具有代表性的题目，但是由于在面试中我多次被问到该题，所以做一个记录。
题目描述

给你一棵二叉树的根节点 root ，翻转这棵二叉树，并返回其根节点。

解法一（DFS）
/**
 * dfs法翻转二叉树（后序遍历）
 */
public TreeNode invertTree1(TreeNode root) {
    if (root == null) {
        return null;
    }
    invertTree1(root.left);
    invertT]]></description><category></category></item><item><title><![CDATA[java数据结构与算法之最长无重复子串问题]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/123648200</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/123648200</guid><author>Hellowenpan</author><pubDate>Mon, 21 Mar 2022 22:25:48 +0800</pubDate><description><![CDATA[①、问题描述
给定一个字符串 s ，请你找出其中不含有重复字符的 最长子串 的长度。力扣第三题

该题主要考察了对string的基础API的熟悉度
对hash表的熟练使用
双指针 + 滑动窗口思想

②、代码展示

本题的核心就是使用hash表的去重功能

public class NoRepeatSubString {

    /**
     * 双指针解法(滑动窗口思想)
     */
    public int lengthOfLongestSubstring3(String s) {
   ]]></description><category></category></item><item><title><![CDATA[java数据结构与算法之最近公共祖先问题]]></title><link>https://blog.youkuaiyun.com/Hellowenpan/article/details/123645353</link><guid>https://blog.youkuaiyun.com/Hellowenpan/article/details/123645353</guid><author>Hellowenpan</author><pubDate>Mon, 21 Mar 2022 20:34:49 +0800</pubDate><description><![CDATA[①、问题描述
给你两个节点node1,node2，这两个节点都在树上，再给你一个节点head，head表示二叉树的头节点，请返回他们【最近的公共祖先】
②、核心点分析

如果我们能顺着某个node向上找到他的父亲节点就好了。如果能从某个节点开始向上找到他的parent节点，那么这个题就和单链表相交问题一样了，变得非常简单了
所以，对于这种二叉树结构，我们只要知道【二叉树的头节点】，那么我们就可以【遍历】这棵二叉树。然后利用【HashMap结构】来存放每个节点的父子关系，这样的话，对于每一个节点，我们都可以找]]></description><category></category></item></channel></rss>