From e1ef2f86640c416206dd2be927119b140452cd4d Mon Sep 17 00:00:00 2001 From: etongfu Date: Thu, 31 Dec 2020 20:22:20 +0800 Subject: [PATCH 01/19] update: toc update --- README.md | 7 ++- "Server/MySQL\346\200\273\347\273\223.md" | 12 +++- ...20\347\240\201\346\211\200\345\276\227.md" | 2 +- .../UnitTest.md" | 55 +++++++++++++++++++ ...15\347\253\257\346\265\213\350\257\225.md" | 13 ----- 5 files changed, 72 insertions(+), 17 deletions(-) create mode 100644 "\345\267\245\347\250\213\345\214\226/UnitTest.md" diff --git a/README.md b/README.md index 18ea590..3ba75c0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Blog -开发过程中的疑率以及学习中碰到的精华整理成的博客。(如果发现问题请提交```issue```)。最近入职了新公司,更新会慢点😁 +开发过程中的疑率以及学习中碰到的精华整理成的博客。(如果发现问题请提交```issue```😁)。 ## 写在前面 文中大部分的代码都在[usually-accumulated](https://github.com/QDMarkMan/usually-accumulated)这个rep中。也是我积累代码的地方。 @@ -66,4 +66,7 @@ - [带你深度解锁Webpack系列(基础篇)](https://juejin.im/post/5e5c65fc6fb9a07cd00d8838) - [带你深度解锁Webpack系列(进阶篇)](https://juejin.im/post/5e6518946fb9a07c820fbaaf) - [The Missing Semester of Your CS Education 中文版](https://missing-semester-cn.github.io/) - +- [前端元编程——使用注解加速你的前端开发](https://zhuanlan.zhihu.com/p/274328551) +- [一份不可多得的 TS 学习指南(1.8W字)](https://juejin.cn/post/6872111128135073806#heading-50) +- [VSCode 源码解读-Workbench](https://zhuanlan.zhihu.com/p/59033621) +- [lerna管理前端packages的最佳实践](http://www.sosout.com/2018/07/21/lerna-repo.html) diff --git "a/Server/MySQL\346\200\273\347\273\223.md" "b/Server/MySQL\346\200\273\347\273\223.md" index 70e6e91..a3b4549 100644 --- "a/Server/MySQL\346\200\273\347\273\223.md" +++ "b/Server/MySQL\346\200\273\347\273\223.md" @@ -376,4 +376,14 @@ UPDATE 表名 SET 列1=值1, 列2=值2, ..., 列n=值n [WHERE 布尔表达式]; ``` - 虽然更新语句的WHERE子句是可选的,但是如果不加WHERE子句的话将更新表中所有的记录,这是玩火的行为!超级危险!十分危险!请慎重使用 \ No newline at end of file + 虽然更新语句的WHERE子句是可选的,但是如果不加WHERE子句的话将更新表中所有的记录,这是玩火的行为!超级危险!十分危险!请慎重使用 + +## 最佳实践 + +一些实际使用中需要注意的点 + +### 为什么SELECT * 会导致查询效率低? + +1. 不需要的列会增加数据传输时间和网络开销。 +2. 对于无用的大字段, 如`varchar` `blob` `tex` 会增加IO操作。 +3. 失去`MySQL`优化器”覆盖索引“ 策略优化的可能性。 \ No newline at end of file diff --git "a/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" "b/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" index f3494d2..1b98dfd 100644 --- "a/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" +++ "b/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" @@ -4,7 +4,7 @@ ## 写在前面 -**现在不建议阅读,我自己都没有读利索** +**现在不建议阅读,还没有读利索** ## 文件结构 diff --git "a/\345\267\245\347\250\213\345\214\226/UnitTest.md" "b/\345\267\245\347\250\213\345\214\226/UnitTest.md" new file mode 100644 index 0000000..ff298a4 --- /dev/null +++ "b/\345\267\245\347\250\213\345\214\226/UnitTest.md" @@ -0,0 +1,55 @@ +# UnitTest + +单元测试实战总结。 + +## Sinon + +> Standalone test spies, stubs and mocks for JavaScript. Works with any unit testing framework. + +Sion是具有独立spies, stubs and mocks功能的测试框架,可以集成到任意的单元测试架构中, 例如`Mocha`等。Sion的主要作用是通过**测试替代**轻松消除测试的复杂度。测试替代是在测试中使用真是代码逻辑的替代品。比如Ajax等。 + +### spies + +俗称间谍函数,主要作用是收集有关函数调用的信息。可以使用它来帮助我们验证事物,例如是否调用了函数。同样spies实现的基础上是不会影响函数本身的正常调用。 + +使用场景。 + +- 验证函数是否被调用。 + + ```js + it('should call save once', function() { + var save = sinon.spy(Database, 'save'); + + setupNewUser({ name: 'test' }, function() { }); + + save.restore(); + sinon.assert.calledOnce(save); + }); + ``` + +- 检查传递给函数的参数。 + + ```js + it('should pass object with correct values to save', function() { + var save = sinon.spy(Database, 'save'); + var info = { name: 'test' }; + var expectedUser = { + name: info.name, + nameLowercase: info.name.toLowerCase() + }; + + setupNewUser(info, function() { }); + + save.restore(); + sinon.assert.calledWith(save, expectedUser); + }); + ``` + + + +### stub + +### mock + + + diff --git "a/\345\267\245\347\250\213\345\214\226/\345\211\215\347\253\257\346\265\213\350\257\225.md" "b/\345\267\245\347\250\213\345\214\226/\345\211\215\347\253\257\346\265\213\350\257\225.md" index 80dca61..fabeb63 100644 --- "a/\345\267\245\347\250\213\345\214\226/\345\211\215\347\253\257\346\265\213\350\257\225.md" +++ "b/\345\267\245\347\250\213\345\214\226/\345\211\215\347\253\257\346\265\213\350\257\225.md" @@ -51,19 +51,6 @@ 对于框架的选择并不是非要选择某一种框架,并不能单纯的说谁好谁坏,只能说哪一款更适合你的工程和团队。 - -## 开始实战(验证中) - -我们这里选用`Jest`框架用于前端测试的探索,因为`Jest`相对来说比较简单,容易配置,开箱即用,而且功能比较强大。 - -以在`Vue`项目中使用作为示例。 - -### 01搭建测试环境 - -### 02进行简单测试 - -### 03测试进阶 - ## 自动化测试 目的: **以最低的成本建立和维护自动化测试用例。** \ No newline at end of file From 1ea1bd174bde6a3ebd5d5851c13338f03793d4c2 Mon Sep 17 00:00:00 2001 From: etongfu Date: Thu, 7 Jan 2021 16:13:27 +0800 Subject: [PATCH 02/19] add: ReadmeTemplate add --- README.md | 1 + ReadmeTemplate.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 ReadmeTemplate.md diff --git a/README.md b/README.md index 3ba75c0..d81e051 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ - [Docker笔记(更新中)](https://github.com/QDMarkMan/CodeBlog/blob/master/Server/Docker基础指南.md) - [MySQL基础总结笔记](https://github.com/QDMarkMan/CodeBlog/blob/master/Server/MySQL总结.md) - [MD写作模版](https://github.com/QDMarkMan/CodeBlog/blob/master/MDDemo.md) +- [Readme模板](https://github.com/QDMarkMan/CodeBlog/blob/master/ReadmeTemplate.md) ## 相关好文(分享🎉) diff --git a/ReadmeTemplate.md b/ReadmeTemplate.md new file mode 100644 index 0000000..a77992f --- /dev/null +++ b/ReadmeTemplate.md @@ -0,0 +1,42 @@ +# Project name + +> Introduce the current project in one sentence. + +## Table of Contents + +- [Project name](#project-name) + - [Table of Contents](#table-of-contents) + - [Background](#background) + - [Installation](#installation) + - [Usage](#usage) + - [Changelog](#changelog) + - [Todo](#todo) + - [Features](#features) + - [FAQ](#faq) + - [LICENSE](#license) + +## Background + +## Installation + +```shell + +``` + +## Usage + +``` js + +``` + +## Changelog + +## Todo + +## Features + +## FAQ + +## LICENSE + +[MIT](LICENSE) \ No newline at end of file From 91ecb4ad99d714823cd97d21fbb793237a804a4f Mon Sep 17 00:00:00 2001 From: etongfu Date: Sat, 13 Mar 2021 09:46:45 +0800 Subject: [PATCH 03/19] feat: add react hook --- ...55\347\232\204\351\227\255\345\214\205.md" | 2 ++ React/Hook.md | 26 +++++++++++++++++++ ...20\347\240\201\346\211\200\345\276\227.md" | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 React/Hook.md diff --git "a/Javascript/\346\210\221\347\234\274\344\270\255\347\232\204\351\227\255\345\214\205.md" "b/Javascript/\346\210\221\347\234\274\344\270\255\347\232\204\351\227\255\345\214\205.md" index 9637de6..9167f26 100644 --- "a/Javascript/\346\210\221\347\234\274\344\270\255\347\232\204\351\227\255\345\214\205.md" +++ "b/Javascript/\346\210\221\347\234\274\344\270\255\347\232\204\351\227\255\345\214\205.md" @@ -8,6 +8,8 @@ > 闭包是指有权访问另一个 函数作用域中的变量的函数。 --红宝书 +> 一般情况下,JavaScript 变量的生命周期被限定在声明其的函数内。全局变量在整个程序未结束之前一直存在,局部变量则在函数未结束之前一直存在。当一个函数执行完毕,其内部的局部变量会被 JavaScript 解析器的垃圾回收机制销毁从而不再是一个变量。当一个内嵌函数保存了其外层函数一个变量的引用,即使外层函数执行完毕,这个引用也继续被保存着。当这种情况发生,我们说创建了一个闭包。--《Pro JavaScript with Mootools》中翻译 + 闭包的概念比较宽泛,而且理解起来不是很容易。我在刚开始学`JavaScript`的时候看着闭包是一脸大写的懵逼。要真正的理解闭包,仅仅的靠着概念去理解肯定是不行的,我们要把闭包给拆分了一步一步去攻克它。 ## 闭包是怎么产生的? diff --git a/React/Hook.md b/React/Hook.md new file mode 100644 index 0000000..ad634ef --- /dev/null +++ b/React/Hook.md @@ -0,0 +1,26 @@ +# React Hook + +> *Hook* 是 React 16.8 的新增特性。它可以让你在**不编写 class 的情况下使用 state** 以及其他的 React 特性。 + +## Hook是什么? + +> Hook是一个特殊的函数,它可以让你`钩入`React的特性,例如`useState`是允许你在React函数组件中添加state的hook。 + +## 解决了什么问题? + +## Hook 怎么用 ? + +## 注意事项 + +`hook`和之前的Class Base 组件还是有一些区别。 + +- Hook 在 class 内部是**不**起作用的。但你可以使用它们来取代 class 。 + +## 如何进阶使用 ? + +## 相关扩展 + +## 总结 + + + diff --git "a/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" "b/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" index 1b98dfd..816cdef 100644 --- "a/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" +++ "b/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" @@ -4,7 +4,7 @@ ## 写在前面 -**现在不建议阅读,还没有读利索** +**现在不建议阅读,笔者还没有读利索源码** ## 文件结构 From 71bef76d98d98c99f738a2751fcfe84352f9aede Mon Sep 17 00:00:00 2001 From: etongfu <531202571@qq.com> Date: Sun, 14 Mar 2021 22:06:01 +0800 Subject: [PATCH 04/19] chore: update react hooks --- Computer/Design Patterns.md | 9 ++++++++- React/Hook.md | 6 +++++- ...e\346\272\220\347\240\201\346\211\200\345\276\227.md" | 3 ++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Computer/Design Patterns.md b/Computer/Design Patterns.md index e08eeed..2a95e0b 100644 --- a/Computer/Design Patterns.md +++ b/Computer/Design Patterns.md @@ -320,4 +320,11 @@ subject.logic() // notify ### 命令模式 -重要程度: \ No newline at end of file +重要程度:⭐️⭐️⭐️⭐️ + +**命令模式**是一种行为设计模式,她可以将请求转化为一个包含与请求相关的所有信息的独立对象。该转换能够让你让你根据不同的请求将方法参数化,延迟请求执行或者将其放入队列中,且能实现可撤销操作。 + +结构: + +1. **发送者(invoker)** + diff --git a/React/Hook.md b/React/Hook.md index ad634ef..9d1351c 100644 --- a/React/Hook.md +++ b/React/Hook.md @@ -8,6 +8,10 @@ ## 解决了什么问题? +1. 解决了在组件之间复用状态逻辑很难的问题, hook可以让你在无需改动组建结构的情况下复用状态逻辑。 +2. 解决复杂组件理解困难的问题。通过hook可以把复杂组件拆解成更小的函数,而且可以减少组件的副作用来减少一些生命周期中的复杂逻辑。 +3. `Class Component` 到目前为止没有稳定的语法提案,而且难以理解。 + ## Hook 怎么用 ? ## 注意事项 @@ -16,7 +20,7 @@ - Hook 在 class 内部是**不**起作用的。但你可以使用它们来取代 class 。 -## 如何进阶使用 ? +## 实际使用功能点 ## 相关扩展 diff --git "a/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" "b/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" index 816cdef..05917ee 100644 --- "a/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" +++ "b/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" @@ -17,4 +17,5 @@ - `document.documentElement!` - 后面的感叹号是非null和非undefined的类型断言 + 后面的感叹号**是非null和非undefined的类型断言** + From 14bf9abd01ca611b343f5ecbc18844cb0e9b9494 Mon Sep 17 00:00:00 2001 From: etongfu <531202571@qq.com> Date: Sun, 18 Apr 2021 22:10:49 +0800 Subject: [PATCH 05/19] =?UTF-8?q?feat:=20=E6=96=B0=E5=8A=A0=E5=B8=B8?= =?UTF-8?q?=E8=A7=81=E9=9D=A2=E8=AF=95=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...01\351\235\242\350\257\225\351\242\230.md" | 56 +++++++++++++++---- 1 file changed, 46 insertions(+), 10 deletions(-) rename "\351\235\242\350\257\225/\345\270\270\351\227\256\347\232\204\344\270\200\344\272\233\344\270\234\350\245\277.md" => "\351\235\242\350\257\225/\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230.md" (92%) diff --git "a/\351\235\242\350\257\225/\345\270\270\351\227\256\347\232\204\344\270\200\344\272\233\344\270\234\350\245\277.md" "b/\351\235\242\350\257\225/\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230.md" similarity index 92% rename from "\351\235\242\350\257\225/\345\270\270\351\227\256\347\232\204\344\270\200\344\272\233\344\270\234\350\245\277.md" rename to "\351\235\242\350\257\225/\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230.md" index b836ca9..b6f6302 100644 --- "a/\351\235\242\350\257\225/\345\270\270\351\227\256\347\232\204\344\270\200\344\272\233\344\270\234\350\245\277.md" +++ "b/\351\235\242\350\257\225/\345\270\270\350\247\201\351\235\242\350\257\225\351\242\230.md" @@ -62,7 +62,7 @@ 3. Q: 防抖和节流的实现 ? - + A: 这估计大家都看吐了。 建议跳过这个问题,毕竟我自己写的也不好。 防抖和节流的区别 @@ -120,6 +120,39 @@ }, 2000, false) ``` + + +4. 编写一个数组去重函数 + + ```javascript + let unique = ( input ) => { + // 请补充逻辑 + } + // 预期结果 ==> [1, "a", {b: 2}, {c: 3}, "1"] + unique( [1, "a", {b: 2}, {c: 3}, {b: 2}, "1", "a"] ) + ``` + +5. 实现一个版本号对比函数,传入三个参数分别为第一个版本号,关系, 第二个版本号。返回一个布尔值来判定输入的关系是否正确 。来自钉钉。 + + ```javascript + function compareVersion (verA, operator, verB) { + // 补充逻辑 + } + + compareVersion( '4.0.1.0' , '=', '0.4.1.0' ) // false + compareVersion( '4.0.1.0' ,'>', '4') // false + compareVersion( '4.0.1.0' ,'<', '4.1.0' ) // true + + ``` + +6. 用JS实现发布-订阅模式。 + + ```js + // 没有标准答案,自由发挥 + ``` + +7. + ## CSS/HTML 1. Q: 表单可以跨域吗 ? @@ -141,7 +174,7 @@ A: `form`表单是可以跨域的。 有问题还请`React`大佬们不吝赐教。 1. Q: 调用`setState`之后发生了什么 ? - + A: 首先我们要了解`state`三不要 1. 不要直接修改`state`, 因为没有用 @@ -154,7 +187,7 @@ A: `form`表单是可以跨域的。 3. 重新构造`React`状态树 4. 根据差异对界面进行最小化重渲染(这里是按需渲染的) 2. Q: `React`声明周期(这个多重要我就不用多说了) - + A: - 初始化/挂载阶段: - `getDefaultProps`:获取实例的默认属性 @@ -171,7 +204,7 @@ A: `form`表单是可以跨域的。 - 销毁阶段 - `componentWillUnmount`:组件即将销毁 - + - 触发流程 ` @@ -180,7 +213,7 @@ A: `form`表单是可以跨域的。 3. Q: 简单叙述`react diff`异步算法 - + A: - 把树形结构按照层级分解,只比较同级元素。 - 给列表结构的每个单元添加唯一的 `key` 属性,方便比较。 @@ -189,7 +222,7 @@ A: `form`表单是可以跨域的。 - 选择性子树渲染。开发人员可以重写 `shouldComponentUpdate` 提高 `diff` 的性能。 4. Q: `Fragments`是干嘛的? - + A: `Fragments` 允许你将子列表分组,从而取消向 `DOM` 添加额外节点。语法如下 ```js // 正常语法 @@ -209,7 +242,7 @@ A: `form`表单是可以跨域的。 ``` 5. 高阶组件(HOC) - + 首先官方给出的解释如下 > 高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。**高阶组件是参数为组件,返回值为新组件的函数** @@ -264,19 +297,22 @@ A: `form`表单是可以跨域的。
``` - ## Typescript + + + + ## Electron 这个一般不怎么问, 就算问的话应该也不会太难。 可以直接看这一篇[`Electron`总结](https://github.com/QDMarkMan/CodeBlog/blob/master/Electron/README.md) -## Typescript + ## Webpack 1. Q: `filename` 和 `chunkFilename` 的区别 - + A: `filename`: 输出文件的名称 `chunkFilename`: 指未被列在 `entry` 中,却又需要被打包出来的 `chunk` 文件的名称。一般来说,这个 `chunk` 文件指的就是要懒加载的代码。 From 47affd025f9f7f1e98625d735591fa90c8f6a741 Mon Sep 17 00:00:00 2001 From: etongfu Date: Fri, 9 Jul 2021 19:08:12 +0800 Subject: [PATCH 06/19] update: update readme --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index d81e051..f04a0b8 100644 --- a/README.md +++ b/README.md @@ -53,21 +53,45 @@ 在划水的时候发现的一些高质量好文章,这些文章包含各个领域,在我看来每一篇都值得反复阅读,我自己也会反复的去看。这个就不分类了。如有侵权请马上联系我删除😀 - [javascript秘密花园:五星推荐](http://bonsaiden.github.io/JavaScript-Garden/zh/#other.timeouts) + - [关于JS中一些重要的api实现, 巩固你的原生JS功底](https://juejin.im/post/5d635566e51d4561e224a360#comment) + - [MongoDB使用初探](https://juejin.im/post/5d0f34c7f265da1ba25268ee) + - [React核心开发者Dan Abramov.的博客(中文版)](https://overreacted.io/zh-hans/) + - [这一次,彻底弄懂 JavaScript 执行机制](https://juejin.im/post/59e85eebf265da430d571f89#comment) + - [手刃前端监控系统](https://juejin.im/post/5bbc2695e51d4539701e7ea6#heading-6) + - [手摸手,带你用vue撸后台 系列五(v4.0新版本)](https://juejin.im/post/5c92ff94f265da6128275a85) + - [不要用JWT替代session管理(上):全面了解Token,JWT,OAuth,SAML,SSO](https://juejin.im/post/5b3b870a5188251ac85826b8) + - [前端想要了解的Nginx](https://juejin.im/post/5cae9de95188251ae2324ec3) + - [让你的网页更丝滑(一)](https://juejin.im/post/5c860282e51d45531330e10e) + - [一篇文章构建你的 NodeJS 知识体系](https://juejin.im/post/5c4c0ee8f265da61117aa527) + - [从VSCode 看大型IDE技术架构](https://zhuanlan.zhihu.com/p/96041706) + - [带你深度解锁Webpack系列(基础篇)](https://juejin.im/post/5e5c65fc6fb9a07cd00d8838) + - [带你深度解锁Webpack系列(进阶篇)](https://juejin.im/post/5e6518946fb9a07c820fbaaf) + - [The Missing Semester of Your CS Education 中文版](https://missing-semester-cn.github.io/) + - [前端元编程——使用注解加速你的前端开发](https://zhuanlan.zhihu.com/p/274328551) + - [一份不可多得的 TS 学习指南(1.8W字)](https://juejin.cn/post/6872111128135073806#heading-50) + - [VSCode 源码解读-Workbench](https://zhuanlan.zhihu.com/p/59033621) + - [lerna管理前端packages的最佳实践](http://www.sosout.com/2018/07/21/lerna-repo.html) + +- [鹅厂技术说 | 深入理解前端性能监控](https://zhuanlan.zhihu.com/p/65065472) + +- [How to Learn Software Design and Architecture - a Roadmap](https://www.freecodecamp.org/news/software-design/) + + From 3e73b6e73c0991b848a245ea5658c248d767f1e2 Mon Sep 17 00:00:00 2001 From: etongfu Date: Mon, 30 Aug 2021 14:36:05 +0800 Subject: [PATCH 07/19] feat: Add Computer science --- Computer/AlgorithmSummary.md | 62 ++++++++++++ .../ComputerScience.md | 13 +-- Computer/Design Patterns.md | 4 +- .../floors.png" => Computer/images/floors.png | Bin .../images/on.png" => Computer/images/on.png | Bin Electron/Develop Electron App like VSCode.md | 7 ++ README.md | 22 +---- ...27\346\263\225\346\200\273\347\273\223.md" | 29 ------ ...27\346\234\272\347\275\221\347\273\234.md" | 88 ------------------ 9 files changed, 79 insertions(+), 146 deletions(-) create mode 100644 Computer/AlgorithmSummary.md rename "Computer/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" => Computer/ComputerScience.md (95%) rename "\351\235\242\350\257\225/images/floors.png" => Computer/images/floors.png (100%) rename "\351\235\242\350\257\225/images/on.png" => Computer/images/on.png (100%) create mode 100644 Electron/Develop Electron App like VSCode.md delete mode 100644 "\351\235\242\350\257\225/\347\256\227\346\263\225\346\200\273\347\273\223.md" delete mode 100644 "\351\235\242\350\257\225/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" diff --git a/Computer/AlgorithmSummary.md b/Computer/AlgorithmSummary.md new file mode 100644 index 0000000..a79d7b5 --- /dev/null +++ b/Computer/AlgorithmSummary.md @@ -0,0 +1,62 @@ +# Algorithm summary + + +最近在断断续续的看一些算法的东西。算法这个东西在高级的工程师的面试中是不可获取的,所以也来记录一下。 + +## 基础 + +这一部分是对算法理解中需要的基础知识。 + +### 时间复杂度 + +时间复杂度简单的理解是**计算的次数或者是消耗的时间**。是判定一个特算法优劣的指标之一。目前一种比较通用的表示法就是「 **大O符号表示法** 」,即 **算法的渐进时间复杂度:**T(n) = O(f(n))。 + +- f(n):表示每行代码执行的次数。 +- O :表示正比例关系。 + +因为大O符号表示法并不是用于来真实代表算法的执行时间的,它是用来表示代码执行时间的增长变化趋势的,所以我们可以简化公式为:**T(n) = O(n)** + +我们看线图理解一下一般的一些时间复杂度。 + +![时间复杂度](./images/on.png '时间复杂度') + +常见的时间复杂度量级有: + +- 常数阶O(1): 无论代码执行了多少行,只要是没有循环等复杂结构,那这个代码的时间复杂度就都是O(1)。 +- 对数阶O(logN):当循环 log2^n 次以后,代码就结束了。因此这个代码的时间复杂度为:**O(logn)** +- 线性阶O(n):它消耗的时间是随着n的变化而变化的 +- 线性对数阶O(nlogN):线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN) +- 平方阶O(n²):平方阶O(n²) 就更容易理解了,如果把 O(n) 的代码再嵌套循环一遍,它的时间复杂度就是 O(n²) 了 +- 立方阶O(n³) +- 指数阶(2^n) +- K次方阶O(n^k): 就是嵌套了2层n循环,它的时间复杂度就是 O(n*n),即 O(n²) + 如果将循环的层数改成k,那么时间复杂度就变成了O(n^k) + +上面从上至下依次的时间复杂度越来越大,执行的效率越来越低。下面是几个简单是示例 + +```js +// O(1)复杂度的运算 +var n = 1 +console.log(n); +// O(N) 复杂度的运算 +for (let i= 0; i< n; i++) { + // 当前循环会循环N次 +} +// O(N^2) 复杂度的运算 +for (let i= 0; i< n; i++) { + for (let i= 0; i< n; i++) { + // 当前循环会循环N*N次 + } +} +``` + +### 空间复杂度 + +空间复杂度是用来衡量计算程序中实际占用的空间的。空间复杂度是对一个算法在运行过程中临时占用存储空间大小的一个量度,同样反映的是一个趋势,我们用 S(n) 来定义。 + +空间复杂度比较常用的有: + +O(1):如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1) + +O(n):,第一行new了一个数组出来,这个数据占用的大小为n,这段代码的2-6行,虽然有循环,但没有再分配新的空间,因此,这段代码的空间复杂度主要看第一行即可,即 S(n) = O(n)。 + diff --git "a/Computer/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" b/Computer/ComputerScience.md similarity index 95% rename from "Computer/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" rename to Computer/ComputerScience.md index 25d3db3..91eb1ed 100644 --- "a/Computer/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" +++ b/Computer/ComputerScience.md @@ -38,23 +38,24 @@ #1 网络接口层 ``` -- **`五层协议`**:七层体系是偏向学院派,重理论。复杂而且不实用。五层协议既简洁又清楚,着重来讲五层 +- **`五层协议`**:七层体系是偏向学院派,重理论。复杂而且不实用。五层协议既简洁又清楚,着重来讲五层 + ```bash #5 应用层 #4 运输层 #3 网络层 #2 数据链路层 - #1 物理层 - ``` - + #1 物理层 +``` + | 架构层 | 作用 | 数据单元 | 协议 | | :------ | :------: | ------ | ------ | | `5:应用层` | 通过进程(运行的程序)间的交互完成网络应用 | **报文(message)** | `HTTP/SMTP(邮件)/FTP` | | `4:运输层` | 负责为进程间的通讯提供**通用数据传输服务** | **报文段(segment)/用户数据报** | `TCP/UDP` | | `3:网络层` | 为分组交换交换网上的**不同主机**通信服务 | **数据报(datagram)** | `IP` | | `2:数据链路层` | 把网络层传来的IP数据报组装成帧,帧里面包括的是数据和控制信息 | **帧(framing)** | `独有协议` | - | `1:物理层` | 接受物理信息,确定一些物理信息 | **比特** | 传递信息使用的是物理媒介 | - +| `1:物理层` | 接受物理信息,确定一些物理信息 | **比特** | 传递信息使用的是物理媒介 | + 关于分层中的注意点: - `TCP`和`UDP` `TCP`: `Transmission Control Protocol` 提供面向连接的,**可靠的**数据服务。传输数据是报文段(segment) diff --git a/Computer/Design Patterns.md b/Computer/Design Patterns.md index 2a95e0b..f167316 100644 --- a/Computer/Design Patterns.md +++ b/Computer/Design Patterns.md @@ -10,9 +10,9 @@ - **开闭原则**:一个软件实体如类,函数或模块应该对扩展开放,对修改关闭。这是一个比较宽泛模糊的概念,这个是最基础的设计原则。 -- **单一职责原则**: 不要存在多于一个导致类变更的原因。 +- **单一职责原则**: 不要存在**多于一个导致类变更**的原因。 -- **里式替换原则**:所有引用基类的地方必须能够透明的使用其子类的对象。通俗的来讲:子类可以扩展父类的方法,但是不能改变父类原有的功能。 +- **里式替换原则**:所有引用基类的地方必须能够透明的使用其子类的对象。通俗的来讲:**子类可以扩展父类的方法,但是不能改变父类原有的功能**。 - **依赖倒置原则**:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。这个原则的一个基准是: 相对于细节的多边性,抽象的东西要稳定的多。大部分情况下抽象指的就是**接口或者抽象类**,而细节指的就是**具体的实现类**。 diff --git "a/\351\235\242\350\257\225/images/floors.png" b/Computer/images/floors.png similarity index 100% rename from "\351\235\242\350\257\225/images/floors.png" rename to Computer/images/floors.png diff --git "a/\351\235\242\350\257\225/images/on.png" b/Computer/images/on.png similarity index 100% rename from "\351\235\242\350\257\225/images/on.png" rename to Computer/images/on.png diff --git a/Electron/Develop Electron App like VSCode.md b/Electron/Develop Electron App like VSCode.md new file mode 100644 index 0000000..6c2f625 --- /dev/null +++ b/Electron/Develop Electron App like VSCode.md @@ -0,0 +1,7 @@ +# Develop Electron App like VSCode + +> VSCode 是目前比较流行的开源编辑器,这篇文章主要分享如何向VSCode那样去开发一个Electron程序。 + +## 写在前面 + +这个小玩意儿其实是基于VSCode工程中提炼出来的一个精简框架,如果想运行起来VSCode, 可以[看这里](https://github.com/microsoft/vscode/wiki/How-to-Contribute) \ No newline at end of file diff --git a/README.md b/README.md index f04a0b8..f891066 100644 --- a/README.md +++ b/README.md @@ -53,45 +53,25 @@ 在划水的时候发现的一些高质量好文章,这些文章包含各个领域,在我看来每一篇都值得反复阅读,我自己也会反复的去看。这个就不分类了。如有侵权请马上联系我删除😀 - [javascript秘密花园:五星推荐](http://bonsaiden.github.io/JavaScript-Garden/zh/#other.timeouts) - - [关于JS中一些重要的api实现, 巩固你的原生JS功底](https://juejin.im/post/5d635566e51d4561e224a360#comment) - - [MongoDB使用初探](https://juejin.im/post/5d0f34c7f265da1ba25268ee) - - [React核心开发者Dan Abramov.的博客(中文版)](https://overreacted.io/zh-hans/) - - [这一次,彻底弄懂 JavaScript 执行机制](https://juejin.im/post/59e85eebf265da430d571f89#comment) - - [手刃前端监控系统](https://juejin.im/post/5bbc2695e51d4539701e7ea6#heading-6) - - [手摸手,带你用vue撸后台 系列五(v4.0新版本)](https://juejin.im/post/5c92ff94f265da6128275a85) - - [不要用JWT替代session管理(上):全面了解Token,JWT,OAuth,SAML,SSO](https://juejin.im/post/5b3b870a5188251ac85826b8) - - [前端想要了解的Nginx](https://juejin.im/post/5cae9de95188251ae2324ec3) - - [让你的网页更丝滑(一)](https://juejin.im/post/5c860282e51d45531330e10e) - - [一篇文章构建你的 NodeJS 知识体系](https://juejin.im/post/5c4c0ee8f265da61117aa527) - - [从VSCode 看大型IDE技术架构](https://zhuanlan.zhihu.com/p/96041706) - - [带你深度解锁Webpack系列(基础篇)](https://juejin.im/post/5e5c65fc6fb9a07cd00d8838) - - [带你深度解锁Webpack系列(进阶篇)](https://juejin.im/post/5e6518946fb9a07c820fbaaf) - - [The Missing Semester of Your CS Education 中文版](https://missing-semester-cn.github.io/) - - [前端元编程——使用注解加速你的前端开发](https://zhuanlan.zhihu.com/p/274328551) - - [一份不可多得的 TS 学习指南(1.8W字)](https://juejin.cn/post/6872111128135073806#heading-50) - - [VSCode 源码解读-Workbench](https://zhuanlan.zhihu.com/p/59033621) - - [lerna管理前端packages的最佳实践](http://www.sosout.com/2018/07/21/lerna-repo.html) - - [鹅厂技术说 | 深入理解前端性能监控](https://zhuanlan.zhihu.com/p/65065472) - - [How to Learn Software Design and Architecture - a Roadmap](https://www.freecodecamp.org/news/software-design/) +- [架构制图:工具与方法论](https://zhuanlan.zhihu.com/p/384958911) - diff --git "a/\351\235\242\350\257\225/\347\256\227\346\263\225\346\200\273\347\273\223.md" "b/\351\235\242\350\257\225/\347\256\227\346\263\225\346\200\273\347\273\223.md" deleted file mode 100644 index a1dedf3..0000000 --- "a/\351\235\242\350\257\225/\347\256\227\346\263\225\346\200\273\347\273\223.md" +++ /dev/null @@ -1,29 +0,0 @@ -# 算法总结 - -最近在断断续续的看一些算法的东西。算法这个东西在高级的工程师的面试中是不可获取的,所以也来记录一下。 - -## 时间复杂度 - -时间复杂度简单的理解是**计算的次数或者是消耗的时间**。是判定一个特算法优劣的指标之一。我们看线图理解一下一般的一些时间复杂度。 - -![时间复杂度](./images/on.png '时间复杂度') - -下面是几个简单是示例 -```js -// O(1)复杂度的运算 -var n = 1 -console.log(n); -// O(N) 复杂度的运算 -for (let i= 0; i< n; i++) { - // 当前循环会循环N次 -} -// O(N^2) 复杂度的运算 -for (let i= 0; i< n; i++) { - for (let i= 0; i< n; i++) { - // 当前循环会循环N*N次 - } -} -``` - -## 空间复杂度 - diff --git "a/\351\235\242\350\257\225/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" "b/\351\235\242\350\257\225/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" deleted file mode 100644 index 25d3db3..0000000 --- "a/\351\235\242\350\257\225/\350\256\241\347\256\227\346\234\272\347\275\221\347\273\234.md" +++ /dev/null @@ -1,88 +0,0 @@ -# 计算机网络相关 - -这个文章虽然放在了面试的模块下,但是它的意义远不止此。计算机网络的相关知识就好比是大楼的地基。你不知道的话不会耽误你写业务,但是多了解一点对职业生 -涯的深度拓展会很有帮助。 - -## 基础部分 -- `协议` 每天都能听到也很常见的名词,但是让你真正的解释她的含义估计是说的也不到位。 - - 含义:**为进行网络中的数据交换而建立的规则,标准或者约定成为网络协议,也可简称为协议**,协议主要由以下哎三个部分组成 - - 作用:协议其实是计算机网络中不可缺少的部分,如果想联网让你的计算机搞点事情,是都需要协议的。 - 1. `语法` 数据与控制信息的结构或者格式。 - 2. `语义` 需要发出何种控制信息,完成何种动作以及做出何种响应。 - 3. `同步` 事件实现顺序的详细说明 - -- 分层的好处:计算机的分层结构好在`下层提供服务,上层作为服务的使用者。相互隐藏各层细节,简化各个模块,通过接口进行通讯。` - -- 计算机分层:计算机分层主要有`OSI七层体系, TCP/IP四层,五层体系`。下面的这个图讲的就很清楚了 - -![分层协议](./images/floors.png '分层协议') - - -- `OSI七层体系`: 完整分层理论 -```bash -#7 应用层 -#6 表示层 -#5 回话层 -#4 运输层 -#3 网络层 -#2 数据链路层 -#1 物理层 -``` -- `TCP/IP四层` -```bash -#4 应用层 -#3 运输层(TCP/UDP) -#2 网际层 -#1 网络接口层 -``` - -- **`五层协议`**:七层体系是偏向学院派,重理论。复杂而且不实用。五层协议既简洁又清楚,着重来讲五层 - ```bash - #5 应用层 - #4 运输层 - #3 网络层 - #2 数据链路层 - #1 物理层 - ``` - - | 架构层 | 作用 | 数据单元 | 协议 | - | :------ | :------: | ------ | ------ | - | `5:应用层` | 通过进程(运行的程序)间的交互完成网络应用 | **报文(message)** | `HTTP/SMTP(邮件)/FTP` | - | `4:运输层` | 负责为进程间的通讯提供**通用数据传输服务** | **报文段(segment)/用户数据报** | `TCP/UDP` | - | `3:网络层` | 为分组交换交换网上的**不同主机**通信服务 | **数据报(datagram)** | `IP` | - | `2:数据链路层` | 把网络层传来的IP数据报组装成帧,帧里面包括的是数据和控制信息 | **帧(framing)** | `独有协议` | - | `1:物理层` | 接受物理信息,确定一些物理信息 | **比特** | 传递信息使用的是物理媒介 | - - 关于分层中的注意点: - - `TCP`和`UDP` - `TCP`: `Transmission Control Protocol` 提供面向连接的,**可靠的**数据服务。传输数据是报文段(segment) - `UDP`: `User Datagram Protocol` 提供无连接的,**不保证可靠性**但是尽努力数据传输服务。传输数据是用户数据报 - - 至于这两个的区别举个例子很简单就能理解 - `TCP`协议就像是面对面交流,我保证你能听到,一次说的内容有限。`UDP`就像是写信,一下可以写很多字,但是我不确定你能收到信。 - - -## `Http` - -### 基础部分 - -- `http` : 容易被攻击 -- `https`: 更安全一些,使用的时候是需要证书的。 - - -- `http1.0`: 一次性连接 -- `http1.1`: 保持连接,性能大幅度提升 -- `http2.0`: 强制`https`, 自带双向通信, 多重复用 - -### `http`协议 - -### 三次握手 - -1次: 客户端发送连接请求 -2次: 服务端告诉客户端接受请求 -3次: 客户端正式向服务器发送请求 - -客户端 --> `Request` 服务端 --> `Response(http消息)` 客户端 - From 6385aa3dfe40c3dadf1d6dbf799f45ccbd2edfbc Mon Sep 17 00:00:00 2001 From: etongfu Date: Sat, 9 Oct 2021 18:34:18 +0800 Subject: [PATCH 08/19] feat: Add VSCode DI --- TypeScript/VSCodeDI.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 TypeScript/VSCodeDI.md diff --git a/TypeScript/VSCodeDI.md b/TypeScript/VSCodeDI.md new file mode 100644 index 0000000..6dff8fc --- /dev/null +++ b/TypeScript/VSCodeDI.md @@ -0,0 +1,35 @@ +# VSCode 中的DI + +## 写在前面 + +对于这篇文章的阅读,需要了解的一些前置知识可以帮助你更加顺畅的阅读本文。 + +- [基本的TypeScript知识](https://www.typescriptlang.org/) +- [什么是Decorators](https://github.com/tc39/proposal-decorators) +- [TS中的Decorators](https://www.typescriptlang.org/docs/handbook/decorators.html) +- [DI是什么](https://zh.wikipedia.org/wiki/%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5) +- [IOC是什么](https://zh.wikipedia.org/zh-hans/%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC) + +## DI + +> 在[软件工程](https://zh.wikipedia.org/wiki/軟件工程)中,**依赖注入**(dependency injection)的意思为,给予调用方它所需要的事物。 “依赖”是指可被方法调用的事物。依赖注入形式下,调用方不再直接使用“依赖”,取而代之是“注入” 。“注入”是指将“依赖”传递给调用方的过程。在“注入”之后,调用方才会调用该“依赖”[[1\]](https://zh.wikipedia.org/wiki/依赖注入#cite_note-1)。传递依赖给调用方,而不是让让调用方直接获得依赖,这个是该设计的根本需求。 - wikipedia + +依赖注射是[控制反转](https://zh.wikipedia.org/wiki/控制反转)的最为常见的一种技术, + +## IoC + +> **控制反转**(英语:Inversion of Control,缩写为**IoC**),是[面向对象编程](https://zh.wikipedia.org/wiki/面向对象编程)中的一种设计原则,可以用来减低计算机代码之间的[耦合度](https://zh.wikipedia.org/wiki/耦合度_(計算機科學))。其中最常见的方式叫做**依赖注入**(Dependency Injection,简称**DI**),还有一种方式叫“依赖查找”(Dependency Lookup)。- wikipedia + +在我的理解里面: **控制反转IoC(Inversion of Control)是说创建对象的控制权进行转移,以前\**创建对象的主动权和创建时机是由自己把控的\**,而现在这种权力转移到第三方**。 + +## 首先来讲一讲`Decorators` + + + +# 总结 + + + +## 参考文章 + +- [依赖注入和控制反转的理解](https://blog.csdn.net/bestone0213/article/details/47424255) \ No newline at end of file From d5ecfa3a36ae67f3097bc074585f693e5485dcf8 Mon Sep 17 00:00:00 2001 From: etongfu Date: Fri, 22 Oct 2021 18:39:37 +0800 Subject: [PATCH 09/19] feat: Add less used API --- Javascript/LessusedAPI.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Javascript/LessusedAPI.md diff --git a/Javascript/LessusedAPI.md b/Javascript/LessusedAPI.md new file mode 100644 index 0000000..9e7c137 --- /dev/null +++ b/Javascript/LessusedAPI.md @@ -0,0 +1,12 @@ +# Less used and interesting API + +> 一些平常比较少用但是很有意思的API + +## Intersection Observer API + +## MutationObserver + + + + + From c360105cd9abf8a051358ee13a216f1cb1e414cb Mon Sep 17 00:00:00 2001 From: etongfu Date: Fri, 22 Oct 2021 18:42:07 +0800 Subject: [PATCH 10/19] feat: Add less used API --- Javascript/LessusedAPI.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Javascript/LessusedAPI.md b/Javascript/LessusedAPI.md index 9e7c137..b31d0e6 100644 --- a/Javascript/LessusedAPI.md +++ b/Javascript/LessusedAPI.md @@ -4,9 +4,11 @@ ## Intersection Observer API -## MutationObserver +[Intersection Observer API 文档](https://developer.mozilla.org/zh-CN/docs/Web/API/Intersection_Observer_API) +## MutationObserver +[MutationObserver文档](https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver) From 1b4ac95b8a899447db8f933d2e6c425a132d6818 Mon Sep 17 00:00:00 2001 From: etongfu Date: Fri, 5 Nov 2021 19:21:17 +0800 Subject: [PATCH 11/19] feat: Add LessusedAPI --- Javascript/LessusedAPI.md | 61 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/Javascript/LessusedAPI.md b/Javascript/LessusedAPI.md index b31d0e6..8d4e895 100644 --- a/Javascript/LessusedAPI.md +++ b/Javascript/LessusedAPI.md @@ -1,11 +1,68 @@ # Less used and interesting API -> 一些平常比较少用但是很有意思的API +> 一些平常比较少用但是很有用的API -## Intersection Observer API +## IntersectionObserver API + +> `**IntersectionObserver**`**接口** (从属于[Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)) 提供了一种异步观察目标元素与其祖先元素或顶级文档视窗([viewport](https://developer.mozilla.org/zh-CN/docs/Glossary/Viewport))交叉状态的方法。祖先元素与视窗([viewport](https://developer.mozilla.org/zh-CN/docs/Glossary/Viewport))被称为**根(root)。** --MDN [Intersection Observer API 文档](https://developer.mozilla.org/zh-CN/docs/Web/API/Intersection_Observer_API) +### 描述 + +在以往我们需要判断元素的可见性的时候,主流的方式是坚挺`scroll`事件后,调用目标元素的`getBoundingClientRect()`方法,得到对应于视口左上角的坐标, 再判断是否再视口之内,这种方法确定很明显,`scroll`事件密集触发,计算量很大。很容易造成性能问题。`IntersectionObserver `可以"自动"观察元素是否可见,由于可见的本质是**目标元素与可视区域产生一个交叉区**, 所以这个API叫做**"交叉观察器"** + +### 用法 + +创建一个新的`IntersectionObserver`对象,当其监听到目标元素的可见部分穿过了一个或多个**阈(thresholds)**时,会执行指定的回调函数 + +#### 构造方法 + +`new IntersectionObserver(callback, option = {});` + +- `callback(entries: Array)`: 可见变化时的回调函数 +- `option: Obejct`: 配置对象(可选) + +#### 实例属性和方法 + +属性 + +- `IntersectionObserver.root` **只读**: 监听对象的具体祖先元素([`element`](https://developer.mozilla.org/zh-CN/docs/Web/API/Element))。如果未传入值或值为`null`,则默认使用顶级文档的视窗。 +- `IntersectionObserver.rootMargin` **只读**: 计算交叉时添加到root中的边界盒的举行偏移量, 这个值可以有效的缩小或者扩大根的判定范围。 +- `IntersectionObserver.thresholds` **只读**: 一个包含阈值的列表, 按照升序排序,列表中的每个阈值都是监听对象的交叉区域与边界区域的比率。当监听对象的任何阈值被越过时,都会生成一个通知(Notification)。如果构造器未传入值, 则默认值为0。 + +方法 + +- ``IntersectionObserver.observe()`:开始监听目标元素。 +- ``IntersectionObserver.disconnect()`:停止监听工作。 +- ``IntersectionObserver.tabkeRecords()`:返回所有观察目标的[`IntersectionObserverEntry`](https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserverEntry)对象数组。 +- ``IntersectionObserver.unObserver()`:停止监听。 + +```js +// 创建观察器实例 +const io = new IntersectionObserver(callback, option); +// 开始观察 多次调用observe方法可以观察多个节点 +io.observe(document.getElementById('example')); +io.observe(document.getElementById('exampleA')); +// 停止观察 +io.unobserve(element) +// 关闭观察器 +io.disconnect(); +``` + + + +#### IntersectionObserverEntry 对象 + +IntersectionObserverEntry对象用于提供目标元素的信息, 一共有6个属性 + +- `time`:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒 +- `target`:被观察的目标元素,是一个 DOM 节点对象 +- `rootBounds`:根元素的矩形区域的信息,`getBoundingClientRect()`方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回`null` +- `boundingClientRect`:目标元素的矩形区域的信息 +- `intersectionRect`:目标元素与视口(或根元素)的交叉区域的信息 🚩 +- `intersectionRatio`:目标元素的可见比例,即`intersectionRect`占`boundingClientRect`的比例,完全可见时为`1`,完全不可见时小于等于`0` 🚩 + ## MutationObserver [MutationObserver文档](https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver) From 390db7e20cca5cc121b31cf536116cc2eba01ecc Mon Sep 17 00:00:00 2001 From: etongfu Date: Tue, 28 Dec 2021 17:37:50 +0800 Subject: [PATCH 12/19] feat: Update Unit test --- ...15\347\253\257\346\265\213\350\257\225.md" | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git "a/\345\267\245\347\250\213\345\214\226/\345\211\215\347\253\257\346\265\213\350\257\225.md" "b/\345\267\245\347\250\213\345\214\226/\345\211\215\347\253\257\346\265\213\350\257\225.md" index fabeb63..4af5454 100644 --- "a/\345\267\245\347\250\213\345\214\226/\345\211\215\347\253\257\346\265\213\350\257\225.md" +++ "b/\345\267\245\347\250\213\345\214\226/\345\211\215\347\253\257\346\265\213\350\257\225.md" @@ -48,9 +48,46 @@ - `Jasmine`: 比较老牌的前端测试框架,开箱即用(支持断言和仿真) - `Ava`: 主打异步和性能,但是使用快照和断言需要第三方库的支持 - `Tape`:主打轻量级,对比其他的框架仅仅提供最底层的`API` +- `Karma `: 能在真实的浏览器中测试,强大适配器,可配置其他单测框架,一般会配合 Mocha 或 Jasmine 等一起使用。 对于框架的选择并不是非要选择某一种框架,并不能单纯的说谁好谁坏,只能说哪一款更适合你的工程和团队。 +## 项目实战 + +> 使用karma 和 mocha 为项目加入测试支持。 + +[karma文档](https://karma-runner.github.io/6.3/index.html) + +[mocha文档](https://mochajs.org/) + +### 1. 安装karma + +```bash +npm install --save-dev karma +``` + +### 2. 初始化Karma + +```bash +# 如果你全局安装了 Karma,执行这个 +$ karma init ./karma.conf.js + +# 如果你没有全局安装 Karma,执行这个 +$ ./node_modules/.bin/karma init ./karma.conf.js +``` + + + ## 自动化测试 -目的: **以最低的成本建立和维护自动化测试用例。** \ No newline at end of file +目的: **以最低的成本建立和维护自动化测试用例。** + +## 相关资料 + +博客文章 + +- [使用 Karma + Mocha + Chai 搭建 Web 单元测试环境](https://liuyib.github.io/2020/03/20/use-karma-mocha-chai-to-test/) +- [前端测试的最佳实践](https://kerminate.me/2019/12/22/%E5%89%8D%E7%AB%AF%E6%B5%8B%E8%AF%95%E7%9A%84%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5/) +- [前端测试体系建设与最佳实践总结](https://cloud.tencent.com/developer/article/1540065) +- [搭建 Karma+Mocha+Chai 测试 TypeScript 项目](https://blog.crimx.com/2019/06/19/%E6%90%AD%E5%BB%BA-karma-mocha-chai-%E6%B5%8B%E8%AF%95-typescript-%E9%A1%B9%E7%9B%AE/) +- [Unit testing Node.js applications using Mocha, Chai, and Sinon](https://blog.logrocket.com/unit-testing-node-js-applications-using-mocha-chai-and-sinon/) \ No newline at end of file From e58cb5aa439904c00b0970901c356cc37a74be6f Mon Sep 17 00:00:00 2001 From: "tongfu.e" <531202571@qq.com> Date: Thu, 17 Feb 2022 17:16:53 +0800 Subject: [PATCH 13/19] feat: Add TechnologyTrends. --- Computer/TechnologyTrends.md | 294 +++++++++++++++++++++++++++++++++++ README.md | 17 ++ 2 files changed, 311 insertions(+) create mode 100644 Computer/TechnologyTrends.md diff --git a/Computer/TechnologyTrends.md b/Computer/TechnologyTrends.md new file mode 100644 index 0000000..401f0cc --- /dev/null +++ b/Computer/TechnologyTrends.md @@ -0,0 +1,294 @@ +# Technology Trends + + + +## Front-end + +#### 工具框架 + +- [tauri](https://tauri.studio/): Build smaller, faster, and more secure desktop applications with a web frontend。 +- [turborepo](https://turborepo.org/): Turborepo is a high-performance build system for JavaScript and TypeScript codebases. + +### 编辑器 + +- [ace](https://link.zhihu.com/?target=https%3A//github.com/ajaxorg/ace):Ace ,即 Ajax.org Cloud9 Editor。 +- [CodeMirror](https://link.zhihu.com/?target=https%3A//github.com/codemirror/CodeMirror):一个浏览器端的代码编辑器,用 JS 实现。 +- [esprima](https://link.zhihu.com/?target=https%3A//github.com/ariya/esprima):用于多用途分析的 ECMAScript 解析器。 +- [quill](https://link.zhihu.com/?target=https%3A//github.com/quilljs/quill):一个带有 API 的跨浏览器富文本编辑器。 +- [medium-editor](https://link.zhihu.com/?target=https%3A//github.com/yabwe/medium-editor):Medium.com 使用的所见即所得编辑器的克隆版。 +- [pen](https://link.zhihu.com/?target=https%3A//github.com/sofish/pen):享受在线编辑(支持 markdown)。 +- [jquery-notebook](https://link.zhihu.com/?target=https%3A//github.com/raphaelcruzeiro/jquery-notebook):一个易用的、简洁优雅的文本编辑器。灵感来源于 Medium。 +- [bootstrap-wysiwyg](https://link.zhihu.com/?target=https%3A//github.com/mindmup/bootstrap-wysiwyg):小巧的、兼容 bootstrap 的所见即所得的富文本编辑器。 +- [ckeditor-releases](https://link.zhihu.com/?target=https%3A//github.com/ckeditor/ckeditor-releases):适用于每个人的 web 文本编辑器。 +- [editor](https://link.zhihu.com/?target=https%3A//github.com/lepture/editor):一个 markdown 编辑器,但仍在开发中。 +- [EpicEditor](https://link.zhihu.com/?target=https%3A//github.com/OscarGodson/EpicEditor):一个可嵌入的 JavaScript Markdown 的编辑器,拥有分屏编辑、即时预览、自动保存草稿和离线支持等功能。 +- [jsoneditor](https://link.zhihu.com/?target=https%3A//github.com/josdejong/jsoneditor):查看、编辑和格式化 JSON 的 web 工具。 +- [vim.js](https://link.zhihu.com/?target=https%3A//github.com/coolwanglu/vim.js):拥有持久化 ~/.vimrc 特性,支持 Vim 的 JavaScript 接口。 +- [Squire](https://link.zhihu.com/?target=https%3A//github.com/neilj/Squire):一个 HTML5 富文本编辑器。 +- [TinyMCE](https://link.zhihu.com/?target=https%3A//github.com/tinymce/tinymce):一个 JavaScript 富文本编辑器。 +- [trix](https://link.zhihu.com/?target=https%3A//github.com/basecamp/trix):由 Basecamp 制作,适用于每天写作的富文本编辑器。 +- [Trumbowyg](https://link.zhihu.com/?target=https%3A//github.com/Alex-D/Trumbowyg):一款轻量且惊人的所见即所得 JavaScript 编辑器 +- [Draft.js](https://link.zhihu.com/?target=https%3A//github.com/facebook/draft-js):用于构建文本编辑器的 React 框架。 +- [bootstrap-wysihtml5](https://link.zhihu.com/?target=https%3A//github.com/jhollingworth/bootstrap-wysihtml5):一款简单漂亮的所见即所得编辑器。 +- [wysihtml5](https://link.zhihu.com/?target=https%3A//github.com/xing/wysihtml5):基于 HTML5 ,渐进增强的开源富文本编辑器,利用非常严苛的规则旨在生成符合 HTML5 规范的标签,避免生成非规范标签和同行样式。 +- [raptor-editor](https://link.zhihu.com/?target=https%3A//github.com/PANmedia/raptor-editor):Raptor,一款 HTML5 所见即所得内容编辑器! +- [popline](https://link.zhihu.com/?target=https%3A//github.com/kenshin54/popline):Popline 是一款 HTML5 富文本工具栏。 +- [Summernote](https://link.zhihu.com/?target=https%3A//github.com/summernote/summernote):一个极简的所见即所得编辑器。 + +### 文档 + +- [DevDocs](https://zhuanlan.zhihu.com/DevDocs):一款多合一接口文档阅读器,界面统一、高效、排版精良。 +- [dexy](https://zhuanlan.zhihu.com/dexy):一款格式自由且文艺的文档工具,可用于编写任何包含代码的技术文档。 +- [docco](https://link.zhihu.com/?target=http%3A//jashkenas.github.io/docco/):一款快且脏、百来行、文艺范的文档生成器,用 Literate CoffeeScript 实现。 +- [styledocco](https://zhuanlan.zhihu.com/StyleDocco):根据样式表生成风格规范文档。 +- [Ronn](https://link.zhihu.com/?target=https%3A//github.com/rtomayko/ronn):构建手册。把对人类阅读友好的简单文本文件转换成 roff 格式文件,便于终端显示,也可以转换为 HTML ,便于 Web 端显示。 +- [dox](https://link.zhihu.com/?target=https%3A//github.com/tj/dox):一款 Node.js 开发的 JavaScript 文档生成器。Dox 不会生成结构样式严苛的文档,而是采用 JSON 表示法,以实现 markdown 和 JSDoc 风格标签。 +- [jsdox](https://link.zhihu.com/?target=https%3A//github.com/sutoiku/jsdox):一款将 JSDoc3 转换成 markdown 的文档生成器。 +- [ESDoc](https://link.zhihu.com/?target=https%3A//github.com/esdoc/esdoc):一款为 JavaScript 设计的优秀文档生成器。 +- [YUIDoc](https://zhuanlan.zhihu.com/YUIDoc - JavaScript Documentation Tool):一款提取源码注释生成[接口文档](https://www.zhihu.com/search?q=接口文档&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra={"sourceType"%3A"answer"%2C"sourceId"%3A2348777302})的 Node.js 应用,功能类似 Javadoc and Doxygen 。 +- [coddoc](https://zhuanlan.zhihu.com/coddoc):一款 jsdoc 解析库。Coddoc 与其他工具相比)的不同之处在于,它很容易扩展,通过 coddoc.addTagHandler 和 coddoc.addCodeHandler 来添加标签和代码解析器。 Coddoc 还可以解析源码生成接口文档。 +- [sphinx](https://link.zhihu.com/?target=http%3A//www.sphinx-doc.org/):一款让创建智能且漂亮文档更加简单的工具。 +- [Using JSDoc](https://link.zhihu.com/?target=http%3A//usejsdoc.org/) +- [Beautiful docs](https://link.zhihu.com/?target=http%3A//beautifuldocs.com/):一款 markdown 格式文档阅读器。 +- [documentation.js](https://zhuanlan.zhihu.com/documentation.js):支持 ES2015+ 和流注释的接口文档生成器。 +- [jsduck](https://link.zhihu.com/?target=https%3A//github.com/senchalabs/jsduck):为 Sencha JavaScript 框架开发的接口文档生成器,当然其他框架也能用。 +- [codecrumbs](https://link.zhihu.com/?target=https%3A//github.com/Bogdan-Lyashenko/codecrumbs):一款用于学习和记录代码库的可视化工具,通过在源码中插入面包屑来实现功能。 + +### 文件 + +- [Papa Parse](https://link.zhihu.com/?target=https%3A//github.com/mholt/PapaParse):一款强大的 CSV 库,支持解析 CSV 文件/字符串,也能导出 CSV。 +- [jBinary](https://link.zhihu.com/?target=https%3A//github.com/jDataView/jBinary):对用声明式语法描述文件类型和数据结构的二进制文件,进行高级 I/O(加载、解析、操作、序列化、存储)操作。 +- [diff2html](https://link.zhihu.com/?target=https%3A//github.com/rtfpessoa/diff2html):git 差异输出解析器,也是 HTML 美化器。 +- [jsPDF](https://link.zhihu.com/?target=https%3A//github.com/MrRio/jsPDF):一款 JavaScript PDF 文件生成器。 +- [PDF.js](https://link.zhihu.com/?target=https%3A//github.com/mozilla/pdf.js):一个 JavaScript PDF 阅读器,社区驱动,Mozilla 支持。 + +### [函数式编程](https://www.zhihu.com/search?q=函数式编程&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra={"sourceType"%3A"answer"%2C"sourceId"%3A2348777302}) + +- [underscore](https://link.zhihu.com/?target=https%3A//github.com/jashkenas/underscore):JavaScript 的实用工具。 +- [lodash](https://link.zhihu.com/?target=https%3A//github.com/lodash/lodash):提供一致性、可定制、高性能和额外功能的实用库。 +- [Sugar](https://link.zhihu.com/?target=https%3A//github.com/andrewplummer/Sugar):一个扩展了原生对象功能的 JavaScript 库。 +- [lazy.js](https://link.zhihu.com/?target=https%3A//github.com/dtao/lazy.js):类似 Underscore,但性能更优越 +- [ramda](https://link.zhihu.com/?target=https%3A//github.com/CrossEye/ramda):一个针对 JavaScript 程序员的实用函数库。 +- [mout](https://link.zhihu.com/?target=https%3A//github.com/mout/mout):模块化的 JavaScript 工具库。 +- [mesh](https://link.zhihu.com/?target=https%3A//github.com/crcn/mesh.js):流数据同步工具。 +- [preludejs](https://link.zhihu.com/?target=https%3A//github.com/alanrsoares/prelude-js):JavaScript 硬核函数式编程。 +- [rambda](https://link.zhihu.com/?target=https%3A//github.com/selfrefactor/rambda):*Ramda* 快速小巧的替代品。 + +### 响应式编程 + +- [RxJs](https://link.zhihu.com/?target=https%3A//github.com/Reactive-Extensions/RxJS):对 JavaScript 进行响应式扩展。 +- [Bacon](https://link.zhihu.com/?target=https%3A//github.com/baconjs/bacon.js):JavaScript 的 FPR(函数式响应式编程)库。 +- [Kefir](https://link.zhihu.com/?target=https%3A//github.com/pozadi/kefir):受 Bacon.js 和 RxJS 启发的 FRP 库,专注于高性能和低内存消耗。 +- [Highland](https://link.zhihu.com/?target=http%3A//highlandjs.org/):对 JavaScript 实用工具的重新思考,Highland 能轻易地管理同步和异步信息,而且仅使用标准 JavaScript 和类 Node 流。 +- [Most.js](https://link.zhihu.com/?target=https%3A//github.com/cujojs/most):高性能 FRP 库。 +- [Cycle.js](https://zhuanlan.zhihu.com/Cycle.js):一款用于可预测代码的函数式和响应式 JavaScript 框架。 +- [concent](https://link.zhihu.com/?target=https%3A//github.com/concentjs/concent):绝对是 ❤️ 最简单却 ⚡️ 最强大的 react 状态管理开发框架,可预测、[渐进式](https://www.zhihu.com/search?q=渐进式&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra={"sourceType"%3A"answer"%2C"sourceId"%3A2348777302})、高性能。 + +### 数据结构 + +*数据结构库用于构建一个更复杂的应用。* + +- [immutable-js](https://link.zhihu.com/?target=https%3A//github.com/facebook/immutable-js):不可变的数据集合,包括 Sequence、Range、Repeat、Map、OrderedMap、Set 和 sparse Vector。 +- [mori](https://link.zhihu.com/?target=https%3A//github.com/swannodette/mori):使用 ClojureScript 持久化数据结构和支持原生 JavaScript API 的库。 +- [buckets](https://link.zhihu.com/?target=https%3A//github.com/mauriciosantos/Buckets-JS):完整的、经过充分测试和文档完备的数据结构的 JavaScript 库。 +- [hashmap](https://link.zhihu.com/?target=https%3A//github.com/flesler/hashmap):简单的哈希映射实现,支持任何类型的键值。 + +### 日期 + +*日期库。* + +- [moment](https://link.zhihu.com/?target=https%3A//github.com/moment/moment):解析、验证、操作和显示日期。 +- [moment-timezone](https://link.zhihu.com/?target=https%3A//github.com/moment/moment-timezone):基于 [moment.js](https://www.zhihu.com/search?q=moment.js&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra={"sourceType"%3A"answer"%2C"sourceId"%3A2348777302}) 的时区库。 +- [jquery-timeago](https://link.zhihu.com/?target=https%3A//github.com/rmm5t/jquery-timeago):一款支持自动更新模糊时间戳的 jQuery 插件(如:"4 分钟之前")。 +- [timezone-js](https://link.zhihu.com/?target=https%3A//github.com/mde/timezone-js):让 JavaScript Date 对象拥有时区功能。使用 Olson zoneinfo 文件记录时区数据。 +- [date](https://link.zhihu.com/?target=https%3A//github.com/MatthewMueller/date):对人类友好的 Date()。 +- [ms.js](https://link.zhihu.com/?target=https%3A//github.com/rauchg/ms.js):小巧的毫秒转换工具。 +- [countdown.js](https://link.zhihu.com/?target=https%3A//github.com/gumroad/countdown.js):超小倒计时。 +- [timeago.js](https://zhuanlan.zhihu.com/'3 hours ago'. No dependency.):一个非常轻量级(~1.7 Kb)的用于将时间转化成 xxx时间前 格式的库。 +- [fecha](https://link.zhihu.com/?target=https%3A//github.com/taylorhakes/fecha):轻量级日期格式化和解析库(约 2kb)。可以用来替换 moment.js 格式化和解析日期功能(moment.js 体积比较大——译者注)。 +- [date-fns](https://link.zhihu.com/?target=https%3A//github.com/date-fns/date-fns):现代 JavaScript 日期功能库。 +- [map-countdown](https://link.zhihu.com/?target=https%3A//github.com/dawidjaniga/map-countdown):构建在 Google 地图上的浏览器倒计时。 +- [dayjs](https://link.zhihu.com/?target=https%3A//github.com/iamkun/dayjs):Day.js 是一款拥有和 Moment.js 一样的现代化接口的日期库,但它仅仅有 2kb 大小,可以用来替换 Moment.js。 + +### 字符串 + +- [voca](https://link.zhihu.com/?target=https%3A//github.com/panzerdp/voca):一款超级好用的 JavaScript 字符串库。 +- [selecting](https://link.zhihu.com/?target=https%3A//github.com/EvandroLG/selecting):一个允许你获取用户选定文本的库。 +- [underscore.string](https://link.zhihu.com/?target=https%3A//github.com/epeli/underscore.string):Underscore.js 的字符串操作扩展。 +- [string.js](https://link.zhihu.com/?target=https%3A//github.com/jprichardson/string.js):额外的 JavaScript 字符串方法。 +- [he](https://link.zhihu.com/?target=https%3A//github.com/mathiasbynens/he):健壮的 HTML 实体编码/解码器。 +- [multiline](https://link.zhihu.com/?target=https%3A//github.com/sindresorhus/multiline):多行字符串。 +- [query-string](https://link.zhihu.com/?target=https%3A//github.com/sindresorhus/query-string):解析和字符串化 URL 查询字符串。 +- [URI.js](https://link.zhihu.com/?target=https%3A//github.com/medialize/URI.js/):URL 操作库。 +- [jsurl](https://link.zhihu.com/?target=https%3A//github.com/Mikhus/jsurl):轻量的 URL 操作库。 +- [sprintf.js](https://link.zhihu.com/?target=https%3A//github.com/alexei/sprintf.js):实现字符串格式化。 +- [url-pattern](https://link.zhihu.com/?target=https%3A//github.com/snd/url-pattern):比正则表达式匹配 url 或其它字符串更简单,字符串和数据可相互转化。 +- [plexis](https://link.zhihu.com/?target=https%3A//github.com/plexis-js/plexis):低保真、强大、社区驱动的字符串操作库。 + +### 数字 + +- [Numeral-js](https://link.zhihu.com/?target=https%3A//github.com/adamwdraper/Numeral-js):对数字进行格式化和操作的库。 +- [chance.js](https://link.zhihu.com/?target=https%3A//github.com/chancejs/chancejs):JavaScript 随机生成器,可以生成数字、字符串等。 +- [odometer](https://link.zhihu.com/?target=https%3A//github.com/HubSpot/odometer):流畅的数字过渡效果。 +- [accounting.js](https://link.zhihu.com/?target=https%3A//github.com/josscrowcroft/accounting.js):对数字、金钱、货币进行格式化的轻量库,完全本地化和无依赖。 +- [money.js](https://link.zhihu.com/?target=https%3A//github.com/josscrowcroft/money.js):一个小巧(1kb)的货币转换库,适用于 web 和 nodeJS。 +- [Fraction.js](https://link.zhihu.com/?target=https%3A//github.com/infusion/Fraction.js):一个有理数库。 +- [Complex.js](https://link.zhihu.com/?target=https%3A//github.com/infusion/Complex.js):一个复数库。 +- [Polynomial.js](https://link.zhihu.com/?target=https%3A//github.com/infusion/Polynomial.js):一个多项式库。 +- [Quaternion.js](https://link.zhihu.com/?target=https%3A//github.com/infusion/Quaternion.js):一款适用于 JavaScript 的四元数操作库。 + +### 存储 + +- [store.js](https://link.zhihu.com/?target=https%3A//github.com/marcuswestin/store.js):为所有浏览器封装了 LocalStorage,而没有使用 cookies 和 flash。隐秘地使用 localStorage、globalStorage 和用户数据。 +- [localForage](https://link.zhihu.com/?target=https%3A//github.com/mozilla/localForage):改善后的离线存储。其封装了 IndexedDB、WebSQL 和 localStorage,拥有操作简单和强大的 API。 +- [jStorage](https://link.zhihu.com/?target=https%3A//github.com/andris9/jStorage):jStorage 是一个简单的键值对数据库,用于在浏览器端存储数据。 +- [cross-storage](https://link.zhihu.com/?target=https%3A//github.com/zendesk/cross-storage):获得权限后,能跨域名本地存储。 +- [basket.js](https://link.zhihu.com/?target=https%3A//github.com/addyosmani/basket.js):用 localStorage 加载和缓存脚本的资源加载器。 +- [bag.js](https://link.zhihu.com/?target=https%3A//github.com/nodeca/bag.js):可以缓存脚本和加载资源,与 basket.js 相似,但增加了键值对接口和对 localStorage / websql / indexedDB 的支持。 +- [basil.js](https://link.zhihu.com/?target=https%3A//github.com/Wisembly/basil.js):智能的 JavaScript 数据持久层库。 +- [jquery-cookie](https://link.zhihu.com/?target=https%3A//github.com/carhartl/jquery-cookie):轻量简单的、用于读取、编辑和删除 cookie 的 jQuery 插件。 +- [js-cookie](https://link.zhihu.com/?target=https%3A//github.com/js-cookie/js-cookie):一款简单、轻量的 cookies 读写删 jQuery 插件。 +- [Cookies](https://link.zhihu.com/?target=https%3A//github.com/ScottHamper/Cookies):一个客户端 Cookie 操作库。 +- [DB.js](https://link.zhihu.com/?target=https%3A//github.com/aaronpowell/db.js/):基于 Promise 的、封装了 IndexedDB 的库。 +- [lawnchair.js](https://link.zhihu.com/?target=https%3A//github.com/brianleroux/lawnchair/):简单的客户端 JSON 存储。 +- [sql.js](https://link.zhihu.com/?target=https%3A//github.com/kripken/sql.js):基于 Emscripten 将 SQLite 编译成 JavaScript。 +- [crumbsjs](https://link.zhihu.com/?target=https%3A//github.com/nirtz89/crumbsjs):一款轻量级原生 ES6 cookies 和本地存储 JavaScript 库。 +- [awesome-web-storage](https://link.zhihu.com/?target=https%3A//github.com/softvar/awesome-web-storage):你必须知道的所有客户端存储知识。 +- [rxdb](https://rxdb.info/): A client side, offline-first, reactive database for JavaScript Applications。 + +### 颜色 + +- [randomColor](https://link.zhihu.com/?target=https%3A//github.com/davidmerfield/randomColor):JavaScript 颜色生成器。 +- [chroma.js](https://link.zhihu.com/?target=https%3A//github.com/gka/chroma.js):拥有各种各样颜色操作的 JavaScript 库。 +- [color](https://link.zhihu.com/?target=https%3A//github.com/MoOx/color):JavaScript 颜色转换和操作库。 +- [colors](https://link.zhihu.com/?target=https%3A//github.com/mrmrs/colors):更智能的默认 web 颜色。 +- [PleaseJS](https://link.zhihu.com/?target=https%3A//github.com/Fooidge/PleaseJS):随机创建出赏心悦目的颜色和配色方案的 JavaScript 库。 +- [TinyColor](https://link.zhihu.com/?target=https%3A//github.com/bgrins/TinyColor):快速、轻巧的颜色操作和转换库。 +- [Vibrant.js](https://link.zhihu.com/?target=https%3A//github.com/jariz/vibrant.js/):从图像提取主要颜色。 + +### 国际化和本地化 + +- [i18next](https://link.zhihu.com/?target=https%3A//github.com/i18next/i18next):用 JavaScript 实现国际化(i18n)简单的方法。 +- [polyglot](https://link.zhihu.com/?target=https%3A//github.com/airbnb/polyglot.js):小巧的国际化助手库。 +- [babelfish](https://link.zhihu.com/?target=https%3A//github.com/nodeca/babelfish/):提供友好易懂 API 的 i18n 库,并且内置多种支持。 +- [ttag](https://link.zhihu.com/?target=https%3A//github.com/ttag-org/ttag):基于 ES6 标签模板和优秀的旧 GNU gettext ,新潮的 JavaScript 国际化、本地化库。 + +### 控制流 + +- [async](https://link.zhihu.com/?target=https%3A//github.com/caolan/async):适用于 node.js 和浏览器的异步工具库。 +- [q](https://link.zhihu.com/?target=https%3A//github.com/kriskowal/q):实现异步 promise 的 JavaScript 工具。 +- [step](https://link.zhihu.com/?target=https%3A//github.com/creationix/step/):一款可以使逻辑执行更简单的异步控制流库。 +- [contra](https://link.zhihu.com/?target=https%3A//github.com/bevacqua/contra/):函数式风格实现的异步流控制。 +- [Bluebird](https://link.zhihu.com/?target=https%3A//github.com/petkaantonov/bluebird/):功能齐全的 promoise 库,专注于功能革新和性能提升。 +- [when](https://link.zhihu.com/?target=https%3A//github.com/cujojs/when):快速可靠的、Promises/A+ 规范的 when() 实现,而且拥有其它异步操作的优秀特性。 +- [ObjectEventTarget](https://link.zhihu.com/?target=https%3A//github.com/gartz/ObjectEventTarget):为普通对象添加事件监听原型(就如浏览器 DOMElement 的 EventTarget 一样)。 +- [sporadic](https://link.zhihu.com/?target=https%3A//github.com/marcoonroad/sporadic):位于 promise 顶部的组合并发抽象(就像流、协程和类似 Go channels 一样),支持 Node.js 和浏览器引擎。 + +### 路由 + +- [director](https://link.zhihu.com/?target=https%3A//github.com/flatiron/director):一个小巧的、与 URL 同构的路由。 +- [page.js](https://link.zhihu.com/?target=https%3A//github.com/visionmedia/page.js):受 Express router 启发的小型客户端路由器(约为1200字节)。 +- [pathjs](https://link.zhihu.com/?target=https%3A//github.com/mtrpcic/pathjs):简单、轻量的 web 路由。 +- [crossroads](https://link.zhihu.com/?target=https%3A//github.com/millermedeiros/crossroads.js):JavaScript 路由。 +- [davis.js](https://link.zhihu.com/?target=https%3A//github.com/olivernn/davis.js):基于 pushState 可降级 RESTful 风格的 JavaScript 路由。 +- [navaid](https://link.zhihu.com/?target=https%3A//github.com/lukeed/navaid):一款浏览器端的导航辅助系统(也可以成为路由),体积才 850 字节! + +### 安全性 + +- [DOMPurify](https://link.zhihu.com/?target=https%3A//github.com/cure53/DOMPurify):针对 HTML、MathML 和 SVG 的仅支持 DOM 的超快速、高容错的 XSS 过滤器。 +- [js-xss](https://link.zhihu.com/?target=https%3A//github.com/leizongmin/js-xss):通过白名单配置,即可过滤不信任的 HTML(防止 XSS 攻击)。 +- [xss-filters](https://link.zhihu.com/?target=https%3A//github.com/yahoo/xss-filters):Yahoo 出品的安全 XSS 过滤器。 + +### 日志 + +- [log](https://link.zhihu.com/?target=https%3A//github.com/adamschwartz/log):带样式的 Console.log。 +- [Conzole](https://link.zhihu.com/?target=https%3A//github.com/Oaxoa/Conzole):对 JavaScript 原生 console 对象方法和功能进行封装的 debug 面板,并将面板显示在页面内。 +- [console.log-wrapper](https://link.zhihu.com/?target=https%3A//github.com/patik/console.log-wrapper):将日志清晰地记录到 console,兼容所有浏览器。 +- [loglevel](https://link.zhihu.com/?target=https%3A//github.com/pimterry/loglevel):最轻量的 JavaScript 日志记录工具库,向封装后的 console.log 方法增加可靠的日志等级。 +- [minilog](https://link.zhihu.com/?target=http%3A//mixu.net/minilog/):轻量的、流式 API 显示的、可用于客户端和服务器端的日志记录库。 +- [storyboard](https://zhuanlan.zhihu.com/Storyboard by guigrpa):通用日志库 + Chrome 扩展。提供一个单一入口查看包含客户端和服务端的任务触发日志。 + +### 正则表达式 + +- [RegEx101](regex101: build, test, and debug regex):在线的 JavaScript 正则表达式测试器和调试器。同时也支持 Python、PHP 和 PCRE。 +- [RegExr](regexr: Learn, Build, & Test RegEx):用于创建、测试和学习正则表达式的 HTML/JS 工具。 + +### 语音命令 + +- [annyang](https://link.zhihu.com/?target=https%3A//github.com/TalAter/annyang):向网站添加语音命令的语音识别库。 +- [voix.js](https://link.zhihu.com/?target=https%3A//github.com/pazguille/voix):向网站、app 或游戏添加语音命令的 JavaScript 库。 + +### API + +- [axios](https://link.zhihu.com/?target=https%3A//github.com/axios/axios):基于 Promise 的 HTTP 客户端,适用于 Node.js 和 浏览器。 +- [bottleneck](https://link.zhihu.com/?target=https%3A//github.com/SGrondin/bottleneck):强大的速度限制器,使调节流量变得更容易。 +- [oauth-signature-js](https://link.zhihu.com/?target=https%3A//github.com/bettiolo/oauth-signature-js):适用于 node 和 浏览器的 OAuth 1.0a 签名生成器。 +- [amygdala](https://link.zhihu.com/?target=https%3A//github.com/lincolnloop/amygdala):为 Web 应用提供 RESTful HTTP 客户端解决方案。 +- [jquery.rest](https://link.zhihu.com/?target=https%3A//github.com/jpillora/jquery.rest):一个让 RESTful API 更易用的 jQuery 插件。 +- [Rails Ranger](https://link.zhihu.com/?target=https%3A//github.com/victor-am/rails-ranger):为 Ruby Tails 接口设计的严格的 REST 客户端。 +- [wretch](https://link.zhihu.com/?target=https%3A//github.com/elbywan/wretch):一款小巧的直觉语法系 fetch 功能封装包。 +- [FarFetch](https://link.zhihu.com/?target=https%3A//github.com/WebsiteBeaver/far-fetch):简单易用的现代 Fetch 接口封装,简化了文件上传。 +- [Optic](https://link.zhihu.com/?target=https%3A//github.com/opticdev/optic):Optic 用于对 API 自动测试和文档生成。 +- [SWR](https://link.zhihu.com/?target=https%3A//github.com/vercel/swr):用于远端数据拉取的 React Hooks 库。 + +### 流媒体 + +- [Tailor](https://link.zhihu.com/?target=https%3A//github.com/zalando/tailor):适用于前端微服务的流媒体布局服务,灵感来自 Facebook BigPipe。 + +### 视觉检测 + +- [tracking.js](https://link.zhihu.com/?target=https%3A//github.com/eduardolundgren/tracking.js):在 web 上实现计算视觉的一种现代方法。 +- [ocrad.js](https://link.zhihu.com/?target=https%3A//github.com/antimatter15/ocrad.js):基于 Emscripten 的 JavaScript OCR 实现。 + +### 机器学习 + +- [ConvNetJS](https://link.zhihu.com/?target=https%3A//github.com/karpathy/convnetjs):JavaScript 深度学习。在浏览器环境训练[卷积神经网络](https://www.zhihu.com/search?q=卷积神经网络&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra={"sourceType"%3A"answer"%2C"sourceId"%3A2348777302})(或者普通神经网络)。 +- [DN2A](https://link.zhihu.com/?target=https%3A//github.com/dn2a/dn2a-javascript):数字神经网络架构。 +- [Brain.js](https://link.zhihu.com/?target=https%3A//github.com/harthur/brain):JavaScript 神经网络。 +- [Mind.js](https://link.zhihu.com/?target=https%3A//github.com/stevenmiller888/mind):一款灵活的神经网络库。 +- [Synaptic.js](https://link.zhihu.com/?target=https%3A//github.com/cazala/synaptic):适用于 Node.js 和浏览器的无架构神经网络库。 +- [TensorFlow.js](https://link.zhihu.com/?target=https%3A//js.tensorflow.org/):一款用于在 浏览器和 Node.js 中训练和部署 ML 模型的 JavaScript 库。 +- [ml5.js](https://zhuanlan.zhihu.com/ml5js·Friendly Machine Learning For The Web):友好的 Web 端机器学习库。 +- [Synapses](https://link.zhihu.com/?target=https%3A//github.com/mrdimosthenis/Synapses):轻量级跨平台神经网络库。 + +### 浏览器检测 + +- [bowser](https://link.zhihu.com/?target=https%3A//github.com/ded/bowser):一个浏览器检测器,特点是小巧快速且 API 丰富。 + +### 基准测试 + +- [benchmark.js](https://link.zhihu.com/?target=https%3A//github.com/bestiejs/benchmark.js):jsPerf.com 使用的基准测试库。 +- [matcha](https://link.zhihu.com/?target=https%3A//github.com/logicalparadox/matcha):一款咖啡因驱动的基准测试简单实现。 + +### 动画 + +- [velocity](https://link.zhihu.com/?target=https%3A//github.com/julianshapiro/velocity):加速 JavaScript 动画。 +- [jquery.transit](https://link.zhihu.com/?target=https%3A//github.com/rstacruz/jquery.transit):拥有超级流畅的 CSS3 变换和过渡效果的 jQuery 插件。 +- [impess.js](https://link.zhihu.com/?target=https%3A//github.com/impress/impress.js):在 HTML 文档里,运用 CSS3 变换和过渡制作类似 Prezi 的展现效果。 +- [bounce.js](https://link.zhihu.com/?target=https%3A//github.com/tictail/bounce.js):可以立刻创建有趣的 CSS3 动画。 +- [GreenSock-JS](https://link.zhihu.com/?target=https%3A//github.com/greensock/GreenSock-JS):适用于所有主流浏览器的高性能 HTML5 动画。 +- [TransitionEnd](https://link.zhihu.com/?target=https%3A//github.com/EvandroLG/transitionEnd):TransitionEnd 是一个运用 transitonend 事件的、跨浏览器的库。 +- [Dynamics.js](https://link.zhihu.com/?target=https%3A//github.com/michaelvillar/dynamics.js):用于创建符合物理运动规律的 CSS 动画库。 +- [the-cube](https://link.zhihu.com/?target=https%3A//github.com/pstadler/the-cube):The Cube 是一个 CSS3 过渡效果实验。 +- [Effeckt.css](https://link.zhihu.com/?target=https%3A//github.com/h5bp/Effeckt.css):一款高性能过渡动画库。 +- [animate.css](https://link.zhihu.com/?target=https%3A//github.com/daneden/animate.css):要多易用有多易用的跨浏览器 CSS 动画库。 +- [textillate](https://link.zhihu.com/?target=https%3A//github.com/jschr/textillate):适用于 CSS3 文本动画的简单插件。 +- [move.js](https://link.zhihu.com/?target=https%3A//github.com/visionmedia/move.js):基于 CSS3 的 JavaScript 动画框架。 +- [animatable](https://link.zhihu.com/?target=https%3A//github.com/LeaVerou/animatable):一个属性,两个值,无穷个可能性。 +- [shuffle-images](https://link.zhihu.com/?target=https%3A//github.com/peachananr/shuffle-images):简单有创意地打乱图片。[Just a moment...](https://zhuanlan.zhihu.com/Just a moment...) +- [smoothState.js](https://link.zhihu.com/?target=https%3A//github.com/miguel-perez/smoothState.js):免打扰式页面过渡 jQuery 库。[http://smoothstate.com/](https://link.zhihu.com/?target=http%3A//smoothstate.com/) +- [Anime.js](https://link.zhihu.com/?target=http%3A//animejs.com/):一款 JavaScript 动画引擎。[anime.js](https://zhuanlan.zhihu.com/anime.js) +- [particles.js](https://link.zhihu.com/?target=https%3A//github.com/VincentGarreau/particles.js):用于创建粒子的轻量 JavaScript 库。 +- [tsParticles](https://link.zhihu.com/?target=https%3A//github.com/matteobruni/tsparticles):particles.js 全新升级版本,修复了 bug ,增加许多新功能。 +- [particles-bg](https://link.zhihu.com/?target=https%3A//github.com/lindelof/particles-bg):一款轻量的粒子运动动画背景 React 组件。 + +### 图片处理 + +- [lena.js](https://link.zhihu.com/?target=https%3A//github.com/davidsonfellipe/lena.js):具有滤镜和实用功能的图像处理库。 +- [pica](https://link.zhihu.com/?target=https%3A//github.com/nodeca/pica):高质量地调整图片大小(使用快速、纯 JS 实现的 Lanczos 滤镜算法)。 +- [cropper](https://link.zhihu.com/?target=https%3A//github.com/fengyuanchen/cropper):一个简单的图像裁剪 jQuery 插件。 + + + +## Backend + diff --git a/README.md b/README.md index f891066..ed3572b 100644 --- a/README.md +++ b/README.md @@ -18,36 +18,53 @@ - [Javascript中函数作为对象的魅力](https://github.com/QDMarkMan/CodeBlog/blob/master/Javascript/Javascript中函数作为对象的魅力.md) - [关于原型的一些东西](https://github.com/QDMarkMan/CodeBlog/blob/master/Javascript/关于原型的一些东西.md) - [一些尺寸相关的API](https://github.com/QDMarkMan/CodeBlog/blob/master/CSS/一些尺寸相关的API.md) + - `NodeJS💪` - [让NodeJS在项目中发光发热](https://github.com/QDMarkMan/CodeBlog/blob/master/Node/%E8%AE%A9NodeJS%E5%9C%A8%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%8F%91%E5%85%89%E5%8F%91%E7%83%AD.md) - [NodeJS发光发热之打包hooks](https://github.com/QDMarkMan/CodeBlog/blob/master/Node/NodeJS%E5%8F%91%E5%85%89%E5%8F%91%E7%83%AD%E4%B9%8B%E6%89%93%E5%8C%85hooks.md) + - [Vue部分相关⭐](https://github.com/QDMarkMan/CodeBlog/blob/master/Vue/README.md) - [Vue知识集锦](https://github.com/QDMarkMan/CodeBlog/blob/master/Vue/Vue开发中问题集锦.md) - [Vue-cli2.9 + webpack4.0升级](https://github.com/QDMarkMan/CodeBlog/blob/master/Vue/Vue-cli2.9更新webpackV4.0.md) - [服务器发布Vue项目指南](https://github.com/QDMarkMan/CodeBlog/blob/master/Vue/%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%8F%91%E5%B8%83Vue%E9%A1%B9%E7%9B%AE%E6%8C%87%E5%8D%97.md) - [加快Vue项目的开发速度](https://github.com/QDMarkMan/CodeBlog/blob/master/Vue/%E5%8A%A0%E5%BF%ABVue%E9%A1%B9%E7%9B%AE%E7%9A%84%E5%BC%80%E5%8F%91%E9%80%9F%E5%BA%A6.md) + - [Electron客户端相关💻](https://github.com/QDMarkMan/CodeBlog/tree/master/Electron) - [Electron入门](https://github.com/QDMarkMan/CodeBlog/tree/master/Electron) - [Electron-builder打包详解](https://github.com/QDMarkMan/CodeBlog/blob/master/Electron/electron-builder%E6%89%93%E5%8C%85%E8%AF%A6%E8%A7%A3.md) - [Electron单例检测](https://github.com/QDMarkMan/CodeBlog/blob/master/Electron/SingleInstance.md) + - [Webpack部分相关🎫](https://github.com/QDMarkMan/CodeBlog/blob/master/Webpack/webpack基础合集.md) - [不得不了解的Babel](https://github.com/QDMarkMan/CodeBlog/blob/master/Webpack/%E4%B8%8D%E5%BE%97%E4%B8%8D%E4%BA%86%E8%A7%A3%E7%9A%84Babel.md) - [webapck合集(新)](https://github.com/QDMarkMan/CodeBlog/blob/master/Webpack/webpack合集.md) - [tree-shaking](https://github.com/QDMarkMan/CodeBlog/blob/master/Webpack/webpack中tree-shaking的威力.md) + - [Ionic混合开发相关📱](https://github.com/QDMarkMan/CodeBlog/blob/master/Ionic/READEME.md) - [Ionic开发App中重要的部分](https://github.com/QDMarkMan/CodeBlog/blob/master/Ionic/使用Ionic构建一个HybridApp.md) + - [Typescript基础以及进阶部分🎫](https://github.com/QDMarkMan/CodeBlog/blob/master/TypeScript/READEME.md) - [TypeScript相关](https://github.com/QDMarkMan/CodeBlog/blob/master/TypeScript/READEME.md) - [简单算法实现](https://github.com/QDMarkMan/CodeBlog/blob/master/TypeScript/%E7%AE%80%E5%8D%95%E7%AE%97%E6%B3%95%E5%AE%9E%E7%8E%B0.md) + - [Flutter/Dart部分](https://github.com/QDMarkMan/CodeBlog/blob/master/Dart/Flutter汇总.md) - [Flutter大杂烩](https://github.com/QDMarkMan/CodeBlog/blob/master/Dart/Flutter汇总.md) + - `服务端相关` + - [1千行MySQL学习笔记](https://github.com/QDMarkMan/CodeBlog/blob/master/Server/1%E5%8D%83%E8%A1%8CMySQL%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0.md) - [Docker笔记(更新中)](https://github.com/QDMarkMan/CodeBlog/blob/master/Server/Docker基础指南.md) - [MySQL基础总结笔记](https://github.com/QDMarkMan/CodeBlog/blob/master/Server/MySQL总结.md) + +- `计算机合集` + + - [TechnologyTrends](https://github.com/QDMarkMan/CodeBlog/blob/master/Computer/TechnologyTrends.md) + - [MD写作模版](https://github.com/QDMarkMan/CodeBlog/blob/master/MDDemo.md) + - [Readme模板](https://github.com/QDMarkMan/CodeBlog/blob/master/ReadmeTemplate.md) + + ## 相关好文(分享🎉) 在划水的时候发现的一些高质量好文章,这些文章包含各个领域,在我看来每一篇都值得反复阅读,我自己也会反复的去看。这个就不分类了。如有侵权请马上联系我删除😀 From e9d5e5b6363c137c1f5af1310a5e54ed0832fe1d Mon Sep 17 00:00:00 2001 From: "tongfu.e" Date: Mon, 19 Sep 2022 09:59:08 +0800 Subject: [PATCH 14/19] feat: Add Software Engineering at Google . --- Computer/SoftwareEngineeringGoogle.md | 55 +++++++++++++++++++++++++++ Computer/TechnologyTrends.md | 2 - Electron/Electron-Protocol.md | 9 +++++ README.md | 3 +- 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 Computer/SoftwareEngineeringGoogle.md create mode 100644 Electron/Electron-Protocol.md diff --git a/Computer/SoftwareEngineeringGoogle.md b/Computer/SoftwareEngineeringGoogle.md new file mode 100644 index 0000000..2a70ea8 --- /dev/null +++ b/Computer/SoftwareEngineeringGoogle.md @@ -0,0 +1,55 @@ +# Software Engineering at Google + +> Software Engineering at Google 笔记。 + +## 第一章 软件工程是什么? + +> "软件工程是随着时间推移的编程。"编程当然是软件工程的一个重要部分:毕竟,编程首先是生成新软件的方式。如果你接受这一区别,那么很明显,我们可能需要在编程任务(开发)和软件工程任务(开发、修改、维护)之间进行划分。时间的增加为编程增加了一个重要的新维度。这是一个立方体三维模型不是正方形的二维模型,距离不是速度。软件工程不是编程。 + +软件工程可以定义为多人协作开发多版本程序。**人是软件工程的核心**,代码是重要的产出。 + +[文章地址](https://qiangmzsx.github.io/Software-Engineering-at-Google/#/zh-cn/Chapter-1_What_Is_Software_Engineering/Chapter-1_What_Is_Software_Engineering) + + +**编程和软件**之间有三个关键的区别 + +- 时间 +- 规模 +- 权衡取舍 + +在一个**软件工程项目**中,**工程师需要更多关注成本和需求变化**。 在软件工程中我们需要更加的关注的是**规模和效率**,无论是对于我们的生产的软件,还是对生产软件的组织。 + +如果你正在维护一个由其他工程师使用的项目,那么关于“有效”与“可维护”最重要的一课就是我们所说的**海勒姆定律**: + +> 当一个API有足够多的用户时,在约定中你承诺的什么都无所谓,所有在你系统里面被观察到的行为都会被一些用户直接依赖。 + +当我们在讨论软件工程的时候,这本书重点是在讨论下面的两件事情 + +- 一个组织和一个程序员的策略,如何评估和改进你的最佳实践,以及用于可维护软件的工具和技术。 +- 你如何维护你的代码,让它正常运行。 + +## 第二章 新成员如何融入团队? + +> 软件开发是团队的努力。要在工程团队或任何其他创造性合作中取得成功,你需要围绕谦逊、尊重和信任的核心原则重新定义你的行为。 + +[文章地址](https://qiangmzsx.github.io/Software-Engineering-at-Google/#/zh-cn/Chapter-2_How_to_Work_Well_on_Teams/Chapter-2_How_to_Work_Well_on_Teams?id=%e7%ac%ac%e4%ba%8c%e7%ab%a0-%e5%a6%82%e4%bd%95%e8%9e%8d%e5%85%a5%e5%9b%a2%e9%98%9f) + +- 早期分享:如果你对世界隐藏着牛逼的想法,并在未完美之前拒绝向任何人进行展示,那么就是在进行一场巨大的赌博。因为在早期非常容易犯基本的设计错误。早起的失误的可能性非常高,你越早的征求反馈,这种风险就越低。**早失败,快失败,经常失败**是一句经得起考验的至理名言。 + +- 巴士因子:团队里因巴士撞倒的多少人,会导致项目失败。简答的来说,你需要进行团队工作而不是独自工作,人们很容易忘记,独自工作是一项艰苦的工作,比人们自认为的慢的多。编程很难,软件工程很难,你需要另外一双眼睛。 + +总结:几乎任何规模的软件工作的基础都是一个运作良好的团队。尽管软件开发者单打独斗的 "天才神话 "仍然存在,但事实是,没有人能够真正地单干。一个软件组织要想经受住时间的考验,就必须有一种健康的文化,植根于谦逊、信任和尊重,围绕着团队而不是个人。此外,软件开发的创造性要求人们承担风险并偶尔失败;为了让人们接受这种失败,必须有一个健康的团队环境。 + + +## 知识共享 + +> 你的组织需要一种学习文化,这需要创造一种心理上的安全感,允许人们承认自己缺乏知识。 + +在某些方面,知识是软件工程组织字重要的无形资产,而知识的共享对于使组织在面对变化时具有弹性和冗余至关重要。一种促进开放和诚实的知识共享的文化可以在整个组织内有效的分配这些知识,并使该组织能够随着时间的推移而扩散。在大多数情况下,对更容易的知识共享的投入会在一个公司的生命周期中获取很多倍的回报。 + +## 测量工程效率 + +> r如果你有一个蓬勃发展的业务想要扩增。据推测,为了增加你的业务范围,你也需要增加你的工程组织的规模。然而,随着组织规模的线性增长,沟通成本也呈二次曲线增长。增加人员对扩大业务范围是必要的,但沟通成本不会随着你增加人员而线性扩展。因此,你将无法根据你的工程组织的规模线性地扩大你的业务范围。 + + +# 总结 diff --git a/Computer/TechnologyTrends.md b/Computer/TechnologyTrends.md index 401f0cc..ba3fc90 100644 --- a/Computer/TechnologyTrends.md +++ b/Computer/TechnologyTrends.md @@ -1,7 +1,5 @@ # Technology Trends - - ## Front-end #### 工具框架 diff --git a/Electron/Electron-Protocol.md b/Electron/Electron-Protocol.md new file mode 100644 index 0000000..fb15b63 --- /dev/null +++ b/Electron/Electron-Protocol.md @@ -0,0 +1,9 @@ +# 通过协议打开Electron应用 + +> + +##总结 + +## 参考 + +- [Electron网页调起客户端](https://xuxin123.com/electron/url-scheme/) \ No newline at end of file diff --git a/README.md b/README.md index ed3572b..0ec2b0c 100644 --- a/README.md +++ b/README.md @@ -91,4 +91,5 @@ - [鹅厂技术说 | 深入理解前端性能监控](https://zhuanlan.zhihu.com/p/65065472) - [How to Learn Software Design and Architecture - a Roadmap](https://www.freecodecamp.org/news/software-design/) - [架构制图:工具与方法论](https://zhuanlan.zhihu.com/p/384958911) - +- [架构制图:工具与方法论](https://zhuanlan.zhihu.com/p/384958911) +- [Software-Engineering-at-Google](https://qiangmzsx.github.io/Software-Engineering-at-Google/#/?id=software-engineering-at-google) From 1ce74caf40a6931a3c11135cd06b2f52a40f6535 Mon Sep 17 00:00:00 2001 From: "tongfu.e" Date: Fri, 10 Mar 2023 10:22:40 +0800 Subject: [PATCH 15/19] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E7=AC=94?= =?UTF-8?q?=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 6148 -> 8196 bytes .gitignore | 1 + Computer/A-Philosophy-of-Software-Design.md | 14 +++ Computer/SoftwareEngineeringGoogle.md | 12 +- Computer/TechnologyTrends.md | 2 +- ...23\345\214\205\350\257\246\350\247\243.md" | 39 ++++++- "Go/Go\345\237\272\347\241\200.md" | 12 +- React/Hook.md | 7 +- Template/RFC Template.md | 103 ++++++++++++++++++ ...76\350\256\241\346\250\241\347\211\210.md" | 49 +++++++++ ...\220\206@types\346\226\207\344\273\266.md" | 26 +++++ ...20\347\240\201\347\254\224\350\256\260.md" | 10 +- ...4\272\206\350\247\243\347\232\204Babel.md" | 6 + 13 files changed, 256 insertions(+), 25 deletions(-) create mode 100644 .gitignore create mode 100644 Computer/A-Philosophy-of-Software-Design.md create mode 100644 Template/RFC Template.md create mode 100644 "Template/\346\226\271\346\241\210\350\256\276\350\256\241\346\250\241\347\211\210.md" create mode 100644 "TypeScript/\347\256\241\347\220\206@types\346\226\207\344\273\266.md" rename "TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" => "TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\347\254\224\350\256\260.md" (77%) diff --git a/.DS_Store b/.DS_Store index 3a6d9df1a3452823a4e10ca9dfe75ac9aa976db1..0981b5bd8f9220024b8695722a4d51f3c9755fba 100644 GIT binary patch literal 8196 zcmeHM&2G~`5T4CX>$CzD2~Y(>vc$D22?ErLOGp!;BEg}q+5=R@j;%JTV@Gz<2&ziC z7tY*x1@62@c>^AT6MXxV*4`u>5mI)g-C29T+1dGaVtY13#2N#?Mzl&q7Alu3%V?$) zKF;ezDX2U5AsO_E2Gpm3lI<{VPoT{W!+>GHFkl!k3>XIf2L|xY=Ea)v-j}1MH4GRA z=8^&ae6UfutSdQ^Qan1)h!g;_gxjK^k32x=*h0hR~J-f)yuR4l*_5qketLUvI1la%WT4x)-)Fw zr!=c^OU>=W-GFw5^F3^wD~^1okRYhe&ai->!Ql|dR!2nF!6PW1i9L0aD2yY%b^PgX z>DKeUa`M^D4EYmyZ~yOXY<{YtdS^4xHn7==9zGAZ@tGTYj~R z&G5#3*W2p^!^4%^TXEEPJ5i7bg^nKp@@~Hq`SGw34RZ zeL(aCV17n$6GAY@)>NHrI2LIS&j~G(c_`+lS)_fK^+f2l=_J2J4B_}U^w=Ety?F5R zGOb##3MMXgY?0Ic17@}_j%5~~Wj-0gFpmuU0hw58lmGw# delta 169 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{MGjdEU6q~50$jJ)gfW#*M7TGKc;;}IJG2}C( zFr=mwC+8&P=jTkGC!{d>g|H|GT%cD(e)BgGLFSDORm_XoIXDEFf%w&zl@~wxd!wdkz2_5tR diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1036bd2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.obsidian/ \ No newline at end of file diff --git a/Computer/A-Philosophy-of-Software-Design.md b/Computer/A-Philosophy-of-Software-Design.md new file mode 100644 index 0000000..7ea5bdd --- /dev/null +++ b/Computer/A-Philosophy-of-Software-Design.md @@ -0,0 +1,14 @@ +> A-Philosophy-of-Software-Design (软件设计哲学)阅读笔记。 + +## 写在前面 + +首先我们来说, **这本书讲的是关于如何使用复杂性来指导软件设计的整个生命周期** + +### 总体目标 + +总体上来说这本书目前有两个目标 + +1. 描述软件复杂性的性质:“复杂性”是什么意思,为什么重要,以及当程序具有不必要的复杂性时如何识别? +2. 介绍可在软件开发过程中使用的技术,以最大程度的减少复杂性。 + + diff --git a/Computer/SoftwareEngineeringGoogle.md b/Computer/SoftwareEngineeringGoogle.md index 2a70ea8..174d982 100644 --- a/Computer/SoftwareEngineeringGoogle.md +++ b/Computer/SoftwareEngineeringGoogle.md @@ -2,7 +2,7 @@ > Software Engineering at Google 笔记。 -## 第一章 软件工程是什么? +## 软件工程是什么? > "软件工程是随着时间推移的编程。"编程当然是软件工程的一个重要部分:毕竟,编程首先是生成新软件的方式。如果你接受这一区别,那么很明显,我们可能需要在编程任务(开发)和软件工程任务(开发、修改、维护)之间进行划分。时间的增加为编程增加了一个重要的新维度。这是一个立方体三维模型不是正方形的二维模型,距离不是速度。软件工程不是编程。 @@ -28,15 +28,15 @@ - 一个组织和一个程序员的策略,如何评估和改进你的最佳实践,以及用于可维护软件的工具和技术。 - 你如何维护你的代码,让它正常运行。 -## 第二章 新成员如何融入团队? +## 新成员如何融入团队? > 软件开发是团队的努力。要在工程团队或任何其他创造性合作中取得成功,你需要围绕谦逊、尊重和信任的核心原则重新定义你的行为。 [文章地址](https://qiangmzsx.github.io/Software-Engineering-at-Google/#/zh-cn/Chapter-2_How_to_Work_Well_on_Teams/Chapter-2_How_to_Work_Well_on_Teams?id=%e7%ac%ac%e4%ba%8c%e7%ab%a0-%e5%a6%82%e4%bd%95%e8%9e%8d%e5%85%a5%e5%9b%a2%e9%98%9f) -- 早期分享:如果你对世界隐藏着牛逼的想法,并在未完美之前拒绝向任何人进行展示,那么就是在进行一场巨大的赌博。因为在早期非常容易犯基本的设计错误。早起的失误的可能性非常高,你越早的征求反馈,这种风险就越低。**早失败,快失败,经常失败**是一句经得起考验的至理名言。 +- **早期分享**:如果你对世界隐藏着牛逼的想法,并在未完美之前拒绝向任何人进行展示,那么就是在进行一场巨大的赌博。因为在早期非常容易犯基本的设计错误。早起的失误的可能性非常高,你越早的征求反馈,这种风险就越低。**早失败,快失败,经常失败**是一句经得起考验的至理名言。 -- 巴士因子:团队里因巴士撞倒的多少人,会导致项目失败。简答的来说,你需要进行团队工作而不是独自工作,人们很容易忘记,独自工作是一项艰苦的工作,比人们自认为的慢的多。编程很难,软件工程很难,你需要另外一双眼睛。 +- **巴士因子**:团队里因巴士撞倒的多少人,会导致项目失败。简答的来说,你需要进行团队工作而不是独自工作,人们很容易忘记,独自工作是一项艰苦的工作,比人们自认为的慢的多。编程很难,软件工程很难,你需要另外一双眼睛。 总结:几乎任何规模的软件工作的基础都是一个运作良好的团队。尽管软件开发者单打独斗的 "天才神话 "仍然存在,但事实是,没有人能够真正地单干。一个软件组织要想经受住时间的考验,就必须有一种健康的文化,植根于谦逊、信任和尊重,围绕着团队而不是个人。此外,软件开发的创造性要求人们承担风险并偶尔失败;为了让人们接受这种失败,必须有一个健康的团队环境。 @@ -47,9 +47,11 @@ 在某些方面,知识是软件工程组织字重要的无形资产,而知识的共享对于使组织在面对变化时具有弹性和冗余至关重要。一种促进开放和诚实的知识共享的文化可以在整个组织内有效的分配这些知识,并使该组织能够随着时间的推移而扩散。在大多数情况下,对更容易的知识共享的投入会在一个公司的生命周期中获取很多倍的回报。 + ## 测量工程效率 -> r如果你有一个蓬勃发展的业务想要扩增。据推测,为了增加你的业务范围,你也需要增加你的工程组织的规模。然而,随着组织规模的线性增长,沟通成本也呈二次曲线增长。增加人员对扩大业务范围是必要的,但沟通成本不会随着你增加人员而线性扩展。因此,你将无法根据你的工程组织的规模线性地扩大你的业务范围。 +> 如果你有一个蓬勃发展的业务想要扩增。据推测,为了增加你的业务范围,你也需要增加你的工程组织的规模。然而,随着组织规模的线性增长,沟通成本也呈二次曲线增长。增加人员对扩大业务范围是必要的,但沟通成本不会随着你增加人员而线性扩展。因此,你将无法根据你的工程组织的规模线性地扩大你的业务范围。 + # 总结 diff --git a/Computer/TechnologyTrends.md b/Computer/TechnologyTrends.md index ba3fc90..7553f0c 100644 --- a/Computer/TechnologyTrends.md +++ b/Computer/TechnologyTrends.md @@ -1,4 +1,4 @@ -# Technology Trends + ## Front-end diff --git "a/Electron/electron-builder\346\211\223\345\214\205\350\257\246\350\247\243.md" "b/Electron/electron-builder\346\211\223\345\214\205\350\257\246\350\247\243.md" index 4313e3e..87ca334 100644 --- "a/Electron/electron-builder\346\211\223\345\214\205\350\257\246\350\247\243.md" +++ "b/Electron/electron-builder\346\211\223\345\214\205\350\257\246\350\247\243.md" @@ -3,6 +3,7 @@ 开发electron客户端程序,打包是绕不开的问题。下面就我在工作中的经验以及目前对```electron-builder```的了解来分享一些心得。 ## 基本概念 + [官网](https://www.electron.build/)的定义 > A complete solution to package and build a ready for distribution Electron app for macOS, Windows and Linux with “auto update” support out of the box. @@ -12,13 +13,16 @@ builder的使用和配置都是很简单的 builder配置有两种方式 + - ```package.json```中直接配置使用(比较常用,我们下面着重来讲这个) - 指定```electron-builder.yml```文件 demo地址会在文章末尾给出(demo项目中`electron`使用得是`V2.0.7`版本,目前更高得是`2.0.8`版本)。 下面是一个简单的```package.js```中带注释的配置 + 1. 基础配置 + ``` js "build": { // 这里是electron-builder的配置 "productName":"xxxx",//项目名 这也是生成的exe文件的前缀名 @@ -33,11 +37,14 @@ demo地址会在文章末尾给出(demo项目中`electron`使用得是`V2.0.7` } } ``` + 在配置文件中加入以上的文件之后就可以打包出来简单的文件夹,文件夹肯定不是我们想要的东西。下一步我们来继续讲别的配置。 2. 打包目标配置 要打包成**安装程序**的话我们有两种方式, + 1. 使用NSIS工具对我们的文件夹再进行一次打包,打包成exe 2. 通过electron-builder的nsis直接打包成exe,配置如下 + ```js "win": { // 更改build下选项 "icon": "build/icons/aims.ico", @@ -48,7 +55,9 @@ demo地址会在文章末尾给出(demo项目中`electron`使用得是`V2.0.7` ] }, ``` + 3. 其他平台配置 + ```js "dmg": { // macOSdmg "contents": [ @@ -68,6 +77,7 @@ demo地址会在文章末尾给出(demo项目中`electron`使用得是`V2.0.7` 这个要详细的讲一下,这个nsis的配置指的是安装过程的配置,其实还是很重要的,如果不配置nsis那么应用程序就会自动的安装在C盘。没有用户选择的余地,这样肯定是不行的 关于nsis的配置是在build中nsis这个选项中进行配置,下面是部分nsis配置 + ```js "nsis": { "oneClick": false, // 是否一键安装 @@ -82,6 +92,7 @@ demo地址会在文章末尾给出(demo项目中`electron`使用得是`V2.0.7` "include": "build/script/installer.nsh", // 包含的自定义nsis脚本 这个对于构建需求严格得安装过程相当有用。 }, ``` + 关于`include` 和 `script` 到底选择哪一个 ? 在对个性化安装过程需求并不复杂,只是需要修改一下安装位置,卸载提示等等的简单操作建议使用`include`配置,如果你需要炫酷的安装过程,建议使用`script`进行完全自定义。 @@ -89,6 +100,7 @@ demo地址会在文章末尾给出(demo项目中`electron`使用得是`V2.0.7` `NSIS`对于处理安装包这种东西,功能非常的强大。但是学习起来并不比一门高级语言要容易。其中的奥秘还要各位大佬自行探索 这里上一些学习资源 + - [NSIS初级篇](https://blog.csdn.net/ddjj_1980/article/details/7843944) - [NSIS 打包脚本基础](http://www.cnblogs.com/jingmoxukong/p/5033622.html) - [示例脚本](http://www.cppblog.com/momoxiao/archive/2010/02/06/107326.html) @@ -99,11 +111,14 @@ demo地址会在文章末尾给出(demo项目中`electron`使用得是`V2.0.7` 主要是windows中64和32位的配置 CLI参数 + ```bash electron-builder --ia32 // 32位 electron-builder // 64位(默认) ``` + nsis中配置 + ```js "win": { "icon": "build/icons/aims.ico", @@ -118,9 +133,11 @@ nsis中配置 ] } ``` + 6. 更新配置 下面这个是给更新用的配置,主要是为了生成```lastest.yaml```配置文件 + ```js "publish": [ { @@ -129,8 +146,11 @@ nsis中配置 } ], ``` + ## 完整配置 + 基本上可用的完整的配置 + ```js "build": { "productName":"xxxx",//项目名 这也是生成的exe文件的前缀名 @@ -196,7 +216,9 @@ nsis中配置 ``` ## 命令行参数(CLI) + Commands(命令): + ```bash electron-builder build 构建命名 [default] electron-builder install-app-deps 下载app依赖 @@ -204,7 +226,9 @@ Commands(命令): electron-builder create-self-signed-cert 为Windows应用程序创建自签名代码签名证书 electron-builder start 使用electronic-webpack在开发模式下运行应用程序(须臾要electron-webpack模块支持) ``` + Building(构建参数): + ```bash --mac, -m, -o, --macos Build for macOS, [array] --linux, -l Build for Linux [array] @@ -219,12 +243,15 @@ Building(构建参数): --config, -c 配置文件路径。 默认为`electron-builder.yml`(或`js`,或`js5`) ``` + Publishing(发布): + ```bash --publish, -p 发布到GitHub Releases [choices: "onTag", "onTagOrDraft", "always", "never", undefined] ``` **Deprecated(废弃):** + ```bash --draft 请改为在GitHub发布选项中设置releaseType [boolean] --prerelease 请改为在GitHub发布选项中设置releaseType [boolean] @@ -233,12 +260,16 @@ Publishing(发布): --arch 目标arch (请更改为选项 --x64 or --ia32) [choices: "ia32", "x64", "armv7l", "arm64", "all", undefined] ``` + Other(其他): + ```bash --help Show help [boolean] --version Show version number [boolean] ``` + Examples(例子): + ```bash electron-builder -mwl 为macOS,Windows和Linux构建(同时构建) electron-builder --linux deb tar.xz 为Linux构建deb和tar.xz @@ -246,20 +277,25 @@ Examples(例子): electron-builder --config.nsis.unicode=false 为NSIS配置unicode选项 ``` + TargetConfiguration(构建目标配置): + ```js target: String - 目标名称,例如snap. arch “x64” | “ia32” | “armv7l” | “arm64”> | “x64” | “ia32” | “armv7l” | “arm64” -arch支持列表 ``` ## 常见的错误 + - `NPM`下载的问题 因为`NPM`在国内比较慢。导致`electron-V.xxxx.zip`下载失败。这些东西如果是第一次打包的话是需要下载对应`electron`版本的支持文件。解决办法有两个 1. 设置镜像:在C盘User中找到`.npmrc`文件。然后加入下面这句代码,但是这个有时候也不是很好用 + ``` ELECTRON_MIRROR=http://npm.taobao.org/mirrors/electron/ ``` + 2. 直接去淘宝镜像文件库找到对应的文件并下载,放到指定的目录下,electron的淘宝[镜像地址](https://npm.taobao.org/mirrors/electron/)。下载完之后放到指定的文件。一般文件得地址在`C:\Users\Administrator\AppData\Local\electron\Cache`。例如我要下载1.8.4版本的`electron`,那么找到镜像下得文件然后放到指定文件夹中。 ![electron](./error1.png 'electron') ![electron](./error2.png 'electron') @@ -276,8 +312,9 @@ arch “x64” | “ia32” | “armv7l” | “arm64”> | “x64” | “ia32 一般情况下解决这些问题的思路就是,缺什么拿什么😄。 # 总结 + `electron-builder`是一个简单又强大的库。解决了打包这个棘手的问题,而且可以应对大部分的打包需求。 [Demo地址](https://github.com/QDMarkMan/electron-builder-start) -[原文地址](https://github.com/QDMarkMan/CodeBlog/tree/master/Electron/electron-builder打包详解.md) 如果觉得有用得话给个⭐吧 \ No newline at end of file +[原文地址](https://github.com/QDMarkMan/CodeBlog/tree/master/Electron/electron-builder打包详解.md) 如果觉得有用得话给个⭐吧 diff --git "a/Go/Go\345\237\272\347\241\200.md" "b/Go/Go\345\237\272\347\241\200.md" index 00ec19e..3e018e8 100644 --- "a/Go/Go\345\237\272\347\241\200.md" +++ "b/Go/Go\345\237\272\347\241\200.md" @@ -55,8 +55,6 @@ - `uintptr`:无符号整型,用于存放指针。 - - 示例: ```go @@ -67,19 +65,19 @@ 值:utf-8类型字符串。 - 示例: + 示例: ```go var strType string strType = "string" strType = ` - 多行字符串 + 多行字符串 ` ``` - `nil`: (空值/零值)未初始化引用 - 以下类型默认初始值: + 以下类型默认初始值: ```go pointers -> nil @@ -90,8 +88,6 @@ interfaces -> nil ``` - - - `pointer`:指针类型 值:使用&,* 完成操作。 @@ -215,8 +211,6 @@ ``` - - ## 杂项 ### Go mod diff --git a/React/Hook.md b/React/Hook.md index 9d1351c..8ef4f53 100644 --- a/React/Hook.md +++ b/React/Hook.md @@ -4,7 +4,7 @@ ## Hook是什么? -> Hook是一个特殊的函数,它可以让你`钩入`React的特性,例如`useState`是允许你在React函数组件中添加state的hook。 +> Hook是一个特殊的函数,它可以让你`钩入`React的特性,例如`useState`是允许你在React函数组件中添加state的hook。 ## 解决了什么问题? @@ -22,9 +22,6 @@ ## 实际使用功能点 -## 相关扩展 +## 相关扩展 ## 总结 - - - diff --git a/Template/RFC Template.md b/Template/RFC Template.md new file mode 100644 index 0000000..c5ea7cd --- /dev/null +++ b/Template/RFC Template.md @@ -0,0 +1,103 @@ +> RFC 全称 (Request for Comments),征求意见稿 [维基百科](https://en.wikipedia.org/wiki/Memorandum)。 + +### 整体结构 [](https://www.rectcircle.cn/series/software-project-management/rust-rfc/#%E6%95%B4%E4%BD%93%E7%BB%93%E6%9E%84) + +- 头部元信息 +- 摘要 +- 动机 +- 指南级别的解释 +- 参考级别解释 +- 缺点 +- 理由和替代方案 +- 现有技术 +- 未解决的问题 +- 未来的可能性 + +### 文件名 [](https://www.rectcircle.cn/series/software-project-management/rust-rfc/#%E6%96%87%E4%BB%B6%E5%90%8D) + +`0000-feature-name.md` + +### 头部元信息 [](https://www.rectcircle.cn/series/software-project-management/rust-rfc/#%E5%A4%B4%E9%83%A8%E5%85%83%E4%BF%A1%E6%81%AF) + +```md +Feature Name: (fill me in with a unique ident, my_awesome_feature) +Start Date: (fill me in with today's date, YYYY-MM-DD) +RFC PR: rust-lang/rfcs#0000 +Rust Issue: rust-lang/rust#0000 +``` + +- Feature Name: 特性唯一标识(和文件名没有关系) +- Start Date: 启动时间 +- RFC PR: 当前 PR 的链接,PR 的 id 将作为 RFC 的编号 + +### 摘要 [](https://www.rectcircle.cn/series/software-project-management/rust-rfc/#%E6%91%98%E8%A6%81) + +我们为什么要这样做?它支持哪些用例?预期的结果是什么? + +### 指南级别的解释 [](https://www.rectcircle.cn/series/software-project-management/rust-rfc/#%E6%8C%87%E5%8D%97%E7%BA%A7%E5%88%AB%E7%9A%84%E8%A7%A3%E9%87%8A) + +解释该提案,好像它已被包含在语言中,并且您正在向另一个 Rust 程序员传授它。这通常意味着: + +- 引入新的命名概念 +- 主要用例子来解释这个特性 +- 解释 Rust 程序员应该如何思考这个特性,以及它应该如何影响他们使用 Rust 的方式。它应该尽可能具体地解释影响。 +- 如果适用,提供错误信息、废弃警告或迁移指导的示例。 +- 如果适用,描述向现有的 Rust 程序员和新的 Rust 程序员教授这个功能的区别。 + +对于以实现为导向的RFC(例如,编译器内部),本节应专注于编译贡献者如何考虑变革,并举例说明其具体影响。对于政策RFC,本节应提供对政策的示例驱动的介绍,并在具体方面解释其影响。 + +### 参考级别解释 + +这是RFC的技术部分。以足够的细节解释设计: + +- 该功能与其他功能的相互作用是明确的。 +- 合理地明确了如何实现该功能。 +- 通过示例解剖视角案例。 + +本节应回到上一节所举的例子,并更充分地解释详细提案如何使这些例子发挥作用。 + +### 缺点 [](https://www.rectcircle.cn/series/software-project-management/rust-rfc/#%E7%BC%BA%E7%82%B9) + +存在缺点 + +### 理由和替代方案 [](https://www.rectcircle.cn/series/software-project-management/rust-rfc/#%E7%90%86%E7%94%B1%E5%92%8C%E6%9B%BF%E4%BB%A3%E6%96%B9%E6%A1%88) + +- 为什么在可能的设计中,这种设计是最好的? +- 还考虑过哪些其他设计,不选择这些设计的理由是什么? +- 不这样做的影响是什么? + +### 现有技术 [](https://www.rectcircle.cn/series/software-project-management/rust-rfc/#%E7%8E%B0%E6%9C%89%E6%8A%80%E6%9C%AF) + +讨论与本提案有关的现有技术,包括好的和坏的。其中可包括以下几个例子: + +- 对于语言、库、crate、工具和编译器的建议。这个功能在其他编程语言中是否存在? 他们的社区有什么经验? +- 对于社区的建议。是否有其他社区做了这个功能,他们有什么经验? +- 对于其他团队来说。我们可以从其他社区在这里做的事情中学到什么经验? +- 论文。有没有发表过的论文或者是讨论这个问题的好帖子?如果你有一些相关的论文可以参考,这可以作为一个更详细的理论背景。 + +本节旨在鼓励您作为作者思考其他语言的 + +经验教训,为您的RFC读者提供更全面的信息。如果没有先例,那也没关系–无论你的想法是全新的,还是从其他语言改编而来,我们都会感兴趣。 + +请注意,虽然其他语言创造的先例是一些动力,但它本身并不能成为RFC的动力。也请考虑到rust有时会故意偏离通用语言的特性。 + +### 未解决的问题 [](https://www.rectcircle.cn/series/software-project-management/rust-rfc/#%E6%9C%AA%E8%A7%A3%E5%86%B3%E7%9A%84%E9%97%AE%E9%A2%98) + +- 在这个功能被合并之前,你期望通过RFC程序解决设计中的哪些部分? +- 在稳定化之前,你期望通过这个功能的实现来解决设计中的哪些部分? +- 您认为哪些相关问题不在本 RFC 的范围内,可以在未来独立于本 RFC 的解决方案解决? + +### 未来的可能性 [](https://www.rectcircle.cn/series/software-project-management/rust-rfc/#%E6%9C%AA%E6%9D%A5%E7%9A%84%E5%8F%AF%E8%83%BD%E6%80%A7) + +想一想你的提案的自然延伸和演变会是什么,以及它将如何整体地影响语言和项目。试着把这部分作为一个工具,在你的提案中更全面地考虑所有可能与项目和语言的互动。同时考虑这一切如何与项目和相关子团队的路线图相适应。 + +这也是一个 “倾倒想法 “的好地方,如果这些想法不在你正在编写的RFC范围内,但在其他方面是相关的。 + +如果你已经尝试过,但想不出任何未来的可能性,你可以简单地声明你想不出任何东西。 + +请注意,在未来可能性部分写下一些东西并不是接受当前或未来 RFC 的理由;这样的说明应该在本 RFC 或后续 RFC 的动机或理由部分。这一节只是提供补充信息。 + +## rfc 的例子 + +[1210-impl-specialization.md](https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md) +[0002-rfc-process.md](https://github.com/rust-lang/rfcs/blob/master/text/0002-rfc-process.md) diff --git "a/Template/\346\226\271\346\241\210\350\256\276\350\256\241\346\250\241\347\211\210.md" "b/Template/\346\226\271\346\241\210\350\256\276\350\256\241\346\250\241\347\211\210.md" new file mode 100644 index 0000000..32d04c7 --- /dev/null +++ "b/Template/\346\226\271\346\241\210\350\256\276\350\256\241\346\250\241\347\211\210.md" @@ -0,0 +1,49 @@ +# XXX方案 + +>简要描述 + +# 1. 需求概述 + +> 清晰讲述需求相关问题 + +# 2. 功能范围 + +## 2.1 本方案实现的功能 + +> _这里定义包含边界。哪些是本模块核心必不可少的功能,定义在这里。哪些是未来可能加,现在还没来得及实现的,也定义在这里_ + +## 2.3 本方案涉及的模块 + +# 3. 具体设计 + +# 4. 接口设计 + +> _这里定义接口边界。本模块提供给接口和方式_ + +# 5. 数据结构 + +> _这里定义模块数据结构。_ + +# 6. 类、框架及其层次关系 + +> _这里定义模块内部类的结构和依赖关系_ + +## 6.1 类图 + +> + +## 6.2 框架图 + +> + +## 6.3 流程图 + +> + +# 7. 场景推演 + +> 辅助伪代码或者图片说明 + +```JavaScript +// add your code sample here +``` diff --git "a/TypeScript/\347\256\241\347\220\206@types\346\226\207\344\273\266.md" "b/TypeScript/\347\256\241\347\220\206@types\346\226\207\344\273\266.md" new file mode 100644 index 0000000..9ca03b3 --- /dev/null +++ "b/TypeScript/\347\256\241\347\220\206@types\346\226\207\344\273\266.md" @@ -0,0 +1,26 @@ +> 在TypeScript技术栈中,管理类型声明文件是一个不太容易抉择的问题,这里开一篇文章详细的记录管理的方式和经验。 + +在生产项目中,如果管理项目中定义的各种类型声明本就是一个比较棘手的问题。 + +## 声明文件作用和配置 + +## 书写声明文件 + +## 官方推荐的管理方式 + +## 项目实战配置 + + +### 其他库是怎么管理的 + +### 推荐的管理方式 + + + +# 参考 + +- [typescript声明文件](https://www.tslang.cn/docs/handbook/declaration-files/introduction.html) +- [DefinitelyTyped 项目](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/README.cn.md) +- [TypeScript入门教程——声明文件](https://ts.xcatliu.com/basics/declaration-files.html) +- [深入理解 TypeScript](https://jkchao.github.io/typescript-book-chinese/) +- [ 管理TypeScript项目中的类型声明](https://shymean.com/article/%E7%AE%A1%E7%90%86TypeScript%E9%A1%B9%E7%9B%AE%E4%B8%AD%E7%9A%84%E7%B1%BB%E5%9E%8B%E5%A3%B0%E6%98%8E) diff --git "a/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" "b/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\347\254\224\350\256\260.md" similarity index 77% rename from "TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" rename to "TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\347\254\224\350\256\260.md" index 05917ee..772daa2 100644 --- "a/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\346\211\200\345\276\227.md" +++ "b/TypeScript/\351\230\205\350\257\273vscode\346\272\220\347\240\201\347\254\224\350\256\260.md" @@ -1,16 +1,19 @@ -# 阅读vscode源码所得 + +# 阅读vscode源码笔记 工作原因最近要阅读`vscode`的源码。这里做个记录 ## 写在前面 -**现在不建议阅读,笔者还没有读利索源码** +> 在看源码时的一些笔记。 +*** ## 文件结构 -## 骚操作 +## 一些小技巧 - 数组复制方式 + ```js const configurations = configRegistry.getConfigurations().slice(); // 返回一个新的数组 ``` @@ -18,4 +21,3 @@ - `document.documentElement!` 后面的感叹号**是非null和非undefined的类型断言** - diff --git "a/Webpack/\344\270\215\345\276\227\344\270\215\344\272\206\350\247\243\347\232\204Babel.md" "b/Webpack/\344\270\215\345\276\227\344\270\215\344\272\206\350\247\243\347\232\204Babel.md" index 60eb94d..d8d068c 100644 --- "a/Webpack/\344\270\215\345\276\227\344\270\215\344\272\206\350\247\243\347\232\204Babel.md" +++ "b/Webpack/\344\270\215\345\276\227\344\270\215\344\272\206\350\247\243\347\232\204Babel.md" @@ -1,6 +1,11 @@ # 不得不了解的babel `Babel` +## 概览 + +- `@babel/runtime`: 一个包含`Babel`模块化运行时助手的库, 主要作用是**将转译的辅助代码从在文件中硬编码方式变为运行时的模块注入方式从而达到在某些条件下(重复代码过多时)缩小编译后的代码体积**。 +- `@babel/transform-runtime`: **类库的打包如果需要注入 polyfill 的话,最好使用 @babel/transform-runtime,因为它提供了一种不污染全局作用域的方式**。 + ## Preset > 预设,相当于编译到哪一个版本。也可以说是某一类 plugin 的集合,包含了某一类插件的所有功能。每年每个 preset 只编译当年批准的内容。 而 babel-preset-env 相当于 es2015 ,es2016 ,es2017 及最新版本。 @@ -170,4 +175,5 @@ module.exports = { # 总结 + `Babel`很强大,但是我希望有一天能够不再需要了😁 \ No newline at end of file From a8004f2e7f49893b6731d246328e23438a88a9d9 Mon Sep 17 00:00:00 2001 From: "tongfu.e" Date: Fri, 17 May 2024 17:42:11 +0800 Subject: [PATCH 16/19] feat: Add 10 Things Software Developers Should Learn about Learning --- .DS_Store | Bin 8196 -> 8196 bytes Electron/Develop Electron App like VSCode.md | 6 +- README.md | 11 +- Server/NginxBasic.md | 1300 ++++++++++++++++++ 4 files changed, 1312 insertions(+), 5 deletions(-) create mode 100644 Server/NginxBasic.md diff --git a/.DS_Store b/.DS_Store index 0981b5bd8f9220024b8695722a4d51f3c9755fba..23726125949e66624fcc1c5862f67f6843ceab56 100644 GIT binary patch delta 178 zcmZp1XmOa}FDlExz`)4BAi&_6lb@WFlb;0S3v4W$#y+uucQZQ&3kNSq1q*{7Lpnny zL&@Zwg7V2+Fdk4Oogt4QpP`5$62Hwr=94s7+(wk=qEMep< mU`S+02P!C@EFmDj*+%Fz>%@kX&Fm82ST-k$E@PV5kO%-!`xgNK diff --git a/Electron/Develop Electron App like VSCode.md b/Electron/Develop Electron App like VSCode.md index 6c2f625..d799827 100644 --- a/Electron/Develop Electron App like VSCode.md +++ b/Electron/Develop Electron App like VSCode.md @@ -4,4 +4,8 @@ ## 写在前面 -这个小玩意儿其实是基于VSCode工程中提炼出来的一个精简框架,如果想运行起来VSCode, 可以[看这里](https://github.com/microsoft/vscode/wiki/How-to-Contribute) \ No newline at end of file +这个小玩意儿其实是基于VSCode工程中提炼出来的一个精简框架,如果想运行起来VSCode, 可以[看这里](https://github.com/microsoft/vscode/wiki/How-to-Contribute) + +# 引用 + +- [资料汇总](https://www.zhihu.com/question/462691782/answer/3039362926) diff --git a/README.md b/README.md index 0ec2b0c..e6b4fcc 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,13 @@ # Blog + 开发过程中的疑率以及学习中碰到的精华整理成的博客。(如果发现问题请提交```issue```😁)。 ## 写在前面 + 文中大部分的代码都在[usually-accumulated](https://github.com/QDMarkMan/usually-accumulated)这个rep中。也是我积累代码的地方。 ## 博客正文(原创) + - [Javascript基础以及进阶部分♥](https://github.com/QDMarkMan/CodeBlog/blob/master/TypeScript/READEME.md) @@ -17,7 +20,7 @@ - [装箱和拆箱](https://github.com/QDMarkMan/CodeBlog/blob/master/Javascript/装箱和拆箱.md) - [Javascript中函数作为对象的魅力](https://github.com/QDMarkMan/CodeBlog/blob/master/Javascript/Javascript中函数作为对象的魅力.md) - [关于原型的一些东西](https://github.com/QDMarkMan/CodeBlog/blob/master/Javascript/关于原型的一些东西.md) - - [一些尺寸相关的API](https://github.com/QDMarkMan/CodeBlog/blob/master/CSS/一些尺寸相关的API.md) + - [一些尺寸相关的API](https://github.com/QDMarkMan/CodeBlog/blob/master/CSS/一些尺寸相关的API.md) - `NodeJS💪` - [让NodeJS在项目中发光发热](https://github.com/QDMarkMan/CodeBlog/blob/master/Node/%E8%AE%A9NodeJS%E5%9C%A8%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%8F%91%E5%85%89%E5%8F%91%E7%83%AD.md) @@ -34,7 +37,7 @@ - [Electron-builder打包详解](https://github.com/QDMarkMan/CodeBlog/blob/master/Electron/electron-builder%E6%89%93%E5%8C%85%E8%AF%A6%E8%A7%A3.md) - [Electron单例检测](https://github.com/QDMarkMan/CodeBlog/blob/master/Electron/SingleInstance.md) -- [Webpack部分相关🎫](https://github.com/QDMarkMan/CodeBlog/blob/master/Webpack/webpack基础合集.md) +- [Webpack部分相关🎫](https://github.com/QDMarkMan/CodeBlog/blob/master/Webpack/webpack基础合集.md) - [不得不了解的Babel](https://github.com/QDMarkMan/CodeBlog/blob/master/Webpack/%E4%B8%8D%E5%BE%97%E4%B8%8D%E4%BA%86%E8%A7%A3%E7%9A%84Babel.md) - [webapck合集(新)](https://github.com/QDMarkMan/CodeBlog/blob/master/Webpack/webpack合集.md) - [tree-shaking](https://github.com/QDMarkMan/CodeBlog/blob/master/Webpack/webpack中tree-shaking的威力.md) @@ -63,8 +66,6 @@ - [Readme模板](https://github.com/QDMarkMan/CodeBlog/blob/master/ReadmeTemplate.md) - - ## 相关好文(分享🎉) 在划水的时候发现的一些高质量好文章,这些文章包含各个领域,在我看来每一篇都值得反复阅读,我自己也会反复的去看。这个就不分类了。如有侵权请马上联系我删除😀 @@ -93,3 +94,5 @@ - [架构制图:工具与方法论](https://zhuanlan.zhihu.com/p/384958911) - [架构制图:工具与方法论](https://zhuanlan.zhihu.com/p/384958911) - [Software-Engineering-at-Google](https://qiangmzsx.github.io/Software-Engineering-at-Google/#/?id=software-engineering-at-google) +- [Docker Containers vs. Kubernetes Pods - Taking a Deeper Look](https://labs.iximiuz.com/tutorials/containers-vs-pods) +- [10 Things Software Developers Should Learn about Learning](https://cacm.acm.org/research/10-things-software-developers-should-learn-about-learning/) diff --git a/Server/NginxBasic.md b/Server/NginxBasic.md new file mode 100644 index 0000000..7300a5a --- /dev/null +++ b/Server/NginxBasic.md @@ -0,0 +1,1300 @@ +# Nginx安装部署手册 + +下载地址: + +本手册版本: + +​ Linux:[nginx-1.14.2](https://nginx.org/download/nginx-1.14.2.tar.gz) + +​ Windows: [nginx/Windows-1.14.2](https://nginx.org/download/nginx-1.14.2.zip) + +参考引用:[Nginx安装及配置详解包括windows环境](https://www.cnblogs.com/loong-hon/p/9060515.html) + +## 安装Nginx + +### Windows + +#### 1、安装 + +下载对应的版本的nginx压缩包,解压到自己电脑上存放软件的文件夹中,例如:C:\Users\hi.li\Desktop\opensource\nginx\nginx-1.14.2 + +**注:要给执行nginx的命令窗口管理员执行权限,否则可能因为读写权限问题无法正常关闭** + +``` +引申:默认的Nginx安装文件并不包括一些nginx模块,例如lua,如果需要使用lua,建议直接使用OpenResty打包的Nginx,已直接集成了通用的lua模块并支持lua。 +OpenResty下载地址:http://openresty.org/cn/download.html +``` + +#### 2、启动nginx + +``` +>cd C:\Users\hi.li\Desktop\opensource\nginx\nginx-1.14.2 +>nginx +# or启动后台任务模式 +>start nginx +# or 指定配置文件启动 +>nginx -c test_nginx.conf +``` + +#### 3、访问nginx + +打开浏览器,输入地址: + +![01](media/nginx-install/01.png) + +#### 4、停止nginx + +命令行进入nginx根目录,执行如下命令,停止服务器: + +``` +>cd C:\Users\hi.li\Desktop\opensource\nginx\nginx-1.14.2 + +# 强制停止nginx服务器,如果有未处理的数据,丢弃 +> nginx -s stop + +# 优雅的停止nginx服务器,如果有未处理的数据,等待处理完成之后停止 +> nginx -s quit +``` + +#### 5、其他nginx命令 + +``` +nginx -s reload :修改配置后重新加载生效 +nginx -s reopen :重新打开日志文件 +nginx -t -c /path/to/nginx.conf : 测试nginx配置文件是否正确 +nginx -h : 打开命令帮助 +``` + +### CentOS(待检验) + +#### 1、安装准备 + +由于nginx的一些模块依赖一些lib库,所以在安装nginx之前,必须先安装这些lib库,这些依赖库主要有g++、gcc、openssl-devel、pcre-devel和zlib-devel 所以执行如下命令安装 + +``` +yum install gcc-c++ +yum install pcre pcre-devel +yum install zlib zlib-devel +yum install openssl openssl--devel +``` + +如果之前有安装国nginx,先删除 + +``` +$ find -name nginx + +# 如果系统已经安装了nginx,那么就先卸载 +$ yum remove nginx +``` + +#### 2、安装 + +下载对应的版本的nginx压缩包,放置到/usr/local目录中,并解压缩: + +``` +$ cd /usr/local + +# 从官网下载最新版的nginx +$ wget https://nginx.org/download/nginx-1.14.2.tar.gz + +# 解压nginx压缩包 +$ tar -zxvf nginx-1.14.2.tar.gz + +# 接下来安装,使用--prefix参数指定nginx安装的目录,make、make install安装 +$ cd nginx-1.14.2 +# 默认安装在/usr/local/nginx +$ ./configure +$ make +$ make install + +# 如果没有报错,顺利完成后,最好看一下nginx的安装目录 +$ whereis nginx +``` + +安装完成后,在/usr/sbin/目录下是nginx命令所在目录,在/etc/nginx/目录下是nginx所有的配置文件,用于配置nginx服务器以及负载均衡等信息 + +#### 3、查看nginx进程是否启动 + +``` +ps -ef|grep nginx +``` + +nginx会自动根据当前主机的CPU的内核数目创建对应的进程数量,启动的服务进程为CPU内核数+1,因为nginx进程在启动的时候,会附带一个守护进程,用于保护正式进程不被异常终止;如果守护进程一旦返现nginx继承被终止了,会自动重启该进程。 + +守护进程一般会称为master进程,业务进程被称为worker进程 + +#### 4、启动、关闭nginx的命令和windows一致 + +## Nginx配置 + +nginx是一个功能非常强大的web服务器加反向代理服务器,同时又是邮件服务器等等。 + +在项目使用中,使用最多的三个核心功能是反向代理、负载均衡和静态服务器。这三个不同的功能的使用,都跟nginx的配置密切相关,nginx服务器的配置信息主要集中在nginx.conf这个配置文件中,并且所有的可配置选项大致分为以下几个部分: + +``` + +``` + +如上述配置文件所示,主要由6个部分组成: + +1. main:用于进行nginx全局信息的配置 +2. events:用于nginx工作模式的配置 +3. http:用于进行http协议信息的一些配置 +4. server:用于进行服务器访问信息的配置 +5. location:用于进行访问路由的配置 +6. upstream:用于进行负载均衡的配置 + +### main模块 + +``` +# user nobody nobody; +worker_processes 2; +# error_log logs/error.log +# error_log logs/error.log notice +# error_log logs/error.log info +# pid logs/nginx.pid +worker_rlimit_nofile 1024; +``` + +上述配置都是存放在main全局配置模块中的配置项 + +- user用来指定nginx worker进程运行用户以及用户组,默认nobody账号运行 + +- worker_processes指定nginx要开启的子进程数量,运行过程中监控每个进程消耗内存(一般几M~几十M不等)根据实际情况进行调整,通常数量是CPU内核数量的整数倍 + +- error_log定义错误日志文件的位置及输出级别【debug / info / notice / warn / error / crit】 + +- pid用来指定进程id的存储文件的位置 + +- worker_rlimit_nofile用于指定一个进程可以打开最多文件数量的描述 + +### event 模块 + +``` +event { + worker_connections 1024; + multi_accept on; + use epoll; +} +``` + +上述配置是针对nginx服务器的工作模式的一些操作配置 + +- worker_connections 指定最大可以同时接收的连接数量,这里一定要注意,最大连接数量是和worker processes共同决定的。 +- multi_accept 配置指定nginx在收到一个新连接通知后尽可能多的接受更多的连接 +- use epoll 配置指定了线程轮询的方法,如果是linux2.6+,使用epoll,如果是BSD如Mac请使用Kqueue + +### http模块 + +作为web服务器,http模块是nginx最核心的一个模块,配置项也是比较多的,项目中会设置到很多的实际业务场景,需要根据硬件信息进行适当的配置,常规情况下,使用默认配置即可! + +``` +http { + ## + # 基础配置 + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + # server_tokens off; + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL证书配置 + ## + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE + ssl_prefer_server_ciphers on; + + ## + # 日志配置 + ## + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + ## + # Gzip 压缩配置 + ## + + gzip on; + gzip_disable "msie6"; + + # gzip_vary on; + # gzip_proxied any; + # gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + # gzip_types text/plain text/css application/json application/javascript + text/xml application/xml application/xml+rss text/javascript; + + ## + # 虚拟主机配置 + ## + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +``` + +1) 基础配置 + +- sendfile on:配置on让sendfile发挥作用,将文件的回写过程交给数据缓冲去去完成,而不是放在应用中完成,这样的话在性能提升有有好处 +- tc_nopush on:让nginx在一个数据包中发送所有的头文件,而不是一个一个单独发 +- tcp_nodelay on:让nginx不要缓存数据,而是一段一段发送,如果数据的传输有实时性的要求的话可以配置它,发送完一小段数据就立刻能得到返回值,但是不要滥用哦 +- keepalive_timeout 10:给客户端分配连接超时时间,服务器会在这个时间过后关闭连接。一般设置时间较短,可以让nginx工作持续性更好 +- client_header_timeout 10:设置请求头的超时时间 +- client_body_timeout 10:设置请求体的超时时间 +- send_timeout 10:指定客户端响应超时时间,如果客户端两次操作间隔超过这个时间,服务器就会关闭这个链接 +- limit_conn_zone $binary_remote_addr zone=addr:5m :设置用于保存各种key的共享内存的参数, +- limit_conn addr 100: 给定的key设置最大连接数 +- server_tokens:虽然不会让nginx执行速度更快,但是可以在错误页面关闭nginx版本提示,对于网站安全性的提升有好处哦 +- include /etc/nginx/mime.types:指定在当前文件中包含另一个文件的指令 +- default_type application/octet-stream:指定默认处理的文件类型可以是二进制 +- type_hash_max_size 2048:混淆数据,影响三列冲突率,值越大消耗内存越多,散列key冲突率会降低,检索速度更快;值越小key,占用内存较少,冲突率越高,检索速度变慢 + +2) 日志配置 + +- access_log logs/access.log:设置存储访问记录的日志 +- error_log logs/error.log:设置存储记录错误发生的日志 + +3) SSL证书加密 + +- ssl_protocols:指令用于启动特定的加密协议,nginx在1.1.13和1.0.12版本后默认是ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2,TLSv1.1与TLSv1.2要确保OpenSSL >= 1.0.1 ,SSLv3 现在还有很多地方在用但有不少被攻击的漏洞。 +- ssl prefer server ciphers:设置协商加密算法时,优先使用我们服务端的加密套件,而不是客户端浏览器的加密套件 + +4) 压缩配置 + +- gzip 是告诉nginx采用gzip压缩的形式发送数据。这将会减少我们发送的数据量。 +- gzip_disable 为指定的客户端禁用gzip功能。我们设置成IE6或者更低版本以使我们的方案能够广泛兼容。 +- gzip_static 告诉nginx在压缩资源之前,先查找是否有预先gzip处理过的资源。这要求你预先压缩你的文件(在这个例子中被注释掉了),从而允许你使用最高压缩比,这样nginx就不用再压缩这些文件了(想要更详尽的gzip_static的信息,请点击这里)。 +- gzip_proxied 允许或者禁止压缩基于请求和响应的响应流。我们设置为any,意味着将会压缩所有的请求。 +- gzip_min_length 设置对数据启用压缩的最少字节数。如果一个请求小于1000字节,我们最好不要压缩它,因为压缩这些小的数据会降低处理此请求的所有进程的速度。 +- gzip_comp_level 设置数据的压缩等级。这个等级可以是1-9之间的任意数值,9是最慢但是压缩比最大的。我们设置为4,这是一个比较折中的设置。 +- gzip_type 设置需要压缩的数据格式。上面例子中已经有一些了,你也可以再添加更多的格式。 + +5) 文件缓存配置 + +- open_file_cache 打开缓存的同时也指定了缓存最大数目,以及缓存的时间。我们可以设置一个相对高的最大时间,这样我们可以在它们不活动超过20秒后清除掉。 +- open_file_cache_valid 在open_file_cache中指定检测正确信息的间隔时间。 +- open_file_cache_min_uses 定义了open_file_cache中指令参数不活动时间期间里最小的文件数。 +- open_file_cache_errors 指定了当搜索一个文件时是否缓存错误信息,也包括再次给配置中添加文件。我们也包括了服务器模块,这些是在不同文件中定义的。如果你的服务器模块不在这些位置,你就得修改这一行来指定正确的位置。 + +### server模块 + +srever模块配置是http模块中的一个子模块,用来定义一个虚拟访问主机,也就是一个虚拟服务器的配置信息: + +``` +server { + listen 80; + server_name localhost 192.168.1.100; + root /nginx/www; + index index.php index.html index.html; + charset utf-8; + access_log logs/access.log; + error_log logs/error.log; + ...... +} +``` + +核心配置信息如下: + +- server:一个虚拟主机的配置,一个http中可以配置多个server +- server_name:用力啊指定ip地址或者域名,多个配置之间用空格分隔 +- root:表示整个server虚拟主机内的根目录,所有当前主机中web项目的根目录 +- index:用户访问web网站时的全局首页 +- charset:用于设置www/路径中配置的网页的默认编码格式 +- access_log:用于指定该虚拟主机服务器中的访问记录日志存放路径 +- error_log:用于指定该虚拟主机服务器中访问错误日志的存放路径 + +### location模块 + +location模块是nginx配置中出现最多的一个配置,主要用于配置路由访问信息 。 + +在路由访问信息配置中关联到反向代理、负载均衡等等各项功能,所以location模块也是一个非常重要的配置模块 + +基本配置: + +``` +location / { + root /nginx/www; + index index.php index.html index.htm; +} +``` + +- location /:表示匹配访问根目录 +- root:用于指定访问根目录时,访问虚拟主机的web目录 +- index:在不指定访问具体资源时,默认展示的资源文件列表 + +反向代理配置方式 + +通过反向代理代理服务器访问模式,通过proxy_set配置让客户端访问透明化 + +``` +location / { + proxy_pass http://localhost:8888; + proxy_set_header X-real-ip $remote_addr; + proxy_set_header Host $http_host; +} +``` + +uwsgi配置 + +wsgi模式下的服务器配置访问方式 + +``` +location / { + include uwsgi_params; + uwsgi_pass localhost:8888 +} +``` + +### upstream模块 + +upstream模块主要负责负载均衡的配置,通过默认的轮询调度方式来分发请求到后端服务器。 + +简单的配置方式如下: + +``` +upstream name { + ip_hash; + server 192.168.1.100:8000; + server 192.168.1.100:8001 down; + server 192.168.1.100:8002 max_fails=3; + server 192.168.1.100:8003 fail_timeout=20s; + server 192.168.1.100:8004 max_fails=3 fail_timeout=20s; +} +``` + +核心配置信息如下 + +- ip_hash:指定请求调度算法,默认是weight权重轮询调度,可以指定 +- server host:port:分发服务器的列表配置 +- -- down:表示该主机暂停服务 +- -- max_fails:表示失败最大次数,超过失败最大次数暂停服务 +- -- fail_timeout:表示如果请求受理失败,暂停指定的时间之后重新发起请求 + +## nginx location正则写法 + +### 语法(Syntax) + +``` +location [ = | ~ | ~* | ^~ ] uri { ... } +location @name { ... } +``` + +- 普通逻辑(uri前不带指令符)的匹配规则是最大匹配,如果是严格匹配(正好完全精确匹配),则匹配上不会再匹配其他规则;如果不是严格匹配,则会继续匹配其他规则;例如 + + ``` + location /login/a.html { + # 匹配/login/a.html开头的uri + proxy_pass http://www.baidu.com; + } + + location /login/ { + # 匹配/login/开头的uri + 规则B + } + + # uri localhost/login/a.html 匹配到第1个规则后停止匹配其他正则规则 + ``` + +- 以" = "(注意前后要有空格)开头表示精确匹配,匹配上会中止其他匹配;例如 + + ``` + location = /login { + # 精确匹配后面的字符, 例如“localhost/login”可以匹配上 + } + ``` + +- `^~` 开头表示uri以某个常规字符串开头,不是正则匹配,匹配上会中止其他匹配;例如 + + ``` + location ^~ /pic/ { + # 匹配/pic/开头的uri,如果匹配上但找不到资源,默认取/pic/ios.jpg + root ../static_server; + try_files $uri /pic/ios.jpg; + } + ``` + +- ~ 开头表示区分大小写的正则匹配;正则匹配只要匹配上就会中止其他匹配; + +- ~* 开头表示不区分大小写的正则匹配;正则匹配只要匹配上就会中止其他匹配; + +- / 通用匹配, 如果没有其它匹配,任何请求都会匹配到,例如 + + ``` + location / { + # 首页,指定主页,如果没有其他匹配,根据uri在../static_server下找资源 + root ../static_server; + index login.html; + } + ``` + +- " = / "和“ / ”的区别 + + ``` + " = / ": 精确匹配 "/" ,后面带任何字符都不能匹配上,也就是严格匹配http://host_name/这种情况 + " / ": 通用匹配,可以匹配上所有uri + ``` + +### uri匹配规则 + +- 普通匹配的uri匹配规则是从前往后最大字符匹配(区分大小写) + +- 正则匹配需要指令符“ ~ ”和“ ~* ”标记,后面的uri使用标准正则表达式即可,例如 + + ``` + location ~* \.(mp3|mp4) { + # 匹配所有以mp3或mp4结尾的uri,不区分大小写 + } + ``` + +- 注意配置中的uri无需进行URLDecode处理,例如要匹配浏览器中的URL“/images/%20/test ”,你写location 的时候匹配目标应该是:“/images/ /test ” + +## Rewrite用法 + +Rewrite功能就是使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。 + +``` +限制: +rewrite只能放在 server{}, location{}, if{}中,并且只能对域名后边的除去传递的参数外的字符串起作用。 +例如 http://seanlook.com/a/we/index.php?id=1&u=str 只对/a/we/index.php重写。 + +如果想对域名或参数字符串起作用,可以使用全局变量匹配,也可以使用proxy_pass反向代理。 +``` + +rewrite和location功能有点像,都能实现跳转。主要区别在于rewrite是在**同一域名内**更改获取资源的路径,而location是对一类路径做控制访问或反向代理,**可以proxy_pass到其他机器**。 + +``` +很多情况下rewrite也会写在location里,它们的执行顺序是: +1 执行server块的rewrite指令 +2 执行location匹配 +3 执行选定的location中的rewrite指令 +``` + +### 语法 + +**Syntax : rewrite regex replacement [flag];** + +- regex :要进行替换的匹配正则表达式(匹配上才会执行rewrite操作),如果表达式中含{},则应使用单引号(')引用起来;同时可以基于该表达式获取原uri中的指定匹配项用于replacement 进行替换 + +- replacement : 要将uri替换后的字符串,可使用“$1”、“$2”等引用前面表达式的匹配项 + +- flag :处理标记位 + + - - last : 相当于Apache的[L]标记,表示完成rewrite + + - break : 停止执行当前虚拟主机的后续rewrite指令集 + + - redirect : 返回302临时重定向,地址栏会显示跳转后的地址 + + - permanent : 返回301永久重定向,地址栏会显示跳转后的地址 + + **注:因为301和302不能简单的只返回状态码,还必须有重定向的URL,这就是return指令无法返回301,302的原因了。** + + ``` + 这里 last 和 break 区别有点难以理解: + 1. last一般写在server和if中,而break一般使用在location中 + 2. last不终止重写后的url匹配,即重写后的url会继续走下面的location匹配处理过程;而break将直接终止重写后的location匹配; + 3. break和last都能阻止继续执行后面(同一个域内,例如同一个location下)的rewrite指令; + ``` + +### rewrite_log + +开启rewrite_log,这样在/var/log/nginx/error.log中显示匹配的规则,便于debug,理解rewrite的过程。 + +``` +rewrite_log on; +access_log /var/log/nginx/access.log; +error_log /var/log/nginx/error.log info; +``` + +### 实例 + +**server中** + +``` +# 如果UA包含"MSIE"(浏览器为IE),rewrite请求到/msie/目录下 +if ($http_user_agent ~ MSIE) { + rewrite ^(.*)$ /msie/$1 break; +} +``` + +**location中** + +``` +# 对形如/images/ef/uh7b3/test.png的请求,重写到/data?file=test.png,于是匹配到location +# /data,先看/data/images/test.png文件存不存在,如果存在则正常响应,如果不存在则重写tryfiles +# 到新的image404 location,直接返回404状态码。 + +location / { + # 注意这里要用‘’单引号引起来,避免{} + rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4; + # 注意不能在上面这条规则后面加上“last”参数,否则下面的set指令不会执行 + set $image_file $3; + set $image_type $4; + + # 对形如/images/bla_500x400.jpg的文件请求,重写到/resizer/bla.jpg?width=500&height=400地址,并会继续尝试匹配location + rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last; +} + +location /data { + # 指定针对图片的日志格式,来分析图片类型和大小 + access_log logs/images.log mian; + root /data/images; + # 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个url里 + try_files /$arg_file /image404.html; +} + +location = /image404.html { + # 图片不存在返回特定的信息 + return 404 "image not found\n"; +} +``` + +## if指令与全局变量 + +### 语法 + +**语法:if (condition) {...}** + +对给定的条件condition进行判断。如果为真,大括号内的指令将被执行(如rewrite或set),if条件(conditon)可以是如下任何内容: + +- 当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false +- 直接比较变量和内容时,使用=或!= +- ~ 正则表达式匹配 +- ~* 不区分大小写的匹配 +- !~ 区分大小写的不匹配 +- -f和!-f 用来判断是否存在文件 +- -d和!-d 用来判断是否存在目录 +- -e和!-e 用来判断是否存在文件或目录 +- -x和!-x 用来判断文件是否可执行 + +**示例** + +``` +# 如果用户设备为IE浏览器的时候,重定向 +if ($http_user_agent ~ MSIE) { + rewrite ^(.*)$ /msie/$1 break; +} + +# 如果cookie匹配正则,设置变量$id等于正则引用部分 +if ($http_cookie ~* "id=([^;]+)(?:;|$)") { + set $id $1; +} + +# 如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302 +if ($request_method = POST) { + return 405; +} + +# 限速,$slow可以通过 set 指令设置 +if ($slow) { + limit_rate 10k; +} + +# 如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查 +if (!-f $request_filename){ + break; + proxy_pass http://127.0.0.1; +} + +# 如果query string中包含"post=140",永久重定向到example.com +if ($args ~ post=140){ + rewrite ^ http://example.com/ permanent; +} + +# 防盗链 +location ~* \.(gif|jpg|png|swf|flv)$ { + valid_referers none blocked www.jefflei.comwww.leizhenfang.com; + if ($invalid_referer) { + return 404; + } +} +``` + +### 全局变量 + +下面是可以用作if判断的全局变量 + +- $args : #这个变量等于请求行中的参数,同$query_string +- $content_length : 请求头中的Content-length字段。 +- $content_type : 请求头中的Content-Type字段。 +- $document_root : 当前请求在root指令中指定的值。 +- $host : 请求主机头字段,否则为服务器名称。 +- $http_user_agent : 客户端agent信息 +- $http_cookie : 客户端cookie信息 +- $limit_rate : 这个变量可以限制连接速率。 +- $request_method : 客户端请求的动作,通常为GET或POST。 +- $remote_addr : 客户端的IP地址。 +- $remote_port : 客户端的端口。 +- $remote_user : 已经经过Auth Basic Module验证的用户名。 +- $request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。 +- $scheme : HTTP方法(如http,https)。 +- $server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。 +- $server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。 +- $server_name : 服务器名称。 +- $server_port : 请求到达服务器的端口号。 +- $request_uri : 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。 +- $uri : 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。 +- $document_uri : 与$uri相同。 + +**示例** + +``` +http://localhost:88/test1/test2/test.php +$host:localhost +$server_port:88 +$request_uri:http://localhost:88/test1/test2/test.php +$document_uri:/test1/test2/test.php +$document_root:/var/www/html +$request_filename:/var/www/html/test1/test2/test.php +``` + +## Nginx内置变量以及日志格式变量参数详解 + +``` +$args #请求中的参数值 +$query_string #同 $args +$arg_NAME #GET请求中NAME的值 +$is_args #如果请求中有参数,值为"?",否则为空字符串 +$uri #请求中的当前URI(不带请求参数,参数位于$args),可以不同于浏览器传递的$request_uri的值,它可以通过内部重定向,或者使用index指令进行修改,$uri不包含主机名,如"/foo/bar.html"。 +$document_uri #同 $uri +$document_root #当前请求的文档根目录或别名 +$host #优先级:HTTP请求行的主机名>"HOST"请求头字段>符合请求的服务器名.请求中的主机头字段,如果请求中的主机头不可用,则为服务器处理请求的服务器名称 +$hostname #主机名 +$https #如果开启了SSL安全模式,值为"on",否则为空字符串。 +$binary_remote_addr #客户端地址的二进制形式,固定长度为4个字节 +$body_bytes_sent #传输给客户端的字节数,响应头不计算在内;这个变量和Apache的mod_log_config模块中的"%B"参数保持兼容 +$bytes_sent #传输给客户端的字节数 +$connection #TCP连接的序列号 +$connection_requests #TCP连接当前的请求数量 +$content_length #"Content-Length" 请求头字段 +$content_type #"Content-Type" 请求头字段 +$cookie_name #cookie名称 +$limit_rate #用于设置响应的速度限制 +$msec #当前的Unix时间戳 +$nginx_version #nginx版本 +$pid #工作进程的PID +$pipe #如果请求来自管道通信,值为"p",否则为"." +$proxy_protocol_addr #获取代理访问服务器的客户端地址,如果是直接访问,该值为空字符串 +$realpath_root #当前请求的文档根目录或别名的真实路径,会将所有符号连接转换为真实路径 +$remote_addr #客户端地址 +$remote_port #客户端端口 +$remote_user #用于HTTP基础认证服务的用户名 +$request #代表客户端的请求地址 +$request_body #客户端的请求主体:此变量可在location中使用,将请求主体通过proxy_pass,fastcgi_pass,uwsgi_pass和scgi_pass传递给下一级的代理服务器 +$request_body_file #将客户端请求主体保存在临时文件中。文件处理结束后,此文件需删除。如果需要之一开启此功能,需要设置client_body_in_file_only。如果将次文件传 递给后端的代理服务器,需要禁用request body,即设置proxy_pass_request_body off,fastcgi_pass_request_body off,uwsgi_pass_request_body off,or scgi_pass_request_body off +$request_completion #如果请求成功,值为"OK",如果请求未完成或者请求不是一个范围请求的最后一部分,则为空 +$request_filename #当前连接请求的文件路径,由root或alias指令与URI请求生成 +$request_length #请求的长度 (包括请求的地址,http请求头和请求主体) +$request_method #HTTP请求方法,通常为"GET"或"POST" +$request_time #处理客户端请求使用的时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。 +$request_uri #这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看$uri更改或重写URI,不包含主机名,例如:"/cnphp/test.php?arg=freemouse" +$scheme #请求使用的Web协议,"http" 或 "https" +$server_addr #服务器端地址,需要注意的是:为了避免访问linux系统内核,应将ip地址提前设置在配置文件中 +$server_name #服务器名 +$server_port #服务器端口 +$server_protocol #服务器的HTTP版本,通常为 "HTTP/1.0" 或 "HTTP/1.1" +$status #HTTP响应代码 +$time_iso8601 #服务器时间的ISO 8610格式 +$time_local #服务器时间(LOG Format 格式) +$cookie_NAME #客户端请求Header头中的cookie变量,前缀"$cookie_"加上cookie名称的变量,该变量的值即为cookie名称的值 +$http_NAME #匹配任意请求头字段;变量名中的后半部分NAME可以替换成任意请求头字段,如在配置文件中需要获取http请求头:"Accept-Language",$http_accept_language即可 +$http_cookie +$http_host #请求地址,即浏览器中你输入的地址(IP或域名) +$http_referer #url跳转来源,用来记录从那个页面链接访问过来的 +$http_user_agent #用户终端浏览器等信息 +$http_x_forwarded_for +$sent_http_NAME #可以设置任意http响应头字段;变量名中的后半部分NAME可以替换成任意响应头字段,如需要设置响应头Content-length,$sent_http_content_length即可 +$sent_http_cache_control +$sent_http_connection +$sent_http_content_type +$sent_http_keep_alive +$sent_http_last_modified +$sent_http_location +$sent_http_transfer_encoding +``` + +**正确设置nginx中remote_addr和x_forwarded_for参数** + +什么是remote_addr: +remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这**样web服务器就会把remote_addr设为这台代理机器的IP** + +什么是x_forwarded_for: +正如上面所述,当你使用了代理时,web服务器就不知道你的真实IP了,为了避免这个情况,代理服务器通常会增加一个叫做x_forwarded_for的头信息,把连接它的客户端IP(即你的上网机器IP)加到这个头信息里,这样就能**保证网站的web服务器能获取到真实IP** + +**使用HAProxy做反向代理时:** +通常网站为了支撑更大的访问量,会增加很多web服务器,并在这些服务器前面增加一个反向代理(如HAProxy),它可以把负载均匀的分布到这些机器上。你的浏览器访问的首先是这台反向代理,它再把你的请求转发到后面的web服务器,这就使得web服务器会把remote_addr设为这台反向代理的IP,为了能让你的程序获取到真实的客户端IP,你需要给HAProxy增加以下配置 + +``` +option forwardfor +``` + +它的作用就像上面说的,增加一个x_forwarded_for的头信息,把客户端的ip添加进去,否则的话经测试为空值 +如上面的日志格式所示:**$http_x_forwarded_for 是客户端真实的IP地址,$remote_addr是前端Haproxy的IP地址** + +**或者:** + +当Nginx处在HAProxy后面时,就会把remote_addr设为HAProxy的IP,这个值其实是毫无意义的,你可以通过nginx的realip模块,让它使用x_forwarded_for里的值。使用这个模块需要重新编译Nginx,增加**--with-http_realip_module**参数 +**./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module \ --with-http_realip_module --http-log-path=/data/logs/nginx/access.log --error-log-path=/data/logs/nginx/error.log** + +``` + set_real_ip_from 10.1.10.0/24; + real_ip_header X-Forwarded-For; +``` + +上面的两行配置就是把从10.1.10这一网段过来的请求全部使用X-Forwarded-For里的头信息作为remote_addr,这样此时remote_addr就是客户端真实的IP地址 + +**X-Forwarded-For 和 X-Real-IP 获取客户端的ip的区别:** +一般来说,X-Forwarded-For是用于记录代理信息的,每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源IP追加在X-Forwarded-For中 来自4.4.4.4的一个请求,header包含这样一行 X-Forwarded-For: 1.1.1.1, 2.2.2.2, 3.3.3.3 代表 请求由1.1.1.1发出,经过三层代理,第一层是2.2.2.2,第二层是3.3.3.3,而本次请求的来源IP 4.4.4.4是第三层代理 **而X-Real-IP,一般只记录真实发出请求的客户端IP,上面的例子,如果配置了X-Read-IP,将会是 X-Real-IP: 1.1.1.1 所以 ,如果只有一层代理,这两个头的值就是一样的** + +​ + +## ngx_lua 模块API说明 + + + +## Nginx实战 + +### 静态资源Web服务器 + +1、设置资源目录,示例: + +``` +C:\Users\hi.li\Desktop\opensource\nginx\static_server\html +C:\Users\hi.li\Desktop\opensource\nginx\static_server\login.html +C:\Users\hi.li\Desktop\opensource\nginx\static_server\mp3 +C:\Users\hi.li\Desktop\opensource\nginx\static_server\pic +C:\Users\hi.li\Desktop\opensource\nginx\static_server\html\a.html +C:\Users\hi.li\Desktop\opensource\nginx\static_server\mp3\1 +C:\Users\hi.li\Desktop\opensource\nginx\static_server\mp3\kaluli.mp3 +C:\Users\hi.li\Desktop\opensource\nginx\static_server\mp3\1\cymx.mp3 +C:\Users\hi.li\Desktop\opensource\nginx\static_server\pic\abc +C:\Users\hi.li\Desktop\opensource\nginx\static_server\pic\android.jpg +C:\Users\hi.li\Desktop\opensource\nginx\static_server\pic\bootstrap.png +C:\Users\hi.li\Desktop\opensource\nginx\static_server\pic\ios.jpg +C:\Users\hi.li\Desktop\opensource\nginx\static_server\pic\abc\redis.png +``` + +2、编辑conf目录下的nginx.conf文件,增加一个虚拟服务器配置(端口为81): + +``` + # 静态资源服务器 + server { + listen 81; + server_name localhost; + + charset utf-8; + + #access_log logs/host.access.log main; + + # 首页,指定主页,如果没有其他匹配,根据uri在../static_server下找资源 + location / { + root ../static_server; + index login.html; + } + + # 图片资源请求, 匹配以/pic/开头的Url, 如果找不到文件,默认显示/pic/ios.jpg + location ^~ /pic/ { + # 设置本地缓存过期时间为30天,充分利用客户端缓存提升性能 + expires 30d; + root ../static_server; + try_files $uri /pic/ios.jpg; + } + + # 音频资源请求,文件后缀为mp3或mp4这类文件,统一到../static_server/mp3下查找, 且进行传输优化 + location ~* \.(mp3|mp4) { + root ../static_server/mp3; + try_files $uri /pic/android.jpg; + sendfile on; + sendfile_max_chunk 1m; + tcp_nodelay on; + keepalive_timeout 65; + } + + # 图片防盗链设置,只有在valid_referers指令列表中的域名过来的链接才能访问: + # none : Referer” 来源头部为空 + # blocked :Referer”来源头部不为空,但是里面的值被代理或者防火墙删除了,这些值都不以http://或者https://开头 + # server_names : “Referer”来源头部包含当前的server_names(当前域名) + # *.ttlsa.com : 任意字符串,定义服务器名或者可选的URI前缀.主机名可以使用*开头或者结尾,在检测来源头部这个过程中,来源域名中的主机端口将会被忽略掉 + # ~\.google\. ~\.baidu\. : 正则表达式,~表示排除https://或http://开头的字符串 + location ~* \.(gif|jpg|png|bmp)$ { + valid_referers none blocked *.ttlsa.com server_names ~\.google\. ~\.baidu\.; + if ($invalid_referer) { + return 403; + #rewrite ^/ http://www.ttlsa.com/403.jpg; + } + } + + # 指定代理转向,uri为/html/b.html时重定向至百度网站 + location /html/b.html { + proxy_pass http://www.baidu.com; + } + + # 动态页面代理转发至其他地址处理 + location ~ .(jsp|do)$ { + proxy_pass http://localhost; + } + + + error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root html; + } + + } +``` + +3、检测配置是否正确: + +``` +# 检测默认配置文件 +> nginx -t +# 检测指定配置文件 +> nginx -t -c conf/nginx.conf +``` + +4、启动服务器 + +5、在浏览器打开以下地址验证配置 + +``` +# html访问 +http://localhost:81/ # 显示login.html +http://localhost:81/index.html # 找不到文件404 +http://localhost:81/html/a.html # 显示a.html +http://localhost:81/html/b.html # 跳转到百度 + +# 图片资源获取 +http://localhost:81/pic/android.jpg # 显示android.jpg +http://localhost:81/pic/bootstrap.png # 显示bootstrap.png +http://localhost:81/pic/abc/redis.png # 显示redis.png +http://localhost:81/pic/ # 显示默认的iso.jpg +http://localhost:81/pic/1.jpg # 显示默认的iso.jpg + +# 音频资源请求 +http://localhost:81/kaluli.mp3 # 下载kaluli.mp3 +http://localhost:81/1/cymx.mp3 # 下载cymx.mp3 +http://localhost:81/cymx.mp3 # 找不到路径,显示默认的android.jpg +http://localhost:81/test/a.mp4 # 找不到路径,显示默认的android.jpg +http://localhost:81/pic/1.mp3 # 优先匹配到/pic/规则,显示默认的iso.jpg +``` + +### Https访问设置 + +#### 申请证书 + +1、购买证书:可以在阿里云控制台-产品与服务-安全(云盾)-CA证书服务(数据安全),点击购买证书;申请完成后可将证书下载到本地; + +2、通过openssl制作证书 + +openssl是目前最流行的SSL密码库工具,其提供了一个通用、健壮、功能完备的工具套件,用以支持SSL/TLS协议的实现。 + +比如生成到:/usr/local/ssl + +``` +openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout /usr/local/ssl/nginx.key -out /usr/local/ssl/nginx.crt +``` + +生成过程: + +``` +# openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout /u sr/local/ssl/nginx.key -out /usr/local/ssl/nginx.crt +Generating a 2048 bit RSA private key +...............................................................................+ ++ +...............+++ +writing new private key to '/usr/local/ssl/nginx.key' +----- +You are about to be asked to enter information that will be incorporated +into your certificate request. +What you are about to enter is what is called a Distinguished Name or a DN. +There are quite a few fields but you can leave some blank +For some fields there will be a default value, +If you enter '.', the field will be left blank. +----- +Country Name (2 letter code) [XX]:CN +State or Province Name (full name) []:beijing +Locality Name (eg, city) [Default City]:beijing +Organization Name (eg, company) [Default Company Ltd]:xxxx +Organizational Unit Name (eg, section) []:xxxx +Common Name (eg, your name or your server's hostname) []:xxxx(一般是域名) +Email Address []:xxxx@xxxx.com +# ll +total 8 +-rw-r--r--. 1 root root 1391 Apr 21 13:29 nginx.crt +-rw-r--r--. 1 root root 1704 Apr 21 13:29 nginx.key +``` + +#### 设置服务器配置 + +1、将两个证书复制到服务器目录,可以自己在nginx目录中创建cert目录,放置证书(nginx.crt、nginx.key); + +2、修改nginx服务器配置,默认为nginx.conf + +``` +# https服务 +server { + listen 443; + server_name hivenet.com; // 你的域名 + ssl on; + root ../static_server; // 前台文件存放文件夹,可改成别的 + index login.html;// 上面配置的文件夹里面的login.html + ssl_certificate cert/nginx.crt;// 改成你的证书的名字 + ssl_certificate_key cert/nginx.key;// 你的证书的名字 + ssl_session_timeout 5m; + # ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + # ssl_prefer_server_ciphers on; + location / { + index login.html; + } +} + +# http服务,跳转到https访问 +server { + listen 80; + server_name hivenet.com;// 你的域名 + rewrite ^(.*)$ https://$host$1 permanent;// 把http的域名请求转成https +} +``` + +### 负载均衡+高可用配置 + +#### 环境信息 + +192.168.0.221:nginx + keepalived master + +192.168.0.222:nginx + keepalived backup + +192.168.0.223:nginx(后台静态资源Web服务器,也可替换为Tomcat等应用服务器) + +192.168.0.224:nginx(后台静态资源Web服务器,也可替换为Tomcat等应用服务器) + +虚拟ip(VIP):192.168.0.200,对外提供服务的ip,也可称作浮动ip + +注:keepalived的安装自行参考其他材料 + +#### Nginx负载均衡配置 + +nginx.conf的配置参考如下(两台服务器的配置完全一样,暂时无主从之分): + +``` +user root; #运行用户 +worker_processes 1; #启动进程,通常设置成和cpu的数量相等 + +#全局错误日志及PID文件 +error_log /usr/local/nginx/logs/error.log; +error_log /usr/local/nginx/logs/error.log notice; +error_log /usr/local/nginx/logs/error.log info; +pid /usr/local/nginx/logs/nginx.pid; + +# 工作模式及连接数上线 +events +{ + use epoll; #epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能 + + worker_connections 1024; #单个后台worker process进程的最大并发链接数 +} + +#设定http服务器,利用它的反向代理功能提供负载均衡支持 +http +{ + include mime.types; + default_type application/octet-stream; + + #设定请求缓冲 + server_names_hash_bucket_size 128; + client_header_buffer_size 32K; + large_client_header_buffers 4 32k; + # client_max_body_size 8m; + + #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用, + #必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime. + sendfile on; + tcp_nopush on; + tcp_nodelay on; + + #连接超时时间 + keepalive_timeout 65; + + #开启gzip压缩,降低传输流量 + gzip on; + gzip_min_length 1k; + gzip_buffers 4 16k; + gzip_http_version 1.1; + gzip_comp_level 2; + gzip_types text/plain application/x-javascript text/css application/xml; + gzip_vary on; + + #添加后端应用服务器列表,真实应用服务器都放在这 + upstream appserver_pool + { + #server 后端服务器地址:端口号 weight表示权值,权值越大,被分配的几率越大; +    server 192.168.0.223:8080 weight=4 max_fails=2 fail_timeout=30s; +   server 192.168.0.224:8080 weight=4 max_fails=2 fail_timeout=30s; + } + + server + { + listen 80; #监听端口 + server_name localhost; + + #默认请求设置 + location / { + proxy_pass http://appserver_pool; #转向后端应用服务器处理 + } + + #所有的jsp页面均由后端应用服务器处理 + location ~ \.(jsp|jspx|dp)?$ + { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://appserver_pool; #转向后端应用服务器处理 + } + + #所有的静态文件直接读取不经过后端,nginx自己处理 + location ~ .*\.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ + { + expires 30d; + } + location ~ .*\.(js|css)?$ + { + expires 1h; + } + + #定义错误提示页面 + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root html; + } + + } +} +``` + +**重点配置项为“upstream appserver_pool ”和“proxy_pass”**,上例中采用了权重(weight)的策略,各种分配策略分别说明如下: + +##### **轮询** + +最基本的配置方法,它是upstream模块默认的负载均衡默认策略。每个请求会按时间顺序逐一分配到不同的后端服务器。 + +``` + upstream appserver_pool + { + #server 后端服务器地址:端口号 参数=参数值 ... +    server 192.168.0.223:8080 max_fails=2 fail_timeout=30s; +   server 192.168.0.224:8080 max_fails=2 fail_timeout=30s; + } +``` + +有如下参数: + +| fail_timeout | 与max_fails结合使用。 | +| ------------ | ------------------------------------------------------------ | +| max_fails | 设置在fail_timeout参数设置的时间内最大失败次数,如果在这个时间内,所有针对该服务器的请求都失败了,那么认为该服务器会被认为是停机了, | +| fail_time | 服务器会被认为停机的时间长度,默认为10s。 | +| backup | 标记该服务器为备用服务器。当主服务器停止时,请求会被发送到它这里。 | +| down | 标记服务器永久停机了。 | + + 注意: + +- 在轮询中,如果服务器down掉了,会自动剔除该服务器。 +- 缺省配置就是轮询策略。 +- 此策略适合服务器配置相当,无状态且短平快的服务使用。 + +##### 权重 + +权重方式,在轮询策略的基础上增加weight参数指定轮询的几率。weight参数用于指定轮询几率,默认值为1;weight的数值与访问比率成正比。比如下例中Tomcat 7.0被访问的几率为其他服务器的两倍。 + +``` +#动态服务器组 +upstream dynamic_zuoyu { + server localhost:8080 weight=2; #tomcat 7.0 + server localhost:8081; #tomcat 8.0 + server localhost:8082 backup; #tomcat 8.5 + server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0 +} +``` + +注意: + +- 权重越高分配到需要处理的请求越多。 +- 此策略可以与least_conn和ip_hash结合使用。 +- 此策略比较适合服务器的硬件配置差别比较大的情况。 + +##### 客户端IP分配 + +指定负载均衡器按照基于客户端IP的分配方式,这个方法确保了相同的客户端的请求一直发送到相同的服务器,以保证session会话。这样每个访客都固定访问一个后端服务器,可以解决session不能跨服务器的问题。 + +``` +#动态服务器组 + upstream dynamic_zuoyu { + ip_hash; #保证每个访客固定访问一个后端服务器 + server localhost:8080 weight=2; #tomcat 7.0 + server localhost:8081; #tomcat 8.0 + server localhost:8082; #tomcat 8.5 + server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0 + } +``` + +注意: + +- 在nginx版本1.3.1之前,不能在ip_hash中使用权重(weight)。 +- ip_hash不能与backup同时使用。 +- 此策略适合有状态服务,比如session。 +- 当有服务器需要剔除,必须手动down掉。 + +##### 连接数较少优先 + +把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。 + +``` +#动态服务器组 +upstream dynamic_zuoyu { + least_conn; #把请求转发给连接数较少的后端服务器 + server localhost:8080 weight=2; #tomcat 7.0 + server localhost:8081; #tomcat 8.0 + server localhost:8082 backup; #tomcat 8.5 + server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0 +} +``` + +注意: + +- 此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况。 + +##### 第三方策略 + +第三方的负载均衡策略的实现需要安装第三方插件。 + +**①fair** + +按照服务器端的响应时间来分配请求,响应时间短的优先分配。 + +``` +#动态服务器组 +upstream dynamic_zuoyu { + server localhost:8080; #tomcat 7.0 + server localhost:8081; #tomcat 8.0 + server localhost:8082; #tomcat 8.5 + server localhost:8083; #tomcat 9.0 + fair; #实现响应时间短的优先分配 +} +``` + +**②url_hash** + +按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,要配合缓存命中来使用。同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费。而使用url_hash,可以使得同一个url(也就是同一个资源请求)会到达同一台服务器,一旦缓存住了资源,再此收到请求,就可以从缓存中读取。 + +``` +#动态服务器组 +upstream dynamic_zuoyu { + hash $request_uri; #实现每个url定向到同一个后端服务器 + server localhost:8080; #tomcat 7.0 + server localhost:8081; #tomcat 8.0 + server localhost:8082; #tomcat 8.5 + server localhost:8083; #tomcat 9.0 +} +``` + +#### keepalived实现nginx高可用(HA) + +keepalived主要起到两个作用:实现VIP到本地ip的映射; 以及检测nginx状态。 + +master上的keepalived.conf内容如下: + +``` +global_defs { + notification_email { + 997914490@qq.com + } + notification_email_from sns-lvs@gmail.com + smtp_server smtp.hysec.com + smtp_connection_timeout 30 + router_id nginx_master # 设置nginx master的id,在一个网络应该是唯一的 +} +vrrp_script chk_http_port { + script "/usr/local/src/check_nginx_pid.sh" #最后手动执行下此脚本,以确保此脚本能够正常执行 + interval 2 #(检测脚本执行的间隔,单位是秒) + weight 2 +} +vrrp_instance VI_1 { + state MASTER # 指定keepalived的角色,MASTER为主,BACKUP为备 + interface eth0 # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) + virtual_router_id 66 # 虚拟路由编号,主从要一直 + priority 100 # 优先级,数值越大,获取处理请求的优先级越高 + advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数) + authentication { + auth_type PASS + auth_pass 1111 + } + track_script { + chk_http_port #(调用检测脚本) + } + virtual_ipaddress { + 192.168.0.200 # 定义虚拟ip(VIP),可多设,每行一个 + } +} +``` + +backup上的keepalived.conf内容如下: + +``` +global_defs { + notification_email { + 997914490@qq.com + } + notification_email_from sns-lvs@gmail.com + smtp_server smtp.hysec.com + smtp_connection_timeout 30 + router_id nginx_backup # 设置nginx backup的id,在一个网络应该是唯一的 +} +vrrp_script chk_http_port { + script "/usr/local/src/check_nginx_pid.sh" + interval 2 #(检测脚本执行的间隔) + weight 2 +} +vrrp_instance VI_1 { + state BACKUP # 指定keepalived的角色,MASTER为主,BACKUP为备 + interface eth0 # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) + virtual_router_id 66 # 虚拟路由编号,主从要一直 + priority 99 # 优先级,数值越大,获取处理请求的优先级越高 + advert_int 1 # 检查间隔,默认为1s(vrrp组播周期秒数) + authentication { + auth_type PASS + auth_pass 1111 + } + track_script { + chk_http_port #(调用检测脚本) + } + virtual_ipaddress { + 192.168.0.200 # 定义虚拟ip(VIP),可多设,每行一个 + } +} +``` + +nginx检测脚本check_nginx_pid.sh内容如下: + +``` +#!/bin/bash +A=`ps -C nginx --no-header |wc -l` +if [ $A -eq 0 ];then + /usr/local/nginx/sbin/nginx #重启nginx + if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then #nginx重启失败,则停掉keepalived服务,进行VIP转移 + killall keepalived + fi +fi +``` From 6fd2409796c57f42c294c894dafd966daf1833e6 Mon Sep 17 00:00:00 2001 From: "tongfu.e" Date: Fri, 17 May 2024 17:44:30 +0800 Subject: [PATCH 17/19] =?UTF-8?q?feat:=20add=20=E3=80=8Ahttps://architectu?= =?UTF-8?q?renotes.co/things-you-should-know-about-databases/=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e6b4fcc..abe6644 100644 --- a/README.md +++ b/README.md @@ -96,3 +96,4 @@ - [Software-Engineering-at-Google](https://qiangmzsx.github.io/Software-Engineering-at-Google/#/?id=software-engineering-at-google) - [Docker Containers vs. Kubernetes Pods - Taking a Deeper Look](https://labs.iximiuz.com/tutorials/containers-vs-pods) - [10 Things Software Developers Should Learn about Learning](https://cacm.acm.org/research/10-things-software-developers-should-learn-about-learning/) +- [Relational Databases Explained](https://architecturenotes.co/things-you-should-know-about-databases/) From c5654221bc3ce9b4869913336284ee153d3c863f Mon Sep 17 00:00:00 2001 From: "tongfu.e" Date: Mon, 22 Jul 2024 14:13:17 +0800 Subject: [PATCH 18/19] feat: update README --- MDDemo.md | 2 +- README.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/MDDemo.md b/MDDemo.md index be114a9..5600fe3 100644 --- a/MDDemo.md +++ b/MDDemo.md @@ -296,4 +296,4 @@ Markdown Nice 这么好用,简直是{喜大普奔|hē hē hē hē}呀! ### 5.4 更多文档 -更多文档请参考 [markdown-nice-docs](https://docs.mdnice.com "更多文档") \ No newline at end of file +更多文档请参考 [markdown-nice-docs](https://docs.mdnice.com "更多文档") diff --git a/README.md b/README.md index abe6644..013d0b4 100644 --- a/README.md +++ b/README.md @@ -97,3 +97,4 @@ - [Docker Containers vs. Kubernetes Pods - Taking a Deeper Look](https://labs.iximiuz.com/tutorials/containers-vs-pods) - [10 Things Software Developers Should Learn about Learning](https://cacm.acm.org/research/10-things-software-developers-should-learn-about-learning/) - [Relational Databases Explained](https://architecturenotes.co/things-you-should-know-about-databases/) +- [基本功 | 一文讲清多线程和多线程同步](https://tech.meituan.com/2024/07/19/multi-threading-and-multi-thread-synchronization.html) From 4b35225709886fc6291a3ed0e5b13722cbcb9446 Mon Sep 17 00:00:00 2001 From: "tongfu.e" Date: Thu, 19 Dec 2024 18:00:04 +0800 Subject: [PATCH 19/19] feat: update docker --- ...72\347\241\200\346\214\207\345\215\227.md" | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git "a/Server/Docker\345\237\272\347\241\200\346\214\207\345\215\227.md" "b/Server/Docker\345\237\272\347\241\200\346\214\207\345\215\227.md" index 269be01..a51b72a 100644 --- "a/Server/Docker\345\237\272\347\241\200\346\214\207\345\215\227.md" +++ "b/Server/Docker\345\237\272\347\241\200\346\214\207\345\215\227.md" @@ -44,14 +44,15 @@ - 创建: `docker create --name name image` - 启动: `docker start name` -- 创建+启动: `docker run --name name --detach image ` --detach: 启动后将程序和控制台分离,使之进入后台模式。 -- 查看:`docker ps --all` +- 创建+启动: `docker run --name name --detach image` --detach: 启动后将程序和控制台分离,使之进入后台模式。 +- 查看:`docker ps --all` - 停止:`docker stop name` (沙盒系统还存在,修改的内容也都保存) - 删除: `docker rm name --force` - 进入容器: `docker exec -it name bash` 其中 `-i` ( `--interactive` ) 表示保持我们的输入流。 `-t` ( `--tty` ) 表示启用一个伪终端,形成我们与 bash 的交互 。 - 衔接容器: `docker attach name` 这个命令最直观的效果可以理解为我们将容器中的主程序转为了“前台”运行 ( 与 `docker run` 中的 `-d` 选项有相反的意思 )。 以启动一个`nginx`容器服务作为示例 + ``` shell docker run -d -rm -p 8800:80 -v /home/nginx/html:/usr/share/nginx/html --name nginx nginx @@ -68,8 +69,6 @@ docker run -d -rm -p 8800:80 -v /home/nginx/html:/usr/share/nginx/html --name ng ![Docker命令](./images/docker.jpg 'Docker命令') - - ### 容器网络 > 容器网络实质上也是由 Docker 为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的**网络设备、IP 协议栈、端口套接字、IP 路由表、防火墙等等与网络相关的模块**。 @@ -79,6 +78,7 @@ docker run -d -rm -p 8800:80 -v /home/nginx/html:/usr/share/nginx/html --name ng - **沙盒 ( Sandbox )**: 提供容器网络栈,主要是隔离了容器网络和宿主机网络,形成完全独立的容器网络环境。 - **网络 ( Network )**: `Docker`内部的虚拟子网,与宿主机网络存在隔离关系,主要目的是形成容器间的安全通讯环境。 - **端点 ( Endpoint )**: 主要目的是形成一个可以控制的突破封闭网络环境的出入口。当容器的端点与网络的断点匹配之后,就如同在两者之间搭建了桥梁,就能进行数据传输了。 + ### 数据管理 数据是应用程序的重要产出,数据可以说是最重要的资产。但是在`docker`中容器运行的文件系统处在于沙盒之中,与外界是隔离的,所以必须是有合理的方式与外界进行数据交换。 @@ -113,7 +113,6 @@ nginx -v:--volume 的缩写形式 ``` - ### `Dockerfile` 这是`docker`特有的镜像构建定义文件,通过了解它就能真正体验一种秒级镜像构建的乐趣。 @@ -142,7 +141,9 @@ nginx ```dockerfile FROM [AS ] FROM [:] [AS ] + FROM [@] [AS ] + ``` `Dockerfile`第一条指令必须是`FROM`指令,因为一切构建过程都基于基础镜像。 @@ -187,10 +188,6 @@ FROM [@] [AS ] CMD ["redis-server"] ``` - - - - - **EXPOSE**:为镜像指定要暴露的端口。 ```dockerfile @@ -224,15 +221,13 @@ FROM [@] [AS ] `docker build` 可以接收一个参数,需要特别注意的是,**这个参数为一个目录路径 ( 本地路径或 URL 路径 ),而并非 Dockerfile 文件的路径**。在 `docker build` 里,这个我们给出的目录会作为构建的环境目录,我们很多的操作都是基于这个目录进行的。 ```shell -$ sudo docker build -t webapp:latest -f ./webapp/a.Dockerfile ./webapp +sudo docker build -t webapp:latest -f ./webapp/a.Dockerfile ./webapp ``` **-t webapp:latest** 指定镜像名称。 **-f ./webapp/a.Dockerfile** 指定dockerfile地址,如果dockerfile不在./webapp中,那么你需要这个选项。 - - ### 高频容器 - `Nginx` @@ -261,8 +256,6 @@ $ sudo docker build -t webapp:latest -f ./webapp/a.Dockerfile ./webapp mysql:5.7.21 ``` - - ## 基础进阶 基础弄完了总要来点高级的 @@ -291,7 +284,7 @@ $ sudo docker build -t webapp:latest -f ./webapp/a.Dockerfile ./webapp version: '3' # 服务内容器的细节 services: - # 一个service是配置的最小单元 + # 一个service是配置的最小单元 webapp: build: ./image/webapp ports: @@ -315,12 +308,15 @@ $ sudo docker build -t webapp:latest -f ./webapp/a.Dockerfile ./webapp logvolume: {} ``` - - 3. 启动项目/应用。 +## 最佳实践 +```shell +# 1. 清理容器,镜像和缓存 +docker system prune -a --volumes +``` ## 总结 -话不多说,`Docker`是真香。 \ No newline at end of file +话不多说,`Docker`是真香。