1.1字符常量和字符串常量的区别

  • 字符常量是单引号引起的一个字符,而字符串常量是双引号引起的0或多个字符
  • 字符常量可以参与一个整型值(ASCII值),可以参加表达式运算
  • 字符常量只占两个字节

Unicode编码字符集中包含汉字,编码占用两个字节,所以 char 类型的变量也能存储Unicode 中的编码的汉字。

1.2final 关键字有什么作用

  • final 修饰的类不能被继承,而final修饰的类中的所有成员方法隐式的指定为final,
  • final 修饰的方法不能被重写
  • final 修饰的变量叫做常量,如果为基本类型,在数值初始化后就不能改变;如果为引用类型的变量,在其初始化后则不能让其指向另一个对象

1.3& 和 && 的区别

  • & 运算符有两种方法: 1.按位与 2.逻辑与
  • && 运算符是短路与运算
    && 短路与作用指,在&& 表达式左边的值为false 时,右边的表达式会被直接短路掉,不会进行运算,效率更高
    注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。

1.4 用最有效率的方法算出2乘以8等于多少

使用位运算来实现效率最高。位运算符是对操作数以二进制比特位为单位进行操作和运算,操作数和结果都是整型数。
对于位运算符 << , 是将一个数左移 n 位,就相当于乘以了 2 的 n 次方,那么,一个数乘以 8 只要将其左移 3 位即可,位运算是 cpu 直接支持的,效率最高。

所以,2乘以8等于几的最效率的方法是 2 << 3

3. 基本数据类型

3.1 Java 中的几种基本数据类型

Name

Size(字节/位数)

Range

byte

1 byte / 8 bit

-128 ~ 127 之间

short

2 byte s / 16 bit

-32768~32767 之间,最大数据存储量是65536

int

4 bytes / 32 bit

-2^31 ~ 2^31-1 之间

long

8 bytes / 64 bit

-2^63 ~ 2^63-1

float

4 bytes / 32 bit

3.4e-45~1.4e38,直接赋值时必须在数字后加上 f 或 F

double

8 bytes / 64 bit

4.9e-324~1.8e308,赋值时可以加 d 或 D 也可以不加

boolean

只有 true 和 false 两个取值

char

2 bytes / 8 bit

存储Unicode码,用单引号赋值

默认自动转换:即从 byte,short, char 三者都会被默认的转到更高的精度类型,精度等级顺序如下 ( ==> int ==> long ==> float ==> double )

疑惑:为什么 float(4个字节)在 long(8个字节)后面
A: 它们底层的存储结构不同

B: float表示的数据范围比long范围要大

long:2^63-1

float:3.410^38 > 210^38 > 28^38 > 22^3^38

= 2*2^144 > 2^63 -1

3.2 java 中自动装箱与拆箱又是什么

将基本类型数据封装成对象的好处是可以用更多的功能方法操作该数据;

  • 自动装箱: 将基本类型用他们对应的引用类包装起来
  • 自动拆箱: 将包装类转换为基本数据类型

3.3 几种包装类类型的常量池(缓冲区)

在JDK5 以后,几种包装类对应的内部实现中通过使用相同的对象引用实现了缓存和重用。例如:Integer类型对于-128-127之间的数字是在缓冲区取的,所以对于在这个范围内的数值用双等号(==)比较是一致的,因为对应的内存地址是相同的。但对于不在这区间的数字是在堆中 new 出来的,所以地址空间不一样,也就不相等。

  1. Byte 、Short 、 Long 缓存范围 [-128,127]
  2. Character 缓存范围: [0,127]
  3. Boolean 直接返回 True Or False

3.4 字符长常量池

JVM 为了提高性能和减少内存的开销,在实例化字符串常量的时候进行了一些优化
4. 为字符串开辟一个字符串常量池,类似与缓存区
5. 创建字符串常量时,首先坚持字符串常量池中是否存在该字符串
6. 存在字符串,返回引用实例,不存在,实例化该字符串并放入池中
字符串常量池 存在于 JVM 的方法区,

3.4.1字符串对象的创建

面试题:String str4 = new String(“abc”) 创建多少个对象?
如果字符串常量池中包含 “abc" 对象,则直接返回对象引用
如果 字符串常量池中不包含 ”abc“ ,则在堆中 new 一个 String(“abc”)对象,并在字符串常量池中创建一个对象。
根据字面量,往往会提出这样的变式题:

String str1 = new String("A"+"B") ; 会创建多少个对象? 
String str2 = new String("ABC") + "ABC" ; 会创建多少个对象?

str1:
字符串常量池:"A","B","AB" : 3个
堆:new String("AB") :1个
引用: str1 :1个
总共 : 5个

str2 :
字符串常量池:"ABC" : 1个
堆:new String("ABC") :1个
引用: str2 :1个
总共 : 3个

4. JVM 内存模型

java 常用字符常量 工具 java中的字符常量_java 常用字符常量 工具


JVM 内存模型其实就是在JVM 启动时,从操作系统申请了一块大的内存空间,然后将这个内存空间分成五个区域: 方法区、堆区、虚拟机栈 、本地方法栈、程序计数器方法区和堆区是线程共享的;虚拟机栈、本地方法栈、程序计数器是线程私有的

java 常用字符常量 工具 java中的字符常量_java 常用字符常量 工具_02

4.1 五大区域说明

虚拟机栈

虚拟机栈 存放的是一个个栈帧,一个栈帧对应一个被调用的方法;栈帧包括一个方法的局部变量表、动态连接、方法出口、操作数栈等信息。栈帧中的 局部变量表 存放方法参数和方法内部定义的局部变量。操作数栈可以理解为一个用于计算临时数据的存储区。

本地方法栈

本地方法栈存放调用系统本地方法的动态链接库所需的栈,即Java调用c/c++ 编写的库方法

程序计数器

维护的是下一条执行命令的地址

方法区

方法区是线程共享的,方法区 存储每个类的信息,包括类名,方法信息、字段信息、常量、静态变量、以及编译后的代码等。方法区一个非常重要的部分就是运行时常量池。
jdk8 中方法区的具体实现是 元空间
jdk8 以前实现是 永久代

永久代:堆内存中的一块逻辑区域,主要用于存储类的结构信息,所以对动态生成的类的情况比较容易出现永久代的内存溢出,比如在jsp 页面比较多的情况下,就会出现内存溢出。

元空间:元空间和永久代的最大区别就是,元空间不在与堆连续,不在虚拟机中,而是直接使用的本地内存( 直接内存是调用native方法分配的内存,不属于JVM管理的内存 )。

堆区

堆区是线程共享的,存放Java中的对象和数组等信息。

堆区分为年轻代和老年代:

java 常用字符常量 工具 java中的字符常量_JVM_03


这时候判断Eden区是否能足够的空间存放对象,如果有,则直接防区Eden区。如果Eden区的内存空间不足,会进行一次Minor GC(Young GC),将Eden区的无用的内存空间进行清理,清理后的对象放入from survivor区(此时存活的对象的分代年龄+1),释放Eden区的空间。然后等到下次Eden区内存不足时,会再次触发一次Minor GC,这次Minor GC会将Eden区和 from survivor区存活的对象复制到to survivor区(此时存活的对象的分代年龄+1),然后释放新生代剩余90%的空间,周而复始,始终会有一个survivor空闲,作为下一次minor gc存放对象的空间。当存活的对象分代年龄达到一个阈值(默认是15),就会放入老年代。

5 方法

5.1 Java 中方法参数传递为值传递还是引用传递

Java中方法参数的传递 方式是值传递:

  • 基本类型 传递的时基本类型的值的拷贝,形式参数的改变对实际参数没有影响
  • 引用类型 传递的是该参数所引用的对象在堆中地址值的拷贝,形式参数的改变影响实际参数(其实传的时对象在内存中的地址,对象信息的改变对应内存地址中的对象信息改变)

5.2 方法重载和重写的区别

  • 方法重载:在一个类中 同名的方法如果又不同的参数列表(参数类型、个数 甚至 是顺序不同)则叫做重载
  • 方法重写 子类堆父类允许访问的方法进行重更新编写

方法重载 是编译时的多态性、方法重写实在运行时的多态性;

方法签名: 方法名+参数类型 ;返回类型不属于方法签名