zl程序教程

您现在的位置是:首页 >  后端

当前栏目

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

JAVA面试题基础 总结 常见
2023-09-11 14:20:19 时间

❤ 作者主页:Java技术一点通的博客
❀ 个人介绍:大家好,我是Java技术一点通!( ̄▽ ̄)~*
❀ 微信公众号:Java技术一点通
🍊 记得点赞、收藏、评论⭐️⭐️⭐️
📣 认真学习! ! !🎉🎉

一、基础概念与常识

1. Java 语言有哪些特点?

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

2. JDK、JRE、JVM

  1. JVM: Java 虚拟机(JVM)是运行 Java 字节码的虚拟机。JVM 有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。字节码和不同系统的 JVM 实现是 Java 语言 “一次编译,随处可以运行” 的关键所在。
  2. JDK: JDK 是 Java Development Kit 缩写,它是功能齐全的 Java SDK。它拥有 JRE 所拥有的一切,还有编译器(javac)和工具(如 javadoc 和 jdb)。它能够创建和编译程序
  3. JRE: JRE 是 Java 运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,包括 Java 虚拟机(JVM),Java 类库,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 运算的效率会相对较低。

 
 

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