JVM内存模型
线程共享区域有:方法区,堆
线程私有区域有:虚拟机栈,本地方法栈,程序计数器。
具体每块区域上保存什么样的数据在图上已经标注了。
可以看到在方法区会保存运行时常量池,
所以String的常量池就存放在方法区上。
原理讲解
String a = "abc";
解释:
做此操作时,会先去常量池中寻找是否存在“abc”字符串,如果存在就直接将引用指向常亮池中存在的字符串,如果不存在,就在常量池中创建“abc”字符串。
String f = new String("123");
解释:
执行new操作,会在堆内存中创建新的对象。
String d = "123";
String e = "123";
String g = d + e;
解释:
执行字符串的拼接操作,其内部是执行原理是:先创建一个空的StringBuilder实例,然后执行append操作进行字符串的连接,然后调用toString方法返回一个字符串。
而toString方法的内部是执行的new String()操作,创建一个新的String实例,放在堆内存中。
创建StringBuilder实例,执行append方法等流程都可通过将代码进行javap操作看到。
StringBuilder的toString方法代码如下:
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
常见的笔试题
String flag_one = "123";
String flag_two = new String("123");
String flag_three = "456";
String flag_four = "123456";
boolean a = flag_one == flag_two; //false
boolean b = flag_one.equals(flag_two); //true
boolean c = flag_one+flag_three == flag_four; //false
boolean d = flag_four.equals(flag_one+flag_three); //true
解释:
a: flag_one是存在于常量池中的,存在于方法区;flag_two是存在于堆内存中的;==操作是比较的两个实例的地址,所以为false。
b: equals操作是比较的值,所以返回true。
c: flag_one+flag_three做字符串的拼接操作,底层实际是创建的StringBuilder实例然后执行的appen方法进行字符串的拼接操作,最后调用的toString方法(new String())操作,所以还是存在于堆内存中。而flag_four是存在于方法去中的常量池中。比较两者的地址所以返回false。
d: equals方法比较两者的值,所以返回true。
闲谈
eleven最近在换工作呢,还是比较有感触吧,已经找了一周的工作了,也拿到了几个offer。总结起来就是互联网公司的门槛还是比较高的,因为我之前就是一直做传统软件,也因为技术能力不达标吧,所以 很难拿到互联网公司的面试邀请。基本上还是一些传统软件公司,当然还有很多外包公司抛出橄榄枝。
新的目标工作是在西安,以后也有打算在西安定居的样子。这一周的面试下来,eleven一年的工作经验在西安只能拿到6.5的样子,在往上提估计很难了。所以如果自己想要高工资的话还是呆在北上广吧。除了一线城市,别的城市的工资基本上都是这样的一个水平。我之前工作在济南,济南的工资水平也是差不多这个样子。
其实平时还是很迷茫的,当然我自己心里也是比较浮躁吧。总是感觉未来很迷茫,也觉得自己很垃圾,没有那么优秀。反正不管怎样吧,在西安工作后平时多看书吧,多了解一些其他的行业,多接触一些不同性格的人群。目的就是让自己能够在之后多一个选择吧。
加油共勉!!
这是我自己的公众号,平时会推送一些校招信息和大厂内推信息,感兴趣的可以关注一下。
也可后台留言给小编获取 “100G免费的JAVA入门到精通” 的视频教程