diff --git a/docs/CS/CA/notes.md b/docs/CS/CA/notes.md new file mode 100644 index 0000000..b881ea1 --- /dev/null +++ b/docs/CS/CA/notes.md @@ -0,0 +1,88 @@ +# CA + +## Cache + +![image-20241022153457116](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410221534291.png) + +### Miss Penalty Reduction + +#### Critical Word First + +这是一个优化内存读取性能的技术。当 CPU 从内存中读取一个块(通常是一个缓存行)时,如果发生了缓存未命中(cache miss),而且 CPU 需要的只是这个块中的某个特定字,传统方法会从内存中将整个块依次读取到缓存中,然后再提供给 CPU。 + +“Critical Word First” 的策略是优先传输 CPU 当前所需要的那个字(critical word),而不是等待整个缓存行被传输完毕。这使得 CPU 可以尽快继续处理,而无需等待整个块加载完毕。这样可以减少缓存未命中带来的等待时间,提高系统的响应速度。 + +#### Early Restart + +**例子** + +假设某个缓存行由 16 个字组成(比如从 `0x1000` 到 `0x103F`),CPU 请求的字是 `0x1004`。在“Early Restart”下: + +- 当内存控制器从内存开始加载这个缓存行时,一旦 `0x1000` 到 `0x1004` 的部分数据被加载到缓存,内存控制器就立即将这些已加载的数据交给 CPU。 + +#### Giving Priority to Read Misses over Writes + +- If a system has a write buffer, writes can be delayed to come after reads. + +- The system must, however, be careful to check the write buffer to see if the value being read is about to be written. + +在缓存系统中,缓存需要处理读操作和写操作。当发生缓存未命中时,读操作(read miss)意味着 CPU 需要的数据当前不在缓存中,而写操作(write)则是将 CPU 产生的数据写入缓存或内存。在这两者发生冲突时,优先处理哪一种操作会影响系统的性能。 + +“Giving Priority to Read Misses over Writes” 是一种策略,即当系统检测到读未命中和写操作同时发生时,它会优先处理读未命中。原因是读操作通常对 CPU 的性能有更大影响,因为 CPU 需要读取数据来执行指令。如果读操作被延迟,CPU 就必须等待,而写操作一般可以稍后再执行。 + +**例子** + +假设一个系统正在执行以下操作: + +- CPU 请求从内存中读取一个数据,但该数据不在缓存中(读未命中)。 +- 同时,缓存中还有一些待写入内存的数据(写操作)。 + +在这种情况下: + +- 系统会优先处理读操作,尽快将读请求的数据从内存加载到缓存中,这样 CPU 就可以继续执行。 +- 写操作被延迟,等到读操作完成后再处理。这种做法的目的是减少读操作的延迟,避免 CPU 停滞,提高系统性能。 + +### Reduce + +1.Reduce the miss penalty + +2. Reduce the miss rate + +- Complier Optimization + - Loop + - Matrix + - Loop Fusion + - Merging Array +- + + + + + + + +2. Reduce the miss penalty and miss rate via parallelism + +- Nonblocking Caches +- Hardware Prefetching of Instructions and data +- Compiler-controlled prefetch + - Binding prefetch + - Non-Binding prefetch + +​ + +3. Reduce the time to hit in the cache. + +**Small and Simple Caches** + +Direct-mapped is faster than set associative for both reads and writes. + +Fitting the cache on the chip with the CPU is also very important for fast access times. + + + +**Avoiding Address Translation during Indexing of the Cache** + +**pipelined Cache Access** + +**Trace Cache** \ No newline at end of file diff --git a/docs/CS/CN/notes.md b/docs/CS/CN/notes.md new file mode 100644 index 0000000..d47497c --- /dev/null +++ b/docs/CS/CN/notes.md @@ -0,0 +1,745 @@ +# Computer Network + +## Data Link Layer + +### 功能 + + 成帧 (Framing) + +- 将比特流划分成“帧”的主要目的是为了检测和纠正物理层在比特传输中可能出现的错误,数据链路层功能需借助“帧”的各个域来实现 + + 差错控制 (Error Control) + +- 处理传输中出现的差错,如位错误、丢失等 + + 流量控制 (Flow Control) + +- 确保发送方的发送速率,不大于接收方的处理速率 + - 避免接收缓冲区溢出 + +#### 成帧 + +##### 字节计数 + +![image.png](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111632475.png) + +##### 带字节填充的定界符法 + +![image.png](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111631960.png) + +![image.png](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111632503.png) + +>[!note] +> +>![image-20241011163429012](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111634101.png) + +##### 带**比特**填充的定界符法 + +![image-20241011163521376](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111635477.png) + +![image-20241011163538953](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111635038.png) + +![image-20241011163552157](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111635251.png) + +##### 物理层编码违例 + +![image-20241011163853843](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111638975.png) + +#### 差错控制 + +![image-20241011163959106](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111639208.png) + +#### 流量控制 + +![image-20241011164012459](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111640536.png) + +### 差错检测和纠正 + +**如何解决信道传输差错问题** + +![image-20241011165139877](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111651973.png) + +- **code word 码字**:包含m个数据位和r个校验位的n位单元 + - 描述为 (n, m) 码,n=m+r +- **码率 (code rate)**:码字中不含冗余部分所占的比例,可以用m/n表示 +- **海明距离 (Hamming distance)** + - **两个码字的海明距离**:两个码字之间*不同对应比特的数目* + - 例:0000000000 与0000011111的海明距离为5 + - 如果两个码字的海明距离为d,则需要d次单比特纠错就可以把一个码字转换成另一个码字 + +>[!note] +> +> **The error-detection and error-correcting properties of** **a code depend on its Hamming distance.** +> +>To detect *d* errors: +> +> - you need *d+1* Hamming distance code. (Because with such a code there is no way that *d* single-bit errors can change a valid code into another valid codeword). +> +>To correct *d* errors: +> +> - you need *2d*+1 Hamming distance code. (Because that way the legal codewords are so far apart that even with *d* changes (A->A’), the original codeword *A* is still closer to *A’* than any other codeword *B*, so it can be uniquely determined.) +> +>>[!note] 练习 +>> +>>Ex2: consider a coding scheme: • 00 => 00000 00000 • 01 => 00000 11111 • 10 => 11111 00000 • 11 => 11111 11111 • Its Hamming distance is ? + +#### • 检错码(error-detecting code) + +• 主要用在高可靠、误码率较低的信道上,例如光纤链路 + +• 偶尔发生的差错,可以通过重传解决差错问题 + +##### 奇偶检验 (Parity Check) + +**交错检验** + +![image-20241011171937581](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111719734.png) + +##### 校验和 (Checksum) + +主要用于TCP/IP体系中的网络层和传输层 + +![image-20241011171422172](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111714271.png) + +- 溢出位的1要加入 + +![image-20241011172237002](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111722131.png) + +##### 循环冗余校验 (Cyclic Redundancy Check,CRC) + +数据链路层广泛使用的校验方法 + +![image-20241011174239132](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410111742227.png) + +- 这里的计算实质上都是对两个数进行亦或操作 + +>[!example] example +> +>image-20241011174045439 + +#### • 纠错码(error-correcting code) + +• 主要用于错误发生比较频繁的信道上,如无线链路 + +• 也经常用于物理层,以及更高层(例如,实时流媒体应用和内容分发) + +• 使用纠错码的技术通常称为前向纠错(FEC,Forward Error Correction) + +![image-20241011214126847](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410112141952.png) + +##### 海明码 Hamming codes + +- 被检验数据位的海明位号等于检验的各个检验位的海明位号之和 + +**如何求编码后的码字** + +img + +- 把一个数据为拆为某几个检验位的和,$P_n$检验位的值就等于所有使用到这个检验位的数据位的异或的结果 +- 检验原理就是将这个过程重新进行 + +**见王道 P62 ** + +##### Reed-Solomon code + +![image-20241011220647011](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410112206154.png) + +##### 卷积码 convolutional codes + +![image-20241011220756739](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410112207810.png) + +- 一个不断移动的输入序列,对它做convolution +- 卷积码的输出由当前输入和之前若干位输入决定,影响当前输出的此前输入位数称为 约束长度 constraint length。如图这种卷积码的约束长度为 6,每个输出 bit 会带来 2 bits 的输出,其中第一个是第 0, 2, 3, 5, 6 位的模二加法(0 指输入位,1~6 指 S1~S6 的值),第二个是第 0, 1, 2, 3, 6 位的模二加法。比如输入序列为 111,输入第一个 1 时 0~6 位是 1000000,因此输出是 11,然后 S1~S6 右移一位变成 100000;输入第二个 1 时为 1100000,因此输出是 10;输入第三个 1 时为 1110000,因此输出是 01。因此编码后为 111001。 + +>[!example] example +> +>![image-20241011221423389](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410112214496.png) + +**解码** + +在所有可能的输出序列中找出与接收到的序列最相近的那一个,解码为这个序列对应的输入序列。 + +>[!example]example +> +>![image-20241011221157854](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410112211964.png) +> +> - S表示不同的输入记忆,通过新的输入进入下一个状态的S + +##### 里所罗门码 Reed-Solomon codes + +##### 低密度奇偶校验码 LDPC, Low-Density Parity Check + +### 基本的数据链路层协议 + +![image-20241011224107845](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410112241982.png) + +**关键假设** + +![image-20241011224237214](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410112242324.png) + +#### 乌托邦式单工协议 A Utopian Simplex Protocol + +• 单工(Simplex)协议:数据单向传输 + +• 完美信道:帧不会丢失或受损 + +• 始终就绪:发送方/接收方的网络层始终处于就绪状态 + +• 瞬间完成:发送方/接收方能够生成/处理无穷多的数据 + +![image-20241011224340934](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410112243043.png) + +#### 无错信道上的停等式协议 A Simplex Stop-and-Wait Protocol for an Error-Free Channel + +- 数据传输保持单向, 但是需要双向传输链路(半双工物理信道) + +接收方每当接收一个帧并处理完成后,发回一个确认帧;发送方在收到确认帧后(不需要处理,因为此时唯一的可能就是确认帧),则可以发送下一帧。这种协议在数据传输上是单工的,但是接收方需要发回消息,因此需要使用半双工信道。这种方案的实际问题在于,没有考虑出现错误的情况。 + +![image-20241011224519328](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410112245441.png) + +#### 有错信道上的单工停等式协议 + +![image-20241011225307188](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410112253309.png) + +![image-20241011231558665](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410112315784.png) + +- 考虑 3 种可能的错误 +- **接收到的帧检出错误** 为了解决第 1 种错误,我们引入一个新的事件 CKSUM_ERR 表示校验和有误;因而接收方在收到一个帧后应当校验正确性,发回一个表示正确或者错误的确认帧;如果检出错误,则直接抛弃该帧等待重传。如果发送方收到了表示错误的确认帧导致事件 CKSUM_ERR 发生,那么发送方将重新发送上一帧。 +- **发送方发送的帧完全丢失** 对于第 2 种错误,**接收方完全没有接到一个帧,因而也不可能对此作出确认。**为了避免这种情况,发送方每次发送一个帧后启动或重置一个计时器,这个计时器的时间应当长于预期正常情况下收到确认帧的时间。如果计时器超时发送方仍未收到确认帧(事件 TIMEOUT),那么第 2 种错误有可能发生,此时发送方会将(缓存下来的)刚刚发出去的那一帧重新发出一次。直至发送方收到一个积极的确认帧,此时发送方再加载下一帧,上一帧的缓存即可以被覆盖掉。 +- **接收方的确认帧丢失,重发可能导致收到重复的帧** 但是需要考虑的是,除了第 2 种错误,这种问题也可能导致发送方没有收到确认帧,因此可能会将一个正确收到(没有被抛弃)的帧重发,导致接收方收到两个该帧;如果不加限制,接收方的网络层则可能收到重复两次的该数据段,引起错误。我们需要防止这种重复的发生。考虑到发送方发送第 i + 1 帧的充要条件是第 i 帧已经收到了正确的确认,而这一确认的必要条件是接收方已经正确收到了第 i 帧。因此我们只需记录每一帧序号的奇偶性,并将其包含在帧头中(称为字段 seq)。如果接收方接收到了预期的(与前一帧相反的)奇偶标记,那么就将其保存;否则就说明前一帧被重复发送了,此时则直接抛弃该帧,同时发回一个确认(作为对前一个丢失确认帧的补充)。 + +#### 效率的评估 + +• F = frame size (bits) + +• R = channel capacity (Bandwidth in bits/second) + +• I = propagation delay + processor service time (second) + +• 每帧发送时间 (Time to transmit a single frame) = F/R + +• 总延迟 (Total Delay) = D =2I + +• 停止等待协议的发送工作时间是F/C,空闲时间是D + +• 当 F[!note] +> +> **捎带确认 piggybacking** +> +>![image-20241012144857669](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121448774.png) + +发送方和接收方都具有一定容量的缓冲区(即窗口),发送端在收到确认之前可以发送多个帧 + +**目的** + +- 对可以连续发出的最多帧数(已发出但未确认的帧)作限制 + +**序号使用** + +- 循环重复使用有限的帧序号 + +**流量控制**:接收窗口驱动发送窗口的转动 + +- 发送窗口:其大小记作WT,表示在收到对方确认的信息之前,可以连续发出的最多数据帧数 +- 接收窗口:其大小记作WR ,为可以连续接收的最多数据帧数 + +**累计确认**:不必对收到的分组逐个发送确认,而是对按序到达的最后一个分组发送确认 + +![image-20241012144611307](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121446430.png) + +- 接收到接收窗口之外的帧会丢弃 + +#### 回退N协议 Go-Back-N | GBN + +其中 N 代表 sending window 的大小,而这种协议中 receiving window 的大小始终为 1。当当前 sending window 的第一帧的计时器(实际上每一帧发出后都启动一个独立的计时器)超时仍未得到 ACK 时,回退 N 位到 sending window 的开头重新发送这 N 帧;而由于 receiving window 的大小是 1,因此提前到达的帧都会被抛弃。 + +![image-20241012150736516](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121507621.png) + +**接收方:** + +1. 窗口尺寸:WR=1 +2. 按序接收:按照PDU编号依序接收,出错、乱序PDU一律丢弃 +3. 确认含义:ACK(k)表示对k-1及以前各编号的PDU的确认,同时期望接收第k号PDU +4. 确认策略:按序到达的PDU可立即确认,也**可延迟确认(收到多帧后一起确认)**,但出错或乱序的PDU,确认ACK(k)(期望接收k号PDU)或不应答 + +>[!example]example +> +>![image-20241012151653444](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121516540.png) +>![image-20241012151710027](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121517152.png) + +>[!note] +> +> **发送窗口的最大尺寸问题** +> +>$1 +>序号是重复使用的 + +#### 选择重传协议 SR + +![image-20241012152412858](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121524965.png) + +![image-20241012153621823](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121543464.png) + +发送方必须响应的三件事 + +• 上层的调用:检测有没有可以使用的序号,如果有就发送 + +• 收到ACK:如果收到的是最小序号的ACK,窗口滑动。如果收到其他序号的 + +ACK,进行标记 + +• 超时事件:每个PDU都有定时器,哪个超时重传哪个 + +>[!example]example +> +>![image-20241012153814965](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121538080.png) +> +>![image-20241012153832425](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121538522.png) + +### 数据链路协议实例 + +#### PPP协议 | Point-to-Point Protocol + +目前使用最多的数据链路层协议之一 + +![image-20241012154747738](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121547917.png) + +- 但是HDLC是 bit 填充的,PPP是byte填充 + +**帧格式** + +![image-20241012154635886](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121546970.png) + +![img](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121550052.png) + +![image-20241012155543411](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410121555491.png) + +### 信道利用率 + +#### Stop-Wait | SW 停等协议 + +王道 P69 + +利用率 $U = \frac{T_D}{T_D+RTT+T_A}$ + +发送时间延迟 $T_D = \frac{分组长度}{传输速率}$,接收方发送确认message的时间延迟$T_A$​一般忽略不计 + +往返时延 RTT + +#### 连续ARQ协议 + +ARQ包括GBN和SR + +利用率$U=\frac{nT_D}{T_D+RTT+T_A}$ + +可能达到1,在一个周期内发送不完,不间断发送 + +## 介质访问子层 | MAC + +>[!note] 知识点 +> +>![image-20241022102654624](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410221027770.png) + +image-20241022102754213 + +>[!faq]- Are callouts foldable? +>Yes! In a foldable callout, the contents are hidden when the callout is collapsed. + +**网络链路** + +- 点到点连接 +- **使用广播通道** multiaccess channel / random access channel +![](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410191140439.png) + +![image.png](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410191142275.png) + +>[!note]- 关于广播信道 +> +>![image-20241022104448204](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410221044357.png) +> +> - 可能两个(或更多)站点同时请求占用信道 +> +> **静态方法** +> +> - FDM 分频 +> - TDM 分时 + +### 多路访问协议 + +image-20241022104933535 + +#### ALOHA + +**纯种Aloha** +![image.png](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410191154902.png) +吞吐率max:$\frac{1}{2e}$ + +**分槽** + +必须等到下一个时间槽开始的时刻才能发送数据 + +image-20241022105336275 + +$\frac{1}{e}$ + +>[!note] 性能分析 +> +> **帧时**:发送一个标准长的帧所需的时间 +> +> **吞吐量(Throughout) S** : 在发送时间T内发送成功的平均帧数 +> +> **运载负载(Carried load) G**,又称网络负载:时间T内所有通信站总共发送的帧平均值(包括原发和重发的分组) +> +> **$P_0$**:$P_0$是一帧发送成功(即未发生冲突)的概率 +> +> - 可以得到$S = G*P_0$​ +> - 对于纯的,$P_0=e^{-2G}$ +> - slotted,$P_0=e^{-G}$ +> +> **单向传播延迟Delay**:D +> +> **冲突危险期:**2*D +> +> - 不遭受冲突:$P_0=e^{-2G}$ +> +>>[!note] - $P_0的计算$ +>> +>>![image-20241022105906778](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410221059893.png) + +#### 载波侦听多路访问协议 | CSMA | Carrier Sense Multiple Access + +##### 1 - Persist CSMA + +![image.png](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410191202157.png) + +**存在冲突的情况** + +- 如果存在两个站同时侦听一条信道,之后会同时发送,也会冲突 +- 由于propagation delay,在发送过程中另外一个站侦听到的信道是空闲的 + +##### non-persist + +![image.png](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410191209747.png) + +- 一定程度上避免了上述情况 1 + +##### p-persist + +只适用于time slot + +- 只是修改了概率,将空闲时的发送改为概率 p 发送 +- 忙的时候,会持续监听(在下一个时隙) + +##### 带冲突检测的 CSMA / CD + +- 网络只能采用半双工通信 +- 争用期 = 2 * 时延 +- 最短帧长(争用期内发送的数据长度) = 时延 * 2 * 传播速率 + - 发送时间太短无法区分是哪个出了问题 +- 如果争用期无冲突,则后续也无冲突 + +![image-20241022110650602](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410221108833.png) + +![image-20241019154627044](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410191546129.png) + +#### 无冲突协议 | 受控访问协议 + +##### 位图协议 + +![image-20241022111114180](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410221111316.png) + +![image-20241019155120470](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410191551555.png) + +##### Token ring + +![ ](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410191628644.png) + +##### Binary Counter + +![image-20241022111433492](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410221114627.png) + +![image-20241019162818450](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410191628621.png) + +#### Limited-contention protoco 有限竞争协议 + +**自适应树遍历协议** + +![image-20241019164136695](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410191641768.png) + +[自适应树游走协议题目题解_牛客竞赛OJ (nowcoder.com)](https://ac.nowcoder.com/acm/problem/blogs/222206) + +### 以太网 + +>[!note] 需要记忆 +>- **10 Base-T** 10 Mbps 双绞线 +>- **1000Base-T** 1000 Mbps 双绞线 +>- **100Base-FX** 光纤 + +- 以太网通过 二进制指数后退 binary exponential backoff 算法确定每次冲突后的等待时间。 + 我们将时间按照 51.2μs 分块;在第 i = 1 ~ 15 次冲突发生后,站等待 0 ~ min((2^i-1), 1023) 个时间槽后再次尝试发送;在发生 16 次冲突后,它放弃发送并给上层返回一个失败报告;高层协议负责进一步的恢复工作。这种算法的考量是,如果等待时间的上限较低,那么多个站发生冲突的时候很可能再次发生冲突;而如果上限较高,则很有可能发生很多无意义的延迟。这种算法可以保证:如果只有少量站发生冲突,则可以保证较低的延迟;当许多站发生冲突时,它也可以保证在一个相对合理的时间内解决冲突。 + +#### 经典以太网 + +##### 物理层 + +- 使用曼彻斯特编码 +- 使用同轴电缆和中继器连接 + +image-20241022113251135 + +##### Mac层 + +- 主机运行CSMA/CD协议 + - 网络层不负责重传,会直接丢弃不符合要求的Packet + - 等待随机一段时间后重发,那么这个时间长度如何确定? + ![image-20241022114144279](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410221141384.png) + +![image-20241022113323331](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410221133436.png) + +![image-20241022113347786](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410221133939.png) + +- 使用ipconfig /all命令查看MAC地址 +- **源地址后面的两个字节**,Ethernet V2将其视为上一层的协议类型,IEEE802.3将其视为数据长度 + - 大的表示长度 + - 小的表示类型 +- **数据字段** + - 46 ~ 1500字节 + - 最小帧长 = 46+18 = 64B + - 最大帧长 = 1500+18 = 1518B (MTU:1500B) + - 数据字段不足46字节,需要填充整数字节(Padding)至46字节,以保证以太网MAC帧不小于64字节。 + - 以太网规定最短有效帧长为 64 字节,凡长度小于 64 字节的帧都是由于冲突而异常中止的无效帧。 + +#### 交换式以太网 + +使用集线器(HUB)组建以太网 + +![image-20241023230010544](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410232300717.png) + +- 交换式以太网的核心是交换机(Switch) + - 工作在数据链路层,检查 MAC 帧的目的地址对收到的帧进行转发 + - 交换机通过高速背板把帧传送到目标端口 + +>[!note] - hub & switch +> +>![](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410221147602.png) + +### 数据链路层交换原理 + +- 数据链路层设备扩充网络 + - 网桥或交换机 + - 分隔了冲突域 + +![image-20241023230221005](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410232302148.png) + +#### **基于Mac地址的学习和转发** + +透明网桥使用 **MAC地址** 进行数据包的转发,而不依赖于IP地址或其他高层协议。这种方式是透明的,因为: + +- 网桥在监听数据包时,不改变数据包的内容。 +- 它通过监听网络中的流量,**学习每个设备的MAC地址**,并将其记录在内部的转发表中(称为 **MAC地址表**)。 +- 当网桥第一次接收到数据包时,会查看目的MAC地址是否在MAC地址表中。 + - 如果存在,网桥会直接将数据包转发到相应的端口。 + - 如果不存在,网桥会将数据包**泛洪**到除发送端口外的所有端口,这样确保数据包能够到达目标设备。 + - 当目标设备响应时,网桥就可以学习到该设备的MAC地址,并将其加入MAC地址表,以便将来能够直接转发。 + +**MAC地址的构建** + +- 增加表项:帧的源地址对应的项不在表中 +- 删除表项:老化时间到期 +- 更新表项:帧的源地址在表中,更新时间戳 + +![image-20241023230805281](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410232308423.png) + +**入境帧的处理** + +![image-20241023230919595](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410232309760.png) + +![image-20241023230925282](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410232309406.png) + +![image-20241023230952859](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410232309986.png) + +• 广播帧:目的地址为FF-FF-FF-FF-FF-FF的数据帧 + +• 未知单播帧:目的地址不在MAC地址转发表中的单播数据帧 + +#### 链路层交换机 + +![image-20241023231532271](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410232315415.png) + +**交换方式 : 带宽** + +- 对称 +- 非对称 + +![image-20241023231548802](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410232315927.png) + +| **特性** | **存储转发模式(Store and Forward)** | **直通模式(Cut-through)** | **无碎片模式(Fragment-free)** | +|---------------------|------------------------------------|-----------------------------|-------------------------------------| +| **数据接收方式** | 接收完整帧 | 读取到目标MAC地址后立即转发 | 接收前 64 字节后再转发 | +| **错误检查** | 完整检查帧校验序列(FCS) | 不进行错误检查 | 检查前 64 字节 | +| **延迟** | 较高(需等待完整帧) | 较低(目标MAC地址解析后立即转发) | 中等(接收 64 字节后转发) | +| **可靠性** | 高(能过滤错误数据帧) | 低(可能传播错误数据帧) | 中等(过滤大部分碰撞和错误帧) | +| **适用场景** | 企业级网络、数据中心 | 高性能计算、金融交易、实时通信 | 一般网络环境,有中等时延和可靠性要求 | +| **网络带宽效率** | 较低(过滤错误帧,消耗带宽) | 较高(快速转发,无错误检查) | 适中(减少小部分无效流量) | +| **碰撞检测** | 完全检测 | 无检测 | 前 64 字节内检测 | +| **数据完整性保证** | 最好 | 最差 | 中等 | + +#### 生成树协议 + +打破了物理环,维护一个逻辑无环树 + +**Why Choose It** + +![image-20241023231656883](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410232316021.png) + +**生成树协议** + +- **根桥ID(Root ID)**: 被选为根的桥ID。 + - 桥ID共8字节,由2字节的优先级和6字节的MAC地址组成的。 +- **根路径开销(Root Path Cost)**: 到根桥的最小路径开销。 +- **指定桥ID(Designated Bridge ID)**: 生成和转发BPDU的桥ID +- **指定端口ID(Designated Port ID)**: 发送BPDU的端口ID + +**选举过程** + +![image-20241024121411262](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410241214410.png) + +(1) 选举根桥(Root Bridge) 。 + +- ID最小的交换机(网桥)成为生成树的根 +- 根桥的所有端口都处在转发状态 + +(2) 为每个非根桥选出一个根端口(Root Port)。 + +- 每个非根桥,通过比较其每个端口到根桥的根路径开销,选出根端口 +- 具有最小根路径开销的端口被选作根端口 + - 根路径开销相同,则端口ID最小的端口被选作根端口 +- 非根桥只能有一个根端口,根端口处于转发状态 + +![image-20241024121200596](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410241212773.png) + +(3) 为每个网段确定一个指定端口(Designated Port)。 + +- 对于每一个网段, 在所有连接到它的交换机(网桥)端口中进行选择 + - 一个具有最小根路径开销的端口,作为该网段的指定端口 +- 指定端口处于转发状态,负责该网段的数据转发 + +![image-20241024121438376](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410241214507.png) + +### 虚拟局域网 | VLAN + +>[!note]- 广播域的概念 +> +>![image-20241024121721384](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410241217512.png) + +- 一个VLAN(Virtual LAN)是一个独立的广播域 +- 交换机通过划分VLAN,来分隔广播域 + +![image-20241024121825431](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410241218594.png) + +- 不同VLAN的成员通信需要通过三层设备 + +![image-20241024121854740](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410241218906.png) + +**Tagged Frame** + +![image-20241024122158300](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410241221425.png) + +**Access 链路类型端口** + +![image-20241024122220556](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410241222696.png) + +**Trunk 链路类型端口** + +![image-20241024122250978](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410241222146.png) + +### 无线局域网 wireless LAN + +LAN 本质上都是广播的 + +## 题目 + +### Data Link Layer + +**计算SW的利用率** + +- A channel has a bit rate of 4 kbps and a propagation delay of 20 msec. For what range of frame sizes does stop-and-wait give an efficiency of at least 50 percent? + +--- + +- Consider an error-free 64-kbps satellite channel used to send 512-byte data frames in one direction, with very short acknowledgements coming back the other way. What is the maximum throughput for window sizes of 1, 7, 15? The earth-satellite propagation time is 270 msec. (give your answer as an integer) + **A.**A. for window size=1: bps + **A.**A. for window size=7: bps + **A.**for window size=15: bps + + + +--- + +A 100-km-long cable runs at the T1 data rate. The propagation speed in the cable is 2/3 the speed of light in vacuum. How many bits fit in the cable? + +**A.** bits + +--- + +**Go-back-n 的窗口大小** + +Assume the sequence number has 5 bits. What is the maximum number of outstanding sending frames for a go back N protocol? + +$2^n-1$ + +--- + +**Go-back-n 的重传机制** + +After the sender first sends frames from 0 to 6 and at the end of timeout receives the acknowledgements for frame 1, 3, and 5, the next frame it will re-transmit is frame ______6__. (assume the protocol is go-back-n) + +- 1 +- 2 +- 5 +- 6 + +Box 1: Select the best answer + +--- + +### MAC + +ch4-2. A group of N stations share a 56-kbps pure ALOHA channel. Each station outputs a 1000-bit frame on an average of once every 100 sec, even if the previous one has not yet been sent (e.g., the stations can buffer outgoing frames). What is the maximum value of N? + +**A:** 1030 + +--- + +**Q.** What is the baud rate of the standard 10-Mbps Ethernet? +**A.** 20 Mbaud + +--- + +The reason for binary exponential backoff in the classical Ethernet is that________ + +- this algorithm is simple +- this algorithm is fast +- **this algorithm is adaptive to network load** +- this algorithm is scalable to network size + +Box 1: Select the best answer + +--- + +**网络接口卡(Network Interface Card,NIC)** 主要在 **物理层** 和 **数据链路层** 工作。以下是这两个层级的具体作用: + +1. **物理层(Physical Layer)**: + - 网络接口卡负责将计算机生成的二进制数据转换为电信号(如电压或光信号)并通过物理介质(如网线或光纤)进行传输。它同样负责接收从网络介质上传输过来的电信号并将其转换回二进制数据。因此,网络接口卡在物理层上扮演了重要角色。 +2. **数据链路层(Data Link Layer)**: + - 网络接口卡在数据链路层上负责帧的构建和解析。它处理数据包的封装,将数据包封装为帧并添加数据链路层的头部信息(如源和目标 MAC 地址)。另外,它还负责错误检测和简单的纠错功能(例如通过校验和 CRC 检查数据完整性)。当接收到数据帧时,NIC 会解析这些帧并将其传递给更高层的网络协议进行进一步处理。 + +--- + + + diff --git a/docs/CS/OS/Ch1_Overview.md b/docs/CS/OS/Ch1_Overview.md index 28326be..ba70a40 100644 --- a/docs/CS/OS/Ch1_Overview.md +++ b/docs/CS/OS/Ch1_Overview.md @@ -69,6 +69,10 @@ graph LR ![image.png](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202409181501574.png) +**状态切换** + +- + ### Timer >一般包含一个 clock 和一个 counter,每次 clock tick 都会使 counter--,counter 等于 0 触发中断。 @@ -137,4 +141,24 @@ https://note.hobbitqia.cc/OS/chap01/#system-calls >[!quote] What is a `rootfs `? >**The root filesystem is at the top of the hierarchical file tree** (also known as ‘/’). The Linux kernel directly mounts rootfs through the configuration argument ‘_root=_‘. The root filesystem also has mount points where we can mount other filesystems as well in order to connect them to this filesystem hierarchy. It has a number of directories containing files critical for booting the system and system operations. >相较于其他文件系统,rootfs 的特殊之处就在于它是第一个被挂载的文件系统,且其被挂载之后,将启动一些默认的初始化程序。 ->比如,在命令 `` \ No newline at end of file +>比如,在命令 `` + +## 题目 + +Which of the following instructions should be privileged(in kernel mode)? + +a. Set value of timer. + +b. Read the clock. + +c. Clear memory. + +d. Issue a trap instruction. + +e. Turn off interrupts. + +f. Modify entries in device-status table. + +g. Switch from user to kernel mode. + +h. Access I/O device. \ No newline at end of file diff --git a/docs/CS/OS/Ch2_Process.md b/docs/CS/OS/Ch2_Process.md index 2beed1c..1a927b3 100644 --- a/docs/CS/OS/Ch2_Process.md +++ b/docs/CS/OS/Ch2_Process.md @@ -92,17 +92,35 @@ A `process` is one program being executing. (`job` 是历史遗留的称呼) ![image.png](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202409281709506.png) -- `Fork` 创建一个新的进程,对于新创建的子进程,其返回值为 0 否则为 pid 值 +- `Fork` 创建一个新的进程,对于新创建的子进程,其返回值为 0 returns the child’s pid to the parent, and 0 to the child. >[!note] From Linux `fork` Manual >The child process is an exact duplicate of the parent process except for the following points: +> >- does not inherit its parent's memory locks > >**Return value** >On success, the PID of the child process is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created, and err no is set appropriately. +> +>>[!Example]example +>>How many processes does this C program create? +>> ``` +>> int main (int argc, char *arg[]) +>> { +>> fork (); +>> if (fork ()) { +>> fork (); +>> } +>> fork (); +>> } +>> ``` +>> +>>The answer should be 12. +>> +>>#todo:给出树形图 -- `Exec` 载入新的二进制程序,顶替之前的镜像 -- `waie` 父进程阻塞,等待子进程 +- `Exec` 载入新的二进制程序,顶替之前的镜像。用在`fork`函数调用之后 +- `wait` 父进程阻塞,等待子进程 **Resource sharing 的分类** @@ -122,6 +140,30 @@ A `process` is one program being executing. (`job` 是历史遗留的称呼) - 要么是父进程的 duplicate - 要么 load 另一个程序 +```c +#include +#include +#include +int value = 10; +int main() +{ + pid_t pid; + pid = fork(); + value += 10; + if (pid == 0) + { /* child process */ + value += 5; + printf("CHILD: value = %d", value); /* LINE C 25 */ + } + else if (pid > 0) + { /* parent process */ + wait(NULL); + printf("PARENT: value = %d", value); /* LINE A 20 */ + exit(0); + } +} +``` + ### Termination **Exit** : A process terminates when it finishes executing its final statement and asks the operating system to delete it by using the ` exit() ` system call. 运行结束 diff --git a/docs/CS/OS/Ch3_Threads.md b/docs/CS/OS/Ch3_Threads.md index ac37e01..a435d77 100644 --- a/docs/CS/OS/Ch3_Threads.md +++ b/docs/CS/OS/Ch3_Threads.md @@ -11,4 +11,154 @@ update: <% tp.date.now("YYYY-MM-DD HH:mm:ss") %> # Thread & Concurrency -## \ No newline at end of file +## Definition + +**共享资源** + +- code section +- data section +- the heap (dynamically allocated memory) +- open files and signals + +**Advantages of Threads** + +- **Economy** + - Creating a thread is cheap + + 如果已经有了一个线程,那么我们创建新的线程只需要给它分配一个栈。Code,data,heap 都已经在内存里分配好了。 + + - Context switching between threads is cheap + + Cache is hot, no need to cache flush. + +- **Resource Sharing** + - Threads naturally share memory + - Having concurrent activities in the same address space is very powerful +- **Responsiveness** + + 如在 web server 中,一个线程在等待 I/O,当有请求来时就再分配一个线程去处理。(进程也可以,但是代价更大) + +- **Scalability** + - multi-core machine 可以并行 + +**Drawbacks** + +- Weak isolation between threads + + 如果有一个线程出错,那么整个进程都会出错。 + +![image-20241011083910439](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410110839636.png) + +一个 Thread 中需要存储的资源 + +- Registers +- Stack +- PC + +`ps -ef`可以查看 kernel threads on a running Linux system + +## Multicore Programming + +- 并行一定并发 +- 并发其实是在multi-core出现之前,多数计算机使用调度实现“多个程序同时运行的假象” + +**Concurrent** + +![image-20241011090434557](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410110904669.png) + +**Parallelism** + +image-20241011095520860 + +- 并行的种类(看他们分发到不同core的内容是什么,实际上更可能是混合使用) + - Data Parallelism 比如数组求和,使用多个core分别计算 + - Task Parallelism + +## Multithread Models + +- **kernel threads** are supported and managed directly by the operating system +- **User threads** are supported above the kernel and are managed without kernel support + +![image-20241011090557088](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410110905149.png) + +### Models + +- Many to one + - The scheduling is **done completely by the thread library** and the kernel itself is not aware of the multiple threads in user-space. + - 不能够利用多核的优势 + +image-20241011090957005 + + + +- One-to-one + - 主流方式 + - **disadvantage** 创建user和kernel 必须一一对应,可能占用大量资源 + +image-20241011091256231 + +- Many-to-Many + - + - 更加复杂 +- Two-Level + - 可供选择 + +image-20241011091910947 + +## Thread Issues + +### The `fork()` and `exec()` + +在 Process 中,进行 `fork` 会创建新的进程,对于它的线程,有两种情况 + +- Duplicate all threads +- Duplicate only thread that calls fork. 这种情况一般是之后要紧跟着一个 `exec`,Duplicate all 没有意义 + +### Signal Handling + +### Cancellation + +**target thread**:A thread that is to be canceled is often referred to as the target thread. + +Terminating a thread before it has finished + +- **Asynchronous cancellation** terminates the target thread immediately 直接关闭 +- **Deferred cancellation** allows the target thread to periodically check via a flag if it should be cancelled + +### Thread-Local Storage | TLS + +### Thread Pool + +创建好一系列 Thread, 让他们在 Pool 中等待 + +Ad: + +- Usually slightly faster to service a request with an existing thread than create a new thread +- Allows the number of threads in the application (s) to be bound to the size of the pool 限制 thread 的数量 + +### Thread Activation + +>Kernel 和 user level kernel 的 Communication 问题 + +>[!note] LWP | lightweight process +> +>intermediate data structure between the user and kernel threads. +>- If a kernel thread blocks (such as while waiting for an I/O operation to complete), the LWP blocks as well. Up the chain, the user-level thread attached to the LWP also blocks. +>![image.png](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410181816919.png) + +在 many-to-many/two-level 的情况下,很多时候需要通过 Kernel 通知上层的 user 来进行调度 + +- Kernel 提供了一个 application with many virtual processors(LWPS),它负责将 user thread 映射到 available virtual processor +- **upcall** kernel inform + - handled by the **thread library** with an upcall handler, upcall handlers must run on a virtual processor. + +## Thread Lib + +- Kernel Level + - Windows +- User Level + +two general strategies for creating multiple threads: + +- **asynchronous threading** +- **synchronous threading** diff --git a/docs/CS/OS/Ch5_CPU Scheduling.md b/docs/CS/OS/Ch5_CPU Scheduling.md index e63a509..a0e1a0b 100644 --- a/docs/CS/OS/Ch5_CPU Scheduling.md +++ b/docs/CS/OS/Ch5_CPU Scheduling.md @@ -10,7 +10,7 @@ update: 2024-10-09 14:02:58 # CPU Scheduling -> 这一章的笔记很大一部分是在 HabbitQia 学长的笔记基础上增改的 +>这一章的笔记很大一部分是在 HabbitQia 学长的笔记基础上增改的 ## CPU Scheduling @@ -82,13 +82,14 @@ Selects from among the processes in memory that are ready to execute, and alloca 比如这里,我们将进程 2 运行,就将它从 ready queue 里拿出来。随后如果他要读硬盘,我们就把 PCB2 挂载到 disk unit 0 的 device queue 上。 -!!! Example - -
- - parent call fork 之后,子进程进入 ready queue。如果父进程使用了 `wait`,他就会被放到子进程的 waiting queue 里(实际上每个被等待的对象都有一个 waiting queue)。当子进程拿到 CPU 时,它结束之后,操作系统会把父进程唤醒,随后父进程进入 ready queue。 - - 当 CPU 再次被父进程拿到时,它会回收子进程这个 zombie。 +> [!example] +> +>
+> parent call fork 之后,子进程进入 ready queue。如果父进程使用了 `wait`,他就会被放到子进程的 waiting queue 里(实际上每个被等待的对象都有一个 waiting queue)。 +> +> 当子进程拿到 CPU 时,它结束之后,操作系统会把父进程唤醒,随后父进程进入 ready queue。 +> +> 当 CPU 再次被父进程拿到时,它会回收子进程这个 zombie。 ### Dispatcher @@ -110,8 +111,6 @@ Selects from among the processes in memory that are ready to execute, and alloca image-20241010225219546 - - ## Scheduling Algorithms 用下面的指标来衡量算法的好坏: @@ -260,6 +259,12 @@ The **Multilevel Feedback Queues** scheme is very general because highly *config ## Thread Scheduling +Local Scheduling (Process-Contention Scope) – How the **threads library** decides which thread to put onto an available LWP + +- 将 user kernel 和 system kernel 进行绑定 + +Global Scheduling (System-Contention Scope) – How the **kernel** decides which kernel thread to run next + * **process-contention scope (PCS)** 每个进程分到时间片一样,然后进程内部再对线程进行调度。 diff --git a/docs/CS/OS/Ch8_MainMemory.md b/docs/CS/OS/Ch8_MainMemory.md new file mode 100644 index 0000000..b763b37 --- /dev/null +++ b/docs/CS/OS/Ch8_MainMemory.md @@ -0,0 +1,102 @@ +# Main Memory + +> 对应教材 Part 4 Memory Management + +## BackGrounds + +- Main memory and the registers built into each processing core are the only general-purpose storage that the CPU can access directly. +- A pair of **base** and limit **registers** define the **logical address space** + +image-20241023185233268 + + + +### Address Binding + +> 就是将不同的地址空间进行mapping + +> [!note]不同类型的地址 +> +> - Symbolic Address: Addresses in the source program are generally symbolic (such as the variable count). 符号地址 +> +> - Relocatable Addresses: A compiler typically binds these symbolic addresses to relocatable addresses (such as “14 bytes from the beginning of this module”). 像是一种local address之后可以转为global address +> - **Absolute Addresses**: The linker or loader binds the relocatable addresses to absolute addresses (such as 74014). + +- **Compile time(编译时刻)**: If memory location known a priori, absolute code can be generated; must recompile code if starting location changes +- **Load time(装入时刻)**: Must generate relocatable code if memory location is not known at compile time +- **Execution time(执行时刻)**: Binding delayed until run time if the process can be moved during its execution from one memory segment to another. Need hardware support for address maps (e.g., base and limit registers) + +image-20241023185946907 + + + +### Logical & Physical Address + +- Logical and physical addresses are the same in compile-time and load-time address-binding schemes; + +- Logical (virtual) and physical addresses differ in execution-time address-binding scheme + +**MMU** + +![image-20241023145150595](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410231451719.png) + +### Dynamic Loading & Dynamic Linking +| 特性 | **Dynamic Loading (动态加载)** | **Dynamic Linking (动态链接)** | +| ------------ | -------------------------------- | ------------------------------------------ | +| **加载时间** | 在程序运行时按需加载,手动控制 | 在程序启动时自动加载 | +| **使用场景** | 适合需要条件性加载的模块,如插件 | 适合常用的共享库,如操作系统的标准库 | +| **内存占用** | 占用较少内存,只有在需要时才加载 | 相对固定,占用内存更多 | +| **更新库** | 更新库时需要重新加载库 | 可以直接更新库,无需重新编译程序 | +| **代码大小** | 程序代码较小,库按需加载 | 程序代码较小,库共享,适合多个程序共享使用 | +| | 无需OS帮助 | 需要OS帮助 | +#### **动态加载的特点** + +- 模块在程序运行时按需加载。 +- 通常使用一些函数来手动加载模块(如 `dlopen` 在 Linux 中,`LoadLibrary` 在 Windows 中)。 +- 适合加载一些只在特定条件下使用的功能模块,减少初始加载时间和内存占用。 + +#### **动态链接的特点** + +**Dynamically linked libraries** (**DLLs**) are system libraries that are linked to user programs when the programs are run + +- 共享库在程序运行时加载并链接。 +- 程序与共享库的接口在编译时绑定,但具体的库代码在运行时加载。 +- 常用于共享库(如 `.dll`、`.so` 文件),减少可执行文件的体积。 +- 更新库版本时不需要重新编译整个程序,只需确保库接口不变。 + + + +## Contiguous Allocation + +### Protection + +> dispatcher loads the relocation and limit registers with the correct values as part of the context switch + +![image-20241023151937007](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410231519113.png) + +### Allocation + +按照动态分配 + + + +![ ](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410232248044.png) + +- First-fit: Allocate the first hole that is big enough +- Best-fit: Allocate the smallest hole that is big enough; must search entire list, unless ordered by size Produces the smallest leftover hole +- Worst-fit: Allocate the largest hole; must also search entire list Produces the largest leftover hole + + + +### Fragmentation + +**External ** holes + +- **Compaction** is possible only if relocation is dynamic, and is done at execution time + +**Internal** 有时会使用block size进行memory的分配,分配到的实际内存大小大于进程需要的内存大小 + +## Paging + +- Divide **physical memory** into fixed-sized blocks called **frames** (size is power of 2, between 512 bytes and 8,192 bytes) +- Divide **logical memory** into blocks of same size called **pages** diff --git "a/docs/CS/OS/\351\242\230\347\233\256.md" "b/docs/CS/OS/\351\242\230\347\233\256.md" new file mode 100644 index 0000000..8141997 --- /dev/null +++ "b/docs/CS/OS/\351\242\230\347\233\256.md" @@ -0,0 +1,8 @@ +# 题目汇总 + +## Overview + +![image-20241024132806286](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410241328386.png) + +--- + diff --git a/docs/CodingLanguage/Java/notes.md b/docs/CodingLanguage/Java/notes.md index 8c10b19..d637710 100644 --- a/docs/CodingLanguage/Java/notes.md +++ b/docs/CodingLanguage/Java/notes.md @@ -11,13 +11,15 @@ update: <% tp.date.now("YYYY-MM-DD HH:mm:ss") %> >[!todo] >**Overview 部分** ->- [ ] 垃圾回收机制 ->- [ ] 保留字 +>- [x] 垃圾回收机制 +>- [x] 保留字 >- [ ] 内存分布 >- [ ] 访问权限符 +>- [x] Package > >**类** >- [ ] 继承 +>- [ ] 类内类的顺序 # Java @@ -27,12 +29,18 @@ update: <% tp.date.now("YYYY-MM-DD HH:mm:ss") %> >[!info] 概念 >- SDK >- JDK +> 功能齐全的 Java 开发工具包。包含JRE和Java Development Tools +>- JVM +> Java 虚拟机(Java Virtual Machine, JVM)是运行 Java 字节码的虚拟机。JVM 有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。字节码和不同系统的 JVM 实现是 Java 语言“一次编译,随处可以运行”的关键所在。 +>- JRE 是运行已编译 Java 程序所需的环境,主要包含以下两个部分: +> 1. **JVM** : 也就是我们上面提到的 Java 虚拟机。 +> 2. **Java 基础类库(Class Library)**:一组标准的类库,提供常用的功能和 API(如 I/O 操作、网络通信、数据结构等)。 ## overview - Compiled Language - All objects should be constructed in runtime and be stored in heap. -- Every class in Java is a descendant of one class: Object +- 单根结构(除了C++的所有OOP语言) Every class in Java is a descendant of one class: Object - Java 中的输入输出,Scanner 容易超时 ```Java @@ -51,10 +59,10 @@ public class Main { - Identifier >[!note] 和 C++ 不同的语言特性 +> >- Java 中的常量使用关键字 `final` 而不是 `const`. `final int a = 5;` >- Java 中类型推导关键字为 `var`. `var s = new StringBuffer();` >- Java 的 reference 更像是 C++中的指针,不可计算. 任何对象变量都是指针 -> - > - 对象变量的赋值 > >>[!example] @@ -80,6 +88,38 @@ public class Main { ### 内存布局 +### Package + +- Java 的 Package 依赖于目录 + - 之后的代码属于这个 package + - 这部分代码必须放在一个名为 `` 的文件夹中 + +```java +package +``` + +- 设置寻找 Package 的地址 + - 环境变量 + - 通过 `-cp` 指定寻找路径, ` java -cp java hello.Hello ` + +**Package的作用域** + +包在 Java 的访问控制中起着重要作用,主要涉及以下访问修饰符: + +- **public**:公共访问,任何类都可以访问。 +- **protected**:受保护的访问,允许**同一包内的类和不同包中的子类**访问。 +- **默认(包私有)**:如果不指定访问修饰符,默认为包私有,只有同一包内的类可以访问。 +- **private**:私有访问,仅在同一类内可见 + +#### Static Import + +```java +double r = Math.cos(Math.PI * theta); +import static java.lang.Math.PI; +import static java.lang.Math.*; +double r = cos(PI * theta); +``` + ## String API - 所有字符类型都是 unicode,就像下面的中文也会是一个字节 @@ -96,27 +136,57 @@ String b = "hello"; // len = 5 **得到属性** - `s.length () ` - `s.charAt (int index) ` + **切片** + - `s.substring (int , int )` -- + **比较** + - `s.compareTo ()` - `s.equals ()` - `s.equalsIgnoreCase ()` - `Boolean startsWith (String str)` - `Boolean endsWith (String str)` + **变换** + - `String trim ()` 删除前导、后导空格 -- `String replace (char c 1, char c 2)` +- `String replace (char c 1, char c 2)` 替换 - `public String replaceAll(String regex, String replacement)` 可使用正则表达式进行替换。[[../../Tools/正则表达式|正则表达式]] -**与其他的值相互转化** + **与其他的值相互转化** ```JAVA String piStr = "3.14159"; Float pi = Float.ValueOf (piStr); -Float pi 2 = Float.ParseFLOAT (piStr); +Float pi2 = Float.ParseFLOAT (piStr); +``` + +### 比较 + +- [深入理解Java字符串常量池 | 二哥的Java进阶之路 (javabetter.cn)](https://javabetter.cn/string/constant-pool.html#字符串常量池在内存中的什么位置呢) + +```java +public static void main(String[] args) { + String s = "abc"; // 指向字符串常量池 + String t = "abc"; + String u = new String("abc"); // new的时候一定会创建一个新的对象在heap + System.out.println(s == t); + System.out.println(s == u); +} ``` +- + +```java +String str = "Person"; +String str1 = new String("Person"); +System.out.println(str == "Person"); // true +System.out.println(str1 == "Person"); // false +``` + + + ## Basic **参数传递** @@ -133,30 +203,27 @@ System.out.println(n1 == n2);  // false Integer n3 = 47;   Integer n4 = 47; System.out.println(n3 == n4);  // true -``` - -### Package - -- Java 的 Package 依赖于目录 - - 之后的代码属于这个 package - - 这部分代码必须放在一个名为 `` 的文件夹中 -```java -package +Integer n1 = 147;// new Integer(47); +Integer n2 = 147;// new Integer(47); +System.out.println(n1 == n2); // false ``` -- 设置寻找 Package 的地址 - - 环境变量 - - 通过 `-cp` 指定寻找路径, ` java -cp java hello.Hello ` +### 垃圾回收 GC + +[深入理解 JVM 的垃圾回收机制 | 二哥的Java进阶之路 (javabetter.cn)](https://javabetter.cn/jvm/gc.html) -### Class +## Class >[!note] >- 类在内存中也是一个对象属于 Class >- Java 会对 new 的对象的内存清空为 0 >- 定义初始化,在构造函数之前,初始化顺序与在 class 中定义的顺序相关 +>- 一个类的定义,可以继承一个父类的同时,再实现多个接口 +> `class MathTest extends Student implements BaseTest` +> - 可以在`Student`类中实现一部分接口的函数,在`MathTest`中就无需实现这部分 -#### 代理构造 +### 代理构造 Java 的代理构造和调用父类的构造函数都要放在构造函数开始的位置。 @@ -170,7 +237,7 @@ public Rectangle() { } ``` -#### 静态初始化 +### 初始化顺序 Static member is to be initialized in the **loading** of the class @@ -180,17 +247,48 @@ graph LR ``` +- Java的初始化会在Heap上申请内存,把这一块内存初始化为空 + - 对于Primitive会赋初值如0 + ```Java -Flower(String s, int petals) { -        this(petals); -        this.s = s; // Another use of "this" -        System.out.println("String & int args"); -    } +class Cupboard { + static { + System.out.println("Loading Cupboard"); + } + { + System.out.println("Loading Cupboard instance"); + } + Cupboard() { + System.out.println("Cupboard()"); + b3.f(1); + } +} +``` + +**静态初始化** + +```java +static { ... } +``` + +- 在类被装载的时候运行且只会执行一次 +- 类的状态是运行时装载,所以可能一个类未被装载 + +**定义初始化** + +```java +{ ... } ``` -#### 定义初始化 +- 每次创建实例都会调用 + +**构造初始化** + +```java +ClassName(){} +``` -#### 函数的绑定 +### 函数的绑定 >Case 2 Shape. Java @@ -199,15 +297,20 @@ Java 默认为动态绑定, - Static binding: call the function as the code - Dynamic binding: call the function of the object -#### override +### override + +### Final -#### Final +### Abstract & Interface -#### Abstract & Interface +**Abstract** - 一个抽象类中可以没有 abstract 函数,但含有 abstract 函数一定要是抽象类 + **Interface** + - All methods in interface are public. +- 不能拥有构造函数 - All data members in interface are **public static final**. - `implements` `interface` 可以实现多个接口 @@ -222,6 +325,145 @@ interface Instrument5 { } ``` +- 它前面的修饰符只能是`abstract / public` + +```java +abstract interface BaseTest +``` + + + +> [!NOTE] +> +> 接口引入了新的方法类型:`default` 方法、`static` 方法和 `private` 方法。这些方法让接口的使用更加灵活。 +> +> - Java 8 引入的`default` 方法用于提供接口方法的默认实现,可以在实现类中被覆盖。这样就可以在不修改实现类的情况下向现有接口添加新功能,从而增强接口的扩展性和向后兼容性。 +> +> ```java +> public interface MyInterface { +> default void defaultMethod() { +> System.out.println("This is a default method."); +> } +> } +> ``` +> +> - `static` 方法无法在实现类中被覆盖,只能通过接口名直接调用( `MyInterface.staticMethod()`),类似于类中的静态方法。`static` 方法通常用于定义一些通用的、与接口相关的工具方法,一般很少用。 +> +> ``` +> public interface MyInterface { +> static void staticMethod() { +> System.out.println("This is a static method in the interface."); +> } +> } +> ``` +> +> ------ +> +> - Java 9 允许在接口中使用 `private` 方法。`private`方法可以用于在接口内部共享代码,不对外暴露。 +> +> ```java +> public interface MyInterface { +> // default 方法 +> default void defaultMethod() { +> commonMethod(); +> } +> +> // static 方法 +> static void staticMethod() { +> commonMethod(); +> } +> +> // 私有静态方法,可以被 static 和 default 方法调用 +> private static void commonMethod() { +> System.out.println("This is a private method used internally."); +> } +> +> // 实例私有方法,只能被 default 方法调用。 +> private void instanceCommonMethod() { +> System.out.println("This is a private instance method used internally."); +> } +> } +> ``` + +### Enum 枚举类 + +- 也是类,相当于构建了匿名子类,不是像C一样的宏(会进行类型检查`int i = 1; i == ONE`报错) + - `==` 和 `equals` 效果相同,是比较特殊的引用类型 + - `enum`类型的每个常量在JVM中只有一个唯一实例,所以可以直接用`==`比较 + + - 无法通过`new`创建实例 + - `Suit.values()`直接遍历访问整个enum类的所有 + + + +```java +public enum Rank { DEUCE, THREE, FOUR, FIVE, SIX, + SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE } + +public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES } +static { + for (Suit suit : Suit.values()) + for (Rank rank : Rank.values()) + protoDeck.add(new Card(rank, suit)); +} +``` + +- 可以存在同名的函数与变量 + +- 解决`switch case`的思路之一 + +- 枚举常量必须在字段和构造函数之前定义 + ```java + public enum Planet { + MERCURY(3.303e+23, 2.4397e6), + VENUS(4.869e+24, 6.0518e6), + EARTH(5.976e+24, 6.37814e6), + MARS(6.421e+23, 3.3972e6), + JUPITER(1.9e+27, 7.1492e7), + SATURN(5.688e+26, 6.0268e7), + URANUS(8.686e+25, 2.5559e7), + NEPTUNE(1.024e+26, 2.4746e7), + PLUTO(1.27e+22, 1.137e6); + + private final double mass; // in kilograms + private final double radius; // in meters + + Planet(double mass, double radius) { + this.mass = mass; + this.radius = radius; + } + + public double mass() { + return mass; + } + + public double radius() { + return radius; + } + + // universal gravitational constant (m3 kg-1 s-2) + public static final double G = 6.67300E-11; + + public double surfaceGravity() { + return G * mass / (radius * radius); + } + + public double surfaceWeight(double otherMass) { + return otherMass * surfaceGravity(); + } + + public static void main(String[] args) { + double earthWeight = Double.parseDouble(args[0]); + double mass = earthWeight / EARTH.surfaceGravity(); + for (Planet p : Planet.values()) + System.out.printf("Your weight on %s is %f%n", + p, p.surfaceWeight(mass)); + } + } + ``` + + + ## 继承与多态 ```Java @@ -246,6 +488,159 @@ class BoardGame extends Game { - 装载是分开做的,只有在使用的时候才会进行装载。 - 函数中的内部类 + - 会在前面加上数字编号以区分不同的函数中的类 + + +#### 匿名类 + +- 构造匿名子类 + - 可以访问外部的内容 but ***Argument must be final to use inside anonymous inner class*** + - 闭包 + 与它相关的本地变量不会被回收,(保存当时的外部环境) + - 定义初始化块可以充当它的初始化函数 + +```java +// 函数中的匿名类 +public Contents cont() { + return new Contents() { + private int i = 11; + public int value() { + return i; + } + }; // Semicolon required in this case +} +``` + +## Generic Containers | 泛型容器 + +![img](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410172337488.png) + +### Array + +```java +int [] a = new int[10]; + +for (var x: a){ + x += 1; // 不会改变它的值,相当于使用值(尽管Array本身是指针) +} + +int [] b = a; // 指针 +b[0] = 16; // a[0] = 16 +``` + +- 对象的数组中放的实质是指针 + +```java +Value [] a = new Value[10]; +for (var x: a) // 这里x为指针,通过x访问它的元素然后改变 +``` + +### Collection + +- Java没有实现重载,访问某个元素只能使用`get`不能使用`[]` + +**共有操作** + +- `add` +- `addAll(Collection)` +- `toArray` + +#### List + +`ArrayList` 存储方式为Array + +```java +``` + +- `add`一个类的对象,放的还是指针 + +```java +ArrayList list = new ArrayList<>; +... +Value v1 = list.get(0); +``` + + + +#### Set + +### Map + +### Generic + +存放类型的变量 Class类的变量 + + + +**subtype** + +![image-20241024164037656](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410241640825.png) + + + +**WildCards** + +```java +void printCollection(Collection c) { + for (Object e : c) { + System.out.println(e); + } +} +// 限定shape子类 +public void drawAll(List shapes) +{ ... } +``` + +## Exception & IO + +- `System.out.println(true ? Integer.valueOf(1) : Double.valueOf(2.0));` + - 编程语言的格式对齐,一条表达语句的结果只能存在一种情况 +- Java中`throw`的对象一定是`Throwable (the exception root class) object` + +**匹配机制** + +- 和C++相同,父类放在最后 + +**异常声明** + +- 未处理的异常必须要声明`throws ...` +- 一个函数中存在异常 + - 调用的函数抛出异常 + - 自己抛出异常 + +**类型** + +![image-20241024192448751](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202410241924911.png) + +- Error 是编译时检查的错误 + + **限制** + +- When you override a method, you can throw only the exceptions that have been specified in + + the base-class version of the method. + +- Classs + - 构造 + - 仍然存在C++资源泄露的问题(文件) + - 非构造 +- 对于多来源的类,子类的能抛出的异常是父类的交集(可能被当做任何一种类,is-a) + +## **补充知识** + +### 命名规范 + +[5 分钟编码,1 小时命名,笑 | 二哥的Java进阶之路 (javabetter.cn)](https://javabetter.cn/basic-extra-meal/java-naming.html#_06、方法-method) + +### Java 正则表达式 + + + +#### Matcher类 + +[Matcher 类 - Dev.java - Java 中文 (java-lang.cn) ](https://dev.java-lang.cn/learn/regex/matchers/) + +### 中文处理 ## 练习题 @@ -276,4 +671,30 @@ class BoardGame extends Game { >**Q 2** >![image.png](https://zzh-pic-for-self.oss-cn-hangzhou.aliyuncs.com/img/202409201632308.png) -### Week 3 \ No newline at end of file +### Week 3 | Class + +- What will happen if you try to compile and execute B’s `main()` method? ( ) + + ```Java + class A { + int i; + A(int i) { this.i = i * 2; } + } + class B extends A { + public static void main(String[] args) { + B b = new B(2); + } + B(int x) { + System.out.println(x); + } + } + ``` + + D. This code will not compile + +> [!note] +> +> class A中只有一个带参数的初始化函数,必须要显式调用!(如果删除则可以通过编译) + +--- + diff --git a/docs/Socket Pragramming.md b/docs/Socket Pragramming.md index 4bd22cd..c6f97f9 100644 --- a/docs/Socket Pragramming.md +++ b/docs/Socket Pragramming.md @@ -1,3 +1,33 @@ +**数据包** +- [ ] +**服务端** +- [x] **序号如何去重复使用** ✅ 2024-10-21 + - [x] 两边主动发送的序号是否需要同步?应该可以把不同类型的序号分开,服务端客户端各自自己的序号从 1 - 255 考虑,检查应答是否正确可以从序号和 Packet.type 判断 ✅ 2024-10-21 +- [ ] UDP version + a) 针对 UDP 模式,需要定义特殊类型的请求和响应,用于建立连接和释放连接。服务端检测该客户端是否处于已连接状态,如果未连接时收到除了连接/释放连接请求之外的其他请求,则发回未连接的错误响应。重复收到连接/释放连接请求时,根据当前连接状态返回适合的响应。接收数据时调用recvfrom(),发送数据时调用sendto()。 +- [ ] 服务端主动推送 + - [ ] + - [x] 其他客户端发送的消息 to test ✅ 2024-10-21 + - [x] 其他客户端上线、下线的消息。 ✅ 2024-10-21 + - [ ] UDP 连接时发送消息,保存信息 + - [ ] 气象预警信息,包括地震、台风等 + 提供人机交互界面,实现人工触发向所有在线的客户端推送气象预警消息的功能。气象预警信息包括地震和台风两类。地震信息包括地震时间、震中经纬度、震级。台风信息包括台风中心经纬度、级别、预计登录地点和时间。 + 解包可以从类别分别解需要的数据,其他数据不用管 +- [ ] 接受客户端传输数据⏫ + - [x] 多线程处理多个客户端 ✅ 2024-10-17 + - [x] 向客户端传送所请求的区号对应的城市名称 ✅ 2024-10-17 + - [x] 向客户端传送服务端所请求的日期、城市的气象信息 ✅ 2024-10-17 + - [x] 向客户端传送当前连接的所有客户端信息 ✅ 2024-10-17 +- [ ] 数据加载 不同的服务端实例可以有不同的配置数据,首次运行时加载 + - [x] 城市和区号的对照列表 初始时至少有20个城市 ✅ 2024-10-14 + - [x] 所有城市七天内的气象信息 至少有20个城市的七天内气象信息 ✅ 2024-10-14 + + - [ ] +**测试** + +- + + **参考:** - [微软官方文档 · Winsock 入门](https://learn.microsoft.com/zh-cn/windows/win32/winsock/getting-started-with-winsock) - [Youtube视频 · C++ Network Programming](https://www.youtube.com/watch?v=gntyAFoZp-E) diff --git a/docs/Todos.md b/docs/Todos.md index 02d4cc9..82ee305 100644 --- a/docs/Todos.md +++ b/docs/Todos.md @@ -11,10 +11,10 @@ - [ ] Lab 7 协议 *+ Socket 示例* - [ ] Notes + 王道 - **计算理论** -- [ ] Lecture 1 -- [ ] 题目 +- [x] Lecture 1 ✅ 2024-10-14 +- [x] 题目 ✅ 2024-10-14 - **OS** -- [ ] Lab 1 report 📅 2024-10-14 +- [x] Lab 1 report 📅 2024-10-14 ✅ 2024-10-14 - [ ] Lab 2 📅 2024-10-21 - **ASM** - [ ] Class 2 diff --git a/docs/Tools/Conda.md b/docs/Tools/Conda.md index 4e03103..8d2cfc4 100644 --- a/docs/Tools/Conda.md +++ b/docs/Tools/Conda.md @@ -1,6 +1,7 @@ # Conda !!! abstraction "Conda" + Conda是一个管理Python环境和版本的工具。 - [知乎](https://zhuanlan.zhihu.com/p/44398592) @@ -58,5 +59,4 @@ conda create xxx -c channels ```sh conda config --add channels conda config --remove channels -``` - +``` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index e070940..4cf0b05 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -211,32 +211,7 @@ nav: - DIP: - 期末复习: CS/DIP/DIP_Review.md - 【短学期】大数据可视化: CS/大数据可视化.md - - ⌨️ 语言学习: - - CodingLanguage/index.md - - ⌨️ C语言: - - CodingLanguage/C/index.md - - 存储类别、链接和内存管理: CodingLanguage/C/存储类别、链接和内存管理.md - - 指针: CodingLanguage/C/指针.md - - ⌨️ CPP: - - CodingLanguage/CPP/index.md - - 基础: CodingLanguage/CPP/基础.md - - Stadard Library: - - IO库: CodingLanguage/CPP/Stadard_Library/IO.md - - String: CodingLanguage/CPP/Stadard_Library/string.md - - 容器: CodingLanguage/CPP/Stadard_Library/容器.md - - 算法库: CodingLanguage/CPP/Stadard_Library/Algorithm.md - - 动态内存和智能指针: CodingLanguage/CPP/Stadard_Library/动态内存.md - - class: - - CodingLanguage/CPP/classes/index.md - - class: CodingLanguage/CPP/classes/class.md - - template: CodingLanguage/CPP/classes/模板.md - - inherit: CodingLanguage/CPP/classes/inherit.md - - copy: CodingLanguage/CPP/classes/Copy.md - - OverloadOperator: CodingLanguage/CPP/classes/OverloadOperator.md - - ⌨️ Python: - - CodingLanguage/Python/index.md - - 💡CS61A: CodingLanguage/Python/CS61A.md - - 一些实践: CodingLanguage/Python/basic.md + - Others: - others/index.md - 大学物理实验: others/大物实验.md