面试总结 一

作者: LiChengZe_Blog | 来源:发表于2019-07-05 00:21 被阅读53次

    最近也去面试了几家公司,现在这个物联网行业这个行情也不是特别的好,也是有点下坡路的感觉。但是工作还是要找的嘛,毕竟我们也是靠这个来吃饭,我们可以在完成工作的同时提高自己,完善自己。希望大家在这个面试旺季都可以找到一个适合自己的工作!接下来步入正题:

    问题:

    1.App启动流程
    2.栈和堆
    3.apk瘦身
    4.Android的四种引用的使用

    解决:

    1.APP启动流程

    这个也是最近面试特别常问到的,对于初级程序员来说:不就是说生命周期嘛,简单。对于初级程序员以上来说:这个东西又问到底层了,好烦啊!从每个阶段来看的角度都是不一样的,接来下我给大家整理一下最近我初步了解的APP的启动流程的步骤:

    ①点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
    ②system_server进程接收到请求后,向zygote进程发送创建进程的请求;
    ③Zygote进程fork出新的子进程,即App进程;
    ④App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
    ⑤system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
    ⑥App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
    ⑦主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。
    ⑧到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面。

    2.栈和堆

    这个问题最近我也是在面试中问到,当时回答的也是很模糊,没有说对底层有特别的了解,在总结的时候我们肯定是要重新了解一下这个栈和堆的关系的,废话少说,上图:


    JVM虚拟机

    堆:
    垃圾回收的主要内存,用来存放实例化的对象以及数组等。
    JVM堆内存分为2块: Permanent Space和Heap Space。
    又分为三代:
    年轻代:包括一个eden和两个survior,往往使用复制垃圾回收算法(Young GC)进行回收。
    年老代:存放生命周期比较长的数据(通过反射产生的class对象),年老代采用标记-清除Gc算法跟标记-整理GC算法(FULL GC)。
    永久代:用来存放静态变量以及通过java反射产生的class对象。

    jvm栈:
    java方法运行时分配的内存,jvm栈会为每个即将运行的java方法分配一个叫帧栈的区域,用来存储方法运行时所需的信息,信息主要包括局部变量表,操作数栈,动态链接以及方法出口信息,线程私有的,生命周期随着线程的创建而创建,随着线程的销毁。
    本地方法栈:
    功能与jvm栈类型,只不过是java本地方法(native关键字修饰的方法,通常比较底层,用于链接操作系统与java)时分配的内存模型。

    3.apk瘦身

    so文件的优化:

    通常我们在使用NDK开发的时候,我们经常会有如下这么一段代码:

    ndk {
    //设置支持的so库架构
    abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64", "armeabi"
    }

    最后我的修改代码如下:

    ndk {
    //设置支持的so库架构
    abiFilters "armeabi-v7a"
    }

    接下来说明这么做的依据:
    看上面图分析,armeabi-v7主要不支持ARMv5(1998年诞生)和ARMv6(2001年诞生).目前这两款处理器的手机设备基本不在我公司的适配范围(市场占比太少)。
    而许多基于 x86 的设备也可运行 armeabi-v7a 和 armeabi NDK 二进制文件。对于这些设备,主要 ABI 将是 x86,辅助 ABI 是 armeabi-v7a。
    最后总结一点:如果适配版本高于4.1版本,可以直接像我上面这样写,当然,如果armeabi-v7a不是设备主要ABI,那么会在性能上造成一定的影响。

    优化res,assets文件大小

    手动lint检查,手动删除无用资源
    在Android Studio中打开“Analyze” 然后选择”Inspect Code…”,范围选择整个项目,然后点击”OK”。

    使用tinypng等图片压缩工具对图片进行压缩。

    打开网址,将大图片导入到tinypng,替换之前的图片资源。

    大部分图片使用Webp格式代替。

    可以给UI提要求,让他们将图片资源设置为Webp格式,这样的话图片资源会小很多。如果想了解更多关于webp,请点击这里webp,当然,如果对图片颜色通道要求不高,可以考虑转jpg,最好用webp,因为效果更佳。

    尽量不要在项目中使用帧动画

    一个帧动画几十张图片,再怎么压缩都还是占很大内存比重的。所以建议是让UI去搞,这里可以参考使用lottie-android,如果项目中动画效果多的话效果更加明显。当然这就要辛苦我们UI设计师大大了。

    . 使用gradle开启shrinkResources

    移除无用资源文件,下面是我的配置:

            release {
                // 不显示Log
                buildConfigField "boolean", "LOG_DEBUG", "false"
                //混淆
                minifyEnabled true
                // 移除无用的resource文件
                shrinkResources true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                signingConfig signingConfigs.release
            }
        }
    

    通过上述步骤操作,又优化了将近5M,别问我为什么还有7.5M,里面大量的gif和webp格式的动图,都是UI丢给我的,一个2.7M.后面再慢慢和他细究这个问题。后面要做的两部分,一部分是将资源文件下的所有gif图放后台下载处理,第二个是和UI讨论下如何减小webp 动图的大小(我看其他平台只有100K的样子,给我的就2.7M)。

    5. 其他

    1.删除无用的语7zip代替
    2.删除翻译资源,只保留中英文
    3.尝试将andorid support库彻底踢出你的项目。
    4.尝试使用动态加载so库文件,插件化开发。
    5.将大资源文件放到服务端,启动后自动下载使用。

    线上项目的版本更新

    大家可以看一下这篇特别好的文章:
    Android 版本更新迭代

    Android的四种引用的使用

    1.强引用
    平时我们编程的时候例如:0 bject ob ject=new0 bject():那 objects就是
    个强引用了。如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾
    回收器绝不会回收它,当内存空间不足,Jawa虚机宁抛出
    Out Of memoryerror错误,使程序异常终止,也不会辞随意回收具有强引用的对象
    来解决内存不足问题
    //创建一个强引用
    String str new Str ing(“hello”)

    2.软引用( Softreference)
    如果一个对象只具有软引用,就类似于可有可物的生活用品.如果内存空间足
    不足了,就会回收这些时的内
    该对象就可以被程序使用、软引用可用来实现内存敏
    口个引用队列( Referencequeue)联合使用,如果软
    用所引用的对象被垃圾回收,ava拟机就会把这个软引用加入到与之关联的引
    用队列中
    //创建一个强引用
    String str= new String(“hello”)
    //创建引用队列:为范型标记,表明队列中存放 String对象的引用
    个弱引用,它引用" hello’对象,井且与rq引用队列关联
    标记,表明 Weakreference会弱引用 Str ing对象
    erence: wf =new Weakreference(str, ra)

    3.弱引用( Weak Reference)
    如果一个对象只具有弱引用,类似于可有可物的生活用品。弱引用与软引用的区别
    只具有弱引用的对象拥有更短的生命周期。在垃圾回收器线程扫描它所管辖的内
    存区域的过程中,一旦发現了只具有弱引用的对象,不管当前内存空间足够与否,都会回
    收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那
    些只具有弱引用的对象。弱引用可以和个引用队列( Referencequeue)联合使用,如
    果弱引用所引用的对象被垃圾回收,ava虚拟机就会把这个弱引用加入到与之关联的引用队列中

    4.虚引用( Phantomreference)
    虚引用顾名思义,就是形同虚设,与建他几种引用都不同,虚引用井不会决定对象的
    生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任问时候都可
    能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。虚引用与软引用和弱引用的
    一个区别別在于:虚引用必须和引用队列( Referencequeue)联合使用,当垃圾回收器准
    回收一个对象时,如果发现它还有成引用,就会在回收对象的内存之前,把这个虚引用加
    入到与之关联的引用队列中,程序可以通过判断引用队列中是否已经加入了虚
    解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经械加入到引用队列
    么就可以在所引用的对象的内存被回收之前来取必要的行动

    相关文章

      网友评论

        本文标题:面试总结 一

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