自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 JavaWeb ——Cookie 对象

API:创建()、发送()、读取()、生命周期()、路径(setPath()中文处理:需通过URLEncoder编码、URLDecoder解码,不能直接存储中文生命周期:默认会话级(内存),setMaxAge(正数)持久化(硬盘),删除路径作用:控制客户端在哪些请求路径下携带 Cookie,推荐设置为项目根路径场景示例:自动登录、记住用户名、跟踪用户偏好。

2026-03-24 23:39:56 170

原创 请求转发vs重定向、同源策略与跨域

请求转发:一次请求,地址栏不变,仅支持项目内部跳转,可通过request对象传递数据,响应状态码为200,用于项目内带数据的跳转。重定向:两次独立请求,地址栏会改变,可跳转至外部网站或跨项目资源,无法通过request传参,响应状态码为302,用于跨源跳转、防表单重复提交。

2026-03-24 21:40:49 196

原创 JavaWeb ——HttpSession 会话对象全解析(附代码案例)

Session 译为 “会话”,指客户端与服务器之间建立的一次连续交互过程(从用户打开浏览器访问服务器,到关闭浏览器结束)。HttpSession 是服务器为每个客户端单独创建的会话对象,用于存储该用户在一次会话内的私有数据(如用户信息、购物车数据),实现跨请求共享。作用:跟踪用户会话状态,存储用户私有数据,解决 HTTP 无状态协议的局限数据存储位置:服务器端(内存、文件、数据库等,默认存储在服务器内存)特性:每个用户对应唯一的 Session 对象,数据私有,不会与其他用户混淆。

2026-03-23 23:50:47 468

原创 JavaWeb ——HttpServletResponse 响应对象全解析(附代码)

设置响应头信息(如 Content-Type、Refresh、Cookie 等)输出响应正文(如 HTML 内容、字符串数据、JSON 数据等)设置响应状态码(如 200 成功、404 资源不存在、500 服务器错误等)实现请求重定向(客户端跳转)解决响应中文乱码问题本质:服务器响应编码与浏览器解码不一致(默认 ISO-8859-1 不支持中文)(一步到位,推荐)关键:编码设置必须在或之前调用,否则无效。

2026-03-23 21:41:21 397

原创 JavaWeb —— 过滤器 (Filter) 与监听器 (Listener) 全解析(附代码)

生命周期:服务器启动(init)→ 每次请求(doFilter)→ 服务器关闭(destroy)执行顺序:由 web.xml 中<filter-mapping>的配置顺序决定,预处理正序,后处理倒序是放行关键,不调用则目标资源无法访问场景示例:统一编码、权限校验、日志记录、数据过滤三大域对象监听:ServletContext(应用级)、HttpSession(会话级)、ServletRequest(请求级)

2026-03-22 22:53:16 331

原创 JavaWeb ——HttpServletRequest 请求对象(附代码)

HttpServletRequest 为每一次请求创建一个实例,封装所有请求数据获取参数的 4 个方法通用,GET/POST 请求无区别,重点处理中文乱码POST 乱码用必须在 getParameter () 之前调用Tomcat8.5 + 默认支持 GET 中文,低版本需手动转码或修改 server.xmlrequest 是域对象,作用范围为一次请求,用于转发时的数据共享请求转发是服务器内部跳转,地址栏不变,一次请求,无需加项目名。

2026-03-22 22:25:48 349

原创 数据库知识点梳理(二):从基础操作到底层原理

非聚簇索引(我们常说的“普通索引”):单独存储的“关键字+行地址”映射文件(如120M),体积小、加载快,但查到地址后,需要再去原表读取完整数据(这一步叫“回表”)聚簇索引:直接对原表所有数据按主键排序,把数据和索引存在一起,一张表只能有一个聚簇索引(因为数据只能按一种顺序物理存储),查到位置后直接返回完整数据,无需回表其实索引的逻辑很简单,用“小文件+有序结构”,实现“精准定位”,从而减少总线传输和磁盘IO,用写入速度和硬盘空间,换取查询速度的提升。

2026-03-21 17:02:04 311

原创 数据库知识点梳理(一):从基础操作到底层原理

以上就是数据库的核心知识点梳理,从基础的SQL操作,到ER图设计、索引优化,再到底层运行原理和卡顿原因,形成了完整的知识闭环。其实数据库并不难,关键是抓住“程序在内存、数据在硬盘”的核心逻辑,再结合实际使用场景理解每个知识点的作用。

2026-03-21 01:13:19 358

原创 并发编程(二十五):9 行 DCL 双重校验锁单例,经典代码详解

构造方法私有:杜绝外部通过 new 创建对象,是单例模式的基础,考察访问控制规则设为静态方法:构造私有后外部无法创建对象,静态方法是唯一访问入口,考察静态与非静态成员的访问规则实例变量加 static:静态方法只能操作静态变量,属于 Java 语法强制要求加 volatile:禁止对象创建的指令重排序,避免线程获取到半初始化的对象,考察 JMM 内存模型加 synchronized 类锁:保证多线程环境下只有一个线程执行实例初始化,保障线程安全。

2026-03-19 21:32:37 412

原创 零基础入门 Servlet:从创建到运行,超详细教程

Servlet 的全称是 Server Let,即运行在 Web 服务器(如 Tomcat)中的 Java 小程序,专门通过 HTTP 协议接收和响应客户端(浏览器)的请求。用户的所有请求,最终都会由对应的 Servlet 来处理(比如登录请求由登录 Servlet 处理,查询请求由查询 Servlet 处理)。Servlet 是 JavaWeb 三大核心组件之一,由 Tomcat 管理,用于处理 HTTP 请求实现 Servlet 的基础方式是实现接口,必须保证。

2026-03-19 17:40:43 791

原创 并发编程(二十四):单例模式(三):构造方法私有:单例模式的 “第一道防线”

构造方法私有 → 外部无法 new 对象 → 无法通过对象调用非静态方法静态方法不依托对象,可通过 类名.方法() 直接调用,是外部访问单例类的唯一入口静态方法在类内部可访问私有构造,能创建并返回唯一的单例对象,间接让外部调用到非静态业务方法而 Servlet/Controller 不建议全设为静态,因为其业务方法多,全静态会导致类加载时大量占用内存,且静态方法无法重写,扩展性差。

2026-03-18 21:41:38 394

原创 并发编程(二十三):单例模式(二):静态/非静态方法:单例内存优化关键

单例模式的核心是保证一个类全局仅有一个实例,而实际开发中,我们不仅要实现单例,更要兼顾内存优化、线程安全与扩展性。

2026-03-18 20:21:46 343

原创 并发编程(二十二):单例模式总览篇:概念、分类与基础实现

单例本质:一个类全局仅有一个实例,依靠私有构造 + 公共静态获取方法实现;经典实现选型:饿汉式简单安全但非懒加载,DCL 懒汉式是面试最优解,volatile是核心底层关联:volatile 禁止指令重排序,解决半初始化对象问题,与 final 内存语义同源Web 实战:Servlet/Controller 默认单例,无状态设计保证线程安全,是内存优化的关键枚举单例:最安全但无懒加载,与 DCL 单例场景互补,需根据业务按需选择。

2026-03-17 23:44:04 522

原创 并发编程(二十一):final域内存语义增强(二)

原因:增强final是为了避免多线程并发初始化时,final从“常量”变成“变量”,违背其原始语义问题:单行代码内部也会拆分成多个底层指令,无约束时会乱序执行,导致final域“半初始化”目标:让final的“一次初始化”规则,在多线程下和单线程下保持一致,不失效。

2026-03-17 18:35:19 329

原创 并发编程(二十):final域的内存语义(一)与重排序规则

基础类型 final:保证构造后,值一定可见,不会重排序到对象发布之后。引用类型 final:额外保证 —— 构造函数里对 final 引用指向对象内部成员的写入,也一定在对象被发布前完成,别的线程看不到半初始化状态。和 volatile 对比:volatile 禁止重排序的范围更广(所有读写环节),final 只在「构造 - 发布」这个环节做限制,管得更窄、更具体。本质:防止指令重排序导致的「对象半初始化可见」问题,实现线程安全的对象发布。

2026-03-16 17:47:16 487

原创 数组实现动态栈与队列

栈和队列是 Java 开发的基础数据结构,基于数组实现的动态版本既保留了数组的高效访问特性,又通过扩容 / 缩容解决了固定容量的限制。队列的关键是「先进先出 + 元素前移」,栈的关键是「先进后出 + 栈顶操作」offset 指针是控制元素增删的核心,队列中标记队尾,栈中标记栈顶扩容 / 缩容逻辑保证了数据结构的灵活性,适配不同的业务场景。

2026-03-16 03:02:51 633

原创 消息队列MQ(二):架构迭代之路 —— 从单体到微服务,再到 MQ 选型指南

首选适用场景:双 11 订单峰值、用户行为日志采集、实时流计算、分布式事务消息选择依据Kafka:高吞吐,适配大数据生态(如 Flink、Spark),支撑百万级 QPSRocketMQ:阿里生态深度适配,金融级可靠性,提供消息回溯、事务消息等丰富功能,适合电商核心业务消息队列选型需结合企业规模、并发量、功能需求高并发大数据场景(如大厂日志采集、峰值订单),优先选 Kafka,极致高吞吐适配大数据生态。

2026-03-10 18:19:38 464

原创 消息队列MQ(一):异步、削峰、解耦,MQ 解决了什么问题?

本质是更高层次的通讯模型,基于底层同步协议(如 Dubbo、HTTP)构建「生产者 - 消费者」模型,屏蔽复杂通讯细节生产者:发送数据的角色;消费者:接收消息的角色并非仅实现异步和解耦,异步 / 解耦是其应用效果,核心目的是解耦底层通讯协议、提供标准化的消息传递模型队列是 先进先出(FIFO)的线性数据结构,与栈(后进先出)相对补充应用场景:线程池队列(分为有界队列、无界队列),用于存储待执行任务。

2026-03-10 01:24:37 383

原创 Redis 安装+基于短信验证码登录功能的完整实现

Redis 作为高性能的键值对数据库,在缓存、限流、分布式锁、验证码存储等场景中应用广泛。Redis 基础:高性能、原子性、过期策略是支撑验证码场景的核心特性工具类封装:RedisUtil 简化了 Redis 字符串操作,提升代码复用性业务逻辑发送短信:通过 Redis 实现 60 秒限流,避免验证码滥用;登录校验:利用 Redis 过期策略自动失效验证码,保证安全性;

2026-03-09 19:54:31 550

原创 重写equals必重写hashCode + HashMap对象相等判断原理

/ 重写equals:只要name和age相同,就认为是同一个对象@Override// 未重写hashCode,使用Object的默认实现(返回内存地址哈希值)Person p1 = new Person("张三", 20);Person p2 = new Person("张三", 20);// true(按重写后的逻辑,两个对象相等)// false(默认hashCode是内存地址哈希,不同对象不同)

2026-03-09 16:52:56 280

原创 【学习笔记】红黑树

红黑树的核心优势的是“平衡与复杂度的折中”:相比AVL树(严格平衡,旋转次数多),红黑树插入/删除时旋转次数更少,适合频繁修改的场景相比普通BST,红黑树能保证稳定的O(log n)时间复杂度,避免性能退化;相比哈希表,红黑树支持有序遍历和范围查询,填补了有序场景的空白。

2026-03-07 23:24:22 367

原创 Java 容器类全解析:从原理到实践

Java 容器类分为Collection(单元素集合)和Map(键值对映射)两大体系,核心实现类的底层数据结构决定了其性能和使用场景非线程安全容器(ArrayList/HashMap 等)性能更高,线程安全场景优先选择 JUC 包下的实现(如 ConcurrentHashMap)

2026-03-07 12:00:00 368

原创 并发编程(十九):ReentrantLock 与 JUC 核心解析 ——AQS、原子类与 ConcurrentHashMap

ReentrantLock 基于 AQS 实现,volatile 的 state 变量是锁内存语义的核心,公平 / 非公平锁的核心差异在于是否遵循 FIFO 队列顺序;JUC 包的底层基石是 CAS + volatile,通过 “volatile 保证可见性 + CAS 保证原子性” 实现高效并发;原子类基于无锁设计实现原子操作,ConcurrentHashMap 通过分区域加锁(桶级锁)兼顾线程安全与高性能,是多线程场景的首选哈希表实现;

2026-03-06 13:00:00 483

原创 并发编程(十八):volatile——特性、重排序规则与内存语义

volatile 的核心等价性:单个读 / 写操作等价于锁同步,复合操作无原子性重排序规则:volatile 写禁止前置重排序、volatile 读禁止后置重排序,通过内存屏障实现内存增强本质:通过约束底层优化,保障可见性和有序性,是轻量级并发安全工具锁的内存语义:覆盖 volatile 的所有特性,额外提供复合操作的原子性保障,是重量级但全量的并发解决方案。

2026-03-06 12:00:00 356

原创 并发编程(十六):ThreadLocal线程隔离——原理、内存泄漏与实战

A:原理是「Thread + ThreadLocal + ThreadLocalMap」三者配合:1. 每个Thread内部维护一个ThreadLocalMap2. ThreadLocal是ThreadLocalMap的访问入口,对外提供set()/get()/remove() API3. ThreadLocalMap以ThreadLocal为key,存储当前线程的变量副本,实现线程之间的变量隔离(每个线程只能访问自己的副本)。

2026-03-05 12:00:00 892

原创 并发编程(十七):可见性与总线事务 —— 从 JMM 到硬件层的一致性保障

处理器与内存之间的数据传递需经过一系列固定步骤,这组步骤统称为总线事务,是硬件层实现内存操作原子性的基础。可见性是并发安全的基础,volatile和加锁是 Java 层保障可见性的核心手段,前者保证变量可见性 / 有序性,后者通过临界区同步保障操作结果可见性;总线事务是硬件层的内存操作原子性保障,通过 “排他性访问” 避免并发内存操作冲突;JDK 5(JSR-133)优化了 64 位变量的读操作原子性,解决了 “半值读取” 的核心风险,是 JMM 适配硬件特性的关键改进。

2026-03-05 12:00:00 702

原创 并发编程(十五):线程池:原理、源码与实战选型

A:核心流程分四步:1. 任务提交时,先判断核心线程池是否已满,未满则创建核心线程执行2. 核心线程满,判断任务队列是否已满,未满则放入队列3. 队列满,判断最大线程池是否已满,未满则创建非核心线程执行4. 最大线程池满,执行拒绝策略。A:1. 不推荐原因:Executors创建的线程池存在隐患,FixedThreadPool用无界队列易内存溢出,CachedThreadPool最大线程数过大易CPU飙升,无法自定义拒绝策略和线程工厂,灵活性差。

2026-03-03 14:50:48 598

原创 并发编程(十四):HashMap 线程不安全与 ConcurrentHashMap 高性能之道

A:put/resize 等方法无锁,导致两大问题:1. 数据覆盖:多线程并发写入同一桶,赋值操作非原子,后写入线程覆盖前写入线程的数据2. 链表成环:扩容时头插法反转链表,多线程并发导致链表成环,CPU 100%差异:JDK 1.8 将头插法改为尾插法,解决成环问题,但仍存在数据覆盖,依然线程不安全。本篇我们彻底讲了 HashMap 线程不安全的核心问题、JDK 版本优化,以及 ConcurrentHashMap 的高性能实现——这是并发容器的重点,也是生产环境中避坑的关键。

2026-03-03 12:00:00 1728

原创 并发编程(十三):AQS 与 ReentrantLock 从原理到源码

今天,我们揭开了 AQS 的神秘面纱,理解了它作为 “锁的底层” 的核心地位,并通过的源码,看到了volatile和 CAS 是如何协同工作,构建出高效的同步组件的。

2026-03-02 23:27:57 607

原创 并发编程(十二):偏向锁→轻量级锁→重量级锁底层实现、触发条件、不可逆原因

偏向锁,是「偏向于第一个获取它的线程」,在无其他线程竞争的情况下,持有偏向锁的线程再次进入同步代码块时,无需做任何 CAS 操作或加锁解锁操作,直接就能进入,彻底消除无竞争场景下的锁开销。大多数场景下,同步代码块的执行都是「单线程」的,即使有多个线程,也很少出现竞争,偏向锁就是利用这一特性,减少无竞争时的性能损耗。轻量级锁,适用于「低竞争」场景(多个线程交替进入同步代码块,不频繁同时竞争)。

2026-03-02 01:23:51 911

原创 并发编程(十一):CPU 硬件原子性、跨缓存行 / 跨页表与 CAS 核心原理

自旋 CAS:就是在一个循环里反复尝试 CAS 操作,直到成功为止。开销大的原因:如果 CAS 长时间不成功(比如高并发场景下,多个线程同时竞争一个变量),CPU 会一直空转,消耗大量资源 —— 看起来 CPU 利用率很高,但其实没做任何有意义的业务操作。原子性由CPU 硬件保证,不是操作系统。跨缓存行、跨页表、复合操作都会破坏原子性。硬件负责原子,OS 负责调度,两层分工明确。自旋 CAS 高效但空耗 CPU,pause 可优化。CAS 指令只操作一个内存地址。

2026-03-01 21:31:18 619

原创 并发编程(十):对象头 Mark Word 与 synchronized 锁升级机制

无锁:没人用偏向锁:一个线程反复用轻量级锁:线程交替用,轻度竞争重量级锁:激烈竞争,大量线程阻塞JVM 根据竞争激烈程度在安全前提下,尽可能减少性能开销。

2026-03-01 18:13:40 710

原创 并发编程(九):synchronized 锁的底层边界与对象锁本质

在并发编程(六)中,我们纠正了的使用误区,了解了它从偏向锁到重量级锁的升级过程。是锁了代码,还是锁了对象?线程递归调用、方法嵌套时,JVM 又是如何精准识别临界区的?

2026-02-28 23:46:33 646

原创 并发编程(八):原子类与 CAS

假设线程 1 执行 CAS 操作,预期值是 A,想要改成 B;线程 2 将内存中的值从A 改成了 B;线程 3 又将内存中的值从B 改回了 A;线程 1 执行 CAS 时,发现内存值仍是 A,认为数据未被修改,成功将其改成 B。从 CAS 的逻辑来看,操作是成功的,但实际上数据已经被修改过两次 —— 这就是 ABA 问题。大部分场景下 ABA 问题不会影响结果,但在涉及 “状态流转”“版本控制” 的场景下,会导致严重的逻辑错误。

2026-02-28 12:00:00 1350

原创 并发编程(六):synchronized :从使用误区到锁升级

的核心是保证原子性,使用时必须把完整操作包裹在同一把锁内,分开加锁等于没加锁非静态同步方法锁的是实例对象,静态同步方法锁的是 Class 对象,两类锁相互独立实际需精准控制锁粒度和锁对象,根据竞争程度选择合适的同步方案。

2026-02-27 12:00:00 479

原创 并发编程(七):伪共享问题与缓存行优化(CPU 缓存的实战优化)

当多个线程操作不同的变量线程 A 修改缓存行中的变量 X → 其他核心中包含 X 的缓存行失效;线程 B 虽然只操作同一缓存行中的变量 Y,但因为缓存行已失效,必须重新从主内存加载;这种 “操作不同变量却互相影响” 的现象,就是伪共享 —— 看似互不相关的变量,因为缓存行的特性 “伪共享” 了同一缓存行,导致频繁的缓存失效和主内存读写,性能大幅下降。伪共享是 CPU 缓存层面的性能问题,根源是 “不同变量共用缓存行,触发频繁的缓存失效”

2026-02-27 12:00:00 1022

原创 并发编程(四):死锁到底是什么?怎么写、怎么防、怎么查?

简单的来讲,两个或多个线程,互相持有对方需要的锁,又都不释放,大家一起永久卡住不动,这就叫死锁。线程 A 拿着锁 A,想要锁 B线程 B 拿着锁 B,想要锁 A谁都不肯松手 → 俩人都卡死 → 程序僵住你拿着我的手机,我拿着你的钥匙你不给我手机,我不给你钥匙俩人都动不了 → 死锁。

2026-02-26 12:00:00 522

原创 并发编程(五):volatile + 内存屏障 + CPU 缓存

CPU 缓存导致了 “可见性和有序性问题”;volatile 关键字用来 “解决这两个问题”;而内存屏障是 “volatile 的底层实现手段”,通过禁止指令重排序、强制刷新缓存,帮 volatile 实现可见性和有序性。

2026-02-26 12:00:00 2652

原创 并发编程(三):线程快照统计・grep+awk+sort+uniq 实战详解

上一篇咱们讲了 jstack dump 线程快照,其中最关键的一步就是用「grep+awk+sort+uniq -c」这串 指令,快速统计线程状态分布,避开了手动翻几百行快照的麻烦。其实它本质就是 4 个 “小工具” 流水线干活,今天咱们就来讲一讲~

2026-02-25 16:00:00 1461

原创 并发编程(二):线上排查,jstack dump 线程快照新手实操

上一篇咱们聊完了多线程的适用场景和上下文切换的隐形消耗,知道了 “线程数量要平衡” 这个核心原则,但实际开发中,问题往往没那么简单 ——线上服务突然变慢、CPU 飙升、接口超时,排查来排查去,怀疑是线程出了问题(比如大量线程阻塞、空闲),但又看不到线程到底在 “干嘛”,这时候该怎么办?今天就给大家讲一个 Java 后端必备的线上排查神器 ——

2026-02-25 12:00:00 1157

Redis安装包windows

Redis安装包windows

2026-03-09

空空如也

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

TA关注的人

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