- 博客(50)
- 资源 (12)
- 收藏
- 关注
原创 跳表的使用场景和原理
跳表(Skip List)是一种高效的有序数据结构,通过多层链表实现快速查找、插入和删除操作,其核心思想是“空间换时间”和“概率性索引分层”。底层(L0)包含所有元素,上层链表(L1, L2...)是下层的“快速通道”,节点数逐层递减。:从最高层开始,向右查找直到下一个节点值大于目标值,然后向下一层继续,直到底层。:需要快速访问有序数据的场景(如 LevelDB 的 MemTable)。:平均 O(log n),最坏 O(n)(但概率极低)。:查找目标节点,逐层更新前驱节点的指针。
2025-03-14 12:43:33
522
原创 索引失效的场景
在数据库查询优化中,索引失效是导致性能下降的常见原因之一。:索引存储的是列原始值,运算后的值无法直接匹配索引结构。:不等于操作通常需要扫描大部分数据,优化器可能放弃索引。:联合索引按最左列有序存储,跳过左列则无法利用索引结构。:数据库需先转换数据类型再比较,导致无法使用索引。:只要有一个条件无法使用索引,优化器可能放弃索引。:索引按前缀排序,无法快速定位中间或结尾的字符串。:查询条件中的数据类型与索引列类型不一致。:未使用联合索引的最左列,或跳过了中间列。:查询字段未被索引覆盖,需回表查询。
2025-03-14 12:34:14
586
原创 分布式选举算法
Leader(主节点)、Follower(从节点)、Candidate(候选节点)。:Proposer(提议者)、Acceptor(决策者)、Learner(学习者)。:如 TiDB(Raft)、CockroachDB(Raft 变种)。节点进入选举状态,广播自己的投票(包含最新事务ID,即 ZXID)。:Leader、Follower、Observer(不参与选举)。比较规则:优先选 ZXID 最大的节点,若相同则选节点ID大的。:预选举(Pre-Vote)减少无效投票(Raft 实现)。
2025-03-14 12:22:03
570
原创 Redis如何实现分布式锁?
对于超高并发场景,可考虑结合 Redis 的 Lua 原子操作或更细粒度的锁设计。在分布式系统中,Redis 实现分布式锁的核心目标是确保多个客户端在竞争共享资源时的互斥访问。当且仅当超过半数节点(N/2 + 1)成功,且总耗时小于锁过期时间,锁才生效。:客户端生成的唯一值(如 UUID),用于安全释放锁。:需大于业务操作耗时,否则锁提前释放会导致并发问题。:释放锁时必须校验值并删除,非原子操作会导致锁失效。:锁的自动过期时间(单位:毫秒),防止死锁。:必须全局唯一,避免误删其他客户端的锁。
2025-03-14 12:17:13
883
原创 synchronized和reentrantlock的区别
提供更灵活的锁控制(如可中断、公平锁、多条件变量),适合复杂同步需求,但需手动管理锁的获取与释放。都用于实现线程同步,但它们在设计理念、功能和使用方式上有显著区别。:适合简单同步场景,代码简洁,由 JVM 自动管理锁,但功能有限。以保持代码简洁,仅在需要高级功能时使用。根据具体需求选择:优先考虑。
2025-03-14 11:54:54
375
原创 用户打开浏览器到看到内容经历了什么?
浏览器并发下载图片、CSS、JavaScript等资源(通常限制为6-8个连接/域名)。:避免阻塞渲染的CSS(内联关键CSS)、异步加载JavaScript(:解析URL,提取协议(HTTP/HTTPS)、域名、路径和端口号。:状态码(200 OK、404 Not Found)和协议版本。:服务器选择TLS版本、加密套件,发送随机数和数字证书。:客户端验证证书有效性(颁发机构、有效期、域名匹配)。:浏览器引擎(如V8)解析JavaScript代码。:默认使用80(HTTP)或443(HTTPS)。
2025-03-14 11:46:03
285
原创 jwt的基本原理
对称加密(如HS256)适合单一服务,非对称加密(如RS256)适用于分布式系统。实际应用中需结合业务需求和安全标准,合理设计令牌的声明及生命周期,以构建安全高效的身份验证体系。:敏感数据(如密码)不应放入Payload,需加密存储可考虑JWE(JSON Web Encryption)。(HMAC SHA-384):更长的哈希值,安全性增强。(HMAC SHA-512):最高安全性,适合敏感场景。(HMAC SHA-256):安全性高,计算速度快。:分布式系统(如微服务),需公钥分发验证的场景。
2025-03-13 23:16:13
606
原创 主从数据库
实际应用中,主从架构常与缓存(Redis)、消息队列(Kafka)等技术结合,构建高性能、高可用的分布式系统。:结合哨兵(Sentinel)、Keepalived 或集群管理工具(如MHA、Orchestrator)。:将数据分片(Sharding)存储到多个主库,每个主库再配置从库。:数据一致性弱(从库可能有延迟),主库宕机时可能丢失未同步的数据。:用户在美国访问美东的从库,亚洲用户访问新加坡的从库。:主库 → 从库A → 从库B,形成多级复制链。:在多地部署从库,就近服务用户,降低访问延迟。
2025-03-13 23:09:28
528
原创 HTTP2.0
于2015年正式发布(RFC 7540),旨在解决HTTP/1.1的性能瓶颈,提升Web应用的加载速度和效率。主流浏览器(Chrome、Firefox)仅支持加密的HTTP/2(基于TLS/SSL)。使用静态表(预定义61个常用头部字段)和动态表(自定义字段),通过哈夫曼编码压缩头部。Web服务器:Nginx(1.9.5+)、Apache(2.4.17+)、Caddy。(Frame),每个帧包含流标识符(Stream ID),实现多路复用。头部大小减少30%~90%,显著降低延迟(尤其是移动端)。
2025-03-13 22:58:58
561
原创 如何理解一切皆文件
将系统的各种资源(如硬件设备、进程、网络连接等)以文件的形式呈现和管理。,通过将复杂性隐藏在文件接口背后,实现了系统的简洁性和一致性。Unix 强调文本作为通用数据格式(如配置文件、日志、管道数据),便于工具链组合(理解这一思想,有助于掌握 Unix 系统的精髓,并设计出模块化、可扩展的软件。如高性能网络数据包处理(DPDK)会绕过文件接口,直接操作硬件。表示 CPU 信息),用户可以通过文件路径直接访问。下的文件用于配置内核参数(如 CPU 频率调节)。(如硬盘):支持随机访问,以块为单位操作。
2025-03-13 22:52:26
797
原创 SQL注入
SQL注入(SQL Injection)是一种通过将恶意SQL代码插入应用程序的输入参数中,从而篡改或破坏数据库操作的攻击手段。它是Web安全中最常见且危害极大的漏洞之一,可能导致数据泄露、篡改、删除甚至服务器被控制。使用ORM(如Hibernate、Django ORM)自动处理参数化,避免手写SQL。:利用应用程序未对用户输入进行充分过滤或转义,将恶意SQL代码拼接到原始查询中。在支持堆叠查询的数据库中执行系统命令(需权限允许)。:将SQL代码与数据分离,避免拼接字符串。:修改商品价格、用户余额等。
2025-03-13 22:49:30
509
原创 自旋锁是什么?
自旋锁(Spinlock)是一种基于忙等待(Busy-Waiting)的同步机制,主要用于多线程或多核环境中保护共享资源。在设计高并发系统时,通常结合自旋锁与互斥锁(如自适应锁)以平衡性能与资源消耗。:自旋线程与释放锁的线程可能运行在不同核心上,减少无效等待。:高优先级线程自旋等待低优先级线程时,需结合优先级继承机制。,而是通过循环(自旋)反复检查锁的状态,直到锁被释放。:锁持有时间极短(如几行代码),避免长时间占用CPU。:需CPU支持原子指令(如x86的。)确保锁的获取和释放是线程安全的。
2025-03-13 22:43:40
375
原创 进程、线程和协程的区别
进程、线程和协程是计算机科学中处理并发和并行的三种主要机制,它们在资源管理、调度方式和应用场景上有显著区别。根据任务需求选择合适模型:进程用于隔离性要求高的场景,线程用于利用多核并行,协程用于高并发I/O处理。:拥有独立的虚拟内存空间(代码、数据、堆栈等),进程间相互隔离,崩溃不影响其他进程。进程间通信复杂(需IPC),线程需处理同步问题(如锁、死锁),协程需设计非阻塞逻辑。:共享进程的内存和资源(如文件句柄),但每个线程有自己的栈和寄存器上下文。:独立的“工厂”,拥有自己的资源和工人(线程)。
2025-03-13 22:35:45
275
原创 缓存数据淘汰算法: LRU 和 LFU
LRU+LRU:最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。LFU:最近最不经常使用,选择最近使用次数最少的页面予以淘汰。对于每个节点,都需要维护其使用次数count、最近使用时间time。针对这两种算法,使用图形演示其保留数据的不同点。
2025-03-13 19:25:48
696
原创 深入理解Java虚拟机
程序计数器、虚拟机栈、本地方法栈 3 个区域随线程生灭(因为是线程私有),栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。而 Java 堆和方法区则不一样,一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,我们只有在程序处于运行期才知道那些对象会创建,这部分内存的分配和回收都是动态的,垃圾回收期所关注的就是这部分内存。
2025-03-13 09:25:17
671
原创 进程调度算法
进程调度算法是操作系统的核心机制之一,负责在多个进程或线程之间分配 CPU 资源,确保系统高效、公平地运行。:静态优先级,需满足利用率上限(∑CiTi≤n(21/n−1)∑TiCi≤n(21/n−1))。:为每个进程分配固定时间片(Time Quantum),依次轮转执行。:平均等待时间长(护航效应,短进程可能被长进程阻塞)。:避免 SJF 的长进程饥饿问题,但需预知运行时间。:为每个进程分配优先级,优先执行高优先级进程。:需预知进程运行时间,可能导致长进程饥饿。
2025-03-12 22:00:03
906
原创 MySQL索引为啥用B+树
MySQL 选择 B+ 树的核心原因在于其综合平衡了磁盘 I/O 效率、范围查询性能、稳定性与维护成本,尤其适合处理大规模数据存储和高并发查询的数据库场景。而哈希表、二叉树等结构因无法同时满足这些需求,仅作为特定场景的补充(如内存临时表)。
2025-03-12 20:41:01
348
原创 MySQL引擎MyISAM和InnoDB的比较
✅ 支持缓冲池(Buffer Pool),减少磁盘 I/O,提升高频访问数据的性能。(Table-level Locking),并发写入时容易阻塞(如批量插入或更新)。✅ 支持外键(Foreign Key),保证数据完整性(级联更新/删除)。(如高并发事务处理)性能更优,得益于行级锁和 MVCC(多版本并发控制)。:数据按主键顺序存储,主键查询极快,但二级索引需两次查找(主键→数据行)。(如数据分析、日志查询)性能更优,因为其索引结构(非聚簇索引)简单。等事务操作,适合需要数据一致性的场景(如金融交易)。
2025-03-12 14:29:42
857
原创 常见网络状态码
请求成功,响应体中包含请求结果(如GET获取资源、POST提交后的页面)。网关或代理服务器从上游服务器收到无效响应(如反向代理后端的服务崩溃)。请求成功,但响应体无内容(如DELETE删除资源后无需返回数据)。资源创建成功(如通过POST新增数据,返回新资源的URL)。到新URL,下次请求可能仍访问原地址(如登录后跳转首页)。严格匹配状态码语义(如创建资源用201,删除用204)。请求资源不存在(如URL拼写错误、资源已被删除)。到新URL,浏览器会缓存新地址(如网站域名更换)。
2025-03-12 12:03:09
315
原创 详细解析 HTTP 与 HTTPS 的区别
那采用HTTPS后,到底会多用多少服务器资源,2010年1月Gmail切换到完全使用HTTPS, 前端处理SSL机器的CPU负荷增加不超过1%,每个连接的内存消耗少于20KB,网络流量增加少于2%,由于Gmail应该是使用N台服务器分布式处理,所以CPU负荷的数据并不具有太多的参考意义,每个连接内存消耗和网络流量数据有参考意义,这篇文章中还列出了单核每秒大概处理1500次握手(针对1024-bit 的 RSA),这个数据很有参考意义。服务器回复该主密钥,并返回给客户端一个用主密钥认证的信息;
2025-03-12 11:56:07
1286
原创 get和post的区别
GET和POST是HTTP协议中最常用的两种请求方法,它们在设计目的、使用场景和实现细节上有显著区别。URL长度受浏览器和服务器的限制(如Chrome限制为2MB,IE为2083字符)。用于向服务器请求数据(如查询信息、加载页面),参数直接暴露在URL中,涉及资金的操作(如支付)必须用POST,避免因浏览器重试导致重复扣款。可被浏览器缓存、记录在历史记录中,可通过书签直接访问带参数的URL。用于向服务器提交数据(如表单提交、文件上传),用户登录、表单提交、文件上传(如提交注册信息)。
2025-03-12 11:34:10
250
原创 关于 TCP 三次握手和四次挥手
客户端收到服务器端响应的 SYN 报文之后,会发送一个 ACK 报文,也是一样把服务器的 ISN + 1 作为 ack 的值,表示已经收到了服务端发来的的 SYN 报文,希望收到的下一个数据的第一个字节的序号是 y + 1,并指明此时客户端的序列号 seq = x + 1(初始为 seq = x,所以第二个报文段要 +1),此时客户端处于。:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于。
2025-03-12 11:25:27
848
原创 为什么需要第三次握手?
第三次握手通过客户端对服务器序列号的最终确认,确保:双方收发能力可靠;初始序列号同步;历史连接请求不会误占资源;抵御部分拒绝服务攻击。这是TCP实现可靠传输、避免资源浪费与数据混乱的核心设计。
2025-03-12 10:20:31
343
原创 Python装饰器
掌握装饰器能显著提升代码复用性和可维护性,是 Python 高级编程的必备技能。:在不修改原函数代码的前提下,为其添加额外功能(如日志、权限校验、性能监控)。Python 装饰器(Decorator)是一种。:在函数定义时立即执行装饰器逻辑(非调用时)。,接受一个函数作为参数,返回一个新函数。:确保装饰器不影响原函数的参数和返回值。装饰器会覆盖原函数的元信息(如。:多个装饰器从下到上应用。
2025-03-12 09:13:47
276
原创 Java中哪些动作可能会造成内存溢出?
简称 OOM)通常是由于程序在运行过程中申请的内存超过了 JVM 的最大可用内存限制。:如热部署框架(Spring Boot DevTools)频繁加载类。:创建大量线程且每个线程占用内存(栈、堆外内存等),超出系统限制。:线程请求的栈深度超过 JVM 允许的最大深度(默认 1MB)。:加载的类信息、常量池等元数据超过 Metaspace 限制。:如 Web 应用重启后,旧的类加载器未释放。:本地代码(如 C/C++)分配内存未回收。:对象实例过多,且无法被垃圾回收(GC)。
2025-03-12 08:38:49
824
原创 Redis主从复制的流程
RDB文件生成完毕后,主节点将其发送给从节点。当从节点短时间断线重连后,可通过该缓冲区直接获取断线期间的命令,避免全量复制。主节点将复制缓冲区中记录的写命令发送给从节点,从节点执行这些命令以保持与主节点数据一致。全量复制完成后,主节点进入命令传播阶段,将后续接收到的所有写命令实时发送给从节点(通过。若从节点断线时间较短,且主节点的复制积压缓冲区仍包含断线期间的命令,从节点发送。若复制积压缓冲区不包含断线期间的命令(如断线时间过长),则触发全量复制。,报告自身复制偏移量,主节点据此监控同步进度。
2025-03-12 08:26:51
224
原创 Redis数据结构的底层实现
小数据用压缩结构(Ziplist/Intset),大数据转标准结构(Dict/SkipList)。:空间预分配(扩容时多分配冗余空间)与惰性释放(缩短时不立即回收内存)。:固定 12KB 内存,支持海量数据基数估计(误差约 0.81%)。:内存连续,节省空间,但插入/删除效率低(需内存重分配)。:高效存储消息 ID(时间戳 + 序列号),支持范围查询。:存储成员到分值的映射,支持 O(1) 单点查询。:扩容时新旧哈希表共存,逐步迁移数据,避免阻塞。:平衡内存与性能,支持两端高效插入/删除。
2025-03-12 08:24:43
525
原创 缓存击穿、缓存雪崩、缓存穿透详解
若可能存在,再查缓存和数据库。:结合本地缓存(Caffeine)与分布式缓存(Redis),减少穿透风险。第一个请求未命中缓存时,加锁查库并回填缓存,其他请求等待或重试。使用 Hystrix 等工具,当数据库压力过大时,拒绝部分请求。:如缓存集群宕机、促销活动结束时大量商品缓存同时失效。:实时监控缓存命中率、数据库 QPS,及时发现问题。非法请求(如无效 ID)绕过缓存,直接访问数据库。:模拟极端场景(如瞬间高并发),验证系统容灾能力。缓存永不过期,但存储逻辑过期时间,异步刷新缓存。
2025-03-12 08:24:22
740
原创 Redis的内存淘汰策略?
Redis 采用随机抽样(默认抽取 5 个键),淘汰其中最久未使用的键,而非全局遍历(节省性能)。:基于 Morris 计数器算法,记录键的访问频率(衰减机制避免旧数据长期占据内存)。分钟,计数器值减半,逐步降低历史高频访问数据的影响。:部分数据允许过期,需优先保留高频访问的热点数据。:所有数据允许被淘汰,需优先保留高频访问数据。中,淘汰**最近最少使用(LRU)**的键。中,淘汰**最不经常使用(LFU)**的键。中,淘汰**最近最少使用(LRU)**的键。中,淘汰**最不经常使用(LFU)**的键。
2025-03-12 08:24:02
1039
原创 Java中序列化是怎么实现的?
实现,适用于简单场景,但存在性能和安全隐患。可选字段,用于标识类的版本。若未显式定义,JVM 会根据类结构自动生成,但类结构变化时可能导致反序列化失败。:避免反序列化不可信数据,或使用白名单验证(如 Apache Commons IO 的。根据字节流重建对象,不调用构造方法(直接分配内存,通过反射设置字段值)。是将对象转换为字节流的过程,以便存储到文件、数据库或通过网络传输;每个对象分配唯一 ID,避免重复写入相同对象(通过引用共享)。:避免序列化大对象或深层嵌套结构。字段:属于类,不参与序列化。
2025-03-11 20:18:31
603
原创 Java中线程安全的数据结构有哪些?
(基于更高效的并发控制,如 CAS、分段锁等)。:高并发优化的哈希表,Java 8 前使用分段锁,Java 8+ 改用。:基于跳表(Skip List)的有序 Map。:即使使用线程安全容器,多个操作的组合(如。:性能低于 JUC 容器(方法级锁)。:基于 CAS 的无锁队列,高性能。:线程安全的动态数组,所有方法用。:写操作时复制新数组,读操作无锁。:线程安全的哈希表,所有方法用。:基于 CAS 的无锁双端队列。:将普通容器包装为线程安全容器。:读操作无锁,写操作锁粒度小。:写操作开销大(需复制数组)。
2025-03-11 20:13:08
725
原创 Set有哪些实现类?区别是什么?
在 Java 中, 接口的常用实现类主要有 HashSet、LinkedHashSet 和 TreeSet。它们的核心区别体现在 底层数据结构、元素顺序性、性能 和 适用场景 上。以下是详细对比:底层实现:基于 (哈希表 + 链表/红黑树,Java 8+ 优化)。元素特性:无序:不保证插入顺序或自然顺序。允许 值:可存储一个 元素。性能:时间复杂度:添加()、删除()、查询()均为 (平均)。哈希冲突:冲突严重时(链表过长),会转为红黑树(Java 8+),查询退化为 。适用场景:快速去重,不关心顺序。
2025-03-11 19:55:09
629
原创 为什么素数作为容量可降低哈希冲突概率
在哈希表中,若哈希值的分布存在某些规律(例如大部分哈希值为偶数),当哈希表容量(即模数)为(如 10)时,这些规律会导致索引分布不均,从而增加冲突。
2025-03-11 19:28:36
343
原创 关于HashTable
HashTable 通过简单的同步机制实现线程安全,但因锁粒度过大、性能低下,已不适用于高并发场景。HashTable 是 Java 早期提供的线程安全的键值对存储结构,基于哈希表实现。:元素数量 ≥ 阈值(阈值 = 容量 × 负载因子,默认负载因子 0.75)。数组的每个元素称为“桶”(Bucket),存储链表的头节点。:锁住整个 HashTable 实例,高并发场景下性能较差。:素数作为容量可降低哈希冲突概率(哈希值取模时分布更均匀)。新容量 = 旧容量 × 2 + 1(保持容量为素数)。
2025-03-11 18:37:59
487
原创 关于HashMap
(Java 8 优化):当链表长度 ≥8 且桶数组长度 ≥64 时,链表转为红黑树(查询时间复杂度从 O(n) → O(logn))。:扩容时需重新哈希所有元素,时间复杂度为 O(n),建议预分配容量以减少扩容次数。:多线程同时修改可能导致数据丢失或死循环(Java 7 的链表头插法问题)。:链表长度 ≥8 且桶数组长度 ≥64 时,链表转为红黑树。(Java 7 及之前):链表在扩容时可能形成环,导致。:通过高位异或减少哈希冲突(避免低位相同导致冲突)。:红黑树节点数 ≤6 时,退化为链表。
2025-03-11 18:04:15
692
原创 Java 容器都有哪些
基于红黑树,元素按自然顺序或自定义比较器排序(O(log n))。:基于红黑树,键按自然顺序或自定义比较器排序(O(log n))。:基于动态数组,查询快(O(1)),增删慢(需要移动元素)。(JUC):线程安全,写操作时复制新数组,适合读多写少场景。:基于双向链表,增删快(O(1)),查询慢(O(n))。:键为弱引用,GC 时自动回收键值对(适合缓存)。:基于哈希表,无序,查询快(O(1))。(JUC):分段锁实现的高并发哈希表。(JUC):线程安全的阻塞队列,如。:线程安全的哈希表(已过时,推荐用。
2025-03-11 17:32:04
329
原创 什么情况下会更倾向于使用抽象类而不是接口
希望子类遵循严格的类层次(如所有子类必须属于同一家族)。:通过单继承限制,确保子类不能同时继承多个父类。:在父类中固定算法步骤,子类仅实现差异化逻辑。:强制子类通过特定方式初始化(如验证参数)。:定义一个算法的流程,部分步骤由子类实现。:已有抽象类需扩展时,避免破坏现有代码。:通过构造方法或继承结构限制子类行为。:需要维护对象的状态(非静态变量)。,子类直接复用代码,减少重复。:多个子类需要复用方法或变量。:定义算法骨架,子类填充细节。,约束子类的实例化过程。),或需要多重继承时。
2025-03-11 17:22:33
722
原创 Java中final的作用
关键字通过限制修改,增强了代码的安全性和可维护性,是多线程编程和API设计中不可或缺的工具。暴露给外部(如注册监听器),可能导致未完全初始化的对象被访问。:变量指向的对象不能变,但对象内部的状态可能可变。字段的初始化值对其他线程立即可见(无需同步)。:必须在声明时、构造方法中或初始化块中赋值。仅限制引用指向,不限制对象内部状态。且无修改方法,则对象是线程安全的。,常用于工具类或安全敏感类(如。,保持父类方法的行为一致性。结合,定义全局不可变常量。:一旦赋值,值不能改变。:只需在使用前赋值一次。
2025-03-11 12:51:56
234
Google的三驾马车论文、中文翻译和PPT.zip
2022-05-22
The Computer for the 21st Century.pdf
2022-05-22
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人