class常量池、运行时常量池 和 字符串常量池 的区别

一、概念

1、class常量池(Constant Pool)

常量池(Constant Pool),也叫 class 常量池(Class Constant Pool)。

java文件被编译成 class文件,class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项就是常量池(Constant Pool),用于存放编译器生成的各种 字面量 和 符号引用。

在这里插入图片描述

常量池的每一项常量都是一个表,一共有如下表所示的11种各不相同的表结构数据,这每个表开始的第一位都是一个字节的标志位(如下所示),代表当前这个常量属于哪种常量类型。

序号常量池中数据项类型类型标志类型描述
1CONSTANT_Utf81UTF-8 编码的Unicode字符串
2CONSTANT_Integer3int 类型字面值
3CONSTANT_Float4float 类型字面值
4CONSTANT_Long5long 类型字面值
5CONSTANT_Double6double 类型字面值
6CONSTANT_Class7对一个类或接口的 符号引用
7CONSTANT_String8String 类型字面值
8CONSTANT_Fieldref9对一个字段的 符号引用
9CONSTANT_Methodref10对一个类中声明的方法的 符号引用
10CONSTANT_InterfaceMethodref11对一个接口中声明的方法的 符号引用
11CONSTANT_NameAndType12对一个字段 或 方法的部分 符号引用

每种不同类型的常量类型具有不同的结构,具体的可以查看《深入理解java虚拟机》第六章的内容。

从上面的表格,大致分两类,如下

  • 字面量, 是序号:1、2、3、4、5、7
  • 符号引用 ,是序号:6、8、9、10、11
1.1、字面量

字面量( Literal )就是我们所说的 常量 ,如文本字符串、被声明为final的常量值 等。

主要分类如下:

  • 文本字符串
  • 被声明为final的常量值
  • 基本数据类型的值
  • 其它
1.2、符号引用

符号引用(Symbolic References) 是一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。

主要包括下面:

  • 类和接口的全限定名
  • 字段的名称和描述符
  • 方法的名称和描述符

在这里插入图片描述

2、Runtime Constant Pool( 运行时常量池 )

运行时常量池 是方法区的一部分。

java文件被编译成class文件之后,也就是会生成我上面所说的 class常量池,那么运行时常量池又是什么时候产生的呢?

jvm在执行某个类的时候,必须经过加载、连接、初始化,而连接又包括验证、准备、解析三个阶段。而当类加载到内存中后,jvm就会将 class常量池 中的内容存放到 运行时常量池 中,由此可知,运行时常量池 也是每个类都有一个。

在上面我也说了,class常量池 中存的是字面量和符号引用,也就是说他们存的并不是对象的实例,而是对象的符号引用值。而经过解析(resolve)之后,也就是把 符号引用 替换为 直接引用 ,解析的过程会去查询 字符串常量池 ,也就是我们上面所说的StringTable,以保证 运行时常量池所 引用的字符串与 字符串常量池 中所引用的是一致的。

举个实例来说明一下:

public class StrTest {

    public static void main(String []args) {
		String str1 = "abc"; 
		String str2 = new String("def"); 
		String str3 = "abc"; 
		String str4 = str2.intern(); 
		String str5 = "def"; 
		System.out.println(str1 == str3);//true 
		System.out.println(str2 == str4);//false 
		System.out.println(str4 == str5);//true
    }
}

解析程序的内存分配过程:

  1. 首先,在堆中会有一个 abc 实例对象,全局 StringTable 中存放着 abc 的一个引用值。

  2. 然后,运行第二句的时候会生成两个实例,一个是 def 的实例对象,并且 StringTable中存储一个 def 的引用值,还有一个是new出来的一个 def 的实例对象 。

  3. 与上面那个是不同的实例,当在解析str3的时候查找StringTable,里面有 abc 的全局驻留字符串引用,所以str3的引用地址与之前的那个已存在的相同 。

  4. str4是在运行的时候调用 intern() 函数,返回StringTable中 def 的引用值,如果没有就将str2的引用值添加进去,在这里,StringTable中已经有了 def 的引用值了,所以返回上面在new str2的时候添加到StringTable中的 def 引用值,

  5. 最后str5在解析的时候就也是指向存在于StringTable中的 def 的引用值。

这样析之后,下面三个打印的值就容易理解了。

上面程序,

  1. 首先,经过编译之后,在该类的 class常量池 中存放一些符号引用;

  2. 然后类加载之后,将 class常量池 中存放的符号引用转存到 运行时常量池 中;

  3. 然后经过验证,准备阶段之后,在堆中生成驻留字符串的实例对象(也就是上例中str1所指向的”abc”实例对象),然后将这个对象的引用存到全局String Pool中,也就是StringTable中;

  4. 最后在解析阶段,要把运行时常量池中的符号引用替换成直接引用,那么就直接查询StringTable,保证StringTable里的引用值与运行时常量池中的引用值一致,大概整个过程就是这样了。

3、String Pool(字符串池、字符串常量池)

String Pool (字符串池),即 String Literal Pool , 又叫 全局字符串池字符串常量池

是在类加载完成,经过验证,准备阶段之后 中生成字符串对象实例,然后 将 该字符串对象实例的 引用值 存到 String Pool 中

记住:String Pool 中存的是 引用值,而不是具体的实例对象,具体的实例对象是在堆中开辟的一块空间存放的。

在 HotSpot VM 里实现的 String Pool 功能的是一个 StringTable 类,它是一个哈希表,里面存的是 驻留字符( 也就是用双引号括起来的部分)的 引用(而不是驻留字符串实例本身),也就是说在堆中的某些字符串实例被这个 StringTable 引用之后就等同被赋予了”驻留字符串”的身份。这个StringTable在每个 HotSpot VM 的实例只有一份,被所有的类共享。

3.1、参考文章:

Java字符串池(String Pool)深度解析

4、总结

  • class常量池在编译阶段,每个class都有的,用于存放编译器生成的 字面量符号引用

  • 运行时常量池 是在类加载完成之后,将每个class常量池 中的符号引用值转存到 运行时常量池 中,也就是说,每个class都有一个 运行时常量池 ,类在 解析阶段 ,将 符号引用 替换成 直接引用 ,与 字符串常量池 中的引用值保持一致。

  • 字符串常量池 在每个VM中只有一份,存放的是字符串常量的 引用值

二、方法区的class文件信息,class常量池 和 运行时常量池的三者关系

面试题:

  1. 方法区里的 class文件信息 和 class文件常量池 是个什么关系。
  2. class文件常量池 和 运行时常量池 是什么关系。

2.1、三者关系图:

2.2、方法区class文件信息

img

可以看到在方法区里的class文件信息包括:魔数,版本号,常量池,类,父类和接口数组,字段,方法等信息,其实类里面又包括字段和方法的信息。

下面的图表是class文件中存储的数据类型:

类型名称数量
u4magic1
u2minor_version1
u2major_version1
u2constant_pool_count1
cp_infoconstant_poolconstant_pool_count - 1
u2access_flags1
u2this_class1
u2super_class1
u2interfaces_count1
u2interfacesinterfaces_count
u2fields_count1
field_infofieldsfields_count
u2methods_count1
method_infomethodsmethods_count
u2attribute_count1
attribute_infoattributesattributes_count

2.3、class常量池:

2.4、运行时常量池:

下面是原 java代码 :

public class TestInt {    
	private  String str = "hello";	
   	void printInt(){
  		System.out.println(65535);
  	}  
}

编译后得到class文件,再javap -v TestInt.class,经过反编译后得到如下信息:

img

可以看出被反编译的class文件中的内容和上面所说的是能对应上的。这就解答了class文件和class文件常量池的关系

2.5、class常量池 和 运行时常量池的关系以及区别

class常量池 存储的是当class文件 被 java虚拟机加载进来后存放在方法区的一些 字面量符号引用字面量 包括 字符串基本类型的常量

运行时常量池 是 当 class文件被加载完成后,java虚拟机会将 class常量池 里的内容转移到 运行时常量池 里,在class常量池的符号引用有一部分是会被转变为直接引用,比如说类的静态方法、私有方法、实例构造方法、父类方法。这是因为这些方法不能被重写其他版本,所以能在加载的时候就可以将符号引用转变为直接引用,而其他的一些方法是在这个方法被第一次调用的时候才会将符号引用转变为直接引用的。

2.5、三者在JVM位置的变化(图)

  • JDK1.6 使⽤ 永久代 实现 ⽅法区

在这里插入图片描述

  • JDK1.7 时发⽣了⼀些变化,将 字符串常量池静态变量 ,存放在
    (方法区 要发生变化,提前将 字符串常量池静态变量 提出来 )

在这里插入图片描述

  • 在 JDK1.8 时,取消 永久代 ,⽽在 直接内存 中划出⼀块区域作为 元空间 (即 方法区),运⾏时常量池类常量池 变化在 元空间 上。

在这里插入图片描述

2.6、总结:

方法区里存储着 class文件的信息 和 运行时常量池,class文件的信息 包括类信息 和 class文件常量池 。

运行时常量池里的内容除了是class文件常量池里的内容外,还将class文件常量池里的符号引用转变为直接引用,而且运行时常量池里的内容是能动态添加的。例如调用String的intern方法就能将string的值添加到String常量池中,这里String常量池是包含在运行时常量池里的,但在jdk1.8后,将String常量池放到了堆中。

三、ChatGPT 回答

class常量池、字符串常量池和运行时常量池是Java中的不同概念,它们有一些区别,如下所示:

  1. Class常量池(Class Constant Pool):

    • Class常量池 是编译时的概念,在 类被编译存储在类文件(.class) 中。
    • 每个类(Class)都有一个常量池,用于存储该类的常量、符号引用等信息。
    • 它包含了字面量(如字符串、数值)、符号引用(如方法、字段的名称和描述符)以及一些特殊的常量(如类和接口的全限定名)。
    • Class常量池在类加载时被加载到方法区,供运行时使用。
  2. 字符串常量池(String Constant Pool):

    • 字符串常量池是字符串的存储区域,用于存储字符串常量对象。
    • 字符串常量池是在堆内存中的一部分,用于存储字符串常量(使用字面量创建的字符串)。
    • 字符串常量池的目的是 重用字符串对象,以节省内存
    • 字符串常量池在运行时被创建和管理,存在于堆内存中。
  3. 运行时常量池(Runtime Constant Pool):

    • 运行时常量池是每个类或接口的运行时表示,包含了该类或接口的常量池信息。
    • 运行时常量池是方法区的一部分,用于存储编译时的符号引用、字面量值等。
    • 运行时常量池是在类加载时被加载到方法区,供运行时使用。
    • 运行时常量池中的常量可以是编译时确定的,也可以是运行时生成的(例如使用String.intern()方法)。

总结:

  • Class常量池是每个类的一部分,在类文件中,用于存储常量、符号引用等。
  • 字符串常量池是字符串对象的存储区域,用于存储字符串常量,存在于堆内存中。
  • 运行时常量池是每个类或接口的运行时表示,包含了常量池信息,在方法区中。

需要注意的是,

  • 字符串常量池,在Java 6及之前位于 方法区 中,从Java 7开始,被移动到 堆内存 中。
  • 运行时常量池运行时常量池 是方法区的一部分,跟随着方式区的变化而变化 。在Java 7之前位于 方法区(永久代) 中,从Java 8开始,变成 方法区 (元空间 Metaspace)。

因此,具体的实现和内存分配可能因Java版本而有所不同。

四、推荐文章

下面有一篇文章写的是比较好的
http://blog.csdn.net/vegetable_bird_001/article/details/51278339
https://www.cnblogs.com/holos/p/6603379.html

  • 34
    点赞
  • 109
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
Java 虚拟机面试题全面解析,《深入理解Java虚拟机》干货版,自己总结,希望能够帮助大家,免费下载~什么是类加载机制? 虚拟机和物理机的区别是什么? 运行时栈帧结构 Java方法调用 什么是方法调用? Java的方法调用,有什么特殊之处? Java虛拟机调用字节码指令有哪些? 虚拟机是如何执行方法里面的字节码指令的? 解释执行 基于栈的指令集和基于寄存器的指令集 什么是基于栈的指令集? 什么是基于寄存器的指令集? 基于栈的指令集的优缺点? Javac编译过程分为哪些步骤? 什么是即时编译器? 解释器和编译器 为什么要采用分层编译? 分层编译器有哪些层次? 编译对象与触发条件 热点代码有哪些? 如何判断一段代码是不是热点代码? Hotspot虚拟机使用第二种,有两个计数器: 方法调用计数器统计方法 有哪些经典的优化技术(即时编译器)? 公共子表达式消除 数组边界检查消除 方法内联 逃逸分析 如果对象不会逃逸到方法或线程外,可以做什么优化? Java与C/C++的编译器对比 物理机如何处理并发问题? Java内存模型 什么是Java内存模型? Java内存模型的目标? 主内存与工作内存 内存间的交互操作 原子性、可见性、有序性 volatile 什么是 volatile? 为什么基于 volatile变量的运算在并发下不一定是安全的? 为什么使用 volatile? 并发与线程 并发与线程的关系? 什么是线程? 实现线程有哪些方式? Java线程的实现 Java线程调度 什么是线程调度? 线程调度有哪些方法? 线程安全的定义? Java语言操作的共享数据,包括哪些? 不可变 如何实现线程安全? 阻塞同步(互斥同步) 非阻塞同步 锁优化是在DK的那个版本? 为什么要提出自旋锁? 自旋锁的原理? 自旋的缺点? 什么是自适应自旋? 锁消除 锁粗化 轻量级锁 偏向锁 JDK是什么? JDK是用于支持Java程序开发的最小环境。 1.Java程序设计语言 2.Java虚拟机 3. Java ap类库 JRE是什么? JRE是支持Java程序运行的标准环境。 1. Java SE aPi子集 2.Java虚拟机 Java历史版本的特性? Java∨ ersion se5.0 引入泛型; 增强循环,可以使用迭代方式; 自动装箱与自动拆箱; 类型安全的枚举 ·可变参数; 静态引入 元数据(注解); 引入 Instrumentation Java∨ ersion se6 支持脚本语言 引入JDBC40API; 引入 Java Compiler API; 可插拔注解; 增加对 Native PKi( Public Key Infrastructure)、 Java gss( Generic Security Service) Kerberos和 LDAP(Lightweight Directory Access Protocol的支持; 继承 Web services 做了很多优化。 Java∨ ersion se7 switch语句块中允许以字符串作为分支条件; 在创建泛型对象时应用类型推断 ·在一个语句块中捕获多种异常; ·支持动态语言; 支持try-with- resources 引入 Java nio.2开发包; ·数值类型可以用2进制字符串表示,并且可以在字符串表示中添加下划线; 钻石型语法; nu值的自动处理。 Java 8 函数式接口 Lambda表达式 接口的增强 运行时数据区域包括哪些? 1.程序计数器 2.Java虚拟机栈 3.本地方法栈 4.Java堆 5.方法区 6.运行时常量池 7.直接内存 程序计数器(线程私有) 程序计数器( Program Counter Register)是一块较小的内存空间,可以看作是当前线程所 执行字节码的行号指示器。分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这 个计数器完成。 由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式实现的。为了线 程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各线程之间的计 数器互不影响,独立存储。 1.如果线程正在执行的是一个Java方法,计数器记录的是正在执行的虚拟机字节码指令的地 址 2.如果正在执行的是 Native方法,这个计数器的值为空 程序计数器是唯一—个没有规定任何 OutofMemoryError的区域 Java虚拟机栈(线程私有) Java虚拟机栈( Java virtual machine stacks)是线程私有的,生命周期与线程相同。 虛拟机栈描述的是Ja阳a方法执行的内存模型:每个方法被执行的时候都会创建一个栈 帧( Stack frame),存储 1.局部变量表 2.操作栈 3.动态链接 4.方法出口 每—一个方法被调用到执行完成的过程,就对应着一个栈帧在虛拟机栈中从入栈到出栈的过程。 这个区域有两种异常情况: 1. StackOverflow error:线程请求的栈深度大于虚拟机所允许的深度 2. OutOfMemoryError:虚拟机栈扩展到无法申请足够的内存时 本地方法栈(线程私有 虚拟机栈为虚拟机执行Java方法(字节码)服务。 本地方法栈( Native method stacks)为虚拟机使用到的 Native方法服务。 Java堆(线程共享) Java堆( Java Heap)是Java虚拟机中内存最大的一块。Java堆在虚拟机启动时创建,被所 有线程共享。 作用:存放对象实例。垃圾收集器主要管理的就是Java堆。Java堆在物理上可以不连续,只 要逻辑上连续即可。 方法区(线程共亨) 方法区( Method area)被所有线程共享,用于存储已被虛拟机加载的类信息、常量、静态 变量、即时编译器编译后的代码等数据。 和Java堆一样,不需要连续的内存,可以选择固定的大小,更可以选择不实现垃圾收集。 运行时常量池 运行时常量池( Runtime Constant pool)是方法区的一部分。保存 Class文件中的符号引 用、翻译岀来的直接引用。运行时常量池可以在运行期间将新的常量放入池中 Java中对象访问是如何进行的? Object ob j new Object( 对于上述最简单的访问,也会涉及到Java栈、Java堆、方法区这三个最重要内存区域。 Object obj 如果出现在方法体中,则上述代码会反映到Java栈的本地变量表中,作为 reference类型数 据出现。 new Object( 反映到Java堆中,形成一块存储了 bject类型所有对象实例数据值的内存。Java堆中还包 含对象类型数据的地址信息,这些类型数据存储在方法区中, 如何判断对象是否“死去”? 1.引用计数法 2.根搜索算法 什么是引用计数法? 给对象添加一个引用计数器,每当有一个地方引用它,计数器就+1,;当引用失效时,计数器 就-1;任何时刻计数器都为0的对象就是不能再被使用的 引用计数法的缺点? 很难解决对象之间的循环引用问题。 什么是根搜索算法? 通过一系列的名为" GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过 的路径称为引用链( Reference chain),当一个对象到 GC Roots没有任何引用链相连(用 图论的话来说就是从 GC Roots到这个对象不可达)时,则证明此对象是不可用的。 object 5 object 6 object 7 仍然存活的对象 □判定可回收的对象 Java的4种引用方式? 在」DK1.2之后,Java对引用的概念进行了扩充,将引用分为 1.强引用 Strong reference 2.软引用 Soft reference 3.弱引用 Weak Reference 4.虚引用 Phantom reference 强引用
int和Integer有什么区别? 答:int是java的原始数据类型,Integer是java为int提供的封装类,java为每个原始数据类型都提供了封装类。 String和StringBuffer的区别? 答:String是不可变的对象,每次对String类型进行改变都相当于产生了一个新的对象,StringBuffer是可变的字符序列,所以如果要经常改变某个字符串的话建议使用StringBuffer。 list、set、map问题? 答:set 不允许重复,无序 list 允许重复,有序 map 成对的数据结构,键值必须具有唯一性 Servlet和CGI的区别? 答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式允许其service方法,一个实例可以服务于多个请求,并且其实例一般不会被销毁,而CGI对每个请求都产生新的进程,服务完后就销毁,所以效率上低于Servlet。 面向对象的特征? 答:1:封装:通过定义类并且给类的属性和方法加上访问控制 2:继承:子类继承父类,子类可以拥有父类中已定义的方法,并且子类可以修改父类中的方法使其更适合特殊需求。 3:多台:不同对象对统一消息作出不同响应称之为多态 4:抽象:忽略与当前主题无关的那些方面,将注意力集中在与当前目标有关的方面 运行时异常和一般异常有何异同? 答:运行时异常时(JVM)java虚拟机在运行过程中发生的问题,比如:内存溢出等问题。这类异常没法要求程序员去一一捕获并抛出,一般异常是Java类库或程序员自己写的代码发生的错误,这类异常可以由我们去一一捕获并抛出。 多线程几种实现方法,同步? 答:多线程有两种实现方法,一种是继承Thread类或者实现Runnable接口。同步就是在方法返回类型后面加上synchronized。 c#中的委托,事件是不是委托? 答:委托就是将方法作为一个参数带入另一个方法叫做委托,事件是一种特殊的委托。 应用程序域? 答:应用程序域可以理解为一种轻量级的进程,起到安全的作用,占用资源小。 Class.forName作用? 答:调用该访问返回一个以字符串指定类名的类对象。 JDO? 答:JDO是java对象持久化的新的规范,为java data object的简称,也是一个用于存取某种数据仓库中的对象的标准化API。 CORBA? 答:CORBA标准是公共对象请求代理结构,用途为:用不同的程序设计语言书写,在不同的进程中运行,为不同的操作系统开发。 xml解析技术? 答:常用的DOM、SAX等 DOM:处理大型文件时性能下降的非常厉害,适合对xml的随机访问 SAX:事件驱动型的xml解析方法,适合对xml的顺序访问 jsp常用动作? 答:jsp:include 引入一个文件 jsp:useBean 实例化JavaBean jsp:setProperty 设置JavaBean属性 jsp:getProperty 输出JavaBean属性 jsp:forward 转发 CTS、CLS、CLR分别作何解释? 答:CTS 通用类型系统、CLS 通用语言规范、CLR 公共语言运行时。 Struts1和Struts2原理和区别? 答:Struts1和Struts2是两个完全不同的框架,Struts1以ActionServlet作为核心控制器,由ActionServlet负责拦截用户的所有请求。Struts2以核心控制器FilterDispatcher为基础,包含了框架内部的控制流程和处理机制。 Hibernate工作原理,Hibernate数据持久化? 答:Hibernate工作原理: 1:读取并解析映射信息,创建SessionFactory 2:打开Session 3:创建事物 4:持久化操作 5:提交事务 6:关闭Session 7:关闭SessionFactory Hibernate持久化:Hibernate根据定义的映射规则将对象持久化保存到数据库,这就实现了对象的持久化。 Spring由那几个模块组成? 答:Spring主要由7个模块组成: 1:Spring核心容器:提供了Spring框架的基本功能 2:Spring AOP:通过配置管理特性 3:Spring ORM:Spring框架集成了若干ORM框架 4:Spring DAO:打开关闭数据库连接 5:Spring WEB:为基于WEB服务的应用程序提供上下文服务 6:Spring Context:向Spring框架提供上下文信息 7:Spring MVC:分离模型、视图、控制器、以便更容易定制 折构函数和虚函数? 答:折构函数式销毁一个类的函数,虚函数是为了C++的动态绑定而设计的。 描述你的编程风格? 答:类名首字母大写,常量一般全部大写,给自己的代码加注释。 控制流程? 答:控制流程一般使用if判断条件。有第二分支,多分支,循环结构。循环本质上也是通过判断来实现的。 多形与继承? 答:多形:一个类中多个同名方法。继承:子类继承父类。 jsp内置对象? 答:request 用户端请求 response 回应 pageContext 网页属性 session 会话 out 输出 page 当前网页 exception 错误网页 application servlet正在执行的内容 config servlet构架部件 Struts模型驱动? 答:封装请求参数。 简述JDBC? 答:JDBC数据库连接,是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问。 什么情况下不建议使用Hibernate? 答:当数据量大,并且表关系复杂的时候不建议使用。 sleep()和wait()有什么区别? 答:sleep()是线程类的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但监控状态依然保持,到时候会自动恢复。 wait()是Object类的方法,对此对象调用了wait方法导致本线程放弃对象锁,进入等待锁定池,只有针对此对象发出notify方法后本线程才进入对象锁定池准备获得对象锁进入运行状态。 同步和异步,在什么情况下分别使用? 答:如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。 当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步。在很多情况下采用异步往往更有效率。 数据库三大范式? 答:1:确保每列都是不可分割的原子值 2:确保每列都和主键相关 3:确保每列都和主键直接相关,而不是间接相关 单例模式有哪些好处? 答:单例模式是一种比较常见的设计模式,带给我们以下好处: 1:控制资源的使用 2:控制实例的产生数量 3:让多个不相关的两个线程或进程之间实现通信 为什么要用spring? 答:1、主要将各个框架有效的联系起来,缩短实际编程时间。 2、可以将各个框架进行有效的管理和控制,让数据传输安全。 spring的IOC和DI? 答:控制反转和依赖注入是spring的两大基础作用。主要是将所有组件在spring提供的外部容器中加载。提高安全性,减低耦合性,使各个框架或者类之间的依赖性降低。 什么是声明式的事务管理?为什么要用?spring如何实现声明式的事务管理? 答:声明式的事务管理主要是将在进行对数据库中数据的添加或者修改时需要执行事务管理,主要是为了避免在执行添加或修改的时候添加或修改不完全正确,导致数据丢失。spring使用AOP面向切面的思想进行事务管理的。 spring和Hibernate继承后,定义事务管理特性的时候查询为什么要定义为read-only? 答:因为添加、删除和更新都涉及到了数据库的修改,而查询并未涉及到数据库修改,所以只需要定义只读,这样可以提高效率,进行更加方便的事务管理。 请你谈谈对Hibernate OR映射的理解? 答:将数据库中的每一张表都映射成一个实体。 配置了lazy="true"一定会懒加载吗? 答:不一定,如果在配置中你也使用了fetch属性的话此时lazy就会失效。 Hibernate数据库标识与主键之间的认识? 答:标识是为了方便和简介映射文件,主键是为了让数据不会重复。 为什么每次请求都要创建一个Action对象? 答:Struts2每次请求的时候都会创建一个action实例,这样会保证线程的安全。Struts1只是在第一次请求的时候创建一个action实例,以后每次相同的请求都直接从内存中去读取,它是单例模式,安全性较差。 Struts2是如何实现MVC模式的? 答:在Struts2里面是将每次页面的请求进行处理,然后将请求需要输出的数据转发到需要做数据显示的页面。Struts2只是起到一个数据接收和转接的功能,就是Controller控制器,而传来数据的页面叫view显示层,Struts2将数据提交给进行处理的类叫Model模型层,专门进行数据处理和数据库的连接。 heap和stack有什么区别? 答:栈是一种线形集合,其添加和删除元素的操作应在同一段完成,栈按照后进先出的方式进行处理。堆是栈的一个组成元素。 EJB和JavaBean的区别? 答:EJB不是一般的JavaBean,EJB是企业级的JavaBean,EJB一共分为3种,实体Bean,消息Bean,会话Bean。书写EJB要遵循一定的规范,另外要运行EJB,你需要有相应的EJB容器,比如WebLogic、jboss等,而JavaBean不需要,只需要安装Tomcat就可以了。EJB用于服务端的应用开发,而JavaBean用于客户端应用开发。 触发器? 答:触发器是一种特殊的存储过程,主要通过事件来触发而被执行。 什么是存储过程?用什么调用? 答:存储过程是一个预编译的SQL语句,优点是允许模块化的设计。就是说只需要创建一次,以后再程序中就可以调用多次。使用存储过程比单纯的SQL语句要快,可以用一个命令对象来调用存储过程。 索引优缺点? 答:索引可以提高对数据库中数据的检索,缺点是减慢了数据录入速度,同时也增加了数据库的尺寸大小。 什么是事务?什么是事锁? 答:事务就是被绑定在一起,作为一个逻辑单元执行的SQL语句。如果任何一个操作失败,那么整个就失败。共同失败或共同成功。锁可以保证事务的完整性和并发性。 什么是视图?游标是什么? 答:视图是一种虚拟的表,具有和物理表相同的功能。游标是对查询出来的结果集作为一个单元来有效的处理,可以对结果集的当前行做修改。 select执行顺序? 答:from where group by having select order by Collection和Collections的区别? 答:Collection是集合类的父类,继承它的主要由set和list Collections是针对集合类的帮助类,它提供了一系列针对集合的搜索,排序,线程安全化等操作。 final、finally、finalize的区别? 答:final用于声明属性方法和类,分别表示:属性不可变,方法不可覆盖,类不可继承。 finally是异常处理语句的一部分,表示总是执行。 finalize是Object的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。 assert是什么?什么时候用到? 答:断言,可以将断言看成是异常处理的一种高级形式,可以用来判断某个特定的表达式或值是否为真。 接口是否可以继承接口?抽象类是否可以实现接口?抽象类是否可以继承实体类? 答:接口可以继承接口,抽象类可以实现接口,抽象类可以继承实体类。 引用传递和值传递? 答:引用传递:形参改变影响实参 值传递:形参改变不影响实参 当一个线程进入一个对象的synchronized方法后,其他线程是否可进入此对象的其他方法? 答:其他方法前是否加了synchronized关键字,如果没加则能。 说出servlet生命周期? 答:servlet实例化时调用init方法,得到请求时调用service方法,service方法自动派遣doget或dopost方法,最后当实例销毁时调用destroy方法。 error和exception有什么区别? 答:error是指错误,通常程序员不能通过代码来解决。底层环境或硬件问题。 exception是指异常,可以通过代码来解决的问题。 forward和redirect的区别? 答:forward是转发,浏览器跳转后不显示新的地址。 redirect是重定向,浏览器跳转后显示新的地址。 对比之下forward更加高效,并且它有助于隐藏实际地址,但是有些情况则必须使用redirect,否则会报异常。 jsp中动态include和静态include的区别? 答:动态include用jsp:include实现,适用于动态页面,可以携带参数 静态include用include伪码实现,适用于静态页面 math.round(11.5)等于多少?math.round(-11.5)等于多少? 答:Math.round()对数字进行四舍五入 Math.round(11.5)=12 Math.round(-11.5)=11 String s=new String("xyz");创建了几个String Object? 答:创建了两个String对象,一个保存的引用地址,一个保存实际的值。 数组有没有length()这个方法?String呢? 答:数组里面没有length()方法,而是length属性。String有length()这个方法。 swtich()能否作用在byte、long、String上? 答:swtich()传递的应该是一个整数表达式,所以它的值只能是:int、short、char、byte所以long和String都不能作用在swtich()上。 jsp和servlet之间的联系? 答:jsp前段动态页面,servlet是纯java类 jsp被编译之后会转换为servlet执行 java基本数据类型有哪些?String是不是基本数据类型,他们有何区别? 答:基本数据类型8种:int、short、byte、long、float、double、char、boolean String不是基本数据类型,引用数据类型。 区别:基本数据类型比较实用“==”,引用数据类型实用equest,并且引用数据类型存放的是地址而不是具体的值。 写一个方法,实现字符串的替换,如:输入bbbwlirbbb,输出bbbhhtccc? 答:String s="bbbwlirbbb"; s.replaceAll("wlirbbb","hhtccc"); 如何将数值型字符转换为数字(Integer,Double)? 答:可以用Integer.parseInt()和Double.parseDouble()方法 如何将数字转换为字符? 答:可以使用String的valueOf()方法。 如何取得1970到现在的毫秒数? 答:可以用getTime()方法。 如何格式化日期? 答:可以用SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd"); 判断是否有子文件?判断是否有子目录?判断文件是否存在? 答:判断是否有子文件使用file.isFile() 判断是否有子目录使用file.isDirectory() 判断文件是否存在使用file.exists() 继承、重载、覆盖问题? 答:继承:子类继承父类,子类可以拥有父类中已定义的方法,并且子类可以修改父类中的方法使其更适合特殊需求。 重载:在一个类中方法名和返回类型相同,参数不同。 覆盖:在子类中覆盖父类的某个方法,要求方法名相同,参数类型相同。 Statement和PreparedStatement之间的区别? 答:Statement比PreparedStatement速度慢 PreparedStatement是预编译,插入时速度高于Statement Statement创建速度很慢,常用选择PreparedStatement Session机制? 答:session机制是一种服务器端机制,服务器使用一种类似于散列表的结构来保存信息。 jsp和servlet中的请求转发分别如何实现? 答:jsp可以使用jsp:forward标签转发 servlet可以使用request.getRequestDispatcher()实现转发 介绍j2ee、j2se、j2me的区别? 答:j2ee(企业版):主要用于企业web开发 j2se(标准版):主要用于web开发,但缺少企业版的一些特性 j2me(微小版):主要用于手机开发 J2ee提供的技术? 答:j2ee提供的技术有EJB、servlet、jsp等。 什么是Application Server? 答:Application Server 应用服务器 简单介绍连接池的优点和原理? 答:数据库连接和关闭是比较花费时间的一件事,而连接池可以提高我们的工作效率。 刚开始创建一定数量的池连接,当需要时从池连接中拿出一个,用完之后再把这个连接重新放回连接池。 Web.xml的作用? 答:Web.xml会在程序启动时执行,如果想在程序刚启动的时候执行一些方法的话可以配置在Web.xml中。 简单介绍您所了解的MVC? 答:在项目中使用MVC模式会使项目分工更加明确,结构更加清晰 M model 模型层:JavaBean V view 视图层:jsp html C controller 控制层:servlet 简单介绍你所了解的XML? 答:XML可扩展标记语言,可以用来标记数据,定义数据结构,是一种允许用户自定义标记的语言 简单介绍您所了解的structs、spring和hibernate? 答:struts:控制层Action,页面标签和Model数据,调用业务层 Spring:Aop管理事务控制,IOC管理各个组件的耦合 Hibernate:负责数据库和对象的映射,负责Dao层 因为你去公司面试,公司让你写笔试,不可能说XX一个题目写两页纸写的太详细,所以以上答案有的可能比较简短,没有说出重点,请大家补充,如果大家有什么更好的答案请拿出来一起分享

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值