408:强化笔记|王道|DS|OS|CO|计网

embedded/2024/9/23 17:23:59/

目录

  • DS 数据结构
    • 算法题
    • 一、快速排序
    • 二、二路归并排序
    • 三、链表(2.3课后习题)
    • 四、二叉树
    • 五、图
    • 应用题
  • OS 操作系统
    • 第二章 进程与线程
      • 零、大观
      • 一、PV操作
    • 第三章 内存管理
      • 一、内存管理大题
  • CO 计算机组成原理
    • 第三章 存储系统
      • 一、Cache大题
      • 二、TLB大题
    • 第二章 数据的表示和运算
    • 第四章 指令系统
      • 一、一堆指令的执行
    • 第五章
      • 一、结构冒险、数据冒险和控制冒险的处理
      • 二、五段式指令流水线
      • 三、一条指令的执行
    • 第七章 输入/输出系统
      • 零、大观
      • 一、深入理解I/O系统
      • 二、Printf—从系统调用开始
        • *sys_write可用三种I/O方式实现:程序查询、中断驱动和DMA*
      • 三、Scanf的完整故事
        • *sys_read用中断方式实现*
  • 计算机网络
    • 二轮复习大观


  • 持续更新~
  • 欢迎评论区留言指正
  • 如果你是Obsidian用户,可以导入自己的笔记库中,效果最佳
  • ⚠️如需转载,请标明出处!

DS 数据结构

算法题

一、快速排序

1、快排代码

①递归—>乱序数组

②关键思想:划分—>参数(数组指针、范围)

// Partitation 划分
int huafen(int A[], int L, int R) {int mid = A[L];				// 刚开始 枢轴元素的值 为 数组最左边的值while (L < R) {while (A[R] >= mid) R --;A[L] = A[R];while (A[L] <= mid)L ++;A[R] = A[L];}A[L] = mid;return L;					// 返回 L 以便于 递归地进行划分
}// 快速排序
void QuickSort(int A[], int L, int R) {if (L >= R) return;			// 递归结束int M = huafen(A, L, R);	// 定义一个 M 记录 上一层递归的枢轴元素QuickSort(A, L, M - 1);		// 左半部分 划分QuickSort(A, M + 1, R);		// 右边部分 划分
}

2、快排实战

2011-42、2013-41、2018-41、2016-43

3、运用快排的"划分"思想

例:使用"划分"函数找到数组中第k小的元素

int func(int A[], int n, int k) {int L = 0, R = n - 1, M = 0;while (1) {M = huafen (A, L, R);if (M = k - 1)break;else if (M > k - 1)R = M - 1; 			// 下标为 k - 1 的元素只能出现在左半部分else if (M < k - 1)L = M + 1;			// 下标为 k - 1 的元素只能出现在右半部分}return A[k - 1];			// 返回下标 k - 1 对应元素的值
}

⚠️复杂度:
每一轮划分的时间复杂度: n + n 2 + n 4 + ⋅ ⋅ ⋅ + n n 令  n = 2 x , ⇒ 2 x + 2 x − 1 + 2 x − 2 + ⋅ ⋅ ⋅ + 1 = 1 − 2 x + 1 1 − 2 = 2 x + 1 − 1 = 2 n − 1 ⇒ 总体时间复杂度 O ( 2 n + 1 ) = O ( n ) 空间复杂度 O ( 1 ) \\ 每一轮划分的时间复杂度:n + \frac{n}{2} + \frac{n}{4}+···+ \frac{n}{n} \\ 令\ n=2^x, \\ \Rightarrow 2^x+2^{x-1}+2^{x-2}+···+1 \\ =\frac{1-2^{x+1}}{1-2}=2^{x+1}-1=2n-1 \\ \Rightarrow 总体时间复杂度O(2n+1)=O(n) \\ 空间复杂度O(1) 每一轮划分的时间复杂度:n+2n+4n+⋅⋅⋅+nn n=2x,2x+2x1+2x2+⋅⋅⋅+1=1212x+1=2x+11=2n1总体时间复杂度O(2n+1)=O(n)空间复杂度O(1)

实战:8.3.3 大题 2

2016-43

二、二路归并排序

0、回顾

1、二路归并 VS 快速排序

2、二归实战

①基本功

②2011-42

三、链表(2.3课后习题)

0、大观

1、基本功训练

①按位序查找

(1)代码

(2)实战

②按关键字条件查找+删除

③按关键字条件查找+插入

④头插法(原地逆置)

⑤尾插法(保持原序)

四、二叉树

0、大观

处理二叉树时常用的代码思路

1、基本功训练

①前/中/后序遍历(递归方法)

// 链式存储的二叉树节点定义
typedef struct BiTNode {int data;							// 数据域struct BiTNode *lchild, *rchild;	// 左右孩子指针
}BiTNode, *BiTree// 前序遍历
void PreOrder(BiTree root) {if (root == null)return;							// 根节点为空 递归结束visit(root);PreOrder(root->left);PreOrder(root->right);
}// 中序遍历
void InOrder(BiTree root) {if (root == null)return;InOrder(root->left);visit(root);InOrder(root->right);
}// 后序遍历
void PostOrder(BiTree root) {if (root == null)return;PostOrder(root->left);PostOrder(root->right);visit(root);
}

②层序遍历

// 初始化队列
void InitQueue(Queue &Q);
// 判空
bool IsEmpty(Queue &Q);
// 入队
void EnQueue(Queue &Q, BiTree T);
// 出队
void DeQueue(Queue &Q, BiTree T);// 层序遍历
void LevelOrder(BiTree T) {Queue Q;InitQueue(Q);					// 初始化队列BiTree p;							EnQueue(Q, T);					// 根节点入队while(!IsEmpty(Q)) {			// 队列非空DeQueue(Q, p);				// 队头节点出队visit(p);					// 先出队再访问if (p->lchild != null)EnQueue(Q, p->lchild);	// 左孩子入队if (p->rchild != null)EnQueue(Q, p->rchild);	// 右孩子入队}
}

2、实战

2014-41、2017-41

五、图

0、大观

1、代码

①图的数据机构定义——邻接矩阵

# define MAXV 6						// 顶点数目的最大值// 图的邻接矩阵
typedef struct {int numVertices, numEdges;		// 图的实际顶点数和边数char VerticesList[MAXV];		// 顶点表int Edge[MAXV][MAXV];			// 边表
}MGraph;MGraph * G = (MGraph *) malloc (sizeof(MGraph));
for (int i = 0; i < MAXV; i ++)for (int j = 0; j < MAXV; j ++)G->Edge[i][j] = 0;			// 408中,权值0表顶点之间没有边G->numVertices = 4;
G->numEdges = 5;
// 初始化各顶点数据
G->VerticesList[0] = 'a';
G->VerticesList[1] = 'b';
G->VerticesList[2] = 'c';
G->VerticesList[3] = 'd';
// 初始化各边数据
G->Edge[0][1] = 1;
G->Edge[0][3] = 1;
G->Edge[1][2] = 1;
G->Edge[1][3] = 1;
G->Edge[2][3] = 1;

②图的数据结构定义——邻接表

// 定义邻接表
# define MAXV 6						// 顶点数目的最大值typedef struct EdgeNode {			// 边表节点int index;						// 这条边所指向的顶点的位置struct EdgeNode *next;			// 指向下一条边的指针int weight;						// 权值(若是无权图,可删)
}EdgeNode;typedef struct VertexNode {			// 顶点表节点char data;						// 节点信息EdgeNode * first;				// 指向第一条依附该顶点的边的指针
}VertexNode, VertexList[MAXV];typedef struct {VertexList list;				// 邻接表int num Vertex, numEdge;		// 图的顶点数和边数
}ALGraph;							// ALGraph 是以邻接表存储的图// 初始化无权有向图
ALGraph * G = (ALGraph *) malloc(sizeof(ALGraph));
for (int i = 0; i < MAXV; i ++)G->List[i].first == NULL;G->numVertex = 4;
G->numEdge = 5;
G->list[0].data = 'a';
G->list[1].data = 'b';
G->list[2].data = 'c';
G->list[3].data = 'd';AddEdge(G, 0, 1, 1);
AddEdge(G, 0, 3, 1);
AddEdge(G, 1, 2, 1);
AddEdge(G, 1, 3, 1);
AddEdge(G, 2, 3, 1);// 在节点<i, j> 之间增加一条边; 边的权值为weight
void AddEdge(ALGraph * G, int i, int j, int weight) {EdgeNode * p = (EdgeNode *) malloc (sizeof(EdgeNode));p->weight = weight;p->index = j;					// 指向顶点jp->next = G.list[i].first;		// 单链表的头插法G->list[i].first = p;
}

2、实战

2021-41、2023-41

2021改、2023改

应用题






OS 操作系统

第二章 进程与线程

零、大观

复习顺序:进程的同步与互斥——>虚拟分页存储管理——>文件目录、文件的物理结构

在这里插入图片描述

一、PV操作

生产者-消费者问题

六步骤(草稿纸上的分析步骤)

1、有几类进程?

2、每个进程分别对应了哪些动作?

​ a. 只做一次——不加while

​ b. 不断重复——加while(1)

3、分析每一动作之前,是否需要P什么(⚠️有P必有V)

⚠️可能存在隐含的互斥

如:对缓冲区访问需加P(mutex),保证访问的互斥性

4、所有PV操作写完后,再定义信号量

5、检查多个P连续出现的地方是否产生死锁;调整(交换)P顺序

6、检查是否符合题意

单纯的同步问题(前v后p)

哲学家进餐问题

模板题

Semaphore Lock = 1; //互斥信号量int a = 9, b = 8, c = 5; // abc三类资源,定义3个int类型信号量Process() {while(1) {P(Lock);if(所有资源都够) {所有资源 int --;取xxx资源;V(Lock);break;}V(Lock);}做进程该做的事(如:哲学家就餐)P(Lock);归还所有资源,所有资源int ++;V(Lock);
} // END

理发师问题

代码框架(较复杂情况——没有顾客,服务员睡眠休息💤)

// 初始化
int waiting = 0;
semaphore mutex = 1;			// 保证各进程对 waiting 的互斥访问
semaphore customer = 0;			// 这里 考虑 服务员 会休息
semaphore service = 0;			// 保证"被服务"与"提供服务"同步								    			// 先取号——确认有顾客——叫号——提供服务//	顾客
customer_i() {while(1) {P(mutex);				// 我们要使用 waiting 变量——需要互斥访问取号;waiting ++;V(mutex);				// 使用(修改)完 释放 mutexV(customer);			// 唤醒 服务员等待被叫号;P(service);				// 上锁之后再被提供服务——1对1——避免产生互斥被服务;}
}//	服务员
server_j() {while(1) {P(mutex);				// 需使用 waiting ——上锁if (waiting > 0) {		// 有顾客叫号;waiting --;V(mutex);V(service);提供服务;} else {V(mutex);			// 保证不存在顾客也能解锁P(customer);		// 没有顾客,服务员休息——上锁} // else_end} // while_end
}

读者-写者问题(OS结课考试会讲)

⚠️近几年从未考察,今年考察的概率很大

第三章 内存管理

一、内存管理大题

1、内存管理章节大题概念考察的很细,多听几遍OS骚图pro

2、CPU执行指令MOV[VA], 3

VA = 0003 996H

VA = FFFB 996H

VA = 0007 996H

分别会发生什么(P2, 约1h49min28s左右)






CO 计算机组成原理

大致有五章(共七章)可能出现大题

大题的建议复习顺序:三—>二—>四—>五—>七

第三章 存储系统

一、Cache大题

二、TLB大题

第二章 数据的表示和运算

第四章 指令系统

一、一堆指令的执行

第五章

一、结构冒险、数据冒险和控制冒险的处理

1、结构冒险及其处理(又称结构冲突,资源冲突)

  • 处理方法一:通过硬件阻塞来处理
  • 处理方法二:指令Cache和数据Cache分离

2、数据冒险的分析及其处理

①分析

从某条指令开始,分析是否与其后相邻的3条指令发生写后读

②处理

  • 硬件阻塞
  • 转发技术(旁路)

3、控制冒险的分析及其处理

①分析

只有==转移类指令(尤指 条件转移)==的执行(阶段)才会引发控制冒险

②处理

  • 硬件阻塞

    将转移类指令的后一条指令的IF段硬件阻塞3个时钟(访存阶段M会修改PC值)

    转移: IF ID EX M WB

    后一条: 阻 阻 阻 IF ID EX M WB

  • 转发技术

二、五段式指令流水线

IFIDEXMWB
取指译码/取数执行/计算地址访存写回

指令按序发送,按序完成

三、一条指令的执行

1、指令执行过程

(I)取指(译码)阶段

所有指令在取指阶段的操作都相同

①根据PC从主存取指令到IR——数据流向:PC->MAR->M(MAR)->MDR->IR

PC+"1"

  • ALU、加法器、带"自增功能"的寄存器实现
  • "1"与指令字长和编制方式(按字节编制/按字编制)有关

(II)执行阶段

学会根据指令类别思考

①数据传送类指令(如:mov、load、store)——关注数据从哪到哪?

数据只会来源于 寄存器、主存、立即数

寄—>寄

寄—>主

主—>寄

立—>寄

立—>主

寄—>暂存寄存器(某条指令的子步骤)

⚠️若有主存,则关注是 读/写主存

// 读
地址—>MAR;
M(MAR)—>MDR;	// 控制单元CU 给 主存发出读信号
MDR—>目的地;// 写
地址—>MAR;
数据—>MDR;
MDR—>M(MAR);	// CU 给 主存发出写信号

⚠️关注总线占用(总线是临界资源),安排控制信号

②运算类指令

加、减

  • ALU、加法器
  • 带"自增自减"的寄存器(实现++/-- )

  • ALU、乘法器
  • 带"移位功能"的寄存器(实现 2 n 2^n 2n 这种特殊乘法,亦可用ALU的移位功能平替)

  • ALU、除法器
  • 带"移位功能"的寄存器(实现 2 n 2^n 2n 这种特殊除法,亦可用ALU的移位功能平替)

移位

  • ALU
  • 带"移位功能"的寄存器

与、或、异或等双操作数逻辑运算

  • ALU

  • ALU——只需一端有输入
  • 带"取反功能"的寄存器

短数—>长数

  • 带"符号扩展功能"的寄存器
  • 带"零扩展功能"的寄存器

③转移类指令(条件转移)——改变PC值

  • 一般前置会有cmp指令(其本质是减法A-B,生成符号位CF、ZF、OF、SF)

  • 原理:根据标志位判断是否转移(指令中会给出地址码)

⚠️若要转移

①注意指令寻址方式

  • 相对寻址——PC+偏移量——其中偏移量可能以字/字节为单位
  • 直接寻址(少见)

②注意PC的值

  • 以字节为单位——CISC、RISC
  • 以指令字为单位——RISC(精简指令集系统的计算机指令长度相同)

第七章 输入/输出系统

零、大观

考察年份

2010、2011、2012

2017、2018

2023(大题)、2024

一、深入理解I/O系统

PIC—可编程的中断控制器

1、从中断控制器的角度理解整个中断处理过程

2、

3、

二、Printf—从系统调用开始

1、中断隐指令与中断处理程序

中断隐指令(由硬件实现)

①保存断点和程序状态字

②将CPU模式从用户态切换为内核态

中断处理程序(由OS-软件实现)

①保存现场(保存通用寄存器中的内容)

②执行系统调用服务例程(一种特殊的中断处理程序)

sys_write可用三种I/O方式实现:程序查询、中断驱动和DMA

1、轮询(程序查询)方式下输出一个字符串

2、中断驱动方式下输出一个字符串

①中断服务程序(中断总控程序)与设备驱动程序的关系

若同时出现中断服务程序和设备驱动程序

则将中断服务程序理解为中断总控程序并与设备驱动程序区分开

3、DMA方式下输出一个字符串

三、Scanf的完整故事

sys_read用中断方式实现

1、中断驱动方式下输入一个字符串





计算机网络

二轮复习大观

1、详细描述访问WWW.xxx.com服务器资源(HTTP资源)所发生的过程

①DNS查询得到IP地址

②ARP查询得到MAC地址

​ 发送ARP请求的是一个广播;收到ARP响应的是一个单播(先发送广播再返回单播)

③主机与服务器建立TCP连接

④主机发送HTTP协议请求服务器响应请求


http://www.ppmy.cn/embedded/110964.html

相关文章

第3篇:【系统分析师】数据库系统

基本概念 三级模式-两级映像 数据库设计 掌握数据库设计的步骤顺序&#xff0c;以及各个阶段的产出物。在逻辑结构设计中做范式处理 数据库模型 E-R模型 关系模型 关系代数&#xff08;sql语言&#xff09; 规范化 函数依赖&#xff0c;键与约束&#xff0c;模式分解 范式 …

图算法 | 图算法的分类有哪些?(下)

图算法的分类有哪些&#xff1f;综合当前学术界和工业界图计算领域目前最新的发展情况&#xff0c;把图算法划分为了以下六大类&#xff1a; ❑中心性(Centrality)算法&#xff1a;如节点出入度、全图出入度、接近中心性、中介中心性、图中心性、调和中心性等。 ❑相似度(Simil…

多字节字符和宽字符

小时候&#xff0c;买东西的单位是一角、二角和五角&#xff0c;现在的单位是一元、五元和十元。人类社会的发展和计算机发展本质没啥两样&#xff0c;形态不同而已。 编码格式的历史 尽管早期只用ASCII码就可以表达所有字符&#xff0c;但计算机日益推广让其他国家不同语言的…

Redis单机、集群、哨兵、主从架构详解

一、Redis 单机模式 1.1 什么是 Redis 单机模式&#xff1f; Redis 单机模式是最基础的部署方式&#xff0c;所有的数据都存储在一个 Redis 实例中。单机模式下&#xff0c;Redis 提供数据存储、数据读写和数据备份等基本功能&#xff0c;适合小规模数据量和对高可用性要求不…

【信创】龙芯3A6000上lscpu与/proc/cpuinfo的区别

原文链接&#xff1a;【信创】龙芯3A6000上lscpu与/proc/cpuinfo的区别 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于在Linux操作系统上&#xff0c;龙芯3A6000处理器中使用lscpu命令和查看/proc/cpuinfo文件之间的区别的文章。在Linux系统中&#xff0c;我们…

如何在 DigitalOcean Droplet 云服务器上部署 Next.js 应用

Next.js 是一个流行的 React 框架&#xff0c;可轻松构建服务器渲染的 React 应用程序。在本教程中&#xff0c;我们将介绍如何使用 Nginx 作为反向代理&#xff0c;在 DigitalOcean 的 droplet 云主机上部署 Next.js 应用程序。以下是逐步指南&#xff0c;假设你已经准备好部署…

基于 onsemi NCV78343 NCV78964的汽车矩阵式大灯方案

一、方案描述 大联大世平集团针对汽车矩阵大灯&#xff0c;推出 基于 onsemi NCV78343 & NCV78964的汽车矩阵式大灯方案。 开发板搭载的主要器件有 onsemi 的 Matrix Controller NCV78343、LED Driver NCV78964、Motor Driver NCV70517、以及 NXP 的 MCU S32K344。 二、开…

Android Studio偶尔打开Flutter项目没有智能提示的解决方案

Flutter支持多种IDE来编程&#xff0c;我曾使用过Android Studio和VSC两款软件&#xff0c;但因为长期使用Android Studio的原因&#xff0c;使用起来会比VSC顺手&#xff0c;然后就发现偶尔AS加载Flutter项目会无法使用智能提示&#xff0c;也没有代码高亮等 问题出现的原因&…