- 博客(51)
- 收藏
- 关注
原创 TCP/UDP协议深度解析(三):TCP流量控制的魔法—滑动窗口、拥塞控制与ACK的智慧
本文详细剖析TCP协议中保障高效可靠传输的四大核心机制:1)滑动窗口实现批量数据传输,通过动态窗口调整兼顾效率与可靠性;2)流量控制通过rwnd窗口动态调节发送速率,避免接收方缓冲区溢出;3)拥塞控制采用慢启动-拥塞避免算法智能适应网络状况;4)延时应答与捎带应答优化ACK机制,提升网络利用率。文章还探讨了零窗口探测、快重传等关键技术,揭示TCP如何在保证可靠性的同时实现高效传输。这些机制共同构成TCP协议的"智能神经系统",使其能优雅应对各种网络环境
2025-06-29 15:21:11
1163
27
原创 TCP/UDP协议深度解析(二):TCP连接管理全解,三次握手四次挥手的完整流程
🔍 TCP连接管理机制深度解析 🔍 本文深入剖析TCP协议中三次握手与四次挥手的核心机制: 1️⃣ 三次握手:通过SYN/ACK报文交互验证双方通信能力,协商初始序列号避免历史数据干扰,确保全双工连接可靠建立。关键点:必须三次才能完整确认收发能力,SYN报文合并ACK实现高效连接。 2️⃣ 四次挥手:分阶段关闭双向数据流,TIME_WAIT状态防止丢包导致连接异常(等待2MSL确保FIN重传)。特殊场景下ACK与FIN可能合并,但本质仍为四次交互。 3️⃣ 异常处理:探讨SYN Flood防御、RST暴
2025-06-25 20:36:32
1007
18
原创 TCP/UDP协议深度解析(一):UDP特性与TCP确认应答以及重传机制
本文深入解析了TCP与UDP两大传输层协议的核心特性。UDP作为"自由派"采用极简设计,具备无连接、不可靠传输等特点,适用于实时应用但存在64KB数据限制;TCP作为"保守派"通过确认应答(ACK)和超时重传(RTO)等十大机制构建可靠传输。文章重点剖析了TCP的报文结构、序号机制,以及两种重传策略:快速重传(基于重复ACK)和超时重传(动态计算RTO)。下期将探讨TCP连接管理的三次握手与四次挥手机制。
2025-06-24 18:50:12
1443
12
原创 网站安全必修课:图解HTTPS加密传输与证书验证机制
本文系统讲解HTTPS的三大安全基石:① 对称加密的高效传输 ② 非对称加密的安全密钥交换 ③ 数字证书的身份验证机制。通过图解方式揭示中间人攻击原理,详细分析数字证书如何通过CA机构、有效期、域名绑定、数字签名四重验证保障公钥真实性。最后探讨黑客可能突破的四种攻击路径,帮助开发者构建更安全的Web通信体系。
2025-06-08 13:21:09
1142
18
原创 HTTP协议详解:GET/POST、Cookie、状态码,一篇就够了!
本文通过Fiddler抓包实战,深入解析HTTP协议的请求/响应结构,揭秘GET与POST的本质区别,并详解常见状态码(200/404/500)的应用场景。附完整代码示例,助你快速掌握Web通信核心!
2025-06-04 21:08:08
991
9
原创 Java网络编程实战:TCP/UDP Socket通信详解与高并发服务器设计
深入讲解TCP可靠传输与UDP数据报的区别,提供完整Socket通信代码实现,涵盖ServerSocket多线程优化、粘包问题解决方案,以及accept()阻塞和IO流交互等核心技术,帮助开发者快速掌握高并发网络编程技巧。
2025-05-31 15:49:21
1165
5
原创 网络协议入门:TCP/IP五层模型如何实现全球数据传输?
本文介绍了计算机网络的基础概念,包括网络的定义、关键设备(路由器和交换机),以及IP地址和端口号的作用。重点讲解了网络协议的分层模型,对比了OSI七层模型和实际使用的TCP/IP五层模型,详细说明了各层的功能。文章还阐述了数据传输的封装和解析过程,以及数据如何在各层间传递。网络通信的核心在于协议分层,这种结构简化了复杂网络的管理,提高了灵活性和可维护性。
2025-05-28 16:29:06
1625
10
原创 开源项目跨平台桌宠 BongoCat,为桌面增添乐趣!
最值得推荐的一点就是,该项目具有穿透模式,已经可以设置透明度,在日常生活中一点不影响使用,这点真的非常值得称赞!
2025-05-25 21:17:30
757
6
原创 Java文件操作:从“Hello World”到“Hello File”
本文介绍了文件操作的基本概念和Java中的实现方法。主要内容包括:文件定义(广义/狭义)、文件分类(二进制/文本文件)、路径类型(绝对/相对路径)及Java文件操作API。文章详细讲解了Java中的文件系统操作(创建、删除等)和内容操作(读写),并对比了字节流与字符流的区别及适用场景。重点强调了流操作资源释放的重要性,推荐使用try-with-resources语法自动关闭资源。最后指出文本文件建议使用字符流,二进制文件建议使用字节流的原则。全文提供了丰富的代码示例和操作注意事项,适合Java开发者学习文件
2025-05-25 20:59:44
901
1
原创 【Java多线程】多线程状态下如何安全使用ArrayList以及哈希表
本文介绍了多线程环境下安全使用ArrayList和哈希表的几种方法。对于ArrayList,可通过手动加锁、Collections.synchronizedList()包装或使用CopyOnWriteArrayList实现线程安全,各有适用场景。对于哈希表,Hashtable通过全局锁保证安全但性能较差,而ConcurrentHashMap采用分段锁、原子类计数和渐进式扩容等优化手段,显著提升了并发性能。文章分析了每种方法的优缺点,帮助开发者根据实际场景选择合适的多线程安全方案。
2025-05-24 14:27:12
991
3
原创 【Java多线程】JUC其他常用组件
本文介绍了Java中的多线程编程相关工具,包括Callable、ReentrantLock、Semaphore和CountDownLatch。Callable用于定义带有返回值的任务,需通过FutureTask获取结果。ReentrantLock提供了比synchronized更灵活的锁机制,支持公平锁和tryLock方法。Semaphore用于管理资源访问,限制同时访问的线程数。CountDownLatch用于等待多个子任务完成,适用于任务拆分场景。
2025-05-22 21:30:34
1007
1
原创 Java原子类的实现原理 && CAS的使用以及缺陷
你的名字叫做小明,今天来到银行取取钱,但是你今天手抖了在取钱的时候多按了一次,还好银行是使用CAS来进行增减(假设!),它在第二次扣款时发现内存值和oldvalue值是不一致的,所以仅扣除了一次。你不由得感叹CAS的伟大。第二天,你又来取钱了,你今天又手抖了一次,取了两次100元,原本CAS是可以避免这个情况的,但是今天你的朋友此时此刻“恰巧”给你转了100元,使你的金额又变回了原样,CAS在第二次判断的时候呢发现你的钱没有变化,又给你扣了一次,这时你发现你只取出来100但是实际上少了200。
2025-05-22 20:15:24
1181
1
原创 【java八股文】深入浅出synchronized优化原理
如果检测到一连串连续的对同一个对象的加锁和解锁操作(即使没有竞争),JVM 可能会将这些操作合并为一个更大范围的加锁,减少锁的获取和释放次数,从而提高性能。这个判定比较保守,只有100%确认这个代码是单线程的时候才会触发,当判断不清楚的时候不会触发,因此不会出现判断逻辑错误导致的线程安全。编译器会判定,当前的这个代码逻辑是否真的需要加锁,如果确实不需要加锁,但是你写了synchronized,就会自动去掉。所谓偏向锁就是进行一个简单的标记,并不是真正的加锁,这个标记非常的轻量,相对于加锁高效的多。
2025-05-03 17:21:10
608
2
原创 面试官最爱问的Java锁策略,90%的人答不全!
在遇到竞争时,会进入阻塞状态等待内核唤醒,因此很难做到及时获取,但是这个过程不必一直消耗cpu,把cpu省下来干别的事情。在默认情况下他是非公平的状态,实现公平锁需要付出一些代价,比如说使用一个队列去记录各个线程获取锁的顺序。如果我们预测,线程尝试获取一个锁的时候,获取频率很低,这种情况一般称其为乐观情况,反之称其为悲观。乐观锁在遇到竞争时,可以即使获取到锁,悲观锁在遇到竞争时获取的概率较低。:在一个线程已经获取到锁的情况下,其他的任何线程尝试获取时都会产生互斥。做额外工作,例如让两个线程去竞争一个锁。
2025-05-03 16:50:24
874
1
原创 【Java多线程】计时器Timer/ScheduledExecutorService的使用
Timer 是 Java 提供的一个简单的任务调度工具(位于 java.util 包),用于在指定的时间执行任务(一次性或周期性执行)。:所有任务都在同一个线程中执行,如果一个任务执行时间过长,会影响其他任务的调度。:如果某个任务抛出未捕获的异常,整个 Timer 会终止,后续任务不会执行。如果任务执行时间超过 period,下一次任务会 立即开始(可能并发执行)。:如果系统时间被调整(如手动修改时间),可能导致任务执行不准确。:只需要在某个时间点执行一次的任务(如延迟初始化、超时任务)。
2025-05-03 14:47:32
853
1
原创 Java面试热门问题,一文带你彻底了解线程池~
例如一个点的坐标可以根据x,y来确定,也可以根据其到原点的距离r以及角度aph来确定,但是因为他们的参数类型都是double的所以无法在创建时实现两种并存。:属于设计模式的一种,因为构造方法的名称是固定的,要想提过不同的版本,就需要通过重载,但是有时候不一定可以构成重载。工厂方法的核心,通过静态方法,把构造对象new的过程,各种属性初始化的过程封装起来了。,在任务多的时候自动扩容成更多的线程,任务少的时候,把额外的线程干掉,节省资源。❌ 长时间阻塞的任务(如死循环任务,可能导致线程池耗尽)
2025-05-01 21:14:35
885
原创 手写一个高性能阻塞队列,彻底掌握生产者-消费者模型
阻塞队列最重要的特性是,当队列为空时再获取值会陷入阻塞状态,直到再插入出新的值。不同的是poll和offer是queue接口实现的方法,并不能实现阻塞等待的效果,如果为空或者为满他俩将会将会丢弃或者返回一个空值。生产者消费者模型 是一种经典的 多线程协作模式,用于解决 生产数据 和 消费数据 的两类线程之间的 高效协同问题。存储数据的中间容器,用于 平衡生产与消费速度差异,通常是一个 线程安全的队列(如 阻塞队列)。BlockingQueue是阻塞队列的一个接口,内部定义了它的基础实现方法。
2025-04-27 21:50:54
874
3
原创 2025蓝桥省赛c++B组第二场题解
这场的题目非常的简单啊,至于为什么有第二场,因为当时河北正在刮大风被迫停止了QwQ,个人感觉是历年来最简单的一场,如果有什么不足之处,还望补充。
2025-04-26 20:10:33
4739
11
原创 一文带你了解单例模式及其逐步优化~
这个问题源于我们的优化导致的,我们在上述使用了双重if,而我们的锁是在第二个if里面的,因此第一个if是不受锁的影响,导致了其他线程的可乘之机。懒和饿是相对的,他会尽可能晚的创建实例,懒在计算机中并不是一个贬义词,尽晚的使用反而会减少实例对计算机的负荷。他在getInstace的时候涉及读和写两种操作,在多线程下可能会产生bug,因此他是线程不安全的。在懒汉模式中,虽然赋值是原子性的操作,但是加上if整体上就不是了,因此我们需要对其进行加锁操作。不同的是他的创建是在getinstance的时候进行的。
2025-04-25 17:07:40
609
原创 Java多线程的暗号密码:5分钟掌握wait/notify
在执行wait操作的时候是必须要加上锁的,代码进入 wait,就会先释放锁,并且阻塞等待如果其他线程做完了必要的工作,调用 notify 唤醒这个 wait 线程wait 就会解除阻塞, 重新获取到锁. 继续执行并返回。务必要确保, 先 wait,后 notify,才有作用如果是先 notify, 后 wait, 此时 wait 无法被唤醒.notify 的这个线程,也没有副作用(notify 一个没有在 wait 的对象,不会报错)wait和notify是Object的方法,任意一个类都可以使用。
2025-04-23 20:57:22
378
2
原创 java多线程的内存可见性问题,volatile是干什么的?
jvm不知道什么时候才会进行修改,而且它的值始终没变所以将读取内存优化成了读取寄存器,因为寄存器比内存快,而这就导致了它无法识别到内存的修改,导致了误判。但是sleep()方法代价太大了,因此引用了volatile(易变的)关键字,既然你编译器无法判别要不要优化,我就手动判别,当它修饰某个关键字的时候,不会把它优化成读寄存器。编译器,虽然声称优化操作,是能够保证逻辑不变,尤其是在多线程的程序中,编译器的判断可能出现失误可能导致编译器的优化,使优化后的逻辑,和优化前的逻辑出现细节上的偏差。
2025-04-21 17:50:10
500
原创 多线程出bug不知道如何调试?java线程几种常见状态
当你的多线程代码结构很复杂的时候很难找出bug的原因所在,此时我们可以使用getState()方法获取该线程当前的状态,通过观察其状态是阻塞了还是因为没有启动等原因导致的。
2025-04-21 13:24:37
284
原创 【java多线程】线程安全是如何保证的?什么是死锁?含大量图解~~
在java中,我们使用synchronized对要执行的任务进行加锁,synchronized在汉语中是同步的意思,但是在里面是互斥的含义。讲了这么多,锁也并不是越多越好的!它的实现原理是让锁对象内部保存当前线程持有那把锁,当后续线程针对这个锁加锁的时候进行对比,如果是同一个就计数器+1,否则正常运行。CPU的线程调度是随机的,程序员无法控制它,所以在执行的时候会有无限的情况,因此cnt的值永远也不会为100000。锁:和生活中的锁一样的概念,互斥、排他,一旦把锁加上了,其他人想要加锁,就得阻塞等待。
2025-04-05 19:46:44
668
原创 从“单线程社畜“到“多线程时间管理大师“的进化之路
多线程有什么作用?想象一下,你是一个餐厅里唯一的服务员,既要接单、上菜,又要收拾桌子、结账……忙得脚不沾地,顾客却还在抱怨“太慢了!”(程序卡成PPT)。这时候,多线程就像老板突然给你雇了几个帮手:线程A专门接单,线程B负责上菜,线程C埋头算账……大家各司其职,效率直接起飞!顾客满意了(用户体验流畅),老板赚钱了(程序性能提升),你甚至能偷闲刷个手机(CPU不再摸鱼)。首先我们要了解一下什么是进程线程在创建和销毁时,开销更小,相当于一个轻量级的进程。
2025-03-30 16:23:36
798
原创 知识大扫盲!一台计算机是如何运行的?
在早期没有操作系统的时候计算机的使用门槛非常高,任何操作都是通过指令来进行的,就拿开机来说,你需要写一大段代码来执行,所谓的计算机启动起来无非就是让CPU加电后开始执行一段初始化代码,为你真正的程序运行铺路,这一大段代码就是所谓的内核,kernel。这里的输入和输出是相对于cpu来说的,要进入cpu的数据都是输入的,要离开cpu的数据都是输出的,比如键盘就是输入设备,显示屏就是输出设备。:常说的几核几核电脑,就是指的cpu的核心数量,当单核的性能难以提升的时候,开发出了多核技术来提升cpu的整体性能。
2025-03-26 17:36:23
681
原创 pta L2-002 链表去重 c++
给定一个带整数键值的链表L,你需要把其中绝对值重复的键值结点删掉。即对每个键值K,只有第一个绝对值等于K的结点被保留。同时,所有被删除的结点须被保存在另一个链表上。例如给定L为 21→-15→-15→-7→15,你需要输出去重后的链表 21→-15→-7,还有被删除的链表 -15→15。
2025-01-08 22:46:55
220
原创 【蓝桥真题练习】蓝桥杯 2021 国赛 A 组 E 题
小蓝发现, 这个数列前 11 项是整数 11 , 接下来 22 项是整数 11 至 22 , 接下来 33 项是整数 11 至 33 , 接下来 44 项是整数 11 至 44 , 依次类推。我们可以使用类似于前缀和的方法来解题,既前r个数字和减去前l个数字和。同样的道理,我们知道了它的行数以及它一维的位置,可以得出它的列坐标。前n行的和为:n * (n + 1) * (n + 2) / 6。首先我们观察这个数列,我们可以把他分解成一个三角形的二维数组。小蓝想知道, 这个数列中, 连续一段的和是多少。
2025-01-07 12:49:08
443
原创 c++初阶 string的底层实现
首先可以明确的是string的底层结构是字符串数组,但是由于字符串数组中是使用。来终止的,因此他实际的存储空间是要比显示的多一个的。声明:非纯手搓,运用到了部分c语言的函数。
2024-08-06 00:57:35
554
原创 【计数排序】一个效率极高还简单的排序算法
它的优势在于在对一定范围内的整数排序时,复杂度为O(n+k)(其中k是整数的范围),快于任何比较排序算法。计数排序的思想类似于哈希表中的直接定址法,在给定的一组序列中,先找出该序列中的最大值和最小值,从而确定需要开辟多大的辅助空间,每一个数在对应的辅助空间中都有唯一的下标。二、从头到尾遍历辅助空间的下标,如果它的数值不为0就将它次数个下标复制给原数组(因为下标代表原数组的值),又因为它是从头到尾遍历的,所以使用此种方法可以排序。一样大的空间,并记录原数组每个值的个数,类似于哈希的映射。
2024-04-25 20:12:08
456
1
原创 【算法精讲】一篇让你掌握前缀和算法(附图解和不少题目练习~~)
前缀和算法是一种用空间换时间的算法,他常常用于解决某些题目或者作为某些高级算法的组成部分。例如:让你求某个矩阵(一维)的子矩阵的最大值,如果使用暴力解法它的时间复杂度将会是O(n^2) ,但如果使用该算法就可以使其时间复杂度降低一个维度也就是O(N).
2024-03-17 20:21:22
10104
4
原创 【C++入门】一篇带你了解类与对象~
C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如:在数据结构初阶中,用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现,会发现struct中也可以定义函数在c++语言中,我们更喜欢用类(class)来代替struct的存在,它相比struct来说完善了很多的内容,功能也更加丰富,比如说构造函数析构函数等,后面我会再写文章来讲解这一方面。class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分。
2024-01-30 22:14:49
1110
1
原创 【算法精讲】选择排序、堆排序(C语言)
直接插入排序是一种简单的排序算法,它将数组分为有序和无序两部分,和插入排序的思路有些类似。堆排序是直接选择排序的进阶版,他在其原本的思想上进行了优化。每次遍历找最大值和最小值,把最大值放后面,最小值放前面。下面的内容涉及一部分数据结构堆的知识,不适合新手学习。时间复杂度:O( N * logN)时间复杂度:O( N^2)
2024-01-27 11:43:54
418
原创 【手撕排序算法】直接插入排序、希尔排序,有详细图解
直接插入排序是一种简单的排序方法,它的思路就像是插扑克牌一样,每次排序一个,最终排序完成。
2024-01-25 19:16:53
516
1
原创 【去重算法】有序去重和无序去重,C语言版
2.如果两个指向的数大小是不同的,则维护空间++,并且把新的数加进去。2.不同的是判断是否重复,每一次判断都需要在已经去重的范围里循环一遍。1.双指针方法,一个用来遍历整体数组,另一个用来维护去重后的空间。纸上得来终觉浅,绝知此事要躬行。时间复杂度:O(N^2)时间复杂度:O(N)
2024-01-25 15:37:33
685
1
原创 【c++入门】内联函数inline:弥补宏定义的不足
2.另外,内联函数对于编译器来说只是一种请求,内不内联取决于编译器,比如说:如果你的函数超过了75行,那么编译器就会驳回你的请求,对于递归的函数编译器也是不会处理的。相比于没加inline的函数,加了inline的函数直接在main函数里面展开,而没有加的需要根据地址去转到函数位置,建立新的栈帧更加消耗性能。的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。这一概念,不仅吸收了宏的优点,还尽可能的优化了缺点。
2024-01-24 18:56:11
441
1
原创 【c++入门】指针的好盆友:引用
作为函数的参数:当函数需要修改其参数的值时,可以将引用作为参数传递给函数。这样,函数对引用的操作实际上是对原始变量的操作,而不是对原始变量的副本进行操作。这种方式可以避免数据的拷贝,提高效率。简化指针操作:通过引用,可以更简洁地操作指针。例如,可以将一个数组的引用传递给函数,使得函数可以直接访问数组元素,而不需要使用指针来解引用。作为函数的返回值:可以将引用作为函数的返回值。当函数返回一个临时对象时,可以通过引用返回该临时对象,避免了返回临时对象所占用的存储空间被重复使用的情况。
2024-01-23 20:24:52
1363
1
原创 【c++入门】缺省参数 && 重载函数
所谓缺省参数,其实和普通参数区别不大,但是需要在函数定义的时候初始化一下,上述代码中的,a便是缺省参数,而参数完全都是缺省参数的函数就叫做缺省函数。在c语言中,函数的传参要和函数的形参一一对应,相应的它的使用就很死板,所以在c++中祖师爷引入了缺省参数这一概念,灵活了函数的使用。在结果中,我们可以发现如果我们在这个参数上传了值,那么那个参数就是传的值,若没有传参则是函数参数定义的初始值。这三个函数的名字是相同的,但由于类型不同,所以其实这可以算是三个不同的函数。但是和缺省函数不同的是,非缺省参数的位置。
2024-01-21 22:38:42
373
1
原创 【c++入门】域的认识
所谓域就是值一块独特的领域,这块领域包括它的所属成员(一个常量或者一个函数均可)。我们先不管这串代码是什么意思,我们后文会讲解到。在这串代码中我们创建了两个域,这两个域虽然都有成员x,但这两个x是相互独立的存在。当我们使用领域的所属成员时,我们需要再前面声明它是谁家的x,这就相当于告诉计算机:你给我去这个地方找人去,找不到就别回来啦。
2024-01-17 16:40:13
779
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人