- 博客(61)
- 收藏
- 关注
原创 Redis网络模型
当我们的客户端想要去连接我们服务器,会去先到IO多路复用模型去进行排队,会有一个连接应答处理器,他会去接受读请求,然后又把读请求注册到具体模型中去,此时这些建立起来的连接,如果是客户端请求处理器去进行执行命令时,他会去把数据读取出来,然后把数据放入到client中, clinet去解析当前的命令转化为redis认识的命令,接下来就开始处理这些命令,从redis中的command中找到这些命令,然后就真正的去操作对应的数据了,当数据操作完成后,会去找到命令回复处理器,再由他将数据写出。我们来梳理一下这张图。
2023-06-11 08:32:55 825 2
原创 Redis通信协议、过期回收策略
try {// 1.建立连接 String host = "服务器IP";// 2.获取输出流、输入流 writer = new PrintWriter(new OutputStreamWriter(s . getOutputStream() , StandardCharsets . UTF_8));// 3.发出请求 // 3.1.获取授权 auth 123321 sendRequest("用户名" , "密码");
2023-06-03 20:45:11 2561 2
原创 Redis五大基本数据结构(原理)
对⼀个内部表示成long型的string执行append, setbit, getrange这些命令,针对的仍然是string的值(即⼗进制表示的字符串),而不是针对内部表⽰的long型进⾏操作。因此,在这些命令的实现中,会把long型先转成字符串再进行相应的操作。String的内部存储结构⼀般是sds(Simple Dynamic String,可以动态扩展内存),但是如果⼀个String类型的value的值是数字,那么Redis内部会把它转成long类型来存储,从⽽减少内存的使用。
2023-05-28 09:01:00 1707
原创 Redis数据结构——QuickList、SkipList、RedisObjective
是一个节点为ZipList的双端链表。节点采用ZipList,解决了传统链表的内存占用问题。控制了ZipList大小,解决连续内存空间申请效率问题。中间节点可以压缩,进一步节省了内存。跳跃表是一个双向链表,每个节点都包含score和ele值。节点按照score值排序,score值一样则按照ele字典排序。每个节点都可以包含多层指针,层数是1到32之间的随机数。不同层指针到下一个节点的跨度不同,层级越高,跨度越大。增删改查效率与红黑树基本一致,实现却更简单。
2023-05-21 08:36:22 520
原创 Redis数据结构——动态字符串、Dict、ZipList
我们都知道Redis中保存的Key是字符串,value往往是字符串或者字符串的集合。可见字符串是Redis中最常用的一种数据结构。不过Redis没有直接使用C语言中的字符串,因为C语言字符串存在很多问题:获取字符串长度的需要通过运算非二进制安全不可修改Redis构建了一种新的字符串结构,称为简单动态字符串(Simple Dynamic String),简称SDS。例如,我们执行命令:那么Redis将在底层创建两个SDS,其中一个是包含“name”的SDS,另一个是包含“虎哥”的SDS。Redis是
2023-05-12 19:55:09 766 1
原创 JAVA模拟堆
/存放堆中的数据 static int [ ] ph;//存放第k个插入点的下标 static int [ ] hp;//存放堆中点的插入次序 static int size;//存放堆中数据个数堆虽然是一种树,但在堆的存储中,通常使用数组存储。这是因为数组在从下标1开始存储值的时候,假设树根root为n,那么它的左子树为2n,右子树为2n+1。
2023-05-06 16:05:13 503 1
原创 LinkedBlockingQueue原理
主要列举 LinkedBlockingQueue 与 ArrayBlockingQueue 的性能比较。Dummy 节点用来占位,item 为 null。高明之处在于用了两把锁和 dummy 节点。
2023-04-23 16:48:36 647
原创 Java8 ConcurrentHashMap源码解析
可以看到实现了懒惰初始化,在构造方法中仅仅计算了 table 的大小,以后在第一次使用时才会真正创建。
2023-04-15 20:15:05 445
原创 ReentrantLock原理--非公平锁、可重入、可打断性
先从构造器开始看,默认为非公平锁实现NonfairSync 继承自 AQS没有竞争时第一个竞争出现时Thread-1 执行了CAS 尝试将 state 由 0 改为 1,结果失败进入 tryAcquire 逻辑,这时 state 已经是1,结果仍然失败接下来进入 addWaiter 逻辑,构造 Node 队列图中黄色三角表示该 Node 的 waitStatus 状态,其中 0 为默认正常状态Node 的创建是懒惰的。
2023-04-01 20:08:18 451
原创 Java并发之AQS原理
全称是 AbstractQueuedSynchronizer,是阻塞式锁和相关的同步器工具的框架。特点:用 state 属性来表示资源的状态(分独占模式和共享模式),子类需要定义如何维护这个状态,控制如何获取锁和释放锁。
2023-03-25 19:51:54 866
原创 自定义线程池以及异步模式之工作线程
对于线程池ExecutorService的实现,学过JUC的都不会陌生,那么怎样去定义一个线程池呢?或者说怎样去实现一个线程池呢?这个问题相信很多人都没有想过。简单来说,线程池就是一个线程集合去处理一个工作阻塞队列中的任务,处理一个出队一个,下面就简单实现一个线程池。第一步:自定义拒绝策略接口@FunctionalInterface // 拒绝策略 interface RejectPolicy < T > {第二步:自定义任务队列。
2023-03-18 19:55:50 491 2
原创 偏向锁撤销
1> 测试延迟特性2> 测试偏向锁利用 jol 第三方工具来查看对象头信息处于偏向锁的对象解锁后,线程 id 仍存储于对象头中。3> 测试禁用在上面测试代码运行时在添加 VM 参数 -XX:-UseBiasedLocking 禁用偏向锁。4> 测试 hashCode。
2023-03-11 16:20:20 644
原创 synchronized原理(轻量级,锁膨胀,自旋,偏向锁)
如果一个对象虽然有多线程要加锁,但加锁的时间是错开的(也就是没有竞争),那么可以使用轻量级锁来优化。轻量级锁对使用者是透明的,即语法仍然是。
2023-03-04 17:10:39 830
原创 对象分配策略
首先进入新生代的Eden区,此后要么是朝生夕死的对象,在某次Minor GC中被回收,要么在新生代中熬过15次Minor GC(默认晋级老年代的分代年龄阈值为15),当对象进入老年代后,就很难轻易被回收了。当然,总有对象死亡的一天,只是时间问题罢了。总体的流程就是这样,但细心的人会发现,文字所描述的过程跟图上有所差别,这里就不得不提一下JVM的动态对象年龄判定,和空间分配担保了。但在我们编码过程中,肯定不是所有的对象都会一直生存到最后,也会有一些特殊情况,而虚拟机也考虑到各种情况,也对其做出了应对。
2023-02-26 10:03:59 532 2
原创 CMS垃圾回收器
上述四个步骤中,初始标记和重新标记两个步骤会“Stop The Word”,也就是会暂停用户线程,如下图。CMS 的并发标记和并发清理阶段, 用户线程是还在继续运行的, 程序在运行自然就还会伴随有新。CMS无法处理浮动垃圾,CMS和用户线程并发运行期间预留的内存不够新对象分配,导致并发失败。的垃圾对象不断产生, 但这一部分垃圾对象是出现在标记过程结束以后,只能下次垃圾回收处理。并行:指多条垃圾收集器线程并行工作,此时用户线程处于等待状态。并发:指用户线程和垃圾回收线程同时工作(也可以交替工作)
2023-02-19 09:52:41 470
原创 对象的内存布局
HotSpot VM使用oop描述对象,oop字面意思是“普通对象指针”。它是指向一片内存的指针,只是将这片内存‘视作’(强制类型转换)Java对象/数组。对象的本质就是用对象头和字段数据填充这片内存。
2023-02-05 13:30:54 174
原创 String的不可变性
如果一个对象在创建之后就不能再改变它的状态,那么这个对象是不可变的(Immutable)。不能改变状态的意思是,不能改变对象内的成员变量,包括基本数据类型变量的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。
2023-01-15 14:37:04 346
原创 JVM方法区的内部结构
而Java 中的字节码需要数据支持,通常这种数据会很大以至于不能直接存到字节码里,换另一种方式,可以存到常量池,这个字节码包含了指向常量池的引用。如果代码多,应用到的结构会更多!常量池表(Constant Pool Table) 是 Class 文件的一部分,用于存放编译期生成的各种字面量与符号应用,这部分内容将在类加载后存放到方法区的运行时常量池中。当创建类或者接口的运行时常量池时,如果构造运行时常量池所需的内存空间超过了方法区所提供的最大值,则 JVM 会抛 OutOfMemoryError 异常。
2022-12-11 09:33:16 492
原创 MinorGC、MajorGC、FullGC
当我们学习到JVM堆时,我们避免不了与GC打交道,其中大家经常混淆Minor GC、Major GC、Full GC,年轻代GC、老年代GC,本篇主要介绍Minor GC、Major GC、Full GC的区别。JVM堆内存被分为年轻代(Young Generation)和老年代(Old Generation)还有永久代和元空间,jdk1.8之前称为永久代,1.8之后称为元空间。Minor GC1.年轻代年轻代是所有新对象产生的地方,当年轻代内存空间被用完时,就会触发垃圾回收,这个垃圾回收叫做Minor G
2022-12-04 15:28:21 266
原创 JVM栈帧
栈帧是栈中的一个栈元素,是一中用于帮助虚拟机执行方法调用与方法执行的数据结构,当前线程中,每执行一个方法就会往栈中插入一个栈帧。栈帧本身是一种数据结构,封装了方法的局部变量表、动态链接信息、方法返回地址(即返回到方法的调用者)以及操作数栈Java虚拟机栈(Java Virtual Machine Stacks)是线程私有的,换句话说,每个线程都会有一个栈,所以对于栈帧来说不存在并发调用的情况。
2022-11-27 10:17:26 352
原创 JVM运行时数据区域之PCRegister和虚拟机栈
如果线程正在执行的是一个 Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;是完全由具体的虚拟机实现自行决定的事情。与程序计数器一样,Java 虚拟机栈(Java Virtual Machine Stack)也是线程私有的,长度的 long 和 double 类型的数据会占用两个变量槽,其余的数据类型只占用一个。Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据。拟机规范》的规定,Java 虚拟机所管理的内存将会包括以下几个运行时数据区域,如图。
2022-11-20 10:39:10 461
原创 实现延迟队列的几种途径
延时队列相比于普通队列最大的区别就体现在其延时的属性上,普通队列的元素是先进先出,按入队顺序进行处理,而延时队列中的元素在入队时会指定一个延迟时间,表示其希望能够在经过该指定时间后处理。从某种意义上来讲,延迟队列的结构并不像一个队列,而更像是一种以时间为权重的有序堆结构。
2022-11-13 08:51:54 2865
原创 线程安全的使用ArrayList和HashMap
如果你看过源码,那么你肯定知道ArrayList和HashMap是线程不安全的,它们二者都采用了fast-fail机制。但之前小组考核的时候,学长问了我如何线程安全的使用HashMap,那时候确实直接呆滞了,话不多说,那么如何线程安全的实现二者呢?
2022-11-05 21:32:25 400
原创 Java中的语法糖
语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。简而言之,语法糖让程序更加简洁,有更高的可读性。可能对于第一次听说语法糖的人来说,百度出来的简介并不能让你有一个比较清晰的认知,只知道是一种语法,并且是方便程序员的使用。那我换一种说法,Switch语句相信大家都有认知,类型泛型擦除也有一定的了解,那么为什么Java语言能做到呢?这就是语法糖的实现了。
2022-10-30 09:13:20 412
原创 横向越权与纵向越权
其原理是由于Web应用没有做权限控制,或仅仅在菜单上做了权限控制,导致恶意用户只要猜测其他管理页面的URL,就可以访问或控制其他角色拥有的数据或页面,达到权限提升的目的。对于一个请求,或者说一个接口,经常使用url拼接的方式去传递参数,如果攻击者在浏览的时候提前知悉了url的参数以及拼接顺序,那么他就可以在任意账号去随意执行你的接口。越权又分为横向越权和纵向越权。即预先定义不同的权限角色,为每个角色分配不同的权限,每个用户都属于特定的角色,横向越权指的是攻击者尝试访问与他拥有相同权限的用户的资源。
2022-10-23 14:20:30 4877
原创 Java中的位运算符号
运算符规则为:参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位同时为 1,那么计算结果才为 1,否则为 0。,其运算规则是:参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位相同(同时为 0 或同时为 1)时,结果为 0;即 1 & 1 = 1 ,1 & 0 = 0,0 & 1 = 0,0 & 0 = 0。即 1 | 1 = 1 ,1 | 0 = 1,0 | 1 = 1,0 | 0 = 0。即 1 ^ 1 = 0 ,1 ^ 0 = 1,0 ^ 1 = 1,0 ^ 0 = 0。
2022-10-16 08:47:28 824
原创 ArrayList扩容机制
继Springsecurity后,框架的学习暂时告一段落,现在回过头来学习Java的一些源码有些许感悟。从学习编程语言开始,我们都是先学习了数组,之后才是集合。众所周知,数组在定义的时候,一般都需要定义数组的空间大小,而ArrayList集合却并不需要。之前也浑然不在意,直到后来听别人问我,为什么集合在引用的时候可以不去传入空间大小?我无言以对,那时候才知道了ArrayList的自动扩充这个概念。
2022-10-09 10:50:17 1325 1
原创 Springboot整合Cos云存储
其实最好的方式是将Cos云配置信息放入application.properties或application.yml文件中,但我在之前配置的时候因为一些原因没这么配置,只好就这样写了,有兴趣的话可以自己配置到配置文件中,引用会更加方便。详细信息直接看代码。最后,delete方法就直接将上面文件生成的路径传进去就可以达到删除的效果了,我就不测试了。测试结果,因为我在多文件上传的时候将文件的访问路径以逗号隔开,有需要的话可以自己更改。首先需要获取相关配置参数,进入腾讯云对象存储,创建存储桶并进入所创建的存储桶。
2022-09-24 22:01:15 1021 3
原创 序列化与反序列化
Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例。
2022-09-17 15:32:27 609
原创 Java8新特性--函数式接口
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 lambda 表达式。Lambda 表达式和方法引用(实际上也可认为是Lambda表达式)上。
2022-09-10 16:49:23 261
原创 HttpURLConnection使用方法
HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重, 对connection对象的一切配置(那一堆set函数) 都必须要在connect()函数执行之前完成。
2022-09-04 08:53:56 4327
原创 数据结构--树
在计算机科学中,树(英语:tree)是一种抽象数据类型(ADT)或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。因为它结合了另外两种数据结构的优点: 一种是有序数组,另一种是链表。在树中查找数据项的速度和在有序数组中查找一样快, 并且插入数据项和删除数据项的速度也和链表一样。树的底层其实同样是用链表。不同的是,在树中大量运用了递归。...
2022-08-14 09:42:31 221
原创 Java栈解决括号匹配
遇到左括号入栈,遇到右括号时先检查栈是否为空,若空则返回false,若不空则弹出栈顶元素看与右括号是否匹配。所有元素处理完后若栈为空则说明匹配成功,否则匹配不成功。另外,栈可以以数组底层,也可以以联表为底层,而这里是采用了链表。链表实现的栈,可以创建任意数据类型的栈。里面只含有 [ , ] , ( , ) 四种括号;现要求判断这个字符串 是否满足括号匹配。如([])()是匹配的([)]是不匹配的。...
2022-08-07 13:13:25 1041
原创 数据结构——栈
定义一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。规则后进先出每个栈帧里面都会存储有相应的一下内容1.局部变量表2.操作数栈3.动态链接4.返回地址。
2022-08-01 10:58:25 145
原创 Spring secrity 自定义密码验证(结合JWT)
众所周知,在Springsecrity中,密码验证由框架进行,但在实际项目开发中,交给secrity原生处理就显得有点局限了。而我们要做的自定义登录,就要去重写一些内容了。首先,继承UsernamePasswordAuthenticationFilter去重写下方方法,获取自定义登录接口的相关信息,再对用户名和密码处理。之后,spring会通过你设置的密码加密方式以及loadUserByUsername方法中的逻辑进行验证,再之后的验证成功与否会有不同的处理。...
2022-07-24 18:10:31 1070
原创 关于JWT
Jsonwebtoken(JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。...
2022-07-17 10:09:21 115
原创 Spring security安全权限注解
在WebSecuirtyConfig添加配置:1 @Secured 当@EnableGlobalMethodSecurity(securedEnabled=true)的时候,@Secured可以使用: 拥有normal或者admin角色的用户都可以方法helloUser()方法。另外需要注意的是这里匹配的字符串需要添加前缀"ROLE_" 如果我们要求,只有同时拥有admin & noremal的用户才能方法helloUser()方法,这时候@Secu
2022-07-09 23:30:45 2099
原创 Spring data JPA 笔记
1. @Entity :标识实体类是JPA实体,告诉JPA在程序运行时生成实体类对应表2. @Table :设置实体类在数据库所对应的表名3. @Id :标识类里所在变量为主键4. @GeneratedValue :设置主键生成策略,此方式依赖于具体的数据库5. @Basic :表示简单属性到数据库表字段的映射(几乎不用)6. @Column :表示属性所对应字段名进行个性化设置7. @Transient :表示属性并非数据库表字段的映射,ORM框架将忽略该属性8. @Temp
2022-07-02 23:49:59 447
原创 Redis持久化机制
Redis 的数据全部在内存里,如果突然宕机,数据就会全部丢失,因此必须有一种机制来保证 Redis 的数据不会因为故障而丢失,这种机制就是 Redis 的持久化机制。 Redis 的持久化机制有两种,第一种是RDB快照,第二种是 AOF 日志。快照是一次全量备份,AOF 日志是连续的增量备份。快照是内存数据的二进制序列化形式,在存储上非常紧凑,而 AOF 日志记录的是内存数据修改的指令记录文本。RDB快照RDB快照是某个时间点的一次全量数据备份,是二进制文件,在存储上非常紧凑。RDB持久化触
2022-06-25 23:06:58 461
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人