文件是如何组织的

文件系统将硬盘空间以块为单位进行划分,每个文件占据若干个块,然后再通过一个文件控制块 FCB 记录每个文件占据的硬盘数据块。

image.png

这个文件控制块在Linux操作系统中就是inode,要想访问文件,就必须获得文件的inode信息,在inode中查找文件数据块索引表,根据索引中记录的硬盘地址信息访问硬盘,读写数据。

image.png

inode中记录着文件权限、所有者、修改时间和文件大小等文件属性信息,以及文件数据块硬盘地址索引。

RAID5将数据划分为N-1片,再利用N-1片数据进行位运算,得到一片校验数据,然后将这N片数据写入到N个硬盘。这样任何一块硬盘损坏都可以利用校验片的数据和其他片的数据进行计算得到丢失的那个数据,而硬盘的利用率也达到了N-1 / N。这样兼顾了磁盘利用率、读写速度和数据可用性,实际生产中用的最多。

RAID5中校验位的生成采用的是异或运算。所有数据的bit位,逐位进行异或,得到的就是校验位。如果丢失部分数据,用校验数据和其余数据逐位进行异或运算,可到丢失部分数据。举例,5块磁盘做RAID5,四块磁盘上的bit为:0 1 1 1 ,那么异或计算后,校验位为 1,如果丢失了第一块盘上的bit位0,那么校验位1和其他三块盘上的bit位进行异或运算,可以算出0。

进程、线程、协程、管程

进程:资源分配的基本单位
线程:程序执行的基本单位

线程通过Linux的线程调度器进行调度。线程上下文切换指的是CPU保存原线程现场(一般放在CPU的cache中),执行新线程,恢复现场继续执行原线程的过程。

线程分为用户线程和内核线程(OS负责创建),JAVA中的每一个线程都是由JVM负责创建,对应OS中的一个内核线程,JVM中的线程和内核线程数量为1:1

golang在启动的时候会初始化一堆内核线程,goroutine启动之后会放在队列中交给内核线程执行,从这方面来讲go routine更像是一个个task。go routine非常类似Java中的线程池。golang在用户空间模拟了CPU的执行。

TCP/IP

面向无连接的方式下可能会有很多的冗余通信。

为什么IP层面向无连接?

原因有2点:简化和提速。面向连接比面向无连接处理相对复杂,甚至管理每个连接本身是一个相反繁琐的事情。此外每次通信之前需要实现建立连接又会降低处理速度。需要有连接的时候可以委托上一层提供此项服务。因此IP为了实现简单化和高速化采用面向无连接的方式。

为了提高可靠性,上一层的TCP采用面向有连接型。

IP提供尽力服务(Best Effort):为了把数据包发送到目标地址,尽最大努力,并不做最终收到与否的验证。IP数据包可能在途中丢包、错位、数据量翻倍的问题。

为什么IP层不提供可靠传输的功能?

如果要一种协议规定所有的功能和作用,那么该协议的具体实现和编程将会变得非常复杂,相比之下,按照网络分层,明确定义每层协议的作用和责任以后,针对每层协议进行编程会更有利于该协议的实现。

IP包的首部有1个字节表示TTL,表示可以中转多少路由器。每经过一个路由器,TTL会减少1,变为0则丢弃这个包。可以避免IP包在网络中无限传递的问题。

  • IP是分组交换的一种协议,面向无连接,它不具备重发机制,属于非可靠性传输协议。
  • TCP/UDP属于传输层的协议,首部使用的源端口和目标端口进行唯一性确认,而IP地址是位于网络层。

参考资料