NodeJS笔记二---kalrry

  • NodeJS
    • 服务器
      • 什么是服务器
      • web服务端保存的资源:
      • web服务器(软件)的作用:
    • nodeJS
      • 介绍
      • 目标
      • 优势
      • 劣势
      • 特点:
      • 环境安装
      • 版本
      • 运行
        • window
        • 苹果
        • vscode
        • webstrom
      • **注意**
    • web服务器的开发
      • 1、搭建服务器 (http模块)
      • 2、静态资源托管(fs模块)
        • 2.1 fs模块
        • 2.2 path模块
      • 3、动态资源(接口实现)
        • 3.1 url模块
        • 3.2 querystring 模块
        • 3.3 获取非地址栏的数据:
    • 模块化规范 commonJS
      • 1、模块化的作用
      • 2、常见的模块化
      • 3、规范是什么
      • 4、commonJS的模块:
      • 5、commonJS模块化格式:
        • 1)、导入(引入)
        • 2)、导出(输出,对外开放)
    • 第三方模块化的管理工具
      • 1、NPM
        • 作用
        • 安装到全局(操作系统)环境
        • 安装到项目环境(本地安装)
          • 初始化项目环境
          • 项目依赖(生产依赖)
          • 开发依赖
        • 查看包
        • 安装所有依赖
        • 版本约束
        • 选择源(选择最快的源进行安装)
        • 安装卡顿时
        • 发布包
      • 2、YARN
        • 安装
        • 使用
      • 3、BOWER
        • 安装bower
        • 安装包到全局环境
        • 安装包到项目环境
          • 初始化项目环境
          • 项目依赖
          • 开发依赖
    • EXPRESS框架
      • 特点
      • 安装
      • 搭建服务器
      • 静态资源托管
      • 动态资源(接口实现)
        • 不同请求方式对应的函数
        • req 请求体
        • res 响应体
        • 处理 多个接口的 公共业务
      • use函数
      • 中间件
      • 扩展
        • req
        • res
    • express脚手架
      • 1、用express脚手架创建项目
      • 2、安装express的依赖
      • 3、 启动express的项目:
      • 4、访问项目
      • 5、脚手架项目解析
    • 后端渲染
      • 模板引擎
      • ejs
        • ejs介绍:
        • ejs特点:
        • **原理**:
        • **使用**
      • 前后端交互流程
    • 数据库
      • 1、回顾mysql
      • 2、node + mysql客户端
      • 3、mongodb
      • 4、node+mongodb
        • 1)、Mongoose简介
        • 2)、安装mongoose
        • 3)、mongoose连接数据完成增删改查
    • MVC
    • web开发中的架构:
      • **耦合架构**
      • **半分离架构**
      • **分离架构**
    • restful规范
      • 概念:
      • 优点:
      • 规范
    • bcrypt模块
      • 介绍:
      • 安装:
      • 加密代码:
    • 身份验证
      • session(会话)
        • 思想
        • 业务场景:
        • express-session
      • token
        • 思想
        • 实现
      • session vs token
      • 如何保存信息给浏览器(cookie)
    • 文件上传
      • multer中间件
    • BSR&&SSR&&SEO
      • BSR
      • SSR
      • SSR与BSR的区别
      • SEO
    • SOCKET
      • socket应用
      • socket介绍
      • socket的通讯流程
      • webSocket
      • webSocket对象介绍
        • 属性
        • 事件
        • 方法
        • 使用步骤:
      • socket.io
        • 介绍:
        • 思路:
        • 代码:

待整理ing

NodeJS

大纲:

1、搭建服务器

2、mongodb 注册和登录增删改查新闻(bootstrap)

3、api server 注册和登录增删改查新闻(bootstrap)

4、bcrypt加密 注册和登录

5、session 登录和其它需要验证身份的模块(如:添加,删除)

6、token 登录,其它需要验证身份的模块(如:添加,删除)

7、上传图片:添加新闻

8、socket :做聊天室

服务器

什么是服务器

服务器就是提供服务的,有web服务器,数据库服务器等等…………

web服务端保存的资源:

静态资源

xx.css xx.html xx.js xx.图片 xx.json xx.字体 … 等等在前端使用的文件。这些文件的内容每次打开时,都是一样的,所以叫静态资源。

动态资源(也有接口)

​ 后端的程序,如:二阶段学习的php文件

web服务器(软件)的作用:

​ 1、接收前端请求
​ 2、查找文件
​ 3、执行服务器端代码
​ 4、响应

node完成了二阶段中apache和php的功能

nodeJS

介绍

​ 后端的编程语言,与之类似有 php c# java ,python,go。不但是后端的编程语言,还可以搭建服务器,如:apche等。

​ nodeJS就是ECMAScirpt。在原来学习的ES的基础上增加了后端相关的API,如:HTTP,fs,URL等等。让javascript还可以做后端的开发,即一门语言搞定前后端,即全栈

目标

数据服务:连接数据库

文件服务:文件上传等等。

web服务:web服务器(如:apache)

优势

性能高,方便、对于前端人员来说入门难度低、大公司都在用(BAT)。

坊间传说:一台node的服务器顶得上86台php服务器。特别是在处理并发的场景,尤为明显。

劣势

  • 服务器提供的相对较少
  • 相对其他语言,能用的上的学习资料少
  • 对程序员的要求高了

特点:

单线程:nodeJS是单线程的,那么如何面对并发,靠的是事件循环。
https://blog.csdn.net/jiang7701037/article/details/95887439
非阻塞 :
NodeJS在访问高IO(input/output)操作后不会等待其完成,而是立即去执行其他代码,操作完成后会使用回调函数返回,保证高效的利用当前线程的cpu 不造成硬件浪费。跟异步差不多。

事件驱动:
通过事件来驱动整个程序的进行, 由于是单线程,所以把高IO的操作 就会移动到事件队列中等待完成,完成后通过回调函数的方式返回给线程来进行处理。这个循环处理的过程称之为:事件循环

环境安装

官网:英文 中文 镜像

测试环境: win+r->命令行(运行->cmd)->node -v

版本

Vx(主).x(子).x(修正)

主版本: 变化了,1/3的API发生巨变 , 使用方式变化了

子版本: API没有删减,使用方式没变化,内部实现发生了变化

修正版: 什么都没变,处理一下bug

V6.8.0 稳定

V6.9.1 非稳定版

beta 测试

rc 、alpha测试稳定

运行

window
a. 找到目标目录-》地址栏输入cmd-》node 文件名.js | node 文件名b. 当前目录->右键->git bash-> node 文件名
苹果
终端->cd 目录-> node 文件名.js | node 文件名
vscode
新建终端->cd 目录->node 文件名.js | node 文件名
调试->运行
webstrom
terminal| run

注意

nodejs 使用的是ECMA语法,不可使用DOMBOM 因为后端开发没有浏览器。

即:前端js代码在浏览器上运行;后端js代码在node环境里运行的。

web服务器的开发

(回顾二阶段)

1、搭建服务器 (http模块)

​ 搭建服务器要使用http模块,http模块,可以创建服务器对象,同时,可以处理请求和响应

1)、引入http模块

let http = require('http')

2)、创建web服务 返回http对象

let app = http.createServer((req,res)=>{req 请求体(请求对象)  浏览器->服务器,服务器端把浏览器发送来的信息整理到req对象里。req.url  地址   提取地址栏数据req.on('data') 提取非地址栏数据 所有的http[s]都会触发end事件req.on('end') res 响应体(响应对象)  服务器->浏览器,服务器端给浏览端发送的信息都整理在res里。res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});响应头设置res.write(字符/数据<string><buffer>) 返回数据res.end() 结束响应 必须})

3)、监听服务器

app.listen(端口,[地址],[回调])

端口: 1-65535 1024以下系统占用

地址:localhost 真实域名xx.duapp.com,ip地址也行。

回调:监听成功,回调一次

4)、启动服务器的命令:

node 文件名

搭建服务器的示例代码:

// 1、引入http模块(nodeJS官方的模块,是个对象)
const http = require("http");// 2、创建服务器对象
let server = http.createServer((req,res)=>{// req:请求对象(包含所有前端请求的信息,如:url,method,)console.log("req.url",req.url);console.log("req.method",req.method);// res:响应对象(包括响应所使用的函数等等,如:res.write() )res.writeHeader(200,{"Content-type":"text/html;charset=utf-8"})// res.setHeader("Content-type","text/html;charset=utf-8")// res.write():给前端响应数据的res.write("<h1>欢迎光临1!</h1>");res.write("<h1>欢迎光临2!</h1>");res.write("<h1>欢迎光临3!</h1>");res.write("<h1>欢迎光临4!</h1>");res.end();
});// 3、启动服务器
server.listen(9000,"10.35.165.56",()=>{console.log("启动成功,请访问……");
})

热部署和启动命令

由于,每次更新代码后, 需要重新启动服务器,很麻烦

推荐命令行工具:supervisor 或者nodemon

安装方式: npm install supervisor -g 或者 npm install nodemon -g

启动服务器 nodemon 文件名

2、静态资源托管(fs模块)

fs:fileSystem; 这个模块可以读取文件的内容,给文件写内容,创建文件夹,删除文件夹等等有关文件和文件夹的一切操作。

一般来说,前端的如下代码都会请求一个静态资源

<a href=".."></a>
<img src="..."/>
location.href="..."
body{background:url(....)
}

后端资源读取静态资源文件就要使用fs模块

fs.readFile(文件名,[编码方式],回调(err,data));

2.1 fs模块

磁盘操作,文件操作

读取

异步的方式:fs.readFile('文件路径',[编码方式],(err,data)=>{})

[^err ]: err 错误 ,null没有错误

同步的方式: let data = fs.readFileSync('文件路径')

处理错误

try{

​ 要排错的代码,如果try分支里有错误,那么就会进入到catch分支。

}catch(e){

}

2.2 path模块

操作系统磁盘路径

windows: c:\user\admin 磁盘的路径的分割是: \ 网络上的路径分割是 /
mac: ~/desktop/1901

API

磁盘路径解析 parse

path.parse('c:\\wamp\\xx.png') // string -> object//返回
{root: 'c:\\', 盘符dir: 'c:\\wamp', 目录base: 'xx.png',  文件名ext: '.png', 扩展名name: 'xx'    文件,不含扩展名
}

片段合并join

path.join('磁盘路径1','磁盘路径2','磁盘路径n')

__dirname :nodeJS的官方全局变量, 返回当前文件所在的磁盘路径。

片段合并 resolve

path.resolve('磁盘路径1','磁盘路径n')

合并磁盘片段,右到左找,如果找到了根,那就不再朝前找了;拼接时,是从左到右拼接,如果没有给根路径,以当前文件路径为根(即默认:加上 __dirname)。

静态资源的示例代码:

//一、在目录下建立  www 目录,写几个html文件//二、服务器代码
// 1、引入http模块(nodeJS官方的模块,是个对象)
const http = require("http");
const fs = require("fs");// 2、创建服务器对象
let server = http.createServer((req, res) => {if (req.url != "/favicon.ico") {try {let filename = "./www" + req.url;let data = fs.readFileSync(filename, "utf8");res.write(data);res.end();} catch (error) {res.write("服务器出错了");res.end();} }
});// 3、启动服务器
server.listen(9000, "10.35.165.56", () => {console.log("启动成功,请访问……");
})

3、动态资源(接口实现)

前端

表单:get/post/put/delete/…

js: ajax/jsonp

后端(如同二阶段的php)

处理方式:http[s]

​ 地址栏上的数据: req.url 抓取 get请求的数据 切字符 | url模块

​ 非地址栏的数据 : req.on('data',(chunk)=>{CHUNK==每次收到的数据buffer})

req.on('end',()=>{ 接收完毕 切字符 querystring })

postman 一个不用写前端,就可以发出各种请求的软件 下载

3.1 url模块

作用

处理 url格式的字符串

用法

url.parse(str,true)  返回 对象   true处理query为对象

str -> obj 返回 对象 true
protocol: ‘http:’, 协议
slashes: true, 双斜杠
auth: null, 作者
host: ‘localhost:8002’, 主机
port: ‘8002’, 端口
hostname: ‘localhost’, baidu
hash: ‘#title’, 哈希(锚)
search: ‘?username=sdfsdf&content=234234’, 查询字符串
query: ‘username=sdfsdf&content=234234’, 数据
pathname: ‘/aaa’, 文件路径
path: ‘/aaa?username=sdfsdf&content=234234’, 文件路径
href: ‘http://localhost:8002/aaa?username=sdfsdf&content=234234#title’

url.format(obj) 返回字符

obj -> str 返回str

3.2 querystring 模块

作用

处理查询字符串 如:?key=value&key2=value2

用法

querystring.parse(str) 返回对象
querystring.stringify(obj) 返回字符串

3.3 获取非地址栏的数据:

如:前端使用post发来的数据

使用:

//用req.on绑定事件data:接收一次数据(一般来说:65536字节),触发一次data
req.on('data',(chunk)=>{})//用req.on绑定事件end:接收完毕。
req.on('end',(err)=>{})

动态资源的示例代码:

const http = require("http");
const url = require("url");let server = http.createServer((req, res) => {// 1、根据书籍编号获取书籍详情// url: bookdetail// method:get// params:bookid  (书籍的编号)// 返回数据格式:// {//     status:"success",//     data:{//         bookid:"01001",//         bookname:"论语",//         bookauthor:"敖东",//     }// }// console.log("req.url",req.url);let urlObj = url.parse(req.url, true);if (urlObj.pathname === "/bookdetail") {// 1、接收前端的数据let bookid = urlObj.query.bookid;// 2、查询数据库// 3、响应res.setHeader("Conent-type","text/plain");if (bookid == "01001") {res.write(`{status: "success",data: {bookid: "01001",bookname: "论语",bookauthor: "敖东",}}`)}else if (bookid == "01002") {res.write(`{status: "success",data: {bookid: "01002",bookname: "中庸",bookauthor: "王冰芊"}}`)}else{res.write(`{status: "fail"}`) }res.end();}// 2、注册// url: regSave// method:post// params://   username:用户名//   userpass:密码// 返回数据格式:// {//     status:"success",//fail// }if (urlObj.pathname === "/regSave") {// 1、接收前端发来的数据//用req.on绑定事件data:接收一次数据(一般来说:65536字节),触发一次datalet str = "";req.on("data",(chunk)=>{console.log("chunk",chunk);// chunk: 本次接收到一块的数据str += chunk;});//用req.on绑定事件end:接收完毕。req.on("end",(err)=>{if(!err){console.log("接到数据是:",str);// 2、处理(连接数据库)// 3、响应 let obj = JSON.parse(str);if(obj.username=="敖东" && obj.userpass=="123"){// res.write(`{//        status:"success",// }`);// res.end();res.end(`{status:"success",}`);}else{res.end(`{status:"fail",}`);}}});}});server.listen(9000, "localhost", () => {console.log("启动成功,请访问……");
})

模块化规范 commonJS

1、模块化的作用

1)、防止全局变量和全局函数重名,不污染全局变量。

2)、隐藏了细节

3)、js文件引用js文件。如果说前端还可以用html引入js文件的话,那么后端就不可能了,因为后端代码里没有html。

2、常见的模块化

前端模块化规范:CMD,AMD,ES6

后端的模块化规范:commonJS,ES6

3、规范是什么

如:

​ AMD是个规范,requireJS是AMD规范的体现

​ CMD是个规范,seaJS是CMD规范的体现

​ commonJS是个规范,node和webpack是commonJS规范的体现

​ ECMA是个规范,JS/AS是ECMA实现了它

4、commonJS的模块:

系统模块

http fs querystring url

第三方模块:

​ gulp

自定义模块:

5、commonJS模块化格式:

1)、导入(引入)

let 变量名 = require('模块名')    // 得到的是个对象  ES6中import
let 变量名 = require('模块名').xx  按需引用  //得到的是对象的某个属性

不指定路径:先找系统模块-> 再从项目环境找node_modules|bower_components (依赖模块)->not found

指定路径 : 找指定路径 -> not found

支持任何类型

所以:系统模块和第三方模块不需要写路径。而我们 的自定义模块需要写路径。

2)、导出(输出,对外开放)

exports.自定义属性 = 值( 任意类型)   //ES6 的 export

可输出多次

如:exports.name = “张三疯”;

​ exports.sex = “男”;

​ exports.person= {

​ }

module.exports = 值( 任意类型)   //ES6 的 export default

只能输出一次,输出的为任意类型的数据,或者类。

如:

module.exports = {

}

module.exports = class Person{

​ constructor(){

​ }

}

模块化规范的代码:

把上面的代码进行提取

//一、routes/bookdetail.js
// 1、根据书籍编号获取书籍详情// url: bookdetail// method:get// params:bookid  (书籍的编号)// 返回数据格式:// {//     status:"success",//     data:{//         bookid:"01001",//         bookname:"论语",//         bookauthor:"敖东",//     }// }
const url = require("url");module.exports = function(req,res){let urlObj = url.parse(req.url, true);// 1、接收前端的数据let bookid = urlObj.query.bookid;// 2、查询数据库// 3、响应res.setHeader("Conent-type","text/plain");if (bookid == "01001") {res.write(`{status: "success",data: {bookid: "01001",bookname: "论语",bookauthor: "敖东",}}`)}else if (bookid == "01002") {res.write(`{status: "success",data: {bookid: "01002",bookname: "中庸",bookauthor: "王冰芊"}}`)}else{res.write(`{status: "fail"}`) }res.end();
}//二、routes/regSave.js// 2、注册
// url: regSave
// method:post
// params:
//   username:用户名
//   userpass:密码
// 返回数据格式:
// {//     status:"success",//fail
// }
module.exports = function (req, res) {// 1、接收前端发来的数据//用req.on绑定事件data:接收一次数据(一般来说:65536字节),触发一次datalet str = "";req.on("data", (chunk) => {console.log("chunk", chunk);// chunk: 本次接收到一块的数据str += chunk;});//用req.on绑定事件end:接收完毕。req.on("end", (err) => {if (!err) {console.log("接到数据是:", str);// 2、处理(连接数据库)// 3、响应 let obj = JSON.parse(str);if (obj.username == "敖东" && obj.userpass == "123") {// res.write(`{//        status:"success",// }`);// res.end();res.end(`{status:"success",}`);} else {res.end(`{status:"fail",}`);}}});}//三、 server.js(服务器diam)
const http = require("http");
const url = require("url");
const bookdetail = require("./routes/bookdetail");
const regSave = require("./routes/regSave");let routes ={"/bookdetail":bookdetail,"/regSave":regSave
}let server = http.createServer((req, res) => {let urlObj = url.parse(req.url);routes[urlObj.pathname](req,res)// if (urlObj.pathname === "/bookdetail") {//     bookdetail(req,res);// }else  if (urlObj.pathname === "/regSave") {//     regSave(req,res);// }});server.listen(9000, "localhost", () => {console.log("启动成功,请访问……");
})

第三方模块化的管理工具

1、NPM

作用

帮助你安装模块(包),并且自动安装所有的依赖,管理包(增,删,更新,项目所有包)。

npm服务器上放置了50多万的包,进行统一管理。

类似: bower yarn

安装到全局(操作系统)环境

  • 安装到电脑系统环境下(相当于给操作系统安装了一个软件,只不过,此时用的是npm安装而已)
  • 使用时在任何位置都可以使用(因为,默认配置了环境变量)
  • 被全局安装的通常是:命令行工具,脚手架
npm install 包名 -g                安装
npm uninstall 包名 -g             卸载

安装到项目环境(本地安装)

只能在当前目录使用,需要使用npm 代 运行

初始化项目环境
npm init   //会自动产生package.json文件

package.json文件示例

{"name": "npm",  //项目名称"version": "0.0.1",   //版本"description": "test and play", //描述"main": "index.js", //入口文件"dependencies": {  //项目依赖(生产依赖)  上线也要用"jquery": "^3.2.1"},"devDependencies": { //开发依赖 上线就不用"gulp": "^3.5.2"},"scripts": {   //命令行"test": "命令行"},"repository": {   //仓库信息"type": "git","url": "git+https://github.com/tianwater.github.io/2017-8-28.git"},"keywords": [  //关键词,github上搜索时,可以使用该关键字"test",'xx','oo'],"author": "tianwater","license": "ISC", //认证"bugs": {"url": "https://github.com/alexwa9.github.io/2017-8-28/issues"//问题提交},"homepage": "https://github.com/alexwa9.github.io/2017-8-28#readme"//首页
}
项目依赖(生产依赖)

不但在当前项目下需要使用,上线了,也需要这个依赖 --save

//安装
npm install 包名 --save      //安装最新版本的包
npm install 包名 -S    // --save可以简写为 -S
npm install 包名@x.x.x -S    //安装指定版本的包//卸载
npm uninstall 包名 --save
npm uninstall 包名 -S

安装了项目依赖后,会产生一个package-lock.json,这个文件千万不要删除

{"name": "nodetest","version": "1.0.0","lockfileVersion": 1,"requires": true,"dependencies": {"jquery": { //包名"version": "3.5.0",  //版本号"resolved": "https://registry.npm.taobao.org/jquery/download/jquery-3.5.0.tgz?cache=0&sync_timestamp=1586533502771&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjquery%2Fdownload%2Fjquery-3.5.0.tgz",   //安装来源"integrity": "sha1-mYC5fZ5BlGEcNlMOfcRqWNc0D8k=" //迭代的id}}
}

package-lock.json文件的作用(这个可以以后再理解):

Node.js v8.0 后,npm 也升级到了5.0,其中package-lock.json文件就是npm5开始有的。

  1. package.json文件下载到的依赖包可能在不同的情况下,各库包的版本语义可能并不相同,有的库包开发者并不严格遵守这一原则:相同大版本号的同一个库包,其接口符合兼容要求。所以说,在不同时间或者不同npm下载源之下,下载的各依赖包版本可能有所不同,因此其依赖库包行为特征也不同,有时候甚至完全不兼容。
  2. package-lock.json文件所标识的具体版本下载依赖库包(包的安装来源),就能确保到一个新的机器上所有库包与上次的安装完全一样。
  3. npm的下载源改为私服地址,这样产生的package-lock.json文件的版本号是这个私服上设置好的版本号

​ 场景:

​ 如果在git上下载了别人的代码,或者你的代码拷贝到其它机子上,一般不会拷贝node_modules文件夹。在新的机子上执行命令: npm i 。那么npm会根据package.json里的配置安装所有的依赖,具体的包来自哪个来源,在package-lock.json里。

开发依赖

只能在当前项目下使用 上线了,依赖不需要了 --save-dev

npm install 包名 --save-dev
npm install 包名 -D

npm代运行

即:使用npm执行 package.json文件里的scripts属性里的内容(叫作 npm脚本)

如:

package.json里这样写:

  "scripts": {"test": "echo \"Error: no test specified\" && exit 1","start": "node ./app.js","n":"node"  //全局"j":"jQuery" //项目依赖},

命令行执行 npm run start 就相当于执行 node ./app.js

另外,start属性可以不用加run,其它属性需要加run。即:npm start 就相当于npm run start

命令行执行 npm run n 就相当于执行 node

命令行执行 npm run j 就相当于执行 jQuery

查看包

npm list  列出项目里所有已装包
npm outdated 版本对比(安装过得包),查看项目中安装的包和npm服务器上的包有没有版本上的不同
npm info 包名 查看当前包概要信息
npm view 包名 versions 查看包历史版本,如果想知道jQuery都有哪些版本:npm view jquery versions

current:当前项目中安装的版本号;

wanted:在你安装的当前主版本号里,推荐你使用的子版本号

latest:最新版本号

安装所有依赖

npm install

安装package.json里面指定的所有包

版本约束

^x.x.x   约束主版本,重新安装时,后面两位找最新
~x.x.x   保持前两位不变,重新安装时,最后一位找最新
*        重新安装时,永远装最新的版本
x.x.x    定死了一个版本

选择源(选择最快的源进行安装)

npm install nrm -g     安装选择源的工具包
nrm ls 查看所有源
nrm test 测试所有源,可以看到当前哪个源的速度快
nrm use 切换源名 ,切换到最快的源

安装卡顿时

ctrl+c -> npm uninstall 包名 -> npm cache clean 清除npm的缓存 -> 换移动数据(开热点)-> npm install 包名

发布包

  • 官网 注册

  • 登录(用命令行)

    • 在项目目录下输入:npm login (注意:一定把源切换到npm,不要用其它的镜像)
    • 输入 user/password/email
  • 创建包(写项目)

    • npm init -y
    • 创建入口index.js
    • 编写,输出
  • 发布

    • npm publish

      注意:发布前,首先需要确定 包名(package.json里的name属性)是否在npm的服务器上存在。进入 npm 官网,搜索一下包名:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mqYcOR9H-1644364678041)(C:\Users\31759\AppData\Roaming\Typora\typora-user-images\1588408182571.png)]

    ​ 把目前切换到当前项目下,然后,输入npm publish。

  • 迭代

    • 修改版本号
    • npm publish
  • 删除

    • npm unpublish

包的发布、迭代、删除,需要在包目录下进行

删除包,有时需要发送邮件

2、YARN

官网

安装

去官网安装

注意:为省事,不要用npm i yarn -g,去安装yarn,而是去下载压缩包,保证注册表和环境变量的硬写入,后期通过yarn安装全局包时方便(否则,可能会装不上)

使用

初始化一个新项目

yarn init

添加依赖包

yarn add [package]
yarn add [package]@[version]
yarn add [package]@[tag]

将依赖项添加到不同依赖项类别中

分别添加到 dependencies,devDependenciespeerDependenciesoptionalDependencies 类别中:

yarn add [package] --save   | -S
yarn add [package] --dev    | -D
yarn add [package] --peer
yarn add [package] --optional

升级依赖包

yarn upgrade [package]
yarn upgrade [package]@[version]
yarn upgrade [package]@[tag]

移除依赖包

yarn remove [package]

安装项目的全部依赖

yarn

或者

yarn install

安装到全局

yarn global add [package]                //global的位置测试不能变,global不能写在最后
yarn global remove [package]

3、BOWER

官网

安装bower

npm install -g bower

安装包到全局环境

bower i 包名 -g        安装
bower uninstall 包名 -g    卸载

安装包到项目环境

初始化项目环境
bower init

bower.json 第三方包管理配置文件

项目依赖

只能在当前项目下使用,上线了,也需要这个依赖 --save

//安装
同npm
bower install 包名#x.x.x -S 指定版本使用#//卸载
同npm
开发依赖

只能在当前项目下使用 ,上线了,依赖不需要了 --save-dev

同npm

EXPRESS框架

nodejs库,不用基础做起,工作简单化,点击进入官网,类似的还有 koa

特点

二次封装,非侵入式,增强形

二次封装:保留了原来的功能,做了进一步的增加。

安装

1、全局安装

npm  install express  -gnpm  install express-generator  -g(mac系统中一般没有问题,windows系统下建议安装)express  -h  测试是否安装成功

2、搭建项目,局部安装

1)、新建项目目录
2)、初始化项目:npm init -y
3)、本地安装express:npm i express --save

搭建服务器

let express=require('express')
let app=express();  //相当于调用  http.createServer()
app.listen(端口,地址,回调)

静态资源托管

app.use(express.static('./www'));

动态资源(接口实现)

不同请求方式对应的函数

支持各种请求方式:get、post、put、delete…

app.请求方式API(接口名称,处理函数)
app.get(url,(req,res,next)=>{})
app.post(url,(req,res,next)=>{})
...

req 请求体

req 对象表示 HTTP 请求,把前端发送请求的一切信息封装到了该对象里。包含了请求查询字符串,参数,内容,HTTP 头部等属性。

req.query //获取地址栏的数据
req.body //获取非地址栏的数据  依赖中间件(body-parser) req.params //获取动态接口名   如: /api/goods/:id 的请求,那么,用req.params.id 获取
req.method //获取前端提交方式

req.body依赖中间件

中间件使用:body-parser

  1. npm install body-parser
  2. let bodyParser = require(‘body-parser’)
  3. app.use(bodyParser ())

res 响应体

response 对象表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据

res.send(any)  //send可以返回任何类型,包括对象 //对等 res.write + end
res.end(string|buffer) //原来的方法还在,这就是非侵入式的意思。
res.json(json) //只返回jsonres.status(404).send({error:1,msg:"Sorry can't find that!"}) //返回一个404,并响应内容,这是链式写法res.sendFile(path.resolve('public/error.html')) //发送文件,如:mp3,mp4等等,html也可以。res.redirect(url)   后端跳转  指向一个接口

处理 多个接口的 公共业务

如:token的处理(前端发来token字符串,后端先验证token是否正确,如果正确,才进行接口的处理)

app.all('/admin/*',(req,res,next)=>{}))  表示任何以admin开始的请求(任何类型)都会经过回调函数

all 处理所有类型的 HTTP 请求(如:get,post,put,delete等等)

需要next 延续后续

// 处理以admin开头请求的公共业务
app.all("/admin/*",(req,res,next)=>{req.name1="admin";res.common = "hi";next();
});// 处理 /admin/a
app.get("/admin/a",(req,res,next)=>{console.log("req.name1",req.name1);console.log( "res.common",res.common);console.log("admin/a");res.json({status:"success",msg:"a"});
});// 处理 /admin/b
app.post("/admin/b",(req,res,next)=>{console.log("req.name1",req.name1);console.log( "res.common",res.common);console.log("admin/b");res.json({status:"success",msg:"b"});
});

use函数

安装中间件、路由。接受一个函数, 中间件其实就是个函数

app.use([地址],中间件|路由|函数体)
app.use('/api/*',(req,res,next)=>{ })  //等价于 app.all('/api/ *  ,(req,res,next)=>{});
app.use('/',(req,res,next)=>{ })  //等价于  app.use((req,res,next)=>{ })  )

即:如果不写地址,那么表示 ‘/’ ,即针对任何请求,都会执行该中间件

app.use,app.all,app.get|app.post的关系

app.use :处理中间件(关注点:在完成功能上,如body-parser)

​ app.all:处理请求

​ app.get :处理某种类型请求

​ app.post

​ app.put

​ ………………

中间件

middleware, 处理自定义业务,只处理从 请求 到 结束响应 的中间部分

举例

npm i body-parser -S //安装包let bodyParser=require('body-parser')//引入中间件app.use(bodyParser())//安装中间件(插入中间件)

body-parser 使用方式,实时查询 npm,可获得最新

扩展

req

  • req.app:当callback为外部文件时,用req.app访问express的实例
  • req.baseUrl:获取路由当前安装的URL路径
  • req.cookies:Cookies
  • req.fresh / req.stale:判断请求是否还「新鲜」
  • req.hostname / req.ip:获取主机名和IP地址
  • req.originalUrl:获取原始请求URL
  • req.path:获取请求路径
  • req.protocol:获取协议类型
  • req.route:获取当前匹配的路由
  • req.subdomains:获取子域名
  • req.accepts():检查可接受的请求的文档类型
  • req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一个可接受字符编码
  • req.get():获取指定的HTTP请求头
  • req.is():判断请求头Content-Type的MIME类型

res

  • res.app:同req.app一样
  • res.append():追加指定HTTP头
  • res.set()在res.append()后将重置之前设置的头
  • res.cookie(name,value [,option]):设置Cookie
  • opition: domain / expires / httpOnly / maxAge / path / secure / signed
  • res.clearCookie():清除Cookie
  • res.download():传送指定路径的文件
  • res.get():返回指定的HTTP头
  • res.location():只设置响应的Location HTTP头,不设置状态码或者close response
  • res.render(view,[locals],callback):渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。
  • res.sendFile(path [,options] [,fn]):传送指定路径的文件 -会自动根据文件extension设定Content-Type
  • res.set():设置HTTP头,传入object可以一次设置多个头
  • res.status():设置HTTP状态码
  • res.type():设置Content-Type的MIME类型

作业

把vue的项目(打包后的)利用express搭建的node服务器来管理,保证资源托管到位,部分接口实现。

express脚手架

1、用express脚手架创建项目

 express  -e  项目名(如:express  -e   expressshop)

2、安装express的依赖

 npm i

这是pakeage.json的依赖代码:
“dependencies”: {
“body-parser”: “~1.18.2”, //专门解析前端提交的数据
“cookie-parser”: “~1.4.3”, //专门解析cookie的
“debug”: “~2.6.9”, //调试程序的,显示调试信息,代替console.log
“ejs”: “~2.5.7”, //nodeJS express的模板,可以用此模板渲染前端页面
“express”: “~4.15.5”,
“morgan”: “~1.9.0”, // 日志
“serve-favicon”: “~2.4.5” //用来设置根目录下favicon.ico图标。
}

3、 启动express的项目:

npm  start

4、访问项目

http://localhost:3000。

5、脚手架项目解析

/bin/www文件:启动服务器

/app.js文件: 所有的请求,都会经过该文件。 处理中间件、设置静态资源, 动态资源( 路径和routes文件夹下的文件的对应关系)

routes文件夹 : 逻辑

后端渲染

​ 通常,前端根据后端返回的json数据,然后来生成html被称为前端渲染,而后端渲染是后端把json与html结合渲染好后返回到浏览器,没前端什么事了。

模板引擎

无论前后谁来渲染页面,都会用到模板引擎,前端渲染页面实际上是操作dom,后端渲染页面是把数据和html字符拼接后丢给浏览器

引擎 前端 后端
angularJs ×
vue/mustach
react
angularTs/mustach
jade(现在重命名为了pug) ×
ejs ×
jquery + art-template ×
handlerbars ×

ejs

ejs介绍:

​ “E” 代表 “effective”,即【高效】。EJS 是一套简单的模板语言,帮你利用普通的 JavaScript 代码生成 HTML 页面。EJS 没有如何组织内容的教条;也没有再造一套迭代和控制流语法;有的只是普通的 JavaScript 代码而已。

ejs特点:

纯 JavaScript:
js代码可以直接使用
语法简单:
EJS 支持直接在标签内书写简单、直白的 JavaScript 代码。只需让 JavaScript 输出你所需要的 HTML ,完成工作很轻松

易于调试
调试 EJS 错误(error)很容易:所有错误都是普通的 JavaScript 异常,并且还能输出异常发生的位置。

原理

fs 抓取前端静态页面 + ejs + 数据 -> 返回send(data) -> 浏览器

使用

1)、后端渲染结果

let ejs = require('ejs')
ejs.renderFile('ejs模板文件',renderData,回调(err,data))

ejs模板 : 后缀名为ejs的html文件

renderData:json对象格式。要渲染到ejs模板文件里的数据,这个对象在ejs模块文件里就是个全局对象

err:错误,null代表没有错误

data: 渲染后的字符|流,即:渲染后的结果

2)、后端渲染结果发送给前端

//设置模板文件的路径
app.set('views', path.join(__dirname, 'views'));
//设置模板的引擎
app.set('view engine', 'ejs');res.render('模板文件名',{数据}) //整合页面和数据,完成渲染,发往浏览器,并结束响应

模板文件名:不用写扩展名,直接写文件名就行

数据是json对象

 如:let data = {news:[{"id":"01","title":"特朗普又说谎了"},{"id":"02","title":"特朗普又又说谎了"}]}res.render("news",data);

3)、ejs模板文件语法

  • ejs 结构就是html

  • 语句:所有的JS代码都写在<%与 %>中间,(与:php和html的混合写法一样)

  • 输出: <%= 数据名|属性名|变量名 + 表达式 %>

  • 非转义输出: <%- 数据名|变量名 + 表达式 %>

  • 载入公共:<%- include(’./hd.ejs’,{数据}) %>

  • 判断

    <% if (user) { %><h2><%= user.name %></h2><% } %>
    

其他扩展

前后端交互流程

后端渲染的流程

​ 用户 - > 地址栏(http[s]请求) -> web服务器(收到) - > nodejs处理请求(返回静态、动态)->请求数据库服务(返回结果)->nodejs(接收到数据)->node渲染页面->浏览器(接收页面,完成最终渲染)

前端渲染的流程

​ 用户 - > http[s]请求 -> web服务器(收到) - > nodejs处理请求(返回静态、动态)->请求数据库服务(返回结果)->nodejs(接收到数据)->返回给前端(渲染)->浏览器(接收页面,完成最终渲染)

数据库

1、回顾mysql

​ 关系数据库,二维表,不存在子表,每条数据的字段都是一样的,就算该字段没有值,但是字段依然存在。即:格式是固定的

sql语句

建库

CREATE DATABASE  `2017-12-6` DEFAULT CHARACTER SET armscii8 COLLATE armscii8_general_ci;

建表

CREATE TABLE  `2020-12-6`.`user` (`name` VARCHAR( 32 ) NOT NULL ,`age` INT( 3 ) NOT NULL ,`address` VARCHAR( 128 ) NOT NULL) ENGINE = INNODB

INSERT INTO 表 (字段列表) VALUES(值列表)
INSERT INTO user (name,age,address) VALUES('苏菲',38,'外滩18号')

DELETE FROM 表 WHERE 字段名=值
DELETE FROM user WHERE name='alex'

UPDATE 表 SET 字段名=值 WHERE 字段名=值
UPDATE user set name='sufei' WHERE name='苏菲'

SELECT ? FROM 表
SELECT * FROM user  查所有

2、node + mysql客户端

安装+引入

npm install mysql -S
var mysql = require('mysql');

创建库链接

var connection = mysql.createConnection({host     : 'localhost:3306',//主机名user     : 'root',password : 'root',database : 'mydb2001'//库名
});connection.connect();

表操作

connection.query('SQL语句', function (error, results, fields) {if (error) throw error;console.log('The solution is: ', results==  查询array||  增删改object);
});

关闭库

connection.end();

3、mongodb

非关系型数据库,又叫nosql,缓存型,使用场景多是解决大规模数据集合多重数据种类

mongodb使用内存映射文件(memory-mapped file)来处理对磁盘文件中数据的读写请求。真正的存储(朝硬盘存储)交给操作系统

将MongoDB用作内存数据库(in-memory database),也即,根本就不让MongoDB把数据保存到磁盘中

  1. 下载 安装帮助

  2. 配置数据文件存储位置:

找到安装目录C:\Program Files\MongoDB\Server\4.0\bin -> cmd回车-> mongod --dbpath c:\data\db

这句命令,同时也启动了数据库服务

data和db目录要手动创建

  1. 服务端启动: 可选

找到安装目录C:\Program Files\MongoDB\Server\4.0\bin -> cmd回车-> mongod 回车

一般开启会默认启动

  1. 客户端连接:

找到安装目录C:\Program Files\MongoDB\Server\4.0\bin -> cmd回车-> mongo 回车

  1. 环境变量 可选

为了在任意盘符下去都可以启动 mongod服务端|mongo客户端,把安装目录添加到环境变量

mysql vs mongodb

mysql mongoDb
database(库) database(库)
table(表) collection(集合)
column(字段) field(域)
row(一条数据) document(文档)
二维表,每次存到磁盘 json数组,存在缓存,关闭时存到磁盘 存储方式

mongodb命令行操作 声明式 | obj.api()

库操作

查: show dbsdb 查看当前库
建(存在该库,就是切换):  use 库名

集合(表)操作

建:db.createCollection('表名',{配置})//配置:{size:集合的最大容量,capped:true,max:条数|文档数} capped定量//db.表(集合).isCapped() 返回 true/false 是否是定量
查:show collections / db.getCollectionNames()
删:db.集合.drop()

文档(row)操作

db.集合.save({}) //添加一条
db.集合.insert({})  //添加一条
db.集合.insertOne({}) //添加一条db.集合.save([{},{}]) //多条
db.集合.insert([{},{}]) //多条
//insert  不会替换相同ID  save会

db.集合.deleteOne({查询条件}) //一条db.集合.remove({查询条件},true)  //一条db.集合.remove({查询条件}) //多条db.集合.remove({}) //清空表

db.集合.update({查询条件},{替换条件},[插入false],[全替换false])

查询条件

​ {age:22} age == 22
​ {age:{KaTeX parse error: Expected 'EOF', got '}' at position 6: gt:22}̲} age > 22 ​ {…lt:22}} age < 22
​ {age:{KaTeX parse error: Expected 'EOF', got '}' at position 7: gte:22}̲} age>=22 ​ {a…lte:22}} age<=22
​ {age:{lte:122,lte:122,lte:122,gte:22}} age<=122 && age>=22
​ {$or:[{age:22},{age:122}]} age22 or age122
​ {key:value,key2:value2} key== value && key2==value2
​ {name:/正则/}

替换条件

{set:age:12,set:{age:12},set:age:12,inc:{age:-1}}

所有:db.集合.find(条件)条数: db.集合.find().count()db.集合.find({条件},{指定要显示列区域})

指定要显示列区域

username:1 显示这个区域,其他不显示

username:0 不显示这个区域,其他显示

_id 是默认显示

db.集合.find().sort({key:1}) //升
db.集合.find().sort({key:-1}) //降
db.集合.find().sort({key1:1,key2:-1}) // 按照key1升序,key1相同时,按照key2降序

限定

db.集合.find().limit(number)  //限定
db.集合.find().skip(number)   //跳过
db.集合.findOne()//找第一个
db.集合.find().limit(1)  //查询第一条

4、node+mongodb

1)、Mongoose简介

mongoose是nodeJS提供连接 mongodb的一个模块,便捷操作MongoDB的对象模型工具(Mongoose的操作是以对象为单位的)

2)、安装mongoose

​ npm i mongoose --save

3)、mongoose连接数据完成增删改查

//1、conndb.js  连接数据库
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/db2106',{useNewUrlParser:true} //使用解析器来解析本次连接
);
module.exports = mongoose;// 2、usersdb.js //针对集合users的所有操作(一般来说,增删改查)
let mongoose = require('./conndb'); //引入连接数据库的代码//模板:创建集合users对应的模板(相当于表结构,在nodejs里创建一个表结构)
let userSchema = new mongoose.Schema({'userName':String,'userPass':String
});//模型:(把数据库中集合users和模板进行对应和绑定)
let UserModel = mongoose.model('users',userSchema);module.exports = {//1)、添加addUser:function(user,success,fail) {//1)、创建实体(要添加到数据库中的数据)let userEntity = new UserModel({userName:"敖东",userPass:"123"});userEntity.save((err,data)=>{if(err){  fail&&fail();}else{   success&&success(); }});}//2)、查询queryUser:function(obj,success,fail){UserModel.find(obj,(err,data)=>{if(err){   fail&&fail();  }else{   success&&success(data); }});},
//3、删除removeUser:function(obj,success,fail){UserModel.remove(obj,(err,data)=>{if(err){fail&&fail();}else{success&&success(data);}});},
//4、修改updateUser:function(condationObj,updateObj,success,fail){UserModel.update(condationObj,updateObj,(err,data)=>{if(err){fail&&fail();}else{success&&success(data);}});}

示例(作业):

1、mongodb 注册和登录增删改查新闻(bootstrap)

2、理解api server和webserver

​ apiserver:只提供数据(完成的接口) ,上周做的vue联合项目中的java同学做的就是apiserver

​ webserver:有页面,上周做的vue联合项目中的我们前端做的是webserver

MVC

项目架构,项目分层,不同的层的职责不同。

C:controller,控制器。(控制的就是某个功能的业务流程)
routers文件夹下的文件。
根据业务流程,调用不同的模块完成对应的功能。

V:view:视图(显示)
views文件夹下的文件。完成显示的格式。使用ejs模板,jade模板

M:model,模型(只是数据处理)
业务逻辑处理,更多体现的是数据库的增删改查,完成具体的功能

​ db文件夹

web开发中的架构:

耦合架构

半分离架构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-whceM72h-1644364678041)(D:\2110third\02node\nodejs_T_v5\image-20211110115658026.png)]

web的工作流程:

1、打开web,加载静态资源,如HTML,CSS,JS等;

2、发起一个Ajax请求再到服务端请求数据,同时展示loading;

3、得到JSON格式的数据后再根据逻辑选择模板渲染出DOM字符串;

4、将DOM字符串插入HTML页面中渲染出DOM结构;

分离架构

​ **前端渲染:**vue脚手架的项目是前后端分离,但是用的是前端的渲染

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PdzLosfl-1644364678041)(D:\2110third\02node\nodejs_T_v5\image-20211110115552713.png)]

​ **后端渲染:**如果要使用后端渲染,那么就需要使用ejs。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cs1LqEdx-1644364678042)(D:\2110third\02node\nodejs_T_v5\image-20211110115419083.png)]

web的工作流程:
1)浏览器请求服务器端的NodeJS;
2)NodeJS再发起HTTP去请求JSP;
3)JSP的API输出JSON给NodeJS;
4)NodeJS收到JSON后再渲染出HTML页面;
5)NodeJS直接将HTML页面发送给浏览器;
这样,浏览器得到的就是普通的HTML页面,而不用再发Ajax去请求服务器了。

restful规范

概念:

RESTful (资源数据接口规范) 是目前最流行的 API 设计规范,用于 Web 数据接口的设计。
前端设备层出不穷(手机、平板、桌面电脑、其他专用设备…)。因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信。这导致API构架的流行。RESTful API是目前比较成熟的API设计理论。要搞清楚restful规范,必须先了解REST。REST强调HTTP应当以资源为中心,并且规范了资源URI的风格;规范了HTTP请求动作(PUT,POST等)的使用,具有对应的语义。

如:
员工信息的uri :http://www.qianfeng.com/employees
书籍信息的uri :http://www.qianfeng.com/books
编号为01001的书籍信息的uri :http://www.qianfeng.com/books/01001

即:不同的资源(信息)是不同的uri

优点:

​ 遵循REST规范的Web应用将会获得下面好处:
​ URL具有很强可读性的,
​ 具有自描述性;
资源描述与视图的松耦合
可提供OpenAPI,
便于第三方系统集成,提高互操作性;
​ 如果提供无状态的服务接口,可提高应用的水平扩展性;

规范

URI
URI(Uniform Resource Identifiers) 统一资源标示符,能够统一标识一个资源的符号都是URI
URL(Uniform Resource Locator) 统一资源定位符,是URI的一种体现形式。
在restfulAPI的规范里,要让一个资源可以被识别,需要有个唯一标识,在Web中这个唯一标识就是 URI(Uniform Resource Identifier),

URI的格式定义如下:

​ URI = scheme “

NodeJS笔记二---kalrry相关推荐

  1. Vue笔记随笔---kalrry

    Vue笔记随笔---kalrry VUE vue框架的两大核心: 一.前端开发历史 二.MV*模式 库 VS 框架 MVC架构模式 MVP架构模式 MVVM架构模式 vue是MVVM 三.开发工具 四 ...

  2. node笔记随笔---kalrry

    node笔记随笔---kalrry nodeJS 服务器 什么是服务器 web服务端保存的资源: web服务器(软件)的作用: nodeJS 介绍 目标 优势 劣势 特点: 环境安装 版本 运行 wi ...

  3. React笔记随笔---kalrry

    React笔记随笔---kalrry React 一.React的简介 1.介绍 2.特点 3.框架对比 二.环境搭建 1.引入文件的方式 2.官方脚手架(模块化) 第三方脚手架 第一个React程序 ...

  4. nodejs linux模块全局,nodejs笔记一--模块,全局process对象;

    一.os模块可提供操作系统的一些基本信息,它的一些常用方法如下: var os = require("os"); var result = os.platform(); //查看操 ...

  5. Nodejs笔记之易错点整理

    Nodejs笔记整理 最近学了在b站学了nodejs,一边看一边敲,现在回过来重新看一下代码,并整理一下笔记.文章可能有不严谨的地方,希望多多指教. 关于结束响应 使用http创建服务器是,res() ...

  6. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7851 ...

  7. oracle直查和call哪个更快,让oracle跑的更快1读书笔记二

    当前位置:我的异常网» 数据库 » <>读书笔记二 <>读书笔记二 www.myexceptions.net  网友分享于:2013-08-23  浏览:9次 <> ...

  8. 【Visual C++】游戏开发笔记二十七 Direct3D 11入门级知识介绍

    游戏开发笔记二十七 Direct3D 11入门级知识介绍 作者:毛星云    邮箱: happylifemxy@163.com    期待着与志同道合的朋友们相互交流 上一节里我们介绍了在迈入Dire ...

  9. [转载]dorado学习笔记(二)

    原文地址:dorado学习笔记(二)作者:傻掛 ·isFirst, isLast在什么情况下使用?在遍历dataset的时候会用到 ·dorado执行的顺序,首先由jsp发送请求,调用相关的ViewM ...

最新文章

  1. python使用imbalanced-learn的KMeansSMOTE方法进行上采样处理数据不平衡问题
  2. 数据结构5: 链表(单链表)的基本操作及C语言实现
  3. 详解Android Handler的使用
  4. Android开发之将Android SVG 转 VectorDrawable矢量图的方法
  5. php长传文件到数据库,php上传文件并存储到mysql数据库的简单示例
  6. Spring之JDBCTemplate
  7. (数据库系统概论|王珊)第九章关系查询处理和关系优化-第三节:查询优化之代数优化
  8. 2.7.3-YARN-获取debug命令:resourceManager+nodeManager
  9. python示例_Python中的缩进示例
  10. PowerShell+you-get批量下载B站视频
  11. 使用QT5 PrintSupport打印和预览标签
  12. 【OpenCV4】fatal error: opencv2/core.hpp: No such file or directory 解决方法
  13. 十分钟掌握Google Guice(上)
  14. Hexo博客进阶:为 Next 主题添加 Waline 评论系统
  15. 计算机黑屏然后蓝屏怎么办,突然蓝屏死机开机黑屏怎么办_蓝屏之后重启屏幕黑屏的解决方法...
  16. Photoshop cs5 永久序列号
  17. 三角公式以及常见关系
  18. 教你如何用思维导图把一本书内容绘制成一张A4纸!
  19. mysql中update和limit_在MySQL中可以将UPDATE查询与LIMIT一起使用吗?
  20. 【论文精读】CMT: Convolutional Neural Networks MeetVision Transformers

热门文章

  1. niuke题霸SQ/L篇
  2. MATLAB中数据平滑处理
  3. 【Unity】制作手游的帧同步时遇到的问题
  4. 微型计算机 电脑爱好者,电脑爱好者杂志
  5. joyfire linux笔记 感谢原作者
  6. 计算机应用技术第一课,计算机应用基础(第一课)
  7. RF使用技巧--导入自定义的库文件
  8. Monkey 简介操作
  9. android图片透明度跟缩放大小动画事件
  10. Uboot启动的第二阶段