文章目录
-
- 一、开场白
- 二、Java多线程相关
-
-
- 线程池的原理,为什么要创建线程池?创建线程池的方式;
- 线程的生命周期,什么时候会出现僵死进程;
- 说说线程安全问题,什么实现线程安全,如何实现线程安全;
- 创建线程池有哪几个核心参数?如何合理配置线程池的大小?
- volatile、ThreadLocal的使用场景和原理;
- ThreadLocal什么时候会出现OOM的情况?为什么?
- synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性;
- 三、JVM相关
-
-
- JVM内存模型,GC机制和原理;
- GC分哪两种,Minor GC 和Full GC有什么区别?什么时候会触发Full GC?分别采用什么算法?
- 常见的JVM调优方法有哪些?可以具体到调整哪个参数,调成什么值?
- 强引用、软引用、弱引用、虚引用;
- Java中的大对象如何进行存储?
- JVM虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的;
- JVM里的有几种classloader,为什么会有多种?
- 什么是双亲委派机制?介绍一些运作过程,双亲委派模型的好处;
- 什么情况下我们需要破坏双亲委派模型,什么是反双亲委派模型;
- 四、Java高级部分
-
-
- 红黑树的实现原理和应用场景;
- HashMap中插入、添加、删除元素的时间复杂度?
- HashMap 1.7和1.8的实现区别?
- List 和 Map 区别,Arraylist 与 LinkedList 区别,ArrayList 与 Vector 区别;
- NIO、BIO、AIO是什么?适用于何种场景?
- Java9比Java8改进了什么;
- HashMap内部的数据结构是什么?底层是怎么实现的?(还可能会延伸考察ConcurrentHashMap与HashMap、HashTable等,考察对技术细节的深入了解程度);
- 说说反射的用途及实现,反射是不是很慢,我们在项目中是否要避免使用反射;
- 说说自定义注解的场景及实现;
- 序列化和反序列化的底层实现原理;
- hashCode和equals方法的区别和联系;
- 五、Spring相关
-
-
- Spring AOP的实现原理和场景?
- Spring bean的作用域和生命周期;
- Spring IOC是什么?优点是什么?
- SpringMVC、动态代理、反射、AOP原理、事务隔离级别;
- Spring Boot比Spring做了哪些改进?Spring 5比Spring4做了哪些改进;
- 如何自定义一个Spring Boot Starter?
- 六、中间件篇
-
-
- 了解几种消息中间件产品?各产品的优缺点介绍;
- RPC的基本原理是什么?一次完整的RPC调用是什么样子的?
- Dubbo完整的一次调用链路介绍;
- Dubbo支持几种负载均衡策略?
- Dubbo Provider服务提供者要控制执行并发请求上限,具体怎么做?
- Dubbo启动的时候支持几种配置方式?
- 消息中间件如何保证消息的一致性和如何进行消息的重试机制?
- Spring Cloud熔断机制介绍;
- Spring Cloud对比下Dubbo,什么场景下该使用Spring Cloud?
- 七、数据库篇
-
-
- 锁机制介绍:行锁、表锁、排他锁、共享锁;
- 乐观锁的业务场景及实现方式;
- 数据库事务隔离级别,MySQL默认的隔离级别、Spring如何实现事务、JDBC如何实现事务、嵌套事务实现、分布式事务实现;
- SQL的整个解析、执行过程原理、SQL行转列;
- 事务介绍,分布式事物的理解,常见的解决方案有哪些,什么事两阶段提交、三阶段提交;
- MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?
- MySQL锁,悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;
- 分布式事务的原理2阶段提交,同步\异步\阻塞\非阻塞;
- 八、Redis
-
-
- Redis为什么这么快?redis采用多线程会有哪些问题?
- Redis单进程单线程的Redis如何能够高并发?
- Redis支持哪几种数据结构;
- Redis 为什么是单线程的?
- Redis跳跃表的问题;
- Redis常见的回收策略?
- Redis如何使用Redis实现分布式锁?
- 缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级?
- Redis分布式锁操作的原子性,Redis内部是如何实现的?
- 九、Nginx
-
-
- 请解释什么是C10K问题或者知道什么是C10K问题吗?
- 正向代理和反向代理;
- Nginx几种常见的负载均衡策略;
- Nginx服务器上的Master和Worker进程分别是什么;
- 十、分布式理论
-
- 十一、计算机网络
-
-
- 三次握手和四次挥手、为什么挥手需要四次;
- 什么是TCP 粘包/拆包;
- TCP粘包/拆包的解决办法;
- 从游览器中输入URL到页面加载的发生了什么?;
- 十二、其他
一、开场白
简单的介绍一下自己的工作经历与职责,在校或者工作中主要的工作内容,主要负责的内容;(你的信息一清二白的写在简历上,这个主要为了缓解面试者的压力)
介绍下自己最满意的,有技术亮点的项目或平台,重点介绍下自己负责那部分的技术细节;(主要考察应聘者对自己做过的事情是否有清晰的描述,判断做的事情的复杂度)
二、Java多线程相关
线程池的原理,为什么要创建线程池?创建线程池的方式;
1.jdk为我们提供了4种类型线程池,通过静态工厂创建,当有请求到来时,若没有达到核心线程的数量则创建核心线程,若达到了就创建非核心线程(超时回收),若达到线程池最大线程数量,则走拒绝策略。
2.使用线程池可以避免频繁创建、销毁线程的开销,并且我们还可以监控线程的运行状态。
3.两种方式创建线程池:new ThreadExecutor(……)或者利用Executors的工厂方法创建。
线程的生命周期,什么时候会出现僵死进程;
僵尸线程:一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,而父进程还没有结束,那么他将变成一个僵尸进程。
危害:进程号被占用,会导致操作系统没有可用的进程号而无法创建进程。
说说线程安全问题,什么实现线程安全,如何实现线程安全;
在多线程环境下,运行的结果与我们所期望的结果一致或与单线程运行的结果相同,则认为是线程安全的。
可以通过加锁的方式保证线程安全。或者使用(ThreadLocal类为每个线程操作自己的变量)
创建线程池有哪几个核心参数?如何合理配置线程池的大小?
- int corePoolSize:核心线程数
- int maximumPoolSize:最大线程数
- long keepAliveTime:线程存活时间
- TimeUnit unit:时间参数
- BlockingQueue workQueue:阻塞队列
- ThreadFactory threadFactory:线程工厂
- RejectedExecutionHandler:拒绝策略(4种)
cpu密集型:n+1 IO密集型:2n+1
volatile、ThreadLocal的使用场景和原理;
volatile可以保证可见性,禁止指令重排序,如果要求变量修改后立即对其他线程可见,可以使用volatile(双重锁单例);ThreadLocal为每一个线程提供一份单独的变量副本,底层通过ThreadLocalMap实现,key为ThreadLocal类型(弱引用),value为变量值。
ThreadLocal什么时候会出现OOM的情况?为什么?
因为value会被强引用所引用(来源当前线程)导致无法GC,从而发生内存泄露,进而导致OOM。
预防:每次使用完毕后调用remove()方法自动清除key为null的value。
synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性;
synchronized可以保证原子性,可见性,顺序性,并且可以作用在方法上,代码块。
synchronized做代码块锁的时候,如果是使用自定义的锁,或者this对象作为锁,那么锁定的是对象,如果对于静态的对象做锁定,那么锁定的就是类了。
volatile只能保证可见性不能保证原子性,并且只能作用于变量,可以禁止指令重排序。
模拟死锁
package DeadLock;
public class TestDeadLock implements Runnable {
public int i;
public static Object o1=new Object();
public static Object o2=new Object();
@Override
public void run() {
if(i==1) {
synchronized(o1) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(o2) {
System.out.println("1");
}
}
}else if(i==2){
synchronized(o2) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(o1) {
System.out.println("2");
}
}
}
}
public static void main(String[] args) {
TestDeadLock t1=new TestDeadLock();
TestDeadLock t2=new TestDeadLock();
t1.i=1;
t2.i=2;
new Thread(t1).start();
new Thread(t2).start();
}
}
三、JVM相关
JVM内存模型,GC机制和原理;
GC分哪两种,Minor GC 和Full GC有什么区别?什么时候会触发Full GC?分别采用什么算法?
常见的JVM调优方法有哪些?可以具体到调整哪个参数,调成什么值?
强引用、软引用、弱引用、虚引用;
Java中的大对象如何进行存储?
JVM虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的;
JVM里的有几种classloader,为什么会有多种?
什么是双亲委派机制?介绍一些运作过程,双亲委派模型的好处;
什么情况下我们需要破坏双亲委派模型,什么是反双亲委派模型;
四、Java高级部分
红黑树的实现原理和应用场景;
HashMap中插入、添加、删除元素的时间复杂度?
HashMap 1.7和1.8的实现区别?
List 和 Map 区别,Arraylist 与 LinkedList 区别,ArrayList 与 Vector 区别;
NIO、BIO、AIO是什么?适用于何种场景?
Java9比Java8改进了什么;
HashMap内部的数据结构是什么?底层是怎么实现的?(还可能会延伸考察ConcurrentHashMap与HashMap、HashTable等,考察对技术细节的深入了解程度);
说说反射的用途及实现,反射是不是很慢,我们在项目中是否要避免使用反射;
说说自定义注解的场景及实现;
序列化和反序列化的底层实现原理;
hashCode和equals方法的区别和联系;
五、Spring相关
Spring AOP的实现原理和场景?
Spring bean的作用域和生命周期;
Spring IOC是什么?优点是什么?
SpringMVC、动态代理、反射、AOP原理、事务隔离级别;
Spring Boot比Spring做了哪些改进?Spring 5比Spring4做了哪些改进;
如何自定义一个Spring Boot Starter?
六、中间件篇
了解几种消息中间件产品?各产品的优缺点介绍;
ActiveMQ:单机吞吐量低,但可用性较好,可实现主从架构,功能完备。
RabbitMQ:单机吞吐量低,基于erlang开发,基于
erlang 开发,并发能力很强,性能极好,延时很低。 RocketMQ:在同等机器下,可以支撑大量的topic,分布式架构,支持分布式事务。
Kafak:可用性高,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用,在同等机器下,Kafka 应该尽量保证 topic数量不要过多
RPC的基本原理是什么?一次完整的RPC调用是什么样子的?
RPC是远程过程调用,可以让我们像调用本地方法 一样调用远程方法。
服务消费者(client客户端)通过调用本地服务的方式调用需要消费的服务;
客户端存根(client stub)接收到调用请求后负责将方法、入参等信息序列化(组装)成能够进行网络传输的消息体;
客户端存根(client stub)找到远程的服务地址,并且将消息通过网络发送给服务端;
服务端存根(server stub)收到消息后进行解码(反序列化操作);
服务端存根(server stub)根据解码结果调用本地的服务进行相关处理;
本地服务执行具体业务逻辑并将处理结果返回给服务端存根(server stub);
服务端存根(server stub)将返回结果重新打包成消息(序列化)并通过网络发送至消费方;
客户端存根(client stub)接收到消息,并进行解码(反序列化);
服务消费方得到最终结果;
参考链接
Dubbo完整的一次调用链路介绍;
1.服务提供者在启动时,向注册中心注册自己提供的服务;
2.服务消费者在启动时,向注册中心订阅自己所需的服务;
3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者;
4.服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用;
5.服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心;
Dubbo支持几种负载均衡策略?
Random LoadBalance 随机,按权重设置随机概率,在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance 轮询,按公约后的权重设置轮询比率,存在慢的提供者累积请求的问题;
LeastActive LoadBalance 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
ConsistentHash LoadBalance 一致性 Hash,相同参数的请求总是发到同一提供者。
Dubbo Provider服务提供者要控制执行并发请求上限,具体怎么做?
并发控制就是限制占用的线程池线程数。
(1)服务端并发执行(或占用线程池线程数)不能超过10个。
(2)限制到方法
(3)占用连接的请求的数不能超过10个
参考链接
Dubbo启动的时候支持几种配置方式?
- xml配置方式
- properties配置方式
- API配置方式
- annotation配置方式
消息中间件如何保证消息的一致性和如何进行消息的重试机制?
- 拿到消息后先根据主键查询一次,若存在,不插入,update一下;
- 如果是写redis,直接set;
- 比如你不是上面两个场景,那做的稍微复杂一点,你需要让生产者发送每条数据的时候,里面加一个全局唯一的 id,类似订单 id 之类的东西,然后你这里消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?如果没有消费过,你就处理,然后这个 id 写 Redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可;
- 数据库加上唯一索引;
重试机制:超时重试,一定时间内没有收到ack请求,进行重试操作。
Spring Cloud熔断机制介绍;
Hystrix 可以让我们在分布式系统中对服务间的调用进行控制,加入一些调用延迟或者依赖故障的容错机制。
Hystrix 通过将依赖服务进行资源隔离,进而阻止某个依赖服务出现故障时在整个系统所有的依赖服务调用中进行蔓延;同时Hystrix 还提供故障时的 fallback 降级机制。
主要特点
- 对依赖服务调用时出现的调用延迟和调用失败进行控制和容错保护。
- 在复杂的分布式系统中,阻止某一个依赖服务的故障在整个系统中蔓延。比如某一个服务故障了,导致其它服务也跟着故障。
- 提供 fail-fast(快速失败)和快速恢复的支持。
- 提供 fallback 优雅降级的支持。
- 支持近实时的监控、报警以及运维操作
Spring Cloud对比下Dubbo,什么场景下该使用Spring Cloud?
Dubbo具有调度、发现、监控、治理等功能,支持相当丰富的服务治理能力。Dubbo架构下,注册中心对等集群,并会缓存服务列表已被数据库失效时继续提供发现功能,本身的服务发现结构有很强的可用性与健壮性,足够支持高访问量的网站。类似于电商等同步调用场景多并且能支撑搭建Dubbo 这套比较复杂环境的成本的产品而言,Dubbo 确实是一个可以考虑的选择。但如果产品业务中由于后台业务逻辑复杂、时间长而导致异步逻辑比较多的话,可能Dubbo 并不合适。同时,对于人手不足的初创产品而言,这么重的架构维护起来也不是很方便。
Spring Cloud由众多子项目组成,可以一站式进行微服务的开发,提供了搭建分布式系统及微服务常用的工具,如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性token、全局锁、选主、分布式会话和集群状态等,满足了构建微服务所需的所有解决方案。
七、数据库篇
锁机制介绍:行锁、表锁、排他锁、共享锁;
乐观锁的业务场景及实现方式;
数据库事务隔离级别,MySQL默认的隔离级别、Spring如何实现事务、JDBC如何实现事务、嵌套事务实现、分布式事务实现;
SQL的整个解析、执行过程原理、SQL行转列;
事务介绍,分布式事物的理解,常见的解决方案有哪些,什么事两阶段提交、三阶段提交;
MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?
MySQL锁,悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;
分布式事务的原理2阶段提交,同步\异步\阻塞\非阻塞;
八、Redis
Redis为什么这么快?redis采用多线程会有哪些问题?
Redis单进程单线程的Redis如何能够高并发?
Redis支持哪几种数据结构;
Redis 为什么是单线程的?
Redis跳跃表的问题;
Redis常见的回收策略?
Redis如何使用Redis实现分布式锁?
缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级?
Redis分布式锁操作的原子性,Redis内部是如何实现的?
九、Nginx
请解释什么是C10K问题或者知道什么是C10K问题吗?
正向代理和反向代理;
Nginx几种常见的负载均衡策略;
Nginx服务器上的Master和Worker进程分别是什么;
十、分布式理论
CAP理论、Base理论、最终一致性;
十一、计算机网络
三次握手和四次挥手、为什么挥手需要四次;
什么是TCP 粘包/拆包;
TCP粘包/拆包的解决办法;
从游览器中输入URL到页面加载的发生了什么?;
十二、其他
项目中遇到了哪些比较有挑战性的问题,是如何解决的;(这个很有争议,一方面是你连一个复杂的问题都解决不了,要你过来干什么,还有就是,我的能力牛逼啊,但是公司没有业务场景让我展示啊!这个就看你遇到的面试官了,祝你好运!)
看过哪些源代码?然后会根据你说的源码问一些细节的问题?(这里主要考察面试者是否对技术有钻研的精神,还是只停留在表面,还是背了几道面经,这个对于很多有强迫症的面试官,如果你连源码都没看过,基本上是会pass掉的,比如我也是这样的!)