面向对象思想

OOP: 继承 封装 多态 ,简单来说就是接口和抽象类,接口可以看做是一个特殊的抽象类。
抽象类和接口是不完整的类。
抽象类既可以抽象方法也可以定义非抽象方法
接口只可以定义方法名
抽象类可以定义普通的变量
接口只能定义public变量
什么时候该用抽象类,什么时候该用接口?
例如BaseActivity基类就是抽象类的使用,主要表现在继承上面,默认的一些行为不需要重复写。很大部分常用的基类就会作为抽象类。
只有需要某个功能才会实现接口,例如某个Activity要用到定位的功能,如果把定位写到基类上就不好了。
面向接口编程,不只是接口,还包括抽象类。

Android与java序列化原理

  1. Java: Serializable Android:Parcelable 提供了两个接口
  2. Serializable与Parcelable的区别:
    1. serializable:JDK 中的一个空接口,这个接口就是用来做标记的,对类打上了一个标记,可以把这个对象写到一个流中写到文件中去。如何做到序列化的呢?假设一个User类,name age属性. 类的所有信息打包写到文件中去,这样读取文件才能逆向反序列化得到这个对象 。serializable有大量的IO和反射操作。
    2. Parcelable:Android提供的一个接口,这个接口就不是一个空的实现了,序列化的时候会调用writeToParcel,记录Parcel 只记录属性的值,作用在内存之间的序列化,不能用在持久化中,不能保存在文件中这是和serializable的区别。而且Parcelable写的顺序要和读的顺序一样。效率会比Serializable高,但是Parcelable实现较为繁琐
  3. 序列化的目的就是把一个对象传输到某个地方,然后得到传输的对象,序列化:把对象的所有字段和属性打标签记录。反序列化:按照一定的顺序把对象恢复过来。序列化是一个过程。
  4. GSON等框架是如何对json字符串序列化为对象?GSON也是序列化只不过GSON的规则变了,Serializable有自己的规则,Parcelable也有自己的规则,序列化的本质并没有变,都是记录标记信息,根据标记的信息进行反序列化。

什么是单例

  • 为什么要使用单例模式?
    • 创建对象和运行开销很大,包含某些重量级的对象,如果每次都创建对象,会非常消耗内存,这时候就需要用到单例
    • 构造方法不对外开放的,一般是private
    • 通过一个静态方法或者枚举返回单例类的对象
    • 注意多线程的场景
    • 注意单例类对象在反序列化时不会重新创建对象
  • 饿汉式:程序总是创建并使用单例实例或在创建和运行时开销不太,不管他会不会用到,立马创建
  • 懒汉式:用到的时候才会初始化需要某些外部资源,双重校验单例模式:线程安全的单例模式
  • 静态内部类
  • 枚举

关于String的面试

什么是内存泄露,java如何处理?

内存泄露:一个长生命周期的对象持有一个短生命周期的对象引用,也就是说该回收的对象,因为引用问题没有被回收,最终产生OOM

Java本身不会帮助我们定位内存泄露,而是需要开发人员通过profiler工具定位的。如果问到了,他可能会要问题如何使用工具去定位内存泄露。

Java回收机制,如何减少OOM的概率

  1. Java回收机制:主要通过可达性分析算法,如果有对象没有达到GC Root就会被回收:
    1. 那么哪些可以作为GC Root的对象:

方法区:类静态属性的对象
方法区:常量的对象
虚拟机栈中的对象(方法执行完以后 就不再GC Roots所以GC会将他们回收掉)
本地方法栈JNI
image.png
image.png

  • 减少OOM的概率
    • 尽可能少的发生内存泄漏
    • 尽可能不在循环中申请内存
    • 尽可能不在调用次数很多的函数中申请内存

常见数据结构分析

ArrayList LinkedList

Iterator迭代器

HashMap SparseArray

排序算法

Java中的引用