- JVM的内存模型
自述:
jvm的内存模型包括:方法区,堆,虚拟机栈,本地方法栈,程序计数器
其中,方法区和堆是线程共享的,虚拟机栈,本地方法栈,程序计数器是线程私有的。
方法区又称为永久代,主要存放类的元数据,静态常量池,1.8以后被元空间取代;
堆是垃圾回收主要管理的部分,主要存放新生成的对象,数组,从垃圾回收的角度又可分为:新生代,老年代;新生代又分为endn去,from,to survior区,采用复制垃圾回收算法;当新生代内存不足时,会进行一次manio gc,回收endn,from区的对象,存活下来的对象存入to区,并将对象的存活年龄+1;老年代主要存放活跃的对象,不经常被回收,采用的标记整理算法,创建的对象大于endn的内存空间,或者存活年龄大于15的对象会存放到老年代,当老年代内存不足时,会出发major gc
虚拟机栈包括:局部变量表,操作数栈,方法返回值,动态链接,和线程的生命周期一直,随着线程的结束而消亡;
-
谈谈GC,CMS的流程,新生代老生代分别用什么算法
复制,标记整理,标记复制 -
谈谈类加载器,类加载器有哪些,双亲委派最终是由父还是子加载
双亲委派机制
自定义classLoader -》 applicationClassLoader -》extendClassLoader -》bootstrapClassLoader
不管哪个类加载器接受到类加载请求,最终都由同一个类加载器加载,保证加载的是同一个类;
最终抛出classNotfundexception
-
操作系统的悲观锁、乐观锁
版本号version -
数据库层面的悲观锁、乐观锁
乐观锁:认为对数据库的操作都是安全的,不会发生冲突;先修改在提交的时候判断纪录是否被更改;实现方式有:cas,version;
cas比较交换,当某个值等于a的时候才可替换成b,否则就重试,但cas无法避免aba问题;
version:提交是时候判断version是否等于查询时的version,否则更新失败;可以用+1的方式实现,也可以用时间戳递增实现;用==比较,会导致同一时刻只有一个线程修改成功,我们需要减少锁力度,提高吞吐率,提高并发量,在秒杀系统中,通常库存数作为锁,比较锁-1>0来实现秒杀业务场景;
悲观锁需要借助数据库锁实现;分为共享锁,排他锁;先获取到锁,再操作
要注意锁的粒度,mysql innodb引擎默认行级锁,但行级锁是走索引的,如果一条sql没有使用到索引,那么锁力度就是标记锁,就会锁住整张表
set autocommit = 0
select for update
使用场景:
响应效率,重试代价,冲突频率;
-
数据库事务讲一下
acid
隔离性,一致性,持久性,原子性 -
Redis的持久化机制
aof,rdb
各自的优缺点:
rdb:加载快,体积小,不安全
如何设置 -
Redis如何实现高可用
集群+哨兵模式
-
索引的类型,索引的底层实现原理
B+数 -
谈谈消息队列
-
HashMap底层实现,哈希冲突怎么解决的
自述:
底层采用的是hash表,由数组和链表组成,1.8后优化为数据+链表+红黑树的结构
对key进行hash运算,并和数组长度与运算得到数组下标,如果当前节点为null,则插入,否则遍历链表,如果相等或equals相等则覆盖value值,否则则新增node插入,1.7之前采用头插法,1.7之后采用尾插法;当元素个数大于阈值的时候,进行扩容操作;2倍扩容,重新计算key的位置;hash是否需要重新计算;
哈希冲突如何解决:对key进行hash运算,使用高16位,低16位进行异或,使数据尽可能的散列,减少碰撞;
- 各种排序算法讲一下
选择排序,冒泡排序,快速排序;