【Java编程】关于Java的几个基础问题

关于Java的几个基础问题

String 和 StringBuffer 和 StringBuilder 的异同?

相同点

  • 三者在 Java 中都是用来处理字符串的。
  • 三个类都被 final 修饰,因此都是不可继承的。
  • StringBuilderStringBuffer 有公共父类 AbstractStringBuilder (抽象类)。

不同点

  • 基本区别:String 为字符串常量,而 StringBuilderStringBuffer 均为字符串变量,String 对象一旦创建后该对象是不可更改的,后两者的对象为变量是可以更改的。
  • 性能区别:三者中 StringBuilder 执行速度最佳,StringBuffer 次之,String 的执行速度最慢。
  • 安全区别:StringStringBuffer 是线程安全的,StringBuilder 是线程不安全的(所以如果程序是单线程的使用 StringBuilder 效率高,如果是多线程使用 StringBuffer 或者 String)。

set 集合的特点

  • 存入集合的顺序和取出集合的顺序不一致
  • 没有索引
  • 存入集合的元素没有重复

set 接口的实现类常用的有 HashSetTreeSet 类。语法格式如下:

Set<String> set1 = new HashSet<String>();
 
Set<String> set2 = new TreeSet<String>();

HashSet 唯一性原理

规则:新添加到 HashSet 集合的元素都会与集合中已有的元素一一比较。

  • 首先比较哈希值(每个元素都会调用 hashCode() 产生一个哈希值)。
  • 如果新添加的元素与集合中已有的元素的哈希值都不同,新添加的元素存入集合。
  • 如果新添加的元素与集合中已有的某个元素哈希值相同,此时还需要调用 equals(Object obj) 比较。
    • 如果 equals(Object obj) 方法返回 true,说明新添加的元素与集合中已有的某个元素的属性值相同,那么新添加的元素不存入集合。
    • 如果 equals(Object obj) 方法返回 false,说明新添加的元素与集合中已有的元素的属性值都不同, 那么新添加的元素存入集合。

throw、throws 的区别?

  • throw 在方法体内使用,throws 在方法声明上使用;
  • throw 后面接的是异常对象,只能接一个。throws 后面接的是异常类型,可以接多个,多个异常类型用逗号隔开;
  • throw 是在方法中出现不正确情况时,手动来抛出异常,结束方法的,执行了 throw 语句一定会出现异常。而 throws 是用来声明当前方法有可能会出现某种异常的,如果出现了相应的异常,将由调用者来处理,声明了异常不一定会出现异常。

以下的变量定义语句中,合法的是?

A. byte=128(不合法)
B. boolean=null(不合法)
C. long a=123L(合法)
D. double=0.9239d(不合法)

A项中 byte 赋值范围为-128~127。B项中 boolean 类型只能赋值 true 或者 false。D项中没变量名。

下面哪个修饰符不允许父类被继承?

A. abstract
B. static
C. protected
D. final

final 修饰的类不能被继承。final 修饰的常量不能修改。

哪些不是 Java 中正确的整数?

A. 22
B. 0x22
C. 022
D. 22h

[解析] 选项 A 中表示的是十进制的整数,选项 B 中表示的是十六进制的整数,选项 C 中表示的是八进制的整数,而选项 D 它表示的也是十六进制整数,只不过它的表示方法在 Java 中不能使用,它是在汇编或接口中使用的十六进制表示整数的方法。

System.out.println(22);
System.out.println(0x22);
System.out.println(022);

在这里插入图片描述

Java 中对象的引用通常存储在哪里?

  • 寄存器:寄存器是速度最快的存储区域,它位于处理器内部,但它的数量有限,所以要按需分配,不能被人控制。
  • 堆栈:通常也叫栈,位于 RAM 中,堆栈指针向下移动,则分配新的内存;向上移动,则释放那些内存。这种存储方式速度仅次于寄存器。常用于存放对象引用与基本数据类型,不存放Java对象。栈内存被要求存放在其中的数据的大小、生命周期必须是已经确定的。
  • :通用的内存池,位于 RAM 中,用于存放所有的 Java 对象。编译器不需要知道存储的数据在堆中存活多长时间;当需要一个对象时,用 new 写一行代码,当执行这行代码时,会自动在堆中进行存储分配,同时,有以上原因,用堆进行存储分配和清理可能比堆栈进行存储分配花更多的时间。
  • 常量存储:常量值通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会改变。但有时在嵌入式系统中,常量本身会和其他部分隔开,放在 ROM 中。
  • 非RAM存储:如果数据完全存活在程序之外,那么它可以不受程序控制,程序没有运行时也可以存在。比如流对象与持久化对象。

一个父类可以有多个子类?

在 Java 中,一个父类可以有多个子类,但是子类只能有一个父类。子类通常通过关键字 extends 来继承父类。就像在现实世界里,一个父亲可能有多个孩子,但一个孩子只能有一个父亲。

为什么一个类不能有多个父类呢?因为当一个类同时继承两个父类时,两个父类中有相同的功能,那么子类对象调用该功能时,运行哪一个呢?因为父类中的方法中存在方法体。

但是 Java 支持多重继承。A继承B,B继承C,C继承D,子子孙孙无穷尽也。多重继承的出现,就有了继承体系。体系中的顶层父类是通过不断向上抽取而来的。它里面定义的该体系最基本最共性内容的功能。

page 对象是一个 servlet 类实例?

page 对象是 JSP 九大内置对象之一。JSP 全称 JavaServerPage,是一种动态网页技术标准,以 Java 语言作为脚本语言。在 JSP 中预先定义了九个内置对象,这个九个内置对象不需要声明就可以在脚本代码和表达式中任意使用,分别是:requestresponsesessionapplicationoutpageContextconfigpageexception

page 对象代表 JSP 页面正在运行所产生的类对象本身,只在 JSP 页面内使用。page 对象本质上包含当前 Servlet 接口引用的变量,类似 Java 类中 this 指针,是 java.lang.Object 的实例 。

page 对象有以下方法:

  • void wait():使 page 对象所在线程处于等待状态,直到被唤醒。
  • void wait(long timeout):使 page 对象所在线程处于等待状态,直到 timeout 毫秒后被唤醒。
  • void wait(long timeout,int nanos):使 page 对象所在线程处于等待状态,直到 timeout 毫秒 + nanos 纳秒后被唤醒。
  • boolean equals(Object obj):比较 page 对象与指定 Object 对象是否相等。
  • String toString():将 page 对象转成 String 类型的对象。
  • Class getClass():返回 page 对象的类。
  • int hashCode():返回 page 对象的哈希值。
  • void notify():唤醒 page 对象正处于线程等待状态下的线程。
  • void notifyAll():唤醒所有 page 对象正处于线程等待状态下的线程。

在 J2EE 中,以下不是 JSP 隐式对象的是()。

A. pageContext
B. context
C. application
D. out

只有 B 选项非九个内置对象之一。

Java 对象在堆区的状态?

Java 中的对象的三种状态是和垃圾回收紧密相关的,因此有必要深究。

  • 状态一:可触及态。从根节点开始,可以搜索到这个对象,也就是可以访问到这个对象,也有人将其称为可达状态。
  • 状态二:可复活态。从根节点开始,无论如何都不能访问到这个对象,也就是说这个对象的所有引用都被释放,没有任何变量引用该对象了,但是该对象有可能在 finalize() 方法中再次被引用,从而复活。
  • 状态三:不可触及态。对象的所有引用都被释放了,并且在对象的 finalize() 方法中没有复活,这样的话该对象就是不可触及状态。

对于状态三我再解释下,所有对象都有 finalize() 方法,并且该方法只会被执行一次,并且它的执行时间是随机的,一般在我们为变量赋值为 null 后,会执行,如果我们在某个对象的 finalize() 方法中为他增加了引用,那么该对象会复活,但是当我们再次为其赋值为 null 时,finalize() 方法不会被执行了,因为该方法只执行一次,该对象也就变成了不可触及态。

说到 finalize() 方法,我再多说点,有的书上写,可以在 finalize() 方法中释放某些资源,其实这并不被我们所推荐,主要有两点:

  • finalize() 方法执行的时间不确定,那么这就会导致资源还没来得及释放,又有一个线程需要访问资源,可能会产生异常错误。尤其是在多线程程序中。
  • finalize() 方法中可能会发生引用外泄,无意中复活对象,从而产能生内存泄漏。

推荐在 try-catch-finally 结构的 finally 块中释放资源。

Java 哪个类提供了随机访问文件?

RandomAccessFile 类

RandomAccessFile 声明在 java.io 包下,但直接继承于 java.lang.Object 类,这个类既可以读,也可以写。

RandomAccessFile 类支持 “随机访问” 的方式,程序可以直接跳到文件的任意地方来读写文件。

  • 支持只访问文件的部分内容
  • 可以向已存在的文件后追加内容

RandomAccessFile 对象包含一个记录指针,用以标示当前读写处的位置。

servlet 程序的入口点是?

A. init()
B. main()
C. service()
D. doGet()

Servlet(Server Applet)是 JavaServlet 的简称,称为小服务程序或服务连接器,用 Java 编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态 Web 内容。

最初 servlet 会调用 init() 进行初始化,然后调用 service() 接受客户端请求,再调用 doGet() 或者 doPost() 处理客户端请求,最后销毁 servlet。Servlet 程序的入口点其实就是 service 方法,它控制着 servlet 一切的接收功能,servlet 的入口就是它了。

forward 和 redirect 的区别?

1.二者的请求方式不同

redirect 是通过客户端发起的请求,forward 是通过服务器端发起的请求。

2.在浏览器中二者的 url 表现不同

  • redirect 是服务器根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,所以地址栏显示的是新的地址。
  • forword 是服务器内部的重定向,服务器直接访问目标地址的 url 网址,把里面的东西读取出来,但是客户端并不知道,因此用 forward 的话,客户端浏览器的网址是不会发生变化的。

3.二者底层实现的思路不同

redirect 发送的请求信息首先会发送到客户端,然后通过客户端再发送到服务器上,所以需要在客户端与服务器之间进行一次通信。forward 是直接找到目标,并 include 过来。

4.参数传递不同

redirect:重新开始一个 request,原页面的 request 生命周期结束。

forward:forward 另一个连接的时候。request 变量是在其生命周期内的。另一个页面也可以使用,其实质是把目标地址 include。

5.定义不同

直接转发方式(forward):客户端和浏览器只发出一次请求,Servlet、HTML、JSP 或其它信息资源,由第二个信息资源响应该请求,在请求对象 request 中,保存的对象 对于每个信息资源是共享的

间接转发方式(redirect):实际是两次 HTTP 请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个 URL 发出请求,从而达到转发的目的。

6.应用场景不同

  • forword 一般用于用户登录的时候,根据角色转发到相应的模块。
  • redirect 一般用于用户注销登录时返回主页面或者跳转到其他网站。

下列哪一种叙述是正确的 ?

A. abstract 修饰符可以修饰字段、方法和类。
B. 抽象方法的 body 部分必须用一对大括号{}包住。
C. 声明抽象方法,大括号可有可无。
D. 声明抽象方法不可写出大括号。

选项 A 描述错误,abstract 修饰符不可以修饰字段。选项 B 描述错误,抽象方法没有 body 执行体,所以不能用大括号包裹。选项 C 描述错误,声明抽象方法,只能含有方法结构,不能含有大括号方法执行体。

Java IO 中的 File 类干什么的 ?

  • File 类在 java.io 包下,是文件和目录(文件夹)的路径名的抽象表示,主要用于创建、获取、删除文件 / 文件夹,判断文件 / 文件夹是否存在,对文件夹进行遍历,获取文件的大小等操作。
  • File 类与操作系统无关,任何操作系统都可以使用类中的方法。
  • 绝对路径与相对路径:绝对路径是一个完整的路径,以盘符开始的路径;相对路径是一个简化的路径,相对指的是相对于当前项目的根目录。路径不区分大小写,但 Windows 系统文件名称分隔符 / 是转义字符,需要用两个 // 来表示。

面向字符的输入流有哪些 ?

面向字符的输入流类都是 Reader 的子类。

【Java编程】关于Java的几个基础问题_第1张图片

类名 功能描述
CharArrayReader 从字符数组读取的输入流
BufferedReader 缓冲输入字符流
PipedReader 输入管道
InputStreamReader 过滤输入流
FilterReader 从字符数组读取的输入流
StringReader 从字符串读取的输入流
LineNumberReader 为输入数据附加行号
PushbackReader 返回一个字符并把此字节放回输入流
FileReader 从文件读取的输入流

主类名 a1,源文件名是啥?

A. a1.java(正确)
B. a1.class
C. a1
D. 都对

重写的方法与被重写的方法返回值类型必须一致吗 ?

重写方法的规则:

  • 参数列表必须完全与被重写的方法相同,否则不能称其为 重写 而是 重载
  • 返回的类型必须一直与被重写的方法的返回类型相同。
  • 访问修饰符的限制一定要大于被重写方法的访问修饰符(public > protected > default > private)。
  • 重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。例如:
    父类的一个方法申明了一个检查异常 IOException,再重写这个方法是就不能抛出 Exception,只能抛出 IOException 的子类异常,可以抛出非检查异常。

主要用于远程调用等需要大量数据传输对象的是 ?

【Java编程】关于Java的几个基础问题_第2张图片
PO(persistant object)持久对象

Persistant Object 持久对象,即持久层。在 O/R 映射的时候出现的概念,如果没有 O/R 映射,就没有这个概念存在了。通常对应数据模型(数据库),本身还有部分业务逻辑的处理。可以看成是与数据库中的表相映射的 Java 对象。最简单的 PO 就是对应数据库中某个表中的一条记录,多个记录可以用 PO 的集合。PO 中应该不包含任何对数据库的操作。

最形象的理解就是一个 PO 就是数据库中的一条记录。好处是可以把一条记录作为一个对象处理,可以方便的转为其它对象。

VO(value object)值对象

ViewObject 表现层对象,即控制层(Action 层)。主要对应界面显示的数据对象。对于一个 WEB 页面,或者 SWT、SWING 的一个界面,用一个 VO 对象对应整个界面的值。

通常用于业务层之间的数据传递,和 PO 一样也是仅仅包含数据而已。但应是抽象出的业务对象,可以和表对应,也可以不对应,这根据业务的需要。个人觉得同 DTO(数据传输对象),在 web 上传递。

BO(business object)业务对象

Business Object 业务对象,即 Service 层。主要作用是把业务逻辑封装为一个对象。这个对象可以包括一个或多个其它的对象。

比如一个简历,有教育经历、工作经历、 关系等等。我们可以把教育经历对应一个 PO,工作经历对应一个 PO, 关系对应一个 PO。建立一个对应简历的 BO 对象处理简历,每个 BO 包含这些 PO。这样处理业务逻辑时,我们就可以针对 BO 去处理。

POJO(plain ordinary java object)简单无规则 java 对象

传统意义的 Java 对象,就是说在一些 Object/Relation Mapping 工具中,能够做到维护数据库表记录的 persisent object,完全是一个符合 Java Bean 规范的纯 Java 对象,没有增加别的属性和方法。我的理解就是最基本的 Java Bean,只有属性字段及 setter 和 getter 方法!

POJO 是最常见最多变的对象,是一个中间对象,也是我们最常打交道的对象。一个 POJO 持久化以后就是 PO。直接用它传递、传递过程中就是 DTO。直接用来对应表示层就是 VO。

【Java编程】关于Java的几个基础问题_第3张图片

DAO(data access object)数据访问对象

是 sun 的一个标准 J2EE 设计模式。这个模式中有个接口就是 DAO,它负责持久层的操作,为业务层提供接口,此对象用于访问数据库。通常和 PO 结合使用,DAO 中包含了各种数据库的操作方法。通过它的方法,结合 PO 对数据库进行相关的操作。夹在业务逻辑与数据库资源中间。配合 VO,提供数据库的 CRUD 操作。

DTO(data transfer object)数据传输对象

主要用于远程调用等需要大量传输对象的地方。

比如,我们一张表有 100 个字段,那么对应的 PO 就有 100 个属性。但是我们界面上只要显示 10 个字段,客户端用 WEB service 来获取数据,没有必要把整个 PO 对象传递到客户端,这时我们就可以用只有这 10 个属性的 DTO 来传递结果到客户端,这样也不会暴露服务端表结构。到达客户端以后,如果用这个对象来对应界面显示,那此时它的身份就转为 VO。

【Java编程】关于Java的几个基础问题_第4张图片
【Java编程】关于Java的几个基础问题_第5张图片

基本类型的默认值。

【Java编程】关于Java的几个基础问题_第6张图片

你可能感兴趣的:(Java编程,java,JavaSE,jvm,IO)