菜狗的大作业(

计算机系统

大作业

题     目 程序人生-Hello’s P2P

专       业 计算机科学与技术

学     号 2021113307

班     级 21w0312

学       生 赵志远  

指 导 教 师 史先俊

计算机科学与技术学院

2022年5月

摘  要

台上一分钟,台下十年功。在台上Hello!World!弹出的短短一瞬,台下的计算机究竟做出了多少工作呢?在本文将简要论述Hello程序在计算机上诞生,运行,结束时,在屏幕上弹出“Hello!World!”时的短暂的表演中,计算机在其中默默无闻的做出的诸多幕后工作。本文将从hello.c的创建,编译,运行开始,详细阐述其中同时发生的进程管理,内存管理,看到计算机运行中的细枝末节。

关键词:计算机系统;Hello;程序人生;

目  录

第1章 概述................................................................................................................ - 4 -

1.1 Hello简介......................................................................................................... - 4 -

1.2 环境与工具........................................................................................................ - 4 -

1.3 中间结果............................................................................................................ - 4 -

1.4 本章小结............................................................................................................ - 4 -

第2章 预处理............................................................................................................ - 5 -

2.1 预处理的概念与作用........................................................................................ - 5 -

2.2在Ubuntu下预处理的命令............................................................................. - 5 -

2.3 Hello的预处理结果解析................................................................................. - 5 -

2.4 本章小结............................................................................................................ - 5 -

第3章 编译................................................................................................................ - 6 -

3.1 编译的概念与作用............................................................................................ - 6 -

3.2 在Ubuntu下编译的命令................................................................................ - 6 -

3.3 Hello的编译结果解析..................................................................................... - 6 -

3.4 本章小结............................................................................................................ - 6 -

第4章 汇编................................................................................................................ - 7 -

4.1 汇编的概念与作用............................................................................................ - 7 -

4.2 在Ubuntu下汇编的命令................................................................................ - 7 -

4.3 可重定位目标elf格式.................................................................................... - 7 -

4.4 Hello.o的结果解析......................................................................................... - 7 -

4.5 本章小结............................................................................................................ - 7 -

第5章 链接................................................................................................................ - 8 -

5.1 链接的概念与作用............................................................................................ - 8 -

5.2 在Ubuntu下链接的命令................................................................................ - 8 -

5.3 可执行目标文件hello的格式....................................................................... - 8 -

5.4 hello的虚拟地址空间..................................................................................... - 8 -

5.5 链接的重定位过程分析.................................................................................... - 8 -

5.6 hello的执行流程............................................................................................. - 8 -

5.7 Hello的动态链接分析..................................................................................... - 8 -

5.8 本章小结............................................................................................................ - 9 -

第6章 hello进程管理...................................................................................... - 10 -

6.1 进程的概念与作用.......................................................................................... - 10 -

6.2 简述壳Shell-bash的作用与处理流程........................................................ - 10 -

6.3 Hello的fork进程创建过程........................................................................ - 10 -

6.4 Hello的execve过程.................................................................................... - 10 -

6.5 Hello的进程执行........................................................................................... - 10 -

6.6 hello的异常与信号处理............................................................................... - 10 -

6.7本章小结.......................................................................................................... - 10 -

第7章 hello的存储管理................................................................................... - 11 -

7.1 hello的存储器地址空间............................................................................... - 11 -

7.2 Intel逻辑地址到线性地址的变换-段式管理............................................... - 11 -

7.3 Hello的线性地址到物理地址的变换-页式管理.......................................... - 11 -

7.4 TLB与四级页表支持下的VA到PA的变换................................................ - 11 -

7.5 三级Cache支持下的物理内存访问............................................................. - 11 -

7.6 hello进程fork时的内存映射..................................................................... - 11 -

7.7 hello进程execve时的内存映射................................................................. - 11 -

7.8 缺页故障与缺页中断处理.............................................................................. - 11 -

7.9动态存储分配管理.......................................................................................... - 11 -

7.10本章小结........................................................................................................ - 12 -

第8章 hello的IO管理.................................................................................... - 13 -

8.1 Linux的IO设备管理方法............................................................................. - 13 -

8.2 简述Unix IO接口及其函数.......................................................................... - 13 -

8.3 printf的实现分析........................................................................................... - 13 -

8.4 getchar的实现分析....................................................................................... - 13 -

8.5本章小结.......................................................................................................... - 13 -

结论............................................................................................................................ - 14 -

附件............................................................................................................................ - 15 -

参考文献.................................................................................................................... - 16 -

第1章 概述

1.1 Hello简介

Hello的P2P:首先写代码,命名为hello,c,之后经过预处理,编译,汇编,链接,运行,经过系统的进程管理,成为了一个进程。

Hello的020:由shell加载hello。映射虚拟内存,进入程序,载入物理内存,执行main函数。程序结束后,shell回收hello进程,删除hello的进程占用。

1.2 环境与工具

硬件环境:

处理器 11th Gen Intel(R) Core(TM) i5-11400H @ 2.70GHz   2.69 GHz

机带 RAM 16.0 GB (15.8 GB 可用)

系统类型    64 位操作系统, 基于 x64 的处理器

GPU:NVIDIA GeForce RTX 3050 Laptop GPU

软件环境:7

Windows 10

Vmware16上的Ubuntu(64位)虚拟机

开发工具:

vim文本编辑器

Visual Studio

EDB

Vscode

Gcc编译器

调试工具:

GDB

1.3 中间结果

列出你为编写本论文,生成的中间结果文件的名字,文件的作用等。

1.hello.i:cpp预处理原始的.c后缀的C程序。主要是将头文件直接插入程序文本中,并且根据define进行字符串的简单替换,得到新的预处理过的C文本文件。(文本文件)

2.hello.s:编译器将预处理过的以.i为后缀的文件编译成汇编文件。(文本文件)

3.hello.o:汇编器将以.s为后缀的汇编文件转化为机器语言,此时为可重定位目标文件(二进制文件)。

4.hello:利用链接器,将C函数库中相应的函数与hello.o可重定位文件链接,生成可执行目标文件(二进制文件)。

5.tmp.txt:hello.o的用readelf产生的文件。

6.tmp2.txt:hello.o的反汇编文件(逐渐潦草的命名( •̀ ω •́ )y)

7.Tmp3.txt:hello用readelf产生的文件。

1.4 本章小结

本章简要介绍了hello的p2p以及020的过程,并简要的介绍了hello.c文本源文件到hello可执行目标文件的转变。并列举了实验进行过程中的硬件环境,软件环境,开发工具,调试工具。

第2章 预处理

2.1 预处理的概念与作用

预处理概念:处理c源文件中的预处理程序和注释。

预处理作用:预处理器(cpp)根据以字符#开头的预处理命令处理c源文件,修改原始的c源文件,预处理过程中,预处理器会分析预处理指令,依据#include进行库文件的插入,依据#define进行字符串的替换等,并且同时去除c源代码中的注释。

2.2在Ubuntu下预处理的命令

2.3 Hello的预处理结果解析

文件长度变长,预编译指令消失,对应库文件的内容被插入到预处理文件中。

2.4 本章小结

本章执行了预处理指令,看了预处理后的文本文件的内容,看了预处理的方式与作用。

第3章 编译

3.1 编译的概念与作用

编译的概念:编译器(ccl)将文本文件.i(C语言)翻译成文本文件.s(汇编语言)。

编译的作用:将C语言文本文件翻译成汇编语言文本文件,每一条汇编文本语言对应一条低级机器指令语言。

3.2 在Ubuntu下编译的命令

3.3 Hello的编译结果解析

3.3.1数据:

printf里的格式字符串:

Main函数的两个参数以及局部变量i:

其中-4(%rbp)为int i的局部变量,-20(%rbp)为mian函数的参数1,-32区域为参数二。

3.3.2赋值:

给局部变量i赋初值0。

3.3.3算数运算:

在循环中给i加1.

3.3.4关系操作:

比较主函数参数1(后边参数个数)和4的关系

循环体中的循环条件。

3.3.5数组/指针/结构操作:

Printf中所需的字符串数组,首地址放入rax中。

前7行是对main函数的字符串数组参数调用,分别调用了第1,2号字符串,最后两行是对printf中格式串字符的引用,都是通过获得首地址来调用数组。

3.3.6控制转移:

对应一下语句

如果等于,进入之后的函数中,如果不等于,则进入exit。

此处为for循环中的条件控制,如果等于8退出,若不等于循环。

3.3.7函数操作:

如果参数个数不等于4,调用printf和exit函数。

在循环体中的printf函数。

调用字符串转数的函数。

调用sleep函数

调用getchar函数。

3.4 本章小结

在本章中我看了汇编文件中的汇编语句,对C语言如何用汇编语言实现,汇编与C语言之间的一一对应关系进行了直观的感受。

第4章 汇编

4.1 汇编的概念与作用

汇编的概念:汇编器将.s文本文件翻译成机器语言。

汇编的作用:汇编器将.s中的汇编语言翻译成计算机能处理的机器指令语言,并输出可重定位文件(二进制文件)。

4.2 在Ubuntu下汇编的命令

4.3 可重定位目标elf格式

Elf格式:

重定位节:

类型表示如何引用,R_X86_64_PC32表示重定位PC相对引用,查询了神奇的互联网后,得知了R_X86_64_PLT32代表了符号在plt项的地址+addend,减去重定位项的offset填入到指令中,PLT貌似是一个函数入口表的格式。R_X86_64_32是重定位绝对引用的意思。

4.4 Hello.o的结果解析

汇编中使用的是十进制的立即数,反汇编得到的为十六进制的立即数。汇编中使用节+偏移表示地址,反汇编使用main+偏移表示转移地址,且没有L1等节。机器识别由操作码和操作数组成的机器语言,机器语言和汇编语言是一对一的映射关系。

4.5 本章小结

本节对汇编产生的可重定位文件进行了分析,看了可重定位文件的各个节,各节的内容和作用;比较了机器语言和汇编代码的关系,分析了反汇编和汇编的关系。

第5章 链接

5.1 链接的概念与作用

链接的概念:合并各个独立的但互相引用的文件。

链接的作用:将多个目标文件进行连接构成可执行目标文件,为的是可以在一个文件中使用另一个文件中定义的函数/全局变量。

5.2 在Ubuntu下链接的命令

5.3 可执行目标文件hello的格式

各段地址大小如下图:(节头部表)

5.4 hello的虚拟地址空间

加载hello后的虚拟地址空间:

对照5.3中的.init节,从0x00401000开始

对照rodata节,从0x00402000开始:从依稀出现的hello看出此处存了一些printf中的格式串。

5.5 链接的重定位过程分析

链接后的可执行文件中相比于连接前的可重定位文件,多了许多函数,且call语句后面为正确的执行位置。而非下一条语句的位置。

链接过程为:链接器根据hello.o文件中重定位条目中重定位元素的类型的不同得到不同的偏移量,通过节偏移和重定位条目的地址就可以计算出重定位后的地址;最基本的重定位类型有两种,分别是重定位一个使用32位PC相对地址的引用和重定位一个使用32位绝对地址的引用。得到地址后根据hello.o中的提示对地址进行修改。就可以完成重定位,之后链接hello运行所需的其他库函数。

5.6 hello的执行流程

以下格式自行编排,编辑时删除

使用edb执行hello,说明从加载hello到_start,到camain,以及程序终止的所有过程。请列出其调用与跳转的各个子程序名或程序地址。

hello程序先调用_init初始化,之后到_start,再到main,main执行之后执行_printf、_exit、_atoi、_sleep、_getchar,最后退出。

程序名和地址:

0000000000401000 <_init>

0000000000401125 <main>

00000000004010f0 <_start>

0000000000401090 <puts@plt>

00000000004010a0 <printf@plt>

00000000004010b0 <getchar@plt>

00000000004010c0 <atoi@plt>

00000000004010d0 <exit@plt>

00000000004010e0 <sleep@plt>

5.7 Hello的动态链接分析

动态链接采用了延迟加载的策略,即在调用函数时才进行符号的映射。使用偏移量表GOT+过程链接表PLT实现函数的动态链接。GOT中存放函数目标地址,为每个全局函数创建一个副本函数,并将对函数的调用转换成对副本函数调用。

在之前的节头表中发现got.plt地址为404000。

dl_init前:

dl_init后:

可见其中个别字节发生了改变,是由于动态链接产生的结果。

5.8 本章小结

概括了链接的概念。分析了hello程序运行时的虚拟地址空间,hello的重定位过程和执行过程中地址的变化。阐述了动态链接的过程。

第6章 hello进程管理

6.1 进程的概念与作用

进程的概念:对处理器,主存,I/O设备的抽象,一个执行中程序的实例。

进程的作用:给我们一种假象,仿佛在计算机上,只有我们的程序是当前唯一运行的程序,我们的程序独占处理器,独占内存。

6.2 简述壳Shell-bash的作用与处理流程

作用:shell是一个为用户提供界面访问操作系统的内核服务。它是用户使用linux的方式。

处理流程:

1.从终端输入程序

2.切分字符串获得参数

3.如果内置命令则立刻执行,否则调用相应的程序为其分配子进程并运行

6.3 Hello的fork进程创建过程

在终端输入命令行后,shell会处理命令,如果不是内置命令,则调用fork创建子进程,子进程与父进程有相同虚拟地址,文件文件描述的相同副本。但PID不同。

6.4 Hello的execve过程

Excave在当前进程中加载并运行包含在可执行目标文件hello的程序,代替当前程序。首先删除已存在的用户区域,之后映射共享部分,最后设置程序计数器。

6.5 Hello的进程执行

1.逻辑控制流:程序计数器(PC)值的序列叫做逻辑控制流,简称为逻辑流。

2.上下文切换:上下文是内核重新启动一个被抢占进程所需的状态。内核可以决定抢占当前的进程,并重新开始一个先前被抢占的进程,这种决策成为调度,由调度器执行。在内核中调度一个新的程序运行,它会抢占当前的进程,该过程中使用的机制成为上下文切换,是一种较高层次的一场控制流来实现的。

3.时间片:进程执行它的控制流的一部分的每一个时间段称为时间片。

Shell调用fork为hello创建子进程,使用excave进行运行,开始hello运行在用户模式,收到信号后进入内核模式,运行信号的处理程序,之后回到用户模式。此时上下文切换,切分成时间片,并且也会切入到其他进程,形成多个程序共用处理器,但给人以独占的感觉。。

6.6 hello的异常与信号处理

可能出现的异常:

  1. 中断:处理器外I/O设备信号的结果,异步异常,总是返回到下一条指令
  2. 陷阱:一种有意的异常,使指令执行的结果,其最重要的用途是在用户程序和内核之间提供一个像过程一样的接口,称为系统调用。一般返回下一条指令。
  3. 由错误的情况引起,非有意。如果被故障处理程序修正,则重新执行;若不能被修正,则终止程序。
  4. 不可恢复的致命性错误。终止处理程序,并且不会控制返回给应用程序。

信号:

Hello中的信号处理:

Ctrl+C结果:终止

乱摁和回车:正常运行。

Ctrl+Z:停止

Ps:显示进程

Jobs:显示任务

Pstree:显示进程

Fg:后台停止程序变为前台运行程序

Kill:发送信号

发送杀死信号:停止程序变为终止程序

发送SIGCONT:停止程序继续运行

6.7本章小结

本章概括了进程的概念,shell的作用,fork和execve的运行过程以及hello的异常和信号处理。

第7章 hello的存储管理

7.1 hello的存储器地址空间

结合hello说明逻辑地址、线性地址、虚拟地址、物理地址的概念。

逻辑地址:由程序产生的和段相关的偏移地址,格式为:段+偏移。

线性地址:逻辑地址加上相应段的基地址就生成了线性地址。

虚拟地址:虚拟地址是一个抽象的地址空间,虚拟地址对应虚拟页,虚拟页会映射磁盘空间的一页,如果要使用该页上的数据,则会将该页载入内存,虚拟地址就对应了物理地址。

物理地址:CPU外部地址总线上的物理内存的地址,可以将内存看成一个从0字节开始的数组,每个字节拥有单独的物理地址。

7.2 Intel逻辑地址到线性地址的变换-段式管理

段式管理:逻辑地址->线性地址==虚拟地址

被选中的段描述符先被送至描述符cache,每次从描述符cache中取32位段基址,与32位段内偏移量(有效地址)相加得到线性地址

7.3 Hello的线性地址到物理地址的变换-页式管理

虚拟内存分割为虚拟页,物理内存分割为物理页,依据虚拟地址的虚拟页号和页偏移得到物理地址。

7.4 TLB与四级页表支持下的VA到PA的变换

通过虚拟地址得到一级页表中下一级页表的位置,以此类推至4级页表,最后得到的是物理地址。

7.5 三级Cache支持下的物理内存访问

首先通过物理地址中的组索引位得到组号。先在L1高速缓存对比有效位和标志位,匹配成功则读取,失败则进入二级高速缓存中再次匹配,以此类推,并且进行缓存的更改,在k-1层存储中缓存该数据。

7.6 hello进程fork时的内存映射

为新进程创建虚拟内存,创建当前进程的的mm_struct, vm_area_struct和页表的原样副本.,两个进程中的每个页面都标记为只读,两个进程中的每个区域结构都标记为私有的写时复制。在新进程中返回时,新进程拥有与调用fork进程相同的虚拟内存,随后的写操作通过写时复制机制创建新页面。

7.7 hello进程execve时的内存映射

为hello程序删除已存在的用户区域,创建新的区域结构,代码和初始化数据映射到.text和.data区(目标文件提供),bss和栈堆映射到匿名文件 ,栈堆的初始长度0,共享对象由动态链接映射到本进程共享区域,设置PC,指向代码区域的入口点。

7.8 缺页故障与缺页中断处理

缺页处理程序的主要步骤为:

1.检查虚拟地址是否合法,若不合法,则程序终止。

2.检查进程是否有读写或执行该区域权限,若不具有,则触发异常保护机制,程序终止。

3.内核选择一个牺牲页面,写入磁盘,重新更换新的页面。

4.控制权转移给hello进程,执行触发缺页的指令。

7.9本章小结

本章阐述了计算机中虚拟内存管理,物理地址,线性地址,逻辑地址以及他们的变换模式,段式,页式管理,在内存映射的基础上重新认识了fork和excave。

结论

Hello的历程:

  1. hello.cC语言文本文件的编写
  2. 预处理过程:hello.c预处理为hello.i
  3. 编译:编译器(ccl)将文本文件hello.i(C语言)翻译成文本文件hello.s(汇编语言)。
  4. 汇编:汇编器将hello.s中的汇编语言翻译成计算机能处理的机器指令语言,并输出可重定位文件hello.o(二进制文件)
  5. 链接:将hello中使用的库函数文件与hello.o文件进行连接构成可执行目标文件。
  6. Shell为hello创建进程
  7. Shell运行hello
  8. 运行指令,读取内存,处理信号和异常。
  9. 结束运行,shell回收hello进程。

经过对hello程序在计算机上表演的始末进行了梳理,对于计算机底层实现有了系统的了解。

附件

列出所有的中间产物的文件名,并予以说明起作用。

1.hello.i:cpp预处理原始的.c后缀的C程序。主要是将头文件直接插入程序文本中,并且根据define进行字符串的简单替换,得到新的预处理过的C文本文件。(文本文件)

2.hello.s:编译器将预处理过的以.i为后缀的文件编译成汇编文件。(文本文件)

3.hello.o:汇编器将以.s为后缀的汇编文件转化为机器语言,此时为可重定位目标文件(二进制文件)。

4.hello:利用链接器,将C函数库中相应的函数与hello.o可重定位文件链接,生成可执行目标文件(二进制文件)。

5.tmp.txt:hello.o的用readelf产生的文件。

6.tmp2.txt:hello.o的反汇编文件(逐渐潦草的命名( •̀ ω •́ )y)

7.Tmp3.txt:hello用readelf产生的文件。

参考文献

[1]  林来兴. 空间控制技术[M]. 北京:中国宇航出版社,1992:25-42.

[2]  辛希孟. 信息技术与信息服务国际研讨会论文集:A集[C]. 北京:中国科学出版社,1999.

[3]  赵耀东. 新时代的工业工程师[M/OL]. 台北:天下文化出版社,1998 [1998-09-26]. http://www.ie.nthu.edu.tw/info/ie.newie.htm(Big5).

[4]  谌颖. 空间交会控制理论与方法研究[D]. 哈尔滨:哈尔滨工业大学,1992:8-13.

[5]  KANAMORI H. Shaking Without Quaking[J]. Science,1998,279(5359):2063-2064.

[6]  CHRISTINE M. Plant Physiology: Plant Biology in the Genome Era[J/OL]. Science,1998,281:331-332[1998-09-23]. http://www.sciencemag.org/cgi/ collection/anatmorp.

计统大作业Hello P2P相关推荐

  1. HIT计统大作业:程序人生-hello’s P2P

    .摘 要 本文简要分析了hello这一程序从"出生"到"成人"的过程,并介绍了相应的计算机系统组成成分在其中扮演的角色.主要包括预处理,编译,汇编,链接,进程管 ...

  2. 程序人生-hit计统大作业

    计算机系统 大作业 题 目 程序人生-Hello's P2P 专 业 计算机科学与技术 学 号 120L022012 班 级 2003007 学 生 石瑞琳 指 导 教 师 吴锐 计算机科学与技术学院 ...

  3. 【无标题】计统大作业-hello

    计算机系统 大作业 题     目 程序人生-Hello's P2P 专       业 计算学部 学   号 120L022124 班   级 2003007 学       生 田茂尧 指 导 教 ...

  4. 【Computer Organization笔记15】清华计组大作业布置:奋战二十天,做台计算机!

    本次笔记内容: P29 计算机组成原理(29):第25分钟起 P30 计算机组成原理(30) 我的计组笔记汇总:计算机组成笔记 视频地址:计算机组成原理 清华大学刘卫东 全58讲 国家精品课程 108 ...

  5. 哈工大计算机系统大作业——hello P2P

    计算机系统 大作业 题     目 程序人生-Hello's P2P 专       业 计算学部 学   号 班   级 学       生 指 导 教 师 刘宏伟 计算机科学与技术学院 2021年 ...

  6. 计网大作业--SMTP邮件代理服务器

    软件设计 2.1 数据结构 变量名: S:本机上的socket链接数据结构 s = socket() host.port :本机IP地址和163邮箱端口号 host = "127.0.0.1 ...

  7. 哈工大计组大作业-RISC处理器设计

    RISC_CPU_HIT RISC处理器设计 地址:https://github.com/944613709/Design-of-RISC-Processor.git 要求 根据计算机组成原理课程所学 ...

  8. 哈工大计算机系统大作业——程序人生-Hello’s P2P

    计算机系统 大作业 题          目程序人生-Hello's P2P 专          业 计算机科学与技术 学       号120L022401 班          级 200300 ...

  9. HIT计算机系统大作业-程序人生-Hello’s P2P

    计算机系统大作业 ** 由于采用静态部署,需要看图片详细分析的小伙伴请移步个人博客网站:** 个人博客 题目:程序人生-Hello's P2P 学号: 姓名:熊峰 摘要: hello程序作为最简单的. ...

最新文章

  1. 利用QCustomePlot绘制热力图,瀑布图,频谱色图等
  2. wincc 报警记录 mysql_wincc查询历史报警记录,归档数据-工业支持中心-西门子中国...
  3. Eclipse中快速为类提供构造器、get()、set()方法、重写toString()、hasCode()、equals()等
  4. Spring boot应用如何支持https
  5. linux vbox安装mac os,超简单的linux下virtualbox4.3.26安装配置黑苹果 OSX 10.9的办法
  6. Ubuntu16.04死机解决方案
  7. python与pycharm的作用_JSON 在pycharm 与python 三者有什么关系?JSON有什么作用?
  8. 实用软件工程(吕云翔版)——第一章
  9. mysql官网 源码下载_mysql官网源码包下载
  10. GD32F303修改外部25M晶振
  11. 【NLP】4 gensim word2vec库入门——官方手册embeddings和KeyedVectors
  12. 生物安全实验室送排风设计标准
  13. 电脑里的文件夹被误删了怎么恢复呢?几个步骤轻松解决
  14. git name consists only of disallowed characters
  15. Android获取定位经纬度
  16. 美国孩子上学真像你以为的那么轻松吗?
  17. 再见,搜不准的百度!你好,6个精准搜索技巧(还可以屏蔽广告哦~)
  18. CHECK的简单用法
  19. UWB技术是如何做到室内精准定位的?
  20. 智和信通,部署智慧交通运维系统,构建一站式运维监控平台

热门文章

  1. 阿里云视频点播的使用(SDK调用示例的运行)
  2. unraid应用_unraid 篇三:unraid docker之网页文件管理,强迫症的福音
  3. js设计模式--代理模式
  4. 数字证书与数字签名(图文并茂)详解
  5. 第四章课后习题-用Python实现羊车门问题,最大公约数计算,猜字游戏,统计不同字符个数。
  6. Python爬虫,爬取51job上有关大数据的招聘信息
  7. 【多校训练】2021牛客多校第一场
  8. SAP SD VF01 销售开票增强
  9. 如何将“\”替换为任意字符
  10. PPT2010中,如何让带圈的序号填充背景颜色?