[转]Android专家级别的面试总结

Android专家级别的面试总结

1.. 自定义View流程 
onMeasure, onLayout, onDraw, 采用深度优先,因为必须子view获得测量结果,父view才能确定大小;

2.. 事件分发机制 
https://www.cnblogs.com/aademeng/articles/6551337.html

ViewGroup: 
boolean dispatchTouchEvent(){ 
if(onInterceptTouchEvent() && onTouchEvent()){ 
return true; 
}else{ 
return child.dispatchTouchEvent(); 

}

View:(View如果有OnTouch则先执行且返回true,则被OnTouch消费;否则如果返回false,则看是否可点击,可以点击的话,一定消费,至于是否是onClick消费看是否设置了OnClickListener,没有的话,就是一个没有反应的点击事件;如果不可点击,则view不消费此事件) 
boolean dispatchTouchEvent(){ 
if(OnTouchListener() && OnTouch()) 
return true; 
else if(clickable()){ 
onClick(); 
return true; 
}else 
return false; 
}

一个事件系列(即DOWN–>MOVE…MOVE–>UP),如果一旦一个view接受处理此事件,那么事件系列后续事件直接给它,不必再次调用onInterceptTouchEvent.

如果所有元素都不处理这个事件,那么这个事件最终会交给Activity去处理,就是Activity的OnTouchEvent方法会被调用

Activity.java 
/** 
* Called when a touch screen event was not handled by any of the views 
* under it. This is most useful to process touch events that happen 
* outside of your window bounds, where there is no view to receive it. 

* @param event The touch screen event being processed. 

* @return Return true if you have consumed the event, false if you haven’t. 
* The default implementation always returns false. 
*/ 
public boolean onTouchEvent(MotionEvent event) { 
if (mWindow.shouldCloseOnTouch(this, event)) { 
finish(); 
return true; 
}

    return false;
}
  • 1
  • 2
  • 3

3.. Service启动模式(startService bindService) 
4.. Activity的启动模式(standard, singleTop, singleTask(Home页面常使用), singleInstance ) 
5.. Android 动画有哪几种?区别? 
1). 帧动画: 大量图片播放,耗内存,容易OOM 
2). 补间动画(Tween动画或者View动画):并未真正改变位置 
3). 属性动画 :真正改变位置

6.. handler, Looper,MessageQueue, Message之间的关系 
7.. 性能优化有哪些方面可以提高性能的 
View方面: 
布局减少嵌套, 多使用Drawable, Include, Merge, ViewStub, 
懒加载

中间: 
耗时任务放入子线程, 多线程并发的情况用线程池

底层: 
DB的大量访问改为事务处理 
大量HTTP download改为一次性

8.. 如何诊断性能问题(log, TraceView, MAT) 
9.. MVP框架的理解 
10.. 多组件开发 和 插件化开发 的理解 
11.. 热修复框架,原理?(AndFix, QZone …) 
12.. 自动化测试框架(JUnit, Espresso)

13.. 项目中遇到的最难的问题是什么?如何解决的? 
1). 有页面加载时间过长,32s,log发现后台执行时间28s,原因for循环里查询数据库组装数据json,解决办法:一次性查出所有数据,在内存中操作拼接;->减少至4s;然后把download数据的http接口全部放入一个里面,减少网络访问次数,保存本地DB事务一次性完成,大大提高性能速度,秒进。 
2). 滑动冲突:嵌套滑动的view,解决办法:外部拦截 + 内部拦截 
3). 曲线画图 eChartsJS –>MPAndroidChart 
4). 蓝牙兼容性问题 
5). 主页进入时间过长,导致有黑屏现象。 
解决办法: 
1. 各个tabFragment懒加载。 
2. 大量计算放入子线程。 
3. SplashFragment方式 
https://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650822284&idx=1&sn=d6b30ab442f417cbd992e784945c7799&chksm=80b78212b7c00b049243a474933e7a3f356c8b6fca1e8d67a9fcf654cef095c0c28f6a51e31c&mpshare=1&scene=1&srcid=0313ZLGSBSoiqyxWXffvrchw&key=ff97d989c700b3d86839adc72e98c86494511f6bb644f8efa1370467ffab8ea6a0160388e64873e4dae98227c48bbf423bbf15bc7f3216428c02b6e32ff68c90638921e4a6ceb38f7ad7069ca82d92af&ascene=0&uin=Mzk2Mjg2NTk1&devicetype=iMac+MacBookPro11%2C1+OSX+OSX+10.10+build(14A389)&version=11000003&pass_ticket=Cwf5%2BnPtLYQCdWMfJ6FyPskVFj5bDmdqEr3Qa5G9%2B7ai7nS0YaH0A2yZoMsgtCVz

14.. 用过哪些设计模式 
单例,抽象工厂,观察者模式,代理模式…

15.. 算法考察

16.. java基础(synchronize关键字理解, 锁,jvm, 多线程,深拷贝,浅拷贝…)

17.. LRU Cache 算法原理?用的什么数据结构?(LinkedHashMap, 双向链表,用的强引用可以控制,最近使用放到队尾,当达到上限时删除对头即可)

18.. Android logcat 里打出的 GC_FOR_ALLOC等等是什么意思?LeakCanary检测内存泄露原理? AndroidAnnotation原理?

19.. HashMap 怎么实现的?和Hashcode关系?

20.. handler, AsyncTask 区别,什么情况用,优缺点。 
都是为了异步线程而存在,handler实现更轻量级,需要自己实现. AsyncTask更重量级,但是封装好,使用简单方便。 
AsyncTask缺点: 
a). 当它为Activity的非静态内部类,则如果后台线程未完成任务,但是Activity已经销毁,则发生内存泄露。 
b). 当Activity在AsyncTask更新UI前已经销毁,则崩溃,所以必须在销毁之前取消 AsyncTask。 
c). 内部是以线程池的方式提供,N+1个。

21.. 哪些情况会导致内存泄露. 
a). 匿名内部类 
b).没有unregisterReceiver, EventBus unregister(this)等 
c). 静态变量持有Context没有及时赋值为NULL

22.. 哪些情况容易OOM,如何有效避免 
a). 大量图片的加载,inSampleSize, ARGB_8888… 
b). 对象池的复用 convertView 
c). 地图单车全量加载一次性23M数据,导致ANR,而且由于做了LoggingInterceptor, EncryptorInterceptor, 在做source.buffer().readString()时需要额外的同样大小的数组,导致一次性分配OOM。解决的办法是对于这个接口单独不做log和加密,或者从产品设计上讲把围栏划分得更小(最好的方案)消除ANR和数据量大导致的OOM。 
d). 相机扫码获取的帧数据进行剪裁和预处理后依然有分配数组OOM。

23.. Https 过程 
http://blog.csdn.net/sean_cd/article/details/6966130

24.. OKhttp 架构图 
http://blog.csdn.net/apple_hsp/article/details/50964923

25.. Android 哪些Context能startActivity? 
I). Activity可以直接启动 
II). Service和Application也可以启动,但是必须加上intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
III). BroadcastReceiver 和 ContentProvider 不能直接startActivity,但是可以 context.startActivity(…), 其中Context看是 I)还是II)来是否加NEW_TASK_FLAG。Context是注册receiver的,比如是在Activity中动态注册的receiver,那么onReceive里的context参数就是此Activity;如果是静态注册,那么是applicationContext.

26.. Intent(context, MyActivity.class) 参数的意义 
第一个参数只是为了获取App的packageName,在此package中寻找第二个参数MyActivity的实现。所以第一个参数是任意的Context均可,比如activity, service, getApplicationContext()等等。

public Intent(Context packageContext, Class<?> cls) {
        mComponent = new ComponentName(packageContext, cls);
    }

public ComponentName(Context pkg, Class<?> cls) { mPackage = pkg.getPackageName(); mClass = cls.getName(); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

27.. View CANCEL事件什么时候触发? 
当用户保持按下操作,并从你的控件转移到外层控件时,会触发ACTION_CANCEL

28.. View DOWN UP事件的区别? 
一个是点击下去时触发,一个起来时触发

29.. 哪些场景需要多开进程service,为什么? 
一般是为了App保活,或者新开进程做长连接,如JPUSH

30.. 如何解决DNS挟持问题? 
HTTPS

31.. Android第三方工具如Bugly, 友盟,bugtags如何获得Java崩溃异常,和Navtive崩溃,ANR的? 
Java崩溃异常:注册自己的UnCaughtExceptionHandler 
Navtive崩溃: 在Navtive层Linux会产生异常信号,而且Linux提供了Core Dump机制。通过JNI注册自己的异常信号捕获sigaction处理不同的信号异常即可。 
具体见http://blog.csdn.net/leeo1010/article/details/50522892 
ANR: 通过在主线程schedule一个runnable, 5秒一次,看看是否执行(比如在runnable计数);是,继续循环;否,则说明有ANR发生。 
http://blog.csdn.net/gaoanchen/article/details/51914690

ANR的具体信息会被写入到/data/anr/traces.txt 
https://github.com/SalomonBrys/ANR-WatchDog/tree/master/anr-watchdog

32.. OKhttp有哪几种拦截Interceptor类型? HTTP重定向是哪个header? 
I. 应用层的拦截:主要对返回的respondeCode,response内容做处理. addInterceptor() 
II. 网络层:可以改变, 增减header等。addNetworkInterceptor() 
HTTP重定向是 Response里的Location 字段。发生在网络层。应用层是看不到的,即当有重定向发生时,应用层拦截器只会调用一次,而网络层拦截器会调用2次。 
https://github.com/square/okhttp/wiki/Interceptors

33.. Android热更新(HotPatch)方案有哪几种?区别? 
主要有腾讯的QZone方案(Class级别的替换,Java实现, 无兼容性问题),阿里的AndFix(Method级的替换,JNI—>Native实现替换方法,Art虚拟机兼容性不好)。

34.. JNI命名规则,原理,能否相互调用? 
java能通过JNI调用C,而C不能调用java。

Java 里调用C:

java: 
public static native int execAL(…);

C++里对java里的native的方法命名规则: 
JNIEXPORT int JNICALL Java_[packageName]_[className]_execAL(….); 
j[int, string …] 对应类型

C里logcat 打log: 
定义宏 #define LOGW(…) android_log_print(ANDROID_LOG, “jni”, __VA_ARGS)

35.. Java和js能否相互调用? 
可以。

java调用js: 
mWebView.loadUrl(“javascript:androidCallJS(‘顺便传个参数给JS!’)”);

js调用java: 
webview.addJavascriptInterface(obj, objStr) 
那么在js里可以把objStr当做obj用,调用其任何方法。 
window.objStr.xxx

36.. https 如何提高成功率 
第一次连接成功后,可以在服务器生成一个session key,后续此client再次发起https请求时带着 sessionID = session key,服务器可以直接验证通过,提升了握手效率和成功率。

37.. 为什么选型okhttp,而不是volley? 
okhttp的拦截器比较强大,可以添加修改header以及针对某些response code做出统一反应。

39.. APK 加壳原理? 
利用加密工具对源APK加密,然后和脱壳程序的DEX合并为新的DEX,然后替换掉脱壳程序的DEX成为新的APK,运行时,脱壳程序DEX负责解密源APK,并运行之。

40.. so层安全性? 
so层加密

41.. 插件化中为定义在宿主app的Manifest中的Activity是如何调起来的? 
I. 在宿主app的Manifest中定义一个fakeActivity 
II. 仍然startActivity(this, Target.class) 
III. 在进入AMS之前HOOK掉Target.class为fakeActivity, 使其通过AMS对Manifest的检查,然后出来之后,再次替换为Target,正确调起来

42.. Parcelable Serializable 区别? 
Serializable 采用变对象为字节流的方式,可以持久化在硬盘中,而Parcelable不行。Parcelable本质是通过把对象拆分为可以用intent传输的方式进行拆解和还原,因此其效率较高。

43.. SparseArray, ArrayMap 和Hashmap区别? 
SparseArray是为了减少内存的使用,使用key[int], value[Obj],来分别存储Key和value,没有浪费内存。使用二分查找来put, delete, 因此效率上稍低,但是对于delete有特殊的对待,只是标记为delete,无需移位。而Hashmap内部采用了数组+链表,以及用hash的方式,会有很多内存空着也要占用。而且其扩容是2的倍数,且需要重新hash把旧的数据放置在新的table中。其内存使用率比SparseArray低,但是put, delete效率较高。

44.. java中的锁有? 
Synchronized, ReentrantLock.保证多线程的同步,即操作的原子性。然后,它们还能保证变量的可见性,锁内使用变量时会去主存获取最新的变量值,释放锁之后把变量最新值从工作内存刷新至主存中。

45.. volatile作用? 
保证变量的可见性,多线程之间使用此变量时,会从主存读取最新的变量值,然后会把最新的变量值从工作内存刷新至主存中。 
volatile保证有序性。 
https://juejin.im/entry/58d8d57a1b69e6006bbddd5f/view

46.. 外部类和内部类的访问权限? 
内部类能直接访问外部类的任何修饰符的成员变量和方法。 
原因是内部类在编译期间编译器会给内部类自动添加一个外部类的成员变量,构造方法参数添加一个外部类参数赋值给其外部类的成员变量。使其持有外部类的对象的引用。 
反之,外部类不能直接访问内部类的任何修饰符的成员变量和方法。因为,内部类必须依赖于外部类的对象而存在。 
另外,内部类不能拥有static成员变量,道理同上。

47.. 类的修饰能有哪些? 
顶级类只能是public 和default 
内部类都可以修饰, public, protected,private, default(friendly).

48.. 泛型 T, ? 区别? 
T是某一类确定的类型,?是未知类型。 
?的上边界extends,只能读,下边界super只能插入。 
https://www.zhihu.com/question/20400700

49.. requestLayout, invalidate, postInvalidate 区别? 
http://blog.csdn.net/a553181867/article/details/51583060

50.. FragmentTransaction 里的 add, replace 区别? 
add不会重建,replace会remove之前此容器里added过的所有fragment实例,然后再add现在的fragment。 
http://blog.csdn.net/gsw333/article/details/51858524

51.. 线程的启动方式? 
// MyThread里的资源不共享 
new MyThread().start()

// m1里的变量 资源共享 
Runnable m1 = new Runnable(); 
new Thread(m1).start() 
…. 
new Thread(m1).start()

52.. 终止线程的方式? 
I. 共享变量flag法,volatile方式:终止正在运行的线程;但是无法终止一个被阻塞的线程(因为无法运行到flag来)。 
II. thread.interrupt() 可以使一个被阻塞的线程抛出一个中断异常,从而使线程提前结束阻塞状态,退出堵塞代码。 
http://www.cnblogs.com/luckygxf/p/4737655.html

53.. Service 与 IntentService 区别? 
IntentService继承Service,内部在OnCreate时自动创建了一个子线程,里面维护了一个消息队列来顺序执行每个onStartCommand的intent。而Service没有,因此如果在Service的onStartCommand里启动一个线程的话, 那么多次调用startService会使多个线程并发。

54.. onStartCommand返回值的作用? 
http://blog.csdn.net/taki_dsm/article/details/8865913

55.. 广播和有序广播(优先级)区别? 
有序广播可以设置优先级来优先获取广播(intentFilter.setPriority()),而且能够把处理结果传递给下一个广播优先级接受者setResultExtras(Bundle bundle)/getResultExtras(Bundle bundle),也可以终止广播传播abortBroadcast()。 
http://www.cnblogs.com/codingblock/p/4856559.html

56.. java里的锁有哪些? 
synchronized, Lock(ReadWriteLock, ReentrantLock)

57.. surfaceView和View最本质的区别? 
surfaceView是在一个新起的单独线程中可以重新绘制画面,而View必须在UI的主线程中更新画面. 
http://www.cnblogs.com/lipeil/archive/2012/08/31/2666187.html

58.. onSaveInstanceState什么时候触发?在onstop之前吗? 
在Activity可能被系统杀掉的情况下触发,1. 按Home键 2. 锁屏 3. 屏幕旋转。必然触发,而且在onPause之后,和onStop之前。并且其中只有屏幕旋转肯定会触发onRestoreInstanceState,因为Activity真的被杀掉重新生成了。

59.. android 中多进程是共用一个Application吗还是不同的Application? 
多进程共用一个Application,因此可能会调用多次同一个Application的onCreate,因此可以在onCreate里根据不同的进程名来判断执行不同的逻辑。

60.. Fragment构造函数,官方只推荐用无参数的,为什么,如何传值? 
http://www.tuicool.com/articles/j22E3u

猜你喜欢

转载自www.cnblogs.com/didiaoxiong/p/9098303.html
今日推荐