- 博客(48)
- 收藏
- 关注
原创 事务失效的场景
Spring事务管理是通过代理机制实现的,而它依赖于捕获到特定的异常来回滚事务。如果你在代码中提前捕获并“消化”了异常,代理就无法感知到异常的发生,从而无法触发回滚机制。如何正确处理异常而不让事务失效?要么在事务方法内不捕获异常,要么捕获后处理完业务再手动抛出异常。
2025-09-25 21:50:24
289
原创 索引失效的情况以及原因
LIKE ‘%abc’ 或 LIKE ‘%abc%’ 这种查询,因为不知道开头是什么,无法从索引树的根节点开始进行高效的范围匹配,只能遍历索引中的所有条目(相当于全索引扫描),很多时候优化器会认为这不如直接全表扫描。当你对索引列使用函数或进行计算时,数据库需要先对表中每一行的该列值都应用这个函数或计算,然后再与条件值比较。如果你的查询条件没有从最左边的列开始,或者跳过了中间的列,索引就无法被有效使用。当查询条件中索引列的数据类型与传入值的数据类型不匹配时,数据库会进行隐式类型转换。
2025-09-25 20:13:03
181
原创 Redisson和Zookeeper实现的分布式锁
可以使用红锁来解决不一致问题,建立多个主节点当获取锁成功的数量n/2+1及以上才算获取锁成功。我觉得就是一个排队,创建节点后看自己是不是最小,不是最小就监听前一个节点,是最小就获取锁成功,锁释放以后,zookeeper会通过Watcher通知当前客户端。客户端获取 /locks/my_lock 目录下所有的子节点,并按节点序号排序。客户端被唤醒后,回到第 2 步,重新检查自己是否变成了最小节点。如果自己不是最小节点,客户端就找到比自己序号小的前一个节点。如果自己创建的节点是序号最小的那个,则成功获取锁。
2025-09-25 16:06:08
321
原创 Redis持久化
AOF全称为Append Only file(追加文件),redis处理的每一个写命令都会记录在AOF文件。在此过程中是有可能发生读写操作的,读操作可以访问共享内存而写操作会拷贝一份数据进行写操作。RDB全称Redis Database Backup file又称Redis数据快照。RDB持久化流程就是由主进程fork出一个子进程由子进程将数据写入RDB文件。两种方式:RDB AOF。
2025-09-25 15:26:43
130
原创 多态、抽象类、接口的概念
父类抽象类定义一个final方法避免模板方法被重写,然后另外定义一个抽象方法由子类去实现具体细节,公共部分由模板方法提供。多态下不能调子类独有的功能因为编译看左边,左边是对象的引用,是父类,而父类中是不存在子类独有的方法的所以不能编译通过。只要有继承或者实现关系的两个类就可以强制类型转换,编译时不会报错,但是运行时可能会存在强制类型转换异常。多态下父类类型作为方法的形参,可以接收一切子类对象方法更便利。final关键字可以修饰(类、方法、变量)是最终的意思。类是单继承的但接口是多继承的。
2025-09-24 15:36:35
270
原创 如何通过构造函数注入一个bean
首先,确保被注入的类本身是一个 Spring Bean(通常使用 @Component 或其派生注解,如 @Service, @Repository)。将一个 Bean(依赖)通过目标 Bean 的构造函数的参数传入,Spring IoC 容器在创建目标 Bean 时会自动寻找这些参数并注入。如果一个类有多个构造函数,需要用 @Autowired 明确指定 Spring 应该使用哪一个来进行依赖注入。在目标 Bean 中创建构造函数,在需要依赖的类中,创建一个以依赖项为参数的构造函数。
2025-09-20 17:47:21
380
原创 抽象类和接口的区别
抽象类描述的是是什么,一个子类只能继承一个抽象类,这表示了子类是什么,接口描述的是能做什么,一个子类可以实现多个接口,比如说一个子类是汽车,那么他需要去继承车这个抽象类,车这个抽象类只定义了一辆车需要有轮子,有发动机,但没有完整的定义这是什么车,而接口定义了车有什么能力,比如一个跑的接口,汽车能跑,人也能跑,于是大家都可以实现这个接口,表示自己拥有这个能力。,因为类是 abstract 的,会报错。这里注意:子类不仅可以重写抽象类中的抽象方法(这是必须的),也完全可以重写抽象类中已经实现了的具体方法。
2025-09-15 13:30:41
194
原创 多线程相关面试题1
定义了共享内存中多线程程序读写操作行为规范,JMM把内存模型分为两块一块是线程独有的的工作内存一块是线程共享的主内存。线程和线程交互需要通过主线程。sleep如果在synchronized中使用不会释放对象锁(我放弃cpu你们也不能用)wait方法执行后会释放对象锁,允许其他线程获得该对象锁(我放弃cpu你们还可以用)wait必须和synchronized配合使用,必须先获取wait对象的锁。notify只随机唤醒一个wait的线程。notifyall唤醒所有wait的线程。wait和sleep的区别。
2025-09-14 01:47:42
155
原创 Mysql相关的面试题1
聚集索引就是叶子节点关联行数据的索引,二级索引就是叶子节点关联主键的索引,聚集索引必须有且仅有一个,二级索引可以有多个。覆盖索引查询使用了索引并且需要返回的列在该索引中全部能够找到。什么是聚集索引(聚簇索引)?什么是二级索引(非聚簇索引)?聚集索引选取规则是先主键再唯一最后可以自动生成一个隐藏的。读未提交 读已提交 可重复读 串行化。acid是什么,事务的特性是什么?在索引列上做计算操作索引会失效。范围查询右边的列不能使用索引。字符串不加单引号导致索引失效。脏读 不可重复读 幻读。
2025-09-13 21:12:29
241
原创 Redis面试相关
全量同步:主节点通过replicationid判断是不是第一次同步,如果是第一次同步需要进行一次bgsave生成rdb文件进行同步,然后把生成的rdb文件传输给从节点,rdb期间执行的命令会记录在日志文件中。redis是纯内存操作性能瓶颈是网络延迟而不是执行速度,I/O多路复用模型就实现了高效的网络请求。slow模式是定时任务,频率是10HZ,执行时间不超过25ms,可以通过配置文件调整频率。当用到那个key的时候再检查是否过期,过期则删除,有效则返回key。redis是纯内存操作,执行速度非常快。
2025-09-12 20:52:40
154
原创 ArrayList和LinkedList底层原理
ArrayList底层是一个动态的数组也就是可以自动扩容的数组,在初始化一个ArrayList的时候,是没有容量的,在第一次添加数据之后才会初始化容量为一个默认值10,当容量不够的时候,数组将会通过一个grow函数实现扩容,扩容到原来的1.5倍。这种情况会由构造函数构造一个指定容量的数组不需要扩容。ArrayList和LinkedList的区别是什么。LinkedList底层是用链表实现的。二者都线程不安全,可以按如下方法解决。如何实现数组和List之间的转换。这实质上使用了装饰器模式。
2025-09-11 20:36:49
113
原创 JVM第一部分
LineNumberTable:是一个映射表,它将上述的偏移量“翻译”成我们程序员能看懂的源代码行号。PC寄存器:存储的是数字 0, 3, 6, 10, 17 这样的字节码偏移量。1.7的堆中有一个区域是永久代,用来存放类信息,静态变量,常量,编译后的代码。栈主要是用来存放局部变量和方法调用,堆主要是用来存储java对象和数组的。1.8移除了永久代,把数据存储到本地内存的元空间中,防止内存溢出。未必,栈内存大了会导致能活动的线程数变少。不涉及,垃圾回收主要是用来回收堆内存。栈是线程私有的,堆是线程共有的。
2025-09-11 15:31:53
210
原创 Spring-Aop相关面试题
其本质是通过AOP,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。AOP(Aspect-Oriented Programming,面向切面编程) 是一种编程范式,旨在将散布在应用程序多个部件中的横切关注点(cross-cutting concerns) 从业务逻辑中分离出来,从而实现更高水平的模块化。AOP 就是在不修改锅和灶具(业务代码)的情况下,优雅地把油烟机装上去。
2025-09-10 18:17:06
107
原创 spring-单例bean是线程安全的吗
不是线程安全的,一般来说,我们在bean中注入的对象都是无状态的,他们是线程安全的,但是如果我们定义了可修改的成员变量,那么此时这些成员变量将是线程不安全的。其中可修改的成员变量有线程不安全问题,不可修改的无状态的 userService是没有线程安全问题的。spring框架中有一个 @Scope注解,默认的值就是singleton,单例的。
2025-09-10 17:32:57
176
原创 ArrayList和LinkedList的区别
ArrayList底层使用数组实现。LinkedList底层使用链表实现,这意味着他们增删查改的效率不同,数组实现就适合随机访问,链表实现插入和删除的效率比较高。另外,LinkedList额外实现了Deque接口,因此它可以作为队列使用。
2025-09-10 15:02:13
329
原创 List和Set的区别
List有序可重复 Set无序不可重复 Null在其中也是一样,List可重复所以可以存多个Null,Set则不可以,另外要注意,List可以支持随机访问,但是Set只支持迭代器访问。
2025-09-10 14:47:01
227
原创 ==和equals的区别
= 如果是基本数据类型比较的是值,如果是引用数据类型比较的是引用地址。equals 看重写之后的比较逻辑,默认是比较内存地址。
2025-09-10 14:42:14
94
原创 hashcode与equals之间的关系
即使发生极小概率的事件,user1 和 user2 的默认 hashCode 计算后落在了同一个桶里,HashMap 接下来会调用 equals 方法来比较桶中已有的键 (user1) 和当前给定的键 (user2) 是否“相等”。user1 == user2 的结果是 false(它们是两个不同的对象),所以 HashMap 仍然会认为 user2 不是我们要找的键,最终返回 null。user1 和 user2 是两个不同的对象,位于不同的内存地址,因此它们的 hashCode 值极大概率是不同的。
2025-09-10 13:43:23
275
原创 java中泛型的原理
编译器认为 parent.set(“World”) 调用的是 Parent.set(String)(因为编译器知道 Parent),但在运行时,JVM 看到的只有 Parent.set(Object)。如果没有桥接方法,JVM 会去调用父类的 set(Object),而不是子类的 set(String),这就错了!从 JVM 的角度看,Child 类中的 set(String value) 方法并不是对父类 set(Object value) 方法的重写!这是一种“编译期”的机制,而不是“运行期”的机制。
2025-09-09 18:14:38
937
原创 Mysql复习5
一对一的关系常用于单表拆分,基础信息和详细信息分开,在任意一方加入外键关联另一方的主键,并且设置外键为唯一,这里设置唯一约束就是为了避免出现一对多的情况,比如在详细信息那边添加了外键,这时候如果两条数据都关联同一个userid就会导致出现一条用户基础信息对应两条详细信息,设置唯一约束则不会出现这种情况。多对多的关系需要加一张中间表转化,中间表至少包含两个外键分别关联双方主键。我觉得子查询最难觉得单开一个笔记好好学学。多表关系有三种,一对一,一对多和多对多。一对多的关系需要在多的一方建立外键。
2025-08-01 01:42:19
126
原创 Mysql复习4
先确定从哪个表查然后按条件筛选出符合条件的数据,然后把这些数据分组后拿到,拿到后可以排序最后分页。SQL是可以多字段排序的,asc可以省略,desc不能省略。常用聚合函数有count avg max sum。DQL:SQL语句中最重要的一部分。注意所有聚合函数不计算null值。
2025-07-30 23:35:11
215
原创 Mysql复习2
我觉得反正正常数据库里的表的每个字段在java中都会对应实体类的一个成员变量,成员变量就是比如private Integer age这种用sql定义就得变成age int comment '年龄’他是反过来的,我直接把数据库创建表和java创建类当作轴对称操作。然后还得注意就是java中是public class a{}而数据库是create table a()一个大括号一个是小括号,数据库是为java服务的,把他当成小弟就行了。这些就是DDL语句个人觉得没什么用,背这些有点浪费脑容量的感觉。
2025-07-30 17:35:50
158
原创 Mysql复习1
目前的状态就是,把java体系全学了一遍最后发现真正踏踏实实会用的没有多少,所以打算沉下心来琢磨每一门技术,就从SQL开始吧。其实我也在想未来有没有一种可能就是我们会看,会判断就可以,这些需要太多精力背诵的东西交给AI就好了,比如说虽然现在我记住的东西不多,但是我知道做什么需要用什么技术,知道大概的流程,让AI给我写出来大概的代码,我也会用,但总怕人家面试官问具体的东西。之前一直分不太清这几种语句,这次复习准备记住这几个单词全程,要不总以为DDL的D是删除,DML的是Management。
2025-07-30 16:39:07
124
原创 黑马点评优惠券秒杀感悟1
解决这个问题需要使用悲观锁,使得每次只能有一个线程去查询订单,但是在tocat集群的情况下,加的互斥锁会失效,所以这里引出分布式锁,分布式锁常用的解决方案是msql,redis和zookeeper,redis的实现方案就是利用一个setnx指令的特性来实现,如果不存在这个key才会创建成功否则失败,为了防止系统宕机所以用过期时间兜底,所以多个线程都想要创建这个key的时候,只有一个key能创建成功,这个创建成功的线程去执行下边的业务。那么怎么解决这个问题呢?这样就可以解决超卖问题。
2025-07-27 20:11:43
837
原创 黑马点评商户查询缓存感悟
然后当查询来的时候,将查询的元素同样用这k个哈希函数做映射,看映射的结果对应数组中的位置是不是全都为一,全都为一的话则这个元素可能存在数据库,为什么是可能呢,因为最开始将数据库元素做映射的时候,一个位置不一定只有一个元素将其设置为一,也就是说有的值为1的位置可能是由别的元素设置的。缓存null对象的原理就是说查询来的时候可能缓存和数据库都未命中,在数据库未命中之后,我们把查询的元素对应的value设置为null并缓存到数据库中,那么下次查询这个元素的时候缓存就能命中,这样就解决了缓存穿透的问题。
2025-07-25 20:55:08
374
原创 黑马点评短信登录感悟
黑马点评中的这种实现方式直接导致了,在这个拦截器中使用redis的时候不能通过@Autowired直接注入redisTemplate而是需要用一个构造函数去得到这个对象,所以需要在这个拦截器中定义一个构造函数参数是redisTemplate,然后在new的时候传入redisTemplate,对了用构造函数得到redis的话,还需要在拦截器中加入一个redisTemplate的成员变量。Session 存储在服务端(如 Redis),所有请求共享同一份数据,但每个请求的线程是独立的。
2025-07-24 16:52:46
172
原创 JS:webapis1
Dom是浏览器提供的一套专门用来操作网页内容的功能,体现标签与标签之间的关系。button的 disabled 属性可以设置button可不可以被点击。通过t.type修改input类型,通过t.value修改值。对于引用类型,const arr指向的是地址而不是数据本身。得到的对象可以通过下标访问,也可以通过for循环打印。通过t.checked = true 设置复选框状态。如果选中则返回的是对象,未选中返回的是null。Dom是文档对象模型,Bom是浏览器对象模型。通过dataset访问。
2025-07-17 15:47:33
198
原创 常用注解复习2
通过Spring提供的 @RequestParam 注解,将请求参数绑定给方法形参。基于Mybatis中提供的动态SQL标签 将SQL语句改造为动态的。@RequestBody用于获取json数据。@PathVariable 用于获取路径参数。
2025-07-15 22:13:15
121
原创 mybatis复习
默认情况下,在Mybatis中,SQL语句执行时,我们并看不到SQL语句的执行日志。XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。实体类属性名和数据库表查询返回的字段名一致,mybatis会自动封装。XML映射文件的namespace属性为Mapper接口全限定名。如果实体类属性名和数据库表查询返回的字段名不一致,不能自动封装。xml映射文件中的dtd约束,直接从mybatis官网复制即可。在pom.xml文件中引入依赖,在配置中引入。
2025-07-15 21:55:15
158
原创 常用注解复习
该注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解@SpringBootApplication 中,默认扫描的范围是启动类所在包及其子包。在@Qualifier的value属性中,指定注入的bean的名称。@Qualifier注。声明bean的时候,可以通过注解的value属性指定bean的名字,如果没有指定,默认为类名。@Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解。当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认的实现。
2025-07-15 19:28:21
157
原创 宏任务与微任务
首先执行同步任务,然后执行微任务队列所有任务,执行完微任务队列,检查宏任务,执行一个宏任务后,执行微任务队列所有任务,再然后检查宏任务,执行微任务队列所有任务。new Promise里面的function会立刻执行所以执行顺序为,执行第一个timeout输出2,3,然后执行微任务输出4。执行第二个timeout输出7,8,然后执行微任务输出9。故正确输出顺序为156234789。1,5 然后执行微任务队列6,
2025-04-24 19:13:10
298
原创 async/await
在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行。readFile正常返回一个Promise对象,加了await后直接读取文件内容。用来简化Promise异步操作,不需要.then()async和await必须同时使用。
2025-04-24 18:32:00
217
原创 Promise解决回调地狱
如果上一个.then()方法中返回了一个新的Promise实例对象,则可以通过下一个.then()继续进行处理。通过.then()方法的链式调用,就解决了回调地狱的问题。前面遇到错误,程序会直接执行catch,若不希望前面的错误导致后续的.then无法正常执行,则可以将.catch的调用提前。Promise是一个构造函数,new出来的实例对象代表一个异步操作。如果链式操作中发生了错误 ,可以使用.catch方法进行捕获和处理。Promise.prototype上包含一个.then方法。
2025-04-24 16:08:26
420
原创 ES6模块化
然后npm init -y初始化一个package.json文件。s2 as str2 在按需导入过程中可以使用as来重命名。接下来加入一项““type”:“module”如果单纯想执行某个模块中的代码,可以直接导入。首先保证node版本>14。最后可以新建js文件去测试。
2025-04-24 14:57:58
208
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅