- 博客(16)
- 收藏
- 关注

原创 Redis常见数据类型和应用场景
String是最基本的key-value结构,key是唯一标识,value是具体的值,value不仅可以是字符串,也可以是数字(整数或者浮点数),value容纳的数据上限为512M。List是简单的字符串列表,按照插入顺序排序,可以从首、尾操作列表中的元素。Set是Redis中的单列集合,满足下列特点:无序元素唯一可进行交集、并集、差集操作list类型和set类型的区别:list可存储重复元素,set只能存储唯一元素。存储元素时list有序,set无序。
2024-09-27 18:09:30
2604
1
原创 缓存穿透、击穿、雪崩
用户的数据一般都是存储在数据库中,也就是硬盘上,但硬盘的读写速度是计算机里最慢的硬件了。当用户请求都访问数据库,访问量一上来,数据库很容易就崩溃了,所以为了避免用户直接访问数据库,会用redis作为缓存层。redis作为内存数据库,内存的读写速度比硬盘高出好几个数量级,大大提高了系统性能。但引入了缓存层就会有缓存异常的三个问题:缓存穿透、缓存击穿和缓存雪崩。
2025-03-13 16:42:06
660
原创 Spring框架常见的注解
一般情况下@Bean和@Configuration搭配使用,但也可以和@Component结合使用。是 Spring 框架中的一个注解,用于标记 Bean 的某个属性(通常是依赖注入的属性)是。启用 Spring Boot 的自动配置机制,自动配置应用程序所需的 Bean。的属性没有被注入值,Spring 容器在初始化 Bean 时会抛出。方法不会被代理,每次调用都会返回一个新的实例。,用于定义 RESTful 控制器。方法,但这种方式不会触发。
2025-03-13 14:04:16
773
原创 Spring Boot自动化配置的原理
该注解通过 @Import 注解导入对应的配置选择器。加载该项目和该项目引用的 Jar 包的META-INF下面的spring.factories 文件中的所配置的类的全类名。在这些配置类中所定义的 Bean 会通过条件过滤和选择需要应用的配置类来决定是否需要将其导入到 Spring 容器中。条件判断会有像 @ConditionalOnClass 这样的注解,判断是否有对应的 class 文件,如果有则加载该类,把这个配置类的所有的 Bean放入 spring 容器中使用。
2025-03-12 23:42:55
150
原创 Bean的生命周期
是 Spring 框架中的一个核心概念,通过XML 配置或注解把一个 Bean 的元数据信息封装成一个BeanDefinition对象。Spring 容器在在进行实例化时,会根据创建和管理 Bean 实例。包含了 Bean 的类名、作用域、属性值、初始化方法、销毁方法等信息。
2025-03-12 22:47:09
870
原创 Setter注入和构造器注入分别是什么,区别在哪里?
在 Spring 中,依赖注入(Dependency Injection, DI)是实现控制反转(IoC)的核心机制,常用的依赖注入方式有两种:和 。
2025-03-12 21:02:07
301
原创 Spring循环依赖
循环依赖是指Bean对象循环引用,两个或多个bean之间相互持有对方的引用,导致Spring容器无法初始化它们。例如,A引用了B,发现B还没创建,于是开始创建B,在创建B的过程中发现B又引用了A,但A还没创建好。
2025-03-12 20:32:27
505
原创 AOP概念理解
AOP称为面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”( Aspect ),以切面作为基本单位。通过代理的方式,在调用想用的对象方法时进行拦截处理,执行切入的逻辑,然后再调用真正的方法实现。减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。
2025-03-11 22:52:59
184
原创 Bean是线程安全的吗?
singleton作用域下,IoC容器中只有唯一的bean实例,可能会存在资源竞争问题(取决于bean是否有状态)。如果这个bean有状态的话,那就存在线程安全问题(有状态的bean是指:包含可变的成员变量的对象)。不过,大多数bean实际都是无状态的,比如Dao类、Service类,这种情况下Bean是线程安全的。(几乎所有场景中bean的作用域都是默认的singleton)。prototype作用域下,每次获取都会创建一个新的bean实例,不存在资源竞争,所以也就没有线程安全的问题。
2025-03-11 22:02:48
138
原创 最长连续序列(leetcode hot100)
降低时间复杂度为O(n):当一个数是连续序列的第一个数的情况下才会进入内层循环,然后在内层循环中匹配连续序列中的数,因此数组中的。3.遍历去重后的set,加上if条件(当一个数是连续序列的第一个数的情况下才会进入内层循环)2. 遍历数组nums中的每一个数并存入set中(去重)。创建一个HashSet,值的类型是int。4.循环遍历求出当前最长连续序列。5.每次遍历更新最长连续序列的值。
2025-02-13 16:41:37
157
原创 字母异位词分组(LeetCode hot100)
4. 检查这个键是否存在于map中,如果存在,就将s添加到对应的列表中;否则,创建新的列表,并将键和列表添加到map中。如何将每个字符串转换成一个统一的标识,这样同一组的异位词会有相同的标识,然后根据这个标识来分组。1. 创建一个HashMap,键的类型是String,值的类型是List<String>。5. 最后,将map中的所有值(即各个列表)收集到一个List中,作为结果返回。3. 对每个s,将其转换为字符数组,然后排序,再转换为字符串作为键。2. 遍历输入的字符串数组strs中的每一个字符串s。
2025-02-13 16:14:28
127
原创 长度最小的子数组算法理解
也可以理解为双指针法的一种,通过不断调节子序列的起始位置和终止位置,从而得到我们想要的结果。只用一个for循环,那么这个循环中的索引一定是终止位置。窗口起始位置如何移动:通过每次满足 sum >= target 时 让 sum -= nums[i--];也就代表窗口开始缩小了,向前移动了。窗口内容:满足 和 >= target 的长度最小的连续子数组。窗口的结束位置:遍历数组的指针,也就是for循环中的索引。暴力算法会导致超时,使用滑动窗口解决。时间复杂度:O(n)
2024-12-11 23:15:05
538
原创 移除元素算法理解
如果要移除的元素恰好在数组的开头,例如序列 [1,2,3,4,5],当 val 为 1 时,我们需要把每一个元素都左移一位。实际上我们可以直接将最后一个元素 5 移动到序列开头,取代元素 1,得到序列 [5,2,3,4],同样满足题目要求。时间复杂度:O(n),其中 n 为序列的长度。时间复杂度:O(n),其中 n 为序列的长度。数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。空间复杂度:O(1)。空间复杂度:O(1)。快指针:寻找新数组的元素(不包含目标值元素的数组)
2024-12-11 07:54:22
167
原创 二分查找算法理解
while(left <= right) 中的符号必须是 <= 因为在这个区间里,left == right是有意义的if(nums[middle] > target) 那么重新定义左区间时 右边界 right = middle -1 ,因为当前这个nums[middle]一定不是target那么接下来要查找的左边界结束下标位置就是middle-1return mid;初始赋值 right = nums.length;
2024-12-11 06:16:28
504
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人