网络编程小总结

news2025/1/18 20:59:57

【一】网络编程

互联网的本质就是一些网络协议

【1】网络开发架构

( 1 ) C / S 架构

C : client (客户端)

S: server (服务端)

APP - 就是服务端

C/S 架构通过客户端软件和服务器之间的交互,实现了前端界面和后端业务逻辑的分离,提供了一种稳定、可靠的架构模式。

( 2 ) B / S 架构

B : brower(网页端)

S: server (服务端)

打开QQ音乐----> 向QQ音乐发起请求

将资源在本地的浏览器进行渲染

B/S 架构通过浏览器和服务器之间的交互,实现了前端界面和后端业务逻辑的分离,提供了一种灵活、可扩展的架构模式。

( 3 ) B / S 架构 和 C / S机构 的优缺点

B / S 架构
  • 维护和升级方式简单 : 我只需要更新服务器的资源就可以了

  • 成本也比较低, 选择性也很多

  • 服务数据太多了, 负载严重

C / S 架构
  • 服务器压力有所减轻, 把一部分资源分跟客户端保存

  • 数据的存储和管理比较透明,APP逆向

  • 成本较高,维护费力

C / S 架构是主流趋势

【2】互联网协议

(1)什么是网络编程

  • 网络编程的研究前提就是基于互联网

  • 网络编程就是基于互联网写代码

(2)网络编程的媒介

  • 网络编程的媒介是计算机网络。

  • 而网络协议和网络编程框架和库则是实现网络编程的基础。

【3】OSI七层协议

image-20240122184416626

网络通信协议标准

  • 应用层:负责处理特定的应用程序协议,包括电子邮件、文件传输、远程登录。

  • 表示层:负责数据的表示和编码,在不同系统中传输前将数据进行转换和压缩等操作。

  • 会话层:负责建立、管理和终止会话,包括数据交换的同步和检查点的创建与恢复等功能。

  • 传输层:负责端到端的数据传输,提供可靠数据传输服务,包括流量控制、拥塞控制、错误恢复和数据重传等功能。

  • 网络层:负责实现不同计算机之间的数据包转发和路由器选择,并提供逻辑寻址和拥塞控制等功能。

  • 数据链路层:通过帧来传输数据,负责数据的可靠传输。

  • 物理层:负责在物理媒介上传输比特流,包括传输介质、物理接口和电气特征

优点:

  • 易于理解和实现:由于OSI模型具有清晰的分层结构,因为易于理解和实现

  • 可扩展性好:由于这个体系结构明确地定义了不同的层次和协议,因此它具有很好的可扩展性,可以随时添加新的协议和服务。

  • 提高了协议的互操作性:由于OSI模型对不同协议提供了明确的指导,所以它可以促进不同厂商和供应商的设备之间的互操作性。

  • 降低了复杂性:与其他体系结构相比,OSI模型具有更少的复杂性,因为每个层次的功能都是固定的。

缺点:

  • 过于理论化:OSI模型过于理论化,导致它在实际实现中的使用受到限制。

  • 缺乏灵活性:由于OSI模型在每一层都定义了特定的功能,因此缺乏灵活性,不能完全适应不同网络环境的要求。

  • 太过繁琐:由于OSI模型分为7层,因此在实际应用中会导致协议的复杂性和资源消耗增加。

  • 实现代价高:由于OSI模型需要使用大量的协议和设备来实现各个层次之间的通信,因此实现代价很高。

【4】TCP五层协议

  • 应用层:负责处理网络应用程序之间的通信。

  • 传输层:传输层协议提供端到端的同学协议,确保数据在网络上可靠传输。

  • 网络层:处理数据在网络中的传输和路由。

  • 数据链路层:在物理网络上提供了可靠的数据传输。它将数据包封装成帧,通过物理介质进行传输。

  • 物理层:负责在物理媒介上传输比特流,包括传输介质、物理接口和电气特征

优点:

  • 简单明了:TCP/IP五层协议简单明了,易于理解和实现。

  • 开放性强:TCP/IP协议是一种开放式标准,具有很好的兼容性和可扩展性。

  • 稳定可靠:TCP协议提供了可靠的数据传输服务,保证数据的完整性和可靠性。

  • 灵活性高:TCP/IP协议支持多种不同的应用程序,如电子邮件、文件传输、网页浏览等。

  • 安全性高:TCP/IP协议提供了一些安全机制,如IPSec、SSL等,保证数据的安全性和私密性。

缺点:

  • 复杂性较高:TCP/IP协议的实现比较复杂,需要深入了解网络协议的原理和相关技术。

  • 性能有限:TCP协议为了保证数据的可靠性,会引入一定的延迟和开销,对实时性要求较高的应用程序不太适合。

  • 安全性不足:TCP/IP协议中的一些安全机制容易受到攻击,需要采取额外的措施来保证安全性。

  • 可靠性有限:TCP/IP协议虽然提供了可靠的数据传输服务,但在网络拥塞时会出现丢包和延迟等问题,需要采取一些手段来解决。

  • 不适合大规模部署:由于TCP/IP协议没有很好地考虑网络管理和维护的问题,因此在大规模的网络部署中可能会出现一些问题。

【5】以太网协议

  • 规范了我们上网的标准

    是一种广泛的有线局域网技术之一,用于在计算机网络中进行数据通信。

    它定义了计算机之间的物理层和数据链路层的通信规则和格式。

以太网协议的特点:

  • 灵活性

  • 高速性

  • 简单性

  • 可靠性

  • 容错性

  • 扩展性

  • 可靠性

【6】IP协议

  • 是一种网络通信协议

TCP/IP 协议是网络层协议,它负责将数据包将数据包从源地址传输到目的的地址

它定义了数据在互联网上如何传输和路由

IP协议的特点:

  • 无链接性

  • 简单灵活

  • 分组传输

  • 路由选择

  • IP地址

  • 版本号

  • 协议类型

【7】Mac地址

  • 网卡

它又称物理地址,是指网络设备(如计算机、路由器、交换机、网卡)在制造时分配的全球唯一的地址

查找名为“物理地址”或“MAC地址”的字段

image-20240122185457204

【8】广播

  • 同一个局域网内进行数据交互

【9】TCP协议

  • 流式协议

  • 可靠

    • 基于一条通道进行传输的

    • 只有符合规范才会允许建立通道

(1)三次握手

  • 客户端向服务端发送连接请求(带着客户端的标识 aaa)

  • 服务端接收到客户端的连接请求,向客户端回请求(带着服务端的标识和客户端的标识 bbb)

  • 客户端和服务端进行建立连接

(2)四次挥手

  • 客户端向服务端发送断开请求

  • 服务端接受到客户端的请求,继续处理完没有完成的数据

  • 向客户端发送断开请求

  • 客户端接收到服务端的断开请求,断开连接

【10】UDP协议

  • 报式协议

UDP协议是在传输层的协议

特点:

  • 无连接性:UDP在发送数据之前不需要建立连接。

  • 简单快速:UDP的协议头部相对较小。通信开销夜宵,因此传输相对较快。

  • 不可靠性:UDP不提供可靠性保证,数据包的传输顺序不被保证。

  • 支持广播和多播:可以连接局域网的所有设备进行广播

  • 适用于实时应用:

【11】socket协适用于实时应用议

  • 如何建立TCP连接 / UDP连接

image-20240122192053942

什么是socket:

Scoket是可以理解为一种抽象端点,它可以用来建立网络连接、发送和接收数据。

Scocket是一种用于实现网络通信的编程接口,它允许应用程序通过网络在不同的计算机之间进行数据传输和同学。

【12】粘包问题

(1)产生原因

  • TCP的流式协议

  • 发送频率较快

(2)解决办法
  • 在服务端向客户端返回数据的时候加一个报头

    • 先获取到数据总长度

    • 把总长度打到字典里编程json字符串

    • json字符串转二进制

    • json二进制数的长度达成struct的包

      • 打出来的长度只有四个

    • 发送数据

      • 先发四个长度的struct

      • json二进制数据

      • 总数据

  • 客户端

    • 先接受4个长度的struct ---> 解包

    • json二进制数数据 ---> json字符串 -- 字典

    • 根据总的数据长度迭代取数据

【二】并发编程

【1】操作系统的发展史

(1)什么是操作系统:

操作系统是一种管理的计算机硬件的软件资源的程序。

(2)操作系统的概念

任何计算机系统都包含一个基本的程序集合,称为操作系统(OS),它是一个进行软硬件资源管理的软件

笼统的理解,操作系统包括:

内核(进程管理,内存管理,文件管理,驱动管理)

其他程序(例如函数库, shell程序等等)

为什么操作系统要管理软硬件呢?

image-20240116151639290

操作系统对下通过合理地管理软硬件资源(手段)对上来为用户提供良好的(稳定的、高效的,安全的)执行环境(目的)。

image-20240122191017938

【2】多道技术

  • 时间上的复用+空间上的复用,就成为多道技术

  • 空间上的复用:

    • 将内存分为几个部分,每个部分放入一个程序,这样,同一内存中就有了多道程序

  • 时间上的复用:

    • 将多个信号按照时间片刻划分的方式进行传输。每个信号在不同的时间段被发送,接收方根据时间信息来分离和恢复各个信号。

【3】进程理论

(1)程序和进程

  • 程序其实就是一堆代码和数据

  • 进程是跑起来的程序

(2)进程通信

  • 队列 先进先出

  • 管道 后进先出

举个例子来说明:

  • 队列:想象一下排队买票的情景,第一个来的人首先排在队列的最前面,当窗口处理完当前的人之后,队列中的下一个人才能进行处理。这就是典型的先进先出(FIFO)模式。

  • 堆栈:类似于叠放书本,每次新的书本都会放在堆栈的顶部,而取书的时候也是从顶部开始取。只有最上面的书本可见,其他书本需要先取走上面的书本才能看到下面的书本。这就是典型的后进先出(LIFO)模式。

【4】开启进程的两种方式

(1)Process类 进程

from multiprocessing import Process
​
def run():
    print('这个是子程序!')
​
if __name__ == '__main__':
    p = Process(target=run)
    # 启动程序
    p.start()
    # 结束程序
    p.join()
    # 这个是子程序!
# 进程
​
import multiprocessing
​
def run():
    print('这个是子程序!')
​
if __name__ == '__main__':
    p = multiprocessing.Process(target=run)
    # 启动程序
    p.start()
    # 结束程序
    p.join()
    # 这个是子程序!

(2)继承Process类

  • 重写了 run 方法

    import multiprocessing
    ​
    class MyProcess(multiprocessing.Process):
        def run(self):
            print('这是一个子进程!')
    ​
    if __name__ == '__main__':
        p = MyProcess()
        p.start()
        p.join()
    ​
    # 这是一个子进程!

(3)启动

task = Porcess(target=函数名,args=(参数))  
task.start() ---》 run方法
​
join方法 ---> 主进程等待所有子进程结束后再结束

线程的启动跟进程大致相同

import threading
​
class MyThread(threading.Thread):
    def run(self):
        print("Hello from a thread!")
​
if __name__ == "__main__":
    # 创建线程对象
    t = MyThread()
    
    # 启动线程
    t.start()
    
    # 等待线程结束
    t.join()
​

【5】进程理论的重要概念

(1)进程的状态

进程可以处于就绪、运行或者阻塞三种状态之一。

  • 就绪表示进程已经准备好允许

    • 但是处理器暂时没有空闲时间;

  • 运行状态表示进程正在执行;

  • 阻塞状态表示进程被正在执行

    • 直到某些时间(比如等待I/O操作)完成后再继续执行

(2)进程控制块

  • 进程控制块是操作系统为每个操作系统为每个进程所创建的数据结构

    • 用于保存进程本身的状态信息 比如进程(ID、优先级、上下文等)

  • PCB可以看作是程序和操作系统之间交互的纽带

    • 在进程需要进行状态切换时

    • 操作系统使用该数据结构记录并管理进程状态

(3)进程同步和进程通信

  • 当多个进程同时访问共享资源时,需要进行进程同步和协调。

    • 进程同步机制包括信号量、互斥量、条件变量等方式,以保证多个进程按照待定的顺序访问共享资源

    • 而进程通信机制包括管理、消息队列、共享内存等方式,让多个进程之间可以相互传递信息、协调工作、完成复杂的任务

【6】互斥锁

是一种同步机制,用于保护对共享资源的访问,避免多个线程同时修改共享数据造成的竞争条件。

  • 为了保护一个可能会被重复修改的数据

# 互斥锁
import threading
​
share_resourse = 45
lock = threading.Lock()
​
def run():
    global share_resourse
​
    # 获取互斥锁
    lock.acquire()
​
    # 访问共享资源
    share_resourse += 1
​
    # 释放互斥锁
    lock.release()
​
if __name__ == '__main__':
    threads = []
    for i in range(10):
        t = threading.Thread(target=run)
        threads.append(t)
        t.start()
​
        t.join()
​
        print(share_resourse)

【7】死锁和递归锁

死锁指的是在多线程或多进程环境中,两个或多个线程/进程无法继续执行,因为它们互相等待对方释放资源。

死锁的特点:

  1. 互斥:线程/进程持有至少一个资源,而这些资源只能被一个线程/进程同时占用

  2. 占有和等待:线程/进程已经占有一个资源,并等待获取其他资源。

  3. 不可剥夺:已经分配的资源不能被其他线程/进程强行剥夺。

  4. 环路等待:存在一个资源的循环等待待链,每个线程/进程都在等待下一个资源。

递归锁是一种特殊的互斥锁,允许同一个线程多次获取同一个锁。

递归锁的特点:

  1. 可以被联系的acquire和release

  2. 但是只能被第一个抢到这把锁执行上述操作

  3. 它的内部有一个计数器 每acquire 一次计数加一 每release 一次技术减一

  4. 只要技术不为0 那么其他人都无法抢到该锁

【8】生产和消费者模型

  • 生产者无法满足消费者

  • 引入了队列 ---> 标志位

  • joinable模块

    • join

    • task_done()

(1)生产者

生产者负责生成数据,并将数据放入共享的缓冲区。

(2)消费者

消费者则从缓冲区中获取数据进行处理。

import threading
import queue
import time
​
# 共享的缓冲区
buffer = queue.Queue(5)
​
# 退出标志位,初始为 False
exit_flag = False
​
# 生产者函数
def producer():
    while not exit_flag:
        # 模拟生产数据
        data = f'数据'
        print(f'生产者生产了:{data}')
        # 将数据放入缓冲区
        buffer.put(data)
        time.sleep(1)
​
# 消费者函数
def consumer():
    while not exit_flag or not buffer.empty():
        # 从缓冲区获取数据
        data = buffer.get()
        print(f'消费者消费了:{data}')
        # 模拟处理数据
        time.sleep(2)
        buffer.task_done()
​
if __name__ == '__main__':
    # 创建生产者线程
    producer_thread = threading.Thread(target=producer)
    # 创建消费者线程
    consumer_thread = threading.Thread(target=consumer)
​
    # 启动线程
    producer_thread.start()
    consumer_thread.start()
​
    # 等待用户输入,回车键退出
    
    input("按回车键退出程序\n")
​
    # 设置退出标志位为 True
    exit_flag = True
​
    # 等待线程结束
    producer_thread.join()
    consumer_thread.join()

小结:

【一】生产者和消费者模型总结 生产者 : 生产数据 生产完所有数据以后要加一个标志位 消费者 : 消费数据 从生产者生产的数据中拿出所有数据 【二】解决生产者和消费者不平稳一 Queue 在生产者生产数据的结尾 ---> 放一个标志位 消费者消费数据 ---> 消费到最后一个数据的时候,得到标志位知道生产的数据空了 --> 结束了 【三】解决生产者和消费者不平稳二 JoinableQueue

在生产者生产数据的结尾 ---> 放一个标志位 join() 在消费者消费数据的 ----> 正产消费 ---> 在消费数据的结尾 task_done() ---> 自动检索上面生产者是否存在 join\

【8】线程理论

线程是操作系统中能够独立执行的最小单位

  1. 轻量性:相比与进程,线程更加轻量级,创建和销毁线程的开销较小。

  2. 并发性:多个线程可以同时执行,实现并发处理。

  3. 共享内存:线程之间可以共享相同的地址空间,即它们可以访问相同的全局变量和静态变量。

  4. 同步机制:线程可以使用同步机制来协调彼此的行为,确保访问共享资源的顺序和正确性

  5. 运行状态:线程可以处于就绪、运行和阻塞三种状态。

  6. 上下文切换:线程之间的切换由操作系统负责,称为上下文切换。

  7. 缺乏独立性:相比于进程,线程之间的独立性较差。一个线程错会影响整个进程的稳定性。

【9】开启线程的两种方式

import threading
​
def my_function():
    # 线程执行的逻辑代码
    print("线程开始执行")
    for i in range(5):
        print(f"线程正在执行,当前值为:{i}")
    print("线程执行完毕")
​
# 创建线程对象并指定执行的函数
my_thread = threading.Thread(target=my_function)
​
# 启动线程
my_thread.start()
# 线程开始执行
# 线程正在执行,当前值为:0
# 线程正在执行,当前值为:1
# 线程正在执行,当前值为:2
# 线程正在执行,当前值为:3
# 线程正在执行,当前值为:4
# 线程执行完毕

第二种

import threading

class MyClass:
    def __call__(self):
        # 线程执行的逻辑代码
        print("线程开始执行")
        for i in range(5):
            print(f"线程正在执行,当前值为:{i}")
        print("线程执行完毕")

# 创建可调用对象的实例
my_object = MyClass()

# 创建线程对象并指定执行的方法
my_thread = threading.Thread(target=my_object)

# 启动线程
my_thread.start()
# 线程开始执行
# 线程正在执行,当前值为:0
# 线程正在执行,当前值为:1
# 线程正在执行,当前值为:2
# 线程正在执行,当前值为:3
# 线程正在执行,当前值为:4
# 线程执行完毕

【10】线程池和进程池

进程池/线程池是一组预先创建的进程/线程,这些可以并行地执行任务。

# 线程池
import concurrent.futures

# 定义任务函数
def task_func(num):
    print(f'执行任务 {num}')
    result = num * 2
    return result


if __name__ == '__main__':
    # 创建线程池, 指定线程数量为4
    pool = concurrent.futures.ThreadPoolExecutor(max_workers=4)
    # 定义任务列表
    tasks = [1, 2, 3, 4, 5, 6, 7]
    # 使用进程池执行任务
    results = pool.map(task_func, tasks)
    # 关闭进程池
    pool.shutdown()

    print(list(results))
    # 执行任务1
    # 执行任务2
    # 执行任务3
    # 执行任务4
    # 执行任务5
    #
    # 执行任务6
    # 执行任务7
    # [2, 4, 6, 8, 10, 12, 14]

【11】GIL全局解释器锁

(1)面试题(为什么有了GIL锁还要互斥锁)

是一种CPython解释器中使用的机制, 它保证统一时刻只有一个线程执行Python字节码。

(2)注意:

GIL(全局解释器)只存在于CPython解释器中,同时Python解释器的一个特定实现。其他编程语言和环境没有这个概念。

GIL是保证解释器级别的数据的安全 。

同一个进程下的多个线程无法利用多核优势!

【12】协程

  • 必须在只有一个单线程里实现并发

  • 修改共享数据不需要加锁

  • 用户程序里自己保存多个控制流的上下文栈

  • 附加:一个协程遇到IO操作自动切换到其他协程(如何实现检测IO、yield、greenlet都无法实现,就用到了gevent模块(select机制))

协程是一个轻量级的线程,可以避免线程切换带来的开销和复杂性。协程可以看作是一种特殊的函数,可以在任意时刻暂停执行,并在稍后恢复执行。

【13】IO模型的了解

I/O模型指的是在进行输入/输出操作时,应用程序与底层操作系统之间的交互方式。它描述了数据在应用程序和底层设备之间传输的方式和机制。

阻塞

非阻塞

I/O多路复用

信号驱动

异步

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

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

相关文章

32GPIO输入LED闪烁蜂鸣器

一.GPIO简介 所有的GPIO都挂载到APB2上,每个GPIO有16个引脚 内核可以通过APB2对寄存器进行读写,寄存器都是32位的,但每个引脚端口只有16位 驱动器用于增加信号的驱动能力 二.具体…

Android系统开发之TimeZoneDetectorService浅析--下

TimeZoneDetectorService类图 可以看出TimeZoneDetectorService类,其具体实现是由TimeZoneDetectorStrategy类完成的。 在TimeZoneDetectorService类中,三种更新时区的接口分别为: suggestGeolocationTimeZone() //更新时区主要有三种方式…

linux安装docker-compose

前言 如果你的docker版本是23,请移步到linux安装新版docker(23)和docker-compose这篇博客 查看docker版本命令: docker --version今天安装docker-compose的时候,找了很多教程,但是本地一直报错&#xff0…

【mongoDB】图形化界面工具(mongoDB Compass)

官网地址:https://www.mongodb.com/try/download/compass 下载完之后直接安装 桌面上会产生一个快捷方式 双击就会进入mongoDB图形化界面工具

MMDetection

什么是MMDetection MMDetection实际上是一个用于目标检测的工具包,面向深度学习时代的。 任务支持 目标检测 实例分割 覆盖广泛 440个预训练模型 60篇论文复现 常用学术数据集 算法丰富 两阶段检测器 一阶段检测器 级联检测器 无锚框检测器 Transform…

【HTML 基础】介绍

文章目录 定义作用基本概念1. 标签(Tags)2. 元素(Elements)3. 属性(Attributes)4. 文档结构 总结 HTML(HyperText Markup Language)是构建世界各地互联网页面的基本构建块之一。作为…

BIOS与CMOS的区别

在日常操作和维护计算机的过程中,常常可以听到有关BIOS设置和CMOS设置的一些说法,许多人对BIOS和CMOS经常混为一谈。下面介绍一些BIOS设置和CMOS设置在基本概念上的区分与联系。 BIOS是什么? 所谓BIOS,实际上就是微机的基本输入输出系统&…

实现上下文初始化参数

实现上下文初始化参数 问题方案 要解决上述问题,需要执行以下任务: 创建Web应用程序。创建检索初始化参数的servlet。指定初始化参数。构建Web应用程序。访问servlet。1. 创建Web应用程序 要使用NetBeans IDE创建Web应用程序,需要执行以下步骤: 选择“开始”→“所有程序”…

MySQL-进阶-SQL优化

一、insert优化 插入大量数据 二、主键优化 1、数据组织方式 2、页分裂 3、页合并 4、逐渐设计原则 三、order by优化 四、group by优化 五、limit优化 六、count优化 七、update优化

如何通过 Nginx 反向代理提高网站安全性和性能?

如何通过 Nginx 反向代理提高网站安全性和性能? 引言Nginx 反向代理的基本原理什么是反向代理?反向代理的工作方式反向代理的好处 配置 Nginx 反向代理的基本步骤1. 安装 Nginx2. 编辑 Nginx 配置文件3. 设置反向代理配置4. 测试并重启 Nginx 提高安全性…

函数式接口当参数使用

如果函数式接口作为一个方法的参数,就以为着要方法调用方自己实现业务逻辑,常见的使用场景是一个业务整体逻辑是不相上下的,但是在某一个步骤有不同的逻辑,例如数据处理有不同的策略。上代码 package com.dj.lambda;import java.…

Docker Image(镜像)

Docker镜像是什么 Docker image 本质上是一个 read-only 只读文件,这个文件包含了文件系统、源码、库文件、依赖、工具等一些运行 application 所必须的文件。我们可以把 Docker image 理解成一个模板, 可以通过这个模板实例化出来很多容器。image 里面…

Nestjs 全局拦截器

一、拦截器 拦截器作用: 在函数执行之前、之后绑定额外的逻辑转换函数的返回结果转换从函数抛出的异常扩展基本函数的行为根据所选条件重写函数 期望接口返回一个标准的json格式,利用拦截器对数据做全局的格式化 {code: "200",data: [],mess…

Nginx解析漏洞(nginx_parsing_vulnerability)

目录 Nginx解析漏洞 环境搭建 复现 漏洞利用 Nginx解析漏洞 NGINX解析漏洞主要是由于NGINX配置文件以及PHP配置文件的错误配置导致的。这个漏洞与NGINX、PHP版本无关,属于用户配置不当造成的解析漏洞。具体来说,由于nginx.conf的配置导致nginx把…

在JavaScript中创建自定义错误

🧑‍🎓 个人主页:《爱蹦跶的大A阿》 🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ 目录 ✨ 前言 ✨ 正文 简介 创建自定义错误 自定义错误属性 instanceof 检…

C#实现对任意区域任意大小的截图

1,目的: 实现类似系统截图工具那样对屏幕任何区域自定义大小的截图。 2,效果展示: 点击截图 选择需要截图的区域: 区域选择完成后,单击右键完成截图: 在合适的载体上粘贴截图: 3,…

【笔记】顺利通过EMC试验(1-15)-视频笔记

目录 视频链接 P2:电子设备的电磁兼容性要求 P3:怎样分析一个电磁兼容的问题 P4:EMC试验注意事项 P5:骚扰源有什么特征 P6:什么是传导骚扰发射 P7:什么是辐射骚扰发射 P8:环路天线的辐射特性 P9:偶极天线的辐…

QT之 QDebug 调试(一)

在QT中&#xff0c;进行调试&#xff0c;则需要在头文件地方加上 #include <QDebug> 加上之后&#xff0c;在编译之后则其输出的信息则在应用程序输出那里显示信息。 其QDebug 信息调试则如&#xff1a; qDebug() << " 需要插入的信息 "…

【Linux】从C语言文件操作 到Linux文件IO | 文件系统调用

文章目录 前言一、C语言文件I/O复习文件操作&#xff1a;打开和关闭文件操作&#xff1a;顺序读写文件操作&#xff1a;随机读写stdin、stdout、stderr 二、承上启下三、Linux系统的文件I/O系统调用接口介绍open()close()read()write()lseek() Linux文件相关重点 复习C文件IO相…

南京观海微电子---如何减少时序报告中的逻辑延迟

1. 引言 在FPGA逻辑电路设计中&#xff0c;FPGA设计能达到的最高性能往往由以下因素决定&#xff1a; ▪ 工作时钟偏移和时钟不确定性&#xff1b; ▪ 逻辑延迟&#xff1a;在一个时钟周期内信号经过的逻辑量&#xff1b; ▪ 网络或路径延迟&#xff1a;Vivado布局布线后引…