1,讲一下JVM的运行时数据区有哪些,作用分别是什么 ?
《Java虚拟机规范》:Java虚拟机所管理的内存包括:堆、方法区、虚拟机栈、本地方法栈、程序计数器。
Java堆
被所有线程共享的一块内存区域,在虚拟机启动时创建。用于存放对象实例和数组。也是垃圾收集器管理的区域(也叫GC堆)。为了更好的回收、分配内存,Java堆可能划分出多个线程私有的分配缓冲区(TLAB)。
堆大小可以通过参数-Xmx(最大堆大小)和-Xms(初始大小)扩展。如果堆中没有内存完成实例分配,并且堆已无法再扩展,则会抛出OutOfMemoryError异常。
方法区
线程共享区域,用于存储被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。JDK1.8之前也叫“永久代”。
JDK1.7前,运行时常量池存放在方法区中,逻辑包含字符串常量池,
JDK1.7 将字符串常量池、静态变量移到堆中。
JDK1.8之后废弃永久代,改用元空间(Metaspace)代替,采用本地内存实现。
参数-XX:MaxPermSize指定永久代上限大小。方法区如果无法满足内存分配需求,抛出OutOfMemoryError异常。
虚拟机栈
线程私有,生命周期与线程相同。描述的是Java方法执行的线程内存模型:每个方法被执行的时候,虚拟机会创建一个栈帧,用于存储局部变量表、操作数栈、动态连接、方法出口等。
局部变量表:编译期可知的各种虚拟机基本数据类型、对象引用(局部变量表)、returnAddress类型。
如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈容量可以动态扩展,当栈无法申请到足够内存会抛出OutOfMemoryError异常。
本地方法栈
与虚拟机栈作用类似,区别是本地方法栈是为虚拟机使用到的本地方法服务。
程序计数器
Program Counter Register,当前线程所执行的字节码的行号指示器。概念模型中,字节码解释器工作需要通过这个计数器选取下一条执行的字节码指令。
线程私有:多线程是通过线程轮流切换、分配处理器执行时间的方式工作,为了线程切换后能恢复到正确的执行位置,程序器必须是线程独有的,互不影响。唯一一块没有规定任何OutOfMemoryError情况的区域。
2,CountDownLatch和CyclicBarrier的区别?
CountDownLatch允许一个或多个线程等待其他线程完成操作,CyclicBarrier允许一组线程到达某个屏障后阻塞,直到所有线程都到达屏障后才继续运行。
CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset()方法重置。
CyclicBarrier可以获得阻塞的线程数量,了解阻塞的线程是否被中断。
3,了解Redis持久化机制吗?
Redis的持久化是为了重启后能快速恢复数据的一种机制。
提供了两种方式:RDB、AOF
RDB:基于快照方式,即某一时刻的数据,不关注过程;
AOF:只追加文件,执行写命令时同时写入AOF文件,redis重启后只要按照顺序重放就可以恢复到原始状态。
4,Map了解多少,就讲1.8?
常用的Map类:HashMap、Hashtable、LinkedHashMap、TreeMap
Hashtable继承自Dictionary类,与HashMap类似,不同的是:它不允许记录的键或者值为空;支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了 Hashtable在写入时效率比较慢。
LinkedHashMap 是HashMap的一个子类,保存了记录的插入顺序。
TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器。
HashMap底层原理
JDK1.8的HashMap底层是由“数组+链表+红黑树”组成,数组元素由Entry<K,V>表示,每个 Map.Entry其实就是一个key-value对,它持有指向下一个元素的引用,同时又构成了一个链表。容器默认的数组大小initialCapacity为16,加载因子loadFactor为0.75。容器的阈值initialCapacity * loadFactor,默认为 16 * 0.75 = 12。对于插入,默认情况下是使用链表节点。当同一个索引位置的节点在新增后达到9个(阈值8)则会触发链表节点转红黑树节点保存。当同一个索引位置的节点在移除后达到 6 个,并且该索引位置的节点为红黑树节点,会触发红黑树节点转链表节点。
put方法:
hash算法算出当前key的hash值,通过hash值去调用 indexFor方法(hash&(length-1))计算当前对象应该存储在数组的几号位置;
将当前对应的 hash,key,value封装成一个Entry,去数组中查找当前位置有没有元素,如果没有放在这个位置上;如果此位置上已存在(碰撞),则在链表上进行查找;
节点的key与当前key进行比较,结果为true则把原来节点上的value返回,将当前新的value替换掉原来的value;如果比较为false,则继续查找;判断是否是红黑树结构,则调用红黑树方法查找;如果为链表结构,则遍历链表查找,如果找到相同key则替换,没有找到就把刚才封装的新的 Entry中next指向当前链表的末尾结点。验证链表长度是否超过8如果是则转换红黑树处理;
判断当前size是否已经达到了当前阈值,如果已经达到阈值,则先进行数组扩容,将数组长度扩容为原来的2倍。
为什么要用红黑树?
5,Java反射与动态代理了解多少?
反射:Java程序在运行过程中可以动态获取类信息和对象的属性方法的功能
动态代理:在程序运行时,运用反射机制动态的创建代理对象并动态地处理对其所代理的方法的调用。
JDK动态代理类位于Java.lang.reflect包下,主要是InvocationHandler和Proxy两个类
主要步骤:
提供一个基础的接口,作为被调用类型和代理类之间的统一入口;
通过实现InvocationHandler接口的invoke方法来自定义自己的处理类,对代理对象方法的调用,会被分派到其 invoke方法来真正实现动作;
调用java.lang.reflect.Proxy类的newProxyInstance 方法,生成一个实现了相应基础接口的代理类实例。
6,事务嵌套的场景,A方法调用B方法事务的传播机制,B方法抛出异常以及发生异常被Catch时A会发生什么场景?
@Transactional(propagation=Propagation.REQUIRED)
如果B方法抛出异常,不管满足B还是A的注解的回滚事务都会回滚;(只要最顶层方法有事务控制,不管是哪个被调用的方法异常,整个调用的业务数据都回滚,不管被调用的方法是否有添加了事务的控制。)
如果B方法异常被捕获,由于B
方法抛出异常导致事务已经回滚,且当前事务被标志为仅回滚,因此当前事务只能回滚,不能再执行提交,此时A方法捕获异常执行提交,会发生异常Transaction rolled back because it has been marked as rollback-only。
7,事务失效的场景?
数据库引擎不支持事务;
所在的类是否是否被spring 管理;
被调用方法不是public修饰;
使用注解事务,同一个对象调用;
异常被捕获;
@Transactional的扩展配置propagation是否正确。
8,AOP有用过吗?什么场景下?原理是什么?
AOP: Aspect Oriented Programming,面向切面编程。
主要用于解决:横切逻辑代码重复问题,代码臃肿。在不改变原有业务逻辑情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复。横切逻辑代码主要是权限校验、日志记录、事务控制、性能监控等业务。
实现原理是动态代理,主要有JDK动态代理和CBLIB动态代理。
9,介绍下mysql的索引?
10,ABC三列字段,让你来建立索引,你会怎么建?为什么?这样建立什么sql会有效,什么sql会失效?
这道面试题你确定不看看吗:一条sql语句,有多个查询条件,你会选择哪个字段作为索引,为什么?_我是树懒的博客-CSDN博客
组合索引不生效场景:where 子句中没有使用到A字段
11, mysql发生死锁的场景,描述一下发生死锁的过程,你们怎么避免?
A查询记录1并更新,B也更新记录1;
当A使用共享锁锁住记录时;B申请排它锁,等待;A此时也申请排它锁,等待,造成死锁。
改为乐观锁
12,垃圾回收算法 标记-复制算法用到了堆的哪一部分?
标记复制算法:将内存划分为大小相等的两块,每次只使用其中一块,当第一块内存使用完了,就把这块内存上存活的对象复制到另一块未使用的内存上,然后清空第一块内存,这种回收对象的算法被称为“标记-复制算法”。
堆中的两块Survivor区域使用到的就是标记复制算法;
13,什么时候用ThreadLocal,使用ThreadLocal注意事项 ?
线程中使用ThreadLocal.ThreadLocalMap维护线程本地变量,
使用场景:用于全局存储用户信息,多数据源切换。
因为ThreadLocalMap中的key为ThreadLocal的弱引用,如果key没有外部强引用,则会在下次垃圾回收中被清理,但是value是强引用,不会被清理,就会出现 key为null的value,当value是很大的对象就会存在内存泄漏风险。手动调用remove方法。
14,TCP三次握手,为什么是三次 ?
TCP
,Transmission Control Protocol(
传输控制协议)。
是一种面向连接的
、可靠的
、基于字节流
的传输层通信协议。
三次握手:
服务端新建套接字,绑定地址信息后开始监听,进入LISTEN状态;客户端新建套接字绑定地址信息后调用connect,发送连接请求SYN,并进入SYN_SENT状态,等待服务器的确认。
服务端一旦监听到连接请求,就会将连接放入内核等待队列中,并向客户端发送SYN和确认报文段ACK,进入SYN_RECD状态;
客户端收到SYN+ACK报文后向服务端发送确认报文段ACK,并进入ESTABLISHED状态,开始读写数据。服务端一旦收到客户端的确认报文,就进入ESTABLISHED状态,就可以进行读写数据了
为什么是三次?
两次不安全,四次没必要。tcp通信需要确保双方都具有数据收发的能力,得到ACK响应则认为对方具有数据收发的能力,因此双方都要发送SYN确保对方具有通信的能力。第一次握手是客户端发送SYN,服务端接收,服务端得出客户端的发送能力和服务端的接收能力都正常;第二次握手是服务端发送SYN+ACK,客户端接收,客户端得出客户端发送接收能力正常,服务端发送接收能力也都正常,但是此时服务器并不能确认客户端的接收能力是否正常;第三次握手客户端发送ACK,服务器接收,服务端才能得出客户端发送接收能力正常,服务端自己发送接收能力也都正常。
15,synchornized与lock区别 ?
synchornized是java关键字;lock是接口类。
synchornized是可重入,非公平的;lock可重入,可以指定公平性。
lock更可扩展性强,可以判断锁状态,适合大量同步场景;synchornized无法判断,适合少量同步。
synchornized自动释放锁;lock需要手动释放,否则会造成死锁。
16, 对比过Mq和kafka的区别吗?
RabbitMQ用于实时的,对可靠性要求较高的消息传递上;kafka用于处于活跃的流式数据,大数据量的数据处理上。
RabbitMQ以broker为中心,有消息的确认机制;kafka以consumer为中心,无消息的确认机制。
RabbitMQ支持消息的可靠的传递,支持事务,不支持批量操作,基于存储的可靠性的要求存储可以采用内存或硬盘,吞吐量小;kafka内部采用消息的批量处理,数据的存储和获取是本地磁盘顺序批量操作,消息处理的效率高,吞吐量高。
RabbitMQ本身不支持负载均衡,需要loadbalancer的支持;kafka采用zookeeper对集群中的broker,consumer进行管理,通过zookeeper的协调机制,producer保存对应的topic的broker信息,可以随机或者轮询发送到broker上,producer可以基于语义指定分片,消息发送到broker的某个分片上。
17, 怎么确保RabbitMQ的消息能够投递到服务上 ?
RabbitMQ 消息的可靠投递_chy_18883701161的博客-CSDN博客
18, 描述下什么是幻读?
一个事务中多次按相同条件查询,结果不一致。体现在数据多了或少了。
事务A查询数据中间,读取到事务B新增或者删除的数据更新。
串行化可以解决。
19, 如何能够使JVM内存溢出?
堆、方法区等没有足够的内存分配都会报内存溢出;
1、Metaspace内存设置太小
2、就是代码里面有大量生成了动态类
20, 数据库的索引结构能介绍下吗?innodb和myisam的区别是什么?
MySQL在5.5版本之前默认采用MyISAM存储引擎,从5.5开始采用InnoDB存储引擎。
1、事务和外键
InnoDB支持事务,具有提交,回滚和崩溃恢复能力,事务安全。
MyISAM:不支持事务和外键,访问速度快。
2、锁机制
InnoDB支持行级锁,锁定指定记录。基于索引来加锁实现。
MyISAM支持表级锁,锁定整张表。
3、索引结构
InnoDB使用聚集索引(聚簇索引),索引和记录在一起存储。
MyISAM使用非聚集索引(非聚簇索引),索引和记录分开。
4、并发处理能力
InnoDB读写阻塞可以与隔离级别有关,可以采用多版本并发控制(MVCC)来支持高并发;
MyISAM使用表锁,会导致写操作并发率低,读之间并不阻塞,读写阻塞。
5、存储文件
InnoDB表对应两个文件,一个.frm表结构文件,一个.ibd数据文件。InnoDB表最大支持64TB;
MyISAM表对应三个文件,一个.frm表结构文件,一个MYD表数据文件,一个.MYI索引文件。从MySQL5.0开始默认限制是256TB。
21,zookeeper的脑裂怎么处理?
脑裂,是指在多机房(网络分区)部署中,若出现网络连接问题,形成多个分区,则可能出现脑裂问题,会导致数据不一致。(严重故障,违反zookeeper实现一致性原则)
集群基本概念—脑裂的产生和解决方案_布鲁斯能上天的博客-CSDN博客_集群脑裂是什么意思
22,秒杀系统流量削峰这事应该怎么做?
消息队列、答题、分层过滤;限流和机器负载保护