From 8f424eb45e805d01f8f45ff360d8831e8695b1f3 Mon Sep 17 00:00:00 2001 From: Jacqueline712 Date: Sun, 5 Nov 2023 17:23:05 +0800 Subject: [PATCH] deploy --- 404.html | 2 +- column/Algorithm/001_Stack.html | 2 +- column/Algorithm/002_Queue.html | 2 +- column/Algorithm/003_LinkedList.html | 2 +- column/Algorithm/004_Dictionary.html | 2 +- column/Algorithm/005_Tree.html | 2 +- column/Algorithm/006_Graph.html | 2 +- column/Algorithm/007_Heap.html | 2 +- column/Algorithm/008_Dynamics.html | 2 +- column/Algorithm/009_Greedy.html | 2 +- column/Algorithm/010_Search.html | 2 +- column/Algorithm/index.html | 2 +- column/BackEnd/Node/001_deploy.html | 2 +- column/BackEnd/Node/002_fullStack.html | 2 +- column/BackEnd/Node/003_graffitiBoard.html | 2 +- column/BackEnd/index.html | 2 +- column/BaseCommand/MacShortcutKey/001_vscode.html | 2 +- column/BaseCommand/MacShortcutKey/002_macos.html | 2 +- column/BaseCommand/MacShortcutKey/003_console.html | 2 +- column/BaseCommand/MacShortcutKey/004_google.html | 2 +- column/BaseCommand/MacShortcutKey/005_typora.html | 2 +- column/BaseCommand/MacShortcutKey/006_notion.html | 2 +- column/BaseCommand/MacShortcutKey/007_git.html | 2 +- column/BaseCommand/MacShortcutKey/008_linux.html | 2 +- column/BaseCommand/MacShortcutKey/009_lark.html | 2 +- column/BaseCommand/WinShortcutKey/001.html | 2 +- column/BaseCommand/WinShortcutKey/002.html | 2 +- column/BaseCommand/WinShortcutKey/003.html | 2 +- column/BaseCommand/WinShortcutKey/004.html | 2 +- column/BaseCommand/index.html | 2 +- column/ComputerKnowledge/Browser/001.html | 2 +- column/ComputerKnowledge/Browser/002.html | 2 +- column/ComputerKnowledge/PerformanceOptimization/001.html | 2 +- column/ComputerKnowledge/Security/001.html | 2 +- column/ComputerKnowledge/index.html | 2 +- column/DeepLearning/index.html | 2 +- column/FrontEnd/CSS/001.html | 2 +- column/FrontEnd/CSS/002.html | 2 +- column/FrontEnd/ComponentLib/001.html | 2 +- column/FrontEnd/ComponentLib/002.html | 2 +- column/FrontEnd/JavaScript/001.html | 2 +- column/FrontEnd/JavaScript/002.html | 2 +- column/FrontEnd/JavaScript/003.html | 2 +- column/FrontEnd/JavaScript/004.html | 2 +- column/FrontEnd/JavaScript/005.html | 2 +- column/FrontEnd/JavaScript/006.html | 2 +- column/FrontEnd/JavaScript/007.html | 2 +- column/FrontEnd/JavaScript/008.html | 2 +- column/FrontEnd/JavaScript/009.html | 2 +- column/FrontEnd/JavaScript/010.html | 2 +- column/FrontEnd/Practice/001.html | 2 +- column/FrontEnd/React/001.html | 2 +- column/FrontEnd/React/002.html | 2 +- column/FrontEnd/React/003.html | 2 +- column/FrontEnd/React/004.html | 2 +- column/FrontEnd/React/005.html | 2 +- column/FrontEnd/Translation/001.html | 2 +- column/FrontEnd/TypeScript/001_tsIntro.html | 2 +- column/FrontEnd/TypeScript/002_tsDecorator.html | 2 +- column/FrontEnd/TypeScript/003_TSIntro2.html | 2 +- column/FrontEnd/VUE/001.html | 2 +- column/FrontEnd/VUE/002.html | 2 +- column/FrontEnd/VUE/003.html | 2 +- column/FrontEnd/VUE/004.html | 2 +- column/FrontEnd/VUE/005.html | 2 +- column/FrontEnd/VUE/006.html | 2 +- column/FrontEnd/VUE/007.html | 2 +- column/FrontEnd/VUE/008_VUE3API.html | 2 +- column/FrontEnd/VUE/009_vitepress_blog.html | 2 +- column/FrontEnd/VUEPrinciple/001.html | 2 +- column/FrontEnd/VUEPrinciple/002.html | 2 +- column/FrontEnd/VUEPrinciple/003.html | 2 +- column/FrontEnd/VUEPrinciple/004.html | 2 +- column/FrontEnd/Webpack/001.html | 2 +- column/FrontEnd/Webpack/002.html | 2 +- column/FrontEnd/Webpack/003.html | 2 +- column/FrontEnd/Webpack/004.html | 2 +- column/FrontEnd/Webpack/005.html | 2 +- column/FrontEnd/YouthCamp/001.html | 2 +- column/FrontEnd/YouthCamp/002.html | 2 +- column/FrontEnd/YouthCamp/003.html | 2 +- column/FrontEnd/YouthCamp/004.html | 2 +- column/FrontEnd/YouthCamp/005.html | 2 +- column/FrontEnd/YouthCamp/006.html | 2 +- column/FrontEnd/YouthCamp/007.html | 2 +- column/FrontEnd/YouthCamp/008.html | 2 +- column/FrontEnd/YouthCamp/009.html | 2 +- column/FrontEnd/YouthCamp/010.html | 2 +- column/FrontEnd/YouthCamp/011.html | 2 +- column/FrontEnd/index.html | 2 +- column/Growing/ReviewSummary/001.html | 2 +- column/Growing/ReviewSummary/002.html | 2 +- column/Growing/ReviewSummary/003.html | 2 +- column/Growing/YearSummary/001.html | 2 +- column/Growing/YearSummary/002.html | 2 +- column/Growing/index.html | 2 +- column/Guide/index.html | 2 +- column/Interview/Browser.html | 2 +- column/Interview/CSS.html | 2 +- column/Interview/CSSWriting.html | 2 +- column/Interview/DataStructure.html | 2 +- column/Interview/DesignMode.html | 2 +- column/Interview/Development.html | 2 +- column/Interview/Html5.html | 2 +- column/Interview/JSWriting.html | 2 +- column/Interview/JavaScript.html | 2 +- column/Interview/Leetcode.html | 2 +- column/Interview/Network.html | 2 +- column/Interview/Node.html | 2 +- column/Interview/OperatingSystem.html | 2 +- column/Interview/Performance.html | 2 +- column/Interview/React.html | 2 +- column/Interview/TypeScript.html | 2 +- column/Interview/Vue.html | 2 +- column/Interview/Webpack.html | 2 +- column/Interview/index.html | 2 +- column/MachineLearning/Tensorflow/01_MLBase.html | 2 +- column/MachineLearning/index.html | 2 +- column/OtherLang/Android/001.html | 2 +- column/OtherLang/PHP/001.html | 2 +- column/OtherLang/PHP/002.html | 2 +- column/OtherLang/PHP/003.html | 2 +- column/OtherLang/index.html | 2 +- column/Product/SoftwareEngineer/000Guide.html | 2 +- column/Product/SoftwareEngineer/001Definition.html | 2 +- column/Product/SoftwareEngineer/002ProcessModel.html | 2 +- column/Product/SoftwareEngineer/003Prototype.html | 2 +- column/Product/SoftwareEngineer/004Product.html | 2 +- column/Product/SoftwareEngineer/005Measure.html | 2 +- column/Product/SoftwareEngineer/006Scope.html | 2 +- column/Product/SoftwareEngineer/007RiskAnalysis.html | 2 +- column/Product/SoftwareEngineer/008Schedule.html | 2 +- column/Product/SoftwareEngineer/009StructuredAnalysis.html | 2 +- column/Product/SoftwareEngineer/010DataFlowDiagram.html | 2 +- column/Product/SoftwareEngineer/011StructuredDesign.html | 2 +- column/Product/SoftwareEngineer/012SoftwareTest.html | 2 +- column/Product/SoftwareEngineer/013UML.html | 2 +- column/Product/SoftwareEngineer/index.html | 2 +- column/Product/SoftwareTesting/001.html | 2 +- column/Product/SoftwareTesting/002.html | 2 +- column/Product/SoftwareTesting/003.html | 2 +- column/Product/SoftwareTesting/004.html | 2 +- column/Product/SoftwareTesting/005.html | 2 +- column/Product/SoftwareTesting/006.html | 2 +- column/Product/index.html | 2 +- column/Template/Notion/001.html | 2 +- column/Template/Notion/002.html | 2 +- column/Template/index.html | 2 +- column/Travel/EastChina/JiangXi.html | 2 +- column/Travel/index.html | 2 +- hashmap.json | 2 +- index.html | 2 +- 152 files changed, 152 insertions(+), 152 deletions(-) diff --git a/404.html b/404.html index 79da0312..e2a2d923 100644 --- a/404.html +++ b/404.html @@ -16,7 +16,7 @@
Skip to content

404

PAGE NOT FOUND

But if you don't change your direction, and if you keep looking, you may end up where you are heading.

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Algorithm/001_Stack.html b/column/Algorithm/001_Stack.html index 28aa31d6..e4cc5214 100644 --- a/column/Algorithm/001_Stack.html +++ b/column/Algorithm/001_Stack.html @@ -329,7 +329,7 @@ }; func1(); //5 4 3

看到这里,很多小伙伴心中可能已经在构思整段代码的执行顺序是什么样的。接下来用一张图来展示。

函数调用堆栈

我们都知道, JavaScript 的执行环境是单线程的。所谓单线程是指一次只能完成一个任务,如果有多个任务,就必须排队,只有当前面一个任务完成时,才能执行后面一个任务,以此类推。上图中所演示的,即每调用一个函数,如果里面还有新的函数,那么就先把它放到调用堆栈里,等到所有任务都放满以后,开始依次执行。

而函数调用堆栈是一个典型的栈的数据结构,遵循后进先出原则,当 func1func2func3 依次放进调用栈后, 遵循后进先出原则 ,那么 func3 函数的内容会先被执行,之后是 func2 ,最后是 func1 。这就是函数调用堆栈。

五、写在最后

栈在前端中的应用就讲到这里啦!栈在我们平常的开发中无处不在,我们写的每一个程序,基本上都会用到函数调用堆栈。且在前端的面试中,面试官也很喜欢问深拷贝和浅拷贝,大家可以对这块知识多回顾多实践。

- + \ No newline at end of file diff --git a/column/Algorithm/002_Queue.html b/column/Algorithm/002_Queue.html index 64c2e3c0..f4ac8c37 100644 --- a/column/Algorithm/002_Queue.html +++ b/column/Algorithm/002_Queue.html @@ -203,7 +203,7 @@ alert('SetTimeout'); //(alert 会阻断 js 执行, 也会阻断 DOM 渲染,便于查看效果) });

以上这段代码中,浏览器显示效果如下。

宏任务

在图中可以看出,当 DOM 对应的文字已经显示时, setTimeout 弹框才出现,所以宏任务 setTimeout 是在 DOM 渲染后(即 DOM 渲染并显示结束)才触发。

讲到这里,回到我们前面所说的知识点。

从上面的演示后,相信大家应该明白了微任务、宏任务和 DOM 的关系。在第一个演示中,微任务 PromiseDOM 还没有渲染时就触发了,所以微任务都是在 DOM 渲染前触发。在第二个演示中,宏任务 setTimeout 在文字显示结束后才触发 alert ,所以微任务都是在 DOM 渲染后才进行触发。

(6)为何微任务更早

理解完微任务和宏任务与 DOM 的关系后,我们也大致基本了解了为什么微任务比宏任务更早。接下来我们在从 eventloop 层面来看,为什么微任务会比宏任务更早,为什么会在 DOM 渲染前就开始触发呢?

先用一张图来表示。

微任务宏任务

微任务在执行时不会经过 Web APIs ,它会把它放到一个叫做 micro task queue (即宏任务队列)当中。且微任务是ES6` 语法规定的,宏任务是由浏览器规定的,所以它会比宏任务更早。

到这里,我们讲完了 event loop 以及与其相关的宏任务和微任务,下面我们再用一张图来总结实际运用的执行顺序。

微任务宏任务

从上图中可以得出结论:

第一步,程序先程序 Call Stack 里面的内容,待 Call Stack 清空时,执行当前的微任务;

第二步,程序找到微任务队列的任务,执行微任务;

第三步,待微任务执行完毕后,尝试执行 DOM 渲染;

第四步DOM 渲染结束后,触发 event loop ,执行宏任务。

五、结束语

队列在前端中的应用可以算是很非常频繁了。基本上我们写的异步函数在执行过程中,都会涉及到事件循环问题。且在前端的面试当中,经常会被问到 event loop 、事件循环或者事件轮询是什么,很多面试者就很容易在这块内容吃亏。相信通过上文的学习,大家都对 eventloop 、微任务和宏任务有了一个更深的认识。

队列在前端中的应用就讲到这里啦!

- + \ No newline at end of file diff --git a/column/Algorithm/003_LinkedList.html b/column/Algorithm/003_LinkedList.html index e7433c3a..8af70738 100644 --- a/column/Algorithm/003_LinkedList.html +++ b/column/Algorithm/003_LinkedList.html @@ -197,7 +197,7 @@ console.log(F.a); //value a console.log(F.b); //value b

知识点:如果在 A 对象上没有找到 x 属性,那么会沿着原型链找 x 属性。

解法:明确 fooF 变量的原型链,沿着原型链找 A 属性和 B 属性。

解析:从上面一段代码中可以看到, foo 是一个对象,那么它的 __proto__ 属性指向 Object.prototype ,所以此时 foo.a 会往它的原型链上面找具体的值,也就是 Object.prototype.a 的值。同理, foo.b 会往它的原型链找值,但是找不到 Object.prototype.b 的值,所以最终返回 undefinedF.aF.b 也是同样的道理,大家可以进行一一验证。

四、写在最后

原型和原型链在前端中是再基础不过的知识了!我们平常所写的每一个对象中,基本上都有它的原型和原型链。因此,对于前端来说,如果原型和原型链的关系都不明白的话,不知不觉中很容易写出各种各样的 bug,这对于后续维护和程序来说都是一个巨大的灾难。所以,了解原型和原型链,对于前端来说是一项必备的技能。

链表在前端中的应用就讲到这里啦!

- + \ No newline at end of file diff --git a/column/Algorithm/004_Dictionary.html b/column/Algorithm/004_Dictionary.html index c1dab3fb..f5b53151 100644 --- a/column/Algorithm/004_Dictionary.html +++ b/column/Algorithm/004_Dictionary.html @@ -509,7 +509,7 @@ }; console.log(minWindow('ASDFFGFGCX', 'AFG')); // ASDFFG

三、📆 结束语

字典和集合可以算是前端面试的必考题了,同时在日常开发中的使用频率也相对较高,因此掌握字典和集合的内容是较为重要的。

关于字典和集合在前端中的应用就讲到这里啦!希望对大家有帮助!

不期而遇,我们下期见!🥂🥂🥂

- + \ No newline at end of file diff --git a/column/Algorithm/005_Tree.html b/column/Algorithm/005_Tree.html index b103260a..73a09871 100644 --- a/column/Algorithm/005_Tree.html +++ b/column/Algorithm/005_Tree.html @@ -1141,7 +1141,7 @@ [ 1, 2 ] [ 'd' ] 1 [ 'd', '0' ] 2 [ 'd', '1' ]

大家看上面的打印结果可以发现,通过深度优先遍历的方式,数据都被一一遍历出来。因此,对于树这种数据结构来说,在前端当中出现的频率也是较高的~~

🏡 六、结束语

通过上文的学习,我们了解了树的两种遍历:深度优先遍历和广度优先遍历。同时,还有一种特殊的树,二叉树。二叉树在面试中,基本上是一大必考点。对于二叉树来说,要了解它的三种遍历方式:先序、中序和后序遍历,并且要掌握好这三者之间的区别以及常见的应用场景。

关于树在前端中的应用讲到这里就结束啦!希望对大家有帮助~

🐣 彩蛋 One More Thing

(:往期推荐

栈 👉栈在前端中的应用,顺便再了解下深拷贝和浅拷贝!

队列 👉详解队列在前端的应用,深剖 JS 中的事件循环 Eventloop,再了解微任务和宏任务

链表 👉详解链表在前端的应用,顺便再弄懂原型和原型链!

字典和集合 👉ES6 的 Set 和 Map 你都知道吗?一文了解集合和字典在前端中的应用

动态规则和分而治之算法 👉一文了解分而治之和动态规则算法在前端中的应用

贪心算法和回溯算法 👉一文了解贪心算法和回溯算法在前端中的应用

(:番外篇

- + \ No newline at end of file diff --git a/column/Algorithm/006_Graph.html b/column/Algorithm/006_Graph.html index 2ff44a15..6f99f181 100644 --- a/column/Algorithm/006_Graph.html +++ b/column/Algorithm/006_Graph.html @@ -579,7 +579,7 @@ } return false; };

🎸 五、结束语

通过上文的学习,我们了解到了图的两种表示法:邻接矩阵表示法邻接表表示法。同时,还学习了图的两种常用操作:图的深度优先遍历图的广度优先遍历。最后,我们引用了几道 leetcode 算法题,来解决了图的一些常用场景。

个人认为,图相对于其他数据结构来说,学习难度更大一点,但又是一个不得不学的基本知识,所以还是得多加练习。

除此之外呢,对于以上算法题,学有余力之余,可以考虑多调试一步步跟着调试走,慢慢的就理解的更透彻了。

关于图在前端中的应用讲到这里就结束啦!希望对大家有帮助~

🐣 彩蛋时间 Painted Eggshell

往期推荐

栈 👉栈在前端中的应用,顺便再了解下深拷贝和浅拷贝!

队列 👉详解队列在前端的应用,深剖 JS 中的事件循环 Eventloop,再了解微任务和宏任务

链表 👉详解链表在前端的应用,顺便再弄懂原型和原型链!

字典和集合 👉ES6 的 Set 和 Map 你都知道吗?一文了解集合和字典在前端中的应用

树 👉一文了解树在前端中的应用,掌握数据结构中树的生命线

动态规则和分而治之算法 👉一文了解分而治之和动态规则算法在前端中的应用

贪心算法和回溯算法 👉一文了解贪心算法和回溯算法在前端中的应用

番外篇

- + \ No newline at end of file diff --git a/column/Algorithm/007_Heap.html b/column/Algorithm/007_Heap.html index 456fd957..c96ee392 100644 --- a/column/Algorithm/007_Heap.html +++ b/column/Algorithm/007_Heap.html @@ -1177,7 +1177,7 @@ } return res.next; };

🐪 六、结束语

学完这个数据结构的时候,想到上回看面经时有一道算法题。那道题目问到说,假设现在有一个文件,里面有很多个单词,请找出前 10 个出现频率最高的词汇。

当时我的心里想的是:遍历?但其实今天学完这个数据结构以后,回想起来,这道题的做法就是用最小堆来实现。

所以,堆在日常的应用中都是相通的,只要明白了其中的思想,间接地,也将可以应用到对应的各种场景当中。

到这里,关于堆在前端中的应用的讲解就结束啦!希望对大家有帮助~

如文章有误或有不理解的地方,欢迎小伙伴们评论区留言撒 💬

🐣 彩蛋 One More Thing

(:往期推荐

栈 👉栈在前端中的应用,顺便再了解下深拷贝和浅拷贝!

队列 👉详解队列在前端的应用,深剖 JS 中的事件循环 Eventloop,再了解微任务和宏任务

链表 👉详解链表在前端的应用,顺便再弄懂原型和原型链!

字典和集合 👉ES6 的 Set 和 Map 你都知道吗?一文了解集合和字典在前端中的应用

树 👉一文了解树在前端中的应用,掌握数据结构中树的生命线

图 👉太平洋大西洋水流问题如何解决?一文了解图在前端中的应用

动态规则和分而治之算法 👉一文了解分而治之和动态规则算法在前端中的应用

贪心算法和回溯算法 👉一文了解贪心算法和回溯算法在前端中的应用

(:番外篇

- + \ No newline at end of file diff --git a/column/Algorithm/008_Dynamics.html b/column/Algorithm/008_Dynamics.html index 3c162582..172b0d43 100644 --- a/column/Algorithm/008_Dynamics.html +++ b/column/Algorithm/008_Dynamics.html @@ -415,7 +415,7 @@ } return f[m - 1][n - 1]; };

五、结束语

分而治之和动态规则算法在前端中的应用还是挺多的,特别是在面试或笔试的时候会经常出现这类题目,大家可以在此之外再继续多刷刷此类 leetcode 的题,做多了慢慢就能举一反三了~

- + \ No newline at end of file diff --git a/column/Algorithm/009_Greedy.html b/column/Algorithm/009_Greedy.html index f7455085..5508e1fb 100644 --- a/column/Algorithm/009_Greedy.html +++ b/column/Algorithm/009_Greedy.html @@ -221,7 +221,7 @@ }; console.log(subsets([1, 2, 3]));

五、写在最后

贪心算法和回溯算法在前端的面试和笔试中也是非常经典的常考题。贪心算法相较于其他算法来说比较简单,而回溯算法涉及到很多溯回问题,逻辑较强,建议大家在做题目时如果看不懂的情况下可以选择多调试代码,一步一步跟着它的思路,多调试几遍,慢慢就能深入理解其逻辑了。

贪心算法和回溯算法在前端中的应用就讲到这里啦!

- + \ No newline at end of file diff --git a/column/Algorithm/010_Search.html b/column/Algorithm/010_Search.html index bdc84926..072c273e 100644 --- a/column/Algorithm/010_Search.html +++ b/column/Algorithm/010_Search.html @@ -485,7 +485,7 @@ } } };

🕙 六、结束语

算法在前端中的应用还是蛮广泛的,比如 js 中的 sort()indexOf() 是基于排序和搜索算法来实现的。同时,算法在也是前端面试中的一大必考点,对于不会算法的开发者来说,无形之中与别人的核心竞争力就会被削减了一大半。

本文主要讲解了一些常见的排序和搜索的基础实现,后续大家还可以继续深挖一些其他场景,举一反三,慢慢的理解就会越来越深入了~

到这里,排序和搜索算法的讲解就结束啦!希望对大家有帮助~

🐣 彩蛋 One More Thing

🏷️ 往期推荐

栈 👉栈在前端中的应用,顺便再了解下深拷贝和浅拷贝!

队列 👉详解队列在前端的应用,深剖 JS 中的事件循环 Eventloop,再了解微任务和宏任务

链表 👉详解链表在前端的应用,顺便再弄懂原型和原型链!

字典和集合 👉ES6 的 Set 和 Map 你都知道吗?一文了解集合和字典在前端中的应用

树 👉一文了解树在前端中的应用,掌握数据结构中树的生命线

图 👉太平洋大西洋水流问题如何解决?一文了解图在前端中的应用

堆 👉最小堆最大堆了解吗?一文了解堆在前端中的应用

动态规则和分而治之算法 👉一文了解分而治之和动态规则算法在前端中的应用

贪心算法和回溯算法 👉一文了解贪心算法和回溯算法在前端中的应用

🏷️ 网站推荐

文章重的可视化动图用到的是 visualgo 网站进行录屏,该网站几乎涵盖了所有数据结构和算法的实现,包括但不限于排序、位掩码、哈希表、二叉堆和循环查找等等动图的功能。戳此链接可直接进入网站体验可视化~

网站推荐

🏷️ 番外篇

- + \ No newline at end of file diff --git a/column/Algorithm/index.html b/column/Algorithm/index.html index 42a4fb93..c9313981 100644 --- a/column/Algorithm/index.html +++ b/column/Algorithm/index.html @@ -19,7 +19,7 @@
Skip to content

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BackEnd/Node/001_deploy.html b/column/BackEnd/Node/001_deploy.html index 8550d717..e94d6cd9 100644 --- a/column/BackEnd/Node/001_deploy.html +++ b/column/BackEnd/Node/001_deploy.html @@ -23,7 +23,7 @@ tar -xvf node-v14.15.4-linux-x64.tar

解压后,将 node 文件夹下的所有内容复制到/usr/local/node,配置环境变量。这里路径/usr/local/node 下的 node 文件需要新建,用mkdir -p 路径名可以直接建立路径下的文件夹。

配置环境变量。linux 的环境变量文件是/etc/profile,可执行文件在/usr/local/node/bin 里,所以要把这个路径加入到这个环境变量文件中。

bash
vi /etc/profile
vi /etc/profile

输入命令后进入界面,再输入 i 进入编辑模式,PageDown 到最后一行,不换行,添加环境变量。

bash
: /usr/local/node/bin
: /usr/local/node/bin

保存退出。

bash
ESC
 Shift zz
ESC
 Shift zz

⑦ 保存退出后执行如下命令,将环境变量生效。

bash
source /etc/profile
source /etc/profile

装完之后node -v查看版本号是否一一对应。

7、部署项目到服务器上

安装完 node 环境,接下来需要把我们的项目部署到服务器上。(这里介绍从 git 上拉项目到服务器上) ① 先到 /home 下面创建一个属于你自己用户名的文件夹,比如名字为 monday ,那么就会有 /home/monday ,之后把自己的项目文件克隆到 monday 文件下,为 /home/monday/project-name 。 ② 进入自己用户名的文件夹,git clone 你的项目地址,之后 npm i 。 ③ 上传 nodejs 项目后,配置数据库。

8、安装 pm2 并启动 nodejs 项目

使用 npm 全局安装 pm2:npm install pm2 -g进入 nodejs 项目目录,我把项目上传到了 /home/monday/project-name ,所以,输入cd /home/monday/project-name 的项目目录回车,进入项目目录启动 nodejs 项目,看个人对自己项目的设计来决定启动方式,我的是npm run prd检查 nodejs 项目是否启动:输入 pm2 list 回车,如果出现下面的列表,就说明 nodejs 项目已经顺利在后台建立了服务。 至此,我们就把服务启动起来啦!

三、快捷指令

1、linux 的常用命令

2、pm2 的常用命令

- + \ No newline at end of file diff --git a/column/BackEnd/Node/002_fullStack.html b/column/BackEnd/Node/002_fullStack.html index b289de6d..a95440c7 100644 --- a/column/BackEnd/Node/002_fullStack.html +++ b/column/BackEnd/Node/002_fullStack.html @@ -19,7 +19,7 @@
Skip to content

《从前端到全栈》小册钻研

第一部分:实现一个文章生成器

这部分主要基于一个开源库做了一些改进,让生成的文章语句更加通顺一些。嗯,虽然还是狗屁不通。🤡👀

具体代码仓库:https://github.com/mondaylab/bullshit-generator-js-mondaylab

第二部分:前后端打通todolist功能

基础:

  • 利用nodetcphttp等模块,进一步深入理解和实践强缓存、协商缓存和文件压缩在实际场景中的应用。

实现todolist功能:

  • 拦截切面为引导,实现能够注册多个拦截切面的函数,同时,将这些拦截切面包装成一个异步的洋葱模型的拦截器框架。
  • 有了拦截切面后,还实现了动态路由,让用户能够通过 / 的方式,直接访问到页面或者接口数据。
  • 与此同时,使用sqlite作为连接的数据库,用来存储用户登录信息session信息todolist信息
  • 目前已实现接口:获取列表(/list)、增加todo信息(/add)、修改todo信息(/update)、登录功能(/login) 。

优化环节:

  • 使用node.js的内置模块Cluster实现多进程的HTTP服务器;
  • 利用多进程的特点,实现实时热更新服务器的功能。

具体代码仓库:

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BackEnd/Node/003_graffitiBoard.html b/column/BackEnd/Node/003_graffitiBoard.html index 72e6b018..36d3ef87 100644 --- a/column/BackEnd/Node/003_graffitiBoard.html +++ b/column/BackEnd/Node/003_graffitiBoard.html @@ -113,7 +113,7 @@ with: coverageCommand: npm run test:coverage debug: true

2、品质管理

帮助我们管理代码质量的工具:SonarCodeCode Climate等。这些工具可以帮助我们分析代码的质量,包括代码的复杂度、测试覆盖率、代码的重复率等。我们可以根据这些指标来判断代码的质量,从而决定是否需要对代码进行重构。

代码测试覆盖率默认并不能在 Code Climate 中给出,因为 Code Climate 不会自动分析测试代码,而是从 GitHub Actions 中获取信息.因此,我们需要将 Code ClimateGitHub Actions 进行集成,这样才能在 Code Climate 中看到测试覆盖率的指标。

- + \ No newline at end of file diff --git a/column/BackEnd/index.html b/column/BackEnd/index.html index 10f17222..92acdc08 100644 --- a/column/BackEnd/index.html +++ b/column/BackEnd/index.html @@ -19,7 +19,7 @@
Skip to content

序言

本分类旨在记录关于服务端开发的知识点以及所遇到的一些坑,各栏目文章如下 👇

文章收录

Node.js

如何将 nodejs 项目程序部署到阿里云服务器上《从前端到全栈》小册钻研

开发环境 Linux

暂无文章,小编正在快马加鞭整理中

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BaseCommand/MacShortcutKey/001_vscode.html b/column/BaseCommand/MacShortcutKey/001_vscode.html index e96b172b..f4c7eb77 100644 --- a/column/BaseCommand/MacShortcutKey/001_vscode.html +++ b/column/BaseCommand/MacShortcutKey/001_vscode.html @@ -19,7 +19,7 @@
Skip to content

这里附上官网最全的 vscode 快捷键指南,详情地址戳:https://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf

下面将整理周一在日常使用到的一些常见快捷键~

通用操作

  • Shift+Command+P, F1 展示命令面板
  • Command+P 快速打开某一个文件
  • Shift+Command+N 创建一个新的窗口
  • Command+W 关闭某一文件或关闭当前窗口
  • Command+, 打开settings界面
  • Command+K+S 键盘快捷键指引

基础编辑

  • Command+K 剪切
  • Command+C 复制
  • Option+↓ / Option+↑ 移动当前行到下行/移动当前行到上行
  • Shift+Option+↓ / Shift+Option+↑ 复制当前行到下行/复制当前行到上行
  • Command+Enter / Shift+Command+Enter 向下插入一行/向上插入一行
  • Shift+Command+\ 跳转到匹配的括号
  • Command+] / Command+[ 向后缩进/向前缩进
  • Home / End 去到当前行的最开头/最结尾
  • Command+↑ / Command+↓ 去到当前文件的最开头/最结尾
  • Control+PgUp / Control+PgDn为单位向上滚动/向下滚动
  • Command+PgUp /Command+PgDn为单位向上滚动/向下滚动
  • Option+Command+[ / Option+Command+] 折叠/展开当前模块代码
  • Command+K+[ / Command+K+] 折叠/展开所有子区域
  • Command+K+0 / Command+K+J 折叠/展开所有区域
  • Command+K+C 添加行注释
  • Command+K+U 移除行注释
  • Command+/ 切换行注释
  • ShiftOption+A 切换块注释
  • Option+Z 如果一行太长了,可以让它自动切换换行

光标和选择

  • Option+click 插入一个新的光标,可以理解为插入同时选中多行中的某个位置
  • Option+Command+↑ 为当前位置的上一行中的同个位置插入光标
  • Option+Command+↓ 为当前位置的下一行中的同个位置插入光标
  • Command+U 撤销上一个光标的操作
  • Shift+Option+I 在已选中行的末尾插入光标
  • Command+L 选中当前行
  • Shift+Command+L 选择当前所选择内容的所有匹配项
  • Command+F2 选择当前单词所选择单词的所有匹配项
  • Control+Shift+Command+ → / ← 扩大/缩小选择的范围
  • Shift+Option+drag mouse 同时拖拽好多个光标
  • Shift+Option+Command+ ↑ / ↓ 向上/下选中每一行中与当前行同一位置的光标
  • Shift+Option+Command+ ← / → 向左/右选择内容
  • Shift+Option+Command+PgUp 当前页面
  • Shift+Option+Command+PgDn 当前位置向上/下一个页面,选中所有光标

搜索和替换

  • Command+F 查找
  • Option+Command+F 查找和替换
  • Command+G / Shift+Command+G 查找下一个内容/查找前一个内容
  • Option+Enter 选中国所有查找后的匹配项
  • Command+D 选中所有下一个要匹配单词的所有项
  • Command+K+D 将最后一个选择移动到下一个要查找的匹配项

富文本编辑

  • Control+Space, Command+I 触发建议(api提示等等)
  • Shift+Command+Space 触发参数提示
  • Shift+Option+F 格式化文档
  • Command+K+F 格式化选择的内容
  • F12 跳转到当前光标背后的逻辑代码处
  • Option+F12 同上,但不跳转,只是在页面中查看
  • Command+K/F12 在侧边打开定义
  • Command+. 快速修复
  • Shift+F12 显示引用内容
  • F2 对所选择内容重命名
  • Command+K+X 删除末尾处的空白
  • Command+K M 改变文件语言(只有在notebook编辑器失焦的情况下生效)

导航相关

  • Command+T 展示所有有当前搜索字符的文件
  • Control+G 去向某一行
  • Command+P 打开某一个文档
  • Shift+Command+O 查找当前文件的关键字
  • Shift+Command+M 展示问题面板
  • F8 / Shift+F8 转到下一个/上一个错误或警告
  • Control+Shift+Tab 顶部导航栏编辑器组的历史记录
  • Control+- / Control+Shift+- 后退/前进(与浏览器类似)
  • Control+Shift+M 切换选项卡来移动焦点

编辑器管理

  • Command+W 关闭编辑器
  • Command+K 关闭文件夹
  • Command+\ 切割编辑器
  • Command+1 / Command+2 / Command+3 把整个编辑器切割成1/2/3组
  • Command+K+← / Command+K+→ 将光标聚焦到当前行的最左边/最右边
  • Command+K Shift+Command+← / Command+K Shift+Command+→ 向左/右移动编辑器
  • Command+K+← / Command+K+→ 向左/右移动正在活动的光标

文档管理

  • Command+N 新建一个文件
  • Command+O 打开某个文件
  • Command+S 保存
  • Shift+Command+S 保存到某一个目录下
  • Option+Command+S 保存所有文件
  • Command+W 关闭当前文件
  • Command+K+W 关闭所有文件
  • Shift+Command+T 重新打开关闭的编辑器
  • Command+K Enter 让预览模式的编辑器保持打开的状态
  • Control+Tab / Control+Shift+Tab 打开当前导航栏的前一个文件/后一个文件
  • Command+K P 复制已激活文件的路径
  • Command+K R 在文件夹中显示当前活动文件
  • Command+K O 在新的窗口展示当前活动的文件(这种类型的都待挖掘如何使用,没怎么验证的出来)

展示相关

  • Control+Command+F 打开/关闭全屏模式
  • Option+Command+0 切换编辑器的布局(水平/垂直)
  • Command+= / Shift+Command+- 放大/缩小窗口
  • Command+B 切换侧边栏的可见性
  • Shift+Command+E 显示资源管理器(系统是切换成中英文)/切换焦点
  • Shift+Command+F 展示搜索框
  • Control+Shift+G 显示源代码管理
  • Shift+Command+D 展示debug的框框
  • Shift+Command+X 展示插件区(下载volar等插件)
  • Shift+Command+H 在文件中替换某一个词
  • Shift+Command+J 切换搜索详情
  • Shift+Command+U 展示输出面板
  • Shift+Command+V 打开markdown预览模式
  • Command+K V 打开markdown预览模式到侧边
  • Command+K Z zen模式

调试相关

  • F9 切换断点
  • F5 开始/继续
  • F11 / Shift+F11 进入/退出
  • F10 跳过
  • Shift+F5 停止
  • Command+K+I 显示悬停状态

集成终端

  • Control+` 展示集成终端
  • Control+Shift+` 创建一个新的终端
  • Command+C 复制已选择的内容
  • Command+↑ / ↓ 往上/下滚动
  • PgUp / PgDn 以页面为单位往上/下滚动
  • Command+Home / End 滚动至顶部/底部

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BaseCommand/MacShortcutKey/002_macos.html b/column/BaseCommand/MacShortcutKey/002_macos.html index 1cca083b..eb67a5c1 100644 --- a/column/BaseCommand/MacShortcutKey/002_macos.html +++ b/column/BaseCommand/MacShortcutKey/002_macos.html @@ -19,7 +19,7 @@
Skip to content

序言

这里附上apple官网所撰写的一些快捷键:https://support.apple.com/zh+cn/HT201236,下面将整理周一在使用过程中比较常见的快捷键。

剪切、拷贝、粘贴和其他常用快捷键

  • Command+X:剪切所选项并拷贝到剪贴板。
  • Command+C:将所选项拷贝到剪贴板。这同样适用于“访达”中的文件。
  • Command+V:将剪贴板的内容粘贴到当前文稿或 App 中。这同样适用于“访达”中的文件。
  • Command+Z:撤销上一个命令。随后您可以按 Shift+Command+Z 来重做,从而反向执行撤销命令。在某些 App 中,您可以撤销和重做多个命令。
  • Command+A:全选各项。
  • Command+F:查找文稿中的项目或打开“查找”窗口。
  • Command+G:再次查找:查找之前所找到项目出现的下一个位置。要查找出现的上一个位置,请按 Shift+Command+G
  • Command+H:隐藏最前面的 App 的窗口。要查看最前面的 App 但隐藏所有其他 App,请按 Option+Command+H
  • Command+M:将最前面的窗口最小化至“程序坞”。要最小化最前面的 App 的所有窗口,请按 Option+Command+M
  • Command+O:打开所选项,或打开一个对话框以选择要打开的文件。
  • Command+P:打印当前文稿。
  • Command+S:存储当前文稿。
  • Command+T:打开新标签页。
  • Command+W:关闭最前面的窗口。要关闭 App 的所有窗口,请按下 Option+Command+W
  • Option+Command+Esc强制退出 App
  • Command+空格键:显示或隐藏“聚焦”搜索栏。要从“访达”窗口执行“聚焦”搜索,请按 Command+Option+空格键。(如果您使用多个输入源以便用不同的语言键入内容,这些快捷键会更改输入源而非显示“聚焦”。了解如何更改冲突的键盘快捷键。)
  • Control+Command+空格键:显示字符检视器,您可以从中选择表情符号和其他符号
  • Control+Command+F:全屏使用 App(如果 App 支持)。
  • 空格键:使用“快速查看”来预览所选项。
  • Command+Tab:在打开的 App 中切换到下一个最近使用的 App
  • Shift+Command+5:在 macOS Mojave 或更高版本中,拍摄截屏或录制屏幕。也可以使用 Shift+Command+3Shift+Command+4 来拍摄截屏。进一步了解截屏
  • Shift+Command+N:在“访达”中创建一个新文件夹。
  • Command+,:打开最前面的 App 的偏好设置。

睡眠、退出登录和关机快捷键

在这些快捷键中,您可能需要按住其中一些快捷键稍长时间。这样有助于避免无意中启用快捷键。

  • 电源按钮:按下可将 Mac 开机或将 Mac 从睡眠状态唤醒。按住这个按钮 1.5 秒可使 Mac 进入睡眠状态*。继续按住则会强制 Mac 关机。
  • Option+Command+电源按钮*Option+Command+Media Eject(Option+Command+介质推出键)🔼:将您的 Mac 置于睡眠状态。
  • Control+Shift+电源按钮*Control+Shift+Media Eject(Control+Shift+介质推出键)🔼:将显示器置于睡眠状态。
  • Control+电源按钮*Control+介质推出键🔼:显示一个对话框,询问您是要重新启动、睡眠还是关机。
  • Control+Command+电源按钮*:强制 Mac 重新启动,系统不会提示是否要存储任何打开且未存储的文稿。
  • Control+Command+Media Eject(Control+Command+介质推出键)🔼:退出所有 App,然后重新启动您的 Mac。如果任何打开的文稿有未存储的更改,系统会询问您是否要存储这些更改。
  • Control+Option+Command+电源按钮*Control+Option+Command+介质推出键🔼:退出所有 App,然后将您的 Mac 关机。如果任何打开的文稿有未存储的更改,系统会询问您是否要存储这些更改。
  • Control+Command+Q:立即锁定屏幕。
  • Shift+Command+Q:退出登录您的 macOS 用户帐户。系统将提示您确认。要在不确认的情况下立即退出登录,请按下 Option+Shift+Command+Q

访达和系统快捷键

  • Command+D:复制所选文件。
  • Command+E:推出所选磁盘或宗卷。
  • Command+F:在“访达”窗口中开始“聚焦”搜索。
  • Command+I:显示所选文件的“显示简介”窗口。
  • Command+R:(1) 如果在“访达”中选择了某个别名:显示所选别名对应的原始文件。(2) 在某些 App(如“日历”或 Safari 浏览器)中,刷新或重新载入页面。(3) 在“软件更新”偏好设置中,再次检查有没有软件更新。
  • Shift+Command+C:打开“电脑”窗口。
  • Shift+Command+D:打开“桌面”文件夹。
  • Shift+Command+F:打开“最近使用”窗口,其中显示了您最近查看或更改过的所有文件。
  • Shift+Command+G:打开“前往文件夹”窗口。
  • Shift+Command+H:打开当前 macOS 用户帐户的个人文件夹。
  • Shift+Command+I:打开 iCloud 云盘。
  • Shift+Command+K:打开“网络”窗口。
  • Option+Command+L:打开“下载”文件夹。
  • Shift+Command+N:新建文件夹。
  • Shift+Command+O:打开“文稿”文件夹。
  • Shift+Command+P:在“访达”窗口中显示或隐藏预览面板。
  • Shift+Command+R:打开“隔空投送”窗口。
  • Shift+Command+T:显示或隐藏“访达”窗口中的标签页栏。
  • Ctrl+Shift+Command+T:将所选的“访达”项目添加到“程序坞”(OS X Mavericks 或更高版本)
  • Shift+Command+U:打开“实用工具”文件夹。
  • Option+Command+D:显示或隐藏“程序坞”。
  • Control+Command+T:将所选项添加到边栏(OS X Mavericks 或更高版本)。
  • Option+Command+P:隐藏或显示“访达”窗口中的路径栏。
  • Option+Command+S:隐藏或显示“访达”窗口中的边栏。
  • Command+斜线 (/):隐藏或显示“访达”窗口中的状态栏。
  • Command+J:显示“显示”选项。
  • Command+K:打开“连接服务器”窗口。
  • Control+Command+A:为所选项制作替身。
  • Command+N:打开一个新的“访达”窗口。
  • Option+Command+N:新建智能文件夹。
  • Command+T:在当前“访达”窗口中有单个标签页开着的状态下显示或隐藏标签页栏。
  • Option+Command+T:在当前“访达”窗口中有单个标签页开着的状态下显示或隐藏工具栏。
  • Option+Command+V:将剪贴板中的文件从原始位置移动到当前位置。
  • Command+Y:使用“快速查看”预览所选文件。
  • Option+Command+Y:显示所选文件的快速查看幻灯片显示。
  • Command+1:以图标方式显示“访达”窗口中的项目。
  • Command+2:以列表方式显示“访达”窗口中的项目。
  • Command+3:以分栏方式显示“访达”窗口中的项目。
  • Command+4:以画廊方式显示“访达”窗口中的项目。
  • Command+左中括号 ([):前往上一文件夹。
  • Command+右中括号 (]):前往下一个文件夹。
  • Command+上箭头:打开包含当前文件夹的文件夹。
  • Command+Control+上箭头:在新窗口中打开包含当前文件夹的文件夹。
  • Command+下箭头:打开所选项。
  • 右箭头:打开所选文件夹。这个快捷键仅在列表视图中有效。
  • 左箭头:关闭所选文件夹。这个快捷键仅在列表视图中有效。
  • Command+Delete:将所选项移到废纸篓。
  • Shift+Command+Delete:清倒废纸篓。
  • Option+Shift+Command+Delete:清倒废纸篓而不显示确认对话框。
  • Command+调低亮度:当 Mac 连接到多台显示器时,打开或关闭视频镜像功能。
  • Option+调高亮度:打开“显示器”偏好设置。这个快捷键可与任一亮度键搭配使用。
  • Control+调高亮度或 Control+调低亮度:更改外部显示器的亮度(如果显示器支持)。
  • Option+Shift+调高亮度或 Option+Shift+调低亮度:以较小的步幅调节显示器亮度。如果您的显示器支持,可以将 Control 键添加到此快捷键,以便在外置显示器上进行调节。
  • Option+“调度中心”:打开“调度中心”偏好设置。
  • Command+“调度中心”:显示桌面。
  • Control+下箭头:显示最前面的 App 的所有窗口。
  • Option+调高音量:打开“声音”偏好设置。这个快捷键可与任一音量键搭配使用。
  • Option+Shift+调高音量或 Option+Shift+调低音量:以较小的步幅调节音量。
  • Option+键盘调高亮度:打开“键盘”偏好设置。这个快捷键可与任一键盘亮度键搭配使用。
  • Option+Shift+键盘调高亮度或 Option+Shift+键盘调低亮度:以较小的步幅调节键盘亮度。
  • 连按 Option 键:在单独的窗口中打开项目,然后关闭原始窗口。
  • 连按 Command 键:在单独的标签页或窗口中打开文件夹。
  • 按住 Command 键拖移到另一个宗卷:将拖移的项目移到另一个宗卷,而不是拷贝它。
  • 按住 Option 键拖移:拷贝托移的项目。拖移项目时指针会随之变化。
  • 拖移时按住 Option+Command:为拖移的项目制作替身。拖移项目时指针会随之变化。
  • 按住 Option 键点按开合三角:打开所选文件夹内的所有文件夹。这个快捷键仅在列表视图中有效。
  • 按住 Command 键点按窗口标题:查看包含当前文件夹的文件夹。
  • 了解如何使用 Command 或 Shift 在“访达”中选择多个项目
  • 点按“访达”菜单栏中的“前往”菜单查看用于打开许多常用文件夹(如“应用程序”、“文稿”、“下载”、“实用工具”和“iCloud 云盘”)的快捷键。

文稿快捷键

这些快捷键的行为可能因您使用的 App 而异。

  • Command+B:以粗体显示所选文本,或者打开或关闭粗体显示功能。
  • Command+I:以斜体显示所选文本,或者打开或关闭斜体显示功能。
  • Command+K:添加网页链接。
  • Command+U:对所选文本加下划线,或者打开或关闭加下划线功能。
  • Command+T:显示或隐藏“字体”窗口。
  • Command+D:从“打开”对话框或“存储”对话框内选择“桌面”文件夹。
  • Control+Command+D:显示或隐藏所选字词的定义。
  • Shift+Command+冒号 (:):显示“拼写和语法”窗口。
  • Command+分号 (;):查找文稿中拼写错误的字词。
  • Option+Delete:删除插入点左边的字词。
  • Control+H:删除插入点左边的字符。也可以使用 Delete 键。
  • Control+D:删除插入点右边的字符。也可以使用 Fn+Delete。
  • Fn+Delete:在没有向前删除 键的键盘上向前删除。也可以使用 Control+D。
  • Control+K:删除插入点与行或段落末尾处之间的文本。
  • Fn+上箭头:Page Up:向上滚动一页。
  • Fn+下箭头:Page Down:向下滚动一页。
  • Fn+左箭头:Home:滚动到文稿开头。
  • Fn+右箭头:End:滚动到文稿末尾。
  • Command+上箭头:将插入点移至文稿开头。
  • Command+下箭头:将插入点移至文稿末尾。
  • Command+左箭头:将插入点移至当前行的行首。
  • Command+右箭头:将插入点移至当前行的行尾。
  • Option+左箭头:将插入点移至上一字词的词首。
  • Option+右箭头:将插入点移至下一字词的词尾。
  • Shift+Command+上箭头:选中插入点与文稿开头之间的文本。
  • Shift+Command+下箭头:选中插入点与文稿末尾之间的文本。
  • Shift+Command+左箭头:选中插入点与当前行行首之间的文本。
  • Shift+Command+右箭头:选中插入点与当前行行尾之间的文本。
  • Shift+上箭头:将文本选择范围扩展到上一行相同水平位置的最近字符处。
  • Shift+下箭头:将文本选择范围扩展到下一行相同水平位置的最近字符处。
  • Shift+左箭头:将文本选择范围向左扩展一个字符。
  • Shift+右箭头:将文本选择范围向右扩展一个字符。
  • Option+Shift+上箭头:将文本选择范围扩展到当前段落的段首,再按一次则扩展到下一段落的段首。
  • Option+Shift+下箭头:将文本选择范围扩展到当前段落的段尾,再按一次则扩展到下一段落的段尾。
  • Option+Shift+左箭头:将文本选择范围扩展到当前字词的词首,再按一次则扩展到后一字词的词首。
  • Option+Shift+右箭头:将文本选择范围扩展到当前字词的词尾,再按一次则扩展到后一字词的词尾。
  • Control+A:移至行或段落的开头。
  • Control+E:移至行或段落的末尾。
  • Control+F:向前移动一个字符。
  • Control+B:向后移动一个字符。
  • Control+L:将光标或所选内容置于可见区域中央。
  • Control+P:上移一行。
  • Control+N:下移一行。
  • Control+O:在插入点后新插入一行。
  • Control+T:将插入点后面的字符与插入点前面的字符交换。
  • Command+左花括号 ({):左对齐。
  • Command+右花括号 (}):右对齐。
  • Shift+Command+竖线 (|):居中对齐。
  • Option+Command+F:前往搜索栏。
  • Option+Command+T:显示或隐藏 App 中的工具栏。
  • Option+Command+C:拷贝样式:将所选项的格式设置拷贝到剪贴板。
  • Option+Command+V:粘贴样式:将拷贝的样式应用到所选项。
  • Option+Shift+Command+V:粘贴并匹配样式:将周围内容的样式应用到粘贴在该内容中的项目。
  • Option+Command+I:显示或隐藏检查器窗口。
  • Shift+Command+P:页面设置:显示用于选择文稿设置的窗口。
  • Shift+Command+S:显示“存储为”对话框或复制当前文稿。
  • Shift+Command+减号 (+):缩小所选项。
  • Shift+Command+加号 (+):放大所选项。Command+等号 (=) 可实现相同的功能。
  • Shift+Command+问号 (?):打开“帮助”菜单。

img

其他快捷键

如需了解更多快捷键,请查看 App 菜单中显示的快捷键缩写。每个 App 都有自己的快捷键,在一个 App 中可用的快捷键可能在另一个 App 中不可用。

进一步了解

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BaseCommand/MacShortcutKey/003_console.html b/column/BaseCommand/MacShortcutKey/003_console.html index cd81c641..c091f461 100644 --- a/column/BaseCommand/MacShortcutKey/003_console.html +++ b/column/BaseCommand/MacShortcutKey/003_console.html @@ -19,7 +19,7 @@
Skip to content

🎯背景

对于开发者来说,最熟悉的调试工具之一莫过于 googleconsole 控制台。那为什么周一会想到要来整理 console 的快捷键呢,原因在于,最近在开发中,有较大的控制台使用频率。用着用着发现,每回想要点按光标或者hover等功能时候,都得鼠标移进移出的,这其实有一点影响开发效率。于是带着这个困扰,周一踏上了整理 console 快捷键的征程。下面将整理console相关一些比较常用的快捷键。

关于 console 快捷键相关网站:https://developer.chrome.com/docs/devtools/shortcuts/?utm_source=devtools。以下所有快捷键将在**控制台面板**中执行才有效哦~

⌨️通用快捷键

打开调试工具

功能Mac OSWindows / Linux
打开最后一次使用过的面板Command+Option+IF12 or Control+Shift+I
打开Console面板Command+Option+JControl+Shift+J
打开Elements面板Command+Shift+C or Command+Option+CControl+Shift+C

全局快捷键

功能Mac OSWindows / Linux
展示控制台中的 settings 设置面板,可以按Esc退出F1 or Function+F1F1
切换到下一个面板Command+]Control+]
切换到上一个面板Command+[Control+[
切换到上一个曾经使用过的面板位置Command+Shift+DControl+Shift+D
切换设备的模式(手机/网页模式)Command+Shift+MControl+Shift+M
切换到检查元素的模式(光标模式)Command+Shift+CControl+Shift+C
打开 Command 菜单Command+Shift+PControl+Shift+P
拉出 抽屉EscapeEscape
普通刷新Command+RF5 or Control+R
强制刷新Command+Shift+RControl+F5 or Control+Shift+R
搜索当前面板的文本(仅支持Elements、Console、Sources、Performance、Memory、JavaScript Profiler和Quick Source)Command+FControl+F
打开抽屉里面的搜索(这里可以搜索所有已加载的资源)Command+Option+FControl+Shift+F
打开Souces面板里面的某一个文档Command+O or Command+PControl+O or Control+P
放大面板Command+Shift++Control+Shift++
缩小面板Command+-Control+-
恢复初始化面板的大小Command+0

⌨️各面板快捷键

Element面板

ActionMacWindows / Linux
撤销Command+ZControl+Z
重做Command+Shift+ZControl+Y
选择已选择元素的上一行/下一行向上↑ / 下↓箭头向上↑ / 下↓箭头
展开当前已选择元素的节点(如果当前节点已经被展开,那么这个快捷键将会去选择在这个节点下面的元素)向右箭头→向右箭头→
折叠当前已选择元素的节点(如果当前节点已经被折叠,那么这个快捷键将会去选择在这个节点上面的那个元素)向左箭头←向左箭头←
展开/折叠当前已选择节点,和展开/折叠已选择节点的所有子节点按住option并且点击左/右箭头按住Control+Alt并且点击左/右箭头
将当前已选择元素切换为属性可编辑的模式EnterEnter
选择下一个/上一个可编辑的属性Tab / Shift+TabTab / Shift+Tab
隐藏当前已选择的元素HH
将当前已选择选择切换成 Edit as HTML 的模式Function+F2F2

Style面板

ActionMacWindows / Linux
Go to the line where a property value is declaredHold Command then click the property valueHold Control then click the property value
Cycle through the RBGA, HSLA, and Hex representations of a color valueHold Shift then click the Color Preview box next to the valueHold Shift then click the Color Preview box next to the value
Select the next / previous property or valueClick a property name or value then press Tab / Shift+TabClick a property name or value then press Tab / Shift+Tab
Increment / decrement a property value by 0.1Click a value then press Option+Up Arrow / Option+Down ArrowClick a value then press Alt+Up Arrow / Alt+Down Arrow
Increment / decrement a property value by 1Click a value then press Up Arrow / Down ArrowClick a value then press Up Arrow / Down Arrow
Increment / decrement a property value by 10Click a value then press Shift+Up Arrow / Shift+Down ArrowClick a value then press Shift+Up Arrow / Shift+Down Arrow
Increment / decrement a property value by 100Click a value then press Command+Up Arrow / Command+Down ArrowClick a value then press Control+Up Arrow / Control+Down Arrow
Cycle through the degrees (deg), gradians (grad), radians (rad) and turns (turn) representations of an angle valueHold Shift then click the Angle Preview box next to the valueHold Shift then click the Angle Preview box next to the value
Increment / decrement an angle value by 1Click the Angle Preview box next to the value then press Up Arrow / Down ArrowClick the Angle Preview box next to the value then press Up Arrow / Down Arrow
Increment / decrement an angle value by 10Click the Angle Preview box next to the value then press Shift+Up Arrow / Shift+Down ArrowClick the Angle Preview box next to the value then press Shift+Up Arrow / Shift+Down Arrow
Increment / decrement an angle value by 15Click the Angle Preview box next to the value then press Shift, click / mouse slide on the Angle Clock OverlayClick the Angle Preview box next to the value then press Shift, click / mouse slide on the Angle Clock Overlay

Souces面板

ActionMacWindows / Linux
Pause script execution (if currently running) or resume (if currently paused)F8 or Command+\F8 or Control+\
Step over next function callF10 or Command+'F10 or Control+'
Step into next function callF11 or Command+;F11 or Control+;
Step out of current functionShift+F11 or Command+Shift+;Shift+F11 or Control+Shift+;
Continue to a certain line of code while pausedHold Command and then click the line of codeHold Control and then click the line of code
Select the call frame below / above the currently-selected frameControl+. / Control+,Control+. / Control+,
Save changes to local modificationsCommand+SControl+S
Save all changesCommand+Option+SControl+Alt+S
Go to lineControl+GControl+G
Jump to a line number of the currently-open filePress Command+O to open the Command Menu, type : followed by the line number, then press EnterPress Control+O to open the Command Menu, type : followed the line number, then press Enter
Jump to a column of the currently-open file (for example line 5, column 9)Press Command+O to open the Command Menu, type :, then the line number, then another :, then the column number, then press EnterPress Control+O to open the Command Menu, type :, then the line number, then another :, then the column number, then press Enter
Go to a function declaration (if currently-open file is HTML or a script), or a rule set (if currently-open file is a stylesheet)Press Command+Shift+O, then type in the name of the declaration / rule set, or select it from the list of optionsPress Control+Shift+O, then type in the name of the declaration / rule set, or select it from the list of options
Close the active tabOption+WAlt+W
Toggle the Navigation sidebar on the leftCommand+Shift+YControl+Shift+Y
Toggle the Debugger sidebar on the rightCommand+Shift+HControl+Shift+H

代码编辑器

ActionMacWindows / Linux
Delete all characters in the last word, up to the cursorOption+DeleteControl+Delete
Add or remove a line-of-code breakpointFocus your cursor on the line and then press Command+BFocus your cursor on the line and then press Control+B
Go to matching bracketControl+MControl+M
Toggle single-line comment. If multiple lines are selected, DevTools adds a comment to the start of each lineCommand+/Control+/
Select / de-select the next occurrence of whatever word the cursor is on. Each occurrence is highlighted simultaneouslyCommand+D / Command+UControl+D / Control+U

Network面板

ActionMacWindows / Linux
Start / stop recordingCommand+EControl+E
Record a reloadCommand+RControl+R
Replay a selected XHR requestRR
Hide the details of a selected requestEscapeEscape

Performance面板

ActionMacWindows / Linux
Start / stop recordingCommand+EControl+E
Save recordingCommand+SControl+S
Load recordingCommand+OControl+O

Memory面板

ActionMacWindows / Linux
Start / stop recordingCommand+EControl+E

Console面板

ActionMacWindows / Linux
Accept autocomplete suggestionRight Arrow or TabRight Arrow or Tab
Reject autocomplete suggestionEscapeEscape
Get previous statementUp ArrowUp Arrow
Get next statementDown ArrowDown Arrow
Focus the ConsoleControl+`Control+`
Clear the ConsoleCommand+K or Option+LControl+L
Force a multi-line entry. Note that DevTools should detect multi-line scenarios by default, so this shortcut is now usually unnecessaryShift+ReturnShift+Enter
ExecuteReturnEnter
Expand all sub-properties of an object that's been logged to the ConsoleHold Alt then click ExpandimgHold Alt then click Expand

Search Tab

Search Tab,顾名思义,可以说是搜索的抽屉。

ActionMacWindows / Linux
Expand/collapse all search resultsCommand+Option+Control+Shift+

⌨️推荐文

在网络上找到一些整理的相对较全的,放这里供大家参考。具体如下👇🏻

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BaseCommand/MacShortcutKey/004_google.html b/column/BaseCommand/MacShortcutKey/004_google.html index 00d6ac01..7b35fca0 100644 --- a/column/BaseCommand/MacShortcutKey/004_google.html +++ b/column/BaseCommand/MacShortcutKey/004_google.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/BaseCommand/MacShortcutKey/005_typora.html b/column/BaseCommand/MacShortcutKey/005_typora.html index b9dff72e..a17b3329 100644 --- a/column/BaseCommand/MacShortcutKey/005_typora.html +++ b/column/BaseCommand/MacShortcutKey/005_typora.html @@ -19,7 +19,7 @@
Skip to content

序言

这里附上官网最全的 typora 快捷键指南,详情地址戳:https://support.typora.io/Shortcut-Keys/#change-shortcut-keys

下面将整理上面网站中提及到的快捷键。

Typora快捷键

文件File

FunctionHotkey (Windows/Linux)Hotkey (macOS)
NewCtrl + NCommand + N
New WindowCtrl + Shift + NCommand +Shift + N
New Tab(Not Supported)Command + T
OpenCtrl + OCommand + O
Open QuicklyCtrl + PCommand + Shift + O
Reopen Closed FileCtrl + Shift + TCommand + Shift + T
SaveCtrl + SCommand + S
Save As / DuplicateCtrl + Shift + SCommand + Shift + S
PreferenceCtrl + ,Command + ,
CloseCtrl + WCommand + W

编辑器Edit

FunctionHotkey (Windows/Linux)Hotkey (macOS)
New ParagraphEnterEnter
New LineShift + EnterShift + Enter
CutCtrl + XCommand + X
CopyCtrl + CCommand + C
PasteCtrl + VCommand + V
Copy As MarkdownCtrl + Shift + CCommand + Shift + C
Paste As Plain TextCtrl + Shift + VCommand + Shift + V
Select AllCtrl + ACommand + A
Select Line/Sentence Select Row (in table)Ctrl + LCommand + L
Delete Row (in table)Ctrl + Shift + BackspaceCommand + Shift + Backspace
Select Style Scope Select Cell (in table)Ctrl + ECommand + E
Select WordCtrl + DCommand + D
Delete WordCtrl + Shift + DCommand + Shift + D
Jump to TopCtrl + HomeCommand + ↑
Jump to SelectionCtrl + JCommand + J
Jump to BottomCtrl + EndCommand + ↓
FindCtrl + FCommand + F
Find NextF3 / EnterCommand + G / Enter
Find PreviousShift + F3 / Shift + EnterCommand + Shift + G / Shift + Enter
ReplaceCtrl + HCommand + H

段落Paragraph

FunctionHotkey (Windows/Linux)Hotkey (macOS)
Heading 1 to 6Ctrl + 1/2/3/4/5/6Command + 1/2/3/4/5/6
ParagraphCtrl + 0Command + 0
Increase Heading LevelCtrl + =Command + =
Decrease Heading LevelCtrl + -Command + -
TableCtrl + TCommand + Option + T
Code FencesCtrl + Shift + KCommand + Option + C
Math BlockCtrl + Shift + MCommand + Option + B
QuoteCtrl + Shift + QCommand + Option + Q
Ordered ListCtrl + Shift + [Command + Option + O
Unordered ListCtrl + Shift + ]Command + Option + U
IndentCtrl + [ / TabCommand + [ / Tab
OutdentCtrl + ] / Shift + TabCommand + ] / Shift + Tab

格式化Format

FunctionHotkey (Windows/Linux)Hotkey (macOS)
StrongCtrl + BCommand + B
EmphasisCtrl + ICommand + I
UnderlineCtrl + UCommand + U
CodeCtrl + Shift + `Command + Shift + `
StrikeAlt + Shift + 5Control + Shift + `
HyperlinkCtrl + KCommand + K
ImageCtrl + Shift + ICommand + Control + I
Clear FormatCtrl + \Command + \

视图层View

FunctionHotkey (Windows/Linux)Hotkey (macOS)
Toggle SidebarCtrl + Shift + LCommand + Shift + L
OutlineCtrl + Shift + 1Command + Control + 1
ArticlesCtrl + Shift + 2Command + Control + 2
File TreeCtrl + Shift + 3Command + Control + 3
Source Code ModeCtrl + /Command + /
Focus ModeF8F8
Typewriter ModeF9F9
Toggle FullscreenF11Command + Option + F
Actual SizeCtrl + Shift + 0(Not Supported)
Zoom InCtrl + Shift + =(Not Supported)
Zoom OutCtrl + Shift + -(Not Supported)
Switch Between Opened DocumentsCtrl + TabCommand + `
Toggle DevToolsCtrl + Shift + I-

结语

在开头的快捷键文章链接中,也向大家展示了如何在系统中新建一个 app 的快捷键,具体可戳地址地址进行详细了解。

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BaseCommand/MacShortcutKey/006_notion.html b/column/BaseCommand/MacShortcutKey/006_notion.html index 9ab806fc..69b451bd 100644 --- a/column/BaseCommand/MacShortcutKey/006_notion.html +++ b/column/BaseCommand/MacShortcutKey/006_notion.html @@ -19,7 +19,7 @@
Skip to content

🚴‍♂️前言

关于 notion 最详细的快捷键,详情可戳官方文档:https://www.notion.so/help/keyboard-shortcuts。下面将整理一些在 notion 中较为常用的快捷键~ 以下展示的是 mac OS 的操作,如果你是 windows 用户,可以把 cmd 改成 ctrloption 改成 shift ,也同样使用~

🚵‍♂️通用操作

最受欢迎的快捷键

  • command+N
  • command+shift+N / command+click
  • command+P
  • command+[
  • command+]
  • command+shift+K
  • command+shift+J
  • command+shift+L

创建和装饰内容排版

  • enter
  • shift+enter
  • command+shift+M
  • ---
  • command+B
  • command+I
  • comman+U
  • command+shift+S
  • command+K
  • command+V
  • command+E
  • Tab
  • shift+Tab
  • /turn
  • /color
  • command+option+0
  • command+option+1
  • command+option+2
  • command+option+3
  • command+option+4
  • command+option+5
  • command+option+6
  • command+option+7
  • command+option+8
  • command+option+9
  • command++
  • command+-
  • command+shift+U
  • 按住option并拖拽

编辑和移动blocks

  • xxx

🧗‍♂️指令操作

@ 指令

  • xxx

[[ 指令

  • xxx

+ 指令

  • Xxx

slash 指令

基础操作

  • Xxx

内联操作

  • xxx

数据库操作

  • xxx

媒体操作

  • xxx

进阶操作

  • xxx

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BaseCommand/MacShortcutKey/007_git.html b/column/BaseCommand/MacShortcutKey/007_git.html index e5136ecd..7907cd35 100644 --- a/column/BaseCommand/MacShortcutKey/007_git.html +++ b/column/BaseCommand/MacShortcutKey/007_git.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/BaseCommand/MacShortcutKey/008_linux.html b/column/BaseCommand/MacShortcutKey/008_linux.html index a2f46de1..8280ed90 100644 --- a/column/BaseCommand/MacShortcutKey/008_linux.html +++ b/column/BaseCommand/MacShortcutKey/008_linux.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/BaseCommand/MacShortcutKey/009_lark.html b/column/BaseCommand/MacShortcutKey/009_lark.html index 2a8c8f22..c60f5bf8 100644 --- a/column/BaseCommand/MacShortcutKey/009_lark.html +++ b/column/BaseCommand/MacShortcutKey/009_lark.html @@ -19,7 +19,7 @@
Skip to content

通用快捷键

飞书文档包含4种类型,分别是:文档表格多维表格思维笔记。当我们新建一个上面谈到的文件时,那么可以通过 control+/ 的方式,来打开快捷键。在右侧面板中,将可以看到对应的各类型文件的快捷键操作。

更详细的使用方式可戳此链接:https://www.feishu.cn/hc/zh-CN/articles/360033771493

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BaseCommand/WinShortcutKey/001.html b/column/BaseCommand/WinShortcutKey/001.html index 43fc8741..a90d0273 100644 --- a/column/BaseCommand/WinShortcutKey/001.html +++ b/column/BaseCommand/WinShortcutKey/001.html @@ -19,7 +19,7 @@
Skip to content

通用快捷键

  • Ctrl+Shift+P 展示全局命令面板
  • Ctrl+P 快速打开最近打开的文件
  • Ctrl+Shift+N 打开新的编辑器窗口
  • Ctrl+shift+W 关闭编辑器

基础编辑

  • Alt+↑ | ↓ 移动上下行
  • Ctrl+Shift+↑ | ↓ 在当前行上下复制当前行
  • Ctrl+Shift+K 删除行
  • Ctrl+Enter 在当前行下方插入新的一行
  • Ctrl+Shift+Enter 在当前行上方插入新的一行
  • Ctrl+Shift+| 匹配花括号的闭合处,并跳转
  • Ctrl+] | [ 行缩进
  • Home 光标跳转到行头
  • End 光标跳转到行尾
  • Ctrl+Home 跳转到页头
  • Ctrl+End 跳转到页尾
  • Ctrl+↑ | ↓ 行视图上下偏移
  • Alt+PgUp/PgDown 屏视图上下偏移
  • Ctrl+Shift+[ 折叠区域代码
  • Ctrl+Shift+] 展开区域代码
  • Ctrl+D 选中当前一样的内容
  • Shift+Alt+F 格式化代码

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BaseCommand/WinShortcutKey/002.html b/column/BaseCommand/WinShortcutKey/002.html index 4cf80775..fbfeb02c 100644 --- a/column/BaseCommand/WinShortcutKey/002.html +++ b/column/BaseCommand/WinShortcutKey/002.html @@ -19,7 +19,7 @@
Skip to content

通用快捷键

  • rmdir /s/q 目录名称 比如: rmdir /s/q 222 表示删除 222 文件夹下的所有文件
  • ctrl + + 放大
  • ctrl + - 缩小

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BaseCommand/WinShortcutKey/003.html b/column/BaseCommand/WinShortcutKey/003.html index b359957e..97c9c68f 100644 --- a/column/BaseCommand/WinShortcutKey/003.html +++ b/column/BaseCommand/WinShortcutKey/003.html @@ -19,7 +19,7 @@
Skip to content

基础操作

  • ctrl+E 代码块
  • ctrl+shift+n 打开一个新的 notion 窗口
  • ctrl+p 打开搜索或跳转至最近浏览的页面
  • ctrl+[ 返回上一页
  • ctrl+] 进入页面
  • ctrl+shift+大写i 切入暗模式

Markdown 语法

  • ctrl+shift+0 创建文本
  • ctrl+shift+1 创建 H1 标题
  • ctrl+shift+2 创建 H2 标题
  • ctrl+shift+3 创建 H3 标题
  • ctrl+shift+4 创建待办事项复选框
  • ctrl+shift+5 创建项目符号列表
  • ctrl+shift+6 创建编号列表
  • ctrl+shift+7 创建一个切换列表
  • ctrl+shift+8 创建一个代码块
  • ctrl+shift+9 创建新页面,或将一行上的所有内容转化为页面
  • ctrl+加号+ 进行放大
  • ctrl+减号- 进行缩小
  • ctrl+shift+u 在页面层次结构上移一级
  • alt 按住 alt 进行拖动,可以复制新的一份

编辑和移动块(block)

  • Esc 选择当前所在的 block 或者 取消选中的 block

  • Ctrl+A 选择光标所在的 block(该block中要有内容)

  • Shift+向上/向下方向键 可向上或向下扩展选中范围、

  • Alt+Shift+单击 选择或取消整个 block

  • Shift+单击 选择另一个 block 以及之间的所有 block

  • backspace(退格)/ delete 删除选定的 block

  • Ctrl+D 复制所选的 block

  • enter 编辑所选 block 的任何文本(或者在页面内打开新的页面)

  • Ctrl+/

编辑或更改一个或多个选定的 block ,使用此快捷方式可以更改block的类型,颜色,或编辑,复制或移动block

在弹出的菜单顶部有一个文本框。只需输入所需的action,就会变成想要的block或颜色。

在板块图中,选择多个卡,然后使用 Ctrl+/ 一次编译所有卡。

  • Ctrl+Shift+方向键 可移动选定的 block。

  • Ctrl+Alt+T 可以展开或关闭切换列表中的所有切换

  • Ctrl+Alt+h 应用最后的文本或突出显示所使用的颜色

  • Ctrl+Enter 修改当前所在的 block。比如:开启页面选中或取消选中待办事项复选框打开或关闭切换列表项嵌入或图片全屏显示

斜杆命令

基本命令

  • /text或/plain 创建一个新的文本 block
  • /page 创建一个新的页面(并在按 enter 时自动打开它)
  • /bullet 创建项目符号列表
  • /num 创建一个编号列表
  • /todo 创建一个带有复选框的代办事项列表
  • /toggle 创建一个切换列表
  • /div 创建浅灰色的分隔线
  • /qutoe 创建一个较大文本的应用块
  • /h1 或/# 创建一个大的标题
  • /h2 或 /## 创建一个中等大小的标题
  • /h3 或/### 创建一个小标题
  • /link 在工作空间中创建指向另一个页面的链接 esc 清除/菜单

插入

  • /mention 允许提及工作区中的页面或人
  • /date 或 /reminder 可在页面上添加时间戳或提醒
  • /equation 可以根据文本添加 Tex 公式
  • /emoji 调出表情符号选择器

数据库

  • /table -inline 在当前页面内创建一个数据库表
  • /board -inline 在当前页面内创建看板
  • /calendar-inline 在页面内创建一个日历
  • /list-inline 在当前页面创建一个列表样式的数据库
  • /gallery-inline 在当前页面创建一个图库
  • /timeline-inline 在当前页面创建时间线也可以使用-full而不是-inline创建以上任何内容,以在自己的页面中自动打开该类型的数据库视图。例如:/table-full,/board-full
  • /linked 创建一个链接数据库-现有数据的副本,你可以将其插入到任何页面中,并按需要过来或查看。有助于从一页面上的同一数据库创建多个摘录

媒体

  • /image 将显示上传或嵌入图像或从Unsplash添加一个图片
  • /pdf 可以将任何 PDFURL 粘贴到此,以便其在页面上内联显示
  • /book 可粘贴任何网站的 URL ,以创建网络书签
  • /video 上传视频文件或嵌入其他视频网站的视频
  • /audio 上传音频或从其他网站的音频
  • /code 创建一个代码块,可以在其中编写和复制任何代码段
  • /file 允许从计算机上传任何文件或创建嵌入
  • /embed 可以添加适用于notion500 多个嵌入中的任何一个

高级

  • /moveto 可以将该块移动到其他页面
  • /delete 删除当前块
  • /math或/latex 使用 Tex 编写数学方程式和符号

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BaseCommand/WinShortcutKey/004.html b/column/BaseCommand/WinShortcutKey/004.html index 4eb5bb03..800e35f9 100644 --- a/column/BaseCommand/WinShortcutKey/004.html +++ b/column/BaseCommand/WinShortcutKey/004.html @@ -19,7 +19,7 @@
Skip to content

通用快捷键

  • Alt+K 旋转屏幕
  • 7 全屏
  • Ctrl+Shift+N 打开新的编辑器窗口
  • Ctrl+shift+W 关闭编辑器

基础编辑

  • Alt+↑ | ↓ 移动上下行
  • Ctrl+Shift+↑ | ↓ 在当前行上下复制当前行
  • Ctrl+Shift+K 删除行
  • Ctrl+Enter 在当前行下方插入新的一行
  • Ctrl+Shift+Enter 在当前行上方插入新的一行
  • Ctrl+Shift+| 匹配花括号的闭合处,并跳转
  • Ctrl+] | [ 行缩进
  • Home 光标跳转到行头
  • End 光标跳转到行尾
  • Ctrl+Home 跳转到页头
  • Ctrl+End 跳转到页尾
  • Ctrl+↑ | ↓ 行视图上下偏移
  • Alt+PgUp/PgDown 屏视图上下偏移
  • Ctrl+Shift+[ 折叠区域代码
  • Ctrl+Shift+] 展开区域代码
  • Ctrl+D 选中当前一样的内容
  • Shift+Alt+F 格式化代码

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/BaseCommand/index.html b/column/BaseCommand/index.html index 63035e87..928314bb 100644 --- a/column/BaseCommand/index.html +++ b/column/BaseCommand/index.html @@ -19,7 +19,7 @@
Skip to content

序言

本专栏旨在打造一个学习干货社区,包括但不限于软件快捷键的使用、工具集的收录等等。各类别干货如下 👇

文章收录

快捷键

001-vscode 快捷键

002-windows 快捷键

003-Notion 快捷键

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/ComputerKnowledge/Browser/001.html b/column/ComputerKnowledge/Browser/001.html index 6bafad75..f1a5328d 100644 --- a/column/ComputerKnowledge/Browser/001.html +++ b/column/ComputerKnowledge/Browser/001.html @@ -19,7 +19,7 @@
Skip to content

前言

要说浏览器存储的方式,我们听到最多的莫过于就是 cookie,localStorage 和 sessionStorage 了。那这三者之前有什么区别,cookie 与 session、sessionId 又有什么关系呢?接下来我们一起来了解一下吧!

一、浏览器存储的方式

特性cookielocalStoragesessionStorageindexedDB
数据生命周期一般由服务器生成,可以设置过期时间除非被清理,否则一直存在页面关闭就清理除非被清理,否则一直存在
数据存储大小4K5M5M无限
与服务端通信每次都会携带在 header 中,对于请求性能有一定影响不参与不参与不参与

补充cookie 原本并不是用来储存的,而是用来与服务端通信的,需要存取请自行封装 api

localStorage 则自带 getItemsetItem 方法,使用很方便。

localStorage 注意点:

  • localStorage 只能存字符串,存取 JSON 数据需配合 JSON.stringify()JSON.parse()

  • 遇上禁用 setItem 的浏览器,需要使用 try...catch 捕获异常。

二、cookie、localStorage 和 sessionStorage

1、cookie、localStorage 和 sessionStorage 是什么?

  • cookie 是一个非常具体的东西,指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。

  • cookie 由服务器生成,发送给浏览器,浏览器把 cookiekv 的形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该 cookie 发送给服务器。

  • cookie 的过期时间由客户端设置。若不设置过期时间,则表示这个 cookie 的生命期为浏览器会话期间,关闭浏览器窗口, cookie 就会消失。这种生命期为浏览器会话期的 cookie 被称为会话 cookie如果设置了过期时间,则在设置的 cookie 过期时间之前一直有效,即使窗口或浏览器关闭也会一直有效。

  • 会话 cookie 一般不存储在硬盘而是保存在内存里,当然这个行为并不是规范规定的。若设置了过期时间,浏览器就会把 cookie 保存到硬盘上,关闭后再打开浏览器后这些 cookie 仍然有效直到超过设定的过期时间。对于保存在内存里的 cookie ,不同的浏览器有不同的处理方式。

  • 可用 document.cookie = "" 来设置 cookie 的值。cookie 的值是键值对的形式存在,当设置的键一样时,会覆盖掉原先的值。当键不一样时,对进行叠加操作。这里附上一篇我看过觉得比较好理解的关于如何设置 cookie 的文章,大家可以根据自身需求进行查看~

(2)localStorage

  • 始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;
  • 同源窗口都会共享,并且不会失效,不管窗口或者浏览器关闭与否都会始终生效。

(3)sessionStorage

  • 浏览器存储的一种形式。

  • 仅在当前浏览器窗口关闭前有效,不可能持久保持。

  • 在相同浏览器里,如果是在当前页面里面跳转进入一个新的页面,可以共享;而如果是直接打开一个新的页面,不能共享。

2、cookie、localStorage 和 sessionStorage 的异同点

(1)三者的相同点在于:

  • 都是保存在浏览器端、且同源的。

(2)三者的区别在于:

  • 与服务器通信不同:

    cookie 数据始终在同源的 http 请求中携带(即使不需要),即 cookie 在浏览器和服务器间来回传递,而sessionStorage 和 localStorage 不会自动把数据发送给服务器,仅在本地保存;

    cookie 随着 http 请求被发送出去,而 loacalStoragesessionStorage 不会随着 http 请求被发送出去。

    cookie 数据还有路径(path)的概念,可以限制 cookie 只属于某个路径下。

  • 存储大小限制也不同:

    cookie 数据不能超过 4K,同时因为每次 http 请求都会携带 cookie 、所以 cookie 只适合保存很小的数据,如会话标识

    sessionStoragelocalStorage 虽然也有存储大小的限制,但比 cookie 大得多,可以达到 5M 或更大。

  • 数据有效期不同:

    sessionStorage :仅在当前浏览器窗口关闭之前有效;

    localStorage :始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;

    cookie :只在设置的 cookie 过期时间之前有效,即使窗口关闭或浏览器关闭。

  • 作用域不同:

    sessionStorage 不在不同的浏览器窗口中共享,即使是同一个页面;

    localstoragecookie所有同源窗口中都是共享的

3、cookie 的用途

(1)保存用户登录状态

例如将用户 id 存储于一个 cookie 内,这样当用户下次访问该页面 时就不需要重新登录了,现在很多论坛和社区都提供这样的功能。

cookie 还可以设置过期时间,当超过时间期限后,cookie 就会自动消失。因此,系统往往可以提示用户保持登录状态的时间:常见选项有一个月、三个 月、一年等

(2)跟踪用户行为

例如一个天气预报网站,能够根据用户选择的地区显示当地的天气情况。 如果每次都需要选择所在地是繁琐的,当利用了 cookie 后就会显得很人性化了,系统能够记住上一次访问的地区,当下次再打开该页面时,它就会自动显示上次用户所在地区 的天气情况。

因为一切都是在后台完成,所以这样的页面就像为某个用户所定制的一样,使用起来非常方便定制页面。如果网站提供了换肤或更换布局的功能,那么可以使用 cookie 来记录用户的选项,例如:背景色、分辨率等。当用户下次访问时,仍然可以保存上一次访问的界面风格。

三、session 和 token

(1)Session

举个例子:

  • session 从字面上讲,就是会话。这个就类似于你和一个人交谈,你怎么知道当前和你交谈的是张三而不是李四呢?对方肯定有某种特征(长相、身高等等)表明他就是张三。
  • session 也是类似的道理,服务器要知道当前发请求给自己的是谁。
  • 为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,这个身份表示也就是我们平常所说的 sessionId 。然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。
  • 至于客户端怎么保存这个“身份标识”,可以有很多种方式,对于浏览器客户端,大部分情况下都默认采用 cookie 的方式,当然也可以使用 localStoragesessionStorage 存储这个身份标识,大家可以依据自身需求进行使用。
  • 需要注意的是, session 为一个会话,当页面不同即使是同一页面打开两次,也被视为同一次会话。
  • 服务器使用 session 把用户的信息临时保存在了服务器上,用户离开网站后 session 会被销毁。
  • 这种用户信息存储方式相对 cookie 来说更安全,但是 session 有一个缺陷:如果 web 服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候 session 会丢失。

综上所述,对 session 做个总结:

  • 当程序需要为某个客户端的请求创建一个 session 时,服务器首先检查这个客户端的请求里是否已包含了一个 session 标识( 称为 sessionId ),如果已包含则说明以前已经为此客户端创建过 session ,服务器就按照此 sessionId 把其对应的 session 检索出来使用(检索不到,会新建一个);反之,如果客户端请求不包含 sessionId ,则为客户端创建一个 session 并且生成一个与此 session 相关联的 sessionIdsessionId 的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个 sessionId 将被在本次响应中返回给客户端保存。保存这个 sessionId 的方式可以采用 cookie ,也可以是 locaStoragesessionStorage ,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。

(2)Token

  • 在 Web 领域基于 Token 的身份验证随处可见。在大多数使用 Web API 的互联网公司中, token多用户下处理认证的最佳方式

  • 以下几点特性会让你在程序中使用基于 Token 的身份验证:

    • 无状态、可扩展;
    • 支持移动设备;
    • 跨程序调用;
    • 安全。
  • 大部分你见到过的 APIWeb 应用都使用 token 。例如 Facebook , Twitter , Google , GitHub 等。

四、结束语

cookie、loacalStorage 和 sessionStorage 是面试中老生常谈的问题了。在学习的过程中,要理解好 cookie、localStorage 和 sessionStorage 的关系,以及 session、sessionId 和 cookie 的关系,只有把它们这几个之间的关系弄明白了,自己才不会一直深陷在一个关系杂圈中。

关于浏览器存储的内容就讲到这里啦!

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/ComputerKnowledge/Browser/002.html b/column/ComputerKnowledge/Browser/002.html index f5b459b3..f8a0ace0 100644 --- a/column/ComputerKnowledge/Browser/002.html +++ b/column/ComputerKnowledge/Browser/002.html @@ -19,7 +19,7 @@
Skip to content

前言

http 对于一个前端工程师来说,是非常需要了解的一个知识点,贯穿于整个前端开发的过程。如果说一个前端工程师不知道 http ,或者说是了解甚少,那他肯定不是一个合格的工程师。那么,http 对于去前端来说,有什么用呢?

  • 前端工程师在开发界面时,需要用到 http 协议;
  • 前端在调用后端的接口时,提交(post)或者获取(get)数据时,需要用到 http 协议;
  • ……

下面将从多个方面讲解 http 协议。

一、http 状态码

1、引例阐述

在讲状态吗之前,我们先来了解什么是状态码。比如百度网站:

百度状态码

大家可以看到,上图中圈红圈的部分就是 http 的状态码,常见的状态码有 200,400,404 等等。接下来对状态码的一些基础知识进行介绍。

2、状态码分类

下表给出状态码分类。

状态码含义解释说明
1xx服务器收到请求收到 1xx 开头的请求表示服务端已经收到请求,但是还没有返回信息给客户端
2xx请求成功,如 200表示客户端已经成功请求数据
3xx重定向,如 302客户端收到 3xx 开头的状态码时,表示此时服务端已经不再管客户端所请求地址,让客户端去请求另外的地址
4xx客户端错误,404表示当客户端请求了一个服务端完全不认识的地址时,就会报出 4xx 的错误
5xx服务端错误,如 500表示此错误来源于服务端,比如服务端写的接口出现了 bug 等问题

3、常见状态码

常见的有 200(正常) 、404(无法找到该网页资源) 、304(跳转页面) 、500(服务器错误)等,具体如下:

状态码含义用途
200OK 成功一般用于 GET 和 POST 请求
301Redirect Permanently 永久重定向配合 location,浏览器自动处理
302Found 临时重定向配合 location,浏览器自动处理
304Not Modified 资源未被修改所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
404Not Found 资源未找到服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站 设计人员可设置"您所请求的资源无法找到"的个性页面
403Forbidden 没有权限服务器理解请求客户端的请求,但是拒绝执行此请求
500Internal server Error 服务器错误服务器内部错误
504Gateway Time-out 网关超时充当网关或代理的服务器,未及时从远端服务器获取请求

下面详细阐述 301302

301 永久重定向:

常见场景有,比如说你的一个网站,域名到期了,或者域名你不想用了,那么老的域名就可以返回一个 301 状态码并配合 location 让 location 的值等于新的域名,最终进行跳转,之后浏览器会记住新的域名,不会再访问老的域名。

302 临时重定向:

常见场景有百度,知乎、简书等等。比如说我们要在百度进入菜鸟教程,搜索出来后有一系列的列表,我们可以选择一个去进行一个点击。点击的那个不会直接进入菜鸟教程,而是先跳转到百度设置的一个临时地址,之后再跳转到菜鸟教程真实的地址。

4、关于协议和规范

  • http 协议就是一个约定,一个规范,要求大家都跟着执行;
  • 因此不要做违规范的事情,例如 IE 浏览器,违反规范终将会落下被历史淘汰的局面。

二、http 方法

1、传统的 methods

  • get 获取服务器的数据;
  • post 向服务器提交数据;
  • head 用户获取报头。

2、现在的 methods

  • get 获取数据;
  • post 新建数据;
  • patch/put 更新数据;
  • delete 删除数据;
  • head,类似于 get 请求,只不过返回的响应中没有具体的内容,用户获取报头;
  • options,允许客户端查看服务器的性能,比如说服务器支持的请求方式等等;
  • trace,追踪路径;
  • connect,要求用隧道协议连接代理。

3、Restful API

(1)Restful API 是什么?

  • Restful API 是一种新的 API 设计方法(早已推广使用)。

  • 传统 API 设计:把每个 url 当做一个功能。

  • Restful API 设计:把每个 url 当做一个唯一的资源。

(2)如何设计成一个资源?

1)尽量不用 url 参数

  • 传统 API 设计:/api/list?pageIndex=2
  • Restful API 设计:/api/list/2

2)用 method 表示操作类型

传统 API 设计:

  • post 请求:/api/create-article

  • post 请求:/api/update-article?id=100

  • get 请求:/api/get-article?id=100

Restful API 设计:

  • post 请求:/api/article

  • post 请求:/api/article/100

  • get 请求:/api/article/100

三、http 头部(http headers)

1、常见的 Request headers

请求头含义
Accept浏览器可接收的数据格式
Accept-Encoding浏览器可以接收的算法,如 gzip
Accept-Language浏览器可接收的语言,如 zh-CN
Connectionkeep-alive 一次 TCP 连接重复使用
cookie客户端接收到的 Cookie 信息
Host指定原始的 URL 中的主机和端口
User-Agent(简称 UA)浏览器内核信息
Content-type发送数据的格式,如 application/json

2、常见的 Response headers

响应头含义
Content-type返回数据的格式,如 application/json
Content-length返回数据的大小,多少字节
Content-Encoding返回数据的压缩算法,如 gzip
Set-Cookie服务端向客户端设置 cookie

四、http 缓存

1、关于缓存的介绍

(1)什么是缓存

缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。

(2)为什么需要缓存?

如果没有缓存的话,每一次网络请求都要加载大量的图片和资源,这会使页面的加载变慢许多。那缓存的目的其实就是为了尽量减少网络请求的体积和数量,让页面加载的更快。

(3)哪些资源可以被缓存?——静态资源(js、css、img)

  • 网站的 html 是不能被缓存的。因为网站在使用过程中 html 随时有可能被更新,随时有可能被替换模板。
  • 网页的业务数据也是不能被缓存的。比如留言板和评论区,用户随时都可以在底下评论,那数据库的内容就会被频繁被更新。

2、http 缓存策略(强制缓存 + 协商缓存)

(1)强制缓存

1)强制缓存是什么?

强制缓存就是文件直接从本地缓存中获取,不需要发送请求。

2)图例

先看第一个图。

强制缓存 图1

从上图可以看到,当初次请求时,浏览器会向服务器发起请求,服务器接收到浏览器的请求后,返回资源并返回一个 Cache-Control 给客户端,该 Cache-Control 一般设置缓存的最大过期时间。


接下来看第二个图。

强制缓存 图2

从上图中可以看到,此时浏览器已经接收到 cache-control 的值,那么这个时候浏览器再次发送请求时,它会先检查它的 cache-control 是否过期,如果没有过期则直接从本地缓存中拉取资源,返回到客户端,而无需再经过服务器。


接下来看第三个图。

强制缓存 图3

强制缓存有过期时间,那么就意味着总有一天缓存会失效。那么假设某一天,客户端的 cache-control 失效了,那么它就没办法从本地缓存中拉取资源。于是它会像第一张图一样,重新向服务器发起请求,之后服务器会再次返回资源和 cache-control 的值。

以上就是强制缓存的全过程。

3)Cache-Control

Cache-Control 是什么?

  • 存在于响应头 Response Headers 中;
  • 控制强制缓存的逻辑;
  • 例如:Cache-Control: max-age = 31536000(单位是秒)。

Cache-Control 的值

Cache-Control 值含义
max-age设置缓存的最大过期时间
no-cache不用本地缓存,正常的向服务端请求,服务端怎么处理我们不用管
no-store简单粗暴,直接从服务端拉取缓存
private只能允许最终用户做缓存,最终用户即电脑、手机等等
public允许中间路由或中间代理做缓存

4)关于 Expires

  • 同在 Response Headers
  • 同为控制缓存的过期时间(早期使用)
  • 如果 cache-control 与 expires 同时存在的话, cache-control 的优先级高于 expires

(2)协商缓存

1)协商缓存是什么?

  • 协商缓存,也叫对比缓存。
  • 它是一种服务端的缓存策略,即通过服务端来判断某件事情是不是可以被缓存。
  • 服务端判断客户端的资源,是否和服务端资源一样,如果一致则返回 304 ,反之返回 200 和最新的资源。

2)图例

同样地,用几张图来演示协商缓存。

先来看第一张图。

协商缓存 图1

在上图中,表明了协商缓存的全过程。首先,如果客户端是第一次向服务器发出请求,则服务器返回资源和相对应的资源标识给浏览器。该资源标识就是对当前所返回资源的一种唯一标识,可以是 Etag 或者是 Last-Modified,这两个字段将在图例结束后展开讲解。

之后如果浏览器再次发送请求时,浏览器就会带上这个资源标识。此时,服务端就会通过这个资源标识,可以判断出浏览器的资源跟服务端此时的资源是否一致,如果一致,则返回 304,即表示 Not Found 资源未修改。如果判断结果为不一致,则返回 200,并返回资源以及新的资源标识。至此就结束了协商缓存的过程。


接下来看第二张图。

协商缓存 图2

假设此时我们的协商缓存用 Last-Modified 来判断。当浏览器第一次发送请求时,服务器返回资源并返回一个 Last-Modified 的值给浏览器。这个 Last-Modified 的值给到浏览器之后,浏览器会通过 If-Modified-Since 的字段来保存 Last-Modified 的值,且 If-Modified-Since 保存在请求头当中。

之后当浏览器再次发送请求时,请求头会带着 If-Modified-Since 的值去找服务器,服务器此刻就会匹配浏览器发过来的 If-Modified-Since 是否和自己最后一次修改的 Last-Modified 的值相等。如果相等,则返回 304 ,表示资源未被修改;如果不相等,则返回 200,并返回资源和新的 Last-Modified 的值。


接下来看第三张图。

协商缓存 图3

假设此时我们的协商缓存用 Etag 来判断。当浏览器第一次发送请求时,服务器返回资源并返回一个 Etag 的值给浏览器。这个 Etag 的值给到浏览器之后,浏览器会通过 If-None-Match 的字段来保存 Etag 的值,且 If-None-Match 保存在请求头当中。

之后当浏览器再次发送请求时,请求头会带着 If-Modified-Since 的值去找服务器,服务器此刻就会匹配浏览器发过来的 If-None-Match 是否和自己最后一次修改的 Etag 的值相等。如果相等,则返回 304 ,表示资源未被修改;如果不相等,则返回 200 ,并返回资源和新的 Etag 的值。

通过图例,相信大家对协商缓存有了一个新的认识。接下来讲解刚刚图例中所包含的一些字段。

3)资源标识

在响应头部 Response Headers 中,有两种资源标识:

  • Last-Modified 资源的最后修改时间,对应请求头为 If-Modified-Since
  • Etag 资源的唯一标识,所谓唯一,可以想象成时人类的指纹,具有唯一性;但 Etag 的本质是一个字符串;对应请求头为 If-None-Match

4)Last-Modified 和 Etag

  • 当响应头部 Response Headers 同时存在 Last-ModifiedEtag 的值时,会优先使用 Etag
  • Last-Modified 只能精确到秒级;
  • 如果资源被重复生成,而内容不变,则 Etag 更精确。

5)Headers 示例

Headers 实例

由上图可以看到,响应头中的 Last-Modified 对应请求头中的 If-Modified-SinceEtag 对应请求头中的 If-None-Match

6)流程图

说到这里,协商缓存的内容也快结束啦!最后的最后,我们用一张流程图来展示协商缓存的全过程。 协商缓存流程图

3、刷新操作方式,对缓存的影响

讲完缓存,我们再来讲个有点重要但是有点题外话的内容:刷新操作。我们平常在上网时,总有某个时刻突然网卡了,这个时候人的本性总是非常不耐烦的,毫不犹豫的就来个刷新。但殊不知,刷新对缓存也存在一定的影响。下面我们一起来看下各种刷新姿势以及其对缓存的影响。

(1)正常操作

定义: 地址栏输入 url ,跳转链接,前进后退等。

对缓存的影响: 强制缓存有效,协商缓存有效。

(2)手动刷新

定义: F5 ,点击刷新按钮,右击菜单刷新。

对缓存的影响: 强制缓存失效,协商缓存有效。

(3)强制刷新

定义: ctrl + F5

对缓存的影响: 强制缓存失效,协商缓存失效。

这一块内容仅当娱乐补充,大家可以根据自身需求学习~

五、写在最后

http 协议对于开发来说时很重要很重要的一块内容,不管时前端还是后端,对于常见的状态码,请求方法请求头和响应头,还有强缓存和协商缓存都是必须要了解的知识点。

关于 http 协议的知识就讲到这里啦!

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/ComputerKnowledge/PerformanceOptimization/001.html b/column/ComputerKnowledge/PerformanceOptimization/001.html index 4ba12b89..28f2b973 100644 --- a/column/ComputerKnowledge/PerformanceOptimization/001.html +++ b/column/ComputerKnowledge/PerformanceOptimization/001.html @@ -409,7 +409,7 @@ </script> </body> </html>

四、写在最后

关于前端性能优化的一些基础内容就讲到这里啦!

- + \ No newline at end of file diff --git a/column/ComputerKnowledge/Security/001.html b/column/ComputerKnowledge/Security/001.html index c9fd699b..ad6d844e 100644 --- a/column/ComputerKnowledge/Security/001.html +++ b/column/ComputerKnowledge/Security/001.html @@ -55,7 +55,7 @@ <a/>
<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
 	重磅消息!!
 <a/>

6、如何防御 csrf

1)验证码

增加验证,例如密码、短信验证码、指纹等等,强制用户必须与应用进行交互,才能完成最终请求。这种方式能很好的遏制 csrf ,但是用户体验相对会比较差。

2)Referer check

referer 代表请求的来源,不可以伪造。后端可以通过写一个过滤器来检查请求的 headers 中的 referer ,检验是不是本网站的请求。但缺点是浏览器可以关闭 referer ,且低版本的浏览器会存在伪造 Referer 的风险。

refererorigin 的区别,只有 post 请求会携带 origin 请求头,而 referer 不论何种情况下都带。

3)token

token 是最普遍的一种防御方法,后端先生成一个 token ,之后将此放在数据库中并发送给前端,那么前端发送请求时就会携带这个 token ,后端通过校验这个 token数据库中的 token 是否一致,以此来判断是否是本网站的请求。

示例: 用户登录输入账号密码,请求登录接口,后端在用户登录信息正确的情况下将 token 放到数据库中,并返回 token 给前端,前端把 token 存放在 localstorage 中,之后再发送请求都会将 token 放到 header 中。 后端写一个过滤器,拦截 POST 请求,注意忽略掉不需要 token 的请求,比如登录接口,获取 token 的接口,以免还没有获取 token 就开始检验 token 。 校验原则:数据库中的 token 和前端 header 中的 token 一致的 post 请求,则说明校验成功,给客户端放行。

三、CSRF 与 XSS 区别

CSRF 与 XSS 区别有以下两点:

四、结束语

对于前端来说,防范攻击还是很重要的,因为谁也预测不了我们写的网站何时会受到攻击。

本文很浅很浅的谈论了关于 Web 前端安全中的两种攻击模式,希望对大家有帮助!

- + \ No newline at end of file diff --git a/column/ComputerKnowledge/index.html b/column/ComputerKnowledge/index.html index 0eef7257..f0f1a97d 100644 --- a/column/ComputerKnowledge/index.html +++ b/column/ComputerKnowledge/index.html @@ -19,7 +19,7 @@
Skip to content

前言

计算机基础知识包括三个部分的内容,分别是浏览器原理前端安全性能优化。各部分的文章如下 👇

1️⃣ 浏览器原理

解决浏览器存储问题,不得不了解的 cookie,localStorage 和 sessionStorage

你知道 304 吗?图解强缓存和协商缓存

2️⃣ 前端安全

浅谈 Web 前端安全策略 xss 和 csrf,及又该如何预防?

3️⃣ 性能优化

关于前端性能优化问题,认识网页加载过程和防抖节流

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/DeepLearning/index.html b/column/DeepLearning/index.html index 9e226516..9d2dcf31 100644 --- a/column/DeepLearning/index.html +++ b/column/DeepLearning/index.html @@ -19,7 +19,7 @@
Skip to content

#第三方第三方

Last updated:

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/FrontEnd/CSS/001.html b/column/FrontEnd/CSS/001.html index 2ac3de64..0861f1a9 100644 --- a/column/FrontEnd/CSS/001.html +++ b/column/FrontEnd/CSS/001.html @@ -409,7 +409,7 @@ </script> </body> </html>

四、写在最后

关于前端性能优化的一些基础内容就讲到这里啦!

- + \ No newline at end of file diff --git a/column/FrontEnd/CSS/002.html b/column/FrontEnd/CSS/002.html index e92ff587..8e951276 100644 --- a/column/FrontEnd/CSS/002.html +++ b/column/FrontEnd/CSS/002.html @@ -305,7 +305,7 @@ #foo[id] { }

这样看起来,会不会就友好了许多呢。

🥳 三、结束语

在上文中,我们讲到关于 css 选择器的一些基础知识,以及 css 选择器的优先级的各种计算方式,还有关于“后来居上”原则和一些提升优先级的小 tips。

讲到这里,关于 css 选择器优先级的讲解就结束啦!希望对大家有帮助~

🐣 彩蛋 One More Thing

🏷️ 往期推荐&参考资料

position 和 z-index👉你可能对 position 和 z-index 有一些误解

书籍 👉 张鑫旭老师的《CSS 选择器世界》

🏷️ 番外篇

- + \ No newline at end of file diff --git a/column/FrontEnd/ComponentLib/001.html b/column/FrontEnd/ComponentLib/001.html index 928f6e1c..b7c161a7 100644 --- a/column/FrontEnd/ComponentLib/001.html +++ b/column/FrontEnd/ComponentLib/001.html @@ -1291,7 +1291,7 @@ </script> <style lang="ts" scoped></style>

此时浏览器的显示效果如下:

dowpdown组件点击外部区域自动隐藏

大家可以看到,最终的显示效果也是一样的。但是呢,通过代码逻辑抽离,我们整个组件的设计看起来也更加完美,可扩展性也变得更高。

5、联合效果

最后,我们把上面所学的 GlobalHeader 和 Columnist 结合起来,来看一下一体化的效果。详情见下图:

联合效果

以上就是关于 ColumnListGlobalHeader 两个组件的实现方式。不知道大家是否还意犹未尽呢~

后面还会持续出关于组件设计的文章,欢迎关注~

🛒 四、结束语

讲到这里,关于组件 GlobalHeaderColumnList 的设计就结束啦!在设计组件的时候呢,要特别考虑组件的可扩展性。如果一个组件在写的时候,感觉没什么复用度,那么这个时候可能就得思考下,是不是哪个环节出现问题了。多问自己为什么,多问自己这个组件是否能抽离的更好。

以上就是本文的全部内容!我们下期见!

🐣 彩蛋 One More Thing

基础知识回顾

软件推荐

这里给大家推荐文章用到的一个画图软件:Axure RP 9

Axure RP 旨在用于画低保真原型图,对于开发者来说也是极其友好的。丰富的控件库和动画交互,可以满足日常画图的大部分需求。安利一波~

- + \ No newline at end of file diff --git a/column/FrontEnd/ComponentLib/002.html b/column/FrontEnd/ComponentLib/002.html index 702781f1..f8374883 100644 --- a/column/FrontEnd/ComponentLib/002.html +++ b/column/FrontEnd/ComponentLib/002.html @@ -1721,7 +1721,7 @@ }, }); </script>

这部分呢,我们成功调用了 formSubmit 事件,并将其进行监听。

好了,到此,我们的表单验证组件设计就完成啦!不知道大家是否对这种设计思想有了一个新的认识呢?

👁️‍🗨️ 四、结束语

在上面的文章中,我们讲到了 Web 世界中的表单元素。从验证输入框 ValidateInut 的抽象验证规则,对 v-model 进行重新设计,以及使用 $attrs 来支持默认属性。再到 ValidateForm 的使用具名插槽让提交按钮高度自定义化,再到最后的 input 之前的父子组件通讯。

整个过程细水长流,但也有很多新的设计思想值得我们去楷模和学习~

到这里,关于本文的讲解就结束啦~

如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😛

💯 往期推荐

👉前端只是切图仔?来学学给开发人看的 UI 设计

👉紧跟月影大佬的步伐,一起来学习如何写好 JS(上)

👉紧跟月影大佬的步伐,一起来学习如何写好 JS(下)

👉组件库实战 | 用 vue3+ts 实现全局 Header 和列表数据渲染 ColumnList

- + \ No newline at end of file diff --git a/column/FrontEnd/JavaScript/001.html b/column/FrontEnd/JavaScript/001.html index 6d074280..06801d7c 100644 --- a/column/FrontEnd/JavaScript/001.html +++ b/column/FrontEnd/JavaScript/001.html @@ -345,7 +345,7 @@ let res3 = add3(5); console.log(res3(1)(2, 3)(4)(5)); //15

三、写在最后

对于函数柯里化的内容我也还不是特别熟悉,写的内容仅供参考,待后面有深入了解之后还会再继续进行补充。

关于作用域、闭包以及闭包的一些应用场景就讲到这里啦!

- + \ No newline at end of file diff --git a/column/FrontEnd/JavaScript/002.html b/column/FrontEnd/JavaScript/002.html index 3170b80a..f8dc4fe4 100644 --- a/column/FrontEnd/JavaScript/002.html +++ b/column/FrontEnd/JavaScript/002.html @@ -493,7 +493,7 @@ obj1.add.myBind(obj2)(['reading', 'working']); // 输出结果:在我的业余时间里,我喜欢reading,working,但同时我也喜欢learning

通过以上我们可以看到, bind 有点类似 applycall 的结合,只不过它返回的是一个函数,需要自身再进行一次调用, 而传给这个函数的参数形式有两种方式,可以是像 apply 一样的数组形式, 也可以是像 call 一样的逐个传入的形式。

大家不要觉得这个后面加个小括号太麻烦,这就是 bind 的强大之处,有时候 bind 也会经常运用在函数柯里化中。

讲到这里,关于 this 的相关知识就讲完啦!接下来我们来做个总结。

5、做个小结

四、写在最后

关于 this 的指向问题在前端的面试中尤为常见,大家可以按照上文中的顺序把 this 的知识点串联起来一起理解!同时,本文内容为本人理解所整理,可能会存在边界歧义等问题。如果有不理解或者有误的地方欢迎勘误~

- + \ No newline at end of file diff --git a/column/FrontEnd/JavaScript/003.html b/column/FrontEnd/JavaScript/003.html index 4d21eeac..3c31df64 100644 --- a/column/FrontEnd/JavaScript/003.html +++ b/column/FrontEnd/JavaScript/003.html @@ -675,7 +675,7 @@ //执行微任务 //(尝试触发 DOM 渲染) // 触发event loop,执行宏任务

这里就不再进行一一解析啦!大家可以前面知识点的学习总计再回顾理解。

四、写在最后

关于 js 的异步问题以及异步的解决方案问题就讲到这里啦!u1s1, promiseasync/await 在我们日常的前端开发中还是蛮重要的,基本上写异步代码时候都会用到 async/await 来解决。啃了 16 个小时总结了event looppromise 、async/await 问题,希望对大家有帮助。

同时,里面可能有一些讲的不好或者不容易理解的地方也欢迎评论区评论或私信我交流~

- + \ No newline at end of file diff --git a/column/FrontEnd/JavaScript/004.html b/column/FrontEnd/JavaScript/004.html index a4967d0e..ffb960b6 100644 --- a/column/FrontEnd/JavaScript/004.html +++ b/column/FrontEnd/JavaScript/004.html @@ -341,7 +341,7 @@ history.forward(); //对网页进行前进
// history
 history.back(); //对网页进行后退
 history.forward(); //对网页进行前进

此时浏览器打印如下。

history

从上图中可以看到,通过 history.back()history.forward() 可以让当前浏览页面进行前进或者后退操作。

结束语

JS 的基础知识规定了 ECMA 的语法标准,而 Web API 则是网页操作的 API ,是 W3C 的标准。如果要说两者的关系,那自然是 ES 标准是 Web API 的基础。在实际应用开发中,只有两者结合才能真正做到实际应用。所以,不管是 ES 标准还是 Web API 中的 DOMBOM 操作,在实际开发中都是至关重要的内容。

关于 DOMBOM 的操作就讲到这里啦!如有疑问欢迎勘误~

- + \ No newline at end of file diff --git a/column/FrontEnd/JavaScript/005.html b/column/FrontEnd/JavaScript/005.html index c2c90129..0c488e11 100644 --- a/column/FrontEnd/JavaScript/005.html +++ b/column/FrontEnd/JavaScript/005.html @@ -425,7 +425,7 @@ </script> </body> </html>

当点击列表中的 item 时,执行结果如下:

事件代理

从上图中可以看出,当点击目标元素时,可以对其进行捕获,在捕获结束后,对其进行冒泡操作,且达到了点击当前元素只显示当前元素的效果。

同时,细心的小伙伴已经发现,在我们上面的代码中,编写顺序是先冒泡后捕获。但结果打印依然是先捕获后冒泡。这也就顺应了我们上面所说的,关于 DOM 事件流的顺序,都是先捕获后冒泡,而跟实际的代码顺序是没有关系的。

四、总结和回顾

讲完事件绑定、DOM 事件流模型中的事件冒泡和事件捕获以及事件代理,我们来做个总结和回顾。

(1)以上的内容总结下来有以下几点:

(2)用几个题目来回顾下我们上面所讲的知识点

Q1:描述事件冒泡的流程

A1:

Q2:当无限下拉图片列表时,如何监听每个图片的点击?

A2:

结束语

一直都不是特别清楚为什么是事件是先捕获后冒泡,脑子里也没有个大概框架,文绉绉的文字也不能让我对它有所理解。直到看到了 W3C 的那张 DOM 事件流模型的图,一下子明白了事件为什么是先捕获后冒泡了。因为 Window 对象是直接面向用户的,那么当用户触发一个事件时,如点击事件,肯定时从 Window 对象开始的,然后再向内逐层递进。所以自然也就是先捕获后冒泡了!

关于 Web API 中的事件就讲到这里啦!如有疑问欢迎勘误~

- + \ No newline at end of file diff --git a/column/FrontEnd/JavaScript/006.html b/column/FrontEnd/JavaScript/006.html index 640842be..fd61b6f3 100644 --- a/column/FrontEnd/JavaScript/006.html +++ b/column/FrontEnd/JavaScript/006.html @@ -225,7 +225,7 @@ *(注意前端请求需要设置 withCredentials = true) */ response.setHeader('Access-Control-Allow-Credentials', 'false');

结束语

以上文章浅谈了 ajax 以及常用的跨域方案,没有深究到很细节层面的内容。希望对大家有帮助!

关于 Ajax 以及跨域的一些信息就讲到这里啦!如有疑问欢迎提issue勘误~

- + \ No newline at end of file diff --git a/column/FrontEnd/JavaScript/007.html b/column/FrontEnd/JavaScript/007.html index fbca4d68..80a59e6e 100644 --- a/column/FrontEnd/JavaScript/007.html +++ b/column/FrontEnd/JavaScript/007.html @@ -187,7 +187,7 @@ </script> </body> </html>

大家可以看到,使用 getElementByTagName 时,获取的是一个 HTMLCollection 集合,这个时候说明对节点进行增删操作时,页面的 DOM 结构会发生改变,且HTMLCollection实时地获取到集合的长度。

📞 三、结束语

写到这里的时候,不得不感概 jsDOM 操作是如此的强大,也突然就明白了自己之前写代码的时候为啥会遇到那么多坑。如果在学习之初就追溯于原理,可能跳的坑应该就能少很多了。

讲到这里,关于 HTMLCollectionNodeList 的内容就结束啦!希望对大家有帮助~

彩蛋有几篇我看过还比较好理解的文章,有需要可以当扩展知识进行扩充哦~

🐣 彩蛋 One More Thing

(:参考资料

lio_zero👉HTMLCollection 和 NodeList 的区别

Snandy👉将 HTMLCollection/NodeList/伪数组转换成数组

binyellow👉DOM 操作,HTMLCollection、NodeList

爱民 👉NodeList 和 HTMLCollection

- + \ No newline at end of file diff --git a/column/FrontEnd/JavaScript/008.html b/column/FrontEnd/JavaScript/008.html index 471e2933..ac5d70af 100644 --- a/column/FrontEnd/JavaScript/008.html +++ b/column/FrontEnd/JavaScript/008.html @@ -664,7 +664,7 @@ }; p1.printName(); // 'Monday'

大家可以看到,通过在 ColorPoint 的实例 p2 上向 Point 类中添加方法,从而影响到了 Point 实例 p1

📑 四、结束语

上文我们讲到了 6 大继承方式以及 class 的继承,在现如今的开发场景中,基本上也是寄生式组合继承和 class 的继承用的比较多。相信通过上文的了解,大家对 javascript 的继承又有了一个新的认识。

到这里,关于 js 的继承讲解就结束啦!希望对大家有帮助!

🐣 彩蛋 One More Thing

(:参考资料

书籍 👉ES6 书籍《ES6 标准入门》

书籍 👉 红宝书《JavaScript 高级程序设计》第四版

同梦奇缘 👉《javascript 高级程序设计》笔记:继承

- + \ No newline at end of file diff --git a/column/FrontEnd/JavaScript/009.html b/column/FrontEnd/JavaScript/009.html index cb5b5462..165646a2 100644 --- a/column/FrontEnd/JavaScript/009.html +++ b/column/FrontEnd/JavaScript/009.html @@ -2183,7 +2183,7 @@ PromiseMon.resolve().then(function () { console.log('two'); // two });

大家可以看到,依据我们所罗列的三种情况, promise.resolve 的功能也一一实现啦!

同时, promise.reject 也是按照这个模式去实现,这里不再进行讲解~

📝 四、结束语

写到这里的时候,发现我已经花了整整三天的时间,大约接近 34h+在 promise 这个知识上,好在最终算是对 promise 核心功能的的实现有一个较为满意的结果。

可能也是第一次这么细致的去啃一个知识,所以在学习过程中遇到很多以前没踩过的坑,中间过程中对问题进行详细记录并尝试解决,慢慢的就完善了一个新的知识体系。

最后,本文讲解到这里就结束啦!希望大家能对 promise 有一个更好的了解~

🐣 彩蛋 One More Thing

(:课代表记录

✅《三 7.》的 Promise.race 方法未用代码在原文中实现。

✅《三 8.》中,据资料调查, promise.resolve 还有第 4 种传参方式,当参数是一个 thenable ,即参数是一个带有 then 方法的对象时,则结果返回具有 then 方法的对象(本功能暂未实现)。

✅《三 8.》的 Promise.reject 方法未用代码在原文中实现。

(:参考资料

👉 [万字详解]JavaScript 中的异步模式及 Promise 使用

👉 [1w6k 字详细讲解] 保姆级一步一步带你实现 Promise 的核心功能

👉 ES6 快速入门

- + \ No newline at end of file diff --git a/column/FrontEnd/JavaScript/010.html b/column/FrontEnd/JavaScript/010.html index d71b043e..9cb86e65 100644 --- a/column/FrontEnd/JavaScript/010.html +++ b/column/FrontEnd/JavaScript/010.html @@ -19,7 +19,7 @@
Skip to content

深度透彻掌握原型

序言

在日常的开发中, 原型看着是一个离我们很遥远又很近的一个东西

一、

为什么要用原型【好处】

原型上所有的方法和属性都可以被构造函数【实际开发原型时主要共享“方法和所有实例公用的引用属性”】的实例共享,那为什么要共享呢?先来看一个案例

没有用原型会有什么问题?

不使用原型会带来大量的空间浪费。

使用原型可以解决所有实例上的方法,还有所有实例上的共同属性都可以放到原型上去定义

认识函数+原型定义

函数也是一个对象,当真正开始执行函数,执行环境(开发时为浏览器或控制台)会为函数分配一个函数对象变量空间函数对象空间,函数对象变量用函数名表示,存在栈空间中,函数对象空间是在堆中开辟的一个内存空间,这个空间中有一个默认的 prototype 属性,这个 prototype 属性就是一个原型对象属性【也叫对象变量】

函数和构造函数的区别:当通过 new 构造函数() 时,此刻这个函数就是构造函数【日后会演变成 TS 类的构造器】

定义:原型 prototype 是定义在函数上的,它由 JS 自动分配给函数的一个可以被所有构造函数实例的对象变量所共享的对象变量【也叫对象属性】

原型也叫原型对象属性

当我用一个对象去访问一个属性的时候,它首先会从对象的实例上去查找是否存在这个属性,如果存在,它会直接输出;如果不存在,那么将去原型上查找。

对象的改变是发生在对象创建之后

如何访问原型对象空间上的属性和方法

  • 构造函数所有实例对象都可以访问对象空间上的属性和方法(每一个实例都有默认的proto属性),这个proto属性指向原型对象空间
  • 关于 __proto__new 在创建新对象的时候,会赋予新对象一个属性指向构造函数的 prototype 对象空间,这个属性就是 __proto__
  • 可以直接通过 构造函数.prototype 对象属性来访问原型对象空间上的属性和方法。

构造函数

构造函数实例【也叫对象】如何访问原型对象空间上的属性和方法

  • 构造函数实例访问一个属性和方法,首先从实例空间中查找【当执行环境执行 new 构造函数()时,构造函数中通过 this 定义的属性和方法会分配在这个空间中】,如果找到该属性和方法,就停止查找,表示找到了;如果没有找到,就继续在该实例的原型对象空间中去查找该属性和方法【实例中默认的 proto对象 属性指向原型对象空间】
  • 实例正是借助自身的 __proto__对象属性 来查找原型对象空间中的属性和方法,有点像儿子去和爸爸要他没有的东西一样。

增加或修改原型对象的属性或方法后,所有的实例/对象将可以立即访问的到【但创建实例后再覆盖原型除外】

js

高频面试题:创建实例后再覆盖原型,实例对象无法访问到,为什么?

js

思考题:QQZhangSan.__proto__.show()QQZhangSan.show() 输出的结果完全一样吗?为什么呢?

object.prototype

二、

1.

2.

3.

三、

1.

2.

3.

四、

1.

2.

3.

五、

1.

2.

3.

八、结束语

彩蛋 One More Thing

(:往期推荐

(:番外篇

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/FrontEnd/Practice/001.html b/column/FrontEnd/Practice/001.html index ac63ac47..038813dd 100644 --- a/column/FrontEnd/Practice/001.html +++ b/column/FrontEnd/Practice/001.html @@ -1377,7 +1377,7 @@ display: flex; align-items: flex-end; }

三、🌔 结果展示

到这里,我们就基本完成了整张网页的绘制。现在,我们用一张动图,来看下实现效果:

[video(video-XySVuLRG-1631329534132)(type-csdn)(url-https://live.csdn.net/v/embed/176793)(image-https://vedu.csdnimg.cn/c8f854d3135b423facf50be37c550d66/snapshots/8d7fa6159fb74a3b9215ae36e2c4609a-00002.jpg)(title-中秋明月结果演示)]

四、🌓 结束语

好了,到这里,关于《水调歌头》的内容呈现就已经结束啦!同时也提前祝大家中秋快乐呀~🥂🥂

☪️ 彩蛋 One More Thing

(:素材获取

- + \ No newline at end of file diff --git a/column/FrontEnd/React/001.html b/column/FrontEnd/React/001.html index 2c2358c7..8ffe4517 100644 --- a/column/FrontEnd/React/001.html +++ b/column/FrontEnd/React/001.html @@ -825,7 +825,7 @@ } export default TodoList;

同样地,我们先把 handleInputChangehandleBtnClickhandleItemDelete 这三个事件给抽离出来。

其次呢,我们把 this.state.list.map() 给单独出来形成 getTodoItem() 方法,并使用 {this.getTodoItem()} 进行调用。

最后,我们分别对事件中的 this.setState({}) 进行升级改造,将当前所有事件中的所有数据都封装在一个函数内。

🌠 四、围绕 React 衍生出的思考

上面我们基本完成了对 TodoList 功能的开发。那么现在,我们将围绕着我们所学的,来衍生出 react 的一些番外的知识点。具体如下:

🌌 五、结束语

在上面的文章中,我们学到了关于 react 的一些基础知识。除此之外呢,我们还对 TodoList 进行了基础编写和进阶操作编写。与此同时,我们还围绕 React 衍生出了一些思考。不知道小伙伴们是否对 react 有一些了解了呢?

- + \ No newline at end of file diff --git a/column/FrontEnd/React/002.html b/column/FrontEnd/React/002.html index 034031f7..80464946 100644 --- a/column/FrontEnd/React/002.html +++ b/column/FrontEnd/React/002.html @@ -380,7 +380,7 @@ } export default App;

此时浏览器的运行效果如下:

css动画进阶探索

对于这种类型的动画来说,我们通过 TransitionGroup 对外层进行包裹,之后通过 CSSTransition 对里层进行包裹,进而达到我们最终的效果。

📮 六、结束语

在上面这篇文章中,我们讲解了 react 中的 props ,同时,还简单的了解了虚拟 DOM 的内容。除此之外呢,还学习了 ref 的使用,以及 react 中的酷炫的过渡动画。当然,最为重要的一点是, react 中的生命周期函数

那到这里, react 的进阶知识讲到这里就结束了。不知道小伙伴们对 react 是否又有进一步的认识呢?

🗳️ 彩蛋

- + \ No newline at end of file diff --git a/column/FrontEnd/React/003.html b/column/FrontEnd/React/003.html index 3abe20ba..2084864f 100644 --- a/column/FrontEnd/React/003.html +++ b/column/FrontEnd/React/003.html @@ -1471,7 +1471,7 @@ const store = createStore(reducer); export default store;

我们将 reducer 中存放的内容进行深拷贝,并把它传回给 store 。这样,就形成了一个数据传递的闭环。


最后,我们来看一下浏览器显示的效果:

React-Redux

相比于使用中间件来说, React-Redux 的使用更加地直观简洁。在实际项目中,不管是 redux 中间件,还是 react-redux ,都值得拿来做状态管理。

那么要注意的是,redux 中间件和 react-redux 之间,各自在使用过程中不同的点,区分好即可。至于在项目中使用哪一种类型,就依据当下的项目场景去决定就好啦!

🚦 十一、结束语

在上面的文章中,我们讲解了 Redux 设计和使用的三项原则,同时,也讲解了 Redux 中的一些核心 API 。除此之外呢,我们还学习了 redux 的中间件, redux-thunkredux-saga 。同时,还学习了另外一个做状态管理的内容, react-redux

到这里,关于 redux 的内容就介绍完毕啦!不知道大家是否对 redux 又有了新的了解呢?

🐣 彩蛋 One More Thing

(:往期推荐

👉初探 react,用 react 实现一个 todoList 功能

👉react 只停留在表层?五大知识点带你梳理进阶知识

- + \ No newline at end of file diff --git a/column/FrontEnd/React/004.html b/column/FrontEnd/React/004.html index bcb7c7b0..0f8e1500 100644 --- a/column/FrontEnd/React/004.html +++ b/column/FrontEnd/React/004.html @@ -3107,7 +3107,7 @@ </Suspense> </Router> }

React 中,我们可以直接用 lazy() 包裹,对页面的内容进行懒加载。当然,还有另外一种情况是,加载类似于首页初次加载页面 Loading 的那种效果,在 react 中可以使用 <Suspense> 来解决。

🗞️ 四、结束语

在上面的文章中,我们讲解了 react 的基本使用以及高级特性。同时,还讲解了 react 的周边插件, ReduxReact-router

前端在做 react 的项目时,总是脱离不开以上文章所涉及到的知识点,唯一的区别在于基本使用的内容用的较多,而高级特性的使用场景相对会少一些。

希望通过上文的讲解,小伙伴们有所收获 🥂

- + \ No newline at end of file diff --git a/column/FrontEnd/React/005.html b/column/FrontEnd/React/005.html index e8a9c8dc..3605806f 100644 --- a/column/FrontEnd/React/005.html +++ b/column/FrontEnd/React/005.html @@ -1489,7 +1489,7 @@ } export default useAxios

这样,才不会出现死循环地一直翻滚的对接口发送数据请求

五、🔍 结束语

在上面的文章中,我们首先认识了 hooks 的基本概念,接着,我们重点阐述了 state hookeffect hook ,同时,我们也简单地了解了其他几种 hooks 。最后,谈到了 react-hooks 在组件逻辑复用方面的贡献,以及 react-hooks 需要注意一些事项。

到这里,关于 react-hooks 的介绍就结束啦!不知道大家对 react-hooks 又有了一些新的了解呢?

🐣 彩蛋 One More Thing

(:往期推荐

react 专栏戳这里 https://juejin.cn/column/7018019097656950815

- + \ No newline at end of file diff --git a/column/FrontEnd/Translation/001.html b/column/FrontEnd/Translation/001.html index c820ac9b..df01fc67 100644 --- a/column/FrontEnd/Translation/001.html +++ b/column/FrontEnd/Translation/001.html @@ -163,7 +163,7 @@ result.should.be.true; }) }

现在,大家可以看到,我们将在测试用例中导入 saveData 函数,而不再使用一个全局的 require 。同时,我们还将使用一个自定义返回的对象,来覆盖 dbdriver 在文件中的中 require 调用。从根本意义上来说,我们没有更改到原始代码,但是这个版本的 saveData 将使用我们残留下来的驱动程序,而不是原来的驱动程序。

在上面的例子中,如果你使用的是 browsify ,那么有一个 proxyquire 的版本你可以使用它。点击这里进行查看

当然,还有另外一种情况是,如果你是在 TypeScript 中使用,那么可以访问这两个网址: https://inversify.io/ https://github.com/typestack/typedi 。使用起来肯定没有那么简单,但这两个网址提供了一个极度兼容 TypeScriptAPI

小知识补充:

[1] : override (sth1) with (sth2) 用 sth2 覆盖 sth1

[2] : stub 作名词时表示残余部分,+ed 后为 stubbed,当形容词使用,表示残留的。

[3] : browsify 是一个 npm 包

结束语

依赖项注入是一个非常好用的工具,它被许多开发人员严重忽视,尤其是在单元测试的时候。不可否认的是,它会在帮助我们编写可扩展且可靠的代码时创造一些奇迹。因此,这非常值得我们去尝试。

JavaScript 中动态的类型和行为是值得我们去做更多尝试的理想选择。所以,多去留意 JS 中的动态美!

JavaScript 中你最喜欢的 DI 库是什么呢?最重要的一点是,你是考虑使用 DI 库进行编码(不理想情况),还是考虑在编写测试代码的时候去构建 DI 呢(最佳情况)?(这句话中的所有 DI 都翻译为依赖项注入

小知识补充:

[1] : dipping your toes into the DI waters 柯林斯词典中将其译为 稍加尝试/谨慎尝试

[2] : 第一部分的 DI water 表示去离子水,第二部分的 DI 是依赖项注入的缩写

- + \ No newline at end of file diff --git a/column/FrontEnd/TypeScript/001_tsIntro.html b/column/FrontEnd/TypeScript/001_tsIntro.html index c04dac06..3a68dfb2 100644 --- a/column/FrontEnd/TypeScript/001_tsIntro.html +++ b/column/FrontEnd/TypeScript/001_tsIntro.html @@ -1243,7 +1243,7 @@ </script> </body> </html>

大家可以看到,如果是在没有使用 webpack 等打包工具的情况下,那么我们需要使用 cdn 的方式去引入一个 require 的库,以便于后续可以使用 require 这种语法。

最终我们来看下浏览器的显示效果。如下图:

展示效果

可以看到,最终展示除了我们想要的效果。那在上面中,我们就简单了解了在 TypeScript 中,如何通过 import 语句来对模块进行拆分和组合。

十四、结束语

关于 ts 的入门讲到这里就结束啦!希望大家能对 ts 有一个简单的认识!

如果这篇文章对你有用,记得留个脚印 jio再走哦~

彩蛋 One More Thing

(:专栏直通车

专栏点这里 👉https://juejin.cn/column/6979926803238354952

(:番外

注:这篇文章是对上一篇文章的补充,增加了一些进阶语法。

以上就是本文的全部内容,我们下期见!🥂🥂🥂

- + \ No newline at end of file diff --git a/column/FrontEnd/TypeScript/002_tsDecorator.html b/column/FrontEnd/TypeScript/002_tsDecorator.html index ddb8c757..7bb2c08e 100644 --- a/column/FrontEnd/TypeScript/002_tsDecorator.html +++ b/column/FrontEnd/TypeScript/002_tsDecorator.html @@ -385,7 +385,7 @@ test.getName(); // userInfo.name 不存在 test.getAge(); // userInfo.age 不存在 test.getGender(); // userInfo.gender 不存在

在上面的代码中,我们做的是捕获异常的一个功能。通过封装 @catchError 装饰器,来对我们最终使用的三个方法,getNamegetAgegetGender ,对这三个方法进行异常捕获

以上算是对装饰器的一次小小的实践,后续深入学习可以再参考一些书籍去多练习。

😏 四、结束语

在上面的文章中,我们讲解了装饰器中最基础的类装饰器,以及类装饰器中的 4 中其他类型的装饰器。最后,我们还用了一个小例子去简单地了解了,装饰器在实际应用中的一些操作。

到这里,关于装饰器的学习就接近尾声啦!不知道小伙伴们对装饰器又有了一些新的了解呢?

如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😉

我们下期再见!👋👋👋

🥳 往期推荐

🛵TypeScript,从 0 到入门带你进入类型的世界

- + \ No newline at end of file diff --git a/column/FrontEnd/TypeScript/003_TSIntro2.html b/column/FrontEnd/TypeScript/003_TSIntro2.html index 1e343c35..134aa444 100644 --- a/column/FrontEnd/TypeScript/003_TSIntro2.html +++ b/column/FrontEnd/TypeScript/003_TSIntro2.html @@ -19,7 +19,7 @@
Skip to content

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/FrontEnd/VUE/001.html b/column/FrontEnd/VUE/001.html index bed95a52..9d87d1a7 100644 --- a/column/FrontEnd/VUE/001.html +++ b/column/FrontEnd/VUE/001.html @@ -2141,7 +2141,7 @@ // 可以访问组件实例 this }, };

四、结束语

以上文章总结了 vue 的基本使用以及 vue 的高级特性,还有概括了 vue 的周边插件 vuexvue-router 的一些常见知识,融合大量案例进行讲解。

前端在做 vue 的项目中,总是脱离不开以上文章所涉及到的内容,唯一的区别在于用的多和用的少的问题。

希望通过以上文章的讲解,小伙伴们能有所收获 🥂

- + \ No newline at end of file diff --git a/column/FrontEnd/VUE/002.html b/column/FrontEnd/VUE/002.html index e0691d6d..808f2ae7 100644 --- a/column/FrontEnd/VUE/002.html +++ b/column/FrontEnd/VUE/002.html @@ -361,7 +361,7 @@ }; }, });

综上可以得出,对于一个项目来说,尤其是代码量越多,逻辑越复杂的, Composition API 的优势会更加明显。那对于一个项目来说,我们应该在这两者中如何抉择而选择更好的方案呢? 接着我们继续往下看。

(2)Composition API 和 Options API 如何选择?

通过上面的分析我们可以知道, Composition API 虽然好用,但也不能乱用。因此,对于 Composition APIOptions API 的使用,主要有以下几点建议:

(3)别误解 Composition API

很多小伙伴在没学 vue3 之前,就依稀有听到 Composition API 的声音,这个时候就会使得很多人觉得,要想学会 Vue3 ,就得先学会 Composition API

其实……不是这样的。

Composition API 属于高阶技巧并不是学基础时必须要会的内容

正如上面所演示的内容, Composition API 的出现是为了解决复杂业务逻辑而设计,而不是为了学基础而设计的。

所以说,对于小白学 vue3 时,需要先学会 vue3 的基础,再来学 Composition API ,这样的学习路线更为合理。

四、🙃 结束语

vue3 确实解决了 vue2 的很多问题,上文所描述的也只是冰山一角。但并没有说 vue3 出了就是 vue3 最好, vue2 不用了。因为 vue3 确实解决了一些问题,但同时也带来了一些问题,所以说,两者更多的是一个相辅相成的结果。

关于 vue3 的超入门知识就讲到这里啦!希望对大家有帮助~

- + \ No newline at end of file diff --git a/column/FrontEnd/VUE/003.html b/column/FrontEnd/VUE/003.html index 9765be94..a6cfe094 100644 --- a/column/FrontEnd/VUE/003.html +++ b/column/FrontEnd/VUE/003.html @@ -529,7 +529,7 @@ }, } </script>

此时浏览器的显示效果如下:

mousePosition

了解完 ref 后,我们来实现这个功能看起来会清晰很多。我们先通过 refxy 做响应式操作,之后通过 .value 来修改值,最终达到时刻获取鼠标定位的效果。同时,如果我们时刻保持着鼠标移动时不断改变值,这样子是非常耗费性能的。所以,我们可以通过一个按钮,来随时控制它的出现与隐藏。

大家可以发现,当隐藏的时候,随后会触发 onUnmounted 生命周期组件内容随之被销毁。也就是说,使用的时候调用,不使用的时候及时销毁,这样子可以很大程度上提升性能

三、🙅‍♀️ 结束语

通过上文的学习,我们可以知道, reftoReftoRefsvue3Composition API 的新特性,且 vue3 一般通过 reftoReftoRefs实现数据响应式。有了这三个内容,实现数据响应式看起来方便许多,而不再像 vue2 中那种处理起来很困难。

到这里,关于 reftoReftoRefs 的内容就讲完啦!希望对大家有帮助!

- + \ No newline at end of file diff --git a/column/FrontEnd/VUE/004.html b/column/FrontEnd/VUE/004.html index 2355f41d..03b52fd0 100644 --- a/column/FrontEnd/VUE/004.html +++ b/column/FrontEnd/VUE/004.html @@ -919,7 +919,7 @@ app.config.globalProperties.customProperty = () = {} app.mount('#app')

(2)常见配置更新

1)全局配置:Vue.config->app.config

2)全局注册类 API

3)行为扩展类 API

六、📮 结束语

到这里,碎碎念一波!在学习过程中,要明白 watchwatchEffect 的不同之处,还要知道 setup 如何获取组件实例,这其中谈论的就是关于 this 的问题。

最后的最后,就是 Vue3 为什么比 Vue2 快,涉及到6 个性能优化的方法,学有余力之余,尽量用在线网站演示一波。随之,紧跟着 vue3 的步伐, vite 也成为了很多开发人员在开发环境中使用的工具。还有就是,解决全局污染等各种问题, Vue3 对全局注册 API 做出的改变。

一波碎碎念结束, vue3 的进阶新特性讲解就结束啦!如有疑问欢迎提issue勘误~

- + \ No newline at end of file diff --git a/column/FrontEnd/VUE/005.html b/column/FrontEnd/VUE/005.html index 0a0fd166..f5fc1468 100644 --- a/column/FrontEnd/VUE/005.html +++ b/column/FrontEnd/VUE/005.html @@ -439,7 +439,7 @@ margin-top: 60px; } </style>

最终浏览器的显示效果如下:

泛型改造异步加载组件

通过代码我们可以发现,用泛型来改造组件,会使得该组件的可扩展性更强ts 这么好的语言谁能不爱呢对吧!

三、📚 结束语

到这里,对于 vue3 开发鼠标追踪器和异步加载组件的讲解就结束啦!在这篇文章中,我们学会了用 vue3 的新特性来实现鼠标追踪器和异步加载组件,同时,我们还使用了 ts 中的泛型和接口,来改造异步加载组件,使其扩展性更强。

vue3 持续学习,更新永不停歇……我们下期见!🥂 🥂 🥂

- + \ No newline at end of file diff --git a/column/FrontEnd/VUE/006.html b/column/FrontEnd/VUE/006.html index 667257b4..e6f8bad3 100644 --- a/column/FrontEnd/VUE/006.html +++ b/column/FrontEnd/VUE/006.html @@ -565,7 +565,7 @@ font-size: 6rem; } </style>

此时我们再将 DogShow.vue 的接口进行修改,让其变成一个无效的 API。代码如下:

js
const rawData = await axios.get('https://dog.ceo/api/breeds/image');
const rawData = await axios.get('https://dog.ceo/api/breeds/image');

接下来我们就来看一下浏览器的运行效果:

如何抓取错误

大家可以看到,修改成无效的 API 后,狗狗的图片也不显示了,最后最上方就是通过 onErrorCaptured 这个生命周期捕捉到的错误,清晰明了。

三、🖐️ 结束语

到这里, teleportSuspense 的内容就讲解结束啦!相信大家对传送门的神奇之处也有了一定的了解,对 Suspense 的独到之处也感受了一番。

vue3 持续学习,更新永不停歇……

- + \ No newline at end of file diff --git a/column/FrontEnd/VUE/007.html b/column/FrontEnd/VUE/007.html index d5972a4f..3799d404 100644 --- a/column/FrontEnd/VUE/007.html +++ b/column/FrontEnd/VUE/007.html @@ -49,7 +49,7 @@ https://github.com/xxx/yyy 前端跳转,不刷新页面 https://github.com/xxx/yyy/zzz 前端跳转,不刷新页面

3、history 的 API

下面阐述几种 HTML5 新增的 history API具体如下表:

API定义
history.pushState(data, title [, url])pushState 主要用于往历史记录堆栈顶部添加一条记录。各参数解析如下:①data会在 onpopstate 事件触发时作为参数传递过去;②title为页面标题,当前所有浏览器都会忽略此参数;③url为页面地址,可选,缺少时表示为当前页地址
history.replaceState(data, title [, url])更改当前的历史记录,参数同上; 上面的 pushState 是添加,这个更改
history.state用于存储以上方法的 data 数据,不同浏览器的读写权限不一样
window.onpopstate响应 pushState 或者 replaceState 的调用

4、history 的特点

对于 history 来说,主要有以下特点:

5、存在问题

对于 history 来说,确实解决了不少 hash 存在的问题,但是也带来了新的问题。具体如下:

6、两者选择

下面我们再来介绍下在实际的项目中,如何对这两者进行选择。具体如下:

🎻 四、结束语

对于 hashhistory 来讲,要清楚两者的区别以及两者各自的使用场景,还有各自的使用特点和优缺点。以上文章只是对前端路由原理的浅谈,希望对大家有帮助~

另下方第三个彩蛋放了一篇关于实现 vue-router 的文章,学有余力的小伙伴有需要自取 o!

🐣 彩蛋 One More Thing

🏷️ 参考资料

jarvis👉在 SPA 项目的路由中,注意 hash 与 history 的区别

vue-router 官方文档 👉vue-router 的两种模式

值得一看 👉从使用到自己实现简单 Vue Router 看这个就行了

- + \ No newline at end of file diff --git a/column/FrontEnd/VUE/008_VUE3API.html b/column/FrontEnd/VUE/008_VUE3API.html index 6a4f30ff..b06d2a60 100644 --- a/column/FrontEnd/VUE/008_VUE3API.html +++ b/column/FrontEnd/VUE/008_VUE3API.html @@ -19,7 +19,7 @@
Skip to content

封面图

📍前言

最近在一次理解vue项目的代码时,发现周一对好多API都不太熟悉。这间接导致的问题是,代码理解速度要比平常要慢很多。于是乎,赶忙把vue API的学习提上了日程。

在下面的文章中,将地板式地扫盲vue3文档中API模块的所有内容,融入周一的理解进行深入介绍。下面就来一起看看吧~🍬

一、🖇框架搭建

1、关于文档

首先附上官方文档的具体材料:https://cn.vuejs.org/api/

2、VUE3 API整体盘点

vue3的全新API中,有部分在vue2的基础上沿用了。还有另外一部分,是vue3所新增加的。我们先来看vue3 API文档主要包含哪些内容?

vue3 API主要包含以下六个部分:

  • 全局API —— 全局会用到的API
  • 组合式API —— vue3所拥有的组合式API
  • 选项式API —— vue2所拥有的选项式API
  • 内置内容 —— 指令、组件、特殊元素和特殊属性
  • 单文件组件 —— 语法定义、<script setup>和CSS功能
  • 进阶API —— 渲染函数、服务端渲染、TS工具类型和自定义渲染

vue3 API盘点

下面将依据上面提到的六大点内容,来进行相应的剖析和讲解。

二、🎨全局API

vue3的全局API包含两个部分:应用实例和通用API。那它们各自都有哪些内容呢?

1、应用实例

02_应用实例

2、通用API

02_通用

三、🚲组合式API

谈到vue3 ,相信大家最为熟悉的就是 composition API 了,也就是 组合式 API 。那么,vue3组合式 API 都给我们带来了什么呢?

1、setup

01_setup

2、响应式:核心

02_响应式核心

3、响应式:工具函数

03_响应式工具函数

4、响应式:进阶

04_响应式进阶

5、生命周期钩子

05_生命周期钩子

6、依赖注入

06_依赖注入

四、🌠选项式API

选项式APIoptions API 。可能有的小伙伴会觉得它在 vue2 项目下会更为常见一些。但在 vue3 项目中,也是有一些 选项式API 值得我们去挖掘的。那都有哪些内容呢,我们来一探究竟。

1、状态选项

01_状态选项

2、渲染选项

02_渲染选项

3、生命周期选项

03_生命周期选项

4、组合选项

04_组合选项

5、其他杂项

05_其他杂项

6、组件实例

06_组件实例

五、🏕内置内容

vue3 的内置内容包括指令组件特殊元素element特殊属性attributes。如果要谈在什么场景下会用到内置内容,那周一可能觉得,在一般的 vue 项目开发中,基本都会用到内置内容。较为常见的是用v-if和v-else-if来判断什么时候显示某个组件,什么时候不显示某个组件。

还有像 v-modelv-onv-for 等指令,都是在 vue 项目中非常高频率使用的指令。那 vue3 的内置内容都还有哪些东西呢?请看下方介绍。

1、指令

01_指令

2、组件

02_组件

3、特殊元素

03_特殊元素

4、特殊属性Attributes

04_特殊属性Attributes

六、📸单文件组件

对于 vue 来说,相信大家都会非常熟悉它的组件化思想,似乎有一种理念是:万物皆可组件。那对于一个组件来说,我们都需要了解它的什么内容呢?比如,我们写的 <template> 是什么,用 <script setup><script lang="ts"> 都分别是什么含义,<style> 用了 scoped 是什么意思,:slotted 插槽选择器又在什么情况下使用呢?我们一起来一探究竟。

1、SFC语法定义

01_SFC语法定义

2、单文件组件script setup

02_单文件组setup

3、css功能

03_CSS功能

七、📈进阶API

上面我们了解了 vue3 的基础API,准确来说,上面的 API 可以解决实际工作中 80% 的问题。那下面,我们就再来看一些较为进阶的 api 操作。下面所涉及到的这些 API ,更多的是可以在某些定制化的场景下,做一些高阶的操作。比如:我们可以在一个 headless 组件里,用 renderh() 函数,来渲染自定义的页面。那 进阶 API 都还有哪些东西呢,来看下面的内容。

1、渲染函数

01_渲染函数

2、服务端渲染

02_服务端渲染

3、TypeScript工具类型

03_TypeScript工具类型

4、自定义渲染

04_自定义渲染

八、🛒结束语

到这里,我们也就讲完了 vue3 API 所有的知识点。个人认为,原理知识的学习,是为了更好的将其运用到项目中。所以在学完以上内容后,不妨可以进一步将其运用到项目里,总结出工作中的最佳实践。

文章根据周一的理解做了一些输出,有观点不当之处欢迎交流~

🐣彩蛋 One More Thing

思维导图github地址:https://github.com/mondaylab/vue3-api

vue3 入门指南文章推荐:焕然一新的 Vue 3 中文文档要来了🎉

以上就是本文的全部内容,我们下期见!🍻🍻🍻

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/FrontEnd/VUE/009_vitepress_blog.html b/column/FrontEnd/VUE/009_vitepress_blog.html index 7da8b766..1dd268b4 100644 --- a/column/FrontEnd/VUE/009_vitepress_blog.html +++ b/column/FrontEnd/VUE/009_vitepress_blog.html @@ -671,7 +671,7 @@ git commit -m "xxx" git push origin HEAD:refs/for/master sh ./vitepress-starter/deploy.sh

最后,可以在仓库的 Setting → Pages 中看到最后的地址:

部署图片

访问上面圈中的地址,就可以正常进行访问啦~

最后,放上此次搭建的demo地址,可以直接fork,然后将相关的文字等内容进行修改即可。

具体地址戳:https://github.com/Jacqueline712/vitepress-demo-mondaylab

五、🎙结束语

在搭建博客的过程中,我突然意识到,文档在日常开发中的使用还蛮广泛的。小到一个组件库的文档说明,大到一个产品的使用说明等等,都需要文档。

这篇文章也从0到1讲解了用vitepress搭建一个博客的全过程,希望对大家有帮助~

如果有一些好玩的周边插件,记得评论区分享呀~

Ending,我们下次见!🍻🍻🍻

💡参考资料

如果想要从vuepress直接升级为vitepress,可以参考:

官方文档:

其他:

- + \ No newline at end of file diff --git a/column/FrontEnd/VUEPrinciple/001.html b/column/FrontEnd/VUEPrinciple/001.html index 89a5c801..92b74d2d 100644 --- a/column/FrontEnd/VUEPrinciple/001.html +++ b/column/FrontEnd/VUEPrinciple/001.html @@ -461,7 +461,7 @@ // 测试 data.info.address = '上海'; // 深度监听 data.nums.push('神游'); // 监听数组

此时浏览器的打印效果如下:

监听数组

我们可以看到,两个数据对应的视图都更新了。通过对数组原型的重新定义,我们就让 Object.defineProperty() 实现了监听数组的能力。

(3)几个缺点

在让 Object.defineProperty() 实现响应式功能以后,我们来总结下其存在的几个缺点:

1)深度监听,需要递归到底,一次性计算量大

在遍历对象或数组时,需要进行深度监听,即需要递归到底,这会使得一次性计算量非常大。(这个问题在 vue3.0 中已经解决,其解决原理是不一定要一次性递归,而是可以我们什么时候用,什么时候再递归。这个将放在后面的文章中讲解)

2)无法监听新增属性/删除属性

Object.defineProperty() 在进行新增属性和删除属性时,视图是无法进行更新的,也就是数据监听不到,这一点在平常的开发中需要特别注意!否则有时候我们在取数据时总会莫名其妙地都不知道自己错在哪里。通常解决这个问题的方法是,使用 Vue.setVue.delete 来进行新增属性删除属性,这样就可以解决数据无法监听的问题。

3)无法原生监听数组,需要特殊处理

Object.defineProperty() 这个 API 本身无法监听原生数组,需要通过重新定义数组原型的方式,来对数组进行数据监听。

四、结束语

对于 vue2.x 的响应式原理讲到这里就结束啦!从上面的分析中我们可以发现, Object.defineProperty() 有它一定的好用之处,但同时也有一些缺点存在。因此 Vue3.0 用了 Proxy 来解决上述缺点中存在的问题,但是呢, proxy 到现在其实也还没有推广开来,因为 proxy 有兼容性的问题存在,如无法兼容 IE11 等问题,且 proxy 无法 polyfill ,所以 vue2.x 很长一段时间内应该还会存在。因此,对于 vue2.xvue3.0 来说,这两者都是得学的,而不是说出了 vue3.0 就不学 vue2.x 了,对于这两者来说,更多的是相辅相成的一个结果。

闲谈到此结束,对于 vue 原理的学习有深深感受到造轮子的快乐,但是啃源码在开始学习时确实会比较枯燥。希望再接再厉,争取啃下更多 vue 的源码,读懂更多原理!

- + \ No newline at end of file diff --git a/column/FrontEnd/VUEPrinciple/002.html b/column/FrontEnd/VUEPrinciple/002.html index 3a0f53ff..19a46113 100644 --- a/column/FrontEnd/VUEPrinciple/002.html +++ b/column/FrontEnd/VUEPrinciple/002.html @@ -831,7 +831,7 @@ } } }

我们先来看两张图:

updateChildren图示1

updateChildren图示2

大家先看图 1, updateChildren 要做得事情就是,将新旧节点进行对比,如果相同则不进行更新,如果不同则对其进行更新操作。

再看图 2,而更新的方式就是,通过对oldStartIdxnewStartIdxoldEndIdxnewEndIdx这四个值进行比较,来得出是否需要更新操作。

那这四个值如何进行比较呢?接下来我们继续看。

阅读源码我们可以分析出,通过对4 种类型的节点进行比较,来判断如何更新节点

第一种,旧的开始节点 oldStartIdx 和新的开始节点 newStartIdx 比较。第二种,旧的开始节点 oldStartIdx 和新的结束节点 newEndIdx 比较。第三种,旧的结束节点 oldEndIdx 和新的开始节点 newStartIdx 比较。第四种,旧的结束节点 oldEndIdx 和新的结束节点 newEndIdx 比较。

如果以上这四种比较都没有命中,则拿取新节点的key ,之后将这个 key 查看是否对应上 oldCh 中某个节点的 key如果没有对应上,则直接重建元素如果对应上了,还要再判断 selkey 是否相等,如果相等,则执行 patchVnode 函数,如果不相等,那跟前面一样,也只能重建元素

四、结束语

vdom 的核心概念主要在 hvnodepatchdiffkey 这几个内容,个人觉得,整个 diff 的比较都在围绕着这几个函数进行,所以了解这几个核心概念很重要。同时,vdom 存在的另一个更重要的价值莫过于数据驱动视图了, vdom 通过控制 DOM 的操作来使得数据可以去驱动视图

关于虚拟 DOM 和 diff 的讲解到此就结束啦!希望对大家有帮助~

- + \ No newline at end of file diff --git a/column/FrontEnd/VUEPrinciple/003.html b/column/FrontEnd/VUEPrinciple/003.html index f66e8046..d6713320 100644 --- a/column/FrontEnd/VUEPrinciple/003.html +++ b/column/FrontEnd/VUEPrinciple/003.html @@ -353,7 +353,7 @@ }, }; </script>

我们通过给获取 DOM 元素的代码外面再嵌套一层 $nextTick 函数,来达到我们想要的效果。在此过程中,当我们点击结束后, data 的值发生变化,此时 $nextTick 会等待DOM 全部渲染完成之后再进行回调。

最终浏览器的打印效果如下:

nextTick2

所以,也就是说, $nextTick 通过汇总 data 的修改,最后再一次性更新视图

这样可以减少 DOM 的操作次数,大大的提高了性能。

3、小结

经过上述一系列的讲解,我们可以把内容分割成以下两个要点:

五、✔️ 结束语

从模板编译,到组件渲染更新过程,我们了解了整个 template 背后的全过程。相信通过本文的学习,大家对模板编译有了一个更深的认识。

关于模板编译的内容就讲到这里啦!如有不理解或文章有误,欢迎提issue勘误~

- + \ No newline at end of file diff --git a/column/FrontEnd/VUEPrinciple/004.html b/column/FrontEnd/VUEPrinciple/004.html index 389bc1c0..5bbd60ea 100644 --- a/column/FrontEnd/VUEPrinciple/004.html +++ b/column/FrontEnd/VUEPrinciple/004.html @@ -225,7 +225,7 @@ } const proxyData = reactive(data)

我们在控制台来验证数据:

proxy

从上图中可以看到,用 proxy 来实现响应式,如果遇到需要深度递归的数组时,它不会像 defineProperty 那样深度递归,它会在什么时候 get ,什么时候再深度递归。本质上来讲就是,你获取到哪一层,那一层才会触发响应式你获取不到的深层,它就不会触发响应式。且从代码中我们可以了解到, Proxy 在修改属性时,如果数据是重复的,则不进行处理。如果数据不重复,再进行处理。这样一来,就极大程度上提高了软件的性能

2、Proxy 总结

现在来对上述 Proxy 的内容做一个总结:

(1)深度监听,性能更好

defineProperty 是一次性递归完成;而 Proxy 是什么时候 get ,什么时候再深度递归

(2)可监听 新增/删除 属性

vue2 中, defineProperty无法新增/删除属性的,需要配合 Vue.setVue.delete 来使用,而在 Vue3 中, Proxy 可以新增和删除属性,无需进行特殊处理。

(3)可监听数组变化

vue2 中,监听数组变化是需要进行特殊处理,且只能一次性深度递归完成。而在 vue3 中,可以监听数组变化,并且是什么时候 get 什么时候再递归,获取不到的深层,不会触发响应式。

3、两者对比

讲到这里,我们再把 vue2 中的 Object.definePropertyvue3 中的 Proxy 做一个对比:

五、🟪 结束语

从某种程度上来说, vue3Proxy 确实带来了一些好处,但同时也带来了一些问题。正因为如此, vue2Object.defineProperty 还会存在很长一段时间。所以,新技术的使用总会经过一个从试用阶段到稳定阶段的过程。

关于 vue3 的响应式原理讲到这里就结束啦!如有疑问欢迎提issue~

- + \ No newline at end of file diff --git a/column/FrontEnd/Webpack/001.html b/column/FrontEnd/Webpack/001.html index 50d66774..04936594 100644 --- a/column/FrontEnd/Webpack/001.html +++ b/column/FrontEnd/Webpack/001.html @@ -967,7 +967,7 @@ }, ]; }

这段代码的意思就是,当用 babel-polyfill 填充低版本浏览器特性的时候,不是把是多有的特性都加进来,而是根据我们的业务代码来决定到底到加什么。

同时, babel-preset 也有很多其他值得学习的配置属性,这里不再进行讲解。大家可以自行到官方文档上进行查看~

📚 十一、结束语

写完这篇文章的时候,突然想起上次面试时的面试官。在最后的反问环节问他关于 webpack 的问题,他说 webpack 一般会让对公司业务很熟悉的员工来处理,毕竟前端工程化不是儿戏。

当时我还没有很大的感触,但现在学到这里突然就想到了那个场景。确实是这样,我这才学了不到它的冰山一角,就已经感到 webpack 的庞大工程了。如果在打包时候,但凡有一个小地方的配置出现问题,就有可能引发整个项目的不可收拾局面。(当然一般情况下不会出现这样的情况,言重了……)

在学习 webpack 的过程中,要明确好自己所使用的 webpack 版本。比如周一刚开始迷迷糊糊的,感觉版本 4 和版本 5 都差不多。但对于 webpack 来说,这完全就是在跟它开玩笑。每一个依赖都有 4 和 5 对应的版本,而不是说想用哪个就哪个。如果胡乱使用的话,无形之中可能会报错到怀疑人生……

因此,确定好此时用 webpack 打包时所使用的版本,并在使用 npm 依赖时也同样要找到对应的版本来进行使用,降低错误的发生。

到这里,关于 webpack 的超入门知识就讲到这里啦!希望对大家有帮助~

本文代码已上传至公众号,后台回复关键词 webpack 即可获取~

🐣 彩蛋 One More Thing

往期推荐

- + \ No newline at end of file diff --git a/column/FrontEnd/Webpack/002.html b/column/FrontEnd/Webpack/002.html index 6a886cab..057b8a97 100644 --- a/column/FrontEnd/Webpack/002.html +++ b/column/FrontEnd/Webpack/002.html @@ -817,7 +817,7 @@ ], }, };

通过配置 imports-loader 以后, webpack 表明,它将会把 js 文件中的 this 指向全部指向 window 全局中。

🎖️ 八、结束语

在今天的文章中,我们学习了使用 Tree Shaking 来优化代码的打包大小,同时,学习了 DevProd 环境下的区分打包,需要明确在这两个模式下各自相同的配置以及不同的配置,分清楚他们之间的关系。

除此之外呢,我们还学会了使用 webpack 来对 js 文件和 css 文件进行代码分割。以及使用 webpack 来对代码进行打包分析和提前加载 preloading

最后,我们还学会了关于 webpack 如何开启浏览器缓存,以及垫片 Shimming 的作用。

关于 webpack 的基础特性和高级特性讲到这里就结束啦!希望对大家有帮助~

如有疑问或文章有误欢迎评论区留言 💬 或加 vx: MondayLaboratory 交流~😉

本文代码已上传至公众号,后台回复关键词 webpack 即可获取~

🐣 彩蛋 One More Thing

(:往期推荐

- + \ No newline at end of file diff --git a/column/FrontEnd/Webpack/003.html b/column/FrontEnd/Webpack/003.html index 06921c7f..ff1bb04b 100644 --- a/column/FrontEnd/Webpack/003.html +++ b/column/FrontEnd/Webpack/003.html @@ -679,7 +679,7 @@ }), ], };

通过以上代码我们可以知道,增加 entryplugins 的配置,来增加多个入口页面,从而达到了多页面应用配置的效果。

🛵 八、结束语

通过上文的讲解,相信大家对 webpack 在一些场景中的实战配置有了一定的了解。上面讲述的也是比较浅显的内容,大家可以根据相对应的知识点,进行知识面的拓宽,以便更好的应用到实际的项目当中。

到这里,关于 webpack 的实战案例配置就讲解结束啦!希望对大家有帮助~

如文章有误或有不理解的地方,欢迎小伙伴们评论区留言哦 💬

本文代码已上传至公众号,后台回复关键词 webpack 即可获取~

🐣 彩蛋 One More Thing

(:往期推荐

- + \ No newline at end of file diff --git a/column/FrontEnd/Webpack/004.html b/column/FrontEnd/Webpack/004.html index 0623ebc6..7467dde3 100644 --- a/column/FrontEnd/Webpack/004.html +++ b/column/FrontEnd/Webpack/004.html @@ -263,7 +263,7 @@ filename: '[name].js', }, };

通过上述代码,我们可以了解到,在(2)中,我们首先需要定义一个类,之后呢,在类中写一个构造器和一个 apply() 方法来调用。然后呢,大家看到(3),通过 require 的方式,来进行 new 实例 ,实例化一个插件,从而在项目中使用这个插件。

最终,我们项目进行打包时,就会生成一个 dist 目录,并且在目录下增加一个 copyright.txt 文件,并且文件中的内容就是 copyright by monday

💹 三、结束语

在上面的文章中,讲解了关于 loader 和 plugin 的基本编写思路,以及如何在项目中对他们进行运用,相信大家对这一块内容有了基础的认识。

到这里,loader 和 plugin 的编写讲解就结束啦!希望对大家有帮助~

如文章有误或有不理解的地方,欢迎小伙伴们评论区留言哦 💬

本文代码已上传至公众号,后台回复关键词 webpack 即可获取~

🐣 彩蛋 One More Thing

(:往期推荐

webpack 入门核心知识 👉不会 webpack 的前端可能是捡来的,万字总结 webpack 的超入门核心知识

webpack 入门进阶知识 👉webpack 入门核心知识还看不过瘾?速来围观万字进阶知识

webpack 实战案例配置 👉万字总结 webpack 实战案例配置

- + \ No newline at end of file diff --git a/column/FrontEnd/Webpack/005.html b/column/FrontEnd/Webpack/005.html index b8dd7f83..c026ca47 100644 --- a/column/FrontEnd/Webpack/005.html +++ b/column/FrontEnd/Webpack/005.html @@ -653,7 +653,7 @@ }; require('./src/index.js') })({"./src/index.js":{"dependencies":{"./message.js":"./src\\message.js"},"code":"\"use strict\";\n\nvar _message = _interopRequireDefault(require(\"./message.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\nconsole.log(_message[\"default\"]);"},"./src\\message.js":{"dependencies":{"./word.js":"./src\\word.js"},"code":"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports[\"default\"] = void 0;\n\nvar _word = require(\"./word.js\");\n\nvar message = \"hello \".concat(_word.word);\nvar _default = message;\nexports[\"default\"] = _default;"},"./src\\word.js":{"dependencies":{},"code":"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.word = void 0;\nvar word = 'monday';\nexports.word = word;"}});

接下来,我们把这个打印结果,放到浏览器上进行检验。检验结果如下:

检验结果

大家可以看到,打包后的结果,在浏览器上成功运行了,并显示除了 hello monday ,至此,说明我们的项目打包成功。

🍓 四、结束语

在上面的这篇文章中,从模块的入口文件分析,再到依赖图谱的解析,最后到生成浏览器所认识的代码,我们了解了打包工具的整个操作流程。

到这里,关于本文的讲解就结束啦!希望对大家有帮助~

如文章有误或有不理解的地方,欢迎小伙伴们评论区留言撒~💬

本文代码已上传至公众号,后台回复关键词 webpack 即可获取~

🐣 彩蛋 One More Thing

(:往期推荐

webpack 入门核心知识 👉不会 webpack 的前端可能是捡来的,万字总结 webpack 的超入门核心知识

webpack 入门进阶知识 👉webpack 入门核心知识还看不过瘾?速来围观万字进阶知识

webpack 实战案例配置 👉[万字总结]webpack 只会基础配置可不行!快来把实战案例配置一起打包带走

手写 loader 和 plugin👉webpack 实战之手写一个 loader 和 plugin

- + \ No newline at end of file diff --git a/column/FrontEnd/YouthCamp/001.html b/column/FrontEnd/YouthCamp/001.html index b2e50cd2..22ef13bc 100644 --- a/column/FrontEnd/YouthCamp/001.html +++ b/column/FrontEnd/YouthCamp/001.html @@ -253,7 +253,7 @@ <track default kind="captions" srclang="en" src="friday.vtt" /> Sorry, your brower doesn't support embedded videos. </video>

🧐 六、HTML 解析

我们来看一下 HTML 是如何进行解析的。

1. DOM 文档对象模型

所谓 DOM ,即对节点的结构化进行表述,并定义了一种方式可以使程序对该结构进行访问,它将 web 页面和脚本语言链接起来。

2. HTML 的解析过程

对于 DOM 树来说,其构建过程如下:

具体如下图所示:

HTML解析

🙃 七、结束语

在上文中,我们了解到了网页的三大元素, HTML 的简介、结构和其解析过程。当然,同样很重要的一点是语义化标签。对于语义化标签来说,它可以很一目了然地让我们知道是什么意思,很大程度上地提升了开发效率。

到这里,关于 HTML 的基础知识讲到这里就结束啦!希望对大家有帮助~

- + \ No newline at end of file diff --git a/column/FrontEnd/YouthCamp/002.html b/column/FrontEnd/YouthCamp/002.html index 9e8c46b0..36cb076e 100644 --- a/column/FrontEnd/YouthCamp/002.html +++ b/column/FrontEnd/YouthCamp/002.html @@ -355,7 +355,7 @@ transform: rotate(360deg); } }

具体显示效果如下:

动画

📰 四、css 精益求精

1. css 调试

(1)审查 css

css 的面板里,可以直接开关、编辑、新增属性的值。如下图所示:

审查css①

(2)理解盒模型

同时,我们来可以通过 layout view 来展示一张选定元素的盒模型示意图如下图所示:

审查css②

2. css 扩展

(1)css 预处理器

另一种组织 CSS 的方法是利用一些对于前端开发者可用的工具,它们让你可以稍微更程式化地 编写 CSS 。预处理工具以你的原文件为基础来进行运行,并将它们转化为样式表代表工具有:

(2)less

这里我们以 less 为例,看看能够为 css 扩充哪些功能。

1)变量,编译后会填充到对应的位置。比如:

变量

2)mixin,类似于函数。比如:

mixin

3. css 革新

随着 CSS 的不断发展,到现在,我们编写样式已经不一定需要写 css 文件了。下面罗列出几种常见的类型:

(1)styled-components 为代表的 css-in-js 方案,通过用 JavaScript 的力量来武装 css

style-components

(2)tailwindcss 为代表的 utility-class 方案,改样式只需要修改 html 文件即可,用有限的选择帮助你定好设计规范

tailwindcss

📑 五、结束语

在上面的文章中,我们从 css 的诞生背景和基础定义入手,先初步认识了 css 。紧接着,介绍了如何能够正确地学习 css ,以及 css 关键的盒模型、文档流、布局、定位等关键概念和相关的 css 属性,并展示了 css 装饰文档的可能性。

最后,我们简略地了解了 css 是如何调试的,以及当今都有什么样的工具可以帮助到我们更好的写 css ,又如何用更好的理念去用 css

到这里,关于 css 的奥秘探索就结束啦!希望文章对大家有帮助~

🐣 彩蛋 One More Thing

(:往期推荐

👉值得关注的 HTML 基础知识

👉你可能对 position 和 z-index 有一些误解

👉谁动了我的选择器?深入理解 CSS 选择器优先级

- + \ No newline at end of file diff --git a/column/FrontEnd/YouthCamp/003.html b/column/FrontEnd/YouthCamp/003.html index 721c956e..6e2ac581 100644 --- a/column/FrontEnd/YouthCamp/003.html +++ b/column/FrontEnd/YouthCamp/003.html @@ -19,7 +19,7 @@
Skip to content

🖼️ 序言

对于开发人来说,不单单要会写代码,有良好的用户体验思想也是非常重要的。毕竟,开发完的内容是要给用户来使用的,而不是自己随心所欲觉得哪里想添加个内容就哪里添加。

因此呢,在下面的这篇文章中,将学习给开发人看的 UI 设计。一起来了解吧~

🎨 一、背景

在讲解本文之前,先给大家抛个问题:前端为何要学习基本的 UI 设计原则和实践套路呢?

1. 想做一个好的作品

  • 入行前端的同学,有不少小伙伴是被其「所见即所得」的开发体验所吸引;此外,就是能够开发一款自己有用、爱用的应用出来,并分享给其他人使用。
  • 而现在市面上,已经有足够多的课程,能够让前端以「全栈」的姿态独立开发一款能用的产品出来。但当页面模块变得复杂起来时,仅仅依赖一些 UI 组件库,已经不能让产品维持在「好用」的状态。
  • 追求极致的「全栈」定义,或许应当包含「设计」的角色。

2. 没有专业 UI

  • 你的团队里可能会有 UI 角色,但不一定专业;
  • UI 给出的设计稿,许多时候只是静态的、仅体现某一交互切面的;
  • 很多交互体验细节,只有在前端摆弄一个 Button 的位置和多场景状态时,才能被捕捉到;
  • 在大厂里,许多 B 端产品时没有专职 UI 的角色的;前端可能要对产品最终呈现出的形态负责。

🧵 二、功能导向

1. 设计中最重要的事

功能导向可以说是设计中最重要的事了,可以说,把功能做好,或许是最重要的设计原则。

2. 例子阐述

我们来看一个例子:

下面先看 Google 近 20 年来首页的变迁,从左到右,分别是 1998、2005、2015 年,如下图所示:

google首页

现在,我们来看 2021 年的,如下图所示:

google首页2021年

大家可以看到,从一开始的内容堆叠,到最后的只显示一个搜索框,把用户最想要的内容显示出来了。或许,这就是功能导向的一个典型例子。

2. 简约设计

有了功能基础之后,我们就可以来画原型了,那么这里我想要介绍的是一些简单的创作工具。

我们可以选择像纸、笔或者excalidraw这样可以立刻上手的工具是比较好的。糙一点的设计笔触可以让你不会过于追求完美,或者说是过于「追求设计」。

我们应该要迅速把框架搭好了,设计细节可以后面再补充。说白了,「功能优先」始终贯穿在设计 & 开发流程中。

当然,你也可以使用如 figmaAxure 之类的更专业的原型设计工具。但作为开发,建议先使用最基本的笔触和组件,克制使用颜色设计简单的、完整的功能优先关注功能。

简约设计

3. 设计简单的、完整的功能

我们在进行功能设计时,要先以 MVP 版本功能来作为设计目标。所谓 MVP ,即 Minimum Viable Product ,即最简化可实行产品。

我们来看一个例子:

  • 一个联系人列表,是否要考虑超过 2000 人的展示情况?如何优化交互?
  • 数据不存在时,根据不同的错误情况,应该如何准备错误信息展示,和用户引导?
  • 一个图片上传模块,其复制粘贴、拖拽、 点击选择文件上传,这些路径是否 MVP 版本都要做,是否都要先做好布局和引导设计?
  • 在开局期间,我们要时刻提醒自己,优先把用户关键路径上的主流场景设计完成,迅速迭代其基本具有的能力。
  • 这就好比开发一个游戏,我们总想着游戏各种花式的玩法。但我们在开发前应该先考虑的点是,如何先让游戏开始,这就是最简单的功能。让游戏开始了,我们才能给后面的内容迭代和升级。

来看一个留言功能,如下图所示:

MVP功能

大家可以看到,短短几句话,简明扼要的概括出来最完整的功能,把 MVP 的内容给体现出来了。

🧶 三、设计原则

1. 层级

(1)层级是什么

  • 层级,是你可能唯一需要关心的原则。
  • 一个产品要好用,就要让用户很容易地,抓到产品重点
  • 在重点里,用户能自在地进入沉浸式阅读、和使用的状态;
  • 当用户想探索其他内容时,ta 能轻松地识别网站的次要板块还有哪些,焦点能迅速转移,并迅速沉浸;
  • 辅助提示信息,精确而又不会打扰各主要模块的呈现。

(2)举例阐述

比如,大家可以来看下面这两个网站。你觉得那张图片展示了更好的阅读体验呢?

层级1

层级2

相信很多小伙伴内心的答案都是第二张图片。在第一张图片当中,内容没有怎么体现出分层,而是一整张图片黑黑白白的,也不知道哪里是重点。而在第二章图片中,明显上面蓝色方框内的内容第一眼就抓住了用户的眼球,很清晰的让用户了解到这张图的用意在哪。

所以你说,哪一张的阅读体验更好呢?

2. 一致性

(1)定义

所谓一致性,指的是用户在站点的各个角落,观察到颜色、间距、阴影、位置、字体和字重的应用,且都在一套有限的框架里,一套能够迅速建立亲切感的框架内。

什么意思呢?

(2)举例阐述

以飞书文档为例,我们来进行一个说明:

当页面中,主要的交互视觉元素都采用同一主题色(图中为蓝色)来表示时,用户可以迅速知道:

  • 页面中有哪些元素是可交互的
  • 我需要的提示信息在哪

飞书文档


再比如下面这张图:

表单控件

在这张图中,表单中 label 和输入框之间、以及输入项之间有序且固定的间距,可以帮助用户迅速识别当前填写的表单项是什么内容、以及稳定地将视线移动到下一个表单项上。

(3)总结

通过上面的例子,相信大家对设计的一致性也有了一定的了解。

所以,能否克制,且重复精确地运用着拟定好的设计体系,会在方方面面上影响着一个站点的质感,同时这也是体现专业性的考量

看下面这张图:

间距配置的合理性

3. 番外 - 《写给大家看的设计书》

这里给大家补充一本书 ——《写给大家看的设计书》,这本书应该是不少人的设计启蒙书。

在这里,我简单介绍下《写给大家看的设计书》四大原则:

  • 对比: 如果两个元素内涵不同,请让它们截然相同;
  • 重复: 设计的视觉要素应当在整个作品中重复出现;
  • 亲密性: 彼此关联的元素应当靠近和放置在一起;
  • 对齐: 任何元素都不能随意安放,应当总是与另外至少一个元素有视觉上的关联。

写给大家看的设计书


这四大原则,就与前面我们总结的两大原则相呼应上了。来看下具体的关联:

  • 层级,就是亲密性+对比的目标。让用户抓重点、切视线,又快又稳。
  • 一致性,就是对齐+重复,克制用户视线所感受的尺度,迅速与网站设计语言建立熟悉感。

书中还有更多关于四原则的解释和其他排版设计的技巧,这里也推荐给大家延伸阅读。

🧷 四、设计体系

1. 布局

(1)居中放

我们先来介绍一个最基本的布局技巧,内容居中放。

如果你是遵循「功能导向」,边开发基础能力边设计迭代的开发过程,那么前期你的功能应当是比较简单的。单列式的居中布局,应该能满足你的需求。

比如像下面这样:

布局居中放①

很多场景下,居中放也是很有意义的。除非大屏浏览是你的核心场景,不然一般来说,你的内容宽度应该在 600 ~ 800px 之间,类似一本书的宽度。

像下面这样:

布局居中放②

(2)多列布局

多列布局的核心也是保持内容的一个合适宽度维持可读性

一般规则是:主要内容列弹性收缩(可以有最小宽度),次要列固定宽度。

如下图所示:

多列布局

2. 间距

(1)间距的定义

保证元素间有基本的间距,是最基本的设计技巧。

如下图所示:

间距

(2)间距的一些规范

现在我们来看一些关于间距的规范。

1)间距——选项

基于 4px 的倍数,设计出数十种间距的选项。如下图所示:

间距——选项

现在,我们来说明一下这十种设计选项的一些具体内容:

  • 设计体系,除了满足「一致性」原则以外,它同时也是帮设计者提前设计好选项
  • 有了这些选项,我们在具体场景中可以逐个尝试,来试出最优解
  • 比起每次都拍脑门决策,现在变成在选项里调优,能极大地加快设计的步伐

来看一个 button 的例子:

button在选项中的应用

大家可以看到,我们把图标以 4px 的倍数进行增长,慢慢地变得越来越饱和,越来越好看。基于 4px 的选项,我们是不是就更加加快了我们的设计步伐了呢。


观察这数十种间距的选项,我们可以发现这是一个类似指数增长的图表📈。这是因为两个相邻间距,在大尺度上,要比小尺度里拉的更开,才能在视线里体现出间距的差距

我们用一张图来比较一下大小尺度里的区别:

小尺度和大尺度的比较

大家先看左边的内容,在小尺度里, 4px 的差距就是 20% 的增幅;再看右边的内容,右图 500px 的尺度中, 20px 的增长只有提升 4% 的效果。

2)间距——多留白些

这是一个间距设计技巧:安排元素时建议先大大的留空,也就是「从松到紧」来调试间距。如下图所示:

间距——多留白些


我们来对上面这组图进行一个比较。

由紧到松类型 👇

先来看一张图:

由紧到松类型

这张图是由紧到松,那么你的思维是「尝试把无关的元素拉开」,而且是「从整体到局部」的 方向,这就不太好操作。

举个例子:

你想先拉开每个段落间距 10px,再调段落内标题与内容的间距 4px,但发现拉的不够开;这时要回过头将段落间间距拉到 20px,这样段落内才好安排 10px 的间距……

由松到紧类型 👇

先来看一张图:

由松到紧类型

由松到紧,这就简单一些:关注的是「哪些元素相关」,把它们拉在一起,然后是「从局部到整体」调优。

一般来说,偏松也比偏紧好。从一开始就留些空间吧。

3)间距——表达关联关系

  • 除了方便阅读,间距也是最合适表达关联关系的工具。
  • 如下图所示,图中的间距差异设计,表明了每个章节的起点,以及标题与段落的关联性

表达关联关系①

  • 同时,如下图所示,挨得太紧的行高和列表项间距,会让用户难以判断阅读时的停顿点在哪,当前列表项是否已经结束。
  • 间距是远比色块边框分界线之类的更适合用来表达关联关系的工具。值得多加练习运用。

表达关联关系②

3. 文字

(1)文字的定义

文本是站点的主要内容载体;字体设计自然也是重中之重。

既然我们在讲设计体系,以一致性为目标。那么同样地,我们也要把站点所使用的字号字重等范围框定在数十个选项中。

数十个是个 magic number,大部分情况下应该都能满足。只要场景够特殊,特殊字体完全可以再加。

(2)文字的一些规范

1)文字——选项设计

相比于间距设计,字号大小我们有一个明显的适合阅读的字号范围,如 12 ~ 20px 。那么我们会更多在这个范围内设置字体选项。

来看下选项设计的 10 大范围,如下图所示:

文字——选项设计

但是呢,仅通过字号来设置层级,很快就会捉襟见肘。因此我们要结合字重 & 颜色(灰度),你会更加地游刃有余。

字重是 css 自带的,用好常用的 3、4 个尺度就好了。

来看一个例子:

字重设计

大家可以看到,在右边的这张图当中,我们适当的使用了字重和颜色,以使得页面的内容更突出,内容更为饱和。

2)文字——对齐

不同字号大小的字体间如何对齐呢?我们应该要基于 baseline 对齐,就是文本的下边缘

baseline 是一个字符的重心;重心对齐了,用户在移动视线时就能有平稳的阅读体验

来看一个例子:

对齐设计

3)文字——行高

基本上,对于所有的文本设计来说,其意图都是为了保持良好的阅读体验,那么行高也不例外。

具体到设计哲学,就是:行高和字号大小大致成反比,目标是用户在视线换行时有稳定的下移体验。

26-文字——行高

4. 色彩

现在,到颜色部分了,谁不爱颜色呢?同样地,与上面一样的归纳步骤,我们来对颜色进行一个归纳。

(1)颜色选项——灰色

在你的色彩库中,应该要有10 种左右的灰色来提供使用,并且这些颜色从文字到背景都用得上。如下图所示:

颜色选项——灰色

(2)颜色选项——主题色

大部分站点都少不了一两个贯穿全局的主题色;它出现在按钮logo背景各种修饰元素之上,是品牌的记忆元素。如下图所示:

颜色选项——主题色

(3)颜色选项——功能色

有一些常见的颜色,被广泛地用来表达某些固定的语义信息。

红色,传达错误信息,或提示危险操作。

黄色,表示警告。

绿色,表示一些积极的变化,以示成功或增长的信息。

如下图所示:

颜色选项——功能色

(4)使用色盘

前面我们准备好了这么多由深入浅的颜色,那该如何使用呢?

我们可以作为前景背景色来使用。主要标题可以用最亮的白色次要标题挑一个背景颜色的浅色版本

如下图所示:

使用色盘①


再来看另外一种用法,即浅色背景深色前景的用法。浅色色块相较于白色背景对比度不大,适合不用过于抢夺眼球的场景。如下图所示:

使用色盘②

(5)使用颜色的注意事项

颜色虽好,但使用不当会很容易打破页面层级的平衡。来看一个例子:

使用颜色的注意事项①

还有一种情况是,色盲的用户消费不了颜色,颜色在不同的文化中可能表示不同的含义。如下图:

使用颜色的注意事项②

大家可以看到,在上面这张图中,左上角的图是我们普通用户所看到的图,而左下角的图是色盲用户所看到的图。

5. 深度

(1)例子阐述

制造深度的技巧,八成与阴影设计有关。

深度补充了间距,从另一个维度上体现了层级。这是为什么?

这种深度的感官来自日常生活。平时我们是怎么感受平面上的深度的?答案是:自上而下的光照打

在平面上所造成的阴影。模拟这个现象,我们便可以实现网页元素的「深度」体验。

来看一个例子:

深度①

大家可以看到,在上面的这张图中,它的的光就是自上而下的光照打

(2)阴影选项

下面我们来看一些常见的阴影选项。如下图所示:

深度②

看了上面的一些常见选项后,我们现在来梳理各种大小的阴影所造成的影响。具体如下:

  • 小的阴影可以使元素略微突出,但不至于抢夺眼球。
  • 中等阴影适用于小型弹出的模块,如下拉框。
  • 最深的阴影则用于彻底地将模块与页面区分开来的场景。

如下所示:

不同阴影大小对设计效果的影响

🐾 五、实用技巧

1. 图片上的层级

如果我们遇到图片上的色块斑驳不一难以找到合适的前景色。这个时候我们应该咋办哩?

比如下面这张图:

色块斑驳不一

下面我们来介绍解决这种问题的几种方法。

(1)增加蒙层

我们可以通过增加蒙层,来显示图片的层级。如下图所示:

增加蒙层

(2)给文字加阴影

除此之外呢,你可以选择给文字加上阴影。 css 可以轻松地做到,只增加文字部分的对比度,而不影响整张图片的阅读体验。

如下图所示:

给文字加阴影

2. 用户头像

不管是在什么样的 app ,我们基本上都有上传图片的环节。那么,如何使得在任何的情况下,都能够清晰地展示用户头像里面的内容会是一个问题。

我们先来看这张图:

用户头像出现空白

大家可以看到,在上面的这张图中,有一些用户头像出现了空白,这样间接地会使得我们不清楚整个用户头像实际上的尺寸是多少。

由小伙伴可能会首先想到,加个 border 。但加个 border 呢,又有点差强人意了,不一定能搭配好。

有个好方法就是,加点内阴影。相当于圈用户头像的外层做边框,这就非常精巧了。

加点内阴影

3. 强调线

有时候,我们会很喜欢把表格类的设计给加上一些边框和分界线,但是这似乎看起来 a little 土。如下左图所示:

干掉分界线

大家可以看到,加了边框,就很像传统的 table 一样,有一点点不美观。

所以呢,如上边右图一样,我们可以用阴影或者不同的背景块来代替边框。这样,间距其实也就清晰了,所以我们也就不需要什么分界线了。

🖌️ 六、资源

1. 译作推荐

在上面的这篇文章中,大部分内容来自于下面这篇译作。想深入了解的同学可以进一步观看。

给开发看的 UI 设计 · 语雀

2. 书籍推荐

前面我们也稍微提到过这本书,这里推荐给大家 👉写给大家看的设计书(第 4 版) (豆瓣)

3. tailwindcss

tailwindutility class 设计,深度实践了本文所讲的设计体系。

它的官网里面还有很多设计资源 👉taildinwcss 设计框架,大家可以进一步学习查看。

同时呢,小伙伴们还可以了解来自 tailwind 作者的著作,Refactoring UI,它是本文的基础。

⛱️ 七、结束语

在上面的文章中,我们讲到了 UI 设计与前端的关系,同时呢,还讲到了设计中的一些功能导向,以及设计原则,设计体系。最后,我们还讲到了处理图片和表格的一些实用性技巧。

到这里,关于给开发人看的 UI 设计讲解就结束啦!希望对大家有帮助~

彩蛋 One More Thing

(:往期推荐

👉值得关注的 HTML 基础知识

👉css 还只停留在写布局?10 分钟带你探索 css 中更为奇妙的奥秘!

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/FrontEnd/YouthCamp/004.html b/column/FrontEnd/YouthCamp/004.html index 696cc79f..190038df 100644 --- a/column/FrontEnd/YouthCamp/004.html +++ b/column/FrontEnd/YouthCamp/004.html @@ -1755,7 +1755,7 @@ foo(); bar(); bar();

假设我们稍微调整了函数的顺序,那么它的执行结果都是不一样的,这种就称为了非纯函数

之所以要使用纯函数的原因在于,它能使得我们代码的可维护性和可扩展性变得更好。

(6)编程范式

1)命令式与声明式

将上面的高阶函数归类起来,我们可以把它总结为命令式与声明式。如下图所示:

编程范式

在实际的应用当中,我们可以说 javascript 既有命令式也有声明式。

对于命令式编程来说,它指的是命令机器如何去做事情 (how) ,这样不管你想要的是什么 (waht) ,它都会按照你的命令实现。

而对于声明式编程来说,它旨在告诉机器你想要的是什么 (what) ,让机器想出如何去做 (how) ,这种方式的可扩展性会更高。

如下图所示:

命令式和声明式

2)例子展示

下面给出几个例子,供大家体验实际应用中的效果~

👉Toggle - 命令式

👉Toggle - 声明式

👉Toggle - 三态

以上三个例子所描述的是关于在不同状态下颜色的切换效果,大家可以点击链接进行查看~

三、🎩 结束语

在上面的这篇文章中,我们讲解了如何写好 JS 的三大原则,分别是各司其职、组件封装以及过程抽象。同时呢,还学习了高阶函数和编程范式,以及其中的一些用法。

到这里,关于写好 JS 的三大原则讲解就结束啦!不知道大家是否对 JS 又有一个新的认识呢?

如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😛

😃 往期推荐

👉值得关注的 HTML 基础知识

👉css 还只停留在写布局?10 分钟带你探索 css 中更为奇妙的奥秘!

👉【青训营】- 前端只是切图仔?来学学给开发人看的 UI 设计

- + \ No newline at end of file diff --git a/column/FrontEnd/YouthCamp/005.html b/column/FrontEnd/YouthCamp/005.html index 5d416f12..f43de4db 100644 --- a/column/FrontEnd/YouthCamp/005.html +++ b/column/FrontEnd/YouthCamp/005.html @@ -103,7 +103,7 @@ return ('' + ch).repeat(padLen) + str; } }

通过这样的改进,使得代码更简洁,同时也极大的提升了运行效率

🥳 结束语

在上面的这篇文章中,我们了解到了当年的 left-pad 事件,同时呢,我们也学习到了写代码应该关注的 5 个问题:风格效率约定使用场景(算法)设计

到这里,关于本文讲解就结束啦~

如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😛

🧐 往期推荐

👉值得关注的 HTML 基础知识

👉css 还只停留在写布局?10 分钟带你探索 css 中更为奇妙的奥秘!

👉【青训营】- 前端只是切图仔?来学学给开发人看的 UI 设计

👉【青训营】- 紧跟月影大佬的步伐,一起来学习如何写好 JS(上)

- + \ No newline at end of file diff --git a/column/FrontEnd/YouthCamp/006.html b/column/FrontEnd/YouthCamp/006.html index 2b0cb418..0c8f0d30 100644 --- a/column/FrontEnd/YouthCamp/006.html +++ b/column/FrontEnd/YouthCamp/006.html @@ -27,7 +27,7 @@ Suppose I could program my computer to create a space in which everything could be linked to everything.” 再试想一下,我可以在我的电脑中写程序来创建一个空间,在这个空间里,一切东西都被相互连接着。 - Tim Berners-Lee, inventor of the World Wide Web

下面附上论文的网页版和 PDF 版本:

👉论文网页版

👉论文 PDF 版

很多人分不清 “上网” 是上的哪个网?即使在互联网的诞生地也是如此。Web 的普及和深入人可见一斑。

上网,其实指的是接入 Internet,它是地球上相互连接的计算机构成的网络。计算机网络诞生于上个世纪的 60 年代,标志性通信协议TCP/IP

 2019年3月-30th Anniversary of Web

(2)架构

1989 年诞生时,Web 由三种技术构成: HTMLHTTPURL

CSSJavaScript 是几年之后才出现的。

架构

(3)变迁

对于 Web 来说,有三个比较重要的变迁时期。分别是:

如下图所示:

变迁

2. 前端应用的领域

(1)所面向群体

对于前端应用来说,主要面向三类用户。分别是: to Bto Cto Dto B 表示的是面向商业to C 表示的是面向用户to D 呢,表示面向开发者

(2)所面向领域

前端应用的领域之浏览器

前端应用领域之浏览器篇

前端应用的领域之服务器

前端应用领域之服务器

前端应用的领域之跨端和终端

前端应用领域之跨端和终端

3. 语言、框架、工具

我们用两张图来看看实际开发中常用的一些编程语言、框架以及工具。具体如下图:

语言、框架和工具

语言、框架和工具

4. 浏览器、网络、服务器

除了上面谈到的,我们还要了解到浏览器中的一些内容。如下图所示:

深入理解现代浏览器

文章传送门:深入理解现代浏览器

同时,我们也要了解一些 HTTP 相关的知识。如下图:

12-HTTP概览

文章传送门:An overview of HTTP

5. 前端学习路线图

对于前端来说,学习路线依据下图:

前端学习路线图

对应网站链接:https://roadmap.sh

在这个网站中,基本上涵盖了所有方向的学习路线图,大家可以根据自身需求进行查看~

⏱️ 二、关于 Web 标准

1. 了解 Web 标准组织

(1)四个概念

对于 Web 标准来说,我们需要了解以下几个概念:

(2)概念细述

下面我们就上面这四个标准来了解一些相关的内容。

1)W3C

2)Ecma TC39

3)WHATWG

4)IETF

2. W3C 与 Ecma 会员

3. W3C 规范制定流程

现在,我们来了解一下 W3C 规范的制定流程,具体如下图:

w3c规范制定流程

文档传送门:w3c 规范制定流程

4. Ecma TC39 规范制定流程

继续,我们来了解 ECMA 规范的制定流程,具体如下图:

ECMA规范制定流程

文档传送门:ECMA 规范制定流程ECMA 规范核心术语

🕰️ 三、结束语

到这里,我们就简单的了解了 Web 视角下的前端开发。不知道大家对 Web 前端开发有了一个更深入的了解呢?

如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😛

⏲️ 往期推荐

👉值得关注的 HTML 基础知识

👉css 还只停留在写布局?10 分钟带你探索 css 中更为奇妙的奥秘!

👉前端只是切图仔?来学学给开发人看的 UI 设计

👉紧跟月影大佬的步伐,一起来学习如何写好 JS(上)

👉紧跟月影大佬的步伐,一起来学习如何写好 JS(下)

- + \ No newline at end of file diff --git a/column/FrontEnd/YouthCamp/007.html b/column/FrontEnd/YouthCamp/007.html index 5ec92cad..e6f1843d 100644 --- a/column/FrontEnd/YouthCamp/007.html +++ b/column/FrontEnd/YouthCamp/007.html @@ -447,7 +447,7 @@ } start();

此时浏览器的显示效果是:

命令式和声明式结果

交通灯的切换可以把它视为是一个不停的循环,那在这个循环里面呢,他会先 setState 一个状态,之后 await 一段时间。后面继续再 setState 一个状态,然后又 await 一段时间,以此类推。

那在实际的应用中,如果我们要对其进行扩展的时候,可以通过修改 while 的方式来进行操作。

🔊 三、在线 online

以上四个版本的在线地址:

📢 四、结束语

到这里,由浅入深的四个交通灯版本的实现就讲解结束啦!

如果换在以前,那我我可能用暴力破解和数据抽象的方法多一点,那通过上文的学习,现在我又多学习了过程抽象和命令式和声明式。

所以说, js 还有很多高阶的内容值得我们去探索和挖掘~

如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😉

📣 往期推荐

👉值得关注的 HTML 基础知识

👉css 还只停留在写布局?10 分钟带你探索 css 中更为奇妙的奥秘!

👉前端只是切图仔?来学学给开发人看的 UI 设计

👉紧跟月影大佬的步伐,一起来学习如何写好 JS(上)

👉紧跟月影大佬的步伐,一起来学习如何写好 JS(下)

👉听红宝书译者谈 Web 视角下的前端开发

- + \ No newline at end of file diff --git a/column/FrontEnd/YouthCamp/008.html b/column/FrontEnd/YouthCamp/008.html index 665ea6a3..e88e118c 100644 --- a/column/FrontEnd/YouthCamp/008.html +++ b/column/FrontEnd/YouthCamp/008.html @@ -161,7 +161,7 @@ // 再用正则表达式来匹配这个二进制的字符串 return /^1(?:00)*$/.test(num); }

如果遇到计算规模不是很大的时候,我们还可以用正则表达式的方式来处理。上面这种方法利用 JavaScript 转换字符串和正则的特性,来对 4 的幂等进行计算。

相比于第三种方法来说,时间开销确实会大一点,但还是算在可以接受的范围内。

⛹️ 三、结束语

在上面的文章中,我们使用了 4 种方法来解决幂等问题,有时间复杂度很低的按位与优化,还有简洁明了的正则匹配法。不知道大家是否都掌握了呢?

如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😉

🤼 往期推荐

👉紧跟月影大佬的步伐,一起来学习如何写好 JS(上)

👉紧跟月影大佬的步伐,一起来学习如何写好 JS(下)

👉每天都在红绿灯前面梭行,不如自己来实现个红绿灯?

- + \ No newline at end of file diff --git a/column/FrontEnd/YouthCamp/009.html b/column/FrontEnd/YouthCamp/009.html index 19250768..b4e2e92d 100644 --- a/column/FrontEnd/YouthCamp/009.html +++ b/column/FrontEnd/YouthCamp/009.html @@ -259,7 +259,7 @@ } resultEl.innerHTML = '<li>' + output.join('</li><li>') + '</li>'; };

另外一种算法呢,我们可以把它称为是栅栏算法

栅栏法

假设说现在有 100 块钱,那么我们可以把它看成是一个竹子。那如果你要把它分为 10 份的话,你要在中间的段里面去切 9 刀,那这 9 刀要切在什么位置呢,都是随机的。如果要在 100 块钱里面切 9 刀的话,那它是有 9999 种方案去切。也就是说,它有多少分钱,那么他就有 多少份钱 - 1 种的方式去切。

最后,我们来看一下效果。如下图所示:

随机红包效果

✳️ 三、在线 Online

以上两 个版本的在线地址:

🆗 四、结束语

在上面的文章中,我们首先谈论了分红包问题的随机性,同时,用了切西瓜法栅栏法来实现了分红包功能。不知道大家对分红包问题是否有了进一步了解呢?

如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😉

🆚 往期推荐

👉紧跟月影大佬的步伐,一起来学习如何写好 JS(上)

👉紧跟月影大佬的步伐,一起来学习如何写好 JS(下)

👉每天都在红绿灯前面梭行,不如自己来实现个红绿灯?

👉幂等问题 vs 如何判断是否是 4 的幂

👉如何给扑克洗牌才能更公平?

- + \ No newline at end of file diff --git a/column/FrontEnd/YouthCamp/010.html b/column/FrontEnd/YouthCamp/010.html index 70f669b1..e8ecdea5 100644 --- a/column/FrontEnd/YouthCamp/010.html +++ b/column/FrontEnd/YouthCamp/010.html @@ -105,7 +105,7 @@ console.log(shuffle(cards)); console.log(result);

基于前面两个版本的瑕疵,我们来实现一种公平的写法。上面的这种算法呢,其复杂度是 O(n) ,它的实现逻辑是,在整个有序数组中,先随机抽取任意一个数,把它放到最后的位置,之后再随机抽取任意一个数,再把它换到最后一个位置进行交换,以此类推。具体思路如下图所示:

洗牌交换法实现思路

下面来看控制台打印效果:

交换法打印效果

大家可以看到,控制台打印出来的数都是相对比较平均的,而不会前后差异特别大。所以,这个算法是公平的。

三、📺 在线 Online

以上三个版本的在线地址:

四、📹 结束语

在上面的文章中,我们首先谈论了平常常用的随机洗牌法的不公平性,之后重新介绍了一种新的交换法则来实现洗牌的公平性。不知道大家对洗牌问题是否有了进一步了解呢?

如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😉

📸 往期推荐

👉紧跟月影大佬的步伐,一起来学习如何写好 JS(上)

👉紧跟月影大佬的步伐,一起来学习如何写好 JS(下)

👉每天都在红绿灯前面梭行,不如自己来实现个红绿灯?

👉幂等问题 vs 如何判断是否是 4 的幂

- + \ No newline at end of file diff --git a/column/FrontEnd/YouthCamp/011.html b/column/FrontEnd/YouthCamp/011.html index bbb2d818..4ee5979a 100644 --- a/column/FrontEnd/YouthCamp/011.html +++ b/column/FrontEnd/YouthCamp/011.html @@ -19,7 +19,7 @@
Skip to content

📸 叮!

记 · 字节跳动第一届青训营顺利结营啦!

从 8 月份的青训营,到 9 月份的实训营,搁置了许久的结营心得终于拾起来辽!

🎬 开营进行时

从答疑会开始,负责人仔细的阐述了本次训练营的性质和最终想要达到的目标。

其中包括班级设置、活动流程以及小伙伴们的一些答疑解惑等等。

流程图

🌾 课程收获

青训营

在前面上 htmlcss 的时候,虽然这些是以前学过的基础,但是在青训营的学习过程中会发现,每一节课都有自己以前所没有触碰过的知识盲区

同时,在中间学习 js 和设计模式内容时,发现 js 远远不是我所认为的 js ,以前写代码时完全没有考虑到这么多细节,而通过本次课程,学到了很多新的设计思想

同时,青训营的课不止步于前端三大组件,同时还涉略了前端的各大板块。包括但不限于前端动画、 web 安全和 http 的知识,不仅巩固了我的知识体系,同时也开拓了前端的另一扇大门。

通过青训营的学习,让我深深的认识到,我所认为的前端远不止于我所认识的前端。

实训营

从青训营的基础课,到实训营造轮子课的转变,课程形式也发生了极大的变化。

在实训营学习的过程中,课程内容相对也是比较丰富的。实训营的课程让我涉及到更多以前从未了解到的板块,也让我更加明确了在前端之路的探索和追求。

在技术上,了解到了更多的新技术和新的工具和使用,开拓了技术盲点的另一扇大门。

实训营课程表

🔥 团队合作

沟通方面

很荣幸加入了进阶班,同时也非常庆幸自己能够进入到这么优秀的队伍!我们小组是4 个校招+3 个社招组成的队伍,当时团队的其他成员可能都比较忙碌,随之我担起了队长的职责。

而我又是其中年龄最小的,当时也是第一次在这种类型的项目去 owner 整个项目,也会担心和害怕因为能力和学识比较不足的原因,而拖累了大家。但好在整个团队都非常给力,大家似乎像是拥有一个相同的目标,达成了某一个一致的共识,最终各类任务也有序地进行着~

🔥🔥🔥

青训营结束后,就到了 9 月份的实训营。

在团队协作上,因为实训营增加了新成员,从原来的 7 个人变为现在的 10 个人,项目协作的沟通成本也会更大一点。而这个过程中,在一些小伙伴身上也学到了很多新的东西。

比如,有一回我们因为一个功能模块的分配工作而大家突然都没有了声音,这个时候团队突然间有一个小伙伴站出来告诉我们,我们应该怎么样去分配这样的事情更加地合理。在这个过程中,也让我学到了,在项目分工这么紧急的情况下,一定要及时找出解决方案才是最好的结果

因此,我也及时复盘了自己在平常协作上存在的一些问题,并在往后中更好的去避免相关事情的发生。

实训营项目协作

实训营项目文档

逻辑方面

以前在学校小打小闹地确实做了很多小项目,但是代码协作相对来说人比较少,且是线下的,大家随时可以讨论,也就没有感觉很困难。但这会因为团队有几个社招小伙伴,我们有过对于 sassless 用哪一个开发效率更高,也有过组件库用哪一个更有利于项目……的冲突。

虽说大家都各执己见,但最后总会是为了效率最大化而形成一个统一

还有一个更为有进步点的是,对于业务来说,我一直存在的一个弊端就是,先关注页面,这样的坏处在于我会经常性的把数据写死,扩展性基本等于 0 。看了小组小伙伴的代码之后,了解到自己在这方面的不足。

对于业务来说,我们应该先关注的是功能,这样我们会不断地去想它哪里有扩展性,到后期功能就有叠加的可能性。而不是一味的 CV 操作,不单代码没有进步,思维逻辑也会一度停滞不前。

项目方面

团队的每一个小伙伴的积极性都很高,大家各司其职,分别完成好各自所分配到的任务。从一开始我们就写了团队每个成员的信息,以更方便地了解每个人所会的技术栈。 之后确定项目选题之后,我们对想要实现的应用进行需求分析,从最基本的功能开始层层递进。并罗列出第一版本第二版本想要实现的功能。

整个过程的调度性也相对较高,每一天每一个成员都会有相应的开发任务,并且在遇到问题(bug)时,会及时提出来问下同组成员是否有遇到过类似的问题,尽可能地提升开发效率,以免耽误后续的开发内容。

同时,字节还给我们每个项目小组分别分配了导师 mentor ,在项目开发的过程中,我们会经常去问导师的问题,不管是困难的 or 简单的,导师总是非常耐心的解答我们的疑惑。

除了项目之外的问题,老师有时候还会跟我们唠嗑,谈到差异化赛道的竞争,谈到了个人成长等等话题。

深切感受到字节不讲 title 的企业文化,不论是 mentor ,还是授课老师,亦或是主办方负责人,交流起来基本 0 代沟, 0 压力。

📆 关于班会

答疑

青训营期间基本上两天会有一次班会,班会的内容通常会有当天课程老师的答疑。每一节课大家都会把问题写到答疑文档中,等到班会的时候任课老师作统一讲解。

当然,班会所谈论的话题也不止于前端内容,还有一些小伙伴可能会有技术上或者成长上的困惑,也会在飞书会议上提出疑问,任课老师和负责人们也会很细心地进行解答。

茶话会

在青训营结束的那个周五晚上,开了最后一场班会。那一节班会持续了 2 个多小时,主要是月影老师和主办方小姐姐们给大家答疑。

犹记得月影老师说的一句话,兴趣是最重要的老师。这句话很是引发共鸣,想起当时我是因为什么而进入的前端领域。

在最后的一次班会中,月影老师谈到了他是零几年的毕业生,然后当时底下的聊天框大家都在敲打着说月影老师毕业时自己还在蹒跚学步~😜

其中,有一个班级小伙伴提到的问题是,不知道怎么去继续进阶前端?而这个时候月影老师回答道,学好通用知识,包括数学知识、算法和数据结构等各类通用的公共知识。同时基础知识要打牢,基础是永远不过时的

想起了我准备春秋招的时候,在学习了很多基础的时候,发现很多东西都是相通的,基础越扎实,那么之后在应用方面的扩展能力也将会越广泛。这也印证了一句话,基础不牢,地动山摇

班会的时候还谈到了内卷这个话题 👇

平常我们都在说被内卷,但很多时候是因为自己没有行动而产生的焦虑。而其实,如果整个行业越卷,那么我们能获得的机会也就会越多。

再谈到一个话题是:一专多能。所谓一专多能,指在自己付出的领域上,至少要有一门技术是精进的,而当一门技术有一定的知识深度之后,那么我们可以尝试着去扩展自己的知识广度

同时,对于技术而言,尽量不要去学习过时的技术。当整个行业都在高速发展时,去学习一门过时的技术对于自己的成长是极为不利的。所以,如果想要保持有自己最基本的核心竞争力,那么趋势是尽量跟随着行业的大体走向走。

差异化赛道的竞争

📑 硕果丰收季

课程部分唠嗑完啦!接下来就是丰收硕果啦!

青训营

在青训营的最后,是整个小组合作完成一个项目。我们小组最终定的选题是基于 vuejs + nodejs 的个人导航应用,项目名称为 Surfing Set

犹记得在最后两天的冲刺时间里,在一天大概凌晨快 3 点的时候,周一还有未解决的 bug ,团队小伙伴还在帮忙修 bug 。到最后的全部解决完毕的时候,大家才去休息。

更为深刻的一个点是, PPT 的制作。以前对于 PPT 的制作,一般都是从 01 一个人制作。但这次项目不一样,因为有部分功能模块是团队小伙伴实现的,而我也不知道其中的项目亮点和难点。于是把最终要展现的文字制作成一个表格,让大家把各自实现的内容给细化进行文字补充。在此基础上,我就减少了 PPT 中部分文字模块的编写,而把重心放在整个 PPT 的逻辑梳理和全局美化。

到了接近路演的时候,主办方前期给到的汇报时间是 5-8min 。于是在完善了 PPT 之后,跟 YK菌 两个人又试着路演,不断计时和调整,把时间压到 8 min 以内。

深刻感受到,如果一个团队大家都很积极,一人完成一点,多个小点汇集在一起,项目的推进也会变得更加地快速。

铛铛铛!最后就是说下项目成果啦!小组项目最终获得了 2022 届的 No.1 !于是还收到了字节方的礼物 🎁🎁🎁

李松峰老师亲笔签名的犀牛书,字节笔记本,眼罩,掘金周边……🤞

硕果丰收

📑📑📑 下面再附上项目的汇报内容 📰📰📰

汇报成果①

汇报成果②

汇报成果③

实训营

实训营的整个周期是 9/20-9/26 ,持续时间一共是 7 天。与前期的青训营完全不同的是,实训营每天要上 8 个小时的课,基本上从早上到晚上,白天 🌞 是脑细胞持久战,晚上 🌗 是笔记整理持久战。

在上课期间,团队小伙伴也很积极,大家也各自讨论着上课的内容,比如:xxx 老师的课程在实际项目中的应用,xxx 知识点会有什么样的扩展体系……

虽说短时间内要消耗的知识点很多,但可能是因为在一群人一起学习的大氛围下,好像学习的积极性也就提高了~

实训营的最后是在周五下午上完课才给的选题,且主办方要求是周六晚上 12 点前提交 prd 。周五晚上小组就赶忙开了会,大家先写各自想要负责的内容,包括但不限于 UI 、前端或者后端三个方向,之后大家一起讨论要做的项目方向。

因为项目的周期非常赶,所以短期内是效率至上的原则,不过多的考虑细节问题。这次不同于青训营的项目是,团队成员比较多,分的也比较细,所以分成了 UI 、前端和后端三个小组。在确定了大致实现内容之后,三个小组也分出了各自的组长,各个方向再对其内容进行内部消化。

基本上周六晚上的时候,大家都是通宵赶项目。有很多小伙伴都是赶到快天亮的时候,项目的进度也基本上完成了 90% 以上,大家赶忙先去休息。

因为是周日下午 4 点要上交最终的答辩内容,所以等到中午 11 点左右的时候,项目组先分出 2 个小伙伴来做汇报 PPT,然后其他成员继续修缮项目后续的内容。

当时跟 昕昕子 两个人,一人分两个主题来进行 PPT 编写。到后期我在审核 PPT 逻辑的时候,时间有点来不及。于是昕昕在此基础上先提前写演讲稿,以便于后续路演更快速地进行。

PPT 和演讲稿完成以后,中间有一个空档期需要试演练。这个时候团队有小伙伴很细心地发现 PPT 的字体不统一,于是在这个期间做了整体的调整。

实训营成果汇报①

实训营成果汇报②

实训营成果汇报③

最后路演由三部分组成,分别是:项目详细成果汇报 + 项目演示 + 文档演示。项目演示部分先提前交给团队前端小伙路演屏,然后我负责前后两个部分的路演。

后面路演完成时基本上接近了 deadline 时间,剩下的是将三个路演视频拼接在一起并进行有序衔接,这项任务最终临时分配给了小远同学,小远同学也非常迅速的对视频进行画质处理和内容衔接,最终作品也顺利地赶在 deadline 前得到了完成。

团队协作

很幸运遇到一个这么好的团队,其中不乏有来自于浙大、华科等名校的小伙伴,更有来自海外的留学生,倒着时差跟大家一起赶项目进度。

虽说大家来自于五湖四海,但我们又因为某种缘分,似乎就达成了某种意义上的共识和默契!We are a team.

此处附上青训营往期推荐精彩内容:https://youthcamp.bytedance.com/activity-previous

静态下一届青训动态的更新!

📞 我还想说

有缘相聚于字节青训,认识到了一群很优秀的小伙伴!

把字节青训的各个模块比作是一张地图上的各个板块,而因为某种缘分,我们汇聚在了一起!

感谢主办方负责人的辛苦付出,感谢字节前端 byteFE 和字节青训给我们提供的平台!

未来,不期而遇~🥂

❤️❤️❤️

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/FrontEnd/index.html b/column/FrontEnd/index.html index d4b60571..d775b765 100644 --- a/column/FrontEnd/index.html +++ b/column/FrontEnd/index.html @@ -19,7 +19,7 @@
Skip to content

序言

前端开发类别旨在记录周一在前端学习过程中的一些干货合集,包 11 个部分的内容,分别是CSSJavaScriptvue.jsreact.jsvue.js 原理解析TypeScriptWebpackvue3+ts 组件库开发实战类青训营 YouthCamp掘金翻译计划。各部分的文章如下 👇

文章收录

CSS

001-你可能对 position 和 z-index 有一些误解

002-谁动了我的选择器?深入理解 CSS 选择器优先级

JavaScript

001-了解 js 基础知识中的作用域和闭包以及闭包的一些应用场景,浅析函数柯里化

002-JS 中 this 的应用场景,再了解下 apply、call 和 bind!

003-解决异步问题,教你如何写出优雅的 promise 和 async/await,告别 callback 回调地狱!

004-提升对前端的认知,不得不了解 Web API 的 DOM 和 BOM

005-你真的理解事件绑定、事件冒泡和事件委托吗?

006-跨越跨域大山,前端不得不知道的 Ajax

007-你可能没有听说过 js 中的 DOM 操作还有这个:HTMLCollection 和 NodeList

008-一文梳理 JavaScript 中常见的七大继承方案

009-超保姆级教程带你实现 Promise 的核心功能

vue.js

001-万字总结 vue 的基本使用和高级特性,周边插件 vuex 和 vue-router 任你挑选

002-初探 vue3,速来围观 vue3 新特性

003-敲黑板!vue3 重点!一文了解 Composition API 新特性:ref、toRef、toRefs

004-紧跟 vue3 的步伐,再来 get 一波进阶新特性!

005-模块化妙用!用 vue3 实现一个鼠标追踪器和异步加载组件

006-vue3 的传送门 teleport 究竟有多神奇?suspense 发起异步请求有多简约?

007-浅谈前端路由原理 hash 和 history

react.js

001-初探 react,用 react 实现一个 todoList 功能

002-react 只停留在表层?五大知识点带你梳理进阶知识

003-Redux 从入门到进阶,看这一篇就够了!

004-React 快速入门,一文弄懂 react 的基本使用和高级特性

005-使用 React hooks,些许又多了不少摸鱼时间

vue.js 原理解析

001-手把手教你剖析 vue 响应式原理,监听数据不再迷茫

002-面试中的网红虚拟 DOM,你知多少呢?深入解读 diff 算法

003-模板编译 template 的背后,究竟发生了什么事?带你了解 template 的纸短情长

004-vue2 的响应式原理学“废”了吗?继续观摩 vue3 响应式原理 Proxy

TypeScript

001-还不会 ts?一文带你打开 ts 的大门

002-代码缺乏装饰?使用 ts 装饰器来装饰你的代码

Webpack

001-不会 webpack 的前端可能是捡来的,万字总结 webpack 的超入门核心知识

002-webpack 入门核心知识还看不过瘾?速来围观万字入门进阶知识

003-万字总结 webpack 实战案例配置

004-webpack 实战之手写一个 loader 和 plugin

005-手写一个简易 bundler 打包工具带你了解 Webpack 原理

vue3+ts 组件库开发

001-组件库实战 | 用 vue3+ts 实现全局 Header 和列表数据渲染 ColumnList

002-组件库实战 | 教你如何设计 Web 世界中的表单验证

一些好玩的实战类

001-一张网页带你了解中秋节的前世今生

青训营 YouthCamp

001-【青训营】- 值得关注的 HTML 基础

002-【青训营】- 10 分钟带你探索 css 中更为奇妙的奥秘

003-【青训营】- 前端只是切图仔?来学学给开发人看的 UI 设计

004-【青训营】- 紧跟月影大佬的步伐,一起来学习如何写好 JS(上)

005-【青训营】- 紧跟月影大佬的步伐,一起来学习如何写好 JS(下)

006-【青训营】- 听红宝书译者谈 Web 视角下的前端开发

007-【青训营】- 每天都在红绿灯前面梭行,不如自己来实现个红绿灯?

008-【青训营】- 幂等问题 vs 如何判断是否是 4 的幂

009-【青训营】- 切西瓜法实现微信抢红包功能

010-【青训营】- 如何给扑克洗牌才能更公平?

011-【青训营】- 结营啦!有缘相聚于青训,未来高处见呀~~

掘金翻译计划

001-JS 中的依赖注入 — 在测试中未使用过的最佳工具

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Growing/ReviewSummary/001.html b/column/Growing/ReviewSummary/001.html index 10f2571b..a2f7f4e0 100644 --- a/column/Growing/ReviewSummary/001.html +++ b/column/Growing/ReviewSummary/001.html @@ -19,7 +19,7 @@
Skip to content

2021 年 7 月复盘总结

🖼️ 序言

搁置了很久的七月复盘在今天才进行了归纳整理。

在上个月中,有 1/3 的时间在准备期末,有 2/3 的时间在给自己充电。

📈 学习时间统计

累计统计天数: 22

累计专注时间: 225 h 15 min

日均学习时间: 10 h 15 min

饼图

学习时长统计

📝blog 输出

新技术

完成 webpack 的入门学习,累计花费时间 65h15min

webpack学习

在学习完 webpack 的入门内容之后,对自己的新期待是,学习大框架的思想,比如 create-react-appvue-cli

数据结构与算法

继五月份过后,重新把之前做过的题目进行归纳总结,进一步复习。

数据结构与算法

对于算法来说,总结下来就是不要提前先去害怕它,而要每天循序渐进地进行题目分配并刷题,算法思想将会慢慢地一步步形成。这也算是相对比较大的一个难关,没有其他捷径可走,多刷题多练习多总结多归纳,方为上策。

一些零碎知识点

之前学习基础知识的时候,对一些知识点的认识只停留在表面,没有很深入的去了解。于是在这个月也赶忙一起整理了,把之前的困惑都尽快地清除。

零散博客整理

⏰ 总结

可以说在 7 月份中,每一天的时间都是自己的,也没有被太多外界的事物所干扰。但是呢,可能正因为这样,才对自己的学习时间有所放宽,间接地摸鱼时间似乎又多了许多。做复盘的同时也想要给自己敲一个警钟,时间对于每个人来说都是平等的,希望能够正视到自己所存在的问题,尽快地调整好作息规范~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Growing/ReviewSummary/002.html b/column/Growing/ReviewSummary/002.html index ec89d367..b26cfb60 100644 --- a/column/Growing/ReviewSummary/002.html +++ b/column/Growing/ReviewSummary/002.html @@ -20,7 +20,7 @@
Skip to content

🗂️ 序言

七月份的时候第一次做月度复盘,发现如果只有每日计划,还是比较零散的。月度复盘可以更直观地看到自己的时间规划和及时纠正当下存在的一些问题。

在 8-9 月份中,有一半在暑假,一半开始于新学期。

📆 学习时间统计

August.

累计统计天数: 28

累计专注时间: 310 h 35 min

日均学习时间: 11 h 05 min

8月学习时长统计

September.

累计统计天数: 18

累计专注时间: 241 h 30 min

日均学习时间: 10 h 15 min

9月学习时间统计

📌 创新视角下的复盘

OKR 模式

OKR 模式看待目标,将目标 Objective 细分为关键结果 Key Result ,这样能够更好地量化每一天的任务。

8~9月OKR

微任务清单

9 月的时候,在一个小红书博主上看到微任务清单。才发现原来自己也有很多很琐碎的事情,东捏一点时间,西捏一点时间,很快就浪费了很多不该浪费的片刻。

于是增加了微任务清单,把微小的任务集中在一个时间点去完成,这样就把琐碎的时间集中在一起,更大地提升时间利用率。

微任务清单

压力 Pressure 解决清单

人生难免出现压力,但适当的压力会给自己带来一定的反思,并且及时做出调整。同样也是受到小红书博主的启发,改造了压力事件解决清单。

当出现压力时,写下具体的压力,并写下此刻的情绪和感受,同时反问自己,希望自己能够给出的具体行动清单。

很多时候,在反问自己时,压力事件自然就给出自己想要的答案了。

因此,学会面对压力带来的坏情绪,正确面对和释然,压力事件也就迎刃而解了~

压力事件解决清单

月复盘总纲

有了 OKR 模式、微任务清单以及压力事件解决方案的探索以后,还增加了月复盘总纲。

首先是先记录自己的收获清单,将本月学到的,收获到的内容集中记录在一起。收获清单的事件往往是可以给你带来多巴胺的事件,是前进的一大动力,在进行记录时,就会发现成就感满满,后续制定目标时也会更有动力。

同时呢,也不要害怕失败,而是要把失败当成自己的第一生产力,坦然面对,正确解决。人生需要承受失败,下一个惊喜才会出现,学会接受自己的错误才能遇见更好的自己。

月复盘总纲

🛒Blog 输出

「offer 来了」系列整理

8~9 月累计输出博客 24 篇,文章总字数累计超过 20w 字。 之前在准备春招的时候就在想,如果我没有把知识点整理成体系,那以后再重新复习的时候,整个复习结构依然是非常零散的。因此,把整个春秋招所有学过的面试相关的知识点整理成一个个的专栏,方便自己以后复习。

offer来了系列

字节青训营

7 月报名了字节的青训营,有幸加入到了进阶班。从青训营到实训营的转变,不管是从课程设计上,还是组队项目上,亦或是造轮子课上,每个阶段的学习基本都是信息量满满,更是让自己感受到山外有山 🚵🏼~

与一群拥有着共同目标的小伙伴,大家相互探讨新技术,互相交流当下阶段的进步与成长。

我们分别来自于五湖四海,但因为各自有着相同的目标,而汇聚在了一起。

字节青训营Youth Camp

青训营blog输出

⏰ 总结

在 8 月份的时候,深深地意识到自己很严重的一个问题就是,拖延。而拖延的原因很多时候是因为畏惧困难(畏难)。

如果突然间有一件事情让我看起来很难,比如说写一道 hard 的算法题,或者说,封装某个逻辑组件。因为还没开始做这件事情我就先去害怕它,间接地导致在畏惧困难的阶段就浪费了很多时间。

而最终调整的做法是,把困难的这件事情先拆分出最简单的步骤出来,然后让自己先去做最简单的部分。最后发现,跟随着这个步伐,困难的问题也将一步步迎刃而解了。

九月份的时候,到了新学期开始。发现时间又变得细碎了起来。从暑假的角色转换到开学的角色,这其中不论是从时间管理上还是从细碎事情处理上,都会有一个很大的转变。

而其中最大的权衡点在于,如何分配时间才能平衡好学习和生活之间的关系,如何才能让时间使用率最大化,这一点是相较于目前阶段来说是比较需要去解决的问题~⁉️

Hi, October!

Hi, October!

🐣 彩蛋

创新视觉下的复盘清单灵感来源于小红书博主进击中的乐多,该博主致力于将一切计划可视化,有很多复盘的模式值得学习和借鉴,小伙伴们可以搜索学习哦~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Growing/ReviewSummary/003.html b/column/Growing/ReviewSummary/003.html index fe2d85b6..6bd19f25 100644 --- a/column/Growing/ReviewSummary/003.html +++ b/column/Growing/ReviewSummary/003.html @@ -19,7 +19,7 @@
Skip to content

📸 叮!

记 · 字节跳动第一届青训营顺利结营啦!

从 8 月份的青训营,到 9 月份的实训营,搁置了许久的结营心得终于拾起来辽!

🎬 开营进行时

从答疑会开始,负责人仔细的阐述了本次训练营的性质和最终想要达到的目标。

其中包括班级设置、活动流程以及小伙伴们的一些答疑解惑等等。

流程图

🌾 课程收获

青训营

在前面上 htmlcss 的时候,虽然这些是以前学过的基础,但是在青训营的学习过程中会发现,每一节课都有自己以前所没有触碰过的知识盲区

同时,在中间学习 js 和设计模式内容时,发现 js 远远不是我所认为的 js ,以前写代码时完全没有考虑到这么多细节,而通过本次课程,学到了很多新的设计思想

同时,青训营的课不止步于前端三大组件,同时还涉略了前端的各大板块。包括但不限于前端动画、 web 安全和 http 的知识,不仅巩固了我的知识体系,同时也开拓了前端的另一扇大门。

通过青训营的学习,让我深深的认识到,我所认为的前端远不止于我所认识的前端。

实训营

从青训营的基础课,到实训营造轮子课的转变,课程形式也发生了极大的变化。

在实训营学习的过程中,课程内容相对也是比较丰富的。实训营的课程让我涉及到更多以前从未了解到的板块,也让我更加明确了在前端之路的探索和追求。

在技术上,了解到了更多的新技术和新的工具和使用,开拓了技术盲点的另一扇大门。

实训营课程表

🔥 团队合作

沟通方面

很荣幸加入了进阶班,同时也非常庆幸自己能够进入到这么优秀的队伍!我们小组是4 个校招+3 个社招组成的队伍,当时团队的其他成员可能都比较忙碌,随之我担起了队长的职责。

而我又是其中年龄最小的,当时也是第一次在这种类型的项目去 owner 整个项目,也会担心和害怕因为能力和学识比较不足的原因,而拖累了大家。但好在整个团队都非常给力,大家似乎像是拥有一个相同的目标,达成了某一个一致的共识,最终各类任务也有序地进行着~

🔥🔥🔥

青训营结束后,就到了 9 月份的实训营。

在团队协作上,因为实训营增加了新成员,从原来的 7 个人变为现在的 10 个人,项目协作的沟通成本也会更大一点。而这个过程中,在一些小伙伴身上也学到了很多新的东西。

比如,有一回我们因为一个功能模块的分配工作而大家突然都没有了声音,这个时候团队突然间有一个小伙伴站出来告诉我们,我们应该怎么样去分配这样的事情更加地合理。在这个过程中,也让我学到了,在项目分工这么紧急的情况下,一定要及时找出解决方案才是最好的结果

因此,我也及时复盘了自己在平常协作上存在的一些问题,并在往后中更好的去避免相关事情的发生。

实训营项目协作

实训营项目文档

逻辑方面

以前在学校小打小闹地确实做了很多小项目,但是代码协作相对来说人比较少,且是线下的,大家随时可以讨论,也就没有感觉很困难。但这会因为团队有几个社招小伙伴,我们有过对于 sassless 用哪一个开发效率更高,也有过组件库用哪一个更有利于项目……的冲突。

虽说大家都各执己见,但最后总会是为了效率最大化而形成一个统一

还有一个更为有进步点的是,对于业务来说,我一直存在的一个弊端就是,先关注页面,这样的坏处在于我会经常性的把数据写死,扩展性基本等于 0 。看了小组小伙伴的代码之后,了解到自己在这方面的不足。

对于业务来说,我们应该先关注的是功能,这样我们会不断地去想它哪里有扩展性,到后期功能就有叠加的可能性。而不是一味的 CV 操作,不单代码没有进步,思维逻辑也会一度停滞不前。

项目方面

团队的每一个小伙伴的积极性都很高,大家各司其职,分别完成好各自所分配到的任务。从一开始我们就写了团队每个成员的信息,以更方便地了解每个人所会的技术栈。 之后确定项目选题之后,我们对想要实现的应用进行需求分析,从最基本的功能开始层层递进。并罗列出第一版本第二版本想要实现的功能。

整个过程的调度性也相对较高,每一天每一个成员都会有相应的开发任务,并且在遇到问题(bug)时,会及时提出来问下同组成员是否有遇到过类似的问题,尽可能地提升开发效率,以免耽误后续的开发内容。

同时,字节还给我们每个项目小组分别分配了导师 mentor ,在项目开发的过程中,我们会经常去问导师的问题,不管是困难的 or 简单的,导师总是非常耐心的解答我们的疑惑。

除了项目之外的问题,老师有时候还会跟我们唠嗑,谈到差异化赛道的竞争,谈到了个人成长等等话题。

深切感受到字节不讲 title 的企业文化,不论是 mentor ,还是授课老师,亦或是主办方负责人,交流起来基本 0 代沟, 0 压力。

📆 关于班会

答疑

青训营期间基本上两天会有一次班会,班会的内容通常会有当天课程老师的答疑。每一节课大家都会把问题写到答疑文档中,等到班会的时候任课老师作统一讲解。

当然,班会所谈论的话题也不止于前端内容,还有一些小伙伴可能会有技术上或者成长上的困惑,也会在飞书会议上提出疑问,任课老师和负责人们也会很细心地进行解答。

茶话会

在青训营结束的那个周五晚上,开了最后一场班会。那一节班会持续了 2 个多小时,主要是月影老师和主办方小姐姐们给大家答疑。

犹记得月影老师说的一句话,兴趣是最重要的老师。这句话很是引发共鸣,想起当时我是因为什么而进入的前端领域。

在最后的一次班会中,月影老师谈到了他是零几年的毕业生,然后当时底下的聊天框大家都在敲打着说月影老师毕业时自己还在蹒跚学步~😜

其中,有一个班级小伙伴提到的问题是,不知道怎么去继续进阶前端?而这个时候月影老师回答道,学好通用知识,包括数学知识、算法和数据结构等各类通用的公共知识。同时基础知识要打牢,基础是永远不过时的

想起了我准备春秋招的时候,在学习了很多基础的时候,发现很多东西都是相通的,基础越扎实,那么之后在应用方面的扩展能力也将会越广泛。这也印证了一句话,基础不牢,地动山摇

班会的时候还谈到了内卷这个话题 👇

平常我们都在说被内卷,但很多时候是因为自己没有行动而产生的焦虑。而其实,如果整个行业越卷,那么我们能获得的机会也就会越多。

再谈到一个话题是:一专多能。所谓一专多能,指在自己付出的领域上,至少要有一门技术是精进的,而当一门技术有一定的知识深度之后,那么我们可以尝试着去扩展自己的知识广度

同时,对于技术而言,尽量不要去学习过时的技术。当整个行业都在高速发展时,去学习一门过时的技术对于自己的成长是极为不利的。所以,如果想要保持有自己最基本的核心竞争力,那么趋势是尽量跟随着行业的大体走向走。

差异化赛道的竞争

📑 硕果丰收季

课程部分唠嗑完啦!接下来就是丰收硕果啦!

青训营

在青训营的最后,是整个小组合作完成一个项目。我们小组最终定的选题是基于 vuejs + nodejs 的个人导航应用,项目名称为 Surfing Set

犹记得在最后两天的冲刺时间里,在一天大概凌晨快 3 点的时候,周一还有未解决的 bug ,团队小伙伴还在帮忙修 bug 。到最后的全部解决完毕的时候,大家才去休息。

更为深刻的一个点是, PPT 的制作。以前对于 PPT 的制作,一般都是从 01 一个人制作。但这次项目不一样,因为有部分功能模块是团队小伙伴实现的,而我也不知道其中的项目亮点和难点。于是把最终要展现的文字制作成一个表格,让大家把各自实现的内容给细化进行文字补充。在此基础上,我就减少了 PPT 中部分文字模块的编写,而把重心放在整个 PPT 的逻辑梳理和全局美化。

到了接近路演的时候,主办方前期给到的汇报时间是 5-8min 。于是在完善了 PPT 之后,跟 YK菌 两个人又试着路演,不断计时和调整,把时间压到 8 min 以内。

深刻感受到,如果一个团队大家都很积极,一人完成一点,多个小点汇集在一起,项目的推进也会变得更加地快速。

铛铛铛!最后就是说下项目成果啦!小组项目最终获得了 2022 届的 No.1 !于是还收到了字节方的礼物 🎁🎁🎁

李松峰老师亲笔签名的犀牛书,字节笔记本,眼罩,掘金周边……🤞

硕果丰收

📑📑📑 下面再附上项目的汇报内容 📰📰📰

汇报成果①

汇报成果②

汇报成果③

实训营

实训营的整个周期是 9/20-9/26 ,持续时间一共是 7 天。与前期的青训营完全不同的是,实训营每天要上 8 个小时的课,基本上从早上到晚上,白天 🌞 是脑细胞持久战,晚上 🌗 是笔记整理持久战。

在上课期间,团队小伙伴也很积极,大家也各自讨论着上课的内容,比如:xxx 老师的课程在实际项目中的应用,xxx 知识点会有什么样的扩展体系……

虽说短时间内要消耗的知识点很多,但可能是因为在一群人一起学习的大氛围下,好像学习的积极性也就提高了~

实训营的最后是在周五下午上完课才给的选题,且主办方要求是周六晚上 12 点前提交 prd 。周五晚上小组就赶忙开了会,大家先写各自想要负责的内容,包括但不限于 UI 、前端或者后端三个方向,之后大家一起讨论要做的项目方向。

因为项目的周期非常赶,所以短期内是效率至上的原则,不过多的考虑细节问题。这次不同于青训营的项目是,团队成员比较多,分的也比较细,所以分成了 UI 、前端和后端三个小组。在确定了大致实现内容之后,三个小组也分出了各自的组长,各个方向再对其内容进行内部消化。

基本上周六晚上的时候,大家都是通宵赶项目。有很多小伙伴都是赶到快天亮的时候,项目的进度也基本上完成了 90% 以上,大家赶忙先去休息。

因为是周日下午 4 点要上交最终的答辩内容,所以等到中午 11 点左右的时候,项目组先分出 2 个小伙伴来做汇报 PPT,然后其他成员继续修缮项目后续的内容。

当时跟 昕昕子 两个人,一人分两个主题来进行 PPT 编写。到后期我在审核 PPT 逻辑的时候,时间有点来不及。于是昕昕在此基础上先提前写演讲稿,以便于后续路演更快速地进行。

PPT 和演讲稿完成以后,中间有一个空档期需要试演练。这个时候团队有小伙伴很细心地发现 PPT 的字体不统一,于是在这个期间做了整体的调整。

实训营成果汇报①

实训营成果汇报②

实训营成果汇报③

最后路演由三部分组成,分别是:项目详细成果汇报 + 项目演示 + 文档演示。项目演示部分先提前交给团队前端小伙路演屏,然后我负责前后两个部分的路演。

后面路演完成时基本上接近了 deadline 时间,剩下的是将三个路演视频拼接在一起并进行有序衔接,这项任务最终临时分配给了小远同学,小远同学也非常迅速的对视频进行画质处理和内容衔接,最终作品也顺利地赶在 deadline 前得到了完成。

团队协作

很幸运遇到一个这么好的团队,其中不乏有来自于浙大、华科等名校的小伙伴,更有来自海外的留学生,倒着时差跟大家一起赶项目进度。

虽说大家来自于五湖四海,但我们又因为某种缘分,似乎就达成了某种意义上的共识和默契!We are a team.

此处附上青训营往期推荐精彩内容:https://youthcamp.bytedance.com/activity-previous

静态下一届青训动态的更新!

📞 我还想说

有缘相聚于字节青训,认识到了一群很优秀的小伙伴!

把字节青训的各个模块比作是一张地图上的各个板块,而因为某种缘分,我们汇聚在了一起!

感谢主办方负责人的辛苦付出,感谢字节前端 byteFE 和字节青训给我们提供的平台!

未来,不期而遇~🥂

❤️❤️❤️

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Growing/YearSummary/001.html b/column/Growing/YearSummary/001.html index 99cb942f..eb247bb9 100644 --- a/column/Growing/YearSummary/001.html +++ b/column/Growing/YearSummary/001.html @@ -19,7 +19,7 @@
Skip to content

图片封面

🕛 序言

今年三月初,善后了上学期事情之后,我开始在想,我的未来规划。

身边的好朋友和同学都在筹划着自己的未来,考研的考研,考公的考公。父母和老师们也在劝我说考研,问我考不考研。

依稀记得回校的那一天我爹还在问我说要不要考研,而这个时候我开始有点动摇了。原来一直不打算考研的我,这个时候在想考研的结果会不会是更好的?

一波了解之后发现,我准备的时间还是太晚了,离我的目标学校可能还有点距离。于是放弃考研想法后的我,开始了我的就业筹划。

这个时候已经到了快 3 月底,各企业的春招正在紧密张罗着。而对于我来说,我发现自身除了实践以外,理论知识非常差。基于以上各种条件,我开始查漏补缺。

在过去的 3 个月里,对自己的规划主要有以下突破 👋

📚 日常 Daily

‌ 每日计划

从原来的滴答清单,进阶到用 Notion 做每日计划,无意间发现自己每天摸鱼的时间变得很长。于是从这个突破点出发,减少自己玩手机的时间,利用碎片化的时间,学习更多的知识。

滴答清单

notion

用 Notion 的好处在于,可以更直观的记录自己每天的学习输入和产出,通过复盘来及时调整学习计划,避免重复性的工作。

英语

在坚持了 1 年的英文外刊精读后,希望打破舒适圈,向英文原版书出发。刚开始我对看英文书是非常畏怕的,因为感觉我平常的外刊就 2min 的音频,而英文书一章的内容有 7-10min ,这无形中看起来增加了好几倍的学习量,所以一直停留在原地,不敢去触碰它。

直到今年春节快接近开学的时候,我一直在找寻突破我学习英语的边界,最终找寻到了我想要突破的边界,就是向英文文献和文档迈进。

从来没有读过原版书籍的我,选择了使用薄荷阅读。我选择了词汇量比我实际词汇量小一档的书本,这样不管是在心里上还是精神上都不会给我带来太大的阅读压力。

经过 100 天的学习,边听边理解的这个步骤,从一开始的一天 2h ,慢慢地到 1.5h ,再到 50min ,最后在读最后一本书的时候,已经到了可以 20min 内完成阅读。

感受到知识的磅礴,也更加坚定了自己的目标。

流利阅读

薄荷阅读

坚持早起读新闻

深知熬夜百害无一利,于是做到了早睡早起。将早上的时间利用起来,听新闻和读新闻。

人民日报打卡

极客早知道打卡

坚持用输出倒逼自己输入

从 4 月初,开始坚持写博客。不想写水文的我坚持原创,坚持优质内容。每一篇文章都认真楷模排版,逻辑和思路,希望对自己负责,也对读者负责。

六月份恰逢更文挑战和新星计划活动的展开,认识了很多垂直领域的大佬,以前从来不爱玩社区的我也开始乐在其中。

在社区中遇到很多业界的号主和大佬,零一、学委、魔王、阿机、三笠……(太多啦不再一一列举),真正感受到了山外有山 🚵🏾。在这个过程中,遇到了很多同行的小伙伴,虽说大家都是卷王,但同时也是内卷受害者。每个人都在坚持原创做好每一篇技术干货,认真输出。

我们就像是一张地图上的不同板块,因为偶然的机会而汇集在了一起。

一群人,深耕于技术写博,致力于互联网开发。

更文数据

更文数据

瓶颈期

在学习的过程中,大概一段时间内就会遇到一个瓶颈期。后来我梳理了以下,发现让我挫败感下降主要有以下几大原因。第一,阶段性任务完成,没有提前给自己设定新任务,会陷入焦虑状态。第二,看不到自己在进步,感觉自己在停滞不动,会非常的焦虑。第三,长期在同一个环境下学习,会感到在一个密闭的圈子里,永无出头之日。

综上几点原因,及时做出调整,降低不必要的时间成本,做更多有效的事情。

🔥 技术 Technology

前端基础

四月初开始补计算机基础,从计网到数构,从浏览器原理到性能优化等等专题。在学习的过程中,深深对自己基础知识的薄弱叹一口气。但是不会就是不会,查漏补缺才是当下应该要做的事情。于是买了很多的基础书,以至于我的书架瞬间填满了。在学习基础知识的过程中,开始写博客总结,归纳整理每个会考的知识点。不断扩充知识的维度,寻找更多的知识点对不饱和的内容进行补充。

书架

新技术

搁置很久的新技术也开始拾了起来,开始学习 vue3 ,开始学习 TS ,开始学习 webpack 。对新技术的感觉就是很容易学过就忘,但好在这回认真的做笔记并缕清逻辑,编写成博客。到后续需要用到这些知识点时,回过头来看博客,很多知识就一目了然了。

vue3+ts

🆙 期末来了 Final

期末月&课设周

6 月 21 号,史上最煎熬的期末月来了。正所谓神仙打架,整个专业都在内卷,从理论考试,到 PHP 课设,再到 Android 课设,没有一科是可以短期速成的。

与慧雯姐、金姐、猪猪和杰哥五人,一起完成最难课设。立下为毕业论文做准备的契机,争取做到最好,最后圆满落幕。

整个过程有着各种各样的摩擦,但就因为这样的摩擦,让我们之间的合作越来越默契。从时间效益、作品最大化效益出发,有时候一个非常难解的问题,因为大家的讨论,个人有个人的知识储备,问题都能得到相对快速的解决。

在课程快结束之时,问专业老师说课设心得是否有上限,👩‍🏫 老师说:没有上限。

🙎‍♀️ 我说:那我能写两三千字。

👩‍🏫 她一惊,老师说:写些重点进去就好了。

课设1

课设2

7 月 7 日下午,考完最后科目,为期大半个月的期末终于结束啦~📢

期末的结束也将意味着大三的结束,而大四的钟声也已经打响~

🔑 下半年目标 Goal

✔️ 秋招顺利

✔️ 清空书架

✔️ 通过 BEC

✔️ 公众号粉丝 Up

📝 最后 End

当一颗蒸不熟煮不烂炒不爆捶不扁响当当的铜碗豆

面对内卷,不被内卷压倒,保持持续学习,扛住卷回去

📐📐📐

文字的力量

不在于绘声绘色

而在于不动声色

📑📑📑

在互联网的鱼龙混杂圈里

保持清醒 持续学习

📸📸📸

机会与努力并存

海有舟可渡 山有路可循

永不言弃 未来可期

👋👋👋

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Growing/YearSummary/002.html b/column/Growing/YearSummary/002.html index e47dc25a..e610a7d0 100644 --- a/column/Growing/YearSummary/002.html +++ b/column/Growing/YearSummary/002.html @@ -19,7 +19,7 @@
Skip to content

📻 叮!

2021 年接近尾声,周一也开始拾起了年终总结。

回顾 2021,有喧嚣,也有欢呼;有奔溃,也有快乐。

但好在 ✏️

对待一件又一件的小事上,始终保持着对自己的要求 📊

不因舒适而放纵,不因辛苦而放弃 📈

日复一日的向着目标奔跑,终将遇见更好的自己。

开始复盘今年的点点滴滴~📌

🎈 漫漫上岸路

准备春秋招

在放弃了考研想法后的我,开始准备春秋招。一直以来,在我心中都有一个进大厂的梦想,但受限于学历的原因,上岸的概率几乎为 0 。在复盘了自己的简历之后,还是想博弈一番。

可以说从三月中旬开始准备春秋招到九月份,一路真的特别不容易。刚开始以为学完计网就可以面试了,结果计网学完,发现还有浏览器原理数据结构与算法前端工程化 webpack ……

中间的春招有投过一些岗位,但因为知识刚学完,还不到完全熟悉的地步,面试可能就是知道有那么个知识,但是却答不出所以然。

一开始的心态就是,怕春招不上岸,秋招更难上岸,所以有时候就特别慌。

但是仔细想想,春招不上岸也没办法呀,我总不能一直处在焦虑状态,所以就在网易二面挂了之后,干脆撇开春招,准备了期末。然后呢,等到期末一结束,马上投身秋招。

与别人不同的是,暑假一样是朝 6 晚 11的生活,一天的学习时间大概也是12-14 个小时左右

关于学历

再说下我的学历,我的学历是三非民办本科,就大家所理解的那种高考踩线过的本科院校。说来,它是一个正处于高阶段发展,但是又没什么人知道的学校。所以一般在面试前面试官都会问我这个学校是否是全日制的……

所以其实在我有了大厂这个目标之后,深知有可能简历一投就直接被沉底,那一般投简历的方式就是找各种内推

其次就是简历加分,现在很庆幸大学几年基本每天都在学习,所以也积淀了一些加分项,一般是实习+项目经验+专业技能+绩点+国赛省赛

但其实我再回过头去复盘简历的时候,发现很多东西还不够亮眼。比如技术深度不够,项目没有什么难点,实习经历 hr 不太 care 等等问题。于是每隔一段时间都会再去复盘我的简历,看下一段时间的成长和收获,有没有新的项目难点和技术点可以增加和替换。

简历修改

比较大的感悟是,身边的学习环境因素也没办法让我尽快获取到最有用的资料。所以,面试要考的所有基础,算法和前端工程化等等内容,只能通过书籍,网上的一些零散博客和资料,然后自己慢慢地去总结和归纳。

准备到一半的时候发现,面试是一场持久战,以后在某个阶段也有可能要面试。如果现在学到的知识不总结出来,那以后面试准备又是从 0 开始。所以开始把我整理的内容进行分类,一个专题一个专题的整理,最后形成自己复习的一套框架。

这里附上整理的「offer 来了」专栏文章:https://juejin.cn/column/7007991853089849351

offer来了

关于内卷

今年其实有很多时候被内卷到,但好在有及时调整过来。说到底,被内卷的原因有以下几点:

  • 看着身边的小伙伴在进步,自己却停滞不前;
  • 跟身边的小伙伴一起在进步,但进度总比别人慢;

出现以上的情况总会给我带来莫名的焦虑,开始怀疑是不是自己不够聪明,学习能力就是比别人差。

但后来复盘后发现,确实学习能力就是比别人差。换位思考一下,深知自己不是天赋型选手,那就勤能补拙。

所以,当被内卷的时候,一定一定要保持清醒,不要和别人比,和自己的上一节点比,要时刻保持自己的节奏,确定当下应该有的目标和计划。而不是看着大家都在学 xxx ,自己也应该去学 xxx 。但其实,当自己有了计划之后就会发现, xxx 可以学,但当下有更重要的目标和任务要去完成。

可以把感兴趣的 xxx 放到未来计划上,做个排列,等以后有时间有精力了再把它从低优先级挪到高优先级中。

额外事物待分配

上岸心得

因为受到学历影响,所以一般能拿到面试的机会都很少。看面经的时候感觉很多小伙伴都是先拿中小厂去海投海面,而我感觉海投海面很耗费时间,连着面试会有点耗费精力,所以在自己学到时间差不多的时候再投递。

大概是 8 月底的时候才开始投递,最终投了百度、字节、腾讯和网易这 4 家公司。收到 3 家公司的面试邀约,最终拿到了 2 家公司的 offer

说实话我感觉我还是算比较幸运的,每家公司收到的面试反馈也都比较快,一般都是 10 天内从面试到 oc

还记得第一回看到面试通过这 4 个字是在今年生日那天,当时人还在校外,激动地抱着我的舍友留下了感动的泪水 😭,手里拿着奈雪的茶一直在颤抖……

在通过了面试之外,感觉像是给这大半年的备试时光划上了圆满句号。

成功上岸卡

百度面经戳这里:百度一二三面面经

想起五月份的时候,因为很少以沟通的方式去回答问题,但又需要背计网和浏览器原理相关的一些文字性一点的知识。于是持续半个多月,每天早上从 8 点开始,读到 12 点,在宿舍旁边的楼道里左右徘徊,来回徘徊,一遍又一遍地反复着说:“面试官您好!我是 xxx 。对于这道题来说,应该怎么怎么样回答。面试官您好!我是 xxx …… ”

计网知识

📚 日常 Daily

时间管理

从一开始的纸质复盘,到中期发现出门都要带上几张每日计划的材料出门感觉会有点冗余,于是改用 notion 做每日计划。

坚持复盘的一年里,发现每一天都有反思到自己存在的不足。复盘的好处在于减少重复工作的发生,比如说:看同一种类型的课程,如果今天学会了,第一次学习要花的时间肯定会更久一点;那么在第二次学习的时候就应该回去看自己的复盘,查看自己曾经在哪一部分踩坑过,有了第一次的教训,第二次学习就会顺畅很多,节省了更多的时间成本。

纸质版notion

notion版计划表

计划可视化

2021 最提上日程的一件事情可以说是计划可视化。每回遇到学习状态松懈的时候,发现很多情况是因为自己学到的知识不能够直观的展示出来,心里或多或少会感觉愧疚。而当把自己当前学习成果直观的罗列出来的时候,看到了一列又一列的数据,心里的幸福感和成就感得到了,学习上也会更有动力

月度复盘清单

复盘清单

7-9 月复盘戳这里:创新视觉下的复盘

关于演讲

演讲以前对我来说是一个很薄弱的地方,而我练习的方式主要有以下三种。

1️⃣ 小汇报 → 演讲

第一种是把每一个小小的汇报都当成演讲。刚开始是学校每一次期末的时候,都会有一些课程需要进行课设汇报。而我把每一次小小的汇报,都认真的写演讲稿并不断地进行练习,以便于在最后的汇报中更顺畅,更流利。渐渐地发现,这种方式很大程度上锻炼了我的演讲能力。

2️⃣ 视听一致

第二种是坚持读新闻和复述新闻。在今年 2 月份开始,每天早起的第一件事是对人民日报听+读。坚持下去的动力还是主播小姐姐的声音是在是太好听惹。

选择人民日报的原因在于人民日报推送的时间是早上 5 点多,这样就能保证每天早上起床就可以看到最新的推送,也不会觉得在读着过时的新闻。

从刚开始对一长串 10 几位的数字都不敏感,嚼着舌根在那里纠正发音和亿万千的状况,到后来慢慢地熟悉句子间的语调和停顿。晨间一个 15min 的微小改变,日复一日的训练就是等待厚积薄发的时刻。

人民日报打卡

3️⃣ 以沟通的方式写博客

第三种是通过写博客的方式与他人沟通。说到这个,当时是为了准备秋招,然后看到上岸的学长学姐说,写博客还加分,所以我在 3 月份开始,就不断的写博客积累。后面慢慢发现,写博客已经变成了一种习惯。且写博客的好处在于,我需要用第三方的语言去把知识点讲给别人听,这间接地其实就是一种与别人交谈的方式。等到写多了慢慢就会发现,自己的语言组织能力也开始丰富了起来,同时,在面试中,你就是用着写博客的语言在跟面试官交流,这间接地会觉得面试是一场对话,而不单单是你问我答的那种状态。

💻 技术提升 Technology

创作成果

去年 5 月份的时候记录了一个 bug ,写了人生中的第一篇博客。从那以后,再也没有创作过。

到今年 3 月份,忘了是从哪里知道的掘金社区,才发现原来博客是可以以知识点的方式去进行创作,而不单单只是记录 bug

于是最开始从专业课的总结开始创作,到学前端各模块的知识,都尽可能的从第三方的视觉出发,用通俗易懂的语言去创作。

这一路的创作历程下来,说难也不难,但好像也挺不容易的。刚开始创作时,每当写完一个知识点的时候,我得返回去看如果把它讲给身边的小伙伴们听,他们能不能理解这个知识点。如果不能理解,要怎么写他们才能更好的理解和明白,这些都是在写博客的时候需要去考虑的一些点。不过虽然前期写的时候会枯燥一点,但慢慢地写多了以后,自己的写作模式也会像被打通了任督二脉一样,在一次又一次的磨练中得到进步。

铛铛铛!接下来就是创作成果啦!

截止目前为止,文章创作篇数 112 篇,总字数应该有 50w60w or 70w

各站数据

今年的创作方向总体偏向于基础知识的创作,因为太深的也写不来。不过相信随着自己学识的长进,文章的内容深度和广度也会慢慢递进,继续加油 ing~

虽说阅读量跟 大V 来比完全不值一提,但也算是近一年来的创作成果。与自己比,在近一年的创作历程中,让我在语言表达上、文笔上等各方面,都有了跳跃性的进步。即便数据量一直处于平平无奇的状态,但相信随着质变和量变的积累,也总会有它绽放光彩的一天。

未来还要写作好多好多年捏,想说写作已经成为终生爱好啦!🎈

博客的心路历程

前期主要以基础为主,刚开始是整理 vue 的内容,基本上会把所有基础的知识点总结归纳一遍。等到学 react 的时候,发现再重新归纳基础的时候,发现有点和学 vue 是一样的做法,撰写博客的时候就会明显感觉速度比之前要快很多。

另外一种还发现到,并不是学的所有知识都适合记录在博客上,那这个时候就需要把这些额外的知识给找个位置来存放。思考了很多种方式,这类笔记的形式应该是让它能够随时随刻查阅,还要主题层次分明

刚开始想着用 notion 来记录,但记录之后发现有时候在外面并不是很方便查阅,并且notion目录呈现可能还不够直观 。于是对于这种类型的笔记,选择了使用飞书文档来记录。我会在飞书文档中先搭建某个知识模块的框架,之后就是往里面进行知识填充。

从某种程度上来讲,这对我来说算是对笔记形式的新突破。以后应该还会有各种新的疑难点出现,继续挖掘 ing~

笔记类新形式

遨游书海

2021 也看了些许书籍。以前都是比较喜欢快餐式学习,不喜欢去啃又厚又难读的书籍。但是今年还是给自己定下了小目标,静下心来去看完几本书。

每每看完一本书的时候,深刻地感到在这浩瀚的知识宇宙里,我是多么渺小的存在。

随着阅读时长的增加,从原来的两个月读 1 本,到一个月读 1 本,再到现在的一个月读 2 本。在这个过程中,慢慢地学会了专注和坚持。

今年还是没能清空书架,所以明年争取尽早清空书架,然后再上新!

💡 活动 Activity

青训营

今年的另一大收获是青训营。训练营整个周期包括青训营+实训营,大概接近 20 天左右。在青训营中,从课程收获、团队合作,再到班会答疑、项目成果等等方面,都让我在各个方面成长了非常多。

虽然周期很短,但基本上接近集训状态,所以行动力也被高度调动了起来。

青训营的收获太多太多辽,详细戳这篇文章:【青训营】- 结营啦!有缘相聚于青训,未来高处见呀 🥂~~

与掘金高校的合作

大概是 10 月份的时候,与掘金高校合作了一场线上活动。以前在学校小打小闹策划了很多线下活动,但与掘金高校的这次活动是线上活动。模式的转变,让我再一次对活动的策划有了新的收获。

初步探讨、沟通渠道,对接社团、线上宣传平台,再到与双方开发人员沟通,每一步的行动与沟通都是一次新的收获与成长。

深刻感受到掘金运营小伙伴的辛苦,在这里 salute 一下~

掘金高校活动

掘金翻译计划

青训营的团队 → 代码敲不队,是一群主动积极、热爱学习、热爱技术的小伙伴,在结营后小组依然保持着浓浓的学习氛围。在 YK 菌童鞋的带动下,约定好一起参加掘金翻译计划,大家根据自己的学习节奏和计划,纷纷认领翻译任务

技术文跟平常的论述文还有点不太一样,有时候可能会出现词汇歧义等各种问题,于是小伙伴们有时候就会提出自己的疑惑出来,大家一起探讨。

犹记得周一的第一篇文章,不知道翻译的怎么样,于是发给身边的朋友看。

结果……朋友说还不如看原文…… u1s1 ,这六个字一开始确实把我打击到了 🤣

不过有错误指出就会有新的进步产生,当下就尽快去复盘下自己的文章。结果发现,为啥我这篇文章能翻译成这么机械,单看中文连我自己都看不懂(差点没把自己吓到……🥶)

出于对自己和对有可能看到文章的读者负责,于是赶紧把文章回炉重造了一番。尽量以第三视角的方式去看文章,要思考一个句子翻译完读者是否上下能衔接住并理解。

掘金翻译计划

翻译小白,如果还有不足的话欢迎大佬们评论区指正评论,知错必改 ing~

搬空掘金的日子

“搬空掘金的日子”,是平常掘友们经常说的一句话。但事实证明,掘金只会活动越来越多,永远搬不空。

3 月初注册的掘金账号,一开始觉得掘金的活动很难,像是小白都参加不了的活动,于是就没有特别注意。

到了 6 月份出现更文挑战,发现掘金的活动对小白创作者极度友好,于是开始进入更文日常。一发不可收拾,每个月都有适合参加的那么一两个活动。

6 月更文挑战,7 月好文召集令,8 月全新更文玩法,9 月青训笔记活动+中秋活动,10 月小知识+掘力星计划,11 月更文又双叒来袭。

现在每天早起的第一件事可能就是先打开掘金签到了 😜

掘金签到

叮,晒一些收到的奖品~

掘金周边

后来掘到的礼品在宿舍放不下就被寄回家给俺爹娘存着辽~(忽略时黑时亮的画质 🤒)

⏰ 其他 Others

小伙伴

2021 年在社区遇到了很多互联网领域的号主和大佬,零一英雄哥小丞同学三笠小卢三心大佬若川巨佬千古壹号……(太多啦),真正感受到了山外有山 🚵🏾。在这个过程中,遇到了很多同行的小伙伴,虽说大家都是卷王,但同时也是内卷受害者。每个人都在坚持原创写好每一篇技术干货,认真输出每一个精彩瞬间。

在青训营也遇到了很多志同道合的小伙伴,@YK 菌@小铭子@昕昕子@前端那同学@Brian@Output@LCK 等。尤为记念大家在一起努力学习课程,熬夜通宵赶项目,一起努力加油干的日子。

值得庆贺的是,青训营同组小伙伴在秋招中也都拿到了各自心仪的大厂 offer ! 👏

📸 未来规划 Future

2022 展望

说一些明年量化的 flag 目标:

  • 精进前端专业技能;
  • 提升产品思维和创新思维;
  • 提升自身软实力;
  • 掘金升级到 Lv4

细化目标等明年年终来还愿。叮,期待未知的 2022~

2022

最后 End

最后就是介绍下我寄己啦!

00 后程序媛 🙆,大家都称呼我为周一

这个名字来源于我的 id 名称:星期一研究室。这个 昵称是前两年申请公众号时起的,到今年开始写博客的时候也一直用这个。久而久之,大家也都习惯称呼我为周一

感觉周一还有点寓意,周一意味着全新的挑战,也希望我在往后每个阶段都能行动力高度调动起来。


最后的最后

希望在互联网的快餐时代里

保持持续学习 做自己的人间清醒~

🔍🔍🔍

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Growing/index.html b/column/Growing/index.html index ae1acad7..5f903173 100644 --- a/column/Growing/index.html +++ b/column/Growing/index.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/Guide/index.html b/column/Guide/index.html index 1a7369c0..d07f11f5 100644 --- a/column/Guide/index.html +++ b/column/Guide/index.html @@ -19,7 +19,7 @@
Skip to content

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Interview/Browser.html b/column/Interview/Browser.html index 2dce12b5..cccbcddb 100644 --- a/column/Interview/Browser.html +++ b/column/Interview/Browser.html @@ -391,7 +391,7 @@ <a/>
<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
 	重磅消息!!
 <a/>

(6)如何防御 csrf

1)验证码

强制用户必须与应用进行交互,才能完成最终请求。此种方式能很好的遏制 csrf ,但是用户体验比较差。

2)Referer check

请求来源限制,此种方法成本最低,但是并不能保证 100% 有效,因为服务器并不是什么时候都能取到 Referer ,并且低版本的浏览器存在伪造 Referer 的风险。

3)token

token 验证的 CSRF 防御机制是公认最合适的方案。

(7)CSRF 与 XSS 区别

🏞️ 五、其他问题

1、Chrome 浏览器用过哪些调试工具

2、浏览器内核的理解

(1)主要分为两个部分渲染引擎js引擎

(2)部分浏览器的内核

🏡 六、结束语

在上文中,从 http 的基础知识,到浏览器缓存问题,再到跨域,前端安全问题,系统地梳理了浏览器在前端面试中的考点。

到这里,本文就讲解结束啦!希望对大家有帮助~

如对文章有补充,或者有发现小细节错误,欢迎小伙伴们评论区留言或联系 vx:MondayLaboratory ,及时订正~

让这份面试内容更加地尽善尽美,造福更多在备试中的小伙伴们!

最后,预祝各位看到这篇文章的小伙伴们,都能够斩获到自己心仪的 offer ~🥂🥂🥂

🐣 彩蛋 One More Thing

🏷️pdf 内容获取

👉 微信关注公众号 星期一研究室 ,回复关键字 浏览器面试pdf 即可获取相关 pdf 内容~

👉 回复 面试大全pdf 可获取全专栏内容!

🏷️ 更新地址

👉 offer 来了面试专栏

- + \ No newline at end of file diff --git a/column/Interview/CSS.html b/column/Interview/CSS.html index de990ba9..fbe7b6ac 100644 --- a/column/Interview/CSS.html +++ b/column/Interview/CSS.html @@ -1367,7 +1367,7 @@ </div> </body> </html>

💡 八、结束语

对于 css 的面试来说, positioncss 选择器优先级以及手写各种布局是久经不衰的话题。所以在复习的过程中,要理解清楚各个知识点所涉及到的内容,这样,在面试中就不难被面试官问倒啦!

到这里,关于 css 的常考面试题讲解就结束啦!希望对大家有帮助~

如文章有误或有想补充的新内容,欢迎加我微信指出呀,👉 vx: MondayLaboratory ~

往后专栏内容如有新补充也将放在下面的更新地址,大家可以戳下方链接直达!

🐣 彩蛋 One More Thing

(:资料获取

👉 微信关注公众号 星期一研究室 ,回复关键字 css面试pdf 即可获取相关资料~

👉 回复 面试大全pdf 可获取全系列资料!

(:更新地址

👉 offer 来了面试专栏

(:番外篇

- + \ No newline at end of file diff --git a/column/Interview/CSSWriting.html b/column/Interview/CSSWriting.html index d162f942..9847a5ce 100644 --- a/column/Interview/CSSWriting.html +++ b/column/Interview/CSSWriting.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/Interview/DataStructure.html b/column/Interview/DataStructure.html index b70993dd..5d7b2e19 100644 --- a/column/Interview/DataStructure.html +++ b/column/Interview/DataStructure.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/Interview/DesignMode.html b/column/Interview/DesignMode.html index d02c7fa5..a49095e4 100644 --- a/column/Interview/DesignMode.html +++ b/column/Interview/DesignMode.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/Interview/Development.html b/column/Interview/Development.html index 8825f130..55b99a9e 100644 --- a/column/Interview/Development.html +++ b/column/Interview/Development.html @@ -19,7 +19,7 @@
Skip to content

🌱 序言

在实际的开发中,开发环境的工具使用,能直观的体现出某个人的工作产出效率。因此,在面试中,面试官也会经常问到关于 gitlinux 等常见的一些面试题。所以,了解相关方面的知识点也是很有必要滴~

那么在下面的这篇文章中,将讲解一些比较常见的开发环境下的知识点,以供大家备试使用。

一起来学习吧~🌱

🌲 一、git

1、为什么要使用 git?

  • 最常用的代码版本管理工具;
  • 大型项目需要多人协作开发,必须熟用 git
  • 如果你知道 git 或者之前不用 git ,很难通过面试;
  • Mac OS 自带 git 命令, windows 可去官网下载;
  • git 服务端常见的有 githubcoding.net 等;
  • 大公司会搭建自己的内网 git 服务。

2、常用的 git 命令

命令用途
git init初始化一个仓库
git clone克隆项目
git add .把所有文件添加上。如果后面有文件名,则只把该文件参加上
git status随时掌握工作区的状态
git diff如果 Git status 告诉你有文件被修改过,用 git diff 可以查看修改内容
git commit -m "xxx"提交一行记录
git push origin master提交到服务端
git pull origin master从服务端拉代码下来
git branch xxx创建新分支,每个人都需要有自己的分支,互不干扰
git checkout -b xxx / git checkout xxx切换分支
git merge xxx做完之后要把主分支合并
git stash把写错的代码先放一边,之后切换分支再放上去
git log穿梭前,用 git log 可以查看提交历史,以便确定要回退到哪个版本
git reflog要重返未来,用 git reflog 查看命令历史,以便确定要回到未来的哪个版本。
git log --graph可以看到分支合并图

3、git 提交规范

下面用一张图来了解下平常我们在提交代码时, git 的一些规范。具体如下图:

git提交规范

🌳 二、Chrome 调试工具

  • Elements
  • Network
  • Console
  • Application
  • debugger
  • 查看内存泄漏等等

🌴 三、抓包

1、抓包工具

  • 移动端 h5 页,查看网络请求,需要用工具抓包;
  • windows 一般用 fiddler 抓包;
  • Mac OS 一般用 charles 来进行抓包。

2、抓包过程

  • 手机和电脑连接同一个局域网;
  • 将手机代理到电脑上;
  • 手机浏览网页,即可抓包;
  • 查看网络请求;
  • 网址代理;
  • https

🌾 四、linux 常用命令

1、为什么要用 linux?

  • 公司的线上机器一般都是 linux (比如阿里云);
  • 测试机也需要保持使用一致的 linux
  • 测试机或者线上机出了问题,本地又不能复现,需要去排查(比如,别人的手机没有问题,另外一个人的手机出现问题,本地环境又不能看是什么错误,这个时候就一定一定要去排查)。

2、linux 常用命令

如下表格:

命令含义
ssh 用户名@ip 地址,如 ssh root@192.168.10.21登录 linux 的线上机或者测试机
ls查看当前文件目录下的所有文件夹
ls -a把隐藏文件夹也一并显示出来
llls 是平铺看文件,ll 是以列表的形式查看所有文件(包括隐藏文件)
clear清空屏幕
mkdir 文件名,如 mkdir abc创建文件夹
rm 文件名删除文件
rm -rf 文件名,如 rm -rf abc删除文件夹
mv 旧文件名 新文件名,如 mv index.html index1.html修改文件 index.html 的名字为 index1.html
tab 键对单词进行填满
cd ../回到上级目录
cp 文件名 1 文件名 2,如 cp a.js b.js拷贝一份 a.js,新拷贝的文件命名为 b.js
touch 文件名,如 touch b.js建立一个空文件
vi 文件名往文件里面添加内容,
vim 文件名往文件里面添加内容,通过 i 键进入编写,es 键退出编写,:w 进行保存,:q!强制退出
vimtutor查看 vim 的教程
cat 文件名打印出该文件的所有内容
head 文件名打印出前面几行
tail 文件名打印出最后几行
grep “关键字” 文件名,如 grep “babel” package.json查询某个文件里面包含关键字的内容

🌿 五、结束语

以上文章讲解了在面试中一些常考的开发环境知识,对于前端的面试来说,开发环境相关的内容考察的相对比较少,所以大家可以通过本文做一个简单的了解。

到这里,关于开发环境的一些常见知识讲到这里就结束啦!希望对大家有帮助~

🐣 彩蛋 One More Thing

🏷️pdf 内容获取

👉 微信搜索 星期一研究室 并关注,回复关键词 开发环境面试pdf 获取相关 pdf 内容~

👉 回复 面试大全pdf 可获取全专栏内容!

🏷️ 更新地址

👉 offer 来了面试专栏

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Interview/Html5.html b/column/Interview/Html5.html index e552ea97..f997058b 100644 --- a/column/Interview/Html5.html +++ b/column/Interview/Html5.html @@ -153,7 +153,7 @@ <source src="jamshed.mp4" type="video/mp4" /> Your browser does'nt support video embedding feature. </video>

9、HTML 全局属性(global attribute)有哪些

✨ 四、结束语

html 相关的内容在面试中考察的部分不多,但该记忆的内容还是得稍微记一下,以防在面试中突然被面试官问倒。

关于 html 相关的题目整理到这里就结束啦!希望对大家有帮助!

如文章有误或有想补充的新内容,欢迎加我微信指出呀,👉 vx: MondayLaboratory~

周一在整个春秋招备试的过程中,深知从 0 到 1准备是非常不容易的。也想要把我所学的所有内容进行整理,让这个面试专栏更加尽善尽美,造福更多在准备面试的小伙伴~💬

往后专栏内容如有新补充也将放在下面的更新地址,大家可以戳下方链接直达~

🐣 彩蛋 One More Thing

(:资料获取

👉 微信关注公众号 星期一研究室 ,回复关键字 html面试pdf 即可获取相关资料~ 👉 回复 面试大全pdf 可获取全系列资料!

(:更新地址

👉 offer 来了面试专栏

(:番外篇

- + \ No newline at end of file diff --git a/column/Interview/JSWriting.html b/column/Interview/JSWriting.html index 60145e9e..76fd7222 100644 --- a/column/Interview/JSWriting.html +++ b/column/Interview/JSWriting.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/Interview/JavaScript.html b/column/Interview/JavaScript.html index b473a839..d64aa0db 100644 --- a/column/Interview/JavaScript.html +++ b/column/Interview/JavaScript.html @@ -2283,7 +2283,7 @@ subject.on(o2); // 我是观察者小明: 明天会下雨 subject.triggle('明天会下雨');

😉 八、结束语

以上收录周一整个秋招备试过程中 JavaScript 的所有面试题,上面的面试题可能还不够全,如有想要补充的内容也欢迎联系 vx:MondayLaboratory ,希望能够让文章内容更加尽善尽美,造福更多备试的小伙伴~

最后,预祝各位看到这篇文章的小伙伴们,都能够斩获到自己心仪的 offer ~

🐣 彩蛋 One More Thing

(:pdf 内容获取

👉 微信关注公众号 星期一研究室 ,回复关键字 js面试pdf 即可获取相关 pdf 内容~

👉 回复 面试大全pdf 可获取全专栏内容!

(:更新地址

👉 offer 来了面试专栏

(:番外篇

- + \ No newline at end of file diff --git a/column/Interview/Leetcode.html b/column/Interview/Leetcode.html index 23075fd5..643b5c96 100644 --- a/column/Interview/Leetcode.html +++ b/column/Interview/Leetcode.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/Interview/Network.html b/column/Interview/Network.html index 24f2edea..f8812cd8 100644 --- a/column/Interview/Network.html +++ b/column/Interview/Network.html @@ -19,7 +19,7 @@
Skip to content

⚾ 序言

大家都知道,计算机网络是前端面试中非常爱考的面试题了,不得不说是八股文的经典。在周一刚开始接触计网时,也是一直看到类似于三次握手四次握手之类的问题。刚开始我是知识比较浮于表面,对计网知识的了解就一直停留在知道有那么一些内容。但随着学习的深入,慢慢地我觉得,在了解一个东西之前,不仅仅要知道它是什么?还要知道它为什么出现?它的出现又解决了什么问题?这样的学习会更加有利于将其运用到我们的日常开发中。

在下面这篇文章中,将分享在秋招备试的过程中我学习计网的一个过程,以及自己整理的关于计网常考的一些面经题。

下面开始进入今天文章的讲解~😜

🏐 一、基础知识环节

1、专栏学习

刚开始面对的是学校发的一本非常厚重的书,u1s1,面对那接近 1000 页的书,我的心里其实蛮奔溃的。后面在机缘巧合下,在一个公众号上看到了一位前端博主的文章,零一。紧接着在 csdn 上看到他写的很多精选专栏,看完他的博客之后,才下意识地感觉……原来还有写的这么好的文章。这一段废话有点多……以后有机会再谈。

我当时先学的是零一博主的 TCP 专栏,博主的每一篇文章对小白都是极其友好类型,非常地通俗易懂。下面附上 TCP 专栏相关的文章链接 👇

序号文章链接
1【TCP/IP】概述网络分层以及协议介绍https://lpyexplore.blog.csdn.net/article/details/108925528
2【TCP/IP】IP 地址的划分及其分类https://lpyexplore.blog.csdn.net/article/details/108935757
3【TCP/IP】链路层的简单认识https://lpyexplore.blog.csdn.net/article/details/109248705
4【TCP/IP】详解 DNS 具体作用过程https://lpyexplore.blog.csdn.net/article/details/109128967
5【TCP/IP】图解 TCP 的通信机制https://lpyexplore.blog.csdn.net/article/details/109133096
6专栏传送门https://blog.csdn.net/l_ppp/category_10448348.html

以上文章可以按顺序学哦~

2、书籍学习

学习完上面的 5 篇博客之后,前后大概花了15-20h左右的时间。看完之后,算是稍微入了个门。但是计网的内容远远不止这些,所以,在学习了博客文章之后,我继续用书籍来深挖知识点。

搜寻了知乎和豆瓣,还有身边的小伙伴的推荐,大家都说对前端比较友好的书籍是: 《图解 TCP/IP》 这一本书。看下图 👇

计网书籍推荐

这本书以图解的形式,讲解了计算机网络的大部分知识。可以说对入门选手和对看书就容易犯困的小伙伴来说实在是太太太友好了……强烈安利!

看完这本书之后,应对面试基本上算是足够了。如果还有想要深挖的小伙伴,可以去看深色封面的那本书……只是听过,但是我没有看过,所以这里只简单概括一下~

有了基础知识预备之后,就可以看一下一些面经题目,尝试着回顾和用自己的话语来回答。同时在文章下面的内容中,我也将对我遇到的系列题目进行归纳总结~

⚽ 二、思维导图环节

我们先用一张思维导图来了解该系列面经题的知识体系。具体如下图 👇

计算机网络面试复习框架

思维导图收入囊中,下面开始分享面经题的解答流程~

🎳 三、OSI 七层模型

1、OSI 模型是什么?

OSI 七层模型,即网络通信的七个层次。之所以将其分为七个层次,是为了让开发人员可以在不同领域分别实现整个系统的不同部分。就像一个非常庞大的工程,每个员工都有自己擅长的岗位和专门负责的工作。

那么七个层次主要包括:物理层、数据链路层、网络层、传输层、会话层、表示层以及应用层。

接下来谈论各个层次的作用。

第一个,应用层。应用层是为应用程序提供服务并规定应用程序中通信相关的细节。包括文件传输、电子邮件、远程登录(虚拟终端)等协议。

第二个,表示层。表示层是将应用处理的信息转换为适合网络传输的格式,或将来自下一层的数据转换为上一层能够处理的格式。因此它主要负责数据格式的转换。

第三个,会话层。会话层是负责建立和断开通信连接,以及数据的分割等数据传输相关的管理。

第四个,传输层。传输层起着可靠传输的作用,它只在通信双方的节点上进行处理,而无需在路由器上处理。

第五个,网络层。网络层将数据传输到目标地址上,目标地址可以是多个网络通过路由器连接而成的某一个地址。因此这一层主要负责寻址和路由选择

第六个,数据链路层。数据链路层负责物理层面上互联的、结点之间的通信传输。

第七个,物理层。负责 0、1 比特流(0、1 序列)与电压的高低、光的闪灭之间的互换。

2、OSI 七层模型遵循原则

OSI 参考模型遵循五个原则:

  • 各个层级之间有清晰的边界,便于理解各个层级的功能;

  • 每个层实现的功能不一样,并且不会互相影响;

  • 层与层之间是服务与被服务关系;

  • 层次划分有利于国际标准协议的制定;

  • 层次数目越多,就越能避免各个层之间的功能重复

🏏 四、TCP 与 UDP

1、TCP 与 UDP 的区别

TCPUDP
TCP 在传输层上UDP 在传输层上
面向连接面向无连接
面向字节流面向报文
一对一通信一对一、一对多、多对一、多对多通信
需要建立可靠的连接不需要建立可靠的连接
适用于可靠传输的应用:web browsing、email、文件传输等适用于实时应用:线上游戏、直播、IP 电话、语音会议等

白话文回答:

  • TCP 是面向连接的,UDP 是面向无连接的,即发送数据前不需要建立连接。
  • TCP 提供可靠的传输服务,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达,而 UDP 则是尽最大努力交付,不保证可靠传输。
  • 因此,因为 TCP 可靠,面向连接且不会丢失数据,所以 TCP 适合大数据量的交换。
  • TCP 面向字节流,实际是 TCP 把数据看成是一连串无结构的字节流UDP 则是面向报文的,且没有拥塞控制,因此,网络出现拥堵的情况下不会使原主机的发送速率降低,但是这个过程会出现丢包,所以它对实时的应用很有用,比如 IP 电话、视频会议和直播等等。
  • 每一条 TCP 连接,只能是一对一的,UDP 则支持一对一、一对多、多对一和多对多的交互通信。
  • TCP 的首部开销为20 字节,而 UDP 的只有8 字节
  • 综上所述,TCP 是面向连接的可靠性传输,而 UDP 则是不可靠的。

注: TCP 需建立三次连接、且 TCP 的包可以进行分组发送,会产生建立连接开销和分组开销。

2、TCP/UDP 的优缺点

(1)TCP 的优点

  • 可靠、稳定。

  • TCP 的可靠体现在 TCP 在传递数据之前,会有三次握手来建立连接;

  • 且在数据传递时,有确认窗口重传拥塞控制等机制;

  • 在数据完成传送以后,还会通过断开连接来节约资源。

(2)TCP 的缺点

  • 慢、效率低、占用系统资源高,易被攻击。
  • TCP 在传递数据前,要先建立连接,这会消耗时间;
  • 且在传递数据时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间;
  • 同时要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的 CPU 、内存等硬件资源;
  • 而且,因为 TCP 有三次握手机制,这些也会导致 TCP 容易被人利用,实现 DOSDDOS 等攻击。

(3)UDP 的优点

  • 快、比 TCP 稍安全。
  • UDP 是一个无状态的传输协议,且 UDP 没有 TCP 的握手、确认、窗口、重传、拥塞控制等机制,所以它在传递数据时非常快。没有 TCP 的这些机制,UDPTCP 能被攻击者利用的漏洞就要少一些。
  • UDP 也是无法避免攻击的,比如:UDP flood 攻击。

(4)UDP 的缺点

  • 不可靠、不稳定。
  • 因为 UDP 没有 TCP 那些可靠的机制,所以在数据传递时,如果网络质量不好,就会很容易丢包

3、DDOS 攻击(由 TCP 和 UDP 的缺点引出 DDOS 攻击问题)

(1)什么是 DDOS 攻击?

  • 分布式拒绝服务攻击(Distributed denial of sevice attack);
  • 即向目标系统同时提出数量庞大的服务请求。

(2)DDOS 攻击方式?

攻击者如何攻击目标主机呢?

  • 通过使网络过载干扰甚至阻断正常的网络通讯。
  • 通过向服务器提出大量的服务请求、使服务器超负荷。
  • 阻断某一用户访问服务器。
  • 阻断某服务与特定系统或个人的通讯。

(3)如何应对 DDOS 攻击?

  • 黑名单。
  • DDOS 清洗:对用户请求的数据进行实时监控,及时发现 DOS 攻击等异常流量,在不影响正常业务开展的情况下清洗掉这些异常流量。
  • CDN 加速。
  • 高仿服务器:高仿服务器主要是指能独立防御50Gbps 以上 ( 1Gbps=1024Mbps,即每秒1000M ) 的服务器,能够帮助网站拒绝服务攻击,定期扫描网络主节点

4、TCP 为什么可靠?

  • TCP 会通过检验和序列号确认应答重发控制连接管理窗口控制等机制实现可靠性传输。
  • 那如何通过以上机制来实现可靠性传输呢?
  • TCP 中,当发送端的数据到达接收主机时,接收端主机会返回一个已收到消息的通知。这个消息叫做确认应答 (ACK) 。(确认应答)
  • 相反,当发送端发送数据出去之后,且在一段时间内,没有等到确认应答,则数据极有可能出现丢失的情况。
  • 如果在一定时间内没有等到确认应答,那么发送方就可以认为数据已经丢失,并进行重发。由此,即使产生了丢包,仍然能够保证数据能够到达对端,实现可靠传输。(丢包重发)
  • 此外,也有可能因为一些其他原因导致确认应答延迟到达,此时,发送主机同样会按照机制重发数据。(延迟重发)
  • 但是这对于目标主机来说,简直是一个巨大的灾难。因为目标主机会反复收到相同的数据。
  • 为此,需要引入一种新的机制,序列号。序列号能够识别是否已经接收数据,及是否需要接收数据。(序列号)
  • 序列号是按照顺序给发送数据的每一个字节都标上号码的编号。接收端会查询所接收数据中 TCP 首部的序列号和数据的长度,将自己下一步应该接收的序号作为确认应答返送回去。(序列号)
  • 就这样,通过序列号、确认应答等机制,实现 TCP 的可靠传输。

注: 序列号主要是让接收端可以丢弃数据并返回下一个应答号,这样就不会频繁地收到同一个数据。

5、TCP 的三次握手和四次挥手

(1)TCP 的三次握手

场景模拟:

  • 如通话一样,比如我现在跟面试官您打电话。那我会先问,喂,您好,听得到吗?
  • 你会回我说,听到啦!那你能听到我的话吗?
  • 我会再回你说,听到了,我们可以开始聊天了。

三次握手:

  • 首先,客户端会发送一个带有 SYN 标志的数据包给对方;
  • 接收方收到以后,会返回一个带有 SYN/ACK 标志的数据包返回给发送端,代表成功传达消息;
  • 之后发送端再回传一个带有 ACK 标志的数据包,代表握手结束。

(2)TCP 为什么要三次握手?

  • 验证服务端和客户端是否遵循 TCP/IP 协议;
  • 为了防止已失效的连接请求报文段突然又传送到服务端,避免错误产生。

(3)TCP 的四次挥手

第一次挥手:

  • 客户端进程发出连接释放报文,并且停止发送数据

第二次挥手:

  • 服务器收到连接释放报文,发出确认报文,此时,服务端就进行了 close-wait (关闭等待)状态。(客户端向服务器方向释放了,但是服务器发送数据,客户端依然要接收)
  • 客户端收到服务器的确认请求后,客户端就进入了 Fin-wait-2 (终止等待 2)状态,等待服务器发送连接释放报文(在这之前还需要接收服务器发送的最后数据)。

第三次挥手:

  • 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,服务器就进入了 Last-ack (最后确认)。

第四次挥手:

  • 客户端收到服务器的连接释放报文后,必须发出确认,客户端就进入了 time-wait (时间等待)状态。
  • 服务端只要收到了客户端发出的确认,立即进入 closed 状态。
  • 至此,就结束了这次的 TCP 连接。(服务器结束 TCP 连接的时间要比客户端早一些)

(4)TCP 为什么要四次挥手?

  • 之所以要四次挥手,其实是确保双方数据都已发送完毕

  • TCP 是全双工模式,这就意味着,当 主机1 发送 FIN 报文段时,只是表示 主机1 已经没有数据要发送了, 主机1 告诉 主机2 ,它的数据已经全部发送完毕了。

  • 主机2 返回 ACK 报文段时,表示它已经知道 主机1 没有数据发送了,但是 主机2 还是可以发送数据到 主机1 的。

  • 主机2 也发送了 FIN 报文段时,这个时候就表示 主机2 也没有数据要发送了,就会告诉 主机1 ,我也没有数据要发送了。

  • 最后, 主机1 再发送 ACK 报文段来确认握手结束,之后彼此就会愉快的断开此次的 TCP 连接。

(5)什么是面向连接协议?什么是面向无连接协议?

面向连接协议:

  • 通信双方在通信时,需要事先建立好一条虚拟的通信线路。
  • 通信过程有“建立连接维护连接断开连接“三个阶段。

面向无连接协议:

  • 与面向连接相对,通信双方不需要事先建立通信线路,而是把每个带有目的地址的报文分组送到通信线路上,由系统自主选定线路进行传输。
  • 面向无连接只有“传送数据”的过程。

(6)为什么建立连接是三次握手,关闭连接是四次挥手呢?

  • 建立连接的时候,服务器在 listen 状态下,收到建立连接请求的 SYN 报文后,服务器把 ACKSYN 放在一个报文里发送给客户端。
  • 而关闭连接时,服务器收到对方的 FIN 报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必所有数据都已经发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方,之后 ③ 己方再发送 FIN 报文给对方来表示同意现在关闭连接。因此,己方 ACKFIN 一般都会分开发送,从而导致多了一次。

注: ①②③ 表示第一二三次挥手

(7)如果已经建立了连接,但是客户端突然出现故障了该怎么办?

  • TCP 还有一个保活计时器
  • 当客户端出现故障时,服务器肯定是不会一直等待下去,白白浪费资源的。
  • 服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常设置为 2h ,若 2h 还没有收到客户端的任何数据,服务器就会发送一个 探测报文段 给客户端,以后每隔 75s 发送一次。
  • 若一连发送 10 个探测报文段 仍没有反应,服务器就认为客户端出了故障,紧接着就会关闭连接。

注: 10x75=750s=12.5min

🏒 五、TCP 的通信机制

1、TCP 的重发控制

  • 我们都知道,在数据传输过程中可能会因为各种原因出现丢包现象,而当出现丢包现象时,即发送端在发完数据并等待一段时间以后,未接收到接收方应答,则视为丢包,于是就会进行重发。
  • 其中,丢包现象分为两种:发送过程丢包;接收过程丢包。
  • 那么,发送端发送完数据以后多久没有收到确认应答才判定数据丢包了呢?
  • 这个一般都是随着网络环境的变化而变化的, TCP 会在每次发包时计算往返时间以及偏差来决定等待时间。
  • 若重发后又出现了丢包,则下一次等待的时间会以2 倍4 倍的指数函数增长。
  • 但它肯定是不会无限进行重发的,当重发次数达到一定程度后[1],会判定为网络异常,两端通信就会被强制关闭。

[1]:TCP 有一个保活计时器,如果在 2h 后还没有收到客户端的数据,那么就会重新复位这个计时器,之后每隔 75s 会发送一次,如果一连发送 10 个还是没有收到,那么就会断开连接。

2、TCP 的滑动窗口控制

解题:

  • 什么原因导致需要有滑动窗口?
  • 有了滑动窗口后可以解决什么问题?

白话文回答:

  • 我们都知道,数据不应该一次性发送,不然丢失了都不知道往哪里找,因此应该采取 分段发送 的措施。
  • 但是呢, TCP 将数据分段发送,虽然提高了传输的可靠性,但是存在着一个致命的缺点,那就是 效率非常低
  • 因为每发送一段数据,都要等待接收端的确认应答后才能继续发送,若整个数据的分段较多,那么通信的性能就会很低了,因此 TCP 引入了 窗口 这个概念。
  • 所谓窗口,表示的是无需等待接收方的确认应答而可以连续发送多段数据
  • 举个例子:假设要发送 4 段数据,如果每次都要发送后接收完才能再重新发送,那来回就得 8 次。但如果用滑动窗口的话,四段数据可以同时发出去,接收端再返回相应的确认应答给发送方。
  • 这个时候发送方会根据相应的确认应答继续发送比该确认序列中序列号大的数据即可。

3、滑动窗口的重发控制

  • 若使用滑动窗口这一技术后,即使某段数据出现丢包现象,也不会造成很大的影响。
  • 因为接收端会一边接收发送端传过来的数据,一边用某种方式告知发送端前面丢失了哪一段数据。

4、TCP 的流量控制机制

为什么需要流量控制机制?

  • 有时,发送端发送给接收端的数据超过了接收端的最大承载能力,就会造成数据无法接收的情况,从而导致之后会进行数据重发,这样子会非常浪费性能

如何解决这种问题呢?引出流量控制机制

  • 为了防止上述情况发生,TCP 提供了一种机制(即流量控制机制)来使得发送端每次发送的数据尽可能的在接收端的承载范围之内
  • 而实现方式就是, 接收端发送端 告知自己能够接收的数据大小,如此一来,发送端每次发送的数据就都不会超过该值,我们成该值为窗口大小
  • 一旦接收端暂时无法接收任何数据,它会告知发送端,因此发送端会暂停数据的发送
  • 但为了后续数据的正常发送,发送端会不时地向接收端发送一个 窗口探测 ,试探性地看一下接收端能否继续接收数据

5、TCP 的拥塞控制

  • 因为出现了窗口控制,数据不再是一段一段发送,而是连续发送多段数据包,因此有时候如果出现网络拥堵的情况下,而我们又同时发送了大量的数据包,这很有可能会导致网络瘫痪。
  • TCP 运用了一种叫做 慢启动 的技巧缓解上述问题。那何为 慢启动 呢?
  • 就是不要在一开始就瞬间发送大量数据包,而是先发送一部分,然后再根据收发情况再发送更多的数据包。
  • 总结就是每次发送的数据包会以 1,2,4 的指数型增长,但窗口大小也不会无限指数型增大,而是会达到某个值时进行一些调整,该值称为 慢启动阈值

流量控制机制和拥塞控制机制的区别:

  • 流量控制是以接收端为主导,接收端明确自己想要的窗口大小,然后发送端再把数据发送给接收端;
  • 而拥塞控制机制则是以发送端为主导,发送端试探性的以 1,2,4 的指数型增长给接收端发送数据,探测接收端的承载能力,等到接收端不能再接收数据时,发送端就会知道接收端没法承载这么多数据,于是就会进行向下调整。

🏸 六、结束语

在上面的这篇文章中,介绍了两种关于计算机网络知识的学习方式,同时,也用了 24 道题目来帮助大家更好地理解计网在前端面试中考察的内容。

对于前端来说,计网考察的内容相对会比较浅层,所以周一也用比较通俗易懂的方式去梳理一些经典的题目。如果有想要再继续深入学习的小伙伴,也可以看书籍继续补充自己的知识深度~

最后,预祝看到这篇文章的小伙伴们,都能够斩获到自己心仪的 offer ~

🐣 彩蛋 One More Thing

🏷️pdf 内容获取

👉 微信关注公众号 星期一研究室 ,回复关键字 计网面试pdf 即可获取相关 pdf 内容~

👉 回复 面试大全pdf 可获取全专栏内容!

🏷️ 更新地址

👉 offer 来了面试专栏

🏷️ 番外篇

  • 如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😉
  • 以上就是本文的全部内容!我们下期见!👋👋👋

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Interview/Node.html b/column/Interview/Node.html index 94d3a08b..d632afdf 100644 --- a/column/Interview/Node.html +++ b/column/Interview/Node.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/Interview/OperatingSystem.html b/column/Interview/OperatingSystem.html index 4bf3a91c..bd06d413 100644 --- a/column/Interview/OperatingSystem.html +++ b/column/Interview/OperatingSystem.html @@ -19,7 +19,7 @@
Skip to content

🎹 序言

操作系统对于前端来说考察的内容并不多,所以在今天的文章中将依据比较常考的知识点进行归纳总结。

下面开始本文的讲解~

🎸 一、思维导图

我们先用一张思维导图来梳理操作系统相关的面试题。具体如下 👇

OS面试题复习框架

下面开始归纳操作系统常见的面试题。

🎺 二、常见面试题

1、进程和线程以及它们的区别

  • 进程是对程序运行时的封装,是系统进行资源调度和分配的的基本单位,实现了操作系统的并发;
  • 线程是进程的子任务,是CPU 调度和分配的基本单位,用于保证程序的实时性,实现进程内部的并发;
  • 一个程序至少有一个进程,一个进程至少有一个线程,线程依赖于进程而存在;
  • 进程在执行过程中拥有独立的内存单元,而多个线程共享进程的内存。

2、进程间通信的几种方式

(1)管道(pipe)及命名管道(named pipe)

  • 管道可用于具有亲缘关系的父子进程间的通信。
  • 命名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

(2)信号(signal)

  • 信号是一种比较复杂的通信方式,用于通知和接收某个已经发生的进程事件。

(3)消息队列

  • 消息队列是消息的链接表,它克服了以上两种通信方式中信号量有限的缺点。
  • 具有写权限的进程可以按照一定的规则向消息队列中添加新信息。
  • 对消息队列有读权限的进程则可以从消息队列中读取信息。

(4)共享内存

  • 可以说这是最有用的进程间通信方式。
  • 它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。
  • 这种方式需要依靠某种同步操作,如互斥锁和信号量等。

(5)信号量

  • 主要作为进程之间及同一种进程的不同线程之间的同步和互斥手段;

(6)套接字

  • 这是一种更为一般的进程间通信机制,它可用于网络中不同机器之间的进程间通信,应用非常广泛。

3、线程同步的方式

(1)互斥量 Synchronized/Lock

  • 采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。
  • 因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。

(2)信号量 Semphare

  • 它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量

(3)事件(信号)Wait/Notify

  • 通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作。

4、什么是死锁?死锁产生的条件?

(1)死锁的概念

  • 在两个或者多个并发进程中,如果每个进程持有某种资源而又等待其它进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。
  • 通俗的讲,就是两个或多个进程无限期的阻塞相互等待的一种状态。

(2)死锁产生的四个必要条件

  • 互斥:至少有一个资源必须属于非共享模式,即一次只能被一个进程使用;若其他申请使用该资源,那么申请进程必须等到该资源被释放为止。
  • 占有并等待:一个进程必须占有至少一个资源,并等待另一个资源,而该资源为其他进程所占有。
  • 非抢占:进程不能被抢占,即资源只能被进程在完成任务后自愿释放。
  • 循环等待:若干进程之间形成一种头尾相接的环形等待资源关系。

(3)处理死锁的基本策略和常用方法

  • 解决死锁的基本方法主要有预防死锁避免死锁检测死锁解除死锁鸵鸟策略等。

5、进程有哪几种状态?

**(1)就绪状态:**进程已获得除处理机以外的所需资源,等待分配处理机资源。

**(2)运行状态:**占用处理机资源运行,处于此状态的进程数小于等于 CPU 数。

(3)阻塞状态: 进程等待某种条件,在条件未满足之前无法执行。

6、线程有几种状态?

在 Java 虚拟机 中,线程从最初的创建到最终的消亡,要经历若干个状态

  • 创建 (new) 、就绪 (runnable/start) 、运行 (running) 、阻塞 (blocked) 、等待 (waiting) 、时间等待 (time waiting) 和 消亡 (dead/terminated)
  • 在给定的时间点上,一个线程只能处于一种状态。

7、段式存储管理

(1)段式存储管理是什么?

段式存储管理是一种符合用户视角的内存分配管理方案

在段式存储管理中,将程序的地址空间划分为若干段(segment),如代码段、数据段、堆栈段;

这样每个进程有一个二维地址空间,相互独立,互不干扰。

(2)段式管理的优缺点

  • 优点没有内碎片(因为段大小可变,可通过改变段大小来消除内碎片)。
  • 缺点:但段换入换出时,会产生外碎片(比如 4k 的段换 5k 的段,会产生 1k 的外碎片)。

(3)页式存储管理方案

页式存储管理方案是一种用户视角下内存与物理内存相分离内存分配管理方案

在页式存储管理中,将程序的逻辑地址划分为固定大小的页 (page) ,而物理内存划分为同样大小的帧,程序加载时,可以将任意一页放入内存中任意一个帧,这些帧不必连续,从而实现了离散分离

(4)页式存储管理的优缺点

  • 优点:没有外碎片(因为页的大小固定)。
  • 缺点:但会产生内碎片(一个页可能填充不满)。

8、进程调度策略

(1)FCFS(先来先服务,队列实现,非抢占的)

先请求 CPU 的进程先分配到 CPU

(2)SJF(最短作业优先调度算法)

平均等待时间最短,但难以知道下一个 CPU 区间长度。

(3)优先级调度算法(可以是抢占的,也可以是非抢占的)

优先级越高越先分配到 CPU ,相同优先级先到先服务。

存在的主要问题是:低优先级进程无穷等待 CPU ,会导致无穷阻塞或饥饿。

解决方案:老化(即对超过一定时间还未使用的进程进行删除)。

(4)时间片轮转调度算法(可抢占的)

队列中没有进程被分配超过一个时间片的 CPU 时间,除非它是唯一可运行的进程。

如果进程的 CPU 区间超过了一个时间片,那么该进程就被抢占并放回就绪队列。

(5)多级队列调度算法

就绪队列分成多个独立的队列,每个队列都有自己的调度算法,队列之间采用固定优先级抢占调度。

其中,一个进程根据自身属性被永久地分配到一个队列中。

(6)多级反馈队列调度算法

与多级队列调度算法相比,其允许进程在队列之间移动:若进程使用过多 CPU 时间,那么它会被转移到更低的优先级队列

在较低优先级队列等待时间过长的进程会被转移到更高优先级队列,以防止饥饿发生。

9、页面调度算法

FIFO 先进先出算法:在操作系统中经常被用到,比如作业调度(主要实现简单,很容易想到)。

LRU(Least recently use)最近最少使用算法:根据开始使用时间到现在为止时间长短来判断。

LFU(Least frequently use)最少使用次数算法:根据使用次数来判断。

OPT(Optimal replacement)最优置换算法:理论的最优,所谓理论,就是要保证置换出去的是不再被使用的页,或者是在实际内存中最晚使用的页。

10、局部性原理

(1) 时间上的局部性最近被访问的页在不久的将来还会被访问。

(2)空间上的局部性内存中被访问的页周围的页也很可能被访问。

🎻 三、结束语

大家可以看到,对于操作系统的面试来说,基本上都在围绕着进程和线程这两个概念交谈。所以在学习的过程中,可以以这两个点来作为主线来对知识点进行扩充和归纳。

关于操作系统的面经归纳到这里就结束啦!希望对大家有帮助~

🐣 彩蛋 One More Thing

🏷️pdf 内容获取

👉 微信关注公众号 星期一研究室 ,回复关键字 操作系统面试pdf 即可获取相关 pdf 内容~

👉 回复 面试大全pdf 可获取全专栏内容 📂

🏷️ 更新地址

👉 offer 来了面试专栏

🏷️ 番外篇

  • 如果您觉得这篇文章有帮助到您的的话不妨点赞支持一下哟~~😉
  • 以上就是本文的全部内容!我们下期见!👋👋👋

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Interview/Performance.html b/column/Interview/Performance.html index 687a50a9..06e73493 100644 --- a/column/Interview/Performance.html +++ b/column/Interview/Performance.html @@ -47,7 +47,7 @@ perspective:1000;

(2) 尽可能少使用 box- shadowsgradients,它们往往严重影响页面的性能,尤其是在一个元素中同时都使用时。

(3) 尽可能让动画元素脱离文档流,以减少重排,如以下代码所示。

css
position: fixed;
 position: absolute;
position: fixed;
 position: absolute;

4、针对 JavaScript,如何优化性能?

(1) 缓存 DOM 的选择和计算。

(2) 尽量使用事件委托模式,避免批量绑定事件。

(3) 使用 touchstart touchend 代替 click

(4) 合理使用 requestAnimation Frame 动画代替 setTimeOut

(5) 适当使用 canvas 动画。

(6) 尽量避免在高频事件(如 TouchMoveScroll事件)中修改视图,这会导致多次渲染。

5、jQuery 性能优化如何做?

(1)使用最新版本的 jQuery 类库

(2)使用合适的选择器

(3)以数组方式使用 jQuery 对象

(4)使用事件委托模式

(5)使用 join()来拼接字符串

(6)合理利用 HTML5 中的 data 属性

🗨️ 二、网站端、移动端优化

1、谈谈你对重构的理解。

网站重构是指在不改变外部行为的前提下,简化结构、添加可读性,且在网站前端保持一致的行为。也就是说,在不改变 UI 的情况下,对网站进行优化,在扩展的同时保持一致的 UI

对于传统的网站来说,重构通常包括以下方面。

深层次的网站重构应该考虑以下方面。

2、列举你知道的 Web 性能优化方法。

具体优化方法如下:

3、移动端性能如何优化?

优化方式如下。

4、哪些方法可以提升网站前端性能?

5、谈谈性能优化问题。

可以在以下层面优化性能。

6、如果一个页面上有大量的图片(大型电商网站),网页加载很慢,可以用哪些方法优化这些图片的加载,从而提升用户体验?

7、如何对网站的文件进行优化?

8、请说出几种缩短页面加载时间的方法。

具体方法如下:

(1) 优化图片。

(2) 选择图像存储格式(比如, GIF 提供的颜色较少,可用在一些对颜色要求不高的地方)。

(3) 优化 CSS (压缩、合并 CSS )。

(4) 在网址后加斜杠。

(5) 为图片标明高度宽度(如果浏览器没有找到高度和宽度这两个参数,它需要一边下载图片一边计算大小。如果图片很多,浏览器需要不断地调整页面。这不但影响速度,而且影响浏览体验。当浏览器知道高度和宽度参数后,即使图片暂时无法显示,页面上也会腾出图片的空位,然后继续加载后面的内容,从而优化加载时间,提升浏览体验)。

9、你知道哪些优化性能的方法?

具体方法如下。

(1) 减少 HTTP 请求次数,控制CSS SpriteJavaScriptCSS 源码、图片的大小,使用网页 GzipCDN 托管、data 缓存、图片服务器。

(2) 通过前端模板 JavaScript 和数据,减少由于 HTML 标签导致的带宽浪费,在前端用变量保存 Ajax 请求结果,每次操作本地变量时,不用请求,减少请求次数。

(3)innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 JavaScript 性能。

(4) 当需要设置的样式很多时,设置 className 而不是直接操作 Style

(5) 少用全局变量,缓存 DOM 节点查找的结果,减少 I/O 读取操作

(6) 避免使用 CSS 表达式,它又称动态属性

(7) 预加载图片,将样式表放在顶部,将脚本放在底部,加上时间戳

(8) 避免在页面的主体布局中使用表,表要在其中的内容完全下载之后才会显示出来,显示的速度比 DIV+CSS 布局慢。

10、你知道哪些 SEO 搜索引擎优化的方法?

🗯️ 三、代码、服务器端优化

1、平时你是如何对代码进行性能优化的?

(1)利用性能分析工具监测性能,包括静态 Analyze 工具和运行时的 Profile 工具(在 Xcode 工具栏中依次单击 Product→ Profile 项可以启动)。

(2)比如测试程序的运行时间,当单击 Time Profiler 项时,应用程序开始运行,这就能获取到运行整个应用程序所消耗时间的分布和百分比。为了保证数据分析在同一使用场景下的真实性,一定要使用真机,因为此时模拟器在 Mac 上运行,而 Mac 上的 CPU 往往比 iOS 设备要快。

2、如何优化服务器端?

具体方法如下:

(1)对组件启用 Gzip 压缩。

(2)延长资源缓存时间,合理设置资源的过期时间,对于一些长期不更新的静态资源,其过期时间可以设置得长一些。

(3)减少 cookie 头部信息的大小,头部信息越大,资源传输速度越慢。

(4)图片或者 CSSJavaScript 文件均可使用 CDN 来加速。

3、如何优化服务器端的接口?

具体方法如下:

(1)接口合并:如果一个页面需要请求两部分以上的数据接口,则建议合并成一个以减少 HTTP 请求数。

(2)减少数据量:去掉接口返回的数据中不需要的数据。

(3)缓存数据:首次加载请求后,缓存数据;对于非首次请求,优先使用上次请求的数据,这样可以提升非首次请求的响应速度。

4、如何优化脚本的执行?

脚本处理不当会阻塞页面加载、渲染,因此在使用时需注意。

(1)CSS 写在页面头部,把 JavaScript 程序写在页面尾部或异步操作中。

(2) 避免图片和 iFrame 等的空 src ,空 src 会重新加载当前页面,影响速度和效率。

(3) 尽量避免重设图片大小。重设图片大小是指在页面、CSS JavaScript 文件等中多次重置图片大小,多次重设图片大小会引发图片的多次重绘,影响性能

(4) 图片尽量避免使用DataURLDataURL 图片没有使用图片的压缩算法,文件会变大,并且要在解码后再渲染,加载慢,耗时长。

5、页面渲染有哪些优化方式?

具体方法如下:

(1) 通过 HTML 设置 Viewport 元标签, Viewport 可以加速页面的渲染,如以下代码所示。

html
<meta name="viewport" content="width=device=width,initial-scale=1" />
<meta name="viewport" content="width=device=width,initial-scale=1" />

(2) 减少 DOM 节点数量,DOM 节点太多会影响页面的渲染,应尽量减少 DOM 节点数量。

(3) 尽量使用 CSS3 动画,合理使用 requestAnimation Frame 动画代替 setTimeout ,适当使用 canvas 动画(5 个元素以内使用 CSS 动画,5 个元素以上使用 canvas 动画( iOS 8 中可使用 webGL )。

(4) 对于高频事件优化 Touchmove , Scroll 事件可导致多次渲染。

(5) 提升 GPU 的速度,用 CSS 中的属性( CSS3 transitionsCSS3 3D transformsOpacityCanvasWebGLVideo )来触发 GPU 渲染。

6、如何设置 DNS 缓存?

在浏览器地址栏中输入 URL 以后,浏览器首先要查询域名 hostname 对应服务器的 IP 地址,一般需要耗费20~120ms的时间。

DNS 查询完成之前,浏览器无法识别服务器 IP ,因此不下载任何数据。基于性能考虑,ISP 运营商、局域网路由、操作系统、客户端(浏览器)均会有相应的DNS 缓存机制。

(1)正 IE 缓存 30min ,可以通过注册表中 DnsCacheTimeout 项设置。

(2)Firefox 混存 1min ,通过 network.dnsCacheExpiration 配置。

(3)在 Chrome 中通过依次单击 “设置”→“选项”→“高级选项” ,并勾选 “用预提取 DNS 提高网页载入速度” 选项来配置缓存时间。

7、什么时候会出现资源访问失败?

开发过程中,发现很多开发者没有设置图标,而服务器端根目录也没有存放默认的 Favicon.ico ,从而导致请求 404 出现。通常在 App 的 webview 里打开 Favicon.ico ,不会加载这个 Favicon.ico,但是很多页面能够分享。

如果用户在浏览器中打开 Favicon. ico ,就会调取失败,一般尽量保证该图标默认存在,文件尽可能小,并设置一个较长的缓存过期时间。另外,应及时清理缓存过期导致岀现请求失败的资源。

8、为什么利用多个域名来存储网站资源会更有效?

9、有一个页面,他必须实时展示最新的数据,你有哪些方案?

💭 四、性能优化文章补充

详解文章补充 👇

💯 五、结束语

随着前端项目不断扩大,浏览器渲染的压力变得越来越重,因此,很多企业专都会专门成立团队去做性能优化。对于性能优化的面试题来说,主要考察应试者对网站性能优化是否有一定了解。

因此,如何做好性能优化,哪些操作会引起性能优化的问题,都值得应试者关注。

到这里,关于性能优化相关的面试题讲到这里就结束啦!希望对大家有帮助~

🐣 彩蛋 One More Thing

🏷️ 参考资料

👉21 道关于性能优化的面试题(附答案)

🏷️pdf 内容获取

👉 微信搜索 星期一研究室 并关注,回复关键词 性能优化面试pdf 获取相关 pdf 内容~

👉 回复 面试大全pdf 可获取全专栏内容!

🏷️ 番外篇

- + \ No newline at end of file diff --git a/column/Interview/React.html b/column/Interview/React.html index 052c38df..8e3ef3c1 100644 --- a/column/Interview/React.html +++ b/column/Interview/React.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/Interview/TypeScript.html b/column/Interview/TypeScript.html index edf4f4cb..318bf540 100644 --- a/column/Interview/TypeScript.html +++ b/column/Interview/TypeScript.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/Interview/Vue.html b/column/Interview/Vue.html index 64153903..d9ef6e3c 100644 --- a/column/Interview/Vue.html +++ b/column/Interview/Vue.html @@ -373,7 +373,7 @@ age: 20, name: 'monday', });

(3)toRefs 是什么

5、vue3 升级了哪些重要的功能?

6、Composition API 如何实现代码的逻辑复用?

7、Vue3 如何实现响应式?

8、Watch 和 watchEffect 的区别是什么?

9、setup 中如何获取组件实例?

vue2 中, Options API 可以使用 this 来获取组件的实例,但是到现在的 vue3 ,已经被摒弃掉了。在 setup 和其他 Composition API 中没有 this ,但是它提供了一个 getCurrentInstance 来获取当前的实例。

10、vue3 为何比 vue2 快?

11、vite 是什么?

12、Composition API 和 React hooks 的对比

📸 七、结束语

vue2.x 的基础知识,再到 vue2.x 的原理知识,最后到 vue3.x 的新特性和原理知识学习,全文贯穿着 vue 的知识要点及相关知识点所涉及到的一些面试题。

最后,关于这部分内容已整理成 PDF ,获取方式放在彩蛋里面,有需要的小伙伴自取 o!

🐣 彩蛋 One More Thing

🏷️ 往期推荐

vue2.xvue3.x 的原理学习,累计博文输出 11 篇,以下是相关专栏文章~

面试专栏 pdf 版本:

更新地址:

🏷️ 番外篇

- + \ No newline at end of file diff --git a/column/Interview/Webpack.html b/column/Interview/Webpack.html index 57a683f4..05e892e7 100644 --- a/column/Interview/Webpack.html +++ b/column/Interview/Webpack.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/Interview/index.html b/column/Interview/index.html index 81914d81..59966680 100644 --- a/column/Interview/index.html +++ b/column/Interview/index.html @@ -19,7 +19,7 @@
Skip to content

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/MachineLearning/Tensorflow/01_MLBase.html b/column/MachineLearning/Tensorflow/01_MLBase.html index 92437d71..92c89961 100644 --- a/column/MachineLearning/Tensorflow/01_MLBase.html +++ b/column/MachineLearning/Tensorflow/01_MLBase.html @@ -19,7 +19,7 @@
Skip to content

背景

平常业务开发中每天都要接触到机器学习和深度学习的概念,在听了很多大佬的普及后,发现甚是有趣。于是小编想着着手开始学习这部分的内容。

那废话不多说,就从最基础的机器学习和神经网络开始~

一、机器学习基础

1、机器学习是什么?

机器学习是对能通过经验自动改进的计算机算法的研究 —— 可以理解为机器学习是一个研究,它的研究对象是计算机算法。这个计算机算法的特点是:能通过经验来自动改进自身的能力。也就意味着,它可以像人一样积累一些经验,然后自动改进。

机器学习是用数据或以往的经验,以此优化计算机程序的性能标准 —— 强调了数据或以往的经验。比如说:拿线性回归来举例,如下图所示:

img

线性回归的意思指的就是你给我一个连续的输入,比如说图上的 x 轴,它从 050,然后我可以给你映射到它对应的 y 轴上的值分别是多少,也就是会给你一个连续的输出,我们可以在图上看到这个 y 轴从 035 也是一个连续的输出。

那么这个线性回归跟机器学习有什么关系呢?如我们上面所说的,这个线性回归问题通过数据或以往的经验来解决。比如说我们这个图里面有很多黄色的点,那么我们就可以沿着这些黄色的点,根据它的分布来画一条黄色的线,画完之后你随便给我一个 x 轴上的值,我都可以找到与之对应的 y 轴上的值。

比如说图上的 x20 的时候,那么它的 y 大概就在 5- 10 之间这个位置,且就是你给我任意一个 x 轴上的值,我都可以得到 y 轴对应的值。当然不只是刚才那个20,其他值也都可以。这就是通过数据以及以往的经验来解决线性回归问题,这些黄色的点就是数据或者说是以往的经验。

还有个问题是,可能有的小伙伴会有疑问:不使用机器学习,我也能画出这条黄线 or 红线。既然自己可以做到了,那为什么还需要机器学习呢?

其实啊,我们的目的就是为了实现人工智能,就是想办法让机器来代替人去画这两条线。

2、机器学习应用场景

上面我们说了机器学习的基础概念,接下来再列举一些常见的应用场景:

  • 图片分类 —— 准备大量图片,让机器去学习,判断这是一只猫、还是一只狗。

img

  • 语音助手 —— siri、小爱同学等等,给机器足够多的声音数据以及对应的标签,那么机器就可以识别我们的语音在讲什么了。

img

3、为何要用机器学习?

有些棘手问题只能用机器学习来解决:

  • 比如说给我一张图片,让我判断这个图片里有没有一只猫。这个问题看似简单,但是即便是很聪明的程序员,也没有办法通过编写规则和编写代码的方法来解决这个问题,这是不可能的。
  • 比如说先是编写了一堆规则,然后判断一只猫,判断一个图片里面有没有一只猫。但是我们想一下,如果这个猫随便换个位置,换个动作,换个颜色,换个品种,那么它的规则是不是就被废弃掉了,就没用了?它要写多少条规则?它要写无数份规则,无数行代码,这显然是不可能解决的。
  • 因此,我们可以通过机器,来学大量猫🐱的图片。之后,机器就大概知道了猫的特征是什么样的。然后等下次你再给它一张新的猫的图片,它就能判断这张图片里有一只猫的概率有多大了。

获取数据比编写规则更加容易:

  • 有些问题它既可以用机器学习来解决,也可以通过编写规则就是编写程序来解决。但是如果获取数据比获取规则更加容易的话,那么这时候就应该用机器学习来解决。
  • 举个例子,比如说你写了一个翻译程序,可以把这个英文翻译成中文,但第二天PM跟你说,想让你把这个翻译程序拓展一下,可以把英文翻译成日语。
  • 如果是通过传统的编程,就会编写一堆的规则,一堆的 if else 逻辑。很大概率所有代码你还要全部再重写一遍,工作量非常大。
  • 但是如果是通过机器学习的手段来做这个翻译程序的话,那么你一行代码都不需要改。我们要做的是,只需要把训练数据换一下,重新训练一个新模型就 OK 了。这也就是为什么要使用机器学习的原因,因为有时候往往获取数据比编写规则要容易得多。

GPU等计算能力显著提升:

  • 机器学习的训练需要消耗大量的计算能力。在过去我们的算力非常的差的时候,其实使用机器学习的成本是很高的,或者说几乎是不可能的。在过去科学家跑一次训练可能得几个月,而且几个月跑一次训练实验,在这个过程中一般还要失败很多次。这个训练实验需要不断地试错,不断地试验,才能慢慢降低失败的次数。
  • but…这么看的话,一次试验都要跑好几个月,那这个实验基本上也就没有什么可行性了,这也是为啥上世纪这个神经网络算法就已经被发明出来,但是到最近几年才火起来,就是因为过去的计算能力太差了。
  • 但是现在我们的计算能力显著提升了,可能一个小时内我就能跑完一次训练,得到一个模型,看到实验结果了。那么这时候使用机器学习的可行性就变得非常高了。

4、机器学习如何运作?

  • 机器学习可以通过神经网络算法来进行运作。
  • 除了神经网络之外,还可以用很多其他的算法来进行机器学习,比如说决策树支持向量机贝叶斯分类器强化学习等等。

二、神经网络简介

1、什么是神经网络

  • 神经网络,也称人工神经网络。
  • 人工神经网络是一种运算模型(就是输入输出的映射),由大量的节点(或称神经元)之间相互联接构成。
  • 运算模型指的是:从输入到输出的一种映射。

2、人工神经网络模型的特点

(1)特点

人工神经网络的特点就是:由大量的节点或神经元相互连接构成,连接之后就形成了一张类似于网络状的结构,所以我们把它称为神经网络

(2)举例

举例生活中很常见的相亲例子:

img

左边是输入层,右边是输出层。中间的隐藏层,其实就是神经元,这个隐藏层是为了用来输出最后结果的。

对于输入来说,输入是我们可以从相亲对象身上直观看到的一些信息,那这些信息,每一个对应到形象、财富、品质和有趣的权重值,都不太一样。

可能五官跟财富和品质就没啥关系,那在财富和品质这两个神经元中,五官的权重就低一点。又或者说,学历和家境可能会对一个人的品质造成影响,所以说在品质这个神经元里面,它的权重可能就比较偏向于学历和家境。

总之,每一个神经元里面都存储着一些权重,然后把上一层的输入乘上这些权重加起来之后就得到一个值,得到值之后,就进入到下一层的神经元。

下一层的神经元就是最后一层的神经元,这个神经元叫满意程度,这个神经元里面也存着 4 个权重,它是把前面形象、财富、品质和有趣这四个神经元算出来权重,加起来得到的满意程度。

不过呢,现实生活中的机器学习比这还要复杂的多。比如说:有些用户他的眼光是比较高的,可能在我们看来已经很好看很漂亮的女孩,或者很帅的小伙,但是在他看来就是一般人,那么这时候我们光靠权重来算形象就不够了,可能还要加上一个偏置。比如说在其他用户眼中,一个相亲对象他的形象有十分,但是在那个眼光比较高的用户眼里,只有 1 分,那么他的偏置就是-9。

值得注意的是,偏置是最后加上的,也就是那些权重乘完之后加起来然后再加上这个偏执。

接着,我们再来考虑一种情况,大多数人可能都会对相亲对象的财富有一定的要求,但是假设说超过了一定范围,其实对我们来说就没有区别了。比如说你觉得你的相亲对象只要年薪超过百万就可以了,那么他年薪 100 万、 200 万对你来说其实差别不大,但是对计算机来说这可是整整两倍的差距。所以说我们要告诉计算机,你不能再这么线性的增长上去了,对我来说只要超过 100 万都没有区别,不要再增加它的值了。

那么如何实现这一点呢?神经元里面还有一个东西叫做激活函数,激活函数的作用就是用来做一些非线性的变化。所谓非线性的变化,就是:比如刚才我们举的例子,年薪超过 100 万就可以了,不要再线性的增长了,接下来我们可以把它想象成一条线,增长着增长这,最后就趋于直线平稳了,这就是一个非线性变化。

3、神经网络总结

最后,我们来对上面所讨论的做一个小结:

  • 每个神经元里存储着若干权重(weight)、偏置(bias)和一个激活函数(activation)。
  • 输入乘上权重加上偏置,经过激活函数得到输出。
  • 激活函数用于添加一些非线性变换。
  • 神经网络通常包含一个输入层、若干隐藏层、一个输出层。
  • 输入层通常不用于计算神经网络的层数。

三、神经网络的训练

1、什么是神经网络的训练?

  • 给大量输入和输出,算出神经网络里所有神经元的权重、偏置,然后给定新的输入,可以算出新的输出。
  • 在机器学习里输入输出被称为特征标签,大量输入输出被称为训练集
  • 同样拿上面的相亲例子做举例:给 1000 个 相亲对象的数据(特征),以及对应的满意程度(标签)。训练完之后给一份新的相亲对象数据,就可以判定满意程度了。

2、如何训练神经网络?

  • 初始化: 随机生成一些权重和偏置。
  • 计算损失: 给定特征,计算出标签,看标签与真实标签差得多远。
  • 优化: 微调权重和偏置(隐藏层),使损失变小。(微调与微积分中求导求梯度有关,哪个方向损失降得最快,那个方向就是正确的方向)

3、前向传播与反向传播

  • 前向传播:把训练数据的特征送入网络,得到标签。
  • 反向传播:计算损失并优化。(在最后一层计算损失,然后微调和优化,之后计算倒数第二层的权重)

4、如何计算损失?

  • 使用业界已经研究出来的且很成熟的损失函数
  • 常见损失函数:均方误差、对数损失、交叉熵…

5、如何优化?

  • 使用业界科学家们已经研发的优化器
  • 常见优化器:随机梯度下降(SGD)、Adam(从第三方库中调用)

结束语

在上面的文章中,我们学习了机器学习的基础知识,以及由机器学习衍生而来的人工神经网络。同时,我们还谈到了如何去训练一个神经网络。

通过本文的介绍,相信你对机器学习和神经网络会有一个基础的认识。

以上就是本文的全部内容,我们下期见~🍻

参考材料:JavaScript玩转机器学习 - Tensorflow.js

Last updated:

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/MachineLearning/index.html b/column/MachineLearning/index.html index ad0b096b..088b25d4 100644 --- a/column/MachineLearning/index.html +++ b/column/MachineLearning/index.html @@ -19,7 +19,7 @@
Skip to content

#第三方第三方

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/OtherLang/Android/001.html b/column/OtherLang/Android/001.html index 4a555961..47d0a2d9 100644 --- a/column/OtherLang/Android/001.html +++ b/column/OtherLang/Android/001.html @@ -3475,7 +3475,7 @@ } }; }

🎵 三、运行结果 Result

到这里,整个系统的设计就差不多要结束啦!现在我们用一段视频来演示整个系统的运行效果 🌈

[video(video-G1g5pVZJ-1626512791305)(type-csdn)(url-https://live.csdn.net/v/embed/170699)(image-https://vedu.csdnimg.cn/50caebd2cd1f477f8b0fd1b205619fd9/snapshots/d066170d085640d482eaa655fcaa17e7-00003.jpg)(title-)]

📈 四、结束语

在拿到这个课题呢,周一首先对课题进行了系统结构设计,结构设计完成之后就到了编码阶段。编码阶段分为两部分进行,先是进行静态页面的楷模,而后到了业务逻辑的编写。

讲到这里,整个系统从设计阶段到编码阶段的整个过程讲解就结束啦!这也算是我学习 Android 的第一个小作品,作品不完美之处较多,后续还将会继续改进~

本文代码已上传至 github,戳此链接可下载代码~

🐣 彩蛋 One More Thing

(:不合理设计

- + \ No newline at end of file diff --git a/column/OtherLang/PHP/001.html b/column/OtherLang/PHP/001.html index beb68319..99c7d87f 100644 --- a/column/OtherLang/PHP/001.html +++ b/column/OtherLang/PHP/001.html @@ -23,7 +23,7 @@ ?>
<?php
 echo "Hello World!";
 ?>

保存代码并在浏览器中,访问站点域名,例如我的是“http://test.local”,演示效果如下:

在这里插入图片描述

- + \ No newline at end of file diff --git a/column/OtherLang/PHP/002.html b/column/OtherLang/PHP/002.html index c717b977..7fcb7a1e 100644 --- a/column/OtherLang/PHP/002.html +++ b/column/OtherLang/PHP/002.html @@ -19,7 +19,7 @@
Skip to content

使用工具:phpEnv、TortoiseGit 具体步骤1.获取 thinkcmf 源代码 2.修改 Hosts 文件设置虚拟域名指向本机 3.配置 apache 建立本地站点 4.建立数据库 5.访问本地站点开始安装

第一步:获取 thinkcmf 源代码1.打开浏览器访问 gitee.com,搜索 thinkCMF,找到软件库(一般是第一个),复制软件仓库的克隆地址 2.打开软件浏览器,git 克隆源代码到具体文件夹(下面称此文件夹为工作站) 此文件夹目录需记住,在后面的步骤中会用到 如本地软件没有下载 git 相关软件,则直接下载软件包再放到具体文件夹中即可

(1)打开gitee.com网站

(2)下载thinkcmf代码

第二步:修改 Hosts 文件设置虚拟域名指向本机1.打开 hosts 文件所在地址:C:\Windows\System32\drivers\etc,用任意文本编辑器进行编辑; 2.设置 127.0.0.1 test.com 在最后一行,之后保存 :test.com 即设置任意域名指向本机,test 仅为参考名,可根据自身情况修改

第三步:配置 apache 建立本地站点1.打开 phpEnv 软件,点击中间位置的站点管理,新建一个站点,各空白区填写内容如下: 网站域名:填写与第二步的第 2 点中一样的域名,如:原来为 test.com,则在新建站点中网站域名即输入 test.com; 网站目录:工作站中 thinkcmf 下的 public 目录; 之后点击新增,启动服务;

(3)启动服务成功后截图

第四步:建立数据库1.打开数据库管理(phpEnv 三大按钮中最右方按钮),输入本机数据库密码,打开数据库; 2.新建一个数据库,名称为 thinkcmf。

(4)输入数据库密码

(5)新建一个数据库

(6)完成数据库创建

第五步:访问本地站点开始安装1.浏览器访问 test.com 进入站点,开始安装,点击接受|下一步,设置数据库密码(本机数据库密码)和数据库名(thinkcmf),继续设置创始人信息,创始人信息包括:管理员账号、密码和 Email(注:此处信息开发者自行设置,但是务必记得,在后面的 thinkcmf 中会用到),点击创建数据,创建成功后点击进入前台,CMF 系统即安装成功。

(7)安装成功

(8)进入前台界面

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/OtherLang/PHP/003.html b/column/OtherLang/PHP/003.html index c426269f..bbce979f 100644 --- a/column/OtherLang/PHP/003.html +++ b/column/OtherLang/PHP/003.html @@ -19,7 +19,7 @@
Skip to content

使用工具:phpEnv 具体步骤1.获取门户应用 portal 源码 2.安装 portal 代码 3.执行 portal 数据库文件 4.安装并启用前台模板 5.导入后台管理菜单

第一步:获取门户应用 portal 源码1.打开官方网站http://kancloud.cn/thinkcmf/faq/1005840,点击左侧邮箱配置|安装门户应用,右侧的下载代码中点击码云,克隆源代码放到工作站 注:对如何克隆源代码不了解的小伙伴可参考本机安装 ThinkCMF 系统文章的第一步

在这里插入图片描述第二步:安装 portal 代码1.复制工作站中 portal 文件夹下的api,app,public三个文件夹; 2.将此三个文件夹放入工作站中 thinkcmf 目录下,粘贴,直接替换原来的文件。

在这里插入图片描述

第三步:执行 portal 数据库文件(安装门户应用的数据库文件)1.用编辑器打开工作站中thinkCMF/app/portal/data/目录下的portal.sql 文件,全选并复制; 2.打开 phpEnv 中数据库管理工具,打开 thinkcmf 数据库,点击查询,将上面复制的代码粘贴进此文本框中,粘贴后运行;

在这里插入图片描述

在这里插入图片描述

第四步:安装并启用前台模板1.浏览器访问test.com/admin/,输入密码进行登录(此账号密码为本机安装 ThinkCMF 系统文章中最后一步所涉及到的内容); 2.登录成功后,在左侧栏设置目录中找到模板管理,右侧点击安装模板,点击安装 simpleboot3,安装成功后,启用新的模板

在这里插入图片描述

第五步:导入后台管理菜单1.点击后台菜单按钮(此按钮位于左侧侧边栏顶部五个按钮中最右侧); 2.点击所有菜单,导入新菜单,点击下一个应用,菜单导入成功; 3.刷新页面,检查左侧是否出现一个名称为门户管理的新菜单,如出现,即说明安装成功。 4.点击首页按钮(此按钮位于左侧侧边栏顶部五个按钮中最左侧),查看首页模板是否更改。如已更改,说明模板启动成功;如未更改,请返回到第四步第 2 点查看模板是否已经启用。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

:此文章为本机安装 ThinkCMF 系统文章的衔接,可以先对上一篇文章的具体步骤先进行操作,再执行此篇文章的具体步骤,理解更深。

▶PS 有疑问欢迎评论区提问

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/OtherLang/index.html b/column/OtherLang/index.html index 855a3d0f..53fe0cb2 100644 --- a/column/OtherLang/index.html +++ b/column/OtherLang/index.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/000Guide.html b/column/Product/SoftwareEngineer/000Guide.html index 298f6bda..04e83ef5 100644 --- a/column/Product/SoftwareEngineer/000Guide.html +++ b/column/Product/SoftwareEngineer/000Guide.html @@ -19,7 +19,7 @@
Skip to content

前言

【软件工程】应该是大学计算机专业必修的一门课,对于开发者来说,可能有人觉得我只要会用,会写代码就行,不需要学这些东西。有时候我也经常在怀疑,学这门课有什么用,它的精髓在哪里呢?突然就找不到支撑我学习这门课下去的理由。

直到有一天,我问了我们老师,学习『软件工程』究竟可以干嘛呢?这么一大堆理论的知识,是为了以后做项目管理吗?

于是我们老师当即跟我说,学习软件工程,是为了后面的软件工程实践。我问她,何为实践?她给我举了 3 个点:这门课立足于系统的整体主要讲授系统分析系统设计测试维护的理论和方法,培养能够从事软件开发、测试、维护和软件项目管理的高级专门人才前面理论的铺垫是为了后面能构建一个软件系统,实践软件开发的全过程

也就是说,每个软件都有它的架构体系,不是凭空相像就能开发出来的,没有经过设计的软件一般都会存在着诸多问题,包括但不限于数据库设计不合理需求不断变更等等问题。所以,基于一定的软件工程基础知识做铺垫,能更合理、更高效的设计出一款软件。

当然,对于想要从事开发岗位的人来说,学习软件工程基础,更是最基本的。下面从几个方面讲解为什么要学习软件工程,该怎么学习

一、引言

首先我是计算机相关的专业,目前正在上『软件工程』这门课程。为了不让自己的知识学完还给老师,也为了自己以后的软件实践能有一个更好的基础架构做支撑,我会将理论和实践相结合融入到这个栏目的文章当中,让读者可以看到比较完整的软件工程实践案例。前期是软件工程和项目管理的一些基础知识,后面是关于软件工程实践的一些方法,包括结构化、面向对象、UML 等相关内容。

二、学习【软件工程】的原因

1、软件设计师证书

软件设计师证书考试,也俗称为“软考”。有人说它含金量高,也有人说它含金量低,但是怎么说呢,能考上总比没有好....我是这么觉得。如果目前是在校生,时间上会比较充足一点,可以在学习的过程中边积累知识边备考。因为知识会记得比较多也比较牢固,这个时间段去备考也是通过率比较高的。

2、相关领域人员必备技能

软件工程包含两个部分:软件和工程,软件是程序员做的,而工程是项目负责人管理、程序员实践的,工程的方法是为了更好的组织、协调编写过程。

现代软件越变越大,大型的编写工作动辄上万人。不管是从事技术类的前后端工程师和运维工程师,还是非技术类的产品开发和产品运营等岗位,都很有必要了解自己目前所负责产品的整个流程和架构,实现更高效的开发和协作沟通。

三、【软件工程】的学习方法

1、不要盲目为了学习而学习

如果说,大家都觉得软件工程很重要,然后抱着一本书去学习,那必然是不太合理的。

抱着写着一大堆理论的书去学习,它的枯燥性和抽象性....完全不能想象。

学习这门课程,可以通过理论+实践相结合,在学到某一块知识的时候,顺带可以找找相关的案例做剖析,再试着自己找一个案例练习,这样得到的结果才不会太差。

2、规划学习路线

在学习『软件工程』之前,你需要先了解一下它都包含了哪些内容,这里我从网上找了个思维导图,大家可以先大概做个了解,初步有个印象。

软件工程学习路径

可以根据这样的学习路径到网上搜寻相关教学视频学习; 同时,我会根据这个学习框架,写一些文章供大家学习使用,并且会把软件工程相关的文章放到『软件工程』这个专栏里,方便大家归类查看;

持续更新中……

四、结束语

创作不易,如果这篇文章对你有用,记得留下Star哦~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/001Definition.html b/column/Product/SoftwareEngineer/001Definition.html index 131f7ab5..7568046b 100644 --- a/column/Product/SoftwareEngineer/001Definition.html +++ b/column/Product/SoftwareEngineer/001Definition.html @@ -19,7 +19,7 @@
Skip to content

一、什么是产品

1、从用户的角度 产品实际上就是信息,以某种方式使得用户世界更加美好 2、从软件工程师的角度 产品实际上就是软件

二、软件的双重角色

1、产品 软件是一个信息变换器,用来获取、显示及管理信息等 2、产品交付使用的载体 软件是 ① 操作系统的基础;② 通信网络的基础;③ 其他软件工具和环境的基础

三、软件的涵义及特征

1、软件的涵义 软件 Software = 程序 Program + 数据 Data + 文档 Document,这些项的每一个均包含一个配置 2、软件的特征1)软件是被开发或设计的,而不是传统意义上被制造的 (2)软件不会“磨损”,但是会退化 注:需了解两种曲线:硬件故障率曲线(浴缸曲线);软件故障率曲线;具体形式图如下:

在这里插入图片描述

在这里插入图片描述

(3)虽然软件产业正在向基于构件的组装前进,大多数软件仍然是定制的 ->构件:是可复用的组成部分,可被用于构造其他软件,比如一些被封装的对象类、功能模块及软件框架等

四、软件应用

1、系统软件 2、应用软件 3、工程/科学软件 4、Web 应用软件 5、人工智能软件 6、……

五、软件危机

1、软件危机的表现 (1)对软件开发成本进度的估计常常不准确(开发成本超出预算,实际进度比预定计划一再拖延的现象并不罕见) (2)用户对“已完成”系统不满意的现象经常发生 (3)软件产品的质量往往靠不住,bug 一大堆 (4)软件的可维护程度非常之低 (5)软件通常没有适当的文档资料 (6)软件的成本不断提高 (7)软件开发生产率的提高赶不上硬件的发展和人们需求的增长 2、软件危机引发的思考1)How do we ensure the quality of the software that we produce? 我们如何确保我们所产生软件的质量? (2)How do we meet growing demand and still maintain budget control? 我们如何满足日益增长的需求,同时又保持预算控制? (3)How do we upgrade an ageing “software plan”? 我们如何升级老化的“软件计划”? (4)How do we avoid disastrous time delays? 我们如何避免灾难性的时间延误? (5)How do we successfully institute new software technologies? 我们如何成功的研究新的软件技术? 3、减轻软件危机的途径1)对计算机软件有一个正确的认识(软件 ≠ 程序)。 (2)必须充分认识到软件开发不是某种个体劳动的神秘技巧,而应该是一种组织良好、管理严密、各类人员协同配合、共同完成的工程项目。 (3)推广使用在实践中总结出来的开发软件的成功技术和方法。 (4)开发和使用更好的软件工具

六、软件神话

1、三大软件神话(1)管理者的神话已有了关于开发软件的标准和规程的书籍,可提供所有的信息。 已有了很多很好的软件开发工具和最新的计算机。 如果已落后于计划,可以增加更多的程序员来赶上进度。 如果决定“外包”,就可以放松让承包公司去建造。 (2)客户神话有了对目标的一般性描述,就可以开始写程序。 项目需求可以不断变更,因为软件是灵活的。 But...变更的代价是:

在这里插入图片描述

(3)实践者的神话一旦写出程序并正常运行,工作就结束了。 在程序真正开始运行之前无法评估其质量。 一个成功的项目唯一应该提交的就是运行程序。 软件工程将使我们创建大量的、不必要的文档,并总是延缓进度。 2、软件开发过程中各单位分配比例1)工作量分配比例

在这里插入图片描述

2)费用分配比例

在这里插入图片描述

如果这篇文章对你有帮助,记得留下star哦~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/002ProcessModel.html b/column/Product/SoftwareEngineer/002ProcessModel.html index 84f4648a..0a49d413 100644 --- a/column/Product/SoftwareEngineer/002ProcessModel.html +++ b/column/Product/SoftwareEngineer/002ProcessModel.html @@ -19,7 +19,7 @@
Skip to content

一、软件工程的定义

1968 年在 NATO 会议上,首次提出“软件工程”这个术语。但软件工程一直以来都缺乏一个统一的定义,有很多学者、组织机构都分别给出了自己认可的定义。以下给出三种常用的定义

1、Fritz Bauer 在 NATO 上给出的定义

The establishment and use of sound engineering principles in order to obtain economically software that is reliable and works on real machines.

建立并使用完善的工程化原则,以较经济的手段获得能在实际机器上有效运行的可靠软件的一系列方法。

2、Barry Boehm

Software engineering is that form of engineering that applies the principles of computer science and mathematics to achieving cost-effective solutions to software problems.

软件工程就是应用计算机科学和数学的原理,来为软件问题提供经济高效的解决方案。

通俗点来说:①运用现代科学技术知识来设计并构造计算机程序;开发、运行和维护这些程序所必需的相关文件资料。

3、IEEE 在软件工程术语汇编中的定义

The application of a systematic,disciplined,quantifiable approach to the development,operation,and maintenance of software.

将系统化的、严格约束的、可量化的方法应用于软件的开发、运行和维护,即将工程化应用于软件。

二、软件工程的层次

软件工程是一种层次化的技术,支持软件工程的根基就在于对质量的关注

1、软件工程三个要素

过程、方法、工具

2、软件工程的层次——图解

3、软件工程的层次——逐一分析

(1)质量焦点(a quality focus)

软件工程的根基,任何工程方法都必须以有组织的质量承诺为基础

(2)过程(process)

是软件工程的基础,定义了一组关键过程区域框架,包括*工程产品的产生*,里程碑的建立等等

(3)方法(methods)

提供了建造软件在技术上需要“如何做”,包括需求分析(analysis)、设计(design)、编码(coding)、测试(testing)和支持(backing)

(4)工具(tools)

对过程和方法提供了自动或半自动的支持

E.g. CASE 工具(计算机辅助软件工程):集成硬件、软件和数据库而创建的软件工程环境,类似于硬件的 CAD(计算机辅助设计)/CAE(计算机辅助工程)

三、软件过程的三个阶段

1、定义阶段——“做什么”

1定义:系统和软件的关键需求被标识

2应用场景系统和信息工程;软件项目计划;需求分析

2、开发阶段——“如何做”

1定义:定义数据结构、体系结构、过程细节、界面表示、算法和测试如何执行

2应用场景软件设计;代码生成;软件测试

3、支持阶段——“变化”

1定义纠正错误;随着软件环境的演化而要求的适应性修改;用户需求的变化而带来的增强型修改

2应用场景纠错性维护(校正式);适应性维护;完善性维护;预防性维护

下面用一张图了解软件过程的三个阶段

在这里插入图片描述

四、软件过程框架

1、引例——煮蛋的启示

很久以前,中国人煮蛋方式与德国人煮蛋方式的不同。

中国人:先找一个锅,倒进水,再把蛋放进去,整个过程需要 10~20min。

德国人:先找一个锅,倒进水,再把蛋放进去,在容器的下方焊接一个托盘,再将锅放到托盘上去烧开,如此,仅用 1min 就把水烧开,之后再用火继续煮了 3min,关火;再用余热继续煮了 3min;煮熟后丢到冷水里面 3min;最后他用 10min 时间把蛋煮熟。

从以上分析来看,德国人煮蛋更讲究过程,不同的过程会导致不一样的结果。研究表明,德国人煮蛋的方式有以下几点好处:① 更省水;② 更省热能;③ 煮蛋所花时间更少;④ 利用余热煮 3min,这个时候蛋的营养价值更高;⑤ 用凉水泡了 3min,蛋壳更容易拨开。

在这里插入图片描述

2、软件工程的过程定义

(1)过程(process):一组有序的任务,每个任务由一些步骤组成,每个步骤涉及到活动、约束及产品

(2)广义上,软件开发的每一个阶段都可看成是一个过程。

(3)简言之,过程就是一个步骤、一个路线图,帮助创建高质量的软件。

3、软件过程框架

先用一张图简单了解软件过程框架:

在这里插入图片描述

(1)通用过程框架活动

  • 沟通
  • 策划
  • 建模
  • 构建
  • 部署

(2)普适性活动

  • 软件项目跟踪和控制
  • 正式的技术评审
  • 软件质量保证
  • 软件配置管理
  • 文档的准备和产生
  • 可复用管理
  • 测度
  • 风险管理

五、CMM

1、基础知识

1)20 世纪 90 年代(CMU/SEI)提出能力成熟度模型(Capability Maturity Model,CMM)

2)CMM 定义了当一个组织达到不同的过程成熟度时应该具有的软件工程能力

3)CMM 是一种衡量软件开发能力成熟度的标准

4)CMM 模型提供了衡量一个公司软件工程实践的整体有效性的方法,且建立了五级的过程成熟度级别

2、CMM 的级别

(1)第一级:初始级(initial)

① 定义:软件过程是定义的偶然的,有时甚至是混乱的。几乎没有过程定义,成功完全取决于个人能力

② 特点:不可预测并且缺乏控制。

(2)第二级:可重复级(repeatable)

① 定义:建立了基本的项目管理过程,能够跟踪费用、进度和功能。有适当的必要的过程规范,可以重复以前类似项目的成功。

② 特点:可重复以前的主要经验。

③ 关键过程区域:需求管理;软件项目计划;软件项目跟踪和监督;软件子合同管理;软件质量保证;软件配置管理。

(3)第三级:定义级(defined)

① 定义:企业的软件过程已经文档化、标准化并与整个组织的软件过程相集成。所有项目都使用统一的、文档化的、组织过程认可的版本来开发和维护软件。包含第二级的所有特征。

② 特点:过程被描述,并得到良好理解。

③ 关键过程区域:组织过程定义;组织过程焦点;培训大纲;集成软件管理;软件质量保证;软件配置管理。

(4)第四级:管理级(managed)

① 定义:软件过程和产品质量的详细数据被收集,通过这些度量数据,软件过程和产品能够被定量地理解和控制。包含第三级的所有特征。

② 特点:过程被测量并受控。

③ 关键过程区域:定量的过程管理;软件质量管理。

(5)第五级:优化级(optimizing)

① 定义:通过定量反馈进行不断的过程改进,这些反馈来自于过程或通过试验新的想法技术而得到。包含第四级所有特征。

② 特点:关注过程改进。

③ 关键过程区域:缺陷预防;技术变更管理;过程变更管理。

六、软件过程模型

1、软件过程模型概述

软件过程模型是软件开发全部过程、活动和任务的结构框架。软件过程模型不是一种具体模型,是一种开发策略,包含过程、方法和工具三个层次以及一般性阶段,常称为:软件开发模型;软件生存期模型;软件工程范型。

2、软件过程模型分类

(1)传统的软件过程模型(7 种)

详细内容见以下第 3 点

(2)敏捷视角下的过程模型(7 种)

详细内容见以下第 4 点

3、传统的软件过程模型

(1)线性顺序模型(瀑布模型)

① 图解

② 存在问题

  • 实际项目很少按照该模型给出的顺序执行
  • 客户常常难以清楚地给出需求
  • 客户必须有耐心,运行版要到开发晚期才能得到
  • 导致“阻塞状态”,常发生在开始和结束时

(2)V 模型

① 图解

在这里插入图片描述

② 特点——强调反馈,不将问题留到下一步

Verification 验证:每个活动保证能正确运行。

Validation 确认:针对需求而言,符合需求规格的定义。

(3)原型实现模型

① 定义

原型是一个可迭代的/可重复的(循环)过程,在这个过程中,一个问题的模型被细化/改进,直到它被接受为止。 ② 流程图

③ 原型开发分类

根据原型与最终产品之间的关系,原型开发分类分为以下三种:

抛弃式 (throw away):验证和澄清系统的需求描述,重新构造系统。

演化式 (evolutionary):逐步改进和细化原型,将原型进化为最终系统。

增量式 (incremental):在建立软件总体设计基础上,采用增量开发方法,使原型成为最终系统。

此处篇幅较长,点击进入原型实现模型的详解

④ 适用情况

当客户有一个合理的需求,但是对细节没有概念的时候最适合使用原型实现模型

⑤ 特点

快速性、迭代性

⑥ 优缺点

优点:

  • 用户能够感受到实际系统
  • 开发者能很快建造出一些东西

缺点:

  • 原型是粗糙的,没考虑软件总体质量和长期的可维护性
  • 开发者常常要对实现内容折中以使得原型能尽快工作

⑦ 不适合的领域

  • 嵌入式系统
  • 实时控制系统
  • 科学数值系统

(4)RAD 模型

① 定义

RAD(Rapid Application Development,快速应用开发)通过使用基于构件的建造方法赢得了快速开发。

② 分类

  • 业务建模
  • 数据建模
  • 过程建模
  • 应用生成(编程阶段 - 基于构件)
  • 测试及反复

③ 流程图

④ 特点

  • 强调极短的开发时间,每一个主要功能在不到三个月的时间内完成;
  • 强调复用

⑤ 存在的问题

  • 对于大型的的项目,RAD 需要足够的人力资源以建立足够的 RAD 组;
  • RAD 要求开发者和客户承担在一个很短的时间框架下完成一个系统所必要的快速活动;
  • 并非所有应用都适合 RAD;
  • 不适合技术风险很高的情况

(5)增量模型

① 定义:增量模型融合了瀑布模型的基本成分原型的迭代特性

② 举个例子

例如,使用增量模型开发一款字处理软件,那么,这款软件需要做什么呢?

  • 基本的文件管理、编辑和文档生成功能;
  • 更完善的编辑和文档生成能力;
  • 实现拼写和语法检查功能;
  • 完成高级的页面布局功能。

③ 流程图

④ 特点

  • 增量 1 往往是“核心产品”;
  • 本质是迭代的,但强调每一增量均发布一个可操作产品。

⑤ 优点

  • 面对不能改变的困难时限时,是可考虑的选择;
  • 早期可投入较少人员;
  • 可有计划地管理技术风险。

⑥ 思考问题

Q:假设一个学校在四个月后要参加教学评估,要求现在开发一个学校综合管理信息系统,如果你是开发者,你会选择哪一种过程模型来开发这个系统,RAD 还是增量式的过程模型?为什么?

A:答案是选择RAD 过程模型。为什么呢? 原因在于,RAD 模型适用于模块化比较强的项目,且必须在 60-90 天内完成,不迭代,没有一个动作在重复进行。 而增量模型则是可迭代的,且增量 1 是核心产品,每一增量均可操作。比较适用于市场竞争激烈的项目,有利于抢占市场。

(6)螺旋模型

① 软件开发可能遇到的风险(引例):

  • 产品交付给用户之后用户可能不满意;
  • 到了预定的交付日期软件可能还未开发出来;
  • 实际的开发成本可能超过预算;
  • 产品完成前一些关键的开发人员可能“跳槽“了;
  • 产品投入市场之前竞争对手发布了一个功能相近、价格更低的软件等;
  • ……

② 螺旋模型的基本思想:使用原型及其他方法来尽量降低风险。

③ 流程图

理解这种模型的一个简便方法,就是把它看作在每个阶段之前都增加了风险分析过程的快速原型模型,如下图所示

在这里插入图片描述

④ 螺旋模型任务区域(4 个象限),各象限含义如下:

  • 客户交流——建立开发者和客户之间有效的通信所需的任务;
  • 制定计划——确定软件目标,选定实施方案,弄清项目开发的限制条件;
  • 风险分析——分析评估所选方案,考虑如何识别和消除风险;
  • 实施工程——实施软件开发和验证;
  • 构造及发布——构造、测试、安装和提供用户支持(如文档及培训)所需的任务;
  • 客户评估——评价开发工作,提出修正建议,制定下一步计划。

:四个象限包含制定计划,风险分析,实施工程,客户评估;

此处列出 6 点是为了更加细分螺旋模型的流程。

⑤ 优缺点

优点:

  • 随着过程进展演化,开发者和客户能够更好地理解和对待每一个级别上的风险,使用原型实现作为降低风险的机制;
  • 更真实地反映了现实世界;
  • 如应用得当,能在风险变成问题之前降低它。

缺点:

  • 模型的成功依赖于风险评估的专门技术;
  • 是一个较新的模型,功效的确定尚需若干年时间。

⑥ 适用情况

主要适用于内部开发的大规模软件项目

(7)形式化方法模型

形式化方法使得软件工程师能够通过应用一个严格的、数学的符号体系来规约、开发和验证基于计算机的系统。净室软件工程师是这种方法的一个变种。

通过应用数学分析,二义性、不完整性和不一致性能更容易发现和纠正。

形式化方法目前还很费时且很昂贵

很少有软件开发者具有实用形式化方法所必要的指示,尚需许多方面的培训。

难以与客户进行沟通。

4、敏捷视角下的过程模型

(1)什么是敏捷

  • 普遍存在的变化是敏捷的基本动力

  • 敏捷就是灵活,支持变化的观点

  • 敏捷过程强调过程的可操作性和适应性

(2)敏捷团队必须具备的特点

  • 基本能力
  • 共同目标
  • 精诚合作
  • 决策能力
  • 模糊问题的解决能力
  • 相互信任和尊重
  • 自我组织

(3)几种重要的敏捷过程模型

① 极限编程(XP)
  • 包含了策划设计编码测试四个框架活动的规则和实践,具体流程如下:

在这里插入图片描述

② 自适应软件开发(ASD)
  • ASD 的生命周期包含思考协作学习三个阶段

在这里插入图片描述

③ 动态系统开发方法(DSDM)

定义三个不同的迭代循环,前面还加了两个生命周期活动,如下:

  • 可行性研究
  • 业务研究
  • 功能模型迭代
  • 设计和构建迭代
  • 实现迭代
④Scrum(橄榄球模型)

强调使用一系列的软件过程模式,每个过程模式定义一系列开发活动:

  • 待定项——能为用户提供业务价值的项目需求或特征的优先级列表;
  • 冲刺——由工作单元组成,是完成待定项中定义的需求所必需的,能在预定时间段内完成的;
  • Scrum 例会——15 分钟;
  • 演示——交付软件,客户进行评估。
⑤Crystal
  • 提倡“机动性”的软件开发方法;

  • 包含具有共性的核心元素,每一个都含有独特的角色过程模式工作产品实践等。

⑥ 特征驱动开发(FDD)
  • 特征,即可以在2 周甚至更短时间内实现具有客户价值的功能。

  • 定义五种协作框架

⑦ 敏捷建模(AM)
  • 有目的的建模
  • 使用多个模型
  • 前进灯
  • 内容重于表达形式
  • 理解模型及工具
  • 适应本地需要

写在最后

看完这篇文章,不妨试问下自己以下问题:

  • 你认为介绍的软件过程模型哪一种最有效,为什么?

  • 举出一个采用增量模型开发的软件项目,并指出各个增量的功能。

  • 当沿着螺旋模型的过程路径向外移动时,你认为正在开发或维护的软件发生了什么变化呢?

  • 分别用图示说明瀑布模型、V 模型、原型、RAD、增量模型及螺旋模型这六种模型的原理。

欢迎评论区留下答案 ٩(๑❛ᴗ❛๑)۶

PS 本文篇幅较长,有错别字欢迎评论区纠正,随时改进~ 如果这篇文章对你有帮助,记得留下star哦~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/003Prototype.html b/column/Product/SoftwareEngineer/003Prototype.html index d7be53ed..3c2b61e2 100644 --- a/column/Product/SoftwareEngineer/003Prototype.html +++ b/column/Product/SoftwareEngineer/003Prototype.html @@ -19,7 +19,7 @@
Skip to content

一、抛弃式原型开发

1、定义:验证和澄清系统的需求描述,重新构造系统。

2、流程图

3、典型例子

开发者与客户进行沟通交流,之后获取到客户的需求,于是开发者开发了该图形用户界面(GUI)的原型。但是之后呢,系统并没有用 GUI 继续做开发,而是采用 C++或者是其他语言来开发。

4、有利条件

1)Reduce risk in a project, see if something can be done.

降低项目中的风险,评估哪些事情可以做,哪些事情不能做;

2)Capture requirements(e.g. whether client likes the GUI or not) .

捕捉需求,比如:客户是否喜欢 GUI 界面。

5、不利条件

1)Resources can be wasted, so control is needed.

资源可能会被浪费,因此需要控制。

2)Good Project Management is required.

需要良好的项目管理。

3)Good communication with the client is required.

与客户保持良好的沟通。

4)When is it a good time to stop developing the prototype.

无法判断停止开发原型的时间。

二、演化式原型开发

1、定义:逐步改进和细化原型,将原型进化为最终系统。

2、流程图

3、典型例子

与汽车行业类似,一款车型也在逐步完善。

4、有利条件

1)The client can see the changes that they want.

客户可以看到他们想要的改变。

2)Very good for improving user interface acceptance.

有利于提高用户界面的接受程度。

5、不利条件

1)Very weak on documentation (e.g. system keeps changing)

不利于文档撰写,比如:系统持续改变,那么文档就不好落笔。

2)The entire project needs strong project control,the same as leader needs to monitor development.

整个项目需要强有力的项目控制,同时领导者也需要监控项目的发展进程。

3)When is it a good time to stop evolving and finishing the project and possible lead to a badly structured system.

是什么时候停止发展和结束项目,我们都不知道;所以这很有可能会导致系统结构不良。

4)Special development staff may be required.

可能需要特殊的开发人员。

6、适用情况

1)Small projects.

小型项目。

2)Limited projects that are limited by time or money.

受时间或金钱限制的有限项目。

3)Those projects that need done quickly.

那些需要快速完成的项目。

4)Projects whose details cannot be determined in advance.

无法预先确定其细节的项目。

5)Projects with a high graphical content.

图形内容丰富的项目。

三、增量式原型开发

1、定义:在建立软件总体设计基础上,采用增量开发方法,使原型成为最终系统。

2、流程图

3、典型例子

英文版

A software company and a client may agree on delivery of system parts. For example, a website delivery might be:

1st January - Delivery of web-server, web-pages,verification and validation scripts.

5th February - Delivery of database, security software.

21st February - Delivery of merchant payment system.

中文版

一个软件公司和客户就系统部件的交付达成协议。 例如,一个网站交付可能是:

1 月 1 日 - 交付 ① 网络服务器;② 网页;③ 验证和确认脚本。

2 月 5 日 - 交付数据库和安全软件。

2 月 21 日 - 商家付款系统的交付。

4、有利条件

1)Good for breaking a larger system into parts, so components can be built easier.

非常适合将较大的系统分解为多个部分,因此组件可以更轻松地被构建。

2)Customer sees the system in stages, so no "big bang" approach.

客户分阶段看到系统,所以可能比较少会有“大爆炸”的态度。

5、不利条件

1)Requires good communication and agreement.

需要良好的沟通和协商。

2)Requires good project management, control and monitoring work.

需要良好的项目管理,控制和监视工作。

3)communication and agreement.

需要良好的沟通和协商。

4)Requires good project management, control and monitoring work.

需要良好的项目管理,控制和监视工作。

如果这篇文章对你有帮助,记得留下star哦~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/004Product.html b/column/Product/SoftwareEngineer/004Product.html index fa1d014d..ab5b6827 100644 --- a/column/Product/SoftwareEngineer/004Product.html +++ b/column/Product/SoftwareEngineer/004Product.html @@ -19,7 +19,7 @@
Skip to content

前言

在日常的软件开发中,很多人可能认为只要技术实力够了,不需要任何的软件项目管理。但殊不知的是,软件项目管理对于整个软件项目起着至关重要的作用,甚至有可能关乎到软件项目的生死存亡。一项调查显示,70%的项目失败是由于管理不善引起的,而并不是因为技术实力不够的原因。

那在软件项目管理当中,重要的 4 个因素又是什么呢?

在下面的这篇文章当中,将讲解软件项目管理中的 4 个重要因素 4P, peopleproductprocessproject

一、项目管理的重要性和定义

1、重要性(两个阶段)

(1)20 世纪 70 年代中期

70%的项目失败是由于管理不善引起的,而并不是因为技术实力不够;

管理是影响软件研发项目全局的因素,而技术只影响局部的因素。

(2)20 世纪 90 年代中期

美国软件工程实施现状的调查:

10%的项目能够在预定的费用和进度下交付;

软件项目管理成为软件项目开发中最重要的核心问题之一。

2、软件项目管理的定义

(1)定义

软件项目管理是为了使软件项目能够顺利完成,而对成本人员进度质量风险等进行分析和管理的活动。

(2)对象

软件工程项目,它所涉及的范围覆盖了整个软件工程过程。

(3)何时(即什么时候做项目管理)

这种管理在技术工作开始之前就应开始,在软件从概念到实现的过程中继续进行,当软件工程过程最后结束时才终止

二、管理四要素 4P

1、管理的四要素(4P)

  • 人员 People —— 成功项目的重要因素;
  • 产品 Product —— 要开发的软件;
  • 过程 Process —— 软件工程的框架活动,包含了任务、里程碑、工作产品以及质量保证点;
  • 项目 Project —— 开发软件所需要的所有工作

2、软件项目中影响最终结果的要素

  • 规模
  • 提交的期限
  • 预算和代价
  • 应用领域
  • 运用的技术
  • 系统约束
  • 用户需求
  • 可提供的资源

3、项目管理关心的问题

  • 产品的质量
  • 风险的识别和管理
  • 度量
  • 代价估算
  • 项目进度
  • 和客户交流
  • 项目成员
  • 其他资源
  • 项目监控

PS: 以下将对 4P 的内容进行详细分析。

三、项目参与者类型(people)

项目参与者类型一般包括以下几类:

  • 高级管理者:负责定义业务问题;
  • 项目(技术)管理者:必须计划、激励、组织和控制软件开发人员;
  • 开发人员:负责开发一个产品或应用所需的专门技术;
  • 客户:负责说明待开发软件相关需求的人以及其他风险承担者;
  • 最终用户:一旦软件发布成为产品,最终用户是直接与软件进行交互的人

总结: ① 高级管理者,即定义业务问题的人; ② 项目管理者,即管理软件开发的人; ③ 开发人员,即应用技术开发软件的人; ④ 客户,即提出软件需求,并承担一定风险的人; ⑤ 最终用户,即与软件交互的人。

四、项目小组结构(people)

1、项目的三种一般小组组织形式

(1)民主分散式(Democratic Decentralized, DD)

(2)控制分散式(Controlled Decentralized, CD)

(3)控制集中式(Controlled Centralized, CC)

2、关于小组结构的说明

(1)DD(民主分散式):没有固定的负责人,适合难度比较高、交付期限很长及生存期较长的项目,最适合于解决模块化程度比较低的问题,因为需要通信;

通俗来说:没有负责人,只有水平通信,成员之间需要广泛的两两交流。

(2)CD(控制分散式):有一个固定的负责人,若有子负责人,子负责人和总负责人的通信垂直的,而个人间的通信水平的,适合交付期限较长、比较简单的项目;

通俗来说:有固定负责人,成员之间需要交流,成员与负责人之间也需要交流;若有子负责人,成员跟子负责交流,子负责人跟总负责交流。

(3)CC(控制集中式)负责人和小组成员之间的通信垂直的,适合解决交付期限比较严格的、简单的、模块化程度高的项目

通俗来说:有固定负责人,成员之间不沟通,只跟上级沟通。

:CD 和 CC 两种结构都需要有一个固定的负责人,而 DD 不用;且会比 DD 产生更少的缺陷。

3、项目小组人员间的通信路径

项目小组人员间的通信路径 从上图中可以看出,项目小组人数越多,通信路径越多。 通信路径计算公式为

$$ C_n^2=\frac{n(n-1)}{2} ,n表示水平通信成员间的人数 $$

4、小组结构的选择需考虑的因素

对于一个小组来说,选择一个合适的结构需考虑以下因素:

  • 待解决软件项目的困难程度
  • 产生的程序规模,以代码行或者功能点来衡量;
  • 小组成员需要共同工作的时间(小组生存期);
  • 项目所需要的通信的程度
  • 问题能够被模块化的程度
  • 待建造系统所要求的质量和可靠性
  • 交付日期的严格程度

5、思考题

Q1:某公司有 21 名员工,请问分别按 DD、CD、CC 方式来进行组织结构的划分,各自会产生多少条的通信路径?假设在 CD 和 CC 方式下被分成四组,画出大概的组织结构图。

A1

思考题解答

下面给出无子负责人有子负责人的框架图:

无子负责人

有子负责人

写到这里,不妨再思考下,在 CD 和 CC 方式下被分成五组,有多少条通信路径?组织架构又是怎么样的呢? 评论区留下你的答案~

五、软件范围及问题分解(product)

1、预告

在开始进行一个项目之前,应该了解些什么呢?

1在进行项目计划之前,软件开发者和客户必须一起定义产品的目的和范围,考虑可选的解决方案,标识技术和管理的约束;

2)没有这些信息,就不可能进行合理的(准确的)成本估算、有效的风险评估、适当的项目任务划分或是可管理的项目进度安排

3)软件范围是软件项目管理的第一个活动。

通过下面一张图来加深对软件范围的理解。

软件范围

圆圈里的内容即软件范围,确定该项目要做什么;那么不在圈子里面的,就先抛开,也就是说,不该做的内容先不要做。

2、软件范围的确定(划定问题的边界)

1)语境;

2)信息目标;

3)功能和性能

3、问题分解(确定各部分的功能)

1)分而治之;

2)估算开始之前,范围中所描述的软件功能必须被评估和细化,以提供更多的细节。因为成本和进度的估算都是面向功能的,所以某种程度的分解通常是很有用的。

六、过程(process)

1、一般性阶段

1)软件过程的一般性阶段(定义、开发和支持)适用于所有软件项目;

2)问题在于选择一个适合项目组所要开发软件的过程模型。

回顾下上一篇文章提到过的过程模型:

  • 线性顺序模型(瀑布模型)
  • V 模型
  • 原型实现模型
  • RAD 模型
  • 增量模型
  • 螺旋模型
  • 形式化方法模型

2、选择过程模型阶段

项目管理者必须决定哪一个过程模型最适合用在此项目,因此在选择过程模型时需考虑以下因素:

1)需要该产品的客户和将做此工作的人员;

2)产品本身的特征;

3)软件项目组工作的项目环境。

3、已确定过程模型阶段

1)当一个过程模型被选定时,项目组基于通用过程框架活动集合,定义一个初步的计划;

2)一旦建立了初步的计划,便可以开始进行过程分解,即必须建立一个完整的计划以反映框架活动中所需要的工作任务

3)工作任务必须针对项目的特定需要进行适应性修改;且框架活动总是一样的,但工作任务则要根据一系列的适应性标准来选择。

七、产品和过程的二元性(product and process)

产品和过程的二元性

从上图中可以看出,横向坐标表示过程,纵向坐标表示产品,也就是说,每一个产品都有它对应的一系列过程。所以,在一个项目中,产品和过程都一样重要,缺了谁都不行,这也就体现了产品和过程的二元性

八、项目的 5W2H 原则(project)

项目的 5W2H 原则包含以下几点:

  • WHY —— 为什么(Why)该系统被开发?(业务目的
  • WHAT —— 将做什么(What)?(项目任务
  • WHEN —— 什么时候(When)做?(里程碑
  • WHO —— 某功能由谁(Who)负责?(角色和责任
  • WHERE —— 他们的机构组织位于何处(Where)?(角色责任界定
  • HOW —— 工作将如何(How)被技术和管理地进行?(管理和技术策略
  • HOW MUCH —— 每种资源需要多少(How much)?(资源分配

九、写在最后——think more

看完上面文章内容后,不妨试问下自己以下问题:

分析如下具体项目情况,选择合适的团队结构(CC、CD、DD)及软件过程模型,并分析原因。

Q1:在一个信息系统组织中,你被指派为项目经理。你的工作是开发一个应用程序,该程序类似于你的团队以前已经做过的某个项目,只是规模更大而且更复杂一些。需求已经由用户写成文档。

Q2:你被指派为一个小型软件产品公司的项目经理。你的工作是开发一个有突破性的产品,该产品结合了虚拟现实的硬件和高超的软件。因为家庭娱乐市场的竞争非常激烈,完成这项工作的压力很大。

Q3:你被指派为一个大型软件产品公司的项目经理。你的工作是管理该公司已被广泛使用的字处理软件的新版本的开发。因为必须获得新的收益,已经规定了紧迫的最后期限并对外公布。

Q4:在一个为遗传工程领域服务的公司中,你被指派为项目经理。你的工作是管理一个软件新产品的开发,该产品能够加速基因分解的速度。这项工作是面向研究及开发的,但其目标是在下一年度内生产出产品。

评论区留下你的答案 ٩(๑❛ᴗ❛๑)۶

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/005Measure.html b/column/Product/SoftwareEngineer/005Measure.html index bba236d7..dc8d29e9 100644 --- a/column/Product/SoftwareEngineer/005Measure.html +++ b/column/Product/SoftwareEngineer/005Measure.html @@ -19,7 +19,7 @@
Skip to content

前言

对于一件事物来说,当你能够测量你所说的并将其用数字表达出来时,你就会对它有了一些了解;但当你不能测量,不能用数字表达它时,你对它的了解就会很贫乏。

上面这句话表明一个事实,当你想要得到一个可量化的结果时,你需要先去测量它,有了测量结果后,才会有度量。对于事物是这样,而对于软件项目管理来说也是如此。一个好的软件项目管理,需要经过多方面的测量和度量,才能更好的呈现出一个比较满意的结果。

在接下来的这篇文章中,将讲解关于软件项目管理中软件的度量

一、度量的目的

1、引例

引用Lord Kelvin曾说过一句话: ① 当你能够测量你所说的并将其用数字表达出来,你就对它有了一些了解;② 但当你不能测量,不能用数字表达它时,你对它的了解就很贫乏、很不令人满意;③ 它可能是知识的开始,但你在思想上还远没有进入科学的境地。

这句话说明,想要得到一个可量化的结果,需要先去测量它,有了测量结果后,才会有度量;也就是说,测量是度量的基础

2、度量的目的

进行度量工作,是为了了解产品开发的技术过程产品本身

  • 度量开发过程的目的是为了改进过程

  • 度量产品的目的是为了提高产品的质量

3、度量的作用

  • 度量的作用是为了有效地定量地进行管理。

二、测量、度量和指标区别

1、引例

假设有 A 和 B 两个人,我们都知道 A 比 B 高。但不知道 A 比 B 高多少?

这个时候是不是就得经过测量身高才能知道具体值。

所以,A 和 B 的身高值即为测量值。

经过测量,A 的身高为 189cm,B 的身高为 170cm。

得出结论,A 比 B 高 19cm。

所以,A 比 B 高 19cm 是度量值。

2、测量、度量和指标的区别

(1)测量(measure) —— 对一个产品或过程的某个属性的范围、数量、维数、容量或大小提供了一个定量的指示。

(2)度量(metrics) —— 对一个系统、部件或过程具有的某个给定属性的度的一个定量测量。

(3)指标(indicator) —— 软件工程师收集测量并开发度量,这样就可以获得“指标(indicator)”;指标是一个度量或度量的组合,它对软件过程软件项目产品本身提供了更深入的理解。

3、思考题

Q:指出下面这段话中哪些是测量,哪些是度量,哪些是指标

有四个软件小组共同完成一个大型项目,但是每个小组必须进行技术评审,

经过检查每人每小时所发现的错误数,管理者发现采用更加正式评审方法的两个小组比起另外两个小组,每人每小时所发现的错误数要高 40%

假设其它参数相同,这就给管理者提供一个指标:正式的评审方法比起其他评审方法在时间投资上能得到更大的回报,他可能会建议所有小组都采用正式的评审方法。

A:从上面这段话中可以得出,每人每小时所发现的错误数为测量值,更加正式的评审方法为指标,每人每小时所发现的错误数要高 40%为度量值

得出结论,测量是度量的基础,度量是为了得到指标,它们的关系为:测量->度量->指标。

三、过程度量和项目度量

软件过程度量主要用于战略的目的,软件项目度量则是战术的

1、过程

(1)过程度量

  • 在软件发布之前的错误数的测量;
  • 交付给最终用户并由最终用户报告的缺陷的测量;
  • 交付的工作产品生产率)的测量;
  • 花费的工作量的测量;
  • 花费的时间的测量;
  • 进度是否一致的测量。

(2)过程指标

  • 使得软件工程组织能够洞悉一个已有过程的功效(如范型、软件工程任务、工作产品及里程碑);

  • 使得管理者和开发者能够评估哪些部分可以起作用,哪些部分不行;

  • 过程度量(Metrics)的收集跨越所有的项目,并经历很长的时间,目的是获得改善软件过程的指标。

2、项目

(1)项目度量

  • 大多数软件项目度量的第一个应用是在估算时发生的;
  • 从过去的项目中收集的度量可用来作为估算现在软件项目的工作量及时间的基础;
  • 所花费的工作量及时间的测量可以和预估算值进行比较,项目管理者使用这些数据来监督和控制项目的进展。

(2)项目度量的目的

  • 能指导进行一些进度上的必要调整,以避免延迟、减少问题及风险,从而使得开发时间减到最少;

  • 项目度量可在项目进行的基础上评估质量,在必要时修改技术方法以改进质量。

(3)项目指标

  • 评估正在进行的项目的状态;
  • 跟踪潜在的风险;
  • 在问题造成不良影响之前发现它们;
  • 调整工作流程或任务;
  • 评估项目组在控制软件工程工作产品的质量的能力。

四、度量的方式

1、物理世界中的测量

(1)直接测量 —— 例如,测量一个螺栓的长度;

(2)间接测量 —— 例如,用次品率来测量生产出的螺栓质量。

2、软件测量

软件测量与物理测量一样,也同样分为两类。

(1)直接测量

过程 —— 软件工程过程直接测量包括所投入的成本和工作量;

产品 —— 软件产品直接测量包括产生的代码行数(LOC)、执行速度、存储量大小、在某种时间周期中所报告的差错数。

(2)间接测量

产品 —— 软件产品的间接测量包括功能性、复杂性、效率、可靠性、可维护性和许多其它的质量特性。

五、面向规模的度量

1、定义

(1)面向规模的度量是对软件和软件开发过程的直接度量

(2)可以建立一个面向规模的数据表格来记录项目的某些信息。

2、有用度量的计算——举例阐述

项目LOC工作量成本文档页数错误缺陷人员
Alpha1210024168365134293
Beta27200624401224321865
Gamma20200433141050256646

Q:该表格列出了在过去几年完成的每一个软件开发项目和关于这些项目的相应的面向规模的数据。那么,从该表中可以获得哪些有用信息?三个项目哪个项目的软件质量最高?哪个项目的生产率最高?哪个项目的单位成本最高?

:LOC 即 Line Of Code,表示代码行数;PM 即 Person Month,表示每人每月。

需要注意的是:在表格中记载的工作量和成本是整个软件工程的活动(分析、设计、编码和测试),而不仅仅是编码活动

对于每一个项目,可以根据表格中列出的基本数据计算简单的面向规模的生产率和质量等的度量。

A:根据表格可以对所有的项目计算出以下有用度量

生产率 = KLOC/PM(人月);(成正比)

质量 = 错误数/KLOC;(成正比)

质量 = 缺陷数/KLOC;(成反比)

成本 = 元/LOC;(成正比)

文档 = 文档页数/KLOC。(成正比)

六、面向功能的度量

1、定义

(1)面向功能的软件度量是对软件和软件开发过程的间接度量

(2)面向功能的度量主要考虑程序的“功能性”和“实用性”,而不是对 LOC 计数;

(3)该度量是一种叫做功能点方法的生产率度量法,利用软件信息域中的一些计数软件复杂性估计的经验关系式而导出功能点 FP。

2、功能点度量的计算

(1)图例

功能点度量的计算

需了解以下公式

FP=总计数值 х(0.65+0.01 х ΣFi);

“ 0.65+0.01 х ΣFi ” :复杂度调整因子。

  • FP 即 Function Points,表示功能点;

  • 总计数值是所有加权计数项的和;与五个信息域有关,即输入,输出,查询,文件,接口,且需考虑加权因子;

  • Fi 为复杂度校正值,需回答 14 个问题,详情看第(3)点

(2)五个信息域

  • 用户输入数:各个用户输入是面向不同应用的输入数据;
  • 用户输出数:各个用户输出是面向应用的输出信息,包括报表,屏幕信息,错误信息等。在报表中的各个数据项不应该再分别计数;
  • 用户查询数:查询是一种联机的交互操作,每一个不同的查询都要计算;
  • 文件数:每一个逻辑主文件都应计数。逻辑主文件是指逻辑上的一组数据,可以是一个大数据库的一部分,也可以是一个单独的文件;
  • 外部接口数:与系统中其他设备通过外部接口读写信息次数均应计数。

(3)关于复杂性校正值 Fi

  1. 系统是否需要可靠的备份和恢复?
  2. 是否需要数据通信?
  3. 是否有分布处理的功能?
  4. 是否性能成为关键?
  5. 系统是否运行在现存的高度实用化的操作环境中?
  6. 系统是否需要联机数据项?
  7. 联机数据项是否需要建立多重窗口显示和操作,以处理输入处理?
  8. 主文件是否联机更新?
  9. 输入、输出、文件、查询是否复杂?
  10. 内部处理过程是否复杂?
  11. 程序代码是否可复用?
  12. 设计中是否包括了转移和安装?
  13. 系统是否设计成可以重复安装在不同机构中?
  14. 系统是否设计成易修改和易使用?

(4)关于计算

一旦收集到上述数据,就可以计算出与每一个计数相关的复杂性值

一个信息域是简单的、平均(中等)的还是复杂的,由使用功能点方法的机构自行确定,从而计算出加权计数

计算功能点,使用如下的计算公式

FP=总计数值 ×[0.65+0.01 × ∑(Fi)],总计数值是所有加权计数项的和;

Fi(i = 1..14)是复杂性校正值,它们应该通过逐一回答 14 个问题来确定,详情看第(3)点;

③④ 注意点

  • Fi 的取值 0~5:0表示没有影响;1表示微小影响;2表示轻度;3表示中度;4表示显著;5表示重大;

  • ∑(Fi)是求和函数。

一旦计算出功能点,就可仿照 LOC 的方式度量软件的生产率、质量和其它属性:

生产率= FP/PM(人月);(成正比)

质量=错误数/FP;(成正比)

质量 = 缺陷数/FP;(成反比)

成本=元/FP;(成正比)

文档=文档页数/FP;(成正比)

(5)基于 FP 的软件度量

  • 每个 FP 的错误数(Errors per FP) —— 质量

    每个 FP 的缺陷数(Defects per FP) —— 质量

  • 每个 FP 的花费($ per FP) —— 成本

  • 每个 FP 的文档页数(Pages of documentation per FP) —— 文档

  • 每人月完成的 FP 数(FP per person-month) —— 生产率

(6)思考题——think more

功能点 FP 和总计数值之间的关系,最小值是()x 总计数值,最大值是()x 总计数值。

如果 14 个问题的复杂度调整值总和为 42,总计数值假设为 100,则功能点 FP 的值为___。

解析:

  • 最小值为0.65 x 总计数值,最大值为1.35 x 总计数值。

  • 功能点 FP 的值为 FP = 总计数值 ×[0.65+0.01 × ∑(Fi)] = 100 x (0.65 + 0.01 x 42) = 100 x 1.07 = 107

3、扩展的功能点度量 —— 特征点

(1)基础知识

扩展的功能点也叫特征点度量法,是另外一种功能点度量;

② 功能点度量最初主要是用于商业信息系统应用中;

强调数据维而排除了功能维及行为(控制)维;

因此,功能点度量不适合用于很多工程及嵌入式系统(它们强调功能及控制)。

(2)特征点

功能点测量的超集(superset),适用于算法复杂性较高的应用,主要应用于系统和工程软件的应用,例如,实时系统、过程控制软件及嵌入式软件应用。

(3)特征点的计算

特征点的计算

由上图可以发现

FP 信息域值计算的基础上增加了一个新的软件特性,即算法——特定计算机程序中所包含的一个界定的计算问题;

在特征点的计算中,权值是固定的,而原来功能点的度量计算中,权值有简单、平均、复杂三种取值。

PS:权值即加权因子

4、调和不同的度量方法

Q:如果我知道 LOC 的数量,有没有可能估算功能点(FP)的数量?

A:代码行数和功能点之间的关系依赖于用来实现软件的程序设计语言设计质量

那么不同程序语言建造一个功能点所需的平均代码行数是多少呢?

如下图所示

不同的语言中建造功能点所需LOC

看到这里,小伙伴们对功能点是否有一定了解了呢?

不妨试问下自己,如果开发一个信息系统需要用到56000 行 VB 代码3000 行 SQL 代码,那么该系统的功能点(FP)是多少?

$$ \frac{56000 LOC}{47 LOC/FP}+\frac{3000 LOC}{40 LOC/FP} ≈ 1192+75 = 1267个 $$

七、软件质量度量

1、软件质量的度量

质量度量贯穿于软件工程的全过程以及软件交付给用户使用之后。

(1)交付前度量

  • 在软件交付之前得到的度量可作为判断设计和测试质量好坏的依据;
  • 这一类度量包括程序复杂性有效的模块性总的程序规模

(2)交付后度量

  • 在软件交付之后的度量则把注意力集中于还未发现的缺陷数系统的可维护性方面;

2、软件质量的度量指标

为了实现实时的质量评估,工程师们必须采用技术测量客观地评估质量,而不能采用主观的方法。以下列出 4 种客观的度量指标:

(1)正确性(最重要)

  • 一个程序必须正确地运行,并为它的用户提供某些输出;
  • 正确性要求软件执行所要求的功能;
  • 关于正确性的最常用的测量是每 KLOC 的缺陷数(Defects/KLOC),这里的缺陷数定义为“验证结果与需求不符的地方”。

思考

Q:缺陷数越高越好还是越少越好?

A:缺陷数越高,软件质量越低;所以缺陷数应该尽可能少。

(2)可维护性

  • 可维护性是指遇到错误时程序能被修改的容易程度,维护所占的工作量比其他活动都大,它无法直接测量

  • 面向时间:

    有一种简单的面向时间的度量,称MTTC(平均变更时间),可以作为可维护性的度量;

    这个时间包括分析变更要求设计适当的修改实现变更并测试、及把变更发送给所有的用户

  • 面向成本:

    还有一种面向成本的可维护性度量,称损坏度,指的是软件发布给最终用户后修改遇到缺陷的成本

思考

Q1:MTTC 越低,可维护性越好还是越差呢?

A1:MTTC 即平均变更时间,变更时间越少,说明软件质量越好;所以,MTTC 越低,可维护性越好。

Q2:当每千代码行的缺陷数降低的同时,损坏度有可能提高吗?

A2:损坏度即遇到缺陷的成本。 举个例子: 假设在一个软件中,遇到 50 个缺陷,这 50 个缺陷都是些很小很细微的问题,很快就能修复完,那么所花费的成本也就不会很高;

再或者在另一个软件中,遇到 5 个缺陷,这 5 个缺陷刚好是 5 个非常重大的漏洞问题,需要很多时日才能修复完,那么所花费的成本就会很高,即损坏度提高;

所以,缺陷数低并不代表成本就会低,这也就意味着,当每千代码行的缺陷数降低的同时,损坏度有可能提高。

(3)完整性

  • 完整性是度量一个系统在安全方面的抗攻击的能力
  • 软件的三个成分,程序、数据和文档都会遭到攻击;
  • 度量完整性,需要定义两个附加的属性:危险性安全性
  • 危险性是特定类型的攻击将在一个给定时间内发生的概率;
  • 安全性是排除特定类型攻击的概率;
  • 一个系统的完整性可定义为 完整性= ∑[1-危险性 ×( 1-安全性) ] 其中,对每一个攻击的危险性和安全性都进行累加。

思考

Q:某个攻击的危险性是 70%,安全性是 40%,那它的完整性等于多少?

A:完整性 = ∑ [1-危险性 ×( 1-安全性) ] = 1 - 0.7(1 - 0.4) = 1 - 0.7x0.6 = 1 - 0.42 = 0.58

试想下,一个完整性为 0.58 的系统,它合格吗?

评论区留下你的答案~

(4)可用性

如果一个程序不具有“用户友好性”,即使它所执行的功能很有价值,也常常会失败。可使用性量化“用户友好性”,并依据以下四个特征进行度量:

  • 为学习系统所需要的体力上的智力上的技能;
  • 为达到适度有效使用系统所需要的时间;
  • 当软件被某些人适度有效地使用时所度量的在生产率方面的净增值
  • 用户角度对系统的主观评价 (可以通过问题调查表得到)。

八、DRE

1、DRE 的全称

DRE,即 Defect Removal Efficiency,表示缺陷排除效率。

2、衡量 DRE 的两种角度

(1)DRE=E/(E+D)

  • DRE 是对质量保证及控制活动中滤除缺陷能力的一个测量;
  • E 是软件交付给最终用户之前所发现的错误数,D 是软件交付之后所发现的缺陷数。

(2)$DRE_i =E_i/(E_i+E_{i+1} )$

  • DRE 也能够用于在项目中评估一个小组在错误传递到下一个活动或任务之前发现这些错误的能力。在这种情况下,我们定义 DRE 为:

$$ 即,DRE_i =E_i/(E_i+E_{i+1} ) $$

  • $E_i$是在软件工程活动 i 中所发现的错误数, $E_{i+1}$是在软件工程活动 i+1 中所发现的错误数,这些错误起源于软件工程活动 i 中未能发现的错误。
  • 可以把$E_i$理解为前一个活动,$E_{i+1}$理解为后一个活动

3、思考题 —— think more

软件团队将软件交付给了最终用户。在使用的第一个月中,用户发现了 8 个缺陷。在交付之前,软件团队在正式的评审和所有的测试任务中发现了 72 个错误。那么,项目总的缺陷排除效率公式是 DRE=E/ ( + ),最后的结果是____(写成小数点的形式)。

解析:

  • 项目总的缺陷排除效率公式是 DRE=E/(E+D);

  • 最后的结果是 DRE = 72 / (72 + 8) = 0.9。

PS 本文篇幅较长,有错别字欢迎评论区纠正,随时改进~ 如果这篇文章对你有帮助,记得留下star哦~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/006Scope.html b/column/Product/SoftwareEngineer/006Scope.html index 8a5a670d..5b8fa48b 100644 --- a/column/Product/SoftwareEngineer/006Scope.html +++ b/column/Product/SoftwareEngineer/006Scope.html @@ -19,7 +19,7 @@
Skip to content

一、软件项目计划

1、目标

软件项目计划的目标是提供一个框架,使得管理人员对资源、成本和进度做出合理估算。 这些估算应当在项目开始时的一个有限的时间段内做出,并且随着项目的进展定期进行更新。

2、步骤

1)Scoping(范围)—— 确定软件范围;

2)Estimation(估算)—— 估算资源、工作量、成本;

3)Risk(风险)—— 风险管理;

4)Schedule(进度)—— 进度安排;

5)Control strategy(控制策略)—— 指定控制策略。

二、软件范围

1、软件范围定义

1)估算开始时,应对功能进行评价,并适当细化以提供更详细的细节。

2)由于成本和进度的估算都与功能有关,因此常常采用某种程度的功能分解。

3)软件范围包括功能性能约束接口可靠性,无二义和可理解。

2、软件范围——引例

思考这样一个问题:针对这个软件的范围描述,请找出软件范围的功能、性能、约束、接口等。

考虑开发一个驱动传送带分类系统(CLSS)的软件,对该软件的范围陈述如下:

1)传送带分类系统将沿传送带移动的盒子进行分类,每个盒子由一个包含零件号的条形码来标识,并在传送带的末端分送到六个箱子中的一个,这些盒子要通过一个由条形码阅读器和一台 PC 所组成的分类站

2)分类站的 PC 连接到一个分流器上,它把盒子分送到不同的箱子中,盒子以随机的顺序通过且其间的距离相同,传送带以每分钟 5 英尺的速度移动。

3)CLSS 软件以和传送带速度一致的时间间隔接受来自条形码阅读器的信息。条形码数据被解码成盒子的标识格式,软件将在最多可容纳 1000 个条目的零件号数据库中进行检索,以确定当前在阅读器(分类站)位置的盒子应该放到哪个箱子中。

4)该箱子的信息被传送到分流器,以把盒子放进合适的箱子中,每个盒子所放进的箱子的记录均被保存起来以供以后提取及报告。

5)CLSS 软件同时也接受来自脉冲流速计的输入,用于使控制信号与分流器同步,根据分类站和分流器之间产生的脉冲数,软件将产生一个控制信号给分流器,以适当地定位盒子。

通过分析,这个过程将产生如下功能

  • 读取条形码输入
  • 读取脉冲流速计
  • 解码零件编码数据
  • 检索数据库
  • 确定合适的箱子
  • 产生分流器的控制信号
  • 维护盒子目的地的记录

性能取决于传送带的速度,对于每个盒子的处理必须在下个盒子到达条形码阅读器之前完成。

约束条件包括:

  • 盒子以随机的顺序通过且其间的距离相同,传送带以每分钟 5 英尺的速度移动;
  • CLSS 软件以和传送带速度一致的时间间隔接受来自条形码阅读器的信息;
  • 控制信号与分流器同步。

接口:条形码阅读器,分流器,PC 等

三、影响估算的因素

软件项目管理过程开始于项目计划,在做项目计划时,重要的一项活动就是估算

那么,影响估算的因素有哪些呢?

  • 复杂性越高,估算的风险就越高。

  • 项目的规模越大,开发工作量越大,估算的风险越高。

  • 项目的结构化程度越高,进行精确估算的能力就能提高,而风险将减少。

  • 历史信息的有效性也影响估算的风险。历史信息越有效, 总的风险就越少。

  • 如果对软件项目的作用范围还不是十分清楚,或者用户的要求经常变更,也会增加估算的风险。

  • 计划人员应当要求在软件系统的规格说明中给出完备的功能、性能、接口的定义。

四、软件项目资源

软件项目计划的第二个任务是对完成该软件项目所需的资源进行估算。

1、软件项目资源构成

(1)最基本的、重要的资源——人员;

(2)现成的用意支持软件开发的工具——硬件工具;

(3)现成的用意支持软件开发的工具——软件工具(CASE);

(4)可复用构件。

2、分析图

软件项目资源构成要素

接下来对各构成要素进行一一分析。

3、人力资源

1)在考虑各种软件开发资源时,人是最重要的资源

2)在安排开发活动时必须考虑人员的技术水平专业人数、以及在开发过程中对各阶段人员的需要

3)对于一些规模较小的项目,只要向专家做些咨询,也许一个人就可以完成所有的软件工程步骤

4)对一些规模较大的项目,在整个软件生存期中,各种人员的参与情况是不一样的

以下通过一张图了解各阶段人员对软件生命周期的共享度。

各阶段人员对软件生命周期的共享度

4、硬件资源

硬件是作为软件开发项目的一种工具而投入的,分别包含以下三种类型

(1)宿主机(Host)—— 软件开发时使用的计算机及外围设备;

(2)目标机(Target)—— 运行已经开发成功软件的计算机及外围设备;

(3)其它硬件设备 —— 专用软件开发时需要的特殊硬件资源;

5、软件工具

软件工程人员在软件开发期间使用了许多软件工具来帮助开发,这种软件工具集叫做计算机辅助软件工程(CASE)。分别包括

1)业务系统计划工具集;

2)项目管理工具集;

3)支援工具 —— 文档生成工具、网络系统软件、数据库、电子邮件、通报板,以及配置管理工具;

4)分析和设计工具;

5)编程工具;

6)组装和测试工具;

7)原型化和模拟工具;

8)维护工具;

9)框架工具 —— 这些工具能够提供建立集成项目支撑环境(IPSE)的框架。

6、可复用构件

(1)可复用的软件资源,被称为构件。可复用构件分别包含:

  • 成品(off-the-shelf)构件:已存在的构件,能够从第三厂商获得,被准备用于当前的项目,并已被完全确认。
  • 具有完全经验的构件:当前项目成员在这些构件上有丰富的经验。
  • 具有部分经验的构件:与当前项目相关,但需做实质性的修改;项目成员对此构件的经验有限。
  • 新构件:为满足项目组的特定需要而专门开发的软件构件。

(2)使用可复用构件时,应考虑:

  • 成品构件能够满足项目的需求 —— 采用!因为低成本和低风险
  • 具有完全经验的构件可以使用,但在项目计划中应反映出来 —— 修改和集成的风险可接受。
  • 具有部分经验的构件使用时必须详细分析 —— 如果要大量的修改,所需的成本可能超过开发新构件的成本。

五、软件工作量与成本的估算

在软件成本和工作量的估算中,不确定因素非常大,包括人、技术、环境、政治等因素都会影响估算结果。

软件项目的估算能够通过一系列系统化的步骤,在可接受的风险范围内提供估算结果。

对于每一个可用的软件成本估算的选择,其效果好坏取决于用于估算的历史数据

先用一张图了解软件工作量和成本的估算方法。

在这里插入图片描述

接下来讲解三种估算方法。

1、基于 LOC 估算工作量和成本

(1)估算步骤

  • ① 给出软件范围 —— 项目计划人员可对每一个分解的功能提出一个有代表性的估算值范围

  • ② 进行功能分解 —— 利用历史数据凭实际经验(当其它的方法失效时),对每个功能分别按最佳的可能的悲观的三种情况给出 LOC 或 FP 估计值 ,记作 a、m、b;

  • ③ 估算每一个子功能 —— 计算 LOC 或 FP 的期望值 E;

    $$ E = \frac{(a+4m+b)}{6} $$

  • ④ 计算总 LOC 数(∑) —— 所有子功能的总估算变量值除以相应于该估算变量的平均生产率度量得到项目的总工作量;

    例如,若假定总的 FP 估算值是 310,基于过去项目的平均 FP 生产率是 5.5 FP/PM,则项目的总工作量是:工作量 = 310/5.5 = 56 PM,即每个月需要 56 个人

  • ⑤ 给出两个历史数据 ——

    第一种:给出生产率和劳动率价格,可以算出工作量成本

    第二种:给出生产率和每行代码成本,也可以算出工作量成本

    下面通过一张图了解这两种方法分别如何计算出工作量和成本:

    基于LOC估算工作量和成本

(2)引例

系统定义评审指明,软件是在一个工作站上运行,其接口必须使用各种计算机图形设备,包括鼠标器、数字化仪、高分辨率彩色显示器和激光打印机。在这个实例中,使用 LOC 做为估算变量。根据系统规格说明, 软件范围的初步叙述如下

“软件将从操作员那里接收 2 维或 3 维几何数据,操作员通过用户界面CAD 系统交互并控制它,这种用户界面将表现出很好的人机接口设计特性。所有的几何数据和其它支持信息保存在一个CAD 数据库内。要开发一些设计分析模块以产生在各种图形设备上显示的输出。软件要设计得能被控制,并能与各种外部设备进行交互,外部设备包括鼠标器、数字化仪、激光打印机和绘图仪。”

从以上的例子可以得出:

① 经过分解, 识别出下列主要软件功能:

  • 用户界面和控制功能;
  • 二维几何分析;
  • 三维几何分析;
  • 数据库管理;
  • 计算机图形显示功能;
  • 外设控制 PC;
  • 设计分析模块。

② 可得到如下估算表:

功能最佳值 a可能值 m悲观值 b期望值 E元/行行/PM成本(元)工作量(PM)
用户接口控制180024002650234014315327607.4
二维几何造型41005200740053802022010760024.4
三维几何造型46006900860068002022013600030.9
数据结构管理2950340036003350182406030013.9
计算机图形显示40504900620049502220010890024.7
外部设备控制2000210024502140281405992015.2
设计分析66008500980084001830015120028.0
总计33360656680144.5

从历史的基线数据求出生产率度量,即 行/PM元/行

根据复杂性程度的不同,对各功能使用不同的生产率度量值。根据估算表可得:

成本 = LOC 的期望值 E 乘以 元/行;

工作量 = LOC 的期望值 E 除以 行/PM;

因此可得,该项目总成本的估算值为 657,000 元,总工作量的估算值为每个月 145 人。

(3)基于 LOC 估算的相关计算

Question:

基于 LOC 估算某软件项目的工作量和人工成本,假设项目的子功能有三个,估算的 LOC 数分别为 1000,2000,3000,项目的生产率为 600LOC/PM,劳动力价格为 6000 元/PM,则项目总的 LOC 数、工作量、人工成本分别为多少?写出计算公式及计算过程。

Answer:

基于LOC估算的相关计算答案

2、基于 FP 估算工作量和成本

(1)估算步骤

  • ① 给出软件范围;

  • ② 进行功能分解(无需很细);

  • ③ 计算五个信息域计数值;

  • ④ 计算总计算值(应考虑加权因子);

  • ⑤ 回答 14 个问题,算出 ∑Fi (Fi 为复杂度校正值) ;

  • ⑥ 计算 FP;

  • ⑦ 给出两个历史数据,生产率(FP/PM)、人工价(元/PM);

    工作量=总 FP/生产率=PM;

    成本=工作量 x 人工价=元

(2)引例

某项目有5 个信息域计数和 1 个算法计数,如下图所示。假设已知该项目的两个历史数据,分别为:生产率为 4FP/PM,人工价为 3000 元/PM,试计算出复杂度校正值 ∑Fi,工作量和成本的值。

测量参数计数值权重(加权因子)求和
输入数404160
输出数255125
查询数12448
文件数4728
外部接口数4728
算法60318
总计数值569
复杂度调整因子0.84
特征点478

由上图可知:

  1. 复杂度调整因子为 0.84,即 0.65+0.01∑Fi=0.84,由此可计算出复杂度校正值 ∑Fi=19;

  2. 若要得到工作量,需先求功能点 FP,即:FP=总计数值 x(0.65+0.01∑Fi)=569x0.84=478FP;

  3. $$ 工作量Efficiency = \frac{总FP}{生产率}=\frac{478FP}{4FP/PM}≈120PM $$

  4. $$ 成本Cost = 工作量×人工价=120PM×3000元/PM=360000元 $$

(3)基于 FP 估算的相关计算

Question:

基于 FP 估算某软件项目的工作量和人工成本,假设项目的输入数、输出数、查询数、文件数、接口数分别为 59、20、10、5、2,加权因子取平均值 4、5、4、10、7,14 个问题的回答取值总和为 15。那么该项目的总计数值是多少?项目的功能点 FP 又是多少?假设项目的生产率为 16FP/PM,劳动力价格为 6000 元/PM,则工作量和人工成本分别为多少?写出计算公式及计算过程。

Answer:

基于FP估算的相关计算答案

写到这里,对基于 LOC 和 FP 的估算做个小结:

  • 这两种类型的估算的基本思想都是,先计算出 LOC 和 FP 的值,然后根据组织生产率每个劳动力价格(人工价)的历史数据,估算总成本工作量
  • 如果在估算的时候,遇到估算差别很大时,一般有以下两种原因① 项目的范围未能被充分理解或被误解;基于问题的估算技术中所使用的的生产率数据对于该应用是不合适的,或是太陈旧了,或是被无用了。

3、COCOMO Ⅱ 模型估算

(1)COCOMO Ⅱ 模型中项目估算的三个阶段

阶段时间功能描述(此阶段要做什么)
应用组装阶段(Application Composition)早期、确定系统性能时① 利用应用点application point 来进行估算规模;② 利用原型来解决高风险问题。
早期设计阶段(early design)需求稳定,体系结构已建立时① 研究可选的体系结构和概念;② 用功能点funtion point 来做估算规模。
体系结构后阶段(post architecture)软件在构造中,知道更多系统信息时① 以FP、LOC作为估算单位。

补充说明应用点知识:

应用点,即对象点。一种间接的软件测量,其计算需要使用以下三个元素:

  • 用户界面上的屏幕数 screens;
  • 报表数 reports;
  • 建造应用可能需要的构件数 3GLcomponents。

(2)COCOMO Ⅱ 模型估算步骤

  • ① 计算屏幕数、报表数和构件;
  • ② 计算对象点 OP,即 ∑(三个计算值 × 加权因子);
  • ③ 计算 NOP=OP × (1-复用度) ;
  • ④ 查表得到生产率参数的值 PROD;
  • ⑤ 工作量 E=NOP/PROD;
  • ⑥ 给出一个历史数据:人工价(元/PM);
  • ⑦ 成本=E× 人工价。

以下给出对象点和 PROD 的具体数值表:

不同类型对象的复杂度加权

复杂度加权
对象类型简单中等困难
屏幕123
报表258
3GL 构件10

不同水平的开发者经验和不同开发环境成熟度下的生产率

因素影响
开发者的经验/能力非常低正常非常高
环境成熟度/能力非常低正常非常高
PROD47132550

(3)基于 COCOMO Ⅱ 模型的计算

Question:

使用 COCOMO II 模型来估算构造一个简单的 ATM 软件所需的工作量和人工成本(单位分别是人月和元),该软件产生 11 个屏幕(有 3 个简单,3 个中等,5 个困难),10 个报表(有4个简单,6 个困难),72 个构件,复用度为 20%,假设开发者的经验能力为高,环境的成熟度能力为低,劳动力价格为 5000 元/PM。则 NOP、生产率能力 PROD、工作量 E 和人工成本 C 分别为多少。写出计算公式及计算过程。

Answer:

基于COCOMO Ⅱ模型的相关计算答案

写在最后

创作不易,如果这篇文章对你有用,记得点赞收藏哦~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/007RiskAnalysis.html b/column/Product/SoftwareEngineer/007RiskAnalysis.html index 7f39fac3..a3d7012b 100644 --- a/column/Product/SoftwareEngineer/007RiskAnalysis.html +++ b/column/Product/SoftwareEngineer/007RiskAnalysis.html @@ -19,7 +19,7 @@
Skip to content

一、风险及风险管理的含义

1、风险的含义

风险即所有在软件开发过程中带来负面影响的问题,是一个潜在的问题。

2、风险管理含义

风险分析和管理是标识风险评估其发生的概率估算其影响建立在实际发生情形下问题的应急计划,是一系列帮助软件小组理解和管理不确定性的步骤。

对于一个好的软件项目管理来说,理解风险和采取积极的措施管理风险是关键

二、被动和主动的风险策略

1、被动风险策略

(1)定义:被动风险策略是一种救火模式,是对风险不闻不问,直到发生了错误后项目组才赶紧采取行动试图迅速地纠正错误。

2、主动风险策略

(1)定义:在技术工作开始之前就已经启动,标识出潜在的风险,评估出现的概率和产生的影响,且按重要性加以排序。

(2)主要目标:主要目标是预防风险,但不是所有的风险都可以预防,因此需要建立一个应急计划,使其在必要时能够以可控的有效的方式做出反应。

三、风险的特性

风险有两大特性,分别为不确定性损失性。具体如下:

1、不确定性 —— 风险可能发生,也可能不发生;

2、损失 —— 如果风险变成了现实,就会产生恶性后果或损失。

四、风险的类型

风险类型有三类,分别是项目风险技术风险商业风险。具体如下:

1、项目风险

(1)主要威胁:威胁到项目计划。

(2)风险因素:①潜在的预算、进度、人力资源、客户和需求等方面的问题以及这些因素对软件项目的影响;项目复杂度、规模和结构不确定性。

2、技术风险

(1)主要威胁:威胁到要开发软件的质量和交付时间。

(2)风险因素:①潜在的设计、实现、接口、验证和维护等方面的问题;技术的不确定性、陈旧的技术和“领先的”技术。

3、商业风险

(1)主要威胁:威胁到要开发软件的生存能力。

(2)五种商业风险类型:

  • 市场风险——开发了一个没有人真正需要的优秀产品或系统;
  • 策略风险——开发的产品不再符合公司的整体商业策略
  • 销售风险——建造了一个销售部门不知道如何去做出售的产品;
  • 管理风险——由于重点转移或人员的变动而失去了高级管理层的支持;
  • 预算风险——没有得到预算或人力上的保证。

五、风险管理的步骤

风险管理主要有三个步骤,第一步为风险识别,第二步为风险预测,第三步为风险缓解、监控和管理。具体如下:

1、风险识别

(1)定义:风险识别是试图系统化地确定对项目计划(估算、进度、资源分配)的威胁。

(2)分类

  • 一般性风险:对每一个软件项目而言,一般性风险都是一个潜在的威胁。
  • 产品特定风险:指只有那些对当前项目的技术、人员及环境非常了解的人才能识别出来。

(3)风险识别的方法

风险识别的方法为建立风险条目检查表,具体步骤如下:

  • ① 产品规模 —— 与需要建造或修改的软件的总体规模相关的经验;
  • ② 商业影响 —— 与管理或市场所添加的约束相关的风险;
  • ③ 客户特征 —— 与客户的素质开发者和客户及时通信的能力相关的风险;
  • ④ 过程定义 —— 与软件过程被定义的程度软件被开发组织所遵守的程度相关的风险;
  • ⑤ 开发环境 —— 与建造产品所使用工具的可用性及质量相关的风险;
  • ⑥ 将建造的技术 —— 与待开发软件的“复杂性”系统所包含技术的“新奇性”相关的风险;
  • ⑦ 人员数目及经验 —— 与软件工程师的总体技术水平和项目经验相关的风险。

总结:

通过建立风险条目检查表,使得计划者通过得出每一项的答案后,能够估算风险产生的影响。

2、风险预测

风险预测从两个方面评估风险:风险发生的可能性或概率,即评估风险概率风险发生所产生的后果,即评估风险影响。具体如下:

(1)评估风险概率:以百分比表示

(2)评估风险影响

① 从定性角度看:有四个级别,分别为可忽略的轻微的严重的灾难性的

② 从定量角度看:即计算风险显露度,RE=P*C;其中P是风险发生的概率,C是风险发生时带来的项目成本。

举个例子:

Question:

某公司计划将使用 60 个可复用构件,其中只有 70%可能被使用,剩下的要重新定制开发,已知构件平均是 100LOC,每个 LOC 的成本是 14 美元,假设该风险发生的概率是 80%,计算风险显露度 RE。

Answer:

  • 风险:30%的构件要重新开发;
  • 风险发生的概率 P 为:P=80%;
  • 损失成本 C 为:C=60×30%×100×14=25200 元;
  • 风险显露度为:RE=P×C=80%×25200=20100。

3、风险缓解、监控和管理(Risk mitigation, monitoring and management,即 RMMM)

(1)风险缓解

目的:避免问题活动产生。

(2)风险监控

目的:提供关于风险的高低变化的指示。

监控措施举例:

  • 监控项目组成员对项目压力的态度;
  • 监控项目组的凝聚力;
  • 监控项目组成员的关系;
  • 监控与报酬和利益相关的潜在问题;
  • 监控在公司内及公司外工作的可能性。

(3)风险管理

目的:假设风险已发生,提前做好管理和应急计划。

总结:在一个项目中,RMMM 越详细越好,但同时,RMMM 步骤将导致额外的项目开销

六、风险表

1、建立风险表的步骤

1)列出所有的风险,并分类。

2)估算每个风险发生的概率。

3)评估每个风险所产生的影响,影响值分为:1=灾难性的;2=严重的;3=轻微的;4=可忽略的。

注意:根据概率和影响来进行排序:高概率、高影响的风险放在表上方。

4)形成 RMMM。

2、风险表图例

风险类别概率影响RMMM
…………………………

七、结束语

在一个软件项目中,风险分析是尤为重要的。如果前期没做好风险分析,那软件所产生的后果完全不堪设想。所以,学会做风险分析和管理,对软件能有一个更好的评估。 软件项目管理的风险分析与管理就讲到这里啦!如果有不明白或有误的地方欢迎私聊或加我微信指正~

  • 公众号:星期一研究室
  • 微信:MondayLaboratory

创作不易,如果这篇文章对你有用,记得点赞收藏哦~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/008Schedule.html b/column/Product/SoftwareEngineer/008Schedule.html index 8e2e8dee..d4bab709 100644 --- a/column/Product/SoftwareEngineer/008Schedule.html +++ b/column/Product/SoftwareEngineer/008Schedule.html @@ -19,7 +19,7 @@
Skip to content

一、项目进度安排的定义及原则

1、进度安排的定义

项目进度安排,即通过将工作量分配给特定的软件工程任务,和将所估算的工作量分布于已经计划好的项目持续时间中。

2、进度安排的基本原则

(1)划分 —— 项目被划分为若干个可管理的活动和任务

(2)相互依赖 —— 活动和任务之间的关系必须被确定为:顺序、并发、后续、独立进行;

(3)时间分配 —— 为每个任务分配工作单位(即开始和结束时间);

(4)工作量确认 —— 确保在任意时段分配到任务的人员数量不会超过项目组的人员数量;(比如:一个项目组此次预估需要有 12 人分配到任务才能完成此项工作,但原定人员数量为 10 人,那么 12>10,这项任务的工作量必然超标了,所以要确保不能超过)

(5)定义责任 —— 每个被调度的任务都应该指定负责人

(6)定义结果 —— 每个被调度的任务都要有一个定义好的输出结果

(7)定义里程碑 —— 每个任务或任务组都与一个项目里程碑相关联;

二、通信开销

1、通信开销的定义

当几个人共同承担软件开发任务时,人与人之间必须通过交流来解决各自承担任务之间的接口问题,即所谓通信问题。通信需花费时间和代价,会引起软件错误增加,降低软件生产率。

2、通信路径计算

如果一个软件开发小组有 n 个人,每两人之间都需要通信,则总的通信路径有 $\frac{n(n-1)}{2}$ 条。

如想对通信路径有进一步了解,可到项目管理中的 4P文章中的项目小组结构进行查看

3、案例分析

Q1:设一个人单独开发软件,生产率是 5000 行/人年。若 4 个人组成一个小组共同开发这个软件,则需要 6 条通信路径。若在每条通信路径上耗费的工作量是 250 行/人年。则小组中每个人的软件生产率降低为多少?

A1:小组中每个人的软件生产率降低为 5000 - $\frac{6}{4}$×250 = 5000 - 375 = 4625 行/人年,所以项目组的生产率为 18500。

Q2:如在上例中,到了开发后期再加入两名工程师,生产率为 840 行/人年,问此时项目组的生产率为?

A2:6 个人所产生的的通信路径为 $\frac{6*(6-1)}{2}$ = 15 条;所以项目组的生产率为 5000 × 4 + 840 × 2 - 15 × 250 = 17930。

从上述分析可知:

  • 一个软件任务由一个人单独开发,生产率最高;而对于一个稍大型的软件项目,一个人单独开发,时间又太长;因此软件开发小组是必要的。
  • 但是,开发小组不宜太大,成员之间要避免过多的通信路径。
  • 在开发进程中,切忌中途加人,避免不必要的的生产率损失。

三、工作量分配

1、40-20-40 规则

1)在整个软件开发过程中,编码工作量仅占 20%,编码前工作量占40%,编码后工作量占 40%

2)40-20-40 规则只应用来作为一个指南,实际的工作量分配比例必须按照各项目的特点来决定。

2、工作量分配图例

用一张图来了解关于软件各阶段的工作量分配比例。

工作量分配

3、工作量分布推荐

在实际的软件开发中,一种比较推荐的工作量分布为:

  • 计划阶段 planning -> 2-3% ;
  • 需求分析阶段 requirements analysis -> 10-25 % ;
  • 设计阶段 design -> 20-25 %;
  • 编码阶段 coding -> 15-20 % ;
  • 测试和调试阶段 testing and debugging -> 30-40 %

四、项目进度安排方法

1、关键路径方法(CPM,Critical Path Method)

(1)定义

在关键路径上的活动才是按时完成任务的关键。

(2)关键路径的相关表达

  • LS:Latest start time 最晚开始时间;
  • ES:Earliest start time 最早开始时间;
  • FT:Float Time 浮动时间;
  • 关键路径的判断:计算哪条路径最长,即为关键路径;
  • 关键路径上的节点对应的浮动时间为FT = 0,且在每个项目中,关键路径不止一条;
  • 如果关键路径上的活动开始时间推迟,将会直接影响工期;
  • 最晚开始时间 - 最早开始时间 = 浮动时间。

(3)案例分析:盖房子

表 1 盖一所房子的重要阶段

阶段完成事项
1.1完成调查
1.2签发许可证
1.3完成挖掘
1.4库存材料
2.1施工地基
2.2外墙完成
2.3外部管道完成
2.4外部电力工作完成
2.5外部壁板完成
2.6外部涂装完成
2.7安装门和一些固定设施
2.8屋顶完成
3.1内部管道完成
3.2内部电力工作完成
3.3墙板就位
3.4内部涂装完成
3.5铺设地板
3.6安装门和一些固定设施

表 2 盖房子相关活动的时间估计

具体活动估计时间(天)
Step1: 准备工作
完成调查3
签发许可证15
完成挖掘10
库存材料10
Step2: 构建外部
施工地基15
外墙完成20
外部管道完成10
外部电力工作完成10
外部壁板完成8
外部涂装完成5
安装门和一些固定设施6
屋顶完成9
Step3: 构建内部
内部管道完成12
内部电力工作完成15
墙板就位9
内部涂装完成18
铺设地板11
安装门和一些固定设施7

表 3 任务网络图

任务网络图

:某项目的活动网络图如表 3 所示,每项活动所需的天数如路径上数字所示。(1)请给出计算过程确定项目的关键路径和工期。(2)设定活动 1.1 和 1.2 的最早开始时间均为第 1 天,给出所有活动的最早开始时间 ES、最迟开始时间 LS 和浮动时间 FT。

答案解析:

(1)从图中可以看出,该项目有 8 条路径可以走到终点,分别为:

  • ①start → 1.1(3) → 1.3(10) →1.4(10) → 2.1(15) → 2.2(20) → 2.3(10) → 2.4(10) → 2.5(8) → 2.6(5) → 2.7(6) → finish;
  • ②start → 1.1(3) → 1.3(10) →1.4(10) → 2.1(15) → 2.2(20) → 2.3(10) → 2.4(10) → 2.5(8) → 2.6(5) → 2.8(9) → finish;
  • ③start → 1.1(3) → 1.3(10) →1.4(10) → 2.1(15) → 2.2(20) → 3.1(12) → 3.2(15) → 3.3(9) → 3.4(18) → finish;
  • ④start → 1.1(3) → 1.3(10) →1.4(10) → 2.1(15) → 2.2(20) → 3.1(12) → 3.2(15) → 3.3(9) → 3.5(11) → 3.6(7) → finish;
  • ⑤start → 1.2(15) → 1.3(10) →1.4(10) → 2.1(15) → 2.2(20) → 2.3(10) → 2.4(10) → 2.5(8) → 2.6(5) → 2.7(6) → finish;
  • ⑥start → 1.2(15) → 1.3(10) →1.4(10) → 2.1(15) → 2.2(20) → 2.3(10) → 2.4(10) → 2.5(8) → 2.6(5) → 2.8(9) → finish;
  • ⑦start → 1.2(15) → 1.3(10) →1.4(10) → 2.1(15) → 2.2(20) → 3.1(12) → 3.2(15) → 3.3(9) → 3.4(18) → finish;
  • ⑧start → 1.2(15) → 1.3(10) →1.4(10) → 2.1(15) → 2.2(20) → 3.1(12) → 3.2(15) → 3.3(9) → 3.5(11) → 3.6(7) → finish。

8 条路径如下图所示:

路径展示

可以计算出,每条路径的工期分别为:

  • ①3+10+10+15+20+10+10+8+5+6=97 天;

  • ②3+10+10+15+20+10+10+8+5+9=100 天;

  • ③3+10+10+15+20+12+15+9+18=112 天;

  • ④3+10+10+15+20+12+15+9+11+7=112 天;

  • ⑤15+10+10+15+20+10+10+8+5+6=109 天;

  • ⑥15+10+10+15+20+10+10+8+5+9=112 天;

  • ⑦15+10+10+15+20+12+15+9+18=124 天;

  • ⑧15+10+10+15+20+12+15+9+11+7=124 天。

综上所述,项目的关键路径有两条,分别为⑦ 和 ⑧,即 1.2 → 1.3 →1.4 → 2.1 → 2.2 → 3.1 → 3.2 → 3.3 → 3.4 和 1.2 → 1.3 →1.4 → 2.1 → 2.2 → 3.1 → 3.2 → 3.3 → 3.5 → 3.6,工期为 124 天。

(2)计算步骤如下:

填充关键路径的浮动时间。已知关键路径的浮动时间都为 0,所以路径 ⑦ 和 ⑧ 上的所有节点的浮动时间都为 0;

计算剩余节点的浮动时间。

  • 由图可得,1.1 → 1.3 需要时间为 13 天,而关键路径 1.2 → 1.3 需要 25 天,所以 1.1 的浮动时间为 12 天;
  • 关键路径的前半部分为 1.2 → 1.3 →1.4 → 2.1 → 2.2,后半部分有 4 个分路,⑦ 和 ⑧ 为关键路径,且后半部分的工期为 54 天;(12+15+9+18=54 天,12+15+9+11+7=54 天)
  • ⑤ 和 ⑥ 的后半部分与关键路径的差额分别为 54-39=15 天,54-42=12 天,那么此时可以确定 2.7 的浮动时间为 15 天,2.8 的浮动时间为 12 天;(10+8+5+6=39 天,10+8+5+9=42 天)
  • 由图可知,2.7 和 2.8 都需要经过 2.3 → 2.4 → 2.5 → 2.6,在这种情况下,选择与关键路径差额小的值为浮动时间,即 2.3 → 2.4 → 2.5 → 2.6 与 2.8 的浮动时间相等。

计算最早开始时间。将每一项活动前面经过的路径(不包含当前活动)进行相加,如遇到分叉口则选择有经过关键路径上的节点

计算最迟开始时间。逆推,通过公式最晚开始时间 - 最早开始时间 = 浮动时间推出最迟开始时间。

项目活动的最早开始时间 ES、最迟开始时间 LS 和浮动时间 FT 如下:

活动最早开始时间最晚开始时间浮动时间
1.111312
1.2110
1.316160
1.426260
2.136360
2.251510
2.3718312
2.4819312
2.59110312
2.69911112
2.710411915
2.810411612
3.171710
3.283830
3.398980
3.41071070
3.51071070
3.61181180
Finish1241240

由上述案例可以得出,通过关键路径可以判断出:

  • 开发时哪些活动必须等待;
  • 开发时哪些活动必须按进度进行防止拖延问题发生。

2、项目(进度计划)评估和评审技术(PERT,Program Evaluation and Preview Technique)

(1)定义

项目评估和评审技术是一种关键路径分析技术,使用正态分布来判断一个活动的最早开始时间接近该活动进度时间的概率。PERT 技术可以计算关键路径、找出最可能成为瓶颈的活动。

注:项目评估和评审技术 (PERT) 的内容比关键路径还更为复杂一点,大家可以先理解关键路径,待我后面深学了再补充这一块知识。或者有小伙伴想补充的也欢迎私聊我哦~

五、获得值分析

获得值分析,主要分析两个内容进度是否拖延;成本是否超出预算。基于这两个内容,对获得值分析进行以下阐述。

1、基本量

(1)计划工作的预计成本(BCWS):截止到某一时刻,计划工作的预计工作量之和。

(2)完成预算(BAC): BCWS 的总量,是项目的总工作量的估计。

(3)预定完成百分比:计划工作的预计成本占预计总工作量的百分比,计算公式为: $\frac{BCWS}{BAC}$。

(4)完成工作的预计成本(BCWP):截止到某一时刻,完成工作的预计工作量之和。

(5)完成百分比:完成工作的预计成本占预计总工作量的百分比,计算公式为: $\frac{BCWP}{BAC}$。

(6)所完成工作的实际成本(ACWP):截止到某一时刻,已完成的工作任务的实际工作量之和。

2、进度指示计算公式

(1)进度性能指标(SPI) = $\frac{BCWP}{BCWS}$;

(2)进度偏差(SV) = BCWP - BCWS;

(3)成本性能指标(CPI) = $\frac{BCWP}{ACWP}$;

(4)成本偏差(CV) = BCWP - ACWP。

总结:

  • 当 SPI > 1,SV > 0,进度超前;
  • 当 SPI = 1,SV = 0,进度正好;
  • 当 SPI < 1,SV < 0,进度落后;
  • 当 CPI > 1,CV > 0,成本节省;
  • 当 CPI = 1,CV = 0,成本正好;
  • 当 CPI < 1,CV < 0,成本超出预算。

3、案例分析

(1)案例一

下图是某工程的实际完成表。

工作任务估计工作量实际工作量估计完成日期实际完成日期(月日年)
15101/25/212/1/21
225202/15/212/15/21
3120802/25/21
440504/15/214/1/21
560507/1/21
680709/1/21

Question:在该工程实施过程中,截止到 21 年 4 月 1 号,进度是否拖延?工期是否超出预算?

Answer:

截止到 21 年 4 月 1 号,计划完成任务 1、2,实际完成了 1、2、4,由此可计算出 BCWSBCWPACWPBAC 的值。

  • 计划工作的预计成本 BCWS 为:5 + 25 = 30

  • 完成工作的预计成本 BCWP 为:5 + 25 + 40 = 70

  • 所完成工作的实际成本 ACWP 为:10 + 20 + 50 = 80

  • 完成预算 BAC 为:5 + 25 + 120 + 40 + 60 + 80 = 330

  • 那么预定完成百分比为: $\frac{BCWS}{BAC} = \frac{30}{330}$

  • 实际完成百分比为:$\frac{BCWP}{BAC} = \frac{70}{330}$

  • 进度性能指标 SPI 为: $SPI = \frac{BCWP}{BCWS} = \frac{70}{30} > 1$

  • 进度偏差 SV 为:$SV = BCWP - BCWS = 70 - 30 = 40 > 0$

  • 成本性能指标 CPI 为: $CPI = \frac{BCWP}{ACWP} = \frac{70}{80} < 1$

  • 成本偏差 CV 为:$CV = BCWP - ACWP = 70 - 80 = -10 < 0$

综上所述,因为 SPI > 1,SV > 0CPI < 1,CV < 0 ,所以截止到 21 年 4 月 1 日,该工程进度超前,成本超出预算。

(2)案例二

工作任务估计工作量实际工作量估计完成日期实际完成日期(月日年)
150701/25/212/1/21
235202/15/212/15/21
320405/15/213/1/21
440404/15/214/1/21
560106/1/21
680207/1/21

Question:若考察点在 21 年 5 月 1 日,此时任务完成进度如上图所示,问进度是否拖延?工期是否超出预算?

Answer:

截止到 21 年 5 月 1 号,计划完成任务 1、2、3、4,实际完成了 1、2、3、4,由此可计算出 BCWSBCWPACWPBAC 的值。

  • 计划工作的预计成本 BCWS 为:50 + 35 + 20 + 40 = 145

  • 完成工作的预计成本 BCWP 为:50 + 35 + 20 + 40 = 145

  • 所完成工作的实际成本 ACWP 为:70 + 20 + 40 + 40 = 170

  • 完成预算 BAC 为:50 + 35 + 20 + 40 + 60 + 80 = 285

  • 那么预定完成百分比为: $\frac{BCWS}{BAC} = \frac{145}{285}$

  • 实际完成百分比为:$\frac{BCWP}{BAC} = \frac{145}{285}$

  • 进度性能指标 SPI 为: $SPI = \frac{BCWP}{BCWS} = \frac{145}{145} = 1$

  • 进度偏差 SV 为:$SV = BCWP - BCWS = 145 - 145 = 0$

  • 成本性能指标 CPI 为: $CPI = \frac{BCWP}{ACWP} = \frac{145}{170} < 1$

  • 成本偏差 CV 为:$CV = BCWP - ACWP = 145 - 170 = -25 < 0$

综上所述,因为 SPI = 1,SV = 0CPI < 1,CV < 0 ,所以截止到 21 年 4 月 1 日,该工程进度正好,即项目按计划进行,但成本超出预算。

(3)案例三

Question:

你被指定负责一个软件项目,这个项目由4个部分(A、B、C、D)组成,项目总预算为 53000 元,其中A任务预算为 26000 元,B任务预算为 12000 元,C 任务预算为 10000 元,D 任务预算为 5000 元。

截止到 8 月 31 日,A任务已经全部完成,B任务过半,C任务刚开始,D任务还没有开始,下表给出截止到 8 月 31 日的计划成本和实际成本,采用 50/50 规则计算截止到 8 月 31 日为止的 CVSVCPISPI

任务计划费用 BCWS(元)实际花费 ACWP(元)已获取价值 BCWP(元)
A260002550026000
B900054006000
C480041005000
D000
总计398003500037000

(备注:50/50 规则指项目一开始就实现一半价值,直到结束才实现全部价值,即完成 1%或 99%,都认为只实现一半价值)

Answer:

截止到 8 月 31 日为止的 CV , SV , CPI , SPI 的计算结果如下:

  • $BCWS = 39800元$
  • $ACWP = 35000元$
  • $BCWP = 37000元$
  • $SPI = \frac{BCWP}{BCWS}$ = 93%
  • $SV = BCWP-BCWS = -2800元$
  • $CPI = \frac{BCWP }{ACWP}$ = 106%
  • $CV = BCWP - ACWP = 2000元$

综上所述,因为 SPI < 1,SV < 0CPI > 1,CV > 0 ,所以截止到 8 月 31 日,该工程进度落后一些,但是费用节省了。

六、写在最后

软件项目进度安排与跟踪的文章就讲解到这里啦!在这一块内容中,计算关键路径部分尤为重要,也是软考当中的常考题。在学会之后还要自己脱稿再演算多遍,且可以将题目举一反三进行多次计算。如果有不理解的欢迎私聊~

同时,如有需要了解软件工程相关的其他内容,可到『软件工程』栏目进行查看学习~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/009StructuredAnalysis.html b/column/Product/SoftwareEngineer/009StructuredAnalysis.html index 3840473b..9de71aa2 100644 --- a/column/Product/SoftwareEngineer/009StructuredAnalysis.html +++ b/column/Product/SoftwareEngineer/009StructuredAnalysis.html @@ -37,7 +37,7 @@ 发批准书,发货单及赊欠报告 else //(欠款未超期) 发批准书,发货单

(4)判定表 (Data Flow Diagram, DFD)

1)使用条件

如果数据流图的加工需要依赖于多个逻辑条件的取值,使用判定表来描述比较合适。

2)图例

条件桩条件项

3)案例剖析

案例一:检查发货单

判定表-检查发货单

大家可以看到,在上图中,左上角的地方是条件,也称为条件桩。而因为条件引发的操作/动作,即左下角部分,称为动作桩。

有了条件桩和动作桩以后,它们有一一对应的数据。条件桩对应条件项,动作桩对应动作项,即右上角和右下角部分。

案例二:旅游预订票系统“计算折扣量”

判定表-旅游管理系统

同样的,与依据案例一的例子同样判断。上面是条件桩和条件项,下面是动作桩和动作项。

(5)判定树 (Data Flow Diagram, DFD)

1)使用条件

判定树也是用来表达加工逻辑的一种工具,有时侯它比判定表更直观

2)案例剖析

同样,我们依据判定表的两个例子来做成判定树。

案例一:检查发货单

判定树-检查发货单

案例二:旅游预订票系统“计算折扣量”

判定树-旅游管理系统

从上面两张图中可以看到,判定树相较于判定表来说会更加直观

三、动态分析方法

1、为什么需要系统动态分析方法?

2、最常用的动态分析方法

(1)状态迁移图

1)状态迁移图是什么?

状态迁移图,即 State Transition Diagram,缩写为 STD 。状态迁移图是描述系统的状态如何使外部的信号进行推移的一种图形表示。

2)状态迁移图的表示方式

3)案例剖析:CPU 进程的状态迁移

假设某个系统当前有多个状态申请占用 CPU 运行的进程, 其中 CPU 所分配进程的状态迁移如下。

状态迁移图

由上图可分析出状态迁移图,状态迁移表以及相对应的状态,如下图所示。

状态迁移相应状态表示

4)状态迁移图的优点

(2)时序图

1)时序图是什么?

时序图 (Sequence Diagram) ,又名序列图、循序图,是一种 UML 交互图。它通过描述对象之间发送消息的时间顺序来显示多个对象之间的动态协作。

2)案例剖析:功能事件

在下图中, 对于事件 e , 功能1~功能3 的处理时间总计为 (T1+T2+T3) ,其中功能间切换时间为 0

功能事件

3)案例剖析:进程间的通信流

在下图中,采用扩充时序图可表示进程间的通信流,用于分析几个事件的交错现象。 C1C2R1R2 是交错的。因此,可以做如下分析:“ HOST1 在等待 C1 的回答时(即 R1 期间),要能接收从 HOST2 发出的命令 C2 。”

进程间的通信流

四、写在最后

对于软件工程中的结构化系统分析来说,主要解决软件“做什么”的问题。特别是关于数据流图和数据字典的内容较多,学完要多消化总结。同时我也将在下一篇文章讲解关于数据流图与数据字典的一些案例分析。

关于软件工程的结构化系统分析就讲到这里啦!如有需要了解软件工程相关的其他内容,可到『软件工程』栏目进行查看学习~

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/010DataFlowDiagram.html b/column/Product/SoftwareEngineer/010DataFlowDiagram.html index e1a4a4f1..7fc02ace 100644 --- a/column/Product/SoftwareEngineer/010DataFlowDiagram.html +++ b/column/Product/SoftwareEngineer/010DataFlowDiagram.html @@ -19,7 +19,7 @@
Skip to content

前言

上一篇文章的内容,我们挑选出几个案例来对数据流图和数据字典进行分析。

一、数据流图案例分析

1、案例 1:商店业务管理系统

(1)某商店业务管理系统的顶层数据流图如下:

商店业务管理系统

以上数据流图只是一个高层的系统逻辑模型,它反映了目标系统要实现的功能。

(2)该管理系统的数据流图绘制步骤为:

  • 首先确定系统的输入输出
  • 根据商店的业务,画出顶层数据流图,以反映最主要业务的处理流程;
  • 经过分析,商店业务处理的主要功能应当有销售采购会计三大项。主要数据流的
  • 然后从输入端开始,根据商店业务的工作流程,画出数据流流经的各个加工框,逐步画到输出端,得到第 0 层数据流图

(3)根据步骤分别画出第 0 层和第 1 层数据流图。具体图形如下:

  • 第 0 层数据流图如下图所示:

第0层数据流图

  • 细化第 0 层数据流图的每一个加工项,得到第 1 层数据流图,其中包括销售采购会计三大项功能。具体数据流图如下:

第1层数据流图—销售细化

第1层数据流图—采购细化

第1层数据流图—会计细化

2、案例 2:学籍管理系统

(1)某学籍管理系统的顶层数据流图如下:

学籍管理系统顶层流程图

(2)该管理系统的数据流图绘制步骤为:

  • 首先确定系统的输入输出
  • 根据学籍管理系统的业务,画出顶层数据流图,以反映最主要业务的处理流程;
  • 经过分析,据学籍管理系统的主要功能应当有注册成绩管理资格管理奖励管理四大项。主要数据流的
  • 然后从输入端开始,根据学籍管理系统相关业务的工作流程,画出数据流流经的各个加工框,逐步画到输出端,得到第 0 层数据流图

(3)根据步骤画出第 0 层数据流图。具体图形如下:

  • 第 0 层数据流图如下图所示:

学籍管理系统第0层流程图

3、案例 3:大型企业数据中心

某大型企业的数据中心为了集中管理、控制用户对数据的访问并支持大量的连接需求,欲构建数据管理中间件,其主要功能如下:

(1)数据管理员可通过中间件进行用户管理、操作管理和权限管理用户管理维护用户信息(用户名、密码),存储在中;操作管理维护数据实体的标准操作及其所属的后端数据库信息,存放在中;权限管理维护,该表存储用户可执行的操作信息。

(2)中间件验证前端应用提供的用户信息。若验证不通过,返回非法用户信息;若验证通过,中间件将等待前端应用提交操作请求。

(3)前端应用提交操作请求后,中间件先对请求进行格式检查。如果格式不正确,返回格式错误信息;如果格式正确,则进行权限验证(验证用户是否有权执行请求的操作),若用户无权执行该操作,则返回权限不足信息,否则进行连接管理

(4)连接管理连接相应的后端数据库并提交操作。连接管理先检查是否存在空闲的数据库连接,如果不存在,新建连接;如果存在,则重用连接

(5)后端数据库执行操作并将结果传输给中间件,中间件对收到的操作结果进行处理后,将其返回给前端应用。

现采用结构化方法对系统进行分析与设计,获得如下图所示的顶层数据流图0 层数据流图

数据管理中间件顶层数据流图

数据管理中间件0层数据流图

回答以下问题:

  1. E1、 E2 和 E3 分别指哪三个实体?E1:前端应用;E2:数据管理层;E3:后端数据库。
  2. D1 、D2 和 D3 分别指哪三个数据存储?D1:用户表;D2:操作表;D3:权限表。
  3. 加工 P 指什么?并指出 0 层数据流图丢失的两条数据流,包括数据流的起点、终点及数据流名称。 加工 p 表示数据管理中间件。0 层数据流图丢失的两条数据如 4 和 5 所示。
  4. 丢失的数据流 1 中,其起点、终点和名称分别是什么。→ 起点为P,终点为E1,名称为处理后的操作结果
  5. 丢失的数据流 2 中,其起点、终点和名称分别是什么。→ 起点为E3,终点为P,名称为操作结果

二、数据字典案例分析

1、案例 1:学籍管理系统

某学籍管理系统的第 0 层数据流图如下所示。

学籍管理系统第0层流程图

Question: 根据以上第 0 层数据流图,请写出该学籍管理系统的五个条目。

Answer:

条目一:数据流

条目一:数据流

条目二:数据元素

条目二:数据元素

条目三:数据存储

条目三:数据存储

条目四:数据加工

条目四:数据加工

条目五:外部项

条目五:外部项

三、写在最后

关于数据流图和数据字典的案例分析就讲到这里啦!大家可以根据上一篇文章和这一篇文章连在一起结合学习。如有需要了解软件工程相关的其他内容,可到『软件工程』栏目进行查看学习~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/011StructuredDesign.html b/column/Product/SoftwareEngineer/011StructuredDesign.html index b75aa92c..b19c6005 100644 --- a/column/Product/SoftwareEngineer/011StructuredDesign.html +++ b/column/Product/SoftwareEngineer/011StructuredDesign.html @@ -115,7 +115,7 @@ dictionary := merge dictionary and good word list END spellcheck

七、界面设计

界面设计也称为接口设计,需了解3 条黄金规则:

八、写在最后

从结构化系统分析到结构化系统设计,我们解决了 从软件“做什么”到软件“怎么做” 的问题。相信大家对结构化系统设计的内容也有了一个新的了解🙋

结构化系统设计的内容就讲到这里啦!如有需要了解软件工程相关的其他内容,可到『软件工程』栏目进行查看学习~

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/012SoftwareTest.html b/column/Product/SoftwareEngineer/012SoftwareTest.html index ced26921..4cf4ced9 100644 --- a/column/Product/SoftwareEngineer/012SoftwareTest.html +++ b/column/Product/SoftwareEngineer/012SoftwareTest.html @@ -19,7 +19,7 @@
Skip to content

前言

在一项系统软件完成之后,且在上线之前,需要经过不断的软件测试,找出 bug 和错误,不断修补,才能正式上线。在下面的这篇文章中,将讲解软件测试的一些基础知识以及测试用例的设计和软件测试的步骤。

接下来开始进行讲解。

一、软件测试概述

1、软件测试的目的

(1)从用户和开发者角度

基于不同的立场,存在着两种完全不同的测试目的:

  • 从用户的角度出发,普遍希望通过软件测试暴露软件中隐藏的错误和缺陷,以考虑是否可接受该产品。

  • 从软件开发者的角度出发,则希望测试表明软件产品中不存在错误的过程,验证该软件已正确地实现了用户的要求,树立人们对软件质量的信心。

(2)Myers 软件测试目的

  • 测试是程序的执行过程,目的在于发现错误;

  • 一个好的测试用例在于能发现至今未发现的错误

  • 一个成功的测试是发现了至今未发现的错误的测试

总结来说就是,测试的目的是想以最少的时间和人力,系统地找出软件中潜在的各种错误和缺陷。如果我们成功地实施了测试,我们就能够发现软件中的错误。测试的附带收获是,它能够证明软件的功能和性能与需求说明相符合。实施测试收集到的测试结果数据为可靠性分析提供了依据。

2、软件测试的原则

  • 应当把“尽早地和不断地进行软件测试”作为软件开发者的座右铭。
  • 测试用例应由测试输入数据对应的预期输出结果这两部分组成。
  • 程序员应避免检查自己的程序
  • 在设计测试用例时,应包括合理的输入条件不合理的输入条件
  • 充分注意测试中的群集现象。经验表明,测试后程序中残存的错误数目与该程序中已发现的错误数目成正比。
  • 严格执行测试计划,排除测试的随意性。
  • 应当对每一个测试结果做全面检查。
  • 妥善保存测试计划,测试用例,出错统计和最终分析报告,为维护提供方便。

3、软件测试的对象

软件测试并不等于程序测试。软件测试应贯穿于软件定义与开发的整个期间。

需求规格说明、概要设计规格说明、详细设计规格说明以及源程序,都应成为软件测试的对象。

简单来说,就是程序、数据和文档都应该成为测试对象。

4、测试信息流

测试信息的步骤:

  • 软件配置(对象):软件需求规格说明、软件设计规格说明、源代码等;
  • 测试配置(方法):测试计划、测试用例、测试程序等;
  • 测试工具:测试数据自动生成程序、静态分析程序、动态分析程序、测试结果分析程序、以及驱动测试的测试数据库等等。
  • 测试结果分析:比较实测结果与预期结果,评价错误是否发生。
  • 排错(调试):对已经发现的错误进行错误定位和确定出错性质,并改正这些错误,同时修改相关的文档。
  • 修正后的文档再测试:直到通过测试为止。

得出结论:

通过收集和分析测试结果数据,对软件建立可靠性模型。

利用可靠性分析,评价软件质量。

如果测试发现不了错误,可以肯定,测试配置考虑得不够细致充分,错误仍然潜伏在软件中。

测试信息流

5、测试与软件开发各阶段的关系

(1)软件开发过程是一个自顶向下逐步细化的过程,主要有以下步骤:

  • 软件计划阶段定义软件作用域。
  • 软件需求分析阶段建立软件信息域、功能和性能需求、约束等。
  • 软件设计。
  • 把设计用某种程序设计语言转换成程序代码。

(2)而测试过程是按照相反顺序安排的自底向上逐步集成的过程。

测试过程

二、软件测试用例

1、黑盒测试概述

测试对象看做一个黑盒子,测试人员完全不考虑程序内部的逻辑结构和内部特性,只依据需求规格说明来检查程序的功能是否符合。

黑盒测试又叫做功能测试数据驱动测试

黑盒测试方法是在程序接口上进行测试,主要是为了发现以下错误:

  • 是否有不正确或遗漏了的功能?

  • 在接口上,输入能否正确地接受? 能否输出正确的结果?

  • 是否有数据文件访问错误?

  • 性能上是否能够满足要求?

用黑盒测试发现程序中的错误,必须在所有可能的输入条件和输出条件中确定测试数据,来检查程序是否都能产生正确的输出。

但这是不可能发生的事情。为什么呢?

假设一个程序 P 有输入量 X 和 Y 及输出量 Z。在字长为 32 位的计算机上运行。若 X、Y 取整数,按照黑盒测试方法进行穷举测试

可能采用的测试数据组:232 x 232 = 264。

如果测试一组数据需要 1 毫秒,一年工作365× 24小时,完成所有测试需5 亿年

5 亿年!想想都不太可能。所以说,程序一般没有办法引入穷举测试。

2、白盒测试概述

把测试对象看做一个透明的盒子,它允许测试人员利用程序内部的逻辑结构设计测试用例,对程序所有逻辑路径进行测试。

通过在不同点检查程序的状态,确定实际的状态是否与预期的状态一致

因此白盒测试又称为结构测试逻辑驱动测试

白盒测试方法,主要对程序模块作出以下检查:

  • 对程序模块的所有独立的执行路径至少测试一次;
  • 所有的逻辑判定,取“”与取“”的两种情况都至少测试一次;
  • 在循环的边界和运行界限内执行循环体;
  • 测试内部数据结构的有效性等等。

对一个具有多重选择和循环嵌套的程序,不同的路径数目可能是天文数字。给出一个小程序的流程图,它包括了一个执行20 次的循环。

包含的不同执行路径数达520条,对每一条路径进行测试需要1 毫秒,假定一年工作365 × 24小时,要想把所有路径测试完,需 3170 年。

比起穷举测试的 5 亿年,3170 年似乎少了不少。但是呢?3170 年会不会也挺太漫长的。

因此,我们要引入一些黑白盒测试方法来解决这些问题。

3、白盒测试方法

白盒测试方法主要有以下 6 种方法:

  • 语句覆盖
  • 判定覆盖
  • 条件覆盖
  • 判定-条件覆盖
  • 条件组合覆盖
  • 路径覆盖

白盒测试方法这里篇幅较长,放在另外一篇文章中,有需要的小伙伴自取~

4、条件测试路径选择

当程序中的判定条件超过一个时,形成的分支结构可以分为两类:嵌套型分支结构连锁型分支结构

对于嵌套型分支结构,若有 n 个判定语句,需要 n+1 个测试用例;

对于连锁型分支结构, 若有 n 个判定语句,需要有 2n 个测试用例,覆盖它的 2n 条路径。

如下图所示:

嵌套型和连锁型分支结构

5、循环测试路径选择

循环分为 4 种不同类型:简单循环连锁循环嵌套循环非结构循环。如下图所示:

循环测试路径选择

接下来对这四种循环进行一一介绍。

(1)简单循环

① 零次循环: 从循环入口到出口。

② 一次循环: 检查循环初始值。

③ 二次循环: 检查多次循环。

④m 次循环: 检查在多次循环。

⑤ 最大次数循环: 比最大次数多一次、少一次的循环。

(2)嵌套循环

对最内层循环做简单循环的全部测试。所有其它层的循环变量置为最小值

② 逐步外推,对其外面一层循环进行测试。测试时保持所有外层循环的循环变量取最小值,所有其它嵌套内层循环的循环变量取“典型”值。

③ 反复进行,直到所有各层循环测试完毕。

对全部各层循环同时取最小循环次数,或者同时取最大循环次数

(3)连锁循环

如果各个循环互相独立,则可以用与简单循环相同的方法进行测试。但如果几个循环不是互相独立的,则需要使用测试嵌套循环的办法来处理。

(4)非结构循环

这一类循环应该使用结构化程序设计方法重新设计测试用例。

6、基本路径测试

基本路径测试法也已经放到白盒测试方法文章当中,有需要的小伙伴自取~

7、黑盒测试的测试用例设计

黑盒测试方法主要有以下 8 种方法:

  • 等价类划分法
  • 边界值分析法
  • 错误推测法
  • 因果图法
  • 判定表驱动法
  • 正交实验设计法
  • 场景法
  • 功能图法

黑盒测试方法篇幅较长,已放在另外一篇文章中,有需要的小伙伴自行查阅~

三、软件测试步骤

测试过程需要按照 4 个步骤进行,分别是单元测试(模块)组装测试(集成)确认测试系统测试详细过程如下:

  • 开始是单元测试,集中对使用源代码实现的每一个程序单元进行测试,检查各个程序模块是否正确地实现了规定的功能。

  • 组装测试已测试过的模块组装起来,主要对与设计相关的软件体系结构的构造进行测试。

  • 确认测试则是要检查已实现的软件是否满足了需求规格说明中已经确定的各种需求,以及软件配置是否完全、正确。

  • 系统测试把已经经过确认的软件纳入实际运行环境中,与其它系统成份地组合在一起进行测试。

    软件测试的步骤

以下将对这四个测试步骤进行一一讲解。

1、单元测试

(1)单元测试的定义

单元测试又称模块测试,是针对软件设计的最小单位 —— 程序模块,进行正确性检验的测试工作。其目的在于发现各模块内部可能存在的各种差错。

单元测试需要从程序的内部结构出发设计测试用例。多个模块可以平行地独立进行单元测试。

(2)单元测试的内容

在单元测试时,测试者需要依据详细设计说明书和源程序清单,了解该模块的 I/O 条件和模块的逻辑结构,主要采用白盒测试的测试用例,辅之以黑盒测试的测试用例,使之对任何合理的输入和不合理的输入,都能鉴别和响应。

如下图所示:

单元测试的内容

下面对这五个测试内容进行一一讲解。

1)模块接口测试

在单元测试的开始,应该对通过被测模块的数据流进行测试。测试项目包括:

  • 调用本模块的输入参数是否正确;
  • 本模块调用子模块时输入给子模块的参数是否正确;
  • 全局量的定义在各模块中是否一致;

在做内外存交换时要考虑:

  • 文件属性是否正确;

  • OPENCLOSE 语句是否正确;

  • 缓冲区容量与记录长度是否匹配;

  • 在进行读写操作之前是否打开了文件;

  • 在结束文件处理时是否关闭了文件;

  • 正文书写/输入错误,

  • I/O 错误是否检查并做了处理。

2)局部数据结构测试

  • 不正确或不一致的数据类型说明;
  • 使用尚未赋值或尚未初始化的变量;
  • 错误的初始值或错误的缺省值;
  • 变量名拼写错或书写错;
  • 不一致的数据类型;
  • 全局数据对模块的影响。

3)路径测试

  • 选择适当的测试用例,对模块中重要的执行路径进行测试;
  • 应当设计测试用例来查找因错误的计算不正确的比较不正常的控制流而导致的错误;
  • 基本执行路径和循环进行测试,可以发现到大量的路径错误。

4) 错误处理测试

  • 出错的描述是否难以理解;
  • 出错的描述是否能够与具体错误相定位;
  • 显示的错误与实际的错误是否相符;
  • 对错误条件的处理正确与否;
  • 在对错误进行处理之前,错误条件是否已经引起系统的干预等。

5) 边界测试

  • 注意数据流控制流中刚好等于、大于或小于确定的比较值时出错的可能性;
  • 对这些地方要仔细地选择测试用例,认真加以测试;
  • 如果对模块运行时间有要求的话,还要专门进行关键路径测试,以确定最坏情况下正常情况下影响模块运行时间的因素。

(3)单元测试的步骤

模块并不是一个独立的程序,因此,在考虑测试模块时,同时要考虑它和外界的联系,用一些辅助模块去模拟与被测模块相联系的其它模块。其中,辅助模块包括:

  • 驱动模块 (driver);
  • 桩模块 (stub) —— 存根模块。

依据驱动模块和桩模块,单元测试的步骤如下图所示:

单元测试的步骤

如果一个模块要完成多种功能,可以将这个模块看成是由几个小的程序组成。必须对其中的每个小的程序先进行单元测试所需要做的工作,对关键模块还要做性能测试

对支持某些标准规定的程序,更要着手进行互联测试。有人把这种情况特别称为模块测试,以区别单元测试

2、组装测试

(1)组装测试的什么

组装测试 ,也称为集成测试联合测试

(2)组装测试需考虑问题

通常,在单元测试的基础上,需要将所有模块按照设计的要求组装成为系统。这时需要考虑的问题是:

  • 在把各个模块连接起来的时侯,穿越模块接口的数据是否会丢失;

  • 一个模块的功能是否会对另一个模块的功能产生不利的影响;

  • 各个子功能组合起来,能否达到预期要求的父功能;

  • 全局数据结构是否有问题;

  • 单个模块的误差累积起来,是否会放大,从而达到不能接受的程度。

  • 在单元测试的同时可进行组装测试,发现并排除在模块连接中可能出现的问题,最终构成要求的软件系统。

  • 子系统的组装测试特别称为部件测试,它所做的工作是要找出组装后的子系统与系统需求规格说明之间的不一致。

  • 通常,把模块组装成为系统的方式有两种:

    • 一次性组装方式
    • 增殖式组装方式

3、确认测试

(1)确认测试是什么

确认测试又称有效性测试

任务是验证软件的功能和性能和其它特性是否与用户的要求一致。

在软件的需求规格说明书中明确规定软件的功能和性能要求。

它包含的信息就是软件确认测试的基础。

如下图所示:

确认测试

(2)确认测试的步骤

  • 进行有效性测试(黑盒测试);
  • 软件配置复查;
  • α 测试和 β 测试;
  • 验收测试 (Acceptance Testing)

4、系统测试

(1)系统测试是什么

将通过确认测试的软件,作为整个基于计算机系统的一个元素,与计算机硬件、外设、某些支持软件、数据和人员等其它系统元素结合在一起

在实际运行环境下,对计算机系统进行一系列的组装测试确认测试

四、写在最后

🙋🙋🙋

在软件工程实践中,也有软件测试这一步骤。但相较于软件测试这一整个大体系而言,软件测试在软件工程中所占的比例较小,个人认为掌握部分基础的内容即可。如有需要学习软件测试的其他内容,也可以到『软件测试』专栏中进行查看~

软件工程实践方法中的软件测试讲到这里就结束啦!如有需要了解软件工程相关的其他内容,可到『软件工程』栏目进行查看学习~

同时,有不理解或有误的地方也欢迎评论区评论或私信我交流~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/013UML.html b/column/Product/SoftwareEngineer/013UML.html index d012ba65..3a72fc4b 100644 --- a/column/Product/SoftwareEngineer/013UML.html +++ b/column/Product/SoftwareEngineer/013UML.html @@ -19,7 +19,7 @@
Skip to content

前言

在下面的这篇文章中,将讲解我们平常常用的一种面向对象的画图方法,即统一建模语言UML(Unified Modeling Language)。

接下来开始进行讲解。

一、UML 的含义

  • 标准的建模语言(具有语言的规范)
  • 促进沟通(各种图示表达规范)
  • 支持系统构建(正向工程,反向工程)

二、UML 的主要内容

1、UML 的概念模型

UML 具有一个完整的概念模型,提供了一套完整、全面的表达方法,其主要元素包括:①UML 的基本构造块支配这些构造块如何放在一起的规则一些运用于整个 UML 的公共机制

2、UML 概念模型图例

思维导图

下面依据概念模型中的这三大类进行一一讲解。

三、UML 的基本构造块

在 UML 中可以将词汇划分为 3 中构造块,即 3 类词汇或基本元素:事物、关系和图。

1、UML 中的事物

(1)UML 中的四种事物

事物是对模型中最具有代表性的成分的抽象,可分为结构事物行为事物分组事物注释事物

1)结构事物

通常是模型的静态部分,描述概念的物理元素。主要有以下五种结构事物:

  • (class) :与面向对象方法中类的概念一致。
  • 接口 (interface) :描述了一个类或构件的一个服务的操作集。
  • 用例 (use case) :代表了一个系统功能,是对一组动作序列的描述,系统执行这些动作将产生一个对特定的参与者(即系统用户)有价值而且可观察的结果。
  • 构件 (component) :描述的是系统中的软件物理事物。
  • 节点 (node) :是在运行时存在的物理元素,表示了一种可计算的资源。

2)行为事物

行为事物主要有:状态、交互。

3)分组事物

分组事物主要有:包。

4)注释事物

注释事物主要有:注解。

(2)UML 中各种事物的图示法

依据上面对四种事物的描述,下面给出 UML 中各种事物的图示。

UML中各种事物的图示法

2、UML 中的四种关系

UML 中的四种关系是:依赖、关联、泛化、实现。

(1)依赖

两个模型元素中,有一个是独立的,一个是非独立的,独立的模型元素发生改变,会影响非独立的模型元素

用带箭头的虚线来表示依赖关系。

如图所示:

依赖关系

(2)关联

关联是一种结构化的关系,指两个模型元素有联系。双向关联用一条实线来表示。

注意:关联关系有多重度,主要有: 010..10..*1..*

如图所示:

关联关系

值得注意的是,关联中有两种特殊的关联关系:组合和聚合

如果是组合和聚合类型,则再加一个棱形符号

如下图所示:

组合

聚合

(3)泛化

一般特殊的关系,也就是继承的关系。用实线加空心三角号来表示。

如图所示:

泛化关系

(4)实现

实现关系是,一种模型元素保证另外一种模型元素的执行,该关系主要用在接口中。用一条实线来表示。

如图所示:

实现关系

讲到这里,以下再给出一张完整的图来回顾这四种关系。

四种关系

3、UML 中的图形(五大类十种图)

(1)用例图

1)用例图的定义

用例图从用户角度描述系统功能,并指出各功能的操作者。

用例图显示若干角色执行者 (actor) 以及这些角色与系统提供的用例之间的连接关系。用例图定义的是系统的功能需求

2)用例图的基本构成

  • 用例;
  • 角色;
  • 角色之间的关系(如果有,主要是泛化);
  • 角色和用例之间的关系(单向关联或双向关联);
  • 用例和用例之间的关系(包含、扩展、泛化)。

3)元素与元素之间的关系

include:

  • include(包含关系),当两个或多个用例中共用一组相同的动作,可以将其抽出来作为一个独立的子用例,供多个基用例所共享。
  • 基用例并非一个完整的用例,所以必须和子用例一起使用才够完整。
  • include 关系在用例图中使用带箭头的虚线表示(在线上标注 <<include>> ),箭头从基用例指向子用例

extend:

  • extend(扩展关系),对基用例的扩展,基用例是一个完整的用例,即使没有子用例的参与,也可以完成一个完整的功能。
  • extend 的基用例中将存在一个扩展点,只有当扩展点被激活时,子用例才会被执行。
  • extend 关系在用例图中使用带箭头的虚线表示(在线上标注 <<extend>> ),箭头从子用例指向基用例

子用例和基用例的关系:

(泛化关系)子用例将继承父用例的所有结构、行为和关系。也就是说在任何使用基用例的地方都可以用子用例来代替。

(泛化关系)在用例图中使用空心的箭头表示,箭头方向从子用例指向基用例

4)图示

用例图

(2)静态图:类图、对象图、包图

1)类图

① 定义: 类图(class diagram)描述系统所有涉及到的类以及类和类之间的关系。

② 类图的基本构成:

  • 类(类名、属性和方法);
  • 类和类之间的关系(依赖、关联、泛化、实现)。

2)对象图

① 定义: 对象图是类图的实例,几乎使用与类图完全相同的标识,但两者之间又有一定的差别,如下图例所示。

② 图例:

对象图

(3)行为图:状态图、活动图

1)状态图

① 定义: 状态图(state chart diagram)描述系统涉及到的某个对象的所有状态以及状态和状态之间转换的事件。

② 状态图的基本构成:

  • 状态(圆角矩形);
  • 状态的起点、终点;
  • 状态之间转换的事件;
  • 注解(有时会有)。

③ 图例:

状态图

2)活动图

① 定义: 活动图(activity diagram)描述满足用例功能需求所要进行的活动以及活动间的约束关系。

② 活动图的基本构成:

  • 活动(注意符号与状态不同);
  • 活动的起点、终点(终点有时有多个);
  • 活动之间用箭头连接;
  • 判定(有时会有,棱型框);
  • 同步条(表示活动的分叉或汇合,包括水平、垂直两种);
  • 泳道(表示活动的不同职责)。

③ 图例:

活动图

(4)交互图:顺序图、协作图

1)顺序图

① 定义: 顺序图显示对象之间的动态合作关系。。

② 顺序图的基本构成:

  • 对象;
  • 生命线(对象正下方的虚线,表示对象在一段时期内的存在) ;
  • 窄矩形条(表示对象被激活,说明对象正在执行某种操作);
  • 交互的消息(有顺序之分,消息其实就是接收对象的操作方法);
  • 注解(有时会有);
  • 可以转换成协作图。

③ 图例:

顺序图

2)协作图

① 定义: 协作图(callobaration diagram)和顺序图的作用一样,反映的也是动态协作

② 协作图的基本构成:

  • 对象;
  • 实线(对象之间的连接线,注意没有箭头) ;
  • 交互的消息(有顺序之分,消息其实就是接收对象的操作方法);
  • 注解(有时会有);
  • 可以转换成顺序图。

③ 图例:

协作图

(5)实现图:构建图、部署图

1)构件图

**① 定义:**描述代码构件的物理结构以及各构件之间的依赖关系。

② 构件图的基本构成: 构件。

③ 图例:

构件图

2)部署图

① 定义: 系统中硬件的物理体系结构。

② 部署图的基本构成:

  • 三维立方体表示部件;
  • 节点名称位于立方体上部。

③ 图例:

部署图

四、写在最后

到这里,关于软件工程的体系知识就讲解结束啦!后面将会继续更新一些实践的内容。敬请期待!

如有需要了解软件工程相关的其他内容,可到『软件工程』栏目进行查看学习~

🙋🙋🙋

同时,有不理解或有误的地方也欢迎评论区评论或私信我交流~

  • 关注公众号 星期一研究室 ,不定期分享学习干货,学习路上不迷路~
  • 如果这篇文章对你有用,记得点个赞加个关注再走哦~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareEngineer/index.html b/column/Product/SoftwareEngineer/index.html index aa9acf8f..f061e2ab 100644 --- a/column/Product/SoftwareEngineer/index.html +++ b/column/Product/SoftwareEngineer/index.html @@ -19,7 +19,7 @@
- + \ No newline at end of file diff --git a/column/Product/SoftwareTesting/001.html b/column/Product/SoftwareTesting/001.html index c1c123df..77617f7c 100644 --- a/column/Product/SoftwareTesting/001.html +++ b/column/Product/SoftwareTesting/001.html @@ -19,7 +19,7 @@
Skip to content

前言

对于一个软件来说,总会存在各种各样的软件缺陷。因此我们需要通过软件测试来检查软件中存在的各种问题。

在下面的这篇文章中,将讲解软件测试的基础知识,让我们一起来了解一下吧 🙋

一、 软件缺陷的概述

1、什么是软件缺陷

软件缺陷就是软件产品中所存在的问题,最终表现为用户所需要的功能没有完全实现,不能满足或不能全部满足用户的需求。

IEEE(电气电子工程师协会)对软件缺陷有一个标准的定义

产品内部看,软件缺陷是软件产品开发或维护过程中所存在的错误、误差等各种问题。

外部看,软件缺陷是系统所需要实现的某种功能的失效或违背。

2、软件缺陷的类型

1)软件未实现产品说明书要求的功能。

2)软件出现了产品说明书不应该出现的错误。

3)软件实现了产品说明书未提到的功能。

4)软件未实现产品说明书虽未明确提及但应该实现的功能。

5)软件难以理解、不易使用、运行缓慢——从测试员的角度看——最终用户会认为不好。

3、软件缺陷的案例

1)千年虫问题(产生约 1974 年)

2)爱国者导弹防御系统(1991 年)

3)英特尔奔腾浮点除法缺陷(1994 年)

4)“冲击波”病毒(2003 年)

5)诺基亚手机平台缺陷(2008 年)

4、软件缺陷的产生原因

  • 需求不明确
  • 软件结构复杂
  • 开发人员水平有限
  • 项目期限短
  • 使用新技术
  • 其他原因

5、软件缺陷的分类

软件缺陷的分类

6、软件缺陷的处理流程

每个公司的软件缺陷处理流程不尽相同,但是它们遵循的最基本流程是一样的,都要经过提交分配确认处理复测关闭等环节。

软件缺陷的处理流程

  • 提交:测试人员发现缺陷之后,将缺陷提交给测试组长。
  • 分配:测试组长接收到测试组员提交的缺陷之后,将其移交给开发人员。
  • 确认:开发人员接收到移交的缺陷之后,会与团队甚至测试人员一起商议,确定该缺陷是否是一个缺陷。
  • 拒绝:如果经过商议之后,缺陷不是一个真正的缺陷则拒绝处理,关闭缺陷。如果经过商议之后,确定其是一个真正的缺陷,则可以根据缺陷的严重程度或优先级等立即处理或延期处理。
  • 复测:开发人员修改好缺陷之后,测试人员重新进行测试(复测),检测缺陷是否确实已经修改。如果未被正确修改,则重新提交缺陷。
  • 关闭:测试人员重新测试之后,如果缺陷已经被正确修改,则将缺陷关闭,整个缺陷处理完成。

7、多学一招:缺陷报告(由测试人员完成)

测试人员在提交软件测试时都会按照公司规定的模板(Word、Excel、缺陷管理软件等)将缺陷的详细情况记录下来生成缺陷报告,每个公司的缺陷报告模板并不相同,但一般都会包括缺陷的编号类型严重程度优先级测试环境等,有时还会有测试人员的建议

8、常见软件缺陷管理工具

(1)Bugzilla

  • Bugzilla 是 Mozilla 公司提供的一款免费的软件缺陷管理工具
  • Bugzilla 能够建立一个完整的缺陷跟踪体系,包括缺陷跟踪记录缺陷报告处理解决情况等。
  • 使用 Bugzilla 管理软件缺陷时,测试人员可以在 Bugzilla 上提交缺陷报告,Bugzilla 会将缺陷转给相应的开发者,开发者可以使用 Bugzilla 做一个工作表,标明要做的事情的优先级时间安排跟踪记录

(2)禅道

  • 禅道是一款优秀的国产项目管理软件,它集产品管理项目管理质量管理缺陷管理文档管理组织管理事务管理于一体,是一款功能完备的项目管理软件,完美地覆盖了项目管理的核心流程
  • 禅道分为专业开源两个版本,专业版是收费软件,开源版是免费软件,对于日常的项目管理,开源版本已经足够使用

(3)JIRA

  • JIRA 是 Atlassian 公司开发的项目与实务跟踪工具,被广泛用于缺陷跟踪客户实务需求收集流程审批任务跟踪项目跟踪敏捷管理等工作领域。JIRA 配置灵活、功能全面、部署简单、扩展丰富、易用性好,是目前比较流行的基于 Java 架构的管理工具。
  • JIRA 软件有两个认可度很高的特色:第一个是Atlassian 公司对该开源项目实行免费提供缺陷跟踪服务第二个是用户在购买 JIRA 软件同时将源代码也购置进来,方便做二次开发

9、修复软件缺陷的成本

软件开发过程是使用软件工程的方法,在整个过程中,都有可能出现各种各样的软件缺陷。**随着开发时间的推移,软件缺陷修复成本呈倍数的增长。**假如早在进行分析时发现相关功能缺失,立即补上就可以了,可以说付出的代价小得几乎忽略不计。如果在发布时发现缺失某个功能,那么此时加上一个功能,相当于重新开发一样,这时的修补费用可以说高了许多。因此要尽早进行测试

二、 软件的概述

1、软件生命周期

先来了解软件生命周期的全过程

软件生命周期的全过程

下面对软件生命周期各个过程进行逐一解析

(1)问题定义:由软件开发方需求方共同讨论,主要确定软件的开发目标及其可行性

(2)需求分析:对软件需求进行更深入的分析,划分出软件需要实现的功能模块,并制作成文档(需求分析说明书)

(3)软件设计:在需求分析结果的基础上,对整个软件系统进行设计,包括系统框架设计数据库设计等。(概要设计、详细设计)

(4)软件开发:在软件设计的基础上,选择一种编程语言进行开发。

(5)软件测试:软件开发完成后对软件进行测试,以查找软件设计与软件开发过程中存在的问题并加以修正。

(6)软件维护:软件投入使用之后,可能无法满足用户的使用需求,此时就需要对软件进行维护升级以延续软件的使用寿命。软件维护是软件生命周期中持续时间最长的阶段。

2、开发过程中的角色

(1)高级经理:参与项目过程中各个关键环节的活动,关注产品开发的进度,对风险控制、资源提供做出决策。

(2)产品经理(项目经理):作为客户方公司内部交流的纽带,对项目过程进行监控,对项目的进度、质量负责。

(3)开发经理:是具体开发过程的领导者,必需由熟悉业务和开发技术的专家担任;职责是界定需求,确定适当的技术架构和体系,保证软件产品按照设计的标准开发。

(4)设计师软件蓝图设计者,可以分需求分析师、架构设计师、业务设计师三种。基本活动包括:需求分析、架构设计和功能设计,按照规范编写相应的文档。

(5)测试经理测试活动的领导者,是公司内部认定的产品质量责任人。责任是计划和组织测试人员对目标产品进行测试,发现 bug、跟踪 bug 直到解决 bug;计划和组织用户培训工作。

(6)开发人员:根据设计师的设计成果进行具体编码工作,对自己的代码进行基本的单元测试

(7)测试人员:根据测试经理的计划和测试总体方案对目标产品进行测试,编写测试用例测试代码,发现和跟踪 bug;编写用户手册;进行用户培训和教育。

(8)项目实施人员:针对工程性质的项目必需的人员配置,负责软件系统安装配置系统割接运行期间的维护工作

3、软件开发模型

(1)瀑布模型

  • 优点:检查点清晰,分工明确,有利于大型软件软件开发人员的组织管理及工具的使用与研究,可以提高开发的效率。
  • 缺点:严格按照线性执行,增加了开发风险;要求必须有产出结果,增加了开发工作量。那么,对于现代软件,各阶段之间的关系很少是线性,瀑布模型已经不适合现代软件开发。

瀑布模型

(2)快速原型模型

  • 优点:克服了需求不明确带来的风险,适用于不能预先确定需求的软件项目。
  • 缺点:原型设计较难;不利于开发人员对产品的扩展。

快速原型模型

(3)迭代模型

  • 优点:适应客户需求变更;降低了开发成本和风险。
  • 缺点:增加了集成失败风险;容易退化为“边做边改”模式,失去对整个项目的控制。

迭代模型

(4)螺旋模型

  • 优点:强调了风险分析,有助于将软件质量融入开发中;小分段构建大型软件,易于计算成本;客户参与,保证项目可控性。
  • 缺点:构建过程太过繁琐,不适合小型项目。

螺旋模型

(5)敏捷模型

  • 定义:敏捷模型以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发。

  • 特点

    • 项目被拆分成多个子项目,迭代完成,每个迭代都要经过测试。
    • 快速响应需求变更,在修改过程中,软件一直处于可用状态。
    • 不断对产品进行细微、渐进式地改进,每次改进一小部分,如果可行再逐步扩大改进范围。
    • 开发未动,测试先行。
    • 注重“人”的作用。
  • 优点:及时响应客户需求变更,不断适应新的趋势。

  • 缺点:管理相对混乱,不适合大型项目。

PS 以上内容是对软件开发模型的简要概括,如需了解软件开发模型的详细内容,请前往软件工程和过程模型

4、软件质量概述

(1)定义:软件质量是指软件产品满足基本需求及隐式需求的程度。软件产品满足基本需求是指其能满足软件开发时所规定需求的特性;其次是软件产品满足隐式需求的程度。

(2)软件质量模型:ISO/IEC 9126:1991 质量模型是最通用的一个评价软件质量的国际标准,建立在 MCCall 和 Boehm 模型基础之上,主要描述了内部质量外部质量使用质量。由6 个特性和 27 个子特性组成。

软件质量模型图如下

软件质量模型

对内部质量、外部质量和使用质量进行逐一解析

① 内部质量:针对内部质量需求被测量和评价的质量,可维护性、灵活性、可移植性、可重用性、可读性、可测试性、可理解性。

② 外部质量:使用外部度量在模拟环境中,用模拟数据测试时,所被测量和评价的质量,即在预定的系统环境中运行时可能达到的质量水平。正确性、可用性、效率、可靠性、完整性、适应性、精确性、坚固性。

③ 使用质量:在规定的使用环境下,软件产品使特定用户在达到规定目标方面的能力。有效性、生产率、安全性、满意程度等。

三、 软件测试的概述

1、软件测试的发展

软件测试的发展也经历了一个漫长的过程,其发展过程可用下图表示:

软件测试的发展

2、软件测试的定义

(1)1983 年,IEEE 给软件测试的定义:

使用人工或自动的手段来运行或测定某个软件系统的过程,其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别。

(2)1990 年,IEEE 再次给出软件测试的定义:

特定的条件下运行系统或构件,观察或记录结果,对系统的某个方面做出评价;

分析某个软件项以发现现存的和要求的条件之差别并评价此软件项的特性。

总结

  • 以上的定义都有一定的片面性。不能只对系统程序进行测试,找出系统程序中的错误,而对分析、设计等过程发生的错误视而不见。
  • 软件产品由文档、数据和程序组成,那么软件测试就是对软件开发过程中形成的文档、数据以及程序进行相关的测试

3、软件测试的目的

  • 对于软件开发来说,软件测试通过找到的问题缺陷帮助开发人员找到开发过程中存在的问题,包括软件开发的模式、工具、技术等方面存在的问题与不足,预防下次缺陷的产生。
  • 对于软件测试来说,使用最少的人力、物力、时间等找到软件中隐藏的缺陷,保证软件的质量,也为以后软件测试积累丰富的经验。
  • 对于客户需求来说,软件测试能够检验软件是否符合客户需求,对软件质量进行评估和度量,为客户评审软件提供有力的依据。

4、软件测试的分类

(1)按照测试阶段分类

  • 单元测试:验证软件单元是否符合软件需求与设计,开发人员自测。
  • 集成测试:将已经测试过的软件单元组合在一起测试它们之间的接口,用于验证软件是否满足设计需求。
  • 系统测试:将经过测试的软件在实际环境中运行,并与其他系统的成分(如数据库、硬件和操作人员等)组合在一起进行测试。
  • 验收测试:主要是对软件产品说明进行验证,逐行逐字的按照说明书的描述对软件产品进行测试,确保其符合客户的各项要求。

(2)按照测试技术分类

  • 黑盒测试:把软件(程序)当作一个有输入与输出的黑匣子,它把程序当作一个输入域到输出域的映射,只要输入的数据能输出预期的结果即可,不必关心程序内部是怎么样实现的。

黑盒测试

  • 白盒测试:测试人员了解软件程序的逻辑结构、路径与运行过程,在测试时,按照程序的执行路径得出结果。白盒测试就是把软件(程序)当作一个透明的盒子,测试人员清楚的知道从输入到输出的每一步过程。

白盒测试

总结:

相对于黑盒测试来说,白盒测试对测试人员的要求会更高一点,它要求测试人员具有一定的编程能力,而且要熟悉各种脚本语言。但是在软件公司里,黑盒测试与白盒测试并不是界限分明的,在测试一款软件时往往是黑盒测试与白盒测试相结合对软件进行完整全面的测试。

(3)按照软件质量特性分类

  • 功能测试:测试软件的功能是否满足客户的需求,包括准确性、易用性、适合性、互操作性等。
  • 性能测试:测试软件的性能是否满足客户的需求,性能测试包括负载测试、压力测试、兼容性测试、可移植性测试和健壮性测试等。

(4)按照自动化程度分类

  • 手工测试:测试人员一条一条的执行代码完成测试工作。费时费力且很难保证测试效果。
  • 自动化测试:借助脚本自动化测试工具等完成相应的测试工作,它也需要人工的参与,但是它可以将要执行的测试代码或流程写成脚本,执行脚本完成整个测试工作。

(5)按照测试项目分类

  • 界面类测试:验证软件界面是否符合客户需求
  • 安全性测试:软件遭受到没有授权的内部或外部用户的攻击或恶意破坏时如何进行处理,是否能保证软件与数据的安全。
  • 文档测试:以需求分析、软件设计、用户手册、安装手册为主,主要验证文档说明与实际软件之间是否存在差异。

(6)其他分类

  • α 测试:软件上线之前进行的版本测试。由开发人员和测试人员或者用户协助进行测试。测试人员记录使用过程中出现的错误与问题,整个测试过程是可控的
  • β 测试:软件上线之后进行的版本测试。由用户在使用过程中发现错误与问题并进行记录,然后反馈给开发人员进行修复。
  • 回归测试:对修改后的程序重新进行测试,确认原有的缺陷已经消除并且没有引入新的缺陷,这个重新测试的过程就叫作回归测试。
  • 随机测试:没有测试用例、检查列表、脚本或指令的测试,它主要是根据测试人员的经验对软件进行功能和性能抽查。

四、 软件测试与软件开发的关系

软件测试在软件开发过程中占有重要的地位,在传统的瀑布模型中,软件测试只成为其阶段性的一段工作——进行代码的测试。而现代软件工程思想将软件测试认为是贯穿整个软件生命周期,并且是保证软件质量的重要手段之一。

有些研究数据显示,在国外软件开发的工作量中,软件测试的工作量占有总工作量的 40%左右;软件开发的总费用中软件测试占有 30%-50%。对于一些高科技开发系统,软件测试占有的时间和费用可能更多更高。

1、软件测试与软件开发

软件测试在项目各个阶段的作用如下

  • 项目规划阶段:负责从单元测试到系统测试的整个测试阶段的监控。
  • 需求分析阶段:确定测试需求分析,即确定在项目中需要测试什么,同时制定系统测试计划。
  • 概要设计与详细设计阶段:制定单元测试计划和集成测试计划。
  • 编码阶段:编写相应的测试代码和测试脚本。
  • 测试阶段:执行测试并提交相应的测试报告。

软件测试与软件开发的关系如下图所示

软件测试与软件开发的关系

2、常见软件测试模型

(1)V 模型

  • 优点:将复杂的测试工作分成了目标明确的小阶段完成,具有阶段性、顺序性和依赖性,它既包含了对于源代码的底层测试也包含了对于软件需求的高层测试。
  • 缺点:只能在编码之后才能开始测试,早期的需求分析等前期工作没有涵盖其中,因此它不能发现需求分析等早期的错误,这为后期的系统测试、验收测试埋下了隐患。

V 模型流程图如下

V模型

(2)W 模型

  • 优点:测试范围不仅包括程序,还包括需求分析、软件设计等前期工作,这样有利于尽早全面的发现问题。
  • 缺点:它将软件开发过程分成需求、设计、编码、集成等一系列的串行活动,无法支持迭代、自发性等需要变更调整的项目。

W 模型流程图如下

W模型

(3)H 模型

  • 设计原理:H 模型的设计原理是将测试活动完全独立了出来,形成一个完全独立的流程,这个流程将测试准备活动测试执行活动清晰的体现出来。测试流程和其他工作流程是并发执行的,只要某一个工作流程的条件成熟就可以开始进行测试。

  • 优点

    • 开发的 H 模型揭示了软件测试除测试执行外,还有很多工作;
    • 软件测试完全独立贯穿整个生命周期,且与其他流程并发进行
    • 软件测试活动可以尽早准备尽早执行,具有很强的灵活性;
    • 软件测试可以根据被测物的不同而分层次、分阶段、分次序的执行,同时也是可以被迭代的
  • 缺点

    • 管理型要求高:由于模型很灵活,必须要定义清晰的规则和管理制度,否则测试过程将非常难以管理和控制;
    • 技能要求高:H 模型要求能够很好的定义每个迭代的规模,不能太大也不能太小
    • 测试就绪点分析困难:测试很多的时候,你并不知道测试准备到什么时候是合适的,就绪点在哪里,就绪点的标准是什么,这就对后续的测试执行的启动带来很大困难;
    • 对于整个项目组的人员要求非常高:在很好的规范制度下,大家都能高效的工作,否则容易混乱。例如:你分了一个小的迭代,但是因为人员技能不足,使得无法有效完成,那么整个项目就会受到很大的干扰。

H 模型流程图如下

H模型

(4)X 模型

  • 设计原理:X 模型的设计原理是将程序分成多个片段反复迭代测试,然后将多个片段集成再进行迭代测试。
  • 优点:对单独程序片段进行的相互分离的编码和测试,保证了测试效果。增加了探索测试,可以帮助测试人员发现计划之外的软件错误。
  • 缺点频繁的集成会增加测试成本;探索测试对测试人员要求更高。

X 模型流程图如下

X模型

经验小结:

  • v 模型适用于中小企业,w 模型适用于中大型企业(因为人员要求高),h 模型人员要求非常高,很少有公司使用;
  • 结合 W 模型与 H 模型进行工作,软件各方面的测试内容是以W 模型为准,而测试周期、测试计划和进度是以H 模型为指导。X 模型更多是作为最终测试、熟练性测试的模板,例如,对一个业务的测试已经有 2 年时间,则可以使用 X 模型进行模块化的、探索性的方向测试。

五、 软件测试的原则

1、软件测试的原则

(1)测试应基于客户需求

所有的测试工作都应该建立在满足客户需求的基础上,从客户角度来看,最严重的错误就是软件无法满足要求。有时候,软件产品的测试结果非常完美,但却不是客户最终想要的产品,那么软件产品的开发就是失败的,而测试工作也是没有任何意义的。因此测试应依照客户的需求配置环境并且按照客户的使用习惯进行测试并评价结果。

(2)测试要尽早进行和不断进行

软件的错误存在于软件生命周期的各个阶段,因此应该尽早开展测试工作,把软件测试贯穿到软件生命周期的各个阶段中,这样测试人员能够尽早地发现和预防错误,降低错误修复的成本。尽早的开展测试工作有利于帮助测试人员了解软件产品的需求和设计,从而预测测试的难度和风险,制定出完善的计划和方案,提高测试的效率。

(3)穷举测试是不可能的

由于时间资源的限制,进行完全(各种输入和输出的全部组合)的测试是不可能的,测试人员可以根据测试的风险优先级等确定测试的关注点,从而控制测试的工作量,在测试成本、风险和收益之间求得平衡。

(4)遵循 GoodEnough 原则

GoodEnough 原则是指测试的投入与产出要适当权衡,形成充分的质量评估过程,这个过程建立在测试花费的代价之上。测试不充分无法保证软件产品的质量,但测试投入过多会造成资源的浪费。随着测试资源投入的增加,测试的产出也是增加的,但当投入达到一定的比例后,测试的效果就不会明显增强了。因此在测试时要根据实际要求和产品质量考虑测试的投入,最好使测试投入与产出达到一个 GoodEnough 状态。

(5)测试缺陷要符合“二八”定理

一般情况下,软件80%的缺陷会集中在 20%的模块中,缺陷并不是平均分布的。因此在测试时,要抓住主要矛盾,如果发现某些模块比其他模块具有更多的缺陷,则要投入更多的人力、精力重点测试这些模块以提高测试效率。

(6)避免缺陷免疫

测试用例被反复使用,发现缺陷的能力就会越来越差;测试人员对软件越熟悉越会忽略一些看起来比较小的问题,发现缺陷的能力也越差,这种现象被称为软件测试的“杀虫剂现象。它主要是由于测试人员没有及时更新测试用例或者是对测试用例和测试对象过于熟悉,形成了思维定势。

六、 软件测试的流程

1、软件测试的基本流程

不同类型的软件产品测试的方式和重点不一样,测试流程也会不一样。同样类型的软件产品,不同的公司所制定的测试流程也会不一样。虽然不同软件的详细测试步骤不同,但它们所遵循的最基本的测试流程是一样的。

软件测试的基本流程

(1)分析测试需求

测试人员在制定测试计划之前需要先对软件需求进行分析,以便对要开发的软件产品有一个清晰的认识,从而明确测试对象及测试工作的范围和测试重点。在分析需求时还可以获取一些测试数据,作为测试计划的基本依据,为后续的测试打好基础。

此外,分析测试需求也是对软件需求进行测试,以发现软件需求中不合理的地方。

序号检查项检查结果说明
1是否覆盖了客户提出的所有需求项是【】否【】NA【】
2用词是否清晰、语义是否存在歧义是【】否【】NA【】
3是否清楚地描述了软件需要做什么以及不做什么是【】否【】NA【】
4是否描述了软件的目标环境,包括软硬件环境是【】否【】NA【】
5是否对需求项进行了合理的编号是【】否【】NA【】
6需求项是否前后一致、彼此不冲突是【】否【】NA【】
7是否清楚地说明了软件的每个输入、输出格式,以及输入与输出之间的对应关系是【】否【】NA【】
8是否清晰地描述了软件系统的性能要求是【】否【】NA【】
9需求的优先级是否合理分配是【】否【】NA【】
10是否描述了各种约束条件是【】否【】NA【】

被确定的测试需求必须是可核实的,测试需求必须有一个可观察可评测的结果。无法核实的需求就不是测试需求。测试需求分析还要与客户进行交流,以澄清某些混淆,确保测试人员与客户尽早地对项目达成共识。

(2)制定测试计划

测试计划一般要做好以下工作安排。

  • 确定测试范围:明确哪些对象是需要测试的,哪些对象不是需要测试的。
  • 制定测试策略:测试策略是测试计划中最重要的部分,它将要测试的内容划分出不同的优先级,并确定测试重点。根据测试模块的特点和测试类型(如功能测试、性能测试)选定测试环境和测试方法(如人工测试、自动化测试)。
  • 安排测试资源:通过对测试难度、时间、工作量等因素对测试资源合理安排,包括人员分配、工具配置等。
  • 安排测试进度:根据软件开发计划、产品的整体计划来安排测试工作的进度,同时还要考虑各部分工作的变化。在安排工作进度时,最好在各项测试工作之间预留一个缓冲时间以应对计划变更。
  • 预估测试风险:罗列出测试工作过程中可能会出现的不确定因素,并制定应对策略。

(3)设计测试用例

  • 测试用例(Test Case)指的是一套详细的测试方案,包括测试环境测试步骤测试数据预期结果。不同的公司会有不同的测试用例模板,虽然它们在风格和样式上有所不同,但本质上是一样的,都包括了测试用例的基本要素。
  • 测试用例编写的原则是尽量以最少的测试用例达到最大测试覆盖率。

(4)执行测试

  • 测试执行就是按照测试用例执行测试的过程,这是测试人员最主要的活动阶段。
  • 在执行测试时要根据测试用例的优先级进行。
  • 在执行测试过程中,测试人员要密切跟踪测试过程,记录缺陷、形成报告等,这一阶段是测试人员最重要的工作阶段。

(5)编写测试报告

一份完整的测试报告必须要包含以下几个要点。

  • 引言:测试报告编写目的、报告中出现的专业术语解释及参考资料等。
  • 测试概要:介绍项目背景、测试时间、测试地点及测试人员等信息。
  • 测试内容及执行情况:描述本次测试模块的版本测试类型,使用的测试用例设计方法及测试通过覆盖率,依据测试的通过情况提供对测试执行过程的评估结论,并给出测试执行活动的改进建议,以供后续测试执行活动借鉴参考。
  • 缺陷统计与分析:统计本次测试所发现的缺陷数目类型等,分析缺陷产生的原因给出规避措施等建议,同时还要记录残留缺陷未解决问题
  • 测试结论与建议:从需求符合度、功能正确性、性能指标等多个维度对版本质量进行总体评价,给出具体明确的结论。

总结:测试报告的数据是真实的,每一条结论的得出都要有评价依据,不能是主观臆断的

七、结束语

下一篇文章讲解黑盒测试和测试用例的基础知识。

关于软件测试的基础知识就讲到这里啦!如有不明白或有误的地方欢迎评论区评论或私信我交流~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareTesting/002.html b/column/Product/SoftwareTesting/002.html index ad224509..229cccda 100644 --- a/column/Product/SoftwareTesting/002.html +++ b/column/Product/SoftwareTesting/002.html @@ -19,7 +19,7 @@
Skip to content

一、黑盒测试的基本概念

1、黑盒测试基本概念

1)所谓黑盒测试,就是把软件(程序)当作一个有输入与输出的黑匣子,它把程序当作一个输入域输出域的映射,只要输入的数据能输出预期的结果即可,不需要了解程序的内部逻辑结构内部特性

2)黑盒测试又称为功能测试数据驱动测试

3)注重于程序的外部结构,主要对软件功能要求、软件界面、外部数据库访问及软件初始化等方面进行测试。测试者只要从程序接口处进行测试,以用户需求规格说明书为测试依据,测试程序是否满足用户的需求,因此是从用户观点出发的测试。

2、黑盒测试错误类型

黑盒测试主要发现的错误类型有:

1)检测功能是否正确或有遗漏;

2)检测性能是否满足要求;

3)检测界面是否有错误;

4)检测外部数据库访问是否有错误;

5)检测程序初始化和终止方面是否有错误。

二、测试用例概述及设计方法

1、测试用例概述

1)是将软件测试的行为活动,做一个科学化的组织归纳。

2)设计一个情况,软件程序在这种情况下,必须能够正常运行并且达到程序所设计的执行结果。

2、测试用例的好处

1)可以避免盲目测试并提高测试效率。

2)令软件测试的实施重点突出、目的明确。

3)软件版本更新后,只需少量修正便可进行测试,降低工作强度缩短项目周期

4)测试用例的通用化复用化则会使软件测试易于开展,并随着测试用例的不断精化其效率也不断攀升。

三、黑盒测试方法

1、等价类划分法

2、边界值分析法

3、错误推测法

4、因果图设计法

5、判定表驱动法

6、场景法

7、正交实验法

8、功能图法

下一篇文章将围绕着黑盒测试的八大方法展开细述。 如果想查看往期文章,也可以直接点击进入软件测试栏目。 码字不易,如果这篇文章对你有用,记得留个Star哦~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareTesting/003.html b/column/Product/SoftwareTesting/003.html index f0de4621..2e6b279a 100644 --- a/column/Product/SoftwareTesting/003.html +++ b/column/Product/SoftwareTesting/003.html @@ -20,7 +20,7 @@
Skip to content

一、等价类划分法

1、定义

一个程序可以有多个输入,等价类划分就是将这些输入数据按照输入需求进行分类,将它们划分为若干个子集,这些子集即为等价类(某个输入域的子集合),在每个等价类中选择有代表性的数据设计测试用例。

举个例子

这种方法类似于学生站队,男生站左边,女生站右边,老师站中间,这样就把师生这整个群体划分成了三个等价类等价类划分举例

2、等价类划分法步骤

(1)先从程序规格说明书中找出各个输入条件; (2)再为每个输入条件划分等价类,形成若干互不相交的子集; (3)列出等价表

输入条件有效等价类无效等价类
………………

3、设计测试用例步骤

等价类划分法设计测试用例要经历划分等价类(列出等价类表)和选取测试用例两步。

(1)划分等价类

等价类是指某个输入域的子集合。在该子集合中,各个输入数据对于揭露程序中的错误都是等效的。测试代表值就等价于这一类其他值的测试。

那在划分等价类的时候,会出现有效等价类和无效等价类,这个时候我们需要怎么判断呢?

有效等价类就是有效值的集合,它们是符合程序要求、合理且有意义的输入数据。

无效等价类就是无效值的集合,它们是不符合程序要求、不合理或无意义的输入数据。

因此,在设计测试用例时,要同时考虑有效等价类和无效等价类的设计。

同时,在划分等价类的时候,需要遵循一定的划分原则:

等价类划分原则

原则 1:如果输入条件规定了取值范围值的个数的情况下,可以确定一个有效等价类两个无效等价类

原则 2:如果输入条件规定了输入值的集合或者规定了**“必须如何”的条件**的情况下,可以确立一个有效等价类一个无效等价类

原则 3:如果输入条件是一个布尔量的情况下,可确定一个有效等价类一个无效等价类

原则 4:如果规定了输入数据的一组值(假定 n 个),并且程序要对每一个输入值分别处理的情况下,可确定n 个有效等价类一个无效等价类

原则 5:如果规定了输入数据必须遵守的规则,可确定一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则)。

原则 6:在确知已划分的等价类中,各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步地划分为更小的等价类。

同一个等价类中的数据发现程序缺陷的能力是相同的,如果使用等价类中的其中一个数据不能捕获缺陷,那么使用等价类中的其他数据也不能捕获缺陷;同样,如果等价类中的其中一个数据能够捕获缺陷,那么该等价类中的其他数据也能捕获缺陷,即等价类中的所有输入数据都是等效的

(2)设计测试用例

  • 在确立了等价类之后,建立等价类列表,列出所有划分出的等价类。
  • 为每个等价类规定一个唯一编号
  • 设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖的有效等价类。重复这一步,直到所有的有效等价类都被覆盖为止。
  • 设计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类。重复这一步,直到所有的无效等价类都被覆盖为止。

4、案例:学生选修课程

看到这里,不妨再做下案例分析。

案例 1:每个学生可以选修 1~3 门课程,要求采用等价类设计测试用例。

解题思路:首先分析有效等价类和无效等价类,然后建立等价类表。

【解析】

(1)根据题干分析有效等价类和无效等价类:

有效等价类:选修 1~3 门课

无效等价类:没有选修课、选修 3 门课以上

(2)根据分析建立等价类表:

等价类表

(3)根据等价类表设计测试用例覆盖有效等价类和无效等价类:

根据等价类表设计测试用例覆盖有效等价类和无效等价类

案例 2:某连锁酒店集团实行积分奖励计划,会员每次入住集团旗下酒店均可以获得一定积分,积分由欢迎积分加消费积分构成。其中欢迎积分跟酒店等级有关,具体标准如表 1-1 所示;消费积分跟每次入住消费金额有关,具体标准为每消费 1 元获得 2 积分(不足 1 元的部分不给分)。此外,集团会员分为优先会员、金会员、白金会员三个级别,金会员和白金会员在入住酒店时可获得消费积分的额外奖励,奖励规则如表 1-2 所示。

表 1-1 集团不同等级酒店的欢迎积分标准

集团不同等级酒店的欢迎积分标准

表 1-2 额外积分奖励规则

额外积分奖励规则

该酒店集团开发了一个程序来计算会员每次入住后所累积的积分,程序的输入包括会员级别 L、酒店等级 C 和消费金额 A(单位:元),程序的输出为本次积分 S。其中,L 为单个字母且大小写不敏感,C 为取值 1 到 6 的整数,A 为正浮点数且最多保留两位小数,S 为整数。

问题一】采用等价类划分法对该程序进行测试,等价类表如表 1-3 所示,请补充表中空(1)-(7)。

问题一答案

问题二】根据以上等价类表设计的测试用例如下表所示,请补充表 2-4 中空(1)-(13)。

问题二答案

二、边界值分析法

1、边界值分析法概述

1)边界值分析法是对软件的输入或输出边界进行测试的一种方法,它通常作为等价类划分法的一种补充测试。

2)在等价类划分法中,无论是输入等价类还是输出等价类,都会有多个边界,而边界值分析法就是在这些边界附近寻找某些点作为测试数据,而不是在等价类内部选择测试数据。

2、设计测试用例

设计测试用例步骤

1)首先划分等价类根据等价类划分情况确定边界情况

2)选取正好等于刚刚大于刚刚小于边界的值作为测试数据,而不是选取等价类中的典型值或任意值。

3、边界值设计原则

原则 1:如果输入条件规定了值的范围,则应取刚达到这个范围的边界的值,以及刚刚超越这个范围边界的值作为测试输入数据

原则 2:如果输入条件规定了值的个数,则用最大个数、最小个数、比最小个数少 1、比最大个数多 1 的数作为测试数据

原则 3:根据规格说明的每个输出条件,使用前面的原则 1。

原则 4:根据规格说明的每个输出条件,使用前面的原则 2。

原则 5:如果程序的规格说明给出的输入域或输出域是有序集合,则应选取集合的第一个元素最后一个元素作为测试用例。

原则 6:如果程序中使用了一个内部数据结构,则应该选择这个内部数据结构边界上的值作为测试用例。

原则 7:分析规格说明,找出其他可能的边界条件

三、错误推测法

1、错误推测法概述

错误推测法就是人们可以靠经验和直觉推测程序中可能存在的各种错误,从而有针对性地编写检查这些错误的例子。

2、错误推测法基本思想

(1)列举出程序中所有可能有的错误和容易发生错误的特殊情况(比如,程序只能输入数字,测试时可以输入字母进行测试)。 (2)根据它们选择测试用例。

四、因果图设计法

1、因果图设计法概述

如果在测试时必须考虑输入条件的各种组合以及各种输出情况,那么可以使用一种适用于描述对于多种条件的组合,相应产生多个动作的形式来设计测试用例,这就需要利用因果图。

2、因果图表示

因果图使用一些简单的逻辑符号和直线将程序的因(输入)与果(输出)连接起来,一般原因用 ci 表示,结果用 ei 表示,各结点表示状态,可以取值“0”或“1”,其中“0”表示状态不出现,“1”表示状态出现。

如下图所示:

因果图表示

ci 与 ei 之间有恒等、非(~)、或(∨)、与(∧)4 种关系,分别为:

恒等:在恒等关系中,要求程序有一个输入和一个输出,输出与输入保持一致。若 c1 为 1,则 e1 也为 1,若 c1 为 0,则 e1 也为 0。

:非使用符号“~”表示,在这种关系中,要求程序有一个输入和一个输出,输出是输入的取反。若 c1 为 1,则 e1 为 0,若 c1 为 0,则 e1 为 1。

:使用符号“∨”表示,或关系可以有任意个输入,只要这些输入中有一个为 1,则输出为 1,否则输出为 0。

:使用符号“∧”表示,与关系也可以有任意个输入,但只有这些输入全部为 1,输出才能为 1,否则输出为 0。

以下用一张图展示这 4 种关系:

因果图4种关系,恒等、非、与、或

总结

  • 在软件测试中,如果程序有多个输入,那么除了输入与输出之间的作用关系之外,这些输入之间往往也会存在某些依赖关系,某些输入条件本身不能同时出现,某一种输入可能会影响其他输入。
  • 例如,某一软件用于统计体检信息,在输入个人信息时,性别只能输入男或女,这两种输入不能同时存在,而且如果输入性别为女,那么体检项就会受到限制。

3、约束条件

为了表示原因与原因之间原因与结果之间可能存在的约束条件,在因果图中可以附加一些表示约束条件的符号。

(1)输入条件的约束类别可分为四种:

E(Exclusive,这些依赖关系在软件测试中称为“约束”,异)、I(at least one,或)、O(one and only one,唯一)、R(Requires,要求),在因果图中,用特定的符号表明这些约束关系。

  • E(异):a 和 b 中最多只能有一个为 1,即 a 和 b 不能同时为 1。
  • I(或):a、b 和 c 中至少有一个必须是 1,即 a、b、c 不能同时为 0。
  • O(唯一):a 和 b 有且仅有一个为 1。
  • R(要求):a 和 b 必须保持一致,即 a 为 1 时,b 也必须为 1,a 为 0 时,b 也必须为 0。

因果图约束条件

(2)输出条件的约束类别只有一种:

  • 除了输入条件,输出条件也会相互约束,输出条件的约束只有一种M(Mask,强制),强制约束关系。若结果 a 是 1,那么结果 b 强制为 0。

4、设计测试用例

(1)因果图设计测试用例思想:

  • 从程序规格说明书的描述中,找出因(输入条件)和果(输出结果或者程序状态的改变);

  • 通过因果图转换为判定表

  • 为判定表中的每一列设计一个测试用例;

(2)使用因果图设计测试用例的步骤:

  • 分析程序规格说明书描述内容,确定程序的输入与输出,即确定“原因”和“结果” 。

  • 分析得出输入与输入之间输入与输出之间的对应关系,将这些输入与输出之间的关系使用因果图表示出来。

  • 由于语法与环境的限制,有些输入与输入之间、输入与输出之间的组合情况是不可能出现的,对于这种情况,使用符号标记它们之间的限制或约束关系。

  • 将因果图转换为决策表,根据决策表设计测试用例。(决策表将在标题五判定表驱动法中提到)

5、优点

因果图法的优点:

  • 考虑到了输入情况的各种组合以及各个输入情况之间的相互制约关系

  • 因果图的约束关系可以有效简化决策表,帮助测试人员高效率的开发测试用例。

  • 因果图法是将自然语言规格说明转化成形式语言规格说明的一种严格的方法,可以指出规格说明存在的不完整性二义性

6、思考题

程序的规格说明要求:输入的第一个字符必须是#或*,第二个字符必须是一个数字,在此情况下进行文件的修改;如果第一个字符不是#或*,则给出信息 N,如果第二个字符不是数字,则给出信息 M。采用因果图法设计该软件的测试用例。

具体解析如下:1)分析程序规格说明中的原因和结果:

原因结果
C1:第一个字符是#e1:给出信息 N
C2:第一个字符是*e2:修改文件
C3:第二个字符是一个数字e3:给出信息 M

(2)画出因果图:

因果图表示

(3)将因果图转换成判定表,3 个条件一般可以有 2³ 种组合

12345678
原因c111110000
c211001100
c310101010
结果e1
e2
e3

(4)简化判定表,第 7 列和第 8 列合并

1234567
原因c11111000
c21100110
c3101010-
结果e1
e2
e3
(5)根据判定表生成测试用例
测试用例 ID输入数据输出结果
:--------::------::-------:
1#3修改文件
2#M给出信息 M
3*5修改文件
4*A给出信息 M
5MM给出信息 N

五、判定表驱动法

1、判定表驱动法概述

判定表也称为决策表,其实质就是一种逻辑表。在程序设计发展初期,判定表就已经被当作程序开发的辅助工具了,帮助开发人员整理开发模式和流程,因为它可以把复杂的逻辑关系和多种条件组合的情况表达的既具体又明确,利用判定表可以设计出完整的测试用例集合。

2、判定驱动法 —— 引例

为了让大家明白什么是判定表,下面通过一个“图书阅读指南”来制作一个判定表,图书阅读指南指明了图书阅读过程中可能出现的状况,以及针对各种情况给读者的建议。

(1)在图书阅读过程中可能会出现 3 种情况:

  • 是否疲倦。
  • 是否对内容感兴趣。
  • 对书中的内容是否感到糊涂。

如果回答是肯定的,则使用“Y”标记;

如果回答是否定的,则使用“N”标记。

那么这 3 种情况可以有2³=8 种组合,针对这 8 种组合。

(2)阅读指南给读者提供了 4 条建议:

  • 回到本章开头重读。
  • 继续读下去。
  • 跳到下一章去读。
  • 停止阅读并休息。

3)针对以上分析,得出以下图书阅读指南判定表

问题与建议12345678
问题是否疲倦YYYYNNNN
是否对内容感兴趣YYNNNYYN
对书中内容是否感到糊涂YNNYYYNN
建议回到本章开头重读
继续读下去
跳到下一章去读
停止阅读并休息

4)在实际测试中,条件桩往往很多,而且每个条件桩都有真假两个条件项,有 n 个条件桩的判定表就会有2n条件规则,如果每条规则都设计一个测试用例,不仅工作量大,而且有些工作量可能是重复的无意义的。例如在“图书阅读指南”中,第 1、2 条规则,第 1 条规则取值为:Y、Y、Y,执行结果为“停止阅读并休息”;第 2 条规则取值为:Y、Y、N,执行结果也是为“停止阅读并休息”;对于这两条规则来说,前两个问题的取值相同,执行结果一样。

这些不影响结果取值的问题称为无关条件项,用“-”表示。忽略无关条件项,可以将两条规则合并。

合并规则需要满足如下两个条件两条规则采取的动作相同;两条规则的条件项取值相似。

(5)根据合并规则,可以将“图书阅读指南”判定表合并。

问题与建议12345
问题是否疲倦YYNNN
是否对内容感兴趣YNNYY
对书中内容是否感到糊涂---YN
建议回到本章开头重读
继续读下去
跳到下一章去读
停止阅读并休息

3、判定表结构

判定表是把作为条件的所有输入的各种组合值以及对应的输出值都罗列出来而形成的表格,判定表由4 个部分组成,判定表结构如下:

条件桩条件项
动作桩动作项

其中每一列称为一个规则。判定表的4 个部分分别为:

  • 条件桩:列出问题的所有条件,除了某些问题对条件的先后次序有要求之外,通常决策表中所列条件的先后次序都无关紧要。
  • 条件项:条件项就是条件桩的所有可能取值。
  • 动作桩:动作桩就是问题可能采取的操作,这些操作一般没有先后次序之分。
  • 动作项:指出在条件项的各组取值情况下应采取的动作。

在判定表中,任何一个条件组合的特定取值及其相应要执行的操作称为一条规则,即判定表中的每一列就是一条规则,每一列都可以设计一个测试用例,根据判定表设计测试用例就不会有所遗漏。

4、判定表的建立步骤

  • 确定规则个数(n 个条件相应的有 2ⁿ 条规则)。
  • 列出所有的条件桩动作桩
  • 填入条件项。
  • 填入动作项,制定初始判定表。
  • 简化,合并相似规则或相同动作。

5、使用判定表设计测试用例的条件

  • 规格说明以判定表的形式给出,或很容易转换成判定表。
  • 条件的排列顺序不影响执行哪些操作。
  • 规则的排列顺序不影响执行哪些操作。
  • 当某一规则的条件已经满足,并确定要执行的操作后,不必检验别的规则。
  • 如果某一规则要执行多个操作,这些操作的执行顺序无关紧要。

6、案例:工资发放

某公司的薪资管理制度如下:员工工资分为年薪制与月薪制两种,员工的错误定位包括普通错误与严重错误两种,如果是年薪制的员工,犯普通错误扣款 2%,犯严重错误扣款 4%;如果是月薪制的员工,犯普通错误扣款 4%,犯严重错误扣款 8%。该公司编写了一款软件用于员工工资计算发放,现在要对该软件进行测试。

对公司员工工资管理进行分析,可得出员工工资由 4 个因素决定:年薪、月薪、普通错误、严重错误。其中,年薪与月薪不可能同时并存,但普通错误与严重错误可以并存。

员工最终扣款结果有 7 种:未扣款、扣款 2%、扣款 4%、扣款 6%(2%+4%)、扣款 4%、扣款 8%、扣款 12%(4%+8%)。

采用判定表驱动法设计该软件的测试用例。

具体解析如下:

1)分析员工工资的原因和结果:

员工工资原因和结果

2)有 4 个原因,每个原因有“Y”和“N”两个取值,理论上可以组成24=16 种规则,但是 c1 与 c2 不能同时并存,因此有23=8 种规则。得出员工工资判定表如下:

员工工资判定表

3)最终得出员工工资测试用例表:

在这里插入图片描述

六、正交实验设计法

1、正交实验设计法概述

正交实验设计法(Orthogonal experimental design)是指从大量的实验点中挑选出适量的有代表性的点,依据 Glois 理论导出“正交表”,从而合理的安排实验的一种实验设计方法。

2、正交实验设计法三个关键因素

  • 指标:判断实验结果优劣的标准。
  • 因子:因子也称为因素,是指所有影响实验指标的条件。
  • 因子的状态:因子的状态也叫因子的水平,它指的是因子变量的取值。

3、利用正交实验法设计测试用例的步骤

  • 提取因子,构造因子状态表
  • 加权筛选,简化因子状态表
  • 构建正交表,设计测试用例

接下来对这三个步骤进行一一解析。

(1)举个栗子(步骤一):

提取因子,构造因子状态表—— 即分析软件的规格需求说明得到影响软件功能的因子,确定因子可以有哪些取值,即确定因子的状态。

例如,某一软件的运行受到操作系统和数据库的影响,因此影响其运行是否成功的因子有操作系统和数据库两个,而操作系统有 Windows、Linux、Mac 三个取值,数据库有 MySQL、MongoDB、Oracle 三个取值,因此操作系统的因子状态为 3,数据库因子状态为 3。得到如下因子-状态表:

因子因子的状态
操作系统WindowsLinuxMac
数据库MySQLMongoDBOracle

(2)举个栗子(步骤二):

加权筛选,简化因子状态表 —— 在实际软件测试中,软件的因子及因子的状态会有很多,每个因子及其状态对软件的作用也大不相同,如果把这些因子及状态都划分到因子-状态表中,最后生成的测试用例会相当庞大,从而影响软件测试的效率。因此需要根据因子及状态的重要程度进行加权筛选,选出重要的因子与状态,简化因子-状态表。

(3)举个栗子(步骤三):

构建正交表,设计测试用例 —— 正交表的表示形式为 Ln(tc) 来表示。

  • L 表示正交表。
  • n 为正交表的行数,正交表的每一行可以设计一个测试用例,因此行数 n 也表示可以设计的测试用例的数目。
  • c 表示正交实验的因子数目,即正交表的列数,因此正交表是一个 n 行 c 列的表。
  • t 称为水平数,表示每个因子能够取得的最大值,即因子有多少个状态。
  • 在行数为 n(n 为正整数)的正交表中,行数 n(试验次数)=∑(每列水平数 t-1)+1。如: ①L8(27),n=7×(2-1)+1=8;②L4(23),n=3×(2-1)+1=4。

下面举出两个例子辅助理解:例 1:L4(23) 是最简单的正交表,它表示该实验有 3 个因子,每个因子有两个状态,可以做 4 次实验,如果用 0 和 1 表示每个因子的两种状态,则该正交表就是一个 4 行 3 列的表。 正交表如下图所示:

正交表实验

例 2: 在实际软件测试中,大多数情况下,软件有多个因子,每个因子的状态数目都不相同,即各列的水平数不等,这样的正交表称为混合正交表,如L8(24 + 41) ,这个正交表表示有 4 个因子有 2 种状态,有 1 个因子有 4 种状态。 那么正交表的行数为 n= ∑(每列水平数t-1)+ 1 = (2-1)×4 + (4-1)×1 + 1 = 8,这个 n 值的计算如果发生在大型项目时往往是很难计算的。 所以,混合正交表往往难以确定测试用例的数目,即 n 的值。因此,在这种情况下,可以登录正交表的一些权威网站,查询 n 值,下面给大家提供一个正交表查询网站, 在这里,可以查询到不同因子数、不同水平数的正交表的 n 值。 最终得出,该混合正交表如下图所示:

混合正交表

4、正交表的特点

正交表最大的特点是取点均匀分散齐整可比,每一列中每种数字出现的次数都相等,即每种状态的取值次数相等。

5、总结

写到这里,对正交实验设计法做个小结:

  • 在正交表中,每个因子的每个水平与另一个因子的各水平都“交互”一次,这就是正交性,它保证了实验点均匀分散在因子与水平的组合之中,因此具有很强的代表性。
  • 对于受多因子多水平影响的软件,正交实验法可以高效适量的生成测试用例,减少测试工作量,并且利用正交实验法得到的测试用例具有一定的覆盖度检错率可达 50%以上
  • 正交实验法虽然好用,但在选择正交表时要注意先要确定实验因子状态及它们之间的交互作用,选择合适的正交表,同时还要考虑实验的精度要求、费用、时长等因素。

6、案例:微信 Web 页面运行环境正交试验设计

微信是一款手机 App 软件,但它也有 web 版微信可以登录,如果要测试微信 web 页面运行环境,需要考虑多种因素,在众多的因素中,我们可以选出几个影响比较大的因素,如服务器、操作系统,插件和浏览器。利用正交实验设计法设计该软件的测试用例。

具体解析如下: > (1)提取因子,构造因子状态表

  • 对于选取出的 4 个影响因素,每个因素又有不同的取值,同样,在每个因素的多个值中,可以选出几个比较重要的值。如:

    • 服务器:IIS、Apache、Jetty;

    • 操作系统:Windows7、Windows10、Mac;

    • 插件:无、小程序、微信插件;

    • 浏览器:IE11、Chrome、FireFox;

  • 构造的因子状态表如下:

因子因子的状态
操作系统IISApacheJetty
数据库Windows7Windows10Mac
插件小程序微信插件
浏览器IE11ChromeFireFox

(2)加权筛选,简化因子状态表

  • 微信 web 版运行环境正交实验中有 4 个因子:服务器、操作系统、插件、浏览器,每个因子又有 3 个水平,因此该正交表是一个 4 因子 3 水平正交表。
  • 所以正交表的行数为 n= ∑(每列水平数t-1)+ 1 = (3-1)×4 + 1 = 9,因此正交表的表示形式为L9(34)
  • 得出 n=9 后,查表可得,简化后的因子状态表如下:

web微信简化后的因子状态表

(3)构建正交表,设计测试用例

  • 将因子、状态映射到正交表,可生成具体的测试用例,具体如下表:

七、场景法

1、设计思想

现在的软件几乎都是由事件来触发的,事情触发便形成了场景,而同一事件不同的触发顺序和处理结果就形成了事件流

2、场景的构成要素

场景可以看成是基本流与备选流的集合。用例的场景用来描述流经用例的路径,从用例的开始到结束遍历这条路径上所有的基本流和备选流。

(1)基本流

基本事件流,从系统某个初始状态开始,经一系列状态后,到达最终状态的一个业务流程,并且是最主要最基本的一个业务流程(无任何差错,程序从开始直接到执行结束)。

(2)场景流

备选事件流,以基本流为基础,在基本流所经过的每个判定节点处满足不同的触发条件而导致的其他事件流。

3、基本流和备选流的场景说明

先用一张图来描述基本流和备选流的流程。

基本流和备选流的绘制

从上图可以看出,图中经过用例的每条路径都用基本流备选流来表示。

基本流:采用直黑线表示,是经过用例的最简单的路径

备选流:采用不同色彩表示,一个备选流可能从基本流开始,在某个特定条件下执行,然后重新加入基本流中(如备选流 1 和 3);也可能起源于另一个备选流(如备选流 2),或者终止用例而不再重新加入到某个流(如备选流 2 和 4)。

根据图中每条经过的可能路径,从基本流开始,再经过基本流、备选流的综合,可以确定不同的用例场景,如下

基本流和备选流的场景

基于以上例子,可以得出以下结论:基本流只有一个,而备选流的数目则取决于基本流上判定节点的数目事务分析的颗粒度,颗粒度越细,考虑越周全,得到的备选流数目就越多,相应的测试工作量就越大。

4、设计测试用例

场景法设计测试用例的基本步骤如下:

1)根据需求规格说明,描述出程序的基本流及各项备选流。

2)根据基本流和各项备选流生成不同的场景。

3)对每一个场景生成相应的测试用例。

4)对生成的所有测试用例重新复审,去掉多余的测试用例。测试用例确定后,对每一个测试用例确定测试数据值。

5、总结

写到这里,对场景法做个小结:

  • 场景法以事件流和场景为核心,又被称为业务流程测试法,要求测试人员使用场景法设计测试用例时把自己当成最终用户,尽可能真实地模拟用户在使用此软件时的操作情形。
  • 在测试过程中,测试人员需要模拟两个方面的业务:正确的操作流程可能出现的错误操作
  • 它适用于业务比较复杂的软件系统测试。

6、案例:在线购物案例

有一个在线购物的实例:用户进入一个在线购物网站进行购物,选购物品后,进行在线购买,这时需要使用账号登录;登录成功后,进行付钱交易;交易成功后,生成订购单;完成整个购物过程。请使用场景法设计测试用例。

案例解析如下:

(1)确定基本流和备选流

  • 基本流:登录在线购物网站,选择物品,登录账号,付钱交易,生成订购单。
  • 备选流 1:账号不存在。
  • 备选流 2:密码错误。
  • 备选流 3:货物库存不足。
  • 备选流 4:账号余额不足。

(2)根据基本流和备选流来确定场景,如下表:

购物系统场景表

场景 1:成功购物基本流
场景 2:账号不存在备选流 1
场景 3:密码错误备选流 2
场景 4:货物库存不足备选流 3
场景 5:用户账号余额不足备选流 4

(3)根据每一个场景,设计需要的测试用例

【解析】

可以采用矩阵判定表来确定和管理测试用例,下面介绍一种通用的格式,其中各行代表各个测试用例,而各列则代表测试用例的信息。 在矩阵中,

  • V(有效)用于表明这个条件必须是 VALID(有效的)才可执行基本流;
  • I(无效)用于表明这种条件下将激活所需备选流;
  • N/A(不适用)表明这个条件不适用于测试用例。

购物系统场景矩阵见下表:

购物系统场景矩阵

测试用例 ID场景账号密码购买商品数量商品库存数量用户账号余额预期结果
1场景 1:成功购物VVVVV成功购物
2场景 2:账号不存在IN/AN/AN/AN/A提示账号不存在
3场景 3:密码错误VIN/AN/AN/A提示密码输入有误
4场景 4:购买商品库存不足VVVIN/A提示库存不足
5场景 5:用户账号余额不足VVVVI提示账号余额不足

(4)设计具体的测试用例数据(假设所购物品单价为 30 元)

购物系统具体测试用例

场景测试用例 ID账号密码购买商品数量商品库存数量用户账号余额预期结果
场景 1:成功购物1admin123test12310 件50 件2000 元成功购物
场景 2:账号不存在2adminN/AN/AN/AN/A提示账号不存在
场景 3:密码错误3admin123testN/AN/AN/A提示密码输入有误
场景 4:购买商品库存不足4admin123test12360 件50 件N/A提示库存不足
场景 5:用户账号余额不足5admin123test12310 件50 件200 元提示账号余额不足

八、功能图法

此处还未学习明白,静待后续更新……

九、黑盒测试方法策略总结

写到这里,对上面八大黑盒测试方法做个小结。

1、各种测试方法选择的综合策略

1首先进行等价类划分,包括输入条件和输出条件的等价划分,将无限测试变成有限测试,这是减少工作量和提高测试效率最有效的方法。

2在任何情况下都必须使用边界值分析方法。经验表明,用这种方法设计出的测试用例发现程序错误的能力最强。

3可以用错误推测法追加一些测试用例,这需要依靠测试工程师的智慧和经验。

4对照程序逻辑,检查已设计出的测试用例的逻辑覆盖程度。如果没有达到要求的覆盖标准,应当再补充足够的测试用例。

5)如果程序的功能说明中含有输入条件的组合情况,则一开始就可选用因果图法判定表

6)对于参数配置类的软件,要用正交试验法选择较少的组合方式达到最佳效果。

7)对于业务流清晰的软件,可以使用场景贯穿测试,再综合使用各种测试方法。

2、黑盒测试的优缺点

(1)优点对较大的代码单元来说,黑盒测试比白盒测试的效率高 ,测试人员不需要了解实现的细节,包括特定的编程语言;测试人员和编程人员是相互独立的,从用户的角度进行测试,很容易被接受和理解,有助于暴露任何与规格不一致或者歧异的地方,测试用例可以在规格完成后马上进行。

(2)缺点:不能测试程序内部特定部位,比如程序未执行的代码,这些代码得不到测试,则无法发现错误。若没有清晰的和简明的规格,测试用例很难被设计,不易进行充分性测试。

十、写在最后

黑盒测试相较于白盒测试来说比较简单,不需要了解程序内部的代码,与软件的内部实现无关;从用户角度出发,能很容易的知道用户会使用到哪些功能,会遇到哪些问题;并且是基于软件开发文档做的相关测试,能较清楚地了解软件实现了文档中的哪些功能。 八大典型的黑盒测试方法讲解到这里就结束啦!如有不理解或者有误的地方欢迎私聊或加我微信指正~ 下一篇文章将讲解白盒测试。 如果想查看往期文章,也可以直接点击进入软件测试栏目

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareTesting/004.html b/column/Product/SoftwareTesting/004.html index 3d97f7f8..67b8ff04 100644 --- a/column/Product/SoftwareTesting/004.html +++ b/column/Product/SoftwareTesting/004.html @@ -203,7 +203,7 @@ j>=yclelen; pos>=panonopt_end; pos<panonopt_end;

【问题 2】

控制流图如下图所示,V(G)=4。

案例2控制流图

【问题 3】

线性无关路径:

路径 1:1、2、8

路径 2:1、2、3、4、2…

路径 3:1、2、3、4、5、6、4…

路径 4:1、2、3、4、5、7、4…

四、写在最后

🙋🙋🙋

对于软件测试中的白盒测试来说,主要需要了解白盒测试的基本概念,静态和动态白盒测试的方法,内容较黑盒测试来说逻辑性会更强一些。同时,值得注意的是,在动态测试中的基本路径测试法中,线性无关路径的识别要尤为小心,在计算过程中很容易出现多写的问题。因此,在此基础上,大家可以再多找几道相关的题目进行练习,举一反三。

白盒测试的内容就讲到这里啦!如有需要了解软件测试相关的其他内容,可到『软件测试』栏目进行查看学习~

- + \ No newline at end of file diff --git a/column/Product/SoftwareTesting/005.html b/column/Product/SoftwareTesting/005.html index 081a038f..5055edb7 100644 --- a/column/Product/SoftwareTesting/005.html +++ b/column/Product/SoftwareTesting/005.html @@ -19,7 +19,7 @@
Skip to content

前言

很多时候,我们都知道软件有黑白盒测试,但往往还遗漏掉了一个性能测试

在下面的这篇文章中,就带领大家来了解性能测试。一起来学习吧~🧐

一、🤪 性能测试概念

1、为什么要有性能测试?

(1)2007 年 10 月,北京奥组委实行 2008 年奥运会门票预售,一时间订票官网访问量激增导致系统瘫痪,最终奥运会门票暂停销售 5 天。

门票预售

(2)2009 年 11 月 22 日,由于圣诞临近, eBay 网站的商品交易量比去年同期增长 33% ,正是由于多出的这 33%使得 eBay 网站不堪重负而崩溃,导致卖家蒙受当日销售额 80% 的损失,可谓损失惨重。

eBay

(3)12306 订票网站,自 2010 年上线以来就饱受诟病,每年春运期间,总会因为抢票高峰而崩溃,用户在买票时出现无法登陆的现象。2014 年,12306 网站甚至出现了安全问题,用户可以轻易获取陌生人的身份证号码、手机号码等信息。

12306订票网站

通过以上例子我们可以清楚的认识到,不管是奥运会的门票预售系统,还是 12306 的订票系统崩塌,都是由于软件系统没有经过性能测试或者性能测试不充分而引发的问题。因此,作为一名测试人员,除了要对软件的基本功能测试之外,还需要对软件性能进行测试,软件性能测试也是非常重要且非常必要的一项测试。

2、性能测试是什么?

所谓性能测试,就是通过性能测试工具模拟正常、峰值及异常负载状态下对系统的各项性能指标进行测试的活动。性能测试能够验证软件系统是否达到了用户期望的性能需求,同时也可以发现系统中可能存在的性能瓶颈及缺陷,从而优化系统的性能。

3、性能测试的目的

性能测试的目的主要有以下四点:

  • 证系统性能是否满足预期的性能需求,包括系统的执行效率、稳定性、可靠性、安全性等。
  • 分析软件系统在各种负载水平下的运行状态,提高性能调整效率
  • 识别系统缺陷,寻找系统中可能存在的性能问题,定位系统瓶颈并解决问题。
  • 系统调优,探测系统设计与资源之间的最佳平衡,改善并优化系统的性能。

二、🤐 性能测试指标

性能测试指标有以下 6 个指标:

  • 响应时间
  • 吞吐量
  • 并发用户数
  • TPS (Transaction per Second)
  • 点击率
  • 资源利用率

接下来将围绕着这 6 个指标进行一一讲解。

1、响应时间

响应时间 (Response Time) 系统对用户请求作出响应所需要的时间。

这个时间是指用户从软件客户端发出请求到用户接收到返回数据的整个过程所需要的时间,包括各种中间件(如服务器、数据库等)的处理时间。

如下图所示:

 响应时间

从上图中可以看到,从客户端发出请求到客户端接收到返回数据的整个过程即为系统的响应时间,为 t1+t2+t3+t4+t5+t6

一般来说,响应时间越短,表明软件的响应速度越快,性能越好。但是响应时间需要与用户的具体需求相结合,例如火车订票查询功能响应时间一般 2s 内就可以完成,而在网站下载电影时,如果一部电影能够在几分钟内完成下载,则说明该网站就已经很快了,所以需要依据实际情况而定。

2、吞吐量

吞吐量 (Throughput) 是指单位时间内系统能够完成的工作量,它衡量的是软件系统服务器的处理能力

吞吐量的度量单位可以是请求数/秒、页面数/秒、访问人数/天、处理业务数/小时等。

吞吐量是软件系统衡量自身负载能力的一个很重要的指标,吞吐量越大系统单位时间内处理的数据越多系统的负载能力越强

3、并发用户数

并发用户数是指同一时间请求和访问的用户数量。

并发用户数量越大,对系统的性能影响越大,并发用户数量较大可能会导致系统响应变慢系统不稳定等问题。软件系统在设计时必须要考虑并发访问的情况,测试工程师在进行性能测试时也必须进行并发访问的测试。

4、TPS(Transaction Per Second)

TPS 是指系统每秒钟能够处理的事务和交易的数量,它是衡量系统处理能力的重要指标。

5、点击率

点击率是指用户每秒向 Web 服务器提交的 HTTP 请求数,这个指标是 Web 应用特有的一个性能指标,通过点击率可以评估用户产生的负载量,并且可以判断系统是否稳定。点击率只是一个参考指标,帮助衡量 Web 服务器的性能。

6、资源利用率

资源利用率是指软件对系统资源的使用情况,包括CPU 利用率内存利用率磁盘利用率等,资源利用率是分析软件性能瓶颈的重要参数。

三、😶 性能测试种类

性能测试种类主要有以下六种:

  • 负载测试
  • 压力测试
  • 并发测试
  • 配置测试
  • 可靠性测试
  • 容量测试

接下来将围绕着以上这六种性能测试种类进行讲解。

1、负载测试

(1)定义

负载测试是指逐步增加系统负载,测试系统性能的变化,并最终确定在满足系统性能指标的情况下,系统所能够承受的最大负载量

(2)举个例子

负载测试类似于举重运动,通过不断给运动员增加重量,确定运动员身体状况保持正常的情况下所能举起的最大重量。

对于负载测试来说,前提是满足性能指标要求,例如一个软件系统的响应时间要求不超过 2s ,则在这个前提下,不断增加用户访问量,当访问量超过 1 万人时,系统的响应时间就会变慢,响应时间会超过 2s 。因此,可以确定系统响应时间不超过 2s 的前提下最大负载量是 1 万人。

2、压力测试

(1)定义

压力测试也叫强度测试,它是指逐步给系统增加压力,测试系统的性能变化,使系统某些资源达到饱和或系统崩溃的边缘,从而确定系统所能承受的最大压力。

(2)压力测试与负载测试的区别

负载测试是在保持性能指标要求的前提下系统能够承受的最大负载,而压力测试则是使系统性能达到极限的状态。

压力测试可以揭露那些只有在高负载条件下才会出现的 Bug ,如同步问题、内存泄露等。

(3)峰值测试

性能测试中还有一种压力测试叫做峰值测试,它是指瞬间(不是逐步加压)将系统压力加载到最大,使测试软件系统在极限压力下的运行情况。

3、并发测试

(1)定义

并发测试是指通过模拟用户并发访问,测试多用户并发访问同一个应用、同一个模块或者数据记录时是否存在死锁或其他性能问题。

(2)举个例子

并发测试一般没有标准,只是测试并发时会不会出现意外情况,几乎所有的性能测试都会涉及到一些并发测试,例如多个用户同时访问某一条件数据,多个用户同时在更新数据,那么数据库可能就会出现访问错误写入错误等异常情况。

4、配置测试

(1)定义

配置测试是指调整软件系统的软硬件环境,测试各种环境对系统性能的影响,从而找到系统各项资源的最优分配原则

2)举个例子

配置测试不改变代码,只改变软硬件配置,例如安装版本更高的数据库、配置性能更好的 CPU、内存等,通过更改外部配置来提高软件的性能。

5、可靠性测试

(1)定义

可靠性测试是指给系统加载一定的业务压力,使其持续运行一段时间(如 7*24h ),测试系统在这种条件下是否能够稳定运行。

6、容量测试

(1)定义

容量测试是指在一定的软硬件及网络环境下,测试系统所能支持的最大用户数最大存储量等。

(2)举个例子

容量测试通常与数据库、系统资源(如 CPU 、内存、磁盘等)有关,用于规划将来需求增长(如用户增长、业务量增加等)时,对数据库和系统资源的优化。

四、😲 性能测试流程

1、性能测试流程

先用一张图来查看性能测试的整个流程。如下图所示:

性能测试流程

2、性能测试流程分析

(1)分析性能测试需求

在性能测试需求分析阶段,测试人员需要收集有关项目的各种资料,并与开发人员进行沟通,对整个项目有一定的了解,针对需要进行性能测试的部分进行分析,确定测试目标。

例如客户要求软件产品的查询功能响应时间不超过 2s ,则需要明确多少用户量情况下,响应时间不超过 2s 。对于刚上线的产品,用户量不多,但几年之后可能用户量会巨增,那么在性能测试时是否要测试产品的高并发访问,以及高并发访问下的响应时间。

(2)制定性能测试计划

  • 确定测试环境: 包括物理环境生产环境、测试团队可利用的工具资源等。
  • 确定性能验收标准: 确定响应时间吞吐量系统资源(CPU、内存等)利用总目标和限制
  • 设计测试场景:产品业务用户使用场景进行分析,设计符合用户使用习惯的场景,整理出一个业务场景表,为编写测试脚本提供依据。
  • 准备测试数据: 性能测试是模拟现实的使用场景,例如模拟用户高并发,则需要准备用户数量、工作时间、测试时长等数据。

(3)设计测试用例

性能测试用例是根据测试场景为测试准备数据,例如模拟用户高并发,可以分别设计 100个 用户并发数量、 1000个 用户并发数量等,此外还要考虑用户活跃时间访问频率场景交互等各种情况。测试人员可以根据测试计划中的业务场景表设计出足够的测试用例以达到最大的测试覆盖

(4)编写性能测试脚本

  • 正确选择协议
  • 根据工具的支持情况和测试人员熟悉程度选取脚本语言。
  • 编写测试脚本时,要遵循代码编写规范,保证代码的质量。
  • 做好脚本的维护管理工作

(5)测试执行及监控

1)了解几个指标

性能指标: 本次性能测试要测试的性能指标的变化。

资源占用与释放情况: CPU 、内存、磁盘、网络等使用情况。性能测试停止后,各项资源是否能正常释放以供后续业务使用。

警告信息: 一般软件系统在出现问题时会发出警告信息,当有警告信息时,测试人员要及时查看。

日志检查: 经常分析系统日志,包括操作系统数据库等日志。

2)结果影响

性能测试监控对性能测试结果分析、对软件的缺陷分析都起着非常重要的作用。

在测试过程中,如果遇到与预期结果不符合的情况,测试人员要调整系统配置或修改程序代码来定位问题。

由于性能测试执行过程需要监控的数据复杂多变,它要求测试人员对监控的数据指标有非常清楚的认识,同时还要求测试人员对性能测试工具非常熟悉。作为性能测试人员,应该不断努力,深入学习,不断积累知识经验才能做的更好。

(6)运行结果分析

性能测试完成之后,测试人员需要收集整理测试数据对数据进行分析,将测试数据与客户要求的性能指标进行对比,若不满足客户的性能要求,需要进行性能调优然后重新测试,直到产品性能满足客户需求。

(7)性能测试报告

性能测试完成之后需要编写性能测试报告,阐述性能测试的目标、性能测试环境、性能测试用例与脚本使用情况、性能测试结果及性能测试过程中遇到的问题和解决办法等。软件产品不能只进行一次性能测试,因此性能测试报告需要备案保存作为下次性能测试的参考

五、🤪 结束语

对于测开人员来说,不能只会黑白盒测试,还要会性能测试。性能测试对于软件来说也是至关重要的一部分,没有经过性能测试的软件一般都会出现 bug 满天飞的问题。相信通过上文的了解,大家对性能测试有一个基础的认识。

性能测试的内容就讲到这里啦!如有需要了解软件测试相关的其他内容,可到『软件测试』栏目进行查看学习~

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Product/SoftwareTesting/006.html b/column/Product/SoftwareTesting/006.html index d3d33e3f..d989ebfb 100644 --- a/column/Product/SoftwareTesting/006.html +++ b/column/Product/SoftwareTesting/006.html @@ -23,7 +23,7 @@ (pw=1or1=1’); ”

案例 2:

sql
str SQL=select * from users where (name=‘张三’;DROP TABLE users;--)”
str SQL=select * from users where (name=‘张三’;DROP TABLE users;--)”
sql
Select *from users where name=‘张三’;
 DROP TABLE users
Select *from users where name=‘张三’;
 DROP TABLE users

(3)如何防范 SQL 注入

SQL 注入是风险非常高的安全漏洞,我们可以在应用程序中对用户输入的数据进行合法性检测,包括用户输入数据的类型和长度,同时,对 SQL 语句中的特殊字符(如单引号、双引号、分号等)进行过滤处理。

由于 SQL 注入攻击的 Web 应用程序处于应用层,因此大多防火墙不会进行拦截。除了完善应用代码外,还可以在数据库服务器端进行防御,对数据库服务器进行权限设置,降低 Web 程序连接数据库的权限,撤销不必要的公共许可,使用强大的加密技术保护敏感数据并对被读取走的敏感数据进行审查跟踪等。

2、XSS 跨站脚本攻击

(1)XSS 命名

XSS 全拼为 Cross Site Scripting ,意为跨站脚本,其缩写原本为 CSS ,但这与 HTML 中的层叠样式表(Cascading Style Sheets)缩写重名了,为了区分就将跨站脚本改为了 XSS

(2)定义

XSS (Cross Site Scripting)是 Web 应用系统最常见的安全漏洞之一,它主要源于 Web 应用程序对用户输入检查和过滤不足。攻击者可以利用 XSS 漏洞把恶意代码注入到网站中,当有用户浏览该网站时,这些恶意代码就会被执行,从而达到攻击的目的。

(3)xss 攻击过程

先用一张图来演示 XSS 的攻击过程:

 XSS攻击过程

XSS 攻击过程有以下 4 个步骤:

(4)如何防御

对于 XSS 漏洞,最核心的防御措施就是对用户的输入进行检查和过滤,包括 URL 、查询关键字、 HTTP 头、 POST 数据等,仅接受指定长度范围、格式适当、符合预期的内容,对其他不符合预期的内容一律进行过滤。

除此之外,当向 HTML 标签或属性中插入不可信数据时,要对这些数据进行相应的编码处理。将重要的 cookie 标记为 http only ,这样 javascript 脚本就不能访问这个 cookie ,避免了攻击者利用 javascript 脚本获取 cookie

3、CSRF 跨站请求伪造攻击

(1)定义

CSRF (Cross-Site Request Forgery)为跨站请求伪造,它是一种针对 Web 应用程序的攻击方式,攻击者利用 CSRF 漏洞伪装成受信任用户的请求,来访问受攻击的网站。

(2)攻击过程

下面用一张图来演示 CSRF 的攻击过程:

 CSRF攻击过程

(3)如何攻击

CSRF 攻击中,当用户访问一个信任网站时,在没有退出会话的情况下,攻击者诱使用户点击恶意网站,恶意网站会返回攻击代码,同时要求访问信任网站,这样用户就在不知情的情况下将恶意网站的代码发送到了信任网站。

(4)CSRF 和 XSS 的不同之处

XSS 是盗取用户信息伪装成用户执行恶意活动,而 CSRF 则是通过用户向网站发起攻击。

如果将 XSS 攻击过程比喻为小偷偷取了用户的身份证去办理非法业务,则 CSRF 攻击则是骗子“劫持”了用户,让用户自己去办理非法业务,以达到自己的目的。

(5)如何防范 CSRF

CSRF 漏洞产生的原因主要是对用户请求缺少更安全的验证机制,防范 CSRF 漏洞的主要思路就是加强后台对用户及用户请求的验证,而不能仅限于 cookie 的识别。

例如,使用 http 请求头中的 Referer 对网站来源进行身份校验,添加基于当前用户身份的 token 验证,在请求数据提交前,使用验证码填写方式验证用户来源,防止未授权的恶意操作。

(6)Referer

HTTP Referer 是请求头的一部分,代表网页的来源(上一页的地址),当浏览器向 Web 服务器发送请求的时候,一般会带上 Referer ,告诉服务器此次访问是从哪个页面链接过来的,服务器由此可以获得一些信息用于处理。

四、🩸 渗透测试

1、渗透测试的定义

渗透测试是利用模拟黑客攻击的方式,评估计算机网络系统安全性能的一种方法。这个过程是站在攻击者角度对系统的任何弱点、技术缺陷或漏洞的主动分析,并且有条件地主动利用安全漏洞。

2、渗透测试的特点

渗透测试是一个渐进的并且逐步深入的过程。

渗透测试是选择不影响业务系统正常运行的攻击方法进行的测试。

3、渗透测试流程主要步骤

渗透测试的主要步骤如下图所示:

渗透测试的主要步骤

4、渗透测试流程

(1)明确目标

(2)收集信息

在信息收集阶段要尽量收集关于项目软件的各种信息,例如,对于一个 Web 应用程序,要收集脚本类型服务器类型数据库类型以及项目所用到的框架开源软件等。信息收集对于渗透测试来说非常重要,只有掌握目标程序足够多的信息,才能更好地进行漏洞检测。

信息收集的方式可分为两种:

主动收集: 通过直接访问、扫描网站等方式收集想要的信息,这种方式可以收集的信息比较多,但是访问者的操作行为会被目标主机记录。

被动收集: 利用第三方服务对目标进行了解,如上网搜索相关信息。这种方式获取的信息相对较少且不够直接,但目标主机不会发现测试人员的行为。

(3)扫描漏洞

在这一阶段,综合分析收集到的信息,借助扫描工具对目标程序进行扫描,查找存在的安全漏洞

(4)验证漏洞

扫描漏洞阶段,测试人员会得到很多关于目标程序的安全漏洞,但这些漏洞有误报,需要测试人员结合实际情况,搭建模拟测试环境对这些安全漏洞进行验证。被确认的安全漏洞才能被利用执行攻击。

(5)分析信息

经过验证的安全漏洞就可以被利用起来向目标程序发起攻击,但是不同的安全漏洞,攻击机制并不相同,针对不同的安全漏洞需要进一步分析,包括安全漏洞原理可利用的工具目标程序检测机制攻击是否可以绕过防火墙等,制定一个详细精密的攻击计划,这样才能保证测试顺利执行。

(6)渗透攻击

渗透攻击就是对目标程序发起真正的攻击,达到测试目的,如获取用户帐号密码、截取目标程序传输的数据、控制目标主机等。一般渗透测试是一次性测试,攻击完成之后要执行清理工作删除系统日志程序日志等,擦除进入系统的痕迹。

(7)整理信息

渗透攻击完成之后,整理攻击所获得的信息,为后面编写测试报告提供依据。

(8)编写测试报告

测试完成之后要编写测试报告,阐述项目安全测试目标、信息收集方式、漏洞扫描工具以及漏洞情况、攻击计划、实际攻击结果、测试过程中遇到的问题等,此外,还要对目标程序存在的漏洞进行分析,提供安全有效的解决办法。

五、🛠️ 常见安全测试工具

1、Web 漏洞扫描工具-AppScan

(1)定义

AppScanIBM 公司出的一款 Web 应用安全测试工具,它采用黑盒测试方式,可以扫描常见的 web 应用安全漏洞。

(2)AppScan 的扫描过程

AppScan 的扫描过程为:探测、测试、扫描

在探测阶段, AppScan 通过发送请求对站内的链接、表单等进行访问,根据响应信息检测目标程序可能存在的安全隐患,从而确定安全漏洞范围。

在测试阶段, AppScan 对潜在的安全漏洞发起攻击。 AppScan 有一个内置的测试策略库,测试策略库可以针对相应的安全隐患检测规则生成对应的测试输入, AppScan 就使用生成的测试输入对安全漏洞发起攻击。

在扫描阶段, AppScan 会检测目标程序对攻击的响应结果,并根据结果来确定探测到的安全漏洞是否是一个真正的安全漏洞,如果是一个真正的安全漏洞则根据其危险程度确定危险级别,为开发人员修复缺陷提供依据。

2、端口扫描工具-Nmap

(1)定义

Nmap 是一个网络连接端口扫描工具,用来扫描网上计算机开放的网络连接端口。确定服务运行的端口,并且推断计算机运行的操作系统。它是网络管理员用以评估网络系统安全必备工具之一。

(2)Nmap 的具体功能

Nmap 具体功能如下:

3、抓包工具-Fiddler

(1)定义

Fiddler 是一个 http 协议调试代理工具,它以代理 Web 服务器形式工作,帮助用户记录计算机和 Internet 之间传递的所有 HTTP(HTTPS) 流量。

如图所示:

抓包工具

(2)Fiddler 的功能

Fiddler 可以捕获来自本地运行程序的所有流量,从而记录服务器到服务器、设备到服务器之间的流量。此外, Fiddler 还支持各种过滤器,过滤出用户想要的流量数据,节省大量时间和精力。 相比于其他抓包工具, Fiddler 小巧易用,且功能完善,它支持将捕获的流量数据存档,以供后续分析使用。

4、Web 渗透测试工具-Metasploit

(1)定义

Metasploit 是一个渗透测试平台,能够查找、验证漏洞,并利用漏洞进行渗透攻击。它是一个开源项目,提供基础架构、内容和工具来执行渗透测试和广泛的安全审计。

(2)Metasploit 的具体功能

对于渗透攻击, Metasploit 主要提供了以下功能模块:

渗透模块(exploit): 运行时会利用目标的安全漏洞进行攻击。

攻击载荷模块(payload): 在成功对目标完成一次渗透之后,测试程序开始在目标计算机上运行。它能帮助用户在目标系统上获得需要的访问和行动权限。

辅助模块(auxiliary): 包含了一系列的辅助支持模块,包括扫描模块漏洞发掘模块网络协议欺骗模块

编码器模块(encoder): 编码器模块通常用来对我们的攻击模块进行代码混淆,逃过目标安全保护机制的检测,如杀毒软件和防火墙等。

Meterpreter: 使用内存技术的攻击载荷,可以注入到进程之中。它提供了各种可以在目标上执行的功能。

(3)Metasploit 的作用

Metasploit 是一个多用户协作工具,团队成员可以共享主机数据,查看收集的证据以及创建主机备注以共享有关特定目标的知识。最终, Metasploit 可帮助用户确定利用目标的最薄弱点,并证明存在漏洞或安全问题。

六、🔚 结束语

对于软件测试来说,除了黑白盒测试、性能测试以外,安全测试也尤为重要。一旦网页有漏洞,攻击者很容易就让受攻击者执行非本意的操作,这种场面并不是谁都想看到的。因此,对于软件来说,要做好安全测试 🙋

关于安全测试的内容就讲到这里啦!如有不理解或文章有误,欢迎评论区留言或私信我交流!

同时,有需要了解软件测试相关的其他内容,可到『软件测试』栏目进行查看学习~

- + \ No newline at end of file diff --git a/column/Product/index.html b/column/Product/index.html index a04b8cf8..f013677e 100644 --- a/column/Product/index.html +++ b/column/Product/index.html @@ -19,7 +19,7 @@
Skip to content

序言

本类别记录与产品相关的文章,包括软件工程、软件测试、产品分析等多领域模块。文章收录详情如下 👇

文章收录

软件工程

『软件工程 0』一份【软件工程】的学习指南已到达,请注意查收!!

『软件工程 1』详解软件是什么

『软件工程 2』 详解软件工程和软件过程模型

『软件工程 3』你应该知道的三种原型实现模型:抛弃式、演化式、增量式

『软件工程 4』一文了解软件项目管理中的 4P

『软件工程 5』详解软件项目管理之软件的度量

『软件工程 6』详解软件项目管理之软件范围与估算

『软件工程 7』详解软件项目管理之风险分析与管理

『软件工程 8』软件项目进度安排与跟踪,一招学会计算关键路径

『软件工程 9』结构化系统分析——解决软件“做什么”问题

『软件工程 10』结构化系统分析:数据流图和数据字典案例分析

『软件工程 11』结构化系统设计:解决软件“怎么做”问题

『软件工程 12』软件工程实践方法——软件测试

『软件工程 13』浅谈面向对象方法,统一建模语言 UML

软件测试

『软件测试 1』你需要了解的软件测试基础知识

『软件测试 2』 关于黑盒测试和测试用例的基础知识

『软件测试 3』八大典型的黑盒测试方法已来袭,快快接住!

『软件测试 4』一文详解四大典型的白盒测试方法

『软件测试 5』测开岗只要求会黑白盒测试?NO!还要学会性能测试!

『软件测试 6』bug 一两是小事,但安全漏洞是大事!

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Template/Notion/001.html b/column/Template/Notion/001.html index 58cbfee8..aa7d33a1 100644 --- a/column/Template/Notion/001.html +++ b/column/Template/Notion/001.html @@ -19,7 +19,7 @@
Skip to content

年度工作流封面图

⏳ 叮咚

新年新景新气象,虎年也要有自己 owner 的个人数据库 📝

寒假整理完自己的工作内容,并用 notion 搭建完自己的年度工作流。

去年三月份的时候开始做时间管理,刚开始用的是纸质档的,但后来慢慢发现有点冗余,有时候出门还需要带纸张记录,会稍显麻烦。于是挖掘到了 notion 这个软件~💡

刚接触 notion 的时候,感觉好难用啊……🥶

不过,notion 真的是一入坑深似海,用了以后其他软件都不想用了。

notion 的好处在于 diy 能力非常强大,可以肆无忌惮的嵌套 block 和打造各种精美模板。

当然,一开始要马上就能做年度计划是不太可能的。

我从每日计划开始,再到每周计划,月度计划。直到最近搭建年度工作流的时候,增加了季度计划和年度计划。

🌸🌸🌸

🖼️ 模板先知晓

我们下来看看用 notion 搭建完成的模板是什么样的?😜 请看下方:

notion模板

📚 搭建灵感

那我的搭建这套模板的灵感来源于哪里呢?

👇 第一步:学习别人先进的思想

搜刮各种优质博主的精美模板,在获得到模板之后,尝试着学习他们在搭建这个模板时候的思想,比如说:为什么 xx 区域会有这样的工作流存在。找到适合自己的工作流部分,将其运用到自己搭建的模板中,也就是取其精华,去其糟粕。

👇 第二步:增添属于自己的工作流

借鉴了别人的工作流之后,接下来就是搭建真正属于自己的工作流。刚刚我们已经搭建了基础框架,接下来呢,就是来让模板变得更加饱满。因此,我把去年已经搭建过的一些关于时间管理和计划可视化的工作流放到对应的模块中,比如专注时间、压力事件、xxx 和月复盘总结模板。这样,整个工作流从计划到复盘一整个流程下来,就清晰了许多。

👇 第三步:美化模板

最后,我们基本上就把框架搭建完毕啦!接下来要做的是美化工作。要知道,一个模板的耐用性取决于它的美观度和高效度。 这个时候就把我们平常经常打开的内容给放超链接到首页当中,方便及时查看和进行链接跳转。 同时,太空白的部分就可以选择一些治愈系一点的图片,给插入到模板中,让整个页面更加具有层次感和更亮眼。 📑📑📑

好啦,到这里关于年度工作流的介绍就结束了!希望笔记对大家有帮助呀~

🗂️ 特别鸣谢

1️⃣notion 灵感:KrimSnow

2️⃣ 时间管理:进击中的多乐、大萌总 MENG

模板中的部分灵感来源于以上博主,大家可以到相关博主个人主页挖掘更多宝藏哦!

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Template/Notion/002.html b/column/Template/Notion/002.html index b56740fe..d1c9027d 100644 --- a/column/Template/Notion/002.html +++ b/column/Template/Notion/002.html @@ -19,7 +19,7 @@
Skip to content

一、焦虑产生的原因

大家会不会经常有存在这样的焦虑,感觉每天做了很多事,又好像没做什么事。比如说:一天 7 点去图书馆,晚上 9 点回来。即便是这样,也有可能心里会觉得空落落的。

然而,人之所以会有这种焦虑产生,是因为想的太多,而做得太少

因此,我们需要对自己一天所做的事情有一个有效的规划和复盘,要明确地看到自己一天的产出,才有可能更好的摆脱当下存在的焦虑,否则,很容易因为计划太庞大毫无头绪的目标而导致计划永远都是「明天再说吧」。

二、每日计划应该考虑的因素

那对于每日计划时间表来说,我们要做到哪几点呢?以下 5 点值得注意:

明确每天的有效学习时间;

制定学习计划和列出琐碎事项;

记录有效时间;

统计专注时间;

复盘总结。

三、拆解每日计划运作模式

针对以上这 5 点,接下来将拆解其在我的每日计划时间表中的运作模式。首先先来瞅瞅我在 notion 中的每日计划表是什么样的,如下图:

每日计划运作模式

第一点:明确每天的有效学习时间

如上图所示,大家可以看到这个表格的最左侧,我把每天的时间分为早起阶段早上阶段下午阶段晚上阶段各阶段的安排如下:

  • 早起阶段 6:00-9:00:成长型事项(成长)
  • 早上阶段 9:00-12:00:脑力任务,优先事项(执行)
  • 下午阶段 14:00-18:00:执行型任务(执行)
  • 晚上阶段 18:00-22:00:个人事项(娱乐)

如下图所示:

有效学习时间

第二点:制定学习计划和列出琐碎事项

在前一天或者每天的早晨时间,先列好自己隔天要做的事情。值得一提的是,计划不要列的太满,否则很容易出现未按要求完成而导致心理大落差。比如我的做法是:列出今天的琐碎事项,像春节期间要走亲戚,那么我会先把**「晚上去 xxx 亲戚家拜年」**放到我的琐碎事项中,这样我就能知道今天的晚上阶段不宜安排任务。

接下来就是填充早起早上下午的任务,通常我会按照时间段进行分配,并且每个时间段会给自己安排「30min 左右」的间歇时间,来处理手机的信息、大脑稍作休息、停下来喝杯水等等。如下图所示:

琐碎事项和一天任务

第三点:记录有效时间和产出效能

计划制定完成后,接下来就是对每一项任务进行记录。记住,要学会动态调整任务。比如当我早上单词和外刊学习完成之后,发现时间已经到 9 点了,这个时候要权衡中级和 vue3 之间的学习哪个更为重要。如果说今天 vue3 需要产出一定的内容出来,而中级的进度稍慢一天也没关系,那么我会果断把中级的进度延后,这个时间点尽快开始学习 vue3,这一点可以说是产出价值最大化最终时间记录为:

产出价值最大化

大家有没有发现,时间的最右边部分,是产出效能。产出效能一共分为四种类型,无效能低效能中效能高效能

当下任务完成时,要考虑自己的产出。四种产出结果分析如下:

  • 无效能 —— 如果时间花出去了,但是没有产出;
  • 低效能 —— 有一点产出,但是没有达到自己的预期;
  • 中效能 —— 产出与自己预期的结果一样;
  • 高效能 —— 产出比自己预期的结果好。

第四点:统计专注时间

接下来是统计每天学习的专注时间。在表格中,左侧我们只需要写好开始时间和结束时间,时间统计那一栏就会帮我们把每个阶段的时间进行统计。在一天的最后,我们就把这几个时间计算一下,给放到右侧的学习时长如下图所示:

统计专注时间

第五点:复盘总结

到这里,一天的任务就结束啦!接下来我们要对一天的计划做复盘总结,复盘总结可以是写今天做得好的、值得表扬的;也可以写做得不够好的、存在不足需要改进的。

这一块内容放到最后侧的原因和反思模块,比如就像上面的计划,我可以做出以下几点原因和反思:

  • 因为睡懒觉,导致早上中级的内容没来得及学习!!要注意闹钟响起就应该起了。
  • 小红书第二篇笔记还差最后收尾阶段,明天再花一点时间来写。
  • 毕设 OKR 第二期完成,接下来尽快把任务放上排期,争取在 3 月前完成所有内容。
  • 在 vue3 的学习中,遇到坑的时候,要学会先看报错,而不要直接百度找答案,不然很容易养成自己的惰性思维,这对自己是非常不好的,要引起重视!

最终计划表填充如下:

复盘总结

好了,到这里完成了一天的任务和复盘总结。反思和总结是为了在往后的工作中,避免不必要的重复工作,同时也让自己对日常一些同类型事物的运作流程更加熟悉,不断提升自己的工作效率

四、从焦虑中解救出来

可能大家刚看到这份每日计划的时候,会觉得有点冗余。而这份计划对于当时刚开始接触的我来说,我也会觉得很麻烦,觉得做计划的时间比学习的时间还长。

但在我开始用这份模板的时候,慢慢地我可以看出,一天中的哪些时间自己在摸鱼哪些时间该学习而沉迷于社交软件……。当在表格中反思出自己的问题后,就会有一种莫名的罪恶感。紧接着,我会思考这些摸鱼的时间应该怎么样去更合理的分配到有意义的事情中,让自己每天过的更充实,慢慢戒掉手机瘾

当能够熟悉使用这套模板的时候,做计划所花的时间在5-10min 左右,一天结束时再花10-15min的时间来复盘。随着时间的推移,慢慢变自律,生活也会过的更加充实。

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Template/index.html b/column/Template/index.html index 9d5cf818..a85bfe50 100644 --- a/column/Template/index.html +++ b/column/Template/index.html @@ -19,7 +19,7 @@
Skip to content

序言

本专栏旨在打造各种各种各样的学习干货模板,包括但不限于 notion 模板、数据可视化模板等等。各类别模板如下所示 👇

文章收录

Notion 模板

001-2022 自律有戏了!使用 notion 搭建属于自己 2022 的年度工作流

002-摆脱看不见的焦虑,notion 搭建超高效率的每日计划工作流

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Travel/EastChina/JiangXi.html b/column/Travel/EastChina/JiangXi.html index 2d24119d..282ecdf0 100644 --- a/column/Travel/EastChina/JiangXi.html +++ b/column/Travel/EastChina/JiangXi.html @@ -19,7 +19,7 @@
Skip to content

江西·游记

叮咚

自国庆后,兜兜转转忙碌了两周,这会脑袋突然灵光炸现,想写篇国庆出行的游记。今年的国庆,周一去了趟江西找好朋友ponyo。那么在聊游玩心得之前,首先先回到了**“国庆”**这个节日本身。 $$ 回想周一过去几年的国庆,高中三年的国庆可能献给了学习。到大一的时候,国庆去了一趟厦门。大二的时候,在实验室coding。大三的时候,那会疫情很严重,国庆的假期记得好像被学校缩水了,于是也在学校度过。大四的时候,好像又刚好遇到了闽城疫情很严重的时候,也是一个足不出校的日子。

直到今年,拥有了第一个较为完成的国庆周期。下面就来谈谈,国庆的7天里,周一都经历了些啥和干了些啥。

抢不到票

看到顶上这个大标题,应该就可以猜测出会聊些啥了。以前从学校回家的那条高铁路线,从来都不拥挤。以至于每回周一从学校回家的时候,都是前一天看一下想要哪个时间段的,然后再直接选坐席,即可马上出票。于是乎,周一对抢票这个事儿,心里从来没有过任何概念,我觉得去哪都是前几天稍微买一下就可以了。

然而,现实总是残酷的。9月中旬的时候,ponyo就跟我说,早点抢票,我那会其实还是有点不以为然的,还觉得ponyo有点大惊小怪。于是到9.22的时候,突然间想起这件事,我就打开了携程软件开始看票。诚然,10.01的票基本都被抢光了。但当时的我其实感觉app后续大概率还会放票,所以就放着在那里抢。本来想着10.01可以顺利出行,结果到10.01出行那天的前2h,印象很深是早上的 6:53app 退了款到微信,宣告抢票失败。

那会的我开始对抢票这个事慌了起来,于是开始看各种中转可能到达的路径。抢了一天,宣告10月1日当天注定无票可出行。还因为抢和退太多次,被12306禁用了账号一天🤐。

1日的晚上,又用了 poyno 的账号看了下2日和3日的中转票,最终抢到了2日下午的中转票,从杭州转到南昌。事后 ponyo 说:真的是皇帝不急太监急。

一番折腾后,我又去查了下高铁票的发售时间,节假日的票一般需要提前15天抢票。

PS:春节回家的票我一定好好抢…(不敢乱来了)

image-20221019223324812

人在赣城

囧记

2日到江西后,第一件事是去找 ponyoponyo 原来说要来接我,到后来,因为她的核酸报告超过了 72小时 ,被关在了校内。于是乎,第一天的囧记是,在南大门口吹了 2h 寒风等 poyno 核酸有报告后再出来。如果要我说现代生活最遥远的距离是什么,那莫过于我的核酸正常,而你的核酸超过了72小时。

2日见到ponyo后,那会已然是晚上9点半。于是我们回到了 ponyo uncle 家,吃了外婆做好的饭。2日结束ing~

接下来几天的江西游玩记,大概可以概括为:当一个零规划选手遇到一个小规划选手,那就是完美的游玩计划了👇🏻

因为 ponyo 在江西,所以我感觉她会比我熟悉很多。于是周一带着休假的心情+毫无规划的心态,去了赣城。

3-6日,我们俩处在一种什么状态呢?早上修图发pyq、下午开始梳妆打扮、傍晚出门产图👀

值得一说的是,国庆的江西,前三天的天气直临40度高温,后面几天又突然爆降。

游玩ing~

3日下午,我们俩在家里学习了一小会(因为天气实在太热了,完全不想出门系列)。傍晚后出门,去了江西省博物馆和紫荆夜市。

省博物馆

4日,去了趟南大,或者说是,骑着小电驴在南大游玩的一天。

南大校门

5日,我们傍晚出门去找摄影师,之后去了滕王阁府拍汉服写真🎇。

滕王阁

6日,在南大附近吃了东北菜,打卡了南昌之星摩天轮,还去了趟万象城。值得一提的是,6日下午在家里的时候,舅舅对弟弟妹妹国庆期间作业的鼓励式辅导,被认真地熏陶到辽~

找不到摩天轮的风景照,这张先将就着~~~

南昌之星

回沪

3-6日游玩结束后,到了7日也要收心回沪搬砖啦!6号在南昌的最后一晚 uncle 请吃了南昌的特色菜,7号临回沪前的早班车,外婆还起早做了早餐。赶动车前,外婆还装了牛奶和茶叶蛋让我放包里💕

赣游总结

结语

南昌是一座很红很砖的城市,在这里,曾经诞生过很多历史人物和发生过很多历史事件。经过它的每一个地方,八一广场、红谷滩等等,都有一种中学时遨游于历史书的感觉。

如果让我重新定义这次旅行,我想我可以再给它几个副标题:

  • 《国庆江西抢票囧记之春节回家一定好好抢票》

  • 《当零规划选手遇到了小规划选手》

  • 《十一在一个又红又砖的城市旅行是什么体验》

Last updated:

Released under the MIT License.

- + \ No newline at end of file diff --git a/column/Travel/index.html b/column/Travel/index.html index 6d93ab38..553856b5 100644 --- a/column/Travel/index.html +++ b/column/Travel/index.html @@ -19,7 +19,7 @@
Skip to content

序言

本栏目将记录周一的一些旅游记呀~📝

文章收录

华东地区

游记 | 一趟又红又砖的城市·江西

华南地区

小编正在快马加鞭赶文章中……

华北地区

小编正在快马加鞭赶文章中……

Released under the MIT License.

- + \ No newline at end of file diff --git a/hashmap.json b/hashmap.json index d2dc8654..a0847edd 100644 --- a/hashmap.json +++ b/hashmap.json @@ -1 +1 @@ -{"column_algorithm_001_stack.md":"10f1a97b","column_algorithm_002_queue.md":"a373ca9d","column_algorithm_003_linkedlist.md":"dcbbdc69","column_algorithm_004_dictionary.md":"fb30ccb3","column_algorithm_005_tree.md":"1f7bbd24","column_algorithm_006_graph.md":"8c589ee6","column_algorithm_index.md":"3acf1728","column_backend_index.md":"e9d87de1","column_algorithm_009_greedy.md":"2cb85f56","column_algorithm_008_dynamics.md":"fe79c113","column_backend_node_003_graffitiboard.md":"a15fc2d6","column_backend_node_001_deploy.md":"6d587c1d","column_backend_node_002_fullstack.md":"f845e9a9","column_basecommand_macshortcutkey_002_macos.md":"65e652bc","column_basecommand_macshortcutkey_005_typora.md":"5a89faae","column_basecommand_macshortcutkey_007_git.md":"68984e9d","column_basecommand_index.md":"ba24ce13","column_basecommand_winshortcutkey_001.md":"8fa1e2ea","column_basecommand_macshortcutkey_008_linux.md":"6aa4e91a","column_basecommand_macshortcutkey_001_vscode.md":"85a13801","column_basecommand_winshortcutkey_003.md":"06b68605","column_basecommand_macshortcutkey_004_google.md":"40392fd2","column_basecommand_macshortcutkey_003_console.md":"7a90960d","column_basecommand_macshortcutkey_006_notion.md":"ed5e962e","column_computerknowledge_index.md":"60da1784","column_basecommand_macshortcutkey_009_lark.md":"4b7caaf2","column_basecommand_winshortcutkey_002.md":"2f8cad1c","column_algorithm_010_search.md":"3f3282c7","column_computerknowledge_browser_001.md":"9c17fdeb","column_basecommand_winshortcutkey_004.md":"5ae17ddc","column_computerknowledge_browser_002.md":"ae340f68","column_deeplearning_index.md":"7446deee","column_computerknowledge_security_001.md":"03357227","column_algorithm_007_heap.md":"f1a0f2a9","column_computerknowledge_performanceoptimization_001.md":"b451d381","column_frontend_css_002.md":"fa2d58e5","column_frontend_css_001.md":"92ae77ab","column_frontend_javascript_001.md":"2f9dfa24","column_frontend_javascript_002.md":"1c338222","column_frontend_componentlib_001.md":"f712d05b","column_frontend_javascript_004.md":"42b3974e","column_frontend_javascript_007.md":"3df370d5","column_frontend_javascript_006.md":"f22dcb29","column_frontend_javascript_005.md":"2f2787bd","column_frontend_javascript_003.md":"18e172aa","column_frontend_componentlib_002.md":"888dd3ea","column_frontend_javascript_010.md":"7ae2dd6f","column_frontend_javascript_008.md":"e0088426","column_frontend_react_002.md":"38d79595","column_frontend_react_001.md":"3aee6e01","column_frontend_practice_001.md":"85cbfb54","column_frontend_javascript_009.md":"b02913bc","column_frontend_translation_001.md":"f3b4de21","column_frontend_react_003.md":"9b5f7c6a","column_frontend_react_005.md":"84c16fee","column_frontend_react_004.md":"d534109e","column_frontend_typescript_003_tsintro2.md":"000ff97c","column_frontend_typescript_002_tsdecorator.md":"7217bedc","column_frontend_typescript_001_tsintro.md":"f02c14ba","column_frontend_vue_002.md":"0fb0b662","column_frontend_vue_003.md":"6ec2f6cc","column_frontend_vue_001.md":"ce7b73cd","column_frontend_vue_005.md":"5f462f64","column_frontend_vue_004.md":"bf209d98","column_frontend_vue_007.md":"f2dc050d","column_frontend_vue_008_vue3api.md":"823a6437","column_frontend_vue_006.md":"f272e9b6","column_frontend_vue_009_vitepress_blog.md":"bc20da02","column_frontend_vueprinciple_001.md":"48305edc","column_frontend_vueprinciple_003.md":"a53f8efc","column_frontend_vueprinciple_002.md":"fc15c149","column_frontend_vueprinciple_004.md":"fe011f12","column_frontend_webpack_001.md":"53aea34d","column_frontend_webpack_002.md":"2987c881","column_frontend_webpack_003.md":"66ce845a","column_frontend_webpack_004.md":"77928cc7","column_frontend_webpack_005.md":"193b51d5","column_frontend_youthcamp_001.md":"25114d40","column_frontend_youthcamp_003.md":"546d29cc","column_frontend_youthcamp_002.md":"6dfc9f8c","column_frontend_youthcamp_005.md":"19da351d","column_frontend_youthcamp_006.md":"a93a99f2","column_frontend_youthcamp_004.md":"7a6b692f","column_frontend_youthcamp_008.md":"db92e179","column_frontend_youthcamp_009.md":"31396407","column_frontend_index.md":"4521f7b8","column_frontend_youthcamp_011.md":"9aa1cc69","column_frontend_youthcamp_010.md":"e3391c45","column_growing_reviewsummary_001.md":"ae0b41b9","column_growing_reviewsummary_002.md":"6e9aec5d","column_frontend_youthcamp_007.md":"8195e127","column_growing_yearsummary_001.md":"d2fe96b6","column_growing_reviewsummary_003.md":"539bb1d5","column_growing_yearsummary_002.md":"234738c3","column_growing_index.md":"22e760dd","column_guide_index.md":"e34e7377","column_interview_csswriting.md":"ba99e374","column_interview_datastructure.md":"74de9ec8","column_interview_designmode.md":"eaba36e5","column_interview_development.md":"0c3c5219","column_interview_browser.md":"3527cff1","column_interview_jswriting.md":"e2392b92","column_interview_html5.md":"9d758981","column_interview_css.md":"0024a8ad","column_interview_leetcode.md":"dd87f6ab","column_interview_node.md":"37b08b60","column_interview_network.md":"a2a54436","column_interview_typescript.md":"296765e8","column_interview_operatingsystem.md":"2ca6c2a0","column_interview_react.md":"058ef395","column_interview_performance.md":"25d981d2","column_interview_webpack.md":"378244a0","column_interview_index.md":"e57f0cde","column_machinelearning_index.md":"3046cd08","column_machinelearning_tensorflow_01_mlbase.md":"0282e43b","column_interview_vue.md":"a3738d58","column_interview_javascript.md":"f29c2cc9","column_otherlang_php_002.md":"7363373e","column_otherlang_php_003.md":"5a1d4c24","column_otherlang_php_001.md":"b42464b2","column_otherlang_index.md":"4ce4aeff","column_product_softwareengineer_000guide.md":"8ffa12b1","column_product_softwareengineer_001definition.md":"1c18824c","column_product_softwareengineer_003prototype.md":"46e6e328","column_product_softwareengineer_004product.md":"ea7bea7e","column_product_softwareengineer_002processmodel.md":"1f559e65","column_product_softwareengineer_005measure.md":"1800e345","column_product_softwareengineer_008schedule.md":"0a26e624","column_product_softwareengineer_010dataflowdiagram.md":"9ac5cf62","column_product_softwareengineer_009structuredanalysis.md":"411a8ac2","column_product_softwareengineer_006scope.md":"fa91b523","column_product_softwareengineer_007riskanalysis.md":"fddf1467","column_product_softwareengineer_index.md":"2c18cd9f","column_product_softwaretesting_002.md":"5fbd374e","column_product_softwareengineer_012softwaretest.md":"4ccda692","column_product_softwareengineer_013uml.md":"fd5dc3b3","column_product_softwaretesting_001.md":"f0fadff0","column_product_softwareengineer_011structureddesign.md":"3b1ff408","column_product_index.md":"b3d901cf","column_product_softwaretesting_005.md":"c00bedc6","column_template_index.md":"7fbfe950","column_template_notion_002.md":"e7042aeb","column_travel_index.md":"6b55aa0b","index.md":"9fbe7df7","column_product_softwaretesting_003.md":"618df137","column_template_notion_001.md":"1e3faabf","column_travel_eastchina_jiangxi.md":"16396ec3","column_product_softwaretesting_006.md":"d90818e4","column_product_softwaretesting_004.md":"9bb84234","column_otherlang_android_001.md":"8e47639a"} +{"column_algorithm_002_queue.md":"a373ca9d","column_algorithm_001_stack.md":"10f1a97b","column_algorithm_003_linkedlist.md":"dcbbdc69","column_algorithm_004_dictionary.md":"fb30ccb3","column_algorithm_006_graph.md":"8c589ee6","column_algorithm_009_greedy.md":"2cb85f56","column_algorithm_index.md":"3acf1728","column_backend_index.md":"e9d87de1","column_algorithm_008_dynamics.md":"fe79c113","column_basecommand_winshortcutkey_001.md":"8fa1e2ea","column_basecommand_macshortcutkey_008_linux.md":"6aa4e91a","column_basecommand_winshortcutkey_002.md":"2f8cad1c","column_basecommand_macshortcutkey_009_lark.md":"4b7caaf2","column_basecommand_index.md":"ba24ce13","column_basecommand_winshortcutkey_004.md":"5ae17ddc","column_basecommand_macshortcutkey_001_vscode.md":"85a13801","column_backend_node_001_deploy.md":"6d587c1d","column_algorithm_005_tree.md":"1f7bbd24","column_basecommand_winshortcutkey_003.md":"06b68605","column_algorithm_010_search.md":"3f3282c7","column_backend_node_002_fullstack.md":"f845e9a9","column_basecommand_macshortcutkey_003_console.md":"7a90960d","column_computerknowledge_browser_001.md":"9c17fdeb","column_basecommand_macshortcutkey_005_typora.md":"5a89faae","column_basecommand_macshortcutkey_006_notion.md":"ed5e962e","column_basecommand_macshortcutkey_007_git.md":"68984e9d","column_basecommand_macshortcutkey_004_google.md":"40392fd2","column_backend_node_003_graffitiboard.md":"a15fc2d6","column_basecommand_macshortcutkey_002_macos.md":"65e652bc","column_deeplearning_index.md":"7446deee","column_computerknowledge_browser_002.md":"ae340f68","column_computerknowledge_index.md":"60da1784","column_computerknowledge_security_001.md":"03357227","column_algorithm_007_heap.md":"f1a0f2a9","column_computerknowledge_performanceoptimization_001.md":"b451d381","column_frontend_css_002.md":"fa2d58e5","column_frontend_css_001.md":"92ae77ab","column_frontend_javascript_001.md":"2f9dfa24","column_frontend_componentlib_001.md":"f712d05b","column_frontend_javascript_002.md":"1c338222","column_frontend_javascript_004.md":"42b3974e","column_frontend_javascript_006.md":"f22dcb29","column_frontend_javascript_007.md":"3df370d5","column_frontend_javascript_003.md":"18e172aa","column_frontend_javascript_005.md":"2f2787bd","column_frontend_componentlib_002.md":"888dd3ea","column_frontend_javascript_010.md":"7ae2dd6f","column_frontend_javascript_008.md":"e0088426","column_frontend_react_002.md":"38d79595","column_frontend_react_001.md":"3aee6e01","column_frontend_practice_001.md":"85cbfb54","column_frontend_translation_001.md":"f3b4de21","column_frontend_typescript_003_tsintro2.md":"000ff97c","column_frontend_javascript_009.md":"b02913bc","column_frontend_react_003.md":"9b5f7c6a","column_frontend_typescript_002_tsdecorator.md":"7217bedc","column_frontend_vue_002.md":"0fb0b662","column_frontend_react_005.md":"84c16fee","column_frontend_typescript_001_tsintro.md":"f02c14ba","column_frontend_vue_003.md":"6ec2f6cc","column_frontend_vue_005.md":"5f462f64","column_frontend_vue_008_vue3api.md":"823a6437","column_frontend_vue_007.md":"f2dc050d","column_frontend_vue_006.md":"f272e9b6","column_frontend_react_004.md":"d534109e","column_frontend_vue_004.md":"bf209d98","column_frontend_vue_001.md":"ce7b73cd","column_frontend_vueprinciple_004.md":"fe011f12","column_frontend_vueprinciple_001.md":"48305edc","column_frontend_vue_009_vitepress_blog.md":"bc20da02","column_frontend_vueprinciple_003.md":"a53f8efc","column_frontend_vueprinciple_002.md":"fc15c149","column_frontend_webpack_004.md":"77928cc7","column_frontend_webpack_002.md":"2987c881","column_frontend_webpack_003.md":"66ce845a","column_frontend_webpack_001.md":"53aea34d","column_frontend_youthcamp_003.md":"546d29cc","column_frontend_youthcamp_001.md":"25114d40","column_frontend_webpack_005.md":"193b51d5","column_frontend_youthcamp_002.md":"6dfc9f8c","column_frontend_youthcamp_006.md":"a93a99f2","column_frontend_youthcamp_005.md":"19da351d","column_growing_yearsummary_001.md":"d2fe96b6","column_growing_reviewsummary_003.md":"539bb1d5","column_frontend_index.md":"4521f7b8","column_frontend_youthcamp_011.md":"9aa1cc69","column_growing_reviewsummary_001.md":"ae0b41b9","column_guide_index.md":"e34e7377","column_growing_yearsummary_002.md":"234738c3","column_growing_index.md":"22e760dd","column_growing_reviewsummary_002.md":"6e9aec5d","column_frontend_youthcamp_008.md":"db92e179","column_frontend_youthcamp_009.md":"31396407","column_frontend_youthcamp_010.md":"e3391c45","column_frontend_youthcamp_007.md":"8195e127","column_frontend_youthcamp_004.md":"7a6b692f","column_interview_browser.md":"3527cff1","column_interview_csswriting.md":"ba99e374","column_interview_designmode.md":"eaba36e5","column_interview_datastructure.md":"74de9ec8","column_interview_development.md":"0c3c5219","column_interview_jswriting.md":"e2392b92","column_interview_html5.md":"9d758981","column_interview_css.md":"0024a8ad","column_interview_leetcode.md":"dd87f6ab","column_interview_node.md":"37b08b60","column_interview_network.md":"a2a54436","column_interview_operatingsystem.md":"2ca6c2a0","column_interview_typescript.md":"296765e8","column_interview_react.md":"058ef395","column_interview_performance.md":"25d981d2","column_interview_webpack.md":"378244a0","column_interview_index.md":"e57f0cde","column_machinelearning_tensorflow_01_mlbase.md":"0282e43b","column_machinelearning_index.md":"3046cd08","column_interview_vue.md":"a3738d58","column_interview_javascript.md":"f29c2cc9","column_otherlang_php_002.md":"7363373e","column_otherlang_php_001.md":"b42464b2","column_otherlang_php_003.md":"5a1d4c24","column_otherlang_index.md":"4ce4aeff","column_product_softwareengineer_000guide.md":"8ffa12b1","column_product_softwareengineer_001definition.md":"1c18824c","column_product_softwareengineer_003prototype.md":"46e6e328","column_product_softwareengineer_004product.md":"ea7bea7e","column_product_softwareengineer_002processmodel.md":"1f559e65","column_product_softwareengineer_005measure.md":"1800e345","column_product_softwareengineer_007riskanalysis.md":"fddf1467","column_product_softwareengineer_006scope.md":"fa91b523","column_product_softwareengineer_008schedule.md":"0a26e624","column_product_softwareengineer_009structuredanalysis.md":"411a8ac2","column_product_softwareengineer_010dataflowdiagram.md":"9ac5cf62","column_product_softwareengineer_012softwaretest.md":"4ccda692","column_product_softwareengineer_011structureddesign.md":"3b1ff408","column_product_softwareengineer_index.md":"2c18cd9f","column_product_softwareengineer_013uml.md":"fd5dc3b3","column_product_softwaretesting_002.md":"5fbd374e","column_product_softwaretesting_001.md":"f0fadff0","column_otherlang_android_001.md":"8e47639a","column_product_softwaretesting_003.md":"618df137","column_product_softwaretesting_004.md":"9bb84234","column_product_softwaretesting_005.md":"c00bedc6","column_product_index.md":"b3d901cf","column_product_softwaretesting_006.md":"d90818e4","column_template_notion_001.md":"1e3faabf","column_template_notion_002.md":"e7042aeb","column_template_index.md":"7fbfe950","column_travel_index.md":"6b55aa0b","column_travel_eastchina_jiangxi.md":"16396ec3","index.md":"9fbe7df7"} diff --git a/index.html b/index.html index 93a68c2d..c68b1fa4 100644 --- a/index.html +++ b/index.html @@ -19,7 +19,7 @@
Skip to content

周一同学

Stay foolish, Stay hungry.

/斜杠青年/人间清醒/工具控/

avatar

Released under the MIT License.

- + \ No newline at end of file