面试考点图
JAVASE部分
Java基础
- Java是什么
Java是一门面向对象编程语言,可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序。
1.Java语言吸收了C++语言的各种优点,具有功能强大和简单易用两个特征。
2.Java语言作为静态面向对象编程语言的代表,实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
3.Java具有简单性、面向对象、分布式、安全性、平台独立与可移植性、动态性等特点。
4.Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等。 - 正则表达式
元字符
代码 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线或汉字[0-9,A-Z,a-z] |
\s | 匹配任意的空白符[\t \n \r \f] |
\d | 匹配数字[0—9] |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
\b | 匹配字符串的结束 |
重复
代码/语法 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
反义
代码/语法 | 说明 |
---|---|
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^aeiou] | 匹配除了aeiou这几个字母以外的任意字符 |
- 请你谈谈Java中是如何支持正则表达式操作的
Java中的String类提供了支持正则表达式操作的方法,包括:matches()、replaceAll()、replaceFirst()、split()。此外,Java中可以用Pattern类表示正则表达式对象,它提供了丰富的API进行各种正则表达式操作。 - 请你讲讲&和&&的区别?
&&运算符是短路与运算。&逻辑与跟&&短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true整个表达式的值才是true。&&之所以称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式会被直接短路掉,不会进行运算。 - 基本类型与包装类型
Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Java为每个原始类型提供了封装类。
原始类 | 型封装类 |
---|---|
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为null,而原始类型实例变量的缺省值与它们的类型有关。
1.包装类型可以为 null,而基本类型不可以
2.包装类型可用于泛型,而基本类型不可以
3.基本类型比包装类型更高效
- 自动装箱和自动拆箱
有了基本类型和包装类型,肯定有些时候要在它们之间进行转换。把基本类型转换成包装类型的过程叫做装箱。反之,把包装类型转换成基本类型的过程叫做拆箱在 Java SE5 之前,开发人员要手动进行装拆箱。Java SE5 为了减少开发人员的工作,提供了自动装箱与自动拆箱的功能。
自动装箱是通过Integer.valueOf()
完成的;自动拆箱是通过Integer.intValue()
完成的。
当需要进行自动装箱时,如果数字在 -128 至 127 之间时,会直接使用缓存中的对象,而不是重新创建一个对象。
// 1)基本类型和包装类型
int a = 100;
Integer b = 100;
System.out.println(a == b);//true
// 2)两个包装类型
Integer c = 100;
Integer d = 100;
System.out.println(c == d);//true
// 3)
Integer c = 200;
Integer d = 200;
System.out.println(c == d);//false
- String、StringBuilder、StringBuffer三者的区别
String | StringBuffer | StringBuilder |
---|---|---|
String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且浪费大量优先的内存空间 | StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量 | 可变类,速度更快 |
不可变 | 可变 | 可变 |
线程安全 | 线程不安全 | |
多线程操作字符串 | 单线程操作字符串 |
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。当对字符串进行修改的时候,特别是字符串对象经常改变的情况下,需要使用 StringBuffer 和 StringBuilder 类。
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
- equals和==的区别?
1.==是判断两个变量或实例是不是指向同一个内存空间,equals是判断两个变量或实例所指向的内存空间的值是不是相同
2.==是指对内存地址进行比较 , equals()是对字符串的内容进行比较
3.==指引用是否相同, equals()指的是值是否相同 - 请你讲讲数组(Array)和列表(ArrayList)的区别?什么时候应该使用Array而不是ArrayList?
-Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
-Array大小是固定的,ArrayList的大小是动态变化的。
-ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。 - 请你解释什么是值传递和引用传递?
值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量.
引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。 所以对引用对象进行操作会同时改变原对象.
一般认为,java内的传递都是值传递. - 请你解释为什么会出现4.0-3.6=0.40000001这种现象?
二进制的小数无法精确的表达十进制小数,计算机在计算10进制小数的过程中要先转换为2进制进行计算,这个过程中出现了误差。 - Lambda 表达式
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
优点:简洁,非常容易并行计算, 可能代表未来的编程趋势。
缺点:1. 若不用并行计算,很多时候计算速度没有比传统的 for 循环快。(并行计算有时需要预热才显示出效率优势)2. 不容易调试。3. 若其他程序员没有学过 lambda 表达式,代码不容易让其他语言的程序员看懂。 - 你知道java8的新特性吗,请简单介绍一下?
(1)Lambda 表达式 − Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中。
(2)方法引用− 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
(3)默认方法− 默认方法就是一个在接口里面有了一个实现的方法。
(4)Nashorn, JavaScript 引擎 − Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。 - 请你介绍一下map的分类和常见的情况
java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMap Hashtable LinkedHashMap 和TreeMap.
Map主要用于存储健值对,根据键得到值,因此不允许键重复(重复了覆盖了),但允许值重复。
HashMap | Hashtable | LinkedHashMap | TreeMap |
---|---|---|---|
Hashmap 是一个最常用的Map,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。 HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null。 | Hashtable继承自Dictionary类,它不允许记录的键或者值为空;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了 Hashtable在写入时会比较慢。 | LinkedHashMap 是HashMap的一个子类,保存了记录的插入顺序。 | TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。 |
关键字
- Java里面的final关键字是怎么用的?
final关键字是最终的意思,可以修饰成员方法,成员变量,类
修饰特点: -修饰方法:表明方法是最终方法,不能被重写
-修饰变量:表名该变量是常量,不能再次被赋值
-修饰类: 表明该类是最终类,不能被继承
修饰局部变量:
-变量是基本类型:final修饰指的是基本类型的数据值不能发生改变
-变量是引用类型:final修饰指的是引用类型的地址值不能发生改变,
但是地址里面的内容是可以发生改变的 - 请你谈谈关于Synchronized和Lock
synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。
Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。 - Syncronized锁修饰一个静态方法,锁住了什么?如果修饰成员方法,锁住了什么?
synchronized修饰静态方法以及同步代码块的synchronized (类.class)用法锁的是类,线程想要执行对应同步代码,需要获得类锁。
synchronized修饰成员方法,线程获取的是当前调用该方法的对象实例的对象锁。 - 请说明Java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?
Java中的方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。与此相对,方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的方法的访问。
面向对象
-
面向对象的"六原则一法则"
(1)单一职责原则:一个类只做它该做的事情(高内聚,低耦合)
(2)开闭原则:软件实体应当对扩展开放,对修改关闭。(抽象,封装可变性)
(3)依赖倒转原则:面向接口编程。(尽可能使用抽象类型而不用具体类型)
(4)里氏替换原则:任何时候都可以用子类型替换掉父类型。(能用父类型的地方就一定能使用子类型)
(5)接口隔离原则:接口要小而专,绝不能大而全。(接口也应该是高度内聚的)
(6)合成聚合复用原则:优先使用聚合或合成关系复用代码。(任何时候都不要继承工具类,工具是可以拥有并可以使用的,而不是拿来继承的)
(7)迪米特法则:迪米特法则又叫最少知识原则,一个对象应当对其他对象有尽可能少的了解。(减少系统的耦合度和复杂度) -
请说明重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求。重载的方法不能根据返回类型进行区分! -
Java异常有哪几种?
Java异常从Throwable直接派生出Exception和Error。其中Exception是可以抛出的基本类型,在Java类库、方法以及运行时故障中都可能抛出Exception型异常。Exception表示可以恢复的异常,是编译器可以捕捉到的;Error表示编译时和系统错误,表示系统在运行期间出现了严重的错误,属于不可恢复的错误,由于这属于JVM层次的严重错误,因此这种错误会导致程序终止执行。Exception又分为检查异常和运行时异常。异常类的结构层次图如下:
典型的RuntimeException(运行时异常)
包括NullPointerException(空指针异常), ClassCastException(类型转换异常),IndexOutOfBoundsException(越界异常), IllegalArgumentException(非法参数异常),ArrayStoreException(数组存储异常),AruthmeticException(算术异常),BufferOverflowException(缓冲区溢出异常)等;
非RuntimeException(检查异常)
包括IOException(输入输出异常), SQLException,InterruptedException(中断异常-调用线程睡眠时候),NumberFormatException(数字格式化异常)等。 -
有return的情况下try catch finally的执行顺序
1、不管有没有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。 -
说明JAVA语言如何进行异常处理
关键字 : throws,throw,try,catch,final
throws是获取异常
throw是抛出异常
try是将会发生异常的语句括起来,从而进行异常的处理,
catch是如果有异常就会执行他里面的语句,
而finally不论是否有异常都会进行执行的语句 -
抽象类和接口的区别
抽象类是一种对事物的抽象,而接口是一种对行为的抽象。
1.一个子类只能继承一个抽象类,但能实现多个接口(单继承,多实现)
2.抽象类中可以不全是抽象方法,而接口中全是抽象方法
3.抽象类中可以有构造方法,而接口中没有
4.抽象类中可以有普通成员变量,而接口中没有
5.抽象类和接口都可以有静态成员变量,抽象类中静态成员变量访问类型任意,但接口只能public static final(默认情况);抽象类中可以有静态方法,而接口不能有
6.抽象类中的方法可以是public protected,而接口只有public
- 面向对象的特征
(1)抽象 (2)继承 (3)封装 (4)多态性 - 请说明Java是否支持多继承
Java中类不支持多继承,只支持单继承(即一个类只有一个父类)。 但是java中的接口支持多继承,即一个子接口可以有多个父接口。(接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,当类实现接口时,类就扩展了相应的功能)。 - 请你讲讲什么是泛型?
泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型。它的本质是参数类型,也就是说所操作的数据类型被指定为一个参数,它将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型。这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口。 - 请说明”static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?
“static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。
Java中static方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而static方法是编译时静态绑定的。static方法跟类的任何实例都不相关,所以概念上不适用。
集合
- 请说明List、Map、Set三个接口存取元素时,各有什么特点?
List:以特定索引来存取元素,可以有重复元素。
Set:不能存放重复元素(用对象的equals()方法来区分元素是否重复)。
Map:保存键值对(key-value pair)映射,映射关系可以是一对一或多对一。
Set和Map容器都有基于哈希存储和排序树的两种实现版本,基于哈希存储的版本理论存取时间复杂度为O(1),而基于排序树版本的实现在插入或删除元素时会按照元素或元素的键(key)构成排序树从而达到排序和去重的效果。 - 请你说明HashMap和Hashtable的区别?
HashMap和Hashtable都实现了Map接口,因此很多特性非常相似。但是,他们有以下不同点:
(1)HashMap允许键和值是null,而Hashtable不允许键或者值是null。
(2)Hashtable是同步的,而HashMap不是。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
(3)HashMap提供了可供应用迭代的键的集合,因此,HashMap是快速失败的。另一方面,Hashtable提供了对键的列举(Enumeration)。
(4)一般认为Hashtable是一个遗留的类。 - 请简单说明一下什么是迭代器?
Iterator提供了统一遍历操作集合元素的统一接口, Collection接口实现Iterable接口,
每个集合都通过实现Iterable接口中iterator()方法返回Iterator接口的实例, 然后对集合的元素进行迭代操作.有一点需要注意的是:在迭代元素的时候不能通过集合的方法删除元素, 否则会抛出ConcurrentModificationException 异常. 但是可以通过Iterator接口中的remove()方法进行删除. - 请解释一下TreeMap?
TreeMap是一个有序的key-value集合,基于红黑树(Red-Black tree)的 NavigableMap实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator进行排序,具体取决于使用的构造方法。
TreeMap的特性:
(1)根节点是黑色
(2)每个节点都只能是红色或者黑色
(3)每个叶节点(NIL节点,空节点)是黑色的。
(4)如果一个节点是红色的,则它两个子节点都是黑色的,也就是说在一条路径上不能出现两个红色的节点。
(5)从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。 - 如果hashMap的key是一个自定义的类,怎么办?
使用HashMap,如果key是自定义的类,就必须重写hashcode()和equals()。
线程
- 请你简要说明一下线程的基本状态以及状态之间的关系?
其中Running表示运行状态,Runnable表示就绪状态(万事俱备,只欠CPU),Blocked表示阻塞状态,阻塞状态又有多种情况,可能是因为调用wait()方法进入等待池,也可能是执行同步方法或同步代码块进入等锁池,或者是调用了sleep()方法或join()方法等待休眠或其他线程结束,或是因为发生了I/O中断。 - 请介绍一下线程同步和线程调度的相关方法。
-wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;
-sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常;
-notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关;
-notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态; - 线程状态
1.新建状态(NEW):新创建了一个线程对象。
2.就绪状态(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。
3.运行状态(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
4.阻塞状态(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种:
(一)等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
(二)同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
(三)其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
5.死亡状态(DEAD):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
- Java中有几种方法可以实现一个线程? 第二个问题:用什么关键字修饰同步方法?
实现线程的方法:继承Thread类、实现Runnable接口、实现Callable接口
使用synchronized,wait与notify关键字修饰同步方法。 - ** 请说明一下sleep() 和 wait() 有什么区别?**
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,把执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。 - 请说明一下线程池有什么优势?
第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能执行。
第三:提高线程的可管理性,线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。 - 什么是死锁?死锁是怎么产生的?死锁产生的四个必要条件?死锁避免的方法?
死锁:多个并发进程因争夺系统资源而产生相互等待的现象
产生原理:当一组进程中的每个进程都在等待某个事件发生,而只有这组进程中的其他进程才能触发该事件,这就称这组进程发生了死锁。
死锁产生的4个必要条件:
(1)互斥: 某种资源一次只允许一个进程访问,即该资源一旦分配给某个进程,其他进程就不能再访问,直到该进程访问结束。
(2)占有且等待: 一个进程本身占有资源(一种或多种),同时还有资源未得到满足,正在等待其他进程释放该资源。
(3)不可抢占: 别人已经占有了某项资源,你不能因为自己也需要该资源,就去把别人的资源抢过来。
(4)循环等待: 存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。
避免死锁的方法:
(1)死锁预防:a.破坏”占有且等待"条件 b.破坏“不可抢占”条件 c.破坏“循环等待”条件
(2)死锁避免: 1、如果一个进程的请求会导致死锁,则不启动该进程
2、如果一个进程的增加资源请求会导致死锁 ,则拒绝该申请。
(3)死锁检测:在检测到运行系统进入死锁,进行恢复-允许系统进入到死锁状态。
(4)死锁的解除:
1.抢占资源:从一个或多个进程中抢占足够数量的资源分配给死锁进程,以解除死锁状态。
2.终止(或撤销)进程:终止或撤销系统中的一个或多个死锁进程,直至打破死锁状态。
JDK
- JDK和JRE区别?
jdk(java develop kit)可以认为是java运行工具集(java运行工作箱子)
jre(java runtime environment)可以认为是java运行环境
反射
- 请说明一下JAVA中反射的实现过程和作用分别是什么?
实现过程:JAVA语言编译之后会生成一个.class文件,反射就是通过字节码文件找到某一个类、类中的方法以及属性等。反射的实现主要借助以下四个类:Class(类的对象),Constructor(类的构造方法),Field(类中的属性对象),Method(类中的方法对象)。
作用:反射机制指的是程序在运行时能够获取自身的信息。在JAVA中,只要给定类的名字,那么就可以通过反射机制来获取类的所有信息
JVM
- 什么是JVM?JVM的作用?
JVM是Java Virtual Machine(Java虚拟机)的缩写。虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java虚拟机屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。简单来说JVM是用来解析和运行Java程序的。 - JVM内存机制?
JVM栈由堆、虚拟机栈、本地方法栈、方法区、程序计数器等部分组成,结构图如下所示:
(1)堆:所有通过new创建的对象的内存都在堆中分配
(2)虚拟机栈:每个线程执行每个方法的时候都会在栈中申请一个栈帧,每个栈帧包括局部变量区和操作数栈,用于存放此次方法调用过程中的临时变量、参数和中间结果。
(3)本地方法栈:用于支持native方法的执行,存储了每个native方法调用的状态。
(4)方法区:存放了要加载的类信息、静态变量、final类型的常量、属性和方法信息。
(5)程序计数器:可看做当前线程执行字节码的行号指示器,字节码解释器工作时通过改变计数器的值来选择下一条所需执行的字节码指令 - 请问什么是java序列化?以及如何实现java序列化?
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。
序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。