一、Java基础
JDK 、 JRE 、JVM有什么区别和联系?
这三者的关系是:一层层的嵌套关系。JDK>JRE>JVM。 |
== 和 equals 的区别是什么?
篇幅限制下面就只能给大家展示小册部分内容了。这份面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取
== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用; equals 默认情况下是引用比较,只是很多类重写了 equals 方法,比如 String、Integer 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等 |
两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
答案是 不一定! hashCode()相等的两个对象他们的equal()不一定相等。 equal()相等的两个对象他们的hashCode()肯定相等。 |
final 在 java 中有什么作用?
final作为Java中的关键字可以用于三个地方。用于修饰类、类属性和类方法。 特征:凡是引用final关键字的地方皆不可修改! (1)修饰类:表示该类不能被继承; (2)修饰方法:表示方法不能被重写; (3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。 |
Java的基础类型有哪些?String属于基础的数据类型吗?
基本数据类型:(共有8种) 整型:byte,short,int,long;长度分别为1,2,4,8; 浮点型:float,double;长度分别为 4,8; 字符型:char;长度为 2; 布尔型:boolean;长度为 1。 注:除了以上8种数据类型,剩下的全部都是引用数据类型(strintg属于引用类型)。 |
java 中操作字符串都有哪些类?它们之间有什么区别?
String、StringBuffer、StringBuilder String :是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象。 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。 StringBuffer线程安全,同步锁(synchronized),多线程仍可以保证数据安全 StringBuilder线程不安全,多线程无法保证数据安全 |
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) | 得到指定内容最后一次出现的下标 |
如何将字符串反转?
-
public static String reverse4(String s) {
-
return new StringBuffer(s).reverse().toString();
-
}
接口和抽象类有哪些区别?
抽象类是什么: 抽象类不能创建实例,它只能作为父类被继承。抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为其子类的模板,从而避免了子类的随意性。 如果一个类中有抽象方法则这个类一定是抽象类 抽象类中的方法不一定是抽象方法 抽象类不不能使用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调用步骤大致可以分为以下四步:
|
Files的常用方法都有哪些?
|
二、容器
java 容器都有哪些?
JAVA中的容器类主要分为两大类,一类是Map类,一类是Collection类,他们有一个共同的父接口Iterator,它提供基本的遍历,删除元素操作。Iterator还有一个子接口LinkIterator,它提供双向的遍历操作。 |
Collection 和 Collections 有什么区别?
Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。 Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。 |
List、Set、Map 之间的区别是什么?
List:有序集合、元素可重复;ArrayList基于数组实现的有序集合可以存储多个null;LinkedList基于链表实现的有序集合可以存储多个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. |
HashMap 和 Hashtable 有什么区别?
篇幅限制下面就只能给大家展示小册部分内容了。这份面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取
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 方法
-
public static void testArray2List() {
-
String[] strs = new String[] {"aaa", "bbb", "ccc"};
-
List<String> list = Arrays.asList(strs);
-
for (String s : list) {
-
System.out.println(s);
-
}
-
}
List 转数组,使用 List 的toArray方法。无参toArray方法返回Object数组,传入初始化长度的数组对象,返回该对象
-
public static void testList2Array() {
-
List<String> list = Arrays.asList("aaa", "bbb", "ccc");
-
String[] array = list.toArray(new String[list.size()]);
-
for (String s : array) {
-
System.out.println(s);
-
}
-
}
ArrayList 和 Vector 的区别是什么?
|
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 怎么使用?有什么特点?
-
public class TestIterator {
-
static List<String> list = new ArrayList<String>();
-
static {
-
list.add("111");
-
list.add("222");
-
list.add("333");
-
}
-
public static void main(String[] args) {
-
testIteratorNext();
-
System.out.println();
-
testForEachRemaining();
-
System.out.println();
-
testIteratorRemove();
-
}
-
//使用 hasNext 和 next遍历
-
public static void testIteratorNext() {
-
Iterator<String> iterator = list.iterator();
-
while (iterator.hasNext()) {
-
String str = iterator.next();
-
System.out.println(str);
-
}
-
}
-
//使用 Iterator 删除元素
-
public static void testIteratorRemove() {
-
Iterator<String> iterator = list.iterator();
-
while (iterator.hasNext()) {
-
String str = iterator.next();
-
if ("222".equals(str)) {
-
iterator.remove();
-
}
-
}
-
System.out.println(list);
-
}
-
//使用 forEachRemaining 遍历
-
public static void testForEachRemaining() {
-
final Iterator<String> iterator = list.iterator();
-
iterator.forEachRemaining(new Consumer<String>() {
-
public void accept(String t) {
-
System.out.println(t);
-
}
-
});
-
}
-
}
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仅能遍历,不能修改。 |
怎么确保一个集合不能被修改?
篇幅限制下面就只能给大家展示小册部分内容了。这份面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取
1. Collections. unmodifiableCollection(Collection c) 方法 |
-
List<Integer> list = new ArrayList<>();
-
list.add(1);
-
list.add(2);
-
list.add(3);
-
Collection<Integer> readOnlyList = Collections.unmodifiableCollection(list);
-
readOnlyList.add(4); // 会报错
2. 使用Arrays.asList创建的集合 |
-
List<Integer> integers = Arrays.asList(11, 22, 33, 44);
-
integers.add(55);
三、多线程
并行和并发有什么区别?
你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。 你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。 你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。 并发的关键是你有处理多个任务的能力,不一定要同时。 并行的关键是你有同时处理多个任务的能力。 所以我认为它们最关键的点就是:是否是『同时』。 |
线程和进程的区别?
1、首先是定义 进程:是执行中一段程序,即一旦程序被载入到内存中并准备执行,它就是一个进程。进程是表示资源分配的的基本概念,又是调度运行的基本单位,是系统中的并发执行的单位。 线程:单个进程中执行中每个任务就是一个线程。线程是进程中执行运算的最小单位。 2、一个线程只能属于一个进程,但是一个进程可以拥有多个线程。多线程处理就是允许一个进程中在同一时刻执行多个任务。 3、线程是一种轻量级的进程,与进程相比,线程给操作系统带来侧创建、维护、和管理的负担要轻,意味着线程的代价或开销比较小。 |
守护线程是什么?
守护线程(即daemon thread),是个服务线程,准确地来说就是服务其他的线程,这是它的作用——而其他的线程只有一种,那就是用户线程。所以java里线程分2种, 1、守护线程,比如垃圾回收线程,就是最典型的守护线程。 2、用户线程,就是应用程序里的自定义线程。 |
创建线程有哪几种方式?
主要有三种: 继承 Thread 重写 run 方法; 实现Runnable接口,重写 run 方法; 实现Callable接口,通过FutureTask包装器来创建Thread线程。 实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。 |