- Oct 2024
-
xiaolincoding.com xiaolincoding.com
-
三级缓存(Singleton Factories):这也是一个Map类型的缓存,存储的是ObjectFactory对象,这些对象可以生成早期的bean引用。当一个bean正在创建过程中,如果它被其他bean依赖,那么这个正在创建的bean就会通过这个ObjectFactory来创建一个早期引用,从而解决循环依赖的问题。这个缓存在DefaultSingletonBeanRegistry类中的singletonFactories属性中。
-
- Sep 2024
-
xiaolincoding.com xiaolincoding.com操作系统面试题2
-
你了解过哪些io模型
-
信号量其实是一个计数器,表示的是资源个数,其值可以通过两个原子操作来控制,分别是 P 操作和 V 操作
P操作(Proberen,尝试):也称为等待操作,当一个进程想要访问共享资源时,会执行P操作。如果信号量的值大于0,则表明有可用资源,信号量减1,进程继续执行;如果信号量的值为0,则表示没有可用资源,此时进程将被阻塞,直到有其他进程释放资源(通过V操作增加信号量的值)。 V操作(Verhogen,增加):也称为信号操作,当进程完成对共享资源的访问后,会执行V操作。此操作会使信号量加1,表示释放了一个资源。如果有其他进程因为资源不足而被阻塞,那么其中一个会被唤醒并尝试再次执行P操作
-
-
javaguide.cn javaguide.cn
-
锁被释放之后,后申请的线程可能会先获取到锁,是随机或者按照其他优先级排序的。性能更好,但可能会导致某些线程永远无法获取到锁
即,不会检查是否有线程在排队,直接竞争锁;但一旦没竞争到锁,两种方式都会排队,当锁释放,唤醒最前面的线程;只是体现在加锁阶段而不体现在唤醒阶段
-
多级反馈队列调度算法
多级反馈队列调度算法是一种操作系统中的进程调度算法。它将进程按照不同的优先级分配到多个不同的队列中。每个队列有不同的优先级和时间片大小。高优先级队列中的进程会优先得到 CPU 时间。如果一个进程在一个队列中未能在给定的时间片内完成,它会被移到更低优先级的队列中。这种算法可以较好地平衡不同类型进程的响应时间和系统资源利用率。
-
-
xiaolincoding.com xiaolincoding.com
-
而在 JDK 1.8 中,HashMap 对扩容操作做了优化。由于扩容数组的长度是 2 倍关系,所以对于假设初始 tableSize = 4 要扩容到 8 来说就是 0100 到 1000 的变化(左移一位就是 2 倍),在扩容中只用判断原来的 hash 值和左移动的一位(newtable 的值)按位与操作是 0 或 1 就行,0 的话索引不变,1 的话索引变成原索引加上扩容前数组。
是一种优化计算新索引的办法,举个例子
当然可以。让我们通过一个具体的例子来说明这个过程。
假设我们有以下初始情况:
- 初始数组大小(tableSize)为 4,对应的二进制表示为 0100。
- 扩容后的数组大小为 8,对应的二进制表示为 1000。
假如有一个元素哈希值为6 (110),其索引应该为6%4即2 (10)。我们取其左移一位和最高位的与操作1100 & 1000 = 1000,不为0,则索引变为原索引加上原数组大小2+4 = 6
-
hashmap不是线程安全的,hashmap在多线程会存在下面的问题
- JDK 1.7中HashMap在多线程下数组扩容时的问题
- Entry链死循环问题
- 在JDK 1.7中,HashMap的扩容操作是通过创建一个新的数组,然后将旧数组中的元素重新计算哈希值并放入新数组中。在多线程环境下,如果多个线程同时进行扩容操作,可能会导致链表形成死循环。
- 例如,假设有两个线程T1和T2同时对一个HashMap进行扩容。当线程T1在迁移链表中的节点时,可能被线程T2中断。线程T2对链表进行了部分重新排序和迁移操作,然后线程T1继续执行。由于线程T1和T2对链表节点的引用操作交错,可能会使链表中的节点形成一个环形结构。
- 数据丢失问题
- 在扩容过程中,多个线程同时操作同一个桶(数组中的一个位置)的链表时,可能会导致部分数据丢失。
- 比如,线程T1正在将旧数组桶中的一个节点迁移到新数组中,此时线程T2也对同一个桶进行操作,可能会覆盖线程T1的操作结果,导致原本应该迁移到新数组中的节点没有被正确迁移,从而造成数据丢失。
- JDK 1.8中HashMap在多线程下put方法的数据覆盖问题
- 在JDK 1.8中,虽然对扩容机制进行了优化,但多线程下的put操作仍存在问题。
- 当多个线程同时调用put方法时,可能会出现数据覆盖的情况。假设线程T1和线程T2同时对同一个键(key)进行put操作。如果它们几乎同时计算出该键对应的数组桶索引,并且在没有合适的同步机制下,可能会导致后执行的put操作覆盖先执行的put操作的结果。
- 例如,线程T1首先计算出键的哈希值并找到对应的桶,开始插入键值对的操作。在T1还没有完全完成插入操作时,线程T2也计算出相同键的哈希值并找到相同的桶,然后线程T2执行put操作,由于没有并发控制,线程T2的操作可能会覆盖线程T1插入的结果。
-
- Aug 2024
-
labuladong.online labuladong.online
-
我们直接看解法
递归解法:
```Java class Solution { public ListNode mergeTwoLists(ListNode list1, ListNode list2) { if (list1 == null){ return list2; } if (list2 == null){ return list1; }
if (list1.val <= list2.val){ list1.next = mergeTwoLists(list1.next, list2); return list1; } else{ list2.next = mergeTwoLists(list1, list2.next); return list2; } }
} ```
-
-
labuladong.online labuladong.online
-
哈希集合 HashSet
什么情况下会选择使用 HashSet 而不是 HashMap:
- 只需要存储唯一元素时:
- HashSet 只存储元素本身,而 HashMap 存储键值对。
- 如果你只关心元素的唯一性,不需要与之关联的值,就应该使用 HashSet。
- 需要快速检查元素是否存在:
- HashSet 提供了高效的 contains() 方法,用于检查元素是否存在。
- 如果你经常需要检查某个元素是否在集合中,HashSet 是个好选择。
- 需要去重:
- HashSet 自动确保所有元素都是唯一的。
- 如果你有一个包含重复元素的集合,并且想要去除重复项,可以将其转换为 HashSet。
- 实现数学集合操作:
- HashSet 适合执行并集、交集、差集等集合操作。因为唯一性
- 不需要保持插入顺序:
- HashSet 不保证元素的顺序
- 内存效率:
- 当你只需要存储元素而不需要额外的键时,HashSet 比 HashMap 更节省内存。
- 只需要存储唯一元素时:
-
就是一定要用字符串的 equals 方法比较两个字符串是否相同,不要用 == 比较
==
是在比较是否是同一个对象
Tags
Annotators
URL
-