<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[第四空间]]></title><description><![CDATA[认真写好每一篇博客]]></description><link>https://blog.csdn.net/vxzhg</link><language>zh-cn</language><generator>https://blog.csdn.net/</generator><copyright><![CDATA[Copyright &copy; vxzhg]]></copyright><item><title><![CDATA[Java如何判断两个数组相等]]></title><link>https://blog.csdn.net/vxzhg/article/details/129316137</link><guid>https://blog.csdn.net/vxzhg/article/details/129316137</guid><author>vxzhg</author><pubDate>Fri, 03 Mar 2023 11:01:12 +0800</pubDate><description><![CDATA[相等是指两个数组的长度相同，且每个对应下标的元素都相等。自己写一个这种方法也不难，但JDK已经帮我们实现了：Arrays.equals()]]></description><category></category></item><item><title><![CDATA[如何阅读Spring的官方文档查找自己想看的主题]]></title><link>https://blog.csdn.net/vxzhg/article/details/126468640</link><guid>https://blog.csdn.net/vxzhg/article/details/126468640</guid><author>vxzhg</author><pubDate>Mon, 22 Aug 2022 16:47:32 +0800</pubDate><description><![CDATA[AOP属于Spring Core，我们点击查看，其他主题也类似。进入后查看目录，我们发现第4、5两章是关于AOP的，阅读即可。AOP属于Spring Framework，选择该工程。进入后查看所有工程，或者直接选择你需要的工程。然后选择Spring版本，点击对应的文档链接。以查看AOP相关文档为例子。]]></description><category></category></item><item><title><![CDATA[等待synchronized锁时响应interrupted中断吗？]]></title><link>https://blog.csdn.net/vxzhg/article/details/126333366</link><guid>https://blog.csdn.net/vxzhg/article/details/126333366</guid><author>vxzhg</author><pubDate>Sun, 14 Aug 2022 16:47:41 +0800</pubDate><description><![CDATA[处于阻塞状态时线程不会响应中断，当等待到锁从阻塞状态恢复到runnable状态时线程的中断标志位还处于中断状态，这时如果有对标志位的判断是可以判断出处于中断状态的。]]></description><category></category></item><item><title><![CDATA[Java线程池的知识]]></title><link>https://blog.csdn.net/vxzhg/article/details/126146326</link><guid>https://blog.csdn.net/vxzhg/article/details/126146326</guid><author>vxzhg</author><pubDate>Sun, 07 Aug 2022 12:13:12 +0800</pubDate><description><![CDATA[在Java中表示线程池的类为ThreadPoolExecutor。定义时最多需要设置7个参数。1.核心线程数，当线程池最少维护的线程个数2.最大线程数，当提交任务时所有核心线程都在工作，切阻塞队列已经满了，则继续创建线程，这个参数定义了创建线程数的上限3和4 线程活跃时间，当线程超过该时间空闲时销毁线程，当然要保留核心线程数个线程5 阻塞队列，任务提交时，当无空闲线程且线程个数到达最大线程数，则先将任务保存到该队列中。...............]]></description><category></category></item><item><title><![CDATA[【算法题解】17.电话号码的字母组合]]></title><link>https://blog.csdn.net/vxzhg/article/details/125829768</link><guid>https://blog.csdn.net/vxzhg/article/details/125829768</guid><author>vxzhg</author><pubDate>Sun, 17 Jul 2022 11:21:54 +0800</pubDate><description><![CDATA[回溯算法使用StringBuilder进行字符串的拼接，可以生成更少的String对象，执行速度更快。回溯执行的主体是取当前遍历到的数字对应的字符集合，依次加到当前已经拼接的字符串尾部，然后进行回溯。然后删除添加的当前字符，进行下一次回溯。当回溯到最后时，没有新的数字，这时将拼接好的字符串加到结果集中即可。在中间dfs的过程中巧妙利用了StringBuilder，只需要一个对象即可。使用其deleteCharAt()方法删除尾部字符，这个方法很关键，如果不知道这个方法，不太容易利用。...]]></description><category></category></item><item><title><![CDATA[MySQL之多版本并发控制MVCC]]></title><link>https://blog.csdn.net/vxzhg/article/details/125138714</link><guid>https://blog.csdn.net/vxzhg/article/details/125138714</guid><author>vxzhg</author><pubDate>Mon, 06 Jun 2022 23:35:49 +0800</pubDate><description><![CDATA[mvcc中文名称为多版本并发控制，用于实现读提交和可重复读隔离级别。多版本是指在对数据进行修改时，会通过undo日志记录数据行的多个版本。通过建立一致性视图，实现事务间的修改不相互影响。一致性视图，记录了当前正在执行的所有事务id。对于可重复读隔离级别，在事务执行过程中读取到的数据是一致的。读取一行数据时，实际会去判断当前数据的事务编号。如果事务id大于当前视图的高水位，说明这是一个未来的事务修改的数据，不能读取。这时就会往前追溯，找到一个undo日志版本号小于当前视图的低水位，或则位于高低水位之间但不在视]]></description><category></category></item><item><title><![CDATA[MySQL之事务的特性、隔离级别和隔离级别解决的问题]]></title><link>https://blog.csdn.net/vxzhg/article/details/125133266</link><guid>https://blog.csdn.net/vxzhg/article/details/125133266</guid><author>vxzhg</author><pubDate>Sun, 05 Jun 2022 16:34:40 +0800</pubDate><description><![CDATA[事务有A、C、I、D四大特性，分别是A原子性、C一致性、I隔离性、D持久性。A原子性：事务的执行过程做为一个整体，要么所有语句执行成功，要么都没有执行。C一致性：事务执行前后，数据保持一致性的状态。比如银行转账时，从A账户减少100元，给B账户增加100元。事务执行后，两个账户的资金总额是不变的。一致性靠原子性、隔离性、持久性三个特性来保证，是一个结果。I隔离性：事务的执行是相互隔离的，互不影响。共有4种隔离级别：读未提交，读已提交，可重复读和串行化。D持久性：事务对数据的修改是持久的。在读未提交隔离级别下]]></description><category></category></item><item><title><![CDATA[MySQL之索引为什么使用B+树而不是跳表实现？]]></title><link>https://blog.csdn.net/vxzhg/article/details/125132669</link><guid>https://blog.csdn.net/vxzhg/article/details/125132669</guid><author>vxzhg</author><pubDate>Sun, 05 Jun 2022 16:06:27 +0800</pubDate><description><![CDATA[B+数是平衡的多路查找树。他的特点是一个结点上可以存储多个元素，带来了扇出较高的优点。只需要很少的层数就可以存储大量的数据。和B树相比，它在叶子结点上存储所有的数据。跳表也是分层的。每一层都是一个链表。除了最下面的一层，每个元素除了有指向下一个元素的指针，还有一个指针指向下一层中和自己相同的元素。上一层的链表做为索引加快对下层链表元素的查找。每一层元素都是顺序排列的。当插入一个元素时，使用随机函数决定其是否在每一层插入。在最底层插入的概率是100%，在倒数第二层是50%，依次类推。这样在从最上层往下查询时就]]></description><category></category></item><item><title><![CDATA[【算法题解】搜索二维矩阵]]></title><link>https://blog.csdn.net/vxzhg/article/details/125124585</link><guid>https://blog.csdn.net/vxzhg/article/details/125124585</guid><author>vxzhg</author><pubDate>Sat, 04 Jun 2022 19:29:32 +0800</pubDate><description><![CDATA[给定一个m*n的矩阵，矩阵中每一行的元素从左往右依次递增，每一行的第一个元素都比上一行的最后一个元素大。给出一个目标值，编写一个高效的算法判断该目标值是否在矩阵中存在。根据题意可以分析出，没一行递增，每一列也递增。《剑指Offer》上有一道题给出的就是这样的矩阵，用那里的方法可以解决。就是从右上角或者左下角开始判断。每次可以排除一行或者一列。时间复杂度为O(m+n)。
这道题里的矩阵其实比《剑指Offer》上的那道，还多了一些条件。就是这里除了行列递增外，每一行整体都比上一行大。也就是按行从左到右，一行行也]]></description><category></category></item><item><title><![CDATA[【算法题解】矩阵置零]]></title><link>https://blog.csdn.net/vxzhg/article/details/125120720</link><guid>https://blog.csdn.net/vxzhg/article/details/125120720</guid><author>vxzhg</author><pubDate>Sat, 04 Jun 2022 12:51:59 +0800</pubDate><description><![CDATA[给定一个 m x n 的矩阵，如果一个元素为 0 ，则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。这个题目并不复杂，只需要遍历一遍数组找出为0的元素，并记录其所在的行、列。最后把这些行、列全部置为零即可。所以可以使用两个数组来分别记录行列是否存在为0的情况。时间复杂度O(m*n)，空间复杂度O(m+n)。具体代码如下：
但是题目要求使用原地算法，原地算法的意思是不使用额外空间。那么我们可以使用第一行、第一列进行记录，为0表示对应行或列存在为0的元素，当第一行、列本身元素就是0时也可以兼容。同时]]></description><category></category></item><item><title><![CDATA[分布式之雪花算法]]></title><link>https://blog.csdn.net/vxzhg/article/details/125108979</link><guid>https://blog.csdn.net/vxzhg/article/details/125108979</guid><author>vxzhg</author><pubDate>Fri, 03 Jun 2022 00:40:34 +0800</pubDate><description><![CDATA[雪花算法用来在分布式集群中生成唯一ID。即在需要在多台机器需要分别生成ID，又要保证生成的ID是唯一的、趋势递增的情况下使用的一种算法。雪花算法生成一个64位的ID，最高位固定为0，之后41位为时间戳，在之后的10位为机器编号，最后的12位为序号。41位的时间戳即2^41毫秒，换算一下是69年。时间戳原本也是一个64位的数字，这里取了其低41位。从当前时间开始，到低41位开始出现重复需要69年。这就是为什么说雪花算法最多可以使用69年的原因。机器编号为10位，2^10=1024，所以雪花算法最多支持1024]]></description><category></category></item><item><title><![CDATA[Redis之缓存击穿、缓存穿透和缓存雪崩]]></title><link>https://blog.csdn.net/vxzhg/article/details/125083710</link><guid>https://blog.csdn.net/vxzhg/article/details/125083710</guid><author>vxzhg</author><pubDate>Wed, 01 Jun 2022 15:51:19 +0800</pubDate><description><![CDATA[缓存击穿是指热点key失效之后，所有请求都访问到数据库，对数据库造成较大压力。
解决方案：
1.加锁，获取到锁的线程去更新缓存；如果是集群部署，则需要使用分布式锁。问题：没获取到锁的其他线程走什么逻辑呢？如果是等待获取锁，那么同一时刻所有线程串行获取锁，后获取到锁的线程等待时间较长。如果直接返回获取不到，要根据具体情况考虑是否能够接受。2.热点key缓存设置永不失效，更新采用异步更新的方式。具体实现可以是启动一个单独线程去定时判断缓存是否失效，失效时进行缓存更新。 存在更新不及时的情况，不能保证缓存和数据库]]></description><category></category></item><item><title><![CDATA[Spring之AOP]]></title><link>https://blog.csdn.net/vxzhg/article/details/125083604</link><guid>https://blog.csdn.net/vxzhg/article/details/125083604</guid><author>vxzhg</author><pubDate>Wed, 01 Jun 2022 15:01:44 +0800</pubDate><description><![CDATA[AOP意思是面向切面的编程。提供一种方式可以在现有代码前后增加一些统一的逻辑。比如监控、打印日志等。使用动态代理技术实现。有两种实现方式，一个是JDK Proxy，另一个是CgLib。
JDK Proxy要求被代理的对象实现一个接口，通过动态代理动态生成该接口的一个实现类。在实际使用时，需要定义一个中间类实现InvocationHandler接口定义代理类要执行的操作。
CgLib不要求被代理类实现接口，它是一个第三方类库，通过生成一个被代理对象的子类来进行动态代理。
两者在使用上都需要定义一个中间类来指定]]></description><category></category></item><item><title><![CDATA[【算法题解】颠倒二进制位]]></title><link>https://blog.csdn.net/vxzhg/article/details/123425127</link><guid>https://blog.csdn.net/vxzhg/article/details/123425127</guid><author>vxzhg</author><pubDate>Fri, 11 Mar 2022 15:05:33 +0800</pubDate><description><![CDATA[题目
颠倒给定的 32 位无符号整数的二进制位。
分析
依次判断每一位数字是0还是1，再设置到结果的对应位置上。
一个技巧是为0时不用专门设置，因为本来就是0。所以只需要设置为1的情况。另外和1&lt;&lt;i相与判断第i位是否为1时，需要判断是否不等于0。而不是大于0，因为也有可能是负数。
public class Solution {
    // you need treat n as an unsigned value
    public int reverseBits(int n) {
   ]]></description><category></category></item><item><title><![CDATA[【算法题解】Excel表列序号、Excel表列名称]]></title><link>https://blog.csdn.net/vxzhg/article/details/123397053</link><guid>https://blog.csdn.net/vxzhg/article/details/123397053</guid><author>vxzhg</author><pubDate>Thu, 10 Mar 2022 11:25:23 +0800</pubDate><description><![CDATA[题目
Excel中的列名，和其序号有如下关系：
A-1
B-2
……
Z-26
AA-27
AB-28
题目1：现给定一个列名求其序号
题目2：给定一个序号，求其对应的列名
分析
题目2直接处理不容易考虑清楚，先完成题目1，再进行倒推比较容易。
题目1解法。A- Z对应1-26。如果在高位则乘以26。
代码如下：
class Solution {
    public int titleToNumber(String columnTitle) {
        int num = 0;
        f]]></description><category></category></item><item><title><![CDATA[【算法题解】二叉树的最小深度]]></title><link>https://blog.csdn.net/vxzhg/article/details/123377913</link><guid>https://blog.csdn.net/vxzhg/article/details/123377913</guid><author>vxzhg</author><pubDate>Thu, 10 Mar 2022 11:11:09 +0800</pubDate><description><![CDATA[题目
求二叉树的最小深度：从根节点到叶子节点的路径上
分析
DFS，当判断到达叶子节点时记录depth，并进行最小比较。
这么做了之后发现效率较低，只击败10%的提交。
思考之后发现可以进行剪枝。当当前depth大于等于min时就不需要再遍历了，因为肯定找不出更短的了。
代码
class Solution {
    public int minDepth(TreeNode root) {
        int[] min = {0};
        dfs(root, min, 0);
       ]]></description><category></category></item><item><title><![CDATA[Java并发之synchronized锁优化]]></title><link>https://blog.csdn.net/vxzhg/article/details/123225166</link><guid>https://blog.csdn.net/vxzhg/article/details/123225166</guid><author>vxzhg</author><pubDate>Wed, 02 Mar 2022 11:32:48 +0800</pubDate><description><![CDATA[1.锁升级
JDK1.6之前 synchronized性能较差，被称作重量级锁，利于操作系统中的管程实现。加解锁需要进行内核空间和用户空间的切换，性能消耗较多。在JDK1.6中对synchronized进行了优化，加入了偏向锁、轻量级锁、自旋锁、重量级锁，从而使用不同程度的锁竞争。
在竞争程度最低的情况下，只有一个线程返回获取锁。这样就会进入偏向锁状态。这时对象头中一个专门的偏向锁标志位就会设置为1，线程ID也会记录下来。当下次再需要获取锁时，判断线程ID和自己相同，就可以直接进入临界区了。
在偏向锁状态下]]></description><category></category></item><item><title><![CDATA[Java并发之CountDownLatch、CyclicBarrier和Semaphore]]></title><link>https://blog.csdn.net/vxzhg/article/details/123116098</link><guid>https://blog.csdn.net/vxzhg/article/details/123116098</guid><author>vxzhg</author><pubDate>Mon, 28 Feb 2022 20:49:17 +0800</pubDate><description><![CDATA[]]></description><category></category></item><item><title><![CDATA[一些刷题时常用但平时写的不多的Java语法总结（持续更新）]]></title><link>https://blog.csdn.net/vxzhg/article/details/123161594</link><guid>https://blog.csdn.net/vxzhg/article/details/123161594</guid><author>vxzhg</author><pubDate>Sun, 27 Feb 2022 11:37:55 +0800</pubDate><description><![CDATA[1.StringBuilder删除最后一个字符
StringBuilder sb = new StringBuilder();
sb.append("abc");
sb.deleteCharAt(sb.length() - 1);

在一些涉及字符串构造的回溯算法中，需要把上一步添加的字符给删除掉。使用deleteCharAt方法可以做到。这个方法平时用的很少，特此记录。另外获取StringBuilder可以使用length()方法。
2.栈、队列的使用
不管是栈还是队列，都是用LinkedList实现。与]]></description><category></category></item><item><title><![CDATA[一次OOM排查的详细经过]]></title><link>https://blog.csdn.net/vxzhg/article/details/122522189</link><guid>https://blog.csdn.net/vxzhg/article/details/122522189</guid><author>vxzhg</author><pubDate>Sun, 16 Jan 2022 22:26:04 +0800</pubDate><description><![CDATA[1.问题定位
预发环境机器出现访问502的问题。
登录机器查看日志，没有发现特别的日志。
考虑到QA刚刚在做压测，想到是不是出现了OOM问题。搜索错误日志：
cat error.log | grep "OutOf" 

果然有OOM错误日志：
java.lang.OutOfMemoryError: GC overhead limit exceeded
java.lang.OutOfMemoryError: GC overhead limit exceeded

锁定是出现OOM问题。
2.查看PID
使用命]]></description><category></category></item></channel></rss>