2021春招必备Java面试题大全(四)Java-String字符串部分 持续更新

  1. 字符型常量和字符串常量的区别
  • 形式上: 字符常量是单引号引起的一个字符 字符串常量是双引号引起的若干个字符
  • 含义上: 字符常量相当于一个整形值(ASCII值),可以参加表达式运算 字符串常量代表一个地址值(该字
    符串在内存中存放位置)
  • 占内存大小 字符常量只占一个字节 字符串常量占若干个字节(至少一个字符结束标志)

字符串在jdk8之前底层使用的是一个char的数组
在jdk8之后使用的是一个byte的数组

  1. 什么是字符串常量池?

字符串常量池位于堆内存中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存 储相同的字符串,在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回 它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。

  1. String有哪些特性
  • 不可变性 : String字符串是一个只读字符串 对它进行任何操作,其实都是创建一个新的对象,再把引用指向该对象。不变模式的主要作用在于当一个对象需要被多线程共享并 频繁访问时,可以保证数据的一致性。
  1. String为什么是不可变的?

简单来说就是String类利用了final修饰的char类型数组存储字符

/** The value is used for character storage. */
private final char value[];

原来String的内容是不变的,只是str由原来指向"Hello"的内存地址转为指向"Hello World"的内存地址而已,也就是说多开辟了一块内存区域给"Hello World"字符串。

反射也可以破坏它的不可变性

  1. String s = new String(“xyz”);创建了几个字符串对象

两个对象,一个是静态区的"xyz",一个是用new创建在堆上的对象。

  1. String 类的常用方法都有那些?
  • charAt(i) 返回第 I - 1个下标的元素
  • subString(a,b) 从第a个位置返回b个元素
  • indexOf(); 返回制定索引的字符
  • replace() 字符串替换
  • trim()。去掉字符串两边的空白部分
  • split() 把一个字符串按照某个符号分成一个数组
  • getBytes() 返回字符串的byte数组
  • toLowerCase()。小写
  • toUpperCase() 大写
  • length() 获取长度
  1. 在使用 HashMap 的时候,用 String 做 key 有什么好处?

HashMap 内部实现是通过 key 的 hashcode 来确定 value 的存储位置,因为字符串是不可变的,所以当创建字符串时,它的 hashcode 被缓存下来,不需要再次计算,所以相比于其他对象更快。

  1. String和StringBuffer、StringBuilder的区别是什么?String为什么是不可 变的
  • 可变性: String类中使用字符数组保存字符串,private final char value[],所以string对象是不可变的。 StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字 符数组保存字符串,char[] value,这两种对象都是可变的。
  • 线程安全性: String中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder是StringBuilder 与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、 indexOf等公共方法。StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全 的。StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。
  • 性能:每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对象。 StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情 况下使用StirngBuilder 相比使用StringBuffer 仅能获得10%~15% 左右的性能提升,但却要冒多线程不 安全的风险。
  • 小总结:
    如果要操作少量的数据用 = String
    单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
    多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
  1. Integer a= 127 与 Integer b = 127相等吗
public static void main(String[] args) {
      Integer a = new Integer(3);
	Integer b = 3; // 将3自动装箱成Integer类型 int c = 3;
	System.out.println(a == b); // false 两个引用没有引用同一对象 System.out.println(a == c); // true a自动拆箱成int类型再和c比较 System.out.println(b == c); // true
	Integer a1 = 128;
	Integer b1 = 128; System.out.println(a1 == b1); // false
	Integer a2 = 127;
	Integer b2 = 127; System.out.println(a2 == b2); // true
}

如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用常量
池中的Integer对象,超过范围 a1==b1的结果是false;

  1. jdk165以后对StringBuffer和锁进行的一些优化
  • 锁粗化 lock eliminate
  • 锁消除
    在插入数据的一个循环中一直插入数据 那么StringBuffer就有一个锁消除的机制 避免重复加入的时候影响效率

你可能感兴趣的:(jvm,java面试,2021春招,字符串,java)