JAVA核心知识点最详细版(面试必备)

转载自https://mp.weixin.qq.com/s/iuGDNAKFFmhU8mxmaRFdpQ 



https://www.cnblogs.com/xiaoxi/p/6599843.html

  • 1. JVM、JRE及JDK的关系 **

  • 2. JAVA语言特点 **

  • 3. JAVA和C++的区别 **

  • 4. Java的基本数据类型  **

  • 5. 隐式(自动)类型转换和显示(强制)类型转换 **

  • 6. 自动装箱与拆箱 **

    • String(不是基本数据类型)

    • 7. String的不可变性  ***

    • 8. 字符型常量和字符串常量的区别 *

    • 9. 什么是字符串常量池?*

    • 10. String 类的常用方法都有哪些?**

    • 11. String和StringBuffer、StringBuilder的区别是什么?***

  • 12. switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上 *

  • 13. Java语言采用何种编码方案?有何特点?*

  • 14. 访问修饰符 **

  • 15. 运算符 *

    • 关键字

    • 16. static关键字 ***

    • 17. final 关键字 ***

    • 18. final finally finalize区别 ***

    • 19. this关键字 **

    • 20. super关键字 **

    • 21. this与super的区别 **

    • 22. break ,continue ,return 的区别及作用 **

  • 23. 面向对象和面向过程的区别 **

  • 24. 面向对象三大特性(封装、继承、多态) ***

  • 25. 面向对象五大基本原则是什么 **

  • 26. 抽象类和接口的对比 ***

  • 27. 在Java中定义一个不做事且没有参数的构造方法的作用 *

  • 28. 在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是 *

  • 29. 一个类的构造方法的作用是什么?若一个类没有声明构造方法,改程序能正确执行吗?为什么? *

  • 30. 构造方法有哪些特性? **

  • 31. 变量 **

  • 32. 内部类 **

  • 重写与重载 ***

    • 33. 重载和重写的区别

    • 34. 构造器(constructor)是否可被重写(override)

    • 35. 重载的方法能否根据返回类型进行区分?为什么?

  • 36. == 和 equals 的区别 ***

  • 37. hashCode 与 equals(为什么重写equals方法后,hashCode方法也必须重写) ***

  • 38. Java 中是值传递还是引用传递,还是两者共存 **

  • 39. IO流 *

  • 40. BIO,NIO,AIO 有什么区别? **

  • 41. 反射 ***

  • 42. JAVA异常 ***

  • 43. JAVA注解 **

  • 44. JAVA泛型 ***

  • 45. JAVA序列化 **

  • 46. 深拷贝与浅拷贝 ***

  • 47. 常见的Object方法 ***

往期内容:

1. JVM、JRE及JDK的关系 **

简单来说就是JDK是Java的开发工具,JRE是Java程序运行所需的环境,JVM是Java虚拟机.它们之间的关系是JDK包含JRE和JVM,JRE包含JVM.

2. JAVA语言特点 **

  • Java是一种面向对象的语言

  • Java通过Java虚拟机实现了平台无关性,一次编译,到处运行

  • 支持多线程

  • 支持网络编程

  • 具有较高的安全性和可靠性

3. JAVA和C++的区别 **

面试时记住前四个就行了

  • Java 通过虚拟机从而实现跨平台特性,但是 C++ 依赖于特定的平台。

  • Java 没有指针,它的引用可以理解为安全指针,而 C++ 具有和 C 一样的指针。

  • Java 支持自动垃圾回收,而 C++ 需要手动回收。

  • Java 不支持多重继承,只能通过实现多个接口来达到相同目的,而 C++ 支持多重继承。

  • Java 不支持操作符重载,虽然可以对两个 String 对象执行加法运算,但是这是语言内置支持的操作,不属于操 作符重载,而 C++ 可以。

  • Java 的 goto 是保留字,但是不可用,C++ 可以使用 goto。

4. Java的基本数据类型  **

注意String不是基本数据类型8中

类型关键字包装器类型占用内存(字节)(重要)取值范围默认值
字节型byteByte1-128(-2^7)  ~  127(2^7-1)0
短整型shortShort2-2^15  ~  2^15-10
整型intInteger4-2^31  ~  2^31-10
长整型longLong8-2^63   ~   2^63-10L
单精度浮点型floatFloat43.4e-45   ~   1.4e380.0F
双精度浮点型doubleDouble84.9e-324   ~   1.8e3080.0D
字符型charCharacter2 '\u0000'
布尔型booleanBoolean1true/flaseflase

5. 隐式(自动)类型转换和显示(强制)类型转换 **

  • 隐式(自动)类型转换:从存储范围小的类型到存储范围大的类型。byteshort(char)intlongfloatdouble

  • 显示(强制)类型转换:从存储范围大的类型到存储范围小的类型。doublefloatlongintshort(char)byte。该类类型转换很可能存在精度的损失。

看一个经典的代码

short s = 1;
s = s + 1;

这是会报错的,因为1是int型,s+1会自动转换为int型,将int型直接赋值给short型会报错。

做一下修改即可避免报错

short s = 1;
s = (short)(s + 1);

或这样写,因为s += 1会自动进行强制类型转换

short s = 1;
s += 1;

6. 自动装箱与拆箱 **

String(不是基本数据类型)

7. String的不可变性  ***

在 Java 8 中,String 内部使用 char 数组存储数据。并且被声明为final,因此它不可被继承。

public final class String implements java.io.Serializable, Comparable<String>, CharSequence { 
 private final char value[];
}

为什么String`要设计成不可变的呢(不可变性的好处):

1.可以缓存 hash 值()

因为 String 的hash值经常被使用,例如String 用做 HashMap 的 key。不可变的特性可以使得 hash值也不可变, 因此只需要进行一次计算。

2.常量池优化

String 对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的引用。

3.线程安全

String 不可变性天生具备线程安全,可以在多个线程中安全地使用。

8. 字符型常量和字符串常量的区别 *

  1. 形式上: 字符常量是单引号引起的一个字符 字符串常量是双引号引起的若干个字符

  2. 含义上: 字符常量相当于一个整形值(ASCII值),可以参加表达式运算 字符串常量代表一个地址值(该字符串在内存中存放位置)

  3. 占内存大小 字符常量占两个字节 字符串常量占若干个字节(至少一个字符结束标志)

9. 什么是字符串常量池?*

字符串常量池位于堆内存中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符串,在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。

 

当一个字符串调用 intern() 方法时,如果 String Pool 中已经存在一个字符串和该字符串值相等(使用 equals() 方法进行确定),那么就会返回 String Pool 中字符串的引用;否则,就会在 String Pool 中添加一个新的字符串,并返回这个新字符串的引用。

下面示例中,s1 和 s2 采用 new String() 的方式新建了两个不同字符串,而 s3 和 s4 是通过 s1.intern() 和 s2.intern() 方法取得同一个字符串引用。intern() 首先把 "aaa" 放到 String Pool 中,然后返回这个字符串引用,因此 s3 和 s4 引用的是同一个字符串。

String s1 = new String("aaa");
String s2 = new String("aaa");
System.out.println(s1 == s2);           // false
String s3 = s1.intern();
String s4 = s2.intern();
System.out.println(s3 == s4);           // true

#new String("abc")

使用这种方式一共会创建两个字符串对象(前提是 String Pool 中还没有 "abc" 字符串对象)。

  • "abc" 属于字符串字面量,因此编译时期会在 String Pool 中创建一个字符串对象,指向这个 "abc" 字符串字面量;
  • 而使用 new 的方式会在堆中创建一个字符串对象。

创建一个测试类,其 main 方法中使用这种方式来创建字符串对象。

public class NewStringTest {
    public static void main(String[] args) {
        String s = new String("abc");
    }
}

使用 javap -verbose 进行反编译,得到以下内容:

// ...
Constant pool:
// ...
   #2 = Class              #18            // java/lang/String
   #3 = String             #19            // abc
// ...
  #18 = Utf8               java/lang/String
  #19 = Utf8               abc
// ...

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=2, args_size=1
         0: new           #2                  // class java/lang/String
         3: dup
         4: ldc           #3                  // String abc
         6: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
         9: astore_1
// ...

在 Constant Pool 中,#19 存储这字符串字面量 "abc",#3 是 String Pool 的字符串对象,它指向 #19 这个字符串字面量。在 main 方法中,0: 行使用 new #2 在堆中创建一个字符串对象,并且使用 ldc #3 将 String Pool 中的字符串对象作为 String 构造函数的参数。

以下是 String 构造函数的源码,可以看到,在将一个字符串对象作为另一个字符串对象的构造函数参数时,并不会完全复制 value 数组内容,而是都会指向同一个 value 数组。

public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}



10. String 类的常用方法都有哪些?**

面试时一般不会问,但面试或笔试写字符串相关的算法题经常会涉及到,还是得背一背(以下大致是按使用频率优先级排序)

  • length():返回字符串长度

  • charAt():返回指定索引处的字符

  • substring():截取字符串

  • trim():去除字符串两端空白

  • split():分割字符串,返回一个分割后的字符串数组。

  • replace():字符串替换。

  • indexOf():返回指定字符的索引。

  • toLowerCase():将字符串转成小写字母。

  • toUpperCase():将字符串转成大写字符。

11. String和StringBuffer、StringBuilder的区别是什么?***

1.可变性

String不可变,StringBuilderStringBuffer是可变的

2.线程安全性

String由于是不可变的,所以线程安全。StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。 StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。

3.性能

StringBuilder > StringBuffer > String

为了方便记忆,总结如下

 是否可变是否安全性能
String不可变安全
StringBuilder可变不安全
StringBuffer可变安全较高

12. switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上 *

switch可以作用于char byte short int及它们对应的包装类型,switch不可作用于long double float boolean及他们的包装类型。在 JDK1.5之后可以作用于枚举类型,在JDK1.7之后可作用于String类型。

13. Java语言采用何种编码方案?有何特点?*

Java语言采用Unicode编码标准,它为每个字符制订了一个唯一的数值,因此在任何的语言,平台,程序都可以放心的使用。

14. 访问修饰符 **

在Java编程语言中有四种权限访问控制符,这四种访问权限的控制符能够控制类中成员的可见性。其中类有两种publicdefault。而方法和变量有 4 种:publicdefaultprotectedprivate

  • public : 对所有类可见。使用对象:类、接口、变量、方法

  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。注意:不能修饰类(外部类)

  • default : 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

  • private : 在同一类内可见。使用对象:变量、方法。注意:不能修饰类(外部类)

    修饰符当前类同包内子类(同包)其他包
    publicYYYY
    protectedYYYN
    defaultYYYN
    privateYNNN

15. 运算符 *

  • &&和&

    &&&都可以表示逻辑与,但他们是有区别的,共同点是他们两边的条件都成立的时候最终结果才是true;不同点是&&只要是第一个条件不成立为false,就不会再去判断第二个条件,最终结果直接为false,而&判断的是所有的条件。

  • ||和|

    |||都表示逻辑或,共同点是只要两个判断条件其中有一个成立最终的结果就是true,区别是||只要满足第一个条件,后面的条件就不再判断,而|要对所有的条件进行判断。

关键字

16. static关键字 ***

static关键字的主要用途就是方便在没有创建对象时调用方法和变量和优化程序性能

1.static变量(静态变量)

static修饰的变量被称为静态变量,也被称为类变量,可以直接通过类名来访问它。静态变量被所有的对象共享,在内存中只有一个副本,仅当在类初次加载时会被初始化,而非静态变量在创建对象的时候被初始化,并且存在多个副本,各个对象拥有的副本互不影响。

2.static方法(静态方法)

static方法不依赖于任何对象就可以进行访问,在static方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用,但是在非静态成员方法中是可以访问静态成员方法/变量的。

public class Main {
    public static String s1 = "s1";//静态变量
    String s2  = "s2";
    public void fun1(){
        System.out.println(s1);
        System.out.println(s2);
    }
    
    public static void fun2(){
        System.out.println(s1);
        System.out.println(s2);//此处报错,静态方法不能调用非静态变量
    }
}


 

12. ”static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?

“static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。

Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。



3.static代码块(静态代码块)

静态代码块的主要用途是可以用来优化程序的性能,因为它只会在类加载时加载一次,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。如果程序中有多个static块,在类初次被加载的时候,会按照static块的顺序来执行每个static块。

public class Main {
    static {
        System.out.println("hello,word");
    }
    public static void main(String[] args) {
        Main m = new Main();
    }
}

4.可以通过this访问静态成员变量吗?(可以)

this代表当前对象,可以访问静态变量,而静态方法中是不能访问非静态变量,也不能使用this引用。

5.初始化顺序

静态变量和静态语句块优先于实例变量和普通语句块,静态变量和静态语句块的初始化顺序取决于它们在代码中的顺序。如果存在继承关系的话,初始化顺序为父类中的静态变量和静态代码块——子类中的静态变量和静态代码块——父类中的实例变量和普通代码块——父类的构造函数——子类的实例变量和普通代码块——子类的构造函数

17. final 关键字 ***

final关键字主要用于修饰类,变量,方法。

  1. 类:被final修饰的类不可以被继承

  2. 方法:被final修饰的方法不可以被重写

  3. 变量:被final修饰的变量是基本类型,变量的数值不能改变;被修饰的变量是引用类型,变量便不能在引用其他对象,但是变量所引用的对象本身是可以改变的。

public class Main {
    int a = 1;
    public static void main(String[] args) {
        final int b = 1;
        b = 2;//报错
        final Main m = new Main();
        m.a = 2;//不报错,可以改变引用类型变量所指向的对象
    }
} 

18. final finally finalize区别 ***

  • final主要用于修饰类,变量,方法

  • finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块 中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。

  • finalize是一个属于Object类的一个方法,该方法一般由垃圾回收器来调用,当我们调用System.gc()方法的时候,由垃圾回收器调用finalize(),回收垃圾,但Java语言规范并不保证inalize方法会被及时地执行、而且根本不会保证它们会被执行。


    一个对象的 finalize 方法只会被调用一次,finalize 被调用不一定会立即回收该对象,所以有可能调用 finalize 后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会再次调用 finalize 了,进而产生问题,因此不推荐使用 finalize 方法。

19. this关键字 **

重点掌握前三种即可

1.this关键字可用来引用当前类的实例变量。主要用于形参与成员名字重名,用this来区分。

public Person(String name, int age) {
    this.name = name;
    this.age = age;
}

2.this关键字可用于调用当前类方法。

public class Main {
    public void fun1(){
        System.out.println("hello,word");
    }
    public void fun2(){
        this.fun1();//this可省略
    }

    public static void main(String[] args) {
        Main m = new Main();
        m.fun2();
    }
}

3.this()可以用来调用当前类的构造函数。(注意:this()一定要放在构造函数的第一行,否则编译不通过)

class Person{
    private String name;
    private int age;
    
    public Person() {
    }
 
    public Person(String name) {
        this.name = name;
    }
    public Person(String name, int age) {
        this(name);
        this.age = age;
    }
}

4.this关键字可作为调用方法中的参数传递。

5.this关键字可作为参数在构造函数调用中传递。

6.this关键字可用于从方法返回当前类的实例。super

20. super关键字 **

1.super可以用来引用直接父类的实例变量。和this类似,主要用于区分父类和子类中相同的字段

2.super可以用来调用直接父类构造函数。(注意:super()一定要放在构造函数的第一行,否则编译不通过)

3.super可以用来调用直接父类方法。

public class Main {
    public static void main(String[] args) {
        Child child = new Child("Father","Child");
        child.test();
    }
}

class Father{
    protected String name;

    public Father(String name) {
        this.name = name;
    }

    public void Say(){
        System.out.println("hello,child");
    }

}

class Child extends Father{
    private String name;

    public Child(String name1, String name2) {
        super(name1);      //调用直接父类构造函数
        this.name = name2;
    }

    public void test(){
        System.out.println(this.name);
        System.out.println(super.name);  //引用直接父类的实例变量
        super.Say();      //调用直接父类方法
    }
}

21. this与super的区别 **

  • 相同点:

    1. super()this()都必须在构造函数的第一行进行调用,否则就是错误的

    2. this()super()都指的是对象,所以,均不可以在static环境中使用。

  • 不同点:

    1. super()主要是对父类构造函数的调用,this()是对重载构造函数的调用

    2. super()主要是在继承了父类的子类的构造函数中使用,是在不同类中的使用;this()主要是在同一类的不同构造函数中的使用

22. break ,continue ,return 的区别及作用 **

23. 面向对象和面向过程的区别 **

  • 面向过程

    优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源。

    缺点:没有面向对象易维护、易复用、易扩展

  • 面向对象

    优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护

    缺点:性能比面向过程低

 

  •  

    public class Main {
        public static void main(String[] args) {
              Person person = new Student(); //向上转型
              person.run();
        }
    }
    
    class Person {
        public void run() {
            System.out.println("Person");
        }
    }
    
    class Student extends Person {   //继承
        @Override 
        public void run() {         //重载
            System.out.println("Student");
        }
    }
    

    运行结果为

    Student
    

     

25. 面向对象五大基本原则是什么 **

  • 单一职责原则(Single-Resposibility Principle)

    **一个类,最好只做一件事,只有一个引起它的变化。**单一职责原则可以看做是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。

  • 开放封闭原则(Open-Closed principle)

    软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭的。

  • 里氏替换原则 (Liskov-Substituion Principle)

    **子类必须能够替换其基类。**这一思想体现为对继承机制的约束规范,只有子类能够替换基类时,才能保证系统在运行期内识别子类,这是保证继承复用的基础。在父类和子类的具体行为中,必须严格把握继承层次中的关系和特征,将基类替换为子类,程序的行为不会发生任何变化。同时,这一约束反过来则是不成立的,子类可以替换基类,但是基类不一定能替换子类。

  • 依赖倒置原则(Dependecy-Inversion Principle)

    **依赖于抽象。**具体而言就是高层模块不依赖于底层模块,二者都同依赖于抽象;抽象不依赖于具体,具体依赖于抽象。

  • 接口隔离原则(Interface-Segregation Principle)

    使用多个小的专门的接口,而不要使用一个大的总接口。

26. 抽象类和接口的对比 ***

在Java语言中,abstract classinterface是支持抽象类定义的两种机制。抽象类:用来捕捉子类的通用特性的。接口:抽象方法的集合。

相同点:

  • 接口和抽象类都不能实例化

  • 都包含抽象方法,其子类都必须覆写这些抽象方法

不同点:

类型抽象类接口
定义abstract classInterface
实现extends(需要提供抽象类中所有声明的方法的实现)implements(需要提供接口中所有声明的方法的实现)
继承抽象类可以继承一个类和实现多个接口;子类只可以继承一个抽象类接口只可以继承接口(一个或多个);子类可以实现多个接口
访问修饰符抽象方法可以有public、protected和default这些修饰符接口方法默认修饰符是public。你不可以使用其它修饰符
构造器抽象类可以有构造器接口不能有构造器
字段声明抽象类的字段声明可以是任意的接口的字段默认都是 static 和 final 的

27. 在Java中定义一个不做事且没有参数的构造方法的作用 *

Java程序存在继承,在执行子类的构造方法时,如果没有用super()来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。如果父类只定义了有参数的构造函数,而子类的构造函数没有用super调用父类那个特定的构造函数,就会出错。

28. 在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是 *

帮助子类做初始化工作。

29. 一个类的构造方法的作用是什么?若一个类没有声明构造方法,改程序能正确执行吗?为什么? *

主要作用是完成对类对象的初始化工作。可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。

30. 构造方法有哪些特性? **

  • 方法名称和类同名

  • 不用定义返回值类型

  • 不可以写retrun语句

  • 构造方法可以被重载

31. 变量 **

  • 类变量:独立于方法之外的变量,用static修饰。

  • 实例变量:独立于方法之外的变量,不过没有 static 修饰。

  • 局部变量:类的方法中的变量。

  • 成员变量:成员变量又称全局变量,可分为类变量和实例变量,有static修饰为类变量,没有static修饰为实例变量。

     类变量实例变量局部变量
    定义位置类中,方法外类中,方法外方法中
    初始值有默认初始值有默认初始值无默认初始值
    存储位置方法区
    生命周期类何时被加载和卸载实例何时被创建及销毁方法何时被调用及结束调用

32. 内部类 **

内部类包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类

  • 成员内部类

    1.成员内部类定义为位于另一个类的内部,成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。

    class Outer{
        private double a = 0;
        public static int b =1;
        public Outer(double a) {
            this.a = a;
        }
    
        class Inner {     //内部类
            public void fun() {
                System.out.println(a);
                System.out.println(b);
            }
        }
    }
    

    2.当成员内部类拥有和外部类同名的成员变量或者方法时,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:外部类.this.成员变量

    3.在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问。

    4.成员内部类是依附外部类而存在的,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象。创建成员内部类对象的一般方式如下:

    class Outter{
        private double a = 0;
        public static int b =1;
        public Outter(){}
        public Outter(double a) {
            this.a = a;
            Inner inner = new Inner();
            inner.fun();     //调用内部类的方法
        }
    
    
        class Inner {     //内部类
            int b = 2;
            public void fun() {
                System.out.println(a);
                System.out.println(b);            //访问内部类的b
                System.out.println(Outter.this.b);//访问外部类的b
            }
        }
    }
    public class Main{
        public static void main(String[] args) {
            Outter outter = new Outter();
            Outter.Inner inner = outter.new Inner(); //创建内部类的对象
        }
    }
    
  • 局部内部类

    局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。

    class Outter {
    
        private int outter_a = 1;
        private static int static_b = 2;
    
        public void test1(){
            int inner_c =3;
            class Inner {
                private void fun(){
                    System.out.println(outter_a);
                    System.out.println(static_b);
                    System.out.println(inner_c);
                }
            }
            Inner  inner = new Inner(); //创建局部内部类
            inner.fun();
        }
        public static void test2(){
            int inner_d =3;
            class Inner {
                private void fun(){
                     System.out.println(outter_a); //编译错误,定义在静态方法中的局部类不可以访问外部类的实例变量
                    System.out.println(static_b);
                    System.out.println(inner_d);
                }
            }
            Inner  inner = new Inner();
            inner.fun();
        }
    }
    
  • 匿名内部类

    匿名内部类只没有名字的内部类,在日常开发中使用较多。使用匿名内部类的前提条件:必须继承一个父类或实现一个接口。

    interface Person {
        public void fun();
    }
    class Demo {
        public static void main(String[] args) {
             new Person() {
                public void fun() {
                    System.out.println("hello,word");
                }
            }.fun();
        }
    }
    
  • 静态内部类

    静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。

    class Outter {
        int a = 1;
        static int b = 2;
        public Outter() {
    
        }
    
        static class Inner {
            public Inner() {
                System.out.println(a);//报错,静态内部类不能访问非静态变量
                System.out.println(b);
            }
        }
    
    }
    public class Main{
        public static void main(String[] args) {
            Outter.Inner inner = new Outter.Inner();
        }
    }
    
    
  • 内部类的优点:

    1. 内部类不为同一包的其他类所见,具有很好的封装性;

    2. 匿名内部类可以很方便的定义回调。

    3. 每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。

    4. 内部类有效实现了“多重继承”,优化 java 单继承的缺陷。

  • 局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上final

    public class Main {
        public static void main(String[] args)  {
             
        }
         
        public void fun(final int b) {
            final int a = 10;
            new Thread(){
                public void run() {
                    System.out.println(a);
                    System.out.println(b);
                };
            }.start();
        }
    }
    

    对于变量a可以从生命周期的角度理解,局部变量直接存储在栈中,当方法执行结束后,非final的局部变量就被销毁,而局部内部类对局部变量的引用依然存在,如果局部内部类要调用没有final修饰的局部变量时,就会造成生命周期不一致出错。

    对于变量b,其实是将fun方法中的变量b以参数的形式对匿名内部类中的拷贝(变量b的拷贝)进行赋值初始化。在run方法中访问的变量b根本就不是test方法中的局部变量b,而是一个拷贝值,所以不存在生命周期不一致的问题,但如果在run方法中修改变量b的值会导致数据不一致,所以需要加final修饰。

重写与重载 ***

33. 重载和重写的区别

 

使用 @Override 注解,可以让编译器帮忙检查是否满足上面的三个限制条件。

下面的示例中,SubClass 为 SuperClass 的子类,SubClass 重写了 SuperClass 的 func() 方法。其中:

 

Java多态的实现原理可看这篇文章:https://my.oschina.net/u/4432600/blog/4535042

  • 重载:发生在同一个类中,方法名相同参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和访问修饰符无关,即重载的方法不能根据返回类型进行区分。

  • 重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类(里氏代换原则);如果父类方法访问修饰符为private则子类中就不是重写。
     

    1. 重写(Override)

    存在于继承体系中,指子类实现了一个与父类在方法声明上完全相同的一个方法。

    为了满足里式替换原则,重写有以下三个限制:

  • 子类方法的访问权限必须大于等于父类方法;
  • 子类方法的返回类型必须是父类方法返回类型或为其子类型。
  • 子类方法抛出的异常类型必须是父类抛出异常类型或为其子类型。
  • 子类方法访问权限为 public,大于父类的 protected。
  • 子类的返回类型为 ArrayList<Integer>,是父类返回类型 List<Integer> 的子类。
  • 子类抛出的异常类型为 Exception,是父类抛出异常 Throwable 的子类。
  • 子类重写方法使用 @Override 注解,从而让编译器自动检查是否满足限制条件。

     

    本质上多态分两种:

    1、编译时多态(又称静态多态)

    2、运行时多态(又称动态多态)

    重载(overload)就是编译时多态的一个例子,编译时多态在编译时就已经确定,运行的时候调用的是确定的方法。

    我们通常所说的多态指的都是运行时多态,也就是编译时不确定究竟调用哪个具体方法,一直延迟到运行时才能确定。这也是为什么有时候多态方法又被称为延迟方法的原因。

    Java实现多态有 3 个必要条件:继承、重写和向上转型。只有满足这 3 个条件,开发人员才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而执行不同的行为。

  • 继承:在多态中必须存在有继承关系的子类和父类。
  • 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
  • 向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才既能可以调用父类的方法,又能调用子类的方法。

34. 构造器(constructor)是否可被重写(override)

构造器可以被重载,不能被重写

构造器不能被继承,因此不能被重写,但可以被重载。每一个类必须有自己的构造函数,负责构造自己这部分的构造。子类不会覆盖父类的构造函数,相反必须一开始调用父类的构造函数。

35. 重载的方法能否根据返回类型进行区分?为什么?

不能,因为调用时不能指定类型信息,编译器不知道你要调用哪个函数。

36. == 和 equals 的区别 ***

  • ==

    对于基本数据类型,==比较的是值;对于引用数据类型,==比较的是内存地址。

  • eauals

    对于没有重写equals方法的类,equals方法和==作用类似;对于重写过equals方法的类,equals比较的是值。

37. hashCode 与 equals(为什么重写equals方法后,hashCode方法也必须重写) ***

  • equals

    先看下String类中重写的equals方法。

        public boolean equals(Object anObject) {
            if (this == anObject) {
                return true;
            }
            if (anObject instanceof String) {
                String anotherString = (String)anObject;
                int n = value.length;
                if (n == anotherString.value.length) {
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) {
                        if (v1[i] != v2[i])
                            return false;
                        i++;
                    }
                    return true;
                }
            }
            return false;
        }
    

    从源码中可以看到:

    1. equals方法首先比较的是内存地址,如果内存地址相同,直接返回true;如果内存地址不同,再比较对象的类型,类型不同直接返回false;类型相同,再比较值是否相同;值相同返回true,值不同返回false。总结一下,equals会比较内存地址、对象类型、以及值,内存地址相同,equals一定返回true;对象类型和值相同,equals方法一定返回true

    2. 如果没有重写equals方法,那么equals==的作用相同,比较的是对象的地址值。

  • hashCode

    hashCode方法返回对象的散列码,返回值是int类型的散列码。散列码的作用是确定该对象在哈希表中的索引位置。

    关于hashCode有一些约定:

    1. 两个对象相等,则hashCode一定相同。

    2. 两个对象有相同的hashCode值,它们不一定相等。

    3. hashCode()方法默认是对堆上的对象产生独特值,如果没有重写hashCode()方法,则该类的两个对象的hashCode值肯定不同

  • 为什么重写equals方法后,hashCode方法也必须重写

    1. 根据规定,两个对象相等,hashCode值也许相同,所以重写equals方法后,hashCode方法也必须重写(面试官肯定不是想听这个答案)

    2. hashCode在具有哈希机制的集合中起着非常关键的作用,比如HashMapHashSet等。以HashSet为例,HashSet的特点是存储元素时无序且唯一,在向HashSet中添加对象时,首先会计算对象的HashCode值来确定对象的存储位置,如果该位置没有其他对象,直接将该对象添加到该位置;如果该存储位置有存储其他对象(新添加的对象和该存储位置的对象的HashCode值相同),调用equals方法判断两个对象是否相同,如果相同,则添加对象失败,如果不相同,则会将该对象重新散列到其他位置。所以重写equals方法后,hashCode方法不重写的话,会导致所有对象的HashCode值都不相同,都能添加成功,那么HashSet中会出现很多重复元素,HashMap也是同理(因为HashSet的底层就是通过HashMap实现的),会出现大量相同的KeyHashMap中的key是唯一的,但不同的key可以对应相同的value)。所以重写equals方法后,hashCode方法也必须重写。同时因为两个对象的hashCode值不同,则它们一定不相等,所以先计算对象的hashCode值可以在一定程度上判断两个对象是否相等,提高了集合的效率。总结一下,一共两点:第一,在HashSet等集合中,不重写hashCode方法会导致其功能出现问题;第二,可以提高集合效率。

38. Java 中是值传递还是引用传递,还是两者共存 **

这是一个很容易搞混又很难解释清楚的问题,先说结论,Java中只有值传递

先看这样一段代码

public class Main{
    public static void main(String[] args) {
        int a = 1;
        printValue(a);
        System.out.println("a:" + a);
    }
    public static void printValue(int b){
        b = 2;
        System.out.println("b:"+ b);
    }
}

输出

b:2
a:1

可以看到将a的值传到printValue方法中,并将其值改为2。但方法调用结束后,a的值还是1,并未发生改变,所以这种情况下为值传递。

再看这段代码

public class Main{
    public static void main(String[] args) {
        Preson p = new Preson();
        p.name = "zhangsan";
        printValue(p);
        System.out.println("p.name: " + p.name);
    }
    public static void printValue(Preson q){
        q.name = "lisi";
        System.out.println("q.name: "+ q.name);
    }
}
class Preson{
    public String name;
}

输出结果

q.name: lisi
p.name: lisi

在将p传入printValue方法后,方法调用结束,pname属性竟然被改变了!所以得出结论,参数为基本类型为值传递,参数为引用类型为时为引用传递。这个结论是错误的,下面来看看判断是值传递还是值传递的关键是什么,先看定义

  • 值传递:是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

  • 引用传递:是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

从定义中可以明显看出,区分是值传递还是引用传递主要是看向方法中传递的是实际参数的副本还是实际参数的地址。上面第一个例子很明显是值传递,其实第二个例子中向printValue方法中传递的是一个引用的副本,只是这个副本引用和原始的引用指向的同一个对象,所以副本引用修改过对象属性后,通过原始引用查看对象属性肯定也是被修改过的。换句话说,printValue方法中修改的是副本引用指向的对象的属性,不是引用本身,如果修改的是引用本身,那么原始引用肯定不受影响。看下面这个例子

public class Main{
    public static void main(String[] args) {
        Preson p = new Preson();
        p.name = "zhangsan";
        printValue(p);
        System.out.println("p.name: " + p.name);
    }
    public static void printValue(Preson q){
        q = new Preson();
        q.name = "lisi";
        System.out.println("q.name: "+ q.name);
    }
}
class Preson{
    public String name;
}

输出结果

q.name: lisi
p.name: zhangsan

可以看到将p传入printValue方法后,printValue方法调用结束后,p的属性name没有改变,这是因为printValue方法中并没有改变副本引用q所指向的对象,而是改变了副本引用q本身,将副本引用q指向了另一个对象并对这个对象的属性进行修改,所以原始引用p所指向的对象不受影响。所以证明Java中只存在值传递。

39. IO流 *

Java IO流主要可以分为输入流和输出流。按照照操作单元划分,可以划分为字节流和字符流。按照流的角色划分为节点流和处理流。

Java I0流的40多个类都是从4个抽象类基类中派生出来的。

  • InputStream:字节输入流

  • Reader:字符输入流

  • OutputStream:字节输出流

  • Writer:字符输出流

40. BIO,NIO,AIO 有什么区别? **

  • BIO (Blocking I/O):服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制来改善。BIO方式适用于连接数目比较小且固定的架构,这种方式对服务端资源要求比较高,并发局限于应用中,在jdk1.4以前是唯一的io

  • NIO (New I/O):服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有IO请求时才启动一个线程进行处理。NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,jdk1,4开始支持

  • AIO (Asynchronous I/O):服务器实现模式为一个有效请求一个线程,客户端的IO请求都是由操作系统先完成了再通知服务器用其启动线程进行处理。AIO方式适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,jdk1.7开始支持。

    这些概念看着比较枯燥,可以从这个经典的烧开水的例子去理解

    BIO :来到厨房,开始烧水,并坐在水壶面前一直等着水烧开。

    NIO:来到厨房,开始烧水,但是我们不一直坐在水壶前面等,而是做些其他事,然后每隔几分钟到厨房看一下水有没有烧开。

    AIO:来到厨房,开始烧水,我们不一直坐在水壶前面等,而是在水壶上面装个开关,水烧开之后它会通知我。

41. 反射 ***

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

Java获取Class对象的三种方式

class Person {
    public String name = "zhangsan";
    public Person() {
    }
}
public class Main{
    public static void main(String[] args) throws ClassNotFoundException {
 //方式1
     Person p1 = new Person();
     Class c1 = p1.getClass();
     //方式2
    Class c2 = Person.class;
    //方式3可能会抛出ClassNotFoundException异常
    Class c3 = Class.forName("com.company");
    }
}

因为在一个类在 JVM 中只会有一个 Class 实例,所以对c1c2c3进行equals比较时返回的都是true

反射优缺点:

  • 优点:运行期类型的判断,动态加载类,提高代码灵活度。

  • 缺点:性能比直接的java代码要慢很多。

反射应用场景:

  1. Java的很多框架都用到了反射,例如Spring中的xml的配置模式等

  2. 动态代理设计模式也采用了反射机制

42. JAVA异常 ***

异常主要分为ErrorException两种

  • Error:Error类以及他的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理。

  • EXception:Exception以及他的子类,代表程序运行时发送的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。

异常框图

图片

除了以上的分类,异常还能分为非检查异常和检查异常

  • 非检查异常(unckecked exception):**该类异常包括运行时异常(RuntimeException及其子类)和错误(Error)。**编译器不会进行检查并且不要求必须处理的异常,也就说当程序中出现此类异常时,即使我们没有try-catch捕获它,也没有使用throws抛出该异常,编译也会正常通过。因为这样的异常发生的原因很可能是代码写的有问题。

  • 检查异常(checked exception):**除了Error和 RuntimeException的其它异常。**这是编译器要求必须处理的异常。这样的异常一般是由程序的运行环境导致的。因为程序可能被运行在各种未知的环境下,而程序员无法干预用户如何使用他编写的程序,所以必须处理这些异常。

下面来看下try{}catch(){}finally{}return之间的“恩恩怨怨”,这里有些乱,面试时问的也不是很多,实在记不住就算啦。还是先看代码猜结果。

public class Main{
    public static void main(String[] args) {
        int a = test1();
        System.out.println(a);
        int b = test2();
        System.out.println(b);
        int c = test3();
        System.out.println(c);
        int d = test4();
        System.out.println(d);
        int e = test5();
        System.out.println(e);
    }
    public static int test1(){
        int a = 1;
        try{
            a = 2;
            return a;
        }catch(Exception e){
            System.out.println("hello,test1");
            a = 3;
        }finally{
            a = 4;
        }
        return a;
    }
    //输出 2
    
    
    public static int test2(){
        int a = 1;
        try{
            a = 2;
            return a;
        }catch(Exception e){
            System.out.println("hello,test2");
            a = 3;
            return a;
        }finally{
            a = 4;
        }
    }
    //输出 2
    
    
    public static int test3(){
        int a = 1;
        try{
            a = 2/0;
            return a;
        }catch(Exception e){
            System.out.println("hello,test3");
            a = 3;
        }finally{
            a = 4;
        }
        return a;
    }
    //输出 hello,test3 
    // 4
    
    
    public static int test4(){
        int a = 1;
        try{
            a = 2/0;
            return a;
        }catch(Exception e){
            System.out.println("hello,test4");
            a = 3;
            return a;
        }finally{
            a = 4;
        }
    }
    //输出 hello,test4
    // 3
    
    public static int test5(){
        int a = 1;
        try{
            a = 2/0;
            return a;
        }catch(Exception e){
            a = 3;
            return a;
        }finally{
            a = 4;
            return a;
        }
    }
    
    //输出 4
}

如果没有仔细的研究过,应该好多会猜错,下面总结下规律。

  1. 从前三个例子可以看出如果try{}中的代码没有异常,catch(){}代码块中的代码不会执行。所以如果try{}catch(){}都含有return时,无异常执行try{}中的return,存在异常执行catch(){}return

  2. 不管任何情况,就算try{}catch(){}中含有returnfinally{}中的代码一定会执行,那么为什么test1test2test3中的结果不是4呢,因为虽然finally是在return后面的表达式运算之后执行的,但此时并没有返回运算之后的值,而是把值保存起来,不管finally对该值做任何的改变,返回的值都不会改变,依然返回保存起来的值。也就是说方法的返回值是在finally运算之前就确定了的。

  3. 如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。这个不理解可以看看上面提到的Java的值传递的问题。

  4. 如果finally{}中含有return,会导致程序提前退出,不在执行try{}catch(){}中的return。所以test5返回的值是4。

最后总计一下try{}catch(){}finally{}的执行顺序。

 

1

2

3

4

5

6

7

8

9

10

11

12

13

public static void function() throws NumberFormatException{

        String s = "abc";

        System.out.println(Double.parseDouble(s));

    }

 

    public static void main(String[] args) {

        try {

            function();

        } catch (NumberFormatException e) {

            System.err.println("非数据类型不能转换。");

            //e.printStackTrace();

        }

}

举例如下:

throw 关键字

复制代码

1

2

3

4

5

6

7

8

9

public static void main(String[] args) {

        String s = "abc";

        if(s.equals("abc")) {

            throw new NumberFormatException();

        } else {

            System.out.println(s);

        }

        //function();

}

throws 关键字

复制代码

  1. 先执行try中的语句,包括return后面的表达式;

  2. 有异常时,执行catch中的语句,包括return后面的表达式,无异常跳过catch语句;

  3. 然后执行finally中的语句,如果finally里面有return语句,执行return语句,程序结束;

  4. finally{}中没有return时,无异常执行try中的return,如果有异常时则执行catch中的return。前两步执行的return只是确定返回的值,程序并未结束,finally{}执行之后,最后将前两步确定的return的返回值返回。

    非受检查异常和受检查异常之间的区别:是否强制要求调用者必须处理此异常,如果强制要求调用者必须进行处理,那么就使用受检查异常,否则就选择非受检查异常。

    作者:程序员库森
    链接:https://www.nowcoder.com/discuss/601272
    来源:牛客网
     

    38. throw 和 throws 的区别是什么?

    Java 中的异常处理除了包括捕获异常和处理异常之外,还包括声明异常和拋出异常,可以通过 throws 关键字在方法上声明该方法要拋出的异常,或者在方法内部通过 throw 拋出异常对象。

    throws 关键字和 throw 关键字在使用上的几点区别如下:

  5. throw 关键字用在方法内部,只能用于抛出一种异常,用来抛出方法或代码块中的异常,受查异常和非受查异常都可以被抛出。
  6. throws 关键字用在方法声明上,可以抛出多个异常,用来标识该方法可能抛出的异常列表。一个方法用 throws 标识了可能抛出的异常列表,调用该方法的方法中必须包含可处理异常的代码,否则也要在方法签名中用 throws 关键字声明相应的异常。



  7. 作者:程序员库森
    链接:https://www.nowcoder.com/discuss/601272
    来源:牛客网
     

    43. JVM 是如何处理异常的?

    在一个方法中如果发生异常,这个方***创建一个异常对象,并转交给 JVM,该异常对象包含异常名称,异常描述以及异常发生时应用程序的状态。创建异常对象并转交给 JVM 的过程称为抛出异常。可能有一系列的方法调用,最终才进入抛出异常的方法,这一系列方法调用的有序列表叫做调用栈。

    JVM 会顺着调用栈去查找看是否有可以处理异常的代码,如果有,则调用异常处理代码。当 JVM 发现可以处理异常的代码时,会把发生的异常传递给它。如果 JVM 没有找到可以处理该异常的代码块,JVM 就会将该异常转交给默认的异常处理器(默认处理器为 JVM 的一部分),默认异常处理器打印出异常信息并终止应用程序。
    想要深入了解的小伙伴可以看这篇文章:https://www.cnblogs.com/qdhxhz/p/10765839.html

43. JAVA注解 **

面试问的不多,但是在使用框架开发时会经常使用,但东西太多了,这里只是简单介绍下概念。

Annotation注解可以看成是java中的一种标记记号,用来给java中的类,成员,方法,参数等任何程序元素添加一些额外的说明信息,同时不改变程序语义。注解可以分为三类:基本注解,元注解,自定义注解

  • 标准注解

    1. @Deprecated:该注解用来说明程序中的某个元素(类,方法,成员变量等)已经不再使用,如果使用的话的编译器会给出警告。

    2. @SuppressWarnings(value=“”):用来抑制各种可能出现的警告。

    3. @Override:用来说明子类方法覆盖了父类的方法,保护覆盖方法的正确使用

  • 元注解(元注解也称为元数据注解,是对注解进行标注的注解,元注解更像是一种对注解的规范说明,用来对定义的注解进行行为的限定。例如说明注解的生存周期,注解的作用范围等)

    1. @Target(value=“ ”):该注解是用来限制注解的使用范围的,即该注解可以用于哪些程序元素。

    2. @Retention(value=“ ”):用于说明注解的生存周期

    3. @Documnent:用来说明指定被修饰的注解可以被javadoc.exe工具提取进入文档中,所有使用了该注解进行标注的类在生成API文档时都在包含该注解的说明。

    4. @Inherited:用来说明使用了该注解的父类,其子类会自动继承该注解。

    5. @Repeatable:java1.8新出的元注解,如果需要在给程序元素使用相同类型的注解,则需将该注解标注上。

  • 自定义注解:用@Interface来声明注解。

44. JAVA泛型 ***

Java 泛型是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

  • 泛型擦除(这是面试考察泛型时经常问到的问题)

    Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。看下面代码

    public class Main{
        public static void main(String[] args) {
            ArrayList<Integer> arrayList1 = new ArrayList<>();
            ArrayList<String> arrayList2 = new ArrayList<>();
    
            System.out.println(arrayList1.getClass() == arrayList2.getClass());
        }
    }
    

    输出结果

    true
    

    可以看到ArrayList<Integer>ArrayList<String>的原始类型是相同,在编译成字节码文件后都会变成List,JVM看到的只有List,看不到泛型信息,这就是泛型的类型擦除。再看下面这段代码

    public class Main{
        public static void main(String[] args) throws Exception {
            ArrayList<Integer> arrayList = new ArrayList<>();
            arrayList.add(1);
            arrayList.getClass().getMethod("add", Object.class).invoke(arrayList, "a");
            System.out.println(arrayList.get(0));
            System.out.println(arrayList.get(1));
        }
    }
    

    输出

    1
    a
    

    可以看到通过反射进行add操作,ArrayList<Integer>竟然可以存储字符串,这是因为在反射就是在运行期调用的add方法,在运行期泛型信息已经被擦除。

  • 既然存在类型擦除,那么Java是如何保证在ArrayList<Integer>添加字符串会报错呢?

    Java编译器是通过先检查代码中泛型的类型,然后在进行类型擦除,再进行编译。

45. JAVA序列化 **

  • 序列化:将对象写入到IO流中

  • 反序列化:从IO流中恢复对象

  • 序列化的意义:将Java对象转换成字节序列,这些字节序列更加便于通过网络传输或存储在磁盘上,在需要时可以通过反序列化恢复成原来的对象。

  • 实现方式:

    1. 实现Serializable接口

    2. 实现Externalizable接口

  • 序列化的注意事项:

    1. 对象的类名、实例变量会被序列化;方法、类变量、transient实例变量都不会被序列化。

    2. 某个变量不被序列化,可以使用transient修饰。

    3. 序列化对象的引用类型成员变量,也必须是可序列化的,否则,会报错。

    4. 反序列化时必须有序列化对象的class文件。

46. 深拷贝与浅拷贝 ***

  • 深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,两个引用指向两个对象,但对象内容相同。

  • 浅拷贝:对基本数据类型进行值传递,对引用数据类型复制一个引用指向原始引用的对象,就是复制的引用和原始引用指向同一个对象。

    具体区别看下图

    图片

  • 深拷贝的实现方式

    1. 重载clone方法

       public class Main{
          public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, CloneNotSupportedException {
              Address s = new Address("天津");
              Person p = new Person("张三", 23, s);
              System.out.println("克隆前的地址:" + p.getAddress().getName());
              Person cloneP = (Person) p.clone();
              cloneP.getAddress().setName("北京");
              System.out.println("克隆后的地址:" + cloneP.getAddress().getName());
          }
      }
      
      class Address implements Cloneable {
          private String city;
          public Address(String name){
              this.city = name;
      }
          @Override
          protected Object clone() throws CloneNotSupportedException {
                  return super.clone();
          }
          public String getName() {
              return city;
      
          }
          public void setName(String name) {
              this.city = name;
      
          }
      }
      class Person implements Cloneable{
          private String name;
          private int age;
          private Address address;
          public Person(String name, int age, Address address){
              this.name = name;
              this.age = age;
              this.address = address;
      
          }
          @Override
          public Object clone() throws CloneNotSupportedException {
                Person  person = (Person) super.clone();
                person.address = (Address)address.clone();
              return person;
          }
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public int getAge() {
              return age;
          }
          public void setAge(int age) {
              this.age = age;
          }
          public Address getAddress() {
              return address;
          }
          public void setAddress(Address address) {
              this.address = address;
          }
      }
      

      输出

      克隆前的地址:天津
      克隆后的地址:北京
      

      其实就是Person类和Address类都要重写clone方法,这里面需要注意的一点是super.clone()为浅克隆,所以在在Person类中重写clone方法时,address对象需要调用address.clone()重新赋值,因为address类型为引用类型。

    2. 序列化

      public class Main{
          public static void main(String[] args) throws IOException, ClassNotFoundException {
              Address s = new Address("天津");
              Person p = new Person("张三", 23, s);
              System.out.println("克隆前的地址:" + p.getAddress().getName());
              Person cloneP = (Person) p.deepClone();
              cloneP.getAddress().setName("北京");
              System.out.println("克隆后的地址:" + cloneP.getAddress().getName());
          }
      }
      
      class Address implements Serializable{
          private String city;
          public Address(String name){
              this.city = name;
          }
      
          public String getName() {
              return city;
      
          }
          public void setName(String name) {
              this.city = name;
      
          }
      }
      class Person implements Serializable{
          private String name;
          private int age;
          private Address address;
          public Person(String name, int age, Address address){
              this.name = name;
              this.age = age;
              this.address = address;
      
          }
      
          public Object deepClone() throws IOException, ClassNotFoundException {        
              ByteArrayOutputStream bos = new ByteArrayOutputStream();
              ObjectOutputStream oos = new ObjectOutputStream(bos);
              oos.writeObject(this);        
              ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
              ObjectInputStream ois = new ObjectInputStream(bis);
              return ois.readObject();
          }
      
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public int getAge() {
              return age;
          }
          public void setAge(int age) {
              this.age = age;
          }
          public Address getAddress() {
              return address;
          }
          public void setAddress(Address address) {
              this.address = address;
          }
      }
      

      输出

      克隆前的地址:天津
      克隆后的地址:北京
      

47. 常见的Object方法 ***

这些方法都很重要,面试经常会问到,要结合其他知识将这些方法理解透彻

  • Object clone():创建与该对象的类相同的新对象

  • boolean equals(Object):比较两对象是否相等

  • void finalize():当垃圾回收器确定不存在对该对象的更多引用时,对象垃圾回收器调用该方法

  • Class getClass():返回一个对象运行时的实例类

  • int hashCode():返回该对象的散列码值

  • void notify():唤醒等待在该对象的监视器上的一个线程

  • void notifyAll():唤醒等待在该对象的监视器上的全部线程

  • String toString():返回该对象的字符串表示

  • void wait():在其他线程调用此对象的 notify() 方法或 notifyAll()方法前,导致当前线程等待


 

26. java 创建对象有哪几种方式?

java中提供了以下四种创建对象的方式:

  • new创建新对象
  • 通过反射机制
  • 采用clone机制
  • 通过序列化机制

前两者都需要显式地调用构造方法。对于clone机制,需要注意浅拷贝和深拷贝的区别,对于序列化机制需要明确其实现原理,在java中序列化可以通过实现Externalizable或者Serializable来实现。

 

27. 什么是不可变对象?好处是什么?

不可变对象指对象一旦被创建,状态就不能再改变,任何修改都会创建一个新的对象,如 String、Integer及其它包装类.不可变对象最大的好处是线程安全.

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ....................................................................................................................................................... 19 2.1. 线程 ...................................................................................................................................................... 20 2.2. JVM 内存区域 ..................................................................................................................................... 21 2.2.1. 程序计数器(线程私有) ................................................................................................................ 22 2.2.2. 虚拟机栈(线程私有) .................................................................................................................... 22 2.2.3. 本地方法区(线程私有) ................................................................................................................ 23 2.2.4. 堆(Heap-线程共享)-运行时数据区 ...................................................................................... 23 2.2.5. 方法区/永久代(线程共享) ..................................................................................................... 23 2.3. JVM 运行时内存 ................................................................................................................................. 24 2.3.1. 新生代 .......................................................................................................................................... 24 2.3.1.1. 2.3.1.2. 2.3.1.3. 2.3.1.4. Eden 区 .................................................................................................................................................... 24 ServivorFrom........................................................................................................................................... 24 ServivorTo .............................................................................................................................................. 24 MinorGC 的过程(复制->清空->互换) ....................................................................................... 24 1:eden、servicorFrom 复制到 ServicorTo,年龄+1................................................................................... 25 2:清空 eden、servicorFrom............................................................................................................................. 25 3:ServicorTo 和 ServicorFrom 互换................................................................................................................25 2.3.3.1. 2.4.1. 如何确定垃圾 .............................................................................................................................. 26 2.4.1.1. 引用计数法............................................................................................................................................... 26 2.4.1.2. 可达性分析............................................................................................................................................... 26 2.3.2. 2.3.3. 老年代 .......................................................................................................................................... 25 永久代 .......................................................................................................................................... 25 JAVA8 与元数据.................................................................................................................................25 2.4. 垃圾回收与算法 .................................................................................................................................. 26 2.4.2. 2.4.3. 2.4.4. 2.4.5. 2.4.5.1. 2.4.5.2. 2.6.1. 2.6.1.1. 2.6.1.2. 2.7.1. 2.7.2. 2.7.3. 2.7.4. 2.7.5. 2.7.6. 2.7.6.1. 标记清除算法(Mark-Sweep) .............................................................................................. 27 复制算法(copying)................................................................................................................. 27 标记整理算法(Mark-Compact).................................................................................................. 28 分代收集算法 .............................................................................................................................. 29 新生代与复制算法 .............................................................................................................................. 29 老年代与标记复制算法 ......................................................................................................................29 2.5. JAVA 四中引用类型 ........................................................................................................................... 30 2.5.1. 强引用 .......................................................................................................................................... 30 2.5.2. 软引用 .......................................................................................................................................... 30 2.5.3. 弱引用 .......................................................................................................................................... 30 2.5.4. 虚引用 .......................................................................................................................................... 30 2.6. GC 分代收集算法 VS 分区收集算法................................................................................................ 30 分代收集算法 .............................................................................................................................. 30 在新生代-复制算法............................................................................................................................. 30 在老年代-标记整理算法.....................................................................................................................30 分区收集算法 .............................................................................................................................. 31 2.7. GC 垃圾收集器 ................................................................................................................................... 31 2.6.2. Serial 垃圾收集器(单线程、复制算法)................................................................................ 31 ParNew 垃圾收集器(Serial+多线程) ................................................................................... 31 .......................................................... 32 ........................................................................... 32 ......................................................................... 33 ..................................................................................... 33 初始标记 .............................................................................................................................................. 33 Parallel Scavenge 收集器(多线程复制算法、高效) Serial Old 收集器(单线程标记整理算法 ) Parallel Old 收集器(多线程标记整理算法) CMS 收集器(多线程标记清除算法) 2.7.6.2. 2.7.6.3. 2.7.6.4. 2.8.1. 2.8.2. 2.8.3. 2.8.4. 2.8.5. 2.8.1. 2.8.2. 2.8.2.1. 2.8.2.2. 2.8.3. 2.8.4. 2.8.5. 并发标记 .............................................................................................................................................. 34 重新标记 .............................................................................................................................................. 34 并发清除 .............................................................................................................................................. 34 G1 收集器 .................................................................................................................................... 34 2.8. JAVA IO/NIO ....................................................................................................................................... 34 2.7.7. 2.9. 2.9.2. 2.9.2.1. 2.9.2.2. 2.9.2.3. 2.9.3. 2.9.4. 2.9.4.1. 2.9.4.2. 阻塞IO模型 ................................................................................................................................ 34 ............................................................................................................................ 35 ........................................................................................................................ 35 ........................................................................................................................ 36 ................................................................................................................................ 36 .................................................................................................................................. 36 .................................................................................................................................... 37 NIO 的缓冲区 .....................................................................................................................................38 NIO 的非阻塞 .....................................................................................................................................38 ....................................................................................................................................... 40 非阻塞 IO 模型 多路复用 IO 模型 信号驱动 IO 模型 ............................................................................................................................................ 40 ........................................................................................................................................ 40 JVM 类加载机制 ................................................................................................................................. 41 2.9.1.1. 2.9.1.2. 2.9.1.3. 2.9.1.4. 2.9.1.5. 2.9.1.6. 2.9.1.7. 2.9.1.8. 加载 .......................................................................................................................................................... 41 验证 .......................................................................................................................................................... 41 准备 .......................................................................................................................................................... 41 解析 .......................................................................................................................................................... 41 符号引用 .............................................................................................................................................. 42 直接引用 .............................................................................................................................................. 42 初始化 ...................................................................................................................................................... 42 类构造器 .............................................................................................................................. 42 类加载器 ...................................................................................................................................... 42 启动类加载器(Bootstrap ClassLoader) ......................................................................................... 43 扩展类加载器(Extension ClassLoader)..........................................................................................43 应用程序类加载器(Application ClassLoader): ..........................................................................43 双亲委派 ...................................................................................................................................... 43 OSGI(动态模型系统) ............................................................................................................ 44 动态改变构造 ...................................................................................................................................... 44 模块化编程与热插拔 .......................................................................................................................... 44 3. JAVA集合............................................................................................................................................45 3.1. 接口继承关系和实现 .......................................................................................................................... 45 3.2. LIST ....................................................................................................................................................... 47 3.2.1. ArrayList(数组)....................................................................................................................... 47 3.2.2. Vector(数组实现、线程同步) ............................................................................................... 47 3.2.3. LinkList(链表) ......................................................................................................................... 47 3.3. SET ....................................................................................................................................................... 48 3.3.1.1. 3.3.1.2. HashSet(Hash 表) ............................................................................................................................. 48 TreeSet(二叉树) ................................................................................................................................ 49 LinkHashSet(HashSet+LinkedHashMap) ................................................................................... 49 3.3.1.3. 3.4. MAP....................................................................................................................................................... 50 3.4.1. HashMap(数组+链表+红黑树)............................................................................................. 50 3.4.1.1. JAVA7 实现 ............................................................................................................................................. 50 3.4.1.2. JAVA8 实现 ............................................................................................................................................. 51 3.4.2. ConcurrentHashMap.................................................................................................................. 51 3.4.2.1. 3.4.2.2. 3.4.2.3. 3.4.2.4. Segment 段.............................................................................................................................................. 51 线程安全(Segment 继承 ReentrantLock 加锁) .............................................................................. 51 并行度(默认 16) ................................................................................................................................. 52 Java8 实现 (引入了红黑树) .............................................................................................................. 52 13/04/2018 Page 2 of 283 异步IO模型 JAVA IO 包 JAVA NIO Channel Buffer Selector 3.4.3. HashTable(线程安全) ........................................................................................................... 53 3.4.4. TreeMap(可排序) .................................................................................................................. 53 3.4.5. LinkHashMap(记录插入顺序) .............................................................................................. 53 4. JAVA 多线程并发.................................................................................................................................54 4.1.1. JAVA 并发知识库 ....................................................................................................................... 54 4.1.2. JAVA 线程实现/创建方式 .......................................................................................................... 54 4.1.2.1. 4.1.2.2. 4.1.2.3. 4.1.2.4. 继承 Thread 类 ........................................................................................................................................ 54 实现 Runnable 接口。............................................................................................................................ 54 ExecutorService、Callable、Future 有返回值线程.............................................................55 基于线程池的方式................................................................................................................................... 56 4.1.3. 4 种线程池 ................................................................................................................................... 56 4.1.3.1. 4.1.3.2. 4.1.3.3. newSingleThreadExecutor ................................................................................................................. 58 4.1.4. 线程生命周期(状态) .................................................................................................................... 58 4.1.3.4. 4.1.4.1. 4.1.4.2. 4.1.4.3. 4.1.4.4. 新建状态(NEW) ................................................................................................................................. 58 就绪状态(RUNNABLE): ................................................................................................................. 59 运行状态(RUNNING): .................................................................................................................... 59 阻塞状态(BLOCKED):....................................................................................................................59 4.1.9.5. 4.1.9.6. 4.1.9.7. 13/04/2018 Semaphore 信号量 ................................................................................................................................. 68 ................................................................................................................................. 68 ................................................................................................................................................................ 68 ........................................................................................................................... 69 AtomicInteger .......................................................................................................................................... 69 Page 3 of 283 newCachedThreadPool ......................................................................................................................... 57 ............................................................................................................................. 57 newScheduledThreadPool .................................................................................................................... 58 newFixedThreadPool 等待阻塞(o.wait->等待对列): ...................................................................................................................... 59 .......................................................................................................................................... 59 ............................................................................................................................................ 59 线程死亡(DEAD)................................................................................................................................ 59 ............................................................................................................................................................... 59 ............................................................................................................................................................... 59 ............................................................................................................................................................... 59 4.1.5. 终止线程 4 种方式 ...................................................................................................................... 60 同步阻塞(lock->锁池) 其他阻塞(sleep/join) 4.1.4.5. 4.1.5.1. 4.1.5.2. 4.1.5.3. 4.1.5.4. 正常运行结束........................................................................................................................................... 60 使用退出标志退出线程...........................................................................................................................60 Interrupt 方法结束线程 ........................................................................................................................... 60 stop 方法终止线程(线程不安全)....................................................................................................... 61 正常结束. 异常结束. 调用 stop 4.1.6. sleep 与 wait 区别....................................................................................................................... 61 4.1.7. start 与 run 区别 .......................................................................................................................... 62 4.1.8. JAVA 后台线程 ........................................................................................................................... 62 4.1.9. JAVA 锁 ....................................................................................................................................... 63 4.1.9.1. 4.1.9.2. 4.1.9.3. 乐观锁 ...................................................................................................................................................... 63 悲观锁 ...................................................................................................................................................... 63 自旋锁 ...................................................................................................................................................... 63 自旋锁的优缺点....................................................................................................................................................63 自旋锁时间阈值(1.6 引入了适应性自旋锁) .................................................................................................. 63 自旋锁的开启........................................................................................................................................................ 64 4.1.9.4. Synchronized 同步锁.............................................................................................................................. 64 ....................................................................................................................................... 64 ....................................................................................................................................... 64 Synchronized 作用范围 Synchronized 核心组件 Synchronized 实现 ............................................................................................................................................... 64 ReentrantLock......................................................................................................................................... 66 ........................................................................................................................................... 66 ................................................................................................................................................................ 66 .................................................................................................................................................................... 67 ........................................................................................................................ 67 ............................................................................................................................................. 67 ......................................................................................................... 68 tryLock 和 lock 和 lockInterruptibly 的区别........................................................................................................ 68 Lock 接口的主要方法 非公平锁 公平锁 ReentrantLock 与 synchronized ReentrantLock 实现 Condition 类和 Object 类锁方法区别区别 实现互斥锁(计数器为 1) 代码实现 Semaphore 与 ReentrantLock 4.1.9.8. 4.1.9.9. 4.1.9.10. 4.1.9.11. 4.1.9.12. 4.1.9.14. 4.1.9.15. 4.1.9.16. 可重入锁(递归锁)............................................................................................................................... 69 公平锁与非公平锁................................................................................................................................... 70 ..................................................................................................................................................... 70 ........................................................................................................................................... 70 ReadWriteLock 读写锁......................................................................................................................70 ........................................................................................................................................................................ 70 ........................................................................................................................................................................ 70 公平锁(Fair) 非公平锁(Nonfair) 读锁 写锁 共享锁和独占锁 .................................................................................................................................. 70 .................................................................................................................................................................... 70 .................................................................................................................................................................... 70 重量级锁(Mutex Lock)................................................................................................................71 轻量级锁 .............................................................................................................................................. 71 锁升级.................................................................................................................................................................... 71 独占锁 共享锁 4.1.9.13. 偏向锁 .................................................................................................................................................. 71 分段锁 .................................................................................................................................................. 71 锁优化 .................................................................................................................................................. 71 减少锁持有时间 .................................................................................................................................................... 72 ............................................................................................................................................................ 72 .................................................................................................................................................................... 72 .................................................................................................................................................................... 72 .................................................................................................................................................................... 72 4.1.10. 线程基本方法..............................................................................................................................72 减小锁粒度 锁分离 锁粗化 锁消除 4.1.10.1. 4.1.10.2. 4.1.10.3. 4.1.10.4. 4.1.10.5. 4.1.10.6. 4.1.10.7. 4.1.10.8. 线程等待(wait) ............................................................................................................................... 73 线程睡眠(sleep)............................................................................................................................. 73 线程让步(yield) .............................................................................................................................. 73 线程中断(interrupt)........................................................................................................................ 73 Join 等待其他线程终止 ...................................................................................................................... 74 为什么要用 join()方法? .................................................................................................................... 74 线程唤醒(notify)............................................................................................................................. 74 其他方法: .......................................................................................................................................... 74 4.1.11. 线程上下文切换..........................................................................................................................75 4.1.11.1. 4.1.11.2. 4.1.11.3. 4.1.11.4. 4.1.11.5. 4.1.11.6. 4.1.11.7. 进程......................................................................................................................................................75 上下文..................................................................................................................................................75 寄存器..................................................................................................................................................75 程序计数器 .......................................................................................................................................... 75 PCB-“切换桢”................................................................................................................................. 75 上下文切换的活动: .......................................................................................................................... 76 引起线程上下文切换的原因 .............................................................................................................. 76 4.1.12. 同步锁与死锁..............................................................................................................................76 4.1.12.1. 同步锁 .................................................................................................................................................. 76 4.1.12.2. 死锁 ...................................................................................................................................................... 76 4.1.13. 线程池原理..................................................................................................................................76 4.1.14.1. 4.1.14.2. 4.1.14.3. 4.1.14.4. 4.1.14.5. 4.1.14.6. 4.1.14.7. 4.1.14.8. 4.1.13.1. 4.1.13.2. 4.1.13.3. 4.1.13.4. 线程复用 .............................................................................................................................................. 76 ...................................................................................................................................... 76 .............................................................................................................................................. 78 ......................................................................................................................... 78 4.1.14. JAVA 阻塞队列原理.................................................................................................................... 79 线程池的组成 拒绝策略 Java 线程池工作过程 阻塞队列的主要方法 .......................................................................................................................... 80 ............................................................................................................................................................ 80 .................................................................................................................................................... 81 ............................................................................................................................. 81 ....................................................................................... 82 ......................................................................... 82 .............................................................. 82 .......................................................................................... 82 .............................................................. 83 ...................................................................................................................... 83 插入操作: 获取数据操作: Java 中的阻塞队列 ArrayBlockingQueue(公平、非公平) LinkedBlockingQueue(两个独立锁提高并发) PriorityBlockingQueue(compareTo 排序实现优先) DelayQueue(缓存失效、定时任务 ) SynchronousQueue(不存储数据、可用于传递数据) LinkedTransferQueue 13/04/2018 Page 4 of 283 4.1.14.9. LinkedBlockingDeque ..................................................................................................................... 83 4.1.15. CyclicBarrier、CountDownLatch、Semaphore 的用法 ........................................................ 84 4.1.15.1. 4.1.15.2. 4.1.15.3. ................................................................................................ 84 ............................................... 84 ....................................................................... 85 CountDownLatch(线程计数器 ) CyclicBarrier(回环栅栏-等待至 barrier 状态再全部同时执行) Semaphore(信号量-控制同时访问的线程个数) 4.1.16. volatile 关键字的作用(变量可见性、禁止重排序) ............................................................. 87 变量可见性............................................................................................................................................................ 87 禁止重排序............................................................................................................................................................ 87 ..................................................................................................................... 87 ................................................................................................................................................................ 87 4.1.17. 如何在两个线程之间共享数据...................................................................................................88 将数据抽象成一个类,并将数据的操作作为这个类的方法.............................................................................88 .................................................................................................................. 89 4.1.18. ThreadLocal 作用( )........................................................................................ 90 .............................................................................................................. 90 ................................................................................................................................................................ 91 4.1.19. synchronized 和 ReentrantLock 的区别 .................................................................................. 91 4.1.19.1. .................................................................................................................................. 91 4.1.19.2. .................................................................................................................................. 92 4.1.20. ConcurrentHashMap 并发......................................................................................................... 92 4.1.20.1. .......................................................................................................................................... 92 4.1.20.2. .......................................................................................................... 92 ................................................. 93 4.1.21. Java 中用到的线程调度 ............................................................................................................. 93 比 sychronized 更轻量级的同步锁 适用场景 Runnable 对象作为一个类的内部类 ThreadLocalMap(线程的一个属性) 线程本地存储 使用场景 两者的共同点: 两者的不同点: 4.1.21.1. 4.1.21.2. 4.1.21.3. 4.1.21.4. 减小锁粒度 ...................................................................................................................................... 93 ...................................................................................................................................... 93 ............................................................................................. 94 ..................................................................................................................... 94 4.1.22. 进程调度算法..............................................................................................................................94 4.1.22.1. 4.1.22.2. 4.1.22.3. ...................................................................................................................................... 94 ...................................................................................................................... 95 .............................................................................................................. 96 )..................................................................96 .......................................................................................................................................... 96 ........................................................................... 97 ............................................................................................................................................. 98 4.1.24. 什么是AQS(抽象的队列同步器).........................................................................................98 Exclusive 独占资源-ReentrantLock ................................................................................................................... 99 Share 共享资源-Semaphore/CountDownLatch ............................................................................................... 99 同步器的实现是 ABS 核心(state 资源状态计数) ....................................................................................... 100 ReentrantReadWriteLock 实现独占和共享两种方式.....................................................................................100 5. JAVA基础..........................................................................................................................................101 4.1.23. 什么是CAS( 4.1.23.1. 4.1.23.2. 4.1.23.3. 5.1.1. 5.1.1.1. 5.1.1.2. 5.1.1.3. 5.1.1.4. JAVA 异常分类及处理.............................................................................................................. 101 .................................................................................................................................................... 101 ............................................................................................................................................ 101 ..................................................................................................................................................................... 101 ........................................................................... 101 ................................................................................................................................ 102 ......................................................... 102 .................................................................................................................. 102 ............................................................................................................ 102 13/04/2018 Page 5 of 283 ConcurrentHashMap 分段锁 ConcurrentHashMap 是由 Segment 数组结构和 HashEntry 数组结构组成 抢占式调度: 协同式调度: JVM 的线程调度实现(抢占式调度) 线程让出 cpu 的情况: 优先调度算法 高优先权优先调度算法 基于时间片的轮转调度算法 比较并交换-乐观锁机制-锁自旋 概念及特性 原子包 java.util.concurrent.atomic(锁自旋) ABA 问题 概念 异常分类 Error Exception(RuntimeException、CheckedException) 异常的处理方式 遇到问题不进行具体处理,而是继续抛给调用者 (throw,throws) try catch 捕获异常针对性处理方式 Throw 和 throws 的区别: 位置不同 功能不同: 5.1.2. 5.1.2.1. 5.1.2.2. 5.1.2.3. 5.1.2.4. 5.1.2.5. 5.1.2.6. 5.1.2.7. 5.1.3. 5.1.4.1. 5.1.4.2. 5.1.4.3. 5.1.4.4. @Documented 描述-javadoc @Inherited 阐述了某个被标注的类型是被继承的 5.1.5.1. 5.1.5.2. 5.1.5.3. 5.1.5.4. 泛型方法() ............................................................................................................................. 112 泛型类 ............................................................................................................................................. 112 类型通配符? .......................................................................................................................................... 113 类型擦除 ................................................................................................................................................ 113 .............................................................................................................................................................. 102 .......................................................................................................................................................... 102 JAVA 反射 ................................................................................................................................. 103 ............................................................................................................................................ 103 ............................................................ 103 ................................................................................................................................ 103 .................................................................................................................................. 103 ...................................................................................................................... 104 .................................................................................................................................... 104 ............................................................................ 104 ..................................................................... 104 ............................................................................................................ 104 ....................................................................................................................... 104 ................................................................................ 104 ............................................................................ 104 动态语言 反射机制概念 (运行状态中知道类所有的属性和方法) 反射的应用场合 编译时类型和运行时类型 的编译时类型无法获取具体方法 Java 反射 API 反射 API 用来生成 JVM 中的类、接口或则对象的信息。 反射使用步骤(获取 Class 对象、调用对象方法) 获取 Class 对象的 3 种方法 调用某个对象的 getClass()方法 调用某个类的 class 属性来获取该类对应的 Class 对象 使用 Class 类中的 forName()静态方法(最安全/性能最好) 创建对象的两种方法 Class 对象的 newInstance() 调用 Constructor 对象的 newInstance() ........................................................................................................................ 105 ............................................................................................................................. 105 .......................................................................................................... 105 JAVA 注解 ................................................................................................................................. 106 5.1.3.1. 概念 ........................................................................................................................................................ 106 5.1.3.2. 4 种标准元注解...................................................................................................................................... 106 @Target 修饰的对象范围 ................................................................................................................................. 106 @Retention 定义 被保留的时间长短 ............................................................................................................... 106 ................................................................................................................................ 106 .............................................................................................. 106 5.1.3.3. 注解处理器............................................................................................................................................. 107 5.1.4. JAVA 内部类 ............................................................................................................................. 109 静态内部类............................................................................................................................................. 109 成员内部类............................................................................................................................................. 110 局部内部类(定义在方法中的类) ..................................................................................................... 110 匿名内部类(要继承一个父类或者实现一个接口、直接使用 new 来生成一个对象的引用) ..... 111 5.1.5. JAVA 泛型 ................................................................................................................................. 112 5.1.6. JAVA 序列化(创建可复用的 Java 对象) ................................................................................. 113 .................................................................................................... 113 ................................................................................................. 113 .................................................................................................................................. 113 Serializable 实现序列化 .................................................................................................................................... 113 ............................................... 113 ................................................................................................ 113 ............................................................................................................................................................. 113 .................................................................................................................................. 114 .............................................................................................................................................. 114 ............................................................................................ 114 5.1.7. JAVA 复制 ................................................................................................................................. 114 5.1.7.1. ......................................................................................................................................... 114 5.1.7.2. ..................................................................................... 114 5.1.7.3. ................................................................................................. 115 5.1.7.4. ........................................................................................................ 115 6. SPRING 原理 ..................................................................................................................................... 116 6.1.1. Spring 特点................................................................................................................................ 116 6.1.1.1. 轻量级 ................................................................................................................................................ 116 13/04/2018 Page 6 of 283 保存(持久化)对象及其状态到内存或者磁盘 序列化对象以字节数组保持-静态成员不保存 序列化用户远程对象传输 ObjectOutputStream 和 ObjectInputStream 对对象进行序列化及反序列化 writeObject 和 readObject 自定义序列化策略 序列化 ID 序列化并不保存静态变量 序列化子父类说明 Transient 关键字阻止该变量被序列化到文件中 直接赋值复制 浅复制(复制引用但不复制引用的对象) 深复制(复制对象和其应用对象) 序列化(深 clone 一中实现) 6.1.1.2. 6.1.1.3. 6.1.1.4. 6.1.1.5. 6.1.2. 6.1.3. 6.1.4. 6.1.5. 6.1.6. 6.1.7. ............................................................................................................................................ 116 ............................................................................................................................................ 116 .................................................................................................................................................... 116 ............................................................................................................................................ 116 Spring 核心组件........................................................................................................................ 117 Spring 常用模块........................................................................................................................ 117 Spring 主要包............................................................................................................................ 118 Spring 常用注解........................................................................................................................ 118 Spring 第三方结合.................................................................................................................... 119 Spring IOC 原理........................................................................................................................ 120 6.1.7.1. 6.1.7.2. 6.1.7.3. 概念 ........................................................................................................................................................ 120 Spring 容器高层视图 ............................................................................................................................ 120 IOC 容器实现......................................................................................................................................... 120 控制反转 面向切面 容器 框架集合 BeanFactory-框架基础设施 .............................................................................................................................. 120 1.1..1.1.1 1.1..1.1.2 1.1..1.1.3 1.1..1.1.4 1.1..1.1.5 1.1..1.1.6 1.1..1.1.7 1.1..1.1.8 BeanDefinitionRegistry 注册表................................................................................................. 121 BeanFactory 顶层接口 .............................................................................................................. 121 ListableBeanFactory ................................................................................................................. 121 HierarchicalBeanFactory 父子级联.......................................................................................... 121 ConfigurableBeanFactory......................................................................................................... 121 AutowireCapableBeanFactory 自动装配 ................................................................................ 122 SingletonBeanRegistry 运行期间注册单例 Bean................................................................... 122 依赖日志框框.............................................................................................................................122 ApplicationContext 面向开发应用 .................................................................................................................... 122 WebApplication 体系架构 ................................................................................................................................. 123 6.1.7.4. Spring Bean 作用域.............................................................................................................................. 123 singleton:单例模式(多线程下不安全) ...................................................................................................... 123 prototype:原型模式每次使用时创建 ................................................................................................................ 124 Request:一次 request 一个实例 .................................................................................................................... 124 session ................................................................................................................................................................ 124 global Session....................................................................................................................................................124 6.1.7.5. Spring Bean 生命周期.......................................................................................................................... 124 实例化.................................................................................................................................................................. 124 IOC依赖注入......................................................................................................................................................124 setBeanName 实现............................................................................................................................................ 124 BeanFactoryAware 实现 ................................................................................................................................... 124 ApplicationContextAware 实现......................................................................................................................... 125 postProcessBeforeInitialization 接口实现-初始化预处理.......................................................................... 125 init-method .......................................................................................................................................................... 125 postProcessAfterInitialization ........................................................................................................................... 125 Destroy 过期自动清理阶段 ............................................................................................................................... 125 destroy-method 自配置清理 ............................................................................................................................. 125 6.1.7.6. Spring 依赖注入四种方式 .................................................................................................................... 126 构造器注入.......................................................................................................................................................... 126 setter方法注入...................................................................................................................................................127 静态工厂注入...................................................................................................................................................... 127 实例工厂.............................................................................................................................................................. 127 6.1.7.7. 5 种不同方式的自动装配...................................................................................................................... 128 6.1.8. Spring APO 原理 ...................................................................................................................... 129 6.1.8.1. 6.1.8.2. 6.1.8.1. 概念 ........................................................................................................................................................ 129 AOP 核心概念 ....................................................................................................................................... 129 AOP 两种代理方式 ............................................................................................................................... 130 JDK 动态接口代理 ............................................................................................................................................. 130 CGLib 动态代理.................................................................................................................................................. 131 6.1.8.2. 实现原理 ................................................................................................................................................ 131 6.1.9. Spring MVC原理......................................................................................................................132 6.1.9.1. MVC 流程............................................................................................................................................... 132 Http 请求到 DispatcherServlet ....................................................................................................................... 133 HandlerMapping 寻找处理器............................................................................................................................133 调用处理器 Controller........................................................................................................................................ 133 13/04/2018 Page 7 of 283 Controller 调用业务逻辑处理后,返回 ModelAndView.................................................................................133 DispatcherServlet 查询 ModelAndView .......................................................................................................... 133 ModelAndView 反馈浏览器 HTTP ................................................................................................................... 133 6.1.9.1. MVC 常用注解 ....................................................................................................................................... 133 6.1.10. Spring Boot 原理....................................................................................................................... 134 1. 创建独立的 Spring 应用程序............................................................................................................................. 134 2.嵌入的Tomcat,无需部署WAR文件.............................................................................................................134 3. 简化 Maven 配置 ................................................................................................................................................ 134 4. 自动配置 Spring ................................................................................................................................................. 134 5. 提供生产就绪型功能,如指标,健康检查和外部配置................................................................................... 134 6. 绝对没有代码生成和对 XML 没有要求配置 [1] ............................................................................................... 134 6.1.11. JPA 原理 .................................................................................................................................... 134 6.1.11.1. 事务....................................................................................................................................................134 6.1.11.2. 6.1.11.1. 6.1.11.1. 本地事务 ............................................................................................................................................ 134 分布式事务 ........................................................................................................................................ 135 两阶段提交 ........................................................................................................................................ 136 1 准备阶段........................................................................................................................................................... 136 2 提交阶段:....................................................................................................................................................... 136 6.1.12. Mybatis 缓存.............................................................................................................................. 137 6.1.12.1. Mybatis 的一级缓存原理(sqlsession 级别)..............................................................................138 6.1.12.2. 二级缓存原理(mapper 基本).....................................................................................................138 具体使用需要配置: .......................................................................................................................................... 139 6.1.13. Tomcat 架构 .............................................................................................................................. 139 7. 微服务 ................................................................................................................................................. 140 7.1.1. 服务注册发现 ............................................................................................................................ 140

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值