最新Android高级面试知识点--Java基础
Posted 安静的Sunny
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最新Android高级面试知识点--Java基础相关的知识,希望对你有一定的参考价值。
2020年开年不利,大家都过得不容易。我们大家都辛苦了!
通过这次的疫情,使我更加直观也更进一步的理解了,何谓“命运共同体”。
如果你现在有工作,那么恭喜你。你要做的就是少点抱怨,更加努力的工作,把工作做好,多存点钱。
如果你正在找工作,那么我想说的是:不要急,选好自己心仪的行业,心仪的公司,好好准备面试,向它发起挑战。只要你真正努力了,真正问心无愧了,那么胜利终将属于你!!
转载请说明出处!
2020年android高级面试知识点干货分享系列,我将分为两大篇(Java基础篇、Android开发篇),多小节的形式进行连载(由于要对笔记进行排版整理)。这些完全都是我个人今年在找工作时的面试准备(知识点笔记),现在分享出来,希望能对你有一点点帮助(如果有些知识点我没有到位的,或者存在错误的,欢迎留言指正。我会持续更新)。
《Java篇》
一、== 与 equals()的区别
对于这两者的区别,想深刻理解的,得对Java类加载机制,JVM内存模型,汇编指令集等都有个了解。可以自己写个java测试类,利用javac编译成class文件,然后再利用javap -c xxx来对字节码进行反汇编,查看代码的执行过程。从而从根源上搞懂==与equals的区别。
$1.1、==
比较操作符,比较的是两个操作数变量的值是否相等。
- 当比较的是int 基本类型时,比较值;
- 当变量为引用类型时,比较的是引用类型变量的内存地址。
下面以引用类型为例看下==的执行过程:
public class Test
public static void main(String[] args)
String var1 = "Hello";
String var2 = "World";
boolean result = (var1 == var2);
System.out.println("result=" + result);
下面利用javap -c Test对其进行反汇编,结果信息如下:
Compiled from "Test.java"
public class ext.sunny.com.activitylifedemo.Test
//构造方法代码块执行
public ext.sunny.com.activitylifedemo.Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":
()V
4: return
public static void main(java.lang.String[]);
Code:
//ldc:指令,用于将int、float、String类型常量从常量池中压到栈顶
//这里指将字符串常量"Hello",压入栈顶
0: ldc #2 // String Hello
//astore_1:pop出栈顶的引用值,并且将它赋值给变量var1
2: astore_1
//ldc:将字符常量“World"从常量池中压到栈顶
3: ldc #3 // String World
//astroe_2:与上面一样,pop出栈顶的引用值,并且将它赋值给变量var2
5: astore_2
//aload指令:加载本地变量,并压入操作数栈
//aload_1:将var1变量的引用值压入操作数栈
//aload_2:将var2变量的引用值压入操作数栈
6: aload_1
7: aload_2
//if_acmpne:有条件转移指令。可以理解像java中的if条件语句
//如果两个对象引用不相等,则跳转
//iconst_0、iconst_1:表示将int类型常量0与1压入栈
8: if_acmpne 15
11: iconst_1
12: goto 16
15: iconst_0
//istore_3:将局部变量(这里指上面条件指令后的结果)存入3变量,即result中。
16: istore_3
下面就是System.out.print()打印输出的执行过程了。
17: getstatic #4 // Field java/lang/System.out:Ljava/
io/PrintStream;
20: new #5 // class java/lang/StringBuilder
23: dup
24: invokespecial #6 // Method java/lang/StringBuilder."<
init>":()V
27: ldc #7 // String result=
29: invokevirtual #8 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
32: iload_3
33: invokevirtual #9 // Method java/lang/StringBuilder.ap
pend:(Z)Ljava/lang/StringBuilder;
36: invokevirtual #10 // Method java/lang/StringBuilder.to
String:()Ljava/lang/String;
39: invokevirtual #11 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
42: return
$1.2、equals()
为Object类中的方法:
public boolean equals(Object obj)
return (this == obj);
注意点:
- equals()不能比较基本数据类型;
- 如果equals()比较的对象没有复写超类的equals()方法,则比较的是内存地址;
- 如果比较的对象有复写equals()方法,比如String,且有自己的比较规则,则按照自己的比较规则进行,比如String对象比较的是char字符值。
【扩展】:
在使用HashMap时,如果其Key你是用的引用对象,为了避免Hash冲突,此引用对象应该重写equals()方法,制定自己的比较规则。
二、String、StringBuffer与StringBuilder的区别
这里主要要理解Java的运行时数据区:
PC计数器、栈、本地方法栈、方法区(常量池属于里面的一块特殊内存空间)、堆
$2.1、String
分两种:字符串常量、对象
- String是字符串常量,则定义后其值存放在常量池,不可变(底层采用字符数组来存储,且是final,因此不可变);
- 如果是用new关键字生成出来的String对象则存放在堆中(只是将其引用值赋值给变量存入栈中)。
$2.2、StringBuffer
- 继承自AbstractStringBuilder
- 是线程安全的,因为里面的操作方法都用synchronized关键字(常用于多线程),同时效率不高
- 值可变。
$2.3、StringBuilder
- 继承自AbstractStringBuilder
- 非线程安全(无synchronized关键字)
- 值可变
- 效率比StringBuffer高,常用于单线程操作多个字符串。
备注:
我们在拼接字符串时,会习惯性的使用“+”,其实这个加号我们反汇编(可以参照上面的反汇编代码)可以发现,它里面就是new的StringBuilder对象来实现的。且它是每一行遇到+就会生成StringBuilder对象。因此在开发中,如果是很简单的拼接或者是测试可以用“+”,但其他情况(非多线程下),从效率以及内存上建议使用StringBuilder。
下一小节还是Java篇,我将分享以下面试笔记【Java集合】、【反射与泛型】、【JVM内存模型】
以上是关于最新Android高级面试知识点--Java基础的主要内容,如果未能解决你的问题,请参考以下文章
最新Android高级面试知识点--Activity启动流程
Android面试复习框架及题型解析,最新Android中高级面试题合集