当后台面试前端Android,你如何解决

一面(70分,毕竟不是特别帅)

信息对接,没啥好说的,仪容仪表,吐词清晰。基本都会过
但给我的感觉的话,五六个人的创业公司,Android一哥这些条件都不是我喜欢的,我自己为什么这么菜,我心里清楚,没有Android大牛和同事一起讨论,光靠自学,进步很慢,且没有竞争性,自己做的好功能,没有线下分享的空间,我内心就很不想这个公司了,既然是五六个人的创业公司,如果项目有说服力度,月入百万(人事说的),基本会找熟人,又怎么可能找我这种工作两年的小渣渣呢。

二面(20分)

渣归渣,自信还是要有的

面试问题一:Activity生命周期

7方法
onCreate —> 创建时调用
onStart —> 即将可见不可交互时调用
onResume —> 可见可交互时调用
onPause —> 即将暂停时调用
onStop —> 即将停止不可见时调用
onDestroy —> 即将销毁时调用
onRestart —> 重启时调用

正常的生命周期方法调用情况
1.长按home键再次回到 Activity 的生命周期log日志。

onRestart_A —> 重启时调用
onStart_A —> 即将可见不可交互时调用
onResume_A —> 可见可交互时调用

2.正常进入Activity_A,启动另一个Activity_B 的生命周期log日志。

onCreate_A —> 创建时调用
onStart_A —> 即将可见不可交互时调用
onResume_A —> 可见可交互时调用
onPause_A —> 即将暂停时调用
onCreate_B —> 创建时调用
onStart_B —> 即将可见不可交互时调用
onResume_B —> 可见可交互时调用
onStop_A —> 即将停止不可见时调用

3.按下物理返回键再次回到Activity_A的生命周期log日志。

onPause_B —> 即将暂停时调用
onRestart_A —> 重启时调用
onStart_A —> 即将可见不可交互时调用
onResume_A —> 可见可交互时调用
onStop_B —> 即将停止不可见时调用
onDestroy_B —> 即将销毁时调用

异常的生命周期方法调用情况
onSaveInstanceState方法和onRestoreInstanceState
当targetSdkVersion小于3时onSaveInstanceState是在onPause方法中调用的,而大于3时是在onStop方法中调用的。
而onRestoreInstanceState是在onStart之后、onResume之前调用的。

总结

6+1+2,生命周期为什么要这样设计
当后台面试前端Android,你如何解决
onPause不在第二个生命周期执行到onResume之后再执行呢?
如果这样执行的话两个Activity都 执行到onResume时候,比如你在打电话,但是你的视频仍然在播放,这就带来了很多困扰

面试问题二:IntentService与Service的区别

1.Service不属于线程进程,不适合写耗时操作,容易ANR(点击5,广播前10后60,服务前20后200,内容10)
2.IntentService是继承Service的,它和service不同的是会在onCreate中内部开了一个线程,去你执行你的耗时操作
3.IntentService在执行onCreate的方法的时候,其实开了一个线程HandlerThread,并获得了当前线程队列管理的looper,并且在onStart的时候,把消息置入了消息队列

总结

IntentService是通过Handler looper message的方式实现了一个多线程的操作,同时耗时操作也可以被这个线程管理和执行,同时不会产生ANR的情况。

面试问题三:自定义View
5中方式
  1. 自定义组合控件 多个控件组合成为一个新的控件,方便多处复用
  2. 继承系统View控件 继承自TextView等系统控件,在系统控件的基础功能上进行扩展
  3. 继承View 不复用系统控件逻辑,继承View进行功能定义
  4. 继承系统ViewGroup 继承自LinearLayout等系统控件,在系统控件的基础功能上进行扩展
  5. 继承ViewViewGroup 不复用系统控件逻辑,继承ViewGroup进行功能定义
绘制流程三方法
  1. measure() 测量View的宽高
    measure(),setMeasuredDimension(),onMeasure()
  2. layout() 计算当前View以及子View的位置
    layout(),onLayout(),setFrame()
  3. draw() 视图的绘制工作
    draw(),onDraw()
Android坐标系(X→,y↓)原点在屏幕的左上角

当后台面试前端Android,你如何解决

View获取自身高度

width = getRight() - getLeft();//或者getWidth();
height = getBottom() - getTop();//或者getHeight();

View自身的坐标

通过如下方法可以获取View到其父控件的距离。

getTop();获取View到其父布局顶边的距离。
getLeft();获取View到其父布局左边的距离。
getBottom();获取View到其父布局顶边的距离。
getRight();获取View到其父布局左边的距离。

实现其构造函数
自定义属性

编写values/attrs.xml,在其中编写styleable等标签元素
在布局文件中View使用自定义的属性
在View的构造方法中通过TypedArray获取

面试问题四:Android事件分发

1.找父类的dispatchTouchEvent()
2.setOnTouchListener中onTouch方法里返回决定是否执行onTouchEvent分发
3.onTouch方法里返回false,就会再去执行onTouchEvent(event)
4.onTouch返回true,onClick就不会再执行了
5.onClick的调用情况取决于switch MotionEvent.ACTION_UPcase中的performClick方法中的
mOnClickListener 是不是为空
6.MotionEvent,false断后(局限button)

面试问题5:JVM (不全主Android和内存泄漏问题)

jvm内存模型
1.类加载
2.运行期数据区
3.执行引擎
4.本地方法库
5.本地方法接口

类的生命周期

加载、链接、初始化、使用、卸载

运行时数据区域

程序计数器,栈,堆,方法区和本地方法区
程序计数器是java虚拟机规范中唯一没有规定内存溢出情况的数据区域,因为
Java的程序计数器是用来指向下一条要执行的指令的位置,所以他是一个可预见大小的值,没有必要outOfMemory,处于cpu上无法操作

重点,java堆,简称gc主战场

1.Java堆属于线程共享区域,所有的线程共享这一块内存区域

2.从内存回收角度,Java堆可被分为新生代和老年代,这样分能够更快的回收内存

3.从内存分配角度,Java堆可划分出线程私有的分配缓存区(Thread Local AllocationBuffer,TLAB),这样能够更快的分配内存

4.当Java虚拟机动态扩展到无法申请足够内存时会抛出OutOfMemory的错误

jvm内存分配小结

1.局部变量中的基本数据类型的值直接存栈中

2.局部变量中的引用数据类型在栈中存的是引用类型的指针(地址)

3.栈中的数据与堆中的数据内存回收并不是同步的,栈中的只要方法运行完,就会直接销毁局部变量,但堆中的对象不一定立即销毁

4.类的成员变量在不同对象中各不相同,都有自己的存储空间(成员变量在堆中的对象中)。而类的方法却是该类的所有对象共享的,只有一套,对象使用方法的时候方法才被压入栈,方法不使用则不占用内存

垃圾回收机制

1.什么时候进行垃圾回收?

2.如何进行垃圾回收?

3.GC算法

Dalvik虚拟机
ART虚拟机