Skip to content

Commit 35a94e6

Browse files
committed
change note
1 parent 318fc73 commit 35a94e6

File tree

5 files changed

+66
-14
lines changed

5 files changed

+66
-14
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ Github项目主页:https://github.com/NotFound9/interviewGuide
1919

2020
所以我发起了这个项目,一方面是便于自己复习巩固,一方面是将这些自己写的解答开源出来分享给大家,希望可以帮助到大家,也欢迎大家一起来完善这个项目,为开源做贡献。
2121

22+
欢迎大家进群一起学习进步!
23+
24+
<figure class="half">
25+
<img src="http://notfound9.github.io/interviewGuide/static/qe222wewewqere.jpeg" width="30%"/>
26+
<img src="http://notfound9.github.io/interviewGuide/static/image1.jpg" width="30%"/>
27+
2228
## 目录
2329

2430
- [首页](README.md)
@@ -176,13 +182,8 @@ Github项目主页:https://github.com/NotFound9/interviewGuide
176182

177183
我平时比较喜欢看书,写技术文章,也比较喜欢讨论技术。这是我的[掘金主页](https://juejin.im/user/5b370a42e51d4558ce5eb969),希望大家可以关注一下,谢谢了!大家如果有事需要联系我,或者想进技术群,一起讨论技术,也可以扫描[主页中我的微信二维码](http://notfound9.github.io/interviewGuide/#/)加我,谢谢了!
178184

179-
<figure class="half">
180-
181-
<img src="http://notfound9.github.io/interviewGuide/static/qe222wewewqere.jpeg" width="30%"/>
182185
<img src="http://notfound9.github.io/interviewGuide/static/image1.jpg" width="30%"/>
183186

184-
</figure>
185-
186187
## 关于转载
187188

188189
如果你需要转载本仓库的一些文章到自己的博客的话,记得注明原文地址就可以了。

docs/JavaBasic.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ String是一个不可变类,任何对String改变都是会产生一个新的St
269269

270270
当频繁对字符串进行修改时,使用String会生成一些临时对象,多一些附加操作,执行效率降低。
271271

272-
```
272+
```java
273273
stringA = StringA + "2";
274274
//实际上等价于
275275
{
@@ -341,7 +341,7 @@ public static Class<?> forName(String className)
341341
}
342342
```
343343
可以自己尝试运行一下这段代码
344-
```
344+
```java
345345
Class class2 = null;
346346
try {
347347
class2 = Class.forName("com.test.Son");//如果实际不存在com.test.Son这个类,那么会抛出ClassNotFoundException异常
@@ -355,6 +355,7 @@ public static Class<?> forName(String className)
355355
class2 is class com.test.Son
356356
```
357357
##### 类名+.class
358+
358359
还有一种方式是使用**类名+.class**来获取类关联的Class对象,与上面两种方法不同之处在于,它返回的是编译时类型,也就是在编译时,类加载器将类加载到JVM中,然后初始化一个Class对象返回。
359360
```
360361
Class class3 = Son.class;
@@ -401,7 +402,7 @@ PS:无论是使用哪种方式来获取类关联的Class对象,类都是只会
401402

402403
在往HashMap中添加一个键值对时,计算得到数组下标后,会遍历数组下标下存储的链表中,拿key的hashCode与每个节点的hashCode进行比较,相等时,才调用equal()方法进行继续调用,节约时间。(在一些类的equal()方法的自定义实现中也会对hashCode进行判断)。
403404

404-
##### 假如只重写hashCode()方法(结果:HashMap无法保证去重
405+
##### 假如只重写hashCode()方法(结果:HashMap可以存在两个内存地址不相同,但是相等的对象,无法保证去重
405406

406407
此时equal()方法的实现是默认实现,也就是当两个对象的内存地址相等时,equal()方法才返回true,假设两个键值对,它们的key类型都是TestObject,的值都是test,但是由于是使用new String()创建而成的字符串对象,key1和key2的内存地址不相等,所以key1==key2的结果会是false,TestObject的equals()方法默认实现是判断两个对象的内存地址,所以 key1.equals(key2)也会是false, 所以两个键值对可以重复地添加到hashMap中去。
407408

@@ -443,7 +444,7 @@ HashMap是
443444
com.test.TestObject@1=value2}
444445
```
445446

446-
##### 假如只重写equals()方法(结果:HashMap无法保证去重)
447+
##### 假如只重写equals()方法(结果:相同的对象hashCode不同,从而映射到不同下标下,HashMap无法保证去重)
447448

448449
假设只equals()方法,hashCode方法会是默认实现,具体的计算方法取决于JVM,可能会导致两个相等的对象,它们的hashCode却不相同,从而计算得到的数组下标不相同,存储到hashMap中不同数组下标下的链表中,也会导致HashMap中存在重复元素。
449450

docs/JavaMultiThread.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,3 +1342,57 @@ public ScheduledThreadPoolExecutor(int corePoolSize,
13421342
参考链接:
13431343

13441344
https://mp.weixin.qq.com/s?src=11&timestamp=1595941110&ver=2487&signature=i8CGBfTlDi4SaG5SSOWYJo-Sgb*bauWAv8MEMYqWQMy4lFBQwjTY4*99R2-8PhC4WtBc4uBy-m3IveQ9a0RlQn53unVD6Xalfl2r30*IbwAdK7CPlbW6-8icKhG4OjKE&new=1
1345+
1346+
### ThreadLocal是什么?怎么避免内存泄露?
1347+
从字面意思上,ThreadLocal会被理解为线程本地存储,就是对于代码中的一个变量,每个线程拥有这个变量的一个副本,访问和修改它时都是对副本进行操作。
1348+
##### 使用场景:
1349+
ThreadLocal 适用于每个线程需要自己独立的实例且该实例需要在多个方法中被使用,也即变量在线程间隔离而在方法或类间共享的场景。例如方法直接调用时传递的变量过多,为了代码简洁性,可以使用ThreadLocal,在前一个方法中,将变量进行存储,后一个方法中取,进行使用。
1350+
```java
1351+
public class ThreadLocalUtil {
1352+
// 每个线程本地副本初始化
1353+
private static ThreadLocal <UserData> userLocal = new ThreadLocal <>(). withInitial (() -> new UserData ());
1354+
public static void setUser (UserLogin user){
1355+
if (user == null )
1356+
return ;
1357+
UserData userData = userLocal. get ();
1358+
userData. setUserLogin (user);
1359+
}
1360+
public static UserLogin getUser (){
1361+
return userLocal. get (). getUserLogin ();
1362+
}
1363+
}
1364+
```
1365+
1366+
##### 实现原理
1367+
1368+
就是每个Thread有一个ThreadLocalMap,类似于HashMap,当调用ThreadLocal#set()进行存值时,实际上是先获取到当前的线程,然后获取线程的map,是一个ThreadLocalMap类型,然后会在这个map中添加一个新的键值对,key就是我们ThreadLocal实例,value就是我们存的值。ThreadLocalMapHashMap不同的时,解决HashMap使用的是**开放定址法**,也就是当发现hashCode计算得到数组下标已经存储了元素后,会继续往后找,直到找到一个空的数组下标,存储键值对。
1369+
1370+
```java
1371+
public void set(T value) {
1372+
Thread t = Thread.currentThread();
1373+
ThreadLocalMap map = getMap(t);
1374+
if (map != null)
1375+
map.set(this, value);
1376+
else
1377+
createMap(t, value);
1378+
}
1379+
ThreadLocalMap getMap(Thread t) {
1380+
return t.threadLocals;
1381+
}
1382+
```
1383+
1384+
##### ThreadLocal中的Entry的key使用了弱引用,为什么使用弱引用?
1385+
1386+
1.如果使用强引用,那么Thread引用了ThreadLocalMapThreadLocalMap引用了每个key和value,key和value都无法回收,又因为key是ThreadLocal变量,从而引用了ThreadLocal的实例对象无法被回收,造成内存泄露。
1387+
1388+
2.如果使用弱引用,不会影响key的回收,也就是不会影响引用了ThreadLocal的实例对象的回收,但是value依然不会被回收,会造成内存泄露。
1389+
1390+
value回收的时机有两个:
1391+
1392+
1.我们在用完ThreadLocal后,手动调用ThreadLocal#remove()对键值对value释放。
1393+
1394+
2.此线程在其他对象中使用ThreadLocal对线程ThreadLocalMap进行set()和get()时,由于需要进行开放定址法进行探测,会对沿途过期的键值对(就是key为null的键值对)进行清除。以及set()方法触发的cleanSomeSlots()方法对过期键值对进行清除。
1395+
1396+
![thread](../static/thread.png)
1397+
1398+
[《一篇文章,从源码深入详解ThreadLocal内存泄漏问题》](https://www.jianshu.com/p/dde92ec37bd1)

docs/algorithm.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@
1010
#### [8.编辑距离](#编辑距离)
1111
#### [9.打印杨辉三角](#打印杨辉三角)
1212

13-
14-
15-
16-
1713
### 常见的排序算法
1814

1915
![img](../static/640-2913012.png)
@@ -52,7 +48,7 @@ int[] sorted(int[] array) {
5248

5349
## 插入排序
5450

55-
就是每次从未排好序的序列中,每次取出一个元素,插入到已排好序的序列中去。
51+
就是每次从未排好序的序列中,每次取出一个元素,插入到已排好序的序列中去。比较好的写法就是数组前面一段是排好序的,这一段往前面进行比较然后互换。
5652

5753
```java
5854
int[] sorted2(int[] array) {

static/thread.png

78.3 KB
Loading

0 commit comments

Comments
 (0)