당신은 OPPO을 몰라! 안드로이드 인터뷰 요약 : 자바 + 안드로이드, 플러스 이해하는 알고리즘

머리말

근처 봄 트릭은, 내가 아니라, 작은 작업의 끝을 활용, 좋은 시간을 인터뷰했다 제조 업체의 영향, 년 후, 준비했다.
안드로이드 개발 기술 제조 업체 OPPO의 인터뷰 요약이 오늘이다 가져왔다.

방법

심천 개발 엔지니어 OPPO 기술 인터뷰, 면접관은 매우 심오한 기본 원칙을 요구하지 않았다, 기초 및 인프라는 자바의 일부는 네 가지 구성 요소는 안드로이드에

이러한 개발 과정의 이론적 기초에 큰 중요성을 첨부하지 않는 경우에, 지식 포인트를 많이 잊어 버리기 쉽습니다.

많은 찾을 수 있습니다 안드로이드 면접 지침서 단순 기억하지 후회에를

공유에 모두를 위해, 저를받을 수에 와서 무료로 나를보기

당신은 OPPO을 몰라!  안드로이드 인터뷰 요약 : 자바 + 안드로이드, 플러스 이해하는 알고리즘

이해 알고리즘도 있습니다

당신은 OPPO을 몰라!  안드로이드 인터뷰 요약 : 자바 + 안드로이드, 플러스 이해하는 알고리즘

인터뷰 과정이 내가있는 그 잊어 버린 지식을 회고 할 수 있도록 한 손에 문제를 가지고 두 개의 인터뷰 덕분에 저에게 힌트를주고, 한 시간 걸립니다, 그것은 또한 당황의 분위기를 완화. . .

OPPO 보안 작업은 여전히 ​​얻을 수있는 임시 패스 신청을 할 필요가 전에 건물의 중앙에, 허우 하이 Zhuo의를 매우 엄격하게 이루어집니다.

또한 당신은 인터뷰 전에 등록해야하고, 휴대 전화의 전면 및 후면 카메라가 실시 인터뷰에 함께 녹화했다.

다음 요약은 기술 면접에 대한 두 부분 지식으로 나누어 져 있습니다.

자바

1, 어떻게 자바의 다형성을 이해하는? 그 중, 과부하와의 차이점은 무엇입니까 다시?

다형성은 여러 가지 상이한 형태 또는 같은 행동의 발현을 할 수있는 능력이며, 다형성 다른 인스턴스를 사용하여 다른 동작이 다형이 프로그램 실행 중에 만 결정 수행 동일한 인터페이스 변수 기준점이되는 것이가는 객체 클래스의 예는, 결국 제조 기준이 가변 메소드 호출 클래스 방법이 실시되는 것이다.

다형성 세 가지 필요 조건이 존재한다 : 상속, 다시, 부모 클래스의 서브 클래스 참조에 대한 참조.

세 다형성 구현은 다음과 같습니다 재 작성, 인터페이스, 추상 클래스와 추상 메소드.

차이 재 작성 (재정의) 무거운 (과부하)의

2 JVM 메모리 구역에 대한 이야기? 비공개 일부가 스레드 대중은 어떤 부분입니까?

지역에 공통적으로 개인 및 지역 스레드와 스레드 : JVM 메모리 영역은 두 가지 범주로 나눌 수 있습니다. 민간 분야 스레드 : 프로그램 카운터, JVM 가상 머신 스택, 네이티브 메소드 스택을 공통 실 면적 : 힙, 메소드 영역, 런타임 상수 풀을.

程序计数器,也有称作PC寄存器。每个线程都有一个私有的程序计数器,任何时间一个线程都只会有一个方法正在执行,也就是所谓的当前方法。程序计数器存放的就是这个当前方法的JVM指令地址。当CPU需要执行指令时,需要从程序计数器中得到当前需要执行的指令所在存储单元的地址,然后根据得到的地址获取到指令,在得到指令之后,程序计数器便自动加1或者根据转移指针得到下一条指令的地址,如此循环,直至执行完所有的指令。

JVM虚拟机栈。创建线程的时候会创建线程内的虚拟机栈,栈中存放着一个个的栈帧,对应着一个个方法的调用。JVM 虚拟机栈有两种操作,分别是压栈和出站。栈帧中存放着局部变量表(Local Variables)、操作数栈(Operand Stack)、指向当前方法所属的类的运行时常量池的引用(Reference to runtime constant pool)、方法返回地址(Return Address)和一些额外的附加信息。

本地方法栈。本地方法栈与Java栈的作用和原理非常相似。区别只不过是Java栈是为执行Java方法服务的,而本地方法栈则是为执行本地方法(Native Method)服务的。在JVM规范中,并没有对本地方发展的具体实现方法以及数据结构作强制规定,虚拟机可以自由实现它。在HotSopt虚拟机中直接就把本地方法栈和Java栈合二为一。

堆。堆是内存管理的核心区域,用来存放对象实例。几乎所有创建的对象实例都会直接分配到堆上。所以堆也是垃圾回收的主要区域,垃圾收集器会对堆有着更细的划分,最常见的就是把堆划分为新生代和老年代。java堆允许处于不连续的物理内存空间中,只要逻辑连续即可。堆中如果没有空间完成实例分配无法扩展时将会抛出OutOfMemoryError异常。

方法区。方法区与堆一样所有线程所共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。在Class文件中除了类的字段、方法、接口等描述信息外,还有一项信息是常量池,用来存储编译期间生成的字面量和符号引用。

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

堆。 通常发生的 OOM 都会发生在堆中,最常见的可能导致 OOM 的原因就是内存泄漏。

JVM虚拟机栈和本地方法栈。 当我们写一个递归方法,这个递归方法没有循环终止条件,最终会导致 StackOverflow 的错误。当然,如果栈空间扩展失败,也是会发生 OOM 的。

方法区。方法区现在基本上不太会发生 OOM,但在早期内存中加载的类信息过多的情况下也是会发生 OOM 的。

3、final关键字的用法?

final 可以修饰类、变量和方法。修饰类代表这个类不可被继承。修饰变量代表此变量不可被改变。修饰方法表示此方法不可被重写 (override)。

4、死锁是怎么导致的?如何定位死锁

某个任务在等待另一个任务,而后者又等待别的任务,这样一直下去,直到这个链条上的任务又在等待第一个任务释放锁。这得到了一个任务之间互相等待的连续循环,没有哪个线程能继续。这被称之为死锁。当以下四个条件同时满足时,就会产生死锁:

  • (1) 互斥条件。任务所使用的资源中至少有一个是不能共享的。

  • (2) 任务必须持有一个资源,同时等待获取另一个被别的任务占有的资源。

  • (3) 资源不能被强占。

  • (4) 必须有循环等待。
    一个任务正在等待另一个任务所持有的资源,后者又在等待别的任务所持有的资源,这样一直下去,直到有一个任务在等待第一个任务所持有的资源,使得大家都被锁住。

要解决死锁问题,必须打破上面四个条件的其中之一。在程序中,最容易打破的往往是第四个条件。

5、数据库如何进行升级?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增删改查:
  • :INSERT INTO table_name (列1, 列2,…) VALUES (值1, 值2,….)

  • : DELETE FROM 表名称 WHERE 列名称 = 值

  • :UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值

  • :SELECT 列名称(通配是*符号) FROM 表名称

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

ALTER TABLE table_name ADD column_name datatype
ALTER TABLE table_name DROP COLUMN column_name

Android

1、Broadcast的分类?有序,无序?粘性,非粘性?本地广播?

广播可以分为有序广播、无序广播、本地广播、粘性广播。其中无序广播通过sendBroadcast(intent)发送,有序广播通过sendOrderedBroadcast(intent)发送。

有序广播

  • (1) 有序广播可以用priority来调整优先级 取值范围-1000~+1000,默认为0,数值越大优先级越高,优先级越高越优先获得广播响应。

  • (2) abortBroadcast()可来终止该广播的传播,对更低优先级的屏蔽,注意只对有序广播生效。

  • (3) 有序广播在传播数据中会发生比如setResultData(),getResultData(),在传播过程中,可以从新设置数据

总的来说,本地广播是通过LocalBroadcastManager内置的Handler来实现的,只是利用了IntentFilter的match功能,至于BroadcastReceiver 换成其他接口也无所谓,顺便利用了现成的类和概念而已。

在register()的时候保存BroadcastReceiver以及对应的IntentFilter,在sendBroadcast()的时候找到和Intent对应的BroadcastReceiver,然后通过Handler发送消息,触发executePendingBroadcasts()函数,再在后者中调用对应BroadcastReceiver的onReceive()方法。

粘性消息:粘性消息在发送后就一直存在于系统的消息容器里面,等待对应的处理器去处理,如果暂时没有处理器处理这个消息则一直在消息容器里面处于等待状态,粘性广播的Receiver如果被销毁,那么下次重建时会自动接收到消息数据。(在 android 5.0/api 21中deprecated,不再推荐使用,相应的还有粘性有序广播,同样已经deprecated)

2、Android中的事件传递机制?

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

调用getWindow.superDispatchTouchEvent()。

如果上一步返回true,则直接返回true;否则return自己的onTouchEvent()。显然,当getWindow.superDispatchTouchEvent()返回true,表示当前事件已经被消费掉,无需调用onTouchEvent;否则代表事件并没有被处理,因此需要调用Activity的onTouchEvent进行处理。

我们都知道,getWindow()返回的是PhoneWindow,因此这句代码本质上调用了PhoneWindow中的superDispatchTouchEvent()。而后者实际上调用了mDecor.superDispatchTouchEvent(event)。这个mDecor也就是DecorView,它是FrameLayout的一个子类。在DecorView中的superDispatchTouchEvent(event)中调用的是super.dispatchTouchEvent()。因此,本质上调用的是ViewGroup的dispatchTouchEvent()。

到这里,事件已经从Activity传递到ViewGroup了。接下来我们分析ViewGroup。

在ViewGroup的dispatchTouchEvent()中逻辑大致如下:

通过onInterceptTouchEvent()判断当前ViewGroup是否拦截,默认的ViewGroup都是不拦截的;

如果拦截,则return自己的onTouchEvent();

如果不拦截,则根据child.dispatchTouchEvent()的返回值判断。如果返回true,则return true;否则return自身的onTouchEvent(),在这里实现了未处理事件的向上传递。

通常情况下,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()中:

如果touchListener不为null,并且这个View是enable的,而且onTouch返回true,都满足时直接return true,走不到onTouchEvent()方法。

否则,就会触发onTouchEvent()。因此onTouch优先于onTouchEvent获得事件处理权。

最后附上流程图总结:

당신은 OPPO을 몰라!  안드로이드 인터뷰 요약 : 자바 + 안드로이드, 플러스 이해하는 알고리즘

3、Handler的原理?

与Handler密切相关的还有Message、MessageQueue、Looper。

Message。Message有两个关键的成员变量:target、callback:

(1) target。就是发送消息的Handler

(2) callback。调用Handler.post(Runnable)时传入的Runnable类型的任务。post事件的本质也是创建了一个Message,将我们传入的这个runnable赋值给创建的Message的callback这个成员变量。

MessageQueue。消息队列用于存放消息,其中重点关注next()方法,它会返回下一个待处理的消息。

Looper。Looper消息轮询器其实是连接Handler和消息队列的核心。想要在一个线程中创建一个Handler,首先要通过Looper.prepare()创建Looper,之后还得调用Looper.loop()开启轮询。

(1) prepare()。这个方法做了两件事:首先通过ThreadLocal.get()获取当前线程中的Looper,如果不为空则抛出RuntimeException。否则创建Looper,并通过ThreadLocal.set(looper)将当前线程与刚刚创建的Looper绑定。值得注意的是,上面的消息队列的创建其实就是发生在Looper的构造函数中。

(2)loop()。这个方法开启了整个事件机制的轮询。其本质是开启一个死循环,不断地通过MessageQueue的next()方法获取消息msg。拿到消息后会调用msg.target.dispatchMessage()来做处理。综上也就是调用handler.dispatchMessage()。

Handler。Handler重点在于发送消息和处理消息。

(1)发送消息。其实发送消息除了 sendMessage 之外还有 sendMessageDelayed 和 post 以及 postDelayed 等等不同的方式。但它们的本质都是调用了 sendMessageAtTime。在 sendMessageAtTime 这个方法中调用了 enqueueMessage。在 enqueueMessage 这个方法中做了两件事:通过 msg.target = this 实现了消息与当前 handler 的绑定。然后通过 queue.enqueueMessage 实现了消息入队。

(2)处理消息。 消息处理的核心其实就是dispatchMessage()这个方法。这个方法里面的逻辑很简单,先判断 msg.callback 是否为 null,如果不为空则执行这个 runnable。如果为空则会执行我们的handleMessage方法。

4、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文件。
5、内存泄露的场景有哪些?内存泄漏分析工具使用方法?
  • 常见的内存泄露有:

  • 单例模式引起的内存泄露。

  • 静态变量导致的内存泄露。

  • 非静态内部类引起的内存泄露。

  • 使用资源时,未及时关闭引起内存泄露。

  • 使用属性动画引起的内存泄露。

  • Webview导致的内存泄露。

메모리 누수 탐지에 관해서는, 일반적으로 사용되는 도구 LeakCanary, MAT (메모리 Analyer 도구), 안드로이드 스튜디오 프로파일 러와 함께 제공됩니다. 온라인 자습서의 많은 자기 검사의 사용에 대한

6. 일반적인 디자인 패턴이 무엇입니까? 당신 여부 책임 패턴의 사슬을 이해?

싱글, 관찰자 ​​패턴, 공장 모드, 빌더 패턴으로 구성 패턴, 중간 모드, 브리지 모드, 어댑터 모드 등이있다.

개요

이제 다시보고 어려운 일이 아니다, 단지 체인 지식과 관련된 많은 세부 사항을 요구하는 질문을 부탁드립니다.

이러한 관점에서 볼, 매일 개발은 재단에 관심을 지불 할 필요가있다.

특히 개발 경험을 1--5 년 안드로이드 개발자는 면접관의 대부분은 기업이 지식, 의사 소통 능력, 요약 능력의 기초가 있는지 여부를 조사한다. 이 인터뷰 노란색이지만, 그러나 결국, 아주 좋은 경험.

BATJ, 바이트 박동 인터뷰 주제, 주제 알고리즘, 하이 엔드 기술 주제, 복합 용도 개발 테마, 자바 인터뷰 주제, 안드로이드, 자바 약간의 지식, 성능 최적화에. .View.OpenCV.NDK 등 스레드, 내 GitHub의에 업로드 된

내 GitHub의 주소를 클릭하십시오https://github.com/Meng997998/AndroidJX 스타 포인트에서 함께 학습

추천

출처blog.51cto.com/14606040/2466826