自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(51)
  • 资源 (1)
  • 收藏
  • 关注

原创 并发编程笔记8--ThreadLocal结构详解

ThreadLocal,即线程变量,是一个以ThreadLocal对象为键,任意对象为值的存储结构。这个结构被附带在线程上,也就是说一个线程可以根据一个ThreadLocal对象查询到绑定在这个线程上的值。可以通过set(T)方法来设置一个值,在当前线程下在通过get()方法获取到原先设置的值。在set方法中,首先获取当前线程,然后获取当前线程关联的ThreadLocalMap,而ThreadLocalMap是ThreadLocal类中定义的一个结构。首先来看下set方法,基于JDK8。

2024-05-25 21:38:51 461

原创 并发编程笔记7--并发编程基础

现代操作系统中运行一个程序,会为他创建一个进程。而每一个进程中又可以创建许多个线程。现代操作系统中线程是最小的调度单元。。一个Java程序从main方法开始执行,然后按照既定的顺序执行代码,看上去没有其他线程参与。但实际上Java程序天生就是多线程程序。我们可以通过JMX来查看一个普通的Java程序包括哪些线程。上面代码执行结果如下:从上图可以看到,一个Java程序运行不仅是main方法的运行,而是main进程和一些其他进程的同时运行。

2024-05-25 21:38:11 501

原创 并发编程笔记6--双重检查锁与延迟初始化

通过对比基于volatile的双重检查锁定方案和基于类初始化的方案,我们发现类初始化方案的实现代码更加简洁。但基于volatile的双重检查锁定方案有一个额外的优势:除了可以对静态字段实现延迟初始化外,还可以对实例实现字段实现延迟加载。

2024-05-18 13:48:24 1039

原创 并发编程笔记5--Java内存模型

JMM通过happens-before关系向程序员提供跨线程间的内存可见性保证。如果A线程的写操作a和B线程的读操作B存在happens-before关系,那么无论a操作和b操作在不在一个线程里,JMM都保证a操作对b操作是可见的。如果一个操作happens-before另一个操作,那么第一个操作的执行结果对第二个操作是可见的,切第一个操作的执行顺序在第二个操作前面。如果两个操作存在happens-before关系,并不意味着java平台就按照happens-before关系指定的关系来进行。

2024-05-18 13:47:24 716

原创 并发编程笔记3--synchronize底层实现原理

Java中每一个对象都可以作为锁,具体的表现为以下3中方式当一个线程试图访问同步代码块时,他必须先获得锁。退出或抛出异常必须释放锁。那么锁到底存在哪里呢?锁中存储的是什么信息呢?从JVM规范中可以看到Synchronize在JVM中的实现原理,JVM是基于进入或退出Monitor对象来实现方法同步和代码块同步,但两者的实现细节不一样。1、代码块同步是使用monitorenter和monitorexit指令实现,2、而方法同步是使用另一种方式实现的,细节在JVM规范中并未详细说明。

2024-05-17 18:09:12 791

原创 并发编程笔记4--原子操作的实现原理

32位IA-32处理器使用基于对缓存加锁或者总线加锁的方式来实现多处理器之间的原子操作。处理器保证从系统内存内读取或写入一个字节是原子的,意思是当一个处理器读取一个字节时,其他处理器不能访问这个字节的地址。

2024-05-17 18:07:52 855

原创 并发编程笔记2--volatile底层实现原理

定义:Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致性更新,线程应该通过排它锁确保单独获得这个变量。volatile在某些情况下比锁更加方便,如果一个字段被声明成volatile,Java线程模型确保所有线程看到的这个变量都是一致的。当一个线程修改这个变量时,其他线程能读到这个修改后的值。

2024-05-16 13:18:38 324

原创 并发编程笔记1--上下文切换

我们知道在单核处理器中也支持多线程,CPU通过为每个线程分配CPU时间片来实现“看上去”的并发。由于每个CPU时间片时间很短,CPU通过快速的切换CPU时间片,来实现我们看上去的多线程的并发执行。但是从CPU的角度来看实际上还是串行执行。因为每个时间片很短,CPU切换时间片之后还要切换到原来的线程上继续执行,其就要保存原来线程的状态,在其切换到原来的线程之后可以在加载到这个任务的状态(继续接着上次的执行)。总结:任务从保存到在加载的过程算是一次上下文切换。

2024-05-16 13:16:44 456

原创 并发编程知识图

然后,既然并发很重要,而并发处理的是任务,接下就是:对任务的抽象、拆解、分工执行。而线程模型,只是其中的一种模型,还有多进程、协程。Java使用的是多线程模型,对应到具体的代码就是:Thread, Runnable, Task,执行任务有:Exectors。引出了线程,有势必存在着线程安全性的问题,因为多线程访问,数据存在着不一致的问题。首先,得理解并发的重要性,为什么需要并发?对于这个问题,只需要放在潜意识里面,只需要两个字:性能!其它的细节,再去慢慢拓展。

2024-05-15 22:12:21 262

原创 布隆过滤器

布隆过滤器本质上是一种数据结构,一种比较巧妙的概率性数据结构。它的特点就是高效的插入和查询。可以用来判断“某个元素是否一定不存在或者可能存在”。在通常情况下,我们要判断某个元素是否存在,可能用的最多还是HashMap。我们确实可以将其映射成HashMap的key。然后可以在O(1)的时间复杂度内返回结果,效率很高。但是HashMap也有自己的缺点。那就是当存储的元素很多的时候,会占用大量的内存。布隆过滤器本质上就是一个bit数组。布隆过滤器本质上是一种数据结构。那么,布隆过滤器是如何存储元素的呢?当

2024-05-15 22:07:59 967

原创 十六、Redis和数据库双写一致性问题

针对上面的情景,睡眠的时间应该根据自己的业务来进行判断,写数据的休眠时间应该在读数据的耗时基础上加上个几百毫秒即可。这样做的目的可以确保读请求结束后,写请求可以删除读请求造成的缓存脏数据。上面就会出现数据不一致问题,即使请求A先删掉缓存,这是请求B在A更新数据库前请求,就会出现又将旧值写到缓存的问题。这就出现请求A更新缓存应该比请求B更新缓存早,但是因为某种原因,B的更新却比A的更新早。这就造成了缓存中的脏数据出现。当请求A去删除请求B读取的旧值写到的缓存时失败,这是又会出现,缓存和数据库不一致的情况。

2024-05-13 13:08:54 944

原创 十五、Redis缓存常见问题

*缓存穿透:**是指查询了一个必然不存在的数据,缓存中和数据库中都不会存在的数据。这就可能存在别人恶意攻击的风险,比如拿个数据库中必然不存在的id(-1,或者非常大的),每次请求都会请求到数据库。缓存击穿是指一个key在缓存中不存在,但是数据库中存在的情况。最常见的情况就是,一个key非常热门,在短时间有有很高的并发在请求。但是如果缓存由于某些原因(比如:机器宕机)或者大量的key由于超时时间相同在同一时刻失效(大批key失效/热点数据失效),大量请求直接请求到数据库中,数据库压力陡增导致系统雪崩。

2024-05-13 13:08:19 889

原创 十四、Redis Cluster集群

总的来说,Redis Cluster相当于是把Redis的主从架构和Sentinel继承在一起,从Reids Cluster的高可用机制、判断故障转移以及执行故障转移的过程,都和主从、Sentinel相关。这也就是为什么说,主从是Redis高可用的基石。

2024-05-12 12:42:44 671

原创 十三、Redis哨兵模式--Sentinel

每个Sentinel以每秒一次的频率向他所知master、slave以及其他Sentinel发送一次ping命令。如果一个实例距离最后一次回复ping命令的时间超过指定的值,则这个实例会被Sentinel标记为主观下线。如果一个master被标记为主观下线,则正在监控这个master的其他Sentinel要以每秒一次的频率确认master是否进入主观下线。如果有足够数量的Sentinel(大于等于quorum指定的值)认为master确实处于主观下线状态,那么master会被标记为客观下线。

2024-05-12 12:42:11 748 1

原创 十二、Redis主从复制

Redis启动时,会创建一个长度为40的随机字符串,作为replid的初值,在建立主从连接后,会用master的replid替换自己的replid。所有的写操作都在master节点上,master节点执行完毕,会将写命令分发到下面的slave节点,如果slave节点下还有其他slave节点,那么写命令会进一步下发到自己下面的slave节点上。在这个过程中,对master的性能损耗较大,slave节点构建数据的时间较长,而且传递rdb文件还会占用大量的带宽,对整个系统的性能和资源的访问影响较大。

2024-05-12 12:39:55 959

原创 十一、Redis持久化-RDB、AOF

Redis提供了两种持久化数据的方式。一种是RDB快照,另一种是AOF日志。RDB快照是一次全量备份,AOF日志是连续的增量备份。RDB快照是以二进制的方式存放Redis中的数据,在存储上比较紧凑;AOF日志记录的是对内存数据修改的指令文本记录。Redis提供的持久化机制,可以有效的避免Redis因为进程退出导出的数据丢失问题。

2024-05-12 12:39:23 1378

原创 十、Redis内存回收策略和机制

在Redis中可以设置key的过期时间,以期可以让Redis回收内存,循环使用。在Redis中有4个命令可以设置Key的过期时间。分别为expirepexpireexpireatpexpireat。

2024-05-11 11:10:55 373

原创 七、Redis三种高级数据结构-HyperLogLog

比如数据集{1,3,5,7,9,3,5,7},那么这个数据集的基数集为{1,3,5,7,9},基数为5(不重复的元素)。基数估计就是在误差可接受的范围内,快速计算基数。

2024-05-11 11:09:19 423

原创 六、Redis五种常用数据结构-zset

dict用来存储value到score的映射关系,这样就可以在O(1)时间内找到对应value的score值。skiplist按照从小到大的顺序存储分数。skiplist每个元素的值都是对。

2024-05-09 09:46:24 562

原创 五、Redis五种常用数据结构-SET

的结构存储的数据和中的类似,都是无序且不重复的。其底层的数据结构有两种,一是当为整数时,且数据量不大时采用来存储。其他情况使用字典存储。集合中最多存储232-1(40多亿)个数据。示意图如下:以上任何一个条件不满足就会使用字典结构。见Hash中的dict结构

2024-05-09 09:45:53 649

原创 四、Redis五种常用数据类型-List

List是Redis中的列表,按照插入顺序保存数据,插入顺序是什么样的,数据就怎么保存。可以添加一个元素到列表的头部(左边)或者尾部(右边)。一个列表最多可以包含232-1个元素(4294967295,每个列表超过40亿个元素)。是一种双向列表结构。与中的类似,中的是一个双向链表,也是由一个个的节点组成。借助语言的链表节点结构如下:指向前一个节点,指向下一个节点,保存着当前节点对应的数据对象。结构示意图如下:链表的结构如下:指向链表的头结点,指向链表的尾节点。表示链表有多少个节点,这样可以在的时间复

2024-05-08 13:21:41 1185

原创 三、Redis五种常用数据结构-Hash

Hash是redis中常用的一种无序数据结构。结构类似HashMap。

2024-05-08 13:21:05 984

原创 二、Redis五种常用数据类型-String

SDS所有的API都是以二进制的方式处理buf数据,且不会对数据做任何处理,写入的时候是什么样子,读取到的也是什么样的。当执行字符串长度减少时,SDS并不会直接减少数据结构的长度,而是修改SDS结构中的len和free(减少len,增加free,保持字符串的总长度不变),避免内存重新分配。:字符串只是简单的字符的数组,当使用strlen获取字符串的长度时,内部其实是顺序遍历数组的内容,找到’\0’对应的字符,从而计算出字符串的长度,即O(n)C字符串除了末尾外不能出现空字符,否则会被认为是字符串的末尾。

2024-05-06 19:40:50 586

原创 一、Redis五种常用数据类型

3、原子—redis的所有单个操作都是原子性,即要么成功,要么失败。其多个操作也支持采用事务的方式实现原子性。1、支持数据的持久化,其可以将数据持久化到磁盘,在下次启动时,重新加载到内存中。2、支持数据备份,即master-slave。2、丰富的数据类型 5种常用,3种高级。1、性能高—基于内存实现数据的存储。

2024-05-06 19:40:15 311 1

原创 JVM笔记4-虚拟机类加载机制

【代码】JVM笔记4-虚拟机类加载机制。

2024-05-05 13:00:41 874 2

原创 JVM笔记3-经典的垃圾收集器

停顿时间越短,越适合需要与用户交互或者需要保证服务响应质量的程序。无法搭配使用的原因在本章ParNew收集器中介绍。

2024-05-05 12:59:45 1209 1

原创 JVM笔记2--垃圾收集算法

稍后收集器会对F-Queue队列上的对象进行第二次小规模标记,如果对象想在finalize()中成功拯救自己——只要。

2024-05-04 13:03:35 1252 1

原创 JVM笔记1--Java内存区域

无论是从父类继承下来的还是子类中定义的字段都必须记录下来。这部分的存储顺序会受到虚拟机分配策略参数(-XX:FieldsAllocationStyle参数)和字段在Java源码中定义的顺序有关。HotSpot虚拟机默认的分配顺序为:longs/doubles、ints、shorts/chars、bytes/booleans、oops,从以上默认分配策略中可以看到,相同宽度的字段总是被分配到一起。在满足这个条件的情况下,在父类中定义的字段会出现子类之前。

2024-05-04 13:02:37 877 2

原创 JVM启动参数设置发生OOM异常,生成dump

JVM启动参数设置 发生OOM,生成dump

2024-05-03 16:15:05 499

原创 JVM笔记-常用命令

JVM笔记-常用命令。

2024-05-03 16:13:11 1138

原创 Spring Scheduled 定时任务没有准时执行

Spring Scheduled 定时任务没有准时执行

2022-05-05 17:58:08 4136

原创 ShardingSphere--Spring boot启动时在ShardingDataSource加载数据库表元数据卡死(慢)的问题

记一次在使用ShardingSphere出现的问题。先说下项目的环境:Spring Boot 2.2.9,ShardingSphere 4.1.1。接下来看下问题现象,不报错就是卡死在加载表元数据那布,项目直接起不来,一直在处理表元数据的加载。![image.png](https://img-blog.csdnimg.cn/img_convert/d0b790579c7e248bc5ac023b9940c793.png#clientId=ua3f7899f-817c-4&from=paste&

2021-08-19 10:00:05 12613 18

原创 归并排序-java实现

基本思想: 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案”修补”在一起,即分而治之)。如图: 可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。...

2018-09-13 16:10:53 165 1

原创 全排列问题

今天在刷剑指offer编程题时遇到全排列的问题,现在在这记录下。题目如下:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。...

2018-09-12 20:27:45 19610 2

原创 小型新闻发布系统-总结

小型新闻发布系统   一、客户需求分析 1.小型新闻发布系统,面向的是发布新闻的人员和管理系统的管理人员 对于两种身份的用户,要具有登陆界面 2.对于发布新闻的人员来说,该系统要具有新闻的发布和查看功能,同时该系统还支持文件的上传和下载 3.对于管理人员来说即具有普通用户的功能,又有自己的特有权限,即在该系统上注册的人员信息的查看 删除 修改 二、项目运行截图 登陆页面: ...

2018-08-21 17:51:35 21934 20

原创 斐波那契查找—Java实现

基本思想:也是二分查找的一种提升算法,通过运用黄金比例的概念在数列中选择查找点进行查找,提高查找效率。同样地,斐波那契查找也属于一种有序查找算法。相对于折半查找,一般将待比较的key值与第mid=(low+high)/2位置的元素比较,比较结果分三种情况:   1)相等,mid位置的元素即为所求   2)>,low=mid+1; 3)<,high=mid-1。  斐波...

2018-08-20 17:13:10 2759 4

原创 差值查找—Java实现

在介绍插值查找之前,首先考虑一个新问题,为什么上述算法一定要是折半,而不是折四分之一或者折更多呢?   打个比方,在英文字典里面查“apple”,你下意识翻开字典是翻前面的书页还是后面的书页呢?如果再让你查“zoo”,你又怎么查?很显然,这里你绝对不会是从中间开始查起,而是有一定目的的往前或往后翻。   同样的,比如要在取值范围1 ~ 10000 之间 100 个元素从小到大均匀分布的数组中查...

2018-08-20 16:19:10 714

原创 二分查找—Java实现

说明:元素必须时有序的,如果是无序的要先进行无序操作基本思想:也称为折半查找,属于有序查找算法。每次取数组的中间值作为比较对象,如果小于a[mid] 则在数组的右边继续比较,如果大于a[mid] 则在数组的左边继续比较,如果等于a[mid] 则返回mid时间复杂度:最坏情况下,关键词比较次数为,且期望时间复杂度为O()注意:折半查找的前提条件是需要有序表顺序存储,对于静态查找表...

2018-08-20 16:04:06 171

原创 顺序查找—Java实现

说明:顺序查找适用于存储结构为顺序存储或链式存储的线性表基本思想:顺序查找也称为线性查找,属于无序查找算法。从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值key相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于key的结点,表示查找失败时间复杂度:查找成功时的平均查找长度为(n+1)/2若查找不成功,需要n+1次比较,时间复杂度为O(n)所以顺序...

2018-08-20 15:48:04 648

转载 快速排序—Java实现

基本思想:先从数列中取出一个数作为基准数分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边再对左右区间重复第二步,直到各区间只有一个数快速排序=挖坑填数+分治法实例: 数组a[]如下,取第一个数作为基准点 初始时,i=0; j=9; key=a[i]=72 因为已经将a[0]保存到key种,可以理解为在a[0]上挖了一个坑,可以将其他数据填进...

2018-08-19 18:40:24 122

小型新闻发布系统

小型新闻发布系统

2018-08-20

空空如也

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

TA关注的人

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