从今天开始,每天复习30个基础知识点,巩固所学内容!
1. JDK 和 JRE 有什么区别?
jdk:java development kit java开发工具包
jre:java runtime environment java开发环境
jdk包含jre +javac(编译java源码)+java调试和分析工具
运行java程序只需要jre
编写则需要jdk
2 和 equals 的区别是什么?
要看情况,比较基本类型时,比值,比较引用类型,比引用(开辟内存空间的就不相同了,如new())
equals一直比较的是值(equals 默认情况下是引用比较,只是很多类重新了 equals 方法,比如 String、Integer 等把它变成了值比较,所以一般情况下 equals 比较的是值是否相等。)
看一下equals的源码:
默认情况下 equals 比较一个有相同值的对象,结果是false,
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
equals 本质上就是 ==。
在string类中重写了:很明显,这是进行的内容比较,而已经不再是地址的比较。依次类推Math、Integer、Double等这些类都是重写了equals()方法的,从而进行的是内容的比较。很明显,这是进行的内容比较,而已经不再是地址的比较。依次类推Math、Integer、Double等这些类都是重写了equals()方法的,从而进行的是内容的比较。
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 重写了 Object 的 equals 方法,把引用比较改成了值比较。
3. 两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
将数据根据特定的算法映射到一个固定地址上 相当于一人一个座位(内存地址) 一人一个座位号(HashCode)的意思 一旦某个座位上有人 那么才和这个座位上的人eqauls比较 同一个人则不分配 不同则分配其他位置(散列) 如果这个座位上没人 则直接就坐
如果eqauls为true 则两者的hashCode一定相同
如果两者的hashCode相同 eqauls不一定为true;hashCode不同 那么eqauls一定不为true
对比两个对象是否相等最可靠的做法是eqauls
哪些情况下hashCode会相同?
相同的字符串
大小一样的Integer
当我们重写一个类的 equals 方法时就应当连同重写 hashcode 方法,并且两个方法应满足:
1:一致性,即:当两个对象 equals 比较为 true,那么 hashcode 值应当相等,反之亦然,因为当两个对象hashcode 值相等,但是 equals 比较为 false,那么在 HashMap 中会产生链表,影响查询性能。
2:成对重写,即重写 equals 就应当重写 hashcode。
想要弄明白hashCode的作用,必须要先知道Java中的集合。
总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set。前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重复。这里就引出一个问题:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢?
这就是Object.equals方法了。但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。也就是说,如果集合中现在已经有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。
于是,Java采用了哈希表的原理。哈希(Hash)实际上是个人名,由于他提出一哈希算法的概念,所以就以他的名字命名了。哈希算法也称为散列算法,是将数据依特定算法直接指定到一个地址上,初学者可以简单理解,hashCode方法实际上返回的就是对象存储的物理地址(实际可能并不是)。
这样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。
简而言之,在集合查找时,hashcode能大大降低对象比较次数,提高查找效率!
https://blog.csdn.net/zj15527620802/article/details/88547914
4. final 在 java 中有什么作用?
final修饰的类(最终类)不能被继承,方法不能被重写,数据是常量必须初始化
5. java 中的 Math.round(-1.5) 等于多少?
扩展JDK中的java.lang.Math类:
round:返回四舍五入,负.5小数返回较大整数,如-1.5返回-1。
ceil:返回小数所在两整数间的较大值,如-1.5返回-1。
tail:返回小数所在两整数间的较小值,如-1.5返回-2。
Math.round(1.4)=1
Math.round(-1.4)=-1
Math.round(1.5)=2
Math.round(-1.5)=-1
Math.round(1.6)=2
Math.round(-1.6)=-2
Math.ceil(1.4)=2.0
Math.ceil(-1.4)=-1.0
Math.ceil(1.5)=2.0
Math.ceil(-1.5)=-1.0
Math.ceil(1.6)=2.0
Math.ceil(-1.6)=-1.0
Math.floor(1.4)=1.0
Math.floor(-1.4)=-2.0
Math.floor(1.5)=1.0
Math.floor(-1.5)=-2.0
Math.floor(1.6)=1.0
Math.floor(-1.6)=-2.0
6. String 属于基础的数据类型吗?
不属于,基础只有8种:int boolean char long short float double byte
string属于对象
在java 中使用字符串最重要的一个规则必须记住,一个字符串对象一旦被创建,它的内容就是固定不变的 public static String str = “abc”;
这个声明会创建一个长度为3,内容为abc的字符串对象,您无法改变这个字符串对象的内容。
str = “1111”;
不要以为这样就改变了字符串对象的内容,事实上。上面那段代码中产生了两个字符串对象,一个是abc字符串对象,长度为3;一个是1111字符串对象,长度为4,两个不同的字符串对象。您不不是在abc 字符串改为1111字符串,而是让str 引用名称从新引用1111字符串,而不在引用abc 字符串但abc字符串在内存中还是存在的,只是现在没有被引用。
所以输出1111
7. java 中操作字符串都有哪些类?它们之间有什么区别?
string不可变
stringbuffer 线程安全
stringbuilder 线程不安全
8. String str="i"与 String str=new String(“i”)一样吗?
不一样,因为内存的分配方式不一样。String str="i"的方式,java 虚拟机会将其分配到常量池中;而 String str=new String(“i”) 则会被分到堆内存中。
Java程序是运行在JVM(Java虚拟机)上的,因此Java的内存分配是在JVM中进行的,JVM是内存分配的基础和前提。Java程序的运行会涉及以下的内存区域:
-
寄存器:JVM内部虚拟寄存器,存取速度非常快,程序不可控制。
-
栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中。
-
堆:存放new出来的对象,注意创建出来的对象只包含各自的成员变量,不包括成员方法。
-
常量池:存放常量,如基本类型的包装类(Integer、Short)和String,注意常量池位于堆中。
-
代码段:用来存放从硬盘上读取的源程序代码。
-
数据段:用来存放static修饰的静态成员。
https://blog.csdn.net/jian_sheng_tan/article/details/78323327
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
11. String 类的常用方法都有那些?
indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
substring():截取字符串。
equals():字符串比较。
12. 抽象类必须要有抽象方法吗?
不需要
13. 普通类和抽象类有哪些区别?
普通类不能包含抽象方法,抽象类可以
抽象类不能实例化,普通类可以的
14. 抽象类能使用 final 修饰吗?
不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类
15. 接口和抽象类有什么区别?
实现,一个是extends 一个是implements
构造,抽象类可以有构造函数,接口没有
main,抽象类可以有,接口没有
数量,一个类可以实现很多接口,只能继承一个抽象类
修饰符,接口方法默认public,抽象类可以任意访问修饰符
16. java 中 IO 流分为几种?
功能来分:input output(输入输出)
类型来分:字节流,字符流
区别,字节流8位来传输,字符16位
17. BIO、NIO、AIO 有什么区别?
BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。
参考网站:https://blog.csdn.net/ty497122758/article/details/78979302
https://www.jianshu.com/p/9a048daa4c3d
18. Files的常用方法都有哪些?
Files.exists():检测文件路径是否存在。
Files.createFile():创建文件。
Files.createDirectory():创建文件夹。
Files.delete():删除一个文件或目录。
Files.copy():复制文件。
Files.move():移动文件。
Files.size():查看文件个数。
Files.read():读取文件。
Files.write():写入文件。
19. java 容器都有哪些?
20. Collection 和 Collections 有什么区别?
java.util.Collection 是一个集合接口
提供对集合基本操作的方法
list和set是它的继承接口
collections 是一个集合类的工具类,提供一系列静态方法
用于排序,搜索,以及线程安全
21. List、Set、Map 之间的区别是什么?
map 顺序:
HashedMap 无序
LinkedHashMap 有序(放入顺序)
TreeMap 有序(默认升序)
22. HashMap 和 Hashtable 有什么区别?
hashMap去掉了HashTable 的contains方法,但是加上了containsValue()和containsKey()方法。
hashTable同步的,而HashMap是非同步的,效率上比hashTable要高。
hashMap允许空键值,而hashTable不允许。
23. 如何决定使用 HashMap 还是 TreeMap?
对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的collection的大小,也许向HashMap中添加元素会更快,将map换为TreeMap进行有序key的遍历。
24. 说一下 HashMap 的实现原理?
HashMap概述: HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
HashMap的数据结构: 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。
当我们往Hashmap中put元素时,首先根据key的hashcode重新计算hash值,根绝hash值得到这个元素在数组中的位置(下标),如果该数组在该位置上已经存放了其他元素,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放入链尾.如果数组中该位置没有元素,就直接将该元素放到数组的该位置上。
需要注意Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn)
25. 说一下 HashSet 的实现原理?
HashSet底层由HashMap实现
HashSet的值存放于HashMap的key上
HashMap的value统一为PRESENT
26. ArrayList 和 LinkedList 的区别是什么?
arraylist底层是数组,支持随机访问
linkedlist底层是双向循环链表,不支持随机访问
使用下标访问一个元素,ArrayList 的时间复杂度是 O(1),而 LinkedList 是 O(n)。
27. 如何实现数组和 List 之间的转换?
list->数组 调用ArrayList的toArray()
反过来 调用Arrays的aslist()
28. ArrayList 和 Vector 的区别是什么?
Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。
ArrayList比Vector快,它因为有同步,不会过载。
ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。
29. Array 和 ArrayList 有何区别?
Array可以容纳基本类型和对象,而ArrayList只能容纳对象。
Array是指定大小的,而ArrayList大小是固定的。
Array没有提供ArrayList那么多功能,比如addAll、removeAll和iterator等。
30. 在 Queue 中 poll()和 remove()有什么区别?
poll() 和 remove() 都是从队列中取出一个元素,但是 poll() 在获取元素失败的时候会返回空,但是 remove() 失败的时候会抛出异常。
31. 哪些集合类是线程安全的?
vector:就比arraylist多了个同步化机制(线程安全),因为效率较低,现在已经不太建议使用。在web应用中,特别是前台页面,往往效率(页面响应速度)是优先考虑的。
statck:堆栈类,先进后出。
hashtable:就比hashmap多了个线程安全。
enumeration:枚举,相当于迭代器。