forked from hollischuang/toBeTopJavaer
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathREADME.md
More file actions
1958 lines (1316 loc) · 60.1 KB
/
Copy pathREADME.md
File metadata and controls
1958 lines (1316 loc) · 60.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
[](https://www.hollischuang.com)
## To Be Top Javaer - Java工程师成神之路
  
| 主要版本 | 更新时间 | 备注 |
| ---- | ---------- | -------------- |
| v1.0 | 2015-08-01 | 首次发布 |
| v1.1 | 2018-03-12 | 增加新技术知识、完善知识体系 |
| v2.0 | 2019-02-19 | 结构调整,更适合从入门到精通;<br>进一步完善知识体系; <br>新技术补充;|
[全套思维导图](/mind-map.md)
## 一、基础篇
### 面向对象
#### 什么是面向对象
[面向对象、面向过程](/basics/java-basic/object-oriented-vs-procedure-oriented.md)
> 面向过程:以事件为中心,按照时间发生的顺序,调用一系列函数。开发简单但是不易于维护。
>
> 面向对象:以对象为中心,把涉及到的事物抽象成对象。好处:结构化、模块化,易于维护。
> [https://zhuanlan.zhihu.com/p/28427324](https://zhuanlan.zhihu.com/p/28427324)
[面向对象的三大基本特征](/basics/java-basic/characteristics.md)和[五大基本原则](/basics/java-basic/principle.md)
> 《think in java》第一章有介绍
>
> 封装、继承、多态:
>
> 封装:一些内部数据可以被不被暴露给外部访问,从而保护数据的安全。可以通过private、protected等关键字实现。
>
> 继承:子类继承父类,可以复用父类的方法什么的。
>
> 多态:后期绑定/动态绑定/运行时绑定。多态机制使具有不同内部结构的对象可以共享相同的外部接口。
>
> 前期绑定:程序执行前就进行绑定,由编译器和连接程序实现
>
> 后期绑定:运行时根据对象的类型进行绑定。对象种会有某种类型信息
>
> 绑定:把方法调用同方法主体关联起来。
>
> http://www.cnblogs.com/hnrainll/archive/2012/09/18/2690846.html
>
>
> 组合优于继承,组合确实比继承更加灵活,也更有助于代码维护。
>
> 继承:会破坏代码的封装性,子类与父类之间紧密耦合,子类依赖于父类的实现,子类缺乏独立性
>
> 组合 vs 继承:https://www.hollischuang.com/archives/1319
>
>
>
> 单一职责原则:一个类,最好只做一件事
>
> 开闭原则:软件实体应该是可扩展的,而不可修改的
>
> 里氏替换原则:子类必须能够替换其基类
>
> 依赖倒置:依赖于抽象。具体而言就是高层模块不依赖于底层模块,在依赖之间定义一个抽象的接口使得高层模块调用接口,而底层模块实现接口的定义
>
> 接口隔离:用多个小的专门的接口,而不要使用一个大的总接口。一个类对另外一个类的依赖应该建立在最小的接口上,不要强迫依赖不用的方法,这是一种接口污染。
>
> https://www.hollischuang.com/archives/220
#### 平台无关性
[Java如何实现的平台无关性的](/basics/java-basic/platform-independent.md)
> 平台无关有两种:源代码级和目标代码级。
>
> 我们常说的跨平台,或者平台无关,指的就是目标代码,或者说是软件交付件跨平台。
>
> Java源码编译出来的字节码文件,JVM会解析翻译成机器语言,即JVM帮我们把字节码翻译成机器语言的过程中就已经充分考虑到对应平台的特性了。
[JVM还支持哪些语言(Kotlin、Groovy、JRuby、Jython、Scala)](/basics/java-basic/jvm-language.md)
> ErJang、Clojure
>
> https://coolshell.cn/articles/2631.html
>
> https://www.zhihu.com/question/20003582
#### 值传递
[值传递、引用传递](/basics/java-basic/java-pass-by.md)
> 基本类型一般是值传递、引用类型一般是引用传递
>
> https://www.zhihu.com/question/31203609/answer/50992895
[为什么说Java中只有值传递](/basics/java-basic/java-pass-by.md)
> 当传入引用类型的时候,传入的是引用类型的地址,当修改这个传入变量的地址后,其实已经是在修改另一个对象了,所以说并没有修改原来的对象。
>
> | | 值传递 | 引用传递 |
> | -------- | :--------------------: | :--------------------: |
> | 根本区别 | 会创建副本对象 | 不创建副本对象 |
> | 所以 | 函数中无法改变原始对象 | 函数中可以改变原始对象 |
#### 封装、继承、多态
[什么是多态](/basics/java-basic/polymorphism.md)、[方法重写与重载](/basics/java-basic/overloading-vs-overriding.md)
> 重载:同一个类中的方法,有相同的函数名,但是有不同的参数列表
>
> 重写:子类重写父类方法
>
> https://www.hollischuang.com/archives/1308
为什么函数签名没有返回值?
> 只要编译器可以根据语境明确判断出语义,比如在int x =f()中,那么的确可以据此却分重载方法。不过,有时你并不关心方法的返回值,你想要的是方法调用的其他效果,这时你可能会调用方法而忽略其返回值。所以,如果像下面这样调用方法:
> f();
>
> https://bluestar.iteye.com/blog/416527
Java的继承与实现
> implements 可以实现多重继承
interface 和 abstract 区别?
> https://data-flair.training/blogs/java-extends-vs-implements/
构造函数与默认构造函数
[Java的继承与组合](/basics/java-basic/inheritance-composition.md)
[构造函数与默认构造函数](/basics/java-basic/constructor.md)
[类变量、成员变量和局部变量](/basics/java-basic/variable.md)
[成员变量和方法作用域](/basics/java-basic/scope.md)
### Java基础知识
#### 基本数据类型
[7种基本数据类型:整型、浮点型、布尔型、字符型](/basics/java-basic/basic-data-types.md)
[整型中byte、short、int、long的取值范围](/basics/java-basic/integer-scope.md)
[什么是浮点型?](/basics/java-basic/float.md)
[什么是单精度和双精度?](/basics/java-basic/single-double-float.md)
[为什么不能用浮点型表示金额?](/basics/java-basic/float-amount.md)
> 浮点数会有精度丢失的问题,可以用 BigDecimal
>
> https://blog.csdn.net/bruce128/article/details/52529734
#### 自动拆装箱
[什么是包装类型、什么是基本类型、什么是自动拆装箱](/basics/java-basic/boxing-unboxing.md)
[Integer的缓存机制](/basics/java-basic/integer-cache.md)
> -128 ~ 127 缓存
>
> 可以通过vm potion `-XX:AutoBoxCacheMax=1000`可以修改,注意最小也是127。
>
> ```java
> /**
> * Cache to support the object identity semantics of autoboxing for values between
> * -128 and 127 (inclusive) as required by JLS.
> *
> * The cache is initialized on first usage. The size of the cache
> * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
> * During VM initialization, java.lang.Integer.IntegerCache.high property
> * may be set and saved in the private system properties in the
> * sun.misc.VM class.
> */
>
> private static class IntegerCache {
> static final int low = -128;
> static final int high;
> static final Integer cache[];
>
> static {
> // high value may be configured by property
> int h = 127;
> String integerCacheHighPropValue =
> sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
> if (integerCacheHighPropValue != null) {
> try {
> int i = parseInt(integerCacheHighPropValue);
> i = Math.max(i, 127);
> // Maximum array size is Integer.MAX_VALUE
> h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
> } catch( NumberFormatException nfe) {
> // If the property cannot be parsed into an int, ignore it.
> }
> }
> ```
>
> Integer的缓存上限可以通过Java虚拟机参数修改,Byte、Short、Long、Character的缓存则没法修改。
>
> https://www.jianshu.com/p/c12ab3f675cc
#### String
[字符串的不可变性](/basics/java-basic/final-string.md)
[JDK 6和JDK 7中substring的原理及区别](/basics/java-basic/substring.md)
replaceFirst、replaceAll、replace区别、
[String对“+”的重载](/basics/java-basic/string-append.md)
[字符串拼接的几种方式和区别](/basics/java-basic/string-concat.md)
[String.valueOf和Integer.toString的区别](/basics/java-basic/value-of-vs-to-string.md)
[switch对String的支持](/basics/java-basic/switch-string.md)
字符串池、常量池(运行时常量池、Class常量池)、intern
StringBuilder和StringBuffer?
> StringBuffer的方法都加了 synchronized 。属于比较早期的类,虽然线程安全,但是没啥使用场景?
>
> JDK1.5 提供了 StringBuilder.
>
> JAVA 中的 StringBuilder 和 StringBuffer 适用的场景是什么? - 小猪的回答 - 知乎
> https://www.zhihu.com/question/20101840/answer/164866159
#### 熟悉Java中各种关键字
transient、instanceof、volatile、synchronized、final、static、const 原理及用法。
> transient:控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。
>
> https://www.hollischuang.com/archives/1150
>
> serialVersionUID:控制反序列化
>
> https://github.com/husterxsp/java-learning/blob/master/daily/083-serialVersionUID.md
>
> instanceof:判断是否有父类、子类以及实现接口的关系
>
> https://stackoverflow.com/questions/7526817/use-of-instance-of-in-java
>
> volatile:原子性、可见性(参见《java并发编程的艺术》)
>
> synchronized:通过字节码指令`monitorenter`和`monitorexit` 加锁(参见《java并发编程的艺术》)
>
> final:
>
> static:
>
> const:
#### 集合类
常用集合类的使用
[ArrayList和LinkedList和Vector的区别](/basics/java-basic/arraylist-vs-linkedlist-vs-vector.md)
[SynchronizedList和Vector的区别](/basics/java-basic/synchronizedlist-vector.md)、
[HashMap、HashTable、ConcurrentHashMap区别](/basics/java-basic/HashMap-HashTable-ConcurrentHashMap.md)
[Set和List区别?](/basics/java-basic/set-vs-list.md)
[Set如何保证元素不重复?](/basics/java-basic/set-repetition.md)
[Java 8中stream相关用法](/basics/java-basic/stream.md)、
apache集合处理工具类的使用、
不同版本的JDK中HashMap的实现的区别以及原因
[Collection和Collections区别](/basics/java-basic/Collection-vs-Collections.md)
[Arrays.asList获得的List使用时需要注意什么](/basics/java-basic/Arrays-asList.md)
[Enumeration和Iterator区别](/basics/java-basic/Enumeration-vs-Iterator.md)
[fail-fast 和 fail-safe](/basics/java-basic/fail-fast-vs-fail-safe.md)
[CopyOnWriteArrayList](/basics/java-basic/CopyOnWriteArrayList.md)
[ConcurrentSkipListMap](/basics/java-basic/ConcurrentSkipListMap.md)
#### 枚举
[枚举的用法](/basics/java-basic/enum-usage.md)
[枚举的实现](/basics/java-basic/enum-impl.md)
[枚举与单例](/basics/java-basic/enum-singleton.md)、Enum类
[Java枚举如何比较](/basics/java-basic/enum-compare.md)
[switch对枚举的支持](/basics/java-basic/enum-switch.md)
[枚举的序列化如何实现](/basics/java-basic/enum-serializable.md)
[枚举的线程安全性问题](/basics/java-basic/enum-thread-safe.md)
#### IO
[字符流、字节流](/basics/java-basic/byte-stream-vs-character-stream.md)、[输入流、输出流](/basics/java-basic/input-stream-vs-output-stream.md)
> 知识星球IO专题
>
> 字节流逐字节地访问文件。字节流适用于任何类型的文件,但不太适合文本文件(txt文件)。例如,如果文件使用的是unicode编码,而字符用两个字节表示,则字节流将会将这个字符分开处理,因而自己还需要做转换。
>
> 字符流将逐个字符地读取文件。需要为字符流提供文件的编码才能正常工作。
>
> 字节流类继承自抽象类 InputStream 和 OutputStream。 字符流类继承自抽象类 Reader 和 Writer。
>
> 输入输出以内存为参照:输入是从外存读入内存
>
> https://github.com/husterxsp/java-learning/blob/master/daily/092-byte-and-character-stream.md
同步、异步、阻塞、非阻塞、Linux 5种IO模型
> 同步,异步,是描述被调用方的。
> 阻塞,非阻塞,是描述调用方的。主要是从CPU的消耗上来说的。阻塞就是CPU停下等待。非阻塞看起来效率高,但是会有线程切换的代价。
>
>
>
> Linux 5种IO模型
>
> - 阻塞式IO模型
> - 非阻塞IO模型
> - IO复用模型
> - 信号驱动IO模型
> - 异步IO模型
BIO、NIO和AIO的区别、三种IO的用法与原理、netty
[同步、异步](/basics/java-basic/synchronized-vs-asynchronization.md)、[阻塞、非阻塞](/basics/java-basic/block-vs-non-blocking.md)、[Linux 5种IO模型](/basics/java-basic/linux-io.md)
[BIO、NIO和AIO的区别、三种IO的用法与原理](/basics/java-basic/bio-vs-nio-vs-aio.md)、netty
> BIO:阻塞IO。java.io 下面的实现
>
> NIO:非阻塞IO。java.nio下的实现
>
> 关键组件 Selector、Channel、Buffer。(《深入分析Java web》)
>
> AIO:异步非阻塞。也在java.nio下面,比如 AsynchronousFileChannel。channel.read 返回的是 future对象
>
> BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
>
> NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
>
> AIO方式适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
>
> netty:Netty 封装了 JDK 的 NIO,不用再写一大堆复杂的代码了。(掘金小册:<https://juejin.im/book/5b4bc28bf265da0f60130116/section/5b4bc28b5188251b1f224ee5>)
#### Java反射与javassist
[反射](/basics/java-basic/reflection.md)与工厂模式、 [反射有什么作用](/basics/java-basic/usage-of-reflection.md)
> **反射** 机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有属性和方法。(星球直面java系列 140期)
>
> 作用:
>
> - 在运行时判断任意一个对象所属的类。
> - 在运行时判断任意一个类所具有的成员变量和方法。
> - 在运行时任意调用一个对象的方法
> - 在运行时构造任意一个类的对象
>
> 反射有哪些优缺点?
>
> 优点
>
> - 反射提高了程序的灵活性和扩展性。
>
> 缺点
>
> - 代码可读性低及可维护性
>
> - 反射代码执行的性能低
>
> - 破坏了封装性。
>
> - 在业务代码中应该尽量避免使用反射。但是,作为一个合格的Java开发,也要能读懂中间件、框架中的反射代码。在有些场景下,要知道可以使用反射解决部分问题。
>
> 反射与工厂模式
> <http://www.hollischuang.com/archives/1163>
[Class类](/basics/java-basic/Class.md)
`java.lang.reflect.*`
> Java的Class类是java反射机制的基础,通过Class类我们可以获得关于一个类的相关信息
>
> Java.lang.Class是一个比较特殊的类,它用于封装被装入到JVM中的类(包括类和接口)的信息。当一个类或接口被装入的JVM时便会产生一个与之关联的java.lang.Class对象,可以通过这个Class对象对被装入类的详细信息进行访问。
>
> 虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每个类(型)都有一个Class对象。运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。(直面java 144)
>
>
>
> Class.forName(“com.test.Foo”) 加载类
>
> 再看
反射的用法?
> 动态代理
> JDBC的class.forName
> BeanUtils中属性值的拷贝
> RPC框架
> ORM框架
> Spring的IOC/DI
#### 动态代理
[静态代理](/basics/java-basic/static-proxy.md)、[动态代理](/basics/java-basic/dynamic-proxy.md)
> 静态代理相当于给原来的方法再包装一层:比如可以记录日志、控制对象访问权限,增强对象功能。
>
> 比如可以实现接口,调用委托类的方法。
>
> 静态代理,需要写很多代码。然后就有了动态代理。
>
> 动态代理中的代理类并不要求在编译期就确定,而是可以在运行期动态生成,从而实现对目标对象的代理功能。
>
动态代理和反射的关系
> 反射是动态代理的一种实现方式。
动态代理的几种实现方式
> jdk动态代理和cglib动态代理
>
> <http://www.iocoder.cn/RPC/laoxu/rpc-dynamic-proxy//>
>
> [Java中的动态代理有几种实现方式,各有什么优缺点](<https://github.com/husterxsp/java-learning/blob/master/daily/150-Java%E4%B8%AD%E7%9A%84%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E6%9C%89%E5%87%A0%E7%A7%8D%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F%EF%BC%8C%E5%90%84%E6%9C%89%E4%BB%80%E4%B9%88%E4%BC%98%E7%BC%BA%E7%82%B9.md>)
>
> Java Proxy 和 CGLIB 动态代理原理:<http://www.importnew.com/27772.html>
>
> FastClass:<https://www.jianshu.com/p/13aa63e1ac95>
>
> - JDK动态代理原理和静态代理类似,只不过是动态生成字节码的。
>
> java.lang.reflect 包中的Proxy类和InvocationHandler接口提供了生成动态代理类的能力。
>
> Cglib是一个第三方代码生成类库,运行时在内存中动态生成一个子类对象从而实现对目标对象功能的扩展。
>
> Cglib与JDK动态代理最大的区别就是:
>
> - 使用动态代理的对象必须实现一个或多个接口
> - 使用cglib代理的对象则无需实现接口,达到代理类无侵入。
> - cglib是通过继承来实现的代理。
问:Java 实现动态代理主要涉及哪几个类?(直面java153)
> java.lang.reflect.Proxy: 这是生成代理类的主类,通过 Proxy 类生成的代理类都继承了 Proxy 类,即 DynamicProxyClass extends Proxy。
> java.lang.reflect.InvocationHandler: 这里称他为"调用处理器",他是一个接口,我们动态生成的代理类需要完成的具体内容需要自己定义一个类,而这个类必须实现 InvocationHandler 接口。
AOP(直面java156)
> 动态代理。
>
> Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。
> JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。
> 如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。
> CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为**final**,那么它是无法使用CGLIB做动态代理的。
[动态代理和反射的关系](/basics/java-basic/dynamic-proxy-vs-reflection.md)
[动态代理的几种实现方式](/basics/java-basic/dynamic-proxy-implementation.md)
[AOP](/basics/java-basic/aop-vs-proxy.md)
#### 序列化
什么是序列化与反序列化、为什么序列化、序列化底层原理、序列化与单例模式、protobuf、为什么说序列化并不安全
><http://www.hollischuang.com/archives/1150>
>
>序列化是将对象转换为可传输格式的过程。 是一种数据的持久化手段。一般广泛应用于网络传输,RMI和RPC等场景中。
>
>Serializable接口:
>
>Externalizable接口:需要重写writeExternal()与readExternal()
>
>序列化会破坏单例模式
>
>- 因为 序列化会通过反射调用无参数的构造方法创建一个新的对象。
>
><https://www.hollischuang.com/archives/1144>
>
>protobuf:一种序列化协议
>
>安全性:<https://www.secpulse.com/archives/60819.html>
>
>- 由于对象序列化是遵循标准协议的,所以可以轻易地分析出流中的信息,并且可以进行篡改
>- 解决
> - 对数据加密
> - 对传输加密
> - 使用transient字段,敏感字段不序列化
#### 注解
元注解、自定义注解、Java中常用注解使用、注解与反射的结合
> 元注解:定义其他注解的注解 。元注解有四个:@Target(表示该注解可以用于什么地方)、@Retention(表示再什么级别保存该注解信息)、@Documented(将此注解包含再javadoc中)、@Inherited(允许子类继承父类中的注解)
>
> 自定义注解:除了元注解,都是自定义注解。通过元注解定义出来的注解。如我们常用的Override 、Autowire等。日常开发中也可以自定义一个注解,这些都是自定义注解。
>
> JDK内置的常用注解:
>
> 1.@Override 表示当前方法覆盖了父类的方法
> 2.@Deprecation 表示方法已经过时,方法上有横线,使用时会有警告。
> 3.@SuppressWarnings 表示关闭一些警告信息(通知java编译器忽略特定的编译警告)
>
注解是什么?谈谈你的理解?
> 应该是能简化用户编程。
>
> "可以理解为是一个标签 " https://blog.csdn.net/briblue/article/details/73824058
Spring常用注解
> 1. @Component指的是组件,
> @Controller,@Repository和@Service 注解都被@Component修饰,用于代码中区分表现层,持久层和业务层的组件,代码中组件不好归类时可以使用@Component来标注
> 2. 当前版本只有区分的作用,未来版本可能会添加更丰富的功能
#### JMS
什么是Java消息服务、JMS消息传送模型
#### JMX
`java.lang.management.*`、 `javax.management.*`
#### 泛型
泛型与继承、类型擦除、泛型中K T V E ? [object等的含义](/basics/java-basic/k-t-v-e.md)、泛型各种用法
限定通配符和非限定通配符、上下界限定符extends 和 super
List<Object>和原始类型List之间的区别?
List<?>和List<Object>之间的区别是什么?
#### 单元测试
junit、mock、mockito、内存数据库(h2)
#### 正则表达式
`java.lang.util.regex.*`
#### 常用的Java工具库
`commons.lang`, `commons.*...` `guava-libraries` `netty`
#### API&SPI
API、API和SPI的关系和区别
如何定义SPI、SPI的实现原理
> SPI:调用方来制定接口,实现方来针对接口来实现不同的实现。调用方来选择自己需要的实现方。
>
> 通过线程上下文类加载器去加载所需要的SPI代码。也就是父加载器请求子类加载器去完成类加载的动作。
>
> 读取META-INF/services/下的配置文件,获得所有能被实例化的类的名称
>
> 通过反射方法Class.forName()加载类对象,并用instance()方法将类实例化
什么是JNDI?
> <https://docs.oracle.com/javase/tutorial/jndi/overview/index.html>
>
>
#### 异常
异常类型、正确处理异常、自定义异常
Error和Exception
异常链、try-with-resources
finally和return的执行顺序
#### 时间处理
时区、冬令时和夏令时、时间戳、Java中时间API
格林威治时间、CET,UTC,GMT,CST几种常见时间的含义和关系
SimpleDateFormat的线程安全性问题
Java 8中的时间处理
如何在东八区的计算机上获取美国时间
#### 编码方式
Unicode、有了Unicode为啥还需要UTF-8
GBK、GB2312、GB18030之间的区别
UTF8、UTF16、UTF32区别
URL编解码、Big Endian和Little Endian
如何解决乱码问题
#### 语法糖
Java中语法糖原理、解语法糖
语法糖:switch 支持 String 与枚举、泛型、自动装箱与拆箱、方法变长参数、枚举、内部类、条件编译、 断言、数值字面量、for-each、try-with-resource、Lambda表达式、
### 阅读源代码
String、Integer、Long、Enum、BigDecimal、ThreadLocal、ClassLoader & URLClassLoader、ArrayList & LinkedList、 HashMap & LinkedHashMap & TreeMap & CouncurrentHashMap、HashSet & LinkedHashSet & TreeSet
> HashMap:死循环问题,<https://coolshell.cn/articles/9606.html>
>
>
### Java并发编程
#### 并发与并行
什么是并发
什么是并行
并发与并行的区别
#### 线程
线程的实现、线程的状态、优先级、线程调度、创建线程的多种方式、守护线程
线程与进程的区别
#### 线程池
自己设计线程池、submit() 和 execute()、线程池原理
为什么不允许使用Executors创建线程池
定时任务?
> ScheduledThreadPoolExecutor
>
> 内部会有一个优先队列,每个任务会有一个time,按照time由小到大排序,执行任务之后,再修改时间。
#### 线程安全
[死锁?](/basics/java-basic/deadlock-java-level.md)、死锁如何排查、线程安全和内存模型的关系
> jstack 查看线程状态:
>
> ```
> java.lang.Thread.State: WAITING (on object monitor)
>
> Found one Java-level deadlock:
>
> ...
> ```
>
>
#### 锁
CAS、乐观锁与悲观锁、数据库相关锁机制、分布式锁、偏向锁、轻量级锁、重量级锁、monitor、
锁优化、锁消除、锁粗化、自旋锁、可重入锁、阻塞锁、死锁
> CAS:compareAndSwap。一般是和循环一块儿使用。由底层C语言代码负责保证原子性。加锁。
>
> 这里说是给总线加锁?<https://juejin.im/post/5a73cbbff265da4e807783f5>
>
> CAS的问题:ABA问题。循环CPU消耗。解决使用版本号。
>
> ---
>
> 都是用在数据库里的。
>
> “悲观锁”,Pessimistic Concurrency Control,缩写“PCC”
>
> “乐观锁”,Optimistic Concurrency Control,缩写“OCC”
>
> <https://www.hollischuang.com/archives/934>
>
> ---
>
> 分布式锁的几种实现方式:<https://www.hollischuang.com/archives/1716>
>
> Zookeeper > 缓存 > 数据库
>
> Zookeeper分布式锁要详细了解。
>
> ---
>
> 偏向锁:对象头和栈帧的锁记录里存储偏向的线程ID,这样下次该线程进出同步块的时候不用CAS来加锁和解锁了,测试简单测试一下对象头里的标记。
>
> 轻量级锁:循环CAS设置。如果设置失败,会膨胀为重量级锁,即阻塞。?
>
> monitor:监视器。
>
> - <https://www.hollischuang.com/archives/2030>
> - <https://stackoverflow.com/questions/3362303/whats-a-monitor-in-java>
> - <https://dymanzy.github.io/2017/08/07/synchronized%E4%B8%8E%E5%AF%B9%E8%B1%A1%E7%9A%84Monitor/>
>
> monitor是一种机制,负责管理同步代码块的访问?每个对应的加锁的对象都有一个monitor对象?底层C实现的monitor对象。。。?其实底层是monitor在负责维护等待队列。
>
> ----
>
> 锁优化、粗化:<https://www.cnblogs.com/paddix/p/5405678.html>
>
> 锁粗化(Lock Coarsening):锁粗化的概念应该比较好理解,就是将多次连接在一起的加锁、解锁操作合并为一次,将多个连续的锁扩展成一个范围更大的锁。
>
>
#### 死锁
死锁的原因
> 对资源的竞争
>
> 产生死锁的四个必要条件:
> (1) 互斥条件:一个资源每次只能被一个进程(线程)使用。
> (2) 请求与保持条件:一个进程(线程)因请求资源而阻塞时,对已获得的资源保
>
> 持不放。
> (3) 不剥夺条件 : 此进程(线程)已获得的资源,在末使用完之前,不能强行剥夺。
>
> (4) 循环等待条件 : 多个进程(线程)之间形成一种头尾相接的循环等待资源关系。
死锁的解决办法
> 1. 增加资源,减少消费者?
> 2. 给资源编号,获取资源按照顺序来
> 3. 一次性获取所有资源再开始。
#### synchronized
[synchronized是如何实现的?](/basics/java-basic/synchronized.md)
synchronized和lock之间关系、[不使用synchronized如何实现一个线程安全的单例](https://mp.weixin.qq.com/s?__biz=MjM5OTMyNzQzMg==&mid=2257483772&idx=1&sn=24294a0e5b77aaf1fa671954d766ac3d&chksm=a447f45b93307d4d3baef97695874afc5fa478a399b1f6270ae5b4afdb9f0600eb0a6c9b65f2&mpshare=1&scene=1&srcid=0422XGfdHA1x7ucONJF3ttJt%23rd)
> synchronized是底层jdk实现的监视器锁 monitorenter 、monitorexit
>
> Lock的主要实现类ReentrantLock 用的是AQS,而AQS底层用的是volatile
>
> ```java
> /**
> * The synchronization state.
> */
> private volatile int state;
> ```
>
>
synchronized和原子性、可见性和有序性之间的关系
#### volatile
happens-before、内存屏障、编译器指令重排和CPU指令重
volatile的实现原理
volatile和原子性、可见性和有序性之间的关系
有了synchronized为什么还需要volatile
> synchronized是重量级锁,性能不高
#### sleep 和 wait
> 1
>
> sleep会不会释放锁,线程状态是TIME_WAITING
>
> sleep()方法正在执行的线程主动让出CPU
>
> wait会释放锁,线程状态WAITING
>
> 2
>
> sleep()方法可以在任何地方使用;wait()方法则只能在同步方法或同步块中使用;
>
> 3
>
> sleep()是线程线程类(Thread)的方法,调用会暂停此线程指定的时间,但监控依然保持,不会释放对象锁,到时间自动恢复;wait()是Object的方法,调用会放弃对象锁,进入等待队列,待调用notify()/notifyAll()唤醒指定的线程或者所有线程,才会进入锁池,不再次获得对象锁才会进入运行状态;
>
>
>
> https://blog.csdn.net/u012050154/article/details/50903326
#### wait 和 notify
> wait的等待队列?wait是jdk底层实现的。
>
> notify唤醒等待线程,重新参与cpu调度
#### notify 和 notifyAll
> notifyAll 唤醒所有 wait 线程
>
> notify 只随机唤醒一个 wait 线程
#### ThreadLocal
> 底层实现?
>
> 通过静态内部类ThreadLocalMap来保存线程本地变量。
>
> 线程终止的时候,这些变量也会被销毁(WeakReference的使用)
#### 写一个死锁的程序
#### 写代码来解决生产者消费者问题
> 用阻塞队列(分类?)
>
>
### 并发包
#### 阅读源代码,并学会使用
Thread、Runnable、Callable、ReentrantLock、ReentrantReadWriteLock、Atomic*、Semaphore、CountDownLatch、、ConcurrentHashMap、Executors
>
## 二、底层篇
### JVM
Client 和 Server 模式?
> 对应JIT即时编译的C1和C2编译器,C2优化程度大一些,所以启动耗时一些。
#### JVM内存结构
class文件格式、运行时数据区:堆、栈、方法区、直接内存、运行时常量池、
堆和栈区别
Java中的对象一定在堆上分配吗?
> - 堆外内存
> - 逃逸分析判断不会逃逸时,直接栈上分配
#### Java内存模型
计算机内存模型、缓存一致性、MESI协议
可见性、原子性、顺序性、happens-before、
内存屏障、synchronized、volatile、final、锁
> https://www.hollischuang.com/archives/2550
>
> **JMM是一种规范,目的是解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题。**
>
> "Java线程之间的通信由Java内存模型控制,JMM决定了一个线程对共享变量的写入,何时对另一个线程可见。—《并发编程的艺术》"
#### 垃圾回收
GC算法:标记清除、引用计数、复制、标记压缩、分代回收、增量式回收
> 标记清除:效率不高,空间碎片
>
> 复制:效率高了,不会有空间碎片,但是代价大,只能用一半的内存空间。
>
> - 目前新生代是用这种复制算法,不过不是1:1,而是分为Edgn,Survivor,8:1:1
> - 当Survivor空间不够用时,由老年代做担保
>
> 标记-整理:一半用于老年代,存活对象较多。与标记清除类似,只是清除完之后,所有的对象往一端移动。然后直接清理掉边界外的空间。
>
> 分代回收:分为新生代和老年代
GCRoots有哪些?
> 所谓“GC roots”,或者说tracing GC的“根集合”,就是**一组必须活跃的引用**。
>
> java的gc为什么要分代? - RednaxelaFX的回答 - 知乎
> https://www.zhihu.com/question/53613423/answer/135743258
GC参数、对象存活的判定、垃圾收集器(CMS、G1、ZGC、Epsilon)
> CMS:并发标记整理
>
> G1:Garbage-First(G1)从整体来看基于标记-整理,但是从局部来看(两个region之间),还是基于复制。有非常好的空间整理能力,不会产生空间碎片。
>
> (具体还是以实测为准,基准测试?)
>
> - G1虽然也还有新生代和老生代的概念,但不是物理的隔离了。
什么情况下会发生full GC?
> 标记清除算法产生较多空间碎片,需要分配一个连续较大空间时会容易发生FGC
Major GC和Full GC的区别是什么?触发条件呢? - RednaxelaFX的回答 - 知乎
https://www.zhihu.com/question/41922036/answer/93079526
#### JVM参数及调优
-Xmx、-Xmn、-Xms、Xss、-XX:SurvivorRatio、
-XX:PermSize、-XX:MaxPermSize、-XX:MaxTenuringThreshold
> -Xmx:最大堆容量,mx表示 memory max
>
> -Xms:最小堆容量,ms表示 memory start
>
> -Xmn:年轻代大小
>
> -Xss:线程栈容量
>
> -XX:SurvivorRatio:年轻代中 Eden区与Survivor区的大小比值
>
> -XX:MaxTenuringThreshold:垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代. 对于年老代比较多的应用,可以提高效率。
<https://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html>
#### Java对象模型
oop-klass、对象头
#### HotSpot
即时编译器、编译优化
#### 虚拟机性能监控与故障处理工具
jps, jstack, jmap、jstat, jconsole, jinfo, jhat, javap, btrace、TProfiler
Arthas
> jps : 查看正在运行的虚拟机进程
>
> jstack : 生成线程快照,可以定位线程长时间停顿的原因,比如死锁,死循环
>
> jmap :生成堆转储快照
>
> jhat : 结合jmap使用,分析堆快照文件
>
> jconsole : 可视化监控工具,集合了很多功能
>
> visual VM : 多合一故障处理程序
>
> jinfo : 查看和调整虚拟机配置信息
>
> jstat :监视,一些统计数据,比如GC次数,内存占用
>
> javap : 反编译
>
> btrace : 基于hotspot 的热替换技术,在不停止目标程序的情况下,动态插入一些调试代码。(线上调试比较有用)
>
> - 重写指定类的字节码
> - https://www.cnblogs.com/fengzheng/p/7416942.html
>
> TProfiler :
>
> - https://github.com/alibaba/TProfiler/wiki
> - TProfiler是一个可以在生产环境长期使用的性能分析工具.它同时支持剖析和采样两种方式,记录方法执行的时间和次数,生成方法热点 对象创建热点 线程状态分析等数据,为查找系统性能瓶颈提供数据支持.
### 类加载机制
classLoader、类加载过程、双亲委派(破坏双亲委派)、模块化(jboss modules、osgi、jigsaw)
> 深度分析Java的ClassLoader机制:<https://www.hollischuang.com/archives/199>
>