2021Java 笔试题总结!Java 个人学习之旅 (第十天)
前言
JVM 内存模型一共包括三个部分:
堆 ( Java 代码可及的 Java 堆 和 JVM 自身使用的方法区)、
栈 ( 服务 Java 方法的虚拟机栈 和 服务 Native 方法的本地方法栈 )
保证程序在多线程环境下能够连续执行的程序计数器
特别地,我们当时就提到 Java 堆是进行垃圾回收的主要区域,故其也被称为 GC 堆;而方法区也有一个不太严谨的表述,就是永久代。总的来说,堆 (包括 Java 堆 和 方法区)是 垃圾回收的主要对象,特别是 Java 堆。
实际上,Java 技术体系中所提倡的 自动内存管理 最终可以归结为自动化地解决了两个问题:给对象分配内存 以及回收分配给对象的内存,而且这两个问题针对的内存区域就是 Java 内存模型中的堆区。关于对象分配内存问题,笔者的博文《JVM 内存模型概述》已经阐述了 如何划分可用空间及其涉及到的线程安全问题,本文将结合垃圾回收策略进一步给出 内存分配规则。另外,我们知道垃圾回收机制是 Java 语言一个显著的特点,其可以有效的防止内存泄露、保证内存的有效使用,从而使得 Java 程序员在编写程序的时候不再需要考虑内存管理问题。Java 垃圾回收机制要考虑的问题很复杂,本文阐述了其三个核心问题
说明:
当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的 value 进行赋值。
当对现的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的 value 进行赋值。
当调用 String 的 replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的 value 进行赋值。
代码举例:
上述代码的结果中的第一个比较结果完全是巧合,原因是字符串刚生成时调用的是同一块字符串常量池,而字符串常量池不会存在相同类型的常量,这也就意味着这两个字符串的地址值是相同的
如果我们再对 a 和 b 赋值然后再比较就能说明问题了
运行结果:
我们同时也可以发现,String 实例化的方式有两种:
通过字面量的方式定义
通过 new + 构造器的方式
第一种方式是在方法区的字符串常量池中直接开辟空间
第二种方式则是在堆生成对象,但引用的值还是来自字符串常量池
String 是引用类型,涉及到引用类型的变量的比较,都用 equals 方法比较稳妥
3. StringBuilder 和 StringBuffer:
==================================================================================================
StringBuilder 和 StringBuffer 都是用来拼接字符串的,后期会经常用到
首先看一下 String,StringBuilder,StringBuffer 三者之间的相关说明:
String:不可变的字符序列;底层使用 char[]存储
StringBuffer:可变的字符序列;线程安全的,效率低;底层使用 char[]存储
StringBuilder:可变的字符序列;jdk5.0 新增的,线程不安全的,效率高;底层使用 char[]存储
StringBuilder 和 StringBuffer 的内存解析:
以 StringBuffer 为例:
运行结果:
可以看到,StringBuilder 的初始容量为 16,没赋值时长度为零
当我们插入的字符串长度超过 StringBuilder 的初始容量时,StringBuilder 会进行扩容,扩容的方式是:
原长度*2 + 2,同时将旧的数组赋值到新的数组中
StringBuilder 和 StringBuffer 中的常用方法:
运行结果:
===============================================================================
声明方式:
这里实例化出来的对象打印出来是这样的
可以发现,虽然控制台打印的是正确的日期,但是可读性并不好,这时候可以用到 SimpleDateFormat 的方法
面试题总结
其它面试题(springboot、mybatis、并发、java 中高级面试总结等)
评论