自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 线程池相关接口和实现类

3.如果当前线程数大于核心线程数并且线程池为RUNNING状态,将线程任务添加到workQueue工作队列中,等待某个空闲工作线程获取并执行任务。5.这次在创建新的Worker工作线程时,会判断当前线程池的线程数是否超过最大线程数,如果超过,则返回false,代表创建失败,执行拒绝策略。1.首先获取线程池的工作状态和工作线程数(线程池用一个32位的整数代表工作状态和工作线程数,前3为代表工作状态,后29位代表工作线程数)。的线程池实现类,通过分叉合并的方式,将一个大任务拆分成多个小任务,并且为。

2023-12-12 16:20:27 88

原创 TCP协议

(2)如果采用二次握手,当第一次连接请求发送后,由于网络等原因,客户端迟迟没有收到服务器的确认请求,由于TCP的重发机制,客户端会发送第二次连接请求,然后服务器对第二次连接请求进行确认后,当第一次连接请求到达服务器时,服务器以为客户端进行重新连接,向客户端再次发送确认请求,客户端此时不会处理服务器第二次的确认请求,则服务器会一直等待着客户端的回复,造成服务器的无效等待,如果频繁发送连接请求,可能会造成服务器停止响应。第一次挥手:有客户端向服务器发送首部格式为FIN=1,ACK=0的释放连接请求。

2023-09-23 18:07:31 87

原创 Spring的AOP

如果需要指明参数: int ========>int,String====>java.lang.String,需要指定完全限定名,通常都只给业务层的所有方法配置aop。连接点(Join point):表示在程序中明确定义的点,典型的包括方法调用,异常处理程序块的执行,也就是所有的方法,不管是接口的抽象方法,还是实现类的重写方法。上面代码中,我们定义了两个类,一个为业务类进行整数计算,另一个为日志切面类,为每个业务方法添加日志功能,接下来,我们通过xml配置文件的方式进行配置。

2023-08-28 11:15:55 77

原创 Spring的DI依赖注入

1.概述:在上篇文章中,我们了解了Spring的IOC思想并且通过<bean>标签配置类信息,通过IOC容器创建对象并获取使用,但是IOC容器是通过无参构造方法创建出的对象,属性值均为null,所以我们就要通过DI依赖注入来进行属性的赋值。通过以上两种自动装配的实现,也可以将IdCard类型的对象注入到Student类的card属性,这也是我们依赖注入的本质,类A中存在类B的属性,IOC容器中存在着类A和类B的bean对象,有IOC容器管理类A和类B的依赖关系。用于引用IOC容器中的bean对象。

2023-08-25 20:27:43 70

原创 Spring的IOC容器

我们通过new关键字直接创建出Driver类的对象,此时代码的耦合度是最高的,因为一旦Driver类被删除了,代码无法运行,所以我们经常使用Class.forName()基于反射的方式加载驱动类。在这次的代码中,我们使用Class.forName()方法基于反射加载驱动类,耦合度有所降低,但是驱动类的完全限定名在代码中写死了,如果改变驱动类,必须修改源代码。为类的完全限定名,IOC容器在底层就会进行读取配置文件中的信息,然后通过反射技术创建出对象返回,接下来,就让我们获取Student类的对象。

2023-08-23 21:21:34 35

原创 ResultMap标签的使用

从Order订单的角度出发,一个订单只能属于一个用户,属于一对一关系,在查询Order订单信息时,我们也需要查询出所对应的User用户信息,可以通过多表联查的方式将数据一次性查出,然后定义映射关系,此文章使用的是级联查询的方式。在该resultMap映射关系定义时,大部分与一对一关系的定义是一致的,唯一不同的是,Order对于User用户来说是一对多的,也就是说,在User类中,存在一个Order订单的List集合,所以,在一对多的关系中,使用。定义映射关系,该标签的属性与<association>标签。

2023-08-21 20:47:00 161

原创 MyBatis框架基本使用

sqlSession.getMapper()方法就使用到了动态代理来生成UserMapper接口的实现类,无需我们调用sqlSession.selectList()一系列的方法来执行sql语句,直接调用实现类的方法即可。在映射文件中定义了namespace命名空间,sql语句写在对应的标签中,sql语句的标签必须在<mapper></mapper>标签之间,sql标签需要。上述的sqlSession.selectList()的参数为sql语句的唯一标识,即mapper映射文件的。

2023-08-16 22:05:41 35

原创 TreadLocal实现线程之间数据隔离

在上面的代码中,我们首先创建出了一个ThreadLocal类型的roleLocal对象, 然后创建出两个不同的线程,在线程中先使用roleLocal分别保存不同的角色名称,然后调用show()方法通过roleLocal取出角色名称,再调用Sample的dosth()方法通过roleLocal取出角色名称。从运行结果看出,两个线程分别保存自己的角色名称,实现了线程之间的数据隔离,在show()方法和Sample类的dosth()方法之间,ThreadLocal实现了同一个线程中不同方法之间的数据传递。

2023-08-15 21:26:06 388

原创 实现动态代理

动态代理基于反射技术实现,可以在程序运行期间动态的创建出代理对象,动态代理分为jdk自带的动态代理和cglib动态代理。在学习动态代理之前,我们先了解一下代理模式是什么,代理模式就是指我们不会直接去调用目标对象的方法,而是通过一个类代理目标对象,然后通过代理对象去调用目标对象的方法,在代理对象中可以对目标对象的方法进行增强,避免对目标对象的代码造成污染。当我们需要对真实主题角色的方法进行调用时,不再直接调用真实主题角色的方法,而是通过代理类,让代理类去调用真实主题的方法,同时进行了方法的增强。

2023-08-11 21:13:46 40 1

原创 RSA非对称加密算法

解密方法中,使用自己的私钥进行解密,加密方法表示该对象需要发送消息给对方,所以必须使用对方的公钥加密,解密方法表示该对象收到了对方使用它的公钥进行解密的密文,所以必须使用自己的私钥进行解密。,当使用A同学的公钥加密后得到的密文,只有A同学使用自己的私钥才能解密,如果别人知道了他的公钥,也不能计算出对应的私钥,所以使用非对称加密算法时,需要使用对方的公钥进行加密。,特点为加密的速度和效率高,但由于双方使用的都是同样的密钥,安全性得不到保证,非对称加密算法加密和解密使用的是。对称加密算法加密和解密使用的是。

2023-08-03 22:38:26 114

原创 DH秘钥交换算法

如上图所示, 加密和解密双方都会拥有自己的私钥和公钥,公钥是公开的,私钥是只有自己知道的,Alice将自己的私钥与g,p两个参数进行计算得到自己的公钥,然后将自己的公钥和g,p两个参数通过网络发送给Bob,Bob根据Alice发送的g,p参数与自己的私钥进行相同计算得到他的公钥,再将他的公钥发送给Alice,最后,双方根据各自的私钥与对方发送来的公钥进行相同的数学计算得到共享秘钥(真正进行加密和解密的秘钥)。在Person类中,分别保存了每个人对应的私钥,公钥和共同的秘钥,在构造方法中通过。

2023-07-27 21:57:33 324 1

原创 CopyOnWriteArrayList核心代码阅读

通过上面代码的阅读, 可以看出CopyOnWriteArrayList集合在增,删,改的方法都加了锁,并且都会将原来的数组复制一份,在新的数组上修改好了之后才设置为集合存储数据的array数组,所以在对CopyOnWriteArrayList集合进行写操作的时候,保证了线程安全,但在每次写操作时,都要复制数组,影响性能。锁,并且在进行写操作的同时,允许进行读操作,还可以多个线程并发进行读操作,读取效率高,性能高于Vector集合。Vector集合也是线程安全的集合,由于Vector集合使用的是。

2023-07-22 20:09:55 56

原创 synchronized锁和ReentrantLock锁的区别

使用synchronized关键字加锁之后,如果有线程想执行代码块中的代码,必须获取该代码块所指定的锁后才能执行,当add()方法执行时,dec()方法所在的线程不能获取锁,所以只有add()方法执行完释放锁后,dec()方法所在线程才能得到锁,dec()方法才可以执行,同样的,在dec()方法执行过程中,其它线程也不能干扰dec()方法的执行,只能等到dec()方法执行结束释放锁后。dec()方法的加锁和释放锁与之一样,需要强调的是,在add()方法和dec()方法中使用到的锁为同一个。

2023-07-19 21:31:11 126

原创 线程池的执行流程

以上面的案例代码来看,当我们提交第一个线程任务时,线程池中还没有线程,所以会创建出一个核心线程来执行该线程任务,随后的第二到五个线程任务都会创建出一个核心线程,此时线程池中的线程数已达到。(4)如果达到最大线程数,就会执行拒绝策略,否则,线程池就会新创建出一个线程对象去执行线程任务,与第(2)步不同的是,这次新创建的线程为。(1)当新的线程任务提交到线程池后,线程池会判断当前线程池中是否有空闲的线程,如果有,就将空闲线程分配给线程任务执行。(2)如果没有空闲线程,线程池就会判断当前线程池中的线程数。

2023-07-18 21:33:12 137 1

原创 线程的创建方式

从上面的运行结果可以看到,当主线程打印到数字5时,子线程才开始执行,而当下次执行时,可能结果就会发生变化,如果想让线程插队,可以调用线程对象的。从运行结果中看出,主线程在子线程之前结束,那是因为当子线程启动后,主线程和子线程的运行由操作系统决定,只有当进程中的所有线程运行结束后,该进程才会结束。方法的SubThread类就是我们自己定义的线程类,在这个子线程中,实现的业务逻辑为打印1-10的数字,在主线程中,我们创建出该线程的线程对象,然后调用。不会启动子线程,进程中依旧只有一个主线程(守护线程除外)。

2023-07-17 20:48:58 97 1

原创 AES算法的两种工作方式

将上面的代码不管执行多少次,只要不修改秘钥和明文的内容,得到的加密结果都是一致的,这样就使得安全性降低,在下面的CBC工作模式中,就会在每次加密时根据随机产生的IV参数使得相同的秘钥和明文,每次加密得到的结果都是不一样的。上面的两次运行结果可以看出在CBC工作模式下,相同的明文和秘钥由于随机的iv参数不同,每次的加密结果不同,相比于ECB工作模式,安全性得到了提高。上面的代码为CBC工作模式下进行的操作,与ECB工作模式相差不多,只是在加密和解密中添加了随机的。秘钥对象,然后调用cipher对象的。

2023-07-15 19:58:02 258 1

原创 java反射机制

(4)getDeclaredMethod(String name,Class...):根据方法的名字和参数获取类中定义的字段(不包括父类的)(2)getMethod(String name,Class...):根据方法的名字和参数获取指定的public修饰的方法(包括父类的)(2)getField(String name):根据字段的名字获取指定的public修饰的字段(包括父类的)我们得到字段的对象后,最主要的操作就是向该字段存值或得到该字段的值,可以使用Field类的set()和get()方法完成。

2023-07-14 20:25:22 58 1

原创 哈希加密算法

我们根据字节数组可以直接创建出密钥对象,当我们数据库中存放的是密钥字符串时,就需要将字符串转换为对应的字节数组,然后创建出密钥对象,因为我们在字节数组转字符串时,是将一个字节转换成了两个十六进制的字符,所以在字符串转字节数组时,应该每两个十六进制字符转换成一个字节。在我们校验数据时,需要用相同的密钥和数据进行加密,然后与数据库中存放的加密结果进行比对才能得到数据的准确性,而往往数据库中存放的是密钥的内容(字节数组或字符串),在加密过程中用到的是。2.当输入内容不一样时,输出内容大概率不一样。

2023-07-10 19:31:37 1261 2

原创 java实现发送邮件

在上面的代码中,我们将与服务器连接的信息封装在Properties对象中,在创建Session对象时,需要传入两个参数 ,第一个参数就是我们封装的服务器连接信息,第二个参数为用户认证对象,因为Authenticator为抽象类,所以创建一个匿名子类对象并将邮箱账号和授权码传入。在生活中,我们经常会发送带有附件的邮件,接下来,我们就通过java程序发送带有附件的邮件,要发送带有附件的邮件,不能直接设置正文内容,需要用到。我们有时候需要在邮件的正文中嵌套图片,那么这个功能在java程序中如何实现呢?

2023-07-08 18:51:12 6616 4

原创 FTP协议网络编程

1概述:FTP协议为文件传输协议,在java程序中可以作为客户端将文件上传到FTP服务器中,也可以从服务器中下载文件到本地磁盘。(3)启动服务器,并在浏览器地址栏中输入服务器的主机号和端口,通过自己设置的账号和密码访问服务器。方法上传文件,第一个参数为上传到服务器后在服务器中的名称,第二个参数为读取本地文件的输入流。文件上传时,连接和登录服务器与上面的代码一致,在上传文件之前,需要通过FTPClient的。方法下载文件,第一个参数为文件在服务器中的名称,第二个参数为存放下载文件的输出流。

2023-07-08 16:22:30 216

原创 Super关键字的用法

其实,在子类Son中,不管我们使用super.name,this.name还是name,编译器都会定位到父类Base的name属性,所以在访问属性的时候,可以不使用super关键字。可以看到我们在上面的代码中没有显式的调用父类的构造方法,那是因为编译器在编译过程中,会自动在第一行加上super()调用父类默认的无参构造。1.概述:在面向对象中,继承是三大特征之一,继承过程中,子类如果想调用父类的属性和行为可以通过super关键字调用,在java中super关键字最常用的是调用父类的构造方法。

2023-07-07 21:19:42 70 1

原创 this关键字用法

在上面的代码中,我们在Student类的构造器中没有使用this关键字调用成员变量,实例化出对象,发现值没有赋给Student的属性,这是因为局部变量与成员变量同名,如果直接使用变量名,编译器会调用最近的变量(就近原则),所以构造器中并不是给成员变量赋值,而是变成了局部变量给局部变量赋值。在内部类中,this关键字代表当前内部类的对象,所以在内部类中使用this.属性名,使用的都是内部类的属性,如果想在内部类中使用外部类的属性或方法,可以通过。1.this.属性名/方法名调用成员变量或方法。

2023-06-28 17:45:05 47 1

原创 final关键字用法

从运行结果中可以看出,被final修饰的引用类型数据变量,值可以被正常修改,但当重新分配内存空间时,编译不通过,报错信息与上面修改基本数据类型值的时候一致。1.概述:在java中,final关键字可以用来修饰类,方法和变量,final为最终的意思,通常通过final关键字修饰的变量就变成了常量。当你不希望一个类被继承的时候,就可以使用final修饰这个类,这样,该类就不能被任何一个类继承。final修饰类时,表明类不能被继承,修饰方法时,说明该方法为最终方法,即不能被子类重写。2.final修饰类。

2023-06-27 21:24:58 66 1

原创 方法重写与方法重载

在上面的Student类中添加4个方法名全为shout的方法,由于传参的不同形成了重载,并没有报错,一个类中是不能出现方法名和参数列表都一致的两个方法。1.概述:在java中,面向对象的三大特征中的多态主要由方法重写和方法重载以及向上或向下转型实现,接下来,就让我们了解一下方法的重写和重载。1.方法重写是对父类的方法进行重新实现,方法重载是根据传参的不同,内部的实现逻辑也就不同。方法的重写是发生在继承或实现的关系中,由子类重写父类的方法或实现类重写接口的方法,其。,与访问修饰符无关,其构造方法可以被重载。

2023-06-26 14:30:40 106 1

原创 抽象类的定义和特点

1.概述 在面向对象中有三大特征,分别为封装,继承,多态.继承往往都是具体子类继承共同的父类,在我们定义父类时,因为不同子类的行为具体实现不同,会出现方法不知道怎么具体实现的情况,这时候,我们就可以将这个方法定义成抽象方法,当然这个父类也就必须为抽象类。例如,鸟的种类有很多,不同的鸟飞行的行为不同,有的鸟翱翔,有的鸟一飞冲天,我们可以定义Brid这个父类代表所有的鸟类,每个鸟都有fly()这个行为,而每个鸟的行为是不一样的,所以fly()方法需要定义为抽象方法。5.抽象类的子类必须重写所有的抽象方法。

2023-06-21 11:55:07 137

原创 HashMap的数据结构

1.概述:在java集合中,集合分为单列集合和键值对集合,ArrayList和LinkedList是常用的单列集合,而HashMap是常用的键值对集合,接下来就让我们一起来了解一下HashMap的底层数据结构。,将e的value改为当前存放的value,返回原来的value,再判断数组是否需要扩容。寻找存放位置,否则通过遍历该位置上的单链表,如果到达最后一个结点,就将封装的Node对象。,然后判断链表的结点数是否达到最大,如果达到最大结点数,就会调用。,如果达到64,才会进行转化,否则,

2023-05-21 22:45:29 104

原创 ArrayList扩容方式的理解

我们可以事先估算要存放数据的容量,通过该有参构造初始化容量,避免进行频繁的扩容,因为扩容会复制大量的元素,如果进行频繁的扩容,就会导致性能下降。我们看到ArrayList有两个有参构造,第一个有参构造方法的参数是int类型的initialCapacity,表示初始化容量,如果initialCapacity大于0,就会为elementData数组分配initialCapacity大小的空间,initialCapacity等于0,则将成员属性。,如果新的容量不够,则以最小容量作为新的容量扩容,并且会将原来。

2023-04-21 18:05:52 136

原创 LinkedList源代码阅读

在LinkedList中存放的是每一个Node对象,Node对象中的next和prev分别指向它的后一个结点和前一个结点,item用来存放数据。指向同一个结点,需要将该结点赋值给first,如果不是第一次添加结点,只需要将原来尾结点的下一结点指向要添加的结点即可。4.如果第一步获取的尾结点为null,说明这是第一次添加结点,当前链表中只有一个结点,删除元素前[A1, A2, A3, A4, A5, A6],再将x.next指为null,将x.data返回。删除元素后[A1, A2, A3, A5, A6]

2023-04-21 18:04:08 163 3

空空如也

空空如也

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

TA关注的人

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