记录2021年面试问题(一)

        很长时间没有更新了,在三月末四月初换了工作,一直在忙着复习、面试。入职了新公司之后,有个很着急的项目要做,也一直处在加班的状态,五一其中的两天和周末也没有避免。跟着也考完了驾照。今天来把之前的面试题进行一下简单的整理,做一下记录。有些问题网上的资源比较多,这里就不做解答了(其实也就是懒。。。。)

1、Android 常见内存泄漏原因和解决方法:

        一、未取消注册或者回调造成的内存泄漏:

                比如在项目中用到的广播、EventBus等等需要注册使用的,应该对应的有取消注册的方法,来释放掉内存,取消持有的activity或context的引用。

        二、activity或context等上下文的引用

                比如一个单例模式中,引用了activity,acitivity在销毁时,需要释放腾出内存,但因为单例模式的特性,它的生命周期是和Application一致的,就导致activity依然被引用,无法释放,从而导致内存泄漏。这里可以使用弱引用、软引用或者使用ApplicationContext。

        三、非静态内部类

                内部类有外部类的引用(隐式引用),还是以Activity为例,当一个ActivityA当中存在一个非静态内部类并且ActivityA达到了需要进行回收的条件,其内部类依然持有ActivityA的引用,就导致ActivityA不能被释放回收内存泄漏。使用静态的内部类,就不会持有外部类的引用,也就不会影响到ActivityA的回收释放。

        四、引用的资源没有及时释放

                比如使用的Bitmap、File、Cursor、Handler等。在对这些资源执行完操作之后,要及时关闭清理它们,及时的释放内存。

        五、WebView的内存泄漏

                这解决起来有些繁琐,需要一个新的进程来启动含有WebView的Activity,在销毁时,调用System.exit(0)来退出新进程。

        六、占用内存比较大的对象(图片过大)引起的内存泄漏

                对图片进行等比例缩小、质量压缩、软引用并及时释放资源。

        七、Handler引起的内存泄漏

                创建一个继承Handler的静态内部类,并且把Handler持有的引用对象(类似于Context,Activity)等设置为弱引用。最后在Activity销毁时,要调用Handler.removeCallbacksAndMessages(null);把消息队列清空。

2、activity的几种启动模式和特点,在什么情形下会调用onNewIntent

        Activity的启动模式分为4种,其一:默认模式Standard,这种模式是activity在创建时的默认模式,只要启动activity,那么在栈中就会生成一个新的activity实例;

        其二:SingleTop栈顶复用,在启动该activity时,如果该activity存在于栈顶,不会创建新的activity实例,而是会复用栈顶的activity并且调用onNewIntent方法;

        其三:SingleTask栈内复用,在启动该activity时,只要栈内存在该activity实例,那么就不会创建新的activity实例,复用栈内的该activiy实例,并回调onNewIntent方法;

        其四:SingleInstance单实例,如果没有创建过该activity实例,启动该activity时,会形成一个新的栈,并在新栈中形成唯一的该activity的实例。

3、ActivityA到B到C,回退时是从C到A再到B,为什么?怎么查看原因?ADB查看栈的命令

       这个问题当时没想起来怎么回事,等面试结束了才想明白,唉,只能说脑子当时是秀逗了吗!

这个现象其实很简单,就是把ActivityB的launchMode属性设置成SingleInstance

        adb shell dumpsys activity activities(查看activity调用栈信息的命令)

参考文档:Android——带你从ADB命令行查看Task任务栈的管理方式_David-Kuper的专栏-CSDN博客

4、View的绘制流程,以及在View的绘制过程中出现卡顿的原因有什么?

        主要分为三个阶段:measure,计算大小;layout,设置位置;draw,最终绘制在屏幕上。

        在measure阶段,是根据父View传递的MeasureSpec 来进行计算的,MeasureSpec当中有两个参数size和mode,mode分三种:EXACTLY,已经知道了View的大小,布局当中width和height为match_parent或者具体的数值;AT_MOST,父View限制了该View的大小,布局中为wrap_content;UNSPECIFIED,不限制该View的大小,用到的情况比较少。

        View绘制过程中出现卡顿,以我的理解就是绘制的层级过多,或者绘制过程中出现了内存泄漏

5、AIDL

        AIDL是用来做进程间通信的。参考文档:Android:远程服务Service(含AIDL & IPC讲解) - ,AIDL的使用、传递复杂对象以及回调客户端 -

6、实现一个列表,展示手机中所有的视频,列表包括视频缩略图、名称、时长等内容,需要进行实时刷新,item点击进入视频播放页面,有进度条,进度条可拖拽等常见的视频播放功能(给出思路即可,Media 数据库)。

        参考文档:Media Data之多媒体数据库(二)MediaProvider -

7、一个类A,判断if(A!=null),当调用A中的方法的时候,A.b(),A报出空指针异常,原因?

        这个问题应该是要和下面的第7个问题相关。

8、如何避免同一数据或类对象被同时操作(关于多线程导致数据不一致)

        一、使用synchronized关键字,同步锁,如果一个线程正在访问这个对象,其他线程试图访问该对象时,会被堵塞。

        二、把多线程用线程池来展示,使用线程池来处理对象或者数据,是把对象或者数据交给整个线程池管理。尤其使用Executors.newSingleThreadExecutor()(单线程线程池,用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行)和Executors.newFixedThreadPool(1)(可重用固定个数线程池,以共享的无界队列方式来运行这些线程)

        其余两种线程池:

                Executors.newCacheThreadPool() :(可缓存线程池,先查看池中有没有以前建立的线程,有就直接使用。没有就建一个线程加入线程池。通常用于执行一些生存期很短的异步型任务)

                Executors.newScheduledThreadPool(int n):(定长线程池,支持定时及周期性任务执行)

        三:Thread的join方法。让父线程等待子线程结束之后才能继续运行

9、在项目中常用的动画

        属性动画(Property Animation):对某些属性值进行不断的变化来实现动画效果,主要由ValueAnimator来计算初始值到结束值的过度变化。

        帧动画(Frame Animation):这个比较简单,就是把一张张的图片进行连贯播放。

        补间动画(Tweened Animation):主要是四种动画效果,alpha (透明),translate(位移),scale(缩放),rotate(旋转),一般在res/anim/文件夹下创建xml文件,来达到这几种效果。

        另外补充一点插值器(Interpolator):控制动画的变化速率 ,即动画的快慢节奏。参考文章:几种常用的Interpolator(插值器)的动画效果 - mingruqi - 博客园

10、Android 中常用的分析工具,开发者模式分析(Android的性能优化方案+工具)

        参考文档:Android性能全面分析与优化方案研究—几乎是史上最全最实用的_黄孝果的博客-CSDN博客_android 性能优化

        这里提一下Android4.1.0启用ddms的方法,在cmd中输入命令monitor,或者在Android sdk/tools中有一个monitor.bat文件,双击打开。

        同样文章中提到的hieararchyviewer按照文章中的方法已经无法打开了,还是在ddms窗口中,按照下图指示打开。

11、Activity的启动流程

12、怎么保证在多个不同的异步的网络请求都返回结果后统一处理

RxJava的组合/合并操作符concat、zip、merge等操作符

参考文档:Android RxJava:组合 / 合并操作符 详细教程 -

13、String,StringBuilder,StringBuffer的区别

14、List、Set、Map的区别

你可能感兴趣的:(记录2021年面试问题(一))