最近出去找工作了,分享一下我在面试过程中遇到的问题,希望对Android找工作的小伙伴有帮助。
Android事件分发顺序是Activity->ViewGroup->View,都是在dispatchTouchEvent()
方法开始调用。
选用Glide图片加载库,使用单例模式,让应用层那边可以链式调用图片加载库,使用Glide内部加载动画,设置图片是是否加载成功的回调。
使用okhttp实现get、post、文件上传和下载请求、每种请求分两种情况自定义请求的情况和没有自定义请求头的情况。响应类型分为Json和文件类型响应处理,做出统一的错误处理将相关的状态回调给调用网络请求的地方,封装一个基于okhttpClient的网络请求类将网络请求和网络请求响应类关联起来,这样就完成一个okhttp的网络请求类。
rxJava是异步线程库,使用观察者模式实现的,主要是有Observable (可观察者,即被观察者)、 Observer (观察者)、 subscribe (订阅)、事件。订阅subscribe你关心的Observerable对象,你可以对这些对象进行操作和全程监控。
Gilde是根据with方法传入的上下文使用RequestManager请求绑定Activity生命周期,RequestManager类实现LifecycleListener生命周期监听器类,利用一个空白的Fragment获取生命周期同步达到绑定的当前界面的效果。
使用Service,利用广播通知Activity更新界面、DownloadTask下载的异步类,在下载的过程中,利用广播通知Activity修改进度条更新。
ANR全名Application Not Responding, 也就是"应用无响应".
①不要在主线程中做耗时的操作,而应放在子线程中来实现。如onCreate()和onResume()里尽可能少的去做创建操作。
②应用程序应该避免在BroadcastReceiver里做耗时的操作或计算。
③避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。
④service是运行在主线程的,所以在service中做耗时操作,必须要放在子线程中。
①App启动优化,Application的onCreate(特别是第三方SDK初始化),首屏Activity的渲染都不要进行耗时操作,如果有,就可以放到子线程或者IntentService中。
②布局优化,尽量不要过于复杂的嵌套,可以使用
,
,
标签。
③响应优化,过于复杂的布局,UI不要做复杂的运算。
④内存优化,减少图片的大小,对图片先进行压缩处理。
⑤电池使用优化,优化网络请求,关闭使用的定位GPS功能。
⑥网络优化,适当的使用网络缓存,避免不要的流量和重复加载。
内存泄漏是对象没有办法被回收。内存泄漏的原因可能是:
内存溢出称为OOM,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。内存溢出通俗的讲就是内存不够用。
①内存缓存,读取速度最快。
②硬盘缓存(文件缓存),读取速度比内存缓存稍慢。
③网络缓存,读取速度最慢。
Handler是实现线程之间的通信,在整个流程中主要有四个对象分别是Handler,Message,MessageQueue,Looper。当应用创建的时候,就会在主线程中创建handler对象,
我们通过要传送的消息保存到Message中,handler通过调用sendMessage方法将Message发送到MessageQueue中,Looper对象就会不断的调用loop()方法,不断的从MessageQueue中取出Message交给handler进行处理。从而实现线程之间的通信。
GC是垃圾收集算法,核心思想是对虚拟机可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,那么称其为存活对象。如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。垃圾收集算法的选择和垃圾收集系统参数的合理调节直接影响着系统性能。
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”或者“短链接”。
TCP是面向连接的,由于tcp连接需要三次握手,所以能够最低限度的降低风险,保证连接的可靠性。
UDP不是面向连接的,udp建立连接前不需要与对象建立连接,无论是发送还是接收,都没有发送确认信号。所以说udp是不可靠的。
协程是比线程更加轻量的线程,或者称为微线程。使用协程的好处是:当它挂起的时候,它不会阻塞其他线程。协程底层库也是异步处理阻塞任务,但是这些复杂的操作被底层库封装起来,协程代码的程序流是顺序的,不再需要一堆的回调函数,就像同步代码一样,也便于理解、调试和开发。它是可控的,线程的执行和结束是由操作系统调度的,而协程可以手动控制它的执行和结束。
public void bubblingSort(Integer[] arr, int n) {
if (n <= 1) {
//如果只有一个元素就不用排序了
return;
}
for (int i = 0; i < n; ++i) {
// 提前退出冒泡循环的标志位,即一次比较中没有交换任何元素,这个数组就已经是有序的了
boolean flag = false;
// 遍历数组里面的数据
for (int j = 0; j < n - i - 1; ++j) {
if (arr[j] > arr[j + 1]) {
// 设置这两个相邻的数是逆序的,交换
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = true;
}
}
if (!flag){
//没有数据交换,数组已经有序,退出排序
break;
}
}
}
以上就是我出去面试遇到的面试题,希望对小伙伴们有帮助。我已经成功获得offer,投入新工作当中。推广一下我的公众号,我会经常更新一下技术干货或者开发踩坑历程,欢迎大家关注我!