面试高频基础
Java平台的理解
1.你怎么理解Java平台?
Java 是一种面向对象的语言,有两个明显特性:
跨平台能力:一次编写,到处运行(Write once,run anywhere); 垃圾收集:
Java 通过字节码和 Java 虚拟机(JVM)这种跨平台的抽象,屏蔽了操作系统和硬件的细节,这也是实现「一次编译,到处执行」的基础。
Java 通过垃圾收集器(Garbage Collector)回收分配内存,大部分情况下,程序员不需要自己操心内存的分配和回收。
最常见的垃圾收集器,如 SerialGC、Parallel GC、 CMS、 G1 等,对于适用于什么样的工作负载最好也心里有数
2.JVM、JRE、JDK 关系
JVM Java Virtual Machine 是 Java 虚拟机,Java 程序需要运行在虚拟机上,不同的平台有自己的虚拟机,因此 Java 语言可以实现跨平台。
JRE Java Runtime Environment包括 Java 虚拟机和 Java 程序所需的核心类库等。
核心类库主要是 java.lang 包:包含了运行 Java 程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省加载这个包
如果想要运行一个开发好的 Java 程序,计算机中只需要安装 JRE 即可。
JDK Java Development Kit是提供给 Java 开发人员使用的,其中包含了 Java 的开发工具,也包括了 JRE。
所以安装了 JDK,就无需再单独安装 JRE 了。其中的开发工具:编译工具(javac.exe),打包工具(jar.exe) 等。
3.Java 是解释执行么?
这个说法不太准确。
我们开发的 Java 的源代码,首先通过 Javac 编译成为字节码(bytecode),在运行时,通过 Java 虚拟机(JVM)内嵌的解释器将字节码转换成为最终的机器码。
但是常见的 JVM,比如我们大多数情况使用的 Oracle JDK 提供的 Hotspot JVM,都提供了 JIT(Just-In-Time)编译器。
也就是通常说的动态编译器,JIT 能够在运行时将热点代码编译成机器码,这种情况下部分热点代码就属于编译执行,而不是解释执行了。
4.采用字节码的好处
字节码:Java 源代码经过虚拟机编译器编译后产生的文件(即扩展为.class 的文件),它不面向任何特定的处理器,只面向虚拟机。
采用字节码的好处:
众所周知,我们通常把 Java 分为编译期和运行时。这里说的 Java 的编译和 C/C++ 是有着不同的意义的,Javac 的编译,编译 Java 源码生成“.class”文件里面实际是字节码,而不是可以直接执行的机器码。Java 通过字节码和 Java 虚拟机(JVM)这种跨平台的抽象,屏蔽了操作系统和硬件的细节,这也是实现“一次编译,到处执行”的基础。
基础语法
1.JDK 1.8 之后有哪些新特性
接口默认方法:Java8 允许我们给接口添加一个非抽象的方法实现,只需要使用 default 关键字即可。
Lambda 表达式和函数式接口:Lambda 表达式本质上是一段匿名内部类,也可以是一段可以传递的代码。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中),使用 Lambda 表达式使代码更加简洁,但是也不要滥用,否则会有可读性等问题,《EffectiveJava》作者 JoshBloch 建议使用 Lambda 表达式最好不要超过 3 行。
StreamAPI:用函数式编程方式在集合类上进行复杂操作的工具,配合 Lambda 表达式可以方便的对集合进行处理。
Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。
使用 StreamAPI 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 StreamAPI 来并行执行操作。
简而言之,StreamAPI 提供了一种高效且易于使用的处理数据的方式。
方法引用:方法引用提供了非常有用的语法,可以直接引用已有 Java 类或对象(实例)的方法或构造器。
与 lambda 联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
日期时间 API:Java8 引入了新的日期时间 API 改进了日期时间的管理。
Optional 类:著名的 NullPointerException 是引起系统失败最常见的原因。
很久以前 GoogleGuava 项目引入了 Optional 作为解决空指针异常的一种方式,不赞成代码被 null 检查的代码污染,期望程序员写整洁的代码。
受 GoogleGuava 的鼓励,Optional 现在是 Java8 库的一部分。
新工具:新的编译工具,如:Nashorn 引擎 jjs、类依赖分析器 jdeps。
2.构造器是否可以重写?
Constructor 不能被 override(重写),但是可以 overload(重载),所以你可以看到?个类中有多个构造函数的情况。
3.wait() 和 sleep 区别
来源不同:sleep()来自 Thread 类,wait()来自 Object 类。
对于同步锁的影响不同:sleep()不会该表同步锁的行为,如果当前线程持有同步锁,那么 sleep 是不会让线程释放同步锁的。
wait()会释放同步锁,让其他线程进入 synchronized 代码块执行。
使用范围不同:sleep()可以在任何地方使用。wait()只能在同步控制方法或者同步控制块里面使用,否则会抛 IllegalMonitorStateException。
恢复方式不同:两者会暂停当前线程,但是在恢复上不太一样。sleep()在时间到了之后会重新恢复;
wait()则需要其他线程调用同一对象的 notify()/nofityAll()才能重新恢复。
4.&和&&的区别
&运算符有两种用法:
按位与;
逻辑与。
&&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是 true 整个表达式的值才是 true。
&&之所以称为短路运算,是因为如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算。
注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。
|