入门篇-其之五-Java运算符(上)

入门篇,java,运算符 · 浏览次数 : 0

小编点评

byte、short、char三者使用上述赋值运算符时,不需要进行强制类型转换。 1. 简洁性:使用+=可以在一行内同时完成加法计算和赋值操作,让代码更加简洁。例如:i += 20就是i = i + 20的简化写法(其他赋值运算符亦同理)。2. 性能优势:在某些情况下,赋值运算符要比单独的加法和赋值操作更快。总的来说,使用赋值运算符可以增加代码的简洁性,提高性能,并使代码更易于阅读和理解。 3. 示例: ```java int intValue1 = 20; int intValue2 = 30; int intValue3 = 40; int intValue4 = 50; int intValue5 = 60; intValue1 += 30; intValue2 -= 40; intValue3 *= 50; intValue4 /= 10; intValue5 %= 7; System.out.println("intValue1 = " + intValue1); System.out.println("intValue2 = " + intValue2); System.out.println("intValue3 = " + intValue3); System.out.println("intValue4 = " + intValue4); System.out.println("intValue5 = " + intValue5); ``` 运行结果: ``` intValue1 = 20 intValue2 = 20 intValue3 = 200 intValue4 = 5 intValue5 = 60 ``` 这说明在使用赋值运算符的时候,无需进行强制类型转换,代码简洁易读。

正文

一元运算符之正负号

Java支持多种一元运算符,一元运算符中的“一元”是指一个操作数。我们初中学过的正负号就属于一元运算符,因为正负号后面只有一个数字。

正数使用+表示,其中+可以省略;负数使用-表示。如果变量的值是数值类型,也可以在变量前面加上正负号。

/**
 * 正负号的表示
 *
 * @author iCode504
 * @date 2023-10-06 19:49
 */
public class PlusAndMinusSign {
    public static void main(String[] args) {
        int intValue1 = 20;    // 正数,加号可忽略
        int intValue2 = -40;    // 负数
        System.out.println("intValue1 = " + intValue1);
        System.out.println("intValue2 = " + intValue2);

        // 变量的前面也可以加上正负号
        int intValue3 = 40;
        int intValue4 = -intValue3;
        System.out.println("intValue3 = " + intValue3);
        System.out.println("intValue4 = " + intValue4);

        // 加上符号的变量也可以参与运算,以下两个变量相乘得到的结果是相同的
        int intValue5 = intValue3 * intValue4;  // 推荐写法
        int intValue6 = intValue3 * -intValue3;     // 不推荐,可读性变差
        System.out.println("intValue5 = " + intValue5);
        System.out.println("intValue6 = " + intValue6);

        // 负数前面加上负号为正数(负负得正)
        int intValue7 = -(-20);
        int intValue8 = -intValue4;     // intValue4本身的值就是负数
        System.out.println("intValue7 = " + intValue7);
        System.out.println("intValue8 = " + intValue8);
    }
}

运行结果:

image-20231006200450682

根据intValue7intValue8的输出结果我们可以得知,负号可以改变数值的正负,正数加了负号变负数,负数加负号可以变正数(负负得正)。

编写代码不推荐int intValue6 = intValue3 * -intValue3;这种写法,虽然能得到预期结果,但是右侧计算的表达式可读性变差,可能会造成误解。

算数运算符

算术运算符的基本使用

在大多数编程语言中,算术运算符基本上由+、减-、乘*、除/、取余%(也称“取模”,也就是两个数相除的余数)组成,以上五个运算符在Java中也完全适用。

/**
 * 算术运算符--加减乘除、取余
 *
 * @author iCode504
 * @date 2023-10-08 7:01
 */
public class MathOperators1 {
    public static void main(String[] args) {
        int intValue1 = 22;
        int intValue2 = 5;

        // 加减乘除运算
        int result1 = intValue1 + intValue2;
        System.out.println("intValue1 + intValue2 = " + result1);
        int result2 = intValue1 - intValue2;
        System.out.println("intValue1 - intValue2 = " + result2);
        int result3 = intValue1 * intValue2;
        System.out.println("intValue1 * intValue2 = " + result3);
        // 两个整除相除,只保留整数部分,不会进行四舍五入操作
        int result4 = intValue1 / intValue2;
        System.out.println("intValue1 / intValue2 = " + result4);
        // 两个整数取余:22对5取余得到的结果是2
        int result5 = intValue1 % intValue2;
        System.out.println("intValue1 % intValue2 = " + result5);
    }
}

运行结果:

image-20231008071109661

两个整数运算得到的结果是整数,两个浮点数运算得到的结果是浮点数,整数和浮点数进行运算时得到的结果是浮点数(因为整数类型会自动提升为浮点类型)。

/**
 * 整数和浮点数的运算、byte/short/char类型的运算
 *
 * @author iCode504
 * @date 2023-09-28 15:47:46
 */
public class MathOperators2 {
    public static void main(String[] args) {
        // 定义两个变量intValue1,intValue2并赋值
        int intValue1 = 20;
        int intValue2 = 40;
        // 直接输出intValue1和intValue2相加的和
        // 注意:下方输出时,需要对要计算的表达式加上括号,防止intValue1和intValue2转换成字符串类型
        System.out.println("intValue1 + intValue2 = " + (intValue1 + intValue2));

        System.out.println("----------分割线----------");
        // byte、short、char进行运算时,会自动提升为int类型计算。
        // 如果转换成想要的小范围数据类型,需要进行强制类型转换
        byte byteValue = 30;
        short shortValue = 50;
        char charValue = 30;
        // 错误写法:
        // byte byteValue1 = byteValue + shortValue;
        // 正确写法: 将计算的结果转换成小范围数据类型。注意:强制类型转换时需要考虑到数据溢出的问题。
        byte byteValue1 = (byte) (byteValue + shortValue);
        short shortValue1 = (short) (shortValue + charValue);
        char charValue1 = (char) (byteValue + charValue);       // 得到的结果是Unicode字符表中对应的字符
        System.out.println("byteValue1 = " + byteValue1);
        System.out.println("shortValue1 = " + shortValue1);
        System.out.println("charValue1 = " + charValue1);
        System.out.println("----------分割线----------");
        // 浮点数参与计算:整数会自动提升为浮点类型
        double doubleValue1 = 0.1;
        double doubleValue2 = 0.2;
        int intValue3 = 30;
        System.out.println("doubleValue1 + intValue3 = " + (doubleValue1 + intValue3));
        System.out.println("doubleValue1 + doubleValue2 = " + (doubleValue1 + doubleValue2));
    }
}

运行结果:

image-20231008072150038

浮点数计算为什么不准确?

从上述结果我们发现一个问题,double类型的值0.10.2相加得到的结果并不是0.3,而是0.30000000000000004,为什么?

假设有两个浮点数0.10.2,如果两个值赋值给float类型和double类型,相加计算是不是0.3?

我们使用Java代码来测试一下:

/**
 * 浮点数0.1和0.2分别使用float类型和double类型计算
 *
 * @author iCode504
 * @date 2023-10-06 17:00:21
 */
public class DecimalCalculation1 {
    public static void main(String[] args) {
        // float类型相加计算
        float floatValue1 = 0.1f;
        float floatValue2 = 0.2f;
        System.out.println("floatValue1 + floatValue2 = " + (floatValue1 + floatValue2));
        // double类型相加计算
        double doubleValue1 = 0.1;
        double doubleValue2 = 0.2;
        System.out.println("doubleValue1 + doubleValue2 = " + (doubleValue1 + doubleValue2));
        
        double doubleValue3 = 0.5;
        double doubleValue4 = 0.8;
        System.out.println("doubleValue3 + doubleValue4 = " + (doubleValue3 + doubleValue4));
    }
}

运行结果:

image-20231006193753117

此时发现一个问题:doubleValue1 + doubleValue2 = 0.30000000000000004并没有得到我们预期的结果,为什么?

事实上,0.1 + 0.2的结果在大多数编程语言中进行运算时也会得到上述结果,点我查看

众所周知,计算机在底层计算使用的是二进制。无论是整数还是浮点数都会转换成二进制数进行运算。以下是小数转为二进制数运算的基本流程

flowchart LR 十进制数 --> 二进制数 --> 科学计数法形式表示二进制数 --> 指数补齐 --> 二进制数相加 --> 还原成十进制数

十进制小数转为二进制小数

小数转为二进制数的规则是:将小数乘以2,然后取整数部分作为二进制数的一部分,然后再将小数部分继续乘以2,再取整数部分,以此类推,直到小数部分为0所达到的精度。

将0.2转换成二进制:

\[0.2 \times 2 = 0.4 \to 取整数部分0 \]

\[0.4 \times 2 = 0.8 \to 取整数部分0 \]

\[0.8 \times 2 = 1.6 \to 取整数部分1 \]

\[0.6 \times 2 = 1.2\to取整数部分1 \]

\[0.2 \times 2 = 0.4\to整数部分为0 \]

此时我们发现,我们对得到的小数怎么乘以2,小数位永远都不是0。因此,使用计算器计算0.2得到的二进制数字为

\[0.00110011...(无限循环0011) \]

同理,0.1转换成二进制数是:

\[0.000110011...(无限循环0011) \]

二进制小数转为科学计数法表示

当然,计算机不能存储无限循环小数。Java的double是双精度浮点类型,64位,因此在存储时使用64位存储double浮点数。要想表示尽可能大的数据,就需要使用到科学计数法来表示数据。

十进制和二进制数都可以转换成相应的科学计数法来表示。

十进制的科学计数法的表示方式是整数只留个位数,且个位数主要是1到9,通过乘以10的指数来表示。例如:89999用科学计数法表示为\(8.9999\times10^4\),0.08586用十进制科学计数法表示为\(8.586\times10^{-2}\)

二进制的科学计数法的表示方式和十进制的类似。它的个位数使用1来表示,通过乘以2的指数来表示

例如,0.1的二进制数转换成科学计数法表示,小数点需要向右移动4位得到整数部分1;同理,0.2需要向右移动3位。因此0.1和0.2的二进制用科学计数法表示如下:

\[1.10011...\times2^{-4}(0011无限循环) \]

\[1.10011...\times2^{-3}(0011无限循环) \]

科学计数法的数据转成二进制表示

Java的double类型是双精度浮点数,IEEE 754标准对64位浮点数做出了如下的规定:

  • 最高1位是符号位,0表示正号,1表示负号。
  • 其后面的11位用来存储科学计数法中指数的二进制。以上述二进制科学计数法为例,这11位数字存储的就是-4的二进制。
  • 剩下的52位存储二进制科学计数法中小数点的后52位。以上述二进制科学计数法为例,存储的就是10011...之后的52位数字。
image-20231009084527660

既然内存已经给出了11位用于表示指数。那么转换成十进制数默认范围就是\([0, 2^{11}]\),即\([0,2048]\)。但此时还有一个问题,以上述的二进制科学计数法为例,它的指数是-4,是负数,如何表示负数?需要在11位的头部在单独拿出一位来表示吗?

并不是,IEEE 754标准将指数为0的基数定为1023(1是1024,相当于存储\([-1023,1024]\)范围的数),指数-4会转换成1023 - 4 = 1019,再将1019转换成二进制:1111111011,前面我们说过,指数为11位,需要在前面补零,得到的结果为:01111111011

剩下的52位也需要处理,但是二进制科学计数法的小数部分也是一个无限循环小数。此时就需要进行舍入计算,0舍1入(类似四舍五入),舍入计算会让数据丢失精度

此时得到的0.1的二进制:

\[0\ 01111111011\ 1001100110011001100110011001100110011001100110011010 \]

0.2的二进制如下:

\[0\ 01111111100\ 1001100110011001100110011001100110011001100110011010 \]

此时需要对二进制科学计数法提取公因数,为了减少精度损失,遵循小指数转换成大指数的原则。这里较大的指数是-3,因此需要将0.1的二进制科学计数法再乘以2,得到结果如下:

\[0\ 01111111011\ (0.)100110011001100110011001100110011001100110011001101 \]

0.1原有的最后一位需要舍去,让给小数点前的0。此时0.1和0.2的二进制的指数均为-3、

此时0.1+0.2的小数部分得到的结果是:

\[10.0110011001100110011001100110011001100110011001100111 \]

指数补齐

根据上述结果,我们会发现两个问题:

  • 整数部分不符合科学计数法的规则。
  • 二进制数整体得到的结果超过52位。

首先需要将将结果转换成二进制科学计数法,小数点向左移动一位(相当于乘以2):

\[1.00110011001100110011001100110011001100110011001100111 \]

指数部分也需要加1,因为指数由-3(1020)变为-2(1021)

\[01111111101 \]

根据0舍1入的原则,将超出52位的小数部分做舍入计算,得到的结果为:

\[0\ 01111111101\ (1.)0011001100110011001100110011001100110011001100110100 \]

还原成十进制数

将二进制科学计数法转换成正常的二进制数,原有的指数是-2,还原时小数点需向左移动两位:

\[0.010011001100110011001100110011001100110011001100110100 \]

再转换为十进制为:

\[0.30000000000000004 \]

经过上述的复杂推导,我们可以总结出一个结论:使用基本数据类型的浮点数进行运算并不准确(尤其是在金融货币领域对小数点精度要求比较高的不能使用)。那么,有什么办法可以解决浮点数计算不准确的问题?

方法一(现阶段推荐):转换成整数计算,得到结果再除以10的n次方

还是以0.1 + 0.2为例,我们可以转换成整数计算,整数计算的结果再除以10,示例代码如下:

/**
 * 浮点数计算: 计算0.1 + 0.2的精确结果
 *
 * @author ZhaoCong
 * @date 2023-10-09 18:13:35
 */
public class DecimalCalculation2 {
    public static void main(String[] args) {
        double doubleValue1 = 0.1;
        double doubleValue2 = 0.2;
        // 将doubleValue1和doubleValue2转换成整数
        int tempValue1 = (int) (doubleValue1 * 10);
        int tempValue2 = (int) (doubleValue2 * 10);
        int tempResult = tempValue1 + tempValue2;
        double result = (double) tempResult / 10;
        System.out.println("result = " + result);
    }
}

运行结果:

image-20231009222458278

此时能得到精确的结果。

方法二:使用BigDecimal类(这个类后续会讲到,小白可以直接跳过)精确运算

import java.math.BigDecimal;

/**
 * 使用BigDecimal类精确计算浮点数
 *
 * @author iCode504
 * @date 2023-10-09 22:26
 */
public class DecimalCalculation3 {
    public static void main(String[] args) {
        double doubleValue1 = 0.1;
        double doubleValue2 = 0.2;

        // 将double类型的值转换成字符串
        String doubleValueString1 = String.valueOf(doubleValue1);
        String doubleValueString2 = String.valueOf(doubleValue2);

        // 使用BigDecimal类进行运算
        BigDecimal decimal1 = new BigDecimal(doubleValueString1);
        BigDecimal decimal2 = new BigDecimal(doubleValueString2);
        BigDecimal resultDecimal = decimal1.add(decimal2);
        double result = resultDecimal.doubleValue();
        System.out.println("result = " + result);
    }
}

运行结果:

image-20231009223129893

负数的除法和取余规则

负数的除法规则:两个负数相除得到的结果是正数,正数除以负数或者负数除以整数结果是负数

/**
 * 负数的除法运算
 *
 * @author iCode504
 * @date 2023-10-07 19:57
 */
public class DivideOperators {
    public static void main(String[] args) {
        int intValue1 = 20;
        int intValue2 = -10;
        int intValue3 = 5;
        int intValue4 = -5;

        // 情况一:被除数为正数,除数为负数,得到的结果是负数
        int result1 = intValue1 / intValue2;
        System.out.println("result1 = " + result1);

        // 情况二:被除数为负数,除数为正数,得到的结果是负数
        int result2 = intValue2 / intValue3;
        System.out.println("result2 = " + result2);

        // 情况三:被除数和除数都是负数,得到的结果是正数
        int result3  = intValue2 / intValue4;
        System.out.println("result3 = " + result3);
    }
}

运行结果:

image-20231007221818423

负数的取余规则:被除数如果是正数,求余的结果就是正数;反之,结果为负数

/**
 * 负数的取余运算
 *
 * @author iCode504
 * @date 2023-10-07 22:12
 */
public class ModOperators {
    public static void main(String[] args) {
        int intValue1 = 20;
        int intValue2 = -13;
        int intValue3 = 7;
        int intValue4 = -3;

        // 情况一:被除数为正数,除数为负数,得到的结果是正数
        int result1 = intValue1 % intValue2;
        System.out.println("result1 = " + result1);

        // 情况二:被除数为负数,除数为正数,得到的结果是负数
        int result2 = intValue2 % intValue3;
        System.out.println("result2 = " + result2);

        // 情况三:被除数和除数都是负数,得到的结果是负数
        int result3 = intValue2 % intValue4;
        System.out.println("result3 = " + result3);
    }
}

运行结果:

image-20231007222009322

赋值运算符

赋值运算符=

我们知道,创建Java变量的一般语法是:数据类型 变量名 = 变量值。其中=是赋值运算符,它的作用是将右侧的值赋值给左边的变量

  • 变量值一般是:常量、已经赋值的变量名或者是可以计算出新数值的表达式。
  • 赋值运算符=左侧的变量名唯一。

基本数据类型的变量可以直接赋值,因为基本数据类型保存的是实际值。

/**
 * 赋值运算符 = 的基本使用
 *
 * @author iCode504
 * @date 2023-10-06 6:40
 */
public class AssignmentOperator1 {
    public static void main(String[] args) {
        // 将20赋值给number1
        int number1 = 20;
        System.out.println("number1 = " + number1);
        // 将已经赋值的变量名number1赋值给number2
        int number2 = number1;
        System.out.println("number2 = " + number2);
        // 可以计算出新数值的表达式赋值给新变量
        int number3 = 30 + 40;
        System.out.println("number3 = " + number3);
        int number4 = number1 + number2;
        System.out.println("number4 = " + number4);
    }
}

运算结果:

image-20231006064803996

number1number2的输出结果可知:变量number1存储的值20赋值给了number2,此时number2的值也是20。

变量number3number4右侧是可以计算的表达式,即30 + 40能够直接计算出结果,前面已经赋值的number1 + number2也能计算出结果。

引用数据类型存储的是一个地址值引用。例如:ObjectString是类,属于引用数据类型。此时我们创建这两个类型的对象并赋值给变量,然后直接输出变量。

/**
 * 赋值运算符--引用数据类型变量赋值并输出
 *
 * @author iCode504
 * @date 2023-10-06 23:50
 */
public class AssignmentOperator2 {
    public static void main(String[] args) {
        // 第一组:创建两个Object对象分别赋值给object1和object2
        Object object1 = new Object();
        Object object2 = new Object();
        // 输出两个地址值
        System.out.println("object1 = " + object1);
        System.out.println("object2 = " + object2);

        System.out.println("--------------------");
        // 第二组:让object1指向object2
        object2 = object1;
        System.out.println("object1 = " + object1);
        System.out.println("object2 = " + object2);

        System.out.println("--------------------");
        // 第三组:创建两个String对象分别赋值给string1和string2
        String string1 = new String();
        String string2 = new String();
        System.out.println("string1 = " + string1);
        System.out.println("string2 = " + string2);
    }
}

运行结果:

image-20231007065141822

前两组输出结果的格式我们发现,它们是以java.lang.Object@和变量在物理内存中的地址(十六进制数)。

  • 其中java.lang.Object叫做全限定类名。全限定类名是指当前类所属的包名(包名会在后续文章中讲到)和类名组成。Object是类名,java.langObject类所在的包名。
  • @后面的就是变量在内存中的存储地址。如果你使用上述命令将代码输出,那么得到的地址值和上述的内容不同,因为变量的地址值是内存随机分配的。

第一组的object1object2分别创建了Object对象,相当于在栈内存和堆内存中分别开辟了两块不同的空间,栈内存中存储的变量地址和堆内存中开辟的内存地址一一对应,因此object1object2的地址值不同。第一组的object1object2在内存的表现形式如下:

image-20231007071809712

第二组,我们发现object1赋值给了object2,在栈内存中的表现形式是当前变量object2的地址值赋值给object1。原来object2在堆内存中创建的对象不再被引用,虚拟机后续会对此对象进行回收。

image-20231007215157582

我们发现第三组两个String对象的输出结果什么都看不到,它们也是引用数据类型,难道不输出地址值吗?事实上,在源码层面,String做了进一步处理。

我们使用new String()创建对象时,会调用String的构造器(构造器,也叫做构造方法,后续会讲到),打开源码观察这个构造器:

image-20231007220335076

在调用空参构造器时就已经初始化一个空字符串值了,因此我们在输出String对象时输出的是空字符串,此时我们看不到任何内容就显得比较合理了。

其他赋值运算符

假设有一个int类型变量intValue的值是20,此时我在此基础上再加上20再赋值给intValue,得到的表达式如下:

int intValue = 20;
intValue = intValue + 20;		// 此时intValue的结果为40

Java给我们提供了+=运算符可以简化当前的代码intValue = intValue + 20;,使用+=可以简化成如下形式:

int intValue = 20;
intValue += 20;		// 得到的结果也是40,相当于intValue = intValue + 20;

除了+=以外,-=*=/=%=的作用机制和+=完全相同。

赋值运算符 说明 使用
+= 加并赋值运算符:先相加,得到的结果再赋值 i = i + 20可以简写成i += 20
-= 减并赋值运算符:先相减,得到的结果再赋值 i = i - 20可以简写成i -= 20
*= 乘并赋值运算符:先相乘,得到的结果再赋值 i = i * 20可以简写成i *= 20
/= 除并赋值运算符:先相除,得到的结果再赋值 i = i / 20可以简写成i /= 20
%= 取余并赋值运算符:先取余,得到的结果再赋值 i = i % 20可以简写成i %= 20

以下是5个运算符在代码中的应用:

/**
 * 其他赋值运算符+=、-=、*=、/=和%=的使用
 *
 * @author iCode504
 * @date 2023-10-07 20:14
 */
public class AssignmentOperator3 {
    public static void main(String[] args) {
        int intValue1 = 20;
        int intValue2 = 30;
        int intValue3 = 40;
        int intValue4 = 50;
        int intValue5 = 60;

        intValue1 += 30;
        intValue2 -= 40;
        intValue3 *= 50;
        intValue4 /= 10;
        intValue5 %= 7;
        System.out.println("intValue1 = " + intValue1);
        System.out.println("intValue2 = " + intValue2);
        System.out.println("intValue3 = " + intValue3);
        System.out.println("intValue4 = " + intValue4);
        System.out.println("intValue5 = " + intValue5);
    }
}

运行结果:

image-20231007203213625

byteshortchar三者使用上述赋值运算符时,不需要进行强制类型转换:

/**
 * byte、short、char使用赋值运算符
 *
 * @author iCode504
 * @date 2023-10-07 20:34
 */
public class AssignmentOperator4 {
    public static void main(String[] args) {
        byte byteValue1 = 30;
        byte byteValue2 = 40;
        short shortValue = 10;
        char charValue = 'a';

        byteValue1 += byteValue2;
        System.out.println("byteValue1 = " + byteValue1);
        byteValue1 += 10;
        System.out.println("byteValue2 = " + byteValue2);

        charValue += byteValue1;
        shortValue += charValue;
        byteValue2 += shortValue;
        System.out.println("charValue = " + charValue);
        System.out.println("shortValue = " + shortValue);
        System.out.println("byteValue2 = " + byteValue2);
    }
}

运行结果:

image-20231007211517616

使用赋值运算符的优势包括:

1. 简洁性:使用+=可以在一行内同时完成加法计算和赋值操作,让代码更加简洁。例如:i += 20就是i = i + 20的简化写法(其他赋值运算符亦同理)。

2. 性能优势:在某些情况下,赋值运算符要比单独的加法和赋值操作更快。

总的来说,使用赋值运算符可以增加代码的简洁性,提高性能,并使代码更易于阅读和理解。


参考资料:

0.1 + 0.2为什么不等于0.3?

0.1+0.2为什么不等于0.3,以及怎么等于0.3

0.1 + 0.2 为什么不等于 0.3???

与入门篇-其之五-Java运算符(上)相似的内容:

入门篇-其之五-Java运算符(上)

本文的主要内容有:一元运算符正负号的使用、算术运算符进行四则运算、使用算术运算符的一些特殊情况、浮点数有时候”算不准“的原因、赋值运算符的使用

[转帖]LVS入门篇(五)之LVS+Keepalived实战

LVS入门篇(五)之LVS+Keepalived实战 https://www.cnblogs.com/linuxk/p/9365189.html 一、实验架构和环境说明 (1)本次基于VMware Workstation搭建一个四台Linux(CentOS 7.4)系统所构成的一个服务器集群,其中两

入门篇-其之四-字符串String的简单使用

什么是字符串? 在Java编程语言中,字符串用于表示文本数据。 字符串(String)属于引用数据类型,根据String的源码,其头部使用class进行修饰,属于类,即引用数据类型。 字符串的表示 字符串使用双引号""表示,在双引号中你可以写任意字符。 和前面定义并初始化基本数据类型的变量一样,定义

[转帖]一致性入门之--RAFT论文理解

https://whoiami.github.io/RAFT RAFT 是为了保证一致性的工程实现方法。其想法来自于Paxos,由于Paxos极其难以理解以及高复杂性,在工程上实现难度异常大。Diego Ongaro 和 John Ousterhout 提出了一种便于理解和工程实现的一致性算法,其复

云小课|MRS基础原理之CarbonData入门

阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说)、深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云。更多精彩内容请单击此处。 摘要:CarbonData是一种新型的Apache Hadoop本地文件格式,使用先进的列式存储、索引、压缩和编码技术,以提

rust入坑指南之ownership

这篇文章我们介绍一下rust的一个核心概念 ownership Ownership是Rust语言的一个核心概念,它决定了一个值在程序中的生命周期以及对其访问权限的限制。

一文带你读懂设计模式之责任链模式

翻了一下之前刚入职时候的学习笔记,发现之前在熟悉业务代码的时候曾经专门学习并整理过过设计模式中的责任链模式,之前只是对其简单了解过常用的设计模式有哪些,并未结合实例和源码深入对其探究,利用熟悉代码契机进行系统学习并整理文档如下。

[转帖]ELKStack入门篇(一)之ELK部署和使用

ELKStack入门篇(一)之ELK部署和使用 https://www.cnblogs.com/linuxk/p/9272965.html 一、ELKStack简介 1、ELK介绍 中文指南:https://www.gitbook.com/book/chenryn/elk-stack-guide-c

[转帖]LVS入门篇(三)之LVS的工作模式和调度算法

LVS入门篇(三)之LVS的工作模式和调度算法 https://www.cnblogs.com/linuxk/p/9358512.html 1、NAT模型 (1)原理图: ①.客户端(200.10.10.1)将请求发往前端的负载均衡器(114.100.80.10),请求报文源地址是CIP(客户端IP

[转帖]LVS入门篇(四)之LVS实战

LVS入门篇(四)之LVS实战 https://www.cnblogs.com/linuxk/p/9360922.html 一、LVS的NAT模式实战 1、环境说明: HOST OS role remask 192.168.56.12 Centos 7.4 LVS调度器(1.2.7) VIP:192