diff --git a/.gitattributes b/.gitattributes index e2e421c..2125666 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -*.* linguist-language=php \ No newline at end of file +* text=auto \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..723ef36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/CONTENT.md b/CONTENT.md new file mode 100644 index 0000000..31c86ef --- /dev/null +++ b/CONTENT.md @@ -0,0 +1,41 @@ +# PHP面试指南 + +> 忘掉你的经验,试试我的方法。 + +## 市场前景 + +### php份额 + +### 技术成熟度曲线 + +## 薪资水平 + +### 程序员 + +### php + +## 作者介绍 + +### 从业经验 + +### 为什么要写这个 + +## 使用指南 + +### 应聘者 + +### 面试官 + +## 我理解的面试 + +### 岗位的来由 + +### 面试流程 + +### 工作能力证明 + +## 问答列表 + +## 参考资料 + +## 版权声明 \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index ee30323..413e778 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,118 @@ -# PHP面试问答 +# PHP 面试问答 + +> PHP 很没前途,请把工作留给我,谢谢! + +## 一、PHP 篇 + +- [【试读】编程语言基础](./docs/php/编程语言简介.md) +- 【试读】PHP 与编程范式 +- [【试读】当下最流行的 PHP 本地环境搭建方式](./docs/php/当下最流行的PHP本地环境搭建方式.md) +- 【试读】代码风格指南 +- 【试读】代码注释 +- [【试读】将变量打印出来,你知道哪些方式](./docs/php/将变量打印出来你知道哪些方式.md) +- 【试读】使用 xdebug 调试你的代码 +- 【试读】基础知识 +- [【试读】单引号和双引号的区别](./docs/php/单引号和双引号的区别.md) +- [【试读】isset 和 empty 的区别之如何判空](./docs/php/isset和empty的区别之如何判空.md) +- 【试读】面向对象编程 +- 【试读】PHP 与函数式编程 +- 【试读】PHP 与元编程 +- 【试读】命名空间 +- 【试读】PHP 标准库(SPL) +- 【试读】日期和时间 +- 【试读】请使用 UTF-8 编码 +- 【试读】本地化与国际化 +- 【试读】2025 年有哪些流行的框架 +- 【试读】如何进行依赖管理 +- 【试读】依赖注入 +- 【试读】错误与异常 +- [【试读】composer 包升级](./docs/php/composer包升级.md) +- 【试读】MySQL 扩展 +- 【试读】PDO 扩展 +- 【试读】单元测试 +- 【试读】Postman + +## 二、数据结构与算法篇 + +## 三、网络篇 + +## 四、设计模式篇 + +- 【试读】如何解决复杂问题 + +## 五、数据基础设施篇 + +## 六、架构篇 + +-【试读】领域驱动设计(DDD) + +## 七、服务器篇 + +## 八、安全篇 + +- 【试读】密码学简介 +- 【试读】加密与编码 + +## 九、客户端篇 + +## 十、番外篇 + +- [【试读】你的编码热情是如何消退的?](./docs/番外/你的编码热情是如何消退的.md) + 结合实际PHP面试,汇总自己遇到的问题,以及网上其他人遇到的问题,尝试提供简洁准确的答案 -网络、数据结构与算法、PHP、Web、MySQL、Redis、Linux、安全、设计模式、架构、面试等部分 +包含网络、数据结构与算法、PHP、Web、MySQL、Redis、Linux、安全、设计模式、架构、面试等部分 > 本仓库将持续更新,fork 无法看到最新内容,建议 Watch 或 Star ~~ -## 面试流程 +**温馨提示** + +- 分享面试遇到的问题,通过提交 Issue + +- 参与项目内容完善,通过提交 PR,提交内容请尽量保证`准确性`和`可读性` -![面试流程](./docs/interview.png) +- 本仓库需要什么内容:`实际经典面试题` + `靠谱简答` + `详细深入文章(必要的话)` -## 微信群 +## 一、面试准备 -扫码加微信,备注:`PIQA`,有时候可能在忙,稍等片刻 +![面试流程](./docs/assets/interview.png) -

wechat

+> 简历 -> 笔试 -> 技术一面 -> 技术二面 -> 技术三面 -> HR面 -> offer -## 问题列表 +- [技术岗面试潜规则](./docs/面试/技术岗面试潜规则.md) +- [设计一份吸引面试官的简历](./docs/面试/设计一份吸引面试官的简历.md) +- [读懂岗位精准投递](./docs/面试/读懂岗位精准投递.md) +- [做好充分的准备去面试](./docs/面试/做好充分的准备去面试.md) +- [把握面试时的关键点](./docs/面试/把握面试时的关键点.md) +- [捕捉面试官微表情,做出应对策略](./docs/面试/捕捉面试官微表情,做出应对策略.md) +- [巧妙推销自己的3个技巧](./docs/面试/巧妙推销自己的3个技巧.md) +- [判断公司背景,做出合理选择](./docs/面试/判断公司背景,做出合理选择.md) +- [了解行业薪资,清晰找准定位](./docs/面试/了解行业薪资,清晰找准定位.md) +- [目标明确,阐明沟通](./docs/面试/目标明确,阐明沟通.md) +- [工作交接流程福利衔接](./docs/面试/工作交接流程福利衔接.md) +- [如何让工作年限变成优势](./docs/面试/如何让工作年限变成优势.md) -### 网络协议篇 +## 二、问答列表 -- [计算机网络体系结构](./docs/01.网络/QA.md#计算机网络体系结构) -- [UDP 的主要特点](./docs/01.网络/QA.md#udp-的主要特点) -- [TCP 的主要特点](./docs/01.网络/QA.md#tcp-的主要特点) -- [简述三报文握手建立 TCP 连接](./docs/01.网络/QA.md#简述三报文握手建立-tcp-连接) -- [建立 TCP 连接为什么最后还要发送确认](./docs/01.网络/QA.md#建立-tcp-连接为什么最后还要发送确认) -- [简述 TCP 连接的释放](./docs/01.网络/QA.md#简述-tcp-连接的释放) -- [TIME-WAIT 是什么,为什么必须等待 2MLS](./docs/01.网络/QA.md#time-wait-是什么为什么必须等待-2mls) -- [TCP 粘包问题](./docs/01.网络/QA.md#tcp-粘包问题) -- [UDP、TCP 区别,适用场景](./docs/01.网络/QA.md#udptcp-区别适用场景) -- [建立 socket 需要哪些步骤](./docs/01.网络/QA.md#建立-socket-需要哪些步骤) -- [DNS 主要作用是什么](./docs/01.网络/QA.md#dns-主要作用是什么) -- [HTTP 报文组成](./docs/01.网络/QA.md#http-报文组成) -- [HTTP 状态码](./docs/01.网络/QA.md#http-状态码) -- [常见的 HTTP 方法](./docs/01.网络/QA.md#常见的-http-方法) -- [HTTP 优缺点](./docs/01.网络/QA.md#http-优缺点) -- [HTTPS 通信原理](./docs/01.网络/QA.md#https-通信原理) -- [HTTP 2.0](./docs/01.网络/QA.md#http-2.0) -- [IPv6 与 IPv4 有什么变化](./docs/01.网络/QA.md#ipv6-与-ipv4-有什么变化) -- [什么是心跳机制](./docs/01.网络/QA.md#什么是心跳机制) -- [什么是长连接](./docs/01.网络/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#其他) +问答模版: -### PHP 篇 +1、工作内容->实际问题->用到知识->设置问题->期望回答->评分表->面试评价 + +2、被安排充当面试官->网上找题库->题库(自己熟悉的)->八股文->筛选 + +### 1、PHP篇 -- [echo、print、print_r、var_dump 区别](./docs/03.PHP/QA.md#echoprintprint_rvar_dump-区别) -- [单引号和双引号的区别](./docs/03.PHP/QA.md#单引号和双引号的区别) -- [isset 和 empty 的区别](./docs/03.PHP/QA.md#isset-和-empty-的区别) - [static、self、$this 的区别](./docs/03.PHP/QA.md#staticselfthis-的区别) - [include、require、include_once、require_once 的区别](./docs/03.PHP/QA.md#includerequireinclude_oncerequire_once-的区别) - [数组处理函数](./docs/03.PHP/QA.md#常见数组函数) @@ -67,8 +124,11 @@ - [public、protected、private、final 区别](./docs/03.PHP/QA.md#publicprotectedprivatefinal-区别) - [客户端/服务端 IP 获取,了解代理透传 实际IP 的概念](./docs/03.PHP/QA.md#客户端服务端-ip-获取了解代理透传-实际ip-的概念) - [类的静态调用和实例化调用](./docs/03.PHP/QA.md#类的静态调用和实例化调用) +- [接口类和抽象类的区别](./docs/03.PHP/QA.md#接口类和抽象类的区别) - [PHP 不实例化调用方法](./docs/03.PHP/QA.md#php-不实例化调用方法) -- [php.ini 配置选项,ini_set 动态设置](./docs/03.PHP/QA.md#phpini-配置选项ini_set-动态设置) +- [php.ini 配置选项](./docs/03.PHP/QA.md#phpini-配置选项) +- [php-fpm.conf 配置](./docs/03.PHP/QA.md#php-fpmconf-配置) +- [502、504 错误产生原因及解决方式](./docs/03.PHP/QA.md#502504-错误产生原因及解决方式) - [如何返回一个301重定向](./docs/03.PHP/QA.md#如何返回一个301重定向) - [PHP 与 MySQL 连接方式](./docs/03.PHP/QA.md#php-与-mysql-连接方式) - [MySQL、MySQLi、PDO 区别](./docs/03.PHP/QA.md#mysqlmysqlipdo-区别) @@ -79,48 +139,15 @@ - [MVC 的理解](./docs/03.PHP/QA.md#mvc-的理解) - [主流 PHP 框架特点](./docs/03.PHP/QA.md#主流-php-框架特点) - [对象关系映射/ORM](./docs/03.PHP/QA.md#对象关系映射orm) +- [串行、并行、并发的区别](./docs/03.PHP/QA.md#串行、并行、并发的区别) +- [同步与异步的理解](./docs/03.PHP/QA.md#同步与异步的理解) +- [阻塞与非阻塞的理解](./docs/03.PHP/QA.md#阻塞与非阻塞的理解) +- [同步阻塞与非同步阻塞的理解](./docs/03.PHP/QA.md#同步阻塞与非同步阻塞的理解) +- [一条echo输出语句是如何执行的](./docs/php/一条echo输出语句是如何执行的.md) +- [FastCGI Process Manager](./docs/php/FastCGI-Process-Manager.md) +- [php支持哪些注释风格](./docs/php/php支持哪些注释风格.md) -### Web 篇 - -- [SEO 有哪些需要注意的](./docs/04.Web/QA.md#seo-有哪些需要注意的) -- [img 标签的 title 和 alt 有什么区别](./docs/04.Web/QA.md#img-标签的-title-和-alt-有什么区别) -- [CSS 选择器的分类](./docs/04.Web/QA.md#css-选择器的分类) -- [CSS sprite 是什么,有什么优缺点](./docs/04.Web/QA.md#css-sprite-是什么有什么优缺点) -- [display: none 与 visibility: hidden 的区别](./docs/04.Web/QA.md#display-none-与-visibility-hidden-的区别) -- [display: block 和 display: inline 的区别](./docs/04.Web/QA.md#display-block-和-display-inline-的区别) -- [CSS 文件、style 标签、行内 style 属性优先级](./docs/04.Web/QA.md#css-文件style-标签行内-style-属性优先级) -- [link 与 @import 的区别](./docs/04.Web/QA.md#link-与-import-的区别) -- [盒子模型](./docs/04.Web/QA.md#盒子模型) -- [容器包含若干浮动元素时如何清理(包含)浮动](./docs/04.Web/QA.md#容器包含若干浮动元素时如何清理包含浮动) -- [如何水平居中一个元素](./docs/04.Web/QA.md#如何水平居中一个元素) -- [如何竖直居中一个元素](./docs/04.Web/QA.md#如何竖直居中一个元素) -- [flex 与 CSS 盒子模型有什么区别](./docs/04.Web/QA.md#flex-与-css-盒子模型有什么区别) -- [Position 属性](./docs/04.Web/QA.md#position-属性) -- [PNG,GIF,JPG 的区别及如何选](./docs/04.Web/QA.md#pnggifjpg-的区别及如何选) -- [为什么把 JavaScript 文件放在 Html 底部](./docs/04.Web/QA.md#为什么把-javascript-文件放在-html-底部) -- [JavaScript 数据类型](./docs/04.Web/QA.md#javascript-数据类型) -- [JavaScript 操作 DOM 的方法有哪些](./docs/04.Web/QA.md#javascript-操作-dom-的方法有哪些) -- [JavaScript 字符串方法有哪些](./docs/04.Web/QA.md#javascript-字符串方法有哪些) -- [JavaScript 字符串截取方法有哪些?有什么区别](./docs/04.Web/QA.md#javascript-字符串截取方法有哪些有什么区别) -- [setTimeout 和 setInterval 的区别](./docs/04.Web/QA.md#settimeout-和-setinterval-的区别) -- [使用 new 操作符实例化一个对象的具体步骤](./docs/04.Web/QA.md#使用-new-操作符实例化一个对象的具体步骤) -- [如何实现 ajax 请求](./docs/04.Web/QA.md#如何实现-ajax-请求) -- [同源策略是什么](./docs/04.Web/QA.md#同源策略是什么) -- [如何解决跨域问题](./docs/04.Web/QA.md#如何解决跨域问题) -- [引起内存泄漏的操作有哪些](./docs/04.Web/QA.md#引起内存泄漏的操作有哪些) -- [闭包理解及应用](./docs/04.Web/QA.md#闭包理解及应用) -- [对 JavaScript 原型的理解](./docs/04.Web/QA.md#对-javascript-原型的理解) -- [对 JavaScript 模块化的理解](./docs/04.Web/QA.md#对-javascript-模块化的理解) -- [如何判断网页中图片加载成功或者失败](./docs/04.Web/QA.md#如何判断网页中图片加载成功或者失败) -- [如何实现懒加载](./docs/04.Web/QA.md#如何实现懒加载) -- [JSONP 原理](./docs/04.Web/QA.md#jsonp-原理) -- [Cookie 读写](./docs/04.Web/QA.md#cookie-读写) -- 从浏览器地址栏输入 URL 到显示页面的步骤 -- [Vue.js 双向绑定原理](./docs/04.Web/QA.md#vuejs-双向绑定原理) -- 如何进行网站性能优化 -- [渐进增强](./docs/04.Web/QA.md#渐进增强) - -### MySQL 篇 +### 2、存储篇 - [体系结构](./docs/05.MySQL/QA.md#体系结构) - [基础操作](./docs/05.MySQL/QA.md#基础操作) @@ -140,9 +167,34 @@ - [EXPLAIN 输出格式](./docs/05.MySQL/QA.md#explain-输出格式) - my.cnf 配置 - 慢查询 - -### Redis 篇 - +- [一条SQL查询语句是如何执行的](./docs/存储/一条SQL查询语句是如何执行的.md) +- [一条SQL更新语句是如何执行的](./docs/存储/一条SQL更新语句是如何执行的.md) +- [事务隔离:为什么你改了我还看不见?](./docs/存储/事务隔离-为什么你改了我还看不见.md) +- [深入浅出索引(上)](./docs/存储/深入浅出索引-上.md) +- [深入浅出索引(下)](./docs/存储/深入浅出索引-下.md) +- [全局锁和表锁:给表加个字段怎么有这么多阻碍](./docs/存储/全局锁和表锁-给表加个字段怎么有这么多阻碍.md) +- [行锁功过:怎么减少行锁对性能的影响](./docs/存储/行锁功过-怎么减少行锁对性能的影响.md) +- [事务到底是隔离的还是不隔离的](./docs/存储/事务到底是隔离的还是不隔离的.md) +- [普通索引和唯一索引,应该怎么选择](./docs/存储/普通索引和唯一索引,应该怎么选择.md) +- [MySQL为什么有时候会选错索引](./docs/存储/MySQL为什么有时候会选错索引.md) +- [怎么给字符串字段加索引](./docs/存储/怎么给字符串字段加索引.md) +- [为什么我的MySQL会抖一下](./docs/存储/为什么我的MySQL会抖一下.md) +- [为什么表数据删掉一半,表文件大小不变](./docs/存储/为什么表数据删掉一半,表文件大小不变.md) +- [count()这么慢,我该怎么办](./docs/存储/count()这么慢,我该怎么办.md) +- [order by是怎么工作的](./docs/存储/order-by是怎么工作的.md) +- [如何正确地显示随机消息](./docs/存储/如何正确地显示随机消息.md) +- [为什么这些SQL语句逻辑相同,性能却差异巨大](./docs/存储/为什么这些SQL语句逻辑相同,性能却差异巨大.md) +- [为什么我只查一行的语句,也执行这么慢](./docs/存储/为什么我只查一行的语句,也执行这么慢.md) +- [幻读是什么,幻读有什么问题](./docs/存储/幻读是什么,幻读有什么问题.md) +- [为什么我只改一行的语句,锁这么多](./docs/存储/为什么我只改一行的语句,锁这么多.md) +- [MySQL有哪些饮鸩止渴提高性能的方法](./docs/存储/MySQL有哪些饮鸩止渴提高性能的方法.md) +- [MySQL是怎么保证数据不丢的](./docs/存储/MySQL是怎么保证数据不丢的.md) +- [MySQL是怎么保证主备一致的](./docs/存储/MySQL是怎么保证主备一致的.md) +- [MySQL是怎么保证高可用的](./docs/存储/MySQL是怎么保证高可用的.md) +- [备库为什么会延迟好几个小时](./docs/存储/备库为什么会延迟好几个小时.md) +- [主库出问题了,从库怎么办](./docs/存储/主库出问题了,从库怎么办.md) +- [读写分离有哪些坑](./docs/存储/读写分离有哪些坑.md) +- [如何判断一个数据库是不是出问题了](./docs/存储/如何判断一个数据库是不是出问题了.md) - [Redis 介绍](./docs/06.Redis/QA.md#redis-介绍) - [Redis 特点](./docs/06.Redis/QA.md#redis-特点) - [Redis 支持哪些数据结构](./docs/06.Redis/QA.md#redis-支持哪些数据结构) @@ -159,29 +211,44 @@ - redis.conf 配置 - 慢查询 -### Linux 篇 - -- [Linux 目录结构](./docs/07.Linux/QA.md#linux-目录结构) -- [Linux 基础](./docs/07.Linux/QA.md#linux-基础) -- [命令与文件查找](./docs/07.Linux/QA.md#命令与文件查找) -- [数据流重定向](./docs/07.Linux/QA.md#数据流重定向) -- [sed](./docs/07.Linux/QA.md#sed) -- [awk](./docs/07.Linux/QA.md#awk) -- [计划任务](./docs/07.Linux/QA.md#计划任务) -- [Vim](./docs/07.Linux/QA.md#vim) -- [负载查看](./docs/07.Linux/QA.md#负载查看) -- [进程、线程、协程区别](./docs/07.Linux/QA.md#进程线程协程区别) - -### 安全篇 - -- [跨站脚本攻击(XSS)](./docs/08.安全/QA.md#跨站脚本攻击xss) -- [跨站点请求伪造(CSRF)](./docs/08.安全/QA.md#跨站点请求伪造csrf) -- [SQL 注入](./docs/08.安全/QA.md#sql-注入) -- [应用层拒绝服务攻击](./docs/08.安全/QA.md#应用层拒绝服务攻击) -- [PHP 安全](./docs/08.安全/QA.md#php-安全) -- [伪随机数和真随机数](./docs/08.安全/QA.md#伪随机数和真随机数) - -### 设计模式篇 +### 3、网络篇 + +- [计算机网络体系结构](./docs/01.网络.md#1-计算机网络体系结构) +- [UDP 的主要特点](./docs/01.网络.md#2-udp-的主要特点) +- [TCP 的主要特点](./docs/01.网络.md#3-tcp-的主要特点) +- [简述三报文握手建立 TCP 连接](./docs/01.网络.md#4-简述三报文握手建立-tcp-连接) +- [建立 TCP 连接为什么最后还要发送确认](./docs/01.网络.md#5-建立-tcp-连接为什么最后还要发送确认) +- [简述 TCP 连接的释放](./docs/01.网络.md#6-简述-tcp-连接的释放) +- [TIME-WAIT 是什么,为什么必须等待 2MLS](./docs/01.网络.md#7-time-wait-是什么为什么必须等待-2mls) +- [TCP 粘包问题](./docs/01.网络.md#8-tcp-粘包问题) +- [UDP、TCP 区别,适用场景](./docs/01.网络.md#9-udptcp-区别适用场景) +- [建立 socket 需要哪些步骤](./docs/01.网络.md#10-建立-socket-需要哪些步骤) +- [DNS 主要作用是什么](./docs/01.网络.md#11-dns-主要作用是什么) +- [HTTP 报文组成](./docs/01.网络.md#12-http-报文组成) +- [HTTP 状态码](./docs/01.网络.md#13-http-状态码) +- [常见的 HTTP 方法](./docs/01.网络.md#14-常见的-http-方法) +- [GET 与 POST 请求方式区别](./docs/01.网络.md#15-get-与-post-请求方式区别) +- [HTTP 优缺点](./docs/01.网络.md#16-http-优缺点) +- [HTTPS 通信原理](./docs/01.网络.md#17-https-通信原理) +- [HTTP 2.0](./docs/01.网络.md#18-http-20) +- [WebSocket](./docs/01.网络.md#19-websocket) +- [IPv6 与 IPv4 有什么变化](./docs/01.网络.md#20-ipv6-与-ipv4-有什么变化) +- [什么是心跳机制](./docs/01.网络.md#21-什么是心跳机制) +- [什么是长连接](./docs/01.网络.md#22-什么是长连接) + +### 4、数据结构与算法篇 + +- [概述](./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-经典算法题) + +### 5、设计模式篇 - [什么是设计模式](./docs/09.设计模式/QA.md#什么是设计模式) - [如何理解框架](./docs/09.设计模式/QA.md#如何理解框架) @@ -198,7 +265,22 @@ - [控制反转](./docs/09.设计模式/QA.md#控制反转) - [依赖注入](./docs/09.设计模式/QA.md#依赖注入) -### 架构篇 +### 6、服务器篇 + +- [Linux 目录结构](./docs/07.Linux/QA.md#linux-目录结构) +- [Linux 基础](./docs/07.Linux/QA.md#linux-基础) +- [命令与文件查找](./docs/07.Linux/QA.md#命令与文件查找) +- [数据流重定向](./docs/07.Linux/QA.md#数据流重定向) +- [sed](./docs/07.Linux/QA.md#sed) +- [awk](./docs/07.Linux/QA.md#awk) +- [计划任务](./docs/07.Linux/QA.md#计划任务) +- [Vim](./docs/07.Linux/QA.md#vim) +- [负载查看](./docs/07.Linux/QA.md#负载查看) +- Linux 内存管理 +- [进程、线程、协程区别](./docs/07.Linux/QA.md#进程线程协程区别) +- 进程间通信与信号机制 + +### 7、架构篇 - [OAuth 2.0](./docs/10.架构/QA.md#oauth-20) - [单点登录](./docs/10.架构/QA.md#单点登录) @@ -223,6 +305,58 @@ - 服务降级 - 语言对比 +### 8、安全篇 + +- [跨站脚本攻击(XSS)](./docs/08.安全/QA.md#跨站脚本攻击xss) +- [跨站点请求伪造(CSRF)](./docs/08.安全/QA.md#跨站点请求伪造csrf) +- [SQL 注入](./docs/08.安全/QA.md#sql-注入) +- [应用层拒绝服务攻击](./docs/08.安全/QA.md#应用层拒绝服务攻击) +- [PHP 安全](./docs/08.安全/QA.md#php-安全) +- [伪随机数和真随机数](./docs/08.安全/QA.md#伪随机数和真随机数) + +### 9、面试篇 + +### 10、web篇 + + +- [SEO 有哪些需要注意的](./docs/04.Web/QA.md#seo-有哪些需要注意的) +- [img 标签的 title 和 alt 有什么区别](./docs/04.Web/QA.md#img-标签的-title-和-alt-有什么区别) +- [CSS 选择器的分类](./docs/04.Web/QA.md#css-选择器的分类) +- [CSS sprite 是什么,有什么优缺点](./docs/04.Web/QA.md#css-sprite-是什么有什么优缺点) +- [display: none 与 visibility: hidden 的区别](./docs/04.Web/QA.md#display-none-与-visibility-hidden-的区别) +- [display: block 和 display: inline 的区别](./docs/04.Web/QA.md#display-block-和-display-inline-的区别) +- [CSS 文件、style 标签、行内 style 属性优先级](./docs/04.Web/QA.md#css-文件style-标签行内-style-属性优先级) +- [link 与 @import 的区别](./docs/04.Web/QA.md#link-与-import-的区别) +- [盒子模型](./docs/04.Web/QA.md#盒子模型) +- [容器包含若干浮动元素时如何清理(包含)浮动](./docs/04.Web/QA.md#容器包含若干浮动元素时如何清理包含浮动) +- [如何水平居中一个元素](./docs/04.Web/QA.md#如何水平居中一个元素) +- [如何竖直居中一个元素](./docs/04.Web/QA.md#如何竖直居中一个元素) +- [flex 与 CSS 盒子模型有什么区别](./docs/04.Web/QA.md#flex-与-css-盒子模型有什么区别) +- [Position 属性](./docs/04.Web/QA.md#position-属性) +- [PNG,GIF,JPG 的区别及如何选](./docs/04.Web/QA.md#pnggifjpg-的区别及如何选) +- [为什么把 JavaScript 文件放在 Html 底部](./docs/04.Web/QA.md#为什么把-javascript-文件放在-html-底部) +- [JavaScript 数据类型](./docs/04.Web/QA.md#javascript-数据类型) +- [JavaScript 操作 DOM 的方法有哪些](./docs/04.Web/QA.md#javascript-操作-dom-的方法有哪些) +- [JavaScript 字符串方法有哪些](./docs/04.Web/QA.md#javascript-字符串方法有哪些) +- [JavaScript 字符串截取方法有哪些?有什么区别](./docs/04.Web/QA.md#javascript-字符串截取方法有哪些有什么区别) +- [setTimeout 和 setInterval 的区别](./docs/04.Web/QA.md#settimeout-和-setinterval-的区别) +- [使用 new 操作符实例化一个对象的具体步骤](./docs/04.Web/QA.md#使用-new-操作符实例化一个对象的具体步骤) +- [如何实现 ajax 请求](./docs/04.Web/QA.md#如何实现-ajax-请求) +- [同源策略是什么](./docs/04.Web/QA.md#同源策略是什么) +- [如何解决跨域问题](./docs/04.Web/QA.md#如何解决跨域问题) +- [引起内存泄漏的操作有哪些](./docs/04.Web/QA.md#引起内存泄漏的操作有哪些) +- [闭包理解及应用](./docs/04.Web/QA.md#闭包理解及应用) +- [对 JavaScript 原型的理解](./docs/04.Web/QA.md#对-javascript-原型的理解) +- [对 JavaScript 模块化的理解](./docs/04.Web/QA.md#对-javascript-模块化的理解) +- [如何判断网页中图片加载成功或者失败](./docs/04.Web/QA.md#如何判断网页中图片加载成功或者失败) +- [如何实现懒加载](./docs/04.Web/QA.md#如何实现懒加载) +- [JSONP 原理](./docs/04.Web/QA.md#jsonp-原理) +- [Cookie 读写](./docs/04.Web/QA.md#cookie-读写) +- 从浏览器地址栏输入 URL 到显示页面的步骤 +- [Vue.js 双向绑定原理](./docs/04.Web/QA.md#vuejs-双向绑定原理) +- 如何进行网站性能优化 +- [渐进增强](./docs/04.Web/QA.md#渐进增强) + ## 为何要写这个 从事软件开发,已经接近五个年头了,去年面试中,发现自己依然处于尴尬的位置。简单重复,缺乏挑战的工作,已经没有多大吸引力了,优秀的平台,面试缺屡次碰壁。人上年纪之后,思维敏感度、记忆力都明显有所下滑。 diff --git "a/docs/01.\347\275\221\347\273\234/QA.md" "b/docs/01.\347\275\221\347\273\234.md" similarity index 72% rename from "docs/01.\347\275\221\347\273\234/QA.md" rename to "docs/01.\347\275\221\347\273\234.md" index 9408fa4..1240a51 100644 --- "a/docs/01.\347\275\221\347\273\234/QA.md" +++ "b/docs/01.\347\275\221\347\273\234.md" @@ -2,9 +2,9 @@ ## 网络篇 -### 计算机网络体系结构 +### 1. 计算机网络体系结构 -![计算机网络体系结构](./assets/网络体系结构-02.png) +![计算机网络体系结构](./assets/network-architecture-02.png) #### 各层作用 @@ -14,9 +14,9 @@ - 数据链路层:将网络层交下来的 IP 数据报组装成帧,并在两个相邻结点间的链路上传送 - 物理层:利用物理媒体以`比特`形式传送数据 -拓展阅读 [《计算机网络体系结构》](./01.计算机网络体系结构.md) +拓展阅读 [《计算机网络体系结构》](./01.网络/01.计算机网络体系结构.md) -### UDP 的主要特点 +### 2. UDP 的主要特点 - UDP 是`无连接的`,即发送数据之前不需要建立连接(发送数据结束时也没有连接可释放),减少了开销和发送数据之前的时延 - UDP 使用`尽最大努力交付`,即不保证可靠交付,主机不需要维持复杂的连接状态表 @@ -25,9 +25,9 @@ - UDP 支持一对一、一对多、多对一和多对多的交互通信 - UDP 的`首部开销小`,只有8个字节,比 TCP 的20个字节的首部要短 -拓展阅读 [《用户数据报协议 UDP》](./02.用户数据报协议UDP.md) +拓展阅读 [《用户数据报协议 UDP》](./01.网络/02.用户数据报协议UDP.md) -### TCP 的主要特点 +### 3. TCP 的主要特点 - TCP 是`面向连接的运输层协议`。应用程序在使用 TCP 协议之前,必须先建立 TCP 连接。在传送数据完毕后,必须释放已经建立的 TCP 连接 - 每一条 TCP 连接只能有两个`端点`,每一条 TCP 连接只能是`点对点`的(一对一) @@ -35,23 +35,24 @@ - TCP 提供`全双工通信`。TCP 允许通信双方的应用进程在任何时候都能发送数据。TCP 连接的两端都设有发送缓存和接受缓存,用来临时存放双向通信的数据 - `面向字节流`。TCP 中的“流”指的是`流入到进程或从进程流出的字节序列` -拓展阅读 [《传输控制协议 TCP》](./03.传输控制协议TCP.md) +拓展阅读 [《传输控制协议 TCP》](./01.网络/03.传输控制协议TCP.md) -### 简述三报文握手建立 TCP 连接 +### 4. 简述三报文握手建立 TCP 连接 -- 服务器进程先创建传输控制块 TCB,并处于监听状态,等待客户端的连接请求 -- 客户端创建传输控制块 TCB,并向服务器发出连接请求报文段 -- 服务器收到连接请求报文段后,如同意建立连接,则发送确认报文段 -- 客户端进程收到服务器的确认报文段后,立即回复确认报文段,并进入已建立连接状态 -- 服务器收到确认报文段之后,也进入已建立连接状态 +- 服务器进程先创建传输控制块 TCB,并处于监听状态,等待客户端的连接请求;此时状态为LISTEN +- 客户端创建传输控制块 TCB,并向服务器发出连接请求报文段SYN,此时状态为SYN-SEND +- 服务器收到连接请求报文段后,如同意建立连接,则发送确认报文段ACK,此时状态为SYN-RECV,并且客户端链接进入半链接队列,系统参数/proc/sys/net/ipv4/tcp_max_syn_backlog +- 客户端进程收到服务器的确认报文段后,立即回复确认报文段ACK,并进入已建立连接状态,此时状态为ESTABLISHED +- 服务器收到确认报文段之后,也进入已建立连接状态,此时状态为ESTABLISHED,并且客户端链接进入全连接队列,系统参数/proc/sys/net/core/somaxconn > 传输控制块 TCB(Transmission Control Block)存储了每一个连接中的一些重要信息 -### 建立 TCP 连接为什么最后还要发送确认 +### 5. 建立 TCP 连接为什么最后还要发送确认 这主要是为了防止已失效的连接请求报文段突然又传到了 TCP 服务器,避免产生错误 +简述为了保证数据的正确性和顺序 -### 简述 TCP 连接的释放 +### 6. 简述 TCP 连接的释放 - 客户端应用进程发出连接释放报文段,并停止再发送数据,进入 FIN-WAIT-1(终止等待1)状态,等待服务器确认 - 服务器收到连接释放报文段后即发出确认,进入 CLOSE-WAIT(关闭等待)状态,服务器若发送数据,客户端扔要接收 @@ -60,11 +61,11 @@ - 客户端收到连接释放报文段后,发出确认,进入 TIME-WAIT(时间等待)状态,经过时间等待计时器设置的时间 2MSL 后,进入 CLOSED(关闭) 状态 - 服务器收到客户端报文段后,进入 CLOSED 状态 -### TIME-WAIT 是什么,为什么必须等待 2MLS +### 7. TIME-WAIT 是什么,为什么必须等待 2MLS TIME-WAIT 是一种 TCP 状态。等待 2MLS 可以保证客户端最后一个报文段能够到达服务器,如果未到达,服务器则会超时重传连接释放报文段,使得客户端、服务器都可以正常进入到 CLOSE(关闭) 状态 -### TCP 粘包问题 +### 8. TCP 粘包问题 #### 粘包问题 @@ -77,9 +78,9 @@ TIME-WAIT 是一种 TCP 状态。等待 2MLS 可以保证客户端最后一个 - 在每条消息的头部加一个长度字段,这恐怕是最常见的做法 - 利用消息本身的格式来分包,例如 XML 格式的消息中 ``...`` 的配对,或者 JSON 格式中的 { ... } 的配对。解析这种消息格式通常会用到状态机(state machine) -拓展阅读 [《TCP粘包拆包》](./04.TCP粘包拆包.md) +拓展阅读 [《TCP粘包拆包》](./01.网络/04.TCP粘包拆包.md) -### UDP、TCP 区别,适用场景 +### 9. UDP、TCP 区别,适用场景 |对比项|UDP|TCP| |-|-|-| @@ -100,11 +101,11 @@ TIME-WAIT 是一种 TCP 状态。等待 2MLS 可以保证客户端最后一个 #### TCP 适用场景 -文件传输(FTP HTTP 对数据准确性要求较高,速度可以相对慢) -发送或接收邮件(POP IMAP SMTP 对数据准确性要求高,非紧急应用) -远程登录(telnet SSH 对数据准确性有要求,有连接的概念) +- 文件传输(FTP HTTP 对数据准确性要求较高,速度可以相对慢) +- 发送或接收邮件(POP IMAP SMTP 对数据准确性要求高,非紧急应用) +- 远程登录(telnet SSH 对数据准确性有要求,有连接的概念) -### 建立 socket 需要哪些步骤 +### 10. 建立 socket 需要哪些步骤 - 创建 socket - 绑定 socket 到指定地址和端口 @@ -112,7 +113,7 @@ TIME-WAIT 是一种 TCP 状态。等待 2MLS 可以保证客户端最后一个 - 读取客户端输入 - 关闭 socket -### DNS 主要作用是什么 +### 11. DNS 主要作用是什么 计算机既可以被赋予 IP 地址,也可以被赋予主机名和域名。用户通常使用主机名或域名来访问对方的计算机,而不是直接通过 IP 地址访问 @@ -120,11 +121,11 @@ TIME-WAIT 是一种 TCP 状态。等待 2MLS 可以保证客户端最后一个 为了解决上述问题,DNS 服务应运而生。DNS 协议提供通过域名查找 IP 地址,或逆向从 IP 地址反查域名的服务 -### HTTP 报文组成 +### 12. HTTP 报文组成 HTTP 报文是由简单字符串组成,HTTP 报文都是纯文本,不是二进制代码,可以很方便地对其进行读写 -![HTTP报文](./assets/http-message.png) +![HTTP报文](./assets/network-http-message.png) 从客户端发往服务器的 HTTP 报文称为`请求报文`(request message)。从服务器发往客户端的报文称为`响应报文`(response message)。HTTP 请求和响应报文的格式很类似 @@ -134,7 +135,7 @@ HTTP 报文组成部分 - 首部字段:起始行后面有零个或多个首部字段。每个首部字段都包含一个名字和一个值 - 主体:空行之后就是可选的报文主体了,其中包含了所有类型的数据 -### HTTP 状态码 +### 13. HTTP 状态码 > HTTP 状态码用来告诉客户端,发生了什么事情,状态码位于响应的起始行中 @@ -152,81 +153,77 @@ HTTP 报文组成部分 |状态码|原因短语|含义|考察概率| |-|-|-|-| -|100|Continue|收到了请求的初始部分,请客户端继续|| -|101|Switching Protocols|正在将协议切换成客户端指定协议|| |200|OK|请求没有问题|***| -|201|Created|用于创建服务器对象的请求|| -|202|Accepted|请求已接收,服务器还未执行操作|| -|203|Non-Authoritative Information|实体首部包含信息来自资源副本|| -|204|No Content|响应报文中没有实体的主体部分|| -|205|Reset Content|告知浏览器清除 HTML 表单元素|| |206|Partial Content|部分或 Range(范围) 请求|*| -|300|Multiple Choices|请求指向多个资源的链接|| |301|Moved Permanently|在请求的链接被移除时使用|**| |302|Found|在请求临时的链接使用|**| -|303|See Other|告知使用另外一个链接来获取资源|| |304|Not Modified|资源未被修改可使用旧资源|**| -|305|Use Proxy|必须使用代理来访问资源|| |307|Temporary Redirect|在请求临时的链接使用|**| |400|Bad Request|告知客户端发送了错误请求|***| -|401|Unauthorized|获取资源许先进行认证|| |403|Forbidden|请求被服务器拒绝|***| |404|Not Found|无法找到所请求的 URL|***| -|405|Method Not Allowed|不支持该请求方法|| -|406|Not Acceptable|无可接受实体|| -|408|Request Timeout|完成请求耗时太长服务器关闭连接|| -|409|Conflict|请求可能在资源上引发冲突|| -|413|Request entiry too large|请求实体过大| +|413|Request entiry too large|请求实体过大|*| |500|Internal Server Error|服务器遇到错误|***| -|501|Not Implemented|请求超过服务器的能力范围|| |502|Bad Gateway|代理或网关错误(无法连接到其父网关)|***| |503|Service Unavailable|无法为请求提供服务|***| |504|Gateway Timeout|代理或网关超时(等待另一服务器响应超时)|***| -拓展阅读 [《HTTP状态码》](./05.HTTP状态码.md) +拓展阅读 [《HTTP状态码》](./01.网络/05.HTTP状态码.md) -### 常见的 HTTP 方法 +拓展阅读 [《5xx系列错误》](../03.PHP/QA.md#502504-错误产生原因及解决方式) -![HTTP方法](./assets/http-method.png) +### 14. 常见的 HTTP 方法 -拓展阅读 [《HTTP方法详解》](./06.HTTP方法详解.md) +![HTTP方法](./assets/network-http-method.png) -### GET 与 POST 请求方式区别 +拓展阅读 [《HTTP方法详解》](./01.网络/06.HTTP方法详解.md) + +### 15. GET 与 POST 请求方式区别 |GET|POST| |-|-| |后退按钮/刷新无害|数据会被重新提交| -|数据长度限制/URL长度2048字符|长度无限制| +|数据长度限制/URL长度2048字符|长度无限制(协议不限制;实际上受nginx和PHP的限制,php还会限制post报文变量的个数)| |数据可见/安全性差|不可见/更安全| |可以被缓存|不可以被缓存| |书签可收藏|书签不可收藏| +|产生一个TCP数据包| 产生两个TCP数据包 | -### HTTP 优缺点 +### 16. HTTP 优缺点 基于应用级的接口,使用方便 传输速度慢,数据包大;如实现实时交互,服务器性能压力大;数据传输安全性差 -### HTTPS 通信原理 - -![HTTPS通信原理](./assets/https.png) +### 17. HTTPS 通信原理 -拓展阅读 [《HTTPS细节介绍》](./07.HTTPS细节介绍.md) +![HTTPS通信原理](./assets/network-https.png) -拓展阅读 [《SSL/TLS协议运行机制的概述》](./08.SSL-TLS协议运行机制的概述.md) +拓展阅读 [《HTTPS细节介绍》](./01.网络/07.HTTPS细节介绍.md) -### HTTP 2.0 +### 18. HTTP 2.0 多路复用、客户端拉拽/服务器推送、流量控制、WebSocket -### IPv6 与 IPv4 有什么变化 +### 19. WebSocket + +WebSocket 是一种通信协议,定义了一个全双工通信信道,仅通过 Web 上的一个 Socket 即可进行通信 + +#### 主要特点 + +- 推送功能:支持由服务器向客户端推送数据的推送功能 +- 减少通信量:只要建立起 WebSocket 连接,就希望一直保持连接状态 + +![websocket](./assets/network-websocket.png) + +### 20. IPv6 与 IPv4 有什么变化 更大的地址空间、扩展的地址层次结构、灵活的首部格式、改进的选项、允许协议继续扩充、支持资源的预分配 -### 什么是心跳机制 +### 21. 什么是心跳机制 心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制 -### 什么是长连接 +### 22. 什么是长连接 -长连接,指在一个连接上可以连续发送多个数据包,在连接保持期间,如果没有数据包发送,需要双方发链路检测包 \ No newline at end of file +长连接,指在一个连接上可以连续发送多个数据包,在连接保持期间,如果没有数据包发送,需要双方发链路检测包 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" old mode 100644 new mode 100755 index 823cd2a..1f18b11 --- "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" @@ -36,7 +36,7 @@ TCP/IP 常被称为是`事实上的国际标准` 对于非常复杂的计算机网络协议,其结构应该是层次式的 -![网络体系结构-图1](./assets/网络体系结构-01.png) +![网络体系结构-图1](./assets/network-architecture-01.png) **分层可以带来很多好处** @@ -70,7 +70,7 @@ TCP/IP 常被称为是`事实上的国际标准` OSI 的七层协议体系结构的概念清楚,理论也较完整,但它既复杂又不实用。TCP/IP 体系结构则不同,但它现在却得到了非常广泛的应用。TCP/IP 是一个四层的体系结构。在学习计算机网络的原理时往往采用折中的办法,即综合 OSI 和 TCP/IP 的优点,采用一种只有五层协议的体系结构,这样既简洁又能将概念阐述清楚 -![网络体系结构-图2](./assets/网络体系结构-02.png) +![网络体系结构-图2](./assets/network-architecture-02.png) ### 各层作用 @@ -86,7 +86,7 @@ OSI 的七层协议体系结构的概念清楚,理论也较完整,但它既 - 运输层主要协议:传输控制协议 TCP、用户数据报协议 UDP - 在 TCP/IP 体系中,由于网络层使用 IP 协议,因此分组也叫 `IP 数据报`,或简称为数据报 -![网络体系结构-图3](./assets/网络体系结构-03.png) +![网络体系结构-图3](./assets/network-architecture-03.png) ## 实体、协议、服务和服务访问点 @@ -98,7 +98,7 @@ OSI 的七层协议体系结构的概念清楚,理论也较完整,但它既 协议是“水平的”,即协议是控制对等实体之间通信的规则。但服务是“垂直的”,即服务是由下层向上层通过层间接口提供的 -![网络体系结构-图4](./assets/网络体系结构-04.png) +![网络体系结构-图4](./assets/network-architecture-04.png) ### 计算机网络协议特点 @@ -110,16 +110,16 @@ OSI 的七层协议体系结构的概念清楚,理论也较完整,但它既 TCP/IP 的体系结构比较简单,只有四层 -![网络体系结构-图5](./assets/网络体系结构-05.png) +![网络体系结构-图5](./assets/network-architecture-05.png) -应当指出,技术的发展并不是遵循严格的 OSI 分层概念。实际上现在的互联网使用的 TCP/IP 体系结构有时已经演变成为图1-23所示的那样,即某些应用程序可以直接使用 IP 层,或甚至直接使用最下面的网络接口层 +应当指出,技术的发展并不是遵循严格的 OSI 分层概念。实际上现在的互联网使用的 TCP/IP 体系结构有时已经演变成为下图所示的那样,即某些应用程序可以直接使用 IP 层,或甚至直接使用最下面的网络接口层 -![网络体系结构-图6](./assets/网络体系结构-06.png) +![网络体系结构-图6](./assets/network-architecture-06.png) 还有一种方法,就是分层次画出具体的协议表示 TCP/IP 协议族,它的特点是上下两头大而中间小:应用层和网络接口层都有多种协议,而中间的 IP 层很小,上层的各种协议都向下汇聚到一个 IP 协议中 -TCP/IP 协议可以为各式各样的应用提供服务,同时 TCP/IP 协议也 允许 IP 协议在各式各样的网络构成的互联网上运行。IP 协议在互联网中充当着核心的作用 +TCP/IP 协议可以为各式各样的应用提供服务,同时 TCP/IP 协议也允许 IP 协议在各式各样的网络构成的互联网上运行。IP 协议在互联网中充当着核心的作用 -![网络体系结构-图7](./assets/网络体系结构-07.png) +![网络体系结构-图7](./assets/network-architecture-07.png) **《计算机网络体系结构》 原文链接:[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" old mode 100644 new mode 100755 index 69e7d92..77d8e6f --- "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" @@ -10,7 +10,7 @@ 2. UDP 使用`尽最大努力交付`,即不保证可靠交付,主机不需要维持复杂的连接状态表 3. UDP 是`面向报文`的,发送方的 UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP 层。UDP 对应用层交下来的报文,既不合并,也不拆分,而是`保留这些报文的边界` -![UDP协议-图1](./assets/udp-01.png) +![UDP协议-图1](./assets/network-udp-01.png) 4. UDP `没有拥塞控制`,网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的 5. UDP 支持一对一、一对多、多对一和多对多的交互通信 @@ -32,13 +32,13 @@ - `长度` UDP 用户数据报的长度,其最小值是8(仅有首部) - `检验和` 检测 UDP 用户数据报在传输中是否有错。有错就丢弃 -![UDP协议-图2](./assets/udp-02.png) +![UDP协议-图2](./assets/network-udp-02.png) ### 端口分用 当运输层从 IP 层收到 UDP 数据报时,就根据首部中的目的端口,把 UDP 数据报通过相应的端口,上交最后的终点——应用进程 -![UDP协议-图3](./assets/udp-03.png) +![UDP协议-图3](./assets/network-udp-03.png) 如果接受方 UDP 发现收到的报文中的目的端口号不正确(即不存在对应于该端口号的应用程序),就丢弃该报文,并由网际控制报文协议 ICMP 发送“端口不可达”差错报文给发送方 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" old mode 100644 new mode 100755 index b3301d8..8d828c9 --- "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" @@ -20,7 +20,7 @@ TCP 不保证接收方应用程序所收到的数据块和发送方应用程序 接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。接收方的应用程序必须有能力识别收到的字节流,把它还原成有意义的应用层数据 -![TCP协议-图1](./assets/tcp-01.png) +![TCP协议-图1](./assets/network-tcp-01.png) TCP 和 UDP 在发送报文时采用的方式完全不同。TCP 并不关心应用进程一次把多长的报文发送到 TCP 的缓存中,而是根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP 发送的报文长度是应用进程给出的)。如果应用进程传送到 TCP 缓存的数据块太长,TCP 就可以把它划分短一些再传送。如果应用进程一次只发来一个字节,TCP 也可以等待积累有足够多的字节后再构成报文段发送出去 @@ -65,7 +65,7 @@ TCP 连接就是由协议软件所提供的一种抽象。`TCP 连接的端口 #### 无差错情况 -![TCP协议-图2](./assets/tcp-02.png) +![TCP协议-图2](./assets/network-tcp-02.png) #### 出现差错 @@ -77,7 +77,7 @@ TCP 连接就是由协议软件所提供的一种抽象。`TCP 连接的端口 #### 确认丢失和确认迟到 -![TCP协议-图3](./assets/tcp-03.png) +![TCP协议-图3](./assets/network-tcp-03.png) 使用上述的确认和重传机制,我们就可以`在不可靠的传输网络上实现可靠的通信` @@ -87,17 +87,17 @@ TCP 连接就是由协议软件所提供的一种抽象。`TCP 连接的端口 停止等待协议的优点是简单,但缺点是信道利用率太低 -![TCP协议-图4](./assets/tcp-04.png) +![TCP协议-图4](./assets/network-tcp-04.png) 为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用`流水线传输`。流水线传输就是发送方可连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认。这样可使信道上一直有数据不间断地在传送。这种传输方式可以获得很高的信道利用率 -![TCP协议-图5](./assets/tcp-05.png) +![TCP协议-图5](./assets/network-tcp-05.png) ### 连续 ARQ 协议 位于发送窗口内的5个分组都可以连续发送出去,而不需要等待对方的确认。可以提高信道利用率 -![TCP协议-图6](./assets/tcp-06.png) +![TCP协议-图6](./assets/network-tcp-06.png) 接收方一般都是采用`累积确认`的方式。接收方不需要对收到的分组逐个发送确认,而是在收到几个分组后,`对按序到达的最后一个分组发送确认` @@ -107,7 +107,7 @@ TCP 连接就是由协议软件所提供的一种抽象。`TCP 连接的端口 TCP 虽然是面向字节流的,但 TCP 传送的数据单元却是报文段。一个 TCP 报文段分为首部和数据两部分。TCP 报文段首部的前20个字节是固定的,后面有4n字节是根据需要而增加的选项(n是整数)。因此 TCP 首部的最小长度是20字节 -![TCP协议-图7](./assets/tcp-07.png) +![TCP协议-图7](./assets/network-tcp-07.png) ### 首部字段 @@ -139,7 +139,7 @@ TCP 虽然是面向字节流的,但 TCP 传送的数据单元却是报文段 TCP 的滑动窗口是以字节为单位的。假定 A 收到了 B `发来`的确认报文段,其中窗口是20字节,而确认号是31(这表明 B 期望收到的下一个序号是31,而序号30为止的数据已经收到了)。根据这两个数据,A 就构造出自己的发送窗口 -![TCP协议-图8](./assets/tcp-08.png) +![TCP协议-图8](./assets/network-tcp-08.png) 发送窗口标识:在没有收到 B 的确认的情况下,A 可以连续把窗口内的数据都发送出去。凡是已经发送出去的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用 @@ -149,35 +149,35 @@ TCP 的滑动窗口是以字节为单位的。假定 A 收到了 B `发来`的 发送窗口前沿通常是不断向前移动,但也有可能不动。这对应于两种情况: -- 一是没有收到信的确认,对应通知的窗口大小也不变 +- 一是没有收到新的确认,对应通知的窗口大小也不变 - 二是收到了新的窗口单对方通知的窗口缩小了,使得发送窗口前沿正好不动 -发送窗口前沿也有可能`向后收缩`。这发生在对方通知的窗口缩小了。但 TCP 的标准`强烈不赞成这样做`。因为很可能发送方在收到这个通知以前已经发生了窗口中的许多数据,现在又要收缩窗口,不让发送这些数据,这样就会产生一些错误 +发送窗口前沿也有可能`向后收缩`。这发生在对方通知的窗口缩小了。但 TCP 的标准`强烈不赞成这样做`。因为很可能发送方在收到这个通知以前已经发送了窗口中的许多数据,现在又要收缩窗口,不让发送这些数据,这样就会产生一些错误 -![TCP协议-图9](./assets/tcp-09.png) +![TCP协议-图9](./assets/network-tcp-09.png) 要描述一个发送窗口的状态需要三个指针:P1,P2,P3。指针都指向字节的序号。这三个指针指向的几个部分的意义如下: - 小于 P1 的是已发送并已收到确认的部分,而大于 P3 的是不允许发送的部分 -- P3 - P1 = A 的发送窗口 +- 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 +现在假定 B 收到了序号为31的数据,并把序号为31\~33的数据交付主机,然后 B 删除这些数据。接着把接收窗口向前移动3个序号,同时给 A 发送确认,其中窗口值仍为20,但确认号是34。这表明 B 已经收到了到序号33为止的数据。B 还收到了序号为37,38和40的数据,但这些都没有按序到达,只能先暂存在接收窗口中。A 收到 B 的确认后,就可以把发送窗口向前滑动3个序号,但指针 P2 不动。现在 A 的可用窗口增大了,可发送的序号范围是42\~53 -![TCP协议-图10](./assets/tcp-10.png) +![TCP协议-图10](./assets/network-tcp-10.png) -A 在继续发送完序号42\~53的数据后,指针 P2 向前移动和 P3 重合。发送窗口内的序号都已用完,但还没有再收到确认。由于 A 的发送窗口已满,可用窗口已减小到零,因此必须停止发送。发送窗口内所有的数据都已正确到达 B,B 也早已发出了确认。但所有这些确认都滞留在网络中。在没有收到 B 的确认时,A 不能猜测:“或许 B 收到了吧!”为了保证可靠传输,A 只能认为 B 还没有收到这些数据。于是,A 在经过一段时间后(由超时计时器控制)就重传这部分数据,重新设置超时计时器,知道收到 B 的确认为止。如果 A 收到确认号落在发送窗口内,那么 A 就可以发送窗口继续向前滑动,并发送新的数据 +A 在继续发送完序号42\~53的数据后,指针 P2 向前移动和 P3 重合。发送窗口内的序号都已用完,但还没有再收到确认。由于 A 的发送窗口已满,可用窗口已减小到零,因此必须停止发送。发送窗口内所有的数据都已正确到达 B,B 也早已发出了确认。但所有这些确认都滞留在网络中。在没有收到 B 的确认时,A 不能猜测:”或许 B 收到了吧!“为了保证可靠传输,A 只能认为 B 还没有收到这些数据。于是,A 在经过一段时间后(由超时计时器控制)就重传这部分数据,重新设置超时计时器,直到收到 B 的确认为止。如果 A 收到确认号落在发送窗口内,那么 A 就可以发送窗口继续向前滑动,并发送新的数据 -![TCP协议-图11](./assets/tcp-11.png) +![TCP协议-图11](./assets/network-tcp-11.png) #### 缓存和窗口 发送方维持的发送缓存和发送窗口,以及接收方维持的接收缓存和接收窗口 -![TCP协议-图12](./assets/tcp-12.png) +![TCP协议-图12](./assets/network-tcp-12.png) 发送缓存用来暂时存放: @@ -203,7 +203,7 @@ A 在继续发送完序号42\~53的数据后,指针 P2 向前移动 TCP 的发送方在规定的时间内没有收到确认就要重传已发送的报文段。这种重传的概念是很简单的,但重传时间的选择却是 TCP 最复杂的问题之一 -由于 TCP 的下层是互联网环境,发送的报文段可能只经过一个高速率的局域网,也可能经过多个低速率的网络,并且每个 IP 数据报所选择的路由还可能不同。如果把超时重传时间设置得太短,就会引起很多报文段的必须要的重传,使网络负荷增大。但若把超时重传时间设置的过长,则又使网络的空闲时间增大,减低了传输效率 +由于 TCP 的下层是互联网环境,发送的报文段可能只经过一个高速率的局域网,也可能经过多个低速率的网络,并且每个 IP 数据报所选择的路由还可能不同。如果把超时重传时间设置得太短,就会引起很多报文段的不必要的重传,使网络负荷增大。但若把超时重传时间设置的过长,则又使网络的空闲时间增大,降低了传输效率 TCP 采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间之差就是`报文段的往返时间 RTT` @@ -230,7 +230,7 @@ RTTD:RTT 的偏差的加权平均值 利用滑动窗口机制可以很方便地在 TCP 连接上实现对发送方的流量控制 -![TCP协议-图13](./assets/tcp-13.png) +![TCP协议-图13](./assets/network-tcp-13.png) `发送方的发送窗口不能超过接收方给出的接收窗口的数值`。TCP 的`窗口单位是字节,不是报文段` @@ -264,7 +264,7 @@ RTTD:RTT 的偏差的加权平均值 `拥塞控制`就是`防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载`。拥塞控制所要做的都是一个前提,就是`网络能够承受现有的网络负荷` -![TCP协议-图14](./assets/tcp-14.png) +![TCP协议-图14](./assets/network-tcp-14.png) ### TCP 的拥塞控制方法 @@ -282,11 +282,11 @@ cwnd:发送方的拥塞窗口,开始发送方设置 cwnd = 1 “拥塞避免”并非完全能够避免拥塞,而是把拥塞窗口控制为按线性规律增长,`使网络比较不容易出现拥塞` -在执行慢开始算法时,发送方每收到一个队新报文段的确认 ACK,就把拥塞窗口值加1,然后开始下一轮的传输。因此拥塞窗口 cwnd 随着传输轮次按指数规律增长。当拥塞窗口 cwnd 增长到慢开始门限值 ssthresh 时,就改成执行拥塞避免算法,拥塞窗口按线性规律增长 +在执行慢开始算法时,发送方每收到一个对新报文段的确认 ACK,就把拥塞窗口值加1,然后开始下一轮的传输。因此拥塞窗口 cwnd 随着传输轮次按指数规律增长。当拥塞窗口 cwnd 增长到慢开始门限值 ssthresh 时,就改成执行拥塞避免算法,拥塞窗口按线性规律增长 ssthresh:慢开始门限,一般的,会有一个初始值,下图中为16个报文段 -![TCP协议-图15](./assets/tcp-15.png) +![TCP协议-图15](./assets/network-tcp-15.png) 当拥塞窗口 cwnd = 24 时,网络出现了超时,发送方判断为网络拥塞。于是调整门限值 ssthresh = cwnd / 2 = 12,同时设置拥塞窗口 cwnd = 1,进入慢开始阶段 @@ -294,11 +294,11 @@ ssthresh:慢开始门限,一般的,会有一个初始值,下图中为16 采用快重传算法可以让发送方`尽早知道发生了个别报文段的丢失`。快重传算法首先要求接收方不要等待自己发送数据时才进行捎带确认,而是要`立即发送确认`,即使收到了`失序的报文段`也要立即发出对已收到的报文段的重复确认 -![TCP协议-图16](./assets/tcp-16.png) +![TCP协议-图16](./assets/network-tcp-16.png) #### 快恢复 -发送发知道当前只是丢失了个别的报文段。于是不启动慢开始,而是执行`快恢复`算法。这时,发送方调整门限值 ssthresh = cwnd / 2 = 8,同时设置拥塞窗口 cwnd = ssthresh = 8,并开始执行拥塞避免算法 +发送方知道当前只是丢失了个别的报文段。于是不启动慢开始,而是执行`快恢复`算法。这时,发送方调整门限值 ssthresh = cwnd / 2 = 8,同时设置拥塞窗口 cwnd = ssthresh = 8,并开始执行拥塞避免算法 TCP Reno 版本:区别于老的 TCP Tahao 版本 @@ -316,7 +316,7 @@ TCP 是面向连接的协议。运输连接是用来传送 TCP 报文的。TCP TCP 建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个 TCP 报文段 -![TCP协议-图17](./assets/tcp-17.png) +![TCP协议-图17](./assets/network-tcp-17.png) #### 连接建立过程 @@ -347,7 +347,7 @@ B 发送给 A 的报文段,可拆成两个报文段。先发送一个确认报 ### TCP 的连接释放 -![TCP协议-图18](./assets/tcp-18.png) +![TCP协议-图18](./assets/network-tcp-18.png) #### 连接释放过程 @@ -376,6 +376,6 @@ B 只要收到 A 发出的确认,就进入 CLOSED 状态。同样,B 在撤 为了更清晰地看出 TCP 连接的各种状态之间的关系,下图为 TCP 的有限状态机。图中每一个方框即 TCP 可能具有的状态。每个方框中的大写英文字符串是 TCP 标准所使用的 TCP 连接状态名。状态之间的箭头表示可能发生的状态变迁。箭头旁边的字,表明引起这种变迁的原因,或表明发生状态变迁后又出现什么动作。请注意图中有三种不同的箭头。`粗实线箭头`表示对`客户进程的正常变迁`。`粗虚线箭头`表示对`服务器进程的正常变迁`。另一种`细线箭头`表示`异常变迁` -![TCP协议-图19](./assets/tcp-19.png) +![TCP协议-图19](./assets/network-tcp-19.png) **《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" old mode 100644 new mode 100755 index 2f7b1ba..5272992 --- "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" @@ -47,4 +47,4 @@ - 请自行移动和增加分割点,一共有超过 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 +**《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" old mode 100644 new mode 100755 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" old mode 100644 new mode 100755 index 609312c..1a4ef84 --- "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" @@ -8,7 +8,7 @@ HTTP 请求方法用于告诉服务器要做什么。HTTP 规范中定义了一 下图描述了7种 HTTP 方法,并不是所有服务器都实现了所有7种方法。有些方法的请求报文中有主体,有些则无主体的请求 -![HTTP方法](./assets/http-method.png) +![HTTP方法](./assets/network-http-method.png) 由于 HTTP 设计易于扩展,除这些方法,其他服务器可能还会实现一些自己的请求方法。这些附加的方法是对 HTTP 规范的扩展,被称为`扩展方法` @@ -16,7 +16,7 @@ HTTP 请求方法用于告诉服务器要做什么。HTTP 规范中定义了一 HTTP 定义了一组被称为`安全方法`的方法。GET 方法和 HEAD 方法都被认为是安全的,这就意味着使用 GET 或 HEAD 方法的 HTTP 请求都不会产生什么动作 -不产生动作,在这里意味着 HTTP 请求不会在服务器上产生什么结果。例如,你在 Colin 的五金商店购物时,点击了“提交购买”按钮。点击按钮时会提交一个带有信用卡信息的 POST 请求(稍后讨论),那么在服务器上,就会为你执行一个动作。在这种情况下,为购买行为支付信用卡就是所执行的动作 +不产生动作,在这里意味着 HTTP 请求不会在服务器上产生什么结果。例如,你在 Colin 的五金商店购物时,点击了“提交购买”按钮。点击按钮时会提交一个带有信用卡信息的 POST 请求,那么在服务器上,就会为你执行一个动作。在这种情况下,为购买行为支付信用卡就是所执行的动作 安全方法并不一定是什么动作都不执行的(实际上,这是由 Web 开发者决定的)。使用安全方法的目的就是当使用可能引发某一动作的不安全方法时,`允许 HTTP 应用程序开发者通知用户`。在 Colin 的五金商店的例子中,你的 Web 浏览器可能会弹出一条警告消息,说明你正在用不安全的方法发起请求,这样可能会在服务器上引发一些事件(比如用你的信用卡支付费用) @@ -26,7 +26,7 @@ HTTP 定义了一组被称为`安全方法`的方法。GET 方法和 HEAD 方法 GET 是最常用的方法。通常用于请求服务器发送某个资源。HTTP/1.1 要求服务器实现此方法 -![HTTP方法-GET](./assets/http-method-01.png) +![HTTP方法-GET](./assets/network-http-method-01.png) ### HEAD 方法 @@ -38,13 +38,13 @@ HEAD 方法与 GET 方法的行为很类似,但服务器在响应中只返回 服务器开发者必须确保返回的首部与 GET 请求所返回的首部完全相同。遵循 HTTP/1.1 规范,就必须实现 HEAD 方法 -![HTTP方法-HEAD](./assets/http-method-02.png) +![HTTP方法-HEAD](./assets/network-http-method-02.png) ### PUT 方法 与 GET 从服务器读取文档相反,PUT 方法会向服务器写入文档。有些发布系统允许用户创建 Web 页面,并用 PUT 直接将其安装到 Web 服务器上去 -![HTTP方法-PUT](./assets/http-method-03.png) +![HTTP方法-PUT](./assets/network-http-method-03.png) PUT 方法的语义就是让服务器用请求的主体部分来创建一个由所请求的 URL 命名的新文档,或者,如果那个 URL 已经存在的话,就用这个主体来替代它。 @@ -54,7 +54,7 @@ PUT 方法的语义就是让服务器用请求的主体部分来创建一个由 POST 方法起初是用来向服务器输入数据的。实际上,通常会用它来支持 HTML 的表单。表单中填好的数据通常会被送给服务器,然后由服务器将其发送到它要去的地方(比如,送到一个服务器网关程序中,然后由这个程序对其进行处理) -![HTTP方法-POST](./assets/http-method-04.png) +![HTTP方法-POST](./assets/network-http-method-04.png) ### TRACE 方法 @@ -66,7 +66,7 @@ TRACE 请求会在目的服务器端发起一个“环回”诊断。行程最 TRACE 请求中不能带有实体的主体部分。TRACE 响应的实体主体部分包含了响应服务器收到的请求的精确副本 -![HTTP方法-TRACE](./assets/http-method-05.png) +![HTTP方法-TRACE](./assets/network-http-method-05.png) ### OPTIONS @@ -74,19 +74,19 @@ OPTIONS 方法请求 Web 服务器告知其支持的各种功能。可以询问 这为客户端应用程序提供了一种手段,使其不用实际访问那些资源就能判定访问各种资源的最优方式 -![HTTP方法-OPTIONS](./assets/http-method-06.png) +![HTTP方法-OPTIONS](./assets/network-http-method-06.png) ### DELETE DELETE 方法所做的事情就是请服务器删除请求 URL 所指定的资源。但是,客户端应用程序无法保证删除操作一定会被执行。因为 HTTP 规范允许服务器在不通知客户端的情况下撤销请求 -![HTTP方法-DELETE](./assets/http-method-07.png) +![HTTP方法-DELETE](./assets/network-http-method-07.png) ### 扩展方法 HTTP 被设计成字段可扩展的,这样新的特性就不会使老的软件失效了。扩展方法指的就是没有在 HTTP/1.1 规范中定义的方法。服务器会为它所管理的资源实现一些 HTTP 服务,这些方法为开发者提供了一种扩展这些 HTTP 服务能力的手段。下图列出了一些常见的扩展方法实例。这些方法就是 WebDAV HTTP 扩展包含的所有方法,这些方法有助于通过 HTTP 将 Web 内容发布到 Web 服务器上去 -![HTTP方法-扩展方法](./assets/http-method-08.png) +![HTTP方法-扩展方法](./assets/network-http-method-08.png) 并不是所有的扩展方法都是在正式规范中定义的,认识到这一点很重要。如果你定义了一个扩展方法,很可能大部分 HTTP 应用程序都无法理解。同样,你的 HTTP应用程序也可能会遇到一些其他应用程序在用的,而它并不理解的扩展方法 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" old mode 100644 new mode 100755 index fde9869..07a6573 --- "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" @@ -8,7 +8,7 @@ HTTPS 加速了因特网应用程序的成长,已经成为基于 Web 的电子 HTTPS 就是在安全的传输层上发送的 HTTP。HTTPS 没有将未加密的 HTTP 报文发送给 TCP,并通过世界范围内的因特网进行传输,它在将 HTTP 报文发送给 TCP 之前,先将其发送给了一个安全层,对其进行加密 -![HTTPS-图01](./assets/https-01.png) +![HTTPS-图01](./assets/network-https-01.png) 现在,HTTP 安全层是通过 SSL 及其现代替代协议 TLS 来实现的。我们遵循常见的用法,用术语 SSL 来表示 SSL 或者 TLS @@ -32,7 +32,7 @@ HTTPS 就是在安全的传输层上发送的 HTTP。HTTPS 没有将未加密的 SSL 是个二进制协议,与 HTTP 完全不同,其流量是承载在另一个端口上的(SSL 通常是由端口 443 承载的)。如果 SSL 和 HTTP 流量都从端口 80 到达,大部分 Web 服务器会将二进制 SSL 流量理解为错误的 HTTP 并关闭连接。将安全服务进一步整合到 HTTP 层中去就无需使用多个目的端口了,在实际中这样不会引发严重的问题 -![HTTPS-图02](./assets/https-02.png) +![HTTPS-图02](./assets/network-https-02.png) ## 建立安全传输 @@ -49,11 +49,11 @@ SSL 是个二进制协议,与 HTTP 完全不同,其流量是承载在另一 - 对两端的身份进行认证 - 生成临时的会话密钥,以便加密信道 -![HTTPS-图03](./assets/https-03.png) +![HTTPS-图03](./assets/network-https-03.png) 在通过网络传输任何已加密的 HTTP 数据之前,SSL 已经发送了一组握手数据来建立通信连接了 -![HTTPS-图04](./assets/https-04.png) +![HTTPS-图04](./assets/network-https-04.png) 这是 SSL 握手的简化版本。根据 SSL 的使用方式,握手过程可能会复杂一些,但总 的思想就是这样 @@ -66,7 +66,7 @@ SSL 支持双向认证,将服务器证书承载回客户端,再将客户端 服务器证书是一个显示了组织的名称、地址、服务器 DNS 域名以及其他信息的 X.509 v3 派生证书。你和你所用的客户端软件可以检查证书,以确保所有的信息都是可信的 -![HTTPS-图05](./assets/https-05.png) +![HTTPS-图05](./assets/network-https-05.png) ## 站点证书的有效性 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" old mode 100644 new mode 100755 diff --git "a/docs/01.\347\275\221\347\273\234/assets/http-message.png" "b/docs/01.\347\275\221\347\273\234/assets/http-message.png" deleted file mode 100644 index 4131a43..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/http-message.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/http-method-01.png" "b/docs/01.\347\275\221\347\273\234/assets/http-method-01.png" deleted file mode 100644 index ff888b1..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/http-method-01.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/http-method-02.png" "b/docs/01.\347\275\221\347\273\234/assets/http-method-02.png" deleted file mode 100644 index 2545348..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/http-method-02.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/http-method-03.png" "b/docs/01.\347\275\221\347\273\234/assets/http-method-03.png" deleted file mode 100644 index 9af25cc..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/http-method-03.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/http-method-04.png" "b/docs/01.\347\275\221\347\273\234/assets/http-method-04.png" deleted file mode 100644 index a068c84..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/http-method-04.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/http-method-05.png" "b/docs/01.\347\275\221\347\273\234/assets/http-method-05.png" deleted file mode 100644 index 077b08d..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/http-method-05.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/http-method-06.png" "b/docs/01.\347\275\221\347\273\234/assets/http-method-06.png" deleted file mode 100644 index 91d2988..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/http-method-06.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/http-method-07.png" "b/docs/01.\347\275\221\347\273\234/assets/http-method-07.png" deleted file mode 100644 index 0b8f751..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/http-method-07.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/http-method-08.png" "b/docs/01.\347\275\221\347\273\234/assets/http-method-08.png" deleted file mode 100644 index 09b19b4..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/http-method-08.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/http-method.png" "b/docs/01.\347\275\221\347\273\234/assets/http-method.png" deleted file mode 100644 index 7e9370a..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/http-method.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/https-01.png" "b/docs/01.\347\275\221\347\273\234/assets/https-01.png" deleted file mode 100644 index b446b80..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/https-01.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/https-02.png" "b/docs/01.\347\275\221\347\273\234/assets/https-02.png" deleted file mode 100644 index cad0c36..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/https-02.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/https-05.png" "b/docs/01.\347\275\221\347\273\234/assets/https-05.png" deleted file mode 100644 index c7dfb3f..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/https-05.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/https.png" "b/docs/01.\347\275\221\347\273\234/assets/https.png" deleted file mode 100644 index 6ed4cdc..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/https.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/net-tcp-connect.png" "b/docs/01.\347\275\221\347\273\234/assets/net-tcp-connect.png" deleted file mode 100644 index 2f584d2..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/net-tcp-connect.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/net-tcp-disconnect.png" "b/docs/01.\347\275\221\347\273\234/assets/net-tcp-disconnect.png" deleted file mode 100644 index e8e8f10..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/net-tcp-disconnect.png" and /dev/null differ 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 0000000..33d0563 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-01.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-architecture-02.png" "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-02.png" new file mode 100755 index 0000000..bd52da9 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-02.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-architecture-03.png" "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-03.png" new file mode 100755 index 0000000..1de6110 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-03.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-architecture-04.png" "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-04.png" new file mode 100755 index 0000000..7ff884b Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-04.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-architecture-05.png" "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-05.png" new file mode 100755 index 0000000..5283b9a Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-05.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-architecture-06.png" "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-06.png" new file mode 100755 index 0000000..2c6158d Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-06.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-architecture-07.png" "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-07.png" new file mode 100755 index 0000000..4886f6b Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-architecture-07.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-http-message.png" "b/docs/01.\347\275\221\347\273\234/assets/network-http-message.png" new file mode 100755 index 0000000..e1d813c Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-http-message.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-http-method-01.png" "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-01.png" new file mode 100755 index 0000000..391c22d Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-01.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-http-method-02.png" "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-02.png" new file mode 100755 index 0000000..9364178 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-02.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-http-method-03.png" "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-03.png" new file mode 100755 index 0000000..c3296b3 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-03.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-http-method-04.png" "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-04.png" new file mode 100755 index 0000000..0f22dee Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-04.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-http-method-05.png" "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-05.png" new file mode 100755 index 0000000..837e0f8 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-05.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-http-method-06.png" "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-06.png" new file mode 100755 index 0000000..5f57bb8 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-06.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-http-method-07.png" "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-07.png" new file mode 100755 index 0000000..fbf741c Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-07.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-http-method-08.png" "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-08.png" new file mode 100755 index 0000000..efda61d Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-http-method-08.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-http-method.png" "b/docs/01.\347\275\221\347\273\234/assets/network-http-method.png" new file mode 100755 index 0000000..220bfa4 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-http-method.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-https-01.png" "b/docs/01.\347\275\221\347\273\234/assets/network-https-01.png" new file mode 100755 index 0000000..b7a9c5a Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-https-01.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-https-02.png" "b/docs/01.\347\275\221\347\273\234/assets/network-https-02.png" new file mode 100755 index 0000000..15cf671 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-https-02.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/https-03.png" "b/docs/01.\347\275\221\347\273\234/assets/network-https-03.png" old mode 100644 new mode 100755 similarity index 89% rename from "docs/01.\347\275\221\347\273\234/assets/https-03.png" rename to "docs/01.\347\275\221\347\273\234/assets/network-https-03.png" index 6c0e300..ef0a714 Binary files "a/docs/01.\347\275\221\347\273\234/assets/https-03.png" and "b/docs/01.\347\275\221\347\273\234/assets/network-https-03.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/https-04.png" "b/docs/01.\347\275\221\347\273\234/assets/network-https-04.png" old mode 100644 new mode 100755 similarity index 75% rename from "docs/01.\347\275\221\347\273\234/assets/https-04.png" rename to "docs/01.\347\275\221\347\273\234/assets/network-https-04.png" index d93d677..293eb11 Binary files "a/docs/01.\347\275\221\347\273\234/assets/https-04.png" and "b/docs/01.\347\275\221\347\273\234/assets/network-https-04.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-https-05.png" "b/docs/01.\347\275\221\347\273\234/assets/network-https-05.png" new file mode 100755 index 0000000..83c1b01 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-https-05.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-https.png" "b/docs/01.\347\275\221\347\273\234/assets/network-https.png" new file mode 100755 index 0000000..4e1112b Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-https.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-01.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-01.png" new file mode 100755 index 0000000..d0f490d Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-01.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-02.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-02.png" new file mode 100755 index 0000000..cc7f634 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-02.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-03.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-03.png" new file mode 100755 index 0000000..54a72b6 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-03.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-04.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-04.png" new file mode 100755 index 0000000..4a9a4b9 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-04.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-05.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-05.png" new file mode 100755 index 0000000..da2dbaa Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-05.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-06.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-06.png" new file mode 100755 index 0000000..de18485 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-06.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-07.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-07.png" new file mode 100755 index 0000000..ebfbe7a Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-07.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-08.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-08.png" new file mode 100755 index 0000000..52254e8 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-08.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-09.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-09.png" new file mode 100755 index 0000000..1e774e5 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-09.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-10.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-10.png" new file mode 100755 index 0000000..acfab03 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-10.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-11.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-11.png" new file mode 100755 index 0000000..12b8842 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-11.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-12.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-12.png" new file mode 100755 index 0000000..20fe73d Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-12.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-13.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-13.png" new file mode 100755 index 0000000..3ffca77 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-13.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-14.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-14.png" new file mode 100755 index 0000000..88ed98b Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-14.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-15.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-15.png" new file mode 100755 index 0000000..3f32e40 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-15.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-16.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-16.png" new file mode 100755 index 0000000..a8e3267 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-16.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-17.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-17.png" new file mode 100755 index 0000000..2e9f46a Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-17.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-18.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-18.png" new file mode 100755 index 0000000..30d7b8c Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-18.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-tcp-19.png" "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-19.png" new file mode 100755 index 0000000..4585fc1 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-tcp-19.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-udp-01.png" "b/docs/01.\347\275\221\347\273\234/assets/network-udp-01.png" new file mode 100755 index 0000000..bce3af7 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-udp-01.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-udp-02.png" "b/docs/01.\347\275\221\347\273\234/assets/network-udp-02.png" new file mode 100755 index 0000000..2d0e8bc Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-udp-02.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-udp-03.png" "b/docs/01.\347\275\221\347\273\234/assets/network-udp-03.png" new file mode 100755 index 0000000..6215e34 Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-udp-03.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/network-websocket.png" "b/docs/01.\347\275\221\347\273\234/assets/network-websocket.png" new file mode 100755 index 0000000..51f1a5a Binary files /dev/null and "b/docs/01.\347\275\221\347\273\234/assets/network-websocket.png" differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/ssl-01.png" "b/docs/01.\347\275\221\347\273\234/assets/ssl-01.png" deleted file mode 100644 index bc9c7bd..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/ssl-01.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/ssl-02.png" "b/docs/01.\347\275\221\347\273\234/assets/ssl-02.png" deleted file mode 100644 index c1cac00..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/ssl-02.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-01.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-01.png" deleted file mode 100644 index 6ad1a68..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-01.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-02.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-02.png" deleted file mode 100644 index f2ac94c..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-02.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-03.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-03.png" deleted file mode 100644 index 863f094..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-03.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-04.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-04.png" deleted file mode 100644 index 455214b..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-04.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-05.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-05.png" deleted file mode 100644 index 5dace04..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-05.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-06.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-06.png" deleted file mode 100644 index 969ddbb..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-06.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-07.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-07.png" deleted file mode 100644 index b685d7b..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-07.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-08.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-08.png" deleted file mode 100644 index 15e5d89..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-08.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-09.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-09.png" deleted file mode 100644 index 063cada..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-09.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-10.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-10.png" deleted file mode 100644 index 1467ad2..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-10.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-11.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-11.png" deleted file mode 100644 index f0e892e..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-11.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-12.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-12.png" deleted file mode 100644 index 2fc1b78..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-12.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-13.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-13.png" deleted file mode 100644 index 65a759a..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-13.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-14.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-14.png" deleted file mode 100644 index 971ff59..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-14.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-15.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-15.png" deleted file mode 100644 index 15e6b93..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-15.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-16.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-16.png" deleted file mode 100644 index 909da76..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-16.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-17.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-17.png" deleted file mode 100644 index 814d923..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-17.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-18.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-18.png" deleted file mode 100644 index 5d69211..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-18.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/tcp-19.png" "b/docs/01.\347\275\221\347\273\234/assets/tcp-19.png" deleted file mode 100644 index d11b856..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/tcp-19.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/udp-01.png" "b/docs/01.\347\275\221\347\273\234/assets/udp-01.png" deleted file mode 100644 index 0d9f2ae..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/udp-01.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/udp-02.png" "b/docs/01.\347\275\221\347\273\234/assets/udp-02.png" deleted file mode 100644 index ae7a9df..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/udp-02.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/udp-03.png" "b/docs/01.\347\275\221\347\273\234/assets/udp-03.png" deleted file mode 100644 index 8d1df73..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/udp-03.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-01.png" "b/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-01.png" deleted file mode 100644 index d22e56b..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-01.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-02.png" "b/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-02.png" deleted file mode 100644 index 2b74a8c..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-02.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-03.png" "b/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-03.png" deleted file mode 100644 index 3fb8792..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-03.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-04.png" "b/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-04.png" deleted file mode 100644 index d52f560..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-04.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-05.png" "b/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-05.png" deleted file mode 100644 index 3b25e86..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-05.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-06.png" "b/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-06.png" deleted file mode 100644 index 426c7ea..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-06.png" and /dev/null differ diff --git "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-07.png" "b/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-07.png" deleted file mode 100644 index 6727636..0000000 Binary files "a/docs/01.\347\275\221\347\273\234/assets/\347\275\221\347\273\234\344\275\223\347\263\273\347\273\223\346\236\204-07.png" and /dev/null differ 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..6a3523e --- /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,241 @@ +# 问题与简答 + +## 数据结构与算法篇 + +### 1. 概述 + +#### 解决问题的效率 + +解决问题方法的效率,跟`数据的组织方式`有关,跟`空间的利用效率`有关,也跟`算法的巧妙程度`有关 + +#### 抽象数据类型 + +`抽象数据类型`(Abstract Data Type,ADT)是一种对"数据类型"的描述,这种描述是"抽象"的 + +数据类型描述内容:一是`数据对象集`,二是`与数据集合相关联的操作集` + +#### 算法定义 + +算法是一个`有限指令集`,它接受一些输入,产生输出,并在一定的有限步骤之后终止 + +#### 算法复杂度 + +- 空间复杂度 S(n):根据算法写成的程序在执行时占用存储单元的长度 +- 时间复杂度 T(n):根据算法写成的程序在执行时耗时时间的长度 + +#### 分析算法效率 + +- 最坏情况的复杂度 Tworst(n) +- 平均复杂度 Tavg(n) + +拓展阅读 [《数据结构与算法概述》](./02.数据结构与算法/01.数据结构与算法概述.md) + +### 2. 实现基础 + +数据结构的处理方法是从这些具体应用中`抽象`出共性的数据组织与操作方式,进而采用某种具体的程序设计语言`实现`相应的数据存储与操作 + +#### 数据存储基础 + +- 数组 + +数组是最基本的构造类型,它是一组相同类型数据的有序集合 + +- 结构 + +结构类型是一种允许把一些数据分量聚合成一个整体的数据类型,它能够把有内在联系的不同类型的数据统一成一个整体,使它们相互关联 + +- 链表 + +链表是一种常见而重要的基础数据结构,也是实现复杂数据结构的重要手段 + +#### 流程控制基础 + +程序设计语言除了能够表达各种各样的数据外,还必须提供一种手段来表达数据处理的过程,即`程序的控制过程` + +按照结构化程序设计的观点,任何程序都可以将程序模块通过三种基本的控制结构进行组合来实现。这三种基本的控制结构是`顺序`、`分支`和`循环` + +拓展阅读 [《数据结构实现基础》](./02.数据结构与算法/02.数据结构实现基础.md) + +### 3. 线性结构 + +#### 线性表 + +线性表(Linear List)是由同一类型的数据元素构成的有序序列的线性结构 + +操作集:初始化、指定查找、查找、插入、删除、求表长 + +实现方式:顺序存储、链式存储 + +#### 堆栈 + +堆栈(Stack)可以认为是具有一定约束的线性表,插入和删除操作都作用在一个称为栈顶(Top)的端点位置 + +操作集:生成栈、判断是否满、压栈、判断是否空、出栈 + +实现方式:顺序存储、链式存储 + +#### 队列 + +队列(Queue)是一个有序线性表,队列的插入和删除操作分别是在线性表的两个不同的端点进行 + +操作集:生成队列、判断是否满、压入队列、判断是否为空,移除队列 + +实现方式:顺序存储、链式存储 + +### 4. 树 + +树(Tree)是一种十分重要且广泛应用的非线性数据结构 + +#### 二叉树 + +五种基本形态:空二叉树、只有根节点的二叉树、只有根节点和左子树TL的二叉树、只有根节点和右子树TR的二叉树、具有根节点、左子树TL和右子树TR的二叉树 + +其它二叉树:斜二叉树、满二叉树、完美二叉树 + +实现方式:顺序存储、链式存储 + +操作集:创建二叉树、判断是否为空、遍历(先序遍历、中序遍历、后序遍历、层序遍历) + +#### 二叉搜索树 + +二叉搜索树(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. 排序 + +没有一种排序算法在任何情况下都是最优的,必须根据实际情况选择最优的算法来解决问题 + +算法稳定性:在一组待排序记录中,如果存在任意两个相等的记录 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 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/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" "b/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" new file mode 100644 index 0000000..34c072f --- /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/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" @@ -0,0 +1,132 @@ +# 数据结构与算法概述 + +## 引子 + +什么是数据结构?如果翻阅不同的教材,可以看到五花八门的描述。事实上,这个问题在计算机科学界至今没有标准的定义。 + +```text +在计算机科学中,数据结构(英语:data structure)是计算机中存储、组织数据的方式(维基百科) +``` + +### 思考问题 + +#### 书籍摆放 + +问题:如果你是书店的主人,该如何摆放你的书籍,才能让顾客最快捷的找到想要的书籍? + +- 方法1:随便放 + +> 放书非常方便,有新书直接插到空位。但是查找很不方便,如果没有这本书,需要翻遍整个书架 + +- 方法2:按照书名的拼音字母顺序排放 + +> 新书插入需要给新书腾出空间,造成图书需要向后移动 + +- 方法3:把书架分成几块区域,每块区域指定摆放某种类别的图书;在每种类别内,按照书名的拼音字母顺序排放 + +> 查找和插入工作量都减少很多,但是无法预估每种类别的图书会有多少,容易造成空间的浪费 + +#### 数字打印 + +问题:写程序实现一个函数 PrintN,使得传入一个正整数为 N 的参数,能顺序打印从 1 到 N 的全部正整数 + +```php +//版本一 +function PrintN($n) +{ + for ($i=1; $i <= $n; $i++) { + echo "{$i}\n"; + } +} +//版本二 +function PrintN($n) +{ + if ($n > 0) { + PrintN($n-1); + echo "{$n}\n"; + } +} +``` + +> 当输入 N 为 100、1000、10000...,N 变的越来越大时候,实现版本一和版本二有什么区别?(debug_backtrace) + +#### 一元多项式计算 + +问题:一元多项式的标准表达式可以写成:f(x) = $a_0$ + $a_1$x + ... + $a_{n-1}$$x^{n-1}$ + $a_n$$x^n$。现给定一个多项式的阶数 n,并将全体系数 $\{a_i\}^n_{i=0}$ 存放在数组 a[] 里。请写程序计算这个多项式在给定点 x 处的值 + +```php +function f($n, $a, $x) +{ + $p = $a[0]; + for ($i=1; $i <= $n; $i++) { + $p += $a[$i] * pow($x, $i); + } + return $p; +} +$x = 2; $n = 1; +$a = []; +for ($i=0; $i <= $n; $i++) { + $a[$i] = $i+1; +} +$fn = f($n, $a, $x); +echo $fn . "\n"; +``` + +通过提公因式 x 减少乘法的运算次数,把多项式改写为: + +> f(x) = $a_0$ + x($a_1$ + x(...($a_{n-1}$ + x($a_n$))...)) + +```php +function f2($n, $a, $x) +{ + $p = $a[$n]; + for ($i=$n; $i > 0 ; $i--) { + $p = $a[$i-1] + $x * $p; + } + return $p; +} +``` + +### 解决问题的效率 + +解决一个非常简单的问题,往往也有多种方法,且不同方法之间的效率可能相差甚远。解决问题方法的效率,跟`数据的组织方式`有关,跟`空间的利用效率`有关,也跟`算法的巧妙程度`有关。 + +## 数据结构 + +### 定义 + +- 数据结构的定义,首先应该包含数据对象在计算机中的组织方式——这类似于图书的摆放方法。并且,数据对象必定与一系列加在数据对象上的操作相关联,就如我们在书架上摆放图书是为了能找得到想要的书,或者是插入一本新买的书。 + +- 在讨论数据结构的时候,关心的是`数据对象`本身以及它们在计算机中的`组织方式`,还要关心与它们相关联的`操作集`,以及实现这些操作的最高效的算法。 + +- 关于数据对象在计算机中的组织方式,包含两个概念:数据对象集的逻辑结构、数据对象集在计算机中的物理存储结构 + +### 抽象数据类型 + +- 抽象数据类型(Abstract Data Type)是一种对"数据结构"的描述,这种描述是"抽象"的。数据类型描述内容:数据对象集、与数据集合相关联的操作集。 + +- 抽象:描述数据类型的方法不依赖于具体实现,即数据对象集合操作集的描述与存放数据的机器无关、与数据存储的物理结构无关、与实现操作的算法和编程语言均无关。抽象是计算机求解问题的基本方式和重要手段,使得一种设计可以应用于多种场景。 + +## 算法 + +### 定义 + +> 算法(algorithm)自于9世纪波斯数学家,在数学上提出了算法这个概念。 + +算法是一个`有限指令集`,它接受一些输入(非必须),产生输出,并一定在有限步骤之后终止。 + +> 算法不是程序,算法比程序更抽象,强调表现做什么,忽略细节性怎么做。这样的好处是使整体思路清晰易懂,形成模块化的风格。 + +### 算法复杂度 + +衡量、比较算法的指标主要有以下两个: + +- 空间复杂度 S(n):根据算法写成的程序在执行时占用存储单元的长度 +- 时间复杂度 T(n):根据算法写成的程序在执行时耗时时间的长度 + +分析一般算法效率: + +- 最坏情况复杂度 $T_{worst}$(n) +- 平均复杂度 $T_{avg}$(n) + +**《数据结构与算法概述》 原文链接:[https://blog.maplemark.cn/2019/07/数据结构与算法概述.html](https://blog.maplemark.cn/2019/07/数据结构与算法概述.html)** \ No newline at end of file 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/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" "b/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" new file mode 100644 index 0000000..e5f6451 --- /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/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" @@ -0,0 +1,170 @@ +# 数据结构实现基础 + +## 引子 + +### 数据统计 + +例子:在日常数据处理中,经常碰到需要对一组数据进行基本的统计分析,包含这些操作:平均数、最大值、最小值、中位数、标准差、方差等。这类统计可能发生在各种情况,比如学生成绩统计、家庭开支情况、GDP 统计等等,都会涉及到这类数据统计。 + +为每个具体应用都编写一个程序不会是一个好方法,程序都具有很大的相似性。数据结构的处理方法是从这些具体应用中`抽象出共性的数据组织与操作方法`,进而采用某种具体的程序设计语言`实现相应的数据存储与操作` + +数据抽象 + +- 类型名称:统计数据集 +- 数据对象集:N 个元素 {x1, x2, ... , xN} 的集合 S +- 操作集: +1. ElementType Average(S, N):求 S 中 N 个元素的平均值 +2. ElementType Max(S, N):求 S 中 N 个元素的最大值 +3. ElementType Min(S, N):求 S 中 N 个元素的最小值 +4. ElementType Median(S, N):求 S 中 N 个元素的中位数 + +### 数据存储 + +数据组织的基本存储方式主要是利用数组和链表方式来实现的,包括很复杂的数据结构,如图、树,也都不外乎应用数组和链表来实现 + +- 若要实现的操作不是基本统计,而是集合运算,需要判断元素是否属于集合、对集合进行并和交运算、元素插入集合等。这些操作虽然在简单数组也可以实现,但是效率不高,使用树的组织方式可以更方便的实现集合的上述运算。 +- 若除了基本的统计操作外,还需要动态的维护一个集合,即经常往集合里加入/删除元素,那应该设计多大的数组来保存这些元素呢,太大浪费空间,太小不够用。使用链表来保存数据或许更适合,但是链表也有缺点,链表需要记录后续节点地址,跟数组存储相比,链表需要更多的存储空间,同时程序实现也比数组更加复杂。 + +数据结构的存储实现跟所需要的操作密切相关,`没有最好的存储方式,只有最合适的存储方式`。 + +### 操作实现 + +- 在确定数据的存储方式后,数据结构涉及的另一个问题是相关的操作如何实现。这些操作的实现需要利用程序设计语言提供的另一个功能,即`流程设计功能`。 + +- 在任何高级程序设计语言都提供了一种的基本流程控制语句,即分支控制语句和循环控制语句。分支控制结构、循环控制结构加上程序自然的语句顺序执行结构,是实现任何算法流程的基本结构。 + +- 在程序中,我们可以将程序的某个基本功能设计为函数,这一方面降低了程序设计的复杂性,另一方面也提高了程序设计的重用性。递归是数据结构算法设计的很重要的手段。 + +## 数据结构存储基础 + +变量是数据存储的基本单位,而变量是有类型的,例如:整型、浮点型、字符型、布尔型 + +### 数组 + +数组是最基本的构造类型,它是一组相同类型数据的有序集合 + +### 指针 + +指针变量用于存放变量的地址,通过指针就能间接访问那个变量 + +### 结构体 + +结构类型是一种允许把一些数据分量聚合成一个整体的数据类型,它能够把有内在联系的不同类型的数据统一成一个整体,使它们相互关联。同时,结构又是一个变量的集合,可以按照与成员类型变量相同的操作方法单独使用其变量成员。结构与数组的区别在于,数组的所有元素必须是相同类型的,而结构的成员可以是不同的数据类型。 + +```text +struct 结构名 { + 类型名 结构成员名 1; + 类型名 结构成员名 2; + ...... + 类型名 结构成员名 n; +}; +``` + +### 链表 + +链表使一种常见而重要的基础数据结构,也是实现复杂数据结构的重要手段。它不按照线性的顺序存储数据,而是由若干个同一结构类型的"结点"依次串联而成的,即每一个结点里保存着下一个结点的地址。使用链表结构可以克服数据需要预先知道数据大小的缺点,可以充分利用计算机内存空间,实现灵活的内存动态管理。但链表失去了数组方便随机存储的优点,同时链表由于增加了结点的指针域,空间开销比较大。 + +### 单向链表 + +#### 单向链表的结构 + +![单向链表的组成示意图](./assets/DSA-single-link.png) + +```php +//单向链表结点 +class node +{ + public $data; + public $next; + + /** + * @param $p1 结点数据 + * @param $p2 下一个结点 + */ + public function __construct($p1, $p2) + { + $this->data = $p1; + $this->next = $p2; + } +} +``` + +#### 单向链表的常见操作 + +- 链表的建立 + +应用链表进行程序设计时,往往需要先建立一个链表,建立链表的过程实际上就是不断在链表中插入结点的过程 + +```php +class singleLinkList +{ + /** + * @param $n int 结点数目 + * @return $head obj 头结点 + */ + public function create($n) + { + $head = new node(0, null); + for ($i=$n; $i > 0; $i--) { + $newNode = new node($i, null); + $newNode->next = $head->next; + $head->next = $newNode; + } + return $head; + } +} +``` + +- 插入结点 + +在单向链表 head 的某个结点 p 之后插入一新结点:找到正确位置 p,申请新结点 t 并对 t 的结点信息赋值,最后将 t 插入在 p 之后 + +- 删除结点 + +从单向链表 head 中删除一个结点:找到被删除结点的前面一个结点 p,删除 p 之后的结点 + +- 单向链表的遍历 + +对单向链表最常见的处理方式:逐个查看链表中每个结点的数据并进行处理 + +### 双向链表 + +![双向链表](./assets/DSA-double-link.png) + +在单向链表基础上增加指向前驱单元指针的链表叫做`双向链表`。结点增加指向其前驱结点的指针,将牺牲一部分空间代价,前驱单元查找可以不必从链头开始查找 + +```php +//双向链表结点 +class node +{ + public $data; + public $next; + public $previous; + + /** + * @param $p1 结点数据 + * @param $p2 下一个结点 + * @param $p3 前一个结点 + */ + public function __construct($p1, $p2, $p3) + { + $this->data = $p1; + $this->next = $p2; + $this->previous = $p3; + } +} +``` + +### 双向循环链表 + +![双向循环链表](./assets/DSA-double-link2.png) + +将双向链表最后一个单元的 Next 指针指向链表的第一个单元,而第一个单元的 Previous 指针指向链表的最后一个单元,这样构成的链表称为`双向循环链表` + +## 流程控制基础 + +程序设计语言除了能表达各种各样的数据外,还必须提供一种手段来表达数据处理的过程,即`程序的控制过程`。程序的控制过程通过程序中的一系列语句来实现。 + +按照结构化程序设计的观点,任何程序都可以将程序模块通过三种基本的控制结构进行组合来实现。这三种基本的控制结构是`顺序`、`分支`、`循环`。 + +**《数据结构实现基础》 原文链接:[https://blog.maplemark.cn/2019/07/数据结构实现基础.html](https://blog.maplemark.cn/2019/07/数据结构实现基础.html)** \ No newline at end of file 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/03.\347\272\277\346\200\247\347\273\223\346\236\204.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/03.\347\272\277\346\200\247\347\273\223\346\236\204.md" new file mode 100644 index 0000000..2d8e6aa --- /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/03.\347\272\277\346\200\247\347\273\223\346\236\204.md" @@ -0,0 +1,156 @@ +# 线性结构 + +在数据的逻辑结构中,有种常见而且简单的结构是`线性结构`,即数据元素之间构成一个`有序`的序列。 + +## 线性表的定义与实现 + +### 线性表的定义 + +线性表(Linear List)是由同一类型的数据元素构成的有序序列的线性结构。线性表中的元素的个数称为线性表的长度;当线性表中没有元素时,称为空表;表的起始位置称为表头;表的结束位置称为表尾。 + +类型名称:线性表(List) + +操作集: +- 1.MakeEmpty:初始化新的空线性表 +- 2.FindKth:根据指定的位序,返回相应元素 +- 3.Find:查找特定元素 +- 4.Insert:指定位序,插入元素 +- 5.Delete:删除指定位序的元素 +- 6.Length:返回线性表的长度 + +### 线性表的顺序存储实现 + +线性表的顺序存储是指在内存中用地址连续的一块存储空间顺序存放线性表的各元素。考虑到线性表的运算有插入、删除等,即表的长度是动态可变的,因此,数组的容量需要设计得足够大。 + +![线性表的顺序存储](./assets/DSA-线性表的顺序存储示意.png) + +> MAXSIZE:根据实际问题定义的足够大的整数 + +> Last:记录当前线性表中最后一个元素在数组中的位置 + +#### 初始化 + +顺序表的初始化即构造一个空表。首先动态分配表结构所需要的存储空间,然后将表中的指针置为空,表示表中没有数据元素。 + +#### 查找 + +顺序存储的线性表中,查找主要是指在线性表中查找给定值相同的数据元素。由于线性表的元素都存储在数组中,所以这个查找过程实际上就是在数组的顺序查找。查找的平均时间复杂度为O(n)。 + +#### 插入 + +顺序表的插入是指在表的第 i 个位序上插入一个值为 X 的新元素。首先将位序之后的元素向后移动,为新元素让出位置;将新元素置入;修改表长度。 + +#### 删除 + +顺序表的删除是指将表中指定位序的元素从线性表中去掉,删除后并改变表长度。将指定位序的元素删除,并将位序之后的元素向前移动;修改表长度。 + +> 由于顺序表的存储特点是用物理上的相邻实现了逻辑上的相邻,它要求用连续的存储单元顺序存储线性表中的各元素,因此,对顺序表插入、删除时需要通过移动数据元素来实现,运行效率影响较大。 + +### 线性表的链式存储实现 + +使用链表结构可以克服数组表示线性表的缺陷。下图为单向链表的图示表示形式,它有 n 个数据单元,每个数据单元由数据域和链接域两部分组成。数据域用来存放数值,链接域是线性表数据单元的结构指针。 + +![线性表的链表表示](./assets/DSA-线性表的链表表示.png) + +```php +//结点的结构定义 +class node +{ + public $data; + public $next; + + /** + * @param $p1 结点数据 + * @param $p2 下一个结点 + */ + public function __construct($p1, $p2) + { + $this->data = $p1; + $this->next = $p2; + } +} +``` + +#### 求表长 + +从链表的第一个元素起,从头到尾遍历一遍。 + +#### 查找 + +线性表的查找有两种:按序号查找、按值查找 + +- 按序号查找 + +从链表的第一个元素起,判断结点序号是否相同,相同则返回结点值,不同则继续,没有则返回错误信息。 + +- 按值查找 + +从头到尾遍历,知道找到为止;从链表的第一个元素结点起,判断当前结点的值是否相等;若是,则返回结点位置,否则继续,知道表结束为止;找不到则返回错误信息。 + +#### 插入 + +线性表的插入是在指定位序前插入一个新元素。在插入位序为1是,代表插入到链表的头;当位序为表尾时,代表插入到链表最后。新增节点,节点值为新元素值,节点指向指针地址根据位序赋予,链表保持。 + +#### 删除 + +单向链表中删除指定位序元素,首先需要找到被删除结点的前一个元素,然后再删除结点并释放空间。 + +## 堆栈 + +`堆栈`(Stack)是具有一定约束的线性表,插入和删除操作都作用在一个称为栈顶(Top)的端点位置。 + +![堆栈](./assets/DSA-stack.png) + +### 表达式求值 + +表达式求值是程序设计语言编译中的一个基本问题,即编译程序要将源程序中描述的表达式转换为正确的机器指令序列或直接求出常量表达式的值。要实现表达式求值,首先需要理解一个表达式,主要是运算的先后顺序。 + +### 抽象数据类型 + +类型名称:堆栈(Stack) +数据对象集:一个有0个或多个元素的有穷线性表 +操作集: +- 1.CreateStack:生成空堆栈 +- 2.IsFull:判断堆栈是否已满 +- 3.Push:将元素压入堆栈 +- 4.IsEmpty:判断堆栈是否为空 +- 5.Pop:删除并返回栈顶元素 + +### 堆栈的实现 + +由于栈是线性表,因而栈的存储结构可采用顺序和链式两种形式。顺序存储的栈称为顺序栈,链式存储的栈称为链栈。 + +#### 栈的顺序存储实现 + +栈的顺序存储结构通常由一个一维数组和一个记录栈顶元素位置的变量组成,另外我们还可以用一个变量来存储堆栈的最大容量,这样方便判断什么时候堆栈是满的。 + +#### 栈的链式存储实现 + +栈的链式存储结构(链栈)与单链表类似,但其操作受限制,插入和删除操作只能在链栈的栈顶进行。栈顶指针就是链表的头指针。 + +### 堆栈应用:表达式求值 + +## 队列 + +`队列`(Queue)是一个有序线性表,队列的插入和删除操作分别在线性表的两个不同端点进行的。先进先出特点。 + +### 队列的定义 + +类型名称:队列(Queue) +数据对象集:一个有0个或多个元素的又穷线性表 +操作集: +- 1.CreateQueue:生成空队列 +- 2.IsFull:判断队列是否已满 +- 3.AddQ:将新元素压入队列 +- 4.IsEmpty:判断队列是否为空 +- 5.DeleteQ:删除并返回队列头元素 + +### 队列的实现 + +#### 队列的顺序存储实现 + +队列最简单的表示方法是用数组。用数组存储队列有许多种具体的方法。一般可以选择将队列头放数组下标小的位置,而将队列尾放在数组下标大的位置,并用两个变量分别指示队列的头和尾。 + +#### 队列的链式存储实现 + +队列与堆栈一样,也可以采用链式存储结构,但队列的头必须指向链表的头结点,队列的尾指向链表的尾结点 \ No newline at end of file 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/04.\346\240\221.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/04.\346\240\221.md" new file mode 100644 index 0000000..2a3ec10 --- /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/04.\346\240\221.md" @@ -0,0 +1,49 @@ +# 树 + +在计算机科学中,`树`(Tree)是一种抽象数据类型(ADT)或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。树是一种十分重要的`非线性数据结构`。 + +## 树的定义、表示和术语 + +树是 n(n≥0)个结点构成的有限集合。当 n=0 时,称为空树。对于任意非空树(n>0),具备如下特点。 + +- 每个节点都只有有限个子节点或无子节点 +- 没有父节点的节点称为根节点 +- 每一个非根节点有且只有一个父节点 +- 除了根节点外,每个子节点可以分为多个不相交的子树 +- 树里面没有环路(cycle) + +## 二叉树 + +### 二叉树的定义 + +在计算机科学中,`二叉树`(Binary tree)是每个节点最多只有两个分支的树结构。通常分支被称作"左子树"或"右子树"。二叉树的分支具有左右次序,不能随意颠倒。 + +![二叉树五种基本形态]() + +### 二叉树的性质 + +### 二叉树的存储结构 + +### 二叉树的操作 + +## 二叉搜索树 + +### 二叉搜索树的定义 + +### 二叉搜索树的动态查找 + +### 二叉搜索树的插入 + +### 二叉搜索树的删除 + +## 平衡二叉树 + +### 平衡二叉树的定义 + +### 平衡二叉树的调整 + +## 树的应用 + +### 堆及其操作 + +### 哈夫曼树 \ No newline at end of file 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/05.\346\225\243\345\210\227\346\237\245\346\211\276.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/05.\346\225\243\345\210\227\346\237\245\346\211\276.md" new file mode 100644 index 0000000..e69de29 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/06.\345\233\276.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/06.\345\233\276.md" new file mode 100644 index 0000000..e69de29 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/07.\346\216\222\345\272\217.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/07.\346\216\222\345\272\217.md" new file mode 100644 index 0000000..e69de29 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/08.\347\256\227\346\263\225\350\241\245\345\205\205.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/08.\347\256\227\346\263\225\350\241\245\345\205\205.md" new file mode 100644 index 0000000..e69de29 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/09.\347\273\217\345\205\270\347\256\227\346\263\225\351\242\230.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/09.\347\273\217\345\205\270\347\256\227\346\263\225\351\242\230.md" new file mode 100644 index 0000000..d75ea41 --- /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/09.\347\273\217\345\205\270\347\256\227\346\263\225\351\242\230.md" @@ -0,0 +1,3 @@ +# 经典算法题 + +## 1 \ No newline at end of file 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/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" "b/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" new file mode 100644 index 0000000..38297d7 Binary files /dev/null and "b/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" differ 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/assets/DSA-double-link2.png" "b/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" new file mode 100644 index 0000000..95e7480 Binary files /dev/null and "b/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" differ 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/assets/DSA-single-link.png" "b/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" new file mode 100644 index 0000000..74e09c0 Binary files /dev/null and "b/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" differ 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/assets/DSA-stack.png" "b/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" new file mode 100644 index 0000000..cb89c11 Binary files /dev/null and "b/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" differ 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/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" "b/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" new file mode 100644 index 0000000..2490f47 Binary files /dev/null and "b/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" differ 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/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" "b/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" new file mode 100644 index 0000000..cec5bb6 Binary files /dev/null and "b/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" differ 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/assets/\346\225\260\346\215\256\347\273\223\346\236\204.sketch" "b/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" new file mode 100644 index 0000000..436eb1e Binary files /dev/null and "b/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" differ diff --git "a/docs/03.PHP/01.PHP\346\225\260\347\273\204.md" "b/docs/03.PHP/01.PHP\346\225\260\347\273\204.md" index 2c07df1..a3b88dd 100644 --- "a/docs/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,178 +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 — 使用用户自定义的比较函数对数组中的值进行排序 \ No newline at end of file +# 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 — 使用用户自定义的比较函数对数组中的值进行排序 diff --git "a/docs/03.PHP/03.echo\343\200\201print\343\200\201print_r\343\200\201var_dump\345\214\272\345\210\253.md" "b/docs/03.PHP/03.echo\343\200\201print\343\200\201print_r\343\200\201var_dump\345\214\272\345\210\253.md" deleted file mode 100644 index f5bd059..0000000 --- "a/docs/03.PHP/03.echo\343\200\201print\343\200\201print_r\343\200\201var_dump\345\214\272\345\210\253.md" +++ /dev/null @@ -1,51 +0,0 @@ -# echo、print、print_r、var_dump 区别 - -## echo - -- 输出单个或多个字符,多个使用逗号分隔 -- 无返回值 - -```php -echo "String 1", "String 2"; -``` - -## print - -- 只可以输出单个字符 -- 返回`1`,因此可用于表达式 - -```php -print "Hello"; -if ($expr && print "foo") {} -``` - -## print_r - -- 输出关于变量的易于理解的信息 -- 支持多种数据类型,包括字符、数组、对象,格式化成易读格式 -- 在调试时非常有用 -- 若设置第二个参数,可将输出值返回(而不直接输出) - -```php -$b = [ - 'm' => 'monkey', - 'foo' => 'bar', - 'x' => ['x', 'y', 'z'], -]; -$results = print_r($b, true); //$results 包含了 print_r 的输出 -``` - -## var_dump - -- 输出关于变量的易于理解的信息,多个可用分号分隔 -- 支持多种数据类型,包括字符、数组、对象,格式化成易读格式 -- 输出格式与`print_r`不同,`var_dump`的输出包含`数据类型` -- 在调试时非常有用 -- 无返回值 - -## 注意 - -- 即使`print`可用于表达式,但这种用法,常常不利于代码可读性,与其他操作符混用容易让人误解 -- `echo`和`print`都是语言结构,`print_r`和`var_dump`是普通函数。`echo`或`print`使用时,不需要使用括号将变量括起来 - -**《echo、print、print_r、var_dump区别》 原文链接:[https://blog.maplemark.cn/2019/04/echo-print-print_r-var_dump区别.html](https://blog.maplemark.cn/2019/04/echo-print-print_r-var_dump区别.html)** \ No newline at end of file diff --git a/docs/03.PHP/QA.md b/docs/03.PHP/QA.md index 18e324d..780114a 100644 --- a/docs/03.PHP/QA.md +++ b/docs/03.PHP/QA.md @@ -1,524 +1,580 @@ -# 问题与简答 - -## PHP 篇 - -### echo、print、print_r、var_dump 区别 - -> `echo`和`print`是语言结构、`print_r`和`var_dump`是普通函数 - -- echo:输出一个或多个字符串 - -- print:输出字符串 - -- print_r:打印关于变量的易于理解的信息 - -- var_dump:打印关于变量的易于理解的信息(带类型) - -拓展阅读 [《echo、print、print_r、var_dump区别》](./03.echo、print、print_r、var_dump区别.md) - -### 单引号和双引号的区别 - -双引号可以被分析器解析,单引号则不行 - -### isset 和 empty 的区别 - -isset:检测变量是否已设置并且非 NULL - -empty:判断变量是否为空,变量为 0/false 也会被认为是空;变量不存在,不会产生警告 - -### static、self、$this 的区别 - -static:static 可以用于静态或非静态方法中,也可以访问类的静态属性、静态方法、常量和非静态方法,但不能访问非静态属性 - -self:可以用于访问类的静态属性、静态方法和常量,但 self 指向的是当前定义所在的类,这是 self 的限制 - -$this:指向的是实际调用时的对象,也就是说,实际运行过程中,谁调用了类的属性或方法,$this 指向的就是哪个对象。但 $this 不能访问类的静态属性和常量,且 $this 不能存在于静态方法中 - -### include、require、include_once、require_once 的区别 - -require 和 include 几乎完全一样,除了处理失败的方式不同之外。require 在出错时产生 E_COMPILE_ERROR 级别的错误。换句话说将导致脚本中止而 include 只产生警告(E_WARNING),脚本会继续运行 - -include_once 语句在脚本执行期间包含并运行指定文件。此行为和 include 语句类似,唯一区别是如果该文件中已经被包含过,则不会再次包含。如同此语句名字暗示的那样,只会包含一次 - -### 常见数组函数 - -array_count_values — 统计数组中所有的值 - -array_flip — 交换数组中的键和值 - -array_merge — 合并一个或多个数组 - -array_multisort — 对多个数组或多维数组进行排序 - -array_pad — 以指定长度将一个值填充进数组 - -array_pop — 弹出数组最后一个单元(出栈) - -array_push — 将一个或多个单元压入数组的末尾(入栈) - -array_rand — 从数组中随机(伪随机)取出一个或多个单元 - -array_keys — 返回数组中部分的或所有的键名 - -array_values — 返回数组中所有的值 - -count — 计算数组中的单元数目,或对象中的属性个数 - -sort — 对数组排序 - -### Cookie 和 Session - -Cookie:PHP 透明的支持 HTTP cookie 。cookie 是一种远程浏览器端存储数据并以此来跟踪和识别用户的机制 - -Session:会话机制(Session)在 PHP 中用于保持用户连续访问Web应用时的相关数据 - -### 预定义变量 - -对于全部脚本而言,PHP 提供了大量的预定义变量 - -超全局变量 — 超全局变量是在全部作用域中始终可用的内置变量 - -```text -$GLOBALS — 引用全局作用域中可用的全部变量 -$_SERVER — 服务器和执行环境信息 -$_GET — HTTP GET 变量 -$_POST — HTTP POST 变量 -$_FILES — HTTP 文件上传变量 -$_REQUEST — HTTP Request 变量 -$_SESSION — Session 变量 -$_ENV — 环境变量 -$_COOKIE — HTTP Cookies -$php_errormsg — 前一个错误信息 -$HTTP_RAW_POST_DATA — 原生POST数据 -$http_response_header — HTTP 响应头 -$argc — 传递给脚本的参数数目 -$argv — 传递给脚本的参数数组 -``` - -- 超全局变量 - -PHP 中的许多预定义变量都是“超全局的”,这意味着它们在一个脚本的全部作用域中都可用。在函数或方法中无需执行 global $variable; 就可以访问它们 - -超全局变量:$GLOBALS、$\_SERVER、$\_GET、$\_POST、$\_FILES、$\_COOKIE、$\_SESSION、$\_REQUEST、$\_ENV - -### 传值和传引用的区别 - -传值导致对象生成了一个拷贝,传引用则可以用两个变量指向同一个内容 - -### 构造函数和析构函数 - -构造函数:PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作 - -析构函数:PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行 - -### 魔术方法 - -\_\_construct(), \_\_destruct(), \_\_call(), \_\_callStatic(), \_\_get(), \_\_set(), \_\_isset(), \_\_unset(), \_\_sleep(), \_\_wakeup(), \_\_toString(), \_\_invoke() 等方法在 PHP 中被称为"魔术方法"(Magic methods) - -### public、protected、private、final 区别 - -对属性或方法的访问控制,是通过在前面添加关键字 public(公有),protected(受保护)或 private(私有)来实现的。被定义为公有的类成员可以在任何地方被访问 - -PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承 - -### 客户端/服务端 IP 获取,了解代理透传 实际IP 的概念 - -客户端IP: $\_SERVER['REMOTE_ADDR'] - -服务端IP: $\_SERVER['SERVER_ADDR'] - -客户端IP(代理透传): $\_SERVER['HTTP_X_FORWARDED_FOR'] - -### 类的静态调用和实例化调用 - -- 占用内存 - -静态方法在内存中只有一份,无论调用多少次,都是共用的 - -实例化不一样,每一个实例化是一个对象,在内存中是多个的 - -- 不同点 - -静态调用不需要实例化即可调用 - -静态方法不能调用非静态属性,因为非静态属性需要实例化后,存放在对象里 - -静态方法可以调用非静态方法,使用 self 关键字。php 里,一个方法被 `self::` 后,自动转变为静态方法 - -调用类的静态函数时不会自动调用类的构造函数 - -### PHP 不实例化调用方法 - -静态调用、使用 PHP 反射方式 - -### php.ini 配置选项 - -- 配置选项 - -|名字|默认|备注| -|-|-|-| -|short_open_tag|"1"|是否开启缩写形式(``)| -|precision|"14"|浮点数中显示有效数字的位数| -|disable_functions|""|禁止某些函数| -|disable_classes|""|禁用某些类| -|expose_php|""|是否暴露 PHP 被安装在服务器上| -|max_execution_time|30|最大执行时间| -|memory_limit|128M|每个脚本执行的内存限制| -|error_reporting|NULL|设置错误报告的级别 `E_ALL` & ~`E_NOTICE` & ~`E_STRICT` & ~`E_DEPRECATED`| -|display_errors|"1"|显示错误| -|log_errors|"0"|设置是否将错误日志记录到 error_log 中| -|error_log|NULL|设置脚本错误将被记录到的文件| -|upload_max_filesize|"2M"|最大上传文件大小| -|post_max_size|"8M"|设置POST最大数据限制| - -```shell -php -ini | grep short_open_tag //查看 php.ini 配置 -``` - -- 动态设置 - -```php -ini_set(string $varname , string $newvalue); - -ini_set('date.timezone', 'Asia/Shanghai'); //设置时区 -ini_set('display_errors', '1'); //设置显示错误 -ini_set('memory_limit', '256M'); //设置最大内存限制 -``` - -### php-fpm.conf 配置 - -|名称|默认|备注| -|-|-|-| -|pid||PID文件的位置| -|error_log||错误日志的位置| -|log_level|notice|错误级别 alert:必须立即处理、error:错误情况、warning:警告情况、notice:一般重要信息、debug:调试信息| -|daemonize|yes|设置 FPM 在后台运行| -|listen|ip:port、port、/path/to/unix/socket|设置接受 FastCGI 请求的地址| -|pm|static、ondemand、dynamic|设置进程管理器如何管理子进程| -|request_slowlog_timeout|'0'|慢日志记录阀值| -|slowlog||慢请求的记录日志| - -### 502、504 错误产生原因及解决方式 - -#### 502 - -502 表示网关错误,当 PHP-CGI 得到一个无效响应,网关就会输出这个错误 - -- `php.ini` 的 memory_limit 过小 -- `php-fpm.conf` 中 max_children、max_requests 设置不合理 -- `php-fpm.conf` 中 request_terminate_timeout、max_execution_time 设置不合理 -- php-fpm 进程处理不过来,进程数不足、脚本存在性能问题 - -#### 504 - -504 表示网关超时,PHP-CGI 没有在指定时间响应请求,网关将输出这个错误 - -- Nginx+PHP 架构,可以调整 FastCGI 超时时间,fastcgi_connect_timeout、fastcgi_send_timeout、fastcgi_read_timeout - -### 如何返回一个301重定向 - -```php -header('HTTP/1.1 301 Moved Permanently'); -header('Location: https://blog.maplemark.cn'); -``` - -### PHP 与 MySQL 连接方式 - -#### MySQL - -```php -$conn = mysql_connect('127.0.0.1:3306', 'root', '123456'); -if (!$conn) { - die(mysql_error() . "\n"); -} -mysql_query("SET NAMES 'utf8'"); -$select_db = mysql_select_db('app'); -if (!$select_db) { - die(mysql_error() . "\n"); -} -$sql = "SELECT * FROM `user` LIMIT 1"; -$res = mysql_query($sql); -if (!$res) { - die(mysql_error() . "\n"); -} -while ($row = mysql_fetch_assoc($res)) { - var_dump($row); -} -mysql_close($conn); -``` - -#### MySQLi - -```php -$conn = @new mysqli('127.0.0.1:3306', 'root', '123456'); -if ($conn->connect_errno) { - die($conn->connect_error . "\n"); -} -$conn->query("set names 'utf8';"); -$select_db = $conn->select_db('user'); -if (!$select_db) { - die($conn->error . "\n"); -} -$sql = "SELECT * FROM `user` LIMIT 1"; -$res = $conn->query($sql); -if (!$res) { - die($conn->error . "\n"); -} -while ($row = $res->fetch_assoc()) { - var_dump($row); -} -$res->free(); -$conn->close(); -``` - -#### PDO - -```php -$pdo = new PDO('mysql:host=127.0.0.1:3306;dbname=user', 'root', '123456'); -$pdo->exec("set names 'utf8'"); -$sql = "SELECT * FROM `user` LIMIT 1"; -$stmt = $pdo->prepare($sql); -$stmt->bindValue(1, 1, PDO::PARAM_STR); -$rs = $stmt->execute(); -if ($rs) { - while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { - var_dump($row); - } -} -$pdo = null; -``` - -### MySQL、MySQLi、PDO 区别 - -#### MySQL - -- 允许 PHP 应用与 MySQL 数据库交互的早期扩展 -- 提供了一个面向过程的接口,不支持后期的一些特性 - -#### MySQLi - -- 面向对象接口 -- prepared 语句支持 -- 多语句执行支持 -- 事务支持 -- 增强的调试能力 - -#### PDO - -- PHP 应用中的一个数据库抽象层规范 -- PDO 提供一个统一的 API 接口,无须关心数据库类型 -- 使用标准的 PDO API,可以快速无缝切换数据库 - -### 数据库持久连接 - -把 PHP 用作多进程 web 服务器的一个模块,这种方法目前只适用于 Apache。 - -对于一个多进程的服务器,其典型特征是有一个父进程和一组子进程协调运行,其中实际生成 web 页面的是子进程。每当客户端向父进程提出请求时,该请求会被传递给还没有被其它的客户端请求占用的子进程。这也就是说当相同的客户端第二次向服务端提出请求时,它将有可能被一个不同的子进程来处理。在开启了一个持久连接后,所有请求 SQL 服务的后继页面都能够重用这个已经建立的 SQL Server 连接。 - -### 代码执行过程 - -PHP 代码 => 启动 php 及 zend 引擎,加载注册拓展模块 => 对代码进行词法/语法分析 => 编译成opcode(opcache) => 执行 opcode - -> PHP7 新增了抽象语法树(AST),在语法分析阶段生成 AST,然后再生成 opcode 数组 - -### base64 编码原理 - -![base64](./assets/php-base64.png) - -### ip2long 实现 - -![ip2long](./assets/php-ip2long.png) - -### MVC 的理解 - -MVC 包括三类对象。模型 Model 是应用对象,视图 View 是它在屏幕上的表示,控制器 Controller 定义用户界面对用户输入的响应方式。不使用 MVC,用户界面设计往往将这些对象混在一起,而 MVC 则将它们分离以提高灵活性和复用性 - -### 主流 PHP 框架特点 - -#### Laravel - -易于访问,功能强大,并提供大型,强大的应用程序所需的工具 - -- 简单快速的路由引擎 -- 强大的依赖注入容器 -- 富有表现力,直观的数据库 ORM -- 提供数据库迁移功能 -- 灵活的任务调度器 -- 实时事件广播 - -#### Symfony - -- Database engine-independent -- Simple to use, in most cases, but still flexible enough to adapt to complex cases -- Based on the premise of convention over configuration--the developer needs to configure only the unconventional -- Compliant with most web best practices and design patterns -- Enterprise-ready--adaptable to existing information technology (IT) policies and architectures, and stable enough for long-term projects -- Very readable code, with phpDocumentor comments, for easy maintenance -- Easy to extend, allowing for integration with other vendor libraries - -#### CodeIgniter - -- 基于模型-视图-控制器的系统 -- 框架比较轻量 -- 全功能数据库类,支持多个平台 -- Query Builder 数据库支持 -- 表单和数据验证 -- 安全性和 XSS 过滤 -- 全页面缓存 - -#### ThinkPHP - -- 采用容器统一管理对象 -- 支持 Facade -- 更易用的路由 -- 注解路由支持 -- 路由跨域请求支持 -- 验证类增强 -- 配置和路由目录独立 -- 取消系统常量 -- 类库别名机制 -- 模型和数据库增强 -- 依赖注入完善 -- 支持 PSR-3 日志规范 -- 中间件支持 -- 支持 Swoole/Workerman 运行 - -### 对象关系映射/ORM - -#### 优点 - -- 缩短编码时间、减少甚至免除对 model 的编码,降低数据库学习成本 -- 动态的数据表映射,在表结构发生改变时,减少代码修改 -- 可以很方便的引入附加功能(cache 层) - -#### 缺点 - -- 映射消耗性能、ORM 对象消耗内存 -- SQL 语句较为复杂时,ORM 语法可读性不高(使用原生 SQL) - -### 链式调用实现 - -类定义一个内置变量,让类中其他定义方法可访问到 - -### 异常处理 - -set_exception_handler — 设置用户自定义的异常处理函数 - -使用 try / catch 捕获 - -### 如何实现异步调用 - -```php -$fp = fsockopen("blog.maplemark.cn", 80, $errno, $errstr, 30); -if (!$fp) { - echo "$errstr ($errno)
\n"; -} else { - $out = "GET /backend.php / HTTP/1.1\r\n"; - $out .= "Host: blog.maplemark.cn\r\n"; - $out .= "Connection: Close\r\n\r\n"; - fwrite($fp, $out); - /*忽略执行结果 - while (!feof($fp)) { - echo fgets($fp, 128); - }*/ - fclose($fp); -} -``` - -### 多进程同时写一个文件 - -加锁、队列 - -### PHP 进程模型,进程通讯方式,进程线程区别 - -消息队列、socket、信号量、共享内存、信号、管道 - -### PHP 支持回调的函数,实现一个 - -array_map、array_filter、array_walk、usort - -is_callable + callbacks + 匿名函数实现 - -### 发起 HTTP 请求有哪几种方式,它们有何区别 - -cURL、file_get_contents、fopen、fsockopen - -### php for while foreach 迭代数组时候,哪个效率最高 - -### 弱类型变量如何实现 - -PHP 中声明的变量,在 zend 引擎中都是用结构体 zval 来保存,通过共同体实现弱类型变量声明 - -### PHP 拓展初始化 - -- 初始化拓展 - -```shell -$ php /php-src/ext/ext_skel.php --ext -``` - -- 定义拓展函数 - -zend_module_entry 定义 Extension name 编写 PHP_FUNCTION 函数 - -- 编译安装 - -```shell -$ phpize $ ./configure $ make && make install -``` - -### 如何获取扩展安装路径 - -### 垃圾回收机制 - -引用计数器 - -### Trait - -自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait - -### yield 是什么,说个使用场景 yield、yield 核心原理是什么 - -一个生成器函数看起来像一个普通的函数,不同的是普通函数返回一个值,而一个生成器可以yield生成许多它所需要的值 - -### traits 与 interfaces 区别 及 traits 解决了什么痛点 - -### 如何 foreach 迭代对象、如何数组化操作对象 $obj[key]、如何函数化对象 $obj(123); - -### Swoole 适用场景,协程实现方式 - -那你知道swoole的进程模型 - -### PHP 数组底层实现 (HashTable + Linked list) - -### Copy on write 原理,何时 GC - -### 如何解决 PHP 内存溢出问题 - -### ZVAL - -### HashTable - -### PHP7 新特性 - -标量类型声明、返回值类型声明、通过 define() 定义常量数组、匿名类、相同命名空间类一次性导入 - -### PHP7 底层优化 - -ZVAL 结构体优化,占用由24字节降低为16字节 - -内部类型 zend_string,结构体成员变量采用 char 数组,不是用 char* - -PHP 数组实现由 hashtable 变为 zend array - -函数调用机制,改进函数调用机制,通过优化参数传递环节,减少了一些指令 - -### PSR 介绍,PSR-1, 2, 4, 7 - -### Xhprof 、Xdebug 性能调试工具使用 - -### 字符串、数字比较大小的原理,注意 0 开头的8进制、0x 开头16进制 - -### BOM 头是什么,怎么除去 - -### 模板引擎是什么,解决什么问题、实现原理(Smarty、Twig、Blade) \ No newline at end of file +# 问题与简答 + +## PHP 篇 + +### static、self、$this 的区别 + +static:static 可以用于静态或非静态方法中,也可以访问类的静态属性、静态方法、常量和非静态方法,但不能访问非静态属性 + +self:可以用于访问类的静态属性、静态方法和常量,但 self 指向的是当前定义所在的类,这是 self 的限制 + +$this:指向的是实际调用时的对象,也就是说,实际运行过程中,谁调用了类的属性或方法,$this 指向的就是哪个对象。但 $this 不能访问类的静态属性和常量,且 $this 不能存在于静态方法中 + +### include、require、include_once、require_once 的区别 + +require 和 include 几乎完全一样,除了处理失败的方式不同之外。require 在出错时产生 E_COMPILE_ERROR 级别的错误。换句话说将导致脚本中止而 include 只产生警告(E_WARNING),脚本会继续运行 + +include_once 语句在脚本执行期间包含并运行指定文件。此行为和 include 语句类似,唯一区别是如果该文件中已经被包含过,则不会再次包含。如同此语句名字暗示的那样,只会包含一次 + +### 常见数组函数 + +array_count_values — 统计数组中所有的值 + +array_flip — 交换数组中的键和值 + +array_merge — 合并一个或多个数组 + +array_multisort — 对多个数组或多维数组进行排序 + +array_pad — 以指定长度将一个值填充进数组 + +array_pop — 弹出数组最后一个单元(出栈) + +array_push — 将一个或多个单元压入数组的末尾(入栈) + +array_rand — 从数组中随机(伪随机)取出一个或多个单元 + +array_keys — 返回数组中部分的或所有的键名 + +array_values — 返回数组中所有的值 + +count — 计算数组中的单元数目,或对象中的属性个数 + +sort — 对数组排序 + +### Cookie 和 Session + +Cookie:PHP 透明的支持 HTTP cookie 。cookie 是一种远程浏览器端存储数据并以此来跟踪和识别用户的机制 + +Session:会话机制(Session)在 PHP 中用于保持用户连续访问Web应用时的相关数据 + +### 预定义变量 + +对于全部脚本而言,PHP 提供了大量的预定义变量 + +超全局变量 — 超全局变量是在全部作用域中始终可用的内置变量 + +```text +$GLOBALS — 引用全局作用域中可用的全部变量 +$_SERVER — 服务器和执行环境信息 +$_GET — HTTP GET 变量 +$_POST — HTTP POST 变量 +$_FILES — HTTP 文件上传变量 +$_REQUEST — HTTP Request 变量 +$_SESSION — Session 变量 +$_ENV — 环境变量 +$_COOKIE — HTTP Cookies +$php_errormsg — 前一个错误信息 +$HTTP_RAW_POST_DATA — 原生POST数据 +$http_response_header — HTTP 响应头 +$argc — 传递给脚本的参数数目 +$argv — 传递给脚本的参数数组 +``` + +- 超全局变量 + +PHP 中的许多预定义变量都是“超全局的”,这意味着它们在一个脚本的全部作用域中都可用。在函数或方法中无需执行 global $variable; 就可以访问它们 + +超全局变量:$GLOBALS、$\_SERVER、$\_GET、$\_POST、$\_FILES、$\_COOKIE、$\_SESSION、$\_REQUEST、$\_ENV + +### 传值和传引用的区别 + +传值导致对象生成了一个拷贝,传引用则可以用两个变量指向同一个内容 + +### 构造函数和析构函数 + +构造函数:PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作 + +析构函数:PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行 + +### 魔术方法 + +\_\_construct(), \_\_destruct(), \_\_call(), \_\_callStatic(), \_\_get(), \_\_set(), \_\_isset(), \_\_unset(), \_\_sleep(), \_\_wakeup(), \_\_toString(), \_\_invoke() 等方法在 PHP 中被称为"魔术方法"(Magic methods) + +### public、protected、private、final 区别 + +对属性或方法的访问控制,是通过在前面添加关键字 public(公有),protected(受保护)或 private(私有)来实现的。被定义为公有的类成员可以在任何地方被访问 + +PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承 + +### 客户端/服务端 IP 获取,了解代理透传 实际IP 的概念 + +客户端IP: $\_SERVER['REMOTE_ADDR'] + +服务端IP: $\_SERVER['SERVER_ADDR'] + +客户端IP(代理透传): $\_SERVER['HTTP_X_FORWARDED_FOR'] + +### 类的静态调用和实例化调用 + +- 占用内存 + +静态方法在内存中只有一份,无论调用多少次,都是共用的 + +实例化不一样,每一个实例化是一个对象,在内存中是多个的 + +- 不同点 + +静态调用不需要实例化即可调用 + +静态方法不能调用非静态属性,因为非静态属性需要实例化后,存放在对象里 + +静态方法可以调用非静态方法,使用 self 关键字。php 里,一个方法被 `self::` 后,自动转变为静态方法 + +调用类的静态函数时不会自动调用类的构造函数 + +### 接口和抽象的区别 +抽象用于描述不同的事物,接口用于描述事物的行为。 + +### PHP 不实例化调用方法 + +静态调用、使用 PHP 反射方式 + +### php.ini 配置选项 + +- 配置选项 + +|名字|默认|备注| +|-|-|-| +|short_open_tag|"1"|是否开启缩写形式(``)| +|precision|"14"|浮点数中显示有效数字的位数| +|disable_functions|""|禁止某些函数| +|disable_classes|""|禁用某些类| +|expose_php|""|是否暴露 PHP 被安装在服务器上| +|max_execution_time|30|最大执行时间| +|memory_limit|128M|每个脚本执行的内存限制| +|error_reporting|NULL|设置错误报告的级别 `E_ALL` & ~`E_NOTICE` & ~`E_STRICT` & ~`E_DEPRECATED`| +|display_errors|"1"|显示错误| +|log_errors|"0"|设置是否将错误日志记录到 error_log 中| +|error_log|NULL|设置脚本错误将被记录到的文件| +|upload_max_filesize|"2M"|最大上传文件大小| +|post_max_size|"8M"|设置POST最大数据限制| + +```shell +php -ini | grep short_open_tag //查看 php.ini 配置 +``` + +- 动态设置 + +```php +ini_set(string $varname , string $newvalue); + +ini_set('date.timezone', 'Asia/Shanghai'); //设置时区 +ini_set('display_errors', '1'); //设置显示错误 +ini_set('memory_limit', '256M'); //设置最大内存限制 +``` + +### php-fpm.conf 配置 + +|名称|默认|备注| +|-|-|-| +|pid||PID文件的位置| +|error_log||错误日志的位置| +|log_level|notice|错误级别 alert:必须立即处理、error:错误情况、warning:警告情况、notice:一般重要信息、debug:调试信息| +|daemonize|yes|设置 FPM 在后台运行| +|listen|ip:port、port、/path/to/unix/socket|设置接受 FastCGI 请求的地址| +|pm|static、ondemand、dynamic|设置进程管理器如何管理子进程| +|request_slowlog_timeout|'0'|慢日志记录阀值| +|slowlog||慢请求的记录日志| + +### 502、504 错误产生原因及解决方式 + +#### 502 + +502 表示网关错误,当 PHP-CGI 得到一个无效响应,网关就会输出这个错误 + +- `php.ini` 的 memory_limit 过小 +- `php-fpm.conf` 中 max_children、max_requests 设置不合理 +- `php-fpm.conf` 中 request_terminate_timeout、max_execution_time 设置不合理 +- php-fpm 进程处理不过来,进程数不足、脚本存在性能问题 + +#### 504 + +504 表示网关超时,PHP-CGI 没有在指定时间响应请求,网关将输出这个错误 + +- Nginx+PHP 架构,可以调整 FastCGI 超时时间,fastcgi_connect_timeout、fastcgi_send_timeout、fastcgi_read_timeout + +#### 500 + +php 代码问题,文件权限问题,资源问题 + +#### 503 + +超载或者停机维护 + +### 如何返回一个301重定向 + +```php +header('HTTP/1.1 301 Moved Permanently'); +header('Location: https://blog.maplemark.cn'); +``` + +### PHP 与 MySQL 连接方式 + +#### MySQL + +```php +$conn = mysql_connect('127.0.0.1:3306', 'root', '123456'); +if (!$conn) { + die(mysql_error() . "\n"); +} +mysql_query("SET NAMES 'utf8'"); +$select_db = mysql_select_db('app'); +if (!$select_db) { + die(mysql_error() . "\n"); +} +$sql = "SELECT * FROM `user` LIMIT 1"; +$res = mysql_query($sql); +if (!$res) { + die(mysql_error() . "\n"); +} +while ($row = mysql_fetch_assoc($res)) { + var_dump($row); +} +mysql_close($conn); +``` + +#### MySQLi + +```php +$conn = @new mysqli('127.0.0.1:3306', 'root', '123456'); +if ($conn->connect_errno) { + die($conn->connect_error . "\n"); +} +$conn->query("set names 'utf8';"); +$select_db = $conn->select_db('user'); +if (!$select_db) { + die($conn->error . "\n"); +} +$sql = "SELECT * FROM `user` LIMIT 1"; +$res = $conn->query($sql); +if (!$res) { + die($conn->error . "\n"); +} +while ($row = $res->fetch_assoc()) { + var_dump($row); +} +$res->free(); +$conn->close(); +``` + +#### PDO + +```php +$pdo = new PDO('mysql:host=127.0.0.1:3306;dbname=user', 'root', '123456'); +$pdo->exec("set names 'utf8'"); +$sql = "SELECT * FROM `user` LIMIT 1"; +$stmt = $pdo->prepare($sql); +$stmt->bindValue(1, 1, PDO::PARAM_STR); +$rs = $stmt->execute(); +if ($rs) { + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { + var_dump($row); + } +} +$pdo = null; +``` + +### MySQL、MySQLi、PDO 区别 + +#### MySQL + +- 允许 PHP 应用与 MySQL 数据库交互的早期扩展 +- 提供了一个面向过程的接口,不支持后期的一些特性 + +#### MySQLi + +- 面向对象接口 +- prepared 语句支持 +- 多语句执行支持 +- 事务支持 +- 增强的调试能力 + +#### PDO + +- PHP 应用中的一个数据库抽象层规范 +- PDO 提供一个统一的 API 接口,无须关心数据库类型 +- 使用标准的 PDO API,可以快速无缝切换数据库 + +### 数据库持久连接 + +把 PHP 用作多进程 web 服务器的一个模块,这种方法目前只适用于 Apache。 + +对于一个多进程的服务器,其典型特征是有一个父进程和一组子进程协调运行,其中实际生成 web 页面的是子进程。每当客户端向父进程提出请求时,该请求会被传递给还没有被其它的客户端请求占用的子进程。这也就是说当相同的客户端第二次向服务端提出请求时,它将有可能被一个不同的子进程来处理。在开启了一个持久连接后,所有请求 SQL 服务的后继页面都能够重用这个已经建立的 SQL Server 连接。 + +### 代码执行过程 + +PHP 代码 => 启动 php 及 zend 引擎,加载注册拓展模块 => 对代码进行词法/语法分析 => 编译成opcode(opcache) => 执行 opcode + +> PHP7 新增了抽象语法树(AST),在语法分析阶段生成 AST,然后再生成 opcode 数组 + +### base64 编码原理 + +![base64](./assets/php-base64.png) + +### ip2long 实现 + +![ip2long](./assets/php-ip2long.png) + + +``` +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 则将它们分离以提高灵活性和复用性 + +### 主流 PHP 框架特点 + +#### Laravel + +易于访问,功能强大,并提供大型,强大的应用程序所需的工具 + +- 简单快速的路由引擎 +- 强大的依赖注入容器 +- 富有表现力,直观的数据库 ORM +- 提供数据库迁移功能 +- 灵活的任务调度器 +- 实时事件广播 + +#### Symfony + +- Database engine-independent +- Simple to use, in most cases, but still flexible enough to adapt to complex cases +- Based on the premise of convention over configuration--the developer needs to configure only the unconventional +- Compliant with most web best practices and design patterns +- Enterprise-ready--adaptable to existing information technology (IT) policies and architectures, and stable enough for long-term projects +- Very readable code, with phpDocumentor comments, for easy maintenance +- Easy to extend, allowing for integration with other vendor libraries + +#### CodeIgniter + +- 基于模型-视图-控制器的系统 +- 框架比较轻量 +- 全功能数据库类,支持多个平台 +- Query Builder 数据库支持 +- 表单和数据验证 +- 安全性和 XSS 过滤 +- 全页面缓存 + +#### ThinkPHP + +- 采用容器统一管理对象 +- 支持 Facade +- 更易用的路由 +- 注解路由支持 +- 路由跨域请求支持 +- 验证类增强 +- 配置和路由目录独立 +- 取消系统常量 +- 类库别名机制 +- 模型和数据库增强 +- 依赖注入完善 +- 支持 PSR-3 日志规范 +- 中间件支持 +- 支持 Swoole/Workerman 运行 + +### 对象关系映射/ORM + +#### 优点 + +- 缩短编码时间、减少甚至免除对 model 的编码,降低数据库学习成本 +- 动态的数据表映射,在表结构发生改变时,减少代码修改 +- 可以很方便的引入附加功能(cache 层) + +#### 缺点 + +- 映射消耗性能、ORM 对象消耗内存 +- SQL 语句较为复杂时,ORM 语法可读性不高(使用原生 SQL) + +### 链式调用实现 + +类定义一个内置变量,让类中其他定义方法可访问到 + +### 异常处理 + +set_exception_handler — 设置用户自定义的异常处理函数 + +使用 try / catch 捕获 + +### 串行、并行、并发的区别 +串行:执行多个任务时,各个任务按顺序执行,完成一个之后才能进行下一个 +并行:多个任务在同一时刻执行 +并发:同一时刻需要执行多个任务 + +### 同步与异步的理解 +**同步和异步是一种消息通信机制**。其关注点在于 `被调用者返回` 和 `结果返回` 之间的关系,描述对象是被调用对象的行为。 + +### 阻塞与非阻塞的理解 +**阻塞和非阻塞是一种业务流程处理方式**。其关注点在于调用发生时 `调用者状态` 和 `被调用者返回结果` 之间的关系,描述对象是等待结果时候调用者的状态。 + +### 同步阻塞与非同步阻塞的理解 +同步阻塞:打电话问老板有没有某书(调用),老板说查一下,让你别挂电话(同步),你一直等待老板给你结果,什么事也不做(阻塞)。 + +同步非阻塞:打电话问老板有没有某书(调用),老板说查一下,让你别挂电话(同步),等电话的过程中你还一边嗑瓜子(非阻塞)。 + +### 异步阻塞与异步非阻塞的理解 +异步阻塞:打电话问老板有没有某书(调用),老板说你先挂电话,有了结果通知你(异步),你挂了电话后(结束调用), 除了等老板电话通知结果,什么事情也不做(阻塞)。 + +异步非阻塞:打电话问老板有没有某书(调用),老板说你先挂电话,有了结果通知你(异步),你挂电话后(结束调用),一遍等电话,一遍嗑瓜子。(非阻塞) + +### 如何实现异步调用 + +```php +$fp = fsockopen("blog.maplemark.cn", 80, $errno, $errstr, 30); +if (!$fp) { + echo "$errstr ($errno)
\n"; +} else { + $out = "GET /backend.php / HTTP/1.1\r\n"; + $out .= "Host: blog.maplemark.cn\r\n"; + $out .= "Connection: Close\r\n\r\n"; + fwrite($fp, $out); + /*忽略执行结果 + while (!feof($fp)) { + echo fgets($fp, 128); + }*/ + fclose($fp); +} +``` + +### 多进程同时写一个文件 + +加锁、队列 + +### PHP 进程模型,进程通讯方式,进程线程区别 + +消息队列、socket、信号量、共享内存、信号、管道 + +### PHP 支持回调的函数,实现一个 + +array_map、array_filter、array_walk、usort + +is_callable + callbacks + 匿名函数实现 + +### 发起 HTTP 请求有哪几种方式,它们有何区别 + +cURL、file_get_contents、fopen、fsockopen + +### php for while foreach 迭代数组时候,哪个效率最高 + +### 弱类型变量如何实现 + +PHP 中声明的变量,在 zend 引擎中都是用结构体 zval 来保存,通过共同体实现弱类型变量声明 + +### PHP 拓展初始化 + +- 初始化拓展 + +```shell +$ php /php-src/ext/ext_skel.php --ext +``` + +- 定义拓展函数 + +zend_module_entry 定义 Extension name 编写 PHP_FUNCTION 函数 + +- 编译安装 + +```shell +$ phpize $ ./configure $ make && make install +``` + +### 如何获取扩展安装路径 + +### 垃圾回收机制 + +引用计数器 + +### Trait + +自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait + +### yield 是什么,说个使用场景 yield、yield 核心原理是什么 + +一个生成器函数看起来像一个普通的函数,不同的是普通函数返回一个值,而一个生成器可以yield生成许多它所需要的值。 + +yield核心原理: PHP在使用生成器的时候,会返回一个Generator类的对象。每一次迭代,PHP会通过Generator实例计算出下一次需要迭代的值。简述即yield用于生成值。 + +yield使用场景:读取大文件、大量计算。 + +yield好处:节省内存、优化性能 + +### traits 与 interfaces 区别 及 traits 解决了什么痛点 + +### 如何 foreach 迭代对象、如何数组化操作对象 $obj[key]、如何函数化对象 $obj(123); + +### Swoole 适用场景,协程实现方式 + +Swoole 是一个使用 C++ 语言编写的基于异步事件驱动和协程的并行网络通信引擎,为 PHP 提供协程、高性能网络编程支持。提供了多种通信协议的网络服务器和客户端模块,可以方便快速的实现 TCP/UDP服务、高性能Web、WebSocket服务、物联网、实时通讯、游戏、微服务等,使 PHP 不再局限于传统的 Web 领域。 + + +协程可以简单理解为线程,只不过这个线程是用户态的,不需要操作系统参与,创建销毁和切换的成本非常低,和线程不同的是协程没法利用多核 cpu 的,想利用多核 cpu 需要依赖 Swoole 的多进程模型。 +在底层实现上是单线程的,因此同一时间只有一个协程在工作,协程的执行是串行的。 +采用 CSP 编程模型,即不要以共享内存的方式来通信,相反,要通过通信来共享内存。 +swoole4.0采用双栈方式,通过栈桢切换来实现协程;即遇到IO等待就切换到。 + +#### swoole的进程模型 + +同一台主机上两个进程间通信 (简称 IPC) 的方式有很多种,在 Swoole 中使用了 2 种方式 Unix Socket 和 sysvmsg。 + +swoole启动后会生成master进程、reactor线程、worker进程、task进程以及manager进程 + +master进程是一个多线程进程,会生成多个reactor线程 +reactor线程负载网络监听、数据收发 +work进程处理reactor线程投递的请求数据 +task进程处理work进程投递的任务 +manager进程用于管理work进程和task进程 + +### PHP 数组底层实现 (HashTable + Linked list) + +PHP 数组底层依赖的散列表数据结构,定义如下(位于 Zend/zend_types.h)。 + +数据存储在一个散列表中,通过中间层来保存索引与实际存储在散列表中位置的映射。 + +由于哈希函数会存在哈希冲突的可能,因此对冲突的值采用链表来保存。 + +哈希表的查询效率是o(1),链表查询效率是o(n);因此PHP数据索引速度很快;但是相对比较占用空间。 + +### Copy on write 原理,何时 GC + +### 如何解决 PHP 内存溢出问题 + +### ZVAL + +### HashTable + +### PHP7 新特性 + +标量类型声明、返回值类型声明、通过 define() 定义常量数组、匿名类、相同命名空间类一次性导入 + +### PHP7 底层优化 + +ZVAL 结构体优化,占用由24字节降低为16字节 + +内部类型 zend_string,结构体成员变量采用 char 数组,不是用 char* + +PHP 数组实现由 hashtable 变为 zend array + +函数调用机制,改进函数调用机制,通过优化参数传递环节,减少了一些指令 + +### PSR 介绍,PSR-1, 2, 4, 7 + +### Xhprof 、Xdebug 性能调试工具使用 + +### 字符串、数字比较大小的原理,注意 0 开头的8进制、0x 开头16进制 + +### BOM 头是什么,怎么除去 + +WINDOWS自带的记事本,在保存一个以 UTF-8 编码的文件时,会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM);它是一串隐藏的字符,用于让记事本等编辑器识别这个文件是否以UTF-8编码。 +去除方法:$result = trim($result, "\xEF\xBB\xBF"); + +### 模板引擎是什么,解决什么问题、实现原理(Smarty、Twig、Blade) + + +### 写一个函数,尽可能高效的从一个标准 URL 中取出文件的扩展名 +parse_str,explode diff --git a/docs/03.PHP/assets/php-ip2long.png b/docs/03.PHP/assets/php-ip2long.png index eaf06aa..981b6f3 100644 Binary files a/docs/03.PHP/assets/php-ip2long.png and b/docs/03.PHP/assets/php-ip2long.png differ diff --git a/docs/04.Web/QA.md b/docs/04.Web/QA.md index 566e360..8c1a61b 100644 --- a/docs/04.Web/QA.md +++ b/docs/04.Web/QA.md @@ -18,19 +18,19 @@ 提高网站速度:网站速度是搜索引擎排序的一个重要指标 -拓展阅读[《初探 SEO》](./04.Web/01.初探SEO.md) +拓展阅读[《初探 SEO》](./01.初探SEO.md) ### img 标签的 title 和 alt 有什么区别 title 属性规定关于元素的额外信息,这些信息通常会在鼠标移到元素上时显示一段提示文本 -alt 是标签的特有属性,是图片内容的等价描述。图片无法加载时显示。搜索引擎会重点分析 +alt 是``标签的特有属性,是图片内容的等价描述。图片无法加载时显示。搜索引擎会重点分析 ### CSS 选择器的分类 ![CSS选择器](./assets/web-css-CSS选择器.png) -拓展阅读[《CSS选择器的分类》](./04.Web/02.CSS选择器的分类.md) +拓展阅读[《CSS选择器的分类》](./02.CSS选择器的分类.md) ### CSS sprite 是什么,有什么优缺点 @@ -50,7 +50,7 @@ alt 是标签的特有属性,是图片内容的等价描述。图片无 维护麻烦,修改一个图片可能需要从新布局整个图片,样式 -拓展阅读[《雪碧图CSS Sprite的应用》](./04.Web/03.CSS-Sprite的应用.md) +拓展阅读[《雪碧图CSS Sprite的应用》](./03.CSS-Sprite的应用.md) ### display: none 与 visibility: hidden 的区别 @@ -126,7 +126,7 @@ link 可以通过 rel="alternate stylesheet"指定候选样式 具备属性:内容(content)、填充(padding)、边框(border)、边界(margin) -拓展阅读[《CSS盒模型》](./04.Web/04.CSS盒模型.md) +拓展阅读[《CSS盒模型》](./04.CSS盒模型.md) ### 容器包含若干浮动元素时如何清理(包含)浮动 @@ -163,7 +163,7 @@ link 可以通过 rel="alternate stylesheet"指定候选样式 不定宽块状使用 float:left 实现居中 -拓展阅读[《CSS 水平居中设置》](./04.Web/05.CSS水平居中设置.md) +拓展阅读[《CSS 水平居中设置》](./05.CSS水平居中设置.md) ### 如何竖直居中一个元素 @@ -171,7 +171,7 @@ link 可以通过 rel="alternate stylesheet"指定候选样式 父元素高度确定的多行文本 -拓展阅读[《CSS 垂直居中设置》](./04.Web/06.CSS垂直居中设置.md) +拓展阅读[《CSS 垂直居中设置》](./06.CSS垂直居中设置.md) ### flex 与 CSS 盒子模型有什么区别 @@ -179,7 +179,7 @@ link 可以通过 rel="alternate stylesheet"指定候选样式 Flex 布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能 -拓展阅读 [《flex 布局的基本概念》](./04.Web/07.flex布局的基本概念.md) +拓展阅读 [《flex 布局的基本概念》](./07.flex布局的基本概念.md) ### Position 属性 @@ -191,7 +191,7 @@ Flex 布局,可以简便、完整、响应式地实现各种页面布局。目 |static|默认值。没有定位,元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声明)| |inherit|规定应该从父元素继承 position 属性的值| -拓展阅读 [《CSS Position学习》](./04.Web/08.CSS-Position学习.md) +拓展阅读 [《CSS Position学习》](./08.CSS-Position学习.md) ### PNG,GIF,JPG 的区别及如何选 @@ -211,19 +211,19 @@ Flex 布局,可以简便、完整、响应式地实现各种页面布局。目 脚本会阻塞页面其他资源的下载,因此推荐将所有`