您的位置:首页 > 职场人生

2017 android面试题总结

2017-12-04 20:52 204 查看

JAVA知识点:

1.malloc是个函数,new是个操作符;都可以初始化对象

2.JAVA的内存结构分为:栈区,堆区,静态区域(方法区)

栈区:栈的读取速度最快,所以保存一些局部变量和小型数据,每个线程都有自己的私有栈

堆区:对象,栈区保存的对象是堆区中的地址,JVM只有一个堆区,且被所有线程共享,存放对象本身和数组本身

静态区:字符常量和一些成员变量,代码

3.Java内存模型中规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了该线程使用到的变量到主内存副本拷贝,线程对变量的所有操作(读取、赋值)都必须在工作内存中进行,而不能直接读写主内存中的变量。不同线程之间无法直接访问对方工作内存中的变量,线程间变量值的传递均需要在主内存来完成

4.JAVA运行内存:

a.堆:是JVM管理的最大的一块内存区域,所有线程共享,是GC管理的主要主要区域,现在主要采用的是分代回收算法,堆可分为年轻代和年老代,年轻代又可细分为Eden,From Survivor,To Survivor

b.方法区:别名Non-Heap ,存储被JVM加载的类信息,静态变量和常量等信息。线程共享

c.程序计数器:是一块较小的内存空间,相当于当前线程所执行的字节码的指示器,如果当前执行一个java方法,计数器记录的就是正在执行的JVM字节码指令的地址,如果是native方法,则为空,此区域是唯一一个没有OutOfMemory的区域

d.JVM栈:线程私有,生命周期和线程同步,主要存放一些局部变量和对象引用等(为执行java方法服务)

e.本地方法栈:和JVM栈相似,不同的是为执行Native方法服务

5.JVM栈,本地方法栈,程序计数器是运行时线程私有的内存区域

6.GC回收算法:

a.标记-清理:标记要回收的内存,统一回收,缺点就是(1)效率低(2)会产生大量不连续的碎片,当碎片太多而需要new一个很大对象时找不到足够的连续内存

b.复制算法: 内存一分为二,每次只使用一半,当一半使用完后,将存活的对象复制到另一半,再将这一半内存回收;缺点是对存活期长久的对象效率会降低

c.标记-整理(压缩):标记过程和标记-清理一样,整理过程是将存活对象向一端移动,然后清理另一端的内存(适合年老代)

d.分代清理:将堆分为年老代和年轻代,对年轻代存活短的特点选择复制算法,对年老代存活期久的特点使用标记-整理算法

7.哈希表:根据关键码值直接进行映射的连续内存的数据结构,有一个映射函数,哈希表也叫散列表。(除留余数法,线性寻址,平方取中
4000


不同的值可能得到同样的地址

8.直接插入算法:稳定算法;从第二个数,保存当前数字,开始向前面的比较,如果小于前面的,前面的就往下挪一格,如果大于则跳出,最后把当前数字插入空出来的地方

9.希尔排序算法:不稳定算法,将数组分为距离为length/2的几个数组,依次用直接插入排序,一轮后length/2,当length为1时跳出循环

10.归并排序:分治算法;将数组分为N组,分别排序再两两合并,合并后的数组再两两排序合并,知道只剩下一个数组

11.快排算法:分治算法;选择一个轴值,一般是中值,然后一分为二,比轴值小的排在左边,大的在右边,对分开的数组再进行这样的操作,知道数组长度小于2

12.稳定算法:归并,直接插入,冒泡,基数排序

13.不稳定算法:快排,希尔,选择,堆排序

Java基础知识复习:

抽象类abstract和interface的区别与联系:(抽象类的主要作用是隐藏类型)

1.abstract中拥有数据成员变量,也拥有飞abstract的成员方法,而且数据成员可以实例化,interface中只有static final的数据成员,必须给定初值

2.一个类只能实现一个abstract,但是可以实现多个interface

JDK=JRE+JVM+一些类库

volley 先创建不同的request请求,然后在onResponse进行网络请求操作,最后添加到队列中Volley.newRequestQueue(this).add(你的request);

okhttp:square公司开源网络请求库,支持http,https,文件下载,加载图片;缺点是callback回来是在线程里面, 不能刷新UI,需要我们手动处理。封装比较麻烦。

volley:谷歌退出的开源网络通信框架,仅支持http,面向接口编程;非常适合数据量不大但是请求频繁的操作,可直接在主线程调用服务端并处理返回结果,可以取消,容易扩展;缺点就是大文件下载支持很糟糕,图片加载性能也比较差;

volley封装更好,简单快捷,okhttp性能优越,难度较大;Retrofit是Square公司出品的默认基于OkHttp封装的一套RESTful网络请求框架

get一般用于查询资源信息,POST一般用于更新资源信息

get方式提交的数据最大为1024字节,POST理论上没有大小限制,理论上是没有的,但是不同的服务器是存在不同限制的

产生死锁的原因主要是:

(1) 系统资源不足

(2) 进程调度不当。

(3) 资源分配不当。

如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则

就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。

产生死锁的四个必要条件:

(1) 互斥条件:一个资源一次只能被一个进程使用。

(2) 请求与保持条件:请求阻塞时,进程拥有的资源不被释放。

(3) 不剥夺条件:进程未运行完前,资源不能被强行剥夺。

(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之

一不满足,就不会发生死锁。

死锁的解除与预防:

理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和

解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确

定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态

的情况下占用资源。因此,对资源的分配要给予合理的规划。

volley分为两个队列,一个是Cache一个是network;如果需要加入Cache队里需要设置shouldcache属性,否则默认为network

Android知识点汇总:

Activity生命周期
1.启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态。
2.当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。
3.当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。
4.当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,然后调用onStop方法,进入停滞状态。
5.用户后退回到此Activity:系统会先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态。
6.当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。
7.用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。

Activity的启动模式,四种方法?
Standard:每次激活activity时都会创建activity实例,放入任务栈(android默认启动方式)
SingleTop:如果栈顶元素是要被激活的组件,则不会创建新的activity放入任务栈,如果不是则创建
SingleTask:如果栈内存在要被激活的组件则不会创建新的,而是将此组件之前的都pop出去,将此组件放在栈顶
SingleInstance:在一个新栈中创建activity实例,多个应用共享,比如(系统的一些界面)拨打电话界面,相册界面等,一个栈只存放一个activity

ListView和RecyclerView的区别?为什么使用RecyclerView,好在哪里?
RecyclerView是ListView控件和GridView控件控件的继承者,所有关于布局、绘制和其他相关的问题,也就是跟数据展示相关的所有问题,都被委派给了一些”插件化”的类来处理。这使得RecyclerView的API变得非常灵活。你需要一个新的布局么?接入另一个LayoutManager就可以了!你想要不同的动画么?接入一个新的ItemAnimator就可以了,诸如此类等等。

项目中BroadcastReceive和Service相关问题

数据库(范式,连接)
第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列。
第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。
第三范式(3NF):首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。

进程和线程的区别:
简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
线程的划分尺度小于进程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.

Override是重写:方法名称、参数个数,类型,顺序,返回值类型都是必须和父类方法一致的。它的关系是父子关系
Overload是重载:方法名称不变,其余的都是可以变更的。它的关系是同一个类,同一个方法名,不同的方法参数或返回值

android内存泄漏:
1.资源型对象比如file,cursor等在使用完后应该调用close()方法区)
2.Bitmap对象不在使用时调用recycle()释放内存
3.handler对象因为是非静态匿名内部类所以持有activity实例,在activity关闭时如果消息队里还有未处理的消息,而消息队列中的Messege又持有handler实例,
这样activity的资源就会得不到及时释放
解决办法(创建一个静态Handler内部类,然后对Handler持有的对象使用弱引用,这样在回收时也可以回收Handler持有的对象。在Activity的Destroy或Stop中移除消息队列中的消息,mHandler.removeCallbacksAndMessages(null);是移除消息队列中所有消息和所有的Runnable。)

4.线程使用造成的内存泄漏,原因和handler差不多,解决办法也差不多
5.当一个activity的context被传递后,关闭此activity,此时就会造成内存泄漏,可以使用全局的静态变量来解决这个问题

Rxjava

广播注册的两种方式,区别,优先级?
Layout的优化的方法
使用过那么多开源框架,有没有看过源代码
service常驻的方法
怎么解析Json
Handle的工作原理和工作过程?(同时还说了Handle会造成内存泄漏的问题)
有没有了解过跨进程通信
static函数和static变量
我的缺点:对自己从事工作存在的困难,自己琢磨的多,向同事或领导请教的少
简单说一下你知道的设计模式,手写单例模式。
Volley底层实现
AsyncTask底层实现
ListView常用优化方法
简单说一下你了解的动画
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: