【動手實驗】發送接收窗口對 TCP傳輸性能的影響

環境準備

服務器信息

兩臺騰訊云機器 t04(172.19.0.4)、t11(172.19.0.11),系統為 Ubuntu 22.04,內核為 5.15.0-139-generic。默認 RT 在 0.16s 左右。

$ ping 172.19.0.4
PING 172.19.0.4 (172.19.0.4) 56(84) bytes of data.
64 bytes from 172.19.0.4: icmp_seq=1 ttl=64 time=0.195 ms
64 bytes from 172.19.0.4: icmp_seq=2 ttl=64 time=0.216 ms
64 bytes from 172.19.0.4: icmp_seq=3 ttl=64 time=0.253 ms
64 bytes from 172.19.0.4: icmp_seq=4 ttl=64 time=0.158 ms
64 bytes from 172.19.0.4: icmp_seq=5 ttl=64 time=0.164 ms
64 bytes from 172.19.0.4: icmp_seq=6 ttl=64 time=0.139 ms
64 bytes from 172.19.0.4: icmp_seq=7 ttl=64 time=0.134 ms
64 bytes from 172.19.0.4: icmp_seq=8 ttl=64 time=0.153 ms
64 bytes from 172.19.0.4: icmp_seq=9 ttl=64 time=0.157 ms
64 bytes from 172.19.0.4: icmp_seq=10 ttl=64 time=0.149 ms
64 bytes from 172.19.0.4: icmp_seq=11 ttl=64 time=0.148 ms
64 bytes from 172.19.0.4: icmp_seq=12 ttl=64 time=0.157 ms
64 bytes from 172.19.0.4: icmp_seq=13 ttl=64 time=0.151 ms
64 bytes from 172.19.0.4: icmp_seq=14 ttl=64 time=0.156 ms
64 bytes from 172.19.0.4: icmp_seq=15 ttl=64 time=0.156 ms
64 bytes from 172.19.0.4: icmp_seq=16 ttl=64 time=0.160 ms
64 bytes from 172.19.0.4: icmp_seq=17 ttl=64 time=0.159 ms
^C
--- 172.19.0.4 ping statistics ---
17 packets transmitted, 17 received, 0% packet loss, time 16382ms
rtt min/avg/max/mdev = 0.134/0.165/0.253/0.028 ms

內核參數信息

內核默認參數值

$ sudo sysctl -a | egrep "rmem|wmem|tcp_mem|adv_win|moderate"
net.core.rmem_default = 212992
net.core.rmem_max = 212992
net.core.wmem_default = 212992
net.core.wmem_max = 212992
net.ipv4.tcp_adv_win_scale = 1
net.ipv4.tcp_mem = 41295	55062	82590
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_rmem = 4096	131072	6291456
net.ipv4.tcp_wmem = 4096	16384	4194304
net.ipv4.udp_rmem_min = 4096
net.ipv4.udp_wmem_min = 4096
vm.lowmem_reserve_ratio = 256	256	32	0	0

參數含義如下:

  • 核心網絡參數 (net.core.)
參數名稱作用范圍默認行為約束關系配置值影響
net.core.rmem_default所有協議套接字未設置SO_RCVBUF時的默認接收緩沖區UDP默認值,TCP有專門設置時被覆蓋212992 (208KB)UDP接收緩沖區默認208KB
net.core.rmem_max所有協議套接字接收緩沖區的硬性上限覆蓋所有協議的max設置212992 (208KB)嚴重限制:TCP最大6MB被壓縮到208KB
net.core.wmem_default所有協議套接字未設置SO_SNDBUF時的默認發送緩沖區UDP默認值,TCP有專門設置時被覆蓋212992 (208KB)UDP發送緩沖區默認208KB
net.core.wmem_max所有協議套接字發送緩沖區的硬性上限覆蓋所有協議的max設置212992 (208KB)嚴重限制:TCP最大4MB被壓縮到208KB
  • TCP專用參數 (net.ipv4.tcp_)
參數名稱作用范圍格式說明約束關系配置值實際效果
net.ipv4.tcp_rmem僅TCP連接[最小值 默認值 最大值]net.core.rmem_max硬性限制4096 131072 6291456最小4KB,默認128KB,最大被限制到208KB
net.ipv4.tcp_wmem僅TCP連接[最小值 默認值 最大值]net.core.wmem_max硬性限制4096 16384 4194304最小4KB,默認16KB,最大被限制到208KB
net.ipv4.tcp_mem全局TCP內存池[低水位 壓力位 高水位] (頁)獨立于單連接緩沖區設置41295 55062 82590全局限制161MB-215MB-323MB
net.ipv4.tcp_moderate_rcvbufTCP動態調整0=關閉,1=開啟在tcp_rmem范圍內動態調整1開啟動態調整,但被208KB限制
net.ipv4.tcp_adv_win_scaleTCP窗口計算整數值影響TCP窗口大小算法1適中的窗口縮放因子
  • UDP專用參數 (net.ipv4.udp_)
參數名稱作用范圍含義約束關系配置值實際效果
net.ipv4.udp_rmem_min僅UDP連接UDP接收緩沖區最小值net.core.rmem_max限制4096UDP最小接收緩沖區4KB
net.ipv4.udp_wmem_min僅UDP連接UDP發送緩沖區最小值net.core.wmem_max限制4096UDP最小發送緩沖區4KB
  • 內存管理參數 (vm.)
參數名稱作用范圍含義配置值影響
vm.lowmem_reserve_ratio系統內存管理各內存區域預留比例256 256 32 0 0防止內存區域被耗盡

上述參數結合 Socket 編程,對緩沖區的影響如下:

  • TCP Socket緩沖區行為
場景接收緩沖區 (SO_RCVBUF)發送緩沖區 (SO_SNDBUF)
不調用setsockopt()默認:131072 (128KB)默認:16384 (16KB)
調用setsockopt(1MB)實際:~425984 (208KB×2)實際:~425984 (208KB×2)
調用setsockopt(100KB)實際:~200KB (100KB×2)實際:~200KB (100KB×2)
動態調整范圍4KB - 208KB (被限制)4KB - 208KB (被限制)
  • UDP Socket緩沖區行為
場景接收緩沖區 (SO_RCVBUF)發送緩沖區 (SO_SNDBUF)
不調用setsockopt()默認:212992 (208KB)默認:212992 (208KB)
調用setsockopt(1MB)實際:~425984 (208KB×2)實際:~425984 (208KB×2)
最小值保證不低于4KB不低于4KB
  • 參數間的優先級關系
1. net.core.*_max (硬性上限,覆蓋一切)↓
2. net.ipv4.tcp_*mem (TCP專用設置)↓  
3. net.ipv4.udp_*mem (UDP專用設置)↓
4. net.core.*_default (通用默認值)↓
5. 應用程序setsockopt()調用

服務端啟動

下面是生成測試文件和啟動服務端的命令。

# 創建測試文件
# ubuntu @ t04 in ~/labs/01-bdp-tcp [10:32:12]
$ dd if=/dev/zero of=testfile  bs=1M count=2048
2048+0 records in
2048+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 8.3587 s, 257 MB/s# ubuntu @ t04 in ~/labs/01-bdp-tcp [10:32:30]
$ ll
total 2.1G
-rw-rw-r-- 1 ubuntu ubuntu 2.0G Jul 15 10:32 testfile# 啟動服務端
# ubuntu @ t04 in ~/labs/01-bdp-tcp [10:32:50] C:1
$ python3 -m http.server 8089
Serving HTTP on 0.0.0.0 port 8089 (http://0.0.0.0:8089/) ...$ netstat -antp | grep 8089
tcp        0      0 0.0.0.0:8089            0.0.0.0:*               LISTEN      12808/python3

實驗分析

環境準備好有,我們利用 tc 工具調整 rtt、丟包率以及調節發送接收緩沖大小,來看下不同情況下的數據傳輸效率。

1. 默認 mem ,默認延遲

首先不做任何改動,內網下載 2GB 的文件,耗時 14s,吞吐為 975Mbps。

2. 默認 mem,100ms 延遲

我們用 tc 將延遲增加到 100ms:

# 服務端機器添加 100ms 延遲
# ubuntu @ t04 in ~
$ sudo tc qdisc add dev eth0 root netem delay 100ms# 添加完成后客戶端執行 ping 操作,延遲已經變成 100ms 了。
# ubuntu @ t11 in ~ [10:10:05]
$ ping 172.19.0.4
PING 172.19.0.4 (172.19.0.4) 56(84) bytes of data.
64 bytes from 172.19.0.4: icmp_seq=1 ttl=64 time=100 ms
64 bytes from 172.19.0.4: icmp_seq=2 ttl=64 time=100 ms

再次執行下載并抓包,結果如下:

$ curl 172.19.0.4:8089/testfile > testfile% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100 2048M  100 2048M    0     0  27.4M      0  0:01:14  0:01:14 --:--:-- 27.0M

可以看到整個下載耗時為 1 分 14s,吞吐為 229Mbps,和默認延遲相比,傳輸速度慢了不少,打開 tcptrace 查看傳輸過程,可以看到每 100ms 會暫停一次,因為服務端要等到 ack 后才會滑動窗口繼續發送數據。

3. 默認 mem,默認延遲,1% 與 20% 丟包

服務端設置 1% 的丟包率

# ubuntu @ t04 in ~
sudo tc qdisc add dev eth0 root netem loss 1%

再次執行下載并抓包,結果如下:

$ curl 172.19.0.4:8089/testfile > testfile% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100 2048M  100 2048M    0     0   185M      0  0:00:11  0:00:11 --:--:--  255M


可以看到整體耗時 10s,平均吞吐為 185MBps。因為帶寬足夠并且 RT 非常小, 雖然引發了重傳,但并沒有導致擁塞窗口的減少,整體的傳輸速度沒有受到明顯的影響。

我們將丟包率調大到 20% 再次執行下載并抓包

$ curl 172.19.0.4:8089/testfile > testfile% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed0 2048M    0 15.0M    0     0   579k      0  1:00:20  0:00:26  0:59:54  410k

這次下載耗時預計達到了 1 個小時,傳輸過程查看 cwnd 可以看到已經縮小到了 1。

$ while true; do sudo ss -ti sport =  :8089 ; sleep 1; done;
State        Recv-Q        Send-Q                Local Address:Port                 Peer Address:Port         Process
ESTAB        0             33792                    172.19.0.4:8089                  172.19.0.11:46002cubic wscale:7,7 rto:204 rtt:0.325/0.358 ato:40 mss:8448 pmtu:8500 rcvmss:536 advmss:8448 cwnd:1 ssthresh:2 bytes_sent:47062993 bytes_retrans:9648128 bytes_acked:37397969 bytes_received:87 segs_out:5623 segs_in:3496 data_segs_out:5622 data_segs_in:1 send 208Mbps lastsnd:172 lastrcv:91576 lastack:172 pacing_rate 499Mbps delivery_rate 520Mbps delivered:4472 busy:91572ms sndbuf_limited:9616ms(10.5%) unacked:2 retrans:1/1150 lost:1 sacked:1 rcv_space:57076 rcv_ssthresh:57076 notsent:16896 minrtt:0.067
State        Recv-Q        Send-Q                Local Address:Port                 Peer Address:Port         Process
ESTAB        0             59136                    172.19.0.4:8089                  172.19.0.11:46002cubic wscale:7,7 rto:408 backoff:1 rtt:0.648/1.036 ato:40 mss:8448 pmtu:8500 rcvmss:536 advmss:8448 cwnd:1 ssthresh:2 bytes_sent:47919057 bytes_retrans:9800192 bytes_acked:38093521 bytes_received:87 segs_out:5725 segs_in:3559 data_segs_out:5724 data_segs_in:1 send 104Mbps lastsnd:48 lastrcv:92592 lastack:260 pacing_rate 375Mbps delivery_rate 814Mbps delivered:4556 busy:92588ms sndbuf_limited:9828ms(10.6%) unacked:3 retrans:1/1168 lost:1 sacked:2 rcv_space:57076 rcv_ssthresh:57076 notsent:33792 minrtt:0.067
State        Recv-Q        Send-Q                Local Address:Port                 Peer Address:Port         Process
ESTAB        0             8448                     172.19.0.4:8089                  172.19.0.11:46002cubic wscale:7,7 rto:204 rtt:0.41/0.467 ato:40 mss:8448 pmtu:8500 rcvmss:536 advmss:8448 cwnd:2 ssthresh:2 bytes_sent:48088017 bytes_retrans:9850880 bytes_acked:38228689 bytes_received:87 segs_out:5745 segs_in:3571 data_segs_out:5744 data_segs_in:1 send 330Mbps lastsnd:16 lastrcv:93604 lastack:16 pacing_rate 395Mbps delivery_rate 845Mbps delivered:4570 busy:93600ms sndbuf_limited:9828ms(10.5%) unacked:1 retrans:0/1174 rcv_space:57076 rcv_ssthresh:57076 minrtt:0.067
State        Recv-Q        Send-Q                Local Address:Port                 Peer Address:Port         Process
ESTAB        0             25344                    172.19.0.4:8089                  172.19.0.11:46002cubic wscale:7,7 rto:204 rtt:0.219/0.218 ato:40 mss:8448 pmtu:8500 rcvmss:536 advmss:8448 cwnd:1 ssthresh:2 bytes_sent:48483281 bytes_retrans:9926912 bytes_acked:38531025 bytes_received:87 segs_out:5792 segs_in:3601 data_segs_out:5791 data_segs_in:1 send 309Mbps lastsnd:184 lastrcv:94616 lastack:184 pacing_rate 1.11Gbps delivery_rate 583Mbps delivered:4608 busy:94612ms sndbuf_limited:9828ms(10.4%) unacked:3 retrans:1/1183 lost:1 sacked:2 rcv_space:57076 rcv_ssthresh:57076 minrtt:0.067

分析抓包文件,可以看到吞吐會周期性斷崖式下跌然后在緩慢爬升。

在丟包時,接收端收到的包會亂序,會影響其 ACK 響應的速度,導致某些包在緩沖區中多等待一會,因此接收窗口也會間歇性的下降,并在收到重傳包后恢復。

4. 默認 mem 和延遲,BBR 算法,20% 丟包

服務器默認使用的是 cubic 算法,受丟包影響較大,我們將算法改為 bbr 算法在測試下傳輸性能。

首先啟用 BBR 擁塞控制算法:

$ sudo modprobe tcp_bbr
$ sudo sysctl -w net.ipv4.tcp_congestion_control=bbr

BBR 算法推薦結合 fq 調度算法使用,實驗環境默認的是 fq_codel,我們利用 tc 來設置 fq 以及 20% 的丟包率,命令如下:

$ sudo tc qdisc add dev eth0 root handle 1: netem loss 20%# ubuntu @ t04 in ~/labs/01-bdp-tcp [12:09:13]
$ sudo tc qdisc add dev eth0 parent 1: handle 2: fq

完成后再次執行下載并抓包,結果如下:

$ curl 172.19.0.4:8089/testfile > testfile% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100 2048M  100 2048M    0     0  84.1M      0  0:00:24  0:00:24 --:--:--  140M

我們直接利用 tc 將擁塞控制算法設置為 bbr 并設置 20

  1. 默認 mem,默認延遲,bbr 算法,20% 丟包
$ curl 172.19.0.4:8089/testfile > testfile% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100 2048M  100 2048M    0     0  84.1M      0  0:00:24  0:00:24 --:--:--  140M$ sudo tc qdisc add dev eth0 root handle 1: netem loss 20%# ubuntu @ t04 in ~/labs/01-bdp-tcp [12:09:13]
$ sudo tc qdisc add dev eth0 parent 1: handle 2: fq# ubuntu @ t04 in ~/labs/01-bdp-tcp [12:09:20]
$ sudo tc qdisc show dev eth0
qdisc netem 1: root refcnt 3 limit 1000 loss 20%
qdisc fq 2: parent 1: limit 10000p flow_limit 100p buckets 1024 orphan_mask 1023 quantum 17028b initial_quantum 85140b low_rate_threshold 550Kbit refill_delay 40ms timer_slack 10us horizon 10s horizon_drop
5. 客戶端 recvbuf 為 4Kb,默認延遲

我們將客戶端的 recvbuf 設置為 4Kb。

$ sudo sysctl -w "net.ipv4.tcp_rmem=4096        4096      4096"

在默認延遲下執行下載,抓包如下:

$ curl 172.19.0.4:8089/testfile > testfile% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100 2048M  100 2048M    0     0  14.8M      0  0:02:18  0:02:18 --:--:-- 14.8M

總體耗時兩分多鐘,抓包可以看到有大量 Window Full 的情況,但內網 RT 非常小,因此空出來后可以很快的通知給服務端,對整體傳輸速率的性能不算太大。

查看傳輸過程,可以看到大約每 40ms 接收窗口會上升,Linux 內核有一個宏定義來設置延遲確認的最小時間為 40ms,推測應該是 delayed ack 起了作用。

# https://elixir.bootlin.com/linux/v5.15.130/source/include/net/tcp.h#L135
# define TCP_DELACK_MIN	((unsigned)(HZ/25))	/* minimal time to delay before sending an ACK */
6. 客戶端 recvbuf 為 4Kb,100ms 延遲

將延遲增加到 100ms 后,整體傳輸時間預計需要 29 小時,這種情況下,數據只能一點點發,而且耗時還比較長,整體傳輸速度變得巨慢無比。

$ sudo tc qdisc add dev eth0 root netem delay 100ms$ curl 172.19.0.4:8089/testfile > testfile% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed0 2048M    0 2789k    0     0  20419      0 29:12:50  0:02:19 29:10:31 20451
7. 服務端 sendbuf 為 4Kb,默認延遲

下載時間只需要 10 幾秒,對性能沒有明顯影響。雖然發送 buffer 小,但因為 rtt 也很小,ACK 包能很快回來可以立即釋放 wmem,因此對速度影響不大。好比即使我們只有兩輛貨車,但裝貨發貨非常快,貨車卸完貨能立馬回來繼續拉,整體運貨速度也是有保證的,但如果卸貨賊慢或者貨車路上跑的賊慢,整體發貨效率也提不上去。

$ curl 172.19.0.4:8089/testfile > testfile% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100 2048M  100 2048M    0     0   164M      0  0:00:12  0:00:12 --:--:--  195M

這里可以和實驗 5 做對比,在默認延遲下修改 recvbuf 和 sendbuf,可以看到修改 recvbuf 對性能的影響更加明顯。都是 RT 很小,但 server 端收到 ACK 后 sendbuf 清理出空間,可以立即發送,是內存級別的演示;但接收端在有 recvbuf 有空間后返回 ACK 到服務端,是網絡通信級別的延遲,兩者相差幾個數量級。

圖片來自 ## TCP性能和發送接收窗口、Buffer的關系

8. 服務端 sendbuf 為 4Kb,100ms 延遲

將延遲增大到 100ms 后,下載時間預計需要 1 小時 37 分鐘,整體效率下降了很多。

$ curl 172.19.0.4:8089/testfile > testfile% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed0 2048M    0 17.4M    0     0   357k      0  1:37:50  0:00:49  1:37:01  366k

抓包查看傳輸過程,可以看到整體傳輸過程是非常絲滑的,放大后看每 100ms 窗口才會增大,性能就是受 RT 的影響一直上不去。

性能問題復現

這里我們模擬任總遇到的場景,假設我們的帶寬是 500Mbps,RT 為 10ms,通過調整發送 buffer 來優化發送效率。

BDP(Bandwidth-Delay Product) 帶寬時延積

首先要理解一個概念帶寬時延積:

Bandwidth-delay product (BDP)

Product of data link’s capacity and its end-to-end delay. The result is the maximum amount of unacknowledged data that can be in flight at any point in time.

《High Performance Browser Networking》

圖片來自 High Performance Browser Networking

其含義就是整個傳輸鏈路上可以傳輸的最大數據,TCP 性能優化的一個關鍵點就是發送的數據要填滿 BDP,從而充分利用帶寬。就好比我們用貨車拉貨時,要盡可能將貨車裝滿才能最大化其運力。

回我們 500Mbps 帶寬,10ms RT 的場景,我們先來計算下 BDP 是 625KB,這意味著我們能夠一下子發出 625KB 時才能最大化的利用網絡帶寬,對應到發送端的優化,則是將發送窗口大小設置為 BDP。

500Mbit/s * 0.01s = 5Mbits
# 轉為 byte
5 * 10^6 bits / 8 = 625,000 bytes
# 轉為 KB
625,000 bytes / 1000 = 625KB

在其他條件都滿足的情況下,傳輸一個 512MB 大小的文件,理想傳輸速度大約為 8~10s 左右。下面是調整 sendbuf 后所得到的下載 512MB 大小文件的速度:

下面是調整 sendbuf 后所得到的下載 512MB 大小文件的速度:

  • sendbuf 為 100KB,下載時長 56s.
$ curl 172.19.0.4:8089/testfile > testfile% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100  512M  100  512M    0     0  9350k      0  0:00:56  0:00:56 --:--:-- 9363k
  • sendbuf 為 200KB,下載時長 24s。
$ curl 172.19.0.4:8089/testfile > /dev/null% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100  512M  100  512M    0     0  21.0M      0  0:00:24  0:00:24 --:--:-- 21.0M
  • sendbuf 為 700KB 或者 100KB,下載速度均為 8 ~ 9s。
$ curl 172.19.0.4:8089/testfile > /dev/null% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100  512M  100  512M    0     0  58.4M      0  0:00:08  0:00:08 --:--:-- 58.7M

簡要總結

整體來看,要想 TCP 數據傳輸的快,需要滿足三個條件:

  • 發得快:發送端窗口足夠,能填滿 BDP,數據發送快。
  • 傳得快:網絡環境好,帶寬大、RT 小、丟包率低。
  • 收的快:接收端數據處理快,接收窗口大。

在實際工作場景中,需要結合具體場景探查性能問題出現在哪一點,然后在尋找針對性的優化方案。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/89580.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/89580.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/89580.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

28、鴻蒙Harmony Next開發:不依賴UI組件的全局氣泡提示 (openPopup)和不依賴UI組件的全局菜單 (openMenu)、Toast

目錄 不依賴UI組件的全局氣泡提示 (openPopup) 彈出氣泡 創建ComponentContent 綁定組件信息 設置彈出氣泡樣式 更新氣泡樣式 關閉氣泡 在HAR包中使用全局氣泡提示 不依賴UI組件的全局菜單 (openMenu) 彈出菜單 創建ComponentContent 綁定組件信息 設置彈出菜單樣…

讓老舊醫療設備“聽懂”新語言:CAN轉EtherCAT的醫療行業應用

在醫療影像設備的智能化升級中,通信協議的兼容性常成為工程師的“痛點”。例如,某醫院的移動式X射線機采用CAN協議控制機械臂,而主控系統基于EtherCAT架構。兩者協議差異導致數據延遲高達5ms,影像定位精度下降,甚至影響…

ubuntu基礎搭建

ubuntu上docker的搭建 https://vulhub.org/zh 網站最下面找到開始使用,有搭建的命令//安裝docker,連接失敗多試幾次 curl -fsSL https://get.docker.com | sh //驗證Docker是否正確安裝: docker version //還要驗證Docker Compose是否可用&am…

動態規劃 + DFS + 記憶化!Swift 解 LeetCode 329 的實戰筆記

文章目錄摘要描述題解答案題解代碼分析代碼解析示例測試及結果時間復雜度空間復雜度總結摘要 這篇文章帶你用 Swift 實戰一道非常經典的 DFS 記憶化搜索題目 —— LeetCode 329《矩陣中的最長遞增路徑》。看似一個簡單的“走格子”游戲,實則考察了搜索順序、剪枝策…

046_局部內部類與匿名內部類

一、局部內部類(Local Inner Class) 1.1 定義與基本概念 局部內部類是定義在方法、構造器或代碼塊內部的類,其作用域僅限于所在的局部范圍(定義它的方法、構造器或代碼塊),超出該范圍則無法訪問。 它的核心…

Jenkins Pipeline 中使用 JsonSlurper 報錯:cannot find current thread

Jenkins Pipeline 中使用 JsonSlurper 報錯:cannot find current thread🌟 背景? 問題重現🧠 原因解析:CPS 與非 CPS 安全方法沖突? 解決方案一:使用 NonCPS 注解(經典方案)? 解決方案二&…

Go 語言循環語句詳解

Go 語言循環語句詳解 在編程語言中,循環語句是實現重復執行某些代碼塊的關鍵元素。Go 語言作為現代編程語言之一,提供了多種循環結構來滿足不同的編程需求。本文將詳細講解 Go 語言中的循環語句,包括 for、while 和 goto 語句,幫助…

day30——零基礎學嵌入式之進程間通信1.0

一、進程間通信7種方式1.傳統的進程間通信方式(1)管道①無名管道:②有名管道:(2)③信號(3)system Ⅴ 》系統Ⅴ 進程間通信方式 inner Process Comunication④共享內存 &#xff…

408考研逐題詳解:2010年第33題——網絡體系結構

2010年第33題 下列選項中,不屬于網絡體系結構所描述的內容是( ) A. 網絡的層次 \qquad B. 每層使用的協議 \qquad C. 協議的內部實現細節 \qquad D. 每層必須完成的功能 解析 本題屬于計算機網絡基礎知識的范疇,考查網絡體系結構…

VR 遠程系統的沉浸式協作體驗?

在傳統的遠程協作中,團隊成員往往通過二維的視頻畫面進行交流,這種方式雖然能實現基本的溝通,但缺乏真實感和互動性。而 VR 遠程系統的出現,徹底改變了這一局面。戴上 VR 設備,員工們仿佛置身于同一個真實的辦公室空間…

記錄DataGrip 2025.1.3破解失敗后,無法重啟問題修復

記錄DataGrip 2025.1.3破解失敗后,無法重啟問題修復安裝過程復盤異常場景解決方式總結安裝過程 在官網下載了最新版本2025.1.3。安裝成功后,使用30天試用方式,打開datagrip。 復盤異常場景 網上搜索破解教程進行破解。找了一個需要現在ja…

私有服務器AI智能體搭建配置選擇記錄

在搭建私有服務器上的AI智能體時,需要從多個方面進行選擇和規劃,以確保系統性能、安全性、可擴展性等方面滿足需求。1. 硬件選擇 服務器配置: CPU:選擇高性能多核CPU(如Intel Xeon或AMD EPYC系列)&#xff…

SDC Specical check setting的描述 - false path

在上一篇文中描述了SDC的基本語法,其中關于時序異常約束并沒有進行詳細的描述,但是在正常的設計中,一般這種異常的設置反而是需要特別關注的,主要包括:1. 虛假路徑- false path不需要滿足任何時序要求的路徑&#xff1…

【Python練習】048. 編寫一個函數,實現簡單的命令行接口,接受用戶輸入并響應

048. 編寫一個函數,實現簡單的命令行接口,接受用戶輸入并響應 在 Python 中,可以通過 input() 函數創建一個簡單的命令行接口,接受用戶輸入并根據輸入內容進行響應。 示例代碼 def simple_command_line_interface():"""實現一個簡單的命令行接口,接受用…

軟件工廠語境下的知識系統選型:兼顧合規性與集成深度

在過去幾十年間,制造業從“工匠手作”邁向“工業流水線”,完成了生產效率的巨大飛躍。當軟件開發也面臨交付復雜性、合規要求與協作成本不斷上升的現實,“軟件工廠”的理念逐步興起。 在這場“開發現代化”的轉型中,知識管理被重新…

C語言-一維數組,二維數組

數組 數組的引入如果要在程序中保存一個人的年齡?如何保存? 答:創建一個基于int類型的變量,舉例:int age 22如果要在程序中保存一個人的三門課的成績?如何保存? 答:創建三個基于flo…

如何區別HTML和HTML5?

要區分 HTML&#xff08;通常指 HTML4 及更早版本&#xff09;和 HTML5&#xff0c;主要可以從以下關鍵方面進行比較&#xff1a;一、文檔聲明區別 <!-- HTML4 文檔聲明 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http:/…

Java實戰:實時聊天應用開發(附GitHub鏈接)

一、前置技術項目介紹&#xff1a; 項目為局域網溝通軟件&#xff0c;類似內網通&#xff0c;核心功能包括昵稱輸入、聊天界面展示在線人數&#xff08;實時更新&#xff09;、群聊&#xff0c;也可擴展私聊、登錄注冊、聊天記錄存儲等功能&#xff0c;結尾附GitHub鏈接。項目涉…

linux 的list_for_each_entry

linux的宏定義提高了代碼的簡潔性&#xff0c;但有時候的命名不夠完美。比如list_for_each_entry&#xff0c;看名字只知道是遍歷list&#xff0c;但一看里面的三個變量參數&#xff0c;有點懵逼。/*** list_for_each_entry - iterate over list of given type* pos: …

分布式面試點

目錄 1.分布式理論 為什么CAP不可兼得呢? 2.CAP對應的模型和應用 3.Base理論 4,有哪些分布式鎖的案例 5.分布式事務 6.Seata 分布式一致性算法 1. 準備階段&#xff08;Prepare Phase&#xff09; 2. 接受階段&#xff08;Accept Phase&#xff09; 3. 學習階段&…