Java基础02
静态代码块 VS 实例代码块
静态代码块在类加载时顺序执行,并且只执行一次。
实例代码块在构造方法之前执行。
1 | public class CodeOrder{ |
执行顺序:
static-01
static-02
main begin
{….}
new CodeOrder();
main end
I/O流
| 字节流 | 字符流 | |
|---|---|---|
| 输入流 | InputStream | Reader |
| 输出流 | OutputStream | Writer |
静态代码块在类加载时顺序执行,并且只执行一次。
实例代码块在构造方法之前执行。
1 | public class CodeOrder{ |
执行顺序:
static-01
static-02
main begin
{….}
new CodeOrder();
main end
| 字节流 | 字符流 | |
|---|---|---|
| 输入流 | InputStream | Reader |
| 输出流 | OutputStream | Writer |
概述
Redis 是一个使用 C 语言开发的开源数据库,不过与传统数据库不同的是 Redis 的数据是存在内存中的 ,也就是它是内存数据库,所以读写速度非常快,因此 Redis 被广泛应用于缓存方向。
用途
String数据结构是简单的key-value类型。
基本操作:
1 | 127.0.0.1:6379> set key value #设置 key-value 类型的值 |
计数器:
1 | 127.0.0.1:6379> set number 1 |
Redis 的 list 的实现为一个 双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。
基本操作:rpush,lpop,lpush,rpop,lrange,llen
1 | 127.0.0.1:6379> rpush myList value1 # 向 list 的头部(右边)添加元素 |
lpush/rpoplpush/lpopRedis 中的 set 类型是一种无序集合,集合中的元素没有先后顺序。当你需要存储一个列表数据,又不希望出现重复数据时,set 是一个很好的选择,可以基于 set 轻易实现交集、并集、差集的操作。比如:你可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis 可以非常方便的实现如共同关注、共同粉丝、共同喜好等功能。
1 | 127.0.0.1:6379> sadd mySet value1 value2 # 添加元素进去 |
sintersuionsdiffhash 是一个 string 类型的 field 和 value 的映射表,特别适合用于存储对象,后续操作的时候,你可以直接仅仅修改这个对象中的某个字段的值。 比如我们可以 hash 数据结构来存储用户信息,商品信息等等。
1 | 127.0.0.1:6379> hmset userInfoKey name "guide" description "dev" age "24" |
1 | 127.0.0.1:6379> zadd myZset 3.0 value1 # 添加元素到 sorted set 中 3.0 为权重 |
1 | > MULTI |
- 开始事务(
MULTI)。- 命令入队(批量操作 Redis 的命令,先进先出(FIFO)的顺序执行)。
- 执行事务(
EXEC)。
Redis的事务和我们平时理解的关系型数据库的事务不同。
我们知道事务具有四大特性: 1. 原子性,2. 隔离性,3. 持久性,4. 一致性。
Redis 是不支持 roll back 的,因而不满足原子性的(而且不满足持久性)。
Verilog可以从五个层次对电路(系统)进行描述,包括:系统级、算法级、寄存器传输级(即RTL级)、门级、开关级。我们平时用的最多的为RTL级,故Verilog代码也经常被称为RTL代码。
1 | Always@(posedge clk) |
凡是带有posedge或negedge的always块,都会被综合成时序逻辑电路。
reg :除wire类型外,另外一种常用的数据类型,一般表示寄存器类型数据,不过并不绝对,记住一条原则:在always块内被赋值的信号应定义成reg型,用assign语句赋值的信号应定义成wire型。
always/assign:两者都不可嵌套
assign语句只能实现组合逻辑赋值,且一个assign语句后面只能跟一条赋值表达式。
always即能实现组合逻辑赋值,又能实现时序逻辑赋值操作,且可以包含多条赋值表达式,多条赋值表达式,则应位于begin/end对中间。
设计规则:
i:在组合逻辑电路中,使用阻塞式赋值方式”=”;
ii: 在时序逻辑电路中,使用非阻塞式赋值方式”<=”
iii:在同一个always块内,只能存在一种赋值方式。
iv:一个信号,只能在一个always或一个assign语句下赋值。
v:原则上来说,一个always块内只处理一个或一类信号,不同的信号可在不同的always块内处理。
vi: always块内只能对reg型信号进行处理,不能对wire型数据赋值,也不能实例化模块
1 | reg [7:0] mem [255:0]; // 256 unpacked elements, each of which is a 8-bit packed vector of reg. |
1 | // Full adder module here |
特点:
任一时刻的输出不仅取决于该时刻的输入,还与电路原来的状态有关。
电路结构上
包含存储电路和组合电路
存储器状态和输入变量共同决定输出

同步:存储电路中所有触发器的时钟使用统一的clk状态变化发生在同一时刻
异步:没有统一的clk,触发器状态的变化有先有后
- 从给定电路写出存储电路中每个触发器的驱动方程(输入的逻辑式),得到整个电路的驱动方程。
- 将驱动方程代入触发器的特性方程,得到状态方程。
- 从给定电路写出输出方程。
移位寄存器可以用来寄存代码,还可以用来实现数据的串行—并行转换、数值的运算以及数据的处理等。
用于计数、分频、定时、产生节拍脉冲等。
原理:在多位二进制数末位加1,若第i位一下皆为1时,则第i位应该翻转。
Ti = (Qi-1)(Qi-2)…(Q0)
相反,减法器原理为 :
Ti = (Qi-1)‘(Qi-2)’…(Q0)‘
基本步骤:
- 逻辑抽象
A. 确定输入、输出变量以及电路的状态数
B. 定义输入、输出逻辑状态和每个电路状态的含义
C. 得出电路的状态转换图(表)- 状态化简和状态分配
- 触发器选型,求出电路的状态方程、驱动方程和输出方程
- 根据得到的方程画出逻辑图
- 检查设计的电路能否自启动
实现模为7的计数器:
因为该器件为异步清零,需要一个过渡态S7来置零。
实现模为7的计数器:
因为该器件为同步清零,只需要从S0-S6,等待时钟信号从S6->S0来置零。
存储电路的基本功能:存储各种数据和信息
寄存器
存储一组数据的电路
结构为一组具有公共时钟信号输入端的触发器
存储器
存储大量数据的电路
基本结构由存储矩阵和读/写控制电路组成

| Sd | Rd | Q | Q’ |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 |
| 1 | 0 | 1 | 1 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 0 |
输入控制门+基本SR触发器
只有触发信号CLK到达,S和R才起作用。

- CLK = 1时,主 按S,R翻转,从 保持
- CLK下降沿到达时,主 保持,从 根据主 的状态翻转
注意:每个CLK周期,输出状态只可能改变一次。

为了解除约束,可以出现S=R=1的情况。
- Q=0时,只允许J=1的信号进入主触发器
- Q=1时,只允许K=1的信号进入主触发器
***主从JK在CLK高电平期间,主只可能翻转一次。**
𝑄∗ = 𝑆′𝑅′𝑄 + 𝑆𝑅′𝑄′ + 𝑆𝑅′𝑄 = 𝑆′𝑅′𝑄 + 𝑆𝑅′ = 𝑆 + 𝑅′𝑄
𝑆𝑅=0
| S | R | Q | Q* |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 |
| 1 | 0 | 1 | 1 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 0 |
| 1 | 1 | 0 | 1* |
| 1 | 1 | 1 | 1* |
𝑄∗ = 𝐽𝑄′ + 𝐾′𝑄
| J | K | Q | Q* |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 |
| 1 | 0 | 1 | 1 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 0 |
| 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 0 |
将JK触发器的输入端J、K连接在一起,作为输入端T,就构成了T触发器。
即当T=0时能保持状态不变,T=1时一定翻转的电路,都称为T触发器。
𝑄∗ = 𝑇𝑄′ + 𝑇′𝑄
| T | Q | Q* |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
D触发器可以用作寄存器和分频器。
𝑄∗ = D
编码:将输入的每个高/低电平信号变成一个对应的二进制代码。
只允许一个输入信号有效
| I0 | I1 | I2 | I3 | I4 | I5 | I6 | I7 | Y2 | Y1 | Y0 |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
| 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 |
| 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 |
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
允许多个输入信号同时有效,但只按优先级最高的有效输入信号编码。
| I0 | I1 | I2 | I3 | I4 | I5 | I6 | I7 | Y2 | Y1 | Y0 |
|---|---|---|---|---|---|---|---|---|---|---|
| X | X | X | X | X | X | X | 1 | 1 | 1 | 1 |
| X | X | X | X | X | X | 1 | 0 | 1 | 1 | 0 |
| X | X | X | X | X | 1 | 0 | 0 | 1 | 0 | 1 |
| X | X | X | X | 1 | 0 | 0 | 0 | 1 | 0 | 0 |
| X | X | X | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
| X | X | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| X | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
译码:将每个输入的二进制代码译成对应的输出高/低电平信号。
| A2 | A1 | A0 | Y7 | Y6 | Y5 | Y4 | Y3 | Y2 | Y1 | Y0 |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
| 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Y0 = A2’A1’A0’ = m0
…
Y7 = A2A1A0 = m7
Y = SEL·A + SEL‘·B
| SEL | A | B | Y |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 1 |
eg:Y1 = D0(A1’A0’) + D1(A1’A0) + D2(A1A0’) + D3(A1A0)
Y=AB+A’C
在B=C=1的条件下,Y=A+A′⇒稳态下Y=1
当A改变状态时存在竞争-冒险
Y = A&B = A·B = AB
| A | B | Y |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |

Y = A | B = A + B
| A | B | Y |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |

Y = A’ = NOT A
| A | Y |
|---|---|
| 0 | 1 |
| 1 | 0 |

| A | B | Y |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |

| A | B | Y |
|---|---|---|
| 0 | 0 | 1 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |

A’ = (A·A)’
A·B = ((AB)’)’
A+B = ((A+B)’)’ = (A’B’)’
| AA = A | A+A = A |
|---|---|
| AA’ = 0 | A+A’ = 1 |
| AB = BA | A+B = B+A |
| (AB)’ = A’+B’ | (A+B)’ = A’B’ |
| A(B+C) = AB+AC | A+BC = (A+B)(A+C) |
| A B + A′ C + B C = A B + A′ C |
|---|
| A B+ A′ C + B C D = A B + A′ C |
| A | B | C | Y |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 |
| 1 | 0 | 1 | 1 |
| 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 0 |
Y = A‘BC + AB‘C + ABC’
| 最小项 | 取值 | 对应 | 编号 |
|---|---|---|---|
| A’B’C’ | 0 0 0 | 0 | m0 |
| A’B’C | 0 0 1 | 1 | m1 |
| AB’C | 0 1 0 | 2 | m2 |
| A’BC | 0 1 1 | 3 | m3 |
| AB’C’ | 1 0 0 | 4 | m4 |
| AB’C | 1 0 1 | 5 | m5 |
| ABC’ | 1 1 0 | 6 | m6 |
| ABC | 1 1 1 | 7 | m7 |
- 在输入变量任一取值下,有且仅有一个最小项的值为1。
- 全体最小项之和为1 。
- 任何两个最小项之积为0 。
- 两个相邻的最小项之和可以合并,消去一对因子,只留下公共因子。
- 相邻:仅一个变量不同的最小项
- 在输入变量任一取值下,有且仅有一个最大项的值为0;
- 全体最大项之积为0;
- 任何两个最大项之和为1;
- 只有一个变量不同的最大项的乘积等于各相同变量之和。
1 | int a = 1101; |

基本数据类型的变量里直接存放值,引用类型的变量存放的是实际对象的地址。
1 | void fun(int a){ |
JAVA只有值传递,没有引用传递。
1 | int a = 10; |
1 | String a = "hello"; |
JAVA中所有对象都继承自object类,equals是object类的方法之一。
1 | public boolean equals(Object obj) { |
但是对于我们常用的String类来说,它重写了equals方法。
1 | String a = "hello"; |
String类的equals方法
1 | public boolean equals(Object anObject) { |
并不是说 == 比较的就是引用是否相等,equals 比较的就是值,具体情况具体分析。
hashCode 值相等,那这两个对象不一定相等(哈希碰撞)。hashCode 值相等并且equals()方法也返回 true,我们才认为这两个对象相等。hashCode 值不相等,我们就可以直接认为这两个对象不相等。如果重写
equals()时没有重写hashCode()方法的话就可能会导致equals方法判断是相等的两个对象,hashCode值却不相等。
操作少量的数据: 适用 String (不可变)
单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder
多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer
如果字符串常量池中不存在字符串对象“abc”的引用,那么会在堆中创建 2 个字符串对象“abc“
如果字符串常量池中已存在字符串对象“abc”的引用,则只会在堆中创建 1 个字符串对象“abc”