Android技术面经Android

OPPO Android开发技术面总结

2018-10-16  本文已影响572人  affyzh

今天早上参加了深圳OPPO开发工程师的技术面试,总的来说面试过程不是很顺利。面试官并没有问一些很深奥的底层原理,基本都是一些Java基础以及Android四大组件内的基础,但是我自身在开发过程中并没有很重视这些理论基础,导致很多知识点都忘记了。整个面试过程耗时一小时,感谢两位面试官不厌其烦地给我提示,一方面让我能够回想起来那些遗忘的知识点,另一方面也缓解了尴尬的气氛。。。   
  顺便一说,OPPO的保密工作还是做得比较严格的,进去后海卓越中心大楼前需要申请临时通行证才能进去。而在面试前还需要登记,并且把手机的前后摄像头都给用胶带封起来才能进行面试。废话少说,下面分成两部分汇总一下这次技术面试的知识点。

Java

  1. 如何理解Java的多态?其中,重载和重写有什么区别?
    多态是同一个行为具有多个不同表现形式或形态的能力,多态是同一个接口,使用不同的实例而执行不同操作,多态就是程序运行期间才确定,一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法。
    多态存在的三个必要条件是:继承,重写,父类引用指向子类引用。
    多态的三个实现方式是:重写,接口,抽象类和抽象方法。

重写(Override)和重载(Overload)的区别

区别点 重载 重写
参数列表 必须修改 不能修改
返回类型 可以修改 不能修改
异常 可以修改 可以减少或删除,一定不能抛出新的或者更广的异常
访问 可以修改 一定不能做更严格的限制(可以降低限制)
  1. 谈一下JVM内存区域划分?哪部分是线程公有的,哪部分是私有的?
    JVM 的内存区域可以分为两类:线程私有和区域和线程共有的区域。 线程私有的区域:程序计数器、JVM 虚拟机栈、本地方法栈;线程共有的区域:堆、方法区、运行时常量池。

其实除了程序计数器,其他的部分都会发生 OOM。

  1. final关键字的用法?
    final 可以修饰类、变量和方法。修饰类代表这个类不可被继承。修饰变量代表此变量不可被改变。修饰方法表示此方法不可被重写 (override)。

  2. 死锁是怎么导致的?如何定位死锁
    某个任务在等待另一个任务,而后者又等待别的任务,这样一直下去,直到这个链条上的任务又在等待第一个任务释放锁。这得到了一个任务之间互相等待的连续循环,没有哪个线程能继续。这被称之为死锁。当以下四个条件同时满足时,就会产生死锁:
    (1) 互斥条件。任务所使用的资源中至少有一个是不能共享的。
    (2) 任务必须持有一个资源,同时等待获取另一个被别的任务占有的资源。
    (3) 资源不能被强占。
    (4) 必须有循环等待。一个任务正在等待另一个任务所持有的资源,后者又在等待别的任务所持有的资源,这样一直下去,直到有一个任务在等待第一个任务所持有的资源,使得大家都被锁住。
    要解决死锁问题,必须打破上面四个条件的其中之一。在程序中,最容易打破的往往是第四个条件。
    关于如何手写死锁和定位方法,可参考这篇博客

  3. 数据库如何进行升级?SQLite增删改查的基础sql语句?

/**
     * Create a helper object to create, open, and/or manage a database.
     * This method always returns very quickly.  The database is not actually
     * created or opened until one of {@link #getWritableDatabase} or
     * {@link #getReadableDatabase} is called.
     *
     * @param context to use to open or create the database
     * @param name of the database file, or null for an in-memory database
     * @param factory to use for creating cursor objects, or null for the default
     * @param version number of the database (starting at 1); if the database is older,
     *     {@link #onUpgrade} will be used to upgrade the database; if the database is
     *     newer, {@link #onDowngrade} will be used to downgrade the database
     */
    public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
        this(context, name, factory, version, null);
    }

    public SQLiteDatabase getWritableDatabase() {
        synchronized (this) {
            return getDatabaseLocked(true);
        }
    }

  private SQLiteDatabase getDatabaseLocked(boolean writable) {
      .......
      db.beginTransaction();
      try {
              if (version == 0) {
                   onCreate(db);
              } else {
                   if (version > mNewVersion) {
                         onDowngrade(db, version, mNewVersion);
                   } else {
                         onUpgrade(db, version, mNewVersion);
                   }
              }
               db.setVersion(mNewVersion);
                db.setTransactionSuccessful();
              } finally {
                 db.endTransaction();
              }
  }

在SQLiteOpenHelper的构造函数中,包含了一个version的参数。这个参数即是数据库的版本。 所以,我们可以通过修改version来实现数据库的升级。 当version大于原数据库版本时,onUpgrade()会被触发,可以在该方法中编写数据库升级逻辑。具体的数据库升级逻辑示例可参考这里

常用的SQL增删改查

ps:操作数据表是:ALTER TABLE。该语句用于在已有的表中添加、修改或删除列。
ALTER TABLE table_name ADD column_name datatype
ALTER TABLE table_name DROP COLUMN column_name

Android

  1. Broadcast的分类?有序,无序?粘性,非粘性?本地广播?
  1. Android中的事件传递机制?
    当我们的手指触碰到屏幕,事件是按照Activity->ViewGroup->View这样的流程到达最终响应触摸事件的View的。而在事件分发过程中,涉及到三个最重要的方法:dispatchTouchEvent()onInterceptTouchEvent()onTouchEvent。我们的手指触摸到屏幕的时候,会触发一个Action_Down类型的事件,当前页面的Activity会首先做出相应,也就是说会走到Activity的dispatchTouchEvent()方法内。在这个方法内部有下面两个逻辑:

到这里,事件已经从Activity传递到ViewGroup了。接下来我们分析ViewGroup。
在ViewGroup的dispatchTouchEvent()中逻辑大致如下:

通常情况下,ViewGroup的onInterceptTouchEvent()都返回false,表示不拦截。这里需要注意的是事件序列,比如Down事件、Move事件...Up事件,从Down到Up是一个完整的事件序列,对应着手指从按下到抬起这一系列事件,如果ViewGroup拦截了Down事件,那么后续事件都会交给这个ViewGroup的onTouchEvent。如果ViewGroup拦截的不是Down事件,那么会给之前处理这个Down事件的View发送一个Action_Cancel类型的事件,通知子View这个后续的事件序列已经被ViewGroup接管了,子View恢复之前的状态即可。

这里举一个常见的例子:在一个 Recyclerview 中有很多的 Button,我们首先按下了一个 button,然后滑动一段距离再松开,这时候 Recyclerview 会跟着滑动,并不会触发这个 button 的点击事件。这个例子中,当我们按下 button 时,这个 button 接收到了 Action_Down 事件,正常情况下后续的事件序列应该由这个 button处理。但我们滑动了一段距离,这时 Recyclerview 察觉到这是一个滑动操作,拦截了这个事件序列,走了自身的 onTouchEvent()方法,反映在屏幕上就是列表的滑动。而这时 button 仍然处于按下的状态,所以在拦截的时候需要发送一个 Action_Cancel 来通知 button 恢复之前状态。

事件分发最终会走到View的dispatchTouchEvent()中。在View的dispatchTouchEvent()中没有onInterceptTouchEvent(),这里很容易理解,View没有child,也就不存在拦截。View的dispatchTouchEvent()直接return了自己的onTouchEvent()。如果onTouchEvent()返回true代表事件被消费,否则未消费的事件会向上传递,直到有View处理了事件或一直没有消费,最终回到Activity的onTouchEvent()终止。

有时候会有人混淆onTouchEvent和onTouch。首先,这两个方法都在View的dispatchTouchEvent()中:

最后附上流程图总结:

touch事件传递流程
参考:https://juejin.im/entry/58df5b33570c35005798493c
https://juejin.im/post/5b8f15e26fb9a01a031b12d9#heading-3
  1. Handler的原理?
    与Handler密切相关的还有Message、MessageQueue、Looper。
  1. ANR出现的情况有几种? 怎么分析解决ANR问题?
    ANR(Application Not responding)。Android中,主线程(UI线程)如果在规定时内没有处理完相应工作,就会出现ANR。具体来说,ANR会在以下几种情况中出现:
    (1) 输入事件(按键和触摸事件)5s内没被处理
    (2) BroadcastReceiver的事件(onRecieve方法)在规定时间内没处理完(前台广播为10s,后台广播为60s)
    (3) service 前台20s后台200s未完成启动
    (4) ContentProvider的publish在10s内没进行完

分析ANR问题,需要结合Log以及trace文件。具体分析流程,可参照以下两篇文章:
https://www.jianshu.com/p/fa962a5fd939
https://blog.csdn.net/droyon/article/details/51099826

  1. 内存泄露的场景有哪些?内存泄漏分析工具使用方法?
    常见的内存泄露有:

而对于内存泄露的检测,常用的工具有LeakCanary、MAT(Memory Analyer Tools)、Android Studio自带的Profiler。关于用法,网上教程很多,可自行查阅,下面两个经供参考:
三种用法MAT
同时附上官方Android Profiler教程

  1. 如何实现启动优化,有什么工具可以使用?
    重点提到了systrace这个工具,详细用法可以参考下面几篇文章:
    https://blog.csdn.net/Kitty_Landon/article/details/79192377
    https://www.cnblogs.com/baiqiantao/p/7700511.html
    https://blog.csdn.net/xiyangyang8/article/details/50545707
    https://blog.csdn.net/cxq234843654/article/details/74388328
  2. 常用的设计模式有哪些?是否了解责任链模式?
    单例模式,观察者模式,工厂模式,建造者模式,构造者模式,中间者模式,桥接模式,适配器模式等等。

总结

现在回顾一下,问的问题并不难,只是环环相扣问出了很多细节相关的知识点。由此看来,在日常开发中还需要注重基础。尤其对于开发经验是1-5年内的Android Developer,面试官考察的多数是基础知识是否牢固,沟通表达能力,总结能力。虽然此次面试黄了,但不失为一次很好的经历。

上一篇下一篇

猜你喜欢

热点阅读