String面试常见问题

String面试常见问题

  1. == 和equals的区别

    答:== :比较基本类型的时候 == 比较的是值是否相同

    ​ 比较引用类型的时候==比较的是引用是否相同

    ​ equals:本质上也是 == ,只不过String 和 Integer 等重写了equals方法 ,把他变成了值的比较

  2. String 的3大核心机制

    • 不变性 String 是一个 immutable 模式的对象,不变模式的主要作用是当一个对象需要被多线程共享并且频繁访问时,可以保持数据的不变性
    • 常量池优化 String对象创建后会在字符串常量池(也是堆内存的一部分)中进行缓存,下次创建同样的对象时,会直接返回缓存的引用
    • final: String类不可被继承,提高了系统的安全性
  3. String不是基本数据类型

  4. String的实例化有两种方式

    • 直接赋值

      String str1 = "hello" ;
      
    • 通过构造函数,可以直接将字符串的值传入,也可以传入一个char数组

      String str2 = new String("hello");
      
  5. equals方法(Object继承而来,但是进行了重写)

    比较字符串的值

    源码理解: 先==比较,如果相等就返回true,不相等则转成char数组,先比较长度,如果长度不等则返回false,长度相等则循环继续比较每一位的char字符是否相等,遇到不相等的直接返回false,如果全相等则返回true.

  6. intern()方法

    当调用某个字符串对象的intern()方法时,会去字符串常量池中去寻找,润过已经存在一个值相等的字符串对象的话,则直接返回该对象的引用。如果不存在则在常量池中去创建字符串对象

  7. String常用的方法

    方法描述
    public String()创建一个值为“”的对象
    public String(String original)创建一个值为original的对象
    public String(char value[] , int offset , int count)将一个char[]转为字符串对象(可以指定范围)
    public String (byte[] bytes , int offset,int count)将一个byte[]转成字符串类型(可以指定范围)
    public int length()返回字符串的长度
    public boolean isEmpty()判断字符串是否为空
    public char charAt(int index)返回字符串中指定位置的字符
    public byte[] getBytes()将字符串转为byte型数组
    public boolean equals(Object anObject)判断两个字符串是否相等
    public boolean equalsIgnoreCase(String anotherString)判断两个自负床是否相等并且忽略大小写
    public int compareTo(String anotherString)按字典顺序比较两个字符串,直到有不一样的字符时,返回ASCII码差值,如果前几位相同,只是长度不一样,则返回长度差值
    public boolean startsWith(String prefix)判断是否以指定的值开头
    public boolean endsWith(String prefix)判断是否以指定的值结尾
    public int hashCode()获取字符串的散列值
    public int indexOf(String str,int fromIndex)从指定位置开始查找指定字符的位置
    public String substring
    (int beginIndex,int endIndex)
    截取字符串从指定位置开始到指定位置结束
    public String concat(String str)追加字符串
    public String replaceAll(String regex,String replacement)替换字符串
    public String[] split(String regex)用指定字符串对目标字符串进行分割,返回数组,同时支持正则表达式
    public String toLowerCase()将字符串转为小写
    public String toUpperCase()将字符串转成大写
    public char[] toCharArray()将字符串转为char型数组

    重点:

    • 字符串的截取
    • 字符串分割
  8. 面试题:

    //下列代码的运行结果是
    String str1 = "Hello World";
    String str2 = "Hello"+ " World";
    System.out.println(str1 == str2);
    //答案:true
    /*
    str1的“Hello World”存到了常量池中,栈内存中变量str1引用常量池的“Hello World”
    str2也是先去查看常量池中是否存在“Hello World”,存在则栈中直接引用常量池中的“Hello World”
    */
    
    //下列代码的运行结果是
    String str1 = "Hello World";
    String str2 = "Hello";
    str2+=" World"
    System.out.println(str1 == str2);
    //答案:false
    /*str2是变量,变量加上一个常量则也为变量,值改变后存在于堆内存中,str2引用堆内存中的对象,而不是和str1一样引用的是常量池中的“Hello World”,所以两者的地址值不一样,故为false*/
    
    //下列代码的运行结果是
    String str1 = "Hello World";
    String str2 = "Hello";
    String str3 = str2 + " World";
    System.out.println(str1 == str3);
    //答案:false(同上)
    /*str2是变量,变量加上一个常量则也为变量,值改变后存在于堆内存中,str3引用堆内存中的对象,而不是和str1一样引用的是常量池中的“Hello World”,所以两者的地址值不一样,故为false*/
    
    //下列代码的运行结果是
    String str1 = "Hello World";
    final String str2 = "Hello";
    String str3 = str2 + " World";
    System.out.println(str1 == str3);
    //答案:true
    /*
    str2有final修饰,所以str2视为一个常量,str3则也为一个常量,str3引用常量池中的对象,和str1一样引用的是常量池中的“Hello World”,所以两者的引用相同,故为true
    */
    
    //下列代码的运行结果是
    String str1 = "Hello World";
    final String str2 = new String("Hello");
    String str3 = str2 + " World";
    System.out.println(str1 == str3);
    //答案:false
    /*
    str2有final修饰,但是构造函数创建的String对象存于堆内存中,而str1引用的是常量池中的“Hello World”,所以两者的引用不相同,故为false
    */
    
    //下列代码的运行结果是
    String str1 = "Hello World";
    String str2 = "Hello";
    String str3 = " World";
    String str4 = str2+str3;
    System.out.println(str1 == str4);
    System.out.println(str1 == str4.intern());
    //答案:false true
    /*
    str1引用的是常量池中的“Hello World” ,str4引用的是堆内存中的“Hello World” , 所以str1 != str4
    str4.intern()方法,先去查看常量池中是否存在“Hello World”,存在则直接返回常量池中的(不存在则创建然后返回),所以str4.intern()同str1的引用的都是常量池中的“Hello World” 故 str1 == str4.intern()
    */
    
    
    **问:什么是字符串常量池(String Pool)?**
    
    答:位于Java堆内存中的,用来存储维护String常量的。
    String对象创建后会在字符串常量中进行缓存,下次创建同样的对象时,会直接返回缓存的引用
    
    问:String是线程安全的吗?
    
    答:安全的String是不可变的,一旦修改就和原先不是一个对象了。保证多线程访问时的一致性。
    
    **问:在使用HashMap的时候,用String做key有什么好处?**
    
    答:HashMap通过key的hashCode值去读取value的,String作为key时已经存到常量池中,hashCode已经被计
    算出来,HashMap每次取出的时候不用再次计算hashCode值,H后面再用的时候直接用就可以了。
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值