一、初识Java计算机语言发展历史计算机编程语言的发展，是随着计算机本身硬件发展而发展的。硬件速度越快、体积越小、成本越低，应用到人类社会的场景就会越多，那么所需要的算法就会越复杂，也就要求计算机编程语言越高级。最初重达几十吨但一秒只能运算5000次的ENIAC(世界上第一台计算机)，只能做非常小的应用，比如：某些情况的弹道计算。现在任何一个人的手机运算能力都可以秒杀那个年代地球上所有计算机运算能力的总和。计算机编程语言的发展历经了从低级到高级发展。发展的核心思想就是“让人更容易编程”。越容易使用的语言，就有越多人使用；越多人使用，就有越多协作；越多协作，就可以创造越复杂的物体；计算机语言经历了三代：第一代是机器语言，第二代是汇编语言，第三代是高级语言。所需程序https://www.123pan.com/s/EGKKVv-GLfxh.html 提取码:bKAy常用DOS命令DOS系统Microsoft公司推出的操作系统。（在windows之前的操作系统） DOS是英文"Disk Operating System"的缩写,其中文含意是"磁盘操作系统". DOS是单用户、单任务的操作系统.（只能执行一个任务）DOS命令在windows中，我们通过鼠标菜单等来操作系统，而在dos操作系统中，要通过dos命令来操作系统。 是DOS操作系统的命令，是一种面向磁盘的操作命令，不区分大小写。切换盘符 c: d: e:显示目录下详细信息 dir改变当前目录 cd清屏 cls创建目录 md删除目录 rd复制文件 copy删除文件 delJava入门程序开发开发Java程序，需要三个步骤：编写代码，编译代码，运行代码[x] 编写代码：任何一个文本编辑器都可以些代码，如Windows系统自带的记事本[x] 编译代码：将人能看懂的源代码（.java文件）转换为Java虚拟机能够执行的字节码文件（.class文件）[x] 运行代码：将字节码文件交给Java虚拟机执行第一个java程序public class helloworld(){ public static void main(String[] args){ System.out.println("hello world"); } }注意：文件名称必须与代码中的类名称一致JDK组成JDK由JVM、核心类库、开发工具组成，如下图所示：什么是JVM?答：JDK最核心的组成部分是JVM（Java Virtual Machine），它是Java虚拟机，真正运行Java程序的地方。什么是核心类库？答：它是Java本身写好的一些程序，给程序员调用的。 Java程序员并不是凭空开始写代码，是要基于核心类库提供的一些基础代码，进行编程。什么是JRE?答：JRE（Java Runtime Enviroment），意思是Java的运行环境；它是由JVM和核心类库组成的；如果你不是开发人员，只需要在电脑上安装JRE就可以运行Java程序。什么是开发工具呢？答：Java程序员写好源代码之后，需要编译成字节码，这里会提供一个编译工具叫做javac.exe，编写好源代码之后，想要把class文件加载到内存中运行，这里需要用到运行工具java.exe。 除了编译工具和运行工具，还有一些其他的反编译工具、文档工具等待...JDK、JRE的关系用一句话总结就是：用JDK开发程序，交给JRE运行Java跨平台原理Java跨平台原理：C语言跨平台原理：总结：JVM(Java Virtual Machine)就是一个虚拟的用于执行bytecode字节码的”虚拟计算机”。他也定义了指令集、寄存器集、结构栈、垃圾收集堆、内存区域。JVM负责将Java字节码解释运行，边解释边运行，这样，速度就会受到一定的影响。不同的操作系统有不同的虚拟机。Java 虚拟机机制屏蔽了底层运行平台的差别，实现了“一次编译，随处运行”。 Java虚拟机是实现跨平台的核心机制。如图所示：我们说的语言跨平台是编译后的文件跨平台，而不是源程序跨平台。接下来我们再比较下两种方式的差异：第一，C语言是编译执行的，编译器与平台相关，编译生成的可执行文件与平台相关；第二，Java是解释执行的，编译为中间码的编译器与平台无关，编译生成的中间码也与平台无关（一次编译，到处运行），中间码再由解释器解释执行，解释器是与平台相关的，也就是不同的平台需要不同的解释器.Java开发工具IDEA想要在IDEA正确的写一个Java程序，必须先认识一下IDEA的管理Java程序的工程结构。第一步：首先得在IDEA中创建一个Project（工程、也叫项目），后面统称为工程。第二步：需要在Project中创建Module（模块），一个工程中可以包含多个模块第三步：需要在Module中新建Package（包），一个模块中可以有多个包第四步：需要在Package中新建Class（类），一个包中可以包含多个类二、Java基础语法2.1 注释为了方便程序的阅读，Java语言允许程序员在程序中写上一些说明性的文字，用来提高程序的可读性，这些文字性的说明就称为注释。注释不会出现在字节码文件中，即Java编译器编译时会跳过注释语句。 在Java中根据注释的功能不同，主要分为单行注释、多行注释和文档注释。单行注释单行注释使用“//”开头，“//”后面的单行内容均为注释。多行注释多行注释以“/”开头以“/”结尾，在“/”和“/”之间的内容为注释，我们也可以使用多行注释作为行内注释。但是在使用时要注意，多行注释不能嵌套使用。文档注释文档注释以“/*”开头以“/”结尾， 注释中包含一些说明性的文字及一些JavaDoc标签（后期写项目时，可以生成项目的API）2.2 字面常量常量通常指的是一个固定的值，例如：1、2、3、’a’、’b’、true、false、”helloWorld”等。 在Java语言中，主要是利用关键字final来定义一个常量。 常量一旦被初始化后不能再更改其值。为了更好的区分和表述，一般将1、2、3、’a’、’b’、true、false、”helloWorld”等称为字面常量，而使用final修饰的PI等称为符号常量（字符常量）。public class LiteralDemo{ public static void main(String[] args){ //1.整数 System.out.println(666); //2.小数 System.out.println(3.66); //3.字符: 字符必须用单引号引起来 System.out.println('a'); System.out.println('0'); System.out.println('中'); System.out.println(' '); //空格也算字符 //特殊字符：\t表示制表符 \n表示换行 System.out.println('\t'); //这相当于一个tab键，专业叫做制表符 System.out.println('\n'); //这是换行的意思 //4.字符串：字符串是双引号引起来的 System.out.println("我爱你中国abc"); //5.布尔值：只有两个值true和false System.out.println(true); System.out.println(false); } }2.3 变量变量本质上就是代表一个可操作的存储空间，空间位置是确定的，但是里面放置什么值不确定。我们可通过变量名来访问“对应的存储空间”，从而操纵这个“存储空间”存储的值。Java是一种强类型语言，每个变量都必须声明其数据类型。变量的数据类型决定了变量占据存储空间的大小。 比如，int a=3;表示a变量的空间大小为4个字节。变量作为程序中最基本的存储单元，其要素包括变量名，变量类型和作用域。变量在使用前必须对其声明, 只有在变量声明以后，才能为其分配相应长度的存储空间。 变量的声明格式：int age = 18; System.out.println(a);当执行int age = 18; 这句代码时，JVM会在内存中申请一块区域，在这个区域中存储了一个整数18，给这个区域取的名字叫age； 相当于在盒子中存了一个数据18，这个盒子的名字是age，当我们打印age时，就是从盒子中把盒子中的数据取出来再打印。变量的作用域变量定义在哪个{}范围内，就只在哪个大括号内有效。变量的有效范围称之为变量的作用域 { int a = 10; System.out.println(a); //这是是对的 } System.out.println(a); //这里会出错注意事项：变量在定义时可以不赋值，但使用时必须赋值。总结：变量是用来记录程序中的数据的，可以把变量理解成内存中的小盒子，盒子里放的东西就是变量记录的数据变量的定义格式： 数据类型 变量名 = 初始值;变量记录的数据程序运行过程中是可以发生改变的：变量名 = 值;2.4 关键字被Java语言赋予了特殊含义，用作专门用途的单词特点：Java中所有关键字都为小写abstractassertbooleanbreakbytecasecatchcharclassconstcontinuedefaultdodoubleelseenumextendsfinalfinallyfloatforgotoifimplementsimportinstanceofintinterfacelongnativenewpackageprivateprotectedpublicreturnstrictfpshortstaticsuperswitchsynchronizedthisthrowthrowstransienttryvoidvolatilewhile2.5 标识符标志符其实就是我们自己取的名字。像前面我们取的类名，变量名其实都是标志符。最好是字母、数字、下划线、$组成不能以数字开头不能是Java的关键字三、数据类型、运算符3.1 数据的表示3.1.1 整数在计算机中的储存原理任何数据在计算机中都是以二进制表示的。所谓二进制其实就是一种数据的表示形式，它的特点是逢2进1。计算机中最小的存储单位是字节（Byte），一个字节占8位（bit），也就是说即使这个数据不足8位也需要用8位来存储。3.1.2 字符在计算机中的储存原理字符并不是直接存储的，而是把每一个字符编为一个整数，存储的是字符对应整数的二进制形式。美国人搞了一套字符和整数的对应关系表，叫做ASCII编码表。ASCII编码表中字符编码的规律：字符0对应48，后面的1,2,3,4...9 对应的十进制整数依次往后顺延字符a对应97，后面的b,c,d,e...z 对应的十进制整数依次往后顺延字符A对应65，后面的B,C,D,E...Z 对应的十进制整数依次往后顺延3.1.3 图片视频声音的存储原理图片的储存从图片开始，如果你把一张图片不断的放大，你会看到有马赛克的效果。你会发现图片中的每一个细节是由一个一个的小方格组成的，每一个小方格中其实就是一种颜色。任何一种颜色可以使用三原色来表示，简称RGB，其中R（红色），G（绿色），B（蓝色），而RGB中每一种颜色又用一个字节的整数来表示，最小值是0最大值是255视频的储存实际上视频和图片是一样的，把多张图片连续播放，在一秒钟内连续播放24张以上，由于人眼存在视觉暂留现象，人眼感受不到画面切换的时间间隔，就认为是连续的视频了。声音的储存声音是以波的形式传播的。我们可以把声波在表示在一个坐标系上，然后在坐标系上取一些点，把这些点的坐标值以二进制的形式存储到计算机中，这就是声音的存储原理。3.1.4 数据的其他表示形式3.1.5 不同进制在Java程序中的书写格式System.out.pirntln('a'+1); //98 System.out.pirntln(0b01100001); //97 System.out.pirntln(0141); //97 System.out.pirntln(0x61); //973.2 数据类型详解Java是一种强类型语言，每个变量都必须声明其数据类型。 Java的数据类型可分为两大类：基本数据类型（primitive data type）和引用数据类型（reference data type）。 基本数据类型：四大类八种引用数据类型：String3.3 数据类型转换3.3.1 自动转换在赋值运算或者算数运算的时候，要求数据类型一致，就要进行类型的转换。类型转换的形式总体分为2种，一种是自动类型转换，一种是强制类型转换。什么是自动类型转换自动类型转换指的是，数据范围小的变量可以直接赋值给数据范围大的变量 byte a = 12; int b = a; //这里就发生了自动类型转换(把byte类型转换int类型)自动类型转换的原理是怎样的自动类型转换其本质就是在较小数据类型数据前面，补了若干个字节//代码示例： public class TypeConversionDemo1 { public static void main(String[] args) { // 目标：理解自动类型转换机制。 byte a = 12; int b = a; // 发生了自动类型转换了 System.out.println(a); System.out.println(b); int c = 100; // 4 double d = c;// 8 发生了自动类型转换了 System.out.println(d); char ch = 'a'; // 'a' 97 => 00000000 01100001 int i = ch; // 发生了自动类型转换了 => 00000000 00000000 00000000 01100001 System.out.println(i); } }表达式的自动类型转换多种数据类型参与运算，其结果以大的数据类型为byte,short,char 三种类型数据在和其他类型数据运算时，都会转换为int类型再运算//代码示例： public class TypeConversionDemo2 { public static void main(String[] args) { // 目标：掌握表达式的自动类型转换机制。 byte a = 10; int b = 20; long c = 30; long rs = a + b + c; System.out.println(rs); double rs2 = a + b + 1.0; System.out.println(rs2); byte i = 10; short j = 30; int rs3 = i + j; System.out.println(rs3); // 面试笔试题： 即使两个byte运算，结果也会提升为int byte b1 = 110; byte b2 = 80; int b3 = b1 + b2; System.out.println(b3); } }3.3.2 强制类型转换强行将范围大的数据，赋值给范围小的变量，这里就需要用到强制类型转换。下面是强制类型转换的格式//格式： 目标数据类型 变量名 = (目标数据类型)被转换的数据;//代码示例： public class TypeConversionDemo3 { public static void main(String[] args) { // 目标：掌握强制类型转换。 int a = 20; byte b = (byte) a; // ALT + ENTER 强制类型转换。 System.out.println(a); System.out.println(b); int i = 1500; byte j = (byte) i; System.out.println(j); double d = 99.5; int m = (int) d; // 强制类型转换 System.out.println(m); // 丢掉小数部分，保留整数部分 } }强制类型转换原理强制类型转换的原理，其实就是强行把前面几个字节砍掉，但是有数据丢失的风险。四、运算符算机是用来处理数据的，处理数据就少不了对数据的计算，想要对数据进行计算就必须用到运算符。运算符就是参与运算的符号。Java提供的运算符有很多种，可以分为算术下面几种算术运算符+，-，*，/，%，++（自增），--（自减）赋值运算符=扩展赋值运算符+=，-=，*=，/=关系运算符>，<，>=，<=，==，!= 逻辑运算符&，|， &&，||，!，^位运算符&，|，^，~ ， >>，<<，>>>条件运算符？：4.1 算数运算符4.2 自增自减运算符4.3 赋值运算符4.4 关系运算符4.5 逻辑运算符4.6 三元运算符4.7 运算优先级4.8 获取用户键盘输入的数据Api文档下载地址（java8）：https://yunyuwu.lanzouy.com/iMaeY1ctqiebScanner就是Java提供给我们用于键盘录入数据的类，为了录入不同类型的数据，还提供了不同的功能，每一个功能会有不同的名称，我们只需要调用Scanner提供的功能就可以完成键盘录入数据。完整代码示例：public class ScannerDemo1 { public static void main(String[] args) { // 1、导包:一般不需要我们自己做，idea工具会自动帮助我们 导包的。 // 2、抄写代码：得到一个键盘扫描器对象（东西） Scanner sc = new Scanner(System.in); // 3、开始 调用sc的功能，来接收用户键盘输入的数据。 System.out.println("请您输入您的年龄："); int age = sc.nextInt(); // 执行到这儿，会开始等待用户输入一个整数，直到用户按了回车键，才会拿到数据。 System.out.println("您的年龄是：" + age); System.out.println("请您输入您的名字："); String name = sc.next(); // 执行到这儿，会开始等待用户输入一个字符串，直到用户按了回车键，才会拿到数据。 System.out.println(name + "欢迎您进入系统~~"); } }五、程序流程控制【1】流程控制的作用：流程控制语句是用来控制程序中各语句执行顺序的语句，可以把语句组合成能完成一定功能的小逻辑模块。【2】控制语句的分类： 控制语句分为三类：顺序、选择和循环。顺序结构”代表“先执行a，再执行b”的逻辑。条件判断结构”代表“如果…，则…”的逻辑。循环结构”代表“如果…，则再继续…”的逻辑。三种流程控制语句就能表示所有的事情！不信，你可以试试拆分你遇到的各种事情。这三种基本逻辑结构是相互支撑的，它们共同构成了算法的基本结构，无论怎样复杂的逻辑结构，都可以通过它们来表达。所以任何一种高级语言都具备上述两种结构。5.1 分支结构5.1.2 if分支
一、函数C语言里可以对语句进行分组，每个语句分组叫做一个函数一旦函数被调用，会执行该函数所表示的语句分组1.1 函数的定义//此段代码为一个函数用于计算a+b的值 int main (int a,int b) { return a + b; }函数调用 - 使用已经定义好的函数被使用的函数称为被调用函数 - printf函数使用被调用函数的函数被称为调用函数 - main函数函数定义的写法：返回值类型 函数名 (输入参数值)//本行为函数头 { //花括号里边的为函数体 做点什么事情吧 return 返回值; }形参与实参：形参与实参相互独立#include<stdio.h> int add (int a,int b)//此处a,b为形式参数、简称：形参 { return a + b; } int main() { int result; result = add(2,3);//此处为实际参数，简称：实参 printf("%d",result); return 0; }1.2 函数调用的本质三步骤：跳转执行返回（从哪儿跳转，到哪儿返回）1.3 为什么要使用函数明确任何C语言程序都是由两部分组成：一堆的变量（包括数组）和一堆的函数前者负责分配内存，后者负责操作访问内存函数的概念：就是一堆语句的组合，一次写好，到处使用！本质目的：减少开发的工作量，提高代码的可维护性1.4 函数的返回值只能从被调用函数向调用函数传递一个数据，这个数据叫做被调用函数的返回值返回值必须记录在被调用函数的储存区里，编写函数的时候要把这个储存区的类型名称卸载函数名称前面被调用函数里使用return关键字指定作为返回值的数值调用函数里要把整个函数调用该语句当作数字使用，这个数字就是被调用函数的返回值1.5 函数的参数可以从调用函数向被调用函数传递多个数据，这些数据的类型可以不同被调用函数需要为每个传递过来的数据提供一个储存区编写函数的时候需要在函数名称后面的小括号里声明一组变量，这些变量就用来表示前面提到的储存区，这些变量叫做形式参数，小括号里的所有内容叫做形式参数列表调用带有参数的函数时需要在函数调用语句的小括号里为每个形式参数提供一个对应的数字，计算机 会把这些数字记录到对应的形式参数里。被调用函数可以通过形式参数得到这些数字。这些数字叫做实际参数只要能当作数字使用的内容，都可以作为实际参数使用。函数调用过程中通常伴随着两个函数之间的数据传递数据传递存在两个完全相反的方向可以从被调用函数向北调用函数传递数据-参数可以从被调用函数向调用函数传递数据-返回值1.6 函数的声明任何函数都可以分为大括号前面的部分和大括号里面的部分函数大括号前面的部分可以单独写成一条语句，这种语句叫做函数声明语句函数声明语句里可以省略形式参数名称把函数声明语句卸载文件开头叫做函数的显式声明除了主函数以外的所有函数都应该进行显式声明格式：extern 返回值类型 函数名(形参列表)函数的定义在函数的调用前面，可以省略函数声明二、递归函数2.1 什么是递归函数C语言里函数可以调用自己，自己调用自己的函数叫递归函数2.2 递归函数编写步骤单独编写语句解决分解后的每个小问题（假设递归函数已经可以使用了）在递归调用语句前编写分支处理不可分解的情况（这种分支必须要能结束函数）三、作用域和生命周期能使用某个变量的所有语句叫做变量的变量的作用域生命周期是一段时间，在生命周期开始的时候计算机给程序分配储存区，在生命周期结束的时候，计算机把分配给程序的储存区收回3.1 局部变量局部变量是定义在函数内的变量作用域：定义的位置开始到函数结束生命周期：函数某一次执行的时间范围3.2 全局变量全局变量是定义在函数外的变量作用域：从定义的位置开始向下的所有语句生命周期：整个程序的执行时间3.3 作用域和生命周期局部变量（静态局部变量）区别：静态局部变量的生命周期是整个程序的执行时间全局变量（静态全局变量）区别：静态全局变量无法被其他文件调用生命周期：定义变量的时候编译器为其分配存储区，函数结束的时候回收其存储区静态变量的生命周期和作用域与普通变量的不一样，静态变量的生命周期是整个程序执行时间声明静态变量的时候需要使用static关键字没有初始化的静态变量会自动被初始化成0函数结束后，静态局部变量的储存区也还是可以使用静态局部变量的作用域仍然只包含函数里面的所有语句静态变量的初始化只在程序开始的时候执行一次，不论初始化语句写在什么地方静态全局变量的生命周期还是整个程序的执行时间，但是它的作用域只包含声明它的文件里的所有语句（不可以跨文件使用静态全局变量）
一、Docker基本概念当我们利用Docker安装应用时，Docker会自动搜索并下载应用镜像（image）。镜像不仅包含应用本身，还包含应用运行所需要的环境、配置、系统函数库。Docker会在运行镜像时创建一个隔离环境，称为容器（container）。镜像仓库，就是专门保存镜像、管理镜像的地方。Docker官方维护了一个公共仓库：Docker Hub，任何注册了的用户都可以上传镜像到Docker Hub，也可以从上面下载镜像。另外，国内也有很多类似的镜像仓库：比如 网易云镜像仓库、阿里云镜像仓库等。1. Docker是做什么的？Docker可以帮助我们下载应用镜像，创建并运行镜像的容器，从而快速部署应用什么是镜像？将应用所需的函数库、依赖、配置等与应用一起打包得到的就是镜像什么是容器?为每个镜像的应用进程创建的隔离运行环境就是容器什么是镜像仓库?存储和管理镜像的服务就是镜像仓库，2. Docker命令docker run -d \ --name mysql \ -p 3306:3306 \ -e TZ=Asia/Shanghai \ -e MYSQL_ROOT_PASSWORD=123 \ mysqldocker run是创建并运行一个容器，-d参数是让容器在后台运行，在关掉终端后也可以运行--name参数是给容器起一个唯一的名字-p参数是设置端口映射，这个选项将容器的3306端口映射到宿主机的3306端口，这样你就可以从宿主机访问到MySQL服务了。-e TZ=Asia/Shanghai \参数是设置环境变量，影响mysql容器的时区设置-e MYSQL_ROOT_PASSWORD=123 \这个选项设置环境变量MYSQL_ROOT_PASSWORD为"123"，这会影响到MySQL的root用户的密码。mysql是要运行的镜像的名字3. Docker镜像命名规范Docker镜像的命名规范主要包括以下几点：使用小写字母和数字：因为Docker镜像名称是大小写敏感的，所以建议使用小写字母和数字来避免混淆。使用短划线(-)或下划线(_)分隔：可以使用短划线或下划线来分隔不同的单词，例如my-image或my_image。以library/project形式命名：镜像名称通常表示其包含的库或项目，因此建议使用library/project的形式来命名镜像，例如ubuntu:18.04或nginx:latest。遵循命名空间规则：如果一个镜像同时包含多个库或项目，可以使用冒号(:)将它们分开，例如redis:6.0.9或node:14.17.0。不要使用特殊字符：尽量避免在镜像名称中使用特殊字符，如空格、斜杠、问号等。这些字符可能会导致镜像名称无法正确解析。使用描述性名称：尽量给镜像起一个描述性的名称，以便于理解它包含的内容。例如，webapp:latest表示一个包含最新版本web应用程序的镜像。二、Docker基础1. 数据卷概念及挂载因为容器与宿主机是隔离的，如果容器删除，容器内的数据会丢失。为了解决这个问题，有了数据卷。在后期宿主机目录发生变更，只要改变数据卷的指向即可。数据卷（volume）是一个虚拟目录，是容器内目录与宿主机目录之间映射的桥梁。它将宿主机目录映射到容器内目录，方便我们操作容器内文件。数据卷创建的默认目录是/var/lib/docker/volumes命令说明docker volume creqate创建数据卷docker volume ls查看所有数据卷docker volume rm删除指定数据卷docker volume inspect查看某个数据卷的详情docker volume prune清除数据卷在执行docker run命令时，使用-v 数据卷:容器内目录 可以完成数据卷挂载在创建容器时，如果挂在了数据卷且数据卷不存在，会自动创建数据卷。2. 本地目录的挂载使用docker run -v命令挂载，具体命令为：docker run -v 本地目录:容器内目录l本地目录必须以“/”或 "./" 开头，如果直接以名称开头，会被识别为数据卷而非本地目录-v mysql : /var/lib/mysql会被识别为一个数据卷叫mysql，运行时会自动创建这个数据卷-v ./mysql : /var/lib/mysql会被识别为当前目录下的mysql目录，如果不存在会自动创建镜像中包含了应用程序所需要的运行环境、函数库、配置、以及应用本身，逐层构建而成。3. 自定义镜像（Dockerfile）镜像就是包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包。构建镜像的过程其实就是把上述文件按照顺序逐层打包。Dockerfile就是一个文本文件，其中包含一个个的指令(Instruction)，用指令来说明要执行什么操作来构建镜像。将来Docker可以根据Dockerfile帮我们构建镜像。常见指令如下：指令说明示例FROM指定基础镜像FROM centos:6ENV设置环境变量，可在后面指令使用ENV key valueCOPY拷贝本地文件到镜像的指定目录COPY ./mysql-5.7.rpm /tmpRUN执行Linux的shell命令，一般是安装过程的命令RUN yum install gccEXPOSE指定容器运行时监听的端口，是给镜像使用者看的EXPOSE 8080ENTRYPOINT镜像中应用的启动命令，容器运行时调用ENTRYPOINT java -jar xx.jar配置示例：# 指定基础镜像 FROM ubuntu:16.04 # 配置环境变量，JDK的安装目录、容器内时区 ENV JAVA_DIR=/usr/local ENV TZ=Asia/Shanghai # 拷贝jdk和java项目的包 COPY ./jdk8.tar.gz $JAVA_DIR/ COPY ./docker-demo.jar /tmp/app.jar # 设定时区 RUN ln -snf /usr/share/zoneinfo/ $TZ /etc/localtime && echo $TZ > /etc/timezone # 安装JDK RUN cd $JAVA_DIR \ && tar -xf ./jdk8.tar.gz \ && mv ./jdk1.8.0_144 ./java8 # 配置环境变量 ENV JAVA_HOME=$JAVA_DIR/java8 ENV PATH=$PATH:$JAVA_HOME/bin # 入口，java项目的启动命令 ENTRYPOINT ["java", "-jar", "/app.jar"]往往不需要这么复杂，我们可以直接基于JDK为基础镜像省略前面的步骤：# 基础镜像 FROM openjdk:11.0-jre-buster # 设定时区 ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 拷贝jar包 COPY docker-demo.jar /app.jar # 入口 ENTRYPOINT ["java", "-jar", "/app.jar"]构建镜像在编写好Dockerfile后，可以使用以下命令来构建镜像：# docker build -t 镜像名 Dockerfile目录 docker build -t myImage:1.0 .-t：时给镜像起名，格式依然是repository:tag的格式，不指定tag时，默认为latest.：是指定Dockerfile所在目录，如果就在当前目录，则指定为："."实操如下：docker load -i xxx.jar # 导入镜像 docker build -t demo: . # 使用当前目录的 Dockerfile 创建镜像，标签为 demo docker run -d --name demo -p 8080:8080 # 启动容器在后台运行，容器名为demo，端口映射为80804. 网络默认情况下，所有的容器都是以bridge方式连接到Docker的一个虚拟网桥上：在安装docker之后，会生成一个虚拟网卡，生成一个虚拟网桥虚拟网卡的名字叫做：docker0，ip为：172.16.0.2/16前两个网段不能改docker是允许我们自定义网络的，加入自定义网络的容器才可以通过容器名互相访问，Docker的网络操作命令如下：命令说明docker network create创建一个网络docker network ls查看所有网络docker network rm删除指定网络docker network prune清除未使用的网络docker network connect使指定容器链接加入某网络docker network disconnect使指定容器连接离开某网络docker network inspect查看网络详细信息# 示例： docker network create xiaobei docker network ls docker network rm demo docker network prune docker network connect xiaobei demo docker network disconnect docker network inspect xiaobei三、Docker Compose1. 基本概念Docker Compose通过一个单独的docker-compose.yml 模板文件（YAML 格式）来定义一组相关联的应用容器，帮助我们实现多个相互关联的Docker容器的快速部署。一个容器就是一个服务2. 文件结构version: "3.8" # 版本 services: mysql: image: mysql # 镜像名：mysql container_name: mysql # 容器名：mysql ports: - "3306:3306" # 端口号：3306:3306 environment: # 环境变量 TZ: Asia/Shanghai MYSQL_ROOT_PASSWORD: 123 volumes: # 数据卷挂载 - "./mysql/conf:/etc/mysql/conf.d" - "./mysql/data:/var/lib/mysql" - "./mysql/init:/docker-entrypoint-initdb.d" networks: # 网络 - new hmall: # 构建新镜像 build: context: . # 指定当前目录 dockerfile: Dockerfile # 文件名为Dockerfile container_name: hmall # 容器名：hmall ports: - "8080:8080" # 端口 networks: - new # 网络 depends_on: # 依赖于谁，该应用依赖于mysql - mysql nginx: image: nginx # 试着自己想想吧，我累了Ovo container_name: nginx ports: - "18080:18080" - "18081:18081" volumes: - "./nginx/nginx.conf:/etc/nginx/nginx.conf" - "./nginx/html:/etc/nginx/html" depends_on: - hmall networks: - new networks: new: name: hmall
一、什么是电流1.1 原子一切都是原子构成，一个简单的原子模型可以简化成带正电荷的原子核在中央，周围环绕有若干个带负电的电子。同性相斥，异性相吸。1.2 原子与电荷原子核带正电，吸引带负电的电子，电子带负电之间又互相排斥。绝大多数固体材料，他们的原子核和电子靠的近是稳定的。但是在金属固体里面，比如铜，电子离原子核远，是可以自由移动的。原子核原地不动，保持着材料的结构稳定，但是电子可能会在原子之间跳动。1.3 电流的产生如果一个电子不老实进行移动，那么附近的电子就会像多米诺骨牌一样不断移动。他们之间不断推着挤，就产生了电流。1.4 电流的单位 安培1000ma=1A1.5 电路与电池电路就是电流导通的道路，电池是一种特殊的通过化学反应产生能量的装置，电池正极吸收电子，电池负极发送电子。1.6 电流方向传统电学：电流从正极流向负极真实世界：电流从负极流向正极1.7 交流电(AC)与直流电(DC)AC(交流电)交流电的电流方向随时间变化电荷会在正、负两个方向上流动，周期性的交替反向交流电通常是通过电网供应的电力用于各种大型较大功耗的电气设备和机械设备如电视、电冰箱、微波炉DC(直流电)直流电是指电流方向不变的电流电荷始终在同一个方向上流动直流电源通常由电池或者其他直流电源供应直流电常用于需要稳定电压和恒定方向的小型设备中如手机、电动车直流交流电的对比1.8 开路与闭路开路与闭路的区别在于电路中开关的状态是否闭合，这直接影响了电路中的电流是否能够流通，从而影响电路中的电气设备是否能够正常工作。开路当电路中的开关处于断开状态，电路就处于开路状态。在这种状态下，电流无法流通，电路中的电气设备也无法工作。闭路当电路中的开u按处于闭合状态，电路就处于闭路状态。在这种状态下，电流可以在电路中流通，电器设备也可以正常工作。二、什么是电压2.1 电压电压就是电势能什么是势能？势能是物理学描述的能量类型，说明物体具备的能量。电压，电势能是指在电子在电路中的动能。单位通常为伏特(V)。电压是电力系统中的一种重要概念，它决定着电流流动的强度。电压越高，电子移动的越快，电流就会越大；而电压越低，电流就会越小。三、电阻和欧姆定律电压产生电势差，推动电流的流动3.1 电阻电压产生电势差，推动电流的流动电阻是电子学中的基本概念，它是指电流经过导体时阻碍电流流动的程度、电阻的单位是欧姆。电压、电阻和电流之间的关系3.2 欧姆定律欧姆定律是电学中的基本定律之一他描述了电流和电压之间的关系。欧姆定律的公式为I=U/R，其中I是电流，U是电压。R是电阻。这个公式表面，在电阻不变的情况下，电压和电流成正比欧姆定律的重要参数I 电流单位 安 AU 电压单位 伏 VR 电阻单位 欧姆 R3.3 欧姆定律的计算串联电路并联电路串并联电路的计算四、常见元器件4.1 电阻器作用就是阻碍电流的流动电阻器的分类电阻器的作用电阻器是一种电子元器件，它可以提供一定的电阻，限制电流的流动。电阻器是由导体材料制成的，通过将导体材料绕制成螺旋状或折叠装，并将两端引出，形成一个固定电阻值的器件。4.1.1 电阻的分类基于功能和制作工艺划分。普通电阻：普通电阻是一种最基本的电阻器，通常由一根或多根绕在绝缘体上的金属丝或碳膜组成，可以提供固定的电阻值，适用于各种电路中。薄膜电阻：薄膜电阻是一种由金属或合金薄膜制成的电阻器，可以提供高精度和稳定性的电阻值，常用于精密仪器、测量仪器等高要求的场合。光敏电阻：光敏电阻是一种电阻值受光照强度影响的电阻器，常用于光敏电路和光控系统中。金属薄膜电阻：金属薄膜电阻器是一种由金属薄膜制成的电阻器，具有较高的精度和稳定性，适用于高精度电路中。电位器：电位器是一种可调电阻器，通常由一个旋转或滑动的电阻器件和一个旋钮或滑动器组成，可以提供可调的电阻值，常用于电路的调节和控制。旋钮可调电阻：旋钮可调电阻是一种可调电阻器，与电位器类似，但是旋钮可调电阻通常是用旋钮来改变电阻值，通常用于电子设备的调节和控制。热敏电阻：热敏电阻是一种电阻值随温度变化而变化的电阻器，通常用于温度测量和控制系统中。压敏电阻：压敏电阻是一种电阻值随压力变化而变化的电阻器，通常用于压力传感器和压力测量等应用场合。高精度电阻：高精度电阻是一种精度较高的电阻器，通常具有稳定的电阻值和温度系数，适用于高精度仪器和精密测量仪器等场合。4.1.2 电阻的数据手册电阻我们主要关心：封装、标称、额定功率封装：看电阻是什么样的，直插还是贴片的，大小是多大标称：看电阻表的电阻阻值是多少，精确度是多少，精度越高越贵额定功率：额定功率计算公式为：P=I*I*R=I*U，额定功率其实决定了耐压值。电阻能通过的最大电流是固定的，额定功率越高，耐压值就越高，超过了电阻的耐压值会导致电阻烧毁。4.2 电容器电容就是装电的容器，主要防止电压的突变电容器是一种电子元件，用于储存电荷和能量。它由两个导体板和介质层组成，介质层位于两个导体板之间。当电容器接入电路时，负电荷被储存在导体板上，并在两板之间产生电场。电容器的单位是法拉（F），一个法拉等于存储一库仑电荷所需的电势差为一伏特的电容器。常见的电容器有电解电容器、陶瓷电容器、聚酯薄膜电容器、铝电解电容器等。不同的材料介质，容纳电荷的能力不一样。电容的充放电是基于静电力的，不涉及化学反应变化，比锂电池更安全一些。4.2.1 电容的分类4.2.2 电容的单位不同的材料介质，容纳电荷的能力不一样。电容单位是法拉F注意：法拉是个非常大非常大的单位哦，其他单位为mf，uf，nf，pf1F（法拉）＝1000mF（毫法）1mF（毫法）＝1000μF（微法）1μF（微法）＝1000nF（纳法）1nF（纳法）＝1000pF（皮法）电容器的作用：阻止电压的突变，储能，滤波（大电容滤低频，小电容滤高频）。生活中的电容：充电器的电源灯并不是立刻断开，里面有电容，电荷慢慢释放掉。4.2.3 电容的分类基于功能和制作工艺划分玻璃电容：使用玻璃作为介质的电容器，具有高温稳定性和低损耗等特点，常用于高频和高温环境下的电路中。钽电容：使用钽金属作为电极的电容器，具有小尺寸、大电容量和高频特性等优点，常用于微型电路中。薄膜电容：使用金属膜或金属箔作为电极的电容器，具有高精度、稳定性好等特点，常用于高性能电子器件中。铝电解电容：使用铝箔和电解液作为电极的电容器，具有大电容量、低成本等特点，常用于低频和直流电路中。云母电容：使用云母作为介质的电容器，具有高精度、高频特性等特点，常用于精密仪器和高频电路中。空气电容：使用空气作为介质的电容器，具有高精度、稳定性好等特点，但体积较大，常用于高频和高压电路中。陶瓷电容：使用陶瓷作为介质的电容器，具有小尺寸、高频特性和高温稳定性等优点，常用于电子设备中。可调电容：具有可变电容值的电容器，常用于无线电和调谐电路中。金属纸电容：使用金属化薄膜作为电极的电容器，具有高精度、稳定性好等特点，常用于高性能电子器件中。超级电容：也称为电化学电容器，具有高能量密度、高功率密度和长寿命等特点，常用于储能系统和电动汽车中。4.2.4 注意事项有些电容有极性，正负极接反会爆炸铝电解电容是一种极性电容，由于其特殊的结构和工作原理，如果接反了极性，可能会导致电容器失效或者损坏，甚至可能导致电容器短路或者起火等危险情况。铝电解电容的结构是由一层氧化铝薄膜和一层电解液构成的。当正极连接正电压，负极连接负电压时，电解液中的氢离子会向氧化铝膜的负极移动，而负离子则向电解液的正极移动，形成一个稳定的电场，从而形成电容效应。如果电容器反接了极性，电解液中的氢离子会向氧化铝膜的正极移动，形成氢气，铝电解电容会爆浆。电容爆浆后压力较大，电解电容的外壳也是无规律的变形，有可能产生手榴弹爆炸后的效果，容易造成其他元器件的损坏。4.3 电感器4.3.1 电和磁的关系电和磁可以互相转换。电机中的电流流过线圈，从而产生磁场，这个磁场将旋转部件（例如电动机轴）带动起来，这就是电磁感应原理的应用。发电机和电机相反，通过旋转磁场，发电机可以转换机械能为电能。4.3.2 什么是电感器主要防止电流的突变电感器是一种电子元件，用于在电路中储存和释放能量。他由一个线圈组成，通常由铜线绕成，通常带有一个铁芯。当电流通过电感器时，它会在线圈中产生一个磁场，从而储存能量。当电流停止流动时，磁场会崩溃，导致电感器逐渐释放储存的能量。电感器的主要作用是在电路中调节电流的变化率。它可以用来过滤电路中的高频噪声，电感器两端的电流不会突变，保护其他电子元件不受到电磁干扰的影响。电感器的核心要点通过磁场储存能量组织电流的突变4.3.3 电感和电阻理想的电感没有能量损耗电感：电磁感应元器件，电会产生磁场，磁场又会抵制电流的变化。理想的电感没有能量损耗。跟电阻不同，电阻阻碍电流，发热。电感使用漆包线，纱包线等外部绝缘导线缠绕到铁芯上电感的单位是亨利（Henry）表示为H，它的中文读法是“恒利”，以英国物理学家亨利的名字命名。电感的基本单位是：H（亨），它和电容一样，也是一个很大的计量单位，另外还有毫亨mh、微亨uh、纳亨nh电感的作用；电感可以作为电路稳定器的一部分，通过抵抗电路中电流的变化，保持电路的稳定性和可靠性。
开篇今天怀着把游戏彻底戒掉的心，给windows甩一边去了，重装了deepin系统。作为入门级Linux，上手简单，适合小白，一来是deepin在Linux中我个人感觉还是比较美观的，二来想熟悉Linux的话，拿deepin练手比较好吧，毕竟有着软件商店的加持，中文社区也活跃，社区资源丰富。感觉对新手入门嘎嘎舒适。三来，就当支持国产崛起了，毕竟deepin也是国产的。起因在将系统装完，安装完该有的软件之后，闲下来的我想去外边的世界看看突然想起来好像我还没有一个合适的梯子。我记得我在香港还是有一个小水管服务器的，于是决定拿来搭梯子。在某论坛找了一个一键脚本，我放到下边。服务端搭建选择海外的服务器，将下方代码复制，粘贴输入到ssh终端后回车。便会出现安装菜单，根据自己的情况输入对应数字，选择合适的安装即可。bash <(curl -sL https://storage.googleapis.com/tiziblog/setup.sh)VMESS，即最普通的V2ray服务器，没有伪装，也不是VLESSVMESS+KCP，传输协议使用mKCP，VPS线路不好时可能有奇效VMESS+TCP+TLS，带伪装的V2ray，不能过CDN中转VMESS+WS+TLS，即最通用的V2ray伪装方式，能过CDN中转，推荐使用VLESS+KCP，传输协议使用mKCPVLESS+TCP+TLS，通用的VLESS版本，不能过CDN中转，但比VMESS+TCP+TLS方式性能更好VLESS+WS+TLS，基于websocket的V2ray伪装VLESS版本，能过CDN中转，有过CDN情况下推荐使用VLESS+TCP+XTLS，目前最强悍的VLESS+XTLS组合，强力推荐使用（但是支持的客户端少一些）trojan，轻量级的伪装协议trojan+XTLS，trojan加强版，使用XTLS技术来提升性能注意：目前一些客户端不支持VLESS协议，或者不支持XTLS，请按照自己的情况选择组合有几个选项会要求输入伪装域名，如果你的服务器上已经部署了网页，有可能会使网页出错对于VLESS协议、VMESS+WS+TLS的组合，网页上输入伪装域名，能正常打开伪装站，说明服务端已经正确配置好。客户端选择Linux端1.安装 V2Ray 内核：# download script curl -Ls https://mirrors.v2raya.org/go.sh | sudo bash # 关闭systemd服务 sudo systemctl disable v2ray --now # install v2ray-core from jsdelivr sudo bash go.sh2.安装 v2rayA方法一：通过软件源安装添加公钥wget -qO - https://apt.v2raya.org/key/public-key.asc | sudo tee /etc/apt/trusted.gpg.d/v2raya.asc添加 V2RayA 软件源echo "deb https://apt.v2raya.org/ v2raya main" | sudo tee /etc/apt/sources.list.d/v2raya.list sudo apt update安装 V2RayAsudo apt install v2raya方法二：手动安装 deb 包下载合适的deb包https://github.com/v2rayA/v2rayA/releaseshttps://yunyuwu.lanzouv.com/iH2lo01z81cd如果从蓝奏云下载，记得先解压。然后可以使用Gdebi、QApt等图形化工具来安装，也可以使用命令行：sudo apt install /path/download/installer_debian_xxx_vxxx.deb ### 自行替换 deb 包所在的实际路径3.启动1.启动v2rayA及设置v2rayA自动启动从 1.5 版开始将不再默认为用户启动v2rayA及设置开机自动。启动v2rayAsudo systemctl start v2raya.service设置开机自动启动sudo systemctl enable v2raya.service2.开始设置通过2017端口 如http://localhost:2017 访问UI界面。如果不能正常访问，请查阅官方相关文档排除。3.创建账号在第一次进入页面时，你需要创建一个管理员账号，请妥善 保管 牢记 你的用户名密码，如果遗忘，使用sudo v2raya --reset-password命令重置。4.导入节点我们从服务器那里查看配置或者导入节点。以创建或导入的方式导入节点，导入支持节点链接、订阅链接、扫描二维码和批量导入等方式。5.连接节点和启动服务导入成功后，节点将显示在SERVER或新的标签中。如图是我自己创建了一个节点的界面。切换到该标签页，选择一个或多个节点连接。这里不建议选择过多的节点，6个以内为佳。如图所示，在未启动服务时，连接的节点呈现粉红色。我们在左上角点击相应按钮启动服务。在启动服务后，所连接的节点呈现蓝色，左上角的图标也显示为蓝色的正在运行，代表服务启动成功代理设置：配置代理由于默认情况下 v2rayA 会通过核心开放 20170(socks5), 20171(http), 20172(带分流规则的http) 端口。修改端口可参阅后端地址和入站端口设置 一节。如果是需要为局域网中的其他机器提供代理，请在设置中打开“局域网共享”，并检查防火墙开放情况。这里记录三种方式使用代理。1.透明代理这种方法是 v2rayA 推荐的方法。它相比于其他方法具有诸多优势，v2rayA 可以一键开启透明代理，为几乎所有程序提供代理服务。在设置中选择透明代理的分流方式，以及实现方式，然后保存即可。具体细节可参阅透明代理一节。注意，如需选择 GFWList，需要下载对应的规则库，请点击右上角的更新以完成下载。2.系统代理系统代理可为主动支持代理的程序提供代理服务。在不同的桌面环境中设置的位置不尽相同，请通过搜索引擎自行搜索。3.浏览器代理SwitchyOmega 等浏览器插件可为浏览器提供代理服务。在所使用的浏览器上安装插件[button color="danger" url="https://chrome.google.com/webstore/detail/proxy-switchyomega/padekgcemlokbadohgkifijomclgjgif?hl=zh" outline="" target="_blank"]插件链接[/button]在v2rayA右上角的设置中查看端口信息请按照下图进行配置4.linux客户端代理export https_proxy=https://127.0.0.1:20171Windows端可以使用v2rayN-Core [button color="danger" url="https://yunyuwu.lanzouv.com/ibEMS01zcd8f" outline="" target="_blank"]蓝奏云链接[/button]下载压缩包后解压缩，然后点击启动即可进行导入及配置，比较简单，博主就不细说了。安卓端1.Trojan支持协议：Vmess（v2ray（v2）），Shadowsocks(ss)，socks5，VLESS，Trojan[button color="info" url="https://github.com/trojan-gfw/igniter" outline="" target="_blank"]GitHub项目地址[/button] [button color="warning" url="https://yunyuwu.lanzouv.com/iER3101zerjc" outline="" target="_blank"]蓝奏云链接[/button]2.v2rayNG[button color="danger" url="https://github.com/2dust/v2rayNG" outline="" target="_blank"]GitHub项目地址[/button] [button color="info" url="https://yunyuwu.lanzouh.com/iVf1c061kyeb" outline="" target="_blank"]蓝奏云链接[/button]iOS系统使用俗称 小火箭 Shadowrocket的软件，可以使用国外苹果id登录AppStore下载，不过需要付费。结尾到此，关于访问wai网的各大客户端配置教程就结束了，不知道能不能把游戏戒掉，反正探索了新知识，也没白忙活。如果有哪里不对，欢迎各位大神指出错误，感谢！本笔记仅用于学习交流，请遵守国内法律制度。
如何对自己的服务器进行压力测试
项目的开展我们对项目进行部署之后，假设这个项目每天会有百万次的访问。我们的项目能不能做到稳定提供服务呢？所以我们需要进行一些测试。如何进行测试一、首先是付费的世界上没有钱解决不了的问题，如果有 那一定是钱的金额不够。1.阿里云提供的阿里云性能测试 PTS阿里云的性能测试PTS无需安装软件；脚本场景监控简单化，省时、省力；分布式并发压测，施压能力无上限；快速大规模集群扩容、支持几十万用户及百万级TPS性能压测；可模拟海量用户的真实业务场景，全方位验证业务站点的性能、容量和稳定性。性能测试PTS（Performance Testing Service）是一款性能测试工具。支持按需发起压测任务，可提供百万并发、千万TPS流量发起能力，100%兼容JMeter。提供的场景编排、API调试、流量定制、流量录制等功能，可快速创建业务压测脚本，精准模拟不同量级用户访问业务系统，帮助业务快速提升系统性能和稳定性。PTS 广泛应用于各种压力测试和性能测试场景，包括但不限于以下场景：详情请观看使用文档如何在一分钟内发起压测？2.腾讯云提供的测压大师LMWeTest 压测大师（Load Master，LM）是简单易用的自动化性能测试平台，为用户提供测试框架及压测环境、创建虚拟机器人模拟产品多用户并发场景，支持 HTTP 或 HTTPS 协议，包括 Web/H5 网站、移动应用、API 、游戏等主流压测场景，适用于产品发布前及运营中的服务器压力测试及性能优化。使用详情请观看使用文档如何在一分钟内发起压力测试二、不花钱的说完了付费的，再说说不花钱的。1.http_loadhttp_load是一款基于Linux平台的web服务器性能测试工具，用于测试web服务器的吞吐量与负载，web页面的性能。它又轻巧又简便，整个安装包就100K左右。它可以快速用来对网站或者Web API进行压力测试。而且功能还挺强大的，特别是在架构验证过程中，测试某个平台的并发和响应时间相当的管用。下载地址：https://yunyuwu.lanzouv.com/ih4Kc01wfvkfhttps://pan.baidu.com/s/105917KnmkhKJuuBNQ1paRA?pwd=ngid安装：上传服务器后#tar xfz http_load-09Mar2016.tar.gz #cd http_load-09Mar2016 #make && sudo make install因为包很小，所以会瞬间安装完成，直接打http_load命令验证下是否安装成功，你应该可以看到下面的信息：usage: http_load [-checksum] [-throttle] [-proxy host:port] [-verbose] [-timeout secs] [-sip sip_file] -parallel N | -rate N [-jitter] -fetches N | -seconds N url_file One start specifier, either -parallel or -rate, is required. One end specifier, either -fetches or -seconds, is required.基本用法：使用http_load的主要方式就是用命令http_load <参数> <url列表文件>。其中url列表文件就是一个文本文件，每行放一条你要测试的URL地址（默认只支持HTTP），http_load在运行时会从中随机抽取地址访问。当然你也可以只放一条，那就是针对特定地址做压测。http_load的参数主要有：-parallel 简写 -p: 同一时间发起的并发连接数-rate 简写 -r: 每秒开启的并发连接数-parallel或-rate必须且只能有一个-fetches 简写 -f ：总计的访问次数-seconds 简写 -s ：总计的访问时间-fetches或-seconds必须且只能有一个-proxy host:port: 指定需经过的代理地址和端口timeout secs: 连接闲置后多久超时，默认60秒-verbose: 控制台输出详细信息注意网上有些文章说-p是并发进程数，千万别被带坑里了。http_load就一个进程，它只是模拟并发连接，不是真起了一大堆客户端进程。每个连接的调用都是非阻塞式的，因此确保了并发量。首先我们编辑一个urls.txt文件格式是每行一个URL。文件中可以有这种格式http://www.baidu.com/亦或是192.168.0.1这一类的都可以测。文件格式如下：https://yunyuwu.cn/adiod https://yunyuwu.cn/3ryn89 https://yunyuwu.cn/489y3y89 http://35.132.432.254#示例： ./http_load -p 并发访问进程数 -s 访问时间 需要访问的URL文件 命令行： $ http_load -p 50 -s 10 urls.txt然后得到了结果：1239 fetches, 50 max parallel, 7.31784e+06 bytes, in 10.0001 seconds 47211.8 mean bytes/connection 15.5 fetches/sec, 731783 bytes/sec msecs/connect: 195.597 mean, 218.047 max, 189.311 min msecs/first-response: 195.951 mean, 271.889 max, 189.239 min 38 bad byte counts HTTP response codes: code 200 -- 155运行结果简述：1.共访问了1239次，50个最大并发，获取了7.31784亿字节的数据，用时10.0001秒2.每次访问平均获取47211.8字节3.每秒15.5次访问，每秒731783字节数据4.平均每次访问195.597毫秒，最大218.047毫秒，最小189.311毫秒5.首次响应平均195.951毫秒，最大271.889毫秒，最小189.239毫秒6.有38次字节计数错误7.HTTP响应代码，155次200，说明有155次访问成功，注意事项如果提示make:cc 命令未找到请执行以下命令。$ yum -y install gcc automake autoconf libtool make $ yum install gcc gcc-c++如果报错：无法创建一般文件‘/usr/local/man/man1’: 没有那个文件或目录可先mkdir /usr/local/man再次make install2.webbenchweb压力测试工具webbench概述webbench最多可以模拟3万个并发连接去测试网站的负载能力并发能力比较高，可以测试https及动态静态页面适合中小型网站测试承受能力。webbench的标准测试可以向我们展示服务器的两项内容：每秒钟相应请求数和每秒钟传输数据量。webbench不但能具有便准静态页面的测试能力，还能对动态页面（ASP,PHP,JAVA,CGI）进行测试的能力。他支持对含有SSL的安全网站例如电子商务网站进行静态或动态的性能测试。安装：下载地址：https://yunyuwu.lanzouv.com/iaCxQ01wlt6fhttps://pan.baidu.com/s/1HmorM8V4TuH5MLQm2UEniw?pwd=97wj# yum install -y gcc ctags #先安装编译需要的组件 # wget http://www.ha97.com/code/webbench-1.5.tar.gz # tar zxvf webbench-1.5.tar.gz # cd webbench-1.5 # make && make install使用webbench -c 1000 -t 30 http://127.0.0.1/test.jpg参数说明：-c表示并发数，-t表示时间(秒)测试结果Webbench - Simple Web Benchmark 1.5 Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software. Benchmarking: GET http://hz.xiaobei.ga/ 3000 clients, running 30 sec. Speed=7946 pages/min, 16725 bytes/sec. Requests: 2241 susceed, 1732 failed.本人测试感觉并没有上一个脚本那么好使。3.SiegeSiege是一个压力测试和评测工具，设计用于WEB开发这评估应用在压力下的承受能力：可以根据配置对一个WEB站点进行多用户的并发访问，记录每个用户所有请求过程的相应时间，并在一定数量的并发访问下重复进行。Siege是一个多线程http负载测试和基准测试工具。Siege：这是Linux系统下的一个测试工具，完全使用C语言实现，可以对HTTP和FTP服务器进行负载和性能测试。通过使用Siege 提供的功能，可以很容易的制定测试计划：包括规定使用并发用户数、重复数量，从而可以模拟在服务器、网络或者其它对象上附加负载以测试他们提供服务的受压能力，方便的测试服务器的性能。最后，利用Siege提供的测试结果来分析性能指标或者分析他们提供的服务在不同负载条件下的性能情况，分析测试结果，找出影响系统性能的瓶颈。下载地址：https://yunyuwu.lanzouv.com/ioqUC01wr4gbhttps://pan.baidu.com/s/1J7uutOI6JNm93it97HrsPQ?pwd=a6wf安装：# wget http://download.joedog.org/siege/siege-4.1.2.tar.gz # tar xzvf siege-4.1.2.tar.gz # cd siege-4.1.2 # ./configure # make && make install提示：如果服务器没有安装编译工具，请先安装：sudo apt-get install build-essential然后运行siege -v出现下方代码即表示成功。New configuration template added to /root/.siege Run siege -C to view the current settings in that file SIEGE 4.1.2sigh常见参数-h帮助-c 指定并发数（是真并发）-r 指定重复次数-d 指定请求的延迟时间，注意每个请求间的随机延迟（模拟用户的思考时间，最多延迟一分钟，其他都是随机默认在一分钟之内）-f 指定url列表，可以一次给多个地址加压（多用于翻页的Url测试）-t 指定用例执行时间，比如，-t 10s，-t 1M(H)之类（主要用于稳定性性测试，长时间进行加压，最容易发现内存泄露的问题）-g 获取请求的headers信息并打印出来，debug专用-H指定请求的headers信息-l或者–log=[File]指定测试结果的路径使用方法：示例：siege -c 50 -r 100 -u http://192.168.91.100注意事项：siege默认只支持255个并发数，可以自己自定义，修改~/.siege/siege.conf下的limit数值。在用户目录下的 .bash_profile 中的末尾加入ulimit -n 2000, 保存后再执行source ～/.bash_profile `即可4.黄金眼ddos此脚本非常简单暴力wget http://pan.gov.duy.la/data/hjy.py脚本设置默认50并发 持续30秒 时间有点短 可以自己去改改脚本 相信大家都能看懂根据自己服务器稍调一下，然后给予hjy.py脚本权限chmod +x hjy.py命令示例如下：./hjy.py http://baidu.com ./hjy.py http://baidu.com -s 300 -w 300参数解释：-u，--useragents要使用的带有用户代理的文件（默认值：随机生成）-w，--workers并发工作者数（默认值：50）-s，--sockets并发套接字数（默认值：30）-m，--method使用'get'或'post'或'random'的HTTP方法（默认：get）-d，-debug启用调试模式[更多详细输出]（默认值：False）5.cc以上就是博主自己整理的关于服务器测压的脚本了，有不足或不对的地方欢迎评论区留言！
起因今天一觉睡醒，犹如执行任务一样打开了我的电脑，打算继续学习C语言。结果在打开浏览器之后，发现居然提示我找不到dns服务器地址。但是可以通过ip打开服务器的宝塔面板，这就让我一脸懵。经过[card title="第一次尝试" color="success"]然后我试图使用之前安装的火绒安全里的网络修复小组件进行修复，以往都是可以修复的。但是今天居然不能修复，在重试了几次后，依然不行。于是我试图通过重装网卡进行修复。[/card][card title="第二次尝试" color="warning"]这次我决定使用重装网卡的方式修复，但是依然没有用。[/card][card title="第三次尝试" color="danger"]在自己无计可施了的情况下，我决定求助广大网友。于是，我使用手机打开了《百度》。经过查找，发现是当前dns服务器地址有问题，或者不可用。[/card]问题的解决[card title="解决方法" color="info"]找到了问题，那么怎么解决呢。要用到dns解析服务器地址，我四处查找找到了几个免费公共的DNS解析服务器。[/card]服务商dns1dns2阿里223.5.5.5223.6.6.6百度180.76.76.762400:da00::6666(ipv6)OpenDNS208.67.222.222208.67.220.220Google208.67.222.222208.67.220.220114 DNS114.114.114.114114.114.115.115Cloudflare1.1.1.11.0.0.1DNSPod119.29.29.29182.254.116.116PS:如果配置了不合理的DNS服务器，可能会导致网速的缓慢、打不开网站等情况。一些恶意的DNS还会让你的电脑弹出恶意广告等安全问题。在网卡设置页，右击点属性，然后双击internet协议版本4(TCP/IPv4)，然后点击使用下面的DNS服务器地址，在下边的两个输入框中输入dns地址`，最后点击确定。这个时候就可以打开浏览器访问网页正常上网了。
css基础第二弹一、emmet语法1、简介Emmet语法的前身是Zen coding,它使用缩写,来提高html/css的编写速度, Vscode内部已经集成该语法。快速生成HTML结构语法快速生成CSS样式语法2、快速生成HTML结构语法生成标签 直接输入标签名 按tab键即可 比如div然后tab键，就可以生成 如果想要生成多个相同标签 加上*就可以了 比如div*3就可以快速生成3个div如果有父子级关系的标签，可以用>比如ul>li就可以了如果有兄弟关系的标签，用+就可以了 比如div+p如果生成带有类名或者id名字的，直接写.demo或者#two tab键就可以了如果生成的div 类名是有顺序的，可以用自增符号$如果想要在生成的标签内部写内容可以用{ }表示3、快速生成CSS样式语法CSS 基本采取简写形式即可比如w200按tab可以生成width: 200px;比如lh26px按tab可以生成line-height: 26px;4、快速格式化代码Vscode快速格式化代码:shift+alt+f也可以设置 当我们 保存页面的时候自动格式化代码:1）文件 ------.>【首选项】---------->【设置】；2）搜索emmet.include;3）在settings.json下的【工作区设置】中添加以下语句："editor.formatOnType": true, "editor.formatOnSave": true二、css的复合选择器1、什么是复合选择器？在 CSS 中，可以根据选择器的类型把选择器分为基础选择器和复合选择器，复合选择器是建立在基础选择器之上，对基本选择器进行组合形成的。复合选择器是由两个或多个基础选择器，通过不同的方式组合而成的，可以更准确、更高效的选择目标元素（标签）常用的复合选择器包括：后代选择器、子选择器、并集选择器、伪类选择器等等2、后代选择器 (重要）定义：后代选择器又称为包含选择器，可以选择父元素里面子元素。其写法就是把外层标签写在前面，内层标签写在后面，中间用空格分隔。当标签发生嵌套时，内层标签就成为外层标签的后代。语法：语法说明：元素1 和 元素2 中间用空格隔开元素1 是父级，元素2 是子级，最终选择的是元素2元素2 可以是儿子，也可以是孙子等，只要是元素1 的后代即可元素1 和 元素2 可以是任意基础选择器例子： 百度 百度 上述语法表示选择ul中li中里面的所有a标签(后代元素)。3、子选择器 (重要）定义：子元素选择器（子选择器）只能选择作为某元素的最近一级子元素。（简单理解就是选亲儿子元素）语法：上述语法表示选择元素1 里面的所有直接后代(子元素) 元素2。语法说明：元素1 和 元素2 中间用 大于号 隔开元素1 是父级，元素2 是子级，最终选择的是元素2元素2 必须是亲儿子，其孙子、重孙之类都不归他管. 你也可以叫他 亲儿子选择器例子： 大肘子 猪头 猪尾巴 4、并集选择器 (重要）定义：并集选择器可以选择多组标签, 同时为他们定义相同的样式，通常用于集体声明。并集选择器是各选择器通过英文逗号（,）连接而成，任何形式的选择器都可以作为并集选择器的一部分。语法：上述语法表示选择元素1 和 元素2。语法说明：元素1 和 元素2 中间用逗号隔开逗号可以理解为和的意思并集选择器通常用于集体声明并集选择器中的最后一个选择器不需要加逗号例子：5、伪类选择器定义：伪类选择器用于向某些选择器添加特殊的效果，比如给链接添加特殊效果，或选择第1个，第n个元素。语法：伪类选择器书写最大的特点是用冒号（:）表示，比如 :hover、:first-child。6、链接伪类选择器定义：伪类选择器用于向某些选择器添加特殊的效果，比如给链接添加特殊效果，或选择第1个，第n个元素。语法：伪类选择器书写最大的特点是用冒号（:）表示，比如 :hover 、 :first-child 。伪类选择器属性a:link没有点击过的(访问过的)链接a:visited点击过的(访问过的)链接a:hover鼠标经过的那个链接a:active鼠标正在按下还没有弹起鼠标的那个链接链接伪类选择器注意事项为了确保生效，请按照 LVHA 的循顺序声明 :link－:visited－:hover－:active记忆法：love hate 或者 lv 包包 hao因为a链接在浏览器中具有默认样式，所以我们实际工作中都需要给链接单独指定样式。链接伪类选择器实际工作开发中的写法：7、:focus伪类选择器定义：:focus伪类选择器用于选取获得焦点的表单元素。焦点就是光标，一般情况 类表单元素才能获取例子：复合选择器总结三、css的显示模式1、什么是元素的显示模式定义：元素显示模式就是元素（标签）以什么方式进行显示，比如自己占一行，比如一行可以放多个。作用：网页的标签非常多，在不同地方会用到不同类型的标签，了解他们的特点可以更好的布局我们的网页。2、元素显示模式的分类2.1、块元素常见的块元素： ~ 、 、 、 、 、 标签是最典型的块元素。块级元素的特点：比较霸道，自己独占一行。高度，宽度、外边距以及内边距都可以控制。宽度默认是容器（父级宽度）的100%。是一个容器及盒子，里面可以放行内或者块级元素。注意：文字类的元素内不能放块级元素 标签主要用于存放文字，因此 里面不能放块级元素，特别是不能放 同理， ~ 等都是文字类块级标签，里面也不能放其他块级元素2.2、行内元素常见的行内元素：、、、、、 、、 、、 标签是最典型的行内元素。有的地方也将行内元素称为内联元素。行内元素的特点：相邻行内元素在一行上，一行可以显示多个。高、宽直接设置是无效的。默认宽度就是它本身内容的宽度。行内元素只能容纳文本或其他行内元素。注意：链接里面不能再放链接特殊情况链接里面可以放块级元素，但是给转换一下块级模式最安全.2.3、行内块元素常见的行内块标签： 、 、 它们同时具有块元素和行内元素的特点。有些资料称它们为行内块元素。行内块元素的特点：和相邻行内元素（行内块）在一行上，但是他们之间会有空白缝隙。一行可以显示多个（行内元素特点）。默认宽度就是它本身内容的宽度（行内元素特点）。高度，行高、外边距以及内边距都可以控制（块级元素特点）。2.4、元素显示模式总结学习元素显示模式的主要目的就是分清它们各自的特点，当我们网页布局的时候，在合适的地方用合适的标签元素。3、元素显示模式的转换简单理解:一个模式的元素需要另外一种模式的特性比如想要增加链接的触发范围。转换方式转换为块元素：display:block;转换为行内元素：display:inline;转换为行内块：display: inline-block;4、单行文字垂直居中的代码解决方案:让文字的行高等于盒子的高度 就可以让文字在当前盒子内垂直居中简单理解:行高的上空隙和下空隙把文字挤到中间了如果行高小于盒子高度,文字会偏上如果行高大于盒子高度,则文字偏下四、css的背景通过 CSS 背景属性，可以给页面元素添加背景样式。背景属性可以设置背景颜色、背景图片、背景平铺、背景图片位置、背景图像固定等。1、背景颜色样式名称：background-color定义元素的背景颜色使用方式：其他说明：元素背景颜色默认值是transparent（透明）2、背景图片样式名称：background-image定义元素的背景图片使用方式：其他说明：实际开发常见于 logo 或者一些装饰性的小图片或者是超大的背景图片, 优点是非常便于控制位置. (精灵图也是一种运用场景)注意：背景图片后面的地址，千万不要忘记加 URL， 同时里面的路径不要加引号。3、背景平铺样式名称：​background-repeat 设置元素背景图像的平铺使用方式：4、背景图片位置样式名称：background-position属性可以改变图片在背景中的位置使用方式：参数代表的意思是：x 坐标和 y 坐标。 可以使用 方位名词 或者 精确单位其他说明：1、参数是方位名词如果指定的两个值都是方位名词，则两个值前后顺序无关，比如 left top 和 top left 效果一致如果只指定了一个方位名词，另一个值省略，则第二个值默认居中对齐2、参数是精确单位如果参数值是精确坐标，那么第一个肯定是 x 坐标，第二个一定是 y 坐标如果只指定一个数值，那该数值一定是 x 坐标，另一个默认垂直居中3、参数是混合单位如果指定的两个值是精确单位和方位名词混合使用，则第一个值是 x 坐标，第二个值是 y 坐标5、背景图片固定样式名称：background-attachment属性设置背景图像是否固定或者随着页面的其余部分滚动。使用方式：其他说明：background-attachment后期可以制作视差滚动的效果。6、背景样式合写背景合写样式：background: 背景颜色 背景图片地址 背景平铺 背景图像滚动 背景图片位置;使用方式：7、背景色半透明CSS3 提供了背景颜色半透明的效果。使用方式：最后一个参数是 alpha 透明度，取值范围在 0~1之间我们习惯把 0.3 的 0 省略掉，写为 background: rgba(0, 0, 0, .3);注意：背景半透明是指盒子背景半透明，盒子里面的内容不受影响CSS3 新增属性，是 IE9+ 版本浏览器才支持的，但是现在实际开发,我们不太关注兼容性写法了,可以放心使用8、背景总结
上一篇文章为HTML标签上半部分，此篇为下半部分。表格标签标签table、tr与td标签表格标签的作用：主要用于显示、展示数据，因为它可以让数据显示的非常的规整，可读性非常好。特别是后台展示数据的时候，能够熟练运用表格就显得很重要。一个清爽简约的表格能够把繁杂的数据表现得很有条理。表格标签不是用来布局，是用来整理数据。 第一行单元格内的文字 第一行单元格内的文字 第一行单元格内的文字 第二行单元格内的文字 第二行单元格内的文字 第二行单元格内的文字 ... 上边的示例中 是用于定义表格的标签。说明这个地方是一个表格 标签用于定义表格中的行，必须嵌套在 标签中。 用于定义表格中的单元格，必须嵌套在标签中。字母td指表格数据（table data），即数据单元格里面的的内容。表格标题 我是表格标题 使用及注意事项：caption元素定义表格标题，通常这个标题会被居中且显示与表格之中。caption标签必须紧随table标签之后。这个标签只存在表格里面才有意义。th（表头单元格）标签一般表头单元格位于表格的第一行或第一列，表头单元格里面的文本内容加粗居中显示. 标签表示HTML表格的表头部分(table head的缩写)。th也是一个单元格，只是和td不一样，会让文字加粗居中。属性名属性值描述alignleft,center,right规定表格相对周围元素的对其方式border1或""规定表格单元是否拥有边框，默认为"",表示没有边框cellpadding像素值规定单元边沿与其内容之间的空白，默认1像素cellspacing像素值规定单元格之间的空白，默认2像素width像素值或百分比规定表格的宽度表格结构标签作用:因为表格可能会很长,为了更好的表示表格的语义，可以将表格分割成表格头部和表格主体两大部分在表格标签中，分别用： 标签表示表格的头部区域、 标签表示表格的主体区域，这样可以更好的分清表格结构。 标记用于提供页脚内容组。此标记在带有标题和正文的HTML表中使用，称为“thead”和“tbody”。 标记是表的子标记，是 和 的父标记。注意事项： 用于定义表格的头部。 内部必须拥有 标签，一般是位于第一行。 用于定义表格的主体，主要用于放数据本体。tfoot标签用于提供页脚内容组，以上标签都是放在 标签中。如果使用thead、tfoot以及tbody元素，就必须使用全部的元素。它们的出现次序是：thead、tfoot、tbody，这样浏览器就可以在收到所有数据前呈现页脚了。合并单元格有些表格不需要那么多的单元格，我们可以给他们合并，这个时候需要用到合并单元格。合并单元格的时候有两种合并，一个是跨行合并，顾名思义就是跨行与行之间合并、还有一个跨列合并，列与列之间合并。跨行合并：rowspan="合并单元格的个数"跨列合并：colspan="合并单元格的个数"使用方法：确定是跨行或跨列在要合并的单元格写上合并方式与合并单元格数量例如： 即跨列合并两个单元格删除被合并的单元格。属性属性名属性值描述border1或""规定表格单元是否拥有边框，默认为"",表示没有边框width像素值或百分比规定表格的宽度height像素值或百分比规定表格的高度cellspacing像素值规定单元格之间的空白，默认2像素单元格与单元格之间的距离cellpadding像素值规定单元边沿与其内容之间的空白，默认1像素alignleft,center,right规定表格相对周围元素的对其方式colspan合并的单元格个数列合并rowspan合并的单元格个数行合并列表表格是用来显示数据的，那么列表就是用来布局的。HTML支持无序列表、有序列表、自定义列表。列表最大的特点就是整齐、整洁、有序，它作为布局会更加自由和方便。无序列表无序列表是一个项目的列表，此列项目使用粗体圆点●进行标记。无序列表使用 标签，列表项使用 标签定义。语法格式： 列表项1 列表项2 列表项3 ... 注意事项：无序列表的各个列表项之间没有顺序级别之分，是并列的。 中只能嵌套 ，不能直接在 标签中输入其他标签或者文字。 之间相当于一个容器，可以容纳所有元素。无序列表会带有自己的样式属性，但在实际使用时，我们会使用 CSS 来设置。有序列表有序列表就是有顺序排列的列表，其各个列表项会按照一定的顺序排列定义。在HTML标签中， 标签用于定义有序列表，列表排序以数字来显示，并且使用 标签来定义列表项。语法格式： 列表项1 列表项2 列表项3 ... 注意事项： 中只能嵌套 ，不能直接在 标签中输入其他标签或者文字。 之间相当于一个容器，可以容纳所有元素。无序列表会带有自己的样式属性，但在实际使用时，我们会使用 CSS 来设置。自定义列表自定义列表不仅仅是一列项目，而是项目及其注释的组合。定义列表常用于对术语或名词进行解释和描述，定义列表的列表项钱没有任何项目符号。在HTML标签中， 标签用于定义描述列表（或定义列表），该标签会与 （定义项目/名字）和 （描述每一个项目/名字）一起使用。语法格式： 某个名词 某个名词的解释1 某个名词的解释2 … 某个名词2 某个名词的解释1 某个名词的解释2 … 注意事项： 里面只能包含 和 和 个数没有限制，经常是一个 对应多个 定义列表的列表项内部可以使用段落、换行符、图片、链接以及其他列表等等列表总结：标签名定义说明 无序列表里面只能包含li，没有顺序 有序列表里面只能包含li，有顺序 自定义列表里面有两个标签，dt和dd表单表单是为了在网页中收集信息表单的组成在HTML中一个完整的表单通常由表单域、表单控件（表单元素）、提示信息3部分组成表单域表单域 是一个包含表单元素的区域在HTML标签中， 标签用于定义表单域，以实现用户信息的收集和传递。 会把它范围内的表单元素信息提交给服务器 各种表单元素控件 属性属性值作用actionurl地址用于指定接受并处理表单数据的服务器程序的url地址methodget/post用于设置表单数据的提交方式，其取值为get或postname名称用于指定表单的名称，用来区分同一个页面中的多个表单域表单控件（表单元素）在表单域中可以定义各种表单元素，这些表单元素就是允许用户在表单中输入或者选择的内容控件。 表单元素在表单元素中， 标签用于收集用户信息。在 标签中包含一个type属性，根据不同的type属性值，输入字段拥有很多种信息（文本字段、复选框、掩码后的文本控件、单选按钮、按钮等）input为单标签type属性设置不同的属性值用来指定不同的控件类型type属性的常用属性值：属性值描述button定义可点击按钮（多数情况下，用于通过JavaScript启动脚本）checkbox定义复选框file定义输入字段和“浏览按钮”，供文件上传hidden定义隐藏的输入字段image定义图像形式的提交按钮password定义密码字段，该字段中的字符被掩码radio定义单选按钮reset定义重置按钮重置按钮会清除表单中的所有数据submit定义提交按钮，提交按钮会把表单数据发送到服务器text定义单行的输入字段，用户可在其中输入文本。默认宽度为20个字符除type属性外，标签还有其他属性常用属性有：属性属性值描述name由用户自定义定义input元素的名称value由用户自定义规定input元素的值checkedchecked规定此input元素首次加载时应当被选中mexlength正整数规定输入字段中的字符的最大长度name和value是每个表单元素都有的属性值,主要是给后台人员使用name表单元素的名字, 要求单选按钮和复选框要有相同的name值.checked属性主要针对于单选按钮和复选框, 主要作用一打开页面,就要可以默认选中某个表单元素maxlength是用户可以在表单元素输入的最大字符数, 一般较少使用label标签 标签为input元素定义标注（标签）使用场景： 标签用于绑定一个表单元素，当点击 标签内的文本时，浏览器就会自动将光标转到或选择对应的表单元素上，用来增加用户体验核心： 标签的for属性应当与相关元素的id属性相同。基本语法： 男 表单元素使用场景: 在页面中，如果有多个选项让用户选择，并且想要节约页面空间时，我们可以使用 标签控件定义下拉列表。基本语法 选项1 选项2 选项3 ... 注意事项 中至少包含一对 。在 中定义selected ="selected"时，当前项即为默认选中项。 表单元素使用场景: 当用户输入内容较多的情况下，我们就不能使用文本框表单了，此时我们可以使用 标签。在表单元素中， 标签是用于定义多行文本输入的控件。使用多行文本输入控件，可以输入更多的文字，该控件常见于留言板，评论。通过 标签可以轻松地创建多行文本输入框。基本语法 文本内容 总结思维导图
开篇昨晚上一不小心给电脑整坏了，无奈之下就重装了系统。装完系统之后最麻烦的当然就是所有学习资料的安装恢复了。这样的工作对我这种记忆力不大好的“老年人”极度不友好！可是这又有什么办法呢，找到了我在云盘的学习资料后，当然是安装对应的工具了。我首先选择恢复的是vscode这款神器，我感觉这款轻量编辑器还是对我挺友好的，各个系统平台都可以使用，支持多种语言不说，还有丰富多样的各类插件免费使用。配置过程要拥有vscode这就不用说了吧，没有的话可以去官网下载地址下载，或者使用我提供的蓝奏云链接，密码：5mp1（64位与32位）https://code.visualstudio.com/#home-termshttps://yunyuwu.lanzouv.com/b00p6w4pi第一步：汉化vscode并安装c插件同时摁住（ctrl+shift+x）在搜索框中输入chinese，然后我们点击第一个简体中文下的install，等待下载完成后重启vscode就可以看到汉化后的页面了。然后我们继续安装以下两款插件C/C++以及Code Runner第二步：安装编译器（MinGW-W64 GCC）由于官网下载地址需要科学上网，为了方便我也上传了蓝奏云一份。官网下载的时候，要下载x86_64-posix-seh这个版本的o！https://sourceforge.net/projects/mingw-w64/files/https://yunyuwu.lanzouv.com/i8aD8xq4muf第三步：配置环境变量下载完成后解压到自己想要的目录（路径中不能有中文），然后我们点击到bin文件夹中，复制bin的路径然后我们点击：此电脑——属性——高级系统设置——环境变量，点击系统环境变量中的Path。接着按下方图片操作后，摁住win+R键输入cmd，在cmd控制台输入下方代码并回车，当输出结果如图所示就是成功了gcc -v -E -x c++ -第四步：配置vscode最后我们配置vscode的相关配置：先新建一个文件夹作为C语言项目文件夹，然后点击菜单中的：文件——打开文件夹——选择我们刚创建的文件夹然后在其中创建一个c语言文件，名字可以随意，结尾必须是.c然后创建一个.vscode文件夹（前面有个.）在里面创建三个json文件，分别是：c_cpp_propertise.json与launch.json和tasks.json分别编辑这三个文件c_cpp_propertise.json：然后我们需要将图片中红色方框内的路径修改为自己刚安装的编译器的地址，将你刚刚安装的路径复制一下，然后修改此代码中的D:/Programs/mingw64部分{ "configurations": [ { "name": "Win32", "includePath": [ "${workspaceRoot}", "D:/Programs/mingw64/include/**", "D:/Programs/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++", "D:/Programs/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32", "D:/Programs/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/backward", "D:/Programs/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include", "D:/Programs/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include-fixed", "D:/Programs/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/include" ], "defines": [ "_DEBUG", "UNICODE", "__GNUC__=6", "__cdecl=__attribute__((__cdecl__))" ], "intelliSenseMode": "msvc-x64", "browse": { "limitSymbolsToIncludedHeaders": true, "databaseFilename": "", "path": [ "${workspaceRoot}", "D:/Programs/mingw64/include/**", "D:/Programs/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++", "D:/Programs/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32", "D:/Programs/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/backward", "D:/Programs/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include", "D:/Programs/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include-fixed", "D:/Programs/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/include" ] } } ], "version": 4 }launch.json：将miDebuggerPath属性里的内容一样改为自己的路径{ "version": "0.2.0", "configurations": [ { "name": "(Windows) Launch", "type": "cppvsdbg", "request": "launch", "program": "cmd", "preLaunchTask": "echo", "args": [ "/C", "${fileDirname}\\${fileBasenameNoExtension}.exe", "&", "echo.", "&", "pause" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "console":"externalTerminal" }, { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/${fileBasenameNoExtension}.exe", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": true, "MIMode": "gdb", "miDebuggerPath": "D:\\Programs\\mingw64\\bin\\gdb.exe",//自己电脑的gdb路径 "preLaunchTask": "echo", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] }tasks.json：直接复制粘贴进去保存即可{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "echo", "type": "shell", "command": "gcc", "args": [ "-g", "${file}", "-o", "${fileBasenameNoExtension}.exe", "-fexec-charset=GBK"//解决中文乱码 ] } ], "presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared", "showReuseMessage": true, "clear": false } }第五步：调试我们输入熟悉的代码然后摁下F5进行调试，就会发现我们可以放飞自我了#include <stdio.h> int main() { printf("hello world"); return 0; }总结总结一下：1.注意替换路径中的\与/改错会闪退的2.如果要运行c++的话，把launch.json文件第16行和tasks.json文件3行的gcc改成g++