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

原创 线程池详解(建议收藏)
线程池(Thread Pool)是一种基于池化技术的多线程处理形式,用于管理线程的创建和生命周期,以及提供一个用于并行执行任务的线程队列。线程池的主要目的是减少在创建和销毁线程时所花费的开销和资源,提高程序性能,同时也提供了对并发执行任务的更好管理,例如控制线程数量。
2024-08-24 17:39:43
9833

原创 ThreadLocal原理和用法(超全面建议收藏)
一、基本概念1、底层结构:有点像HashMap,可以保存kv键值对,它实质是通过在k位置关联当前线程的,并在v的位置为当前线程绑定一套副本,ThreadLocal内部只能保存一个kv的键值对,且内部不提供遍历和查询方法,不同的线程意味着不同的空间,所以每个线程只能获取自己的副本2 用法:②set是为当前线程设置副本③get则是获取当前线程的副本④remove()用来移除当前线程中变量的副本3 作用:①保证线程安全②为每个线程管理一个副本③实现线程在上下文传递参数public class
2021-03-28 11:27:58
1678
1
原创 CompletableFuture(图解 + 实战业务场景 + 源码深度解读,建议收藏)
如果线程ForkJoinPool.commonPool-worker-3执行taskA方法较慢,等到执行thenApply方法的时候taskA依然没有执行完,此时CompleteFuture的result为null,那么当ForkJoinPool.commonPool-worker-3执行完毕taskA时,会在后面的回调方法中执行taskB,所以两方法的执行线程都是一致的。
2025-05-14 15:47:03
689
原创 mybatis中${}和#{}的区别
/控制台sql执行日志对比一下,如果是把${field}替换成#{filed}再玩个更有趣的,如果我们某个sql查询字段需要通过入参确定,如下</我们的入参为name,测试结果如下也就是说这个sql变成了我们把#{field}替换成${filed}再看一下</如下,恢复正常了。
2025-05-13 17:42:40
812
原创 mysql锁
在这个隔离级别下,可能出现一个问题,即使一行数据正在被一个事务修改,其他事务仍然可以读取这行数据的原始值,缓存双删策略适用于对实时性要求比较高的缓存数据,先删除缓存,然后修改数据,假如修改数据过程耗时比较久,这时候有一个查询请求,缓存中没有这条数据,所以要去mysql中取数据,但此时这条数据正在修改中,在mysql默认隔离级别下,读出来的依然是修改前的数据,所以这种情况下。mysql默认可重复读的隔离级别下,对于被行锁保护的数据行,其他事务的读操作是可以进行的,这种行为被称为“
2025-05-06 11:42:05
615
原创 开发规范 - 空指针异常等低级问题注意点
对任何对象(从request(前端、aop)中,从缓存/数据库中拿)拿出来时、做读写getter/setter处理操作的时候,都把它当成空的对待,先做非空判断和空值处理不要把null作为方法参数,至少传入一个空对象,一个方法被调用十几次(复用性角度),其中只有一个参数为null,极易出现空指针异常。
2025-05-06 11:40:36
888
1
原创 jvm内存结构
本节主要讲的是运行时数据区,也就是下图这部分,它是在类加载完成后的阶段当我们通过前面的:类的加载-> 验证 -> 准备 -> 解析 -> 初始化 这几个阶段完成后,就会用到执行引擎对我们的类进行使用,同时执行引擎将会涉及到到我们运行时数据区更形象的举例子运行时数据区显然就是那一堆存放食材的加载,厨师就是执行引擎,做完饭后还需要打扫卫生(GC)内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行JVM内存布局规定了Java在运行过程
2025-02-04 15:31:09
670
原创 类加载器详解
Java还允许开发者自定义类加载器,只需要继承java.lang.ClassLoader类,然后覆盖findClass()方法即可。自定义类加载器可以支持一些特殊需求,如网络类加载器,加密类加载器等。
2025-02-03 18:26:05
386
原创 2025大纲
参考sql如下,说一下六种加索引的方法(无索引,只对name加索引,只对city加索引,对name和city加索引,对name,city以及select的字段加索引,对city和name字段加索引)重载(方法名同,参数个数,不同类型参数顺序不同、返回值类型权限无关)与重写(2同2小1大,说明底层原因,结合模板方法模式、jvm角度分析),向上转型与向下转型,重载的典型案例如下。缺字段导致索引失效、范围查询导致索引失效的原理是什么?从堆内存的角度分析下,对象创建的流程,如果是创建一个比总内存还大的大对象呢?
2024-12-03 10:31:25
880
原创 IDEA中maven更新pom文件后使其生效(自动 + 手动)
以上是正常情况,但大家或多或少都会遇到过idea抽风的场景,这基本都是因为你笔记本配置不够,或者长时间未重启导致运行卡顿了,这种情况下可以先重启,如果还不行,那就用最后的杀招Invalitate cache …如果懒得每次手动Reload,那么可以在这个地方选择Any change,即任何对pom文件的修改都会哦。pom文件更新后默认是不生效的,需要手动刷新maven,即点击Reload Project,,这样的话刷新会很慢,因为会对整个项目Reload Project。
2024-11-08 08:44:04
1496
1
原创 开发规范 - mac系统1小时装机极速装机开发环境
jdk不用单配配置,在idea中,选择一个语言环境(jdk8/jdk11/jdk17…),然后默认下载jdk这样,一个hello word就能跑起来了。
2024-10-14 16:25:26
544
原创 依赖传递与依赖冲突(附解决方法)
Maven 在对项目进行编译、测试和运行时,会分别使用三套不同的 classpath。Maven 项目构建时,在不同阶段引入到 classpath 中的依赖时不同的我们使用idea跑项目当中src/main/java目录下的代码实际上就是运行的当前项目target/classes目录下的字节码文件。我们使用idea跑项目当中src/test/java目录下的代码实际上就是运行的当前项目target/test-classes目录下的字节码文件。
2024-10-11 14:30:32
508
原创 缓存穿透,缓存击穿,缓存雪崩(原理 + 标准代码)
key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。
2024-09-10 09:29:55
438
原创 Callable详解
Callable类似于Runnable,如果你的某个实例的方法想要被线程执行,也可以通过实现Callable接口的call方法。
2024-08-26 16:40:37
277
原创 Runnable
如果你的某个实例的方法想要被线程执行,那么可以通过实现Runnable接口,重写Runnable的run方法,这个方法是个无入参无返回值的方法,然后将你这个实例作为Thread的构造器参数去执行。
2024-08-25 12:25:06
314
原创 java对象创建的过程
这包括初始化声明的字段和执行构造方法中的所有语句。在此过程中,可能会调用父类的构造方法,以确保整个继承层次结构中的每个类都得到正确的初始化。在内存中分配对象所需的内存空间。具体的内存分配方式有很多种,包括堆上的对象分配、栈上的对象分配等,在主流的Java虚拟机中,大部分对象的内存分配发生在堆上。内存分配后,JVM将分配给对象的内存空间初始化为零值。创建对象的过程,属于类的主动使用,在加载、连接类完毕后,还会触发类的初始化过程。JVM设置对象头信息,包括类的元数据信息、对象的哈希码、对象的GC分代年龄等。
2024-08-21 17:36:39
488
原创 类加载的过程与触发时机
所谓加载,简而言之就是将 Java 类的字节码文件加载到机器内存中,(一个Java文件从编码完成到最终执行,一般主要包括两个过程:编译和运行,其中编译就是把我们写好的java文件,通过javac命令编译成字节码,也就是我们常说的.class文件,编译过程中会对java代码做语法层面校验,有问题的话会编译失败并抛出编译期错误,然后运行则是把编译声称的.class文件交给Java虚拟机(JVM)执行。
2024-08-21 15:37:45
1307
原创 CAS原理
不是线程安全的。i++实际上是一个复合操作,包括三个步骤:读取i的值,对i加1,将新值写回内存。如果多个线程同时执行这个操作,就可能导致线程安全问题。例如,两个线程同时读取了i的值,然后各自增加1,然后将新值写回内存,这样实际上i只增加了1,而不是2,这就是所谓的线程冲突。为了保证线程安全,可以使用同步机制(如互斥锁)来保护i++操作。
2024-08-19 08:23:13
255
原创 mysql表设计
status 状态 java代码中用一个枚举类,比如我的请假表还处于草稿状态,可以是新建态,提交后处于待审批状态,审批完成则是成功态,审批拒绝就是拒绝态。start_time 开始时间 dateTime类型。end_time 起始时间 dateTime类型。employee_id 外键,和员工信息表想管理。type 请假类型,对应一个枚举类,病假,事假。create_time 请假记录的创建时间。如果让你设计一个请假表,如何设计?approve_id 外键。
2024-07-23 16:32:02
243
原创 git区域与对象
2 git write -tree是生成暂存区的对象tree同时提交到版本库中(存储到objects下),我们可以不断的向暂存区进行增删改直到自己满意再进行提交,git对象代表文件的一次次版本,tree对象代表项目的一次次版本,这就是暂存区的作用,因为objects本来就有一个关于test.txt的git对象,后来又接收了一个从缓存区提交上来的test.txt的tree对象,所以有两个对象类型;②将本地文件的内容做快照并保存到Git 的对象库,实际上就是一个包含文件索引的目录树,像是一个虚拟的工作区。
2024-03-13 14:17:13
1143
原创 redis中setnx命令的底层原理是什么
该命令的含义是set if not exists,Redis是单线程的,所有的命令都是串行执行的。而且Redis的SETNX操作是原子的,即使有大量的线程同时发送SETNX命令,Redis也会一个接一个地执行这些命令。锁的超时问题,setnx用作锁的时候,必须要设置一个过期时间,防止这个锁无法及时释放造成死锁,且要注意setnx和expired必须是原子性的,如果不能保证原子性,那可能由于线程调度问题expired没有生效,依然会有死锁风险,过期时间设置也要结合实际线上情况,太短会出现问题。
2024-03-13 14:03:43
1392
原创 过滤器中捕获报错 Broken pipe
因为接口执行时间过长,已经超过三十秒,所以服务器段和客户浏览器端的连接因为超时的原因就断开了,而且我还特意去找前端同事去确认了下,发现确实是和浏览器有关,也就是接口请求超过一定时间,浏览器会主动关闭这个连接,不同的浏览器的连接最大保持时间不同,常见的谷歌浏览器应该是可以保持30秒,所以接口将数据返回给前端的时候,会在服务器tomcat/undertow进行网络通信将返回值响应回前端时层抛出Broken pipe异常,而后被过滤器层捕获并打印报错。这个错误通常出现在网络通信中,这个错误的常见原因有。
2023-12-02 08:53:01
1192
原创 java: 警告: 源发行版 17 需要目标发行版 17
这个大家很熟悉,是maven项目中指定jdk编译版本的,现在主流框架用的都是springboot,也就是说我们自己的项目maven的父依赖都是这个,点进去查看spring-boot-starter-parent的pom文件。因为我此时设置的jdk版本是1.8,但我在pom文件中指定的maven编译版本java.version是17,不一致,所以报的这个错,解决方案就是在idea中选择jdk17版本。本地jdk开发环境,可以在idea中的project structrue中设置jdk的开发版本。
2023-12-02 07:58:09
1136
原创 Spring注册bean的方式
解决:ImportSelector,springboot的自动装配能力就是基于此,通过扫描spring.factories自动装配文件,该文件下全是常用的配置类,通过扫描这些配置类,引入这些组件实现自动装配,同时通过@Condition等一系列条件注解实现按条件装配。痛点:如果一个项目需要引入几十个或几百个配置类,配置依然会很麻烦,且直接Import容易引入大量无关的类。痛点,可以引入第三方jar包中的组件,但如果第三方中有几十几百个个要用的组件呢,手动配置会很麻烦。下有五种,痛点与解决。
2023-11-29 11:18:29
1233
原创 ClassNotFoundException与NoClassDefFoundError
查资料发现是springcloud的依赖版本和springboot的依赖版本不兼容,顺藤摸瓜找到springcloud jar包中调用org.springframework.boot.context.properties.ConfigurationPropertiesBean的位置上,发现果然,当前项目中所引入的springbootboot jar包版本并没有这个类。所以明显是当前springboot版本不适配springcloud,调整版本即解决报错。
2023-10-01 12:58:24
426
原创 An attempt was made to call the method xxx.jedis but it does not exist
在公司项目中做配置迁移的时候,服务启动时报错报错信息这种问题一看就是maven引入第三方依赖相关问题,该问题导致这个springboot服务启动报错,其实这种报错还是看上去比较舒服的,这个报错提示是非常到位,咱们试着理解下这个报错提示。
2023-10-01 12:18:06
661
原创 Postman返回了一个html页面
调用公司的测试环境接口,从浏览器控制台接口处cCopy as cURL(cmd),获取完整的请求内容,然后导入postman发起请求。2、问题定位到Postman,验证方法时把完整请求体给同事,同事的电脑是可以跑通的,于是把问题确实是Postman抽风导致的…1、请求体的HEADER中的标识浏览器信息的相关字段,于是把浏览器升级到最新,再从中Copy as URL,还是同样的报错。postman可能在转义请求内容时可能出了问题,导致公司网关处理时请求体时不适配,换一个api工具即恢复正常。
2023-08-20 11:19:12
7320
3
原创 There is no getter for property named ‘xxx‘ in ‘class java.lang.String
后续的版本,应该是mybatis 3.5或3.6以上的版本中,不必再强制对mapper接口入参加@Param注解了,但个人觉得最好还是加上,这样代码更规范一些。我这里用的mybatis-spring-boot-starter的2.1.3版本,那么这个依赖中包含的3.4.6的mybatis依赖。而这一版本中,mapper层中的接口入参,必须要遵守规范,通过@Param注解对入参做一个标识,如下。如果没有@Param注解,就会报该错误。检查mybatis相关依赖。
2023-06-03 21:44:50
205
原创 class path resource [db.properties] cannot be opened because it does not exist
但还要注意,resources中的文件可能不会一起被生成到target,我们可以手动复制到target,这样就不会影响本地开发了,resource下的文件,是直接存放到target文件夹下的。也就是默认情况下会顺手输出到默认的SpringWang的out文件夹下,推荐这里修改下,使其输出到各个子maven的target文件夹下面,如下。首先看你项目中编译后的项目生成的位置,这个默认情况下会输出到公共文件夹SpringWang的out文件下,如下。然后再看各个子项目的默认的字节码文件输出地址。
2023-04-22 13:33:54
1205
原创 找不到org.apache.commons.pool.impl.GenericObjectPool.Config的解决方法
经测试commons-pool1.5x版本会报这个问题,但点开commons-pool1.5x版本依赖包也是能看到这个类的,类中确实包含内部类Config。有点超出我的理解,解决方案是使用1.6或更高级的commons-pool版本。后续等我搞明白后会再次更新。
2023-04-11 10:49:06
748
原创 mysql索引与sql优化面试题(建议收藏)
备注:一开始粗心了,有效接待字段搞错了,导致数据对不上(把sessionHumanValidRecep和sessionHumanSelfValidRecep搞混了),追代码中字段sessionHumanValidRecep,,看看有没有字段或者后续的查询,弄了半天发现是字段选错了...
2023-03-26 22:35:39
1020
1
原创 一百字讲明白instanceOf关键字
instanceof 是 Java 的保留关键字,它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型,需要注意的是,该关键字用的是它左边对象的实际类型去判断的,而不是用的它的引用类型,例如对象obj的引用类型是A,但它的实际类型是D。
2023-03-15 08:58:59
134
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人