CSDN全套Java面试题(面试必备)

一、Java基础

JDK 、 JRE 、JVM有什么区别和联系?
  1. JDK :英文名称(Java Development Kit),Java 开发工具包。jdk 是整个 Java 开发的核心,它集成了 jre 和一些好用的小工具。例如:javac.exe,java.exe,jar.exe 等。
  2. JRE :英文名称(Java Runtime Environment),Java 运行时环境。它主要包含两个部分,jvm 的标准实现和 Java 的一些基本类库。它相对于 jvm 来说,多出来的是一部分的 Java 类库。
  3. JVM :英文名称(Java Virtual Machine),就是我们耳熟能详的 Java 虚拟机。它只认识 xxx.class 这种类型的文件,它能够将 class 文件中的字节码指令进行识别并调用操作系统向上的 API 完成动作。所以说,jvm 是 Java 能够跨平台的核心,具体的下文会详细说明。

这三者的关系是:一层层的嵌套关系。JDK>JRE>JVM。

== 和 equals 的区别是什么?

== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用

equals 默认情况下是引用比较,只是很多类重写了 equals 方法,比如 String、Integer 等把它变成了值比较,所以一般情况下 equals 比较的是是否相等

两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

答案是 不一定!

hashCode()相等的两个对象他们的equal()不一定相等。

equal()相等的两个对象他们的hashCode()肯定相等。
final 在 java 中有什么作用?

final作为Java中的关键字可以用于三个地方。用于修饰、类属性和类方法

特征:凡是引用final关键字的地方皆不可修改!

(1)修饰类:表示该类不能被继承;

(2)修饰方法:表示方法不能被重写;

(3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。
Java的基础类型有哪些?String属于基础的数据类型吗?

基本数据类型:(共有8种)

整型:byteshortintlong;长度分别为1,2,4,8;

浮点型:floatdouble;长度分别为 4,8;

字符型:char;长度为 2;

布尔型:boolean;长度为 1。

注:除了以上8种数据类型,剩下的全部都是引用数据类型(strintg属于引用类型)。
java 中操作字符串都有哪些类?它们之间有什么区别?

StringStringBufferStringBuilder

String :是不可变的对象,每次操作都会生成的 String 对象,然后将指针指向新的 String 对象。

StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。

StringBuffer线程安全,同步锁(synchronized),多线程仍可以保证数据安全

StringBuilder线程不安全,多线程无法保证数据安全

篇幅限制下面就只能给大家展示小册部分内容。给大家整理了一份核心的面试题包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

 需要全套面试笔记的【点击此处即可】即可免费获取

String str="i"与 String str=new String(“i”)一样吗?

答:不一样

因为内存的分配方式不一样。String str="i"的方式,Java 虚拟机会将其分配到常量池中;而 String str=new String(“i”)方式,则会被分到堆内存中。
String 类的常用方法都有那些?

和长度有关

返回类型

方法名

作用

int

length()

得到一个字符串的字符个数

和数组有关

返回类型

方法名

作用

byte[]

getByte()

将一个字符串转换成字节数组

char[]

toCharArray()

将一个字符串转换成字符数组

String[]

split(String)

将一个字符串按照指定内容分割开

和判断有关

返回类型

方法名

作用

boolean

equals()

判断两个字符串的内容是否一样

boolean

equalsIsIgnoreCase(String)

忽略太小写的比较两个字符串的内容是否一样

boolean

contains(String)

判断一个字符串里面是否包含指定的内容

和改变内容有关

返回类型

方法名

作用

String

toUpperCase()

将一个字符串全部转换成大写

String

toLowerCase()

将一个字符串全部转换成小写

String

replace(String,String)

将某个内容全部替换成指定内容

String

substring(int,int)

从下标x截取到下标y-1对应的元素

String

trim()

去除一个字符串的前后空格

和位置有关

返回类型

方法名

作用

char

charAt(int)

得到指定下标位置对应的字符

int

indexOf(String)

得到指定内容第一次出现的下标

int

lastIndexOf(String)

得到指定内容最后一次出现的下标

如何将字符串反转?
 
  1. public static String reverse4(String s) {

  2. return new StringBuffer(s).reverse().toString();

  3. }

接口和抽象类有哪些区别?

抽象类是什么:

抽象类不能创建实例,它只能作为父类被继承。抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为其子类的模板,从而避免了子类的随意性。

如果一个类中有抽象方法则这个类一定是抽象类

抽象类中的方法不一定是抽象方法

抽象类不不能使用final修饰  抽象类是用于被继承的,final修饰的类不可修改,不可继承

(1)抽象类可以有构造方法,接口中不能有构造方法。

(2)抽象类中可以有普通成员变量,接口中没有普通成员变量

(3)抽象类中可以包含静态方法,接口中不能包含静态方法

(4) 一个类可以实现多个接口,但只能继承一个抽象类。

(5)接口可以被多重实现,抽象类只能被单一继承

(6)如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法
java 中 IO 流分为几种?

IO流的分类

(1)按照数据的流向:

输入流、输出流

(2)按照流数据的格式:

字符流、字节流

(3)按照流数据的包装过程:

节点流(低级流)、处理流(高级流)

最基本的几种进行简单介绍

•InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。

•OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

IO流图表

BIO、NIO、AIO 有什么区别?

BIO (Blocking I/O):同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。这里使用那个经典的烧开水例子,这里假设一个烧开水的场景,有一排水壶在烧开水,BIO的工作模式就是, 叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。

NIO (New I/O):同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞I/O模式来说明,那么什么叫做同步非阻塞?如果还拿烧开水来说,NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。

AIO ( Asynchronous I/O):异步非阻塞I/O模型。异步非阻塞与同步非阻塞的区别在哪里?异步非阻塞无需一个线程去轮询所有IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。对应到烧开水中就是,为每个水壶上面装了一个开关,水烧开之后,水壶会自动通知我水烧开了。

进程中的IO调用步骤大致可以分为以下四步:

  1. 进程向操作系统请求数据 ;
  2. 操作系统把外部数据加载到内核的缓冲区中;
  3. 操作系统把内核的缓冲区拷贝到进程的缓冲区 ;
  4. 进程获得数据完成自己的功能 ;
  5. 当操作系统在把外部数据放到进程缓冲区的这段时间(即上述的第二,三步),如果应用进程是挂起等待的,那么就是同步IO,反之,就是异步IO,也就是AIO 。
Files的常用方法都有哪些?
  • Files. exists():检测文件路径是否存在。
  • Files. createFile():创建文件。
  • Files. createDirectory():创建文件夹。
  • Files. delete():删除一个文件或目录。
  • Files. copy():复制文件。
  • Files. move():移动文件。
  • Files. size():查看文件个数。
  • Files. read():读取文件。
  • Files. write():写入文件。

二、容器

java 容器都有哪些?
JAVA中的容器类主要分为两大类,一类是Map类,一类是Collection类,他们有一个共同的父接口Iterator,它提供基本的遍历,删除元素操作。Iterator还有一个子接口LinkIterator,它提供双向的遍历操作。
Collection 和 Collections 有什么区别?

Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。

Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。
List、Set、Map 之间的区别是什么?

List有序集合、元素可重复ArrayList基于数组实现的有序集合可以存储多个nullLinkedList基于链表实现的有序集合可以存储多个null

Set无序集合、元素不可重复LinkHashSet按照插入排序可以存储一个null-------SortSet可排序----------HashSet无序可以存储一个null

Map键值对集合、储存键、值和之间的映射,Key无序,唯一Value不要求有序,允许重复。hashmap 、linkedhashmap  key与value均可以为null.  treemap  key不可以为null,value可以为null.  hashtable、concurrenthashmap key与value均不能为null.

 篇幅限制下面就只能给大家展示小册部分内容。给大家整理了一份核心的面试题包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

 需要全套面试笔记的【点击此处即可】即可免费获取

HashMap 和 Hashtable 有什么区别?

HashMap允许键和值是null,而Hashtable则不允许键或者值是null。

Hashtable是同步的,而HashMap不是,所以HashMap更适用于单线程环境,Hashtable则适用于多线程环境。
如何决定使用 HashMap 还是 TreeMap?
如果你需要得到一个有序的结果时就应该使用TreeMap(因为HashMap中元素的排列顺序是不固定的)。除此之外,由于HashMap有更好的性能,所以大多不需要排序的时候我们会使用HashMap。
说一下 HashMap 、HashSet的实现原理?

HashMap 的实现原理:

HashMap是基于Hash算法实现的,

我们通过put(key,value)存储数据,通过get(key)来获取数据

当传入key时,HashMap会根据Key.hashCode()计算出Hash值,根据Hash值将value保存在bucket里 。

当计算出相同的Hash值时,我们称之为Hash冲突,HashMap 的做法是用链表和红黑树存储相同Hash值的value,

当hash冲突的个数比较少时,使用链表存储,

否则使用红黑树。

HashSet 的实现原理:

HashSet是基于HashMap实现的,HashSet 底层使用HashMap来保存所有元素,

因此HashSet 的实现比较简单,相关HashSet 的操作,基本上都是直接调用底层HashMap的相关方法来完成,HashSet不允许有重复的值,并且元素是无序的。
ArrayList 和 LinkedList 的区别是什么?

数据结构实现

ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。

随机访问效率

ArrayList 比 LinkedList 在随机访问的时候效率要高,因为 LinkedList 是线性的数据存储方式,所以需要移动指针从前往后依次查找。

增加和删除效率

在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高,因为 ArrayList 增删操作要影响数组内的其他数据的下标。

  综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用 LinkedList
如何实现数组和 List 之间的转换?

数组转 List ,使用 JDK 中 java.util.Arrays 工具类的 asList 方法

 
  1. public static void testArray2List() {

  2. String[] strs = new String[] {"aaa", "bbb", "ccc"};

  3. List<String> list = Arrays.asList(strs);

  4. for (String s : list) {

  5. System.out.println(s);

  6. }

  7. }

List 转数组,使用 List 的toArray方法。无参toArray方法返回Object数组,传入初始化长度的数组对象,返回该对象

 
  1. public static void testList2Array() {

  2. List<String> list = Arrays.asList("aaa", "bbb", "ccc");

  3. String[] array = list.toArray(new String[list.size()]);

  4. for (String s : array) {

  5. System.out.println(s);

  6. }

  7. }

ArrayList 和 Vector 的区别是什么?
  • Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。
  • vector是线程(Thread)同步(Synchronized)的,所以它也是线程安全的,而Arraylist是线程异步(ASynchronized)的,是不安全的。如果不考虑到线程的安全因素,一般用Arraylist效率比较高。
如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长度的50%.如过在集合中使用数据量比较大的数据,用vector有一定的优势。
Array 和 ArrayList 有何区别?
  • Array类型的变量在声明的同时必须进行实例化(至少得初始化数组的大小),而ArrayList可以只是先声明。(int[] array = new array[3];或 int[] array = {1,2,3};)
  • Array只能存储同构的对象,而ArrayList可以存储异构的对象。同构的对象是指类型相同的对象,若声明为int[]的数组就只能存放整形数据,string[]只能存放字符型数据,但声明为object[]的数组除外。而ArrayList可以存放任何不同类型的数据
  • Array是始终是连续存放的,而ArrayList的存放不一定连续。
  • Array对象的初始化必须只定指定大小,且创建后的数组大小是固定的,而ArrayList的大小可以动态指定,其大小可以在初始化时指定,也可以不指定,也就是说该对象的空间可以任意增加。
  • Array不能够随意添加和删除其中的项,而ArrayList可以在任意位置插入和删除项。
在 Queue 中 poll()和 remove()有什么区别?
队列的两种实现方式
1、offer()和add()的区别
add()和offer()都是向队列中添加一个元素。但是如果想在一个满的队列中加入一个新元素,调用 add() 方法就会抛出一个 unchecked 异常,而调用 offer() 方法会返回 false。可以据此在程序中进行有效的判断!
2、peek()和element()的区别
peek()和element()都将在不移除的情况下返回队头,但是peek()方法在队列为空时返回null,调用element()方法会抛出NoSuchElementException异常。
3、poll()和remove()的区别
poll()和remove()都将移除并且返回对头,但是在poll()在队列为空时返回null,而remove()会抛出NoSuchElementException异常。
哪些集合类是线程安全的?

Vector

Stack

Hashtable

java.util.concurrent包下所有的集合类

   ArrayBlockingQueue、ConcurrentHashMap、ConcurrentLinkedQueue、ConcurrentLinkedDeque...
迭代器 Iterator 是什么?

迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

Java中的Iterator功能比较简单,并且只能单向移动:

(1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。

(2) 使用next()获得序列中的下一个元素。

(3) 使用hasNext()检查序列中是否还有元素。

(4) 使用remove()将迭代器新返回的元素删除。

Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。
Iterator 怎么使用?有什么特点?
 
  1. public class TestIterator {

  2. static List<String> list = new ArrayList<String>();

  3. static {

  4. list.add("111");

  5. list.add("222");

  6. list.add("333");

  7. }

  8. public static void main(String[] args) {

  9. testIteratorNext();

  10. System.out.println();

  11. testForEachRemaining();

  12. System.out.println();

  13. testIteratorRemove();

  14. }

  15. //使用 hasNext 和 next遍历

  16. public static void testIteratorNext() {

  17. Iterator<String> iterator = list.iterator();

  18. while (iterator.hasNext()) {

  19. String str = iterator.next();

  20. System.out.println(str);

  21. }

  22. }

  23. //使用 Iterator 删除元素

  24. public static void testIteratorRemove() {

  25. Iterator<String> iterator = list.iterator();

  26. while (iterator.hasNext()) {

  27. String str = iterator.next();

  28. if ("222".equals(str)) {

  29. iterator.remove();

  30. }

  31. }

  32. System.out.println(list);

  33. }

  34. //使用 forEachRemaining 遍历

  35. public static void testForEachRemaining() {

  36. final Iterator<String> iterator = list.iterator();

  37. iterator.forEachRemaining(new Consumer<String>() {

  38. public void accept(String t) {

  39. System.out.println(t);

  40. }

  41. });

  42. }

  43. }

     篇幅限制下面就只能给大家展示小册部分内容。给大家整理了一份核心的面试题包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

     需要全套面试笔记的【点击此处即可】即可免费获取

Iterator 和 ListIterator 有什么区别?

一.相同点

都是迭代器,当需要对集合中元素进行遍历不需要干涉其遍历过程时,这两种迭代器都可以使用。

二.不同点

1.使用范围不同,Iterator可以应用于所有的集合,Set、List和Map和这些集合的子类型。而ListIterator只能用于List及其子类型。

2.ListIterator有add方法,可以向List中添加对象,而Iterator不能。

3.ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator不可以。

4.ListIterator可以定位当前索引的位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。

5.都可实现删除操作,但是ListIterator可以实现对象的修改,set()方法可以实现。Iterator仅能遍历,不能修改。
怎么确保一个集合不能被修改?
1. Collections. unmodifiableCollection(Collection c) 方法
 
  1. List<Integer> list = new ArrayList<>();

  2. list.add(1);

  3. list.add(2);

  4. list.add(3);

  5. Collection<Integer> readOnlyList = Collections.unmodifiableCollection(list);

  6. readOnlyList.add(4); // 会报错

2. 使用Arrays.asList创建的集合
 
  1. List<Integer> integers = Arrays.asList(11, 22, 33, 44);

  2. integers.add(55);

三、多线程

并行和并发有什么区别?

你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。

你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。

你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。

并发的关键是你有处理多个任务的能力,不一定要同时。

并行的关键是你有同时处理多个任务的能力。

所以我认为它们最关键的点就是:是否是『同时』。
线程和进程的区别?

1、首先是定义

进程:是执行中一段程序,即一旦程序被载入到内存中并准备执行,它就是一个进程。进程是表示资源分配的的基本概念,又是调度运行的基本单位,是系统中的并发执行的单位。

线程:单个进程中执行中每个任务就是一个线程。线程是进程中执行运算的最小单位。

2、一个线程只能属于一个进程,但是一个进程可以拥有多个线程。多线程处理就是允许一个进程中在同一时刻执行多个任务。

3、线程是一种轻量级的进程,与进程相比,线程给操作系统带来侧创建、维护、和管理的负担要轻,意味着线程的代价或开销比较小。
守护线程是什么?

守护线程(即daemon thread),是个服务线程,准确地来说就是服务其他的线程,这是它的作用——而其他的线程只有一种,那就是用户线程。所以java里线程分2种,

1、守护线程,比如垃圾回收线程,就是最典型的守护线程。

2、用户线程,就是应用程序里的自定义线程。
创建线程有哪几种方式?

主要有三种:

    继承 Thread 重写 run 方法;

    实现Runnable接口,重写 run 方法;

实现Callable接口,通过FutureTask包装器来创建Thread线程。

    实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。
说一下 Runnable 和 Callable 有什么区别?

1、两者最大的不同点是:实现Callable接口的任务线程能返回执行结果;而实现Runnable接口的任务线程不能返回结果

2、Callable接口的call()方法允许抛出异常;而Runnable接口的run()方法的异常只能在内部消化,不能继续上抛;

Callable接口支持返回执行结果,此时需要调用FutureTask.get()方法实现,此方法会阻塞主线程直到获取‘将来’结果;当不调用此方法时,主线程不会阻塞!
线程有哪些状态?

1、新建状态(New):新创建了一个线程对象。

2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取CPU的使用权

   即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。

3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。

4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。

   阻塞的情况分三种:

①.等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,

   必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒,

②.同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。

③.其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时,或者I/O处理完毕时,线程重新转入就绪状态。

5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
sleep() 和 wait() 有什么区别?

sleep:Thread类中定义的方法,表示线程休眠,会自动唤醒;

  wait:Object中定义的方法,需要手工调用notify()或者notifyAll()方法。

  sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

  sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。
notify()和 notifyAll()有什么区别?

notify()和notifyAll()都是用来用来唤醒调用wait(方法进入等待锁资源队列的线程,区别在于:

notify()

唤醒正在等待此对象监视器的单个线程。 如果有多个线程在等待,则选择其中一个随机唤醒(由调度器决定),唤醒的线程享有公平竞争资源的权利

notifyAll()

唤醒正在等待此对象监视器的所有线程,唤醒的所有线程公平竞争资源
线程的 run()和 start()有什么区别?
  1. start()方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码;
  2. run()方法当作普通方法的方式调用,程序还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码;
创建线程池有哪几种方式?

java中创建线程池的方式一般有两种:

    通过Executors工厂方法创建

通过new ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)自定义创建
线程池都有哪些状态?

线程池的生命周期,总共有五种状态

    RUNNING :能接受新提交的任务,并且也能处理阻塞队列中的任务;

    SHUTDOWN:关闭状态,不再接受新提交的任务,但却可以继续处理阻塞队列中已保存的任务。在线程池处于 RUNNING 状态时,调用 shutdown()方法会使线程池进入到该状态。(finalize() 方法在执行过程中也会调用shutdown()方法进入该状态);

    STOP:不能接受新任务,也不处理队列中的任务,会中断正在处理任务的线程。在线程池处于 RUNNING 或 SHUTDOWN 状态时,调用 shutdownNow() 方法会使线程池进入到该状态;

    TIDYING:如果所有的任务都已终止了,workerCount (有效线程数) 为0,线程池进入该状态后会调用 terminated() 方法进入TERMINATED 状态。

    TERMINATED:在terminated() 方法执行完后进入该状态,默认terminated()方法中什么也没有做。

进入TERMINATED的条件如下:线程池不是RUNNING状态;

              线程池状态不是TIDYING状态或TERMINATED状态;

     如果线程池状态是SHUTDOWN并且workerQueue为空;

              workerCount为0;

              设置TIDYING状态成功。
线程池的生命周期流程图
 线程池中 submit()和 execute()方法有什么区别?

1、接收的参数不一样。exucute只能执行实现Runnable接口的线程,submit可以执行实现Runnable接口或Callable接口的线程

2、submit有返回值,而execute没有
在 java 程序中怎么保证多线程的运行安全?

线程的安全性问题体现在:

    原子性:一个或者多个操作在 CPU 执行的过程中不被中断的特性

    可见性:一个线程对共享变量的修改,另外一个线程能够立刻看到

    有序性:程序执行的顺序按照代码的先后顺序执行

导致原因:

    缓存导致的可见性问题

    线程切换带来的原子性问题

    编译优化带来的有序性问题

解决办法:

    JDK Atomic开头的原子类、synchronized、LOCK,可以解决原子性问题

    synchronized、volatile、LOCK,可以解决可见性问题

    Happens-Before 规则可以解决有序性问题

Happens-Before 规则如下:

    程序次序规则:在一个线程内,按照程序控制流顺序,书写在前面的操作先行发生于书写在后面的操作

    管程锁定规则:一个unlock操作先行发生于后面对同一个锁的lock操作

    volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个变量的读操作

    线程启动规则:Thread对象的start()方法先行发生于此线程的每一个动作

    线程终止规则:线程中的所有操作都先行发生于对此线程的终止检测

    线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生

    对象终结规则:一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始

多线程锁的升级原理是什么?

锁的级别从低到高:

无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁
偏向锁轻量级锁轻量级锁
适用场景只有一个线程进入同步块虽然很多线程,但是没有冲突:多条线程进入同步块,但是线程进入时间错开因而并未争抢锁

发生了锁争抢的情况:多条线程进入同步块并争用锁

本质取消同步操作CAS操作代替互斥同步互斥同步
优点不阻塞,执行效率高(只有第一次获取偏向锁时需要CAS操作,后面只是比对ThreadId)不会阻塞

不会空耗CPU

缺点适用场景太局限。若竞争产生,会有额外的偏向锁撤销的消耗长时间获取不到锁空耗阻塞,上下文切换,重量级操作,消耗操作系统资源

 篇幅限制下面就只能给大家展示小册部分内容。给大家整理了一份核心的面试题包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

 需要全套面试笔记的【点击此处即可】即可免费获取

什么是死锁?怎么防止死锁?
什么是死锁?
所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。
死锁产生的4个必要条件?
  • 互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。
  • 请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。
  • 不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。
环路等待条件:在发生死锁时,必然存在一个进程--资源的环形链。
解决死锁的基本方法
  • 资源一次性分配:一次性分配所有资源,这样就不会再有请求了:(破坏请求条件)
  • 只要有一个资源得不到分配,也不给这个进程分配其他的资源:(破坏请保持条件)
  • 可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件)
资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)
  感谢信是一个与招聘团队联系的最有力工具。为了体现你的真诚可信,你需要对每个成员分别表达你的谢意,要避免千篇一律的内容。尝试把重点放在与面试你的每个人的交流方面。   值得大家思考的是:求职者,特别是很多资深人士要牢记这些集体的决策者,因为从长远观点来看,这样做是值得的 *************************************************** end start ************************ 毕业生如何顺利通过面试关2008-06-04 13:11参加面试是求职者应聘的重要环节。求职者要在应聘面试中取得成功,就要了解到,用人单位的招聘原则是在适合本单位某项工作要求的前提下找到优秀的人选,即“最合适、最优秀”原则。为此,应聘者不但要在面试中展示自己的优秀才华和素质,还要让面试考官认为自己是最适合该单位该工作的。不同的用人单位有不同的用人标准和要求,但是优秀的用人单位总是在“诚实、正直、踏实、合作、潜力、技能”等方面有大体一致的要求。这些基本素质和技能不仅体现于个人的求职材料,还体现于应聘面试的方方面面。 一、着装得体 根据季节需要着装,尤其是一些小细节,比如说,衣襟是否平整,纽扣是否系全等,都不能忽视,如果穿着凌乱,不注意小节,用人单位会因此联想到毕业生今后的工作态度也会不认真、不严谨,会给用人单位留下不好的印象。 二、做到知己知彼 应聘面试要知己知彼。“知己”,就是充分分析自己的职业倾向和实力,做好职业定位和职业选择,要有目的去应聘。“知彼”的内容主要有:首先须了解用人单位和所求职位的情况,还要熟悉该单位招聘面试的特点和程序,了解用人单位的名称、产品、经营情况、企业文化、用人理论等。 三、做好心理准备 毕业生一定要轻松自信把握机会,其实面试就是考核毕业生的心理素质,如果自己都有给自己自信,那如何能面对考官的质疑,一定要相信自己能行。应聘面试的心理准备包括:首先要有一颗平常心。心情越平静,越有利于发挥个性与才干。其次,要培养自己的信心。对应聘面试要在战略上重视,战术上藐视,要相信,既然自己有面试的机会就证明自己有优势把能力和知识展示出来。再者,要有抗挫折的心理准备。即使这次不成功,还有其他的机会,决不能因这一次面试失败就心灰意冷,失去信心。最后,要调节好自己的心情。心情会影响你给人的第一印象,所以愉快的心情也能感染面试者。 四、准备几个问题 面试主要是考察毕业生对单位和职位的了解程度、毕业生的专业知识和技能,以及他们的社会意识、综合素质、敬业精神等。所以在谈话和提问式的面试中,总有一些问题是面试者常常提问的,例如:“简单地自我介绍”、“为什么要应聘这个职位”、“你认为你为什么能胜任这个工作”、“你能不能举两个例子来证明你刚才所说的能力和素质”、 “你的优势劣势有哪些”、“你期望的工作是什么样子的,你是如何为自己设计职业生涯的”等等。所以要根据所了解的情况和自身情况对回答进行精心准备与设计。 五、掌握应答技巧 应答是应聘面试的重头戏,面试者要掌握面试应答技巧。  1、发音清楚掌握节奏 面试时要注意发音清楚,掌握节奏。在回答考官的问题时,毕业生讲话的声音要以坐得最远的考官能够清楚地听到你的回答为标准,讲话节奏快慢以考官能够完整地听清你的含义,略有思考为标准,毕业生应多加练习,面试时注意掌握情况,视情况而定。   2、保持诚信 其实说到底,面试就是要向企业展现最优秀的自己,这其中没有捷径,更不存在投机取巧,诚实是唯一的技巧。求职者千万不要心存侥幸,在简历中灌水,肆意吹嘘自己的能力和经验,须知企业的招考官阅人无数,早已炼就识珠慧眼,加之兼备胜任力模型和行为面谈法,任何夸大和不实都无处遁形。即便是通过了面试这关,求职者在日后的实习工作当中也难免会因为能力不济而原形毕露,大吃苦头。 3、应对得体 很多初涉职场的求职者在见到面试官时都表现得精神紧张,手足无措,做出许多下意识的动作,比如不停的搓手,玩弄小饰物,转笔,抖动双脚,不敢抬头,眼神游离等,殊不知正是这些细微的动作出卖了你紧张的内心,给面试官留下胆怯失措、唯唯诺诺的印象,其面试结果也可想而知。正确的方式应该是平稳自己的情绪,端正自己的坐姿,敢于与面试官进行眼神交流,在倾听对方讲话时将身体略微前倾,让对方感受到你对工作的重视及诚意。声音保持平稳洪亮,清晰流畅的表达自己的所思所想,展现自己的风采特长。 4、礼仪细节 还有一些求职者不太注重职场礼仪,认为这些细微琐碎的事情无关痛痒,然而这些细节往往会影响到面试的成绩。面试时自觉敲门,并主动向面试官问好、握手或鞠躬致敬,面试时坐
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值