自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 JVM常见知识点

在《深入理解Java虚拟机》一书中,介绍了JVM的相关特性。

2025-01-25 23:31:53 1665

原创 IP协议特性

在网络层中,最重要的协议就是IP协议,IP协议也有两个特性,即和。

2025-01-22 21:22:01 716

原创 IP协议格式

在传输层中有两个重要的协议,分别为UDP和TCP。UDP追求高效的效率,TCP追求更可靠的传输。但是这两个协议都太极端了,有没有一个协议可以在保证可靠性的同时又不失较高的效率。针对上面的问题,网络层的IP协议是更好的解决方案。

2025-01-22 07:38:08 415

原创 TCP报文格式与核心机制

TCP与UDP都是传输层的重要协议,TCP的特性包括有连接、可靠传输、面向字节流、全双工。

2025-01-19 15:00:15 1129

原创 UDP报文格式

UDP是传输层的一个重要协议,他的特性有面向数据报、无连接、不可靠传输、全双工。

2025-01-16 16:04:23 626

原创 HTTPS加密原理

HTTPS是在HTTP的基础上加上SSL / TSL安全协议,SSL / TSL也是应用层协议,专门负责数据加密。对HTTP进行加密后,原本明文传输的数据就变成密文传输了。HTTP加密分为两种情况,即对称加密和非对称加密。

2025-01-16 00:32:40 777

原创 HTTP协议

HTTP协议是应用层的一个重要协议。

2025-01-14 22:51:33 709

原创 IO多路复用简单介绍

由于在绝大情况下,客户端都是沉默的,线程只需要在客户端发来请求时进行处理就行了,这个请求结束后,这个线程就可以处理其他客户端发来的请求,同时,多个客户端在同一时间发送请求的概率较小。场景二就相当于只有一个线程在工作,先完成A,再完成B,最后完成C,但由于每一个事务都有自己的执行时间,相当于这个线程花费了三倍的时间,虽然节省了内存资源,但是时间更长了;场景三:同样的,由小明买三个人的食物,但这次小明先去买A,在等A做好的同时,再去买B,在等A和B做好的同时,去买C,这样也能买到三人想吃的食物。

2025-01-14 15:58:08 195

原创 UDP、TCP特性

在传输层中,最重要的两个协议就是UDP协议和TCP协议,其中TCP协议更为重要。对于TCP协议,其性质为;对于UDP协议,其性质为。下面针对这几个性质展开对比讨论。

2025-01-13 16:13:26 713

原创 网络数据通信基本流程

网络通信就是发送数据、接收数据、处理数据的过程,发送数据时要读数据进行处理(封装),接收数据时也要对数据进行处理(分用),1)封装对数据进行加工处理,如添加报头或报尾;2)分用对封装后的数据进行处理,提取出源数据,即封装的逆向过程。3)结构化数据类似于C语言的结构体;4)序列化、反序列化时,将结构化数据转化为字符串/二进制bit流;时,将字符串/二进制bit流转化为结构体数据;

2025-01-12 22:13:34 920

原创 网络基本概念

用来标识网络中一台设备的位置,类似于生活中快递地址。

2025-01-12 16:22:46 407

原创 Java中的集合类与线程安全的讨论

ArrayList是线程不安全的,可以在单线程中使用,在多线程中可以根据代码选择合适的时机进行加锁,实现线程安全的操作,但对代码能力要求较高。

2024-11-15 23:15:47 514

原创 Java中创建线程中的几种方式

当我们实现了Callable接口后,由于Thread的构造方法不能直接传入callable对象,于是需要使用FutuerTask过度一下,将callable对象传入 FutureTask中,再将futureTask对象传入Thread中,就完成了线程的创建过程。由于Thread本身不提供获取返回值的方法,于是就需要使用FutureTask中的get方法来获取call的返回值,在call的结果计算出来之前,其他线程就会产生阻塞,包括main线程。

2024-11-13 18:06:10 433

原创 信号量(Semaphore)介绍

在Semaphore中,有两个处理资源的方法,acpuire和release。acpuire可以用来获取资源,release可以用来释放资源,现假设Semaphor中由100个资源,每执行一次acquire,就会消耗一个资源,每执行一次release,就会释放一个资源,当将100个资源全部申请完后,若再继续申请就会进行阻塞等待。

2024-11-13 16:45:24 378

原创 LeetCode76.最小覆盖子串

遍历s,将s中的字ch存入数组sArr中,若sArr[ch] <= tArr[ch],则说明ch是一个有效字符,将count++;定义两个指针left和right,均指向s的第一个字符,将right指向的字符in存放到sArr中,锁sArr[in] <= tArr[in],就说明in是一个有效字符,将count++;可以用一个数组tArr存下t中每个字符的个数,用count表示有效字符的个数;题目意思为在s中找到一个最短的子串,这个子串要求要包含t中所有的字符;

2024-10-31 00:41:29 418

原创 LeetCode30.串联所有单词的子串

让right与left之间的距离大于等于size * strLen时,就移动left,取出left与left + strLen之间的子串subString1,若hashMap1中subString1的值小于等于hashMap中的值,就表示subString1是一个有效的子串,将count--,left向右移动strLen,反之直接将left向右移动strLen,当count与size相等时,就说明这个子串符合条件,将left存入结果集中;

2024-10-30 23:27:34 888

原创 synchronized与ReentrantLock的区别

ReetrantLock是可重入锁,synchronized也是可重入锁,即可以频繁加锁同时不造成死锁;ReetrantLock是一个类,在使用时要创建实例locker;locker.lock()即加锁,locker.unlock()即解锁,将可能会引发线程安全的代码放到这两个之间;

2024-10-30 01:01:55 273

原创 CAS中的ABA问题

现有两个线程thread1和thread2,有一个变量count = 1;现让thread1先后两次获取count的值,发现都是1,但可能thread2对count进行了修改,但在thread1第二次获取count的值之前又将count的值改回了1,那么thread1第二次获取到的count的值就是1,虽然thread1先后两次获取到的count的值相等,但count的值发生了改变;

2024-10-27 22:21:21 333

原创 LeetCode438.找到字符串中所有字母异位词

先让right向右移动,将right指向的字符存放到arrSub中,若该字符在arrSub中的值小于或等于在arrP中的值,就说明这个字符是一个有效字符,将count++;先定义两个指针left与right,两指针均指向s的第一个字符,再定义一个数组arrP用来存放p字符的种类与个数,用count来记录s子串中有效字符的个数,用数组arrSub存放子串中字符的种类与个数;将题目意思转换后,即为在s中找到与p相同长度的字符串并且其中的字符要一一对应,但字符顺序可以改变;

2024-10-27 01:27:19 532

原创 常见的锁策略

现有一把锁,有100个线程同时竞争这把锁,每一个线程加锁的频率都很高,一个线程尝试加锁时,另一个线程大概率会占有这把锁;解决方案:使用重量级锁,由于悲观锁的竞争很激烈,就导致线程阻塞时间过长,效率更低下;

2024-10-26 21:30:33 1069

原创 LeetCode904.水果成篮

先对这个数组进行双重遍历,内层循环从外层循环的下一个数开始遍历,在进入外层循环之前,先将计数器加一,再将外层循环的起始水果类型放入链表中,在内层循环中,先判断这个水果类型在链表中是否存在,若存在,将计数器加一;我们先让right指针向右移动,若right指向的水果类型再数组中有没有,即若数组中对应类型的值为0,就将kind++,并将arr[kind]++;由于题目中要求对水果的种类进行判断,于是可以用一个链表来存储水果的种类;我们可以在第一次判断完成之后,只将3类型的水果移出篮子即可。

2024-10-26 02:20:25 444

原创 线程池——Java

在字符串常量池中,字符串常量在java程序运行之前就已经创建好了,等程序运行起来后,就可以直接从常量池中拿到字符串并加载到内存中,这样的设计就省下了字符串的构造与销毁的内存开销。

2024-10-25 23:06:08 1198

原创 阻塞队列——Java

阻塞队列也是队列的一种,但是带有阻塞性质。但是这种阻塞情况是极端情况,在生产、消费者模型中,当生产者与消费者不协调时,就会出现阻塞情况。

2024-10-25 21:42:08 507

原创 工厂模式介绍

工厂模式也是一种设计模式,下面有一个案例可以解释问什么要使用工厂模式:在数学中,我们要表示一个二维平面的点时,可以使用平面直角坐标系和极坐标系://横坐标或半径//纵坐标或角度this.a = x;this.b = y;this.a = r;this.b = o;由于两个构造方法的方法名、参数列表均相同,就无法构成重载,但有时又需要使用两种构造方法,这时就可以引入工厂模式。

2024-10-25 00:33:41 441

原创 单例模式介绍

单例模式是针对一个类的设计方式而言,若该类使用了单例模式,那么再整个程序中这个类只会有一个对象,当创建第二个对象时就会直接报错。即使只能创建一个对象,也会存在例外,即可以通过反射创建第二个实例,但这种情况也基本上不会见到。

2024-10-25 00:14:46 918

原创 操作不是原子的与指令重排序

这两个都会引发线程安全问题。

2024-10-20 10:08:52 292

原创 线程安全问题的原因和解决方案

在编写多线程代码时,时常会出现预期结果与实际觉果不相符的情景,其中很大一部分是由于多线程的安全问题引起的,下面就谈谈为什么会产生线程安全问题以及都有哪些解决方案。

2024-10-20 00:32:28 1392

原创 LeetCode1658.将x减到0的最小操作数

题目的要求为要在数组的首、尾找到最少的若干个数,使得这些数的和等于x,若直接从题目条件入手,会发现要一会判断数组首元素,一会又要判断数组最后一个元素,就会非常麻烦,于是我们可以转变题目的意思,即在数组中找到若干个相邻的数使得这些数的和等于数组全部元素的和减去目标值;先用sum1加上right指向的元素,再将right向右移动一位,当sum1>sum - x时,用sum1减去left指向的元素,再将left向右移动,若存在sum1 == sum - x时,更新count的值,之后再次进行循环;

2024-10-18 23:47:43 504

原创 LeetCode1004.最大连续1的个数

由常规解法可知,在第一轮遍历的时候,结果为“1 1 1 0 0”,在下一轮遍历时,从第二个1开始,但由于“1 1 0 0”在第一轮遍历时已经判断为符合条件的数据,就会发生重复判断,因此,可以使用滑动窗口解决问题。让right开始向后移动,当right指向的元素为1时,继续向后移动,当right指向的元素为0时,将count加一;先定义两个指针left和right,均指向第一个元素,再定义一个变量count记录子串中0的个数;1.常规解法(会超时)

2024-10-18 22:15:56 469

原创 LeetCode3.无重复字符的最长子串

在常规解法中可以看到,第一次的子串为abc,第二次的子串为bca,而两个子串有重复的部分,即为bc,那么在第一次判断完成之后,由于下一次进来的a与子串中的a重复,于是就可以将1串中的字符逐个去除直到子串中没有a,在这种条件下,就可以使用滑动窗口来解题。先定义两个指针left和right,两指针均指向第一个字符,再定义一个用来计数的字符数组,范围为0-127;希望读者能够提出建议!

2024-10-16 00:07:20 345

原创 LeetCode209.长度最小的子数组

先让right向右移动,并用sum加上right指向的元素,当sum>=target时,可以求出符合条件的子数组的长度,这时可以让left向右移动,用sum减去left指向的元素,根据单调性,sum会越减越小,当sum<target时,left停止移动,继续上面的操作,当right指向数组外面时,最后的len就是结果。使用该方法的前提是数组中的元素全是大于等于0的,可以使用单调性解题。在上述代码中,使用了flag来判断是否有符合条件的子数组。1.常规解法(会超时)

2024-10-15 22:29:15 448

原创 线程的六种状态

线程状态一共分为NEW, RUNNABLE, TERMINATED, TIMED_WAITTING, WAITTING, BLOCKED.使用join后,main线程(主线程)等待thread线程执行结束后才能执行。可以在线程运行的时候使用sleep(1000)方法是该线程休眠1000ms。在java中,使用getStart方法可以获取到当前线程的状态。线程阻塞(不参与CPU调度,不继续执行),但阻塞时间要是有限的。2)线程随时可以去CPU上执行。线程结束但对象还在。

2024-10-15 00:15:59 188

原创 LeetCode18.四数之和

现保持p1和p2不动,让left与right相向运动,若(long)nums[left] + (long)nums[right] + (long)nums[p1] + (long)nums[p2] == target,则将这个四元组添加到结果中,由于不能出现出重复的四元组,就需要去除与left和right指向元素相同的元素;先定义四个指针p1,p2,left,right,p1指向最后一个数,p2指向倒数第二个数,left指向第一个数,right指向p2前一个数;希望读者指出不足之处!1.常规解法(会超时)

2024-10-12 14:09:04 1084

原创 线程中的join

main线程被阻塞,thread1与thread2先运行,由于thread1先于thread2结束,则thread2结束后“thread1.join()”是无效语句,mian接着运行。会使main线程阻塞,thread1与thread2同时运行,由于thread1运行时间短,则thread1会先结束,结束后thread2与main同时运行。会使mian线程阻塞,thread1与thread2同时运行,thread1结束后,thread2依然在运行,thread2结束后main才会运行。

2024-10-11 23:51:05 185

原创 LeetCode15.三数之和

去重:若使用contains判断三元组是否重复,代码就会超时,这时我们就要在nums[left] + nums[right] + nums[p] == 0时,将与left和right指向的数的相同的数去掉,由于这个数组是有序的,那么相同的数就会聚集在一起,只需要使用while循环去重即可;定义三个指针left,right,p,先将p固定在最后一个数,left在第一个数的位置,right在倒数第二个数的位置,接下来在每一轮循环中,保持p不动,只要移动left和right即可。希望大家积极指出不足之处。

2024-10-10 23:37:23 672

原创 Thread类的基本用法

注意,在使用lambda表达式时,若要使用外面的变量(main中的局部变量但不在lambda中的变量),则该变量不能被修改,因为使用时会触发变量捕获,由于lambda是回调函数,执行时机是很久之后(操作系统真正创建出线程后才会执行),有可能main先执行完,导致该变量在使用前就被销毁,于是该变量不能被修改。在上述代码中,都使用了Thread来创建线程thread,再使用start()方法来启动线程,虽然thread.run()也能使程序运行,但本质上并没有创建出一个新的线程,只是普通的方法调用。

2024-10-10 21:47:58 405

原创 进程,线程的区别与联系

只有第一个线程创建时(即和进程一起创建的时候)才申请资源,后续的线程创建都不申请资源;只有所有的线程都销毁(即进程销毁)才真正释放资源,运行过程中销毁某个线程也不会释放资源;进程内的线程会共享进程的内存资源、硬盘资源、网络带宽等;进程即运行起来的程序,由PCB构成,其中有若干属性。线程相当于一个要执行的任务,或是运行的一段代码指令。一个线程出现异常,若处理不当,就会带走整个进程。创建或销毁进程开销大,尤其是频繁的创建销毁;进程之间涉及到的资源时独立的,相对稳定;进程创建和销毁都需要申请资源;

2024-10-08 21:57:14 236

原创 LeetCode.179查找总价格为目标值的两个商品

判断left和right指向元素的和与目标值的大小关系,若和大于目标值,以right为基准,left右边的值均大于left指向的值,根据单调性,left右边的值与right相加的和均大于目标值,就需要让right向左移动一位;若和小于目标值,以left为基准,right左边的值与left的和均小于目标值,就需要让left向右移动一位。为了方便,我们可以先将数组从小到大排序,再定义指针left和right,left指向首元素,right指向末元素。1.常规解法(会超时)希望读者能指点一二!

2024-10-05 15:23:02 223

原创 LeetCode.611有效三角形的个数

保持p不动,判断left和right指向的元素之和与p的大小关系,若和大于p指向的元素,那么对于left、right、p指向的元素构成的三元组是能构成三角形的,同时,以right为基准,left到right之间的元素均大于left指向的元素,由单调性可知,left到right之间的元素与right相加的和也一定大于p指向的元素,那么count就要加上right - left,再将right向左移动一位;当right

2024-10-05 14:28:21 481

原创 LeetCode11.盛水最多的容器

定义两个指针left和right,left指向数组首元素。right指向数组最后一个元素,先求出left和right之间能盛多少水,再比较left和right指向的值,若left指向的值小于right指向的值,根据木桶效应(一个水桶能盛的最多的水取决于最短的那根木板)那么right左边的值由于木板长度不会变大(最大就是left指向的值),而且由于单调性,left与right之间的距离也会缩短,就导致之后盛的水一定没有当前left位置盛的水多,那么就应该向又移动left,以改变木板的最短长度;

2024-10-03 14:12:26 418

空空如也

空空如也

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

TA关注的人

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