1、List和set的区别?
相同点:
List和set都是继承自Collection接口。
不同点:
Set:
- 元素无序,不可重复;
- 只能用迭代,不能用for循环;
- 检索效率低,增删效率高;
- 插入和删除不会引起元素位置的变化
List:
- 元素有序,可重复;
- 可以用for循环遍历;
- 检索效率高,插入效率低
- 会引起元素位置的变化
注释:set 元素虽然无放入顺序,但是元素在set中的位置是有该元素的 HashCode 决定的,其位置其实是固定的,加入Set 的Object 必须定义 equals ()方法 。
2、HashSet 是如何保证不重复的
我们可以根据hashSet的源码来解说,以下是 HashSet 部分源码:
private static final Object PRESENT = new Object();
private transient HashMap<E,Object> map;
public HashSet() {
map = new HashMap<>();
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
因为HashMap的 key 是唯一的,由上面的代码可以看出HashSet 添加进去的值就是作为HashMap 的key。所以不会 重复。(不仅要比较hash值,同时还要结合 equles 方法比较。)
3、HashMap是线程安全的吗,为什么不是线程安全的?
首先HashMap 不是线程安全的。
举个例子说明:
- 如果有两个线程A和B,都在做插入数据,并且刚好这俩数据经过哈希计算后得到的哈希值一样,且该位置没有别的数据。
- 假设有一种情况,线程A通过if语句判定,该位置没有哈希冲突,进入了if语句内,但还没有执行插入数据的时候,CPU把资源让给了线程B (你说气不气人)。
- 这个时候线程A停留在了if语句里面,但没有执行插入数据。
- 线程B获得CPU资源后,也通过if语句判定该位置没有哈希冲突,也进入了if语句。线程B使用完CPU资源后,轮到了线程A,这时候线程A直接执行插入数据操作,而无需判定。
- 这时候你就会发现,线程A把线程B插入的数据给覆盖掉了。
4、HashMap的扩容过程
我们都知道,在向HashMap容器里。添加元素的时候,会先判断容器内的元素个数,如果大于等于这个阈值(知道这个阈字怎么念吗?不念 fa 值,念 yu 值四声)。即当前数组的长度乘以加载因子的值的时候,就要自动扩容啦。
扩容就是重新计算容量,当然 Java 里的数组是无法自动扩容的,方法 是使用一个新的数组代替已有的容量小的数组。在扩容的时候也可能会导致数据不一致,因为扩容是从一个数组拷贝到另外一个数组。
5、Java获取反射的三种方法
- 通过new对象实现反射机制
- 通过路径实现反射机制
- 通过类名实现反射机制
例如:
public class Student {
private int id;
String name;
protected boolean sex;
public float score;
}
public class Get {
//获取反射机制三种方式
public static void main(String[] args) throws ClassNotFoundException {
//方式一(通过建立对象)
Student stu = new Student();
Class classobj1 = stu.getClass();
System.out.println(classobj1.getName());
//方式二(所在通过路径-相对路径)
Class classobj2 = Class.forName("fanshe.Student");
System.out.println(classobj2.getName());
//方式三(通过类名)
Class classobj3 = Student.class;
System.out.println(classobj3.getName());
}
}
6、Redis持久化机制原理
Redis通过持久化把内存中的数据同步到磁盘上,来保证数据的持久话。当redis重启后,就会把硬盘里的数据读取到缓存中,达到恢复数据的目的。
实现原理:
单独创建一个 fork() 子进程,把当前父进程的数据复制到子进程的内存中,然后由子进程写入到临时文件中。然后临时文件会替换掉快照文件,子进程退出,内存释放。
RDB是redis默认的持久化方式,根据一定的时间周期策略把内存的数据以快照的形式保存到硬盘上,文件名为:dump.rdb。
AOF:Redis会将每一个收到的写命令都通过Write函数追加到文件最后,类似于MySQL的binlog。当Redis重启是会通过重新执行文件中保 存的写命令来在内存中重建整个数据库的内容。
7、redis持久化的方式各有哪些优缺点
首先RDB模式下:
优点:
- 只有一个文件 dump.rdb,方便持久化;
- 容灾性好,一个文件可以保存到安全的磁盘。
- 性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO最大化。
- 相对于数据集大时,比 AOF 的启动效率更高。
缺点:
- 数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。
AOF模式下:
优点:
- 数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次命令操作就记录到 aof 文件中一次。
- 通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof工具解决数据一致性问题。
- AOF 机制的 rewrite 模式。(AOF 文件没被 rewrite 之前,可以删除其中的某些命令)
缺点:
- AOF 文件比 RDB 文件大,且恢复速度慢。
- 数据集大的时候,比 rdb 启动效率低。