一、谈谈你对java的理解

1、平台无关性,一次编译到处运行

2、GC

3、语言特性

4、面向对象

5、类库

6、异常处理

二、Java如何做到一次编译到处运行?(如何做到平台无关性)

首先我们先来编写一个java程序:

public class ByteCodeSimple {
public static void main(String[] args) {
int i = 1, j = 5;
i++;
++j;
System.out.println(i);
System.out.println(j);
}
}

首先我们先对这段程序使用javac 命令进行编译:

可以看到得到了对应ByteCodeSimple.class

之后再src目录下,用java命令加上包名执行class文件,我们可以看到他的执行是符合预期的。

我们如何查看.class文件呢,可以通过Idea打开,就可以自动进行反编译。

下面我们使用javap命令来进行反编译-c的意义代表反编译,如果想查询帮助指令,可以输入javap -help进行查询。

一次编译到处运行如何实现?

java文件->.class文件

Java源码首先被编译成字节码,再由不同平台的JVM进行解析,Java语言在不同的平台上运行时不需要重新进行编译,Java虚拟机在执行字节码时,把字节码转换成具体平台的机器指令。

三、JVM如何加载.class文件

JVM最值得学习:jvm内存模型,GC

Class Loader(类加载器):依据特定格式,加载class文件到内存

Execution Engine(执行引擎):对命令进行解析。

Native Interface(本地方法借口):融合不同开发语言的原生库为Java所用。

Runtime Data Area(内存模型):JVM内存空间结构模型。

结论:首先是由ClassLoader加载.class文件,之后通过Execution Engine命令进行执行。

四、什么是反射?

首先新建一个Robot类

public class Robot {
private String name; public void hello1(String content) {
System.out.println(content + name);
} private String hello2(String content) {
return "hello2" + content + name;
}
}

使用反射去调用Robot类中的方法:

public class ReflectSample {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//根据类名获取Class对象
Class rc = Class.forName("com.interview.reflect.Robot");
//根据类类型,去创建Robot对象
Robot robot = (Robot) rc.newInstance();
//调用方法hello1
robot.hello1("123"); //这个方法可以获得道类内部的所有方法包含公有和私有方法,却不能获得器父类继承的方法,和接口实现的方法
Method method = rc.getDeclaredMethod("hello2", String.class);
//在反射私有方法时要设置这个方法的值为true
method.setAccessible(true);
//执行方法并获得返回值
String result = (String) method.invoke(robot, "wzy");
//输出结果
System.out.println("result:" + result); //这个方法可以获取类内的公有方法,和父类继承公有的方法;
Method method1 = rc.getMethod("hello1", String.class);
//调用方法hello1
method1.invoke(robot, "welcome"); //获取私有成员变量
Field name = rc.getDeclaredField("name");
//设置允许方法私有属性
name.setAccessible(true);
//设置私有对象的值
name.set(robot, "yuan"); //调用hello1方法
method1.invoke(robot, "123");
}
}

运行结果:

五、谈谈ClassLoader

类从编译到执行的过程

编译器将Robot.java源文件编译为Robot.class字节码文件

ClassLoader将字节码转换为JVM中的Class<Robot>对象

JVM利用Class<Robot>对象实例化为Robot对象。

ClassLoader在Java中有着非常重要的作用,它主要工作在Class的装载的加载阶段,其主要作用是从系统外部获得Class的二进制数据流,它是Java的核心组件,所有的

Class都是由ClassLoader进行加载的,ClassLoader负责通过将Class文件里的二进制数据流装载进系统,让后交给java虚拟机进行连接、初始化等操作。

通过查看源码我们可以发现,ClassLoader是一个抽象类:

其中最重要的方法就是ClassLoader中的loadClass(String name)方法

我们还可以发现ClassLoader类当中有parent成员变量,是另一个ClassLoader说名ClassLoader的种类不止一种。

ClassLoader的种类:

BootStrapClassLoader:C++编写,加载核心库java.*

ExtClassLoader:Java编写,加载扩展库javax.*(用户看的到的ClassLoader)(C:\Java\jdk\jre\lib\ext;C:\Windows\Sun\Java\lib\ext)

AppClassLoader:Java编写,加载程序所在的目录

自定义ClassLoader:Java编写,定制加载

通过查看ExtClassLoader源码,可以看到它的class的加载路径,用到才会去加载

我们对这个路径进行打印得到:

通过查看AppClassLoader源码,我们可以看到其对应的加载路径:

对这个路径进行打印,得到结果,其中就包含了我们项目本身的.class文件输出路径out.加载类路径(classpath)最重要的路径:E:\project\javabasic\out\production\javabasic;

实现自定义ClassLoader:

首先我们先创建一个类:

 public class Wali {
static {
System.out.println("Hello Wali");
}
}

之后单独对这个类使用javac进行编译,而不通过IDE,注意这个Wali类中没有定义package,否则执行的时候需要带着包名

创建一个MyClassLoader类

 public class MyClassLoader extends ClassLoader {
/**
* 加载类的路径
*/
private String path;
/**
* 类加载器的名称
*/
private String classLoaderName; /**
* 定义构造方法
* @param path 加载类的路径
* @param classLoaderName 类加载器的名称
*/
public MyClassLoader(String path, String classLoaderName) {
this.path = path;
this.classLoaderName = classLoaderName;
} /**
* 用于寻找类文件
* @param name
* @return
*/
@Override
public Class findClass(String name) {
byte[] b = loadClassData(name);
return defineClass(name, b, 0, b.length );
} /**
* 将文件转换为字节流
* @param name
* @return
*/
private byte[] loadClassData(String name) {
//拼接出文件的名字
name = path + "\\" + name + ".class";
InputStream in = null;
ByteArrayOutputStream bos = null; try {
in = new FileInputStream(name);
bos = new ByteArrayOutputStream();
int i = 0;
//对文件进行读取
while ((i = in.read()) != -1) {
bos.write(i);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//返回字节数组
return bos.toByteArray();
}
}

MyClassLoader测试类:

 public class MyClassLoaderChecker {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
MyClassLoader myClassLoader = new MyClassLoader("E:\\project\\javabasic\\src\\com\\interview\\reflect", "myClassLoader");
Class aClass = myClassLoader.findClass("Wali");
//创建对象触发执行静态块代码
Object o = aClass.newInstance();
}
}

运行结果:

Java面试01的更多相关文章

  1. Java面试01|JVM相关

    1.JVM内存查看与分析,编写内存泄露实例 堆区.栈区.方法区.本机内存都有可能内存溢出.在这里编写堆区内存溢出实例.如下(来自<深入理解Java虚拟机>一书. // -Xms20m -X ...

  2. Java面试----01.JavaSE

    1.面向对象和面向过程的区别 面向过程:面向过程性能比面向对象高. 因为类调用时需要实例化,比较消耗资源,所以当性能是最重要的考虑因素时,比如单片机.嵌入式开发.Linux/Unix等一般采用面向对象 ...

  3. Java面试系列

    如果你的面试简历是如下这样写的,请务必准备回答下面的所有问题. 面试职位:Java高级工程师 专业技能: (1)牢固掌握Java基础知识,如集合.并发.I/O等,并对Java源码有一定的研究. (2) ...

  4. Java 面试宝典-2017

    http://www.cnblogs.com/nelson-hu/p/7190163.html Java面试宝典-2017   Java面试宝典2017版 一. Java基础部分........... ...

  5. Java面试宝典-2017

    Java面试宝典2017版 一. Java基础部分........................................................................... ...

  6. Java 面试知识点解析(四)——版本特性篇

    前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...

  7. Java面试宝典2018

    转 Java面试宝典2018 一. Java基础部分…………………………………………………………………………………….. 7 1.一个“.java”源文件中是否可以包括多个类(不是内部类)?有什么限制 ...

  8. Java面试知识点之线程篇(一)

    前言:在Java面试中,一定会遇到线程相关问题,因此笔者在这里总结Java中有关线程方面知识点,多数从网上得来(文中会贴出主要参考链接),有些也是笔者在面试中所遇到的问题,如有错误,请不吝指正.主要参 ...

  9. Java面试,如何在短时间内做突击

    面试前很有必要针对性的多刷题,大部分童鞋实战能力强,理论不行,面试前不做准备很吃亏.这里整理了很多常考面试题,希望对你有帮助.   面试技术文 Java岗 面试考点精讲(基础篇01期) Java岗 面 ...

随机推荐

  1. Session技术入门代码案例

    package com.loaderman.demo; import javax.servlet.ServletException; import javax.servlet.http.*; impo ...

  2. 数据解析框架之FastJson

    演示实体类 import java.util.List; public class Student { public String name; public int age; public List& ...

  3. 阶段3 3.SpringMVC·_02.参数绑定及自定义类型转换_5 自定义类型转换器演示异常

    后端自动进行类型的转换.前端输入的年龄都是字符串的形式传递到后端. user的实体类  加一个Date日期类型格式的字段.生成get和set还有toString的方法 重新部署程序 日期用横线的方式 ...

  4. 七十九:flask.Restful之flask-Restful标准化返回参数示例

    接上一篇的代码和数据 对于复杂结构的数据如果只是定义单一结构的话返回的数据就没意义了,此时定义的数据结构需精确到所有数据的每一个字段有时候要返回的数据结构中,会有比较复杂的数据结构,证实后可以使用一些 ...

  5. redis(3)主从与集群

    一.主从架构 yum安装的redis cd /etc/ cp redis.conf /etc/slave.conf vim slave.conf bind 192.168.42.7 slaveof p ...

  6. django 模板里面for循环和if常用的方法

    django 模板里面for循环常用的方法 {% for %} 允许我们在一个序列上迭代.与Python的for 语句的情形类似,循环语法是 for X in Y ,Y是要迭代的序列而X是在每一个特定 ...

  7. LeetCode.1122-相对排序数组(Relative Sort Array)

    这是小川的第393次更新,第427篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第258题(顺位题号是1122).给定两个数组arr1和arr2,arr2中的元素是不同的 ...

  8. 【JulyEdu-Python基础】第 6 课:高级面向对象

    使用@property添加属性和自定义属性 __slots__和property 方法和属性的动态绑定 使用__slots__限定class实例能添加的属性 __slots__仅对当前类实例起作用,对 ...

  9. 【机器学习】Learning to Rank 简介

    Learning to Rank 简介 去年实习时,因为项目需要,接触了一下Learning to Rank(以下简称L2R),感觉很有意思,也有很大的应用价值.L2R将机器学习的技术很好的应用到了排 ...

  10. 【VS开发】PCIe体系结构的组成部件

    PCIe总线作为处理器系统的局部总线,其作用与PCI总线类似,主要目的是为了连接处理器系统中的外部设备,当然PCIe总线也可以连接其他处理器系统.在不同的处理器系统中,PCIe体系结构的实现方法略有不 ...