面试官灵魂拷问:这些Java基础,为何总让候选人瞬间沉默?

61 阅读6分钟

大家好,我是徒手敲代码。

目前正值春招,相信不少小伙伴也在找工作或者实习,本人也是刚经历完秋招的严刑拷打,正在实习,想分享一些常见的java面试题,文章的内容都是自己手敲,希望用通俗易懂的语言,来破解每一道题目。

说说Object 类的常见方法

Object() 类的常用方法有 getClass()、toString()、hashCode()、equals()、notify()、notifyAll() 这几个。

1、getClass() 是用来获取一个对象的类,返回这个对象的类对象,getClass方法只能看这个对象直属的那个类,而如果要看这个对象的父类的话,就需要用到 getSuperClass() 方法;

2、toString() 默认返回 String 类型的类名加地址,对于一个自定义的类,如果想要用 toString 来表示它的属性和对应值的话,可以重写这个方法;

3、hashCode() 根据对象的内容或值,经过哈希函数运算之后,返回一个int类型的结果,一般来说,相同的两个对象,hashCode 一定相等,但是 hashCode 相等的两个对象,不一定相同,所以如果要判断两个对象的各个属性值是否完全一样,还需要用到 equals() 方法,hashCode 相比于 equals,底层不需要其它复杂的操作,速度较快;

4、equals() 用来判断两个对象是否相同。对于自定义的对象,一般要同时重写equals() 和 hashCode() 方法,来保证 hashMap、HashSet 等集合,在判断冲突的时候,不至于出错;

5、notify()notifyAll() 用于唤醒等待某个资源的线程。notify 是随机唤醒一个线程,而 notifyAll 是唤醒所有线程。这两个方法都只能在同步方法或同步代码块中使用。一般建议使用 notifyAll,因为使用 notify 可能导致某些线程永远不会被唤醒,而导致无意义的等待。例如:两个资源A B,线程1占用了A,线程2占用了B,此时有个线程3申请使用A,线程4申请使用B,因为线程1 2还没释放A B的锁,线程3 4只能进入等待队列进行等待。在某个时刻,线程1释放了A,如果使用notify,那么可能恰好唤醒了线程4,而线程4不是想要资源A,所以会继续等待,而想要获取资源A的线程3却没有被唤醒,导致一直在做无意义的等待。

Java 的平台无关性,你了解吗

同一套代码,在不同操作系统上运行,不需要对源代码做任何修改,即可顺利运行,这就叫做平台无关性。java 之所以可以实现平台无关性,依靠的是 JVM 和字节码(Class文件)。java编译器首先把 .java 文件编译打包成字节码,然后启动JVM,由JVM在不同平台上运行这些字节码,所以 java 代码的运行是不用直接跟操作系统交互的,而是通过 JVM 作为中间层,来屏蔽平台的差异,所以 java 程序员只需要专注于 java 程序的开发逻辑即可,而不需要过多的关注平台的细节。当然,这并不意味着 java 程序完全与平台无关,还是要注意一些可能导致问题的因素,例如:文件路径、编码格式、系统属性等。

== 和 equals() 有什么区别

equals() 是一个Object类的常用方法,用于引用类型的比较,默认实现是比较两个对象的内存地址,但是很多类都重写了 equals 方法,使得比较的是对象的属性和对应的值,例如String Integer等类,比较是否相等时,都应该用 equals();而==多用在基本数据类型的比较,比如 int char 等,可以直接比较它们的值是否相等。

equals() 与hashcode(),什么时候重写,为什么重写,怎么重写

默认情况下,equals() 比较的是两个对象的内存地址是否相同,而 hashCode() 是将对象的内容或值,经过哈希函数运算之后,返回一个int类型的结果。这两个方法都用于两个对象之间的比较。对于 HashMap HashSet 等集合来说,比较两个对象的大致流程是,先计算出两个对象的 hashCode,如果 hashCode 不相等,说明这两个对象不相同;如果 hashCode 相等,就用 equals 方法再进行比较,判断这两个对象是否相同。

一般来说,对于自定义的类(除了没有任何业务处理的情况,比如一些只用于接口返回的对象),都需要对 equals 和 hashCode 这两个方法进行重写,保证集合在处理这些类的对象时,能够正确地存储和查找对象。

重写这两个方法,使用 Lombok 的注解 @Data,是比较简单的方式,学校作业可以这么玩。不过实际开发中,应该根据具体的场景来决定,两个对象相同的情况,比如:两个电脑对象,只要名字和价格一样,就算是两台一模一样的电脑吗?万一CPU 和显卡型号不一样呢?

对于 equals() 方法,传进来一个 Object 类型的对象,如果这个对象为空,或者跟当前对象不是属于同一个类,直接返回 false。再把传进来的对象,本来 Object 类型,强转为当前对象的类型,比较这两个对象的各个属性是否相等。

对于 hashCode() 方法,直接调用 Objects 类的 hash() 方法,把这个类的所有属性传进去。

重载和重写有什么区别

重载是一个类中,方法名一样,但是要求参数列表和返回类型都不一样的方法。重载的方法可以有不同的异常抛出、访问修饰符;

重写是在子类中,定义了跟父类的方法名一样,参数列表也一样的方法。

两者都能体现出 java 多态的特性,重载体现了编译时多态,而重写体现了运行时多态。从 JVM 的角度看,重载是静态绑定,意思是在编译阶段,就决定了调用哪个方法。而重写是动态绑定,意思是运行时根据对象的实际类型,来决定调用哪个方法。


点击下方“关注”,让我们在技术的星辰大海、生活的诗与远方中共勉同行,一起书写属于我们的精彩篇章!

欢迎关注微信公众号“徒手敲代码”,发现更多精彩内容!