【JAVA面试题】java基础面试50道题

文章目录

1. 面向对象的特征有哪些方面?

  • 封装
    最常见的是把属性私有化封装在一个类里面,只能通过方法去访问,我们常用的get(),set()方法
  • 继承
    子类继承父类,从而继承了父类的方法和属性 extends
  • 抽象
    比如一个英雄类,抽象出了name,hp这些属性,使得开发过程中更加易于理解abstract
    接口是抽象类的变体,接口比抽象类更加抽象,接口中所有的方法都是抽象的。
    public interface AP
    public abstract class AP
    抽象类和接口的区别
    区别1:
    子类只能继承一个抽象类,不能继承多个
    子类可以实现多个接口
    区别2:
    抽象类可以定义
    public,protected,package,private
    静态和非静态属性
    final和非final属性
    但是接口中声明的属性,只能是
    public
    静态
    final的
    即便没有显式的声明
  • 多态
    多态分操作符的多态和类的多态。
    操作符的多态:同一个操作符在不同情境下,具备不同的作用
    如果+号两侧都是整型,那么+代表 数字相加
    如果+号两侧,任意一个是字符串,那么+代表字符串连接
    类的多态:1. 父类引用指向子类对象,并且有继承或接口实现,2. 调用的方法有重写。

2. String是最基本的数据类型吗?

String是类类型,不是基本类型。
基本类型 有八种
这八种基本类型分别是:
整型 (4种)byte(8位), short(16位),int(32位),long(64位)
字符型 (1种)char(16位)
浮点型 (2种)float(32位),double(64位)
布尔型(1种)boolean布尔型真正存放的数据是0(false) 1(true),但是,不能直接使用0 1 进行赋值

字符串即字符的组合,在Java中,字符串是一个类,所以我们见到的字符串都是对象
常见创建字符串手段:

  1. 每当有一个字面值出现的时候,虚拟机就会创建一个字符串
  2. 调用String的构造方法创建一个字符串对象
  3. 通过+加号进行字符串拼接也会创建新的字符串对象
package character;
public class TestString {
    public static void main(String[] args) {
        String garen ="盖伦"; //字面值,虚拟机碰到字面值就会创建一个字符串对象
        String teemo = new String("提莫"); //创建了两个字符串对象
        char[] cs = new char[]{'崔','斯','特'};
        String hero = new String(cs);//  通过字符数组创建一个字符串对象
        String hero3 = garen + teemo;//  通过+加号进行字符串拼接
    }
}

String 被修饰为final,所以是不能被继承的

3. int 和 Integer 有什么区别?

int 是基本类型32位长度的整数
Integer 是类类型,是int的封装类
int和Integer之间可以通过自动装箱 自动拆箱 互相转换

 int i = 5;
 //自动转换就叫装箱
 Integer it2 = i;
 //自动转换就叫拆箱
 int i3 = it2;

4. String 和StringBuffer的区别?

String是immutable的,其内容一旦创建好之后,就不可以发生改变。
StringBuffer 是可以变长的,内容也可以发生改变
改变的原理是StringBuffer内部采用了字符数组存放数据,在需要增加长度的时候,创建新的数组,并且把原来的数据复制到新的数组这样的办法来实现。
自己实现一个StringBuffer

5. 运行时异常与一般异常有何异同?

运行时异常

运行时异常(RuntimeException) 又叫做非可查异常,在编译过程中,不要求必须进行显示捕捉
常见运行时异常:

  • 除数不能为0异常:ArithmeticException
  • 下标越界异常:ArrayIndexOutOfBoundsException
  • 空指针异常:NullPointerException
		//任何除数不能为0:ArithmeticException
        int k = 5/0;
        //下标越界异常:ArrayIndexOutOfBoundsException
        int j[] = new int[5];
        j[10] = 10;
        //空指针异常:NullPointerException
        String str = null;
        str.length();

在编写代码的时候,依然可以使用try catch throws进行处理,与可查异常不同之处在于,即便不进行try catch,也不会有编译错误
Java之所以会设计运行时异常的原因之一,是因为下标越界,空指针这些运行时异常太过于普遍,如果都需要进行捕捉,代码的可读性就会变得很糟糕。

一般异常

一般异常又叫做可查异常
可查异常: CheckedException
可查异常即必须进行处理的异常,要么try catch住,要么往外抛,谁调用,谁处理,比如 FileNotFoundException
如果不处理,编译器,就不让你通过

 public static void main(String[] args) {
        File f= new File("d:/LOL.exe");
        try{
            System.out.println("试图打开 d:/LOL.exe");
            new FileInputStream(f);
            System.out.println("成功打开");
        }
        catch(FileNotFoundException e){
            System.out.println("d:/LOL.exe不存在");
            e.printStackTrace();
        }
    }

错误

Error,指的是系统级别的异常,通常是内存用光了
在默认设置下,一般java程序启动的时候,最大可以使用16m的内存
如例不停的给StringBuffer追加字符,很快就把内存使用光了。抛出OutOfMemoryError
与运行时异常一样,错误也是不要求强制捕捉的

public class TestException {
    public static void main(String[] args) {
        StringBuffer sb =new StringBuffer();
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            sb.append('a');
        }
    }
}

异常分三类

  1. 错误
  2. 运行时异常
  3. 可查异常
    在这里插入图片描述

6. 说出ArrayList,Vector, LinkedList的存储性能和特性。

先说ArrayList和Vector
两者都继承了抽象类AbstractList,但是Vector是线程安全的,而ArrayList是非线程安全的.
再说ArrayList和LinkedList的区别
ArrayList 是数组结构,所以定位很快,但是插入和删除很慢
LinkedList 是双向链表结构,所以插入和删除很快,但是定位很慢

7. Collection 和 Collections的区别。

首先不要说成了一个是单数,一个是复数。。。
Collection是接口,Collection是 Set List Queue(先进先出队列)和 Deque(双向链表)的接口
在这里插入图片描述
Collection和Map之间没有关系,Collection是放一个一个对象的,Map 是放键值对的
Deque 继承 Queue,间接的继承了 Collection

Collections是工具类,提供了排序,混淆等等很多实用方法
reverse 使List中的数据发生翻转
shuffle 混淆List中数据的顺序
sort 对List中的数据进行排序
swap 交换两个数据的位置
rotate 把List中的数据,向右滚动指定单位的长度

8. &和&&的区别

& 有两个作用,分别是 位与 和 逻辑与

//位与
//5的二进制是101
//6的二进制是110
//所以 5&6 对每一位进行与运算,得到 100->4
public static void main(String[] args) {
	int i  =5;
    int j = 6;
    System.out.println(i&j); //所以 5&6 对每一位进行与运算,得到 100->4
}

&& 就是逻辑与
作为逻辑与, & 和 && 分别表示长路与和短路与
长路与 两侧,都会被运算
短路与 只要第一个是false,第二个就不进行运算了

 public static void main(String[] args) {
        //长路与  无论第一个表达式的值是true或者false,第二个的值,都会被运算
        int i = 2;
        System.out.println( i== 1 & i++ ==2  ); //无论如何i++都会被执行,所以i的值变成了3
        System.out.println(i);
         
        //短路与 只要第一个表达式的值是false的,第二个表达式的值,就不需要进行运算了
        int j = 2;
        System.out.println( j== 1 && j++ ==2  );  //因为j==1返回false,所以右边的j++就没有执行了,所以j的值,还是2
        System.out.println(j);     
         
    }

9. HashMap和Hashtable的区别

HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式

  1. 区别1:
    HashMap可以存放 null
    Hashtable不能存放null
  2. 区别2:
    HashMap不是线程安全的类
    Hashtable是线程安全的类

10. final, finally, finalize的区别

  • final
    final修饰类,方法,基本类型变量,引用的时候分别有不同的意思
    修饰类 表示该类不能被继承
    修饰方法 表示该方法不能被重写
    修饰基本类型变量 表示该变量只能被赋值一次
    修饰引用 表示该引用只有一次指向对象的机会
  • finally
    finally 是用于异常处理的场面,无论是否有异常抛出,都会执行
  • finalize
    finalize是Object的方法,所有类都继承了该方法。 当一个对象满足垃圾回收的条件,并且被回收的时候,其finalize()方法就会被调用

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

即重载和重写的区别。
Overload是方法重载的意思,指的是在同一个类里面,方法名一样,但是参数不一样
Override是方法重写的意思,指的是子类继承了父类的某个方法后,重新又写了一遍
Overloaded的方法是否可以改变返回值的类型?
可以,重载其实本质上就是完全不同的方法,只是恰好取了相同的名字

12. Error和Exception有什么区别?

Error和Exception都实现了Throwable接口
Error指的是JVM层面的错误,比如内存不足OutOfMemoryError
Exception 指的是代码逻辑的异常,比如下标越界OutOfIndexException
在这里插入图片描述

13. abstract class和interface有什么区别?

abstract class 抽象类和interface接口的区别

  • 使用方式:
    抽象类只能够通过继承被使用
    接口必须通过实现被使用

  • 实现方法:
    抽象类不仅可以提供抽象方法,也可以提供实现方法
    接口只能提供抽象方法,不能提供实现方法。 但是在JAVA8版本开始,接口可以提供实现方法了,前提是要在方法前加一个default修饰符

14. heap和stack有什么区别

  • heap: 堆
  • stack: 栈 (在一些书籍里,会被翻译为堆栈,实际上指的就是单纯的这个栈)
  1. 存放的内容不一样:
    heap: 是存放对象的
    stack: 是存放基本类型(int, float, boolean 等等)、引用(对象地址)、方法调用

  2. 存取方式不一样:
    heap: 是自动增加大小的,所以不需要指定大小,但是存取相对较慢
    stack: 是固定大小的,并且是FILO 先入后出的顺序,并且存取速度比较快

15. GC是什么? 为什么要有GC?

GC是Garbage Collection的缩写,即垃圾回收
这里所谓的垃圾,指的是那些不再被使用的对象,JVM的垃圾回收机制使得开发人员从无聊、容易犯错的手动释放内存资源的过程中解放出来。
开发人员可以更加专注的进行业务功能的开发,而资源回收的工作交由更加专业的垃圾回收机制自动完成。

16. short s1 = 1; s1 = s1 + 1;有什么错?

在这里插入图片描述

short s1 = 1; 这一句没有错误,编译器会自动把1这个整数处理为short.
s1 = s1 + 1; 右侧的表达式会返回一个Int类型的整数,再把这个int类型的整数赋给short类型的s1的时候,就会出现强制转换错误

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

Math.round 的意思是+0.5 取整数
所以 Math.round(11.5) 即 11.5+0.5 = 12
Math.round(-11.5) 即 -11.5+0.5 = -11
Math.round(11.4)即 11.4+0.5 =11.9= 11(向下取整)
Math.round(-11.4)即 -11.4+0.5 =10.9= -11(向下取整)

18. String s = new String(“xyz”);创建了几个String Object?

在这里插入图片描述

String s = new String(“xyz”);
首先构造方法 new String(“xyz”); 中的"xyz" 这本身就是一个字符串对象
然后 new 关键字一定会创建一个对象
所以总共创建了两个String对象

19. Java有没有goto?

有,goto是关键字,但是是保留字,并不具备功能性

20. 接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?

  1. 接口是否可继承接口?
    可以,比如List 就继承了接口Collection
  2. 抽象类是否可实现(implements)接口?
    可以,比如 MouseAdapter鼠标监听适配器 是一个抽象类,并且实现了MouseListener接口
  3. 抽象类是否可继承实体类(concrete class)?
    可以,所有抽象类,都继承了Object

21. List, Set, Map是否继承自Collection接口?

List 和 Set 继承了Collection接口
但是Map和Collection之间没有继承关系,因为一个是键值对容器,一个是单值容器,无法兼容
在这里插入图片描述

22. abstract的method是否可同时是static,是否可同时是synchronized?是否可以同时是native

都不可以
1、abstract是抽象的,指的是方法只有声明而没有实现,他的实现要放入声明该类的子类中实现。
2、static是静态的,是一种属于类而不属于对象的方法或者属性
3、synchronized 是同步,是一种相对线程的锁。
4、native 本地方法,这种方法和抽象方法及其类似,它也只有方法声明,没有方法实现,但是它与抽象方法不同的是,它把具体实现移交给了本地系统的函数库,而没有通过虚拟机,可以说是Java与其它语言通讯的一种机制。
5、那么我们就来谈谈这些关键字为什么不能和abstract混用。

  • 首先abstract与static,声明static说明可以直接用类名调用该方法;
    声明abstract说明需要子类重写该方法;
    如果同时声明static和abstract,用类名调用一个抽象方法肯定不行。
  • synchronized 是同步,然而同步是需要有具体操作才能同步的,如果像abstract只有方法声明,那同步一些什么东西就会成为一个问题了,当然抽象方法在被子类继承以后,可以添加同步。
  • native,这个东西本身就和abstract冲突,他们都是方法的声明,只是一个吧方法实现移交给子类,另一个是移交给本地操作系统。如果同时出现,就相当于即把实现移交给子类,又把实现移交给本地操作系统,那到底谁来实现具体方法呢!
  • 不能放在一起的修饰符:final和abstract,private和abstract,static和abstract,因为abstract修饰的方法是必须在其子类中实现(覆盖),才能以多态方式调用,以上修饰符在修饰方法时期子类都覆盖不了这个方法,final是不可以覆盖,private是不能够继承到子类,所以也就不能覆盖,static是可以覆盖的,但是在调用时会调用编译时类型的方法,因为调用的是父类的方法,而父类的方法又是抽象的方法,又不能够调用,所以上的修饰符不能放在一起。

23. 数组有没有length()这个方法? String有没有length()这个方法?

数组获取长度的手段是 .length 属性
String获取长度的手段是 length()方法
集合获取长度的手段是 size()方法
文件获取长度的手段是 length()方法

24. Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?

以HashSet为例,判断重复的逻辑是:

  1. 首先看hashcode是否相同,如果不同,就是不重复的
  2. 如果hashcode一样,再比较equals,如果不同,就是不重复的,否则就是重复的。

25. 构造器Constructor是否可被override?是否可以继承String类?

子类不能继承父类的构造方法,所以就不存在重写父类的构造方法。
注: super() 表示子类调用父类的构造方法,这不能被叫做继承父类的构造方法
String是final修饰的,所以不能够被继承

26. switch 是否能作用在byte上,是否能作用在long上,是否能作用在String上?

switch 可以作用在 byte,short,int String,Enum(枚举) 上,但是不能作用在long上面
switch可作用于char byte short int对应的包装类
switch不可作用于long double float boolean,包括他们的包装类
switch中可以是字符串类型,String(jdk1.7之后才可以作用在string上)
switch中可以是枚举类型

注:注:switch 作用在String上从JDK1.7开始支持,实质是编译时将字符串替换为了其对应的hash值

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

try里的return 和 finally里的return 都会执行,但是当前方法只会采纳finally中return的值

28. 两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?

因为hashCode()方法和equals()方法都可以通过自定义类重写,是可以做到equals相同,但是hashCode不同的
但是,在Object类的equals()方法中有这么一段话

* Note that it is generally necessary to override the {@code hashCode}
* method whenever this method is overridden, so as to maintain the
* general contract for the {@code hashCode} method, which states
* that equal objects must have equal hash codes.
 

翻译如下:

通常来讲,在重写这个方法的时候,也需要对hashCode方法进行重写,
以此来保证这两个方法的一致性——
当equals返回true的时候,这两个对象一定有相同的hashcode.
在这里插入图片描述

所以这个题的答案应该是否定的,但是得搞清楚里面的原委

29. 垃圾回收的优点和原理。并考虑2种回收机制。

  • 与C语言开发人员需要手动进行内存资源的释放不同,Java提供垃圾回收机制,自动进行GC,将开发人员从容易犯错的内存资源管理中解放出来。

  • 原理:当某个一个对象,没有任何引用指向它的时候,那么它就满足垃圾回收的条件,在适当的时候,JVM虚拟机进行GC将其回收,释放空间,以供后续再利用。

  • 两种常见的回收机制:

  1. 定时回收
    每隔30分钟进行一次回收,这种机制的弊端是如果垃圾产生的比较快,有可能30分钟之内垃圾已经把内存占用光了,导致性能变慢

  2. 当垃圾占到某个百分比的时候,进行回收
    比如,当垃圾占到70%的时候,进行回收。 这种机制的弊端是,如果垃圾产生的频率很快,那么JVM就必须高频率的进行垃圾回收。 而在垃圾回收的过程中, JVM会停顿下来,只做垃圾回收,而影响业务功能的正常运行。

  • 一般说来 JVM会采用两种机制结合的方式进行垃圾回收。

30. 你所知道的集合类都有哪些?主要方法?

  • 常见的集合
    ArrayList,LinkedList,HashSet,HashMap,TreeSet 等等
    常见方法:
    size()
    add()
    remove()等等

31. char型变量中能不能存贮一个中文汉字?为什么?

char是16位的,占两个字节
汉字通常使用GBK或者UNICODE编码,也是使用两个字节
所以可以存放汉字

32. 解析XML文档有哪几种方式?

主要是两种,SAX和DOM
SAX 就是逐行读取,直到找到目标数据为止
DOM 是先全文档加载,然后读取

33. 关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?

  • throws 用在方法声明上面,表示该方法有可能抛出某个异常
private static void method2() throws FileNotFoundException {
	File f = new File("d:/LOL.exe");
 	System.out.println("试图打开 d:/LOL.exe");
    new FileInputStream(f);
    System.out.println("成功打开");
    }
  • throw 抛出一个指定的异常,throw通常都出现在方法体内。
public void attackHero(Hero h) throws EnemyHeroIsDeadException{
        if(h.hp == 0){
            throw new EnemyHeroIsDeadException(h.name + " 已经挂了,不需要施放技能" );
        }
    }
  • throws与throw这两个关键字接近,不过意义不一样,有如下区别:
  1. throws 出现在方法声明上,而throw通常都出现在方法体内。
  2. throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某个异常对象。
  • try catch 在try中有可能会抛出某个异常,一旦某个异常抛出后,就会在catch中进行捕捉,他俩一般说来都是成对出现的。

  • finally: 表示无论是否捕捉住异常,都会执行

34. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?

在这里插入图片描述

可以包括多个类,但是只能出现一个public修饰的类,但是可以出现多个非public修饰的类。

35. java中有几种类型的流?

在这里插入图片描述

Java中所有的流都是基于字节流,所以最基本的流是

  • 输入输出字节流
    InputStream
    OutputStream
  • 在字节流的基础上,封装了字符流
    Reader
    Writer
  • 进一步,又封装了缓存流
    BufferedReader
    PrintWriter
  • 以及数据流
    DataInputStream
    DataOutputStream
  • 对象流
    ObjectInputStream
    ObjectOutputStream

以及一些其他的奇奇怪怪的流 ~~~

36. java中会存在内存泄漏吗,请简单描述。

  • 因为Java是自动进行垃圾回收管理的,所以不存在 C语言中同等概念的内存泄漏.
  • 在C++中,所有被分配了内存的对象,不再使用后,都必须程序员手动的释放他们。所以,每个类,都会含有一个析构函数,作用就是完成清理工作,如果我们忘记了某些对象的释放,就会造成内存泄露。
  • 但是存在Java特色的内存泄漏,但是在Java中,我们不用(也没办法)自己释放内存,无用的对象由GC自动清理,这也极大的简化了我们的编程工作。但,实际有时候一些不再会被使用的对象,在GC看来不能被释放,就会造成内存泄露。
  • 当某些对象不被使用,但是又有非直接引用指向的时候,那么就不满足垃圾回收的条件,而形成内存泄漏。
  • 比如代码中的例子,每个Object创建的时候,有一个引用o指向,接着就被放进了集合al中。 下一个Object创建的时候,上一个Object就没有引用指向了。
  • 这些Object都没有引用指向,但是却放在ArrayList中,而这个Arraylist忘记了回收,那么里面的所有对象,都会一直存活下去,虽然不再被使用了。
package j2se;
import java.util.ArrayList;
public class MemoryLeak {
	static ArrayList<Object> al = new ArrayList<Object>();
	public static void main(String[] args) {
		for (int i = 0; i < 100; i++) {
			Object o = new Object();
			al.add(o);
		}
	}
}

解决办法:这里要解决很简单,手动赋值为null即可:

package j2se;
import java.util.ArrayList;
public class MemoryLeak {
	static ArrayList<Object> al = new ArrayList<Object>();
	public static void main(String[] args) {
		for (int i = 0; i < 100; i++) {
			Object o = new Object();
			al.add(o);
			o = null;
		}
	}
}

37. java中实现多态的机制是什么?

  • Java实现多态有三个必要条件:继承、重写、向上转型。
  • 多态就是指一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
  • 因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
  • 特点:
  1. 指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。
  2. 若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。

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

静态变量 直接通过类就可以访问,无需实例
实例变量 比如通过类的某个具体实例,才可以访问
在jvm层面来说,在初始化你阶段,clinit方法会收集所有类变量的赋值动作

39. 什么是java序列化,如何实现java序列化?

序列化指的是把一个Java对象,通过某种介质进行传输,比如Socket输入输出流,或者保存在一个文件里
实现java序列化的手段是让该类实现接口 Serializable,这个接口是一个标识性接口,没有任何方法,仅仅用于表示该类可以序列化。

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

不行,因为非static方法需要一个具体的实例才可以调用,而调用 static方法的时候,不一定存在一个实例

41 . 在JAVA中,如何跳出当前的多重嵌套循环?

在外部循环的前一行,加上标签
在break的时候使用该标签
即能达到结束多重嵌套循环的效果

public class HelloWorld {
    public static void main(String[] args) {
        //打印单数     
        outloop: //outloop这个标示是可以自定义的比如outloop1,ol2,out5
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                System.out.println(i+":"+j);
                if(0==j%2)  
                    break outloop; //如果是双数,结束外部循环
            }
        }
    }
}

42. List、Map、Set三个接口,存取元素时,各有什么特点?

List 是有顺序的,并且可以重复
Set 是无序的,不可以重复
Map 保存数据的方式是键值对

43. Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以 implements(实现)interface(接口)?

匿名内部类本质上就是在继承其他类,实现其他接口

如例:

package j2se;
public class HelloWorld {
    public static void main(String[] args) {
        // 匿名类1
        new Thread() {
            public void run() {
            }
        };
        // 匿名类2
        new Runnable() {
            public void run() {
            }
        };
    }
}

匿名类1,就是继承了Thread
匿名类2 ,就是实现了Runnable接口

44. 内部类可以引用外部类的成员吗?有没有什么限制?

可以使用
如果是非静态内部类,可以使用外部类的所有成员
如果是静态内部类,只能使用外部类的静态成员

45. 多线程有几种实现方法,都是什么?

通常来讲,Java 创建一个线程有三种方式

  1. 继承一个Thread类
  2. 实现Runnable接口
  3. 匿名内部类
  4. 详细请参考 Java 创建一个线程的三种方式

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

首先sleep和wait之间没有任何关系

sleep 是Thread类的方法,指的是当前线程暂停。
Thread.sleep(1000); 表示当前线程暂停1000毫秒 ,其他线程不受影响
Thread.sleep(1000); 会抛出InterruptedException 中断异常,因为当前线程sleep的时候,有可能被停止,这时就会抛出 InterruptedException

 
public class TestThread {
    public static void main(String[] args) {
        Thread t1= new Thread(){
            public void run(){
                int seconds =0;
                while(true){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.printf("已经玩了LOL %d 秒%n", seconds++);
                }              
            }
        };
        t1.start();
    }
     
}

wait 是Object类的方法, 指的占用当前对象的线程临时释放对当前对象的占用,以使得其他线程有机会占用当前对象。 所以调用wait方法一定是在synchronized 中进行

47. 说出数据连接池的工作机制是什么?

数据库连接池原理:
因为创建连接和关闭连接的行为是非常耗时的,会显著降低软件的性能表现。解决办法就是先创建n条数据库连接Connection,循环使用,但是不进行关闭,这样再执行SQL语句,就不需要额外创建连接了,直接使用现成的连接就可以了,从而节约了创建连接和关闭连接的时间开销。

48. 简述synchronized和java.util.concurrent.locks.Lock的异同 ?

  1. Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现,Lock是代码层面的实现。

  2. Lock可以选择性的获取锁,如果一段时间获取不到,可以放弃。synchronized不行,会一根筋一直获取下去。 借助Lock的这个特性,就能够规避死锁,synchronized必须通过谨慎和良好的设计,才能减少死锁的发生。

  3. synchronized在发生异常和同步块结束的时候,会自动释放锁。而Lock必须手动释放, 所以如果忘记了释放锁,一样会造成死锁。

49. Class.forName的作用?为什么要用?

Class.forName常见的场景是在数据库驱动初始化的时候调用。

Class.forName本身的意义是加载类到JVM中。 一旦一个类被加载到JVM中,它的静态属性就会被初始化,在初始化的过程中就会执行相关代码,从而达到"加载驱动的效果"

50. 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法

这要看情况而定,如果该对象的其他方法也是有synchronized修饰的,那么其他线程就会被挡在外面。否则其他线程就可以进入其他方法。

51. 给我五个你最常见到的runtime exception。

  • NullPointerException 空指针异常
  • ArithmeticException 算术异常,比如除数为零
  • ClassCastException 类型转换异常
  • ConcurrentModificationException 同步修改异常,遍历一个集合的时候,删除集合的元素,就会抛出该异常
  • IndexOutOfBoundsException 数组下标越界异常
  • NegativeArraySizeException 为数组分配的空间是负数异常

猜你喜欢

转载自blog.csdn.net/qq_43925089/article/details/107708019