- 博客(82)
- 收藏
- 关注
原创 synchronized的锁对象 和 wait,notify的调用者之间的关系
wait()正确说法说明wait()和notify()是基于“同一个锁对象”的线程协作机制多个线程通过操作同一个对象的 Monitor 来实现等待/通知调用obj.wait()的线程会释放obj的锁并等待它“把自己挂起”调用的线程会唤醒一个在obj上等待的线程它“唤醒别人”只有调用了obj.wait()的线程才会被唤醒没有wait()就不会被通知影响控制范围 = 所有使用obj作为锁并调用obj.wait()的线程obj是协作的“公共频道”
2025-08-31 22:34:09
892
原创 Java中,任何方法都有其调用者
场景调用者在main或其他方法中调用obj在本类的非静态方法中调用另一个非静态方法this(隐式)静态方法调用静态方法类名(或直接调用,不涉及this只要是非静态方法的调用,就一定有调用者;在本类中,这个调用者就是this,只是被隐藏了。这是理解 Java 对象行为和方法绑定机制的重要基础。👏我记得调用静态方法的时候,不是应该用类名调用吗?那为什么在测试类的main方法中,调用其他本类中的静态方法时,仍然没有调用者。你提出了一个非常棒的问题!这触及了 Java 语言设计中的一个语法糖机制和。
2025-08-31 17:56:14
596
原创 Java强制转换
转换类型允许条件基本类型自动转目标类型范围 ≥ 源类型范围(如int→long基本类型强制转数值类型间理论上可行(但可能损失精度)引用类型向上转子类→父类/接口(总是安全)引用类型向下转父类→子类 +实际对象是目标类型(需instanceof验证)完全禁止转换1. 无关系的基本类型(如boolean→int2. 无继承关系的引用类型能够提出问题的能力很重要,这里我直接把Deepseek的解答贴过来,方便高效其实对于引用数据类型来说,变量存的就是一个内存地址。这个内存地址指向具体的一个对象。
2025-07-28 13:25:25
378
原创 接口多态中的编译看左,运行看右
我之前一直以为,当运行run这个方法的时候,this指向的是sportsman。但实际上,我搞混了运行和编译。当真正在运行run这个方法的时候。this指向的其实是s1。在编译阶段,编译器会检查 SportMan 接口中是否有 run() 方法,如果有,则编译通过,编译通过后开始运行,而编译看左边,运行看右边,右边指的就是接口具体的实现类对象当写到这里的时候,我就产生了三个疑问。
2025-07-28 13:08:39
274
原创 同一条链上哈希值不一定一样,只是根据不一样的哈希值算出来该存入的索引是一样的
同一条链上的元素可以有不同的哈希值,但因为计算出的索引位置相同而被放在同一个桶中。→ 不同哈希值(17,33,49)都映射到索引12. 索引冲突(哈希值不同但索引相同)HashMap 如何处理这种情况?存储结构示例:桶数组索引: 0 1 2 3 ... 15 | | | | | ∅ [K1] ∅ ∅ ∅
2025-07-27 11:38:28
302
原创 初探HashMap中的HashCode方法
听课的时候,一个老师说,这个hash map里元素的哈希值是由键值计算的。首先在HashMap里计算这个哈希值是用键值来计算的。那Hashcode,他不论重不重写,他不都是用这个键值来计算的吗?
2025-07-25 20:02:23
505
原创 集合中Comparable接口和Equals方法的冲突
equals方法是在讲解集合的时候讲到的,因为集合的特点是,无序,不重复,无索引,LinkedHashSet有序是因为,它的底层是通过双向链表和哈希表共同完成的。通过双向链表来获取第一个第二个元素。从而保证添加顺序和遍历的顺序是一样的。HashSet和LinkedHashSet保证存储元素不重复的方法是通过equals方法。而TreeSet保证元素不重复的方法是通过。比较方法,即Comparable或Comparator。
2025-07-24 22:02:33
277
原创 接口多态之我的误解
Collection和Link和Set都是接口,接口多态,和编译看左边,运行看右边的关键之处,在于其调用的方法或属性,而不在于,父类或者接口,有没有,子类中重写方法中,包含的其他方法,虽然Collection没有equals方法(HashSet,add方法中用到的equals方法),但这不是关键,只要Collection有调用的方法即可(即add)问题产生的起因是:我当时纳闷collection接口里面应该没有equals方法,所以collection集合,添加元素的时候,应该可以添加重复元素。
2025-07-24 19:42:41
345
原创 【无标题】
在执行 `System.out.println(obj)` 时,尽管 `obj` 是 `Parent` 类型的引用,但由于它是对 `Child` 对象的引用,JVM会查询 `Child` 对象的虚方法表来找到 `toString` 方法的正确实现,并调用 `Child` 类中重写的 `toString` 方法。- 如果 `Child` 类重写了 `toString` 方法,那么在 `Child` 的虚方法表中,`toString` 方法对应的条目将指向 `Child` 类中的实现。
2025-05-03 17:47:51
861
原创 如何让a和b的地址互换?
m和n本质上还是一个变量,而&a和&b是一个常量,你不能写成&a=&b,这就相当于写10=20,肯定不行,m只是记录了a的地址,但m不是&a本身。的地址并不是一个常见的操作,因为变量的地址是由编译器分配的,通常不能直接更改。然而,你可以通过指针来间接实现类似的效果。如果你需要更复杂的内存管理或地址交换操作,可能需要深入理解动态内存分配(如使用。的值,从而实现了指针所指向对象的“交换”。现在分别指向了对方原本指向的变量。在这个例子中,我们定义了两个指针。在C语言中,直接交换两个变量。
2025-01-19 20:02:55
273
原创 c语言之字符指针疑难解答(10.19)
用%s打印东西时,只要给printf要打印的字符串的地址就行20分钟左右,还得再听一遍,难cpp[-1]可以转化为*(cpp-1)cpp[-1][-1]可以转化为*(*(cpp-1)-1)这里有一个要点:cpp是一个指针,当它对它进行自增自减操作时,它不会自动复原,不像你自己定义了一个数组之后,当然数组名是没法改变它的地址的(下图代码会报错)在上面这串代码中,parr[0]存的并不是变量a的地址,要写成这样才行 int* parr[] = { &a,&b,&c };
2024-10-19 18:43:22
1129
原创 学习笔记之指针进阶(10.11)
在 C 语言中,当你对一个指针进行加法操作时,编译器会根据指针所指向的数据类型来决定实际移动的字节数。如果你有一个指向某个类型的指针。,结果都是相同的:指针都会移动到下一个相同类型元素的位置。在这两种情况下,数值 1 都是作为元素的数量,而不是字节数来使用的。以上解释是错误的,a[0]不是整个数组的名字,a+1才是第二个一维数组的地址。指向的是一个结构体,那么它们会使指针向后移动该结构体的大小(即。实际上是没有区别的。这里的关键在于理解指针算术。向后移动一个元素的大小。的意思是将指针向后移动。
2024-10-11 17:56:43
491
原创 char类型的-128到底是个神马东西?
char类型的-128的补码是什么样的?在计算机中,负数通常使用补码形式来表示。对于一个有符号的char类型,其大小为 8 位(1 字节),可以表示从 -128 到 127 的整数。-128 是有符号 8 位整数能够表示的最小值。它的二进制补码表示是特殊的,因为它是唯一一个没有正数对应项的负数。在 8 位系统中,-128 的补码直接就是1000 0000。这里是如何得到这个结果的简要解释:首先,考虑正数 128 的二进制表示,它会是1000 0000。
2024-10-11 17:03:14
1163
原创 date:10.4(Content:Mr.Peng)( C language practice)
局部变量是存放在栈上的,栈又是从高到底存放所以先存i后存arr[]
2024-10-04 21:54:07
358
原创 有符号整型和无符号整型比较大小,整型提升{9.28下午}
有符号整型和无符号整型比较大小时,会先把有符号整型先转变成无符号整型-1的补码是32个1,当成无符号整型来处理时,补码就是源码,所以是一个超级大的数在C语言中,当有符号整型(如int)和无符号整型(如)进行比较时,并不会直接将有符号整型转换为无符号整型来进行比较。然而,实际的行为可能会让人误解为发生了这样的转换,因为比较操作是按照“值的二进制表示”来进行的,而不是按照它们的数学意义。在比较时,有符号整型会被“隐式地”转换为一个更大的类型(在这个情况下,通常是),但这个转换并不是简单的数值转换。
2024-10-04 21:53:00
1354
原创 有问题未解决(9.28)
数组名+1,就是下一个元素的地址,int类型的数组名+1移动四个字节,char类型的数组名+1移动1个字节,数组的类型决定了数组名+1移动的距离。[5]之所以不能省略是因为arr的类型是int[5],它的步长是5,和指针类似,一般情况下,指针的类型要和传过去的地址的类型一样。数组名是首元素的地址,arr2的首元素类型是一级指针,一级指针的地址要放到二级指针里面,实际上,arr2就是一个二级指针。arr是一个int类型的数组,他存的就是一个数,而不是变量,a的地址和arr的地址并不一样。
2024-09-28 17:30:15
527
原创 所有的表达式都有结果吗?
在C语言中,大多数表达式都有结果或返回值,但这些结果或返回值的用途和类型可能因表达式的类型而异。然而,并不是所有的语法结构都是表达式,也不是所有的表达式都被设计为产生可用于其他表达式的直接结果。*dest++=*src++,表达式的结果就是字符,而字符又通过ascll码表转化为对应的数字,'\0'对应的值是0,所以循环结束。a=b+3,这个表达式的结果就是8,8再赋值给c.int main()int a = 10;int b = 30;p = &b;//*p = 20;//
2024-09-20 16:13:42
1124
原创 探索C语言中数组作为函数参数的奥秘
在C语言的世界里,数组是一种基础且强大的数据结构,它允许我们存储相同类型的数据集合。然而,在处理函数和数组的关系时,尤其是在数组作为函数参数传递时,初学者往往会感到困惑。今天,我们就来深入探讨这一话题,通过具体的代码示例来揭开其神秘面纱。
2024-08-27 10:56:50
502
原创 c语言每日学习8.24
因此,当你传递一个字符串(即字符数组的指针)给函数时,函数可以通过遍历字符串直到遇到空字符来确定字符串的长度。void reverse_string(char* str) 为什么不用传递数组的长度?函数会遍历字符串直到遇到空字符,并返回遍历过的字符数量(不包括空字符)。函数也能通过遍历字符串来确定其长度,并进行反转操作。函数不需要显式传递数组长度的原因。函数可以计算字符串的长度,这是因为。在C语言中,字符串通常是以空字符。所以,即使不传递数组的长度,
2024-08-25 09:37:43
1078
原创 c语言指针(8.11)
虽然在技术上是合法的,并且可能符合你的预期(得到指向下一个元素的指针),但它实际上是在对已经退化为指针的。不是一个指针,而是一个数组(尽管在表达式中它会被退化为指向其首元素的指针)。进行赋值或将其作为函数参数传递(因为它不是一个左值),但你可以通过索引来访问它的元素(如。表示一个数组(尽管在表达式中它通常会被退化为指向其首元素的指针)时,直接对。存储了一个地址,这个地址是二维数组第一行的首元素的地址。的第一行(或称为第一个一维数组)的首元素的地址。是按照指针的步长(即指向类型的大小)来计算的,对于。
2024-08-11 12:05:23
563
原创 c语言(8.10)
同理,在二维指针数组中,指针指向的是第一个数组的地址,&arr,而不是第一个数组的第一个元素的地址,其实第一个数组的地址和第一个数组的第一个元素的地址是一样的,只不过。在 C 语言中,一旦数组名被用作指针(例如在表达式中),它就失去了其原始数组类型的信息,只保留了指向其首元素的指针类型的信息。为了获取数组的长度,你通常需要以某种方式显式地传递或存储这个信息,就像我之前提到的那样,使用一个额外的数组来存储每个数组的长度。在指针数组中(一维数组),指针指向的是数组中第一个元素的地址,
2024-08-10 23:59:16
939
原创 arr的谜思
第一个打印的是数组首元素的地址,第二个打印的是整个数组的地址(尽管在内存布局上,这两个地址是相同的)。然而,在大多数表达式中,数组名会被转换为指向数组首元素的指针。但是,如果你想要强调的是你正在获取整个数组的地址(尽管这在大多数实际用途中并不常见),你可以使用。时,你实际上看到的是整个数组在内存中的起始位置,这与数组首元素的地址在数值上是相同的,但它们的类型意义不同。函数时,你可以打印出任何指针类型的值,包括指向数组的指针。时,你得到的是指向整个数组的指针,而不是指向数组首元素的指针。
2024-08-04 18:11:48
738
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅