Vue-2.nodejs的介绍和安装

news2024/11/27 12:51:40

nodejs简介

创建 Node.js 应用:package.json

  • 首先,创建一个新文件夹以便于容纳需要的所有文件,并且在此其中创建一个 package.json 文件,描述你应用程序以及需要的依赖:

  • 配合着你的 package.json 请运行 npm install。如果你使用的 npm 是版本 5 或者之后的版本,这会自动生成一个 package-lock.json 文件,它将一起被拷贝进入你的 Docker 镜像中。

{
  "name": "docker_web_app",
  "version": "1.0.0",
  "description": "Node.js on Docker",
  "author": "First Last <first.last@example.com>",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  }
}

Node.js项目入口:server.js(可以自定义命名)

  • 使用 node server.js 运行程序,访问 http://localhost:3000,你就会看到一个消息,写着“Hello World”。
const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

nodejs的安全问题

请使用 Buffer.from()/Buffer.alloc()

  • Buffer() 和 new Buffer() 构造函数对于有安全顾虑的人而言是不推荐使用的。请使用新的方法 Buffer.alloc(),Buffer.allocUnsafe() 或者是 Buffer.from() 构造函数。

ESLint 规则(推荐)

ESLint 规则不使用缓存构造函数或 node/ 未废除的 Api 也会寻找到使用 Buffer() 废弃的函数。 这些规则预先已经包含了。

使用内存堆剖析器

时间轴的分配

在 Chrome 中连接开发工具实例,然后:

  • 选择 memory 选项卡
  • 选择 Allocation instrumentation timeline
  • 开始剖析
    在这里插入图片描述
    在这里插入图片描述

采样内存堆剖析器信息

在 Chrome 中连接开发工具的实例,然后:

  • 选择 memory 选项卡
  • 选择 Allocation sampling
  • 开始剖析
    在这里插入图片描述
    在这里插入图片描述

阻塞对比非阻塞一览

阻塞

  • 阻塞 是指在 Node.js 程序中,其它 JavaScript 语句的执行,必须等待一个非 JavaScript 操作完成。这是因为当 阻塞 发生时,事件循环无法继续运行 JavaScript。在 Node.js 标准库中使用libuv 的同步方法是最常用的 阻塞 操作。原生模块中也有 阻塞 方法。

非阻塞

  • 在 Node.js 标准库中的所有 I/O 方法都提供异步版本,非阻塞,并且接受回调函数。某些方法也有对应的 阻塞 版本,名字以 Sync 结尾。

代码比较

同步示例看上去比异步示例简单些,但是有一个缺陷:第二行语句会 阻塞 其它 JavaScript 语句的执行直到整个文件全部读取完毕,也就是moreWork()在同步示例中要等待执行,而在异步示例不需要等待

  • 同步
const fs = require('fs');
const data = fs.readFileSync('/file.md'); // blocks here until file is read
console.log(data);
moreWork(); // 在 console.log 之后执行
  • 异步
const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
  if (err) throw err;
  console.log(data);
});
moreWork(); // 在 console.log 之前执行

并发和吞吐量

  • 在 Node.js 中 JavaScript 的执行是单线程的,因此并发性是指事件循环在完成其他工作后执行 JavaScript 回调函数的能力。任何预期以并行方式运行的代码必须让事件循环能够在非 JavaScript 操作(比如 I/O )执行的同时继续运行

  • 让我们思考这样一种情况:每个对 Web 服务器的请求需要 50 毫秒完成,而那 50 毫秒中的 45 毫秒是可以异步执行的数据库 I/O。选择 非阻塞 异步操作可以释放每个请求的 45 毫秒来处理其它请求。仅仅是选择使用非阻塞方法而不是 阻塞 方法,就能造成并发的显著差异。

  • 事件循环不同于许多其他语言的模型,其它语言创建额外线程来处理并发工作。

混合阻塞和非阻塞代码的危险

  • 处理 I/O 时应该避免一些模式。我们来看一个例子:
const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
  if (err) throw err;
  console.log(data);
});
fs.unlinkSync('/file.md');
  • 在以上的例子中, fs.unlinkSync() 极有可能在 fs.readFile() 之前执行,它会在实际读取之前删除 file.md 。更好的写法是完全 非阻塞 并保证按正确顺序执行:以下代码在 fs.readFile() 的回调中对 fs.unlink() 进行了 非阻塞 调用,这保证了正确的操作顺序。
const fs = require('fs');
fs.readFile('/file.md', (readFileErr, data) => {
  if (readFileErr) throw readFileErr;
  console.log(data);
  fs.unlink('/file.md', (unlinkErr) => {
    if (unlinkErr) throw unlinkErr;
  });
});

事件循环(nodejs的核心机制)

  • 事件循环是 Node.js 处理非阻塞 I/O 操作的机制——尽管 JavaScript 是单线程处理的——当有可能的时候,它们会把操作转移到系统内核中去
  • 因为目前大多数内核都是多线程的,所以它们可以在后台处理多种操作。当其中的一个操作完成的时候,内核通知 Node.js 将适合的回调函数添加到 轮询 队列中等待时机执行。

事件循环机制解析

  • 当 Node.js 启动后,它会初始化事件循环,处理已提供的输入脚本,它可能会调用一些异步的 API调度定时器,或者调用process.nextTick(),然后开始处理事件循环。
    ┌───────────────────────────┐
    ┌─>│timers (定时器阶段此阶段执行由 setTimeout() 和 setInterval() 排序)
    │ └─────────────┬─────────────┘
    │ ┌─────────────┴─────────────┐
    │ │pending callbacks(挂起的回调阶段执行 I/O 回调推迟到下一个循环迭代
    │ └─────────────┬─────────────┘
    │ ┌─────────────┴─────────────┐
    │ │idle, prepare(空闲,准备阶段仅在内部使用
    │ └─────────────┬─────────────┘
    │ ┌─────────────┴─────────────┐
    │ │poll (轮询阶段
    检索新的 I/O 事件; 执行与 I/O 相关的几乎任何回调
    (由“计时器”或 “setImmediate()”所设的紧邻回调除外);
    node 将在适当时机在此处暂停
    │ └─────────────┬─────────────┘
    │ ┌─────────────┴─────────────┐
    │ │check(检查阶段 setImmediate() 回调在此处被调用
    │ └─────────────┬─────────────┘
    │ ┌─────────────┴─────────────┐
    └──┤close callbacks(关闭回调阶段一些关闭的回调函数,如:socket.on('close', ...)
    └───────────────────────────┘

      注意:每个框被称为事件循环机制的一个阶段。
    

定时器阶段解读

  • 计时器可以 在回调后面 指定 阈值,而不是用户希望回调执行的确切时间。因为在经过指定的一段时间间隔后, 计时器回调将被尽可能早地运行。但是,操作系统调度或其它正在运行的回调可能会延迟它们。
  • 从技术上讲, 轮询 阶段 控制执行计时器的时间。
  • 为了防止 轮询 阶段挤占事件循环的执行,libuv(实现 Node.js 事件循环和平台上所有异步行为的 C 函数库)还设有一个最大硬性限制(取决于系统),以避免继续轮询更多事件。

轮询阶段解读

► 轮询过程

例如,您调度了一个在 100 毫秒后执行回调的定时器,并且您的脚本开始异步读取文件,这会耗费 95 毫秒:

  • 计算应该阻塞和轮询 I/O 的时间(95毫秒)。
  • 事件循环等待95毫秒,将需要10毫秒才能完成的回调添加到轮询队列,当回调完成时,队列中不再有回调
  • 100毫秒达到时,事件循环机制将发现计时器最快的阈值(100ms)的已经达到,然后将回到 计时器 阶段,以执行定时器的回调(一旦 轮询 队列为空,事件循环将检查 已达到时间阈值的计时器。如果一个或多个计时器已准备就绪,则事件循环将绕回计时器阶段以执行这些计时器的回调。)
  • 在本示例中,您将看到调度计时器到它的回调被执行之间的总延迟将为 105 毫秒。`

► 轮询分析

  • 如果 轮询队列 不是空的 ,事件循环将循环访问回调队列并同步执行它们,直到队列已用尽,或者达到了与系统相关的硬性限制。
  • 如果 轮询队列 是空的 ,还有两件事发生:
    1. 如果脚本被 setImmediate() 调度,则事件循环结束 轮询 阶段,并继续 检查 阶段以执行那些被调度的脚本。
    1. 如果脚本setImmediate()调度,则事件循环将等待回调被添加到队列中,然后立即执行。
  • 注意:为了防止 轮询 阶段事件循环陷入吃不饱的状态,libuv(实现 Node.js 事件循环和平台的所有异步行为的 C 函数库)在停止轮询以获得更多事件之前,还有一个硬性的最大值(依赖于系统)。

► setImmediate() 对比 setTimeout()

  • setImmediate() 是为了在 当前 所有检测阶段完成后执行脚本。
    通常,在执行代码时,事件循环最终会进入轮询阶段,在该阶段它将等待传入连接、请求等。但是,如果回调已使用 setImmediate()调度过并且轮询阶段变为空闲状态则它将结束此阶段并继续到检查阶段而不是继续等待轮询事件。
  • setTimeout() 安排一个脚本,在已过期的最小阈值后运行。

► process.nextTick()

  • 任何时候在给定的阶段中调用 process.nextTick(),所有传递到 process.nextTick() 的回调将在事件循环继续之前解析
  • 这可能会造成一些糟糕的情况,因为它允许您通过递归 process.nextTick()调用来饿死您的 I/O,阻止事件循环到达轮询阶段
let bar;

function someAsyncApiCall(callback) {
  process.nextTick(callback);
}

someAsyncApiCall(() => {
  console.log('bar', bar); // 1
});

bar = 1;
  • 允许传递参数给 process.nextTick(),这将允许它接受任何在回调函数位置之后的参数,并将参数传递给回调函数作为回调函数的参数,这样您就不必嵌套函数了。
function apiCall(arg, callback) {
  if (typeof arg !== 'string')
    return process.nextTick(
      callback,
      new TypeError('argument should be string')
    );
}
  • 通过使用process.nextTick(),我们保证 apiCall() 始终在用户代码的其余部分之后和在让事件循环继续进行之前,执行其回调函数。为了实现这一点,JS 调用栈被允许展开,然后立即执行提供的回调,允许进行递归调用 process.nextTick(),而不触碰 RangeError: 超过 V8 的最大调用堆栈大小 限制。

► 为什么要使用 process.nextTick()?

  • 允许用户处理错误,清理任何不需要的资源,或者在事件循环继续之前重试请求。
  • 有时有让回调在栈展开后,但在事件循环继续之前运行的必要。

► process.nextTick() 对比 setImmediate()

  • process.nextTick() 在同一个阶段立即执行。
  • setImmediate() 在事件循环的接下来的迭代或 ‘tick’ 上触发。

► EventEmitter

另一个例子是扩展 EventEmitter, 并在构造器内释放一个事件:

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {
  constructor() {
    super();
    this.emit('event');
  }
}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('an event occurred!');
});

你不能立即从构造函数中触发事件,因为脚本尚未处理到用户为该事件分配回调函数的地方。因此,在构造函数本身中可以使用 process.nextTick() 来设置回调,以便在构造函数完成后发出该事件,这是预期的结果

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {
  constructor() {
    super();

    // use nextTick to emit the event once a handler is assigned
    process.nextTick(() => {
      this.emit('event');
    });
  }
}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('an event occurred!');
});

► 不要阻塞你的事件循环(或是工作线程池)

  • Node.js 通过事件循环机制(初始化和回调)的方式运行 JavaScript 代码,并且提供了一个线程池处理诸如文件 I/O 等高成本的任务。
  • Node.js 是用很少量的线程来处理大量客户端请求的。 在 Node.js 中,有两种类型的线程:一个事件循环线程(也被称为主循环,主线程,事件线程等)。另外一个是在工作线程池里的 k 个工作线程(也被称为线程池)。
  • 如果一个线程执行一个回调函数(事件轮询线程)或者任务(工作线程)需要耗费很长时间,我们称之为“阻塞”。 当一个线程在处理某一个客户端请求时被阻塞了,它就无法处理其它客户端的请求了。 这里给出两个不能阻塞事件轮询线程和工作线程的理由:
    1. 性能:如果你在任意类型的线程上频繁处理繁重的任务,那么你的服务器的 吞吐量(请求/秒)将面临严峻考验。
    1. 安全性:如果对于特定的输入,你的某种类型的线程可能会被阻塞,那么恶意攻击者可以通过构造类似这样的“恶意输入”,故意让你的线程阻塞,然后使其它客户端请求得不到处理。这就是拒绝服务攻击。

► Node.js 模块中有如下这些 API 用到了事件循环线程

  • 事件轮询线程执行事件的回调函数,并且负责对处理类似网络 I/O 的非阻塞异步请求。

► Node.js 模块中有如下这些 API 用到了工作线程池

  • I/O 密集型任务:
    1. DNS:dns.lookup(),dns.lookupService()。
    1. 文件系统:所有的文件系统 API。除 fs.FSWatcher() 和那些显式同步调用的 API 之外,都使用 libuv 的线程池。
  • CPU 密集型任务:
    1. Crypto:crypto.pbkdf2()、crypto.scrypt()、crypto.randomBytes()、crypto.randomFill()、crypto.generateKeyPair()。
    1. Zlib:所有 Zlib 相关函数,除那些显式同步调用的 API 之外,都适用 libuv 的线程池。

► 事件循环线程和工作线程池

  • 抽象来说,事件轮询线程和工作池线程分别为等待中的事件回调和等待中的任务维护一个队列。

  • 而事实上,事件轮询线程本身并不维护队列,它持有一堆要求操作系统使用诸如 epoll (Linux),kqueue (OSX),event ports (Solaris) 或者 IOCP (Windows) 等机制去监听的文件描述符。 这些文件描述符可能代表一个网络套接字,一个监听的文件等等。 当操作系统确定某个文件的描述符发生变化,事件轮询线程将把它转换成合适的事件,然后触发与该事件对应的回调函数。

  • 相对而言,工作线程池则使用一个真实的队列,里边装的都是要被处理的任务。 一个工作线程从这个队列中取出一个任务,开始处理它。当完成之后这个工作线程向事件循环线程中发出一个“至少有一个任务完成了”的消息。

  • Node.js有两种线程:一个事件循环和 k 工作者。 事件循环负责JavaScript 回调和非屏蔽I/O, 和一个工人执行对 C++ 代码的任务,完成异步请求,包括阻塞I/O 和 CPU密集工作。 两种类型的线程每次只能在一个活动上工作。 如果任何回调或任务需要很长时间,运行的线程会被屏蔽 。 如果您的应用程序阻止回调或任务,这最多可能导致通过量化(客户/秒),最坏情况下完全拒绝服务。

  • 要写入一个高吞吐量,更多地预防 DoS 服务攻击的服务,您必须确保在良性和恶意输入中, 你的事件循环和你的 Worker 始终不会屏蔽。

Node.js 中的定时器

  • ► setTimeout() 可被用来在一段指定时间之后执行某个代码任务,唯一 保证的是定时器不会比声明的时间间隔 提早 执行。
function myFunc(arg) {
  console.log(`arg was => ${arg}`);
}

setTimeout(myFunc, 1500, 'funky');
  • ► setImmediate() 在此之后立即执行, 将在当前事件轮询的末尾处执行,setImmediate() 返回一个 Immediate 对象,它可以被用于取消安排的定时任务(见下面的 clearImmediate() )。

不要把 setImmediate() 和 process.nextTick() 相混淆。它们有一些主要的差别:第一, process.nextTick() 将在任何设置好的 Immediate 以及任何安排好的 I/O 前 执行。第二, process.nextTick() 是不可擦除的,换句话说,一旦有代码使用 process.nextTick() 执行,执行无法中断,这就像一个普通函数一样

console.log('before immediate');

setImmediate((arg) => {
  console.log(`executing immediate: ${arg}`);
}, 'so immediate');

console.log('after immediate');

before immediate
after immediate
executing immediate: so immediate
  • ► setInterval() 永远的轮询,setInterval() 接受一个函数作为其参数,该函数将被运行无限次,第二个参数便是一个给定的延时毫秒数。另外一个和 setTimeout() 类似的地方是延时不保证精确。
function intervalFunc() v.
  console.log('Cant stop me !');
}

setInterval(intervalFunc, 1500);
  • ► 清除定时器
const timeoutObj = setTimeout(() => {
  console.log('timeout beyond time');
}, 1500);

const immediateObj = setImmediate(() => {
  console.log('immediately executing immediate');
});

const intervalObj = setInterval(() => {
  console.log('interviewing the interval');
}, 500);

clearTimeout(timeoutObj);
clearImmediate(immediateObj);
clearInterval(intervalObj);
  • ► 让定时器在背后运行
    你已经记住了 Timeout 对象是通过 setTimeout 和 setInterval 返回的。 Timeout 对象提供了两个针对 Timeout 行为的函数
    (1)unref() 取消setTimeoutsetInterv函數的調用
    (2)ref() 恢復setTimeoutsetInterv函數的調用
const timerObj = setTimeout(() => {
  console.log('will i run?');
});

// if left alone, this statement will keep the above
// timeout from running, since the timeout will be the only
// thing keeping the program from exiting
timerObj.unref();

// we can bring it back to life by calling ref() inside
// an immediate
setImmediate(() => {
  timerObj.ref();
});

下载安装nodejs

下载nodejs

  • 点击下载nodejs,选择长期维护版

在这里插入图片描述

安装

  • 直接点击next直接完成安装(记住这个路径:C:\Program Files\nodejs
    在这里插入图片描述

配置环境变量

新建文件夹如下

  • D:\nodejs\node_global
  • D:\nodejs\node_cache

更改文件夹权限

在这里插入图片描述

添加环境变量

在这里插入图片描述

验证是否安装成功

C:\Users\Administrator>node -v
v18.17.1

C:\Users\Administrator>npm -v
9.6.7

C:\Users\Administrator>

修改模块下载位置

C:\Users\Administrator>npm get prefix
C:\Users\Administrator\AppData\Roaming\npm
C:\Users\Administrator>npm get cache
C:\Users\Administrator\AppData\Local\npm-cache
C:\Users\Administrator>
C:\Users\Administrator>npm config set prefix "D:\nodejs\node_global"
C:\Users\Administrator>npm config set cache "D:\nodejs\node_cache"
C:\Users\Administrator>

测试默认位置是否更改成功

C:\Users\Administrator>npm install express -g

added 58 packages in 20s

8 packages are looking for funding
  run `npm fund` for details

C:\Users\Administrator>

在这里插入图片描述
在这里插入图片描述

设置淘宝镜像,并安装cnpm

C:\Users\Administrator>npm config get registry
https://registry.npmjs.org/

C:\Users\Administrator>npm config set registry https://registry.npmmirror.com

C:\Users\Administrator>npm config get registry
https://registry.npmmirror.com

C:\Users\Administrator>npm install -g cnpm --registry=https://registry.npmmirror.com

added 399 packages in 18s

28 packages are looking for funding
  run `npm fund` for details

C:\Users\Administrator>
npm config get registry
npm config set registry https://registry.npm.taobao.org
npm config set registry https://registry.npmmirror.com
npm config get registry
npm install -g cnpm --registry=https://registry.npm.taobao.org
npm install -g cnpm --registry=https://registry.npmmirror.com

查看cnpm模块

在这里插入图片描述

执行命令查看cnpm是否安装成功

C:\Users\Administrator>cnpm -v
cnpm@9.2.0 (D:\nodejs\node_global\node_modules\cnpm\lib\parse_argv.js)
npm@9.8.1 (D:\nodejs\node_global\node_modules\cnpm\node_modules\npm\index.js)
node@18.17.1 (C:\Program Files\nodejs\node.exe)
npminstall@7.9.0 (D:\nodejs\node_global\node_modules\cnpm\node_modules\npminstall\lib\index.js)
prefix=D:\nodejs\node_global
win32 x64 10.0.19044
registry=https://registry.npmmirror.com

C:\Users\Administrator>

附上所有命令

Microsoft Windows [版本 10.0.19044.3086]
(c) Microsoft Corporation。保留所有权利。

C:\Users\Administrator>node -v
v18.17.1

C:\Users\Administrator>npm -v
9.6.7

C:\Users\Administrator>npm get prefix
C:\Users\Administrator\AppData\Roaming\npm

C:\Users\Administrator>npm get cache
C:\Users\Administrator\AppData\Local\npm-cache

C:\Users\Administrator>npm config set prefix "D:\nodejs\node_global"

C:\Users\Administrator>npm config set cache "D:\nodejs\node_cache"

C:\Users\Administrator>npm install express -g

added 58 packages in 20s

8 packages are looking for funding
  run `npm fund` for details

C:\Users\Administrator>npm config get registry
https://registry.npmjs.org/

C:\Users\Administrator>npm config set registry https://registry.npmmirror.com

C:\Users\Administrator>npm config get registry
https://registry.npmmirror.com

C:\Users\Administrator>npm install -g cnpm --registry=https://registry.npmmirror.com

added 399 packages in 18s

28 packages are looking for funding
  run `npm fund` for details

C:\Users\Administrator>cnpm -v
cnpm@9.2.0 (D:\nodejs\node_global\node_modules\cnpm\lib\parse_argv.js)
npm@9.8.1 (D:\nodejs\node_global\node_modules\cnpm\node_modules\npm\index.js)
node@18.17.1 (C:\Program Files\nodejs\node.exe)
npminstall@7.9.0 (D:\nodejs\node_global\node_modules\cnpm\node_modules\npminstall\lib\index.js)
prefix=D:\nodejs\node_global
win32 x64 10.0.19044
registry=https://registry.npmmirror.com

C:\Users\Administrator>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/858607.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业权限管理(七)-权限操作

1. 数据库与表结构 1.1 用户表 1.1.1 用户表信息描述 users 1.1.2 sql语句 CREATE TABLE users( id varchar2(32) default SYS_GUID() PRIMARY KEY, email VARCHAR2(50) UNIQUE NOT NULL, username VARCHAR2(50), PASSWORD VARCHAR2(50), phoneNum VARCHAR2(20), STATUS INT )…

内网穿透是什么意思?快解析如何实现内网穿透

在家里或者公司&#xff0c;我们常常会使用路由器来连接网络&#xff0c;以便我们能够上网学习和工作&#xff0c;但有时候使用起来真的不方便。有的时候我们在外面&#xff0c;想访问家里或者公司内部的设备&#xff0c;就会碰到一个问题&#xff1a;我们无法直接通过公网IP访…

yolov5代码解读之yolo.py【网络结构】

​这个文件阿对于做模型修改、模型创新有很好大好处。 首先加载一些python库和模块&#xff1a; 如果要执行这段代码&#xff0c;直接在终端输入python yolo.py. yolov5的模型定义和网络搭建都用到了model这个类(也就是以下图片展示的东西)&#xff1a;&#xff08;以前代码没…

接口数据处理

调取接口 增删改查 增 对接口的数据添加字段 url: urlData.filter((urlItem) > urlItem.id item.id),url: urlData.find((urlItem) > urlItem.id item.id)//理想&#xff0c;不能实现 url: urlData.find((urlItem) > {if (urlItem.id item.id) {return urlItem.u…

Linux Linux系统文件类型与文件权限

一、文件类型 &#xff08;1&#xff09;在windows系统中文件类型以文件的后缀名来区分&#xff0c;在Linux系统中文件类型不以后缀名来区分。注意编写c代码时必须写后缀名.c&#xff0c;不然C编译器不会编译该文件。 &#xff08;2&#xff09;在Linux系统中以文件的标志来区…

ROS入门-常见的rostopic命令及其用法的示例

目录 常见的rostopic命令及其用法的示例 1. 列出所有可用的话题&#xff1a; 2. 获取话题详细信息&#xff1a; 3. 实时显示话题消息内容&#xff1a; 4. 发布消息到话题&#xff1a; 5. 发布随机消息到话题&#xff1a; 6. 查看话题消息类型&#xff1a; 7. 查看话题消…

HTTP代理授权方式介绍

在网络爬虫过程中&#xff0c;我们经常需要使用HTTP代理来实现IP隐藏、突破限制或提高抓取效率。而为了确保代理的正常使用&#xff0c;并避免被滥用&#xff0c;代理服务商通常会采用授权方式。在本文中&#xff0c;我们将介绍几种常见的HTTP代理授权方式&#xff0c;以帮助你…

required a single bean, but 2 were found

1.问题描述 要求一个bean,但是发现了两个 说明&#xff1a; 当我们声明一个bean注解时&#xff0c;没有指定BeanName&#xff0c;Spring使用了默认值 spring的IOC容器中 默认一个类型只能有一个bean对象如果有两个bean对象&#xff0c;需要指定BeanName Bean //这个bean的名字…

Docker前置背景:架构演进

"但人类都环绕星球&#xff0c;我更愿追随彗星漂流~" 在正式引入架构演进之前&#xff0c;本小节会对一些比较重要、常见的概念进行介绍。 基本概念: (1)应用(application)/系统(system) 为了完成一整套服务的一个程序或者一组相互配合的程序群。生活例子类比&…

使用公网访问内网IIS网站服务器【无需公网IP】

使用公网访问内网IIS网站服务器【无需公网IP】 文章目录 使用公网访问内网IIS网站服务器【无需公网IP】前言1. 注册并安装cpolar2. 创建隧道映射3. 获取公网地址 前言 这里介绍通过内网穿透&#xff0c;实现公网访问内网IIS网站服务器。 都知道&#xff0c;现在基本不会被分配…

Qt自定义对话框

介绍 自定义框主要通过对现有对话框QDialog类的派生&#xff0c;根据需求编写成员函数、重载信号函数、槽函数&#xff0c;进而实现在主QWidget中点击某个按钮后&#xff0c;一个对话框的弹出 流程 简化创建派生类 最后点击完成即可。 自定义ui界面&#xff0c;编写成员函数…

pytest fixture 常用参数

fixture 常用的参数 参数一&#xff1a;autouse&#xff0c;作用&#xff1a;自动运行&#xff0c;无需调用 举例一&#xff1a;我们在类中定义一个function 范围的fixture; 设置它自动执行autouseTrue&#xff0c;那么我们看下它执行结果 输出&#xff1a; 说明&#xff1a;…

前端项目环境变量如何配置?

我们在项目开发过程中&#xff0c;至少会经历开发环境、测试环境和生产环境三个阶段。不同阶段请求的状态&#xff08;如接口地址等&#xff09;不尽相同&#xff0c;若手动切换接口地址是相当繁琐切容易出错的。于是环境变量配置的需求就应运而生&#xff0c;我们只需做简单的…

【论文简介】PP-OCR中文字符识别论文概述

相关论文 2009.PP-OCR: A Practical Ultra Lightweight OCR System 2109.PP-OCRv2: Bag of Tricks for Ultra Lightweight OCR System 2206.PP-OCRv3: More Attempts for the Improvement of Ultra Lightweight OCR System 工程代码&#xff1a; github_PaddleOCR | 国内gitee_…

FlexRay汽车总线静电防护,如何设计保护方案图?

FlexRay是一种高速、实时、可靠、具备故障容错能力的总线技术&#xff0c;是继CAN和LIN总线之后的最新研发成果。FlexRay为线控应用&#xff08;即线控驱动、线控转向、线控制动等&#xff09;提供了容错和时间确定性性能要求。虽然FlexRay将解决当前高端和未来主流车载网络的挑…

HCIP-OpenStack

1、linux模板制作 使用minimal最小化安装Stream-8 制作Linux 虚拟机模板&#xff0c;后面克隆&#xff08;完整克隆&#xff09;出计算节点compute和控制节点controller&#xff0c;https://blog.51cto.com/cloudcs/5258769 1、修改网卡信息# cat ifcfg-ens160 TYPE…

yolov5代码解读之train.py【训练模型】

哇咔咔&#xff0c;登场 代码开头都是一些导包到模块的&#xff1a; 接下来来到入口函数&#xff1a; 我们直接来到main函数的内容&#xff1a;&#xff08;分四个部分&#xff09; 前两部分&#xff1a; 关于main函数的第二部分中的resume参数&#xff08;496行&#xff09;&…

进程间通信的编程方式(IPC)及实验

进程间通信&#xff08;IPC&#xff09;方式 目录 Socket 管道 匿名管道 消息队列 共享内存 信号 远程过程调用 Socket Socket编程是一种在计算机网络中进程间通信的编程方法。Socket提供了一种在不同主机上运行的进程之间传输数据的机制。通过使用Socket API&#xff…

ABC300

ABC300E 题面 思路 对于投骰子&#xff0c;最后一步可能得到1、2、3、4、5、6&#xff0c;那么对应的最后一步之前的数是n/1、n/2、n/3、n/4、n/5&#xff0c;n/6。并且每个数字&#xff08;1、2、3、4、5、6&#xff09;得到的概率是一样的&#xff0c;即为1/6。 也就是F(n…

Jmeter(七) - 从入门到精通 - 建立数据库测试计划实战<MySQL数据库>(详解教程)

1.简介 在实际工作中&#xff0c;我们经常会听到数据库的性能和稳定性等等&#xff0c;这些有时候也需要测试工程师去评估和测试&#xff0c;上一篇文章主要介绍了jmeter连接和创建数据库测试计划的过程,在文中通过示例和代码非常详细地介绍给大家&#xff0c;希望对各位小伙伴…