一、Java 基础
1.JDK 和 JRE 有什么区别?
jdk:java development kit
jre:java runtime Environment
jdk是面向开发人员的,是开发工具包,包括开发人员需要用到的一些类。
jre是java运行时环境,包括java虚拟机等,是提供给使用java的人用的
2.== 和 equals 的区别是什么?
==比较的是两个对象,包括对象的地址位,如果比较的两个对象地址位不同,值相同也会返回false
equals比较的是两个字符串的值,只要值相同,就会返回true
3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
不对,hashCode也是可以重写的,所以不一定。
反之,如果equals()相同,那么hashCode是一定相等的。
4.final 在 java 中有什么作用?
修饰类不可被继承;
修饰方法不可被重写;
修饰变量不能被修改。
篇幅限制下面就只能给大家展示小册部分内容了。这份面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取
5.JAVA 中的 Math.round(-1.5) 等于多少?
-1
向上取整Math.ceil();
向下取整Math.floor();
四舍五入Math.round(x); //==Math.floor(x+0.5)
6.String 属于基础的数据类型吗?
不属于,是final修饰的Java类。
java中的基本数据类型:byte、char、short、int、long、float、double、boolean
7.java 中操作字符串都有哪些类?它们之间有什么区别?
String、StringBuffer、StringBuilder
String类型的字符串是不可变的,StringBuffer和StringBuilder是可以对同一个对象做更新操作的
StringBuffer是线程安全的,StringBuilder不是线程安全的。
8.String str="i"与 String str=new String("i")一样吗?
不一样。他们不是同一个对象
前者如果定义多个变量都为相同值的话,会共用同一个地址,创建的对象应该放在了常量池中;
后者是创建了一个新的对象,放在的是堆内存中。
9.如何将字符串反转?
使用StringBuffer 或 StringBuilder 的 reverse 成员方法。
10.String 类的常用方法都有那些?
"".toCharArray("");
"".charAt();
"".split();
"".indexOf();
"".equals();
"".contains();
"".length();
"".subString("");
"".replace("","");
11.抽象类必须要有抽象方法吗?
不是。抽象类可以没有抽象方法,但是如果你的一个类已经声明成了抽象类,即使这个类中没有抽象方法,它也不能再实例化,即不能直接构造一个该类的对象。如果一个类中有了一个抽象方法,那么这个类必须声明为抽象类,否则编译通不过。
12.普通类和抽象类有哪些区别?
普通类可以被继承,不能包含抽象方法,不可以被实现。
抽象类也可被继承,但是子类必须要实现父类中的抽象方法;
抽象类中的方法不能包含主体。
抽象类中的方法在扩展性和延伸性要比普通类的更好;
抽象类可以应用多态,普通类不可以。
13.抽象类能使用 final 修饰吗?
不能。
14.接口和抽象类有什么区别?
接口是要被实现的,抽象类是要被继承;
接口用interface修饰;抽象类使用abstract修饰;
两者均不能被实例化,方法都不包含主体;
一个类只能继承一个抽象类,但是可以实现多个接口。
15.java 中 IO 流分为几种?
字节流:InputStream、OutputStream
字符流:Reader、Writer
字节流是最基本的
1.字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串;
2.字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。
读文本的时候用字符流,例如txt文件。读非文本文件的时候用字节流,例如mp3。
16.BIO、NIO、AIO 有什么区别?
BIO:Block IO 同步阻塞式 IO
NIO:Non IO 同步非阻塞 IO
AIO:Asynchronous IO 异步非阻塞IO
BIO是一个连接一个线程。JDK4之前的唯一选择
NIO是一个请求一个线程。JDK4之后开始支持,常见聊天服务器
AIO是一个有效请求一个线程。JDK7之后开始支持,常见相册服务器
17.Files的常用方法都有哪些?
file.getName();
file.getPath();
file.delete();
file.exits();
file.createDirectory();
file.copy();
file.move();
file.size();
file.read();
file.write();
18.重写和重载的区别
重载:必须有不同的参数列表;可以有不同的访问修饰符;可以抛出不同的异常;
重写:参数列表必须要与被重写的相同;返回的类型必须保持一致;修饰符和抛出的异常不能在被重写的方法之外
重写是父类与子类的关系,是垂直关系;重载是同一个类方法中的关系,是水平关系。
19.什么是多态
一种事物的多种表现形态就是多态,比如定义一个类为动物,那么动物可以被子类继承,从而实现具体动物的方法。
二、容器
1.java 容器都有哪些?
数组、Util下的容器:Collection(Set、List)、Map
2.Collection 和 Collections 有什么区别?
Collection是集合的接口,其实现类有List和Set;
Collections是工具类,包含许多有关集合操作的静态多态方法,可以直接使用。
3.List、Set、Map 之间的区别是什么?
List:有序集合、元素可重复
Set:元素不可重复,HashSet无序,LinkedHashSet按照插入排序,SortedSet可排序
Map:键值对集合,存储键、值之间的映射。key无序,唯一,value可重复
4.HashMap 和 Hashtable 有什么区别?
HashMap不是线程安全的,HashTable是线程安全的
HashMap允许Null Key和Null Value,HashTable不允许
5.如何决定使用 HashMap 还是 TreeMap?
如果需要得到一个有序的结果应该使用TreeMap
如果不需要排序最好选用HashMap,性能更优
6.说一下 HashMap 的实现原理?
HashMap基于Hash算法实现,通过put(key,value)存储,get(key)来获取value
当传入key时,HashMap会根据key,调用Hash(Object key)方法,计算出Hash值,根据Hash值将Value保存在Node对象里,Node对象保存在数组里。
当计算出的Hash值相同时,称为Hash冲突,HashMap的做法是用链表和红黑树存储相同Hash值的value
当Hash冲突的个数:小于等于8使用链表,大于8使用红黑树解决链表查询慢的问题。
7.说一下 HashSet 的实现原理?
HashSet是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,因此HashSet的操作相对比较简单,相关HashSet的操作,基本上都是直接调用底层的HashMap的相关方法来完成,HashSet不允许有重复的值,并且元素是无序的
8.ArrayList 和 LinkedList 的区别是什么?
ArrayList的数据结构是动态数组;LinkedList的数据结构是双向链表。
ArrayList比LinkedList在随机访问的时候效率要高,因为LinkedList是线性的数据结构,需要依次往后查找
在非首尾的增删操作,LinkedList要比ArrayList的效率要高,因为ArrayList在操作增删时要影响其他元素的下标
总结:需要频繁读取集合中的元素时,推荐使用ArrayList;插入和删除操作较多时,推荐使用LinkedList
9.如何实现数组和 List 之间的转换?
List转数组:String[] list = List.toArray(array);//array为List
数组转List:List list = java.util.Arrays.asList(array);//array为数组
10.ArrayList 和 Vector 的区别是什么?
相同点:都实现了List接口,都是有序集合
区别:Vector是线程安全的,ArrayList不是线程安全的;
当Vector或ArrayList中的元素超过它的初始大小时,Vector会将容量翻倍,而ArrayList只会将容量扩大50%
11.Array 和 ArrayList 有何区别?
Array类型的变量在声明时必须实例化;ArrayList可以只是先声明;
Array大小是固定的,而ArrayList的大小是动态变化的;
Array可以包含基本类型和对象类型,ArrayList只能包含对象类型
12.在 Queue 中 poll()和 remove()有什么区别?
Queue中poll()和remove()都是用来从队列头部删除一个元素;
在队列元素为空的情况下,remove()方法会抛出NoSuchElementException异常,而poll()只会返回null
13.哪些集合类是线程安全的?
- Vector:相比ArrayList多了线程安全;
- HashTable:相比HashMap多了线程安全;
- ConcurrentHashMap:高效且线程安全;
- Stack:继承于Vector,也是线程安全
14.迭代器 Iterator 是什么?
迭代器是一种设计模式,它是一个对象,可以遍历并选择序列中的对象。
15.Iterator 怎么使用?有什么特点?
next();
hashNext();
remove();
Iterator接口被Collection接口继承,Collection接口的iterator()方法返回一个iterator对象。
16.Iterator 和 ListIterator 有什么区别?
ListIterator有add()方法,可以向List中添加对象,而Iterator不能;
ListIterator有hasPrevious()和previous()方法,可以向前遍历,Iterator不能;
ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现;
ListIterator可以实现对对象的修改,使用set()实现;而Iterator只能遍历,不能修改
17.怎么确保一个集合不能被修改?
可以使用Collections.unmodifiableCollection(Collection c) 方法创建一个只读集合
这样改变集合的任何操作都会抛出Java. lang. UnsupportedOperationException异常。
三、多线程
1.并行和并发有什么区别?
并行是指两个或多个事件在同一时刻发生,是在不同实体上的多个事件;
并发是指两个或多个事件在同一时间间隔发生,是在同一个实体上的多个事件
2.线程和进程的区别?
进程是资源分配最小单位,线程是程序执行最小单位
每个进程都有相应的线程
进程有独立的地址空间,线程没有
线程是指处理机调度的基本单位
进程执行开销大,线程执行开销小
3.守护线程是什么?
在java线程开发中,有两种线程:User Thread(用户线程);Daemon Thread(守护线程)
普通用户进程在JVM退出时依然会继续执行,导致JVM并不能退出
普通进程可以使用setDaemon(true)方法升级为守护进程,守护进程在JVM退出时会自动结束运行。
守护线程拥有自动结束自己生命周期的特性,而非守护线程不具备这个特点
4.创建线程有哪几种方式?
继承Thread类并实现run方法,调用继承类的start方法开启线程;
通过实现Runnable接口,重写run方法,调用线程对象的start方法开启线程;
除此之外,还可以通过实现Callable接口,实现call方法,并用FutureTask类包装Callable对象开启线程。
5.说一下 runnable 和 callable 有什么区别?
实现Callable接口的任务线程能返回执行结果,而实现Runnable接口的任务线程并不能返回执行结果
Callable接口的call方法允许抛出异常,而Runnable接口的run方法的异常只能在内部消化,不能继续上抛
6.线程有哪些状态?
新建、就绪、运行、阻塞、死亡
7.sleep() 和 wait() 有什么区别?
sleep后程序不会释放同步锁,wait后程序会释放同步锁
sleep可以指定睡眠时间,自动唤醒,wait可以直接用notify唤醒
sleep的类是Thread,wait的类是Object
8.notify()和 notifyAll()有什么区别?
notify()方法会唤醒对象等待池中的一个线程,进入锁池;
notifyAll()方法会唤醒等待池中的所有线程,进入锁池
9.线程的 run()和 start()有什么区别?
调用start()方法是用来启动线程的,轮到该线程执行时,会自动调用run方法;
直接运行run方法无法达到启动多线程的目的,相当于调用Thread对象中的run方法
一个线程的start方法只能调用一次,多次调用会抛出异常;而run方法可以多次调用
10.创建线程池有哪几种方式?
主要使用Excutors提供的通用线程池创建方法,去创建不同配置的线程池
newCachedThreadPool();特点:用来处理大量短时间工作任务的线程池
newFixedThreadPool(int nThreads);特点:重用指定数目(nThreads)的线程
newSingleThreadExecutor();特点:工作线程数目限制为1
newSingleThreadScheduledExecutor()和newScheduledThreadPool(int corePoolSize)可以进行周期或定时性的工作调度
newWorkStealingPool(int parallelism);特点:JDK8以后才加入
11.线程池都有哪些状态?
RUNNING:线程池被创建,可以接收新线程
SHUTDOWN:线程池被关闭,不接收新线程,但是可以处理已有的线程。通过调用shutdown()方法;
STOP:线程池停止,不接受新线程,中断当前的线程,并且不会处理已有的线程。通过调用shutdownnow()方法;
TIDYING:线程池等待,当线程池处于SHUTDOWN或者STOP状态,并且任务队列为空且执行中任务为空则会转变;
TERMINATED:线程池彻底终止,线程池在TIDYING状态中执行完terminated()方法后就会转变为此状态。
12.线程池中 submit()和 execute()方法有什么区别?
execute() 参数 Runnable ;submit() 参数 (Runnable) 或 (Runnable 和 结果 T) 或 (Callable)
execute() 没有返回值;而 submit() 有返回值
submit()的返回值Future调用get方法时,可以捕获处理异常
13.在 java 程序中怎么保证多线程的运行安全?
JDK Atomic开头的原子类、synchronized、LOCK,可以解决原子性问题
synchronized、volatile、LOCK,可以解决可见性问题
Happens-Before 规则可以解决有序性问题
14.多线程锁的升级原理是什么?
锁的级别:无锁 => 偏向锁 => 轻量级锁 => 重量级锁
无锁:没有对资源进行锁定,所有线程都可以访问,但是只有一个能修改成功,其他的线程会不断尝试,直至修改成功。
偏向锁:对象的代码一直被同一线程执行,不存在多个线程竞争,偏向锁,指的就是偏向第一个加锁线程,该线程不会主动释放偏向锁,只有当其他线程尝试竞争偏向锁时才会被释放。
偏向锁的撤销,需要在某个时间点上没有字节码正在执行时,先暂停拥有偏向锁的线程,然后判断锁对象是否处于被锁定状态。如果线程不处于活动状态,则将对象头设置成无锁状态,并撤销偏向锁;
如果线程处于活动状态,升级为轻量级锁的状态。
轻量级锁:轻量级锁是指当锁是偏向锁的时候,被第二个线程 B 所访问,此时偏向锁就会升级为轻量级锁,线程 B 会通过自旋的形式尝试获取锁,线程不会阻塞,从而提高性能。当前只有一个等待线程,则该线程将通过自旋进行等待。但是当自旋超过一定的次数时,轻量级锁便会升级为重量级锁;当一个线程已持有锁,另一个线程在自旋,而此时又有第三个线程来访时,轻量级锁也会升级为重量级锁。
重量级锁:指当有一个线程获取锁之后,其余所有等待获取该锁的线程都会处于阻塞状态。
15.什么是死锁?
死锁是指两个或两个以上的进程在竞争资源的过程中造成的不可解堵塞。两个线程都在互相等待。
16.怎么防止死锁?
预防:资源一次性分配;可剥夺资源;资源有序分配;超时放弃
避免:银行家算法;
检测:为每个进程和每个资源建立唯一的ID,建立资源分配表和进程等待表
解除:剥夺资源;撤销进程
17.ThreadLocal 是什么?有哪些使用场景?
ThreadLocal是线程本地存储,在每个线程中都创建了一个ThreadLocalMap对象,每个线程可以访问自己内部ThreadLocal对象内的value。
经典的使用场景是为每个线程分配一个JDBC连接的Connection,这样就可以保证每个线程都在各自的Connection上进行数据库的操作,不会出现A线程关了B线程的Connection,还有Session管理等问题。