Java基础知识点汇总

基础知识点汇总

  1. /**
     * The <code>Stack</code> class represents a last-in-first-out
     * (LIFO) stack of objects. 
     * ... 
     * <p>A more complete and consistent set of LIFO stack operations is
     * provided by the {@link Deque} interface and its implementations, which
     * should be used in preference to this class.  For example:
     * <pre>   {@code
     *   Deque<Integer> stack = new ArrayDeque<Integer>();}</pre>
     *
     * @author  Jonathan Payne
     * @since   JDK1.0
     */
    public
    class Stack<E> extends Vector<E> {...
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51

    > 上面是jdk Stack源码中的注释,其中,建议当我们需要使用Stack这个数据类型时,优先使用Deque及其实现类,它实现了一组更完整和一致的LIFO的栈操作。
    >
    > Deque<Integer> stack = new ArrayDeque<Integer>();

    2. 面向对象的三大特征

    - 封装

    - 继承

    - 多态

    > 顾名思义,表示一个对象具有多种的状态。具体表现为父类的引用指向子类的实例。
    >
    > 常说的“面向接口编程”即使多态。

    - 执行方法调用时,具体执行哪个类中的方法,必须在程序运行期间才能确定。

    3. String为什么是不可变的?String StringBuffer和StringBuilder的区别?

    String类中使用final关键字修饰字符数组来保存字符串,`private final char[] value`,所以String对象是不可变的。

    > Java 9之后,String,StringBuffer和StringBuilder的实现改为byte数组存储字符串`private final byte[] vlaue`

    - 关于线程安全

    String对象是不可变得,可以理解为常量,线程安全。

    StringBuffer对方法加了`同步锁`,所以是线程安全的。

    StringBuilder没有添加同步锁,所以是非线程安全的。

    - 关于性能

    - 在不考虑线程安全的情况下,StringBuilder > StringBuffer > String

    - String类型每次进行改变时,都会生成一个新的String对象,然后将指针指向新的String对象。
    - StringBuffer每次都会对StringBuffer对象本身操作,而不是生成新的对象并改变对象引用。所以性能比String好。
    - StringBuilder的操作方式与StringBuffer一样,不过由于没有同步锁,所以性能好一些。

    - 总结:

    - 操作少量(几个)字符串时,使用`String`;
    - 单线程操作较多字符串时,使用`StringBuilder`;
    - 多线程操作较多字符串时,使用`StringBuffer`;

    4. Object类的常见方法总结

    Object类是所有类的父类,它提供的方法需要知道

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85



    5. 什么是反射?反射机制的优缺点?反射的应用场景?

    6. 什么是动态代理?使用场景?动态代理基于什么原因?

    7. 异常

    8. IO[ Java IO]

    9. 谈谈final、finally、finalize有什么不同?

    10. 强引用、软引用、弱引用、幻象引用有什么区别?

    11. int和Integer有什么区别?

    # 12. 深拷贝和浅拷贝

    - 深拷贝:完全拷贝一个对象,包括基本类型和引用类型,堆内的引用对象也会复制一份;
    - 安全的,拷贝前后两个对象完全互不影响。
    - 浅拷贝:仅拷贝基本类型和引用,堆内的引用对象和被拷贝的对象共享;
    - 不安全的,拷贝前后共享堆内对象,一方修改内容,另一方会受到影响。



    使用场景:

    1. 如果对象的属性全是基本类型,深拷贝,浅拷贝都可以;
    2. 如果对象的属性不会被改变,深浅都可以;
    3. 如果对象的属性经常改变,而拷贝后的对象不希望受到之前对象的影响,深拷贝。

    # 13. 重载和重写的区别?

    - 重载:在同一个类中,方法名相同,参数类型、顺序或者个数不同。即方法签名不同。

    > 注意:方法签名,是方法名和参数列表,不包括返回值。

    - 重写(Override):指子类重写父类的方法,方法签名一致。但是重写的子类方法的逻辑抛出的异常要么和父类一样要么是父类异常的子类,同时方法的访问权限不得低于父类。

    # 14. 什么是内部类,有什么用?

    内部类,是定义在一个类的内部的类

    - 成员内部类:在成员变量的位置定义,则是成员内部类;
    - 静态内部类:使用 static 修饰的则为静态内部类;
    - 匿名内部类:没有具体类名的为匿名内部类;
    - 局部内部类,定义在方法中(一般不太用);



    成员内部类,可以使用外部类的所有成员变量以及方法,包括 private 的;

    静态内部类,只能使用外部类的静态成员变量以及方法;

    内名内部类,常用来作为回调,使用的时候再实现具体逻辑来执行回调。



    实际上,内部类是一个编译层面的概念,像语法糖一样,经过编译之后,内部类会提升为外部顶级类,和外部类没有任何区别,所以在 JVM 中是没有内部类的概念的。

    一般情况下,非静态内部类用在内部类和其他类无任务关联,专属于这个外部类使用,并且也便于调用外部类的成员变量和方法,比较方便。

    静态外部类其实就等于一个顶级类,可以独立于外部类使用,所以更多的只是表明类结构和命名空间。



    ## Java 位运算

    位运算符:

    - & ,与, 一假则假,即对应的两个位都为1 时,结果才为 1;

    用途:

    1. 清零,如果希望指定位为0,只需要与一个对应位为0 的数与操作即可。

    2. 取一个数的指定位,例如,取一个int数的高3位,或取低4位,取高3位时只需与高3位为 1,低29位都为0的数相与即可;取低4位,只需与一个高位为0,低4位为1 的数相与即可;

    ```java
    // ThreadPoolExecutor.java 中 高3位表示 runState,即运行状态,低29位表示workerCount,线程数
    // 这是利用一个数表示两种状态的方式。
    private static final int COUNT_BITS = Integer.SIZE - 3; // 29
    private static final int CAPACITY = (1 << COUNT_BITS) - 1; // 低 29 位能表达的最大值,此时低29位全为 1;
    private static int runStateOf(int c) { return c & ~CAPACITY; } // 取一个int数的最高3个位,CAPACITY 表示 最高的3个位为0,其余29位为1,取反后最高的3个位为1,其余29位为0,和 c 进行 & 操作,得到的就是 c 中最高的3个位。
  2. 判断奇偶,

    只需要根据最末位是 0 还是 1 来判断即可,为 0 则是偶数,为 1 则是奇数,因此可以使用 if ((a & 1) == 0) 代替 if (a % 2 == 0) 来判断 a 是否为偶数;

  3. 判断第N位是否为1,(与2,3条类似)

    1
    2
    3
    4
    x & (1<<n)  // 判断 x 的第 n 位是否为1 (第3条也是这个意思, 1<<1 == 1,所以可以省略)
    // 得到的结果为1,则说明原值该位为1,得到为0,说明该位原值为0;

    x & ~(1<<n) // 这里还可以设置 x 的第 n 位为 0;
  • | ,或, 一真则真,即对应的两个位有一个为 1 时,结果就为 1;都为 0 时,结果才为 0;

    用途:

    1. 与 0 进行 或运算,得到原值;

    2. 可以对一个数的某些位设置为 1;

      1
      x | (1<<n)  // 设置 x 的第 n 位为 1;
  • ~ ,取反,0 -> 1, 1 -> 0 ;

  • ^ , 异或,对应的两个位相同为 0 ,相异(不同)为 1 ;

    几个特性:

    • 交换律
    • 结合律:(a^b)^c == a^(b^c)
    • 对于任何数x,都有 x^x=0,x^0=x
    • 自反性: a^b^b=a^0=a;

    用途:

    1. 翻转指定位

    2. 交换两个数

      1
      2
      3
      4
      5
      6
      7
      void swap(int a, int b) {
      if (a != b) {
      a ^= b;
      b ^= a;
      a ^= b;
      }
      }
  • << , 左移,各个二进制位全部左移若干位,高位丢弃,低位补 0 ;每左移1位,相当于乘以 2;左移 N 位,相当于乘以 2 的N 次方;

  • >> ,右移,各个二进制位全部右移若干位,对无符号位,高位补 0 ,有符号位,高位补1;每右移1位,相当于除以 2;右移 N 位,相当于除以 2 的N次方;

  • >>> ,Java中的无符号右移,不用担心会溢出。具体原因后面再找。

什么是位图(BitMap)

将一组bit位数据(即0或1)放到一个数组中即为位图(BitMap)

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2023 ligongzhao
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信