1.public、private、protected、默认(default也称friendly)
public: 公有变量,可供全局调用
protected: 可供本类,子类,同包下的其他类调用
default: 它是针对本包访问而设计的,任何处于本包下的类、接口、异常等,都可以相互访问,即使是父类没有用protected修饰的成员也可以
private: 只为本类提供
当前类 | 当前包 | 子类 | 外部包 | |
---|---|---|---|---|
public | ✔️ | ✔️ | ✔️ | ✔️ |
protected | ✔️ | ✔️ | ✔️ | ❌ |
default(friendly) | ✔️ | ✔️ | ❌ | ❌ |
private | ✔️ | ❌ | ❌ | ❌ |
2.http和https区别
1. https需要ca证书,一般免费证书较少,所以需要一定费用的
2. http是超文本传输协议,信息为明文传输。https是具有安全性的ssl加密传输协议
3. http和https使用的是完全不同的连接方式,http端口为80,https端口为443
4. http是简单链接,无状态的。https协议是有ssl+http协议构建的可进行加密传输、身份认证的网络协议,比http协议安全
3.android6.0、7.0.、8.0、9.0 新加特性
- 5.0加入Material Design、recycleView,
- 6.0动态权限,系统级指纹,
- 7.0分屏多任务,获取uri方式改变,
- 8.0画中画,app更新增加未知来源应用安装权限,
- 9.0,刘海儿屏、Material Design更新,代码反射检测)
4.handle机制,Looper.loop()之后代码会执行吗,主线程为什么没有堵塞
5.SharedPreferences能跨进程访问吗?
- 不能跨进程
6.TCP与UDP区别总结:
- 1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
- 2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
- 3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的,UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
- 4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
- 5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
- 6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
7.内存分析
内存计数中的类别如下所示:
- Java:从 Java 或 Kotlin 代码分配的对象内存。
- Native:从 C 或 C++ 代码分配的对象内存。
即使您的应用中不使用 C++,您也可能会看到此处使用的一些原生内存,因为 Android 框架使用原生内存代表您处理各种任务,如处理图像资源和其他图形时,即使您编写的代码采用 Java 或 Kotlin 语言。
Graphics:图形缓冲区队列向屏幕显示像素(包括 GL 表面、GL 纹理等等)所使用的内存。 (请注意,这是与 CPU 共享的内存,不是 GPU 专用内存。)
**Stack: **您的应用中的原生堆栈和 Java 堆栈使用的内存。 这通常与您的应用运行多少线程有关。
Code:您的应用用于处理代码和资源(如 dex 字节码、已优化或已编译的 dex 码、.so 库和字体)的内存。
Other:您的应用使用的系统不确定如何分类的内存。
Allocated:您的应用分配的 Java/Kotlin 对象数。 它没有计入 C 或 C++ 中分配的对象。
当连接至运行 Android 7.1 及更低版本的设备时,此分配仅在 Memory Profiler 连接至您运行的应用时才开始计数。 因此,您开始分析之前分配的任何对象都不会被计入。 不过,Android 8.0 附带一个设备内置分析工具,该工具可记录所有分配,因此,在 Android 8.0 及更高版本上,此数字始终表示您的应用中待处理的 Java 对象总数。
8.java面向对象思想理解
Java中面向对象的三大特征:封装、继承、多态。
-
封装:
- 目的:
增强安全性和简化编程,使用者不必了解具体的实现细节,只要通过对外公开的访问方法调用。
- 目的:
-
继承
- 类的划分
- 1.普通类:使用class定义且不含有抽象方法的类。
- 2.抽象类:使用abstract class定义的类,它可以含有和不含有抽象方法。
- 3.接口:使用interface定义的类。
- 继承规则
- 普通类可以继承普通类,可以继承抽象类,可以继承接口。
- 抽象类可以继承普通类,可以继承抽象类,可以继承接口。
- 接口只能继承(extends)接口。
- 继承约束
- 一个普通类或者一个抽象类只能继承一个普通类,或者只能继承一个抽象类,即所谓的单继承。
- 一个普通类或者一个抽象类可以(实现)一个接口,也可以继承(实现)任意多个接口。
- 一个普通类继承一个抽象类之后,必须实现这个抽象类中所有的抽象方法,否则只能定义为抽象类。
- 一个普通类继承(实现)一个接口后,必须实现这个接口中定义的所有方法,否则只能被定义为抽象类。
- 抽象类继承抽象类,或者实现接口时,可以部分、全部或者完全不实现父类抽象类的抽象方法或者父类接口中定义的方法。
- 类的划分
-
多态
-
实现多态的是必要条件
- 继承:在多态中必须存在有继承关系的子类和父类。
- 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
- 向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。
只有满足了上述三个条件,我们才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。
重载(overloading)重写(overriding)
-
9.一个".java"源文件中是否可以包含多个类(不是内部类)?有什么限制?
- 一个".java"文件内可以有多个类,但只能有一个类是公开的
10.如何理解浅拷贝和深拷贝
- 浅拷贝是指克隆了引用副本,两个引用指向统一实例。
11.成员内部类、静态内部类、局部内部类和匿名内部类的理解,以及项目中的应用
- 成员内部类: 1.内部类持有外部类的引用。 2.成员内部类不允许static。
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
- 静态内部类: 1.static修饰的内部类。2.静态内部类不会持有外部类的引用
3.静态内部类可以访问外部的静态变量,如果访问外部类的成员变量必须通过外部类的实例访问。 - 局部内部类: 1.局部内部类嵌套在方法内,只能供该方法使用。2.根据情况决定持有外部类对象引用。3.不能使用private,protected,public修饰符。4.不能包含静态成员。
public void show(){
final double tvMoney=10000;
final double netMoney=20000;
class AdverTeam{
String teamName="shen_hua";
//电视宣传
public void tvShow(){
System.out.println("宣传队是:"+teamName);
System.out.println("这是电视宣传,学校名称"+schoolName+",业务内容:"+buss+",学校人数:"+studentNum+",宣传所需费用"+tvMoney);
}
//网络宣传
public void netShow(){
System.out.println("宣传队是:"+teamName);
System.out.println("这是网络宣传,学校名称"+schoolName+",业务内容:"+buss+",学校人数:"+studentNum+",宣传所需费用"+netMoney);
}
}
new AdverTeam().tvShow();
new AdverTeam().netShow();
};
- 匿名内部类: 直接上例子:
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
.....
}
});
- 内部类优点: 因为Java不支持多继承,支持实现多个接口。但有时候会存在一些使用接口很难解决的问题,这个时候我们可以利用内部类提供的、可以继承多个具体的或者抽象的类的能力来解决这些程序设计问题。可以这样说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。
12. 阐述final、finally、finalize的区别。
这是三个不同的概念,只是因为长得较像而被出成了一道题
final
final是一个修饰符,用来修饰类,变量,方法
- final修饰的类不能被继承
- final修饰的方法不能被重写
- final修饰的成员变量是不可变的,如果成员变量是基本数据类型,初始化之后成员变量的值不能被改变,如果成员变量是引用类型,那么它只能指向初始化时指向的那个对象,不能再指向别的对象,但是对象当中的内容是允许改变的
finally
- finally与try,catch一起搭配使用,不论是否catch到异常,finally中的内容都会执行
finalize
- finalize是Object类中的方法,垃圾回收器在垃圾回收时会调用该方法,我们可以在子类中重写该方法来做一些清理工作
13. finally 语句一定会执行吗
在极特殊的情况下可能不执行
- 调用了System.exit()方法
- JVM崩溃了
14. int和Integer有什么区别?
1.int是基本类型,Integer是int的包装类型
2.包装类型可以有一些自己的方法,引入包装类型可以使java更好的面向对象
3.每个基本类型都有其包装类:
原始类型: boolean,char,byte,short,int,long,float,double
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
扩展1:
java5中引入了自动拆装箱功能,例如在比较时可以自动拆装箱
class AutoUnboxingTest {
public static void main(String[] args) {
Integer a = new Integer(3);
Integer b = 3; // 将3自动装箱成Integer类型
int c = 3;
System.out.println(a == b); // false 两个引用没有引用同一对象
System.out.println(a == c); // true a自动拆箱成int类型再和c比较
}
}
扩展2:
一道和装箱有关的面试题
public class Test03 {
public static void main(String[] args) {
Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
System.out.println(f1 == f2); //true
System.out.println(f3 == f4); //false
}
}
分析:自动装箱时,使用的时Integer的valueof方法,当int在-128到127之间时,并不会new一个新的对象,而是直接使用常量池中的Integer
15. String是基本数据类型嘛
不是。String属于库函数
- java中8个基本类型为:byte、short、char、int、float、long、double、boolean。
- java中除基本类型外,都是引用类型(枚举是java5以后引入的特殊引用类型)
- String类型比较特殊,不可变。但它不是基本类型。
16. String和StringBuilder、StringBuffer的区别
String 是只读字符串,StringBuilder和StringBuffer可以改变,StringBuilder效率高,线程不安全,StringBuffer线程安全。 在拼接String时,使用+编译器会帮我们进行优化,使用StringBuilder进行拼接,这时+和StringBuilder没有多大区别。但当循环中使用+时,我们应该显示的使用StringBuilder,以防止多次调用new StringBuilder,造成不必要的性能浪费。
循环中使用+举例:
String str = "hello,world!";
String result = "";
for (int i = 0; i < loopCount; i++) {
result += str;
}
这个时候编译器会优化成
String str = "hello,world!";
String result = "";
for (int i = 0; i < loopCount; i++) {
result = new StringBuilder(result).append(str).toString();
}
多次new StringBuilder造成了性能浪费。
扩展例题
class StringEqualTest {
public static void main(String[] args) {
String s1 = "Programming";
String s2 = new String("Programming");
String s3 = "Program";
String s4 = "ming";
String s5 = "Program" + "ming";
String s6 = s3 + s4;
System.out.println(s1 == s2); // false
System.out.println(s1 == s5); //true
System.out.println(s1 == s6); //false
System.out.println(s1 == s6.intern()); //true
System.out.println(s2 == s2.intern()); //false
}
}
解析:1. String是引用类型,这里 == 比较的是引用是否相同,即是否指向相同的地址
2. 在new String对象时,会产生一个新的对象,并不会使用常量池中的字符串
3. intern会在常量池中寻找该字符串(如果没有责新建),并返回他的地址
17. String s = new String("xyz");创建了几个字符串对象?
两个对象,一个是静态区的"xyz";一个是用new创建在堆上的对象。
18. Java中如何实现序列化,有什么意义。
1.序列化是将对象的状态信息转换为可以存储或传输的形式的过程。
2.java将对象序列化成了字节信息
3.java通过实现Serializable接口实现序列化
19.for-each与常规for循环的效率对比
- for-each 使代码更加简洁优雅
- for-each 实际上是通过迭代器(Iterator)实现的
20. java8 有哪些新特性
支持Lambda 表达式,方法引用,增加了新的时间工具类等
21.用最有效率的方法计算2乘以8?
2 << 3(左移n位相当于乘以2的n次方,右移n位相当于除以2的n次方)。
22.简述一下你了解的设计模式
所谓设计模式,就是一套被反复使用的代码设计经验的总结(情境中一个问题经过证实的一个解决方案)。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式使人们可以更加简单方便的复用成功的设计和体系结构。将已证实的技术表述成设计模式也会使新系统开发者更加容易理解其设计思路。 在GoF的《Design Patterns: Elements of Reusable Object-Oriented Software》中给出了三类(创建型[对类的实例化过程的抽象化]、结构型[描述如何将类或对象结合在一起形成更大的结构]、行为型[对在不同的对象之间划分责任和算法的抽象化])共23种设计模式,包括:Abstract Factory(抽象工厂模式),Builder(建造者模式),Factory Method(工厂方法模式),Prototype(原始模型模式),Singleton(单例模式);Facade(门面模式),Adapter(适配器模式),Bridge(桥梁模式),Composite(合成模式),Decorator(装饰模式),Flyweight(享元模式),Proxy(代理模式);Command(命令模式),Interpreter(解释器模式),Visitor(访问者模式),Iterator(迭代子模式),Mediator(调停者模式),Memento(备忘录模式),Observer(观察者模式),State(状态模式),Strategy(策略模式),Template Method(模板方法模式), Chain Of Responsibility(责任链模式)。 面试被问到关于设计模式的知识时,可以拣最常用的作答,例如:
- 工厂模式:工厂类可以根据条件生成不同的子类实例,这些子类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作(多态方法)。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。
- 代理模式:给一个对象提供一个代理对象,并由代理对象控制原对象的引用。实际开发中,按照使用目的的不同,代理可以分为:远程代理、虚拟代理、保护代理、Cache代理、防火墙代理、同步化代理、智能引用代理。
- 适配器模式:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起使用的类能够一起工作。
- 模板方法模式:提供一个抽象类,将部分逻辑以具体方法或构造器的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法(多态实现),从而实现不同的业务逻辑。 除此之外,还可以讲讲上面提到的门面模式、桥梁模式、单例模式、装潢模式(Collections工具类和I/O系统中都使用装潢模式)等,反正基本原则就是拣自己最熟悉的、用得最多的作答,以免言多必失。
持续更新中...
参考
Android面试之Java 基础篇