java面试题(四)

简介: 1、什么时候用断言(assert)? 答: 断言在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。一 般来说,断言用于保证程序最基本、关键的正确性。断言检查通常在开发和测试 时开启。为了保证程序的执行效率,在软件发布后断言检查通常是关闭的。断言 是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为 true;如果表 达式的值为 false,那么系统会报告一个 AssertionError。断言的使用如下面的代码所示:assert(a > 0); // throws an AssertionError if a <= 0断言可以有两种形式: assert

1、什么时候用断言(assert)?

答:

断言在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。一

般来说,断言用于保证程序最基本、关键的正确性。断言检查通常在开发和测试

时开启。为了保证程序的执行效率,在软件发布后断言检查通常是关闭的。断言

是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为 true;如果表

达式的值为 false,那么系统会报告一个 AssertionError。

断言的使用如下面的代码所示:

assert(a > 0); // throws an AssertionError if a <= 0

断言可以有两种形式:

assert Expression1;

assert Expression1 : Expression2 ;

Expression1 应该总是产生一个布尔值。

Expression2 可以是得出一个值的任意表达式;这个值用于生成显示更多调试信

息的字符串消息。

要在运行时启用断言,可以在启动 JVM 时使用-enableassertions 或者-ea 标记。

要在运行时选择禁用断言,可以在启动 JVM 时使用-da 或者-disableassertions

标记。要在系统类中启用或禁用断言,可使用-esa 或-dsa 标记。还可以在包的基

础上启用或者禁用断言。

注意:断言不应该以任何方式改变程序的状态。简单的说,如果希望在不满足某

些条件时阻止代码的执行,就可以考虑用断言来阻止它。

2、Error 和 Exception 有什么区别?

答:

Error 表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情

况下的一种严重问题;比如内存溢出,不可能指望程序能处理这样的情况;

Exception 表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题;

也就是说,它表示如果程序运行正常,从不会发生的情况。

3、Java 语言如何进行异常处理,关键字:throws、throw、try、catch、finally 分别如何使用?

答:

Java 通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了

良好的接口。在 Java 中,每个异常都是一个对象,它是 Throwable 类或其子类

的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,

调用这个对象的方法可以捕获到这个异常并可以对其进行处理。Java 的异常处理

是通过 5 个关键词来实现的:try、catch、throw、throws 和 finally。一般情况

下是用 try 来执行一段程序,如果系统会抛出(throw)一个异常对象,可以通过

它的类型来捕获(catch)它,或通过总是执行代码块(finally)来处理;try 用

来指定一块预防所有异常的程序;catch 子句紧跟在 try 块后面,用来指定你想要

捕获的异常的类型;throw 语句用来明确地抛出一个异常;throws 用来声明一个

方法可能抛出的各种异常(当然声明异常时允许无病呻吟);finally 为确保一段

代码不管发生什么异常状况都要被执行;try 语句可以嵌套,每当遇到一个 try 语

句,异常的结构就会被放入异常栈中,直到所有的 try 语句都完成。如果下一级的

try 语句没有对某种异常进行处理,异常栈就会执行出栈操作,直到遇到有处理这

种异常的 try 语句或者最终将异常抛给 JVM。

4、运行时异常与受检异常有何异同?

答:

异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常

操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就

不会发生。受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可

能因使用的问题而引发。Java 编译器要求方法必须声明抛出可能发生的受检异常,

但是并不要求必须声明抛出未被捕获的运行时异常。

异常和继承一样,是面向对象程序设计中经常被滥用的东西,在 Effective Java 中对异常的使用给出了以下指导原则:

不要将异常处理用于正常的控制流(设计良好的 API 不应该强迫它的调用者为了正常的控制流而使用异常)

对可以恢复的情况使用受检异常,对编程错误使用运行时异常

避免不必要的使用受检异常(可以通过一些状态检测手段来避免异常的发生)

优先使用标准的异常

每个方法抛出的异常都要有文档

保持异常的原子性

不要在 catch 中忽略掉捕获到的异常

5、列出一些你常见的运行时异常?

ArithmeticException(算术异常)

ClassCastException (类转换异常)

IllegalArgumentException (非法参数异常)

IndexOutOfBoundsException (下标越界异常)  

NullPointerException (空指针异常)

SecurityException (安全异常)

6、阐述 final、finally、finalize 的区别。

答:

final:

修饰符(关键字)有三种用法:如果一个类被声明为 final,意味着它不能再派生出新的子类,即不能被继承,因此它和 abstract 是反义词。将变量声明为 final,可以保证它们在使用中不被改变,被声明为 final 的变量必须在声明时给定初值,而在以后的引用中只能读取不可修改。被声明为 final 的方法也同样只能使用,不能在子类中被重写。

finally:

通常放在 try…catch…的后面构造总是执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要 JVM 不关闭都能执行,可以将释放外部资源的代码写在 finally 块中。

finalize:

Object 类中定义的方法,Java 中允许使用 finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写 finalize()方法可以整理系统资源或者执行其他清理工作。

7、阐述 ArrayList、Vector、LinkedList 的存储性能和特性。

答:

ArrayList 和 Vector 都是使用数组方式存储数据,此数组元素数大于实际存储的

数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉

及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector 中的方法由

于添加了 synchronized 修饰,因此 Vector 是线程安全的容器,但性能上较

ArrayList 差,因此已经是 Java 中的遗留容器。LinkedList 使用双向链表实现存

储(将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索

引的线性结构,这种链式存储方式与数组的连续存储方式相比,内存的利用率更

高),按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本

项的前后项即可,所以插入速度较快。Vector 属于遗留容器(Java 早期的版本中

提供的容器,除此之外,Hashtable、Dictionary、BitSet、Stack、Properties

都是遗留容器),已经不推荐使用,但是由于 ArrayList 和 LinkedListed 都是非

线程安全的,如果遇到多个线程操作同一个容器的场景,则可以通过工具类

Collections 中的 synchronizedList 方法将其转换成线程安全的容器后再使用(这

是对装潢模式的应用,将已有对象传入另一个类的构造器中创建新的对象来增强

实现)。

补充:遗留容器中的 Properties 类和 Stack 类在设计上有严重的问题,Properties

是一个键和值都是字符串的特殊的键值对映射,在设计上应该是关联一个

Hashtable 并将其两个泛型参数设置为 String 类型,但是 Java API 中的

Properties 直接继承了 Hashtable,这很明显是对继承的滥用。这里复用代码的方式应该是 Has-A 关系而不是 Is-A 关系,另一方面容器都属于工具类,继承工具类本身就是一个错误的做法,使用工具类最好的方式是 Has-A 关系(关联)或Use-A 关系(依赖)。同理,Stack 类继承 Vector 也是不正确的。Sun 公司的工程师们也会犯这种低级错误,让人唏嘘不已。

8、Collection 和 Collections 的区别?

答:

Collection 是一个接口,它是 Set、List 等容器的父接口;Collections 是个一个

工具类,提供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索、

排序、线程安全化等等。

9、TreeMap 和 TreeSet 在排序时如何比较元素? Collections 工具类中的 sort()方法如何比较元素?

答:

TreeSet 要求存放的对象所属的类必须实现 Comparable 接口,该接口提供了比

较元素的 compareTo()方法,当插入元素时会回调该方法比较元素的大小。

TreeMap 要求存放的键值对映射的键必须实现 Comparable 接口从而根据键对元

素进行排序。Collections 工具类的 sort 方法有两种重载的形式,第一种要求传入

的待排序容器中存放的对象比较实现 Comparable 接口以实现元素的比较;第二

种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是

Comparator 接口的子类型(需要重写 compare 方法实现元素的比较),相当于

一个临时定义的排序规则,其实就是通过接口注入比较元素大小的算法,也是对

回调模式的应用(Java 中对函数式编程的支持)。

例子 1:

public class Student implements Comparable<Student> {

   private String name; // 姓名

   private int age; // 年龄

   public Student(String name, int age) {

       this.name = name;

       this.age = age;

   }

   @Override

   public String toString() {

       return "Student [name=" + name + ", age=" + age + "]";

   }

   @Override

   public int compareTo(Student o) {

       return this.age - o.age; // 比较年龄(年龄的升序)

   }

}

import java.util.Set;

import java.util.TreeSet;

class Test01 {

   public static void main(String[] args) {

       Set<Student> set = new TreeSet<>(); // Java 7 的钻石语法

       (构造器后面的尖括号中不需要写类型)

               set.add(new Student("Hao LUO", 33));

       set.add(new Student("XJ WANG", 32));

       set.add(new Student("Bruce LEE", 60));

       set.add(new Student("Bob YANG", 22));

       for(Student stu : set) {

           System.out.println(stu);

       }

// 输出结果:

// Student [name=Bob YANG, age=22]

// Student [name=XJ WANG, age=32]

// Student [name=Hao LUO, age=33]

// Student [name=Bruce LEE, age=60]

   }

}

10、Thread 类的 sleep()方法和对象的 wait()方法都可以让线程暂停执行,它们有什么区别?

答:

sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程

暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保

持,因此休眠时间结束后会自动恢复(线程回到就绪状态,请参考第 66 题中的线

程状态转换图)。wait()是 Object 类的方法,调用对象的 wait()方法导致当前线

程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用

对象的 notify()方法(或 notifyAll()方法)时才能唤醒等待池中的线程进入等锁池

(lock pool),如果线程重新获得对象的锁就可以进入就绪状态。

补充:可能不少人对什么是进程,什么是线程还比较模糊,对于为什么需要多线

程编程也不是特别理解。简单的说:进程是具有一定独立功能的程序关于某个数

据集合上的一次运行活动,是操作系统进行资源分配和调度的一个独立单位;线

程是进程的一个实体,是 CPU 调度和分派的基本单位,是比进程更小的能独立运

行的基本单位。线程的划分尺度小于进程,这使得多线程程序的并发性高;进程

在执行时通常拥有独立的内存单元,而线程之间可以共享内存。使用多线程的编

程通常能够带来更好的性能和用户体验,但是多线程的程序对于其他程序是不友

好的,因为它可能占用了更多的 CPU 资源。当然,也不是线程越多,程序的性能

就越好,因为线程之间的调度和切换也会浪费 CPU 时间。时下很时髦的 Node.js

就采用了单线程异步 I/O 的工作模式。

相关文章
|
8天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
28 2
|
13天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
18天前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
14天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
39 4
|
15天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
55 4
|
1月前
|
存储 安全 算法
Java面试题之Java集合面试题 50道(带答案)
这篇文章提供了50道Java集合框架的面试题及其答案,涵盖了集合的基础知识、底层数据结构、不同集合类的特点和用法,以及一些高级主题如并发集合的使用。
91 1
Java面试题之Java集合面试题 50道(带答案)
|
27天前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
54 5
|
26天前
|
存储 Java
[Java]面试官:你对异常处理了解多少,例如,finally中可以有return吗?
本文介绍了Java中`try...catch...finally`语句的使用细节及返回值问题,并探讨了JDK1.7引入的`try...with...resources`新特性,强调了异常处理机制及资源自动关闭的优势。
20 1
|
1月前
|
Java 程序员
Java 面试高频考点:static 和 final 深度剖析
本文介绍了 Java 中的 `static` 和 `final` 关键字。`static` 修饰的属性和方法属于类而非对象,所有实例共享;`final` 用于变量、方法和类,确保其不可修改或继承。两者结合可用于定义常量。文章通过具体示例详细解析了它们的用法和应用场景。
28 3
|
2月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
421 37
下一篇
无影云桌面