美文网首页
知识复盘

知识复盘

作者: 茴香豆的第五种写法 | 来源:发表于2019-07-10 11:15 被阅读0次
    temp.jpg

    1:熟练使用Android常用性能调优

    1:内存优化
    GC释放对象包含(引用点):java栈中引用的对象;静态方法引用的对象;静态常量引用的对象;Native中JNI引用的对象,Thread。
    内存溢出原因:瞬间申请了大量内存导致OOM;长期不能释放导致超过阈值导致OOM;小范围累积不能释放导致卡顿的OOM。
    优化方式:利用profiler查看堆栈快照,具体查看波动内存是哪里导致的。
    利用leakCanary工具查看生成的dump文件。
    2:UI布局优化
    UI卡顿的情况:View过渡绘制;Layout过于复杂,无法在16ms内完成渲染;View频繁出发measure,layout。
    优化方式:开启GPU过渡绘制工具查看当前布局的绘制情况。
    a:用RealtiveLayout代替LinearLayout
    b:include,ViewStub,merge标签的使用
    3:代码质量优化
    a:使用as自带的unused resource清理无用资源
    b:代码混淆
    4:网络优化
    a:用as自带的profiler进行网络监听。
    ANR产生的原因:
    Activity5s内无响应;广播10s无法处理完;服务service20s无法处理完。
    网络请求中的图片可以用webp格式,质量相同的情况下减少流量。
    优化方式:
    一般多线程可以通过Asynctask处理,可以控制线程的顺序,执行完A后根据A返回的参数执行B线程。
    5:耗电优化
    a:需要进行网络请求时先判断当前的网络状态。
    b:当有wifi和移动网络时候,优先选择wifi比移动网络耗电低。
    c:减少后台任务的唤醒操作。
    6:启动优化
    a:冷启动,杀死进程后启动或程序第一次启动,耗时最久,因为要重新经历application初始化,启动ui线程,创建Activity,导入视图绘制视图等。
    b:暖启动,当activity被销毁,但在内存中常驻时,启动减少了对象的初始化,布局加载等,启动时间短。
    c:热启动,启动时间最短,比如按home键重新回到应用。
    优化方式:Application创建过程尽量少,减少布局层次,启动页预加载等。
    

    2:Java常用设计模式

    单例模式:某个类只能有一个实例,提供一个全局的访问点。避免对象的重复创建,提高资源的有效利用。
    代理模式:为其他对象提供一个代理,以便控制这个对象的访问。
    工厂模式:定义一个创建对象的接口,让子类决定实例化哪个类。
    观察者模式:对象间的一对多的依赖关系。
    

    3:Android常用设计模式(架构)

    MVC:model数据层,view视图层,controller业务逻辑控制层。
    mvc通讯方式,有view通知controller,controller完成处理后重新赋值到model,然后model发送到view。
    MVP:model数据层,view视图层,persenter。view与model不发生联系,通过persenter处理。优点:解耦,提高维护性。缺点:接口和类暴增;当业务逻辑到达一定量时候,Activity类会臃肿;一旦视图变更,persenter也要改动。
    MVVM:viewmodel,伪fragment,跟随Activity的生命周期,data-bingding数据绑定,用retrofit2+rxjava可以直接将返回数据变成一个可观察对象,简化viewmodel。viewmodel不关心具体业务逻辑,只做数据处理响应操作。viewmodel不能持有上下文。
    

    4:AndroidUI,网络,数据库框架

    UI框架,基本上自定义或者使用原生控件,图形图表用MPAndroidChart
    网络框架:okhttp,
    a:okhttpclient实现了Call.Fctory,负责为Request创建Call;
    b:RealCall为Call的具体实现,其enqueue()异步请求接口通过Dispatcher()调度器利用ExcutorService实现,而最终进行网络请求时和同步的execute()接口一致,都是通过getResponseWithinterceptorChain()函数实现
    c:getResponseWithInterceptorChain()中利用Interceptor链条,责任链模式分层实现缓存、透明压缩、网络IO等功能;最终将响应数据返回给用户。
    数据库框架:Room,Greendao。
    属于轻量级orm框架(对象映射型数据库),配合sqlcipher支持加密。GreenDao支持protobuf协议,不需要映射就可以与服务器交互。
    room可以做很好的迁移和升级,编译时检查,减少出错概率。
    

    5:自定义控件

    自定义View:继承View
    基于现有组件:继承View的派生类
    组合方式:自定义控件中包含了其他的组件
    onMeasure:测量View的大小宽高
    根据父View和MeasureSpec加上子view自己的LayoutParams,通过相应的转化规则而得到大小。
    MeasureSpec代表宽度或高度的要求,每个MeasureSpec都包含了size和mode,MeasureSpec的模式主要分为:
    (1)exactly:父容器已经测量出子view的大小,对应view的layoutparams的match_parent。
    (2)at_most:父容器已经限制了view的大小,对应view的layoutParams的wrap_content。
    onLayout:计算显示位置。
    对View进行排版布局,要看父容器,也就是viewGroup。
    onDraw:绘制背景,内容,绘制子view等
    

    6:RecyclerView优缺点

    RecyclerView卡顿情况:布局复杂,多层嵌套,设置setNestedScrollingEnable(false);含视频,滑动到item时加载,item滑出界面释放资源;含图片,图片懒加载(默认图占位)
    RecyclerView4级缓存:
    第一级mChangedScrap匹配position或者id获取holder缓存。
    第二级从mAttachedScrap中通过匹配position获取holder缓存,或者通过childHelper找到隐藏但没有被移除的View,通过getChildViewHolderInt(view)方法获取holder缓存,或者从mCachedViews中通过匹配position获取holder缓存。
    第三级从mAttachedScrap中通过匹配id获取holder缓存,或者从mCachedViews中通过匹配id获取holder缓存。
    第四级从ViewChacheExtension获取holder缓存。
    第五级通过RecyclerView的ViewHolder缓存池获取holder。
    

    7:Http&Socket编程,TCP/IP原理

    TCP:面向连接的,数据顺序,数据正确性,面向字节流。(类似打电话,需要三次握手,4次挥手)
    UDP:面向无连接的,基于数据包的,可能丢包,数据顺序不保证(类似发短信)
    三次握手:
    A:你好我是A。
    B:你好A,我是B。
    A:你好B
    四次挥手:
    A:B啊,我不想玩了。
    B:哦,你不想玩了,我知道了。(这个时候,只是A不想玩了,A不再发送数据,但B可能有未完成的数据,所以需要等待)
    B:A啊,好吧,我也不玩了,拜拜。
    A:好的,拜拜。
    Http和Https区别:
    https是具有安全性的ssl加密身份认证的传输协议,需要到ca申请证书。端口443。
    http是超文本传输协议,信息是明文传输。端口是80,是无状态连接。
    

    8:图片优化,Glide源码

    bitmap占用内存=图片长*图片宽*一个像素点占用的字节数。
    bitmap.config中argb_4444和argb_8888代表一个像素点占用多少位。
    图片压缩方式:
    a:质量压缩,bitmap.compress不会改变图片所在内存大小,改变的是图片所占磁盘大小。
    b:设置图片格式,png无损,jpeg有损,webp有损和无损,体积更小。
    c:采样率压缩inSampleSize宽高压缩。
    d:缩放压缩,减少图片的像素来降低磁盘和内存大小,可用于缩略图。
    e:JNI调用JPEG库。(图片引擎采用skia,去掉了压缩算法导致)
    Glide:
    用法是with().load().into()。用法和pissco一致,是pissco的升级版。
    SupportRequestManagerFragment是一致存在于栈中的fragment。不管上下文是用activity还是application的基本不会造成OOM,LruCache通过键值对形式存储bitmap,通过linkedHashmap保证插入顺序,Gilde可以从LruCache获取图片,从弱引用中获取缓存,从网络请求中获取图片。
    

    9:flutter原理优势,weex对比

    weex和flutter都是write once,run everywhere。
    weex主要分为JS Bridge、Render、Dom。
    JsBridge主要用来和js端实现进行双向通信;Dom主要用于负责dom解析,映射,添加等操作,最后通知UI线程更新。Render负责在UI线程中对dom实现渲染。不支持热重载,不能真机调试,支持热更新。适合单页面快速开发。
    Flutter,基于Dart语言,基于独有的图形引擎Skia,不需要要桥接,不基于webkit,解决比较彻底。
    摒弃JSBridge,Flutter是直接编译成本地代码,用skia渲染展示。热重载hot reload,jsBridge需要build打包。flutter不支持热更新,适合整体app开发。
    

    10:Handle机制(postDelay),postDelay执行时候是什么时候把message添加Queue中的?怎么保证next时候message的唯一性?

    handler不仅仅能将子线程的数据发送给主线程,它试用与任意两个线程间的通信方式。
    在App初始化时候ActivityThread的main方法实现了looper的prepare和loop方法,所有在主线程使用handler时候不需要looper.prepare。
    1:在使用handler时候,handler所创建的线程需要维护一个唯一的Looper对象,每个线程对应一个Looper,每个线程的Looper通过ThreadLocal来保证。Looper对象内部又维护有唯一一个MessageQueue,所以一个线程可以有多个handler,但是只有有一个Looper和一个MessageQueue。
    2:在Message在MessageQueue中不是通过一个列表来存储的,而是将Message存入到上一个Message的next中,取出时候通过顶部的Message就能按放入的顺序依次取出Message。
    3:Looper对象通过loop方法开启一个死循环,不断从Loop的MessageQueue中取出message,然后通过handler将消息传回handler所在的线程。
    handler内存泄漏原因:
    当其他线程持有了该handler,线程没有被销毁,则Activity一直被Handler持有导致无法回收。
    解决方式:
    使用静态内部类+弱引用方式。
    psotDelay(new Runnable())运行在主线程中,因为runnable会在handler所依附的线程中执行,handler是主线程创建,所以自然依附在主线程中。
    为什么loop死循环不会卡死:
    线程是一段可执行的代码,当执行完后线程的生命周期便终止,线程退出。而主线程我们希望一直运行下去,死循环便能保证不会被退出。真正导致卡死主线程的操作是在回调onCreate/onStart/onResume等操作时间过长导致ANR,looper.loop本身不会导致应用卡死。
    handler.postDelay并不是先等待一定的时间再放入到MessageQueue中,而是直接进入MessageQueue,以MessageQueue的时间顺序排列和唤醒的方式结合实现的。使用后者的方式,我认为是集中式的统一管理了所有message,而如果像前者的话,有多少个delay message,则需要起多少个定时器。前者由于有了排序,而且保存的每个message的执行时间,因此只需一个定时器按顺序next即可
    

    11:触摸事件机制?onTouchEvent&onClick&setOnClickLisenter执行顺序?移动过程中move,只需要前5s做拦截后不拦截怎么处理?

    Activity/View处理触摸事件的方法:
    dispatchTouchEvent()
    onTouchEvent()
    ViewGroup触摸事件处理:
    dispatchTouchEvent()
    onInterceptTouchEvent()
    onTouchEvent()
    在activity中当用户屏幕点击了后会先触发dispatchTouchEvent()如果view处理该事件则返回true,事件传递结束。如果返回false则调用onTouchEvent()处理该事件。
    在ViewGroup中ViewGroup的dispatchTouchEvent先判断ViewGroup是否拦截Touch事件,如果拦截了则不向下传递直接调用TouchEvent处理事件,如果没有拦截则遍历所有子view找到点击的那个View把touch事件传递给它。viewgroup的onInterceptTouchEvent方法默认false,viewgroup事件分发都会调用它,一旦onInterceptTouchEvent返回true则表示拦截了事件,后续进行事件分发不再调用onInterceptTouchEvent方法。
    总体优先级 setTouchListener > onTouchEvent > onClick > setClickListener 
    注意:DOWN或UP就是一个事件,不是DOWM+MOVE+UP才是一个事件,加起来是我们称作一系列事件 
    重写onTouchEvent时千万别删了super.onTouchEvent(event)——本人手贱,为此付出过惨痛代价。
    
    待补充!!!!
    --------------------- 
    
    

    12:如何计算View大小&如何对子控件进行布局

    计算View大小:
    view在测量过程和activity生命周期不是同步的,所以在onCreate/onStart/onResume获取view宽高是0。
    在onWindowFocusChanged里面获取。(getMeasuredWidth(),getMesureHeight())
    子View布局:
    可以通过addView方式,infalte布局
    

    13:Binder机制

    进程间通信方案。
    优点:
    1:性能方面,为了省电,Binder相对于传统的Socket方式更加高效,sokect,消息队列都需要2次,共享内存方式一次内存拷贝都不需要,但是实现方式比较复杂。
    2:安全方面,socket通信ip地址容易进行伪造,binder机制支持通信双方做身份校验。
    binder通信4种角色:
    Clinet进程:使用服务的进程;Servie进程:提供服务的进程;ServiceManager进程;Binder驱动:负责建立Binder通信。
    Binder和aidl区别:
    1:他们都是远程调用有关。
    2:Binder是一个对象,继承IBinder对象,AIDL是android提供的接口定义语言。
    3:作用范围不同,如果在一个应用里实现远程调用使用Binder即可,如果是在多应用之间远程通信,则用aidl。
    

    14:LMK机制

    LMK:low memory killer
    内存不足时调用oom,LMK每隔一段时间会检查。
    (1)当系统发现内存不足时候,会执行low memory killer杀进程,并回收内存。
    (2)当app请求一块新的内存空间但发现没有足够空间时候,会执行low memory killer杀进程,收回内存后在进行内存分配。
    

    15:日志记录框架(美团logan)

    logan优点:
    1:采用先压缩后加密的顺序,使用流式加密和压缩,减少cpu使用。
    2:使用AES进行日志加密(对称加密,像RES是非对称加密)确保日志安全。
    3:核心逻辑在c层完成,提供跨平台能力,内存不会在java堆中占用,提高了性能。
    

    16:EventBus原理

    register注册,post发送消息。
    EventBus解耦其实是使用了反射,在register时候会通过反射将信息记录下来。
    观察者模式:通过subscrible订阅消息,Observer观察者。
    源码解析:
    getDefalut()是一个单例方法,保证当前只有一个EventBus实例。
    

    17:AAC框架原理

    AAC:处理UI周期与数据的持久化。
    AAC应用:liveData和viewModel
    liveData需要用到LifeCyclerOwner,可以监听生命周期。
    ViewModel用于存储和管理UI变化的相关数据,横竖屏后仍然可以保存数据,并且不能持有context。
    

    18:插件化

    问题:
    模块间耦合度过大沟通成本高,app方法数超过65535等问题
    解决:
    将一个apk拆分成多个小apk,每个小apk能单独运行。业务模块基本完全解耦。
    1:dex加载原理
    dexClassLoader:可以加载文件系统上的jar、dex、apk。
    PathClassLoader:可以加载/data/app目录下的apk,只能加载已安装的apk。
    2:Android资源加载与管理
    AssetManager、resoures是资源加载与管理的核心类,通过反射调用AssetManager的addAssetPath把插件中的资源加载进来。
    3:四大组件的加载与管理(怎么注册activity?)
    Activity通过proxyActivity进行代理;
    通过Hook系统服务Activity Manager Service绕过清单文件的注册。
    

    19:热修复

    image
    腾讯的tinker和阿里的andfix。
    本地热修复
    1:修改好代码后编译后生成.class文件
    2:用sdk中提供的dx工具将需要替换的.class文件转化成dex。
    3:将.dex文件放入磁盘,创建一个DexClassLoader,通过PathClassLoader遍历出需要修改的dexElements,设值新的参数。
    4:启动时候重新loadFixdex()
    

    20:组件化

    目的:提高代码的复用性。
    使用场景:
    1:业务,需要做一个实时上传位置的功能。
    2:基础lib,百度地图,高德地图。
    3:应用,美团外卖上传位置,美团酒店上传位置。
    

    21:Activity启动过程

    1:通过Launcher启动Activity或者startActivity来启动,都是通过Binder进程间通信进入到ActivityManagerService进程中,并且调用ActivityManagerService.startActivity接口;
    2:ActivityManagerService调用ActivityStack.startActivityMayWait来做准备要启动activity的相关信息;
    3:ActivityStack通知Application Thread要进行Activity启动调度了。
    4:Application Thread不执行真正的启动操作,它通过调用ActivityManagerService.activityPaused接口进入到ActivityManagerService进程中,看看是否需要创建新的进程来启动Activity;
    5:如果是通过Launcher的情况,ActivityManagerService会调用startProcessLocked来创建新的进程,对于startActivity来启动的情况,这一步不需要执行,直接在原来Activity所在的进程中启动。
    6:ActivityManagerService调用Application Thread.scheduleLaunchActivity接口,通知相信的进程启动Activity;
    7:Application Thread把这个启动Activity的操作转发给ActivityThread,ActivityThread通过ClassLoader导入相应的Activity类,然后启动起来了。
    

    22:AMS,PMS源码

    都是属于framework层
    AMS:ActivityManagerService,android内核的核心功能之一,系统在启动SystemService时启动此服务。
    PMS:PackageManagerService
    WMS:WindowManagerService
    

    24:hashmap原理与Hashtable区别,arrayList,LinkedList原理比较

    HashMap是非线程安全的,只试用单线程环境下,实现了Serializable接口,支持序列化,内部维护了一个存储数据的Entry数组,key和value都允许为null。
    HashTable继承Dictionary类,key和value不允许出现null值。
    

    25:单例设计模式的双重校验的目的?去掉第一个判空或第二个判空有啥不同?

    synchronized锁住的是代码段,volatile关键字可以防止jvm对这个变量进行优化,双重校验目的:因为可能会有多个线程一起进入同步块外的if,如果在同步块内不进行二次校验的话就会生成多个实例。
    

    26:工厂模式解决了什么问题?

    工厂模式:把对象的创建放在一个工厂类中,通过参数来创建不同的对象。在新增对象类型的时候,只需要改变工厂方法,减少维护量。
    

    27:retrofit,rxjava原理,okhttp用到了哪些设计模式,连接池的实现原理,rxjava线程切换的原理。

    retrofit:
    通过动态代理生成实现类,使用注解+java接口来定义API接口,Retrofit,create()创建接口动态代理,为接口的每个method创建一个对应的ServiceMethod,并使用这个ServiceMethod对象创建OkhttpCall,并使用ServiceMethod实例的callAdater来调用okhttpCall并返回结果。
    Rxjava原理:
    是一种基于观察者模式的响应式编程框架。Rxjava中线程切换时候可以用subscribeOn(Schedulers.io())或subscribeOn(AndroidSchedulers.mainThread())。线程切换是执行在订阅回调层。
    rxjava线程切换原理:
    待补充。。。
    线程池原理:
    先启动若干数量的线程,并让这些线程处理睡眠状态,当客户端有一个新请求时就会唤醒某一个睡眠线程,让它来处理这个请求,当处理完这个请求,线程又休眠。创建线程池为了统一管理,提高性能。
    

    28:jvm模型,java内存模型,垃圾回收机制,垃圾回收哪个区域,对象在内存哪个区域。

    jvm内存模型:方法区,堆,程序计数器,本地方法栈。
    垃圾回收机制执行:
    1:年老代被写满
    2:持久带被写满
    3:System.gc()被显示调用
    4:上一次gc之后heap的分配策略动态变化。
    对象在内存中的堆里面。JVM所有对象都是在堆中分配内存空间,栈只是保存局部变量和临时变量,如果是对象只保存引用。
    

    29:startService和bindService区别,多次启动调用哪些方法?

    1:生命周期上的区别:
    startService:onCreate-->onStartCommand-->onStop-->onDestory
    bindService:onCreate-->onBind-->unBindService-->onDestroy。
    多次调用startService时service只能被创建一次,每次调用startService,onStartCommand都会执行;
    第一次执行bindService时,onCreate-->onBind都会被调用,多次执行时候,onCreate-->onBind不会多次调用。
    

    30:Activity旋转会调用哪些方法?

    没有任何配置的情况下:
    onPause()--onStop()--onDestroy()--onCreate()--onStart()--onResume();
    

    31:冒泡排序&手写单例

    冒泡:
    public static void main(String){
          int  arry[]={2,3,1,4};
          for(int i=0;i<arry.length-1;i++){
                for(int j=0;j<arry.length-i-1;j++){
                    if(arry[j]>arry[j+1]){
                          int temp=arry[j];
                          arry[j]=arry[j+1];
                          arry[j+1]=temp;
                        }
               }
        }
    for(int num:array){
        syso.print(num);
        }
    }
    单例:
    public class SingleIntence{
          private static volatile SingleIntence intence;
          public static SingleIntence(){
              if(intence==null){
                  synczoid(SingleIntence.class){
                   if(intence==null){
                       intence=new SingleIntence();
                  }
           }
        }
            return intence;
        }
     }
    

    34:java中重载和多态

    重载:
    是内部的方法结构上的不同,同一个Method参数不同,实现同一类型的功能。
    多态:
    1:继承 2:重写(重写父类继承的方法)3:父类引用指向子类对象
    

    35:java中注解

    Annotation。
    在构建过程中生成代码,注解不会出现在编译后的代码中,可以通过反射访问到这些注解。
    一个简单的java注解@Entity,其中@就是告诉编译器是注解,Entiry是注解名,类似@Ovrrived。
    

    37:屏幕适配方案

    传统方案:
    在res下建不同的values文件夹,创建不同的dimens。
    今日头条:
    通过反射适配系统的density(密度)值
    密度=屏幕中1dp所占的多少像素点
    限定符适配:
    smallestwidth,通过宽高限定符,配置在manifast.xml中,程序启动时候读取xml设值。
    

    38:跨进程通信方式(IPC),AIDL原理

    Content Provider
    广播
    Aidl:
    aidl其实就是通过Binder实现的,在定义好aidl文件后,as会生成相关的binder类,aidl并不是必须的文件,因为binder类可以手写出来。
    message,bundle,contentProvider都是通过binder来实现的,只是他们的封装方式不一样。
    Binder
    Intent
    

    41:Android动画

    逐帧动画(放电影,一帧一帧)
    补间动画(控制平移,旋转,缩放等)
    属性动画(升级版的补间动画,支持任意属性的变化)
    SurfaceView实现动画。
    

    42:多线程同步问题,锁lock,syc

    synchronized:可以加载代码快,对象中。是托管给jvm执行的
    lock:需要指定起始位置和终止位置。是java写的控制锁的代码。
    

    43:线程池ThreadPool

    1:线程池管理器(ThreadPool)
    用于创建并管理线程池,包括创建线程池,启动等
    2:工作线程(PoolWorker)
    线程池中线程,在没有任务时处理等待,可循环执行任务。
    3:任务接口(Task)
    每个任务必须实现的接口,供工作线程调度任务的执行。规定了任务的入口,收尾,执行状态等。
    4:任务队列(TaskQueue)
    用于存放没有处理的任务,提供一种缓冲机制。
    

    44:android APT

    Butterknife也是用apt方式。
    通过注解方式编译时生成代码
    

    45:APK安装过程

    复制APK安装包到/data/app目录下,
    解压并扫描安装包,
    向资源管理器注入APK资源,
    解析manifest文件,
    在data/data目录下创建应用数据目录,
    针对dalvik环境优化dex文件,
    保存到dalvik-cache目录,
    将manifest文件解析出的组件权限注册到packgeManagerService并发送广播。
    

    46:invalidate()和postInvalidate()区别

    invalidate会刷新整个View,只能在UI线程中调用。
    postInvalidate,可以在非UI线程中去调用刷新UI,postInvalidate是通过handler将刷新事件通知到handlerMessage中执行invalidate的。
    

    47:Parcelable和Serializable区别

    Parcelable:
    Android提供的,代码多,速度高
    Serializable:
    java自带的,代码量少,速度低
    

    49:匿名共享内存,使用场景

    是什么?
    在Android中,主要提供了MemoryFile这个类来供应用使用匿名共享内存,在android应用程序框架层,提供了一个MemoryFile接口来封装匿名共享内存文件的创建和使用,通过JNI调用底层c++方法。
    使用场景:
    使用Binder在进程间传递数据的时候,有时会报出TransactionTooLargeException这个异常,因为Binder驱动对内存的限制引起的,Binder通常传递数据限制为1M。
    

    50:ContentProvider实现原理,如何进行批量操作?

    ContentProvider可以作为数据访问接口之外,还可以在不同应用程序之间进行数据共享。因为Binder传递数据有大小限制,所以用ContentProvider来处理比较高效。
    ContentProvider必须在Manifest中声明。访问provider需要知道它的URI,所以把provider的URI作为公共常量出来。
    ContentProviderOperation:
    可以批量更新,插入,删除数据。
    ContentProviderOperation.Builder:
    newInsert 插入操作
    newUpdate 更新操作
    newDelete 删除操作
    newAssertQuery 查询没有符合条件的数据
    

    51:广播注册后不注销有什么问题?(内存泄漏)

    广播在onReceiver方法中的参数Context,所以BroadCastReveiver中持有Activity,
    而且广播不仅被Activity持有,可能还被ActivityManagerService等系统服务持有。
    当Activity调用onDestroy方法时候,Activity并不能被回收,从而导致内存泄漏。
    所以需要结束时候调用unregisterReceiver()。
    

    53:BrocastReceive里面可不可以执行耗时操作?

    onReceive()在10s内没有执行完会ANR。
    

    55:Dalvik与ART区别?

    Dalvik是Android虚拟机。dex格式是专为Dalvik提供的压缩格式。
    Dalvik与JVM(java虚拟机)区别:
    Dalvik基于寄存器,jvm基于java字节码。
    Dalvik运行dex文件,jvm运行java字节码。
    Dalvik比jvm占用空间更好,编译速度更快。
    ART:
    Android RunTime,在第一次安装时候,字节码会预编译成机器码,首次执行和启动速度更快。而Dalvik每次运行都会将字节码转换成机器码。
    ART优点:
    性能提升,电池续航能力更长,应用运行更流畅。
    缺点:
    机器码占用存储空间更大,字节码变成机器码后,可能增加包的大小。应用安装时间变长。
    

    56:Android动态权限?各版本差异性?

    5.0
    沉浸式状态栏
    6.0
    动态权限,httpclient删除。
    7.0 8.0 9.0
    更注重耗电和后台优化。将bitmap中的像素点放在native层等。
    

    57:ViewPager如何判断左右滑动?

    监听addOnPageChangeListener(),当屏幕触摸时候先调用onPageScrolled,position等于Viewpager当前下标,向左滑=当前position,向右滑=position-1。
    

    59:Asset目录与res目录的区别

    Asset:文件路径+文件名,能获取子目录下的资源。
    res: R.XX,不能获取子目录下的资源。
    

    60:Application在多进程下多次调用onCreate()吗?

    当manifest中配置了service,应用启动时候可能多次调用onCreate()。
    解决办法:
    在oncreate中获取进程名称,在不同的进程中进行不同的初始化即可。
    

    61:FragmentPageAdater和FragmentStateAdapter区别?

    FragmentPageAdater:fragment对象会一直在内存中,适用于少数的page情况。
    FargmentStateAdapter:默认保存三个fragment,上一个当前的和下一个,一起对象的fragment会被销毁,但是在执行ondestroy时先调用onSaveInstenceState()来保存Fragment的状态,当fragment执行oncreate时候再把Bundle中的值取出来,比较适合多页面。
    

    62:SurfaceView和View

    SurfaceView的绘制方式效率非常高,继承自View,但是SurfaceView不需要重绘应用程序的窗口。
    View通过刷新来重绘视图:
    普通视图(子元素,局部刷新)的重绘都是会导致整个视图结构重绘一次。
    

    63:AsyncTask异步任务

    更新UI操作必须在主线程进行,下载图片,文件,网络请求需要在子线程进行,可以用handler机制。
    Asynctask:
    对线程和Handler进行了封装,可以直接对UI进行更新操作。
    1:onPreExecute():执行在后台下载操作之前,与现行在主线程中。
    2:doInBackground:核心方法,运行在子线程中
    3:onPostExecute():后台下载完成后回调,运行在主线程中。
    4:onProgressUpdate():在下载操作中调用publicProgress用于更新下载进度,运行在主线程中。
    

    64:Servie&IntentService

    Servie不能做耗时操作
    IntentService继承自service,可以做后台下载等耗时操作。
    

    65:Android强软弱虚引用的应用场景

    1:强引用,定义的常量属于强引用,内存不足OOM时候也不会去回收该对象。
    2:软引用,内存足够就不回收,不足是进行回收
    3:弱引用,比软引用生命周期更短,只要被垃圾回收器线程发现,就会被回收。
    4:虚引用,任何时候都可能会回收。
    

    66:混淆的优点和使用场景(注解类)

    nimifyEnabled true开启混淆
    优点:
    1:增加对apk反编译的困难性
    2:减少apk体积
    注意:
    1:避免混淆Android基本组件,避免混淆get/set方法,避免混淆枚举类,序列化类等。
    

    67:保证service不被杀死

    在应用程序结束时候启动一个1像素的activity。
    

    68:加速启动Activity

    1:减少主线程的阻塞时间
    2:提高Adater的效率
    3:优化布局文件
    4:使用profiler观察Activity内存网络情况。
    

    70:equals与==区别

    equals:比较的是两个对象是否相等
    ==:比较的是栈内存中的值
    

    71 : try catch fianlly ,try里有return,finally还执行吗?

    try里面有return也会执行finally,如果try里面报错会执行catch,最终还是执行finally。
    

    72 : String,StringBuffer,StringBuilder区别

    StringBuffer:
    解决拼接字符串问题,append和add方法,属于线程安全。
    StringBuilder:
    在单线程操作字符串情况下使用StringBuilder。线程不安全。
    String:
    不经常发生变化的场景使用String。
    

    74:方法锁,对象锁和类锁的意义和区别

    方法锁:
    当方法被synchronized修饰后,该方法一旦执行就会占用该锁,其他方法调用该方法时候被阻塞,直到这个锁被释放。
    对象锁:
    方法锁也叫对象锁,方法锁针对一个方法,对象锁针对一个代码快。
    类锁:
    synchronized修饰的静态方法,该类实例化对象共用一把锁,概念上的东西,不存在的。
    

    75:java反射

    反射:
    对于任意一个类,都能得到它的属性和方法。通过setAccessible(true),可以得到私有属性
    

    76:android安全性,防止抓包(公钥,指纹码),sslFactory,res非对称加密

    安全性,可以通过混淆代码形式。
    防止抓包,可以通过指纹码或者公钥证书,配合okhttp里面的sslFactory做防止中间人攻击。
    res:服务端提供公钥,根据公钥对密码进行加密后传递给后台(每次值不一样,非对称加密),后台根据私钥解密出信息。
    

    78:加壳原理(爱加密)

    20190506114334.png

    79:fragmentation框架(好用的第三方框架推荐)

    单Activity+多Fragment设计。
    1:方便查看栈信息。
    2:支持懒加载
    3:支持滑动退出fragment
    4:继承supprotActivity
    

    80:IO操作(断点续传原理)

    RandomAccessFile:
    支持对随即访问文件的读写。
    

    81:androidX和support-v7

    v4:
    包含了基本的Fragment,ViewPager等
    v7:
    包含了v4的全部内容,新的控件和新的动画等。
    v13:
    针对平板。
    androidX:
    support库越来越臃肿,不便于维护,代码体积过大。as可以自带切换androidX。
    

    84:wait() 和 sleep() 的区别?

    wait:线程睡眠时,释放对象锁,其他线程可以访问。
    sleep:线程睡眠时,仍然占有该锁,其他线程无法访问。
    

    85:滑动不流畅怎么处理?50fps 有什么办法可以提高到 60fps?

    60fps是每秒屏幕更新60次。
    开启手机配置强制cpu加速
    

    86:int、Integer有什么区别?

    Integer是int的包装类,默认是null;int是基本数据类型,默认值是0;
    

    87:android四种启动模式

    1:standard标准模式:
    每次启动都会重新创建一个新的实例入栈,不管之前是否存在。
    2:SingleTop:
    栈顶复用模式,如果Activity处于栈顶,则不再创建新的activity,如果不存在栈顶则重新创建实例。
    3:SingleTask:
    栈内复用模式,当需要创建这个activity时,如果activity已经存在则将所有的在它之上的activity销毁,让它处于栈顶。
    4:singleInstance:
    单实例模式,具有此模式的Activity单独位于一个任务栈中。只能有一个实例。
    

    88:SharedPrefrence原理,能否夸进程,如何实现?

    SharedPrefrence是基于xml实现的一种数据持久化手段。
    SharedPrefrence不支持多进程。
    SharedPrefrence的commit与apply一个是同步一个是异步。
    SharedPrefrence不要存储过大数据。
    

    89:消息推送原理,如何实现心跳连接?

    1:轮询,tcp三次握手,4次挥手,比较耗电耗时。
    2:心跳包,单次心跳不需要拆除tcp连接。
    AlarmManager:全局定时闹钟,定时执行任务,cpu可以正常的休眠,执行任务时才唤醒cpu。
    通过消息循环
    

    90:敏捷开发scrum与传统开发

    敏捷开发(结果不确定性):
    1:响应计划高于遵循计划,随时可变优先级。
    2:每日站会,需求评审会,迭代计划会,迭代回顾会。
    3:需求通过故事点拆分,业务尽量不能交叉
    4:燃尽图
    瀑布模式:
    需求->架构->编码->测试。不可回滚,可控性强。
    

    91:是否看过Android源码

    Logcat:
    1:位于system/cor/logcat目录下
    

    92:如何优化多个网络请求过慢导致界面长时间等待的情况

    采用分模块加载,区域性loadng方式,提高交互体验。
    

    93:webView加载h5的优化,webView内存泄漏是否了解。

    页面加载速度优化:
    1:选择合适的浏览器缓存机制
    2:常用资源预加载,常用JS本地化及延迟加载,放在本地加载。
    导致内存泄漏:
    系统在attachTowindow和detachFromWindow处进行注册和反注册component callback导致。
    封装自己的webView,不再xml中声明,在代码中直接new WebView,传入Application的上下文防止acitivty被滥用。
    WebView webView =  new WebView(getContext().getApplicationContext());
    webFrameLayout.addView(webView, 0);
    

    95:A启动B时activity的两个activity生命周期的流程。

    A启动:
    Aactivity oncreate  onstart onResume
    A进入B:
    Activity onPause  BActivity oncrete onstart onResume Activity onStop
    B返回:
    Bctivity onPause Activity restart  start onResume Bactivity onStop ondestroy
    A返回:
    Activity onPase onstop ondestroy
    

    96:如何监听activity是否后台切换到前台?不是在onReusme()中处理。

    1:ActivityManager中处理:
    getRunningTasks返回一个list集合,通过getClassName获取在前台的Activity。
    2:OnResume中和onPause中记录一个变量。
    

    98:两个进程如何使用binder进行双向通信?

    aidl
    

    99:如何监测普通对象是否泄漏,leakcanary在dump时卡顿厉害,这里如何优化?

    增加debug和relase时候的不同依赖。在relase时候不进行监测。
    

    100:对app架构的理解

    1:可靠性
    2:安全性
    3:可扩展性
    4:可定制行
    5:可维护性
    6:用户体验
    。。。
    

    101:PathClassLoader和DexClassLoader区别

    PathClassLoader和DexClassLoader都是Android提供给我们的ClassLoader,都能加载dex
    网上很多文章都说PathClassLoader只能加载已经被系统安装过的apk,DexClassLoader无此限制,然而我自己测试是都可以
    根据art源码来看,两者都继承自BaseDexClassLoader,最终都会创建一个DexFile,不同点是一个关键的参数:optimizedDirectory,PathClassLoader为null,DexClassLoader则使用传递进来的
    然后会根据optimizedDirectory判断对应的oat文件是否已经生成(null则使用/data/dalvik-cache/),如果有且该oat对应的dex正确则直接加载,否则触发dex2oat(就是这家伙耗了我们宝贵的时间!!),成功则用生成的oat,失败则走解释执行
    ps:貌似Q版做了优化,不会再卡死在dex2oat里了
    根据加载外部dex的实验,DexClassLoader会触发dex2oat,而PathClassLoader不会
    

    102:ContentProvider

    使用ContentResolver来获取ContentProvider提供的数据,同时注册ContentObserver监听Uri数据的变化
    

    103:乐观锁和悲观锁

    锁是为了避免自己在修改资源的时候,别人同时在修改,导致同一时间产生两份修改,不知道如何处理的情况而设置的独占资源,避免多个操作同时处理同一资源的技术。
    
    乐观锁:默认为,某个线程在自己处理共享资源的时候,不会出现同一时刻来修改此资源的前提,只在处理完毕,最后写入内存的时候,检测是否此资源在之前未被修改。类似于读写锁的读锁就是乐观锁。
    
    悲观锁:默认为,某个线程在自己处理共享资源的时候,一定会出现同一时刻来修改此资源,所以刚拿到这个资源就直接加锁,不让其他线程来操作,加锁在逻辑处理之前。类似,synchronized关键字,条件锁,数据库的行锁,表锁等就是悲观锁。
    

    104:AIDL

    1、定义 AIDL 是 android Interface Dialog Launguage , 是一个android 接口 对话语言,
    2、作用是 为了实现进程间之间服务的通信。
    3、实现方式, Service Client 和 Service Service 同时 持有一个 AIDL文件,编译的时候, 会自动变成一个可以引用的Binder子类。 Client 绑定服务成功后, 获取这个子类,可以使用里面的方法。 Service 在 onBind 方法里面 返回 这个Binder 类。
    4、内部实现原理 是Binder ,实现了进程之间的通信。
    

    105:线程池

    线程池是用来存放线程的池子,里面的线程可以被重复利用,不浪费。
    创建线程池:用Executors 。
    singleThreadPool单一线程
    fixedThreadPool固定数量的线程池
    scheduleThreadPool周期任务
    cacheThreadPool想建几个就建几个
    

    相关文章

      网友评论

          本文标题:知识复盘

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