美文网首页
android题库系列--360

android题库系列--360

作者: 谷哥得小弟 | 来源:发表于2019-03-01 18:06 被阅读6次

    Q:软引用、弱引用区别
      软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。
      弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。

    Q:垃圾回收
    1、那些内存需要回收:
      可以采用引用计数法,有引用就+1,为0的就是没有引用的直接回收,但无法回收两个对象相互引用的情况;这种情况需要使用可达性分析法,当一个对象到GC roots无引用,证明这个对象可以被回收,可以当作gc roots结点的对象有:虚拟机栈、方法区静态属性、方法区静态常量、本地方法栈
    2、什么时候回收:
      一般有几个阶段,新生代(新对象,快速回收)、老年代(老对象、生命周期长)、持久代(存放静态文件、大文件、基本不回收)
    3、如何回收:
      对于新生代,对象容易死亡、存活率低,采用复制算法收集,效率高;对于老年代或者持久代,采用标记-清除算法或者标记整理算法

    gc收集器
    年轻代收集器包括:Serial收集器、ParNew收集器以及Parallel Scavenge收集器
    老年代收集包括:Serial Old收集器、Parallel Old收集器以及CMS收集器。

    Q:多线程:怎么用、有什么问题要注意;Android线程有没有上限,然后提到线程池的上限
      有几种方法可以新开一个线程:继承一个thread,实现一个runable接口,实现一个callable接口;需要注意线程导致的内存泄漏,不要随意新建线程池,尽量复用线程池;Android线程没有上限,但只享有一个进程的资源,所以合适的线程数量很重要,线程池中线程的数量一般CPU核数或者I/O效能有关,那个负债高以那个为标准,比如CPU密集型为n+1; I/O密集型为2n+1;

    Q:锁
    有三种锁机制实现方案,1、synchronized对象锁,自动释放锁 2、ReentrantLock重入锁,需要手动释放锁,lock.lock();// 得到锁 ,lock.unlock();// 释放锁 3、读写锁 ReadWriteLock这个保证读和读不用互斥,提高了效率

    锁机制处理同步时一种悲观策略,因为锁会产生阻塞,一个线程在执行,其他线程必须等待而不能执行其他任务,大大降低了效率,引申出了volatile和CAS,比单纯的锁能提供更高性能的一种共享资源访问机制

    Q:OOM,内存泄漏
    内存溢出OOM,当分配的内存不够加载相关资源时容易导致内存溢出,内存泄漏也是比较容易导致内存溢出的。开发中比较容易出现的地方:
    1、加载大图、微博长图。在某些低端机容易OOM
    2、bitmap大对象使用完没有关闭
    3、文件流使用完没有关闭、广播和服务没有取消注册等
    4、过多的耗时操作没有关闭,访问网络、数据的线程池
    5、滥用上下文

    Q:ANR怎么分析解决
    ANR原因:
    1、主线程阻塞或者进行数据读取
    2、CPU满负荷或者I/O阻塞
    3、内存不足
    4、各大组件生命周期ANR,比如广播onReceive(),输入5秒,前台服务20秒,后台服务60秒

    解决办法:
    根据log日志查找anr类型,复现;
    分析trace.txt 的ANR日志;
    借助DDMS进行分析;

    Q:LinearLayout、RelativeLayout、FrameLayout的特性、使用场景
    LinearLayout用在横向或者纵向控件比较多的时候,效率较高;
    RelativeLayout 执行两次绘制onMesure(),用在子布局有很多控件且布局不规则的时候;
    FrameLayout 使用在需要有视图效果重叠控件的地方比较方便;
    绘制效率:FrameLayout >LinearLayout>RelativeLayout

    Q:如何实现Fragment的滑动
    和viewpager绑定使用,作为一个page 页面;

    Q:ViewPager使用细节,如何设置成每次只初始化当前的Fragment,其他的不初始化
    重写setUserVisibleHint(boolean isVisibleToUser)方法,在里面判断是否对用户可见,如果可见则开始初始化页面,如加载网络数据

    Q:ListView重用的是什么
    主要是针对子view控件的复用,采用ViewHolder当内容contentview不为空时,直接从tag里面取viewholder获取相关控件,不用再次findViewById;

    Q:进程间通信的机制
    android 系统中采用的是Binder,其他方式还有共享内存、管道、文件等

    Q:AIDL机制
    AIDL是一种接口语言,Binder的数据传输过程就是通过AIDL来实现的:
    1、服务端中的Service给与其绑定的客户端提供Binder对象
    2、客户端通过AIDL接口中的asInterface()将这个Binder对象转换为代理Proxy并通过它发起RPC请求
    3、客户端挂起当前线程,并将数据写入data然后调用transact();
    4、服务端调用ontransact()并启动线程池处理请求并返回处理数据,写入reply;
    5、返回调用结果并唤醒客户端

    Q:AsyncTask机制
    AsyncTask内部是通过handler和线程池来实现异步任务的

    Q:如何取消AsyncTask
    1、task.cancel();
    2、在doInBackground和onProgressUpdate中进行检测,如果任务已经取消,则直接退出循环

    Q:序列化
    序列化就是把当前的数据保存下来,这种操作要么就是通过流写入磁盘或者其他介质,这种过程叫做序列化,反之从其他位置获取到内存这个过程称为反序列化;

    Q:Android为什么引入Parcelable
    Serializable的设计初衷是为了序列化对象到本地文件、数据库、网络流、RMI以便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。而Android的Parcelable的设计初衷是由于Serializable效率过低,消耗大,而android中数据传递主要是在内存环境中(内存属于android中的稀有资源),因此Parcelable的出现为了满足数据在内存中低开销而且高效地传递问题。

    Q:有没有尝试简化Parcelable的使用
    Parcelable自动生成代码插件

    Q:项目:拉活怎么做的
    1、提升进程优先级,或者把当前服务提升为前台服务
    2、当锁屏时,生成一个1像素的前台服务
    3、当应用退出时,在接收到应用关闭广播时尝试重新打开应用

    Q:应用安装过程
    应用的安装是由PMS(包管理器)进行管理的,
    1) 拷贝apk文件到指定目录
    在Android系统中,apk安装文件是会被保存起来的,默认情况下,用户安装的apk首先会被拷贝到 /data/app 目录下。
    /data/app目录是用户有权限访问的目录,在安装apk的时候会自动选择该目录存放用户安装的文件,而系统出厂的apk文件则被放到了 /system 分区下,包括 /system/app,/system/vendor/app,以及 /system/priv-app 等等,该分区只有Root权限的用户才能访问,这也就是为什么在没有Root手机之前,我们无法删除系统出厂的app的原因了。
    (2) 解压apk,拷贝文件,创建应用的数据目录
    为了加快app的启动速度,apk在安装的时候,会首先将app的可执行文件(dex)拷贝到 /data/dalvik-cache 目录,缓存起来。
    然后,在/data/data/目录下创建应用程序的数据目录(以应用的包名命名),存放应用的相关数据,如数据库、xml文件、cache、二进制的so动态库等等。

    (3) 解析apk的AndroidManifinest.xml文件
    Android系统中,也有一个类似注册表的东西,用来记录当前所有安装的应用的基本信息,每次系统安装或者卸载了任何apk文件,都会更新这个文件。这个文件位于如下目录:
    /data/system/packages.xml
    系统在安装apk的过程中,会解析apk的AndroidManifinest.xml文件,提取出这个apk的重要信息写入到packages.xml文件中,这些信息包括:权限、应用包名、APK的安装位置、版本、userID等等。
    由此,我们就知道了为啥一些应用市场和软件管理类的app能够很清楚地知道当前手机所安装的所有的app,以及这些app的详细信息了。
    另外一件事就是Linux的用户Id和用户组Id,以便他可以获得合适的运行权限。
    以上这些都是由PackageServiceManager完成的,下面我们会重点介绍PackageServiceManager。

    (4) 显示快捷方式
    这些应用程序只是相当于在PackageManagerService服务注册好了,如果我们想要在Android桌面上看到这些应用程序,还需要有一个Home应用程序,负责从PackageManagerService服务中把这些安装好的应用程序取出来,并以友好的方式在桌面上展现出来,例如以快捷图标的形式。在Android系统中,负责把系统中已经安装的应用程序在桌面中展现出来的Home应用程序就是Launcher了
    2.PackageManagerService的启动过程
    Android系统在启动的过程中,会启动一个应用程序管理服务PackageManagerService,这个服务负责扫描系统中特定的目录,找到里面的应用程序文件,即以Apk为后缀的文件,然后对这些文件进解析,得到应用程序的相关信息。应用程序管理服务PackageManagerService安装应用程序的过程,其实就是解析析应用程序配置文件AndroidManifest.xml的过程,并从里面得到得到应用程序的相关信息,例如得到应用程序的组件Activity、Service、Broadcast Receiver和Content Provider等信息,有了这些信息后,通过ActivityManagerService这个服务,我们就可以在系统中正常地使用这些应用程序了。应用程序管理服务PackageManagerService是系统启动的时候由SystemServer组件启动的,启后它就会执行应用程序安装的过程,因此,本文将从SystemServer启动PackageManagerService服务的过程开始分析系统中的应用程序安装的过程。

    相关文章

      网友评论

          本文标题:android题库系列--360

          本文链接:https://www.haomeiwen.com/subject/zanhuqtx.html