- 博客(65)
- 收藏
- 关注
原创 常见的锁策略
本文介绍了Java中自定义锁的实现策略及相关优化机制。主要内容包括:1.六种锁策略(乐观/悲观锁、轻量/重量级锁、读写锁、可重入锁、公平锁);2.锁消除优化机制;3.锁升级过程(无锁→偏向锁→轻量级锁→重量级锁);4.锁粗化技术。文章通过具体案例说明如何根据应用场景选择合适的锁策略,并分析了各种锁的特性及适用场景,旨在帮助开发者优化多线程程序的性能。
2025-05-26 13:44:25
738
原创 多线程初阶(2)
1.锁具有互斥性(锁的基本特性)当一个锁被一个线程获取之后,当别的线程想要获取这个锁的时候,会线程阻塞。2.锁不可抢占(锁的基本特性)当这个锁已经被获取时,别的线程是不能强行抢占这个锁的, 必须等待获取。3.请求和保持当一个线程已经有至少一个锁的时候,尝试获取别的锁遇到阻塞,这时候该线程也不会放弃原来的锁。4.循环等待线程1等待线程2,线程2等待线程3,线程3等待线程4,线程4等待线程5,线程5等待线程1,这样就产生了死循环。
2025-05-09 00:04:57
656
原创 多线程初阶(1)
在使用计算机的过程中我们打开一个进程和销毁一个进程的频率会非常高,对于我们日常使用的电脑来说可能不太明显,设想一下,对于百度的服务端来说,每时每刻都会收到来自全球的客户端的创建线程的申请和销毁。于此同时呢,进程的销毁和创建其实是一个很大的开销,这样就会导致操作系统的效率很低,这时就引出了线程,所以了解线程和线程进程之间的关系也是很有必要的,接下来就详细讲讲。
2025-04-29 13:42:58
936
原创 计算机是如何工作的(下)
在计算机是如何工作的(上)中我们讲到进程与线程,在接下来编程的路上,我们都会与多线程打交道,那么我们就详细讲讲在硬件角度上CPU在执行多线程时具体是怎么实现的。
2025-04-25 00:25:27
670
原创 计算机是如何工作的(上)
对于学习JavaEE初阶为什么要知道计算机是如何工作的,是因为在未来我们写代码的时候,会出现一些bug,而在代码层面是看不出来的,所以我们需要了解一些关于计算机内部是如何工作的,从而提高代码的健壮度。
2025-04-22 00:03:43
492
原创 优先级队列(堆)
优先级队列(Priority Queue)是一种数据结构,与普通队列不同,它不仅按照先进先出(FIFO)的原则处理元素,还根据每个元素的优先级来决定处理顺序。优先级队列中的元素可以具有不同的优先级,处理时总是优先处理优先级高的元素。
2024-10-10 21:50:55
785
原创 详解栈和队列
添加元素:使用offer()处理容量受限的队列,使用add()处理没有容量限制的队列。移除元素:使用poll()安全地移除元素,若队列为空则返回null,使用remove()在队列为空时抛出异常。查看元素:使用peek()安全地查看队列头部元素,若队列为空则返回null,使用element()在队列为空时抛出异常。
2024-08-20 17:45:39
1052
原创 泛型的详解
顾名思义,所谓泛型就是指能存放所有类型数据的类型,我们肯定会想到用Object,那我们就拿它试试。这么写有两个明显的缺点:1. 存放数据太乱,什么都能放;2. 每次取出数据的时候还需要强转。当我们存放的数据类型与中的类型不一样时,他就会自动检查数据类型,这样一来我们在存放数据时就不会很乱。,并且在我们获取里面的内容时也不需要强制类型转化,非常的便捷。注意:1. 里面只能写类类型,不能写简单类型;
2024-07-16 00:13:23
597
原创 抽象类和接口
3. 这种没有具体实现的方法叫作抽象方法,也需要abstract关键字来修饰,抽象方法只能出现在抽象类中,在普通类中会报错,这也是普通类和抽象类的区别所在。7. 如果一个类不想实现接口中的方法,那么此时这个类可以定义为抽象类,但这个抽象类如果被继承,他的子类就必须实现所有没有被实现的方法。在我们写在一个类中写一个没有具体实现的方法,在正常类中是无法实现的,但是在抽象类中就可以实现,这大大提高了开发的效率。2. 接口中的抽象方法默认都是public abstract修饰的,定义方式可与接口中的成员变量类比。
2024-06-28 15:35:11
810
1
原创 继承和多态
程序在编译的时候确实调用的是父类的draw() 方法,当代码运行时,通过父类引用,调用了父类和子类重写的那个方法,结果实际调用了子类的方法,此时我们把这种情况叫做动态绑定。程序在编译的时候确实调用的是父类的draw() 方法,当代码运行时,通过父类引用,调用了父类和子类重写的那个方法,结果实际调用了子类的方法,此时我们把这种情况叫做动态绑定。这个代码叫做注解,注解有很多种,@Override只是其中之一,它是用来修饰被重写的方法,起到一个提示作用,如果在它下面的方法不满足重写的条件,编译器就会报错...
2024-05-24 19:38:15
1094
7
原创 类和对象详解
比如现在要你去雕刻一个雕像,那我会跟你说要雕刻些什么,比如有眼睛,鼻子,嘴巴,高矮胖瘦等等,而我说的这些内容就是一个类,你根据这些内容所雕刻出来的东西就叫做对象,由此我们可以得出:类是来描述一个对象的;对象是一个真实存在的实体。类是抽象的,不存在;对象是具象的,它真实存在。注:建议一个文件中只放一个类,被public修饰的类的名字要与文件名相同。System.out.println(this.name + "正在吃狗粮....");
2024-05-20 21:41:27
998
6
原创 初识Java
注意方法名一般采用小驼峰命名。修饰符 + 返回值类型 + 方法名 + (形式参数列表) {方法体;在Java中,我们是拿不到栈上的局部变量的地址的,所以不存在通过传指针来改变实参的值的,所以以下写法是错误的://1和2没有区别。//1.//2.//3这种定义并没有初始化元素的值,默认全为其类型对应的“0”值。//3.//4.//不建议这样写错误写法1:错误写法2:定义一个数组:array叫做引用变量,它里面储存的是地址。在内存中它的储存形式是这样的:0x99是首元素的地址。
2024-05-15 20:41:16
1116
7
原创 每日一题——求符合给定条件的整数集
给定不超过6的正整数A,考虑从A开始的连续4个数字。请输出所有由它们组成的无重复数字的3位数。输出满足条件的的3位数,要求从小到大,每行6个整数。这段代码实现了将所有满足条件的三位数打印出来,每行显示6个数字。接下来,使用一个循环将数组中的数字打印出来,每行显示6个数字。如果生成的三个数中有相同的数字,则跳过。否则,将生成的三位数存储在数组。中存储了所有生成的三位数。:计算一个比输入的整数。大3的数,存储在变量。,用于存储生成的三位数。,生成三位数的百位数。,生成三位数的十位数。,生成三位数的个位数。
2024-04-25 13:41:28
595
1
原创 每日一题——阶乘计算升级版
其中N是用户传入的参数,其值不超过1000。如果N是非负整数,则该函数必须在一行中打印出N!的值,否则打印“Invalid input”。
2024-04-14 23:05:41
460
5
原创 每日一题——环形链表的约瑟夫问题
如果不为空,则将当前节点接到尾节点后,并更新尾节点为当前节点。如果其中一个为空,就返回另一个链表,因为合并后的链表就是非空链表本身。开始5个人 1,2,3,4,5 ,从1开始报数,1->1,2->2编号为2的人离开。1,3,4,5,从3开始报数,3->1,4->2编号为4的人离开。1,3,5,从5开始报数,5->1,1->2编号为1的人离开。是否还有剩余节点,如果有,则将剩余节点接到合并链表的尾部。3,5,从3开始报数,3->1,5->2编号为5的人离开。当前节点的值,将值较小的节点接到合并后的链表中。
2024-04-10 23:13:10
579
原创 每日一题——合并两个有序链表
加入操作分为两种情况:如果合并后的链表为空,则将头节点和尾节点都设为当前节点;如果不为空,则将当前节点接到尾节点后,并更新尾节点为当前节点。如果其中一个为空,就返回另一个链表,因为合并后的链表就是非空链表本身。当循环结束后,可能存在其中一个链表还有剩余节点未加入合并链表中。新链表是通过拼接给定的两个链表的所有节点组成的。是否还有剩余节点,如果有,则将剩余节点接到合并链表的尾部。当前节点的值,将值较小的节点接到合并后的链表中。分别表示合并后链表的头节点和尾节点,初始时都为。最后返回合并后的链表的头节点。
2024-04-10 23:07:33
485
原创 每日一题——反转链表
指针更新为下一个节点。这样做的效果是,不断地将当前节点指向其前一个节点,从而实现了链表的反转。首先,我们检查输入的头节点是否为空,如果为空则直接返回,因为空链表无需反转。,它们分别代表当前节点的前一个节点、当前节点和当前节点的后一个节点。这种方法的时间复杂度是 O(n),其中 n 是链表的长度。在循环的每一次迭代中,我们将当前节点。指向的节点即为反转后链表的头节点,因此返回。为空时,说明已经遍历完整个链表,此时。,请你反转链表,并返回反转后的链表。接着,我们进入一个循环,条件是。然后,我们定义了三个指针。
2024-04-09 23:07:11
363
原创 文件操作详解
磁盘(硬盘)上的⽂件是⽂件。但是在程序设计中,我们⼀般谈的⽂件有两种:程序⽂件、数据⽂件(从⽂件功能的⻆度来分类 的)。上⾯说的适⽤于所有输⼊流⼀般指适⽤于标准输⼊流和其他输⼊流(如⽂件输⼊流);所有输出流⼀ 般指适⽤于标准输出流和其他输出流(如⽂件输出流)。
2024-03-27 21:53:49
913
1
原创 动态内存管理详解
C/C++程序内存分配的⼏个区域:1. 栈区(stack):在执⾏函数时,函数内局部变量的存储单元都可以在栈上创建,函数执⾏结束时 这些存储单元⾃动被释放。栈内存分配运算内置于处理器的指令集中,效率很⾼,但是分配的内 存容量有限。栈区主要存放运⾏函数⽽分配的局部变量、函数参数、返回数据、返回地址等。2. 堆区(heap):⼀般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。分配⽅ 式类似于链表。3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。
2024-03-22 22:49:55
1002
原创 自定义类型:结构体
下图是⽹络协议中,IP数据报的格式,我们可以看到其中很多的属性只需要⼏个bit位就能描述,这⾥ 使⽤位段,能够实现想要的效果,也节省了空间,这样⽹络传输的数据报⼤⼩也会较⼩⼀些,对⽹络 的畅通是有帮助的。4.如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构 体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。这个是错误的用法,因为⼀个结构体中再包含⼀个同类型的结构体变量,这样结构体变量的⼤ ⼩就会⽆穷的⼤,是不合理的。2. 位段中最⼤位的数⽬不能确定。
2024-03-20 13:04:22
807
6
原创 数据在内存中的存储(2)
上一个博文里面讲到了整形在内存中的存储,但是浮点型的内容是否与整形的储存方式一样呢?常⻅的浮点数:3.14159、1E10等,浮点数家族包括: float、double、long double 类型。浮点数表⽰的范围: float.h 中定义根据国际标准IEEE(电⽓和电⼦⼯程协会)754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:V = (−1) 的S次方 ∗ M ∗ 2 的E次方• (−1) 的S次方表⽰符号位,当S=0,V为正数;当S=1,V为负数 S。
2024-03-17 19:47:15
981
1
原创 C语言内存函数
1. memcpy使⽤和模拟实现2. memmove使⽤和模拟实现及详解3. memset函数的使⽤4. memcmp函数的使⽤。
2024-03-14 21:43:43
423
5
原创 字符函数和字符串函数
1. 字符分类函数2. 字符转换函数3. strlen的使⽤和模拟实现4. strcpy的使⽤和模拟实现5. strcat的使⽤和模拟实现6. strcmp的使⽤和模拟实现7. strncpy函数的使⽤8. strncat函数的使⽤9. strncmp函数的使⽤10. strstr的使⽤和模拟实现11. strtok函数的使⽤12. strerror函数的使⽤。
2024-03-09 23:38:07
906
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人