自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(44)
  • 收藏
  • 关注

原创 一文搞懂transient关键字,附案例

Len_Transient_Object{str=[aaa, bbb, ccc, ddd, null], tra_strObj=null, name=‘张三’, tra_name=‘null’, age=18, tra_age=0}使用transient关键字修饰的变量在序列化的过程中会被赋为默认值。序列化: 内存 --> 磁盘;反序列化: 磁盘 --> 内存。

2025-01-08 10:43:19 191

原创 阅读线程池源码中遇到的retry:

可以看到break “标记位” 直接跳转到最外层循环,并且结束了循环继续向下执行。continue 关键字:跳出本次循环执行体,继续执行循环(如果条件满足)。continue “标记位” : 跳出循环体,继续执行。continue “标记位”

2024-12-30 15:54:04 253

原创 通过一个场景彻底搞懂非对称加密

没多久, 小丽觉得聊天越聊越不对劲,言语中透露出一丝丝猥琐之意,这表达方式与之前小明表达风格完全不同,于是小丽将聊天截图给小明发了过去,小明一看,WNM,这哪是我说的话…小明将要发送的信息在本地加密好,通过网络发送到了小丽那边,此时还是加密的信息,小丽要想看懂信息,是不是必须要进行解密,解密肯定就需要密钥,既然是对称加密,加密和解密使用的是同一个密钥,密钥如何到小丽手里呢?加密和解密使用不同的密钥,加密的公钥传递给对方,解密的私钥只留在本地,这样就避免了解密的密钥在网络上传递了。

2024-12-03 23:21:49 457

原创 为什么重写了hash()函数后,要重写equals方法 ?

这是因为hashCode()和equals(Object obj)这两个方法之间存在一定的约定关系,它们共同保证了对象的正确性和一致性。当需要从散列表中检索对象时,首先会使用对象的hashCode()来定位正确的桶,然后使用equals(Object obj)方法在那个桶内查找具体的对象。:如果两个对象根据equals(Object obj)方法比较结果为相等,则调用这两个对象任意一个的hashCode()方法必须产生相同的整数结果。

2024-11-06 10:30:06 147

原创 SQL语句中 NOT IN 子句的隐患

在写SQL语句的时候,若where条件是判断用户不在某个集合当中,我们习惯使用 where 列名 not in (集合) 子句,这种写法本身没有问题,但实践过程中却发现很多人在写类似的SQL语句时,写的代码存在隐患,而这种隐患往往难以发现。Impossible WHERE:表示优化器已经确定 WHERE 子句中的条件是不可能满足的,因此查询不会返回任何行。MySQL 会在这种情况下跳过实际的表扫描,直接返回空结果集,从而提高性能。因此在使用Not IN 关键字的时候,要避免出现 NULL 值。

2024-11-06 10:03:15 296

原创 前后端分离,Jackson,Long精度丢失

这是因为JavaScript中的数字一律采用IEEE-754标准的64位浮点数表示,这种格式可以很好地处理大多数数字运算,但对于非常大的整数(超出2^53 - 1),就可能出现精度损失,这就非常的恶心了,可能会让你感到莫名其妙。当从后端获取到Long类型的值并尝试在前端展示时,如果该值超过了JavaScript安全整数范围,那么显示的结果可能不准确。全局解决方案:项目中所有的Long都会被转换为String进行输出。案例:后端接口放回一个Long数据。

2024-11-05 14:42:38 722

原创 并发带来的对象一致性问题

test2中使用的使this.so 获取当前的值,也即永远可以获取最新的值,可能会带来操作对象不一致的情况。后,一个线程改变了this.so的“指向”,指向了一个新的对象,再执行this.so.getCode();则获取的是最新对象的值,而不是原有对象的值。首先main方法中创建了Object_IS对象,对象中包含另外一个对象Student_Object (初始值: name = “张三”,code = 123);如蓝线所示,这样即使os中的so发生了变化,也不会影响方法中下面操作该对象的值。

2024-09-17 21:00:42 567

原创 BolckingQueue

false ------------------------------------------队列满后,插入失败。函数说明:向队列中添加一个元素,当队列为空时抛NPE异常,队列满时,抛IllegalStateException异常。如图: 进入队列的顺序是1,2,3,那么出队列的顺序只能是1,2,3,不可能是其他顺序,这是由队列的特点保证的。与offer(E e)的不同点在于,offer(E e)只插入一次,成功或者失败立即返回;

2024-09-16 17:56:11 1880

原创 ThreadLocal

ThreadLocal 直译过来就是“线程本地的”;相当于线程自己的小仓库。

2024-09-15 22:39:44 558

原创 强引用、软引用、弱引用、虚引用

如果不停的创建对象,总有一个时刻会占满内存空间,为了避免这种现象的发生,jvm会主动的将未使用的内存空间进行回收(GC)。java中基本数据类型分为两大类:1、基本数据类型;2、引用数据类型。JDK1.2中又将引用数据类型分为4类: 强引用、软引用、弱引用、虚引用,引入的目的是为了更好的管理内存空间。其中,FinalReference 被设计出来的目的是给 JVM 用的,这里暂时不学习。下面从强到弱学习四种引用类型。

2024-09-14 14:57:45 2771

原创 java基础-IO(6)转换流InputStreamReader、OutputStreamWriter

字符集:定义了可用字符及其对应的数字编码的集合。常见的字符集有UTF-8、GBK、Unicode等等;不同的字符集对同一个字符的编码可能不一样。如: 汉字 “一” 在GB2312字符集中用两个字节进行编码(11010010 10111011);在UTF-8字符集使用三个字节进行编码(11100100 10111000 10000000)。从第一节可知,流分为两类:字节流和字符流,转换流就是在两者之间进行转换。字节流转换为字符流;字符流转换为字节流。

2024-09-10 22:40:46 430

原创 java基础-IO(5)缓冲流、BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter

可类别送快递:一开始是一件一件送,后来用车送到一个集中点,然后再送到用户手上,极大节省了中间的传输时间。原有的流是直接读入读出,读出的时候直接与存储系统交互(如磁盘等),涉及到I\O操作就比较慢。字符缓冲流与其功能类似,使用字符进行数据缓存。缓冲流就是带有一个缓冲区的流。

2024-09-10 15:12:35 612

原创 java基础-IO(4)管道流 PipedOutputStream、PipedInputStream、PipedReader、PipedWriter

如果从上一个管道到下一个管道,只是走个过场岂不是没有任何意义,既然要处理就需要逗留,逗留就意味着需要暂存,字节流使用字节数组存储,字符流使用字符数据存储。PipedReader、PipedWriter 字符管道类似于字节管道,只不过使用字符数组存储数据。字节流(PipedOutputStream、PipedInputStream)"流"从上一个管道 ——-> 下一个管道。又细分为字节流和字符流。提到管道,第一印象就是水管或者地下管道,一节接着一节,形如下图。案例:一个字符串从上一个管道写到下一个管道。

2024-09-08 22:48:17 508

原创 java基础-IO(3)数组流(ByteArrayInputStream、ByteArrayOutputStream、CharArrayReader、CharArrayWriter)使用及源码

注意:读取的是一个byte数组,但是返回值是int,,默认进行了数据类型提升(由byte->int),java会保留其符号位,原本的负值会在提升后仍然是负值。如果 buf[pos] 是负值(如 -1 对应的字节值),那么在进行 & 0xff 操作后,它的结果将是 255(即 0xFF)。与其他流不太一样的是:数组流是内存中的一个流,写出目标是内存中的字节(符)数组,读取操作的目标也是该数组。否则逐个读取数组中的元素。通过 (buf[pos++] & 0xff) 操作,可以将字节转换为一个无符号的整数。

2024-09-08 12:10:53 438

原创 java基础-IO(2)文件流

从上一小节中可以,字节流读取的单位是字节,因此字节流可以读取一切。日常涉及IO最常见的是操作文件,因此本节探讨文件的读取。常见的文件有音频、视频、文本文件等,使用字节流可以读取一切文件,字符流的读取单位是字符,适合文本文件。细节:在文件写出的时候,如果这个文件已经存在,那么再次写出的内容是追加到原有文件末尾还是覆该原有文件?既然是要复制文件,则必须提供文件的位置,因此有下面的构造方法。同样的,需要知道把文件写出到哪个文件中。案例:使用文件字节流复制一张图片。默认是覆盖原有文件!

2024-09-08 09:55:48 252

原创 java基础-IO(1)

电脑电脑,有电才能发挥出“脑”的作用,没电就是破铜烂铁一堆,根据电的特性(高低电平)巧妙的使用0、1组合,记住了万事万物,才得以让"破铜烂铁"发挥出神奇的功效。计算机在处理数据的时候不是按照单个0、1进行处理的(处理起来太慢并且单个比特位表示的信息范围有限),因此在处理数据的时候采用处理一组比特位,也称为字节(B/byte),1B = 8bit。综上所述:虽然计算机最底层使用的是比特位存储信息,但是计算机在处理数据都是以字节为单位进行处理,所以可以认为“字节的不同组合”能表示一切信息。

2024-09-08 09:07:51 396

原创 CAS带来的ABA问题以及解决方案

线程1和线程2同时对变量i = 1 进行操作,线程1对i进行了两次操作,先将i+1 写出,后又进行了i-1并写出,线程2过来读的时候与原来值1仍然是相等的,虽然值仍然相等,但是i的值却发生过改变,期间从1变成2又变成1(ABA问题)。java中使用AtomicMarkableReference或者AtomicStampedReference。AtomicStampedReference: 使用int 记录改变的次数(推荐)!AtomicMarkableReference:使用boolean表示是否修改过。

2024-09-04 12:20:13 323

原创 AtomicIntegerArray使用、核心源码解析

cas需要三个参数(绝对地址,期望值,新值),根据绝对地址获取值然后与期望值进行比较,若相等则更新为新值,反之不更新。base = unsafe.arrayBaseOffset(int[].class): 获取数组的首地址;知道数组中每个元素占用的字节,元素占用的字节*元素的下标=元素的偏移地址(相对数组首地址偏移);举例: 假设是int[] 单个元素占用4字节, 第5个元素的首地址应该是(前面有4个元素)其次需要知道数组的首地址(相对地址,相对对象首地址偏移);首先需要直到对象的首地址(绝对地址);

2024-09-04 11:34:40 1076

原创 AtomicInteger类的API、源码解读

就是获取value属性在对象中的偏移地址。传递this(当前对象)即可获取当前对象的绝对地址,通过当前对象的绝对地址+value的偏移地址即可获得value属性的绝对地址,通过value属性的绝对地址,cpu就可直接操作其值。既然有绝对地址那么就有相对地址,相对地址相对的是段的首地址,也称为偏移地址。上述四个方法支持函数式编程设置值。

2024-09-02 12:01:13 592

原创 java之浅拷贝、深拷贝

这里写到流中的对象则是原始对象的一个拷贝,因为原始对象还存在 JVM 中,所以我们可以利用对象的序列化产生克隆对象,然后通过反序列化获取这个对象。在深度拷贝中,需要被拷贝的对象中的所有引用数据类型都实现Cloneable()接口并且重写clone()方法,如果一个对象有好多引用数据类型,则比较费劲,有没有其他方法呢?使用clone()方法时,必须实现该接口并且复写clone()方法。PeoSon{age=123, book=Book{bookName=‘java从入门到入坟’, price=10}}

2024-08-31 17:22:39 2279

原创 java基础之枚举Enum

3、使用对象数组存储枚举实例对象,且会按照对象声明顺序给对象进行编号,编号不可修改( private final int ordinal)。可以发现 values()、valueOf()方法并自定义的枚举类或者Enum类中,这两个方法来自哪里?使用EnumSet时 底层使用RegularEnumSet 或者JumboEnumSet实现,待续…2、自定义枚举默认继承Enum类,由于java是单继承,因此不可再继承其他类;1.1:枚举,从名称可知数据量一定是有限的,可列举的。5、会自动增加两个静态方法。

2024-08-31 11:13:26 499

原创 java基础之 静态代码块、实例代码块、构造方法执行顺序问题

父类静态变量 > 父类静态代码块 > 子类静态变量 > 子类静态代码块 > 父类构造代码块 > 父类构造方法 > 子类构造代码块 > 子类构造方法。构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象(某个)初始化。静态变量 > 静态代码块 > main()方法 > 构造代码块 > 构造方法。静态代码块在类的加载时候执行,由于类只加载一次,所以静态代码块只执行一次;首先要理解构造代码块的作用,是给所有对象进行统一初始化,提高代码的复用率。注意:构造代码块在对象一建立就运行,优于构造函数执行。

2024-08-31 09:12:11 209

原创 FactoryBean 与 BeanFactory

原理:从Spring容器中获取到的bean对象是FactoryBean或者是实现FactoryBean的,会使用getObject()获取到真实的bean对象,这个对象是由用户自己进行创建管理的,体现了扩展性通过上述可以得到:BeanFactory提供了获取Bean的方式,(BeanFactory是Spring核心接口之一)FactoryBean是一个特殊的bean,实现该接口可以自定义实现bean的创建逻辑(扩展性)。

2024-08-22 16:17:55 366

原创 MyBatis源码系列3(解析配置文件,创建SqlSessionFactory对象)

创建SqlSessionFactory;首先读取配置文件,使用构造者模式创建SqlSessionFactory对象。核心:解析xml配置文件,解析的配置文件用Configuration对象保存。创建SqlSessionFactory 时序图。解析顺序与配置文件中的设置信息完全一致。

2024-08-17 21:52:43 460

原创 MyBatis源码系列2(简易版MyBatis)

本案例使用注解进行(选择注解的原因:在执行步骤2的时候,核心是执行脚本,执行脚本之前需要对参数进行处理,执行完成之后需要进行结果处理,符合动态代理设计模式)。通过步骤2可以看出,脚本是与“目标数据”绑定在一起的,如何完成这种绑定?通过上一篇分析可知,可以访问数据库繁琐步骤封装为两部分完成。步骤2、封装一个“方法”,入参为脚本,出参为“目标”数据。步骤1、使用数据库连接池完成数据库的连接;方案1:建立一个实体,保存方法和返回值对象。下一节,正式阅读mybatis源码。方案2:在方法上使用注解。

2024-08-16 15:44:40 400

原创 MyBatis源码系列1(使用JDBC查询数据)

执行脚本之前需要给脚本动态赋值,脚本执行以后需要对结果进行解析,正好对应代理模式(动态代理)。1、每与数据库交互一次,都要执行一遍上面的流程,流程繁琐,下一篇基于 动态代理+注解 实现简易版的MyBatis。脚本不同(传递参数),返回值不同[反射解决](查询操作)2、脚本与业务代码强耦合,不利于复用和维护。1、从数据库连接池中获取数据库连接;步骤3~步骤7中,核心是。2、传入脚本获取结果。

2024-08-15 18:09:57 364

原创 MyBatis自定义数据类型转换器的使用

实现方式实现TypeHandler接口或 继承BaseTypeHandler类。本案例以实现TypeHandler接口。1、自定义数据类型转换器@OverrideSystem.out.println("参数自定义类型转换器1111111 参数进行了处理......");//处理后的参数@Override@Override@Override2、注册类型转换器(mybatis-config.xml)</</3、使用自定义的数据类型转换器</1、实现数据类型转换器```python。

2024-08-09 17:50:02 251

原创 java基础之ArrayList使用Iterator遍历问题

在后续迭代器的操作时, 会对expectedModCount 、modCount 进行值比较,如果相等,则表示源数据没继续增加或删除,如果不等,则表示源数据进行了增加或者删除(进行增加或者删除的时候,modCount值会+1,expectedModCount 则不会)。可以简单的理解为,在创建迭代器后对其进行了"约束",既然交给Iterator进行管理了,你就不要再操作了。modCount: 记录了集合的操作次数,没向集合中添加一个元素、删除一个元素都会对该值+1。注意红色的变量名词。

2024-08-06 18:13:24 427

原创 Java基础之增强for循环

增强的 for 循环会在内部创建一个迭代器(Iterator),用于遍历 arrayList,既然是使用迭代器进行循环,所以在使用增强for循环时不能。具体原因见下一篇 Iterator 的深入学习。里面的元素,可以修改元素的值。

2024-08-06 16:42:22 205

原创 设计模式之模板方法模式

模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。

2024-08-03 11:12:05 374

原创 设计模式之建造者模式 与 工厂模式

建造者模式与工厂模式都用于生产对象。区别: 建造者模式用于生产比较复杂的对象,注重生成对象过程中的细节,可能最后创建对象的步骤依赖之前的准备工作。工厂模式用于生成简单的对象,注重结果不注重过程。打个比方:建造者模式是生产包子,在包出包子之前,需要准备馅儿、调味等前置工作,前置工作准备完成后最后是包包子。工厂模式是生产馒头,简单快捷。

2024-07-29 21:29:06 300

原创 设计模式之观察者模式

主题接口仅仅依赖于观察者接口,这样,就可以让创建具体主题的类也仅仅是依赖于观察者接口,因此,如果增加新的实现观察者接口的类,不必修改创建具体主题的类的代码。同样,创建具体观察者的类仅仅依赖于主题接口,如果增加新的实现主题接口的类,也不必修改创建具体观察者类的代码。同样,由于观察者仅仅依赖于主题接口,因此具体观察者只是知道它依赖的主题是实现主题接口的某个类的实例,但不需要知道具体是哪个类。在本案例中,堤坝成为了被观察者对象,是否出现管涌、决堤等情况,武警、消防、医护是观察者,根据堤坝的状态做出相应的措施。

2024-07-28 09:19:06 965

原创 设计模式之责任链模式

在酒宴上宾客依次坐定位置,由一人击鼓,击鼓的地方与传花的地方是分开的,以示公正。比如下面这个场景: 在公司请假,请半天或1天假需要组长审批即可,请2-3天假,需要直系经理进行审批,请4-5天假需要部门经理审批,请超过5天假期需要公司高层审批。:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。在责任链模式1中,事件会经过链上的每一环节,有些情况是没必要经过全部环节的,可以在链上的任意一个环节进行中断返回。

2024-07-27 10:09:20 781

原创 设计模式之工厂方法模式

工厂方法模式:工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式。工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。举例说明:相信很多人都做过导入导出功能,就拿导出功能来说。

2024-07-24 15:52:07 548

原创 设计模式之简单工厂设计模式

简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。如果后期功能扩展,需要提供邮箱密码验证登录方式,则只需扩展ILoginService的实现类+创建对应的对象即可,原有功能无需任何改动。举例 (场景描述): 用户登录,可以使用 账户+密码 登录,也可使用 账户 + 动态验证码登录。以上仅是个人思考,有更好的idea,欢迎一起探讨。抽象出登录验证的动作,如下图所示。

2024-07-23 22:55:57 234

原创 UML学习

关联关系体现的是两个类,或者类与接口之间的强依赖关系,这种关系很强烈,比依赖更强,不是偶然性的,也不是临时性的,而是一种长期性,相对平等的关系,表现在代码层面,为。举个例子,如某人要过河,则人与船的关系就是依赖,人过河之后,与船的关系就解除了,因此是一种弱的连接。,这是因为组合关系的整体和部分是共生关系,如果通过外部注入,那么即使整体不存在,那么部分还是存在的,这就相当于变成了一种聚合关系了。表示类与类之间的继承关系,接口与接口之间的继承关系,或类对接口的实现关系;聚合关系是关联关系的一种情况。

2024-07-23 17:33:57 612

原创 java基础之泛型

泛型解释为:将类型由原来的具体的类型参数化(也即参数化类型对于一个普通的方法有形参,形参有参数类型,在使用该方法的时候传递的是实参。泛型就是将形参的数据类型参数化。//方法1(普通方法)public void pnt(String var) { //形参的数据类型为String, 形参var//方法2(泛型方法)public <T> void pnt2(T t) { //未给出具体形参数据类型,形参的数据类型也是一个参数。

2024-07-21 22:12:38 948

原创 Java读取properties

【代码】Java读取properties。

2024-07-21 14:03:39 137

原创 java集合1--ArrayList

通过上述可知,使用java.util.ArrayList存储元素时即使传过来的不是使用Object[]数组存储的,会把元素复制到Object[]数组。通过 Arrays.asList(“11”) 创建的集合对象,返回的是java.util.Arrays$ArrayList(明显是内部类)。在初始化的时候,若未初始化大小,则为空数组。new ArrayList().toArray()底层是使用Object[]数组进行存储的。给定合适的容量,在进行第一次添加数组元素的时候,无需再进行容量扩增。

2024-07-19 11:01:16 371

原创 jdk1.8 反射:方法获取不到形参真实名称

真实形参名词为: id,name 获取到的形参名词为arg0,arg1。在idea中设置配置: 配置设置完成后reBuild project一次即可。

2024-07-18 10:59:07 254

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除