大部分开发者进入公司,一个必备的环节就是面试,只有经过面试,才能知道求职者是否符合公司的要求,也只有经过面试,求职者才能有幸进入到企业里工做,那么怎么才能提升面试的成功率呢?对于开发者而言,显然是技术的掌握水平,因为技术的面很是广,咱们并不可能所有的都掌握,可是,多多少少咱们都有所了解,准备的越充足,意味着成功率也能大大的提升。java
对于Android的面试,咱们能够发现,要求的是愈来愈多,愈来愈严苛,面试如同造航母,已经远不如14年15年那么好找了,对于一些点,不只仅要会用,一些原理源码性的东西,也必须得去研究掌握。面试
接下来的几篇文章,主要罗列一下Android面试中常见的点,但愿能够帮助到你们,这一篇主要针对java中常见的点。安全
equals的做用是判断两个对象是否相等。多线程
经过判断两个对象的地址是否相同来判断。app
==通常用于基本类型数据的比较,判断两个值是否相同函数
也能够用于类的比较,一样也是比较两个对象的内存地址。(就是两个对象都是同一个对象)ui
因此在equals没覆盖的状况下,==和equals是等价的。spa
( 咱们能够经过覆盖equals来让相同内容的对象来返回true。)线程
可以高效率的产生一个离散的int值。指针
经过hashCode()来计算出两个对象的hash值而后进行比较。
可是会出现不一样的类也会有相同hash值,因此这不是安全、不可靠的。
####总结
总的来讲就是通常状况equals和==是等价的。
若是两个对象相等,则他们必定是equals返回true。
若是两个对象的hashCode相同,也不能 100%保证它们是相同的。
1 Integer是int的包装类,int则是Java的一种基本数据类型
2 Integer变量必须实例化以后才可使用,而int变量不须要
3 Integer实际是对象的引用,当new一个Integer时,其实是生成一个指针指向此对象;而int则是直接存储数据值
4 Integer的默认值是null,int的默认值是0
打个比方 父亲person有行为这个方法,里面包括几个动做:吃饭,睡觉,走路 父亲有三个儿子,三个儿子都继承了父亲的行为方法,因此三个儿子都有吃饭,睡觉,走路这些动做,可是三个儿子又分别有本身的动做--大儿子A会弹吉他,二儿子B会唱歌,三儿子C会打鼓 ...
1.Person person = new A(); 不是父类对象指向子类引用而是父类引用指向子类对象
2.这个对象不能调用子类A特有的弹吉他方法--person.guitar(); X
3.若是仅是这么写程序,还不是多态,记住实现多态的三要素:继承 重写 父类引用指向子类对象
4.以后,若是你调用persion.guitar(),此时在代码的编译阶段,persion调用的仍然是本身的guitar(),不是儿子的。而当程序运行时,就是java XXX, persion调用的倒是儿子的guitar()。这个动态的过程才是多态 。
Person person;
//父类的引用指向子类的方法;
person = new Student();
//person类型引用作一个判断
//(1)if(person.eat().size==2 )
{
if(person instanceof Person)
{
person.eat();
}else if(person instanceof Student) {
Student stu = (Student)person;
stu.eat();
}
person.eat();//从代码角度看,此时是父类的引用调用的是父类中的eat方法
//(2)子类若覆盖了父类的方法,eat动态绑定到父类的引用Person上,换个名字叫动态绑定
//父类的引用能够调用子类的方法,咱们把这一现象成为多态
//从字面意思来理解person这个父类的引用一会是person一会是student
//person有多种状态;
//也叫方法的动态绑定
//继承是通向多态的入口
person.f2();
person.gotobed();
person.eat();
Student stu = new Student();
stu.eat();
stu.gotobed();
//父类的引用可以调用子类的方法
}
Java中,父类的引用既能够指向父类的对象,也能够指向子类的对象。但子类的引用不能指向父类的对象。
引用类型也能够进行类型转换。
但转换的类型必定具备继承关系,即仅容许父子类之间进行转换。
若是尝试将毫无关联的两个类型进行转换,将会引起编译错误。可使用instanceof来判断引用是否为指定的类型。
咱们先对比下String, StringBuffer, StringBuilder这三个类。他们的主要区别通常体如今线程安全和执行效率上。
String类是用final修饰符修饰的,它的值是不可修改的,所以是线程安全的。 若是一个StringBuffer对象在缓冲区被多个线程使用时,由于StringBuffer的方法都是带有synchronized关键字的,因此能够保证线程安全,而StringBuilder的方法没有该关键字,不能保证线程安全,所以可能会出现一些操做错误。多线程状况下建议使用StringBuffer,单线程建议使用速度较快的StringBuilder。
先看一段代码:
String str = "abcdef";
str = str + "123456";
System.out.println(str);
这段代码输出的结果是: “abcdef123456”, 看着好像是str被改变了,但实际上这是一种假象,JVM对上述代码是这样处理的。 1.执行第一行代码:新建一个String对象“abcdef”(该对象保存在字符串常量池中)将“abcdef”对象的实例引用赋值给str(保存在栈中)。 2.执行第二行代码: 再新建一个String对象str,用来执行str + "123456"操做,也就是说,str这个对象是没有发生改变的(String不可变)。每当用String操做字符串时,其实是在不断的建立新的对象,而原来的对象就会变为垃圾被GC回收掉,可想而知这样执行效率会有多低。 一个特殊例子:
String str = "This is a" + "special" + "example";
StringBuilder stringBuilder = new StringBuilder("This is a").append("special").append("example");
你会发现生成str对象的速度简直太快了,而这个时候StringBuilder速度上根本一点都不占优点。 其实这是JVM的一个把戏,实际上:String str = "This is a" + "special" + "example";其实就是: String str = “This is a special example”;因此不须要太多的时间了。 要注意的是,若是你的字符串是来自另外的String对象的话,速度就没那么快了,譬如:
String str2 = "This is a";
String str3 = "special";
String str4 = "test";
String str = str2 +str3 + str4;
这时候JVM会规规矩矩的按照原来的方式去作。
1.若是要操做少许的数据用 --> String 2.单线程操做字符串缓冲区 下操做大量数据 --> StringBuilder 3.多线程操做字符串缓冲区 下操做大量数据 --> StringBuffer
将一个类定义在另外一个类里面或者一个方法里面,这样的类称为内部类。
成员内部类能够无条件访问外部类的全部成员属性和成员方法(包括private成员和静态成员)。
当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认状况下访问的是成员内部类的成员。
局部内部类是定义在一个方法或者一个做用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该做用域内。
匿名内部类就是没有名字的内部类
指被声明为static的内部类,他能够不依赖内部类而实例,而一般的内部类须要实例化外部类,从而实例化。静态内部类不能够有与外部类有相同的类名。不能访问外部类的普通成员变量,可是能够访问静态成员变量和静态方法(包括私有类型)
一个 静态内部类去掉static 就是成员内部类,他能够自由的引用外部类的属性和方法,不管是静态仍是非静态。可是不能够有静态属性和方法、
1.每一个内部类都能独立的继承一个接口的实现,因此不管外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整,
2.方便将存在必定逻辑关系的类组织在一块儿,又能够对外界隐藏。
3.方便编写事件驱动程序
4.方便编写线程代码
抽象类不能建立实例,它只能做为父类被继承。抽象类是从多个具体类中抽象出来的父类,它具备更高层次的抽象。从多个具备相同特征的类中抽象出一个抽象类,以这个抽象类做为其子类的模板,从而避免了子类的随意性。
(1) 抽象方法只做声明,而不包含实现,能够当作是没有实现体的虚方法
(2) 抽象类不能被实例化
(3) 抽象类能够但不是必须有抽象属性和抽象方法,可是一旦有了抽象方法,就必定要把这个类声明为抽象类
(4) 具体派生类必须覆盖基类的抽象方法
(5) 抽象派生类能够覆盖基类的抽象方法,也能够不覆盖。若是不覆盖,则其具体派生类必须覆盖它们
(1) 接口不能被实例化
(2) 接口只能包含方法声明
(3) 接口的成员包括方法、属性、索引器、事件
(4) 接口中不能包含常量、字段(域)、构造函数、析构函数、静态成员
(1)抽象类能够有构造方法,接口中不能有构造方法。
(2)抽象类中能够有普通成员变量,接口中没有普通成员变量
(3)抽象类中能够包含静态方法,接口中不能包含静态方法
(4) 一个类能够实现多个接口,但只能继承一个抽象类。
(5)接口能够被多重实现,抽象类只能被单一继承
(6)若是抽象类实现接口,则能够把接口中方法映射到抽象类中做为抽象方法而没必要实现,而在抽象类的子类中实现接口中方法
(1) 均可以被继承
(2) 都不能被实例化
(3) 均可以包含方法声明
(4) 派生类必须实现未实现的方法