欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA开发面试题&String篇&第一部分

程序员文章站 2022-06-12 19:45:14
...


面试知识点内容较多,本文为 String篇 的 第一部分,string篇预计 1篇.
本文应公众号用户需求发布,本篇为 String篇 ,过于基础,免费,请需要者自取。

点击跳转上一篇章, 基础篇 第一部分: https://blog.csdn.net/zsk1996888/article/details/109600251.
点击跳转下一篇,集合篇第一部分: link.

1.下面程序的运行结果是()(选择一项)

String str1="hello";
 
String str2=new String("hello");
 
System.out.println(str1==str2);
选项 内容
A true
B false
C hello
D he

答案:B
分析:str1没有使用new关键字,在堆中没有开辟空间,其值”hello”在常量池中,str2使用new关键字创建了一个对象,在堆中开辟了空间,”==”比较的是对象的引用,即内存地址,所以str1与str2两个对象的内存地址是不相同的

2.Java语言中,String类中的indexOf()方法返回值的类型是()

选项 内容
A int32
B int16
C int
D long

答案:C。语法bai为strObj.indexOf(subString[, startIndex])。
参数:
1、strObj:必选项du。String 对象或文字。
2、subString:必选项。要在 String 对象中查找的子字符串。
3、starIndex:可选项。该整数值指出在 String 对象内开始查找的索引。如果省略,则从字符串的开始处查。

3.给定以下代码,程序的运行结果是 ()

public class Example {
String str=new String("good");
char [] ch={'a','b','c'};
 
public static void main(String[] args) {
Example ex=new Example();
ex.change(ex.str, ex.ch);
System.out.print(ex.str+"and");
System.out.print(ex.ch);
}
 
public void change(String  str,char ch[]){
str="test ok";
ch[0]='g';
}
}

答案:goodandgbc
分析:在方法调用时,在change方法中对str的值进行修改,是将str指向了常量江池中的”test ok”,而主方法中的ex.str仍然指向的是常量池中的”good”。字符型数组在方法调用时,将主方法中ex.ch的引用传递给change方法中的ch,指向是堆中的同一堆空间,所以修改ch[0]的时候,ex.ch可以看到相同的修改后的结果

4.执行下列代码后,哪个结论是正确的()(选择两项)

String[] s=new String[10];
选项 内容
A s[10]为””
B s[9]为null
C s[0]为未定义
D s.length为10

答案:BD
分析: 引用数据类型的默认值均为null
s.length数组的长度

5.实现String类的replaceAll方法

思路说明:replaceAll方法的本质是使用正则表达式进行匹配,最终调用的其实是Matcher对象的replaceAll方法。

import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class TestStringReplaceAll {
public static void main(String[] args) {
String str = "a1s2d3f4h5j6k7";
// 将字符串中的数字全部替换为0
System.out.println(replaceAll(str, "\\d", "0"));
}
 
/**
 * @param str:源字符串
 * @param regex:正则表达式
 * @param newStr:替换后的子字符串
 * @return 返回替换成功后的字符串
 */
public static String replaceAll(String str, String regex, String newStr) {
Pattern pattern = Pattern.compile(regex);
Matcher mathcer = pattern.matcher(str);
String reslut = mathcer.replaceAll(newStr);
return reslut;
}
}

6.在“=”后填写适当的内容:

String []a=new String[10];
则:a[0]~a[9]=(空一);
a.length=10;
如果是int[]a=new int[10];
则:a[0]~a[9]= (空二
a.length= (空三
答案:null、0、10

7.是否可以继承String类?

答:不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。

public final class String implements java.io.Serializable,
Comparable< String>, CharSequence

8.String类为什么是final的

答:1) 为了效率。若允许被继承,则其高度的被使用率可能会降低程序的性能。
2)为了安全。JDK中提供的好多核心类比如String,这类的类的内部好多方法的实现都不是java编程语言本身编写的,好多方法都是调用的操作系统本地的API,这就是著名的“本地方法调用”,也只有这样才能做事,这种类是非常底层的,和操作系统交流频繁的,那么如果这种类可以被继承的话,如果我们再把它的方法重写了,往操作系统内部写入一段具有恶意攻击性质的代码什么的,这不就成了核心病毒了么?不希望别人改,这个类就像一个工具一样,类的提供者给我们提供了, 就希望我们直接用就完了,不想让我们随便能改,其实说白了还是安全性,如果随便能改了,那么java编写的程序肯定就很不稳定,你可以保证自己不乱改, 但是将来一个项目好多人来做,管不了别人,再说有时候万一疏忽了呢?他也不是估计的, 所以这个安全性是很重要的,java和C++相比,优点之一就包括这一点。

9.给定两个字符串s和t, 写一个函数来决定是否t是s的重组词。你可以假设字符串只包含小写字母。

方法一:转为数组,利用现成的数组方法进行整理,再判断

class Solution {
    public boolean isAnagram(String s, String t) {
        
        char[] ss = s.toCharArray();//将s字符串转换为数组
        char[] tt = t.toCharArray();//将t字符串转换为数组
        
        if(ss.length != tt.length) return false;//长度不等,直接pass
        
        Arrays.sort(ss);//排列组合
        Arrays.sort(tt);
        
        return Arrays.equals(ss,tt);//看他们各自拼接的组合有无相等的可能
        
    }
}

方法二:用for遍历,直接判断ASCII码

public class Solution {
    public boolean isAnagram(String s, String t) {
        if(s.length()!=t.length())
            return false;
        int bit[] = new int[26];
        for(int i=0;i<s.length();i++){
            bit[s.charAt(i)-'a']++;
        }
 
        for(int i=0;i<s.length();i++){
            if(--bit[t.charAt(i)-'a']<0)
                return false;
        }
        return true;
    }
}

附ASCII码表: http://ascii.911cha.com/.
JAVA开发面试题&String篇&第一部分

10.String s=new String(“abc”);创建了几个String对象?

答: 两个或一个,”abc”对应一个对象,这个对象放在字符串常量缓冲区,常量”abc”不管出现多少遍,都是缓冲区中的那一个。New String每写一遍,就创建一个新的对象,它依据那个常量”abc”对象的内容来创建出一个新String对象。如果以前就用过’abc’,这句代表就不会创建”abc”自己了,直接从缓冲区拿。

11.输出结果?

String str1=“hello”;
Sring str2=“he”+new String(“llo”);
Sysem.out.println(str1==str2));
Sysem.out.println(str.equal(str2));

false
true
注:相似题目点击: https://blog.csdn.net/skisqibao/article/details/81155454.

12.下面哪个是正确的()

选项 内容
A String temp[ ] = new String{“a”,”b”,”c”};
B String temp[ ] = {“a”,”b”,”c”};
C String temp= {“a”,”b”,”c”};
D String[ ] temp = {“a”,”b”,”c”};

答案:BD。数组的创建参见博文: https://blog.csdn.net/qq_44518192/article/details/107085678.

13.字符串如何转换为int类型

public class Test {
public static void main(String[] args) {
 //方式一
 int num=Integer.parseInt("123");
 //方式二
 int num2=Integer.valueOf("123");
 System.out.println(num+"  "+num2);
}
}

14.写一个方法,实现字符串的反转,如:输入abc,输出cba

public class Test {
public static void main(String[] args) {
String result=reverse("abc");
System.out.println(result);
}
public static String reverse(String str){
StringBuilder result=new StringBuilder("");
char[] chArra=str.toCharArray();
for(int i=chArra.length-1;i>=0;i--){
char ch=chArra[i];
result.append(ch);
}
return result.toString();
}
}

在网上发现一篇写的不错的360文档,点击查看: http://www.360doc.com/content/10/0628/22/380362_35815752.shtml.

15.编写java,将“I follow Bill Gate.Tom Gate.John Gate”中的“Gate”全部替换为“Gates”

public classDemo1 {
	publicstaticvoid main(String[] args) {
		String s="I follow Bill Gate.Tom Gate.John Gate";
		System.out.println(s);
		s=s.replaceAll("Gate","Gates");
		System.out.println(s);
	}
}

16.String 是最基本的数据类型吗?

答: 不是 。Java中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type)和枚举类型(enumeration type),剩下的都是引用类型(reference type)。

17.String 和StringBuilder、StringBuffer 的区别?

答: Java 平台提供了两种类型的字符串:String和StringBuffer / StringBuilder
相同点:
它们都可以储存和操作字符串,同时三者都使用final修饰,都属于终结类不能派生子类,操作的相关方法也类似例如获取字符串长度等;
不同点:
其中String是只读字符串,也就意味着String引用的字符串内容是不能被改变的,而StringBuffer和StringBuilder类表示的字符串对象可以直接进行修改,在修改的同时地址值不会发生改变。StringBuilder是JDK 1.5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方面都没有被synchronized修饰,因此它的效率也比StringBuffer略高。在此重点说明一下,String、StringBuffer、StringBuilder三者类型不一样,无法使用equals()方法比较其字符串内容是否一样!
补充1:有一个面试题问:有没有哪种情况用+做字符串连接比调用StringBuffer / StringBuilder对象的append方法性能更好?答:如果连接后得到的字符串在静态存储区中是早已存在的,那么用+做字符串连接是优于StringBuffer / StringBuilder的append方法的。
补充2:下面也是一个面试题,问程序的输出,看看自己能不能说出正确答案。

package com.bjsxt;
public class smallT {
public static void main(String[] args) {
        String a = "Programming";
        String b = new String("Programming");
        String c = "Program" + "ming";
              System.out.println(a == b);
              System.out.println(a == c);
               System.out.println(a.equals(b));
               System.out.println(a.equals(c));
               System.out.println(a.intern() == b.intern());
}
}

解析:
String类存在intern()方法,含义如下:返回字符串对象的规范化表示形式。它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern()才为 true。
字符串比较分为两种形式,一种使用比较运算符”==”比较,他们比较的是各自的字符串在内存当中的地址值是否相同;一种是使用equals()方法进行比较,比较的是两个字符串的内容是否相同!

结果如下:

a == b-->false
a == c-->true
a.equals(b)-->true
a.equals(c)-->true
a.intern() == b.intern()-->true

对应 内存模型 图:
JAVA开发面试题&String篇&第一部分

18.String s=“Hello”;s=s+“world!”;执行后,是否是对前面s指向空间内容的修改?

答:不是对前面s指向空间内容的直接修改。
因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是 “Hello”,然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。
通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为 String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。
同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:

public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}

而非s = new String("Initial Value");
后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。
上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。
至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即 StringBuffer。参见《Thinking in Java》第370-380页。

19.String s = new String(“xyz”);创建几个String Object?

答:两个或一个,”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”不管出现多少遍,都是缓冲区中的那一个。New String每写一遍,就创建一个新的对象,它依据那个常量”xyz”对象的内容来创建出一个新String对象。如果以前就用过’xyz’,这句代表就不会创建”xyz”自己了,直接从缓冲区拿。

20.下面这条语句一共创建了多少个对象:String s=“a”+“b”+“c”+“d”;

答:对于如下代码:

String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");

第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以 对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。
题目中的第一行代码被编译器在编译时优化后,相当于直接定义一个”abcd”的字符串,所以,上面的代码应该只创建了一个String对象。
写如下两行代码,

String s = "a" + "b" + "c" + "d";
System.out.println(s == "abcd");

最终打印的结果应该为true。