Java面试题总结

Java基础

1.请描述你理解的数据类型

数据类型分为基本数据类型和引用数据类型

基本数据类型有八种,有byte,short,int,long,float,double,char,boolean

  • 其中byte到double的取值范围依次增加,并且从取值范围小的类型可以隐式转换为取值范围大的类型但是从取值范围大的类型转换为取值范围小的类型需要强制类型转换,在强制类型转换过程中会出现精度的损失。

  • byte,int,char之间的转换是以int为中间桥梁进行转换的,例如byte转为char不能直接转为char类型,需先将byte类型转换为int,再转换为char

  • 在java中默认整数类型为int型,浮点数类型为double型

引用数据类型主要有类,接口,数组,枚举等

2.地址传递和值传递的区别

地址传递通过改变地址从而实现数据的传递,发生在jvm的堆中

值传递只会改变数值的大小并不会改变地址,发生在jvm的栈中

3.前置++和后置++的区别

前置++是先进行+1操作再执行后续操作

后续++是先执行具体操作再进行+1

4.逻辑运算符&&和&的区别

&&(短路与)其在前面的判断是false时就不会再去判断后面的语句而&会在判断完前面的为false后还会去判断后面的语句是否为false

5.请描述嵌套for循环执行的过程

嵌套for循环是在外层执行一次的情况下内内层会执行若干次

for(int i=0;i<10;i++){
    for(int j=0;j<10;j++){
        
    }
}

例如上述的for循环,在外层循环执行一次的情况下,内层循环会执行10次

6.为什么要重写toString()方法

如若不重写toString()方法,那么它的可读性是很差的,默认的toString()方法的输出为getClass().getName()+‘@’+Integer.toHexString(hashCode())

那如果重写toString()方法,可以根据业务逻辑或者读者的要求去进行设置,具有较强的可读性

7.this和super的区别

this在调用属性时,会先在本类中寻找若本类中没有此属性那么会在父类中寻找

this在调用方法时,会先在本类中寻找若本类中没有此方法那么会在父类中寻找

this在调用构造方法时,会先调用父类的构造方法来初始化父类的属性,再初始化本类中的属性

super在调用属性时,会直接调用父类的属性

super在调用方法时,会直接调用父类的方法

super在调用构造方法时,会直接调用父类的构造方法

8.重载和重写的区别

重载应用在一个类中,主要作用是为了不同的需求来初始化实现功能

重写的实现必须是子父类之间,子类继承父类的方法,但是子类并不局限于父类方法的功能,需要扩展或者修改时,需要重写父类的方法

9.请写出空指针异常的名字(英文),并描述其产生的原因

NullPointerException,产生空指针的主要原因有

  1. 对象为空,但是调用其属性和方法,此时会出现空指针异常
  2. 局部变量未赋值,因在方法中的局部变量必须初始化,若未初始化那么也会出现空指针异常

10.你对static关键字的理解

static关键字既能修饰属性又能修饰方法,当用其修饰后,不管是方法还是属性都会变为共享数据。并且用static修饰的属性和方法是用类来调用而不是用对象来调用(也可以用类对象来调用),用static修饰的方法只能访问外界的static修饰的属性和方法,用static修饰的属性在jvm中和普通属性的放置位置是不同的,它放在方法区中,也解释了为什么其需要用类来调用,被static修饰的方法不能被重写。

11.类==和equals()方法的区别

==在判断基本数据类型时,是判断的数值,当判断引用数据类型时,判断的是引用数据类型的地址。

equals方法在判断基本数据类型时,判断的是数值,若判断的是引用数据类型,若equals()方法未被重写则判断的是地址相当于==,若equals()方法被重写了,则判断的是什么需要根据重写的内容进行判断

12.final关键字的作用

final关键字可以修饰类,可以修饰方法,可以修饰属性

当其修饰类时,此类不能被继承

当其修饰方法时,此方法不能被重写

当其修饰属性时,此属性为常量

并且在接口中定义的所有属性都是final的

13.对多态的理解

多态就是同一方法,针对不同事物,表现出不同的行为

其主要应用在一个父类多个子类重写同一个父类方法时

14.写一个单例设计模式程序

单例设计模式分为饿汉式和懒汉式

饿汉式不会产生线程安全问题,懒汉式会产生线程安全问题

饿汉式:

public class Lazy{
    private Lazy(){
        
    };
    private static Lazy lazy=new Lazy();
    public static Lazy getInfo(){
        return lazy;
    }
}

懒汉式:

public class Hungry{
    private Hungry(){
        
    };
    private static Hungry hungry=null;
    public static Hungry getInfo(){
        if(hungry==null){
            return new Hungry();
        }
    }
}

15.请描述你对模板方法设计模式的理解

模板方法设计模式,见名知意,其主要思想是设计一个模板,当一个类需要此模板中的具体方法时,继承此模板,实现模板的价值。模板设计模式主要是对继承知识的应用。

16.描述你对工厂方法设计模式的理解

工厂方法设计模式,主要分为,简单工厂设计模式,工厂方法设计模式,抽象工厂设计模式

其中简单工厂设计模式是用来生产同一等级结构中的任意产品,但是对于新增产品时需要修改已有代码,扩展性较差

工厂方法设计模式是用来生产同一等级中的固定产品,支持新增同一等级下的产品,但是在生产其他品种的产品时扩展性较差

抽象工厂设计模式是用来生产不同品种的全部产品,当需要新增产品时,无能为力,但是在新增新的品种时会展现其模式的特点

工厂方法设计模式的主要思想就是将创建对象的内容隐藏只暴露一个接口从而实现了创建对象和调用方法的分离

17.描述你对代理设计模式的理解

代理设计模式分为静态代理和动态代理

代理设计模式的主要思想是将代理人和被代理人的公共方法提取,代理人执行方法同步给被代理人从而实现代理人和被代理人的数据同步,主要应用的知识点是接口

静态代理:将代理人和被代理人的公共方法提取,目的是使被代理人无需管理但是也会被同步。在代码逻辑上看,创建接口,代理人和被代理人实现接口,但是代理人可以定义其他方法,为了同步,需要在代理人类中创建被代理人类的属性和以被代理人为参数的构造方法。

动态代理:动态代理主要解决了静态代理的拓展问题,在静态代理中,当多个类需要代理时,那么需要创建多个接口,多个代理类,各个类的耦合度较高。那么用动态代理只需将需要代理的类名传入动态代理的方法中从而实现代理。动态代理也是SpringAop的底层原理,动态代理分为java动态代理和CGlib动态代理。

18.描述你理解的对象数组

对象数据,顾名思义,就是在普通数组中存储对象元素,其与普通基本元素数组的区别是其存储的不是元素本身而是其对象的地址,在访问对象数组的某个元素时,是先拿取地址再在地址的基础上去访问对象元素

19.描述数组的扩容机制

数组的扩容机制的主要思想是:创建一个新数组此数组是原来数组长度的二倍再将原数组中的元素传入新数组中,再利用地址传递的形式将新数组的地址赋给原数组的引用,从而实现了数组的扩容。

数组的扩容还可以利用Arrays类下的copy方法实现,但是其底层原理都是一样的。

20.请描述动态数组中指定索引新增元素和指定索引删除元素的区别

动态数组中指定索引新增元素的思路是在原数组的基础上将指定索引之后的元素进行集体向后拷贝而指定索引元素删除元素的思路是在原数组的基础上将指定索引之后的元素集体向前拷贝。

动态数组中指定索引新增元素和指定索引删除元素的基本思路都是将原数组进行拷贝移动。

21.描述快速排序算法的比较过程及代码实现

  • 首先定义两个变量分别接收函数传来的第一个元素和最后一个元素,再定义一个元素来定义基准值,普遍将基准值设置为首元素的值
  • 若是将基准值设置为首元素那么应先去访问尾元素去判断其与基准值的大小,若比基准值大尾元素则向前移动一位,若比基准值小则不动,并将此处的值赋给首元素所在位置,再转为首元素移动,首元素若比基准值小则向后移动一位,若比基准值大则不动,并将首元素此时的值赋为尾元素所在位置,直至首元素位置和尾元素位置相等时,则将基准元素放在首元素位置也是尾元素位置。
  • 最后利用递归的思想将前后部分分别按照上述的方式进行操作,最后即可产生顺序的数列
public void QuickSort(int[] num,int left,int right){
    int beigin=left;
    int end=right;
    int key=left;
    while(begin<end){
        while(begin<end&&num[end]>num[key]){
            end--;
        }
        num[begin]=num[end];
        while(begin<end&&num[begin]<num[key]){
            begin++;
        }
        num[end]=num[begin];
    }
    num[begin]=num[key];
    QuickSort(num,left,begin-1);
    QuickSort(num,begin+1,right);
}

22.try{}里面有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候执行,在return前还是后

try后的finally{}里的代码会在return之前执行,此处的流程是先遇到return然后将其压入栈中,因为每个try-finally语句必须执行finally中的代码,此时将执行完finally里的代码之后再将return语句弹出栈执行

23.如何将一个数值型的字符串转成整数

利用包装类中的parsexxx()方法,可以将一个数值型的字符串转成整数。而将整形转为字符串型时是使用String类的ValueOf方法,也可以使用String类的构造方法。

24.Instance of关键字的作用

Instance of 关键字使用在多态,其作用是判断父类引用是否由其子类创建的,若不是则返回false,若是则返回true

25.对象数组存储的是否是实例本身,如果不是,存储的又是什么

对象数组存储的不是实例本身,其存储的是对象的地址

26.Break、continue、return的区别

break:应用在switch-case和循环语句中,在switch-case中遇到break时则结束此次判断,在循环中遇到break时则结束此循环

continue:应用在循环语句中,在循环中遇到continue时,则跳过此次循环执行下一次循环

return:应用在方法中,在方法中遇到return时,直接结束此方法

27.请描述你对构造方法的理解

构造方法无返回值,主要作用是创建对象和初始化属性

构造方法分为无参构造和有参构造

若一个类中没有定义任何构造方法那么就会默认构建无参构造

有参构造可以根据不同的业务创建不同的有参构造方法

并且在构造方法中会无形的调用父类的构造方法初始化父类的属性

28.接口和抽象类的区别

抽象类和接口都不能创建对象,抽象类和接口中都可以编写抽象方法,抽象类和接口的实现类必须重写抽象类和接口中的所有的抽象方法,否则此实现类为抽象类

抽象类使用abstract关键字修饰,抽象类中既可以包括普通的方法也可以包括抽象方法,子类继承抽象类是单继承

接口使用interface关键字修饰,接口中包含抽象方法以及共有静态常量,public static修饰的方法,public default修饰的方法,接口的出现主要弥补了继承单继承的缺点,因此接口是多继承的

29.谈谈你理解的异常

异常即程序出现了bug,当程序出现bug时,bug下面的代码不会执行,那么想要bug下的代码执行,则需要抛出异常和处理异常。故产生了try-catch和throws,两者的主要区别是try-catch既可以抛出异常也可以处理异常而throws只能抛出异常不能处理异常

30.谈谈你理解的面向对象

面对对象设计思想相对于面向过程设计思想的主要区别是:

不再专注于过程,步骤,而是利用一个对象去处理事物,用虚拟思想模拟现实

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值