网络编程(python)

news2024/11/25 8:22:23

文章目录

  • 一、网络基础(IP,端口,TCP等)
  • 二、TCP网络应用可开发流程
  • 三、HTTP协议和静态Web服务器
  • 四、搭建Python自带静态Web服务器

一、网络基础(IP,端口,TCP等)

IP地址:标识网络中设备的一个地址

ping可以检查网络,ping www.baidu.com可以查看百度网址的IP,网页搜索ping出来的这个IP也同样可以进入百度网页,网页搜索网址,实际上是搜索IP,只不过使用了URL网页网址(如www.baidu.com)封装,方便记忆搜寻,www.baidu.com相比一串数字(112.80.248.76,随着时间不同,该IP可能会变化),肯定是网址好记,如下图
在这里插入图片描述

端口:端口是传输数据的通道,每个端口都有对应的端口号,每个电脑存在一个IP地址,拥有多个端口,每个程序对应一个端口,以保证将该电脑接收到数据传输给对应的程序,比如发送微信,根据IP可以知道发送到哪台电脑,根据端口可以知道发送到该电脑的微信,而不是QQ或其他程序

端口号分为知名端口号和动态端口号
知名端口号范围从1到1023,这些端口号一般固定分配给一些服务,比如21端口分配给FTP(文件传输协议)服务,25端口分配给SMTP(简单邮件传输协议) 服务,80端口分配给HTTP服务(如输入www.baidu.com:80搜索还是百度首页)。
动态端口号范围从1024到65535,一般用于程序员开发应用程序使用的端口,如果程序员开发的程序没有设置端口号,操作系统会在动态端口号这个范围内随机生成一个给开发的应用程序使用。当运行一个程序默认会有一个端口号,当这个程序退出时,所占用的这个端口号就会被释放。

TCP:通过IP地址和端口号可以进行数据传输,在数据传输之前,需要选择一个对应的传输协议,保证程序之间按照指定的传输规则进行数据的通信,这个传输协议就是TCP。TCP简称传输监控协议,是一种面向连接的、可靠的、基于字节流的传输层通讯协议,TCP 是一个稳定、可靠的传输协议,常用于对数据进行准确无误的传输,比如: 文件下载,浏览器上网。

TCP通讯步骤:创建连接(TCP三次握手)、传输数据、关闭连接(四次挥手)

TCP 的特点
面向连接:通信双方必须先建立好连接才能进行数据的传输,数据传输完成后,双方必须断开此连接,以释放系统资源。
可靠传输:TCP 采用发送应答机制;超时重传;错误校验;流量控制和阻塞管理

socket:通讯数据的传输是通过socket来实现,socket(简称 套接字)是进程之间的通信工具,负责进程之间的网络数据传输,好比数据的搬运工,进程之间想要进行网络通信需要基于这个 socket。只要跟网络相关的应用程序或者软件都使用到了socket。

二、TCP网络应用可开发流程

TCP网络应用开发分为TCP客户端程序开发和TCP服务端程序开发(客户端程序是指运行在用户设备上的程序 服务端程序是指运行在服务器设备上的程序,专门为客户端提供数据服务)

步骤:创建服务端端套接字对象;绑定端口号;设置监听;等待接受客户端的连接请求;接收数据;发送数据;关闭套接字

TCP客户端程序开发
步骤:创建客户端套接字对象(socket());和服务端套接字建立连接(connect());发送数据(send());接收数据(recv());关闭客户端套接字(close())

socket.socket(AddressFamily, Type):创建客户端对象,参数说明:AddressFamily表示IP地址类型,分别为IPv4(socket.AF_INET)和IPv6(socket.AF_INET6),Type表示连接类型(socket.SOCK_STREAM表示以TCP形式创建socket,socket.SOCK_DGRAM表示以UDP形式创建socket)
connect((host,port)):表示和服务端套接字建立连接,host是服务器ip地址,port是应用程序的端口号
send(data) :表示发送数据,data是二进制数据(使用"".encode(“gbk”)转化)接收服务端在win系统上编码使用gbk编码,如果是mac、linux默认使用utf-8
recv(buffersize) :表示接收数据,buffersize是每次接收数据的长度

TCP服务端程序开发
步骤:创建服务端套接字对象;绑定端口号;设置监听;等待接受客户端的连接请求;接收数据;发送数据;关闭套接字;

socket.socket(AddressFamily, Type):创建客户端对象,参数说明:AddressFamily表示IP地址类型,分别为IPv4(socket.AF_INET)和IPv6(socket.AF_INET6),Type表示连接类型(socket.SOCK_STREAM表示以TCP形式创建socket,socket.SOCK_DGRAM表示以UDP形式创建socket)
setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True):端口复用,让程序退出端口号立马释放,因为服务器是一次性的,如果马上重启服务器时,会报错,原因是地址和端口没有被释放
bind(host, dort)):表示绑定端口号, host 是ip地址﹐port 是端口号﹐ip地址一般不指定﹐表示本机的任何一个ip地址都可以。
listen(backlog):表示设置监听﹐backlog参数表示最大等待建立连接的个数
accept():表示等待接受客户端的连接请求
send(data) :表示发送数据,data是二进制数据(使用"".encode(“gbk”)转化)
recv(buffersize) :表示接收数据,buffersize是每次接收数据的长度

下面两段代码,分别为客户端和服务端,先运行服务端,再运行客户端,两者之间会有数据传输

客户端

import socket

if __name__ == '__main__':
    # 创建TCP客户端套接字
    tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 和服务端建立连接
    tcp_socket.connect(('127.0.0.1', 8888))

    # 发送数据
    send_data = "发送数据内容".encode("gbk")
    tcp_socket.send(send_data)

    # 接收数据(设置最大字节数为1024),接收的是二进制数据,需要解码
    recv_data = tcp_socket.recv(1024).decode("gbk")
    print(recv_data)

    # 关闭嵌套字
    tcp_socket.close()

服务端

import socket

if __name__ == '__main__':
    # 创建TCP服务端套接字
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,让程序退出端口号立马释放
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号  绑定没有给定IP时默认本地IP地址
    server_socket.bind(('', 8888))
    # 设置监听
    server_socket.listen(10)
    # 等待客户端   客户端连接后,该函数会返回两个数据,一个是客户端Socket对象,一个是客户端的地址信息
    client_socket, ip_port = server_socket.accept()
    print(f'客户端 {ip_port[0]} 使用端口 {ip_port[1]} 连接成功...')

    # 接收客户端数据
    data = client_socket.recv(1024).decode('gbk')
    print(data)

    # 给客户端发送数据
    data = '数据内容'.encode('gbk')
    client_socket.send(data)

    # 关闭客户端
    client_socket.close()
    # 关闭服务端
    server_socket.close()

TCP网络应用程序的注意点介绍

当TCP客户端程序想要和TCP服务端程序进行通信的时候必须要先建立连接;TCP客户端程序一般不需要绑定端口号,因为客户端是主动发起建立连接的;TCP服务端程序必须绑定端口号,否则客户端找不到这个TCP 服务端程序;listen后的套接字是被动套接字,只负责接收新的客户端的连接请求,不能收发消息;当TCP客户端程序和TCP服务端程序连接成功后﹐TCP服务器端程序会产生一个新的套接字﹐收发客户端消息使用该套接字。
关闭accept返回的套接字意味着和这个客户端已经通信完毕;关闭listen后的套接字意味着服务端的套接字关闭了﹐会导致新的客户端不能连接服务端﹐但是之前已经接成功的客户端还能正常通信;当客户端的套接字调用close后﹐服务器端的recv 会解阻塞﹐返回的数据长度为O﹐服务端可以通过返回数据的长度来判断客户端是否已经下线﹐反之服务端关闭套接字﹐客户端的recv也会解阻塞﹐返回的数据长度也为0。

案例多任务TCP服务端程序开发
完成任务可以使用线程,比进程节省资源

步骤

编写一个TCP服务端程序,循环等待接受客户端的连接请求;
当客户端和服务端建立连接成功,创建子线程,使用子线程专门处理客户端的请求,防止主线程阻塞;
把创建的子线程设置成为守护主线程,防止主线程无法退出

多任务TCP服务器(函数client_task在threading.Thread的args参数中)

import socket
import threading

# 实现多任务功能函数
def client_task(client_socket, ip_port):
    print(ip_port, '已连接...')
    # 实现一个循环,持续接收客户消息
    while True:
        # 接收客户端数据
        data = client_socket.recv(1024).decode('gbk')
        if len(data) != 0:
            print(f'客户端{ip_port[0]} 发来的消息是 {data}')
        else:
            print(f'客户端{ip_port[0]} 已断开...')
            break

        # 服务端回复的消息
        data = '数据内容'.encode('gbk')
        client_socket.send(data)

    # 关闭客户端
    client_socket.close()


if __name__ == '__main__':
    # 创建TCP服务端套接字
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,让程序退出端口号立马释放
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号
    server_socket.bind(('', 8888))
    # 设置监听
    server_socket.listen(128)

    # 循环接收客户连接,等待客户端
    while True:
        # 客户端连接后,该函数会返回两个数据,一个是客户端Socket对象,一个是客户端的地址信息
        client_socket, ip_port = server_socket.accept()
        print(f'客户端 {ip_port[0]} 使用端口 {ip_port[1]} 连接成功...')
        # 实现多任务
        t_client = threading.Thread(target=client_task, args=(client_socket, ip_port))
        # 设置守护线程
        # t_client.setDaemon(True)
        # 启动多任务
        t_client.start()

    # 关闭服务端
    server_socket.close()

面向对象多任务TCP服务器

import socket
import threading

# 设置一个类
class SocketServer(object):
    # 实例化
    def __init__(self, port):
        # 创建TCP服务端套接字
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置端口号复用,让程序退出端口号立马释放
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        # 绑定端口号
        self.server_socket.bind(('', port))
        # 设置监听
        self.server_socket.listen(128)

    # 启动服务器
    def start(self):
        # 循环接收客户连接,等待客户端
        while True:
            # 客户端连接后,该函数会返回两个数据,一个是客户端Socket对象,一个是客户端的地址信息
            client_socket, ip_port = self.server_socket.accept()
            print(f'客户端 {ip_port[0]} 使用端口 {ip_port[1]} 连接成功...')
            # 实现多任务
            t_client = threading.Thread(target=self.client_task, args=(client_socket, ip_port))
            # 设置守护线程
            # t_client.setDaemon(True)
            # 启动多任务
            t_client.start()

        # 关闭服务端
        server_socket.close()

    # 实现多任务功能函数
    def client_task(self, client_socket, ip_port):
        print(ip_port, '已连接...')
        # 实现一个循环,持续接收客户消息
        while True:
            # 接收客户端数据
            data = client_socket.recv(1024).decode('gbk')
            if len(data) != 0:
                print(f'客户端{ip_port[0]} 发来的消息是 {data}')
            else:
                print(f'客户端{ip_port[0]} 已断开...')
                break

            # 服务端回复的消息
            data = '数据内容'.encode('gbk')
            client_socket.send(data)

        # 关闭客户端
        client_socket.close()


if __name__ == '__main__':
    # 创建SocketServer对象,并启动服务器
    server = SocketServer(8888)
    server.start()

send和recv都不是直接接收到对方的数据和发送数据到对方,发送数据刽写入到发送缓冲区,接收数据是从缓冲区来读取,发送数据和接收数据最终是由操作系统控制网卡来完成
在这里插入图片描述

三、HTTP协议和静态Web服务器

HTTP协议超文本传输协议。超文本是指超越文本限制或者超链接,比如:图片、音乐、视频、超链接等等都属于超文本。传输HTTP协议格式的数据是基于TCP 传输协议的,发送数据之前需要先建立连接。HTTP协议规定了浏览器和 Web 服务器通信数据的格式,也就是说浏览器和web服务器通信需要使用http协议

URL是统一资源定位符,即网络资源地址,也就是我们常说的网址。URL由协议部分(如http://、https://、ftp://)、域名部分(如www.baidu.com)、资源路径部分(如com后面的部分)组成,部分可能包含查询参数部分(如?page=1&count=10)。域名就是IP地址的别名,使用域名就是方便的记住某台主机IP地址。

开发者工具按F12可以打开浏览器的开发者工具,开发者工具包括元素、控制台、源代码、网络。元素 (Elements):用于查看或修改HTML标签;控制台 (Console执行js代码;源代码 (Sources):查看静态资源文件,断点调试JS代码;网络 (Netwiork):查看http协议的通信过程。开发者工具的Headers选项总共有三部分组成:General: 主要信息;Response Headers: 响应头;Request Headers: 请求头

在这里插入图片描述

HTTP请求报文最常见的有两种:GET方式的请求报文(获取web服务器数据);POST方式的请求报文(向web服务器提交数据)

HTTP响应报文是由响应行、响应头、空行和响应体4个部分组成。响应行是由三部分组成:HTTP协议版本、状态码、状态描述,最常见的状态码是200

HTTP常见状态码(开头为1表示消息,2成功,3重定向,4请求错误,5服务器错误)

状态码说明
200请求成功
307重定向
400错误的请求,请求地址或参数有误
404请求资源在服务器中不存在
500服务器内部资源代码出现错误

四、搭建Python自带静态Web服务器

静态Web服务器可以为发出请求的浏览器提供静态文档,使用指令python3 -m http.server 端口号搭建Python自带静态Web服务器。-m表示运行包里面的模块,执行这个命令的时候,需要进入你自己指定静态文件的目录,然后通过浏览器就能访问对应的 html文件了,这样一个静态的web服务器就搭建好了,然后可以输入IP地址访问本地服务器页面。

静态Web服务器-返回固定页面数据
实现步骤:编写一个TCP服务端程序;获取浏览器发送的http请求报文数据;读取固定页面数据,把页面数据组装成HTTP响应报文数据发送给浏览器;HTTP响应报文数据发送完成以后,关闭服务于客户端的套接字。

实例一:在py文件同级目录创建文件static/index.html文件,然后服务器代码如下,运行下面代码,在浏览器中搜索localhost:8888,然后页面就会展示index.html文件内容

import socket

if __name__ == '__main__':
    # 创建TCP服务端套接字
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,让程序退出端口号立马释放
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号  绑定没有给定IP时默认本地IP地址
    server_socket.bind(('', 8888))
    # 设置监听
    server_socket.listen(128)

    while True:
        # 等待客户端   客户端连接后,该函数会返回两个数据,一个是客户端Socket对象,一个是客户端的地址信息
        client_socket, ip_port = server_socket.accept()
        print(f'客户端 {ip_port[0]} 使用端口 {ip_port[1]} 连接成功...')

        # 接收客户端数据
        data = client_socket.recv(1024).decode('gbk')
        print(data)

        # 读取文件数据
        with open("static/index.html", 'rb') as file:
            file_data = file.read()

        # 响应行
        response_line = "HTTP/1.1 200 ok\r\n"
        # 响应头
        response_header = "Server: PWS1.0\r\n"
        # 响应体
        response_body = file_data

        # 拼接响应报文
        response_data = (response_line + response_header + "\r\n").encode("gbk") + response_body
        # 发送数据
        client_socket.send(response_data)

        # 关闭客户端
        client_socket.close()
    # 关闭服务端
    server_socket.close()

实例二:上面实例一中,不管用户搜索什么,返回的都是固定页面的数据,接下来需要根据用户的请求返回指定页面的数据(根据URL不同展示不同HTML文件
步骤:获取用户请求资源的路径;根据请求资源的路径,读取指定文件的数据;组装指定文件数据的响应报文,发送给浏览器;判断请求的文件在服务端不存在,组装404状态的响应报文,发送给浏览器

import socket

if __name__ == '__main__':
    # 创建TCP服务端套接字
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,让程序退出端口号立马释放
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号  绑定没有给定IP时默认本地IP地址
    server_socket.bind(('', 8888))
    # 设置监听
    server_socket.listen(128)

    while True:
        # 等待客户端   客户端连接后,该函数会返回两个数据,一个是客户端Socket对象,一个是客户端的地址信息
        client_socket, ip_port = server_socket.accept()
        print(f'客户端 {ip_port[0]} 使用端口 {ip_port[1]} 连接成功...')

        # 接收客户端数据
        data = client_socket.recv(1024).decode('gbk')
        # print(data)

        # 对数据进行分隔,最大分隔次数为2
        request_list = data.split(" ", maxsplit=2)

        # 获取请求资源路劲
        request_path = request_list[1]
        print(request_path)

        # 判断请求的是否是根目录,如果条件成立,指定首页数据返回
        if request_path == "/":
            request_path = "/index.html"

        try:
            # 读取文件数据
            with open("static" + request_path, 'rb') as file:
                file_data = file.read()
        except Exception as e:
            # 文件找不到,拼接404异常报文
            # 响应行
            response_line = "HTTP/1.1 404 NOT FOUND\r\n"
            # 响应头
            response_header = "Server: PWS1.1\r\n"
            # 响应体
            with open("static/error.html", 'rb') as file:
                error_data = file.read()

            # 拼接响应报文
            response_data = (response_line + response_header + "\r\n").encode("gbk") + error_data
            # 发送数据
            client_socket.send(response_data)
        else:
            # 响应行
            response_line = "HTTP/1.1 200 ok\r\n"
            # 响应头
            response_header = "Server: PWS1.0\r\n"
            # 响应体
            response_body = file_data

            # 拼接响应报文
            response_data = (response_line + response_header + "\r\n").encode("gbk") + response_body
            # 发送数据
            client_socket.send(response_data)

        # 关闭客户端
        client_socket.close()
    # 关闭服务端
    server_socket.close()

多任务的静态Web服务器:上面的不支持多用户同时访问,只能一个一个的处理客户端请求,这里可以使用多线实现多任务模式,即支持多用户同时访问
步骤:把创建的子线程设置成为守护主线程,防止主线程无法退出;当客户端和服务端建立连接成功,创建子线程,使用子线程专门处理客户端的请求,防止主线程阻塞

import socket
import multiprocessing

def server_start(port):
    # 创建TCP服务端套接字
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,让程序退出端口号立马释放
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号  绑定没有给定IP时默认本地IP地址
    server_socket.bind(('', port))
    # 设置监听
    server_socket.listen(128)

    while True:
        # 等待客户端   客户端连接后,该函数会返回两个数据,一个是客户端Socket对象,一个是客户端的地址信息
        client_socket, ip_port = server_socket.accept()
        print(f'客户端 {ip_port[0]} 使用端口 {ip_port[1]} 连接成功...')

        p = multiprocessing.Process(target=task, args=(client_socket,))
        p.start()
        client_socket.close()

    # 关闭服务端
    server_socket.close()

def task(client_socket):
    # 接收客户端数据
    data = client_socket.recv(1024).decode('gbk')
    # print(data)

    # 对数据进行分隔,最大分隔次数为2
    request_list = data.split(" ", maxsplit=2)

    # 获取请求资源路劲
    request_path = request_list[1]
    print(request_path)

    # 判断请求的是否是根目录,如果条件成立,指定首页数据返回
    if request_path == "/":
        request_path = "/index.html"

    try:
        # 读取文件数据
        with open("static" + request_path, 'rb') as file:
            file_data = file.read()
    except Exception as e:
        # 文件找不到,拼接404异常报文
        # 响应行
        response_line = "HTTP/1.1 404 NOT FOUND\r\n"
        # 响应头
        response_header = "Server: PWS1.1\r\n"
        # 响应体
        with open("static/error.html", 'rb') as file:
            error_data = file.read()

        # 拼接响应报文
        response_data = (response_line + response_header + "\r\n").encode("gbk") + error_data
        # 发送数据
        client_socket.send(response_data)
    else:
        # 响应行
        response_line = "HTTP/1.1 200 ok\r\n"
        # 响应头
        response_header = "Server: PWS1.0\r\n"
        # 响应体
        response_body = file_data

        # 拼接响应报文
        response_data = (response_line + response_header + "\r\n").encode("gbk") + response_body
        # 发送数据
        client_socket.send(response_data)
    finally:
        # 关闭客户端
        client_socket.close()

if __name__ == '__main__':
    server_start(8888)

面向对象静态Web服务器是在上面的基础上将上面的方法封装成类
通过sys可以获取参数,比如,上面服务端的代码文件为main.py,运行指令python3 main.py 8888可以开启服务器并且将8888传入到port中

if __name__ == '__main__':
    # sys.argv属性用来接收命令行参数,返回一个列表
    # 第一个参数是当前执行的程序文件,后面还可以跟其它数据,依次放到列表中
    # 取出第二个参数,用来做为当前程序的端口号
    port = int(sys.argv[1])
    
    server_start(port)

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

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

相关文章

企业的数据中台到底指的是什么?_光点科技

随着数据技术的不断发展和企业数据应用的广泛应用,越来越多的企业开始将数据中台作为数字化转型的核心战略之一。那么,企业的数据中台到底指的是什么呢? 数据中台是一种以数据为核心的企业数字化转型架构,旨在通过数据的汇聚、整合…

Lego- 美团接口自动化测试实战(详细解析)

目录:导读 一、概述 1.1 接口自动化概述 1.2 提高 ROI 1.3 Lego 的组成 二、脚本设计 2.1 Lego 的做法 2.2 测试脚本 2.3 配置文件 三、用例设计 3.1 一些思考 3.2 Lego 接口自动化测试用例 3.3 参数化 3.4 前后置动作 3.5 执行各部分 四、网站功能 …

软件测试员----面试,你准备好了么?

最近有机会做一些面试工作,主要负责面试软件测试人员招聘的技术面试。 之前一直是应聘者的角色,经历了不少次的面试之后,多少也积累一点面试的经验,现在发生了角色转变。初次的面试就碰到个工作年限比我长的,也没有时间…

c++11 标准模板(STL)(std::stack)(四)

定义于头文件 <stack> template< class T, class Container std::deque<T> > class stack;std::stack 类是容器适配器&#xff0c;它给予程序员栈的功能——特别是 FILO &#xff08;先进后出&#xff09;数据结构。 该类模板表现为底层容器的包装…

Spark学习——DataFrame清洗HDFS日志并存入Hive中

目录 1.开启Hadoop集群和Hive元数据、Hive远程连接 2.配置 3.读取日志文件并清洗 4.单独处理第四列的数据——方法一&#xff1a; 5.单独处理第四列的数据——方法二&#xff1a; 6.单独处理第四列的数据——方法三&#xff1a; 7.数据清洗结果展示 8.存入Hive中 9.…

The 2021 China Collegiate Programming Contest (Harbin) D. Math master

题目链接 题解 2632^{63}263大概是101910^{19}1019那么一共有19位需要讨论, 每一个位数各有保留和删除两种状态, 全部状态就是2182^{18}218种 因为每一位数都有两种状态, 使用二进制数表示每个状态, 正好能全部表示, 在二进制位数下1表示保留, 0表示删除(反过来也一样) 使用二…

分布式版本控制工具 —— Git

一、Git 基本介绍 1.1 相关概念 1️⃣ 首先&#xff0c;我们要知道什么是Git&#xff1f; Git 是一个免费、开源的版本控制系统&#xff0c;它可以有效地跟踪文件的更改&#xff0c;协调多人在同一个项目上的开发&#xff0c;以及管理不同版本的代码。 Git 最初是由 Linus …

微服务架构下认证和鉴权理解

认证和鉴权 从单体应用到微服务架构&#xff0c;优势很多&#xff0c;但是并不是代表着就没有一点缺点了。 微服务架构&#xff0c;意味着每个服务都是松散耦合的。因此&#xff0c;作为软件工程师和架构师&#xff0c;我们在分布式架构中面临着安全挑战。微服务对外开放的端…

PLE详解

具体的实践中&#xff0c;我们主要参考了腾讯的PLE(Progressive Layered Extraction)模型&#xff0c;PLE相对于前面的MMOE和ESMM&#xff0c;主要解决以下问题&#xff1a; 多任务学习中往往存在跷跷板现象&#xff0c;也就是说&#xff0c;多任务学习相对于多个单任务学习的…

Linux/Ubuntu服务自启动原理剖析及三种实现方式

面向Linux系统&#xff0c;并非只是Ubuntu&#xff1b;系统版本不同&#xff0c;配置上可能有所不同。 1、自启动的原理剖析 1.1、 运行等级 Linux分了7个运行等级&#xff0c;分别用数字0&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;6表示…

【Python】【进阶篇】十八、Python爬虫获取动态加载数据

目录十八、Python爬虫获取动态加载数据18.1 确定网站类型18.2 影片详情信息18.3 影片总数量18.4 影片类型与类型码18.5 编写完整程序十八、Python爬虫获取动态加载数据 如何获取电影“分类排行榜”中的电影数据&#xff08;电影&#xff09;&#xff0c;比如输入“剧情”则会输…

用EasyX图形库画一个哆啦A梦

继续说图形库&#xff0c;加一点实战用图形画图&#xff08;用来巩固代码&#xff09;&#xff1a; rectangle这个函数 四个参数&#xff0c;左上角坐标的x,y值&#xff0c;右下角坐标的x,y值&#xff1b;因为只要有两个点&#xff0c;就可以以它们的横坐标之差为长&#xff…

三范式建模和维度建模,到底该选哪一个?

编辑导语&#xff1a;当你需要从头开始设计数据仓库时&#xff0c;你会选择哪种建模方式&#xff1f;也许&#xff0c;你会从三范式建模和维度建模二者中选择。但是这二者有其各自的适用范围&#xff0c;具体选择哪种方法&#xff0c;还需要回归至业务层。本篇文章里&#xff0…

day-004-链表-两两交换链表中的节点、删除链表的倒数第N个节点、链表相交、环形链表II

两两交换链表中的节点 题目建议&#xff1a;用虚拟头结点&#xff0c;这样会方便很多。 题目链接/文章讲解/视频讲解 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* Li…

手麻系统源码,手术麻醉管理系统源码,二次开发方便快捷

手术麻醉管理系统源码&#xff0c;手麻系统源码&#xff0c;C# .net 桌面软件 C/S版 手术麻醉管理系统采用下拉式汉化菜单&#xff0c;界面友好&#xff0c;实用性强&#xff0c;设有与住院、病区、药房等系统的软件接口。 文末获取联系&#xff01; 开发语言&#xff1a;C# …

4.1 随机变量的数学期望

学习目标&#xff1a; 如果我想学习随机变量的数学期望&#xff0c;我可能会采取以下步骤&#xff1a; 掌握概率论基础知识&#xff1a;在学习随机变量的期望之前&#xff0c;我需要了解概率论的基本概念&#xff0c;例如概率、随机变量、概率密度函数等。 学习数学期望的定义…

算法总结---最常用的五大算法(算法题思路)

一、总结 一句话总结&#xff1a; 【明确所求&#xff1a;dijkstra是求点到点的距离&#xff0c;辅助数组就是源点到目标点的数组】 【最简实例分析&#xff1a;比如思考dijkstra&#xff1a;假设先只有三个点】 1、贪心算法是什么&#xff1f; 当前看来最好的选择 局部最…

第二章(2):从零开始掌握PyTorch基础知识,打造NLP学习利器

第二章&#xff08;2&#xff09;&#xff1a;从零开始掌握PyTorch基础知识&#xff0c;打造NLP学习利器&#xff01; 目录第二章&#xff08;2&#xff09;&#xff1a;从零开始掌握PyTorch基础知识&#xff0c;打造NLP学习利器&#xff01;1. Pytorch基础1.1 Pytorch安装1.1.…

计算机网络考试复习——第四章 4.1 4.2.1 4.2.2

网络层传输的单位是IP数据报 4.1 网络层的几个重要概念 网络层提供的两种服务&#xff1a;网络层应该向运输层提供怎样的服务&#xff1f;面向连接还是无连接&#xff1f; 在计算机通信中&#xff0c;可靠交付应当由谁来负责&#xff1f;是网络还是端系统&#xff1f; 面向连…

X79G Xeon 2630v2 电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网&#xff0c;转载需注明出处。&#xff08;下载请直接百度黑果魏叔&#xff09; 硬件型号驱动情况 主板X79G 处理器Intel Xeon 2630v2已驱动 内存32g (16*2 2666MHZ)已驱动 硬盘Intel 760p 512GB已驱动 显卡RX 470已驱动 声卡瑞昱 英特尔 High De…