安卓面试宝典

本篇文章主要内容为笔者面试安卓岗位面试常问问题,如果要面试安卓相关岗位的同学建议看一下

五大布局:

  1. LinearLayout 线性布局

线性布局是按照水平或垂直的顺序将子元素(可以是控件或布局)依次按照顺序排列,每一个元素都位于前面一个元素之后。线性布局分为两种:水平方向和垂直方向的布局。

  1. TableLayout 表格布局

表格布局,适用于多行多列的布局格式,每个TableLayout是由多个TableRow组成,一个TableRow就表示TableLayout中的每一行,这一行可以由多个子元素组成。

  1. RelativeLayout 相对布局

RelativeLayout继承于android.widget.ViewGroup,其按照子元素之间的位置关系完成布局的,作为Android系统五大布局中最灵活也是最常用的一种布局方式,非常适合于一些比较复杂的界面设计。

  1. FrameLayout 框架布局

将所有的子元素放在整个界面的左上角,后面的子元素直接覆盖前面的子元素,所以用的比较少。

5)AbsoluteLayou 绝对布局

绝对布局中将所有的子元素通过设置android:layout_x 和 android:layout_y属性,将子元素的坐标位置固定下来,即坐标(android:layout_x, android:layout_y) ,layout_x用来表示横坐标,layout_y用来表示纵坐标。

(6)Constraintlayout

ConstraintLayout非常适合使用可视化的方式来编写界面,它可以有效地解决布局嵌套过多的问题,ConstraintLayout则是使用约束的方式来指定各个控件的位置和关系的,它有点类似于RelativeLayout,但远比RelativeLayout要更强大。

Activity生命周期:

OOM内存泄漏:

如果说这个对象已经不会再被使用到了,是无用的,我们依然持有他的引用的话,就会造成内存泄漏,例如 一个长期在后台运行的线程持有 Activity 的引用,这个时 候 Activity 执行了 onDestroy 方法,那么这个 Activity 就是从根节点可到达并且无用的对象, 这个 Activity 对象就是泄漏的对象,给这个对象分配的内存将无法被回收。

 

 

 

 

 

单例模式造成的内存泄漏

由于单例的特性使得单例的生命周期和应用的生命周期一样长。如果一个对象已经不需要使用了,而单例对象还持有该对象的引用,那么这个对象将不能被正常回收,导致内存泄漏

如果传入的是Application的Context没有任何问题,因为单例的生命周期和Application的一样长。如果传入的是Activity的Context,当这个Context对应的Activity退出时,但是单列对象持有当前Activity的引用,导致Activity无法被回收,从而导致内存泄漏。

Handler造成的内存泄漏

这种创建Handler的方式会造成内存泄漏,由于mHandler是Handler的非静态匿名内部类的实例,持有外部类Activity的引用。消息队列是在一个Looper线程中不断轮询处理消息,如果当前Activity退出时消息队列中还有未处理的消息或者正在处理消息,而消息队列中的Message持有mHandler实例的引用,而mHandler又持有Activity的引用,导致Activity的内存资源无法回收,引发内存泄漏。

线程造成的内存泄漏

线程使用Runnable匿名内部类,因此它们对当前Activity都有一个隐式引用。如果Activity在销毁之前,任务还未完成, 那么将导致Activity的内存资源无法回收,造成内存泄漏。

非静态内部类造成的内存泄漏

非静态内部类默认会持有外部类的引用,如果使用了该非静态内部类创建了一个静态的实例, 该静态实例的生命周期和应用的一样长,这就导致了该静态实例一直会持有该Activity的引用,导致Activity的内存资源不能正常回收,造成内存泄漏。

 

1.使用缓存技术,比如LruCache、DiskLruCache、对象重复并且频繁调用可以考虑对象池

2.对于引用生命周期不一样的对象,可以用软引用或弱引用SoftReferner WeakReferner

3.对于资源对象 使用finally 强制关闭

4.内存压力过大就要统一的管理内存

ANR问题:

输入事件(按键和触摸事件)5s内没被处理

BroadcastReceiver的事件(onRecieve方法)在规定时间内没处理完(前台广播为10s,后台广播为60s)

service 前台20s后台200s未完成启动 Timeout executing service

ContentProvider的publish在10s内没进行完

 

实现原理:

1.在进行相关操作调用hander.sendMessageAtTime()发送一个ANR的消息,延时时间为ANR发生的时间(如前台Service是当前时间20s之后)。2.进行相关的操作3.操作结束后向remove掉该条message。如果相关的操作在规定时间没有执行完成,该条message将被handler取出并执行,就发生了ANR。

 

  1. 主线程在做一些耗时的工作
  2. 主线程被其他线程锁
  3. cpu被其他进程占用,该进程没被分配到足够的cpu资源。

 

  1. 避免主线程读取数据
  2. 不要在broadcastReciever的onRecieve()方法中干活
  3. 各个组件的生命周期函数都不应该有太耗时的操作
  4. 尽量避免主线程的被锁的情况

 

 

 

 

Activity的启动模式?

standard: 标准模式,一调用 startActivity()方法就会产生一个新的实例。

singleTop: 如果已经有一个实例位于 Activity 栈的顶部时, 就不产生新的实例, 而只是调用Activity 中的 newInstance()方法。如果不位于栈顶,会产生一个新的实例。

singleTask: 会在一个新的 task 中产生这个实例,以后每次调用都会使用这个,不会去产生 新的实例了。

 

 

基本算法:

 

1.冒泡排序

相邻的数据进行两两比较,小数放在前面,大数放在后面,这样一趟下来,最小的数就被排在了第一位,第二趟也是如此,如此类推,直到所有的数据排序完成。

2.选择排序

先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

3.插入排序

将数据分为两部分,有序部分与无序部分,一开始有序部分包含第1个元素,依次将无序的元素插入到有序部分,直到所有元素有序。插入排序又分为直接插入排序、二分插入排序、链表插入等,这里只讨论直接插入排序。它是稳定的排序算法,时间复杂度为O(n^2)。

4.快速排序

 

快速排序是目前在实践中非常高效的一种排序算法,它不是稳定的排序算法,平均时间复杂度为O(nlogn),最差情况下复杂度为O(n^2)。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

 

5..归并排序

 

归并排序具体工作原理如下(假设序列共有n个元素):

 

将序列每相邻两个数字进行归并操作(merge),形成floor(n/2)个序列,排序后每个序列包含两个元素

 

将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素

 

重复步骤2,直到所有元素排序完毕

 

归并排序是稳定的排序算法,其时间复杂度为O(nlogn),如果是使用链表的实现的话,空间复杂度可以达到O(1),但如果是使用数组来存储数据的话,在归并的过程中,需要临时空间来存储归并好的数据,所以空间复杂度为O(n)。

 

5.堆排序

 

先将初始数据R[1..n]建成一个最大堆,此堆为初始的无序区

 

再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key

 

由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。

 

重复2、3步骤,直到无序区只有一个元素为止。

 

 

 

 

 

 

 

 

对封装、继承、多态、抽象的理解

  封装:是面向对象方法的重要原则,就是把对象的属性和行为(数据)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节,就是把不想告诉或者不该告诉别人的东西隐藏起来,把可以告诉别人的公开,别人只能用我提供的功能实现需求,而不知道是如何实现的。增加安全性

       继承:是面向对象最显著的一个特性,继承是从已有的类中派生出新的类称为子类,子类继承父类的数据属性和行为,并能根据自己的需求扩展出新的行为,提高了代码的复用性。

  多态:指允许不同的对象对同一消息做出相应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用)。封装和继承几乎都是为多态而准备的,在执行期间判断引用对象的实际类型,根据其实际的类型调用其相应的方法。

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值