<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[huapro.vip的程序人生]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/comphoner</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; comphoner]]></copyright><item><title><![CDATA[Spring+MyBatis实现读写分离四种实现方案整理]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123427205</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123427205</guid><author>comphoner</author><pubDate>Fri, 11 Mar 2022 15:59:29 +0800</pubDate><description><![CDATA[方案1
通过MyBatis配置文件创建读写分离两个DataSource，每个SqlSessionFactoryBean对象的mapperLocations属性制定两个读写数据源的配置文件。将所有读的操作配置在读文件中，所有写的操作配置在写文件中。
方案2
通过Spring AOP在业务层实现读写分离，在DAO层调用前定义切面，利用Spring的AbstractRoutingDataSource解决多数据源的问题，实现动态选择数据源
方案3
通过Mybatis的Plugin在业务层实现数据库读写分离，在MyB]]></description><category></category></item><item><title><![CDATA[synchronized底层源码]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123417134</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123417134</guid><author>comphoner</author><pubDate>Fri, 11 Mar 2022 10:01:18 +0800</pubDate><description><![CDATA[一、synchronized的使用场景
synchronized一般使用在下面这几种场景：

修饰代码块，指定一个加锁的对象，给对象加锁

public Demo1{
   Object lock=new Object();
   public void test1(){
       synchronized(lock){
       }
   }
}


修饰静态方法，对当前类的Class对象加锁

public class Demo2 {
   //形式一
    public void test1]]></description><category></category></item><item><title><![CDATA[synchronized修饰static方法与非static方法的区别]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123416930</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123416930</guid><author>comphoner</author><pubDate>Fri, 11 Mar 2022 09:39:06 +0800</pubDate><description><![CDATA[当synchronized修饰一个static方法时，多线程下，获取的是类锁（即Class本身，注意：不是实例），作用范围是整个静态方法，作用的对象是这个类的所有对象。


当synchronized修饰一个非static方法时，多线程下，获取的是对象锁（即类的实例对象），作用范围是整个方法，作用对象是调用该方法的对象。
结论：类锁和对象锁不同，他们之间不会产生互斥。


public class SynchoronizedDemo {

    //synchronized修饰非静态方法
    pu..]]></description><category></category></item><item><title><![CDATA[linux下tcp服务器并发连接数限制]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123402937</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123402937</guid><author>comphoner</author><pubDate>Thu, 10 Mar 2022 15:31:12 +0800</pubDate><description><![CDATA[1、修改用户进程可打开文件数限制
在Linux平台上，无论编写客户端程序还是服务端程序，在进行高并发TCP连接处理时，最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个TCP连接都要创建一个socket句柄，每个socket句柄同时也是一个文件句柄)。可使用ulimit命令查看系统允许当前用户进程打开的文件数限制：
[speng@as4 ~]$ ulimit -n
1024
这表示当前用户的每个进程最多允许同时打开1024个文件，这1024个文件中还得除去每个进程必然打开的]]></description><category></category></item><item><title><![CDATA[ThreadLocal源码]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123392946</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123392946</guid><author>comphoner</author><pubDate>Thu, 10 Mar 2022 09:32:35 +0800</pubDate><description><![CDATA[This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typic]]></description><category></category></item><item><title><![CDATA[MVCC详解]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123294481</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123294481</guid><author>comphoner</author><pubDate>Sat, 05 Mar 2022 14:38:49 +0800</pubDate><description><![CDATA[正确的理解MySQL的MVCC及实现原理
多版本控制: 指的是一种提高并发的技术。最早的数据库系统，只有读读之间可以并发，读写，写读，写写都要阻塞。引入多版本之后，只有写写之间相互阻塞，其他三种操作都可以并行，这样大幅度提高了InnoDB的并发度。在内部实现中，与Postgres在数据行上实现多版本不同，InnoDB是在undolog中实现的，通过undolog可以找回数据的历史版本。找回的数据历史版本可以提供给用户读(按照隔离级别的定义，有些读请求只能看到比较老的数据版本)，也可以在回滚的时候覆盖数据页上]]></description><category></category></item><item><title><![CDATA[innodb三大特性]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123289602</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123289602</guid><author>comphoner</author><pubDate>Sat, 05 Mar 2022 09:19:30 +0800</pubDate><description><![CDATA[InnoDB的三个关键特性
InnoDB存储引擎的三个关键特性：插入缓冲（insert buffer）、二次写（double write）、自适应哈希索引（adaptive hash index）。
1、插入缓冲（insert buffer）的原理：
对于非聚集索引的插入和更新，不是每一次直接插入索引页中，而是首先判断插入的非聚集索引页是否在缓冲池中，如果在，则直接插入，否则，先放入一个插入缓冲区中。好似欺骗数据库这个非聚集的索引已经插入到叶子节点了，然后再以一定的频率执行插入缓冲和非聚集索引页子节点的合并]]></description><category></category></item><item><title><![CDATA[Redis 性能优化]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123289454</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123289454</guid><author>comphoner</author><pubDate>Sat, 05 Mar 2022 09:01:54 +0800</pubDate><description><![CDATA[Redis 是基于单线程模型实现的，也就是 Redis 是使用一个线程来处理所有的客户端请求的，尽管 Redis 使用了非阻塞式 IO，并且对各种命令都做了优化（大部分命令操作时间复杂度都是 O(1)），但由于 Redis 是单线程执行的特点，因此它对性能的要求更加苛刻，本文我们将通过一些优化手段，让 Redis 更加高效地运行。
本文我们将使用以下手段，来提升 Redis 的运行速度：

缩短键值对的存储长度；
使用 lazy free（延迟删除）特性；
设置键值的过期时间；
禁用长耗时的查询命令；
使用]]></description><category></category></item><item><title><![CDATA[redis 过期策略]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123232164</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123232164</guid><author>comphoner</author><pubDate>Sat, 05 Mar 2022 08:51:32 +0800</pubDate><description><![CDATA[redis是单线程，收割时间也会占用线程处理时间，如果收割过于频繁，会导致读写出现卡顿。
1、主库过期策略
1.1、定时扫描
首先将每个设置了过期时间的key放到一个独立的hash中，默认每秒定时遍历这个hash而不是整个空间：
并不会遍历所有的key，采用一种简单的贪心策略
1.1.1、从过期key字典中，随机找20个key。
1.1.2、删除20gekey中过期的key
1.1.3、如果2中过期的key超过1/4，则重复第一步
1.1.4、每次处理的时间都不会25ms
如果有大量的key在同一时间段内过]]></description><category></category></item><item><title><![CDATA[一致性哈希算法的原理与实现]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123232605</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123232605</guid><author>comphoner</author><pubDate>Sat, 05 Mar 2022 08:51:03 +0800</pubDate><description><![CDATA[https://blog.youkuaiyun.com/kefengwang/article/details/81628977
https://blog.youkuaiyun.com/qq_31601743/article/details/89477787
对于 K 个关键字和 n 个槽位(分布式系统中的节点)的哈希表，增减槽位后，平均只需对 K/n 个关键字重新映射。

...]]></description><category></category></item><item><title><![CDATA[哪些是线程安全的容器？]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123233900</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123233900</guid><author>comphoner</author><pubDate>Sat, 05 Mar 2022 08:50:24 +0800</pubDate><description><![CDATA[同步容器类：使用了synchronized 1.Vector 2.HashTable
并发容器： 3.ConcurrentHashMap:分段 4.CopyOnWriteArrayList：写时复制 5.CopyOnWriteArraySet：写时复制
Queue: 6.ConcurrentLinkedQueue：是使用非阻塞的方式实现的基于链接节点的无界的线程安全队列，性能非常好。 （java.util.concurrent.BlockingQueue 接口代表了线程安全的队列。） 7.ArrayBloc]]></description><category></category></item><item><title><![CDATA[Spring事务回滚和异常类]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123288994</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123288994</guid><author>comphoner</author><pubDate>Sat, 05 Mar 2022 08:49:47 +0800</pubDate><description><![CDATA[1、异常的一些基本知识
异常的架构
　　异常的继承结构：Throwable为基类，Error和Exception继承Throwable。Error和RuntimeException及其子类成为未检查异常（unchecked），其它异常成为已检查异常（checked）。
　

Error异常

Error表示程序在运行期间出现了十分严重、不可恢复的错误，在这种情况下应用程序只能中止运行，例如JAVA 虚拟机出现错误。Error是一种unchecked Exception，编译器不会检查Error是否被处理，在]]></description><category></category></item><item><title><![CDATA[rabbitmq五种工作模式]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123289112</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123289112</guid><author>comphoner</author><pubDate>Sat, 05 Mar 2022 08:05:32 +0800</pubDate><description><![CDATA[1、简单模式
在这里插入图片描述
1个生产者将消息交给默认的交换机(AMQP default)
2 交换机获取消息后交给绑定这个生产者的队列(关系是通过队列名称完成)
3 监听当前队列的消费者获取消息,执行消费逻辑
应用场景:短信,聊天
2、工作模式(资源争抢)
1 生产者将消息交个交换机
2 交换机交给绑定的队列
3 队列由多个消费者同时监听,只有其中一个能够获取这一条消息,形成了资源的争抢,谁的资源空闲大,争抢到的可能越大;
应用场景:抢红包,大型系统的资源调度
3 发布订阅(publish/fanou]]></description><category></category></item><item><title><![CDATA[Spring 中事务方法的调用]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123289060</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123289060</guid><author>comphoner</author><pubDate>Sat, 05 Mar 2022 07:56:45 +0800</pubDate><description><![CDATA[前言
Spring 提供了事务的管理机制，我们只需要在方法或者类上加上 @Transactional 注解进行事务管理。而非事务方法与事务方法之间相互调用，有时会使事务失效，本文是对该情形下的事务总结
什么是事务传播机制
事务在多个方法的调用中是如何传递的，是重新创建事务还是使用父方法的事务？父方法的回滚对子方法的事务是否有影响？这些都是可以通过事务传播机制来决定的。
Spring 默认是 PROPAGATION_REQUIRED 机制。 下面来举一个例子：
	public class Demo
	{
		]]></description><category></category></item><item><title><![CDATA[LeetCode-344-反转字符串]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123230243</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123230243</guid><author>comphoner</author><pubDate>Wed, 02 Mar 2022 14:54:07 +0800</pubDate><description><![CDATA[一、双指针
class Solution {
    public void reverseString(char[] s) {
        int n = s.length;
        for (int left = 0, right = n - 1; left &lt; right; ++left, --right) {
            char tmp = s[left];
            s[left] = s[right];
            s[right] = ]]></description><category></category></item><item><title><![CDATA[反转二叉树]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123229994</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123229994</guid><author>comphoner</author><pubDate>Wed, 02 Mar 2022 14:43:37 +0800</pubDate><description><![CDATA[1.递归版本
/**
 * LeetCode 226 - Invert Binary Tree
 */
public class Solution {
    /**
     * 翻转二叉树
     * @param root 二叉树的根
     * @return
     */
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return root;
        }
]]></description><category></category></item><item><title><![CDATA[rabbitmq 怎么保证幂等性，数据一致性问题]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123229614</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123229614</guid><author>comphoner</author><pubDate>Wed, 02 Mar 2022 14:32:08 +0800</pubDate><description><![CDATA[mq的作用主要是用来解耦，削峰，异步，
增加MQ,系统的复杂性也会增加很多，
也会带来其他的问题，比如MQ挂了怎么办，怎么保持数据的幂等性
幂等性问题通俗点讲就是保证数据不被重复消费，同时数据也不能少，
也就是数据一致性问题。
下面是MQ丢失的3种情况

1，生产者发送消息至MQ的数据丢失
解决方法:在生产者端开启comfirm 确认模式，你每次写的消息都会分配一个唯一的 id，
然后如果写入了 RabbitMQ 中，RabbitMQ 会给你回传一个 ack 消息，告诉你说这个消息 ok 了
2，MQ收到消]]></description><category></category></item><item><title><![CDATA[springboot 静态方法获取Bean]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123229398</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123229398</guid><author>comphoner</author><pubDate>Wed, 02 Mar 2022 14:23:42 +0800</pubDate><description><![CDATA[实现ApplicationContextAware
ApplicationContextAware 通过它Spring容器会自动把上下文环境对象调用ApplicationContextAware接口中的setApplicationContext方法。
我们在ApplicationContextAware的实现类中，就可以通过这个上下文环境对象得到Spring容器中的Bean。
看到—Aware就知道是干什么的了，就是属性注入的，但是这个ApplicationContextAware的不同地方在于，实现了这个]]></description><category></category></item><item><title><![CDATA[JVM配置信息]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123228743</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123228743</guid><author>comphoner</author><pubDate>Wed, 02 Mar 2022 14:03:58 +0800</pubDate><description><![CDATA[首先先看一下jvm的结构图

从上图可以看出jvm的内存主要分了三个部分：堆内存，永久代，栈。
对于堆内存和永久代这个是线程共享的。
堆内存（Heap）
对于大多数应用来说，Java 堆（Java Heap）是Java 虚拟机所管理的内存中最大的一块。Java 堆是被所有线程共享的一块内存区域，在虚拟机启动时创建。
此内存区域的唯一目的就是存放对象实例，几乎所有的对象实例都在这里分配内存。
堆内存是所有线程共有的，可以分为两个部分：年轻代和老年代。
下图中的Perm代表的是永久代，但是注意永久代并不属于堆内]]></description><category></category></item><item><title><![CDATA[jstack Dump 日志文件中的线程状态]]></title><link>https://blog.youkuaiyun.com/comphoner/article/details/123228442</link><guid>https://blog.youkuaiyun.com/comphoner/article/details/123228442</guid><author>comphoner</author><pubDate>Wed, 02 Mar 2022 13:58:24 +0800</pubDate><description><![CDATA[dump 文件里，值得关注的线程状态有：
1、死锁，Deadlock（重点关注）
死锁线程，一般指多个线程调用间，进入相互资源占用，导致一直等待无法释放的情况。
2、执行中，Runnable
一般指该线程正在执行状态中，该线程占用了资源，正在处理某个请求，有可能正在传递SQL到数据库执行，有可能在对某个文件操作，有可能进行数据类型等转换。
3、等待资源，Waiting on condition（重点关注）
1、如果堆栈信息明确是应用代码，则证明该线程正在等待资源。一般是大量读取某资源，且该资源采用了资源锁的]]></description><category></category></item></channel></rss>