iproute2和流量控制(ip和tc工具)---iproute2/ip/tc/qdisc实现Linux下的QoS控制

news2024/11/18 19:29:57

iproute2是一个软件包,这个软件包包含了多种用于高级路由,隧道和流量控制配置工具软件。
iproute2提供了Linux内核对QoS的实现,你可以在以下网站中找到英文原版的信息osdl.org和lartc.org。这些工具软件中,最重要的当数ip和tc这二个工具。

1、网络配置: "ip"工具

ip工具提供了Linux网络配置所需要的大部分功能。通过它,你可以配置网络接口, ARP,路由策略,隧道等等。ip工具支持IPv4和IPv6,并且它的语法简单易懂。最重要的是我们要学会在什么时候使用这个工具来完成什么功能。
首先,ip工具可以用于配置 动态路由协议(BGP, OSPF, and RIP) 。

我们可以通过ip help来查看一下ip工具支持哪些功能。

xxx@raspberrypi:~ $ ip help
Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
       ip [ -force ] -batch filename
where  OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |
                   tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |
                   netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |
                   vrf | sr | nexthop | mptcp }
       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
                    -h[uman-readable] | -iec | -j[son] | -p[retty] |
                    -f[amily] { inet | inet6 | mpls | bridge | link } |
                    -4 | -6 | -I | -D | -M | -B | -0 |
                    -l[oops] { maximum-addr-flush-attempts } | -br[ief] |
                    -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |
                    -rc[vbuf] [size] | -n[etns] name | -N[umeric] | -a[ll] |
                    -c[olor]}

  • ip link命令:
    显示出所有可以用ip link set命令去修改的配置项。本命令用于修改网络接口设备的属性,但不能用于修改IP地址。

  • ip addr命令
    显示所有网络接口设备的IP地址(等同于ip addr show)。ip addr add命令可以用于给网络接口设置增加主或者第二IP地址。ip addr del命令用于删除网络接口设备的IP地址。还有其它一些用途,比如ip addr flush dynamic命令可以直接清除掉所有通过动态路由协议添加到内核的路由表项。

  • ip neighbor命令
    用于管理Arp表,它包含了add, change, replace, delete和flush多个子功能。

  • ip tunnel命令
    用于管理隧道连接。支持gre, ipip和sit等多种隧道协议。用于创建管理隧道。

  • ip monitor命令
    ip工具提供了实时查看路由,地址,设备状态的的功能。

  • ip route命令
    此命令用于对内核的路由表进行操作,包括add, change, replace, delete, show, flush和get等功能。

  • ip rule命令
    iproute2还有一个非常重要的功能就是它能通过ip rule和ip route二种命令实现策略路由。

2、流量控制工具Traffic Control: tc工具

tc工具让使用Linux来代替昂贵的QoS设备成为可能,因为tc工具可以让工程师在Linux主机上配置各种QoS策略。Linux甚至比常用的QoS设备支持更多的QoS功能,这使得我们用Linux机器当做便宜又强大的QoS设备。这个的前提是你的Linux发行版的内核在编译里已经支持QoS选项(CONFIG_NET_QOS=“Y” 和 CONFIG_NET_SCHED=“Y”,这个一般目前能拿到的通用的Linux发行版都是默认打开的,如果你自己编译内核才需要注意这二个配置)。

2.1、流量整形:Queuing Packets(也称做traffic shaping)

Linux系统里,使用Queuing队列机制来决定数据如何被发送,比如控制发送数据包的速度与多少,控制数据包发送的优先级等等。注意队列机制只能用于管理发出的数据包,不能用来管理收到的数据包(这个很好理解,收到的数据包的多少与速度是由发送发决定的,接收方只能被动接收)。如下图所示:我们可以看到,在路由器上,我们只能控制上下行二个方向的发送的QoS。

  • 下行方向
    路由器只能控制路由器从网口eth1 向PC发送的数据包;
  • 上行方向
    路由器只能控制路由器从网口eth0向网络上的服务器发送的数据包。
    在这里插入图片描述
    虽然只能控制发送一个方向的数据流量,但考虑到TCP协议的流控功能 (即:通信双方能通过TCP协议的ACK报文的发送来控制对方的发包速度),控制发送速度与数量就可以达到很好的双向流量整形的效果。UDP不支持协议层面上的流量控制,但大多数基于UDP协议的上层应用层协议带了流量控制功能,所以同样可以达到流量整形的效果。
    但因为只能控制发送方向的数据,不能控制接收方向数据包的QoS,还是带来一些问题,比如泛洪攻击flood attacks导致的DoS的存在就是因为无法控制接收方向上的数据包的多少与速度。
    用于流量整形的队列机制queuing disciplines可以分成二种,classless和classful。

开始讨论这二种Qdiscs之前,让我们来回顾一下qdiscs工作在哪里,ingress Qdiscs工作在进入Linux的TCP/IP协议栈之前, egress Qdiscs工作在报文出了CP/IP协议栈之后。
在这里插入图片描述

2.2、Classless Queuing Disciplines (Classless qdiscs)无分类Qdiscs

Classless qdiscs只支持最简单的规则,比如accept, drop, delay 或者 reschedule数据包。这个classless Qdiscs可以被配置在一个网络接口设备上,也只能对该网络接口设备上的所有数据包做整形,不知道对数据包和流量作分类整形。
Linux内核支持以下几种classless Qdiscs:

  • FIFO (pfifo 和 bfifo):
    最基本的qdisc, 这个只支持最基本的先进先出原则。FIFO算法分成二类,如果是pfifo, 那么它定义了一个队列长度限制;如果是bfifo, 那么它定义了一个缓冲区字节长度限制。
  • pfifo_fast:
    这个是Linux网络接口设备默认的Qdisc。后面我们会详解pfifo_fast的具体工作原理。
  • Token Bucket Filter (tbf):
    这个通常被称为令牌桶,用于限定某个网络接口设备的发送速率。这个机制允许短时间的超出限制,称为burst,是一种CPU占用率友好型的Qdisc。
  • Stochastic Fair Queuing (SFQ):
    这是使用最为广泛的Qdisc。SFQ的原则是尽可能公平合理的调度传输多个数据流flow上的数据包。
  • Enhanced Stochastic Fair Queuing (ESFQ):
    非Linux内核原生支持的Qdisc,它的工作原理与SFQ相似,但为用户提供了更多配置项如depth (flows) limit, hash table size options (SFQ中这个参数是固定值)和 hash types等,以让用户可以更好的控制流量。
  • Random Early Detection and Generic Random Early Detection (RED and GRED):
    一种适用于骨干网的qdiscs。

除了上面列出来的Qdisc之外,还有很多各种流量整形的方法。通常SFQ和ESFQ能对流量做出非常好的整形和控制效果。

Linux默认的Qdisc是pfifo_fast。 它是一种以数据包为单位的先进先出的机制,但实际上,它之所以被称为_fast是因为它提供了三个等级,0, 1和 2, 数据包按照TOS字节的值被分成这三个等级。然后以下面的规则进行发送:

  • 定义为0级的报文拥有最高的优先级
  • 定义为1级的报文,只有在定义为0级的报文全部发送完毕后才能被发送
  • 定义为2级的报文的优先级最低,只有定义为0和1的所有报文全部发送完毕后才能被发送

如下图我们可以看到系统是数据根据每个报文的TOS将数据包映射为0,1,2三个级别的:
在这里插入图片描述TOS字节里,3-6bits被定义为TOS比特,每个bit的意义的定义如下:
在这里插入图片描述
然后按下表,映射成3个等级:
在这里插入图片描述由于Linux默认使用pfifo_fast这种Qdisc,所以Linux是会根据数据包的TOS字节定义的优先级进行传输的,通常,类似Telnet, FTP, SMTP这些协议就是通过定义TOS 字节来优化传输效率的。

2.3、 Classful Queuing Disciplines (Classfull qdiscs)

分类classful qdiscs用于对不同类型的数据流进行分类整形,按流据流类型的不同,提供不同的QoS服务。最觉的classful qdiscs是CBQ (Class Based Queuing,基于流类型的流量整形)和HTB (Hierarchical Token Bucket分层令牌桶)。
首先,我们来理解一下classful queuing disciplines 是怎么工作的。第一个是分层,每个网络接口设备都有一个root qdisc。其次,有一个子类child class附属于这个root qdisc。 这个子分类child class有自己的一个或者多个子子分类child classes,每人子子类又有自己的去真正配置如何进行数据包的传输调度qdiscs和一个或者多个的叶子分类leaf classes。如下图所示的一个5层结构:
在这里插入图片描述
所以CBQ 或者 HTB qdiscs 允许我们去创建自己的CBQ 或 HTB子分类 classes,以支持对不同的数据流进行不同的数据整形QoS服务。

3、tc的 qdisc, class和filter三个概念之间的关系

上图中显示的树状层次关系配置,我们需要用到以下tc命令:

  • tc qdisc
    配置queuing disciplines.
  • tc class
    配置classes.
  • tc filter
    配置filters, 用于对数据流进行分类

我们可以通过调整CBQ 和 HTB的参数,来优化它们的性能。在本文中可以看到针对不同的App产生的不同流量,我们使用了不同的参数。

CBQ 的qdiscs和classes命令格式如下:

xxx@xxx-OptiPlex-3080:~$ tc qdisc add cbq help
Usage: ... cbq bandwidth BPS avpkt BYTES [ mpu BYTES ]
               [ cell BYTES ] [ ewma LOG ]
xxx@xxx-OptiPlex-3080:~$ tc class add cbq help
Usage: ... cbq	bandwidth BPS rate BPS maxburst PKTS [ avpkt BYTES ]
		[ minburst PKTS ] [ bounded ] [ isolated ]
		[ allot BYTES ] [ mpu BYTES ] [ weight RATE ]
		[ prio NUMBER ] [ cell BYTES ] [ ewma LOG ]
		[ estimator INTERVAL TIME_CONSTANT ]
		[ split CLASSID ] [ defmap MASK/CHANGE ]
		[ overhead BYTES ] [ linklayer TYPE ]

HBQ 的qdiscs和classes命令格式如下:

xxx@xxx-OptiPlex-3080:~$ tc qdisc add htb help
What is "help"?
Usage: ... qdisc add ... htb [default N] [r2q N]
                      [direct_qlen P] [offload]
 default  minor id of class to which unclassified packets are sent {0}
 r2q      DRR quantums are computed as rate in Bps/r2q {10}
 debug    string of 16 numbers each 0-3 {0}

 direct_qlen  Limit of the direct queue {in packets}
 offload  enable hardware offload
... class add ... htb rate R1 [burst B1] [mpu B] [overhead O]
                      [prio P] [slot S] [pslot PS]
                      [ceil R2] [cburst B2] [mtu MTU] [quantum Q]
 rate     rate allocated to this class (class can still borrow)
 burst    max bytes burst which can be accumulated during idle period {computed}
 mpu      minimum packet size used in rate computations
 overhead per-packet size overhead used in rate computations
 linklay  adapting to a linklayer e.g. atm
 ceil     definite upper class rate (no borrows) {rate}
 cburst   burst but for ceil {computed}
 mtu      max packet size we create rate map for {1600}
 prio     priority of leaf; lower are served first {0}
 quantum  how much bytes to serve from leaf at once {use r2q}

TC HTB version 3.3
xxx@xxx-OptiPlex-3080:~$ tc class add htb help
Usage: ... qdisc add ... htb [default N] [r2q N]
                      [direct_qlen P] [offload]
 default  minor id of class to which unclassified packets are sent {0}
 r2q      DRR quantums are computed as rate in Bps/r2q {10}
 debug    string of 16 numbers each 0-3 {0}

 direct_qlen  Limit of the direct queue {in packets}
 offload  enable hardware offload
... class add ... htb rate R1 [burst B1] [mpu B] [overhead O]
                      [prio P] [slot S] [pslot PS]
                      [ceil R2] [cburst B2] [mtu MTU] [quantum Q]
 rate     rate allocated to this class (class can still borrow)
 burst    max bytes burst which can be accumulated during idle period {computed}
 mpu      minimum packet size used in rate computations
 overhead per-packet size overhead used in rate computations
 linklay  adapting to a linklayer e.g. atm
 ceil     definite upper class rate (no borrows) {rate}
 cburst   burst but for ceil {computed}
 mtu      max packet size we create rate map for {1600}
 prio     priority of leaf; lower are served first {0}
 quantum  how much bytes to serve from leaf at once {use r2q}

TC HTB version 3.3

Filters 是用于对数据流进行分类的。我们可以通过基于防火墙规则的fw classifier, 基于IP头的u32 classifier, route classifier或者rsvp/rsvp6 classifiers。

tc filter的命令格式如下:

xxx@xxx-OptiPlex-3080:~$ tc filter help
Usage: tc filter [ add | del | change | replace | show ] [ dev STRING ]
       tc filter [ add | del | change | replace | show ] [ block BLOCK_INDEX ]
       tc filter get dev STRING parent CLASSID protocol PROTO handle FILTERID pref PRIO FILTER_TYPE
       tc filter get block BLOCK_INDEX protocol PROTO handle FILTERID pref PRIO FILTER_TYPE
       [ pref PRIO ] protocol PROTO [ chain CHAIN_INDEX ]
       [ estimator INTERVAL TIME_CONSTANT ]
       [ root | ingress | egress | parent CLASSID ]
       [ handle FILTERID ] [ [ FILTER_TYPE ] [ help | OPTIONS ] ]

       tc filter show [ dev STRING ] [ root | ingress | egress | parent CLASSID ]
       tc filter show [ block BLOCK_INDEX ]
Where:
FILTER_TYPE := { rsvp | u32 | bpf | fw | route | etc. }
FILTERID := ... format depends on classifier, see there
OPTIONS := ... try tc filter add <desired FILTER_KIND> help

一般来说,最大的需求是根据源IP地址,目标IP地址,源端口,目标端口来对数据流进行分类,所以最常用的classifier是u32 classifier。本文中,我们会同时使用fw classifier和u32 classifier。

u32 classifier 的命令参数如下:

xxx@xxx-OptiPlex-3080:~$ tc filter add u32 help
Usage: ... u32 [ match SELECTOR ... ] [ link HTID ] [ classid CLASSID ]
               [ action ACTION_SPEC ] [ offset OFFSET_SPEC ]
               [ ht HTID ] [ hashkey HASHKEY_SPEC ]
               [ sample SAMPLE ] [skip_hw | skip_sw]
or         u32 divisor DIVISOR

Where: SELECTOR := SAMPLE SAMPLE ...
       SAMPLE := { ip | ip6 | udp | tcp | icmp | u{32|16|8} | mark }
                 SAMPLE_ARGS [ divisor DIVISOR ]
       FILTERID := X:Y:Z

NOTE: CLASSID is parsed at hexadecimal input.

fw classifier的命令参数格式如下:

wangsheng@wangsheng-OptiPlex-3080:~$ tc filter add fw help
Usage: ... fw [ classid CLASSID ] [ indev DEV ] [ action ACTION_SPEC ]
	CLASSID := Push matching packets to the class identified by CLASSID with format X:Y
		CLASSID is parsed as hexadecimal input.
	DEV := specify device for incoming device classification.
	ACTION_SPEC := Apply an action on matching packets.
	NOTE: handle is represented as HANDLE[/FWMASK].
		FWMASK is 0xffffffff by default.

3.1、一个详细配置例子

如下图,我们准备将10M带宽分给home-user, office和 另外一个网络三者去使用,如下图所示:
在这里插入图片描述

在这里插入图片描述
我们准备给home user 分配1Mbps带宽,给office分配4Mbps带宽,给另外一个网络分配5Mbps带宽。

3.1.1、下面我们看一下用CBQ如何来实现。

  1. 第一步,我们在eth1网卡下添加root qdisc:
tc qdisc add dev eth1 root handle 10: cbq bandwidth 100Mbit avpkt 1000

这条命令用于

  • 在设备eth1下增加一个Qdisc。
  • root这个参数表示这是一个root qdisc。
  • 然后把这个root qdisc的handle设置成10。
  • cbq 表示root qdics 的类型是cbq。
  • bandwidth设置带宽成100Mbps,表示当前网络接口上的网络的最大带宽
  • avpkt表示报文的平均长度为1000
  1. 第二步,创建child class
    这个子类是所有其它类的父节点。这个child class的带宽是等于root qdisc的带宽的,与网络最大可用带宽一至。
tc class add dev eth1 parent 10:0 classid 10:10 cbq bandwidth 100Mbit rate 100Mbit allot 1514 weight 10Mbit prio 5 maxburst 20 avpkt 1000 bounded
  • 配置child classes的parent class,它是10:0,在这里是指root class。

  • 配置classid 10:10

  • 可用带宽100Mbit

  • rate参数,限制可用带宽为100Mbps。

  • allot参数:定义一次当着class可以发送的数据量。

  • weight参数:是给CBQ使用的,CBQ会用这个参数和allot参数去计算一次可以发送的数据量,定义了以字节为单位的数据发送速率。

      注意本文中只用到了bandwidth, rate和weight三个参数, 如果你有其它参数的问题的话,请自行查阅http://www.lartc.org/howto/lartc.qdisc.classful.html#AEN939
    
  1. 第三步,针对这里的家用电脑,办公室和子网络,我们为它们各定义一个leaf classes, qdiscs 和 filters
  • 为家用电脑定义:
tc class add dev eth1 parent 10:10 classid 10:100 cbq bandwidth 100Mbit rate 1Mbit allot 1514 weight 128Kbit prio 5 maxburst 20 avpkt 1000 bounded
tc qdisc add dev eth1 parent 10:100 sfq quantum 1514b perturb 15
tc filter add dev eth1 parent 10:0 protocol ip prio 5 u32 match ip dst 1.1.1.1 flowid 10:100

我们先创建一个叫10:100的child class(这个class的rate是1Mbit, weight是128Kbit。然后,我们把一个sfq的qdisc和一个过滤目标地址为1.1.1.1的u32 filter挂在这个10:100的class下。 bounded参数表示这个class 10:100最大速率不会超过1Mbps。

  • 为办公室定义:
#the office
tc class add dev eth1 parent 10:10 classid 10:200 cbq bandwidth 100Mbit rate 4Mbit allot 1514 weight 512Kbit prio 5 maxburst 20 avpkt 1000 bounded
tc qdisc add dev eth1 parent 10:200 sfq quantum 1514b perturb 15
tc filter add dev eth1 parent 10:0 protocol ip prio 5 u32 match ip dst 1.1.2.0/24 flowid 10:200
  • 为子网络定义:
#the ISP
tc class add dev eth1 parent 10:10 classid 10:300 cbq bandwidth 100Mbit rate 5Mbit allot 1514 weight 640Kbit prio 5 maxburst 20 avpkt 1000 bounded
tc qdisc add dev eth1 parent 10:300 sfq quantum 1514b perturb 15
tc filter add dev eth1 parent 10:0 protocol ip prio 5 u32 match ip dst 1.1.1.2 flowid 10:300
tc filter add dev eth1 parent 10:0 protocol ip prio 5 u32 match ip dst 1.1.3.0/24 flowid 10:300

在子网终的例子里,我们可以看到,多个filters可以被加入到同一个class里。

  • 验证我们的配置
    使用tc class show dev eth1 命令来查看:
root@router:~# tc class show dev eth1
class cbq 10: root rate 100000Kbit (bounded,isolated) prio no-transmit
class cbq 10:100 parent 10:10 leaf 806e: rate 1000Kbit (bounded) prio 5
class cbq 10:10 parent 10: rate 100000Kbit (bounded) prio 5
class cbq 10:200 parent 10:10 leaf 806f: rate 4000Kbit (bounded) prio 5
class cbq 10:300 parent 10:10 leaf 8070: rate 5000Kbit (bounded) prio 5

现在我们可以看出来,class是用来做流量整形的,我们发送3个ping报文到1.1.1.1, 然后使用tc -s class show dev eth1命令去查看CBQ class是不是命中了这三个报文。

root@router:~# tc -s class show dev eth1 | fgrep -A 2 10:100
class cbq 10:100 parent 10:10 leaf 806e: rate 1000Kbit (bounded) prio 5
Sent 294 bytes 3 pkts (dropped 0, overlimits 0)
borrowed 0 overactions 0 avgidle 184151 undertime 0

我们可以看到,所有的配置都正常生效了。

3.1.2、下面我们看一下用HTB如何来实现。

  1. 删除之前添加的CBQ root qdisc:
root@router:~# tc qdisc del root dev eth1
  1. 添加HTB的root qdisc:
tc qdisc add dev eth1 root handle 10: htb
  1. 创建child class 10:10
tc class add dev eth1 parent 10:0 classid 10:10 htb rate 100Mbit
  1. 为家用电脑,办公室室和子网络创建class, qdisc和filter:
# home user
tc class add dev eth1 parent 10:10 classid 10:100 htb rate 1Mbit
tc qdisc add dev eth1 parent 10:100 sfq quantum 1514b perturb 15
tc filter add dev eth1 protocol ip parent 10:0 prio 5 u32 match ip dst 1.1.1.1 flowid 10:100

#the office
tc class add dev eth1 parent 10:10 classid 10:200 htb rate 4Mbit
tc qdisc add dev eth1 parent 10:200 sfq quantum 1514b perturb 15
tc filter add dev eth1 parent 10:0 protocol ip prio 5 u32 match ip dst 1.1.2.0/24 flowid 10:200

#the ISP
tc class add dev eth1 parent 10:10 classid 10:300 htb rate 5Mbit
tc qdisc add dev eth1 parent 10:300 sfq quantum 1514b perturb 15
tc filter add dev eth1 parent 10:0 protocol ip prio 5 u32 match ip dst 1.1.1.2 flowid 10:300
tc filter add dev eth1 parent 10:0 protocol ip prio 5 u32 match ip dst 1.1.3.0/24 flowid 10:300
  1. 用tc class show dev eth1确认配置
root@router:~# tc class show dev eth1
class htb 10:10 root rate 100000Kbit ceil 100000Kbit burst 126575b cburst 126575b
class htb 10:100 parent 10:10 leaf 8072: prio 0 rate 1000Kbit ceil 1000Kbit burst 2849b cburst 2849b
class htb 10:200 parent 10:10 leaf 8073: prio 0 rate 4000Kbit ceil 4000Kbit burst 6599b cburst 6599b
class htb 10:300 parent 10:10 leaf 8074: prio 0 rate 5000Kbit ceil 5000Kbit burst 7849b cburst 7849b
  1. 验证数据包是不是命中class
root@router:~# tc -s class show dev eth1 | fgrep -A 4 10:100
class htb 10:100 parent 10:10 leaf 8072: prio 0 rate 1000Kbit ceil
1000Kbit burst 2849b cburst 2849b
Sent 294 bytes 3 pkts (dropped 0, overlimits 0)
rate 24bit
lended: 3 borrowed: 0 giants: 0
tokens: 18048 ctokens: 18048

4、汇总

本文介绍了netfilter/iptables和iproute2。 我们如果想构建自己的防火墙的话,很重要的是理解报文是在哪里如何被分析的。所以在qdiscs工作在哪里这篇文章中,我们介绍了数据报文进入Linux后,是如何在filter, nat, mangle , raw这些table里转发的。使用iptables命令,我们可以在tables的chain里(append, insert, delete, list)规则,然后给命中这些规则的报文设置一个target (DROP, ACCEPT, REJECT, LOG) 来告诉Linux应该如何处理这些被规则命中的报文。
我们介绍了 iproute2的二个工具软件ip和tc。同时我们学习了Qdiscs的工作原理,并以CBQ和HTB这二种Qdiscs为例,讲述了如何 配置Qdiscs以实现QoS。

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

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

相关文章

【Flutter从入门到入坑之五】你真的会使用 Widget 中的 State 吗?

【Flutter从入门到入坑】Flutter 知识体系 【Flutter从入门到入坑之一】Flutter 介绍及安装使用 【Flutter从入门到入坑之二】Dart语言基础概述 【Flutter从入门到入坑之三】Flutter 是如何工作的 【Flutter从入门到入坑之四】构建Flutter界面的基石——Widget State 前沿UI 编…

2023 年 3 月青少年机器人技术等级考试理论综合试卷(一级)

2023 年 3 月青少年机器人技术等级考试理论综合试卷&#xff08;一级&#xff09; 一、单选题(共 30 题&#xff0c;共 60 分) 1.关于使用动滑轮说法正确的是&#xff1f;&#xff08; B&#xff09; A. 是否省力与动滑轮的颜色有关 B.可以改变力的大小 C.不能省力 D.动滑轮的位…

AUTOSAR知识点Com(十三):ComM内容分析

目录 1、概述 1.1、总览 1.2、功能描述 1.3、依赖关系 2、功能SPEC 2.1、PNC 2.2、通道状态机 2.3、时序图解析 3、COMM工具配置 3.1、ComMGeneral 3.2、ComMConfigSet 1、概述 1.1、总览 ComM的全程是Communication Manager 管理通信&#xff0c;是BSW里面的一个组…

关于大模型对未来影响的一点看法

人们总是高估了未来一到两年的变化&#xff0c;低估了未来十年的变革。 ---比尔盖茨 近来OpenAI的GPT技术可以说在全球都带来了巨大的影响&#xff0c;也让大家看到了什么叫大力出奇迹。chatGPT和GPT4的能力给了大家很大的震撼&#xff0c;其流畅自如、逻辑清晰、出众的能力&am…

【vscode远程开发】使用SSH远程连接服务器 「内网穿透」

文章目录 前言视频教程1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 转…

Rosetta从头蛋白抗体设计、结构优化及在药物研发中的应用

Rosetta从头蛋白抗体设计、结构优化及在药物研发中的应用 第一天 内容 主要知识点 从蛋白质折叠到蛋白质设计教学目标&#xff1a;了解本方向内容、理论基础、研究意义。 蛋白质折叠与结构预测简介 主链二面角与二级结构侧链堆积与三级结构蛋白质设计简介 蛋白质设计的分…

shell编程之条件语句__例题

文章目录 (1) 检查用户家目录中的test.sh文件是否存在&#xff0c;并且检查是否有执行权限. [rootclr /opt/mywork]# cat 1.sh #!/bin/bash #检查用户家目录中的 test.sh 文件是否存在&#xff0c;并且检查是否有执行权 cd /roottest -f test.shif [ $? -eq 0 ];thentest -x…

插件、组件、控件,你分得清吗?

最近和小伙伴交流&#xff0c;时常发生插件、组件、控件等概念混淆的情况&#xff0c;因此导致经常会错意。感觉还是很有必要带大家整理清楚的&#xff0c;今天就来跟大家来聊一聊插件、组件、控件的区别。 什么是插件 先按照官方的一些解释来看看插件的概念描述&#xff1f;…

搭建Debug(printf)Viewer调试环境

希望对KEIL开发的小白的有用&#xff0c;KEIL开发如果高效正确调用Printf 打印输出调试信息。 需要添加红色字体代码 #include <stdio.h> #define ITM_Port8(n) (*((volatile unsigned char *)(0xE00000004*n))) #define ITM_Port16(n) (*((volatile unsigned short *)(…

Android类似微信聊天页面教程(Kotlin)五——选择发送图片

前提条件 安装并配置好Android Studio Android Studio Electric Eel | 2022.1.1 Patch 2 Build #AI-221.6008.13.2211.9619390, built on February 17, 2023 Runtime version: 11.0.150-b2043.56-9505619 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 11 …

【模拟IC学习笔记】 负反馈系统的稳定性

反馈方程 输出方程 误差方程 环路增益 定义:当输入电压接地、并将环路断开时&#xff0c;所计算的增益就是环路增益 时&#xff08;幅度1&#xff0c;相位-180&#xff09;电路稳定在电源或低状态或在电源和地之间振荡。 分析稳定性时是对环路增益进行分析&#xff0c;通过环…

Java+Selenium+Testng自动化学习(一):环境搭建

目录 一、软件准备及版本介绍&#xff1a; 二、安装步骤及环境变量配置&#xff1a; 2.1 Java安装及配置 2.2 IDE工具&#xff08;Intellij IDEA&#xff09;安装及配置 2.3 Maven安装及配置 2.4 Maven本地仓库配置 2.5 Intellij IDEA配置mvn 一、软件…

全开放式时代来临,南卡OE带给你非同寻常的舒适和听觉感受

NANK南卡一直致力于深耕音频领域&#xff0c;不断创新&#xff0c;将于五月份发布全新形态的全开放式蓝牙耳机。相较于传统耳机&#xff0c;开放式蓝牙耳机除了佩戴零感舒适&#xff0c;还能在沉浸音乐的同时与外界保持沟通。南卡OE作为新推出的开放式蓝牙耳机&#xff0c;采用…

7年从测试废物到测试主管,如何从纯功能测试内卷中破局?

我大学学的计算机专业&#xff0c;有一点编程基础。我的软件测试职业开始和大多数测试人员一样&#xff0c;一开始在一家电商公司做软件功能测试。 大部分进入测试行业的朋友&#xff0c;最开始接触都是纯功能界面测试&#xff0c;随着工作年限&#xff0c;会接触到一些常用测试…

计算机体系结构总结:内存一致性模型 Memory consistency Model

存储一致性是为了保证多线程背景下的访存顺序&#xff0c;多线程的语句是可以交错执行&#xff0c;使得顺序不同产生不同的执行结果。 下面P2的输出结果可能是什么&#xff1f; P1, P2两个线程的语句是可以交叉执行的&#xff0c;比如1a, 2a, 2b, 1b&#xff1b;一个线程内的语…

网络基础学习:什么是网络与网络发展史

什么是网络与网络发展史 什么是网络&#xff1f;什么是网络发展史&#xff1f;分组交换技术TCP/IP技术Web技术ARPANET&#xff08;1969年&#xff09;Internet&#xff08;1983年&#xff09;万维网&#xff08;1990年&#xff09;移动互联网&#xff08;2007年&#xff09;物联…

Golang - GraphQL 搭配 Database

介绍 上一篇我们用GraphQL 已经有个基本的认识 接着来模拟真实的情境搭配Database 来使用 这篇主要都是在初始化环境 示例代码 通过 Docker 设置 MySQL 数据库 从 DockerHub 拉取 MySQL 镜像docker pull mysql 创建MySQL数据库 $ docker exec -it mysql bash $ mysql -u …

Python代码学习之给图片添加文字或图片水印

前言 图片加水印有什么好处&#xff1f;在现今的数字化时代&#xff0c;网络上的图片泛滥&#xff0c;盗图现象也越来越严重。因此&#xff0c;在发布文章时&#xff0c;为了保护自己的原创作品版权&#xff0c;很多人选择使用水印来保护他们的图片。这样就能更好地做到&#…

Java基础(十九)反射机制

1. 反射(Reflection)的概念 1.1 反射的出现背景 Java程序中&#xff0c;所有的对象都有两种类型&#xff1a;编译时类型和运行时类型&#xff0c;而很多时候对象的编译时类型和运行时类型不一致。 Object obj new String(“hello”); obj.getClass() 例如&#xff1a;某些变…

ChatGPT技术如何助力汽车门店销售服务水平提升?

过往&#xff0c;由于线下销售过程没有数字化记录&#xff0c;销售顾问的销讲要点执行情况、客户在体验展车、试乘试驾等过程中的反馈&#xff0c;没法真实全面地记录下来&#xff0c;因此很难做精细化的销售管理和客户心声分析。销售沟通过程不透明、员工服务质量难评估。 在…