阿里新零售部门面试总结

一、简历面

1、String, StringBuilder, StringBuffer的区别、使用场景

  • String数据内部结构用的是private final char[],是不可变的
    • 其实被private final修饰的是引用对象,只要引用不变,char[]数组中的内容是可以变的,但是String没有提供方法修改String,所以String是不可变的。但是,可以用反射把value的访问权限valueField.setAccessible(true);,那么外部就可以对value进行修改了。
    • 对String进行 “+=”操作 时,会生成一个新的String对象,让引用指向新的对象。如果经常改变String内容的场景,不要用String类型,内存中无引用的对象多了,容易造成内存泄漏GC就开始工作,性能会降低
  • 使用String类的concat与replace方法时,不会对原来的对象产生影响,他们会返回一个全新的对象
  • StringBuilder线程不安全,性能较好
  • StringBuffer线程安全,加了Synchronized同步锁,保证取数据或者修改数据时的线程安全性,性能较差

StringBuilder, StringBuffer的实现原理:

  • 用char[]存储数据,当char[]盛不下时,进行扩容,2倍扩容,避免总是扩容,默认数组的长度是16,如果能够预测char[]的长度的话,如果长度小于16,那么可以不设置,如果比16长的话,应该尽量设置长度,不然的话,会进行扩容,导致性能降低。

2、类加载过程假如自己定义了一个String类,且String在的包也是java.util.String,在这个String中只写main方法,main方法中打印一句“hello world”,那么程序运行的结果是?

  • 类加载过程:加载class文件;验证;准备;解析(将常量池内的符号转换成直接引用);初始化

初始化:为类变量进行初始化,执行类构造器<clinit>方法

<clinit>方法的特点:

  • 内容:包括变量的赋值操作和静态语句块(执行顺序,源文件中出现的顺序)
  • <clinit>方法实例构造器<init>方法不同,不需要显示调用父类构造器,jvm会保证执行子类的<clinit>方法前,父类的<clinit>方法已经被执行了,因此object的<clinit>方法最先执行
  • 如果一个类没对变量的赋值操作和静态代码块,就可以不为该类生成<clinit>方法
  • 只有一个线程执行<clinit>方法,其他线程阻塞

判断2个类是否相同:

首先看他们的类加载器是不是一样的,如果不一样,那么肯定不是同一个类

猜你喜欢

转载自blog.csdn.net/csdnlijingran/article/details/89946625