在这里分享一下我的面经吧
Q:Redis 基本数据类型
五个基础数据类型
- String
- Hash
- List
- Set
- Zset
Q:hashMap的底层 怎么计算哈希
Q:LOCK和Synchronized区别 性能区别 lock底层原理
synchronized 和 lock 的区别
1.synchronized是java的一个修饰符 lock是一个类
2.synchronized 可重入锁 不可中断 非公平锁 ;lock 可重入锁 可中断 可以设置公平或非公平锁
3.synchronized 是自动释放锁;lock需要手动加锁解锁
4.synchronized遇到阻塞会死死地等待;lock可以使用trylock()来尝试获得锁
5.synchronizd适合锁代码量较小的代码块。;lock适合锁代码量大的;
6.synchronizd无法判断锁的状态,lock可以判断是否获得了锁。
7.synchronizd是隐式锁,lock是显示锁
Q:事务的隔离级别,可重复读怎么实现的
Q:线程池除了复用线程还有什么好处?线程池的底层实现?
线程的好处
怎么分析呢?首先线程池最大的作用就是线程的复用,因为线程创建和销毁需要花费大量的CPU资源,那么除了可以线程复用还有什么好处呢?我们可以从线程池的七大参数来分析,首先我们可以设置线程的最大并发数,更好管理线程,其次,对于等待的线程我们可以设置最优的拒绝策略来处理线程,或者使用队列来将线程缓存处理,我们还可以使用不同的线程池处理不同的方向的任务,实现业务独立不互相影响。还有线程池提供一些方法实现定时执行、周期执行。
总结如下:
- 利用线程池管理并复用线程、控制最大并发数等。
- 实现任务线程队列缓存策略和拒绝机制。
- 实现某些与时间相关的功能,如定时执行、周期执行等。
- 隔离线程环境。比如,交易服务和搜索服务在同一台服务器上,分别开启两个线程池,交易线程的资源消耗明显要大;因此,通过配置独立的线程池,将较慢的交易服务与搜索服务隔开,避免个服务线程互相影响。
Q:线程池最终容量
线程池运行过程
线程池概述
七大参数之 maxpoolsize 的值
Q:阿里巴巴为什么不用excutors创建线程池 ?
Executors各个方法的弊端:
1)newFixedThreadPool和newSingleThreadExecutor:
LinkedBlockingQueue 其实也是有界队列,但是不设置大小时就时Integer.MAX_VALUE,主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。
2)newCachedThreadPool和newScheduledThreadPool:
主要问题是线程数最大数maximumPoolSize是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。
分析
Q:mysql索引的数据结构,为什么使用B+树?B+树和B树的区别
因为数据只在叶子节点,就可以让更多的非叶子结点空间存放关键字,可以让树更低,就可以减少IO的次数
查询between等一段的数据时可以更快,因为B+树数据都在叶子节点且为一个链表
查询性能比较一致,都在叶子节点,不会有的快有的慢
mysql索引
Q:Http到TCP协议之间的过程
Q:UDP到TCP协议之间的区别
tcp udp 对比
TCP :打电话
连接 稳定
三次握手 四次挥手 ABA ABBA
客户端 服务器端
传输完成 释放连接 效率低
UDP : 发短信
不连接 不稳定
没有服务端客户端的概念
只管发送一个包就完事
Q:TCP三次握手四次挥手
Q:类加载的过程,初始化的过程 初始化后静态变量存放在哪里
- 加载 :JVM将.class字节码文件加载到内存中,并将这些数据(静态变量、静态方法块、常量池等存放在方法区(元空间)中),并在堆中生成Class对象代表这个类
- 校验: 确保加载的类符合JVM安全规范
- 准备: 正式为类的变量(static变量)设置初始值(例如 Integer 设为0)并分配内存空间
- 解析:虚拟机常量池中的符号引用替换为直接引用 地址引用 (比如我们在定义的时候引了另一个类,但是我们并不知道他是啥,就先给他一个符号,解析的时候再来获得他的内存地址改为直接引用)
不懂符号引用和直接引用的可以参考这个博客:https://www.cnblogs.com/shinubi/articles/6116993.html - 初始化: 执行类构造方法(),自动收集类变量的赋值,和执行static静态代码块
Q:JVM内存模型中,JDK1.8和1.7永久代和元空间的区别
先了解一下方法区:
方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的应该是与Java堆区分开来。
永久代和元空间都是方法区的实现方式,元空间是jdk1.8之后才出现的,他最大的区别就是他的物理空间不再是虚拟机,而变成了主机内存,那么我们经常遇到的OOM异常也会相应减少,因为它相对之下比较大。
不错的解析
Q:GC回收的过程,对象成为永久代的条件
GC 算法
堆内存的划分
具体看我的JVM写的还是可以的
Q:Sping怎么解决循环依赖 A中实例化了B B中实例化了A
Q:final关键字用在哪里?可以修饰在方法上吗?类 变量 不能 为什么Interface需要修饰final
一、final关键字可以用来修饰类、方法、变量。
A、修饰类(class)。
1、该类不能被继承。
2、类中的方法不会被覆盖,因此默认都是final的。
3、用途:设计类时,如果该类不需要有子类,不必要被扩展,类的实现细节不允许被改变,那么就设计成final类
B、修饰方法(method)
1、该拥有该方法的类可以被继承,但是不能被覆盖。
2、用途:一个类不允许子类覆盖该方法,则用final来修饰
3、好处:可以防止继承它的子类修改该方法的意义和实现;更为高效,编译器在遇到调用fianal方法转入内嵌机制,提高了执行效率。
4、注意:父类中的private成员方法不能被子类覆盖,因此,private方法默认是final型的(可以查看编译后的class文件)
C、修饰变量(variable)
1、用final修饰后变为常量。包括静态变量、实例变量和局部变量这三种。
2、特点:可以先声明,不给初值,这种叫做final空白 。但是使用前必须被初始化。一旦被赋值,将不能再被改变。
D、修饰参数(arguments)
1、用final修饰参数时,可以读取该参数,但是不能对其作出修改
二、final关键字不能用来抽象类和接口。
我们定义抽象类就是为了来被继承的,接口就是为了来重写的,肯定不能用final修饰。