“极客时间-Java核心技术36讲”阅读总结(1)

一、对平台的看法

       近两天,我在技术公众号看到了极客时间的推荐,里面提及到评论区有很多高手,于是我就付费体验了一下,先表述一下感想。

       1、极客时间的专栏价格真的挺贵的,不过分享给朋友订阅能获取现金奖励,加之为平台推荐新用户能获得每个用户一张优惠券的奖励,加起来能省不少钱,也许还能赚钱,在这里我为平台的商业模式点个赞,确实能吸引不少用户,如果大牛订阅了专栏还会牵动着大批的粉丝,我就是其中的一个。

       2、评论区是真的质量很高,而且大牛云集,是个学习的平台。但是囿于篇幅,文章的质量很多知识点都是点到即止,需要各位看官回去细细品味。我觉得最好的一点是能向作者提问,评论区里也有不少高能提问,能学到不少知识。

       3、于我而言,专栏对我帮助最大的是专栏的知识体系比较完善,获取的知识也比较容易串联起来,而且还能吸取不少技术大拿的经验,这是我们仅靠看书无法得到的。但专栏始终无法代替书籍,书籍相对来说更深入完善,而且理解书中晦涩的内容对人的提供更大。只是看书需要花大量的时间,专栏能在短时间内获取知识,总体来说专栏能让人快速上手,可以作为书籍的一个补充。

       我觉得知识付费有知识付费的好处,毕竟这对作者来说也是一种鼓励,而且花点小钱就能使自身能力得到提高,这对我们来说也是很大的财富。我觉得花钱得来的知识更使人懂得珍惜,而且不舍得花钱学习的人是真心想提高自己吗?我表示很大的疑问。

二、学习总结

       侃完了对平台的感受,接下来做正事,总结我今天学到的知识。

       先从“Java核心技术36讲”这个专栏说起吧,这个专栏由Oracle首席工程师杨晓峰编写,里面的文章都是以面试题为切入点,文章中给出了作者的观点以及相关拓展,最后提出一道思考题来引导读者对课程相关内容进行思考。

       今天我就看了三篇(请原谅一名初出茅庐的菜鸟),每一篇都很仔细地看过,接下来结合评论区的内容分篇总结,以及对自己的疑问进行解答。

(1)谈谈你对Java平台的理解

       这种问题考察的是对Java平台的整体把握,可以从语言特性、Java类库、JVM、Java工具、Java生态、平台模块这几方面回答。既要从整体上把握Java平台,也要理解底层,做到知其然知其所以然。

Java语言特性:面向对象、反射、泛型、枚举、平台无关等

Java类库:集合框架、并发包、IO/NIO、网络、安全等

JVM:GC机制、运行时、动态编译等

Java工具:辅助工具(jar、jlink、jdeps等)、编译工具(javac、jaotc等)、诊断工具(jmap、jstack、jconsole、jcmd等)

Java生态:Spring等Java框架、Spark、Hadoop、ElasticSearch等

Java平台模块:JVM>JRE>JDK,JVM是Java运行时环境,JRE除了JVM外还有Java类库等一些模块,JDK包含了JRE以及Java工具

       Java程序从源代码到运行需要经过几个步骤:Java源代码通过编译器编译成字节码,字节码在JVM中通过解释或编译转换成机器码。令我疑惑的是Java的两次编译是怎么回事?字节码解释和编译又有什么不同?Java的第一次编译是源码编译成字节码,这样才能被JVM加载;第二次编译是即时编译JIT(just in time),它是运行时动态编译,是方法级的。这是JVM的一种优化机制,经过多次调用选出热点代码,将其编译成机器码并缓存起来,接下来用的时候不用重复编译。而解释则少了缓存步骤,每次调用都要解释执行。热点代码有淘汰机制,会随着机器的运行动态变化。因此,Java是解释和编译混合的一种模式,片面地说编译执行或者解释执行都是不对的。

       JVM启动时,可通过传入参数指定其运行模式。“-Xint”告诉JVM只解释执行;“-Xcomp”告诉JVM关闭解释器,不解释执行。但这样JVM启动很慢,而且也不利于JIT的分支预测。Java9中引入了一种新的编译方式AOT(Ahead-of-Time Compilation),将字节码直接编译成机器码,省去了JIT预热的开销。

(2)Exception和Error的区别

       Exception和Error都是Throwable的子类,只有Throwable的子类才可以被抛出和捕获。Exception是我们设计时可以用到的,能进行捕获并处理异常。Error会导致程序处于非正常的、不可恢复状态。

Error: OutOfMemoryError、StackOverflowError、NoClassDefFoundError等

Exception:可检查异常和不可检查异常

可检查异常:编译时检查的一场( 如IOException以及一些显式抛出的异常 )

不可检查异常:编译时不检查,运行时才抛出的异常(如ClassNotFoundException、 NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException、ArithmeticException、IllegalArgumentException等)

       那么,ClassNotFoundException和NoClassDefFoundError有什么区别呢?简单来说,当类加载器无法找在指定路径下无法找到类的时候,就会抛出ClassNotFoundException。产生ClassNotFoundException的另一个原因就是多个类加载器在同一个包中加载同一个类,可以通过控制动态类加载过程避免。当JVM或类加载器尝试加载类的时候却无法找到类的定义,会发生NoClassDefFoundError,也就是该类在编译时存在,在其他类new时都可以通过编译,但是在运行new时却无法找到该类的定义

       对于异常处理,有一些实践性的技巧。随着Java的发展,产生了一些新特性,如try-with-resourse、multipyle catch。try-with-resourse是Java1.7引入的新特性,指的是在编写代码时可以不用显式调用实现了AutoCloseable或Closable的类的关闭方法,编译时编译器会自动填充。multipyle catch是指多个Exception可以在一个catch块中被捕获,简化代码编写。

       在进行异常捕获时,我们捕获特定异常,而不是Exception这类通用异常,这样能在代码中明确异常的目的。对于异常,我们尽量不要“生吞”,捕获到异常而不做任何处理,一般情况下可以将异常信息记录到日志中,不建议printStackTrace(),因为不知道异常信息会输出到哪里。

       在处理异常时,我们要本着early throw,catch late的原则,先考虑抛出异常,等有足够的信息时再捕获处理,捕获异常时需要注意避免包含敏感信息。

       checked exception已经偏离了设计初衷,大多数情况下不可恢复。而且checked exception对函数式编程不兼容,意思是说受检查异常在进行函数式编程时无法抛出,只能被捕获。

       异常处理会给性能带来一定的开销,try-catch会影响JVM对代码进行优化,而Exception对象的创建会对栈进行快照,发生频繁时开销就不可忽视了。当然创建Exception对象时也可以不进行栈快照,只是在编码前要仔细斟酌,避免遗漏必要的堆栈信息。

三、结束语

       由于时间限制,今天先总结两篇文章。看了这几篇文章,我最大大的感受就是我的基础还不够牢靠,很多热门技术和专业属于都不知道,如反应式编程(Reactive Stream)、异常处理的TraceId、Spring的一些异常处理机制等。“路漫漫其修远兮,吾将上下而求索”,我相信只要不断学习积累,一定能到达我向往的高度,共勉!!!

你可能感兴趣的:(“极客时间-Java核心技术36讲”阅读总结(1))