python进阶篇-day05-网络编程(TCP)与进程

news2024/11/14 21:41:22

day05网络编程

一. 网编三要素

ip

概述

设备(电脑, 手机, IPad, 耳机...)在网络中的唯一标识.

分类

按照 代数 划分:

IPv4: 4字节, 十进制来表示, 例如: 192.168.13.157 IPv6: 8字节, 十六进制来表示, 理论上来讲, 可以让地球上的每一粒沙子都有自己的IP.

Ipv4 常用类别划分:

​ 城域网: 第1段是网络地址 + 后3段是主机地址, 例如: 10.0.0.0 广域网: 前2段是网络地址 + 后2段是主机地址, 例如: 10.21.0.0 局域网: 前3段是网络地址 + 后1段是主机地址, 例如: 192.168.13.*

IP相关命令

查看本机的IP: ipconfig 适用于 windows系统 ifconfig 适用于 linux系统, Mac系统测试网络连接是否通畅: ping 主机地址 或者 域名

端口号

端口:

传输数据的通道, 每个程序都有

端口号:

应用程序在设备中的唯一标识

范围:

所有范围: 0 ~ 65535, 但是0 ~ 1023已经被占用(或预留端口),

​ 自己用1024 ~ 65535

协议

UDP: 类似于群聊

  1. 面向无连接

  2. 采用数据包的形式传输数据, 有大小限制(每个包不超过64KB)

  3. 不安全(不可靠)协议

  4. 效率相对较低

  5. 不区分客户端和服务端, 叫: 发送端和接收端

TCP: 类似于打电话

  1. 面向有连接的

  2. 采用 流的方式传输数据, 理论上无大小限制

  3. 安全(可靠)协议

  4. 效率相对较低

  5. 区分客户端和服务器端

查看端口号和协议

netstat -ano

面试题

三次握手

自己:

  1. 客户端请求建立连接

  2. 服务器处理(校验客户端数据是否合法)并发送是否可以建立连接

  3. 服务器允许建立连接 , 客户端重新请求建立连接通道

讲义:

  1. 客户端向服务端发送请求,等待服务端确认。

  2. 服务端收到请求后知道客户端请求建立连接,回复给客户端以确认连接请求。

  3. 客户端收到确认后,再次发送请求确认服务端,服务端收到正确请求后,如果正确则连接建立成功,完成三次握手,随后客户端与服务端之间可以开始传输数据了。

四次挥手

讲义:

  1. 当主机A(可以是客户端也可以是服务端)完成数据传输后, 提出停止TCP连接的请求

  2. 第二次挥手: 主机B收到请求后对其作出响应,确认这一方向上的TCP连接将关闭

  3. 第三次挥手: 主机B 端再提出反方向的连接关闭请求

  4. 第四次挥手: 主机A对主机B 的请求进行确认,双方向的关闭结束

图解

二. socket套接字

进程之间通信工具

原理

网络通信也叫套接字通信, Socket通信, 即: 通信双方都有自己的Socket对象, 数据在两个Socket之间通过 数据报包 或者 流(字节流) 的方式传输数据

步骤

图解

客户端

步骤
  1. 创建客户端Socket对象.

  2. 连接(服务器端的)ip和端口号, 元组形式.

  3. 发送数据给服务器端.

  4. 接受服务器端发送的数据. 回执信息.

  5. 释放资源.

代码

127.0.0.1 本地回路(回环)地址, 即: 在哪台计算机上运行, 就代表哪台电脑. 简单理解: 代表本机.

import socket
​
# 在main中测试.
if __name__ == '__main__':
    # 1. 创建客户端Socket对象, 指定: 地址族, 传输类型.
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2. 连接(服务器端)地址和端口.
    # client_socket.connect(("127.0.0.1", 2121))
    client_socket.connect(("192.168.13.157", 2121))
    # 3. 接受服务器端发送的数据并打印.
    # 分解版
    # recv_data_bys = client_socket.recv(1024)
    # recv_data = recv_data_bys.decode("utf-8")
    # 合并版
    recv_data = client_socket.recv(1024).decode("utf-8")
    print(f'客户端收到: {recv_data}')
    # 4. 给服务器端发送数据(回执信息).
    client_socket.send('有内鬼, 终止交易! Over'.encode("utf-8"))
    # 5. 关闭Socket对象.
    client_socket.close()

服务器端

步骤
  1. 创建服务器端Socket对象.

  2. 绑定(服务器端的)ip和端口号, 元组形式.

  3. 设置监听数量.

  4. 等待客户端申请建立连接, 如果有客户端申请建立连接, 校验数据合法后, 会返回1个: (负责和该客户端交互的socket对象, 客户端的信息) 元组

  5. 给客户端发送数据. 字节形式.

  6. 接收客户端发送的数据. 字节形式.

  7. 释放资源.

代码
# 导包.
import socket
​
# 在main中编写.
if __name__ == '__main__':
    # 1. 创建服务器端Socket对象, 指定: 地址族, 传输类型.
    # 参1: IPV4,  参2: 字节流
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2. 绑定地址和端口.
    # server_socket.bind(("127.0.0.1", 2121))
    server_socket.bind(("192.168.13.157", 2121))
    # 3. 设置监听数量.    范围: 1 ~ 128
    server_socket.listen(5)
    # 4. 等待客户端连接, 如有连接, 则返回: (和客户端交互的Socket对象, 客户端地址)
    print('等待客户端连接中.....')
    # print('Server 1')
    accept_socket, client_info = server_socket.accept()
    # print('Server 2')
    # 5. 给客户端发送数据.
    # accept_socket.send('Welcome to study socket!'.encode('utf-8'))
    accept_socket.send(b'Welcome to study socket!')
​
    # 6. 接受客户端发送的数据并打印.
    recv_data_bys = accept_socket.recv(1024)        # receive: 接收,  一次读取1024个字节
    # 把字节转成字符串, 并打印.
    recv_data = recv_data_bys.decode('utf-8')
    print(f'服务器端收到 {client_info} 发送的信息: {recv_data}')
​
    # 7. 关闭Socket对象.
    accept_socket.close()       # 一般只关闭 和客户端交互的socket对象.
    # server_socket.close()     # 服务器端socket对象一般不关闭.

编解码

概述

编解码指的是 字符串 和 二进制数据之间相互转换.编码: 字符串(我们能看懂的) ==> 二进制(计算机能看懂)解码: 二进制(计算机能看懂) ==> 字符串(我们能看懂的)

细节

  1. 码表 = 字符 + 数字, 即: 码表存储的就是该字符对应的数字.例如(假设): 存数据流程: 中 => 按照码表, 转成123456(十进制) => 0101 1011(二进制, 源码) => 二进制反码 => 二进制补码 => 存储到计算机中. 读数据流程: 读取二进制数据(补码) => 二进制反码 => 二进制源码 => 转成十进制(例如: 123456) => 根据码表, 找到字符 '中'

  2. 在GBK码表(针对于国内)中, 1个中文占2个字节, 在UTF-8码表(万国码, 统一码)中, 中文占3个字节.

  3. 英文字母, 数字, 特殊符号无论在什么码表中, 都只占1个字节.

  4. 如果遇到乱码情况了, 原因只有1个: 编解码不一致.

  5. 针对于二进制数据, 语法糖写法为: b'内容', 但是该形式只针对于 英文字母, 数字, 特殊符号 有效, 针对于中文无效.

代码
# 需求1: 演示编码.
s1 = '黑马aB1!'
bys1 = s1.encode()          # bytes: 字节数组, 默认码表: utf-8
bys2 = s1.encode('gbk')
bys3 = s1.encode('utf-8')
print(f'bys1: {bys1}')  # b'\xe9\xbb\x91\xe9\xa9\xac aB1!'
print(f'bys2: {bys2}')  # b'\xba\xda\xc2\xed aB1!'
print(f'bys3: {bys3}')  # b'\xe9\xbb\x91\xe9\xa9\xac aB1!'
print("-" * 21)
​
# 需求2: 解码
bys4 = b'\xe9\xbb\x91\xe9\xa9\xacaB1!'
s2 = bys4.decode(encoding='utf-8')
s3 = bys4.decode(encoding='gbk')
print(f's2: {s2}')  # 黑马aB1!
print(f's3: {s3}')  # 榛戦┈aB1!
print("-" * 21)
​
# 需求3: 二进制的特殊写法.
bys5 = b'aB1!'
print(type(bys5))   # <class 'bytes'>

端口复用

解释

当服务器端关闭的时候, 端口号释放可能需要1 ~ 2分钟的时间, 如果此时再次开启服务器端, 可能会报: 端口号占用的错误. 解决方案如下: 1. 重新手动更换1个端口号. 2. 设置端口号重用(复用).

server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

代码
# 导包.
import socket
​
# 在main中编写.
if __name__ == '__main__':
    # 1. 创建服务器端Socket对象, 指定: 地址族, 传输类型.
    # 参1: IPV4,  参2: 字节流
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2. 绑定地址和端口.
    # server_socket.bind(("127.0.0.1", 2121))
    server_socket.bind(("192.168.13.157", 2121))
    # 3. 设置监听数量.    范围: 1 ~ 128
    server_socket.listen(5)
    # 4. 等待客户端连接, 如有连接, 则返回: (和客户端交互的Socket对象, 客户端地址)
    print('等待客户端连接中.....')
    # print('Server 1')
    accept_socket, client_info = server_socket.accept()
    # print('Server 2')
    # 5. 给客户端发送数据.
    # accept_socket.send('Welcome to study socket!'.encode('utf-8'))
    accept_socket.send(b'Welcome to study socket!')
​
    # 6. 接受客户端发送的数据并打印.
    recv_data_bys = accept_socket.recv(1024)        # receive: 接收,  一次读取1024个字节
    # 把字节转成字符串, 并打印.
    recv_data = recv_data_bys.decode('utf-8')
    print(f'服务器端收到 {client_info} 发送的信息: {recv_data}')
​
    # 7. 关闭Socket对象.
    accept_socket.close()       # 一般只关闭 和客户端交互的socket对象.
    # server_socket.close()     # 服务器端socket对象一般不关闭.
​
    # 8. 设置端口号复用.
    # 参1: 当前的套接字对象.
    # 参2: 参数名, 即: 设置端口号复用.
    # 参3: 参数的值, True: 启用
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
​

多客户端

代码
import socket
​
​
def tcp_server():
    # 创建套接字对象
    tss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定IP与端口号
    tss.bind(('', 2121))
    # 监听客户端连接
    tss.listen(128)
    while True:
        try:
            # 接收客户端信息
            new_s, ip_port = tss.accept()
            # 发送数据给客户端
            new_s.send('back_data'.encode(encoding='utf-8'))
            # 接收客户端信息
            res = new_s.recv(1024)
            res_data = res.decode('utf-8')
            print(f'{ip_port}: {res_data}')
            new_s.close()
            tss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        except:
            print('断开连接')
​
​
# 释放资源
tcp_server()
​

长连接

客户端

import socket
​
​
if __name__ == '__main__':
    # 套接字对象
    cli_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 连接服务器端口号
    cli_socket.connect(('127.0.0.1', 6666))
    # 发送信息到服务端
    while True:
        data = input('客户端输入信息:')
        cli_socket.send(data.encode('utf-8'))
        if data == '886':
            break
    cli_socket.close()

服务端

import socket
​
​
if __name__ == '__main__':
    # 套接字对象
    ser_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定端口号
    ser_socket.bind(('127.0.0.1', 6666))
    # 设置监听
    ser_socket.listen(128)
    # 启动监听
    accept_socket, client_info = ser_socket.accept()
    # 发送信息到服务端
    while True:
        recv_data = accept_socket.recv(1024).decode('utf-8')
        print(f'服务端收到信息: {recv_data}')
        if recv_data == '886':
            break
    accept_socket.close()

文件

客户端

import socket
​
​
if __name__ == '__main__':
    # 实例化套接字对象
    cli_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 连接到服务端
    cli_socket.connect(('127.0.0.1', 8848))
    # 读取数据源数据, 并发送到服务端
    with open('data/data.txt', 'rb') as src_f:
        # cli_socket.send('hang.txt'.encode('utf-8'))
        # 分批读取
        while True:
            # 读取数据
            data = src_f.read(1024)
            # 发送到服务器
            cli_socket.send(data)
            # 读取到空结束
            if len(data) <= 0:
                break
    cli_socket.close()

服务端

import socket
​
if __name__ == '__main__':
    # 实例化套接字对象
    ser_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 连接到服务端
    ser_socket.bind(('127.0.0.1', 8848))
    # 设置监听
    ser_socket.listen(1)
    # 启动监听, 等待客户端连接
    accept_socket, client_info = ser_socket.accept()
    # 接收客户端数据
    # 关联目的地文件, 用于把客户端的数据写到文件中
    with open('./data/file.txt', 'wb') as dest_f:
        while True:
            # 接收客户端数据
            res = accept_socket.recv(1024)
            if len(res) <= 0:
                break
            else:
                dest_f.write(res)
    accept_socket.close()

多客户端

服务端

import socket
​
​
if __name__ == '__main__':
    # 实例化套接字对象
    ser_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 连接到服务端(IP可以不写)
    ser_socket.bind(('', 8888))
    # 设置监听
    ser_socket.listen(10)
    # 启动监听, 等待客户端连接
    try:
        cnt = 0
        while True:
            cnt += 1
            filename = './data/文件_'.join(str(cnt) + 'txt')
            accept_socket, client_info = ser_socket.accept()
            # 接收客户端数据
            # 关联目的地文件, 用于把客户端的数据写到文件中
            with open(filename, 'wb') as dest_f:
                while True:
                    res = accept_socket.recv(1024)
                    if len(res) <= 0:
                        break
                    dest_f.write(res)
                accept_socket.send('文件上传成功'.encode('utf-8'))
            print(f'服务器端收到客户端:{client_info}的文件, 接收成功')
            accept_socket.close()
    except:
        pass

三. 进程

每个软件都可以看作是一个进程(数据隔离)

软件内的多个任务可以看作是多个线程(数据共享)

单核CPU: 宏观并行, 微观并发

真正的并行必须有多核CPU

多任务介绍

概述

多任务指的是, 多个任务同时执行

目的

节约资源, 充分利用CPU资源, 提高效率

表现形式

并发

针对于单核CPU来讲, 如果有多个任务同时请求执行, 但是同一瞬间CPU只能执行1个(任务), 于是就安排他们交替执行.

因为时间间隔非常短, 所以宏观上看是并行, 但是微观上还是并发的.

并行

针对多核CPU来讲, 多个任务可以同时执行

进程介绍

概述

进程: 值得是可执行程序, 也是CPU分配资源的最小单位.

线程: 进程的执行路径, 执行单元

解释:

进程: 车

线程: 车道

多进程实现步骤

  1. 导包(multiprocessing)

  2. 创建进程对象, 关联 该进程要执行的任务(函数)

  3. 启动进程执行任务

代码
import multiprocessing, time
​
​
# 定义代码函数
def coding():
    for i in range(1, 21):
        time.sleep(1)
        print(f'正在敲代码----  {i}')
​
        
# 定义音乐函数
def music():
    for i in range(1, 21):
        time.sleep(1)
        print(f'正在听音乐****  {i}')
​
​
if __name__ == '__main__':
    # 创建进程对象
    p1 = multiprocessing.Process(target=coding)
    p2 = multiprocessing.Process(target=music)
    # 执行进程
    p1.start()
    p2.start()

进程参数

参数

target: 用于关联 进程要执行的任务的.name: 进程名, 默认是: Process-1, Process-2,...., 可以手动修改, 一 般不改.args: 可以通过 元组 的形式传递参数, 实参的个数 及 对应的数据类型 要和 形参的个数及类型 一致.kwargs: 可以通过 字典 的形式传递参数, 实参的个数 要和 形参的个数 一致.

代码演示
import multiprocessing, time
​
​
def coding(name, num):
    for i in range(1, num):
        time.sleep(0.01)
        print(f'{name}正在敲第{i}行代码-')
​
​
def music(name, num):
    for i in range(1, num):
        time.sleep(0.01)
        print(f'{name}正在听第{i}首音乐********')
​
​
if __name__ == '__main__':
    p1 = multiprocessing.Process(target=coding, args=('小明', 21))
    p2 = multiprocessing.Process(target=music, kwargs={'num': 21, 'name': '小明'})
    p11 = multiprocessing.Process(target=coding, args=('小明', 21), name='QQ')
    p22 = multiprocessing.Process(target=music, kwargs={'num': 21, 'name': '小明'}, name='WX')
    print(f'p1:{p1.name}')
    print(f'p2:{p2.name}')
    print(f'p11:{p11.name}')
    print(f'p22:{p22.name}')
    p1.start()
    p2.start()
​

main进程

解释

main程序入口也相当于一个进程, 在程序执行时遇到自定义进程会发生资源抢占, 上述代码中在输出进程对象后, 进程才启动, 所以上述的自定义进程不会和main进程强制资源, 并且自定义进程的启动需要一定时间, 此时的main进程可能已经完成自己的任务, 执行自定义进程.

图解

代码
import multiprocessing, time
​
​
def coding(name, num):
    for i in range(1, num):
        time.sleep(0.01)
        print(f'{name}正在敲第{i}行代码-')
​
​
def music(name, num):
    for i in range(1, num):
        time.sleep(0.01)
        print(f'{name}正在听第{i}首音乐********')
​
​
if __name__ == '__main__':
    p1 = multiprocessing.Process(target=coding, args=('小明', 11))
    p2 = multiprocessing.Process(target=music, kwargs={'num': 11, 'name': '小明'})
    # p11 = multiprocessing.Process(target=coding, args=('小明', 11), name='QQ')
    # p22 = multiprocessing.Process(target=music, kwargs={'num': 11, 'name': '小明'}, name='WX')
    p1.start()
    p2.start()
    # print(f'p1:{p1.name}')
    # time.sleep(0.1)
    # print(f'p2:{p2.name}')
    # time.sleep(0.1)
    # print(f'p11:{p11.name}')
    # time.sleep(0.1)
    # print(f'p22:{p22.name}')
​
    for i in range(1, 21):
        print(f'main: -------  {i}')
        time.sleep(0.1)

注: 上述代码中, 若将main中的循环放到自定义进程前, 则自定义进程不会和main抢占资源, 因为执行完main中的循环才执行到自定义进程, 可以把main函数看作栈, 从上到下执行

代码执行结果(每次可能都不一样)

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

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

相关文章

同三维S61-20SDI 20倍 HDMI SDI USB3.0 网口 3高清摄像机

同三维S61-20SDI 高清摄像机 20倍光学变焦&#xff0c; HDMI/SDI/USB3.0/网口&#xff0c;3.5音频口输入&#xff0c;350万像素 索尼机芯&#xff0c;支持POE&#xff0c;NDI HX2/Full NDI&#xff08;可定制&#xff09; 两款&#xff1a; S61-20SDI (不支持NDI) 单价&#…

1分钟 快速掌握 双向信号(inout信号)

​在数字电路设计中&#xff0c;三态门扮演着至关重要的角色。它是Verilog硬件描述语言中的一个基本元素&#xff0c;用于实现复杂电路的设计与模拟。 今天&#xff0c;我们一起来探讨三态门的基本原理、在Verilog中的实现方式。 一、什么是三态门? 三态门&#xff0c;简单…

fpga图像处理实战-边缘检测 (Roberts算子)

Roberts算子 Roberts算子是一种用于边缘检测的算子,主要用于图像处理中检测图像的边缘。它是最早的边缘检测算法之一,以其计算简单、速度快而著称。Roberts算子通过计算图像像素在对角方向的梯度来检测边缘,从而突出图像中灰度变化最剧烈的部分。 原理 Roberts算子通过…

力扣刷题(4)

正则表达式匹配 正则表达式匹配-力扣 思路来源&#xff1a;ithewei 若 *p 为空&#xff0c;*s 为空则匹配&#xff0c;*s 为非空则不匹配&#xff1b;当 *s为非空时&#xff0c;*p *s || *p ‘.’ 时第一个字符匹配&#xff1b;若 *(p1) ! ’ * 时&#xff0c;则递归判断…

python开发VTK入门

首先用pip命令安装VTK的python库&#xff1b; 需要一些时间&#xff0c;安装完成如下&#xff1b; 基本示例代码&#xff0c; import vtkcube vtk.vtkCubeSource() cube.SetXLength(100.0) cube.SetYLength(200.0) cube.SetZLength(300.0)mapper vtk.vtkPolyDataMapper() ma…

25届计算机毕业设计:3步打造北部湾助农平台,Java SpringBoot实践

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

《OpenCV计算机视觉》—— 图像轮廓检测与绘制

文章目录 一、轮廓的检测二、轮廓的绘制图像轮廓检测与绘制的代码实现 三、轮廓的近似 一、轮廓的检测 轮廓检测是指在包含目标和背景的数字图像中&#xff0c;忽略背景和目标内部的纹理以及噪声干扰的影响&#xff0c;采用一定的技术和方法来实现目标轮廓提取的过程注意:做轮…

探索Python中的Ellipsis:不仅仅是三个点

在Python 3.9中&#xff0c;Ellipsis 对象被赋予了一个新名称&#xff0c;即 ...&#xff0c;这使得它更容易输入和使用。这个变化是在Python 3.9版本中引入的&#xff0c;而不是3.1。这个变化的好处包括&#xff1a; 易用性&#xff1a;使用 ... 比输入 Ellipsis 更快&#xf…

第11讲 回环检测

1、理解回环检测的必要性 2、掌握基于词袋的外观式回环检测 3、通过DBoW3的实验&#xff0c;学习词袋模型的实际用途 1、概述 1.1 回环检测的意义 回环检测模块能够给出除了相邻帧的一些是个更加久远的约束。相机经过了同一个地方&#xff0c;采集了相似的数据。回环检测的关…

OpenCV 之图像平滑处理

引言 图像平滑处理&#xff08;也称为“模糊处理”&#xff09;是计算机视觉中一项非常基础的技术&#xff0c;常用于减少图像噪声或失真&#xff0c;提高图像质量。平滑处理可以通过各种滤波器实现&#xff0c;常见的滤波器包括均值滤波、方框滤波、高斯滤波和中值滤波。本文…

【赵渝强老师】大数据生态圈中的组件

大数据体系架构中的组件非常多&#xff0c;每个组件又属于不同的生态圈系统。从最早的Hadoop生态圈体系开始&#xff0c;逐步有了Spark生态圈体系和Flink生态圈体系。因此在学习大数据之前有必要了解一下每一个生态圈体系中具体包含哪些组件&#xff0c;以及它们的作用又是什么…

在移动应用程序中集成模糊方法的基于物联网的天气监测系统的实现

这篇论文的标题是《IMPLEMENTATION OF WEATHER MONITORING SYSTEM BASED INTERNET OF THINGS USING INTEGRATED FUZZY METHOD IN MOBILE APPLICATIONS》&#xff0c;作者是 Muhammad Malik Amin&#xff0c;来自 Politeknik Negeri Jakarta 的 D-IV INSTRUMENTASI DAN KONTROL …

WebAssembly内存结构学习记录

参考&#xff1a; 大文件上传深入研究&#xff1a;https://juejin.cn/post/6870837414852886542 WorkerWasm切片上传&#xff1a;https://juejin.cn/post/7221003401996091429 Wasm实现MD5文件编码&#xff1a;https://juejin.cn/post/7319541565318398003 SharedArrayBuffer与…

Python | 使用Pygments生成漂亮的代码段截图

在创建技术文档或教程时&#xff0c;包含代码段的图像以说明特定的示例或概念可能会有所帮助。但是&#xff0c;对代码文件进行屏幕截图可能看起来不专业&#xff0c;并且难以阅读。本文将探索如何使用库pygments将编程代码转换为Python中美丽的图像片段。 Pygments库 Pygmen…

基于Java+SpringBoot+Vue+MySQL的失物招领管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于SpringBootVue的失物招领管理系统【附源码文档】、前后…

Java 入门指南:Java 并发编程 —— 并发容器 LinkedBlockingQueue

BlockingQueue BlockingQueue 是Java并发包&#xff08;java.util.concurrent&#xff09;中提供的一个阻塞队列接口&#xff0c;它继承自 Queue 接口。 BlockingQueue 中的元素采用 FIFO 的原则&#xff0c;支持多线程环境并发访问&#xff0c;提供了阻塞读取和写入的操作&a…

JavaEE---Spring MVC(4)

MVC学习小案例1 在这里我们要实现一个计算器的功能 在这之前,先解决一个bug! 写好代码之后开始运行,运行发现不对,sum计算不出来,然后我百思不得其解, 1.对着后端代码一顿输出,还是没觉得有问题. 2.对着前端代码一顿输出,也没看出任何问题 3.是不是我前后端交互出错了呢?查找…

Python案例 | 四阶龙格库塔法简介

1.引言 在数值分析中&#xff0c;龙格-库塔法&#xff08;Runge-Kutta methods&#xff09;是用于非线性常微分方程的解的重要的一类隐式或显式迭代法。这些技术由数学家卡尔龙格和马丁威尔海姆库塔于1900年左右发明。 龙格-库塔(Runge-Kutta)方法是一种在工程上应用广泛的高…

工厂验收(FAT)和现场验收(SAT)的含义

工厂验收&#xff08;Factory Acceptance Test&#xff0c;FAT&#xff09;和现场验收&#xff08;Site Acceptance Test&#xff0c;SAT&#xff09;是在工程领域中常见的术语&#xff0c;用于确保设备在制造商及用户之间达成一致的验收标准&#xff0c;保证设备能够正常、安全…

【图灵完备 Turing Complete】游戏经验攻略分享 Part.2 算术运算

算术运算部分算是开始有难度了。 前几关按照自己思路来&#xff0c;二进制速算应该没问题。 画真值表&#xff0c;卡诺图&#xff0c;推表达式。 下面几关&#xff0c;几个输出信号分开来看&#xff0c;有三个输出就画三个卡诺图&#xff0c;有几个画几个&#xff0c;分而治之。…