当前位置: 首页 > article >正文

Java面试黄金宝典1

1. 8 种基本数据类型

  • 整数类型
    1. byte
      它是最小的整数类型,占用 1 个字节(8 位)。在一些对内存使用要求极高的场景,比如嵌入式系统开发、数据传输时对数据量有严格限制的情况,会使用 byte 类型。例如,在处理图像数据中的像素值时,如果每个像素值范围在 -128 到 127 之间,就可以用 byte 存储。
    2. short
      占用 2 个字节(16 位)。在一些特定的图形处理库中,可能会使用 short 来表示一些相对较小的坐标值或颜色分量值,因为它比 int 更节省内存。
    3. int
      这是 Java 中最常用的整数类型,占用 4 个字节(32 位)。在日常的编程中,如计数、索引、循环控制等场景,通常都会使用 int 类型。例如,遍历数组、计算循环次数等。
    4. long
      占用 8 个字节(64 位)。当需要处理非常大的整数时,如计算时间戳(以毫秒为单位)、处理大数据量的统计结果等,就需要使用 long 类型。定义时,需要在数字后面加上 Ll,建议使用大写的 L,因为小写的 l 容易与数字 1 混淆。
  • 浮点类型
    1. float
      单精度浮点数,占用 4 个字节(32 位)。在一些对精度要求不高的科学计算、图形处理中的一些近似计算等场景中使用。例如,在游戏开发中,计算物体的位置、速度等,可能只需要一定的精度,此时可以使用 float 类型。定义时需要在数字后面加上 Ff
    2. double
      双精度浮点数,占用 8 个字节(64 位)。是 Java 中默认的浮点类型,精度比 float 高。在大多数需要处理小数的场景中,如金融计算、科学研究等,都会使用 double 类型。
  • 字符类型
    1. char
      占用 2 个字节(16 位),基于 Unicode 字符集,可以表示世界上大多数语言的字符。在处理文本、字符串操作时,char 类型非常有用。例如,遍历字符串中的每个字符时,就会用到 char 类型。
  • 布尔类型
    1. boolean
      只有两个值,truefalse,用于逻辑判断。在条件语句(如 ifwhile 等)、逻辑运算中广泛使用。

2. 什么是装箱和拆箱

  • 装箱
    1. 自动装箱:Java 编译器会自动将基本数据类型转换为对应的包装类对象。例如:

java

int num = 10;
Integer integerObj = num; // 自动装箱

                  2. 手动装箱:在 Java 9 及以前,可以使用包装类的构造方法进行装箱;Java 9 及以后,部分构造方法已被弃用,建议使用 valueOf 方法。例如:

java

int num = 10;
// Java 9 以前
// Integer integerObj2 = new Integer(num); 
// Java 9 及以后
Integer integerObj2 = Integer.valueOf(num); 

使用 valueOf 方法的好处是,它会缓存一些常用的值,提高性能。例如,Integer 类会缓存 -128 到 127 之间的整数对象,当使用 valueOf 方法创建这个范围内的对象时,会直接返回缓存的对象,而不是创建新的对象。

  • 拆箱
    1. 自动拆箱:Java 编译器会自动将包装类对象转换为对应的基本数据类型。例如:

java

Integer integer = 20;
int num2 = integer; // 自动拆箱

                    2. 手动拆箱:调用包装类的 xxxValue() 方法进行拆箱。例如:

java

Integer integer = 20;
int num3 = integer.intValue(); // 手动拆箱

3. String 转出 int 型,判断能不能转?如何转?

  • 判断能否转换的更多方法

  1. 正则表达式:可以使用正则表达式判断字符串是否只包含数字字符。例如:

java

import java.util.regex.Pattern;

public class StringToInt {
    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("^-?\\d+$");
        return pattern.matcher(str).matches();
    }

    public static void main(String[] args) {
        String str = "123";
        if (isNumeric(str)) {
            try {
                int num = Integer.parseInt(str);
                System.out.println(num);
            } catch (NumberFormatException e) {
                System.out.println("字符串不能转换为整数");
            }
        } else {
            System.out.println("字符串不是有效的数字");
        }
    }
}

       2. 尝试转换并捕获异常:直接尝试使用 Integer.parseInt()Integer.valueOf() 方法进行转换,并捕获 NumberFormatException 异常。例如:

java

public class StringToInt2 {
    public static void main(String[] args) {
        String str = "abc";
        try {
            int num = Integer.parseInt(str);
            System.out.println(num);
        } catch (NumberFormatException e) {
            System.out.println("字符串不能转换为整数");
        }
    }
}

  • 转换方法的性能分析

  1. Integer.parseInt() 方法直接返回基本数据类型 int,效率相对较高,适用于需要直接使用 int 类型的场景。
  2. Integer.valueOf() 方法返回的是 Integer 对象,在需要基本数据类型时会自动拆箱。如果需要使用 Integer 对象,或者在泛型、集合等场景中使用,建议使用 Integer.valueOf() 方法。

4. short s1 = 1; s1 = s1 + 1; 有什么错?short s1 = 1; s1 +=1; 有什么错?

  • short s1 = 1; s1 = s1 + 1;
    在 Java 中,当进行算术运算时,shortbytechar 类型会自动提升为 int 类型。所以 s1 + 1 的结果是 int 类型。而 s1short 类型,将 int 类型的值赋给 short 类型的变量需要进行强制类型转换,否则会导致编译错误。正确的写法是:

java

short s1 = 1;
s1 = (short) (s1 + 1);

  • short s1 = 1; s1 +=1;
    += 是复合赋值运算符,它会自动进行类型转换。s1 += 1 实际上等价于 s1 = (short)(s1 + 1),所以不会有编译错误。

5. Int 与 Integer 区别

  • 内存使用差异

  1. int 类型变量直接存储值,存储在栈内存中,占用的内存空间是固定的,根据类型不同而不同(如 int 占用 4 个字节)。
  2. Integer 是引用类型,变量存储的是对象的引用,对象本身存储在堆内存中,引用存储在栈内存中。除了对象本身占用的内存外,还需要额外的内存来存储引用。

  • 性能差异

  1. 在进行大量的数值计算时,int 类型的性能要高于 Integer 类型。因为 int 类型不需要进行装箱和拆箱操作,而 Integer 类型在进行计算时需要进行装箱和拆箱,会带来一定的性能开销。

6. 字节字符区别

  • 编码与解码

  1. 字节:字节是计算机存储和传输数据的基本单位,在不同的编码格式下,字节与字符的对应关系不同。例如,在 ASCII 编码中,一个字节对应一个字符;在 UTF - 8 编码中,一个字符可能由 1 到 4 个字节表示。
  2. 字符:字符是人类能够识别的符号,在 Java 中,char 类型基于 Unicode 字符集。在进行文件读写、网络传输等操作时,需要进行字符编码和解码。例如,将字符串转换为字节数组时,需要指定编码格式:

java

String str = "你好";
try {
    byte[] bytes = str.getBytes("UTF-8");
} catch (Exception e) {
    e.printStackTrace();
}

  • 处理场景

  1. 字节处理:在处理二进制文件(如图片、视频、音频等)时,主要使用字节进行操作。例如,使用 FileInputStreamFileOutputStream 进行文件读写时,读取和写入的都是字节数据。
  2. 字符处理:在处理文本文件(如 .txt 文件)、进行字符串操作时,主要使用字符进行操作。例如,使用 FileReaderFileWriter 进行文件读写时,读取和写入的都是字符数据。

7. 基本类型与引用类型的区别

  • 垃圾回收

  1. 基本类型:基本类型变量存储在栈内存中,当变量的作用域结束时,栈内存中的空间会自动释放,不需要垃圾回收机制进行处理。
  2. 引用类型:引用类型对象存储在堆内存中,当对象不再被引用时,会被垃圾回收机制标记为可回收对象,在合适的时机进行回收。

  • 数组与基本类型、引用类型的关系

  1. 基本类型数组:数组中的每个元素都是基本类型,数组本身是引用类型,存储在堆内存中,而数组元素存储在数组所占用的内存空间中。例如:

java

int[] arr = new int[10];

     2. 引用类型数组:数组中的每个元素都是引用类型,数组本身和数组元素都存储在堆内存中。例如:

java

String[] strArr = new String[10];

8. 重写重载封装继承多态

  • 重写的注意事项

  1. 异常处理:子类重写的方法不能抛出比父类被重写方法更多、更宽泛的异常。例如,如果父类方法抛出 IOException,子类重写的方法可以抛出 IOException 或其子类异常,或者不抛出异常。
  2. 方法签名严格匹配:方法名、参数列表和返回值类型必须与父类被重写的方法相同(子类返回值类型可以是父类返回值类型的子类,这称为协变返回类型)。

  • 重载的实现原理

重载方法是根据方法的参数列表(参数个数、类型或顺序)来区分的。在编译时,编译器会根据调用方法时传递的参数类型和数量,选择合适的重载方法进行调用。

  • 封装的优势

  1. 提高安全性:通过将数据和操作数据的方法封装在一起,使用 private 访问修饰符隐藏对象的内部实现细节,只对外提供必要的接口,可以防止外部代码直接访问和修改对象的内部数据,从而提高代码的安全性。
  2. 提高可维护性:当需要修改对象的内部实现时,只需要修改封装类的内部代码,而不会影响到外部调用代码,降低了代码的耦合度,提高了代码的可维护性。

  • 继承的限制和拓展

  1. 单继承限制:Java 只支持单继承,即一个子类只能有一个直接父类。但可以通过实现多个接口来实现类似多继承的功能。
  2. 方法重写和调用父类方法:子类可以重写父类的方法来实现自己的功能,同时可以使用 super 关键字调用父类的方法。例如:

java

class Parent {
    public void print() {
        System.out.println("Parent");
    }
}

class Child extends Parent {
    @Override
    public void print() {
        super.print();
        System.out.println("Child");
    }
}

  • 多态的实现方式和应用场景

  1. 实现方式:多态的实现方式有继承和接口。通过父类引用指向子类对象,在运行时根据实际对象类型调用相应的方法。例如:

java

class Animal {
    public void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.sound();
    }
}

       2.应用场景:多态在代码的可扩展性和可维护性方面有很大的优势。例如,在游戏开发中,不同的角色可能有不同的攻击方式,可以通过多态来实现统一的攻击接口,根据实际角色类型调用相应的攻击方法。

9.是否可以覆盖 (override) 一个 private 或者是 static 的方法?

  • private 方法
    private 方法的作用域仅限于当前类,子类无法访问父类的 private 方法。所以子类中定义的与父类 private 方法同名的方法,只是一个新的方法,与父类的方法没有关系。例如:

java

class Parent {
    private void privateMethod() {
        System.out.println("Parent private method");
    }
}

class Child extends Parent {
    public void privateMethod() {
        System.out.println("Child private method");
    }
}

在这个例子中,Child 类中的 privateMethod 方法与 Parent 类中的 privateMethod 方法没有重写关系。

  • static 方法
    静态方法属于类,而不是对象。子类可以定义与父类静态方法同名的静态方法,这称为方法隐藏。调用时,根据引用类型决定调用哪个方法,而不是根据实际对象类型。例如:

java

class Parent {
    public static void staticMethod() {
        System.out.println("Parent static method");
    }
}

class Child extends Parent {
    public static void staticMethod() {
        System.out.println("Child static method");
    }
}

public class Main {
    public static void main(String[] args) {
        Parent parent = new Child();
        parent.staticMethod(); // 调用 Parent 类的 staticMethod 方法
    }
}

10. 什么是 PriorityQueue

  • 实现原理

PriorityQueue 基于优先级堆实现,优先级堆是一种完全二叉树,它的每个节点的值都大于或等于其子节点的值(最大堆),或者小于或等于其子节点的值(最小堆)。在 PriorityQueue 中,默认是最小堆。插入和删除元素的时间复杂度为 O (log n),获取队首元素的时间复杂度为 O (1)。

  • 自定义比较器

可以通过提供自定义的 Comparator 来指定元素的排序规则。例如,要创建一个最大堆的 PriorityQueue

java

import java.util.PriorityQueue;
import java.util.Comparator;

public class PriorityQueueExample {
    public static void main(String[] args) {
        PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder());
        pq.add(3);
        pq.add(1);
        pq.add(2);

        while (!pq.isEmpty()) {
            System.out.println(pq.poll());
        }
    }
}

  • 应用场景拓展

  1. 任务调度:在操作系统中,任务调度器可以使用 PriorityQueue 来管理任务,根据任务的优先级来决定任务的执行顺序。
  2. Dijkstra 算法:在图算法中,Dijkstra 算法可以使用 PriorityQueue 来优化,提高算法的效率。

 友情提示:本文已经整理成文档,可以到如下链接免积分下载阅读

 https://download.csdn.net/download/ylfhpy/90493708


http://www.kler.cn/a/592046.html

相关文章:

  • 数据库:一文掌握 MongoDB 的各种指令(MongoDB指令备忘)
  • linux 出现网卡 down 没起来 怎么办 ? 已解决
  • Python - 爬虫-网页抓取数据-工具wget
  • 文献阅读篇#1:C会/期刊的改进YOLO论文应放弃即插即用,至少要学会简单融合拼接(1)
  • 蓝桥杯24年真题:回文字符串
  • 力扣:2.两数相加(O(n)复杂度)
  • Git 使用SSH登陆
  • OpenCV多分辨率模板匹配与容错优化实战指南
  • 顺序表和链表的对比(一)
  • Python----数据分析(Pandas三:一维数组Series的数据操作:数据清洗,数据转换,数据排序,数据筛选,数据拼接)
  • Git 克隆问题排查与解决方案
  • HarmonyOS NEXT开发教程:加速web页面访问
  • ubuntu中的环境变量文件 bashrc、profile、environment简要总结
  • 确保刷新页面后用户登录状态不会失效,永久化存储用户登录信息
  • 大模型面试高频考点-显存占用
  • 大数据学习(72)-zookeeper选举机制
  • Linux top 命令详解:从入门到高级用法
  • Leetcode Hot 100 46.全排列
  • 在LORA训练中,LORA模型的矩阵的行列是多少
  • 《Python深度学习》第五讲:文本处理中的深度学习