equals方法用过吧?看看这道题,说说看equals方法在前和在后有什么区别?
没什么区别。java
错,初学者或者代码打得少的人都会犯这个错。程序员
test1会直接报空指针异常,你想一想看,null.equals看不起来不就怪怪的吗?空指针怎么可能有方法呢是吧,面试
拓展:咱们通常在企业开发中都会将已知的字面量放在equals,未知的参数放在equals后面,这样能够避免空指针,编程新手容易犯这个异常,我review过的代码这么实现的,说实话,挺屡次的,不止编程新人,两三年工做经验的都会这么作,实在不该该,算法
说说看equlas 跟 == 的区别
equals方法比较的是字符串的内容是否相等,而 == 比较的则是对象地址。数据库
这么回答也是对的,可是,咱们更但愿听到更专业的回答,好比:编程
首先Java中的数据类型能够分为两种,一种是基本数据类型,也称原始数据类型,如byte,short,char,int,long,float,double,boolean 他们之间的比较,应用双等号(==),比较的是他们的值。后端
另外一种是复合数据类型,包括类,当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,因此,除非 是同一个new出来的对象,他们的比较后的结果为true,不然比较后结果为false。设计模式
而JAVA当中全部的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而再也不是比较类在堆内存中的存放地址了。api
这么回答显的既专业又牛逼,还大气上档次,你学废了吗?服务器
聊聊对hashCode和equals方法的理解
通常问到这种问题,候选人均可以回答:
若是两个对象equals方法相等,则它们的hashCode必定相同;
若是两个对象的hashCode相同,它们的equals()方法则不必定相等。
而两个对象的hashCode()返回值相等不能判断这两个对象是相等的,但两个对象的hashcode()返回值不相等则能够断定两个对象必定不相等。
考察对hashCode的理解 那请问hashCode有什么做用呢?为何要这么规范
基本上初学者或者应届生在这一步就被我卡主了, 支支吾吾的回答不了多少,基本上都在这里掉分,由于上面的规范回答百度一查一大把,可是对hashCode做用有深刻了解的却不多,这道题也能够看出一我的的专业水平。
正确的回答是:
hashCode的做用其实是为了提升在散列结构存储中查找的效率,天然只有每一个对象的hashCode尽量的不一样才能保证散列存储性能的提升,这也是为何Object默认提供hash码都是不一样的缘由。
举个例子:
以HashSet为例,要想保证元素不重复则须要调用对象的equals方法比较一次,可是若是这个结构放了不少元素,好比5000次,若是没有hashCode的话则须要在每次加元素的时候对比5000次,而若是有hashCode则不同了,当集合要添加新的元素的时候先调用hashCode方法,这样即可以定位到元素的地址,而无需屡次判断。
考察对clone方法的理解看看这道题,结果输出什么?
每次问到这道题,大部分人都是回答2,小部分人是回答1。
都错,正确答案是直接报错
为何?由于clone方法是Object的protect方法,须要子类显示的去重写clone方法,而且实现Cloneable 接口,这是规定。
那么问题来了?加上Cloneable 接口后呢?究竟是2仍是1呢?
这又是我挖的坑,主要为了考察候选人对浅拷贝和深拷贝的理解
最终结果实际上是2,由于直接用clone拷贝的时候是一种浅拷贝,最终拷贝对象和原始对象的引用类型引用仍是同一个对象。
若是想要实现深拷贝,则须要开发人员本身在clone方法内本身进行重写。
拓展:在企业开发中通常咱们不容许直接用clone方法来作拷贝,存在抛出异常的风险,还须要进行类型转换。若是是我review到这种代码,都是直接告诉同事:在Effective Java 书上有讲到,最好不要去使用 clone(),咱们可使用拷贝构造函数或者拷贝工厂来拷贝一个对象,好比这样
总结:咱们都知道Java是面向对象编程的,个人理解实际上就是面对Object编程,可以合理的使用和了解原理equals和hashCode是一个初级程序员必须具有的素养,而对浅拷贝和深拷贝的理解也基本是基础中的基础,但愿看完这系列,你们能够了然于胸,下次碰见这种面试题,直接吹。
考察候选人编码水平 说说看你对抽象类的理解
抽象类和抽象方法都使用 abstract 关键字进行声明,若是一个类中包含抽象方法,那么这个类必须声明为抽象类,而且抽象类和普通类最大的区别是,抽象类不能被实例化,只能被继承。
bingo,答案是对的,可是还不够好
上面的是标准答案,随便一本Java书籍均可以看到,可是能够补充下大家对应用的理解,这能够体现你的编码水平到了哪一步,我这边补充我理想的答案:
抽象类能够实现代码的重用,模板方法设计模式是抽象类的一个典型应用,例如咱们游戏的全部活动都要进行同样的初始化,可是初始化的时候须要根据不一样活动进行不一样功能开启判断,那么就能够定义一个活动的基类,将功能开启判断作成一个抽象方法,让全部活动都继承这个基类,而后在子类自行重写功能开启判断。
补充上本身对应用的理解,能够充分体现你的专业,面试官听完,确定是心里一顿尼玛的牛逼。
继续考察候选人编码水平说说看你对接口的理解
接口能够说成是抽象类的一种延伸,接口中的全部方法都必须是抽象的。实际上,接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
大家懂的,这又是一个标准回答,实际上,不够好,能够补充如下几句话
从Java8开始,接口也能够拥有默认的方法实现了,为啥Java团队要作这个支持呢?
实际上,在Java上深耕多年的老司机其实都被接口没有默认实现搞过,维护成本过高了,你想一想,若是你如今有100个类实现了一个接口,而在这个时候,须要给接口新增一个方法,特么Java8以前不容许给接口加默认实现,因此你就得改100个类,这特么不得搞出人命吗?
真心话:可以说出对抽象类和接口应用的理解的候选人很少,基本上说出来的我心里都是往牛逼去吹的,大写的服,由于这充分体现一个开发人员对编码方面的思考,你不知道一个写代码有思考和整洁,而不是只顾实现功能的程序员,主管会多喜欢!!!
真正的直接背的答案说说看抽象类和接口的区别
这个就是标准答案了,不过咱们面试官比较但愿能够在回答区别题的时候本身作些拓展回答,将上面接口和抽象类的理解都说一遍,而不是背书同样的回答,切记,回答问题,碰见本身懂的知识点,尽可能作拓展,加上本身的理解,一是能够向面试官展现你的专业,二是能够拖时间,尽可能避免让面试官想更多难题坑你
总结:看到这里,估计不少人对抽象类和接口都嗤之以鼻,都是随口能够说出的答案,可是,你觉得咱们只是想要听你背书式的回答吗,错了,咱们想知道的是后面你的拓展和理解,这才能够体现你的编码能力和专业。
给你们来一个笔试中超级常见的题 看看如下这道题,说说看结果是啥?
这道题简直就是了,不少年前我来我司应聘的时候也碰见过这道题,说实话,应届生和初级绕不过这道题,如今直接给你们亮牌:
给你们说说如何理解这种题,理解如下的原则就能够了:
JVM在调用一个方法时,会优先从本类中查找看是否有对应的方法,若是没有再到父类中查看是否从父类继承来。
若是没有怎么办?那JVM就会对参数进行转型,转成父类以后看是否有对应的方法。
总的来讲,方法调用的优先级以下:
记住这个过程就能够了。
开始挖坑 说说看如下的是否是方法重载?
class TestMain {
public int show(int x) {
return x;
}
public void show(int x) {
System.out.println(x);
}
}
我面试过的大部分初级或者应届都会回答是,不得不说这道题实在太坑了,不开玩笑,你看那堆被这道题埋过的人里边就有我。
千万记住了,重载的定义是:在同一个类中,一个方法与已经存在的方法名称上相同,而且参数类型、个数、顺序至少有一个不一样。这句话里边并无包含着返回值,若是只是返回值不一样,其它都相同根本不算是重载。
固然,idea是会直接提示报错的,这也是为何我没有截idea的源码出来给你们看的缘由,一看有爆红大家就知道有问题了。不过仍是那句话,这并不意味着idea能够检测出来的东西,你就能够不懂,这是基础。
总结:说实话,在笔试题中出现重载和重写那两道题实在是太常见了,百分之九十的应届生或者初级开发都被坑过,因此看完这篇文章记得收藏啊,并非你看了就记住了,而是记得在面试前从新看一遍,这但是关系到你offer上那个金光闪闪的数字的上限的啊
终于到了反射了,咱们面试官其实很喜欢这个知识点,能够用它来筛掉一大批的api工程师
了解过反射吗?说说看什么是反射?
在运行时,Java 反射,能够获取任意类的名称、package 信息、全部属性、方法、注解、类型、类加载器、现实接口等,而且能够调用任意方法和实例化任意一个类的独享,经过反射咱们能够实现动态装配,下降代码的耦合度、实现动态代理等,不过反射的过分使用会严重消耗系统资源。
上面的回答很标准,不过开始深挖了 你刚刚的回答有提到了反射的做用,说说哪里用到了反射机制?
例子不少,好比:
基本上回答几个就能够了,这里由于还没到框架模块,因此先不对Spring、JDBC等源码进行深挖,通常都是基础题面完了,才开始挖对框架的使用和源码的理解。
继续挖,咱们面试官很喜欢抓细节,因此最好保证你说的东西你都有必定的了解,不然嘿嘿嘿你刚刚还说到了动态代理,说说你对动态代理的理解,以及有什么用
动态代理其实就是是运行时动态生成代理类。 动态代理的应用有 Spring AOP、测试框架的后端 mock、rpc,Java注解对象获取等应用。
怎么实现动态代理呢?
目前动态代理能够提供两种,分为JDK 原生动态代理和 CGLIB动态代理;
JDK 原生动态代理是基于接口实现的,而 CGLIB是基于继承当前类的子类实现的,当目标类有接口的时候才会使用JDK动态代理,实际上是由于JDK动态代理没法代理一个没有接口的类,由于JDK动态代理是利用反射机制生成一个实现代理接口的匿名类;
而CGLIB是针对类实现代理,主要是对指定的类生成一个子类,而且覆盖其中的方法。
挖一个大坑 你上面有说到 Spring AOP有用到了动态代理,那你说说看AOP用到了哪一种方式?
大部分都会回答JDK 原生动态代理,小部分人会回答CGLIB。
但其实二者都是错的,这是我挖好的坑,太多候选人都只知道AOP用了动态代理了,可是可以完整回答出来用了哪一种的却寥寥无几,毕竟只有看过源码的人才能回答这个问题,通常可以回答出来的,我这边都会额外加分
实际答案是:在Spring中默认使用的是JDK动态代理,除非目标类没有实现接口,才会转为CGLIB代理,若是想要强行使用CGLIB代理免责须要在Spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true" />
,
然而在SpringBoot中,从2.0开始就默认使用CGLIB代理。**
说说看反射机制的优缺点
优势:能够动态执行,在运行期间根据业务功能动态执行方法、访问属性,最大限度发挥了java的灵活性。 缺点:对性能有影响,这类操做老是慢于直接执行java代码。
对性能有影响,那请问怎么解决这个问题?
到了这里基本上不少候选人都没法回答了,我见过太多一开始就说性能性能的,但是一说到如何解决,就基本支支吾吾的回答不出来。
记住了,若是聊到性能,记得想好怎么回答优化方面的问题,不然就是本身搬起石头砸本身的脚。
实际上能够从如下几个方面回答:
总结:这里其实建议你们多去玩玩反射,不要只会api调用,对于咱们面试官而言,熟悉和理解反射是一个中级程序员必备的条件。
作为一个Javer,应该对Error 和 Exception很熟悉吧,说说看它们的区别
目前来讲,能够做为异常抛出的类,分为两种: Error 和 Exception。
而其中 Error 用来表示 JVM 没法处理的错误,而后Exception 也分为两种,分别是:
说说看什么是注解?以及有什么用
注解提供了一种相似注释的机制,用来将任何的信息或数据与类、方法、或者成员变量等进行关联。
Annontation像一种修饰符同样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。
注解的用处不少,举两个最多见的例子:
Java.lang.annotation 提供了四种元注解,是哪四种?有什么用呢?
JAVA 中有如下几个『元注解』:
没错,这几个元注解太常见了,可是却不多人可以真的用的好。
说说看@Target做用目标有哪些?
关于@Target的做用目标有多个目标类型,直接截图以下:
基本上回答几个就能够了,不过记住了,上面的TYPE就是指的是类,也就是说这个注解是做用在类上的。
@Retention注解的生命周期有哪几种?有什么区别?
@Retention注解的生命周期能够分为如下几种:
区别在于:
第一种是只能在编译期可见,编译后会被丢弃;
第二种会被编译器编译进 class 文件中,不管是类或是方法,乃至字段,他们都是有属性表的,而 JAVA 虚拟机也定义了几种注解属性表用于存储注解信息,可是这种可见性不能带到方法区,类加载时会予以丢弃;
第三种则是永久存在的可见性,能够反射获取,基本上用这种居多。
对于注解生命周器的理解能够避免一些坑,仍是那句话,基本上注解这块能回答的比较流畅的,说明都是玩过组件或者看过源码的,由于对于开发一个组件来讲,注解太经常使用了。
送命题,百分之九十的候选人答不上来 父类使用了注解,请问子类继承了这个父类后,是否也携带了这个注解呢?若是没有,要怎么实现这个过程?
这道题不多人会回答的上来,毕竟你们对@Inherited这个元注解太陌生了。
在注解上使用元注解@Inherited,表示该注解会被子类所继承,注意注意,仅针对类哟,成员、方法并不受该元注解的影响
所以,若是想要让子类也继承父类的注解,则须要给注解加上元注解@Inherited。
拓展:通常初级开发都基本不会用上注解,由于注解更多的是用来写组件用的,咱们项目组这边就很喜欢自定义一些注解来实现组件,由于用起来实在是太舒服了。
总结:关于异常这块,Error 和 Exception是常常会被问到的基础考点,而注解这块是一个可以加分的点,但愿你们别错过这个知识点,学透它,不过记住上面几个坑点,其实也差很少了。
上一篇文章:https://mp.weixin.qq.com/s/F73r_f5YcBOayPdsin4gBg 点赞和阅读量都很高,说明文章质量是ok的,感谢你们的支持;
Java基础系列也基本差很少了,说实话,这两篇文章的坑点,只要你记住了,Java基础这块基本上没问题了。
后续安排:
有兴趣的关注我一波,Java面试官带大家跨过一个个的面试坑,保证不亏。
为了感谢最近你们的支持,我这边特意跳了一些Java相关的资源,不少专题,好比JAVA+TCP、Java反射机制、Java多线程专题等,都是针对性训练的利器,建议人手一份。
给文章点个再看,关注公众号,回复:Java面试 便可拿到资源。
公众号:饭谈编程 原文连接:https://mp.weixin.qq.com/s/F73r_f5YcBOayPdsin4gBg
谢谢点赞支持👍👍👍!