【java 面试总结】

面试中常问到的问题

zk的选举机制及cap原则

  1. 半数机制: 集群半数以上存活可用,按机器启动顺序分配id,启动越晚id越大,启动时给自己投一票,然后和别人交换id,大的胜出, 超过半数被选为leader,其他后面的服从,选举完成
  2. leader挂了,follower重新选举,id大的胜出,成为leader, leader可以读写,follower只能读
  3. cap原理是指:一致性,可用性,分区容错性,三则无法同事满足,只能三选二,zk是满足cp, C就是他的同步机制(初始化同步和更新同步),P指的是他某个节点网络不通的情况下,可以由其他节点提供数据,但是leader挂了需要重新选举,不能提供服务所以他不满足可用性

jvm模型及调优

https://blog.csdn.net/weixin_48268269/article/details/125534970

  1. jvm分为执行引擎+内存模型
  2. jvm内存模型分为五个部分: 堆,虚拟机栈, 本地方法栈,元空间、程序计数器
  3. jvm GC
    a. GC通过roots引用查找,找不可以找到root引用的对象,该类对象不存活,可以被清除,首先GC时jvm会stw找到所有roots,可被作为roots的对象有,静态变量、常量引用对象,
    方法栈中本地变量表引用的对象,也就是进栈方法的局部变量。
    b. 首先执行minor GC也叫yong GC,主要清理的是年轻代的eden区域的对象,当年轻代eden区满了以后,GC扫描年轻代eden,被引用的对象被打上标记, 并将打上标记被转移到s1,清除eden区;
    下次GC继续扫描,eden区和s1区中存活的被转移到s2 ,清理eden, s1;下次GC返过来,然后往复上面的步骤请求最后经历15次GC被转移到老年代,当然s区不够会被直接转移到老年代。
    这就是minor GC的标记清除法,其中年轻代中内存占比eden:s1:s2 = 8:1:1, 可以通过参数设置
    c. major GC也叫full GC,用来清理老年代,当老年代内存占用达到90%执行GC, 清除未被引用的对象
    d. 年期代和老年代比例我1:2, 可以通过参数设置
    e. GC垃圾回收算法
    gc垃圾回收常用的算法有3中
  1. 标记清除法
  2. 标记整理法
  3. 复制法
    各有优缺点
    java jvm 采用分代收集算法
    年轻代使用复制算法
    老年代使用标记整理活标记清除算法
    f. GC时机
    Minor GC触发条件:当Eden区满时,触发Minor GC。
    Full GC触发条件:
    1).调用System.gc时,系统建议执行Full GC,但是不必然执行
    2).老年代空间不足
    3).方法区空间不足
    4).通过Minor GC后进入老年代的平均大小大于老年代的可用内存
    5).由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小
    g. jvm调优
    JVM初始分配的内存由-Xms指定,默认是物理内存的1/64
    JVM最大分配的内存由-Xmx指 定,默认是物理内存的1/4
  4. 一般制定最大堆内存和初始化堆内存大小一致, 因为最小堆内存空余<40%时扩大到最大堆内存,当最小堆内存空余率达到>70% 缩小到最小堆内存
    这个时候申请到的内存空间并不会释放,而且扩容和收缩存在开销。
  5. 根据年轻代和老年代使用比例调整年轻代占比

高并发

线程锁-悲观锁

a. Synchronized关键修饰注意加锁的对象是类还是实例,自动加锁和释放锁,在没有锁的情况下回等待,这个时候会导致cpu上下文切换,耗费性能,性能较低。
原理是通过在class文件中加入monitorenter和monitorexit实现,1.6以后jdk对其进行了优化

b. RentLocak锁,手动加锁和释放锁,性能高

线程锁-乐观锁

Cas原理

Acompare and set, 是现代CPU广泛支持的一种对内存中的共享数据进行操作的一种特殊指令,CAS 底层是靠调用 CPU 指令集的 cmpxchg 完成的,ABA原理。
把变量A = 1指加载到内存,修改值+1得到 B= 2, cpu在设置新值赋值时比较内存中的值和预期值是否一致,不一致则拒绝,重复执行直到成功
再高并发下可能导致多次重复自选,Cas的使用场景sun.misc.Unsafe类

volatile关键字

volidate关键字修饰的成员变量可以保证内存可见性和禁止指令重排

  1. 内容可见性:多线程中一个线程修改变量后会通知另一个线程变量不可用,另一个线程使用时就会重新加载
  2. 禁止指令重排: 被修改时的变量读写不允许指令重排,可以防止普通读中的判断逻辑分支走错
    指令重排就是jvm程序的优化策略,按最优的方式执行,只保证结果与代码一致不保证顺序一致
    volidate放弃了cpu缓存,性能肯定是有损失,但是相比起synchronized还是有好处的,volidate不能保证原子一致性,所以
    volatile最适合用的场景是一个线程修改被volatile修饰的变量,其他多个线程获取这个变量的值,不适用多个线程并发修改一个变量,
    当多个线程并发修改某个变量值时,必须使用synchronized来进行互斥同步

cas和volatile组合使用

java.util.concurrent.atomic包下的类,使用volatile修饰变量同时使用Unsafe类 保证Cas
volatile 保证共享变量的可见性,CAS 保证更新操作的原子性, 从而保证无锁状态下的高并发

各种锁介绍

  1. 公平锁 vs 非公平锁
    2)乐观锁 VS 悲观锁
    3)可重入锁
  2. 读写锁
    5)自旋锁 & 适应性自旋锁
    6)无锁 vs 偏向锁vs 轻量级锁 vs 重量级锁
  3. 独占锁 vs共享锁

redis的几种数据类型及redis快的原因

a. 数据类型有:

  1. string
  2. list
  3. set
  4. zset带权重
  5. hash
    b. redis高可用方案
  6. 搭建集群,使用主从模式搭建集群,投票选举模式判断节点是否存活,如果主节点挂了从节点会顶上
  7. 持久化到硬盘策略
    2.1)aof追加的方式写入本地磁盘,这种方式性能低但是防止数据丢失, 可以选择每秒或者有修改时追加,使用重写机制缩减文件大小
    2.2)rdb以快照的方式写入dump文件,覆盖原先的文件,通过fork子进程一定频率执行一次,期间可能导致主进程宕机,这种方式性能高但是容易丢失数据,但是效率高
    c. redis快的原因
  8. 单线程减少cpu上下文切换消耗
  9. 使用io多路复用模型
    d. 如何防止数据丢失
    f. redis事务
    通过开启(mutli)、执行(exec)、取消控制事务(discad),但是是弱事务,不支持回滚, 就是出错一个事务内不回滚

TCP三次握手和4次挥手

spring cloud

数据库 mysql

网络7层

spring 循环依赖中的三级缓存

spring三级缓存失效情况

spring配置问题导致三级缓存失效

项目中遇到比较难得问题&怎么解决

如果管理团队

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值