<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[怪咖小青年的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/ma_chen_qq</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; ma_chen_qq]]></copyright><item><title><![CDATA[Java中的锁]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/104738756</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/104738756</guid><author>ma_chen_qq</author><pubDate>Sun, 08 Mar 2020 19:49:11 +0800</pubDate><description><![CDATA[1. Lock接口
一般来说，一个锁能够防止多个线程同时访问共享资源（但是有些锁可以允许多个线程并发的访问共享资源，比如读写锁）。Java SE 5之后，并发包中新增了Lock接口（以及相关实现类）用来实现锁功能，它提供了与synchronized关键字类似的同步功能，只是在使用时需要显式地获取和释放锁。虽然它缺少了（通过synchronized块或者方法所提供的）隐式获取释放锁的便捷性，但是却拥...]]></description><category></category></item><item><title><![CDATA[springBoot实现邮件发送]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/104468346</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/104468346</guid><author>ma_chen_qq</author><pubDate>Sun, 23 Feb 2020 21:51:16 +0800</pubDate><description><![CDATA[1.邮件协议背景知识
1.1 SMTP协议（Simple Mail Transfer Protocol）
SMTP协议，又称简单邮件传输协议，是建立在FTP文件传输服务上的一种邮件服务，SMTP的重要特性之一是其能跨越网络传输邮件，能够在不同的网络中“接力”传输。可实现相同网络处理进程之间的邮件传输，也可通过中继器或网关实现某处理进程与其他网络之间的邮件传输。
1.2 POP3协议（Post Of...]]></description><category></category></item><item><title><![CDATA[spring事务管理]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/83450402</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/83450402</guid><author>ma_chen_qq</author><pubDate>Sat, 27 Oct 2018 22:37:26 +0800</pubDate><description><![CDATA[事务回顾

1、事务的特性:

①原子性：事务是不可分割的，要么都成功，要么都失败

②一致性：事务发生前和事务发生后，事件的总数状态不变。（例如：转账操作）

③隔离性：多个事务在执行时可能会收到彼此的影响，所以采用了不同的隔离级别来避免这种影响

④持久性：事务一旦提交，它对数据的改变就是永久性的，即使数据库发生故障也不应该有什么影响。

2、多个事务造成的影响

①脏读：一个事务读取到了另一...]]></description><category></category></item><item><title><![CDATA[spring循环依赖问题]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/83449732</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/83449732</guid><author>ma_chen_qq</author><pubDate>Sat, 27 Oct 2018 22:03:19 +0800</pubDate><description><![CDATA[什么是循环依赖

循环依赖就是循环引用，就是两个或多个bean之间相互持有对象，比如A引用B，B引用C，C引用A，他们最终反映为一个环，如下类图所示：



 

spring如何解决循环依赖

spring容器的循环依赖分为两类：一类是构造器循环依赖，另一类是setter循环依赖。

（1）构造器循环依赖

构造函数构成的循环依赖是无法解决的，只能抛出BeanCurrentlyInCreatio...]]></description><category></category></item><item><title><![CDATA[CyclicBarrier栅栏]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/83274832</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/83274832</guid><author>ma_chen_qq</author><pubDate>Mon, 22 Oct 2018 17:12:19 +0800</pubDate><description><![CDATA[CyclicBarrier有什么作用？

在现实生活中，在进行某个活动前需要等待人全部都齐了才开始。例如吃饭时要等全家人都上座了才动筷子，旅游时要等全部人都到齐了才出发，比赛时要等运动员都上场后才开始。

栅栏就可以很好的模拟这类场景，利用CyclicBarrier类可以实现一组线程相互等待，当所有线程都到达某个屏障点后再进行后续的操作。下图演示了这一过程。

 



CyclicBarrier...]]></description><category></category></item><item><title><![CDATA[线程池ThreadPoolExecutor]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/83016295</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/83016295</guid><author>ma_chen_qq</author><pubDate>Thu, 11 Oct 2018 18:43:44 +0800</pubDate><description><![CDATA[为什么使用线程池，线程池有什么优势？

因为线程的创建和销毁都会伴随着系统的开销，过于频繁的创建/销毁线程，会很大程度上影响处理效率。而且线程并发数量过多，抢占系统资源从而导致阻塞。所以需要对线程进行简单的管理，比如：延时执行，定时循环执行，这就需要线程池来进行管理。

线程池有以下好处：

1、降低资源消耗；
	2、提高响应速度；
	3、提高线程的可管理性。
Java1.5中引入的Executo...]]></description><category></category></item><item><title><![CDATA[CountDownLatch闭锁]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/83013691</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/83013691</guid><author>ma_chen_qq</author><pubDate>Thu, 11 Oct 2018 16:23:04 +0800</pubDate><description><![CDATA[什么是闭锁

闭锁的作用相当于一扇门：用来同步一个或多个任务，强制他们等待由其他任务执行的一组操作完成。在闭锁到达结束状态之前，这扇门一直是关闭的，并且没有任务线程能通过。直到闭锁达到结束状态时，这扇门才会打开，并且允许所有的线程通过。当闭锁到达结束状态后，这扇门将永远保持打开状态，因为闭锁将不会在改变其状态。

CountDownLatch是一种灵活的闭锁实现，它的内部提供了一个计数器，该计数器...]]></description><category></category></item><item><title><![CDATA[线程之间的协作——Exchange]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/82997272</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/82997272</guid><author>ma_chen_qq</author><pubDate>Wed, 10 Oct 2018 15:01:32 +0800</pubDate><description><![CDATA[Exchanger作用
&amp;amp;amp;nbsp;&amp;amp;amp;nbsp;&amp;amp;amp;nbsp;&amp;amp;amp;nbsp;&amp;amp;amp;nbsp; Exchanger是个线程间协作的工具类。Exchanger用于进行线程间的数据交换。它提供一个同步点，在这个同步点，两个线程可以交换彼此的数据。这两个线程通过 exchange*() 方法交换数据，如果第一个线程先执行exchange()方法，它会一直等待第二个线程也执行exchange方法，当两个线]]></description><category></category></item><item><title><![CDATA[happen-before原则]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/82990603</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/82990603</guid><author>ma_chen_qq</author><pubDate>Tue, 09 Oct 2018 23:27:30 +0800</pubDate><description><![CDATA[happen-before是JMM最核心的概念，所以在了解happen-before原则之前，首先需要了解java的内存模型。
JMM内存模型
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; java内存模型是共享内存的并发模型，线程之间主要通过读-写共享变量来完成隐式通信。java中的共享变量是存储在内存中的，多个线程由其工作内存，其工作方式是将共享内存中的变量拿出来放在工作内存，操作完成后，...]]></description><category></category></item><item><title><![CDATA[Condition接口]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/82990283</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/82990283</guid><author>ma_chen_qq</author><pubDate>Tue, 09 Oct 2018 22:50:36 +0800</pubDate><description><![CDATA[Condition
wait()、notify()与synchronized配合可以实现等待通知，condition和Lock配合同样也可以实现等待通知，但是两者之前还是有区别的。
Condition定义了等待/通知两种类型的方法，当前线程调用这些方法时，需要提前获取到Condition对象关联的锁，Condition对象是由Lock对象创建出来的(Lock.newCondition)，换句话说，...]]></description><category></category></item><item><title><![CDATA[深克隆和浅克隆]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/82912363</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/82912363</guid><author>ma_chen_qq</author><pubDate>Sun, 30 Sep 2018 17:53:44 +0800</pubDate><description><![CDATA[为什么需要克隆？
new出来的对象中的属性都是初始化时候的值，当需要一个新的对象来保存当前对象的“状态”就靠clone方法了。直接使用Object a=new Object();Object b;b=a不行吗，答案是不行的。因为这只是克隆了引用。
如何实现克隆？
首先由两种克隆的方式，一个是深克隆，一个是浅克隆。他们之间的区别在于：是否支持引用类型的成员变量的复制，深克隆会克隆引用类型的成员变量。...]]></description><category></category></item><item><title><![CDATA[redis内存淘汰策略]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/82876547</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/82876547</guid><author>ma_chen_qq</author><pubDate>Fri, 28 Sep 2018 09:45:33 +0800</pubDate><description><![CDATA[&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;Redis内存淘汰指的是当缓存内存不够用的清情况下，用户存储的一些键被可以被Redis主动地从实例中删除。内存的淘汰机制的初衷是为了更好地使用内存，用一定的缓存miss来换取内存的使用效率。
首先缓存都有哪些清空策略？
场景的缓存清空策略一般有：


FIFO(first in first out)
先进先出策略，最先进入缓存的数据在缓存...]]></description><category></category></item><item><title><![CDATA[删除倒数第K个节点]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/81323989</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/81323989</guid><author>ma_chen_qq</author><pubDate>Wed, 01 Aug 2018 08:52:30 +0800</pubDate><description><![CDATA[题目描述： 
给定一个链表，删除链表的倒数第 n 个节点，并且返回链表的头结点。

示例：

给定一个链表: 1-&amp;gt;2-&amp;gt;3-&amp;gt;4-&amp;gt;5, 和 n = 2.

当删除了倒数第二个节点后，链表变为 1-&amp;gt;2-&amp;gt;3-&amp;gt;5.

思考： 
链表因为其特殊的结构，在操作链表的时候最常见的就是使用多种指针操作，对于这个问题使用两个指针就可以搞定了，具体的思路如下图所以...]]></description><category></category></item><item><title><![CDATA[两个单向链表的第一个公共结点]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/81323897</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/81323897</guid><author>ma_chen_qq</author><pubDate>Wed, 01 Aug 2018 08:44:31 +0800</pubDate><description><![CDATA[leetcode160：相交链表

题目：

编写一个程序，找到两个单链表相交的起始节点

实例：



A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3



思路：

因为链表是单向链表，所...]]></description><category></category></item><item><title><![CDATA[动态规划--0-1背包问题]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/81174379</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/81174379</guid><author>ma_chen_qq</author><pubDate>Mon, 23 Jul 2018 20:42:39 +0800</pubDate><description><![CDATA[问题描述:

有一个背包，它的容量为C(Capacity)，现在有n种不同的物品，编号为0..n-1，其中每一件物品的重量为W(i)，价值为v(i)。问可以向这个背包中盛放那些物品，使得在不超过背包容量的基础上，物品的总价值最大



使用递归解决问题的时候，要首先知道递归要解决怎样的问题，也就是说定义状态。首先有两个变量n个物品，容量为C的背包，所以：
  F(n，C)考虑将n个物品放进容量为C...]]></description><category></category></item><item><title><![CDATA[内存屏障]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/81173868</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/81173868</guid><author>ma_chen_qq</author><pubDate>Mon, 23 Jul 2018 20:25:49 +0800</pubDate><description><![CDATA[         

       锁在保证可见性的时候，会有两个操作刷新处理器缓存(获得锁)和冲刷处理器缓存(释放锁)。前一个动作保证了：当前线程能够读取到前一个线程对共享数据的更新，后一个动作保证了：该锁的所有持有线程对这些数据所做的更新对该锁的所有持有线程可见。而这两个动作的实现是通过：内存屏障完成的。

什么是内存屏障？

       内存屏障是一种CPU指令，用于控制特定条件下的重排序...]]></description><category></category></item><item><title><![CDATA[JVM运行时内存划分]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/81023957</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/81023957</guid><author>ma_chen_qq</author><pubDate>Thu, 12 Jul 2018 23:32:16 +0800</pubDate><description><![CDATA[一、运行时数据区域JVM在执行java程序的过程中会把他所管理的内存划分为若干个不同的数据区域。这些区域有各自的创建和销毁的时间，这些区域可分为线程私有和共有两类，线程私有的有：程序计数器、java虚拟机栈、本地方法栈；线程公有的有：堆、方法区。如图所示：1、程序计数器（线程私有）也就是字节码的行号指示器（模拟的是CPU的程序计数器），指示当前进程所要执行的字节码（而不是下一条），这个指令...]]></description><category></category></item><item><title><![CDATA[spring 事务管理]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/80987285</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/80987285</guid><author>ma_chen_qq</author><pubDate>Tue, 10 Jul 2018 16:02:27 +0800</pubDate><description><![CDATA[事务回顾1、事务的特性:①原子性：事务是不可分割的，要么都成功，要么都失败②一致性：事务发生前和事务发生后，事件的总数状态不变。（例如：转账操作）③隔离性：多个事务在执行时可能会收到彼此的影响，所以采用了不同的隔离级别来避免这种影响④持久性：事务一旦提交，它对数据的改变就是永久性的，即使数据库发生故障也不应该有什么影响。2、多个事务造成的影响①脏读：一个事务读取到了另一个事务还没有提交的数据（脏数...]]></description><category></category></item><item><title><![CDATA[LeetCode27：移除元素]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/80501367</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/80501367</guid><author>ma_chen_qq</author><pubDate>Tue, 29 May 2018 20:18:25 +0800</pubDate><description><![CDATA[给定一个数组 nums 和一个值 val，你需要原地移除所有数值等于 val 的元素，返回移除后数组的新长度。不要使用额外的数组空间，你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。示例 1:给定 nums = [3,2,2,3], val = 3,

函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。...]]></description><category></category></item><item><title><![CDATA[leetcode24：两两交换相邻的节点]]></title><link>https://blog.youkuaiyun.com/ma_chen_qq/article/details/80112607</link><guid>https://blog.youkuaiyun.com/ma_chen_qq/article/details/80112607</guid><author>ma_chen_qq</author><pubDate>Fri, 27 Apr 2018 20:56:05 +0800</pubDate><description><![CDATA[描述：给定一个链表，两两交换其中相邻的节点，并返回交换后的链表。示例:给定 1-&amp;gt;2-&amp;gt;3-&amp;gt;4, 你应该返回 2-&amp;gt;1-&amp;gt;4-&amp;gt;3.说明:你的算法只能使用常数的额外空间。 你不能只是单纯的改变节点内部的值，而且对于链表的操作，一般都要求操作节点而仅仅是修改节点上的数据。思路：    因为需要操作头结点（head），为了统一过程，需要新建一个表头节点（preHe...]]></description><category></category></item></channel></rss>