spring面试

spring bean 容器的生命周期是什么样的?

spring bean 容器的生命周期流程如下:

  1. Spring 容器根据配置中的bean 定义中实例化bean。
  2. Spring 使用依赖注入填充所有属性,如bean 中所定义的配置。
  3. 如果bean 实现BeanNameAware 接口,则工厂通过传递bean 的ID 来调用setBeanName()。
查看更多

spring源码

生命周期:在后台线程处理

AbstractApplicationContext reflesh方法卡点:来dubug主流程

tomcat 下Lifecycle类包含tomcat生命周期变迁路示

不去996的,要空余时间学习,不要浪费时间在无用的事上

可实现可不实现,是勾子函数

查看更多

kafka关键点

如何保证消息队列的高可用?

replica(复制品)副本机制。每个 partition 的数据都会同步到其它机器上,形成自己的多个 replica 副本。broker宕机,存在leader partition ,则会从其他broker上该partition
 的follower 中,选举leader。

如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?

Kafka 使用offset记录消息者消费记录,消费者来保证幂等性

  • 写db时,用主键查,存在则更新;使用唯一约束
  • 写redis时,不用处理,天然幂等性
查看更多

aqs与volatile

aqs.png

volatile.png

AQS就是基于CLH队列,用volatile修饰共享变量state,线程通过CAS去改变状态符,成功则获取锁成功,失败则进入等待队列,等待被唤醒

自旋锁是一种非阻塞锁,它的核心机制就在自旋两个字,即用自旋操作来替代阻塞操作。某一线程尝试获取某个锁时,如果该锁已经被另一个线程占用的话,则此线程将不断循环检查该锁是否被释放,而不是让此线程挂起或睡眠。一旦另外一个线程释放该锁后,此线程便能获得该锁。自旋是一种忙等待状态,过程中会一直消耗CPU的时间片。

互斥锁有一个很大的缺点,即获取锁失败后线程会进入睡眠或阻塞状态,这个过程会涉及到用户态到内核态的调度,上下文切换的开销比较大。假如某个锁的锁定时间很短,此时如果锁获取失败则让它睡眠或阻塞的话则有点得不偿失,因为这种开销可能比自旋的开销更大。
总结起来就是互斥锁更适合持有锁时间长的情况,而自旋锁更适合持有锁时间短的情况。

查看更多

缓存数据分布的算法

Hash

对服务器节点数取模

缺点:增加或减少节点时,查找时无法直接定位节点

一致性Hash

一致性Hash算法是对2^32取模,将整个哈希值空间组织成一个虚拟的圆环,这个由2^32个点组成的圆环称为Hash环

2,将各个服务器使用Hash进行一个哈希(选择服务器的IP或主机名作为关键字)
3,定位数据节点:将数据key使用相同的函数Hash计算出哈希值,并确定此数据在环上的位置,从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器

容错性和可扩展性

查看更多

cas

CAS的全称为Compare-And-Swap ,它是一条CPU并发原语。它的功能是判断内存某个位置的值是否为预期值,如果是则更新为新的值,这个过程是原子的。
CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。 如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值 。否则,处理器不做任何操作。

CAS操作都是通过sun包下Unsafe类实现,而Unsafe类中的方法都是native方法,由JVM本地实现

CAS缺陷: 循环时间太长、只能保证一个共享变量原子操作、ABA问题

AtomicStampedReference

MySQL复制

MySQL的异步复制、全同步复制与半同步复制

半同步复制(Semisynchronous replication)

  1. 逻辑上

是介于全同步复制与全异步复制之间的一种,主库只需要等待至少一个从库节点收到并且 Flush Binlog 到 Relay Log 文件即可,主库不需要等待所有从库给主库反馈。同时,这里只是一个收到的反馈,而不是已经完全完成并且提交的反馈,如此,节省了很多时间。

查看更多