首页 > 编程语言 >今日一学,5道Java基础面试题(附Java面试题及答案整理)

今日一学,5道Java基础面试题(附Java面试题及答案整理)

时间:2024-10-14 22:10:51浏览次数:1  
标签:面试题 一学 int equals 哈希 Integer println Java public

前言

马上国庆了,本来想着给自己放松一下,刷刷博客,慕然回首,自动拆装箱?equals?==?HashCode? instanceof? 似乎有点模糊了,那就大概看一下5道Java基础面试题吧。好记性不如烂键盘~

*** 12万字的java面试题整理 ***

instanceof 关键字的作用

instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为:

if (object instanceof Json) {
	Json json = (Json)object;
}

其中 object 为一个对象,Json表示一个类或者一个接口,当 object 为 Json的对象,或者是其直接
或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。
注意:编译器会检查 object 是否能转换成右边的Json类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定。

nt i = 0;
System.out.println(i instanceof Integer);//编译不通过 i必须是引用类型,不能是基本类型
System.out.println(i instanceof Object);//编译不通过
Integer integer = new Integer(1);
System.out.println(integer instanceof Integer);//true
System.out.println(null instanceof Object);//false ,在 JavaSE规范 中对 instanceof 运算符的规定就是:如果 obj 为 null,那么将返回 false。

Java自动装箱与拆箱

装箱就是自动将基本数据类型转换为包装器类型(int-->Integer);调用方法:Integer的
valueOf(int) 方法

拆箱就是自动将包装器类型转换为基本数据类型(Integer-->int)。调用方法:Integer的
intValue方

为什么会需要这功能呢?
在Java SE5之前,如果要生成一个数值为100的Integer对象,必须这样进行:

Integer i = new Integer(100);

而在从Java SE5开始就提供了自动装箱的特性,如果要生成一个数值为100的Integer对象,只需要这样就可以了:

Integer i = 100

面试题1:以下代码会输出什么?

public class Main {
	public static void main(String[] args) {
		Integer i1 = 100;
		Integer i2 = 100;
		Integer i3 = 200;
		Integer i4 = 200;
		System.out.println(i1==i2);
		System.out.println(i3==i4);
	}
}
true
false

为什么会出现这样的结果?时只需一看源码便知究竟

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
  		}
private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

从这2段代码可以看出问题了吗?第一段代码,if判断,true拿缓存,false就new一个,是不是很熟悉

面试题2:以下代码输出什么

public class Main {
	public static void main(String[] args) {
		Double i1 = 100.0;
		Double i2 = 100.0;
		Double i3 = 200.0;
		Double i4 = 200.0;
		System.out.println(i1==i2); // false
		System.out.println(i3==i4); // false
	}
}

在某个范围内的整型数值的个数是有限的,而浮点数却没有,本身没做这数值的缓存

equals与==的区别

首先,先看定义

  • == 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作
public static void main(String[] args) {
		System.out.println(10L == 10); // true
		}

当你使用 == 操作符比较这两个值时,Java会自动进行类型提升,将较小的数据类型(这里是 int)转换为较大的数据类型(这里是 long),以便进行比较。

  • equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话(String就是很好的例子),调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断,
public class Object {
	public boolean equals(Object obj) {
	        return (this == obj);
	    }
}
public class String{
	public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
}

Hashcode的作用

在Java中,集合框架主要分为两大类:List 和 Set。List 是有序且允许重复元素的集合,而 Set 则是无序且不允许重复元素的集合。
当我们向 Set 中插入元素时,需要确保该元素之前没有被添加过。这通常通过调用元素的 equals 方法来实现。然而,当集合中的元素数量非常大时,直接使用 equals 方法进行逐个比较会变得效率低下
为了解决这个问题,引入了哈希算法。哈希算法能够提高查找、插入和删除操作的效率。每个对象都有一个 hashCode 方法,该方法返回一个整数值,这个值被称为哈希码。哈希码用于确定对象应该存储在集合内部的哪个位置(也称为桶或槽)。具体来说,哈希码可以用来快速定位到可能包含该对象的存储区域
在实际操作中,当尝试向 Set 添加新元素时,首先计算该元素的哈希码,并根据哈希码找到对应的存储区域。如果该区域为空,则可以直接将新元素存入;如果该区域已包含其他元素,那么就需要进一步调用 equals 方法来确认这些元素是否与新元素相同。只有当 equals 方法返回 false 时,才会将新元素存入集合中(这里面就涉及到另一个面试题,hashcode相等的对象是否相等)。
通过这种方式,哈希码减少了直接使用 equals 方法进行比较的次数,从而大大提高了性能。理想情况下,即使集合中有很多元素,查找特定元素的操作也可以接近常数时间复杂度 O(1)。

需要注意的是,为了保证哈希表的高效运行,hashCode 方法的实现必须满足以下条件:

  • 相等的对象必须具有相等的哈希码(即如果 x.equals(y) 返回 true,那么 x.hashCode() 必须等于 y.hashCode())。(hashcode相等的对象是否相等)
  • 不相等的对象最好拥有不同的哈希码,以减少碰撞(不同对象具有相同的哈希码的情况),尽管这是不可能完全避免的。

因此,正确地重写 equals 和 hashCode 方法对于自定义类型的对象是非常重要的,这样可以确保它们能够在基于哈希的集合中正确工作。

重载和重写的区别

  1. 重载(Overloading)
    • 定义:在同一个类中,允许存在多个方法名相同但参数列表不同的方法。
    • 目的:提供一种方式来执行相似功能的方法,但是针对不同类型的输入或数量的参数。
public class Calculator {
    public int add(int a, int b) { return a + b; }
    public double add(double a, double b) { return a + b; } // 重载
}
  1. 重写(Overriding)
    • 定义:子类重新定义从父类继承下来的方法,以实现特定的行为。
    • 目的:当子类认为父类的方法不能满足需求时,可以覆盖该方法以实现新的行为,子类方法的访问级别不能比父类更严格(例如,如果父类方法是 public,那么子类方法也必须是 public),如果父类方法被声明为 final 或 private,则子类无法重写这些方法,使用 @Override 注解可以帮助编译器检查是否正确实现了重写
class Animal {
    public void sound() {
        System.out.println("Some generic animal sound");
    }
}

class Dog extends Animal {
    @Override
    public void sound() { // 重写
        System.out.println("Bark");
    }
}

标签:面试题,一学,int,equals,哈希,Integer,println,Java,public
From: https://www.cnblogs.com/xswz/p/18466305

相关文章

  • JavaScript 代码能够成功进行树摇(Tree Shaking),代码规范
    要确保JavaScript代码能够成功进行树摇(TreeShaking),你可以遵循以下几个实践:1.使用ES6模块树摇主要依赖于ES6的模块语法(import和export)。确保你的代码使用这种模块系统,而不是CommonJS的require和module.exports。//正确的ES6模块语法exportconstfoo=()......
  • Java二维数组
    Java中的二维数组是一个存储多个一维数组的数组。它可以被看作是一个表格或者矩阵。声明一个二维数组的方法如下:dataType[][]arrayName;其中,dataType是指定数组元素类型的数据类型,arrayName是数组的名称。初始化二维数组的方法有两种:指定数组的大小,并逐个赋值:dataType......
  • Javaweb之SpringBootWeb案例之 登录功能的详细解析
     1.登录功能1.1需求编辑在登录界面中,我们可以输入用户的用户名以及密码,然后点击"登录"按钮就要请求服务器,服务端判断用户输入的用户名或者密码是否正确。如果正确,则返回成功结果,前端跳转至系统首页面。1.2接口文档我们参照接口文档来开发登录功能基本信息请求路径:/login请......
  • java中,深克隆和浅克隆怎么用,有什么应用场景?-----面试题分享
    在Java中,对象的克隆可以分为浅克隆(ShallowClone)和深克隆(DeepClone)。这两种克隆方式的主要区别在于它们如何处理对象内部的引用类型字段。浅克隆(ShallowClone)定义:浅克隆创建一个新对象,然后将原始对象中的非静态字段复制到新对象中。如果字段是基本类型,则直接复制其值;如......
  • Java基础语法-变量,常量,作用域
    变量、常量、作用域变量是什么:就是可以变化的量。Java是一种强类型语言,每个变量都必须声明其类型。Java变量是程序中最基本的存储单元。其要素包括变量名,变量类型和作用域。typevarName[=value][{,varName[=value]}];//数据类型 变量名=值;可以使用逗号隔开来声明多个同......
  • 乱七八糟的java static知识(建议不要看)
    static变量(静态变量)静态变量是被static关键字声明的类变量,它们属于类而不是类的实例。特点:所有实例共享同一个静态变量。在类加载时初始化,且在程序运行期间始终存在。示例:publicclassCounter{//静态变量privatestaticintcount=0;//构造函数publicCounter()......
  • java多线程基础知识速通
     1.线程和进程的区别进程是正在运行的程序实例,每个进程包含了多个线程,每个现场执行不同的任务进程都有自己的内存空间,而一个进程下的线程们则是共享内存空间线程更加轻量,线程上下文切换的成本远低于进程上下文切换的成本 2.并行与并发的区别并行是多核CPU一般执行相应个......
  • JAVA中的Xms、Xmx、MetaspaceSize、MaxMetaspaceSize都是什么意思?
    原文链接:JAVA中的Xms、Xmx、MetaspaceSize、MaxMetaspaceSize都是什么意思?–每天进步一点点(longkui.site)某天需要修改一个web服务器的配置文件,看到了下面这样一行配置JAVA_OPTS="-Xms64m-Xmx512m-XX:MetaspaceSize=64M-XX:MaxMetaspaceSize=512m-Djava.net.preferIPv......
  • JavaScript中的对象,常用内置对象和数据类型
    一、对象1.概念什么是对象?在JavaScript中,对象是一组无序的相关属性和方法集合,所有的事物都是对象,例如:字符串、数值、数组和函数等等。对象是由属性和方法组成的。属性:事物的特征,在对象中属性来表示(常用名词)方法:事物的行为,在对象中用方法来表示(常用动词)手机: 属性—......
  • vue-java分享源码基于Spring Boot框架的学生作业课程管理系统的设计与实现
    目录功能和技术介绍系统实现截图本项目源码获取地址下载开发核心技术介绍:为什么选择最新的Vue与SpringBoot技术核心代码部分展示功能和技术介绍SpringBoot和Vue作为当前主流的技术框架,具有开发效率高、安全性强、用户体验良好等优点。使用开源的SpringBoot框架进行......