📚【学习不息,成长不止】在这个快速变化的世界里,唯有不断学习,才能不被时代淘汰。每一天都让自己进步一点点,未来的你会感谢现在努力的自己。
1、线程的 run() 和 start() 有什么区别
start方法用来启动相应的线程;
run方法只是thread的一个普通方法,在主线程里执行;
需要并行处理的代码放在run方法中,start方法启动线程后自动调用run方法;
run方法必须是public的访问权限,返回类型为void。
2、为什么要同时重写 equals 方法和 hashcode 方法
equals相等,hashcode一定相等。
equals不等,hashcode不一定不等。
hashcode不等,equals一定不等。
hashcode相等,equals不一定相等。
hashCode()方法的作用是确定对象在散列存储结构例如HashMap、HashSet中的存储地址
如果两个对象的HashCode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置
如果改写了equals(),而不改写hashcode的话,Object内默认hashcode()方法必定不同的(new 出对象的地址一定不同),这样hashmap存储的2个对象,都在不同的链上,这样无法进行equals()比较。
则当我们将两个对象同时加入散列存储结构map、set时,就可能出现数据结构中存在两个值相等的对象的情况,从而导致混淆。
3、单例模式
单例模式是指在内存中有且仅创建一次对象的设计模式。单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象
在单线程环境下,单例模式根据实例化对象时机的不同,有两种经典的实现:一种是 饿汉式单例(立即加载),饿汉式单例在单例类被加载时候,就实例化一个对象并交给自己的引用;
立即加载 : 在类加载初始化的时候就主动创建实例;
一种是 懒汉式单例(延迟加载)。而懒汉式单例只有在真正使用的时候才会实例化一个对象并交给自己的引用。
延迟加载: 等到真正使用的时候才去创建实例,不用时不去主动创建。
4、简述线程池的底层
核心底层为ThreadPoolExecutor类
- corePoolSize: 核心线程数
- 如果线程中的线程数没有达到核心线程数,在需要线程进行调度时,你不会使用空闲线程,而是创建新的线程,一直到达到核心线程数
- maximumPoolSize : 最大线程数
- 如果最大线程数大于核心线程数,所有核心线程数全部被使用了,如果还要新的任务,还会创建新的线程,一直到最大线程数。
- handler : 拒绝策略
- 如果线程池已经达到了最大线程数,还有请求进来,此时就必须拒绝
- AbortPolicy 拒绝执行,然后抛出异常
- CallerRunsPolicy 拒绝执行,丢弃
- DiscardOldestPolicy 暂停最老的,然后执行它
- DiscardPolicy 把当前正在执行的线程丢弃,然后执行它。
- keepAliveTime : 空闲线程存活时间 10
- unit : 单位
- threadFactory : 创建线程的工厂(默认)
- workQueue:任务队列,被提交但尚未被执行的任务。
5、String、StringBuffer、StringBuilder 之间的区别
操作字符串的类有:String、StringBuffer、StringBuilder。
String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象,而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。
StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。
6、Java中IO流有几种
按功能来分:输入流(input)、输出流(output)。
按类型来分:字节流和字符流。
字节流和字符流的区别是:字节流按 8 位传输以字节为单位输入输出数据,字符流按 16 位传输以字符为单位输入输出数据。
7、Collection 和 Collections 的区别
Collection 是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法,所有集合都是它的子类,比如 List、Set 等。
Collections 是一个集合工具类,比如提供的排序方法:Collections. sort(list)。
8、final 和 finally 的区别
final是一个修饰符,可以修饰类,方法,变量
final修饰的类不可以被继承
final修饰的方法不可以被覆盖
final修饰的变量是一个常量,只能赋值一次。
finally是try语句中的语句体,不能单独使用,用来释放资源,常与try;try-catch一起使用,表示无论是否发生异常,finally代码块中的代码总会被执行。
9、简述 ArrayList 和 LinkedList 的底层
ArrayList:
ArrayList是List的一个实现类,使用一个内部的Object数组来存储元素;
默认数组容量是10,当需要添加元素时,如果当前的内部数组已经满了, ArrayList会根据需要进行动态扩容,扩容为原来的1.5倍(0-10-15-22-33-49...);
ArrayList通过索引访问存储的元素;
在ArrayList中,在指定位置插入或删除一个元素可能需要对后续元素进行移动,以保持连续性。
LinkedList:
LinkedList底层是一个双向链表,使用一个Node节点类来表示链表中的每个节点;
LinkedList维护了两个特殊的引用,分别是指向链表的第一个节点的头引用和指向链表的最后一个节点的尾引用;
在LinkedList中插入和删除一个节点的操作非常高效;
LinkedList的访问需要从链表的头节点或尾节点开始,以节点间的引用进行遍历,直到找到目标元素。