
数据结构与算法
文章平均质量分 90
大树~~
哦
展开
-
JUC-并发编程18-线程池深入分析-ThreadPoolExecutor-2
前面我们一起学习了Java中线程池的体系结构、构造方法和生命周期,本章我们一起来学习线程池中普通任务到底是怎么执行的。1、案例示例我们创建一个线程池,它的核心数量为5,最大数量为10,空闲时间为1秒,队列长度为5,拒绝策略打印一句话。代码如下:public class ThreadPoolTest01 { public static void main(String[] args) { //核心数量为5,最大数量为10,空闲时间为1秒,队列长度为5,拒绝策略打印一句话。原创 2021-01-12 20:46:05 · 319 阅读 · 0 评论 -
JUC-并发编程17-线程池深入分析-ThreadPoolExecutor-1
1、简介ThreadPoolExecutor的构造方法是创建线程池的入口,虽然比较简单,但是信息量很大,由此也能引发一系列的问题,同样地,这也是面试中经常被问到的问题,下面只是列举了一部分关于ThreadPoolExecutor构造方法的问题。2、构造方法...原创 2020-10-27 21:36:25 · 340 阅读 · 0 评论 -
JUC-并发编程16-线程池深入分析-体系结构
1、简介上一节我们自己手动写了一个线程池,但是它是不支持带返回值的任务的,那么,我们自己能否实现呢?必须可以。2、对比无返回值的任务提交了就完事,主线程并Care它到底没有执行完,并不关心它是不是抛出异常,主线程提交线程到线程池中,其余什么都不管。有返回值的任务就不一样了,主线程首先要提交任务到线程池中,它需要使用到任务执行的结果,所以它必须等到任务执行完毕才能拿到任务执行的结果。那么,为什么不直接在execute的时候就等待任务执行完毕呢?这样的话那不就是串行了,线程池就没有啥意义了。原创 2020-08-31 15:04:29 · 212 阅读 · 0 评论 -
JUC-并发编程15-手写一个线程池
1、简介线程池是java并发编程中经常使用的技术,那么自己如何动手写一个线程池呢?2、属性分析线程池,首先有要一个池子来放线程,而线程又是用来执行任务的。首先,线程池中的线程应该是有类别的,有的线程是核心线程,有的是非核心线程,所以我们需要对这个两个类别线程数量来标记,就我们常说的coreSize和最大线程数量maxSize。当线程池中线程数未达到核心线程数coreSize时,来一个任务加一个线程是可以的,也可以提高任务执行的效率。 当线程池中线程数达到核心线程数后,得控制一下线程的数量原创 2020-08-27 17:50:30 · 212 阅读 · 0 评论 -
JUC-并发编程14-CyclicBarrier栅栏
1、简介CyclicBarrier,回环栅栏,它会阻塞一组线程直到这些线程同时达到某个条件才继续执行。它与CountDownLatch很类似,但又不同,CountDownLatch需要调用countDown()方法触发事件,而CyclicBarrier不需要,它就像一个栅栏一样,当一组线程都到达了栅栏处才继续往下走。...原创 2020-08-27 11:12:48 · 231 阅读 · 0 评论 -
JUC-并发编程13-CountDownLatch倒计时器
1、简介CountDownLatch,可以翻译为倒计时器,但是似乎不太准确,它的含义是允许一个或多个线程等待其它线程的操作执行完毕后再执行后续的操作。CountDownLatch的通常用法和Thread.join()有点类似,等待其它线程都完成后再执行主任务。2、继承关系CountDownLatch中只包含了Sync一个内部类,它没有公平/非公平模式,所以它算是一个比较简单的同步器了。3、内部syncprivate static final class Sync extends A原创 2020-08-20 16:31:09 · 292 阅读 · 0 评论 -
JUC-并发编程12-Semaphore信号量
1、简介Semaphore,信号量,他保存了一系列的许可(permits),每次调用acquire()都将消耗一个许可,每次调用release()都将归还一个许可。2、特性Semaphore通常用于限制同一时间对共享资源的访问次数上,也就是常说的限流。3、继承关系Semaphore中包含了一个实现AQS的同步器Sync,以及它的两个子类FairSync和NonFairSync,这说明Semaphore也是区分公平模式和非公平模式的。4、内部类Syncabstract sta原创 2020-08-19 11:59:34 · 240 阅读 · 0 评论 -
JUC-并发编程11-ReentrantReadWriteLock读写锁
读写锁是一种特殊的锁,它把对共享资源的访问分为读访问和写访问,多个线程可以同时对共享资源进行读访问,但是同一时间只能有一个线程对共享资源进行写访问,使用读写锁可以极大地提高并发量。读写锁实际维护了一对锁,一个读锁,一个写锁,通过分离读锁和写锁,使得其并发性比独占式锁(排他锁)有了很大的提升。为什么需要读写锁?通过前面文章的学习,我们知道了ReentrantLock(下文简称:RLock)对象了。Rlock比起synchronized(下文简称Sync)来说有三个优点:RLock可以被中断;RLock原创 2020-08-18 18:19:03 · 361 阅读 · 0 评论 -
JUC-并发编程10-各种锁名称整理
1、公平锁/非公平锁公平锁,是指按照线程申请的顺序获取锁。非公平锁,是指不是按照线程申请的顺序获取锁,有可能后申请的线程反而先获取到锁,假如先来的线程一直获取不到锁,会造成锁饥饿现象。2、可重入锁是指一个线程获取锁之后再尝试获取锁时会自动获取锁,可重入锁的优点是避免死锁。ReentrantLock和synchronized都是可重入锁。3、独享锁/共享锁独享锁,是指锁一次只能被一个线程持有。共享锁,是指锁一次可以被多个线程持有。ReentrantLock和synchronized都原创 2020-07-20 17:11:28 · 326 阅读 · 0 评论 -
JUC-并发编程-09-阻塞队列BlockingQueue之-DelayQueue
DelayQueue队列中每个元素都有个过期时间,并且队列是个优先级队列,当从队列获取元素时候,只有过期元素才会出队列。1、继承结构从继承体系可以看到,DelayQueue实现了BlockingQueue,所以它是一个阻塞队列。另外,DelayQueue还组合了一个叫做Delayed的接口,DelayQueue中存储的所有元素必须实现Delayed接口。那么,Delayed是什么呢?...原创 2020-07-20 16:31:52 · 228 阅读 · 0 评论 -
JUC-并发编程-08-阻塞队列BlockingQueue之-PriorityBlockingQueue
PriorityBlockingQueue是一个支持优先级的无界阻塞队列,直到系统资源耗尽。默认情况下元素采用自然顺序升序排列。也可以自定义类实现compareTo()方法来指定元素排序规则,或者初始化PriorityBlockingQueue时,指定构造参数Comparator来对元素进行排序。但需要注意的是不能保证同优先级元素的顺序。PriorityBlockingQueue也是基于最小二叉堆实现,使用基于CAS实现的自旋锁来控制队列的动态扩容,保证了扩容操作不会阻塞take操作的执行。我们在数据结构地原创 2020-07-13 22:10:12 · 316 阅读 · 0 评论 -
JUC-并发编程-08-阻塞队列BlockingQueue之-ArrayBlockingQueue
1、概述我们在并发编程中,通常需要线程安全的队列。线程安全的队列分为两种:阻塞队列,使用锁来实现 非阻塞队列,使用CAS来实现。阻塞队列在实际应用中非常广泛,许多消息中间件中定义的队列,通常就是一种“阻塞队列”。其使用场景一般是在 “生产者-消费者” 模式中,用于线程之间的数据交换或系统解耦。“生产者-消费者”这种模式中,“生产者” 和 “消费者” 是相互独立的,两者之间的通信需要依靠一个队列。这个队列就是要说的阻塞队列。引入“阻塞队列”的最大好处就是解耦,在软件工程中,“高内聚,低耦合”是进行原创 2020-07-08 12:11:20 · 239 阅读 · 0 评论 -
JUC-并发编程-07-AtomicInteger源码分析
在多线程编程下,原子类操作必不可少。在juc下面也有为我们提供。如下图:本期以atomicInteger为例,学习源码。1、继承关系从继承关系来看,是没有什么特殊操作的,那么他是如何保证原子操作的。我们下面继续看。首先介绍一下原子操作:原子操作是指不会被线程调度机制打断的操作,这种操作一旦开始,就一直运行到结束,中间不会有任何线程上下文切换。原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱,也不可以被切割而只执行其中的一部分,将整个操作视作一个整体是原子.原创 2020-07-07 15:25:36 · 220 阅读 · 0 评论 -
JUC-并发编程-06-HashMap与CurrentHashMap
本期学习hashMap与currentHashMap一个是我们在单线程的常用的集合框架,但是对于多线程的情况下就不在适用,所以juc下,有个CurrentHashMap。两个比较学习。后面再做个总结。本次学习是基于1.81、HashMap1.1 数据结构1.1.1 继承关系是Map接口的具体实现。1.1.2 属性介绍//默认初始容量-必须为2的幂static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;//最大容量,如原创 2020-07-06 12:11:07 · 605 阅读 · 0 评论 -
算法题-栈和队列-06-生成窗口最大值数组
题:有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边,窗口每次向右边滑一个位置。例如,数组为[4,3,5,4,3,3,6,7],窗口大小为3时:如果数组长度为n,窗口大小为w,则一共产生n-w+1个窗口的最大值。请实现一个函数。解析代码如下:public class MaxWindowStack { //获取窗体里面最值 public s...原创 2020-05-06 12:23:22 · 159 阅读 · 0 评论 -
算法题-栈和队列-05-用一个栈实现另一个栈的排序
题:一个栈中元素的类型为整型,现在想将该栈从顶到底按从大到小的顺序排序,只许申请一个栈。除此之外,可以申请新的变量,但不能申请额外的数据结构。如何完成排序?解答:将要排序的栈标记为stack,申请的辅助栈记为help。在stack上执行pop操作,弹出的元素记为cur。如果cur小于或等于help的栈顶元素,则将cur直接压入help; 如果cur大于help的栈顶元素,则将he...原创 2020-04-13 11:03:09 · 135 阅读 · 0 评论 -
算法题-栈和队列-04-猫狗队列
public class Pet { private String type; public Pet(String type){ this.type=type; } public String getPetType(){ return this.type; }}public class Dog extends Pet{...原创 2020-04-08 14:29:58 · 184 阅读 · 0 评论 -
算法题-栈和队列-03-递归函数和栈操作逆序一个栈
题:一个栈依次压入1、2、3、4、5,那么从栈顶到栈底分别为5、4、3、2、1。将这个栈转置后,从栈顶到栈底为 1、2、3、4、5,也就是实现栈中元素的逆序,但是只能用递归函数来实现,不能用其他数据结构。解答:本题考的是栈的操作和递归函数的设计,我们需要设计出两个递归函数。递归函数一:将栈stack的栈底元素返回并移除。具体过程...原创 2020-04-07 17:20:55 · 304 阅读 · 0 评论 -
算法题-栈和队列-02-由两个栈组成的队列
题:编写一个类,用两个栈实现队列,支持队列的基本操作(add、poll、peek)。解析:我们知道栈是先进后出的,而队列是先进先出。所以我们用两个栈正好能把顺序反过来实现类似队列的操作。具体实现时是一个栈作为压入栈,在压入数据时只往这个栈中压入,记为stackPush;另一个栈只作为弹出栈,在弹出数据时只从这个栈弹出,记为stackPop。因为数据压入栈的时候,顺序是先进后出的...原创 2020-04-03 11:22:28 · 120 阅读 · 0 评论 -
算法题-栈和队列-01-设计一个有getMin功能的栈
今天算法实践第一题,从现在开始每天一到算法实战题。这个子系列是关于栈和队列的算法。我们看下题目:题:实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。难度系数:一颗星解析:首先明白栈的数据结构定义,先进后出。具体可以看我之前的数据结构文章。https://blog.youkuaiyun.com/qq_29434541/article/details/103795755...原创 2020-04-02 18:20:37 · 182 阅读 · 0 评论 -
算法面试与实战-05排序算法- 时间复杂度为O(n)的排序算法(桶排序)
上期我们学习了计数排序,但是计数排序也有局限性,比如针对于double型就不好使用计数排序。所以本期我们学习另一种排序算法来解决非整型排序:桶排序。概念:将数组分到有限数量的桶里,然后对每个桶进行分别排序(有可能使用别的排序算法或者递归继续使用桶排序)。桶排序的思想近乎彻底的分治思想。那么桶是什么概念呢?每一个桶代表一个区间范围,里面可以承载一个或者多个元素。桶排序的第一步,就是创建这些桶...原创 2020-03-18 21:10:24 · 288 阅读 · 0 评论 -
算法面试与实战-04排序算法- 时间复杂度为O(n)的排序算法(计数排序)
hi~上期我们学习了堆排序,是对二叉堆的再次应用,比较桥面。这种的方法的事假复杂度是O(nlogn)有没有这更快的算法呢?有的,我们本期就是学习这个算法-计数排序,什么叫做计数排序呢?首先我们回顾一下以前学习算法,不管是冒泡排序,还是快速排序,堆排序等等都是基于元素的之间的比较来进行排序的。但是有一种特殊的排序算法叫做计数排序,他是利用数组下标来确定元素的正确位置。计数排序是如何进行排...原创 2020-03-17 20:22:18 · 486 阅读 · 0 评论 -
算法面试与实战-03排序算法- 时间复杂度为O(nlogn)的排序算法(堆排序)
hi~大家好,最近疫情慢慢控制,各城市也开始逐步复工。风雨终究会过去,但是依然还是要努力,不管是在什么时候。好了,本篇我们学习堆排序。啥子叫堆排序呢?堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。今天我们就能把二叉堆的知识用上啦。还记得二叉堆的特性是什么吗?最大堆的堆顶是整个堆中的最大元素...原创 2020-03-09 15:38:50 · 718 阅读 · 0 评论 -
算法面试与实战-02排序算法- 时间复杂度为O(nlogn)的排序算法(快速排序)
hi~各位新年已过,今天是上班,中间苗某小小的休息了一下,其实在家好无聊,不想动~但是学习还是不能断,好了我们继续学习排序算法。上期我们说了时间复杂度为O(n2)的排序算法-以冒泡排序为例。本期我们学习时间复杂度为O(nlogn)的排序算法:快速排序 归并排序 堆排序本篇介绍快速排序的原理。1、概念为啥快速排序比冒泡排序快呢,因为快速排序用了分治法的思想。同冒泡排序一样,...原创 2020-03-08 15:01:51 · 1416 阅读 · 0 评论 -
算法面试与实战-01排序算法- 时间复杂度为O(n2)的排序算法(冒泡排序深度优化)
hi~数据结构我们基本完结了,当然后面有新的知识会再添加。现在开始学习算法。本来想先写算法思想的,我找了各种对比,发现比较抽象,感觉还是先易后难比较容易入门。本期我们学习常见的时间复杂度为O(n2)的排序算法冒泡排序 选择排序 插入排序 希尔排序希尔排序比较特殊,他的性能介于O(),但是又比不上O(),暂且归于本类。本篇以比较经典的冒泡排序为例。讲解,后面若是有时间在将其他部分进行...原创 2020-01-25 16:41:04 · 2292 阅读 · 0 评论 -
不就几种数据类型么?07-位运算
hi~本期学习位运算,学完了就开始学习算法了。为啥要学习位运算呢,就从基本java的来说,我们再去看jdk源码的时候,发现很多地方都用到位运算尤其数据结构方面。位运算主要是直接操控二进制时使用 ,主要目的是节约内存,使你的程序速度更快。位运算主要包括按位与(&)、按位或(|)、按位异或(^)、取反( ~ )、左移(<<)、右移(>>)这几种。其中除了取反( ~ ...原创 2020-01-22 15:50:09 · 403 阅读 · 0 评论 -
不就几种数据类型么?06-图论
临近年关,有点倦怠,本来计划周末完成图论,但是赶到过年回家,感冒不舒服,不想动~。这期主要是讲图论,虽然说我们开发中对这块理论不常见,但是也是比较重要的一种数据结构~,咬咬牙,学了就是,对吧,拉屎的时间就够你把我这篇看完了,0.0下面步入正题:1.图论背景引入学前小故事~,开心一晚上。一笔画问题问题描述:18世纪著名古典数学问题之一。在哥尼斯堡的一个公园里,有七座桥将普...原创 2020-01-20 23:14:07 · 156 阅读 · 0 评论 -
不就几种数据类型么?05-补充版-AVL树,红黑树,B树
上期学了关于树的知识点,但是一个朋友说到没有B树,本来想着在写mysql优化之索引原理再将B树和B+树介绍一下。现在介绍也可以写个补充版。啊哈~找找资料,学习一番。本篇介绍AVL树,红黑树,B树。1、AVL树1.1 前景:二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树, 查找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Ad...原创 2020-01-13 23:50:42 · 199 阅读 · 0 评论 -
不就几种数据类型么?05-我家门前有颗“树”
hi~上期我们学习数组,链表,队列和栈,散列表,其实这些都是链式存储。但是仅仅是链式存储已经无法满足我们实际开发的需求了。比如,我们在学习散列表以hashmap举例时。hashMap在java8后做了优化,当链表长度到达8以后转为红黑树结构以便增加查询与修改的效率。1、树1.1 什么是树在生活与软件开发中,层次化的数据之间可能有的祖先—后代、上级—下属、整体—部分以及其他...原创 2020-01-08 15:51:47 · 211 阅读 · 0 评论 -
不就几种数据类型么?04-散列表的神奇之处
hi~这是我重新开始学习的数据结构篇第四篇。这里大致说下为什么把算法和数据结构分开,苗某觉得先把数据结构搞熟悉,然后学算法时候就不会很吃力。前三篇讲了数组,链表,栈和队列。对了上篇留了一个小关子,优先队列如何实现。这个不是在本篇讲解哦,这个设计到树的知识。所以要到下篇。很快的,以苗某的这单身二十年的手速~是吧哈哈。1、散列表学习散列表可以带着几个问题。1)、实现原理-数据结构是什么样子...原创 2020-01-03 17:00:55 · 220 阅读 · 0 评论 -
不就几种数据类型么?03-栈与队列
hi~各位元旦快乐,经过前两篇的学习,我想大家对数据结构的认知不是那么陌生了吧,苗某这几天整理资料,写文章,对数据结构慢慢有了了解。好了,我们前两期学了链表和数组(其实只是基础介绍,还有很多深层次挖掘需要各位看官自己去深入研究啦)。本期我们学习栈与队列。1、物理结构和逻辑结构啥是物理结构,逻辑结构。看名字有点迷。没事,我们慢慢了解。1.1 什么是数据存储的物理结构呢?如果说把数据结...原创 2020-01-02 15:30:56 · 293 阅读 · 1 评论 -
不就几种数据类型么?02-链表
上期回顾:上次我们学习数组,感觉也还好,并没有多少难度~(哈)本期我们学习链表,首先带着几个小问题来学习。1、链表和数组有啥子区别2、链表在内存中存储结构是啥样子的3、它的增删改查的如何做的1、链表1.1概念:链表是一种物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。2、链表的基本结构2.1 单向链表由图可见...原创 2020-01-01 14:30:14 · 252 阅读 · 3 评论 -
不就几种数据类型么?01-数组
哈!这是苗某重新开始学习的第一篇文章。各位看官,别离数月,可否安好?我想还是不错的。快过年了,将去年的计划拿来改个日期...擦,还能用,毕竟是祖国花朵,缝缝补补的优良传统可不丢~哈哈~话归正传,本篇文章的主旨:就是对常见的数据结构做一个普及。画了了一个脑图,如下:哇,这图画的真棒(手动滑稽~)1、数组1.1 数组概念:1)、什么是数组?数组对应的英文是a...原创 2020-01-01 14:21:37 · 196 阅读 · 0 评论