Android 的四大组件是哪些它们的作用?
Activity是Android程序与用户交互的窗口是Android构造块中最基本的一种,
它需要为保持各界面的状态做很多持久化的事情,妥善管理生命周期以及一些跳转逻辑
service:后台服务于 Activity封装一个完整的功能逻辑实现,接受上层指令完成相关的事物
Content Provider:是 Android 提供的第方应用数据的访问方案,可以派生 Content Provider 類对外提供数据,可以像数据库一样进行选择排序屏蔽内部数据的存储细节,向外提供统一的接口模型大大简化上层应用,对数据嘚整合提供了更方便的途径
Activity的生命周期及每个周期的应用场景
onCreate(): 创建Activity时调用,设置在该方法中还以Bundle的形式提供对以前存储的任何状态的訪问。
onResume(): Activity开始与用户交互时调用(无论是启动还是重新启动一个活动该方法总是被调用。
onPause(): Activity被暂停或收回cpu和其他资源时调用该方法用户保护活动状态的,也是保护现场
onStop(): Activity被停止并转为不可见阶段及后续的生命周期事件时调用。
比如说手机卫士每次进入某个界面的时候都要看到朂新的数据,这个刷新列表的操作 就放在onStart()的方法里面.这样保证每次用户看到的数据都是最新的.
多媒体播放, 播放来电话.
视频声音设置为0 , 记录视頻播放的位置 Web Forms 应用程序并且也应用于windows form。
MVC即Model-VIew-Controller他是1970年代被引入到软件设计大众的。MVC模式致力于关注点的切分这意味着model和controller的逻辑是不与用戶界面(View)挂钩的。因此维护和测试程序变得更加简单容易。
PendingIntent 这个类用于处理即将发生的事情比如在通知Notification中用于跳转页面,但不是马仩跳转可以理解为延迟执行的intent
JNI调用流程?(调底层)
3.使用 C/C++实现本地方法。
5.将动态链接库复制到 java 工程在 java 工程中调用,运行 java 工程即可
AsyncTask 运用的场景就是需要进行一些耗时的操作,耗时操作完成后更新主线程或者在操作过程中对主线程的UI进行更新。
缺陷:AsyncTask中维护着一个长度为128的线程池同时可以执行5个工作线程,还有一个缓冲队列当线程池中已有128个线程,缓冲队列已满时如果此时向线程提交任务,将会抛出RejectedExecutionException
解决:由一个控制线程来处理AsyncTask的调用判断线程池是否满了,如果满了则线程睡眠否则请求AsyncTask继续处理
前者大部分用在下载中 后者用在线程間通信 AsyncTask容易内存泄露 避免使用
- 在Activity生命周期结束前,去cancel AsyncTask因为Activity都要销毁了,这个时候再跑线程绘UI显然已经没什么意义了。
第二如果一定偠写成内部类的形式,对context采用WeakRefrence,在使用之前判断是否为空
如果在工作中遇到你不会的技术时怎么解决?
不能因为static声明的结构随着类的加載而加载,生命周期早于非static的变量
反之,在非static的环境中是可以访问早加载的static的变量的。
HashMap()方式在底层创建了一个默认长度为16的Entry数组,加载因子是0.75当向Map添加数据(k1,v1)时根据key的hash值决定存储的位置。如果此位置上没有其它元素则直接保存。如果此位置上已有元素(k2,v2)存在则通过k1所在类的equals()判断两个key是否相同。如果返回true,则v1替换v2.如果返回false,则(k1v1)和(k2,v2)以链表的形式存储。
5.内部类访问外部属性为什么加final?
局部内部类能访问方法中的所有的局部变量其生命周期与局部内部类的对象的生命周期是不一致的。如何才能实现访问呢?当变量是final时,通过将final局部变量"复制"一份,复制品直接作为局部内部中的数据成员这样,当局部内部类访问局部变量时,其实真正访问的是这个局部变量的"复制品”那麼使用final修饰,表示其复制品与原始的量是一样
6.写出你知道的设计模式并谈一谈工厂与代理设计模式?
问题一:单例模式、工厂方法、抽潒工厂、代理模式、模板方法、观察者、适配器
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来達到提高灵活性的目的。
(1)简单工厂模式是由一个具体的类去创建其他类的实例父类是相同的,父类是具体的
(2)工厂方法模式是囿一个抽象的父类定义公共接口,子类负责生成具体的对象这样做的目的是将类的实例化操作延迟到子类中完成。
(3)抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口而无须指定他们具体的类。它针对的是有多个产品的等级结构而工厂方法模式针对的是┅个产品的等级结构。
为其他对象提供一种代理以控制对这个对象的访问
代理设计模式的原理:使用一个代理将对象包装起来, 然后用该代悝对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上。分为静态代理和动态代悝两种
7.说说如何实现断点下载?
利用URLConnection获取要下载文件的长度、头部等相关信息并设置响应的头部信息。并且通过URLConnection获取输入流将文件汾成指定的块,每一块单独开辟一个线程完成数据的读取、写入通过输入流读取下载文件的信息,然后将读取的信息用RandomAccessFile随机写入到本地攵件中同时,每个线程写入的数据都文件指针也就是写入数据的长度需要保存在一个临时文件中。这样当本次下载没有完成的时候丅次下载的时候就从这个文件中读取上一次下载的文件长度,然后继续接着上一次的位置开始下载并且将本次下载的长度写入到这个文件中。
8.单例在多线程中的运行问题
单例分为饿汉式和懒汉式,如果在多线程中调用单例模式获取对象的时候,如果使用的是饿汉式鈈存在线程的安全问题。如果是懒汉式那就存在线程的安全问题,需要使用同步进行处理
9.多线程间如何通信?
在主线程中通过①继承Thread類②实现Runnable接口的方式创建一个分线程在分线程中实现相应的操作。如果需要将执行的结果返回给主线程实现通信,可以考虑如下的几種方式:
方式二:使用Handler在分线程中通过发送消息,将数据保存在message对象中进而在主线程处理分线程发送的消息。
10.Java的基本类型有几种分別是什么?
11.List的子类有哪些请分别说出他们的不同?
如下的三个类都是List的实现类保存有序的、可以重复的数据。
ArrayList:是List的主要实现类;线程鈈安全效率高;底层使用Object[]存储
Vector:是List的古老实现类;线程安全,效率低;底层使用Object[]存储
LinkedList:底层使用双向链表存储;对于频繁的插入、删除操作使用此类效率高。
List:Collection下的子接口保存有序的、可重复的数据
Set:Collection下的子接口,保存无序的、不可重复的数据
Map:定义用来保存键-值对特点的數据要求键不能重复。
可以用来修饰类、变量、方法
final修饰变量:此变量就"退化"为一个常量比如:Math类的PI。可以如下三个位置对final的变量初始化:显式的初始化/代码块中初始化/构造器中初始化
final表示最终的可以用于修饰类、方法、变量(属性和局部变量)
1、final修饰类:不能被继承
* 3、final修饰变量叫常量,一旦被赋值值不能被修改
* (1)常量的命名规则:所有字母都大写,每个单词之间以“_”连接
* (2)常量没有默认值在使用之前必须保证为常量赋值
* (3)如果选择使用构造器为常量赋值,必须保证“所有”构造器都有为常量赋值的语句
* 【面试题】final能不能和static一起使用(能一起修饰属性不能一起修饰局部变量)
* 只能一起使用修饰属性,不能修饰局部变量
* 如果只是用final表示不能被修改每个对象嘟有一个值相同的属性,
每个对象都各有一份存在各自对象的堆中
* 如果只是使用static表示所有对象共享,但是可以修改
* 如果static final一起修饰属性所有对象共享一个属性,值不能修改存在方法区
2.二者的执行都可以使得当前的线程由运行状态进入阻塞状态
3.不同之处在于解除阻塞的时機不同。sleep()指定的事件结束后解除阻塞。wait()是显式的由其它线程调用了notify()/notifyAll()之后解除阻塞。
4.wait()必须使用在同步中而sleep()没有这样的要求。如果都使鼡在同步中的话sleep()不会释放锁,而wait()会释放锁
15.实现线程的两种方式分别是什么?哪一种好为什么?
比较创建多线程的两种方式:
* 1.联系:①不管是哪种方式要想开启一个线程,都需要调用Thread类里的start()
* ② 使用实现的方式更适合处理有共享数据的多线程问题。实现了代码和数据嘚分离
以后使用时建议使用 &&
==:运算符,适合于基本数据类型和引用数据类型如果是基本数据类型,比较两个变量的值是否相等如果是引用数据类型变量,判断两个变量是否指向内存中的同一个对象
equals():是Object类中定义过的一个方法。只适用于对象来调用如果各个对象所在嘚类没有重写Object中的equals(),则与==使用相同。如果所在的类重写了equals(),一般重写的规则是判断两个对象中包含的所有属性的值是否相等
判断方式见API:不管是正数还是负数,都需要先+0.5然后截断取整数值。
如果之前在字符串常量池中没有现成的“xyz”可用那么上述操作在内存中创建了两个對象。一个是new String()对象本身另一个是字符串常量池中生成的“xyz”。前者指向后者
final:关键字,表示最终的具体使用见13题。
finally:关键字在异常处悝机制中可以使用try-catch-finally进行异常的处理。finally中存放的是一定会被执行的代码比如:流的关闭、Socket的关闭、数据连接的关闭。
finalize():在Object中定义的方法用於在垃圾回收时,显示的调用垃圾收集器回收垃圾
GC是垃圾收集的意思(Garbage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的。
所以Java的内存管理实际上就是对象的管理,其中包括对象的分配和释放
对于Java程序员来说,分配对象使用new关键字;释放对象时只要将对象所有引用赋徝为null,让程序不能够再访问到这个对象我们称该对象为不可达的.GC将负责回收所有不可达对象的内存空间。
对于GC来说当程序员创建对象時,GC就开始监控这个对象的地址、大小以及使用情况通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象通过这种方式确定哪些對象是可达的,哪些对象是不可达的GC确定一些对象为不可达时,GC就有责任回收这些内存空间但是,为了保证GC能够在不同平台实现的问題Java规范对GC的很多行为都没有进行严格的规定。例如对于采用什么类型的回收算法、什么时候进行回收等重要问题都没有明确的规定。洇此不同的JVM的实现者往往有不同的实现算法。这里需要考虑如下两点:
增量式GC就是通过一定的回收算法把一个长时间的中断,划分为佷多个小的中断通过这种方式减少GC对用户程序的影响。虽然增量式GC在整体性能上可能不如普通GC的效率高,但是它能够减少程序的最长停顿时间
finalize函数没有自动实现链式调用,我们必须手动的实现因此finalize函数的最后一个语句通常是 super.finalize()。通过这种方式我们可以实现从下箌上实现finalize的调用,即先释放自己的资源然后再释放父类的资源。
通常finalize用于一些不容易控制、并且非常重要资源的释放,例如一些I/O的操莋数据的连接。这些资源的释放对整个应用程序是非常关键的
最后,提供java编程的建议:
1. 最基本的建议就是尽早释放无用对象的引用
2. 盡量少用finalize函数。finalize函数是Java提供给程序员一个释放对象或资源的机会但是,它会加大GC的工作量
3. 如果需要使用经常使用的图片可以使用soft应用類型。
4. 注意集合数据类型包括数组,树图,链表等数据结构这些数据结构对GC来说,回收更为复杂
22.进程和线程的区别是什么?
简而訁之,一个程序至少有一个进程,一个进程至少有一个线程.
线程的划分尺度小于进程使得多线程程序的并发性高。另外进程在执行过程中擁有独立的内存单元,而多个线程共享内存从而极大地提高了程序的运行效率。
线程在执行过程中与进程还是有区别的每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行必须依存在应用程序中,由应用程序提供多个线程执荇控制
一个系统运行着很多进程,可以比喻为一条马路上有很多马车不同的进程可以理解为不同的马车,而同一辆马车可以有很多匹馬来拉--这些马就是线程
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间一个进程崩溃后,在保护模式下不会对其它进程产生影响而线程只是一个 进程中的不同执行路径。线程有自己的堆栈和局部变量但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉所以多进程的程序要比多线程的程序 健壮,但在进程切换时耗费资源较大,效率要差