Java核心技术36讲(持续更新中)
2021-03-09 19:37:51 0 举报
AI智能生成
Java核心技术36讲(持续更新中)
作者其他创作
大纲/内容
java版本新特性
jdk8
1.Lambdas表达式与Functional接口
2.接口的默认与静态方法
3.新增方法的调用方式类似php
4.try catch resource
5.优化了HashMap以及ConcurrentHashMap
6.G1垃圾回收器
2.接口的默认与静态方法
3.新增方法的调用方式类似php
4.try catch resource
5.优化了HashMap以及ConcurrentHashMap
6.G1垃圾回收器
jdk9
1.HTTP/2
jdk10
1.局部变量类型判断
2.GC的优化以及内存管理
2.GC的优化以及内存管理
jdk11
1、本地变量类型推断
2、字符串加强
3、集合加强
4、Stream 加强
5、Optional 加强
6、InputStream 加强
7、HTTP Client API
8、化繁为简,一个命令编译运行源代码
2、字符串加强
3、集合加强
4、Stream 加强
5、Optional 加强
6、InputStream 加强
7、HTTP Client API
8、化繁为简,一个命令编译运行源代码
增强
1.ZFG垃圾回收器,并行回收,增量回收,更细粒度
2.集合,Stream,字符串增强
3.lambada表达式的增强
4.Http Client API
5.总体往更简洁,效率更高的方向
2.集合,Stream,字符串增强
3.lambada表达式的增强
4.Http Client API
5.总体往更简洁,效率更高的方向
第1讲 | 谈谈你对Java平台的理解?
Java本身是一种面向对象的语言,最显著的特性有两个方面
一是所谓的“书写一次,到处运行”( Write once, run anywhere),能够非常容易地获得跨平台能力
二是垃圾收
集( GC, Garbage Collection), Java通过垃圾收集器( Garbage Collector)回收分配内存,大部分情况下,程序员不需要自己操心内存的分配和回收。
集( GC, Garbage Collection), Java通过垃圾收集器( Garbage Collector)回收分配内存,大部分情况下,程序员不需要自己操心内存的分配和回收。
JRE( Java Runtime Environment)或者JDK( Java Development Kit)
JRE,也就是Java运行环境,包含了JVM和Java类库,以及一些模块等。
JDK可以看作是JRE的一个超集,提供了更多工具,比如编译器、各种诊断工具等。
Java编译执行原理
1.开发 按照java平台的语法规范,结合平台提供的三方类库和框架开发程序,
2.编译 开发完成后使用平台提供的javac工具将程序编译成.class文件,
3.加载 平台通过类加载器(classloder)解释或者编译执行 编译成功的.class文件到JVM中
4.运行 在运行时, JVM使用JIT将.class文件中的二进制字节码解释或编译(根据使用频率来判断使用解释还是编译)成计算机底层能够读懂的机器代码去执行
5.回收 运行期间,通过JVM的垃圾回收,根据参数使用不同的回收方法,将不再使用的内存地址中的数据清空
6.监控,调优 在JVM运行时我们还可以通过平台提供的如: jmap, jconsole等进行监控诊断工具,程序的性能进行监控诊断,进行程序的诊断和调优工作
2.编译 开发完成后使用平台提供的javac工具将程序编译成.class文件,
3.加载 平台通过类加载器(classloder)解释或者编译执行 编译成功的.class文件到JVM中
4.运行 在运行时, JVM使用JIT将.class文件中的二进制字节码解释或编译(根据使用频率来判断使用解释还是编译)成计算机底层能够读懂的机器代码去执行
5.回收 运行期间,通过JVM的垃圾回收,根据参数使用不同的回收方法,将不再使用的内存地址中的数据清空
6.监控,调优 在JVM运行时我们还可以通过平台提供的如: jmap, jconsole等进行监控诊断工具,程序的性能进行监控诊断,进行程序的诊断和调优工作
解释和编译的混合模式(-Xmixed)
Java虚拟机启动时,可以指定不同的参数对运行模式进行选择。 比如,指定“-Xint”,就是告诉JVM只进行解释执行,不对代码进行编译,这种模式抛弃了JIT可能带来的性能优势。与其相对应的,还有一个“-Xcomp”参数,这是告诉JVM关闭解释器,不要进行解释执行,或者叫作最大优化级别。
Java平台架构图
java
第2讲 | Exception和Error有什么区别?
Exception和Error都是继承了Throwable类
Exception是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。Exception又分为检查型( checked)异常和非检查型( unchecked)异常,可检查异常在源代码里必须显式地进行捕获处理,这是编译期检查的一部分。不检查异常就是所谓的运行时异常,类似 NullPointerException、 ArrayIndexOutOfBoundsException之类,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译期强制要求。
Error是指在正常情况下,不大可能出现的情况,绝大部分的Error都会导致程序(比如JVM自身)处于非正常的、不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常见的比如OutOfMemoryError之类,都是Error的子类。
NoClassDefFoundError和ClassNotFoundException区别
NoClassDefFoundError是一个错误(Error),而ClassNOtFoundException是一个异常,在Java中对于错误和异常的处理是不同的,我们可以从异常中恢复程序但却不应该尝试从错误中恢复程序。
ClassNotFoundException
Class.forName方法来动态地加载类,任意一个类的类名如果被作为参数传递给这个方法都将导致该类被加载到JVM内存中,如果这个类在类路径中没有被找到,那么此时就会在运行时抛出ClassNotFoundException异常。当一个类已经某个类加载器加载到内存中了,此时另一个类加载器又尝试着动态地从同一个包中加载这个类。通过控制动态类加载过程,可以避免上述情况发生。
Class.forName方法来动态地加载类,任意一个类的类名如果被作为参数传递给这个方法都将导致该类被加载到JVM内存中,如果这个类在类路径中没有被找到,那么此时就会在运行时抛出ClassNotFoundException异常。当一个类已经某个类加载器加载到内存中了,此时另一个类加载器又尝试着动态地从同一个包中加载这个类。通过控制动态类加载过程,可以避免上述情况发生。
NoClassDefFoundError
如果JVM或者ClassLoader实例尝试加载(可以通过正常的方法调用,也可能是使用new来创建新的对象)类的时候却找不到类的定义。要查找的类在编译的时候是存在的,运行的时候却找不到了。这个时候就会导致NoClassDefFoundError.造成该问题的原因可能是打包过程漏掉了部分类,或者jar包出现损坏或者篡改。解决这个问题的办法是查找那些在开发期间存在于类路径下但在运行期间却不在类路径下的类。
如果JVM或者ClassLoader实例尝试加载(可以通过正常的方法调用,也可能是使用new来创建新的对象)类的时候却找不到类的定义。要查找的类在编译的时候是存在的,运行的时候却找不到了。这个时候就会导致NoClassDefFoundError.造成该问题的原因可能是打包过程漏掉了部分类,或者jar包出现损坏或者篡改。解决这个问题的办法是查找那些在开发期间存在于类路径下但在运行期间却不在类路径下的类。
异常捕获try-catch-finally throw throws
第一, 尽量不要捕获类似Exception这样的通用异常,而是应该捕获特定异常
除非深思熟虑了,否则不要捕获Throwable或者Error,这样很难保证我们能够正确程序处理OutOfMemoryError
除非深思熟虑了,否则不要捕获Throwable或者Error,这样很难保证我们能够正确程序处理OutOfMemoryError
第二, 不要生吞( swallow)异常。这是异常处理中要特别注意的事情,因为很可能会导致非常难以诊断的诡异情况。最好通过logger日志打印
异常如何处理:如果实在不知道如何处理,可以选择保留原有异常的cause信息,直接再抛出或者构建新的异常抛出去。在更高层面,因为有了清晰的(业务)逻辑,往往会更清楚合适的处理方式是什么。
try-catch代码段会产生额外的性能开销,或者换个角度说,它往往会影响JVM对代码进行优化,所以建议仅捕获有必要的代码段,尽量不要一个大的try包住整段的代码;与此同时,利用异常控制代码流程,也不是一个好主意,远比我们通常意义上的条件语句( if/else、 switch)要低效。
Java每实例化一个Exception,都会对当时的栈进行快照,这是一个相对比较重的操作。如果发生的非常频繁,这个开销可就不能被忽略了。
异常架构图
java异常
第3讲 | 谈谈fnal、 fnally、 fnalize有什么不同?
典型回答
fnal可以用来修饰类、方法、变量,分别有不同的意义, fnal修饰的class代表不可以继承扩展, fnal的变量是不可以修改的,而fnal的方法也是不可以重写的( override)。
fnal可以用来修饰类、方法、变量,分别有不同的意义, fnal修饰的class代表不可以继承扩展, fnal的变量是不可以修改的,而fnal的方法也是不可以重写的( override)。
fnalize是基础类java.lang.Object的一个方法,它的设计目的是保证对象在被垃圾收集前完成特定资源的回收。 fnalize机制现在已经不推荐使用,并且在JDK 9开始被标记为deprecated。
第4讲 | 强引用、软引用、弱引用、幻象引用有什么区别?
体现的是对象不同的可达性( reachable)状态和对垃圾收集的影响。
所谓强引用( "Strong" Reference),就是我们最常见的普通对象引用,只要还有强引用指向一个对象,就能表明对象还“活着”,垃圾收集器不会碰这种对象。对于一个普通的对象,如果没有其他的引用关系,只要超过了引用的作用域或者显式地将相应(强)引用赋值为null,就是可以被垃圾收集的了,当然具体回收时机还是要看垃圾收集策略。
软引用( SoftReference),是一种相对强引用弱化一些的引用,可以让对象豁免一些垃圾收集,只有当JVM认为内存不足时,才会去试图回收软引用指向的对象。 JVM会确保在抛出OutOfMemoryError之前,清理软引用指向的对象。软引用通常用来实现内存敏感的缓存,如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理掉,这样就保证了使用缓存的同时,不会耗尽内存。
弱引用( WeakReference)并不能使对象豁免垃圾收集,仅仅是提供一种访问在弱引用状态下对象的途径。这就可以用来构建一种没有特定约束的关系,比如,维护一种非强制性的映射关系,如果试图获取时对象还在,就使用它,否则重现实例化。它同样是很多缓存实现的选择。
对于幻象引用,有时候也翻译成虚引用,你不能通过它访问对象。幻象引用仅仅是提供了一种确保对象被fnalize以后,做某些事情的机制,比如,通常用来做所谓的PostMortem清理机制,我在专栏上一讲中介绍的Java平台自身Cleaner机制等,也有人利用幻象引用监控对象的创建和销毁。
0 条评论
下一页