- 博客(63)
- 资源 (1)
- 收藏
- 关注
原创 解决 attempt to unlock lock, not locked by current thread by node id redisson异常
3.多线程竞争的问题,当第一个线程完成lock,此时并未 unlock,第二个线程未获取到锁,但执行finally,第二线程尝试着去释放第一个线程的锁。就是问题的翻译如下:尝试去释放不是当前线程持有的锁。2.多线程竞争的问题,当第一个线程完成lock,此时并未 unlock,如此,第二个线程尝试获取锁,并进行lock操作,会抛出该异常。1.当你在完成lock后,里面的业务代码执行时间大于lock时间时,进行unlock,会抛出该异常。为什么会这样,由于在进行lock操作时,会设置一个时间默认30s,
2024-10-29 15:49:37 225
原创 实体与DTO如何转换
它是一个代码生成器,它基于约定优于配置的方法,极大地简化了 Java Bean 类型之间的映射实现。生成的映射代码使用简单的方法调用,因此执行速度快、类型安全且易于理解。另一方面,它是一个运行时库,用于实例化和调用生成的映射器。它采用基于约定的方法,同时提供简单、重构安全的应用程序接口(API)来处理特定用例。这里添加了Order到OrderDto转换的映射,将Order中的orderAmount映射到OrderDto中的money。在Spring环境下,建议配置如下的Bean以方便我们进行转换。
2024-10-22 10:24:34 372
原创 synchronized为什么会有两个monitor exit
于是线程就会释放锁。因为文章开头已经说过,这是由于Java在多个线程同时访问同一个对象的成员变量的时候,每个线程都拥有了这个对象变量的拷贝。代码如果遇到了这个标识,就表示获取到了对象的监视器monitor(monitor对象是由C++实现的),这个获取的过程是排他的,也就是同一时刻只能有一个线程获取到由synchronized所保护对象的监视器。在多线程之间,共享变量的值是线程不安全的,因为线程在开始运行之后都会拥有自己的工作空间,而从自己工作空间把修改的值刷新回主存的时候需要CPU的调度。
2024-09-05 13:45:43 390
原创 天书般的Tree工具类
3.1 JAVA中树形对象的定义在JAVA中树形结构是通过对象嵌套方式来定义的,如MenuVo对象中有一个子对象subMenus:3.2 JSON数据格式中的树形结构JSON数据天然就是树形结果,如以下展示一个简单的JSON树形结构: TreeUtil代码分析直接看这神一样的方法makeTree():是不是完全看不懂?像看天书一样?makeTree方法为了通用使用了泛型+函数式编程+递归,正常人一眼根本看不这是在干什么的,我们先不用管这个makeTree合成树的代码原理,先直接
2024-08-15 14:39:11 841
原创 线程池常见问题
9)MemorySafeLinkedBlockingQueue:而且 LinkedBlockingQueue 默认是使用 Integer.MAX_VALUE 作为容量的,也就是个无界队列,可能会有发生 OOM 的风险,所以自己实现了一个内存安全的 MemorySafeLinkedBlockingQueue,可以配置最大剩余内存,当内存达到该值的时候,再往队列放任务就会失败,很好的保证了不会发生令人头疼的 OOM 问题。这公式太偏理论化了,很难实际落地下来,首先很难获取准确的等待时间和计算时间。
2024-08-12 13:53:52 721
原创 @PathVariable使用
通常请求的路径变量是在Controller层被捕获并处理的。如果你希望在Service层或其他非Controller组件中获取这些路径变量,而不是通过参数传递的方式,你则可以通过如下的方式。为使映射正确工作,捕获 URI 变量 {id} 的名称必须与 @PathVariable 成员参数 String id 相同。默认情况下@PathVariable路径变量是必须,否则服务端将。在类和方法级别访问URI 变量。注解来访问捕获的 URI 变量。下面的示例展示了如何使用。
2024-08-12 11:23:27 157
原创 读取jar文件方式
为了更好的模拟我们实际生产中的环境,我们直接通过Controller层来对jar中的文件进行访问。,这在某些场景下非常有用。Spring框架提供了。
2024-08-12 10:40:27 297
原创 微服务下保证事务的一致性
定义:在单体应用中,我们执行多个业务操作使用的是同一个连接,操作同一个数据库,操作不同表,一旦有异常我们可以整体回滚。其实在介绍事务的定义中,也介绍了一部分本地事务。本地事务通过ACID保证数据的强一致性,在我们实际开发过程中,我们或多或少都使用了本地事务。例如,MySQL事务处理使用begin开始事务、rollback回滚事务、commit确认事务。事务提交后,通过redo log记录变更,通过undo log 在失败时进行回滚,保证事务原子性。
2024-08-02 16:23:06 875
原创 TCP连接中客户端的端口号是如何确定的?
事实上很多我们平时遇到的问题都和这个端口选择过程相关,如果能深度理解这个过程,将有助于我们对这些问题的深刻理解。Cannot assign requested address 报错是怎么回事?一个客户端端口可以同时用在两条 TCP 连接上吗?还是让我们借助一段简单到只有两句的代码,从这个来讲起!
2024-07-30 13:55:41 1130
原创 深度解析单线程的 Redis 如何做到每秒数万 QPS 的超高处理能力
Redis 服务器端只需要单线程可以达到非常高的处理能力,每秒可以达到数万 QPS 的高处理能力。如此高性能的程序其实就是对 Linux 提供的多路复用机制 epoll 的一个较为完美的运用而已。在 Redis 源码中,核心逻辑其实就是两个,一个是 initServer 启动服务,另外一个就是 aeMain 事件循环。把这两个函数弄懂了,Redis 就吃透一大半了。......// 启动初始化// 运行事件处理循环,一直到服务器关闭为止。
2024-07-30 13:52:24 658
原创 Nacos配置中心交互模型是 push 还是 pull
Nacos在做配置中心的时候,配置数据的交互模式是服务端推过来还是客户端主动拉的?客户端主动拉的!
2024-07-30 13:35:21 853
原创 java锁的认识
自旋锁的定义:当一个线程尝试去获取某一把锁的时候,如果这个锁此时已经被别人获取(占用),那么此线程就无法获取到这把锁,该线程将会等待,间隔一段时间后会再次尝试获取。这种采用循环加锁 -> 等待的机制被称为自旋锁(spinlock)。ReentrantLock 是一把可重入锁,也是一把互斥锁,它具有与相同的方法和监视器锁的语义,但是它比 synchronized 有更多可扩展的功能。ReentrantLock 的可重入性是指它可以由上次成功锁定但还未解锁的线程拥有。当只有一个线程尝试加锁时,该线程调用。
2024-07-15 14:17:39 805
原创 Socket
这些信息会传递给协议栈中的 TCP 模块,TCP 模块会对请求报文进行封装,再传递给 IP 模块,进行 IP 报文头的封装,然后传递给物理层,进行帧头封装,之后通过网络介质传递给服务器,服务器上会对帧头、IP 模块、TCP 模块的报文头进行解析,从而找到对应的套接字,套接字收到请求后,会写入相应的信息,并且把状态改为正在连接。所以浏览器需要根据网址来查询服务器的 IP 地址,做这项工作的协议是 DNS,查询到目标主机后,再把目标主机的 IP 告诉协议栈,至此,客户端这边就准备好了。
2024-07-14 22:01:46 693
原创 MySQL 的 varchar
来看极限边界情况,innodb为了记录一下varchar真实存储多少个字节,最多分配2个字节的空间去记录,2个字节16个比特位,全部为1,最大能记录的数字是2^16-1是65535个,innodb最大能记录varchar占用的字节数就是65535个,utf8mb4字符集一个字符是最大是4个字节,65535 / 4 = 16383.75,只要varchar字符数不超过16383个,innodb就可以记录真实占用的长度L,再多就记录不了了!这20字节的空间存储的是分散行的地址和占用的字节数。
2024-07-14 21:21:53 767
原创 Spring AOP 的 5 种通知类型
如果您正在学习Spring Cloud,推荐一个经典教程(含Spring Cloud Alibaba):https://blog.didispace.com/spring-cloud-learning/返回通知 (@AfterReturning)。异常通知 (@AfterThrowing)。环绕通知 (@Around) :(优先级最高)前置通知 (@Before)。后置通知 (@After)。
2024-07-14 21:13:46 192
原创 36 张图详解 DNS :网络世界的导航
DNS,全称。采用模式,DNS client发出查询请求,DNS server响应请求。DNS client通过查询DNS server获得主机的 IP 地址,进而完成后续的 TCP/IP 通信过程。当 Windows 系统用户使用命令时,DNS 会自动查找注册了主机名和 IP 地址的数据库,并返回对应的 IP 地址。
2024-07-14 20:58:23 662
原创 JVM 配置常用参数和常用 GC 调优策略
如上表所示,目前,对于大内存的应用而言,串行的性能太低,因此使用到的主要是并行和并发两种。并行和并发 GC 的策略通过 UseParallelGC 和 UseConcMarkSweepGC 来指定,还有一些细节的配置参数用来配置策略的执行方式。例如:XX:ParallelGCThreads, XX:CMSInitiatingOccupancyFraction 等。通常:Young 区对象回收只可选择并行(耗时间),Old 区选择并发(耗 CPU)。
2024-07-12 13:45:46 305
原创 三次握手理解
在后端相关岗位的入职面试中,三次握手的出场频率非常的高。其实在三次握手的过程中,不仅仅是一个握手包的发送 和 TCP 状态的流转。还包含了端口选择,连接队列创建与处理等很多关键技术点1. 服务器 listen 时,计算了全/半连接队列的长度,还申请了相关内存并初始化。2. 客户端 connect 时,把本地 socket 状态设置成了 TCP_SYN_SENT,选则一个可用的端口,发出 SYN 握手请求并启动重传定时器。3. 服务器响应 ack 时,会判断下接收队列是否满了,满的话可能会丢弃该请求。
2024-07-12 11:32:01 894
原创 Redis为什么变慢了?一文讲透如何排查Redis性能问题
好了,以上就是我总结的在使用 Redis 过程中,常见的可能导致延迟、甚至阻塞的问题场景,以及如何快速定位和分析这些问题,并且针对性地提供了解决方案。这里我也汇总成了思维导图,方便你在排查 Redis 性能问题时,快速地去分析和定位。这里再简单总结一下,Redis 的性能问题,既涉及到了业务开发人员的使用方面,也涉及到了 DBA 的运维方面。
2024-07-12 11:15:02 1355
原创 为什么服务端程序都需要先 listen 一下?
icsk->icsk_accept_queue 定义在 inet_connection_sock 下,是一个 request_sock_queue 类型的对象。是内核用来接收客户端请求的主要数据结构。我们平时说的全连接队列、半连接队列全部都是在这个数据结构里实现的。我们来看具体的代码。*/......我们再来查找到 request_sock_queue 的定义,如下。//全连接队列//半连接队列......
2024-07-12 10:26:48 688
原创 缓存和数据库一致性问题
好了,总结一下这篇文章的重点。1、想要提高应用的性能,可以引入「缓存」来解决2、引入缓存后,需要考虑缓存和数据库一致性问题,可选的方案有:「更新数据库 + 更新缓存」、「更新数据库 + 删除缓存」3、更新数据库 + 更新缓存方案,在「并发」场景下无法保证缓存和数据一致性,且存在「缓存资源浪费」和「机器性能浪费」的情况发生。
2024-07-12 10:15:18 614
原创 自定义json序列化和反序列化
Bean/*** 自定义反序列化处理器* 支持yyyy-MM-dd、yyyy-MM-dd HH:mm:ss*/@Overridetry {/*** 自定义序列化处理器*//*** 默认序列化yyyy-MM-dd HH:mm:ss* 若存在@JsonFormat(pattern = "xxx") 则根据具体其表达式序列化*/@Overridereturn;/*** 通过字段已知的上下文信息定制 JsonSerializer。
2024-07-11 09:36:39 1210
原创 Retrofit使用
Retrofit是适用于Android和Java且类型安全的HTTP客户端工具,在Github上已经有39k+Star。其最大的特性的是支持通过接口的方式发起HTTP请求,类似于我们用Feign调用微服务接口的那种方式。SpringBoot是使用最广泛的Java开发框架,但是Retrofit官方并没有提供专门的Starter。于是有位老哥就开发了,它实现了Retrofit与SpringBoot框架的快速整合,并且支持了诸多功能增强,极大简化开发。
2024-07-11 09:31:39 415
原创 G1垃圾回收器
总结下,我们可以列出一些关于G1收集器在年老代的上关键点。并发标记阶段当应用运行时,并发的计算活性信在疏散暂停期间,活性信息鉴定哪些区被最好的回收没有像CMS一样的清除操作重新标记阶段使用比在CMS中使用的算法更快的Snapshot-at-the-Beginning(SATB)算法完全空的区域会被回收掉复制/清理阶段年轻代和年老代被同时回收年老代区域基于它们的活性被选择当Java虚拟机在Survivor和晋升的对象垃圾回收期间,堆空间用光了就会发生晋升失败。
2024-05-08 10:15:28 1004
原创 JVM内存分配策略
在虚拟机中,我们知道对象的内存是分配在堆中的。但是堆又可以划分为更小的区域以便垃圾回收,那么,对象到底是怎么在分配在堆中的呢?
2024-05-08 10:00:51 219
原创 多态实现机制-动态分配和静态分配
向上转型后调用子类覆写的方法便是一个很好地说明动态分派的例子。很显然,在判断执行父类中的方法还是子类中覆盖的方法时,如果用静态类型来判断,那么无论怎么进行向上转型,都只会调用父类中的方法,但实际情况是,根据对父类实例化的子类的不同,调用的是不同子类中覆写的方法,很明显,这里是要根据变量的实际类型来分派方法的执行版本的。静态类型和实际类型在程序中都可以发生一些变化,区别是静态类型的变化仅仅在使用时发生,变量本身的静态类型不会被改变,并且最终的静态类型是在编译期可知的,而实际类型变化的结果在运行期才可确定。
2024-05-07 16:58:50 947
原创 分布式事务及两阶段提交、三阶段提交的理解
在数据有多份副本的情况下,如果网络、服务器或者软件出现故障,会导致部分副本写入成功,部分副本写入失败。这就造成各个副本之间的数据不一致,数据内容冲突。造成事实上的数据不一致。
2024-04-30 17:29:41 622
原创 多线程的上下文切换
CPU通过时间片段的算法来循环执行线程任务,而循环执行即每个线程允许运行的时间后的切换,而这种循环的切换使各个程序从表面上看是同时进行的。而切换时会保存之前的线程任务状态,当切换到该线程任务的时候,会重新加载该线程的任务状态。而这个从保存到加载的过程称之为上下文切换。若当前线程还在运行而时间片结束后,CPU将被剥夺并分配给另一个线程。若线程在时间片结束前阻塞或结束,CPU进行线程切换。而不会造成CPU资源浪费。
2024-04-30 15:59:22 229
原创 MySQL索引实战2
整个过程会读取 t2 表的所有数据(扫描100行),然后遍历这每行数据中字段 a 的值,根据 t2 表中 a 的值索引扫描 t1 表中的对应行(扫描100次 t1 表的索引,1次扫描可以认为最终只扫描 t1 表一行完整数据,也就是总共 t1 表也扫描了100行)。字段有索引:count(*)≈count(1)>count(字段)>count(主键 id) //字段有索引,count(字段)统计走二级索引,二级索引存储数据比主键索引少,所以count(字段)>count(主键 id)
2024-04-30 14:22:36 464
原创 MySQL索引实战
MySQL 5.6引入了索引下推优化,可以在索引遍历过程中,对索引中包含的所有字段先做判断,过滤掉不符合条件的记录之后再回表,可以有效的减少回表次数。以社交场景APP来举例,我们一般会去搜索一些好友,这里面就涉及到对用户信息的筛选,这里肯定就是对用户user表搜索了,这个表一般来说数据量会比较大,我们先不考虑分库分表的情况,比如,我们一般会筛选地区(省市),性别,年龄,身高,爱好之类的,有的APP可能用户还有评分,比如用户的受欢迎程度评分,我们可能还会根据评分来排序等等。
2024-04-30 10:15:48 719
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人