Java的几个常考的基础面试题

目录

一、方法重载与重写的区别?

二、String和StringBuffer、StringBuilder的区别?( String为什么是不可变的?)

三、自动装箱与拆箱

四、 == 与 equals 的区别

五、说说 final关键字 。

六、Object类的常用方法有哪些?

七、键盘输入的常用获取方法?

八、接口和抽象类的区别?


 

一、方法重载与重写的区别?

重载:在同一个类中,方法名相同,但 参数的类型,个数,或 顺序不同;
           重载方法的返回值 和 权限修饰符可以相同也可以不同;
           重载发生在编译时。

重写:即指子类重写父类的方法,方法名、参数列表 都必须一样;
           子类重写方法的 返回值的范围、抛出异常的范围  都必须小于等于 父类中被重写的方法;
           子类重写方法的 权限修饰符范围 必须大于等于 父类中被重写的方法;
           若父类中的方法的权限修饰符为 private,那子类就不能重写该方法;

 

二、String和StringBuffer、StringBuilder的区别?( String为什么是不可变的?)

区别1: 可变性
String对象是不可变的,而StringBuilder和StringBuffer对象是可变的。
原因在于,虽然三者的底层都是使用字符数组保存字符串,
但是  String 中用了final修饰,private final char value[] ,
而 StringBuilder和StringBuffer 都是继承自 AbstractStringBuilder 类,该类中没用final修饰, char[] value ;
String源码:

StringBuilder和StringBuffer源码:

 

区别2:线程安全性
①String对象是不可变的,可以理解为常量,线程安全;
StringBuilder和StringBuffer 都是继承自 AbstractStringBuilder 类,该类定义了一些字符串的基本操作,如append、insert、indexOf
等公共方法。
②StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以 线程安全;
③StringBuilder没有给方法加同步锁,所以 线程不安全;

 

区别3:性能
String类型改变时,都要生成一个新的String对象,并将指针指向新的String对象,性能一般;
StringBuffer类型改变时,会对StringBuffer对象本身进行操作,而不是去生成新的对象操作,所以性能较高;
StringBuilder操作类型时,相同情况下,会比StringBuffer提高10%~15%的性能,但是要从承担多线程不安全的风险;

使用总结:

  1. 操作少量数据时,用 String;
  2. 单线程操作 字符串缓冲区下的大量数据,用 StringBuilder;(单线程不存在线程不安全问题,所以不怕线程不安全;)
  3. 多线程操作 字符串缓冲区下的大量数据,用StringBuffer;(多线程可能存在线程不安全问题,所以用线程安全的StringBuffer)

 

三、自动装箱与拆箱

装箱:将基本数据类型转换为对应的包装类型;

拆箱:将包装类型转换为对应的基本数据类型;

基本数据类型 与 包装类 对应表:

 

 

四、 == 与 equals 的区别

== 是用来判断两个对象是不是同一个对象,即比较的是两个对象的地址;
(基本数据类型比较的是值,引用数据类型比较的是内存地址。)

equals 如果没有被重写,底层其实就是 ==

可以顺便看下equals源码:

不过,我们一般不会直接使用equals (直接使用可以用 == 呀~),

一般我们都是使用 重写之后的 equals 。

重写之后的equals 判断的是两个对象的值是否相等;

像String,List,等官方的,其实已经帮我们重写好了 equals ,默认就算比较两个对象的值了;

我们可以顺便看一下String中帮我们重写好的equals方法:

 

五、说说 final关键字 。

final关键字主要用在三个地方:变量、方法、类

final修饰变量:如果是基本数据类型的变量,则其数值一旦初始化之后就不能修改了;

                        如果是引用类型的变量,则在对其初始化之后就不能再让其指向其他对象了(但指向的对象的内容是可以变化的。因                             为引用的值是一个地址,不变的是地址,而该地址上的内容是可以变的。);

final修饰方法:一是可以锁定方法,防止任何继承类修改它的含义,类中所有的private方法都隐式地指定都为final方法;

                        二是可以提升效率,不过现在的Java版本已经不需要使用final方法来进行优化了;

final修饰类:表明这个类不能被继承,且该类中的所有成员方法都会被隐式地指定为final方法。

 

六、Object类的常用方法有哪些?

Object类是所有类的父类,所有类都默认继承了Object类。

Object类实现的方法:

  1. getClass 方法
    final修饰,用于返回当前运行时对象的class对象。
  2. hashCode 方法
    用于返回对象的哈希码,主要使用在哈希表中,如 JDK中的HashMap。
  3. equals 方法
    用于比较两个对象的内存地址是否相等;
    但一般都是使用重写后的equals方法,用于比较两个对象的值是否相等。
  4. clone 方法
    用于创建并返回对象的一份拷贝(浅复制);
    调用clone方法前需要先实现Cloneable接口并重写clone方法,否则会报CloneNotSupportedException异常。
  5. toString 方法
    会返回 类的名字@实例的哈希码的16进制 的字符串;
    一般都是使用重写后的toString方法。
  6. notify 方法
    final修饰,用于唤醒在该对象上等待的线程,如果有多个线程在等待,则随机唤醒其中一个。
  7. notifyAll 方法
    final修饰,用于唤醒在该对象上等待的所有线程。
  8. wait 方法 (3种)
    final修饰,用于暂停线程的执行,相比sleep方法,wait方***释放锁;
    1. wait() 方***一直暂停线程执行;
    2. wait(long timeout) 方***暂停线程,timeout 是超时时间(毫秒);
    3. wait(long timeout,int nanos)  方法和 wait(long timeout) 一样,但是超时时间要加上nanos(毫微秒); 
  9. finalize 方法
    实例被垃圾回收器回收的时候触发的操作

 

七、键盘输入的常用获取方法?

  1. Scanner
    Scanner input = new Scanner(System.in);
    String str = input.nextLine();
    input.close();

     

  2. BufferedReader
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
    String s = input.readLine();

     

 

八、接口和抽象类的区别?

  1. 接口中的方法默认是public,没有具体实现(java8之后可以有默认实现);抽象类中可以有非抽象的方法。
  2. 接口中的实例变量默认是final类型的,抽象类中则不是;
  3. 一个类可以实现多个接口,但只能继承一个抽象类;
  4. 接口的实现类必须实现接口中的所有普通方法;而抽象类的继承类如果也是一个抽象类,可以不需要实现抽象类中的所有抽象方法。
  5. 接口不能用new实例化,但是可以声明,不过必须引用一个实现该类接口的对象。
    从设计层面来看,抽象是对类的抽象,是一种模板设计;接口是对行为的抽象,是一种行为的规范。

PS:
在JDK8中,接口也可以定义静态方法,可以直接用接口名调用;实现类和实现是不可以调用的;
如果同时实现两个接口,两个接口中有一样的默认方法,则必须重写该方法,否则会报错。

 

 

全部评论

相关推荐

09-27 14:42
已编辑
浙江大学 Java
未来未临:把浙大放大加粗就行
点赞 评论 收藏
分享
Hello_WordN:咱就是说,除了生命其他都是小事,希望面试官平安,希望各位平时也多注意安全
点赞 评论 收藏
分享
1 1 评论
分享
牛客网
牛客企业服务