1、什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?
Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。
Java被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。Java虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。
2、JDK和JRE的区别是什么?
JRE: Java Runtime Environment
JDK:Java Development Kit
JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库。
是使用java语言编写的程序运行所需要的软件环境,
是提供给想运行java程序的用户使用的。
JDK顾名思义是java开发工具包,
是程序员使用java语言编写java程序所需的开发工具包,
是提供给程序员使用的。
JDK包含了JRE,同时还包含了编译java源码的编译器javac,
还包含了很多java程序调试和分析的工具:jconsole,jvisualvm等工具软件,
还包含了java程序编写所需的文档和demo例子程序。
如果需要运行java程序,只需安装JRE就可以了。如果你需要编写java程序,需要安装JDK。
3、是否可以在static环境中访问非static变量?
static变量在Java中是属于类的,它在所有的实例中的值是一样的。
当类被Java虚拟机载入的时候,会对static变量进行初始化。
如果代码尝试不用实例来访问非static的变量,编译器会报错,
因为这些变量还没有被创建出来,还没有跟任何实例关联上。
4、Java中的方法覆盖(Overriding)和方法重载(Overload)是什么意思?
方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。
方法覆盖是说子类重新定义了父类的方法。
方法覆盖必须有相同的方法名,参数列表和返回类型。
覆盖者可能不会限制它所覆盖的方法的访问。
5、Java中类不支持多继承,只支持单继承(即一个类只有一个父类)。
但是java中的接口支持多继承,即一个子接口可以有多个父接口。
接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,
当类实现接口时,类就扩展了相应的功能。
6、进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。线程又叫做轻量级进程。
a.地址空间和其它资源:
进程间相互独立,同一进程的各线程间共享。
某进程内的线程在其它进程不可见。
b.通信:进程间通信IPC,
线程间可以直接读写进程数据段(如全局变量)来进行通信,
但需要进程同步和互斥手段的辅助,以保证数据的一致性。
c.调度和切换:线程上下文切换比进程上下文切换要快得多。
d.在多线程OS中,进程不是一个可执行的实体。
7、创建线程有4种方式
继承Thread类
实现Runnable接口
应用程序可以使用Executor框架来创建线程池
实现Callable接口
8、如何确保N个线程可以访问N个资源同时又不导致死锁?
指定获取锁的顺序,并强制线程按照指定的顺序获取锁。
因此所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。
9、Iterator接口提供了很多对集合元素进行迭代的方法。
每一个集合类都包含了可以返回迭代器实例的迭代方法。
迭代器可以在迭代的过程中删除底层集合的元素,
但是不可以直接调用集合的remove(Object Obj)删除,
可以通过迭代器的remove()方法删除。
10、Java中的HashMap以键值对(key-value)的形式存储元素
HashMap需要一个hash函数,
它使用hashCode()和equals()方法来向集合/从集合添加和检索元素。
当调用put()方法的时候,
HashMap会计算key的hash值,
然后把键值对存储在集合中合适的索引上。
如果key已经存在了,value会被更新成新值。
HashMap的一些重要的特性是它的容量(capacity),
负载因子(load factor)和扩容极限(threshold resizing)。
11、HashMap使用hashCode()和equals()方法来确定键值对的索引
当根据键获取值的时候也会用到这两个方法。
如果没有正确的实现这两个方法,两个不同的键可能会有相同的hash值,
可能会被集合认为是相等的。
这两个方法也用来发现重复元素。
12、对于基本类型数据,集合使用自动装箱来减少编码工作量。但当处理固定大小的基本数据类型的时候,这种方式相对比较慢。
数组Array可以包含基本类型和对象类型,列表ArrayList只能包含对象类型。
Array大小是固定的,ArrayList的大小是动态变化的。
ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
13、ArrayList和LinkedList都实现了List接口
ArrayList是基于索引的数据接口,它的底层是数组。
它可以以O(1)时间复杂度对元素进行随机访问。
LinkedList是以元素列表的形式存储它的数据,
每一个元素都和它的前一个和后一个元素链接在一起,
查找某个元素的时间复杂度是O(n)。
LinkedList的插入,添加,删除操作速度更快,
因为当元素被添加到集合任意位置的时候,
不需要像数组那样重新计算大小或者是更新索引。
LinkedList比ArrayList更占内存,
因为LinkedList为每一个节点存储了两个引用,
一个指向前一个元素,一个指向下一个元素。
14、HashSet是由一个hash表来实现的,它的元素是无序的。add(),remove(),contains()方法的时间复杂度是O(1)。TreeSet是由一个树形的结构来实现的,它里面的元素是有序的。因此,add(),remove(),contains()方法的时间复杂度是O(logn)。
15、Java垃圾回收在内存中存在没有引用的对象或超过作用域的对象时进行。
垃圾回收的目的是识别并且丢弃应用不再使用的对象来释放和重用资源。
16、有序数组最大的好处在于查找的时间复杂度是O(log n),而无序数组是O(n)。有序数组的缺点是插入操作的时间复杂度是O(n),因为值大的元素需要往后移动来给新元素腾位置。相反,无序数组的插入时间复杂度是常量O(1)。
17、System.gc()和Runtime.gc()用来提示JVM要进行垃圾回收。
但立即开始还是延迟进行垃圾回收是取决于JVM的。
18、如果对象的引用被置为null,垃圾收集器不会立即释放对象占用的内存。
在下一个垃圾回收周期中,这个对象将是可被回收的。
19、Java中有两种异常:受检查的(checked)异常和不受检查的(unchecked)异常。
不受检查的异常不需要在方法或者是构造函数上声明,
就算方法或者是构造函数的执行可能会抛出这样的异常,
并且不受检查的异常可以传播到方法或者是构造函数的外面。
相反,受检查的异常必须要用throws语句在方法或者是构造函数上声明。
20、Exception和Error都是Throwable的子类。
Exception用于用户程序可以捕获的异常情况。
Error定义了不期望被用户程序捕获的异常。
21、Throws和throw
Throw用于方法内部,Throws用于方法声明上
Throw后跟异常对象,Throws后跟异常类型
Throw后只能跟一个异常对象,Throws后可以一次声明多种异常类型
22、异常处理完成以后,Exception对象会在下一个垃圾回收过程中被回收掉。
23、裁剪(clipping)和重绘(repainting)的联系
当窗口被AWT重绘线程进行重绘的时候,
它会把裁剪区域设置成需要重绘的窗口的区域。
24、GUI组件可以处理它自己的事件,只要它实现相对应的事件监听器接口,并且把自己作为事件监听器。
25、JDBC是允许用户在不同数据库之间做选择的一个抽象层。
JDBC允许开发者用JAVA写数据库应用程序,而不需要关心底层特定数据库的细节。
26、数据库连接池
像打开关闭数据库连接这种和数据库的交互可能是很费时的,
尤其是当客户端数量增加的时候,
会消耗大量的资源,成本是非常高的。
可以在应用服务器启动的时候建立很多个数据库连接并维护在一个池中。
连接请求由池中的连接提供。
在连接使用完毕以后,
把连接归还到池中,以用于满足将来更多的请求。
27、Web应用程序是对Web或者是应用服务器的动态扩展。
有两种类型的Web应用:面向表现的和面向服务的。
面向表现的Web应用程序会产生包含了
很多种标记语言和动态内容的交互的web页面作为对请求的响应。
面向服务的Web应用实现了Web服务的端点(endpoint)。
一般来说,一个Web应用可以看成是一组安装在服务器URL名称空间
的特定子集下面的Servlet的集合。
28、服务端包含(SSI)是一种简单的解释型服务端脚本语言
大多数时候仅用在Web上,用servlet标签嵌入进来。
SSI最常用的场景把一个或多个文件包含到Web服务器的一个Web页面中。
当浏览器访问Web页面的时候,
Web服务器会用对应的servlet产生的文本来替换Web页面中的servlet标签。
29、如何知道是哪一个客户端的机器正在请求你的Servlet?
ServletRequest类可以找出客户端机器的IP地址或者是主机名。
getRemoteAddr()方法获取客户端主机的IP地址,
getRemoteHost()可以获取主机名。
30、HTTP响应由三个部分组成:
状态码(Status Code):描述了响应的状态。
可以用来检查是否成功的完成了请求。
请求失败的情况下,状态码可用来找出失败的原因。
如果Servlet没有返回状态码,默认会返回成功的状态码HttpServletResponse.SC_OK。
HTTP头部(HTTP Header):它们包含了更多关于响应的信息。
比如:头部可以指定认为响应过期的过期日期,
或者是指定用来给用户安全的传输实体内容的编码格式。
主体(Body):它包含了响应的内容。
它可以包含HTML代码,图片,等等。
主体是由传输在HTTP消息中紧跟在头部后面的数据字节组成的。
31、cookie是Web服务器发送给浏览器的一块信息。
浏览器会在本地文件中给每一个Web服务器存储cookie。
以后浏览器在给特定的Web服务器发请求的时候,
同时会发送所有为该服务器存储的cookie。
下面列出了session和cookie的区别:
无论客户端浏览器做怎么样的设置,session都应该能正常工作。
客户端可以选择禁用cookie,
但是,session仍然是能够工作的,因为客户端无法禁用服务端的session。
在存储的数据量方面session和cookies也是不一样的。
session能够存储任意的Java对象,cookie只能存储String类型的对象。
32、浏览器和Servlet通信使用的是HTTP协议。
33、JSP页面是一种包含了静态数据和JSP元素两种类型的文本的文本文档。
静态数据可以用任何基于文本的格式来表示,比如:HTML或者XML。
JSP是一种混合了静态内容和动态产生的内容的技术。