From 462d8237b81fdcc0ef3c2213581e944e30a6f90f Mon Sep 17 00:00:00 2001 From: yrb <8400040@qq.com> Date: Mon, 13 Feb 2023 16:11:50 +0800 Subject: [PATCH 1/5] '123' --- 123.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 123.txt diff --git a/123.txt b/123.txt new file mode 100644 index 0000000..d800886 --- /dev/null +++ b/123.txt @@ -0,0 +1 @@ +123 \ No newline at end of file -- Gitee From d18c1e164f818d0d648e1028de4b470f00dc00ad Mon Sep 17 00:00:00 2001 From: yrb <8400040@qq.com> Date: Mon, 13 Feb 2023 16:29:50 +0800 Subject: [PATCH 2/5] '0213' --- 123.txt | 1 - .../1\345\210\235\345\247\213node.md" | 194 ++++++++++++++++++ 2 files changed, 194 insertions(+), 1 deletion(-) delete mode 100644 123.txt create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-13/1\345\210\235\345\247\213node.md" diff --git a/123.txt b/123.txt deleted file mode 100644 index d800886..0000000 --- a/123.txt +++ /dev/null @@ -1 +0,0 @@ -123 \ No newline at end of file diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-13/1\345\210\235\345\247\213node.md" "b/\346\235\250\350\215\243\346\237\217/23-02-13/1\345\210\235\345\247\213node.md" new file mode 100644 index 0000000..00411cf --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-13/1\345\210\235\345\247\213node.md" @@ -0,0 +1,194 @@ +## 微专业 3,4月份会开设微专业 + +### 实施工程师 + +​首先,在整个互联网行业中,主要基石就是研发。研发人员负责软件的开发和需求定制,设计人员负责绘制软件logo、图标和版式,封装完成之后,打成软件包,如.exe、.war等格式的安装包,此时产品完成。销售人员把产品销售给客户后,诞生了一个问题:研发会安装,但是他需要查找漏洞发布补丁或者写新的产品;销售不懂技术,无法教给客户使用。所以有需求才有市场,诞生了一个新的岗位:实施工程师。那么说实施工程师负责的内容,就是把产品的安装包带到客户现场,进行安装和调试,并且教给客户如何使用,不恰当的比喻可以理解为一个经常出差的弱化版的研发。 + +实施开发工程师与软件开发工程师不同,实施开发人员事实上很少接触到项目的编码,主要以数据库的操作,编码存储过程和数据转换为主,因而工作多年后在编码能力上非常弱。但是实施开发工程师极其了解项目的业务逻辑,擅长客户沟通。继而多以需求沟通分析为主,而对于实施工程师而言,多以项目经理与管理行政为发展方向。当然数据库管理员是最理想的职位。 + +### 硬件实施 + +​​首先看到“硬件”二字,有的人可能会理解为干体力活,搬东西。其实不然,举个最简单的例子:个人电脑上的QQ,是软件,如果你把QQ.exe带到客户现场,没有服务器等硬件设备作为支撑的话软件也是无法安装运行的。所以,硬件实施的职责,就是负责把硬件设备带到客户现场进行安装调试,中间可能会需要体力付出,比如拉货,但是大部分情况下是不需要的。当然,货拉来摆上并不意味着完了,硬件实施也需要一定的软件基础,举个例子:你新买一台无系统的电脑,是需要装操作系统的,涉及到硬盘分区、系统引导等知识。所以,硬件实施也是需要了解软件知识,简单的如:系统安装,稍微难的,例如:交换机的调试、防火墙的配置等。所以,想要从事硬件实施工程师,你可以不会SQL语句等操作,但是必须要会Linux等指令型的知识。 + + +### 软件实施 + +当硬件实施将客户现场的硬件环境搭建好之后,就到了软件实施大显身手的时刻。首先,就系统软件层来讲,可能操作系统为Windows、也可能为Linux,所以软件实施要懂得系统的基本操作、指令以及一些简单问题的处理;其次,产品本身要存放数据的,所以要学会对数据库的使用,由于大部分实施工程师的权限不够高,所以只需要掌握基本的查询语句即可,当然,要想在这一行有个更好的发展,一些高级用法,比如:存储过程、触发器、索引等也是需要会写,这个是后话;然后,在软件实施工作时,硬件实施应该离开客户现场了,这时也需要掌握一些常见的硬件问题排查,比如Windows蓝屏代码阅读、网络无法连接等;最后,客户可能会需要一些文档,比如培训PPT、实施方案等,所以,也需要对office办公软件有一定的知识掌握。 + + +### 运维工程师 + + +在谈及运维工程师之前,首先了解一个软件行业的基本概念:厂家、渠道(集成商)和客户:厂家研发产品,但是不会直接售卖给客户,客户购买产品需要进行招标,那么渠道就是中间人。所以在厂家的软件实施、硬件实施都完成工作后,渠道会给客户派运维人员进行售后运维工作。其主要工作内容,就包括:熟知客户软硬件环境、了解客户使用的产品等,所以侧面也说明了,运维工程师需要了解的技术知识要比实施人员更杂,需要了解到多方位的信息,全方位懂得如何排障,以及在无法处理的情况如何及时联系实施人员,确保得到厂家的售后技术支持。总的来说,运维工程师是博众家之长,集大成者。 + + +### 技术支持 + +技术支持这个岗位,相比于前三者而言,属于较为轻松的一个。技术支持一般不需要出差,以在公司办公为主,基本为电话、远程解决客户提出的问题,可以简单理解为实施人员的附属团队,实施人员负责前期安装调试,技术支持人员负责后期简单的问题解答,以及无法处理时联系研发、实施人员获得解决办法。所以需要了解的技术和实施人员相似,在此不做复述。 + +### 测试工程师 + +简单的说就是对开发的项目进行测试,看功能是否能达到产品的业务逻辑. + + +## 课程安排 + +本学期的三门课:node(后端技术) vue(国内最热的前端的框架) webapi(以java的springboot为例) + +7,8月安装实训项目 + + + + +## 什么是node + +从本章开始,我们就正式开启JavaScript的后端开发之旅。 + +Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 + +众所周知,在Netscape设计出JavaScript后的短短几个月,JavaScript事实上已经是前端开发的唯一标准。 + +后来,微软通过IE击败了Netscape后一统桌面,结果几年时间,浏览器毫无进步。(2001年推出的古老的IE 6到今天仍然有人在使用!) + +没有竞争就没有发展。微软认为IE6浏览器已经非常完善,几乎没有可改进之处,然后解散了IE6开发团队!而Google却认为支持现代Web应用的新一代浏览器才刚刚起步,尤其是浏览器负责运行JavaScript的引擎性能还可提升10倍。 + +先是Mozilla借助已壮烈牺牲的Netscape遗产在2002年推出了Firefox浏览器,紧接着Apple于2003年在开源的KHTML浏览器的基础上推出了WebKit内核的Safari浏览器,不过仅限于Mac平台。 + +随后,Google也开始创建自家的浏览器。他们也看中了WebKit内核,于是基于WebKit内核推出了Chrome浏览器。 + +Chrome浏览器是跨Windows和Mac平台的,并且,Google认为要运行现代Web应用,浏览器必须有一个性能非常强劲的JavaScript引擎,于是Google自己开发了一个高性能JavaScript引擎,名字叫V8,以BSD许可证开源。 + +现代浏览器大战让微软的IE浏览器远远地落后了,因为他们解散了最有经验、战斗力最强的浏览器团队!回过头再追赶却发现,支持HTML5的WebKit已经成为手机端的标准了,IE浏览器从此与主流移动端设备绝缘。 + +浏览器大战和Node有何关系? + +话说有个叫Ryan Dahl的歪果仁,他的工作是用C/C++写高性能Web服务。对于高性能,异步IO、事件驱动是基本原则,但是用C/C++写就太痛苦了。于是这位仁兄开始设想用高级语言开发Web服务。他评估了很多种高级语言,发现很多语言虽然同时提供了同步IO和异步IO,但是开发人员一旦用了同步IO,他们就再也懒得写异步IO了,所以,最终,Ryan瞄向了JavaScript。 + +因为JavaScript是单线程执行,根本不能进行同步IO操作,所以,JavaScript的这一“缺陷”导致了它只能使用异步IO。 + +选定了开发语言,还要有运行时引擎。这位仁兄曾考虑过自己写一个,不过明智地放弃了,因为V8就是开源的JavaScript引擎。让Google投资去优化V8,咱只负责改造一下拿来用,还不用付钱,这个买卖很划算。 + +于是在2009年,Ryan正式推出了基于JavaScript语言和V8引擎的开源Web服务器项目,命名为Node.js。虽然名字很土,但是,Node第一次把JavaScript带入到后端服务器开发,加上世界上已经有无数的JavaScript开发人员,所以Node一下子就火了起来。 + +在Node上运行的JavaScript相比其他后端开发语言有何优势? + +最大的优势是借助JavaScript天生的事件驱动机制加V8高性能引擎,使编写高性能Web服务轻而易举。 + +其次,JavaScript语言本身是完善的函数式语言,在前端开发时,开发人员往往写得比较随意,让人感觉JavaScript就是个“玩具语言”。但是,在Node环境下,通过模块化的JavaScript代码,加上函数式编程,并且无需考虑浏览器兼容性问题,直接使用最新的ECMAScript 6标准,可以完全满足工程上的需求 + +## 环境的安装 + + +官网:https://nodejs.org/en/download/ + + +### 怎么判断有没安装成功 + +在cmd终端输入node如果有输出版本信息等则安装成功 + +## 第一个node代码 + +```javascript + +console.log("hello world"); + +``` +## 什么是npm + +npm是什么东东?npm其实是Node.js的包管理工具(package manager),比较新的node(node11以上)都自带了npm. + +为啥我们需要一个包管理工具呢?因为我们在Node.js上开发时,会用到很多别人写的JavaScript代码。如果我们要使用别人写的某个包,每次都根据名称搜索一下官方网站,下载代码,解压,再使用,非常繁琐。于是一个集中管理的工具应运而生:大家都把自己开发的模块打包后放到npm官网上,如果要使用,直接通过npm安装就可以直接用,不用管代码存在哪,应该从哪下载。 + +更重要的是,如果我们要使用模块A,而模块A又依赖于模块B,模块B又依赖于模块X和模块Y,npm可以根据依赖关系,把所有依赖的包都下载下来并管理起来。否则,靠我们自己手动管理,肯定既麻烦又容易出错。 + +### 注意现有的版本(16)的node是自带npm的,早期的版本10的node以下是不带npm + + +## 查看npm的版本 + +```javascript + npm -v + +``` + +## git 工具,码云,github,gitlab(相对少点) git之父:linux之父 + + +git 的分支,初始化的git项目,就一个master分支(主分支),实际开发中会有个developer(开发分支) + +master 是最终分支,developer 开发分支.developer测试没问题,最后再合到master分支 + + + + +### 要记得切分支,master(主分支),工作中会创建一个 developer (开发)分支 + + +master 分支是最终分支,生产环境就用master分支。developer 是开发分支,开发最终都是合并到developer分支 + + +git branch 查看分支,和创建分支(创建分支需要具体给个分支名称) + +git branch 不跟分支名,就显示所以的分支 + +git branch 分支名 创建分支 + + +git checkout '分支名' 切换分支 (提交作业时每个同学自己起一个分支名称) + + +git add 新增文件进行跟踪 + + +commit 和 push 提交跟邱老师之前说的一样 + + +记住不能只建立空文件夹,文件夹要有文件 + + +提交作业时候:在自己码云上提交一个 pr(到master分支) + + + + + + + +## 作业:搭建node环境,三四节课.创建一个自己分支(分支最好是自己的名称) + +## 仓库地址:https://gitee.com/lai123/class7nodehomework/invite_link?invite=7ec51fa0a5171339cd80d606a438442e24450ecfaee0b4c38b40572f73d50c1e5680de527c7c7871e766b0d826817bc9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- Gitee From 3efabc49099c39b8e1bd9c03aa983f6e4f0fbf94 Mon Sep 17 00:00:00 2001 From: yrb <8400040@qq.com> Date: Mon, 13 Feb 2023 16:33:28 +0800 Subject: [PATCH 3/5] '23-02-13' --- .../23-02-13/1\345\210\235\345\247\213node.md" | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-13/1\345\210\235\345\247\213node.md" "b/\346\235\250\350\215\243\346\237\217/23-02-13/1\345\210\235\345\247\213node.md" index 00411cf..3a4bf91 100644 --- "a/\346\235\250\350\215\243\346\237\217/23-02-13/1\345\210\235\345\247\213node.md" +++ "b/\346\235\250\350\215\243\346\237\217/23-02-13/1\345\210\235\345\247\213node.md" @@ -2,13 +2,13 @@ ### 实施工程师 -​首先,在整个互联网行业中,主要基石就是研发。研发人员负责软件的开发和需求定制,设计人员负责绘制软件logo、图标和版式,封装完成之后,打成软件包,如.exe、.war等格式的安装包,此时产品完成。销售人员把产品销售给客户后,诞生了一个问题:研发会安装,但是他需要查找漏洞发布补丁或者写新的产品;销售不懂技术,无法教给客户使用。所以有需求才有市场,诞生了一个新的岗位:实施工程师。那么说实施工程师负责的内容,就是把产品的安装包带到客户现场,进行安装和调试,并且教给客户如何使用,不恰当的比喻可以理解为一个经常出差的弱化版的研发。 +首先,在整个互联网行业中,主要基石就是研发。研发人员负责软件的开发和需求定制,设计人员负责绘制软件logo、图标和版式,封装完成之后,打成软件包,如.exe、.war等格式的安装包,此时产品完成。销售人员把产品销售给客户后,诞生了一个问题:研发会安装,但是他需要查找漏洞发布补丁或者写新的产品;销售不懂技术,无法教给客户使用。所以有需求才有市场,诞生了一个新的岗位:实施工程师。那么说实施工程师负责的内容,就是把产品的安装包带到客户现场,进行安装和调试,并且教给客户如何使用,不恰当的比喻可以理解为一个经常出差的弱化版的研发。 实施开发工程师与软件开发工程师不同,实施开发人员事实上很少接触到项目的编码,主要以数据库的操作,编码存储过程和数据转换为主,因而工作多年后在编码能力上非常弱。但是实施开发工程师极其了解项目的业务逻辑,擅长客户沟通。继而多以需求沟通分析为主,而对于实施工程师而言,多以项目经理与管理行政为发展方向。当然数据库管理员是最理想的职位。 ### 硬件实施 -​​首先看到“硬件”二字,有的人可能会理解为干体力活,搬东西。其实不然,举个最简单的例子:个人电脑上的QQ,是软件,如果你把QQ.exe带到客户现场,没有服务器等硬件设备作为支撑的话软件也是无法安装运行的。所以,硬件实施的职责,就是负责把硬件设备带到客户现场进行安装调试,中间可能会需要体力付出,比如拉货,但是大部分情况下是不需要的。当然,货拉来摆上并不意味着完了,硬件实施也需要一定的软件基础,举个例子:你新买一台无系统的电脑,是需要装操作系统的,涉及到硬盘分区、系统引导等知识。所以,硬件实施也是需要了解软件知识,简单的如:系统安装,稍微难的,例如:交换机的调试、防火墙的配置等。所以,想要从事硬件实施工程师,你可以不会SQL语句等操作,但是必须要会Linux等指令型的知识。 +​首先看到“硬件”二字,有的人可能会理解为干体力活,搬东西。其实不然,举个最简单的例子:个人电脑上的QQ,是软件,如果你把QQ.exe带到客户现场,没有服务器等硬件设备作为支撑的话软件也是无法安装运行的。所以,硬件实施的职责,就是负责把硬件设备带到客户现场进行安装调试,中间可能会需要体力付出,比如拉货,但是大部分情况下是不需要的。当然,货拉来摆上并不意味着完了,硬件实施也需要一定的软件基础,举个例子:你新买一台无系统的电脑,是需要装操作系统的,涉及到硬盘分区、系统引导等知识。所以,硬件实施也是需要了解软件知识,简单的如:系统安装,稍微难的,例如:交换机的调试、防火墙的配置等。所以,想要从事硬件实施工程师,你可以不会SQL语句等操作,但是必须要会Linux等指令型的知识。 ### 软件实施 @@ -152,6 +152,14 @@ commit 和 push 提交跟邱老师之前说的一样 +本地远程云端 + +git branch -r 查看远程的 + +git branch -b 本地分支 origin/远程分支 + +注: 本地分支名最好与远程分支名一样 + ## 作业:搭建node环境,三四节课.创建一个自己分支(分支最好是自己的名称) -- Gitee From c99659b90bae16d401363f12ecb075d8d948af4e Mon Sep 17 00:00:00 2001 From: yrb <84300040@qq.com> Date: Wed, 15 Feb 2023 11:21:02 +0800 Subject: [PATCH 4/5] '02-15' --- .../23-02-15/23-02-15/index.js" | 5 + .../23-02-15/23-02-15/mods.js" | 42 ++++ .../23-02-15/23-02-15/test.js" | 2 + ...50\345\261\200\345\257\271\350\261\241.md" | 114 +++++++++ .../node/1\345\210\235\345\247\213node.md" | 204 ++++++++++++++++ ...344\270\216npm\344\275\277\347\224\250.md" | 96 ++++++++ ...66\350\257\273\345\206\231\344\270\212.md" | 162 +++++++++++++ ...66\350\257\273\345\206\231\344\270\213.md" | 77 +++++++ ...56\345\272\223\346\223\215\344\275\234.md" | 217 ++++++++++++++++++ ...47\232\204http\346\250\241\345\235\227.md" | 53 +++++ ...255\245\345\256\236\347\216\260promise.md" | 131 +++++++++++ .../23-02-15/node/images/1.png" | Bin 0 -> 36026 bytes .../node_express\346\241\206\346\236\2661.md" | 63 +++++ .../node_express\346\241\206\346\236\2662.md" | 117 ++++++++++ .../node_express\346\241\206\346\236\2663.md" | 65 ++++++ .../node_express\346\241\206\346\236\2664.md" | 74 ++++++ .../node/node\347\232\204restfullapi.md" | 19 ++ .../node\351\241\271\347\233\256/test-git" | 1 + .../path.js" | 40 ++++ .../\346\250\241\345\235\227/moduleObj.js" | 18 ++ .../\346\250\241\345\235\227/moudle.js" | 45 ++++ .../\346\250\241\345\235\227/use.js" | 16 ++ .../23-02-15/node/test/express.js" | 0 .../\346\250\241\345\235\227/moduleObj.js" | 18 ++ .../node/\346\250\241\345\235\227/moudle.js" | 45 ++++ .../node/\346\250\241\345\235\227/use.js" | 16 ++ 26 files changed, 1640 insertions(+) create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/23-02-15/index.js" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/23-02-15/mods.js" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/23-02-15/test.js" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/1-1node\347\232\204\345\205\250\345\261\200\345\257\271\350\261\241.md" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/1\345\210\235\345\247\213node.md" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/2\346\250\241\345\235\227\344\270\216npm\344\275\277\347\224\250.md" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/3node\347\232\204\346\226\207\344\273\266\350\257\273\345\206\231\344\270\212.md" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/4node\347\232\204\346\226\207\344\273\266\350\257\273\345\206\231\344\270\213.md" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/5node\347\232\204\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234.md" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/6node\347\232\204http\346\250\241\345\235\227.md" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/7node\347\232\204\345\274\202\346\255\245\345\256\236\347\216\260promise.md" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/images/1.png" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2661.md" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2662.md" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2663.md" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2664.md" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/node\347\232\204restfullapi.md" create mode 160000 "\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/test-git" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\345\205\250\345\261\200\345\257\271\350\261\241/path.js" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\346\250\241\345\235\227/moduleObj.js" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\346\250\241\345\235\227/moudle.js" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\346\250\241\345\235\227/use.js" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/test/express.js" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/\346\250\241\345\235\227/moduleObj.js" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/\346\250\241\345\235\227/moudle.js" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-15/node/\346\250\241\345\235\227/use.js" diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/23-02-15/index.js" "b/\346\235\250\350\215\243\346\237\217/23-02-15/23-02-15/index.js" new file mode 100644 index 0000000..673f0d7 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/23-02-15/index.js" @@ -0,0 +1,5 @@ +// 写个加减乘除的模块(尽量少写暴露,要考虑复用性) +let obj = require("./mods.js"); +obj.obj.change(8,4); +console.log(obj.obj.jia()); + diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/23-02-15/mods.js" "b/\346\235\250\350\215\243\346\237\217/23-02-15/23-02-15/mods.js" new file mode 100644 index 0000000..47c8467 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/23-02-15/mods.js" @@ -0,0 +1,42 @@ +var num1; +var num2; +let obj ={ + change:function(num11,num22){ + num1=num11; + num2=num22; + }, + jia:function(){ + // lastpd(num1,num2); + return num1+num2; + }, + jian:function(){ + return num1-num2; + }, + cheng:function(){ + return num1*num2; + }, + chu:function(){ + return num1/num2; + } +} + + + +// function pd (num1,num2){ +// if(Number(num1)==NaN && Number(num2)==NaN){ +// return 1 +// }else{ +// return 0; +// } +// } +// function lastpd (num1,num2){ +// if(pd(num1,num2)==1){ +// return "只能为数字" +// }else{ + +// } + +// } + +module.exports.obj = obj; +// module.exports.change = change; \ No newline at end of file diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/23-02-15/test.js" "b/\346\235\250\350\215\243\346\237\217/23-02-15/23-02-15/test.js" new file mode 100644 index 0000000..89bc65b --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/23-02-15/test.js" @@ -0,0 +1,2 @@ +var num = "-10" +console.log(Number(num)); \ No newline at end of file diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/1-1node\347\232\204\345\205\250\345\261\200\345\257\271\350\261\241.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/1-1node\347\232\204\345\205\250\345\261\200\345\257\271\350\261\241.md" new file mode 100644 index 0000000..3646d8b --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/1-1node\347\232\204\345\205\250\345\261\200\345\257\271\350\261\241.md" @@ -0,0 +1,114 @@ +## Node.js 全局对象 + +JavaScript 中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量。 + +在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global 对象的属性。 + +在 Node.js 我们可以直接访问到 global 的属性,而不需要在应用中包含它。 + +## 全局对象与全局变量 +global 最根本的作用是作为全局变量的宿主。按照 ECMAScript 的定义,满足以下条 件的变量是全局变量: + +在最外层定义的变量; +全局对象的属性; +隐式定义的变量(未定义直接赋值的变量)。 +当你定义一个全局变量时,这个变量同时也会成为全局对象的属性,反之亦然。需要注 意的是,在 Node.js 中你不可能在最外层定义变量,因为所有用户代码都是属于当前模块的, 而模块本身不是最外层上下文。 + +注意: 最好不要使用 var 定义变量以避免引入全局变量,因为全局变量会污染命名空间,提高代码的耦合风险。 + +## __filename +__filename 表示当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同。 如果在模块中,返回的值是模块文件的路径。 + +## 实例 + +```js + +// 输出全局变量 __filename 的值 +console.log( __filename ); + +``` + +## __dirname + +__dirname 表示当前执行脚本所在的目录。 + + +```js + +// 输出全局变量 __dirname 的值 +console.log( __dirname ); + +``` + +## setTimeout(cb, ms) +setTimeout(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb)。:setTimeout() 只执行一次指定函数。 + +返回一个代表定时器的句柄值。 + +```js + +function printHello(){ + console.log( "Hello, World!"); +} +// 两秒后执行以上函数 +setTimeout(printHello, 2000); + +``` + +## setInterval(cb, ms) + +setInterval(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb)。 + +返回一个代表定时器的句柄值。可以使用 clearInterval(t) 函数来清除定时器。 + +setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。 + +```js + +function printHello(){ + console.log( "Hello, World!"); +} +// 两秒后执行以上函数 +setInterval(printHello, 2000); + +``` + + +## console +console 用于提供控制台标准输出,它是由 Internet Explorer 的 JScript 引擎提供的调试工具,后来逐渐成为浏览器的实施标准。 + +Node.js 沿用了这个标准,提供与习惯行为一致的 console 对象,用于向标准输出流(stdout)或标准错误流(stderr)输出字符 + + + +## process +process 是一个全局变量,即 global 对象的属性。 + +它用于描述当前Node.js 进程状态的对象,提供了一个与操作系统的简单接口。通常在你写本地命令行程序的时候,少不了要 和它打交道。下面将会介绍 process 对象的一些最常用的成员方法。 + +exit +当进程准备退出时触发。 + +beforeExit +当 node 清空事件循环,并且没有其他安排时触发这个事件。通常来说,当没有进程安排时 node 退出,但是 'beforeExit' 的监听器可以异步调用,这样 node 就会继续执行。 + + +uncaughtException +当一个异常冒泡回到事件循环,触发这个事件。如果给异常添加了监视器,默认的操作(打印堆栈跟踪信息并退出)就不会发生。 + + +```js +process.on('exit', function(code) { + + // 以下代码永远不会执行 + setTimeout(function() { + console.log("该代码不会执行"); + }, 0); + + console.log('退出码为:', code); +}); +console.log("程序执行结束"); + +``` + + diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/1\345\210\235\345\247\213node.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/1\345\210\235\345\247\213node.md" new file mode 100644 index 0000000..6e90483 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/1\345\210\235\345\247\213node.md" @@ -0,0 +1,204 @@ +## 微专业 3,4月份会开设微专业 + +### 实施工程师 + +​首先,在整个互联网行业中,主要基石就是研发。研发人员负责软件的开发和需求定制,设计人员负责绘制软件logo、图标和版式,封装完成之后,打成软件包,如.exe、.war等格式的安装包,此时产品完成。销售人员把产品销售给客户后,诞生了一个问题:研发会安装,但是他需要查找漏洞发布补丁或者写新的产品;销售不懂技术,无法教给客户使用。所以有需求才有市场,诞生了一个新的岗位:实施工程师。那么说实施工程师负责的内容,就是把产品的安装包带到客户现场,进行安装和调试,并且教给客户如何使用,不恰当的比喻可以理解为一个经常出差的弱化版的研发。 + +实施开发工程师与软件开发工程师不同,实施开发人员事实上很少接触到项目的编码,主要以数据库的操作,编码存储过程和数据转换为主,因而工作多年后在编码能力上非常弱。但是实施开发工程师极其了解项目的业务逻辑,擅长客户沟通。继而多以需求沟通分析为主,而对于实施工程师而言,多以项目经理与管理行政为发展方向。当然数据库管理员是最理想的职位。 + +### 硬件实施 + +​​首先看到“硬件”二字,有的人可能会理解为干体力活,搬东西。其实不然,举个最简单的例子:个人电脑上的QQ,是软件,如果你把QQ.exe带到客户现场,没有服务器等硬件设备作为支撑的话软件也是无法安装运行的。所以,硬件实施的职责,就是负责把硬件设备带到客户现场进行安装调试,中间可能会需要体力付出,比如拉货,但是大部分情况下是不需要的。当然,货拉来摆上并不意味着完了,硬件实施也需要一定的软件基础,举个例子:你新买一台无系统的电脑,是需要装操作系统的,涉及到硬盘分区、系统引导等知识。所以,硬件实施也是需要了解软件知识,简单的如:系统安装,稍微难的,例如:交换机的调试、防火墙的配置等。所以,想要从事硬件实施工程师,你可以不会SQL语句等操作,但是必须要会Linux等指令型的知识。 + + +### 软件实施 + +当硬件实施将客户现场的硬件环境搭建好之后,就到了软件实施大显身手的时刻。首先,就系统软件层来讲,可能操作系统为Windows、也可能为Linux,所以软件实施要懂得系统的基本操作、指令以及一些简单问题的处理;其次,产品本身要存放数据的,所以要学会对数据库的使用,由于大部分实施工程师的权限不够高,所以只需要掌握基本的查询语句即可,当然,要想在这一行有个更好的发展,一些高级用法,比如:存储过程、触发器、索引等也是需要会写,这个是后话;然后,在软件实施工作时,硬件实施应该离开客户现场了,这时也需要掌握一些常见的硬件问题排查,比如Windows蓝屏代码阅读、网络无法连接等;最后,客户可能会需要一些文档,比如培训PPT、实施方案等,所以,也需要对office办公软件有一定的知识掌握。 + + +### 运维工程师 + + +在谈及运维工程师之前,首先了解一个软件行业的基本概念:厂家、渠道(集成商)和客户:厂家研发产品,但是不会直接售卖给客户,客户购买产品需要进行招标,那么渠道就是中间人。所以在厂家的软件实施、硬件实施都完成工作后,渠道会给客户派运维人员进行售后运维工作。其主要工作内容,就包括:熟知客户软硬件环境、了解客户使用的产品等,所以侧面也说明了,运维工程师需要了解的技术知识要比实施人员更杂,需要了解到多方位的信息,全方位懂得如何排障,以及在无法处理的情况如何及时联系实施人员,确保得到厂家的售后技术支持。总的来说,运维工程师是博众家之长,集大成者。 + + +### 技术支持 + +技术支持这个岗位,相比于前三者而言,属于较为轻松的一个。技术支持一般不需要出差,以在公司办公为主,基本为电话、远程解决客户提出的问题,可以简单理解为实施人员的附属团队,实施人员负责前期安装调试,技术支持人员负责后期简单的问题解答,以及无法处理时联系研发、实施人员获得解决办法。所以需要了解的技术和实施人员相似,在此不做复述。 + +### 测试工程师 + +简单的说就是对开发的项目进行测试,看功能是否能达到产品的业务逻辑. + + +## 课程安排 + +本学期的三门课:node(后端技术) vue(国内最热的前端的框架) webapi(以java的springboot为例) + +7,8月安装实训项目 + + + + +## 什么是node + +从本章开始,我们就正式开启JavaScript的后端开发之旅。 + +Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 + +众所周知,在Netscape设计出JavaScript后的短短几个月,JavaScript事实上已经是前端开发的唯一标准。 + +后来,微软通过IE击败了Netscape后一统桌面,结果几年时间,浏览器毫无进步。(2001年推出的古老的IE 6到今天仍然有人在使用!) + +没有竞争就没有发展。微软认为IE6浏览器已经非常完善,几乎没有可改进之处,然后解散了IE6开发团队!而Google却认为支持现代Web应用的新一代浏览器才刚刚起步,尤其是浏览器负责运行JavaScript的引擎性能还可提升10倍。 + +先是Mozilla借助已壮烈牺牲的Netscape遗产在2002年推出了Firefox浏览器,紧接着Apple于2003年在开源的KHTML浏览器的基础上推出了WebKit内核的Safari浏览器,不过仅限于Mac平台。 + +随后,Google也开始创建自家的浏览器。他们也看中了WebKit内核,于是基于WebKit内核推出了Chrome浏览器。 + +Chrome浏览器是跨Windows和Mac平台的,并且,Google认为要运行现代Web应用,浏览器必须有一个性能非常强劲的JavaScript引擎,于是Google自己开发了一个高性能JavaScript引擎,名字叫V8,以BSD许可证开源。 + +现代浏览器大战让微软的IE浏览器远远地落后了,因为他们解散了最有经验、战斗力最强的浏览器团队!回过头再追赶却发现,支持HTML5的WebKit已经成为手机端的标准了,IE浏览器从此与主流移动端设备绝缘。 + +浏览器大战和Node有何关系? + +话说有个叫Ryan Dahl的歪果仁,他的工作是用C/C++写高性能Web服务。对于高性能,异步IO、事件驱动是基本原则,但是用C/C++写就太痛苦了。于是这位仁兄开始设想用高级语言开发Web服务。他评估了很多种高级语言,发现很多语言虽然同时提供了同步IO和异步IO,但是开发人员一旦用了同步IO,他们就再也懒得写异步IO了,所以,最终,Ryan瞄向了JavaScript。 + +因为JavaScript是单线程执行,根本不能进行同步IO操作,所以,JavaScript的这一“缺陷”导致了它只能使用异步IO。 + +选定了开发语言,还要有运行时引擎。这位仁兄曾考虑过自己写一个,不过明智地放弃了,因为V8就是开源的JavaScript引擎。让Google投资去优化V8,咱只负责改造一下拿来用,还不用付钱,这个买卖很划算。 + +于是在2009年,Ryan正式推出了基于JavaScript语言和V8引擎的开源Web服务器项目,命名为Node.js。虽然名字很土,但是,Node第一次把JavaScript带入到后端服务器开发,加上世界上已经有无数的JavaScript开发人员,所以Node一下子就火了起来。 + +在Node上运行的JavaScript相比其他后端开发语言有何优势? + +最大的优势是借助JavaScript天生的事件驱动机制加V8高性能引擎,使编写高性能Web服务轻而易举。 + +其次,JavaScript语言本身是完善的函数式语言,在前端开发时,开发人员往往写得比较随意,让人感觉JavaScript就是个“玩具语言”。但是,在Node环境下,通过模块化的JavaScript代码,加上函数式编程,并且无需考虑浏览器兼容性问题,直接使用最新的ECMAScript 6标准,可以完全满足工程上的需求 + +## 环境的安装 + + +官网:https://nodejs.org/en/download/ + + +### 怎么判断有没安装成功 + +在cmd终端输入node如果有输出版本信息等则安装成功 + +## 第一个node代码 + +```javascript + +console.log("hello world"); + +``` +## 什么是npm + +npm是什么东东?npm其实是Node.js的包管理工具(package manager),比较新的node(node11以上)都自带了npm. + +为啥我们需要一个包管理工具呢?因为我们在Node.js上开发时,会用到很多别人写的JavaScript代码。如果我们要使用别人写的某个包,每次都根据名称搜索一下官方网站,下载代码,解压,再使用,非常繁琐。于是一个集中管理的工具应运而生:大家都把自己开发的模块打包后放到npm官网上,如果要使用,直接通过npm安装就可以直接用,不用管代码存在哪,应该从哪下载。 + +更重要的是,如果我们要使用模块A,而模块A又依赖于模块B,模块B又依赖于模块X和模块Y,npm可以根据依赖关系,把所有依赖的包都下载下来并管理起来。否则,靠我们自己手动管理,肯定既麻烦又容易出错。 + +### 注意现有的版本(16)的node是自带npm的,早期的版本10的node以下是不带npm + + +## 查看npm的版本 + +```javascript + npm -v + +``` + +## git 工具,码云,github,gitlab(相对少点) git之父:linux之父 + + +git 的分支,初始化的git项目,就一个master分支(主分支),实际开发中会有个developer(开发分支) + +master 是最终分支,developer 开发分支.developer测试没问题,最后再合到master分支 + + + + +### 要记得切分支,master(主分支),工作中会创建一个 developer (开发)分支 + + +master 分支是最终分支,生产环境就用master分支。developer 是开发分支,开发最终都是合并到developer分支 + + +git branch 查看分支,和创建分支(创建分支需要具体给个分支名称) + +git branch 不跟分支名,就显示所以的分支 + +git branch 分支名 创建分支 + +git branch -r 查看远程分支 + +git checkout -b 本地分支 origin/远程分支 创建本地分支并关联远程 + +git branch --set-upstream-to origin/远程分支 本地分支 + +git pull 拉取 + + +git checkout '分支名' 切换分支 (提交作业时每个同学自己起一个分支名称) + + +git add 新增文件进行跟踪 + + + + +commit 和 push 提交跟邱老师之前说的一样 + + +记住不能只建立空文件夹,文件夹要有文件 + + +提交作业时候:在自己码云上提交一个 pr(到master分支) + + + + + + + +## 作业:搭建node环境,三四节课.创建一个自己分支(分支最好是自己的名称) + +## 仓库地址:https://gitee.com/lai123/class5nodehomework/invite_link?invite=7ec51fa0a5171339cd80d606a438442e690736c6f33ca9e38b40572f73d50c1e5f978c4d84091279e766b0d826817bc9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/2\346\250\241\345\235\227\344\270\216npm\344\275\277\347\224\250.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/2\346\250\241\345\235\227\344\270\216npm\344\275\277\347\224\250.md" new file mode 100644 index 0000000..61d6bdf --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/2\346\250\241\345\235\227\344\270\216npm\344\275\277\347\224\250.md" @@ -0,0 +1,96 @@ +## 什么是模块 + +在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。 + +为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Node环境中,一个.js文件就称之为一个模块(module)。 + +使用模块有什么好处? + +最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Node内置的模块和来自第三方的模块。 + +使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中,因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。 + + +#### 简单来说,模块就是把代码分成一个个文件 + + +#### 来个案例 + +```js +//文件 a + +'use strict'; + +var s = 'Hello'; + +function greet(name) { + console.log(s + ', ' + name + '!'); +} + +module.exports = greet; + +//文件 b + + +'use strict'; + +// 引入hello模块: +var greet = require('./a'); + +var s = 'Michael'; + +greet(s); // Hello, Michael! + +``` + +#### 简单说要暴露的使用 module.exports 暴露, 要使用的 require(跟php 类似)引入文件,要注意文件的位置 + + +## 什么是 npm + +npm是什么东东?npm其实是Node.js的包管理工具(node package manager)。 + +为啥我们需要一个包管理工具呢?因为我们在Node.js上开发时,会用到很多别人写的JavaScript代码。如果我们要使用别人写的某个包,每次都根据名称搜索一下官方网站,下载代码,解压,再使用,非常繁琐。于是一个集中管理的工具应运而生:大家都把自己开发的模块打包后放到npm官网上,如果要使用,直接通过npm安装就可以直接用,不用管代码存在哪,应该从哪下载。 + +更重要的是,如果我们要使用模块A,而模块A又依赖于模块B,模块B又依赖于模块X和模块Y,npm可以根据依赖关系,把所有依赖的包都下载下来并管理起来。否则,靠我们自己手动管理,肯定既麻烦又容易出错。 + + +## npm的常用命令 + +2.npm 常用命令 参考 https://www.npmjs.cn/cli/init/ + +npm install //安装 也可简写成 npm i 如何指定版本gulp@3.9.1 + +npm uninstall //移除 + +npm update //更新 npm + 英文 + +npm ls //列出列表 + +npm init //初始化 init 初始化 + +npm cache + +npm start + +npm outdated 检查模块是否已经过时 + +npm root 查看包的安装路径 + +npm version 查看模块版本 + +npm install -g cnpm --registry=https://registry.npm.taobao.org + +npm 的官网 http://npmjs.com/ + +3.package.json 介绍 name 包名 description 包简介 author 作者 version 版本 repository 源码托管地址 maintainers 包维护者列表 cotributors 贡献者列表 dependencies 需要的依赖包列表 devde-- 开发环境需要的包列表 keywords 关键词数组 main 模块的入口文件 scripts 脚本说明对象 + +### 作业:写个加减乘除的模块(尽量少写暴露,要考虑复用性),供外部使用. 作业每个分支要建一个目录(自己名字) + + + + + + + + diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/3node\347\232\204\346\226\207\344\273\266\350\257\273\345\206\231\344\270\212.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/3node\347\232\204\346\226\207\344\273\266\350\257\273\345\206\231\344\270\212.md" new file mode 100644 index 0000000..c33277f --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/3node\347\232\204\346\226\207\344\273\266\350\257\273\345\206\231\344\270\212.md" @@ -0,0 +1,162 @@ +#### 文件的读取 + +Node.js内置的fs模块就是文件系统模块,负责读写文件。 + +和所有其它JavaScript模块不同的是,fs模块同时提供了异步和同步的方法。 + +回顾一下什么是异步方法。因为JavaScript的单线程模型,执行IO操作时,JavaScript代码无需等待,而是传入回调函数后,继续执行后续JavaScript代码。比如jQuery提供的getJSON()操作: + +```js + +$.getJSON('http://example.com/ajax', function (data) { + console.log('IO结果返回后执行...'); +}); +console.log('不等待IO结果直接执行后续代码...'); + +``` + + +而同步的IO操作则需要等待函数返回: + +```js + +// 根据网络耗时,函数将执行几十毫秒~几秒不等: +var data = getJSONSync('http://example.com/ajax'); + +``` + +同步操作的好处是代码简单,缺点是程序将等待IO操作,在等待时间内,无法响应其它任何事件。而异步读取不用等待IO操作,但代码较麻烦。 + +```js + +'use strict'; + +var fs = require('fs'); + +fs.readFile('sample.txt', 'utf-8', function (err, data) { + if (err) { + console.log(err); + } else { + console.log(data); + } +}); + +``` + +请注意,sample.txt文件必须在当前目录下,且文件编码为utf-8。 + +异步读取时,传入的回调函数接收两个参数,当正常读取时,err参数为null,data参数为读取到的String。当读取发生错误时,err参数代表一个错误对象,data为undefined。这也是Node.js标准的回调函数:第一个参数代表错误信息,第二个参数代表结果。后面我们还会经常编写这种回调函数。 + +由于err是否为null就是判断是否出错的标志,所以通常的判断逻辑总是: + +``` +if (err) { + // 出错了 +} else { + // 正常 +} +``` + +如果我们要读取的文件不是文本文件,而是二进制文件,怎么办? + +下面的例子演示了如何读取一个图片文件: + +```js + +'use strict'; + +var fs = require('fs'); + +fs.readFile('sample.png', function (err, data) { + if (err) { + console.log(err); + } else { + console.log(data); + console.log(data.length + ' bytes'); + } +}); +``` + +## 同步读文件 +除了标准的异步读取模式外,fs也提供相应的同步读取函数。同步读取的函数和异步函数相比,多了一个Sync后缀,并且不接收回调函数,函数直接返回结果。 + +用fs模块同步读取一个文本文件的代码如下: + +``` + +'use strict'; + +var fs = require('fs'); + +var data = fs.readFileSync('sample.txt', 'utf-8'); +console.log(data); + +``` + +可见,原异步调用的回调函数的data被函数直接返回,函数名需要改为readFileSync,其它参数不变。 + +如果同步读取文件发生错误,则需要用try...catch捕获该错误: + +```js + +try { + var data = fs.readFileSync('sample.txt', 'utf-8'); + console.log(data); +} catch (err) { + // 出错了 +} + +``` + +## 写文件 +将数据写入文件是通过fs.writeFile()实现的: + +``` + +'use strict'; + +var fs = require('fs'); + +var data = 'Hello, Node.js'; +fs.writeFile('output.txt', data, function (err) { + if (err) { + console.log(err); + } else { + console.log('ok.'); + } +}); + +``` + +## stat + +如果我们要获取文件大小,创建时间等信息,可以使用fs.stat(),它返回一个Stat对象,能告诉我们文件或目录的详细信息: + +``` +'use strict'; + +var fs = require('fs'); + +fs.stat('sample.txt', function (err, stat) { + if (err) { + console.log(err); + } else { + // 是否是文件: + console.log('isFile: ' + stat.isFile()); + // 是否是目录: + console.log('isDirectory: ' + stat.isDirectory()); + if (stat.isFile()) { + // 文件大小: + console.log('size: ' + stat.size); + // 创建时间, Date对象: + console.log('birth time: ' + stat.birthtime); + // 修改时间, Date对象: + console.log('modified time: ' + stat.mtime); + } + } +}); + +``` + +## 作业:随机生成一个文件,必须有 “英文,中文,数字,特殊字符”,然后读取出这个文件的内容 + diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/4node\347\232\204\346\226\207\344\273\266\350\257\273\345\206\231\344\270\213.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/4node\347\232\204\346\226\207\344\273\266\350\257\273\345\206\231\344\270\213.md" new file mode 100644 index 0000000..1fb0050 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/4node\347\232\204\346\226\207\344\273\266\350\257\273\345\206\231\344\270\213.md" @@ -0,0 +1,77 @@ +## stream 流 + +stream是Node.js提供的又一个仅在服务区端可用的模块,目的是支持“流”这种数据结构。 + +什么是流?流是一种抽象的数据结构。想象水流,当在水管中流动时,就可以从某个地方(例如自来水厂)源源不断地到达另一个地方(比如你家的洗手池)。我们也可以把数据看成是数据流,比如你敲键盘的时候,就可以把每个字符依次连起来,看成字符流。这个流是从键盘输入到应用程序,实际上它还对应着一个名字:标准输入流(stdin)。 + +如果应用程序把字符一个一个输出到显示器上,这也可以看成是一个流,这个流也有名字:标准输出流(stdout)。流的特点是数据是有序的,而且必须依次读取,或者依次写入,不能像Array那样随机定位。 + +有些流用来读取数据,比如从文件读取数据时,可以打开一个文件流,然后从文件流中不断地读取数据。有些流用来写入数据,比如向文件写入数据时,只需要把数据不断地往文件流中写进去就可以了。 + +在Node.js中,流也是一个对象,我们只需要响应流的事件就可以了:data事件表示流的数据已经可以读取了,end事件表示这个流已经到末尾了,没有数据可以读取了,error事件表示出错了。 + +下面是一个从文件流读取文本内容的示例 + +```js +'use strict'; + +var fs = require('fs'); + +// 打开一个流: +var rs = fs.createReadStream('sample.txt', 'utf-8'); + +rs.on('data', function (chunk) { + console.log('DATA:') + console.log(chunk); +}); + +rs.on('end', function () { + console.log('END'); +}); + +rs.on('error', function (err) { + console.log('ERROR: ' + err); +}); + +``` + +要注意,data事件可能会有多次,每次传递的chunk是流的一部分数据。 + +要以流的形式写入文件,只需要不断调用write()方法,最后以end()结束: + +```js +'use strict'; + +var fs = require('fs'); + +var ws1 = fs.createWriteStream('output1.txt', 'utf-8'); +ws1.write('使用Stream写入文本数据...\n'); +ws1.write('END.'); +ws1.end(); + +var ws2 = fs.createWriteStream('output2.txt'); +ws2.write(new Buffer('使用Stream写入二进制数据...\n', 'utf-8')); +ws2.write(new Buffer('END.', 'utf-8')); +ws2.end(); +``` + +所有可以读取数据的流都继承自stream.Readable,所有可以写入的流都继承自stream.Writable。 + +## pipe +就像可以把两个水管串成一个更长的水管一样,两个流也可以串起来。一个Readable流和一个Writable流串起来后,所有的数据自动从Readable流进入Writable流,这种操作叫pipe。 + +在Node.js中,Readable流有一个pipe()方法,就是用来干这件事的。 + +让我们用pipe()把一个文件流和另一个文件流串起来,这样源文件的所有数据就自动写入到目标文件里了,所以,这实际上是一个复制文件的程序: + +```js + +'use strict'; + +var fs = require('fs'); + +var rs = fs.createReadStream('sample.txt'); +var ws = fs.createWriteStream('copied.txt'); + +rs.pipe(ws); +``` \ No newline at end of file diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/5node\347\232\204\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/5node\347\232\204\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234.md" new file mode 100644 index 0000000..6cdaae6 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/5node\347\232\204\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234.md" @@ -0,0 +1,217 @@ +## 对mysql的操作 + +当我们安装好MySQL后,Node.js程序如何访问MySQL数据库呢? + +访问MySQL数据库只有一种方法,就是通过网络发送SQL命令,然后,MySQL服务器执行后返回结果。 + +我们可以在命令行窗口输入mysql -u root -p,然后输入root口令后,就连接到了MySQL服务器。因为没有指定--host参数,所以我们连接到的是localhost,也就是本机的MySQL服务器。 + +在命令行窗口下,我们可以输入命令,操作MySQL服务器: + +## 对mysql的直接操作 + +如果直接使用mysql包提供的接口,我们编写的代码就比较底层,例如,查询代码 + +```js + +connection.query('SELECT * FROM users WHERE id = ?', ['123'], function(err, rows) { + if (err) { + // error + } else { + for (let row in rows) { + processRow(row); + } + } +}); +``` + +## 传说中的orm + +这就是传说中的ORM技术:Object-Relational Mapping,把关系数据库的表结构映射到对象上。是不是很简单? + +但是由谁来做这个转换呢?所以ORM框架应运而生。 + +我们选择Node的ORM框架Sequelize来操作数据库。这样,我们读写的都是JavaScript对象,Sequelize帮我们把对象变成数据库中的行。 + +用Sequelize查询pets表,代码像这样: + +```js + +Pet.findAll() + .then(function (pets) { + for (let pet in pets) { + console.log(`${pet.id}: ${pet.name}`); + } + }).catch(function (err) { + // error + }); + + ``` + +## ORM是什么? +ORM(Object Relational Mapping,对象关系映射),是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术,通过描述对象和数据库之间映射的元数据,把程序中的对象自动持久化到关系数据库中。它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了 。这就好比入java的Mybatis, thinkphp的model类,通过映射数据库,简化数据库操作,使开发者不需要书写复杂的SQL语句,将更多的时间放在逻辑的书写上。 + + + +sequelize的基本使用 + +下载 + +```js +npm install --save sequelize + +``` + +安装数据库驱动程序: + +```js + +$ npm install --save pg pg-hstore # Postgres +$ npm install --save mysql2 +$ npm install --save mariadb +$ npm install --save sqlite3 +$ npm install --save tedious # Microsoft SQL Server + + +``` + +创建数据库配置 + +```js + +const { Sequelize } = require('sequelize'); + +// 方法 1: 传递一个连接 URI +const sequelize = new Sequelize('sqlite::memory:') // Sqlite 示例 +const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname') // Postgres 示例 + +// 方法 2: 分别传递参数 (sqlite) +const sequelize = new Sequelize({ + dialect: 'sqlite', + storage: 'path/to/database.sqlite' +}); + +// 方法 3: 分别传递参数 (其它数据库) +const sequelize = new Sequelize('database', 'username', 'password', { + host: 'localhost', + dialect: /* 选择 'mysql' | 'mariadb' | 'postgres' | 'mssql' 其一 */ +}); + + +``` +连接测试 + +```js +使用 .authenticate() 函数测试连接是否正常 + try { + await sequelize.authenticate(); + console.log('Connection has been established successfully.'); +} catch (error) { + console.error('Unable to connect to the database:', error); +} + +``` + +同步数据库 + +```js +sequelize.sync() - 如果不存在,则创建该表(如果已经存在,则不执行任何操作) +sequelize.sync({ force: true }) - 将创建表,如果表已经存在,则将其首先删除 +sequelize.sync({ alter: true }) - 这将检查数据库中表的当前状态(它具有哪些列,它们的数据类型等) +``` + +实例 + +```js + +const sequelize = new Sequelize('admin', 'root', '893100', { + host: 'localhost', + port: 3306, + dialect: 'mysql' + }); + + try { + sequelize.authenticate(); + // console.log('Connection has been established successfully.'); + } catch (error) { + // console.error('Unable to connect to the database:', error); + } + +sequelize.sync({ alter: true }); + + module.exports = sequelize + +``` + +创建数据库模型 + +```js + +const { DataTypes } = require('sequelize'); +const sequelize = require('../config/db') + +const Student = sequelize.define('student', { + // 这里定义模型属性 + name: { + type: DataTypes.STRING, + allowNull: false + }, + sex: { + type: DataTypes.STRING + // allowNull 默认为 true + }, + QQ: { + type: DataTypes.STRING + // allowNull 默认为 true + }, + id: { + type: DataTypes.STRING, + primaryKey: true + // allowNull 默认为 true + }, + number: { + type: DataTypes.STRING + // allowNull 默认为 true + }, + telphone: { + type: DataTypes.STRING + // allowNull 默认为 true + }, + classe: { + type: DataTypes.STRING + // allowNull 默认为 true + } + }, { + freezeTableName: true + }); + + + module.exports = Student + +``` + +快速查询 + +```js + +// controller层 +const Student = require('../model/students') + async getAdmin (ctx) { + const res = await Student.findAll() + console.log(res) + ctx.body = { + data: res, + statusCode: 200, + message: '数据获取成功' + } + } + + +``` + +## 作业:创建一个用户表(要有主键,用户名,密码,创建时间,更新时间,性别)等,使用orm框架去数据库进行增删改查 + + + + + diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/6node\347\232\204http\346\250\241\345\235\227.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/6node\347\232\204http\346\250\241\345\235\227.md" new file mode 100644 index 0000000..a313370 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/6node\347\232\204http\346\250\241\345\235\227.md" @@ -0,0 +1,53 @@ + +## http 协议 + +Node.js开发的目的就是为了用JavaScript编写Web服务器程序。因为JavaScript实际上已经统治了浏览器端的脚本,其优势就是有世界上数量最多的前端开发人员。如果已经掌握了JavaScript前端开发,再学习一下如何将JavaScript应用在后端开发,就是名副其实的全栈了。 + +## HTTP协议 +Web系统的基础就是HTTP协议,HTTP协议是一个应用层协议,也就是TCP传输层的上一层协议,HTTP协议只定义传输的内容是什么,不定义如何传输(这是底层协议做的事),所以理解HTTP协议,只需要理解协议的数据结构及所代表的意义即可。 + + +无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。可以设置Connecction:keep-alive 保存TCP连接。后面如果还要用到这个连接不会每次都新建连接 + + +无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量増大。另一方面,在服务器不需要先前信息时它的应答就较快。 + +明文传输,HTTP协议不支持加密处理,所以在安全性方面是一大硬伤。目前解决这一安全问题的方法是使用Https协议(基于HTTP+SSL/TLS协议)的一种安全传输方案。 + +HTTP服务器 +要开发HTTP服务器程序,从头处理TCP连接,解析HTTP是不现实的。这些工作实际上已经由Node.js自带的http模块完成了。应用程序并不直接和HTTP协议打交道,而是操作http模块提供的request和response对象。 + +request对象封装了HTTP请求,我们调用request对象的属性和方法就可以拿到所有HTTP请求的信息; + +response对象封装了HTTP响应,我们操作response对象的方法,就可以把HTTP响应返回给浏览器。 + +用Node.js实现一个HTTP服务器程序非常简单。我们来实现一个最简单的Web程序hello.js,它对于所有请求,都返回Hello world!: + + +```js + +'use strict'; + +// 导入http模块: +var http = require('http'); + +// 创建http server,并传入回调函数: +var server = http.createServer(function (request, response) { + // 回调函数接收request和response对象, + // 获得HTTP请求的method和url: + console.log(request.method + ': ' + request.url); + // 将HTTP响应200写入response, 同时设置Content-Type: text/html: + response.writeHead(200, {'Content-Type': 'text/html'}); + // 将HTTP响应的HTML内容写入response: + response.end('

Hello world!

'); +}); + +// 让服务器监听8080端口: +server.listen(8080); + +console.log('Server is running at http://127.0.0.1:8080/'); + + +``` + +## 搭建一个web服务器,针对不同的参数,给予不同的回应 diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/7node\347\232\204\345\274\202\346\255\245\345\256\236\347\216\260promise.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/7node\347\232\204\345\274\202\346\255\245\345\256\236\347\216\260promise.md" new file mode 100644 index 0000000..360d4b8 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/7node\347\232\204\345\274\202\346\255\245\345\256\236\347\216\260promise.md" @@ -0,0 +1,131 @@ +## Promise 期约 + +Promise 是一个 ECMAScript 6 提供的类,目的是更加优雅地书写复杂的异步任务。 +由于 Promise 是 ES6 新增加的,所以一些旧的浏览器并不支持,苹果的 Safari 10 和 Windows 的 Edge 14 版本以上浏览器才开始支持 ES6 特性。 +不是所有的浏览器都支持 + + +## 构造 Promise +现在我们新建一个 Promise 对象: + +```js +new Promise(function (resolve, reject) { + // 要做的事情... +}); +``` + + +Promise 构造函数只有一个参数,是一个函数,这个函数在构造之后会直接被异步运行,所以我们称之为起始函数。起始函数包含两个参数 resolve 和 reject。 + +当 Promise 被构造时,起始函数会被异步执行: + +```js + +new Promise(function (resolve, reject) { + console.log("Run"); +}); + +``` +这段程序会直接输出 Run。 + +resolve 和 reject 都是函数,其中调用 resolve 代表一切正常,reject 是出现异常时所调用的: + +```js +new Promise(function (resolve, reject) { + var a = 0; + var b = 1; + if (b == 0) reject("Divide zero"); + else resolve(a / b); +}).then(function (value) { + console.log("a / b = " + value); +}).catch(function (err) { + console.log(err); +}).finally(function () { + console.log("End"); +}); + +``` +Promise 类有 .then() .catch() 和 .finally() 三个方法,这三个方法的参数都是一个函数,.then() 可以将参数中的函数添加到当前 Promise 的正常执行序列,.catch() 则是设定 Promise 的异常处理序列,.finally() 是在 Promise 执行的最后一定会执行的序列。 .then() 传入的函数会按顺序依次执行,有任何异常都会直接跳到 catch 序列 + + +## 案例 + + +通过新建一个 Promise 对象好像并没有看出它怎样 "更加优雅地书写复杂的异步任务"。我们之前遇到的异步任务都是一次异步,如果需要多次调用异步函数呢?例如,如果我想分三次输出字符串,第一次间隔 1 秒,第二次间隔 4 秒,第三次间隔 3 秒: + +```js + +setTimeout(function () { + console.log("First"); + setTimeout(function () { + console.log("Second"); + setTimeout(function () { + console.log("Third"); + }, 3000); + }, 4000); +}, 1000); +``` + +这段程序实现了这个功能,但是它是用 "函数瀑布" 来实现的。可想而知,在一个复杂的程序当中,用 "函数瀑布" 实现的程序无论是维护还是异常处理都是一件特别繁琐的事情,而且会让缩进格式变得非常冗赘。 + +现在我们用 Promise 来实现同样的功能: + +```js +new Promise(function (resolve, reject) { + setTimeout(function () { + console.log("First"); + resolve(); + }, 1000); +}).then(function () { + return new Promise(function (resolve, reject) { + setTimeout(function () { + console.log("Second"); + resolve(); + }, 4000); + }); +}).then(function () { + setTimeout(function () { + console.log("Third"); + }, 3000); +}); +``` + +## 异步函数 +异步函数(async function)是 ECMAScript 2017 (ECMA-262) 标准的规范,几乎被所有浏览器所支持,除了 Internet Explorer。 + +在 Promise 中我们编写过一个 Promise 函数 + +```js +function print(delay, message) { + return new Promise(function (resolve, reject) { + setTimeout(function () { + console.log(message); + resolve(); + }, delay); + }); +} + +print(1000, "First").then(function () { + return print(4000, "Second"); +}).then(function () { + print(3000, "Third"); +}); + + + +async function asyncFunc() { + try { + await new Promise(function (resolve, reject) { + throw "Some error"; // 或者 reject("Some error") + }); + } catch (err) { + console.log(err); + // 会输出 Some error + } +} +asyncFunc(); + +``` + + + diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/images/1.png" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/images/1.png" new file mode 100644 index 0000000000000000000000000000000000000000..69062cad1a0f8cbe4bec062e4c977a64087e47d9 GIT binary patch literal 36026 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 literal 0 HcmV?d00001 diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2661.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2661.md" new file mode 100644 index 0000000..bcfc76c --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2661.md" @@ -0,0 +1,63 @@ +## node 的框架 + +### 初始Express + +1.1 Express介绍 +Express是目前流行的基于Node.js运行环境的Web应用程序开发框架,它简洁且灵活,为Web应用程序提供了强大的功能。Express提供了一个轻量级模块,类似于jQuery(封装的工具库),它把Node.js的HTTP模块的功能封装在一个简单易用的接口中,用于扩展HTTP模块的功能,能够轻松地处理服务器的路由、响应、Cookie和HTTP请求的状态。 + +Express的优势: +(1)简洁的路由定义方式。 +(2)简化HTTP请求参数的处理。 +(3)提供中间件机制控制HTTP请求。 +(4)拥有大量第三方中间件。 +(5)支持多种模版引擎 + +### 安装express 框架 + +```js + +// 项目初始化 +npm init -y +// 安装 +npm install express --save + +// 查看版本 + +npm list express + + +``` + +## 利用Express搭建Web服务器 + +利用Express搭建Web服务器的基本步骤: + +#### 引入express模块; +#### 调用express()方法创建服务器对象; +#### 定义路由; +#### 调用listen()方法监听端口 + + +来个例子 + +```js + +// 引入express模块 +const express = require("express"); +// 创建Web服务器对象 +const app = express(); +// 定义GET路由,接收/处理客户端的GET请求 +app.get("/", (req, res) => { + // 对客户端做出响应,send()方法会根据内容的类型自动设置请求头 + res.end("hello express"); +}) +// 监听3000端口 +app.listen(3000); + +``` +#### 理解 app 是啥,req,res 是啥.怎么接收参数,怎么回应参数. + +## 作业:写个个人简历 + + + diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2662.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2662.md" new file mode 100644 index 0000000..84fbc0a --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2662.md" @@ -0,0 +1,117 @@ +## Express中间件 + +Express通过中间件接收客户端发来的请求,并对请求做出响应,也可以将请求交给下一个中间件继续处理。 + +Express中间件指业务流程中的中间处理环节,可以把中间件理解为客户端请求的一系列方法。如果把请求比作水流,那么中间件就是阀门,阀门可以控制水流是否继续向下流动,也可以在当前阀门处对水流进行排污处理,处理完成后再继续向下流动。 + +如图: + +![image](./images/1.png) + +#### 路由保护:当客户端访问登录页面时,可以先使用中间件判断用户的登录状态,如果用户未登录,则拦截请求,直接响应提示信息,并禁止用户跳转到登录页面。 +#### 网站维护公告:在所有路由的最上面定义接收所有请求的中间件,直接为客户端做出响应,并提示网站正在维护中。 +#### 自定义404页面:在所有路由的最上面定义接收所有请求的中间件,直接为客户端做出响应,并提示404页面错误信息。 + + +常用的中间件方法有app.get()、app.post()、app.use(),其基本语法形式如下 + +```js +app.get('请求路径', '请求处理函数'); // 接收并处理GET请求 +app.post('请求路径', '请求处理函数'); // 接收并处理POST请求 +app.use('请求路径', '请求处理函数'); // 接收并处理所有请求 + +``` + + +## app.get()中间件 + +当客户端向服务器端发送GET请求时,app.get()中间件方法会拦截GET请求,并通过app.get()中间件中的请求处理函数对GET请求进行处理。 + +```js +app.get('/', (req, res, next) => { + next(); +}); + + + +``` +同一个请求路径可以设置多个中间件,表示对同一个路径的请求进行多次处理,默认情况下Express会从上到下依次匹配中间件。 + +示例:使用app.get()定义中间件并返回req.name的值 + +```js + +// 引入express模块 +const express = require("express"); +// 创建Web服务器对象 +const app = express(); +// 定义中间件 +app.get("/request", (req, res, next) => { + req.name = "橘猫吃不胖"; + next(); // 启动下一个中间件 +}) +app.get("/request", (req, res) => { + res.end(req.name); +}) +// 监听3000端口 +app.listen(3000); + +``` + +## post 中间件 + +当浏览器向服务器发送POST请求时,app.post()定义的中间件会接收并处理POST请求。 + +示例:使用app.post()定义中间件发送post请求 + +第一步:新建一个用于发送post请求的表单index.htm + +```js +
+ +
+ +``` + +第二步:定义app.post()中间件,接受并处理浏览器发送的POST请求,返回req.name的值 + +```js + +const express = require("express"); +const app = express(); +// 定义中间件 +app.post("/post", (req, res, next) => { + req.name = "橘猫吃不胖"; + next(); +}) +app.post("/post", (req, res) => { + res.end(req.name); +}) +// 监听4000端口 +app.listen(4000); + +``` + +## app.use()中间件 + +通过app.use()定义的中间件既可以处理GET请求又可以处理POST请求。在多个app.use()设置了相同请求路径的情况下,服务器都会接收请求并进行处理。 + +示例:使用app.use()定义中间件,处理GET和SET请求 + +```js + +const express = require("express"); +const app = express(); +// 定义中间件 +app.use("/form", ((req, res, next) => { + req.name = "橘猫吃不胖"; + next(); +})) +app.use("/form", (req, res) => { + res.end(req.name); +}) +// 监听3000端口 +app.listen(3000); + + +``` diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2663.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2663.md" new file mode 100644 index 0000000..8ad9aa7 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2663.md" @@ -0,0 +1,65 @@ +## 静态资源的处理和中间件的应用 + +express.static()是Express框架提供的内置中间件,它接收静态资源访问目录作为参数。 + +使用express.static()内置中间件可以方便地托管静态文件,在客户端访问服务器的静态资源时使用。常用的静态资源有图片、CSS、JavaScript和HTML文件等。 + +express.static()参数是静态资源所在的目录,它需要作为app.use()的参数使用,示例代码如下 + +```js +app.use(express.static('public')); + +``` + +举个栗子:实现静态资源访问 + +第一步:在src目录下新建public文件夹,用于存放静态文件,在该目录下新建一个文件夹images,存放一个图片文件 + + +第二步:在src目录下新建static.js文件,代码如下 +```js +const express = require("express"); +const app = express(); +// 静态资源处理 +app.use(express.static("public")); +// 监听3000端口 +app.listen(3000); + +``` +第三步:启动服务器,在浏览器中输入:localhost:3000/images/1.jpg,页面上就会显示出来放在images文件夹下面的图片 + +## 利用中间件处理错误 + +在程序执行的过程中,不可避免的会出现一些无法预料的错误,比如文件读取失败、数据库连接失败等。这时候就需要用到错误处理中间件了,用它来集中处理错误。 + +利用app.use()定义错误处理中间件的示例代码如下: + +```js +app.use((err, req, res, next) => { + console.log(err.message); +}); + + +const express = require("express"); +const fs = require("fs"); +const app = express(); +// 使用app.get()中间件进行文件读取操作 +app.get("/readFile", (req, res, next) => { + // 读取a.txt文件 + fs.readFile("./a.txt", "utf8", (err, result) => { + if (err !== null) { // 如果错误信息不为空,将该信息传给下一个中间件 + next(err); + } else { + res.send(result); + } + }) +}) +// 错误处理中间件 +app.use((err, req, res, next) => { + // 设置响应状态码为500,并发送错误信息 + res.status(500).send(err.message); +}) +app.listen(3000); + + +``` \ No newline at end of file diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2664.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2664.md" new file mode 100644 index 0000000..7b76593 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node_express\346\241\206\346\236\2664.md" @@ -0,0 +1,74 @@ +## 参数的接收 + +### 接受GET请求 + +Express框架中的req.query用于获取GET请求参数,框架内部会将GET参数转换为对象并返回。利用req.query获取GET请求参数的示例代码如下。 + +```js + +app.get('/', (req, res) => { + res.send(req.query); +}); + + +``` + + +示例:获取GET请求参数 + +```js +const express = require("express"); +const app = express(); +app.get("/query", (req, res) => { + // 获取get请求参数 + res.send(req.query); +}) +app.listen(3000); + +``` + + + +## 接收POST请求参数 +Express中的req.body用于获取POST请求参数,需要借助第三方body-parser模块将POST参数转换为对象形式。利用req获取POST请求参数的示例代码如下。 + +示例: + +### 第一步:安装body-parser模块 +```js +npm install body-parser@1.18.3 --save + +``` +### 第二步:编写query.js文件 + +```js + +const express = require("express"); +const bodyParsee = require("body-parser"); +const app = express(); +app.use(bodyParsee.urlencoded({ extended: false })); +app.post("/query", (req, res) => { + // 获取get请求参数 + res.send(req.body); +}) +app.listen(3000); + + +``` + +### 第三步:编写index.html文件 + + +```js + +
+ 用户名: +
+ 密码: +
+ +
+ + +``` + diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\347\232\204restfullapi.md" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\347\232\204restfullapi.md" new file mode 100644 index 0000000..8f81623 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\347\232\204restfullapi.md" @@ -0,0 +1,19 @@ +## 什么是 REST? +REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。 + +表述性状态转移是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是RESTful。需要注意的是,REST是设计风格而不是标准。REST通常基于使用HTTP,URI,和XML(标准通用标记语言下的一个子集)以及HTML(标准通用标记语言下的一个应用)这些现有的广泛流行的协议和标准。REST 通常使用 JSON 数据格式。 + + +## HTTP 方法 + +以下为 REST 基本架构的四个方法: + +GET - 用于获取数据。 + +PUT - 用于更新或添加数据。 + +DELETE - 用于删除数据。 + +POST - 用于添加数据 + +## \ No newline at end of file diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/test-git" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/test-git" new file mode 160000 index 0000000..2b4876a --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/test-git" @@ -0,0 +1 @@ +Subproject commit 2b4876ac9942891cf96dd927da7a477141c53a20 diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\345\205\250\345\261\200\345\257\271\350\261\241/path.js" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\345\205\250\345\261\200\345\257\271\350\261\241/path.js" new file mode 100644 index 0000000..3b9e2ec --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\345\205\250\345\261\200\345\257\271\350\261\241/path.js" @@ -0,0 +1,40 @@ +//全局变量 +//__filename 获取文件的路径,获取到绝对路径,包括文件名 +//__filename 前面是两个下划线 +console.log(__filename); +console.log('__filename'); +//eval 会把字符串当做js代码执行 +console.log(eval('__filename')); + +//__dirname 获取当前文件所在的文件夹 +//__dirname 前面也是两个下划线 +console.log(__dirname); + +//过一段时间执行里面的方法,只执行一次,第二次参数 timeout是 时间,单位毫秒 +setTimeout(() => { + console.log("过三秒后执行") +}, 3000); +console.log("我会不会先执行"); + +//周期性执行 +// setInterval(() => { +// console.log("看能不能周期性的执行") +// }, 2000); + +//process 当前的这个程序 +//console.log(process); + +process.on('exit',()=>{ + setTimeout(() => { + console.log('-----------------------------------------------------我会不会被执行') + }, 0); + console.log('要退出了') +}); + +process.on('beforeExit',()=>{ + console.log("我能不能优先于上面的代码先输出"); +}) + + + + diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\346\250\241\345\235\227/moduleObj.js" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\346\250\241\345\235\227/moduleObj.js" new file mode 100644 index 0000000..82dcb0d --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\346\250\241\345\235\227/moduleObj.js" @@ -0,0 +1,18 @@ +let obj ={ + js:function(){ + return 4000; + }, + 'php':function(){ + return 4000; + }, + python:function(){ + return 5000; + }, + money:300, +} + + + +//module.exports 可以理解对外暴露的空对象 +//module.exports.obj = obj;//也可以只是使用的模块,多了一层obj +module.exports = obj; \ No newline at end of file diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\346\250\241\345\235\227/moudle.js" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\346\250\241\345\235\227/moudle.js" new file mode 100644 index 0000000..38b5103 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\346\250\241\345\235\227/moudle.js" @@ -0,0 +1,45 @@ + + +function giveFlower() { + console.log('送花'); + return "送花"; +} + +function giveGift() { + console.log("手机"); + return "苹果手机"; +} + +function giveMoney() { + console.log("money"); + return "给钱"; +} + +function giveBook() { + console.log("一起好好读书"); + return "一起自习"; +} + +var money = 200; +function changeMoney(num){ + money = money+num; + console.log(money); + +} + +// changeMoney(500); +// console.log(money); + + +//module.exports 理解为一个对外暴露的空对象 +// let obj={} +// obj.name = function(){ + +// } +module.exports.flower = giveFlower; +module.exports.giveMoney = giveMoney; +module.exports.giveBook = giveBook; +module.exports.qian = money;//等效于 module.exports.qian = 200 +module.exports.changeMoney = changeMoney; + + diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\346\250\241\345\235\227/use.js" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\346\250\241\345\235\227/use.js" new file mode 100644 index 0000000..d25c1d4 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/node\351\241\271\347\233\256/\346\250\241\345\235\227/use.js" @@ -0,0 +1,16 @@ +//使用模块,需要使用一个关键词 require +let obj=require("./moudle.js"); +console.log(obj);// 引入一个模块就是一个对象 + +obj.flower(); + +//require进来,.js可以省去, 如果是同一层级 ./ 不能省去 +let useObj = require("./moduleObj"); +// console.log(useObj); +// console.log(useObj.obj.js()) +console.log(useObj.js()); + +//修改module.js里面的金额 +console.log(obj.qian);// +obj.changeMoney(500); +console.log(obj.qian);//200 还是 700 diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/test/express.js" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/test/express.js" new file mode 100644 index 0000000..e69de29 diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/\346\250\241\345\235\227/moduleObj.js" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/\346\250\241\345\235\227/moduleObj.js" new file mode 100644 index 0000000..82dcb0d --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/\346\250\241\345\235\227/moduleObj.js" @@ -0,0 +1,18 @@ +let obj ={ + js:function(){ + return 4000; + }, + 'php':function(){ + return 4000; + }, + python:function(){ + return 5000; + }, + money:300, +} + + + +//module.exports 可以理解对外暴露的空对象 +//module.exports.obj = obj;//也可以只是使用的模块,多了一层obj +module.exports = obj; \ No newline at end of file diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/\346\250\241\345\235\227/moudle.js" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/\346\250\241\345\235\227/moudle.js" new file mode 100644 index 0000000..38b5103 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/\346\250\241\345\235\227/moudle.js" @@ -0,0 +1,45 @@ + + +function giveFlower() { + console.log('送花'); + return "送花"; +} + +function giveGift() { + console.log("手机"); + return "苹果手机"; +} + +function giveMoney() { + console.log("money"); + return "给钱"; +} + +function giveBook() { + console.log("一起好好读书"); + return "一起自习"; +} + +var money = 200; +function changeMoney(num){ + money = money+num; + console.log(money); + +} + +// changeMoney(500); +// console.log(money); + + +//module.exports 理解为一个对外暴露的空对象 +// let obj={} +// obj.name = function(){ + +// } +module.exports.flower = giveFlower; +module.exports.giveMoney = giveMoney; +module.exports.giveBook = giveBook; +module.exports.qian = money;//等效于 module.exports.qian = 200 +module.exports.changeMoney = changeMoney; + + diff --git "a/\346\235\250\350\215\243\346\237\217/23-02-15/node/\346\250\241\345\235\227/use.js" "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/\346\250\241\345\235\227/use.js" new file mode 100644 index 0000000..d25c1d4 --- /dev/null +++ "b/\346\235\250\350\215\243\346\237\217/23-02-15/node/\346\250\241\345\235\227/use.js" @@ -0,0 +1,16 @@ +//使用模块,需要使用一个关键词 require +let obj=require("./moudle.js"); +console.log(obj);// 引入一个模块就是一个对象 + +obj.flower(); + +//require进来,.js可以省去, 如果是同一层级 ./ 不能省去 +let useObj = require("./moduleObj"); +// console.log(useObj); +// console.log(useObj.obj.js()) +console.log(useObj.js()); + +//修改module.js里面的金额 +console.log(obj.qian);// +obj.changeMoney(500); +console.log(obj.qian);//200 还是 700 -- Gitee From 584e2cff1e66fd83a076579da436b2fc634aa7ec Mon Sep 17 00:00:00 2001 From: unknown <84300040@qq.com> Date: Fri, 17 Feb 2023 17:27:56 +0800 Subject: [PATCH 5/5] '2-16' --- wish.html | 12 ------ .../2-13/\347\254\224\350\256\260.txt" | 7 --- .../jie.js" | 5 --- .../zy.js" | 43 ------------------- .../2-16\344\275\234\344\270\232/zy.js" | 30 ------------- .../23-02-16/1.txt" | 1 + .../23-02-16/10.txt" | 1 + .../23-02-16/100.txt" | 1 + .../23-02-16/11.txt" | 1 + .../23-02-16/12.txt" | 1 + .../23-02-16/13.txt" | 1 + .../23-02-16/14.txt" | 1 + .../23-02-16/15.txt" | 1 + .../23-02-16/16.txt" | 1 + .../23-02-16/17.txt" | 1 + .../23-02-16/18.txt" | 1 + .../23-02-16/19.txt" | 1 + .../23-02-16/2.txt" | 1 + .../23-02-16/20.txt" | 1 + .../23-02-16/21.txt" | 1 + .../23-02-16/22.txt" | 1 + .../23-02-16/23.txt" | 1 + .../23-02-16/24.txt" | 1 + .../23-02-16/25.txt" | 1 + .../23-02-16/26.txt" | 1 + .../23-02-16/27.txt" | 1 + .../23-02-16/28.txt" | 1 + .../23-02-16/29.txt" | 1 + .../23-02-16/3.txt" | 1 + .../23-02-16/30.txt" | 1 + .../23-02-16/31.txt" | 1 + .../23-02-16/32.txt" | 1 + .../23-02-16/33.txt" | 1 + .../23-02-16/34.txt" | 1 + .../23-02-16/35.txt" | 1 + .../23-02-16/36.txt" | 1 + .../23-02-16/37.txt" | 1 + .../23-02-16/38.txt" | 1 + .../23-02-16/39.txt" | 1 + .../23-02-16/4.txt" | 1 + .../23-02-16/40.txt" | 1 + .../23-02-16/41.txt" | 1 + .../23-02-16/42.txt" | 1 + .../23-02-16/43.txt" | 1 + .../23-02-16/44.txt" | 1 + .../23-02-16/45.txt" | 1 + .../23-02-16/46.txt" | 1 + .../23-02-16/47.txt" | 1 + .../23-02-16/48.txt" | 1 + .../23-02-16/49.txt" | 1 + .../23-02-16/5.txt" | 1 + .../23-02-16/50.txt" | 1 + .../23-02-16/51.txt" | 1 + .../23-02-16/52.txt" | 1 + .../23-02-16/53.txt" | 1 + .../23-02-16/54.txt" | 1 + .../23-02-16/55.txt" | 1 + .../23-02-16/56.txt" | 1 + .../23-02-16/57.txt" | 1 + .../23-02-16/58.txt" | 1 + .../23-02-16/59.txt" | 1 + .../23-02-16/6.txt" | 1 + .../23-02-16/60.txt" | 1 + .../23-02-16/61.txt" | 1 + .../23-02-16/62.txt" | 1 + .../23-02-16/63.txt" | 1 + .../23-02-16/64.txt" | 1 + .../23-02-16/65.txt" | 1 + .../23-02-16/66.txt" | 1 + .../23-02-16/67.txt" | 1 + .../23-02-16/68.txt" | 1 + .../23-02-16/69.txt" | 1 + .../23-02-16/7.txt" | 1 + .../23-02-16/70.txt" | 1 + .../23-02-16/71.txt" | 1 + .../23-02-16/72.txt" | 1 + .../23-02-16/73.txt" | 1 + .../23-02-16/74.txt" | 1 + .../23-02-16/75.txt" | 1 + .../23-02-16/76.txt" | 1 + .../23-02-16/77.txt" | 1 + .../23-02-16/78.txt" | 1 + .../23-02-16/79.txt" | 1 + .../23-02-16/8.txt" | 1 + .../23-02-16/80.txt" | 1 + .../23-02-16/81.txt" | 1 + .../23-02-16/82.txt" | 1 + .../23-02-16/83.txt" | 1 + .../23-02-16/84.txt" | 1 + .../23-02-16/85.txt" | 1 + .../23-02-16/86.txt" | 1 + .../23-02-16/87.txt" | 1 + .../23-02-16/88.txt" | 1 + .../23-02-16/89.txt" | 1 + .../23-02-16/9.txt" | 1 + .../23-02-16/90.txt" | 1 + .../23-02-16/91.txt" | 1 + .../23-02-16/92.txt" | 1 + .../23-02-16/93.txt" | 1 + .../23-02-16/94.txt" | 1 + .../23-02-16/95.txt" | 1 + .../23-02-16/96.txt" | 1 + .../23-02-16/97.txt" | 1 + .../23-02-16/98.txt" | 1 + .../23-02-16/99.txt" | 1 + .../23-02-16/demo.js" | 24 +++++++++++ 106 files changed, 124 insertions(+), 97 deletions(-) delete mode 100644 wish.html delete mode 100644 "\346\235\216\345\255\220\344\272\221/2-13/\347\254\224\350\256\260.txt" delete mode 100644 "\346\235\216\345\255\220\344\272\221/2-15 \345\205\250\345\261\200\345\222\214\346\250\241\345\235\227/jie.js" delete mode 100644 "\346\235\216\345\255\220\344\272\221/2-15 \345\205\250\345\261\200\345\222\214\346\250\241\345\235\227/zy.js" delete mode 100644 "\346\235\216\345\255\220\344\272\221/2-16\344\275\234\344\270\232/zy.js" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/1.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/10.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/100.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/11.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/12.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/13.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/14.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/15.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/16.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/17.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/18.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/19.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/2.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/20.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/21.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/22.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/23.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/24.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/25.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/26.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/27.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/28.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/29.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/3.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/30.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/31.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/32.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/33.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/34.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/35.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/36.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/37.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/38.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/39.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/4.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/40.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/41.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/42.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/43.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/44.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/45.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/46.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/47.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/48.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/49.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/5.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/50.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/51.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/52.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/53.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/54.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/55.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/56.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/57.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/58.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/59.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/6.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/60.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/61.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/62.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/63.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/64.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/65.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/66.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/67.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/68.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/69.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/7.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/70.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/71.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/72.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/73.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/74.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/75.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/76.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/77.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/78.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/79.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/8.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/80.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/81.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/82.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/83.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/84.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/85.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/86.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/87.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/88.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/89.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/9.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/90.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/91.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/92.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/93.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/94.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/95.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/96.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/97.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/98.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/99.txt" create mode 100644 "\346\235\250\350\215\243\346\237\217/23-02-16/demo.js" diff --git a/wish.html b/wish.html deleted file mode 100644 index 8fd0b0f..0000000 --- a/wish.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - 要工作了 - - -

好好学习,努力挣钱,养自己/养女朋友/养男朋友

- - \ No newline at end of file diff --git "a/\346\235\216\345\255\220\344\272\221/2-13/\347\254\224\350\256\260.txt" "b/\346\235\216\345\255\220\344\272\221/2-13/\347\254\224\350\256\260.txt" deleted file mode 100644 index 87f962f..0000000 --- "a/\346\235\216\345\255\220\344\272\221/2-13/\347\254\224\350\256\260.txt" +++ /dev/null @@ -1,7 +0,0 @@ -git branch 显示分支 -git branch 分支名 创建分支 -git add 添加文件 -git status 添加到当前分支 -git checkout 分支名 切换分支 -commit -m '内容' 上传 -push 提交 diff --git "a/\346\235\216\345\255\220\344\272\221/2-15 \345\205\250\345\261\200\345\222\214\346\250\241\345\235\227/jie.js" "b/\346\235\216\345\255\220\344\272\221/2-15 \345\205\250\345\261\200\345\222\214\346\250\241\345\235\227/jie.js" deleted file mode 100644 index bf2b645..0000000 --- "a/\346\235\216\345\255\220\344\272\221/2-15 \345\205\250\345\261\200\345\222\214\346\250\241\345\235\227/jie.js" +++ /dev/null @@ -1,5 +0,0 @@ -let obj=require('./zy') -console.log(obj.jia(3,1)) -console.log(obj.jian(6,1)) -console.log(obj.cheng(2,1)) -console.log(obj.chu(2,1)) \ No newline at end of file diff --git "a/\346\235\216\345\255\220\344\272\221/2-15 \345\205\250\345\261\200\345\222\214\346\250\241\345\235\227/zy.js" "b/\346\235\216\345\255\220\344\272\221/2-15 \345\205\250\345\261\200\345\222\214\346\250\241\345\235\227/zy.js" deleted file mode 100644 index e796b7a..0000000 --- "a/\346\235\216\345\255\220\344\272\221/2-15 \345\205\250\345\261\200\345\222\214\346\250\241\345\235\227/zy.js" +++ /dev/null @@ -1,43 +0,0 @@ -// ### 作业:写个加减乘除的模块(尽量少写暴露,要考虑复用性),供外部使用. 作业每个分支要建一个目录(自己名字) -let jieguo; -let obj={ - jia:function(a,b){ - if(Number(a) && Number(b)){ - jieguo=Number(a)+Number(b) - }else{ - jieguo="输入的必须为数字" - } - - return jieguo; - }, - jian:function(a,b){ - if(Number(a) && Number(b)){ - jieguo=Number(a)-Number(b) - }else{ - jieguo="输入的必须为数字" - } - - return jieguo; - }, - cheng:function(a,b){ - if(Number(a) && Number(b)){ - jieguo=Number(a)*Number(b) - }else{ - jieguo="输入的必须为数字" - } - - return jieguo; - }, - chu:function(a,b){ - if(Number(a) && Number(b)){ - jieguo=Number(a)/Number(b) - }else{ - jieguo="输入的必须为数字" - } - - return jieguo; - }, - - -} -module.exports=obj \ No newline at end of file diff --git "a/\346\235\216\345\255\220\344\272\221/2-16\344\275\234\344\270\232/zy.js" "b/\346\235\216\345\255\220\344\272\221/2-16\344\275\234\344\270\232/zy.js" deleted file mode 100644 index c2401f2..0000000 --- "a/\346\235\216\345\255\220\344\272\221/2-16\344\275\234\344\270\232/zy.js" +++ /dev/null @@ -1,30 +0,0 @@ -// ## 作业:生成100个文件,每个文件存入一个1到1000的随机数字,再取出最大值的那个文件,值也要取出来,再取出最小的那个. -let fs=require("fs"); -let shu=[] -let max=0 -let maxwj=0; - -let min=1001; -let minwj=0; -for(let i=1;i<101;i++){ - //创建随机数 - let num=Math.ceil(Math.random()*1000); - //创建一百个文件并且赋值随机数 - fs.writeFileSync("./"+i+".txt",""+num+""); - //读取一百个文件内容并且存入数组 - shu[i]=(fs.readFileSync("./"+i+".txt").toString()); - //最大值 - if(Number(shu[i])>max){ - max=Number(shu[i]) - maxwj=i; - } - //找最小 - if(Number(shu[i])max){ + max = y; + maxname = x+".txt"; + } + if(y