springboot第59集:面试官万字挑战,一文让你走出微服务迷雾架构周刊

news/2024/7/4 7:59:50 标签: 架构, 微服务, 云原生

加群联系作者vx:xiaoda0423(个人简介:男,深圳,一名全栈架构师,25+)b32338f08f158cce5756eae9c335ce54.png

image.png
5c0d29925eaea6965506778334efb9f1.png
image.png
7d5706822bd9d5b5e1313efe12bea891.png
image.png
9837db9572b3b36dbcb7025380656597.png
image.png
a98140c3862d5e574eefa36745ac28bb.png
image.png
c3cfd6cf7cc41c8ed857cde83cb43f57.png
image.png
18f46485f27272b1ae1be0bf45b34863.png
image.png
75017b778dbeb19c5ca4a6ebe440d9f2.png
image.png
f1d5168b43ce21a0bb5fafc81b52a670.png
image.png
ed067d73bc78a0d92ce37e94e26110a4.png
image.png
7c3184d5614570158f205e4e96d0ef6b.png
image.png
97714796d01b364a318b5596d4c25ccf.png
image.png
5e9bb820b72e5b16b48422fabc40a5ac.png
image.png
eac3ebbe957fa08a5ec79721b9693350.png
image.png
ec6e71dd5a23f26805d38ccaf49d5152.png
image.png
5cc69a81991aa21826beac4479f7c7b9.png
image.png
9ea6fca802ea92574dc27d83cb00a2f6.png
image.png
88ccc8ee308a41156f5010cd845dce88.png
image.png
27557068b1aec3d4f7acf7b0c8e09046.png
image.png
3c116c0156c07a8bd11ae81acfb1307b.png
image.png
7d4860dd4ae6bbc119b7b40bc6f5a951.png
image.png
b05355cd8e1dc9355042e06ae6990862.png
image.png
7dfde7a1c01228173fe2992681c49ac5.png
image.png
8cd165604827be51d7e9ca580e8bf781.png
image.png
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class SynchronizedArrayListExample {
    public static void main(String[] args) {
        // 创建一个线程安全的 ArrayList
        List<Integer> synchronizedList = Collections.synchronizedList(new ArrayList<>());

        // 创建并启动多个线程同时向 ArrayList 中添加元素
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    synchronized (synchronizedList) {
                        synchronizedList.add(j);
                    }
                }
            }).start();
        }

        // 等待所有线程执行完毕
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 输出 ArrayList 中的元素个数
        System.out.println("Size of synchronized ArrayList: " + synchronizedList.size());
    }
}

在高并发的情况下,多个线程同时操作 ArrayList 可能会引发线程不安全的问题,主要有以下几个原因:

  1. 非线程安全的操作: ArrayList 不是线程安全的数据结构,它的内部结构不是线程安全的。在多线程环境下,多个线程同时对 ArrayList 进行添加、删除、修改等操作可能会导致内部状态混乱,从而产生不可预知的结果。

  2. 并发修改异常: 当一个线程正在对 ArrayList 进行修改操作(如添加、删除元素)时,另一个线程也同时对 ArrayList 进行修改操作,可能会导致并发修改异常(ConcurrentModificationException)。

为了避免这些问题,通常需要在多线程环境下使用线程安全的数据结构,或者采用同步机制来保护共享数据的访问。下面是一个示例,演示了在多线程环境下操作 ArrayList 可能引发的线程不安全问题:

import java.util.ArrayList;

public class UnsafeArrayListExample {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();

        // 创建并启动多个线程同时向 ArrayList 中添加元素
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    arrayList.add(j);
                }
            }).start();
        }

        // 等待所有线程执行完毕
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 输出 ArrayList 中的元素个数
        System.out.println("Size of ArrayList: " + arrayList.size());
    }
}

栈溢出通常是由于以下原因之一导致的:

  1. 递归调用:递归调用的层数过多,导致函数调用栈空间不足,从而引发栈溢出错误。

  2. 大量循环或死循环:如果程序中存在大量循环或者死循环,并且循环次数过多,会导致栈空间不断增长,最终导致栈溢出。

  3. 全局变量过多:如果程序中定义了大量的全局变量,会增加栈空间的压力,可能导致栈溢出。

  4. 数据结构过大:如果程序中使用的数据结构(如数组、列表、映射等)过大,会占用大量内存空间,增加栈空间的压力,可能导致栈溢出。

下面是一些示例代码,演示了可能导致栈溢出的情况:

  1. 递归调用:

  2. 大量循环或死循环:

  3. 全局变量过多:

  4. 数据结构过大:

public class StackOverflowExample {
    public static void main(String[] args) {
        recursiveCall(0);
    }

    public static void recursiveCall(int n) {
        recursiveCall(n + 1);
    }
}

fifinally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。

public class Main {
    public static void main(String[] args) {
        System.out.println(test());
    }

    public static int test() {
        try {
            System.out.println("In try block");
            return 1;
        } catch (Exception e) {
            System.out.println("In catch block");
            return 2;
        } finally {
            System.out.println("In finally block");
        }
    }
}

在 Java 中,无论在 try 块中是否有 return 语句,finally 块都会执行。finally 块通常用于释放资源或执行清理操作,无论 try 块中是否发生异常,都会执行 finally 块。

使用 BigDecimal 类可以避免浮点数精度问题,确保得到精确的计算结果。

import java.math.BigDecimal;

public class Main {
    public static void main(String[] args) {
        BigDecimal result = new BigDecimal("3").multiply(new BigDecimal("0.1"));
        System.out.println(result); // 输出:0.3
    }
}

在 Java 中,3 * 0.1 应该返回 0.3,但由于浮点数的精度问题,可能会出现计算结果不准确的情况。这是因为在计算机中,浮点数的表示方式是有限的,而某些十进制小数无法精确地表示为二进制小数。

因此,当我们执行 3 * 0.1 这样的计算时,可能会出现一个非精确的结果。在实际测试中,可能会得到 0.30000000000000004 或者 0.29999999999999999 这样的结果,而不是精确的 0.3。这是由于浮点数的精度问题导致的。

为了避免由于浮点数精度问题导致的误差,通常建议在需要精确计算的场景中,使用 BigDecimal 类进行计算。

使用序列化机制创建对象(需要实现 Serializable 接口):

import java.io.*;

public class SerializationExample {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 使用序列化机制创建对象
        MyClass obj1 = new MyClass();
        // 将对象写入到字节流中
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(obj1);
        // 从字节流中读取对象
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        MyClass obj2 = (MyClass) objectInputStream.readObject();
        obj2.printMessage(); // 输出:Hello, world!
    }
}

使用 clone() 方法创建对象(需要实现 Cloneable 接口):

public class CloneExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        // 使用 clone() 方法创建对象
        MyClass obj1 = new MyClass();
        MyClass obj2 = (MyClass) obj1.clone();
        obj2.printMessage(); // 输出:Hello, world!
    }
}

使用 new 关键字创建新对象:

public class NewObjectExample {
    public static void main(String[] args) {
        // 使用 new 关键字创建新对象
        MyClass obj = new MyClass();
        obj.printMessage(); // 输出:Hello, world!
    }
}

class MyClass {
    public void printMessage() {
        System.out.println("Hello, world!");
    }
}

使用反射机制创建对象:

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ReflectionExample {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        // 使用反射机制创建对象
        Class<MyClass> cls = MyClass.class;
        Constructor<MyClass> constructor = cls.getConstructor();
        MyClass obj = constructor.newInstance();
        obj.printMessage(); // 输出:Hello, world!
    }
}
import java.util.concurrent.ConcurrentHashMap;

public class Main {
    public static void main(String[] args) {
        // 创建一个 ConcurrentHashMap
        ConcurrentHashMap<Integer, String> concurrentHashMap = new ConcurrentHashMap<>();

        // 创建并启动多个线程
        for (int i = 0; i < 5; i++) {
            int finalI = i;
            new Thread(() -> {
                // 向 ConcurrentHashMap 中添加元素
                for (int j = 0; j < 10; j++) {
                    concurrentHashMap.put(finalI * 10 + j, "Value_" + finalI + "_" + j);
                    System.out.println(Thread.currentThread().getName() + " added: " + finalI * 10 + j);
                }
            }).start();
        }

        // 等待所有线程执行完毕
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 输出 ConcurrentHashMap 中的所有元素
        System.out.println("ConcurrentHashMap: " + concurrentHashMap);
    }
}

当需要在多线程环境中操作时,可以使用线程安全的 ConcurrentHashMap

Hashtable 是线程安全的,但在性能上可能不如 HashMap,因为 Hashtable 中的方法使用了 synchronized 关键字进行同步,这会造成一定的性能开销。因此,在不需要线程安全保证的情况下,推荐使用 HashMap,在需要线程安全保证的情况下,再考虑使用 Hashtable 或者 ConcurrentHashMap

import java.util.Hashtable;

public class Main {
    public static void main(String[] args) {
        // 创建一个 Hashtable
        Hashtable<Integer, String> hashtable = new Hashtable<>();

        // 创建并启动多个线程
        for (int i = 0; i < 5; i++) {
            int finalI = i;
            new Thread(() -> {
                // 向 Hashtable 中添加元素
                for (int j = 0; j < 10; j++) {
                    hashtable.put(finalI * 10 + j, "Value_" + finalI + "_" + j);
                    System.out.println(Thread.currentThread().getName() + " added: " + finalI * 10 + j);
                }
            }).start();
        }

        // 等待所有线程执行完毕
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 输出 Hashtable 中的所有元素
        System.out.println("Hashtable: " + hashtable);
    }
}

Hashtable 是线程安全的,因为它的每个方法都使用了 synchronized 关键字进行同步,这使得它可以直接用于多线程环境中。

目录和文件

创建目录

mkdir 名称 => mkdir /data

创建目录及子目录

mkdir -p 名称 => mkdir -p /data/node

创建一个或多个(用空格分开即可)

touch 文件1 文件2 => touch 1.txt 2.txt

复制文件

cp 文件 目录 => cp 1.txt /opt/data

复制文件并改名

cp 文件 目录 => cp 1.txt /opt/data/2.txt

移动目录到另一个目录

mv 目录 目录 => mv data /opt

移动目录到另一个目录并改名

mv 目录 目录 => mv data /opt/data2

强制删除一个目录

rm -rf data

文件夹授予权限

chmod 777 -R 目录 => chmod 777 -R data

解压tar.gz

tar -zxvf 压缩包 => tar -zxvf 1.tar.gz

解压zip

unzip 压缩包 => unzip 1.zip

查询目录路径

pwd

查看文件

cat 目录 => cat 1.txt

编辑文件

vi 目录 => vi 1.txt

将xxx写入文件

echo 内容 >> 文件 => echo '111' >> 1.txt

输出文件尾部内容

tail -n 行数 文件 => tail -n 1000 1.txt

查看文件

find /-name 文件 => find /-name 1.txt #网络

重启网络

service network restart #防火墙

关闭防火墙

systemctl stop firewalld.service

重启防火墙

systemctl restart firewalld.service

启动防火墙

systemctl start firewalld.service

防火墙状态

systemctl status firewalld.service

开启开机自启动

systemctl enable firewalld.service

关闭开机自启动

systemctl disable firewalld.service

查看已开放端口

firewalld-cmd --list-ports

开放端口(永久有效)(需要重新加载防火墙)

firewalld-cmd --zone=public --add-port=端口/tcp --permanent => firewalld-cmd --zone=public --add-port=8080/tcp --permanent

重新加载防火墙

firewalld-cmd --reload #服务

查看服务开机启动状态

systemctl list-run-files

关闭指定服务自启动

systemctl disable 服务 => systemctl disable mysql

开启指定服务自启动

systemctl enable 服务 => systemctl enable mysql #磁盘

查看磁盘

df -h #进程

查看端口

netstat -ntlp

进程启动情况

ps -ef|grep 进程名 => ps -ef|grep java

查看端口占用

netstat -tunlp|grep 端口 => netstat -tunlp|grep 8080

查看进程

ps -aux

终止进程

kill 进程 => kill 884

强制终止进程

kill -9 进程 => kill -9 884 #CPU

查看cpu情况

top #账号

切换账号

su 账号 => su root

新增账号

useradd 用户名 => useradd mysql

添加到分组

useradd -g 组名 用户名 => useradd -g mysql-group mysql

设置密码

passwd 用户名 => passwd mysql

删除用户

userdel 用户名 => userdel mysql

登录用户信息

whomi

Docker

查看内核

uname -r

启动docker

systemctl start docker

查看docker状态

systemctl status docker

重启docker

systemctl restart docker

查看版本

docker version

查看信息

docker info

获取帮助

docker --help

查看镜像

docker images

启动镜像

docker run -d -p 对外端口:容器端口 镜像名称 => docker run -d -p 6379:6379 redis

查看日志

docker logs 容器id => docker logs xz2wxdf

搜索镜像

docker search 镜像名称 => docker search jdk

打包镜像

docker tag 镜像名称:标签 => docker tag redis:7.0.1

删除镜像

docker rmi 镜像id => docker rmi dxfdxzsa

进入容器

docker exec -it 容器id /bin/bash => docker exec -it xsdfds /bin/bash

重启容器

docker restart 容器id => docker restart xsddf

列出容器

docker ps --a

停止容器

docker stop 容器id => docker stop exfds

删除容器

docker rm 容器id => docker rm xsdfds

强制停止容器

docker kill 容器id

查看容器内部细节

docker inspect 容器id

查看所有卷情况

docker volume ls

查看某个卷

docker volume inspect 卷名 => docker volume inspect /data

构建镜像

dokcer build -t 镜像名称:标签 . => docker build -t jdk:21 . #docker-compose

构建镜像

docker-compose build

构建镜像(不带缓存构建)

docker-compose build --no-cache

查看docker镜像

docker-compose images

启动所有镜像

docker-compose up -d

查看所有编排容器(包括已停止容器)

docker-compose ps -a

进入指定容器

docker-compose exec 容器名 bash => docker-compose exec nginx bash

停止所有启动容器

docker-compose stop

停止所有启动容器并删除

docker-compose down

停止某一个容器

docker-compose stop 容器名称 => docker-compose stop nginx

启动某一个容器

docker-compose up -d 容器名称 => docker-compose up -d nginx

重启某一个容器

docker-compose restart 容器名称 => docker-compose restart nginx

删除所有容器

docker-compose rm

查看容器日志

docker-compose logs -f 容器名称 => docker-compose logs -f nginx

查看容器运行进程

docker-compose top

yaml配置

nacos使用https和http协议,只要注册临时服务,都是走RPC,因此使用https需要改为https

spring:
  cloud:
    # nacos
    nacos:
      discovery:
        server-addr: https://127.0.0.1:8848
        namespace: public
        username: nacos
        password: nacos
        group: LAOKOU_GROUP
        # https
        secure: true
        # true 临时 false 持久
        ephemeral: true
      config:
        server-addr: https://127.0.0.1:8848
        namespace: public
        username: nacos
        password: nacos
        # 指定读取的文件格式
        file-extension: yaml
        group: LAOKOU_GROUP
        refresh-enabled: true

keytool命令详解

1.生成pfx证书(.p12是pfx的新格式)

keytool -genkey 
       -alias laokou-register # 证书别名,不区分大小写
       -storetype PKCS12 # 密钥库类型,常用类型有JKS、PKCS12
       -keyalg RSA # 密钥算法,可选密钥算法:RSA\DSA,默认DSA
       -keysize 2048 # 密钥长度(RSA=2048,DSA=2048)
       -keystore scg-keystore.p12  # 密钥库文件名称
       -validity 3650 # 证书有效天数

2.导出证书为cer(cer/crt是证书的公钥格式,cer是crt证书的微软形式)

keytool -exportcert -v 
        -alias laokou-register # 证书别名,不区分大小写
        -keystore scg-keystore.p12  # 密钥库文件名称
        -storepass laokou # 密钥库口令,推荐与keypass一致(获取keystore信息所需要密码)
        -file register.cer # 导出的文件名
a3bd9749f7ea7a74860c17ca46d61d0b.png
image.png
import java.util.Hashtable;
import java.util.Enumeration;

public class Main {
    public static void main(String[] args) {
        // 创建一个 Hashtable
        Hashtable<Integer, String> hashtable = new Hashtable<>();

        // 添加元素到 Hashtable
        hashtable.put(1, "Apple");
        hashtable.put(2, "Banana");
        hashtable.put(3, "Orange");

        // 获取 Hashtable 中的值的枚举
        Enumeration<String> values = hashtable.elements();

        // 遍历枚举并输出值
        while (values.hasMoreElements()) {
            System.out.println(values.nextElement());
        }
    }
}

Hashtable 类的 elements() 方法用于返回此 Hashtable 中的值的枚举(Enumeration)。

LinkedList 是 Java 中的双向链表实现。在 LinkedList 中,每个节点都包含对前一个节点和后一个节点的引用,这使得在链表中插入和删除元素的操作更加高效,因为它不需要像数组那样移动其他元素来保持顺序。

以下是 LinkedList 的基本特点:

  1. 双向链表结构:每个节点包含两个引用,分别指向前一个节点和后一个节点。

  2. 无需连续内存空间:与数组不同,LinkedList 中的节点在内存中可以不必连续存储。

  3. 插入和删除操作高效:由于双向链表的结构,插入和删除操作的时间复杂度为 O(1)。

  4. 随机访问效率低:由于 LinkedList 没有像数组那样可以通过索引进行快速随机访问,因此访问特定位置的元素需要遍历链表,时间复杂度为 O(n)。

  5. 不适合大量数据:由于每个节点都需要额外的空间存储指向前后节点的引用,因此在存储大量数据时,LinkedList 的空间开销会比较大。

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        // 创建一个 LinkedList
        LinkedList<String> linkedList = new LinkedList<>();

        // 添加元素到 LinkedList
        linkedList.add("Apple");
        linkedList.add("Banana");
        linkedList.add("Orange");

        // 访问元素
        System.out.println("LinkedList: " + linkedList);

        // 获取第一个和最后一个元素
        String firstFruit = linkedList.getFirst();
        String lastFruit = linkedList.getLast();
        System.out.println("First fruit: " + firstFruit);
        System.out.println("Last fruit: " + lastFruit);

        // 添加元素到列表的开头和末尾
        linkedList.addFirst("Grape");
        linkedList.addLast("Watermelon");
        System.out.println("LinkedList after adding first and last elements: " + linkedList);

        // 删除第一个和最后一个元素
        linkedList.removeFirst();
        linkedList.removeLast();
        System.out.println("LinkedList after removing first and last elements: " + linkedList);

        // 获取元素个数
        int size = linkedList.size();
        System.out.println("Size of LinkedList: " + size);

        // 判断是否包含某个元素
        boolean containsBanana = linkedList.contains("Banana");
        System.out.println("LinkedList contains 'Banana': " + containsBanana);
    }
}
import java.util.ArrayList;

public class ArrayListExample {
    public static void main(String[] args) {
        // 创建一个 ArrayList
        ArrayList<String> arrayList = new ArrayList<>();

        // 添加元素到 ArrayList
        arrayList.add("Apple");
        arrayList.add("Banana");
        arrayList.add("Orange");

        // 访问元素
        System.out.println("ArrayList: " + arrayList);

        // 获取指定位置的元素
        String fruit = arrayList.get(1);
        System.out.println("Fruit at index 1: " + fruit);

        // 修改元素
        arrayList.set(0, "Grape");
        System.out.println("Updated ArrayList: " + arrayList);

        // 删除元素
        arrayList.remove(2);
        System.out.println("ArrayList after removing element at index 2: " + arrayList);

        // 获取元素个数
        int size = arrayList.size();
        System.out.println("Size of ArrayList: " + size);

        // 判断是否包含某个元素
        boolean containsBanana = arrayList.contains("Banana");
        System.out.println("ArrayList contains 'Banana': " + containsBanana);
    }
}

ArrayList 适用于随机访问和遍历操作,而 LinkedList 适用于频繁的插入和删除操作

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // 创建一个数组
        String[] array = {"apple", "banana", "orange"};

        // 使用 asList 方法将数组转换为列表
        List<String> list = Arrays.asList(array);

        // 修改原数组或列表中的元素
        array[0] = "grape";
        list.set(1, "watermelon");

        // 打印数组和列表
        System.out.println("Array: " + Arrays.toString(array));
        System.out.println("List: " + list);
    }
}

加群联系作者vx:xiaoda0423

仓库地址:https://github.com/webVueBlog/JavaGuideInterview


http://www.niftyadmin.cn/n/5389896.html

相关文章

01_第一章 WEB开发概述(技术栈,交互模式,CS和BS模式,前后端分离)

文章目录 第一章 WEB概述1.1 JAVAWEB简介1.2 JAVAWEB技术栈1.3 JAVAWEB交互模式1.4 JAVAWEB的CS和BS模式1.5 JAVAWEB实现前后端分离 第一章 WEB概述 1.1 JAVAWEB简介 用Java技术来解决相关web互联网领域的技术栈.使用JAVAEE技术体系开发企业级互联网项目. 项目规模和架构模式与…

网卡本质,网络发展(局域网,广域网概念)

目录 引入 网卡的本质 网络的发展 引入 早期 局域网LAN&#xff08;Local Area Network&#xff09; 广域网WAN&#xff08;Wide Area Network&#xff09; 注意 引入 前面我们已经学习了很多关于linux系统的知识,其中文件系统和线程尤为繁杂 而网络其实也算系统的一部…

【ArcGIS】利用高程进行坡度分析:区域面/河道坡度

在ArcGIS中利用高程进行坡度分析 坡度ArcGIS实操案例1&#xff1a;流域面上坡度计算案例2&#xff1a;河道坡度计算2.1 案例数据2.2 操作步骤 参考 坡度 坡度是地表单元陡缓的程度&#xff0c;通常把坡面的垂直高度和水平距离的比值称为坡度。 坡度的表示方法有百分比法、度数…

CSV数据导入到ClickHouse数据库

问题描述&#xff1a;手头上有一个数据量较大的CSV文件&#xff0c;希望导入到指定的ClickHouse数据中&#xff0c;ClickHouse部署在服务器中。 解决方案&#xff1a;通常来说&#xff0c;数据量较少的CSV文件可以直接通过DBeaver软件的可视化界面导入数据。 若数据量较大&…

将矩阵按对角线排序(c++题解)

题目描述 矩阵对角线 是一条从矩阵最上面行或者最左侧列中的某个元素开始的对角线&#xff0c;沿右下方向一直到矩阵末尾的元素。例如&#xff0c;矩阵 mat 有 6 行 3 列&#xff0c;从 mat[2][0] 开始的 矩阵对角线 将会经过 mat[2][0]、mat[3][1] 和 mat[4][2] 。 给你一个…

一个更好的IP工具箱MyIP

什么是 MyIP &#xff1f; MyIP 是一个完全开源的 IP 信息查看器&#xff0c;可以轻松检查你的 IP&#xff0c;IP 地理位置&#xff0c;检查 DNS 泄漏&#xff0c;检查 WebRTC 连接&#xff0c;速度测试&#xff0c;ping 测试&#xff0c;MTR 测试&#xff0c;检查网站可用性等…

VR系统的开发流程

虚拟现实&#xff08;Virtual Reality&#xff0c;VR&#xff09;系统是一种通过计算机技术模拟出的具有三维视角和交互性的虚拟环境&#xff0c;使用户能够沉浸在其中并与虚拟环境进行交互。这种技术通常利用头戴式显示器和手柄等设备&#xff0c;使用户能够感觉到仿佛身临其境…

LVS的工作模式及其原理

1、LVS 介绍 &#xff08;1&#xff09;LVS 是Linux Virtual Server的简称&#xff0c;也就是 Linux 虚拟服务器, 是一个由章文嵩博士发起的自由软件项目&#xff0c;它的官方站点是www.linuxvirtualserver.org。现在LVS已经是 Linux标准内核的一部分&#xff0c;因此性能较高…