- 博客(36)
- 收藏
- 关注
原创 Java中高并发下缓存删除失败怎么办?
每次都单独起一个线程,该线程专门做重试的工作。但如果在高并发的场景下,可能会创建太多的线程,导致系统OOM问题,不太建议使用。订阅mysql的binlog,在订阅者中,如果发现了更新数据请求,则删除相应的缓存。将重试的请求写入mq等消息中间件中,在mq的consumer中处理。将重试的任务交给线程池处理,但如果服务器重启,部分数据可能会丢失。将重试数据写表,然后使用elastic-job等定时任务进行重试。
2024-03-11 18:59:52
439
1
原创 设计模式之观察者模式
又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。
2023-06-30 09:14:53
353
原创 设计模式之状态模式
【例】通过按钮来控制一个电梯的状态,一个电梯有开门状态,关门状态,停止状态,运行状态。每一种状态改变,都有可能要根据其他状态来更新处理。例如,如果电梯门现在处于运行时状态,就不能进行开门操作,而如果电梯门是停止状态,就可以执行开门操作。类图如下://电梯的4个状态 //开门状态 public final static int OPENING_STATE = 1;//关门状态 public final static int CLOSING_STATE = 2;
2023-06-30 09:11:12
362
原创 设计模式之装饰器模式
饰者模式可以带来比继承更加灵活性的扩展功能,使用更加方便,可以通过组合不同的装饰者对象来获取具有不同行为状态的多样化的结果。装饰者模式比继承更具良好的扩展性,完美的遵循开闭原则,继承是静态的附加责任,装饰者则是动态的附加责任。抽象装饰(Decorator)角色 : 继承或实现抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。当对象的功能要求可以动态地添加,也可以再动态地撤销时。
2023-06-28 16:38:02
184
原创 设计模式之建造者模式
建造者(Builder)模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合。造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适。在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得。将复杂产品的创建步骤分解在不同的方法中,使得创建过。创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表。
2023-06-27 22:41:00
73
原创 设计模式之原型模式
将上面的“三好学生”奖状的案例中Citation类的name属性修改为Student类型的属性。这就是浅克隆的效果,对具体原型类(Citation)中的。stu对象和stu1对象是同一个对象,就会产生将stu1对象中name属性值改为“李四”,两个。浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原。深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。象原型类,而实现了Cloneable接口的子实现类就是具体的原型类。性能和安全要求比较高。
2023-06-27 22:11:43
65
原创 安装mongodb且使用密码验证登录连接Navicat
MongoDB是一个开源、高性能、支持海量数据存储的文档型数据库。是NoSQL数据库产品中的一种,是最像关系型数据库(MySQL)的非关系型数据库。1.数据存储量较大,甚至是海量2.对数据读写的响应速度要求较高3.某些数据安全性要求不高,可以接受一定范围内的误差MongoDB的安装1、执行命令,进入 mongodb 容器(mongodb-server 为容器名)2、在 mongodb 容器中执行以下命令#更新源即可开启远程连接。3、远程连接要有对应的用户名和数据库。
2023-06-27 15:10:35
1392
原创 事务的7种传播行为
PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,这是最常见的选择,也是Spring默认的事务传播行为。PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
2023-06-18 17:16:13
158
原创 事务四种隔离级别
存在幻读问题:幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。存在不可重复读问题:同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。4、Serializable 序列化。
2023-06-18 17:15:16
93
原创 构造方法注入和设值注入有什么区别?
(4)在设值注入时如果对象A和对象B互相依赖,在创建对象A时Spring会抛出ObjectCurrentlyInCreationException异常,因为在对象B被创建之前对象A是不能被创建的,反之亦然。Spring用设值注入解决了循环依赖问题,因为对象的设值方法是在对象被创建之前被调用的。1)设值注入支持大部分依赖注入,如果我们仅需要注入int、string和long型的变量,不要用设值方法注入。(3)在使用设值注入时还不能保证某种依赖是否已经被注入,也就是说,这时对象的依赖关系有可能是不完整的。
2023-06-13 22:34:36
87
原创 连接mysql时报错Public Key Retrieval is not allowed的解决方法
连接mysql时报错Public Key Retrieval is not allowed的解决方法。加上allowPublicKeyRetrieval=true即可。
2023-06-12 14:32:33
871
原创 【解决方案】打不开磁盘Ubuntu.64位.vmdk,导致打开虚拟机失败
虚拟磁盘(.vmdk)本身有一个磁盘保护机制,为了防止多台虚拟机同时访问同一个虚拟磁盘(.vmdk)带来的数据丢失和性能削减方面的隐患,每次启动虚拟机的时候虚拟机会使用扩展名为.lck(磁盘锁)文件对虚拟磁盘(.vmdk)进行锁定保护。当虚拟机关闭时.lck(磁盘锁)文件自动删除。但是可能由于您非正常关闭虚拟机,这时虚拟机还没来得及删除您系统上的.lck(磁盘锁)文件,所以当下次您启动虚拟机的时候出现了上述错误。删除所有以.lck为后缀的文件,重新打开即可。
2023-06-11 10:15:48
2307
原创 volatile 对比 Synchronized 的异同
用volatile修饰后的变量,赋值后多执行了一个lockaddl指令的操作,作用相当于一个内存屏障,使得指令重排序时不能把后面的指令重排序到内存屏障之前,从而阻止了指令重排序。基于volatile变量的运算在并发下不一定是安全的。volatile变量在各个线程的工作内存,不存在一致性问题(各个线程的工作内存中volatile变量,每次使用前都要刷新到主内存)。volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。
2023-06-11 10:09:09
61
原创 ArrayList 和 LinkedList 的区别是什么?
当对数据进行增加和删除的操作(add和remove操作)时,LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,4、在前方插入时,ArrayList可以使用后方插入,最后再使用Collections.reverse()方法反转,速度依然完爆LinkedList。ArrayList自由性较低,因为它需要手动的设置固定大小的容量,但是它的使用比较方便,只需要创建,然后添加数据,通过调用下标进行使用;4、主要控件开销不同。
2023-06-09 22:41:51
2600
原创 volatile 对比 Synchronized 的异同
用volatile修饰后的变量,赋值后多执行了一个lockaddl指令的操作,作用相当于一个内存屏障,使得指令重排序时不能把后面的指令重排序到内存屏障之前,从而阻止了指令重排序。基于volatile变量的运算在并发下不一定是安全的。volatile变量在各个线程的工作内存,不存在一致性问题(各个线程的工作内存中volatile变量,每次使用前都要刷新到主内存)。volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。
2023-06-09 22:40:56
60
原创 动态代理是什么?有哪些应用?
(2)CGLIB动态代理(这个是第三方实现的,所以使用这种方式,我们要引入jar包)与jdk动态代理相比,CGLIB不要求必须要实现接口StudentInterface ,就能直接对目标对象就行代理增强,更加的简单方便。通过克隆可以创建一个新对象,该对象的属性和原始对象相同,但是对新对象所做的更改不会影响原始对象的状态。Java中的克隆是指创建一个与原始对象完全相同的新对象,包括它的属性和值。例如,某个对象可能需要使用复杂的初始化过程才能被创建,但是通过克隆,我们可以避免让客户端了解这些实现细节。
2023-06-09 22:36:41
179
原创 new String(“a“) + new String(“b“) 会创建几个对象?
19 new #4 <java/lang/String> :创建 String 对象,对应于 new String(“b”)7 new #4 <java/lang/String> :创建 String 对象,对应于 new String(“a”)11 ldc #5 :在字符串常量池中放入 “a”(如果之前字符串常量池中没有 “a” 的话)23 ldc #8 :在字符串常量池中放入 “b”(如果之前字符串常量池中没有 “b” 的话)
2023-06-09 22:36:16
176
原创 什么是反射?
在程序运行状态中,对于任意一个类或对象,都能够获取到这个类的所有属性和方法(包括私有属性和方法),这种动态获取信息以及动态调用对象方法的功能就称为反射机制。简单来讲,通过反射,类对我们是完全透明的,想要获取任何东西都可以。在程序运行状态中,对于任意一个类或对象,都能够获取到这个类的所有属性和方法(包括私有属性和方法),这种动态获取信息以及动态调用对象方法的功能就称为反射机制。【Runtime运行时阶段】对象.getClass():此方法是定义在Objec类中的方法,因此所有的类都会继承此方法。
2023-06-09 22:35:42
67
原创 java 中操作字符串都有哪些类?它们之间有什么区别?
String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。这是因为在源代码中StringBuffer的很多方法都被关键字synchronized 修饰了,而StringBuilder没有。它们之间有什么区别?
2023-06-09 22:34:29
48
原创 String str=“i“与 String str=new String(“i”)一样吗?
创建了5个对象 i创建1个,new创建2个 jvm编译优化把‘+’优化stringbuilder一个,string返回连接后的对象一个(在常量池中不创建联合在一起的);不一样,因为Str="i"会把i这个值通过jvm放在常量池里面,而new String(i)会把这个对象先放进堆里面然后判断字符串常量池里面有没有i如果有堆直接引用没有则创建并引用i。String str="i"与 String str=new String(“i”)一样吗?
2023-06-09 22:33:28
154
原创 == 和 equals 的区别是什么?
判断的是对象的地址是否指向同一处,一般就算是new 都会新创建一个内存空间所以就算值一样也是false,而我们用equals的时候 如果类没有重写equals方法。不对,如果两个对象相等hashcode一定相等,如果两个对象不相等hashcode也可能相等因为根据值计算的。则比较是否值相等(如果是引用类型就比较地址)相当于==,但是重写equals就会去比较值相等。如果比较的是引用数据类型变量,比较两个对象的地址值是否相同,即两个引用是否指向同一个地址值。(不一定数据类型相同)hashcode可能会相等。
2023-06-09 22:33:11
41
原创 Final 在 java 中有什么作用?
final修饰基本数据类型变量和引用数据类型变量。引用类型的引用地址不可改变但是对象的内容可以修改。另外一个作用是在编译器对方法进行内联, 提升效率。但是现在已经很少这么使用了。修饰的类所有成员方法都将被隐式修饰为final方法。final修饰方法(如:Object的getClass方法)final修饰类(如:String、System类等)首要作用是锁定方法, 不让任何继承类对其进行修改。final修饰的常量在编译阶段会被放入常量池中。
2023-06-09 22:32:10
107
原创 探究Java类的加载过程
这个阶段是类加载过程的最后一步,是代码真正开始执行的时候,在这个阶段,开发人员可以根据自己的需求去给类变量初始化赋值。简单来说就是执行类构造器()方法的过程。一个类型从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期将会经历加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化lhitialization)、使用(Using)和卸载(Unloading)七个阶段,其中验证、准备、解析三个部分统称为连接(Linking)。
2023-05-25 19:08:31
128
1
原创 (Java实习生) Jvm_2
对象的创建对于我们程序员来说通常就是一个new关键字而已,在虚拟机层面,对象可不仅仅是new那么简单,Jvm可以说是一个非常复杂的过程,可以从三个角度来分析。
2023-05-23 16:36:03
131
1
原创 (Java实习生)深入理解JVM_1
虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Jaya虚拟机都会同步创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程、就对应着二个栈帧在虚拟机栈中从入栈到出栈的过程。在Java 虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。虚拟机规范》中定义的内存区域。
2023-05-23 16:16:59
204
1
原创 HashMap负载因子为什么是0.75
即在处理哈希地址的冲突时,若得到的另一个哈希地址H1仍然发生冲突,则再求下一个地址H2,若H2仍然冲突,再求的H3,直至Hk不发生冲突为止,则Hk为记录在表中的地址。负载因子是0.5的时候,这也就意味着,当数组中的元素达到了一半就开始扩容,既然填充的元素少了,Hash冲突也会减少,那么底层的链表长度或者是红黑树的高度就会降低。指针需要额外的空间,故当结点规模较小时,开放定址法较为节省空间,而若将节省的指针空间用来扩大散列表的规模,可使装填因子变小,这又减少了开放定址法中的冲突,从而提高平均查找速度。
2023-04-18 10:29:56
590
原创 面试官:一千万数据,怎么快速查询?
数据量过大的情况下, limit offset 分页会由于扫描数据太多而越往后查询越慢. 可以配合当前页最后一条ID进行查询, SELECT * FROM T WHERE id > #{ID} LIMIT #{LIMIT} . 当然, 这种情况下ID必须是有序的, 这也是有序ID的好处之一.
2023-03-01 09:25:01
178
原创 Docker 安装 添加普通用户执行权限(ubantu)
3.如果普通用户执行docker命令,如果提示get ……dial unix /var/run/docker.sock权限不够,则修改/var/run/docker.sock权限。1、 首先创建docker用户组,如果docker用户组存在可以忽略。2、普通用户加入docker用户组。使用root用户执行如下命令,即可。4.重启docker。
2022-11-01 11:15:07
1358
原创 流对数据数理对于迭代的区别
文章参考:《Java核心技术卷 卷2》在处理集合时,我们通常会迭代遍历他的元素,并对元素进行各种操作。例如:我们想要对某本书的所有长单词进行计数: String con=new String(Files.readAllBytes(Paths.get("book.txt")), StandardCharsets.UTF_8);//从文件读取字符串 List<String> words=List.of(con.split("\\PL+"));...
2021-10-24 09:44:42
123
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人