彻底搞懂 I/O 多路复用:从多进程到 epoll 的演进神话在构建高性能网络服务的道路上,有一个绕不开的圣地——I/O 多路复用。无论是支撑高并发的 Nginx,还是单线程却快到飞起的 Redis,其底层的核心基石都是这项技术。
本文将带你从最原始的多进程模型出发,一步步拆解技术演进的逻辑,看看内核开发者们是如何精妙地解决 C10K(万级并发) 问题,最终孵化出 epoll 这一高性能杀手锏的。
一、 网络模型演进史:我们是如何走到 I/O 多路复用的?在深入内核之前,我们先通过一张全景图,看看在 I/O 多路复用出现之前,传统的并发模型经历了怎样的痛点与迭代。
模型
核心机制
优点
缺点 / 瓶颈
适用场景
多进程
每个连接一个 fork()
进程隔离,安全,一个子进程崩了不影响整体
内存开销巨大,上下文切换极慢(需切虚拟内存)
早期系统,连接数极少(<100)
多线程
每个连接一个 pthread
比进程轻量,共享内存,切换开销小
频繁创建销毁开销大;线程死锁或崩溃会导致整个进程挂掉
连接数较少,任务耗时较长 ...
左闭右开二分查找:一套模板搞定所有场景二分查找是算法面试和工程开发中的高频考点,但左闭右闭、左闭右开两种写法容易混淆出错。
今天给大家整理一套彻底统一、零歧义、永不死循环的左闭右开二分模板,背会这一套,所有二分查找问题直接套用,堪称标准答案!
一、核心基础:左闭右开定义这是理解整个模板的前提,必须牢牢记住:
1. 区间规则1[l, r)
左闭:l 是有效下标,可以取到
右开:r 是边界下标,永远取不到
2. 初始化写法12int l = 0; // 左边界:数组起始位置int r = nums.length; // 右边界:数组长度(取不到最后一个元素)
二、万能通用模板(背诵版)所有二分查找的核心骨架,直接背!
1234567891011121314151617// 初始化:左闭右开 [0, nums.length)int l = 0, r = nums.length;while (l < r) { // 防溢出写法,替代 (l+r)/2 int mid = l + (r - l) / 2; // 核心条件:根据需求修 ...
🚀 为什么要用 TransmittableThreadLocal?一文读懂线程上下文传递问题在 Java Web 开发中,我们经常用 ThreadLocal 来保存每个请求的用户信息,例如 userId。但当我们使用线程池或异步方法(如 @Async)时,很多人会遇到这样的问题:
❗ 主线程设置了 ThreadLocal,子线程里却拿不到!
这是因为 ThreadLocal 的值默认不会在线程池中传递到子线程,会导致上下文丢失,比如 userId 为 null,traceId 无法传递等问题。
🧩 问题重现1234567// 主线程中设置用户 IDUserContext.setUserId(123L);// 子线程中获取(比如线程池执行)executorService.submit(() -> { System.out.println(UserContext.getUserId()); // 输出 null});
✅ 解决方案:使用阿里开源的 TransmittableThreadLocal (TTL)TransmittableThreadL ...
ConcurrentHashMap解析以下是对 Java 8 及以后版本 ConcurrentHashMap 源码的深入解析,涵盖其底层数据结构、并发控制机制、核心操作流程、扩容与迁移、树化/退化策略,以及性能特性。总体来说,ConcurrentHashMap 在 JDK 8 中摒弃了原有的 Segment 分段锁,采用了「数组 + 链表/红黑树 + CAS + synchronized」的设计,使得检索无锁、更新高并发,且在扩容时支持多线程协作,以此在确保线程安全的同时,最大化地提升性能和可伸缩性。
底层数据结构ConcurrentHashMap 维护一个类型为 Node<K,V>[] table 的主数组,数组长度始终为 2 的幂次方,每个桶(bin)最初存储 Node 节点(单链表)或 TreeBin(红黑树)
Node:包含 final int hash; final K key; volatile V val; volatile Node<K,V> next;,用于链表结构的实现
TreeBin:当单链表长度 ≥ 8 且数组容量 ...
LinkedHashMap解析LinkedHashMap 是 Java 集合框架中在保留 HashMap 高效存取性能的基础上,通过额外维护一条双向链表来保证元素的迭代顺序(插入顺序或访问顺序)的 Map 实现。其核心思路是在每个桶(bucket)节点上都增加 before 和 after 指针,串联成一个环形双向链表,并由 head、tail 引用维护链表首尾。当执行 put、get(若开启访问顺序)、remove 等操作时,除了调用 HashMap 的基本操作,还会对链表做相应调整,以保证有序迭代。以下从源码结构、主要方法、链表维护、扩容与迭代等方面做深入剖析。
1. 源码结构概览1.1 继承关系与节点设计
LinkedHashMap<K,V> 直接继承自 HashMap<K,V>,复用其拉链表/红黑树冲突解决机制,同时为每个节点增加双向链表功能
内部静态类 LinkedHashMap.Entry<K,V> extends HashMap.Node<K,V>,在父类 Node 的基础上新增两个指针:
12Entry< ...
HashMap解析本质上,HashMap 通过一个长度为 2 的次幂的数组 table 维护所有条目,解决哈希冲突采用“数组 + 链表”或“数组 + 红黑树”混合结构。当链表长度超过阈值(TREEIFY_THRESHOLD = 8)且表容量不小于 MIN_TREEIFY_CAPACITY = 64 时,会将该链表转化为红黑树,以确保最坏情况下的查询性能由 O(n) 降至 O(log n);反之,在扩容时若红黑树节点数低于 UNTREEIFY_THRESHOLD = 6,则会“退化”回链表结构。HashMap 的默认初始容量为 16,默认加载因子为 0.75,**每次扩容都会将容量翻倍**,并更新阈值 threshold = capacity * loadFactor,以保证空间与时间开销的平衡。以上设计使得 HashMap 在大多数应用场景中既能保持常数级别的平均时间复杂度,又能在极端冲突情况下依然提供可接受的性能保证。
底层数据结构数组与链表 / 红黑树HashMap 的主体是一个 Node<K,V>[] table 数组,每个 Node 包含 key、valu ...
java中ArrayList扩容机制的解析本文将系统地介绍 Java 中 ArrayList 的扩容机制,包括其初始容量的设置、触发扩容的时机、容量增长算法、扩容的详细流程以及性能优化建议,帮助读者从源码层面深入理解这一关键特性,并在实际开发中合理预分配容量以提升性能。
一、ArrayList 简介ArrayList 底层由一个可变长度的数组 elementData 支撑,可在运行时动态调整大小,属于顺序表的具体实现,具有随机访问速度快、增删效率相对较低、非线程安全的特点
二、初始化与构造1. 无参构造器
调用 new ArrayList<>() 时,elementData 被赋值为一个空数组常量 DEFAULTCAPACITY_EMPTY_ELEMENTDATA,此时容量为 0
当第一次添加元素时,ensureCapacityInternal(1) 将最小容量 minCapacity 与默认容量 DEFAULT_CAPACITY = 10 比较,最终分配容量为 10
2. 指定初始容量构造器
使用 new ArrayList<>(initialCapaci ...
微服务中组件扫描(ComponentScan)的工作原理你的问题涉及到Spring框架中@ComponentScan的工作原理以及Maven依赖管理的影响。我来解释为什么能够扫描到common模块的bean而扫描不到其他模块的bean。
根本原因关键在于**类路径(Classpath)**的包含情况:
Maven依赖的模块会被包含在最终的类路径中
未通过Maven依赖的模块不会被包含在类路径中
详细解释对于common模块
当你通过Maven引入了common模块依赖:
12345<dependency> <groupId>com.csuft</groupId> <artifactId>common</artifactId> <version>1.0.0</version></dependency>
Maven会将该模块的编译输出(通常是jar包)包含在你的应用类路径中
@ComponentScan("com.csuft")工作时:
Sprin ...
实现Sentinel与Nacos的规则双向同步:完整解决方案前言在微服务架构中,流量控制和熔断降级是保障系统稳定性的重要手段。阿里开源的Sentinel作为一款轻量级的流量控制组件,常被用于实现这些功能。然而,在实际生产环境中,我们往往需要动态调整规则配置,这就需要将Sentinel规则与配置中心(如Nacos)集成。
本文将详细介绍如何实现Sentinel规则(包括流控规则和熔断规则)与Nacos的双向同步,确保规则变更能够实时生效并持久化。
一、核心设计思路我们实现的双向同步机制包含三个关键功能:
从Nacos读取初始配置 - 服务启动时加载最新规则
监听Nacos配置变更 - 实时响应远程配置变化
Sentinel改变规则本地动态加载-实时响应远程配置变化
本地规则变更写回Nacos - 确保所有服务实例配置一致
123456graph LR A[Sentinel Dashboard] -->|1.修改规则| B[本地RuleManager] B -->|2.通知| C[NacosDataSource] C -->|3.发布到| D[Nac ...
AI技术前沿:Function Calling、RAG与MCP的深度解析与应用实践随着人工智能技术的迅猛发展,大型语言模型(LLM)正逐步从单纯的文本生成工具进化为能够与外部世界交互的智能系统。在这一演进过程中,Function Calling、RAG(检索增强生成)和MCP(模型上下文协议)三大技术扮演着关键角色。本文将深入探讨这三种技术的核心原理、应用场景以及它们如何共同推动AI应用进入新阶段,同时提供实用的代码示例和行业趋势分析,帮助开发者把握AI技术的最新发展方向。
引言:AI技术发展的新阶段2025年,人工智能技术迎来了前所未有的发展浪潮。从AIGC(人工智能生成内容)到智能体(Agent),从AI+RPA到推理模型优化,AI的应用场景不断拓展和深化2。在这一背景下,如何让大型语言模型突破自身局限,实现与外部世界的高效交互,成为技术发展的关键挑战。
传统的大型语言模型虽然具备强大的文本理解和生成能力,但仍存在明显局限:无法获取实时信息、缺乏垂直领域专业知识、不能直接操作系统或工具完成任务。为解决这些问题,行业先后发展出了三种关键技术方案:
Function Calling: ...





























