【2021-07-07】Java Q/A

1、Java语言的鲁棒性

Java在编译和运行程序时,都要对可能出现的问题进行检查,以消除错误的产生。它提供自动垃圾收集来进行内存管理,防止程序员在管理内存时容易产生的错误。通过集成的面向对象的例外处理机制,在编译时,Java揭示出可能出现但未被处理的异常,帮助程序员正确地进行选择以防止系统的崩溃。另外,Java在编译时还可捕获类型声明中的许多常见错误,防止动态运行时不匹配问题的出现。

2、局部变量为什么要初始化

局部变量是指类方法中的变量,必须初始化。局部变量运行时被分配在栈中,量大,生命周期短,如果虚拟机给每个局部变量都初始化一下,是一笔很大的开销,但变量不初始化为默认值就使用是不安全的。出于速度和安全性两个方面的综合考虑,解决方案就是虚拟机不初始化,但要求编写者一定要在使用前给变量赋值。

3、形参&实参

形式参数可被视为local variable.形参和局部变量一样都不能离开方法。只有在方法中使用,不会在方法外可见。
形式参数只能用final修饰符,其它任何修饰符都会引起编译器错误。但是用这个修饰符也有一定的限制,就是在方法中不能对参数做任何修改。不过一般情况下,一个方法的形参不用final修饰。只有在特殊情况下,那就是: 方法内部类。一个方法内的内部类如果使用了这个方法的参数或者局部变量的话,这个参数或局部变量应该是final。
形参的值在调用时根据调用者更改,实参则用自身的值更改形参的值(指针、引用皆在此列),也就是说真正被传递的是实参。

4、Java移位运算符

java中有三种移位运算符
1.<< :左移运算符,x << 1,相当于x乘以2(不溢出的情况下),低位补0
2.>> :带符号右移,x >> 1,相当于x除以2,正数高位补0,负数高位补1
3.>>> :无符号右移,忽略符号位,空位都以0补齐

5、序列化

声明为static和transient类型的数据不能被序列化, 反序列化需要一个无参构造函数

6、构造内部类和静态内部类对象

public class Enclosingone {
	public class Insideone {}
	public static class Insideone{}
}

public class Test {
	public static void main(String[] args) {
	// 构造内部类对象需要外部类的引用
	Enclosingone.Insideone obj1 = new Enclosingone().new Insideone();
	// 构造静态内部类的对象
	Enclosingone.Insideone obj2 = new Enclosingone.Insideone();
	}
}

静态内部类不需要有指向外部类的引用。但非静态内部类需要持有对外部类的引用。非静态内部类能够访问外部类的静态和非静态成员。静态内部类不能访问外部类的非静态成员,只能访问外部类的静态成员。

7、this() & super()在构造方法中的区别

1.调用super()必须写在子类构造方法的第一行, 否则编译不通过
2.super从子类调用父类构造, this在同一类中调用其他构造均需要放在第一行
3.尽管可以用this调用一个构造器, 却不能调用2个
4.this和super不能出现在同一个构造器中, 否则编译不通过
5.this()、super()都指的对象,不可以在static环境中使用
6.本质this指向本对象的指针。super是一个关键字

8、super出现在父类的子类中。有三种存在方式

super.xxx(xxx为变量名或对象名)意思是获取父类中xxx的变量或引用
super.xxx(); (xxx为方法名)意思是直接访问并调用父类中的方法
super() 调用父类构造
注: super只能指代其直接父类

9、受检查异常和运行时异常

  1. 受检查的异常(checked exceptions),其必须被try…catch语句块所捕获, 或者在方法签名里通过throws子句声明。受检查的异常必须在编译时被捕捉处理,命名为Checked Exception是因为Java编译器要进行检查, Java虚拟机也要进行检查, 以确保这个规则得到遵守。
    常见的checked exception: ClassNotFoundException IOException FileNotFoundException EOFException
  2. 运行时异常(runtime exceptions), 需要程序员自己分析代码决定是否捕获和处理,比如空指针,被0除…
    常见的runtime exception: NullPointerException ArithmeticException ClassCastException IllegalArgumentException IllegalStateException IndexOutOfBoundsException NoSuchElementException
  3. Error的,则属于严重错误,如系统崩溃、虚拟机错误、动态链接失败等,这些错误无法恢复或者不可能捕捉,将导致应用程序中断,Error不需要捕获。

10、关于finally

  1. finally不管有没有异常都要处理
  2. 当try和catch中有return时,finally仍然会执行,finally比return先执行
  3. 不管有木有异常抛出, finally在return返回前执行
  4. finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,仍然是之前保存的值),所以函数返回值是在finally执行前确定的

注意: finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值 finally不执行的几种情况: 程序提前终止如调用了System.exit, 病毒,断电

11、异常

相关的关键字 throw、throws、try…catch、finally

  1. throws 用在方法签名上, 以便抛出的异常可以被调用者处理
  2. throw 方法内部通过throw抛出异常
  3. try 用于检测包住的语句块, 若有异常, catch子句捕获并执行catch块

12、抽象类和最终类

抽象类可以没有抽象方法, 最终类可以没有最终方法
最终类不能被继承, 最终方法不能被重写(可以重载)

13、接口与抽象类

一个子类只能继承一个抽象类,但能实现多个接口 抽象类可以有构造方法,接口没有构造方法 抽象类可以有普通成员变量,接口没有普通成员变量 抽象类和接口都可有静态成员变量,抽象类中静态成员变量访问类型任意,接口只能public static final(默认) 抽象类可以没有抽象方法,抽象类可以有普通方法,接口中都是抽象方法 抽象类可以有静态方法,接口不能有静态方法 抽象类中的方法可以是public、protected;接口方法只有public abstract

14、String、StringBuffer与StringBuilder的区别

第一点: 可变和适用范围。String对象是不可变的,而StringBuffer和StringBuilder是可变字符序列。每次对String的操作相当于生成一个新的String对象,而对StringBuffer和StringBuilder的操作是对对象本身的操作,而不会生成新的对象,所以对于频繁改变内容的字符串避免使用String,因为频繁的生成对象将会对系统性能产生影响。
第二点: 线程安全。String由于有final修饰,是immutable的,安全性是简单而纯粹的。StringBuilder和StringBuffer的区别在于StringBuilder不保证同步,也就是说如果需要线程安全需要使用StringBuffer,不需要同步的StringBuilder效率更高。

15、equals与==的区别

区别1. ==是一个运算符 equals是Object类的方法
区别2. 比较时的区别 用于基本类型的变量比较时: ==用于比较值是否相等,equals不能直接用于基本数据类型的比较,需要转换为其对应的包装类型。 用于引用类型的比较时。==和equals都是比较栈内存中的地址是否相等 。相等为true 否则为false。但是通常会重写equals方法去实现对象内容的比较。

16、Object有哪些公用方法?

clone equals hashcode wait notify notifyall finalize toString getClass 除了clone和finalize其他均为公共方法。 11个方法,wait被重载了两次。

17、Java 中,抽象类与接口之间有什么不同?

Java 中,抽象类和接口有很多不同之处,但是最重要的一个是 Java 中限制一个类只能继承一个类,但是可以实现多个接口。抽象类可以很好的定义一个家族类的默认行为,而接口能更好的定义类型,有助于后面实现多态机制 参见第六条。

18、接口是什么? 为什么要使用接口而不是直接使用具体类?

接口用于定义 API。它定义了类必须得遵循的规则。同时,它提供了一种抽象,因为客户端只使用接口,这样可以有多重实现,如 List 接口,你可以使用可随机访问的 ArrayList,也可以使用方便插入和删除的 LinkedList。接口中不允许普通方法,以此来保证抽象,但是 Java 8 中你可以在接口声明静态方法和默认普通方法。

19、说出 5 个 JDK 1.8 引入的新特性?

Java 8 在 Java 历史上是一个开创新的版本,下面 JDK 8 中 5 个主要的特性: Lambda 表达式,允许像对象一样传递匿名函数 Stream API,充分利用现代多核 CPU,可以写出很简洁的代码 Date 与 Time API,最终,有一个稳定、简单的日期和时间库可供你使用 扩展方法,现在,接口中可以有静态、默认方法。 重复注解,现在你可以将相同的注解在同一类型上使用多次。
下述包含 Java 面试过程中关于 SOLID 的设计原则,OOP 基础,如类,对象,接口,继承,多态,封装,抽象以及更高级的一些概念,如组合、聚合及关联。也包含了 GOF 设计模式的问题。

20、Java 中,Serializable 与 Externalizable 的区别?

Serializable 接口是一个序列化 Java 类的接口,以便于它们可以在网络上传输或者可以将它们的状态保存在磁盘上,是 JVM 内嵌的默认序列化方式,成本高、脆弱而且不安全。Externalizable 允许你控制整个序列化过程,指定特定的二进制格式,增加安全机制。

21、静态内部类与顶级类有什么区别?

一个公共的顶级类的源文件名称与类名相同,而嵌套静态类没有这个要求。一个嵌套类位于顶级类内部,需要使用顶级类的名称来引用嵌套静态类,如 HashMap.Entry 是一个嵌套静态类,HashMap 是一个顶级类,Entry是一个嵌套静态类。

22、Java 中的编译期常量是什么? 使用它又什么风险?

变量也就是我们所说的编译期常量,这里的 public 可选的。实际上这些变量在编译时会被替换掉,因为编译器知道这些变量的值,并且知道这些变量在运行时不能改变。这种方式存在的一个问题是你使用了一个内部的或第三方库中的公有编译时常量,但是这个值后面被其他人改变了,但是你的客户端仍然在使用老的值,甚至你已经部署了一个新的jar。为了避免这种情况,当你在更新依赖 JAR 文件时,确保重新编译你的程序。

23、final、finalize 和 finally 的不同之处?

final 是一个修饰符,可以修饰变量、方法和类。如果 final 修饰变量,意味着该变量的值在初始化后不能被改变。
Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的,但是什么时候调用 finalize 没有保证。
finally 是一个关键字,与 try 和 catch 一起用于异常的处理。finally 块一定会被执行,无论在 try 块中是否有发生异常。

参考文档

Thinking in Java (Java 编程思想) Gitbook中文文档 https://java.quanke.name/ Thinking in Java (Java 编程思想) Github https://github.com/quanke/think-in-java Thinking in Java (Java 编程思想) Gitbook2 https://www.gitbook.com/book/wizardforcel/thinking-in-java/details

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值