- 博客(32)
- 收藏
- 关注
原创 散列表介绍
实际的情况下想找一个散列函数能够做到对于不同的key计算得到的散列值都不同几乎是不可能的,即便像著名的MD5,SHA等哈希算法也无法避免这一情况,这就是散列冲突(或者哈希冲突,哈希碰撞,在散列表中,数组的每个下标位置我们可以称之为桶(bucket)或者槽(slot),每个桶(槽)会对应一条链表,所有散列值相同的元素我们都放到相同槽位对应的链表中。插入操作,通过散列函数计算出对应的散列槽位,将其插入到对应链表中即可,插入的时间复杂度是 O(1)平均情况下基于链表法解决冲突时查询的时间复杂度是O(1)
2023-10-06 23:07:53
57
原创 Redis(上)
string key:value hash 大key k1【field】 v1 k2 v2 list key:集合 有序 set key:集合 无序 不重复 zset【sorted set】
2023-10-04 21:38:05
57
原创 分布式事务
事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有操作作为一个整体一起向系统提交或撤销操作请求,既这些操作要么同时成功,要么同时失败。
2023-09-27 20:36:17
49
原创 多线程与锁
进程 进程是程序执行的一次过程,是系统运行程序的基本单位,进程是动态的.系统运行一个程序就代表一个进程生命周期从创建,运行到消亡的过程。在java中,启动main函数就代表启动了一个jvm的进行.main函数所在的线程就是这个进程中的一个线程,也称主线程.
2023-09-25 21:13:42
45
原创 bean的加载方式
由于方式一种需要将spring管控的bean全部写在xml文件中,对于程序员来说非常不友好,所以就有了第二种方式。哪一个类要受到spring管控加载成bean,就在这个类的上面加一个注解,还可以顺带起一个bean的名字(id)。这里可以使用的注解有@Component以及三个衍生注解@Service、@Controller、@Repository。@Service。
2023-09-24 18:21:38
48
原创 synchronized
来实现的,Java 的线程是映射到操作系统的原生线程之上的。如果要挂起或者唤醒一个线程,都需要操作系统帮忙完成,而操作系统实现线程之间的切换时需要从用户态转换到内核态,这个状态之间的转换需要相对比较长的时间,时间成本相对较高。是 Java 中的一个关键字,翻译成中文是同步的意思,主要解决的是多个线程之间访问资源的同步性,可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。JDK1.6 对锁的实现引入了大量的优化,如偏向锁、轻量级锁、自旋锁、适应性自旋锁、锁消除、锁粗化等技术来减少锁操作的开销。
2023-09-21 21:45:48
70
原创 JWT与token+redis对比
基于状态的Web服务在基于状态的Web服务中,Client与Server交互的信息(如:用户登录状态)会保存在Server的Session中。再这样的前提下,Client中的用户请求只能被保存有此用户相关状态信息的服务器所接受和理解,这也就意味着在基于状态的Web系统中的Server无法对用户请求进行负载均衡等自由的调度(一个Client请求只能由一个指定的Server处理)。
2023-09-20 16:13:01
169
原创 java并发篇 悲观锁和乐观锁
乐观锁总是假设最好的情况,认为共享资源每次被访问的时候不会出现问题,线程可以不停的执行,无需加锁也无需等待,只是在提交修改的时候去验证对应的资源(也就是数据)是否被其他线程修改了(具体方法可以使用版本号机制或CAS算法)高并发的场景下,乐观锁相比悲观锁来说,不存在锁竞争造成线程阻塞,也不会有死锁的问题,在性能上往往会更胜一筹。但是,如果冲突频繁发生(写占比非常多的情况),会频繁失败和重试,这样同样会非常影响性能,导致CPU飙升。
2023-09-17 20:03:04
46
原创 java并发篇 线程
线程死锁描述的是这样一种情况:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。wait()是让获得对象锁的线程实现等待,会自动释放当前线程占有的对象锁。每个对象(Object)都拥有对象锁,既然要释放当前线程占有的对象锁并让其进入 WAITING 状态,自然是要操作对应的对象(Object)而非当前的线程(Thread为什么sleep()方法定义在Thread中?因为sleep()是让当前线程暂停执行,不涉及到对象类,也不需要获得对象锁。
2023-09-15 20:43:14
50
原创 java并发 进程与线程
程序计数器的主要作用有两个:1. 字节码是通过程序计数器来读取指令,从而实现代码的流程控制的.2. 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道上次线程运行到哪里了.因此程序技术器私有主要是为了线程切换后能恢复到正确的位置每个 Java 方法在执行之前会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。
2023-09-14 17:55:29
63
原创 Java 序列化详解
如果我们需要持久化 Java 对象比如将 Java 对象保存在文件中,或者在网络传输 Java 对象,这些场景都需要用到序列化。序列化:将数据结构或对象转换成二进制字节流的过程反序列化:将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程对于 Java 这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class),但是在 C++这种半面向对象的语言中,struct(结构体)定义的是数据结构类型,而 class 对应的是对象类型。
2023-09-12 22:24:31
43
原创 IO字节流
用于从源头(通常是文件)读取数据(字节信息)到内存中,用于将数据(字节信息)写入到目的地(通常是文件),抽象类是所有字节输入流的父类。抽象类是所有字节输出流的父类。
2023-09-11 21:47:00
33
原创 SpringCloud入门
微服务架构(也可简称为微服务)是一种依赖于一系列可独立部署服务的架构方法。这些服务有自己的业务逻辑和数据库,并负责实现特定的目标。更新、测试、部署和扩展都在每一项服务中进行。微服务可将特定于领域的主要业务问题分解为单独的独立代码库。微服务不会降低复杂性,但它们可将任务划分成彼此独立运行且对整体有益的较小流程,从而使任何复杂情况都变得一目了然且更易管理。
2023-09-09 18:14:22
31
原创 Map集合
属性维护红黑树的根结点,因为红黑树在旋转的时候,根结点可能会被它原来的子节点替换掉,在这个时间点,如果有其他线程要写这棵红黑树就会发生线程不安全问题,所以在。)的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据时,其他段的数据也能被其他线程访问。不过,Node 只能用于链表的情况,红黑树的情况需要使用 TreeNode。数组的大小默认是 16,也就是说默认可以同时支持 16 个线程并发写。属性维护当前使用这棵红黑树的线程,来防止其他线程的进入。中的,还是因为找不到对应的键而返回的。
2023-09-08 21:25:26
33
原创 Map集合(续)
为了能让 HashMap 存取高效,尽量较少碰撞,也就是要尽量把数据分配均匀。Hash 值的范围值-2147483648 到 2147483647,前后加起来大概 40 亿的映射空间,只要哈希函数映射得比较均匀松散,一般应用是很难出现碰撞的。但问题是一个 40 亿长度的数组,内存是放不下的。所以这个散列值是不能直接拿来用的。用之前还要先做对数组的长度取模运算,得到的余数才能用来要存放的位置也就是对应的数组下标。这个数组下标的计算方法是“(n 代表数组长度)。
2023-09-06 21:07:13
34
原创 Map集合
值来判断对象加入的位置,同时也会与其他加入的对象的。会假设对象没有重复出现。自己不得不实现之外,其他方法都是直接调用。相等的对象是否真的相同。的源码非常非常少,因为除了。值作比较,如果没有相符的。就不会让加入操作成功。值的对象,这时会调用。
2023-09-05 22:23:37
27
原创 Linux常用命令
p: 确保目录名称存在,不存在的就创建一个。ls -al /etc 查看/etc目录下所有文件及目录详细信息。-r: 如果复制的是目录需要使用此选项,此时将复制该目录下所有的子目录和文件。cd /usr/local 切换到/usr/local目录。-f : 动态读取文件末尾内容并显示,通常用于日志文件的内容输出。-r: 将目录及目录中所有文件(目录)逐一删除,即递归删除。ll 查看当前目录文件及目录的详细信息。-p: 当子目录被删除后使父目录为空目录的话,则一并删除。
2023-09-03 19:52:50
28
原创 Queue(下)
BlockingQueue(阻塞队列是一个接口)继承自Queue。BlockingQueue阻塞的原因是其支持的队列没有元素时会一直阻塞,直到有元素;还支持如果队列已满,一直等到队列可以放入新元素时,在放入。BlockingQueue常用于生产者与消费者模式中,生产者线程会向队列中添加数据,而消费者线程会从队列中取出数据。
2023-09-02 21:30:43
29
原创 Queue
的接口, 增加了在队首和队尾进行插入和删除的方法,同样根据失败后处理方式的不同分为两类。不需要扩容,但是每次插入数据时均需要申请新的堆空间,均摊性能相比更慢。的区别在于元素出队顺序是与优先级相关的,即总是优先级最高的元素先出队。是单端队列,只能从一端插入元素,另一端删除元素,实现上一般遵循。接口,两者都具有队列的功能,但两者有什么区别呢?是双端队列,在队列的两端均可以插入或删除元素。是基于可变长的数组和双指针来实现,而。是在 JDK1.6 才被引入的,而。从性能的角度上,选用。
2023-08-30 21:40:40
35
原创 Set集合
Comparablejava.langComparatorjava.util一般对一个集合使用自定义排序时,我们就要重写方法或compare()方法,当我们需要对某一个集合实现两种排序方式,比如一个song对象中的歌名和歌手名分别采用一种排序方法的话,我们可以重写方法和使用自制的Comparator方法或者以两个Comparator来实现歌名排序和歌星名排序,第二种代表我们只能使用两个参数版的。
2023-08-29 21:35:33
22
原创 List(下)
底层数据结构是链表,内存地址不连续,只能通过指针来定位,不支持随机快速访问,所以不能实现。是一个标记接口,用来表明实现该接口的类支持随机访问(即可以通过索引快速访问元素)。
2023-08-29 21:32:38
165
原创 Java 集合概览
ArrayListObject[]数组VectorObject[]数组LinkedList:双向链表(JDK1.6 之前为循环链表,JDK1.7 取消了循环)
2023-08-26 00:29:44
21
原创 乐观锁存在那些问题
如果一个变量 V 初次读取的时候是 A 值,并且在准备赋值的时候检查到它仍然是 A 值,这个时候并不能说明他是没有修改过的。因为在这段时间它的值可能被改为其他值,然后又改回 A,那 CAS 操作就会误认为它从来没有被修改过。这个问题被称为 CAS 操作的。方法就是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。CAS 只对单个共享变量有效,当操作涉及跨多个共享变量时 CAS 无效。类就是用来解决 ABA 问题的,其中的。
2023-08-24 22:23:23
47
原创 乐观锁和悲观锁
在高并发的情况下,乐观锁相比悲观锁来说不会存在锁竞争激烈的情况下,也就不会造成线程阻塞也没有死锁的问题,在性能上会更胜一筹。但是如果在冲突频繁的情况下也就是写的操作较多的情况下,会频繁失败和重试(悲观锁的开销是固定的),这样会非常影响性能,导致CPU飙升。悲观锁总是假设最坏的情况,认为共享资源每次被访问时都可能会出现问题,所以在每次获取资源时都会进行上锁,这样其他线程想拿到这个共享资源时就会阻塞直到锁被释放,也就是共。在高并发的情况下,激烈的锁竞争会造成线程阻塞。大量线程的阻塞会造成系统的上下文切换。
2023-08-21 21:07:02
17
原创 ArrayList 和 Array(数组)的区别
ArrayList会根据实际存储的元素动态地扩容或缩容,而 Array 被创建之后就不能改变它的长度了。 ArrayList 允许使用泛型来确保类型安全,Array 则不可以。 ArrayList 中只能存储对象。对于基本类型数据,需要使用其对应的包装类(如 Integer、Double 等)。Array 可以直接存储基本类型数据,也可以存储对象。 ArrayList 支持插入、删除、遍历等常见操作,并且提供了丰富的 API 操作方法,比如 add()、remove()等。Array 只是一个固定长度
2023-08-19 20:34:22
99
原创 ThreadLocal
而ThreadLocalMap默认Key和Vvalue值都是null,并且只有当前线程调用了ThreadLocal类的。set或get方法才会去创建他们,实际上可以说调用ThreadLocal的get和set实际上调用的是。没有被外部强引用的情况下,在垃圾回收的时候,key 会被清理掉,而 value 不会被清理掉。所以可以说ThreadLocal是ThreadLocalMap的封装。主要是为了让每一个线程都有自己的存储空间,可以存储自己的私有变量。的弱引用,而 value 是强引用。
2023-08-18 21:00:28
18
原创 HashMap详解
HashMap提供了丰富的功能和灵活的用法,可以通过合适的初始容量和正确实现hashCode()和equals()方法来提高性能。然而,需要注意的是HashMap不是线程安全的,需要采取适当的同步措施来保证线程安全性。这个过程被称为树化。正确定义hashCode()和equals()方法:确保键对象正确实现hashCode()和equals()方法,以保证哈希算法的正确性。避免频繁的resize操作:如果对HashMap进行了大量的插入和删除操作,考虑使用合适的初始容量,以避免频繁的resize操作。
2023-08-16 20:22:42
80
原创 深入解析String的底层机制、原理和设计思想
通过本文的介绍,我们了解了String的内部表示、不可变性、字符串池、字符串拼接、性能优化和常见操作的实现方式。字符串池是一个保存字符串实例的特殊存储区域,其中的字符串是唯一的,即相同内容的字符串只会在字符串池中存在一份。当创建一个新的字符串对象时,Java会先检查字符串池中是否已经存在相同内容的字符串,如果存在,则直接返回字符串池中的实例,否则创建一个新的字符串对象并放入字符串池中。我们将介绍String的内部表示、不可变性、字符串池、字符串拼接、性能优化和常见操作的实现方式等内容。
2023-08-15 19:09:02
355
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人