JAVA后端开发面经2

本文详细解读了Java编程中的关键概念,包括`=`和`equals`的区别、静态变量与实例变量的差异、静态方法与非静态方法调用、Integer与int的区别、构造器重载与重写、接口继承等,帮助开发者避免常见陷阱并提高理解深度。
摘要由CSDN通过智能技术生成

​面经来源于github上的

Java-Interview

在学习时,用自己的语言解释​

11."=="和equals方法究竟有什么区别?

  • ==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。
  • equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。

简单来说:==是比较两个首地址是否相同,equals是比较两个地址中存放的数值是否相同

在实际开发中,我们经常要比较传递进行来的字符串内容是否等,例如,String input = input.equals(“quit”),许多人稍不注意就使用==进行比较了,这是错误的,随便从网上找几个项目实战的教学视频看看,里面就有大量这样的错误。记住,字符串的比较基本上都是使用equals方法。

这说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object 类继承的)就是使用==操作符,也是在比较两个变量指向的对象是否是同一对象,这时候使用equals和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回false。

 

12.静态变量和实例变量的区别?

在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。

在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量。静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来引用。

通俗来说:例如,新建一个JAVA程序时

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

都会有一个默认新建的static,这个就是整个项目的启动类,新建的时候就会由于静态变量,给默认这个项目分配空间。其余的对象是创建是实现你的项目功能的,就在这个分配的空间中进行实现。

例如,对于下面的程序,无论创建多少个实例对象,永远都只分配了一个staticVar变量,并且每创建一个实例对象,这个staticVar就会加1;但是,每创建一个实例对象,就会分配一个instanceVar,即可能分配多个instanceVar,并且每个instanceVar的值都只自加了1次。

public class VariantTest {
    public static int staticVar = 0;
    public int instanceVar = 0;
​
    public VariantTest() {
        staticVar++;
        instanceVar++;
        System.out.println("staticVar=" + staticVar + ",instanceVar=" + instanceVar);
    }
}

 

13.是否可以从一个static方法内部发出对非static方法的调用?

不可以。

因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而static方法调用时不需要创建对象,可以直接调用。也就是说,当一个static方法被调用时,可能还没有创建任何实例对象,如果从一个static方法中发出对非static方法的调用,那个非static方法是关联到哪个对象上的呢?这个逻辑无法成立,所以,一个static方法内部发出对非static方法的调用。

看过第十二点,这点不难想到。连static空间都还没有建立,怎么去调用它空间里面的方法,那么假设可以调用方法,那调用的方法也不会是这个static中的

14.Integer与int的区别

int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的情况,例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer。

如果做过项目的友友也清楚,在项目中的数据库设置中,int和Integer不对应会有报错。

图来自MySQL中的字段类型对应于Java对象中的数据类型

 

e91df77a52714f099301a77f2a03702f.png

 

0a6fa1f96e854abd8efcdd1256d898b0.png

 

15.Math.round(11.5)等于多少? Math.round(-11.5)等于多少?

round方法,它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11。

 

16.请说出作用域public,private,protected,以及不写时的区别

这四个作用域的可见范围如下表所示。

说明:如果在修饰的元素上面没有写任何访问修饰符,则表示friendly。

作用域当前类同一package子孙类其他package
public
protected×
friendly××
private×××

备注:只要记住了有4种访问权限,4个访问范围,然后将全选和范围在水平和垂直方向上分别按排从小到大或从大到小的顺序排列,就很容易画出上面的图了。

其他package:也就是其他文件夹能不能调用这个文件夹的功能

子孙类:也就是能不能继承

同一package:也就是本文件夹能不能调用这个文件夹的功能

 

17.Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?

Overload是重载的意思,Override是覆盖的意思,也就是重写。、

Override大概很多人都知道是什么,但是Overload是什么?

这里我们看一下菜鸟教程是怎么说的:Java 重写(Override)与重载(Overload)

  • 重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
  • 每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
  • 最常用的地方就是构造器的重载。

如果不明白的话,再看一下代码:

可以发现,方法名字都叫做test()

但是参数不同,返回类型有些同有些不同。

如果说有什么用处的话,其实也就是这个类,为调用它的方法提供了更多方法路径,任君选择的感觉。

public class Overloading {
    public int test(){
        System.out.println("test1");
        return 1;
    }
 
    public void test(int a){
        System.out.println("test2");
    }   
 
    //以下两个参数类型顺序不同
    public String test(int a,String s){
        System.out.println("test3");
        return "returntest3";
    }   
 
    public String test(String s,int a){
        System.out.println("test4");
        return "returntest4";
    }   
 
    public static void main(String[] args){
        Overloading o = new Overloading();
        System.out.println(o.test());
        o.test(1);
        System.out.println(o.test(1,"test3"));
        System.out.println(o.test("test4",1));
    }
}

 

18.构造器Constructor是否可被override?

构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload。

解释一下:构造器(Constructor)不能被继承的原因主要是因为构造器的主要目的是用于初始化一个新创建的对象。在面向对象编程中,每个类都有自己的特定属性和行为,这些属性和行为是通过类的构造器来初始化的。如果可以继承

 

  • 违反封装原则:封装原则要求隐藏对象的内部状态,并防止对象的状态被随意修改。如果子类可以继承父类的构造器,那么子类将能够访问和修改父类的私有属性和方法,这会破坏封装原则。
  • 违反单一职责原则:单一职责原则要求每个类应该只有一个职责。如果子类可以继承父类的构造器,那么子类可能会被迫承担父类的职责,这会导致子类变得复杂和混乱。

 

19.接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)? 抽象类中是否可以有静态的main方法?

接口可以继承接口。抽象类可以实现(implements)接口,抽象类可以继承具体类。抽象类中可以有静态的main方法。

只有记住抽象类与普通类的唯一区别就是不能创建实例对象和允许有abstract方法。

举个栗子:把抽象类比作父类,普通类比作子类。那么父子都可以使用工具(implements)接口,

但是子类继承父类时,也就是继承抽象方法的子类必须重写该方法,才能去实现。否则,该子类也必须声明为抽象类。

 

20.写clone()方法时,通常都有一行代码,是什么?

clone 有缺省行为,super.clone();因为首先要把父类中的成员复制到位,然后才是复制自己的成员。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值