当前位置: 首页 > news >正文

网站建设整个过程全网搜索指数

网站建设整个过程,全网搜索指数,c语言网页编辑器,重庆网站建设微信开发每日一句 生活总会给你另一个机会, 这个机会叫明天。 目录 每日一句 一.数据结构的基本概念 1.数据相关核心概念 2.数据结构(data structure) 3.数据类型(data type) 4.数据结构的内容(逻辑结构、物…

每日一句

生活总会给你另一个机会,

这个机会叫明天。


目录

每日一句

一.数据结构的基本概念

1.数据相关核心概念

2.数据结构(data structure)

3.数据类型(data type)

4.数据结构的内容(逻辑结构、物理结构、操作集合)

(1)逻辑结构

(2)物理结构(存储结构)

顺序存储

链式存储

索引存储

散列存储(哈希存储)

(3)操作集合

二.抽象数据类型(ADT)

1.抽象的思想

2.抽象数据类型的定义

3.例子:ADT整数(课本表1-2)

4.ADT的意义

三.算法描述

1.算法与程序的关系

2.算法的描述方式

3.算法的5个重要特性

4.“好算法”的目标

四.算法分析

1.算法分析的分类

2.时间复杂度

3.空间复杂度

五.数据结构的C语言表示

1.算法的描述方式

2.用C语言表述抽象数据类型(ADT)

ADT的定义(伪码形式)

用C语言实现ADT(存储结构 + 操作函数)

3.基本操作的算法描述

总结


一.数据结构的基本概念

1.数据相关核心概念

  • 数据(data):**计算机能处理的各种符号(数值、字符、图像、视频等),是 “计算机可识别的信息载体”。**对客观事物的描述,是计算机能输入并加工的符号集合(如数值、字符、图像、视频等),可理解为“计算机能识别和操作的信息”。
  • 数据元素(data element):构成数据的 基本单位 ,程序中通常将其作为整体处理(如 “一条学生选课记录”“报刊订阅系统的一个节点”); 一个数据元素可包含多个 “数据项”。构成数据的基本单位,程序中通常将其作为整体处理。例如:学生选课表的“一行记录”、报刊订阅系统结构图的“每个节点”(如“登录”“用户”等)。
  • 数据项(data item):数据中 不可再分割的最小单位。例如选课记录里的“学号”“课程名”“成绩”,一个数据元素可包含多个数据项(如“一条选课记录”包含学号、课程名等)。
  • 数据对象(data object):由 性质相同的数据元素 组成的集合,是数据的子集。例如:整个学生选课表、“整数集合 ( D = {0, \pm1, \pm2, \dots} )”、“字母集合 ( C = {A,B,\dots,Z} )”。

2.数据结构(data structure)

数据结构是“相互之间存在特定关系的数据元素的集合”,经典定义为二元组 ( \text{Data_Structure} = (D, R) ),其中:

  • ( D ) 是数据对象(要处理的数据集);
  • ( R ) 是 ( D ) 上关系的有限集(数据元素之间的逻辑关联)。
    简言之,数据结构 = 数据元素 + 元素间的关系。

3.数据类型(data type)

是“一个值的集合 + 定义在该集合上的一组操作”的总称。例如C语言的int类型:取值范围为 (-32768 \sim +32767),支持加、减、乘、除等操作,规定了“能存储什么值”和“能对值做什么操作”。
高级语言的“整型、实型、字符型”等,本质是已实现的数据结构实例(因为它们定义了数据的组织方式和操作)。

4.数据结构的内容(逻辑结构、物理结构、操作集合)

数据结构研究三方面内容:逻辑结构物理结构(存储结构)对数据的操作

(1)逻辑结构

数据元素之间的逻辑关系(与“存储方式”无关,只关注元素间的关联),分为4类基本结构

  • 集合结构:元素间仅存在“同属一个集合”的关系,无其他关联;
  • 线性结构:元素间是一对一的关系(如排队,一人接一人);
  • 树形结构:元素间是一对多的关系(如公司架构:老板管理多个经理,每个经理管理多个员工);
  • 图形结构:元素间是多对多的关系(如社交网络:一人可关注多人,多人也可关注同一人)。
    逻辑结构又可分为线性结构(所有元素排成一个序列)和非线性结构(元素与多个其他元素关联)。

(2)物理结构(存储结构)

逻辑结构在计算机内存中的实际存储方式,核心有两种:
物理结构指数据在计算机内存中的具体存储方式与实现逻辑,直接决定数据操作(插入、删除、查找等)的效率。根据存储方式的不同,主要分为以下四种:

顺序存储
  • 定义:将数据元素存放在内存中连续的存储空间内,数据元素的逻辑顺序与物理存储顺序完全一致
  • 核心特点
    • 无需额外存储“元素间的关系信息”,存储密度高
    • 可通过“下标”随机访问元素(时间复杂度 ( O(1) ),如数组 arr[3] 可直接通过地址计算访问);
    • 插入/删除元素时,需移动大量后续数据(如数组中间插入元素,后续元素需整体后移,时间复杂度 ( O(n) ))。
  • 示例:C语言中的数组(如 int arr[5] = {1,2,3,4,5}),元素 1 2 3 依次存储在内存连续地址(如 0x100 0x104 0x108)中。
链式存储
  • 定义:数据元素存放在内存中非连续的存储空间内,通过给每个元素附加“指针(或引用)”,指向其逻辑上的相邻元素,以此建立元素间的关系。
  • 核心特点
    • 插入/删除元素时,仅需修改指针指向(无需移动数据,时间复杂度 ( O(1) ));
    • 无法“随机访问”(需从首元素开始依次遍历,时间复杂度 ( O(n) ));
    • 指针会占用额外存储空间,存储密度低于顺序存储
  • 示例:单链表(每个节点包含“数据域”和“指针域”,如:
    struct Node {int data;           // 数据域:存储元素值struct Node* next;  // 指针域:指向下一个节点
    };
    
    节点1的 next 指针指向节点2,节点2指向节点3,通过指针串联非连续存储的元素)。
索引存储
  • 定义:将数据分为两部分——数据区(存储所有数据元素)和索引表(存储“关键字-数据地址”的映射关系);通过关键字在索引表中快速查找对应数据的存储地址,再到数据区访问数据。
  • 核心特点
    • 大幅提升查找效率(尤其海量数据,时间复杂度接近 ( O(1) ));
    • 索引表会占用额外存储空间
    • 插入/删除数据时,需同步维护索引表(增加操作开销)。
  • 示例
    • 图书馆的“图书索引”:索引表记录“书名 → 书架编号”,读者先查索引找到书架,再去书架取书;
    • 数据库中的索引:如MySQL的B+树索引,通过索引快速定位表中数据的物理位置。
散列存储(哈希存储)
  • 定义:通过“散列函数(哈希函数)”,将数据元素的“关键字”直接映射为其在内存中的存储地址,实现“关键字 → 地址”的直接对应。
  • 核心特点
    • 查找、插入、删除效率极高(理想情况下时间复杂度 ( O(1) ));
    • 可能出现“哈希冲突”(不同关键字映射到同一地址),需额外处理(如链地址法:冲突元素用链表串联;开放定址法:冲突时寻找下一个空闲地址);
    • 散列函数的设计直接影响存储效率(需尽可能减少冲突)。
  • 示例
    • 哈希表:如Java中的 HashMap,通过 hash(key) 计算元素存储位置,直接定位元素;
    • 密码学哈希:如MD5算法,将任意长度数据映射为固定长度的哈希值(用于数据完整性校验)。

(3)操作集合

对数据的操作,如增加、删除、修改、查找、排序等。数据结构的完整定义是:“按逻辑组织的数据 + 存储方式 + 可执行的操作”的整体。

二.抽象数据类型(ADT)

1.抽象的思想

抽象是从同类事物中舍弃“个别、非本质的属性”,抽取“共同、本质的属性”。例如“四边形”:无论正方形、长方形还是不规则四边形,只要是“四条边组成的平面封闭图形”,就被抽象为“四边形”;在数据结构中,用抽象描述程序中数据的组织形式(如树、图的抽象定义)。

2.抽象数据类型的定义

抽象数据类型(Abstract Data Type,ADT)是“一组数据对象 + 元素间的结构关系 + 对数据的操作集合”,形式化表示为三元组:

ADT 抽象数据类型名 {数据对象D;   // 要处理的数据集数据关系R;   // 数据元素间的关系基本操作P;   // 可对数据执行的操作
} ADT 抽象数据类型名

核心是只定义“逻辑特性和操作接口”,不关心“具体实现细节”。例如C语言的“整型”是基本类型,基于它可构造“栈、队列”等更复杂的ADT。

3.例子:ADT整数(课本表1-2)

ADT 整数 {数据对象:整数有序序列(从0到最大整数)、布尔值(True/False);基本操作:Zero();        // 类似构造函数,初始化整数Is_Zero(x);    // 判断x是否为0,返回True/FalseAdd(x, y);     // 两整数相加,返回和Equal(x, y);   // 判断x与y是否相等,返回True/FalseSubtract(x, y);// 两整数相减,返回差Successor(x);  // 返回x的下一个自然数,若x是最大整数则返回最大整数
} ADT 整数

ADT的关键:用户只需关心“如何调用操作”,无需关心“操作内部如何实现”(如Add(x,y)是用硬件加法器还是软件模拟,用户无需知晓)。

4.ADT的意义

ADT实现了“信息隐藏”:内部实现细节(如用数组还是链表存储数据)对外屏蔽,仅暴露“操作接口”。这样带来两个好处:

  • 修改内部实现时,只要接口不变,外部代码无需修改(如把“栈”的存储从数组换成链表,调用push/pop的代码无需变更);
  • 软件更“模块化、可复用”,像“搭积木”一样组合ADT开发大型程序(如栈、队列的ADT可在多个场景重复使用)。
    课本强调:“ADT抽象程度越高,软件复用程度越高”(如“图”的ADT比“整型”抽象程度高,能支持更复杂的场景)。

三.算法描述

1.算法与程序的关系

Niklaus Wirth的名言:“算法 + 数据结构 = 程序”——算法是“解决问题的步骤逻辑”,程序是“算法用具体编程语言的实现”。例如计算 ( 1 - \frac{1}{2} + \frac{1}{3} - \frac{1}{4} + \dots + \frac{1}{99} - \frac{1}{100} ),不同算法对应不同程序代码:

  • 算法1:直接逐项相加/相减

    #include <stdio.h>
    int main() {double sum = 0.0;int sign = 1; // 符号标记:1为正,-1为负for (int i = 1; i <= 100; i++) {sum += sign * 1.0 / i;sign = -sign; // 切换符号}printf("结果:%lf\n", sum);return 0;
    }
    
  • 算法2:拆分为两个多项式相减 ( (1 + \frac{1}{3} + \frac{1}{5} + \dots + \frac{1}{99}) - (\frac{1}{2} + \frac{1}{4} + \frac{1}{6} + \dots + \frac{1}{100}) )

    #include <stdio.h>
    int main() {double sum1 = 0.0, sum2 = 0.0;// 计算奇数项和for (int i = 1; i <= 99; i += 2) {sum1 += 1.0 / i;}// 计算偶数项和for (int i = 2; i <= 100; i += 2) {sum2 += 1.0 / i;}double sum = sum1 - sum2;printf("结果:%lf\n", sum);return 0;
    }
    

2.算法的描述方式

  • 自然语言:用中文、英文等描述,优点是“简单易懂”,缺点是“歧义多、不严谨”(如“然后处理数据”,未明确处理逻辑)。
  • 类语言(伪代码):介于自然语言和编程语言之间,更接近代码逻辑(如for i from 1 to n),比自然语言准确,且无需严格遵循某门语言的语法。
  • 程序设计语言(如C语言):最准确,能直接运行,但“编写繁琐,受语言语法限制”。课本后续用C语言描述算法(因C语言类型丰富、执行效率高)。

3.算法的5个重要特性

算法是 “解决特定问题的有限、确定的步骤集合”,需满足 5 个基本特性

  • 有穷性:对任意合法输入,算法必须在有限步骤内结束,且每个步骤的执行时间有限(死循环不是算法)。
  • 确定性:每一条指令的含义明确无歧义,任何情况下算法只有“一条执行路径”(如“若 ( x>0 ) 则执行操作A,否则执行操作B”,条件清晰)。
  • 可行性:算法中的操作都能通过“已实现的基本运算”(如加减乘除、赋值、比较)有限次完成
  • 输入:可以有0个或多个输入(输入是算法执行前的初始数据,若算法内部可生成数据,则无需外部输入)。
  • 输出:至少有一个输出(算法的结果,如打印、返回值等,无输出的算法无意义)。

4.“好算法”的目标

设计算法时,追求以下目标:

  • 正确性:能正确解决问题,分4个层次:
    • 程序无语法错误;
    • 对“合法输入”能得到符合要求的结果;
    • 对“非法输入”能适当处理(如提示错误);
    • 对“所有合法输入”都能得到正确结果(最难达到,通常验证关键场景)。
  • 可读性:容易被人理解,便于交流、维护(如代码添加注释、逻辑清晰)。
  • 健壮性:输入非法数据时,能“做出反应”(如提示“输入错误”),而非崩溃或给出错误结果。
  • 高效率与低存储量需求:执行时间尽可能短(高效率),占用存储空间尽可能少(低存储量)——两者都与“问题规模”(如数据量大小)相关。

四.算法分析

数据结构的优劣通过算法效率体现,需分析算法的时间效率(执行时间)和空间效率(存储空间)。

1.算法分析的分类

  • 算法分析理论上评估效率,不依赖具体计算机(得到通用结论)。
  • 性能测量实际运行程序,统计执行时间和空间占用,但受硬件、软件环境影响大(如在低配电脑和高配电脑上,同一程序运行时间不同)。
    课本重点讲解算法分析(以得到“与具体机器无关”的通用效率结论)。

2.时间复杂度

  • 定义:算法的执行时间随问题规模 ( n ) 增长的趋势,用大O符号表示(大O表示“渐进上界”,即“最坏情况下的增长趋势”)。
    算法执行时间 ≈ 编译时间 + 所有语句执行时间的总和。由于“编译时间与问题规模无关”,因此主要分析语句执行时间

  • 基本操作:与“问题规模”无关的操作(如赋值、比较、算术运算等)。算法的时间消耗,取决于“基本操作的执行次数”。

  • 语句频度与时间复杂度

    • 语句频度:语句执行的次数,记为 ( T(n) );
    • 时间复杂度:记为 ( T(n) = O(f(n)) ),表示“当 ( n ) 趋近于无穷大时,( T(n) ) 的增长趋势与 ( f(n) ) 一致”(低阶项、常数项可忽略,只关注最高阶项)。
  • 经典例子

    • ① 单条操作:

      ++x;
      

      执行次数为1,时间复杂度 ( O(1) )(常数阶)——无论 ( n ) 多大,执行时间基本不变。

    • ② 一层循环:

      for(int i=1; i<=n; i++) {++x;
      }
      

      循环 ( n ) 次,执行次数为 ( n ),时间复杂度 ( O(n) )(线性阶)——( n ) 翻倍,时间也翻倍。

    • ③ 两层循环:

      for(int i=1; i<=n; i++)for(int j=1; j<=n; j++) {++x;}
      

      循环 ( n^2 ) 次,执行次数为 ( n^2 ),时间复杂度 ( O(n^2) )(平方阶)——( n ) 翻倍,时间翻四倍。

  • 课本案例

    • 矩阵相乘(例1-4)

      #define N 100 // 假设矩阵大小为N×N
      void mult(int a[][N], int b[][N], int c[][N], int n) {for(int i=1; i<=n; i++)for(int j=1; j<=n; j++) {c[i][j] = 0;for(int k=1; k<=n; k++) {c[i][j] += a[i][k] * b[k][j];}}
      }
      

      基本操作是“乘法”,执行次数约为 ( 2n^3 + 2n^2 + n )。当 ( n ) 很大时,低阶项(( 2n^2 )、( n ))和常数可忽略,时间复杂度 ( O(n^3) )。

    • 选择排序(例1-5)

      void select_sort(int a[], int n) {int j, k, temp;for(int i=0; i<n-1; i++) {j = i;for(k=i+1; k<n; k++) {if(a[k] < a[j]) j = k;}if(j != i) {temp = a[i];a[i] = a[j];a[j] = temp;}}
      }
      

      基本操作是“比较”,执行次数约为 ( \frac{n(n-1)}{2} )(≈( \frac{n^2}{2} )),时间复杂度 ( O(n^2) )。

    • 冒泡排序(例1-6)

      void bubble_sort(int a[], int n) {int change, temp;for(int i=n-1; i>=1 && change; i--) {change = 0;for(int j=0; j<i; j++) {if(a[j] > a[j+1]) {temp = a[j];a[j] = a[j+1];a[j+1] = temp;change = 1;}}}
      }
      
      • 最好情况(数组已排好序):执行次数为 ( n ),时间复杂度 ( O(n) );
      • 最坏情况(数组逆序):执行次数为 ( \frac{n(n-1)}{2} ),时间复杂度 ( O(n^2) )。
        通常分析最坏时间复杂度(保证算法在“最坏情况”下也能高效运行)。
  • 常用时间复杂度的顺序
    ( O(1) < O(\log_2 n) < O(n) < O(n \log_2 n) < O(n^2) < O(n^3) < O(2^n) )
    越往后,( n ) 增大时执行时间增长越快,因此优先选择复杂度低的算法。

3.空间复杂度

  • 定义:算法所需存储空间的度量,记为 ( S(n) = O(f(n)) ),其中 ( n ) 是问题规模。

  • 空间组成

    • 固定空间需求:与输入无关的空间,如“指令存储空间”“简单变量”“固定大小的结构变量(如结构体)”“常量”等。
    • 可变空间需求:与输入有关的空间,如“输入数据的存储空间”“动态分配的空间(如链表节点)”“递归调用的栈空间”等。
  • 时间与空间的权衡:“时间成本和空间成本是矛盾的”:

    • 时间换空间:如“压缩数据”(节省空间),但需要花费时间“压缩/解压”;
    • 空间换时间:如“预先计算并存储结果”(节省时间),但需要更多存储空间。

五.数据结构的C语言表示

这部分是“抽象到具体”的关键,将“ADT、数据结构”用C语言落地实现。

1.算法的描述方式

描述算法的常见方式:自然语言、流程图、伪代码、N-S结构流程图、PAD图等。
课本选择**“以C语言为主,伪代码为辅”**的策略:

  • 用C语言描述“可直接运行的数据结构实现”;
  • 用伪代码描述“只含抽象操作的算法逻辑”(避免被C语言语法细节干扰,突出核心逻辑)。

2.用C语言表述抽象数据类型(ADT)

ADT的“实现”分为**“定义(逻辑层面)”“代码(物理层面)”**两步。

ADT的定义(伪码形式)

ADT的定义只关注“逻辑要做什么”,不涉及具体语言语法,格式为:

ADT 抽象数据类型名 {数据对象: <对象的抽象定义>数据关系: <元素间关系的抽象定义>基本操作: <操作的抽象定义>
} ADT 抽象数据类型名

其中,“基本操作”的定义需明确前置条件(操作执行的前提)和后置条件(操作执行的结果)。

例子:ADT string(串的抽象定义,例1-7)

ADT string {数据对象: {S | S由字符组成,i=0,1,…,n-1,n≥0}  // 串是“字符序列”数据关系: {R | R={<S₀,S₁>,<S₁,S₂>,…,<Sₙ₋₂,Sₙ₋₁>}}  // 字符间的“顺序关联”关系基本操作:StrAssign(S, chars);  // 赋值:将字符序列chars赋给串SStrDestroy(S);        // 销毁:释放串S的存储空间StrCopy(S₁, S₂);      // 复制:将串S₂的内容复制到S₁StrCompare(S₁, S₂);   // 比较:比较串S₁和S₂的大小StrCombine(S, S₁, S₂); // 连接:将S₁和S₂连接,生成新串SStrReplace(S, S₁, S₂); // 替换:用S₂替换S中与S₁匹配的子串//... 其他操作
} ADT string

ADT定义是“逻辑抽象”,不关心“具体用C语言如何存储、如何编写函数”,只定义“要做什么”。

用C语言实现ADT(存储结构 + 操作函数)

ADT的“实现”需解决两个核心问题:数据怎么存(存储结构) + 操作怎么写(函数)

  • 存储结构的表示(typedef + 结构体)
    用C语言的typedef(类型定义)和struct(结构体),描述“数据的物理存储方式”。

    例子:串的动态数组存储(例1-8)

    typedef struct string {char *str;          // 指针,指向存储字符串的基地址(动态分配内存)int maxlength;      // 动态数组可存储的最大字符数(总空间大小)int length;         // 当前串的实际长度
    } DString, *DStr;
    

    解释:

    • typedefstruct string重命名为DString结构体类型),*DStr是“指向DString的指针类型”(方便用指针操作串);
    • char *str是动态数组的核心:运行时通过malloc分配空间,可灵活存储字符序列;
    • maxlength记录总空间大小,length记录串的实际长度——这种设计能“按需分配、灵活管理”字符串空间。

    补充:类型与变量的区别DString是“类型名”(规定串的存储规范),只有定义DString s;这样的变量时,才会真正分配存储空间。

  • 用C函数实现ADT的操作
    ADT中的“基本操作”(如StrAssignStrCopy),需编写为C函数,格式为:

    函数类型 函数名(函数参数表) {/* 算法说明 */  // 注释:解释函数要完成的逻辑语句序列       // 具体的C代码(赋值、循环、指针操作等)
    }
    

    示例(简化的StrAssign逻辑):

    // 假设Status为int类型,1表示成功,0表示失败
    typedef int Status;
    Status StrAssign(DString *S, char *chars) {/* 算法说明:将chars赋值给串S。成功返回1,失败返回0 */// 1. 释放S原有空间(若存在)if (S->str != NULL) free(S->str);// 2. 计算chars长度,分配新空间int len = strlen(chars);S->str = (char *)malloc((len + 1) * sizeof(char));if (S->str == NULL) return 0; // 内存分配失败// 3. 复制chars到S->str,并设置长度strcpy(S->str, chars);S->length = len;S->maxlength = len + 1;return 1; // 操作成功
    }
    

    补充:

    • 参数传递:常用指针参数(如DString *S),利用C语言的“传地址”特性,直接修改传入变量的内容;
    • 返回状态:若函数需返回“操作是否成功”,可定义typedef int Status;(如1表示成功,0表示失败)。

3.基本操作的算法描述

课本中算法的“类C语言”描述具有以下特点:

  • 格式:函数类型 函数名(参数表),内部包含“注释(算法说明) + 语句序列”;
  • 参数:明确参数类型,辅助变量可通过注释说明(如/* 字符指针p */);
  • 返回值:若返回“操作状态”则用Status类型,若返回具体数据则用对应类型(如intchar *);
  • 指针传递:依赖C语言的指针特性,实现“修改传入变量”的效果(如修改串的内容、长度)。

总结

绪论搭建了“数据结构与算法”的整体框架:

  • 明确“数据怎么组织”(逻辑结构 + 存储结构);
  • 掌握“怎么抽象描述数据”(ADT);
  • 理解“怎么用算法处理数据”(算法的描述、分析);
  • 学会“怎么用C语言实现”(编程语言与数据结构的结合)。

每个概念都为后续“栈、队列、树、图”等具体数据结构的学习奠定基础,透彻理解绪论,后续学习会更加顺畅。

http://www.dtcms.com/a/403324.html

相关文章:

  • 安科瑞ADL200N-CT 单相户用储能表
  • 网站如何建立这么做简单的网站
  • Zabbix7.4.8(一):通过Zabbix agent 2监控postgresql相关指标
  • 实战:基于 BRPC+Etcd 打造轻量级 RPC 服务 —— 从注册到调用的完整实现
  • 企业为什么建设网站万网主机怎么上传网站吗
  • 【C++】Visual Studio+CMake 开发 C++ 入门指南:从环境搭建到项目实战
  • web3hardhat 框架实战-ERC20
  • Linux《线程同步和互斥(上)》
  • Hibernate批量操作详解及最优实践
  • 住房与建设部网站如何修改dns 快速使用境外网站
  • 【复习】计网每日一题--PPP链路
  • cpt和pretrain的差别,IFT和SFT的差别是怎么样的
  • RTX5060 Ti显卡安装cuda版本PyTorch踩坑记录
  • MongoDB数据类型与python操作
  • 脑电模型实战系:脑电模型进阶-构建一个高效的全连接网络
  • 东莞网站建设怎么收费展会布置效果图
  • 滕滕州网站建设住房和建设局官网
  • Vue调用本地EXE程序
  • Vue2 全局事件总线:通俗易懂 + 简单案例
  • Flask模板中使用Vue、ant-design-vue、@ant-design/icons-vue示例模板
  • 石狮建设局网站保定网站建设系统
  • vLLM PD分离推理服务配置指南
  • C++ 学习与 CLion 使用:(十五)多文件编程,和C语言一样的多文件编程
  • BEAT币
  • 淘宝的网站怎么做公司网站如何被收录
  • Ansible实现自动化运维
  • Zabbix7.4.8(三):通过Zabbix agent 2监控Docker相关指标
  • 小型个人网站制作网页打不开的原因及解决方法
  • Ansible 入门到实战:自动化运维的瑞士军刀
  • 嵌入式学习---(linux驱动)