Resid学习记录
Redis 简介Redis(Remote Dictionary Server)是一个开源的内存数据库,遵守 BSD 协议,它提供了一个高性能的键值(key-value)存储系统,常用于缓存、消息队列、会话存储等应用场景。 特点: 性能极高:能够支持每秒数十万次的读写操作 丰富的数据结构:Redis 不仅支持基本的键值存储,还提供了丰富的数据类型,包括字符串、列表、集合、哈希表、有序集合等。 原子性操作:Redis 的所有操作都是原子性的,这意味着操作要么完全执行,要么完全不执行。 持久化:Redis 支持数据的持久化,可以将内存中的数据保存到磁盘中,以便在系统重启后恢复数据 支持发布/订阅模式:Redis 内置了发布/订阅模式(Pub/Sub),允许客户端之间通过消息传递进行通信。 主从复制:Redis 支持主从复制,可以通过从节点来备份数据或分担读请求,提高数据的可用性和系统的伸缩性。 使用方式 CLI:命令行 API:java 或 python GUI:用户界面 安装Windows wsl 来安装,使用 wsl 来安装 linux 系统,在通过 linux 系统的方式...
Caffeine
Caffeine 概述Caffeine — 一个高性能的 Java 缓存库Caffeine 的底层数据存储采用 ConcurrentHashMap。Caffeine 面向 JDK8,在 jdk8 中 ConcurrentHashMap 增加了红黑树,在 hash 冲突严重时也能有良好的读性能。Caffeine 是 Spring 5 默认支持的 Cache,可见 Spring 对它的看重 回收策略为在指定时间删除哪些对象。此策略直接影响缓存的命中率 — 缓存库的一个重要特征。Caffeine 使用 Window TinyLfu 回收策略,提供了一个近乎最佳的命中率。它可以解决频率统计不准确以及访问频率衰减问题关于淘汰策略我在淘汰策略有详细介绍可自行查阅 使用添加依赖123456<dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> <version>2.5.5...
Web 前端面试题
事件冒泡事件冒泡(Event Bubbling) 是 DOM 事件传播的一种机制,指当一个元素触发事件后,事件会按照 “从触发元素到顶层元素” 的顺序逐级向上传播,就像气泡从水底逐渐浮到水面一样。 12345<div id="grandparent" onclick="console.log('祖父元素被点击')"> <div id="parent" onclick="console.log('父元素被点击')"> <button id="child" onclick="console.log('子元素被点击')">点击我</button> </div></div> 控制台输出: 123子元素被点击父元素被点击祖父元素被点击 点击事件从按钮(最内层元素)依次向上传播到父元素和祖父元素。这会对父元素造成污染, 我们可以使用 ...
CAS学习记录
CAS 概述CAS(Compare And Swap,比较并交换)是并发编程中一种无锁同步机制,它通过硬件层面的原子操作保证多线程环境下变量更新的安全性,避免了传统锁(如 synchronized)带来的线程上下文切换开销,是实现乐观锁的核心技术。 有三个核心参数: 内存地址 V:存储要操作的变量的内存位置 预期值:线程认为当前内存地址 V 中应该存储的值 新值:线程希望将内存地址 V 更新为的值 当且仅当内存地址 V 中的实际值等于预期值 A 时,才将 V 的值更新为 B;否则不做任何操作。保证了原子性。 执行流程当多线程修改一个共享变量 count 时,假设初始值为 10: 线程 1 读取 count 的值,记录预期值为 A,计划将其更新为新值 B=11; 线程 1 执行 CAS 操作:检查 count 的实际值是否等于 A(10); 若相等:则将 count 更新为 B(11),操作成功 若不相等:说明 count 被其它线程修改过,则不更新,操作失败 若操作失败,线程可以选择重新读取新值,再次尝试 CAS 或放弃。 底层实现CAS 的原子性依赖于 CPU 硬件...
ConcurrentHashMap学习记录
ConcurrentHashMap 概述ConcurrentHashMap 是 Java 并发包(java.util.concurrent)中最重要的并发容器之一,专为多线程环境设计,用于解决哈希表的线程安全问题,同时保持高效的并发性能。它的核心目标是在保证线程安全的前提下,尽可能减少锁竞争,支持高并发的读写操作。 为什么需要 ConcurrentHashMap在 ConcurrentHashMap 出现之前,处理哈希表的线程安全有两种方案: Hashtable:通过 synchronized 修饰所有方法,对所有共享资源整体上锁,当一个线程访问该资源时,其它线程必须阻塞等待,并发性能差 内部通过包装 HashMap,使用一个全局锁(mutex)保证安全,同样是全表锁, ConcurrentHashMap 的出现打破了全表锁,大大提升了并发效率 JDK 1.7 中的实现方式核心采用 “分段锁(Segment)” 机制,这是一种将哈希表分割为多个独立段(Segment),每段单独加锁的设计 每个 Segment 数组就是一个小的哈希表,自身继承了 ReentrantLock,即...
JVM 内存分配
内存分配在 JVM 中内存分配是对象生命周期的起点,涉及内存区域划分、分配策略、线程交互等。 堆:存储对象实例和数组(对象主要分配在堆内存) 方法区:存储类信息、常量、静态变量(静态对象的引入,静态对象的实例在堆中) 虚拟机栈:局部变量表;(基本类型局部变量和对象局部变量的引用) 本地方法栈:不直接参与 Java 对象分配 程序计数器:记录当前线程执行位置,不参与内存分配 Java 对象的实例数据几乎都分配在堆中;局部变量(引用类型)在栈中存地址,指向堆中对象。 新生代:占堆内存的 1/3,分为 3 个区域;Eden 分配新对象;Survivor(幸存者区),分为 From 和 To 两个大小相等的区域(各占 10%),用于存放经历一次 GC 后存活的对象。新对象先进入 Eden 区;当 Eden 区满时,触发 Minor GC(新生代 GC),存活对象被复制到 Survivor 的 From 区。下次 Minor GC 时,From 区存活对象被复制到 To 区(年龄 + 1),同时清空 From 区;之后 From 和 To 角色互换。当对象年龄达到阈值(默认 15,可...