java基础知识问答

来源:互联网 发布:剑灵捏脸数据大全人女 编辑:程序博客网 时间:2024/06/06 03:45
线程与进程的区别归纳
a.地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见
b.通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性
c.调度和切换:线程上下文切换比进程上下文切换要快得多
创建线程有几种不同的方式?你喜欢哪一种?为什么?
a.继承Thread类
b.实现Runnable接口
c.应用程序可以使用Executor框架来创建线程池
实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。
概括的解释下线程的几种可用状态
1.新建( new ):新创建了一个线程对象
2.可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象 的 start ()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取 cpu 的使用权 。
3. 运行( running ):可运行状态( runnable )的线程获得了 cpu 时间片( timeslice ) ,执行程序代码。
4. 阻塞( block ):阻塞状态是指线程因为某种原因放弃了 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 ()方法,则该线程结束生命周期。死亡的线程不可再次复生
这里写图片描述
同步方法和同步代码块的区别是什么?
区别:同步方法默认用this或者当前类class对象作为锁;同步代码块可以选择以什么来加锁,比同步方法要更细颗粒度,我们可以选择只同步会发生同步问题的部分代码而不是整个方法;
在监视器(Monitor)内部,是如何做线程同步的?程序应该做哪种级别的同步?
在java虚拟机中,每个对象(Object和class)通过某种逻辑关联监视器,每个监视器和一个对象引用相关联,为了实现监视器的互斥功能,每个对象都关联着一把锁.一旦方法或者代码块被synchronized修饰,那么这个部分就放入了监视器的监视区域,,确保一次只能有一个线程执行该部分的代码, 线程在获取锁之前不允许执行该部分的代码
如何确保N个线程可以访问N个资源同时又不导致死锁?
死锁必须满足的四个条件:
1)互斥:一个资源每次只能被一个进程使用
2)保持和请求:一个进程因请求资源而阻塞时,对已经获得的资源保持不变
3)不可剥夺性:进程已经获得资源,在未使用完前,不能被剥夺
4)循环等待:若干个进程之间形成一种循环等待资源的关系。
所想要损坏死锁,不满足条件之一就可以。 其中最简单的方法是:指定获取锁的顺序,并强制线程按照锁的顺序加锁访问资源,依次使用依次释放
为什么集合类没有实现Cloneable和Serializable接口?
克隆(cloning)或者是序列化(serialization)的语义和含义是跟具体的实现相关的。因此,应该由集合类的具体实现来决定如何被克隆或者是序列化。
Iterator和ListIterator的区别是什么?
Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。
快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
快速失败:当你在迭代一个集合的时候,如果有另一个线程正在修改你正在访问的那个集合时,就会抛出一个ConcurrentModification异常。在java.util包下的都是快速失败。
安全失败:你在迭代的时候会去底层集合做一个拷贝,所以你在修改上层集合的时候是不会受影响的,不会抛出ConcurrentModification异常。在java.util.concurrent包下的全是安全失败的。
数组(Array)和列表(ArrayList)有什么区别?什么时候应该使用Array而不是ArrayList?
Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
Array大小是固定的,ArrayList的大小是动态变化的。
ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。
ArrayList和LinkedList有什么区别?
ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。
与此对应,LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。
相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。
LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。
如何权衡是使用无序的数组还是有序的数组?
有序数组最大的好处在于查找的时间复杂度是O(log n),而无序数组是O(n)。有序数组的缺点是插入操作的时间复杂度是O(n),因为值大的元素需要往后移动来给新元素腾位置。相反,无序数组的插入时间复杂度是常量O(1)。
Java中垃圾回收有什么目的?什么时候进行垃圾回收?
目的:回收堆内存中不再使用的对象,释放资源
回收时间:当对象永久地失去引用后,系统会在合适的时候回收它所占的内存
System.gc()和Runtime.gc()会做什么事情?
这俩个方法都是用来提示java虚拟机进行垃圾回收,但是否立即回收还是延迟回收由java虚拟机决定。
调用 System.gc() 实际上等效于调用: Runtime.getRuntime().gc()
finalize()方法什么时候被调用?析构函数(finalization)的目的是什么?
1.在释放对象占用的内存之前,垃圾收集器会调用对象的finalize()方法。
2.如果内存总是充足的,那么垃圾回收器永远不会进行,也就是finailize()可能永远不被执行。finalize()最主要的用途是回收特殊渠道申请的内存。
如果对象的引用被置为null,垃圾收集器是否会立即释放对象占用的内存?
不会,在下一个垃圾回收周期中,这个对象将是可被回收的。
Java堆的结构是什么样子的?什么是堆中的永久代(Perm Gen space)?
1.JVM的堆是运行时数据区,所有类的实例和数组都是在堆上分配内存。它在JVM启动的时候被创建,对象所占的堆内存是由垃圾收集器回收。
2.虚拟机中的堆共划分为三个代:年轻代、年老代和持久代。持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大。年轻代和年老代的划分是对垃圾收集影响比较大的。
年轻代:所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。
年老代:在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。年老代中存放的都是一些生命周期较长的对象。
持久代:用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响。
JVM的永久代中会发生垃圾回收么?
垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收(Full GC),这就是为什么正确的永久代大小对避免Full GC是非常重要的原因。
Java中的两种异常类型是什么?他们有什么区别?
Java中有两种异常:受检查的(checked)异常和不受检查的(unchecked)异常。
不受检查的异常不需要在方法或者是构造函数上声明,方法或者是构造函数的执行可能会抛出这样的异常,并且可以传播到方法或者是构造函数的外面。
相反,受检查的异常必须要用throws语句在方法或者是构造函数上声明。
Java中Exception和Error有什么区别?
Exception和Error都是Throwable的子类。Exception用于用户程序可以捕获的异常情况;Error定义了不期望被用户程序捕获的异常。
throw和throws有什么区别?
throw关键字用来在程序中明确的抛出异常;throws语句用来表明方法不能处理的异常。(记忆:throws 后跟多个异常类,throw后跟一个异常对象)
public void fun() throws KeyException, ExportException {    fun1();    fun2();}public static void fun1() throws ExportException {    throw new ExportException("");}public static void fun2() throws KeyException {    throw new KeyException();}
finally代码块和finalize()方法有什么区别?
无论是否抛出异常,finally代码块都会执行,它主要是用来释放应用占用的资源。finalize()方法是Object类的一个protected方法,它是在对象被垃圾回收之前由Java虚拟机来调用的。
事件监听器接口(event-listener interface)和事件适配器(event-adapter)有什么关系?
事件监听器接口定义了对特定的事件,事件处理器必须要实现的方法;事件适配器给事件监听器接口提供了默认的实现。
GUI组件如何来处理它自己的事件?
GUI组件可以处理它自己的事件,只要它实现相对应的事件监听器接口,并且把自己作为事件监听器。
什么是JDBC?
JDBC是一个允许用户在不同数据库之间做选择的抽象层。JDBC允许开发者用JAVA写数据库应用程序,而不需要关心底层特定数据库的细节。
解释下驱动(Driver)在JDBC中的角色。
JDBC驱动提供了特定厂商对JDBC API接口类的实现,驱动必须要提供java.sql包下面这些类的实现:Connection, Statement, PreparedStatement,CallableStatement, ResultSet和Driver。
Class.forName()方法有什么作用?
初始化参数指定的类,并且返回此类对应的Class 对象
数据库连接池是什么意思?
打开关闭数据库连接会消耗大量的资源,可以在应用服务器启动的时候建立很多个数据库连接并维护在一个池中。连接请求由池中的连接提供,在连接使用完毕以后,把连接归还到池中,以用于满足将来更多的请求。
什么是RMI?
Java RMI(Remote Method Invocation)–Java的远程方法调用允许运行在一个Java虚拟机上的对象调用运行在另一个Java虚拟机上的对象的方法,从而使Java编程人员可以方便地在网络环境中作分布式计算。
RMI体系结构的基本原则是什么?
RMI体系结构是基于一个非常重要的行为定义和行为实现相分离的原则。RMI允许定义行为的代码和实现行为的代码相分离,并且运行在不同的JVM上。
RMI中的远程接口(Remote Interface)扮演了什么样的角色?
远程接口用来标识哪些方法是可以被非本地虚拟机调用的接口,远程对象必须要直接或者是间接实现远程接口。
什么是分布式垃圾回收(DGC)?它是如何工作的?
DGC叫做分布式垃圾回收。RMI使用DGC来做自动垃圾回收。因为RMI包含了跨虚拟机的远程对象的引用,垃圾回收是很困难的。DGC使用引用计数算法来给远程对象提供自动内存管理。
解释下Serialization和Deserialization。
Java对象序列化机制,把对象表示成一连串的字节的对象扁平化方式;反序列化是把对象从扁平状态转化成活动对象的相反的步骤。
doGet()方法和doPost()方法有什么区别?
1) get是从服务器上获取数据,post是向服务器传送数据;
2) get是把参数数据加到URL中,在URL中可以看到;post将各个字段与其内容放置在HTML HEADER内一起传送到指的URL地址,用户看不到这个过程;
3) get传送的数据量较小,不能大于2KB;post传送的数据量较大,一般被默认为不受限制;
4) get方式的安全性较Post方式要差些,但是执行效率却比Post方法好。
HTTP响应的结构是怎么样的?
http响应有三部分:
①响应码:回应客户端此次响应是否成功;
②消息头:服务器与客户端通信的暗码,告诉客户端该怎么执行某些操作;
③响应正文:传递服务器响应给客户端要显示的内容,可以是下载文件或者显示界面。
什么是cookie?session和cookie有什么区别?

cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户的状态,就使用response向客户端浏览器颁发一个cookie。客户端浏览器会把cookie保存起来,当浏览器再次请求该网站时,浏览器就会把请求地址和cookie一同给服务器。服务器检查该cookie,从而判断用户的状态。

session是另一种记录客户端状态的机制。不同的是cookie保存在客户端浏览器中,而session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是session。客户端浏览器再次访问时只需要从该session中查找该客户的状态就可以了。

如果说cookie机制是通过检查客户身上的“通信证”,那么session机制就是通过检查服务器上的“客户明细表”来确认客户身份。

封装的定义和好处有哪些?
封装给对象提供了隐藏内部特性和行为的能力。对象提供一些能被其他对象访问的方法来改变它内部的数据。
封装的一些好处:
1) 通过隐藏对象的属性来保护对象内部的状态;
2) 提高了代码的可用性和可维护性;
3) 禁止对象之间的不良交互提高模块化。
多态的定义?
多态:相同类型的引用变量,调用同一个方法时呈现出多种不同的行为特征。多态分两种类型:
编译时多态:在编译时能够确定执行多态方法中的哪一个,称为编译时多态; 方法重载是编译时多态。
运行时多态:在执行期间根据实际类型判断并调用相应的属性和方法。主要用于继承父类和实现接口时,父类引用指向子类对象。
方法覆盖表现出两种多态性:当对象引用本类实例时,为编译时多态;否则为运行时多态。
当一个父类引用子类对象时,运行时确定执行那些在父类中声明、被子类覆盖的子类方法,不能执行子类增加的方法。
0 0
原创粉丝点击