Java基础常见面试题总结(上)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

一、基础概念与常识

1. Java 语言有哪些特点?

  1. 简单易学
  2. 面向对象封装、继承、多态
  3. 平台无关性Java虚拟机实现平台无关性
  4. 支持多线程
  5. 可靠性
  6. 安全性
  7. 支持网络编程并且很方便
  8. 编译与解释并存

2. JDK、JRE、JVM

  1. JVM Java 虚拟机JVM是运行 Java 字节码的虚拟机。JVM 有针对不同系统的特定实现WindowsLinuxmacOS目的是使用相同的字节码它们都会给出相同的结果。字节码和不同系统的 JVM 实现是 Java 语言 “一次编译随处可以运行” 的关键所在。
  2. JDK JDK 是 Java Development Kit 缩写它是功能齐全的 Java SDK。它拥有 JRE 所拥有的一切还有编译器javac和工具如 javadoc 和 jdb。它能够创建和编译程序
  3. JRE JRE 是 Java 运行时环境。它是运行已编译 Java 程序所需的所有内容的集合包括 Java 虚拟机JVMJava 类库java 命令和其他的一些基础构件。但是它不能用于创建新程序

三者的关系图
在这里插入图片描述
 
一个Java程序的执行过程

  1. 我们利用JDK通过调用一些Java API写出java源程序然后储存在.java文件中。
  2. JDK中的源码编译器javac将源代码编译成java字节码储存在.class文件中。
  3. JRE加载、验证、执行Java字节码。
  4. JVM将字节码文件解析为机器码映射到CPU指令集或者供系统调用。

3. 什么是字节码?采用字节码的好处是什么?

在 Java 中JVM 可以理解的代码就叫做字节码即扩展名为 .class 的文件它不面向任何特定的处理器只面向虚拟机。
Java 语言通过字节码的方式在一定程度上解决了传统解释型语言执行效率低的问题同时又保留了解释型语言可移植的特点。所以 Java 程序运行时相对来说还是高效的而且由于字节码并不针对一种特定的机器因此Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。

 

4. 为什么说 Java 语言“编译与解释并存”

我们可以将高级编程语言按照程序的执行方式分为两种

  1. 编译型 编译型语言 会通过编译器将源代码一次性翻译成可被该平台执行的机器码。一般情况下编译语言的执行速度比较快开发效率比较低。常见的编译性语言有 C、C++、Go、Rust 等等。
  2. 解释型 解释型语言会通过解释器一句一句的将代码解释interpret为机器代码后再执行。解释型语言开发效率比较快执行速度比较慢。常见的解释性语言有 Python、JavaScript、PHP 等等。

Java 语言“编译与解释并存”的原因
这是因为 Java 语言既具有编译型语言的特征也具有解释型语言的特征。因为 Java 程序要经过先编译后解释两个步骤由 Java 编写的程序需要先经过编译步骤生成字节码.class 文件这种字节码必须由 Java 解释器来解释执行。

 

5. Java 和 C++ 的区别?

  1. Java 不提供指针来直接访问内存程序内存更加安全。
  2. Java 的类是单继承的C++ 支持多重继承虽然 Java 的类不可以多继承但是接口可以多继承。
  3. Java 有自动内存管理垃圾回收机制(GC)不需要程序员手动释放无用内存。
  4. C ++同时支持方法重载和操作符重载但是 Java 只支持方法重载。

 

二、基本语法

1. 注释有哪几种形式

Java中的注释有三种

  1. 单行注释 通常用于解释方法内某单行代码的作用。
  2. 多行注释 通常用于解释一段代码的作用。
  3. 文档注释 通常用于生成Java开发文档。

2. 标识符和关键字的区别是什么

在我们编写程序的时候需要大量地为程序、类、变量、方法等取名字于是就有了 标识符
有一些标识符Java 语言已经赋予了其特殊的含义只能用于特定的地方这些特殊的标识符就是 关键字 。简单来说关键字是被赋予特殊含义的标识符

 

3. Java 语言关键字有哪些

在这里插入图片描述

4. 静态变量有什么作用

静态变量可以被类的所有实例共享。无论一个类创建了多少个对象它们都共享同一份静态变量。
通常情况下静态变量会被 final 关键字修饰成为常量。

5. 什么是方法的返回值?方法有哪几种类型

方法的返回值 是指我们获取到的某个方法体中的代码执行后产生的结果前提是该方法可能产生结果。返回值的作用是接收出结果使得它可以用于其他的操作
我们可以按照方法的返回值和参数类型将方法分为下面这几种

  1. 无参数无返回值的方法
public void f1() {
    //......
}
// 下面这个方法也没有返回值虽然用到了 return
public void f(int a) {
    if (...) {
        // 表示结束方法的执行,下方的输出语句不会执行
        return;
    }
    System.out.println(a);
}
  1. 有参数无返回值的方法
public void f2(Parameter 1, ..., Parameter n) {
    //......
}
  1. 有返回值无参数的方法
public int f3() {
    //......
    return x;
}
  1. 有返回值有参数的方法
public int f4(int a, int b) {
    return a * b;
}

6. 静态方法和实例方法有何不同

  1. 调用方式
    在外部调用静态方法时可以使用 类名.方法名 的方式也可以使用 对象.方法名 的方式而实例方法只有后面这种方式。也就是说调用静态方法可以无需创建对象
    不过需要注意的是一般不建议使用 对象.方法名 的方式来调用静态方法。这种方式非常容易造成混淆静态方法不属于类的某个对象而是属于这个类。
    因此一般建议使用 类名.方法名 的方式来调用静态方法。
public class Person {
    public void method() {
      //......
    }

    public static void staicMethod(){
      //......
    }
    public static void main(String[] args) {
        Person person = new Person();
        // 调用实例方法
        person.method();
        // 调用静态方法
        Person.staicMethod()
    }
}
  1. 访问类成员是否存在限制
    静态方法在访问本类的成员时只允许访问静态成员即静态成员变量和静态方法不允许访问实例成员即实例成员变量和实例方法而实例方法不存在这个限制。

7. 重载和重写有什么区别

重载就是同样的一个方法能根据输入数据的不同做出不同的处理。
重写就是当子类继承自父类的相同方法输入数据一样但要做出有别于父类的响应时你就要覆盖父类方法。

重载
发生在同一个类中或者父类和子类之间方法名必须相同参数类型不同、个数不同、顺序不同方法返回值和访问修饰符可以不同。

Java 允许重载任何方法 而不只是构造器方法。

重写
重写发生在运行期是子类对父类的允许访问的方法的实现过程进行重新编写。

  1. 方法名、参数列表必须相同子类方法返回值类型应比父类方法返回值类型更小或相等抛出的异常范围小于等于父类访问修饰符范围大于等于父类。
  2. 如果父类方法访问修饰符为 private/final/static 则子类就不能重写该方法但是被 static 修饰的方法能够被再次声明。
  3. 构造方法无法被重写。

综上重写就是子类对父类方法的重新改造外部样子不能改变内部逻辑可以改变。

在这里插入图片描述

8. 什么是可变长参数

从 Java5 开始Java 支持定义可变长参数所谓可变长参数就是允许在调用方法时传入不定长度的参数。就比如下面的这个 方法就可以接受 0 个或者多个参数

public static void method1(String... args) {
   //......
}

另外可变参数只能作为函数的最后一个参数但其前面可以有也可以没有任何其他参数。

public static void method2(String arg1, String... args) {
   //......
}

另外Java 的可变参数编译后实际会被转换成一个数组我们看编译后生成的 class文件就可以看出来了。

public class VariableLengthArgument {

    public static void printVariable(String... args) {
        String[] var1 = args;
        int var2 = args.length;

        for(int var3 = 0; var3 < var2; ++var3) {
            String s = var1[var3];
            System.out.println(s);
        }

    }
    // ......
}

 
 

三、基本数据类型

1. Java 中的几种基本数据类型了解么

Java中有8种基本数据类型分别为

  • 6种数字类型

    • 4种整数型byteshortintlong
    • 2种浮点型floatdouble
  • 1种字符类型char

  • 1种布尔型boolean

这 8 种基本数据类型的默认值以及所占空间的大小如下
在这里插入图片描述

这八种基本类型都有对应的包装类分别为ByteShortIntegerLongFloatDoubleCharacterBoolean

2. 基本类型和包装类型的区别

  1. 成员变量包装类型不赋值就是 null 而基本类型有默认值且不是 null
  2. 包装类型可用于泛型而基本类型不可以。
  3. 基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中基本数据类型的成员变量未被 static 修饰 存放在 Java 虚拟机的堆中。包装类型属于对象类型我们知道几乎所有对象实例都存在于堆中。
  4. 相比于对象类型 基本数据类型占用的空间非常小。

3. 自动装箱与拆箱了解吗原理是什么

什么是自动拆装箱

  • 装箱 将基本类型用它们对应的引用类型包装起来
  • 拆箱 将包装类型转换为基本数据类型

举例

Integer i = 10;  //装箱
int n = i;   //拆箱

4. 为什么浮点数运算的时候会有精度丢失的风险

浮点数运算精度丢失代码演示

float a = 2.0f - 1.9f;
float b = 1.8f - 1.7f;
System.out.println(a);// 0.100000024
System.out.println(b);// 0.099999905
System.out.println(a == b);// false

为什么会出现这个问题呢
这个和计算机保存浮点数的机制有很大关系。我们知道计算机是二进制的而且计算机在表示一个数字时宽度是有限的无限循环的小数存储在计算机时只能被截断所以就会导致小数精度发生损失的情况。这也就是解释了为什么浮点数没有办法用二进制精确表示。

5. 如何解决浮点数运算的精度丢失问题

BigDecimal 可以实现对浮点数的运算不会造成精度丢失。通常情况下大部分需要浮点数精确运算结果的业务场景比如涉及到钱的场景都是通过 BigDecimal 来做的。

BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
BigDecimal c = new BigDecimal("0.8");

BigDecimal x = a.subtract(b);
BigDecimal y = b.subtract(c);

System.out.println(x); /* 0.1 */
System.out.println(y); /* 0.1 */
System.out.println(Objects.equals(x, y)); /* true */

6. 超过 long 整型的数据应该如何表示

基本数值类型都有一个表达范围如果超过这个范围就会有数值溢出的风险。
在 Java 中64 位 long 整型是最大的整数类型。

long l = Long.MAX_VALUE;
System.out.println(l + 1); // -9223372036854775808
System.out.println(l + 1 == Long.MIN_VALUE); // true

BigInteger 内部使用 int[] 数组来存储任意大小的整形数据。

相对于常规整数类型的运算来说BigInteger 运算的效率会相对较低。

 
 

创作不易如果有帮助到你请给文章点个赞和收藏让更多的人看到
关注博主不迷路内容持续更新中。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java