1、讲一下GC的过程
https://blog.csdn.net/bisal/article/details/106066216
https://blog.csdn.net/bisal/article/details/106846249
https://blog.csdn.net/wangshiwen011/article/details/107473814
https://zhuanlan.zhihu.com/p/107789906
2、什么样的对象会被老年代回收
根据经验来看存在以下几种情况什么发生FullGC(PS:针对Hotsot虚拟机):
- 老年代的使用率达到阈值(通过JVM参数:CMSInitiatingOccupancyFraction设定,默认为92%)
- 永久代的使用率到达阈值CMSInitiatingPermOccupancyFraction设定,默认为92%)
- 当新生代对象沉淀到老年代时担保失败,Eden+s0的对象大于s1区,只能往老年代存放
3、为什么要设置S0,S1区
解决碎片化
https://blog.csdn.net/qq_29066329/article/details/89743047
4、什么样的对象可以作为GC roots
一般而言我们分析出来有以下特点的对象引用是可以作为GC roots的。
- 栈帧当中本地变量表中引用的对象。
- 方法区中类static类型的引用。
- 方法区中常量类型的引用。
- 本地native方法中引用的对象。
https://www.cnblogs.com/wjh123/p/11141497.html
5、多线程的异步调用怎么实现的
6、讲讲你最常用的单例模式 (我答的双重检测)
7、双重检测的INSTACNE为什么要用voliate修饰
-
如果没有加 volatile 就不一定是线程安全的,原因是多线程下有指令重排序的优化的存在,加入 volatile 可以禁止指令重排。
- 原因是在于某一个线程执行到第一次检测,读取到的 instance 不为 null 时,instance 的引用对象可能还没有完成初始化。
instance = new Singleton()
可以分为以下三步完成-
memory = allocate(); // 1.分配对象空间 instance(memory); // 2.初始化对象 instance = memory; // 3.设置instance指向刚分配的内存地址,此时instance != null
步骤 2 和步骤 3 不存在依赖关系,而且无论重排前还是重排后程序的执行结果在单线程中并没有改变,因此这种优化是允许的。
-
发生重排
-
emory = allocate(); // 1.分配对象空间 instance = memory; // 3.设置instance指向刚分配的内存地址,此时instance != null,但对象还没有初始化完成 instance(memory); // 2.初始化对象
-
所以不加 volatile 返回的实例不一定为空,有可能是未初始化的实例
8、voliate怎么保证可见性的
通过插入内存屏障禁止在内存屏障前后的指令执行重排序优化。内存屏障另外一个作用是强制刷出各种CPU的缓存数据 ,因此任何CPU的线程都能读取到这些数据的最新版本。
9、Sychonized的作用是什么
https://www.processon.com/view/5c25db87e4b016324f447c95
https://www.zhihu.com/question/267980537/answer/1267465466
10、Sychonized 和 lock的区别
11、排序算法以及时间复杂度
12、讲讲代理模式
13、网络编程有了解吗,讲讲TCP/UDP的区别
https://www.cnblogs.com/aademeng/articles/11025371.html
14、为什么UDP速率比TCP快
TCP为了实现网络通信的可靠性,使用了复杂的拥塞控制算法,建立了繁琐的握手过程以及重传策略。由于TCP内置在系统协议栈中,极难对其进行改进。
UDP相对于TCP而言,是缺bai少一个可靠的丢失重du发机制,因此zhi可以立即返回,所以你觉得快
UDP属于发射后dao不管,但是从IP层来说,它的效率和TCP相比,几乎相同
TCP为什么慢呢?就是因为需要 发射 确认 这样一个循环过程,所以慢
现在喜欢用UDP代替TCP的原因主要是 TCP的重发机制不完美,等待时间不合理,响应经常偏慢
UDP的问题主要在于丢包,如果你的API层协议规定部分数据可以丢失,那么UDP的响应速度会是最好的选择
同样,如果规定绝对不可以丢包,那么需要你自己在API或者引擎里负责处理UDP的可靠传输
一般测试下,在相对可靠的环境里,UDP的丢包率很低,因此即使采用确认模式传输,速度也很快
但是,如果在INTERNET上,例如 电信到CNC线路,丢包率是偏高的,效率会严重降低,CPU开销剧烈增加[主要是确认机制导致的]
跟谁学(文思海辉)-- 视频面试 44分钟
1、JVM调优的工具和命令,jstat 查看状态都有哪些
2、线程的状态
- 建状态:
使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。 - 就绪状态:
当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。 - 运行状态:
如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。 - 阻塞状态:
如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:- 等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
- 同步阻塞:线程在获取 synchronized同步锁失败(因为同步锁被其他线程占用)。
- 其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。
- 死亡状态:
一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。
3、wait不需要时间吗 sleep 和 wait锁的区别
- 1、sleep是线程中的方法,但是wait是Object中的方法。
- 2、sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中。
- 3、sleep方法不依赖于同步器synchronized,但是wait需要依赖synchronized关键字。
- 4、sleep不需要被唤醒(休眠之后推出阻塞),但是wait需要(不指定时间需要被别人中断)。
- http://baijiahao.baidu.com/s?id=1647423693517849309&wfr=spider&for=pc
4、线程池了解过吗,7种参数
- corePollSize:核心线程数。在创建了线程池后,线程中没有任何线程,等到有任务到来时才创建线程去执行任务。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中。
- maximumPoolSize:最大线程数。表明线程中最多能够创建的线程数量。
- keepAliveTime:空闲的线程保留的时间。
- TimeUnit:空闲线程的保留时间单位。
- BlockingQueue<Runnable>:阻塞队列,存储等待执行的任务。参数有ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue可选。
- ThreadFactory:线程工厂,用来创建线程
- RejectedExecutionHandler:队列已满,而且任务量大于最大线程的异常处理策略。有以下取值
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
5、线程池的阻塞队列用的最多的是什么
主要有3种类型的BlockingQueue:
无界队列
队列大小无限制,常用的为无界的LinkedBlockingQueue,使用该队列做为阻塞队列时要尤其当心,当任务耗时较长时可能会导致大量新任务在队列中堆积最终导致OOM。阅读代码发现,Executors.newFixedThreadPool 采用就是 LinkedBlockingQueue,而楼主踩到的就是这个坑,当QPS很高,发送数据很大,大量的任务被添加到这个无界LinkedBlockingQueue 中,导致cpu和内存飙升服务器挂掉。
有界队列
常用的有两类,一类是遵循FIFO原则的队列如ArrayBlockingQueue,另一类是优先级队列如PriorityBlockingQueue。PriorityBlockingQueue中的优先级由任务的Comparator决定。
使用有界队列时队列大小需和线程池大小互相配合,线程池较小有界队列较大时可减少内存消耗,降低cpu使用率和上下文切换,但是可能会限制系统吞吐量。
在我们的修复方案中,选择的就是这个类型的队列,虽然会有部分任务被丢失,但是我们线上是排序日志搜集任务,所以对部分对丢失是可以容忍的。
同步移交队列
如果不希望任务在队列中等待而是希望将任务直接移交给工作线程,可使用SynchronousQueue作为等待队列。SynchronousQueue不是一个真正的队列,而是一种线程之间移交的机制。要将一个元素放入SynchronousQueue中,必须有另一个线程正在等待接收这个元素。只有在使用无界线程池或者有饱和策略时才建议使用该队列。
6、ArrayBlockingQuene 和 LinkdeBlockingQuene的区别是什么
7、ArrayList 和 LinkedList的区别是什么
8、ArrayList为什么查询比较快,查询是怎么查的
ArrayList从原理上就是数据结构中的数组,也就是内存中一片连续的空间,这意味着,当我get(index)的时候,我可以根据数组的(首地址+偏移量),直接计算出我想访问的第index个元素在内存中的位置。写过C的话,可以很容易的理解。
LinkedList可以简单理解为数据结构中的链表(说简单理解,因为其实是双向循环链表),在内存中开辟的不是一段连续的空间,而是每个元素有一个[元素|下一元素地址]这样的内存结构。当get(index)时,只能从首元素开始,依次获得下一个元素的地址。
9、List的线程安全实现有哪些
Vector
Collections.synchronizedList(List list)
直接加synchronized
10、CopyOnWriteList 的写锁是怎么加的锁
lock.lock();
11、项目中遇到挑战在哪里
12、Oracle和 Mysql的隔离级别为什么不同
13、怎么查看Mysql的sql执行情况
https://www.wenjiangs.com/article/mysql-explain.html
14、Explain sql 中参数
https://www.wenjiangs.com/article/mysql-explain.html
15、Redis中的zset和Three set有什么区别
https://blog.csdn.net/u010838785/article/details/104455029
16、Three set是怎么实现排序的
17、还知道哪些可以排序的树 我说的B+ 树
18、B+树的运用场景,我说的Mysql中的索引
19、是所有索引都用的B+ 树吗,哪些用了
20、一道算法题 写一个数字反序的方法 我写的没有考虑溢出的情况
用Long解决
Long a = 2147483648L;
Long b = 2147483648L;
BigDecimal add = new BigDecimal(a).add(new BigDecimal(b));
快手 -- 视频面试30分钟
1、谈一下项目
2、谈一下对IOC和AOP的理解
3、Memchached 和 Redis 的区别
4、Redis的持久化实现
5、Redis的淘汰策略
6、定期删除和惰性删除的区别、优缺点
7、IOC的原理是什么
8、Hashmap的底层实现和原理
9、手写一个,实现map的put方法
学堂在线 -- 视频面试20分钟
1、说下spring事务,@Transition 这个注解在哪些情况下不会生效
2、Synchronized 基本原理
3、Synchronized和ReentrantLock 都是可重入锁,他们俩是怎么实现可重入的
4、线程池的工作原理和7个参数
5、Volatile的用处
6、JVM在什么情况下会发生YoungGC和FullGC
7、Redis的淘汰机制
8、类加载机制说一下
9、快速排序的基本实现
10、Mysql优化是怎么优化的,索引失效的情况都有哪些
11、实现一个抢红包的算法,怎么实现
12、让你实现一个LRU算法,怎么实现
LinkedHashMap默认的支持按照插入顺序保存数据,新的数据插入双向链表尾部。
package com.jane;
import java.util.LinkedHashMap;
public class LruLinkedMap<K,V> extends LinkedHashMap<K,V> {
private int size;
public LruLinkedMap(int initialCapacity,
float loadFactor,
boolean accessOrder) {
super(initialCapacity, loadFactor, accessOrder);
this.size = initialCapacity;
}
/**
* @description 重写LinkedHashMap中的removeEldestEntry方法,当LRU中元素多余6个时,
* 删除最不经常使用的元素
*/
@Override
protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
if(size() > size){
return true;
}
return false;
}
}
销售易 -- 视频面试 30分钟
1、项目说了很多
2、Spring是怎么管理Bean的
spring在启动的时候,会创建应用上下文容器,而所有的bean都是在创建应用上下文容器的时候进行加载的,大致流程就是,应用上下文对象会根据我们传入的配置文件路径去加载这个配置文件,然后解析配置文件的<beans>标签下的<bean>标签,然后会对每个bean标签进行解析,这时会根据我们在bean标签中配置的属性(这里我们只定义了id和class)给每一个bean实例化一个BeanDefinition,同时会把这些BeanDefinition对象放入到应用上下文中的一个List<BeanDefinition>集合中,接着就是对List<BeanDefinition>进行循环并且通过class的值通过反射,实例化bean,最后将实例化的bean维护到一个map中,map的key就是bean的id,map的value就是bean的实例化对象,最后我们就可以通过id来获取我们想要的bean了,但是这里只是简单的介绍了bean的加载,应用上下文所做的事情远不止这些,还有对懒加载bean的维护,对bean之间依赖关系的维护(就是我们常说的依赖关系,其实也是通过一个Map<String, Set<String>>类型ConcurrentHashMap来维护的)等等。
3、你们公司用AOP都做了什么
4、AOP的实现原理是什么
5、为什么JDK动态代理要实现接口,CGLIB不用实现
6、CGLIB动态代理的实现方式
7、如果让你实现AOP,你会怎么实现
8、Redis的基本数据类型
9、Redis的hash是怎么实现的
10、Redis的事务是怎么实现的
11、Redis的淘汰机制
12、LRU是怎么实现的
13、HashMap的实现原理
14、HashMap中哪里用到了数组
15、HashMap的扩容机制
16、你能想到别的方法进行数组的扩容吗
17、为什么链表要转换成红黑树
18、链表是怎么转换成红黑树的
19、SpringBoot自动装配的原理
20、AutoConfigurationImportSelector这个类是怎么实现的
21、SpringApplication对象是怎么创建的
22、Spring循环依赖怎么解决的
搜狐一面 -- 视频面试 50分钟
1、JVM垃圾回收机制
2、怎么判断当前对象能否被回收
3、对象首次创建的话创建在哪个区(新生代还是老年代,新生代哪个区)
4、解释一下stop the world
5、Stop the world 过程中,如果有新的垃圾产生怎么办
6、我说我们项目用的是JDK1.6,面试官就问,1.8和1.6都有哪些区别
7、有了解过1.8的stream流吗
8、HashMap1.8和1.8之前的区别,以及底层实现
9、HashMap为什么不是线程安全的
10、HashMap还会造成什么问题(1.8之前头插法会导致死循环)
11、实现HashMap线程安全的有哪些(我答了三种)
12、CurrentHashMap的底层原理,以及1.8和之前的区别
13、详细讲讲CAS的工作原理
14、CAS的ABA问题怎么解决的
15、你常用的线程池有哪些
16、线程池的7个参数
17、SingleThreadExecutor和CachedThreadPool为什么不推荐使用,会出现哪些问题
18、写一个冒泡排序
19、写一个算法,快乐数(LeetCode原题),我一开始用递归写,会出现死循环的状态,面试官超好提醒我,然后花了很长时间修改算法,通过
20、Mybatis有了解它的插件吗
21、MybatisTemplate 有了解吗
22、Redis的五个参数
23、Redis的事务,我Muliti事务开始,然后写了五个key,其中有一个失败了,Redis怎么处理的,会回滚吗
24、Redis事务和Mybatis事务有什么区别
25、Redis主从复制了解吗
26、Redis主服务器是怎么给从服务器写入数据的
27、看你还了解Docker,(简单说了一下玩过一点点)
美团(美团地图)一面 -- 视频面试 50分钟
1、聊了十多分钟做的项目
2、你们公司自研的Spring和市面上流行的Spring有什么不一样
3、Redis主要用来干嘛的
4、Redis的持久化方式
5、Redis的事务有了解吗(我说了使用的基本命令和mybatis、mysql的区别)
6、你对你们经常使用的集合底层有了解吗
7、HashMap的底层原理,1.8以及之前的,线程安全实现方式
8、Sychonized和ReentrantLock 的区别
9、Volatile的作用是什么
10、对JVM垃圾回收器有了解吗
11、CMS垃圾回收器说一下工作原理
12、堆和栈的区别
13、JVM的调优
14、try{}catch{}finally{}中,如果finally{}中的返回值+1,返回的是多少,会改变返回结果吗
15、线程池有了解吗,它的工作原理
16、固定长度的线程池有什么缺点
17、Mysql和Oracle你用的最大的区别是什么(我说了两者的事务隔离级别,以及mysql中的Explain和oracle当中的Explain plan for的区别)
18、Mysql的聚簇索引和非聚簇索引有了解吗
19、看你做过Sql优化,讲讲你做了哪些优化
20、Mysql回表知道是什么吗
21、SpringMVC的工作流程是什么
22、一道简单的算法题,反转链表,我说这题我前段时间专门leetcode上练过,我算法不好,这段时间主要是复习基础了,面试官夸我基础很扎实,应该二面稳了,面试体检极佳
美团(美团地图)二面 -- 视频面试 40分钟
1、是个小姐姐程序员,聊了聊项目
2、问了下我们公司现在项目用到的技术栈
3、和一面一样问了下我们公司自研的Spring有哪些不一样
4、同样讲了讲oracle和mysql的区别
5、讲讲不可重复读是什么
不可重复读是指在事务1内,读取了一个数据,事务1还没有结束时,事务2也访问了这个数据,修改了这个数据,并提交。紧接着,事务1又读这个数据。由于事务2的修改,那么事务1两次读到的的数据可能是不一样的,因此称为是不可重复读。
6、Jdk1.8有了解过CompletableFuture吗(我没有了解过,流下来没技术的眼泪)
7、那你知道Future吗(好像是Callable的时候返回值会用到它,又流下了没技术的眼泪)
Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。
在Future接口中声明了5个方法,下面依次解释每个方法的作用:
- cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。
- isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
- isDone方法表示任务是否已经完成,若任务完成,则返回true;
- get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
- get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
也就是说Future提供了三种功能:
1)判断任务是否完成;
2)能够中断任务;
3)能够获取任务执行结果。
因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask。
8、写一个算法题吧,牛客网的 密码合格校验,写了十多分钟,全是靠if else解决的
小姐姐也说,这个写的没问题,但是需要更多的考虑更好的办法,比如借助java自带的工具类等等。
9、说一些和技术无关的,你对你自己的技术发展有什么想法(我就说,平时会多看看技术公众号,看B站学习技术,会关注很多新技术然后跟着学习,想去更大的平台通过实际场景的应用丰富自己的阅历)
美团(美团打车)一面 -- 视频面试 40分钟
1、String,StringBuild,StringBuff的区别
https://www.cnblogs.com/Jacian/p/11553320.html
2、StringBuff为什么是线程安全的
https://www.cnblogs.com/Jacian/p/11553320.html
3、ArrayList和LinkedList的区别是什么
4、以上二位是线程安全的吗,怎么实现线程安全
5、Vector实现线程安全的原理是什么
6、多线程编程中你知道哪些都是保证线程安全的
7、Volatile的底层实现是什么
8、线程池了解吗,说说工作原理
9、内存溢出说一下
10、栈溢出说一下
栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的 字节数,因而导致栈中与其相邻的变量的值被改变。
11、要实现一个OOM和栈溢出,怎么实现
12、说一下你常用的垃圾回收器
13、Stop the world 解释一下
14、CMS的工作流程是什么
15、Spring中bean的作用域
https://www.cnblogs.com/amunamuna/p/10959796.html
16、Spring中bean的生命周期说一下
https://www.cnblogs.com/javazhiyin/p/10905294.html
17、说一下你在项目中遇到的印象深刻的问题是什么,有什么收货
18、Redis的持久化怎么实现的
AOF快照和RDB
19、写一道编程题,leetcode 第一道经典题目--两数之和
20、对美团打车有什么想了解的吗(问了下美团打车和滴滴高德打车的区别)
字节跳动 视频面试 -- 30分钟
1、简单介绍了一下项目
2、HashMap介绍一下
3、为什么要用红黑树的结构
4、红黑树一般都会用在哪些场景中
5、Oracle的索引了解吗
6、Mysql的索引底层实现是什么
7、B+树的实现原理了解吗
8、Mysql事务特性了解吗,具体说一说
9、Mysql的事务隔离级别了解吗
10、Mysql的事务隔离级别是怎么实现的
11、算法题:[(5,7),(1,6),(15,50),(60,90),(35,37)] 合并二元数组 输出[(1,7),(15,50),(60,90)]
12、算法题:分层打印二叉树
13、算法题:反转链表起网络