首页 > 编程语言 >2024最新Java面试题——java基础

2024最新Java面试题——java基础

时间:2024-05-22 20:07:28浏览次数:32  
标签:面试题 java 对象 2024 线程 面向对象编程 Java 拷贝 方法

1. 如何理解OOP面向对象编程


       在面向对象编程中,程序被组织成一系列互相关联和相互作用的对象,每个对象都有自己的属性和方法。对象之间通过消息传递的方式进行交互,通过定义类和实例化对象来创建具体的对象。

       面向对象是一种编程思想,也是一种编程模式,将现实中的实物抽象成对象,因此,也有人将抽象定义为面向对象编程的第四大特点。

        面向对象编程的主要特点包括:

  • 封装
           封装是将数据和操作数据的方法封装在一个对象内部,隐藏内部实现细节,只对外提供公共接口。这样可以保护数据的完整性和安全性,并且提高代码的模块化和可维护性。
  • 继承
           继承允许一个类(子类)继承另一个类(父类)的属性和方法。子类可以重用父类代码,并且可以通过过添加新的特性或者修改已有特性来扩展或定制父类的功能。
  • 多态
           多态是指同一个方法可以根据不同的对象类型表现出不同的行为。多态使得代码更加灵活,可以处理不同类型的对象,并且可以在运行时多态确定对象的实际类型。


       通过面向对象编程,开发人员可以更好地模拟现实世界的问题领域,将复杂的问题分解为简单的对象,并通过对象之间的交互来解决问题。面向对象编程提供了一种结构化和模块化的方法,是的代码更易于维护。重用和扩展。
常见的面向对象编程语言包括Java,C++,Python等。

2. JVM、JRE、JDK的区别

  • JVM:java虚拟机,负责将Java字节码解释编程成特定平台的机器码来执行。
  • JRE:java运行环境,由JVM和运行java程序所必需的内库等组成。
  • JDK:java开发工具包。由JRE和开发java程序所需的命令等组成。

3. 面向对象和面向过程的区别

       面向对象编程(OOP) 和面向过程编程是两种不同的编程范式。主要区别是:

  • 核心思想
    • 面向对象编程:将程序中的数据和方法组织在一起,形成”对象“,并通过对象之间的互相通信与协作来完成任务,强调的是数据和行为的封装。
    • 面向过程编程:将问题划分为一系列的步骤或过程,通过调用函数来依次执行这些步骤来解决问题。强调的是算法和逻辑的执行流程。
  • 代码结构
    • 面向对象编程:程序被看做一组对象的集合,每个对象包含数据和方法,对象之间通过消息传递进行通信,可以实现数据的封装、继承和多态。
    • 面向过程编程:程序被看做一系列的函数或者过程的集合,数据和函数是分离的,函数通过参数传递数据进行处理。
  • 重用性
    • 面向对象编程:支持代码的重用行,通过类和对象的继承关系可以实现代码的复用,同时也能提高代码的可维护性和扩展性。
    • 面向过程编程:代码重用主要依靠函数的复用,缺乏类和对象的概念,因此在复杂项目中可能会导致代码的冗余和难以维护。
  • 维护性
    • 面向对象编程:由于具有良好的封装性和模块化特性,使得程序结构清晰,易于维护和修改。
    • 面向过程编程:较为直接的线性执行方式,可能随着程序规模的增大而变得难以维护。
  • 使用场景
    • 面向对象编程:适用于大型,复杂的软件系统开发,能更高的应对需求变化和扩展。
    • 面向过程编程:适用于简单,小规模的程序开发,以及对性能要求较高的场景。
      总的来说,面向对象编程更加注重数据的封装和抽象,适合于大型软件系统的开发。而面向过程编程更加注重算法和流程的执行,适合于较为简单和直接的问题求解。

4. 重载与重写的区别

  • 重载(overload)指的是在同一个类中,可以有多个方法拥有相同的名称,但是他们的参数列表不同,编译器会区分这些方法,并且根据调用时传入的数据类型和数量来确定具体调用哪一个方法。重载能够使同一个方法名进行不同的操作,提高了代码的灵活性和可读性。

  • 重写(override)指的是子类重新定义了父类中已有的方法,使得子类的方法覆盖了父类中的方法。在重写中,方法名、返回类型和参数列表必须与父类中的方法完全相同,这样才能实现方法的重写。重写允许子类根据自身的需要对继承而来的方法进行修改,实现了多态性的特性。

5. 接口与抽象类的异同

  • 相同点
    1. 都是用于实现多态性和代码重用的机制。
    2. 都可以包含抽象方法,需要子类提供具体实现。
    3. 都不能被实例化,只能被其它类继承或实现。
  • 不同点

    1. 定义方式不同
    • 接口只能包含抽象方法、常量和默认方法,不能包含字段和构造函数。
    • 抽象类可以包含抽象方法、具体方法、字段和构造函数。

    1. 继承方式不同
    • 一个类可以实现多个接口,但只能继承一个抽象类。
    • 接口之间可以相互继承,形成接口的继承链,而抽象类只能单继承。

    1. 目的不同
    • 接口用于定义类之间的契约,描述了类应该具有的行为,强调接口的实现。
    • 抽象类用于捕捉子类之间的通用行为,提供一种模板或者结构,强调代码的复用性和扩展性。

    1. 设计思想不同
    • 接口强调“做什么”而不关心“怎么做”,侧重于约定规范和行为。
    • 抽象类强调子类之间的共性,并提供默认的实现,侧重于代码的重用和扩展。

6. 深拷贝与浅拷贝的理解

       深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是编程中用于复制对象或数据结构的两种不同方式。主要区别是:

  • 浅拷贝
    • 浅拷贝是指在复制过程中,只复制对象本身(对象地址),而不复制对象内部的引用类型数据。
    • 在浅拷贝中,新对象和原对象共享相同的内存地址,因此修改新对象可能会影响原对象,反之亦然。
    • 浅拷贝通常是通过复制对象的字段值或引用来实现的,如使用赋值操作符或copy()方法。
  • 深拷贝
    • 深拷贝是指在复制过程中,不仅复制对象本身,还递归复制对象内部的所有引用类型数据,确保新对象与原对象完全独立,互不影响。
    • 在深拷贝中,新对象和原对象拥有不同的内存地址,修改一个对象不会影响另一个对象。
    • 深拷贝通常需要遍历对象的所有属性,对每个引用类型属性进行独立复制,以确保所有层级的引用关系都被复制。
      在实际编程中,选择深拷贝还是浅拷贝取决于需求:
  • 如果对象的内部包含了可变对象,并且需要保持原对象和新对象的独立性,避免相互影响,应该使用深拷贝。
  • 如果对象的内部没有可变对象,或者共享内部对象并不会造成问题,可以使用浅拷贝来提高效率。

Tip:深拷贝可能会比浅拷贝消耗更多的时间和资源,特别是当对象结构较为复杂时。因此,在选择拷贝方式时,需要综合考虑程序的性能和需求,选择最合适的方式。

7. "=="和equals的区别

       "=="和equals是用于比较两个对象的不同方式。主要区别在于:

  • "=="操作符
    • "=="操作符用于比较两个对象的引用是否指向同一内存地址,即比较对象的引用是否相同。
    • 当使用"=="来比较基本数据类型时,比较的是它们的值;当比较对象时,比较的是它们在内存中的存储地址。
  • "equals"方法
    • "equals"方法是Object类中定义的方法,用于比较两个对象的内容是否相等。
    • 在Object类中,"equals"方法默认行为是和"=="操作符相同,即比较对象的引用是否相同。
    • 但是,很多类(String, Integer, ...)会重写”equals“方法,以便比较对象的内容是否相等。

8. sleep和wait的异同

        sleep() 和 wait() 是用于线程控制的两个方法。

  • 相同点
    1. 都是用于线程控制,可以使线程进入暂停状态。
    2. 在调用这两个方法时,都会暂停当前线程的执行。

  • 不同点
    1. 来源不同
      • sleep() 方法来自Thread类,是静态方法。
      • wait() 方法来自Object类,需要在同步代码块或同步方法中调用。
    2. 使用场景不同
      • sleep() 方法通常用于让线程休眠一段时间,在等待一定时间后自动恢复执行,他不会释放对象的锁。
      • wait() 方法通常用于线程间的协作和通信,当调用wait() 方法时,当前线程会释放对象的锁,进入等待状态,知道另一个线程调用notify() 或notifyAll() 方法唤醒该线程。
    3. 锁的释放情况不同
      • sleep() 方法在休眠期间不会释放对象的锁,其他线程无法获得对象的监视器。
      • wait() 方法在等待期间会释放对象的锁,允许其他线程获得该对象的监视器并执行。
    4. 唤醒方式不同
      • sleep() 方法只能通过指定的时间间隔或者被中断才能唤醒。
      • wait() 方法在等待期间需要等待其他线程调用notify() 或notifyAll() 方法来唤醒。
               总体来说,sleep() 主要用于线程的休眠和定时任务的处理,而wait() 主要用于多线程之间的协调和通信。

9. 什么是自动拆装箱?int和Integer有什么区别?

  • 自动拆装箱是java的一种特性,它允许基本数据类型和其对应的包装类之间进行自动切换,从而使得在需要使用包装类的地方可以直接使用基本数据类型,反之亦然。这样可以简化代码,使得代码更加易读和便于维护。
    int和Integer之间的区别:

    1. int是Java的基本数据类型,表示整数,占用4字节的存储空间,可以直接存储数值。
    2. Integer是int的包装类,属于Java中的引用数据类型,用于将基本数据类型包装成对象,从而可以在需要对象的地方是使用。Integer对象是不可变的,即一旦创建不能被修改。
    3. 主要区别包括:
    • 存储方式:int存储的是具体的数值,而Integer存储的是对象的引用。
    • 使用方式:int是基本数据类型,直接存储数值;而Integer是对象,需要通过构造函数或自动装箱才能创建。
    • null值:int不支持null值,而Integer可以赋值为null。
    • 性能:基本数据类型int的性能通常比Integer对象要高,因为不涉及对象的创建和内存管理。
  • 在一般情况下,优先使用基本数据类型,只有在需要使用对象的场景下才考虑到使用包装类。使用自动拆装箱时要注意潜在的性能影响,避免不必要的拆装箱操作。

  • Java集合框架只能存储对象类型,不能直接存储基本数据类型。通过自动拆装箱功能,可以方便的在集合中存储基本数据类型的值,而无需手动进行转换。

10. 序列化和反序列化

序列化和反序列化时Java中对象持久化的概念,他们允许将对象转换成字节序列的方式以便存储和传输,以及将字节序列重新转化为对象。

  • 序列化
    1. 序列化(Serialization) 是指将对象的状态转换为字节序列的过程。在Java中实现了 Serializable 接口的类的对象才能被序列化。
    2. 通过使用 ObjectOutputStream 类,可以将一个实现了 Sreializable 接口的对象转换为字节序列,并输出到文件、数据库或网络流中。
      实现代码如下:
import java.io.*;

public class SerializationExample{
    public static void main(String[] args){
        //创建一个对象
        Student student = new Student("Alice", 20);
        
        try{
            //创建一个ObjectOutputStream类序列化对象并写入文件
            FileOutputStream fileOut = new FileOutputStream("student.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            
            //序列化对象
            out.writeObject(sytudent);
            
            //关闭源
            out.close();
            fileOut.close();
            
            System.out.println("对象已经被序列化并写入文件中");
        }catch(IOException e){
            e.printStackTrace();
                        }
    }
}
  • 反序列化
    1. 反序列化(Deserialization) 是指将字节序列转换为对象的过程。在Java中,使用 ObiectInputStream 类可以实现反序列化操作。
    2. 通过 ObjectInputStreamreadObject() 方法,可以从文件、数据库或网络流中读取字节序列,并将其转换为原始的对象。

11. Java中的修饰词有哪些

             在Java中,修饰词用来修饰类、方法、变量等。常见修饰词包括:

  • public: 表示该类、方法或变量时公共的,可以被其它类访问。
  • private: 表示该类、方法或变量是私有的,只能在当前类内部访问。
  • protected: 表示该类、方法或变量对同一包内的类和所有子类可见。
  • static: 表示静态的,可以用来修饰方法、变量和代码块。
  • final: 表示最终的,可以用来修饰类、方法和变量,表示不可更改。
  • abstract: 表示抽象的,用来修饰类和方法,表示不能实例化或需要子类实现。
  • synchronized: 表示同步的,用来修饰方法,确保在多线程环境下方法的安全性。
  • volatile: 表示易变的,用来修饰变量,确保多线程环境下变量的可见性。
  • transient: 表示瞬时的,用来修饰变量,表示不参与序列化。
  • native: 表示本地的,用来修饰方法,表示该方法的实现由本地代码提供。

12. String能被继承吗?为什么用final修饰?

  • 在Java中,String类是一个final类,因此不能被继承。当一个类被声明为final时,意味着他不能有子类,不能被其它类所继承。
  • String类被设计为不可变类,即一旦创建了String对象,其内容就不能被修改。这是通过使用final关键字来修饰String类的方法实现的。通过将String类声明为final,Java确保了String类的不可变性,既避免了String类被子类修改或破坏其不可变特性。
  • 为了确保字符串的安全性和稳定性,将String类声明为final,这样在程序中使用String类不必担心其被子类修改导致的潜在问题。

13. StringBuffer 和 StringBuilder 的区别

       StringBuffer 和 StringBuilder 都是用于处理字符串的类,他们之间的主要区别在于线程安全性和性能。

  • StringBuffer
    1. 线程安全性:StringBuffer 是线程安全的,所有其方法都是同步的,多个线程可以安全的同时访问一个 StringBuffer 对象而不会出现数据混论。
    2. 性能:由于其所有方法都是同步的,这也导致 StringBuffer 的性能相对较低。在多线程环境下,由于需要进行同步处理,可能会导致一些性能开销。
  • StringBuilder
    1. 线程安全性:StringBulider 线程不安全,它的方法并不是同步的,因此在单线程环境下使用StringBuilder更为高级。
    2. 性能:由于没有同步开销,StringBuilder 的性能通常优于 StringBuilder。因此,在单线程环境下,推荐使用 StringBuilder 来处理字符串操作。

14. final, finally, finalize的区别

  • final:用来修饰类、方法和变量。当用final修饰一个类时,表示该类不能被继承;当修饰一个方法时,表示该方法不能被子类重写;当修饰一个变量时,表示该变量是常量,其数值在初始化后不能被改变。
  • finally: 通常用于异常处理的 try-catch-finally 语句块中,无论是否发生异常,finally 块中的代码都会被执行。一般情况下,finally 块用来释放资源,如关闭文件或释放网络连接等操作。
  • finalize: finalize() 是Object类中的一个方法,在Java中的所有类都继承自Object类,因此都可以重写finalize() 方法。finalize() 方法在对象被垃圾回收之前被调用,可以在该方法中进行一些清理工作,如释放非Java资源(文件句柄、数据库连接等)。但由于Java的垃圾回收机制的不确定性,finalize() 方法并不适合用来进行资源释放,推荐使用 try-with-resources 或其他方式来确保资源的及时释放。

15. Object类中有哪些方法?

       常用方法如下:

  • equals(Object obj): 判断当前对象是否与给定对象 obj 相等;
  • hashCode(): 返回当前对象的哈希码值;
  • toString(): 返回当前对象的字符串表示;
  • getClass(): 返回当前对象的运行时类。
  • clone(): 创建并返回当前对象的副本(浅拷贝)。
  • finalize(): 在对象被垃圾回收之前调用,用于进行资源清理等操作。
  • notify(): 唤醒在当前对象上等待的单个线程。
  • notifyAll(): 唤醒在当前对象上等待的所有线程。
  • wait(): 导致当前线程等待,直到另一个线程调用 notify() 或 notifyAll() 方法时才能被唤醒。
  • wait(long timeout): 导致当前线程等待指定的毫秒数,直到另一个线程调用 notify() 或 notifyAll() 方法时才能被唤醒。
  • wait(long timeout, int nanos): 导致当前线程等待指定的毫秒数和纳米数,直到另一个线程调用 notify() 或 notifyAll() 方法时才能被唤醒。
    这些常用的Object类中的方法,其他类可以通过过继承Object类来继承这些方法,也可以重写这些方法满足需求。

16. Java异常处理机制

              异常处理机制主要通过 try-catch-finally 块来实现。基本流程框架如下:

  • 抛出异常:当程序运行发生异常状况时,可以使用 throw 关键字手动抛出一个异常对象。
  • 捕获异常:使用 try-catch 块来捕获可能抛出的异常。在 try 块中放置可能会引发异常的代码,然后在 catch 块中处理异常情况。
  • 处理异常:在 catch 块中可以编写处理异常的代码,比如记录日志、提示用户等。
  • finally块:finally 块中的代码总是被执行,不管是否发生异常。通常用于释放资源或者执行清理操作。
  • 自定义异常:除了Java提供的异常处理机制,也可以根据需求自定义异常类来表示特定的异常情况。
  • 异常处理机制能帮助开发人员更好的管理和处理程序中可能出现的异常情况,保证程序的稳定性和可靠性。

17. throw和throws的区别

  • throw
    • throw用于手动抛出异常。当程序执行到throw语句时,会立即抛出一个异常,并终止当前方法的执行。
    • 使用throw关键字可以在代码中显式地抛出异常,例如在检测到不符合预期的条件时,可以通过throw抛出一个适合的异常对象。
  • throws
    • throws关键字用于声明方法可能抛出的异常类型。当方法可能抛出异常时,可以使用throws在方法声明中列出可能抛出的异常类型,通知调用方法需要处理这些异常。
    • 调用方可以选择捕获方法可能抛出的一场,也可以将异常继续向上抛出。

标签:面试题,java,对象,2024,线程,面向对象编程,Java,拷贝,方法
From: https://www.cnblogs.com/mochen1025/p/18206995

相关文章

  • 揭秘Java反射:如何轻松获取类的属性及父类属性
    哈喽,大家好,我是木头左!相信很多小伙伴在学习Java的过程中,都曾经遇到过需要动态地获取类的属性和方法的场景。而Java反射正是解决这个问题的利器。那么,如何使用Java反射来获取类的属性及父类的属性呢?一、Java反射简介要了解一下Java反射是什么。简单来说,Java反射就是运行时能够......
  • 力扣1542 2024.5.22
    原题网址:此处为链接个人难度评价:1700分析:很惊讶会又在力扣看到区域赛的几乎原题。此题加上一个哈希就是区域赛题目了。回文其实你只需要关注奇偶性。那么你用前缀和,维护[0:i]区间内每个数的奇偶性,此时你可以发现[0:i]和[i:j]的前缀和异或之后,为0的位就说明[i:j]内此位为偶。(也......
  • Java:如何轻松获取当前执行的方法名
    哈喽,大家好,我是木头左!在编程的世界里,经常会遇到各种各样的问题。有时候,需要了解当前执行的方法名,以便更好地调试代码或者记录日志。那么,如何在Java中轻松获取当前执行的方法名呢?本文将为您揭示这个神秘的技巧!一、Java方法的执行上下文在Java中,每个方法都有一个与之关联的执行......
  • Docker openjdk java AES 解密报错
    javaAES解密报错java.security.InvalidKeyException:Illegalkeysizeordefaultparametersatjavax.crypto.Cipher.checkCryptoPerm(Cipher.java:1026)atjavax.crypto.Cipher.implInit(Cipher.java:801)atjavax.crypto.Cipher.chooseProvider(Cipher.java:864)atjavax.c......
  • 【2024.05.22】寄出的是相片,还是我的回忆?
    这段时间一直在朋友写信,太久没写信了曾经我总是觉得照片这种载体会被淘汰,应该会被视频所取代,现在看来不是的想给朋友们一个520惊喜,所以翻了下过去的照片在打印照片的时候却陷入了回忆之中去回想按下快门的那一刻,我是什么状态,那段时间在做什么想什么或许这就是最美好的感情吧,......
  • Java RMI遇到的Connection refused to Host: 127.x.x.x/192.x.x.x/10.x.x.x问题解决方
    问题故障解决记录--JavaRMIConnectionrefusedtohost:x.x.x.x....在学习JavaRMI时,我遇到了以下情况问题原因:可能大家的host是10或者192的私有地址,我估计都是和我一样的一个原因:/etc/hosts文件的配置问题(我是ubuntu系统下的实验环境),也就是主机名称和IP地址的映射关系......
  • 2024年度 OKR 最佳平台: Tita OKR 软件
    当公司开始使用“目标和关键结果(OKR)”时,它们便像大多数公司一样开始使用手动跟踪方法,例如Excel,Google表格,PowerPoint和其他手动过程。通过使用这些类型的实践,可以手动创建,更新OKR,并通过电子邮件,企业微信,钉钉和其他各种通信渠道进行共享。 不幸的是,当组织开始深入了解OKR方法......
  • 04 Java8新特性
    一函数式编程函数式编程是把动作作为参数对象传给调用的方法。@TestpublicvoidtestAddThen(){List<Integer>list=Arrays.asList(3,1);List<Integer>collect=list.stream()//map的入参是Function类型对象......
  • 2024年5月中国数据库排行榜:OP持续领跑,GoldenDB稳步上升进前八
    入夏时节,2024年5月的中国流行度排行榜排行榜如期发布。在这个骄阳似火的季节,各大数据库产品之间的竞争愈发激烈,名次间的细微变动展示了市场的动态和活力。各家厂商不断创新,通过技术升级和性能优化,力求在激烈的市场中占据更有利的位置。本月排行榜主要呈现以下几个特点:榜单产品......
  • 2024-2030数据集成成熟度曲线(一)
    作者|郭炜导读:最新发布的《技术成熟度曲线2024》全面评估数据集成技术架构的7个维度,包括技术成熟度、技术难度、业务价值、技术成熟周期、管理协作难度、大模型结合等评估维度,报告篇幅较长,我们将报告分为3篇系列文章,本文为报告第一篇,描述了「从ETL到ELT,到EtLT的趋势」。接......