cookie&集合容器

Cookie

一、Cookie和Session有什么区别?

当Tomcat服务器第一次接收到客户端的请求信息时,会开辟一个新的Session空间,创建一个新的Session对象,生成一个Session id。然后放在响应头发送给客户端。客户端收到之后就会存放在浏览器的Cookie中。以后用户的每次请求,都会在请求头附带这个Session id,这样服务器就可以返回上次的会话内容,如登陆状态

二、当服务端从单机扩展为分布式后,cookie和session如何扩展?

首先如果服务器是在多机分布式的场景下,session id只会在其中一个服务器当中,如果第二次请求在另一个服务器,就会失去上次会话信息。扩展方法如下:

1.可以让客户端把所有请求发送到拥有该session id的Tomcat实例中。但是存在的问题在于,如果这个服务端实例挂了之后,请求就会被转发到其他的服务端Tomcat实例中,session id就会丢失。

2.让Tomcat实例把session id同步复制到其它的Tomcat实例上,来保证无论请求由哪一个Tomcat实例来响应,都有session id。问题在于,服务器端同步session id开销大,而且容易丢失。

3.服务端的session都存在一个redis进行共享
在这里插入图片描述

集合容器

一、简述HashMap扩容原理。为什么说HashMap多线程下不安全?

JDK1.7:开辟一个更大的数组,并通过一个双层循环(有链表节点需要第二层循环,链表插入是头插法,因此拷贝过去后整个新链表会翻转)把原数组的节点完整拷贝过去。

多线程下可能会导致链表成环,出现while死循环。根本原因在于使用头插法

JDK1.8:同1.7,区别在于链表插入使用了尾插法,且要拷贝的节点正好是一棵红黑树的根,那么要重新计算红黑树下每个节点对应在新数组下的索引下标位置(数组容量不同,下标不一定相同)。

并发执行put操作时,如果线程A未插入时就挂起,则当A重新获得时间片后直接插入,会出现数据覆盖情况。

二、为什么使用ConcurrentHashMap?简述ConcurrentHashMap在JDK7和8下的区别?

1.因为HashMap多线程环境下不安全;而HashTable通过synchronized保证线程安全,但是它的锁粒度比较大,是一个全表锁,因此效率会比较低。

两者区别在于①继承父类不同②HashMap扩容时是原来的两倍;而HashTable扩容时容量变为原来的两倍加一。③HashMap解决冲突时节点数量小于8则用链表解决,大于等于8则用红黑树进行存储,小于6时由转化为链表存储;而HashTable解决冲突都是以链表方式进行存储。
在这里插入图片描述

2.ConcurrentHashMap在JDK1.7下使用的是分段锁机制,一个ConcurrentHashMap下维护一个segment数组,每个segment下都有一个HashMap链表并继承ReentrantLock可重入锁。写操作put()时只需要锁住当前Segment不会影响到其它的段,而对于读操作get()则不需要加锁,因为具体的值都是使用volatile来修饰的。缺点在于定位一个数据需要两次hash,第一次先找到该数据所在的Segment,然后再定位在链表中的位置。
在这里插入图片描述

而JDK1.8下则是使用跟HashMap一样的数据结构,维护一个Node数据,冲突时根据该节点长度来扩展为链表或者是红黑树。控制并发的方式是使用synchronized+CAS,这里sychronized不同于HashTable,它只锁住Node节点链表头,只要没有Node节点哈希冲突就不会产生并发问题。

三、ArrayList和LinkedList区别

ArrayList基于动态数组,适合使用下标搜索,随机访问。扩容时头部插入数据损耗性能,而使用尾插法效率更高。初始数组大小为10,每次扩容变数组大小为原来的1.5倍。

LinkedLIst基于链表,适合插入删除。实现了Deque接口,可以当作双端队列使用。

四、String,StringBuilder和StringBuffer区别

1.String是final修饰的,不可变的(它的对象生成在方法区),不可以对对象进行操作。当使用substring()或者是split()等方法时会创建新的String对象。

2.StringBuilder是线程不安全的;而StringBuffer是线程安全的,因为它的每个方法都是synchronized修饰的,但是效率低。使用时一般有限考虑StringBuilder,而在多线程使用共享变量下则需要使用StringBuffer。对象不需要修改则使用String。

3.相互转换

 String str="ssg"; //String和StringBuilder转换
 StringBuilder s=new StringBuilder();
 s.append(str);
 String str2=s.toString();
 /--------------------------------------------------/
 char[] s1=str.toCharArray();  //String和字符数组转换
 String str3=new String(s1,0,s1.length);


今日总结

学习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值