Java基础面试题

1. final修饰类,方法,变量

  • 修饰类:类不能被继承
  • 修饰方法:方法不能被重写
  • 修饰变量:变量变常量,只能被赋值一次

2. 操作字符串的类和String类的操作方法

1)操作字符串的类:String,StringBuilder,StringBuffer

  • String:声明不可变的对象,修改对象时创建一个新对象;适用于少量字符串操作;
  • StringBuilder:可以修改原对象,不会创建新对象;线程不安全,适用于单线程下在字符串缓冲区进行大量操作;
  • StringBuffer:可以修改原对象,不会创建新对象。线程安全,适用于多线程下在字符串缓冲区进行大量操作。

2)String类的操作方法:

  • toCharArray():字符串转成字符数组,char[] c = str1.toCharArray();
  • charAt():从字符串中取出指定位置字符,从1开始数;
  • length():字符串长度;
  • indexOf():查找指定字符串位置,没有返回-1;
  • contains():是否包含字符串,返回boolean值;
  • trim():去掉字符串左右空格;
  • subString():截取字符串;
  • split():拆分字符串,String[] s = str1.split(" ");
  • toUpperCase()和toLowCase():大小写转换;
  • startsWith()和endsWith():判断是否以字符串开头或结尾;
  • equals()和equalsIgnoreCase():equals()不区分大小写比较,equalsIgnoreCase()不区分大小写比较;
  • replaceAll():将指定字符串替换成目标字符串;

3. String类两种对象实例化方式的区别

  • 直接赋值(String str = “字符串”;):只会开辟一块堆内存空间并且会自动保存在对象池之中以供下次重复使用,栈内存str指向堆内存“字符串”;
  • 构造方法(String str = new String(“字符串”);):会开辟两块堆内存空间(字符串常量开辟的堆内存空间和new关键字开辟的堆内存空间),其中有一块空间将成为垃圾(字符串常量开辟的堆内存空间),并且不会自动入池,但是用户可以使用intern()方法手工入池。

4. 接口和抽象类区别:

  • 接口中成员变量类型必须是public static final,意味着都是常量,并且不能被自己和外部修改;抽象类可以有各种成员变量,并且可以通过自己的非抽象方法改变;
  • 接口中可以有实现体方法(Java8以后新增实现体方法,default method和public static method),抽象方法,没有构造方法;抽象类可以有实现体方法(无default method),抽象方法,构造方法,其他方法的访问权限可以是public,private,protected;
  • 接口可以多继承,一个接口可以继承多个接口;抽象类只能单继承,一个子类只能继承一个父类;(单继承多实现)
  • 接口类比抽象类更加抽象;抽象类更接近普通类,只是可以有抽象方法;

总之,如果关心的是java中的多继承,那么用接口吧;如果关心属性或方法是否是private,protected,non-static或final的,那么考虑抽象类。

5. Collection和Collections区别

  • java.util.Collection 是一个集合接口。(List和Set接口)
  • java.util.Collections 是一个集合工具类,Collections.emptyList()  Collections.sort() 等。

6. 数组和list转换

1)数组转list:String[] str=new String[] {"hello","world"};

  •  for循环把数组str元素加进list;
  •  List<String> list2=new ArrayList<String>(Arrays.asList(str));//返回java.util.ArrayList;
  •  List<String> list3 = Arrays.asList(str);//返回java.util.Arrays.ArrayList,无add()和remove()方法;
  •  Collections.addAll(); Collections.addAll(new ArrayList<String>(str.length), str);
  •  Stream中的Collector收集器, List<String> list5=Stream.of(str).collect(Collectors.toList());

2)list转数组:

  • for循环;
  • toArray(); String strings[]=(String [])list.toArray();

7. 创建线程有几种方式?

  • 继承Thread重写run方法;
  • 实现Runnable接口重写run方法;
  • 实现Callable接口重写call方法(有返回值可抛异常)

8. start() 和 run() 有什么区别?

  • start() 可启动多线程,内部调用native本地方法,使线程处于就绪(可运行)状态,并没有运行。一旦得到cpu时间片,就开始执行run方法。
  • run() 只是thread的一个普通方法调用,还是在主线程里执行,是不会开启多线程的。

参考:https://www.cnblogs.com/agilestyle/p/11421515.html

9. sleep() 和 wait() 有什么区别?

sleep() 和 wait() 都用来改变线程的状态,能够让线程从运行状态,转变为休眠状态。

  • sleep() 是Thread类方法;wait() 是Object类方法。
  • sleep() 不会释放对象锁;wait() 会释放对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify 方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
  • 使用范围,sleep() 可以在任何地方使用;wait() notify() 和 notifyAll() 只能在同步控制方法或者同步控制块里面使用。synchronized(x){  x.notify()  //或者wait()  }
  • sleep() 必须捕获异常;wait() notify() 和 notifyAll() 不需要捕获异常。

参考:https://blog.csdn.net/nyistzp/article/details/12878417

原文地址:https://www.cnblogs.com/yuki67/p/14236295.html