Linux NameSpace 虚拟化 资源隔离

news2024/11/17 4:29:37

NameSpace

NameSpace介绍

在操作系统中命名空间命名空间提供的是系统资源的隔离,其中系统资源包括了:进程、网络、文件系统等等

  • 实际上linux系统实现命名空间主要目的之一就是为了实现轻量级虚拟化服务,也就是我们说的容器,在同一个命名空间下的进程可以感知彼此的变化,而对其他命名空间的进程一无所知,这样就可以让容器中的进程产生一个错觉,仿佛它自己置身于一个独立的系统环境当中,以此达到独立和隔离的目的。

Linux的namespace(名字空间)的作用就是“隔离内核资源”。

在Linux的世界里,

文件系统挂载点、

主机名、

POSIX进程间通信消息队列、

进程PID数字空间、

IP地址、

user ID数字空间等全局系统资源被namespace分割,装到一个个抽象的独立空间里。

而隔离上述系统资源的namespace分别是Mount namespace、UTS namespace、IPC namespace、PID namespace、network namespace和user namespace。

对进程来说,要想使用namespace里面的资源,首先要“进入”(具体操作方法,下文会介绍)到这个namespace,而且还无法跨namespace访问资源。

Linux的namespace给里面的进程造成了两个错觉:

(1)它是系统里唯一的进程。

(2)它独享系统的所有资源。

默认情况下,Linux进程处在和宿主机相同的namespace,即初始的根namespace里,默认享有全局系统资源

namespace分类

namespace针对不同资源有不同的隔离方案和实现.

资源描述实现思路
进程隔离进程IDLinux通过命名空间管理进程号,同一个进程,在不同的命名空间进程号不同. 进程命名空间是一个父子结构,子空间对于父空间可见
网络隔离网络设备、协议栈、端口等通过网络命名空间,实现网络隔离 docker采用虚拟网络设备,将不同命名空间的网络设备连接到一起
IPC隔离进程间通信进程间交互方法 PID命名空间和IPC命名空间可以组合起来用, 同一个IPC名字空间内的进程可以彼此看见,允许进行交互,不同空间进程无法交互
磁盘隔离挂载点隔离文件目录 进程运行时可以将挂载点与系统分离,使用这个功能时,我们可以达到 chroot 的功能,而在安全性方面比 chroot 更高
UTS隔离Hostname和NIS域名让容器拥有独立的主机名和域名,从而让容器看起来像个独立的主机 目的是独立出主机名和网络信息服务(NIS)
用户隔离用户和group ID每个容器内上的用户跟宿主主机上不在一个命名空间 同进程 ID 一样,用户 ID 和组 ID 在命名空间内外是不一样的,并且在不同命名空间内可以存在相同的 ID

NameSpace隔离原理

NameSpace怎么实现隔离的?

它是Linux内核级别支持的.

Linux内核自2.4.19版本接纳第一个namespace:Mount namespace(用于隔离文件系统挂载点)起,到3.8版本的user namespace(用于隔离用户权限),总共实现了上文提到的6种不同类型的namespace。

尽管Linux的namespace隔离技术很早便存在于内核中,而且它就是为Linux的容器技术而设计的,但它一直鲜为人知。直到Docker引领的容器技术革命爆发,它才进入普罗大众的视线——Docker 容器作为一项轻量级的虚拟化技术,它的隔离能力来自Linux内核的namespace技术

Network Namespace

它在Linux内核2.6版本引入,作用是隔离Linux系统的设备,以及IP地址、端口、协议栈/路由表、防火墙规则等网络资源。因此,每个网络namespace里都有自己的网络设备(如IP地址、路由表、端口范围、/proc/net目录等)。从网络的角度看,network namespace使得容器非常有用,一个直观的例子就是:由于每个容器都有自己的(虚拟)网络设备,并且容器里的进程可以放心地绑定在端口上而不必担心冲突,这就使得在一个主机上同时运行多个监听80端口的Web服务器变为可能

以下是网络命名空间如何实现这些隔离的简单概述:

  1. 网络设备隔离:每个网络命名空间都可以有自己的网络设备(网卡)。同一网络设备不能同时出现在多个命名空间中,但可以通过veth(Virtual Ethernet)设备对或者macvlan等技术,在不同的网络命名空间之间建立网络连接。当网络设备移动到另一网络命名空间时,对于原命名空间,该设备就像是被移除了一样。

  2. 协议栈隔离:网络协议栈是操作系统实现网络协议(如TCP/IP)的一部分,它处理如何发送和接收数据包。Linux的每个网络命名空间都有自己的网络协议栈,它们是彼此独立的。这意味着,网络配置(如IP地址、路由规则、防火墙规则等)在一个命名空间中的改变不会影响其他命名空间。

  3. 端口隔离:在网络命名空间中,端口是隔离的。每个网络命名空间都有自己的端口范围和端口分配。例如,不同的网络命名空间都可以使用相同的端口号(如80),而不会发生冲突,因为它们在不同的命名空间中。

这样,网络命名空间使得我们可以创建多个隔离的网络环境,每个网络环境都可以有自己的网络设备、IP地址、路由规则和其他网络配置。这在创建容器等隔离环境时非常有用。

  • 在 Linux 中,网络命名空间可以被认为是隔离的拥有单独网络栈(网卡、路由转发表、iptables)的环境。网络命名空间经常用来隔离网络设备和服务,只有拥有同样网络命名空间的设备,才能看到彼此。几乎所有物理存在的都可以进行虚拟虚拟局域网,虚拟MAC地址,虚拟交换机,虚拟网络层,虚拟链路层等等各个维度的,具体支持的类型可以在 ip netns的bash shell中查看 man ip-link

    • 网络设备: 如网卡

    • 路由转发表

    • iptables

    • 邻接表

    • netfilter表

    • 网络套接字

    • 网络procfs条目

    • 网络sysfs条目

    • 其他网络资源

  • 从逻辑上说,网络命名空间是网络栈的副本,拥有自己的网络设备、路由选择表、邻接表、Netfilter表、网络套接字、网络procfs条目、网络sysfs条目和其他网络资源。

  • 从系统实现角度来看,当通过clone()系统调用创建新进程时,传递标志CLONE_NEWNET将在新进程中创建一个全新的网络命名空间。

  • 从用户交互API角度来看,我们只需使用工具ip(package is iproute2)来创建一个新的持久网络命名空间。

 

网络命名空间管理

创建

ip netns add netns01

这个命令ip netns add netns01用于在Linux系统中添加一个新的网络命名空间,具体解释如下:

  1. ip: 这是Linux系统的一个常用命令,用于显示或操作路由、设备、策略路由和隧道。

  2. netns: 是ip命令的子命令,用于管理网络命名空间。网络命名空间(Network Namespace)是Linux内核的一个功能,用于隔离网络环境,例如隔离网络设备、IP地址、路由表等。

  3. add: 是netns的子命令,用于添加一个新的网络命名空间。

  4. netns01: 这是新建网络命名空间的名称。

创建的网络命名空间在文件系统中以文件的形式存在,位于/var/run/netns/目录下。

# ll /var/run/netns/
total 0
-r--r--r--. 1 root root 0 Jul 28 23:33 netns01

使用说明和注意事项:

  • 在运行ip netns add命令之前,你需要确保ip命令有足够的权限(需要root权限)来创建新的网络命名空间。

  • 网络命名空间创建后,可以使用ip netns exec netns01 command命令在新的网络命名空间中执行命令。例如,ip netns exec netns01 ip link set lo up可以在新的网络命名空间中启用lo(loopback)设备。

  • 当不再需要网络命名空间时,可以使用ip netns del netns01命令来删除它。

  • 注意,创建的网络命名空间是隔离的,新的网络命名空间并不会自动拥有任何网络设备,包括lo(loopback)设备,这些设备需要在新的网络命名空间中手动创建和启用。

  • 在操作网络命名空间时需要小心,不正确的操作可能会导致网络问题,例如错误地删除或修改网络设备、IP地址或路由规则等。在生产环境下操作时,应遵循最佳实践,并在可能的情况下进行充分的测试。

查看

网络命名空间

ip netns ls

ip netns identifyip netns ls

ip netns identifyip netns ls 这两个命令在功能和用途上有很大的不同。

  1. ip netns identify:此命令用于查找并打印与给定进程相关联的所有网络命名空间的名称。例如,ip netns identify 1234 将列出与进程ID为1234相关的所有网络命名空间的名称。

  2. ip netns ls:此命令列出系统上存在的所有网络命名空间的名称。这并不涉及任何特定的进程,而是给出了系统当前的所有网络命名空间。

删除

ip netns del

ip netns del netns01
ip netns ls

上面这条命令实际上并没有删除netns1这个network namespace,它只是移除了这个network namespace对应的挂载点。只要里面还有进程运行着,network namespace便会一直存在。

进入

进入空间及执行命令

ip netns add netns01
ip netns exec netns01 bash

ip netns exec netns01 bash命令是在创建的网络命名空间netns01内执行bash shell的命令。在这个命令中:

  • 执行完bash之后其实就是启动了一个bash shell,后续的操作都是在这个shell空间中进行了,但是注意没有提示,你需要先退出才能退回到os的shell

  • ip netns exec是命令的前缀,用于在指定的网络命名空间执行后面的命令。

  • netns01是网络命名空间的名称。

  • bash是要执行的命令。它启动了一个bash shell,该shell会在netns01命名空间中运行。这意味着在这个bash shell中执行的所有命令,都会在netns01命名空间中运行。

除了bash,ip netns exec后面可以接任何命令,例如:

  • ip netns exec netns01 ip addr:在netns01网络命名空间中查看网络接口的IP地址。

  • ip netns exec netns01 ping 8.8.8.8:在netns01网络命名空间中ping一个IP地址。

注意事项:

  • 在使用ip netns exec命令时,你需要root权限。

  • ip netns exec会改变命令的网络命名空间上下文,但不会改变其他的命名空间上下文,例如PID命名空间、用户命名空间等。如果你需要在完全隔离的环境中运行命令,你可能需要使用其他工具,例如unshare或docker。

  • 你需要确保你在正确的网络命名空间中运行命令。在错误的网络命名空间中运行命令可能会导致网络问题或者数据丢失。如果你不确定,你可以使用ip netns identify命令来查看当前的网络命名空间。

  • ip netns exec命令在运行命令时会更改网络命名空间。如果你在一个脚本中使用ip netns exec,你需要确保这个脚本不会在改变命名空间后的命令失败时继续执行,否则后续的命令可能会在错误的网络命名空间中运行。

空间内指令

在进入命名空间的bash shell上下文后,你就有一个空间内的shell环境了

查看网卡

# 在网络命名空间中查看网络命名空间中的网卡信息
ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# 可以看到目前处于DOWN状态


# 在Linux主机系统中查看
ip netns exec netns01 ip link list
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

当你执行 ip netns exec netns01 bash 并进入到网络命名空间的 bash shell 之后,你可以执行的操作就和在任何 Linux shell 中一样广泛。然而,因为你现在在一个特定的网络命名空间内,所以所有的网络相关的操作都将局限于这个网络命名空间。以下是一些可能的操作:

  1. 网络配置:使用 ipifconfigroutenetstat 等命令查看和更改网络配置。例如,你可以使用 ip addr 来查看网络接口的 IP 配置。注意事项:因为你在特定的网络命名空间中,所以你看到的将仅仅是在这个命名空间内的网络配置。

  2. 网络通信:使用 pingtraceroutenctelnetssh 等命令来测试网络连接或者进行网络通信。注意事项:你只能够连接到在同一命名空间内,或者是可以路由到的网络实体。

  3. 网络服务:你可以启动或停止在特定网络命名空间内运行的网络服务,如 HTTP 服务器、FTP 服务器等。注意事项:这些服务只能在此网络命名空间内访问,除非进行了特殊配置。

  4. 系统命令:你可以执行像 lscatvitop 这样的系统命令,它们和网络无关。注意事项:这些命令的执行不受网络命名空间的影响。

退出空间

# 退出已进入的网络命名空间
exit

配置虚拟网卡

如果没有网卡那是无法通信的,所以容器也需要配置网卡,虚拟网卡.

对容器来说需要创建一对网卡.因为一个网卡是容器的一个是物理机的,容器需要连接到物理机的网卡才能对外通信

创建
ip link add veth01 type veth peer name veth10
ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
10: veth10@veth01: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
    link/ether 06:6e:31:5e:f3:19 brd ff:ff:ff:ff:ff:ff
11: veth01@veth10: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
    link/ether 9a:77:14:b4:99:dd brd ff:ff:ff:ff:ff:ff
​
# 可以直接指定空间
netns <netns>:这个选项允许你直接将新创建的veth对的一端移动到指定的网络命名空间。例如,
ip link add veth0 type veth peer name veth1 netns mynetns
将会创建一个veth对veth0和veth1,其中veth1会被放入到名为mynetns的网络命名空间。
迁移

ip link set veth01 netns netns01


从空间1移动到空2

# 进入源(netns01)网络命名空间执行
ip link set veth10 netns netns02
​
# 宿主机执行 netns01移动到netns02
ip netns exec netns01 ip link set veth10 netns netns02


# 创建到目标空间
ip link add veth01 type veth peer name veth10 netns netns01
# 查看本地
ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 00:0c:29:c6:03:83 brd ff:ff:ff:ff:ff:ff
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT qlen 1000
    link/ether 52:54:00:04:70:ac brd ff:ff:ff:ff:ff:ff
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN mode DEFAULT qlen 1000
    link/ether 52:54:00:04:70:ac brd ff:ff:ff:ff:ff:ff
5: veth01@if12: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
    link/ether f2:53:c0:3b:ef:f2 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    
# 查看目标空间
ip netns exec netns01 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
12: veth10@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
    link/ether 5a:50:9d:01:dc:cc brd ff:ff:ff:ff:ff:ff link-netnsid 0
移出
# 在netns01命名空间执行删除
ip link delete veth01
或者执行
ip link delete veth10
# 都是成对删除, 删除任何一个,另一个也会被删除
​
# 或者宿主机bash执行
ip netns exec netns01 ip link delete veth10
​
# 查看
ip link show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
删除
ip link delete veth10
# 自动成对删除

配置地址

配置地址

ip addr add 172.16.193.233/24 dev veth10

查看地址

ip addr show

此时状态是DOWN,需要up启动状态

启动

ip link set veth10 up
ip addr show

启动lo回环网卡

ip link set lo up

此时还是不通的,为什么?

因为这个成对的网卡,另外一个还没有地址

宿主机执行

6: veth01@if7: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether e6:1e:9b:28:c5:6a brd ff:ff:ff:ff:ff:ff link-netnsid 1

配置成对地址

宿主机分配IP

ip addr add 172.16.193.234/24 dev veth01
# 宿主机不需要执行up,当你执行其中一个虚拟网卡up的时候 另一个网卡也是up的 
# 执行up之后直接退出了, 且重启之后netns都消失了
client_loop: send disconnect: Broken pipe

ping验证

宿主机ping网络空间虚拟网卡

ping 172.16.193.233

配置路由条目

ip netns exec netns01 ip route add default via 172.16.193.233

网络空间虚拟网卡ping宿主机

ip netns exec netns01 ping -c 4 172.16.193.133
配置路由

通过查看虚拟网卡的路由表

ip netns exec netns01 route

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.50.0    0.0.0.0         255.255.255.0   U     0      0        0 veth1

我们看到它智能到达50网段的出口,没有外网出口,即它无法访问外网

ip netns exec netns01 ping -c 1 www.baidu.com

通过ping可以看到是不通.

那我们就要思考怎么才能联通外网呢,只能利用成对的虚拟网卡,因为那个网卡是在宿主机上,是可以出外网的

所以我们可以在命名空间的虚拟网卡配置下路由,让他联通成对虚拟网卡

ip netns exec netns01 ip route add default via 192.168.50.3
ip netns exec netns01 route -n
---
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.50.3    0.0.0.0         UG    0      0        0 veth1
192.168.50.0    0.0.0.0         255.255.255.0   U     0      0        0 veth1
[root@centos133 ~]#

配置了这个路由还不行,还是没法转发出去

配置脚本

ip netns add netns01
ip link add veth0 type veth peer name veth1
ip link set veth1 netns netns01
ip netns exec netns01 ip addr add 192.168.30.2/24 dev veth1
ip netns exec netns01 ip link set veth1 up
ip netns exec netns01 ip link set lo up
ip addr add 192.168.30.3/24 dev veth0
ip link set veth0 up
ip netns exec netns01 ip route add default via 192.168.30.3
# ping 虚拟机
ping -c 1 172.16.193.133
# ping 虚拟机 veth0
ping -c 1 192.168.30.3
# 在宿主机上ping netns01 中的veth1
ping -c 1 192.168.50.76
# 增加ipv4转发,主要是能访问外网主机
vim /etc/sysctl.conf
net.ipv4.ip_forward=1

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分享一个赛车动画

先看效果&#xff08;动画太大了放不上来&#xff0c;甘心去复制代码运行即可&#xff09;&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>赛车</title><…

AD21 PCB设计的高级应用(六)极坐标的应用

&#xff08;六&#xff09;极坐标的应用 在 PCB 设计过程中,特别是 LED圆形灯板的 PCB 设计,需要对 LED灯珠进行圆形等间距排列,如果每个元件都计算清楚其坐标再进行放置会非常烦琐。要实现如图 所示的元件布局效果,在 Altium Designer 软件里可以使用极坐标的方法。 (1)打开…

Vue2 第十一节 Vue的生命周期

1.生命周期的概念 2.生命周期流程图 3.生命周期分析 一.生命周期概念 生命周期又称为生命周期回调函数&#xff0c;生命周期函数&#xff0c;生命周期钩子是Vue在关键时刻帮我们调用的一些特殊名称的函数生命周期函数的名字不可更改&#xff0c;但函数的具体内容是程序员根…

【低代码开发】:加速应用开发的未来趋势

低代码开发&#xff1a;加速应用开发的未来趋势 引言什么是低代码以及功能特点&#xff1f;什么是低代码开发&#xff1f;低代码平台的特点和功能低代码平台的应用场景和优势低代码的优点低代码的缺点低代码平台项目开发流程选择和实施低代码平台 低代码未来的发展趋势低代码平…

MyBatis缓存-提高检索效率的利器--一级缓存

&#x1f600;前言 本篇博文是关于MyBatis一级缓存的介绍使用和缓存失效情况分析&#xff0c;希望能够帮助到您&#x1f60a; &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家…

c++基础知识(inline、auto、nullptr)

⭐️ 内联函数 &#x1f4ac; 为什么会有内联函数&#xff1f;   内联函数其实是为了弥补 c 的缺陷&#xff0c;比如当我们遇到了一些少量逻辑和代码的情况时&#xff0c;而这些少量的代码又需要被重复使用多次&#xff08;swap&#xff09;&#xff0c;我们往往会封装成为一…

linux快速安装tomcat

linux快速安装tomcat 前提安装好jdk 下载Tomcat安装包 wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.0.27/bin/apache-tomcat-10.0.27.tar.gz如果出现颁发的证书已经过期的错误提示,用下面命令 wget --no-check-certificate https://dlcdn.apache.org/tomcat/tomcat-1…

剑指 Offer 第二版

剑指 Offer 第二版 文章目录 剑指 Offer 第二版[剑指 Offer 06. 从尾到头打印链表](https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId13&tqId23278&ru/exam/oj/ta&qru/ta/coding-interviews/question-ranking&sourceUrl%2Fexam%2Foj…

区块链实验室(13) - 在PBFT中节点的度与其流量的特征

前面若干实验说明了PBFT的耗时、流量与度的特征&#xff0c;见 区块链实验室(10) - 实例说明PBFT的共识过程, 区块链实验室(11) - PBFT耗时与流量特征, 区块链实验室(12) - 网络拓扑对PBFT共识流量的影响 同样的实验方案&#xff0c;在100个节点构成的无标度网络中完成100次交…

html学习4(区块、布局)

1、<div> 是块级元素&#xff0c;它独占一行&#xff0c;可以设置宽度、高度以及边距等样式属性。它适合用于创建页面的大块结构&#xff0c;例如页面的主体区域、容器、布局等。 2、<span> 是行内元素&#xff0c;它不会独占一行&#xff0c;宽度默认由其内容决定…

Ubuntu20.04安装Autoware.universe并与Awsim联调

文章目录 引言一、安装依赖1.1 安装git1.2 克隆Autoware到本地1.3 自动安装相关依赖1.4 安装显卡驱动1.5 安装ROS2 Galactic1.6 安装ros2_dev_tools1.7 安装rmw_implementation1.8 安装pacmod1.9 安装autoware_core1.10 安装autoware universe dependencies1.11 安装pre_commit…

(2)Gymnasium--CartPole的测试

1、主要参考 &#xff08;1&#xff09; CartPole 强化学习详解1 - DQN_Oxalate-c的博客-CSDN博客 &#xff08;2&#xff09;官方文档&#xff0c;推荐&#xff01;&#xff01;&#xff01;&#xff01; Cart Pole - Gymnasium Documentation 2、相关说明 2.1 动作空间 …

DP-GAN-生成器代码

在train文件中&#xff0c;对生成器和判别器分别进行更新&#xff0c;根据loss的不同&#xff0c;分别计算对于的损失&#xff1a; loss_G, losses_G_list model(image, label, "losses_G", losses_computer)loss_D, losses_D_list model(image, label, "los…

环形链表 II(JS)

环形链表 II 题目 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;…

企业数字化转型失败率达80%,面临哪些挑战?应该如何规划?

随着数字化在社会的飞速发展&#xff0c;人们的生活工作娱乐等方方面面都已经被数字化占领&#xff0c;数字化所衍生出的数字经济更是成为高速增长的国民经济支柱&#xff0c;而数据作为“副产品”也成功进化为第五大生产要素&#xff0c;发挥出巨大的价值&#xff0c;变成了个…

智慧展馆展厅人员定位系统解决方案:提升参观体验与管理效率

随着数字化时代的到来&#xff0c;展馆和展厅逐渐成为人们了解文化、艺术、科技等领域的重要窗口。 然而&#xff0c;传统的展馆和展厅存在着一些问题&#xff0c;例如参观者迷路、信息获取不及时、管理效率低下等。 为了提升参观体验和管理效率&#xff0c;研发智慧展馆展厅…

测试|Selenium之WebDriver常见API使用

测试|Selenium之WebDriver常见API使用 文章目录 测试|Selenium之WebDriver常见API使用1.定位对象&#xff08;findElement&#xff09;css定位xpath定位css选择器语法&#xff1a;xpath语法:校验结果 2.操作对象鼠标点击对象在对象上模拟按键输入clear清除对象输入的文本内容su…

TCP三次握手和四次挥手以及11种状态(一)

1、三次握手 置位概念&#xff1a;根据TCP的包头字段&#xff0c;存在3个重要的标识ACK、SYN、FIN ACK&#xff1a;表示验证字段 SYN&#xff1a;位数置1&#xff0c;表示建立TCP连接 FIN&#xff1a;位数置1&#xff0c;表示断开TCP连接 三次握手过程说明&#xff1a; 1、…

【自动化剧本】Role角色

目录 一、Roles模块1.1roles的目录结构1.2roles 内各目录含义解释1.3在一个 playbook 中使用 roles 的步骤 二、使用Role编写LNMP剧本2.1 搭建Nginx角色2.2搭建Mysql角色2.3搭建php角色2.4lnmp剧本 一、Roles模块 roles用于层次性、结构化地组织playbook。roles能够根据层次型结…

实战!聊聊工作中使用了哪些设计模式

实战&#xff01;聊聊工作中使用了哪些设计模式 策略模式 业务场景 假设有这样的业务场景&#xff0c;大数据系统把文件推送过来&#xff0c;根据不同类型采取不同的解析方式。多数的小伙伴就会写出以下的代码&#xff1a; if(type"A"){//按照A格式解析}else if(t…