开局自我介绍。
项目部分:
- 讲一讲RTMP协议(项目中用到了)
RTMP协议是一种实时数据传输协议,底层实现采用TCP协议,是一种设计用来进行实时数据通信的网络协议,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。
建立连接之后通过一些指令,例如set up启动指令,快进指令等等来对其进行控制。 - 为什么要用MVP模式
1 ) 优化代码结构
2 )降低M层跟V层的耦合关系
3) 使开发更加顺畅
其在使用时,P层会持有M层以及V层,此处的V层一般就是activty,M层被P层持有,若M层不销毁,P层也不会销毁,此时V层也不会销毁。导致内存泄漏的出现,一般的解决方案就是在P层销毁时把M层一并销毁了,或者做成软引用。 - 还做了什么项目
- 为什么要用MVVM
1 ) 优化代码结构
2 ) 降低MVP模式中P层过于庞大的情况出现
3 ) 实现V层以及M层的双向绑定
其中主要用到的有三个架构组件:
1) ViewModel:ViewModel负责与Model层交互,并且还需要将Model层的数据以可观察的对象形式提供给View。该层的一个重要实现准则是将它与View分离,即ViewModel不应该知道与之交互的View。
2)Livedata:基于观察者模式的数据变化订阅组件,可以实现消费者订阅生产者,生产者变化后影响消费者。第二个特点时与生命周期强绑定,避免出现内存泄漏问题。
3)dataBinding:数据绑定框架组件,可以实现数据与视图的双向绑定。 - 做过什么优化
1) ListView优化:1、用ViewHolder持有View,减少FindViewById()的时间 2、判断convertView是否存在,减少View.inflate时间。
2) handler内存泄漏优化,用静态内部类写Handler且使用虚引用持有外部view
Java部分:
- 讲一讲四种引用
强引用:正常创建一个对象时都是强引用,发生GC时不会对其进行回收。
软引用:创建对象后用SoftReference引用,正常情况下不会GC回收,只有在要发生OOM时才会发生被GC,一般用来做一些缓存机制。
弱引用:创建对象后用WeakReference引用,发生GC后就会被回收,一般用来做弱持有,若某对象只是偶尔使用,不想让其浪费内存,就可以使用虚引用。
虚引用:“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。”虚引用“主要用于追踪GC回收器的活动。 - 了解什么线程同步的方法
反思:
下次回答相关的比较广的问题,还是要先从是什么、为什么来开始入手,不能直接说结论。要给面试官一种由浅入深,了解很充分的感觉。
线程同步是一种避免在多线程环境下对内存进行修改后出现与预期效果不一致的情况。一般的线程同步方法有加锁,锁一般使用的是synchronize以及reentrantLock,以及volatile关键字。
然后再根据面试官的反应做下一步动作。 - 讲一讲CAS机制
CAS机制是一种确保修改有效的机制,在CAS的一次过程主要有:
1 ) 变量的主存地址存储到线程内存中
2 ) 修改前,比较线程内存与主存地址数据是否一致
3 ) 若一致,修改成功,若不一致,修改失败
- 手写一下两个线程循环打印1-10(太久没写代码,不会,讲了思路)
应该是创建一个对象,用synchronize进行锁,然后双方进行先wait()后notify()操作。
Android部分:
- 活动A启动活动B的生命周期
A:onPauese() -? B:onCreate() -> onstart() -> onResume() -> A:onStop()(根据此时A是否可见) - 什么时候活动A不会进入onStop()
在A活动可见时不会进入onStop()状态,例如活动B只是一个弹窗,没有完全遮挡住A。 - 讲一讲启动模式(详细的讲了一下)
这里是回答的比较好的地方,讲清楚了Task的概念以及创建一个活动之后的详细情况。
- 标准模式(standard):创建活动时,直接创建一个新的Activity到对应的Task,是默认的情况
- 栈顶复用模式(singleTop):创建Activity时,判断该Task的栈顶是否为目的Activity,若是则复用,不是创建新的。适用于通知栏点击启动Activity。
- 栈内复用模式(singleTask):创建Activity时,判断该Task内是否有目的Activity,若有,将其上所有Activity全部弹出,将其放到栈顶,适用于使用比较频繁的Activity,如主页。
- 单例模式(singleInstance):创建Activity时,创建一个新的Task来装载,每次调用时,直接来这个独立的Task取。
当使用singleTop时,app间活动会将TASK叠在另一个TASK上,在返回后台后将所有task归回。singleInstance也是。
- 讲一讲四大组件
这里回答的也不错,大体上将四大组件的比较核心的点都讲了一下。
- 为什么要有ContentProvider
个人回答主要是几点:
1、封装底层数据库格式,能够提供一种统一的数据格式给Android使用,是一种抽象的思想
2、安全,只暴露想要暴露的部分,不想暴露的部分不多加暴露。
3、提供一种跨进程的通信方式。 - 有什么持久化数据方式
这里回答了序列化方式,不知道是对的还是错的。
答案应该是文件存储、数据库存储、sharepeference。
- 有什么存储数据的方式
数据库,sharepeferrence。
- 讲一讲Hanlder机制
这里把所有的情况都讲了,比较基础与熟悉,不再复盘。 - Looeper怎么初始化(忘了)
使用Looper.prepare()来进行。
数据结构与算法
- 如何判断是不是完全二叉树
完全二叉树的概念:一棵树按照层次遍历不能出现有空缺节点,直至遇到结束。
判断方法:
可用层次遍历的思想来做,若下层不为空,但此层出现有空节点,说明不是完全二叉树。
也就是说:当前遍历到了NULL结点,如果后续还有非NULL结点,说明是非完全二叉树。
- 一个100M的文件,内存受限如何去重(稀里糊涂讲了一通)
其他:
为什么要走Android这条路?
反问:
评价一下?
数据结构预算法需要加强,整体还好
什么时候出结果?
7个工作日内
结束。
本次体验比一面好一点,但是一面面的太垃圾了,估计TOPK要挂了。
也让自己明白还有什么不足的地方,继续努力!
全部评论
(1) 回帖