自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(106)
  • 收藏
  • 关注

原创 手写Tomcat原理整理

所以手写 Tomcat 的核心就是:启动阶段:扫描 → 反射 → 注解 → 实例化 → 存 HashMap请求阶段:Socket 接收 → 线程池处理 → 封装 Request/Response → 判断静态资源还是 Servlet → HashMap 匹配 → invoke 调用 → 返回响应而支撑这一切的三大核心技术就是:反射、线程池、动态代理。这也是几乎所有 Java 框架的通用模式。

2026-07-20 15:04:36 211

原创 Claude code实战:Harness工程之道 阅读笔记(1)

传统使用方式只发挥 Claude Code 极小一部分能力,其真正核心价值在于一套完整工程化 Agent 框架,把软件工程成熟设计模式迁移到 AI 开发场景;分层记忆、权限隔离、事件拦截、模块化复用,全部是后端 / 前端通用经典工程思想,学习门槛贴合现有开发者认知;企业落地核心收益:统一团队 AI 辅助标准、自动化质量管控、支撑大规模代码重构、打通外部业务数据,将 AI 深度融入研发流水线;行业趋势:AI 编程比拼不再只是模型生成能力,Agent 工程化、标准化、可复用框架是团队长期提效关键。

2026-07-14 16:08:37 607

原创 使用Tableau Public

优势:采用拖拽式操作界面,维度 / 度量字段分类清晰,可视化图表类型一键切换,右侧展示窗格提供直观的图表选择入口,新手易上手。不足:免费版功能受限(如无数据提取、高级分析功能),界面定制化程度低于 Tableau Desktop。

2026-03-31 17:36:04 374

原创 Tasker笔记

Tasker 是一款运行在 Android 系统上的强大自动化辅助应用。它通过配置文件(Profiles)设置触发条件,并执行对应的任务(Tasks),实现各种自动化操作。触发器类型:程序、时间、日期、位置、硬件/软件状态、事件、快捷方式、桌面小工具、计时器任务组成:一系列操作(Actions),支持循环、变量、条件判断(If)特性无需 Root 权限即可使用大部分功能(部分底层操作需要 Root)支持第三方插件(如 AutoVoice、AutoInput)无需编程基础桌面插件。

2026-03-31 15:08:30 690

原创 系统性能指标与损耗分析

按并发量级选架构,低并发不盲目分布式,高并发不硬扛单机。磁盘是最大瓶颈,能用内存解决的绝不碰磁盘。全链路控损耗:减少网络 RTT、控制带宽、缩短线程阻塞、轻量化业务逻辑。架构无银弹,先压测定位瓶颈,再针对性优化,比盲目堆机器更有效。把这套损耗逻辑吃透,你就能从 “卡了就加机器” 升级为 “精准优化、百万 QPS 稳跑” 的架构思维。

2026-03-28 16:49:34 358

原创 神经网络与 Transformer 原理

神经网络:用多层加权计算模拟复杂决策,训练就是暴力拟合最优权重;算法优化:核心是降维与拆解,用更聪明的计算方式替代纯算力堆砌;:靠注意力机制理解上下文,实现链式推理与文本生成;工程架构:从单体走向分布式,依靠缓存、无状态、负载均衡支撑高并发。AI 既不是玄学,也不是简单的暴力计算,而是数学优化 + 神经网络结构 + Transformer 注意力机制 + 分布式高并发架构的综合产物。理解这些,你就真正看透了大模型从训练到上线的完整逻辑。

2026-03-28 16:44:13 338

原创 AI底层数学原理与训练机制

多因素:指影响最终结果的所有特征变量。比如识别人脸,会涉及脸型、五官比例、肤色、纹理等多个维度;判断一句话的语义,会涉及词语、语序、上下文、情感倾向等大量因素。这些因素在数学上,共同构成一个高维空间。最优解:在所有变量组合中,找到一组让目标效果最好的方案。对分类任务而言,最优解意味着识别准确率最高;对生成任务而言,最优解意味着内容最贴合需求、误差最小。在高维空间中,寻找函数的最大值或最小值。数学本质:在高维空间求解多因素最优解,依靠梯度寻找极值;计算核心:通过卷积实现降维与特征提取,解决高维灾难;

2026-03-28 16:32:45 415

原创 AI视觉识别的原理与流程(一)

以 RGB 像素与亮度差异为基础 → 边缘检测定位目标轮廓 → 池化平滑去除干扰 → 数学求导判断形状 → 特征点拆分实现高精度识别。理解这套底层流程,不仅能看懂 OpenCV、YOLO 等框架的工作原理,更能在实际项目中定位识别误差、优化检测效果,而不只是停留在 “调包调用” 层面。无论是学习深度学习,还是做工程落地,扎实的视觉基础都是必不可少的核心能力。

2026-03-28 16:26:19 582

原创 AI视觉识别原理与YOLO框架应用

AI视觉识别并非不可理解的“黑箱”,而是一套建立在数学、物理和工程学基础上的严谨技术体系。从像素点的RGB值,到边缘检测的导数计算,再到特征工程的特征拆分,每一个环节都体现着“化繁为简”的工程智慧。YOLO与OpenCV等框架通过封装底层逻辑和自动化学习,极大降低了AI视觉识别的应用门槛,让更多开发者能够快速构建识别系统。然而,面对细小目标、不规则目标等特殊场景,通用框架仍存在明显短板。理解底层原理、掌握手写识别代码的能力,才能在复杂场景中实现精准识别——

2026-03-28 11:54:50 575

原创 ConcurrentHashMap ——put + get

无锁读volatile保证可见性,读操作不加锁,性能接近HashMap。细粒度锁:写操作只锁当前桶的头节点,并发写入互不干扰。CAS 无锁更新:空桶插入、计数更新等简单操作使用 CAS,避免锁开销。多线程协助扩容:将扩容任务分摊给多个写线程,大幅减少扩容停顿时间。高效计数LongAdder思想分散计数压力,高并发下依然准确高效。

2026-03-27 21:30:18 376

原创 ConcurrentHashMap 设计原理笔记

通过一系列精妙的设计,在保证线程安全的前提下,提供了接近HashMap的读写性能。无锁读:借助volatile保证可见性,读操作完全不加锁,实现高并发读。细粒度锁:锁的粒度从整个表缩小到每个桶的头节点,并发写能力大幅提升。CAS 无锁更新:对于简单的、无需遍历的操作,使用 CAS 原子更新,避免锁开销。多线程协助扩容:将耗时的扩容任务拆分为多个子任务,允许写线程帮忙迁移,降低扩容停顿。高效计数:采用LongAdder思想,分散计数压力,提升高并发下的计数性能。

2026-03-27 21:26:43 342

原创 Java线程池工作原理与回收机制

线程池的复用和回收机制是其高效运行的基础。通过循环 + 阻塞的方式,线程得以持续处理多个任务;通过poll和take的灵活切换,实现了对空闲线程的回收,使线程数能够根据负载动态伸缩。理解这些机制,不仅有助于我们正确配置线程池参数,还能在遇到问题时快速定位原因。在实际开发中,建议:根据业务场景合理设置和,避免线程数过大或过小。设置合理的,平衡线程回收速度和资源占用。除非有特殊需求,保持核心线程默认不回收,保证快速响应。在应用关闭时,务必调用shutdown()并配合优雅终止线程池。

2026-03-27 21:12:22 474

原创 Java线程池——核心方法解析execute / submit / shutdown

executesubmit和shutdown是线程池使用的三个基石。execute负责最基础的任务提交,submit提供了更强大的结果获取和异常处理能力,而shutdown系列方法则保障了线程池的优雅退出。理解它们的内部原理,不仅可以帮助我们写出更安全的并发代码,还能在遇到问题时快速定位。在实际开发中,建议:对无需结果的任务,优先使用execute并处理好异常。对需要结果或异常感知的任务,使用submit并务必处理Future。始终记得在应用关闭时调用shutdown并配合实现优雅退出。

2026-03-27 21:07:34 423

原创 Java线程池——工作原理

本文从线程池的诞生背景出发,详细介绍了的核心参数、执行流程、源码实现、队列选择、拒绝策略以及监控调优等内容。掌握线程池的工作原理,不仅可以帮助我们写出更健壮的多线程代码,还能在遇到性能瓶颈时从容定位和解决问题。

2026-03-27 20:46:59 476

原创 HashMap、Hashtable、ConcurrentHashMap对比

HashMap是性能标杆,但只能在单线程中使用。Hashtable是历史产物,全局锁限制了其并发能力,已逐渐被淘汰。是现代并发编程的首选,JDK 1.8的演进使其在并发度、内存效率、扩容性能上都达到了新的高度。

2026-03-26 19:37:22 385

原创 JDK 1.8 ConcurrentHashMap——CAS+synchronized

维度JDK 1.7JDK 1.8数据结构Segment数组 +HashEntry数组Node数组 + 链表/红黑树锁粒度按Segment加锁,默认16个段按单个桶加锁,理论上可达到数组长度级别并发控制CAS读操作无锁,依赖volatile完全无锁,同样依赖volatile写操作锁定Segment桶为空时CAS,非空时锁头节点扩容每个Segment独立扩容,单线程迁移多线程协同扩容,性能大幅提升计数方式遍历Segment的count,采用两次遍历+加锁兜底LongAdder思想,

2026-03-26 19:31:34 396

原创 JDK 1.7 ConcurrentHashMap——分段锁

高并发:相比Hashtable,锁粒度细化,默认并发度可达 16,在多线程环境下吞吐量显著提升。读操作无锁get方法利用volatile实现无锁读,读写操作几乎不互斥,适合读多写少的场景。分段独立性:每个Segment独立管理自己的数据,扩容、计数等操作互不干扰,降低了复杂度。JDK 1.7 的通过分段锁机制,在保证线程安全的前提下大幅提升了并发性能,是 Java 并发容器中里程碑式的设计。它巧妙地平衡了锁的粒度与实现复杂度,为后来的 JDK 1.8 版本(采用CAS的细粒度锁)奠定了基础。

2026-03-26 19:24:40 419

原创 Java笔记——JMM

Java内存模型是理解并发编程的基石。它通过定义主内存与工作内存的交互规则,以及happens-before原则,为开发者屏蔽了底层硬件的复杂性。在实际开发中:当需要保证可见性和有序性时,可以使用volatile关键字。当需要保证原子性时,可以使用或。对于高并发下的计数器等场景,可以使用Atomic系列类(基于CAS)。掌握JMM,不仅能帮你写出线程安全的代码,还能让你在面对各种诡异的并发Bug时,拥有快速定位问题的能力。

2026-03-26 19:19:54 454

原创 数据结构——红黑树

每个节点是红色或黑色。根节点是黑色。每个叶子节点(NIL节点,即空节点)是黑色。通常实现中,我们用null代表叶子节点,并认为其颜色为黑色。如果一个节点是红色,则它的两个子节点都是黑色。这条性质保证了没有两个连续的红色节点。对于每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。这条性质称为“黑色平衡”,它确保了红黑树的最长路径不超过最短路径的两倍,从而保证了操作的时间复杂度为O(log n)。

2026-03-26 19:09:29 488

原创 数据结构——树

树是由n(n ≥ 0)个节点组成的有限集合。当 n = 0 时,称为空树。当 n > 0 时,存在一个特殊的节点称为根节点(Root),其余节点被划分为 m(m ≥ 0)个互不相交的有限集合,每个集合本身又是一棵树,称为根节点的子树(Subtree)。这种定义具有递归性:树由根和若干子树组成,而子树又是树。正是这种递归特性,使得很多树相关的算法天然适合用递归实现。数据结构查找平均查找最坏插入平均插入最坏删除平均删除最坏普通 BSTO(log n)O(n)O(log n)O(n)

2026-03-25 11:24:38 491

原创 数据结构——链表

链表是一种线性数据结构数据域:存储元素本身的值。指针域:存储指向下一个节点(或上一个节点)的引用。节点之间通过指针链接,形成一条逻辑上的线性序列。与数组不同,链表中的节点在内存中不必连续,它们可以分散在内存的各个角落,通过指针串联在一起。动态大小:可以根据需要随时增加或减少节点,没有容量限制(受限于内存)。非连续存储:节点在内存中任意位置,通过指针维护顺序。插入删除高效:只要知道操作位置,插入或删除节点只需修改指针,无需移动其他元素。

2026-03-25 11:20:02 423

原创 数据结构——数组

数组是一种线性数据结构,它用一组连续的内存空间存储相同类型的数据元素,并通过索引(下标)来访问每个元素。在大多数编程语言中,数组的索引从 0 开始。连续内存:所有元素在内存中紧密排列,没有空隙。固定类型:数组中的元素通常具有相同的数据类型(在静态类型语言中强制,在动态语言如 Python 中虽可混合但底层仍是同质)。随机访问:通过索引可以在 O(1) 时间内直接访问任意元素。静态或动态:有的语言提供静态数组(长度固定),有的提供动态数组(可自动扩容)。操作静态数组动态数组(均摊)随机访问O(1)

2026-03-25 11:11:04 497

原创 数据结构——队列

队列是一种操作受限的线性表,它只允许在一端(称为队尾,Rear)进行插入操作,在另一端(称为队头,Front)进行删除操作。队列中没有元素时称为空队列。可以把队列想象成一根水管:水从一端注入(入队),从另一端流出(出队)。最先注入的水会最先流出,后注入的水只能等前面的水都流出后才能流出。本文全面介绍了队列这一基础数据结构:队列遵循先进先出原则,只允许在队尾插入、队头删除。enqueuedequeuefront等,时间复杂度均为 O(1)。实现方式有顺序队列(循环队列)和链式队列。

2026-03-25 11:05:43 502

原创 数据结构——栈

栈是一种操作受限的线性表,它只允许在表的一端进行插入和删除操作,这一端被称为栈顶(Top),另一端则称为栈底(Bottom)。栈中没有元素时称为空栈。可以想象一个羽毛球筒:放入羽毛球(入栈)只能从顶部放入,取出羽毛球(出栈)也只能从顶部取出,最先放入的羽毛球反而最后才能被取出。本文介绍了栈的核心概念:栈是一种后进先出的线性数据结构,操作受限。pushpoppeekis_empty等,时间复杂度均为 O(1)。可以通过数组(顺序栈)或链表(链式栈)实现,各有优缺点。

2026-03-25 11:01:34 510

原创 Java笔记——反射

反射是指程序在运行期可以访问、检测和修改它自身状态或行为的一种能力。通过反射,我们可以:获取任意类的名称、包信息、父类、接口等。动态创建对象实例。获取并调用任意方法(包括私有方法)。访问和修改字段的值(包括私有字段)。操作数组。Java 反射 API 主要位于包中。Java 反射机制是一种强大的工具,它使程序具备了动态性,是框架和基础库不可或缺的部分。优点:提供了极高的灵活性,支持动态代理、依赖注入、注解处理等高级特性。缺点:性能损耗、破坏封装、可能引发安全问题、代码可读性降低。

2026-03-24 22:34:34 325

原创 Java笔记——IO

字节流和字符流,分别用于处理二进制数据和文本数据。每个大类又细分为输入流和输出流。BIO简单可靠,适合小规模应用;NIO通过多路复用实现了高并发,成为现代高性能服务器的基石(如 Netty、Tomcat NIO 模式);AIO进一步将异步能力交给操作系统,但在实际应用中尚未完全取代 NIO。对于大多数开发者来说,理解 NIO 的原理已经足够应对日常开发。如果想深入,可以研究 Netty 框架,它封装了 NIO 的复杂性,提供了优雅的 API 和稳定的性能。

2026-03-24 22:25:13 282

原创 Java并发——线程间的通信

优先使用LockCondition如果需要精确控制线程唤醒顺序、支持中断或超时,或者需要更灵活的锁机制,推荐使用和Condition。避免虚假唤醒无论使用还是,判断条件时必须使用while循环,而不是if。在finally中释放锁必须放在finally块中,确保锁在任何情况下都能被释放,避免死锁。使用多个Condition实现精确通信当需要多个线程协作时,为每个线程创建独立的Condition,结合状态标志,可以显著提高代码的可读性和效率。注意notify()vs使用。

2026-03-24 21:51:20 429

原创 Java并发——Lock锁

锁类型特点简单、自动释放,但功能单一,不可中断,无法公平手动控制锁,支持公平锁、可中断、限时等待,可重入读写分离,读读并发,写写互斥,适用于读多写少场景,支持锁降级在实际开发中,应根据具体需求选择合适的锁:简单的同步逻辑,优先使用。需要高级功能(公平、超时、可中断)时,选用。读多写少的场景,使用能显著提升并发性能。掌握这些锁的特性,能够帮助我们编写出更高效、更可靠的多线程程序。

2026-03-24 21:46:15 408

原创 Java并发——线程池

在Java并发编程的世界里,线程池是一个绕不开的核心话题。无论是面试中的高频考点,还是实际项目中的性能优化,线程池都扮演着至关重要的角色。本文将带你深入理解线程池的设计思想、实现原理以及最佳实践。// 获取CPU核心数cpuCores, // 核心线程数cpuCores * 2, // 最大线程数60, // 空闲存活时间new ArrayBlockingQueue<>(200), // 有界队列new CustomThreadFactory(), // 自定义线程工厂。

2026-03-24 21:41:36 400

原创 Java并发——并发编程的三大挑战

即使是单核处理器,也能通过时间片轮转机制支持多线程并发执行。CPU为每个线程分配一个极短的时间片(几十毫秒),任务执行完当前时间片后,会切换到下一个任务。在切换前,系统会保存上一个任务的状态(寄存器、程序计数器等),以便下次切换回来时能够恢复执行。这个“保存-再加载”的过程就是上下文切换。就像我们读两本书,中途查字典时需要记住当前读到了哪一页哪一行,查完再接着读——这样的切换会降低效率,上下文切换同样会带来性能开销。当两个或两个以上的线程互相持有对方需要的资源,且都不释放自己占有的资源时,就会陷入死锁。

2026-03-23 16:54:37 320

原创 Java并发——死锁

死锁是指两个或两个以上的线程,在执行过程中因争夺资源而造成的一种互相等待的现象。若无外力干预,它们都将无法推进下去。简单来说,就是:线程 A 持有资源 1,等待资源 2;线程 B 持有资源 2,等待资源 1。双方都得不到想要的资源,于是永远阻塞。死锁是多线程编程中难以完全避免的问题,但通过理解其产生的四个必要条件,我们可以有针对性地采用预防策略:按顺序申请资源、使用超时锁、减少锁持有时间等。同时,掌握 jstack、JConsole 等工具能帮助我们在问题发生后快速定位。

2026-03-23 16:52:30 347

原创 Java并发——CAS(比较并替换)

CAS的全称是Compare And Swap(比较并交换),它是一种CPU原语级的原子操作,用于实现多线程环境下共享变量的无锁修改。V:主内存中的当前值(变量实际存储的位置)A:线程预期的旧值(线程从主内存读取后保存在本地的副本)B:线程希望写入的新值CAS的执行过程极其简单:如果 V == A,则将 V 更新为 B;否则不做任何操作。整个“比较+交换”过程由CPU硬件保证原子性,不会被任何其他线程中断。从宏观上看,CAS是一条乐观的指令:它假定在读取之后到更新之前,没有其他线程修改过该变量;

2026-03-23 11:07:29 459

原创 Java并发——共享资源并发风险

原子性是指一个操作要么全部执行且不受干扰,要么完全不执行。在Java中,对基本类型变量的赋值和读取通常是原子的(long和double例外),但像i++i += 1这样的复合操作不是原子的。并发编程中的共享资源风险,源于操作系统的时间片轮转和线程交错执行。数据覆盖原子性破坏临界资源竞争是三种最常见的并发问题,它们本质都是对共享资源的多线程访问缺乏协调。要避免这些风险,必须为临界区提供互斥保护,确保同一时刻只有一个线程能执行关键操作。从到Lock,再到Atomic。

2026-03-23 09:45:42 355

原创 Java并发——锁的状态演变

Java锁的状态演变是JVM为了平衡性能与正确性而设计的精巧机制。通过对象头中的Mark Word记录锁状态,并动态升级,使得在无竞争时几乎零开销,在有竞争时也能保证线程安全。理解锁升级过程,有助于我们更好地诊断并发问题,例如:为什么在高并发下性能下降?(升级为重量级锁,线程阻塞)为什么偏向锁在某些场景下反而拖慢性能?(频繁撤销导致安全点暂停)随着JDK的发展,锁优化也在不断演进。尽管偏向锁逐渐淡出,但轻量级锁和自适应自旋依然是现代JVM中性能的重要保障。

2026-03-23 09:36:26 372

原创 Java并发——synchronized锁

明确锁对象:实例方法锁的是this,静态方法锁的是Class对象,同步代码块锁的是任意指定对象。错误地选择锁对象(如用String常量或Integer值)可能导致意想不到的全局锁或锁失效。控制锁粒度:同步代码块提供了最细粒度的控制,应尽量缩小同步范围,避免在锁内执行耗时操作或IO操作。锁对象不可变:锁对象一旦确定,不应被重新赋值,否则会导致锁失效。通常使用作为专用锁。注意死锁:当多个锁嵌套使用时,要避免循环等待,可以通过统一顺序或使用tryLock等高级工具规避。了解锁升级:在JDK 1.6之后,

2026-03-22 22:28:09 352

原创 Java并发——并发编程底层原理

并发编程的底层,是操作系统和硬件精心编排的一场“时间分片”大戏。时间片轮转让我们在单核时代体验到“并行”的错觉,上下文切换则保证多任务公平执行的同时,也带来了性能损耗。了解这些底层机制,我们才能在实际开发中更理性地设计并发策略:既充分利用多核资源,又避免过度切换带来的开销。

2026-03-22 22:24:38 286

原创 Java并发——多线程

Java多线程编程从基础的Thread到高级的,提供了丰富的抽象和工具。掌握线程的生命周期、同步机制以及JUC中的并发组件,是构建高性能、高可用系统的基石。在实际开发中,应根据场景选择合适的并发策略,避免过度优化或忽视线程安全。并发编程虽复杂,但通过系统学习和实践,完全可以驾驭。

2026-03-22 22:13:06 410

原创 Java笔记——static和final关键字

当static和final一起修饰变量时,就定义了一个编译期常量。这样的变量属于类,且值不可修改。Java 编译器会对这种常量进行内联优化,直接将常量值嵌入到使用它的代码中,提升性能。注意:对于引用类型的静态常量,如果引用的是可变对象(如),虽然引用本身不可变,但列表的内容仍然可以被修改。因此,如果要实现真正的不可变集合,需要结合等工具。static和final是Java中两个基础但强大的关键字。static赋予成员“类级别”的生命周期和共享特性,适用于工具方法、单例模式、静态常量等场景。final。

2026-03-22 22:05:44 367

原创 Java并发——偏向锁

在一个线程多次获取同一把锁的场景下,让该线程无需进行任何同步操作即可获得锁,从而降低CAS操作带来的开销。假设一个锁被同一个线程反复获取,比如在单线程环境中或通过循环调用synchronized方法,那么偏向锁允许线程在第一次获得锁后,后续再进入同步块时直接检查对象头中的线程ID是否为自己,如果是,则无需任何CAS操作,直接进入同步块。这可以大大减少无竞争情况下的锁开销。偏向锁是HotSpot JVM为优化synchronized而设计的一把“双刃剑”。

2026-03-22 21:34:05 365

原创 Java笔记——多态

多态的字面意思是“多种形态”。在Java中,多态指的是同一个行为具有多个不同表现形式或实现的能力。具体来说,就是同一个引用类型,调用同一个方法,根据实际指向的对象不同,执行的结果也不同。父类引用指向子类对象,调用重写方法,实际执行的是子类的方法。多态是Java面向对象编程的核心,它让程序能够根据对象的实际类型动态决定行为,从而实现代码的灵活、可扩展和易于维护。多态的基础:继承(或实现)、重写、父类引用指向子类对象。动态绑定:方法调用在运行时才确定,这是Java多态的底层机制。成员访问。

2026-03-21 22:36:26 426

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除