Java面试基础

Java基础

 

一、对比篇

1final, finally, finalize的区别

final如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在new一个对象时初始化(即只能在声明变量或构造器或代码块内初始化),而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能覆盖(重写)

finally:在异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。

finalize:方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。注意:finalize()不一定被jvm调用,只有当垃圾回收器要清除垃圾时才被调用。

 

2List, Set, Map区别

List实现Collection接口,元素有放入顺序,元素可重复,实现类:LinkedListArrayListVector 

Set实现Collection接口,元素无放入顺序,元素不重复,实现类:HashSet, LinkedHashSet

Map不实现接口,元素无放入顺序,元素按键值对,实现类:HashMapHashTableLinkeHashMap 

 

3Arraylist, Linkedlist, Vector, Stack区别

Arraylist数组实现、非线程安全,容量可扩展。

Linkedlist双向链表实现、非线程安全,容量可扩展。

Vector数组实现、线程安全,容量可扩展。

Stack继承于Vector

 

4HashMap, Hashtable, LinkedHashMap, TreeMap区别

HashMap哈希表数据结构,实现Map接口,继承AbstractMap,非线程安全,允许有null的键和值,有containsvaluecontainsKey方法。

Hashtable哈希表数据结构,实现Map接口,继承Dictiionary,线程安全,不允许有null的键和值,有contains方法方法。

LinkedHashMap: 继承于HashMap,保存了记录的插入顺序。

TreeMap二叉树数据结构,实现SortedMap接口,可按自然顺序或自定义顺序遍历键。

 

5errorexception区别

Throwable 是所有 Java 程序中错误处理的父类 ,有两种子类: Error 和 Exception 

Error表示由 JVM 所侦测到的无法预期的错误,由于这是属于 JVM 层次的严重错误 ,导致 JVM 无法继续执行,因此,这是不可捕捉到的,无法采取任何恢复的操作,顶多只能显示错误信息。

Exception表示可恢复的例外,这是可捕捉到的。

Java 提供了两类主要的异常 :runtime exception 和 checked exception 。 checked exception也就是我们经常遇到的 IO 异常,以及 SQL 异常。对于这种异常, JAVA 编译器强制要求我们必需对出现的这些异常进行 catch 。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆 catch 块去处理可能的异常。

runtime exception也称运行时异常,我们可以不处理。当出现这样的异常时,总是由JVM接管。比如:我们从来没有人去处理过 NullPointerException 异常,它就是运行时异常,并且这种异常还是最常见的异常之一。

 

6jdk, jre, jvm区别

JDKJava Development ToolKit(Java开发工具包)JDK是整个JAVA的核心,包括了Java运行环境(Java Runtime Envirnment,一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。有以下三种版本:J2SE标准版;J2EE企业版;J2ME主要用于移动设备、嵌入式设备上的java应用程序。我们常常用JDK来代指Java APIJava APIJava的应用程序接口,其实就是前辈们写好的一些java Class,包括一些重要的语言结构以及基本图形,网络和文件I/O等等 ,我们在自己的程序中,调用前辈们写好的这些Class,来作为我们自己开发的一个基础。当然,现在已经有越来越多的性能更好或者功能更强大的第三方类库供我们使用。

JREJava Runtime Enviromental(java运行时环境)。也就是我们说的JAVA平台,所有的Java程序都要在JRE下才能运行。包括JVMJAVA核心类库和支持文件。与JDK相比,它不包含开发工具——编译器、调试器和其它工具。

JVMJava Virtual Mechinal(java虚拟机)JVMJRE的一部分,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。它的主要工作是解释自己的指令集(即字节码)并映射到本地的 CPU 的指令集或 OS 的系统调用。Java语言是跨平台运行的,其实就是不同的操作系统,使用不同的JVM映射规则,让其与操作系统无关,完成了跨平台性。JVM 对上层的 Java 源文件是不关心的,它关注的只是由源文件生成的类文件(class file)。类文件的组成包括 JVM 指令集,符号表以及一些补助信息。

    我们开发的实际情况是:我们利用JDK(调用JAVA API)开发了属于我们自己的JAVA程序后,通过JDK中的编译程序(javac)将我们的文本java文件编译成JAVA字节码,在JRE上运行这些JAVA字节码,JVM解析这些字节码,映射到CPU指令集或OS的系统调用。

 

7X=X+YX+=Y区别

虽然 x+=y 和 x=x+y 两个表达式在一般情况下可以通用,但是在 Java 环境中运行时存在一些细微的差别。这差别在于 += 除了实现 功能外,还会根据接收变量的类型自动进行类型的强制转换。

 

 

二、Servlet

1Servlet的生命周期

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

(1) Servlet 通过调用 init () 方法进行初始化。

(2)  Servlet 调用 service() 方法来处理客户端的请求。

(3) Servlet 通过调用 destroy() 方法终止(结束)。

最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

init()它只会被调用一次,它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,就像 Applet 的 init 方法一样。Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。

service()它是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 检查 HTTP 请求类型(GETPOSTPUTDELETE 等),并在适当的时候调用 doGetdoPostdoPutdoDelete 等方法。所以,您不用对 service() 方法做任何动作,您只需要根据来自客户端的请求类型来重载 doGet() 或 doPost() 即可。

destroy()它只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。

 

2

 

三、线程篇

1、进程与线程

进程:是程序的一次动态执行,它对应着从代码加载,执行至执行完毕的一个完整的过程,是一个动态的实体,它有自己的生命周期。它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消。反映了一个程序在一定的数据 集上运行的全部动态过程。通过进程控制块 (PCB) 唯一的标识某个进程。同时进程占据着相应的资源(例如包括CPU的使用,轮转时间以及一些其它设备的权限)。进程是系统进行资源分配和调度的一个独立单位。

线程可以理解为进程的多条执行线,每条线对应着各自独立的生命周期。线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行、共享该进程的资源。

进程是资源分配的最小单位,线程是CPU调度的最小单位。

 

2、竞争与死锁

    进程共享资源包括软件资源和硬件资源。软件资源有变量、表格、队列;硬件资源有物理设备,例如:打印机,输入设备等。进程共享资源有一个重要内容就是共享内存,进程共享内存是共享操作系统空间资源,而非进程本身内存

竞争:多个进程/线程所共享的资源(不同进程之间需要开发共享),不足以同时满足它们的需要时,引起它们对资源的竞争。

死锁:多个进程/线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去,此时称死锁。

死锁不一定是由竞争引起。

 

3sleep()wait()的区别

 (1) 这两个方法来自不同的类分别是ThreadObject

 (2) 最主要是sleep方法没有释放锁,而 wait 方法释放了锁。

 (3)  waitnotifynotifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。

 (4)  sleep必须捕获异常,而waitnotifynotifyAll不需要捕获异常。

 

 

四、执行顺序篇

1try{}中的returnfinally{}块的执行顺序

 (1)  finally{}语句在return语句执行之后return返回之前执行。

 (2)  finally{}中的return语句会覆盖try{}中的return返回。

 (3)  finally{}可能修改try{}中的return返回值,因为java是值传递(finally{}类似一个方法)。

 (4)  try{}里的return语句在异常的情况下不会被执行。

 (5) 当发生异常后,catch{}中的return执行情况与未发生异常时try{}return的执行情况完全一样。

 

2

 

五、其它篇

1、迭代器

迭代器:它是一种设计模式,是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

Java中的Iterator功能比较简单,并且只能单向移动:

  (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iteratornext()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,Collection继承。

  (2) 使用next()获得序列中的下一个元素。

  (3) 使用hasNext()检查序列中是否还有元素。

  (4) 使用remove()将迭代器新返回的元素删除。

IteratorJava迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。

 

2、值传递

java只有值传递。如果是基本数据类型,传递的就是实际的值,如果是引用数据类型,传递的就是该引用的地址值.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值