模拟面试,了解一蛤?
Activity的生命周期,启动模式。
正常的生命周期:onCreate() --> onStart() --> onResume() --> onPause() --> onStop() --> onDestory()
Activity从后台返回前台:onStop() --> onRestart() --> onStart()
启动模式:
- 标准模式:standard
- 栈顶复用模式:singleTop
- 栈内复用模式:singleTask
- 单例模式:singleInstance
谈谈对封装、继承、多态的理解
封装:
隐藏对象的属性和实现细节,增强安全性和简化编程。
继承:
通过继承实现代码复用。单继承。尽量减少继承关系,降低耦合。
多态:
分为编译时多态和运行时多态,例如方法重载又被称为编译时多态,而对于覆盖或继承的方法,Java运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态。
组合了解吗?组合和继承有什么区别?
组合就是A类的对象是B类的成员变量,相当于A类对象是B类对象的一个变量,A类对象的所有功能,B类都可以通过A类对象来实现。
体现的是整体与部分的关系,即has - a 关系。
继承体现的是父子关系,即 is - a 关系。
继承结构中,父类的内部细节对于子类是可见的,所以通过继承的代码复用是一种白盒式代码复用。如果父类的实现跟随版本而发生变化,那么子类的实现也将随之改变,这样就导致了子类行为的不可预知性。
组合是通过对现有的类进行组合产生新的更复杂的功能。因为在类之间,各自的内部细节是不可见的,所以这种方式的代码复用是黑盒式代码复用。
进程和线程的区别
- 进程是系统进行资源分配和调度的一个独立单位,线程是进程中执行运算的最小单位,即线程是CPU调度和分派的基本单位。
- 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其他进程产生影响,而线程只是一个进程中的不同执行路径。
- 线程能减少并发执行的时间和空间开销,能更有效的利用多处理器和多内核。
谈谈你对泛型的了解?
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。泛型的好处是在编译的时候检查类型安全,有效的避免类转换异常,并且所有的强制转换都是自动和隐式的,提高代码的可读性和重用率。需要注意的是,泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。
Java中的泛型,只在编译阶段有效。(泛型擦除)
谈谈Android中的消息机制
在子线程执行完耗时操作,当Handler发送消息时,将会调用MessageQueue.enqueueMessage,向消息队列中添加消息。当通过Looper.loop开启循环后,会不断的从线程池中读取消息,即调用MessageQueue.next,然后调用目标Handler的dispatchMessage方法传递消息,然后返回到Handler所在线程,目标Handler收到消息,调用handleMessage方法处理消息。
简述Android的事件分发机制
事件流向:Activity --> ViewGroup --> View 责任链模式
涉及的三个方法以及作用:
dispatchTouchEvent:用于事件分发
onInterceptTouchEvent:用于事件拦截,只存在于ViewGroup中
onTouchEvent:用于处理事件
ListView卡顿原因以及怎么优化
卡顿原因:
- ItemView的布局嵌套复杂或者有透明元素等
- 快速滑动的时候加载过多ItemView
- Adapter里的耗时操作,比如处理复杂的业务逻辑或计算逻辑
- Adapter中重复创建对象以及大量的findViewById操作
- 外部嵌套了可滑动组件
优化:
- 减少ItemView的布局层级,监听ListView滑动状态,不要在ListView滑动的时候加载图片等
- convertView复用以及ViewHolder优化
- Adapter中减少复杂的逻辑操作,少做耗时操作
- ScollView --> NestedScollView,同时可以把ListView的高度固定死,避免ScollView在快速滑动过程中需要大量计算每一个ListView的高度。
- 开启硬件加速,当然,同时也会带来不可预料的BUG
- 使用RecycleView代替,并设置缓存池,即RecycleViewPool