Java基础面试题小结

  1. JDK和JRE有什么区别?

    JRE全称为java运行环境,JRE包括java虚拟机和java程序所需的核心类库等。如果想要运行一个开发好的java程序,计算机中只需要安装JRE即可。

    JDK全称为java开发工具包,JDK是提供java开发人员使用的,其中包含了java的开发工具,也包括了JRE。其中的开发工具:编译工具(javac.exe)、打包工具(jar.exe)。
    一般的说,安装了JDK,就不用在单独安装JRE了。

  2. = =和equals的区别是什么?

    = =:它的作用是判断两个对象的地址是否相等。即判断两个对象是不是同一个对象。如果比较的对象是基础类型的,则= =比较的是值,如果对象是引用数据类型,= =比较的是内存地址。
    equals():它的作用是判断两个对象是否相等。但它一般有两个使用情况:

    情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
    情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象的内容相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。

    使用代码举例:

public class test1 {
    public static void main(String[] args) {
        String a = new String("ab"); // a 为一个引用
        String b = new String("ab"); // b为另一个引用,对象的内容一样
        String aa = "ab"; // 放在常量池中
        String bb = "ab"; // 从常量池中查找
        if (aa == bb) // true
            System.out.println("aa==bb");
        if (a == b) // false,非同一对象
            System.out.println("a==b");
        if (a.equals(b)) // true
            System.out.println("aEQb");
        if (42 == 42.0) { // true
            System.out.println("true");
        }
    }
}
说明:
1.String 中的 equals 方法是被重写过的,因为 object 的 equals 方法是比较的对象的内存地址,而 String 的 equals 方法比较的是对象的值。
2.当创建 String 类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个 String 对象。
  1. 两个对象的hashCode()相同,则equals()也一定为true吗
    hashCode()介绍
    hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数。

    散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)

    hashCode()与equals()的相关规定
    1.如果两个对象相等,则hashcode一定也是相同的
    2.两个对象相等,对两个对象分别调用equals方法都返回true
    3.两个对象有相同的hashcode值,它们也不一定是相等的,即equals()不一定为true
    4.equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
    5.hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)

  2. final 在 Java 中有什么作用?
    final关键字主要用在三个地方:变量、方法、类。

    1. 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
    2. 当用final修饰一个类时,表明这个类不能被继承。final类中的所有成员方法都会被隐式地指定为final方法。
    3. 使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升(现在的Java版本已经不需要使用final方法进行这些优化了)。类中所有的private方法都隐式地指定为final。
  3. Java 中的 Math.round(-1.5) 等于多少?
    -1

  4. String 属于基础的数据类型吗?
    String不是基本数据类型,而是一个类(class),是C++、java等编程语言中的字符串。

    String类是不可变的,对String类的任何改变,都是返回一个新的String类对象。 String 对象是 System.Char 对象的有序集合,用于表示字符串。String 对象的值是该有序集合的内容,并且该值是不可变的。
    因为,java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。

    为了提高效率节省空间,我们应该用StringBuffer类。

  5. Java 中操作字符串都有哪些类?它们之间有什么区别?
    String StringBuffer StringBuilder
    它们之间的区别:
    可变性

    简单的来说:String 类中使用 final 关键字字符数组保存字符串,private final char value[],所以 String 对象是不可变的。而StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串char[]value 但是没有用 final 关键字修饰,所以这两种对象都是可变的。

    StringBuilder 与 StringBuffer 的构造方法都是调用父类构造方法也就是 AbstractStringBuilder 实现的,大家可以自行查阅源码。

    AbstractStringBuilder.java
    
    abstract class AbstractStringBuilder implements Appendable, CharSequence {
        char[] value;
        int count;
        AbstractStringBuilder() {
        }
        AbstractStringBuilder(int capacity) {
            value = new char[capacity];
        }

线程安全性
String 中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

性能

每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。

对于三者使用的总结:

  • 操作少量的数据 = String
  • 单线程操作字符串缓冲区下操作大量数据 = StringBuilder
  • 多线程操作字符串缓冲区下操作大量数据 = StringBuffer
  1. String str="i"与 String str=new String(“i”)一样吗?
    关于String str =new String(“abc”)和 String str = "abc"的比较

  2. 如何将字符串反转?

  3. String 类的常用方法都有那些?

  • charAt(int i);返回索引处的char值
  • concat(String str);将指定字符串连接至末尾
  • indexof(String str);返回指定子字符串第一次出现的字符串内的索引。
  • compareTo(String anotherString);按字典顺序比较两个字符串。
  • isEmpty();如果,当且仅当 length()为 0 。返回 true
  • matches(String regex);匹配正则
  • replace(char oldChar, char newChar);返回从替换所有出现的导致一个字符串 oldChar在此字符串 newChar 。
  • split(String reg);按照正则分割字符串
  • substring(int beginIndex, int endIndex);返回一个字符串,该字符串是此字符串的子字符串。
  • toLowerCase();转小写
  • toUpperCase();转大写
  • trim();去首尾空白
  • valueOf(char,float,double,int,boolean);转换String
  1. 抽象类必须要有抽象方法吗?
  • 使用abstract修饰符修饰的类被称为抽象类;

    抽象类不能实例化对象,只能被继承;

  • 使用abstract修饰符修饰的方法被称为抽象方法;

  • 抽象方法不能有方法体,子类必须重写抽象类中所有的抽象方法;

  • 抽象类中不一定包含抽象方法,但包含抽象方法的类一定是抽象类;

  1. 普通类和抽象类有哪些区别?
    1.抽象类不能被实例化。
    2.抽象类可以有构造函数,被继承时子类必须继承父类一个构造方法,抽象方法不能被声明为静态。
    3.抽象方法只需申明,而无需实现,抽象类中可以允许普通方法有主体
    4.含有抽象方法的类必须申明为抽象类
    5.抽象的子类必须实现抽象类中所有抽象方法,否则这个子类也是抽象类。

  2. 抽象类能使用 final 修饰吗?
    abstract修饰一个类表示这个类是抽象类,抽象类的特点是如果一个类是抽象类,里面不一定包含抽象的方法,可以全都是具体的方法。反过来说,如果一个类里面包含了抽象的方法,这个类必然是抽象类。对于抽象类来说,不管里面是不是全都是具体的方法,java规定它都不能被实例化,不能通过new的方式来生成它的一个对象,我们必须通过一个子类继承它来完成这个抽象类所完成的功能。通过实例化它的子类来实现抽象类的功能。final修饰一个类的时候表示类不能被继承,它是一个终态类。所以abstact和final是一种矛盾的状况。

  3. 接口和抽象类有什么区别?
    1.接口是抽象类的变体,接口中所有的方法都是抽象的。而抽象类是声明方法的存在而不去实现它的类。
    2 接口可以多继承,抽象类不行
    3.接口定义方法,不能实现,而抽象类可以实现部分方法。
    4.接口中基本数据类型为static 而抽类象不是的。

  4. Java 中 IO 流分为几种?

  • 按照流的流向分,可以分为输入流和输出流;
  • 按照操作单元划分,可以划分为字节流和字符流;
  • 按照流的角色划分为节点流和处理流。
  1. BIO、NIO、AIO 有什么区别?
    BIO、NIO、AIO的总结
  2. Files的常用方法都有哪些?
    Files的常用方法

猜你喜欢

转载自blog.csdn.net/qq_41304579/article/details/88605022