1.Euraka自我保护机制:
某时刻某个微服务不可用了,Euraka不会立刻清理,依旧会对该服务信息进行保存
2.谈谈对微服务的理解:
微服务强调的是一个个的个体,每个个体完成一个具体的任务和功能;
将单一应用程序划分成一组小的服务,每个服务运行在其独立的自己的进程中
3.说一下dubbo和springCloud的区别
通信机制不一样,dubbo用RPC、springCloud用restful
4.谈谈微服务的优点
每个服务足够内聚、足够小;
开发简单、开发效率高;
小团队单独开发;
送耦合,独立部署;
不同语言开发;
5.SpringCloud是什么?
分布式微服务架构下的一站式解决方案,是各个微服务架构落地技术的集合体
6.Euraka和Zookeeper的区别
C:强一致性 A:可用性 P:分区容错性
Zookeeper属于CP
Euraka属于AP(各个节点平等,没有主从)
7.Ribbon 客户端的负载均衡
8.进程与进程之间如何通信?
a:管道
b:消息队列
c:共享内存
d:信号量
e:socket
9.Spring的IOC
实现原理:工程模式加反射机制
10.Spring的AOP
实现原理:代理设计模式
核心:在方法前或方法后处理事情
作用:复用和解耦
应用场景:日志、事务、权限、性能监控、异常处理
11.Spring的AOP中的关注点、切面、切入点怎么理解
关注点:重复代码
切面:关注点形成的类,可以叫切面类;将重复的代码抽取出来,在运行的时候动态植入
切入点:哪些方法可以被拦截
12.静态代理和动态代理区别
静态代理需要生成目标代理对象
动态代理不需要
13.jdk代理和CGLIB代理
jdk动态代理只需要子类实现,基于反射实现(反射虚拟生成代理类)
CGLIB是基于ASM字节码包装的一个类库(基于ASM字节码虚拟生成代理类)
14.阿里规约为什么不建议new线程?
因为new线程创建了一个size为Integer.MAX_VALUE的线程阻塞队列,可能会堆积大量请求,消耗很大内存
15.HashMap扩容怎么实现
如果大于等于阈值(当前数组长度乘以加载因子)时就扩容,使用一个新的数组代替已有的容量小的数组
16.requestBody和requestParam区别
requestParam在requestHead里面取值,requestBody在requestBody里面取值
17.Mysql索引类型
1.普通索引 create index index_name on mytable (name)
2.唯一索引 create unique index index_name on mytable (name)
3.主键索引
4.组合索引
5.全文索引 create Full Text index index_name on mytable (name)
18.索引的缺点
索引本身也是表,因此会占用存储空间,在修改数据时(增,删,改)同时还需要修改索引表
19.什么时候使用索引
1.主键自动建立唯一索引
2.经常作为查询条件在where或者order by 语句中出现的列要建立索引
3.作为排序的列要建立索引
4.外键关联建立索引
5.高并发下倾向组合索引
6.用于聚合函数的列可以建立索引;例如:max()、count()
20.什么时候不要使用索引
1.经常增删改的列
2.有大量重复数据的列
3.表中数据少
21.电脑的32位和64位是什么意思?
指CPU一次处理数据的能力是32(2的32次方)位还是64位,
32位系统的处理器最大只支持到4G内存,而64位系统支持的内存高达亿位数
22. su -root 环境变量一起切换
23 谈谈JVM
JVM由两个子系统(classLoader类装载器和execution engine 执行引擎)
和两个组件(Runtime data运行时数据区和Native interface 本地接口) 组成
24.类加载过程
类加载器把java代码转换为字节码,运行时数据区再把字节码加载到内存中
而字节码并不能直接交给底层操作系统去执行
因此需要特定的命令解析器执行引擎将字节码翻译成底层系统指令,
再交由CPU去执行,而这个过程需要调用其他语言的本地库接口
25.注解 例如:@Override
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override{}
Target:定义的注解可以用在什么地方
Retention:注解声明周期,定义注解存活阶段 (source:源码级别、class:字节码级别、runtime:运行时级别)
26.微服务有哪些模块
服务注册与发现、服务消费、负载均衡、断路器 、智能路由、配置管理
27.springCloud的服务调用
1.ribbon + testTemplate(可以进行负载均衡)
2.feign
a.采用的是基于接口的注解
b.整合了Ribbon,具有负载均衡能力
c.整合了Hystrix,具有熔断能力
28.谈谈zuul
路由转发和过滤器
filterType:返回一个字符串代表过滤类型(pre:路由前、post:路由后、routing:路由之时、error:发送错误调用)
filterOrder:过滤的顺序
shouldFilter:可以写逻辑判断。是否要过滤,true ->永远过滤
run:过滤器的具体逻辑
29.springCloud Bus消息总线
将分布式的节点用轻量的消息代理连接起来,用于广播文件的更改或者服务间的通讯,也可以用于监控
30.redis有哪些数据类型
string、list(列表)、set(集合)、zset(有序集合)、hash(散列)
31.怎么在项目中配置Redis
1.添加Redis依赖包 2.配置Redis数据库连接
32.线程池有哪些参数?都是什么意思?
new ThreadPoolExecutor(
corePoolSize: //核心线程数
maximumPoolSize: //线程上限
keepAliveTime: //超过corePoolSize的线程idle时间
timeUnit: //超过这个时间多余的线程就会被收回
hanlder: //拒绝策略
BlockingQueue
)
流程:小于核心线程数:每来一个任务就会创建一个线程去执行
超过核心线程数:则加入到任务队列中
若加入队列成功,则等待空闲线程将它取出去执行
若失败,则创建新的线程
线程数大于maximumPoolSize时则采取任务拒绝策略进行处理
33.合理的配置线程池的线程数
CPU密集型任务:尽可能减少线程,CPU+1 个
IO密集型任务:2xCPU 个
java获得CPU个数的方法:Runtime.getRuntime().availableProcessors()
34.synchronized和Lock区别
1.synchronized是java关键字,而Lock是一个接口
2.synchronized同步时,一条线程用完会自动释放锁;Lock需要手动释放,如果不收到释放,可能会死锁
3.Lock可以使用响应中断或用规定等待时间的锁(有方法)
4.Lock可以得知是否获得锁
应用场景:对于资源竞争不激烈时,但当大量线程同时竞争时用Lock
35.锁的种类
1.类锁:当synchronized指定修饰静态方法或者class对象时,拿到的就是类锁,类锁是所有对象争抢一把
2.对象锁:每个对象都有一把,如果同一个类有两个对象,不安全
36.在JVM中,对象在内存中的布局?
可分为对象头、实列数据、对齐填充
每一个对象都有一个moniter监视器,调用moniter就是尝试获取这个对象,成功获取就将值+1,离开值减1
37.谈谈TreadLocal
ThreadLocal是一个线程级别的局部变量,为每个使用该变量的线程提供了一个独立的变量副本,
每个线程修改副本时不影响其他线程对象的副本
38.ConCurrentHashMap是安全的,怎样实现的?
ConCurrentHashMap将数据分为多个segment,默认16个
每次操作对一个segment加锁
其实没有使用锁:用到了volatile,变化可以立刻得知
39.java代码平时是怎样优化的?
1.尽量指定类,方法final修饰符(编译器会内联所有final方法,性能提升50%)
2.尽量重用对象
3.尽量使用局部变量
局部变量保存在栈中,栈中创建的对象随着方法运行结束就没有了,不需要回收
静态变量,成员变量保存在堆中,较慢
4.及时关闭流
5.尽量减少对变量的重复调用
例如:list.size() 应当 int length = list.size() 用length
6.String常量之类的,用枚举或者常量代替
7.for循环中如果要new对象,把引用放到for循环之外,整个for循环就只创建了一个对象
40.SQL的执行顺序
from + join
where
group by
having
select
order by
limit
41.sql中的in和exist区别
in适合主表大,子表小
exist适合主表小,子表大
42.start()方法用来启动一个线程,此时线程处于就绪状态,并没有运行;调用run()来完成运行操作
43.线程池有哪些
newSingleThreadExecutor
newFixedThreadPool(定长线程池,有最大并发数,超出线程会在队列中等待)
newCachedThreadPool
newScheduledThreadPool(处理定时任务)
44.IOC常见容器:ApplicationContext、BeanFactory
IOC是基于反射机制和工厂模式实现的
45.多态:不用修改源程序代码就可以让引用变量绑定到各种不同的实现类上,让程序可以选择多个运行状态。
多态:让引用变量绑定到各种不同的类实现上
46.toStirng 快于 String.valueOf() 快于 +“”
47.构造方法不能被继承
48类中声明的变量(成员变量)有默认初始值;
方法中的(局部变量)没有,必须定义初始值
49.native关键字
方法对应的实现不是在当前文件,而是在用其他语言实现的文件中
50.String s = "abc"
先去字符数据池中搜索,有,直接用;没有再生成一个;
new创建字符串时先看字符数据池中有没有,有则拷贝一份到堆中,然后返回堆中地址;没有则在堆中创建一份
51.两个Integer类型进行==比较,如果在-128-127,则返回true;否则返回false
52.两个基本类型的封装进行equals()比较,首先用equals()比较类型,类型相同,则继续比较值,值也相同则返回true
53.transient关键字
用transient关键字标记的成员变量不参与序列化过程
54.ArrayList底层是数组
可变长度的数组,数组扩容时,会将老的数组中的元素重新拷贝到一个新的数组中
用到了Fail-Fast机制
55HashMap
HashMap是基于哈希表的Map接口非同步实现
底层使用数组实现,数组中每一项是一个单向链表,即数组和链表的结合体;当链表长度大于一定阈值时,链表转换为红黑树
将key-value作为一个node对象 放在一个Node[] 数组中
当存储一个Node时,key的hash算法决定在Node[]中的存储位置,再根据equals()方法决定在Node[]位置上链表中的位置。
超过阈值扩大一倍
56.类的初始化顺序
父类 --> 类构造器方法 --> static变量赋值语句 --> static{}代码块
57.类的定义信息、常量、静态变量在方法区;
成员变量、集合在堆;
引用和私有变量在栈 -->线程私有;
程序计数器:执行到哪一行;
native stack:本地方法(和操作系统相关)-->本地栈
58.Http默认情况下建立TCP连接不会断开,只有在请求报头中声明connection:close才会在请求完后关闭连接;
一个TCP连接可以发送多个HTTP请求
59.SpringFactoriesLoader从classPath中搜寻所有META/spring.factories文件,并将其中的key -> 全类名的
EnableAutoConfiguration 对应的value通过反射方式实例化为对应的标注了@Configuration的IOC容器配置类
60.@SpringBootApplication注解由哪些注解组合而成?
@SpringBootConfiguration 标准的standalone类型的java程序的main函数启动类,也没有特殊的东西
@EnableAutoConfiguration 能实现自动配置的原理
@ComponentScan 非必须
61.FastDateFormat线程安全的
62.java11有哪些新特性?
1.自动类型推断,var s = "java" 等于 String s ="java"
2.字符串加强 isBlank(),strip()(去首尾空格) ,repeat()复制,lines().count()行数统计
3.不可变集合 List.of("a","b"); List.copy(list);
63.java强制我们wait()/notify()调用必须在同一个同步代码块中,以避免lost wake up 异常
lost wake up 异常:消费者在检查count到调用wait()之间,count被改掉了,准备唤醒一个线程,而这个时候消费者还没睡呢,
所以这个通知丢掉,消费者就睡过去了
64. kotlin
完全兼容java、null safe、支持lamda表达式、支持扩展、体验一致的开发工具
65.Docker(go语言开发)
虚拟化技术(简化配置、快速部署)
是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植容器中
然后发布到任何流行的Linux机器上
为什么用? 更快的交付和部署、更轻松的迁移和扩展、更简单的更新管理
或
1.解决了运行环境和配置问题,方便发布
2.更轻量级的虚拟化,节省了虚拟机的性能损耗
66.static成员方法
static方法是类的方法,不需要创建对象就可以调用,并且不能使用this和super关键字
不能调用非static方法,只能访问所属类的静态成员变量和方法
因为当static方法被调用时,改类的对象可能还没有被创建,即使创建了,也无法确定是哪个对象的方法
67.如果有x.equals(y),那么一定会有x.hashCode()==y.hashCode()
如果x.hashCode() != y.hashCode(),那么一定会有x.equals(y) == false
其他情况则不一定
68.存储过程和函数有什么区别?
1.函数有返回值
2.函数在创建中没有declare关键字,而是用is或者as关键字代替
69. 堆 = 年轻代 + 老年代 +持久代(类定义在持久代)
年轻代:老年代 = 1:4
回收15次后进入老年代
复制算法
70.RPC:远程过程调用协议
通过网络从远处计算机程序上请求服务,而不需要了解底层网络技术的协议
71. Nginx: (HTTP server) 常做静态内容服务器和代理服务器
Tomcat/JBoss/jetty :(Application Server) 应用容器
72.怎样对sql进行优化?
1.首先考虑在where及order by涉及的列上建立索引
2.应尽量避免在where中对字段进行null判断,使用!=或大于小于,否则导致索引失效
3.尽量避免用or来连接条件,可以用union all
4.in和not in 会导致全表扫描,能用between 不用in
5.索引不适合超过6个
6.任何地方都不要使用select *
7.like 'name%' 索引有效
8.避免在where后进行函数操作
73.Netty 是把NIO封装后的一个框架
本质:JBoss做的一个jar包
目的:快速开发高性能、高可靠的网络服务器和客户端服务器
优点:提供异步的、事件驱动的网络应用程序框架和工具
一句话就是一个好使处理socket的东西
NIO:NoneBlocking IO 非阻塞IO(同步非阻塞)
NIO用的事件机制,用一个线程把Accept,Read,Write 请求处理的逻辑全干了,如果什么事都没有做,它也
不会死循环,它会将线程休眠起来,直到下个事件来了再继续干活
BIO:Blocking IO 阻塞IO (同步阻塞)例如:Read是阻塞的,只有请求来了,Read才能返回,子线程才能继续
74.分布式事务的解决方案?
1.基于可靠消息服务的分布式事务
2.TCC(补偿事务)
3.最大努力通知
分布式系统:部署在不同节点上的系统通过网络交互来完成协同工作
事务:由一组操作组成的一个工作单元,这个单元具有原子性、一致性、隔离性、持久性
幂等性:指同一个操作无论请求多少次,其结果都相同
实现幂等性方法有:1操作之前在业务方法进行判断,如果执行过了就不再执行
2缓存所有请求和处理结果,已处理的直接返回结果
3在数据库中加一个状态字段(未处理、已处理)
用RocketMQ实现可靠消息事务:
1.发送Prepared消息
2.update DB
3.根据上一步成功或失败,confirm或者取消Prepared消息
RocketMQ会定期(默认一分钟)扫描所有Prepared消息,询问到底是发送这条消息还是取消
74.消息队列并不仅为了解决通讯问题,更重要的,它主要用来实现异步处理、服务解耦、流量控制
75.JDK的克隆是浅度克隆,它只将对象中的基础数据类型克隆到新的对象中,引用类型只克隆一个引用,克隆后的引用还是指向原对象
深克隆对象可以用:mapstruct、反射、序列化和反序列化
76. 对象由什么组成?
一个对象包含对象头、实列数据、对齐填充
对象头:GCage、hashCode、synchronized
77.Synchronized
1.synchronized加锁对象为A,叫对象锁,进入同步代码块之前要获取锁
synchronized (a) {}
2.在静态方法上加锁。加锁类型是这个方法对应的类锁
public static synchronized void test(){}
3.实例锁:实列方法上加锁。加锁类型是这个方法对应的对象
public synchronized void test() {}
78. 谈谈mybatis的二级缓存?
Mybatis默认支持一级缓存
一级缓存是sqlSession级别
二级缓存是跨sqlSession的,是mapper级别(同一个命名空间namespace)的缓存,不同的sqlSession是可以共享的
缓存的数据结构:map
key:hashcode + sql +sql参数 +结果
value:用户信息
怎样开启二级缓存:
1.配置文件
2.对应的映射文件mapper里加
3.需要将查询结果映射的pojo实现序列化接口,不实现则抛出异常(二级缓存可以将内存数据写到磁盘,存在序列化和反序列化,所有需要实现serializable接口)
什么时候不适合用二级缓存?
对于变化频率较高的sql,需要禁用二级缓存
查询频率高,变化频率低使用二级缓存
可以设置刷新间隔时间。每隔一段时间自动清空缓存,flushInterval来设置
79.redis不能用作海量数据的高性能读写,主要用在较小数据的高性能操作和运算上
80.为什么用缓存? 高性能、高并发
81.redis为什么快?
1.完全的基于内存(复杂度O(1))
2.数据结构简单
3.采用单线程。避免了不必要的上下文切换和竞争条件,也不存在多线程的切换而消耗cpu
4.非阻塞IO
5.redis直接自己构建了vm机制
82.redis的过期策略?
1.定时过期
2.定期过期:每隔一段时间,清除已过期的key
3.惰性过期:只有当访问一个key时,才会判断是否过期
83.redis 的内存淘汰机制
1. noeviction :默认 -> 内存不足直接报错
2.allkey-lru:移除最近最少使用的key
3.allkey-random :随机移除
4.volatile-lru:在设置了过期时间的key中,移除最近最少使用的key
5.volatile-random:在设置了过期时间的key中,随机移除
6.volatile-ttl:在设置了过期时间的key中,优先删除更早过期的key
84.用redis实现分布式锁
1.redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对redis的连接并不存在竞争关系
2.setnx()命令可以方便的实现分布式锁
解决死锁:为锁加过期时间,在释放锁之前判断已释放则不要再释放
85.redis持久化方式
1.AOF:文件存储方式,执行过写的指令记录下来,当重启时会执行 (appendonly:yes)
2.RDB:快照存储方式,在指定的时间间隔对数据进行快照存储 (save 900 1 900秒有一个key被修改则发起快照)
86.MQ
作用:解耦、异步、削峰
RabbitMQ:erlang语言,中小公司使用
RocketMQ:java语言,阿里,大型公司使用
Kafka:大数据领域的实时计算和日志采集
87.MQ有哪些常见问题?如何解决这些问题?
1.消息顺序问题
保证生产者 - > MQserver - > 消费者 是一对一关系
2.消息重复问题
利用一张日志表来记录已经处理成功的消息ID
88.RabbitMQ的使用场景?
1服务间异步通讯 2 顺序消费 3 定时任务 4请求削峰
模式:simple模式、work工作模式、 publish/subscribe发布订阅 、routing路由模式、topic主题模式
89.如何保障RabbitMQ消息的顺序性
拆分多个queue,每个queue一个consumer;
或者一个queue,但对应一个consumer,然后这个cunsumer内部用内存队列做排队,然后分发给底层不同的worker来处理
90.消息基于什么传输?
RabbitMQ使用信道的方式来传输数据
91.分布式事务的BASE理论
BA:basic Available基本可用
S:softstate 柔性状态:可以不需要实时一致
E:Eventual consisstency:最终一致性
同一数据的不同副本可以不需要实时一致,但一定要保证经过一定时间后仍是一致的