第5集Redis工作原理之底层数据结构
Redis数据结构概览Redis作为高性能的内存数据库,其卓越的性能不仅来自于epoll I/O多路复用技术,更得益于其精心设计的底层数据结构。Redis并没有直接使用传统的数据结构,而是针对内存使用效率和操作性能进行了深度优化。
Redis的五种基本数据类型Redis提供了五种基本数据类型,每种类型都有其对应的底层数据结构实现:
String(字符串) - SDS(Simple Dynamic String)
List(列表) - 双向链表 + 压缩列表
Hash(哈希) - 压缩列表 + 哈希表
Set(集合) - 整数集合 + 哈希表
Sorted Set(有序集合) - 压缩列表 + 跳跃表
SDS:Redis的字符串实现传统C字符串的问题传统的C字符串存在以下问题:
获取长度需要O(n)时间复杂度:需要遍历整个字符串
缓冲区溢出:容易造成内存越界
二进制不安全:不能存储包含’\0’的数据
频繁内存重分配:每次修改都可能需要重新分配内存
SDS的设计优势Redis使用SDS(Simple Dynamic String)来解决这些问题:
12345struct sdshd ...
第4集Redis工作原理之epoll
Redis为什么这么快?Redis作为高性能的内存数据库,其卓越的性能表现主要归功于以下几个方面:
采用epoll I/O多路复用技术:高效处理大量并发连接
单线程处理模型:避免了多线程上下文切换和锁竞争的开销
高效的数据结构:针对不同场景优化的数据结构实现
内存操作:所有数据都在内存中,避免了磁盘I/O的瓶颈
本文将重点介绍Redis高性能的第一个关键因素:epoll I/O多路复用技术。
I/O模型的演进1. 阻塞I/O (BIO)在最初的阻塞I/O模型中:
每个连接需要一个专门的线程处理
线程在等待数据时会被阻塞
大量并发连接会导致大量线程被创建,系统资源很快耗尽
伪代码示例:
12345678while(true) { // 接受新连接,阻塞直到有新连接到来 socket = accept(); // 为每个连接创建一个新线程 new Thread(() -> { handleRequest(socket); }).start();}
问题:当连接数增加时,系统需要创建大量线程,导致系统 ...
第3集Redis工作原理之双写一致性
什么是双写一致性问题?在使用Redis作为MySQL的缓存时,我们经常会遇到双写一致性问题。所谓双写一致性,是指当数据需要同时写入数据库和缓存时,如何保证两者数据的一致性。
双写一致性的主要矛盾双写一致性问题主要有两个核心矛盾:
更新完数据库后,是更新缓存还是删除缓存?
如果选择删除缓存,是先删缓存还是先更新数据库?
解决方案分析方案1:缓存设置过期时间设置缓存过期时间是保持最终一致性的基础方案,但无法保证强一致性。
原理:缓存过期后,再次获取缓存时会走数据库,获取到最新数据后再更新缓存
优点:实现简单,不需要额外的操作
缺点:在过期前可能会出现数据不一致的情况
方案2:先更新数据库,再更新缓存这种做法实际上是不可取的,因为不能保证线程安全。
问题场景:
线程A更新了数据库,还没更新缓存
线程B更新了同一数据,并且更新了缓存
线程A再把缓存更新为自己的值
结果:从时效上看,B的更新应该覆盖A的,但实际上A覆盖了B的更新
业务角度:如果写操作频繁,会导致缓存频繁更新,性能浪费严重
方案3:先删除缓存,再更新数据库这种方案可能导致脏读问题:
问题场景:
线程A进行写操 ...
第2集DOM事件继承链
DOM事件继承链深度解析问题1:DOM节点元素上的事件方法是继承链是什么样的?即事件方法从何而来?在浏览器中,DOM元素的事件处理能力是通过原型链继承得来的。DOM节点元素的继承链如下:
HTMLElement → Element → Node → EventTarget → Object
继承链详解
HTMLElement:特定HTML元素的接口(如HTMLDivElement、HTMLButtonElement等)
Element:提供了元素的基本属性和方法
Node:提供了节点的基本属性和方法
EventTarget:提供了事件处理的核心方法
Object:JavaScript中所有对象的基类
EventTarget接口事件处理的核心方法来自于EventTarget接口,它提供了三个关键方法:
addEventListener:添加事件监听器
removeEventListener:移除事件监听器
dispatchEvent:触发事件
例如,当我们在一个按钮上调用addEventListener方法时,实际上是调用了从EventTarget继承来的方法:
1234// 这个 ...
第1集Event事件
什么是事件?在JavaScript中,事件是网页中发生的”事情”,比如用户点击按钮、提交表单、页面加载完成等。JavaScript可以”监听”这些事件,并在事件发生时执行相应的代码。
常见的事件类型鼠标事件
click - 当用户点击元素时触发
dblclick - 当用户双击元素时触发
mousedown - 当用户在元素上按下鼠标按钮时触发
mouseup - 当用户在元素上释放鼠标按钮时触发
mousemove - 当用户在元素上移动鼠标时触发
mouseover - 当鼠标移入元素时触发
mouseout - 当鼠标移出元素时触发
键盘事件
keydown - 当用户按下键盘按键时触发
keyup - 当用户释放键盘按键时触发
keypress - 当用户按下并释放键盘按键时触发
表单事件
submit - 当表单提交时触发
change - 当表单元素的值改变时触发
focus - 当元素获得焦点时触发
blur - 当元素失去焦点时触发
窗口事件
load - 当页面加载完成时触发
resize - 当窗口大小改变时触发
scroll - 当用户滚动页面时触发
事件 ...