太过伤心,小王被这 10 道 Java 面试题虐哭了

小王写了一本《茶花女》

老王在读《哈姆雷特》

在父类的构造方法中,分别调用了 write()read() 方法,write()

方法是 public 的,可以被重写,因此执行了子类的 write() 方法,read() 方法是私有的,无法被重写,因此执行的仍然是父类的 read() 方法。

和私有方法类似,静态方法在编译期也是通过静态绑定的方式绑定的,不依赖于特定引用变量所持有的对象类型。方法重写适用于动态绑定,因此静态方法无法被重写。

public class StaticOrrideTest {

public static void main(String[] args) {

Laozi zi = new Xiaozi();

zi.write();

}

}

class Laozi{

public static void write() {

System.out.println(“老子写了一本《基督山伯爵》”);

}

}

class Xiaozi extends Laozi {

public static void write() {

System.out.println(“小子写了一本《茶花女》”);

}

}

程序输出结果如下所示:

老子写了一本《基督山伯爵》

引用变量 zi 的类型为 Laozi,所以 zi.write() 执行的是父类中的 write() 方法。

静态方法也叫类方法,直接通过类名就可以调用,通过对象调用的时候,IDE 会发出警告。

第四题,1.0/0.0 得到的结果是什么?会抛出异常吗,还是会出现编译错误?

小王之所以没答对这道题,是因为他没有深入研究过 double 类型和 int 类型的除法运算。

数字在 Java 中可以分为两种,一种是整形,一种是浮点型。不太清楚的小伙伴先去研究一下数据类型

当浮点数除以 0 的时候,结果为 Infinity 或者 NaN。

System.out.println(1.0 / 0.0); // Infinity

System.out.println(0.0 / 0.0); // NaN

Infinity 的中文意思是无穷大,NaN 的中文意思是这不是一个数字(Not a Number)。

当整数除以 0 的时候(10 / 0),会抛出异常:

Exception in thread “main” java.lang.ArithmeticException: / by zero

at com.itwanger.eleven.ArithmeticOperator.main(ArithmeticOperator.java:32)

通常,我们在进行整数的除法运算时,需要先判断除数是否为 0,以免程序抛出异常。

第五题,Java 支持多重继承吗?

小王之所以没答对这道题,是因为他知道,通过接口可以达到多重继承的目的。

来定义两个接口,Fly 会飞,Run 会跑。

public interface Fly {

void fly();

}

public interface Run {

void run();

}

然后让一个类同时实现这两个接口。

public class Pig implements Fly,Run{

@Override

public void fly() {

System.out.println(“会飞的猪”);

}

@Override

public void run() {

System.out.println(“会跑的猪”);

}

}

但说到多重继承,讨论的关键字是 extends,而非 implements。

Java 只支持单一继承,是因为涉及到菱形问题。如果有两个类共同继承一个有特定方法的父类,那么该方法可能会被两个子类重写。然后,如果你决定同时继承这两个子类,那么在你调用该重写方法时,编译器不能识别你要调用哪个子类的方法。

类 C 同时继承了类 A 和类 B,类 C 的对象在调用类 A 和类 B 中重写的方法时,就不知道该调用类 A 的方法,还是类 B 的方法。

第六题,当在 HashMap 中放入一个已经存在的 key 时,会发生什么?

小王之所以没答对这道题,是因为他没有深入研究过 HashMap 的工作原理。

Hash,一般译作“散列”,也有直接音译为“哈希”的,这玩意什么意思呢?就是把任意长度的数据通过一种算法映射到固定长度的域上(散列值)。

再直观一点,就是对一串数据 wang 进行杂糅,输出另外一段固定长度的数据 er——作为数据 wang 的特征。我们通常用一串指纹来映射某一个人,别小瞧手指头那么大点的指纹,在你所处的范围内很难找出第二个和你相同的(人的散列算法也好厉害,有没有)。

对于任意两个不同的数据块,其散列值相同的可能性极小,也就是说,对于一个给定的数据块,找到和它散列值相同的数据块极为困难。再者,对于一个数据块,哪怕只改动它的一个比特位,其散列值的改动也会非常的大——这正是 Hash 存在的价值!

大家应该知道,HashMap 的底层数据结构是一个数组,通过 hash() 方法来确定下标。

static final int hash(Object key) {

int h;

return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);

}

当我们放入一个键值对的时候,会先调用 hash() 方法对 key 进行哈希算法,如果 key 是相同的,那么哈希后的结果也是相同的,意味着数组中的下标是相同的,新放入的值就会覆盖原来的值。

第七题,下面这段代码将会打印出什么?

public class Test {

public static void main(String[] args) {

char[] chars = new char[]{‘\u0097’};

String str = new String(chars);

byte[] bytes = str.getBytes();

System.out.println(Arrays.toString(bytes));

}

}

小王之所以没答对这道题,是因为他没有深入研究过字符编码方面的一些知识。

在这段程序中,我们通过一个字符数组创建了一个字符串对象,然后调用 String 类的 getByte() 方法得到字节数组并将其打印到控制台。

这道面试题考察的核心并不是最终的打印结果(结果是不确定的),而是字符编码。通常情况下,我们在调用 getBytes() 方法时,要指定编码,比如说 str.getBytes(StandardCharsets.UTF_8)

当我们没有指定编码的时候,JDK 会调用平台默认的字符编码,而不同的操作系统,编码不尽相同的,bytes 的结果也就会不同。

当使用 UTF_8 时,结果为 -62, -105,当使用 GB2312 时,结果为 63

第八题,当方法在父类中抛出 NullPointerException 时,是否可以使用抛出 RuntimeException 的方法来重写它?

小王之所以没答对这道题,是因为他被重写(overriding)和重载(overloading)的概念搞混了。

方法重写和方法重载时,方法名可以完全相同,但根本的不同在于方法重写时发生在运行时,方法重载时发生在编译时。

另外,方法重写和方法重载时的规则也不尽相同。在 Java 中,不能重写 private、static 和 final 方法,但可以重载它们。

我们来重点看一下方法重写时的规则:

1)方法签名必须相同,包括返回类型、参数的数量、参数的类型和参数的顺序。

2)重写后的方法不能抛出比父类中更高级别的异常。举例来说,如果父类中的方法抛出的是 IOException,那么子类中重写的方法不能抛出 Exception,可以是 IOException 的子类或者不抛出任何异常。这条规则只适用于可检查的异常。

可检查(checked)异常必须在源代码中显式地进行捕获处理,不检查(unchecked)异常就是所谓的运行时异常,比如说 NullPointerException、ArrayIndexOutOfBoundsException 之类的,不会在编译器强制要求。

3)重写后的方法访问权限不能比父类中的方法低,比如说父类中的方法是 public,重写后的方法就不能是 protected。

public class ExceptionDemo {

public static void main(String[] args) {

Super s = new Child();

s.write();

}

}

class Super{

public void write() throws NullPointerException { }

}

class Child extends Super {

@Override

public void write() throws RuntimeException { }

}

RuntimeException 和 NullPointerException 属于不检查异常,所以本题的答案是可以的。如果是可检查异常的话,IDE 就会发出警告。

第九题,下面这段代码使用了 compareTo() 方法,有问题吗?

class Employee implements Comparable {

private int id;

@Override

public int compareTo(Object o) {

Employee emp = (Employee) o;

return this.id - emp.id;

}

}

小王之所以没答对这道题,是因为他想当然地认为 id 的都是正整数。

当我们需要按照一定的规则进行排序的时候,通常要实现 Comparable 接口,并实现 compareTo 方法,规则如下:

1)如果当前对象小于另外一个对象,则 compareTo 方法必须返回负数;如果当前对象大于另外一个对象,则必须返回正数;如果两个对象相等,则返回零。

2)通常来说,compareTo 方法必须和 equals 方法一致,如果两个对象通过 equals 方法判断的结果为 true,那么 compareTo 必须返回零。

不过,JDK 中有一个反例,就是 BigDecimal。

BigDecimal bd1 = new BigDecimal(“2.0”);

BigDecimal bd2 = new BigDecimal(“2.00”);

System.out.println("equals: " + bd1.equals(bd2));

System.out.println("compareTo: " + bd1.compareTo(bd2));

输出结果如下所示:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

由于细节内容实在太多了,为了不影响文章的观赏性,只截出了一部分知识点大致的介绍一下,每个小节点里面都有更细化的内容!

小编准备了一份Java进阶学习路线图(Xmind)以及来年金三银四必备的一份《Java面试必备指南》

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
你有帮助,可以扫码获取!!(备注Java获取)**

img

最后

由于细节内容实在太多了,为了不影响文章的观赏性,只截出了一部分知识点大致的介绍一下,每个小节点里面都有更细化的内容!

[外链图片转存中…(img-j9gFDBGx-1712906192335)]

小编准备了一份Java进阶学习路线图(Xmind)以及来年金三银四必备的一份《Java面试必备指南》

[外链图片转存中…(img-CFAcPYO0-1712906192335)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值