文章目录

  • 一、简介
  • 二、Vue2和Vue3区别
  • 三、Vue知识点学习
  • 四、TypeScript知识点
  • 五、项目实战
  • 六、项目打包和自动化部署
    • 一. 项目部署和DevOps
      • 1.1. 传统的开发模式
      • 1.2. DevOps开发模式
      • 1.3. 持续集成和持续交付
      • 1.4. 自动化部署流程
    • 二. 购买云服务器
      • 2.1. 注册阿里云的账号
      • 2.2. 购买云服务器
    • 三. 搭建服务器环境
      • 3.1.CentOS安装和使用DNF
    • 3.2. jenkins自动化部署
      • 3.2.1. 安装Java环境
      • 3.2.2. 安装Jenkins
      • 3.2.3. Jenkins用户
      • 3.2.4. Jenkins配置
      • 3.2.5. Jenkins任务
      • 3.2.6 Jenkins执行任务时 permission denied
    • 3.3. nginx安装和配置
      • 3.3.1. 安装nginx
      • 3.3.2. 配置nginx
  • 七、沿途学习代码地址及案例地址
    • 1、沿途学习代码地址
    • 2、项目案例地址
  • 八、知识拓展
    • 1、ES6数组与对象的解构赋值详解
      • 数组的解构赋值
      • 对象的解构赋值
      • 字符串的解构赋值
    • 2、JavaScript的 ...(展开运算符)
    • 3、export 'defineEmit' (imported as 'defineEmit') was not found in 'vue'
  • 九、其他知识学习
    • 1、Webpack学习
    • 2、数据可视化-echarts
    • 3、Vue2学习
    • 4、JavaScript面向对象和设计模式
    • 5、微前端学习

一、简介

Vue3+TypeScript从入门到进阶(一)——Vue3简介及介绍——附沿途学习案例及项目实战代码

二、Vue2和Vue3区别

Vue3+TypeScript从入门到进阶(二)——Vue2和Vue3的区别——附沿途学习案例及项目实战代码

三、Vue知识点学习

Vue3+TypeScript从入门到进阶(三)——Vue3基础知识点(上)——附沿途学习案例及项目实战代码

Vue3+TypeScript从入门到进阶(四)——Vue3基础知识点(中)——附沿途学习案例及项目实战代码

Vue3+TypeScript从入门到进阶(五)——Vue3基础知识点(下)——附沿途学习案例及项目实战代码

四、TypeScript知识点

Vue3+TypeScript从入门到进阶(六)——TypeScript知识点——附沿途学习案例及项目实战代码

五、项目实战

Vue3+TypeScript从入门到进阶(七)——项目实战——附沿途学习案例及项目实战代码

六、项目打包和自动化部署

一. 项目部署和DevOps

1.1. 传统的开发模式

在传统的开发模式中,开发的整个过程是按部就班就行:

但是这种模式存在很大的弊端:

  • 工作的不协调:开发人员在开发阶段,测试和运维人员其实是处于等待的状态。等到测试阶段,开发人员等待测试反馈bug,也会处于等待状态。
  • 线上bug的隐患:项目准备交付时,突然出现了bug,所有人员需要加班、等待问题的处理;
1.2. DevOps开发模式

DevOps是Development和Operations两个词的结合,将开发和运维结合起来的模式:

1.3. 持续集成和持续交付

伴随着DevOps一起出现的两个词就是持续集成和持续交付(部署):

  • CI是Continuous Integration(持续集成);
  • CD是两种翻译:Continuous Delivery(持续交付)或Continuous Deployment(持续部署);

持续集成CI:

持续交付和持续部署:

1.4. 自动化部署流程

二. 购买云服务器

2.1. 注册阿里云的账号

云服务器我们可以有很多的选择:阿里云、腾讯云、华为云。

  • 目前在公司使用比较多的是阿里云;
  • 我自己之前也一直使用阿里云,也在使用腾讯云;
  • 之前华为云也有找我帮忙推广他们的活动;

但是在我们的课程中,我选择目前使用更加广泛的阿里云来讲解:

我们需要注册阿里云账号

  • https://aliyun.com/

  • 注册即可,非常简单

2.2. 购买云服务器

购买云服务器其实是购买一个实例。

1.来到控制台:

2.创建实例,选择类型和配置

3.配置网络安全组

4.创建实例

三. 搭建服务器环境

3.1.CentOS安装和使用DNF

DNF新一代的RPM软件包管理器。他首先出现在 Fedora 18 这个发行版中。而最近,他取代了YUM,正式成为 Fedora 22 的包管理器。

DNF包管理器克服了YUM包管理器的一些瓶颈,提升了包括用户体验,内存占用,依赖分析,运行速度等多方面的内容。

DNF使用 RPM, libsolv 和 hawkey 库进行包管理操作。尽管它没有预装在 CentOS 和 RHEL 7 中,但你可以在使用 YUM 的同时使用 DNF 。

DNF 的最新稳定发行版版本号是 1.0,发行日期是2015年5月11日。 这一版本的额 DNF 包管理器(包括在他之前的所有版本) 都大部分采用 Pathon 编写,发行许可为GPL v2.

– 安装 DNF 包管理器

DNF 并未默认安装在 RHEL 或 CentOS 7系统中,但是 Fedora 22 已经默认使用 DNF .

1.为了安装 DNF ,您必须先安装并启用 epel-release 依赖。

在系统中执行以下命令:

yum install epel-release

或者

yum install epel-release -y

其实这里并没有强制使用”-y”的理由,相反的,在不使用”-y”的情况下,用户可以在安装过程中查看到底有哪些东西被安装进了系统。但对于没有这个需求的用户,您可以在 YUM 中使用”-y”参数来自动安装所有东西。

2.使用 epel-release 依赖中的 YUM 命令来安装 DNF 包。、

在系统中执行以下命令:

yum install dnf

然后, DNF 包管理器就被成功的安装到你的系统中了。接下来,是时候开始我们的教程了!在这个教程中,您将会学到27个用于 DNF 包管理器的命令。使用这些命令,你可以方便有效的管理您系统中的 RPM 软件包。现在,让我们开始学习 DNF 包管理器的27条常用命令吧!

– 查看 DNF 包管理器版本

用处:该命令用于查看安装在您系统中的 DNF 包管理器的版本

命令:

dnf –version
3.2. jenkins自动化部署
3.2.1. 安装Java环境

Jenkins本身是依赖Java的,所以我们需要先安装Java环境:

  • 这里我安装了Java1.8的环境
dnf search java-1.8
dnf install java-1.8.0-openjdk.x86_64
3.2.2. 安装Jenkins

因为Jenkins本身是没有在dnf的软件仓库包中的,所以我们需要连接Jenkins仓库:

  • wget是Linux中下载文件的一个工具,-O表示输出到某个文件夹并且命名为什么文件;
  • rpm:全称为The RPM Package Manage,是Linux下一个软件包管理器;
wget –O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo# 导入GPG密钥以确保您的软件合法
rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key
# 或者
rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key

编辑一下文件/etc/yum.repos.d/jenkins.repo

  • 可以通过vim编辑
[jenkins]name=Jenkins-stablebaseurl=http://pkg.jenkins.io/redhatgpgcheck=1

安装Jenkins

dnf install jenkins # --nogpgcheck(可以不加)

启动Jenkins的服务:

systemctl start jenkins
systemctl status jenkins
systemctl enable jenkins

Jenkins默认使用8080端口提供服务,所以需要加入到安全组中:

3.2.3. Jenkins用户

我们后面会访问centos中的某些文件夹,默认Jenkins使用的用户是 jenkins,可能会没有访问权限,所以我们需要修改一下它的用户:

修改文件的路径:/etc/sysconfig/jenkins

之后需要重启一下Jenkins:

systemctl restart jenkins
3.2.4. Jenkins配置

打开浏览器,输入:http://8.134.60.235:8080/

  • 注意:你输入自己的IP地址

获取输入管理员密码:

  • 在下面的地址中 cat /var/lib/jenkins/secrets/initialAdminPassword

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kGFIYzwF-1653820193033)(/Users/coderwhy/Library/Application Support/typora-user-images/image-20201203173047824.png)]

可以安装推荐的插件:

3.2.5. Jenkins任务

新建任务:

配置项目和保留策略:

源码管理:

构建触发器:

这里的触发器规则是这样的:

  • 定时字符串从左往右分别是:分 时 日 月 周
#每半小时构建一次OR每半小时检查一次远程代码分支,有更新则构建
H/30 * * * *#每两小时构建一次OR每两小时检查一次远程代码分支,有更新则构建
H H/2 * * *#每天凌晨两点定时构建
H 2 * * *#每月15号执行构建
H H 15 * *#工作日,上午9点整执行
H 9 * * 1-5#每周1,3,5,从8:30开始,截止19:30,每4小时30分构建一次
H/30 8-20/4 * * 1,3,5

构建环境:

注意:我们需要搭建Node的环境

  • 第一步:配置Node的环境;
  • 第二步:安装Node的插件;

第一步:配置Node的环境

第二步:安装Node的插件

  • 这里因为我已经安装过了,所以没有搜索到;

构建执行的任务:

  • 查看Node的版本等是否有问题;
  • 执行 npm install 安装项目的依赖;
  • 移除原来mall_cms文件的所有内容;
  • 将打包的dist文件夹内容移动到mall_cms文件夹;
pwd
node -v
npm -vnpm install
npm run buildpwdecho '构建成功'ls# 删除/root/mall_cms文件夹里所有的内容
rm -rf /root/mall_cms/* cp -rf ./dist/* /root/mall_cms/

3.2.6 Jenkins执行任务时 permission denied

Jenkins执行任务shell时,有时需要进行删除文件或者移动并删除文件等操作。但是Jenkins的权限组时 Jenkins。

但是我们创建的文件有时候的权限会这个高。比如文件夹的权限是root的。这个时候执行脚本就会报错

但是这个网上找了很多方式,比如把Jenkins的权限组换成root,但是这样会出现新的问题,因为Jenkins的启动会用到JDK,如果把Jenkins的权限组换成了root,那JDK就无法辅助Jenkins启动了。

所以最简单的方式是 将 Jenkins要进行操作的文件夹的上层文件夹的权限进行更换,换成Jenkins的

chown -R jenkins:jenkins 目标文件夹路径
3.3. nginx安装和配置
3.3.1. 安装nginx

后续我们部署会使用nginx,所以需要先安装一下nginx:

dnf install nginx

启动nginx:

systemctl start nginx
systemctl status nginx
systemctl enable nginx
3.3.2. 配置nginx

我们这里主要配置nginx的用户和默认访问目录:

配置用户:

通过Linux命令创建文件夹和文件:

mkdir /root/mall_cms
cd /root/mall_cms
touch index.htmlvi index.html

配置访问目录:

七、沿途学习代码地址及案例地址

1、沿途学习代码地址

https://gitee.com/wu_yuxin/vue3-learning.git

2、项目案例地址

https://gitee.com/wu_yuxin/vue3-ts-cms.git


八、知识拓展

1、ES6数组与对象的解构赋值详解

数组的解构赋值

基本用法

ES6允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,这被称之为解构(Destructuring)

// 以前为变量赋值,只能直接指定值
var a = 1;
var b = 2;
var c = 3;
// ES6允许写成这样
var [a,b,c] = [1,2,3];

本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

下面是一些使用嵌套数组进行解构的例子:

let [foo,[[bar],baz]] = [1,[[2],3]];
foo // 1
bar // 2
baz // 3
let [,,third] = ["foo","bar","baz"];
third // "baz"
let [head,...tail] = [1,2,3,4];
head // 1
tail // [2,3,4]
let [x,y,...z] = ['a'];
x // "a"
y // undefined
z // []

默认值

解构赋值允许制定默认值

var [foo = true] = [];
foo // true
[x,y='b'] = ['a'];
// x='a', y='b'

注意,ES6内部使用严格相等运算符(===),判断一个位置是否有值。

所以,如果一个数组成员不严格等于undefined,默认值是不会生效的。

var [x=1] = [undefined];
x //1
var [x=1] = [null];
x // null

如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值:

function f(){console.log('aaa');
}
let [x=f()] = [1];

上面的代码中,因为x能取到值,所以函数f()根本不会执行。上面的代码其实等价于下面的代码:

let x;
if([1][0] === undefined){x = f();
}else{x = [1][0];
}

默认值可以引用解构赋值的其他变量,但该变量必须已经声明:

let [x=1,y=x] = [];
// x=1; y=1
let [x=1,y=x] = [2];
// x=2; y=2
let [x=1,y=x] = [1,2];
// x=1; y=2
let [x=y,y=1] = []; // ReferenceError

上面最后一个表达式,因为x用到默认值是y时,y还没有声明。

对象的解构赋值

1、最简单的案例

看下面的案例

 let person = {name: 'yhb',age: 20}/*注意:下面虽然看起来是创建了一个对象,对象中有两个属性 name 和 age但是:其实是声明了两个变量name:等于对象person 中的name属性的值age:等于对象person 中的 age属性的值*/let { name, age } = personconsole.log(name,age)

如上面注释中所说,声明了变量 name和age,然后分别从对象person中寻找与变量同名的属性,并将属性的值赋值给变量

所以,这里的关键,就是首先要知道对象中都有哪些属性,然后再使用字面量的方式声明与其同名的变量

2、属性不存在怎么办
如果不小心声明了一个对象中不存在的属性怎么办?

或者,实际情况下,可能是我们就是想再声明一个变量,但是这个变量也不需要从对象中获取值,这个时候,此变量的值就是 undefined

let person = {name: 'yhb',age: 20
}
let { name, age,address } = person
console.log(name,age,address)

此时,可以给变量加入一个默认值

let { name, age,address='北京' } = person

3、属性太受欢迎怎么办

当前声明了 name 和 age 变量,其值就是person对象中name和age属性的值,如果还有其他变量也想获取这两个属性的值怎么办?

 let { name, age, address = '北京' } = personconsole.log(name, age, address)let { name, age } = personconsole.log(name, age)

上面的方法肯定不行,会提示定义了重复的变量 name 和 age

那怎么办呢?

难道只能放弃结构赋值,使用老旧的方式吗?

let l_name=person.name
let l_age=person.age
console.log(l_name,l_age)

其实不然!

let {name:l_name,age:l_age}=person
console.log(l_name,l_age)

说明:

声明变量 l_name 并从对象person中获取name属性的值赋予此变量
声明变量 l_age, 并从对象person中获取age属性的值赋予此变量
这里的重点是下面这行代码

let {name:l_name,age:l_age}=person

按照创建对象字面量的逻辑,name 为键,l_name 为值。但注意,这里是声明变量,并不是创建对象字面量,所以争取的解读应该是

声明变量 l_name,并从person 对象中找到与 name 同名的属性,然后将此属性的值赋值给变量 l_name

所以,我们最后输出的是变量 l_name和l_age

console.log(l_name,l_age)

当然这种状态下,也是可以给变量赋予默认值的

let { name:l_name, age:l_age, address:l_address='北京' }=person

4、嵌套对象如何解构赋值

let person = {name: 'yhb',age: 20,address: {province: '河北省',city: '保定'}
}
// 从对象 person 中找到 address 属性,并将值赋给变量 address
let {address}=person
// 从对象 address 中找到 province 属性,并将值赋给变量 province
let {province}=address
console.log(province)

上面代码一层层的进行结构赋值,也可以简写为如下形式

let {address:{province}}=person

从peson 对象中找到 address 属性,取出其值赋值给冒号前面的变量 address,然后再将 变量address 的值赋值给 冒号 后面的变量 {province},相当于下面的写法

let {province}=address
字符串的解构赋值

1、字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

let {length : len} = 'hello';
len // 5

2、JavaScript的 …(展开运算符)

三个连续的点具有两个含义:展开运算符(spread operator)和剩余运算符(rest operator)。

展开运算符

展开运算符允许迭代器在接收器内部分别展开或扩展。迭代器和接收器可以是任何可以循环的对象,例如数组、对象、集合、映射等。你可以把一个容器的每个部分分别放入另一个容器。

const newArray = ['first', ...anotherArray];

剩余参数

剩余参数语法允许我们将无限数量的参数表示为数组。命名参数的位置可以在剩余参数之前。

const func = (first, second, ...rest) => {};

用例

定义是非常有用的,但是很难仅从定义中理解概念。我认为用日常用例会加强对定义的理解。

复制数组

当我们需要修改一个数组,但又不想改变原始数组(其他人可能会使用它)时,就必须复制它。

const fruits = ['apple', 'orange', 'banana'];
const fruitsCopied = [...fruits]; // ['apple', 'orange', 'banana']console.log(fruits === fruitsCopied); // false// 老方法
fruits.map(fruit => fruit);

它正在选择数组中的每个元素,并将每个元素放在新的数组结构中。我们也可以使用 map 操作符实现数组的复制并进行身份映射。

唯一数组

如果我们想从数组中筛选出重复的元素,那么最简单的解决方案是什么?

Set 对象仅存储唯一的元素,并且可以用数组填充。它也是可迭代的,因此我们可以将其展开到新的数组中,并且得到的数组中的值是唯一的。

const fruits = ['apple', 'orange', 'banana', 'banana'];
const uniqueFruits = [...new Set(fruits)]; // ['apple', 'orange', 'banana']// old way
fruits.filter((fruit, index, arr) => arr.indexOf(fruit) === index);

串联数组
可以用 concat 方法连接两个独立的数组,但是为什么不再次使用展开运算符呢?

const fruits = ['apple', 'orange', 'banana'];
const vegetables = ['carrot'];
const fruitsAndVegetables = [...fruits, ...vegetables]; // ['apple', 'orange', 'banana', 'carrot']
const fruitsAndVegetables = ['carrot', ...fruits]; // ['carrot', 'apple', 'orange', 'banana']// 老方法
const fruitsAndVegetables = fruits.concat(vegetables);
fruits.unshift('carrot');

将参数作为数组进行传递

当传递参数时,展开运算符能够使我们的代码更具可读性。在 ES6 之前,我们必须将该函数应用于 arguments。现在我们可以将参数展开到函数中,从而使代码更简洁。

const mixer = (x, y, z) => console.log(x, y, z);
const fruits = ['apple', 'orange', 'banana'];mixer(...fruits); // 'apple', 'orange', 'banana'// 老方法
mixer.apply(null, fruits);

数组切片

使用 slice 方法切片更加直接,但是如果需要的话,展开运算符也可以做到。但是必须一个个地去命名其余的元素,所以从大数组中进行切片的话,这不是个好方法。

const fruits = ['apple', 'orange', 'banana'];
const [apple, ...remainingFruits] = fruits; // ['orange', 'banana']// 老方法
const remainingFruits = fruits.slice(1);

将参数转换为数组
Javascript 中的参数是类似数组的对象。你可以用索引来访问它,但是不能调用像 map、filter 这样的数组方法。参数是一个可迭代的对象,那么我们做些什么呢?在它们前面放三个点,然后作为数组去访问!

const mixer = (...args) => console.log(args);
mixer('apple'); // ['apple']

将 NodeList 转换为数组
参数就像从 querySelectorAll 函数返回的 NodeList 一样。它们的行为也有点像数组,只是没有对应的方法。

[...document.querySelectorAll('div')];// 老方法
Array.prototype.slice.call(document.querySelectorAll('div'));

复制对象
最后,我们介绍对象操作。复制的工作方式与数组相同。在以前它可以通过 Object.assign 和一个空的对象常量来实现。

const todo = { name: 'Clean the dishes' };
const todoCopied = { ...todo }; // { name: 'Clean the dishes' }
console.log(todo === todoCopied); // false// 老方法
Object.assign({}, todo);

合并对象
合并的唯一区别是具有相同键的属性将被覆盖。最右边的属性具有最高优先级。

const todo = { name: 'Clean the dishes' };
const state = { completed: false };
const nextTodo = { name: 'Ironing' };
const merged = { ...todo, ...state, ...nextTodo }; // { name: 'Ironing', completed: false }// 老方法
Object.assign({}, todo, state, nextTodo);

需要注意的是,合并仅在层次结构的第一级上创建副本。层次结构中的更深层次将是相同的引用。

将字符串拆分为字符
最后是字符串。你可以用展开运算符把字符串拆分为字符。当然,如果你用空字符串调用 split 方法也是一样的。

const country = 'USA';
console.log([...country]); // ['U', 'S', 'A']// 老方法
country.split('');

3、export ‘defineEmit’ (imported as ‘defineEmit’) was not found in ‘vue’



在学习vue3的顶层编写方式时的父子组件通信的时候,我们会看到一些比较老(2020、2021年初)的博客里面会有使用defineEmit的,但是如果我们用比较新版本的Vue3的话,就会报错。原因是,新版本的Vue3将defineEmit改成了defineEmits了

九、其他知识学习

1、Webpack学习

Webpack从入门到进阶(一)—附沿路学习案例代码

Webpack从入门到进阶(二)—附沿路学习案例代码

Webpack从入门到进阶(三)—附沿路学习案例代码

2、数据可视化-echarts

数据可视化-echarts入门、常见图表案例、超详细配置解析及项目案例

3、Vue2学习

Vue项目开发-仿蘑菇街电商APP

Vue 知识点汇总(上)–附案例代码及项目地址

Vue 知识点汇总(下)–附案例代码及项目地址

4、JavaScript面向对象和设计模式

JavaScript面向对象编程浅析

JavaScript设计模式浅析

5、微前端学习

SingleSpa及qiankun入门、源码分析及案例

Vue3+TypeScript从入门到进阶(八)——项目打包和自动化部署——附沿途学习案例及项目实战代码相关推荐

  1. Vue3+TypeScript从入门到进阶(六)——TypeScript知识点——附沿途学习案例及项目实战代码

    文章目录 一.简介 二.Vue2和Vue3区别 三.Vue知识点学习 四.TypeScript知识点 一.JavaScript和TypeScript 二.TypeScript的安装和使用 1.Type ...

  2. 项目打包和自动化部署

    项目打包和自动化部署 一. 项目部署和DevOps 1.1. 传统的开发模式 在传统的开发模式中,开发的整个过程是按部就班就行: 但是这种模式存在很大的弊端: 工作的不协调:开发人员在开发阶段,测试和 ...

  3. Vue3+TypeScript从入门到精通系列之:Try changing the lib compiler option to es2015 or later

    Vue3+TypeScript从入门到精通系列之:Try changing the lib compiler option to es2015 or later tsc ./泛型接口.ts tsc编译 ...

  4. Vue3+TypeScript从入门到精通系列之:泛型接口

    Vue3+TypeScript从入门到精通系列之:泛型接口 一.TypeScript的泛型接口代码 二.TypeScript的泛型接口代码转化为js代码 三.泛型接口.js输出如下所示 一.TypeS ...

  5. Webpack从入门到进阶(二)---附沿路学习案例代码

    文章目录 Webpack从入门到进阶(一)---附沿路学习案例代码 一.Webpack简介 1.前端发展的几个阶段 2.前端三个框架的脚手架 3.Webpack是什么? 4.webpack和vite ...

  6. Angular项目打包到nginx部署过程

    Angular项目打包到nginx部署过程 一. 打包Angluar ng build,会在项目文件夹下生成dist文件,里面是打包后的文件 二. 部署nginx 在nginx官网中下载nginx 把 ...

  7. Spring Boot学习案例开源项目

    为了更好的学习并使用springboot进行开发,维护了一个springboot学习案例开源项目,涉及springboot从基础开发到企业实战,涵盖不同场景的开发案例.公司内部所有的服务都基于spri ...

  8. IDEA集成Docker插件实现项目打包镜像一键部署与Docker CA加密认证

    IDEA集成Docker插件实现项目打包镜像一键部署与Docker CA加密认证 Docker开启远程访问 修改该Docker服务文件 加载配置与重启 验证是否开启成功 IDEA配置docker 编写 ...

  9. SQL Server AlwaysON从入门到进阶(6)——分析和部署AlwaysOn Availability Group

    本文属于SQL Server AlwaysON从入门到进阶系列文章 前言: 本节是整个系列的重点文章,到现在,读者应该已经对整个高可用架构有一定的了解,知道独立的SQL Server实例和基于群集的S ...

最新文章

  1. Tensorflow会话
  2. Centos 7 全网备份Rsync
  3. JAVA WEB开发环境搭建教程
  4. php 字符串打散为数组,用逗号分隔出数组
  5. (干货!最全)Tomcat入门
  6. 数据结构(二十)二叉树的递归遍历算法
  7. Python---字符串与列表
  8. java导出excel 客户端_java如何将导出的excel下载到客户端
  9. windows10百度网盘下载,windows iso文件下载
  10. html区分手机和电脑,移动端和pc端的区别是什么
  11. ESP32-C2 Homekit烧录示例
  12. httprunner之业务解耦
  13. Nginx+Tomcat负载均衡、动静分离
  14. matlab bmp rgb如何转换,RGB到XYZ转化
  15. C语言程序设计-关系运算符和关系表达式、逻辑运算符和逻辑表达式
  16. StampedLock原理分析
  17. 清空缓冲区:fflush(stdin)、fflush(stdout)
  18. [gdc13]《孤岛危机3》渲染技术
  19. SRM 504.5 DIV2
  20. CVPR2022-图像恢复重建Restormer论文解读

热门文章

  1. ios 图片拉伸不变形的方法
  2. 记:flex布局遇到white-space:nowrap失效的问题
  3. 关于恶意代码的一些TIPS
  4. ArcGIS之字段计算器
  5. 怎么把文字生成图片?三款ai绘画生成器分享
  6. 在html监听鼠标拖动,使用javaScript实现鼠标拖拽事件
  7. 计算机机等级考试四级模拟,2017年全国计算机等级考试四级模拟试题(四)
  8. 无线网络wifi的一些概念、信道channel,带宽,有线和无线网络的区别、DBDC双频双发、RSDB(双频合一)、MESH组网
  9. [LeetCode解题报告] 365. 水壶问题
  10. CSS的before属性的用法