Java 基础知识复习

1. Java面向对象:对象的概念及面向对象的三个基本特征

  1. 封装:隐藏内部实现细节,对外提供可访问的方法
  2. 继承:子类自动继承父类中所有的非私有属性和方法Java 语言是单继承的,即只能有一个父类,但 Java 可以实现多个接口(接口类似于类,但接口的成员没有执行体。可以防止多继承所引起的冲突问题。
  3. 多态:同一事物,多种不同的表示形态,例如:重载、重写
  4. 抽象:可以不用管具体的实现,定义统一的抽象规则

2. HashMap的特性

  1. HashMap存储键值对实现快速存取,允许为nullkey值不可重复,若key值重复则覆盖。
  2. 非同步,线程不安全。
  3. 底层是hash表,不保证有序
  4. JDK7 采用的是数组+链表
  5. JDK8 采用的数组+链表+红黑树
  6. 链表主要是为了解决数组中的key发生hash冲突时,将发生碰撞的key存到链表中
  7. 红黑树主要是为了解决链表过长,的查询速度太慢问题

3. 单例模式

属于对象创建模式,它可以确保系统中一个类只产生一个实例。这样的行为能带来两大好处:
对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销。由于new操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻GC压力,缩短GC停顿时间。

    1. 单例饿汉式和懒汉式区别
      饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。
      懒汉式懒汉式是延时加载,他是在需要的时候才创建对象,而饿汉式在虚拟机启动的时候就会创建。
      两者建立单例对象的时间不同。 “懒汉式”是在你真正用到的时候才去建这个单例对象, “饿汉式”是在不管用不用得上,一开始就建立这个单例对象。
    1. java单例模式之 双重校验锁
public class Singleton03 {
    private volatile static Singleton03 instance;
    /**
     * 私有构造方法
     */
    private Singleton03(){}
    public static Singleton03 getInstance() {
        if(instance == null) {
            synchronized (Singleton03.class) {
                if (instance == null) {
                    instance = new Singleton03();
                }
            }
        }
        return instance;
     }
}
    1. 第一次校验, if(singleton == null) 意义是由于单利模式只需创建一个实列,所以当第一次创建实列成功之后,再次调用Singleton.getInstance() 就没必要进入同步锁代码块,直接返回之前创建的实列即可。
    1. 第二次校验是为了防止二次创建实列,我们假设一种状况,当singleton还未被创建的时候,线程r1 调用了getInstance 方法,由于此时的singleton 为空,则可以进入第一层判断,线程r1正准备继续执行,此时,线程r2抢占cpu资源,此时r2也调用了getInstance 方法,同理线程r1并没有实例化singleton,线程r2也可以进去判断,然后继续往下执行,进入到同步代码块,进入第二层判断,完成了singleton 的创建,并分配空间,r2线程运行周期结束。执行任务又回到了r1,如果没有第二层判断,线程r1 也会创建一个实列(r2线程已经创建一个实列,第二层判断为false),这样就完全避免掉多线程环境下会创建多个实列的的问题
    1. private static volatile Singleton singleton = null;这是必要的 因为volatile关键字可以防止jvm指令重排优化,就是 singleton = new Singleton() 可以理解为三个阶段:1 为singleton 分配空间 2 初始化singleton 3 将创建的singleton实列指向分配的内存空间。
      因为JVM具有指令重排的特性,执行顺序有可能变成 1-3-2。 指令重排在单线程下不会出现问题,但是在多线程下会导致一个线程获得一个未初始化的实例。例如:线程r1执行了1和3,此时r2调用 getInstance() 后发现 singleton 不为空,因此返回 singleton, 但是此时的 singleton 还没有被初始化。
    1. 使用 volatile会禁止JVM指令重排,从而保证在多线程下也能正常执行

4. 反射机制

  1. 优点:运行期类型判断,动态加载,提高代码的灵活性。
  2. 缺点:性能瓶颈:反射相当于一系列的解释操作,通知JVM要做的事情,性能比直接的Java代码要慢很多。安全问题:让我们可以动态操作改变类的属性同时也增加了类的安全隐患。
  3. 反射的应用场景:
    例如模块化的开发,通过反射去调用对应的字节码;动态代理设计模式,也采用了反射机制;还有Spring等框架,也是利用反射机制实现的(反射是框架设计的灵魂)。

5. 泛型的实现

  • 泛型是通过 类型擦除 来实现的,编译器在编译时擦除了所有类型相关的信息,所以在运行时不存在任何类型相关的信息。也就是说,泛型只在编译期有效

6. 注解

  • AnnotationJava 5开始引入的新特性.Java 注解是附加在代码中的一些元信息,用于一些工具的编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在java.lang.annotation 包中。

7. 垃圾回收算法

    1. 标记清除算法:
      1.1 标记: 从根集合进行扫描,对存活的对象进行标记。
      1.2 清除: 对堆内存从头到尾进行线性遍历,回收不
      1.3 标记-清除算法的缺点是会造成很多内存碎片
    1. 复制算法: 将内存按容量按一定的比例分为对象面和空闲面。对象在对象面上创建。存活的对象被从对象面复制到空闲面。 年轻代很多垃圾收集器,都用这个算法回收
      2.1 优点
      解决了内存碎片化的问题。顺序分配内存,简单高效。适用于对象存活率低的场景。
      2.2 缺点
      对于对象存活率高的场景不适合。
      标记整理算法。分代收集算法
    1. 标记-整理算法?
      1. 标记: 从根集合进行扫描,对存活的对象进行标记。
      1. 清除: 移动所有存活的对象, 且按照内存地址次序依次排列,然后将末端内存地址以后的内存全部回收
      1. 避免了内存的不连续性。不用设置两块内存互换。
        适用于存活率高的场景。
    1. 分代收集算法:
      4.1 垃圾回收算法的组合拳。
      4.2 按照对象生命周期的不同划分区域以 采用不同的垃圾回收算法。
      4.3 目的: 提高JVM的 回收效率。

8. java有几种解决线程安全方法

    1. 同步代码块
 synchronized(同步监视器=对象){     
      //需要被同步的代码
   }

    1. 同步方法
      2.1 同步方法仍然涉及到同步监视器,只是不需要我们显式的声明。
      2.2 非静态的同步方法,同步监视器是:this.静态的同步方法,同步监视器是:当前类本身
    1. Lock锁 — JDK5.0新增

你可能感兴趣的:(Java 基础知识复习)