首页 > 编程语言 >node的一部分知识(还在学习)

node的一部分知识(还在学习)

时间:2023-07-23 22:24:16浏览次数:38  
标签:node express console log res 知识 学习 fs const

node.js

一,node最基础

一,为什么要学node.js

1.可以让每个人都访问到我们的网页

2.为了学习vue

二,node是什么

一款应该程序,是一个软件,可以运行javascript

三,node的作用

1.开发服务器端应用

2.开发工具类应用

3.开发桌面端应用

四,node的安装

之前安装过

二,命令的相关知识

一,认识命令行工具

windows+r cmd

二,命令的结构

命令的名称+命令的参数1+参数2

三,常用的命令

说明操作
切换盘符 C: D:
切换工作目录 c'd
查看目录文件 dir

三,node开始

一,第一个node

helloworld.js

console.log('hello world')

在终端运行 node helloworld.js后得到结果

二,node编写时的注意事项

1.不能够使用BOM,DOM的API,可以使用console和定时器API

2.顶级对象为global,可以用globalThis访问顶级对象

四,Buffer

一,什么是Buffer

buffer翻译为缓冲区,是一个类似于Array的对象,用于表示固定长度序列

特点

1.长度固定

2.新能较好,直接对计算机内存进行操作

3.每个元素的大小为1字节(byte)

五,程序运行流程

安装到硬盘,硬盘将数据放入内存,cpu去内存执行指令,再将指令交给I/O设备

程序一般保存在硬盘中,安装过程就是将程序写入硬盘的过程。

六,进程和线程

进程可以理解为运行中的程序,或者一个程序执行的过程。

线程,时一个进程的执行的执行流。

七,fs模块

实现与硬盘的交互

一,写入文件

四个参数 文件名(如果文件不存在,会自动创建),写入的数据,选项设置,回调函数


const fs = require('fs');
fs.writeFile('./qwe.txt','好好学习',err=>{
   //如果写入失败erroe的值就是错误对象,如果写入成功err的值就是null
   if(err){
   console.log('error')
   return}
   console.log('success')
   
}
   
  )

二,fs的同步和异步

fs的同步写入


fs.writeFileSync('abc.txt','666)

三,文件的追加写入


const fs = require('fs');
//另一种写法
fs.writeFile('qwe.txt','努力',{flag:'a'} ,error=>{
   console.log('真的绝')
})
fs.appendFile('./qwe.txt',',天天向上',err=>{
   //如果写入失败erroe的值就是错误对象,如果写入成功err的值就是null
   if(err){
   console.log('error')
   return}
   console.log('success')
   
}
   
  )

四,流式写入

const fs = require('fs')

const ws = fs.createWriteStream('./学习.txt')

ws.write('床前明月光')

ws.write('疑是地上霜')

//关闭流
ws.close()

适合大量写入文件

五,文件写入的场景

例如下载文件,安装软件

在每次需要持久化保存文件的的时候,不一定一定要使用文件写入,但是要向着这个方向去想,问题就不会太大。

六,文件的读取


//引入模块
const fs = require('fs')
//异步读取
// fs.readFile('qwe.txt',(err,data)=>{
//     if(err){
//         console.log('fail')
//         return
//     }
//     console.log(data.toString())
// })


//同步读取
const wr = fs.readFileSync('./qwe.txt')
console.log(wr.toString())

七,文件读取应用场景

例如电脑开机,程序运行,上传文件

八,fs文件流式读取


const fs = require('fs')

const rs = fs.createReadStream('./素材.mp3')

rs.on('data',chunk =>{
   console.log(chunk.length)
})

rs.on('end',()=>{
   console.log("读取完成")
})

九,文件重命名和移动


const fs = require('fs')
//调用fs对象的rename方法
// fs.rename('qwe.txt','好好学习.txt',err=>{
//     if(err){
//         console.log('rename fall')
//     }
//     console.log('rename success')
// })

// 以上是重命名方法

//下面是文件的移动

fs.rename('qwe.txt','./素材/好好学习.txt',err=>{
   if(err){
       console.log('rename fall')
  }
   console.log('rename success')
})

十,文件的删除


const fs = require('fs')
//方法一 unlink方法
fs.unlink('./素材/好好学习.txt',(err) => {
   
   if(err){
       console.log('failed')
       return;
  }
   console.log('success')

}
   
)

//方法二 rm方法 用法和上面一致

十一,fs文件夹操作


const { error } = require('console')
const fs = require('fs')
// 文件夹的一般创建 make
fs.mkdir('./好好学习',(err) => {
   if (err) {
       console.log('失败');
       return;
  }
   console.log('成功')
})

// 递归创建
// 用法是一致的,不过这个方法要写第二个参数表示允许调用,详细如下
fs.mkdir('./好好学习/b/c',{recursive:true},(err) => {
   if (err) {
       console.log('失败');
       return;
  }
   console.log('成功')
})

//删除文件夹 remove

fs.rmdir('./好好学习',(err) => {
   if (err) {
       console.log('失败');
       return;
  }
   console.log('成功')
})

// 递归删除 但是我们不推荐这样删除,这里推荐使用rm方法删除
fs.rmdir('./好好学习/b/c',{recursive:true},(err) => {
   if (err) {
       console.log('失败');
       return;
  }
   console.log('成功')
})

十二,查看资源状态

文件的状态



const fs = require('fs')

fs.stat('学习.txt',(err,data) => {
   if(err){
       console.log('faild')
       return

  }
   console.log('success',data)
   // data的两个方法检查是否为文件isFile ,检查是否为文件夹isDirectory
})

十三,路径

绝对路径和相对路径

相对路径有一个bug,相对路径的参考目录为工作行的目录

绝对路径‘全局变量’保存的是,所在文件的所在目录的绝对路径

八,path模块

path模块用来操作路径的

API说明 
path.resolve 拼接规范的绝对路径
path.sep 获取操作路径分隔符
path.parse 解析路径,获取路径相关信息
path.basename 获取路径基础名称
path.dirname 获取路径目录名
path.extname 获取路径扩展名

九,http协议*

双方必须遵守的约定

一,请求报文的结构

二,请求行

组成:请求方法 URL HTTP协议版本号

请求方法:

方法作用
GET 主要用于获取数据
POST 主要用于新增数据
PUT 主要用于更新数据
DELETE 主要用于删除数据

方法有很多主要是这几个,更主要的是get和post

URL:

定义服务器内的资源

组成:协议名 和 主机名(定位网络上的计算机)和端口号和路径和查询字符串

下面例子:这个例子没有查询字符串

http://127.0.0.1:5500/html/%E6%89%8B%E9%A3%8E%E7%90%B4%E6%A1%88%E4%BE%8B.html

http版本号:

顾名思义不做解释

三,请求头

记录了当前浏览器的一些信息

四,请求体

内容非常灵活可以写任意内容

五,相应报文和相应行和相应头和相应体

 

十,网络基础知识

一,ip的介绍

32bit二进制数据

标识网络中的设备实现设备之间的通信

IP本身就是一个标识

二,ip分类

个人感觉分类为:公共ip和个人ip,在一个公共场所,通过路由器分配给每个人一个ip和整体的ip,不举例子解释不清楚,分类也不是我说的这么草率。

三,端口

一台计算机有65536个端口,端口用来实现不同计算机的通讯

十一,http模块

一,创建http服务


// 导入http模块
const http = require('http');

//创建服务对象
//request请求报文的封装对象
//response返回报文的对象
const server = http.createServer((request,response) => {
   response.end('Hello HTTP Server');//设置响应体
})

//监听端口,启动服务
// listen中的两个参数,一个是端口号,一个是启动服务器后的回调方法
server.listen(9000,() => {
   console.log("success")
})

二,注意事项

  1. ctrl+c停止服务器

  2. 当服务器启动后,更新代码,必须重启服务器才能生效

  3. 响应内容中文乱码解决办法:


    response.setHeader('content-type','text/html;charset=utf-8')
  4. 常见的问题端口被占用:1.关闭当前正在运行的监听端口服务2.修改其他端口号

  5. http协议默认端口号的80,开发常用的端口号有3000,8080,8090,9000

三,浏览器查看http报文

控制台 network

四,提取http请求报文

想获取请求的数据,需要通过request对象

这里只列举重点,不仅仅只有这几个属性

含义语法
请求方法 request.method
请求路径 request.url
url路径 require('url').parse(request.url).pathname
url字符串 require('url').parse(request.url,true).query
请求头 request.headers

// 导入http模块
const http = require('http');

//创建服务对象
//request请求报文的封装对象
//response返回报文的对象
const server = http.createServer((request,response) => {
   response.setHeader('content-type','text/html;charset=utf-8')
   // 获取请求的方法
   console.log(request.method);
   // 获取请求的url
   console.log(request.url);//这里只包括url中的路径和查询字符串
   //获取HTTP协议版本号
   console.log(request.httpVersion);//基本上用不到
   //获取HTTP的请求头
   console.log(request.headers);
   response.end('Hello HTTP Server,你好');//设置响应体
})

//监听端口,启动服务
// listen中的两个参数,一个是端口号,一个是启动服务器后的回调方法
server.listen(9000,() => {
   console.log("success")
})

我还是不习惯写;啊啊啊啊啊啊

五,提取请求体的内容


// 导入http模块
const http = require('http');


const server = http.createServer((request,response) => {
   
   // 声明一个变量
   let body = '';
   // 绑定data事件
   request.on('data',chunk =>{
       body += chunk;
  })
   // 绑定end事件
   request.on('end',()=>{

       console.log(body)
       response.end('Hello');
  })

})

//监听端口,启动服务
// listen中的两个参数,一个是端口号,一个是启动服务器后的回调方法
server.listen(9000,() => {
   console.log("success")
})

六,获取路径和查询字符串


// 导入http模块
const http = require('http');

const url = require('url')

const server = http.createServer((request,response) => {
   

   let res = url.parse(request.url,true);

   let keyword = res.query.name

   let pathname = res.pathname
   //获取路径
   console.log(res)
   console.log(keyword)
   // console.log(pathname)
   response.end('url')

})

//监听端口,启动服务
// listen中的两个参数,一个是端口号,一个是启动服务器后的回调方法
server.listen(9000,() => {
   console.log("success")
})

上面的方法时旧的

下面的是新的


// 导入http模块
const http = require('http');

const url = require('url')

const server = http.createServer((request,response) => {
   
// 实例化url对象
let url = new URL(request.url,'http://localhost')

console.log(url)
})

//监听端口,启动服务
// listen中的两个参数,一个是端口号,一个是启动服务器后的回调方法
server.listen(9000,() => {
   console.log("success")
})

七,响应报文


// 导入http模块
const http = require('http');

const server = http.createServer((request,response) => {
   
   //设置响应状态码
   response.statusCode = 201
   //设置响应状态描述4
   response.statusMessage("666")
   //响应头
   response.setHeader('Server','Node.js')
   //响应体设置
   response.write("666")


   response.end("666")
})

//监听端口,启动服务
// listen中的两个参数,一个是端口号,一个是启动服务器后的回调方法
server.listen(9000,() => {
   console.log("success")
})

八,静态资源和动态资

静态资源是指内容长时间不发生改变的资源,例如图片,视频,CSS

动态资源是指内容经常发生改变的资源

十二,模块化

一,模块化初体验

index1.js


const Study = require('./index2.js')

Study();

index2.js


function Study(){
   console.log('我其实不喜欢学习')
}

module.exports = Study;

二,模块暴露数据

两种方法:


function Study(){
   console.log('我其实不喜欢学习')
}

function Play(){
   console.log('我也不喜欢玩')
}

// 方法一:model.exports = value
module.exports = {
   Study,
   Play
}

// 方法二:exports.name = value
exports.Study = Study;
exports.Play = Play;

const me = require('./index2.js')

me.Study();
me.Play();

三,导入文件夹

首先先寻找文件夹里package.json里main的值,如果没有则尝试寻找index.json或者index.js文件

不好演示:




const a = require('./model')
console.log(a);

四,导入自定义模块流程

  1. 将相对路径转换为绝对路径,定位文件夹

  2. 检测缓存

  3. 读取文件夹代码

  4. 包裹为一个函数执行(自己执行的函数),通过arguments.callee.toString()查看自执行函数

  5. 缓存模块的值

  6. 返回model.exports的值

这里代码有点离谱,先不看了

 

十五,express

一,创建express


//导入express模块
import express, { response } from 'express'
// 创建应用对象
const app = new express();
// 创建路由
app.get('/home',(req,res) => {
   res.end('hello wds')
});
// 监听接口,启动服务
app.listen(3000,()=>{
   console.log('服务器已经启动监听窗口中')
})

二,路由的使用


app.<methods>(path,callback)

//导入express模块
import express, { response } from 'express'
// 创建应用对象
const app = new express();
// 创建路由 注意这里的路径是一个斜线,这里是真正的首页
app.get('/',(req,res) => {
   res.end('home')
});

app.post('/login',(req,res)=>{
   res.end('login page')
})

app.all('/test',(req,res)=>{
   res.end('test')
})

app.all('*',(req,res)=>{
   res.end('Not Fond 404')
})

// 监听接口,启动服务
app.listen(3000,()=>{
   console.log('服务器已经启动监听窗口中')
})

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>
<body>
   
<form action="http://localhost:3000/login" method="post">
   <button>按钮</button>
</form>

</body>
</html>

三,获取请求报文参数


//导入express模块
import express, { response } from 'express'

// 创建应用对象
const app = new express();



app.get('/home',(req,res)=>{

   // 原生操作
   console.log(req.method);
   console.log(req.url);
   console.log(req.httpVersion);
   console.log(req.headers);

   //express 操作
   console.log(req.path);//查询路径
   console.log(req.query);//查询字符串

   //获取ip
   console.log(req.ip);
})



app.listen(3000,()=>{
   console.log('服务器已经启动监听窗口中')
})

四,获取 路由参数


//导入express模块
import express, { response } from 'express'

// 创建应用对象
const app = new express();



app.get('/:id.html',(req,res)=>{

   // 获取通配符
   console.log(req.params.id);


})



app.listen(3000,()=>{
   console.log('服务器已经启动监听窗口中')
})

五,路由参数练习


//导入express模块
const express = require('express')

// 创建应用对象
const app = new express();

const {students} =  require('./students.json')


app.get('/students/:id.html',(req,res)=>{

   let id = req.params.id;

   let result = students.find(item=>{
       //这里我犯了一个错误,这里的id是字符串,因该类型转换成Number类型
       if(item.id === Number(id)){
           return true
      }
  })


   if(!result){
       res.statusCode = 404;
       res.end('Not Fond Student')
       return;
  }



   res.end(`
   <!DOCTYPE html>
   <html lang="en">
   <head>
       <meta charset="UTF-8">
       <meta http-equiv="X-UA-Compatible" content="IE=edge">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <title>Document</title>
   </head>
   <body>
       <h2>${result.name}</h2><br>
       <h2>${result.age}</h2><br>
       <h2>${result.address}</h2>
   </body>
   </html>
   `)

     

})



app.listen(3000,()=>{
   console.log('服务器已经启动监听窗口中')
})

{
   "students": [
      {
           "id":1,
           "name": "wds1",
           "age": 21,
           "address": "山西省太原市"
      },
      {
           "id":2,
           "name": "wds2",
           "age": 22,
           "address": "山西省太原市"
      },
      {
           "id":3,
           "name": "wds3",
           "age": 23,
           "address": "山西省太原市"
      },
      {
           "id":4,
           "name": "wds4",
           "age": 24,
           "address": "山西省太原市"
      },
      {
           "id":5,
           "name": "wds5",
           "age": 25,
           "address": "山西省太原市"
      }
  ]
}

六,一般响应设置


//导入express模块
const express = require('express')

// 创建应用对象
const app = new express();


app.get('/response',(req,res)=>{

//   express响应
   res.status(500);
   res.set('aaa','bbb');
   res.send('你好')

   // 甚至可以合起来写
   res.status(200).set('aaa','bbb').send('这都是ok的');
     

})



app.listen(3000,()=>{
   console.log('服务器已经启动监听窗口中')
})

七,其他响应设置

  • res.redirect() 跳转响应

  • res.download() 下载响应

  • res.json() 响应

  • res.sendFile() 响应文件内容

八,中间件

真的不想写啊:

全局中间件


//导入express模块
const express = require('express')

// 创建应用对象
const app = new express();


const fs = require('fs')

function abc(req,res,next){
   let {ip,path} = req;
   console.log(ip,path);
   res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
   fs.appendFileSync('./存储.txt',`${ip} ${path}\r\n`);

   next();

}

app.use(abc)



app.get('/test1',(req,res)=>{



   res.end('test1页面')
})

app.get('/test2',(req,res)=>{

   res.end('test2页面')
})

app.all('*',(req,res)=>{

   res.end('404')
})



app.listen(3000,()=>{
   console.log('服务器已经启动监听窗口中')
})

路由中间件

顾名思义路由可以用,在路由定义的时候的形式参数的而第二个参数传入函数名字,就这样,真的不想写了

静态资源中间件


//导入express模块
const express = require('express')

// 创建应用对象
const app = new express();


app.use(express.static(__dirname + '/贪吃蛇小游戏'))


app.get('/',(req,res)=>{

   res.end('HOME')
})



app.all('*',(req,res)=>{

   res.end('404')
})



app.listen(3000,()=>{
   console.log('服务器已经启动监听窗口中')
})

注意事项:

  1. index.html文件为默认打开资源

  2. 如果静态资源于路由规则同时匹配,谁先匹配谁响应

  3. 路由响应动态资源,静态资源中间件响应静态资源

十,防盗链


//导入express模块
const express = require('express')

// 创建应用对象
const app = new express();

app.use((req, res, next) => {
   const refer = req.get('referer')
   if (refer) {
       let url = new URL(refer);
       let hostname = url.hostname;
       if(hostname !== 'localhost'){
           res.status(404).send(`<h1>找不见</h1>`)
      }
  }
   next();
})

app.use(express.static('./test'))

app.listen(3000, () => {
   console.log('服务器已经启动监听窗口中')
})

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>
<body>
   <h2>这是静态资源中间件</h2>
   <img src="http://localhost:3000/img/练习.jpg" alt="">
</body>
</html>

十一,模块化路由



const express = require('express');

const router = new express.Router



router.get('/',(req,res)=>{

   res.end('HOME1')
})

router.get('/home',(req,res)=>{

   res.end('HOME2')
})
router.get('/admain',(req,res)=>{

   res.end('HOME3')
})
router.get('/login',(req,res)=>{

   res.end('HOME4')
})


router.all('*',(req,res)=>{

   res.end('404')
})


module.exports = router;

//导入express模块
const express = require('express')

// 创建应用对象
const app = new express();

const homerouter = require('./homerouter')


app.use(homerouter);


app.listen(3000,()=>{
   console.log('服务器已经启动监听窗口中')
})

十二,模板引擎

学了没坏处,但是现在不想学,前后端分离都用vue了,还直接上手吗?

十六,MYSQL

以编程写代码的形式操作数据库里的内容

要说数据库最重要的就是增删改查了

查询数据select 插入数据insert into 更新数据update 删除数据delete

sql语法:

where条件 and和or运算符 order by排序 count(*)函数

一,数据查询

一,查询


-- 通过*把user表中的数据全部查询
SELECT * FROM `user`

-- 查询表中的任意数据
SELECT `账号` FROM `user`

二,添加


-- 插入信息
INSERT INTO user(id,`姓名`,`账号`,`密码`) VALUES (4,'adasda',123456,123456)
-- 插入后需要重新查看
SELECT * FROM `user`

三,更新


-- UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
UPDATE `user` SET `姓名` = '李四' WHERE id = 4

SELECT * FROM `user`

四,删除


-- 删除操作
DELETE FROM `user` WHERE id=4

-- SELECT * FROM `user`

二,where和or和and

where运算符

操作符描述
= 等于
<> 不等于
> 大于
< 小于
>= 大于等于
<= 小于等于
BETWEEN 在某个范围内
LIKE 搜索某种形式

sql版本呢较老的话不等于写成!=

and和or运算符

and相当于&&与

or相当于||或

三,操作mysql数据库

一,链接数据库



const mysql = require('mysql')


const db = mysql.createPool({
   host:'127.0.0.1', //数据库ip地址
   user:'root',  //登录数据库账号
   password:'123', //登录数据库密码
   database:'mytest' //指定要操作那个数据库
})


db.query('select 1',(err,result) => {
   if(err){
       console.log('链接失败',err.message)
  }else{
        //注意执行的是select语句结果是数组
       console.log('数据库连接成功')
  }
})

二 ,操作数据库

 

 

标签:node,express,console,log,res,知识,学习,fs,const
From: https://www.cnblogs.com/laonianrenws/p/17576041.html

相关文章

  • nodejs sqlite报错 typeorm[ Expression tree is too large (maximum depth 1000)]
    最近在给公司开发一个工具时,使用SQLite,然后突然发现报错:(node:16195)UnhandledPromiseRejectionWarning:QueryFailedError:SQLITE_ERROR:Expressiontreeistoolarge(maximumdepth1000)athandler(/snapshot/server-work/node_modules/typeorm/driver/sqlite/Sql......
  • spring6 ioc aop 从入门到精通零基础进阶学习路线?
    当你已经掌握了Spring框架的基础知识以及IoC和AOP的核心概念后,可以进一步深化你的学习。以下是更详细的学习路线:1.IoC容器进阶:-学习如何自定义Bean的初始化和销毁方法,并了解Bean生命周期的各个阶段。-深入了解Spring的作用域(Scope)概念,如单例模式、原型模式、会话模式和请求模......
  • 学习MySQL,创建表,数据类型
    连接本地mysql语句mysql-hlocalhost-uroot-prootMySQL通用语法DDL数据库操作DDL:数据定义语言,用来定义数据库对象(数据库,表,字段)查询所有数据库showdatabases;创建数据库语法:createdatabase[ifnotexists]数据库名称[defaultcharset字符编码];createdat......
  • 无法注册程序集“D:\JAVA学习之路\jni4netTest\FanucDataCollectionAPI\FanucData
    无法注册程序集"D:\JAVA学习之路\jni4netTest\FanucDataCollectionAPI\FanucData"在Java开发中,我们经常需要与其他语言进行集成,以实现更复杂的功能或访问底层资源。JNI(JavaNativeInterface)是一种机制,允许Java代码调用本地代码(通常是C或C++编写的)。然而,在使用JNI时,有时会遇到无......
  • 初识机器学习及机器学习线性拟合的实现
    从最小二乘法到机器学习1,什么是机器学习?机器学习有下⾯⼏种定义:机器学习是⼀⻔⼈⼯智能的科学,该领域的主要研究对象是⼈⼯智能,特别是如何在经验学习中改善具体算法的性能。机器学习是对能通过经验⾃动改进的计算机算法的研究。机器学习是⽤数据或以往的经验,以此优化计算机程......
  • [学习笔记] 倍增 Floyd
    一、朴素Floydfor(inti=1;i<=n;++i){for(intj=1;j<=n;++j){for(intk=1;k<=n;++k){d[i][j]=min(d[i][j],d[i][k]+d[k][j]);}}}二、倍增Floyd/传递闭包要做\(k(\leq10^9)\)次Floyd,怎么办?......
  • GNN学习 GNN Layer(持续更新中)
    GNN学习GNNLayerGNN的通用框架1.对GNN的一个网络层进行信息转换和信息聚合两个操作2.连接GNN的网络层3.图增强,分为图特征增强和图结构增强4.学习目标,有监督学习还是无监督学习,节点/边/图级别1.信息转换和信息聚合GNNLayer=Message+Aggregation不同的实例有不同的信......
  • LSM树学习笔记
    LSM-Tree即logstructuredmergetree。LSM-Tree是许多高度可扩展的NoSQL分布式键值类型数据库(如亚马逊的DynamoDB、Cassandra和ScyllaDB)的基础数据结构。众所周知,这些数据库在设计上支持的写入率远远超过传统关系数据库所能提供的写入率。几乎所有NoSQL数据库都使用LSM树的变体......
  • [c/c++][考研复习笔记]排序篇学习笔记
    考研排序复习笔记插入排序#include<stdio.h>#include<stdlib.h>#defineMaxSize9//折半插入排序voidZBInsertSort(intA[],intn){ inti,j,high,low,mid; for(i=2;i<=n;i++){ A[0]=A[i]; low=1;high=i-1; while(low<=high){ mid=(low+high)/2......
  • PMP 学习笔记(七)
    07.18星期二CPI0.65——成本偏差较大,使用自下而上的估计出现新的干系人,应更新干系人登记册,敏捷方法由产品经理列入待办事项凸显模型适用于复杂的干系人大型社区审查可交付成果,干系人表现出对最终产品的担忧,按时可交付成果有问题,应审查项目需求文件产品不合格,根本原因是开发......