概述
是面试题也是技能点
对常见面试题的回答提供参考
网络资源搜集
仅供个人学习使用
后端技术
JavaSE
Java基础
1.JDK和 JRE的区别(简述题)
-
JDK:Java Development Kit 的简称,Java开发工具包,提供了Java的开发环境和运行环境。
-
JRE:Java Runtime Environment 的简称,Java运行环境,为Java的运行提供了所需环境。
具体来说JDK其实包含了JRE,同时还包含了编译Java源码的编译器javac,还包含了很多Java程序调试和分析的工具。简单来说:如果你需要运行Java程序,只需安装JRE即可,如果你需要编写Java程序,需要安装JDK。
2.==与equals的区别(简述题)
==解读
对于基本类型和引用类型==的作用效果是不同的:
-
基本类型:比较的是值是否相同;
-
引用类型:比较的是引用是否相同。
String x = "string";
String y = "string";
String z = new String("string");
System.out.println(x==y); // true
System.out.println(x==z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true
代码解读:因为x和y指向的是同一个引用,所以是 true,而new String()方法则重新开辟了内存空间,所以结果为 false,而equals比较的一直是值,所以结果都为 true。
equals解读
equals本质上就是==,只不过String和Integer等重写了equals方法,把它变成了值比较。
3.Java基本类型与引用类型(简述题)
基本数据类型:Java中一共分为8种基本数据类型,byte、short、int、long、float、double、char、boolean。其中byte、short、int、long是整型;float、double是浮点型;char是字符型;boolean是布尔型。
引用类型:Java为每种基本类型都提供了对应的封装类型,分别为:Byte、Short、Integer、Long、Float、Double、Character、Boolean。引用类型是一种对象类型,它的值是指向内存空间的引用,就是地址。
4.String属于基本数据类型吗?(简述题)
string不属于基本类型,基本类型有8种:byte、short、int、long、float、double、char、boolean,而String属于对象。
5.基本类型与引用类型的区别(简述题)
-
默认值:整型byte、short、int、long的默认值都为0,浮点型float、double的默认值为0.0,boolean默认值为false,char默认值为空。对应的包装类型默认值都为null。
-
内存分配:基本数据类型的变量是存储在栈内存中,而引用类型变量存储在栈内存中,保存的是实际对象在堆内存中的地址,实际对象保存这内容。
-
自动装箱、自动拆箱:Java从jdk1.5开始引入自动装箱和拆箱,使得基本数据类型与引用类型之间相互转换变得简单。
**自动装箱:**Java自动将原始类型转化为引用类型的过程,自动装箱时编译器会调用valueOf方法,将原始类型转化为对象类型。
**自动拆箱:**Java自动将引用类型转化为原始类型的过程,自动拆箱时编译器会调用intValue(),doubleVlue()这类的方法将对象转换成原始类型值。
6.final在Java中的作用?(简述题)
-
final修饰的类叫最终类,该类不能被继承。
-
final修饰的方法不能被重写。
-
final修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。
7.Java中操作字符串都有哪些类,它们之间有什么区别?(简述题)
操作字符串的类有:String、StringBuffer、StringBuilder。
String和StringBuffer、StringBuilder的区别在于String声明的是不可变的对象,每次操作都会生成新的String对象,然后将指针指向新的String对象,而StringBuffer、StringBuilder可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用String。
StringBuffer和SringBuilder最大的区别在于,StringBuffer是线程安全的,而StringBuilder是非线程安全的,但是StringBuilder的性能却高于StringBuffer,所以在单线程环境下推荐使用StringBuilder,多线程环境下推荐使用StringBuffer。
8.String类的常用方法都有哪些?(简述题)
-
indexOf() - 返回指定字符的索引
-
charAt() - 返回指定索引处的字符
-
replace() - 字符串替换
-
trim() - 去除字符串两端的空白
-
split() - 分割字符串,返回一个分割后的字符串数组
-
getBytes() - 返回字符串的byte类型数组
-
length() - 返回字符串长度
-
toLowerCase() - 将字符串转成小写字母
-
toUpperCase() - 将字符串转成大写字母
-
substirng() - 截取字符串
-
equals() - 字符串比较
9.请你讲讲Java支持的数据类型有哪些?什么是自动拆装箱?(简述题)
Java语言支持8种基本数据类型:byte、short、int、long、float、double、boolean、char
自动装箱是Java编译器在基本数据类型和对应的对象包装类型之间做的一个转化。比如:把int转化成Integer,double转化成Double等等。反之就是自动拆箱。
10.可以将布尔值与整数进行比较吗?(单选题)
A.可以 B.不可以
会报错
11.谈谈对Java package(包)的理解?(简述题)
为了更好地组织类,Java提供了包机制,用于区别类名的命名空间。
包的作用
① 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
② 如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名是不同的,不同包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
③ 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。
12.JDK类库中有哪些包?(简述题)
JDK类库中的包,最高一级的包名是java和javax。
-
java.lang:提供利用 Java 编程语言进行程序设计的基础类,例如:String、Math、Integer、System和Thread等。
-
java.util:java工具类,包含对集合的操作、事件模型、日期和时间设施、国际化和各种实用工具类。
-
java.io:通过数据流、序列化和文件系统提供系统输入和输出。
-
java.net:为实现网络应用程序提供类。
-
java.awt:包含用于创建用户界面和绘制图形图像的所有类。
13.基本的Java语言函数存储在一下那个Java包中?(单选题)
A.java.lang B.java.io C.java.net D.java.util
java.lang包含:
-
包装类
-
String类
-
Math类 ------包含函数
-
Class类
-
Object类
14.Java支持多继承吗?(简述题)
Java中类不支持多继承,只支持单继承(即一个类只有一个父类)。但是Java中的接口支持多继承,即一个子接口可以有多个父接口。(接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,当类实现接口时,类就扩展了相应的功能)。
【例如】
-
Java类的单继承:
class B extends classA
-
Java接口多继承:
interface3 extends interface1,interface2
15.java中数组有没有length()方法?String中有没有length()方法?(简述题)
数组没有length()这个方法,有length属性。String有length()方法。
int[] arr = {
1,2,3,4,5,6};
int arrLength = arr.length;//数组长度
String str = "hello";
int strLength = str.length();//字符串长度
16.重载(Overload)和重写(Override)的区别?(简述题)
方法的重载和重写都是实现多态的方式,区别在于重载实现的是编译时的多态性,而重写实现的是运行时的多态性。
-
重载:发生在同一个类中,方法名相同参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和修饰符无关,即重载的方法不能根据返回类型进行区分。
-
重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类,注意的是如果方法访问修饰符为private则子类中就不是重写。
17.构造器是否可以被重写?(简述题)
构造器不能被重写(Override),但是可以被重载(Overload)。(重载是发生在同一个类中,方法名相同,参数列表不同。重写是发生在父子类中,方法名和参数列表都相同。)
18.是否可以继承String类?(简述题)
String 类是final类,不可以被继承。
19.数组有几种初始化方式(简述题)
静态初始化
int[] a1 = {
10,20,30};
动态初始化
int[] a2 = new int[3];
20.是否可以继承 String 类?(简述题)
String 类是final类,不可以被继承。
21.&和&&的区别?(简述题)
&运算符有两种用法:(1)按位与;(2)逻辑与。
&&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true整个表达式的值才是true。&&之所以称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式会被直接短路掉,不会进行运算。很多时候我们可能都需要用&&而不是&,例如在验证用户登录时判定用户名不是null而且不是空字符串,应当写为:username != null &&!username.equals(""),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。
22.JDK1.8 新特性有哪些?(简述题)
-
引入了lambda表达式,可以简化匿名内部类的代码,允许将方法作为参数。
-
方法引用,可以进一步简化lambda表达式的书写,可以引用类的构造方法,静态方法,特定类的方法和某个对象的方法。
-
可以在接口中使用default定义默认方法和静态方法,引入默认方法方便了接口升级的维护,之前如果在接口中新增一个方法必须修改所有实现类。
-
引入了stream类,支持链式编程,为集合类和数组提供了一些方便的操作方法,例如filter、skip、limit和map、concat等。
-
可以通过类型自动推测泛型参数。
-
允许重复使用注解,扩大了注解的使用范围,可以用在局部变量和泛型,方法异常上。
-
入了Optional类解决空指针异常,更新了日期类的API等。
23. &和&&的区别?(简述题)
&运算符有两种用法:(1)按位与;(2)逻辑与。**
24.JDK1.8新特性有哪些 ?(简述题)
- 引入了lambda表达式,可以简化匿名内部类的代码,允许将方法作为参数。
- 方法引用,可以进一步简化lambda表达式的书写,可以引用类的构造方法,静态方法,特定类的方法和某个对象的方法。
- 可以在接口中使用default定义默认方法和静态方法,引入默认方法方便了接口升级的维护,之前如果在接口中新增一个方法必须修改所有实现类。
- 引入了stream类,支持链式编程,为集合类和数组提供了一些方便的操作方法,例如filter、skip、limit和map、concat等。
- 可以通过类型自动推测泛型参数。
- 允许重复使用注解,扩大了注解的使用范围,可以用在局部变量和泛型,方法异常上。
- 入了Optional类解决空指针异常,更新了日期类的API等。
25. 阐述静态变量和实例变量的区别?(简述题)
静变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。
补充:在Java开发中,上下文类和工具类中通常会有大量的静态成员。
26. Java语言采用何种编码方案?有何特点?(简述题)
Java语言采用Unicode编码标准,Unicode(标准码),它为每个字符制订了一个唯一的数值,因此在任何的语言,平台,程序都可以放心的使用。
Java集合
1.List、Set、Map是否继承自Collection接口?(简述题)
List、Set 是,Map 不是。
Map是键值对映射容器,与List和Set有明显的区别,而Set存储的零散的元素且不允许有重复元素(数学中的集合也是如此),List是线性结构的容器,适用于按数值索引访问元素的情形。
2.Collection和Collections 有什么区别?(简述题)
-
java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承有List、Set、Queue。
-
Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,对于对集合元素进行排序、搜索以及线程安全等各种操作。
3.如何实现数组和List之间的转换?(简述题)
-
List转换成为数组:调用ArrayList的toArray方法。
-
数组转换成为List:调用Arrays的asList方法。
4.Java集合类框架的基本接口有哪些?(简述题)
总共有两大接口:Collection和Map,一个元素集合,一个是键值对集合;其中List和Set接口继承了Collection接口,一个是有序元素集合,一个是无序元素集合;而ArrayList和LinkedList实现了List接口,HashSet实现了Set接口,这几个都比较常用;HashMap和HashTable实现了Map接口,并且HashTable是线程安全的,但是HashMap性能更好。
5.如何决定使用HashMap还是TreeMap?(简述题)
对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的Collection的大小,也许向HashMap中添加元素会更快,将Map换为TreeMap进行有序key的遍历。
6.请讲讲数组(Array)和列表(ArrayList)的区别?什么时候应该使用Array而不是ArrayList?(简述题)
Array 和 ArrayList 的不同点:
-
Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
-
Array大小是固定的,ArrayList的大小是动态变化的。
-
ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
对于基本类型数据,集合使用自动装配箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。
7.怎么给List排序?(简述题)
使用List自身的sort方法,或者使用Collections.sort(list)方法;
8.List是线程安全的吗?如果要使线程安全怎么做?(简述题)
List中的Vector才是线程安全的。
其他要实现线程安全使用工具类:Collections.synchronizedList(new ArrayList())方法。
9.List、Set、Map之间的区别是什么?(简述题)
比较 | List | Set | Map |
---|---|---|---|
继承接口 | Collection | Collection | |
常见实现类 | AbstractList(其常用子类有ArrayList、LinkedList、Vector) | AbstractSet(其常用子类有HashSet、LinkedHashSet、TreeSet) | HashMap、Hashtable |
常见方法 | add()、remove()、clear()、get()、contains()、size() | add()、remove()、clear()、contains()、size() | put()、get()、remove()、clear()、containsKey()、containsValue()、keySet()、values()、size() |
元素 | 可重复 | 不可重复(用equals()判断) | 不可重复 |
顺序 | 有序 | 无序(实际上由HashCode决定) | |
线程安全 | Vector线程安全 | HashTable线程安全 |
10.HashMap和Hashtable有什么区别?(简述题)
-
HashMap 去掉了Hashtable 的 contains方法,但是加上了containsValue() 和 containsKey() 方法。
-
Hashtable 是同步的,而HashMap 是非同步的,但是效率上比Hashtable要高。
-
HashMap 允许空键值,而Hashtable不允许。
11.ArrayList和Vector的区别是什么?(简述题)
-
Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。
-
ArrayList比Vector快,它是异步,不会过载。
-
ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。
Java多线程
1.并行和并发有什么区别?(简述题)
-
并行是指两个或者多个事件在同一时刻发生;并发是指两个或多个事件在同一时间间隔发生。
-
并行是在不同实体上的多个事件,并发是在同一个实体上的多个事件。
-
在一台处理器上“同时”处理多个任务,在多台处理器上同时处理多个任务。如hadoop分布式集群。
所以并发编程的目标是充分的利用处理器的每一个核,以达到最高的处理性能。
2.线程和进程的区别?(简述题)
简而言之,进程是程序运行和资源分配的基本单元,一个程序至少有一个进程,一个进程至少有一个线程。进程在执行过程中拥有独立的内存单元,而多个线程共享内存资源,减少切换次数,从而效率更高。线程是进程的一个实体,是CPU调度和分派的基本单位,是比程序更小的能独立运行的基本单位。同一进程中的多个线程之间可以并发执行。
3.守护线程是什么?(简述题)
守护线程(即daemon thread),是个服务线程,准确地来说就是服务其他的线程。
4.创建线程有哪几种方式?(简述题)
①.继承Thread类创建线程类
-
定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。
-
创建Thread子类的实例,即创建了线程对象。
-
调用线程对象的start()方法来启动线程。
②通过Runnable接口创建线程类
-
定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
-
创建Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
-
调用线程对象的start()方法来启动该线程。
③通过Callable和Future创建线程
-
创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
-
创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
-
使用FutureTask对象作为Thread对象的target创建并启动新线程。
-
调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。
5.线程有哪些状态?(简述题)
线程通常都有五种状态,创建、就绪、运行、阻塞和死亡。
-
创建状态:在生成线程对象,并没有调用该对象的start()方法,这是线程处于创建状态。
-
就绪状态:当调用了线程对象的start()方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。
-
阻塞状态:线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。
-
死亡状态:如果一个线程的run()方法执行结束或者调用stop()方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start()方法令其进入就绪。
Java流与文件
1.Java中IO流分为几种?(简述题)
-
按功能来分:输入流(input)、输出流(output)
-
按类型来分:字节流、字符流
2.字节流和字符流的区别?(简述题)
-
字节流按8位传输以字节为单位输入输出数据
-
字符流按16位传输以字符为单位输入输出数据
3.Files的常用方法都有哪些?(简述题)
- Files.exists():检测文件路径是否存在
- Files.createFile():创建文件
- Files.createDirectory():创建文件夹
- Files.delete():删除一个文件或目录
- Files.copy():复制文件
- Files.move():移动文件
- Files.size():查看文件个数
- Files.read():读取文件
- Files.write():写入文件
4.BIO、NIO、AIO有