1.集合
一.集合的架构、怎样选择集合
Iterable<-Collection(I)
|
List(I) Set(I) Queue(I)
| | |
ArrayList(c) HashSet(c) LinkedList(c)
LinkedList(c) SortedSet(I) Deque(I)
Vector(c) |-TreeSet(c) |-LinkedList(c)
Stack(c)栈
选择集合的要素:
集合是否允许重复
是否有顺序
是否要排序
二.底层实现
1.List(I)有序列表,可重复:
a.ArrayList 数组,顺序结构,标号,连续空间
b.LinkedList 节点,链表结构,head、next
c.Vector 同ArrayList,有多个锁
2.Set(I)不可重复
a.HashSet (无序散列表)hashCode() equals()
b.TreeSet(二叉树-中序遍历)从小到大-比较Comparable-compareTo
3.Queue(队列:先进先出)
Deque(I)双端队列:两边都可以进出
Stack (c)栈:先进后出 压栈push() 弹栈pop()
2.Map
一.HashMap\Hashtable\ConcurrentHashMap\LinkedHashMap的区别
a.HashMap:无序;不安全
b.TreeMap:有序;不安全;根据键排列,可自定义Comparator
c.Hashtable:无序;安全;不允许null
d.LinkedHashMap:有序;不安全;根据插入访问顺序排序,有序的HashMap
e.ConcurrentHashMap:无序;安全;线程安全的HashMap
二.HashMap的底层实现
Hash->HashSet
HashSet就是HashMap的key的部分
TreeSet就是TreeMap的key的部分
HashSet的存储过程->HashMap的存储过程
1.hashCode()计算位置
2.位置上如果没有元素,直接加入
3.位置上如果有元素,对比equals()方法比较
a.相等,不添加
b.和位置上的链表的每一个节点判断不相等,添加到链表末尾
因为链表访问效率很低,所以尽量使每一个位置上的链表长度要短
这就要求容量大,但是考虑到空间使用率,容量不能无限大,默认初始容量jdk提供16
后期数据量太大,要扩容,但是不能存满再扩容
扩容:容量改变,原来集合中的元素复制到新扩容的集合中,要重新计算位置
需要消耗时间,所以不能频繁扩容,综合考虑,当集合存储到75%的时候,进行扩容一倍
结论:
HashMap初始容量16
加载因子0.75
集合选取原则:
是否需要键值对:
是:Map,是否需要排序:
是:TreeMap
否:HashMap
否:Collection,元素是否唯一:
是:Set,是否需要排序
是:TreesSet
否:HashSet
否:List :
安全:Vector
增删多:LinkedList
查询多:ArrayList
三.线程:
线程异步:多个线程、使用同一个资源、抢占资源
线程同步:排队执行
什么时候会产生线程安全问题?
答:线程异步
怎么样解决线程安全问题?
答:synchronized
java线程 锁-原理?
答:使自己的高速缓存无效、这样就保证了直接从主内存中装入变量
sleep和wait区别:
答:1.sleep()方法正在执行的线程继续往下执行(sleep方法只让出了cpu,并不会释放同步资源锁)而wait()方法则是值当前线程让自己暂时退出同步资源锁,以便其他正在等待该资源的线程得到该资源而运行,只有调用了notify()方法才会接触线程的调度
2.sleep()方法可以在任何地方使用;wait()方法则只能在同步方法或同步块中使用
3.sleep()是线程类(Thread)的方法,调用会暂停此线程的时间,但监控依然保持,不会释放对象锁,到时间恢复;wait()是Object的方法,调用会放弃对象锁,进入等待队列,待调用notify()/notifyAll()唤醒指定的线程或者所有线程,才会进入锁池,不再次获得对象锁才会进入运行状态
sleep()方法导致了程序暂停执行,指定时间,让出了cpu给其他线程,但是他的监控状态依然保持着,当指定的时间到了又会自动恢复运行状态,在调用sleep()方法过程中,线程不会释放对象锁,而调用wait()方法的时候,线程会放弃对象锁,进入等待次对象的等待锁定池,只有针对此对象调用notify()方法后才进入对象锁定池准备,获取对象锁定池准备,获取对象锁进入运行状态。
线程池的好处、优势、功能,使用线程池的必要性
答:线程池:线程对象ExcutorService
直接new Thread()以后一般不用
ExecutorService pool=Executors.newFixedThreadPool(3);创建一个可重用固定线程数的线程池
ExecutorService pool=Executors.newCachedThreadPool();按照需求
ExxecutorService pool=Excutors.newSingleThreadPool();创建一个
Runnable/callable的区别
答:1.Runnable执行方法是run(),Callable是call()
2.实现Runnable接口的任务线程无返回值;实现callable接口的任务能返回执行结果
3.call方法可以抛出异常,run方法若有异常只能在内部消化
TCP/IP协议:
一共有四层:应用层,传输层,网络层,数据链路层
应用层:http、ftp等
传输层:TCP、UDP协议
网络层:IP协议
数据链路层:网络接口层
三次握手:
第一次:客户端发送一个TCP标志SYN=1,ACK=0的数据包给服务端
第二次:服务端要对客户端的联机请求进行确认,向客户端发送应答号ACK=1、SYN=1 确认号码为Ack=K+1
第三次:客户端收到数据后检查Ack是否为J+1,以及标志位ACK的值是否为1,若为1,则会发送ACK=1、确认号码Ack=K+1
视图的作用是什么、好处是什么:
1.如果需要经常执行某项复杂查询,可以基于这个复杂查询建立视图,此后查询此视图即可,简化复杂查询;
2.视图本质上就是一条select语句,所以当访问视图时,只能访问到所对应的select语句中涉及到的列,对基表中的其他列起到安全和保密的作用,可以限制数据访问
索引的必要性有哪些?怎么合理添加索引?索引的优势?
1.索引时独立于表的对象,可以存放在与表不同的表空间中。对索引进行的I/O操作比对表进行操作要少很多;索引一旦被建立就将被oracle系统自动维护,查询语句中不用指定使用哪个索引,是一种提高查询效率的机制
2.创建和使用索引的原则
为经常出现在where子句中的列创建索引
为经常出现在order by distinct后面的字段建立索引,如果建立的时复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致
为经常作为表的连接条件的列上创建索引
不要经常做DML操作的表上建立索引
不要在小表上建立索引
限制表上的索引数目,索引不是越多越好
删除很少使用的、不合理的索引
索引的原理
什么是HTTP协议:
HTTP是超文本传输所要遵守的规则。
包括request和response
HTTP请求包括:请求行、请求头、请求体
请求行:请求方式:Get/Post form method="post"、请求的资源、协议版本
协议版本:1.0 发送请求,创建一次连接,获得一个web资源,连接断开
1.1 发送请求,创建一次连接,获得多个web资源,连接保持
请求头:客户端发送给服务器端的一些信息,使用键值对表示,Cookie、User-Agent等
请求体:当请求方式为post时;发送请求参数
注:如果是get会拼接在url后面
HTTP响应包括:响应行、响应头、响应体
响应行:状态码;200:请求成功;302:请求重定向;304:请求资源没有改变,访问本地缓存;404请求资源不存在;500:服务器内部错误
响应头:将服务器端的信息以键值对的方式返回:Locantion:指定响应路径;Connect-Disposition:通过浏览器下载方式解析正文;Set-Cookie与会话技术,服务器向浏览器写入cookie
响应体:服务器写回给客户端的页面正文,浏览器将正文加载到内存中,然后解析渲染显示页面内容;
get和post的区别
- 请求缓存:get会被缓存,而post不会
- 收藏书签:get可以,post不能
- 保留浏览器历史记录:get可以,post不能
- 用处:get常用于取回数据,post用于提交数据
- 安全性:post比get安全
- 请求参数:get的querystring仅支持urlencode编码,post的参数式放在body(支持多种编码
- 长度限制:get请求长度最多1m,post对请求数据没有限制