自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(152)
  • 收藏
  • 关注

原创 八股文-Redis篇

对应类似mset,mget这样的多个key的原生批量操作命令,redis集群只支持所有key落在同一slot的情况,如果有多个key一定要用mset命令在redis集群上操作,则可以在key的前面加上{XXX},这样参数数据分片hash计算的只会是大括号里的值,这样能确保不同的key能落到同一slot里。在链表的基础上,每个节点增加的随机的层数。3.服务器运行ID:每个redis节点,都有其运行ID,运行ID由节点在启动时自动生成,主节点会将自己的运行ID发送给从节点,从节点会将主节点的运行ID存起来。

2023-01-31 11:54:57 574

原创 AQS(AbstractQueuedSynchronizer)

前置知识公平锁和非公平锁、可重入锁、LockSupport、自旋锁、数据结构之链表、设计模式值模板设计模式。是什么字面意思是抽象的队列同步器。源代码结构AbstractQueuedSynchronizer简称AQS。技术解释它是用来构建锁或者其他同步器组件的重量级基础框架及整个JUC体系的基石,通过内置的FIFO队列来完成线程获取资源的排队工作,并通过一个int类型变量表示持有锁的状态。大致意思就是:当某个线程抢占锁资源后,其他线程被阻塞,这些被阻塞的线程怎么才能更好的管理呢?就是通过

2021-08-20 16:52:29 314

原创 LockSupport

是什么LockSupport用于创建锁和其他同步类的基本线程阻塞原语。LockSupport中的park()和unpark()的作用分别是阻塞线程和唤醒阻塞线程。3中让线程等待和唤醒的方法方式1:使用Object中的wait()方法让线程等待,使用Object中的notify()方法唤醒线程。方式2:使用JUC包中的Condition的await()方法让线程等待,使用signal()方法唤醒线程。方式3:LockSupport类的park方法阻塞线程,unpark方法唤醒线程。Obje

2021-08-20 15:10:45 228

原创 String中的intern()方法

案例此案例是《深入理解java虚拟机》中的一个案例。package javase;public class StringPool58Demo { public static void main(String[] args) { String str1 = new StringBuilder("ha").append("llo").toString(); System.out.println(str1); System.out.println(

2021-08-19 11:37:19 592

原创 强、软、弱、虚引用

整体架构强引用当内存不足,JVM开始垃圾回收,对于强引用的对象,就算是出现了OOM也不会对该对象进行回收。强引用是最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还活着,垃圾收集器不会碰这种对象。在Java中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即使该对象以后永远都不会被用到,JVM也不会回收。因此强引用是造成Java内存泄漏的主要原因之一。对于一个普通的对象,如果没有

2021-08-17 14:35:01 114

原创 死锁编码与定位

概念死锁是指两个或两个以上的进程在执行的过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉,那它们都将无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。package juc;import java.util.concurrent.TimeUnit;class HoldLockThread implements Runnable{ private String lockA; private Stri

2021-08-16 14:12:20 115

原创 线程池复习

为什么用线程池,优势。线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任务来执行。它的主要特点为:线程复用;控制最大并发数;管理线程。第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会

2021-08-13 16:51:38 135 1

原创 阻塞队列以及生产者消费者案例

阻塞队列,顾名思义,首先是一个队列,而阻塞队列在数据结构中所起的作用是:线程1向队列添加元素,线程2从队列取元素。当阻塞队列是空时,从队列取元素的操作会被阻塞。当阻塞队列满时,向队列添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加元素的线程也会被阻塞,直到其他线程从队列中移除一个或者多个元素或者完全清空队列后使队列重新变得空闲起来并后续新增。在多线程领域:所谓阻塞,在某些情况下会挂起线程(即阻塞),一旦

2021-08-12 14:10:31 112

原创 CountDownLatch/CyclicBarrier/Semaphore

CountDownLatch让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒。该类主要的两个方法是await()、countDown()。调用await()的方法的线程会进入阻塞状态,其他调用countDown()方法,会使计数器减一,直到减为0,被阻塞的线程才会继续运行。案例一放学后需要一个人最后走负责锁门,那么这个人就需要等待其他同学都走后才会锁门。不加CountDownLatchpackage juc;import java.util.concurrent.CountDownLat

2021-08-11 14:25:39 105

原创 独占锁(写锁)/共享锁(读锁)/互斥锁

理论独占锁:指该锁一次只能被一个线程所持有。对于ReentrantLock和Synchronized而言都是独占锁。共享锁:该锁可以被多个线程所持有。对于ReentrantReadWriteLock来说,其读锁是共享锁,写锁是独占锁。读锁的共享锁可保证并发读是非常高效的,读写,写读,读读的过程是互斥的。代码验证加锁前:package locks;import java.util.HashMap;import java.util.Map;import java.util.concurrent

2021-07-29 17:06:42 1823

原创 公平锁/非公平锁/可重入锁/递归锁/自旋锁

公平和非公平锁公平锁:是指多个线程按照申请锁的顺序获取锁。先来后到。非公平锁:是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁,在高并发下,有可能会造成优先级反转或者饥饿现象。非公平锁的优点在于吞吐量比公平锁大。ReentrantLock默认是非公平锁Lock lock = new ReentrantLock();public ReentrantLock() { sync = new NonfairSync(); }其有

2021-07-28 17:42:40 215

原创 集合类不安全的问题

ArrayList当我们构造一个ArrayList的时候,会为我们创建一个初始容量为10的空列表。/** * Constructs an empty list with an initial capacity of ten. */ //构造一个初始容量为 10 的空列表 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }可以看到,eleme

2021-07-28 15:04:26 151

原创 ABA问题

引言CAS的缺点包括循环判断真实值和主内存的值时会使CPU资源损耗大、只能对一个共享变量执行CAS、ABA问题。CAS算法实现的一个重要前提需要取出内存中某时刻的数据并在当下时刻比较并替换,那么在这个时间差类会导致数据的变化。比如说一个线程one从内存位置V中取出A,这时候另一个线程two也从内存中取出A,并且线程two进行了一些操作将值变成了B,然后线程two又将V位置的数据变成A,这时候线程one进行CAS操作发现内存中仍然是A,但实际上是发生了变化。尽管线程one的CAS操作成功,但是不代表这

2021-07-28 10:40:01 151

原创 CAS底层原理

CAScas(比较与替换)。源码:/** * Atomically sets the value to the given updated value * if the current value {@code ==} the expected value. * * @param expect the expected value * @param update the new value * @return {@code true} if

2021-07-27 17:08:58 326

原创 volatile

volatilevolatile:是jvm提供的一种轻量级的同步机制 它保证了可见性和禁止指令重排序,但不保证原子性。JMM:java内存模型,是一种抽象概念,是一种规范。JMM同步规范: 1.解锁前,线程必须将值刷新回主内存。2.加锁前,线程必须将主内存变量的最新值读到工作内存。3.加锁解锁是同一把锁。主内存与工作内存: jvm程序运行的实例是线程,线程被创建时,jvm会为每个线程分配一个属于自己的工作内存空间,是线程私有的区域。而主内存是线程共享的区域。主内存中的变量为线程共享,当多线

2021-07-27 14:40:18 91

原创 复习篇spring(一)

Spring简介Spring是一个包含了多种框架的集合,例如:Spring framework、SpringMVC、SpringBoot、SpringCloud等,故而又称Spring全家桶。而我们平时所用的Spring框架就是Spring framework。Spring是一种分层的一站式轻量级开源框架,以Ioc(Inverse of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)为核心。其中Ioc就是将对象的创建权交由Spring去创建

2021-07-14 16:25:25 113

原创 sql FIND_IN_SET函数实现一行变多行

介绍FIND_IN_SET(str,strlist):返回str在strlist中所在的位置,没有返回0。注:strlist必须以逗号分隔。数据准备select 'a' a,'1,2' bunion allselect 'b' a,'1,2,3' bselect 1 id,'t1' v union ALLselect 2 id,'t2' v union ALLselect 3 id,'t3' v 将上表转为以下结果实现sqlselect t1.a,t2.id from

2021-07-12 17:46:06 296

原创 格式化生成年、季、月、周的sql语句

根据具体的业务需求,把下面sql语句的时间换成自己想要格式化的时间即可。年SELECT date_format( '2021-07-05 14:55:17', '%Y年' ) sj月SELECT date_format( '2021-07-05 14:55:17', '%Y年%m月' ) sj季度SELECT concat(CONVERT ( date_format( '2021-07-05 14:55:17', '%Y' ) USING utf8mb4 ),'年第',floor(((d

2021-07-05 09:45:55 829

原创 注解:spring实体类与数据库映射注解

介绍以下注解主要功能是用来将实体类和数据库进行映射。这样在建表的时候就不需要写建表语句,直接从实体类用注解标注好,表结构就会自动生成在数据库中。@Entity :可以标注在类上,主要表明该类为实体类。@Table :该注解主要是映射数据库中的表,其中name属性可以指定表名,默认为实体类的名称。@Id :用来指定该实体类(或该表)的主键。@GeneratedValue : 提供主键值的生成策略的规范。默认为自增。@Column : 将实体类属性与表中的字段进行映射。 name属性可以指定字段名。

2021-06-30 15:22:22 7112 1

原创 java用HttpClient发送文件和数据

详情由于业务需求,需要向其他项目的接口发送文件和数据,特此把代码分享一下。发送端//url:需要向指定接口发送的url, dataFile:需要传输的文件, currentTime,filecode,sign:分别是接收端需要的数据,这些可以根据自己//的具体业务来发送相应的数据private void post(String url, File dataFile, String currentTime, String filecode, String sign) throws Excepti

2021-06-24 16:04:32 1912

原创 Redis知识点总结

什么是Redis?简述它的优缺点?Redis(Remote Dictionary Server)本质上是一个Key-Value类型的基于内存的一种非关系型数据库。整个数据库都是加载到内存中进行操作的。定期通过异步操作把数据库flush到硬盘上进行保存。高性能:由于redis是基于内存的,所以对数据的处理非常快。丰富的数据类型:redis支持String、List、Set、Hash、Zset数据类型。redis支持持久化。正因为redis是基于内存的,所以它会受到物理内存的限制,不能用作海量数据

2021-06-17 16:33:10 119

原创 类初始化时机

使用new关键字实例化对象的时候、读取或设置一个类的静态字段的时候、已经调用一个类的静态方法的时候。使用new关键字public class TestClassLoader { static{ System.out.println("**********"); }}public class Test { public static void main(String[] args) { new TestClassLoader(); }

2021-06-11 17:04:04 1070 2

原创 mysql:ON DUPLICATE KEY UPDATE

ON DUPLICATE KEY UPDATEON DUPLICATE KEY UPDATE是mysql独有的一种语句,目的是当需要插入的数据存在时,会执行update,否则执行insert。注: 由于是mysql独有的语句,那么在数据移植是需要注意;而且此语句必须配合唯一索引或者主键使用。例表中数据如下:表中有id为1的数据情况://有数据name修改为楚风,否则添加一条name为叶凡的数据INSERT INTO user(id,name,age) VALUES(1,"叶凡",16) ON

2021-06-02 15:27:11 559

原创 order by和case when联用

今天遇到了一个需求,数据分为了两部分,一部分按照时间正排,另一部分按照时间倒排。我用的方法就是order by和case when联用(也可以用union,不过语句比较多)。案例有以下几条数据:dp为1的按照时间正排,为2的按照时间倒排。SELECT id,name,time,dpFROM USERORDER BY dp,//可写可不写,只是按照dp正排 CASE WHEN dp = 1 THEN time END ASC, CASE WHEN dp = 2 THEN time END

2021-05-20 15:34:03 1655

原创 Fail-Fast(快速失败机制)

介绍快速失败机制是java集合的一种错误检测机制,当迭代集合时集合的结构发生改变,就会产生fail-fast机制。举例单线程情况public class Test { public static void main(String[] args) { List<String> list = new ArrayList<>(); for(int i = 0; i < 10; i++){ list.add(i

2021-05-14 14:25:19 1452 2

原创 希尔排序

插入排序存在的问题例如数组arr = {2,3,4,5,6,1} 这时需要插入的数1的过程是:{2,3,4,5,6,6}{2,3,4,5,5,6}{2,3,4,4,5,6}{2,3,3,4,5,6}{2,2,3,4,5,6}{1,2,3,4,5,6}当需要插入的数是较小的数时,后移的次数明显增多,效率低。希尔排序希尔排序是希尔提出的一种排序算法。它是一种插入排序。是简单插入排序经过改良后的一个版本,也称之为缩小增量排序。基本思想希尔排序是把记录按下标的一定增量分组,对每组使用直接插入

2021-04-02 16:36:16 102

原创 插入排序

基本概念插入排序属于内部排序法,是对要排序的元素以插入的方式寻找该元素的适当位置,以达到排序的目的。基本思想把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。...

2021-04-02 14:33:28 82

原创 选择排序

基本概念选择排序属于内部排序法,是从要排序的数据中,按指定的规则选出某一元素,再依规定交换位置后达到排序的目的。基本思想第一次从arr[0]~arr[n-1]中选取最小值,与arr[0]交换,第二次从arr[1] ~ arr[n-1]中选取最小值,与arr[1]交换,以此类推,从而得到排序后的结果。代码推导package sort;import java.util.Arrays;public class SelectSort { public static void main(S

2021-04-02 10:12:41 62

原创 冒泡排序

基本概念冒泡排序:通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底下的气泡一样逐渐向上冒泡。案例将五个无序的数: 3,9,-1,10,20使用冒泡排序法将其排成一个从小到大的有序数列。如果在某次排序中,没有发生一次交换,可以提前结束排序。代码演变package sort;import java.util.Arrays;public class BubbleSort { public static

2021-04-01 16:05:36 68

原创 排序算法

分类内部排序:指将需要处理的所有数据都加载到内存中进行排序。内部排序大致包括:插入排序(直接插入排序、希尔排序),选择排序(简单选择排序、堆排序),交换排序(冒泡排序、快速排序),归并排序,基数排序。外部排序:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。时间复杂度用来衡量算法执行的时间。一般有两种方法:事后统计法:有两个缺点,一是要想对设计的算法的运行性能进行评测,需要实际运行该程序;二是所得时间的统计量依赖于计算机的硬件、软件等环境因素,这种方式,要在同一台计算机的相同状

2021-04-01 15:04:58 259

原创 回溯算法:八皇后问题

八皇后问题八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。(92种)思路...

2021-03-25 10:00:39 88

原创 迷宫回溯(递归)

递归调用机制简单的递归代码打印public static void main(String[] args) { //递归调用机制 test(4); }public static void test(int n){ if(n > 2){ test(n-1); } System.out.println("n="+n); }阶乘public static int factorial(int n){

2021-03-19 13:40:57 81

原创 前缀、中缀、后缀(逆波兰)表达式

前缀表达式(3+4)*5-6对应的前缀表达式就是[- * + 3 4 5 6]。从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做对应的计算(栈顶元素和次顶元素),并将结果入栈;重复上述过程,知道表达式最左端,最后运算得出的值即为表达式的结果。例如:(3+4)*5-6对应的前缀表达式就是[- * + 3 4 5 6]。针对前缀表达式求值步骤如下:从右至左扫描,将6、5、4、3压入堆栈。遇到+运算符,因此弹出3和4(3为栈顶元素,4为次顶元素),计算出

2021-03-18 10:55:38 1335 2

原创 git常用命令

基本操作状态查看操作: git status (查看工作区、暂存区状态)添加操作: git add [file name] (将工作区的“新建/修改”添加到暂存区)提交操作: git commit -m “commit message” [file name] (将暂存区的内容提交到本地库)查看日志:git log (完整形式)多屏显示控制方式:空格向下翻页b向上翻页q退出git log --pretty=oneline (每个版本以一行的形式显示)git log --

2021-03-17 14:14:17 80

原创 栈实现综合计算器

需求输入一个表达式,利用栈计算其结果。比如,计算式:[722-5+1-5+3-3],输入的是722-5+1-5+3-3的字符串,从而计算结果。以3+2*6-2为例:扫描的第一个数为3,入数栈:继续扫描,下一个为+,并且符号栈为空,入符号栈:接下来的数字为2,继续入数栈:之后的符号为*,并且符号栈中有数据,进行比较。*的优先级大于+,直接入符号栈:接下来的数据为6,入数栈:接下来的数据是-,与符号栈中进行比较,-优先级小于*优先级,此时先将6、 2、*pop出,并进行计算,将计

2021-03-09 17:01:52 125

原创

介绍栈是一个先入后出(FILO)的有序列表。栈是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)。根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除。应用场景子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。处理递归调用:和子程

2021-03-05 14:42:01 101

原创 约瑟夫问题

约瑟夫问题设编号为1,2,……,n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,他的下一位又从1开始报数,数到m的那个人又出列,以此类推,直到所有人出列为止,由此产生一个出队编号的序列。示意图假设n=5,即有5个人;k=1,从第一个人开始报数;m=2,数2下。...

2021-03-05 10:48:47 135 1

原创 双向链表

单向链表的缺点单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找。单向链表不能自我删除,需要靠辅助节点,而双向链表,则可以自我删除。next:指向后一个节点。pre:指向前一个节点。分析遍历方式和单链表一样,只是可以向前,也可以向后查找添加(默认添加到双向链表的最后)(1).先找到双向链表的最后这个节点。(2).temp.next = new HeroNode(3).new HeroNode.pre = temp;修改思路和原来的单向链表一样。删除(1).因

2021-03-04 10:07:11 76 1

原创 人生三境界

人生三境界是有王国维先生从古代几位大词人的词作中摘引出这几段名句来讲做学问的三境界。“昨夜西风凋碧树。独上高楼,望尽天涯路。” —晏殊《蝶恋花·槛菊愁烟兰泣露》“衣带渐宽终不悔,为伊消得人憔悴。” —柳永《蝶恋花·伫倚危楼风细细》“众里寻他千百度。蓦然回首,那人却在,灯火阑珊处。” —辛弃疾《青玉案·元夕》第一境: 对人生的迷茫,孤独而不知前路几何。排除干扰,不为暂时的烟雾所迷惑。可以从短暂的困惑中挣脱出来,寻求目标。想起了刚入社会找工作的时候,也是很迷茫的,不过大方向还是确定了。经过了半

2021-03-01 12:12:14 121 1

原创 单链表倒序遍历

上图要求倒序打印单链表。思路:方法一:先将单链表进行反转操作,然后再遍历即可,这样做的问题是会破话原来的单链表的结构,不建议。方法二:可以利用栈这个数据结构,将各个节点压入到栈中,然后利用栈的先进后出的特点,就实现了逆序打印的效果。//使用栈逆序打印单链表 public static void reversePrint(HeroNode head){ if(head.next == null){ return;//空链表 } .

2021-02-26 11:19:28 604

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除