From c1c1e122ca639681f771316eee811368725653f4 Mon Sep 17 00:00:00 2001
From: zhuxiaojie
Date: Mon, 8 Jul 2019 15:21:14 +0800
Subject: [PATCH 01/72] modify ip2long implementation
---
docs/03.PHP/QA.md | 9 +++++++++
docs/03.PHP/assets/php-ip2long.png | Bin 7611 -> 13498 bytes
2 files changed, 9 insertions(+)
diff --git a/docs/03.PHP/QA.md b/docs/03.PHP/QA.md
index 7acd48d..570f9d5 100644
--- a/docs/03.PHP/QA.md
+++ b/docs/03.PHP/QA.md
@@ -337,6 +337,15 @@ PHP 代码 => 启动 php 及 zend 引擎,加载注册拓展模块 => 对代码

+
+```
+124.205.30.150=2093817494
+
+list($p1,$p2,$p3,$p4) = explode(',','124.205.30.150');
+
+$realNum = $p1<<24+$p2<<16+$p3<<8+$p4;
+```
+
### MVC 的理解
MVC 包括三类对象。模型 Model 是应用对象,视图 View 是它在屏幕上的表示,控制器 Controller 定义用户界面对用户输入的响应方式。不使用 MVC,用户界面设计往往将这些对象混在一起,而 MVC 则将它们分离以提高灵活性和复用性
diff --git a/docs/03.PHP/assets/php-ip2long.png b/docs/03.PHP/assets/php-ip2long.png
index eaf06aa756ec628d6fe1171364657919da87ba7c..981b6f3ffd41b24b067e0bde90406ff4d8cc6e8b 100644
GIT binary patch
literal 13498
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
literal 7611
zcmd5=c{r5syZ3D`N-L7367p4}vSqIbL&&~`RCYsQ>`W?cvKC@2WoKd%LzY1a+1D|Q
zj4cLZ-}gE9ob%uL>-=@DpXGIU2V0)hqw>1u&^9Ps;lU+u
z>xu*W;P3H*7XYL?}X`oAODkv)Y*Agbks~*
zLEMc4a(i~G7`?xKiTk8akihS2BfozSiw}<
zv>&ti{^?@)+|k(kkM;+>xN+;&tqvp}&3HP4{2g`>*+|>=9lebvW$V*Cl4ZAX`kCAZ
zVMqUoKTng{QVFbc57RO-0v)(&Bf1g$cbX-dwX6b`NrYUBFiM*xC8>yFX)k)C-)ys-
zP}m)W-Oa1n_mHdhcQ-=W!d?ueV~!FlJoU*XH-P%GXzT~JF^pHvtn5If;(vBPS>&0^2Ji*rxt&FA~jiSj;f>Q1q#S1UGW${g`pon3I^zl-bK
z1dNYQNo^Q!-~Cefs&t8ST^MhtGP{C-YrKelhJ?&O(S?tcLr*i#J(f}P_4OUpiTYMh
zup5v6K71&YPr*z_aXn2tS6CdFZi(AFrcaSmS6%{d-}_
zC&Mb!y#<-K!+Z5^DJ#>a`-;V+6%@8>y1KgB1=PaWP}A2)qhWG0St}F?EgM@~$L4s+
zP|5&papKpT6NfY8Jf}Wha2TivX!!j*YjJk)$MaIg&ZZ=K(x5p}&REWCrt5=8q6tVjgkD>@dILy#m{2
zJr@_3&;STZp+o1=XslIt{OU}9nWW!}v(2MN<2ksz4&o{m2iug$_79z&HT%Y=n5<)k
z*(U64(UclT=DXr;XQ{+^NvD{+@&%1h9vQteQqJ~Y{SQ0T%POq?apzX>Equv#I%T3W
zQ&di_tiJAm>K+8mB>zG11qXU}E~y){(rZU4LSbXXtnzm6KQf+Q$H(d{ho1b96u9A_
zur*hGh?TW0q6QV^IZbgGYl@4PcC}2!Z}o9kUpcPTnP9_JD=a7|Sl8LnVTshysXQkm
z)7wq4!8K>;rb;+=U1Vm88KZADjl1Zoq1>cF+Fi+9#%#M9e{Li~M#j{<$hke{vUyjD
zyB%?35*I}FEVD4e8AcWQE<5I063rggg^|vf%D@ep5+fT;?-r4gGFt8TvbsxBmhCL!_Z>gCy*-P;qc_`A)zGv=FUOv*
z)|9W-C^4TFX#CKNbkKiTe(7r+HC*)EFD&$`4UdDJAZ-28m`NUI8w`8(hSF>wJ?B
zA3mhTiQ750B*-kR`+qaJWJYj|-p9su)c!B3wMO&7{kHLA
zsH<16re|ko)7h%M`>wnT_nhi!|E6q;{wVMBO*=_mB(^bKH&qo%Or@^~^}c#2g5((8
zyfQo6w6wHzLs&l+z|dVvr7dQE`gAs8Y;AsIvMc+&Y8a15abNE1*ROAw7581nHfQ|$
zrPA-#csZ)&-fez)?<*0uqYcqC3)=lQjy?_d1MKX^w{Hh`e=!xnk#e&2Gxs5qGIWv=
zA)^E2jLu9QG6bG?yf{sKdc20ys_WTa)+LG)egZxv;RBa(Rf=lie1;AV*)Aoc9Jkff
zG-ciW7T)V9Mmoe_V-vVIc@C)=b1AZKy8GQ}amUNmtYYP#-o1NQtHJp#v
zgip@%OLwk0=h{7P_jmVC{YiHf)XvmDcI;RXJ7#-hnOofU&i&0IRG$QjB5{~k*5HKD
zovf?A`XpnkfOM=&DH5Es_BH1K=9WOZVlzx5Vq#Xpfikj{UmXc8i3s+l
z=N1<}8Bv82L;d-#D^|Jn4Rmd3Yq6DHLQBHMbXRIc{VOUeY1{O%Y9LgadJ#$L4m~Zd
z8XX-S)xvhHHC|FP3NSBp>eQ*d&!QU|8XSW{Iww9f+je4hXc$LGhgpeRy0et|{q;<~
z!mitQ`Ty(r(M@y|ziW!3dU#WGV;&ezn`7@Ajl
zPMZk|3yTU0-Ub>7w+vjjiH?okUj%5)HZOKDEA_~}hlqU}5)vI3mkj|SaTiK>XlCW@
zDq>FK%empq+L{#|GkGX|wm+!z-i
zu27sLi`Liu6(Q^npf~8T=%ge*E<}=?SKe4lB5rBPLt*{zdr}9aN#xqKYjc!Qx4o*q
zTLK8}O!2Rm2s5uWMT=uOP@-!P=_z(H_ExjCLSGj1hI
zu(H$qa7|QNOQIaTl%A(=YnuTSDu4t|?bH+_rYUU=v6l|LJoESQbqR-#3kq{pyJ?2u
z8yjUYU(}St_!R!l?93ji3wP>BL&`oGexawYzq~dQzW-ThX@jv9W}pMT0ZTB&0@?BU
zn1IJDaaC%A>&LsQ^hnirT<1b+Qe65=9Txu92W29*PFy^3{P->hJZO)hk&z=~XZ!8j
zw;(@x@_ga9l$|R2z53Cy!y_Yt$YQE54%mN!+X3`7SJJ6_Jebq64TMh+N%URLiOkE&
zQcn)t$hO36qY179mK|}(6sR#Bg2%yw2meJN@(S)K-ORA&vQ;j&i4S2cCP|^-Djyv_?eP9Z};v=eez9S+wK*62H|MLd_1<_Nh$Nf1DWML-_P#YUyA0IaZ3Y%>=>6_BasIP
z9tx8q{Pk;NSl6WuI=*q*lm7V?U&jd@`OlR*%lPFOe8o;hI$gqJ{4Q#s!s68t-VWgJ
zJmDnoly24mO4zX`#9PcsJ92_w3B?^uqd0$%l
zk1wuMi~6Sd{dd-BnXNOGDS{27G!I$yVzV?3vhvb;eCQRw5jX-#D5vdFG0Z{#K)}dX
zMA_6gM*+S-LsuE88t?+k%VaCjt5Qm9H@+tR=kI0-A=w)
z3b8P_sH11G9piLPPR?B1wkfNfEU~hMZv-7(0;Uxa7Z*QTrJ)zjr_hzE7VhYfnwpC4
zLly6}OjZmqW93A20qdXssFM$9ZcbLR0$C1Br4N!n?&JwhwjX7TlbYhhPn~cd3mXC{
z@L+7ON}E(FN9hwos}{-rK`9Yax9i@F20dk{)d42{XZ_3z(?g>{2I
z6CTtYB7*);l5nv_F8yY+{!!n)eXBaSQ_Ze)@#@w5TI6v~PT`5B5foSkyto)9(|h>W
zn<_Vyl7x|oN!G`YAEmbUbopG2Ucv|xQCzhf-5(!26!c1X&D>+^3g`)e$w1OnZ{_y(
zb`1@Us0*W`qZ0+Kinyy?E?h5DQc{-cg_FDD7?R|B`j>C4>`&tNp9|s;v-|?SMRx$h
z2pH52oVc^O;MD*%+l9w$J0b1H5Nr4dtKWt@CVAskASe>R4%W6lw0WbP^OJbqNgkE$^%)ipo
z#kJ*!kPY?q4sQEO
z8nM97(W1tVAP4cX=o|{c$rx2RJp6#^rlXc%*?o$Af|@Z|AkBza&5_#B_hkCvsRF-M
z7i7o6Xd~hNk6l`E*KRv?f63-}0S?OmJL~rM_c7x77?!jHD%dqOt9-`eN1w*S*1DHa
ztx9Aj(}E3jT3;9q5*x{wgtI(&@ZbaJUPp)Csgoz|NjZiZnwoO|6WSIM&$7L`y?vID
zc0v{{$xk~|J5lfE&7f=I;%Byw{mxif4Q$rUWLo9aaK)(334_4E3b=*~?Xi5lnoGDc
z>~@5a`k2X9UMY_Z$rfITQqDb}Kw-1(T9e|h*}UcRpS#HvZ~crr?X+YJVxoxzPOD&P
zrH_%cDgAixhE}`;5{@qY=dtpAJ{3|SN676(S}S?DCWJ}#Af-6wlaw%lp&m?LV@iTk
z)5oim{bj{2r4t#BmBWtl8B#8Pvie*riE-3?)<%iuktk~9lBcut)R-1linODthf;|}
zSS-OACh7RfZouK_ytf3HO>ScxW}`FtLqfu(iKf>*ezU~Pve^pr42Ma;6SLJZxO?}L
z8lR6!2*>593+SmHUEqbbL@%mHr-Y$(j#UI~nw4EV
zY*raaTyM16>F_AI*PK+$ShUY>-K^Vrw;60N1|mNOez*yjSK1(<)p_aS#VfI5RxV-O
zk`4F1J$kbaS`%N~?}?T1S$O2WxiX#M5IAb^q~fuPqd|&oapvt0O=E!e_85
z=mvLkt6jw^)sNX$G%qZ;iHnJ~{(;8rei@lA$<8OwrA~i*eOF(RbMJ#O8jXD21ey9xzSL*=N*OeMrg2A14oE^BYP^SLL+
zH)p)gF?40vtz?oXhWMIK4R2`fBDQq-#x&)p&zUXhZ$VODD*Wm>-P?At&_e!$Mj`)u
zKoi>5jkw{iuA}2Reg5q0Hp?~>82(HjoIJ+aDIrbpJbgFOA->P7j1B#nSg3#^5ZjEN
zmOcsmzsd*pQAjt%*$A+YM{qne^}O^
zR0@L`T@bF`<~T1ivv?8YD|Y@J3u|j@TlcZ;ho-sRpB4O8nm(j~b}mDeDAg!kq17uUBs8WZ>oNWq-#H>Ey;_Vx|x0a5<()fibtM}jgXLkFoOqFDO`7))C1Z!Mcs*|jUt^WB_*21k`
zFjXf}cG;yMc1dkxrfhbf*UX=FjG=*nvls$lDO`U?L&LZF%DXmDg+D3cv&!CPW@f<`
z;QCf<<0!WXusQt|Jd%+UZ>6EppdC_kJTf}E#$RFZ{LR5#h2Pw1pVzEtV`Ef1I0tlZ
zT2gG)zOe7ZK0ZEP#s&s|HS~0K+p&g=BBG*wLsoFrh&(^#>1PHq&L18Y*7DWlk}j-q
z-`aWzR~OE2b+O)@a7QhSXPsXPds#+NF)-ems~wV$b$54nU5&jN1=OtOMem-DgONax
zOR=1iwDjr_jIE%B`RiHcE?93{fTp*7u4WXPTw3|{>(>|lz_p>I@87>;TWv=fxGr#-F<3HDo2Ce5N=?^{wS%s=VW|3*oq^T>kgZyPVsiD!
zd;%LgyUy!3Z`Mm%Y39B_M`r{@WMyRqpuUq|TE8gmpBdo`&-?_^DB7an0##y+JO`q)
z+4x!cRR&BU!d=LD{cK1@B#dHgWY0(--IBEMLA&?!9cE>vpGSfdHa*G7>7^O%Tz$Cu
zz`VD7O(@3rpFMJ#PMj<^ra`(^dwYA4WnQy<%*C;S;Jh+bRaDsIq*319-uOI=GDR^Y
zB*grzNM(^cG{Uk2SJ<%CLp@1}iTz;zEtHS&$*-M3Iu2B9=SpF7T}exz2m>>JN)|g3
z5)v9AECW$#pG-pyGM`yUJ-eWtrtW>UCtWR
zZ@$f$(A3bNw)aLxEG#T&MH!%XeNn1>FRW96$lh`ebcG#ubaX7k%#X*!%xps!(mV>K
z`50oPgLEtFS99zGq-SCR19whDeMnAbydwIoTG9t>^G!Aq`d95OmiNweR_C7o6nc%V
z+ITd*zjAQi``@ibBOCz(U4<0z92#VIjUFkWHbd&|6GMMhhk=BlDW~4($C;crP%OBj
z(HpiLn!kFt%MFdpaT)o2(++S{jFMO7&h{pwxaPqd8LSWi2(hfCnE~!bGaGjvyuGo8
zosb|qx5R5*&i?_XF3jTIYbRWvmqu0q2;%IFH}4_HQWJM>L?k3^J+Zg9_qVj9DnqDR
zr9Nars`*ZxLZkitw?g;s-7BWPQ0PRS5yDVuiiFOinVlul^77?YV8QU={7O6J7rbuW
z`pIk9`QpWko>t;sv{4G?$Af$oQlwCoBVlExE4#CEKRaK!jD&)Qbnz1&%F4=p
zV8#6+Y936qe^}UkKoN-e%&8M6#C^e9Z_4xOWcR!9UqS-!;SCH7cw*AvW>>a@2j49F
z5;Gq>d{|dgTN}1G>o?Vt9}E)`{sgQYoIn6luwx9VmfXFMt!H-LJFIVd#RK{8#fv6W
zt!4QTf&4URu`wZU-*QVm9<1684x-Aoz`{(j8G6a$u7&Sz-o-BcNl10|?>bRHbVi(~
zP7y63{bGs4V6@RQ*wk4hvuKHyuA|Ze{)_6ZNead$x!rtF8o(r~%sPg0N(5e}8tLgR
z%rHSKna;=ZY=01In<}rIr}ItNUo>Rtv`g`356tx$I?SE#Oz)Hkfsn+isH$4(qpfhH
z(r-objSUTo{l%^Wl1w0}sj41f1&o{M>PG6Dn5-2S2wc(9gBN=0>gpp
zZ=gZcnd;1J70Rx?EaC*f@r7KzSX)~=&Ag-B(lxzqM24H6Ur7=uHHS>UEQ6lxq6`lY
zOF}G7VQBjbm?Qc^ax3k6z{b+6`ucjOhYudqVlyTbJ;vK|6?~Vxb)%*{H%DQ^AVx#W
zVSiW-xNO;Qk6cEVoj7bCFE-DC`I
z;>$P`5+(|+9O1cs#VTsrx%4j#LmPfP-_HpXMdE2rPU)KjtLwqFpkCu79JvpA0F30d
zYi
From f92e852490dbffcf8ec0981ebebae3c795329feb Mon Sep 17 00:00:00 2001
From: Colin
Date: Sun, 14 Jul 2019 11:03:47 +0800
Subject: [PATCH 02/72] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=AE=97=E6=B3=95?=
=?UTF-8?q?=E5=86=85=E5=AE=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...04\344\270\216\347\256\227\346\263\225.md" | 43 +++++++++++++++++++
1 file changed, 43 insertions(+)
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
diff --git "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md" "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
new file mode 100644
index 0000000..4f08f6a
--- /dev/null
+++ "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
@@ -0,0 +1,43 @@
+# 问题与简答
+
+## 数据结构与算法篇
+
+### 概论
+
+#### 解决问题的效率
+
+解决问题方法的效率,跟`数据的组织方式`有关,跟`空间的利用效率`有关,也跟`算法的巧妙程度`有关
+
+#### 抽象数据类型
+
+`抽象数据类型`(Abstract Data Type)是一种对"数据类型"的描述,这种描述是"抽象"的
+
+数据类型描述内容:一是`数据对象集`,二是`与数据集合相关联的操作集`
+
+#### 算法
+
+算法是一个`有限指令集`,它接受一些输入,产生输出,并在一定的有限步骤之后终止
+
+算法复杂度
+
+- 空间复杂度 S(n):根据算法写成的程序在执行时占用存储单元的长度
+- 时间复杂度 T(n):根据算法写成的程序在执行时耗时时间的长度
+
+分析算法效率
+
+- 最坏情况的复杂度 Tworst(n)
+- 平均复杂度 Tavg(n)
+
+### 实现基础
+
+### 线性结构
+
+### 堆栈
+
+### 树
+
+### 散列查找
+
+### 图
+
+### 排序
\ No newline at end of file
From 0ac10c419126696a8b3eddcd318b78c9bbe177a0 Mon Sep 17 00:00:00 2001
From: ColinLiu
Date: Sun, 14 Jul 2019 23:16:32 +0800
Subject: [PATCH 03/72] =?UTF-8?q?=E8=A1=A5=E5=85=85=E5=AE=9E=E7=8E=B0?=
=?UTF-8?q?=E5=9F=BA=E7=A1=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 17 ++++----
...04\344\270\216\347\256\227\346\263\225.md" | 42 +++++++++++++++----
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/README.md b/README.md
index a0e09ef..7680909 100644
--- a/README.md
+++ b/README.md
@@ -53,13 +53,16 @@
### 数据结构与算法篇
-- [衡量、比较算法优劣的指标](./docs/02.数据结构与算法/QA.md#衡量比较算法优劣的指标)
-- [链表有哪些](./docs/02.数据结构与算法/QA.md#链表有哪些)
-- [线性结构](./docs/02.数据结构与算法/QA.md#线性结构)
-- [树](./docs/02.数据结构与算法/QA.md#树)
-- [散列查找](./docs/02.数据结构与算法/QA.md#散列查找)
-- [排序](./docs/02.数据结构与算法/QA.md#排序)
-- [其他](./docs/02.数据结构与算法/QA.md#其他)
+- [基本概论](./docs/02.数据结构与算法/QA.md#1-基本概论)
+- [实现基础](./docs/02.数据结构与算法/QA.md#2-实现基础)
+- [线性结构](./docs/02.数据结构与算法/QA.md#3-线性结构)
+- [堆栈](./docs/02.数据结构与算法/QA.md#4-堆栈)
+- [树](./docs/02.数据结构与算法/QA.md#5-树)
+- [散列查找](./docs/02.数据结构与算法/QA.md#6-散列查找)
+- [图](./docs/02.数据结构与算法/QA.md#7-图)
+- [排序](./docs/02.数据结构与算法/QA.md#8-排序)
+- [补充](./docs/02.数据结构与算法/QA.md#9-补充)
+- [经典算法题](./docs/02.数据结构与算法/QA.md#10-经典算法题)
### PHP 篇
diff --git "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md" "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
index 4f08f6a..f98a5d0 100644
--- "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
+++ "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
@@ -2,7 +2,7 @@
## 数据结构与算法篇
-### 概论
+### 1.基本概论
#### 解决问题的效率
@@ -28,16 +28,42 @@
- 最坏情况的复杂度 Tworst(n)
- 平均复杂度 Tavg(n)
-### 实现基础
+### 2.实现基础
-### 线性结构
+数据结构的处理方法是从这些具体应用中`抽象`出共性的数据组织与操作方式,进而采用某种具体的程序设计语言`实现`相应的数据存储与操作
-### 堆栈
+#### 数据存储基础
-### 树
+- 数组
-### 散列查找
+数组是最基本的构造类型,它是一组相同类型数据的有序集合
-### 图
+- 结构
-### 排序
\ No newline at end of file
+结构类型是一种允许把一些数据分量聚合成一个整体的数据类型,它能够把有内在联系的不同类型的数据统一成一个整体,使它们相互关联
+
+- 链表
+
+链表是一种常见而重要的基础数据结构,也是实现复杂数据结构的重要手段
+
+#### 流程控制基础
+
+程序设计语言除了能够表达各种各样的数据外,还必须提供一种手段来表达数据处理的过程,即`程序的控制过程`
+
+按照结构化程序设计的观点,任何程序都可以将程序模块通过三种基本的控制结构进行组合来实现。这三种基本的控制结构是`顺序`、`分支`和`循环`
+
+### 3.线性结构
+
+### 4.堆栈
+
+### 5.树
+
+### 6.散列查找
+
+### 7.图
+
+### 8.排序
+
+### 9.补充
+
+### 10.经典算法题
\ No newline at end of file
From 35f3ef97e09f81c341027dd2bf5a658f32b62bf1 Mon Sep 17 00:00:00 2001
From: ColinLiu
Date: Sun, 14 Jul 2019 23:17:53 +0800
Subject: [PATCH 04/72] =?UTF-8?q?=E9=93=BE=E6=8E=A5=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/README.md b/README.md
index 7680909..4e178cc 100644
--- a/README.md
+++ b/README.md
@@ -53,16 +53,16 @@
### 数据结构与算法篇
-- [基本概论](./docs/02.数据结构与算法/QA.md#1-基本概论)
-- [实现基础](./docs/02.数据结构与算法/QA.md#2-实现基础)
-- [线性结构](./docs/02.数据结构与算法/QA.md#3-线性结构)
-- [堆栈](./docs/02.数据结构与算法/QA.md#4-堆栈)
-- [树](./docs/02.数据结构与算法/QA.md#5-树)
-- [散列查找](./docs/02.数据结构与算法/QA.md#6-散列查找)
-- [图](./docs/02.数据结构与算法/QA.md#7-图)
-- [排序](./docs/02.数据结构与算法/QA.md#8-排序)
-- [补充](./docs/02.数据结构与算法/QA.md#9-补充)
-- [经典算法题](./docs/02.数据结构与算法/QA.md#10-经典算法题)
+- [基本概论](./docs/02.数据结构与算法.md#1-基本概论)
+- [实现基础](./docs/02.数据结构与算法.md#2-实现基础)
+- [线性结构](./docs/02.数据结构与算法.md#3-线性结构)
+- [堆栈](./docs/02.数据结构与算法.md#4-堆栈)
+- [树](./docs/02.数据结构与算法.md#5-树)
+- [散列查找](./docs/02.数据结构与算法.md#6-散列查找)
+- [图](./docs/02.数据结构与算法.md#7-图)
+- [排序](./docs/02.数据结构与算法.md#8-排序)
+- [补充](./docs/02.数据结构与算法.md#9-补充)
+- [经典算法题](./docs/02.数据结构与算法.md#10-经典算法题)
### PHP 篇
From d10f9b61b527352b12d0d1dc0104f0f1b2e4d15d Mon Sep 17 00:00:00 2001
From: ColinLiu
Date: Mon, 15 Jul 2019 00:14:30 +0800
Subject: [PATCH 05/72] =?UTF-8?q?=E5=86=85=E5=AE=B9=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 13 ++---
...04\344\270\216\347\256\227\346\263\225.md" | 58 +++++++++++++++----
2 files changed, 54 insertions(+), 17 deletions(-)
diff --git a/README.md b/README.md
index 4e178cc..6395865 100644
--- a/README.md
+++ b/README.md
@@ -56,13 +56,12 @@
- [基本概论](./docs/02.数据结构与算法.md#1-基本概论)
- [实现基础](./docs/02.数据结构与算法.md#2-实现基础)
- [线性结构](./docs/02.数据结构与算法.md#3-线性结构)
-- [堆栈](./docs/02.数据结构与算法.md#4-堆栈)
-- [树](./docs/02.数据结构与算法.md#5-树)
-- [散列查找](./docs/02.数据结构与算法.md#6-散列查找)
-- [图](./docs/02.数据结构与算法.md#7-图)
-- [排序](./docs/02.数据结构与算法.md#8-排序)
-- [补充](./docs/02.数据结构与算法.md#9-补充)
-- [经典算法题](./docs/02.数据结构与算法.md#10-经典算法题)
+- [树](./docs/02.数据结构与算法.md#4-树)
+- [散列查找](./docs/02.数据结构与算法.md#5-散列查找)
+- [图](./docs/02.数据结构与算法.md#6-图)
+- [排序](./docs/02.数据结构与算法.md#7-排序)
+- [补充](./docs/02.数据结构与算法.md#8-补充)
+- [经典算法题](./docs/02.数据结构与算法.md#9-经典算法题)
### PHP 篇
diff --git "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md" "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
index f98a5d0..83c6cad 100644
--- "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
+++ "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
@@ -2,7 +2,7 @@
## 数据结构与算法篇
-### 1.基本概论
+### 1. 基本概论
#### 解决问题的效率
@@ -28,7 +28,7 @@
- 最坏情况的复杂度 Tworst(n)
- 平均复杂度 Tavg(n)
-### 2.实现基础
+### 2. 实现基础
数据结构的处理方法是从这些具体应用中`抽象`出共性的数据组织与操作方式,进而采用某种具体的程序设计语言`实现`相应的数据存储与操作
@@ -52,18 +52,56 @@
按照结构化程序设计的观点,任何程序都可以将程序模块通过三种基本的控制结构进行组合来实现。这三种基本的控制结构是`顺序`、`分支`和`循环`
-### 3.线性结构
+### 3. 线性结构
-### 4.堆栈
+#### 线性表
-### 5.树
+线性表(Linear List)是由同一类型的数据元素构成的有序序列的线性结构
-### 6.散列查找
+操作集:初始化、指定查找、查找、插入、删除、求表长
-### 7.图
+实现方式:顺序存储、链式存储
-### 8.排序
+#### 堆栈
-### 9.补充
+堆栈(Stack)可以认为是具有一定约束的线性表,插入和删除操作都作用在一个称为栈顶(Top)的端点位置
-### 10.经典算法题
\ No newline at end of file
+操作集:生成栈、判断是否满、压栈、判断是否空、出栈
+
+实现方式:顺序存储、链式存储
+
+#### 队列
+
+队列(Queue)是一个有序线性表,队列的插入和删除操作分别是在线性表的两个不同的端点进行
+
+操作集:生成队列、判断是否满、压入队列、判断是否为空,移除队列
+
+实现方式:顺序存储、链式存储
+
+### 4. 树
+
+树(Tree)是一种十分重要且广泛应用的非线性数据结构
+
+#### 二叉树
+
+五种基本形态:空二叉树、只有根节点的二叉树、只有根节点和左子树TL的二叉树、只有根节点和右子树TR的二叉树、具有根节点、左子树TL和右子树TTR的二叉树
+
+其它二叉树:斜二叉树、满二叉树、完美二叉树
+
+实现方式:顺序存储、链式存储
+
+操作集:创建二叉树、判断是否为空、遍历(先序遍历、中序遍历、后序遍历、层序遍历)
+
+#### 二叉搜索树
+
+#### 平衡二叉树
+
+### 5. 散列查找
+
+### 6. 图
+
+### 7. 排序
+
+### 8. 补充
+
+### 9. 经典算法题
\ No newline at end of file
From 17588a92804488d7d2a4f352562cd29d5ae956cf Mon Sep 17 00:00:00 2001
From: ColinLiu
Date: Mon, 15 Jul 2019 00:15:42 +0800
Subject: [PATCH 06/72] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md" | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md" "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
index 83c6cad..415e9c6 100644
--- "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
+++ "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
@@ -84,7 +84,7 @@
#### 二叉树
-五种基本形态:空二叉树、只有根节点的二叉树、只有根节点和左子树TL的二叉树、只有根节点和右子树TR的二叉树、具有根节点、左子树TL和右子树TTR的二叉树
+五种基本形态:空二叉树、只有根节点的二叉树、只有根节点和左子树TL的二叉树、只有根节点和右子树TR的二叉树、具有根节点、左子树TL和右子树TR的二叉树
其它二叉树:斜二叉树、满二叉树、完美二叉树
From 10bf95e51f2893c413710903932f3978a5716425 Mon Sep 17 00:00:00 2001
From: ColinLiu
Date: Sun, 21 Jul 2019 18:31:37 +0800
Subject: [PATCH 07/72] =?UTF-8?q?=E6=96=B0=E5=A2=9EDSA=E5=86=85=E5=AE=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...04\344\270\216\347\256\227\346\263\225.md" | 64 +++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md" "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
index 415e9c6..da4d827 100644
--- "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
+++ "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
@@ -94,10 +94,74 @@
#### 二叉搜索树
+二叉搜索树(Binary Search Tree)是一种对排序和查找都很有用的特殊二叉树
+
+定义:左子树 < 根节点 < 右子树
+
+实现方式:一般用链表实现
+
+操作集:创建二叉树、判断是否为空、遍历、查找、查找最小元素、查找最大元素、插入、删除
+
+时间复杂度:最好 O(logN) 最差 O(N)
+
#### 平衡二叉树
+平衡二叉树(Balanced Binary Tree)又称为 AVL 树,AVL 树的插入、删除、查找操作均可在O(logN)时间内完成
+
+定义:任一结点的左、右子树均为 AVL 树;根节点左、右子树高度差的绝对值不超过1
+
+平衡二叉树的调整:单旋调整、双旋调整
+
+#### 树的应用
+
+堆及其操作、哈夫曼树、集合及其运算
+
### 5. 散列查找
+符号表(SymbolTable)是名字(Name)-属性(Attribute)对的集合,符号表最核心的操作是查找、插入和删除
+
+操作集:创建符号表、查找指定名字是否存在、获取指定名字对应属性、更改指定名字对应属性、插入新名字及其属性、删除名字及其属性
+
+使用散列技术实现符号表的操作集,符号表也叫做`散列表`(Hash Table,即哈希表),散列(Hashing)是一种重要的查找方法
+
+散列函数(哈希函数):在查找数据时,由函数 h 对给定值 key 计算出地址,将 key 与该地址单元中数据对象关键字进行比较,确定查找是否成功。散列法又称为"关键字-地址转换法"
+
+关键字分类:一般把关键字分为`数字型关键字`和`字符串型关键字`
+
+#### 数字型关键字的散列构造
+
+- 直接定址法
+
+h(key) = a x key + b (a、b为常数)
+
+- 除留余数法
+
+h(key) = key mod p
+
+- 数字分析法
+
+h(key) = atoi(key + 7)
+
+#### 字符串型关键字的散列构造
+
+- ASCII 码加和法
+
+h(key) = (Σkey[i]) mode TableSize
+
+#### 冲突处理
+
+- 开放地址法
+
+开放地址法就是一旦产生了冲突,即该地址已经存放了其它数据元素,就去寻找另一个空的散列地址
+
+- 链地址法
+
+链地址法是将所有关键词为同义词的数据对象通过结点链接存储在同一个单链表中
+
+- 影响冲突的因素
+
+散列函数是否均匀、处理冲突的方法、散列表的装填因子 α
+
### 6. 图
### 7. 排序
From 93c9a3296e652fb90c523b8c704eb03f365a8df3 Mon Sep 17 00:00:00 2001
From: ColinLiu
Date: Sun, 21 Jul 2019 20:04:12 +0800
Subject: [PATCH 08/72] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8E=92=E5=BA=8F?=
=?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=86=85=E5=AE=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...04\344\270\216\347\256\227\346\263\225.md" | 66 +++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md" "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
index da4d827..7697026 100644
--- "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
+++ "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
@@ -164,8 +164,74 @@ h(key) = (Σkey[i]) mode TableSize
### 6. 图
+图的结构是任意两个数据对象之前都可能存在某种特定关系的数据结构
+
### 7. 排序
+没有一种排序算法在任何情况下都是最优的,必须根据实际情况选择最优的算法来解决问题
+
+算法稳定性:在一组待排序记录中,如果存在任意两个相等的记录 R 和 S,且在待排序记录中 R 在 S 前,如果在排序后 R 依然在 S 前,即它们的前后位置在排序前后不发生改变,则称为排序算法为稳定的
+
+#### 选择排序
+
+- 简单选择排序
+
+简单选择排序(Simple Selection Sort)是一种直观的排序算法,在未排序的序列中,选出最小的元素和序列的首位元素交换,接下来在剩下的未排序序列中再选出最小元素与序列的第二位元素交换,依次类推,最后形成从小到大的已排序序列
+
+时间复杂度:O(N2)
+
+- 堆排序
+
+将无序的序列生成一个最大堆,将堆顶元素与最后一个元素对换位置,将剩下元素生成最大堆,依次进行元素交换并生成最大堆
+
+时间复杂度:O(NlogN)
+空间复杂度:O(1)
+
+#### 插入排序
+
+- 简单插入排序
+
+将待排序的一组序列分为已排好序和未排序的两个部分,初始状态时,已排序序列仅包含第一个元素,未排序序列中的元素为除了第一个以外N-1个元素;此后将未排序序列中的元素逐一插入到已排序的序列中。如此往复,经过N-1次插入后,未排序序列中元素个数为0,则排序完成
+
+时间复杂度:O(N2) 稳定排序
+
+- 希尔排序
+
+将待排序的一组元素按一定间隔分为若干个序列,分别进行插入排序。开始时设置的"间隔"较大,在每轮排序中将间隔逐步减小,直到"间隔"为1,也就是最后一步是进行简单插入排序
+
+时间复杂度:和增量序列的选取有关 非稳定排序
+
+#### 交换排序
+
+- 冒泡排序
+
+对元素个数为 N 的待排序序列进行排序时,共进行N-1次循环。在第 k 次循环中,对从第1到第N-k个元素从前往后进行比较,每次比较相邻的两个元素,若前一个元素大于后一个元素,则两者互换位置,否则保持位置不变
+
+时间复杂度:O(N2)
+
+- 快速排序
+
+将未排序元素根据一个作为基准的"主元"分为两个子序列,其中一个子序列的记录均大于主元,而另一个子序列均小于主元,然后递归地对这两个子序列用类似的方法进行排序
+
+时间复杂度:O(Nlog2N)
+
+#### 归并排序
+
+将大小为 N 的序列看成 N 个长度为1的子序列,接下来将相邻子序列两两进行归并操作,形成N/2(+1)个长度为2(或1)的有序子序列;然后再继续进行相邻子序列两两归并操作,如果一直循环,直到剩下1个长度为 N 的序列,则该序列为原序列完成排序后的结果
+
+时间复杂度:O(Nlog2N)
+空间复杂度:O(N)
+
+#### 基数排序
+
+- 桶排序
+
+如果已知 N 个关键字的取值范围是在 0 到 M-1 之间,而 M 比 N 小的多,则桶排序算法将关键字的每个取值建立一个"桶",即建立 M 个桶,在扫描 N 个关键字时,将每个关键字放入相应的桶中,然后按桶的顺序收集一遍就自然有序了
+
+- 基数排序
+
+基数排序是桶排序的一种推广,它所考虑的待排记录包含不止一个关键字
+
### 8. 补充
### 9. 经典算法题
\ No newline at end of file
From e1f22fb1a16366850f286be95cd0a5f7ad68811d Mon Sep 17 00:00:00 2001
From: ColinLiu
Date: Sun, 21 Jul 2019 20:10:43 +0800
Subject: [PATCH 09/72] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=86=85=E5=AE=B9?=
=?UTF-8?q?=E7=BB=93=E6=9E=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 5 +-
.../QA.md" | 93 ------------------
docs/{ => assets}/interview.png | Bin
docs/{ => assets}/wechat.jpg | Bin
4 files changed, 2 insertions(+), 96 deletions(-)
delete mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/QA.md"
rename docs/{ => assets}/interview.png (100%)
rename docs/{ => assets}/wechat.jpg (100%)
diff --git a/README.md b/README.md
index 6395865..a00b7d9 100644
--- a/README.md
+++ b/README.md
@@ -16,14 +16,13 @@
## 面试流程
-
+
## 微信群
扫码加微信,备注:`PIQA`,有时候可能在忙,稍等片刻
-
-
+
## 问题列表
### 网络篇
diff --git "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/QA.md" "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/QA.md"
deleted file mode 100644
index 89dfd26..0000000
--- "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/QA.md"
+++ /dev/null
@@ -1,93 +0,0 @@
-# 问题与简答
-
-## 数据结构与算法篇
-
-### 衡量、比较算法优劣的指标
-
-> 空间复杂度S(n)、时间复杂度T(n)
-
-### 链表有哪些
-
-> 单向链表、双向链表、循环链表
-
-### 线性结构
-
-- 线性表
-
-> 线性表是由同一类型的数据元素构成的有序序列的线性结构
-
-> 实现方式: 线性存储、链式存储
-
-- 堆栈
-
-> 堆栈可以认为是具有一定约束的线性表,插入和删除操作都作用在一个称为栈顶的端点位置
-
-- 队列
-
-> 队列是一个有序线性表,但队列的插入和删除是分别在线性表的两个不同端点进行的
-
-### 树
-
-- 查找
-
-> 顺序查找、二分查找
-
-- 二叉树
-
-- 二叉搜索树
-
-- 平衡二叉树
-
-### 散列查找
-
-- 散列表
-
-- 散列函数的构造方法
-
-> 数字型关键字、字符串关键字
-
-- 处理冲突的方法
-
-> 开放地址法、链地址法
-
-### 排序
-
-- 选择排序
-
-> 简单选择排序、堆排序
-
-- 插入排序
-
-> 简单插入排序、希尔排序
-
-- 交换排序
-
-> 冒泡排序、快速排序
-
-- 归并排序
-
-- 基数排序
-
-> 桶排序、基数排序
-
-### 跳跃表
-
-### 其他
-
-- KPM
-
-- 布隆过滤器
-
-- 贪心算法
-
-- 回溯算法
-
-- 动态规划
-
-- 最小生成树
-
-- 最短路径
-
-- 推荐算法
-
-- 深度优先、广度优先
\ No newline at end of file
diff --git a/docs/interview.png b/docs/assets/interview.png
similarity index 100%
rename from docs/interview.png
rename to docs/assets/interview.png
diff --git a/docs/wechat.jpg b/docs/assets/wechat.jpg
similarity index 100%
rename from docs/wechat.jpg
rename to docs/assets/wechat.jpg
From 852b7c4b4a1eb438422e8520ef880b2e09b892bb Mon Sep 17 00:00:00 2001
From: ColinLiu
Date: Sat, 27 Jul 2019 16:52:59 +0800
Subject: [PATCH 10/72] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8B=93=E5=B1=95?=
=?UTF-8?q?=E8=B5=84=E6=96=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 2 +-
...6\236\204\344\270\216\347\256\227\346\263\225.md" | 12 +++++++-----
...0\257\255\345\257\271\347\205\247\350\241\250.md" | 4 ++++
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
index a00b7d9..980a52f 100644
--- a/README.md
+++ b/README.md
@@ -52,7 +52,7 @@
### 数据结构与算法篇
-- [基本概论](./docs/02.数据结构与算法.md#1-基本概论)
+- [概述](./docs/02.数据结构与算法.md#1-概述)
- [实现基础](./docs/02.数据结构与算法.md#2-实现基础)
- [线性结构](./docs/02.数据结构与算法.md#3-线性结构)
- [树](./docs/02.数据结构与算法.md#4-树)
diff --git "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md" "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
index 7697026..674bd32 100644
--- "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
+++ "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
@@ -2,7 +2,7 @@
## 数据结构与算法篇
-### 1. 基本概论
+### 1. 概述
#### 解决问题的效率
@@ -10,24 +10,26 @@
#### 抽象数据类型
-`抽象数据类型`(Abstract Data Type)是一种对"数据类型"的描述,这种描述是"抽象"的
+`抽象数据类型`(Abstract Data Type,ADT)是一种对"数据类型"的描述,这种描述是"抽象"的
数据类型描述内容:一是`数据对象集`,二是`与数据集合相关联的操作集`
-#### 算法
+#### 算法定义
算法是一个`有限指令集`,它接受一些输入,产生输出,并在一定的有限步骤之后终止
-算法复杂度
+#### 算法复杂度
- 空间复杂度 S(n):根据算法写成的程序在执行时占用存储单元的长度
- 时间复杂度 T(n):根据算法写成的程序在执行时耗时时间的长度
-分析算法效率
+#### 分析算法效率
- 最坏情况的复杂度 Tworst(n)
- 平均复杂度 Tavg(n)
+拓展阅读 [《数据结构与算法概述》](https://blog.maplemark.cn/2019/07/数据结构与算法概述.html)
+
### 2. 实现基础
数据结构的处理方法是从这些具体应用中`抽象`出共性的数据组织与操作方式,进而采用某种具体的程序设计语言`实现`相应的数据存储与操作
diff --git "a/docs/\346\234\257\350\257\255\345\257\271\347\205\247\350\241\250.md" "b/docs/\346\234\257\350\257\255\345\257\271\347\205\247\350\241\250.md"
index a04f7c7..0caf026 100644
--- "a/docs/\346\234\257\350\257\255\345\257\271\347\205\247\350\241\250.md"
+++ "b/docs/\346\234\257\350\257\255\345\257\271\347\205\247\350\241\250.md"
@@ -48,6 +48,10 @@ ACK (Acknowledgement)即是确认字符,在数据通信中,接收站发给
传输层安全性协议(英语:Transport Layer Security,缩写作 TLS),及其前身安全套接层(Secure Sockets Layer,缩写作 SSL)是一种安全协议,目的是为互联网通信提供安全及数据完整性保障
+## ADT
+
+抽象数据类型(Abstract Data Type,ADT)是计算机科学中具有类似行为的特定类别的数据结构的数学模型;或者具有类似语义的一种或多种程序设计语言的数据类型。抽象数据类型是间接定义的,通过其上的可执行的操作以及这些操作的效果的数学约束(与可能的代价)
+
## PHP
PHP(全称:PHP:Hypertext Preprocessor,即“PHP:超文本预处理器”)是一种开源的通用计算机脚本语言,尤其适用于网络开发并可嵌入 HTML 中使用
From a44810d3757a6f98399372039086917ade414f5b Mon Sep 17 00:00:00 2001
From: ColinLiu
Date: Sun, 28 Jul 2019 21:34:04 +0800
Subject: [PATCH 11/72] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8B=93=E5=B1=95?=
=?UTF-8?q?=E8=B5=84=E6=96=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md" | 2 ++
1 file changed, 2 insertions(+)
diff --git "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md" "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
index 674bd32..682ca14 100644
--- "a/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
+++ "b/docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225.md"
@@ -54,6 +54,8 @@
按照结构化程序设计的观点,任何程序都可以将程序模块通过三种基本的控制结构进行组合来实现。这三种基本的控制结构是`顺序`、`分支`和`循环`
+拓展阅读 [《数据结构实现基础》](https://blog.maplemark.cn/2019/07/数据结构实现基础.html)
+
### 3. 线性结构
#### 线性表
From 550fdf51b6cfb80ca6865d1048ed4dbb93343872 Mon Sep 17 00:00:00 2001
From: ColinLiu
Date: Tue, 13 Aug 2019 15:59:03 +0800
Subject: [PATCH 12/72] =?UTF-8?q?=E5=86=85=E5=AE=B9=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 980a52f..9780061 100644
--- a/README.md
+++ b/README.md
@@ -18,11 +18,10 @@

-## 微信群
+## 微信公众号
-扫码加微信,备注:`PIQA`,有时候可能在忙,稍等片刻
+
-
## 问题列表
### 网络篇
From dba8e47ca3bd9b93bf94e02bab048ff5db0c9b52 Mon Sep 17 00:00:00 2001
From: Sccw <34470287+Sccw@users.noreply.github.com>
Date: Sat, 23 Nov 2019 13:32:23 +0800
Subject: [PATCH 13/72] =?UTF-8?q?Update=20and=20rename=20docs/03.PHP/01.PH?=
=?UTF-8?q?P=E6=95=B0=E7=BB=84.md=20to=20=E6=96=87=E6=A1=A3/=2003.PHP/01.P?=
=?UTF-8?q?HP=E6=95=B0=E7=BB=84.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
增加了换行,之前看起来在一坨看起来很难受
---
.../01.PHP\346\225\260\347\273\204.md" | 82 ++++++++++++++++++-
1 file changed, 81 insertions(+), 1 deletion(-)
rename "docs/03.PHP/01.PHP\346\225\260\347\273\204.md" => "\346\226\207\346\241\243/ 03.PHP/01.PHP\346\225\260\347\273\204.md" (95%)
diff --git "a/docs/03.PHP/01.PHP\346\225\260\347\273\204.md" "b/\346\226\207\346\241\243/ 03.PHP/01.PHP\346\225\260\347\273\204.md"
similarity index 95%
rename from "docs/03.PHP/01.PHP\346\225\260\347\273\204.md"
rename to "\346\226\207\346\241\243/ 03.PHP/01.PHP\346\225\260\347\273\204.md"
index 2c07df1..8681735 100644
--- "a/docs/03.PHP/01.PHP\346\225\260\347\273\204.md"
+++ "b/\346\226\207\346\241\243/ 03.PHP/01.PHP\346\225\260\347\273\204.md"
@@ -96,83 +96,163 @@ PHP 有一些用来排序数组的函数
## 数组函数
array_change_key_case — 将数组中的所有键名修改为全大写或小写
+
array_chunk — 将一个数组分割成多个
+
array_column — 返回数组中指定的一列
+
array_combine — 创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值
+
array_count_values — 统计数组中所有的值
+
array_diff_assoc — 带索引检查计算数组的差集
+
array_diff_key — 使用键名比较计算数组的差集
+
array_diff_uassoc — 用用户提供的回调函数做索引检查来计算数组的差集
+
array_diff_ukey — 用回调函数对键名比较计算数组的差集
+
array_diff — 计算数组的差集
+
array_fill_keys — 使用指定的键和值填充数组
+
array_fill — 用给定的值填充数组
+
array_filter — 用回调函数过滤数组中的单元
+
array_flip — 交换数组中的键和值
+
array_intersect_assoc — 带索引检查计算数组的交集
+
array_intersect_key — 使用键名比较计算数组的交集
+
array_intersect_uassoc — 带索引检查计算数组的交集,用回调函数比较索引
+
array_intersect_ukey — 用回调函数比较键名来计算数组的交集
+
array_intersect — 计算数组的交集
+
array_key_exists — 检查数组里是否有指定的键名或索引
+
array_key_first — Gets the first key of an array
+
array_key_last — Gets the last key of an array
+
array_keys — 返回数组中部分的或所有的键名
+
array_map — 为数组的每个元素应用回调函数
+
array_merge_recursive — 递归地合并一个或多个数组
+
array_merge — 合并一个或多个数组
+
array_multisort — 对多个数组或多维数组进行排序
+
array_pad — 以指定长度将一个值填充进数组
+
array_pop — 弹出数组最后一个单元(出栈)
+
array_product — 计算数组中所有值的乘积
+
array_push — 将一个或多个单元压入数组的末尾(入栈)
+
array_rand — 从数组中随机取出一个或多个单元
+
array_reduce — 用回调函数迭代地将数组简化为单一的值
+
array_replace_recursive — 使用传递的数组递归替换第一个数组的元素
+
array_replace — 使用传递的数组替换第一个数组的元素
+
array_reverse — 返回单元顺序相反的数组
+
array_search — 在数组中搜索给定的值,如果成功则返回首个相应的键名
+
array_shift — 将数组开头的单元移出数组
+
array_slice — 从数组中取出一段
+
array_splice — 去掉数组中的某一部分并用其它值取代
+
array_sum — 对数组中所有值求和
+
array_udiff_assoc — 带索引检查计算数组的差集,用回调函数比较数据
+
array_udiff_uassoc — 带索引检查计算数组的差集,用回调函数比较数据和索引
+
array_udiff — 用回调函数比较数据来计算数组的差集
+
array_uintersect_assoc — 带索引检查计算数组的交集,用回调函数比较数据
+
array_uintersect_uassoc — 带索引检查计算数组的交集,用单独的回调函数比较数据和索引
+
array_uintersect — 计算数组的交集,用回调函数比较数据
+
array_unique — 移除数组中重复的值
+
array_unshift — 在数组开头插入一个或多个单元
+
array_values — 返回数组中所有的值
+
array_walk_recursive — 对数组中的每个成员递归地应用用户函数
+
array_walk — 使用用户自定义函数对数组中的每个元素做回调处理
+
array — 新建一个数组
+
arsort — 对数组进行逆向排序并保持索引关系
+
asort — 对数组进行排序并保持索引关系
+
compact — 建立一个数组,包括变量名和它们的值
+
count — 计算数组中的单元数目,或对象中的属性个数
+
current — 返回数组中的当前单元
+
each — 返回数组中当前的键/值对并将数组指针向前移动一步
+
end — 将数组的内部指针指向最后一个单元
+
extract — 从数组中将变量导入到当前的符号表
+
in_array — 检查数组中是否存在某个值
+
key_exists — 别名 array_key_exists
+
key — 从关联数组中取得键名
+
krsort — 对数组按照键名逆向排序
+
ksort — 对数组按照键名排序
+
list — 把数组中的值赋给一组变量
+
natcasesort — 用“自然排序”算法对数组进行不区分大小写字母的排序
+
natsort — 用“自然排序”算法对数组排序
+
next — 将数组中的内部指针向前移动一位
+
pos — current 的别名
+
prev — 将数组的内部指针倒回一位
+
range — 根据范围创建数组,包含指定的元素
+
reset — 将数组的内部指针指向第一个单元
+
rsort — 对数组逆向排序
+
shuffle — 打乱数组
+
sizeof — count 的别名
+
sort — 对数组排序
+
uasort — 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联
+
uksort — 使用用户自定义的比较函数对数组中的键名进行排序
-usort — 使用用户自定义的比较函数对数组中的值进行排序
\ No newline at end of file
+
+usort — 使用用户自定义的比较函数对数组中的值进行排序
From 2d837634b4d4ceeb380a92060aef3628bf5f44b4 Mon Sep 17 00:00:00 2001
From: ColinLiu
Date: Sat, 30 Nov 2019 23:09:26 +0800
Subject: [PATCH 14/72] =?UTF-8?q?=E4=BF=AE=E5=A4=8DPR=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../03.PHP/01.PHP\346\225\260\347\273\204.md" | 516 +++++++++---------
1 file changed, 258 insertions(+), 258 deletions(-)
rename "\346\226\207\346\241\243/ 03.PHP/01.PHP\346\225\260\347\273\204.md" => "docs/03.PHP/01.PHP\346\225\260\347\273\204.md" (96%)
diff --git "a/\346\226\207\346\241\243/ 03.PHP/01.PHP\346\225\260\347\273\204.md" "b/docs/03.PHP/01.PHP\346\225\260\347\273\204.md"
similarity index 96%
rename from "\346\226\207\346\241\243/ 03.PHP/01.PHP\346\225\260\347\273\204.md"
rename to "docs/03.PHP/01.PHP\346\225\260\347\273\204.md"
index 8681735..a3b88dd 100644
--- "a/\346\226\207\346\241\243/ 03.PHP/01.PHP\346\225\260\347\273\204.md"
+++ "b/docs/03.PHP/01.PHP\346\225\260\347\273\204.md"
@@ -1,258 +1,258 @@
-# PHP 数组
-
-## 简介
-
-这些函数允许你通过不同的方式来使用和操作数组。数组是存储、管理和操作变量组的必不可少的工具。
-
-PHP 支持简单数组和多维数组,数组可由用户自己创建也可以由其它函数创建。有很多特殊的数据库处理函数可以从数据库查询中返回数组以及一些返回数组的函数。
-
-## 预定义常量
-
-下列常量作为 PHP 核心的一部分总是可用的。
-
-CASE_LOWER (integer)
-
-> CASE_LOWER 用在 array_change_key_case() 中将数组的键名转换成小写字母。这也是 array_change_key_case() 的默认值。
-
-CASE_UPPER (integer)
-
-> CASE_UPPER 用在 array_change_key_case() 中将数组的键名转换成大写字母。
-排序顺序标识:
-
-SORT_ASC (integer)
-
-> SORT_ASC 用在 array_multisort() 函数中,使其升序排列。
-
-SORT_DESC (integer)
-
-> SORT_DESC 用在 array_multisort() 函数中,使其降序排列。
-
-- 排序类型标识:用于各种排序函数
-
-SORT_REGULAR (integer)
-
-> SORT_REGULAR 用于对对象进行通常比较。
-
-SORT_NUMERIC (integer)
-
-> SORT_NUMERIC 用于对对象进行数值比较。
-
-SORT_STRING (integer)
-
-> SORT_STRING 用于对对象进行字符串比较。
-
-SORT_LOCALE_STRING (integer)
-
-> SORT_LOCALE_STRING 基于当前区域来对对象进行字符串比较。PHP 4.4.0 和 5.0.2 新加。
-
-COUNT_NORMAL (integer)
-
-COUNT_RECURSIVE (integer)
-
-EXTR_OVERWRITE (integer)
-
-EXTR_SKIP (integer)
-
-EXTR_PREFIX_SAME (integer)
-
-EXTR_PREFIX_ALL (integer)
-
-EXTR_PREFIX_INVALID (integer)
-
-EXTR_PREFIX_IF_EXISTS (integer)
-
-EXTR_IF_EXISTS (integer)
-
-EXTR_REFS (integer)
-
-## 对数组进行排序
-
-PHP 有一些用来排序数组的函数
-
-主要区别有:
-
-- 有些函数基于 array 的键来排序, 而其他的基于值来排序的:$array['key'] = 'value';。
-- 排序之后键和值之间的关联关系是否能够保持, 是指排序之后数组的键可能 会被重置为数字型的(0,1,2 ...)。
-- 排序的顺序有:字母表顺序, 由低到高(升序), 由高到低(降序),数字排序,自然排序,随机顺序或者用户自定义排序。
-- 注意:下列的所有排序函数都是直接作用于数组本身, 而不是返回一个新的有序的数组。
-- 以下函数对于数组中相等的元素,它们在排序后的顺序是未定义的。 (也即相等元素之间的顺序是不稳定的)。
-
-|函数名称|排序依据|数组索引健保持|排序的顺序|相关函数|
-|-|-|-|-|-|
-|array_multisort()|值|键值关联的保持,数字类型的不保持|第一个数组或者由选项指定|array_walk()|
-|asort()|值|是|由低到高|arsort()|
-|arsort()|值|是|由高到低|asort()|
-|krsort()|键|是|由高到低|ksort()|
-|ksort()|键|是|由低到高|asort()|
-|natcasesort()|值|是|自然排序,大小写不敏感|natsort()|
-|natsort()|值|是|自然排序|natcasesort()|
-|rsort()|值|否|由高到低|sort()|
-|shuffle()|值|否|随机|array_rand()|
-|sort()|值|否|由低到高|rsort()|
-|uasort()|值|是|由用户定义|uksort()|
-|uksort()|键|是|由用户定义|uasort()|
-|usort()|值|否|由用户定义|uasort()|
-
-## 数组函数
-
-array_change_key_case — 将数组中的所有键名修改为全大写或小写
-
-array_chunk — 将一个数组分割成多个
-
-array_column — 返回数组中指定的一列
-
-array_combine — 创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值
-
-array_count_values — 统计数组中所有的值
-
-array_diff_assoc — 带索引检查计算数组的差集
-
-array_diff_key — 使用键名比较计算数组的差集
-
-array_diff_uassoc — 用用户提供的回调函数做索引检查来计算数组的差集
-
-array_diff_ukey — 用回调函数对键名比较计算数组的差集
-
-array_diff — 计算数组的差集
-
-array_fill_keys — 使用指定的键和值填充数组
-
-array_fill — 用给定的值填充数组
-
-array_filter — 用回调函数过滤数组中的单元
-
-array_flip — 交换数组中的键和值
-
-array_intersect_assoc — 带索引检查计算数组的交集
-
-array_intersect_key — 使用键名比较计算数组的交集
-
-array_intersect_uassoc — 带索引检查计算数组的交集,用回调函数比较索引
-
-array_intersect_ukey — 用回调函数比较键名来计算数组的交集
-
-array_intersect — 计算数组的交集
-
-array_key_exists — 检查数组里是否有指定的键名或索引
-
-array_key_first — Gets the first key of an array
-
-array_key_last — Gets the last key of an array
-
-array_keys — 返回数组中部分的或所有的键名
-
-array_map — 为数组的每个元素应用回调函数
-
-array_merge_recursive — 递归地合并一个或多个数组
-
-array_merge — 合并一个或多个数组
-
-array_multisort — 对多个数组或多维数组进行排序
-
-array_pad — 以指定长度将一个值填充进数组
-
-array_pop — 弹出数组最后一个单元(出栈)
-
-array_product — 计算数组中所有值的乘积
-
-array_push — 将一个或多个单元压入数组的末尾(入栈)
-
-array_rand — 从数组中随机取出一个或多个单元
-
-array_reduce — 用回调函数迭代地将数组简化为单一的值
-
-array_replace_recursive — 使用传递的数组递归替换第一个数组的元素
-
-array_replace — 使用传递的数组替换第一个数组的元素
-
-array_reverse — 返回单元顺序相反的数组
-
-array_search — 在数组中搜索给定的值,如果成功则返回首个相应的键名
-
-array_shift — 将数组开头的单元移出数组
-
-array_slice — 从数组中取出一段
-
-array_splice — 去掉数组中的某一部分并用其它值取代
-
-array_sum — 对数组中所有值求和
-
-array_udiff_assoc — 带索引检查计算数组的差集,用回调函数比较数据
-
-array_udiff_uassoc — 带索引检查计算数组的差集,用回调函数比较数据和索引
-
-array_udiff — 用回调函数比较数据来计算数组的差集
-
-array_uintersect_assoc — 带索引检查计算数组的交集,用回调函数比较数据
-
-array_uintersect_uassoc — 带索引检查计算数组的交集,用单独的回调函数比较数据和索引
-
-array_uintersect — 计算数组的交集,用回调函数比较数据
-
-array_unique — 移除数组中重复的值
-
-array_unshift — 在数组开头插入一个或多个单元
-
-array_values — 返回数组中所有的值
-
-array_walk_recursive — 对数组中的每个成员递归地应用用户函数
-
-array_walk — 使用用户自定义函数对数组中的每个元素做回调处理
-
-array — 新建一个数组
-
-arsort — 对数组进行逆向排序并保持索引关系
-
-asort — 对数组进行排序并保持索引关系
-
-compact — 建立一个数组,包括变量名和它们的值
-
-count — 计算数组中的单元数目,或对象中的属性个数
-
-current — 返回数组中的当前单元
-
-each — 返回数组中当前的键/值对并将数组指针向前移动一步
-
-end — 将数组的内部指针指向最后一个单元
-
-extract — 从数组中将变量导入到当前的符号表
-
-in_array — 检查数组中是否存在某个值
-
-key_exists — 别名 array_key_exists
-
-key — 从关联数组中取得键名
-
-krsort — 对数组按照键名逆向排序
-
-ksort — 对数组按照键名排序
-
-list — 把数组中的值赋给一组变量
-
-natcasesort — 用“自然排序”算法对数组进行不区分大小写字母的排序
-
-natsort — 用“自然排序”算法对数组排序
-
-next — 将数组中的内部指针向前移动一位
-
-pos — current 的别名
-
-prev — 将数组的内部指针倒回一位
-
-range — 根据范围创建数组,包含指定的元素
-
-reset — 将数组的内部指针指向第一个单元
-
-rsort — 对数组逆向排序
-
-shuffle — 打乱数组
-
-sizeof — count 的别名
-
-sort — 对数组排序
-
-uasort — 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联
-
-uksort — 使用用户自定义的比较函数对数组中的键名进行排序
-
-usort — 使用用户自定义的比较函数对数组中的值进行排序
+# PHP 数组
+
+## 简介
+
+这些函数允许你通过不同的方式来使用和操作数组。数组是存储、管理和操作变量组的必不可少的工具。
+
+PHP 支持简单数组和多维数组,数组可由用户自己创建也可以由其它函数创建。有很多特殊的数据库处理函数可以从数据库查询中返回数组以及一些返回数组的函数。
+
+## 预定义常量
+
+下列常量作为 PHP 核心的一部分总是可用的。
+
+CASE_LOWER (integer)
+
+> CASE_LOWER 用在 array_change_key_case() 中将数组的键名转换成小写字母。这也是 array_change_key_case() 的默认值。
+
+CASE_UPPER (integer)
+
+> CASE_UPPER 用在 array_change_key_case() 中将数组的键名转换成大写字母。
+排序顺序标识:
+
+SORT_ASC (integer)
+
+> SORT_ASC 用在 array_multisort() 函数中,使其升序排列。
+
+SORT_DESC (integer)
+
+> SORT_DESC 用在 array_multisort() 函数中,使其降序排列。
+
+- 排序类型标识:用于各种排序函数
+
+SORT_REGULAR (integer)
+
+> SORT_REGULAR 用于对对象进行通常比较。
+
+SORT_NUMERIC (integer)
+
+> SORT_NUMERIC 用于对对象进行数值比较。
+
+SORT_STRING (integer)
+
+> SORT_STRING 用于对对象进行字符串比较。
+
+SORT_LOCALE_STRING (integer)
+
+> SORT_LOCALE_STRING 基于当前区域来对对象进行字符串比较。PHP 4.4.0 和 5.0.2 新加。
+
+COUNT_NORMAL (integer)
+
+COUNT_RECURSIVE (integer)
+
+EXTR_OVERWRITE (integer)
+
+EXTR_SKIP (integer)
+
+EXTR_PREFIX_SAME (integer)
+
+EXTR_PREFIX_ALL (integer)
+
+EXTR_PREFIX_INVALID (integer)
+
+EXTR_PREFIX_IF_EXISTS (integer)
+
+EXTR_IF_EXISTS (integer)
+
+EXTR_REFS (integer)
+
+## 对数组进行排序
+
+PHP 有一些用来排序数组的函数
+
+主要区别有:
+
+- 有些函数基于 array 的键来排序, 而其他的基于值来排序的:$array['key'] = 'value';。
+- 排序之后键和值之间的关联关系是否能够保持, 是指排序之后数组的键可能 会被重置为数字型的(0,1,2 ...)。
+- 排序的顺序有:字母表顺序, 由低到高(升序), 由高到低(降序),数字排序,自然排序,随机顺序或者用户自定义排序。
+- 注意:下列的所有排序函数都是直接作用于数组本身, 而不是返回一个新的有序的数组。
+- 以下函数对于数组中相等的元素,它们在排序后的顺序是未定义的。 (也即相等元素之间的顺序是不稳定的)。
+
+|函数名称|排序依据|数组索引健保持|排序的顺序|相关函数|
+|-|-|-|-|-|
+|array_multisort()|值|键值关联的保持,数字类型的不保持|第一个数组或者由选项指定|array_walk()|
+|asort()|值|是|由低到高|arsort()|
+|arsort()|值|是|由高到低|asort()|
+|krsort()|键|是|由高到低|ksort()|
+|ksort()|键|是|由低到高|asort()|
+|natcasesort()|值|是|自然排序,大小写不敏感|natsort()|
+|natsort()|值|是|自然排序|natcasesort()|
+|rsort()|值|否|由高到低|sort()|
+|shuffle()|值|否|随机|array_rand()|
+|sort()|值|否|由低到高|rsort()|
+|uasort()|值|是|由用户定义|uksort()|
+|uksort()|键|是|由用户定义|uasort()|
+|usort()|值|否|由用户定义|uasort()|
+
+## 数组函数
+
+array_change_key_case — 将数组中的所有键名修改为全大写或小写
+
+array_chunk — 将一个数组分割成多个
+
+array_column — 返回数组中指定的一列
+
+array_combine — 创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值
+
+array_count_values — 统计数组中所有的值
+
+array_diff_assoc — 带索引检查计算数组的差集
+
+array_diff_key — 使用键名比较计算数组的差集
+
+array_diff_uassoc — 用用户提供的回调函数做索引检查来计算数组的差集
+
+array_diff_ukey — 用回调函数对键名比较计算数组的差集
+
+array_diff — 计算数组的差集
+
+array_fill_keys — 使用指定的键和值填充数组
+
+array_fill — 用给定的值填充数组
+
+array_filter — 用回调函数过滤数组中的单元
+
+array_flip — 交换数组中的键和值
+
+array_intersect_assoc — 带索引检查计算数组的交集
+
+array_intersect_key — 使用键名比较计算数组的交集
+
+array_intersect_uassoc — 带索引检查计算数组的交集,用回调函数比较索引
+
+array_intersect_ukey — 用回调函数比较键名来计算数组的交集
+
+array_intersect — 计算数组的交集
+
+array_key_exists — 检查数组里是否有指定的键名或索引
+
+array_key_first — Gets the first key of an array
+
+array_key_last — Gets the last key of an array
+
+array_keys — 返回数组中部分的或所有的键名
+
+array_map — 为数组的每个元素应用回调函数
+
+array_merge_recursive — 递归地合并一个或多个数组
+
+array_merge — 合并一个或多个数组
+
+array_multisort — 对多个数组或多维数组进行排序
+
+array_pad — 以指定长度将一个值填充进数组
+
+array_pop — 弹出数组最后一个单元(出栈)
+
+array_product — 计算数组中所有值的乘积
+
+array_push — 将一个或多个单元压入数组的末尾(入栈)
+
+array_rand — 从数组中随机取出一个或多个单元
+
+array_reduce — 用回调函数迭代地将数组简化为单一的值
+
+array_replace_recursive — 使用传递的数组递归替换第一个数组的元素
+
+array_replace — 使用传递的数组替换第一个数组的元素
+
+array_reverse — 返回单元顺序相反的数组
+
+array_search — 在数组中搜索给定的值,如果成功则返回首个相应的键名
+
+array_shift — 将数组开头的单元移出数组
+
+array_slice — 从数组中取出一段
+
+array_splice — 去掉数组中的某一部分并用其它值取代
+
+array_sum — 对数组中所有值求和
+
+array_udiff_assoc — 带索引检查计算数组的差集,用回调函数比较数据
+
+array_udiff_uassoc — 带索引检查计算数组的差集,用回调函数比较数据和索引
+
+array_udiff — 用回调函数比较数据来计算数组的差集
+
+array_uintersect_assoc — 带索引检查计算数组的交集,用回调函数比较数据
+
+array_uintersect_uassoc — 带索引检查计算数组的交集,用单独的回调函数比较数据和索引
+
+array_uintersect — 计算数组的交集,用回调函数比较数据
+
+array_unique — 移除数组中重复的值
+
+array_unshift — 在数组开头插入一个或多个单元
+
+array_values — 返回数组中所有的值
+
+array_walk_recursive — 对数组中的每个成员递归地应用用户函数
+
+array_walk — 使用用户自定义函数对数组中的每个元素做回调处理
+
+array — 新建一个数组
+
+arsort — 对数组进行逆向排序并保持索引关系
+
+asort — 对数组进行排序并保持索引关系
+
+compact — 建立一个数组,包括变量名和它们的值
+
+count — 计算数组中的单元数目,或对象中的属性个数
+
+current — 返回数组中的当前单元
+
+each — 返回数组中当前的键/值对并将数组指针向前移动一步
+
+end — 将数组的内部指针指向最后一个单元
+
+extract — 从数组中将变量导入到当前的符号表
+
+in_array — 检查数组中是否存在某个值
+
+key_exists — 别名 array_key_exists
+
+key — 从关联数组中取得键名
+
+krsort — 对数组按照键名逆向排序
+
+ksort — 对数组按照键名排序
+
+list — 把数组中的值赋给一组变量
+
+natcasesort — 用“自然排序”算法对数组进行不区分大小写字母的排序
+
+natsort — 用“自然排序”算法对数组排序
+
+next — 将数组中的内部指针向前移动一位
+
+pos — current 的别名
+
+prev — 将数组的内部指针倒回一位
+
+range — 根据范围创建数组,包含指定的元素
+
+reset — 将数组的内部指针指向第一个单元
+
+rsort — 对数组逆向排序
+
+shuffle — 打乱数组
+
+sizeof — count 的别名
+
+sort — 对数组排序
+
+uasort — 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联
+
+uksort — 使用用户自定义的比较函数对数组中的键名进行排序
+
+usort — 使用用户自定义的比较函数对数组中的值进行排序
From 89e6db8acea17f270328f1767b81e1759abbb518 Mon Sep 17 00:00:00 2001
From: ColinLiu
Date: Fri, 17 Apr 2020 21:59:32 +0800
Subject: [PATCH 15/72] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=86=85=E5=AE=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...23\347\263\273\347\273\223\346\236\204.md" | 125 ++++++
...346\212\245\345\215\217\350\256\256UDP.md" | 49 +++
...345\210\266\345\215\217\350\256\256TCP.md" | 381 ++++++++++++++++++
...30\345\214\205\346\213\206\345\214\205.md" | 50 +++
...TP\347\212\266\346\200\201\347\240\201.md" | 168 ++++++++
...71\346\263\225\350\257\246\350\247\243.md" | 95 +++++
...06\350\212\202\344\273\213\347\273\215.md" | 93 +++++
...66\347\232\204\346\246\202\350\277\260.md" | 142 +++++++
.../assets/network-architecture-01.png" | Bin 0 -> 55697 bytes
.../assets/network-architecture-02.png" | Bin 0 -> 93933 bytes
.../assets/network-architecture-03.png" | Bin 0 -> 115331 bytes
.../assets/network-architecture-04.png" | Bin 0 -> 43934 bytes
.../assets/network-architecture-05.png" | Bin 0 -> 115331 bytes
.../assets/network-architecture-06.png" | Bin 0 -> 20397 bytes
.../assets/network-architecture-07.png" | Bin 0 -> 46260 bytes
.../assets/network-http-message.png" | Bin 0 -> 33544 bytes
.../assets/network-http-method-01.png" | Bin 0 -> 34364 bytes
.../assets/network-http-method-02.png" | Bin 0 -> 35726 bytes
.../assets/network-http-method-03.png" | Bin 0 -> 53478 bytes
.../assets/network-http-method-04.png" | Bin 0 -> 83233 bytes
.../assets/network-http-method-05.png" | Bin 0 -> 71933 bytes
.../assets/network-http-method-06.png" | Bin 0 -> 47376 bytes
.../assets/network-http-method-07.png" | Bin 0 -> 49791 bytes
.../assets/network-http-method-08.png" | Bin 0 -> 45153 bytes
.../assets/network-http-method.png" | Bin 0 -> 67932 bytes
.../assets/network-https-01.png" | Bin 0 -> 35909 bytes
.../assets/network-https-02.png" | Bin 0 -> 51890 bytes
.../assets/network-https-03.png" | Bin 0 -> 144450 bytes
.../assets/network-https-04.png" | Bin 0 -> 110028 bytes
.../assets/network-https-05.png" | Bin 0 -> 67898 bytes
.../assets/network-https.png" | Bin 0 -> 350335 bytes
.../assets/network-tcp-01.png" | Bin 0 -> 90316 bytes
.../assets/network-tcp-02.png" | Bin 0 -> 57821 bytes
.../assets/network-tcp-03.png" | Bin 0 -> 80710 bytes
.../assets/network-tcp-04.png" | Bin 0 -> 36868 bytes
.../assets/network-tcp-05.png" | Bin 0 -> 60735 bytes
.../assets/network-tcp-06.png" | Bin 0 -> 48112 bytes
.../assets/network-tcp-07.png" | Bin 0 -> 113112 bytes
.../assets/network-tcp-08.png" | Bin 0 -> 73106 bytes
.../assets/network-tcp-09.png" | Bin 0 -> 116446 bytes
.../assets/network-tcp-10.png" | Bin 0 -> 120999 bytes
.../assets/network-tcp-11.png" | Bin 0 -> 63391 bytes
.../assets/network-tcp-12.png" | Bin 0 -> 83027 bytes
.../assets/network-tcp-13.png" | Bin 0 -> 106305 bytes
.../assets/network-tcp-14.png" | Bin 0 -> 38455 bytes
.../assets/network-tcp-15.png" | Bin 0 -> 63168 bytes
.../assets/network-tcp-16.png" | Bin 0 -> 57084 bytes
.../assets/network-tcp-17.png" | Bin 0 -> 98107 bytes
.../assets/network-tcp-18.png" | Bin 0 -> 128569 bytes
.../assets/network-tcp-19.png" | Bin 0 -> 207892 bytes
.../assets/network-udp-01.png" | Bin 0 -> 55976 bytes
.../assets/network-udp-02.png" | Bin 0 -> 79353 bytes
.../assets/network-udp-03.png" | Bin 0 -> 23070 bytes
.../assets/network-websocket.png" | Bin 0 -> 208222 bytes
...27\346\263\225\346\246\202\350\277\260.md" | 132 ++++++
...36\347\216\260\345\237\272\347\241\200.md" | 170 ++++++++
...77\346\200\247\347\273\223\346\236\204.md" | 156 +++++++
.../04.\346\240\221.md" | 49 +++
...43\345\210\227\346\237\245\346\211\276.md" | 0
.../06.\345\233\276.md" | 0
.../07.\346\216\222\345\272\217.md" | 0
...27\346\263\225\350\241\245\345\205\205.md" | 0
...70\347\256\227\346\263\225\351\242\230.md" | 3 +
.../assets/DSA-double-link.png" | Bin 0 -> 29072 bytes
.../assets/DSA-double-link2.png" | Bin 0 -> 38549 bytes
.../assets/DSA-single-link.png" | Bin 0 -> 22924 bytes
.../assets/DSA-stack.png" | Bin 0 -> 4249 bytes
...6\350\241\250\350\241\250\347\244\272.png" | Bin 0 -> 14496 bytes
...0\345\202\250\347\244\272\346\204\217.png" | Bin 0 -> 19340 bytes
...46\215\256\347\273\223\346\236\204.sketch" | Bin 0 -> 40993 bytes
70 files changed, 1613 insertions(+)
create mode 100755 "docs/01.\347\275\221\347\273\234/01.\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204.md"
create mode 100755 "docs/01.\347\275\221\347\273\234/02.\347\224\250\346\210\267\346\225\260\346\215\256\346\212\245\345\215\217\350\256\256UDP.md"
create mode 100755 "docs/01.\347\275\221\347\273\234/03.\344\274\240\350\276\223\346\216\247\345\210\266\345\215\217\350\256\256TCP.md"
create mode 100755 "docs/01.\347\275\221\347\273\234/04.TCP\347\262\230\345\214\205\346\213\206\345\214\205.md"
create mode 100755 "docs/01.\347\275\221\347\273\234/05.HTTP\347\212\266\346\200\201\347\240\201.md"
create mode 100755 "docs/01.\347\275\221\347\273\234/06.HTTP\346\226\271\346\263\225\350\257\246\350\247\243.md"
create mode 100755 "docs/01.\347\275\221\347\273\234/07.HTTPS\347\273\206\350\212\202\344\273\213\347\273\215.md"
create mode 100755 "docs/01.\347\275\221\347\273\234/08.SSL-TLS\345\215\217\350\256\256\350\277\220\350\241\214\346\234\272\345\210\266\347\232\204\346\246\202\350\277\260.md"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-architecture-01.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-architecture-02.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-architecture-03.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-architecture-04.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-architecture-05.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-architecture-06.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-architecture-07.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-http-message.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-http-method-01.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-http-method-02.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-http-method-03.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-http-method-04.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-http-method-05.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-http-method-06.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-http-method-07.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-http-method-08.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-http-method.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-https-01.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-https-02.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-https-03.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-https-04.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-https-05.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-https.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-01.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-02.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-03.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-04.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-05.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-06.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-07.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-08.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-09.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-10.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-11.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-12.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-13.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-14.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-15.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-16.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-17.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-18.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-tcp-19.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-udp-01.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-udp-02.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-udp-03.png"
create mode 100755 "docs/01.\347\275\221\347\273\234/assets/network-websocket.png"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/01.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225\346\246\202\350\277\260.md"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/02.\346\225\260\346\215\256\347\273\223\346\236\204\345\256\236\347\216\260\345\237\272\347\241\200.md"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/03.\347\272\277\346\200\247\347\273\223\346\236\204.md"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/04.\346\240\221.md"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/05.\346\225\243\345\210\227\346\237\245\346\211\276.md"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/06.\345\233\276.md"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/07.\346\216\222\345\272\217.md"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/08.\347\256\227\346\263\225\350\241\245\345\205\205.md"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/09.\347\273\217\345\205\270\347\256\227\346\263\225\351\242\230.md"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/assets/DSA-double-link.png"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/assets/DSA-double-link2.png"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/assets/DSA-single-link.png"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/assets/DSA-stack.png"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/assets/DSA-\347\272\277\346\200\247\350\241\250\347\232\204\351\223\276\350\241\250\350\241\250\347\244\272.png"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/assets/DSA-\347\272\277\346\200\247\350\241\250\347\232\204\351\241\272\345\272\217\345\255\230\345\202\250\347\244\272\346\204\217.png"
create mode 100644 "docs/02.\346\225\260\346\215\256\347\273\223\346\236\204\344\270\216\347\256\227\346\263\225/assets/\346\225\260\346\215\256\347\273\223\346\236\204.sketch"
diff --git "a/docs/01.\347\275\221\347\273\234/01.\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204.md" "b/docs/01.\347\275\221\347\273\234/01.\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204.md"
new file mode 100755
index 0000000..1f18b11
--- /dev/null
+++ "b/docs/01.\347\275\221\347\273\234/01.\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204.md"
@@ -0,0 +1,125 @@
+# 计算机网络体系结构
+
+在计算机网络的基本概念中,分层次的体系结构是最基本的
+
+## 计算机网络体系结构的形成
+
+### 分层
+
+相互通信的两个计算机系统必须高度协调工作才行,而这种“协调”是相当复杂的。为了设计这样复杂的计算机网络,最初提出了分层的方法。“`分层`”可将庞大而复杂的问题,转化为若干较小的局部问题,而这些较小的局部问题比较易于研究和处理
+
+### 国际标准
+
+全球经济的发展使得不同网络体系结构的用户迫切要求能够互相交换信息,国际标准化组织 ISO 提出了 OSI。只要遵循 OSI 标准,一个系统就可以和位于世界上任何地方的、也遵循这同一标准的其他任何系统进行通信
+
+现今规则最大的、覆盖全球的、基于 TCP/IP 的互联网并未使用 OSI 标准。在20世纪90年代初期,虽然整套的 OSI 国际标准已制定出来,但基于 TCP/IP 的互联网已抢先在全球相当大的范围成功地运行了,而同时却几乎找不到有厂家生产出符合 OSI 标准的商业产品。OSI 只获得了一些理论研究的成果,市场化方面则彻底失败了
+
+TCP/IP 常被称为是`事实上的国际标准`
+
+## 协议与划分层次
+
+### 网络协议
+
+在计算机网络中要做到有条不紊地交换数据,就必须准守一些事先约定好的规则。这些规则明确了所交换的数据的格式以及有关的同步问题
+
+为进行网络中的数据交换而建立的规则、标准或约定称为`网络协议`。网络协议也可简称为`协议`
+
+**协议组成要素**
+
+- `语法`,即数据与控制信息的结构或格式
+- `语义`,即需要发出何种控制信息,完成何种动作以及做出何种响应
+- `同步`,即事件实现顺序的详细说明
+
+协议通常有两种不同的形式。一种是使用便于人来阅读和理解的文字描述。另一种是使用让计算机能够理解的程序代码。这两种不同形式的协议都必须能够对网络上的信息交换过程做出精确的解释
+
+### 划分层次
+
+对于非常复杂的计算机网络协议,其结构应该是层次式的
+
+
+
+**分层可以带来很多好处**
+
+- `各层之间是独立的`。某一层并不需要知道它的下一层是如何实现的,而仅仅需要知道该层通过层间接口(即界面)所提供的服务
+- `灵活性好`。当任何一层发送变化时(例如由于技术的变化),只要层间接口关系保持不变,则在这层以上或以下各层均不受影响
+- `结构上可分割开`。各层都可以采用最合适的技术来实现
+- `易于实现和维护`。这种结构使得实现和调试一个庞大而又复杂的系统变得易于处理,因为整个的系统已被分解为若干个相对独立的子系统
+- `能促进标准化工作`。因为每一层的功能及其所提供的服务都已有了精确的说明
+
+**各层所要完成的功能**
+
+- `差错控制` 使相应层次对等方的通信更加可靠
+- `流量控制` 发送端的发送速率必须使接收端来得及接收,不要太快
+- `分段和重装` 发送端将要发送的数据块划分为更小的单位,在接收端将其还原
+- `复用和分用` 发送端几个高层会话复用一条逻辑连接,数据传送结束后释放连接
+- `连接建立和释放` 交换数据前先建立一条逻辑连接,数据传送结束后释放连接
+
+**分层缺点**
+
+有些功能会在不同的层次中重复出现,因而产生了额外开销
+
+**体系结构**
+
+计算机网络的各层及其协议的集合就是网络的`体系结构`。计算机网络的体系结构就是这个计算机网络及其构件所应完成的功能的精确定义
+
+体系结构是抽象的,而实现则是具体的,是真正在运行的计算机硬件和软件
+
+## 具有五层协议的体系结构
+
+### 五层协议
+
+OSI 的七层协议体系结构的概念清楚,理论也较完整,但它既复杂又不实用。TCP/IP 体系结构则不同,但它现在却得到了非常广泛的应用。TCP/IP 是一个四层的体系结构。在学习计算机网络的原理时往往采用折中的办法,即综合 OSI 和 TCP/IP 的优点,采用一种只有五层协议的体系结构,这样既简洁又能将概念阐述清楚
+
+
+
+### 各层作用
+
+- 应用层:应用层协议定义的是应用进程间通信和交互的规则
+- 运输层:运输层的任务就是负责向`两台主机中进程之间的通信`提供`通用的数据传输`服务
+- 网络层:把运输层产生的报文段或用户数据报封装成`分组`或`包`进行传送
+- 数据链路层:将网络层交下来的 IP 数据报组装成帧,并在两个相邻结点间的链路上传送
+- 物理层:利用物理媒体以`比特`形式传送数据
+
+### 小结
+
+- 把应用层交互的数据单元称为`报文`
+- 运输层主要协议:传输控制协议 TCP、用户数据报协议 UDP
+- 在 TCP/IP 体系中,由于网络层使用 IP 协议,因此分组也叫 `IP 数据报`,或简称为数据报
+
+
+
+## 实体、协议、服务和服务访问点
+
+当研究开放系统中的信息交换时,往往使用`实体`(entity)这一较为抽象的名词表示`任何可发送或接受信息的硬件或软件进程`
+
+协议是控制两个对等实体(或多个实体)进行通信的规则的集合
+
+在协议的控制下,两个对等实体间的通信使得本层能够向上一层提供服务。要实现本层协议,还需要使用下面一层所提供的服务
+
+协议是“水平的”,即协议是控制对等实体之间通信的规则。但服务是“垂直的”,即服务是由下层向上层通过层间接口提供的
+
+
+
+### 计算机网络协议特点
+
+协议必须把所有不利的条件事先都估计到,而不能假定一切都是正常的和非常理想的
+
+非常仔细地检查这个协议能否应付各种异常情况
+
+## TCP/IP 的体系结构
+
+TCP/IP 的体系结构比较简单,只有四层
+
+
+
+应当指出,技术的发展并不是遵循严格的 OSI 分层概念。实际上现在的互联网使用的 TCP/IP 体系结构有时已经演变成为下图所示的那样,即某些应用程序可以直接使用 IP 层,或甚至直接使用最下面的网络接口层
+
+
+
+还有一种方法,就是分层次画出具体的协议表示 TCP/IP 协议族,它的特点是上下两头大而中间小:应用层和网络接口层都有多种协议,而中间的 IP 层很小,上层的各种协议都向下汇聚到一个 IP 协议中
+
+TCP/IP 协议可以为各式各样的应用提供服务,同时 TCP/IP 协议也允许 IP 协议在各式各样的网络构成的互联网上运行。IP 协议在互联网中充当着核心的作用
+
+
+
+**《计算机网络体系结构》 原文链接:[https://blog.maplemark.cn/2019/04/计算机网络体系结构.html](https://blog.maplemark.cn/2019/04/计算机网络体系结构.html)**
\ No newline at end of file
diff --git "a/docs/01.\347\275\221\347\273\234/02.\347\224\250\346\210\267\346\225\260\346\215\256\346\212\245\345\215\217\350\256\256UDP.md" "b/docs/01.\347\275\221\347\273\234/02.\347\224\250\346\210\267\346\225\260\346\215\256\346\212\245\345\215\217\350\256\256UDP.md"
new file mode 100755
index 0000000..77d8e6f
--- /dev/null
+++ "b/docs/01.\347\275\221\347\273\234/02.\347\224\250\346\210\267\346\225\260\346\215\256\346\212\245\345\215\217\350\256\256UDP.md"
@@ -0,0 +1,49 @@
+# 用户数据报协议 UDP
+
+## UDP 概述
+
+用户数据报协议 UDP 只在 IP 的数据报服务之上增加了很少一点的功能,这就是复用和分用的功能以及查错检测的功能
+
+### UDP 的主要特点
+
+1. UDP 是`无连接的`,即发送数据之前不需要建立连接(发送数据结束时也没有连接可释放),减少了开销和发送数据之前的时延
+2. UDP 使用`尽最大努力交付`,即不保证可靠交付,主机不需要维持复杂的连接状态表
+3. UDP 是`面向报文`的,发送方的 UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP 层。UDP 对应用层交下来的报文,既不合并,也不拆分,而是`保留这些报文的边界`
+
+
+
+4. UDP `没有拥塞控制`,网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的
+5. UDP 支持一对一、一对多、多对一和多对多的交互通信
+6. UDP 的`首部开销小`,只有8个字节,比 TCP 的20个字节的首部要短
+
+### 存在问题
+
+1. 某些实时应用需要使用没有拥塞控制的 UDP,但很多的源主机同时都向网络发送高速率的实时视频流时,网络就有可能发生拥塞,导致大家都无法正常接收。
+2. 还有一些使用 UDP 的实时应用,需要对 UDP 的不可靠传输进行适当的改进,以减少数据的丢失。应用进程可以在不影响应用的实时性的前提下,增加一些提高可靠性的措施,如采用前向纠错或重传已丢失的报文
+
+## UDP 的首部格式
+
+用户数据报 UDP 有两个字段:`数据字段`和`首部字段`。首部字段很简单,只有8个字节,由四个字段组成,每个字段都是两个字节
+
+### 首部字段
+
+- `源端口` 源端口号。在需要对方回信时。不需要时可用全0
+- `目的端口` 目的端口号。这在终点交付报文时必须使用
+- `长度` UDP 用户数据报的长度,其最小值是8(仅有首部)
+- `检验和` 检测 UDP 用户数据报在传输中是否有错。有错就丢弃
+
+
+
+### 端口分用
+
+当运输层从 IP 层收到 UDP 数据报时,就根据首部中的目的端口,把 UDP 数据报通过相应的端口,上交最后的终点——应用进程
+
+
+
+如果接受方 UDP 发现收到的报文中的目的端口号不正确(即不存在对应于该端口号的应用程序),就丢弃该报文,并由网际控制报文协议 ICMP 发送“端口不可达”差错报文给发送方
+
+### 伪首部
+
+UDP 用户数据报首部中检验和的计算方法有些特殊。在计算检验和时,要在 UDP 用户数据报之前增加 12 个字节的`伪首部`。所谓“伪首部”是因为这种伪首部并不是 UDP 用户数据报真正的首部。只是在计算检验和时,临时添加在 UDP 用户数据报前面,得到一个临时的 UDP 用户数据报。检验和就是按照这个临时用户数据报来计算的。伪首部既不向下传也不向上递交,而仅仅是为了计算检验和
+
+**《用户数据报协议UDP》 原文链接:[https://blog.maplemark.cn/2019/04/用户数据报协议udp.html](https://blog.maplemark.cn/2019/04/用户数据报协议udp.html)**
\ No newline at end of file
diff --git "a/docs/01.\347\275\221\347\273\234/03.\344\274\240\350\276\223\346\216\247\345\210\266\345\215\217\350\256\256TCP.md" "b/docs/01.\347\275\221\347\273\234/03.\344\274\240\350\276\223\346\216\247\345\210\266\345\215\217\350\256\256TCP.md"
new file mode 100755
index 0000000..8d828c9
--- /dev/null
+++ "b/docs/01.\347\275\221\347\273\234/03.\344\274\240\350\276\223\346\216\247\345\210\266\345\215\217\350\256\256TCP.md"
@@ -0,0 +1,381 @@
+# 传输控制协议 TCP
+
+## 传输控制协议 TCP 概述
+
+### TCP 最主要的特点
+
+- TCP 是`面向连接的运输层协议`。应用程序在使用 TCP 协议之前,必须先建立 TCP 连接。在传送数据完毕后,必须释放已经建立的 TCP 连接
+- 每一条 TCP 连接只能有两个`端点`,每一条 TCP 连接只能是`点对点`的(一对一)
+- TCP 提供`可靠交付`的服务。通过 TCP 连接传送的数据,无差错、不丢失、不重复,并且按序到达
+- TCP 提供`全双工通信`。TCP 允许通信双方的应用进程在任何时候都能发送数据。TCP 连接的两端都设有发送缓存和接受缓存,用来临时存放双向通信的数据
+- `面向字节流`。TCP 中的“流”指的是`流入到进程或从进程流出的字节序列`
+
+### 面向字节流
+
+“面向字节流”的含义是:虽然应用程序和 TCP 的交互式一次一个数据块(大小不等),但 TCP 把应用程序交下来的数据仅仅看成是一连串的`无结构的字节流`。TCP 并不知道所传送的字节流的含义
+
+TCP 不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系
+
+> 例如,发送方应用程序交给发送方的 TCP 共10个数据块,但接收方的 TCP 可能只用了4个数据块就把收到的字节流交付上层的应用程序
+
+接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。接收方的应用程序必须有能力识别收到的字节流,把它还原成有意义的应用层数据
+
+
+
+TCP 和 UDP 在发送报文时采用的方式完全不同。TCP 并不关心应用进程一次把多长的报文发送到 TCP 的缓存中,而是根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP 发送的报文长度是应用进程给出的)。如果应用进程传送到 TCP 缓存的数据块太长,TCP 就可以把它划分短一些再传送。如果应用进程一次只发来一个字节,TCP 也可以等待积累有足够多的字节后再构成报文段发送出去
+
+### TCP 的连接
+
+TCP 把`连接`作为`最基本的抽象`。TCP 的许多特性都与 TCP 是面向连接的这个基本特性有关
+
+TCP 连接的端点叫做`套接字(socket)或插口`,根据 RFC 793 的定义:端口号拼接到(concatenated with) IP 地址即构成了套接字
+
+> 套接字 socket = (IP 地址:端口号)
+
+`每一条 TCP 连接唯一地被通信两端的两个端点(即两个套接字)所确定`
+
+> TCP 连接 ::= {socket1, socket2} = {(IP1: port1), (IP2: port2)}
+
+TCP 连接就是由协议软件所提供的一种抽象。`TCP 连接的端口是个很抽象的套接字`,即( `IP地址`: `端口号`)。同一个 IP 地址可以有多个不同的 TCP 连接,而同一个端口号也可以出现在多个不同的 TCP 连接中
+
+### 易混淆的 socket
+
+同一个名词 socket 却可表示多种不同的意思,以下 socket 的意思跟本文中所引用的 RFC 793 定义的 socket(指端口号拼接到 IP 地址)不同
+
+- 允许应用程序访问连网协议的`应用编程接口 API(Application Programming Interface)`,即运输层和应用层之间的接口,称为 socket API,并简称为 socket
+- 在 socket API 中使用的一个`函数名`也叫做 socket
+- 调用 socket 函数的`端点`称为 socket,如“创建一个数据报 socket”
+- 调用 socket 函数时,其`返回值`称为 socket 描述符,可简称为 socket
+- 在操作系统内核中连网协议的 Berkeley 实现,称为 socket `实现`
+
+## 可靠传输的工作原理
+
+### 理想的传输条件
+
+理想的传输条件有以下两个特点
+
+- 传输信道不产生差错
+- 不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据
+
+实际的网络不具备以上两个理想条件。需要使用一些可靠的传输协议,当出现差错时让发送方重传出现差错的数据,同时在接收方来不及处理收到的数据时,及时告诉发送方适当减低发送数据的速度。这样,不可靠的传输信道就能够实现可靠传输了
+
+### 停止等待协议
+
+全双工通信的双方既是发送方也是接收方。把传送的数据单元都称为分组。“停止等待”就是每发完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组
+
+#### 无差错情况
+
+
+
+#### 出现差错
+
+只要超过一段时间没有收到确认,就认为刚才发送的分组丢失了,因而重传前面发送过的分组。这就叫做`超时重传`。要实现超时重传,就要在每发送完一个分组时设置一个`超时计时器`
+
+- 发送完一个分组后,`必须暂时保留已发送的分组的副本`(在发生超时重传时使用)。只有在收到相应的确认后才能清除暂时保留的分组副本
+- 分组和确认分组都必须进行`编号`。这样才能明确是哪一个发送出去的分组收到了确认,而哪一个分组还没有收到确认
+- 超时计时器的重传时间`应当比数据在分组传输的平均往返时间更长一些`
+
+#### 确认丢失和确认迟到
+
+
+
+使用上述的确认和重传机制,我们就可以`在不可靠的传输网络上实现可靠的通信`
+
+像上述的这种可靠传输协议常称为`自动重传请求 ARQ(Automatic Repeat reQuest)`。重传的请求是自动进行的。接收方不需要请求发送方重传某个出错的分组
+
+#### 信道利用率
+
+停止等待协议的优点是简单,但缺点是信道利用率太低
+
+
+
+为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用`流水线传输`。流水线传输就是发送方可连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认。这样可使信道上一直有数据不间断地在传送。这种传输方式可以获得很高的信道利用率
+
+
+
+### 连续 ARQ 协议
+
+位于发送窗口内的5个分组都可以连续发送出去,而不需要等待对方的确认。可以提高信道利用率
+
+
+
+接收方一般都是采用`累积确认`的方式。接收方不需要对收到的分组逐个发送确认,而是在收到几个分组后,`对按序到达的最后一个分组发送确认`
+
+积累确认有优点也有缺点。优点是:容易实现,即使确认丢失也不必重传。缺点是不能向发送方反映出接收方已经正确收到的所有分组的信息
+
+## TCP 报文段的首部格式
+
+TCP 虽然是面向字节流的,但 TCP 传送的数据单元却是报文段。一个 TCP 报文段分为首部和数据两部分。TCP 报文段首部的前20个字节是固定的,后面有4n字节是根据需要而增加的选项(n是整数)。因此 TCP 首部的最小长度是20字节
+
+
+
+### 首部字段
+
+- `源端口`和`目的端口` 各占2个字节,分别写入源端口号和目的端口号
+- `序号` 占4字节。序号范围是[0, 232-1],共232(即4 294 967 296)个序号。序号增加到232-1后,下一个序号就又回到0。在一个 TCP 连接中传送的字节流中的`每一个字节都按顺序编号`
+- `确认号` 占4字节,是`期望收到对方下一个报文段的第一个数据字节的序号`
+- `数据偏移` 占4字节,它指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。这个字段实际上是指出 TCP 报文段的首部长度
+- `保留` 占6位,保留为今后使用,但目前应置为0
+
+下面有6个`控制位`,用来说明本报文段的性质
+
+- `紧急 URG(URGent)` 当 URG=1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据),而不是按原先的排队顺序来传送
+- `确认 ACK(ACKnowledgment)` 仅当 ACK=1 时确认号字段才有效。当 ACK=0 时,确认号无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置1
+- `推送 PSH(Push)` 当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应
+- `复位 RST(ReSeT)` 当 RST=1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接
+- `同步 SYN(SYNnchronization)` 在连接建立时用来同步序号。当 SYN=1 而 ACK=0 时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使 SYN=1 和 ACK=1
+- `终止 FIN(FINis)` 用来释放一个连接。当 FIN=1 时,表明此报文段的发送发的数据已发送完毕,并要求释放运输连接
+
+- `窗口` 占2字节。窗口值是[0, 216-1]之间的整数。窗口值作为接收方让发送方设置其发送窗口的依旧
+- `检验和` 占2字节。检验和字段检验的范围包括首部和数据这两部分
+- `紧急指针` 占2字节。紧急指针仅在 URG=1 时才有意义,它指出本报文段中的紧急数据的字节数
+- `选项` 长度可变,最长可达40字节
+
+## TCP 可靠传输的实现
+
+### 以字节为单位的滑动窗口
+
+#### 发送窗口构造
+
+TCP 的滑动窗口是以字节为单位的。假定 A 收到了 B `发来`的确认报文段,其中窗口是20字节,而确认号是31(这表明 B 期望收到的下一个序号是31,而序号30为止的数据已经收到了)。根据这两个数据,A 就构造出自己的发送窗口
+
+
+
+发送窗口标识:在没有收到 B 的确认的情况下,A 可以连续把窗口内的数据都发送出去。凡是已经发送出去的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用
+
+#### 发送窗口变化
+
+发送窗口的位置由窗口前沿和后沿的位置共同确定。发送窗口后沿的变化情况有两种,即不动(没有收到新的确认)和前移(收到了新的确认)。发送窗口后沿不可能向后移动,因为不能撤销已收到的确认
+
+发送窗口前沿通常是不断向前移动,但也有可能不动。这对应于两种情况:
+
+- 一是没有收到新的确认,对应通知的窗口大小也不变
+- 二是收到了新的窗口单对方通知的窗口缩小了,使得发送窗口前沿正好不动
+
+发送窗口前沿也有可能`向后收缩`。这发生在对方通知的窗口缩小了。但 TCP 的标准`强烈不赞成这样做`。因为很可能发送方在收到这个通知以前已经发送了窗口中的许多数据,现在又要收缩窗口,不让发送这些数据,这样就会产生一些错误
+
+
+
+要描述一个发送窗口的状态需要三个指针:P1,P2,P3。指针都指向字节的序号。这三个指针指向的几个部分的意义如下:
+
+- 小于 P1 的是已发送并已收到确认的部分,而大于 P3 的是不允许发送的部分
+- P3 - P1 = `A 的发送窗口`
+- P2 - P1 已发送但尚未收到确认的字节数
+- P3 - P2 允许发送但当前尚未发送的字节数(又称为`可用窗口`或`有效窗口`)
+
+B 的接收窗口大小是20。在接收窗口外面,到30号为止的数据是已经发送过确认,并且已经交付主机了。因此在 B 可以不再保留这些数据。接收窗口内的序号(31\~50)是允许接收的。在上图中,B 收到了序号为32和33的数据。这些数据没有按序到达,因为序号为31的数据没有收到(也许丢失了,也许滞留在网络中的某处)。请注意,B 只能对按序收到的数据中的最高序号给出确认,因此 B 发送的确认报文段中的确认号仍然是31(即期望收到的序号),而不是32或33
+
+现在假定 B 收到了序号为31的数据,并把序号为31\~33的数据交付主机,然后 B 删除这些数据。接着把接收窗口向前移动3个序号,同时给 A 发送确认,其中窗口值仍为20,但确认号是34。这表明 B 已经收到了到序号33为止的数据。B 还收到了序号为37,38和40的数据,但这些都没有按序到达,只能先暂存在接收窗口中。A 收到 B 的确认后,就可以把发送窗口向前滑动3个序号,但指针 P2 不动。现在 A 的可用窗口增大了,可发送的序号范围是42\~53
+
+
+
+A 在继续发送完序号42\~53的数据后,指针 P2 向前移动和 P3 重合。发送窗口内的序号都已用完,但还没有再收到确认。由于 A 的发送窗口已满,可用窗口已减小到零,因此必须停止发送。发送窗口内所有的数据都已正确到达 B,B 也早已发出了确认。但所有这些确认都滞留在网络中。在没有收到 B 的确认时,A 不能猜测:”或许 B 收到了吧!“为了保证可靠传输,A 只能认为 B 还没有收到这些数据。于是,A 在经过一段时间后(由超时计时器控制)就重传这部分数据,重新设置超时计时器,直到收到 B 的确认为止。如果 A 收到确认号落在发送窗口内,那么 A 就可以发送窗口继续向前滑动,并发送新的数据
+
+
+
+#### 缓存和窗口
+
+发送方维持的发送缓存和发送窗口,以及接收方维持的接收缓存和接收窗口
+
+
+
+发送缓存用来暂时存放:
+
+- 发送应用程序传送给对方 TCP 准备发送的数据
+- TCP 已发送出但尚未收到确认的数据
+
+已被确认的数据应当从发送缓存中删除,因此发送缓存和发送窗口的后沿是重合的。发送应用程序必须控制写入缓存的速率,不能太快,否则发送缓存就会没有存放数据的空间
+
+接收缓存用来暂时存放:
+
+- 按序到达的、但尚未被接收应用程序读取的数据
+- 未按序到达的数据
+
+收到的分组被检测出有差错,则丢弃。接收应用程序来不及读取收到的数据,接收缓存最终就会被填满,使接收窗口减小到零。接收应用程序能够及时从接收缓存中读取收到的数据,接收窗口就可以增大,最大亦不能超过接收缓存的大小
+
+要点小结:
+
+- 虽然 A 的发送窗口是根据 B 的接收窗口设置的,但在同一时刻,A 的发送窗口并不总是和 B 的接收窗口一样大。通过网络传送窗口值需要经历一定的时间滞后,该时间并不确定的
+- 对于不按序到达的数据,TCP 通常是先临时存放在接收窗口,等字节流中所缺少的字节收到后,在`按序交付上层的应用进程`
+- TCP 要求接收方必须有累积确认的功能,这样可以减少传输开销
+
+### 超时重传时间的选择
+
+TCP 的发送方在规定的时间内没有收到确认就要重传已发送的报文段。这种重传的概念是很简单的,但重传时间的选择却是 TCP 最复杂的问题之一
+
+由于 TCP 的下层是互联网环境,发送的报文段可能只经过一个高速率的局域网,也可能经过多个低速率的网络,并且每个 IP 数据报所选择的路由还可能不同。如果把超时重传时间设置得太短,就会引起很多报文段的不必要的重传,使网络负荷增大。但若把超时重传时间设置的过长,则又使网络的空闲时间增大,降低了传输效率
+
+TCP 采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间之差就是`报文段的往返时间 RTT`
+
+> 新的 RTTs = (1 - α) x (旧的 RTTs) + α x (新的 RTT 样本)
+
+RTT:报文段往返时间
+RTTs:加权平均往返时间
+α: 0 ≤ α < 1,RFC 6298 推荐的 α 值为 1/8,即 0.125
+
+> RTO = RTTs + 4 x RTTD
+
+RTO:超时重传时间
+RTTD:RTT 的偏差的加权平均值
+
+> 新的 RTTD = (1 - β) x (旧的 RTTD) + β x |RTTs - 新的 RTT 样本|
+
+β:小于1的系数,推荐值是 1/4,即 0.25
+
+## TCP 流量控制
+
+### 利用滑动窗口实现流量控制
+
+流量控制(flow control):让发送方的发送速率不要太快,要让接收方来得及接收
+
+利用滑动窗口机制可以很方便地在 TCP 连接上实现对发送方的流量控制
+
+
+
+`发送方的发送窗口不能超过接收方给出的接收窗口的数值`。TCP 的`窗口单位是字节,不是报文段`
+
+避免死锁:TCP 为每一个连接设有一个`持续计时器(persistence timer)`。只要 TCP 连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个零窗口`探测报文段`(仅携带1字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值。如果窗口仍是零,那么收到这个报文段的一方就重新设置持续计时器。如果窗口不是零,那么死锁的僵局就可以打破了
+
+### TCP 的传输效率
+
+#### 发送机制
+
+- TCP 维持一个变量,它等于`最大报文段长度 MSS`。只要缓存中存放的数据达到 MSS 字节时,就组装成一个 TCP 报文段发送出去
+- 由发送方的应用进程指明要求发送报文段,即 TCP 支持的`推送(push)`操作
+- 发送方的一个计时器期限到了,这时把当前已有的缓存数据装入报文段(但长度不能超过 MSS)发送出去
+
+#### Nagle 算法
+
+> 在 TCP 的实现中广泛使用 Nagle 算法
+
+若发送应用进程把要发送的数据逐个字节地送到 TCP 的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后才继续发送下一个报文段。当数据达到较快而网络速率较慢时,用这样的方法可明显地减少所用的网络宽带。Nagle 算法还规定,当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段。这样可以有效提高网络的吞吐量
+
+#### 糊涂窗口综合征
+
+> TCP 接收方的缓存已满,仅剩一个字节,并还将保持这种状态持续一段时间。导致发送方只能发送一个字节。导致网络的效率很低
+
+为了解决这个问题,可以`让接收方等待一段时间`,使得或者接受缓存已有足够空间容纳一个最长的报文段,或者`等到接受缓存已有一半空闲的空间`。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。发送方也不要发送大小的报文段,而是把数据积累成足够大的报文段,或达到接收方缓存的空间的一半大小
+
+## TCP 的拥塞控制
+
+### 拥塞控制的一般原理
+
+在计算机网络中的链路容量(即宽带)、交换结点中的缓存和处理机等,都是网络资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫做`拥塞`(congestion)
+
+`拥塞控制`就是`防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载`。拥塞控制所要做的都是一个前提,就是`网络能够承受现有的网络负荷`
+
+
+
+### TCP 的拥塞控制方法
+
+TCP 进行拥塞控制的算法有四种,即`慢开始`(slow-start)、`拥塞避免`(congestion avoidance)、`快重传`(fast retransmit)和`快恢复`(fast recovery)
+
+#### 慢开始
+
+当主机开始发送数据时,由于并不清楚网络的负荷情况,如果立即把大量数据字节注入到网络,就有可能引起网络发生拥塞。经验证明,较好的方法是先探测一下,即`由小到大逐渐增大发送窗口`,也就是说,`由小到大逐渐增大拥塞窗口数值`
+
+cwnd:发送方的拥塞窗口,开始发送方设置 cwnd = 1
+
+#### 拥塞避免
+
+让拥塞窗口 cwnd 缓慢地增大,即每经过一个往返时间 RTT 就把发送方的拥塞窗口 cwnd 加1,而不是像慢开始阶段那样加倍增加。因此在拥塞避免阶段就有“`加法增大`” AI(Additive Increase)的特点。这表明在拥塞避免阶段,拥塞窗口 cwnd `按线性规律缓慢增长`,比慢开始算法的拥塞窗口增长速率缓慢得多
+
+“拥塞避免”并非完全能够避免拥塞,而是把拥塞窗口控制为按线性规律增长,`使网络比较不容易出现拥塞`
+
+在执行慢开始算法时,发送方每收到一个对新报文段的确认 ACK,就把拥塞窗口值加1,然后开始下一轮的传输。因此拥塞窗口 cwnd 随着传输轮次按指数规律增长。当拥塞窗口 cwnd 增长到慢开始门限值 ssthresh 时,就改成执行拥塞避免算法,拥塞窗口按线性规律增长
+
+ssthresh:慢开始门限,一般的,会有一个初始值,下图中为16个报文段
+
+
+
+当拥塞窗口 cwnd = 24 时,网络出现了超时,发送方判断为网络拥塞。于是调整门限值 ssthresh = cwnd / 2 = 12,同时设置拥塞窗口 cwnd = 1,进入慢开始阶段
+
+#### 快重传
+
+采用快重传算法可以让发送方`尽早知道发生了个别报文段的丢失`。快重传算法首先要求接收方不要等待自己发送数据时才进行捎带确认,而是要`立即发送确认`,即使收到了`失序的报文段`也要立即发出对已收到的报文段的重复确认
+
+
+
+#### 快恢复
+
+发送方知道当前只是丢失了个别的报文段。于是不启动慢开始,而是执行`快恢复`算法。这时,发送方调整门限值 ssthresh = cwnd / 2 = 8,同时设置拥塞窗口 cwnd = ssthresh = 8,并开始执行拥塞避免算法
+
+TCP Reno 版本:区别于老的 TCP Tahao 版本
+
+## TCP 的运输连接管理
+
+TCP 是面向连接的协议。运输连接是用来传送 TCP 报文的。TCP 运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。运输连接有三个阶段,`连接建立`、`数据传送`和`连接释放`。运输的连接管理就是使运输连接的建立和释放都能够正常地进行
+
+在 TCP 连接建立过程中要解决以下三个问题:
+
+- 要使每一方能够确知对方的存在
+- 要允许双方协商一些参数(最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等)
+- 能够对运输实体资源(缓存大小、连接表中的项目等)进行分配
+
+### TCP 的连接建立
+
+TCP 建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个 TCP 报文段
+
+
+
+#### 连接建立过程
+
+1. 最初客户/服务器的 TCP 进程都处于 `CLOSED(关闭)`状态。在本实例中,A `主动打开连接`,而 B `被动打开连接`
+2. B 的 TCP 服务器进程先创建`传输控制块` TCB,并处于 `LISTEN(收听)` 状态,等待客户的连接请求
+3. A 的 TCP 客户进程创建`传输控制模块` TCB。并向 B 发出连接请求报文段,首部中的同部位 SYN = 1,选择一个初始序号 seq = x。TCP 客户端进程进入 `SYN-SENT(同步已发送)` 状态。TCP 规定,SYN 报文段(即 SYN = 1 的报文段)不能携带数据,但要`消耗一个序号`
+4. B 收到连接请求报文段后,如同意建立连接,则向 A 发送确认。在确认报文段中应把 SYN 位和 ACK 位都置1,确认号是 ack = x + 1,同时也为自己选择一个初始序号 seq = y。这时 TCP 服务器进程进入 `SYN-RCVD(同步收到)` 状态。这个报文段也不能携带数据,但同样`要消耗掉一个序号`
+5. TCP 客户进程收到 B 的确认后,还要向 B 给出确认。确认报文段的 ACK 置1,确认号 ack = y + 1,而自己的序号 seq = x + 1。TCP 的标准规定,ACK 报文段可以携带数据。但`如果不携带数据则不消耗序号`,在这种情况下,下一个数据报文段的序号仍是 seq = x + 1。这时,TCP 连接已经建立,A 进入 `ESTABLISHED(已建立连接)` 状态
+6. 当 B 收到 A 的确认后,也进入 `ESTABLISHED` 状态
+
+> `传输控制块` TCB(Transmission Control Block)存储了每一个连接中的一些重要信息,如:TCP 连接表,指向发送和接收缓存的指针,指向重传队列的指针,当前的发送和接收序号等等
+
+#### 四报文握手
+
+B 发送给 A 的报文段,可拆成两个报文段。先发送一个确认报文段(ACK = 1,ack = x + 1),然后再发送一个同步报文段(SYN = 1,seq = y)。这样的过程就变成了`四报文握手`,与三报文握手效果一致
+
+#### 异常情况
+
+为什么 A 最后还要发送一次确认呢?这主要是为了防止已失效的连接请求报文段突然又传到了 B,因而产生错误
+
+正常情况:A 发出连接请求,但因连接请求报文丢失而未收到确认。于是 A 再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接。A 共发送了两个连接请求报文段,其中第一个丢失,第二个到达了 B,没有“已失效的连接请求报文段”
+
+异常情况:A 发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了,以致延误到连接释放以后的某个时间才到达 B。本来这是一个早已失效的报文段。但 B 收到此失效的连接请求报文段后,就误认为是 A 又发出一次新的连接请求。于是就向 A 发出确认报文段,同意建立连接。假定不采用报文握手,那么只要 B 发出确认,新的连接就建立了。
+
+> 现在 A 并没有发出建立连接的请求,因此不会理睬 B 的确认,也不会向 B 发送数据。但 B 却以为新的运输连接已经建立了,并一直等待 A 发来数据。B 的`许多资源就这样被浪费了`。
+
+> 采用三报文握手的办法,可以防止上述现象的发生
+
+### TCP 的连接释放
+
+
+
+#### 连接释放过程
+
+1. A 的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接。A 把连接释放报文段首部的终止控制位 FIN 置1,其序号 seq = u,它等于前面已传送过的数据的最后一个字节的序号加1。这时 A 进入 `FIN-WAIT-1(终止等待1)` 状态,等待 B 的确认。TCP 规定,FIN 报文段即使不携带数据,也消耗一个序号
+2. B 收到连接释放报文段后即发出确认,确认号是 ack = u + 1,而这个报文段自己的序号是 v,等于 B 前面已传送过的数据的最后一个字节的序号加1。B随即进入 `CLOSE-WAIT(关闭等待)` 状态。TCP 服务器进程这时应通知高层应用进程,因而从 A 到 B 这个方向的连接就释放了,这时的 TCP 连接处于 `半关闭(half-close)` 状态,即 A 已经没有数据要发送了,但 B 若发送数据,A 仍要接收。也就是说,从 B 到 A 这个方向的连接并未关闭,这个状态可能会持续一段时间
+3. A 收到来自 B 的确认后,就进入 `FIN-WAIT-2(终止等待2)` 状态,等待 B 发出的连接释放报文段
+4. 若 B 已经没有要向 A 发送的数据,其应用进程就通知 TCP 释放连接。这时 B 发出的连接释放报文段必须使 FIN = 1。现假定 B 的序号为 w(在半关闭状态 B 可能又发送了一些数据)。B 还必须重复上次已发送过的确认号 ack = u + 1。这时 B 就进入 `LAST-ACK(最后确认)`状态,等待 A 的确认
+5. A 在收到 B 的连接释放报文段后,必须对此发出确认。在确认报文段中把 ACK 置1,确认号 ack = w + 1,而自己的序号是 seq = u + 1(根据 TCP 标准,前面发送过的 FIN 报文段要消耗一个序号)。然后进入到 `TIME-WAIT(时间等待)`状态。此时 TCP 连接还没有释放掉。必须经过`时间等待计时器(TIME-WAIT timer)`设置的时间2MSL后,A 才进入到 `CLOSED` 状态
+6. 当 A 撤销相应的传输控制块 TCB 后,就结束了这次的 TCP 连接
+
+> 时间 MSL 叫做`最长报文段寿命`(Maximum Segment Lifetime),RFC 793建议设为2分钟。但这完全是从工程上来考虑的,对于现在的网络,MSL = 2分钟可能太长了一些
+
+#### TIME-WAIT 等待时间
+
+为什么 A 在 TIME-WAIT 状态必须等待 2MSL 的时间呢?
+
+为了保证 A 发送的最后一个 ACK 报文段能够到达 B。这个 ACK 报文段有可能丢失,因而使处在 LAST-ACK 状态的 B 收不到对已发送的 FIN + ACK 报文段的确认。B 会超时 重传这个 FIN + ACK 报文段,而 A 就能在 2MSL 时间内收到这个重传的 FIN + ACK 报文段。接着 A 重传一次确认,重新启动 2MSL 计时器。最后,A 和 B 都正常进入到 CLOSED 状态。如果 A 在 TIME-WAIT 状态不等待一段时间,而是在发完 ACK 报文段后立即释放连接,那么就无法收到 B 重传的 FIN + ACK 报文段,因而也不会再发送一次确认报文段。这样,B 就无法安装正常步骤进入 CLOSED 状态
+
+防止前面提到的“已失效的连接请求报文段”出现在本连接中。A 在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段
+
+B 只要收到 A 发出的确认,就进入 CLOSED 状态。同样,B 在撤销相应的传输控制 TCB 后,就结束了这次的 TCP 连接。B 结束 TCP 连接的时间要比 A 早一些
+
+`保活计时器(keepalive timer)`:服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置通常是两小时。若两小时没有收到客户的数据,服务器就发送一个探测报文段,以后则每隔75秒发送一次。若一连发送10个探测报文段后仍无客户的响应,服务器就认为客户端出了故障,接着就关闭这个连接
+
+### TCP 的有限状态机
+
+为了更清晰地看出 TCP 连接的各种状态之间的关系,下图为 TCP 的有限状态机。图中每一个方框即 TCP 可能具有的状态。每个方框中的大写英文字符串是 TCP 标准所使用的 TCP 连接状态名。状态之间的箭头表示可能发生的状态变迁。箭头旁边的字,表明引起这种变迁的原因,或表明发生状态变迁后又出现什么动作。请注意图中有三种不同的箭头。`粗实线箭头`表示对`客户进程的正常变迁`。`粗虚线箭头`表示对`服务器进程的正常变迁`。另一种`细线箭头`表示`异常变迁`
+
+
+
+**《TCP协议详解》原文链接:[https://blog.maplemark.cn/2019/04/tcp协议详解.html](https://blog.maplemark.cn/2019/04/tcp协议详解.html)**
\ No newline at end of file
diff --git "a/docs/01.\347\275\221\347\273\234/04.TCP\347\262\230\345\214\205\346\213\206\345\214\205.md" "b/docs/01.\347\275\221\347\273\234/04.TCP\347\262\230\345\214\205\346\213\206\345\214\205.md"
new file mode 100755
index 0000000..5272992
--- /dev/null
+++ "b/docs/01.\347\275\221\347\273\234/04.TCP\347\262\230\345\214\205\346\213\206\345\214\205.md"
@@ -0,0 +1,50 @@
+# TCP 粘包拆包
+
+## 粘包问题
+
+在 TCP 这种字节流协议上做`应用层分包`是网络编程的基本需求。分包指的是在发生一个消息(message)或一帧(frame)数据时,通过一定的处理,让接收方能从字节流中识别并截取(还原)出一个个消息。因此,`“粘包问题”是个伪命题`
+
+## 短连接分包
+
+对于短连接的 TCP 服务,分包不是一个问题,只要发送方主动关闭连接,就表示一个消息发送完毕,接收方 read() 返回0,从而知道消息的结尾
+
+## TCP 发送机制
+
+为了提高 TCP 的传输效率,TCP 有一套自己的发送机制
+
+- TCP 维持一个变量,它等于`最大报文段长度 MSS`。只要缓存中存放的数据达到 MSS 字节时,就组装成一个 TCP 报文段发送出去
+- 由发送方的应用进程指明要求发送报文段,即 TCP 支持的`推送(push)`操作
+- 发送方的一个计时器期限到了,这时把当前已有的缓存数据装入报文段(但长度不能超过 MSS)发送出去
+
+## 长连接分包
+
+对于长连接的 TCP 服务,分包有四种方法
+
+- 消息长度固定
+- 使用特殊的字符或字符串作为消息的边界,例如 HTTP 协议的 headers 以“\r\n”为字段的分隔符
+- 在每条消息的头部加一个长度字段,这恐怕是最常见的做法
+- 利用消息本身的格式来分包,例如 XML 格式的消息中 ``...`` 的配对,或者 JSON 格式中的 { ... } 的配对。解析这种消息格式通常会用到状态机(state machine)
+
+## 复杂的分包
+
+假如消息格式非常简单,“消息”本身是一个字符串,每条消息有一个4字节的头部,以网络序存放字符串的长度。消息直接没有间隙,字符串也不要求以 '\0' 结尾
+
+发送两条消息“hello”和“smartboy”,打包后的字节流共有21字节
+
+```text
+0x00, 0x00, 0x00, 0x05, 'h', 'e', 'l', 'l', 'o',
+0x00, 0x00, 0x00, 0x08, 's', 'm', 'a', 'r', 't', 'b', 'o', 'y'
+```
+
+假设数据最终都全部到达,数据解析逻辑至少能正确处理以下各种数据到达的次序
+
+- 一个字节一个字节到达
+- 数据分两次到达,第一次收到2个字节,不足消息的长度字段
+- 数据分两次到达,第一次收到4个字节,刚好够长度字段,但是没有 body
+- 数据分两次到达,第一次收到8个字节,长度完整,但 body 不完整
+- 数据分两次到达,第一次收到9个字节,长度完整,但 body 也完整
+- 数据分两次到达,第一次收到10个字节,第一条消息的长度完整、body 也完整,第二条消息长度不完整
+- 请自行移动和增加分割点,一共有超过 100 万种可能(221-1)
+- 数据一次就全部到达
+
+**《TCP粘包拆包》 原文链接:[https://blog.maplemark.cn/2019/04/tcp粘包拆包.html](https://blog.maplemark.cn/2019/04/tcp粘包拆包.html)**
\ No newline at end of file
diff --git "a/docs/01.\347\275\221\347\273\234/05.HTTP\347\212\266\346\200\201\347\240\201.md" "b/docs/01.\347\275\221\347\273\234/05.HTTP\347\212\266\346\200\201\347\240\201.md"
new file mode 100755
index 0000000..a8f666d
--- /dev/null
+++ "b/docs/01.\347\275\221\347\273\234/05.HTTP\347\212\266\346\200\201\347\240\201.md"
@@ -0,0 +1,168 @@
+# HTTP 状态码
+
+## 状态码
+
+状态码是来告诉客户端,发生了什么事情。状态码为客户端提供了一种`理解事务处理结果`的`便捷方式`。状态码位于响应的起始行中
+
+> 比如,在行 HTTP/1.0 200 OK 中,状态码就是200
+
+客户端向一个 HTTP 服务器发送请求报文时,会遇到很多意想不到的情况,请求不一定能够成功完成。服务器可能会告诉你无法找到所请求的资源,你没有访问资源的权限,或者资源被移到了其他地方
+
+状态码是在每条响应报文的起始行中返回的。会返回一个数字状态和一个可读的状态。`数字码`便于程序进行差错处理,而`原因短语`则便于人们理解
+
+## 原因短语
+
+原因短语是响应起始行中的最后一个组件。它为状态码提供了`文本形式`的解释
+
+> 比如,在行 HTTP/1.0 200 OK 中,OK 就是原因短语
+
+原因短语和状态码是成对出现的。原因短语是状态码的`可读`版本,应用程序开发者将其传送给用户,用于说明在请求间发生了什么情况。HTTP 规范并没有提供任何硬性规定,要求原因短语以何种形式出现
+
+## 状态码分类
+
+### 五大类
+
+可以通过三位数字代码对不同状态码进行分类
+
+- 200 到 299 之间的状态码表示成功
+- 300 到 399 之间的代码表示资源已经被移走了
+- 400 到 499 之间的代码表示客户端的请求出错了
+- 500 到 599 之间的代码表示服务器出错了
+
+|状态码|整体范围|已定义范围|分类|
+|-|-|-|-|
+|1XX|100~199|100~101|信息提示|
+|2XX|200~299|200~206|成功|
+|3XX|300~399|300~305|重定向|
+|4XX|400~499|400~415|客户端错误|
+|5XX|500~599|500~505|服务器错误|
+
+当前的 HTTP 版本只为每类状态定义了几个代码。随着协议的发展,HTTP 规范中会正式地定义更多的状态码。若收到了不认识的状态码,可能是有人将其作为当前协议的`扩展定义`的。可以根据其所处的范围,将它作为那个类别中一个普通的成员来处理
+
+> 例如,若收到了状态码 515(在 5XX 代码的已定义范围之外),就应该认为这条响应指出了服务器的错误,这是 5XX 报文的通用类别
+
+### 100 ~ 199,信息状态码
+
+HTTP/1.1 向协议中引入了信息性状态码。这些状态码相对较新,关于其复杂性和感
+知价值存在一些争论,而受到限制
+
+|状态码|原因短语|含义|
+|-|-|-|
+|100|Continue|说明收到了请求的初始部分,请客户端继续。发送了这个状态码之后,服务器在收到请求之后必须进行响应|
+|101|Switching Protocols|说明服务器正在根据客户端的指定,将协议切换成 Update 首部所列的协议|
+
+100 Continue 状态码的目的是对这样的情况进行优化:HTTP 客户端应用程序有一个实体的主体部分要发送给服务器,但希望在发送之前查看一下服务器是否会接受这个实体。客户端应用程序只有在避免向服务器发送一个服务器`无法处理或使用的大实体`,才应该使用 100 Continue
+
+### 200 ~ 299,成功状态码
+
+客户端发起请求时,这些请求通常都是成功的。服务器有一组用来表示成功的状态码,分别对应于不同类型的请求
+
+|状态码|原因短语|含义|
+|-|-|-|
+|200|OK|请求没问题,实体的主体部分包含了所请求的资源|
+|201|Created|用于创建服务器对象的请求(比如:PUT)。响应的实体主体部分中应该包含引用了已创建的资源的URL,Location首部包含的则是最具体的引擎。服务器必须在发送这个状态码之前创建好对象|
+|202|Accepted|请求已被接受,服务器还未对其执行任何动作。不能保证服务器会完成这个请求;接受请求时,它看起来是有效的。服务器应在实体的主体部分包含对请求状态的描述,或附加请求预计处理时间、信息获取指针|
+|203|Non-Authoritative Information|实体首部包含的信息不是来自于源端服务器,而是来自资源的副本。如果中间节点上有一份副本,但无法或没有对元数据进行验证,就会出现这种情况|
+|204|No Content|响应报文中包含若干首部和一个状态行,但没有实体的主体部分。主要用于在浏览器不转为显示新文档的情况下,对其进行更新(比如刷新一个表单页面)|
+|205|Reset Content|另一个主要用于浏览器的代码。负责告知浏览器清除当前页面中的所有 HTML 表单元素|
+|206|Partial Content|成功执行了一个部分或 Range(范围)请求。客户端可以通过一些特殊的首部来获取部分或某个范围内的文档|
+
+### 300 ~ 399,重定向状态码
+
+重定向状态码要么告知客户端使用替代位置来访问他们所感兴趣的资源,要么就提供一个替代的响应而不是资源的内容。如果资源已被移动,可发送一个重定向状态码和一个可选的 Location 首部来告知客户端资源已被移走,以及现在可以在哪里找到它。这样,浏览器就可以在不打扰使用者的情况下,透明地转入新的位置了
+
+请求报文
+
+```text
+GET /index.php HTTP/1.1
+Host: blog.maplemark.cn
+Accept: *
+```
+
+响应报文
+
+```text
+HTTP/1.1 301 Moved Permanently
+Server: nginx/1.12.2
+Date: Fri, 19 Apr 2019 03:58:59 GMT
+Content-Type: text/html; charset=UTF-8
+X-Powered-By: PHP/7.2.16
+Location: https://blog.maplemark.cn/
+```
+
+请求报文
+
+```text
+GET / HTTP/1.1
+Host: blog.maplemark.cn
+Accept: *
+```
+
+响应报文
+
+```text
+HTTP/1.1 200 OK
+Server: nginx/1.12.2
+Date: Fri, 19 Apr 2019 03:59:34 GMT
+Content-Type: text/html; charset=UTF-8
+Transfer-Encoding: chunked
+Connection: keep-alive
+...
+```
+
+|状态码|原因短语|含义|
+|-|-|-|
+|300|Multiple Choices|客户端请求一个实际指向多个资源的URL时会返回这个状态码,比如服务器上有某个HTML文档有多个语言版本。返回时会带有一个选项列表,用户可以选择期望使用的那项|
+|301|Moved Permanently|在请求的 URL 已被移除时使用。响应的 Location 首部中应该包含资源现在所处的 URL|
+|302|Found|与 301 状态码类似;但是,客户端应该使用 Location 首部给出的URL 来临时定位资源。将来的请求仍应使用老的 URL|
+|303|See Other|告知客户端应该用另一个 URL 来获取资源。新的 URL 位于响应报文的 Location 首部。其主要目的是允许 POST 请求的响应将客户端定向到某个资源上去|
+|304|Not Modified|客户端可以通过所包含的请求首部,使其请求变成有条件的。若用户发起了一个条件 GET 请求,而资源近期未被修改,可以通过该状态码表明。带有这个状态码的响应不应该包含实体的主体部分|
+|305|Use Proxy|用来说明必须通过一个代理来访问资源;代理的位置由 Location首部给出。客户端是相对某个特定资源来解析这条响应的,不能假定所有请求,甚至所有对持有所请求资源的服务器的请求都通过这个代理进行。如果客户端错误地让代理介入了某条请求,可能会引发破坏性的行为,而且会造成安全漏洞|
+|306|(未使用)|当前未使用|
+|307|Temporary Redirect|与 301 状态码类似;但客户端应该使用 Location 首部给出的 URL来临时定位资源。将来的请求应该使用老的 URL|
+
+> 302、303 和 307 状态码之间存在一些交叉。这些状态码的用法有着细微的差别,大部分差别都源于 HTTP/1.0 和 HTTP/1.1 应用程序对这些状态码`处理方式`的不同,为兼容 HTTP/1.0 而保留了一些状态码(例如 302 状态码)
+
+### 400 ~ 499,客户端错误状态码
+
+有时客户端会发送一些服务器`无法处理`的东西,比如格式错误的请求报文,或者最常见的是,请求一个不存在的 URL
+
+很多客户端错误都是由浏览器来处理的,甚至不会打扰到你。只有少量错误,比如404,还是会穿过浏览器来到用户面前
+
+|状态码|原因短语|含义|
+|-|-|-|
+|400|Bad Request|用于告知客户端它发送了一个错误的请求|
+|401|Unauthorized|与适当的首部一同返回,在这些首部中请求客户端在获取对资源的访问权之前,对自己进行认证|
+|402|Payment Required|现在这个状态码还未使用,但已经被保留,以作未来之用|
+|403|Forbidden|用于说明请求被服务器拒绝了。如果服务器想说明为什么拒绝请求,可以包含实体的主体部分来对原因进行描述。但这个状态码通常是在服务器不想说明拒绝原因的时候使用的|
+|404|Not Found|用于说明服务器无法找到所请求的 URL。通常会包含一个实体,以便客户端应用程序显示给用户看|
+|405|Method Not Allowed|发起的请求中带有所请求的 URL 不支持的方法时,使用此状态码。应该在响应中包含 Allow 首部,以告知客户端对所请求的资源可以使用哪些方法|
+|406|Not Acceptable|客户端可以指定参数来说明它们愿意接收什么类型的实体。服务器没有与客户端可接受的 URL 相匹配的资源时,使用此代码。通常,服务器会包含一些首部,以便客户端弄清楚为什么请求无法满足|
+|407|Proxy Authentication Required|与 401 状态码类似,但用于要求对资源进行认证的代理服务器|
+|408|Request Timeout|如果客户端完成请求所花的时间太长,服务器可以回送此状态码,并关闭连接。超时时长随服务器的不同有所不同,但通常对所有的合法请求来说,都是够长的|
+|409|Conflict|用于说明请求可能在资源上引发的一些冲突。服务器担心请求会引发冲突时,可以发送此状态码。响应中应该包含描述冲突的主体|
+|410|Gone|与 404 类似,只是服务器曾经拥有过此资源。主要用于 Web 站点的维护,这样服务器的管理者就可以在资源被移除的情况下通知客户端了|
+|411|Length Required|服务器要求在请求报文中包含 Content-Length 首部时使用|
+|412|Precondition Failed|客户端发起了条件请求,且其中一个条件失败了的时候使用。客户端包含了 Expect 首部时发起的就是条件请求|
+|413|Request Entity Too Large|客户端发送的实体主体部分比服务器能够或者希望处理的要大时,使用此状态码|
+|414|Request URI Too Long|客户端所发请求中的请求 URL 比服务器能够或者希望处理的要长时,使用此状态码|
+|415|Unsupported Media Type|服务器无法理解或无法支持客户端所发实体的内容类型时,使用此状态码|
+|416|Requested Range Not Satisfiable|请求报文所请求的是指定资源的某个范围,而此范围无效或无法满足时,使用此状态码|
+|417|Expectation Failed|请求的 Expect 请求首部包含了一个期望,但服务器无法满足此期望时,使用此状态码。如果代理或其他中间应用程序有确切证据说明源端服务器会为某请求产生一个失败的期望,就可以发送这个响应状态码|
+
+### 500 ~ 599,服务器错误状态码
+
+有时客户端发送了一条有效请求,服务器自身却出错了。这可能是客户端碰上了服务器的缺陷,或者服务器上的子元素,比如某个网关资源,出了错
+
+代理尝试着代表客户端与服务器进行交流时,经常会出现问题。代理会发布 5XX 服务器错误状态码来描述所遇到的问题
+
+|状态码|原因短语|含义|
+|-|-|-|
+|500|Internal Server Error|服务器遇到一个妨碍它为请求提供服务的错误时,使用此状态码|
+|501|Not Implemented|客户端发起的请求超出服务器的能力范围(比如,使用了服务器不支持的请求方法)时,使用此状态码|
+|502|Bad Gateway|作为代理或网关使用的服务器从请求响应链的下一条链路上收到了一条伪响应(比如,它无法连接到其父网关)时,使用此状态码|
+|503|Service Unavailable|用来说明服务器现在无法为请求提供服务,但将来可以。如果服务器知道什么时候资源会变为可用的,可以在响应中包含一个 RetryAfter 首部|
+|504|Gateway Timeout|与状态码 408 类似,只是这里的响应来自一个网关或代理,它们在等待另一服务器对其请求进行响应时超时了|
+|505|HTTP Version Not Supported|服务器收到的请求使用了它无法或不愿支持的协议版本时,使用此状态码。有些服务器应用程序会选择不支持协议的早期版本|
+
+**《HTTP状态码》 原文链接:[https://blog.maplemark.cn/2019/04/http状态码.html](https://blog.maplemark.cn/2019/04/http状态码.html)**
\ No newline at end of file
diff --git "a/docs/01.\347\275\221\347\273\234/06.HTTP\346\226\271\346\263\225\350\257\246\350\247\243.md" "b/docs/01.\347\275\221\347\273\234/06.HTTP\346\226\271\346\263\225\350\257\246\350\247\243.md"
new file mode 100755
index 0000000..1a4ef84
--- /dev/null
+++ "b/docs/01.\347\275\221\347\273\234/06.HTTP\346\226\271\346\263\225\350\257\246\350\247\243.md"
@@ -0,0 +1,95 @@
+# HTTP方法详解
+
+## 常见的 HTTP 方法
+
+HTTP 请求方法用于告诉服务器要做什么。HTTP 规范中定义了一组常用的请求方法。
+
+> 例如:GET 方法负责从服务器获取文档,POST 方法会向服务器发送需要处理的数据,OPTIONS 方法用于确定服务器的一般功能,或者服务器处理特定资源的能力
+
+下图描述了7种 HTTP 方法,并不是所有服务器都实现了所有7种方法。有些方法的请求报文中有主体,有些则无主体的请求
+
+
+
+由于 HTTP 设计易于扩展,除这些方法,其他服务器可能还会实现一些自己的请求方法。这些附加的方法是对 HTTP 规范的扩展,被称为`扩展方法`
+
+## 安全方法
+
+HTTP 定义了一组被称为`安全方法`的方法。GET 方法和 HEAD 方法都被认为是安全的,这就意味着使用 GET 或 HEAD 方法的 HTTP 请求都不会产生什么动作
+
+不产生动作,在这里意味着 HTTP 请求不会在服务器上产生什么结果。例如,你在 Colin 的五金商店购物时,点击了“提交购买”按钮。点击按钮时会提交一个带有信用卡信息的 POST 请求,那么在服务器上,就会为你执行一个动作。在这种情况下,为购买行为支付信用卡就是所执行的动作
+
+安全方法并不一定是什么动作都不执行的(实际上,这是由 Web 开发者决定的)。使用安全方法的目的就是当使用可能引发某一动作的不安全方法时,`允许 HTTP 应用程序开发者通知用户`。在 Colin 的五金商店的例子中,你的 Web 浏览器可能会弹出一条警告消息,说明你正在用不安全的方法发起请求,这样可能会在服务器上引发一些事件(比如用你的信用卡支付费用)
+
+## 方法详解
+
+### GET 方法
+
+GET 是最常用的方法。通常用于请求服务器发送某个资源。HTTP/1.1 要求服务器实现此方法
+
+
+
+### HEAD 方法
+
+HEAD 方法与 GET 方法的行为很类似,但服务器在响应中只返回首部。不会返回实体的主体部分。这就允许客户端在未获取实际资源的情况下,对资源的首部进行检查。使用 HEAD,可以:
+
+- 在不获取资源的情况下了解资源的情况(比如,判断其类型)
+- 通过查看响应中的状态码,看看某个对象是否存在
+- 通过查看首部,测试资源是否被修改了
+
+服务器开发者必须确保返回的首部与 GET 请求所返回的首部完全相同。遵循 HTTP/1.1 规范,就必须实现 HEAD 方法
+
+
+
+### PUT 方法
+
+与 GET 从服务器读取文档相反,PUT 方法会向服务器写入文档。有些发布系统允许用户创建 Web 页面,并用 PUT 直接将其安装到 Web 服务器上去
+
+
+
+PUT 方法的语义就是让服务器用请求的主体部分来创建一个由所请求的 URL 命名的新文档,或者,如果那个 URL 已经存在的话,就用这个主体来替代它。
+
+因为 PUT 允许用户对内容进行修改,所以很多 Web 服务器都要求在执行 PUT 之前,用密码登录
+
+### POST 方法
+
+POST 方法起初是用来向服务器输入数据的。实际上,通常会用它来支持 HTML 的表单。表单中填好的数据通常会被送给服务器,然后由服务器将其发送到它要去的地方(比如,送到一个服务器网关程序中,然后由这个程序对其进行处理)
+
+
+
+### TRACE 方法
+
+客户端发起一个请求时,这个请求可能要穿过防火墙、代理、网关或其他一些应用程序。每个中间节点都可能会`修改原始的 HTTP 请求`。TRACE 方法允许客户端在最终将请求发送给服务器时,看看它变成了什么样子
+
+TRACE 请求会在目的服务器端发起一个“环回”诊断。行程最后一站的服务器会弹回一条 TRACE 响应,并在响应主体中携带它收到的原始请求报文。这样客户端就可以查看在所有中间 HTTP 应用程序组成的请求/响应链上,原始报文是否,以及如何被毁坏或修改过 TRACE 方法主要用于诊断;也就是说,用于验证请求是否如愿穿过了请求/响应链。它也是一种很好的工具,可以用来查看代理和其他应用程序对用户请求所产生效果
+
+尽管 TRACE 可以很方便地用于诊断,但它确实也有缺点,它假定中间应用程序对各种不同类型请求(不同的方法——GET、HEAD、POST 等)的处理是相同的。很多 HTTP 应用程序会根据方法的不同做出不同的事情——比如,代理可能会将 POST 请求直接发送给服务器,而将 GET 请求发送给另一个 HTTP 应用程序(比如Web 缓存)。TRACE 并不提供区分这些方法的机制。通常,中间应用程序会自行决定对 TRACE 请求的处理方式
+
+TRACE 请求中不能带有实体的主体部分。TRACE 响应的实体主体部分包含了响应服务器收到的请求的精确副本
+
+
+
+### OPTIONS
+
+OPTIONS 方法请求 Web 服务器告知其支持的各种功能。可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法。(有些服务器可能只支持对一些特殊类型的对象使用特定的操作)
+
+这为客户端应用程序提供了一种手段,使其不用实际访问那些资源就能判定访问各种资源的最优方式
+
+
+
+### DELETE
+
+DELETE 方法所做的事情就是请服务器删除请求 URL 所指定的资源。但是,客户端应用程序无法保证删除操作一定会被执行。因为 HTTP 规范允许服务器在不通知客户端的情况下撤销请求
+
+
+
+### 扩展方法
+
+HTTP 被设计成字段可扩展的,这样新的特性就不会使老的软件失效了。扩展方法指的就是没有在 HTTP/1.1 规范中定义的方法。服务器会为它所管理的资源实现一些 HTTP 服务,这些方法为开发者提供了一种扩展这些 HTTP 服务能力的手段。下图列出了一些常见的扩展方法实例。这些方法就是 WebDAV HTTP 扩展包含的所有方法,这些方法有助于通过 HTTP 将 Web 内容发布到 Web 服务器上去
+
+
+
+并不是所有的扩展方法都是在正式规范中定义的,认识到这一点很重要。如果你定义了一个扩展方法,很可能大部分 HTTP 应用程序都无法理解。同样,你的 HTTP应用程序也可能会遇到一些其他应用程序在用的,而它并不理解的扩展方法
+
+在这些情况下,最好对扩展方法宽容一些。如果能够在不破坏端到端行为的情况下将带有未知方法的报文传递给下游服务器,代理应尝试传递这些报文。如果可能破坏端到端行为则应以 501 Not Implemented(无法实现)状态码进行响应。最好按惯例“对所发送的内容要求严一点,对所接收的内容宽容一些”来处理扩展方法(以及一般的 HTTP 扩展)
+
+**《HTTP方法详解》 原文链接:[https://blog.maplemark.cn/2019/04/http方法详解.html](https://blog.maplemark.cn/2019/04/http方法详解.html)**
\ No newline at end of file
diff --git "a/docs/01.\347\275\221\347\273\234/07.HTTPS\347\273\206\350\212\202\344\273\213\347\273\215.md" "b/docs/01.\347\275\221\347\273\234/07.HTTPS\347\273\206\350\212\202\344\273\213\347\273\215.md"
new file mode 100755
index 0000000..07a6573
--- /dev/null
+++ "b/docs/01.\347\275\221\347\273\234/07.HTTPS\347\273\206\350\212\202\344\273\213\347\273\215.md"
@@ -0,0 +1,93 @@
+# HTTPS 细节介绍
+
+HTTPS 是最常见的 HTTP `安全版本`。它得到了很广泛的应用,所有主要的商业浏览器和服务器上都提供 HTTPS。HTTPS 将 HTTP 协议与一组强大的对称、非对称和基于证书的加密技术结合在一起,使得 HTTPS 不仅很安全,而且很灵活,很容易在处于无序状态的、分散的全球互联网上进行管理
+
+HTTPS 加速了因特网应用程序的成长,已经成为基于 Web 的电子商务快速成长的主要推动力。在广域网中对分布式 Web 应用程序的安全管理方面,HTTPS 也是非常重要的
+
+## HTTPS 概述
+
+HTTPS 就是在安全的传输层上发送的 HTTP。HTTPS 没有将未加密的 HTTP 报文发送给 TCP,并通过世界范围内的因特网进行传输,它在将 HTTP 报文发送给 TCP 之前,先将其发送给了一个安全层,对其进行加密
+
+
+
+现在,HTTP 安全层是通过 SSL 及其现代替代协议 TLS 来实现的。我们遵循常见的用法,用术语 SSL 来表示 SSL 或者 TLS
+
+## HTTPS 方案
+
+现在,安全 HTTP 是可选的。因此,对 Web 服务器发起请求时,我们需要有一种方式来告知 Web 服务器去执行 HTTP 的安全协议版本。这是在 URL 的方案中实现的。通常情况下,非安全 HTTP 的 URL 方案前缀为 http,如下所示:
+
+> http://blog.maplemark.cn
+
+在安全 HTTPS 协议中,URL 的方案前缀为 https,如下所示:
+
+> https://blog.maplemark.cn
+
+请求一个客户端(比如 Web 浏览器)对某 Web 资源执行某事务时,它会去检查 URL 的方案
+
+- 如果 URL 的方案为 http,客户端就会打开一条到服务器端口 80(默认情况下)
+的连接,并向其发送老的 HTTP 命令
+- 如果 URL 的方案为 https,客户端就会打开一条到服务器端口 443(默认情况下)
+的连接,然后与服务器“握手”,以二进制格式与服务器交换一些 SSL 安全参数,
+附上加密的 HTTP 命令
+
+SSL 是个二进制协议,与 HTTP 完全不同,其流量是承载在另一个端口上的(SSL 通常是由端口 443 承载的)。如果 SSL 和 HTTP 流量都从端口 80 到达,大部分 Web 服务器会将二进制 SSL 流量理解为错误的 HTTP 并关闭连接。将安全服务进一步整合到 HTTP 层中去就无需使用多个目的端口了,在实际中这样不会引发严重的问题
+
+
+
+## 建立安全传输
+
+在未加密 HTTP 中,客户端会打开一条到 Web 服务器端口 80 的 TCP 连接,发送一条请求报文,接收一条响应报文,关闭连接
+
+由于 SSL 安全层的存在,HTTPS 中这个过程会略微复杂一些。在 HTTPS 中,客户端首先打开一条到 Web 服务器端口 443(安全 HTTP 的默认端口)的连接。一旦建立了 TCP 连接,客户端和服务器就会初始化 SSL 层,对加密参数进行沟通,并交换密钥。握手完成之后,SSL 初始化就完成了,客户端就可以将请求报文发送给安全层了。在将这些报文发送给 TCP 之前,要先对其进行加密
+
+## SSL 握手
+
+在发送已加密的 HTTP 报文之前,客户端和服务器要进行一次 SSL 握手,在这个握手过程中,它们要完成以下工作
+
+- 交换协议版本号
+- 选择一个两端都了解的密码
+- 对两端的身份进行认证
+- 生成临时的会话密钥,以便加密信道
+
+
+
+在通过网络传输任何已加密的 HTTP 数据之前,SSL 已经发送了一组握手数据来建立通信连接了
+
+
+
+这是 SSL 握手的简化版本。根据 SSL 的使用方式,握手过程可能会复杂一些,但总
+的思想就是这样
+
+## 服务器证书
+
+SSL 支持双向认证,将服务器证书承载回客户端,再将客户端的证书回送给服务器。而现在,浏览时并不经常使用客户端证书。大部分用户甚至都没有自己的客户端证书。服务器可以要求使用客户端证书,但实际中很少出现这种情况。
+
+另一方面,安全 HTTPS 事务总是要求使用服务器证书的。在一个 Web 服务器上执行安全事务,比如提交信用卡信息时,你总是希望是在与你所认为的那个组织对话。由知名权威机构签发的服务器证书可以帮助你在发送信用卡或私人信息之前评估你对服务器的信任度。
+
+服务器证书是一个显示了组织的名称、地址、服务器 DNS 域名以及其他信息的 X.509 v3 派生证书。你和你所用的客户端软件可以检查证书,以确保所有的信息都是可信的
+
+
+
+## 站点证书的有效性
+
+SSL 自身不要求用户检查 Web 服务器证书,但大部分现代浏览器都会对证书进行简单的完整性检查,并为用户提供进行进一步彻查的手段。网景公司提出的一种 Web 服务器证书有效性算法是大部分浏览器有效性验证技术的基础。
+
+- 日期检测
+
+首先,浏览器检查证书的起始日期和结束日期,以确保证书仍然有效。如果证书过期了,或者还未被激活,则证书有效性验证失败,浏览器显示一条错误信息
+
+- 签名颁发者可信度检测
+
+每个证书都是由某些证书颁发机构(CA)签发的,它们负责为服务器担保。证书有不同的等级,每种证书都要求不同级别的背景验证。比如,如果申请某个电子商务服务器证书,通常需要提供一个营业的合法证明
+
+任何人都可以生成证书,但有些 CA 是非常著名的组织,它们通过非常清晰的流程来验证证书申请人的身份及商业行为的合法性。因此,浏览器会附带一个签名颁发机构的受信列表。如果浏览器收到了某未知(可能是恶意的)颁发机构签发的证书,那它通常会显示一条警告信息。有些证书会携带到受信 CA 的有效签名路径,浏览器可能会选择接受所有此类证书。换句话说,如果某受信 CA 为“Sam 的签名商店”签发了一个证书,而 Sam 的签名商店也签发了一个站点证书,浏览器可能会将其作为从有效 CA 路径导出的证书接受
+
+- 签名检测
+
+一旦判定签名授权是可信的,浏览器就要对签名使用签名颁发机构的公开密钥,并将其与校验码进行比较,以查看证书的完整性
+
+- 站点身份检测
+
+为防止服务器复制其他人的证书,或拦截其他人的流量,大部分浏览器都会试着去验证证书中的域名与它们所对话的服务器的域名是否匹配。服务器证书中通常都包含一个域名,但有些 CA 会为一组或一群服务器创建一些包含了服务器名称列表或通配域名的证书。如果主机名与证书中的标识符不匹配,面向用户的客户端要么就去通知用户,要么就以表示证书不正确的差错报文来终止连接
+
+**《HTTPS细节介绍》 原文链接:[http://blog.maplemark.cn/2019/05/https细节介绍.html](http://blog.maplemark.cn/2019/05/https细节介绍.html)**
\ No newline at end of file
diff --git "a/docs/01.\347\275\221\347\273\234/08.SSL-TLS\345\215\217\350\256\256\350\277\220\350\241\214\346\234\272\345\210\266\347\232\204\346\246\202\350\277\260.md" "b/docs/01.\347\275\221\347\273\234/08.SSL-TLS\345\215\217\350\256\256\350\277\220\350\241\214\346\234\272\345\210\266\347\232\204\346\246\202\350\277\260.md"
new file mode 100755
index 0000000..c268ba7
--- /dev/null
+++ "b/docs/01.\347\275\221\347\273\234/08.SSL-TLS\345\215\217\350\256\256\350\277\220\350\241\214\346\234\272\345\210\266\347\232\204\346\246\202\350\277\260.md"
@@ -0,0 +1,142 @@
+# SSL/TLS协议运行机制的概述
+
+互联网的通信安全,建立在SSL/TLS协议之上。
+
+本文简要介绍SSL/TLS协议的运行机制。文章的重点是设计思想和运行过程,不涉及具体的实现细节。如果想了解这方面的内容,请参阅[RFC文档](http://tools.ietf.org/html/rfc5246)。
+
+## 一、作用
+
+不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文传播,带来了三大风险。
+
+- `窃听风险`(eavesdropping):第三方可以获知通信内容。
+- `篡改风险`(tampering):第三方可以修改通信内容。
+- `冒充风险`(pretending):第三方可以冒充他人身份参与通信。
+
+SSL/TLS协议是为了解决这三大风险而设计的,希望达到:
+
+- 所有信息都是`加密传播`,第三方无法窃听。
+- 具有`校验机制`,一旦被篡改,通信双方会立刻发现。
+- 配备`身份证书`,防止身份被冒充。
+
+互联网是开放环境,通信双方都是未知身份,这为协议的设计带来了很大的难度。而且,协议还必须能够经受所有匪夷所思的攻击,这使得SSL/TLS协议变得异常复杂。
+
+## 二、历史
+
+互联网加密通信协议的历史,几乎与互联网一样长。
+
+```text
+1994年,NetScape公司设计了SSL协议(Secure Sockets Layer)的1.0版,但是未发布。
+1995年,NetScape公司发布SSL 2.0版,很快发现有严重漏洞。
+1996年,SSL 3.0版问世,得到大规模应用。
+1999年,互联网标准化组织ISOC接替NetScape公司,发布了SSL的升级版TLS 1.0版。
+2006年和2008年,TLS进行了两次升级,分别为TLS 1.1版和TLS 1.2版。最新的变动是2011年TLS 1.2的修订版。
+```
+
+目前,应用最广泛的是TLS 1.0,接下来是SSL 3.0。但是,主流浏览器都已经实现了TLS 1.2的支持。
+
+TLS 1.0通常被标示为SSL 3.1,TLS 1.1为SSL 3.2,TLS 1.2为SSL 3.3。
+
+## 三、基本的运行过程
+
+SSL/TLS协议的基本思路是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。
+
+但是,这里有两个问题。
+
+- 如何保证公钥不被篡改?
+
+> 解决方法:将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。
+
+- 公钥加密计算量太大,如何减少耗用的时间?
+
+> 解决方法:每一次对话(session),客户端和服务器端都生成一个"对话密钥"(session key),用它来加密信息。由于"对话密钥"是对称加密,所以运算速度非常快,而服务器公钥只用于加密"对话密钥"本身,这样就减少了加密运算的消耗时间。
+
+因此,SSL/TLS协议的基本过程是这样的:
+
+> 客户端向服务器端索要并验证公钥。
+
+> 双方协商生成"对话密钥"。
+
+> 双方采用"对话密钥"进行加密通信。
+
+上面过程的前两步,又称为"握手阶段"(handshake)。
+
+## 四、握手阶段的详细过程
+
+"握手阶段"涉及四次通信,我们一个个来看。需要注意的是,"握手阶段"的所有通信都是明文的。
+
+### 4.1 客户端发出请求(ClientHello)
+
+首先,客户端(通常是浏览器)先向服务器发出加密通信的请求,这被叫做ClientHello请求。
+
+在这一步,客户端主要向服务器提供以下信息。
+
+> 支持的协议版本,比如TLS 1.0版。
+
+> 一个客户端生成的随机数,稍后用于生成"对话密钥"。
+
+> 支持的加密方法,比如RSA公钥加密。
+
+> 支持的压缩方法。
+
+这里需要注意的是,客户端发送的信息之中不包括服务器的域名。也就是说,理论上服务器只能包含一个网站,否则会分不清应该向客户端提供哪一个网站的数字证书。这就是为什么通常一台服务器只能有一张数字证书的原因。
+
+对于虚拟主机的用户来说,这当然很不方便。2006年,TLS协议加入了一个Server Name Indication扩展,允许客户端向服务器提供它所请求的域名。
+
+### 4.2 服务器回应(SeverHello)
+
+服务器收到客户端请求后,向客户端发出回应,这叫做SeverHello。服务器的回应包含以下内容。
+
+> 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
+
+> 一个服务器生成的随机数,稍后用于生成"对话密钥"。
+
+> 确认使用的加密方法,比如RSA公钥加密。
+
+> 服务器证书。
+
+除了上面这些信息,如果服务器需要确认客户端的身份,就会再包含一项请求,要求客户端提供"客户端证书"。比如,金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供USB密钥,里面就包含了一张客户端证书。
+
+### 4.3 客户端回应
+
+客户端收到服务器回应以后,首先验证服务器证书。如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。
+
+如果证书没有问题,客户端就会从证书中取出服务器的公钥。然后,向服务器发送下面三项信息。
+
+> 一个随机数。该随机数用服务器公钥加密,防止被窃听。
+
+> 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
+
+> 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。
+
+上面第一项的随机数,是整个握手阶段出现的第三个随机数,又称"pre-master key"。有了它以后,客户端和服务器就同时有了三个随机数,接着双方就用事先商定的加密方法,各自生成本次会话所用的同一把"会话密钥"。
+
+至于为什么一定要用三个随机数,来生成"会话密钥",dog250解释得很好:
+
+> "不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。
+
+> 对于RSA密钥交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。
+
+> pre master的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么pre master secret就有可能被猜出来,那么仅适用pre master secret作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上pre master secret三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。"
+
+此外,如果前一步,服务器要求客户端证书,客户端会在这一步发送证书及相关信息。
+
+### 4.4 服务器的最后回应
+
+服务器收到客户端的第三个随机数pre-master key之后,计算生成本次会话所用的"会话密钥"。然后,向客户端最后发送下面信息。
+
+> 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
+
+> 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。
+
+至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用"会话密钥"加密内容。
+
+## 五、参考链接
+
+- MicroSoft TechNet, [SSL/TLS in Detail](http://technet.microsoft.com/en-us/library/cc785811(v=ws.10).aspx)
+- Jeff Moser, [The First Few Milliseconds of an HTTPS Connection](http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html)
+- Wikipedia, [Transport Layer Security](http://en.wikipedia.org/wiki/Transport_Layer_Security)
+- StackExchange, [How does SSL work?](http://security.stackexchange.com/questions/20803/how-does-ssl-work)
+
+(完)
+
+**《SSL/TLS协议运行机制的概述》 [原文链接](http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html)**
\ No newline at end of file
diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-architecture-01.png" "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-01.png"
new file mode 100755
index 0000000000000000000000000000000000000000..33d056303fe5b8f9be3218c781508224b6a0a483
GIT binary patch
literal 55697
zcmaI81yt2<6E%A1P66re?vfS|q(kWj=|);ox;sRr1*Jn$q@`3u5D<_qMM)_UzTyAI
zckf#Fy)IqC;hbMR&&=%Edk=Bins@N9DX|d<1fHsjqAmh~tbjluQDY**E2Wj{8t@;5
zkCLH}p8EqIKPxXgguJc0wH>{xtChW-uAP-_fakEC6as<5=%{b#W2m7nY2)t7Yjyn|
zUVm2)_%s3`CF}2DW#eq;LvL+o@8~AYxZClTk>1f(n$bW+gI~krww;5cN}!jWUZAGF
zO`x-lge{}2484@UBpkri&c}-0-_^ye@t@;L!q?X?^D)x@^A;axX~utDl%a+;
z{cU$IJ9-gbAs!ok0RehZQCvq%KttWd?(H5;N#;V$;apC=f~?O#Ov;5&nF-uA#r^SK|vmP2ak7vn~#-0kDE8s
ze~zGN=WXNV=;7n&?nZxoL@R6ehd$DbaHapc1y_&%9@fqK-;W6%7@xnD2cG~h|Me~X
z=ZzW~|Nn1wb^Y(Vy?u1;{_pkve;(LdKfuF|PuI@d{h^l)EZhU8>r;71-uAMy@^Sal
zcXxOB&r{TPaQAWdc5wHgzpW=q&u-x8X6x?f&GFCsH8dnu-MoFQ+-&Sr6{Q*B2)vGt
zwvzG+f{M3AL;m6ZeplqAGOgaqWpL`B6EL`1}eBqaXxSw(l7hpu*RKL7cw?f?C(
z(Et4G^;U58fHN!Fc{%#p*(!UvyVC!2%aV@&`(_=kfmiS=;}8Edu}ZvwUzdeAf&6
z|5)h%yac=F`pf@rTlnU`8{f_icDomB>&9o*y$Hk?G*v};egCgJZ|s8a-8s2@6o0Fy
znh+Ta6^m@1r`05FMSH%;zkbD>`fi%#KtcyPn;~)!F}EBhF>`p~$>HCpzu#`op2P{u
zDLgjf`(VE-(P*DiWi;LXAmw6j`!ibx8IN(3!zW^CmJbB77lqF93D++u8j%0_7nAp%