同花顺一面面经
面经
写面经,攒人品
- 自我介绍
- jvm
- 堆内存溢出
- 怎么快速的堆内存溢出
- 溢出怎么防止
- 为什么会堆内存溢出
- 不段创建String对象,和不断创建线程造成溢出的区别?
- 怎么分析,dump内存文件
- 分析hprof文件,有那些内容
- 栈指针溢出
- 怎么快速的栈指针溢出
- 怎么防止
- 为什么会栈指针溢出
- 垃圾回收器
- 你们用的垃圾回收器
- 你知道的垃圾回收器
- 讲一讲过程,区别(CMS,G1)
- 堆内存溢出
- redis分布式锁实现
- mysql索引,为什么需要索引,自己的理解
- mysql索引的数据结构
- 你们数据量级,一次处理的数据量
- 线程池,几个核心参数的作用,不背原理
- hashmap和hashtable的区别
- dubbo如何实现高可用的
- 反问
解答
redis分布式锁的实现
mysql索引,为什么需要索引
mysql索引的最大最用就在于提高查询效率,原理在数据结构中,索引在提高查询效率的同时降低了修改的效率。
mysql索引的数据结构
索引数据的组织结构和数据的组织结构是一样的,都是B+树的结构,区别在于他们的叶子节点所存储的数据,数据存储文件中叶子节点中存储着主键索引和表中的数据,而索引保存文件中,叶子节点则存储着索引字段以及对应的主键id值。
当通过素引进行查询时,会先根据索引查询出主键id的值,在在数据保存文件中,根据id查出所需要的数据,这个过程叫做回表。
线程池理解(corepoolsize)
- threadpool
- threadpool
个人理解,核心线程数,就相当于车间里面的流水线数,就是正常情况下运行的流水线数,最大的线程数,就是再有紧急订单的情况下,我们在正常的流水线上,扩充到的流水线数。
hashmap和hashtable
hashmap和hashtable的区别有几点:
- 继承和实现方式不同
- hashmap实现的是map接口
- hashtable实现的是map接口继承的Dictionary类
- 线程安全不同
- hashmap线程不安全
- hashtable线程安全,在每个方法中都加入Synchronize方法。
- 对null的处理不同
- hashtable键与值均不允许null
- hashmap均可以null,null为键只会有一个
- 支持的遍历种类不同
- Hashtable、HashMap都使用了Iterator。
- 而由于历史原因,Hashtable还使用了Enumeration的方式 。
- 通过Iterator迭代器遍历时,遍历的顺序不同
- hashmap采用fail-fast机制
- hashtable在1.8以后才用了fail-fast机制
- 容量的初始值和增加方式都不一样
- hashmap初始16,扩容为2倍
- hashtable为11,扩容为2*N+1
- 添加key-value时的hash值算法不同
- haspmap采用key的hashcode确定位置
- hashtable采用对象的hashcode,然后对长度才用除留余数法确定位置
dubbo如何实现高可用
dubbo通过一系列手段实现了,高可用。
- zookeeper宕机与dubbo直连
- zookeeper注册中心宕机,还可以消费dubbo暴露的服务
- 监控中心宕掉不影响使用,只是丢失部分采样数据
- 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
- 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
- 注册中心全部宕机后,可以通过本地缓存进行通信,(直连)
- 服务提供者无状态,任意一台宕掉后,不影响使用
- 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
- zookeeper注册中心宕机,还可以消费dubbo暴露的服务
- 集群下的负载均衡
- 带权重的随机
- 带权重的轮询
- 最少活跃数
- 一致性hash
- 服务降级
- 集群容错机制
- Failover Cluster:失败自动切换
- Failfast Cluster:快速失败,失败则立即报错
- Failsafe Cluster:安全失败,失败就会忽略
- Failback Cluster:失败自动恢复,会定时重发
- Forking Cluster:并行调用,只需一个成功返回
- Broadcast Cluster:广播调用,逐个调用每个提供者,任意一台报错则报错
JVM
堆内存溢出
怎么快速的堆内存溢出?
通过jvm参数去设置堆内存大小,然后再循环里面不断的创建线程,直到报OutOfMemory异常。
堆内存溢出怎么防止?
最直接的办法就是直接调整堆内存的大小,也有一写在编写代码过程中注意的,防止内存溢出:
- 尽早释放无用对象的引用
- 程序进行字符串处理时,尽量避免使用String,而应该使用StringBuffer
- 尽量少用静态变量(全局的,存在方法区,不会被回收)
- 避免集中创建对象,尤其是大对象,如果可以的话尽量使用流操作
- 尽量运用对象池技术以提高系统性能
- 不要在经常调用的方法中创建对象,尤其忌讳在循环中创建对象
- 优化配置
- 从代码层面进行优化完善,尽量避免该情况发生
- 调整优化服务器配置:
- 设置-Xms、-Xmx等
- 设置NewSize、MaxNewSize相等
- 设置Heap size,PermGen space
可以通过一些手段保证代码安全:
- 是否应用中的类中和引用变量过多使用了Static修饰
- 是否应用中使用了大量的递归或无限递归(递归中创建对象)
- 是否App中使用了大量循环或死循环(循环中创建对象)
- 检查应用中是否使用了向数据库查询所有记录的方法
- 检查是否有数组,List,Map中存放的是对象的引用而不是对象(这些引用会使得对象无法被释放)
- 检查是否使用了“非字面量字符串进行+”的操作,String对象每次+
为什么会堆内存溢出?
内存大小不够;是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory。
不断创建String和不断创建线程造成内存溢出的区别?
本质上,创建String就是创建了一个对象,分配了一块内存空间,而创建线程,则也会创建线程对象(Thread类的对象),区别在于创建线程的对象中,会包含一些线程的相关信息,也就是区别在线程对象的信息和普通对象的信息不同。
怎么分析,dump内存文件
一般有两种方法,自动和手动。
- jvm参数:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/logs/java.hprof
- jmap -dump:format=b,file=/home/admin/logs/heap.hprof javapid
dump内存文件后,可以通过一些工具进行分析。
- mat
- visual VM
- JProfiler
栈指针溢出
怎么快速栈指针溢出?
通过死循环内调用方法,或者递归没有出口,无限递归,造成StackOverFlow异常。
怎么防止栈指针溢出?
通过一些判断,保证代码安全,破坏栈指针溢出的条件:
- 是否有递归调用
- 是否有大量循环或者死循环
- 全局变量是否过多
- 数组、List、map数据是否过大
- 使用DDMS工具进行查找大概出现栈溢出的位置
为什么为栈指针溢出?
栈指针溢出其实可以分为两种,不过一般说的是第一种,本质都是由内存不足引起的。
- 线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError
- 虚拟机在扩展栈深度时无法申请到足够的内存空间,将抛出OutOfMemberError
垃圾回收器
你们用的垃圾回收器?你知道的垃圾回收器?CMS和G1的区别?
参考文献 & 鸣谢
相关文章