深入浅出计算机组成原理(一)--计算机指令

因为计算机或者说 CPU 本身,并没有能力理解这些高级语言,计算机只能理解 “机器码”,即一连串的 “0” 和 “1” 这样的数字。

CPU

CPU 是计算机的大脑,Central Processing Unit,中文为 中央处理器

从硬件角度: CPU 是一个超大规模的集成电路,通过电路实现加法、减法、乘法等逻辑运算。

从软件角度:CPU 是一个执行 计算机指令的逻辑电器。这里的计算机指令是指 CPU 能够听懂的语言,可以把它看做 机器语言

每种 CPU 能够听懂的语言是不同的,例如个人 PC 中的 Intel 的 CPU, IPhone 中的 ARM 的 CPU。每种 CPU 有自己能够支持的 计算机指令。不同 CPU 间的计算机指令是不可互通的,例如你不能把运行在计算机上的程序复制到手机上,这是没有办法运行的。

一个计算机程序编译后,有很多的计算机指令。

Read More

Jetpack之WorkManager基本了解

0x0000 概述

通过WorkManager API,可以轻松安排即使应用程序退出或设备重新启动也可以运行的可延迟的异步任务。

0x0001 feature

  • 向后兼容到 API 14

    • 在 API 23+ 的设备上使用 JobScheduler。
    • 在 API 14-22 的设备上使用 BroadcastReceiver 以及 AlarmManager。
  • 为网络或获取充电状态添加约束

  • 安排一次性异步任务或定期任务

  • 监控和管理计划任务

  • 链接多个任务

  • 即使应用程序或设备重新启动,也可确保任务执行

  • 坚持Doze模式等省电模式

Read More

Java集合之Map

概述

Map 用于保存具有 映射关系 的数据,因此 Map 集合内保存着两组数据,一组保存 Map 的 key,一组保存 Map 的 value,并且 key 和 value 可以是任何类型的数据。

Map

可以把 Map 里的 Key 放在一起,它们组成一个 Set 集合(Key 没有顺序、不可重复),其实Map 的内部的 keySet() 方法确实是返回的所有的 key 组成的 Set 集合对象。而把 Map 内的 Value 放在一起,它们类似一个 List 集合(可重复,此时的索引为 key)。

如果抽象的看 Map 的 key 可以看作为 Set 集合(即无序、不可重复),而 value 可以看作为 Array 集合(可重复)

操作

向 Map 中添加数据中,如果 Map 中有存在 key,那么新添加的 value 会覆盖原来的 value。

Read More

Java集合之Queue

概述

List、Set、Queue

Queue 用于模拟 “队列” 这种数据结构,队列为 先进先出(First In First Out,FIFO) 的容器。队列可以将元素插入尾部,可以访问位于队列头部的元素,所以队列不能随机访问队列的元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public interface Queue<E> extends Collection<E> {
/**
* 将指定元素加入队列的尾部,内部调用 offer
*/
boolean add(E e);
/**
* 将指定元素加入队列的尾部
*/
boolean offer(E e);
/**
* 获取队列头部的元素,并删除该元素
*/
E remove();
/**
* 获取队列头部的元素,并删除该元素
*/
E poll();
/**
* 获取队列头部的元素,但是不删除该元素,与 peek 唯一不同是会抛出 NoSuchElementException 异常
*/
E element();
/**
* 获取队列头部的元素,不删除该元素
*/
E peek();
}

Queue 有 PriorityQueue 实现类,同时 Queue 还有一个 Deque 接口,Deque 代表一个 “双端队列”,双端队列可以在两端进行添加、删除元素,Deque 的实现类既可以当做队列来使用也可以当做栈来使用,其有两个实现类: ArrayDeque、LinkedList。

PriorityQueue 类

PriorityQueue 保存队列元素的顺序不是按加入队列的顺序,而是按队列元素的大小进行重新排序。而其排序方式有:自然排序和定制排序。两种排序规则的实现与 TreeSet 相同,不赘述。

PriorityQueue 内部通过数组实现。

Deque 接口与 ArrayDeque 实现类

Deque 为 Queue 的子接口,代表了一个 双端队列,可以在双端添加、删除数据的,具体操作可以查看 Deque 的 Api。

与 Queue 方法不同为以上方法可以拆分为 xxxFirst()、xxxLast() 方法,代表对队列的两端进行的处理。

我们可以把 Deque 当做 队列 使用,也可以当做 来使用。

与 ArrayList 相同,它们底层都是采用 一个动态的、可重新分配的 Object[] 数组 来存储集合元素。

把 ArrayDeque 当做 “栈”(Fitst In Last Out,FILO) 来使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private static void test2() {
ArrayDeque arrayDeque = new ArrayDeque();
//将 3 个元素 push 入栈
arrayDeque.push("one");
arrayDeque.push("two");
arrayDeque.push("three");
System.out.println(arrayDeque);
// 访问第一个元素,但不出栈
System.out.println(arrayDeque.peek());
System.out.println(arrayDeque);
// 第一个元素出栈
System.out.println(arrayDeque.pop());// 实现栈的关键
System.out.println(arrayDeque);
}

打印日志:

1
2
3
4
5
[three, two, one]
three
[three, two, one]
three
[two, one]

ArrayDeque 很好的实现了 “栈” – 先入后出 这种数据结构。在程序中使用栈时推荐使用 ArrayDeque ,避免使用 Stack(性能较差)。

把 ArrayDeque 当做 “队列” 来使用

当然 ArrayDeque 也可以当做队列使用,使用 先进先出 的方式操作集合元素。

1
2
3
4
5
6
7
8
9
10
11
12
private static void test3() {
ArrayDeque arrayDeque = new ArrayDeque();
// 将 3 个元素加入队列
arrayDeque.offer("one");
arrayDeque.offer("two");
arrayDeque.offer("three");
System.out.println(arrayDeque);
System.out.println(arrayDeque.peek());
System.out.println(arrayDeque);
System.out.println(arrayDeque.poll());//实现队列的关键
System.out.println(arrayDeque);
}

打印日志:

1
2
3
4
5
[one, two, three]
one
[one, two, three]
one
[two, three]

LinkedList

1
2
3
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable

LinkedList 是 List 的实现类,同时它也实现了 Deque 接口,所以 LinkedList 可以 根据 索引 来随机访问集合的元素,也可以被当做 双端队列 来使用,由此可见 LinkedList 既可以当做队列也可以当做栈来使用

LinkedList 内部实现机制与 ArrayList 、 ArrayDeque 不同,后两者内部维护动态、可扩容的 Object[] 数组,因此访问随机集合元素的性能较高;LinkedList 内部以 链表 的形式来保存集合中的元素,因此随机访问集合元素的性能较差,但是在 插入、删除集合元素性能较高(只需改变指针所指的地址)

各种线性表的性能表现

Java 中 List 是一个线性表接口,最具代表性的实现类为:ArrayList(基于数组的线性表)、LinkedList(基于链的线性表)。Queue 代表了队列,Deque 代表了双端队列。

由于数组以一块连续内存来保存数组元素,所以数组的随机访问的性能较好,那么以数组为底层实现的集合在随机访问时性能较好;而内部以链表为顶层实现的集合在添加、删除集合元素时有较好的性能。总体上 ArrayList 的性能比 LinkedList 的性能较好,因此大部分时候选用 ArrayList。

关于使用 List 几点建议:

  1. 遍历 List 集合。对于 ArrayList 、ArrayDeque 等底层实现为数组集合使用随机访问来遍历元素,这样性能更好;而对于 LinkedList 则应该使用 Itertor 迭代器来遍历集合元素。
  2. 经常添加、删除元素操作的集合,可考虑 LinkedList。使用 ArrayList、Vector 集合可能需要经常重新分配内部数组的大小,性能较差。
  3. 多个线程访问 List 集合,可以使用 Collections 工具类对集合进行包装来实现线程安全。

Java集合之List

概述

List、Set、Queue

List 集合为元素有序、可重复的集合。

List 集合判断元素相等的标准:两个对象的 equals() 方法比较返回值为 true 。

实现排序:List 的 sort() 方法需要一个 Comparator 对象来控制元素的排序。

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {

List list = new ArrayList();
list.add(new ClassE(2));
list.add(new ClassE(1));
list.add(new ClassE(3));
System.out.println(list);
list.sort((o1, o2) ->
((ClassE)o1).getNum() -((ClassE)o2).getNum()
);
System.out.println(list);
}

打印日志:

1
2
[ClassD{num=2}, ClassD{num=1}, ClassD{num=3}]
[ClassD{num=1}, ClassD{num=2}, ClassD{num=3}]

Read More

Jetpack 之 Lifecycle 组件学习笔记

2019.10.21 更新

0x0000 概述

在 A/F 生命周期变化后,生命周期感知组件(Lifecycle—aware component)会响应相应动作,它会帮助你编写有良好组织的、轻量级、易维护的代码。

传统模式下,要想做的生命感知需要做的是实现其他组件的接口,并在 A/F 的生命周期函数中调用其他组件的方法。但是这样并不是好的代码组织方式,并且容易产生错误。而通过 生命周期感知组件(Lifecycle—aware component) 可以把这部分逻辑从 A/F 中移到组件自身中。

android.arch.lifecycle (androidx 下为 androidx.lifecycle ) 包下的类和接口允许你创建 生命周期感知组件(lifecycle-aware components),它们 可以根据 A/F 的生命周期来调整自己的行为

像 Activity、Service 等组件的生命周期均是由 Android Framework 管理,同样的,Lifecycle 也由运行的系统或者 Framework 中的进程管理,在编写 Andorid 程序时需要遵守相应的规则,不然会产生内存泄漏,甚至会导致应用奔溃。

0x0001 Lifecycle

Lifecycle 持有 A/F 组件有关生命周期的信息,并且允许其他对象监听它的状态。在 Android API 26.0.1以及其后 A/F实现了LifecycleOwner,可在 A/F 中通过 getLifecycle() 获得 A/F 的 Lifecycle 对象。

Read More

Java 集合之 Set 集合

Set 集合

List、Set、Queue

Set 集合的特点无序、不可重复。

Set 集合不能记住元素的添加顺序。Set 集合不能包含相同的元素,把两个相同的元素添加到同一个 Set 集合中,则添加失败,add() 方法返回 false,且新元素不会被添加。

HashSet 类

HashSet 集合按 Hash 算法 来存储集合的元素,因此具有很好的存取和查找功能

HashSet 具有以下特点:

  1. 不能保证元素的排列顺序,这也是 Set 集合元素不能通过索引只能通过元素本身访问的原因。
  2. HashSet 不是线程安全的。
  3. 元素可以为 null。

Read More

Java 集合概述

Java 集合在日常的开发中的使用频率是很高的,我们可以通过 Java
集合来实现常见的数据结构,如堆、栈等。

Java 集合的分类

Java 集合分为 List、Set、Map、Queue 四种体系,以下为各个体系的特点:

  • List:有序、可重复的集合。
  • Set:无序、不可重复的集合。
  • Map:具有映射关系的集合。
  • Queue:Java5 后增加了 Queue 体系,代表队列的一种实现。

谈到集合就不得不提在 Java5 增加的泛型,但是不在这里进行阐述。

Java 集合可用来 存储对象,因此被称为 容器类。与 数组既可以存储基本数据类型也可以存储对象不同,集合只能存储对象。

Java 集合之 List

Java 集合之 Set

Java 集合之 Map

Java 集合之 Queue

Java 集合工具类–Collections

Read More

Jetpack之LiveData 笔记

0x000 概述

在官方文档中首先对 LiveData 做了一个概述 : LiveData is an observable data holder class, LiveData 是一个 可观察的 数据持有者类。它是可以感知 Activity/Fragment/Service 的生命周期的,这使得 LiveData 只会在以上组件处于 活跃状态下 更新组件。

LiveData 认为上述中的 活跃状态 为对应的 Observer 处于 STARTEDRESUMED 状态。LiveData 数据更改不会触发非活跃组件的更新。

LiveData 与 观察者(实现 LifecycleOwner 的类) 建立的连接会在组件处于 DESTORY 状态后被移除。

0x0001 个人理解

官方文档看了几遍,大致明白了 LiveData 的作用, LiveData 可持有数据,并且它有一个重要的方法:

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)

Read More

Jetpack 之 ViewModle 组件学习笔记

0x0000 概述

ViewModel 类旨在 通过生命周期感知 的方式存储、管理与 UI 相关的数据。ViewModel 类可以在屏幕旋转情况下保持数据处于 存活 的状态。

Android 通过 Framework 层管理 UI(Activity/Fragment) 的生命周期。为了响应用户的动作,系统可能会新建或重建 UI,但是这些都不是开发者所能控制的。

Read More