1.Arraylist和Linkedlist的区别?
- Arraylist底层是数组结构;Linkedlist底层是链表结构
- 随机访问时,Arraylist的效率高。(因为Arraylist是基于索引进行查询,可以直接映射到,而Linkedlist需要移动指针进行查询)
- 插入、删除数据时,LInkedlist的效率高。(Linkedlist是链表结构,通过更改引用达到增加或删除的目的,而Arraylist底层是数组结构,通过移动数组中的数据来进行增加或删除操作)
- Linkedlist的开销比Arraylist的开销大,因为Linkedlist的节点除了存储数据还要存储引用
2.怎么对数组进行排序?
- Arraylist底层是数组结构;Linkedlist底层是链表结构
- 随机访问时,Arraylist的效率高。(因为Arraylist是基于索引进行查询,可以直接映射到,而Linkedlist需要移动指针进行查询)
- 插入、删除数据时,LInkedlist的效率高。(Linkedlist是链表结构,通过更改引用达到增加或删除的目的,而Arraylist底层是数组结构,通过移动数组中的数据来进行增加或删除操作)
- Linkedlist的开销比Arraylist的开销大,因为Linkedlist的节点除了存储数据还要存储引用
使用Collections.sort()方法对数组进行排序:
public static void main(String[] args) {
List list = new ArrayList();
list.add(1);
list.add(3);
list.add(2);
list.add(8);
list.add(6);
list.add(0);
list.add(5);
list.add(6);
list.add(7);
list.add(12);
System.out.println(list);
//使用Collections.sort()方法对数组进行排序
Collections.sort(list);
System.out.println(list);
}
结果:
3、HashMap的原理、Java8做出了什么改变?4、 Hashmap大小为什么是2的幂次方?
- Hashmap是以键值对进行存储数据的集合容器
- Hashmap是非线程安全的(Hashtable是线程安全的,底层使用了synchronized进行同步,而hashmap会在插入和扩容时出现数据覆盖和数据丢失问题)
- Hashmap底层在Java8之前是数组+链表,Java8之后变成数组+(链表、红黑树)
- Hashmap数组的默认长度是16,key和value都可以为null
- Hashmap的内部数据为Node[]数组,上面存的是key-value键值对的节点。Hashmap通过put()和get()方法进行存储和获取
- Java8把put()方法进行更改
5、List、Set和Map的区别?
- 减少Hash碰撞,尽量使Hash算法的结果均匀
6、 poll()和remove()方法的区别?
- List是以索引来存储元素,有序,元素允许重复,可以插入多个null
- Set不能存放重复元素,无序,只允许一个null
- Map保存键值对映射,映射关系可以一对一、一对多
- List可以基于数据、链表两种实现方式
- Set、Map容器基于哈希存储和红黑树两种方式实现
- Set基于Map实现、Set里的元素值就是Map的键值
7、 Hashmap、Hashtable、Concurrenthashmap的共同点和区别?
- Queue队列中,poll()和remove()方法都是从队列中取出一个元素,在队列元素为空的情况下,remove()会抛出异常,而poll()方法只会返回null
8、 在遍历Arraylist时删除某一个特定元素Hashmap:
- 底层是数据+链表+红黑树实现
- 可以存储null值和null键
- 线程不安全
- 初始容量为16,扩容每次都是2的n次幂
- 加载因为为0.75,当Map中元素总数超过Entry数组的0.75,会触发扩容操作
- 并发情况下,Hashmap进行put操作会引起死循环,导致CPU利用率接近100%
- Hashmao是Map接口的实现
Hashtable
- Hashtable的底层也是数据+链表+红黑树
- 无论是key还是value都不能是null
- 他是线程安全的,使用synchronized关键字
- Hashtable实现了Map接口和Dictionary抽象类
- Hashtable的初始容量为11
Concurrenthashmap
- 底层也是数组+链表+红黑树
- 不能存储null值和null键
- Concurrenthashmap是线程安全的
- Concurrenthashmap使用锁分段技术保证线程安全
public static void main(String[] args) {
List list = new ArrayList<>();
list.add("qwq");
list.add("qwq1");
list.add("qwq2");
list.add("qwq3");
list.add("qwq4");
list.add("qwq5");
list.add("qwq6");
list.add("qwq6");
list.add("qwq7");
System.out.println(list);
//fori顺序便利删除不了重复元素,条件满足后删除一个其他元素不会删除
// for (int i = 0; i < list.size(); i++) {
// if (list.get(i).equals("qwq6")) {
// list.remove(i);
// }
// }
//倒序删除
// for (int i = list.size()-1; i >-1 ; i--) {
// if (list.get(i).equals("qwq6")){
// list.remove(i);
// }
// }
//迭代器删除
// Iterator iterator = list.iterator();
// while (iterator.hasNext()) {
// if (iterator.next().equals("qwq6")){
// iterator.remove();
// }
// }
System.out.println(list);
}
9、 Java怎么打印数组?
public static void main(String[] args) {
String[] aa = {"qwqw","qweqa","qweqeqasxxa","qsaszzxa"};
//直接打印不会显示内容
System.out.println(aa);
//使用流的方式遍历
Stream.of(aa).forEach(System.out::println);
//使用API,查看数组内容
System.out.println(Arrays.toString(aa));
}
结果:
10、那些集合类是线程安全的?那些不安全?11、如何决定使用Hashmap还是Treemap?
- Vector:底层进行了synchronized操作
- Hashtable:大部分方法都是使用synchronized锁进行修饰,保证了线程安全性
- Concurrenthashmap:jdk1.8之后使用CAS+synchronized实现线程安全
- 其他的是线程不安全的
12、Array和Arraylist的区别?Treemap能够把它保存的记录根据键排序,默认是按key的升序排序,也可以指定排序的比较器。当用iterator遍历Treemap时,得到的记录是排过序的
13、==和equals()有什么区别?
- 定义一个Array时,必须指定数组的数据类型及数组长度,即数组中存放的元素个数固定并且类项相同
- Arraylist是动态数组,长度动态可变,会自动扩容。不使用泛型的时候,可以添加不同类型的元素
14、int和integer的区别?
- “==”是运算符,如果是基本数据类型,则比较存储的值;如果是引用数据类型,则比较所指向对象的地址值
- equals是Object的方法,比较的是所指向的对象的地址值,一般情况下,重写之后比较的是对象的值
15、final和finally的区别?
- integer是int的包装类;int是基本数据类型
- Integer变量必须实例化后才能使用;int变量不需要
- Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;直接存储数据值
- Integer的默认值是null;int的默认值是0
16、重写和重载的区别?
- final修饰的类成为最终类,不能被继承扩展
- final修饰的方法是最终方法,不能被重写
- final修饰的变量是最终变量,不能被修改
- finally是保证重点代码一定被执行
17、 运行时异常和一般异常有何不同?
- 重写是子类继承父类,重新编写方法体中的业务代码
- 重载是一个类中存在多个方法名相同,传参的类型,个数,顺序不同,返回值可以相同也可以不同的方法
18、常见的运行时异常
- 运行时异常可以不进行处理,交给虚拟机解决
- 一般异常是必须声明可能会抛出来的异常,并捕获
19、什么是序列化?序列化的用途是什么?
- 空指针异常
- 数组越界异常
- 类型转换异常
- 没有这样的元素异常(常出现在迭代器迭代时出现)
- 并发修改异常(常出现在迭代器正在迭代时使用集合修改元素)
- 没有序列化异常(没有实现serializable接口)
20、 BIO、NIO和AIO区别?
- 序列化就是用来处理对象流的一种机制
- 可以对流化后的对象进行读写操作
- 可以将流化后的对象传输于网络之间
21、线程有几种状态?
- BIO:同步阻塞、实现方法是一个链接一个线程
- NIO:同步非阻塞、实现方法是多个请求一个线程、即请求会注册到多路复用器上,等到有io请求时才启动一个线程
- AIO:异步非阻塞、实现方式是多个有效请求请求一个线程,由os完成后再通知服务器去启动线程处理
22、线程池有几种创建方法?
- 新建、就绪、运行、阻塞、死亡
23、start()和run()区别?
- 通过线程池
- 扩展Thread类,重写run()方法
- 实现Runnable接口,重写run()方法
- 实现Callable接口,重写call()方法
24、什么是数据库的事务?事务有哪些属性?
- start()方法可以真正的实现多线程,无需等待run()方法执行结束,即可继续执行下方代码
- run()方法只是一个普通方法,程序中仍然只有主线程一个线程
25、事务并发产生的问题
- 在一次操作中的多条sql语句执行要么全部成功、要么全部失败
- 原子性:事务中的修改,要么全部执行,要么全不执行
- 一致性:保证事务在查询和修改时不发生冲突
- 隔离性:控制数据访问的机制,确保事务只能访问处于一执行级别下的数据
- 持久性:更改后不可逆转,在讲数据修改写入磁盘之前会吧修改写到事物日志中
26、MySQL如何实现乐观锁和悲观锁?
- 脏读:一个事务读取另一个事务还未提交的数据!(第二个事务可能进行回滚,导致第一个事务读取的数据有误)
- 不可重复度:一个事务读取另一个事物提交的修改数据!(第一个事务查询后,第二个事务对数据进行修改,导致第一个事务两次查询结果不相同)
- 虚读:一个事物读取另一个事物提交的插入数据!(第一个事务查询后,第二个事务对数据进行插入,导致第一个事务两次查询结果不相同)
、
- 乐观锁:通过版本号(在表中添加一个version字段,读取时一同读出;数据每进行一次更新,version加一;当提交更新时,判断当前版本号与之前取出来的版本号是否一致?一致便直接更新,不一致判定为过期数据进行其他操作)和时间戳(与版本号差不多,version字段换成时间戳)控制
- 悲观锁:必须关闭mysql数据库的自动提交属性;开启事务;在进行数据库操作;最后提交事务
、
25、怎么添加索引?
、
- ALTER TABLE`` ADD UNIQUE(``)
、
、
、
、
、
、
27、redis的持久化机制
28、缓存问题
29、热点数据和冷数据缓存雪崩
- 1
缓存穿透
- 1
缓存预热
- 1
缓存更新
- 1
缓存降级
- 1
30、单线程的redis为什么这么快?
31、redis的数据类型,以及每种数据类型的应用场景
32、redis的过期策略和内存淘汰机制
31、对于大量请求怎么样处理
32、redis事务
33、redis的分布式锁
32、
2、
2、
2、
2、
2、
2、



