面试题目

作者: 戴定康 | 来源:发表于2017-06-01 18:03 被阅读164次

    MVC,MVP,MVVM的区别

    • MVC

        软件可以分为三部分
        
        视图(View):用户界面
        控制器(Controller):业务逻辑
        模型(Model):数据保存
        各部分之间的通信方式如下:
        
        View传送指令到Controller
        Controller完成业务逻辑后,要求Model改变状态
        Model将新的数据发送到View,用户得到反馈
        Tips:所有的通信都是单向的。
        
        互动模式
        接受用户指令时,MVC可以分为两种方式。一种是通过View接受指令,传递给Controller。
        
        另一种是直接通过Controller接受指令
      
    • MVP

        MVP模式将Controller改名为Presenter,同时改变了通信方向。
        
        各部分之间的通信,都是双向的
        View和Model不发生联系,都通过Presenter传递
        View非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而Presenter非常厚,所有逻辑都部署在那里。
      
    • MVVM

        MVVM模式将Presenter改名为ViewModel,基本上与MVP模式完全一致。
        
        唯一的区别是,它采用双向绑定(data-binding):View的变动,自动反映在ViewModel,反之亦然。
      

    请解释下在单线程模型中Message,Handler,Message Queue,Looper之间的关系

        Handler是Android官方给我们提供的一套更新UI线程的机制,也是一套消息处理机制,可以通过Handler来处理消息,更新UI等。
    
    
        拿主线程来说,主线程启动时会调用Looper.prepare()方法,会初始化一个Looper,放入Threadlocal中,接着调用Looper.loop()不断遍历Message Queue,
        
        Handler的创建依赖与当前线程中的Looper,如果当前线程没有Looper则必须调用Looper.prepare()。Handler , sendMessage到MessageQueue,Looper不断
        
        从MessageQueue中取出消息,回调handleMessage方法。 
    

    面试题:有没有用过自定义View?

        答:有用过,一般指定View都需要进行这几个步骤,首先可以自定义一些自己的属性,在res/values/attrs.xml里面定义,然后在layout中使用,在View中通过context.obtainStyledAttributes(attrs,R.styleable.自定义属性的名字)进行获取。
        然后在测量onMeasure,一般通过他的三个模式(EXACTLY,AT_MODE,,UNSPECIFIED)进行测量,调用setMeasuredDimension进行传入设置的值。
        接着如果是ViewGroupt 的话我们还需要设置下子View的位置,一般是通过requestLayout去触发onLayout的方法的。
        最后在onDraw里面通过Canvas的一些方法进行绘制。
        如果需要进行触摸事件的话,一般需要有实现onTouchEvent事件,注意,如果需要多点触摸,需要实现ACTION_POINTER_DOWN和ACTION_POINTER_UP进行处理。
    

    怎么启动Service?

        答:有两种启动方式,一种是通过startService进行启动,这个时候Service跟启动的Activity没有关联,只有当调用stopService的
        时候才会结束Service,他的生命周期是:onCreate->onStartCommand->Service Run ->stopService->onDestory();
        如果是通过bindService启动的,那么这个Service就跟启动他的进程有关了,这个时候如果启动他的进程销毁了,那么这个Service也紧
        跟着销毁了或者直接调用unBindService,
        生命周期是:onCreate->onBindService->Service Run->unBindService->onDestory.
    

    面试题:广播的动态注册和静态注册有什么区别?

    静态注册:在AndroidManifest.xml文件中进行注册,当App退出后,Receiver仍然可以接收到广播并且进行相应的处理
    动态注册:在代码中动态注册,当App退出后,也就没办法再接受广播了。
    

    面试题:动画有哪些类型,动画的区别?

    在Android3.0以前,动画有两种类型,一种是补间动画,即tween,他指的是通过自身的变形达到的效果,比如说透明度的变化,放大缩小等,
    还有一种是帧动画,即Frame,是通过一针一针的对图片进行连贯起来播放的,Android3.0的时候定义了一个属性动画,即
    PropertyAnimation,指的是控件的真实移动,就是不断的改变某些属性的值进行的。具体可以通过实现ValueAnimator等类进行实现。
    

    如果后台的Activity由于某原因被系统回收了,如何在被系统回收之前保存当前状态?

    重写onSaveInstanceState()方法,在此方法中保存需要保存的数据,该方法将会在activity被回收之前调用。通过重写
    onRestoreInstanceState()方法可以从中提取保存好的数据
    

    描述一下android的系统架构

        android系统架构分从下往上为linux 内核层、运行库、应用程序框架层、和应用程序层。
    

    简述 android 应用程序结构是哪些

        1)main code
        
        2) unit test
        
        3)mianifest
        
        4)res->drawable,drawable-xxhdpi,layout,value,mipmap
        
        mipmap 是一种很早就有的技术了,翻译过来就是纹理映射技术.
        
        google建议只把启动图片放入。
        
        5)lib
        
        6)color
    

    什么是ANR 如何避免它?

        1). KeyDispatchTimeout(5 seconds) --主要类型按键或触摸事件在特定时间内无响应
        
        2). BroadcastTimeout(10 seconds) --BroadcastReceiver在特定时间内无法处理完成
        
        3). ServiceTimeout(20 seconds) --小概率类型 Service在特定的时间内无法处理完成
    
        答:ANR:Application Not Responding。在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应,当用户
        操作的在5s内应用程序没能做出反应,BroadcastReceiver在10秒内没有执行完毕,就会出现应用程序无响应对话框,这既是ANR。
        
        避免方法:Activity应该在它的关键生命周期方法(如onCreate()和onResume())里尽可能少的去做创建操作。潜在的耗时操作,例如
        网络或数据库操作,或者高耗时的计算如改变位图尺寸,应该在子线程里(或者异步方式)来完成。主线程应该为子线程提供一个
        Handler,以便完成时能够提交给主线程。
    
        1)避免在activity里面做耗时操作,oncreate & onresume
        
        2)避免在onReceiver里面做过多操作
        
        3)避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。
        
        4)尽量使用handler来处理UI thread & workthread的交互。
    

    如何避免 OOM 异常

        首先OOM是什么?
        
        当程序需要申请一段“大”内存,但是虚拟机没有办法及时的给到,即使做了GC操作以后
        这就会抛出 OutOfMemoryException 也就是OOM
        Android的OOM怎么样?
    
        如何避免OOM
        减少内存对象的占用(减少bitmap的内存占用)
        内存对象的重复利用(listView的复用)
    

    ListView的优化方案

    1、如果自定义适配器,那么在getView方法中要考虑方法传进来的参数contentView是否为null,如果为null就创建contentView并返回,
    如果不为null则直接使用。在这个方法中尽可能少创建view。
    
    2、给contentView设置tag(setTag()),传入一个viewHolder对象,用于缓存要显示的数据,可以达到图像数据异步加载的效果。
    
    3、如果listview需要显示的item很多,就要考虑分页加载。比如一共要显示100条或者更多的时候,我们可以考虑先加载20条,等用户拉到列
    表底部的时候再去加载接下来的20条。
    

    屏幕适配的方式:

    xxxdpi, wrap_content,match_parent. 获取屏幕大小,做处理。
    
    dp来适配屏幕,sp来确定字体大小
    
    weight,这是权重的适配。
    AndroidAutoLayout和百分百布局
    

    AsyncTask原理

    AsyncTask是对Handler与线程池的封装

    BroadcastReciver和EventBus区别

    EventBus又是什么鬼呢?EventBus是一个发布 / 订阅的事件总线。
    EventBus通过反射来调用订阅

    事件分发机制

    我们知道事件拦截的顺序,父ViewGroup先接收到拦截,再传递给子ViewGroup 或子View。事件的处理顺序是,子ViewGroup 或子View先处理,若子ViewGroup处理了,父ViewGroup就不用处理,若子ViewGroup未处理,则传给父ViewGroup处理。

    其实当你触摸到控件时,就会调用dispatchTouchEvent方法,以前面点击Button为例,当我们点击该按钮时,应用会去Button的类中寻找该方法,发现没有,就会继续往上找,找到容纳该button的TextView时,发现该类中仍没有该方法,最后继续往上寻找,找到View这时发现了该方法:

    dispatchTouchEvent->onInterceptTouchEvent->onTouchEvent

    首先我们必须了解三个方法

        1.dispatchTouchEvent
        
        2interceptTouchEvent     
        
        3.TouchEvent
    

    下面先介绍第一个:dispatchTouchEvent

    public boolean diapatchTouchEvent

        当返回true //执行自己
        
        返回 false  //执行 onTouchEvent
        
        默认  是执行 interceptTouchEvent
    

    public boolean interceptToouchEvent

        当返回 true  //由他自己的OnTouchEvent处理
        
        返回 false  //继续分发
    

    public boolean OnTouchEvent

        返回  true 自己处理
        
        返回  false  继续传递分发
        
        默认继续传递
    

    在view类中有dispatchTouchEvent和onTouchEvent两个方法

    而ViewGroup是继承View,包含这两个方法,并且还包含onInterceptTouchEvent方法

    从用户点击屏幕开始触发一个系列的点击事件时,事件真正的传递流程是:Activity(PhoneWindow)->DecorView->ViewGroup->View,在到达ViewGroup之前还有一个DecorView,事件是从Activity传过来的,但这些东西其实和ViewGroup的原理是一样的,Activity能看做一个大的ViewGroup,当它的DecorView包含的所有子View没有人能够消耗事件的时候(这样说有漏洞,大家懂我的意思就行了)最后还是会交给Activity处理。

    • 如何不被拦截

      如果ViewGroup的onInterceptTouchEvent(ev) 当ACTION_MOVE时return true ,即拦截了子View的MOVE以及UP事件;

      此时子View希望依然能够响应MOVE和UP时该咋办呢?

      Android给我们提供了一个方法:requestDisallowInterceptTouchEvent(boolean) 用于设置是否允许拦截,我们在子View的dispatchTouchEvent中直接这么写:

    前面我们了解到了我们的View是树形结构的,基于这样的结构,我们的事件可以进行有序的分发。

    事件收集之后最先传递给 Activity, 然后依次向下传递,大致如下:

    Activity -> PhoneWindow -> DecorView -> ViewGroup -> ... -> View

    这样的事件分发机制逻辑非常清晰,可是,你是否注意到一个问题?如果最后分发到View,如果这个View也没有处理事件怎么办,就这样让事件浪费掉?

    当然不会啦,如果没有任何View消费掉事件,那么这个事件会按照反方向回传,最终传回给Activity,如果最后 Activity 也没有处理,本次事件才会被抛弃:

    Activity <- PhoneWindow <- DecorView <- ViewGroup <- ... <- View

    相关文章

      网友评论

      本文标题:面试题目

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