UNTITLED

2020-03-01  本文已影响0人  CNSTT

SPRING CLOUD

狠人 Spring Cloud 20000 字总结!

1、Eureka注册中心

SPRING CLOUD中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册和发现
默认30秒发送心跳,90秒接受不到心跳就剔除节点。

说说ZooKeeper与Eureka的区别

ZooKeeper满足CP强一致性,选举制度,一个leader其余的是followers,如果重新选举会导致整个集群都不可用,生产环境无法容忍。
Eureka满足AP高可用性,每个节点独立平等,挂了不影响其他节点自动切换。另外拥有自我保护机制,如果15分钟内85%以上节点没收到心跳注册,认为出现注册中心和节点网络故障,将不再剔除剩下的服务。

2、Ribbon负载均衡

Ribbon 是 Netflix 公司的一个开源的负载均衡 项目,是一个客户端的负载均衡器,运行在消费者端
目的是为了高可用,客户端从eureka注册中心获取服务注册信息列表,缓存到本地,实现轮询负载均衡策略。
@LoadBalanced注解修饰过的RestTemplate
Ribbon 默认采用的策略:RoundRobinRule 轮询策略。
其他还有IPHash,权重

Redis

  1. 是一个完全开源免费的key-value内存数据库
  2. 数据结构 String、map、 list(无序)、set(无序)、 sorted set(有序)
缓存雪崩

缓存雪崩:缓存大量KEY同一时间大面积失效,导致请求落到数据库上。
缓存失效时间分散开,避免同一时间重复失效。
使用互斥锁,第一次SETNX,如果为TRUE加锁,其他线程自旋等待,请求完了释放锁,其余的请求读取缓存。

缓存穿透

缓存穿透:缓存和数据库中都没有的数据,导致请求大量落在数据库(一般是恶意攻击)
在接口层做校验,例如不可能的值直接拦截报错
最常用的是布隆过滤器,将所有可能存在的数据哈希散列到一个足够大的bitmap中,一个一定不存在的数据会被bitmap拦截掉。
在缓存中设置一个KEY-NULL,过期时间设置为较短的时间,防止针对某个KEY恶意攻击。

缓存击穿

缓存击穿:缓存中没有但数据库有的数据,并发过高读取同一个KEY,导致数据库压力瞬间增大。
一般是热点数据,设为永不过期
使用互斥锁

Redis的2种持久化RDB和AOF

RDB:redis database,快照,先写入临时文件然后持久化写入磁盘。速度快,但是不安全。
AOF:append only file,只追加不修改的日志。速度慢,但是相对安全。因为只追加所以文件越来越大,所以有了rewrite重写机制。适合启动redis时候使用。

SPRING

Spring Bean的生命周期

读取配置文件,得到BeanDefination定义信息
createBeanInstance 执行Bean构造器,实例化一个Bean对象,全是默认值
populateBean 填充属性
aware 执行aware方法。设置BeanFactory
postProcessBeforeInitialization
init-method 初始化方法
postProcessAfterInitialization
得到完整的Bean,销毁使用destroy方法

Spring 的7种事务传播行为

两个Service中两个方法

methodA () {
  methodB();
}

1、REQUIRED 如果A当前没有事务,B就新建一个事务,如果B已经存在一个事务A中,加入到这个事务A中,合为一个事务。这是最常见的选择,也是Spring的默认的事务传播行为。
2、REQUIRES_NEW 事务B创建新事务,无论当前A存不存在事务,都创建新事务B,并且以独立的事务运行,互不干扰。
3、SUPPORTED 假设B当前在事务A,以事务的形式执行。假设B当前不在一个事务A中,那么B就以非事务的形式执行(跟随父节点)。
4、NOT_SUPPORTED B总是非事务,如果当前A存在事务,就把当前事务挂起。
5、MANDATORY B必须在A父事务中执行。也就是说,如果A不是事务,就抛出异常。

No existing transaction found for transaction marked with propagation 'mandatory'

6、NEVER B以非事务方式执行,如果当前A存在事务,则抛出异常。

Existing transaction found for transaction marked with propagation 'never'

7、NESTED 嵌套
如果当前A存在事务,则在嵌套事务内执行。如果当前A没有事务,则执行与REQUIRED类似的操作。
(这个和REQUIRED区别在于一个是加入到一个事务,一个是在嵌套事务运行)

JAVA基础

1、List

image.png
1.1、ArrayList*

底层是有序动态数组,线程不安全,方法之间是线程不同步的
数组在内存中分配连续的内存空间
synchronizedListCopyOnWriteArrayList来解决线程安全问题

protected static List<Object> arrayListSafe2
 = Collections.synchronizedList(new ArrayList<Object>());  

初始容量为10,扩容为原来的1.5

int newCapacity = oldCapacity + (oldCapacity >> 1);

优势:随机查找和遍历
劣势:指定插入和删除
get() 直接读取第i个下标,复杂度 O(1)
add(E) 添加元素,直接在后面添加,复杂度 O(1)
add(index, E) 添加元素,在第i个元素后面插入,后面的元素需要向后移动,复杂度O(n)
remove()删除元素,后面的元素需要逐个移动,复杂度O(n)

1.2、Vector

底层是有序动态数组,线程安全,方法之间是线程同步的,所以访问比ArrayList慢
初始容量为10,扩容为原来的2
复杂度和ArrayList类似

1.3、LinkedList*

数据结构为双向链表,线程不安全,在内存中分配的空间不是连续的
get() 获取第几个元素,依次遍历,复杂度O(n)
add(E) 添加到末尾,复杂度O(1)
add(index, E) 添加第几个元素后,需要先查找到第几个元素,直接指针指向操作,复杂度O(n)
remove()删除元素,直接指针指向操作,复杂度O(1)

2、Map

2.1、HashMap和HashTable区别

HashMap线程不安全,所以效率高。支持key、value为null(key仅一个)
HashTable线程安全,所以效率低。不支持key或value为null
Collections.synchronizedMap()ConcurrentHashMap(更优)来解决HashMap的线程安全问题

2.1、HashMap

HashMap 的初始长度16,加载因子0.75
JDK1.7版本 数组+链表
JDK1.8版本 数组+链表+红黑树
https://blog.51cto.com/u_14962799/2721972

3、基本数据类型

类型 默认值
byte 0
short 0
int 0 -2^31 ~ 2^31-1
long 0L
float 0.0f
double 0.0d
char 'u0000'
boolean false

== 和 equals 的区别

== 在比较基本数据类型比较值(栈内存),引用数据类型比较堆内存地址
equals 默认是比较对象的内存地址值,如果内部重写了equals方法,例如String、Integer、Date,比较值是否相等

访问修饰符

image.png

public 所有类可见 公有的
protected 当前包、当前类、子类(在不同的包中也可以访问)
default 当前包和类(本包中的子类非子类可以访问,不同包中的类及子类均不能访问)
private 当前类 私有的

Mybatis

1、#{} 和 ${} 的区别

#{} 占位符?,sql预编译,所以防止SQL注入风险,值两边加上单引号
尽可能使用#{}
${} 字符串拼接,所以无法防止SQL注入
传递字段为表名或者字段名必须用${}
例如接在order by 、as 等后

2、使用 updateById 更新字段为null 不更新

实体类字段加上 @TableField(strategy = FieldStrategy.IGNORED) 忽略判断

@TableField(strategy = FieldStrategy.IGNORED) 
private String name;

但是要慎用,因为在使用mapper.update(con, po)的时候会自动修改为null,多人开发时有隐患。

字符串操作

1、substring

String s = "0123456789", s1, s2;
s1 = s.substring(2);
s2 = s.substring(2, 5);
System.out.println("s1:---------------" + s1); // 23456789
System.out.println("s2:---------------" + s2); // 234

JVM

1、CPU占用过多如何定位

  1. top 定位哪个进程对CPU占用最高(获取进程ID)
  2. ps 定位哪个线程引起CPU占用最高(根据进程ID)
  3. jstack 定位问题代码源码行数(根据线程ID)

2、字符串常量池

s1、s3、s4、s5、s8在字符串常量池中
s2、s6、s7在堆内存中(引用指向)

String s1 = "Programming";
String s2 = new String("Programming");
String s3 = "Program";
String s4 = "ming";
String s5 = "Program" + "ming";
String s6 = s3 + s4;
String s7 = "Program" + s4;
String s8 = "Program" + "min" + "g";
System.out.println(s1 == s2); // false
System.out.println(s1 == s5); // true
System.out.println(s1 == s6); // false
System.out.println(s1 == s6.intern()); // true(此处s6.intern指向常量池)
System.out.println(s2 == s2.intern()); // false(此处s2.intern指向常量池,s2未赋值所以还是堆中)
System.out.println(s2 == s6.intern()); // false
s2 = s2.intern(); // 此处s2指向常量池)
System.out.println(s2 == s6.intern()); // true 此处s2和s6.intern都指向常量池)
System.out.println(s2.intern() == s6.intern()); // true 都指向常量池
System.out.println(s1 == s7); // false
System.out.println(s1 == s8); // true
System.out.println(s1 == s2); // true
上一篇下一篇

猜你喜欢

热点阅读