JavaSE阶段面试题(一)

目录

1.int a = 1, int b = 1, Integer c = 1, Integer d = 1;四个区别和联系,以及c和d是同一个吗?

2.为什么重写HashCode必须重写euqals,两者之间的关系?

3.创建对象的方式有哪些

4.重写和重载的区别

5.抽象类和接口的区别

6.String的不可变原则

7.浅拷贝和深拷贝


本专栏全是博主自己收集的面试题,仅可参考,不能相信面试官就出这种题目。

       

1.int a = 1, int b = 1, Integer c = 1, Integer d = 1;四个区别和联系,以及c和d是同一个吗?

   a 和 b 是基本数据类型 int 的 变量,它们直接存储在栈(stack)上,并且每个变量都有自己的存储空间。

        c 和 d 是 Integer 类型的 对象,它们存储在堆(heap)上,。多个 Integer 对象被创建并且它们的值相同,Java 可能会使它们引用相同的对象,从而节省内存。因此cd 可能会引用相同的 Integer 对象。所以可能是同一个

联系c 和 d 都是通过自动装箱从基本数据类型 int 转换而来的 Integer 对象。

区别:a、b是变量,存储在栈上;c和d是对象,是Integer类的实例,可以调用方法。

2.为什么重写HashCode必须重写euqals,两者之间的关系?

        解答问题之前,回忆一下,什么是HashCode和equals,及其作用

        HashCode是在Java中用于获取对象的唯一标识符的方法。它是根据对象的内容生成的一个整数值。对象的hashCode()方法被调用时,它返回的是对象内存地址的哈希码。哈希码可以用于在哈希表等数据结构中快速定位对象

注意点:

  1. 每一次运行对象内容即使一致,但hash值不一定一致
  2. 运行过程里,new的两个对象,内容相等 ≠ 哈希码相等
  3. 不同的对象可能会生成相同的哈希码,概率极低

那么为什么需要重写hashcode呢?

我也不太清楚,但是重写hashcode可以让两个内容相同的对象拥有同一个哈希码

例子:

public class Student {
    int age;
    String sex;
    String name;
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + this.age;
        result = prime * result + (this.sex == null ? 0 : this.sex.hashCode());
        result = prime * result + (this.name == null ? 0 : this.name.hashCode());
        return result;
    }

        在回忆一下equals,在Java中,equals() 方法被设计用来比较对象的用于比较对象的内容或状态是否相等!

        因此,疑问出来了,既然equals()方法比较的是内容或状态,那么是否hashCode()值相等,两个对象通过 equals() 方法被认为是相等吗?

解析:

        在 Java 中,当我们重写 hashCode() 方法时,通常需要同时重写 equals() 方法,这是为了维护 hashCode()equals() 方法之间的协定,确保对象在集合(如哈希表)中正确地工作。

  1. hashCode() 值相等

    • 如果两个对象的 hashCode() 值相等,那么根据 Java 的约定,这是 equals() 方法返回 true 的必要条件。也就是说,如果两个对象通过 equals() 方法相等,它们的 hashCode() 值必须相等。
  2. hashCode() 值不相等

    • 如果两个对象的 hashCode() 值不相等,那么按照 Java 的规定,这两个对象不应该通过 equals() 方法返回 true。即使 equals() 方法返回 true,也会违反 hashCode() 方法的契约,这可能导致在使用哈希集合(如 HashMapHashSet 等)时出现不一致的行为,甚至会导致数据结构的错误操作。

总结:HashCode()方法,HashCode方法通过内容一致得出相同的哈希码

           equals()方法,通过内容判断对象是否相同。

概述:一个类有三个属性,原本只通过一个属性重写了hashcode()和equals()方法,但是我将hashcode()方法,通过2个属性得出该对象的哈希值,可equals()方法还是根据一个属性判断,这并不安全,也会出现bug。

3.创建对象的方式有哪些

一般有5种:

第一种:常见的使用构造方法new对象

第二种:使用工厂设计模型,根据你需要的,自动创建出来。

// 定义汽车类
class Car {
    private String model;
    private int year;

    public Car(String model, int year) {
        this.model = model;
        this.year = year;
    }

    // 省略 getter 和 setter 方法
}

// 定义汽车工厂类
class CarFactory {
    // 工厂方法,根据型号和年份创建汽车对象
    public static Car createCar(String model, int year) {
        //----- 判断条件 -----
        return new Car(model, year);
    }
}

// 在主程序中使用工厂方法创建对象
public class Main {
    public static void main(String[] args) {
        // 使用工厂方法创建汽车对象
        Car myCar = CarFactory.createCar("Toyota Camry", 2023);
    }
}

第三种:克隆

克隆又分两种,一种浅克隆、一种深克隆,使用接口Cloneable和方法clone()

区别在于一个类中如果含有其他类,那么浅克隆,只能克隆表面,包含的类无法克隆,反之,深克隆可以做到!

class Teacher  implements Cloneable{
    private String name;
    private  int age;
    private Student student;
}
public class Test1 {

    public static void Shallow_cloning(){
        Teacher teacher = new Teacher();
        teacher.setAge(19);
        teacher.setName("李华");
        Student student = new Student();
        student.setName("喜喜");
        teacher.setStudent(student);

        Teacher teacher1 = teacher.clone();
}

第四种:通过反射

        反射机制允许在运行时检查类的信息,并动态地创建类的对象,可以调用类的构造方法来实现对象的创建

Class<?> clazz = Class.forName("指定的被反射的类");
类名 obj = (类名) clazz.getDeclaredConstructor().newInstance();

第五种:反序列化

        通过反序列化可以从存储设备(如文件、数据库)中读取对象的字节流,并将其转换回对象

ObjectInputStream in = new ObjectInputStream(new FileInputStream("文件名"));
MyClass obj = (MyClass) in.readObject();

4.重写和重载的区别

        重写:在面向对象的继承中,子类可以通过重写父类的方法来实现自己的版本。重写指的是子类定义了一个与父类中相同名称和参数列表(签名)的方法,并且返回类型和抛出的异常类型也必须与父类中的方法一致。重写的方法需要加上 @Override 注解(可选),这样可以让编译器帮助检查是否正确地重写了父类的方法

        重载:重载是指在同一个类中,可以定义多个方法名相同但参数列表不同(包括参数类型、参数个数或参数顺序)的方法。重载的方法彼此之间的签名必须不同,返回类型可以不同,但通常情况下只有返回类型不同是不够的。

总结

  • 重写发生在子类继承父类的过程中,用于实现多态性,要求方法签名相同。
  • 重载发生在同一个类中,用于提供多个同名方法以应对不同的参数情况,要求方法签名不同。

5.抽象类和接口的区别

抽象类:不能被实例化,都是被继承使用,可以有抽象方法(没有具体实现的方法),也可有具体的实现方法,可以有构造方法,被子类调用。

接口:定义了一组没有具体实现的方法,一个类可以实现多个接口,

  • 接口中的方法默认是 public abstract 的,属性默认是 public static final 的(Java 8 之后接口中可以有默认方法和静态方法)。
  • 类通过 implements 关键字来实现接口,并提供接口中定义的所有方法的具体实现。

6.String的不可变原则

        在Java中,String 类被设计为不可变的。有人说,我一开始让String类型指向"abc",然后再指向"wer" 不是发生了改变吗?

        不不不,实际上是创建了一个新的字符串对象,而不是修改原来的对象。旧的字符串对象将被Java的垃圾回收机制清理掉。

为什么是不可变的呢?

 线程安全角度:字符串不可变性确保了字符串对象在多线程环境下是安全的,不需要额外的同步操作。因为字符串一旦创建,它的值不会改变,所以不会出现多个线程同时修改一个字符串对象的情况。

哈希值:字符串被广泛用作 HashMap 和 HashSet 的键。由于字符串不可变,可以安全地缓存它们的哈希值,提高了哈希表的性能。

安全敏感操作:在安全敏感的环境中,不可变字符串确保了关键信息(如密码)不会被意外修改。

或许有人说,如果需要频繁更改,岂不是很麻烦!

不不不,因为字符串池(String Pool)存在。字符串池是一种特殊的内存区域,用于存储字面量字符串,以便多个字符串引用可以共享相同的实例,从而节省内存。

7.浅拷贝和深拷贝

        之前我们在描述创建对象的时候,以及提及到了浅拷贝和深拷贝

拷贝:将一组数据原封不动的转移到另容器。

例如:字符串拷贝和数组拷贝

String original = "Hello";
String copied = new String(original);

String original = "Hello";
String copied = original.substring(0); // 从索引0开始,复制到字符串末尾

int[] original = {1, 2, 3, 4, 5};
int[] copied = original.clone();  //用数组的 clone() 方法

但是对象也是一组数据,因此也可以拷贝

浅拷贝:通过对象实现了 Cloneable 接口,重写clone()方法

class Teacher2  implements Cloneable{
    private String name;
    private  int age;
    @Override
    protected Teacher2 clone(){
        Teacher2 t1 = null;
        try {
            t1 = (Teacher2) super.clone();
            // 克隆引用类型
            t1.setStudent(t1.getStudent().clone());
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
        return t1;
    }
}
 public static void Shallow_cloning(){
        Teacher2 teacher = new Teacher();
        teacher.setAge(19);
        teacher.setName("李华");
        //克隆
        Teacher2 teacher1 = teacher.clone();
}

而所谓的深克隆就是针对一种类的有其他对象的存在,例如:

class Teacher  implements Cloneable{
    private String name;
    private  int age;
    private Student student;   //存在一个对象Student

}

这种情况下,即使克隆,其中的student还是原来的,只是共享了数据。

解决方法有三种:

  1. 所有引用属性都实现克隆,整个对象就变成了深克隆。
  2. 使用 JDK 自带的字节流序列化和反序列化对象实现深克隆。(略)
  3. 使用第三方工具实现深克隆,比如 Apache Commons Lang 库。(略)

引用属性都实现克隆方法:

public class CloneDemo {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setName("张三");
        p1.setAge(18);
        // 引用类型
        Address address = new Address();
        address.setCity("北京");
        p1.setAddress(address);
        // 克隆 p1 对象
        Person p2 = p1.clone();
        // 对比引用类型的地址值是否相同
        System.out.println(p1.getAddress() == p2.getAddress()); // false
    }
}

@Getter
@Setter
class Person implements Cloneable {
    private String name;
    private int age;
    private Address address; // 引用类型

    @Override
    public Person clone() {
        Person person = null;
        try {
            person = (Person) super.clone();
            // 克隆引用类型
            person.setAddress(person.getAddress().clone());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return person;
    }
}

@Getter
@Setter
class Address implements Cloneable {
    private String city;

    @Override
    public Address clone() {
        Address address = null;
        try {
            address = (Address) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return address;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/768245.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

firewalld(6)自定义services、ipset

简介 在前面的文章中我们已经介绍了zone、rich rule 、--direct等功能和基本配置。在前面文章中&#xff0c;我们提到过firewalld内置了很多服务&#xff0c;可以通过firewall-cmd --get-services来查看服务&#xff0c;也可以通过配置文件查看这些服务/var/lib/firewalld/ser…

汽车IVI中控开发入门及进阶(三十三):i.MX linux开发之开发板

前言: 大部分物料/芯片,不管MCU 还是SoC,都会有原厂提供配套开发板,有这样一个使用原型,在遇到问题时或者进行开发时可以使用。 i.MX 8QuadXPlus MEK board: 1、要测试display显示器,可使用i.MX mini SAS将“LVDS1_CH0”端口连接到LVDS到HDMI适配器的cable。 2、要测试…

12. Revit API: Document、Element

12. Revit API: Document、Element 前言 还是先讲一下Document吧&#xff0c;不然Selection不好讲&#xff0c;那涉及到了挺多东西的&#xff0c;比元素&#xff08;Element&#xff09;和各类Filter&#xff0c;这些都与Document有关&#xff0c;所以先简单讲一下这个。 一、…

解码AWS EC2:塑造云服务器新标杆的五大核心优势

在云计算领域&#xff0c;亚马逊弹性计算云&#xff08;Amazon Elastic Compute Cloud, 简称EC2&#xff09;作为AWS的明星服务&#xff0c;凭借其卓越的性能、灵活性和广泛的生态系统&#xff0c;已经成为企业构建云上基础设施的首选。EC2不仅仅是一个简单的云服务器租用服务&…

【C++】多态详解

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 一、多态概念 二、多态的定义及实现 1. 多态的构成条件 2. 虚函数 2.1 什么是虚函数 2.2 虚函数的重写 2.3 虚函数重写的两个…

【坚果识别】果实识别+图像识别系统+Python+计算机课设+人工智能课设+卷积算法

一、介绍 坚果识别系统&#xff0c;使用Python语言进行开发&#xff0c;通过TensorFlow搭建卷积神经网络算法模型&#xff0c;对10种坚果果实&#xff08;‘杏仁’, ‘巴西坚果’, ‘腰果’, ‘椰子’, ‘榛子’, ‘夏威夷果’, ‘山核桃’, ‘松子’, ‘开心果’, ‘核桃’&a…

C++基础(三):C++入门(二)

上一篇博客我们正式进入C的学习&#xff0c;这一篇博客我们继续学习C入门的基础内容&#xff0c;一定要学好入门阶段的内容&#xff0c;这是后续学习C的基础&#xff0c;方便我们后续更加容易的理解C。 目录 一、内联函数 1.0 产生的原因 1.1 概念 1.2 特性 1.3 面试题 …

nohup java -jar 启动java项目

hi&#xff0c;我是程序员王也&#xff0c;一个资深Java开发工程师&#xff0c;平时十分热衷于技术副业变现和各种搞钱项目的程序员~&#xff0c;如果你也是&#xff0c;可以一起交流交流。 今天我们聊聊linux中运行java jar包的问题~ 理解nohup命令 nohup命令的基本概念 noh…

Flutter Navigator.popUntil 参数传递

Flutter 使用页面传参 以下是 在flutter 中页面传参的常用形式&#xff0c;都可以有有直接的传值参数提供。 Navigator.push #跳转到指定页面 压栈路由表Navigator.pushReplacement #关闭当前页面 跳转到指定页面压栈路由表Navigator.pus…

[单master节点k8s部署]16.监控系统构建(一)Prometheus介绍

prometheus prometheus是继k8s之后&#xff0c;第二个被托管到CNCF的项目&#xff0c;是一个开源的监控报警系统。 1.prometheus支持多维数据模型&#xff0c;每一个时间序列数据都由metric度量指标名称和它的标签label组成一组键值对。 2.Prometheus有自己的PromQL查询语言…

【刷题汇总--简写单词、dd爱框框、除2!】

C日常刷题积累 今日刷题汇总 - day0031、简写单词1.1、题目1.2、思路1.3、程序实现 - 思路11.4、程序实现 - 思路2(优化) 2、dd爱框框2.1、题目2.2、思路2.3、程序实现 - 蛮力法2.4、程序实现 - 同向双指针(滑动窗口) 3、除2!3.1、题目3.2、思路3.3、程序实现 4、题目链接 今日…

Trident Dehazing Network

Trident去雾网络 【Trident&#xff1a;三齿的&#xff0c;三叉戟】 摘要 针对现有的去雾方法对非均匀雾霾的鲁棒性差&#xff0c;以及高雾霾区域的信息未知且难以估计&#xff0c;导致去雾效果模糊的问题&#xff0c;提出了一种由粗到精的模型Trident Dehazing Network&…

基于iview.viewUI实现行合并(无限制/有限制合并)【已验证可正常运行】

1.基于iview.viewUI实现行合并&#xff08;列之间没有所属对应关系&#xff0c;正常合并&#xff09; 注&#xff1a;以下代码来自于GPT4o&#xff1a;国内直连GPT4o 只需要修改以下要合并的列字段&#xff0c;就可以方便使用啦 mergeFields: [majorNo, devNam, overhaulAdvic…

查找python包的安装路径

前提&#xff1a;自己已经安装过的包 1、打开任一python解析器&#xff0c;如VSCode 2、 以matplotlib为例&#xff0c;敲下面命令 import matplotlibprint(matplotlib.path) 3、运行代码就可以了 需要注意&#xff1a; 部分包没有path&#xff08;比如time&#xff09;&am…

使用 Java Swing 和 XChart 创建多种图表

在现代应用程序开发中&#xff0c;数据可视化是一个关键部分。本文将介绍如何使用 Java Swing 和 XChart 库创建各种类型的图表。XChart 是一个轻量级的图表库&#xff0c;支持多种类型的图表&#xff0c;非常适合在 Java 应用中进行快速的图表绘制。 1、环境配置 在开始之前&…

ElementUI中的el-table解决宽度问题 - 根据内容自动撑开

在使用element-ui中&#xff0c;会发现表格组件el-table在未指定宽度情况下&#xff0c;会自动计算并给表格宽度赋值。但实际开发中&#xff0c;有时需要根据内容实际长度自动撑开显示&#xff0c;由内容的多少而决定表格的宽度&#xff0c;而不是默认宽度为100%。在默认情况下…

韩语日常口语留学韩语旅游韩语口语柯桥语言培训

韩语每日一词打卡&#xff1a;행정적[행정적]【名词】行政 原文:나라는 항상 행정적 명령을 통해 경제운행을 조절합니다. 意思&#xff1a;国家经常通过行政命令去调节经济的运行。 【原文分解】 1、항상[항상]总是 &#xff0c;经常 2、나라[나라]国家 3、명령[명:녕]命令 …

计算机网络——数据链路层(点对点协议PPP)

点对点协议PPP的概述 对于点对点的链路&#xff0c;目前使用得最广泛的数据链路层协议是点对点协议 PPP (Point-to-Point Protocol)。 它主要应用于两个场景&#xff1a; 用户计算机与ISP之间的链路层协议就是点对点协议 PPP&#xff0c;1999年公布了回以在以太网上运行的PPP协…

JAVA每日作业day7.1-7.3小总结

ok了家人们前几天学了一些知识&#xff0c;接下来一起看看吧 一.API Java 的 API &#xff08; API: Application( 应用 ) Programming( 程序 ) Interface(接口 ) &#xff09; Java API 就是 JDK 中提供给我们使用的类&#xff0c;这些类将底层 的代码实现封装了起来&#x…

10 docker 安装 mysql详解

目录 一、安装mysql 1. 镜像获取 2. 简单版 2.1. 使用mysql镜像 2.2. 建库建表插入数据 2.3. 外部win 连接并插入中文数据测试 2.4. 简单版本问题 3. 创建容器-实战版 3.1. 新建容器实列并挂载卷 3.2. 新建my.cnf , 解决中文乱码 3.3. 重启容器验证 3.4. 总结 一、…