Vue-2.nodejs的介绍和安装

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>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于ffmpeg与SDL的视频播放库

由于工作需要&#xff0c;自己封装的基于ffmpeg的视频编解码库&#xff0c;显示采用了SDL库。可以播放本地文件或网络流&#xff0c;支持多端口播放&#xff0c;支持文字叠加&#xff0c;截图、视频录制等等。 头文件代码&#xff1a; #pragma once #ifdef __DLLEXPORT #defin…

SpringCloud实用篇5——elasticsearch基础

目录 1.初识elasticsearch1.1 了解ES1.1.1 elasticsearch的作用1.1.2 ELK技术栈1.1.3 elasticsearch和lucene1.1.4 总结 1.2.倒排索引1.2.1.正向索引1.2.2.倒排索引1.2.3.正向和倒排 1.3 es的一些概念1.3.1 文档和字段1.3.2 索引和映射1.3.3 mysql与elasticsearch 1.4 部署单点…

flutter开发实战-TextPainter计算文本内容的宽度

flutter开发实战-TextPainter计算文本内容的宽度 最近开发过程中根据Text文本的大小判断是否需要进行显示跑马灯效果&#xff0c;获取文本的大小&#xff0c;需要TextPainter来获取Size 一、TextPainter TextPainter主要用于实现文本的绘制。TextPainter类可以将TextSpan渲染…

浏览器多管闲事之跨域

年少时的梦想就是买一台小霸王游戏机 当时的宣传语就是小霸王其乐无穷~。 大些了&#xff0c;攒够了零花钱&#xff0c;在家长的带领下终于买到了 那一刻我感觉就是最幸福的人 风都是甜的&#xff01; 哪成想... 刚到家就被家长扣下了 “”禁止未成年人玩游戏机 (问过卖家了&a…

Window下安装MinGW64

欢迎来到我的酒馆 介绍Windows下&#xff0c;安装MinGW64。 目录 欢迎来到我的酒馆二.MinGW64三.配置系统环境变量 二.MinGW64 从sourceforge下载mingw64&#xff0c; sourceforge下载MinGW https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/ 下…

香港站群服务器为什么适合seo优化?

​  香港站群为什么适合seo优化?本文主要从以下四点出发进行原因阐述。 1.香港站群服务器的优势 2.香港站群服务器与国内服务器的对比 3.多IP站群服务器的优势 4.香港站群服务器在SEO优化中的注意事项 1.香港站群服务器的优势 香港站群服务器是为了满足企业SEO优化需求而提供…

实践分享:Vue 项目如何迁移小程序

最近我们小组刚经历了将成熟的 HTML5 项目转换成小程序&#xff0c;并在app中运行的操作&#xff01;记录下来分享给各位。 项目&#xff1a;将已有的 Vue 项目转为小程序&#xff0c; 在集成了FinClip SDK 的 App 中运行。 技术&#xff1a;uni-app、FinClip 两个注意事项&…

[每周一更]-(第57期):用Docker、Docker-compose部署一个完整的前后端go+vue分离项目

文章目录 1.参考项目2.技能点3.GO的Dockerfile配置后端的结构如图Dockerfile先手动docker调试服务是否可以启动报错 4.Vue的Dockerfile配置前端的结构如图nginx_docker.confDockerfile构建 5.docker-compose 整合前后端docker-compose.yml错误记录&#xff08;1&#xff09;ip端…

PS AI版本安装教程

好久没写博客了&#xff0c;今天更新一下子吧&#xff01; 随着chatGPT的提出&#xff0c;各种软件逐渐开始镶嵌人工智能&#xff0c;为我们的生活带来了极大的便利&#xff01;话不多说&#xff0c;开始介绍今天的主角&#xff0c;PS的AI版本。 安装教程&#xff1a; 1.安装…

Docker一键部署项目,无需登录XShell

文章目录 一键部署项目Docker手动部署SpringBoot项目编写docker部署的脚本文件script.sh 脚本内容 特别注意&#xff01;编写dockerfiledockerfile 文件内容 上传后端服务的jar包到服务器中执行 script 脚本部署后端服务 自动部署SpringBoot项目引入jsch依赖编写jsch工具类执行…

工业4.0:欢迎来到智能制造

制造业正在经历一场被称为“工业4.0”的全新技术革命&#xff0c;这场革命将数字化、网络化、智能化和自动化技术融合在一起&#xff0c;旨在打造高质、高效、高产且可持续的智能工厂。工业4.0将彻底改变产品制造的方式&#xff0c;颠覆我们对制造业的传统认知。 什么是工业4.…

【Java】try|catch|throws 具体详解+应用

目录 tryCatch 基本介绍 使用细节 throws异常处理 基本介绍 ​ 使用细节 自定义异常 基本概念 步骤 throw和throws的区别 tryCatch 基本介绍 使用细节 throws异常处理 基本介绍 使用细节 自定义异常 基本概念 步骤 throw和throws的区别

【数据结构】Disruptor环形数组无锁并发框架阅读

Disruptor 是苹国外厂本易公司LMAX开发的一个高件能列&#xff0c;研发的初夷是解决内存队列的延识问顾在性能测试中发现竟然与10操作处于同样的数量级)&#xff0c;基于Disruptor开发的系统单线程能支撑每秒600万订单&#xff0c;2010年在QCn演讲后&#xff0c;获得了业界关注…

MinGW-W64 下载、安装与配置(支持最新版的GCC,目前 GCC 13.2.0)

文章目录 一、简介1. MinGW 和 MinGW-W64 区别和联系2. MSVCRT 和 UCRT 介绍 二、下载1. 从 sourceforge.net 下载2. 从 github 下载3. 从 镜像站点 下载4. 自己编译 三、安装与配置1. 在线安装2. 离线安装3. 环境配置 四、总结 一、简介 1. MinGW 和 MinGW-W64 区别和联系 M…

数组slice、splice字符串substr、split

一、定义 这篇文章主要对数组操作的两种方法进行介绍和使用&#xff0c;包括&#xff1a;slice、splice。对字符串操作的两种方法进行介绍和使用&#xff0c;包括&#xff1a;substr、split (一)、数组 slice:可以操作的数据类型有&#xff1a;数组字符串 splice:数组 操作数组…

【go语言学习笔记】04 Go 语言工程管理

文章目录 一、质量保证1. 单元测试1.1 定义1.2 Go 语言的单元测试1.3 单元测试覆盖率 2. 基准测试2.1 定义2.2 Go 语言的基准测试2.3 计时方法2.4 内存统计2.5 并发基准测试2.6 基准测试实战 3. 特别注意 二、性能优化1. 代码规范检查1.1 定义1.2 golangci-lint1.2.1 安装1.2.2…

vue3 + ts+element-plus学习笔记

子组件通过defineProps方法接收父组件传递过来的数据&#xff0c;是vue3中提供的方法&#xff0c;不需要引入&#xff0c;直接使用 方法的写法&#xff1a; const onClick (){... }自定义事件&#xff1a; 子组件点击事件 全局事件总线 mitt 兄弟组件之间的事件&#x…

【福建事业单位-资料分析】03 比重和平均数

【福建事业单位-资料分析】03 比重和平均数 一、比重&#xff08;现期比重&#xff0c;基期比重、两期比重&#xff09;1.1 现期比重增长贡献量&#xff0c;利润率 1.2基期比重&#xff08;用现期和增长率逆求&#xff09;1.3两期比重&#xff08;难点重点&#xff09;——比较…

基础实验篇 | QGC实时调整控制器参数实验

PART 1 实验名称及目的 QGC实时调整控制器参数实验&#xff1a;在进行硬件在环仿真和真机实验时&#xff0c;常常需要在QGC地面站中观察飞行状态&#xff0c;并对控制器参数进行实时调整&#xff0c;以使得飞机达到最佳的控制效果&#xff0c;但是&#xff0c;在Simulink中设…

改进的麻雀算法优化最大相关峭度解卷积(SCSSA-MCKD),实现早期微弱故障诊断,MATLAB代码实现

01 引言 由于一些设备的早期故障产生的冲击十分微弱&#xff0c;易被系统噪声干扰&#xff0c;如何有效地对设备的原始故障信号进行降噪并增强信号中微弱冲击成分&#xff0c;是进行该类部件早期故障诊断的关键。 最大相关峭度解卷积&#xff08;MCKD&#xff09;通过解卷积运算…