当前位置: 首页 > news >正文

IO-操作系统

用户态和内核态

        现代操作系统,为了保护系统的安全,都会划分出内核空间和用户空间,或者我们经常说的内核态和用户态。简单来说,就是划分为内核态和用户态两个等级,运行在用户态的进程大都是一些应用程序,能够访问的系统资源受到极大的限制。而运行在内核态的进程权限就非常大,可以"为所欲为”。
        这么做的目的是为了保护操作系统的底层资源,例如文件都要存在硬盘,但是如果用户编写的应用程序可以随意的操作硬盘的启动扇区,那就很容易把系统搞崩溃,分为内核态和用户态之后,用户态的应用程序就不能直接操作底层的硬件接口了,如果需要操作硬盘,比如存文件,那就必须经过内核态来协调。这样就可以对所有底层硬件的操作方式进行规范。
        有了用户态和内核态的划分后,应用程序就经常需要在用户态和内核态之间进行切换。例如程序要保存一个文件到硬盘,在程序执行的用户态,是不能直接操作磁盘的。只有切换到内核态才能真正去操作磁盘。
        内核态运行操作系统程序,操作硬件,用户态运行用户程序;当程序运行在 3 级特权级上时,可以称之为运行在用户态,当程序运行在 0 级特权级上时,称之为运行在内核态。
        特权级别
        R0、R1、R2 和 R3
        R0 相当于内核态,R3 相当于用户态;
        不同级别能够运行不同的指令集合;

IO

        IO,英文全称是 Input/Output,翻译过来就是输入/输出。我们听得挺多,就是磁盘 IO,网络 IO 等。
        IO 即输入/输出,到底谁是输入?谁是输出?IO 如果脱离了主体,会让人疑惑。

 

计算机角度的 IO

        我们常说的输入输出,比较直观的意思就是计算机的输入输出计算机就是主体
        计算机分成分为 5 个部分:运算器、控制器、存储器、输入设备、输出设备。

 

        输入设备是向计算机输入数据和信息的设备,键盘,鼠标都属于输入设备;输出设备是计算机硬件系统的终端设备,用于接收计算机数据的输出显示,一般显示器、打印机属于输出设备。

操作系统角度的 IO

        我们要将内存中的数据写入到磁盘的话,那么主体就是一个程序. 操作系统负责计算机的资源管理和进程的调度,我们电脑上跑着的应用程序,其实是需要经过操作系统,才能做一些特殊操作,如磁盘文件读写、内存的读写等等。
        真正的 IO 是在操作系统执行的。即应用程序的 IO 操作分为两种动作:IO 调用和 IO 执行。IO 调用是由进程(应用程序的运行态)发起,而 IO 执行是操作系统内核的工作。
        应用程序发起的一次 IO 操作包含两个阶段:
                IO 调用:应用程序进程向操作系统内核发起调用。
                IO 执行:操作系统内核完成 IO 操作。

 

IO 模型

阻塞 IO

        假设应用程序的进程发起 IO 调用,但是如果内核的数据还没准备好的话,那应用程序进程就一直在阻塞等待,一直等到内核数据准备好了,从内核拷贝到用户空间,才返回成功提示,此次 IO 操作,称之为阻塞 IO
        阻塞 IO 比较经典的应用就是阻塞 socket、Java BIO。阻塞 IO 的缺点就是:如果内核数据一直没准备好,那用户进程将一直阻塞,浪费性能,可以使用非阻塞IO 优化。

非阻塞 IO

        如果内核数据还没准备好,可以先返回错误信息给用户进程,让它不需要等待,而是通过轮询的方式再来请求。这就是非阻塞 IO。 

 

非阻塞 IO 的流程如下:
  • 应用进程向操作系统内核,发起 recvfrom( )读取数据。
  • 操作系统内核数据没有准备好,立即返回 EWOULDBLOCK 错误码。
  • 应用程序进程轮询调用,继续向操作系统内核发起 recvfrom 读取数据。
  • 操作系统内核数据准备好了,从内核缓冲区拷贝到用户空间。
  • 完成调用,返回成功提示。
        recvfrom()用来接收远程主机经指定的 socket 传来的数据,并把数据传到由参数buf 指向的内存空间.
        非阻塞 IO 模型,简称 NIO,Non-Blocking IO。它相对于阻塞 IO,虽然大幅提升了性能,但是它依然存在性能问题,即频繁的轮询,导致频繁的系统调用,同样会消耗大量的 CPU 资源。可以考虑 IO 复用模型,去解决这个问题。

IO 多路复用

概述

        既然 NIO 无效的轮询会导致 CPU 资源消耗,我们等到内核数据准备好了,主动通知应用进程再去进行系统调用。
        IO 复用模型核心思路:系统给我们提供一类函数(如 select、poll、epoll),它们可以同时监控多个 fd 的操作,任何一个返回内核数据就绪,应用进程再发起 recvfrom 系统调用。
        文件描述符 fd(File Descriptor),它是计算机科学中的一个术语,形式上是一个非负整数。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。

 IO 多路复用之 select

        应用进程通过调用 select 函数,可以同时监控多个 fd,在 select 函数监控的 fd中,只要有任何一个数据状态准备就绪了,select 函数就会返回可读状态,这时应用进程再发起 recvfrom( )请求去读取数据。
        非阻塞 IO 模型(NIO)中,需要 N(N>=1)次轮询系统调用,然而借助select 的 IO 多路复用模型,只需要发起一次询问就够了,大大优化了性能。
        但是呢,select 有几个缺点:
                监听的 IO 最大连接数有限,在 Linux 系统上一般为 1024。select 函数返回后,是通过遍历 fdset,找到就绪的描述符 fd。(仅知道有 I/O 事件发生,却不知是哪几个流,所以遍历所有流). 因为存在连接数限制,所以后来又提出了poll。与 select 相比,poll 解决了连接数限制问题。但是,select 和 poll 一样,还是需要通过遍历文件描述符来获取已经就绪的 socket。如果同时连接的大量客户端,在一时刻可能只有极少处于就绪状态,伴随着监视的描述符数量的增长,
效率也会线性下降
        因此经典的多路复用模型 epoll 诞生。

IO 多路复用之 epoll

        为了解决 select/poll 存在的问题,多路复用模型 epoll 诞生,它采用事件驱动来实现,流程图如下:
        epoll 先通过 epoll_ctl()来注册一个 fd(文件描述符),一旦基于某个 fd 就绪时,内核会采用回调机制,迅速激活这个 fd,当进程调用 epoll_wait()时便得到通知。这里去掉了遍历文件描述符的坑爹操作,而是采用监听事件回调的机制。
        这就是 epoll 的亮点。
总结一下 select、poll、epoll 的区别
        epoll 明显优化了 IO 的执行效率,但在进程调用 epoll_wait()时,仍然可能被阻塞。能不能不用我老是去问你数据是否准备就绪,等我发出请求后,你数据准备好了通知我就行了,这就诞生了信号驱动 IO 模型

IO 模型之信号驱动模型

        信号驱动不再用主动询问的方式去确认数据是否就绪,而是向内核发送一个信号,然后应用用户进程可以去做别的事,不用阻塞。当内核数据准备好后,再通过信号通知应用进程,数据准备好后的可读状态。应用用户进程收到信号之后,立即调用 recvfrom,去读取数据。
        信号驱动 IO 模型,在应用进程发出信号后,是立即返回的,不会阻塞进程。它已经有异步操作的感觉了。但是上面的流程图,发现数据复制到应用缓冲的时候,应用进程还是阻塞的。回过头来看下,不管是 BIO,还是 NIO,还是信号驱动,在数据从内核复制到应用缓冲的时候,都是阻塞的。

         还有没有优化方案呢?AIO(真正的异步 IO)!

异步 IO(AIO asynchronous IO)

        前面讲的 BIO,NIO 和信号驱动,在数据从内核复制到应用缓冲的时候,都是阻塞的,因此都不算是真正的异步。AIO 实现了 IO 全流程的非阻塞,就是应用进程发出系统调用后,是立即返回的,但是立即返回的不是处理结果,而是表示提交成功类似的意思。等内核数据准备好,将数据拷贝到用户进程缓冲区,发送信号通知用户进程 IO 操作执行完毕。
        流程如下:

 

        异步 IO 的优化思路很简单,只需要向内核发送一次请求,就可以完成数据状态询问和数据拷贝的所有操作,并且不用阻塞等待结果。日常开发中,有类似思想的业务场景:
        比如发起一笔批量转账,但是批量转账处理比较耗时,这时候后端可以先告知前端转账提交成功,等到结果处理完,再通知前端结果即可。
阻塞、非阻塞、同步、异步 IO 划分:

 

        一个通俗例子读懂 BIO、NIO、AIO
        同步阻塞(blocking-IO)简称 BIO
        同步非阻塞(non-blocking-IO)简称 NIO
        异步非阻塞(asynchronous-non-blocking-IO)简称 AIO
一个经典生活的例子:
BIO
        小明去吃同仁四季的椰子鸡,就这样在那里排队,等了一小时,轮到她了,然后才开始吃椰子鸡。
NIO
        小红也去同仁四季的椰子鸡,她一看要等挺久的,于是去逛会商场,每次逛一下,就跑回来看看,是不是轮到她了。于是最后她既购了物,又吃上椰子鸡了。
AIO
        小华一样,去吃椰子鸡,由于他是高级会员,所以店长说,你去商场随便逛会吧,等下有位置,我立马打电话给你。于是小华不用干巴巴坐着等,也不用每过一会儿就跑回来看有没有等到,最后也吃上了美味的椰子鸡
Java NIO 概述
        Java NIO(Non Blocking IO)是从 Java 1.4 版本开始引入的一个新的 IO API,可以替代标准的 Java IO API,NIO 支持面向缓冲区的、基于通道的 IO 操作。NIO 将以更加高效的方式进行文件的读写操作。

阻塞 IO(Blocking I/O BIO)

        通常在进行同步 I/O 操作时,如果读取数据,代码会阻塞直至有可供读取的数据。同样,写入调用将会阻塞直至数据能够写入。
        传统的 Server/Client 模式服务器会为每个客户端请求建立一个线程,由该线程单独负责处理一个客户请求。
        这种模式带来的一个问题就是线程数量的剧增,大量的线程会增大服务器的开销。大多数的实现为了避免这个问题,都采用了线程池模型,并设置线程池线程的最大数量,这由带来了新的问题,如果线程池中有 100 个线程,而有 100 个用户都在进行大文件下载,会导致第 101 个用户的请求无法及时处理,即便第 101 个用户只想请求一个几 KB 大小的页面。传统的 Server/Client 模式如下图所示:

非阻塞( non-blocking IO NIO) 

核心思想
        NIO 中非阻塞 I/O 调用不会被阻塞,核心是注册感兴趣的特定 I/O 事件,如可读数据到达,新的套接字连接等等,在发生特定事件时,系统再通知我们。
        NIO 中实现非阻塞 I/O 的核心对象就是 Selector.
        Selector 就是注册各种 I/O 事件地方,而且当我们感兴趣的事件发生时,就是这个对象告诉我们所发生的事件,如下图所示:
        从图中可以看出,当有读或写等任何注册的事件发生时,可以从 Selector 中获得相应的 SelectionKey,同时从 SelectionKey 中可以找到发生的事件和该事件所发生的具体的 SelectableChannel,以获得客户端发送过来的数据。
        非阻塞指的是 IO 事件本身不阻塞,但是获取 IO 事件的 select()方法是需要阻塞等待的.
        区别是 BIO 会阻塞在 IO 操作上,NIO 阻塞在事件获取上,没有事件就没有IO,从高层次看 IO 就不阻塞了.

NIO

Java NIO 核心部分组成
        Channels
        Buffers
        Selectors
        虽然 Java NIO 中除此之外还有很多类和组件,但 Channel,Buffer 和Selector 构成了核心的 API。其它组件,如 Pipe 和 FileLock,只不过是与三个核心组件共同使用的工具类。

Channel

        Channel,可以翻译成“通道”。Channel 和 IO 中的 Stream(流)是差不多一个等级的。只不过 Stream 是单向的,譬如:InputStream,OutputStream.
        而 Channel 是双向的,既可以用来进行读操作,又可以用来进行写操作。因为Channel 是全双工的,所以它可以比流更好地映射底层操作系统的 API。
        Channel 是一个对象,可以通过它读取和写入数据。所有数据都通过 Buffer对象来处理。你永远不会将字节直接写入通道中,相反,您是将数据写入包含一个或者多个字节的缓冲区。同样,您不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。
        NIO 中的 Channel 的主要实现有:
                FileChannel:从文件中读写数据
                DatagramChannel:通过 UDP 读写网络中的数据
                SocketChannel:通过 TCP 读写网络中的数据
                ServerSocketChannel:可以监听新进来的 TCP 连接

 

Buffer

        Java NIO 中的 Buffer 用于和 NIO 通道进行交互。数据是从通道读入缓冲区,从缓冲区写入到通道中的。
        缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成 NIO Buffer 对象,并提供了一组方法,用来方便的访问该块内存。
        NIO 中的关键的 Buffer 实现有:
                ByteBuffer
                CharBuffer
                ShortBuffer
                IntBuffer
                LongBuffer
                FloatBuffer
                DoubleBuffer
        对数据的读取/写入需要使用 buffer,buffer 本质就是一个数组
        常用方法:
                ByteBuffer.allocate(1024); 创建字节数据
                byteBuffer.flip(); 翻转这个缓冲区,读操作前使用
                byteBuffer.clear(); 清除缓存,写操作前使用
一个基本的 NIO 案例
FileInputStream in = new FileInputStream("E:/source.txt");
FileOutputStream out = new FileOutputStream("E:/dest.txt");
FileChannel inchannel = in.getChannel();
FileChannel outchannel = out.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);while(inchannel.read(byteBuffer)!=-1){byteBuffer.flip();outchannel.write(byteBuffer);byteBuffer.clear();}

Selector

        Selector 一般称为选择器。它是 Java NIO 核心组件中的一个,用于检查一个或多个 NIO Channel(通道)的状态是否处于可读、可写。如此可以实现单线程管理多个 channels,也就是可以管理多个网络链接。
        使用 Selector 的好处在于:使用更少的线程来就可以来处理通道了,相比使用多个线程,避免了线程上下文切换带来的开销。

 

相关文章:

IO-操作系统

用户态和内核态 现代操作系统,为了保护系统的安全,都会划分出内核空间和用户空间,或者我们经常说的内核态和用户态。简单来说,就是划分为内核态和用户态两个等级,运行在用户态的进程大都是一些应用程序,能够…...

Downie 4 4.6.12 MAC上最好的一款视频下载工具

Downie for Mac 简介 Downie是Mac下一个简单的下载管理器,可以让您快速将不同的视频网站上的视频下载并保存到电脑磁盘里然后使用您的默认媒体播放器观看它们。 Downie 4 Downie 4 for Mac Downie 4 for Mac软件特点 支持许多站点 -当前支持1000多个不同的站点&…...

unity 玩家移动时idle和run动画频繁切换

项目场景: unity 控制玩家移动 问题描述 idle和run动画频繁切换 void Movement(){ xVelocity Input.GetAxisRaw("Horizontal"); anim.SetFloat("speed",Mathf.Abs(rb.velocity.x));//跑动动画 if(xVelocity !0){ transform.localScal…...

小程序 table组件

最近有在小程序中用table的需求,但是没有找到有符合要求的组件,所以自己弄了一个,能满足基本需求。 组件下载:https://download.csdn.net/download/weixin_67585820/85047405 引入 "usingComponents": {"table": "…...

利用摄影测量进行地形建模的介绍

一、前言 从一个地方到另一个地方的地球表面由连续和突然的海拔变化组成,个人和社会都必须应对这些变化。 水从高山和丘陵向下流,从溪流流入河流,形成三角洲,最终汇入大海。 三维 (3D) 地面信息的获取和表示一直是与行星表面相关的…...

中文代码138

邢唷?? > ? ? ? ? ? ? ?R o o t E n t r y ? F 喹8N"a? ? S u m m a r y I n f …...

JQuery用法

JQuery 优点 : (1)提供了强大的功能函数 (2)解决浏览器兼容性问题 (3)实现丰富的 UI 和插件 (4)纠正错误的脚本知识… 1、Jquery对象 $ 符号在 jQuery 中代表对 jQuery 对象的引用,…...

Python采集热门城市景点数据+简单制作数据可视化图

人生苦短,我用python 真的好想出去玩啊!!! 春游啊这是!!! 万物复苏的好季节!!! python 安装包资料:点击此处跳转文末名片获取 一、模块使用: …...

VUE-cli搭建项目

vue-cli 官方提供的一个脚手架,用于快速生成一个 vue 的项目模板;预先定义好的目录结构及基础代码,就好比咱们在创建 Maven 项目时可以选择创建一个骨架项目,这个骨架项目就是脚手架,我们的开发更加的快速;…...

Feign返回值统一处理

背景 服务端的接口一般有固定的返回格式&#xff0c;有数据、返回码和异常时错误信息。结构如下 Data public class BaseResponse<T> {private String code;private String message;private T data;public boolean isSuccess() {return "SUCCESS".equals(cod…...

探究如何在Linux系统中修改进程资源限制:四种方法调整进程限制,让你的系统高效运行(包含应用层getrlimit和setrlimit API)

探究如何在Linux系统中修改进程资源限制1.进程资源限制的概念2.修改进程资源限制的意义与应用场景1.软限制与硬限制2.常见资源限制类型Linux中的资源限制1.ulimit命令a. 语法及选项b. 示例与应用2./etc/security/limits.conf配置文件a. 配置文件结构b.示例与应用3. 使用cgroups…...

9.5. 机器翻译与数据集

笔记 9.5. 机器翻译与数据集 — 动手学深度学习 2.0.0 documentation 1.下载文件 读文件 2.处理数据 在所有标点符号前面加空格 后面用于分割 因为法语英语可能有半角全角的字符区分用utf编码的方式统一成半角字符的空格 3.因为分隔用的是空格split 所有vocab是没有空格的 …...

跟着凯新生物2 Arm PEG Biotin,2-Branched PEG Biotin,生物素-聚乙二醇-二臂/支,学试剂知识

中英文名&#xff1a;2 Arm/Branched PEG Biotin&#xff0c;2 ArmPEG Biotin&#xff0c;二臂/支 PEG 生物素一、Product specifications&#xff1a; 1.CAS No&#xff1a;N/A 2.Packaging specification&#xff1a;10mg&#xff0c;25mg&#xff0c;50mg, flexible packagi…...

react组件进阶(四)

文章目录1. 组件通讯介绍2. 组件的 props3. 组件通讯的三种方式3.1 父组件传递数据给子组件3.2 子组件传递数据给父组件3.3 兄弟组件4. Context5. props 深入5.1 children 属性5.2 props 校验5.3 props 的默认值6. 组件的生命周期6.1 组件的生命周期概述6.2 生命周期的三个阶段…...

阿维塔城区NCA智驾导航辅助,复杂路口,全面胜任

阿维塔11城区NCA智驾导航辅助将于3月在上海、深圳等城市分阶段开启体验&#xff0c;以看得清、判得准、控得稳的“智驾”&#xff0c;进一步巩固业界智能天花板的地位。智能驾驶里程碑&#xff0c;拨杆两下开启都市安适旅程作为AVATRANS智能领航系统的重要组成部分&#xff0c;…...

[Pandas] div()函数

div()方法将DataFrame中的每个值除以指定的值&#xff0c;并返回一个计算处理后的Dataframe结果 DataFrame.div()函数其实是除法运算&#xff0c;表格中的每个数据都是被除数 导入数据 import pandas as pd df pd.DataFrame({"col1":[5, 3, None, 4], "col2…...

c++并发与多线程

c并发与多线程 子线程结束&#xff0c;主线程不能结束&#xff0c;否则会出错&#xff0c;和java不一样。 可以用join的方式让主线程等待子线程执行结束。 quickStart 线程相关头文件 #include <thread> 使用全局函数构造一个线程对象 #include <iostream> #…...

Vinylsulfone PEG Biotin,Biotin-PEG-VS,生物素聚乙二醇乙烯砜,VS基团容易与游离巯基发生反应

●中文名&#xff1a;乙烯砜PEG生物素&#xff0c;生物素聚乙二醇乙烯砜 ●英文名&#xff1a;Vinylsulfone PEG Biotin, VS-PEG-Biotin&#xff0c;Vinyl sulfone-PEG-Biotin&#xff0c;Biotins-PEG-sulfone Vinyl●产品理化指标&#xff1a; CAS号&#xff1a;N/A 分子量&am…...

论文学习——Tune-A-Video

Tune-A-Video: One-Shot Tuning of Image Diffusion Models for Text-to-Video Generation Abstract 本文提出了一种方法&#xff0c;站在巨人的肩膀上——在大规模图像数据集上pretrain并表现良好的 text to image 生成模型——加入新结构并进行微调&#xff0c;训练出一套 …...

C++类与对象part1

目录 1.类的6个默认函数 2.构造函数&#xff08;相当于init&#xff09; 3.析构函数 &#xff08;相当于destroy&#xff09; 4.拷贝构造函数 赋值运算符重载 运算符重载 赋值运算符重载 引入&#xff1a; 你知道为什么cout可以自动识别类型吗&#xff1f; 其实cout是一…...

记一次抓取网页内容

已打码 // UserScript // name --------- // namespace http://tampermonkey.net/ // version 0.1 // description https://---------oups/{id}/topics?scopeall&count20&begin_time2022-09-01T00%3A00%3A00.000%2B0800&end_time2022-10-01T00%…...

parasoft帮助史密斯医疗通过测试驱动开发提供安全、高质量的医疗设备

parasoft是一家专门提供软件测试解决方案的公司&#xff0c;Parasoft通过其经过市场验证的自动化软件测试工具集成套件&#xff0c;帮助企业持续交付高质量的软件。Parasoft的技术支持嵌入式、企业和物联网市场&#xff0c;通过将静态代码分析和单元测试、Web UI和API测试等所有…...

SpringBoot整合Oauth2开放平台接口授权案例

<!-- SpringBoot整合Web组件 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId>&l…...

Linux_创建用户

创建一个名为hello的用户&#xff0c;并指定/home/hello为根目录useradd -d /home/hello -m hello 设置密码 ,密码会输入两次&#xff0c;一次设置密码&#xff0c;一次确认密码&#xff0c;两次密码要输入的一样passwd hellouseradd的常用参数含义-d指定用户登入时的主目录&am…...

RDD(弹性分布式数据集)总结

文章目录一、设计背景二、RDD概念三、RDD特性四、RDD之间的依赖关系五、阶段的划分六、RDD运行过程七、RDD的实现一、设计背景 1.某些应用场景中&#xff0c;不同计算阶段之间会重用中间结果&#xff0c;即一个阶段的输出结果会作为下一个阶段的输入。如&#xff1a;迭代式算法…...

服务器版RstudioServer安装与配置详细教程

Docker部署Rstudio server 背景&#xff1a;如果您想在服务器上运行RstudioServer&#xff0c;可以按照如下方法进行操作&#xff0c;笔者测试时使用腾讯云服务器&#xff08;系统centos7&#xff09;&#xff0c;需要在管理员权限下运行 Rstudio 官方提供了使用不同 R 版本的 …...

如何在Java中将一个列表拆分为多个较小的列表

在Java中&#xff0c;有多种方法可以将一个列表拆分为多个较小的列表。在本文中&#xff0c;我们将介绍三种不同的方法来实现这一目标。 方法一&#xff1a;使用List.subList()方法 List接口提供了一个subList()方法&#xff0c;它可以用来获取列表中的一部分元素。我们可以使…...

TryHackMe-Inferno(boot2root)

Inferno 现实生活中的机器CTF。该机器被设计为现实生活&#xff08;也许不是&#xff1f;&#xff09;&#xff0c;非常适合刚开始渗透测试的新手 “在我们人生旅程的中途&#xff0c;我发现自己身处一片黑暗的森林中&#xff0c;因为直截了当的道路已经迷失了。我啊&#xf…...

微信原生开发中 JSON配置文件的作用 小程序中有几种JSON配制文件

关于json json是一种数据格式&#xff0c;在实际开发中&#xff0c;JSON总是以配制文件的形式出现&#xff0c;小程序与不例外&#xff0c;可对项目进行不同级别的配制。Q&#xff1a;小程序中有几种配制文件A:小程序中有四种配制文件分别是&#xff1a;project.config.json si…...

【python】为什么使用python Django开发网站这么火?

关注“测试开发自动化” 弓中皓&#xff0c;获取更多学习内容&#xff09; Django 是一个基于 Python 的 Web 开发框架&#xff0c;它提供了许多工具和功能&#xff0c;使开发者可以更快地构建 Web 应用程序。以下是 Django 开发中的一些重要知识点&#xff1a; MTV 模式&#…...

app设计网站推荐/谷歌 chrome 浏览器

UDP(User Data Protocol&#xff0c;用户数据报协议)(1) UDP是一个非连接的协议&#xff0c;传输数据之前源端和终端不建立连接&#xff0c;当它想传送时就简单地去抓取来自应用程序的数据&#xff0c;并尽可能快地把它扔到网络上。在发送端&#xff0c;UDP传送数据的速度仅仅是…...

北京单页营销型网站/品牌运营推广方案

我正在用PHP编写一个基本的莫尔斯代码转换器,它可以接受一个字符串并将其转换为莫尔斯代码.它使用了一个关联数组,一个foreach循环和一个for循环.它有效,除了某些原因它在每个转换后的字符后输出等效于’0’的莫尔斯码.我无法弄清楚0的来源.如果我从关联数组中删除0,没有问题,但…...

wordpress前台主题切换/扫一扫识别图片

文章目录1、闭包的概念2、实现一个闭包3、在闭包中外函数把临时变量绑定给内函数4、闭包中内函数修改外函数局部变量5、注意&#xff1a;6、练习&#xff1a;1、闭包的概念 请大家跟我理解一下&#xff0c;如果在一个函数的内部定义了另一个函数&#xff0c;外部的我们叫他外函…...

湘潭哪里做网站 电话/如何创建公司网站

这篇文章主要介绍了Python常用模块sys,os,time,random功能与用法,结合实例形式分析了Python模块sys,os,time,random功能、原理、相关模块函数、使用技巧与操作注意事项,需要的朋友可以参考下 本文实例讲述了Python常用模块sys,os,time,random功能与用法。分享给大家供大家参考&…...

怎样做可以连接服务器的网站/关键词营销优化

初始Linux操作系统&#xff08;手把手带你拿捏&#xff0c;一步一步进行操作讲解&#xff09; 备注&#xff1a; 楼主不才&#xff0c;不喜勿喷&#xff0c;若有错误或需要改进的地方&#xff0c;非常感谢你的指出&#xff0c;我会积极学习采纳。谢谢家人们一直以来的支持和鼓…...

国际企业网站建设/郑州seo顾问热狗

在Unity3D中动态创建对象和创建Prefab原型对象的三种方式u3d里动态创建对象&#xff0c;需要使用prefab而创建的时候 MonoBehaviour.Instantiate( GameObject orignal) 需要一个作为原型的对象。本文提供三种方式获得prefab对象。方式一&#xff1a;使用脚本的public字段直接在…...