17 描述一下 JVM 加载 class 文件的原理机制 ?
首先来看一下java程序的执行过程。
从这个框图很容易大体上了解java程序工作原理。首先,你写好java代码,保存到硬盘当中。然后你在命令行中输入 :javac YourClassName.java 。此时,你的java代码就被编译成字节码(.class)。如果你是在Eclipse IDE或者其他开发工具中,你保存代码的时候,开发工具已经帮你完成了上述的编译工作,因此你可以在对应的目录下看到class文件。此时的class文件依然是保存在硬盘中,因此,当你在命令行中运行:java YourClassName ,就完成了上面红色方框中的工作。JRE的来加载器从硬盘中读取class文件,载入到系统分配给JVM的内存区域--运行数据区(Runtime Data Areas). 然后执行引擎解释或者编译类文件,转化成特定CPU的机器码,CPU执行机器码,至此完成整个过程。
18 列出某文件夹下的所有文件?
public class FileTest {
public static void main(String[] args) {
File file = new File("指定目录的文件夹");
String[] strArray = file.list();
for (String str : strArray) {
System.out.println(str);
}
}
}
19 写一个复制文件的程序?
设计思路:
用被复制文件的路径创建一个InputStream对象,
用复制文件的新路径创建一个OutpStream对象,
用read()方法循环把数据读出到一个byte数组中,直到读出数据的长度小于0,
用write()方法把byte数组中的字节写入输出流中,
关闭流。
代码:
public void FileCopy() {
FileInputStream fin = new FileInputStream("d:/test/a.txt");
FilteOutputStream fout = new FileOutputStream("d:/test/b.txt");
byte []buff = new byte[256];
int len = 0; //每次读取数据的长度
while((len = fin.read(buff)) > 0) {
fout.write(buff, 0, len);
}
fin.close();
fout.close();
}
20 进程与线程的区别?
进程就是程序的一次执行,而线程可以理解为进程中执行的一段程序片段,也就是一种包含的关系。线程的划分尺度小于进程,使得多线程程序的并发性高。进程在执行的过程中拥有独立的内存单元,而多个线程是共享内存的。进程能独立运行,而线程必须依存在应用程序中,由应用程序提供多个线程执行控制。
主要区别:
1) 线程的划分尺度小于进程,线程隶属于某个进程。
2) 进程是程序的一种动态形式,是CPU、内存等资源占用的基本单位,而线程是不能独立的占有这些资源的。
3) 进程之间相互独立,通信困难,而线程之间共享一块内存区域,通信比较方便。
4) 进程在执行过程中,包含比较固定的入口、执行顺序和出口,而线程的这些过程会被应用程序所控制。
21 反射的原理是什么?
反射是为了能够动态的加载一个类,动态的调用一个方法,动态的访问一个属性等动态要求而设计的。它的出发点就在于JVM会为每一个类创建一个Class类实例,通过该对象可以获取这个类的信息,然后通过是用java.lang.reflect包下的API以达到各种动态需求。
java用Class类来代表所有的类,方便开发者掌控类信息。通过Class,开发者可以得到属性(Field)、方法(Method)、构造器(Constructor)等信息。动态获取这些信息后,可以用来创建实例、调用方法、访问属性等,这就是反射的主要用途。
22 如何用反射来实例化一个类?
两种途径:
1) 如果使用无参构造方法,直接使用Class类的newInstance()方法即可。
2) 若需特定的构造方法,则先获取Constructor实例,再用newInstance()方法创建对象。
代码实例如下:
class Student {
private String name;
private int age;
public Student() { super(); }
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String toString(){ return "stu" + name + "," + age; }
}
public class NewInstanceTest {
public static void main(String []args) {
Class<Student> clazz = Student.class;
Studeng obj = clazz.newInstance(); //第一种方法
System.out.println(obj);
Constructor<Student> con = clazz.getConstructor(String.class, int.class);
obj = con.newInstance("zhangsan", 30);
System.out.println(obj);
}
}
23 java的TCP编码模型?
服务端:
1)创建一个服务端的Socket,指定一个端口号。
2)开始监听来至客户端的请求要求。
3)获得输出流或输入流。
4)调用输入流或输出流的read()或write()方法,进行数据的传输。
5)释放资源,关闭流、Socket和Server Socket对象。
客户端:
1)创建Socket对象,建立与服务器端的连接。
2)获得输出流或输入流。
3)调用输入流或输出流的read()或write()方法进行数据传输。
4)释放资源,关闭流和Socket对象。
24 java UDP模型是什么?
大致的步骤:
1)创建数据Socket,指定一个端口号。
2)对于接收消息的一端来说,提供一个byte数组进行数据的存储;而对于发送消息一端,除此以外还需要提供对端的IP地址和端口号。
3)调用DatagramPacket的receive()或send()方法进行数据的接收或发送。
4)调用DatagramPacket的getData()方法得到byte数组的数据。
5)释放资源。
25 java与C++程序在编译和运行上有什么区别?
C++源码编译以后,生成的是特定机器可以直接运行的文件,而java源码经过编译后,生成的是中间的字节码文件。这些字节码文件是需要放在JVM中运行的,而JVM是有多个平台的版本的。因此,java具有跨平台性,而C++没有。
26 类静态成员的特点?
类的静态成员是通过static关键字修饰的成员,主要包括:静态成员变量、静态方法和静态代码块。
1) 在类加载的时候,就进行创建和初始化或执行代码。
2)它们对于一个类来说,都只有一份。
3)类的所有实例都可以访问到它们。
27 输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数?
import java.util.*;
public class lianxi07 {
public static void main(String[] args) {
int digital = 0;int character = 0;int other = 0;int blank = 0;char[] ch = null;Scanner sc = new Scanner(System.in);//输入字符串String s = sc.nextLine();ch = s.toCharArray();for(int i=0; i<ch.length; i++) {if(ch >= '0' && ch <= '9') {digital ++;} else if((ch >= 'a' && ch <= 'z')|| ch > 'A' && ch <= 'Z') {character ++;} else if(ch == ' ') {blank ++;} else {other ++;}}System.out.println("数字个数: " + digital);System.out.println("英文字母个数: " + character);System.out.println("空格个数: " + blank);System.out.println("其他字符个数:" + other );
}
28 什么是线程池(thread pool)?
在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁,这就是"池化资源"技术产生的原因。线程池顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。
在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁,这就是"池化资源"技术产生的原因。线程池顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。
Java 5+中的Executor接口定义一个执行线程的工具。它的子类型即线程池接口是ExecutorService。要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,因此在工具类Executors面提供了一些静态工厂方法,生成一些常用的线程池,如下所示:
29 java内存分配的解释
在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁,这就是"池化资源"技术产生的原因。线程池顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。
一般Java在内存分配时会涉及到以下区域:
◆寄存器:我们在程序中无法控制
◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中
◆堆:存放用new产生的数据
◆静态域:存放在对象中用static定义的静态成员
◆常量池:存放常量
◆非RAM存储:硬盘等永久存储空间
30 比较一下Java 和JavaSciprt?
在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁,这就是"池化资源"技术产生的原因。线程池顾名思义就是事先创建若干个可执行的线程放入一个池(容器)中,需要的时候从池中获取线程不用自行创建,使用完毕不需要销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。
JavaScript 与Java是两个公司开发的不同的两个产品。Java 是原Sun 公司推出的面向对象的程序设计语言,特别适合于互联网应用程序开发;而JavaScript是Netscape公司的产品,为了扩展Netscape浏览器的功能而开发的一种可以嵌入Web页面中运行的基于对象和事件驱动的解释性语言,它的前身是LiveScript;而Java 的前身是Oak语言。
下面对两种语言间的异同作如下比较:
1)基于对象和面向对象:Java是一种真正的面向对象的语言,即使是开发简单的程序,必须设计对象;JavaScript是种脚本语言,它可以用来制作与网络无关的,与用户交互作用的复杂软件。它是一种基于对象(Object-Based)和事件驱动(Event-Driven)的编程语言。因而它本身提供了非常丰富的内部对象供设计人员使用;
2)解释和编译:Java 的源代码在执行之前,必须经过编译;JavaScript 是一种解释性编程语言,其源代码不需经过编译,由浏览器解释执行;
3)强类型变量和类型弱变量:Java采用强类型变量检查,即所有变量在编译之前必须作声明;JavaScript中变量声明,采用其弱类型。即变量在使用前不需作声明,而是解释器在运行时检查其数据类型;
4)代码格式不一样。
补充:上面列出的四点是原来所谓的标准答案中给出的。其实Java和JavaScript最重要的区别是一个是静态语言,一个是动态语言。目前的编程语言的发展趋势是函数式语言和动态语言。在Java中类(class)是一等公民,而JavaScript中函数(function)是一等公民。对于这种问题,在面试时还是用自己的语言回答会更加靠谱。