当前位置 博文首页 > lzh_2_4的博客:各种笔记

    lzh_2_4的博客:各种笔记

    作者:[db:作者] 时间:2021-08-02 15:42

    nginx中的if和后面的()中间必须有空格

    查找阿里有关的Java视频资料

    三目运算符多条件使用

    Boolean ? 结果a : Boolean ? 结果b : 结果c;

    SQl的执行顺序

    (1)from
    (3) join
    (2) on
    (4) where
    (5)group by(开始使用select中的别名,后面的语句中都可以使用)
    (6) avg,sum…
    (7)having
    (8) select
    (9) distinct
    (10) order by

    CMS接口开发

    文件上传

    MySQL读写分离

    SpringCloud+SpringBoot

    RabbitMQ搭建

    SpringSecurity Oauth2

    课程管理

    SpringBoot+SpringDataJPA:操作简单的增删改查+Mybatis:多表联查等

    搜索

    媒资管理

    SpringSecurity

    分布式事务

    反射

    SpringBoot如何创建一个新项目

    分布式事务

    SpringCloud

    数据库范式

    JS&JQ对象转化

    SpringJPA

    DOM BOM

    泛型

    四种引用

    MySQL视图

    SpringMVC的工作流程

    • 请求发送到服务器之后,被封装为request对象(tomcat封装)进入到之后DispatcherServlet(springmvc的入口)
    • 接下来到达HanlderMapping(处理器映射器)之后来选择映射
      • 根据注解@RequestMapping注解的路径和tomcat封装好的请求路径来进行匹配
    • 接下来进入到处理器执行链(HandlerExecutionChain)
      • 调用控制器对应的拦截器
      • 接下来调用处理器适配器(HandlerAdapter)
      • 通过处理器适配器来调用我们写的controller
      • 然后统一返回modelandview对象
    • 在转发前,会把model中的数据存入request作用域中
      • 再由视图解析器(viewResolver)将视图名转换为最终的jsp路径,并转发到jsp
    • 如果执行过程中出现了异常:
      • 异常解析器(exceptionhandlerexceptionresolver)进行处理
    • jsp动态生成html代码并返回响应

    九种域对象

    SpringBoot

    1).所有的模块都要继承spring-boot-starter-parent
    @SpringBootApplication注解,是核心注解,具有包扫描的作用,默认扫描当前包及其子包,标识当前类是引导类,若需要扫描其他包,那么在此注解下添加@ComponentScan(basePackage=("需要扫描的全包名","com.lzh..."))
    借助main执行SpringApplication.run方法,表示要运行SpringBoot的引导类,run方法的参数就是SpringBoot引导类的字节码对象(谁有注解谁是引导类)
    2).热部署:在pom.xml中添加spring-boot-devtools坐标
    3).**起步依赖** parent:依赖于dependencies(通过<dependencyManagement>来统一管理依赖的版本)
    
    4).起步依赖 web:依赖传递,依赖于parent,parent依赖于dependencies
    5).**自动配置**:@SpringBootApplication由三个注解组成(@SpringBootConfiguration:声明当前类是Spring的一个配置类
    @ComponentScan:进行包扫描的注解,默认扫描当前包及其子包
    @EnableAutoConfiguration:自动配置的核心注解,是否自动配置的开关)
    
    
    
    

    Redis的穿透

    解决方案 使用string存储数据 若查询不到那么将请求参数设置null值并存入缓存,同时设置过期时间,那么在过期时间内将不会再访问数据库
    所有的请求不会访问数据库,只访问redis,设置定时任务,定期更新redis中的数据
    

    Redis的击穿

    高并发情况下,缓存失效,造成大量请求瞬间请求数据库
    设置条件,同样的请求只能有一个线程去访问数据库,再使用互斥锁(trylock)
    

    Redis的雪崩

    大量的高并发的缓存同时失效,造成的数据库压力过大(整点抢购活动)
    解决方案:设置不同的过期时间,
    只查redis,通过定时任务定时更新redis
    

    设计模式

    设计模式五大原则和一法则

    • 单一职责原则(Single Responsibility Principle)(高内聚,低耦合):一个类只负责一项职责,对一个类而言,只能有一个引起他变化的原因

    • 里氏替换原则(LSP liskov substitution principle):子类可以扩展父类的功能,但不能改变父类原有的功能(增强程序的健壮性)

    • 依赖倒置原则(dependence inversion principle)**:面向接口编程,上层模块不应该依赖下层模块,两者应依赖其抽象

    • 接口隔离(interface segregation principle)**:建立单一接口,类之间的依赖关系应该建立在最小的接口上,客户端不应该依赖不需要的接口【接口粒度越小,系统越灵活,但复杂性越高,维护性降低】

    • 迪米特原则(law of demeter LOD):最少知道原则,尽量降低类于类之间的耦合;一个对象应该对其他对象有最少的了解

    • 总:开闭原则(open closed principle):用抽象构建架构,用实现扩展原则

    	1.工厂模式:****
    		类别:创建型模式;
    		功能:提供了一种创建对象的最佳方式;
    		优点:1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体逻辑实现,调用者只关心产品的接口;
    		缺点:适合复杂对象适合工厂模式,使得系统中的类的个数成倍增加会增加系统复杂度和具体类的依赖;
    		使用场景:1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 
    		2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 	3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。 
    	2.抽象工厂模式:*****
    		类别:创建型模式;
    		功能:提供了一种创建对象的最佳方式;
    		优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象;
    		缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
    	3.单例模式:****
    		类别:创建型模式;
    		功能:提供了一种创建对象的最佳方式;
    		优点:1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。2、避免对资源的多重占用(比如写文件操作);
    		缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。;
    		使用场景:     	
    		1、要求生产唯一序列号。
    	    2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
    	    3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
    	4.建造者模式:**
    		类别:创建型模式
    		功能:使用多个简单的对象一步一步构建成一个复杂的对象
    		优点:建造者独立,易于扩展,便于控制细节风险
    		缺点:产品需有共同点,范围有限制,内部变化复杂,辉有很多的建造类
    		使用场景:
    		1、需要生成的对象具有复杂的内部结构
    		2、需要生成的对象内部属性本身相互依赖
    		**与工厂模式的区别是:建造者模式更加关注零件装配的顺序。
    	5.原型模式:***
    		类别:创建型模式
    		功能:用于创建重复的对象,同时又能保证性能。提供了创建对象的最佳方式,在运行期建立和删除原型
    		关键代码:继承Cloneable重写clone()方法
    		优点:性能提高,避开构造函数的约束
    		缺点:对于已有的类不支持串行化的间接对象或含有循环结构,需实现Cloneable接口
    		使用场景:
    		1、资源优化场景
    		2、类的初始化需要消耗非常多的资源
    		3、性能和安全要求的场景
    		4、通过new产生一个对象需要非常多的数据准备或,访问权限
    		5、一个对象或多个修改者的场景
    		6、一个对象需要被多个对象访问且修改时可以拷贝多个对象给他们用
    		7、原型模式一般结合工厂方法模式一起出现,通过clone的方法创建一个对象,通过工厂方法提供给调用者,
    		======((((这个模式和volatile有啥区别))))=====
    	6.适配器模式(转换器)****
    		类别:结构型模式
    		功能:将一个类的接口转换成另一个接口,使不兼容的类可以一起工作
    		关键代码:适配器继承或依赖已有对象,实现想要的目标接口
    		优点:可以让两个没有关联的类一起运行,提高了类的复用,增加了类的透明度,灵活性好
    		缺点:过多使用会让系统零乱,不易整体把握。Java单继承,最多适配一个适配者类
    		使用场景:有动机的修改一个正常运行的系统的接口,可以考虑使用适配器模式
    		**适配器是解决正在服役的项目问题
    	7.桥接模式***
    		类别:结构型模式
    		功能:使实体类的功能独立于接口实现类,这两种类型的类可被结构化改变而互不影响。(将抽象部分和实现部分分离,使他们可以独立变化)
    		关键代码:抽象类依赖实现类
    		优点:抽象和实现的分离,扩展能力强,实现细节对客户透明
    		缺点:因聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与变成
    		使用场景:1、一个系统需要在构件的抽象化角色和具体化角色之间增加灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使他们在抽象层建立一个关联关系2、对于不希望使用继承,或因多层次继承导致系统类的个数增加过多的系统3、一个类存在两个独立变化的纬度且这两个类都需要进行扩展
    		**对于两个独立变化的维度,使用桥接模式非常合适
    	8.过滤器模式(或标准模式)
    		类别:结构型模式
    		功能:获得符合多个条件的对象
    		使用场景:对一组数据进行分组的情况下,可以定义一个接口,通过实现接口重写过滤方法,比如传入一个集合,将集合中姓刘的人筛选出来,定义方法,遍历传入的集合,将符合条件的数据加入新的集合并返回,总的来说就是传入数据,去掉不符合条件的并返回
    	9.组合模式(部分整体模式)****
    		类别:结构型模式
    		功能:使客户程序与复杂元素的内部结构解耦(动态的给一个对象添加一些额外的职责)
    		关键代码:树枝和叶子实现统一接口,数值内部组合该接口
    		实例:算术表达式包括[操作数,操作符,另一个操作数],另一个操作符也可以是操作数、操作符和另一个操作数。
    		优点:高层模块调用简单,节点自由增加
    		缺点:其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则
    		使用场景:部分,整体场景,树形菜单,文件,文件夹的管理
    	10.装饰器模式***
    		类别:结构型模式(创建了一个装饰类用来包装原有的类)
    		功能:保持类方法签名完整性的前提下,提供了额外的功能
    		关键代码:
    			1.Component类充当抽象角色,不应该具体实现
    			2.修饰类引用和继承Component类,具体扩展类重写父类的方法
    		实例:孙悟空72变,本质还是猴子
    		优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,可以动态的扩展一个实现类的功能
    		缺点:多层装饰比较复杂
    		使用场景:扩展一个类的功能,动态的增加功能,动态撤销
    	11.外观模式*****
    		类别:结构型模式
    		功能:为子系统中的一组接口提供一个一致的界面,降低访问复杂系统的内部子系统的复杂度,简化客户端与其的接口
    		关键代码:在客户端和复杂系统之间再加一层,在这一层将调用顺序和依赖关系处理好
    		实例:西京医院便民门诊(ps:哈哈哈哈秀emmm虽然便民关了)
    		优点:减少系统相互依赖,提高灵活性,安全性
    		缺点:不符合开闭原则,若要改东西,那么将会很麻烦
    		使用场景:1.为复杂的模块或子系统提供外界访问的模块
    				2.子系统相对独立
    				3.预防低水平人员带来的风险
    	12.享元模式*
    		类别:结构型模式
    		功能:尝试重用现有的同类对象,若无则创建新对象
    		关键代码:用HashMap存储这些对象
    		实例:String类型的字符串,如果有那么返回,如果没有,那么创建一个字符串保存在字符串缓存池里;数据库的数据池
    		优点:大大减少了对象的创建,降低系统的内存,使效率提高
    		缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,否则可能会引起线程安全问题,这些类需要有一个工厂对象加以控制.
    		使用场景:系统有大量相似对象,需要缓冲池的场景
    		我的问题:为什么需要分离外部状态和内部状态,为什么会引起线程安全问题,为什么需要工厂对象加以控制,如string创建时的过程,工厂是谁?怎么分离的状态
    	13.代理模式****
    		类别:结构型模式
    		功能:为其他对象提供一种代理以控制对这个对象的访问,
    		关键代码:实现与被代理类组合
    		实例:应用的快捷方式,spring aop,火车票代售点,kfc甜品站(emm)
    		优点:职责清晰,扩展性高,智能化
    		缺点:有些类型的代理模式可能会造成请求的处理速度变慢,某些代理模式特别复杂
    		使用场景:1、远程代理。2、虚拟代理。3、copy-on-write代理。4、保护代理。5、cache代理。6、防火墙代理。7、同步化代理。8、只能引用代理。
    		注意:1、和适配器模式的区别:适配器模式主要考虑对象的接口,而代理模式不能改变所代理类的接口。2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
    	14.责任链模式**
    		类别:行为模式
    		功能:让多个对象都有可能接受请求,责任链上的处理者负责处理请求,客户只需要将请求发送到责任链上即可,无需关心请求的处理细节和请求的传递,所以责任链将请求的发送者和请求的处理者解耦了,一般用在处理消息时过滤很多道
    		关键代码:Handler里面聚合它自己,在HandlerRequest里判断是否合适,若妹达到条件则向下传递,向谁传递之前set进去
    		实例:Javaweb中tomacat对encoding的处理,jsp servlet的filter
    		优点:
    			1、降低请求的发送者和接收者的耦合度
    			2、简化对象,使对象不需要知道链的结构
    			3、增强给对象指派职责的灵活性,通过改变链内的成员或调动他们的次序,允许动态地增加或删除责任
    			4、增加新的请求处理类很方便(实现接口就好??)
    		缺点:影响系统性能,不能保证请求一定被接受,不容易观察运行时的特征影响除错
    		使用场景:
    				1、多个对象处理同一个请求
    				2、在不明确指定接收者的情况下,想多个对象中的一个提交一个请求
    				3、可动态制定一组对象处理请求
    				
    				
    	15.命令模式****
    		类别:行为模式
    		功能:将一个请求封装成一个对象,传给调用对象,调用对象寻找可以处理该命令的合适的对象,并将该命令传给响应的对象,该对象执行传入的请求对象。
    		关键代码:定义三个角色:
    			1、received真正的命令执行对象
    			2、Command
    			3、invoker使用命令对象的入口
    		优点:降低了系统耦合度,新的命令可以很容易的添加到系统中
    		缺点:可能导致系统由过多的具体命令类
    		使用场景:需要对行为进行记录、撤销/重做、事务等处理,需要将行为请求者和行为实现者解耦,那么就需要将一组行为抽象为对象从而实现松耦合
    		实例:springmvc中doget,dopost;实现一个控制器转发到多个模型,定义接口,让所有模型实现这个接口那么就可以转发过去;
    	16.解释器模式*
    		类别:行为模式
    		功能:该接口解释一个特定的上下文
    		关键代码:构建环境类,包含解释器之外的一些全局信息,一般是使用hashmap
    		优点:扩展性好,易于实现简单文法
    		缺点:可利用场景较少,难维护,一般采用的递归调用
    		使用场景:将解释执行的语言中的句子表示为一个抽象语法树,重复出现的问题可以用一种简单的语言来表达
    		**在Java中可以用expression4j代替
        17.迭代器模式*****
    		类别:行为模式
    		功能:顺序访问集合对象的元素,不需要知道集合对象的底层表示
    		关键代码:定义接口hasNext,next
    		优点:
    			1、支持不同的方式遍历一个聚合对象
    			2、迭代器简化了聚合类
    			3、在同一个聚合上可以有多个遍历
    			4、增加新的聚合类和迭代器类都很方便,无需修改原有代码
    		缺点:增加了系统的复杂性。
            使用场景:
            1、访问一个聚合对象的内容而无须暴露它的内部表示。 
            2、需要为聚合对象提供多种遍历方式。
            3、为遍历不同的聚合结构提供一个统一的接口。
            实例:iterator
    	18.中介者模式**
        	类别:行为模式
        	功能:降低多个对象和类之间的通信复杂性,使代码易于维护
        	关键代码:对象之间的通信封装到一个类中单独处理
        	优点:降低了类的复杂度,解耦,符合迪米特原则
        	缺点:中介者复杂庞大难以维护
        	使用场景:对象之间存在比较复杂的引用关系,难以复用
        	实例:MVC框架 controller是model和view的中介者
        19.备忘录模式**
        	类别:行为模式
        	功能:保存一个对象的某个状态,用于适当的时候恢复对象
        	关键代码:客户不与备忘录耦合,与备忘录管理类耦合
        	优点:方便的找回历史状态,实现了信息的封装,不需要关心状态的保存细节
        	缺点:消耗资源
        	使用场景:需要恢复数据的场景,提供回滚的操作
        	实例:数据库事务,ctrl+z
        20.策略模式****
        	类别:行为模式
        	功能:随着策略对象的改变从而使用不同的算法
        	关键代码:实现同一个接口
        	优点:算法可以自由切换,避免使用多重条件判断,扩展性好
        	缺点:策略类会增多,所有策略类都需要对外暴露服务
        	使用场景:动态的让一个对象在许多行为中选择一个,系统需要动态的在集中算法中选择一种
        	实例:webmagic,java AWT中的LayoutManager
        	**若策略多于四个需要考虑使用混合模式
        21.访问者模式*
        	类别:行为模式
        	功能:将数据结构和数据操作分离
        	关键代码:在数据基础类里有一个方法接受访问者,将自身传入访问者
        	优点:符合单一职责原则,优秀的扩展性,灵活性
        	缺点:
        		1、具体元素对访问者公布细节,违反了迪米特原则
        		2、具体元素变更比较困难
        		3、违反了依赖倒置原则,依赖了具体类,没有依赖抽象
        	使用场景:对象结构中对象对应的类很少改变,需要对对象结构中的对象进行很多不同且不相关的操作
        	实例:报表,UI,拦截器,过滤器
        22.模板模式***
        	类别:行为模式
        	功能:一些方法通用,却在每一个子类都重写了这个方法
        	关键代码:在抽象类实现,其他不通用的方法在子类实现
        	优点:
        		1、封装不变的部分,扩展可变部分
        		2、提取公共代码,便于维护
        		3、行为又父类控制,子类实现
        	缺点:每一个不同的实现都需要一个子类来实现,类会过多
        	使用场景:重要的复杂的方法可以考虑作为模板方法
        	实例:spring对hibernate的支持
        	**为防止恶意操作,一般模板方法都加上 final 关键词
        23.状态模式***
        	类别:行为模式
        	功能:允许对象在内部状态发生改变时改变他的行为,对象看起来好像修改了他的类
        	关键代码:状态模式的接口中有一个或者多个方法
        	优点:
        		1、封装了转换规则
        		2、枚举可能的状态
        		3、将所有与某个状态有关的行为放到一个类中,并且可以方便的增加新的状态,只需要改变对象状态就可以改变对象的行为
        		4、允许状态逻辑转换与状态对象合成一起
        		5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数
        	缺点:
        		1、会增加系统类和对象的个数
        		2、对开闭原则的支持并不友好
        	使用场景:行为随状态改变而改变的场景,条件分支语句的代替者
        	实例:比赛时的状态,一般,及格,超长
         24.观察者模式***
        	类别:行为模式
        	功能:当一个对象被修改时,自动通知他的依赖对象
        	关键代码:在抽象类中有一个ArrayList存放观察者
        	优点:观察者和被观察者是抽象耦合的,建立了一套触发机制
        	缺点:
        		1、若观察者过多,消耗资源会过多
        		2、若观察者和观察目标之间有依赖循环的话,可能导致循环调用(类似递归无出口)
        		3、没有相应的机制让观察者知道目标是怎么发生变化的
        	使用场景:一个对象的改变将导致其他一个多个对象也发生改变,a影响b,b影响c
        	注意:
        		1、java中已经有对观察者模式支持的类
        		2、避免循环引用
        		3、一般采用异步方式。顺序执行可能会导致系统卡壳
       
    			
    

    java内部类的特点

    静态内部类才可以声明静态方法
    静态方法不可以使用非静态变量
    抽象方法不可以有函数体
    
    1.为什么使用内部类?
    使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,
    对于内部类都没有影响
    1.1.使用内部类最大的优点就在于它能够非常好的解决多重继承的问题,使用内部类还能够为我们带来如下特性:
    (1)、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独。
    (2)、在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
    (3)、创建内部类对象的时刻并不依赖于外围类对象的创建。
    (4)、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
    (5)、内部类提供了更好的封装,除了该外围类,其他类都不能访问。
    2.内部类分类:
    (一).成员内部类:
    	
    public class Outer{
            private int age = 99;
            String name = "Coco";
            public class Inner{
                String name = "Jayden";
                public void show(){
                    System.out.println(Outer.this.name);
                    System.out.println(name);
                    System.out.println(age);
                }
            }
            public Inner getInnerClass(){
                return new Inner();
            }
            public static void main(String[] args){
                Outer o = new Outer();
                Inner in = o.new Inner();
                in.show();
            }
        }
    1.Inner 类定义在 Outer 类的内部,相当于 Outer 类的一个成员变量的位置,Inner 类可以使用任意访问控制符,
    如 public 、 protected 、 private 等
    2.Inner 类中定义的 show() 方法可以直接访问 Outer 类中的数据,而不受访问控制符的影响,
    如直接访问 Outer 类中的私有属性age
    3.定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,
    即:内部类 对象名 = 外部类对象.new 内部类( );
    4.编译上面的程序后,会发现产生了两个 .class 文件: Outer.class,Outer$Inner.class{}
    5.成员内部类中不能存在任何 static 的变量和方法,可以定义常量:
    (1).因为非静态内部类是要依赖于外部类的实例,而静态变量和方法是不依赖于对象的,仅与类相关,
    简而言之:在加载静态域时,根本没有外部类,所在在非静态内部类中不能定义静态域或方法,编译不通过;
    非静态内部类的作用域是实例级别
    (2).常量是在编译器就确定的,放到所谓的常量池了
    ★★友情提示:
    1.外部类是不能直接使用内部类的成员和方法的,可先创建内部类的对象,然后通过内部类的对象来访问其成员变量和方法;
    2.如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,
    可以使用 this 关键字,如:Outer.this.name
    (二).静态内部类: 是 static 修饰的内部类,
    1.静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
    2.如果外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员;
    如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
    3.创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名 = new 内部类();
    public class Outer{
                private int age = 99;
                static String name = "Coco";
                public static class Inner{
                    String name = "Jayden";
                    public void show(){
                        System.out.println(Outer.name);
                        System.out.println(name);                  
                    }
                }
                public static void main(String[] args){
                    Inner i = new Inner();
                    i.show();
                }
            }
    (三).方法内部类:其作用域仅限于方法内,方法外部无法访问该内部类
    (1).局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的
    (2).只能访问方法中定义的 final 类型的局部变量,因为:
    当方法被调用运行完毕之后,局部变量就已消亡了。但内部类对象可能还存在,
    直到没有被引用时才会消亡。此时就会出现一种情况,就是内部类要访问一个不存在的局部变量;
    ==>使用final修饰符不仅会保持对象的引用不会改变,而且编译器还会持续维护这个对象在回调方法中的生命周期.
    局部内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,
    自己内部的方法调用的实际是自己的属性而不是外部类方法的参数;
    防止被篡改数据,而导致内部类得到的值不一致
       /*
            使用的形参为何要为 final???
             在内部类中的属性和外部方法的参数两者从外表上看是同一个东西,但实际上却不是,所以他们两者是可以任意变化的,
             也就是说在内部类中我对属性的改变并不会影响到外部的形参,而然这从程序员的角度来看这是不可行的,
             毕竟站在程序的角度来看这两个根本就是同一个,如果内部类该变了,而外部方法的形参却没有改变这是难以理解
             和不可接受的,所以为了保持参数的一致性,就规定使用 final 来避免形参的不改变
             */
            public class Outer{
                public void Show(){
                    final int a = 25;
                    int b = 13;
                    class Inner{
                        int c = 2;
                        public void print(){
                            System.out.println("访问外部类:" + a);
                            System.out.println("访问内部类:" + c);
                        }
                    }
                    Inner i = new Inner();
                    i.print();
                }
                public static void main(String[] args){
                    Outer o = new Outer();
                    o.show();
                }
            }    
    (3).注意:在JDK8版本之中,方法内部类中调用方法中的局部变量,可以不需要修饰为 final,匿名内部类也是一样的,主要是JDK8之后增加了 Effectively final 功能
    http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html
    反编译jdk8编译之后的class文件,发现内部类引用外部的局部变量都是 final 修饰的
    (四).匿名内部类:
    (1).匿名内部类是直接使用 new 来生成一个对象的引用;
    (2).对于匿名内部类的使用它是存在一个缺陷的,就是它仅能被使用一次,创建匿名内部类时它会立即创建一个该类的实例,
    该类的定义会立即消失,所以匿名内部类是不能够被重复使用;
    (3).使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口;
    (4).匿名内部类中是不能定义构造函数的,匿名内部类中不能存在任何的静态成员变量和静态方法;
    (5).匿名内部类中不能存在任何的静态成员变量和静态方法,匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法
    (6).匿名内部类初始化:使用构造代码块!利用构造代码块能够达到为匿名内部类创建一个构造器的效果
    	
      public class OuterClass {
                public InnerClass getInnerClass(final int   num,String str2){
                    return new InnerClass(){
                        int number = num + 3;
                        public int getNumber(){
                            return number;
                        }
                    };        /* 注意:分号不能省 */
                }
                public static void main(String[] args) {
                    OuterClass out = new OuterClass();
                    InnerClass inner = out.getInnerClass(2, "chenssy");
                    System.out.println(inner.getNumber());
                }
            }
            interface InnerClass {
                int getNumber();
            }         
    

    常用Linux指令

     1.ps 查看当前服务器上的进程 -ef | grep xxx -- color  查看xxx是否在进程中
     2.top查看资源
     3.tail 显示文件尾部 通常配合 -f /logs/catalina.out 查看日志文件
     4.free 查看当前服务器的内存总数 -m 是将结果已m的形式展示
     5.查看磁盘剩余空间 desk
    

    反射的特点

      反射指的是在运行时能够分析类的能力的程序。
      反射机制可以用来:
    1.在运行时分析类的能力--检查类的结构--所用到的就是java.lang.reflect包中的Field、Method、Constructor,分别用于描述类的与、方法和构造器。A中的Class类在java.lang中。
    2.在运行时查看对象。
    3.实现通用的数组操作代码。
    反射机制的功能:
    在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
    反射机制常见作用:
    动态加载类、动态获取类的信息(属性、方法、构造器);动态构造对象;动态调用类和对象的任意方法、构造器;动态调用和处理属性;获取泛型信息(新增类型:ParameterizedType,GenericArrayType等);处理注解(反射API:getAnnotationsdeng等)。
    反射机制性能问题:
    反射会降低效率。
    void setAccessible(boolean flag):是否启用访问安全检查的开关,true屏蔽Java语言的访问检查,使得对象的私有属性也可以被查询和设置。禁止安全检查,可以提高反射的运行速度。
    可以考虑使用:cglib/javaassist操作。
    

    红黑树的基本原则

    性质1. 节点是红色或黑色。
    性质2. 根节点是黑色。
    性质3. 每个叶子的子节点都是黑色的空节点 
    性质4. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
    性质5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
    

    TDD的三个原则

    1)没有测试之前不要写任何功能代码
    2)只编写恰好能够体现一个失败情况的测试代码
    3)只编写恰好能通过测试的功能代码
    
    在实际开发过程中,可能并不需要严格遵守这三个原则。即便只是大体上应用TDD到复杂功能开发,就能发挥很大的作用。
    具体来说,首先在开发前期,按照TDD的原则不断在添加测试用例和开发功能代码之间切换。
    在这个循环迭代过程中,不断地通过重构和面向对象思想,完善代码设计。
    并且可以引入业界公认的设计模式使自己的代码更加专业、优美。
    
    这样做的优点:
    一是帮助思考。对于很复杂的功能需要迭代开发,不可能一下子就把逻辑实现全想明白。于是可以先实现最简单功能,再逐步完善;
    二是快速调试。有了单元测试,可以通过失败的用例直接找到对应出问题的代码,几乎不需要太多调试了;
    三是通过TDD不断迭代出的代码,设计比较合理,后期更加容易维护。
    
    当然凡事都是有利有弊的,TDD也有它的缺点和局限:
    一是前期进开发稍慢一些,因为需要编写单元测试(但是TDD往往在开发中后期会让你的开发进度越来越快,
    TDD节省下来的时间将远远超过编写和维护测试用例的时间。这就好比玩即时战略游戏,前期的精心布局将在中后期看到效果);
    二是对于简单功能并不适用,要注意应用场景。
    

    CAS(比较并交换)

    ? 应用:自旋锁

    public class SpinLock {
    
      private AtomicReference<Thread> sign =new AtomicReference<>();
    
      public void lock(){
        Thread current = Thread.currentThread();
        while(!sign .compareAndSet(null, current)){
        }
      }
    
      public void unlock (){
        Thread current = Thread.currentThread();
        sign .compareAndSet(current, null);