Java基础面试题

文章目录

一、JavaOOP面试题

1、short s1 = 1; s1 = s1 + 1;有错吗? short s1 = 1; s1 += 1; 有错吗?

int 占4个字节 4x8=32位 short占用两个字节 2x8=16位

short s1 = 1; s1 = s1 + 1; 有错

s1为short型 s1+1 变量提升为int型,不能显示转换为int型

short s1 = 1; s1 += 1; 没有错

s1+=1; 等价于 s1 = (short)(s1+1)

​ 第一个为简单赋值操作符,第二个为复合赋值操作符

在Java规范中提到,复合赋值(E1 op = E2)等价于简单赋值 E1 = (short)((E1)op (E2))

复合赋值表达式自动将执行的结果—>转化为左侧变量的类型

假若结果类型与变量类型相同,转型不会造成影响;

然而结果类型比变量类型要宽,复合操作符执行一个窄化原生类型转换 例如:long t1; t1+=1;

2、重载和重写的区别

答:方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性

  • 重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;
  • 重写发生在子类与父类之间,重写要求子类重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。
    重载对返回类型没有特殊的要求,不能根据返回类型进行区分。

重写(Overiide) —> 简单的说:就是子类把父类本身有的方法重新写一遍,子类继承父类原有的方法

​ 子类可以对父类的方法体进行修改或重写(在方法名,参数列表,返回类型(除了子类方法的返回类型是父类方法返回类型的子类时))

​ 注意:子类函数的访问修饰符权限不能少于父类的

//重写(Overiide)
class Animal{
   
    public void skinColor(){
   
        System.out.println("皮肤有颜色");
    }
}
class Dog extends Animal{
   
    public void skinColor(){
   
        System.out.println("皮肤-->黄色");
    }
}
  • 重写 总结:
    1.发生在父类与子类之间
    2.方法名,参数列表,返回类型(除子类中方法的返回类型父类返回类型的子类)必须相同
    3.访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)
    4.重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常

重载(Override)

在一个类中,同名方法如果有不同的参数列表(参数类型不同、参数个数不同甚至是参数顺序不同)则视为重载。

同时重载的返回类型没有要求,但是==不能通过返回类型是否相同来判断重载==。

//重载(Override)
class Animal{
   
    public void skinColor(){
   
        System.out.println("皮肤有颜色");
    }
    public void skinColor(String skColor){
   }
}
3、数组实例化有几种方式?

3.1 静态实例化:创建数组的时候已经指定数组中的元素

int [] a= new int[]{
    1 , 3 , 3}

3.2 动态实例化:实例化数组的时候,只指定了数组程度,数组中所有元素都是数组类型的默认值

int [] a= new int[2];
a[0]=1;//给数组元素赋值
a[2]=2;

3.3 数组的默认初始化

数组是引用类型,他的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化

实例:int a2[]=new int[2];//默认值0,0

boolean[] b=new boolean[2];//默认值 false,false

String[] s=new String[2];//默认值null
4、Java中各种数据默认值(引用类型在堆里,基本类型在栈里。)
  • Byte,short,int,long默认是都是0
  • Boolean默认值是false
  • Char类型的默认值是\u0000
  • Float与double类型的默认是0.0
  • 对象类型的默认值是null
5、Object类常用方法有哪些?

Equals
Hashcode
toString
wait
notify
clone
getClass

6、java中是值传递引用传递?

​ Java是值传递。

  • 当传的是基本类型时,传的是值的拷贝,对拷贝变量的修改不影响原变量;

  • 当传的是引用类型时,传的是引用地址的拷贝,但是拷贝的地址和真实地址指向的都是同一个真实数据,

因此可以修改原变量中的值;

  • 当传的是String类型时,虽然拷贝的也是引用地址,指向的是同一个数据,但是String的值不能被修改,因此无法修改原变量中的值。
7、形参与实参区别

7.1 主体不同

  1. 实参:在调用有参函数时,函数名后面括号中的参数为**“实际参数**”。
  2. 形参:不是实际存在变量,又称虚拟变量。

7.2 目的不同

  1. 实参:可以是常量、变量或表达式, 无论实参是何种类型的量,在进行函数调用时,都必须具有确定的值, 以便把这些值传送给形参
  2. 形参:定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数

7.3 特点不同

  1. 实参:在调用函数过程中,系统会把实参的值传递给被调用函数的形参。或者说,形参从实参得到一个值。该值在函数调用期间有效,可以参加该函数中的运算。
  2. 形参:形参的本质是一个名字,不占用内存空间
8、构造方法能不能重写?能不能重载?

构造方法不可以被重写,因为重写发生在父类和子类之间,要求方法名称相同,而构造方法的名称是和类名相同的,而子类类名不会和父类类名相同,所以不可以被重写

构造方法可以被重载

9、内部类与静态内部类的区别?

​ 定义在一个类内部的类叫内部类,包含内部类的类称为外部类。内部类可以声明public、protected、private等访问限制,

可以声明 为abstract的供其他内部类或外部类继承与扩展,或者声明为static、final的,也可以实现特定的接口。

10、final在java中的作用,有哪些用法?

​ final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)

10.1 修饰类

  • 当用final修饰一个类时,表明这个类不能被继承。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。(尽量不要将类设计为final类)

10.2 修饰方法

  • 使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;

  • 第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。

    但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。“

    因此,如果只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。即父类的final方法是不能被子类所覆盖的,也就是说子类是不能够存在和父类一模一样的方法的。

    final修饰的方法表示此方法已经是“最后的、最终的”含义,亦即此方法不能被重写(可以重载多个final修饰的方法)。

    此处需要注意的一点是:因为重写的前提是子类可以从父类中继承此方法,如果父类中final修饰的方法同时访问控制权限为private,

    将会导致子类中不能直接继承到此方法,因此,此时可以在子类中定义相同的方法名和参数,此时不再产生重写与final的矛盾,

    而是在子类中重新定义了新的方法。(注:类的private方法会隐式地被指定为final方法。)

10.3 修饰变量

  • final成员变量表示常量,只能被赋值一次,赋值后值不再改变。

  • 当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;

    如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的

    本质上是一回事,因为引用的值是一个地址,final要求值,即地址的值不发生变化。

    final修饰一个成员变量(属性),必须要显示初始化。这里有两种初始化方式,一种是在变量声明的时候初始化;

    第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。

    当函数的参数类型声明为final时,说明该参数是只读型的。即你可以读取使用该参数,但是无法改变该参数的值。

二、Java集合/泛型面试题

1、ArrayList和linkedList的区别
  1. ArrayList的实现是基于数组的数据结构,LinkedList的基于链表的数据结构。这两个数据结构的逻辑关系是不一样,当然物理存储的方式也会是不一样。

  2. LinkedList比ArrayList更占内存,因为LinkedList的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素

  3. 对于随机访问,ArrayList要优于LinkedList。因为LinkedList要移动指针

  4. 对于插入和删除操作,LinkedList优于ArrayList。因为ArrayList要移动数据

//参考 https://www.cnblogs.com/huzi007/p/5550440.html
 static final int N=50000;
 static long timeList(List list){
   
     long start=System.currentTimeMillis();
     Object o = new Object();
     for(int i=0;i<N;i++) {
   
         list.add(0, o);
     }
     return System.currentTimeMillis()-start;
 }
 static long readList(List list){
   
     long start=System.currentTimeMillis();
     for(int i=0,j=list.size();i<j;i++){
   

     }
     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值