面试考察知识点如下:
一.序列化的实现方式
概念:序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
目的:1、以某种存储形式使自定义对象持久化; 2、将对象从一个地方传递到另一个地方。
实现方法:
1:被序列化的类要实现 java.io.Serializable 接口,序列化时,需要用到对象输出流ObjectOutputStream ,然后通过文件输出流构造 ObjectOutputStream 对象调用writeObject写入到文件 ,反之,反序列化时用到对象输入流ObjectIntputStream, 然后通过文件输出流构造 ObjectIntputStream对象调用readObject加载到内存,注意,是返回万能Object类型
注意:序列化时transient变量(这个关键字的作用就是告知JAVA我不可以被序列化)和静态变量不会被序列化(关于静态变量不会序列化保留意见,本实例先不用静态变量) ,也是最应该注意的,如果你先序列化对象A后序列化B,那么在反序列化的时候一定记着JAVA规定先读到的对象是先被序列化的对象,不要先接收对象B,那样会报错。
序列化
//创建一个对象输出流,将对象输出到文件
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(fileName));
out.writeObject("序列化日期是:"); //序列化一个字符串到文件
out.writeObject(new Date()); //序列化一个当前日期对象到文件
UserInfo user=new UserInfo("renyanwei","888888",20);
out.writeObject(user); //序列化一个会员对象
out.close();
反序列化
//创建一个对象输入流,从文件读取对象
ObjectInputStream in=new ObjectInputStream(new FileInputStream(fileName));
//注意读对象时必须按照序列化对象顺序读,否则会出错
//读取字符串
String today=(String)(in.readObject());
System.out.println(today);
//读取日期对象
Date date=(Date)(in.readObject());
System.out.println(date.toString());
//读取UserInfo对象并调用它的toString()方法
UserInfo user=(UserInfo)(in.readObject());
System.out.println(user.toString());
in.close();
2: 被序列化的类要实现java.io.Externalizable接口,Externalizable 接口定义了两个方法,writerExternal方法在序列化时被调用,可以再该方法中控制序列化内容,readExternal方法在反序列时被调用,可以在该方法中控制反序列的内容。
//当序列化对象时,该方法自动调用
public void writeExternal(ObjectOutput out) throws IOException{
System.out.println("现在执行序列化方法");
//可以在序列化时写非自身的变量
Date d=new Date();
out.writeObject(d);
//只序列化userName,userPass变量
out.writeObject(userName);
out.writeObject(userPass);
}
//当反序列化对象时,该方法自动调用
public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException{
System.out.println("现在执行反序列化方法");
Date d=(Date)in.readObject();
System.out.println(d);
this.userName=(String)in.readObject();
this.userPass=(String)in.readObject();
}
序列化
//创建一个对象输出流,讲对象输出到文件
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(fileName));
UserInfo user=new UserInfo("renyanwei","888888",20);
out.writeObject(user); //序列化一个会员对象
out.close();
反序列化
//创建一个对象输入流,从文件读取对象
ObjectInputStream in=new ObjectInputStream(new FileInputStream(fileName));
//读取UserInfo对象并调用它的toString()方法
UserInfo user=(UserInfo)(in.readObject());
System.out.println(user.toString());
in.close();
二.基本的动态代理
概念:所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些 interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
实现方法:
import java.lang.reflect.Method;
import java.lang.reflect.InvocationHandler;
//动态代理类(需要继承自InvocationHandler )
public class HelloHandler implements InvocationHandler {
private Object proxyed;
public HelloHandler() {
}
public HelloHandler(Object proxyed) {
this.proxyed=proxyed;
}
@Override
public Object invoke(Object proxy1, Method method, Object[] args)
throws Throwable {
Object result;
System.out.println("start to invoke");
//调用原始对象的方法
result=method.invoke(proxyed, args);//返回调用结果
System.out.println("end to invoke");
return result;
}
}
测试
Hello world=new HelloWord();
//实例化一个动态代理类
InvocationHandler in=new HelloHandler(world);
//获取反射类
Class cls=Proxy.getProxyClass(world.getClass().getClassLoader(), world.getClass().getInterfaces());
//获取反射构造
Constructor ct = cls.getConstructor(new Class[]{InvocationHandler.class});
//返回实例
Hello subject =(Hello) ct.newInstance(new Object[]{in});
//调用
subject.say(5,10);
可以合并起来写
Hello subject =(Hello)Proxy.newInstance(world.getClass().getClassLoader(), world.getClass().getInterfaces(),in);
subject.say(5,10);
三.了解jvm体系
Java虚拟机是一个想象中的机器,在实际的计算机上通过软件模拟来实现。Java虚拟机有自己想象中的硬件,如处理器、堆栈、寄存器等,还具有相应的指令系统。
Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。
Java语言使用模式Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。
JVM定义了控制Java代码解释执行和具体实现的五种规格,它们是:
*JVM指令系统 : Java指令系统是以Java语言的实现为目的设计的,其中包含了用于调用方法和监视多先程系统的指令。Java的8位操作码的长度使得JVM最多有256种指令,目前已使用了160多种操作码。
*JVM寄存器: 4个最为常用的寄存器。它们是: pc程序计数器、optop操作数栈顶指针、frame当前执行环境指针 vars指向当前执行环境中第一个局部变量的指针。所有寄存器均为32位。pc用于记录程序的执行。optop,frame和vars用于记录指向Java栈区的指针。速度最快。
*JVM栈结构: 局部变量、执行环境、操作数栈。局部变量用于存储一个类的方法中所用到的局部变量。vars寄存器指向该变量表中的第一个局部变量。执行环境用于保存解释器对Java字节码进行解释过程中所需的信息。操作数栈用于存储运算所需操作数及运算的结果。速度仅次于寄存器。存储java引用,不会存储java对象。
*JVM碎片回收堆:Java类的实例所需的存储空间是在堆上分配的。解释器具体承担为类实例分配空间的工作。解释器在为一个实例分配完存储空间后,便开始记录对该实例所占用的内存区域的使用。一旦对象使用完毕,便将其回收到堆中。对内存进行释放和回收的工作是由Java运行系统承担的。
*JVM存储区: JVM有两类存储区:常量缓冲池和方法区。常量缓冲池用于存储类名称、方法和字段名称以及串常量。方法区则用于存储Java方法的字节码。
注:存储区有如上4种JVM寄存器、JVM栈结构、JVM碎片回收堆、JVM存储区(常量缓冲池和方法区)。还可以有如序列化存储的方式。
注:Java的编译方式有两种,一种是和C++等语言一样的,把源代码编译成和本地机器平台相关的机器语言,叫即时编译。另一种是编译成一种中间的字节码,与机器平台无关的,这种也是常用的,叫解释型的。
javac 编译器,用于将java源代码文件编译成字节码.
java 解释器,用于执行java字节码
JVM的体系结构(如图)

JAVA虚拟机的运行过程(如图)

四.多线程
概念:在一个程序中,这些独立运行的程序片断叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理”。
目的:多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。线程是在同一时间需要完成多项任务的时候实现的。
线程的4个状态:
New(新建)线程对象仅仅是创建,并没有调用start()方法。
runnable(就绪)只要调度程序将时间片分配给线程,它便可以立刻运行
Blocked(阻塞)线程可以运行,但是由于某个条件阻止了它的运行。当线程为阻塞状态时,调度程序将不会将时间片分给它。
Dead(死亡)
注:线程进入阻塞的某些原因:1)sleep()方法,使线程进入休眠状态。2)wait()方法,使线程挂起。3)线程等待某个输入/输出的完成。4)线程试图调用某个对象上的同步控制方法,但是该对象锁不可用。5)suspend(),但是Java 2 中被废弃了。通常有3种可以恢复:sleep自动恢复、对于suspend调用resume恢复、对于wait可以用通知(notify或notiyA11)方法使其恢复。
实现方式:继承Thread类和实现Runnable接口重写run方法
线程的级别:
static int MAX_PRIORITY
线程可以具有的最高优先级。
static int MIN_PRIORITY
线程可以具有的最低优先级。
static int NORM_PRIORITY
分配给线程的默认优先级。
主要方法
void interrupt() //中断线程。
static boolean interrupted() //测试当前线程是否已经中断。
boolean isAlive()//测试线程是否处于活动状态。
boolean isDaemon() //测试该线程是否为守护线程。
boolean isInterrupted() //测试线程是否已经中断。
void join() //等待该线程终止。
run()//如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回
static void sleep(long millis)//在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。
void start()// 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
void stop()// 过时
suspend()//已过时。
resume()// 已过时。
destroy()//已过时。
yield()//暂停当前正在执行的线程对象,并执行其他线程。
执行图

注意点:
sleep() 方法:sleep() 允许 指定以毫秒为单位的一段时间作为参数,它使得线程在指定的时间内进入阻塞状态,不能得到CPU 时间,指定的时间一过,线程重新进入可执行状态。可能给其他线程执行的机会(自私,睡着了,不释放锁,时间到了才放锁)
yield() 方法:yield() 使得线程放弃当前分得的 CPU 时间,但是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 时间。调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程。不过yield()只能使同等级别的线程获取执行的机会(公平竞争,释放大家再次选举)。而sleep(1000)使同级别或不同级别的都有可能。
wait() 和 notify() 和notifyAll()方法是Object中定义的方法:
必须在synchronized代码块中使用,在synchronized代码被执行期间,线程可以调用对象的wait()方法,释放对象的锁标志,进入等待的状态,并且可以调用notify()或者notifyAll()方法通知正在等待的其他线程。notify()通知的是等待队列中的第一个线程,notifyAll()通知的是等待队列中的所有数量。
几个方法配套使用,wait() 使得线程进入阻塞状态,它有两种形式,一种允许 指定以毫秒为单位的一段时间作为参数,另一种没有参数,前者当对应的 notify() 被调用或者超出指定时间时线程重新进入可执行状态,后者则必须对应的 notify() 被调用。
wait()和sleep()方法的区别:
wait()在object类里定义;sleep()在Thread类里定义。
wait()方法只能放在同步方法或同步块中,表示资源同步时,线程需要等待。
sleep()方法可放在任何位置,表示当前线程睡眠。
wait()方法会释放对象锁;sleep()不会释放对象锁。
wait()方法要等待唤醒之后,线程才会继续执行。
sleep()则是休眠一段时间,线程自动恢复执行.
sleep()必须捕获异常,而wait(),notify()和notifyAll()不需要捕获异常
notify()和notifyAll()的区别
notify() 方法导致解除阻塞的线程是从因调用该对象的 wait() 方法而阻塞的线程中随机选取的,我们无法预料哪一个线程将会被选择,所以编程时要特别小心,避免因这种不确定性而产生问题。
notifyAll() 方法将把因调用该对象的 wait() 方法而阻塞的所有线程一次性全部解除阻塞。当然,只有获得锁的那一个线程才能进入可执行状态。
join()是直到执行完(或强制执行一段时间)当前的线程后才往下执行主线程或其他的线程
Java有两种Thread:“守护线程Daemon”与“用户线程User”。
用户线程:Java虚拟机在它所有非守护线程已经离开后自动离开。
守护线程:守护线程则是用来服务用户线程的,如果没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去。
setDaemon(boolean on)方法可以方便的设置线程的Daemon模式,true为Daemon模式,false为User模式。setDaemon(boolean on)方法必须在线程启动之前调用,当线程正在运行时调用会产生异常。isDaemon方法将测试该线程是否为守护线程。值得一提的是,当你在一个守护线程中产生了其他线程,那么这些新产生的线程不用设置Daemon属性,都将是守护线程,用户线程同样。
例:我们所熟悉的Java垃圾回收线程就是一个典型的守护线程,当我们的程序中不再有任何运行中的Thread,程序就不会再产生垃圾,垃圾回收器也就无事可做,所以当垃圾回收线程是Java虚拟机上仅剩的线程时,Java虚拟机会自动离开。
在守护线程中创建非守护线程(前提是非守护线程执行语句要放在守护线程前),则不会因为其他所有非守护线程的结束而程序运行结束。总之一句话,如果当前还有一个非守护线程在执行,则程序不会结束(不管他是不是在守护线程中创建)。因为在守护线程中创建的默认都是守护线程,当然如果把守护线程创建的默认守护线程改成非守护线程,运行结果就不一样了。而在非守护线程中创建守护线程就很好理解了。
同步:
同步有两种方法。一种同步方法,一种同步代码!分别是synchronized,wait与notify
注意:
同步和异步有何异同,在什么情况下分别使用他们?。
如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。
synchronized 和 java.util.concurrent.locks.Lock 的异同
主要相同点: Lock能完成synchronized所实现的所有功能
主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。
其他:
关于创建多进程、线程组、线程池查看本博客的例子
重点:理解基本的概念和使用 ,以及经典的“生产者和消费者”

- 大小: 18.8 KB

- 大小: 10.5 KB
分享到:
相关推荐
在Java开发领域,掌握核心知识点对于应对技术面试至关重要。...以上就是根据提供的文件内容整理出的Java工程师面试要点。掌握这些知识点可以为面试提供扎实的技术基础,并能够应对面试中出现的各种技术问题。
里面包含多个知名公司的面试题目,而且覆盖了ssh、数据库、java基础、js框架的各方面的面试题,总共四十一份 神舟航天软件公司 1、xml解析方式 2、ejb几种类型 3、String和StringBuffer区别 4、jsp有哪些动作标记 5...
这是一本Java面试题及答案的书籍,它包含了Java面试的要点和答案,可以帮助你更好地准备Java面试。你可以在知乎专栏上找到最全的Java面试题及答案整理,这里有很多经典的Java程序员面试题以及答案,包含Java语言常见...
包含众多面试点,如java基础 并发 集合,数据机构 算法,分布式,缓存,数据库等等
### JAVA程序员面试必备的32个要点详解 #### 1. final、finally、finalize 的区别 - **final**: 用于声明变量、方法或类时,表示该元素是不可变的。例如,当一个变量被声明为final时,则该变量不能重新赋值;如果是...
Java 面试要点(适用于 2 年以上经验,1 年亦可) Java 是一种广泛使用的编程语言,涵盖了基础知识、JVM、并发、锁、分布式等领域。以下是Java面试要点的详细知识点总结: 基础篇 1. JVM 内存结构:堆、栈、方法...
Java面试通常涵盖多个方面,包括Java基础知识、编程技能、问题解决能力,以及对Java生态系统和相关技术的理解。以下是一些建议的Java面试准备要点和资源描述: 一、Java基础知识 数据类型、变量与运算符:理解Java...
Java基础、Java集合、多线程、JDBC、HTTP、JSP、Servlet、Struts面试题汇总(附答案).docx java工程师面试题大全-100%公司笔试题你都能碰到几个.docx Java开发工程师上机笔试题.docx Java开发求职面试题.docx Java...
### Java基础面试题概览 #### 1. 线程安全与同步机制 线程安全是Java多线程编程中的关键概念。当多个线程同时访问共享资源时,可能会引发数据不一致的问题。为了确保数据的一致性,Java提供了多种同步机制,如`...
资深Java工程师面试要点大全 #### 一、Java基础知识 1. **所有类的父类**: 在Java中,所有类的父类是`Object`类。这意味着每一个自定义类都直接或间接地继承自`Object`类。`Object`类提供了一些重要的方法,比如`...
总的来说,《Java面试宝典2018版》是一本全面而深入的指南,它将帮助Java开发者系统复习技术要点,提升专业素养,从而在面试中展现出色的技术能力。通过深入阅读并实践书中的知识,你将能够更好地应对各种面试挑战,...
### Java基础面试题集解析 #### 一、Java在企业中的应用 ...以上知识点涵盖了Java基础面试题集中提到的核心概念和技术要点,对于准备Java技术面试的学习者而言,深入理解和掌握这些内容将大有裨益。
读书笔记:Java 从小白到大牛涵盖Java 基础、进阶、面试要点等核心要点助你一臂之力。
#### 一、Java基础 **1.1 Collection和Map** - **知识点概述:** - 掌握`Collection`接口及其子接口`List`、`Set`的不同之处。 - 理解`Map`接口与`Collection`接口的主要区别。 - `HashMap`与`HashSet`内部实现...
在求职者寻求初级、中级、中高级职位时,拥有一定的Java基础是至关重要的。在如今的市场上,Java程序员需求量很大,尤其是中高级职位,常常出现人才供不应求的局面。Java作为一个成熟的编程语言,在20年的历史中,...
张孝祥整理Java就业面试题大全.doc 应届生应聘技术工作的面试技巧(来自培训机构多年经验总结).ppt sql面试题.doc JAVA面试题解惑系列.pdf Java面试题大全.pdf ...java程序员面试必备的32个要点 - Java _ Java SE.txt
### JAVA基础面试题大全整理版本 #### 一、前言 在Java领域内,无论是初学者还是资深开发者,面试都是通往下一个职业阶段的关键步骤。本文档旨在为求职者提供一份全面且实用的Java基础面试题汇总及解答指南,旨在...
"115个Java面试要点.zip"这个压缩包集合了常见的Java面试问题,涵盖了多个核心主题,旨在帮助求职者准备全面的面试。以下是对这些面试要点的详细解读: 1. **基础知识**:面试通常会从Java的基础语法开始,如数据...
### Java中级面试要点详解 #### 一、类加载机制与子父类加载顺序 ...以上是对Java中级面试要点的详细解析,涵盖了类加载机制、单例模式、多线程基础、线程池等方面的知识点。希望对准备面试的朋友有所帮助。