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
equals本质上就是==只不过String与包装类重写了equals的方法,将其从比较两个对象的地址变成比较两个对象的内容,也就是值。
解读:x与y是指向字符串常量池中相同的字符串的指针,即x与y的地址相同,而z指向堆中开辟的新的内存空间,所以x与y相同而x与z不同,而用equals比较的是值是否相等,而明显x、y、z的值全都相同,所以x调用equals函数去比较y与z之后得出的结果都为true。
代码示例:
class Cat {
public Cat(String name) {
this.name = name;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Cat c1 = new Cat("王磊");
Cat c2 = new Cat("王磊");
System.out.println(c1.equals(c2)); // false
为什么结果会是false?
代码示例:
public boolean equals(Object obj) {
return (this == obj);
}
查看源码之后可以知道,对象比较原理是都是调用== ,而两个对象实在堆中开辟了两块内存地址不同,所以结果为false。
然而如果利用引用数据类型String的话上述的结果即为true,这是为什么?
代码示例:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
查看String的源码就知道,Java的开发者将String的equals函数重写了,使其比较字符串中的值,所以可知结果。所以启示我们自己创建类的时候一般都要重写equals方法。
3、两个对象的hashCode()相同那么equals也一定为true,对吗?
不对,两个对象的hashCode()相同只能说明这两个对象键值对的哈希值相同,然而两个对象的哈希值相同并不能不能说明这两个对象的键值对相同。而两个键值对相同才说明值相同
用下面的代码验证一下:
代码示例:
String str1 = "通话";
String str2 = "重地";
System. out. println(String. format("str1:%d | str2:%d", str1. hashCode(),str2. hashCode()));
System. out. println(str1. equals(str2));
执行结果:
str1:1179395 | str2:1179395
false
4、final在Java中有什么作用?
- final修饰的类叫最终类,该类不能被继承
- final修饰的方法不能被重写,但是能被重载
- final修饰的变量叫做常量,常量必须初始化,初始化之后值就不能被修改
5、Java中Math.round(-1.5)等于多少?
结果为-1。因为-1.5 + 0.5 = -1 然后向下取整,最后结果为-1。
拓展:Math类的静态方法round(value)的计算方式为:[value + 0.5] ([]表示向下取整)
6、String属于基础的数据类型吗?
不属于,Java的基础数据类型包括byte、short、int、long、float、double、boolean、char,String属于引用数据类型
7、Java中操作字符串都有哪些类?他们之间有什么区别?
操作字符串的类有String、StringBuffer、StringBuilder。
String与StringBuffer、StringBuilder之间的区别为String声明的是不可变的对象,每次操作都会生成新的String对象,然后指针指向新的String对象,而StringBuffer、StringBuilder可以在原有对象的基础上进行操作,所以有经常改变字符串内容的时候最好不要用String。
而StringBuffer与StringBuilder的区别在于,StringBuffer是线程安全的,而StringBuilder是非线程安全的,但是StringBuilder的性能却高于StringBuffer,所以单线程中经常使用StringBuilder,而多线程程序中一般推荐使用StringBuffer。
8、String str = “i” 与 String str = new String("i")一样吗?
不一样,使用String str = "i"的方式的话,JVM会将其分配到常量池中,而使用String str = new String(“i”)的方式的话则会被分到堆内存中
9、如何将字符串反转?
使用StringBuilder或者StringBuffer的reverse()方法
// StringBuffer reverse
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("abcdefg");
System.out.println(stringBuffer.reverse()); // gfedcba
// StringBuilder reverse
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("abcdefg");
System.out.println(stringBuilder. reverse()); // gfedcba
10、String类的常用方法有哪些?
- indexOf():返回指定字符的索引
- charAt():返回指定索引处的字符
- replace():字符串替换
- trim():去除字符串两端空白
- split():分割字符串,返回分割后的字符串数组
- getBytes:返回字符串的byte类型的数组
- length():返回字符串的长度
- toLowerCase():将字符串全部转成小写字母
- toUpperCase():将字符串全部转成大写字母
- substring():截取字符串
- equals():字符串比较
11、抽象类必须要有抽象方法吗?
不需要,抽象类并不一定需要抽象方法
代码示例:
abstract class Cat {
public static void sayHi() {
System. out. println("hi~");
}
}
上述代码为抽象类,但是完全可以运行
12、普通类和抽象类的区别?
- 普通类中不能有抽象方法,而抽象类中可以有抽象方法
- 抽象类不能直接实例化,普通类可以实例化
13、抽象类使用final修饰吗?
- 不能,因为定义抽象类就是让其他类继承,如果定义为final则该类就不能被继承,这样彼此会产生矛盾,所以final不能修饰抽象类
14、接口和抽象类有什么区别?
- 实现:抽象类的子类必须使用extends来继承,而类必须使用implements来实现接口
- 构造函数:抽象类可以有构造函数;接口不能有。
- 实现数量:类可以实现很多接口;但是只能继承一个抽象类
- 访问修饰符:接口中的方法默认使用public修饰;
15、Java中IO流分为几种?
- 按功能来分:输入流(Input)、输出流(Output)
- 按照类型来分:字节流与字符流。
- 字节流与字符流的区别:字节流按8位传输以字节为单位输入输出数据,字符流按16位传输以字符为单位输入输出设备
16、BIO、NIO、AIO有什么区别?
- BIO:Block IO 同步阻塞式IO,就是我们平常使用的传统IO,它的特点是模式简单使用方便,并发处理能力低。
- NIO:Non IO 同步非阻塞IO,是传统IO的升级,客户端和服务器端通过Channel(通道)通讯,实现多路复用
- AIO:Asynchronous IO是NIO的升级,也叫NIO2,实现异步非阻塞IO,异步IO的操作基于事件和回调机制。
17、Files的常用方法有哪些?
- Files.exists() :检测文件路径是否存在。
- Files.createFile():创建文件。
- Files.createDirectory():创建文件夹。
- Files.delete():删除一个文件或者目录。
- Files.copy():复制文件
- Files.move():移动文件。
- Files.size():查看文件个数。
- Files.read():读取文件。
- Files.write():写入文件。
18、Java容器都有哪些?
Java容器分为Collection与Map两大类,其下又有很多子类
- Collection
- List
- ArrayList
- LinkedList
- Vector
- Stack
- Set
- HashSet
- LinkedHashSet
- TreeSet
- List
- Map
- HashMap
- LinkedHashMap
- TreeMap
- ConcurrentHashMap
- HashTable
- HashMap
19、Collection与Collections有什么区别?
- Collection是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法,所以集合都是它的子类,比如List、Set等。
- Collections是一个包装类,包含了很多静态方法,不能被实例化,就像一个工具类,比如提供的排序方法:Collections.sort(list)。
20、List、Set、Map之间的区别是什么?
List、Set、Map的区别主要体现在两个方面:元素是否有序、是否允许元素重复
三者的区别如下表:
21、HashMap与HashTable有什么区别?
- 存储:HashMap允许key和value为null,而HashTable不允许
- 线程安全:HashTable是线程安全的而HashMap是非线程安全的
- 推荐使用:在Hashtable的类注释可以看到,HashTable是保留类不建议使用,推荐在单线程环境下使用HashMap替代,如果需要多线程使用则用ConcurrentHashMap替代。
22、如何决定使用HashMap与TreeMap?
对于在Map中插入、删除、定位一个元素这类操作,HashMap是最好的选择,因为相对而言HashMap是最好的选择,因为相对而言HashMap的插入会更快,但如果要对key集合进行有序的遍历,那TreeMap是更好的选择。
23、说下HashMap的实现原理?
HashMap基于Hash算法实现的,通过put(key,value)存储,get(key)来获取。当传入key时,HashMap会根据key.HashCode()计算出hash值,根据hash值将value保存在bucket里,当计算出的hash值相同时,我们称之为hash冲突,HashMap的做法是用链表和红黑树存储相同hash值的value。当hash值的冲突个数比较少时,使用链表否则使用红黑树。