1 Star 0 Fork 0

方温南/学习文档

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
面试题 5.46 KB
一键复制 编辑 原始数据 按行查看 历史
方温南 提交于 2020-06-22 09:33 +08:00 . 2020.06.22-整合公司电脑学习笔记
面试题:
1.ArrayList和LinkedList的区别
a.是否线程安全
都不安全
b.底层数据结构
ArrayList 底层使用的是 Object[] 数组;LinkedList 使用的是双向链表数据结构(JDK1.6前为双向循环链表,JDK1.7后取消了循环)
c.插入删除影响
1.ArrayList采用数组存储,因此插入和删除元素的时间复杂度都受元素位置的影响.比如:执行add(E e)方法的时候,ArrayList
会默认将该元素追加到此列表的末尾,这种情况的时间复杂度就是O(1).但是如果要在指定位置i插入和删除元素的话(add(int index, E element)
那么时间复杂度就为O(n-i),因为在进行上述操作的时候,集合中第i和第i个元素之后的(n-i)个元素,都要执行向后/前位移一位的操作.
2.LinkedList采用的是链表存储,所以插入、删除元素时间复杂度不受元素位置的影响,都是近似O(1),而数组为近似O(n).
d.快速随机访问
LinkedList不支持快速随机访问,而ArrayList支持.
e.内存空间占用
ArrayList的空间浪费,主要体现在List列表的结尾,会预留一定的空间容量;而LinkedList 的空间花费
则体现在它的每一个元素,都需要消耗比ArrayList更多的空间,这是由于直接后继和直接前驱的存在.
数组天然支持随机访问,而链表不行
RandomAccess 接口只是一个标识,并不是说ArrayList实现RandomAccess接口,才具有快速随机访问的功能.
双向链表:包含两个指针,一个prev指针指向前一个节点(第一个prev指向nil),一个next指针指向后一个节点(最后一个next同样指向nil).
双向循环链表:最后一个节点的next指针指向第一个节点的head,而第一个节点的head的prev指针指向最后一个节点,所以是构成一个循环.
2.线程死锁
必备条件:
1.互斥条件
2.请求与保持条件
3.不剥夺条件
4.循环等待条件
3.线程生命周期和状态
NEW:初始状态
RUNNABLE:运行状态
BLOCKED:阻塞状态
WAITING:等待状态
TIME_WAITING:超时等待状态
TERMINATED:终止状态
线程创建后,处于NEW(新建)状态,调用start()方法后开始运行,线程这时候处于READY(可运行)状态;可运行状态的线程获得了CPU
时间片(timeslice)后,就处于RUNNING(运行)状态.
面试题
2020-06-03
线程池
1.为什么要用线程池
a.降低资源消耗,利用重复利用创建的线程
b.提供相应速度,任务到达时无需等待线程创建完成
c.提高线程的可管理型
2.实现Runnable接口和Callable接口的区别
Runnable接口的执行方法无法返回返回值
工具类Executors可以实现Runnable对象转换成Callable对象
3.执行execute()方法和submit()方法的区别
execute方法用于执行不需要返回值的任务,所以无法判断认识是否执行与否
submit方法会返回一个Future的对象,可以判断任务是否执行成功,并且可以通过
Future的get()方法来获取返回值,get方法会阻塞当前线程直到任务完成
get(long timeout,TimeUnit unit)会在阻塞timeout时间之后返回.
Executors的问题
1.FixedThreadPool和SingleThreadExecutor允许的请求队列最大长度为Integer.MAX_VALUE
可能会堆积大量的请求,导致OOM
2.CachedThreadPool和ScheduledThreadPool允许的线程数量为Integer.MAX_VALUE,可能会
堆积大量的线程,导致OOM
方式一:通过构造方法实现
方式二:通过Executor框架的工具Executors来实现,可以创建三种类型的ThreadPoolExecutor
a.FixedThreadPool
创建固定数量的线程池,如果线程进入时有空闲线程则直接执行,如果没有空闲的线程
则进入任务队列等待
b.SingleThreadExecutor
创建一个单线程的线程池,如果线程进入时有空闲线程则直接执行,如果没有空闲的线程
则进入任务队列等待
c.CachedThreadPool
返回一个可根据实际情况调整线程数量的线程池,新请求进入时如果有可复用的线程则
会复用
原子类
基本类型
使用原子的方式更新基本类型
AtomicInteger:整形原子类
AtomicLong:长整型原子类
AtomicBoolean:布尔型原子类
数组类型
使用原子的方式更新数组里的某个元素
AtomicIntegerArray:整形数组原子类
AtomicLongArray:长整形数组原子类
AtomicReferenceArray:引用类型数组原子类
引用类型
AtomicReference:引用类型原子类
AtomicStampedReference:原子更新引用类型里的字段原子类
AtomicMarkableReference :原子更新带有标记位的引用类型
对象的属性修改类型
AtomicIntegerFieldUpdater:原子更新整形字段的更新器
AtomicLongFieldUpdater:原子更新长整形字段的更新器
AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来
可用于解决原子的更新数据和数据的版本号,以及解决使用 CAS 进行原子更新时可能出现的ABA问题
CAS的原理,是拿期望值和原本的值作比较,如果相同,则更新成新的值。UnSafe 类的 objectFieldOffset()
方法是个本地方法,这个方法是用来拿“原值”的内存地址,返回值是 valueOffset;另外,value 是一个volatile变量
因此 JVM 总是可以保证任意时刻的任何线程总能拿到该变量的最新值
并发编程三要素:
原子性,有序性,可见性
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Java
1
https://gitee.com/nanwenfang/learning_documents.git
git@gitee.com:nanwenfang/learning_documents.git
nanwenfang
learning_documents
学习文档
master

搜索帮助