基础概念与常识
- 简单易学
- 面向对象(继承、封装、多态)
- 平台无关性
- 支持多线程
JavaSE和JavaEE?
- SE:是Java的基础版本,更适合开发一些简单应用程序。
- EE:是Java的高级版本,适合开发一些企业级应用程序。
JVM、JDK、JRE?
- JVM:是Java最核心和最具特色的功能之一,主要是将字节码文件转换为特定平台的机器码斌执行。除此之外还提供了内存管理、垃圾回收、即时编译等功能。
- JDK:主要是面向Java开发人员,提供了完整的开发环境。包括编译、调试、运行和文档生成等功能。
- JRE:是Java运行时所需要的最小环境,其包括了Java虚拟机以及一系列的核心库文件和运行时支持文件。
什么是字节码?采用字节码的好处是什么?
- 字节码:字节码是一种中间代码,它是由Java编译器编译Java原生代码生成的一种代码。它由一系列以字节为单位的指令组成,每个指令对应一条操作如(存储、运算)。这些字节码文件可以被JVM解释执行,从而实现跨平台的能力(一次编写,到处运行)。
- 好处:
- 跨平台:字节码文件可以在任何实现了Java虚拟机规范的平台上运行
- 性能优化: 字节码可以被即时编译器(JIT Compiler)动态地编译成本地机器码,以提高程序的执行效率
- 安全性:Java虚拟机会对字节码进行严格的检查,提高安全性
为什么说JAVA是编译与解释共存的语言?
- 由字节码==》机器码。
- 在最初时,在这里JVM虚拟机首先会加载字节码文件,然后通过解释器去逐行解释执行,这种方式执行速度很慢。
- 后面经过改进,对于热点代码,将其通过JIT编译器,在编译时将该字节码对应的机器码保存下来,下次遇到该字节码时直接使用即可。
- 这也是为什么说JAVA是编译与解释共存的语言
解释一下编译型语言和解释型语言?
- 编译型:编译型语言会通过编译器将源代码一次性翻译为可以被平台执行的机器码。(C、C++)
- 解释型:解释型语言会通过解释器将代码解释为机器码后再执行(Python、PHP、JavaScript)
什么是AOT、有什么优点?
- AOT是Java9之后引入的一种新的编译模式、其在程序执行前就将其编译为机器码(与C、C++类似)
- 优点:避免了JIT预热的时间紧开销、减少了内存开销、提高了Java的启动速度
为什么不全部使用AOT?
- AOT更适合云原生场景、对微服务框架的支持也比较友好。但是其不支持Java的一些动态特性。如反射、动态代理等
Java和C++的相同点和不同点?
- 相同点:都是面向对象的语言、都支持继承多态和封装
- 不同点:
- Java不提供指针来直接访问内存,程序内存更加安全
- Java的类是单继承的,而C++支持多重继承
- Java无需手动释放内存,通过其垃圾回收机制来释放内存
基本语法
Java的注释有几种?
- 单行注释
- 多行注释
- 文档注释
标识符合关键字的区别?
- 标识符用来命名变量、类、方法等。在程序当中起到标识和引用的作用。
- 关键字是编程语言预先定义好的具有特殊含义的单词。如for,while,this等
移位运算符
- 基本运算符之一、常用在在各种框架的源码当中。
- <<:左移:x<<1。表示x乘以2
- >>:右移:x>>1。表示x除以2
- >>>:无符号右移
continue、break和return的区别是什么?
- continue:表示跳出当前这一次循环,继续下一次循环
- break:表示跳出整个循环体
- return:表示跳出当前方法
基本数据类型
Java的几种基本数据类型:
- byte:1字节
- short:2字节
- int:4字节
- long:8字节
- float:4字节
- char:2字节
- double:8字节
- boolean:1位
基本数据类型和包装类型的区别?
- 用途:基本数据类型可以用来定义一些常量和局部变量。而包装类可以用于泛型
- 存储方式:基本数据类型的局部变量,存储在Java虚拟机栈的局部变量表当中;基本数据类型的成员变量,存储在Java虚拟堆当中。包装类属于对象类型,基本所有的对象实例都存放在堆中。
- 比较方式:对于基本数据类型来说,==比较的是值。对于包装数类型来说,==比较的是对象的内存地址。所以整型包装类对象之间值的比较,全部使用equals()方法
为什么说基本所有的对象实例都存放在堆当中?
- 在虚拟机引入JIT优化后,会对对象进行逃逸分析,如果发现对象没有逃逸到方法的外部,就有可能会进行栈上分配来代替堆分配内存。
什么是自动装箱和拆箱?原理是什么?
- 自动装箱:是指将基本类型的值自动转换为对应的包装类型的对象
- 自动拆箱:是指将包装类型转换为对应的基本数据类型的值
- 原理:在编译时,编译器会根据代码上下文自动插入装箱和拆箱的代码,使得程序员可以直接使用基本类型和包装类型而不必关心它们之间的转换
- 注意:如果频繁拆装箱的话,也会严重影响系统的性能
为什么浮点数运算的时候会有精度丢失的风险?
- 浮点数运算的精度丢失风险主要是由于浮点数的二进制表示方式以及浮点数运算的特性所导致的。
- 如何解决:涉及到需要高精度计算的场景下,可以考虑使用 BigDecimal 类型来进行精确计算。
变量
成员变量和局部变量的区别?
- 作用域:成员变量是定义在类中的变量,它的作用域是整个类。而局部变量是定义在某个方法当中,其作用域为所在方法或代码块当中
- 存储位置:成员变量存储在堆(Heap)内存中,因为它们随着对象的创建而创建,随着对象的销毁而销毁。局部变量存储在栈(Stack)内存中,一旦方法调用结束或者代码块执行完毕,局部变量就会被销毁。
- 默认值:成员变量会被自动初始化为其对应的默认值(如int型默认值为0,引用类型默认值为null)。局部变量不会被自动初始化。
静态变量有什么作用?
- 静态变量也就是被
static
关键字修饰的变量。它是属于类的,能够被类的所有实例对象共享,也就是说,即使创建了多个对象,静态变量只会被分配一次内存,可以节省内存开销。
字符型常量和字符串常量的区别?
- 形式 : 字符常量是单引号引起的一个字符,字符串常量是双引号引起的 0 个或若干个字符
- 含义 : 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址值(该字符串在内存中存放位置)。
- 占内存大小:字符常量只占 2 个字节; 字符串常量占若干个字节。
方法
什么是方法的返回值?方法有哪几种类型?
- 指我们获取到的某个方法体中的代码执行后产生的结果!(前提是该方法可能产生结果)。返回值的作用是接收出结果,使得它可以用于其他的操作
- 无参数无返回值的方法
- 有参数无返回值的方法
- 有返回值无参数的方法
- 有返回值有参数的方法
静态方法为什么不能调用非静态成员?
- 静态方法是属于类的,在类加载的时候就会分配内存,可以通过类名这访问
- 非静态成员属于类的实例对象,只有在实例化对象后才存在,需要通过对象进行访问。
- 静态方法是先存在的,这时候去调用还不存在的非静态成员肯定是非法的。
静态方法和实例方法有何不同?
- 调用方式:静态方法可以通过类名直接调用,无需创建类的实例对象。实例方法必须通过类的实例对象来调用
- 访问权限:静态方法中可以直接访问静态变量,但不能直接访问实例变量。实例方法中可以直接访问静态变量和实例变量。
- 内存分配:静态方法在类加载时被加载到内存中。实例方法在实例化对象时被加载到内存中,
重载和重写的区别?
- 重载就是同样的一个方法能够根据输入数据的不同,做出不同的处理
- 重写就是当子类继承自父类的相同方法,输入数据一样,但要做出有别于父类的响应。
什么是可变长参数?
- 可变长参数(Varargs)是 Java 中的一种特性,在方法声明时,可以指定一个参数为可变长参数,这样在调用方法时可以传入任意数量的参数,这些参数会被自动封装成一个数组。
参考
- What is the difference between JDK and JRE?:https://stackoverflow.com/questions/1906445/what-is-the-difference-between-jdk-and-jreopen in new window
- Oracle vs OpenJDK:https://www.educba.com/oracle-vs-openjdk/open in new window
- Differences between Oracle JDK and OpenJDK:https://stackoverflow.com/questions/22358071/differences-between-oracle-jdk-and-openjdkopen in new window
- 彻底弄懂 Java 的移位操作符:https://juejin.cn/post/6844904025880526861