终于大规模复工了,感谢!疫情,退,退,退。
技术人复工了,有一大批则失业了。
复工的有一丝幸运,也有一丝焦虑。
大环境就是这样,从996式的内卷,到诡异的35岁的槛,需要提醒自己不断努力。
内卷没有什么不对,这是绝大部分人当前的最优解。
我们需要的是相对好的结果,内卷只是途径和方式,我也卷过,但我卷的是各种新技术,面对层出不穷的新技术新名词,不追就怕落后,追吧,总是有新的技术不但冒出来,疲于追它们,所以很难把他们追透彻,大多停留在应用的层面,回头来看总感觉自己中空,也就是常说的不扎实。
直到有一天我看到了这句话,“这些层出不穷的技术看似‘纷繁杂乱’,实则是殊途同归,它们背后都是一些通用的底层技术加上创新的设计思想”,这就是万变不离其宗吧。
所以,扎实的基础知识和底层技术是技术人的内功,决定着技术人的天花板。
一直以来吃灰的极客时间是时候好好学习了,学习笔记用思维导图的方式记录,我也在思考怎么样更高效,更直接,更科学的去学习并消化它们,如果你有更好的方法或建议,还请在评论区不惜赐教。
初步选定了‘Java 核心技术面试精讲‘,原因有二,一是在极客时间它有着十万加的学习者,目前 top 5;还有就是Java语言受众广,殷实自我基础的同时,希望或多或少帮助到有这方面需要的同行,那将不胜荣幸。
除了Java 核心技术面试精讲,初步还定了下面几个专栏学习,后面我会定期更新,感谢你能耐心看到这里。
Java 核心技术面试精讲总体目录:
开篇-以面试题为切入点 有效提升Java内功
Java基础-对Java平台的理解:
考虑到手机用户看图不太方便,脑图笔记中的文字贴在下方。
开篇-以面试题为切入点有效提升Java内功
Java工程师应聘要求
- 初级、中级工程师
- 扎实的 Java 和计算机科学基础
- 掌握主流开源框架使用
- 高级工程师或技术专家
- Java IO/NIO
- 并发
- 虚拟机
- 分布式
- 安全
- 性能
Java工程师大多存在的问题
- 知其然不知其所以然
- 知识碎片化,不成系统
Java工程师学习现状
- 精力有限
- 网络资源碎片化严重
- 各种“宝典”不够深入
Java基础-对Java平台的理解
具体问题
谈谈你对 Java 平台的理解?“Java 是解释执行”,这句话正确吗?
典型回答
-
对Java平台的理解
- 跨平台能力:书写一次,到处运行(Write once, run anywhere)
- 垃圾收集(GC, Garbage Collection) : Java 通过垃圾收集器回收分配内存,通常无需关心内存分配和回收
- 日常接触到 JRE (Java Runtime Environment)或者 JDK (Java Development Kit)。JRE 是 Java 运行环境,包含JVM 和 Java 类库,及一些模块等;JDK 是 JRE 超集,提供了更多工具,比如编译器、各种诊断工具等
-
Java 是解释执行?
这个说法不准确。 Java 源代码首先通过 Javac 编译成为字节码(bytecode),然后在运行时,通过 Java 虚拟机(JVM) 内嵌的解释器将字节码转换为最终的机器码。但常见的 JVM都提供了 JIT (Just-In-Time) 编译器,也就是通常所说的动态编译器,JIT 能够在运行时将热点代码编译成机器码,这种情况下部分热点代码就属于编译执行,而不是解释执行
考点分析
- 题目本身是开放的,考察多个方面,比如基础知识理解是否很清楚;是否掌握 Java 平台主要模块和运行原理等
- 需尽量表现出自己的思维深入和系统化,及对Java 知识的理解较全面,要避免给面试官“知其然不知其所以然”的印象。明白基本组成和机制,是日常工作中问题诊断或性能调优等很多事情的基础
知识扩展
对于 Java 平台的理解,可从多方面简明扼要谈一下
- Java 语言特性:包括泛型、Lambda 等语言特性;
- 基础类库:包括集合、IO/NIO、网络、并发、安全等基础类库。对于我们日常工作应用较多的类库,面试前可以系统化总结一下,有助于临场发挥
- JVM 基础概念和机制:如 Java 的类加载机制,常用版本 JDK(如 JDK 8)内嵌的 Class-Loader,如 Bootstrap、 Application 和 Extension Class-loader;类加载大致过程:加载、验证、链接、初始化;自定义 Class-Loader 等。还有垃圾收集的基本原理,最常见的垃圾收集器,如 SerialGC、Parallel GC、 CMS、 G1 等,对于适用于什么样的工作负载最好也心里有数
- JDK 包含工具或 Java 领域内其他工具:如编译器、运行时环境、安全工具、诊断和监控工具等。这些基本工具是日常工作效率的保证,对我们工作在其他语言平台上同样有帮助,很多都是触类旁通的
解释执行和编译执行稍微深入探讨
- 我们通常把 Java 分为编译期和运行时。这里说的 Java 编译和 C/C++ 是有不同的意义的,Javac 的编译是编译 Java 源码生成“.class”文件,文件里实际是字节码,而不是可以直接执行的机器码。Java 通过字节码和 Java 虚拟机(JVM)这种跨平台的抽象,屏蔽了操作系统和硬件的细节,这也是实现“一次编译,到处执行”的基础
- 在运行时,JVM 会通过类加载器(Class-Loader)加载字节码,然后解释或编译执行。如前面提到的主流 Java 版本实际是解释和编译混合的一种模式,即所谓的混合模式(-Xmixed)。通常运行在 server 模式的 JVM,会进行上万次调用以收集足够的信息进行高效编译,client 模式这个门限是 1500 次。Oracle Hotspot JVM 内置了两个不同的 JIT compiler,C1 对应前面说的 client 模式,适用于对于启动速度敏感的应用,比如普通 Java 桌面应用;C2 对应 server 模式,它是为长时间运行的服务器端应用优化设计的。默认采用的是所谓的分层编译(TieredCompilation)
- Java 虚拟机启动时,可指定不同的参数选择运行模式。如指定“-Xint”,就是告诉 JVM 只进行解释执行,不对代码进行编译,这种模式抛弃了 JIT 可能带来的性能优势。毕竟解释器(interpreter)是逐条读入,逐条解释运行的。与其相对应的还有一个“-Xcomp”参数,是告诉 JVM 关闭解释器,不要进行解释执行,或者叫最大优化级别。你可能会问这种模式是否最高效?还真未必,“-Xcomp”会导致 JVM 启动变慢很多,同时有些 JIT 编译器优化方式,如分支预测,如果不进行 profiling,并不能进行有效优化
- 除日常最常见的 Java 使用模式,还有一种新的编译方式,即所谓的 AOT(Ahead-of-Time Compilation),直接将字节码编译成机器代码,这样就避免了 JIT 预热等各方面的开销,如 Oracle JDK 9 就引入了实验性的 AOT 特性,并且增加了新的 jaotc 工具。利用相关命令即可把某个类或者某个模块编译成为 AOT 库。
精选留言
“一次编译、到处运行”说的是Java语言跨平台特性,Java跨平台特性与Java虚拟机的存在密不可分,比如说Windows平台和Linux平台都有相应的JDK,安装好JDK后也就有了Java语言的运行环境。Java语言本身与其他编程语言没有特别大的差异,并不是Java语言可以跨平台,而是在不同的平台都有可以让Java语言运行的环境,所以才有了Java一次编译,到处运行这样的效果。 严格讲,跨平台语言不止Java一种,但Java较为成熟。“一次编译,到处运行”这种效果跟编译器有关。编程语言的处理需要编译器和解释器。Java虚拟机和DOS类似,为Java程序运行提供了平台。
程序从源代码到运行分三个阶段:编码——编译——运行——调试。Java在编译阶段体现了跨平台的特点。编译的大概过程:首先将Java源代码转化成.CLASS文件字节码,这是第一次编译。.class文件就是可以到处运行的文件。然后Java字节码会被转化为目标机器代码,这是由JVM来执行的,即Java的第二次编译。
“到处运行”的关键和前提就是JVM。因为在第二次编译中JVM起着关键作用。在可以运行Java虚拟机的地方都内含着一个JVM操作系统。从而为JAVA提供了不同平台上的虚拟机制,实现了“到处运行”的效果。需要强调的一点是,java并不是编译机制,而是解释机制。Java字节码的设计充分考虑了JIT这一即时编译方式,可将字节码直接转化成高性能的本地机器码,这同样是虚拟机的一个构成部分。
- Java特性:
- 面向对象(封装,继承,多态)
- 平台无关性(JVM运行.class文件)
- 语言(泛型,Lambda)
- 类库(集合,并发,网络,IO/NIO)
- JRE(Java运行环境,JVM,类库)
- JDK(Java开发工具,包括JRE,javac,诊断工具)
- Java是解析运行吗? 不正确!
- Java源代码经过Javac编译成.class文件
- .class文件经JVM解析或编译运行。
- 解析:.class文件经过JVM内嵌的解析器解析执行。
- 编译:存在JIT编译器(Just In Time Compile 即时编译器)把经常运行的代码作为"热点代码"编译为本地平台相关的机器码,并进行各种层次的优化。
- AOT编译器:Java 9提供的直接将所有代码编译成机器码执行。
- 宏观角度: 跟c/c++最大的不同点在于,c/c++编程是面向操作系统的,需要开发者极大地关心不同操作系统之间的差异性;而Java平台通过虚拟机屏蔽了操作系统的底层细节,使得开发者无需过多地关心不同操作系统之间的差异性。 通过增加一个间接的中间层来进行”解耦“是计算机领域非常常用的一种”艺术手法“,虚拟机是这样,操作系统是这样,HTTP也是这样。 Java平台已经形成了一个生态系统,在这个生态系统中,有着诸多的研究领域和应用领域:
- 虚拟机、编译技术的研究(例如:GC优化、JIT、AOT等):对效率的追求是人类的另一个天性之一
- Java语言本身的优化
- 大数据处理
- Java并发编程
- 客户端开发(例如:Android平台)
- ......
- 微观角度: Java平台中有两大核心:
- Java语言本身、JDK中所提供的核心类库和相关工具
- Java虚拟机以及其包含的GC
- Java语言本身、JDK中所提供的核心类库和相关工具 从事Java平台的开发,掌握Java语言、核心类库以及相关工具是必须的,我觉得这是基础中的基础。
1)对语言本身的了解,需要开发者非常熟悉语言的语法结构;而Java又是一种面对对象的语言,这又需要开发者深入了解面对对象的设计理念;
2)Java核心类库包含集合类、线程相关类、IO、NIO、J.U.C并发包等;
3)JDK提供的工具包含:基本的编译工具、虚拟机性能检测相关工具等。
- Java虚拟机
Java语言具有跨平台的特性,也正是因为虚拟机的存在,Java源文件被编译成字节码,被虚拟机加载后执行。这里隐含的意思有两层:
1)大部分情况下,编程者只需要关心Java语言本身,而无需特意关心底层细节。包括对内存的分配和回收,也全权交给了GC。
2)对于虚拟机而言,只要是符合规范的字节码,它们都能被加载执行,当然,能正常运行的程序光满足这点是不行的,程序本身需要保证在运行时不出现异常。所以,Scala、Kotlin、Jython等语言也可以跑在虚拟机上。
围绕虚拟机的效率问题展开,将涉及到一些优化技术,例如:JIT、AOT。因为如果虚拟机加载字节码后,完全进行解释执行,这势必会影响执行效率。所以,对于这个运行环节,虚拟机会进行一些优化处理,例如JIT技术,会将某些运行特别频繁的代码编译成机器码。而AOT技术,是在运行前,通过工具直接将字节码转换为机器码。