文档库 最新最全的文档下载
当前位置:文档库 › 类的加载

类的加载

类的加载
类的加载

类从加载到虚拟机到卸载,它的整个生命周期包括:加载(Loading),验证(Validation),准备(Preparation),解析(Resolution),初始化(Initialization),使用(Using)和卸载(Unloading)。其中,验证、准备和解析部分被称为连接(Linking)。

加载:

在加载阶段,虚拟机主要完成三件事:

1.通过一个类的全限定名来获取定义此类的二进制字节流。

2.将这个字节流所代表的静态存储结构转化为方法区域的运行时数据结构。

3.在Java堆中生成一个代表这个类的https://www.wendangku.net/doc/1110840573.html,ng.Class对象,作为方法区域数据的访问入口。

验证:

验证阶段作用是保证Class文件的字节流包含的信息符合JVM规范,不会给JVM造成危害。如果验证失败,就会抛出一个https://www.wendangku.net/doc/1110840573.html,ng.VerifyError异常或其子类异常。验证过程分为四个阶段:

1.文件格式验证:验证字节流文件是否符合Class文件格式的规范,并且能被当前虚拟机正确的处理。

2.元数据验证:是对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言的规范。

3.字节码验证:主要是进行数据流和控制流的分析,保证被校验类的方法在运行时不会危害虚拟机。

4.符号引用验证:符号引用验证发生在虚拟机将符号引用转化为直接引用的时候,这个转化动作将在解析阶段中发生。

准备:

准备阶段为变量分配内存并设置类变量的初始化。在这个阶段分配的仅为类的变量(static修饰的变量),而不包括类的实例变量。对已非final的变量,JVM会将其设置成“零值”,而不是其赋值语句的值:

pirvate static int size = 12;

那么在这个阶段,size的值为0,而不是12。final修饰的类变量将会赋值成真实的值。

解析:

解析过程是将常量池内的符号引用替换成直接引用。主要包括四种类型引用的解析。类或接口的解析、字段解析、方法解析、接口方法解析。

初始化:

在准备阶段,类变量已经经过一次初始化了,在这个阶段,则是根据程序员通过程序制定的计划去初始化类的变量和其他资源。这些资源有static{}块,构造函数,父类的初始化等。

至于使用和卸载阶段阶段,这里不再过多说明,使用过程就是根据程序定义的行为执行,卸载由GC完成。

都是父类先执行

()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}块)再执行构造方法

虚拟机类加载机制:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型。

Java语言里,类型的加载和连接过程是在程序运行期间完成的。

类的生命周期:

加载loading

验证verification

准备preparation

解析resolution

初始化initialization

使用using

卸载unloading

有且只有以下四种情况必须立即对类进行”初始化”(称为对一个类进行主动引用):

1.遇到new、getstatic、putstatic、invokestatic这四条字节码指令时(使用new实例化对象

的时候、读取或设置一个类的静态字段、调用一个类的静态方法)。

2.使用https://www.wendangku.net/doc/1110840573.html,ng.reflet包的方法对类进行反射调用的时候。

3.当初始化一个类的时候,如果发现其负类没有进行过初始化,则需要先触发其父类的初始化。

4.当虚拟机启动时,虚拟机会初始化主类(包含main方法的那个类)。

被动引用:

1.通过子类引用父类的静态字段,不会导致子类初始化(对于静态字段,只有直接定义这个字段的

类才会被初始化)。

2.通过数组定义类应用类:ClassA [] array=new ClassA[10]。触发了一个名为[LClassA的类

的初始化,它是一个由虚拟机自动生成的、直接继承于Object的类,创建动作由字节码指令newarray触发。

3.常量会在编译阶段存入调用类的常量池。

编译器会为接口生成()构造器,用于初始化接口中定义的成员变量。一个接口在初始化时,并不要求其父类接口全部完成了初始化,只有在真正使用到父接口的时候才会初始化。

1. 加载

1.通过一个类的全限定名来获取此类的二进制字节流。

2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。

3.在java堆中生成一个代表这个类的Class对象,作为方法区这些数据的访问入口。

2. 验证

验证:确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

虚拟机规范:如果验证到输入的字节流不符合Class文件的存储格式,就抛出一个

https://www.wendangku.net/doc/1110840573.html,ng.VerifyError异常或其子类异常。

1.文件格式验证:验证字节流是否符合Class文件格式的规范,并且能被当前版本的虚拟机处理。

这个阶段的验证时给予字节流进行的,经过了这个阶段的验证之后,字节流才会进入内存的方法区中进行存储所以后面的验证阶段都是给予方法区的存储结构进行的。

2.元数据验证:对类的元数据信息进行语义校验,保证不存在不符合java语言规范的元数据信息。

3.字节码验证:进行数据流和控制流分析,对类的方法体进行校验分析,保证被校验的类的方法在

运行时不会做出危害虚拟机安全的行为。

4.符号引用验证:发生在虚拟机将符号引用转化为直接引用的时候(解析阶段),对常量池中的各种

符号引用的信息进行匹配性的校验。

3. 准备

准备阶段是正式为类变量分配内存并设置类变量初始值(各数据类型的零值)的阶段,这些内存将在方法区中进行分配。但是如果类字段的字段属性表中存在ConstantValue属性,那在准备阶段变量值就会初始化为ConstantValue属性指定的值。

public static final int value=122;

4. 解析

解析阶段是在虚拟机将常量池内的符号引用替换为直接引用的过程。

符号引用:符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。符号引用与虚拟机实现的内存布局无关,引用的目标并不一定已经加载到内存中。

直接引用:直接引用可以是直接指向目标的指针、相对偏移量或者一个能间接定位到目标的句柄。

如果有了直接引用,那引用的目标必定已经在内存中存在。

A. 类或接口(对应于常量池的CONSTANT_Class_info类型)的解析:

假设当前代码所处的类为D,需要将一个从未解析过的符号引用N解析为一个类或接口C的直接引用:

1.如果C不是一个数组类型,虚拟机将会把代表C的全限定名传递给D的类加载器去加载这个类。

2.如果C是一个数组类型,并且数组的元素类型为对象(N的描述符类似[https://www.wendangku.net/doc/1110840573.html,ng.Integer),

将会加载数组元素类型(https://www.wendangku.net/doc/1110840573.html,ng.Integer),接着由虚拟机生成一个代表此数组维度和元素的数组对象。

3.如果以上过程没有发生异常,则C在虚拟机中已经成为了一个有效的类和接口了,之后还要进

行的是符号引用验证,确认D是否具有对C的访问权限,如果没有,将抛出

https://www.wendangku.net/doc/1110840573.html,ng.IllegalAccessError异常。

B. 字段(对应于常量池的CONSTANT_Fieldref_info类型)解析:

1.对字段表中的class_index项中索引的CONSTANT_Class_info符号引用进行解析。用C表

示这个字段所属的类或接口。

2.如果C本身就包含了简单名称和字段描述符都与目标相匹配的字段,则返回这个字段的直接引

用。

3.否则,如果C实现了接口,则会按照继承关系从下往上递归搜索各个接口和他的父接口,如果

接口中包含了简单名称和字段描述符都与目标相匹配的字段,则返回这个字段的直接引用。

4.否则,如果C不是https://www.wendangku.net/doc/1110840573.html,ng.Object类型的话,将会按照继承关系从下往上递归的搜索其父类,

如果在父类中包含了简单名称和字段描述符都与目标相匹配的字段,则返回这个字段的直接引用。

5.否则,查找失败,抛出https://www.wendangku.net/doc/1110840573.html,ng.NoSuchFieldError异常。

虚拟机的编译器实现可能会更严格:如果一个同名字段同时出现在C实现的接口和父类中,或者同时在自己或父类的多个接口中出现,编译器将可能拒绝编译。

C. 类方法(对应于常量池的CONSTANT_Methodref_info类型)解析:

1.对方法表中的class_index项中索引的CONSTANT_Class_info符号引用进行解析。用C表

示这个方法所属的类或接口。

2.类方法和接口方法符号引用的常量类型定义是分开的,如果在类方法表中发现class_index中

索引的C是个接口,则抛出https://www.wendangku.net/doc/1110840573.html,ng.IncompatibleClassChangeError。

3.在类C中查找是否有简单名称和描述符都与目标相匹配的方法,如果有则返回这个方法的直接

引用。

4.否则,在C的父类中递归查找是否有简单名称和描述符都与目标相匹配的方法,如果有则返回

这个方法的直接引用。

5.否则,在C实现的接口列表及它们的父接口中递归的查找是否有简单名称和描述符都与目标相

匹配的方法,如果有说明C是个抽象类,查找结束,抛出https://www.wendangku.net/doc/1110840573.html,ng.AbstractMethodError 异常。

6.否则,查找失败,抛出https://www.wendangku.net/doc/1110840573.html,ng.NoSuchMethodError异常。

7.如果查找返回了直接引用,将会对这个方法进行权限验证,如果发现不具备对这个方法的访问权

限,则抛出https://www.wendangku.net/doc/1110840573.html,ng.IllegalAccessError异常。

D. 接口方法(对应于常量池的CONSTANT_InterfaceMethodref_info类型):

1.对方法表中的class_index项中索引的CONSTANT_Class_info符号引用进行解析。用C表

示这个方法所属的类或接口。

2.如果在接口方法表中发现class_index中索引的C是个类,则抛出

https://www.wendangku.net/doc/1110840573.html,ng.IncompatibleClassChangeError。

3.否则,在接口C中查找是否有简单名称和描述符都与目标相匹配的方法,如果有则返回这个方

法的直接引用。

4.否则,在接口C的父接口中递归查找,知道https://www.wendangku.net/doc/1110840573.html,ng.Object类(包括在内),看是否有简单名

称和描述符都与目标相匹配的方法,如果有则返回这个方法的直接引用。

5.否则,查找失败,抛出https://www.wendangku.net/doc/1110840573.html,ng.NoSuchMethodError。

5. 初始化

初始化阶段是执行类构造器()方法的过程。

1.()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}块)

中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序决定的。静态语句块只能访问到定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块中可以赋值,但是不能访问。

2. 方法与实例构造器()不同,不需要显示的调用父类构造器,虚拟机会保证在子类

()方法执行之前,父类的()已经执行完毕。

3. ()方法对于类或接口来说不是必须的,如果一个类中没有静态语句块也没有对

变量的赋值操作,那么编译器可以不为这个类生成()方法。

4. 执行接口的()不需要先执行父接口的()方法,只有当父接口中定义的

变量被使用时,父接口才会被初始化。接口的实现类在初始化时也不会执行接口的()方法。

5. 虚拟机会保证一个类的()方法在多线程环境中被正确的加锁和同步,如果多

个线程同时去初始化一个类,则只会有一个线程去执行这个类的()方法,其他线程需要阻塞等待。

北大青鸟推荐:Java精选笔试题(含答案解析)

北大青鸟推荐:Java精选笔试题(含答案解析)如果你是计算机专业出生,但是还没有找到工作的话,你就得补补技术了,一些关于面试、笔试的题要多刷一刷。有可能你知道答案,但是由于语言组织能力有所欠缺,所以面试官的印象不是很好,下面分享一些Java精选的鄙视题,希望对面试这者有帮助。 1,volatile关键字是否能保证线程安全?() 答案:否 volatile关键字用在多线程同步中,可保证读取的可见性,JVM只是保证从主内存加载到线程工作内存的值是最新的读取值,而非cache中。但多个线程对volatile的写操作,无法保证线程安全。 假如线程1,线程2 在进行read,load 操作中,发现主内存中count的值都是5,那么都会加载这个最新的值,在线程1对count进行修改之后,会write到主内存中,主内存中的count变量就会变为6;线程2由于已经进行read,load操作,在进行运算之后,也会更新主内存count的变量值为6;导致两个线程及时volatile关键字修改之后,还是会存在并发的情况。 2,下面哪个流类属于面向字符的输入流( ) A、BufferedWriter B、FileInputStream C、ObjectInputStream D、InputStreamReader 答案:D Java的IO操作中有面向字节(Byte)和面向字符(Character)两种方式。

面向字节的操作为以8位为单位对二进制的数据进行操作,对数据不进行转换,这些类都是InputStream和OutputStream的子类。 面向字符的操作为以字符为单位对数据进行操作,在读的时候将二进制数据转为字符,在写的时候将字符转为二进制数据,这些类都是Reader和Writer的子类。 3,Java能不能不通过构造函数创建对象() A、能 B、不能 答案:A Java创建对象的几种方式: (1) 用new语句创建对象,这是最常见的创建对象的方法。 (2) 运用反射手段,调用https://www.wendangku.net/doc/1110840573.html,ng.Class或者https://www.wendangku.net/doc/1110840573.html,ng.reflect.Constructor类的newInstance()实例方法。 (3) 调用对象的clone()方法。 (4) 运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法。 (1)和(2)都会明确的显式的调用构造函数;(3)是在内存上对已有对象的影印,所以不会调用构造函数;(4)是从文件中还原类的对象,也不会调用构造函数。 4,下列哪个叙述是正确的() A.子类继承父类的构造方法。 B.abstract类的子类必须是非abstract类。 C.子类继承的方法只能操作子类继承和隐藏的成员变量。 D.子类重写或新增的方法也能直接操作被子类隐藏的成员变量。 答案:C 子类是不继承父类的构造方法的,而是必须调用其父类的构造方法。

VC++动态链接库创建和调用全过程详解

1.概论 先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。在仓库的发展史上经历了“无库-静态链接库-动态链接库”的时代。 静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。 对动态链接库,我们还需建立如下概念: (1)DLL 的编制与具体的编程语言及编译器无关 只要遵循约定的DLL接口规范和调用方式,用各种语言编写的DLL都可以相互调用。譬如Windows提供的系统DLL(其中包括了Windows的API),在任何开发环境中都能被调用,不在乎其是Visual Basic、Visual C++还是Delphi。 (2)动态链接库随处可见 我们在Windows目录下的system32文件夹中会看到kernel32.dll、user32.dll和gdi32.dll,windows的大多数API都包含在这些DLL中。kernel32.dll中的函数主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面;gdi32.dll中的函数则负责图形方面的操作。 一般的程序员都用过类似MessageBox的函数,其实它就包含在user32.dll这个动态链接库中。由此可见DLL对我们来说其实并不陌生。 (3)VC动态链接库的分类 Visual C++支持三种DLL,它们分别是Non-MFC DLL(非MFC动态库)、MFC Regular DLL(MFC规则DLL)、MFC Extension DLL(MFC扩展DLL)。 非MFC动态库不采用MFC类库结构,其导出函数为标准的C接口,能被非MFC或MFC编写的应用程序所调用;MFC规则DLL 包含一个继承自CWinApp的类,但其无消息循环;MFC扩展DLL采用MFC的动态链接版本创建,它只能被用MFC类库所编写的应用程序所调用。 由于本文篇幅较长,内容较多,势必需要先对阅读本文的有关事项进行说明,下面以问答形式给出。 问:本文主要讲解什么内容? 答:本文详细介绍了DLL编程的方方面面,努力学完本文应可以对DLL有较全面的掌握,并能编写大多数DLL程序。 问:如何看本文? 答:本文每一个主题的讲解都附带了源代码例程,可以随文下载(每个工程都经WINRAR压缩)。所有这些例程都由笔者编写并在VC++6.0中调试通过。

Java API 试题

永隆 JAVA笔试题 一、选择题 1、关于Java 类的加载过程,下面哪些描述是正确的() A、在 Java 中,有四种类型的类加载器:BootStrapClassLoader、ExtClassLoader、AppClassLoader 以及用户自定义的ClassLoader。//Extension ClassLoader, System ClassLoader+用户自定义的classloader B、使用 new 关键字创建类实例时,其实就显示地包含了类的加载过程 C、在 Java 中,类的实例化流程分为两个部分:类的加载和类的实例化。类的加载又分为显式加载和隐式加载。 D、Class.forName 来加载类时,是通过 ExtClassLoader进行加载的。 //system classLoader 加载 2、关于HashMap的实现机制,下面哪些描述是正确的() A、HashMap中key-value 当成一个整体进行处理,系统总是根据数组的坐标来获得key-value 的存储位置。//没有存储顺序,无下标之说! B、HashMap基于哈希表的 Map 接口的实现,允许使用 null 值和 null 键。 C、如果HashMap中,如果Key的hash相同的话,HashMap将会出错。//会替换相应的value D、HashMap每次容量的扩增都是以2的倍数来增加。//大约获得2倍的桶数! 3、下面的代码执行输出正确的是() 1. public class test( 2. public int aMethod()[ 3. static int i=0; 4. i++; 5. return I; 6. ) 7. public static void main (String args[]){ 8. test test = new test(); 9. test.aMethod(); 10.int j = test.aMethod(); 11.System.out.printIn(j); 12.] 13.} A. 编译错误 B. 编译成功,打印出是“0” C. 编译成功,打印出是“1” D. 编译成功,打印出是“2” A 4、如何获取下面表单 select

VC++动态链接库(DLL)编程深入浅出

VC++动态链接库(DLL)编程深入浅出 作者:宋宝华 联系作者:e-mail:21cnbao@https://www.wendangku.net/doc/1110840573.html, 出处:Pconline 由于本文篇幅较长,内容较多,势必需要先对阅读本文的有关事项进行说明,下面以问答形式给出。 问:本文主要讲解什么内容? 答:本文详细介绍了DLL编程的方方面面,努力学完本文应可以对DLL有较全面的掌握,并能编写大多数DLL程序。 问:如何看本文? 答:本文每一个主题的讲解都附带了源代码例程,可以随文下载(每个工程都经WINRAR压缩)。所有这些例程都由笔者编写并在VC++6.0中调试通过。 当然看懂本文不是读者的最终目的,读者应亲自动手实践才能真正掌握DLL的奥妙。 问:学习本文需要什么样的基础知识? 答:如果你掌握了C,并大致掌握了C++,了解一点MFC的知识,就可以轻松地看懂本文。 目录 1、概论 2、静态链接库 3、库的调试与查看 4、非MFC DLL 5、MFC规则DLL 6、MFC扩展DLL的创建

1.概论 先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量、函数或类。在仓库的发展史上经历了“无库-静态链接库-动态链接库”的时代。 静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。 对动态链接库,我们还需建立如下概念: (1)DLL 的编制与具体的编程语言及编译器无关 只要遵循约定的DLL接口规范和调用方式,用各种语言编写的DLL都可以相互调用。譬如Windows提供的系统DLL(其中包括了Windows的API),在任何开发环境中都能被调用,不在乎其是Visual Basic、Visual C++还是Delphi。 (2)动态链接库随处可见 我们在Windows目录下的system32文件夹中会看到kernel32.dll、user32.dll和gdi32.dll,windows的大多数API都包含在这些DLL中。kernel32.dll中的函数主要处理内存管理和进程调度;user32.dll中的函数主要控制用户界面;gdi32.dll中的函数则负责图形方面的操作。 一般的程序员都用过类似MessageBox的函数,其实它就包含在user32.dll这个动态链接库中。由此可见DLL对我们来说其实并不陌生。 (3)VC动态链接库的分类 Visual C++支持三种DLL,它们分别是Non-MFC DLL(非MFC动态库)、MFC Regular DLL(MFC规则DLL)、MFC Extension DLL(MFC扩展DLL)。 非MFC动态库不采用MFC类库结构,其导出函数为标准的C接口,能被非MFC或MFC编写的应用程序所调用;MFC规则DLL 包含一个继承自CWinApp的类,但其无消息循环;MFC扩展DLL采用MFC的动态链接版本创建,它只能被用MFC类库所编写的应用程序所调用。

ClassLoader详解

ClassLoader详解 目录 1.什么是C LASS L OADER (2) 2.C LASS L OADER的层次 (2) 3.C LASS L OADER加载C LASS的过程 (5) 4.类加载器的顺序 (5) 5.JVM是如何来建立类加载器的结构 (6) 6.如何实现在运行时的动态载入和更新 (9) 7.为什么要扩展C LASS L OADER (14) 8.C LASS L OADER树和委托模型 (14) 9.U NLOADING?R ELOADING? (15) 10.由名字空间引发的 (16) 11.类的查询 (18) 12.一些重要的方法 (20) 13.怎么组装这些方法 (21) 14.J AV A 2中C LASS L OADER 的变动 (21) 15.类与数据 (22) 16.类加载器如何工作? (23) 17.名词解释 (27) 18.T IPS (27) 19.类加载原则概括: (29) 20.问题 (29) 21.其他 (34)

1.什么是ClassLoader 与普通程序不同的是,Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java虚拟机),然后再把Java class加载到JVM 里头运行,负责加载Java class的这部分就叫做Class Loader。 JVM本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,Bootstrap ClassLoader是用本地代码实现的,它负责加载核心Java Class(即所有java.*开头的类)。另外JVM还会提供两个ClassLoader,它们都是用Java语言编写的,由Bootstrap ClassLoader加载;其中Extension ClassLoader负责加载扩展的Java class(例如所有javax.*开头的类和存放在JRE的ext目录下的类),Application ClassLoader负责加载应用程序自身的类。 术语“类加载”指的是找出一个给定类名的字节所在的位置并且将这些字节转换成Java类实例的过程。 2.ClassLoader的层次 bootstrap classloader | extension classloader | app classloader app classloader 的parent是extension classloader,extension classloader的parent 是bootstrap classloader,bootstrap classloader的parent 是Null。 继承结构: Bootstrap ClassLoader |__URLClassLoader |__ExtClassLoader |__AppClassLoader

字节跳动面试经验分享(非常详细)

字节跳动面试官一招差点KO我,一共面试了3轮(5年经验),艰难拿下2-2职级offer! 前言 我从大学毕业开始做Android开发,现在已经五年时间了,现在在山东老家济南做Android开发。这三年里面,也只是一心在做Android开发,其他语言接触的并不多,了解点JS之类的。现在感觉Android开始不像以前那样好做了,也可能是现在年纪慢慢大了,要考虑的事情变多了的缘故吧。 不知道以后应该何去何从,总是感觉做Android或者说做程序员一直处在一种不稳定之中,在一些中小公司里面,可能工作一年两年就因为各种各样的原因而离职。马上就要结婚了,该买房了。济南的房价一直在涨,而自己的收入还是这么不温不火的,加上这不稳定的工作,让人对于前途实在是乐观不起来。 再加上今年的大环境非常差,互联网企业裁员的现象比往年更严重了,可今年刚好是我的第一个“五年计划”截止的时间点,说什么也不能够耽搁了,所以早早准备的跳槽也在疫情好转之后开始进行了。但是,不得不说,这次字节的面试真的太难为我了,可以说是和面试官大战了3个回合,不过好在最后给了offer。 我个人情况是5年Android开发经验,字节跳动定级2-2(年薪是50-100w左右含加班费和股票折现,不含车餐房补)的样子,我是拿到了年薪60w+,13薪。下面是我的面试经历,与学习经验分享,希望能带来一些不一样的启发和帮助。 我与字节跳动面试官“大战”3回合,胜! 我的学习经验 1—4年大学 ?Java

无论什么级别的Android从业者,Java作为Android开发基础语言。不管是工作还是面试中,Java都是必考题。如果不懂Java的话,薪酬会非常吃亏(美团尤为重视Java基础) 详细介绍了Java泛型、注解、并发编程、数据传输与序列化、高效IO、容器集合、反射与类加载以及JVM重点知识线程、内存模型、JVM运行时内存、垃圾回收与算法、Java中四种引用类型、GC 分代收集算法 VS 分区收集算法、GC 垃圾收集器、JAVA IO/NIO 、JVM 类加载机制的各大知识点。 ?筑基必备 Android架构师筑基包括哪些内容呢: 1.深入 Java 泛型. 2.解深入浅出 3.并发编程 4.数据传输与序列化 5.Java 虚拟机原理 6.反射与类加载 7.高效 IO 8.Kotlin项目实战 大学1-4年架构师筑基必备 ?学习笔记整理 架构师筑基必备目录 架构师筑基必备第一章

类的加载

类从加载到虚拟机到卸载,它的整个生命周期包括:加载(Loading),验证(Validation),准备(Preparation),解析(Resolution),初始化(Initialization),使用(Using)和卸载(Unloading)。其中,验证、准备和解析部分被称为连接(Linking)。 加载: 在加载阶段,虚拟机主要完成三件事: 1.通过一个类的全限定名来获取定义此类的二进制字节流。 2.将这个字节流所代表的静态存储结构转化为方法区域的运行时数据结构。 3.在Java堆中生成一个代表这个类的https://www.wendangku.net/doc/1110840573.html,ng.Class对象,作为方法区域数据的访问入口。 验证: 验证阶段作用是保证Class文件的字节流包含的信息符合JVM规范,不会给JVM造成危害。如果验证失败,就会抛出一个https://www.wendangku.net/doc/1110840573.html,ng.VerifyError异常或其子类异常。验证过程分为四个阶段: 1.文件格式验证:验证字节流文件是否符合Class文件格式的规范,并且能被当前虚拟机正确的处理。 2.元数据验证:是对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言的规范。 3.字节码验证:主要是进行数据流和控制流的分析,保证被校验类的方法在运行时不会危害虚拟机。

4.符号引用验证:符号引用验证发生在虚拟机将符号引用转化为直接引用的时候,这个转化动作将在解析阶段中发生。 准备: 准备阶段为变量分配内存并设置类变量的初始化。在这个阶段分配的仅为类的变量(static修饰的变量),而不包括类的实例变量。对已非final的变量,JVM会将其设置成“零值”,而不是其赋值语句的值: pirvate static int size = 12; 那么在这个阶段,size的值为0,而不是12。final修饰的类变量将会赋值成真实的值。 解析: 解析过程是将常量池内的符号引用替换成直接引用。主要包括四种类型引用的解析。类或接口的解析、字段解析、方法解析、接口方法解析。 初始化: 在准备阶段,类变量已经经过一次初始化了,在这个阶段,则是根据程序员通过程序制定的计划去初始化类的变量和其他资源。这些资源有static{}块,构造函数,父类的初始化等。 至于使用和卸载阶段阶段,这里不再过多说明,使用过程就是根据程序定义的行为执行,卸载由GC完成。

用JS启动一个应用程序或加载一个动态链接库

用JS启动一个应用程序或加载一个动态链接库 请输入要运行的程序:







Java程序是如何运行的

Java程序是如何运行的 JVM是Java的运行时虚拟机,所有的Java程序都是在JVM沙箱中运行,每个Java程序就是一个独立的JVM进程。 谈到Java程序是如何运行的,首先需要理解的肯定是JVM是如何运行的,什么是JVM;要理解我们编写的Java程序,运行起来以后到底是什么样子,本质上就是弄清楚JVM是什么样子。 Java程序的代码是什么样的 Java诞生之初最大的卖点就是编写的代码跨平台可移植性,实现这种可移植性,是因为Java通过平台特定的虚拟机,运行中间的字节码,而不是直接编译成本地二进制代码实现,中间字节码也就是java文件编译后生成的.class文件,Jar包的话,实际上只是一系列.class文件的集合。 编写Java程序,首先需要一个入口点,在运行的时候通过指定MainClass来指定入口点,代码层面主类必须实现一个静态的main函数,运行时虚拟机会从MainClass.main开始执行指令,其他的逻辑只是import和函数调用了。 SDK自带的javac命令,负责将我们编程的Java代码,也就是.java文件,编译成平台无关的字节码;字节码可以在任何操作系统平台上,通过平台对应的JVM执行;JVM执行的时候,运行字节码,根据自己的平台特性,将字节码转换成平台相关的二进制码运行。 javac编译器运行的过程大致分为:词法分析(Token流)、语法分析(语法树)、语义分析(注解语法树),还有代码生成器,根据注解语法树,生成字节码, 语义分析阶段,编译器会做一些操作,将人类友好的代码,做一些处理,转换成更符合机器执行机制的代码,例如全局变量,魔法变量,依赖注入,注解这些魔法机制。大致分为以下步骤: 1. 给类添加默认构造函数 2. 处理注解 3. 检查语义的合法性并进行逻辑判断 4. 数据流分析 5. 对语法树进行语义分析(变量自动转换并去掉语法糖) JVM是什么 JVM = 类加载器 classloader + 执行引擎 execution engine + 运行时数据区域 runtime data area JVM就是运行编译好字节码的虚拟机,不同的操作系统和平台上,虚拟机将平台无关的字节码,编译成特定平台的指令去执行。我觉得,JVM首先是一个独立运行在操作系统上的进程。执行java命

java多选题

java多选题 多选题 1、下列选项代码正确的有()。 A、 int i=0; if (i) { System.out.println(“OK”); } B、 boolean b=true; boolean b2=true; if(b==b2) { System.out.println(“OK”); } C、 int i=1; int j=2; if(i==1 &| j==2) System.out.println(“OK”); D、 int i=1; int j=2; if (i==1 || j==2) System.out.println(“OK”); 解答:B, D 知识点:3.3 Java语言算术运算符、关系运算符、逻辑运算符、位运算符和复合赋值运算符的功能及使用; 2、下面哪三项演示了继承关系(is a)?() A、interface Component{ } class Container extends Component{} B、class Father { } class son extends Father { } C、abstract class Colorable { } class Shape extends Colorable { } D、public class Species{ } public class Animal{private Species species;} E、interface Person { } public class Employee implements Person{ } 解答:B,C,E 知识点:5.3 Java 父类与子类、域继承和方法继承的操作过程。

java类加载机制

Java类加载机制(一) 译:ayi 第一次翻译,翻译得不是很好,请多多指点 我的邮箱:nonopo12345@https://www.wendangku.net/doc/1110840573.html, 原文:https://www.wendangku.net/doc/1110840573.html,/pub/a/onjava/2005/01/26/classloading.html 类加载是java特性的一个重量级的组成部分。尽管,java中“advanced topics”的发展,使java的类加载机制的地位有所下降。但每位编程着都应该知道这部分的工作机制,以及怎样去更好与其配合。这可以使我们节省很多时间,二不必要浪费在调试ClassNotFoundException, ClassCastException, 等。 这篇文章将从最基本的开始,比如代码和数据的关系和区别,以及他们怎么样关系起来形成一个实例或者对象。然后将会说到,java中怎样通过类加载器把代码加载到JVM中,以及java中实现的主要的几种类型的类加载器。然后在这篇文章中我们将会了解到java类加载机制的内幕,我们将使用最基本的代码来描述,这些代码执行与类加载器之后,但在加载一个类之前。在接下来的部分将使用一些例子来强调,对于开发者继承和开发自己的类加载器的必要性。接着将告诉你们怎样编写自己的类加载器,以及怎样使用它们去创建一个一般的能加载包括远程客户端辅助代码的类加载器引擎,以及怎样把它在JVM中定义,实例化,然后执行。习惯上,把J2EE-specific components 中说明的作为java类加载的规范,这篇文章正是从这本手册总结来的。 类和数据 一个类代表一段要执行的代码,然而数据则代表与这些代码相关联的某种状态。状态可以改变,代码不能改变。我们把一种特定状态与一个类关联起来时,就得到了这个类的一个实例。所以同一个类的不同实例有不同的状态,但都参照相同的代码。在java中,一个类通常它的代码就包含在一个 .class 文件中,虽然其中也包括异常。然而,在java运行时,每个类都会构造一个超类对象(first-class object),它们其实是https://www.wendangku.net/doc/1110840573.html,ng.Class的实例。不论何时编译一个java文件,编译器都会在编译后的字节码中嵌入一个public, static, final型的字段class,这个字段表示的就是一个https://www.wendangku.net/doc/1110840573.html,ng.Class型的实例。因为它是public类型的,我们可以通过标识符来访问它,像这样: https://www.wendangku.net/doc/1110840573.html,ng.Class klass = Myclass.class; 只要一个类被加载到JVM,相同的类(强调:相同的类)将不会被重复加载。这将产生一个问题,什么才是相同的类?一个对象有一种特定状态和标识,对象总是与它所属类联系在一起,与这种状况相似,一个被加载到JVM中类也有特定的标识,接下来我们就阐述: 在java中,一个类通过认证的类全名来唯一标识。认证的类全名是由包名和类名两部分组

java实验指导书

实验一java开发环境及语言基础 实验目的 (1)确保正确配置java开发环境。 (2)了解javac和java命令的使用。 (3)熟悉java中的运算符。 (4)掌握条件语句和循环语句的使用。 (5)掌握通过命令行参数接受数据。 (6)掌握用Scanner类接受数据。 实验内容 (1)在控制台中输入java命令,查看输入结果。 (2)编写一个java程序,计算半径为3.0的圆周长和面积并输出结果。 (3)求a+aa+aaa+...+a...a(n个)的和,其中a为1~9之间的整数。例如,当a=3、n=4时,求3+33+333+3333的和。 (4)给定一个正整数m,统计其位数,分别打印每一位数字,再按照逆序打印出各位数字。(5)用Scanner类方法输入三角形三边求三角形面积。 实验要求 (1)JDK的安装及配置。 (2)在DOS及eclipse下编辑、编译运行第一个java程序:hello world。 (3)求圆周长和面积用方法实现,主函数调用。 (4)从命令行输入1~9之间的整数a,当所求的和大与106时,输出相应的a值及所求的和值。 (5)用Scanner类的方法输入正整数m,m的值不应该超过99999,否则给出错误信息。应引入包:import java.util.Scanner,然后在需要的方法中实例化对象:Scanner sc = new Scanner(System.in),最后调用对象的next方法,如int n=nextInt(),接受整数。 实验二数组 实验目的 (1)掌握数组的定义和使用方法。 (2)熟悉数组的排序、查找的方法。 (3)巩固循环的使用。 实验内容 (1)使用for循环,将二维数组的行与列互换,即完成矩阵的转置。 (2)编写数组的排序程序。 (3)编写杨辉三角。 实验要求 (1)编写一个界面1 选择排序2 冒泡排序3插入排序4 快速排序5 退出 当选择1、2、3、4、5的时候完成相应的功能。 (2)杨辉三角形状为等腰三角形 实验三字符串 实验目的 (1)掌握正则表达式的使用。 (2)熟悉java的字符串。

java 使用tomcat类加载器加载类,找不到加载器

The Tomcat installation directory is not valid. It is missing expected file or folder common/i18n. eclipse 配置使用apache-tomcat-5.5.34时,提示如上。 换了个apache-tomcat-5.5.29 的版本。 但是加载启动项目时,出现类加载器无法加载类。因为apache-tomcat-5.5.29 版本中缺少类加载器的类。 Caused by: https://www.wendangku.net/doc/1110840573.html,ng.ClassNotFoundException: org.apache.catalina.loader.WebappLoader 在\apache-tomcat-5.5.29\conf\Catalina\localhost 下会有项目配置的比如project.xml运行生成。这样启动的时候才会把项目加载上。 在eclipse\plugins\com.sysdeo.eclipse.tomcat_3.2.1 找到DevLoader.zip 文件夹。 1、在eclipse目录下,找到DevLoader包,位于 eclipse\plugins\com.sysdeo.eclipse.tomcat_3.2.1的DevLoader.zip 2、复制DevLoader.zip到Tomcat apache-tomcat-5.5.29 的\lib下。 3、解压缩DevLoader.zip在当前文件夹,然后把\DevLoader 下的org文件夹全部copy到\apache-tomcat-5.5.29\server\classes下。必须是server\classes 下,而不能是apache-tomcat-5.5.29\common\classes 下。

Java开源架构技术学习重点(部分答案版)(1)

第一章 Strut2框架技术的入门 1、Struts2的是怎么产生的? Struts2是Struts的下一代产品,是在Struts1和WebWork的技术基础上进行了合并,全新的Struts2框架。其全新的Struts2的体系结构与Struts1的体系结构的差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与Servlet API完全脱离开,所以Struts 2可以理解为WebWork的更新产品。因此Struts2和Struts 1有着太大的变化,但是相对于WebWork,Struts2只有很小的变化。 2、Struts2的设计模式是什么?采用这种设计模式有什么好处? MVC模式 MVC模式对于Web应用的开发无疑是一种非常先进的设计思想,无论选择 哪种语言,无论应用多复杂,它都能为理解分析应用模型提供最基本的分析方法, 为构造产品提供清晰的设计框架,为软件工程提供规范的依据。 1. 模型(Model) Model 部分包括业务逻辑层和数据库访问层。在Java Web 应用程序中,业务逻辑层一般由JavaBean或EJB构建。Model 部分就是业务流程或状态的处理以及业务规则的制定。业务流程的处理过程对其他层来说是黑箱操作,模型接受视图请求的数据,并返回最终的处理结果。业务模型的设计可以说是MVC最主要的组件。MVC并没有提供模型的设计方法,而只提供给用户应该组织管理这些模型,以便于模型的重构和提高重用性。 2. 视图(View) 在Java Web 应用程序中,View 部分一般用JSP 和HTML 构建,也可以是XHTML、XML、Applet和JavaScript。客户在View 部分提交请求,在业务逻辑层处理后,

关于DLL动态库调用

关于DLL动态库调用小结 引言 比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。在构造软件系统时,如果将所有模块的源代码都静态编译到整个应用程序EXE 文件中,会产生一些问题:一个缺点是增加了应用程序的大小,它会占用更多的磁盘空间,程序运行时也会消耗较大的内存空间,造成系统资源的浪费;另一个缺点是,在编写大的EXE程序时,在每次修改重建时都必须调整编译所有源代码,增加了编译过程的复杂性,也不利于阶段性的单元测试。 Windows系统平台上提供了一种完全不同的较有效的编程和运行环境,你可以将独立的程序模块创建为较小的DLL(Dynamic Linkable Library)文件,并可对它们单独编译和测试。在运行时,只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。这种方式不仅减少了EXE文件的大小和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序使用。Windows自己就将一些主要的系统功能以DLL 模块的形式实现。 一般来说,DLL是一种磁盘文件,以.dll、.DRV、.FON、.SYS和许多以.EXE为扩展名的系统文件都可以是DLL。它由全局数据、服务函数和资源组成,在运行时被系统加载到进程的虚拟空间中,成为调用进程的一部分。如果与其它DLL之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。DLL模块中包含各种导出函数,用于向外界提供服务。DLL可以有自己的数据段,但没有自己的堆栈,使用与调用它的应用程序相同的堆栈模式;一个DLL在内存中只有一个实例;DLL实现了代码封装性;DLL的编制与具体的编程语言及编译器无关。 在Win32环境中,每个进程都复制了自己的读/写全局变量。如果想要与其它进程共享内存,必须使用内存映射文件或者声明一个共享数据段。DLL模块需要的堆栈内存都是从运行进程的堆栈中分配出来的。Windows在加载DLL模块时将进程函数调用与DLL文件的导出函数相匹配。Windows操作系统对DLL的操作仅仅是把DLL映射到需要它的进程的虚拟地址空间里去。DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有. 调用方式

JAVA判断题含答案

判断题 1. 利用equals()方法判定Date类时,判断的是对象的值而不是对象的地址。 A. 错误 B. 正确 2. 类加载器加载程序运行所需要的所有类,它通过区分本机文件系统的类和网络系统导入的类增加安全性。 A. 错误 B. 正确 1. == 操作符判定两个分立的对象的内容和类型是否一致。 A. 错误 B. 正确 2. 类加载器加载程序运行所需要的所有类,由网络系统导入的指定类总是先被加载。 A. 错误 B. 正确 1. equals()方法只有在两个对象的内容一致时返回true。 A. 错误 B. 正确 2. 调用System.gc()方法不能保证JVM立即进行垃圾收集,而只能是建议。 A. 错误 B. 正确 1. friendly关键字是Java语言的访问控制修饰符。 A. 错误 B. 正确 2. maxElements是一个成员变量,声明为:“public static final int maxElements=100;”。 A. 错误 B. 正确

3. 实例变量在使用new Xxxx()创建该类的实例时被创建,而其生存期和该类的实例对象的生存期相同。 A. 错误 B. 正确 4. 在构造方法中如调用super()语句,则必须使其成为构造方法中的第一条语句。 A. 错误 B. 正确 5. 重写的方法的访问权限不能比被重写的方法的访问权限高。 A. 错误 B. 正确 6. 类变量在该类被加载时被创建,不能用new Xxxx()创建,所有该类的实例对象共享类变量,其生存期是类的生存期。 A. 错误 B. 正确 7. 调用sleep()方法可以使一个线程停止运行。 A. 错误 B. 正确 8. 一个新线程启动start()方法,表示线程可为JVM的线程调度程序调度而不表示它可以立即运行。 A. 错误 B. 正确 9. 垃圾收集的过程在Java程序的生存期中是自动的,不需要分配和释放内存,也避免了内存泄漏。 A. 错误 B. 正确 10. equals()方法只有在两个对象的内容一致时返回true。 A. 错误 B. 正确

JAVA笔试题1

知识点: (1) 1.面向对象的软件开发有哪些优点? (1) 2.什么叫对象?什么叫类?类和对象有什么关系。 (1) 3.什么是包?把一个类放在包里有什么作用? (2) 4.作用域public、private、protected以及不写时(default)有什么区别? (2) 5.什么是方法?方法的结构是怎样的?设计方法应考虑哪些因素? (2) 6.什么是方法的覆盖?与方法的重载有何不同?方法的覆盖与属性的隐藏有何不同? (3) 7.什么是成员变量、局部变量、类变量和实例变量? (3) 8.什么是继承?什么是父类?什么是子类?继承的特性可给面向对象编程带来什么好处? (3) 9.什么是多态?面向对象程序设计为什么要引入多态的特性? (4) 10.“子类的域和方法的数目一定大于等于父类的域和方法的数目”,这种说法是否正确?为什么? (4) 11.父类对象与子类对象相互转化的条件是什么?如何实现它们的相互转化? (4) 12.接口与抽象类有哪些异同点? (4) 13.区分接口与抽象类分别在什么场合使用? (5) 14.一个类如何实现接口?实现某接口的类是否一定要重载该接口中的所有抽象方法? (5) 15.进程与线程的区别与联系? (5) 编程: (6) 1.统计一个字符串中出现某个字母的次数(注意区分大小写)。 (6) 2.编写一个程序,在主类中创建和调用方法sumf(),方法sumf()的功能是进行两个浮点数的加法运算。6知识点: 1.面向对象的软件开发有哪些优点? 面向对象设计是一种把面向对象的思想应用于软件开发过程中,指导开发活动的系统方法,是建立在“对象”概念基础上的方法学。所谓面向对象就是基于对象概念,以对象为中心,以类和继承为构造机制,来认识、理解、刻画客观世界和设计、构建相应的软件系统。 从面向过程到面向对象是程序设计技术的一个飞跃。人们之所以要采用面向对象的程序设计技术,其目的在于:按照与人类习惯思维方法一致的原则开发系统;提高代码的可重用性(或者称为复用性);提升程序的开发与运行效率;提高程序的可靠性与可维护性;提高程序的可扩展性;增强程序的可控制性。总之,面向对象的程序设计,能够有效分解、降低问题的难度与复杂性,提高整个求解过程的可控制性、可监视性和可维护性,从而获得较高的开发效率与可靠效果。 2.什么叫对象?什么叫类?类和对象有什么关系。 对象(Object)是一个应用系统中用来描述客观事物的实体,是具有特定属性(数据)和行为(方法)的基本运行单位,是类的一个特定状态下的实例。对象是一件事、一个实体、一个名词、一个可以想象为有自己的标识的任何东西。对象是类的实例化。概括来说:万物皆对象。对象具有状态,一个对象用数据值来描述它的状态。 类(Class)是Java代码的基本组织模块,是用以描述一组具有共同属性和行为的对象的基本原型,是对这组对象的概括、归纳与抽象表达。类是对象的模板,它定义了本类对象所应拥有的状态属性集及操作这组属性的行为方法集。是对一组有相同数据和相同操作的对象的定义,一个类所包含的方法和数据描述一组对象的共同属性和行为。

ELF文件的加载和动态链接过程

ELF 文件的加载和动态链接过程 本文的目的:大家对于Hello World 程序应该非常熟悉,随便使用哪一种语言,即使还不熟悉的语言,写出一个Hello World 程序应该毫不费力,但是如果让大家详细的说明这个程序加载和链接的过程,以及后续的符号动态解析过程,可能还会有点困难。本文就是以一个最基本的C 语言版本Hello World 程序为基础,了解Linux 下ELF 文件的格式,分析并验证ELF 文件和加载和动态链接的具有实现。 本文的实验平台: Ubuntu 7.04 Linux kernel 2.6.20 gcc 4.1.2 glibc 2.5 gdb 6.6 objdump/readelf 2.17.50 本文的组织: 第一部分大致描述ELF 文件的格式; 第二部分分析ELF 文件在内核空间的加载过程; 第三部分分析ELF 文件在运行过程中符号的动态解析过程; (以上各部分都是以Hello World 程序为例说明) 第四部分简要总结; 第五部分阐明需要深入了解的东西。 一、 ELF 文件格式 1. 概述 Executable and Linking Format(ELF)文件是x86 Linux 系统下的一种常用目标文件(object file)格式,有三种主要类型: 1) 适于连接的可重定位文件(relocatable file),可与其它目标文件一起创建可执行文件 和共享目标文件。 2) 适于执行的可执行文件(executable file),用于提供程序的进程映像,加载的内存执 行。 3) 共享目标文件(shared object file),连接器可将它与其它可重定位文件和共享目标文 件连接成其它的目标文件, 动态连接器又可将它与可执行文件和其它共享目标文件

相关文档