异常
异常的分类和原因?
throwable是所有错误和异常的父类,Throwable分为Error和Exception
Exception指的是Java程序运行时的异常,即程序中发生了不被期望的情况,分为RuntimeException和CheckedException
RuntimeException指Java虚拟机正常运行期间抛出的异常,可以被捕获并处理,如数组越界,空指针异常
异常的处理方式?
抛出异常:遇到异常不处理,而是抛出给调用者,由调用者视情况处理,
一种是throws,作用在方法上
另外一种是throw,作用在方法内
Error是指Java程序运行时错误,出现Error的原因一般是系统的内部错误或者资源耗尽,出现Error不能在程序运行时动态的处理,如果说出现了Error,系统只能记录错误的原因和安全终止
CheckedException指的时Java虚拟机在编译时的异常,要强制捕获并处理的异常,如io异常,SQL异常
利用try/catch进行异常的捕获并处理,try中发生的异常,被catch中的代码块捕获,视情况进行处理,如果有finally代码块,无论是否发生异常,最后都会执行,一般用于释放资源
集合
Collection
list:有序,可重复,有索引
Arraylist:底层是通过数组实现的,线程不安全,查询速度快,增删慢,底层是数组,默认大小是10,默认扩展是50%
Vector:是线程安全的Arraylist,但是效率低,查询快,增加删除慢,默认大小是10,当增加的容量大于0时,可以自定义容量,不自定义的话默认扩充为原来的两倍,底层是用数组实现的,通过synchronized修饰方法来保证线程的安全
set:无序,不可重复(唯一)
HashSet:底层就是HashMap,利用key来保证元素的唯一性
TreeSet
LinkedHashSet:
Map:无序,通过key-values键值对形式存储元素的集合
HashMap:底层通过数组加链表加红黑树实现,HashMap线程不安全,可以用ConcurrentHashMap保证线程安全
ConcurrentHashMap是线程安全的HashMap,通过分段锁实现线程安全,性能较好
LinkedHashMap;可以通过key的操作顺序对集合进行排序
TreeMap:可以按照默认或者指定的规则对集合排序
数组和链表
数组:查询速度快,增删速度慢,查询快是因为数组在内存中是一块连续的区域,增删慢是因为要移动大量元素
链表:插入比较快,增删比较快,查询比较慢,是因为元素在内存中是分散存储的,查找元素时要从头指针出发寻找,插入快,只需要改变前一节点的指针域和要修改的指针域
多线程
创建线程的方式有哪些?
1.继承Thread类,重写run方法:优点;编码简单,缺点:不能继承其他的类,功能比较单一
linkedlist;底层是通过双链表实现与ArrayList相比增删块,查询慢,线程不安全
2.实现Runnable接口,重写run方法,并将该实现类作为参数传入Thread构造器中
3.实现callable接口,重写call方法,并包装成FutureTesk对象,并作为参数传入Thread构造器中
4.线程池
什么是线程安全问题如何解决?
多个线程对同一个共享变量进行操作
使用内部锁synchronized,可以使用同步代码块
使用Java.util.concurrent包中的锁,使用ReentrentLock
多线程不可见的原因及解决的方法?
原因:每个线程都有自己的工作内存,线程需要从主内存中拷贝共享变量的副本值,每个线程都是在自己的工作内存操作共享变量的
解决方法:加锁,使用volatile关键字。使用volatile修饰的变量会通知其他线程,之前读取到的值已经失效,不能用了,需要重新从主内存中加载最新的值到自己的工作区间中
volatile关键字的作用是什么?
保证被volatile修饰的变量对所有线程可见,一个线程修改了变量的值,新修改的值对于其他线程是可以立刻知道的
volatile不会执行加锁操作,也不会造成线程阻塞,主要适用于一个变量被多个线程共享
synchronized关键字的作用?
用于Java对象,方法,代码块提供线程安全的操作,属于悲观锁,也属于可重入锁
被synchronized修饰的方法或者代码块,在同一时刻,只能有一个线程进行访问,其他线程等待这个锁释放资源后才能访问
讲一讲ReentrantLock是什么?
是lock接口的实现类,可重入锁reentrantlock锁,通过AQS同步队列实现
支持公平锁和非公平锁,可响应中断锁,定时锁,可轮询锁,
通过lock和unlock方法,显示的添加锁和释放锁的
synchronized和ReentrantLock有哪些区别?
synchronized是隐式锁,是关键字,不用释放锁。ReentrantLock显示锁,接口,必须在finally代码块中添加释放锁 的操作
synchronized是非公平锁,ReentrantLock可以实现公平锁。
ReentrantLock可响应中断,可轮回,为处理锁提高了更多灵活性。
synchronized采用悲观并发策略,ReentrantLock采用的是乐观并发策略
Java中的锁有什么作用?有哪些分类?
Java中的锁主要的作用是什么:保证多并发情况下数据保证一致性,线程首先必须获取锁才能进行操作,才能保证数据的安全
锁有乐观锁和悲观锁
获取资源的公平性是公平锁和非公平锁
从共享资源的角度,分为共享锁和排它锁
从锁的状态角度可分为偏向锁、轻量级锁和重量级锁
悲观锁和乐观锁的区别?
悲观锁:一来就加锁,每次读取数据时,不管有没有被更改,就是先上锁
乐观锁:读取数据时,不上锁,但是在更新数据时会判断一下,在更新期间有没有人更新数据,采用写时先加上版本号,后加锁。采用CAS(比较并更新)当前的值和传入的值进行比较,比较当前版本号和上一次版本号
讲一讲公平锁与非公平锁?
基本上归结于排队问题,谁排队久先给谁,有的人插队,就是非公平锁
线程池是什么?为什么要创建线程池?
线程池:创建若干个可执行的线程放到一个池子(容器)里面,有任务需要处理时,会提交到线程池的任务队列中去,处理完了,线程不会被销毁,会重新放回池子里面,等待下一个任务<br>
创建线程池的原因:避免频繁的创建和销毁线程,节省资源,提高系统性能