Skip to content

Commit c2e4adb

Browse files
committed
change image
1 parent 06befc9 commit c2e4adb

18 files changed

+179
-55
lines changed

docs/HashMap.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ table = newTab;
502502
hash%length=hash&(length-1)
503503
```
504504

505-
而因为length是2的N次幂,length-1在二进制中其实是N-1个1。例如:
505+
而因为length是2的N次幂,length-1在二进制中其实是N个1。例如:
506506

507507
length为16,length用2进制表示是10000,
508508

docs/JavaJVM.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1178,7 +1178,7 @@ class name列:表示的就是当前类的名称,class name 对于基本数
11781178

11791179
##### jmap -dump
11801180

1181-
使用`jmap -dump:format=b,file=dump.hprof 进程id`可以生成当前的堆栈快照,堆快照和对象统计信息,对生成的堆快照进行分析,可以分析堆中对象所占用内存的情况,检查大对象等。执行`jvisualvm`命令打开使用Java自带的工具Java VisualVM来打开堆栈快照文件,进行分析。可以用于排查内存溢出,内存泄露问题。在Java VisualVM里面可以看到每个类的实例对象占用的内存大小,以及持有这个对象的实例所在的类等等信息。
1181+
使用`jmap -dump:format=b,file=dump.hprof 进程id`可以生成当前的堆栈快照,堆快照和对象统计信息,对生成的堆快照进行分析,可以分析堆中对象所占用内存的情况,检查大对象等。执行`jvisualvm`命令打开使用Java自带的工具**Java VisualVM**来打开堆栈快照文件,进行分析。可以用于排查内存溢出,内存泄露问题。在**Java VisualVM**里面可以看到每个类的实例对象占用的内存大小,以及持有这个对象的实例所在的类等等信息。
11821182

11831183
也可以配置启动时的JVM参数,让发送内存溢出时,自动生成堆栈快照文件。
11841184

docs/JavaMultiThread.md

Lines changed: 61 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ Linux系统会给每个进程分配4G的虚拟地址空间(0到3G是User地址
5454

5555
五态模型一般指的是:
5656

57-
新建态(创建一个进程)
57+
**新建态**(创建一个进程)
5858

59-
就绪态(已经获取到资源,准备好了,进入运行队列,一旦获得时间片可以立即执行)
59+
**就绪态**(已经获取到资源,准备好了,进入运行队列,一旦获得时间片可以立即执行)
6060

61-
运行态(获取到了时间片,执行程序)
61+
**运行态**(获取到了时间片,执行程序)
6262

63-
阻塞态(运行过程中等待获取其他资源,I/O请求等)
63+
**阻塞态**(运行过程中等待获取其他资源,I/O请求等)
6464

65-
终止态(进程被杀死了)
65+
**终止态**(进程被杀死了)
6666

6767
#### 并发性
6868

@@ -204,7 +204,7 @@ class ThreadTarget implements Runnable {
204204

205205
##### 原理
206206

207-
之所以有这种实现方法,是因为Thread类的run方法中会判断成员变量target是否为空,不为空就会调用target类的run方法。
207+
之所以有这种实现方法,是因为Thread类的run()方法中会判断成员变量target是否为空,不为空就会调用target类的run方法。
208208

209209
```java
210210
private Runnable target;
@@ -258,7 +258,7 @@ thread.start()
258258

259259
#### 第三种 实现Callable接口
260260

261-
Runnable接口中的run方法是没有返回值,如果我们需要执行的任务带返回值就不能使用Runnable接口。创建一个类CallableTarget,实现Callable接口,实现带有**返回值的call()方法**,然后根据CallableTarget创建一个任务FutureTask,然后根据FutureTask来创建一个线程Thread,调用Thread的start方法可以执行任务。
261+
Runnable接口中的run()方法是没有返回值,如果我们需要执行的任务带返回值就不能使用Runnable接口。创建一个类CallableTarget,实现Callable接口,实现带有**返回值的call()方法**,然后根据CallableTarget创建一个任务FutureTask,然后根据FutureTask来创建一个线程Thread,调用Thread的start方法可以执行任务。
262262

263263
```java
264264
public class CallableTarget implements Callable<Integer> {
@@ -386,6 +386,40 @@ public interface RunnableFuture<V> extends Runnable, Future<V> {
386386
}
387387
```
388388

389+
##### 使用案例
390+
391+
使用时,Runnable实现类的实例可以作为Thread的入参使用,而Callable只能使用FutureTask进行封装使用。
392+
393+
```java
394+
//Runnable配合Thread进行使用
395+
Thread threadA = new Thread(new Runnable() {
396+
@Override
397+
public void run() {
398+
//任务的代码
399+
}
400+
});
401+
402+
//Callable使用FutureTask封装后,配合线程池进行使用
403+
ExecutorService pool = Executors.newSingleThreadExecutor();
404+
FutureTask task = new FutureTask(new Callable() {
405+
@Override
406+
public Object call() throws Exception {
407+
//任务的代码
408+
return null;
409+
}
410+
});
411+
pool.submit(task);
412+
413+
//Runnable使用FutureTask封装后,配合线程池进行使用
414+
FutureTask task1 = new FutureTask(new Runnable() {
415+
@Override
416+
public void run() {
417+
//任务的代码
418+
}
419+
});
420+
pool.submit(task1);
421+
```
422+
389423
### Java中单例有哪些写法?
390424

391425
正确并且可以做到延迟加载的写法其实就是三种:
@@ -762,14 +796,11 @@ static void ensure_join(JavaThread* thread) {
762796

763797
thread->clear_pending_exception();
764798

765-
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
766-
799+
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
767800
java_lang_Thread::set_thread(threadObj(), NULL);
768-
769801
//同志们看到了没,别的不用看,就看这一句
770802
//thread就是当前线程,是啥?就是刚才例子中说的threadA线程
771803
lock.notify_all(thread);
772-
773804
thread->clear_pending_exception();
774805
}
775806
```
@@ -848,24 +879,24 @@ FutureTask提供了cancel(boolean mayInterruptIfRunning)方法来取消任务,
848879
示例代码如下:
849880

850881
```java
851-
Thread threadA = new Thread(new Runnable() {
852-
@Override
853-
public void run() {
882+
Thread threadA = new Thread(new Runnable() {
883+
@Override
884+
public void run() {
854885
//执行threadA的任务
855-
}
856-
});
857-
Thread threadB= new Thread(new Runnable() {
858-
@Override
859-
public void run() {
860-
//执行threadB的任务
861-
}
862-
});
863-
//执行线程A任务
864-
threadA.start();
865-
//主线程进行等待
866-
threadA.join();
867-
//执行线程B的任务
868-
threadB.start();
886+
}
887+
});
888+
Thread threadB= new Thread(new Runnable() {
889+
@Override
890+
public void run() {
891+
//执行threadB的任务
892+
}
893+
});
894+
//执行线程A任务
895+
threadA.start();
896+
//主线程进行等待
897+
threadA.join();
898+
//执行线程B的任务
899+
threadB.start();
869900
```
870901

871902
##### 子线程Join
@@ -1422,9 +1453,9 @@ public ThreadPoolExecutor(int corePoolSize,
14221453

14231454
从阻塞队列取任务时,如果阻塞队列为空:
14241455

1425-
核心线程的会一直卡在`workQueue.take`方法,被阻塞并挂起,不会占用CPU资源。
1456+
**核心线程**的会一直卡在`workQueue.take`方法,被阻塞并挂起,不会占用CPU资源。
14261457

1427-
非核心线程会调用workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS)方法取任务 ,如果超过keepAliveTime时间后还没有拿到,下一次循环判断**compareAndDecrementWorkerCount**就会返回`null`,Worker对象的`run()`方法循环体的判断为`null`,任务结束,然后线程被系统回收)
1458+
**非核心线程**会调用workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS)方法取任务 ,如果超过keepAliveTime时间后还没有拿到,下一次循环判断**compareAndDecrementWorkerCount**就会返回`null`,Worker对象的`run()`方法循环体的判断为`null`,任务结束,然后线程被系统回收)
14281459

14291460
##### 2.maximumPoolSize 最大线程数
14301461

@@ -1611,8 +1642,6 @@ ThreadPoolExecutor提供了如下几个public的setter方法
16111642

16121643
![image-20210119104549770](../static/image-20210119104549770.png)
16131644

1614-
1615-
16161645
调用corePoolSize方法之后,线程池会直接覆盖原来的corePoolSize值,并且基于当前值和原始值的比较结果采取不同的处理策略。(总得来说就是,多退少补的策略)
16171646

16181647
**对于新corePoolSize<当前工作线程数的情况:**

docs/MySQLNote.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,23 +1016,22 @@ EXPLAIN SELECT * FROM res_user ORDER BYmodifiedtime LIMIT 0,1000
10161016
table | type | possible_keys | key |key_len | ref | rows | Extra EXPLAIN列的解释:
10171017

10181018
- table 显示这一行的数据是关于哪张表的
1019-
- type 这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL
1019+
- type 这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、index和ALL
1020+
- ref 表里面的哪个索引被用到了
10201021
- rows 显示需要扫描行数
10211022
- key 使用的索引
10221023

1023-
const就是针对主键或者唯一性索引的等值查询,通过索引查找一次就行了。仅仅是查一条数据。
1024+
const就是针对主键或者唯一性索引的等值查询,通过索引查找一次就行了。仅仅是查一条数据。
10241025

1025-
eq_ref 唯一性索引键扫描,对于每个索引键,表中只有一条数据与其对应,例如join查询时,对于前表查出的结果集,每个结果在第二个表只有一条数据对应。
1026+
eq_ref 唯一性索引键扫描,对于每个索引键,表中只有一条数据与其对应,例如join查询时,对于前表查出的结果集,每个结果在第二个表只有一条数据对应。
10261027

1027-
ref 非唯一性索引查询
1028-
1029-
ref : 此类型通常出现在多表的 join 查询, 针对于非唯一或非主键索引, 或者是使用了 `最左前缀` 规则索引的查询. 关键字:非唯一性索引
1028+
ref 非唯一性索引查询 此类型通常出现在多表的 join 查询, 针对于非唯一或非主键索引, 或者是使用了 `最左前缀` 规则索引的查询. 关键字:非唯一性索引
10301029

10311030
ref_or_null:与ref方法类似,只是增加了null值的比较。
10321031

1033-
`range`: 表示使用索引范围查询, 通过索引字段范围获取表中部分数据记录. 这个类型通常出现在 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN() 操作中.
1032+
range: 表示使用索引范围查询, 通过索引字段范围获取表中部分数据记录. 这个类型通常出现在 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, IN() 操作中.
10341033

1035-
`index`: 表示全索引扫描(full index scan), 关键字:查询字段和条件都是索引本身
1034+
index: 表示全索引扫描(full index scan), 关键字:查询字段和条件都是索引本身
10361035

10371036
index_merge:表示查询使用了两个以上的索引,最后取交集或者并集,常见and ,or的条件使用了不同的索引.效率不是很高 关键字:索引合并
10381037

@@ -1114,9 +1113,11 @@ SELECT * FROM test where id > 100 AND name = '123'
11141113
https://dev.mysql.com/doc/refman/5.7/en/index-condition-pushdown-optimization.html
11151114
11161115
##### Using filesort
1117-
如果在关联表查询时,Order By的所有字段都来自第一个表(也就是驱动表),那么在处理驱动表时,从驱动表中取出满足条件的结果集时就会进行排序,不需要使用临时表存储数据行,进行重排序。
1116+
1117+
如果在关联表查询时,Order By的所有字段都来自第一个表(也就是驱动表),那么在处理驱动表时,从驱动表中取出满足条件的结果集时就会进行排序,不需要使用临时表存储数据行进行重排序,extral那一列就会显示是Using index。如果Order By的字段不在索引中,那么就需要在查找出结果集后,进行重排序,就会显示Using filesort。
11181118
##### Using temporary; Using fileSort
1119-
再进行关联表查询时,如果Order By的字段不全是来自驱动表,那么会把关联结果存放在临时表中,等所有的关联都结束后,再在内存中对数据行进行排序。
1119+
1120+
再进行关联表查询时,如果Order By中的字段不全是来自驱动表,也就是使用了被驱动表中的字段进行排序,那么会把关联结果全部查找出来,存放在临时表中,等所有的关联都结束后,再在内存中对数据行进行排序。
11201121
11211122
##### 优化的方法:
11221123

docs/RedisBasic.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,8 @@ https://xie.infoq.cn/article/b3816e9fe3ac77684b4f29348
249249

250250
### 同步与异步的区别是什么?
251251
同步与异步的区别在于调用结果的通知方式上。
252-
同步执行一个方法后,需要等待结果返回,然后继续执行下去。
253-
异步执行一个方法后,不会等待结果的返回,调用方定时主动去轮询调用结果或者被调用方在执行完成后通过回调来通知调用方
252+
同步执行一个方法后,需要等待结果返回轮询调用结果才能继续执行,然后继续执行下去。
253+
异步执行一个方法后,不会等待结果的返回,被调用方在执行完成后通过回调来通知调用方继续执行
254254

255255
### 阻塞与非阻塞的区别是什么?
256256
阻塞与非阻塞的区别在于进程/线程在等待消息时,进程/线程是否是挂起状态。
@@ -291,7 +291,7 @@ Redis 缓存穿透指的是攻击者故意大量请求一些Redis缓存中不存
291291

292292
1.在给缓存设置失效时间时加一个随机值,避免集体失效。
293293

294-
2.双缓存机制,缓存A的失效时间为20分钟,缓存B没有失效时间,从缓存A读取数据,缓存A中没有时,去缓存B中读取数据,并且启动一个异步线程来更新缓存A。
294+
2.双缓存机制,缓存A的失效时间为20分钟,缓存B的失效时间会比A长一些,从缓存A读取数据,缓存A中没有时,去缓存B中读取数据,并且启动一个异步线程来更新缓存A(如果已经有异步线程正在更新了,就不用重复更新了)。以及更新缓存B,以便延迟B的过期时间
295295

296296
### 如何解决缓存与数据库的数据一致性问题?
297297

docs/Spring.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,23 @@ IOC就是invention of control,就是控制反转,将对象获取外界依赖
169169
DI(Dependency Injection,依赖注入)其实就是IOC的另外一种说法,就是IOC是通过依赖注入技术实现的。
170170
《跟我学spring3系列》https://www.iteye.com/blog/jinnianshilongnian-1413851
171171
https://www.cnblogs.com/xdp-gacl/p/4249939.html
172+
173+
### Spring IOC是怎么解决循环依赖问题的?
174+
175+
Spring使用了3Map来保存Bean,俗称为三级依赖:
176+
177+
singletonObjects 一级缓存,用于保存实例化、注入、初始化完成的bean实例,可以使用的。
178+
179+
earlySingletonObjects 二级缓存,用于保存依赖注入完成的bean实例,但是没有完成初始化完成的bean。
180+
181+
singletonFactories 三级缓存,用于保存bean创建工厂,以便于后面扩展有机会创建代理对象,此时的bean是没有完成属性填充的。
182+
183+
184+
185+
假设A类和B类相互依赖,A中有一个B类的属性,B中有一个A类的属性。那么在初始化ABean时,首先会依次去一级依赖,去二级依赖,三级依赖中去找,都没有就调用创建方法创建实例A,将A添加到三级依赖中,然后对A的属性进行依赖注入,填充属性时,发现BBean在各级依赖中都没有,就创建B的bean添加到三级依赖,然后对B的属性进行填充,填充B的属性A时,会从三级依赖中取出A,填充完放到二级依赖,然后对B进行初始化,初始化完成添加到一级依赖。B初始化完成后,将B从一级依赖中,填充到实例AA可以进入到二级依赖,完全初始化完成后,A进入到一级依赖,供用户代码使用。
186+
187+
![img](../static/d7687db8ecbd43a79d041badf07bbaf4~tplv-k3u1fbpfcp-watermark.image)
188+
189+
https://juejin.cn/post/6911692836714840077
190+
191+
https://segmentfault.com/a/1190000015221968

0 commit comments

Comments
 (0)