From eb80e3a3d0114064d26ca8ffdd4e3b2d6d789edc Mon Sep 17 00:00:00 2001 From: cdevelopr Date: Fri, 22 Mar 2019 11:56:07 +0800 Subject: [PATCH] modify name: cdevelopr -> DLonng --- README.md | 188 +++++++++++++++++++++++++++--------------------------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/README.md b/README.md index e72fd65..2ad3314 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ - 一个双向链表首先是一个链表,但是在每个结点中有两个指针,前驱指针指向前驱结点,后继指针指向后继结点。双向链表也有一个头结点,头结点的后继指针指向第一个结点。最后一个结点的后继指针指向空,但是如果最后一个结点的后继指针指向第一个结点,这时称这个链表为双向循环链表。双向循环链表能非常方便地从每个结点查找它的前驱结点和后继结点。 ![双向链表](https://upload.wikimedia.org/wikipedia/commons/thumb/5/5e/Doubly-linked-list.svg/610px-Doubly-linked-list.svg.png) - + | 算法 | 平均 | 最坏 | |:------------:|:----:|:----:| | 空间 (Space) | O(n) | O(n) | @@ -150,7 +150,7 @@ > 贪心算法与动态规划的不同在于它对每个子问题的解决方案都做出选择,不能回退。动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能。 > > 贪心法可以解决一些最优化问题,如:求图中的最小生成树、求哈夫曼编码……对于其他问题,贪心法一般不能得到我们所要求的答案。一旦一个问题可以通过贪心法来解决,那么贪心法一般是解决这个问题的最好办法。由于贪心法的高效性以及其所求得的答案比较接近最优结果,贪心法也可以用作辅助算法或者直接解决一些要求结果不特别精确的问题。 -> +> @@ -160,13 +160,13 @@ - 解释一下 OOP 的概念 - 面向对象编程是使用类,对象,[继承性](https://zh.wikipedia.org/wiki/%E7%BB%A7%E6%89%BF_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6)),[多态性](https://zh.wikipedia.org/wiki/%E5%A4%9A%E5%9E%8B_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6)),[封装性](https://zh.wikipedia.org/wiki/%E5%B0%81%E8%A3%9D_(%E7%89%A9%E4%BB%B6%E5%B0%8E%E5%90%91%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88))和[抽象](https://zh.wikipedia.org/wiki/%E6%8A%BD%E8%B1%A1%E5%8C%96_(%E8%A8%88%E7%AE%97%E6%A9%9F%E7%A7%91%E5%AD%B8))的一种程序设计方法。。 - + 1. 抽象 - + > 在面向对象的概念中,所有对象都是由类来描述,但是反过来,并不是所有类都是用来描述对象的。如果一个类中没有包含足够信息来描绘一个具体的对象,这样的类就是抽象类。 - + 2. 继承 - + >继承(英语:inheritance)是面向对象软件技术当中的一个概念。如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”。继承可以使得子类别具有父类别的各种属性和方法,而不需要再次编写相同的代码。在令子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能。另外,为子类别追加新的属性和方法也是常见的做法。 一般静态的面向对象编程语言,继承属于静态的,意即在子类别的行为在编译期就已经决定,无法在执行期扩充。 有些编程语言支持多重继承,即一个子类别可以同时有多个父类别,比如C++编程语言;而在有些编程语言中,一个子类别只能继承自一个父类别,比如Java编程语言,这时可以利用接口来实现与多重继承相似的效果。 现今面向对象程式设计技巧中,继承并非以继承类别的“行为”为主,而是继承类别的“型态”,使得元件的型态一致。另外在设计模式中提到一个守则,“多用合成,少用继承”,此守则也是用来处理继承无法在执行期动态扩充行为的遗憾。 @@ -176,18 +176,18 @@ > 从字面上理解就是包装的意思,是指利用抽象数据类型,将数据和关于数据的操作封装起来,使其成为一个不可分割的独立实体。数据将会被保护在抽象数据类型的内部,仅能够通过暴露在表面的操作(public方法,比如setter和getter)来与这个对象进行交流和交互。用户不知道对象的内部细节,但是通过该对象提供的接口来访问对象。其好处是:减少耦合,方便地在未来修改调整自己,更加有把握地(精确地)控制成员,隐藏信息,实现细节。 4. 多态 - + >使用相同的消息,使得类作出不同的反应(继承为我们使用多态打下了基础)。Java实现多态有三个必要条件:继承、重写、向上转型。 - - + + - 面向对象的三个基本元素和五个原则 1. 三个基本元素: - + 封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 - - 继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。 - + + 继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。 + 多态: 多态性是指允许不同类的对象对同一消息作出 响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,这是一种泛型技术。所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法。比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议。 @@ -207,14 +207,14 @@ - 抽象类是一个可同时包含具体方法和抽象方法(方法未被实现)的类。抽象方法必须被该抽象类的子类实现。抽象类是可以继承的。 - 接口像是描述类的一张蓝图或者说是类的一种契约,它包含了许多空方法,这代表着它的所有的子类都应该拥有共同点。它的子类应该提供这些空方法的具体实现。一 个类需要用 `implements` 来实现接口,接口可以用 `extends` 来继承其他接口。 - + - 在设计层级理解他们的不同: 1. 抽象的层次不同:抽象类对类的整体(包括属性,行为)都可以进行抽象,接口对类的局部进行抽象,具体来说接口仅仅是对类的行为进行抽象。 2. 跨域不同:抽象类是 从各种子类中提取相似的部分,然后泛化成抽象类,子类可以继承这样的抽象类。 实现接口是 不存在`is-a`的关系的类们,你不可以称同样可以飞行的飞机和鸟为同一个抽象类,但是他们可以有同样的接口`fly-able`。抽象类的父类和派生类在概念上一致,接口的原生类和派生类在仅仅在局部行为上一致。 3. 设计层次不同:抽象类是从一堆在底层的子类们来进行抽象提取,从下往上,从而产生抽象类;接口是在直接定义的高度来声明的,然后从这个高度上往下实现此接口。抽象类是自底向上抽象而来的,接口是自顶向下设计出来的。 - - + + - 序列化是什么?如何实现它? @@ -227,21 +227,21 @@ - 什么是匿名内部类? 普通的类可以自然地实例化他自己,相反地,内部类是这样的类: - *一定要绑定上一个外部类才能进行实例化的类*。 + *一定要绑定上一个外部类才能进行实例化的类*。 + + 内部类提供了一种模拟车和车轮的机制,车是外部类,车轮是内部类 - 内部类提供了一种模拟车和车轮的机制,车是外部类,车轮是内部类 - 而匿名内部类也就是没有名字的内部类,因为没有名字,所以只能使用一次。 - + 使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口 - + 详情可见: - + http://www.cnblogs.com/nerxious/archive/2013/01/25/2876489.html - 对字符串进行 `==` 和 `equals()` 操作时有什么区别? - + `==` 比较两个字符串的地址,初学者很经常拿来比较其内容,将会导致出现不等的情况。 `equals()`是String这个类重写的一个方法,平常的类的`equals()`也仅仅是比较两个变量的地址,而String类的`equals()`重写后,将依次比较其串中的字符。 @@ -253,7 +253,7 @@ 2. 如果两个对象相同,就是适用于equals(java.lang.Object) 方法,那么这两个对象的hashCode一定要相同; 3. 如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致,否则就会违反上面提到的第2点; 4. 两个对象的hashCode相同,并不一定表示两个对象就相同,也就是不一定适用于equals(java.lang.Object) 方法,只能够说明这两个对象在散列存储结构中,如Hashtable,他们“存放在同一个篮子里”。 - + hashCode请参考:http://blog.csdn.net/fenglibing/article/details/8905007 - Java 中的 `final`, `finally` 和 `finalize`? @@ -266,7 +266,7 @@ 3. finalize:finalize出现的原因在于: 我们一定需要进行清理动作。Java没有用于释放对象的,如同C++里的delete调用,的方法,而是使用垃圾回收器(GC)帮助我们释放空间。当垃圾回收器准备释放对象占用的存储空间的时候,将首先调用其finalize()方法。 - 什么是内存泄露,Java 是如何处理它的? - +    总的来说是:保留下来却永远不再使用的对象引用    它包括: 1. 静态集合类引起内存泄漏, @@ -276,7 +276,7 @@ 5. 内部类和外部模块的引用 6. 单例模式    详情可见:http://note.youdao.com/noteshare?id=376631d4640128dc55646c8e577cc3ab - +    而关于Java 如何处理它,我还不能给出准确答案,应该是使用各种检测泄漏的工具检测到之后,使用GC处理它们 - 垃圾收集器是什么?它是如何工作的 @@ -292,17 +292,17 @@ - 比较 `Arrays` 和 `ArrayLists`。 Arrays:一个包含许多和操纵数组有关方法的类,比如排序和查找,它继承自Object类。 - +    ArraysList:是一个容器,它可以实现数组的大小可变,方便地增加和删除元素。它实现了List接口的类。 - +    详细的笔记在:http://note.youdao.com/noteshare?id=659562b6beba34649d769d09cd2e0533 - 比较 `HashSet` 和 `TreeSet`。    TreeSet是基于二叉树实现的,其中的数据是自动排序好的。不允许放入null值。 - +    HashSet是基于Hash表实现的,其中的数据是无序的,允许放入null值。 - +    详细的笔记在:http://note.youdao.com/noteshare?id=4a3e44e90105d9906eb308317bc816bb - Java 中的类型转换。 @@ -311,11 +311,11 @@     ![img](http://wx4.sinaimg.cn/mw690/005JrW9Kly1fip3s09u9jj30r908emxl.jpg)    在Java中,整数类型(byte/short/int/long)中,对于未声明数据类型的整形,其默认类型为int型。在浮点类型(float/double)中,对于未声明数据类型的浮点型,默认为double型。而当我们将一个数值范围较小的类型赋给一个数值范围较大的数值型变量,jvm在编译过程中会将此数值的类型进行自动提升。在数值类型的自动类型提升过程中,数值精度至少不应该降低(整型保持不变,float->double精度将变高)。而当我们需要将数值范围较大的数值类型赋给数值范围较小的数值类型变量时,我们需要手动地转换,称为强制类型转换。 - +    2.引用数据类型的类型转换 - +    由于继承和向上转型,子类向父类的转换是很自然的。但是当把父类转换为子类时,强制类型转换会在运行时检查父类的真实类型:如果引用的父类对象的真实身份是子类类型,只不过这个子类类型的对象经历了向上转型变成父类对象,这个时候我们再向下转回来子类,是可以的;而如果真的是父类的类型,就会抛出ClassCastException的异常。 - +    详细的笔记在:http://note.youdao.com/noteshare?id=7e85432e5d781ef8ad86ddabfc964885 - 方法重载和重写的区别 @@ -343,23 +343,23 @@ - 接口可以继承另一个接口吗? 可以,通过继承,你可以 - + 1. 在接口中添加新的方法声明 - + 2. 还可以通过继承,在新的接口中组合数个接口,这时只需要用逗号将接口名一一分开来即可。 - Java 中 `static` 关键字是什么意思? static是Java里的非访问修饰符,它可以用来创建类方法和类变量。 - + 当修饰一个变量的时候,此变量就成了独立于对象的静态变量,无论一个类实例化了多少个对象,这个类只有一份这个静态变量的拷贝,所以static修饰的变量,即静态变量,也被叫做类变量。一个局部变量不能被声明为static变量。 - + 当修饰一个方法的时候,此方法就成了独立于对象的静态方法,静态方法不能使用类的非静态变量,因为静态方法和静态变量先于非静态的其他成员初始化,静态方法先出来,然后才是非静态的,所以明白这个顺序很重要。静态方法从参数列表得到数据,然后计算这些数据。 - + >有些人认为static方法不是面向对象的,因为它们确实具有全局函数的语义;使用static方法时,由于不存在this,所以不是通过「向对象发送消息」的方式来完成的。当代码中出现很多static方法时,你应该反思自己的设计的,然而,static确有其用。 - + 总结一下,当static: - + 1. 修饰方法时,此方法能够不用在初始化对象的前提下直接调用,即,可以直接通过类名.static方法()这样来访问。 2. 修饰代码块时,这部分代码块只会被执行一次。 @@ -379,9 +379,9 @@ - 什么是多态?什么是继承? - 多态是:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用) - + > 允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”) - + - 继承是:子类继承父类的特征和行为,使得子类具有父类的各种属性和方法。 - `Integer` 和 `int` 之间的区别 @@ -430,9 +430,9 @@ - 在 Java 中什么是强引用、软引用、弱引用以及虚引用?  强引用:不会被GC轻易清理,只要引用存在,垃圾回收器永远不会回收。 - + `Object obj = new Object();` - +  软引用: 非必须引用,内存溢出之前进行回收 ``` Object obj = new Object(); @@ -440,9 +440,9 @@ obj = null; sf.get();//有时候会返回null ``` - +  弱引用: 第二次垃圾回收时回收 - +  ``` Object obj = new Object(); WeakReference wf = new WeakReference(obj); @@ -450,9 +450,9 @@ wf.get();//有时候会返回null wf.isEnQueued();//返回是否被垃圾回收器标记为即将回收的垃圾 ``` - +  虚引用: 垃圾回收时回收,无法通过引用取到对象值 - +  ``` Object obj = new Object(); PhantomReference pf = new PhantomReference(obj); @@ -462,7 +462,7 @@ ``` 具体笔记可参考:http://note.youdao.com/noteshare?id=d52d8dd97e8dc162ddc90ff72a5c6001 - +  以及:http://note.youdao.com/noteshare?id=a9b2cebfbeb8fb33093ca318db58b389 - 什么是依赖注入?能说几个依赖注入的库么?你使用过哪些? @@ -470,20 +470,20 @@ - 关键字`synchronized`的作用是什么? synchronized通过修饰一个方法或者代码块,从而产生一个同步对象锁,以及对应 的同步代码块。每当有线程要对该同步代码块进行访问时,线程就会首先尝试获取这个对 象的锁,并在成功获取到对象锁后,对这个同步代码块进行正常的访问。在同步代码块的 访问过程中,线程会一直持有这个对象锁,直到同步代码块访问完毕,然后才会释放。 - + 在上述线程持有同步锁并进行同步代码块访问过程中,其它线程将无法获得该对象锁,也 无法访问该同步代码,这些线程都会被阻塞直到上述线程访问完毕 - 为什么说`String`不可变的? 1. java.lang.String类型在实现时,其内部成员变量全部使用final来修饰,保证成员变量的引用值只能通过构造函数来修改; - + 2. java.lang.String类型在实现时,在外部某个地方,可能修改一个String实例的内部存储值的函数实现中,在这个地方的调用返回时,一律构造新的String对象或者新的byte数组或者char数组,给赋值符号的左边变量(左值);  详细请看:http://note.youdao.com/noteshare?id=747f5d269dd7e177153e4f099f095876 - 修饰符`transient`和`volatile`的作用是什么? - + 1. volatile 易式修饰符 @@ -512,23 +512,23 @@ - 对象的实例化和初始化之间的区别是什么? 实例化可以理解为做出一个蛋糕: - + `Cake ca = new Cake();` - + 初始化可以理解为,每个蛋糕都要有它自己的奶油: - + `ca.iceCream = "香草味奶油";` - + 实例化着重于动作,强调==对象==从无到右的创建过程,而初始化着重于状态,强调==对象的特征==从无到有的过程。 - + - 静态块何时运行?  初始化的顺序大致是这样的: - +  1. 为类中的静态变量分配好空间(同时给变量以默认值) 2. 如果创建了类的对象,那么为类的实例变量分配地址空间(同时给变量以默认值) - + 就在这两步之间,发生了静态块的运行 @@ -537,7 +537,7 @@ - `StringBuffer` 和`StringBuilder` 的区别在哪里?  StringBuffer、StringBuilder和String一样,也用来代表字符串。String类是不可变类,任何对String的改变都 会引发新的String对象的生成;StringBuffer和StringBuilder则是可变类 - +  先说一下,以集合为例,HashTable是线程安全的,很多方法都是synchronized方法,而HashMap不是线程安全的,但其在单线程程序中的性能比HashTable要高。StringBuffer和StringBuilder类的区别也是如此,他们的原理和操作基本相同,区别在于StringBufferd支持并发操作,线性安全的,适 合多线程中使用。StringBuilder不支持并发操作,线性不安全的,不适合多线程中使用。新引入的StringBuilder类不是线程安全的,但其在单线程中的性能比StringBuffer高。 - `StringBuilder` 是怎么避免不可变字符串分配的问题? @@ -548,44 +548,44 @@ 简单一点说,装箱就是 自动将基本数据类型转换为包装器类型;拆箱就是 自动将包装器类型转换为基本数据类型 自动装箱(autoboxing): - + 一般来说,这是我们创建一个类的实例时,我们会这样: - + ``` - + MyClass a = new MyClass(); - + ``` - + 但是当我们新建一些支持自动装箱和拆箱的数据类型的时侯(比如Integer,基本数据类型的包装类),我们可以这样: - + ``` - + Integer i = 100; - + ``` - + 执行这句语句,将会被编译器执行为: - + ``` - + Integer i = Integer.valueOf(100); - + ``` - + 这就是自动装箱 - + 自动拆箱(unboxing): - + 将对象中的基本数据从对象中自动取出 - + 比如: - + ``` - + Integer i = 10;//autoboxing int c = i;//unboxing - + ``` - 枚举和迭代器有什么区别? @@ -598,7 +598,7 @@ Iterator只有3个函数接口。Iterator除了能读取集合的数据之外, 2. Iterator支持fail-fast机制,而Enumeration不支持。 Enumeration 是JDK 1.0添加的接口。使用到它的函数包括Vector、Hashtable等类,这些类都是JDK 1.0中加入的,Enumeration存在的目的就是为它们提供遍历接口。Enumeration本身并没有支持同步,而在Vector、Hashtable实现Enumeration时,添加了同步。 而Iterator 是JDK 1.2才添加的接口,它也是为了HashMap、ArrayList等集合提供遍历接口。Iterator是支持fail-fast机制的:当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。 - + - Java 中 *fail-fast* 和 *fail-safe* 的区别? @@ -614,36 +614,36 @@ Enumeration 是JDK 1.0添加的接口。使用到它的函数包括Vector、Hash 创建 onCreate - 启动onStart – 开始 onResume – 暂停 onPause – 结束 onStop – 销毁onDestroy -每一个活动( Activity )都处于某一个状态,对于开发者来说,是无法控制其应用程序处于某一个状态的,这些均由系统来完成。 -但是当一个活动的状态发生改变的时候,开发者可以通过调用 onXX() 的方法获取到相关的通知信息。 +每一个活动( Activity )都处于某一个状态,对于开发者来说,是无法控制其应用程序处于某一个状态的,这些均由系统来完成。 +但是当一个活动的状态发生改变的时候,开发者可以通过调用 onXX() 的方法获取到相关的通知信息。 -在实现 Activity 类的时候,通过覆盖( override )这些方法即可在你需要处理的时候来调用。 +在实现 Activity 类的时候,通过覆盖( override )这些方法即可在你需要处理的时候来调用。 -•onCreate :当活动第一次启动的时候,触发该方法,可以在此时完成活动的初始化工作。 +•onCreate :当活动第一次启动的时候,触发该方法,可以在此时完成活动的初始化工作。 onCreate 方法有一个参数,该参数可以为空( null ),也可以是之前调用 onSaveInstanceState()方法保存的状态信息。 -•onStart :该方法的触发表示所属活动将被展现给用户。 +•onStart :该方法的触发表示所属活动将被展现给用户。 -•onResume :当一个活动和用户发生交互的时候,触发该方法。 +•onResume :当一个活动和用户发生交互的时候,触发该方法。 -•onPause :当一个正在前台运行的活动因为其他的活动需要前台运行而转入后台运行的时候,触发该方法。这时候需要将活动的状态持久化,比如正在编辑的数据库记录等。 +•onPause :当一个正在前台运行的活动因为其他的活动需要前台运行而转入后台运行的时候,触发该方法。这时候需要将活动的状态持久化,比如正在编辑的数据库记录等。 -•onStop :当一个活动不再需要展示给用户的时候,触发该方法。如果内存紧张,系统会直接结束这个活动,而不会触发 onStop 方法。 所以保存状态信息是应该在onPause时做,而不是onStop时做。活动如果没有在前台运行,都将被停止或者Linux管理进程为了给新的活动预留足够的存储空间而随时结束这些活动。因此对于开发者来说,在设计应用程序的时候,必须时刻牢记这一原则。在一些情况下,onPause方法或许是活动触发的最后的方法,因此开发者需要在这个时候保存需要保存的信息。 +•onStop :当一个活动不再需要展示给用户的时候,触发该方法。如果内存紧张,系统会直接结束这个活动,而不会触发 onStop 方法。 所以保存状态信息是应该在onPause时做,而不是onStop时做。活动如果没有在前台运行,都将被停止或者Linux管理进程为了给新的活动预留足够的存储空间而随时结束这些活动。因此对于开发者来说,在设计应用程序的时候,必须时刻牢记这一原则。在一些情况下,onPause方法或许是活动触发的最后的方法,因此开发者需要在这个时候保存需要保存的信息。 -•onRestart :当处于停止状态的活动需要再次展现给用户的时候,触发该方法。 +•onRestart :当处于停止状态的活动需要再次展现给用户的时候,触发该方法。 -•onDestroy :当活动销毁的时候,触发该方法。和 onStop 方法一样,如果内存紧张,系统会直接结束这个活动而不会触发该方法。 +•onDestroy :当活动销毁的时候,触发该方法。和 onStop 方法一样,如果内存紧张,系统会直接结束这个活动而不会触发该方法。 -•onSaveInstanceState :系统调用该方法,允许活动保存之前的状态,比如说在一串字符串中的光标所处的位置等。 +•onSaveInstanceState :系统调用该方法,允许活动保存之前的状态,比如说在一串字符串中的光标所处的位置等。 通常情况下,开发者不需要重写覆盖该方法,在默认的实现中,已经提供了自动保存活动所涉及到的用户界面组件的所有状态信息。 - + * 谈谈 Android 的四大组件。 1. 活动: Android 中,Activity是所有程序的根本,所有程序的流程都运行在Activity 之中,Activity可以算是开发者遇到的最频繁,也是Android 当中最基本的模块之一。在Android的程序当中,Activity 一般代表手机屏幕的一屏。如果把手机比作一个浏览器,那么Activity就相当于一个网页。在Activity 当中可以添加一些Button、Check box 等控件。可以看到Activity 概念和网页的概念相当类似。一般一个Android 应用是由多个Activity 组成的。这多个Activity 之间可以进行相互跳转,例如,按下一个Button按钮后,可能会跳转到其他的Activity。和网页跳转稍微有些不一样的是,Activity 之间的跳转有可能返回值,例如,从Activity A 跳转到Activity B,那么当Activity B 运行结束的时候,有可能会给Activity A 一个返回值。这样做在很多时候是相当方便的。 -  当打开一个新的屏幕时,之前一个屏幕会被置为暂停状态,并且压入历史堆栈中。用户可以通过回退操作返回到以前打开过的屏幕。可以选择性的移除一些没有必要保留的屏幕,因为Android会把每个应用的开始到当前的每个屏幕保存在堆栈中。 +  当打开一个新的屏幕时,之前一个屏幕会被置为暂停状态,并且压入历史堆栈中。用户可以通过回退操作返回到以前打开过的屏幕。可以选择性的移除一些没有必要保留的屏幕,因为Android会把每个应用的开始到当前的每个屏幕保存在堆栈中。 2. 服务 @@ -947,7 +947,7 @@ Content Provider 是Android提供的第三方应用数据的访问方案。 感谢这些无私的贡献者,排名不分先后。 -[mengxn](https://github.com/mengxn)、[innovatorCL](https://github.com/innovatorCL)、[SmartNJ](https://github.com/SmartNJ)、[Zhiw](https://github.com/Zhiw)、[lanyuanxiaoyao](https://github.com/lanyuanxiaoyao)、[934079371](https://github.com/934079371)、[cdevelopr](https://github.com/cdevelopr)、[smartbeng](https://github.com/smartbeng)、[ikook](https://github.com/china-kook)、[mrfanr](https://github.com/mrfanr)、[androidZzT](https://github.com/androidZzT)、[qiaojialin](https://github.com/qiaojialin)、[maokai1229](https://github.com/maokai1229)、[renxuelong](https://github.com/renxuelong)、[dzx1994](https://github.com/dzx1994) +[mengxn](https://github.com/mengxn)、[innovatorCL](https://github.com/innovatorCL)、[SmartNJ](https://github.com/SmartNJ)、[Zhiw](https://github.com/Zhiw)、[lanyuanxiaoyao](https://github.com/lanyuanxiaoyao)、[934079371](https://github.com/934079371)、[DLonng](https://github.com/DLonng)、[smartbeng](https://github.com/smartbeng)、[ikook](https://github.com/china-kook)、[mrfanr](https://github.com/mrfanr)、[androidZzT](https://github.com/androidZzT)、[qiaojialin](https://github.com/qiaojialin)、[maokai1229](https://github.com/maokai1229)、[renxuelong](https://github.com/renxuelong)、[dzx1994](https://github.com/dzx1994) ### License