Java面试题问答(基础篇一)

Java面试题问答(基础篇)

题源来源于网上https://shimo.im/docs/KwyvcwKpQ6qpkxtQ/read

1.JDK 和 JRE 有什么区别?

JRE是个运行环境,JDK是个开发环境。程序电脑转的是JDK,而服务器装的是JRE

简单理解为层级关系

JDK > JRE > JVM(java虚拟机)

JDK:是Java Development Kit简写,主要是是开发人员使用的SDK(Software Development Kit 一般指软件开发包),提供java的开发环境和运行环境

JRE:是Java Runtime Enviromentd的简写,只能为java程序提供一个运行环境、编译java源码的编译器javac,不能为之提供开发环境和java程序调试和分析的工具:console,jvisualvm等工具软件。包含了JVM标准的java核心类库,不包含开发工具(编译器、调试器等)

下面用图片展示区别

jdk和jre

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

==: 比较是否是同一个对象;equals(): 比较的是对象里的内容

==:比较的是原始的地址,判断两个字符串在内存中首地址是否相同,即判断两者是否是同一个字符串对象

equals:没有重写equals()方法比较的是对象的地址,如果地址相同返回true,不同再比较里面的值,见下面的equals的源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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;
}

==equals的应用:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test {
public static void main(String[] args) {
String str1 = "fujiatian";
String str2 = "fujiatian";
System.out.println(str1==str2);//true
System.out.println(str1.equals(str2));//true

String str3 = new String("fujiatian");
String str4 = new String ("fujiatian");
System.out.println(str3==str4);//false
System.out.println(str3.equals(str4));//true
}
}

3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

不一定;hashCode()相同,只能说明两个对象在散列存储结构中存放在同一个位置;如果要判断两个对象是否真正相等,必须通过equals方法


​ 这里需要详细了解hashCode()和equals()的基本原理,equals()上面已经讲过了,下面详细讲一下hashCode()方法,这里参考大佬(小刺猬喜歡獨角獸)的文章

1、hashCode简介

public int hashCode():hashCode是根类Obeject中的方法。默认情况下,Object中的hashCode() 返回对象的32位jvm内存地址。也就是说如果对象不重写该方法,则返回相应对象的32为JVM内存地址。

2、hashCode注意点

关于hashCode方法,一致的约定是:
1、重写了euqls方法的对象必须同时重写hashCode()方法。
2、如果两个对象equals相等,那么这两个对象的HashCode一定也相同

3、如果两个对象的HashCode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置

3、hashCode作用

​ 从Object角度看,JVM每new一个Object,它都会将这个Object丢到一个Hash表中去,这样的话,下次做Object的比较或者取这个对象的时候(读取过程),它会根据对象的HashCode再从Hash表中取这个对象。这样做的目的是提高取对象的效率。若HashCode相同再去调用equal。

HashCode是用于查找使用的,而equals是用于比较两个对象的是否相等的。

4、为什么重写

实际开发的过程中在hashmap或者hashset里如果不重写的hashcode和equals方法的话会导致我们存对象的时候,把对象存进去了,取的时候却取不到想要的对象。
重写了hashcode和equals方法可以迅速的在hashmap中找到键的位置;
1、重写hashcode是为了保证相同的对象会有相同的hashcode;
2、重写equals是为了保证在发生冲突的情况下取得到Entry对象(也可以理解是key或是元素);

4.final 在 java 中有什么作用?

凡是引用final关键字的地方皆不可修改

final在java编程中可以用于修饰类类熟悉类方法

  1. 修饰类: 表示该类不可被继承
  2. 修饰方法:表示该方法不可被重写(@override)
  3. 修饰变量:表示变量只能一次赋值以后值不能被修改,只能当常量使用

5.java 中的 Math.round(-1.5) 等于多少?

​ Math.round(1.5)的返回值是2,Math.round(-1.5)的返回值是-1。四舍五入的原理是在参数上加0.5然后做向下取整

扩展:

  1. ​ round:返回四舍五入,负.5小数返回较大整数,如-1.5返回-1。
  2. ​ ceil:返回小数所在两整数间的较大值,如-1.5返回-1。
  3. ​ tail:返回小数所在两整数间的较小值,如-1.5返回-2。

6.String 属于基础的数据类型吗?

​ String不是基本的数据类型,是final修饰的java类,属于引用类型,所谓的引用类型包括:类,接口,数组…

java中的基本类型一共有 8 个,它们分别为

  • 字符类型:byte,char
  • 基本整型:short,int,long (默认值都是为0)
  • 浮点型:float,double (默认值为0.0)
  • 布尔类型:boolean (默认值为false)

7.java 中操作字符串都有哪些类?它们之间有什么区别?

一般有三类 : StringStringBufferStringBuilder

  1. String:是用final修饰的,不可变字符序列,每次对String类型的改变都会生成一个新的对象;不频繁的字符串操作使用 String
  2. StringBuffer:可变字符序列,对字符串的操作的方法都加了同步synchronized处理,保证线程安全,可用于多线程;
  3. StringBuilder:可变字符序列,同步sychronized修饰,单线程,线程不安全、效率高

总结:

从效率上来说,StringBulider > StringBuffer >> String.concat > “+”,在循环拼接字符串的场景中,使用StringBuilder 和StringBuffer,临时变量应使用StringBuilder(效率更高),避用StringBuffer ,千万不要使用String类型,效率低下;在循环内部,不要使用append(a+b)的形式,而应改为append(a).append(b)

8.String str=”str1”与 String str=new String(“str1”)一样吗?

不一样。

  • String str1="str1":Java 虚拟机会将其分配到常量池中
    • 在栈中创建str1的引用,初始化的时候查看常量池是否有相同的Unicode编码的字符串常量,有点话将地址指向过去,没有的话创建一个’str1’,然后将地址指过去;
    • 如果是重新赋值,也是新创建对象,然后将新建的对象地址进行指向到str1变量中
  • String str=new String(“i”) :分到堆内存中
    • String str1 = new String(“str1”); String str2 = new String(“str1”);str2不会指向之前创建的对象,而是重新创建一个对象。
    • 在常量池中创建内容为“str1”的对象,在堆中创建内容为“str1”的对象

最后代码展示:

1
2
3
4
5
6
7
8
9
10
11
12
13
  String str1 = "str1";
        String str2 = "str1";
        String str3 = new String("str1");
        String str4 = new String("str1");
        System.out.println(str1==str2);//true地址一样
        System.out.println(str3==str4);//false,但地址不一样
        System.out.println(str3.equals(str4));//true,值一样
        System.out.println(str2.equals(str3));//true,值一样
        System.out.println((str1+"a")==(str2+"a"));//false;进行了+连接地址不一样
        System.out.println((str1+"a").equals((str2+"a")));//true;进行了+连接值一样
---------------------
版权声明:本文为CSDN博主「追魂嫖客」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/siqiangming/article/details/74452215

参考链接 https://blog.csdn.net/siqiangming/article/details/74452215

9.如何将字符串反转?

比如将字符串’abcd’反转为’dcba’

​ 可以使用三种方法实现

  1. 利用 StringBuffer 或 StringBuilder 的 rweverse 成员方法:

    1
    2
    3
    4
    // StringBuffer
    public static String reverse1(String str) {
    return new StringBuilder(str).reverse().toString();
    }
  2. 利用 String 的 toCharArray 方法先将字符串转化为 char 类型数组,然后将各个字符进行重新拼接:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // toCharArray
    public static String reverse2(String str) {
    char[] chars = str.toCharArray();
    String reverse = "";
    for (int i = chars.length - 1; i >= 0; i--) {
    reverse += chars[i];
    }
    return reverse;
    }
  3. 利用 String 的 CharAt 方法取出字符串中的各个字符:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // charAt
    public static String reverse3(String str) {
    String reverse = "";
    int length = str.length();
    for (int i = 0; i < length; i++) {
    reverse = str.charAt(i) + reverse;
    }
    return reverse;
    }

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

这里最全最直接的方法是查看String.java 文件,能够详细指导所有方法。这里常用的方法比较普遍,借用大佬的博客即可

  1. int length();  语法:字符串变量名.length();  返回值为 int 类型。得到一个字符串的字符个数(中、英、空格、转义字符皆为字符,计入长度)

    1
    2
    3
    4
    5
            String a="挨点aidian \t\n";
    int l = a.length();
    System.out.println(l);

    运行结果:11
  1. char charAt(值);  语法 :字符串名.charAt(值);  返回值为 char 类型。从字符串中取出指定位置的字符 ;说明一下,这里是 根据值获取位置索引

    1
    2
    3
    4
    5
         String str="张三疯";
    char c = str.charAt(2);
    System.out.println("指定字符为:" + c);

    运行结果:指定字符为:疯
  2. char toCharArray();  语法 :字符串名.toCharArray();  返回值为 char 数组类型。将字符串变成一个字符数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    String str="张三疯"
    char c[] = str.toCharArray();
    for (int i = 0; i < c.length; i++)
    System.out.println("转为数组输出:" + c[i]);

    运行结果:
    转为数组输出:张
    转为数组输出:三
    转为数组输出:疯
  3. int indexOf(“字符”)  语法 :字符串名.indexOf(“字符”);字符串名.indexOf(“字符”,值);查找一个指定的字符串是否存在,返回的是字符串的位置,如果不存在,则返回-1; int lastIndexOf(“字符”) 得到指定内容最后一次出现的下标

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    String str="只为挨你近一点";
    int a1 = str.indexOf("你");// 查找字符你的位置
    int a2 = str.indexOf("为", 2);// 查找为的位置,从第3个开始查找
    int a3 = str.lastIndexOf("点");
    System.out.println("你的位置为:" + a1);
    System.out.println("为的位置为:" + a2);
    System.out.println("点最后出现的位置为:" + a3);
    运行结果:
    你的位置为:3

    为的位置为:-1

    点最后出现的位置为:7
  4. toUpperCase(); toLowerCase();字符串大小写的转换

    1
    2
    3
    4
    5
    6
    7
    String str="hello world";
    System.out.println("将字符串转大写为:" + str.toUpperCase());
    System.out.println("将字符串转换成小写为:" + str.toUpperCase().toLowerCase());

    运算结果:
    将字符串转大写为:HELLO WORLD
    将字符串转换成小写为:hello world
  5. String[] split(“字符”)  根据给定的正则表达式的匹配来拆分此字符串。形成一个新的String数组

    1
    2
    3
    4
    5
    6
    String str = "boo:and:foo";
    String[] arr1 = str.split(":");
    String[] arr2 = str.split("o");
    运行结果:
      arr1  //{ "boo", "and", "foo" }
      arr2  //{ "b", "", ":and:f" }
  6. boolean equals(Object anObject)  语法 :字符串变量名.equals(字符串变量名);  返回值为布尔类型。

    1
    2
    3
          String str = "hello";
    String str1="world";
    System.out.println(str.equals(str1)); //false
  7. trim();  去掉字符串左右空格  replace(char oldChar,char newChar);新字符替换旧字符,也可以达到去空格的效果一种。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    String str = " 挨点博客 ";
    System.out.println("去掉左右空格后:" + str.trim());

    运行结果:
      去掉左右空格后:挨点博客



    第二种:
    String str = " 挨点博客 ";
    System.out.println("去掉左右空格后:" + str.replace(" ",""));

    运行结果:
      去掉左右空格后:挨点博客
  8. String substring(int beginIndex,int endIndex)  截取字符串 

    1
    2
    3
    4
    5
    6
    7
      String str = "123挨点博客456";  
    System.out.println("截取后的字符为:" + str.substring(0,3));//截取0-3个位置的内容 不含3
    System.out.println("截取后字符为:" + str.substring(2));// 从第3个位置开始截取 含2

    运行结果:
        截取后的字符为:123
        截取后字符为:3挨点博客456
  9. equalsIgnoreCase(String) 忽略大小写的比较两个字符串的值是否一模一样,返回一个布尔值

    1
    2
    3
             String str = "HELLO WORLd";
    String str1 = "hello world";
    System.out.println(str.equalsIgnoreCase(str1));//true
  10. contains(String) 判断一个字符串里面是否包含指定的内容,返回一个布尔值

    1
    2
    3
    String str = "HELLO WORLd";
    String str1 = "WO";
    System.out.println(str.contains(str1));//true
  11. startsWith(String)  测试此字符串是否以指定的前缀开始。返回一个布尔值

    1
    2
    3
    4
    5
    String str = "HELLO WORLd";
    String str1 = "HE";
    String str2 = "LL";
    System.out.println(str.startsWith(str1));//true
    System.out.println(str.startsWith(str2));//false
  12. replaceAll(String,String) 将某个内容全部替换成指定内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
            String Str = new String("www.google.com");
    System.out.println(Str.replaceAll("(.*)google(.*)", "runoob" ));,
    //匹配成功返回值 :runoob
    //replaceFirst()
    String Str = new String("hello runoob,I am from runoob。");

    System.out.print("返回值 :" );
    System.out.println(Str.replaceFirst("runoob", "google" ));
    System.out.print("返回值 :" );
    System.out.println(Str.replaceFirst("(.*)runoob(.*)", "google" ));,,
您的打赏,是我创作的动力,谢谢支持。
0%