Java语言中凡是没有方法体的方法都是抽象方法

  • 错,object类中就有很多方法没有方法体,但它们都不是抽象方法
    • 例如:public native int hashCode();
  • 这个方法底层调用了C++写的动态链接程序
  • 前面修饰符列表中没有abstract,有一个native,表示调用JVM本地程序

以下代码执行结果

  1. public static void main(String[] args) {
  2. System.out.println(m());
  3. }
  4. public static int m () {
  5. int i = 100;
  6. try {
  7. return i;
  8. } finally {
  9. i++;
  10. }
  11. }
  12. //字节码文件反编译之后
  13. int i = 1oo;
  14. int j = i;
  15. i++;
  16. return j;

100

final 、finally 、fianalize 有什么区别

  1. final是一个关键字,表示最终的,不变的
  2. finally也是一个关键字,和try联合使用,使用在异常处理机制中,finally语句块中的代码是一定会执行的
  3. finalize() 是Object类中的标识符,作为方法名出现,JVM的GC垃圾回收器负责调用

    这么多的集合中,用哪个集合最多

  • ArrayList集合用的最多
  • 因为往数组末尾添加元素,效率不受影响,而且我们检索查找某个元素的操作比较多
    • 数组的内存地址是连续的,每个元素占用的空间大小相同,知道首元素内存地址,然后知道下标,通过数学表达式就能计算出元素的内存地址,所以检索效率高

JVM中的内存划分

  1. JDK6.0(包含)以前
    1. 寄存器(程序计数器):存储计算机硬件(CPU)相关的内容
    2. 本地方法栈内存:存储和操作系统相关的内容
    3. 本地方法栈:俗称“栈内存”,正在运行的方法
    4. 堆内存:存储隐式和显式new出来的东西
    5. 方法区:存储字节码文件对象(类文件class)
  2. JDK7.0
    1. 寄存器(程序计数器):存储计算机硬件(CPU)相关的内容
    2. 本地方法栈内存:存储和操作系统相关的内容
    3. 本地方法栈:俗称“栈内存”,正在运行的方法
    4. 堆内存:存储隐式和显式new出来的东西
    5. 方法区:将方法区划归到堆内存中
  3. JDK(8.0)以后
    1. 寄存器(程序计数器):存储计算机硬件(CPU)相关的内容
    2. 本地方法栈内存:存储和操作系统相关的内容
    3. 本地方法栈:俗称“栈内存”,正在运行的方法
    4. 堆内存:存储隐式和显式new出来的东西
    5. 元空间:存储特殊值的空间

String类面试题

String类面试题1

  • 字符串的字面值常量存储于内存中的“字符串常量池中

    1. public static void main(String[] args) {
    2. String str1 = new String("HelloWorld");
    3. String str2 = new String("HelloWorld");
    4. System.out.println(str1 == str2);//false
    5. System.out.println("============================");
    6. String str3 = "HelloWorld";//常量池==>字符串常量池
    7. String str4 = "HelloWorld";//常量池==>字符串常量池
    8. System.out.println(str3 == str4);//true
    9. System.out.println("============================");
    10. String str5 = new String("Hello");
    11. String str6 = new String("World");
    12. System.out.println(str1 == (str5 + str6));//堆 堆 false
    13. System.out.println("============================");
    14. String str7 = "Hello";
    15. String str8 = "World";
    16. System.out.println(str3 == (str7 + str8));//常量池 == 堆 false
    17. System.out.println("============================");
    18. System.out.println(str3 == "Hello" + "World");//true
    19. }

    String类面试题2

    1. public class StringDemo02 {
    2. public static final String str1 = "HelloWorld";
    3. public static final String str2 = "HelloWorld";
    4. public static final String str3 = "Hello";
    5. public static final String str4 = "World";
    6. public static final String str5;
    7. public static final String str6;
    8. public static final String str7;
    9. public static final String str8;
    10. static {
    11. str5 = "HelloWorld";
    12. str6 = "HelloWorld";
    13. str7 = "Hello";
    14. str8 = "World";
    15. }
    16. public static void main(String[] args) {
    17. System.out.println(str1 == str2);
    18. System.out.println(str5 == str6);
    19. System.out.println(str1 == str5);
    20. System.out.println("=========================================");
    21. System.out.println(str1 == (str3 + str4));//true常量池 == 常量池
    22. System.out.println(str5 == (str7 + str8));//false
    23. }
    24. }

    String类笔试题3

    1. public static void main(String[] args) {
    2. String str1 = "HelloWorld";
    3. //String对象数量和位置:1个(常量池)
    4. String str2 = new String("HelloWorld");
    5. //String对象数量和位置:2个(常量池1个,堆内存1个)
    6. String str3 = "H" + "e" + "l" + "l" + "o" + "W" + "o" + "r" + "l" + "d";
    7. //String对象数量和位置:1个(常量池)
    8. String s1 = "H";
    9. String s2 = "e";
    10. String s3 = "l";
    11. String s4 = "l";
    12. String s5 = "o";
    13. String s6 = "W";
    14. String s7 = "o";
    15. String s8 = "r";
    16. String s9 = "l";
    17. String s10 = "d";
    18. String str4 = s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
    19. //String对象数量和位置:8个(常量池7个,堆内存1个)
    20. }

    Integer面试题

    Integer面试题1

  • 当包装类型对象和基本数据类型比较,包装类型会根据从简原则拆箱再和基本数据类型比较

    public static void main(String[] args) {
      int num1 = 987;
      int num2 = 987;
      System.out.println(num1 == num2);
      System.out.println("=====================");
      Integer num3 = new Integer(654);
      Integer num4 = new Integer(654);
      System.out.println(num3 == num4);//false
      System.out.println("=====================");
      Integer num5 = 321;
      Integer num6 = 321;
      System.out.println(num5 == num6);//false
      System.out.println("=====================");
      Integer num7 = 123;//Integer类的cache数组的中内容(-128~127)
      Integer num8 = 123;
      System.out.println(num7 == num8);
      System.out.println("=====================");
      Integer num9 = 200;
      int num10 = 200;
      System.out.println(num9 == num10);//从简原则
      System.out.println(num10 == num9);//
    }
    

    Integer面试题2

    public class IntegerDemo02 {
      public static final Integer num1 = 200;
      public static final Integer num2 = 200;
      public static final Integer num3 = 50;
      public static final Integer num4 = 150;
      public static final Integer num5;
      public static final Integer num6;
      public static final Integer num7;
      public static final Integer num8;
      static {
          num5 = 200;
          num6 = 200;
          num7 = 50;
          num8 = 150;
      }
      public static void main(String[] args) {
          System.out.println(num1 == num2);
          System.out.println(num3 == num7);
          System.out.println("=====================");
          System.out.println(num1 == (num3 + num4));
          System.out.println(num5 == (num7 + num8));
      }
    }
    

    Integer面试题3

  1. 包装类整型的特殊数据:
    1. 在底层缓冲了一个长度为256的对应包装类型的数组,存储-128~127的该类型的对象,如果在范围内,拿数组中对象进行复用,如果不在范围内,new新的该类型的对象
  2. 包装类字符型的特殊数据:
    1. 在底层缓冲了一个长度为128的对应包装类型的数组,存储ASCII码表上的所有字符对象,如果在范围内,拿数组中对象进行复用,如果不在范围内,new新的该类型的对象
  3. 包装类布尔型的特殊数据:

    1. 在底层缓冲了两个Boolean对象,分别存储true和false,如果使用拿对应的对象进行复用 ```java public static void main(String[] args) { Double num1 = 0.0; Double num2 = 0.0; System.out.println(num1 == num2);//false 对象比较的是内存地址,Double类对象没有缓存对象

      Character num3 = ‘a’; Character num4 = ‘a’; System.out.println(num3 == num4);//true

      Boolean num5 = true; Boolean num6 = true; System.out.println(num5 == num6);//true

Integer i1 = 128;
Integer i2 = 128;
int i3 = 128;
int i4 = 128;
System.out.println(i1 == i2);//false,比较地址,128超过Integer缓存对象
System.out.println(i3 == i4);//true,比较数据值
System.out.println(i1 == i3);//true,i1自动拆箱按照基本数据类型比较
//包装类对象与基本数据类型进行比较时,就会把包装类对象自动拆箱,按照基本数据类
型的规则进行比较

} ```

Collection集合面试题

使用多态的形式创建Collection集合对象,而多态的特点主要和方法有关,当多态的对象调用方法,先虚调用父类或父接口中的方法,如果有执行子类或实现类重写后的方法,如果没有,编译报错,在打印集合对象时,其实就是调用集合多态对象的toString(),调用该toString()会先需调用父接口Collection中的toString(),通过查看源码发现ACollection接口及其父接口都没有toString(),代码应该编译报错,但实际上并没有报错,为什么?

所有的接口都继承Object的抽象形式,所有的接口都含有Object类中方法的抽象形式

重写hashCode()时重要参数为什么是31?

  1. 为了减少hashCode值的重复概率,这个数必须是质数
  2. 这个数不宜过小(原因:过小增大重复概率)
  3. 这个数不宜过大(原因:过大会有可能超出int范围,造成数据的精度的损失,增大重复概率)
  4. .通过”泊松分布”计算出数字29和31是较为合适的数字
  5. 通过数学科学计数法的改写,29可以写成2^5-3,31可以写成2^5-1,31的格式和整数取值范围相似或者二进制满位原因,最终选择31

    HashMap集合默认的加载因子为什么是0.75

    默认加载因子(0.75)在时间和空间成本上寻求一种折中,加载因子过高虽然减少了空间开销,但同时也增加了查询(时间)成本;加载因子过低虽然减少了查询(时间)开销,但同时也增加了空间成本