mirror of
https://github.com/CyC2018/Interview-Notebook.git
synced 2026-10-29 23:23:43 +00:00
Update Java 基础.md
重新绘制异常体系图,更新各版本新特性和字符串常量池的描述,补充与 Go、Python 的对比。
This commit is contained in:
+49
-25
@@ -256,7 +256,7 @@ System.out.println(s5 == s6); // true
|
||||
|
||||
使用这种方式一共会创建两个字符串对象(前提是 String Pool 中还没有 "abc" 字符串对象)。
|
||||
|
||||
- "abc" 属于字符串字面量,因此编译时期会在 String Pool 中创建一个字符串对象,指向这个 "abc" 字符串字面量;
|
||||
- "abc" 属于字符串字面量,编译时记录在 class 文件的常量池中,HotSpot 在运行时第一次执行到对应的 ldc 指令时,才在 String Pool 中创建这个字符串对象,之后再执行就直接复用;
|
||||
- 而使用 new 的方式会在堆中创建一个字符串对象。
|
||||
|
||||
创建一个测试类,其 main 方法中使用这种方式来创建字符串对象。
|
||||
@@ -295,7 +295,7 @@ Constant pool:
|
||||
// ...
|
||||
```
|
||||
|
||||
在 Constant Pool 中,#19 存储这字符串字面量 "abc",#3 是 String Pool 的字符串对象,它指向 #19 这个字符串字面量。在 main 方法中,0: 行使用 new #2 在堆中创建一个字符串对象,并且使用 ldc #3 将 String Pool 中的字符串对象作为 String 构造函数的参数。
|
||||
在 class 文件的常量池中,#19 存储字符串字面量 "abc",#3 是 String 类型的常量,它指向 #19;运行时解析 #3 得到的就是 String Pool 中的字符串对象。在 main 方法中,0: 行使用 new #2 在堆中创建一个字符串对象,并且使用 ldc #3 将 String Pool 中的字符串对象作为 String 构造函数的参数。
|
||||
|
||||
以下是 String 构造函数的源码,可以看到,在将一个字符串对象作为另一个字符串对象的构造函数参数时,并不会完全复制 value 数组内容,而是都会指向同一个 value 数组。
|
||||
|
||||
@@ -1384,7 +1384,7 @@ Throwable 可以用来表示任何可以作为异常抛出的类,分为两种
|
||||
- **受检异常** :需要用 try...catch... 语句捕获并进行处理,或者用 throws 声明抛出,并且可以从异常中恢复;
|
||||
- **非受检异常** :是程序运行时错误,例如除 0 会引发 ArithmeticException。编译器不强制处理这类异常,通常应该修改代码来避免,而不是捕获之后恢复。
|
||||
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/PPjwP.png" width="600"/> </div><br>
|
||||
<div align="center"> <img src="pics/java-exceptions.png" width="760px"/> </div><br>
|
||||
|
||||
- [Java Exception Interview Questions and Answers](https://www.journaldev.com/2167/java-exception-interview-questions-and-answers)
|
||||
|
||||
@@ -1414,35 +1414,44 @@ Java 注解是附加在代码中的一些元信息,用于一些工具在编译
|
||||
|
||||
### Java 各版本的新特性
|
||||
|
||||
**New highlights in Java SE 8**
|
||||
目前常用的是长期支持(LTS)版本 8、11、17、21,面试中最常问 Java 8 和 Java 21:
|
||||
|
||||
1. Lambda Expressions
|
||||
2. Pipelines and Streams
|
||||
3. Date and Time API
|
||||
4. Default Methods
|
||||
5. Type Annotations
|
||||
6. Nashorn JavaScript Engine
|
||||
7. Concurrent Accumulators
|
||||
8. Parallel operations
|
||||
9. PermGen Error Removed
|
||||
| 版本 | 与上一个长期支持版本相比的主要新特性 |
|
||||
| --- | --- |
|
||||
| Java 8(2014) | Lambda 表达式、Stream、Optional、新的日期时间 API(java.time)、接口默认方法;永久代被元空间取代 |
|
||||
| Java 11(2018) | var 用于 Lambda 参数(var 本身在 Java 10 引入)、标准化的 HttpClient、String 新增 isBlank、strip、repeat 等方法 |
|
||||
| Java 17(2021) | 记录类(record)、密封类(sealed)、文本块、instanceof 模式匹配、新的 switch 表达式 |
|
||||
| Java 21(2023) | 虚拟线程、switch 模式匹配、记录模式、有序集合接口 SequencedCollection |
|
||||
|
||||
**New highlights in Java SE 7**
|
||||
以下代码在 JDK 21 上编译运行,用到了其中的大部分特性:
|
||||
|
||||
1. Strings in Switch Statement
|
||||
2. Type Inference for Generic Instance Creation
|
||||
3. Multiple Exception Handling
|
||||
4. Support for Dynamic Languages
|
||||
5. Try with Resources
|
||||
6. Java nio Package
|
||||
7. Binary Literals, Underscore in literals
|
||||
8. Diamond Syntax
|
||||
```java
|
||||
sealed interface Shape permits Circle, Square {}
|
||||
record Circle(double r) implements Shape {}
|
||||
record Square(double side) implements Shape {}
|
||||
|
||||
- [Difference between Java 1.8 and Java 1.7?](http://www.selfgrowth.com/articles/difference-between-java-18-and-java-17)
|
||||
- [Java 8 特性](http://www.importnew.com/19345.html)
|
||||
static double area(Shape s) {
|
||||
return switch (s) { // switch 模式匹配,编译器检查是否覆盖了所有子类
|
||||
case Circle c -> Math.PI * c.r() * c.r();
|
||||
case Square(double side) -> side * side; // 记录模式,直接取出字段
|
||||
};
|
||||
}
|
||||
|
||||
var upper = List.of("redis", "mysql", "kafka", "java").stream()
|
||||
.filter(w -> w.length() == 5)
|
||||
.map(String::toUpperCase)
|
||||
.collect(Collectors.toList()); // [REDIS, MYSQL, KAFKA]
|
||||
|
||||
Thread.ofVirtual().start(() -> System.out.println(Thread.currentThread().isVirtual())); // true
|
||||
```
|
||||
|
||||
Lambda 表达式不会生成匿名内部类的 class 文件。用 javap 查看编译结果,Lambda 的方法体被编译成当前类的私有静态方法 lambda$main$0,调用处是一条 invokedynamic 指令,第一次执行时由 LambdaMetafactory 在运行时生成实现函数式接口的类。
|
||||
|
||||
Stream 是惰性求值的:filter、map 等中间操作只是记录下来,遇到 collect、findFirst 等终止操作才开始执行,并且每个元素依次走完整条流水线。上例改为 findFirst() 时,只处理了第一个元素 redis 就返回了,后面的 mysql、kafka 都没有被处理。
|
||||
|
||||
### Java 与 C++ 的区别
|
||||
|
||||
- Java 是纯粹的面向对象语言,所有的对象都继承自 java.lang.Object,C++ 为了兼容 C 即支持面向对象也支持面向过程。
|
||||
- Java 的代码都写在类中,除了基本类型之外,所有的对象都继承自 java.lang.Object;C++ 为了兼容 C,既支持面向对象也支持面向过程。
|
||||
- Java 通过虚拟机从而实现跨平台特性,但是 C++ 依赖于特定的平台。
|
||||
- Java 没有指针,它的引用可以理解为安全指针,而 C++ 具有和 C 一样的指针。
|
||||
- Java 支持自动垃圾回收,而 C++ 需要手动回收。
|
||||
@@ -1452,6 +1461,16 @@ Java 注解是附加在代码中的一些元信息,用于一些工具在编译
|
||||
|
||||
[What are the main differences between Java and C++?](http://cs-fundamentals.com/tech-interview/java/differences-between-java-and-cpp.php)
|
||||
|
||||
与 Go、Python 相比:
|
||||
|
||||
| | Java | Go | Python(CPython) |
|
||||
| --- | --- | --- | --- |
|
||||
| 执行方式 | 编译为字节码,由 JVM 解释执行,热点代码由 JIT 编译为机器码 | 直接编译为机器码,生成一个可执行文件,启动快 | 编译为字节码,由解释器执行,3.13 起有实验性的 JIT |
|
||||
| 类型检查 | 静态类型,编译时检查 | 静态类型,编译时检查 | 动态类型,运行时才发现类型错误 |
|
||||
| 并发 | 线程对应操作系统线程,JDK 21 起有虚拟线程 | goroutine 由运行时调度到少量线程上,用 channel 通信 | 有全局解释器锁(GIL),同一时刻只有一个线程执行 Python 代码,CPU 密集型任务要用多进程;3.13 起提供去掉 GIL 的版本,3.14 起正式支持,但不是默认版本 |
|
||||
| 内存回收 | 分代的垃圾收集器,可以选择 G1、ZGC 等 | 与程序并发执行的标记清除,不移动对象 | 以引用计数为主,计数为 0 时立即释放,再用垃圾收集器处理循环引用 |
|
||||
| 错误处理 | 异常 | 函数返回 error 值,由调用方检查 | 异常 |
|
||||
|
||||
### JRE or JDK
|
||||
|
||||
- JRE:Java Runtime Environment,Java 运行环境的简称,为 Java 的运行提供了所需的环境。它是一个 JVM 程序,主要包括了 JVM 的标准实现和一些 Java 基本类库。
|
||||
@@ -1461,3 +1480,8 @@ Java 注解是附加在代码中的一些元信息,用于一些工具在编译
|
||||
|
||||
- Eckel B. Java 编程思想[M]. 机械工业出版社, 2002.
|
||||
- Bloch J. Effective java[M]. Addison-Wesley Professional, 2017.
|
||||
- [JEP 441: Pattern Matching for switch](https://openjdk.org/jeps/441)
|
||||
- [JEP 444: Virtual Threads](https://openjdk.org/jeps/444)
|
||||
- [PEP 703: Making the Global Interpreter Lock Optional in CPython](https://peps.python.org/pep-0703/)
|
||||
- [What’s New in Python 3.14](https://docs.python.org/3/whatsnew/3.14.html)
|
||||
- [A Guide to the Go Garbage Collector](https://go.dev/doc/gc-guide)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 138 KiB |
@@ -0,0 +1,69 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="760" height="330" viewBox="0 0 760 330">
|
||||
<style>
|
||||
text { font-family: "PingFang SC", "Microsoft YaHei", Helvetica, Arial, sans-serif; fill: #3F3F3F; font-size: 12px; }
|
||||
.title { font-weight: bold; font-size: 15px; fill: #333; text-anchor: middle; }
|
||||
.b { font-weight: bold; }
|
||||
.c { text-anchor: middle; }
|
||||
.e { text-anchor: end; }
|
||||
.sub { font-size: 11px; fill: #6E6E6E; }
|
||||
.note { fill: #C0605A; }
|
||||
.ok { fill: #6A9F68; }
|
||||
.mono { font-family: Menlo, Consolas, monospace; }
|
||||
.arrow { stroke: #555; stroke-width: 1.1; fill: none; marker-end: url(#a); }
|
||||
.red { stroke: #C0605A; marker-end: url(#r); }
|
||||
.green { stroke: #6A9F68; marker-end: url(#g); }
|
||||
.dash { stroke-dasharray: 5 4; }
|
||||
.line { stroke: #555; stroke-width: 1.1; fill: none; }
|
||||
.frame { fill: none; stroke: #999; stroke-width: 1; stroke-dasharray: 4 3; }
|
||||
.shadow { fill: #DADADA; }
|
||||
</style>
|
||||
<defs>
|
||||
<marker id="a" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M1,1.5 L9.5,5 L1,8.5 z" fill="#555"/>
|
||||
</marker>
|
||||
<marker id="r" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M1,1.5 L9.5,5 L1,8.5 z" fill="#C0605A"/>
|
||||
</marker>
|
||||
<marker id="g" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
||||
<path d="M1,1.5 L9.5,5 L1,8.5 z" fill="#6A9F68"/>
|
||||
</marker>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="#FFFFFF"/>
|
||||
|
||||
<text x="380" y="28" class="title">Java 异常的层次</text>
|
||||
<rect x="320" y="46" width="120" height="30" rx="6" fill="#EAE9E7" stroke="#BFBEBA"/>
|
||||
<text x="380" y="65.5" class="c sub b mono">Throwable</text>
|
||||
<rect x="110" y="106" width="150" height="30" rx="6" fill="#E6E3FA" stroke="#B8B0DE"/>
|
||||
<text x="185" y="125.5" class="c sub b mono">Error</text>
|
||||
<rect x="500" y="106" width="150" height="30" rx="6" fill="#C6E4FB" stroke="#7FB2D6"/>
|
||||
<text x="575" y="125.5" class="c sub b mono">Exception</text>
|
||||
<line x1="350" y1="78" x2="190" y2="104" class="arrow "/>
|
||||
<line x1="410" y1="78" x2="570" y2="104" class="arrow "/>
|
||||
<rect x="30" y="186" width="155" height="30" rx="6" fill="#FFFFFF" stroke="#BBBBBB"/>
|
||||
<text x="107.5" y="205.5" class="c sub b mono">OutOfMemoryError</text>
|
||||
<line x1="185" y1="138" x2="108" y2="184" class="arrow "/>
|
||||
<rect x="195" y="186" width="155" height="30" rx="6" fill="#FFFFFF" stroke="#BBBBBB"/>
|
||||
<text x="272.5" y="205.5" class="c sub b mono">StackOverflowError</text>
|
||||
<line x1="185" y1="138" x2="273" y2="184" class="arrow "/>
|
||||
<rect x="370" y="186" width="150" height="30" rx="6" fill="#E6E3FA" stroke="#B8B0DE"/>
|
||||
<text x="445" y="205.5" class="c sub b mono">RuntimeException</text>
|
||||
<rect x="530" y="186" width="105" height="30" rx="6" fill="#C6E4FB" stroke="#7FB2D6"/>
|
||||
<text x="582.5" y="205.5" class="c sub b mono">IOException</text>
|
||||
<rect x="645" y="186" width="105" height="30" rx="6" fill="#C6E4FB" stroke="#7FB2D6"/>
|
||||
<text x="697.5" y="205.5" class="c sub b mono">SQLException</text>
|
||||
<line x1="555" y1="138" x2="445" y2="184" class="arrow "/>
|
||||
<line x1="575" y1="138" x2="582" y2="184" class="arrow "/>
|
||||
<line x1="600" y1="138" x2="697" y2="184" class="arrow "/>
|
||||
<rect x="350" y="246" width="200" height="30" rx="6" fill="#FFFFFF" stroke="#BBBBBB"/>
|
||||
<text x="450" y="265.5" class="c sub b mono">NullPointerException</text>
|
||||
<rect x="350" y="282" width="200" height="30" rx="6" fill="#FFFFFF" stroke="#BBBBBB"/>
|
||||
<text x="450" y="301.5" class="c sub b mono">ArithmeticException</text>
|
||||
<line x1="445" y1="218" x2="445" y2="244" class="arrow "/>
|
||||
<rect x="560" y="246" width="190" height="30" rx="6" fill="#FFFFFF" stroke="#BBBBBB"/>
|
||||
<text x="655" y="265.5" class="c sub b mono">FileNotFoundException</text>
|
||||
<line x1="582" y1="218" x2="600" y2="244" class="arrow "/>
|
||||
<text x="30" y="262" class="sub">淡紫色的 Error、RuntimeException 及它们的子类</text>
|
||||
<text x="30" y="280" class="sub">是非受检异常,编译器不强制处理;</text>
|
||||
<text x="30" y="298" class="sub">其余的 Exception(浅蓝)是受检异常,必须</text>
|
||||
<text x="30" y="316" class="sub">捕获或者用 throws 声明。</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
Reference in New Issue
Block a user