- 博客(171)
- 收藏
- 关注
原创 ThreadLocal
ThreadLocal是多线程中实现线程隔离的资源共享工具,通过为每个线程维护独立的变量副本来解决并发冲突。核心方法包括set()、get()和remove(),其底层通过ThreadLocalMap存储数据,key为弱引用的ThreadLocal实例。使用时需注意内存泄漏风险,建议手动调用remove()释放资源,避免因弱引用导致key被回收而value仍存在的内存问题。主要应用于线程封闭场景(如数据库连接管理)和线程内资源共享。
2025-05-24 09:52:40
670
原创 http和https
HTTP和HTTPS是互联网数据传输的两种协议,主要区别在于安全性。HTTP是无状态的应用层协议,适用于公开信息传输,如普通资讯网站,但数据以明文传输,易被截获。HTTPS在HTTP基础上增加了SSL/TLS加密层,确保数据传输的机密性和完整性,适用于敏感信息交互,如网上银行和电商支付。HTTPS使用443端口,需要SSL/TLS证书,并在浏览器中显示安全锁图标,而HTTP使用80端口,无需证书。尽管HTTPS因加密解密过程可能增加性能开销,但其安全性优势使其成为保护敏感数据的首选。
2025-05-23 21:19:05
346
原创 Cookie、Session、JWT
Cookie、Session和JWT是Web开发中用于用户身份验证和会话管理的三种主要技术。Cookie是由服务器发送到客户端并存储在浏览器中的小型文本文件,适用于存储用户偏好和简单会话管理,但安全性较低。Session则是服务器端存储用户会话信息的机制,安全性较高,适合传统Web应用,但存在SessionID泄露的风险。JWT是一种以JSON对象形式在客户端和服务器间安全传输信息的开放标准,适用于分布式系统和前后端分离架构,通过签名机制保证数据安全,但密钥泄露会威胁其安全性。每种技术都有其特定的应用场景和
2025-05-23 20:44:20
485
原创 AOF持久化
RDB持久化是Redis的一种数据备份机制,通过将内存中的数据快照保存到磁盘中,以便在Redis实例故障重启后恢复数据。RDB文件默认保存在当前运行目录。RDB持久化在四种情况下执行:执行save命令、执行bgsave命令、Redis停机时以及触发RDB条件时。save命令会阻塞主进程,而bgsave命令则通过创建子进程异步执行,不影响主进程处理请求。RDB的触发条件可以在redis.conf文件中配置,如“save 60 10000”表示60秒内至少10000次修改时触发RDB。RDB的缺点包括执行间隔时
2025-05-21 22:07:45
346
原创 spring的注入方式都有什么区别
文章主要介绍了Spring框架中四种依赖注入方式:构造器注入、Setter注入、字段注入和接口注入。构造器注入通过构造方法完成,适用于强制依赖和不可变对象,具有依赖不可变、强制注入和循环依赖检测的特点。Setter注入通过公共的Setter方法完成,适用于可选依赖和动态修改依赖的场景,具有灵活性和可选依赖的特点。字段注入通过反射直接注入私有字段,代码简洁但依赖关系不明确,适用于简单组件和快速开发。接口注入通过实现特定接口来声明依赖,但侵入性强且已过时。文章建议优先使用构造器注入,使用Setter注入处理可选
2025-05-21 21:35:45
1368
原创 ThreadLocal
ThreadLocal是Java中用于解决多线程环境下变量并发冲突的类,它为每个线程提供独立的变量副本,确保线程安全。常见的应用场景包括JDBC连接管理,通过将每个线程的Connection对象存储在各自的ThreadLocal中,避免线程间的连接冲突。ThreadLocal的核心方法包括set(value)、get()和remove(),分别用于设置、获取和清除线程局部变量。在实现上,ThreadLocal依赖于内部的ThreadLocalMap类,类似于HashMap,存储线程局部变量。需要注意的是,T
2025-05-19 22:08:56
591
原创 并行和并发
在单核CPU系统中,线程通过任务调度器轮流使用CPU时间片,实现微观串行、宏观并行的并发执行。多核CPU则允许多个线程真正并行运行。并发指同一时间应对多任务,而并行指同一时间执行多任务。例如,家庭主妇独自处理多项家务是并发,雇佣多个保姆分工合作则是并行。现代多核CPU支持并发和并行,如4核CPU可同时执行4个线程,提高效率。
2025-05-19 20:25:43
229
原创 volatile
第一:保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。volatile 是一个关键字,可以修饰类的成员变量、类的静态成员变量,主要有两个功能。第二: 禁止进行指令重排序,可以保证代码执行有序性。底层实现原理是,添加了一个。,通过插入内存屏障禁止在内存屏障。的指令执行重排序优化。
2025-05-18 20:55:37
232
原创 `CAS`
CAS(CompareAndSwap)是一种乐观锁机制,用于在无锁情况下保证线程操作共享数据的原子性。它广泛应用于AQS框架和AtomicXXX类中,通过自旋锁提高效率。CAS底层调用操作系统提供的Unsafe类方法,避免了线程阻塞,效率较高。然而,在竞争激烈时,频繁重试会影响效率。CAS基于乐观锁思想,允许其他线程修改共享变量,失败后重试;而synchronized基于悲观锁思想,通过加锁防止其他线程修改共享变量。
2025-05-18 20:53:52
141
原创 HashMap的扩容机制
在数组初始化或添加元素时,需调用resize方法进行扩容。初始数组长度为16,当元素数量达到当前容量的75%时触发扩容,每次扩容为原容量的2倍。扩容后,会创建新数组并将旧数组数据迁移至新数组。对于无哈希冲突的节点,直接通过e.hash & (newCap-1)计算新索引。若节点为红黑树,则按红黑树规则处理;若为链表,则遍历链表并根据e.hash & oldCap判断元素位置,可能保留原位置或移动至原位置加新增容量的位置。
2025-05-18 19:39:09
232
原创 HashMap的实现原理
HashMap是一种基于哈希表的数据结构,底层由数组和链表或红黑树组成。当插入元素时,通过key的hashCode计算数组下标。若发生哈希冲突,若key相同则覆盖原值,若不同则将键值对存入链表或红黑树。JDK1.8之前使用拉链法处理冲突,即将冲突值加入链表。JDK1.8后,当链表长度超过8且数组长度达到64时,链表会转换为红黑树以提高搜索效率。在扩容时,若红黑树的节点数小于等于6,则退化为链表。
2025-05-18 19:38:20
122
原创 ArrayList和LinkedList的区别是什么?
ArrayList按照下标查询的时间复杂度O(1)【内存是连续的,根据寻址公式】, LinkedList不支持下标查询。ArrayList尾部插入和删除,时间复杂度是O(1);LinkedList头尾节点增删时间复杂度是O(1),其他都需要遍历链表,时间复杂度是O(n)查找(未知索引): ArrayList需要遍历,链表也需要遍历,时间复杂度都是O(n)LinkedList 是双向链表需要存储数据,和两个指针,更占用内存。ArrayList底层是数组,内存连续,节省内存。
2025-05-17 20:07:39
199
原创 数组集合互转问题
Arrays.asList转换list之后,如果修改了数组的内容,list会受影响,因为它的底层使用的Arrays类中的一个内部类ArrayList来构造的集合,在这个集合的构造器中,把我们传入的这个集合进行了包装而已,最终指向的都是同一个内存地址。list用了toArray转数组后,如果修改了list内容,数组不会影响,当调用了toArray以后,在底层是它是进行了数组的拷贝,跟原来的元素就没啥关系了,所以即使list修改了以后,数组也不受影响。List转数组不受影响。数组转List受影响。
2025-05-17 15:26:01
164
原创 MYSQL创建索引的原则
控制索引数量,因为索引虽然可以提高查询速度,但也会影响插入、更新的速度。选择查询频繁的字段作为索引,如查询条件、排序字段或分组字段。如果字段区分度不高,可以将其放在组合索引的后面。表中的数据量超过10万以上时考虑创建索引。尽量使用复合索引,覆盖SQL的返回值。对于内容较长的字段,考虑使用前缀索引。
2025-05-16 20:43:43
201
原创 BASE理论
BASE 理论通过放宽对一致性的严格要求,来换取分布式系统的高可用性和良好性能,与 CAP 理论中的 AP 模型紧密相关。许多分布式系统如分布式缓存(Redis、Memcached )、消息队列(RabbitMQ、Kafka )常遵循该理论。BASE 理论是对 CAP 理论的扩展与补充 ,用于解决分布式系统中一致性、可用性和平衡性问题,适用于需高可用性和可扩展性,且能容忍一定程度数据不一致的分布式系统。
2025-05-16 12:52:08
325
原创 AP CP
在中,和是其支持的两种不同的,用于适应不同的业务场景需求。Nacos 作为微服务架构中的核心组件,主要解决和因此,Nacos 通过来平衡不同场景下的一致性与可用性需求,其底层基于和实现。
2025-05-15 16:13:27
455
原创 Spring中的循环引用
循环依赖发生在两个或两个以上的bean互相持有对方,形成闭环。一级缓存:单例池,缓存已完成初始化的bean对象。二级缓存:缓存尚未完成生命周期的早期bean对象。,用于创建bean对象。
2025-05-14 22:40:53
391
原创 Spring的bean的生命周期?
进行bean的依赖注入,例如通过setter方法或。的后置处理器,可能在这里产生代理对象。调用构造函数实例化bean。获取bean的定义信息。调用初始化方法,如实现了。最后是销毁bean。
2025-05-14 22:40:21
271
原创 数据库事务并发问题
脏读、幻读和不可重复读是数据库并发操作中常见的三种问题。脏读指一个事务读取了另一个未提交事务修改的数据,可能导致读取到无效数据。幻读指事务在操作过程中,由于其他事务的插入或删除操作,导致前后两次查询的结果集不一致。不可重复读指事务在多次读取同一数据时,由于其他事务对该数据进行了修改并提交,导致每次读取到的数据不一致。脏读涉及未提交的数据,不可重复读涉及同一数据项的多次读取结果不一致,幻读则涉及结果集行数的变化。这些问题可能影响数据库的一致性和准确性,通常通过设置不同的事务隔离级别来避免或减少其发生。
2025-05-13 13:52:11
309
原创 进程和线程
进程和线程是操作系统中实现并发执行的两个关键概念。进程是程序的一次执行,拥有独立的内存空间和系统资源,是资源分配和调度的基本单位。线程则是进程内的执行单元,共享进程资源,但拥有独立的栈和寄存器。核心区别在于资源占用、调度开销、并发性、通信方式、健壮性及创建/销毁成本。进程间资源独立,通信复杂,但健壮性强;线程资源共享,通信简单,但一个线程的崩溃可能影响整个进程。进程的创建和销毁成本高,线程则相对较低。
2025-05-12 16:43:50
268
原创 typora快捷键
本文详细列出了文本编辑软件的各项快捷键,涵盖了菜单栏、文件、编辑、段落、格式和视图六大功能模块。菜单栏部分包括文件、编辑、段落、格式、视图、主题和帮助的快捷键;文件模块涉及新建、打开、保存等操作;编辑模块包括撤销、重做、剪切、复制等常用功能;段落模块涵盖标题、表格、代码块等编辑工具;格式模块涉及文本样式调整,如加粗、斜体、下划线等;视图模块则提供了侧边栏、大纲视图、全屏等显示选项的快捷键。这些快捷键帮助用户高效完成文档编辑和格式调整任务。
2025-05-10 20:16:24
470
原创 适配器模式
适配器设计模式通过创建中间适配器类,解决了接口实现类需要重写所有抽象方法的问题。适配器类实现接口并对所有方法进行空实现,真正的实现类只需继承适配器类并按需重写所需方法,减少了代码冗余,提高了开发灵活性。适配器类通常被声明为抽象类,以确保其仅作为父类被继承,符合设计意图。这种模式在仅需使用接口中部分方法时尤为有效,简化了代码结构并提升了效率。
2025-05-10 13:16:00
206
原创 @PostConstruct @PreDestroy
是 Java EE(现 Jakarta EE)中的一个注解,用于标记一个方法在对象。它在 Spring 框架、Java Web 应用等场景中广泛使用,主要用于资源初始化、依赖注入完成后的配置等操作。@Autowiredvoidpublicprotectedprivate是 Java EE(现 Jakarta EE)中的一个注解,用于标记一个方法在对象。它与相对应,主要用于资源释放、清理操作,确保对象在生命周期结束时正确释放占用的资源(如关闭数据库连接、停止线程、释放文件句柄等)。
2025-05-09 21:23:20
388
原创 抽象类和接口的区别
Java中的抽象类和接口是两种关键的抽象类型,用于定义规范和实现多态性。抽象类使用abstract class定义,可以包含抽象方法和具体方法,支持单继承,适用于共享状态和默认行为的场景。接口使用interface定义,只能包含抽象方法、默认方法和静态方法,支持多实现,适用于定义行为规范和解耦设计。抽象类强调“是什么”,提供公共属性和行为;接口强调“能做什么”,定义行为契约。选择抽象类还是接口取决于设计需求:若需共享状态或默认行为,选择抽象类;若需定义行为规范且支持多重实现,选择接口。
2025-05-09 20:59:06
378
原创 高并发优化方案
解决高并发问题从宏观角度来说有3个方向:其中,水平扩展和服务保护侧重的是运维层面的处理。而提高单机并发能力侧重的则是业务层面的处理,也就是我们程序员在开发时可以做到的。
2025-05-08 16:45:38
1144
原创 通用分布式锁组件
注解本身起到标记作用,同时还要带上锁参数:锁名称锁等待时间锁超时时间时间单位@Component@Aspect// 1.创建锁对象// 2.尝试获取锁// 3.判断是否成功if(!isLock) {// 3.1.失败,快速结束throw new BizIllegalException("请求太频繁");try {// 3.2.成功,执行业务// 4.释放锁@Overridereturn 0;
2025-05-07 22:19:01
982
原创 Redisson
Redisson是一个基于Redis的工具包,功能非常强大。将JDK中很多常见的队列、锁、对象都基于Redis实现了对应的分布式版本。
2025-05-07 21:01:35
409
原创 优惠券并发安全问题(1)
超卖这样的线程安全问题,解决方案有哪些?悲观锁:添加同步锁,让线程串行执行优点:简单粗暴缺点:性能一般乐观锁:不加锁,在更新时判断是否有其它线程在修改优点:性能好缺点:存在成功率低的问题。
2025-04-29 08:57:00
867
原创 悲观锁与乐观锁
乐观锁持有 “乐观” 的态度,它认为在大多数情况下,多个线程或事务对共享资源的操作不会发生冲突,所以在操作之前不会加锁。例如,在银行系统中,对用户账户余额的修改操作通常使用悲观锁,以确保在一个事务对账户进行修改时,不会有其他事务同时修改该账户,避免出现数据不一致的问题。例如,在电商系统中,商品的库存信息通常会被大量用户读取,但只有在用户下单时才会进行写操作,这种情况下可以使用乐观锁来提高系统的并发性能。所以在操作之前,会先对资源进行加锁,以防止其他线程或事务的干扰,确保操作的独占性。
2025-04-29 08:44:06
498
原创 领取优惠券
领券的本质就是新增一条记录到user_coupon表,去记录用户和领券的优惠券之间的关系,使用状态等信息。不过,用户id我们可以自己获取,因此前端只要传递优惠券id即可。只传一个参数,我们可以直接用路径占位符传参。更新发行数量(已领取数量),不仅仅起到统计作用,同时也可以帮助我们判断库存是否充足。更新coupon表中已经领取的数量,别忘了在coupon表中是有一些统计字段的。校验优惠券的发放时间,是不是正在发放中。校验优惠券是否存在,不存在无法领取。1.Controller层。校验优惠券的每人限领数量。
2025-04-27 22:39:49
410
原创 查询发放中的优惠券
这里要查询的是发放中的,并且领取方式是手动领取的优惠券。但是这里有一些隐含的内容在原型中没有显示出来:大家思考一下,如果这个优惠券我点击过立即领取,并且领取成功以后,页面该如何显示?不过这都是一些状态信息,不需要前端传递,我们自己在业务中判断即可。有效天数:券的使用有效期有两种方式,一种是到期时间;有效期的结束时间:页面写的是有效期至xxx,也就是说不关心有效期的开始时间,只关心结束时间。是否已经领取:也就是用户是否有已经领取,尚未使用的券。1.Controller层。领取方式是手动领取的。
2025-04-27 22:37:56
242
原创 异步生成兑换码
假如一个优惠券是通过兑换码方式领取。第一次发放时我们生产了兑换码,然后被暂停,然后再次发放,如果我们再次生成兑换码,这就重复了。在发放优惠券的时候,如果发现优惠券的领取方式是兑换码方式,则需要生成兑换码。而且,由于生成兑换码的数量较多,可能比较耗时,这里推荐基于线程池异步生成。之前的状态必须是待发放,不能是暂停。领取方式必须是兑换码方式。不过,需要注意的是,
2025-04-25 19:02:15
252
原创 发放优惠券
发放(领用)开始时间:如果为空说明是立刻发放,开始时间就是当前时间。,我们才知道发放的是哪张券,当然这个可以通过路径占位符传参。使用期限开始时间:如果为空说明是固定天数有效期。使用期限结束时间:如果为空说明是固定天数有效期。有效期天数:如果为空说明是固定有效期。1.Controller层。发放(领用)结束时间。
2025-04-25 19:00:13
353
原创 自定义starter
这是因为在实际的项目开发当中,我们可能会用到很多第三方的技术,并不是所有的第三方的技术官方都给我们提供了与SpringBoot整合的starter起步依赖,但是这些技术又非常的通用,在很多项目组当中都在使用。我们前面案例当中所使用的阿里云OSS对象存储服务,现在阿里云的官方是没有给我们提供对应的起步依赖的,这个时候使用起来就会比较繁琐,我们需要引入对应的依赖。上面我们简单介绍了自定义starter的场景,以及自定义starter时涉及到的模块之后,接下来我们就来完成一个自定义starter的案例。
2025-04-25 13:10:42
1089
原创 @Conditional
我们在跟踪SpringBoot自动配置的源码的时候,在自动配置类声明bean的时候,除了在方法上加了一个@Bean注解以外,还会经常用到一个注解,就是以Conditional开头的这一类的注解。以Conditional开头的这些注解都是条件装配的注解。下面我们就来介绍下条件装配注解。@ConditionalOnMissingBean:判断环境中没有对应的bean(类型或名称),才注册bean到IOC容器。作用:按照一定的条件进行判断,在满足给定条件后才会注册对应的bean对象到Spring的IOC容器中。
2025-04-25 12:57:15
139
原创 分页查询优惠券
优惠券规则:这里是对优惠规则的描述,而数据库中保存的是具体的优惠金额;这里我们不组装描述返回,仅仅返回优惠金额信息,由前端自己组织展示即可。一个典型的带过滤条件的分页查询,非常简单。使用范围:这里无需展示真正的限定范围,只要告诉前端有没有限定范围即可。其它字段没什么特殊的,此处不再赘述了。1.Controller层。
2025-04-24 22:08:57
345
原创 新增优惠券
需要特别注意的是,如果优惠券限定了使用范围,则需要保存限定的课程分类。而这些信息不再coupon表,而是一张中间关系表:coupon_scope。一个基本的新增接口,按照Restful风格设计即可,关键是请求参数。之前表分析时已经详细介绍过这个页面及其中的字段,这里不再赘述。1.Controller层。
2025-04-24 22:07:19
238
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人