第一周总结

时间:2019 年 01 月 02 日 ~ 2019 年 01 月 04 日

一、Linux 网络 I/O 模型

Linux 内核将所有外部设备作为一个文件进行处理,对每个文件的读写操作都会调用内核提供的系统命令,返回一个文件描述符 fd(file descriptor),对一个 socket 的读写也有相应的描述符,称为 socket fd,描述符是一个数字,指向内核中的一个结构体(文件路径、数据区等一些属性)

1.阻塞 I/O
用户进程进行系统调用时开始进入 block 状态,内核开始 I/O 的第一个阶段(准备数据到缓冲区),之后数据准备完成后,开始第二个阶段(将数据从内核缓冲区拷贝到用户进程的内存中),这是用户进程才解除 block 状态,开始重新运行
特点:Blocking I/O 在 I/O 执行的两个阶段都被 block 了

2.非阻塞 I/O
用户进程进行系统调用,I/O 的第一个阶段没有阻塞,但是用户进程需要不停的轮询内核,看数据是否准备好了,I/O 的第二个阶段是阻塞的

3.I/O 复用
用户进程在 I/O 的两个阶段都是阻塞的,但两个阶段是独立的,在一次完整的 I/O 操作中,该用户进程是发起了两次系统调用

4.信号驱动 I/O
用户进程进行系统调用,I/O 的第一个阶段没有阻塞,当数据准备就绪时会为进程生成一个 SIGIO 信号,通过信号回调通知用户进程去读取数据

5.异步 I/O
用户进程进行系统调用,立刻就可以开始去做其他的事情,然后直到 I/O 执行的两个阶段都完成之后,内核会给用户进程发通知,告诉用户进程操作已经完成了

IO 和 NIO

NIO:New IO,在 JDK 1.4 中引入,实现方式和 IO 不同
最大的区别就是 IO 是面向流的,NIO 是面向缓冲区的

IO 是阻塞的,读写操作会阻塞当前线程,知道数据完全被读取或写入
NIO 是(同步)非阻塞的,线程发起请求读写数据,在数据真正读取或写入之前,当前线程不会阻塞,可以继续做其他的事情,只是会不断的轮询是否有可用的数据(select/poll 是顺序扫描 fd 是否就绪,epoll 使用基于事件驱动方式代替顺序扫描,因此性能更高。当有 fd 就绪时,立即回调函数 rollback)

同步与异步区别在于内核是否会主动通知应用程序相应操作已完成
阻塞与非阻塞的区别在于应用程序发出请求后是否只等待内核该操作的响应而不去干别的事
注:如果是同步非阻塞 I/O,应用程序虽不阻塞,但仍需要同过轮询的方式询问内核操作是否完成(对应 I/O 复用中的 select 和 poll)

同步异步描述的是执行 IO 操作的主体,同步为用户进程执行最终的 IO 操作,异步是内核完成 IO 操作后通知用户进程即可
阻塞非阻塞描述的是函数,访问某个函数时,是否会阻塞线程(进入 block 状态)
同步:用户进程参与 IO 操作,操作之前会检查数据是否准备就绪,因此可能会直接阻塞直到数据就绪,也可能通过轮询的方式检测数据就绪状态
异步:操作系统执行 IO 读写操作,用户进程不关心 IO 读写操作,当操作系统完成 IO 读写操作后,会给用户进程发送通知,之后用户进程获取数据即可
阻塞:函数有结果,才返回
非阻塞:函数没有结果,也立马返回
同步非阻塞:用户进程执行 IO 读写操作,读写方法不阻塞,立马返回,但是需要用户进程检查数据是否就绪,虽说是非阻塞,但实际上还是要等待内核把 IO 操作之后的数据复制到用户进程
同步阻塞:用户进程执行 IO 读写操作,读写方法阻塞(有结果才返回),同时需要用户进程检查数据是否就绪,全程都在等
异步非阻塞:操作系统执行 IO 读写操作,并且 IO 操作完成后回调用户进程提供的 callback
异步阻塞:操作系统执行 IO 读写操作,读写方法是阻塞的(select 函数)

二、Comparable 和 Comparator

1.Comparable 的使用

// Comparable 排序称为类的自然排序
public interface Comparable<T> {
    // 类的自然比较方法
    public int compareTo(T o);
}

常见操作就是判断 compareTo() 方法的返回值:
对 a 和 b 进行比较,a.compareTo(b)
大于 0,a > b
等于 0,a == b
小于 0,a < b

① Comparable 排序称为类的自然排序,compareTo() 方法自然排序方法
② 实现 Comparable 接口的对象,对应组成的列表(和数组)可以按 Collections#sort(list) 或 Collections.sort(array) 自动排序。实现此接口的对象可以用作 sorted map 排序映射中的键,也可以用作 sorted set 排序集中的元素,而无需单独再指定 Comparator
③ 当且仅当 e1.compareto(e2)==0 的布尔值与 e1.equals(e2)对于类中的每个 e1 和 e2 的布尔值相同时,类的自然顺序才被称为与 equals 一致。请注意,空值不是任何类的实例,并且 e.compareto(null)应引发nullpointerException,即使 e.equals(null)返回 false
④ 强烈建议(尽管不是必需的)自然顺序与 equals() 方法一致。这是因为没有显式比较器的排序集(和排序映射)在与自然顺序与等于不一致的元素(或键)一起使用时表现出“奇怪”的行为。特别是这样的排序集(或排序映射)违反了集合(或映射)的一般约定,集合(或映射)是根据 equals() 方法定义的
⑤ 如果一个添加了两个键 a 和 b 的代码(a 和 b 不相等):!a.equals(b)&& a.compareto(b)==0,对于不使用显式比较器的排序集,第二个加法操作返回 false(排序集的大小不增加),因为从排序集的角度来看,a 和 b 是等效的

总结:简单来说,自然排序可以使用 Comparable#compareTo() 方法,由于 null 比较特殊,并不是一个对象,所以 comPareTo() 方法此时应抛出空指针异常;因为集合是根据 equals() 方法来判断元素是否相同,所以墙裂建议 compareTo() 方法需要和 equals() 方法保持一致,以免对集合进行修改时出现异常情况

2.Comparator

public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
    ...
}

Comparator 是一个接口,实现类被称之为比较器,compare() 方法作用和 Comparable#compareTo() 方法类似,都用来比较两个对象,只是 Comparator 一般不会被实现,而是在外部单独实现或者作为匿名内部类使用

三、Random 种子的作用、含参与不含参构造函数区别

种子 seed
1.seed 相同,对应的 Random 实例的随机值相同
2.在构造函数中指定了 seed,产生的随机数是固定的值,不指定 seed,则会根据当前时间产生不同的值

四、CharSequence 与 String

都可以用来表示字符串,CharSequence 是接口,String 继承了 CharSequence 接口,并且是 final 类型

五、String 相关、泛型、反射(…)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值