From c37976f0b633f1dafdc26ec9f459a8dfcea9d11a Mon Sep 17 00:00:00 2001 From: suyuan32 <1137661202@qq.com> Date: Fri, 16 Feb 2024 03:43:21 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20suyuan32?= =?UTF-8?q?/GoGuide@f4502ee1ad471a79f6e9505274584a2113b9331c=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 404.html | 6 +++--- ...tml-DbR7Ocm4.js => 1-basic.html-BieaWbc7.js} | 2 +- ...tml-Oj5lYJbp.js => 1-basic.html-D5nncuCC.js} | 2 +- ...my6.js => 1-database-basic.html-CfhjjJrP.js} | 4 ++-- ...61A.js => 1-database-basic.html-DzAKcAVh.js} | 4 ++-- ...-Bu_vfCri.js => 1-keywords.html--Q_8y9NZ.js} | 2 +- ...-Cb_-qdNV.js => 1-keywords.html-D8qOdfzt.js} | 2 +- ...l-C_EZgcM6.js => 1-network.html-BUDov-jI.js} | 2 +- ...l-V2ivHazx.js => 1-network.html-Blr4KIdV.js} | 2 +- ...-B4Zluvs9.js => 2-datatype.html-BBe-LqVn.js} | 2 +- ...-Bhx9jV3s.js => 2-datatype.html-CPzWcUi9.js} | 2 +- ...ml-EVBDDzD_.js => 2-medium.html-C1NwI0Ox.js} | 2 +- ...ml-CUT2Gn3u.js => 2-medium.html-cqpOA0o-.js} | 2 +- assets/2-tcp-udp.html-BABQQ_zo.js | 1 + assets/2-tcp-udp.html-BbAGUlCW.js | 1 - assets/2-tcp-udp.html-D4XJmffI.js | 1 - assets/2-tcp-udp.html-IZeSrbLS.js | 1 + ...-DcFs0BUM.js => 3-operator.html-BwDwjYWH.js} | 2 +- ...-BWtKH6YH.js => 3-operator.html-C8kTpa_2.js} | 2 +- ...Ud58.js => 4-errorhandling.html-DNHfljPB.js} | 2 +- ...CtwI.js => 4-errorhandling.html-E6HmUyLW.js} | 2 +- ...04.html-B3jmriWY.js => 404.html-DPAHxMnN.js} | 2 +- ....html-DJfb0ND7.js => 5-map.html-CaKde_jH.js} | 2 +- ....html-BucnXcKM.js => 5-map.html-coD4WfmK.js} | 2 +- ...tml-JMIMK1-9.js => 6-slice.html-D0sTuz-d.js} | 2 +- ...tml-CTtneWZ6.js => 6-slice.html-DxG6N77X.js} | 2 +- ...l-6gWgcYt9.js => 7-channel.html-DWDDXmkq.js} | 2 +- ...l-CQe5Eha5.js => 7-channel.html-DcY0VHb2.js} | 2 +- ...l-Ckq0jHxV.js => 8-context.html-B9nsgQ4v.js} | 2 +- ...l-DI8Yqf21.js => 8-context.html-BURlTMoP.js} | 2 +- ...ult-BDxOW_ov.js => SearchResult-Q8xgYrff.js} | 2 +- assets/{app-Bsw6rBWV.js => app-C0BAr50I.js} | 6 +++--- assets/image/article/network/udp.png | Bin 0 -> 52497 bytes assets/image/article/network/udp_en.png | Bin 0 -> 49050 bytes ....html-TKkSvLzY.js => index.html-1Nx2oT3r.js} | 2 +- ....html-q-4AM6qQ.js => index.html-1Y6NdWAO.js} | 2 +- ....html-DBpVKrL9.js => index.html-2GK5VV8e.js} | 2 +- ....html-ChX_4YQ3.js => index.html-5Kj3Bkky.js} | 2 +- ....html-BQR5-7-D.js => index.html-B-auqxUp.js} | 2 +- ....html-T2UIAV4q.js => index.html-B47cmPYZ.js} | 2 +- ....html-CV8s24FG.js => index.html-BIAHWB1B.js} | 2 +- ....html-DZQMWWHK.js => index.html-BlVsVRN4.js} | 2 +- ....html-DZ6fXLsW.js => index.html-Bz9RForh.js} | 2 +- ....html-zgvkyyEG.js => index.html-BzPKbSiO.js} | 2 +- ....html-BAWnyXuw.js => index.html-CCIUmYMw.js} | 2 +- ....html-BZ6P1cG5.js => index.html-CeroSw2z.js} | 2 +- ....html-CsL29kfO.js => index.html-CtCM_MAH.js} | 2 +- ....html-nkEwrf4M.js => index.html-CxLVFEy9.js} | 2 +- ....html-D8cXLzPU.js => index.html-DAz-Ra5W.js} | 2 +- ....html-DceXrgJn.js => index.html-DEnQWnwC.js} | 2 +- ....html-CvRlnlxH.js => index.html-Drh9TwcQ.js} | 2 +- ....html-jsKKBcg2.js => index.html-ckgkylJ7.js} | 2 +- .../concepts/database/1-database-basic.html | 8 ++++---- en/guide/concepts/database/index.html | 6 +++--- en/guide/concepts/golang/1-keywords.html | 4 ++-- en/guide/concepts/golang/2-datatype.html | 4 ++-- en/guide/concepts/golang/3-operator.html | 4 ++-- en/guide/concepts/golang/4-errorhandling.html | 4 ++-- en/guide/concepts/golang/5-map.html | 4 ++-- en/guide/concepts/golang/6-slice.html | 4 ++-- en/guide/concepts/golang/7-channel.html | 4 ++-- en/guide/concepts/golang/8-context.html | 4 ++-- en/guide/concepts/golang/index.html | 4 ++-- en/guide/concepts/index.html | 6 +++--- en/guide/concepts/network/1-network.html | 8 ++++---- en/guide/concepts/network/2-tcp-udp.html | 8 ++++---- en/guide/concepts/network/index.html | 6 +++--- en/guide/index.html | 4 ++-- en/guide/interview/golang/basic/1-basic.html | 4 ++-- en/guide/interview/golang/basic/2-medium.html | 4 ++-- en/guide/interview/golang/basic/index.html | 4 ++-- en/guide/interview/golang/index.html | 4 ++-- en/guide/interview/index.html | 4 ++-- en/index.html | 4 ++-- guide/concepts/database/1-database-basic.html | 8 ++++---- guide/concepts/database/index.html | 6 +++--- guide/concepts/golang/1-keywords.html | 4 ++-- guide/concepts/golang/2-datatype.html | 4 ++-- guide/concepts/golang/3-operator.html | 4 ++-- guide/concepts/golang/4-errorhandling.html | 4 ++-- guide/concepts/golang/5-map.html | 4 ++-- guide/concepts/golang/6-slice.html | 4 ++-- guide/concepts/golang/7-channel.html | 4 ++-- guide/concepts/golang/8-context.html | 4 ++-- guide/concepts/golang/index.html | 4 ++-- guide/concepts/index.html | 6 +++--- guide/concepts/network/1-network.html | 8 ++++---- guide/concepts/network/2-tcp-udp.html | 8 ++++---- guide/concepts/network/index.html | 6 +++--- guide/index.html | 4 ++-- guide/interview/golang/basic/1-basic.html | 4 ++-- guide/interview/golang/basic/2-medium.html | 4 ++-- guide/interview/golang/basic/index.html | 4 ++-- guide/interview/golang/index.html | 4 ++-- guide/interview/index.html | 4 ++-- index.html | 4 ++-- search-pro.worker.js | 2 +- sitemap.xml | 2 +- 98 files changed, 162 insertions(+), 162 deletions(-) rename assets/{1-basic.html-DbR7Ocm4.js => 1-basic.html-BieaWbc7.js} (99%) rename assets/{1-basic.html-Oj5lYJbp.js => 1-basic.html-D5nncuCC.js} (99%) rename assets/{1-database-basic.html-BXLjRmy6.js => 1-database-basic.html-CfhjjJrP.js} (76%) rename assets/{1-database-basic.html-BrHVm61A.js => 1-database-basic.html-DzAKcAVh.js} (77%) rename assets/{1-keywords.html-Bu_vfCri.js => 1-keywords.html--Q_8y9NZ.js} (99%) rename assets/{1-keywords.html-Cb_-qdNV.js => 1-keywords.html-D8qOdfzt.js} (99%) rename assets/{1-network.html-C_EZgcM6.js => 1-network.html-BUDov-jI.js} (79%) rename assets/{1-network.html-V2ivHazx.js => 1-network.html-Blr4KIdV.js} (77%) rename assets/{2-datatype.html-B4Zluvs9.js => 2-datatype.html-BBe-LqVn.js} (99%) rename assets/{2-datatype.html-Bhx9jV3s.js => 2-datatype.html-CPzWcUi9.js} (99%) rename assets/{2-medium.html-EVBDDzD_.js => 2-medium.html-C1NwI0Ox.js} (99%) rename assets/{2-medium.html-CUT2Gn3u.js => 2-medium.html-cqpOA0o-.js} (98%) create mode 100644 assets/2-tcp-udp.html-BABQQ_zo.js delete mode 100644 assets/2-tcp-udp.html-BbAGUlCW.js delete mode 100644 assets/2-tcp-udp.html-D4XJmffI.js create mode 100644 assets/2-tcp-udp.html-IZeSrbLS.js rename assets/{3-operator.html-DcFs0BUM.js => 3-operator.html-BwDwjYWH.js} (99%) rename assets/{3-operator.html-BWtKH6YH.js => 3-operator.html-C8kTpa_2.js} (99%) rename assets/{4-errorhandling.html-Cq7NUd58.js => 4-errorhandling.html-DNHfljPB.js} (99%) rename assets/{4-errorhandling.html-CZWtCtwI.js => 4-errorhandling.html-E6HmUyLW.js} (99%) rename assets/{404.html-B3jmriWY.js => 404.html-DPAHxMnN.js} (94%) rename assets/{5-map.html-DJfb0ND7.js => 5-map.html-CaKde_jH.js} (99%) rename assets/{5-map.html-BucnXcKM.js => 5-map.html-coD4WfmK.js} (99%) rename assets/{6-slice.html-JMIMK1-9.js => 6-slice.html-D0sTuz-d.js} (99%) rename assets/{6-slice.html-CTtneWZ6.js => 6-slice.html-DxG6N77X.js} (99%) rename assets/{7-channel.html-6gWgcYt9.js => 7-channel.html-DWDDXmkq.js} (99%) rename assets/{7-channel.html-CQe5Eha5.js => 7-channel.html-DcY0VHb2.js} (99%) rename assets/{8-context.html-Ckq0jHxV.js => 8-context.html-B9nsgQ4v.js} (99%) rename assets/{8-context.html-DI8Yqf21.js => 8-context.html-BURlTMoP.js} (99%) rename assets/{SearchResult-BDxOW_ov.js => SearchResult-Q8xgYrff.js} (98%) rename assets/{app-Bsw6rBWV.js => app-C0BAr50I.js} (96%) create mode 100644 assets/image/article/network/udp.png create mode 100644 assets/image/article/network/udp_en.png rename assets/{index.html-TKkSvLzY.js => index.html-1Nx2oT3r.js} (94%) rename assets/{index.html-q-4AM6qQ.js => index.html-1Y6NdWAO.js} (94%) rename assets/{index.html-DBpVKrL9.js => index.html-2GK5VV8e.js} (94%) rename assets/{index.html-ChX_4YQ3.js => index.html-5Kj3Bkky.js} (97%) rename assets/{index.html-BQR5-7-D.js => index.html-B-auqxUp.js} (94%) rename assets/{index.html-T2UIAV4q.js => index.html-B47cmPYZ.js} (94%) rename assets/{index.html-CV8s24FG.js => index.html-BIAHWB1B.js} (94%) rename assets/{index.html-DZQMWWHK.js => index.html-BlVsVRN4.js} (97%) rename assets/{index.html-DZ6fXLsW.js => index.html-Bz9RForh.js} (94%) rename assets/{index.html-zgvkyyEG.js => index.html-BzPKbSiO.js} (94%) rename assets/{index.html-BAWnyXuw.js => index.html-CCIUmYMw.js} (94%) rename assets/{index.html-BZ6P1cG5.js => index.html-CeroSw2z.js} (94%) rename assets/{index.html-CsL29kfO.js => index.html-CtCM_MAH.js} (94%) rename assets/{index.html-nkEwrf4M.js => index.html-CxLVFEy9.js} (97%) rename assets/{index.html-D8cXLzPU.js => index.html-DAz-Ra5W.js} (94%) rename assets/{index.html-DceXrgJn.js => index.html-DEnQWnwC.js} (94%) rename assets/{index.html-CvRlnlxH.js => index.html-Drh9TwcQ.js} (94%) rename assets/{index.html-jsKKBcg2.js => index.html-ckgkylJ7.js} (96%) diff --git a/404.html b/404.html index 579db17f..36dc7020 100644 --- a/404.html +++ b/404.html @@ -30,11 +30,11 @@ Go 面试宝典 - + -
跳至主要內容

404

页面不存在

这 是 四 零 四 !

- +
跳至主要內容

404

页面不存在

这里什么也没有

+ diff --git a/assets/1-basic.html-DbR7Ocm4.js b/assets/1-basic.html-BieaWbc7.js similarity index 99% rename from assets/1-basic.html-DbR7Ocm4.js rename to assets/1-basic.html-BieaWbc7.js index 4633f24c..ba102a0b 100644 --- a/assets/1-basic.html-DbR7Ocm4.js +++ b/assets/1-basic.html-BieaWbc7.js @@ -1,4 +1,4 @@ -import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as s,b as e}from"./app-Bsw6rBWV.js";const t={},i=e(`

Pointer

What is a pointer and a pointer variable?

Answer

Ordinary variables store data, while pointer variables store the address of the data.

// Define an ordinary variable and print it
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as s,b as e}from"./app-C0BAr50I.js";const t={},i=e(`

Pointer

What is a pointer and a pointer variable?

Answer

Ordinary variables store data, while pointer variables store the address of the data.

  • Learning about pointers mainly involves two operators & and *.

  • &: Address operator, used to get the address from a variable

// Define an ordinary variable and print it
 num := 99
 fmt.Println(num) //output: 99
 
diff --git a/assets/1-basic.html-Oj5lYJbp.js b/assets/1-basic.html-D5nncuCC.js
similarity index 99%
rename from assets/1-basic.html-Oj5lYJbp.js
rename to assets/1-basic.html-D5nncuCC.js
index 16c344f8..c9a03ad3 100644
--- a/assets/1-basic.html-Oj5lYJbp.js
+++ b/assets/1-basic.html-D5nncuCC.js
@@ -1,4 +1,4 @@
-import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,b as e}from"./app-Bsw6rBWV.js";const t={},p=e(`

指针

什么是指针和指针变量?

答案

普通变量存储数据,而指针变量存储的是数据的地址。

  • 学习指针,主要有两个运算符号&*
    1. &:地址运算符,从变量中取地址
    2. *:引用运算符,取地址中数据
num := 99
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,b as e}from"./app-C0BAr50I.js";const t={},p=e(`

指针

什么是指针和指针变量?

答案

普通变量存储数据,而指针变量存储的是数据的地址。

  • 学习指针,主要有两个运算符号&*
    1. &:地址运算符,从变量中取地址
    2. *:引用运算符,取地址中数据
num := 99
 fmt.Println(num) //输出: 99
 
 ptr := &num
diff --git a/assets/1-database-basic.html-BXLjRmy6.js b/assets/1-database-basic.html-CfhjjJrP.js
similarity index 76%
rename from assets/1-database-basic.html-BXLjRmy6.js
rename to assets/1-database-basic.html-CfhjjJrP.js
index 67975e34..b07079a9 100644
--- a/assets/1-database-basic.html-BXLjRmy6.js
+++ b/assets/1-database-basic.html-CfhjjJrP.js
@@ -1,4 +1,4 @@
-import{_ as t}from"./sql-join-Bp3AkZJ8.js";import{_ as d}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as e,c as n,b as a}from"./app-Bsw6rBWV.js";const s={},r=a('

关系键

关系键用于标识数据表中的每一行或者标识与其他表的关系

关系键介绍
主键 (Primary key - Unique key)主键是数据列中用来唯一标识的字段,不允许为空,一个表只能有一个主键
超键 (Super key)超键是能唯一标识数据列的所有属性集, 即若任意单个或多个字段如果也能唯一标识数据列,则都属于超键
候选键 (Candidate key)候选键是超键的子集,候选键是不包含多余字段的超键,候选键中删除任意字段都不属于超键
外键 (Foreign key)外键用于建立表之间的关系,如 A 表的主键是 B 表的字段,这时候 B 表中的 A 表的主键字段就是外键

注意

主键和唯一键的区别:

  • 一张表只能有一个主键,可以有多个唯一键
  • 主键不能为空,唯一键可以为空
例子

假设有两张表

studentteacher
idid
namename
ageage
identify_card (身份证号)
teacher_id
  • 主键: student.id teacher.id
  • 超键: 以 student 表为例: (student.id, student.name),(student.id, student.name, student.age) ... 任何和主键和身份证的组合都为超键
  • 候选键: 以 student 表为例: student.id student.identify_card
  • 外键: student.teacher_id

表连接

要学习表连接,首先要了解笛卡尔积

笛卡尔积

笛卡尔积(Cartesian product)指的是两个集合 X, Y 中 X 的所有元素分别乘以 Y 中所有元素的集合,又称为直积

例如 X={a,b} Y={1,2} 则 X 和 Y 的笛卡尔积为

Z={(a,1),(a,2),(b,1),(b,2)}

表连接是通过条件对两表之间的笛卡尔积进行筛选后的结果

表连接示意图

sql-join
sql-join

示例表

示例表

接下来的查询都是围绕该示例表

course

idtitle
1Math
2Art
3Music
4Geography
15Sport

student

idnameagecourse_id
1Elaine Morris123
2Beverly Turner114
3Connie Murphy112
4Jamie Romero125
5Clifford Reyes101
6Francisco Cook122
7Alan Sanchez119
8Tony Garcia123
9Bobby Burns128
10Glenn Adams115
11Glenn Griffin124
12Justin Rogers138

注意

一般我们称第一个表为驱动表,第二个表为被驱动表,在例子中 student驱动表course被驱动表

内连接 (inner Join)

内连接 inner join 等同于 join, 用于只返回匹配的行。

以下三种写法相同

select * from a,b;
+import{_ as t}from"./sql-join-Bp3AkZJ8.js";import{_ as d}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as e,c as n,b as a}from"./app-C0BAr50I.js";const s={},r=a('

关系键

关系键用于标识数据表中的每一行或者标识与其他表的关系

关系键介绍
主键 (Primary key - Unique key)主键是数据列中用来唯一标识的字段,不允许为空,一个表只能有一个主键
超键 (Super key)超键是能唯一标识数据列的所有属性集, 即若任意单个或多个字段如果也能唯一标识数据列,则都属于超键
候选键 (Candidate key)候选键是超键的子集,候选键是不包含多余字段的超键,候选键中删除任意字段都不属于超键
外键 (Foreign key)外键用于建立表之间的关系,如 A 表的主键是 B 表的字段,这时候 B 表中的 A 表的主键字段就是外键

注意

主键和唯一键的区别:

  • 一张表只能有一个主键,可以有多个唯一键
  • 主键不能为空,唯一键可以为空
例子

假设有两张表

studentteacher
idid
namename
ageage
identify_card (身份证号)
teacher_id
  • 主键: student.id teacher.id
  • 超键: 以 student 表为例: (student.id, student.name),(student.id, student.name, student.age) ... 任何和主键和身份证的组合都为超键
  • 候选键: 以 student 表为例: student.id student.identify_card
  • 外键: student.teacher_id

表连接

要学习表连接,首先要了解笛卡尔积

笛卡尔积

笛卡尔积(Cartesian product)指的是两个集合 X, Y 中 X 的所有元素分别乘以 Y 中所有元素的集合,又称为直积

例如 X={a,b} Y={1,2} 则 X 和 Y 的笛卡尔积为

Z={(a,1),(a,2),(b,1),(b,2)}

表连接是通过条件对两表之间的笛卡尔积进行筛选后的结果

表连接示意图

sql-join
sql-join

示例表

示例表

接下来的查询都是围绕该示例表

course

idtitle
1Math
2Art
3Music
4Geography
15Sport

student

idnameagecourse_id
1Elaine Morris123
2Beverly Turner114
3Connie Murphy112
4Jamie Romero125
5Clifford Reyes101
6Francisco Cook122
7Alan Sanchez119
8Tony Garcia123
9Bobby Burns128
10Glenn Adams115
11Glenn Griffin124
12Justin Rogers138

注意

一般我们称第一个表为驱动表,第二个表为被驱动表,在例子中 student驱动表course被驱动表

内连接 (inner Join)

内连接 inner join 等同于 join, 用于只返回匹配的行。

以下三种写法相同

select * from a,b;
 
 select * from a join b;
 
@@ -7,4 +7,4 @@ import{_ as t}from"./sql-join-Bp3AkZJ8.js";import{_ as d}from"./plugin-vue_expor
 

结果

idnameagecourse_idid(1)title
5Clifford Reyes1011Math
6Francisco Cook1222Art
3Connie Murphy1122Art
8Tony Garcia1233Music
1Elaine Morris1233Music
11Glenn Griffin1244Geography
2Beverly Turner1144Geography

可以看到只有满足 s.course_id=c.id 的数据列被返回了

外连接 (outer join)

左连接 (left join)

select * from student s left join course c on s.course_id=c.id;
 

结果

idnameagecourse_idid(1)title
5Clifford Reyes1011Math
6Francisco Cook1222Art
3Connie Murphy1122Art
8Tony Garcia1233Music
1Elaine Morris1233Music
11Glenn Griffin1244Geography
2Beverly Turner1144Geography
10Glenn Adams115
4Jamie Romero125
12Justin Rogers138
9Bobby Burns128
7Alan Sanchez119

相关信息

可以看到不只有满足 s.course_id=c.id 的数据列被返回了,同时驱动表未匹配的其他数据也会返回

右连接 (right join)

select * from student s right join course c on s.course_id=c.id;
 

结果

idnameagecourse_idid(1)title
5Clifford Reyes1011Math
6Francisco Cook1222Art
3Connie Murphy1122Art
8Tony Garcia1233Music
1Elaine Morris1233Music
11Glenn Griffin1244Geography
2Beverly Turner1144Geography
15Sport

相关信息

可以看到不只有满足 s.course_id=c.id 的数据列被返回了,同时被驱动表未匹配的其他数据也会返回

全外连接 (full outer join)

select * from student s full outer join course c on s.course_id=c.id;
-

结果

idnameagecourse_idid(1)title
5Clifford Reyes1011Math
6Francisco Cook1222Art
3Connie Murphy1122Art
8Tony Garcia1233Music
1Elaine Morris1233Music
11Glenn Griffin1244Geography
2Beverly Turner1144Geography
15Sport
10Glenn Adams115
4Jamie Romero125
12Justin Rogers138
9Bobby Burns128
7Alan Sanchez119

相关信息

可以看到不只有满足 s.course_id=c.id 的数据列被返回了,同时未匹配的其他数据也会返回

查询条件

在使用连接后支持两种过滤条件:

where

使用 where 子句只会返回满足 where 条件的列

on

使用 on 时,在内连接的查询中 on 和 where 的效果是一致的,在外连接中如左连接会返回驱动表不匹配的数据

注意

如果有多个表连接如 a inner join b inner join c 首先会执行 a inner join b, 然后将结果再 inner join c

重要

join 的时候利用索引可以减少回表次数

`,37),o=[r];function i(c,l){return e(),n("div",null,o)}const g=d(s,[["render",i],["__file","1-database-basic.html.vue"]]),m=JSON.parse('{"path":"/guide/concepts/database/1-database-basic.html","title":"数据库基础","lang":"zh-CN","frontmatter":{"order":1,"title":"数据库基础","description":"关系键 关系键用于标识数据表中的每一行或者标识与其他表的关系 注意 主键和唯一键的区别: 一张表只能有一个主键,可以有多个唯一键 主键不能为空,唯一键可以为空 例子 假设有两张表 主键: student.id teacher.id 超键: 以 student 表为例: (student.id, student.name),(student.id, st...","head":[["link",{"rel":"alternate","hreflang":"en-us","href":"https://goguide.ryansu.tech/en/guide/concepts/database/1-database-basic.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/guide/concepts/database/1-database-basic.html"}],["meta",{"property":"og:site_name","content":"Go 面试宝典"}],["meta",{"property":"og:title","content":"数据库基础"}],["meta",{"property":"og:description","content":"关系键 关系键用于标识数据表中的每一行或者标识与其他表的关系 注意 主键和唯一键的区别: 一张表只能有一个主键,可以有多个唯一键 主键不能为空,唯一键可以为空 例子 假设有两张表 主键: student.id teacher.id 超键: 以 student 表为例: (student.id, student.name),(student.id, st..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://goguide.ryansu.tech/assets/image/article/concept/sql-join.png"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:locale:alternate","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-01-29T02:53:54.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"数据库基础"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-01-29T02:53:54.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"数据库基础\\",\\"image\\":[\\"https://goguide.ryansu.tech/assets/image/article/concept/sql-join.png\\"],\\"dateModified\\":\\"2024-01-29T02:53:54.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":2,"title":"关系键","slug":"关系键","link":"#关系键","children":[]},{"level":2,"title":"表连接","slug":"表连接","link":"#表连接","children":[{"level":3,"title":"表连接示意图","slug":"表连接示意图","link":"#表连接示意图","children":[]},{"level":3,"title":"内连接 (inner Join)","slug":"内连接-inner-join","link":"#内连接-inner-join","children":[]},{"level":3,"title":"外连接 (outer join)","slug":"外连接-outer-join","link":"#外连接-outer-join","children":[{"level":4,"title":"左连接 (left join)","slug":"左连接-left-join","link":"#左连接-left-join","children":[]},{"level":4,"title":"右连接 (right join)","slug":"右连接-right-join","link":"#右连接-right-join","children":[]},{"level":4,"title":"全外连接 (full outer join)","slug":"全外连接-full-outer-join","link":"#全外连接-full-outer-join","children":[]}]}]}],"git":{"createdTime":1706254115000,"updatedTime":1706496834000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":2}]},"readingTime":{"minutes":4.2,"words":1259},"filePathRelative":"guide/concepts/database/1-database-basic.md","localizedDate":"2024年1月26日","autoDesc":true,"excerpt":"

关系键

\\n

关系键用于标识数据表中的每一行或者标识与其他表的关系

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
关系键介绍
主键 (Primary key - Unique key)主键是数据列中用来唯一标识的字段,不允许为空,一个表只能有一个主键
超键 (Super key)超键是能唯一标识数据列的所有属性集, 即若任意单个或多个字段如果也能唯一标识数据列,则都属于超键
候选键 (Candidate key)候选键是超键的子集,候选键是不包含多余字段的超键,候选键中删除任意字段都不属于超键
外键 (Foreign key)外键用于建立表之间的关系,如 A 表的主键是 B 表的字段,这时候 B 表中的 A 表的主键字段就是外键
"}');export{g as comp,m as data}; +

结果

idnameagecourse_idid(1)title
5Clifford Reyes1011Math
6Francisco Cook1222Art
3Connie Murphy1122Art
8Tony Garcia1233Music
1Elaine Morris1233Music
11Glenn Griffin1244Geography
2Beverly Turner1144Geography
15Sport
10Glenn Adams115
4Jamie Romero125
12Justin Rogers138
9Bobby Burns128
7Alan Sanchez119

相关信息

可以看到不只有满足 s.course_id=c.id 的数据列被返回了,同时未匹配的其他数据也会返回

查询条件

在使用连接后支持两种过滤条件:

where

使用 where 子句只会返回满足 where 条件的列

on

使用 on 时,在内连接的查询中 on 和 where 的效果是一致的,在外连接中如左连接会返回驱动表不匹配的数据

注意

如果有多个表连接如 a inner join b inner join c 首先会执行 a inner join b, 然后将结果再 inner join c

重要

join 的时候利用索引可以减少回表次数

`,37),o=[r];function i(c,l){return e(),n("div",null,o)}const g=d(s,[["render",i],["__file","1-database-basic.html.vue"]]),m=JSON.parse('{"path":"/guide/concepts/database/1-database-basic.html","title":"基础","lang":"zh-CN","frontmatter":{"order":1,"title":"基础","description":"关系键 关系键用于标识数据表中的每一行或者标识与其他表的关系 注意 主键和唯一键的区别: 一张表只能有一个主键,可以有多个唯一键 主键不能为空,唯一键可以为空 例子 假设有两张表 主键: student.id teacher.id 超键: 以 student 表为例: (student.id, student.name),(student.id, st...","head":[["link",{"rel":"alternate","hreflang":"en-us","href":"https://goguide.ryansu.tech/en/guide/concepts/database/1-database-basic.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/guide/concepts/database/1-database-basic.html"}],["meta",{"property":"og:site_name","content":"Go 面试宝典"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:description","content":"关系键 关系键用于标识数据表中的每一行或者标识与其他表的关系 注意 主键和唯一键的区别: 一张表只能有一个主键,可以有多个唯一键 主键不能为空,唯一键可以为空 例子 假设有两张表 主键: student.id teacher.id 超键: 以 student 表为例: (student.id, student.name),(student.id, st..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://goguide.ryansu.tech/assets/image/article/concept/sql-join.png"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:locale:alternate","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-02-16T03:42:36.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"基础"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-02-16T03:42:36.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"https://goguide.ryansu.tech/assets/image/article/concept/sql-join.png\\"],\\"dateModified\\":\\"2024-02-16T03:42:36.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":2,"title":"关系键","slug":"关系键","link":"#关系键","children":[]},{"level":2,"title":"表连接","slug":"表连接","link":"#表连接","children":[{"level":3,"title":"表连接示意图","slug":"表连接示意图","link":"#表连接示意图","children":[]},{"level":3,"title":"内连接 (inner Join)","slug":"内连接-inner-join","link":"#内连接-inner-join","children":[]},{"level":3,"title":"外连接 (outer join)","slug":"外连接-outer-join","link":"#外连接-outer-join","children":[{"level":4,"title":"左连接 (left join)","slug":"左连接-left-join","link":"#左连接-left-join","children":[]},{"level":4,"title":"右连接 (right join)","slug":"右连接-right-join","link":"#右连接-right-join","children":[]},{"level":4,"title":"全外连接 (full outer join)","slug":"全外连接-full-outer-join","link":"#全外连接-full-outer-join","children":[]}]}]}],"git":{"createdTime":1706254115000,"updatedTime":1708054956000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":3}]},"readingTime":{"minutes":4.19,"words":1256},"filePathRelative":"guide/concepts/database/1-database-basic.md","localizedDate":"2024年1月26日","autoDesc":true,"excerpt":"

关系键

\\n

关系键用于标识数据表中的每一行或者标识与其他表的关系

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
关系键介绍
主键 (Primary key - Unique key)主键是数据列中用来唯一标识的字段,不允许为空,一个表只能有一个主键
超键 (Super key)超键是能唯一标识数据列的所有属性集, 即若任意单个或多个字段如果也能唯一标识数据列,则都属于超键
候选键 (Candidate key)候选键是超键的子集,候选键是不包含多余字段的超键,候选键中删除任意字段都不属于超键
外键 (Foreign key)外键用于建立表之间的关系,如 A 表的主键是 B 表的字段,这时候 B 表中的 A 表的主键字段就是外键
"}');export{g as comp,m as data}; diff --git a/assets/1-database-basic.html-BrHVm61A.js b/assets/1-database-basic.html-DzAKcAVh.js similarity index 77% rename from assets/1-database-basic.html-BrHVm61A.js rename to assets/1-database-basic.html-DzAKcAVh.js index b42b3ef1..22c04499 100644 --- a/assets/1-database-basic.html-BrHVm61A.js +++ b/assets/1-database-basic.html-DzAKcAVh.js @@ -1,4 +1,4 @@ -import{_ as t}from"./sql-join-Bp3AkZJ8.js";import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as d,c as n,b as a}from"./app-Bsw6rBWV.js";const s={},r=a('

Relationship Keys

Relationship keys are used to identify each row in a data table or to identify relationships with other tables

Relationship KeyDescription
Primary Key (Unique Key)The primary key is the field used to uniquely identify in the data column, cannot be null, and a table can only have one primary key
Super KeyThe super key is all attribute sets that can uniquely identify the data column, i.e., if any single or multiple fields can also uniquely identify the data column, they all belong to the super key
Candidate KeyThe candidate key is a subset of the super key, the candidate key is the super key without redundant fields, and any field removed from the candidate key does not belong to the super key
Foreign KeyThe foreign key is used to establish relationships between tables, such as if the primary key of table A is a field of table B, then the primary key field of table A in table B is a foreign key

Warning

The difference between the primary key and the unique key:

  • A table can only have one primary key, but can have multiple unique keys
  • The primary key cannot be null, the unique key can be null
Example

Assume there are two tables

studentteacher
idid
namename
ageage
identify_card (ID number)
teacher_id
  • Primary Key: student.id teacher.id
  • Super Key: For example, in the student table: (student.id, student.name),(student.id, student.name, student.age) ... Any combination with the primary key and ID number is a super key
  • Candidate Key: For example, in the student table: student.id student.identify_card
  • Foreign Key: student.teacher_id

Table Join

To learn about table join, you first need to understand Cartesian Product

Cartesian Product

The Cartesian product refers to the set of all elements in X, Y where all elements in X are multiplied by all elements in Y, also known as direct product

For example, X={a,b} Y={1,2} then the Cartesian product of X and Y is

Z={(a,1),(a,2),(b,1),(b,2)}

Table join is the result of filtering the Cartesian product between two tables through conditions

Table Join Diagram

sql-join
sql-join

Sample Table

Sample Table

The following queries are all around this sample table:

course

idtitle
1Math
2Art
3Music
4Geography
15Sport

student

idnameagecourse_id
1Elaine Morris123
2Beverly Turner114
3Connie Murphy112
4Jamie Romero125
5Clifford Reyes101
6Francisco Cook122
7Alan Sanchez119
8Tony Garcia123
9Bobby Burns128
10Glenn Adams115
11Glenn Griffin124
12Justin Rogers138

Warning

Generally, we call the first table the driving table and the second table the driven table. In the example, student is the driving table and course is the driven table.

Inner Join

The inner join inner join is equivalent to join, used to return only matching rows.

The following three methods are the same

select * from a,b;
+import{_ as t}from"./sql-join-Bp3AkZJ8.js";import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as d,c as n,b as a}from"./app-C0BAr50I.js";const s={},r=a('

Relationship Keys

Relationship keys are used to identify each row in a data table or to identify relationships with other tables

Relationship KeyDescription
Primary Key (Unique Key)The primary key is the field used to uniquely identify in the data column, cannot be null, and a table can only have one primary key
Super KeyThe super key is all attribute sets that can uniquely identify the data column, i.e., if any single or multiple fields can also uniquely identify the data column, they all belong to the super key
Candidate KeyThe candidate key is a subset of the super key, the candidate key is the super key without redundant fields, and any field removed from the candidate key does not belong to the super key
Foreign KeyThe foreign key is used to establish relationships between tables, such as if the primary key of table A is a field of table B, then the primary key field of table A in table B is a foreign key

Warning

The difference between the primary key and the unique key:

  • A table can only have one primary key, but can have multiple unique keys
  • The primary key cannot be null, the unique key can be null
Example

Assume there are two tables

studentteacher
idid
namename
ageage
identify_card (ID number)
teacher_id
  • Primary Key: student.id teacher.id
  • Super Key: For example, in the student table: (student.id, student.name),(student.id, student.name, student.age) ... Any combination with the primary key and ID number is a super key
  • Candidate Key: For example, in the student table: student.id student.identify_card
  • Foreign Key: student.teacher_id

Table Join

To learn about table join, you first need to understand Cartesian Product

Cartesian Product

The Cartesian product refers to the set of all elements in X, Y where all elements in X are multiplied by all elements in Y, also known as direct product

For example, X={a,b} Y={1,2} then the Cartesian product of X and Y is

Z={(a,1),(a,2),(b,1),(b,2)}

Table join is the result of filtering the Cartesian product between two tables through conditions

Table Join Diagram

sql-join
sql-join

Sample Table

Sample Table

The following queries are all around this sample table:

course

idtitle
1Math
2Art
3Music
4Geography
15Sport

student

idnameagecourse_id
1Elaine Morris123
2Beverly Turner114
3Connie Murphy112
4Jamie Romero125
5Clifford Reyes101
6Francisco Cook122
7Alan Sanchez119
8Tony Garcia123
9Bobby Burns128
10Glenn Adams115
11Glenn Griffin124
12Justin Rogers138

Warning

Generally, we call the first table the driving table and the second table the driven table. In the example, student is the driving table and course is the driven table.

Inner Join

The inner join inner join is equivalent to join, used to return only matching rows.

The following three methods are the same

select * from a,b;
 
 select * from a join b;
 
@@ -7,4 +7,4 @@ import{_ as t}from"./sql-join-Bp3AkZJ8.js";import{_ as e}from"./plugin-vue_expor
 

Result

idnameagecourse_idid(1)title
5Clifford Reyes1011Math
6Francisco Cook1222Art
3Connie Murphy1122Art
8Tony Garcia1233Music
1Elaine Morris1233Music
11Glenn Griffin1244Geography
2Beverly Turner1144Geography

You can see that only the data columns that satisfy s.course_id=c.id are returned

Outer Join

Left Join

select * from student s left join course c on s.course_id=c.id;
 

Result

idnameagecourse_idid(1)title
5Clifford Reyes1011Math
6Francisco Cook1222Art
3Connie Murphy1122Art
8Tony Garcia1233Music
1Elaine Morris1233Music
11Glenn Griffin1244Geography
2Beverly Turner1144Geography
10Glenn Adams115
4Jamie Romero125
12Justin Rogers138
9Bobby Burns128
7Alan Sanchez119

Info

You can see that not only the data columns that satisfy s.course_id=c.id are returned, but also other unmatched data from the driving table are returned

Right Join

select * from student s right join course c on s.course_id=c.id;
 

Result

idnameagecourse_idid(1)title
5Clifford Reyes1011Math
6Francisco Cook1222Art
3Connie Murphy1122Art
8Tony Garcia1233Music
1Elaine Morris1233Music
11Glenn Griffin1244Geography
2Beverly Turner1144Geography
15Sport

Info

You can see that not only the data columns that satisfy s.course_id=c.id are returned, but also other unmatched data from the driven table are returned

Full Outer Join

select * from student s full outer join course c on s.course_id=c.id;
-

Result

idnameagecourse_idid(1)title
5Clifford Reyes1011Math
6Francisco Cook1222Art
3Connie Murphy1122Art
8Tony Garcia1233Music
1Elaine Morris1233Music
11Glenn Griffin1244Geography
2Beverly Turner1144Geography
15Sport
10Glenn Adams115
4Jamie Romero125
12Justin Rogers138
9Bobby Burns128
7Alan Sanchez119

Info

You can see that not only the data columns that satisfy s.course_id=c.id are returned, but also other unmatched data are returned

Query Condition

After using the join, two filtering conditions are supported:

where

Using the where clause will only return columns that meet the where condition

on

When using on, in the inner join query, the effect of on and where is consistent. In the outer join, such as left join, the unmatched data of the driving table will be returned

Warning

If there are multiple table joins such as a inner join b inner join c, a inner join b will be executed first, and then the result will be inner join c

Important

Using indexes when join can reduce the number of table returns

`,37),i=[r];function o(l,c){return d(),n("div",null,i)}const y=e(s,[["render",o],["__file","1-database-basic.html.vue"]]),b=JSON.parse('{"path":"/en/guide/concepts/database/1-database-basic.html","title":"Database basic","lang":"en-US","frontmatter":{"order":1,"title":"Database basic","description":"Relationship Keys Relationship keys are used to identify each row in a data table or to identify relationships with other tables Warning The difference between the primary key a...","head":[["link",{"rel":"alternate","hreflang":"zh-cn","href":"https://goguide.ryansu.tech/guide/concepts/database/1-database-basic.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/en/guide/concepts/database/1-database-basic.html"}],["meta",{"property":"og:site_name","content":"Go Guide"}],["meta",{"property":"og:title","content":"Database basic"}],["meta",{"property":"og:description","content":"Relationship Keys Relationship keys are used to identify each row in a data table or to identify relationships with other tables Warning The difference between the primary key a..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://goguide.ryansu.tech/assets/image/article/concept/sql-join.png"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:locale:alternate","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-01-29T02:53:54.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"Database basic"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-01-29T02:53:54.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Database basic\\",\\"image\\":[\\"https://goguide.ryansu.tech/assets/image/article/concept/sql-join.png\\"],\\"dateModified\\":\\"2024-01-29T02:53:54.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":2,"title":"Relationship Keys","slug":"relationship-keys","link":"#relationship-keys","children":[]},{"level":2,"title":"Table Join","slug":"table-join","link":"#table-join","children":[{"level":3,"title":"Table Join Diagram","slug":"table-join-diagram","link":"#table-join-diagram","children":[]},{"level":3,"title":"Inner Join","slug":"inner-join","link":"#inner-join","children":[]},{"level":3,"title":"Outer Join","slug":"outer-join","link":"#outer-join","children":[{"level":4,"title":"Left Join","slug":"left-join","link":"#left-join","children":[]},{"level":4,"title":"Right Join","slug":"right-join","link":"#right-join","children":[]},{"level":4,"title":"Full Outer Join","slug":"full-outer-join","link":"#full-outer-join","children":[]}]}]}],"git":{"createdTime":1706254115000,"updatedTime":1706496834000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":2}]},"readingTime":{"minutes":3.58,"words":1074},"filePathRelative":"en/guide/concepts/database/1-database-basic.md","localizedDate":"January 26, 2024","autoDesc":true,"excerpt":"

Relationship Keys

\\n

Relationship keys are used to identify each row in a data table or to identify relationships with other tables

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
Relationship KeyDescription
Primary Key (Unique Key)The primary key is the field used to uniquely identify in the data column, cannot be null, and a table can only have one primary key
Super KeyThe super key is all attribute sets that can uniquely identify the data column, i.e., if any single or multiple fields can also uniquely identify the data column, they all belong to the super key
Candidate KeyThe candidate key is a subset of the super key, the candidate key is the super key without redundant fields, and any field removed from the candidate key does not belong to the super key
Foreign KeyThe foreign key is used to establish relationships between tables, such as if the primary key of table A is a field of table B, then the primary key field of table A in table B is a foreign key
"}');export{y as comp,b as data}; +

Result

idnameagecourse_idid(1)title
5Clifford Reyes1011Math
6Francisco Cook1222Art
3Connie Murphy1122Art
8Tony Garcia1233Music
1Elaine Morris1233Music
11Glenn Griffin1244Geography
2Beverly Turner1144Geography
15Sport
10Glenn Adams115
4Jamie Romero125
12Justin Rogers138
9Bobby Burns128
7Alan Sanchez119

Info

You can see that not only the data columns that satisfy s.course_id=c.id are returned, but also other unmatched data are returned

Query Condition

After using the join, two filtering conditions are supported:

where

Using the where clause will only return columns that meet the where condition

on

When using on, in the inner join query, the effect of on and where is consistent. In the outer join, such as left join, the unmatched data of the driving table will be returned

Warning

If there are multiple table joins such as a inner join b inner join c, a inner join b will be executed first, and then the result will be inner join c

Important

Using indexes when join can reduce the number of table returns

`,37),i=[r];function o(l,c){return d(),n("div",null,i)}const y=e(s,[["render",o],["__file","1-database-basic.html.vue"]]),m=JSON.parse('{"path":"/en/guide/concepts/database/1-database-basic.html","title":"Basic","lang":"en-US","frontmatter":{"order":1,"title":"Basic","description":"Relationship Keys Relationship keys are used to identify each row in a data table or to identify relationships with other tables Warning The difference between the primary key a...","head":[["link",{"rel":"alternate","hreflang":"zh-cn","href":"https://goguide.ryansu.tech/guide/concepts/database/1-database-basic.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/en/guide/concepts/database/1-database-basic.html"}],["meta",{"property":"og:site_name","content":"Go Guide"}],["meta",{"property":"og:title","content":"Basic"}],["meta",{"property":"og:description","content":"Relationship Keys Relationship keys are used to identify each row in a data table or to identify relationships with other tables Warning The difference between the primary key a..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://goguide.ryansu.tech/assets/image/article/concept/sql-join.png"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:locale:alternate","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-02-16T03:42:36.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"Basic"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-02-16T03:42:36.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Basic\\",\\"image\\":[\\"https://goguide.ryansu.tech/assets/image/article/concept/sql-join.png\\"],\\"dateModified\\":\\"2024-02-16T03:42:36.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":2,"title":"Relationship Keys","slug":"relationship-keys","link":"#relationship-keys","children":[]},{"level":2,"title":"Table Join","slug":"table-join","link":"#table-join","children":[{"level":3,"title":"Table Join Diagram","slug":"table-join-diagram","link":"#table-join-diagram","children":[]},{"level":3,"title":"Inner Join","slug":"inner-join","link":"#inner-join","children":[]},{"level":3,"title":"Outer Join","slug":"outer-join","link":"#outer-join","children":[{"level":4,"title":"Left Join","slug":"left-join","link":"#left-join","children":[]},{"level":4,"title":"Right Join","slug":"right-join","link":"#right-join","children":[]},{"level":4,"title":"Full Outer Join","slug":"full-outer-join","link":"#full-outer-join","children":[]}]}]}],"git":{"createdTime":1706254115000,"updatedTime":1708054956000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":3}]},"readingTime":{"minutes":3.58,"words":1073},"filePathRelative":"en/guide/concepts/database/1-database-basic.md","localizedDate":"January 26, 2024","autoDesc":true,"excerpt":"

Relationship Keys

\\n

Relationship keys are used to identify each row in a data table or to identify relationships with other tables

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
Relationship KeyDescription
Primary Key (Unique Key)The primary key is the field used to uniquely identify in the data column, cannot be null, and a table can only have one primary key
Super KeyThe super key is all attribute sets that can uniquely identify the data column, i.e., if any single or multiple fields can also uniquely identify the data column, they all belong to the super key
Candidate KeyThe candidate key is a subset of the super key, the candidate key is the super key without redundant fields, and any field removed from the candidate key does not belong to the super key
Foreign KeyThe foreign key is used to establish relationships between tables, such as if the primary key of table A is a field of table B, then the primary key field of table A in table B is a foreign key
"}');export{y as comp,m as data}; diff --git a/assets/1-keywords.html-Bu_vfCri.js b/assets/1-keywords.html--Q_8y9NZ.js similarity index 99% rename from assets/1-keywords.html-Bu_vfCri.js rename to assets/1-keywords.html--Q_8y9NZ.js index b561522e..7820f115 100644 --- a/assets/1-keywords.html-Bu_vfCri.js +++ b/assets/1-keywords.html--Q_8y9NZ.js @@ -1,4 +1,4 @@ -import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,b as e}from"./app-Bsw6rBWV.js";const t={},o=e(`

Keywords

Golang has 25 reserved keywords that cannot be used as program identifiers.

TypeKeywordsIntroduction
Declarationconst func import package type varThese keywords are used to declare various elements in the code.
Composite Typeschan interface map structThese keywords are used to declare some special compound types.
Control Flowbreak case continue default else fallthrough for goto if range return select switchThese keywords are used to control the flow of program execution.
Function Modifiersdefer goUsed to modify special functions.

Declaration Types

const

const is used to declare constants, which once declared cannot be changed, and must specify an initial value when declaring a constant.

Example
const identifier T = value  // T is the data type, which can be omitted, and the compiler will infer it.
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,b as e}from"./app-C0BAr50I.js";const t={},o=e(`

Keywords

Golang has 25 reserved keywords that cannot be used as program identifiers.

TypeKeywordsIntroduction
Declarationconst func import package type varThese keywords are used to declare various elements in the code.
Composite Typeschan interface map structThese keywords are used to declare some special compound types.
Control Flowbreak case continue default else fallthrough for goto if range return select switchThese keywords are used to control the flow of program execution.
Function Modifiersdefer goUsed to modify special functions.

Declaration Types

const

const is used to declare constants, which once declared cannot be changed, and must specify an initial value when declaring a constant.

Example
const identifier T = value  // T is the data type, which can be omitted, and the compiler will infer it.
 const identifier1, identifier2 = value1, value2 // Declare multiple, such as const a, b, c = "hello", 100, true
 
 const (
diff --git a/assets/1-keywords.html-Cb_-qdNV.js b/assets/1-keywords.html-D8qOdfzt.js
similarity index 99%
rename from assets/1-keywords.html-Cb_-qdNV.js
rename to assets/1-keywords.html-D8qOdfzt.js
index 8b050b74..0c4aeb32 100644
--- a/assets/1-keywords.html-Cb_-qdNV.js
+++ b/assets/1-keywords.html-D8qOdfzt.js
@@ -1,4 +1,4 @@
-import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,b as e}from"./app-Bsw6rBWV.js";const t={},o=e(`

保留关键字

golang 有 25 个保留的关键字,这些关键字不能用作程序标识符。

类型关键字介绍
声明const func import package type var这些关键字用于声明代码中的各种元素
复合类型chan interface map struct这些关键字用于声明一些特殊的复合类型
流程控制break case continue default else fallthrough for goto if range return select switch这些关键字用于控制程序运行流程
功能修饰defer go用于修饰特殊的 function

注意

注意: 下面的例子中的 T 表示任意类型

声明类型关键字

const

const 用于声明常量,常量一经声明就不能被更改,声明常量必须指定初始值。

例子
const identifier T = value  // T 为数据类型,可以省略,编译器会自己推断。
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,b as e}from"./app-C0BAr50I.js";const t={},o=e(`

保留关键字

golang 有 25 个保留的关键字,这些关键字不能用作程序标识符。

类型关键字介绍
声明const func import package type var这些关键字用于声明代码中的各种元素
复合类型chan interface map struct这些关键字用于声明一些特殊的复合类型
流程控制break case continue default else fallthrough for goto if range return select switch这些关键字用于控制程序运行流程
功能修饰defer go用于修饰特殊的 function

注意

注意: 下面的例子中的 T 表示任意类型

声明类型关键字

const

const 用于声明常量,常量一经声明就不能被更改,声明常量必须指定初始值。

例子
const identifier T = value  // T 为数据类型,可以省略,编译器会自己推断。
 const identifier1, identifier2 = value1, value2 // 声明多个,如 const a, b, c = "hello", 100, true
 
 const (
diff --git a/assets/1-network.html-C_EZgcM6.js b/assets/1-network.html-BUDov-jI.js
similarity index 79%
rename from assets/1-network.html-C_EZgcM6.js
rename to assets/1-network.html-BUDov-jI.js
index b708a23d..ff596355 100644
--- a/assets/1-network.html-C_EZgcM6.js
+++ b/assets/1-network.html-BUDov-jI.js
@@ -1 +1 @@
-import{_ as t,a as e}from"./signature-_OrRzcAy.js";import{_ as i}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as r,c as s,b as o}from"./app-Bsw6rBWV.js";const n="/assets/image/article/network/httpsgraph_en.png",a={},d=o('

OSI Seven-Layer Model

LayerFunction
PhysicalMainly implements transparent transmission of bitstreams between adjacent nodes, defines the standards of physical devices, such as the type of network cable, the network card also works at this layer.
Data LinkAssembles the bit data packets passed down from the network layer into frames and sends frames on the link of adjacent nodes. The data link layer divides the 0,1 sequence into meaningful data frames and sends them to the other end.
NetworkSelects the appropriate route and switch node, can timely transmit data, the data of this layer is called data packet, the focus is on IP protocol.
TransportProvides a general data transmission service to the host process. The protocol that needs to be focused on in the transport layer is TCP protocol and UDP protocol.
SessionResponsible for establishing, maintaining and terminating communication between two nodes in the network, common protocols are ADSP, RPC, etc.
PresentationMainly responsible for data format conversion, solving communication syntax problems between different systems
ApplicationProvides interactive services for applications, the purpose is to make it more convenient for applications to receive data from the network, the focus is on HTTP protocol
osi
osi

TCP and IP Model

OSI Seven-Layer ModelTCP/IP Five-Layer ModelTCP/IP Four-Layer ModelFunctionTCP/IP Protocol Suite
ApplicationApplicationApplicationFile transfer, email, file service, virtual terminal, etc.SMTP, DNS, Telnet, TFTP, HTTP, SNHP, FTP
PresentationApplicationApplicationData formatting, code conversion, data encryptionNone
SessionApplicationApplicationDissolve or establish contact with other nodesNone
TransportTransportTransportProvides end-to-end interfaceTCP, UDP
NetworkNetworkNetworkSelects routes for data packetsIP, ICHP, RIP, OSPF, BCP, ICMF
Data LinkData LinkNetwork InterfaceTransmits addressed stops and error detection functionsSLIP, CSLIP, PPP, ARP, RARP, MTU
PhysicalPhysicalNetwork InterfaceTransmits data in binary form on physical mediaIS02110, IEEE802, IEEE802.2

HTTP

Request Methods

Info

HTTP 1.0 supports three request methods:

  • GET
  • POST
  • HEAD

HTTP 1.1 additionally supports 6 request methods

  • OPTIONS
  • PUT
  • PATCH
  • DELETE
  • TRACE
  • CONNECT
MethodDescription
GETRequests a specified resource, used to get data
HEADSimilar to GET, but only returns the response header, does not return the response body
POSTUsed to submit information to the target address, used for data submission and file upload
PUTSubmits updated information, used to replace original data
DELETEDeletes the specified resource
CONNECTEstablishes a tunnel with the server
OPTIONSReturns the HTTP request methods supported by a specific server address, can also be used to test the functionality supported by the server
TRACEEchoes the request received by the server, mainly used for testing or diagnosis
PATCHSimilar to PUT, mainly used for partial updates

HTTP Status Codes

NumberMeaning
1XXIndicative information, indicates that the request has been received, continue processing
2XXSuccess, indicates that the request has been successfully received, understood, accepted
3XXThe status code indicates that the resource requested by the client has changed, and the client needs to resend the request with a new URL to get the resource, which is redirection
4XXThe status code indicates that the client's request message is incorrect, the server cannot process, which is the meaning of the error code
5XXThe status code indicates that the client's request message is correct, but an internal error occurred during server processing, which is the server-side error code
Common Status Codes

Sure, here is the English translation of your text:

HTTP Status CodeNameDescription
100ContinueContinue indicates that the client can continue to submit the request
101Switching ProtocolsSwitching Protocols switches the transmission protocol, can only switch from a lower version to a higher version, such as HTTP1.0 switching to HTTP1.1
200OKOK indicates that the server has successfully returned the data
201CreatedCreated indicates that the server has successfully received the request and created the corresponding resource
202AcceptedAccepted indicates that the server has accepted the request, the request will be processed
203Non-Authoritative InformationNon-Authoritative Information indicates that the request was successful, but the returned meta information is not on the original server, but a copy
204No ContentNo Content indicates that the server has successfully processed the request
205Reset ContentReset Content the server has successfully processed, the user terminal (e.g., browser) should reset the document view. This return code can clear the browser's form field
206Partial ContentPartial Content the server has successfully processed part of the GET request
300Multiple ChoicesMultiple Choices the requested resource can include multiple locations, the response can return a list of resource characteristics and addresses for the user terminal (e.g., browser) to choose
301Moved PermanentlyMoved Permanently the requested resource has been permanently moved to a new URI, the return information will include the new URI, the browser will automatically redirect to the new URI. Any new requests in the future should use the new URI instead
302FoundFound similar to 301. But the resource is only temporarily moved. The client should continue to use the original URI
303See OtherSee Other similar to 301. Use GET and POST requests to view
304Not ModifiedNot Modified the requested resource has not been modified, the server returns this status code, will not return any resources. Clients usually cache accessed resources, by providing a header information indicating that the client wants to only return resources modified after a specified date
305Use ProxyUse Proxy the requested resource must be accessed through a proxy
307Temporary RedirectTemporary Redirect similar to 302. Use GET request to redirect
400Bad RequestBad Request indicates that the client's request message is incorrect
401UnauthorizedUnauthorized missing or incorrect authentication, this status code must be used with the WWW-Authenticate header field
403ForbiddenForbidden indicates that the server prohibits access to resources, it is not the client's request error
404Not FoundNot Found indicates that the requested resource does not exist or was not found on the server, so it cannot be provided to the client
501Not ImplementedNot Implemented indicates that the functionality requested by the client is not yet supported
502Bad GatewayBad Gateway is usually an error code returned by the server when it acts as a gateway or proxy, indicating that the server itself is working normally, but an error occurred when accessing the backend server
503Service UnavailableService Unavailable indicates that the server is currently very busy and temporarily unable to respond to the server
504Gateway TimeoutGateway Timeout is a gateway timeout, used by the server as a proxy or gateway, indicating that it cannot get a response from the remote server in a timely manner

HTTPS vs HTTP

FeatureHTTPHTTPS
DefinitionHTTP is the Hypertext Transfer Protocol, used to transfer hypertext from the World Wide Web server to the local browser.HTTPS is HTTP with security, providing encryption processing, data integrity checking and identity authentication through SSL/TLS.
PortThe default HTTP port is 80.The default HTTPS port is 443.
SecurityHTTP itself is not secure, because data is not encrypted during transmission, it may be obtained by third parties.HTTPS is secure, because data is encrypted during transmission, preventing it from being obtained by third parties.
SpeedHTTP is relatively fast, because there is no encryption and decryption process.HTTPS is relatively slow, because data needs to be encrypted and decrypted during transmission.

Working Principle

The HTTPS protocol will encrypt the transmitted data, and the encryption process uses asymmetric encryption

  1. The Client initiates an HTTPS request
  2. The Server returns the pre-configured public key certificate to the client.
  3. The Client verifies the public key certificate: for example, whether it is within the validity period, whether the purpose of the certificate matches the site requested by the Client, whether it is in the CRL revocation list, whether its superior certificate is valid, this is a recursive process, until it is verified to the root certificate (the Root certificate built into the operating system or the Client), if the verification passes, continue, if not, display a warning message.
  4. The Client uses a pseudorandom number generator to generate the symmetric key used for encryption, then encrypts this symmetric key with the certificate's public key, and sends it to the Server.
  5. The Server uses its own private key to decrypt this message, obtaining the symmetric key. At this point, both the Client and Server hold the same symmetric key.
  6. The Server uses the symmetric key to encrypt the plaintext content A and sends it to the Client.
  7. The Client uses the symmetric key to decrypt the response ciphertext, obtaining the plaintext content A.
  8. The Client initiates an HTTPS request again, encrypts the plaintext content B of the request with the symmetric key, and then the Server uses the symmetric key to decrypt the ciphertext, obtaining the plaintext content B.
https
https

HTTP 1.0 vs 1.1 vs 2.0

Differences

FeatureHTTP 1.0HTTP 1.1HTTP 2.0
ConnectionNon-persistent, each request requires a new connectionPersistent, reduces the overhead of repeated TCP connection establishment and terminationMultiplexing, multiple HTTP requests can be concurrent on a single TCP connection
Head-of-line blockingExists, the next request can only be sent after the response of the previous request arrivesExists, although multiple requests can be initiated, the server must send responses in the order of received requestsSolved, multiple requests or responses can be concurrent in a single connection without having to correspond one by one
Header compressionNot supportedNot supportedSupported, uses HPACK algorithm to compress headers
Server pushNot supportedNot supportedSupported

Digital Certificate

A digital certificate is an authoritative electronic document that provides a way to verify identity on the Internet. Digital certificates verify the online credentials and identity of individuals or organizations, and let network users and recipients know that the data they enter will go to a trusted source. They are similar to security badges for websites and users, and help ensure the security of the Internet.

Digital certificates are issued by Certificate Authorities (CAs) for encrypting online data. Digital certificates are also known as public key certificates or identity certificates. For example, TLS/SSL certificates have two purposes: to encrypt and protect data transmitted between websites, browsers, and web servers, and to help identify and verify the owner of the website.

The basic architecture of a digital certificate is Public Key Infrastructure (PKI), which uses a pair of keys to implement encryption and decryption. The keys include a private key and a public key. The private key is mainly used for signing and decryption, is user-defined, and is known only to the user; the public key is used for signature verification and encryption, and can be shared by multiple users.

The application of digital certificates is very wide. For example, using digital certificates in secure email can construct secure email certificates, mainly for encrypting the transmission of emails, protecting the security of emails during transmission and reception. In addition, digital certificates can also be used for terminal protection. For example, if a digital certificate is installed during the process of e-commerce activities, then even if its account or password and other personal information are stolen, the information and financial security in its account can still be effectively guaranteed.

How Digital Signature Works

signature
signature

Signature Process

  1. Use the signature hash algorithm (such as sha256 md5) to calculate information including the issuer's information, the certificate holder's information, the certificate validity period, the certificate holder's public key, etc. (as in the example of x.509), to generate a certificate digest α.
  2. The issuer generates a pair of private and public keys, then uses the private key to encrypt the fingerprint, and the encrypted data is the issuer's digital signature γ.
  3. Attach the digital signature γ to the digital certificate to form a signed digital certificate.
  4. The issuer gives the signed digital certificate and the public key to the certificate holder.

Verification Process

  1. The user obtains the signed digital certificate through some means (for example, browser access), and after parsing, the digital signature γ and the digital certificate can be obtained.
  2. The user uses the fingerprint algorithm in the digital certificate to recalculate the relevant content of the digital certificate, generating a new fingerprint β.
  3. At the same time, the user uses the obtained issuer's public key to decrypt the digital signature, and obtains the decrypted fingerprint α.
  4. Compare the two fingerprints α and β. If they are the same, it proves that the certificate is legal, and the user can trust and use the information in the certificate (for example, the holder's public key).
Example: Information contained in an X.509 certificate
  1. Certificate version information
  2. Certificate serial number
  3. Signature algorithm used by the certificate
  4. Name of the certificate issuing authority
  5. Certificate validity period, now commonly used certificates generally use UTC time format, its timing range is 1950-2049
  6. Name of the certificate owner
  7. Public key of the certificate owner
  8. Signature of the certificate issuer on the certificate

Functions

  1. Data encryption: Encrypt data to ensure data security
  2. Identity confirmation: Ensure the correct identity of both parties
  3. Non-tampering: Unable to modify signed files
  4. Non-repudiation: Under the supervision of CA, ensure that transactions cannot be denied after they are concluded
',33),c=[d];function l(h,p){return r(),s("div",null,c)}const f=i(a,[["render",l],["__file","1-network.html.vue"]]),y=JSON.parse('{"path":"/en/guide/concepts/network/1-network.html","title":"Computer Network","lang":"en-US","frontmatter":{"order":1,"title":"Computer Network","description":"OSI Seven-Layer Model osiosi TCP and IP Model HTTP Request Methods Info HTTP 1.0 supports three request methods: GET POST HEAD HTTP 1.1 additionally supports 6 request methods O...","head":[["link",{"rel":"alternate","hreflang":"zh-cn","href":"https://goguide.ryansu.tech/guide/concepts/network/1-network.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/en/guide/concepts/network/1-network.html"}],["meta",{"property":"og:site_name","content":"Go Guide"}],["meta",{"property":"og:title","content":"Computer Network"}],["meta",{"property":"og:description","content":"OSI Seven-Layer Model osiosi TCP and IP Model HTTP Request Methods Info HTTP 1.0 supports three request methods: GET POST HEAD HTTP 1.1 additionally supports 6 request methods O..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://goguide.ryansu.tech/assets/image/article/network/tcpip.png"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:locale:alternate","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-02-14T15:36:34.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"Computer Network"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-02-14T15:36:34.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Computer Network\\",\\"image\\":[\\"https://goguide.ryansu.tech/assets/image/article/network/tcpip.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/httpsgraph_en.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/signature.png\\"],\\"dateModified\\":\\"2024-02-14T15:36:34.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":3,"title":"OSI Seven-Layer Model","slug":"osi-seven-layer-model","link":"#osi-seven-layer-model","children":[]},{"level":3,"title":"TCP and IP Model","slug":"tcp-and-ip-model","link":"#tcp-and-ip-model","children":[]},{"level":3,"title":"HTTP","slug":"http","link":"#http","children":[{"level":4,"title":"HTTP Status Codes","slug":"http-status-codes","link":"#http-status-codes","children":[]},{"level":4,"title":"HTTPS vs HTTP","slug":"https-vs-http","link":"#https-vs-http","children":[]},{"level":4,"title":"Working Principle","slug":"working-principle","link":"#working-principle","children":[]}]},{"level":3,"title":"HTTP 1.0 vs 1.1 vs 2.0","slug":"http-1-0-vs-1-1-vs-2-0","link":"#http-1-0-vs-1-1-vs-2-0","children":[]},{"level":3,"title":"Digital Certificate","slug":"digital-certificate","link":"#digital-certificate","children":[{"level":4,"title":"How Digital Signature Works","slug":"how-digital-signature-works","link":"#how-digital-signature-works","children":[]}]}],"git":{"createdTime":1707924994000,"updatedTime":1707924994000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":1}]},"readingTime":{"minutes":7.58,"words":2275},"filePathRelative":"en/guide/concepts/network/1-network.md","localizedDate":"February 14, 2024","autoDesc":true,"excerpt":"

OSI Seven-Layer Model

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
LayerFunction
PhysicalMainly implements transparent transmission of bitstreams between adjacent nodes, defines the standards of physical devices, such as the type of network cable, the network card also works at this layer.
Data LinkAssembles the bit data packets passed down from the network layer into frames and sends frames on the link of adjacent nodes. The data link layer divides the 0,1 sequence into meaningful data frames and sends them to the other end.
NetworkSelects the appropriate route and switch node, can timely transmit data, the data of this layer is called data packet, the focus is on IP protocol.
TransportProvides a general data transmission service to the host process. The protocol that needs to be focused on in the transport layer is TCP protocol and UDP protocol.
SessionResponsible for establishing, maintaining and terminating communication between two nodes in the network, common protocols are ADSP, RPC, etc.
PresentationMainly responsible for data format conversion, solving communication syntax problems between different systems
ApplicationProvides interactive services for applications, the purpose is to make it more convenient for applications to receive data from the network, the focus is on HTTP protocol
"}');export{f as comp,y as data}; +import{_ as t,a as e}from"./signature-_OrRzcAy.js";import{_ as i}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as r,c as s,b as n}from"./app-C0BAr50I.js";const o="/assets/image/article/network/httpsgraph_en.png",a={},d=n('

OSI Seven-Layer Model

LayerFunction
PhysicalMainly implements transparent transmission of bitstreams between adjacent nodes, defines the standards of physical devices, such as the type of network cable, the network card also works at this layer.
Data LinkAssembles the bit data packets passed down from the network layer into frames and sends frames on the link of adjacent nodes. The data link layer divides the 0,1 sequence into meaningful data frames and sends them to the other end.
NetworkSelects the appropriate route and switch node, can timely transmit data, the data of this layer is called data packet, the focus is on IP protocol.
TransportProvides a general data transmission service to the host process. The protocol that needs to be focused on in the transport layer is TCP protocol and UDP protocol.
SessionResponsible for establishing, maintaining and terminating communication between two nodes in the network, common protocols are ADSP, RPC, etc.
PresentationMainly responsible for data format conversion, solving communication syntax problems between different systems
ApplicationProvides interactive services for applications, the purpose is to make it more convenient for applications to receive data from the network, the focus is on HTTP protocol
osi
osi

TCP and IP Model

OSI Seven-Layer ModelTCP/IP Five-Layer ModelTCP/IP Four-Layer ModelFunctionTCP/IP Protocol Suite
ApplicationApplicationApplicationFile transfer, email, file service, virtual terminal, etc.SMTP, DNS, Telnet, TFTP, HTTP, SNHP, FTP
PresentationApplicationApplicationData formatting, code conversion, data encryptionNone
SessionApplicationApplicationDissolve or establish contact with other nodesNone
TransportTransportTransportProvides end-to-end interfaceTCP, UDP
NetworkNetworkNetworkSelects routes for data packetsIP, ICHP, RIP, OSPF, BCP, ICMF
Data LinkData LinkNetwork InterfaceTransmits addressed stops and error detection functionsSLIP, CSLIP, PPP, ARP, RARP, MTU
PhysicalPhysicalNetwork InterfaceTransmits data in binary form on physical mediaIS02110, IEEE802, IEEE802.2

HTTP

Request Methods

Info

HTTP 1.0 supports three request methods:

  • GET
  • POST
  • HEAD

HTTP 1.1 additionally supports 6 request methods

  • OPTIONS
  • PUT
  • PATCH
  • DELETE
  • TRACE
  • CONNECT
MethodDescription
GETRequests a specified resource, used to get data
HEADSimilar to GET, but only returns the response header, does not return the response body
POSTUsed to submit information to the target address, used for data submission and file upload
PUTSubmits updated information, used to replace original data
DELETEDeletes the specified resource
CONNECTEstablishes a tunnel with the server
OPTIONSReturns the HTTP request methods supported by a specific server address, can also be used to test the functionality supported by the server
TRACEEchoes the request received by the server, mainly used for testing or diagnosis
PATCHSimilar to PUT, mainly used for partial updates

HTTP Status Codes

NumberMeaning
1XXIndicative information, indicates that the request has been received, continue processing
2XXSuccess, indicates that the request has been successfully received, understood, accepted
3XXThe status code indicates that the resource requested by the client has changed, and the client needs to resend the request with a new URL to get the resource, which is redirection
4XXThe status code indicates that the client's request message is incorrect, the server cannot process, which is the meaning of the error code
5XXThe status code indicates that the client's request message is correct, but an internal error occurred during server processing, which is the server-side error code
Common Status Codes

Sure, here is the English translation of your text:

HTTP Status CodeNameDescription
100ContinueContinue indicates that the client can continue to submit the request
101Switching ProtocolsSwitching Protocols switches the transmission protocol, can only switch from a lower version to a higher version, such as HTTP1.0 switching to HTTP1.1
200OKOK indicates that the server has successfully returned the data
201CreatedCreated indicates that the server has successfully received the request and created the corresponding resource
202AcceptedAccepted indicates that the server has accepted the request, the request will be processed
203Non-Authoritative InformationNon-Authoritative Information indicates that the request was successful, but the returned meta information is not on the original server, but a copy
204No ContentNo Content indicates that the server has successfully processed the request
205Reset ContentReset Content the server has successfully processed, the user terminal (e.g., browser) should reset the document view. This return code can clear the browser's form field
206Partial ContentPartial Content the server has successfully processed part of the GET request
300Multiple ChoicesMultiple Choices the requested resource can include multiple locations, the response can return a list of resource characteristics and addresses for the user terminal (e.g., browser) to choose
301Moved PermanentlyMoved Permanently the requested resource has been permanently moved to a new URI, the return information will include the new URI, the browser will automatically redirect to the new URI. Any new requests in the future should use the new URI instead
302FoundFound similar to 301. But the resource is only temporarily moved. The client should continue to use the original URI
303See OtherSee Other similar to 301. Use GET and POST requests to view
304Not ModifiedNot Modified the requested resource has not been modified, the server returns this status code, will not return any resources. Clients usually cache accessed resources, by providing a header information indicating that the client wants to only return resources modified after a specified date
305Use ProxyUse Proxy the requested resource must be accessed through a proxy
307Temporary RedirectTemporary Redirect similar to 302. Use GET request to redirect
400Bad RequestBad Request indicates that the client's request message is incorrect
401UnauthorizedUnauthorized missing or incorrect authentication, this status code must be used with the WWW-Authenticate header field
403ForbiddenForbidden indicates that the server prohibits access to resources, it is not the client's request error
404Not FoundNot Found indicates that the requested resource does not exist or was not found on the server, so it cannot be provided to the client
501Not ImplementedNot Implemented indicates that the functionality requested by the client is not yet supported
502Bad GatewayBad Gateway is usually an error code returned by the server when it acts as a gateway or proxy, indicating that the server itself is working normally, but an error occurred when accessing the backend server
503Service UnavailableService Unavailable indicates that the server is currently very busy and temporarily unable to respond to the server
504Gateway TimeoutGateway Timeout is a gateway timeout, used by the server as a proxy or gateway, indicating that it cannot get a response from the remote server in a timely manner

HTTPS vs HTTP

FeatureHTTPHTTPS
DefinitionHTTP is the Hypertext Transfer Protocol, used to transfer hypertext from the World Wide Web server to the local browser.HTTPS is HTTP with security, providing encryption processing, data integrity checking and identity authentication through SSL/TLS.
PortThe default HTTP port is 80.The default HTTPS port is 443.
SecurityHTTP itself is not secure, because data is not encrypted during transmission, it may be obtained by third parties.HTTPS is secure, because data is encrypted during transmission, preventing it from being obtained by third parties.
SpeedHTTP is relatively fast, because there is no encryption and decryption process.HTTPS is relatively slow, because data needs to be encrypted and decrypted during transmission.

Working Principle

The HTTPS protocol will encrypt the transmitted data, and the encryption process uses asymmetric encryption

  1. The Client initiates an HTTPS request
  2. The Server returns the pre-configured public key certificate to the client.
  3. The Client verifies the public key certificate: for example, whether it is within the validity period, whether the purpose of the certificate matches the site requested by the Client, whether it is in the CRL revocation list, whether its superior certificate is valid, this is a recursive process, until it is verified to the root certificate (the Root certificate built into the operating system or the Client), if the verification passes, continue, if not, display a warning message.
  4. The Client uses a pseudorandom number generator to generate the symmetric key used for encryption, then encrypts this symmetric key with the certificate's public key, and sends it to the Server.
  5. The Server uses its own private key to decrypt this message, obtaining the symmetric key. At this point, both the Client and Server hold the same symmetric key.
  6. The Server uses the symmetric key to encrypt the plaintext content A and sends it to the Client.
  7. The Client uses the symmetric key to decrypt the response ciphertext, obtaining the plaintext content A.
  8. The Client initiates an HTTPS request again, encrypts the plaintext content B of the request with the symmetric key, and then the Server uses the symmetric key to decrypt the ciphertext, obtaining the plaintext content B.
https
https

HTTP 1.0 vs 1.1 vs 2.0

Differences

FeatureHTTP 1.0HTTP 1.1HTTP 2.0
ConnectionNon-persistent, each request requires a new connectionPersistent, reduces the overhead of repeated TCP connection establishment and terminationMultiplexing, multiple HTTP requests can be concurrent on a single TCP connection
Head-of-line blockingExists, the next request can only be sent after the response of the previous request arrivesExists, although multiple requests can be initiated, the server must send responses in the order of received requestsSolved, multiple requests or responses can be concurrent in a single connection without having to correspond one by one
Header compressionNot supportedNot supportedSupported, uses HPACK algorithm to compress headers
Server pushNot supportedNot supportedSupported

Digital Certificate

A digital certificate is an authoritative electronic document that provides a way to verify identity on the Internet. Digital certificates verify the online credentials and identity of individuals or organizations, and let network users and recipients know that the data they enter will go to a trusted source. They are similar to security badges for websites and users, and help ensure the security of the Internet.

Digital certificates are issued by Certificate Authorities (CAs) for encrypting online data. Digital certificates are also known as public key certificates or identity certificates. For example, TLS/SSL certificates have two purposes: to encrypt and protect data transmitted between websites, browsers, and web servers, and to help identify and verify the owner of the website.

The basic architecture of a digital certificate is Public Key Infrastructure (PKI), which uses a pair of keys to implement encryption and decryption. The keys include a private key and a public key. The private key is mainly used for signing and decryption, is user-defined, and is known only to the user; the public key is used for signature verification and encryption, and can be shared by multiple users.

The application of digital certificates is very wide. For example, using digital certificates in secure email can construct secure email certificates, mainly for encrypting the transmission of emails, protecting the security of emails during transmission and reception. In addition, digital certificates can also be used for terminal protection. For example, if a digital certificate is installed during the process of e-commerce activities, then even if its account or password and other personal information are stolen, the information and financial security in its account can still be effectively guaranteed.

How Digital Signature Works

signature
signature

Signature Process

  1. Use the signature hash algorithm (such as sha256 md5) to calculate information including the issuer's information, the certificate holder's information, the certificate validity period, the certificate holder's public key, etc. (as in the example of x.509), to generate a certificate digest α.
  2. The issuer generates a pair of private and public keys, then uses the private key to encrypt the fingerprint, and the encrypted data is the issuer's digital signature γ.
  3. Attach the digital signature γ to the digital certificate to form a signed digital certificate.
  4. The issuer gives the signed digital certificate and the public key to the certificate holder.

Verification Process

  1. The user obtains the signed digital certificate through some means (for example, browser access), and after parsing, the digital signature γ and the digital certificate can be obtained.
  2. The user uses the fingerprint algorithm in the digital certificate to recalculate the relevant content of the digital certificate, generating a new fingerprint β.
  3. At the same time, the user uses the obtained issuer's public key to decrypt the digital signature, and obtains the decrypted fingerprint α.
  4. Compare the two fingerprints α and β. If they are the same, it proves that the certificate is legal, and the user can trust and use the information in the certificate (for example, the holder's public key).
Example: Information contained in an X.509 certificate
  1. Certificate version information
  2. Certificate serial number
  3. Signature algorithm used by the certificate
  4. Name of the certificate issuing authority
  5. Certificate validity period, now commonly used certificates generally use UTC time format, its timing range is 1950-2049
  6. Name of the certificate owner
  7. Public key of the certificate owner
  8. Signature of the certificate issuer on the certificate

Functions

  1. Data encryption: Encrypt data to ensure data security
  2. Identity confirmation: Ensure the correct identity of both parties
  3. Non-tampering: Unable to modify signed files
  4. Non-repudiation: Under the supervision of CA, ensure that transactions cannot be denied after they are concluded
',33),c=[d];function l(h,p){return r(),s("div",null,c)}const f=i(a,[["render",l],["__file","1-network.html.vue"]]),y=JSON.parse('{"path":"/en/guide/concepts/network/1-network.html","title":"Basic","lang":"en-US","frontmatter":{"order":1,"title":"Basic","description":"OSI Seven-Layer Model osiosi TCP and IP Model HTTP Request Methods Info HTTP 1.0 supports three request methods: GET POST HEAD HTTP 1.1 additionally supports 6 request methods O...","head":[["link",{"rel":"alternate","hreflang":"zh-cn","href":"https://goguide.ryansu.tech/guide/concepts/network/1-network.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/en/guide/concepts/network/1-network.html"}],["meta",{"property":"og:site_name","content":"Go Guide"}],["meta",{"property":"og:title","content":"Basic"}],["meta",{"property":"og:description","content":"OSI Seven-Layer Model osiosi TCP and IP Model HTTP Request Methods Info HTTP 1.0 supports three request methods: GET POST HEAD HTTP 1.1 additionally supports 6 request methods O..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://goguide.ryansu.tech/assets/image/article/network/tcpip.png"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:locale:alternate","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-02-16T03:42:36.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"Basic"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-02-16T03:42:36.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Basic\\",\\"image\\":[\\"https://goguide.ryansu.tech/assets/image/article/network/tcpip.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/httpsgraph_en.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/signature.png\\"],\\"dateModified\\":\\"2024-02-16T03:42:36.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":3,"title":"OSI Seven-Layer Model","slug":"osi-seven-layer-model","link":"#osi-seven-layer-model","children":[]},{"level":3,"title":"TCP and IP Model","slug":"tcp-and-ip-model","link":"#tcp-and-ip-model","children":[]},{"level":3,"title":"HTTP","slug":"http","link":"#http","children":[{"level":4,"title":"HTTP Status Codes","slug":"http-status-codes","link":"#http-status-codes","children":[]},{"level":4,"title":"HTTPS vs HTTP","slug":"https-vs-http","link":"#https-vs-http","children":[]},{"level":4,"title":"Working Principle","slug":"working-principle","link":"#working-principle","children":[]}]},{"level":3,"title":"HTTP 1.0 vs 1.1 vs 2.0","slug":"http-1-0-vs-1-1-vs-2-0","link":"#http-1-0-vs-1-1-vs-2-0","children":[]},{"level":3,"title":"Digital Certificate","slug":"digital-certificate","link":"#digital-certificate","children":[{"level":4,"title":"How Digital Signature Works","slug":"how-digital-signature-works","link":"#how-digital-signature-works","children":[]}]}],"git":{"createdTime":1707924994000,"updatedTime":1708054956000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":2}]},"readingTime":{"minutes":7.58,"words":2274},"filePathRelative":"en/guide/concepts/network/1-network.md","localizedDate":"February 14, 2024","autoDesc":true,"excerpt":"

OSI Seven-Layer Model

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
LayerFunction
PhysicalMainly implements transparent transmission of bitstreams between adjacent nodes, defines the standards of physical devices, such as the type of network cable, the network card also works at this layer.
Data LinkAssembles the bit data packets passed down from the network layer into frames and sends frames on the link of adjacent nodes. The data link layer divides the 0,1 sequence into meaningful data frames and sends them to the other end.
NetworkSelects the appropriate route and switch node, can timely transmit data, the data of this layer is called data packet, the focus is on IP protocol.
TransportProvides a general data transmission service to the host process. The protocol that needs to be focused on in the transport layer is TCP protocol and UDP protocol.
SessionResponsible for establishing, maintaining and terminating communication between two nodes in the network, common protocols are ADSP, RPC, etc.
PresentationMainly responsible for data format conversion, solving communication syntax problems between different systems
ApplicationProvides interactive services for applications, the purpose is to make it more convenient for applications to receive data from the network, the focus is on HTTP protocol
"}');export{f as comp,y as data}; diff --git a/assets/1-network.html-V2ivHazx.js b/assets/1-network.html-Blr4KIdV.js similarity index 77% rename from assets/1-network.html-V2ivHazx.js rename to assets/1-network.html-Blr4KIdV.js index 11cd1b34..002fa041 100644 --- a/assets/1-network.html-V2ivHazx.js +++ b/assets/1-network.html-Blr4KIdV.js @@ -1 +1 @@ -import{_ as t,a as d}from"./signature-_OrRzcAy.js";import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as r,c as o,b as n}from"./app-Bsw6rBWV.js";const i="/assets/image/article/network/httpsgraph.png",a={},l=n('

OSI七层模型

层级功能
物理层主要实现相邻节点间比特流的透明传输,物理层定义了物理设备的标准,如网线的类型等, 网卡也会在这层工作
数据链路层将网络层传下来的比特数据包组装成帧,并在相邻节点的链路上传送帧。数据链路层会将0、1序列划分为具有意义的数据帧传送给另一端。
网络层选择合适的路由和交换结点,能让数据及时传送,此层的数据称为数据包,要关注的是IP协议。
传输层向主机进程提供通用的数据传输服务。传输层需要关注的协议有TCP协议和UDP协议。
会话层负责在网络中的两节点之间建立、维持和终止通信,常见的协议有 ADSP、RPC 等。
表示层主要负责数据格式的转换,解决不同系统之间通信语法问题
应用层为应用程序提供交互服务,目的是更方便应用从网络中接收的数据,重点关注HTTP协议
osi
osi

TCP和IP模型

OSI七层模型TCP/IP 五层模型TCP/IP 四层模型功能TCP/IP协议族
应用层应用层应用层文件传输,电子邮件,文件服务,虚拟终端等SMTP,DNS,Telnet,TFTP,HTTP,SNHP,FTP
表示层应用层应用层数据格式化,代码转换,数据加密
会话层应用层应用层解除或建立与别的接点的联系
传输层传输层传输层提供端对端的接口TCP,UDP
网络层网络层网络层为数据包选择路由IP,ICHP,RIP,OSPF,BCP,ICMF
数据链路层数据链路层网络接口层传输有地址的顿以及错误检测功能SLIP,CSLIP,PPP,ARP,RARP,MTU
物理层物理层网络接口层以二进制数据形式在物理媒介上传输数据IS02110,IEEE802,IEEE802.2

HTTP

请求方法

相关信息

HTTP 1.0 支持三种请求方式:

  • GET
  • POST
  • HEAD

HTTP 1.1 额外支持 6 种请求方式

  • OPTIONS
  • PUT
  • PATCH
  • DELETE
  • TRACE
  • CONNECT
方法描述
GET请求一个指定资源,用于获取数据
HEAD和 GET 类似,但是只返回响应头,不返回响应体
POST用于提交信息到目标地址,用于数据提交和文件上传
PUT提交更新的信息,用于替换原数据
DELETE删除指定的资源
CONNECT与服务器建立隧道
OPTIONS返回特定服务器地址所支持的 HTTP 请求方法, 也可用于测试服务器支持的功能
TRACE回显服务器收到的请求,主要用于测试或诊断
PATCHPUT 相似,主要用于部分更新

HTTP 状态码

数字含义
1XX指示信息,表示请求以接收,继续处理
2XX成功,表示请求已经被成功接收、理解、接受
3XX状态码表示客户端请求的资源发送了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向
4XX状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。
5XX状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码
常见状态码
HTTP 状态码名称描述
100Continue继续 表示客户端可以继续提交请求
101Switching Protocols切换协议 切换传输协议,只能从低版本切换到高版本,如 HTTP1.0 切换为 HTTP1.1
200OK请求成功 表示服务器成功返回了数据
201Created已创建 表示服务器成功接收到请求并创建了对应的资源
202Accepted已接受 表示服务器已经接受了请求,请求将会被处理
203Non-Authoritative Information非授权信息 表示请求成功,但返回的meta信息不在原始的服务器,而是一个副本
204No Content无内容 表示服务器成功处理请求
205Reset Content重置内容 服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206Partial Content部分内容服务器成功处理了部分GET请求
300Multiple Choices多种选择请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301Moved Permanently永久移动请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302Found临时移动与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303See Other查看其它地址与301类似。使用GET和POST请求查看
304Not Modified未修改 所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305Use Proxy使用代理 所请求的资源必须通过代理访问
307Temporary Redirect临时重定向与302类似。使用GET请求重定向
400Bad Request错误请求表示客户端请求的报文有错误
401Unauthorized未授权缺失或错误的认证,这个状态代码必须和WWW-Authenticate报头域一起使用
403Forbidden禁止访问表示服务器禁止访问资源,并不是客户端的请求出错
404Not Found未找到表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端
501Not Implemented功能未实现表示客户端请求的功能还不支持
502Bad Gateway网关错误通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误
503Service Unavailable服务器不可用表示服务器当前很忙,暂时无法响应服务器
504Gateway Timeout网关超时网关超时,由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答

HTTPS vs HTTP

特性HTTPHTTPS
定义HTTP 是超文本传输协议,用于从万维网服务器传输超文本到本地浏览器的传送协议。HTTPS 是带有安全性的 HTTP,通过 SSL/TLS 提供加密处理、数据完整性校验及身份认证。
端口默认的 HTTP 端口是 80。默认的 HTTPS 端口是 443。
安全性HTTP 本身不是安全的,因为数据在传输过程中没有加密,可能会被第三方获取。HTTPS 是安全的,因为数据在传输过程中会被加密,防止被第三方获取。
速度HTTP 相对较快,因为没有加密和解密的过程。HTTPS 相对较慢,因为数据在传输过程中需要进行加密和解密。

工作原理

HTTPS 协议会对传输的数据进行加密,而加密过程是使用了非对称加密实现

  1. Client发起一个HTTPS的请求
  2. Server把事先配置好的公钥证书返回给客户端。
  3. Client验证公钥证书:比如是否在有效期内,证书的用途是不是匹配Client请求的站点,是不是在CRL吊销列表里面,它的上一级证书是否有效,这是一个递归的过程,直到验证到根证书(操作系统内置的Root证书或者Client内置的Root证书),如果验证通过则继续,不通过则显示警告信息。
  4. Client使用伪随机数生成器生成加密所使用的对称密钥,然后用证书的公钥加密这个对称密钥,发给Server。
  5. Server使用自己的私钥解密这个消息,得到对称密钥。至此,ClientServer双方都持有了相同的对称密钥。
  6. Server使用对称密钥加密明文内容A,发送给Client
  7. Client使用对称密钥解密响应的密文,得到明文内容A
  8. Client再次发起HTTPS的请求,使用对称密钥加密请求的明文内容B,然后Server使用对称密钥解密密文,得到明文内容B
https
https

HTTP 1.0 vs 1.1 vs 2.0

区别

特性HTTP 1.0HTTP 1.1HTTP 2.0
连接方式无连接,每次请求都要建立连接长连接,减少了 TCP 连接的重复建立和断开所造成的额外开销多路复用,一个 TCP 连接上可以并发多个 HTTP 请求
队头阻塞存在,下一个请求必须在前一个请求响应到达之前才能发送存在,虽然可以发起多个请求,但服务器必须按照接收请求的顺序发送响应解决,可以在一个连接中并发多个请求或回应,而不用按照顺序一一对应
头部压缩不支持不支持支持,使用 HPACK 算法对 header 进行压缩
服务器推送不支持不支持支持

数字证书

数字证书是一种权威性的电子文档,它提供了一种在互联网上验证身份的方式。数字证书对个人或组织的线上凭据与身份进行验证,并能让网络用户和接收者知道其所输入的数据将前往受信任的来源。它们类似于网站和用户的安全徽章,并有助于确保互联网的安全性。

数字证书由证书颁发机构(CA)所颁发,用于对线上数据进行加密。数字证书也称为公钥证书或身份证书。例如,TLS/SSL证书有两种用途:对网站、浏览器和Web服务器之间传输的数据进行加密和保护,以及有助于识别并验证网站所有者。

数字证书的基本架构是公开密钥PKI,即利用一对密钥实施加密和解密。其中密钥包括私钥和公钥,私钥主要用于签名和解密,由用户自定义,只有用户自己知道;公钥用于签名验证和加密,可被多个用户共享。

数字证书的应用非常广泛,例如在安全电子邮件中使用数字证书可以建构安全电子邮件证书,主要用户加密电子邮件的传输,保护电子邮件在传输和接收过程中的安全²。另外,数字证书也可以用于终端的保护,例如在电子商务的活动过程中安装了数字证书,那么即使其账户或者密码等个人信息被盗取,其账户中的信息与资金安全仍然能得到有效的保障。

数字签名工作原理

signature
signature

签名过程

  1. 利用签名哈希算法(例如 sha256 md5)计算包括证书颁发者信息、证书持有者信息、证书有效期、证书持有者公钥等在内的信息(如 x.509 的例子),生成证书摘要 α
  2. 颁发者生成一对私钥和公钥,然后使用私钥对指纹进行加密,得到的加密数据即为颁发者的数字签名γ
  3. 将数字签名γ附加到数字证书上,形成一个签名过的数字证书。
  4. 颁发者将签名过的数字证书和公钥一起交给证书持有者。

验签过程

  1. 使用者通过某种方式(例如,浏览器访问)获取签名过的数字证书,解析后可以得到数字签名γ和数字证书。
  2. 使用者使用数字证书中的指纹算法重新计算数字证书相关内容,生成一个新的指纹β
  3. 同时,使用者使用获取到的颁发者的公钥解密数字签名,得到解密后的指纹α
  4. 对比两个指纹αβ,如果相同,则证明证书是合法的,使用者可以信任并使用该证书中的信息(例如,持有者的公钥)。
例子:X.509 证书包含的信息
  1. 证书的版本信息
  2. 证书的序列号
  3. 证书所使用的签名算法
  4. 证书的发行机构名称
  5. 证书的有效期,现在通用的证书一般采用UTC时间格式,它的计时范围为1950-2049
  6. 证书所有人的名称
  7. 证书所有人的公开密钥
  8. 证书发行者对证书的签名

作用

  1. 数据加密:加密数据确保数据安全
  2. 身份确定:确保双方身份正确
  3. 不可篡改:无法修改已签名的文件
  4. 不可否认:CA 的监督下确保交易达成后不能否认未进行交易
',33),s=[l];function c(h,T){return r(),o("div",null,s)}const m=e(a,[["render",c],["__file","1-network.html.vue"]]),u=JSON.parse('{"path":"/guide/concepts/network/1-network.html","title":"计算机网络基础","lang":"zh-CN","frontmatter":{"order":1,"title":"计算机网络基础","description":"OSI七层模型 osiosi TCP和IP模型 HTTP 请求方法 相关信息 HTTP 1.0 支持三种请求方式: GET POST HEAD HTTP 1.1 额外支持 6 种请求方式 OPTIONS PUT PATCH DELETE TRACE CONNECT HTTP 状态码 常见状态码 HTTPS vs HTTP 工作原理 HTTPS 协议会对...","head":[["link",{"rel":"alternate","hreflang":"en-us","href":"https://goguide.ryansu.tech/en/guide/concepts/network/1-network.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/guide/concepts/network/1-network.html"}],["meta",{"property":"og:site_name","content":"Go 面试宝典"}],["meta",{"property":"og:title","content":"计算机网络基础"}],["meta",{"property":"og:description","content":"OSI七层模型 osiosi TCP和IP模型 HTTP 请求方法 相关信息 HTTP 1.0 支持三种请求方式: GET POST HEAD HTTP 1.1 额外支持 6 种请求方式 OPTIONS PUT PATCH DELETE TRACE CONNECT HTTP 状态码 常见状态码 HTTPS vs HTTP 工作原理 HTTPS 协议会对..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://goguide.ryansu.tech/assets/image/article/network/tcpip.png"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:locale:alternate","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-02-14T15:36:34.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"计算机网络基础"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-02-14T15:36:34.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"计算机网络基础\\",\\"image\\":[\\"https://goguide.ryansu.tech/assets/image/article/network/tcpip.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/httpsgraph.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/signature.png\\"],\\"dateModified\\":\\"2024-02-14T15:36:34.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":3,"title":"OSI七层模型","slug":"osi七层模型","link":"#osi七层模型","children":[]},{"level":3,"title":"TCP和IP模型","slug":"tcp和ip模型","link":"#tcp和ip模型","children":[]},{"level":3,"title":"HTTP","slug":"http","link":"#http","children":[{"level":4,"title":"HTTP 状态码","slug":"http-状态码","link":"#http-状态码","children":[]},{"level":4,"title":"HTTPS vs HTTP","slug":"https-vs-http","link":"#https-vs-http","children":[]},{"level":4,"title":"工作原理","slug":"工作原理","link":"#工作原理","children":[]}]},{"level":3,"title":"HTTP 1.0 vs 1.1 vs 2.0","slug":"http-1-0-vs-1-1-vs-2-0","link":"#http-1-0-vs-1-1-vs-2-0","children":[]},{"level":3,"title":"数字证书","slug":"数字证书","link":"#数字证书","children":[{"level":4,"title":"数字签名工作原理","slug":"数字签名工作原理","link":"#数字签名工作原理","children":[]}]}],"git":{"createdTime":1707924994000,"updatedTime":1707924994000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":1}]},"readingTime":{"minutes":11.19,"words":3357},"filePathRelative":"guide/concepts/network/1-network.md","localizedDate":"2024年2月14日","autoDesc":true,"excerpt":"

OSI七层模型

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
层级功能
物理层主要实现相邻节点间比特流的透明传输,物理层定义了物理设备的标准,如网线的类型等, 网卡也会在这层工作
数据链路层将网络层传下来的比特数据包组装成帧,并在相邻节点的链路上传送帧。数据链路层会将0、1序列划分为具有意义的数据帧传送给另一端。
网络层选择合适的路由和交换结点,能让数据及时传送,此层的数据称为数据包,要关注的是IP协议。
传输层向主机进程提供通用的数据传输服务。传输层需要关注的协议有TCP协议和UDP协议。
会话层负责在网络中的两节点之间建立、维持和终止通信,常见的协议有 ADSP、RPC 等。
表示层主要负责数据格式的转换,解决不同系统之间通信语法问题
应用层为应用程序提供交互服务,目的是更方便应用从网络中接收的数据,重点关注HTTP协议
"}');export{m as comp,u as data}; +import{_ as t,a as d}from"./signature-_OrRzcAy.js";import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as r,c as o,b as n}from"./app-C0BAr50I.js";const i="/assets/image/article/network/httpsgraph.png",a={},l=n('

OSI七层模型

层级功能
物理层主要实现相邻节点间比特流的透明传输,物理层定义了物理设备的标准,如网线的类型等, 网卡也会在这层工作
数据链路层将网络层传下来的比特数据包组装成帧,并在相邻节点的链路上传送帧。数据链路层会将0、1序列划分为具有意义的数据帧传送给另一端。
网络层选择合适的路由和交换结点,能让数据及时传送,此层的数据称为数据包,要关注的是IP协议。
传输层向主机进程提供通用的数据传输服务。传输层需要关注的协议有TCP协议和UDP协议。
会话层负责在网络中的两节点之间建立、维持和终止通信,常见的协议有 ADSP、RPC 等。
表示层主要负责数据格式的转换,解决不同系统之间通信语法问题
应用层为应用程序提供交互服务,目的是更方便应用从网络中接收的数据,重点关注HTTP协议
osi
osi

TCP和IP模型

OSI七层模型TCP/IP 五层模型TCP/IP 四层模型功能TCP/IP协议族
应用层应用层应用层文件传输,电子邮件,文件服务,虚拟终端等SMTP,DNS,Telnet,TFTP,HTTP,SNHP,FTP
表示层应用层应用层数据格式化,代码转换,数据加密
会话层应用层应用层解除或建立与别的接点的联系
传输层传输层传输层提供端对端的接口TCP,UDP
网络层网络层网络层为数据包选择路由IP,ICHP,RIP,OSPF,BCP,ICMF
数据链路层数据链路层网络接口层传输有地址的顿以及错误检测功能SLIP,CSLIP,PPP,ARP,RARP,MTU
物理层物理层网络接口层以二进制数据形式在物理媒介上传输数据IS02110,IEEE802,IEEE802.2

HTTP

请求方法

相关信息

HTTP 1.0 支持三种请求方式:

  • GET
  • POST
  • HEAD

HTTP 1.1 额外支持 6 种请求方式

  • OPTIONS
  • PUT
  • PATCH
  • DELETE
  • TRACE
  • CONNECT
方法描述
GET请求一个指定资源,用于获取数据
HEAD和 GET 类似,但是只返回响应头,不返回响应体
POST用于提交信息到目标地址,用于数据提交和文件上传
PUT提交更新的信息,用于替换原数据
DELETE删除指定的资源
CONNECT与服务器建立隧道
OPTIONS返回特定服务器地址所支持的 HTTP 请求方法, 也可用于测试服务器支持的功能
TRACE回显服务器收到的请求,主要用于测试或诊断
PATCHPUT 相似,主要用于部分更新

HTTP 状态码

数字含义
1XX指示信息,表示请求以接收,继续处理
2XX成功,表示请求已经被成功接收、理解、接受
3XX状态码表示客户端请求的资源发送了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向
4XX状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。
5XX状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码
常见状态码
HTTP 状态码名称描述
100Continue继续 表示客户端可以继续提交请求
101Switching Protocols切换协议 切换传输协议,只能从低版本切换到高版本,如 HTTP1.0 切换为 HTTP1.1
200OK请求成功 表示服务器成功返回了数据
201Created已创建 表示服务器成功接收到请求并创建了对应的资源
202Accepted已接受 表示服务器已经接受了请求,请求将会被处理
203Non-Authoritative Information非授权信息 表示请求成功,但返回的meta信息不在原始的服务器,而是一个副本
204No Content无内容 表示服务器成功处理请求
205Reset Content重置内容 服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206Partial Content部分内容服务器成功处理了部分GET请求
300Multiple Choices多种选择请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301Moved Permanently永久移动请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302Found临时移动与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303See Other查看其它地址与301类似。使用GET和POST请求查看
304Not Modified未修改 所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305Use Proxy使用代理 所请求的资源必须通过代理访问
307Temporary Redirect临时重定向与302类似。使用GET请求重定向
400Bad Request错误请求表示客户端请求的报文有错误
401Unauthorized未授权缺失或错误的认证,这个状态代码必须和WWW-Authenticate报头域一起使用
403Forbidden禁止访问表示服务器禁止访问资源,并不是客户端的请求出错
404Not Found未找到表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端
501Not Implemented功能未实现表示客户端请求的功能还不支持
502Bad Gateway网关错误通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误
503Service Unavailable服务器不可用表示服务器当前很忙,暂时无法响应服务器
504Gateway Timeout网关超时网关超时,由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答

HTTPS vs HTTP

特性HTTPHTTPS
定义HTTP 是超文本传输协议,用于从万维网服务器传输超文本到本地浏览器的传送协议。HTTPS 是带有安全性的 HTTP,通过 SSL/TLS 提供加密处理、数据完整性校验及身份认证。
端口默认的 HTTP 端口是 80。默认的 HTTPS 端口是 443。
安全性HTTP 本身不是安全的,因为数据在传输过程中没有加密,可能会被第三方获取。HTTPS 是安全的,因为数据在传输过程中会被加密,防止被第三方获取。
速度HTTP 相对较快,因为没有加密和解密的过程。HTTPS 相对较慢,因为数据在传输过程中需要进行加密和解密。

工作原理

HTTPS 协议会对传输的数据进行加密,而加密过程是使用了非对称加密实现

  1. Client发起一个HTTPS的请求
  2. Server把事先配置好的公钥证书返回给客户端。
  3. Client验证公钥证书:比如是否在有效期内,证书的用途是不是匹配Client请求的站点,是不是在CRL吊销列表里面,它的上一级证书是否有效,这是一个递归的过程,直到验证到根证书(操作系统内置的Root证书或者Client内置的Root证书),如果验证通过则继续,不通过则显示警告信息。
  4. Client使用伪随机数生成器生成加密所使用的对称密钥,然后用证书的公钥加密这个对称密钥,发给Server。
  5. Server使用自己的私钥解密这个消息,得到对称密钥。至此,ClientServer双方都持有了相同的对称密钥。
  6. Server使用对称密钥加密明文内容A,发送给Client
  7. Client使用对称密钥解密响应的密文,得到明文内容A
  8. Client再次发起HTTPS的请求,使用对称密钥加密请求的明文内容B,然后Server使用对称密钥解密密文,得到明文内容B
https
https

HTTP 1.0 vs 1.1 vs 2.0

区别

特性HTTP 1.0HTTP 1.1HTTP 2.0
连接方式无连接,每次请求都要建立连接长连接,减少了 TCP 连接的重复建立和断开所造成的额外开销多路复用,一个 TCP 连接上可以并发多个 HTTP 请求
队头阻塞存在,下一个请求必须在前一个请求响应到达之前才能发送存在,虽然可以发起多个请求,但服务器必须按照接收请求的顺序发送响应解决,可以在一个连接中并发多个请求或回应,而不用按照顺序一一对应
头部压缩不支持不支持支持,使用 HPACK 算法对 header 进行压缩
服务器推送不支持不支持支持

数字证书

数字证书是一种权威性的电子文档,它提供了一种在互联网上验证身份的方式。数字证书对个人或组织的线上凭据与身份进行验证,并能让网络用户和接收者知道其所输入的数据将前往受信任的来源。它们类似于网站和用户的安全徽章,并有助于确保互联网的安全性。

数字证书由证书颁发机构(CA)所颁发,用于对线上数据进行加密。数字证书也称为公钥证书或身份证书。例如,TLS/SSL证书有两种用途:对网站、浏览器和Web服务器之间传输的数据进行加密和保护,以及有助于识别并验证网站所有者。

数字证书的基本架构是公开密钥PKI,即利用一对密钥实施加密和解密。其中密钥包括私钥和公钥,私钥主要用于签名和解密,由用户自定义,只有用户自己知道;公钥用于签名验证和加密,可被多个用户共享。

数字证书的应用非常广泛,例如在安全电子邮件中使用数字证书可以建构安全电子邮件证书,主要用户加密电子邮件的传输,保护电子邮件在传输和接收过程中的安全²。另外,数字证书也可以用于终端的保护,例如在电子商务的活动过程中安装了数字证书,那么即使其账户或者密码等个人信息被盗取,其账户中的信息与资金安全仍然能得到有效的保障。

数字签名工作原理

signature
signature

签名过程

  1. 利用签名哈希算法(例如 sha256 md5)计算包括证书颁发者信息、证书持有者信息、证书有效期、证书持有者公钥等在内的信息(如 x.509 的例子),生成证书摘要 α
  2. 颁发者生成一对私钥和公钥,然后使用私钥对指纹进行加密,得到的加密数据即为颁发者的数字签名γ
  3. 将数字签名γ附加到数字证书上,形成一个签名过的数字证书。
  4. 颁发者将签名过的数字证书和公钥一起交给证书持有者。

验签过程

  1. 使用者通过某种方式(例如,浏览器访问)获取签名过的数字证书,解析后可以得到数字签名γ和数字证书。
  2. 使用者使用数字证书中的指纹算法重新计算数字证书相关内容,生成一个新的指纹β
  3. 同时,使用者使用获取到的颁发者的公钥解密数字签名,得到解密后的指纹α
  4. 对比两个指纹αβ,如果相同,则证明证书是合法的,使用者可以信任并使用该证书中的信息(例如,持有者的公钥)。
例子:X.509 证书包含的信息
  1. 证书的版本信息
  2. 证书的序列号
  3. 证书所使用的签名算法
  4. 证书的发行机构名称
  5. 证书的有效期,现在通用的证书一般采用UTC时间格式,它的计时范围为1950-2049
  6. 证书所有人的名称
  7. 证书所有人的公开密钥
  8. 证书发行者对证书的签名

作用

  1. 数据加密:加密数据确保数据安全
  2. 身份确定:确保双方身份正确
  3. 不可篡改:无法修改已签名的文件
  4. 不可否认:CA 的监督下确保交易达成后不能否认未进行交易
',33),s=[l];function c(h,T){return r(),o("div",null,s)}const m=e(a,[["render",c],["__file","1-network.html.vue"]]),u=JSON.parse('{"path":"/guide/concepts/network/1-network.html","title":"基础","lang":"zh-CN","frontmatter":{"order":1,"title":"基础","description":"OSI七层模型 osiosi TCP和IP模型 HTTP 请求方法 相关信息 HTTP 1.0 支持三种请求方式: GET POST HEAD HTTP 1.1 额外支持 6 种请求方式 OPTIONS PUT PATCH DELETE TRACE CONNECT HTTP 状态码 常见状态码 HTTPS vs HTTP 工作原理 HTTPS 协议会对...","head":[["link",{"rel":"alternate","hreflang":"en-us","href":"https://goguide.ryansu.tech/en/guide/concepts/network/1-network.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/guide/concepts/network/1-network.html"}],["meta",{"property":"og:site_name","content":"Go 面试宝典"}],["meta",{"property":"og:title","content":"基础"}],["meta",{"property":"og:description","content":"OSI七层模型 osiosi TCP和IP模型 HTTP 请求方法 相关信息 HTTP 1.0 支持三种请求方式: GET POST HEAD HTTP 1.1 额外支持 6 种请求方式 OPTIONS PUT PATCH DELETE TRACE CONNECT HTTP 状态码 常见状态码 HTTPS vs HTTP 工作原理 HTTPS 协议会对..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://goguide.ryansu.tech/assets/image/article/network/tcpip.png"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:locale:alternate","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-02-16T03:42:36.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"基础"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-02-16T03:42:36.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"基础\\",\\"image\\":[\\"https://goguide.ryansu.tech/assets/image/article/network/tcpip.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/httpsgraph.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/signature.png\\"],\\"dateModified\\":\\"2024-02-16T03:42:36.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":3,"title":"OSI七层模型","slug":"osi七层模型","link":"#osi七层模型","children":[]},{"level":3,"title":"TCP和IP模型","slug":"tcp和ip模型","link":"#tcp和ip模型","children":[]},{"level":3,"title":"HTTP","slug":"http","link":"#http","children":[{"level":4,"title":"HTTP 状态码","slug":"http-状态码","link":"#http-状态码","children":[]},{"level":4,"title":"HTTPS vs HTTP","slug":"https-vs-http","link":"#https-vs-http","children":[]},{"level":4,"title":"工作原理","slug":"工作原理","link":"#工作原理","children":[]}]},{"level":3,"title":"HTTP 1.0 vs 1.1 vs 2.0","slug":"http-1-0-vs-1-1-vs-2-0","link":"#http-1-0-vs-1-1-vs-2-0","children":[]},{"level":3,"title":"数字证书","slug":"数字证书","link":"#数字证书","children":[{"level":4,"title":"数字签名工作原理","slug":"数字签名工作原理","link":"#数字签名工作原理","children":[]}]}],"git":{"createdTime":1707924994000,"updatedTime":1708054956000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":2}]},"readingTime":{"minutes":11.17,"words":3352},"filePathRelative":"guide/concepts/network/1-network.md","localizedDate":"2024年2月14日","autoDesc":true,"excerpt":"

OSI七层模型

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
层级功能
物理层主要实现相邻节点间比特流的透明传输,物理层定义了物理设备的标准,如网线的类型等, 网卡也会在这层工作
数据链路层将网络层传下来的比特数据包组装成帧,并在相邻节点的链路上传送帧。数据链路层会将0、1序列划分为具有意义的数据帧传送给另一端。
网络层选择合适的路由和交换结点,能让数据及时传送,此层的数据称为数据包,要关注的是IP协议。
传输层向主机进程提供通用的数据传输服务。传输层需要关注的协议有TCP协议和UDP协议。
会话层负责在网络中的两节点之间建立、维持和终止通信,常见的协议有 ADSP、RPC 等。
表示层主要负责数据格式的转换,解决不同系统之间通信语法问题
应用层为应用程序提供交互服务,目的是更方便应用从网络中接收的数据,重点关注HTTP协议
"}');export{m as comp,u as data}; diff --git a/assets/2-datatype.html-B4Zluvs9.js b/assets/2-datatype.html-BBe-LqVn.js similarity index 99% rename from assets/2-datatype.html-B4Zluvs9.js rename to assets/2-datatype.html-BBe-LqVn.js index 93f5491e..f9f011b6 100644 --- a/assets/2-datatype.html-B4Zluvs9.js +++ b/assets/2-datatype.html-BBe-LqVn.js @@ -1,4 +1,4 @@ -import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as e,c as a,b as t}from"./app-Bsw6rBWV.js";const s={},i=t(`

Integers (int)

Integers come in two types:

TypeRangeDescription
Signed integers-∞ ~ +∞Signed integers include positive and negative numbers
Unsigned integers0 ~ +∞Unsigned integers include 0 and all positive numbers

In Golang, types starting with int are signed integers, and those starting with uint are unsigned integers.

Integer types in Golang:

BitsType
8int8 uint8
16int16 uint16
32int32 uint32
64int64 uint64
32 or 64 (based on system architecture)int uint

There are also two equivalent types:

  • rune: equivalent to int32 , used to store Unicode characters
  • byte: equivalent to uint8 , used to store ASCII characters

Floating-point Numbers (float)

Floating-point numbers are numbers that contain a decimal point.

BitsType
32float32
64float64

Complex Numbers (complex)

Complex numbers contain imaginary and real numbers, with the real part being a floating-point number.

BitsType
32-bit float + imaginarycomplex64
64-bit float + imaginarycomplex128
Example
// Initialize a complex number
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as e,c as a,b as t}from"./app-C0BAr50I.js";const s={},i=t(`

Integers (int)

Integers come in two types:

TypeRangeDescription
Signed integers-∞ ~ +∞Signed integers include positive and negative numbers
Unsigned integers0 ~ +∞Unsigned integers include 0 and all positive numbers

In Golang, types starting with int are signed integers, and those starting with uint are unsigned integers.

Integer types in Golang:

BitsType
8int8 uint8
16int16 uint16
32int32 uint32
64int64 uint64
32 or 64 (based on system architecture)int uint

There are also two equivalent types:

  • rune: equivalent to int32 , used to store Unicode characters
  • byte: equivalent to uint8 , used to store ASCII characters

Floating-point Numbers (float)

Floating-point numbers are numbers that contain a decimal point.

BitsType
32float32
64float64

Complex Numbers (complex)

Complex numbers contain imaginary and real numbers, with the real part being a floating-point number.

BitsType
32-bit float + imaginarycomplex64
64-bit float + imaginarycomplex128
Example
// Initialize a complex number
 var complexData complex64 = complex(5, 3) // Equals: 5 + 3i
 
 // Another way to initialize
diff --git a/assets/2-datatype.html-Bhx9jV3s.js b/assets/2-datatype.html-CPzWcUi9.js
similarity index 99%
rename from assets/2-datatype.html-Bhx9jV3s.js
rename to assets/2-datatype.html-CPzWcUi9.js
index 6fa73753..a6e038df 100644
--- a/assets/2-datatype.html-Bhx9jV3s.js
+++ b/assets/2-datatype.html-CPzWcUi9.js
@@ -1,4 +1,4 @@
-import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as t,b as s}from"./app-Bsw6rBWV.js";const e={},i=s(`

整数 (int)

整数有两种类型:

类型范围介绍
有符号数 (signed integers)-∞ ~ +∞有符号数包含正数和负数
无符号数 (unsigned integers)0 ~ +∞无符号数包含 0 和所有正数

golang 中 int 开头为有符号数, uint 开头为无符号数

Golang 中的整数类型:

类型
8int8 uint8
16int16 uint16
32int32 uint32
64int64 uint64
32 或 64 (基于系统架构)int uint

同时还有两个等价类型

  • rune : 等价于 int32 , 用于存储 Unicode 字符
  • byte :等价于 uint8 , 用于存储 ASCII 字符

浮点数 (float)

浮点数就是包含小数点的数字

类型
32float32
64float64

复数 (complex)

复数包含虚数和实数,实数为浮点数

类型
32 位浮点数 + 虚数complex64
64 位浮点数 + 虚数complex128
例子
// 初始化一个复数
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as t,b as s}from"./app-C0BAr50I.js";const e={},i=s(`

整数 (int)

整数有两种类型:

类型范围介绍
有符号数 (signed integers)-∞ ~ +∞有符号数包含正数和负数
无符号数 (unsigned integers)0 ~ +∞无符号数包含 0 和所有正数

golang 中 int 开头为有符号数, uint 开头为无符号数

Golang 中的整数类型:

类型
8int8 uint8
16int16 uint16
32int32 uint32
64int64 uint64
32 或 64 (基于系统架构)int uint

同时还有两个等价类型

  • rune : 等价于 int32 , 用于存储 Unicode 字符
  • byte :等价于 uint8 , 用于存储 ASCII 字符

浮点数 (float)

浮点数就是包含小数点的数字

类型
32float32
64float64

复数 (complex)

复数包含虚数和实数,实数为浮点数

类型
32 位浮点数 + 虚数complex64
64 位浮点数 + 虚数complex128
例子
// 初始化一个复数
 var complexData complex64 = complex(5, 3) // 等于: 5 + 3i
 
 // 另一种初始化方式
diff --git a/assets/2-medium.html-EVBDDzD_.js b/assets/2-medium.html-C1NwI0Ox.js
similarity index 99%
rename from assets/2-medium.html-EVBDDzD_.js
rename to assets/2-medium.html-C1NwI0Ox.js
index a119617e..a763271a 100644
--- a/assets/2-medium.html-EVBDDzD_.js
+++ b/assets/2-medium.html-C1NwI0Ox.js
@@ -1 +1 @@
-import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{r,o,c as s,a as e,e as d,f as i,b as t}from"./app-Bsw6rBWV.js";const c={},l=t('

Have you used context? What are the use cases for context?

Answer
ScenarioIntroduction
Timeout handlingBy using context, you can easily set a timeout, and the coroutine will automatically terminate after the timeout
Terminate coroutineBy using the cancel() method, coroutines can be easily terminated
Data transferWe can write data into context to transfer data between different coroutines

Is channel thread-safe?

Answer

channel is thread-safe, the reason is that channel has implemented a lock mechanism internally,

Is the traversal of a Map using range ordered or unordered?

Answer

Unordered

Internally, Map uses a hash algorithm to place elements. When it automatically expands, it recalculates the hash values, so the addresses of the elements keep changing. To prevent users from thinking that the arrangement of Map elements is ordered, it directly returns in a random order, so the traversal is unordered.

Is Map concurrency-safe?

Answer

Map cannot guarantee concurrency safety

To ensure concurrency safety, use the following methods:

  • Manually add read-write locks
  • Use sync.Map

Will the memory of a key be released after the key is deleted from the Map?

',9),h={class:"hint-container details"},u=t("Answer

If the value of the map is

  • Value type (int uint float32 string struct{}...), then the value will not be garbage collected after the key is deleted
  • Reference type (map slices chan ...), then the value will be garbage collected after the key is deleted

If we want to force garbage collection, how do we operate?

  • Set the map to nil
  • Place the values that need to be retained in a new map and assign it to the current map
",5),m={class:"hint-container tip"},p=e("p",{class:"hint-container-title"},"Exclusive for members",-1),f={href:"https://articles.zsxq.com/id_4w1a11i6xrw0.html",target:"_blank",rel:"noopener noreferrer"};function y(g,b){const a=r("ExternalLinkIcon");return o(),s("div",null,[l,e("details",h,[u,e("div",m,[p,e("p",null,[e("a",f,[d("Code combat analysis"),i(a)])])])])])}const v=n(c,[["render",y],["__file","2-medium.html.vue"]]),k=JSON.parse('{"path":"/en/guide/interview/golang/basic/2-medium.html","title":"Medium","lang":"en-US","frontmatter":{"order":2,"title":"Medium","description":"Have you used context? What are the use cases for context? Answer Is channel thread-safe? Answer channel is thread-safe, the reason is that channel has implemented a lock mechan...","head":[["link",{"rel":"alternate","hreflang":"zh-cn","href":"https://goguide.ryansu.tech/guide/interview/golang/basic/2-medium.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/en/guide/interview/golang/basic/2-medium.html"}],["meta",{"property":"og:site_name","content":"Go Guide"}],["meta",{"property":"og:title","content":"Medium"}],["meta",{"property":"og:description","content":"Have you used context? What are the use cases for context? Answer Is channel thread-safe? Answer channel is thread-safe, the reason is that channel has implemented a lock mechan..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:locale:alternate","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-01-31T03:45:48.000Z"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-01-31T03:45:48.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Medium\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-01-31T03:45:48.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":3,"title":"Have you used context? What are the use cases for context?","slug":"have-you-used-context-what-are-the-use-cases-for-context","link":"#have-you-used-context-what-are-the-use-cases-for-context","children":[]},{"level":3,"title":"Is channel thread-safe?","slug":"is-channel-thread-safe","link":"#is-channel-thread-safe","children":[]},{"level":3,"title":"Is the traversal of a Map using range ordered or unordered?","slug":"is-the-traversal-of-a-map-using-range-ordered-or-unordered","link":"#is-the-traversal-of-a-map-using-range-ordered-or-unordered","children":[]},{"level":3,"title":"Is Map concurrency-safe?","slug":"is-map-concurrency-safe","link":"#is-map-concurrency-safe","children":[]},{"level":3,"title":"Will the memory of a key be released after the key is deleted from the Map?","slug":"will-the-memory-of-a-key-be-released-after-the-key-is-deleted-from-the-map","link":"#will-the-memory-of-a-key-be-released-after-the-key-is-deleted-from-the-map","children":[]}],"git":{"createdTime":1705721989000,"updatedTime":1706672748000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":4}]},"readingTime":{"minutes":0.95,"words":285},"filePathRelative":"en/guide/interview/golang/basic/2-medium.md","localizedDate":"January 20, 2024","autoDesc":true,"excerpt":"

Have you used context? What are the use cases for context?

\\n
Answer\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
ScenarioIntroduction
Timeout handlingBy using context, you can easily set a timeout, and the coroutine will automatically terminate after the timeout
Terminate coroutineBy using the cancel() method, coroutines can be easily terminated
Data transferWe can write data into context to transfer data between different coroutines
\\n
"}');export{v as comp,k as data}; +import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{r,o,c as s,a as e,e as d,f as i,b as t}from"./app-C0BAr50I.js";const c={},l=t('

Have you used context? What are the use cases for context?

Answer
ScenarioIntroduction
Timeout handlingBy using context, you can easily set a timeout, and the coroutine will automatically terminate after the timeout
Terminate coroutineBy using the cancel() method, coroutines can be easily terminated
Data transferWe can write data into context to transfer data between different coroutines

Is channel thread-safe?

Answer

channel is thread-safe, the reason is that channel has implemented a lock mechanism internally,

Is the traversal of a Map using range ordered or unordered?

Answer

Unordered

Internally, Map uses a hash algorithm to place elements. When it automatically expands, it recalculates the hash values, so the addresses of the elements keep changing. To prevent users from thinking that the arrangement of Map elements is ordered, it directly returns in a random order, so the traversal is unordered.

Is Map concurrency-safe?

Answer

Map cannot guarantee concurrency safety

To ensure concurrency safety, use the following methods:

  • Manually add read-write locks
  • Use sync.Map

Will the memory of a key be released after the key is deleted from the Map?

',9),h={class:"hint-container details"},u=t("Answer

If the value of the map is

  • Value type (int uint float32 string struct{}...), then the value will not be garbage collected after the key is deleted
  • Reference type (map slices chan ...), then the value will be garbage collected after the key is deleted

If we want to force garbage collection, how do we operate?

  • Set the map to nil
  • Place the values that need to be retained in a new map and assign it to the current map
",5),m={class:"hint-container tip"},p=e("p",{class:"hint-container-title"},"Exclusive for members",-1),f={href:"https://articles.zsxq.com/id_4w1a11i6xrw0.html",target:"_blank",rel:"noopener noreferrer"};function y(g,b){const a=r("ExternalLinkIcon");return o(),s("div",null,[l,e("details",h,[u,e("div",m,[p,e("p",null,[e("a",f,[d("Code combat analysis"),i(a)])])])])])}const v=n(c,[["render",y],["__file","2-medium.html.vue"]]),k=JSON.parse('{"path":"/en/guide/interview/golang/basic/2-medium.html","title":"Medium","lang":"en-US","frontmatter":{"order":2,"title":"Medium","description":"Have you used context? What are the use cases for context? Answer Is channel thread-safe? Answer channel is thread-safe, the reason is that channel has implemented a lock mechan...","head":[["link",{"rel":"alternate","hreflang":"zh-cn","href":"https://goguide.ryansu.tech/guide/interview/golang/basic/2-medium.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/en/guide/interview/golang/basic/2-medium.html"}],["meta",{"property":"og:site_name","content":"Go Guide"}],["meta",{"property":"og:title","content":"Medium"}],["meta",{"property":"og:description","content":"Have you used context? What are the use cases for context? Answer Is channel thread-safe? Answer channel is thread-safe, the reason is that channel has implemented a lock mechan..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:locale:alternate","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-01-31T03:45:48.000Z"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-01-31T03:45:48.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Medium\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-01-31T03:45:48.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":3,"title":"Have you used context? What are the use cases for context?","slug":"have-you-used-context-what-are-the-use-cases-for-context","link":"#have-you-used-context-what-are-the-use-cases-for-context","children":[]},{"level":3,"title":"Is channel thread-safe?","slug":"is-channel-thread-safe","link":"#is-channel-thread-safe","children":[]},{"level":3,"title":"Is the traversal of a Map using range ordered or unordered?","slug":"is-the-traversal-of-a-map-using-range-ordered-or-unordered","link":"#is-the-traversal-of-a-map-using-range-ordered-or-unordered","children":[]},{"level":3,"title":"Is Map concurrency-safe?","slug":"is-map-concurrency-safe","link":"#is-map-concurrency-safe","children":[]},{"level":3,"title":"Will the memory of a key be released after the key is deleted from the Map?","slug":"will-the-memory-of-a-key-be-released-after-the-key-is-deleted-from-the-map","link":"#will-the-memory-of-a-key-be-released-after-the-key-is-deleted-from-the-map","children":[]}],"git":{"createdTime":1705721989000,"updatedTime":1706672748000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":4}]},"readingTime":{"minutes":0.95,"words":285},"filePathRelative":"en/guide/interview/golang/basic/2-medium.md","localizedDate":"January 20, 2024","autoDesc":true,"excerpt":"

Have you used context? What are the use cases for context?

\\n
Answer\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
ScenarioIntroduction
Timeout handlingBy using context, you can easily set a timeout, and the coroutine will automatically terminate after the timeout
Terminate coroutineBy using the cancel() method, coroutines can be easily terminated
Data transferWe can write data into context to transfer data between different coroutines
\\n
"}');export{v as comp,k as data}; diff --git a/assets/2-medium.html-CUT2Gn3u.js b/assets/2-medium.html-cqpOA0o-.js similarity index 98% rename from assets/2-medium.html-CUT2Gn3u.js rename to assets/2-medium.html-cqpOA0o-.js index b1840f39..54ad51d2 100644 --- a/assets/2-medium.html-CUT2Gn3u.js +++ b/assets/2-medium.html-cqpOA0o-.js @@ -1 +1 @@ -import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{r as o,o as c,c as r,a as e,e as i,f as d,b as t}from"./app-Bsw6rBWV.js";const l={},s=t('

使用过 context 吗? context 有哪些使用场景?

答案
场景介绍
超时处理通过使用 context 可以方便地设置超时时间,在超时后自动终止协程
终止协程通过使用 cancel() 方法,协程可以很方便地终止
传递数据我们可以将数据写入 context, 在不同协程间传递数据

channel 是线程安全的吗?

答案

channel 是线程安全的,原因是 channel 内部实现了锁的机制,

Map 使用 range 遍历时是有序还是无序的?

答案

无序的

Map 在内部使用哈希算法放置元素,在自动扩容时又会重新计算哈希值,因此元素的地址会不断变化,官方为了避免用户认为 Map 元素排列是有序的,直接采用随机顺序返回,所以遍历是无序的。

Map 并发安全吗?

答案

Map不能保证并发安全

要保证并发安全,使用以下方式:

  • 手动加读写锁
  • 使用 sync.Map

Map 的 key 删除后 key 的内存会被释放吗?

',9),p={class:"hint-container details"},h=t("答案

若 map 的 value 为

  • 值类型 (int uint float32 string struct{}...), 则 key 被删除后 value 不会被内存回收
  • 引用类型 (map slices chan ...), 则 key 被删除后 value 会被内存回收

如果我们想强制回收,如何操作?

  • 将 map 设置为 nil
  • 将 map 需要保留的值放置到一个新的 map 并赋值给当前的 map
",5),m={class:"hint-container tip"},u=e("p",{class:"hint-container-title"},"会员专属",-1),g={href:"https://articles.zsxq.com/id_4w1a11i6xrw0.html",target:"_blank",rel:"noopener noreferrer"};function y(x,_){const a=o("ExternalLinkIcon");return c(),r("div",null,[s,e("details",p,[h,e("div",m,[u,e("p",null,[e("a",g,[i("代码实战解析"),d(a)])])])])])}const f=n(l,[["render",y],["__file","2-medium.html.vue"]]),v=JSON.parse('{"path":"/guide/interview/golang/basic/2-medium.html","title":"进阶","lang":"zh-CN","frontmatter":{"order":2,"title":"进阶","description":"使用过 context 吗? context 有哪些使用场景? 答案 channel 是线程安全的吗? 答案 channel 是线程安全的,原因是 channel 内部实现了锁的机制, Map 使用 range 遍历时是有序还是无序的? 答案 无序的 Map 在内部使用哈希算法放置元素,在自动扩容时又会重新计算哈希值,因此元素的地址会不断变化,官方为了...","head":[["link",{"rel":"alternate","hreflang":"en-us","href":"https://goguide.ryansu.tech/en/guide/interview/golang/basic/2-medium.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/guide/interview/golang/basic/2-medium.html"}],["meta",{"property":"og:site_name","content":"Go 面试宝典"}],["meta",{"property":"og:title","content":"进阶"}],["meta",{"property":"og:description","content":"使用过 context 吗? context 有哪些使用场景? 答案 channel 是线程安全的吗? 答案 channel 是线程安全的,原因是 channel 内部实现了锁的机制, Map 使用 range 遍历时是有序还是无序的? 答案 无序的 Map 在内部使用哈希算法放置元素,在自动扩容时又会重新计算哈希值,因此元素的地址会不断变化,官方为了..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:locale:alternate","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-01-31T03:45:48.000Z"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-01-31T03:45:48.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"进阶\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-01-31T03:45:48.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":3,"title":"使用过 context 吗? context 有哪些使用场景?","slug":"使用过-context-吗-context-有哪些使用场景","link":"#使用过-context-吗-context-有哪些使用场景","children":[]},{"level":3,"title":"channel 是线程安全的吗?","slug":"channel-是线程安全的吗","link":"#channel-是线程安全的吗","children":[]},{"level":3,"title":"Map 使用 range 遍历时是有序还是无序的?","slug":"map-使用-range-遍历时是有序还是无序的","link":"#map-使用-range-遍历时是有序还是无序的","children":[]},{"level":3,"title":"Map 并发安全吗?","slug":"map-并发安全吗","link":"#map-并发安全吗","children":[]},{"level":3,"title":"Map 的 key 删除后 key 的内存会被释放吗?","slug":"map-的-key-删除后-key-的内存会被释放吗","link":"#map-的-key-删除后-key-的内存会被释放吗","children":[]}],"git":{"createdTime":1705721989000,"updatedTime":1706672748000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":4}]},"readingTime":{"minutes":1.31,"words":393},"filePathRelative":"guide/interview/golang/basic/2-medium.md","localizedDate":"2024年1月20日","autoDesc":true,"excerpt":"

使用过 context 吗? context 有哪些使用场景?

\\n
答案\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
场景介绍
超时处理通过使用 context 可以方便地设置超时时间,在超时后自动终止协程
终止协程通过使用 cancel() 方法,协程可以很方便地终止
传递数据我们可以将数据写入 context, 在不同协程间传递数据
\\n
"}');export{f as comp,v as data}; +import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{r as o,o as c,c as r,a as e,e as i,f as d,b as t}from"./app-C0BAr50I.js";const l={},s=t('

使用过 context 吗? context 有哪些使用场景?

答案
场景介绍
超时处理通过使用 context 可以方便地设置超时时间,在超时后自动终止协程
终止协程通过使用 cancel() 方法,协程可以很方便地终止
传递数据我们可以将数据写入 context, 在不同协程间传递数据

channel 是线程安全的吗?

答案

channel 是线程安全的,原因是 channel 内部实现了锁的机制,

Map 使用 range 遍历时是有序还是无序的?

答案

无序的

Map 在内部使用哈希算法放置元素,在自动扩容时又会重新计算哈希值,因此元素的地址会不断变化,官方为了避免用户认为 Map 元素排列是有序的,直接采用随机顺序返回,所以遍历是无序的。

Map 并发安全吗?

答案

Map不能保证并发安全

要保证并发安全,使用以下方式:

  • 手动加读写锁
  • 使用 sync.Map

Map 的 key 删除后 key 的内存会被释放吗?

',9),p={class:"hint-container details"},h=t("答案

若 map 的 value 为

  • 值类型 (int uint float32 string struct{}...), 则 key 被删除后 value 不会被内存回收
  • 引用类型 (map slices chan ...), 则 key 被删除后 value 会被内存回收

如果我们想强制回收,如何操作?

  • 将 map 设置为 nil
  • 将 map 需要保留的值放置到一个新的 map 并赋值给当前的 map
",5),m={class:"hint-container tip"},u=e("p",{class:"hint-container-title"},"会员专属",-1),g={href:"https://articles.zsxq.com/id_4w1a11i6xrw0.html",target:"_blank",rel:"noopener noreferrer"};function y(x,_){const a=o("ExternalLinkIcon");return c(),r("div",null,[s,e("details",p,[h,e("div",m,[u,e("p",null,[e("a",g,[i("代码实战解析"),d(a)])])])])])}const f=n(l,[["render",y],["__file","2-medium.html.vue"]]),v=JSON.parse('{"path":"/guide/interview/golang/basic/2-medium.html","title":"进阶","lang":"zh-CN","frontmatter":{"order":2,"title":"进阶","description":"使用过 context 吗? context 有哪些使用场景? 答案 channel 是线程安全的吗? 答案 channel 是线程安全的,原因是 channel 内部实现了锁的机制, Map 使用 range 遍历时是有序还是无序的? 答案 无序的 Map 在内部使用哈希算法放置元素,在自动扩容时又会重新计算哈希值,因此元素的地址会不断变化,官方为了...","head":[["link",{"rel":"alternate","hreflang":"en-us","href":"https://goguide.ryansu.tech/en/guide/interview/golang/basic/2-medium.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/guide/interview/golang/basic/2-medium.html"}],["meta",{"property":"og:site_name","content":"Go 面试宝典"}],["meta",{"property":"og:title","content":"进阶"}],["meta",{"property":"og:description","content":"使用过 context 吗? context 有哪些使用场景? 答案 channel 是线程安全的吗? 答案 channel 是线程安全的,原因是 channel 内部实现了锁的机制, Map 使用 range 遍历时是有序还是无序的? 答案 无序的 Map 在内部使用哈希算法放置元素,在自动扩容时又会重新计算哈希值,因此元素的地址会不断变化,官方为了..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:locale:alternate","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-01-31T03:45:48.000Z"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-01-31T03:45:48.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"进阶\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-01-31T03:45:48.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":3,"title":"使用过 context 吗? context 有哪些使用场景?","slug":"使用过-context-吗-context-有哪些使用场景","link":"#使用过-context-吗-context-有哪些使用场景","children":[]},{"level":3,"title":"channel 是线程安全的吗?","slug":"channel-是线程安全的吗","link":"#channel-是线程安全的吗","children":[]},{"level":3,"title":"Map 使用 range 遍历时是有序还是无序的?","slug":"map-使用-range-遍历时是有序还是无序的","link":"#map-使用-range-遍历时是有序还是无序的","children":[]},{"level":3,"title":"Map 并发安全吗?","slug":"map-并发安全吗","link":"#map-并发安全吗","children":[]},{"level":3,"title":"Map 的 key 删除后 key 的内存会被释放吗?","slug":"map-的-key-删除后-key-的内存会被释放吗","link":"#map-的-key-删除后-key-的内存会被释放吗","children":[]}],"git":{"createdTime":1705721989000,"updatedTime":1706672748000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":4}]},"readingTime":{"minutes":1.31,"words":393},"filePathRelative":"guide/interview/golang/basic/2-medium.md","localizedDate":"2024年1月20日","autoDesc":true,"excerpt":"

使用过 context 吗? context 有哪些使用场景?

\\n
答案\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
场景介绍
超时处理通过使用 context 可以方便地设置超时时间,在超时后自动终止协程
终止协程通过使用 cancel() 方法,协程可以很方便地终止
传递数据我们可以将数据写入 context, 在不同协程间传递数据
\\n
"}');export{f as comp,v as data}; diff --git a/assets/2-tcp-udp.html-BABQQ_zo.js b/assets/2-tcp-udp.html-BABQQ_zo.js new file mode 100644 index 00000000..5b2bd4e6 --- /dev/null +++ b/assets/2-tcp-udp.html-BABQQ_zo.js @@ -0,0 +1 @@ +import{_ as a,a as c,b as o,c as r}from"./sack-B470dwkI.js";import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{r as l,o as p,c as h,a as t,e,f as i,b as d}from"./app-C0BAr50I.js";const g="/assets/image/article/network/tcp.png",u="/assets/image/article/network/tcp_state.png",m="/assets/image/article/network/tcp-send-window.png",C="/assets/image/article/network/tcp-receive-window.png",T="/assets/image/article/network/tcp-congestion-control.png",P="/assets/image/article/network/udp.png",f={},y=d('

TCP

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

TCP 头部结构

tcp 头部
tcp 头部
TCP头部字段描述
源端口发送方的端口号,范围(0~65535)
目标端口接收方的端口号,范围(0~65535)
序列号如果TCP数据过大(大于IP数据包的允许程度),则需要进行分段。这个序列号记录每个数据包的序列号,使接收端可以重新组合TCP数据。序列号字段的值是本报文段发送的数据的第一个字节的序列号。简称为seq
确认号为了确认接收端确实收到了发送端发送的数据包数据,当发送端收到这个确认码时,就可以确定之前传递的数据包已经被正确接收。这个确认号是期望收到对方下一个报文段的数据的第一个字节的序列号。简称ack
头部长度表示TCP头部的长度,范围(0~15),单位32位,例如值为5时,表示头部长度是20字节(160位),如果选项字段为空,则TCP头部长度为20字节,即值为5
URGURG=1表示存在紧急数据,紧急数据的最后一个字节由紧急数据指针指出,一般使用较少
ACKACK=1表示确认号字段中的值是有效的,为0表示无效
PSHURG=1表示紧急指针字段有效,代表该数据包为紧急数据包。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)
RSTRSP=1表示重建连接,如果接收到RST位时,通常发生了某些错误
SYNSYN=1表示这是一个连接请求或连接接受报文,一般用于握手阶段
FINFIN=1表示此报文段的发送端的数据已发送完毕,并要求释放运输连接
接收窗口用于流量控制,指示接收方愿意接收的字节数量,范围0~65535字节
校验和校验和覆盖了整个TCP报文段,即TCP头部和TCP数据,这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证
紧急数据指针URG=1时有效,是一个正的偏移量,和序列号中的值相加表示紧急数据最后一个字节的序列号
选项用于发送方和接收方协商最大报文长度(MSS)时(只存在于SYN报文)或在高速网络环境下用作窗口调节因子时使用,还可以存放时间戳数据

TCP 状态机

TCP Stateful
TCP Stateful

TCP 三次握手/四次挥手

TCP Connection
TCP Connection

三次握手过程

  1. 客户端发送SYN=1,并指明客户端的初始序列号ISN,即x.
  2. 服务端发送自己的SYN段作为应答,同样指明自己的ISNy。为了确认客户端的SYN,将x+1作为ACK数值。这样,每发送一个SYN,序列号就会加1. 如果有丢失的情况,则会重传。
  3. 为了确认服务器端的SYN,客户端将y+1作为返回的ACK数值。

TCP 四次挥手

  1. 客户端发送FIN=1,并包含一个自己当前的序列号x+2。 同时还包含一个ACK=y+1表示确认对方最近一次发过来的数据。
  2. 服务端将x+2值加1作为ACK序号值,表明收到了上一个包。这时上层的应用程序会被告知另一端发起了关闭操作,通常这将引起应用程序发起自己的关闭操作。
  3. 服务端发起自己的FIN=1seq=y+1
  4. 客户端确认, 向服务器发送 ACK=y+2

为什么要三次握手?作用是什么?

详情

TCP 建立连接的过程就是同步序列号的过程,SYN (Synchronize Sequence Numbers)就是同步序列号。因此,三次握手的目的就是使客户端(Client)和服务端(Service)获取到对方的序列号。

为什么要四次挥手?作用是什么?

详情

之所以需要四次挥手,是因为 tcp 是全双工协议,即客户端和服务端都可以主动发送消息,因此需要两端分别在传输完成后发送断开连接的指令,需要分别发送 FIN=1 指令断开,通过 ACK 判断是否发送成功。

如果连接时 SYN 超时会发生什么?

详情

假如客户端发送 SYN 指令,在服务器返回 SYN 指令之前掉线了,服务器会尝试重发 SYN-ACK 指令,linux 下默认重试 5 次,间隔时间从 1s 开始翻倍增长,即 1s, 2s, 4s, 8s, 16s, 因此超时时间为 1s + 2s + 4s+ 8s+ 16s + 32s = 63s。在超时之后 TCP 才会断开连接。

TCP 如何保证传输的可靠性?

TCP 通过以下几个特性保证数据传输的可靠性

  • 序列号和确认应答
  • 超时重传
  • 流量控制
  • 拥塞控制
  • 校验和
序列号和确认应答信号

TCP 通过序列号可以对数据包进行排序和去重,同时通过 ACK 应答机制确保数据包成功送达,保证了数据的完整性。

超时重传

TCP 通过超时重传机制可以在数据包丢失或者延迟时,重新发送数据包直到收到 ACK 应答。

什么是RTT?什么是RTO?

详情

RTT代表往返时间(Round Trip Time),是指数据从发送方传输到接收方并返回所需的时间。RTT用于衡量网络延迟,即数据在传输过程中经过的总时间。

RTO代表重传超时时间(Retransmission Timeout),是指在网络通信中,发送方发送数据后等待确认(ACK)的时间。如果发送方在RTO时间内未收到确认,它会假设数据丢失,并重新发送该数据。

RTO的计算通常基于RTT的测量。发送方根据前一次的RTT来估计下一次发送数据的RTO。一般情况下,RTO的值会比RTT大一些,以确保在网络延迟较高或不稳定的情况下也能够成功重传数据。

RTO的计算方法可以根据具体的网络协议或实现而有所不同,但其目的是为了确保数据的可靠传输,以应对网络中的丢包、延迟和拥塞等问题。

RTO 长短对重传有什么影响?

详情

若 RTO 过长则重传时间会大大延长,降低传输效率。若 RTO 过短则可能会导致频繁重传,加剧网络的拥堵,进一步触发更多的重传。

',22),_={class:"hint-container tip"},w=t("p",{class:"hint-container-title"},"常见的重传机制",-1),S={class:"hint-container details"},b=d('详情
  • 超时重传
timeout retransmission
timeout retransmission

超时重传有两种情况,发送的数据包丢失导致的超时,和返回的 ACK 数据包丢失导致的超时。超时重传机制下,在每次发送数据包的时候都会启动一个定时器,如果定时器到期则会触发重传。若重传失败,则下一次超时时间为当前值的两倍。超时重传的缺点是周期较长,可能会降低效率。

  • 快速重传
tcp
tcp

在快速重传机制下,在数据包丢失后,接收端每接收一个失序的数据包就立即返回重复的确认报文段,告知发送端缺少的报文段。当发送方收到三个重复的确认报文段后,会立即重传缺失的报文段。

在快速重传的机制下,我们可以看到 3,4,5 的报文段返回的都是 ACK=2, 因此还需要重传 3,4,5 报文段。有没有方法可以不需要重传 3,4,5 报文段?

  • SACK (Selective Acknowledgment, 选择性确认)
SACK
SACK
',10),k={href:"https://www.ietf.org/rfc/rfc2883.txt",target:"_blank",rel:"noopener noreferrer"},v=t("ul",null,[t("li",null,"D-SACK (Duplicate SACK, 重复选择性确认)")],-1),x={href:"https://datatracker.ietf.org/doc/html/rfc2018",target:"_blank",rel:"noopener noreferrer"},R=d('

流量控制

TCP 使用滑动窗口来控制流量,使得发送端可以根据接收端的接收能力控制发送数据的速度。

发送窗口(窗口大小为 7)接收窗口(窗口大小为 7)

注意

接收端在应答 ACK 的时候会将当前可用的窗口大小写入 tcp 头部,发送端根据窗口大小调整发送速率。

拥塞控制

算法

  • 慢开始
  • 拥塞避免
  • 快重传
  • 快恢复
拥塞控制
拥塞控制

相关名词

  • cwnd - 拥塞窗口
  • ssthresh - 慢开始门限

重要

  • cwnd < ssthresh,使用慢开始算法。

  • cwnd > ssthresh,使用拥塞避免算法。

  • cwnd = ssthresh,使用慢开始与拥塞避免算法任意一个。

慢开始

在慢开始阶段, cwnd 初始值为 1, 每经过一个传播轮次,cwnd 都会翻倍,直到达到 ssthresh

拥塞避免

cwnd 达到 ssthresh ,则会执行拥塞避免算法,此时 cwnd 的增长从翻倍增长变为每经过一个传播轮次就加 1 。若发送方检测到网络拥塞(即发送的消息没得到及时的回应),就会将 ssthresh 设置为发生网络拥塞时的 cwnd 值的一半,同时 cwnd 的值将会重置为 1 ,重新执行慢开始。

快重传和快恢复

快重传在前面已介绍过,即如果连续收到三个重复的确认就会立即发送尚未接收到的报文段。快恢复算法需要配合快重传算法使用。图中的 5 号为快恢复阶段。

快恢复算法

  • 当发送端连续收到三个重复的确认时,将 ssthresh 减半。
  • cwnd 设置为 ssthresh 的大小

校验和

TCP 还会对数据计算校验和,确保数据在传输过程中未丢失或出现错误。

UDP

UDP,全称用户数据报协议(User Datagram Protocol),是OSI(开放系统互联)参考模型中的一种无连接的传输层协议。它提供面向事务的简单不可靠信息传送服务,其正式规范是 IETF RFC 768

特点

  • 无连接:UDP在传输数据前不需要在客户和服务器之间建立一个连接。
  • 速度快:由于UDP不需要进行握手或检查数据是否正确到达,所以它能够比TCP更快地传输数据。
  • 不可靠性:当报文发送之后,是无法得知其是否安全完整到达的。如果UDP数据报在传输过程中丢失,它不会重新发送。
  • 应用广泛:UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。例如,许多互联网电话服务使用的IP语音 (VoIP) 通常是使用UDP发送的。

结构

udp
udp
字段大小描述
源端口16位源端口号。若全为 0 则意味着不允许回信
目的端口16位目标端口号
长度16位UDP用户数据报的长度,其最小值是8(仅有首部)
检验和16位检测数据在传输过程中是否丢失或修改

广播类型

类型描述
单播用于两个主机之间端对端的通信。即一对一(客户端与服务器端点到点连接)
广播用于一个主机对整个局域网上所有主机通信。即一对所有。广播禁止在Internet宽带网上传输(广播风暴)
组播(多播)对一组特定的主机进行通信,而不是整个局域网上的所有主机。即一对一组

注意

  • TCP 只支持一对一
  • UDP 多播较为常用,广播仅用于局域网

TCP 和 UDP 区别

特性TCPUDP
可靠传输
连接面向连接无连接
数据有序性不保证
数据边界不保存保留
传输速度相对慢
流量控制和拥塞控制没有
协议类型重量级轻量级
首部长度20字节8字节
',29);function N(A,K){const n=l("ExternalLinkIcon");return p(),h("div",null,[y,t("div",_,[w,t("details",S,[b,t("p",null,[e("SACK 方法 ("),t("a",k,[e("RFC 2018"),i(n)]),e(") 在 tcp 的 option 字段添加了缓冲区,用于记录已传输的数据包,这样发送方可以看到未成功传输的数据包,使得发送方可以仅传输缺失的数据包而不需要额外重传其他数据包。")]),v,t("p",null,[e("D-SACK ("),t("a",x,[e("RFC 2883"),i(n)]),e(") 主要解决了 ACK 丢失的问题, D-SACK 使用 SACK 第一个段作为标志位,用于标记已经 ACK 的数据包。 当接收端接收到重复的报文段时会将该报文段写入 D-SACK 的标志位,告诉发送方已接收到报文段, ACK 可能已丢失。")])])]),R])}const Y=s(f,[["render",N],["__file","2-tcp-udp.html.vue"]]),z=JSON.parse('{"path":"/guide/concepts/network/2-tcp-udp.html","title":"TCP/UDP","lang":"zh-CN","frontmatter":{"order":2,"title":"TCP/UDP","description":"TCP 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。 TCP 头部结构 tcp 头部tcp 头部 TCP 状态机 TCP StatefulTCP Stateful TCP 三次握手/四次挥手 TCP ConnectionTCP Connection 三次握手过程...","head":[["link",{"rel":"alternate","hreflang":"en-us","href":"https://goguide.ryansu.tech/en/guide/concepts/network/2-tcp-udp.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/guide/concepts/network/2-tcp-udp.html"}],["meta",{"property":"og:site_name","content":"Go 面试宝典"}],["meta",{"property":"og:title","content":"TCP/UDP"}],["meta",{"property":"og:description","content":"TCP 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。 TCP 头部结构 tcp 头部tcp 头部 TCP 状态机 TCP StatefulTCP Stateful TCP 三次握手/四次挥手 TCP ConnectionTCP Connection 三次握手过程..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://goguide.ryansu.tech/assets/image/article/network/tcp.png"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:locale:alternate","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-02-16T03:42:36.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"TCP/UDP"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-02-16T03:42:36.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"TCP/UDP\\",\\"image\\":[\\"https://goguide.ryansu.tech/assets/image/article/network/tcp.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp_state.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-connect.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/timeout-retransmission.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-3-retry-new.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/sack.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-send-window.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-receive-window.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-congestion-control.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/udp.png\\"],\\"dateModified\\":\\"2024-02-16T03:42:36.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":3,"title":"TCP","slug":"tcp","link":"#tcp","children":[{"level":4,"title":"TCP 头部结构","slug":"tcp-头部结构","link":"#tcp-头部结构","children":[]},{"level":4,"title":"TCP 状态机","slug":"tcp-状态机","link":"#tcp-状态机","children":[]},{"level":4,"title":"TCP 三次握手/四次挥手","slug":"tcp-三次握手-四次挥手","link":"#tcp-三次握手-四次挥手","children":[]},{"level":4,"title":"TCP 如何保证传输的可靠性?","slug":"tcp-如何保证传输的可靠性","link":"#tcp-如何保证传输的可靠性","children":[]},{"level":4,"title":"超时重传","slug":"超时重传","link":"#超时重传","children":[]},{"level":4,"title":"流量控制","slug":"流量控制","link":"#流量控制","children":[]},{"level":4,"title":"拥塞控制","slug":"拥塞控制","link":"#拥塞控制","children":[]},{"level":4,"title":"校验和","slug":"校验和","link":"#校验和","children":[]}]},{"level":3,"title":"UDP","slug":"udp","link":"#udp","children":[{"level":4,"title":"特点","slug":"特点","link":"#特点","children":[]},{"level":4,"title":"结构","slug":"结构","link":"#结构","children":[]},{"level":4,"title":"广播类型","slug":"广播类型","link":"#广播类型","children":[]}]}],"git":{"createdTime":1707924994000,"updatedTime":1708054956000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":3}]},"readingTime":{"minutes":10.96,"words":3287},"filePathRelative":"guide/concepts/network/2-tcp-udp.md","localizedDate":"2024年2月14日","autoDesc":true,"excerpt":"

TCP

\\n

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

\\n

TCP 头部结构

\\n
\\"tcp
tcp 头部
\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
TCP头部字段描述
源端口发送方的端口号,范围(0~65535)
目标端口接收方的端口号,范围(0~65535)
序列号如果TCP数据过大(大于IP数据包的允许程度),则需要进行分段。这个序列号记录每个数据包的序列号,使接收端可以重新组合TCP数据。序列号字段的值是本报文段发送的数据的第一个字节的序列号。简称为seq
确认号为了确认接收端确实收到了发送端发送的数据包数据,当发送端收到这个确认码时,就可以确定之前传递的数据包已经被正确接收。这个确认号是期望收到对方下一个报文段的数据的第一个字节的序列号。简称ack
头部长度表示TCP头部的长度,范围(0~15),单位32位,例如值为5时,表示头部长度是20字节(160位),如果选项字段为空,则TCP头部长度为20字节,即值为5
URGURG=1表示存在紧急数据,紧急数据的最后一个字节由紧急数据指针指出,一般使用较少
ACKACK=1表示确认号字段中的值是有效的,为0表示无效
PSHURG=1表示紧急指针字段有效,代表该数据包为紧急数据包。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)
RSTRSP=1表示重建连接,如果接收到RST位时,通常发生了某些错误
SYNSYN=1表示这是一个连接请求或连接接受报文,一般用于握手阶段
FINFIN=1表示此报文段的发送端的数据已发送完毕,并要求释放运输连接
接收窗口用于流量控制,指示接收方愿意接收的字节数量,范围0~65535字节
校验和校验和覆盖了整个TCP报文段,即TCP头部和TCP数据,这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证
紧急数据指针URG=1时有效,是一个正的偏移量,和序列号中的值相加表示紧急数据最后一个字节的序列号
选项用于发送方和接收方协商最大报文长度(MSS)时(只存在于SYN报文)或在高速网络环境下用作窗口调节因子时使用,还可以存放时间戳数据
"}');export{Y as comp,z as data}; diff --git a/assets/2-tcp-udp.html-BbAGUlCW.js b/assets/2-tcp-udp.html-BbAGUlCW.js deleted file mode 100644 index b4de89fe..00000000 --- a/assets/2-tcp-udp.html-BbAGUlCW.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as c,a as d,b as o,c as r}from"./sack-B470dwkI.js";import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{r as l,o as p,c as h,a as t,e,f as a,b as n}from"./app-Bsw6rBWV.js";const g="/assets/image/article/network/tcp.png",m="/assets/image/article/network/tcp_state.png",u="/assets/image/article/network/tcp-send-window.png",C="/assets/image/article/network/tcp-receive-window.png",T="/assets/image/article/network/tcp-congestion-control.png",P={},f=n('

TCP

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

TCP 头部结构

tcp 头部
tcp 头部
TCP头部字段描述
源端口发送方的端口号,范围(0~65535)
目标端口接收方的端口号,范围(0~65535)
序列号如果TCP数据过大(大于IP数据包的允许程度),则需要进行分段。这个序列号记录每个数据包的序列号,使接收端可以重新组合TCP数据。序列号字段的值是本报文段发送的数据的第一个字节的序列号。简称为seq
确认号为了确认接收端确实收到了发送端发送的数据包数据,当发送端收到这个确认码时,就可以确定之前传递的数据包已经被正确接收。这个确认号是期望收到对方下一个报文段的数据的第一个字节的序列号。简称ack
头部长度表示TCP头部的长度,范围(0~15),单位32位,例如值为5时,表示头部长度是20字节(160位),如果选项字段为空,则TCP头部长度为20字节,即值为5
URGURG=1表示存在紧急数据,紧急数据的最后一个字节由紧急数据指针指出,一般使用较少
ACKACK=1表示确认号字段中的值是有效的,为0表示无效
PSHURG=1表示紧急指针字段有效,代表该数据包为紧急数据包。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)
RSTRSP=1表示重建连接,如果接收到RST位时,通常发生了某些错误
SYNSYN=1表示这是一个连接请求或连接接受报文,一般用于握手阶段
FINFIN=1表示此报文段的发送端的数据已发送完毕,并要求释放运输连接
接收窗口用于流量控制,指示接收方愿意接收的字节数量,范围0~65535字节
校验和校验和覆盖了整个TCP报文段,即TCP头部和TCP数据,这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证
紧急数据指针URG=1时有效,是一个正的偏移量,和序列号中的值相加表示紧急数据最后一个字节的序列号
选项用于发送方和接收方协商最大报文长度(MSS)时(只存在于SYN报文)或在高速网络环境下用作窗口调节因子时使用,还可以存放时间戳数据

TCP 状态机

TCP Stateful
TCP Stateful

TCP 三次握手/四次挥手

TCP Connection
TCP Connection

三次握手过程

  1. 客户端发送SYN=1,并指明客户端的初始序列号ISN,即x.
  2. 服务端发送自己的SYN段作为应答,同样指明自己的ISNy。为了确认客户端的SYN,将x+1作为ACK数值。这样,每发送一个SYN,序列号就会加1. 如果有丢失的情况,则会重传。
  3. 为了确认服务器端的SYN,客户端将y+1作为返回的ACK数值。

TCP 四次挥手

  1. 客户端发送FIN=1,并包含一个自己当前的序列号x+2。 同时还包含一个ACK=y+1表示确认对方最近一次发过来的数据。
  2. 服务端将x+2值加1作为ACK序号值,表明收到了上一个包。这时上层的应用程序会被告知另一端发起了关闭操作,通常这将引起应用程序发起自己的关闭操作。
  3. 服务端发起自己的FIN=1seq=y+1
  4. 客户端确认, 向服务器发送 ACK=y+2

为什么要三次握手?作用是什么?

详情

TCP 建立连接的过程就是同步序列号的过程,SYN (Synchronize Sequence Numbers)就是同步序列号。因此,三次握手的目的就是使客户端(Client)和服务端(Service)获取到对方的序列号。

为什么要四次挥手?作用是什么?

详情

之所以需要四次挥手,是因为 tcp 是全双工协议,即客户端和服务端都可以主动发送消息,因此需要两端分别在传输完成后发送断开连接的指令,需要分别发送 FIN=1 指令断开,通过 ACK 判断是否发送成功。

如果连接时 SYN 超时会发生什么?

详情

假如客户端发送 SYN 指令,在服务器返回 SYN 指令之前掉线了,服务器会尝试重发 SYN-ACK 指令,linux 下默认重试 5 次,间隔时间从 1s 开始翻倍增长,即 1s, 2s, 4s, 8s, 16s, 因此超时时间为 1s + 2s + 4s+ 8s+ 16s + 32s = 63s。在超时之后 TCP 才会断开连接。

TCP 如何保证传输的可靠性?

TCP 通过以下几个特性保证数据传输的可靠性

  • 序列号和确认应答
  • 超时重传
  • 流量控制
  • 拥塞控制
  • 校验和
序列号和确认应答信号

TCP 通过序列号可以对数据包进行排序和去重,同时通过 ACK 应答机制确保数据包成功送达,保证了数据的完整性。

超时重传

TCP 通过超时重传机制可以在数据包丢失或者延迟时,重新发送数据包直到收到 ACK 应答。

什么是RTT?什么是RTO?

详情

RTT代表往返时间(Round Trip Time),是指数据从发送方传输到接收方并返回所需的时间。RTT用于衡量网络延迟,即数据在传输过程中经过的总时间。

RTO代表重传超时时间(Retransmission Timeout),是指在网络通信中,发送方发送数据后等待确认(ACK)的时间。如果发送方在RTO时间内未收到确认,它会假设数据丢失,并重新发送该数据。

RTO的计算通常基于RTT的测量。发送方根据前一次的RTT来估计下一次发送数据的RTO。一般情况下,RTO的值会比RTT大一些,以确保在网络延迟较高或不稳定的情况下也能够成功重传数据。

RTO的计算方法可以根据具体的网络协议或实现而有所不同,但其目的是为了确保数据的可靠传输,以应对网络中的丢包、延迟和拥塞等问题。

RTO 长短对重传有什么影响?

详情

若 RTO 过长则重传时间会大大延长,降低传输效率。若 RTO 过短则可能会导致频繁重传,加剧网络的拥堵,进一步触发更多的重传。

',22),y={class:"hint-container tip"},_=t("p",{class:"hint-container-title"},"常见的重传机制",-1),S={class:"hint-container details"},k=n('详情
  • 超时重传
timeout retransmission
timeout retransmission

超时重传有两种情况,发送的数据包丢失导致的超时,和返回的 ACK 数据包丢失导致的超时。超时重传机制下,在每次发送数据包的时候都会启动一个定时器,如果定时器到期则会触发重传。若重传失败,则下一次超时时间为当前值的两倍。超时重传的缺点是周期较长,可能会降低效率。

  • 快速重传
tcp
tcp

在快速重传机制下,在数据包丢失后,接收端每接收一个失序的数据包就立即返回重复的确认报文段,告知发送端缺少的报文段。当发送方收到三个重复的确认报文段后,会立即重传缺失的报文段。

在快速重传的机制下,我们可以看到 3,4,5 的报文段返回的都是 ACK=2, 因此还需要重传 3,4,5 报文段。有没有方法可以不需要重传 3,4,5 报文段?

  • SACK (Selective Acknowledgment, 选择性确认)
SACK
SACK
',10),w={href:"https://www.ietf.org/rfc/rfc2883.txt",target:"_blank",rel:"noopener noreferrer"},v=t("ul",null,[t("li",null,"D-SACK (Duplicate SACK, 重复选择性确认)")],-1),R={href:"https://datatracker.ietf.org/doc/html/rfc2018",target:"_blank",rel:"noopener noreferrer"},b=n('

流量控制

TCP 使用滑动窗口来控制流量,使得发送端可以根据接收端的接收能力控制发送数据的速度。

发送窗口(窗口大小为 7)接收窗口(窗口大小为 7)

注意

接收端在应答 ACK 的时候会将当前可用的窗口大小写入 tcp 头部,发送端根据窗口大小调整发送速率。

拥塞控制

算法

  • 慢启动
  • 拥塞避免
  • 快重传
  • 快恢复
拥塞控制
拥塞控制

UDP

常见面试题

什么是 SYN Flood 攻击?

详情
',10);function N(x,A){const i=l("ExternalLinkIcon");return p(),h("div",null,[f,t("div",y,[_,t("details",S,[k,t("p",null,[e("SACK 方法 ("),t("a",w,[e("RFC 2018"),a(i)]),e(") 在 tcp 的 option 字段添加了缓冲区,用于记录已传输的数据包,这样发送方可以看到未成功传输的数据包,使得发送方可以仅传输缺失的数据包而不需要额外重传其他数据包。")]),v,t("p",null,[e("D-SACK ("),t("a",R,[e("RFC 2883"),a(i)]),e(") 主要解决了 ACK 丢失的问题, D-SACK 使用 SACK 第一个段作为标志位,用于标记已经 ACK 的数据包。 当接收端接收到重复的报文段时会将该报文段写入 D-SACK 的标志位,告诉发送方已接收到报文段, ACK 可能已丢失。")])])]),b])}const z=s(P,[["render",N],["__file","2-tcp-udp.html.vue"]]),D=JSON.parse('{"path":"/guide/concepts/network/2-tcp-udp.html","title":"TCP/UDP","lang":"zh-CN","frontmatter":{"order":2,"title":"TCP/UDP","description":"TCP 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。 TCP 头部结构 tcp 头部tcp 头部 TCP 状态机 TCP StatefulTCP Stateful TCP 三次握手/四次挥手 TCP ConnectionTCP Connection 三次握手过程...","head":[["link",{"rel":"alternate","hreflang":"en-us","href":"https://goguide.ryansu.tech/en/guide/concepts/network/2-tcp-udp.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/guide/concepts/network/2-tcp-udp.html"}],["meta",{"property":"og:site_name","content":"Go 面试宝典"}],["meta",{"property":"og:title","content":"TCP/UDP"}],["meta",{"property":"og:description","content":"TCP 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。 TCP 头部结构 tcp 头部tcp 头部 TCP 状态机 TCP StatefulTCP Stateful TCP 三次握手/四次挥手 TCP ConnectionTCP Connection 三次握手过程..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://goguide.ryansu.tech/assets/image/article/network/tcp.png"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:locale:alternate","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-02-15T15:50:33.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"TCP/UDP"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-02-15T15:50:33.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"TCP/UDP\\",\\"image\\":[\\"https://goguide.ryansu.tech/assets/image/article/network/tcp.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp_state.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-connect.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/timeout-retransmission.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-3-retry-new.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/sack.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-send-window.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-receive-window.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-congestion-control.png\\"],\\"dateModified\\":\\"2024-02-15T15:50:33.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":3,"title":"TCP","slug":"tcp","link":"#tcp","children":[{"level":4,"title":"TCP 头部结构","slug":"tcp-头部结构","link":"#tcp-头部结构","children":[]},{"level":4,"title":"TCP 状态机","slug":"tcp-状态机","link":"#tcp-状态机","children":[]},{"level":4,"title":"TCP 三次握手/四次挥手","slug":"tcp-三次握手-四次挥手","link":"#tcp-三次握手-四次挥手","children":[]},{"level":4,"title":"TCP 如何保证传输的可靠性?","slug":"tcp-如何保证传输的可靠性","link":"#tcp-如何保证传输的可靠性","children":[]},{"level":4,"title":"超时重传","slug":"超时重传","link":"#超时重传","children":[]},{"level":4,"title":"流量控制","slug":"流量控制","link":"#流量控制","children":[]},{"level":4,"title":"拥塞控制","slug":"拥塞控制","link":"#拥塞控制","children":[]}]},{"level":3,"title":"UDP","slug":"udp","link":"#udp","children":[]},{"level":3,"title":"常见面试题","slug":"常见面试题","link":"#常见面试题","children":[]}],"git":{"createdTime":1707924994000,"updatedTime":1708012233000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":2}]},"readingTime":{"minutes":7.94,"words":2381},"filePathRelative":"guide/concepts/network/2-tcp-udp.md","localizedDate":"2024年2月14日","autoDesc":true,"excerpt":"

TCP

\\n

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

\\n

TCP 头部结构

\\n
\\"tcp
tcp 头部
\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
TCP头部字段描述
源端口发送方的端口号,范围(0~65535)
目标端口接收方的端口号,范围(0~65535)
序列号如果TCP数据过大(大于IP数据包的允许程度),则需要进行分段。这个序列号记录每个数据包的序列号,使接收端可以重新组合TCP数据。序列号字段的值是本报文段发送的数据的第一个字节的序列号。简称为seq
确认号为了确认接收端确实收到了发送端发送的数据包数据,当发送端收到这个确认码时,就可以确定之前传递的数据包已经被正确接收。这个确认号是期望收到对方下一个报文段的数据的第一个字节的序列号。简称ack
头部长度表示TCP头部的长度,范围(0~15),单位32位,例如值为5时,表示头部长度是20字节(160位),如果选项字段为空,则TCP头部长度为20字节,即值为5
URGURG=1表示存在紧急数据,紧急数据的最后一个字节由紧急数据指针指出,一般使用较少
ACKACK=1表示确认号字段中的值是有效的,为0表示无效
PSHURG=1表示紧急指针字段有效,代表该数据包为紧急数据包。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)
RSTRSP=1表示重建连接,如果接收到RST位时,通常发生了某些错误
SYNSYN=1表示这是一个连接请求或连接接受报文,一般用于握手阶段
FINFIN=1表示此报文段的发送端的数据已发送完毕,并要求释放运输连接
接收窗口用于流量控制,指示接收方愿意接收的字节数量,范围0~65535字节
校验和校验和覆盖了整个TCP报文段,即TCP头部和TCP数据,这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证
紧急数据指针URG=1时有效,是一个正的偏移量,和序列号中的值相加表示紧急数据最后一个字节的序列号
选项用于发送方和接收方协商最大报文长度(MSS)时(只存在于SYN报文)或在高速网络环境下用作窗口调节因子时使用,还可以存放时间戳数据
"}');export{z as comp,D as data}; diff --git a/assets/2-tcp-udp.html-D4XJmffI.js b/assets/2-tcp-udp.html-D4XJmffI.js deleted file mode 100644 index 57052636..00000000 --- a/assets/2-tcp-udp.html-D4XJmffI.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as s,a as r,b as o,c}from"./sack-B470dwkI.js";import{_ as d}from"./plugin-vue_export-helper-DlAUqK2U.js";import{r as h,o as l,c as m,a as e,e as t,f as i,b as n}from"./app-Bsw6rBWV.js";const u="/assets/image/article/network/tcp_en.png",p="/assets/image/article/network/tcp_state_en.png",g={},f=n('

TCP

Transmission Control Protocol (TCP) is a connection-oriented, reliable, byte-stream-based transport layer communication protocol.

TCP Header Structure

tcp header
tcp header
TCP Header FieldDescription
Source PortSender's port number, range (0~65535)
Destination PortReceiver's port number, range (0~65535)
Sequence NumberIf the TCP data is too large (greater than the allowable degree of IP packet), it needs to be segmented. This sequence number records the sequence number of each packet, allowing the receiver to reassemble the TCP data. The value of the sequence number field refers to the sequence number of the first byte of data sent by this segment. Abbreviated as seq
Acknowledgment NumberTo confirm that the receiver has indeed received the packet data sent out by the sender, when the sender receives this acknowledgment code, it can confirm that the previous packet has been correctly received. This acknowledgment number is the sequence number of the first byte of data from the next segment expected to be received from the other party. Abbreviated as ack
Header LengthIndicates the length of the TCP header, range (0~15), unit 32bit, for example, when the value is 5, it means that the header length is 20Byte(160bit), if the option field is empty, then the TCP header length is 20Byte, that is, the value is 5
URGURG=1 indicates that there is urgent data, the last byte of the urgent data is pointed out by the urgent data pointer, generally less used
ACKACK=1 indicates that the value in the acknowledgment number field is valid, 0 indicates invalid
PSHURG=1 indicates that the urgent pointer field is valid, representing that this packet is an urgent packet. It tells the system that there is urgent data in this segment and should be transmitted as soon as possible (equivalent to high-priority data)
RSTRSP=1 rebuilds the connection, if the RST bit is received, some errors usually occur
SYNSYN=1 indicates that this is a connection request or connection acceptance message, generally used in the handshake stage
FINFIN=1 indicates that the data of the sender of this segment has been sent and requests to release the transport connection
Receive WindowUsed for flow control, indicating the number of bytes the receiver is willing to receive, range 0~65535 bytes
ChecksumThe checksum covers the entire TCP segment, i.e., the TCP header and TCP data. This is a mandatory field, it must be calculated and stored by the sender, and verified by the receiver
Urgent Data PointerWhen URG=1 is valid, it is a positive offset, and the sum with the value in the sequence number represents the sequence number of the last byte of urgent data
OptionsUsed when the sender and receiver negotiate the maximum segment length (MSS) (only exists in SYN messages) or used as a window adjustment factor in high-speed network environments, can also store timestamp data

TCP State Machine

TCP Stateful
TCP Stateful

TCP Three-Way Handshake

TCP Connection
TCP Connection

Three-Way Handshake Process

  1. The client sends SYN=1, and specifies the client's initial sequence number ISN, i.e., x.
  2. The server sends its own SYN segment as an acknowledgment, also specifying its own ISN, i.e., y. To acknowledge the client's SYN, it sets ACK to x+1. In this way, each time a SYN is sent, the sequence number will increase by 1. If there is a loss, it will be retransmitted.
  3. To acknowledge the server's SYN, the client sets ACK to y+1 in the returned value.

TCP Four-Way Handshake

  1. The client sends FIN=1, and includes its current sequence number x+2. It also includes an ACK=y+1 to acknowledge the data most recently received from the other side.
  2. The server adds 1 to the value x+2 as the ACK sequence number, indicating that the previous packet has been received. At this time, the upper-layer application will be notified that the other end has initiated a shutdown operation, which usually causes the application to initiate its own shutdown operation.
  3. The server initiates its own FIN=1, seq=y+1.
  4. The client acknowledges, sends ACK=y+2 to the server.

Why is a three-way handshake needed? What is its purpose?

Details

The process of TCP establishing a connection is the process of synchronizing sequence numbers, SYN (Synchronize Sequence Numbers) is to synchronize sequence numbers. Therefore, the purpose of the three-way handshake is to allow the client (Client) and the server (Service) to obtain each other's sequence number.

Why is a four-way handshake needed? What is its purpose?

Details

The reason why a four-way handshake is needed is because TCP is a full-duplex protocol, i.e., both the client and the server can actively send messages, so both ends need to send disconnect instructions after the transmission is completed, and need to send FIN=1 separately to disconnect, and use ACK to determine whether the sending was successful.

What happens if SYN times out during connection?

Details

If the client sends a SYN command, and drops the line before the server returns the SYN command, the server will try to resend the SYN-ACK command. Under Linux, the default is to retry 5 times, the interval time starts to double from 1s, i.e., 1s, 2s, 4s, 8s, 16s, so the timeout time is 1s + 2s + 4s+ 8s+ 16s + 32s = 63s. After the timeout, TCP will disconnect.

How does TCP ensure the reliability of transmission?

TCP ensures the reliability of data transmission through the following features

  • Sequence numbers and acknowledgments
  • Timeout retransmission
  • Flow control
  • Congestion control
  • Checksum
Sequence numbers and acknowledgment signals

TCP uses sequence numbers to sort and deduplicate packets, and through the ACK acknowledgment mechanism, it ensures that packets are successfully delivered, ensuring the integrity of the data.

Timeout retransmission

TCP can retransmit packets until an ACK acknowledgment is received when packets are lost or delayed, through the timeout retransmission mechanism.

What is RTT? What is RTO?

Details

RTT stands for Round Trip Time, which refers to the time required for data to be transmitted from the sender to the receiver and back. RTT is used to measure network latency, that is, the total time that data passes through during transmission.

RTO stands for Retransmission Timeout, which refers to the time that the sender waits for acknowledgment (ACK) after sending data in network communication. If the sender does not receive an acknowledgment within the RTO time, it will assume that the data is lost and resend the data.

The calculation of RTO is usually based on the measurement of RTT. The sender estimates the RTO of the next data transmission based on the previous RTT. In general, the value of RTO will be larger than RTT to ensure that data can be successfully retransmitted even in cases of high or unstable network latency.

The calculation method of RTO can vary depending on the specific network protocol or implementation, but its purpose is to ensure the reliable transmission of data to cope with problems such as packet loss, delay, and congestion in the network.

What is the impact of RTO length on retransmission?

Details

If the RTO is too long, the retransmission time will be greatly extended, reducing transmission efficiency. If the RTO is too short, it may lead to frequent retransmissions, exacerbating network congestion, and further triggering more retransmissions.

',22),y={class:"hint-container tip"},b=e("p",{class:"hint-container-title"},"Common retransmission mechanisms",-1),w={class:"hint-container details"},k=n('Details
  • Timeout retransmission
timeout retransmission
timeout retransmission

There are two situations for timeout retransmission, the timeout caused by the loss of the sent data packet, and the timeout caused by the loss of the returned ACK data packet. Under the timeout retransmission mechanism, a timer is started every time a data packet is sent. If the timer expires, retransmission will be triggered. If the retransmission fails, the next timeout time will be twice the current value. The disadvantage of timeout retransmission is that the cycle is long, which may reduce efficiency.

  • Fast retransmission
tcp
tcp

Under the fast retransmission mechanism, after a data packet is lost, the receiving end immediately returns a duplicate acknowledgment packet for each out-of-order packet received, informing the sending end of the missing packet. When the sender receives three duplicate acknowledgment packets, it will immediately retransmit the missing packet.

Under the fast retransmission mechanism, we can see that the packets 3,4,5 all return ACK=2, so we need to retransmit the packets 3,4,5. Is there a way to not need to retransmit packets 3,4,5?

  • SACK (Selective Acknowledgment)
SACK
SACK
',10),T={href:"https://www.ietf.org/rfc/rfc2883.txt",target:"_blank",rel:"noopener noreferrer"},v=e("ul",null,[e("li",null,"D-SACK (Duplicate SACK)")],-1),C={href:"https://datatracker.ietf.org/doc/html/rfc2018",target:"_blank",rel:"noopener noreferrer"},P=n('

UDP

Common interview questions

What is a SYN Flood attack?

Details
',3);function _(S,x){const a=h("ExternalLinkIcon");return l(),m("div",null,[f,e("div",y,[b,e("details",w,[k,e("p",null,[t("The SACK method ("),e("a",T,[t("RFC 2018"),i(a)]),t(") adds a buffer to the tcp option field to record the transmitted packets, so that the sender can see the packets that have not been successfully transmitted, allowing the sender to only transmit the missing packets without needing to retransmit other packets.")]),v,e("p",null,[t("D-SACK ("),e("a",C,[t("RFC 2883"),i(a)]),t(") mainly solves the problem of ACK loss. D-SACK uses the first segment of SACK as a flag to mark the packets that have been ACKed. When the receiving end receives a duplicate packet, it will write the packet into the D-SACK flag, telling the sender that the packet has been received, and the ACK may have been lost.")])])]),P])}const N=d(g,[["render",_],["__file","2-tcp-udp.html.vue"]]),K=JSON.parse('{"path":"/en/guide/concepts/network/2-tcp-udp.html","title":"TCP/UDP","lang":"en-US","frontmatter":{"order":2,"title":"TCP/UDP","description":"TCP Transmission Control Protocol (TCP) is a connection-oriented, reliable, byte-stream-based transport layer communication protocol. TCP Header Structure tcp headertcp header T...","head":[["link",{"rel":"alternate","hreflang":"zh-cn","href":"https://goguide.ryansu.tech/guide/concepts/network/2-tcp-udp.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/en/guide/concepts/network/2-tcp-udp.html"}],["meta",{"property":"og:site_name","content":"Go Guide"}],["meta",{"property":"og:title","content":"TCP/UDP"}],["meta",{"property":"og:description","content":"TCP Transmission Control Protocol (TCP) is a connection-oriented, reliable, byte-stream-based transport layer communication protocol. TCP Header Structure tcp headertcp header T..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://goguide.ryansu.tech/assets/image/article/network/tcp_en.png"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:locale:alternate","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-02-15T15:50:33.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"TCP/UDP"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-02-15T15:50:33.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"TCP/UDP\\",\\"image\\":[\\"https://goguide.ryansu.tech/assets/image/article/network/tcp_en.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp_state_en.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-connect.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/timeout-retransmission.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-3-retry-new.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/sack.png\\"],\\"dateModified\\":\\"2024-02-15T15:50:33.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":3,"title":"TCP","slug":"tcp","link":"#tcp","children":[{"level":4,"title":"TCP Header Structure","slug":"tcp-header-structure","link":"#tcp-header-structure","children":[]},{"level":4,"title":"TCP State Machine","slug":"tcp-state-machine","link":"#tcp-state-machine","children":[]},{"level":4,"title":"TCP Three-Way Handshake","slug":"tcp-three-way-handshake","link":"#tcp-three-way-handshake","children":[]},{"level":4,"title":"How does TCP ensure the reliability of transmission?","slug":"how-does-tcp-ensure-the-reliability-of-transmission","link":"#how-does-tcp-ensure-the-reliability-of-transmission","children":[]},{"level":4,"title":"Timeout retransmission","slug":"timeout-retransmission","link":"#timeout-retransmission","children":[]}]},{"level":3,"title":"UDP","slug":"udp","link":"#udp","children":[]},{"level":3,"title":"Common interview questions","slug":"common-interview-questions","link":"#common-interview-questions","children":[]}],"git":{"createdTime":1707924994000,"updatedTime":1708012233000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":2}]},"readingTime":{"minutes":5.32,"words":1595},"filePathRelative":"en/guide/concepts/network/2-tcp-udp.md","localizedDate":"February 14, 2024","autoDesc":true,"excerpt":"

TCP

\\n

Transmission Control Protocol (TCP) is a connection-oriented, reliable, byte-stream-based transport layer communication protocol.

\\n

TCP Header Structure

\\n
\\"tcp
tcp header
"}');export{N as comp,K as data}; diff --git a/assets/2-tcp-udp.html-IZeSrbLS.js b/assets/2-tcp-udp.html-IZeSrbLS.js new file mode 100644 index 00000000..f83fb685 --- /dev/null +++ b/assets/2-tcp-udp.html-IZeSrbLS.js @@ -0,0 +1 @@ +import{_ as i,a as r,b as o,c as d}from"./sack-B470dwkI.js";import{_ as c}from"./plugin-vue_export-helper-DlAUqK2U.js";import{r as h,o as l,c as m,a as e,e as t,f as s,b as a}from"./app-C0BAr50I.js";const u="/assets/image/article/network/tcp_en.png",p="/assets/image/article/network/tcp_state_en.png",g={},f=a('

TCP

Transmission Control Protocol (TCP) is a connection-oriented, reliable, byte-stream-based transport layer communication protocol.

TCP Header Structure

tcp header
tcp header
TCP Header FieldDescription
Source PortSender's port number, range (0~65535)
Destination PortReceiver's port number, range (0~65535)
Sequence NumberIf the TCP data is too large (greater than the allowable degree of IP packet), it needs to be segmented. This sequence number records the sequence number of each packet, allowing the receiver to reassemble the TCP data. The value of the sequence number field refers to the sequence number of the first byte of data sent by this segment. Abbreviated as seq
Acknowledgment NumberTo confirm that the receiver has indeed received the packet data sent out by the sender, when the sender receives this acknowledgment code, it can confirm that the previous packet has been correctly received. This acknowledgment number is the sequence number of the first byte of data from the next segment expected to be received from the other party. Abbreviated as ack
Header LengthIndicates the length of the TCP header, range (0~15), unit 32bit, for example, when the value is 5, it means that the header length is 20Byte(160bit), if the option field is empty, then the TCP header length is 20Byte, that is, the value is 5
URGURG=1 indicates that there is urgent data, the last byte of the urgent data is pointed out by the urgent data pointer, generally less used
ACKACK=1 indicates that the value in the acknowledgment number field is valid, 0 indicates invalid
PSHURG=1 indicates that the urgent pointer field is valid, representing that this packet is an urgent packet. It tells the system that there is urgent data in this segment and should be transmitted as soon as possible (equivalent to high-priority data)
RSTRSP=1 rebuilds the connection, if the RST bit is received, some errors usually occur
SYNSYN=1 indicates that this is a connection request or connection acceptance message, generally used in the handshake stage
FINFIN=1 indicates that the data of the sender of this segment has been sent and requests to release the transport connection
Receive WindowUsed for flow control, indicating the number of bytes the receiver is willing to receive, range 0~65535 bytes
ChecksumThe checksum covers the entire TCP segment, i.e., the TCP header and TCP data. This is a mandatory field, it must be calculated and stored by the sender, and verified by the receiver
Urgent Data PointerWhen URG=1 is valid, it is a positive offset, and the sum with the value in the sequence number represents the sequence number of the last byte of urgent data
OptionsUsed when the sender and receiver negotiate the maximum segment length (MSS) (only exists in SYN messages) or used as a window adjustment factor in high-speed network environments, can also store timestamp data

TCP State Machine

TCP Stateful
TCP Stateful

TCP Three-Way Handshake

TCP Connection
TCP Connection

Three-Way Handshake Process

  1. The client sends SYN=1, and specifies the client's initial sequence number ISN, i.e., x.
  2. The server sends its own SYN segment as an acknowledgment, also specifying its own ISN, i.e., y. To acknowledge the client's SYN, it sets ACK to x+1. In this way, each time a SYN is sent, the sequence number will increase by 1. If there is a loss, it will be retransmitted.
  3. To acknowledge the server's SYN, the client sets ACK to y+1 in the returned value.

TCP Four-Way Handshake

  1. The client sends FIN=1, and includes its current sequence number x+2. It also includes an ACK=y+1 to acknowledge the data most recently received from the other side.
  2. The server adds 1 to the value x+2 as the ACK sequence number, indicating that the previous packet has been received. At this time, the upper-layer application will be notified that the other end has initiated a shutdown operation, which usually causes the application to initiate its own shutdown operation.
  3. The server initiates its own FIN=1, seq=y+1.
  4. The client acknowledges, sends ACK=y+2 to the server.

Why is a three-way handshake needed? What is its purpose?

Details

The process of TCP establishing a connection is the process of synchronizing sequence numbers, SYN (Synchronize Sequence Numbers) is to synchronize sequence numbers. Therefore, the purpose of the three-way handshake is to allow the client (Client) and the server (Service) to obtain each other's sequence number.

Why is a four-way handshake needed? What is its purpose?

Details

The reason why a four-way handshake is needed is because TCP is a full-duplex protocol, i.e., both the client and the server can actively send messages, so both ends need to send disconnect instructions after the transmission is completed, and need to send FIN=1 separately to disconnect, and use ACK to determine whether the sending was successful.

What happens if SYN times out during connection?

Details

If the client sends a SYN command, and drops the line before the server returns the SYN command, the server will try to resend the SYN-ACK command. Under Linux, the default is to retry 5 times, the interval time starts to double from 1s, i.e., 1s, 2s, 4s, 8s, 16s, so the timeout time is 1s + 2s + 4s+ 8s+ 16s + 32s = 63s. After the timeout, TCP will disconnect.

How does TCP ensure the reliability of transmission?

TCP ensures the reliability of data transmission through the following features

  • Sequence numbers and acknowledgments
  • Timeout retransmission
  • Flow control
  • Congestion control
  • Checksum
Sequence numbers and acknowledgment signals

TCP uses sequence numbers to sort and deduplicate packets, and through the ACK acknowledgment mechanism, it ensures that packets are successfully delivered, ensuring the integrity of the data.

Timeout retransmission

TCP can retransmit packets until an ACK acknowledgment is received when packets are lost or delayed, through the timeout retransmission mechanism.

What is RTT? What is RTO?

Details

RTT stands for Round Trip Time, which refers to the time required for data to be transmitted from the sender to the receiver and back. RTT is used to measure network latency, that is, the total time that data passes through during transmission.

RTO stands for Retransmission Timeout, which refers to the time that the sender waits for acknowledgment (ACK) after sending data in network communication. If the sender does not receive an acknowledgment within the RTO time, it will assume that the data is lost and resend the data.

The calculation of RTO is usually based on the measurement of RTT. The sender estimates the RTO of the next data transmission based on the previous RTT. In general, the value of RTO will be larger than RTT to ensure that data can be successfully retransmitted even in cases of high or unstable network latency.

The calculation method of RTO can vary depending on the specific network protocol or implementation, but its purpose is to ensure the reliable transmission of data to cope with problems such as packet loss, delay, and congestion in the network.

What is the impact of RTO length on retransmission?

Details

If the RTO is too long, the retransmission time will be greatly extended, reducing transmission efficiency. If the RTO is too short, it may lead to frequent retransmissions, exacerbating network congestion, and further triggering more retransmissions.

',22),y={class:"hint-container tip"},b=e("p",{class:"hint-container-title"},"Common retransmission mechanisms",-1),w={class:"hint-container details"},k=a('Details
  • Timeout retransmission
timeout retransmission
timeout retransmission

There are two situations for timeout retransmission, the timeout caused by the loss of the sent data packet, and the timeout caused by the loss of the returned ACK data packet. Under the timeout retransmission mechanism, a timer is started every time a data packet is sent. If the timer expires, retransmission will be triggered. If the retransmission fails, the next timeout time will be twice the current value. The disadvantage of timeout retransmission is that the cycle is long, which may reduce efficiency.

  • Fast retransmission
tcp
tcp

Under the fast retransmission mechanism, after a data packet is lost, the receiving end immediately returns a duplicate acknowledgment packet for each out-of-order packet received, informing the sending end of the missing packet. When the sender receives three duplicate acknowledgment packets, it will immediately retransmit the missing packet.

Under the fast retransmission mechanism, we can see that the packets 3,4,5 all return ACK=2, so we need to retransmit the packets 3,4,5. Is there a way to not need to retransmit packets 3,4,5?

  • SACK (Selective Acknowledgment)
SACK
SACK
',10),T={href:"https://www.ietf.org/rfc/rfc2883.txt",target:"_blank",rel:"noopener noreferrer"},v=e("ul",null,[e("li",null,"D-SACK (Duplicate SACK)")],-1),C={href:"https://datatracker.ietf.org/doc/html/rfc2018",target:"_blank",rel:"noopener noreferrer"},P=a('

Checksum

TCP also calculates a checksum on the data to ensure that the data was not lost or corrupted during transmission.

UDP

UDP, short for User Datagram Protocol, is a connectionless transport layer protocol in the OSI (Open Systems Interconnection) reference model. It provides a simple, unreliable transaction-oriented message delivery service, and its official specification is IETF RFC 768.

Characteristics

  • Connectionless: UDP does not need to establish a connection between the client and the server before transmitting data.
  • Fast: Since UDP does not need to handshake or check whether the data has arrived correctly, it can transmit data faster than TCP.
  • Unreliability: Once the datagram is sent, it is impossible to know whether it has arrived safely and completely. If the UDP datagram is lost during transmission, it will not be resent.
  • Widely used: UDP is used to support network applications that need to transmit data between computers. Many client/server model network applications, including network video conferencing systems, need to use the UDP protocol. For example, many Internet phone services use IP voice (VoIP) usually sent using UDP.

Structure

FieldSizeDescription
Source Port16-bitSource port number. If all are 0, no reply is allowed
Destination Port16-bitDestination port number
Length16-bitLength of the UDP user datagram, its minimum value is 8 (header only)
Checksum16-bitDetect whether the data is lost or modified during transmission

Broadcast Types

TypeDescription
UnicastUsed for end-to-end communication between two hosts. That is, one-to-one (client and server point-to-point connection)
BroadcastUsed for a host to communicate with all hosts on the entire LAN. That is, one to all. Broadcasting is prohibited from transmitting on the Internet broadband network (broadcast storm)
MulticastCommunicate with a specific group of hosts, not all hosts on the entire LAN. That is, one to a group

Warning

  • TCP only supports one-to-one
  • UDP multicast is more commonly used, broadcast is only used for LAN

Difference between TCP and UDP

FeatureTCPUDP
Reliable TransmissionYesNo
ConnectionConnection-orientedConnectionless
Data OrderlinessYesNot guaranteed
Data BoundaryNot preservedPreserved
Transmission SpeedRelatively slowFast
Flow Control and Congestion ControlYesNo
Protocol TypeHeavyweightLightweight
Header Length20 bytes8 bytes
',12);function S(_,x){const n=h("ExternalLinkIcon");return l(),m("div",null,[f,e("div",y,[b,e("details",w,[k,e("p",null,[t("The SACK method ("),e("a",T,[t("RFC 2018"),s(n)]),t(") adds a buffer to the tcp option field to record the transmitted packets, so that the sender can see the packets that have not been successfully transmitted, allowing the sender to only transmit the missing packets without needing to retransmit other packets.")]),v,e("p",null,[t("D-SACK ("),e("a",C,[t("RFC 2883"),s(n)]),t(") mainly solves the problem of ACK loss. D-SACK uses the first segment of SACK as a flag to mark the packets that have been ACKed. When the receiving end receives a duplicate packet, it will write the packet into the D-SACK flag, telling the sender that the packet has been received, and the ACK may have been lost.")])])]),P])}const N=c(g,[["render",S],["__file","2-tcp-udp.html.vue"]]),I=JSON.parse('{"path":"/en/guide/concepts/network/2-tcp-udp.html","title":"TCP/UDP","lang":"en-US","frontmatter":{"order":2,"title":"TCP/UDP","description":"TCP Transmission Control Protocol (TCP) is a connection-oriented, reliable, byte-stream-based transport layer communication protocol. TCP Header Structure tcp headertcp header T...","head":[["link",{"rel":"alternate","hreflang":"zh-cn","href":"https://goguide.ryansu.tech/guide/concepts/network/2-tcp-udp.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/en/guide/concepts/network/2-tcp-udp.html"}],["meta",{"property":"og:site_name","content":"Go Guide"}],["meta",{"property":"og:title","content":"TCP/UDP"}],["meta",{"property":"og:description","content":"TCP Transmission Control Protocol (TCP) is a connection-oriented, reliable, byte-stream-based transport layer communication protocol. TCP Header Structure tcp headertcp header T..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:image","content":"https://goguide.ryansu.tech/assets/image/article/network/tcp_en.png"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:locale:alternate","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-02-16T03:42:36.000Z"}],["meta",{"name":"twitter:card","content":"summary_large_image"}],["meta",{"name":"twitter:image:alt","content":"TCP/UDP"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-02-16T03:42:36.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"TCP/UDP\\",\\"image\\":[\\"https://goguide.ryansu.tech/assets/image/article/network/tcp_en.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp_state_en.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-connect.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/timeout-retransmission.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/tcp-3-retry-new.png\\",\\"https://goguide.ryansu.tech/assets/image/article/network/sack.png\\"],\\"dateModified\\":\\"2024-02-16T03:42:36.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":3,"title":"TCP","slug":"tcp","link":"#tcp","children":[{"level":4,"title":"TCP Header Structure","slug":"tcp-header-structure","link":"#tcp-header-structure","children":[]},{"level":4,"title":"TCP State Machine","slug":"tcp-state-machine","link":"#tcp-state-machine","children":[]},{"level":4,"title":"TCP Three-Way Handshake","slug":"tcp-three-way-handshake","link":"#tcp-three-way-handshake","children":[]},{"level":4,"title":"How does TCP ensure the reliability of transmission?","slug":"how-does-tcp-ensure-the-reliability-of-transmission","link":"#how-does-tcp-ensure-the-reliability-of-transmission","children":[]},{"level":4,"title":"Checksum","slug":"checksum","link":"#checksum","children":[]}]},{"level":3,"title":"UDP","slug":"udp","link":"#udp","children":[{"level":4,"title":"Characteristics","slug":"characteristics","link":"#characteristics","children":[]},{"level":4,"title":"Structure","slug":"structure","link":"#structure","children":[]},{"level":4,"title":"Broadcast Types","slug":"broadcast-types","link":"#broadcast-types","children":[]}]}],"git":{"createdTime":1707924994000,"updatedTime":1708054956000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":3}]},"readingTime":{"minutes":6.55,"words":1964},"filePathRelative":"en/guide/concepts/network/2-tcp-udp.md","localizedDate":"February 14, 2024","autoDesc":true,"excerpt":"

TCP

\\n

Transmission Control Protocol (TCP) is a connection-oriented, reliable, byte-stream-based transport layer communication protocol.

\\n

TCP Header Structure

\\n
\\"tcp
tcp header
"}');export{N as comp,I as data}; diff --git a/assets/3-operator.html-DcFs0BUM.js b/assets/3-operator.html-BwDwjYWH.js similarity index 99% rename from assets/3-operator.html-DcFs0BUM.js rename to assets/3-operator.html-BwDwjYWH.js index 84ce043c..beb0ce3f 100644 --- a/assets/3-operator.html-DcFs0BUM.js +++ b/assets/3-operator.html-BwDwjYWH.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as d,c as e,b as r}from"./app-Bsw6rBWV.js";const a={},n=r('

算术运算符

AB
5020
操作符操作结果描述
+A + B70相加
-A - B30相减
*A * B1000相乘
/A / B2相除
%A % B10取余
++A++51自增
--A--49自减

关系运算符

AB
5020
操作符操作结果描述
==A == Bfalse检查两数是否相等,若相等则为 true,否则为 false
!=A != Btrue检查两数是否不相等,若不相等则为 true , 否则为 false
>A > Btrue检查左边是否大于右边,若成立则为 true, 否则为 false
<A < Bfalse检查左边是否小于右边,若成立则为 true, 否则为 false
>=A >= Btrue检查左边是否大于等于右边,若成立则为 true, 否则为 false
<=A <= Bfalse检查左边是否小于等于右边,若成立则为 true, 否则为 false

逻辑运算符

AB
truefalse
操作符操作结果描述
&&A && Bfalse若两边都为 true,则结果为 true,否则为 false
!=A != Btrue若两边有一边为 true,则结果为 true,若两边都为 false , 则结果为 false
!Afalse若条件为 true 则结果为 false, 反之若条件为 false, 则结果为 true

位运算符

真值表

pqp & qp | qp ^ q
00000
01011
11110
10011

假设

变量
A0110 1000
B0111 0011
操作符操作结果描述
&A & B0110 0000按位进行与运算
|A | B0111 1011按位进行或运算
^A ^ B0001 1011按位进行异或运算
<<A << 21010 0000左移 2 位,低位补 0
>>A >> 20001 1010右移 2 位,高位补 0

赋值运算符

我们可以使用 = 将右边的结果赋值到左边,如 C = A + B

运算符操作等同于
+=A += BA = A + B
-=A -= BA = A - B
*=A *= BA = A * B
/=A /= BA = A / B
%=A %= BA = A % B
<<=A <<= 2A = A << 2
>>=A >>= 2A = A >> 2
&=A &= 2A = A & 2
|=A |= 2A = A | 2
^=A ^= 2A = A ^ 2

其他符号

运算符描述
&取地址
*指针

符号优先级

从高到低为:

优先级运算符
5* / % << >> & &^
4+ - | ^
3== != < <= > >=
2&&
1||

可以使用括号提高优先级

',24),h=[n];function l(o,s){return d(),e("div",null,h)}const c=t(a,[["render",l],["__file","3-operator.html.vue"]]),g=JSON.parse('{"path":"/guide/concepts/golang/3-operator.html","title":"运算符","lang":"zh-CN","frontmatter":{"order":3,"title":"运算符","description":"算术运算符 关系运算符 逻辑运算符 位运算符 真值表 假设 赋值运算符 我们可以使用 = 将右边的结果赋值到左边,如 C = A + B 其他符号 符号优先级 从高到低为: 可以使用括号提高优先级 ","head":[["link",{"rel":"alternate","hreflang":"en-us","href":"https://goguide.ryansu.tech/en/guide/concepts/golang/3-operator.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/guide/concepts/golang/3-operator.html"}],["meta",{"property":"og:site_name","content":"Go 面试宝典"}],["meta",{"property":"og:title","content":"运算符"}],["meta",{"property":"og:description","content":"算术运算符 关系运算符 逻辑运算符 位运算符 真值表 假设 赋值运算符 我们可以使用 = 将右边的结果赋值到左边,如 C = A + B 其他符号 符号优先级 从高到低为: 可以使用括号提高优先级 "}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:locale:alternate","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-01-17T10:20:55.000Z"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-01-17T10:20:55.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"运算符\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-01-17T10:20:55.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":2,"title":"算术运算符","slug":"算术运算符","link":"#算术运算符","children":[]},{"level":2,"title":"关系运算符","slug":"关系运算符","link":"#关系运算符","children":[]},{"level":2,"title":"逻辑运算符","slug":"逻辑运算符","link":"#逻辑运算符","children":[]},{"level":2,"title":"位运算符","slug":"位运算符","link":"#位运算符","children":[]},{"level":2,"title":"赋值运算符","slug":"赋值运算符","link":"#赋值运算符","children":[]},{"level":2,"title":"其他符号","slug":"其他符号","link":"#其他符号","children":[]},{"level":2,"title":"符号优先级","slug":"符号优先级","link":"#符号优先级","children":[]}],"git":{"createdTime":1705486855000,"updatedTime":1705486855000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":1}]},"readingTime":{"minutes":1.84,"words":551},"filePathRelative":"guide/concepts/golang/3-operator.md","localizedDate":"2024年1月17日","autoDesc":true,"excerpt":"

算术运算符

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
AB
5020
\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
操作符操作结果描述
+A + B70相加
-A - B30相减
*A * B1000相乘
/A / B2相除
%A % B10取余
++A++51自增
--A--49自减
"}');export{c as comp,g as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as d,c as e,b as r}from"./app-C0BAr50I.js";const a={},n=r('

算术运算符

AB
5020
操作符操作结果描述
+A + B70相加
-A - B30相减
*A * B1000相乘
/A / B2相除
%A % B10取余
++A++51自增
--A--49自减

关系运算符

AB
5020
操作符操作结果描述
==A == Bfalse检查两数是否相等,若相等则为 true,否则为 false
!=A != Btrue检查两数是否不相等,若不相等则为 true , 否则为 false
>A > Btrue检查左边是否大于右边,若成立则为 true, 否则为 false
<A < Bfalse检查左边是否小于右边,若成立则为 true, 否则为 false
>=A >= Btrue检查左边是否大于等于右边,若成立则为 true, 否则为 false
<=A <= Bfalse检查左边是否小于等于右边,若成立则为 true, 否则为 false

逻辑运算符

AB
truefalse
操作符操作结果描述
&&A && Bfalse若两边都为 true,则结果为 true,否则为 false
!=A != Btrue若两边有一边为 true,则结果为 true,若两边都为 false , 则结果为 false
!Afalse若条件为 true 则结果为 false, 反之若条件为 false, 则结果为 true

位运算符

真值表

pqp & qp | qp ^ q
00000
01011
11110
10011

假设

变量
A0110 1000
B0111 0011
操作符操作结果描述
&A & B0110 0000按位进行与运算
|A | B0111 1011按位进行或运算
^A ^ B0001 1011按位进行异或运算
<<A << 21010 0000左移 2 位,低位补 0
>>A >> 20001 1010右移 2 位,高位补 0

赋值运算符

我们可以使用 = 将右边的结果赋值到左边,如 C = A + B

运算符操作等同于
+=A += BA = A + B
-=A -= BA = A - B
*=A *= BA = A * B
/=A /= BA = A / B
%=A %= BA = A % B
<<=A <<= 2A = A << 2
>>=A >>= 2A = A >> 2
&=A &= 2A = A & 2
|=A |= 2A = A | 2
^=A ^= 2A = A ^ 2

其他符号

运算符描述
&取地址
*指针

符号优先级

从高到低为:

优先级运算符
5* / % << >> & &^
4+ - | ^
3== != < <= > >=
2&&
1||

可以使用括号提高优先级

',24),h=[n];function l(o,s){return d(),e("div",null,h)}const c=t(a,[["render",l],["__file","3-operator.html.vue"]]),g=JSON.parse('{"path":"/guide/concepts/golang/3-operator.html","title":"运算符","lang":"zh-CN","frontmatter":{"order":3,"title":"运算符","description":"算术运算符 关系运算符 逻辑运算符 位运算符 真值表 假设 赋值运算符 我们可以使用 = 将右边的结果赋值到左边,如 C = A + B 其他符号 符号优先级 从高到低为: 可以使用括号提高优先级 ","head":[["link",{"rel":"alternate","hreflang":"en-us","href":"https://goguide.ryansu.tech/en/guide/concepts/golang/3-operator.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/guide/concepts/golang/3-operator.html"}],["meta",{"property":"og:site_name","content":"Go 面试宝典"}],["meta",{"property":"og:title","content":"运算符"}],["meta",{"property":"og:description","content":"算术运算符 关系运算符 逻辑运算符 位运算符 真值表 假设 赋值运算符 我们可以使用 = 将右边的结果赋值到左边,如 C = A + B 其他符号 符号优先级 从高到低为: 可以使用括号提高优先级 "}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"og:locale:alternate","content":"en-US"}],["meta",{"property":"og:updated_time","content":"2024-01-17T10:20:55.000Z"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-01-17T10:20:55.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"运算符\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-01-17T10:20:55.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":2,"title":"算术运算符","slug":"算术运算符","link":"#算术运算符","children":[]},{"level":2,"title":"关系运算符","slug":"关系运算符","link":"#关系运算符","children":[]},{"level":2,"title":"逻辑运算符","slug":"逻辑运算符","link":"#逻辑运算符","children":[]},{"level":2,"title":"位运算符","slug":"位运算符","link":"#位运算符","children":[]},{"level":2,"title":"赋值运算符","slug":"赋值运算符","link":"#赋值运算符","children":[]},{"level":2,"title":"其他符号","slug":"其他符号","link":"#其他符号","children":[]},{"level":2,"title":"符号优先级","slug":"符号优先级","link":"#符号优先级","children":[]}],"git":{"createdTime":1705486855000,"updatedTime":1705486855000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":1}]},"readingTime":{"minutes":1.84,"words":551},"filePathRelative":"guide/concepts/golang/3-operator.md","localizedDate":"2024年1月17日","autoDesc":true,"excerpt":"

算术运算符

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
AB
5020
\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
操作符操作结果描述
+A + B70相加
-A - B30相减
*A * B1000相乘
/A / B2相除
%A % B10取余
++A++51自增
--A--49自减
"}');export{c as comp,g as data}; diff --git a/assets/3-operator.html-BWtKH6YH.js b/assets/3-operator.html-C8kTpa_2.js similarity index 99% rename from assets/3-operator.html-BWtKH6YH.js rename to assets/3-operator.html-C8kTpa_2.js index a1989656..f454fc77 100644 --- a/assets/3-operator.html-BWtKH6YH.js +++ b/assets/3-operator.html-C8kTpa_2.js @@ -1 +1 @@ -import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as e,c as d,b as r}from"./app-Bsw6rBWV.js";const a={},o=r('

Arithmetic Operators

AB
5020
OperatorOperationResultDescription
+A + B70Addition
-A - B30Subtraction
*A * B1000Multiplication
/A / B2Division
%A % B10Modulus
++A++51Increment
--A--49Decrement

Relational Operators

AB
5020
OperatorOperationResultDescription
==A == BfalseCheck if two numbers are equal, if yes then true, otherwise false
!=A != BtrueCheck if two numbers are not equal, if yes then true, otherwise false
>A > BtrueCheck if left side is greater than right side, if yes then true, otherwise false
<A < BfalseCheck if left side is less than right side, if yes then true, otherwise false
>=A >= BtrueCheck if left side is greater than or equal to right side, if yes then true, otherwise false
<=A <= BfalseCheck if left side is less than or equal to right side, if yes then true, otherwise false

Logical Operators

AB
truefalse
OperatorOperationResultDescription
&&A && BfalseIf both sides are true, then true, otherwise false
!=A != BtrueIf either side is true, then true, if both sides are false, then false
!!AfalseIf the condition is true, then false, otherwise true

Bitwise Operators

Truth Table

pqp & qp | qp ^ q
00000
01011
11110
10011

Assuming

VariableValue
A0110 1000
B0111 0011
OperatorOperationResultDescription
&A & B0110 0000Bitwise AND
|A | B0111 1011Bitwise OR
^A ^ B0001 1011Bitwise XOR
<<A << 21010 0000Left shift by 2 bits, padded with 0
>>A >> 20001 1010Right shift by 2 bits, padded with 0

Assignment Operators

We can use = to assign the result on the right to the left, such as C = A + B

OperatorOperationEquivalent to
+=A += BA = A + B
-=A -= BA = A - B
*=A *= BA = A * B
/=A /= BA = A / B
%=A %= BA = A % B
<<=A <<= 2A = A << 2
>>=A >>= 2A = A >> 2
&=A &= 2A = A & 2
|=A |= 2A = A | 2
^=A ^= 2A = A ^ 2

Other Symbols

OperatorDescription
&Address of
*Pointer

Symbol Precedence

From high to low:

PrecedenceOperator
5* / % << >> & &^
4+ - | ^
3== != < <= > >=
2&&
1||

Parentheses can be used to increase precedence

',24),n=[o];function s(h,i){return e(),d("div",null,n)}const c=t(a,[["render",s],["__file","3-operator.html.vue"]]),g=JSON.parse('{"path":"/en/guide/concepts/golang/3-operator.html","title":"Operators","lang":"en-US","frontmatter":{"order":3,"title":"Operators","description":"Arithmetic Operators Relational Operators Logical Operators Bitwise Operators Truth Table Assuming Assignment Operators We can use = to assign the result on the right to the lef...","head":[["link",{"rel":"alternate","hreflang":"zh-cn","href":"https://goguide.ryansu.tech/guide/concepts/golang/3-operator.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/en/guide/concepts/golang/3-operator.html"}],["meta",{"property":"og:site_name","content":"Go Guide"}],["meta",{"property":"og:title","content":"Operators"}],["meta",{"property":"og:description","content":"Arithmetic Operators Relational Operators Logical Operators Bitwise Operators Truth Table Assuming Assignment Operators We can use = to assign the result on the right to the lef..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:locale:alternate","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-01-17T10:20:55.000Z"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-01-17T10:20:55.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Operators\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-01-17T10:20:55.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":2,"title":"Arithmetic Operators","slug":"arithmetic-operators","link":"#arithmetic-operators","children":[]},{"level":2,"title":"Relational Operators","slug":"relational-operators","link":"#relational-operators","children":[]},{"level":2,"title":"Logical Operators","slug":"logical-operators","link":"#logical-operators","children":[]},{"level":2,"title":"Bitwise Operators","slug":"bitwise-operators","link":"#bitwise-operators","children":[]},{"level":2,"title":"Assignment Operators","slug":"assignment-operators","link":"#assignment-operators","children":[]},{"level":2,"title":"Other Symbols","slug":"other-symbols","link":"#other-symbols","children":[]},{"level":2,"title":"Symbol Precedence","slug":"symbol-precedence","link":"#symbol-precedence","children":[]}],"git":{"createdTime":1705486855000,"updatedTime":1705486855000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":1}]},"readingTime":{"minutes":1.34,"words":403},"filePathRelative":"en/guide/concepts/golang/3-operator.md","localizedDate":"January 17, 2024","autoDesc":true,"excerpt":"

Arithmetic Operators

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
AB
5020
\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
OperatorOperationResultDescription
+A + B70Addition
-A - B30Subtraction
*A * B1000Multiplication
/A / B2Division
%A % B10Modulus
++A++51Increment
--A--49Decrement
"}');export{c as comp,g as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as e,c as d,b as r}from"./app-C0BAr50I.js";const a={},o=r('

Arithmetic Operators

AB
5020
OperatorOperationResultDescription
+A + B70Addition
-A - B30Subtraction
*A * B1000Multiplication
/A / B2Division
%A % B10Modulus
++A++51Increment
--A--49Decrement

Relational Operators

AB
5020
OperatorOperationResultDescription
==A == BfalseCheck if two numbers are equal, if yes then true, otherwise false
!=A != BtrueCheck if two numbers are not equal, if yes then true, otherwise false
>A > BtrueCheck if left side is greater than right side, if yes then true, otherwise false
<A < BfalseCheck if left side is less than right side, if yes then true, otherwise false
>=A >= BtrueCheck if left side is greater than or equal to right side, if yes then true, otherwise false
<=A <= BfalseCheck if left side is less than or equal to right side, if yes then true, otherwise false

Logical Operators

AB
truefalse
OperatorOperationResultDescription
&&A && BfalseIf both sides are true, then true, otherwise false
!=A != BtrueIf either side is true, then true, if both sides are false, then false
!!AfalseIf the condition is true, then false, otherwise true

Bitwise Operators

Truth Table

pqp & qp | qp ^ q
00000
01011
11110
10011

Assuming

VariableValue
A0110 1000
B0111 0011
OperatorOperationResultDescription
&A & B0110 0000Bitwise AND
|A | B0111 1011Bitwise OR
^A ^ B0001 1011Bitwise XOR
<<A << 21010 0000Left shift by 2 bits, padded with 0
>>A >> 20001 1010Right shift by 2 bits, padded with 0

Assignment Operators

We can use = to assign the result on the right to the left, such as C = A + B

OperatorOperationEquivalent to
+=A += BA = A + B
-=A -= BA = A - B
*=A *= BA = A * B
/=A /= BA = A / B
%=A %= BA = A % B
<<=A <<= 2A = A << 2
>>=A >>= 2A = A >> 2
&=A &= 2A = A & 2
|=A |= 2A = A | 2
^=A ^= 2A = A ^ 2

Other Symbols

OperatorDescription
&Address of
*Pointer

Symbol Precedence

From high to low:

PrecedenceOperator
5* / % << >> & &^
4+ - | ^
3== != < <= > >=
2&&
1||

Parentheses can be used to increase precedence

',24),n=[o];function s(h,i){return e(),d("div",null,n)}const c=t(a,[["render",s],["__file","3-operator.html.vue"]]),g=JSON.parse('{"path":"/en/guide/concepts/golang/3-operator.html","title":"Operators","lang":"en-US","frontmatter":{"order":3,"title":"Operators","description":"Arithmetic Operators Relational Operators Logical Operators Bitwise Operators Truth Table Assuming Assignment Operators We can use = to assign the result on the right to the lef...","head":[["link",{"rel":"alternate","hreflang":"zh-cn","href":"https://goguide.ryansu.tech/guide/concepts/golang/3-operator.html"}],["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/en/guide/concepts/golang/3-operator.html"}],["meta",{"property":"og:site_name","content":"Go Guide"}],["meta",{"property":"og:title","content":"Operators"}],["meta",{"property":"og:description","content":"Arithmetic Operators Relational Operators Logical Operators Bitwise Operators Truth Table Assuming Assignment Operators We can use = to assign the result on the right to the lef..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"en-US"}],["meta",{"property":"og:locale:alternate","content":"zh-CN"}],["meta",{"property":"og:updated_time","content":"2024-01-17T10:20:55.000Z"}],["meta",{"property":"article:author","content":"Go Guide"}],["meta",{"property":"article:modified_time","content":"2024-01-17T10:20:55.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"Operators\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2024-01-17T10:20:55.000Z\\",\\"author\\":[{\\"@type\\":\\"Person\\",\\"name\\":\\"Go Guide\\",\\"url\\":\\"https://github.com/suyuan32\\"}]}"]]},"headers":[{"level":2,"title":"Arithmetic Operators","slug":"arithmetic-operators","link":"#arithmetic-operators","children":[]},{"level":2,"title":"Relational Operators","slug":"relational-operators","link":"#relational-operators","children":[]},{"level":2,"title":"Logical Operators","slug":"logical-operators","link":"#logical-operators","children":[]},{"level":2,"title":"Bitwise Operators","slug":"bitwise-operators","link":"#bitwise-operators","children":[]},{"level":2,"title":"Assignment Operators","slug":"assignment-operators","link":"#assignment-operators","children":[]},{"level":2,"title":"Other Symbols","slug":"other-symbols","link":"#other-symbols","children":[]},{"level":2,"title":"Symbol Precedence","slug":"symbol-precedence","link":"#symbol-precedence","children":[]}],"git":{"createdTime":1705486855000,"updatedTime":1705486855000,"contributors":[{"name":"Ryan Su","email":"yuansu.china.work@gmail.com","commits":1}]},"readingTime":{"minutes":1.34,"words":403},"filePathRelative":"en/guide/concepts/golang/3-operator.md","localizedDate":"January 17, 2024","autoDesc":true,"excerpt":"

Arithmetic Operators

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
AB
5020
\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
OperatorOperationResultDescription
+A + B70Addition
-A - B30Subtraction
*A * B1000Multiplication
/A / B2Division
%A % B10Modulus
++A++51Increment
--A--49Decrement
"}');export{c as comp,g as data}; diff --git a/assets/4-errorhandling.html-Cq7NUd58.js b/assets/4-errorhandling.html-DNHfljPB.js similarity index 99% rename from assets/4-errorhandling.html-Cq7NUd58.js rename to assets/4-errorhandling.html-DNHfljPB.js index 9f286d8f..c49c7af5 100644 --- a/assets/4-errorhandling.html-Cq7NUd58.js +++ b/assets/4-errorhandling.html-DNHfljPB.js @@ -1,4 +1,4 @@ -import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,b as e}from"./app-Bsw6rBWV.js";const t={},o=e(`

接口

golang 提供了 error 类型的接口

type error interface {
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,b as e}from"./app-C0BAr50I.js";const t={},o=e(`

接口

golang 提供了 error 类型的接口

type error interface {
     Error() string
 }
 

只要结构体实现了 Error() 方法就属于 error 类型

创建错误

golang 提供了多种创建 error 的方法

我们可以使用 errors.New() fmt.Errorf() 来创建错误

例子
package main
diff --git a/assets/4-errorhandling.html-CZWtCtwI.js b/assets/4-errorhandling.html-E6HmUyLW.js
similarity index 99%
rename from assets/4-errorhandling.html-CZWtCtwI.js
rename to assets/4-errorhandling.html-E6HmUyLW.js
index a43cd792..6588adf9 100644
--- a/assets/4-errorhandling.html-CZWtCtwI.js
+++ b/assets/4-errorhandling.html-E6HmUyLW.js
@@ -1,4 +1,4 @@
-import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,b as e}from"./app-Bsw6rBWV.js";const t={},o=e(`

Interface

Golang provides an interface type error:

type error interface {
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,b as e}from"./app-C0BAr50I.js";const t={},o=e(`

Interface

Golang provides an interface type error:

type error interface {
     Error() string
 }
 

Any structure that implements the Error() method belongs to the error type.

Creating Errors

Golang provides several ways to create an error.

We can use errors.New() or fmt.Errorf() to create errors.

Example
package main
diff --git a/assets/404.html-B3jmriWY.js b/assets/404.html-DPAHxMnN.js
similarity index 94%
rename from assets/404.html-B3jmriWY.js
rename to assets/404.html-DPAHxMnN.js
index c831cb40..55a7de9a 100644
--- a/assets/404.html-B3jmriWY.js
+++ b/assets/404.html-DPAHxMnN.js
@@ -1 +1 @@
-import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as e,c as o,a as n}from"./app-Bsw6rBWV.js";const r={},a=n("p",null,"404 Not Found",-1),c=[a];function p(s,i){return e(),o("div",null,c)}const m=t(r,[["render",p],["__file","404.html.vue"]]),u=JSON.parse('{"path":"/404.html","title":"","lang":"zh-CN","frontmatter":{"layout":"NotFound","description":"404 Not Found ","head":[["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/404.html"}],["meta",{"property":"og:site_name","content":"Go 面试宝典"}],["meta",{"property":"og:description","content":"404 Not Found "}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"Go Guide"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"\\",\\"description\\":\\"404 Not Found \\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0.01,"words":3},"filePathRelative":null,"autoDesc":true,"excerpt":"

404 Not Found

\\n"}');export{m as comp,u as data}; +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as e,c as o,a as n}from"./app-C0BAr50I.js";const r={},a=n("p",null,"404 Not Found",-1),c=[a];function p(s,i){return e(),o("div",null,c)}const m=t(r,[["render",p],["__file","404.html.vue"]]),u=JSON.parse('{"path":"/404.html","title":"","lang":"zh-CN","frontmatter":{"layout":"NotFound","description":"404 Not Found ","head":[["meta",{"property":"og:url","content":"https://goguide.ryansu.tech/404.html"}],["meta",{"property":"og:site_name","content":"Go 面试宝典"}],["meta",{"property":"og:description","content":"404 Not Found "}],["meta",{"property":"og:type","content":"website"}],["meta",{"property":"og:locale","content":"zh-CN"}],["meta",{"property":"article:author","content":"Go Guide"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"WebPage\\",\\"name\\":\\"\\",\\"description\\":\\"404 Not Found \\"}"]]},"headers":[],"git":{},"readingTime":{"minutes":0.01,"words":3},"filePathRelative":null,"autoDesc":true,"excerpt":"

404 Not Found

\\n"}');export{m as comp,u as data}; diff --git a/assets/5-map.html-DJfb0ND7.js b/assets/5-map.html-CaKde_jH.js similarity index 99% rename from assets/5-map.html-DJfb0ND7.js rename to assets/5-map.html-CaKde_jH.js index 425abd3a..68ecacc6 100644 --- a/assets/5-map.html-DJfb0ND7.js +++ b/assets/5-map.html-CaKde_jH.js @@ -1,4 +1,4 @@ -import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,d as t,b as e}from"./app-Bsw6rBWV.js";const p={},i=e(`

创建 Map

map 是一种键值映射表,通过 key 获取对应的 value

map 的声明方式

map[KeyType]ValueType
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,d as t,b as e}from"./app-C0BAr50I.js";const p={},i=e(`

创建 Map

map 是一种键值映射表,通过 key 获取对应的 value

map 的声明方式

map[KeyType]ValueType
 

KeyType 为 key 的数据类型 , ValueTypevalue 的数据类型

例子
// 声明 map
 var m map[string]int
 
diff --git a/assets/5-map.html-BucnXcKM.js b/assets/5-map.html-coD4WfmK.js
similarity index 99%
rename from assets/5-map.html-BucnXcKM.js
rename to assets/5-map.html-coD4WfmK.js
index f90802be..2115c372 100644
--- a/assets/5-map.html-BucnXcKM.js
+++ b/assets/5-map.html-coD4WfmK.js
@@ -1,4 +1,4 @@
-import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as s,d as e,b as t}from"./app-Bsw6rBWV.js";const p={},i=t(`

Creating a Map

map is a key-value mapping table, where you can get the corresponding value by using the key.

The declaration of map is as follows:

map[KeyType]ValueType
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as s,d as e,b as t}from"./app-C0BAr50I.js";const p={},i=t(`

Creating a Map

map is a key-value mapping table, where you can get the corresponding value by using the key.

The declaration of map is as follows:

map[KeyType]ValueType
 

KeyType is the data type of the key, and ValueType is the data type of the value.

Example
// Declare a map
 var m map[string]int
 
diff --git a/assets/6-slice.html-JMIMK1-9.js b/assets/6-slice.html-D0sTuz-d.js
similarity index 99%
rename from assets/6-slice.html-JMIMK1-9.js
rename to assets/6-slice.html-D0sTuz-d.js
index 178fa20c..41fcbac7 100644
--- a/assets/6-slice.html-JMIMK1-9.js
+++ b/assets/6-slice.html-D0sTuz-d.js
@@ -1,4 +1,4 @@
-import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,b as t}from"./app-Bsw6rBWV.js";const e={},p=t(`

创建切片

有三种方式可以创建切片

package main
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as s,c as a,b as t}from"./app-C0BAr50I.js";const e={},p=t(`

创建切片

有三种方式可以创建切片

package main
 
 import "fmt"
 
diff --git a/assets/6-slice.html-CTtneWZ6.js b/assets/6-slice.html-DxG6N77X.js
similarity index 99%
rename from assets/6-slice.html-CTtneWZ6.js
rename to assets/6-slice.html-DxG6N77X.js
index fa6d126c..811b860d 100644
--- a/assets/6-slice.html-CTtneWZ6.js
+++ b/assets/6-slice.html-DxG6N77X.js
@@ -1,4 +1,4 @@
-import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as s,b as t}from"./app-Bsw6rBWV.js";const e={},p=t(`

Creating Slices

There are three ways to create slices.

package main
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as s,b as t}from"./app-C0BAr50I.js";const e={},p=t(`

Creating Slices

There are three ways to create slices.

package main
 
 import "fmt"
 
diff --git a/assets/7-channel.html-6gWgcYt9.js b/assets/7-channel.html-DWDDXmkq.js
similarity index 99%
rename from assets/7-channel.html-6gWgcYt9.js
rename to assets/7-channel.html-DWDDXmkq.js
index 59438d52..053d1190 100644
--- a/assets/7-channel.html-6gWgcYt9.js
+++ b/assets/7-channel.html-DWDDXmkq.js
@@ -1,4 +1,4 @@
-import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as e,c as a,b as s}from"./app-Bsw6rBWV.js";const t={},c=s(`

Introduction

A channel is a conduit for end-to-end data communication, often used for data sharing between goroutines.

Creating a channel

We use make to create a channel

ch1 := make(chan T) // Unbuffered
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as e,c as a,b as s}from"./app-C0BAr50I.js";const t={},c=s(`

Introduction

A channel is a conduit for end-to-end data communication, often used for data sharing between goroutines.

Creating a channel

We use make to create a channel

ch1 := make(chan T) // Unbuffered
 
 ch2 := make(chan T, 2) // Buffered
 

T is the data type.

Warning

  • An unbuffered channel will be blocked until the data is received
  • A buffered channel will be blocked when the sent data reaches the buffer size

Sending and receiving data

Using <- pointing to the channel means sending data to that channel, such as ch <- 10

Using <- on the left side of the channel means receiving data, such as <-ch

Closing a channel

Use close() to close a channel

close(ch)
diff --git a/assets/7-channel.html-CQe5Eha5.js b/assets/7-channel.html-DcY0VHb2.js
similarity index 99%
rename from assets/7-channel.html-CQe5Eha5.js
rename to assets/7-channel.html-DcY0VHb2.js
index cf02b3ea..1fd86119 100644
--- a/assets/7-channel.html-CQe5Eha5.js
+++ b/assets/7-channel.html-DcY0VHb2.js
@@ -1,4 +1,4 @@
-import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as e,b as s}from"./app-Bsw6rBWV.js";const t={},c=s(`

介绍

channel 是一个信道,用于端到端数据的通信,常用于 goroutine 之间数据共享。

创建 channel

我们使用 make 来创建 channel

ch1 := make(chan T) // 无缓冲
+import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as e,b as s}from"./app-C0BAr50I.js";const t={},c=s(`

介绍

channel 是一个信道,用于端到端数据的通信,常用于 goroutine 之间数据共享。

创建 channel

我们使用 make 来创建 channel

ch1 := make(chan T) // 无缓冲
 
 ch2 := make(chan T, 2) // 带缓冲
 

T 为数据类型。

注意

  • 无缓冲区的信道会被阻塞直到数据被接收
  • 有缓冲区的信道在发送的数据达到缓冲区大小后才会被阻塞

发送接收数据

使用 <- 指向 channel 表示发送数据到该 channel, 如 ch <- 10

使用 <- 在 channel 左侧表示接收数据,如 <-ch

关闭 channel

使用 close() 关闭 channel

close(ch)
diff --git a/assets/8-context.html-Ckq0jHxV.js b/assets/8-context.html-B9nsgQ4v.js
similarity index 99%
rename from assets/8-context.html-Ckq0jHxV.js
rename to assets/8-context.html-B9nsgQ4v.js
index 99ac3896..de5c6a7e 100644
--- a/assets/8-context.html-Ckq0jHxV.js
+++ b/assets/8-context.html-B9nsgQ4v.js
@@ -1,4 +1,4 @@
-import{_ as n}from"./context-D1eIaWGO.js";import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as t,b as e}from"./app-Bsw6rBWV.js";const o={},i=e(`

Introduction

Context is a very important interface in Golang, used to define the context information in goroutine. Context is commonly used in the following situations:

  • Data transfer: Transfer data among multiple goroutines.
  • Timeout management: By setting a timeout, the termination time of the coroutine can be conveniently configured.
  • Terminate coroutine: By using the cancel() method, the coroutine can be easily terminated, and multiple coroutines can be managed in batches.

Context Interface

// A Context carries a deadline, a cancelation signal, and other values across
+import{_ as n}from"./context-D1eIaWGO.js";import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as t,b as e}from"./app-C0BAr50I.js";const o={},i=e(`

Introduction

Context is a very important interface in Golang, used to define the context information in goroutine. Context is commonly used in the following situations:

  • Data transfer: Transfer data among multiple goroutines.
  • Timeout management: By setting a timeout, the termination time of the coroutine can be conveniently configured.
  • Terminate coroutine: By using the cancel() method, the coroutine can be easily terminated, and multiple coroutines can be managed in batches.

Context Interface

// A Context carries a deadline, a cancelation signal, and other values across
 // API boundaries.
 //
 // Context's methods may be called by multiple goroutines simultaneously.
diff --git a/assets/8-context.html-DI8Yqf21.js b/assets/8-context.html-BURlTMoP.js
similarity index 99%
rename from assets/8-context.html-DI8Yqf21.js
rename to assets/8-context.html-BURlTMoP.js
index dc36c196..5233fa2f 100644
--- a/assets/8-context.html-DI8Yqf21.js
+++ b/assets/8-context.html-BURlTMoP.js
@@ -1,4 +1,4 @@
-import{_ as n}from"./context-D1eIaWGO.js";import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as t,b as e}from"./app-Bsw6rBWV.js";const c={},o=e(`

介绍

Context 是 golang 中十分重要的接口,用于定义 goroutine 中的上下文信息,context 常用于以下几种情况:

  • 数据传递: 在多个 goroutine 中传递数据
  • 超时管理: 通过配置超时时间,可以方便地配置协程的终止时间
  • 终止协程: 通过使用 cancel() 方法,协程可以很方便地终止,可以批量管理多个协程的终止

Context 接口

// A Context carries a deadline, a cancelation signal, and other values across
+import{_ as n}from"./context-D1eIaWGO.js";import{_ as s}from"./plugin-vue_export-helper-DlAUqK2U.js";import{o as a,c as t,b as e}from"./app-C0BAr50I.js";const c={},o=e(`

介绍

Context 是 golang 中十分重要的接口,用于定义 goroutine 中的上下文信息,context 常用于以下几种情况:

  • 数据传递: 在多个 goroutine 中传递数据
  • 超时管理: 通过配置超时时间,可以方便地配置协程的终止时间
  • 终止协程: 通过使用 cancel() 方法,协程可以很方便地终止,可以批量管理多个协程的终止

Context 接口

// A Context carries a deadline, a cancelation signal, and other values across
 // API boundaries.
 //
 // Context's methods may be called by multiple goroutines simultaneously.
diff --git a/assets/SearchResult-BDxOW_ov.js b/assets/SearchResult-Q8xgYrff.js
similarity index 98%
rename from assets/SearchResult-BDxOW_ov.js
rename to assets/SearchResult-Q8xgYrff.js
index 5f3d85eb..3f78f74f 100644
--- a/assets/SearchResult-BDxOW_ov.js
+++ b/assets/SearchResult-Q8xgYrff.js
@@ -1 +1 @@
-import{u as j,g as Z,h as ee,i as B,j as se,k as ae,t as te,l as le,m as b,n as A,p as re,w as M,q as a,s as I,v as O,R as U,x as ue,y as ne,z as ie,A as oe,B as ce,C as ve,D as pe,E as ye,F as de,G as he,H as me,I as fe,J as ge,K as L}from"./app-Bsw6rBWV.js";const He=[],Re="SEARCH_PRO_QUERY_HISTORY",y=j(Re,[]),ke=()=>{const{queryHistoryCount:t}=L,l=t>0;return{enabled:l,queryHistory:y,addQueryHistory:r=>{l&&(y.value.length{y.value=[...y.value.slice(0,r),...y.value.slice(r+1)]}}},E=t=>He[t.id]+("anchor"in t?`#${t.anchor}`:""),Qe="SEARCH_PRO_RESULT_HISTORY",{resultHistoryCount:D}=L,d=j(Qe,[]),xe=()=>{const t=D>0;return{enabled:t,resultHistory:d,addResultHistory:l=>{if(t){const r={link:E(l),display:l.display};"header"in l&&(r.header=l.header),d.value.length{d.value=[...d.value.slice(0,l),...d.value.slice(l+1)]}}},we=t=>{const l=ce(),r=B(),{search:Q,terminate:v}=ve(),m=b(!1),f=pe([]);return ye(()=>{const h=()=>{f.value=[],m.value=!1},x=ge(g=>{m.value=!0,g?Q({type:"search",query:g,locale:r.value,options:l}).then(p=>{f.value=p,m.value=!1}).catch(p=>{console.error(p),h()}):h()},L.searchDelay);M([t,r],()=>x(t.value),{immediate:!0}),de(()=>{v()})}),{searching:m,results:f}};var Ce=Z({name:"SearchResult",props:{query:{type:String,required:!0},isFocusing:Boolean},emits:["close","updateQuery"],setup(t,{emit:l}){const r=ee(),Q=B(),v=se(ae),{enabled:m,addQueryHistory:f,queryHistory:h,removeQueryHistory:x}=ke(),{enabled:g,resultHistory:p,addResultHistory:T,removeResultHistory:Y}=xe(),P=m||g,w=te(t,"query"),{results:H,searching:z}=we(w),u=le({isQuery:!0,index:0}),o=b(0),c=b(0),_=A(()=>P&&(h.value.length>0||p.value.length>0)),S=A(()=>H.value.length>0),C=A(()=>H.value[o.value]||null),G=()=>{const{isQuery:e,index:s}=u;s===0?(u.isQuery=!e,u.index=e?p.value.length-1:h.value.length-1):u.index=s-1},J=()=>{const{isQuery:e,index:s}=u;s===(e?h.value.length-1:p.value.length-1)?(u.isQuery=!e,u.index=0):u.index=s+1},K=()=>{o.value=o.value>0?o.value-1:H.value.length-1,c.value=C.value.contents.length-1},V=()=>{o.value=o.value{c.value{c.value>0?c.value-=1:K()},q=e=>e.map(s=>he(s)?s:a(s[0],s[1])),W=e=>{if(e.type==="customField"){const s=me[e.index]||"$content",[n,k=""]=fe(s)?s[Q.value].split("$content"):s.split("$content");return e.display.map(i=>a("div",q([n,...i,k])))}return e.display.map(s=>a("div",q(s)))},R=()=>{o.value=0,c.value=0,l("updateQuery",""),l("close")};return re("keydown",e=>{if(t.isFocusing){if(S.value){if(e.key==="ArrowUp")N();else if(e.key==="ArrowDown")$();else if(e.key==="Enter"){const s=C.value.contents[c.value];f(t.query),T(s),r.push(E(s)),R()}}else if(g){if(e.key==="ArrowUp")G();else if(e.key==="ArrowDown")J();else if(e.key==="Enter"){const{index:s}=u;u.isQuery?(l("updateQuery",h.value[s]),e.preventDefault()):(r.push(p.value[s].link),R())}}}}),M([o,c],()=>{var e;(e=document.querySelector(".search-pro-result-list-item.active .search-pro-result-item.active"))==null||e.scrollIntoView(!1)},{flush:"post"}),()=>a("div",{class:["search-pro-result-wrapper",{empty:w.value?!S.value:!_.value}],id:"search-pro-results"},w.value===""?P?_.value?[m?a("ul",{class:"search-pro-result-list"},a("li",{class:"search-pro-result-list-item"},[a("div",{class:"search-pro-result-title"},v.value.queryHistory),h.value.map((e,s)=>a("div",{class:["search-pro-result-item",{active:u.isQuery&&u.index===s}],onClick:()=>{l("updateQuery",e)}},[a(I,{class:"search-pro-result-type"}),a("div",{class:"search-pro-result-content"},e),a("button",{class:"search-pro-remove-icon",innerHTML:O,onClick:n=>{n.preventDefault(),n.stopPropagation(),x(s)}})]))])):null,g?a("ul",{class:"search-pro-result-list"},a("li",{class:"search-pro-result-list-item"},[a("div",{class:"search-pro-result-title"},v.value.resultHistory),p.value.map((e,s)=>a(U,{to:e.link,class:["search-pro-result-item",{active:!u.isQuery&&u.index===s}],onClick:()=>{R()}},()=>[a(I,{class:"search-pro-result-type"}),a("div",{class:"search-pro-result-content"},[e.header?a("div",{class:"content-header"},e.header):null,a("div",e.display.map(n=>q(n)).flat())]),a("button",{class:"search-pro-remove-icon",innerHTML:O,onClick:n=>{n.preventDefault(),n.stopPropagation(),Y(s)}})]))])):null]:v.value.emptyHistory:v.value.emptyResult:z.value?a(ue,{hint:v.value.searching}):S.value?a("ul",{class:"search-pro-result-list"},H.value.map(({title:e,contents:s},n)=>{const k=o.value===n;return a("li",{class:["search-pro-result-list-item",{active:k}]},[a("div",{class:"search-pro-result-title"},e||v.value.defaultTitle),s.map((i,X)=>{const F=k&&c.value===X;return a(U,{to:E(i),class:["search-pro-result-item",{active:F,"aria-selected":F}],onClick:()=>{f(t.query),T(i),R()}},()=>[i.type==="text"?null:a(i.type==="title"?ne:i.type==="heading"?ie:oe,{class:"search-pro-result-type"}),a("div",{class:"search-pro-result-content"},[i.type==="text"&&i.header?a("div",{class:"content-header"},i.header):null,a("div",W(i))])])})])})):v.value.emptyResult)}});export{Ce as default};
+import{u as j,g as Z,h as ee,i as B,j as se,k as ae,t as te,l as le,m as b,n as A,p as re,w as M,q as a,s as I,v as O,R as U,x as ue,y as ne,z as ie,A as oe,B as ce,C as ve,D as pe,E as ye,F as de,G as he,H as me,I as fe,J as ge,K as L}from"./app-C0BAr50I.js";const He=[],Re="SEARCH_PRO_QUERY_HISTORY",y=j(Re,[]),ke=()=>{const{queryHistoryCount:t}=L,l=t>0;return{enabled:l,queryHistory:y,addQueryHistory:r=>{l&&(y.value.length{y.value=[...y.value.slice(0,r),...y.value.slice(r+1)]}}},E=t=>He[t.id]+("anchor"in t?`#${t.anchor}`:""),Qe="SEARCH_PRO_RESULT_HISTORY",{resultHistoryCount:D}=L,d=j(Qe,[]),xe=()=>{const t=D>0;return{enabled:t,resultHistory:d,addResultHistory:l=>{if(t){const r={link:E(l),display:l.display};"header"in l&&(r.header=l.header),d.value.length{d.value=[...d.value.slice(0,l),...d.value.slice(l+1)]}}},we=t=>{const l=ce(),r=B(),{search:Q,terminate:v}=ve(),m=b(!1),f=pe([]);return ye(()=>{const h=()=>{f.value=[],m.value=!1},x=ge(g=>{m.value=!0,g?Q({type:"search",query:g,locale:r.value,options:l}).then(p=>{f.value=p,m.value=!1}).catch(p=>{console.error(p),h()}):h()},L.searchDelay);M([t,r],()=>x(t.value),{immediate:!0}),de(()=>{v()})}),{searching:m,results:f}};var Ce=Z({name:"SearchResult",props:{query:{type:String,required:!0},isFocusing:Boolean},emits:["close","updateQuery"],setup(t,{emit:l}){const r=ee(),Q=B(),v=se(ae),{enabled:m,addQueryHistory:f,queryHistory:h,removeQueryHistory:x}=ke(),{enabled:g,resultHistory:p,addResultHistory:T,removeResultHistory:Y}=xe(),P=m||g,w=te(t,"query"),{results:H,searching:z}=we(w),u=le({isQuery:!0,index:0}),o=b(0),c=b(0),_=A(()=>P&&(h.value.length>0||p.value.length>0)),S=A(()=>H.value.length>0),C=A(()=>H.value[o.value]||null),G=()=>{const{isQuery:e,index:s}=u;s===0?(u.isQuery=!e,u.index=e?p.value.length-1:h.value.length-1):u.index=s-1},J=()=>{const{isQuery:e,index:s}=u;s===(e?h.value.length-1:p.value.length-1)?(u.isQuery=!e,u.index=0):u.index=s+1},K=()=>{o.value=o.value>0?o.value-1:H.value.length-1,c.value=C.value.contents.length-1},V=()=>{o.value=o.value{c.value{c.value>0?c.value-=1:K()},q=e=>e.map(s=>he(s)?s:a(s[0],s[1])),W=e=>{if(e.type==="customField"){const s=me[e.index]||"$content",[n,k=""]=fe(s)?s[Q.value].split("$content"):s.split("$content");return e.display.map(i=>a("div",q([n,...i,k])))}return e.display.map(s=>a("div",q(s)))},R=()=>{o.value=0,c.value=0,l("updateQuery",""),l("close")};return re("keydown",e=>{if(t.isFocusing){if(S.value){if(e.key==="ArrowUp")N();else if(e.key==="ArrowDown")$();else if(e.key==="Enter"){const s=C.value.contents[c.value];f(t.query),T(s),r.push(E(s)),R()}}else if(g){if(e.key==="ArrowUp")G();else if(e.key==="ArrowDown")J();else if(e.key==="Enter"){const{index:s}=u;u.isQuery?(l("updateQuery",h.value[s]),e.preventDefault()):(r.push(p.value[s].link),R())}}}}),M([o,c],()=>{var e;(e=document.querySelector(".search-pro-result-list-item.active .search-pro-result-item.active"))==null||e.scrollIntoView(!1)},{flush:"post"}),()=>a("div",{class:["search-pro-result-wrapper",{empty:w.value?!S.value:!_.value}],id:"search-pro-results"},w.value===""?P?_.value?[m?a("ul",{class:"search-pro-result-list"},a("li",{class:"search-pro-result-list-item"},[a("div",{class:"search-pro-result-title"},v.value.queryHistory),h.value.map((e,s)=>a("div",{class:["search-pro-result-item",{active:u.isQuery&&u.index===s}],onClick:()=>{l("updateQuery",e)}},[a(I,{class:"search-pro-result-type"}),a("div",{class:"search-pro-result-content"},e),a("button",{class:"search-pro-remove-icon",innerHTML:O,onClick:n=>{n.preventDefault(),n.stopPropagation(),x(s)}})]))])):null,g?a("ul",{class:"search-pro-result-list"},a("li",{class:"search-pro-result-list-item"},[a("div",{class:"search-pro-result-title"},v.value.resultHistory),p.value.map((e,s)=>a(U,{to:e.link,class:["search-pro-result-item",{active:!u.isQuery&&u.index===s}],onClick:()=>{R()}},()=>[a(I,{class:"search-pro-result-type"}),a("div",{class:"search-pro-result-content"},[e.header?a("div",{class:"content-header"},e.header):null,a("div",e.display.map(n=>q(n)).flat())]),a("button",{class:"search-pro-remove-icon",innerHTML:O,onClick:n=>{n.preventDefault(),n.stopPropagation(),Y(s)}})]))])):null]:v.value.emptyHistory:v.value.emptyResult:z.value?a(ue,{hint:v.value.searching}):S.value?a("ul",{class:"search-pro-result-list"},H.value.map(({title:e,contents:s},n)=>{const k=o.value===n;return a("li",{class:["search-pro-result-list-item",{active:k}]},[a("div",{class:"search-pro-result-title"},e||v.value.defaultTitle),s.map((i,X)=>{const F=k&&c.value===X;return a(U,{to:E(i),class:["search-pro-result-item",{active:F,"aria-selected":F}],onClick:()=>{f(t.query),T(i),R()}},()=>[i.type==="text"?null:a(i.type==="title"?ne:i.type==="heading"?ie:oe,{class:"search-pro-result-type"}),a("div",{class:"search-pro-result-content"},[i.type==="text"&&i.header?a("div",{class:"content-header"},i.header):null,a("div",W(i))])])})])})):v.value.emptyResult)}});export{Ce as default};
diff --git a/assets/app-Bsw6rBWV.js b/assets/app-C0BAr50I.js
similarity index 96%
rename from assets/app-Bsw6rBWV.js
rename to assets/app-C0BAr50I.js
index 703bd806..3db769b3 100644
--- a/assets/app-Bsw6rBWV.js
+++ b/assets/app-C0BAr50I.js
@@ -14,7 +14,7 @@
 * @vue/runtime-dom v3.4.19
 * (c) 2018-present Yuxi (Evan) You and Vue contributors
 * @license MIT
-**/const xd="http://www.w3.org/2000/svg",Td="http://www.w3.org/1998/Math/MathML",jt=typeof document<"u"?document:null,ks=jt&&jt.createElement("template"),Ld={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const o=t==="svg"?jt.createElementNS(xd,e):t==="mathml"?jt.createElementNS(Td,e):jt.createElement(e,n?{is:n}:void 0);return e==="select"&&r&&r.multiple!=null&&o.setAttribute("multiple",r.multiple),o},createText:e=>jt.createTextNode(e),createComment:e=>jt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>jt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,o,l){const s=n?n.previousSibling:t.lastChild;if(o&&(o===l||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===l||!(o=o.nextSibling)););else{ks.innerHTML=r==="svg"?`${e}`:r==="mathml"?`${e}`:e;const a=ks.content;if(r==="svg"||r==="mathml"){const c=a.firstChild;for(;c.firstChild;)a.appendChild(c.firstChild);a.removeChild(c)}t.insertBefore(a,n)}return[s?s.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Rt="transition",Fn="animation",In=Symbol("_vtc"),Wt=(e,{slots:t})=>u(Rf,Ci(e),t);Wt.displayName="Transition";const Ei={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},Sd=Wt.props=Se({},ei,Ei),en=(e,t=[])=>{ne(e)?e.forEach(n=>n(...t)):e&&e(...t)},xs=e=>e?ne(e)?e.some(t=>t.length>1):e.length>1:!1;function Ci(e){const t={};for(const j in e)j in Ei||(t[j]=e[j]);if(e.css===!1)return t;const{name:n="v",type:r,duration:o,enterFromClass:l=`${n}-enter-from`,enterActiveClass:s=`${n}-enter-active`,enterToClass:a=`${n}-enter-to`,appearFromClass:c=l,appearActiveClass:i=s,appearToClass:f=a,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:p=`${n}-leave-active`,leaveToClass:h=`${n}-leave-to`}=e,g=Ad(o),w=g&&g[0],_=g&&g[1],{onBeforeEnter:y,onEnter:x,onEnterCancelled:b,onLeave:k,onLeaveCancelled:O,onBeforeAppear:C=y,onAppear:M=x,onAppearCancelled:P=b}=t,$=(j,Q,_e)=>{$t(j,Q?f:a),$t(j,Q?i:s),_e&&_e()},H=(j,Q)=>{j._isLeaving=!1,$t(j,d),$t(j,h),$t(j,p),Q&&Q()},q=j=>(Q,_e)=>{const ge=j?M:x,G=()=>$(Q,j,_e);en(ge,[Q,G]),Ts(()=>{$t(Q,j?c:l),Tt(Q,j?f:a),xs(ge)||Ls(Q,r,w,G)})};return Se(t,{onBeforeEnter(j){en(y,[j]),Tt(j,l),Tt(j,s)},onBeforeAppear(j){en(C,[j]),Tt(j,c),Tt(j,i)},onEnter:q(!1),onAppear:q(!0),onLeave(j,Q){j._isLeaving=!0;const _e=()=>H(j,Q);Tt(j,d),xi(),Tt(j,p),Ts(()=>{j._isLeaving&&($t(j,d),Tt(j,h),xs(k)||Ls(j,r,_,_e))}),en(k,[j,_e])},onEnterCancelled(j){$(j,!1),en(b,[j])},onAppearCancelled(j){$(j,!0),en(P,[j])},onLeaveCancelled(j){H(j),en(O,[j])}})}function Ad(e){if(e==null)return null;if(Ee(e))return[ko(e.enter),ko(e.leave)];{const t=ko(e);return[t,t]}}function ko(e){return Pu(e)}function Tt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[In]||(e[In]=new Set)).add(t)}function $t(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[In];n&&(n.delete(t),n.size||(e[In]=void 0))}function Ts(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Id=0;function Ls(e,t,n,r){const o=e._endId=++Id,l=()=>{o===e._endId&&r()};if(n)return setTimeout(l,n);const{type:s,timeout:a,propCount:c}=ki(e,t);if(!s)return r();const i=s+"end";let f=0;const d=()=>{e.removeEventListener(i,p),l()},p=h=>{h.target===e&&++f>=c&&d()};setTimeout(()=>{f(n[g]||"").split(", "),o=r(`${Rt}Delay`),l=r(`${Rt}Duration`),s=Ss(o,l),a=r(`${Fn}Delay`),c=r(`${Fn}Duration`),i=Ss(a,c);let f=null,d=0,p=0;t===Rt?s>0&&(f=Rt,d=s,p=l.length):t===Fn?i>0&&(f=Fn,d=i,p=c.length):(d=Math.max(s,i),f=d>0?s>i?Rt:Fn:null,p=f?f===Rt?l.length:c.length:0);const h=f===Rt&&/\b(transform|all)(,|$)/.test(r(`${Rt}Property`).toString());return{type:f,timeout:d,propCount:p,hasTransform:h}}function Ss(e,t){for(;e.lengthAs(n)+As(e[r])))}function As(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function xi(){return document.body.offsetHeight}function Pd(e,t,n){const r=e[In];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Is=Symbol("_vod"),Od=Symbol(""),Rd=/(^|;)\s*display\s*:/;function Md(e,t,n){const r=e.style,o=$e(n),l=r.display;let s=!1;if(n&&!o){if(t&&!$e(t))for(const a in t)n[a]==null&&Jo(r,a,"");for(const a in n)a==="display"&&(s=!0),Jo(r,a,n[a])}else if(o){if(t!==n){const a=r[Od];a&&(n+=";"+a),r.cssText=n,s=Rd.test(n)}}else t&&e.removeAttribute("style");Is in e&&(e[Is]=s?r.display:"",r.display=l)}const Ps=/\s*!important$/;function Jo(e,t,n){if(ne(n))n.forEach(r=>Jo(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=$d(e,t);Ps.test(n)?e.setProperty(Nn(r),n.replace(Ps,""),"important"):e[r]=n}}const Os=["Webkit","Moz","ms"],xo={};function $d(e,t){const n=xo[t];if(n)return n;let r=Ke(t);if(r!=="filter"&&r in e)return xo[t]=r;r=Dn(r);for(let o=0;oTo||(Vd.then(()=>To=0),To=Date.now());function Gd(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;lt(Wd(r,n.value),t,5,[r])};return n.value=e,n.attached=zd(),n}function Wd(e,t){if(ne(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>o=>!o._stopped&&r&&r(o))}else return t}const Ns=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Kd=(e,t,n,r,o,l,s,a,c)=>{const i=o==="svg";t==="class"?Pd(e,r,i):t==="style"?Md(e,n,r):ur(t)?pl(t)||Fd(e,t,n,r,s):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Ud(e,t,r,i))?Dd(e,t,r,l,s,a,c):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Nd(e,t,r,i))};function Ud(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&Ns(t)&&re(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const o=e.tagName;if(o==="IMG"||o==="VIDEO"||o==="CANVAS"||o==="SOURCE")return!1}return Ns(t)&&$e(n)?!1:t in e}const Ti=new WeakMap,Li=new WeakMap,qr=Symbol("_moveCb"),Ds=Symbol("_enterCb"),Si={name:"TransitionGroup",props:Se({},Sd,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=dn(),r=Qa();let o,l;return oi(()=>{if(!o.length)return;const s=e.moveClass||`${e.name||"v"}-move`;if(!Qd(o[0].el,n.vnode.el,s))return;o.forEach(Yd),o.forEach(Xd);const a=o.filter(Jd);xi(),a.forEach(c=>{const i=c.el,f=i.style;Tt(i,s),f.transform=f.webkitTransform=f.transitionDuration="";const d=i[qr]=p=>{p&&p.target!==i||(!p||/transform$/.test(p.propertyName))&&(i.removeEventListener("transitionend",d),i[qr]=null,$t(i,s))};i.addEventListener("transitionend",d)})}),()=>{const s=le(e),a=Ci(s);let c=s.tag||Xe;o=l,l=t.default?Sl(t.default()):[];for(let i=0;idelete e.mode;Si.props;const Zd=Si;function Yd(e){const t=e.el;t[qr]&&t[qr](),t[Ds]&&t[Ds]()}function Xd(e){Li.set(e,e.el.getBoundingClientRect())}function Jd(e){const t=Ti.get(e),n=Li.get(e),r=t.left-n.left,o=t.top-n.top;if(r||o){const l=e.el.style;return l.transform=l.webkitTransform=`translate(${r}px,${o}px)`,l.transitionDuration="0s",e}}function Qd(e,t,n){const r=e.cloneNode(),o=e[In];o&&o.forEach(a=>{a.split(/\s+/).forEach(c=>c&&r.classList.remove(c))}),n.split(/\s+/).forEach(a=>a&&r.classList.add(a)),r.style.display="none";const l=t.nodeType===1?t:t.parentNode;l.appendChild(r);const{hasTransform:s}=ki(r);return l.removeChild(r),s}const ep=Se({patchProp:Kd},Ld);let Lo,Hs=!1;function tp(){return Lo=Hs?Lo:ld(ep),Hs=!0,Lo}const np=(...e)=>{const t=tp().createApp(...e),{mount:n}=t;return t.mount=r=>{const o=op(r);if(o)return n(o,!0,rp(o))},t};function rp(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function op(e){return $e(e)?document.querySelector(e):e}var lp=["link","meta","script","style","noscript","template"],sp=["title","base"],ap=([e,t,n])=>sp.includes(e)?e:lp.includes(e)?e==="meta"&&t.name?`${e}.${t.name}`:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,Object.entries(t).map(([r,o])=>typeof o=="boolean"?o?[r,""]:null:[r,o]).filter(r=>r!=null).sort(([r],[o])=>r.localeCompare(o)),n]):null,ip=e=>{const t=new Set,n=[];return e.forEach(r=>{const o=ap(r);o&&!t.has(o)&&(t.add(o),n.push(r))}),n},cp=e=>e[0]==="/"?e:`/${e}`,Ai=e=>e[e.length-1]==="/"||e.endsWith(".html")?e:`${e}/`,pn=e=>/^(https?:)?\/\//.test(e),up=/.md((\?|#).*)?$/,Pn=(e,t="/")=>!!(pn(e)||e.startsWith("/")&&!e.startsWith(t)&&!up.test(e)),Ii=e=>/^[a-z][a-z0-9+.-]*:/.test(e),gr=e=>Object.prototype.toString.call(e)==="[object Object]",fp=e=>{const[t,...n]=e.split(/(\?|#)/);if(!t||t.endsWith("/"))return e;let r=t.replace(/(^|\/)README.md$/i,"$1index.html");return r.endsWith(".md")?r=r.substring(0,r.length-3)+".html":r.endsWith(".html")||(r=r+".html"),r.endsWith("/index.html")&&(r=r.substring(0,r.length-10)),r+n.join("")},Rl=e=>e[e.length-1]==="/"?e.slice(0,-1):e,Pi=e=>e[0]==="/"?e.slice(1):e,dp=(e,t)=>{const n=Object.keys(e).sort((r,o)=>{const l=o.split("/").length-r.split("/").length;return l!==0?l:o.length-r.length});for(const r of n)if(t.startsWith(r))return r;return"/"},Ie=e=>typeof e=="string";const pp="modulepreload",hp=function(e){return"/"+e},js={},J=function(t,n,r){let o=Promise.resolve();if(n&&n.length>0){const l=document.getElementsByTagName("link");o=Promise.all(n.map(s=>{if(s=hp(s),s in js)return;js[s]=!0;const a=s.endsWith(".css"),c=a?'[rel="stylesheet"]':"";if(!!r)for(let d=l.length-1;d>=0;d--){const p=l[d];if(p.href===s&&(!a||p.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${s}"]${c}`))return;const f=document.createElement("link");if(f.rel=a?"stylesheet":pp,a||(f.as="script",f.crossOrigin=""),f.href=s,document.head.appendChild(f),a)return new Promise((d,p)=>{f.addEventListener("load",d),f.addEventListener("error",()=>p(new Error(`Unable to preload CSS for ${s}`)))})}))}return o.then(()=>t()).catch(l=>{const s=new Event("vite:preloadError",{cancelable:!0});if(s.payload=l,window.dispatchEvent(s),!s.defaultPrevented)throw l})},vp=JSON.parse("{}"),mp=Object.fromEntries([["/",{loader:()=>J(()=>import("./index.html-ChX_4YQ3.js"),__vite__mapDeps([0,1])),meta:{y:"h",t:"Go 面试宝典",i:"home"}}],["/en/",{loader:()=>J(()=>import("./index.html-jsKKBcg2.js"),__vite__mapDeps([2,1])),meta:{y:"h",t:"Go Guide",i:"home"}}],["/guide/",{loader:()=>J(()=>import("./index.html-DZQMWWHK.js"),__vite__mapDeps([3,1])),meta:{y:"a",t:"指南",i:"mingcute:book-line"}}],["/en/guide/",{loader:()=>J(()=>import("./index.html-nkEwrf4M.js"),__vite__mapDeps([4,1])),meta:{y:"a",t:"Guide",i:"mingcute:book-line"}}],["/guide/concepts/database/1-database-basic.html",{loader:()=>J(()=>import("./1-database-basic.html-BXLjRmy6.js"),__vite__mapDeps([5,6,1])),meta:{y:"a",t:"数据库基础",O:1}}],["/guide/concepts/golang/1-keywords.html",{loader:()=>J(()=>import("./1-keywords.html-Cb_-qdNV.js"),__vite__mapDeps([7,1])),meta:{y:"a",t:"保留关键字",O:1}}],["/guide/concepts/golang/2-datatype.html",{loader:()=>J(()=>import("./2-datatype.html-Bhx9jV3s.js"),__vite__mapDeps([8,1])),meta:{y:"a",t:"数据类型",O:2}}],["/guide/concepts/golang/3-operator.html",{loader:()=>J(()=>import("./3-operator.html-DcFs0BUM.js"),__vite__mapDeps([9,1])),meta:{y:"a",t:"运算符",O:3}}],["/guide/concepts/golang/4-errorhandling.html",{loader:()=>J(()=>import("./4-errorhandling.html-Cq7NUd58.js"),__vite__mapDeps([10,1])),meta:{y:"a",t:"错误处理",O:4}}],["/guide/concepts/golang/5-map.html",{loader:()=>J(()=>import("./5-map.html-DJfb0ND7.js"),__vite__mapDeps([11,1])),meta:{y:"a",t:"Map (集合)",O:5}}],["/guide/concepts/golang/6-slice.html",{loader:()=>J(()=>import("./6-slice.html-JMIMK1-9.js"),__vite__mapDeps([12,1])),meta:{y:"a",t:"切片",O:6}}],["/guide/concepts/golang/7-channel.html",{loader:()=>J(()=>import("./7-channel.html-CQe5Eha5.js"),__vite__mapDeps([13,1])),meta:{y:"a",t:"信道",O:7}}],["/guide/concepts/golang/8-context.html",{loader:()=>J(()=>import("./8-context.html-DI8Yqf21.js"),__vite__mapDeps([14,15,1])),meta:{y:"a",t:"Context",O:8}}],["/guide/concepts/network/1-network.html",{loader:()=>J(()=>import("./1-network.html-V2ivHazx.js"),__vite__mapDeps([16,17,1])),meta:{y:"a",t:"计算机网络基础",O:1}}],["/guide/concepts/network/2-tcp-udp.html",{loader:()=>J(()=>import("./2-tcp-udp.html-BbAGUlCW.js"),__vite__mapDeps([18,19,1])),meta:{y:"a",t:"TCP/UDP",O:2}}],["/en/guide/concepts/database/1-database-basic.html",{loader:()=>J(()=>import("./1-database-basic.html-BrHVm61A.js"),__vite__mapDeps([20,6,1])),meta:{y:"a",t:"Database basic",O:1}}],["/en/guide/concepts/golang/1-keywords.html",{loader:()=>J(()=>import("./1-keywords.html-Bu_vfCri.js"),__vite__mapDeps([21,1])),meta:{y:"a",t:"Keywords",O:1}}],["/en/guide/concepts/golang/2-datatype.html",{loader:()=>J(()=>import("./2-datatype.html-B4Zluvs9.js"),__vite__mapDeps([22,1])),meta:{y:"a",t:"Data Type",O:2}}],["/en/guide/concepts/golang/3-operator.html",{loader:()=>J(()=>import("./3-operator.html-BWtKH6YH.js"),__vite__mapDeps([23,1])),meta:{y:"a",t:"Operators",O:3}}],["/en/guide/concepts/golang/4-errorhandling.html",{loader:()=>J(()=>import("./4-errorhandling.html-CZWtCtwI.js"),__vite__mapDeps([24,1])),meta:{y:"a",t:"Error Handling",O:4}}],["/en/guide/concepts/golang/5-map.html",{loader:()=>J(()=>import("./5-map.html-BucnXcKM.js"),__vite__mapDeps([25,1])),meta:{y:"a",t:"Map",O:5}}],["/en/guide/concepts/golang/6-slice.html",{loader:()=>J(()=>import("./6-slice.html-CTtneWZ6.js"),__vite__mapDeps([26,1])),meta:{y:"a",t:"Slices",O:6}}],["/en/guide/concepts/golang/7-channel.html",{loader:()=>J(()=>import("./7-channel.html-6gWgcYt9.js"),__vite__mapDeps([27,1])),meta:{y:"a",t:"Channel",O:7}}],["/en/guide/concepts/golang/8-context.html",{loader:()=>J(()=>import("./8-context.html-Ckq0jHxV.js"),__vite__mapDeps([28,15,1])),meta:{y:"a",t:"Context",O:8}}],["/en/guide/concepts/network/1-network.html",{loader:()=>J(()=>import("./1-network.html-C_EZgcM6.js"),__vite__mapDeps([29,17,1])),meta:{y:"a",t:"Computer Network",O:1}}],["/en/guide/concepts/network/2-tcp-udp.html",{loader:()=>J(()=>import("./2-tcp-udp.html-D4XJmffI.js"),__vite__mapDeps([30,19,1])),meta:{y:"a",t:"TCP/UDP",O:2}}],["/guide/interview/golang/basic/1-basic.html",{loader:()=>J(()=>import("./1-basic.html-Oj5lYJbp.js"),__vite__mapDeps([31,1])),meta:{y:"a",t:"基础",O:1}}],["/guide/interview/golang/basic/2-medium.html",{loader:()=>J(()=>import("./2-medium.html-CUT2Gn3u.js"),__vite__mapDeps([32,1])),meta:{y:"a",t:"进阶",O:2}}],["/en/guide/interview/golang/basic/1-basic.html",{loader:()=>J(()=>import("./1-basic.html-DbR7Ocm4.js"),__vite__mapDeps([33,1])),meta:{y:"a",t:"Basic",O:1}}],["/en/guide/interview/golang/basic/2-medium.html",{loader:()=>J(()=>import("./2-medium.html-EVBDDzD_.js"),__vite__mapDeps([34,1])),meta:{y:"a",t:"Medium",O:2}}],["/404.html",{loader:()=>J(()=>import("./404.html-B3jmriWY.js"),__vite__mapDeps([35,1])),meta:{y:"p",t:""}}],["/guide/concepts/database/",{loader:()=>J(()=>import("./index.html-DZ6fXLsW.js"),__vite__mapDeps([36,1])),meta:{y:"p",t:"Database"}}],["/guide/concepts/",{loader:()=>J(()=>import("./index.html-BQR5-7-D.js"),__vite__mapDeps([37,1])),meta:{y:"p",t:"Concepts"}}],["/guide/concepts/golang/",{loader:()=>J(()=>import("./index.html-CsL29kfO.js"),__vite__mapDeps([38,1])),meta:{y:"p",t:"Golang"}}],["/guide/concepts/network/",{loader:()=>J(()=>import("./index.html-DceXrgJn.js"),__vite__mapDeps([39,1])),meta:{y:"p",t:"Network"}}],["/en/guide/concepts/database/",{loader:()=>J(()=>import("./index.html-TKkSvLzY.js"),__vite__mapDeps([40,1])),meta:{y:"p",t:"Database"}}],["/en/guide/concepts/",{loader:()=>J(()=>import("./index.html-zgvkyyEG.js"),__vite__mapDeps([41,1])),meta:{y:"p",t:"Concepts"}}],["/en/guide/concepts/golang/",{loader:()=>J(()=>import("./index.html-BZ6P1cG5.js"),__vite__mapDeps([42,1])),meta:{y:"p",t:"Golang"}}],["/en/guide/concepts/network/",{loader:()=>J(()=>import("./index.html-DBpVKrL9.js"),__vite__mapDeps([43,1])),meta:{y:"p",t:"Network"}}],["/guide/interview/golang/basic/",{loader:()=>J(()=>import("./index.html-q-4AM6qQ.js"),__vite__mapDeps([44,1])),meta:{y:"p",t:"Basic"}}],["/guide/interview/golang/",{loader:()=>J(()=>import("./index.html-CV8s24FG.js"),__vite__mapDeps([45,1])),meta:{y:"p",t:"Golang"}}],["/guide/interview/",{loader:()=>J(()=>import("./index.html-CvRlnlxH.js"),__vite__mapDeps([46,1])),meta:{y:"p",t:"Interview"}}],["/en/guide/interview/golang/basic/",{loader:()=>J(()=>import("./index.html-D8cXLzPU.js"),__vite__mapDeps([47,1])),meta:{y:"p",t:"Basic"}}],["/en/guide/interview/golang/",{loader:()=>J(()=>import("./index.html-T2UIAV4q.js"),__vite__mapDeps([48,1])),meta:{y:"p",t:"Golang"}}],["/en/guide/interview/",{loader:()=>J(()=>import("./index.html-BAWnyXuw.js"),__vite__mapDeps([49,1])),meta:{y:"p",t:"Interview"}}]]);/*!
+**/const xd="http://www.w3.org/2000/svg",Td="http://www.w3.org/1998/Math/MathML",jt=typeof document<"u"?document:null,ks=jt&&jt.createElement("template"),Ld={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const o=t==="svg"?jt.createElementNS(xd,e):t==="mathml"?jt.createElementNS(Td,e):jt.createElement(e,n?{is:n}:void 0);return e==="select"&&r&&r.multiple!=null&&o.setAttribute("multiple",r.multiple),o},createText:e=>jt.createTextNode(e),createComment:e=>jt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>jt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,o,l){const s=n?n.previousSibling:t.lastChild;if(o&&(o===l||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===l||!(o=o.nextSibling)););else{ks.innerHTML=r==="svg"?`${e}`:r==="mathml"?`${e}`:e;const a=ks.content;if(r==="svg"||r==="mathml"){const c=a.firstChild;for(;c.firstChild;)a.appendChild(c.firstChild);a.removeChild(c)}t.insertBefore(a,n)}return[s?s.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Rt="transition",Fn="animation",In=Symbol("_vtc"),Wt=(e,{slots:t})=>u(Rf,Ci(e),t);Wt.displayName="Transition";const Ei={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},Sd=Wt.props=Se({},ei,Ei),en=(e,t=[])=>{ne(e)?e.forEach(n=>n(...t)):e&&e(...t)},xs=e=>e?ne(e)?e.some(t=>t.length>1):e.length>1:!1;function Ci(e){const t={};for(const j in e)j in Ei||(t[j]=e[j]);if(e.css===!1)return t;const{name:n="v",type:r,duration:o,enterFromClass:l=`${n}-enter-from`,enterActiveClass:s=`${n}-enter-active`,enterToClass:a=`${n}-enter-to`,appearFromClass:c=l,appearActiveClass:i=s,appearToClass:f=a,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:p=`${n}-leave-active`,leaveToClass:h=`${n}-leave-to`}=e,g=Ad(o),w=g&&g[0],_=g&&g[1],{onBeforeEnter:y,onEnter:x,onEnterCancelled:b,onLeave:k,onLeaveCancelled:O,onBeforeAppear:C=y,onAppear:M=x,onAppearCancelled:P=b}=t,$=(j,Q,_e)=>{$t(j,Q?f:a),$t(j,Q?i:s),_e&&_e()},H=(j,Q)=>{j._isLeaving=!1,$t(j,d),$t(j,h),$t(j,p),Q&&Q()},q=j=>(Q,_e)=>{const ge=j?M:x,G=()=>$(Q,j,_e);en(ge,[Q,G]),Ts(()=>{$t(Q,j?c:l),Tt(Q,j?f:a),xs(ge)||Ls(Q,r,w,G)})};return Se(t,{onBeforeEnter(j){en(y,[j]),Tt(j,l),Tt(j,s)},onBeforeAppear(j){en(C,[j]),Tt(j,c),Tt(j,i)},onEnter:q(!1),onAppear:q(!0),onLeave(j,Q){j._isLeaving=!0;const _e=()=>H(j,Q);Tt(j,d),xi(),Tt(j,p),Ts(()=>{j._isLeaving&&($t(j,d),Tt(j,h),xs(k)||Ls(j,r,_,_e))}),en(k,[j,_e])},onEnterCancelled(j){$(j,!1),en(b,[j])},onAppearCancelled(j){$(j,!0),en(P,[j])},onLeaveCancelled(j){H(j),en(O,[j])}})}function Ad(e){if(e==null)return null;if(Ee(e))return[ko(e.enter),ko(e.leave)];{const t=ko(e);return[t,t]}}function ko(e){return Pu(e)}function Tt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[In]||(e[In]=new Set)).add(t)}function $t(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[In];n&&(n.delete(t),n.size||(e[In]=void 0))}function Ts(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Id=0;function Ls(e,t,n,r){const o=e._endId=++Id,l=()=>{o===e._endId&&r()};if(n)return setTimeout(l,n);const{type:s,timeout:a,propCount:c}=ki(e,t);if(!s)return r();const i=s+"end";let f=0;const d=()=>{e.removeEventListener(i,p),l()},p=h=>{h.target===e&&++f>=c&&d()};setTimeout(()=>{f(n[g]||"").split(", "),o=r(`${Rt}Delay`),l=r(`${Rt}Duration`),s=Ss(o,l),a=r(`${Fn}Delay`),c=r(`${Fn}Duration`),i=Ss(a,c);let f=null,d=0,p=0;t===Rt?s>0&&(f=Rt,d=s,p=l.length):t===Fn?i>0&&(f=Fn,d=i,p=c.length):(d=Math.max(s,i),f=d>0?s>i?Rt:Fn:null,p=f?f===Rt?l.length:c.length:0);const h=f===Rt&&/\b(transform|all)(,|$)/.test(r(`${Rt}Property`).toString());return{type:f,timeout:d,propCount:p,hasTransform:h}}function Ss(e,t){for(;e.lengthAs(n)+As(e[r])))}function As(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function xi(){return document.body.offsetHeight}function Pd(e,t,n){const r=e[In];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Is=Symbol("_vod"),Od=Symbol(""),Rd=/(^|;)\s*display\s*:/;function Md(e,t,n){const r=e.style,o=$e(n),l=r.display;let s=!1;if(n&&!o){if(t&&!$e(t))for(const a in t)n[a]==null&&Jo(r,a,"");for(const a in n)a==="display"&&(s=!0),Jo(r,a,n[a])}else if(o){if(t!==n){const a=r[Od];a&&(n+=";"+a),r.cssText=n,s=Rd.test(n)}}else t&&e.removeAttribute("style");Is in e&&(e[Is]=s?r.display:"",r.display=l)}const Ps=/\s*!important$/;function Jo(e,t,n){if(ne(n))n.forEach(r=>Jo(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=$d(e,t);Ps.test(n)?e.setProperty(Nn(r),n.replace(Ps,""),"important"):e[r]=n}}const Os=["Webkit","Moz","ms"],xo={};function $d(e,t){const n=xo[t];if(n)return n;let r=Ke(t);if(r!=="filter"&&r in e)return xo[t]=r;r=Dn(r);for(let o=0;oTo||(Vd.then(()=>To=0),To=Date.now());function Gd(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;lt(Wd(r,n.value),t,5,[r])};return n.value=e,n.attached=zd(),n}function Wd(e,t){if(ne(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>o=>!o._stopped&&r&&r(o))}else return t}const Ns=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Kd=(e,t,n,r,o,l,s,a,c)=>{const i=o==="svg";t==="class"?Pd(e,r,i):t==="style"?Md(e,n,r):ur(t)?pl(t)||Fd(e,t,n,r,s):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Ud(e,t,r,i))?Dd(e,t,r,l,s,a,c):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Nd(e,t,r,i))};function Ud(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&Ns(t)&&re(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const o=e.tagName;if(o==="IMG"||o==="VIDEO"||o==="CANVAS"||o==="SOURCE")return!1}return Ns(t)&&$e(n)?!1:t in e}const Ti=new WeakMap,Li=new WeakMap,qr=Symbol("_moveCb"),Ds=Symbol("_enterCb"),Si={name:"TransitionGroup",props:Se({},Sd,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=dn(),r=Qa();let o,l;return oi(()=>{if(!o.length)return;const s=e.moveClass||`${e.name||"v"}-move`;if(!Qd(o[0].el,n.vnode.el,s))return;o.forEach(Yd),o.forEach(Xd);const a=o.filter(Jd);xi(),a.forEach(c=>{const i=c.el,f=i.style;Tt(i,s),f.transform=f.webkitTransform=f.transitionDuration="";const d=i[qr]=p=>{p&&p.target!==i||(!p||/transform$/.test(p.propertyName))&&(i.removeEventListener("transitionend",d),i[qr]=null,$t(i,s))};i.addEventListener("transitionend",d)})}),()=>{const s=le(e),a=Ci(s);let c=s.tag||Xe;o=l,l=t.default?Sl(t.default()):[];for(let i=0;idelete e.mode;Si.props;const Zd=Si;function Yd(e){const t=e.el;t[qr]&&t[qr](),t[Ds]&&t[Ds]()}function Xd(e){Li.set(e,e.el.getBoundingClientRect())}function Jd(e){const t=Ti.get(e),n=Li.get(e),r=t.left-n.left,o=t.top-n.top;if(r||o){const l=e.el.style;return l.transform=l.webkitTransform=`translate(${r}px,${o}px)`,l.transitionDuration="0s",e}}function Qd(e,t,n){const r=e.cloneNode(),o=e[In];o&&o.forEach(a=>{a.split(/\s+/).forEach(c=>c&&r.classList.remove(c))}),n.split(/\s+/).forEach(a=>a&&r.classList.add(a)),r.style.display="none";const l=t.nodeType===1?t:t.parentNode;l.appendChild(r);const{hasTransform:s}=ki(r);return l.removeChild(r),s}const ep=Se({patchProp:Kd},Ld);let Lo,Hs=!1;function tp(){return Lo=Hs?Lo:ld(ep),Hs=!0,Lo}const np=(...e)=>{const t=tp().createApp(...e),{mount:n}=t;return t.mount=r=>{const o=op(r);if(o)return n(o,!0,rp(o))},t};function rp(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function op(e){return $e(e)?document.querySelector(e):e}var lp=["link","meta","script","style","noscript","template"],sp=["title","base"],ap=([e,t,n])=>sp.includes(e)?e:lp.includes(e)?e==="meta"&&t.name?`${e}.${t.name}`:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,Object.entries(t).map(([r,o])=>typeof o=="boolean"?o?[r,""]:null:[r,o]).filter(r=>r!=null).sort(([r],[o])=>r.localeCompare(o)),n]):null,ip=e=>{const t=new Set,n=[];return e.forEach(r=>{const o=ap(r);o&&!t.has(o)&&(t.add(o),n.push(r))}),n},cp=e=>e[0]==="/"?e:`/${e}`,Ai=e=>e[e.length-1]==="/"||e.endsWith(".html")?e:`${e}/`,pn=e=>/^(https?:)?\/\//.test(e),up=/.md((\?|#).*)?$/,Pn=(e,t="/")=>!!(pn(e)||e.startsWith("/")&&!e.startsWith(t)&&!up.test(e)),Ii=e=>/^[a-z][a-z0-9+.-]*:/.test(e),gr=e=>Object.prototype.toString.call(e)==="[object Object]",fp=e=>{const[t,...n]=e.split(/(\?|#)/);if(!t||t.endsWith("/"))return e;let r=t.replace(/(^|\/)README.md$/i,"$1index.html");return r.endsWith(".md")?r=r.substring(0,r.length-3)+".html":r.endsWith(".html")||(r=r+".html"),r.endsWith("/index.html")&&(r=r.substring(0,r.length-10)),r+n.join("")},Rl=e=>e[e.length-1]==="/"?e.slice(0,-1):e,Pi=e=>e[0]==="/"?e.slice(1):e,dp=(e,t)=>{const n=Object.keys(e).sort((r,o)=>{const l=o.split("/").length-r.split("/").length;return l!==0?l:o.length-r.length});for(const r of n)if(t.startsWith(r))return r;return"/"},Ie=e=>typeof e=="string";const pp="modulepreload",hp=function(e){return"/"+e},js={},J=function(t,n,r){let o=Promise.resolve();if(n&&n.length>0){const l=document.getElementsByTagName("link");o=Promise.all(n.map(s=>{if(s=hp(s),s in js)return;js[s]=!0;const a=s.endsWith(".css"),c=a?'[rel="stylesheet"]':"";if(!!r)for(let d=l.length-1;d>=0;d--){const p=l[d];if(p.href===s&&(!a||p.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${s}"]${c}`))return;const f=document.createElement("link");if(f.rel=a?"stylesheet":pp,a||(f.as="script",f.crossOrigin=""),f.href=s,document.head.appendChild(f),a)return new Promise((d,p)=>{f.addEventListener("load",d),f.addEventListener("error",()=>p(new Error(`Unable to preload CSS for ${s}`)))})}))}return o.then(()=>t()).catch(l=>{const s=new Event("vite:preloadError",{cancelable:!0});if(s.payload=l,window.dispatchEvent(s),!s.defaultPrevented)throw l})},vp=JSON.parse("{}"),mp=Object.fromEntries([["/",{loader:()=>J(()=>import("./index.html-5Kj3Bkky.js"),__vite__mapDeps([0,1])),meta:{y:"h",t:"Go 面试宝典",i:"home"}}],["/en/",{loader:()=>J(()=>import("./index.html-ckgkylJ7.js"),__vite__mapDeps([2,1])),meta:{y:"h",t:"Go Guide",i:"home"}}],["/guide/",{loader:()=>J(()=>import("./index.html-BlVsVRN4.js"),__vite__mapDeps([3,1])),meta:{y:"a",t:"指南",i:"mingcute:book-line"}}],["/en/guide/",{loader:()=>J(()=>import("./index.html-CxLVFEy9.js"),__vite__mapDeps([4,1])),meta:{y:"a",t:"Guide",i:"mingcute:book-line"}}],["/guide/concepts/database/1-database-basic.html",{loader:()=>J(()=>import("./1-database-basic.html-CfhjjJrP.js"),__vite__mapDeps([5,6,1])),meta:{y:"a",t:"基础",O:1}}],["/guide/concepts/golang/1-keywords.html",{loader:()=>J(()=>import("./1-keywords.html-D8qOdfzt.js"),__vite__mapDeps([7,1])),meta:{y:"a",t:"保留关键字",O:1}}],["/guide/concepts/golang/2-datatype.html",{loader:()=>J(()=>import("./2-datatype.html-CPzWcUi9.js"),__vite__mapDeps([8,1])),meta:{y:"a",t:"数据类型",O:2}}],["/guide/concepts/golang/3-operator.html",{loader:()=>J(()=>import("./3-operator.html-BwDwjYWH.js"),__vite__mapDeps([9,1])),meta:{y:"a",t:"运算符",O:3}}],["/guide/concepts/golang/4-errorhandling.html",{loader:()=>J(()=>import("./4-errorhandling.html-DNHfljPB.js"),__vite__mapDeps([10,1])),meta:{y:"a",t:"错误处理",O:4}}],["/guide/concepts/golang/5-map.html",{loader:()=>J(()=>import("./5-map.html-CaKde_jH.js"),__vite__mapDeps([11,1])),meta:{y:"a",t:"Map (集合)",O:5}}],["/guide/concepts/golang/6-slice.html",{loader:()=>J(()=>import("./6-slice.html-D0sTuz-d.js"),__vite__mapDeps([12,1])),meta:{y:"a",t:"切片",O:6}}],["/guide/concepts/golang/7-channel.html",{loader:()=>J(()=>import("./7-channel.html-DcY0VHb2.js"),__vite__mapDeps([13,1])),meta:{y:"a",t:"信道",O:7}}],["/guide/concepts/golang/8-context.html",{loader:()=>J(()=>import("./8-context.html-BURlTMoP.js"),__vite__mapDeps([14,15,1])),meta:{y:"a",t:"Context",O:8}}],["/guide/concepts/network/1-network.html",{loader:()=>J(()=>import("./1-network.html-Blr4KIdV.js"),__vite__mapDeps([16,17,1])),meta:{y:"a",t:"基础",O:1}}],["/guide/concepts/network/2-tcp-udp.html",{loader:()=>J(()=>import("./2-tcp-udp.html-BABQQ_zo.js"),__vite__mapDeps([18,19,1])),meta:{y:"a",t:"TCP/UDP",O:2}}],["/en/guide/concepts/database/1-database-basic.html",{loader:()=>J(()=>import("./1-database-basic.html-DzAKcAVh.js"),__vite__mapDeps([20,6,1])),meta:{y:"a",t:"Basic",O:1}}],["/en/guide/concepts/golang/1-keywords.html",{loader:()=>J(()=>import("./1-keywords.html--Q_8y9NZ.js"),__vite__mapDeps([21,1])),meta:{y:"a",t:"Keywords",O:1}}],["/en/guide/concepts/golang/2-datatype.html",{loader:()=>J(()=>import("./2-datatype.html-BBe-LqVn.js"),__vite__mapDeps([22,1])),meta:{y:"a",t:"Data Type",O:2}}],["/en/guide/concepts/golang/3-operator.html",{loader:()=>J(()=>import("./3-operator.html-C8kTpa_2.js"),__vite__mapDeps([23,1])),meta:{y:"a",t:"Operators",O:3}}],["/en/guide/concepts/golang/4-errorhandling.html",{loader:()=>J(()=>import("./4-errorhandling.html-E6HmUyLW.js"),__vite__mapDeps([24,1])),meta:{y:"a",t:"Error Handling",O:4}}],["/en/guide/concepts/golang/5-map.html",{loader:()=>J(()=>import("./5-map.html-coD4WfmK.js"),__vite__mapDeps([25,1])),meta:{y:"a",t:"Map",O:5}}],["/en/guide/concepts/golang/6-slice.html",{loader:()=>J(()=>import("./6-slice.html-DxG6N77X.js"),__vite__mapDeps([26,1])),meta:{y:"a",t:"Slices",O:6}}],["/en/guide/concepts/golang/7-channel.html",{loader:()=>J(()=>import("./7-channel.html-DWDDXmkq.js"),__vite__mapDeps([27,1])),meta:{y:"a",t:"Channel",O:7}}],["/en/guide/concepts/golang/8-context.html",{loader:()=>J(()=>import("./8-context.html-B9nsgQ4v.js"),__vite__mapDeps([28,15,1])),meta:{y:"a",t:"Context",O:8}}],["/en/guide/concepts/network/1-network.html",{loader:()=>J(()=>import("./1-network.html-BUDov-jI.js"),__vite__mapDeps([29,17,1])),meta:{y:"a",t:"Basic",O:1}}],["/en/guide/concepts/network/2-tcp-udp.html",{loader:()=>J(()=>import("./2-tcp-udp.html-IZeSrbLS.js"),__vite__mapDeps([30,19,1])),meta:{y:"a",t:"TCP/UDP",O:2}}],["/guide/interview/golang/basic/1-basic.html",{loader:()=>J(()=>import("./1-basic.html-D5nncuCC.js"),__vite__mapDeps([31,1])),meta:{y:"a",t:"基础",O:1}}],["/guide/interview/golang/basic/2-medium.html",{loader:()=>J(()=>import("./2-medium.html-cqpOA0o-.js"),__vite__mapDeps([32,1])),meta:{y:"a",t:"进阶",O:2}}],["/en/guide/interview/golang/basic/1-basic.html",{loader:()=>J(()=>import("./1-basic.html-BieaWbc7.js"),__vite__mapDeps([33,1])),meta:{y:"a",t:"Basic",O:1}}],["/en/guide/interview/golang/basic/2-medium.html",{loader:()=>J(()=>import("./2-medium.html-C1NwI0Ox.js"),__vite__mapDeps([34,1])),meta:{y:"a",t:"Medium",O:2}}],["/404.html",{loader:()=>J(()=>import("./404.html-DPAHxMnN.js"),__vite__mapDeps([35,1])),meta:{y:"p",t:""}}],["/guide/concepts/database/",{loader:()=>J(()=>import("./index.html-Bz9RForh.js"),__vite__mapDeps([36,1])),meta:{y:"p",t:"Database"}}],["/guide/concepts/",{loader:()=>J(()=>import("./index.html-B-auqxUp.js"),__vite__mapDeps([37,1])),meta:{y:"p",t:"Concepts"}}],["/guide/concepts/golang/",{loader:()=>J(()=>import("./index.html-CtCM_MAH.js"),__vite__mapDeps([38,1])),meta:{y:"p",t:"Golang"}}],["/guide/concepts/network/",{loader:()=>J(()=>import("./index.html-DEnQWnwC.js"),__vite__mapDeps([39,1])),meta:{y:"p",t:"Network"}}],["/en/guide/concepts/database/",{loader:()=>J(()=>import("./index.html-1Nx2oT3r.js"),__vite__mapDeps([40,1])),meta:{y:"p",t:"Database"}}],["/en/guide/concepts/",{loader:()=>J(()=>import("./index.html-BzPKbSiO.js"),__vite__mapDeps([41,1])),meta:{y:"p",t:"Concepts"}}],["/en/guide/concepts/golang/",{loader:()=>J(()=>import("./index.html-CeroSw2z.js"),__vite__mapDeps([42,1])),meta:{y:"p",t:"Golang"}}],["/en/guide/concepts/network/",{loader:()=>J(()=>import("./index.html-2GK5VV8e.js"),__vite__mapDeps([43,1])),meta:{y:"p",t:"Network"}}],["/guide/interview/golang/basic/",{loader:()=>J(()=>import("./index.html-1Y6NdWAO.js"),__vite__mapDeps([44,1])),meta:{y:"p",t:"Basic"}}],["/guide/interview/golang/",{loader:()=>J(()=>import("./index.html-BIAHWB1B.js"),__vite__mapDeps([45,1])),meta:{y:"p",t:"Golang"}}],["/guide/interview/",{loader:()=>J(()=>import("./index.html-Drh9TwcQ.js"),__vite__mapDeps([46,1])),meta:{y:"p",t:"Interview"}}],["/en/guide/interview/golang/basic/",{loader:()=>J(()=>import("./index.html-DAz-Ra5W.js"),__vite__mapDeps([47,1])),meta:{y:"p",t:"Basic"}}],["/en/guide/interview/golang/",{loader:()=>J(()=>import("./index.html-B47cmPYZ.js"),__vite__mapDeps([48,1])),meta:{y:"p",t:"Golang"}}],["/en/guide/interview/",{loader:()=>J(()=>import("./index.html-CCIUmYMw.js"),__vite__mapDeps([49,1])),meta:{y:"p",t:"Interview"}}]]);/*!
   * vue-router v4.2.5
   * (c) 2023 Eduardo San Martin Morote
   * @license MIT
@@ -25,10 +25,10 @@
 ${r}}`)),t.appendChild(o)}},Pv=e=>{const t=Xt(e),n={html:[],js:[],css:[],isLegal:!1};return["html","js","css"].forEach(r=>{const o=t.filter(l=>va[r].types.includes(l));if(o.length){const l=o[0];n[r]=[e[l].replace(/^\n|\n$/g,""),va[r].map[l]||l]}}),n.isLegal=(!n.html.length||n.html[1]==="none")&&(!n.js.length||n.js[1]==="none")&&(!n.css.length||n.css[1]==="none"),n},Ic=e=>e.replace(/
/g,"
").replace(/<((\S+)[^<]*?)\s+\/>/g,"<$1>"),Pc=e=>`
${Ic(e)}
`,Ov=e=>`${e.replace("export default ","const $reactApp = ").replace(/App\.__style__(\s*)=(\s*)`([\s\S]*)?`/,"")}; -ReactDOM.createRoot(document.getElementById("app")).render(React.createElement($reactApp))`,Rv=e=>e.replace(/export\s+default\s*\{(\n*[\s\S]*)\n*\}\s*;?$/u,"Vue.createApp({$1}).mount('#app')").replace(/export\s+default\s*define(Async)?Component\s*\(\s*\{(\n*[\s\S]*)\n*\}\s*\)\s*;?$/u,"Vue.createApp({$1}).mount('#app')").trim(),Oc=e=>`(function(exports){var module={};module.exports=exports;${e};return module.exports.__esModule?module.exports.default:module.exports;})({})`,Mv=(e,t)=>{const n=zl(t),r=e.js[0]||"";return{...n,html:Ic(e.html[0]||""),js:r,css:e.css[0]||"",isLegal:e.isLegal,getScript:()=>{var o;return n.useBabel?((o=window.Babel.transform(r,{presets:["es2015"]}))==null?void 0:o.code)||"":r}}},$v=/