Skip to content

Commit 1a80252

Browse files
committed
📝bloomfilter
1 parent 989c429 commit 1a80252

File tree

2 files changed

+103
-31
lines changed

2 files changed

+103
-31
lines changed

docs/java/Collections/Collections-FAQ.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
「我是大厂面试官」—— Java 集合,你肯定会被问到这些
22

3+
> 文章收录在 GitHub [JavaKeeper](https://github.com/Jstarfish/JavaKeeper) ,N线互联网开发必备技能兵器谱
4+
35
作为一位小菜 ”一面面试官“,面试过程中,我肯定会问 Java 集合的内容,同时作为求职者,也肯定会被问到集合,所以整理下 Java 集合面试题
46

7+
![](https://i02piccdn.sogoucdn.com/fe487f455e5b1eb6)
8+
59
> 说说常见的集合有哪些吧?
610
>
711
> HashMap说一下,其中的Key需要重写hashCode()和equals()吗?
@@ -46,7 +50,7 @@ Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一
4650
Map 接口和 Collection 接口是所有集合框架的父接口:
4751

4852
1. Collection接口的子接口包括:Set、List、Queue
49-
2. List是有序的不允许有重复元素的Collection,实现类主要有:ArrayList、LinkedList、Stack以及Vector等
53+
2. List是有序的允许有重复元素的Collection,实现类主要有:ArrayList、LinkedList、Stack以及Vector等
5054
3. Set是一种不包含重复元素且无序的Collection,实现类主要有:HashSet、TreeSet、LinkedHashSet等
5155
4. Map没有继承Collection接口,Map提供key到value的映射。实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap 以及 Properties 等
5256

@@ -120,7 +124,7 @@ Map 接口和 Collection 接口是所有集合框架的父接口:
120124
- **插入和删除是否受元素位置的影响:**
121125
- **ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。** 比如:执行 `add(E e)`方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是O(1)。但是如果要在指定位置 i 插入和删除元素的话( `add(intindex,E element)`)时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。
122126
- **LinkedList 采用链表存储,所以插入,删除元素时间复杂度不受元素位置的影响,都是近似 $O(1)$,而数组为近似 $O(n)$。**
123-
- ArrayList 一般应用于查询较多但插入以及删除较少情况,如果插入以及从删除较多则建议使用 LinkedList
127+
- ArrayList 一般应用于查询较多但插入以及删除较少情况,如果插入以及删除较多则建议使用 LinkedList
124128
- **是否支持快速随机访问**LinkedList 不支持高效的随机元素访问,而 ArrayList 实现了 RandomAccess 接口,所以有随机访问功能。快速随机访问就是通过元素的序号快速获取元素对象(对应于 `get(intindex)`方法)。
125129
- **内存空间占用**ArrayList 的空间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(因为要存放直接后继和直接前驱以及数据)。
126130

@@ -1464,7 +1468,7 @@ HashSet的底层其实就是HashMap,只不过我们**HashSet是实现了Set接
14641468

14651469

14661470

1467-
1471+
![](https://user-gold-cdn.xitu.io/2020/3/20/170f5beacffbc730?w=750&h=390&f=jpeg&s=29031)
14681472

14691473
## 参考与感谢
14701474

docs/java/JVM/Reference.md

Lines changed: 96 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,42 @@
1-
阿里面试题: 说说强引用、软引用、弱引用、虚引用分别是什么?
1+
## 阿里面试回顾: 说说强引用、软引用、弱引用、虚引用分别是什么?
2+
3+
我们都知道 JVM 垃圾回收中,GC判断堆中的对象实例或数据是不是垃圾的方法有**引用计数法****可达性算法**两种。
24

35
无论是通过引用计数算法判断对象的引用数量,还是通过根搜索算法判断对象的引用链是否可达,判定对象是否存活都与“引用”有关。
46

5-
在JDK 1.2之前,Java中的引用的定义很传统:如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,就称该 refrence 数据是代表某块内存、某个对象的引用。这种定义很纯粹,但是太过狭隘,一个对象在这种定义下只有被引用或者没有被引用两种状态,对于如何描述一些“食之无味,弃之可惜”的对象就显得无能为力。
7+
在 JDK 1.2 之前,Java 中的引用的定义很传统:如果 reference 类型的数据中存储的数值代表的是另外一块内存的起始地址,就称该 refrence 数据是代表某块内存、某个对象的引用。这种定义很纯粹,但是太过狭隘,一个对象在这种定义下只有被引用或者没有被引用两种状态,对于如何描述一些“食之无味,弃之可惜”的对象就显得无能为力。
8+
9+
比如我们希望能描述这样一类对象:当内存空间还足够时,则能保留在内存之中;如果内存在进行垃圾收集后还是非常紧张,则可以抛弃这些对象。很多系统的缓存功能都符合这样的应用场景。
10+
11+
在 JDK 1.2 之后,Java 对引用的概念进行了扩充,将引用分为
12+
13+
- 强引用(Strong Reference)
14+
- 软引用(Soft Reference)
15+
- 弱引用(Weak Reference)
16+
- 虚引用(Phantom Reference)
17+
18+
这四种引用强度依次逐渐减弱。
619

7-
我们希望能描述这样一类对象:当内存空间还足够时,则能保留在内存之中;如果内存在进行垃圾收集后还是非常紧张,则可以抛弃这些对象。很多系统的缓存功能都符合这样的应用场景。
820

9-
在JDK 1.2之后,Java对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)四种,这四种引用强度依次逐渐减弱。
1021

11-
- 强引用就是指在程序代码之中普遍存在的,类似“Object obj = new Object()”这类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用的对象。
12-
- 软引用用来描述一些还有用,但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中并进行第二次回收。如果这次回收还是没有足够的内存,才会抛出内存溢出异常。在JDK 1.2之后,提供了SoftReference类来实现软引用。
13-
- 弱引用也是用来描述非必需对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。在JDK 1.2之后,提供了WeakReference类来实现弱引用。
14-
- 虚引用也称为“幽灵引用”或者“幻影引用”,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是希望能在这个对象被收集器回收时收到一个系统通知。在JDK 1.2之后,提供了PhantomReference类来实现虚引用。
22+
### JDK 8中的 UML关系图
23+
24+
![Finalizer.png](https://i.loli.net/2020/05/07/AqsHUeYCOf2hzZc.png)
1525

1626

1727

1828
### 强引用
1929

20-
当内存不足,JVM 开始垃圾回收,对于强引用的对象,**就算是出现了 OOM 也不会对该对象进行回收,打死都不收。**
30+
在 Java 中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。类似 `“Object obj = new Object()”` 这类的引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾收集器就不会碰这种对象。
31+
32+
当一个对象被强引用变量引用时,它处于可达状态,是不可能被垃圾回收器回收的,即使该对象永远不会被用到也不会被回收。
2133

22-
强引用是我们最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾收集器不会碰这种对象。在 Java 中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,是不可能被垃圾回收器回收的,即使该对象永远不会被用到也不会被回收。因此强引用是造成 Java 内存泄露的主要原因之一。
34+
当内存不足,JVM 开始垃圾回收,对于强引用的对象,**就算是出现了 OOM 也不会对该对象进行回收,打死都不收。**因此强引用是造成 Java 内存泄露的主要原因之一。
2335

2436
对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显示地将相应(强)引用赋值为 null,一般认为就是可以被垃圾收集器回收。(具体回收时机还要要看垃圾收集策略)。
2537

38+
#### coding~
39+
2640
```java
2741
public class StrongRefenenceDemo {
2842

@@ -37,31 +51,33 @@ public class StrongRefenenceDemo {
3751
}
3852
```
3953

40-
o2一直存在,不会被垃圾回收
54+
TODO : demo中尽管o1已经被回收,但是o2一直存在,不会被垃圾回收
4155

4256

4357

4458
### 软引用
4559

46-
软引用是一种相对强引用弱化了一些的引用,需要用`java.lang.ref.SoftReference` 类来实现,可以让对象豁免一些垃圾收集。对于只有软引用的对象来说,
60+
软引用是一种相对强引用弱化了一些的引用,需要用`java.lang.ref.SoftReference` 类来实现,可以让对象豁免一些垃圾收集。
61+
62+
软引用用来描述一些还有用,但并非必需的对象。对于软引用关联着的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中并进行第二次回收。如果这次回收还是没有足够的内存,才会抛出内存溢出异常。
63+
64+
对于只有软引用的对象来说
4765

4866
- 当系统内存充足时它不会被回收
4967
- 当系统内存不足时它才会被回收
5068

5169
软引用通常用在对内存敏感的程序中,比如高速缓存就有用到软引用,内存够用的时候就保留,不够用就回收。
5270

53-
eg:
54-
55-
VM options配置 `-Xms5m -Xmx5m`
71+
#### coding~
5672

5773
```java
74+
//VM options: -Xms5m -Xmx5m
5875
public class SoftRefenenceDemo {
5976

6077
public static void main(String[] args) {
6178
softRefMemoryEnough();
6279
System.out.println("------内存不够用的情况------");
6380
softRefMemoryNotEnough();
64-
6581
}
6682

6783
private static void softRefMemoryEnough() {
@@ -122,10 +138,14 @@ TODO
122138

123139
### 弱引用
124140

125-
弱引用需要用`java.lang.red.WeakReference`类来实现,它比软引用的生存期更短。
141+
弱引用也是用来描述非必需对象的,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
142+
143+
弱引用需要用`java.lang.ref.WeakReference`类来实现,它比软引用的生存期更短。
126144

127145
对于只有软引用的对象来说,只要垃圾回收机制一运行,不管 JVM 的内存空间是否足够,都会回收该对象占用的内存。
128146

147+
#### coding~
148+
129149
```java
130150
public class WeakReferenceDemo {
131151

@@ -149,31 +169,84 @@ public class WeakReferenceDemo {
149169

150170
#### 软引用和弱引用的适用场景
151171

152-
![](https://tva1.sinaimg.cn/large/00831rSTly1gdegg6qqm6j31fq0logzr.jpg)
172+
假如有一个应用需要读取大量的本地图片:
173+
174+
- 如果每次读取图片都从硬盘读取则会严重影响性能
175+
- 如果一次性全部加载到内存中又可能造成内存溢出
176+
177+
此时使用软引用就可以解决这个问题。
178+
179+
设计思路:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效的避免了OOM的问题。
180+
181+
Map<String,SoftReference<Bitmap>> imageCache = new HashMap<String,SoftReference<Bitmap>>();
153182

154183

155184

156185
> 你知道弱引用的话,能说下 WeakHashMap吗
157186
158-
![img](https://tva1.sinaimg.cn/large/00831rSTly1gdego93wwdj31f00m0k18.jpg)
187+
```java
188+
public class WeakHashMapDemo {
189+
190+
public static void main(String[] args) {
191+
myHashMap();
192+
myWeakHashMap();
193+
194+
}
195+
196+
public static void myHashMap() {
197+
HashMap<String, String> map = new HashMap<String, String>();
198+
String key = "k1";
199+
String value = "v1";
200+
map.put(key, value);
201+
System.out.println(map);
202+
203+
key = null;
204+
System.out.println(map);
205+
206+
System.gc();
207+
System.out.println(map);
208+
}
209+
210+
public static void myWeakHashMap() {
211+
WeakHashMap<String, String> map = new WeakHashMap<String, String>();
212+
String key = "weak";
213+
String value = "map";
214+
map.put(key, value);
215+
System.out.println(map);
216+
217+
key = null;
218+
System.out.println(map);
159219

160-
![img](https://tva1.sinaimg.cn/large/00831rSTly1gdegpyj70yj31ek0oy4bt.jpg)
220+
System.gc();
221+
System.out.println(map);
222+
}
223+
224+
}
225+
```
161226

162227

163228

164229
### 虚引用
165230

231+
虚引用也称为“**幽灵引用**”或者“**幻影引用**”,它是最弱的一种引用关系。
232+
233+
虚引用,顾名思义,就是形同虚设,与其他几种引用都不太一样,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。
234+
235+
为一个对象设置虚引用关联的唯一目的就是希望能在这个对象被收集器回收时收到一个系统通知。
236+
166237
虚引用需要`java.lang.ref.PhantomReference` 来实现。
167238

168-
虚引用,顾名思义,就是形同虚设,与其他几种引用都不太一样,虚引用并不会决定对象的生命周期。
169239

170-
如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收,它不能单独使用也不能通过它访问对象,虚引用必须和引用队列(RefenenceQueue)联合使用。
171240

241+
如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收,它不能单独使用也不能通过它访问对象,虚引用必须和引用队列(RefenenceQueue)联合使用。
172242

243+
虚引用的主要作用是跟踪对象垃圾回收的状态。仅仅是提供了一种确保对象被finalize以后,做某些事情的机制。
173244

174-
![](https://tva1.sinaimg.cn/large/00831rSTly1gdegs2tppxj31ge0os1ew.jpg)
245+
PhantomReference的get方法总是返回null,因此无法访问对应的引用对象。其意义在于说明一个对象已经进入finalization阶段,可以被gc回收,用来实现比finalization机制更灵活的回收操作。
175246

247+
换句话说,设置虚引用的唯一目的,就是在这个对象被回收器回收的时候收到一个系统通知或者后续添加进一步的处理。
176248

249+
Java技术允许使用finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。
177250

178251

179252

@@ -185,12 +258,7 @@ public class WeakReferenceDemo {
185258

186259

187260

188-
JDK 1.2 版之后引入了软(SoftReference)、弱(WeakReference)、虚(PhantomReference)三种引用。
189261

190-
- 强引用:最传统的「引用」的定义,是指在程序代码之中普遍存在的引用赋值,即类似`Object obj=new Object()`这种引用关系。只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。
191-
- 软引用:描述一些还有用,但非必须的对象。只被软引用关联着的对象,在系统将要发生内存溢出异常前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。
192-
- 弱引用:描述那些非必须对象,但是它的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生为止。当垃圾收集器开始工作,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。
193-
- 虚引用:是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的只是为了能在这个对象被收集器回收时收到一个系统通知。
194262

195263
## 二、引用到底有什么作用
196264

0 commit comments

Comments
 (0)