六、架构设计和设计模式
1.谈谈你对Android设计模式的理解
2.MVC MVP MVVM原理和区别
3.你所知道的设计模式有哪些?
4.项目中常用的设计模式
5.手写生产者/消费者模式
6.写出观察者模式的代码
7.适配器模式,装饰者模式,外观模式的异同?
8.用到的一些开源框架,介绍一个看过源码的,内部实现过程。
9.谈谈对RxJava的理解
10.Rxjava发送事件步骤
11.RxJava的作用,与平时使用的异步操作来比的优缺点
12.说说EventBus作用,实现方式,代替EventBus的方式
13.从0设计一款App整体架构,如何去做?
14.说一款你认为当前比较火的应用并设计(比如:直播APP,P2P金融,小视频等)
15.谈谈对java状态机理解
16.Fragment如果在Adapter中使用应该如何解耦?
17.Binder机制及底层实现
18.对于应用更新这块是如何做的?(解答:灰度,强制更新,分区域更新)?
19.实现一个Json解析器(可以通过正则提高速度)
20.统计启动时长,标准
参考答案:
1.谈谈你对Android设计模式的理解
六大原则
单一职责 一人做一事
开闭原则 对扩展开放 对修改封闭
里式替换 继承和多态的体现 父类声明 子类new
依赖倒置 解耦 高层依赖接口 不依赖细节
接口隔离 最小接口 7 + 2
迪米特 最少了解
设计模式
单例模式
public class Singleton {
private volatile static Singleton instance;
//将默认的构造函数私有化,防止其他类手动new
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
Builder模式
AlertDialog.Builer builder = new AlertDialog.Builder(context);
builder.setIcon(R.drawable.icon)
.setTitle("title")
.setMessage("message")
.setPositiveButton("Button1",
new DialogInterface.OnclickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
setTitle("click");
}
})
.create()
.show();
原型模式
Uri uri = Uri.parse("smsto:10086");
Intent shareIntent = new Intent(Intent.ACTION_SENDTO, uri);
//克隆副本
Intent intent = (Intetn) shareIntent.clone();
startActivity(intent);
工厂模式
public Object getSystemService(String name) {
if (getBaseContext() == null) {
throw new IllegalStateException("System services not available to Activities before onCreate()");
}
//........
if (WINDOW_SERVICE.equals(name)) {
return mWindowManager;
} else if (SEARCH_SERVICE.equals(name)) {
ensureSearchManager();
return mSearchManager;
}
//.......
return super.getSystemService(name);
}
抽象工厂
public class BaseService extends Service{
@Nullable
@Override
public IBinder onBind(Intent intent){
return new Binder();
}
}
策略模式
状态模式
WIFI
责任链模式
android 点击
解释器模式
PackageManagerService 解释 Manifest
命令模式
观察者模式
ListView notifyDataSetChanged()
备忘录模式
onSaveInstanceState
onRestoreInstanceState
迭代器模式
Iterator
Cursor
cursor.moveToFirst();
do{
//cursor.getXXX(int);
} while (cursor.moveToNext);
模板方法模式
Activity
访问者模式
APT Annotation Processing Tools
中介者模式
中介者对象是将系统从网状结构转为以调停者为中心的星型结构。
ServiceManager持有各种系统服务的引用 ,当我们需要获取系统的Service时,比如ActivityManager、WindowManager等(它们都是Binder),
首先是向ServiceManager查询指定标示符对应的Binder,再由ServiceManager返回Binder的引用。
这里的ServiceManager和Binder驱动就是中介者。
代理模式
aidl
组合模式
ViewGroup
适配器模式
ListView RecyclerView
装饰模式
Context
ContextThremeWrapper 继承 ContextWrapper 继承 Context
ContextWrapper 持有 mBase(ContextImpl)
享元模式
Message.obtain()
外观模式
Context
桥接模式
View Display HardwareLayer Canvas
MVC MVP MVVM
M 数据库/网络 -> V
V 布局 Activity Fragment -> M C
C Activity Fragment -> M V
M 数据库/网络 -> P
V 布局 Activity Fragment -> P
P Presenter -> M V
M 数据库/网络 -> VM
V 布局 Activity Fragment -> VM
VM ViewModel -> M
2.MVC MVP MVVM原理和区别
3.你所知道的设计模式有哪些?
继承 实现 组合 聚合 关联 依赖
简单工厂 Simpale Factory Pattern
工厂根据参数创建不同的产品,产品都实现同一接口。一个工厂,多个产品
工厂方法模式 Factory Method Pattern
各自的工厂生产各自的一个产品,工厂、产品都实现于抽象类。多个工厂,多个产品
抽象工厂模式 Abstract Factory Pattern
各自的工厂生产各自的一组产品,工厂、产品都实现于抽象类。多个工厂,多组产品
单例模式 Singleton Pattern
/**
* Singleton helper class for lazily initialization.
*
* Modeled after frameworks/base/include/utils/Singleton.h
*
* @hide
*/
public abstract class Singleton<T> {
@UnsupportedAppUsage
public Singleton() {
}
@UnsupportedAppUsage
private T mInstance;
protected abstract T create();
@UnsupportedAppUsage
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
生成器模式 建造者模式 Builder Pattern
复杂对象构建分步进行,相同步骤不同表示
原型模式 Prototype Pattern
Linux Zygote 进程
装饰模式 Decorator Pattern
不改变原有对象,动态增加格外功能 ContextImpl
外观模式 Facade Pattern
同一对外定义简单接口
代理模式 Proxy Pattern
在原访问路径中增加一个代理
享元模式 Flyweight Pattern
桥接模式 Bridge Pattern
将抽象部分与他的实现部分分开,使他们都能独立的变化
适配器模式 包装器 Adapter Pattern Wrapper Pattern
责任链模式 Chain of Responsibility Pattern
避免耦合,层层传递,触摸事件传递
命令模式 Command Pattern
请求封装为命令
解释器模式 Interpreter Pattern
定义语法,建立解释器
迭代器模式 Iterator Pattern
统一迭代方式
中介者模式 Madiator Pattern
解耦
备忘录模式 Memento Pattern Token Pattern
对象之外保存一个对象状态,用于后期恢复
onSaveInstanceState
onRestoreInstanceState
观察者模式 Observer Pattern
多人订阅一个新闻频道
发布-订阅(Publish/Subscribe)模式
模型-视图(Model/View)模式
源-监听器(Source/Listener)模式
从属者(Dependents)模式
状态模式 State Pattern
一定一组状态,每个状态可以相互替换,非独立存在
策略模式 Strategy Pattern Policy Pattern
定义一组策略,每个策略可以相互替换,并且独立存在
模板方法模式 Template Method
定义操作,子类实现
访问者模式 Visitor Pattern
4.项目中常用的设计模式
创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。
5.手写生产者/消费者模式
6.写出观察者模式的代码
7.适配器模式,装饰者模式,外观模式的异同?
共同点:介于调用者和被调者之间,中间层,起到隔离
不同点:装饰模式是“新增行为”,代理模式是“控制访问行为”,适配器模式是"转换行为",外观模式是一种"简化行为"
适配器模式:包装另一个对象,并提供不同的接口。
外观模式:包装许多对象,以简化他们的接口。
装饰者模式:包装另一个对象,并提供额外的行为。
代理模式:包装另一个对象,并控制对它的访问。
8.用到的一些开源框架,介绍一个看过源码的,内部实现过程。
9.谈谈对RxJava的理解
//被观察者
Observable novel = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("连载1");
emitter.onNext("连载2");
emitter.onNext("连载3");
emitter.onComplete();
}
});
回调细节:
onNext方法可以无限调用,所有的调用都能接收到,
onComplete 可重复调用,只接受一次,与 onError 互斥
onError 只能调用一次,第二次会报异常,与 onComplete 互斥
代码:
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("连载1");
emitter.onNext("连载2");
emitter.onNext("连载3");
emitter.onComplete();
}
}).observeOn(AndroidSchedulers.mainThread())//回调在主线程
.subscribeOn(Schedulers.io())//执行在io线程
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.e(TAG, "onSubscribe");
}
@Override
public void onNext(String value) {
Log.e(TAG, "onNext:" + value);
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError=" + e.getMessage());
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete()");
}
});
复杂操作
Observable.create(new ObservableOnSubscribe<Drawable>() {
@Override
public void subscribe(ObservableEmitter<Drawable> emitter) throws Exception {
for (int i = 0; i < drawableRes.length; i++) {
Drawable drawable = getResources().getDrawable(drawableRes[i]);
//第6个图片延时3秒后架子
if (i == 5) {
sleep(3000);
}
//复制第7张图片到sd卡
if (i == 6) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
saveBitmap(bitmap, "test.png", Bitmap.CompressFormat.PNG);
}
//第8张上传到网络
if (i == 7) {
updateIcon(drawable);
}
emitter.onNext(drawable);
}
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Drawable>() {
@Override
public void accept(Drawable drawable) throws Exception {
//回调后在UI界面上展示出来
}
});
10.Rxjava发送事件步骤
注: 比如发送多个onComplete是可以正常运行的, 依然是收到第一个onComplete就不再接收了, 但若是发送多个onError, 则收到第二个onError事件会导致程序会崩溃.
注意: 调用dispose()并不会导致上游不再继续发送事件, 上游会继续发送剩余的事件.
map
flatmap 不保证顺序
concatmap 保证顺序
Flowable的源码中就有这个buffersize 128 MissingBackpressureException
11.RxJava的作用,与平时使用的异步操作来比的优缺点
又叫响应式编程、响应式扩展ReactiveX 是基于观察者模式设计的,核心对象只有 Observable 和 Observer。
Rx使代码简化
函数式风格:对可观察数据流使用无副作用的输入输出函数,避免了程序里错综复杂的状态
简化代码:Rx的操作符通通常可以将复杂的难题简化为很少的几行代码
异步错误处理:传统的try/catch没办法处理异步计算,Rx提供了合适的错误处理机制
轻松使用并发:Rx的Observables和Schedulers让开发者可以摆脱底层的线程同步和各种并发问题
RxJava 的优势也是简洁,但它的简洁的与众不同之处在于,随着程序逻辑变得越来越复杂,它依然能够保持简洁
12.说说EventBus作用,实现方式,代替EventBus的方式
13.从0设计一款App整体架构,如何去做?
想要设计App的整体框架,首先要清楚我们做的是什么
一般我们与网络交互数据的方式有两种:主动请求(http),长连接推送
结合网络交互数据的方式来说一下我们开发的App的类型和特点:
数据展示类型的App:特点是页面多,需要频繁调用后端接口进行数据交互,以http请求为主;推送模块,IM类型App的IM核心功能以长连接为主,比较看重电量、流量消耗。
手机助手类App:主要着眼于系统API的调用,达到辅助管理系统的目的,网络调用的方式以http为主。
游戏:一般分为游戏引擎和业务逻辑,业务脚本化编写,网络以长连接为主,http为辅。
一般我们做的App都是类型1,简要来说这类app的主要工作就是
把服务端的数据拉下来给用户展示 把用户在客户端修改的数据上传给服务端处理 所以这类App的网络调用相当频繁,而且需要考虑到网络差,没网络等情况下,App的运行,成熟的商业应用的网络调用一般是如下流程:
UI发起请求 - 检查缓存 - 调用网络模块 - 解析返回JSON / 统一处理异常 - JSON对象映射为Java对象 - 缓存 - UI获取数据并展示
这之中可以看到很明显职责划分,即:数据获取;数据管理;数据展示
14.说一款你认为当前比较火的应用并设计(比如:直播APP,P2P金融,小视频等)
15.谈谈对java状态机理解
有限状态机
状态 条件 时间 动作 迁移
分层状态机
16.Fragment如果在Adapter中使用应该如何解耦?
MVVM
17.Binder机制及底层实现
18.对于应用更新这块是如何做的?(解答:灰度,强制更新,分区域更新)?
www.qingtingip.com/h_239744.ht…
19.实现一个Json解析器(可以通过正则提高速度)
20.统计启动时长,标准
adb shell am start -w packagename/activity
WaitTime 返回从 startActivity 到应用第一帧完全显示这段时间. 就是总的耗时,包括前一个应用 Activity pause 的时间和新应用启动的时间;
ThisTime 表示一连串启动 Activity 的最后一个 Activity 的启动耗时;
TotalTime 表示新应用启动的耗时,包括新进程的启动和 Activity 的启动,但不包括前一个应用Activity pause的耗时。
生命周期函数执行流程
-> Application 构造函数
-> Application.attachBaseContext()
-> Application.onCreate()
-> Activity 构造函数
-> Activity.setTheme()
-> Activity.onCreate()
-> Activity.onStart
-> Activity.onResume
-> Activity.onAttachedToWindow
-> Activity.onWindowFocusChanged
1.起始时间点
Application.attachBaseContext()
Activity.onRestart()
2.结束时间点
Activity.onResume 错误
Activity.onWindowFocusChanged