- 博客(38)
- 收藏
- 关注
原创 抛出自定义异常
本文介绍了Java中自定义异常和全局异常处理的实现方法。首先定义了一个ServiceImplException运行时异常类,配合ResultCode枚举类来管理状态码和异常信息。然后通过@RestControllerAdvice注解创建全局异常处理器GlobalExceptionHandler,使用@ExceptionHandler注解分别处理不同类型的异常(如请求方法不支持异常、运行时异常、业务异常等)。该方案能自动捕获服务层抛出的异常,并返回统一的错误响应格式,实现了异常处理的集中管理和规范化输出,提高
2025-08-04 23:43:55
238
原创 SpringBoot自动装配原理
摘要:Spring Boot的自动装配是其核心特性,通过@SpringBootApplication注解简化配置流程。自动装配的核心是@EnableAutoConfiguration注解,该注解会导入AutoConfigurationImportSelector类,通过selectImports()方法筛选并加载符合条件的Bean。开发者只需在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中
2025-08-04 23:19:30
748
原创 实现游戏排行榜
本文介绍了一个基于Java的并发游戏排行榜系统实现。系统采用ConcurrentHashMap存储玩家分数,实现O(1)时间复杂度的分数查询;使用ConcurrentSkipListMap按分数降序存储玩家ID集合,支持高效的排名查询和前N名获取。设计方案考虑了线程安全、高效查询(获取排名O(logn)、前N名O(n))以及同分玩家处理等关键需求。通过分析对比多种数据结构,最终选择跳表+哈希表的组合,在保证并发安全的同时,提供了良好的查询性能。文章详细解析了核心代码逻辑,特别是原子性更新操作的实现原理。
2025-08-03 21:09:09
758
原创 Java中finally执行规则
Java中finally块的执行机制:finally块中的代码在正常情况下(try/catch块执行后)总会执行,即使遇到异常或return语句,除非JVM被终止(如System.exit())。执行时机为:在return前暂存返回值,执行finally后再返回;或在异常抛出前先执行finally。需注意finally中的return会覆盖原返回值,应避免使用以防止掩盖原始异常或返回值。唯一不执行finally的情况是JVM崩溃或强制终止。
2025-08-01 15:31:40
305
原创 Redis持久化-AOF
摘要:Redis的AOF持久化通过记录写命令确保数据实时持久化。AOF采用内存缓冲区(减少IO次数)和顺序写盘(提升性能)策略,基本不影响处理速度。工作流程包括命令写入缓冲区、定期同步硬盘、文件重写压缩和重启加载。提供always/everysec/no三种同步策略,默认everysec兼顾性能与安全。重写机制通过删除冗余命令和合并操作来缩小文件体积,可手动或自动触发。Redis启动时优先使用AOF恢复数据,因其记录更完整。相比RDB快照,AOF更适合实时持久化,与RDB共同构成Redis的持久化方案。
2025-07-22 21:27:46
697
原创 Redis的持久化-RDB
Redis持久化机制包括RDB和AOF,RDB通过快照保存数据。RDB触发方式分为手动(save/bgsave)和自动(配置触发、主从复制、关闭服务)。bgsave采用fork子进程实现,通过写时拷贝技术减少性能开销。RDB文件默认压缩保存,具有快速恢复优势,但不适合实时持久化且存在版本兼容风险。持久化功能确保Redis重启后能恢复数据,但需权衡性能和存储空间。
2025-07-19 19:37:28
1018
原创 Spring中的设计模式
Spring框架中广泛应用了多种设计模式,主要包括:工厂模式(通过BeanFactory和ApplicationContext创建对象)、单例模式(默认Bean作用域)、代理模式(实现AOP)、模板方法模式(如JdbcTemplate)、观察者模式(事件驱动模型)和适配器模式(AOP通知和MVC控制器适配)。这些模式帮助Spring实现了控制反转(IoC)和依赖注入(DI)的核心思想,通过解耦对象依赖关系、管理对象生命周期、增强扩展性等方式,显著提升了框架的灵活性和可维护性。
2025-07-18 23:14:18
856
原创 Spring MVC详解
Spring MVC 是一种基于 Java 的实现了 MVC (Model-View-Controller) 设计模式的轻量级 Web 框架,属于 Spring Framework 的一部分。它通过将模型 (数据)、视图 (用户界面) 和控制器 (处理请求逻辑) 分离,使开发者能够构建松耦合、可维护的 Web 应用程序。
2025-07-02 23:19:50
871
原创 【Java--SQL】${}与#{}区别和危害
MyBatis中#{}和${}的区别及${}的SQL注入风险 摘要:#{}采用预编译处理,将参数值作为占位符传递,能有效防止SQL注入;${}直接拼接SQL语句,存在安全风险。示例显示,当使用${}处理用户输入时,攻击者可构造恶意输入('or1='1)绕过验证,导致查询出全部数据。建议优先使用#{},仅在需要动态拼接SQL时谨慎使用${},并做好参数过滤。
2025-06-28 22:22:06
386
原创 SQL语句在MySQL中的执行过程
MySQL基础架构分析摘要 MySQL采用分层架构,分为Server层和存储引擎层。Server层包含连接器、查询缓存(8.0移除)、分析器、优化器和执行器等组件,负责身份认证、SQL解析、优化和执行等核心功能。存储引擎层采用插件式架构,支持InnoDB、MyISAM等引擎,负责数据存储。 查询语句执行流程:权限检查→分析器→优化器→执行器→引擎。更新语句引入了日志模块,采用redolog(InnoDB特有)和binlog双重日志机制,通过两阶段提交保证数据一致性。关键区别在于更新流程包含redolog的p
2025-06-26 18:51:42
824
原创 MySQL事物隔离级别详解
SQL事务隔离级别解析:四种标准级别从低到高分别为READ-UNCOMMITTED(允许脏读)、READ-COMMITTED(阻止脏读)、REPEATABLE-READ(阻止不可重复读)和SERIALIZABLE(完全隔离)。InnoDB默认使用REPEATABLE-READ并通过MVCC机制和Next-Key锁优化,有效解决了幻读问题。不同级别在数据一致性和并发性能间权衡,实际应用中需根据场景选择。高隔离级别可能降低并发性能,但InnoDB的优化使REPEATABLE-READ在多数场景下仍能保持良好性能
2025-06-26 18:50:30
771
原创 缓存穿透、缓存击穿、缓存雪崩
本文介绍了缓存使用中的三大问题及其解决方案:1.缓存穿透(请求key不存在于缓存和数据库):解决方案包括参数校验、缓存无效key、使用布隆过滤器预先拦截非法请求等;2.缓存击穿(热点数据缓存过期):建议采用预热热点数据、加锁重建缓存或设置合理过期时间;3.缓存雪崩(大量缓存同时失效):可通过多级缓存、随机过期时间、Redis集群等方式预防。文章还对比了穿透与击穿的区别,强调预防措施需根据业务场景综合运用,如秒杀场景需特别注意数据预热和过期策略。
2025-06-24 23:41:08
1084
原创 JWT基础概念详解
JWT(JSON Web Token)是一种流行的跨域认证解决方案,采用基于Token的无状态认证机制。它由Header、Payload和Signature三部分组成,通过数字签名确保数据安全。JWT的优势在于简单易用、安全可靠、支持跨域和移动端,特别适合微服务架构。但存在注销后仍有效、续签等问题,常见解决方案包括黑名单机制、双Token策略等。尽管JWT有诸多优点,仍需根据项目需求合理选择认证方案,不能盲目推崇。其核心在于签名安全,密钥保管尤为重要。
2025-06-18 19:56:24
848
原创 ArrayList源码分析
ArrayList是Java集合框架中的动态数组实现,底层基于Object[]数组存储。与数组相比,其容量可自动扩容,默认初始容量为10。主要特点包括:支持快速随机访问(实现RandomAccess接口)、允许存储null值、线程不安全。与LinkedList相比,ArrayList在随机访问时性能更优(O(1)),但插入删除效率较低(需移动元素)。扩容机制采用1.5倍增长策略,通过System.arraycopy()和Arrays.copyOf()实现数据迁移。关键源码分析显示,当容量不足时会调用
2025-06-17 19:25:07
628
原创 Json和XML文件相互转化
本文介绍了在Java中实现XML与JSON相互转换的多种方法。对于XML转JSON,讲解了使用org.json库的步骤,包括读取XML文件、转换为JSONObject并格式化输出。对于JSON转XML,则演示了如何通过org.json、Jackson以及Gson+XStream三种方式实现转换。每种方法都提供了详细的Maven依赖配置和完整代码示例,并说明了关键代码的功能。文章还比较了不同转换库的特点:org.json简单易用,Jackson功能全面适合大数据处理,Gson+XStream则更轻量灵活。这些
2025-06-16 09:19:33
1902
原创 访问网页的全过程
本文梳理了访问网页的全过程,按照网络五层模型进行解析。首先通过DNS协议获取域名对应的IP地址,涉及根服务器、TLD服务器和权威服务器的协同查询。随后浏览器通过HTTP/HTTPS协议发起TCP连接请求,服务器返回响应后浏览器解析HTML并加载资源。文章详细介绍了URL结构、DNS工作流程(含递归和迭代查询)、HTTP传输机制,并强调网络层的核心功能是转发与路由。整个过程涵盖了从应用层到网络层的关键知识点,为理解计算机网络通信提供了系统框架。
2025-06-15 10:39:59
933
原创 HTTP和HTTPS协议
HTTP协议是应用层协议,采用TCP作为底层传输,默认端口80,具有无状态特性。HTTPS通过SSL/TLS协议实现数据加密,结合非对称加密(用于密钥交换)和对称加密(用于数据传输)确保通信安全。非对称加密使用公钥/私钥对,而对称加密共享单一密钥。为防止中间人攻击,引入第三方证书机构验证服务器公钥真实性。数字签名机制通过加密校验和,确保证书未被篡改,从而建立安全通信通道。该方案兼顾安全性与效率,非对称加密保障密钥传输安全,对称加密提升数据传输速度。
2025-06-14 17:23:30
1313
2
原创 基于Redis实现分布式锁
摘要:分布式锁主要用于解决多线程环境下共享资源的互斥访问问题,避免数据竞争和超卖等问题。本地锁在单一JVM中有效,但在分布式系统中失效,因此需要分布式锁。分布式锁应具备互斥性、高可用性、可重入性、高性能和非阻塞性。基于Redis的分布式锁可通过SETNX实现互斥,并通过Lua脚本确保解锁原子性。为防止锁释放失败,需设置锁的过期时间,但需注意避免锁提前过期。Redisson提供自动续期机制(WatchDog),确保锁在共享资源操作未完成时不会过期。推荐使用Redisson实现高效可靠的分布式锁。
2025-06-13 15:14:15
926
原创 如何基于Redis实现延时任务
Redis实现延时任务的两种方案:一是通过过期事件监听机制,利用Redis的发布订阅功能监听key过期事件,但存在时效性差、消息丢失和重复消费等问题;二是使用Redisson内置的延时队列,基于SortedSet实现任务排序和定时触发,具有消息持久化、避免重复消费的优势。相比而言,Redisson方案更可靠,但实际项目中推荐优先考虑消息队列的延时消息功能。
2025-06-13 10:06:05
595
原创 【Java-EE进阶】代理模式详解
代理模式是一种通过代理对象访问真实对象的设计模式,可在不修改原对象的基础上扩展功能。分为静态代理和动态代理两种。静态代理需要为每个目标类手动创建代理类,灵活性差;动态代理则更灵活,包括JDK动态代理(基于接口)和CGLIB动态代理(基于继承)。JDK动态代理通过InvocationHandler接口实现方法拦截,而CGLIB通过MethodInterceptor接口实现。两者相比,JDK代理效率更高,但CGLIB能代理未实现接口的类。动态代理在运行时生成字节码,比静态代理的编译时生成更灵活。
2025-06-12 11:36:57
1577
原创 LRU LFU FIFO缓存以及代码实现
介绍了三种常见缓存策略的实现方法。LRU缓存通过哈希表+双向链表实现,将最新访问数据移至头部,淘汰尾部数据;LFU缓存优化版采用频率哈希表+双向链表结构,按使用频率维护节点;FIFO缓存借助LinkedHashMap的插入顺序特性自动淘汰最早数据。各策略均提供Java实现代码,其中LRU和优化LFU实现O(1)时间复杂度,而基础LFU使用优先队列实现O(logN)复杂度。文章对比了三种策略的数据结构选择和操作流程,并针对LFU基础实现的缺陷给出了优化方案。
2025-06-11 10:59:52
1116
原创 SpringAOP详细解读
Spring Aop(Aspect-Oriented Programming,面向切面编程)是一个Spring框架中的一个核心模块,主要用于处理横切关注点。
2025-06-10 11:42:19
788
原创 【Java-EE初阶】synchronized详解
1.AQS是多线程中的队列同步器。2.AQS的内部是一个先进先出的双向队列,线程在队列中进行排队。3.AQS中的属性state为0时就是无锁状态(默认),当一个线程将state设置为1的时候就获取了该锁。4.state属性的修改主要使用CAS,保证多线程数据修改的原子性。
2025-06-09 11:21:45
743
原创 【Java-EE初阶】序列化和反序列化
在进行反序列化时,Jvm会把传来的字节流中的serialVersionUID与本地实体类中serialVersionUID进 行比较,如果相同则认为是一致的,便可以进行反序列化,否则就会报序列化版本不一致的异常。使用单利模式时,通常希望这个对象是唯一的,但是如果该类是可序列化的,单例模式初始化的对象不一致,可以。父类实现了序列化,子类没有,他的子类都将自动的实现序列化,不需要显示实现序列化接口。序列化保存的是对象的状态,而静态变量属于类的状态,因此,序列化并不保存静态变量。
2025-04-03 10:57:38
863
原创 c语言-联合体和枚举
像结构体一样,联合体也是由一个或者多个成员构成。这些成员可以不同的类型。但是编译器只为最大的成员分配足够的内存空间。联合体的特点就是所有成员共用一块空间。所以联合体也叫:共用体。给联合体其中一个成员赋值,其他成员的值也跟着变化。首先我们先计算联合体的大小可以看出来这个联合体的大小个为4个字节,同时呢也能看出来这两个公用一块空间。
2025-03-29 10:57:51
773
原创 C语言-结构体内存对齐
我们要想掌握内存对齐,首先得先知道对齐规则1.结构体的第一个成员对齐和结构体变量起始位置偏移量为0的地址处2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处对齐数=编译器默认的一个对齐数与该成员变量大小的较小值-VS中默认的值为8-Linux中gcc没有默认对其书,对齐数就是成员自身的大小。3.结构体总大小为最大对齐数(结构体中每个成员变量都有一个对齐数,所有对齐数中最大)的整数倍。(所以结构体中开辟的空间有的不一定能够用到)
2025-03-29 09:30:56
899
原创 【网络原理】Tcp相关的一些机制
Tcp的相关特性:1.有链接 2.可靠传输 3.面向字节流 4.全双工其中可靠传输是重中之重,是tcp最核心的特性,所谓的可靠传输不是说100%能够将数据传输到对方,而是退而求其次,1.发送方将数据发出去之后,能够知道接收方是否收到数据。2.一旦发现对方没有收到,就可以通过一系列的手段来进行“补救”。1.确认应答发送方,把数据给接收方之后,接收方收到数据就会给发送方返回一个应答报文。发送方,如果收到了这个应答报文,就知道自己的数据是否发送成功了。
2024-11-23 10:49:45
2069
原创 LeetCode和牛客网有关列表题目总结—Java
举个例子,有一段路程一个人的速度是另一个人的速度的两倍,当快的走完全程的时候,慢的正好走到中间,这里也是一样的。head的指向无非就是这两个链表其中的一个,在第一次比较的时候就出现了,head等于list1或等于list2,而cur也需要这样赋值,之后就是来比较list1和list2的val值,小的链接在cur的后面。在进行回文结构的判断的时候,我们先想到的是让一个引用在前面一个引用在后面,分别进行遍历。相交链表一定是Y字型的,而不是X字型的,因为相交链表是两个链表的其中一个节点的next域相同。
2024-10-11 22:05:10
1968
原创 Java中的多态
1.静态为什么不能重写,是因为静态的方法不属于对象,而重写的目的是满足子类自己的需要,并且进行调用的,这一过程必须有对象的实例化,所以静态的方法不能重写。向下转型用的少,一旦转换失败就是抛异常,就引入了instanceof,如果表达式为true,就会安全转换。B的构造方法中调用了func方法,此时会触动发生动态绑定,会调用到D中的func。通过父类引用,调用这个父类和子类重写的方法,结果是调用了子类的方法。所谓的向下转型就是父类的引用,去调用子类特有方法。也就是通过父类的引用来调用重写的方法。
2024-10-02 17:42:30
946
原创 Java中的继承
在我们的身边一直会听继承这个概念和多态这个概念,那么继承和多态到底是什么呢?在我们的生活中会发现许多有关联的事物,而在编程中也是这样,所谓的继承就是对多个事物进行共性抽取,实现代码的复用。面这两个类成员变量和方法都十分类似,我们写两个类是不是有点浪费时间呢?我们可以通过继承写一个Animal类,让这两个类继承Animal类中成员变量和方法,达到代码的效果。
2024-10-01 19:01:45
1059
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人