设计模式
1、单例模式
某个类只能生成一个实例,该实例全局访问,例如Spring容器里一级缓存里的单例池。
优点:
唯一访问:如生成唯一序列化的场景、或者spring默认的bean类型。
提高性能:频繁实例化创建销毁或者耗时耗资源的场景,如连接池、线程池。
缺点:
不适合有状态且需变更的
实现方式:
饿汉式:线程安全速度快
懒汉式:双重检测锁,第一次减少锁的开销、第二次防止重复、volatile防止重排序导致实例化未完成
静态内部类:线程安全利用率高
枚举:effictiveJAVA推荐,反射也无法破坏
2、工厂模式
定义一个用于创建产品的接口,由子类决定生产何种产品。
优点: 解耦:提供参数即可获取产品,通过配置文件可以不修改代码增加具体产品。
缺点: 每增加一个产品就得新增一个产品类
3、抽象工厂模式
提供一个接口,用于创建相关或者依赖对象的家族,并由此进行约束。
优点: 可以在类的内部对产品族进行约束
缺点: 假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。
4、 待续......
设计原则
1、开闭原则
定义: 软件实体应当对扩展开放,对修改关闭,这就是开闭原则的经典定义。 这里的软件实体包括以下几个部分: 1. 项目中划分出的模块 2. 类与接口 3. 方法
含义: 当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以 扩展模块的功能,使其满足新的需求。
作用: 开闭原则是面向对象程序设计的终极目标,它使软件实体拥有一定的适应性和灵活性的同时具备稳定性 和延续性。具体来说,其作用如下。 1. 对软件测试的影响 2. 可以提高代码的可复用性 3. 可以提高软件的可维护性
实现方法: 可以通过“抽象约束、封装变化”来实现开闭原则,即通过接口或者抽象类为软件实体定义一个相对 稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中。
举例:
- 学校有许多的课程,其中有一门课程为java课程,我们需要打印出该课程的id、名称以及售价,为此 新建一个接口类ICourse和实现类JavaCourse,JavaCourse实现接口ICours
- 此时,正好赶上节日,我们有一个促销活动,JAVA课程我们打六折
- 第一种选择: 在ICours新增打折方法getDiscountPrice, 这种会将所有实现ICours接口的实现类都得做改变
- 第二种选择: 每次打折我们都修改JavaCourse类,这种代码显然是不合理的,这样破坏了原本稳定的代码
- 第三种选择: 新建一个JavaDiscountCourse类继承JavaCourse,并在JavaDiscountCourse新增加一个打折即可
2、待续......
面试题
构造方法
构造方法可以被重载,只有当类中没有显性声明任何构造方法时,才会有默认构造方法。
构造方法没有返回值,构造方法的作用是创建新对象。
初始化块
静态初始化块的优先级最高,会最先执行,在非静态初始化块之前执行。
静态初始化块会在类第一次被加载时最先执行,因此在 main 方法之前。
This
关键字 this 代表当前对象的引用。当前对象指的是调用类中的属性或方法的对象
关键字 this 不可以在静态方法中使用。静态方法不依赖于类的具体对象的引用
重写和重载的区别
重载指在同一个类中定义多个方法,这些方法名称相同,签名不同。
重写指在子类中的方法的名称和签名都和父类相同,使用override注解
Object类方法
toString 默认是个指针,一般需要重写
equals 比较对象是否相同,默认和==功能一致
hashCode 散列码,equals则hashCode相同,所以重写equals必须重写hashCode
finalize 用于垃圾回收之前做的遗嘱,默认空,子类需重写
clone 深拷贝,类需实现cloneable的接口
getClass 反射获取对象元数据,包括类名、方法、
notify、wait 用于线程通知和唤醒
基本数据类型和包装类
| 类型 | 缓存范围 |
|---|---|
| Byte,Short,Integer,Long | [-128, 127] |
| Character | [0, 127] |
| Boolean | [false, true] |