<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[ccuaman的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/ccuaman</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; ccuaman]]></copyright><item><title><![CDATA[如何解决Maven资源过滤问题]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107571616</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107571616</guid><author>ccuaman</author><pubDate>Fri, 24 Jul 2020 23:32:23 +0800</pubDate><description><![CDATA[如何解决Maven资源过滤问题
1.定义
就是让指定配置文件里面的引用maven属性的内容，能够获取到在pom文件中定义的maven属性的值。指定目录：也就就是指src/main/resources和src/test/resources文件下的所有文件，默认情况下，这些文件会被复制到classpath下面，即target/classes下面。

2.例子介绍：
在pom.xml文件做以下设置：
 &lt;properties&gt;
    &lt;project.build.sourceEncoding&]]></description><category></category></item><item><title><![CDATA[Java中IO模型之NIO(同步非阻塞模型)]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107491327</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107491327</guid><author>ccuaman</author><pubDate>Tue, 21 Jul 2020 16:14:35 +0800</pubDate><description><![CDATA[NIO：同步非阻塞模型

NIO中提供了选择器（Selector 类似底层操作系统提供的IO复用器：select、poll、epoll）,也叫做多路复用器，作用是检查一个或者多个NIO Channel（通道）的状态是否是可读、可写。。。可以实现单线程管理多个channel，也可以管理多个网络请求
**Channel：**通道，用于IO操作的连接，在Java.nio.channels包下定义的，对原有IO的一种补充，不能直接访问数据需要和缓冲区Buffer进行交互
通道主要实现类：
SocketChannel]]></description><category></category></item><item><title><![CDATA[Java中IO模型之BIO（同步阻塞模型）]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107491169</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107491169</guid><author>ccuaman</author><pubDate>Tue, 21 Jul 2020 16:08:07 +0800</pubDate><description><![CDATA[Java中IO模型之BIO（同步阻塞模型）
BIO：同步阻塞模型
在JDK1.4之前，建立网络通信采用的BIO模型
需要现在服务器启动一个ServerSocket，然后客户端启动一个Socket来对服务端进行连接，默认的情况下服务端需要对每一个请求建立一个线程等待处理，客户端发送请求后，需要等待服务端是否有相应的线程来处理客户端的连接，如果没有线程则会一致等待或者拒绝请求，如果有的话，客户端会等待线程来处理客户端请求
在了解BIO模型之前先让我们回顾一下Socket通信流程

基于BIO的编程
通过网络通信]]></description><category></category></item><item><title><![CDATA[深入理解三次握手和四次挥手]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107418090</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107418090</guid><author>ccuaman</author><pubDate>Fri, 17 Jul 2020 21:51:26 +0800</pubDate><description><![CDATA[深入理解三次握手和四次挥手
三次握手的过程就像是东北人茬架，场景如下：
一天在东北的酒馆里，两个大哥在不同桌吃着饭呢，一个大哥看见另一个大哥看对眼儿了，下面大哥A叫长海，大哥B叫二柱（如有雷同 不胜感激）
三次握手

长海：你愁啥
二柱：瞅你咋滴
长海：来！干一架！

三次握手（Three-way Handshake）其实就是指建立一个TCP连接时，需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实]]></description><category></category></item><item><title><![CDATA[深入了解ConcurrentHashMap]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107417735</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107417735</guid><author>ccuaman</author><pubDate>Fri, 17 Jul 2020 21:12:43 +0800</pubDate><description><![CDATA[深入了解ConcurrentHashMap
属性及默认值
//默认初始容量 16 
static final int DEFAULT_INITIAL_CAPACITY = 16;
//默认加载因子 0.75
    static final float DEFAULT_LOAD_FACTOR = 0.75f;
//默认的并发度 16 -&gt;segments数组的大小 
    static final int DEFAULT_CONCURRENCY_LEVEL = 16;
//容量的上限-&gt;seg]]></description><category></category></item><item><title><![CDATA[银行家算法]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107326099</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107326099</guid><author>ccuaman</author><pubDate>Mon, 13 Jul 2020 22:16:29 +0800</pubDate><description><![CDATA[银行家算法
在了解银行家算法之前，我们先回顾一下死锁产生的条件和处理方法
死锁产生的四个必要条件
1、互斥条件：一个资源每次只能被一个线程使用
2、请求与保持条件：一个进程因请求资源而阻塞时，对已获得的资源保持不放
3、不剥夺条件：进程已获得的资源，在未使用之前，不能强行剥夺
4、循环等待条件：若干进程之间形成一种头尾相连接的循环等待资源关系
死锁的解除与预防
解决死锁的三种途径：预防、避免、检测与恢复。那么如何避免死锁，就是今天所要踢到的经典避免死锁方法——银行家算法。
避免死锁（银行家算法）
避免死锁的]]></description><category></category></item><item><title><![CDATA[生产者消费者模型]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107325997</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107325997</guid><author>ccuaman</author><pubDate>Mon, 13 Jul 2020 21:50:38 +0800</pubDate><description><![CDATA[生产者-消费者模型
生产者-消费者（producer-consumer）问题，称之为有界缓冲区问题，两个线程共享一个固定的大小的缓冲区
其中一个是生产者、生产消息存放到缓冲区、另一个是消费者，在缓冲区取出消息

具体说明：
生产者生产数据到缓存区，消费者从缓存去取数据
如果缓存区满了，则生产者线程阻塞
如果缓存区空了，消费者线程阻塞
将阻塞的线程在一定的时间进行唤醒，通过线程的通信机制来唤醒，对于生产者线程，他的唤醒是有消费者有消费时就可以通知唤醒，同样，对于消费者线程，他的唤醒是有生产者生产了数据后通知唤]]></description><category></category></item><item><title><![CDATA[深入理解ReentrantLock重入锁]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107325835</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107325835</guid><author>ccuaman</author><pubDate>Mon, 13 Jul 2020 21:46:20 +0800</pubDate><description><![CDATA[ReentrantLock
公平性锁和非公平性锁
非公平性：如果一个线程因为CPU时间全部被其他的线程抢走而无法获得CPU的执行时间，这种状态称之为饥饿，而该线程被称为“饥饿致死”，非公平锁就存在“饥饿”，因为线程得不到CPU的运行时间机会。
Java的线程饥饿原因：
1、高优先级的线程抢夺所有的低优先级的线程CPU时间
2、线程被永久阻塞在一个等待进入同步块的状态
3、线程在等待一个本身也处于永久等待完成的对象（比如调用这个对象的wait方法）
公平性：所有的线程均能公平性的获取到执行的机会
公平性锁的实]]></description><category></category></item><item><title><![CDATA[CAS和Atomic]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107322538</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107322538</guid><author>ccuaman</author><pubDate>Mon, 13 Jul 2020 18:30:20 +0800</pubDate><description><![CDATA[CAS和Atomic
在了解CAS和Atomic之前我们要先来认识一下悲观锁和乐观锁的一个概念！
悲观锁和乐观锁
悲观锁
假设是每次获取数据都认为会被其他线程修改，每次来操作数据（可读、可写）的时候都会加锁
悲观锁的实现是Synchronized
悲观锁存在问题：
1、多线程竞争，引起性能问题 （锁的释放和获取需要上下文切换和调度等）
2、一个线程获取锁会导致其他线程被挂起（则塞）
乐观锁
假设对数据的操作一般都不会发生冲突，读取操作时，不会加锁，在对数据进行变更操作是，才来检测当前的数据是否发送冲突，发生]]></description><category></category></item><item><title><![CDATA[线程通信之wait() 和notify() 方法]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107260428</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107260428</guid><author>ccuaman</author><pubDate>Fri, 10 Jul 2020 18:44:01 +0800</pubDate><description><![CDATA[线程通信之wait() 和notify() 方法
通信方法
wait():调用wait方法的线程，当前持有锁的该线程等待，直至该对象的另一个持锁线程调用notify/notifyAll操作。
wait(long timeOut)、wait(long timeOut,int nanos)
notify():通知持有该对象锁的所有线程中的的随意一个线程被唤醒
notifyAll():通知持有该对象锁的所有线程被同时唤醒
线程通信的方法：wait\notify\notifyAll操作都是属于Object类提供的方]]></description><category></category></item><item><title><![CDATA[深入理解synchronized关键字]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107258713</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107258713</guid><author>ccuaman</author><pubDate>Fri, 10 Jul 2020 18:26:58 +0800</pubDate><description><![CDATA[深入理解synchronized关键字
synchronized是解决线程安全问题的一个方法，提供了线程同步的方式
Synchronized的使用方式
synchronized关键字可以修饰方法或者代码块，确保多个线程在同一时刻，只能有一个线程处理方法或者是同步块，保证线程对访问变量的可见性，有序性，原子性。
• 修饰普通方法
• 修饰静态方法
• 修饰代码块
修饰普通方法
//修饰普通方法
    public synchronized void add() {
        //do somethin]]></description><category></category></item><item><title><![CDATA[深入理解Volatile关键字]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107215623</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107215623</guid><author>ccuaman</author><pubDate>Wed, 08 Jul 2020 21:47:39 +0800</pubDate><description><![CDATA[深入理解Volatile关键字
在仔细讲解Java的volatile关键字之前优先回顾一下并发的特征，并发性的特征一共有三个：原子性，可见性，有序性。
-原子性
如果一个操作是不可分割的，那这就是一个原子操作。相反，如果一个操作是可以分割的，那么他就是非原子操作，
eg：a++是线程安全的操作吗？
答：不是。当有多个线程同时操作a++这个过程时，a++的操作可以分割成int a;a=0;a+1;这三步操作，在每一次操作被调用的时候都会发生错误，所以它是非线程安全操作
-可见性
一个变量被多个线程共享，如果一]]></description><category></category></item><item><title><![CDATA[线程创建与常用方法介绍]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107209017</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107209017</guid><author>ccuaman</author><pubDate>Wed, 08 Jul 2020 16:57:04 +0800</pubDate><description><![CDATA[线程创建与常用方法介绍
一、线程创建方式
- 实现Runable接口
- 继承Thread
- 实现Callable接口
实现Runable接口
public interface Runnable {
    //抽象的run方法
    public abstract void run();
}

实现Runnable接口，实现其提供的run方法
Runnable实现类使用Demo
//Runnable实现类的使用
RunableDemo runable = new RunableDemo();
Thre]]></description><category></category></item><item><title><![CDATA[并发与并行]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107176093</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107176093</guid><author>ccuaman</author><pubDate>Tue, 07 Jul 2020 10:49:42 +0800</pubDate><description><![CDATA[并发与并行
一、什么是并发
并发是指多个线程操作同一个资源，不是同时执行，而是交替执行，单核CPU，只不过因为CPU的时间片很短，速度太快，看起来是同时执行（张三、李四厨师，共用一口锅炒菜，交替执行）

二、什么是并行
并行才是真正的同时执行，多核CPU。每个线程使用一个单独的CPU的资源来运行（张三、李四厨师、一人一口锅，一起炒菜）

三、高并发
高并发：我们设计的程序，可以执行海量的任务同时执行
1.影响高并发性能的四个因素
• QPS：每秒能够响应的请求数，QPS并不是并发数
• 吞吐量：单位时间内处]]></description><category></category></item><item><title><![CDATA[PriorityQueue优先队列源码解析]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107163866</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107163866</guid><author>ccuaman</author><pubDate>Mon, 06 Jul 2020 18:13:02 +0800</pubDate><description><![CDATA[PriorityQueue优先队列源码解析
一、什么是PriorityQueue优先队列？
PriorityQueue 一个基于优先级的无界优先级队列。优先级队列的元素按照其自然顺序进行排序，或者根据构造队列时提供的 Comparator 进行排序，具体取决于所使用的构造方法。该队列不允许使用 null 元素也不允许插入不可比较的对象(没有实现Comparable接口的对象)。
PriorityQueue 队列的头指排序规则最小那个元素。如果多个元素都是最小值则随机选一个。
PriorityQueue 是一]]></description><category></category></item><item><title><![CDATA[Java集合比较器的实现]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107129296</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107129296</guid><author>ccuaman</author><pubDate>Sat, 04 Jul 2020 19:54:43 +0800</pubDate><description><![CDATA[Java集合比较器的实现
一、基本概念
Comparable和Comparator接口都是为了对类进行比较，众所周知，诸如Integer，double等基本数据类型，java可以对他们进行比较，而对于类的比较，需要人工定义比较用到的字段比较逻辑。可以把Comparable理解为内部比较器，而Comparator是外部比较器。
Comparable
Comparable是在集合内部定义的方法实现的排序，位于java.util下。是一个对象本身就已经支持自比较所需要实现的接口，如String、Integer自己]]></description><category></category></item><item><title><![CDATA[HashMap底层源码探究]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107107967</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107107967</guid><author>ccuaman</author><pubDate>Fri, 03 Jul 2020 17:05:20 +0800</pubDate><description><![CDATA[HashMap底层源码探究
一、什么是哈希表
1.定义：散列表（Hash table，也叫哈希表），是根据关键码值(Key value)而直接进行访问的数据结构。也就是说，它通过把关键码值映射到表中一个位置来访问记录，以加快查找的速度。这个映射函数叫做散列函数，存放记录的数组叫做散列表。
给定表M，存在函数f(key)，对任意给定的关键字值key，代入函数后若能得到包含该关键字的记录在表中的地址，则称表M为哈希(Hash）表，函数f(key)为哈希(Hash) 函数。

2.哈希冲突：然而万事无完美，如果两]]></description><category></category></item><item><title><![CDATA[垃圾回收的三种算法]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107067222</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107067222</guid><author>ccuaman</author><pubDate>Wed, 01 Jul 2020 17:07:42 +0800</pubDate><description><![CDATA[垃圾回收的三种算法
主要阐明垃圾回收算法的思想，而不对相关代码进行深究！
其中引用计数法也属于垃圾回收算法中的一种，在java中是通过引用来和对象进行关联的，也就是说如果要操作对象，必须通过引用来进行。那么很显然一个简单的办法就是通过引用计数来判断一个对象是否可以被回收。不失一般性，如果一个对象没有任何引用与之关联，则说明该对象基本不太可能在其他地方被使用到，那么这个对象就成为可被回收的对象了。这种方式成为引用计数法。
这种方式的特点是实现简单，而且效率较高，但是它无法解决循环引用的问题，因此在Java中并]]></description><category></category></item><item><title><![CDATA[LinkedList源码解析]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/107047408</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/107047408</guid><author>ccuaman</author><pubDate>Tue, 30 Jun 2020 18:17:14 +0800</pubDate><description><![CDATA[LinkedList源码解析
简要概述
LinkedList类是List接口的实现类，它是一个集合，可以根据索引来随机的访问集合中的元素，还实现了Deque接口，它还是一个队列，可以被当成双端队列来使用。虽然LinkedList是一个List集合，但是它的实现方式和ArrayList是完全不同的，ArrayList的底层是通过一个动态的Object[]数组来实现的，而LinkedList的底层是通过链表来实现的，因此它的随机访问速度是比较差的，但是它的删除，插入操作会很快。

LinkedList是基于双向]]></description><category></category></item><item><title><![CDATA[常见排序算法及其优化]]></title><link>https://blog.youkuaiyun.com/ccuaman/article/details/106987076</link><guid>https://blog.youkuaiyun.com/ccuaman/article/details/106987076</guid><author>ccuaman</author><pubDate>Sat, 27 Jun 2020 22:01:03 +0800</pubDate><description><![CDATA[排序算法及其优化
一、冒泡排序
每次冒泡过程都是从数列的第一个元素开始，然后依次和剩余的元素进行比较，若小于相邻元素，则交换两者位置，同时将较大元素作为下一个比较的基准元素，继续将该元素与其相邻的元素进行比较，直到数列的最后一个元素

  public static void main(String[] args) {
        int arr[] = {13, 15, 6, 1, 4, 5};
        for (int i = 0; i &lt; arr.length-1; i++) {

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