1.list和set的区别
List和set都是继承collection的接口。List的实现是有序的序列,允许有重复的元素。允许多个null元素。Set的实现是无序的容器,不包括a.equal(b)的元素。所以不允许有重复的元素。
2.HashSet是如何保证不重复的。
HashSet的构造方法是实例还一个hashMap,然后把add进去的value当做hashMap的key值保存到hashMap进去,这个时候hashMap的value默认一个值。因为hashMap的key是不能重复的,所以也就保证了hashSet的不重复性。hashMap的key值不重复性如下:
通过添加元素的hash(a.hashCode)和equal对比保证的。如果hash值不同,说明为新元素,如果hash值相同,则通过equal判断,如果equal相同,则为已存在元素,不添加进去,否则为新元素,则添加进去。
3.为什么hashMap不能保证线程安全。
原因很多,其中一个的原因是put方法非线程同步的。解释如下:hashMap调用put方法添加的时候,如果碰上hash碰撞,也就是两个put的值hash值一样,这个时候就要把值添加到同一个链表上。因添加时是非线程安全的,所以不能保证hashMap的线程安全性。
4.Sychronized实现原理
此关键字是把任何一个非null对象作为锁。当sychronized作用到一般方法上时,锁住的是对象的实例,作用到静态方法上时,锁住的就是对象对应的class实例,由于class实例存在于永久代中,因此静态方法锁相当于类的一个全局锁。
作用到同一个类上一个实例上的两个不同的非静态sychronized方法,实现同步。原因是两个方法都需要去竞争同一个实例上的对象锁,所以实现同步。
作用到同一个类上2个实例上的两个不同的静态sychronized方法,实现同步。原因是两个方法是静态方法,所以需要竞争同一个类的class实例对象锁。一个类即时有多个实例,也只有一个class实例。所以实现同步。
5.Sychronized和lock
Sychronized是java内置的关键字,lock只是一个类。Sychronized释放锁是线程允许完会自动是否锁,或者线程运行异常,也会释放锁。而lock需要手动的释放锁,如果不释放可能会造成死锁。
Syschronized不灵活,lock灵活。
6.关于dubbo
·dubbo是一个分布式服务框架。
·有各个节点组成,Provider:暴漏服务的服务提供方。Consumer:调用远程服务费的服务消费方。Registry:服务注册于发现的注册中心。Monitor:统计服务调用次数及时间的监控中心。Container:服务允许容器。调用关系说明:服务容器负责启动、加载、运行服务提供者。服务提供者启动时,想注册中心注册自己提供的服务。服务消费者启动服务时,想注册中心订阅自己所需的服务。注册中心返回服务提供者的服务列表给服务消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者,服务消费者,从服务提供者列表里面,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选择另一台。服务提供者和消费者,在内存中统计调用次数及时间,定时没分钟报送给监控中心。
·dubbo提供很多协议,dubbo协议、RMI协议、Hession协议等等。Dubbo默认使用的协议是dubbo协议。如下配置:
<!-- 配置服务提供者协议:设置dubbo提供服务的端口-->
<dubbo:protocol name="dubbo" port="20400" accesslog="false" threads="800" host="${fund.dubbo.host}"/>
Dubbo协议采用单一长连接和NIO异步通讯,适合小数据量大并发的服务调用,以及服务消费者数据远大于服务提供者机器数的情况下。它不太适合传送大数据量的服务,比如文件、视频等。
7.Redis数据结构
Redis内部存储数据类型为:String(字符串)、list(列表)、hash(哈希)、set(集合)、zset(有序集合)
Redis是单线程,线程安全。因为是单线程,所以线程安全。
8.关于内存
关于内存溢出,有堆溢出和栈溢出。总的来说都是堆和栈超过了最大容量导致溢出。如堆溢出,我们知道堆里面主要存储的是对象,如果往堆里面添加过多的对象就会引起堆内存溢出如:while(true){new Object();},就会引起堆内存的溢出。对于栈,我们知道,栈主要是方法,如果调用的方法过多,可能会引起栈内容溢出。例如:
Public class Test{
int i = 0;
public void aa(){i++;this.aa();}
public static void main(String arg[]){new Test().aa();}
}
强引用:垃圾回收器不会回收他,当内存空间不足时,java虚拟机会抛出内存溢出异常,是程序终结,也不会随意回收强引用对象来解决内存不足。
软引用(SoftReference):在保持对象的引用时保证java虚拟机内存不足时把他清除掉。清除取决于垃圾回收器的算法及java虚拟机内存情况。
软引用可以用来实现内存敏感的高速缓存,比如网页缓存、图片缓存等。
弱引用(weakReference):对于生存周期相对较长且重新创建的开销也不高时比较有用。当垃圾回收器运行时如果碰到了弱可及对象,将释放弱引用对象。
弱对象是用来描述非必须对象的,当jvm进行垃圾回收时,无论内存是否充足,都会回收弱引用关联的对象。
虚引用(PhantomReferenc):随时可收集。虚引用和软引用及弱引用不同,他不影响对象的生命周期,如果一个对象只与虚引用关联,则跟没有引用关联一样,在任何时候都可以被垃圾回收器回收。
9.TCP三次握手
TCP传输的过程是,建立连接、数据传输、断开连接。
建立连接的TCP三次握手,通俗说法:
C:你好,听到我说话吗?
S:听到了。你能听到我说话吗?
C:听到了。(三次握手完成)
断开连接的四次握手,通俗说法:
C:你好,我要断开连接
S:好的,稍等
S:你好,我已经断开了。
C:好的,知道了。(四次握手完成)
10.CAP理解
CAP是分布式架构的理论基础,主要是
C(一致性):数据一致更新、所有的数据变动都是同步的。
A(可用性):好的响应性能。
P(分区可容忍性):可靠性。
11.CAS操作
cas全称是比较和替换。compare and swap;CAS操作相当于乐观锁。syschronized相当于悲观锁。都是相对于线程来说的,CAS操作也就是不加锁的线程安全。
其核心算法有三个参数,CAS(V,E,N),V表示要更新的变量;E表示预期值;N表示新值; 如果V值等于E值,则将V的值设为N。若V值和E值不同,则说明已经有其他线程做了更新,则当前线程什么都不做。
通俗的理解就是CAS操作需要我们提供一个期望值,当期望值与当前线程的变量值相同时,说明还没线程修改该值,当前线程可以进行修改,也就是执行CAS操作,但如果期望值与当前线程不符,则说明该值已被其他线程修改,
此时不执行更新操作,但可以选择重新读取该变量再尝试再次修改该变量,也可以放弃操作