复习

#### 总结

1.java中方法参数的使用:
一个方法不能修改一个基本数据类型的参数(即数值型和布尔型)
一个方法可以改变一个对象参数的状态
一个方法不能让对象参数引用一个新的对象
2.spring 声明式事务
PROPAGATION_REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER–以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED–如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与 PROPAGATION_REQUIRED类似的操作。

  1. 集合
  • 1.ArrayList:默认初始化容量大小10。arrayList每次扩容当前数组1.5倍。查询快,增删慢,线程不安全。推荐使用CopyOnWriteArrayList。
    
  • 2.linkedList:是有序的,底层是双向链表的,对增删元素有很高的效率、查询效率较低、尤其是随机访问、效率不忍直视。线程不安全。
    
  • 3.Vector: 是内部是以动态数组的形式来存储数据的。Vector是线程安全的。方法上都加了synchronized
    
  • 4.HashSet:保证集合中存储的值都是唯一不重复的,若插入重复的值,重复的值会替换掉原来的值。底层由HashMap实现。线程安全。
    
  • 5.TreeMap和TreeSet:的实现就是红黑树平衡数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证当需要快速检索指定节点。底层是hashset。
    
  • 6.HashMap:HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。默认长度16,每当大于当前map的75%的时候进行扩容,每次扩容是当前map两倍也就是2幂次方。在 Java 1.8 中,如果链表的长度超过了 8 ,那么链表将转化为红黑树。发生 hash 碰撞时,Java 1.7 会在链表头部插入,而 Java 1.8 会在链表尾部插入;
    
  • 反射和代理 自行了解,
    2.jvm内存模型

jvm中内存划分:
在这里插入图片描述

如上图,一共分为五块,其中:
线程共享区域为:
1、java堆
2、方法区

线程私有区域为:
3、JVM栈
4、本地方法栈
5、程序计数器

各区域作用:
1、java堆:
java堆是jvm内存管理中最大的一块,线程共享。在jvm启动的时候创建。此区域唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。但是随着JIT编译器(即时编译器)的发展与逃逸分析技术的逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙变化(对象可能会分配到栈上),所以这种所有对象都分配在堆上也不是那么绝对的。
java堆细分为新生代和老年代,新生代又分为Eden空间、From Survivor空间、To Survivor空间,新生代中垃圾回收算法为复制算法,复制算法是先将内存分为连个部分,一部分用来放入对象,而另一部分暂时不用,当使用的一部分内存要进行垃圾回收的时候会将不需要回收的对象复制保存在另一个空间中,然后再对使用过的那部分区域进行垃圾回收,这样虽然效率很高,但是很浪费空间,所以一般将新生代分为Eden空间和两个Survivor空间,其大小在HotSpot虚拟机中默认比例为8:1:1,这样在新生代中采用复制算法回收垃圾效率就很高了,具体回收过程是将Eden区域和From Survivor区域作为对象的存储空间,当要进行垃圾回收的时候先将这两个区域中不需要回收的对象复制保存在To Survivor区域中,然后再进行垃圾回收。另外有一点是当一个对象在Eden区域和From Survivor区域中存储的时候发现内存不足,这时会进行内存分配担保,就是将此对象直接存入在老年代中。
老年代中采用的GC算法为标记-清除算法或者标记-整理算法。标记-清除算法为:首先标记出要进行GC的对象,标记完成后再进行GC。这种算法效率不高,并且会产生很多内存碎片。标记-整理算法:同样是先对要进行GC的对象进行标记,但是不同的是在标记完成后不是立刻执行GC,而是先将不需要GC的对象移动到一端,然后在边界外再对要回收的对象进行GC。
关于对象的分配:对象优先在Eden区域分配,大对象会直接进入老年代,长期存活的对象会进入老年代,这里的长期存活是根据新生代中的对象年龄阈值来定义的,对象刚分配到新生代的时候年龄为1,每进行一次GC对象的年龄会加1,HotSpot中默认的阈值是15,也就是说对象年龄达到15岁的时候会被分配到老年区,这个值是可以通过参数配置的。
在进行垃圾回收的时候新生代GC又叫minor GC,老年代GC可以设置内存容量达到百分比的多少的时候进行GC,老年代的GC又叫Full GC,minor GC时间短,频率高,而Full GC时间长,频率低。

2、方法区
方法区又被称为永久区,线程共享,是用来存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区为堆的一个逻辑部分,但是在JDK1.7的HotSpot中已经将方法区中的字符串常量池移出,部分资料显示JDK1.8已经去除了方法区(不确定)。不过已经可以猜测此区域将会被本地内存逐步取代。
这个区域很少进行垃圾回收,回收目标主要是针对常量池的回收和对类型的卸载。

3、JVM栈
JVM栈是线程私有的,它的生命周期与线程相同。JVM栈描述的是java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
局部变量表中存放了编译期可知的各种基本数据类型、对象的引用类型。局部变量表中需要的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

4、本地方法栈
本地方法栈和JVM栈非常相似,它们之间的区别不过是jvm栈是为执行java方法服务,而本地方法栈是为jvm使用到对的本地方法服务。HotSpot虚拟机中直接把本地方法栈和JVM栈合二为一了。

5、程序计数器
程序计数器是一块较小的内存空间,线程私有。它可以看作是当前线程所执行的字节码的行号指示器。在jvm的概念模型里,字节码解释器工作就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
如果线程正在执行的是一个java方法,这个计数器记录的是正在执行的jvm字节码指令的地址;如果正在执行的是本地方法,这个计数器值则为空。

总结:
在jvm划分的内存区域中JVM栈和本地方法栈可能会抛出StackOverflowError异常和OutOfMemoryError异常。java堆和方法区可能会抛出OutOfMemoryError异常。程序计数器中没有地方规定会抛出这两个异常。

扩展:
在jvm规范中,StackOverflowError异常为:如果线程请求的栈深度大于JVM允许的栈深度,将抛出StackOverflowError异常。OutOfMemoryError异常:如果jvm可以动态扩展,如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。
HotSpot虚拟机中标记要清除的对象方法不是使用引用计数器(有引用的时候计数器+1,引用失效-1,应用为0时回收),而使用的是可达性分析算法:以“GC Roots“的对象为起点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明这个对象不可达,即这个对象不可用,所以这个对象会被判定为是可回收对象。

标记-清除算法处理前后:
在这里插入图片描述
复制算法处理前后:
在这里插入图片描述
标记-整理算法处理前后:
在这里插入图片描述
分代收集算法(就是把存活对象在eden和from和to来回复制,满足一定次数以后,就会转移到老年代)
在这里插入图片描述
JAVA分代机制的好处是可以根据Java的实际对象创建和销毁时机,在不同的生代中可以采用不同的垃圾回收策略,已提高垃圾回收的效率。在Java中,几乎所有对象的实例都分配与新生代,而大部分对象的存活时间都不长,新生代中的对象回收会比较频繁。而老年代中的存放是那些存活时间较长,或者对象过大导致无法在新生代中分配的对象。而永久代比较特殊,它一般是指内存区域中的方法区,HotSpot在实现方法区时作为永久代来处理,避免了额外来管理方法区。这块区域的内存回收我们一般不做考虑,因为效果不会很明显,而且回收的条件也非常苛刻。

常用设计模式有:单例模式,代理模式,适配器模式,工厂模式(静态工厂和静态工厂)

/** 
 * 线程安全  并且效率高 
 * 
 */ 
public class SingletonTest {  
    private static SingletonTest instance;  
   
    private SingletonTest() {  
    }  
   
    public static SingletonTest getIstance() {  
        if (instance == null) {  
            synchronized (SingletonTest.class) {  
                if (instance == null) {  
                    instance = new SingletonTest();  
                }  
            }  
        }  
        return instance;  
    }  
}  

性能优化

线程池:解决用户响应时间长的问题
连接池
JVM启动参数:调整各代的内存比例和垃圾回收算法,提高吞吐量
程序算法:改进程序逻辑算法提高性能

主流框架核心原理总结

1、spring原理
内部最核心的就是IOC了,动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟xml Spring的配置文件来动态的创建对象,和调用对象里的方法的 。
Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象 进行监督和控制(也就是 在调用这类对象的具体方法的前后去调用你指定的 模块)从而达到对一个模块扩充的功能。这些都是通过 配置类达到的。
Spring目的:就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring根据这些配置 内部通过反射去动态的组装对象)
要记住:Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能。
Spring里用的最经典的一个设计模式就是:模板方法模式。(这里我都不介绍了,是一个很常用的设计模式), Spring里的配置是很多的,很难都记住,但是Spring里的精华也无非就是以上的两点,把以上两点跟理解了 也就基本上掌握了Spring.

Spring AOP与IOC
一、 IoC(Inversion of control): 控制反转
1、IoC:
概念:控制权由对象本身转向容器;由容器根据配置文件去创建实例并创建各个实例之间的依赖关系
核心:bean工厂;在Spring中,bean工厂创建的各个实例称作bean
二、AOP(Aspect-Oriented Programming): 面向方面编程
1、 代理的两种方式:
静态代理:
 针对每个具体类分别编写代理类;
 针对一个接口编写一个代理类;
动态代理:
针对一个方面编写一个InvocationHandler,然后借用JDK反射包中的Proxy类为各种接口动态生成相应的代理类

spring cloud总结

eureka 两大组件 :eureka server 和eureka client 自我保护 actuator 可以配置自定义别名,显示IP地址,详情内容设置

eureka 集群:修改hosts文件,配置映射域名,修改 eureka配置文件(yml),hostname改成hosts文件配置域名,defaultZone: 配置另外集群eureka 映射域名,
在修改服务者的 eureka.service-url.defaultZone 把配置集群的所有eureka路径配置进去用逗号分隔
关系型数据库原则:A原子性,C一致性,I独立性,D持久性。
非关系型数据原则,C强一致性,A可用性,P分区容错性。
zookeeper 原则 CP 一致性,分区容错性。
eureka 原则 AP 可用性,分区容错性。
ribbon 是一个软负载均衡的客户端组件
ribbon 负载均衡 7种算法:
feign 可以使调用多个微服务,调用更方便简洁,减少开发量,想调用接口一样简单。
Hystrix断路器 可以进行 服务降级,服务熔断,服务限流,服务监控。
zuul包含对请求的路由和过滤和代理功能。

解决并发编程三个源头,可见性,原子性,有序性。
happens-before规则解决多线程中,可见性,有序性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值