C语言入门(一)——程序的基本概念

news2024/12/24 8:03:41

程序的基本概念

程序和编程语言

自然语言和形式语言

程序的调试

第一个程序


程序的基本概念

程序和编程语言

1.程序

程序(Program )告诉计算机应如何完成一个计算任务,这里的计算可以是数学运算,比如解方 程,也可以是符号运算,比如查找和替换文档中的某个单词。从根本上说,计算机是由数字电路组 成的运算机器,只能对数字做运算,程序之所以能做符号运算,是因为符号在计算机内部也是用数字表示的。此外,程序还可以处理声音和图像,声音和图像在计算机内部必然也是用数字表示的,这些数字经过专门的硬件设备转换成人可以听到、看到的声音和图像。

程序由一系列指令组成, 指令是指示计算机做某种运算的命令,通常包含以下几类:

  • 输入(Input):从键盘,文件或者其他设备获取数据.
  • 输出(Output):把数据显示到屏幕,或者存入一个文件,或者发送到其他设备.
  • 基本运算:执行最基本的数学运算和数据存取.
  • 测试和分支:测试某个条件,然后根据不同的测试结果执行不同的后续指令.
  • 循环:重复执行一系列操作

基本我们用过的任何一个程序,都是由这几类指令组成的,程序是虽然很复杂,但是编写程序能够用到的指令只有这简单的几种,这中间的东西需要我们来填充,所以编写程序就是一件很复杂的工作.

实质就是:把复杂的问题分解为子任务,把子任务再分解成更为简单的任务,层层分解,直到最后简单得可以用上面的指令来完成.

2.编程语言

编程语言( Programming Language )分为低级语言( Low-level Language )和高级语言( High-level Language)。机器语言( Machine Language)和汇编语言(Assembly Language )属于低级语言,直接用计算机指令编写程序。而C C++JavaPython 等属于高级语言,用语句(Statement )编写程序,语句是计算机指令的抽象表示。举个例子,同样一个语句用 C 语言、汇编语言和机器语言分别表示如下:
编程语言表示形式
C语言a=b+1
汇编语言

mov  0x804a01c,%eax

add  $0x1,%eax

mov %eax,0x804a18

机器语言

a1 1c a0 04 08

83 c0 01

a3 18 a0 04 08

 计算机中只能对数字做运算处理,符号,声音等在计算机内部都需要用数组来表示,指令也不例外,上述表中机器语言都是由十六进制数字组成的.最早一批的程序员就是使用机器语言进行编程的,但是是很麻烦的,需要查询大量的表格来确定每个数字代表的意思,编写出来的程序也不是很友好,于是再次基础上有了汇编语言,就是把机器语言中一组一组的数字用助记符表示,直接用这些助记符写出汇编程序,然后让汇编器去查表把助记符替换成数字,也就把汇编语言翻译成了机器语言.从上面的例子可以看出,汇编语言和机器语言的指令是一一对应的,汇编语言有三条指令,机器语言也有三条指令,汇编器就是做一个简单的替换工作,例如在第一条指令中,把mov ?,%eax这种格式的指令替换成机器码a1 ?,?表示一个地址,在汇编指令中是0x804a01c,转换成机器码之后是1c a0 04 08.(小端表示)

从上述例子我们还可以看出来,C语言的语句和低级语言的指令之间并不是简单都得一一对应关系,一语句a=b+1;语句要翻译成三条汇编或者机器指令,这个过程我们称为编译,由编译器来完成,显然编译器的功能比汇编器要复杂的多.用C语言编写的程序必须经过编译转成机器指令才能被计算机指令,编译需要花一些时间,这是用高级语言编译的一个缺点,然而更多的是优点.首先,用C语言编程更容易,写出来的代码更紧凑,可读性更强,出了错也更容易改正.其次,C语言是可移植的或者称为平台无关的.

首先来解释一下平台这个词的意思,可以指的是计算机体系结构,也可以指的是操作系统,也可以指开发平台(编译器,连接器等).不同的计算机体系结构有不同的指令集,可以识别的机器指令格式是不同的,直接用某种体系结构的汇编或机器指令写出来的程序只能在这种体系结构的计算机上运行,然后各种体系结构的计算机都有各自的C编译器,可以把C程序编译成各种不同体系结构的机器指令,这意味着用C语言写的程序只需要稍加修改甚至不用修改就可以在不用的计算机上编译运行.各种高级语言也都是具备C语言的这些优点,所以绝大部分程序都是用高级语言编写的,只有和硬件关系密切的少数程序(例如驱动程序)才会用到低级语言.还要注意一点,即使在相同的体系结构和操作系统下,用不同的C编译器编译同一个程序得到的结果也有可能是不同的,C语言有些语言特性在C标准种并没有明确规定,各编译器有不同的实现方式,编译出来的指令行为特性也会不同,应该尽量避免使用不可移植的语法特性.

总结一下编译执行的过程,首先你用文本编辑器写一个C程序,然后保存成一个文件,例如test.c.这称为源代码或源文件,然后运行编译器对它进行编译,编译的过程并不执行程序,而是把源代码全部翻译成机器指令,再加上一些描述信息,生成一个新的文件,例如a.out,这成为可执行文件,可执行文件可以被操作系统加载运行,计算机执行该文件中由编译器生成的指令.

 有些高级语言以解释(Interpret的方式执行,解释执行过程和C语言的编译执行过程很不一样。

例如编写一个Shell 脚本 script.sh ,内容如下:
#! /bin/sh
VAR=1
VAR=$(($VAR+1))
echo $VAR

 定义Shell变量VAR的初始值是1,然后自增1,然后打印VAR的值。用Shell程序/bin/sh解释执行这个脚本,结果如下:

$ /bin/sh script.sh
2

 这里的/bin/sh称为解释器Interpreter),它把脚本中的每一行当作一条命令解释执行,而不需要

先生成包含机器指令的可执行文件再执行。如果把脚本中的这三行当作三条命令直接敲到 Shell 提示符下,也能得到同样的结果:
$ VAR=1
$ VAR=$(($VAR+1))
$ echo $VAR
2

编程语言仍在发展演化。以上介绍的机器语言称为第一代语言(1GL1st Generation Programming Language),汇编语言称为第二代语言2GL2nd Generation Programming Language),CC++JavaPython等可以称为第三代语言3GL3rdGenerationProgramming Language)。目前已经有了4GL4th Generation Programming Language)和5GL5th Generation Programming Language)的概念。3GL的编程语言虽然是用 语句编程而不直接用指令编程,但语句也分为输入、输出、基本运算、测试分支和循环等几种,和 指令有直接的对应关系。而4GL以后的编程语言更多是描述要做什么(Declarative)而不描述具体 一步一步怎么做(Imperative),具体一步一步怎么做完全由编译器或解释器决定,例如SQL语言 (SQLStructured Query Language,结构化查询语言)就是这样的例子。

问题一: 解释执行的语言相比编译执行的语言有什么优缺点?

 1.主体不同:

编译执行:由编译程序将目标代码一次性编译成目标程序,再由机器运行目标程序

解释执行:将源语言直接作为源程序输入,解释执行解释一句后就提交计算机执行一句,并不形成目标程序。

2.优势不同

编译执行:相比解释执行编译执行效率高,占用资源小,适合复杂程序
解释执行:开发速度快,出现严重BUG的几率小。

3.缺点不同

编译执行:兼容性差,例如在windows平台上写的编译程序一般不可以在unix平台上运行。

解释执行:解析需要时间,不生成目标程序而是一句一句的执行的方式会造成计算机资源的浪费,即执行效率低。

各类语言分类:

  • 编译执行:GO语言、C语言、C++
  • 解释执行:python
  • 半编译半解释型语言:java、C#

自然语言和形式语言

自然语言( Natural Language )就是人类讲的语言,比如汉语、英语和法语。这类语言不是人为设
计(虽然有人试图强加一些规则)而是自然进化的。形式语言( Formal Language )是为了特定应
用而人为设计的语言。例如数学家用的数字和运算符号、化学家用的分子式等。编程语言也是一种
形式语言,是专门设计用来表达计算过程的形式语言。
形式语言有严格的语法( Syntax )规则,例如, 3+3=6 是一个语法正确的数学等式,而 3=+6$ 则不
是, H 2 O 是一个正确的分子式,而 2 Zz 则不是。语法规则是由符号( Token )和结构(Structure)的规则所组成的。Token的概念相当于自然语言中的单词和标点、数学式中的数和运 算符、化学分子式中的元素名和数字,例如3=+6$ 的问题之一在于 $ 不是一个合法的数也不是一个 事先定义好的运算符,而2 Zz 的问题之一在于没有一种元素的缩写是 Zz 。结构是指 Token 的排列方式,3=+6$ 还有一个结构上的错误,虽然加号和等号都是合法的运算符,但是不能在等号之后紧跟加号,而2 Zz 的另一个问题在于分子式中必须把下标写在化学元素名称之后而不是前面。关于Token 的规则称为词法( Lexical )规则,而关于结构的规则称为语法( Grammar )规则.
当阅读一个自然语言的句子或者一种形式语言的语句时,你不仅要搞清楚每个词( Token )是什么
意思,而且必须搞清楚整个句子的结构是什么样的(在自然语言中你只是没有意识到,但确实这样
做了,尤其是在读外语时你肯定也意识到了)。这个分析句子结构的过程称为解析( Parse )。例
如,当你听到 “The other shoe fell.” 这个句子时,你理解 the other shoe 是主语而 fell 是谓语动词,一
旦解析完成,你就搞懂了句子的意思,如果知道 shoe 是什么东西, fall 意味着什么,这句话是在什
么上下文( Context )中说的,你还能理解这个句子主要暗示的内容,这些都属于语(Semantic )的范畴。
虽然形式语言和自然语言有很多共同之处,包括 Token 、结构和语义,但是也有很多不一样的地
方。
现在给出一些关于阅读程序(包括其它形式语言)的建议。首先请记住形式语言远比自然语言紧
凑,所以要多花点时间来读。其次,结构很重要,从上到下从左到右读往往不是一个好办法,而应
该学会在大脑里解析:识别 Token ,分解结构。最后,请记住细节的影响,诸如拼写错误和标点错
误这些在自然语言中可以忽略的小毛病会把形式语言搞得面目全非。

程序的调试

编程是一件复杂的工作,因为是人做的事情,所以难免经常出错。据说有这样一个典故:早期的计
算机体积都很大,有一次一台计算机不能正常工作,工程师们找了半天原因最后发现是一只臭虫钻
进计算机中造成的。从此以后,程序中的错误被叫做臭虫( Bug ),而找到这些 Bug 并加以纠正的
过程就叫做调试( Debug )。有时候调试是一件非常复杂的工作,要求程序员概念明确、逻辑清
晰、性格沉稳,还需要一点运气。调试的技能我们在后续的学习中慢慢培养,但首先我们要区分清
楚程序中的 Bug 分为哪几类。
  • 编译时错误:
    编译器只能翻译语法正确的程序,否则将导致编译失败,无法生成可执行文件。对于自然语
    言来说,一点语法错误不是很严重的问题,因为我们仍然可以读懂句子。而编译器就没那么
    宽容了,只要有哪怕一个很小的语法错误,编译器就会输出一条错误提示信息然后罢工,你
    就得不到你想要的结果。虽然大部分情况下编译器给出的错误提示信息就是你出错的代码
    行,但也有个别时候编译器给出的错误提示信息帮助不大,甚至会误导你。在开始学习编程
    的前几个星期,你可能会花大量的时间来纠正语法错误。等到有了一些经验之后,还是会犯
    这样的错误,不过会少得多,而且你能更快地发现错误原因。等到经验更丰富之后你就会觉
    得,语法错误是最简单最低级的错误,编译器的错误提示也就那么几种,即使错误提示是有
    误导的也能够立刻找出真正的错误原因是什么。相比下面两种错误,语法错误解决起来要容
    易得多
  • 运行时错误
    编译器检查不出这类错误,仍然可以生成可执行文件,但在运行时会出错而导致程序崩溃。
    对于我们接下来的几章将编写的简单程序来说,运行时错误很少见,到了后面的章节你会遇
    到越来越多的运行时错误。读者在以后的学习中要时刻注意区分编译时和运行时( Run-
    time )这两个概念,不仅在调试时需要区分这两个概念,在学习 C 语言的很多语法时都需要区
    分这两个概念,有些事情在编译时做,有些事情则在运行时做。
  • 逻辑错误和语义错误
    第三类错误是逻辑错误和语义错误。如果程序里有逻辑错误,编译和运行都会很顺利,看上
    去也不产生任何错误信息,但是程序没有干它该干的事情,而是干了别的事情。当然不管怎
    么样,计算机只会按你写的程序去做,问题在于你写的程序不是你真正想要的,这意味着程
    序的意思(即语义)是错的。找到逻辑错误在哪需要十分清醒的头脑,要通过观察程序的输
    出回过头来判断它到底在做什么。

第一个程序

通常一本教编程的书中第一个例子都是打印 “Hello, World.” C 语言写这个程序可以这样写:
#include <stdio.h>
/* main: generate some simple output */
int main(void)
{
 printf("Hello, world.\n");
 return 0;
}
将这个程序保存成 main.c ,然后编译执行
$ gcc main.c
$ ./a.out
Hello, world.

gcc Linux 平台的 C 编译器,编译后在当前目录下生成可执行文件 a.out ,直接在命令行输入这个可
执行文件的路径就可以执行它。如果不想把文件名叫 a.out ,可以用 gcc -o 参数自己指定文件名:
虽然这只是一个很小的程序,但我们目前暂时还不具备相关的知识来完全理解这个程序,比如程序
的第一行,还有程序主体的 int main(void){...return 0;} 结构,这些部分我们暂时不详细解释,
读者现在只需要把它们看成是每个程序按惯例必须要写的部分( Boilerplate )。但要注意 main 是一
个特殊的名字, C程序总是从main 里面的第一条语句开始执行的,在这个程序中是指 printf 这条语
句.
3 行的 /* ... */ 结构是一个注释( Comment ),其中可以写一些描述性的话,解释这段程序在
做什么。注释只是写给程序员看的,编译器会忽略从 /* */ 的所有字符,所以写注释没有语法规
则,爱怎么写就怎么写,并且不管写多少都不会被编译进可执行文件中。
printf 语句的作用是把消息打印到屏幕。注意语句的末尾以 ; 号( Semicolon )结束,下一条语
return 0; 也是如此。
C 语言用 {} 括号( Brace Curly Brace )把语法结构分成组,在上面的程序中 printf return 语句套
main {} 括号中,表示它们属于 main 的定义之中。我们看到这两句相比 main 那一行都缩进
Indent )了一些,在代码中可以用若干个空格( Blank )和 Tab 字符来缩进,缩进不是必须的,但
这样使我们更容易看出这两行是属于 main 的定义之中的,要写出漂亮的程序必须有整齐的缩进.
正如前面所说,编译器对于语法错误是毫不留情的,如果你的程序有一点拼写错误,例如第一行写
成了 stdoi.h ,在编译时会得到错误提示:
$ gcc main.c
main.c:1:19: error: stdoi.h: No such file or directory
这个错误提示非常紧凑,初学者往往不容易看明白出了什么错误,即使知道这个错误提示说的是
1 行有错误,很多初学者对照着书看好几遍也看不出自己这一行哪里有错误,因为他们对符号和
拼写不敏感(尤其是英文较差的初学者),他们还不知道这些符号是什么意思又如何能记住正确的
拼写?对于初学者来说,最想看到的错误提示其实是这样的: main.c 程序第 1 行的第 19 列,您试
图包含一个叫做 stdoi.h 的文件,可惜我没有找到这个文件,但我却找到了一个叫做 stdio.h 的文
件,我猜这个才是您想要的,对吗? 可惜没有任何编译器会友善到这个程度,大多数时候你所得
到的错误提示并不能直接指出谁是犯人,而只是一个线索,你需要根据这个线索做一些侦探和推
理。
有些时候编译器的提示信息不是 error 而是 warning ,例如把上例中的 printf("Hello, world.\n");改成 printf(1); 然后编译运行:
$ gcc main.c
main.c: In function ‘main’:
main.c:7: warning: passing argument 1 of ‘printf’ makes pointer from
integer without a cast
$ ./a.out 
Segmentation fault
这个警告信息是说类型不匹配,但勉强还能配得上。警告信息不是致命错误,编译仍然可以继续,
如果整个编译过程只有警告信息而没有错误信息,仍然可以生成可执行文件。但是,警告信息也是
不容忽视的。出警告信息说明你的程序写得不够规范,可能有 Bug ,虽然能编译生成可执行文件,
但程序的运行结果往往是不正确的,例如上面的程序运行时出了一个段错误,这属于运行时错误。
各种警告信息的严重程度不同,像上面这种警告几乎一定表明程序中有 Bug ,而另外一些警告只表
明程序写得不够规范,一般还是能正确运行的,有些不重要的警告信息 gcc 默认是不提示的,但这
些警告信息也有可能表明程序中有 Bug 。一个好的习惯是打开 gcc -Wall 选项,也就是让 gcc 提示所
有的警告信息,不管是严重的还是不严重的,然后把这些问题从代码中全部消灭。
比如把上例中的printf("Hello, world.\n"); 改成 printf(0); 然后编译运行:
$ gcc main.c
$ ./a.out
编译既不报错也不报警告,一切正常,但是运行程序什么也不打印。如果打开 -Wall 选项编译就会
报警告了
$ gcc -Wall main.c
main.c: In function ‘main’:
main.c:7: warning: null argument where non-null required (argument 
1)
如果 printf 中的 0 是你不小心写上去的(例如错误地使用了编辑器的查找替换功能),这个警告就
能帮助你发现错误。虽然本书的命令行为了突出重点通常省略 -Wall 选项,但是强烈建议你写每一
个编译命令时都加上 -Wall 选项。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/78258.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Centos7下安装PostgreSQL14及其基本命令使用

MySQL关系型数据库目前算是互联网公司使用最多的。前两天看到一个推文&#xff0c;相对比国内使用MySQL&#xff0c;PostgreSQL在国内的普及貌似不高&#xff1f;国外像网络电话公司Skype公司等在大量使用PostgreSQL 作为互联网从业者&#xff0c;保持学习是必须的。开始学习Po…

小甲鱼C语言【课后笔记第一章——打印(printf)

目录 1、“打印”就是“输出”的意思 2、使用 GCC 编译程序&#xff1a;gcc 源代码 -o 可执行文件。 3、printf 是格式化输出函数 a、函数概要 b、函数原型 c、参数分析 d、返回值 e、演示 4. 转义字符 5. 反斜杠的奥义 6、课后习题&#xff08;编程题&#xff09; 1、…

性能工具之JMeter模拟多IP地址访问

文章目录一、前言二、前置条件三、操作步骤一、前言 今天一同事在压测时提到怎么用 JMeter 里虚拟多个 IP 来发送请求&#xff0c;我想了一下以前用LR时用过虚拟ip地址&#xff0c;JMeter 还没有使用过。想着原理应该是相通的&#xff0c;既然 LR 都能支持的话&#xff0c;那 …

多线程学习笔记(四)-- 常见类及使用

1. thread的方法 Thread.sleep()&#xff1a;占用cpu资源 Thread.yeild()&#xff1a;当前线程让渡cpu资源&#xff0c;大家竞争&#xff0c;也有再抢到cpu的机会 t1.join()&#xff1a;在t2线程中&#xff0c;调用t1.join()&#xff0c;是等待t1执行完成 2. 线程状态 3. sy…

力扣(LeetCode)142. 环形链表 II(C++)

哈希表 最直观的思想&#xff0c;哈希表记录遍历的结点&#xff0c;如果结点重复出现&#xff0c;则有环。如果遍历到空结点&#xff0c;无环。 class Solution { public:ListNode *detectCycle(ListNode *head) {unordered_set<ListNode *> ad;auto tail head;while(…

java计算机毕业设计ssm医患交流平台93xzr(附源码、数据库)

java计算机毕业设计ssm医患交流平台93xzr&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。…

用Excel自带图表插入带分类变量的箱形图(单坐标轴并列箱)

箱型图主要用来观察一个或多个类别下&#xff0c;数值型变量的分位数及离群值的特征和分布&#xff0c;以及在一定程度上观察到偏度和峰度的状态。网上有一些自己计算分位数来绘制箱型图的方法&#xff0c;但一方面是没有直接使用excel自带的箱型图好看和功能全面&#xff0c;二…

qq群聊机器人接入ChatGPT-简介和源码

qq群聊机器人接入ChatGPT 最近 ChatGPT 很火&#xff0c;也注册了账号玩了玩&#xff0c;确实灰常强大。但是也有的小伙伴可能没办法注册账号&#xff0c;我就想着把qq群机器人接入ChatGPT。 过程还是比较简单顺利的。下面简单介绍一下 直接跳过介绍&#xff0c;查项目代码 1…

绘制金字塔-第10届蓝桥杯Scratch选拔赛真题精选

[导读]&#xff1a;超平老师计划推出Scratch蓝桥杯真题解析100讲&#xff0c;这是超平老师解读Scratch蓝桥真题系列的第100讲。 蓝桥杯选拔赛每一届都要举行4~5次&#xff0c;和省赛、国赛相比&#xff0c;题目要简单不少&#xff0c;再加上篇幅有限&#xff0c;因此我精挑细选…

基于java(springboot)校园新闻管理系统源码(java毕业设计)

基于java(springboot)校园新闻管理系统 校园新闻管理系统是基于java编程语言&#xff0c;MySQL数据库&#xff0c;和springboot框架&#xff0c;用idea开发工具开发的设计&#xff0c;本设计分为学生用户&#xff0c;管理员两个角色&#xff0c; 学生的主要功能是可以注册登陆…

Cpolar实现虚拟机内网穿透,搭建私人云服务器

Cpolar实现虚拟机内网穿透,搭建私人云服务器 一、Cpolar功能介绍 Cpolar官网 Cpolar是一个安全的内网穿透的服务&#xff0c;可以将内网下的本地服务器通过安全隧道暴漏给公网。允许公网用户可以正常访问内网服务&#xff0c;是一款免费的内网穿透软件。只需要一行命令&#…

Python小炼(1):初识Python

"也许对我来说&#xff0c;太多拘束可能" 本篇的主要内容,针对的是一些常见的语法&#xff0c;在python中是怎样表示的&#xff0c;例如,python变量如何定义、选择、循环、判断结构是如何表示的&#xff1f;python函 数定义是怎么定义的…… ----前言 一、认识pyt…

无需代理及注册在VsCode中使用ChatGPT

无需代理及注册在VsCode中使用ChatGPT 安装 要安装扩展&#xff0c;请按照下列步骤操作&#xff1a; 1.打开 Visual Studio Code 2.单击左侧栏中的扩展程序图标 3.搜索"ChatGPT中文版" 4.点击安装按钮安装扩展 5.重启VSCode 用法 开始使用 在编辑器中右键触发…

【LeetCode每日一题:1691. 堆叠长方体的最大高度~~~排序+贪心】

题目描述 给你 n 个长方体 cuboids &#xff0c;其中第 i 个长方体的长宽高表示为 cuboids[i] [widthi, lengthi, heighti]&#xff08;下标从 0 开始&#xff09;。请你从 cuboids 选出一个 子集 &#xff0c;并将它们堆叠起来。 如果 widthi < widthj 且 lengthi < …

Java学习笔记6.3.3 文件操作 - 对象序列化与反序列化

文章目录零、本讲学习目标一、对象序列化与反序列化&#xff08;一&#xff09;对象序列化与反序列化概念&#xff08;二&#xff09;对象序列化与反序列化示意图&#xff08;三&#xff09;实际开发中序列化和反序列化的场景&#xff08;四&#xff09;实现对象序列化的两种方…

26岁,干了三年测试,月薪才12k,能跳槽找到一个更高薪资的工作吗?

在我们的身边&#xff0c;存在一个普遍现象&#xff1a;很多人从事软件测试岗&#xff0c;不计其数&#xff0c;经历的心酸难与外人道也。可是技术确难以提升、止步不前&#xff0c;薪资也只能看着别人水涨船高&#xff0c;自己却没有什么起色。 虽然在公司里属于不可缺少的一…

计算机网络:数据链路层

数据链路层 数据链路层主要处理单个链路上如何传输数据&#xff0c;并且向网络层向上提供服务 1. 数据链路层概述 1.1 术语介绍 主机拥有全部的计算机网络结构&#xff0c;路由器只有一部分 各个路由器之间由物理层连接 红线为发送的信息 1.2 数据链路层的三个重要问题 封装…

职业危机:从无到有,从弱到强;反思再反思和应对措施

一、写在开头 每天每周不写点东西&#xff0c;不把脑中的疑惑写明白&#xff0c;就感觉不到每天的进步。 每天没进步&#xff0c;这北漂生活&#xff0c;何时是个头啊。 可以北漂10年&#xff0c;也可以20年&#xff0c;但不可能是一辈子。 因为我不是北京人呐。 二、持续转…

Redis的字符串是怎么实现的

本篇会讲以下内容&#xff1a; Redis字符串的实现 Redis字符串的性能优势 Redis字符串的实现 Redis虽然是用C语言写的&#xff0c;但却没有直接用C语言的字符串&#xff0c;而是自己实现了一套字符串。目的就是为了提升速度&#xff0c;提升性能&#xff0c;可以看出Redis为…

Nacos的服务注册之客户端

服务注册到Nacos以后,会保存在一个本地注册表中,这个注册表是一个map. private Map<String, Map<String, Service>> serviceMap new ConcurrentHashMap<>(); key是namespace,用来隔离环境 value又是一个map      key是group      value又是一个s…