java基础:
1.list去重:hashset.addall
2.hashset底层用hashmap实现,保证不会重复
3.hashmap的底层实现和concurrenthashmap的底层实现?
a、hashmap:
容量、加载因子、扩容阈值
b、concurrenthashmap
http://www.importnew.com/28263.html
https://crossoverjie.top/2018/07/23/java-senior/ConcurrentHashMap/
http://www.jasongj.com/java/concurrenthashmap/
4.
java并发:
wait和sleep的区别:
1.所属的类不一样wait:Object sleep:Thread
2.调用sleep方法的线程不会释放对象锁,而调用wait() 方法会释放对象锁
synchronized 的实现原理以及锁优化? (悲观锁)
同步代码块底层是通过monitorenter和monitorExit指令实现,同步方法修饰符上的ACC_SYNCHRONIZED实现。
synchronized 在静态方法和普通方法,代码块。
锁优化:
1.自旋锁:
2.自适应自旋锁
3.锁消除 :不可能存在数据竞争,逃逸分析(不会当做参数传到其它方法等)。StringBuffer的append()方法
4.锁粗化:加锁出现在循环体之内。
5.偏向锁
6.轻量级锁
7.重量级锁:对性能有较大影响,挂起和恢复线程从用户态到内核态。
cas:乐观锁
自旋CAS(也就是不成功就一直循环执行直到成功)如果长时间不成功,会给CPU带来非常大的执行开销。
对象,内存偏移量,预期值和新值。
volatile 的实现原理? (没有原子性)(java内存模型)
happen-before原则:
在单线程环境下我们可以认为整个步骤都是原子性操作,但是在多线程环境下则不同,Java只保证了基本数据类型的变量和赋值操作才是原子性的(注:在32位的JDK环境下,对64位数据的读取不是原子性操作*,如long、double)。要想在多线程环境下保证原子性,则可以通过锁、synchronized来确保。
1.可见性(内存模型)
2.指令重排序
观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令。lock前缀指令其实就相当于一个内存屏障。内存屏障是一组处理指令,用来实现对内存操作的顺序限制。volatile的底层就是通过内存屏障来实现的。
3.transient
java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
AQS:
ReentrantLock:排他锁
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
tryAcquire():
a.先尝试快速放到队尾 b.不成功则放入队列,CAS"自旋",直到成功加入队尾
3.acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
CountDownLatch:共享锁
ArrayBlockingQueue,AtomicInteger,ReentrantReadWriteLock,ReentrantLock和Condition,future和callback,fork/join,线程池。
Spring:
1、BeanFactory 和 FactoryBean的区别?
BeanFactory是容器,FactoryBean特殊的bean。
2.bean的加载过程
1.bean的解析:加载资源-封装资源-获取输入流-获取对xml文件的验证模式(DTD or XSD)-加载xml,得到对应的document-根据返回的document注册bean的信息。
3.Spring 循环注入的原理?
提前暴露ObjectFactory,循环依赖的时候回实例化好。
算法:
两个栈实现一个队列
分布式id:
https://tech.meituan.com/2017/04/21/mt-leaf.html
消息系统:
高可用:
kafka:由多个 broker 组成,每个 broker 是一个节点;你创建一个 topic,这个 topic 可以划分为多个 partition,每个 partition 可以存在于不同的 broker 上,每个 partition 就放一部分数据。HA(High Availability, 高可用性) 的机制:Kafka 0.8 以后,提供了 HA 机制,就是 replica(复制品) 副本机制。每个 partition 的数据都会同步到其它机器上,形成自己的多个 replica 副本。所有 replica 会选举一个 leader 出来,那么生产和消费都跟这个 leader 打交道,然后其他 replica 就是 follower。写的时候,leader 会负责把数据同步到所有 follower 上去,读的时候就直接读 leader 上的数据即可。只能读写 leader?很简单,要是你可以随意读写每个 follower,那么就要 care 数据一致性的问题,系统复杂度太高,很容易出问题。Kafka 会均匀地将一个 partition 的所有 replica 分布在不同的机器上,这样才可以提高容错性。
如何保证消息消费的幂等性:
业务幂等,数据库唯一索引
如何处理消息丢失的问题:
消费端:关闭自动提交 offset,但是此时确实还是可能会有重复消费,自己保证幂等性
mq:
replication.factor
参数:这个值必须大于 1,要求每个 partition 必须有至少 2 个副本。min.insync.replicas
参数:这个值必须大于 1,这个是要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系,没掉队,这样才能确保 leader 挂了还有一个 follower 吧。acks=all
:这个是要求每条数据,必须是写入所有 replica 之后,才能认为是写成功了。retries=MAX
(很大很大很大的一个值,无限次重试的意思):这个是要求一旦写入失败,就无限重试,卡在这里了。生产者:ack=all。
设计mq:
高可用,可伸缩,消息确保(持久化)
原文:https://www.cnblogs.com/faker2014/p/10541625.html