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

Django框架的推导

文章目录

  • Web应用简介
    • 什么是Web框架?
    • 什么是Web?
    • 应用程序的两种模式
    • Web应用程序的优缺点
  • 手写Web框架
    • HTTP协议的相关知识
      • 1.四大特性
      • 2.请求数据格式
      • 3.响应数据格式
    • 手写框架
  • 使用wsgiref模块
    • 基于wsgiref模块搭建Web框架(最初版)
    • 基于wsgiref模块搭建Web框架(第二版)
    • 基于wsgiref模块搭建Web框架(最终版)
  • Python主流Web框架
      • 1.Django:重量级框架
      • 2.Flask:轻量级框架
      • 3.Tornado:异步非阻塞框架
      • 4.fastapi框架

前言:

我们之前学习了数据库、前端、Python基础等三大部分,但是他们三块的内容没有串在一起,也就没办法开发出一个完成的web项目出来,因此,我们通过Django框架把这三者融合在一起,以后我们就可以很方便的开发出各种各样的项目。

在了解Django之前,我们可以先了解web框架,了解它的好处是什么呢?在一步步搭建它的过程中,我们会逐步明白到Django是如何写的,以及如果处理页面接收与反馈给页面数据的。当然 这样讲可能有点抽象,那么我们先来了解一下吧!

Web应用简介

什么是Web框架?

Web框架是用来进行Web应用开发的一个软件架构,主要用于动态网络开发。开发者在基于Web框架实现自己的业务逻辑。Web框架实现了很多功能,为实现业务逻辑提供了一套通用方法。

框架的意思就是别人提前写好的框架(就是一堆目录和文件),我们只需要按照人家的要求在固定的位置写代码即可

什么是Web?

Web应用程序时一种可以通过Web访问的应用程序,用户只需要有浏览器即可,无需再安装其他软件

应用程序的两种模式

应用程序有两种模式C/S、B/S两种模式

C/S模式是客户端----->服务端程序,也就是说这类程序一般独立运行。
B/S模式是浏览器端----->服务端应用程序,这类应用程序一般借助IE等浏览器来运行。
而Web应用程序一般是B/S模式

Web应用程序的优缺点

优点:

  1. 只需要一个适用的浏览器即可,无需安装其他应用软件
  2. 节省用户的硬盘空间资源
  3. 它们无需更新,因为所有新的特性都在服务端上执行,从而自动传达到客户端
  4. 跨平台使用。例如:Windows、Mac、Linux等。

缺点:

  1. 严重依赖服务端的正常运行,一旦服务端出现问题、宕机,会直接影响客户端正常访问

手写Web框架

Web应用程序时B/S架构的,所以我们需要自己写一个服务端,这里的Web服务端是我们使用socket套接字来实现的,以浏览器作为客户端,朝我们搭建的服务端发送数据,已经我们的服务端给浏览器返回数据的过程。

因为这里是用浏览器做客户端,就涉及到了HTTP协议的相关知识

HTTP协议的相关知识

1.四大特性

  1. 基于请求和响应
  2. 基于TCP协议之上的应用层协议
  3. 无状态
  4. 短连接

2.请求数据格式

  1. 请求首行(请求方式、协议、版本号、路径)
  2. 请求头
  3. 换行(\r\n\r\n)
  4. 请求体(Get请求方式是没有请求体的,Post请求方式才有请求体)

3.响应数据格式

  1. 响应首行(响应状态码)
  2. 响应头
  3. 换行(\r\n\r\n)
  4. 响应体(一般情况下就是浏览器要展示给用户看的数据)

具体HTTP协议的相关知识可以去看我这篇博客里面的“HTTP超文本传输协议节点处即可”HTTP协议相关知识


手写框架

'''手写框架'''
import socket  # 导入socket套接字模块# 生成一个socket对象,并设置协议和类型(括号内不写默认是基于TCP协议)
server = socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
'我这里是补全的TCP协议的,也可以选择UDP'# 绑定ip和端口号给服务端
server.bind(('127.0.0.1', 8000))# 建立监听 半连接池
server.listen(5)while True:# 等待客户端的连接sock, addr = server.accept()# 接收客户端发送的请求数据data = sock.recv(1024)  # 单次最大字节数 接收的是bytes类型# print(data.decode('utf-8'))  # 解码接收的请求数据'''当我们在浏览器输入127.0.0.1:8000/index时通过打印请求数据我们看到了请求方式(Get 朝服务端索要数据   Post 朝服务端提交数据)GET /index HTTP/1.1Host: 127.0.0.1:8000这样我们可以通过切分字符串并以索引的方式获取到想要的数据'''# 从请求数据中看到可以直接按照空格切分字符串str_data = data.decode('utf-8').split(' ')[1]# print(str_data)# 回应客户端请求数据'''因为是浏览器客户端所以需要遵循HTTP协议的需求'''# TCP流式传输协议,短时间内可以分多次接收多个数据sock.send(b'HTTP/1.1 200 ok \r\n\r\n')'''然后我们需要根据网址后缀的不同请求不同的内容如:127.0.0.1:8000/index等所以我们得回到接收的请求数据位置处筛选出我们想要的数据''''''然后通过判断来进行根据后缀回应不同的数据'''if str_data == '/index':sock.send(b'from index')elif str_data == '/home':sock.send(b'from home')elif str_data == '/html':with open(r'../Myhtml.html', 'rb') as f:  # rb模式 二进制sock.send(f.read())else:sock.send(b'404 Error')

但是这种Web框架的代码缺陷有点多

  1. socket代码重复编写
  2. 针对请求数据格式的处理复杂且重复
  3. 针对不同网址后缀的匹配逻辑过于简单
  4. 没有解决高并发问题

那么该怎么优化以上存在的问题呢?

使用wsgiref模块

基于wsgiref模块搭建Web框架(最初版)

wsgiref模块是内置模块,很多Web框架底层使用的模块

来看看使用wsgiref模块怎么做吧

from wsgiref.simple_server import make_server  # 导入模块def run(request,respose):""":param request:  客户端的请求数据:param respose:  给客户端进行响应的数据:return:    返回给客户端的真实数据"""respose('200 ok', [])  # 返回响应状态给客户端print(request)  # 这个参数是wsgiref帮助我们封装的一个大字典,字典中携带的客户端的请求数据return [b'hello world!']  # 返回给客户单的真实数据if __name__ == '__main__':'''我们可以通过查看源码的方式看到make_server中需要的几个参数host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler'''server = make_server('127.0.0.1', 8000, app=run)  # 分别代表:ip地址、端口号、由那个程序来处理请求
'''
1.它会实时监听127.0.0.1:8000这个地址,只要由客户端来连接这个地址,它就可以做出响应
2.app=run:它的意思是,当由客户端请求过来的时候,会把该请求交给run函数来处理,但是这个地方不要加括号
3.django中这里写的是函数名,当请求来的时候,会调用这个函数,函数叫括号
4.如果是flask框架,当请求来的时候,也会把请求交给这个对象处理,只不过变成了对象()---实例化----调用__call__方法执行
(__call__方法里面写的就是flask框架的源码入口位置)
'''server.serve_forever()  # 将服务器持续开启

在这里插入图片描述
而用户请求的数据:打印出来的是一个字典的形式的
在这里插入图片描述

基于wsgiref模块搭建Web框架(第二版)

那么此时,我们可以在浏览器发送请求时,稍作变动

比如:让用户访问127.0.0.1:8000/index,那么页面要出现index后缀我们该怎么实现。

首先服务端要获取url后面的/index,才能进行处理。

	from wsgiref.simple_server import make_server  # 导入模块def run(request,respose):""":param request:  客户端的请求数据:param respose:  给客户端进行响应的数据:return:    返回给客户端的真实数据"""respose('200 ok', [])  # 返回响应状态给客户端print(request)  # 这个参数是wsgiref帮助我们封装的一个大字典,字典中携带的客户端的请求数据# 获取大字典中的ip和端口号后面的后缀current_path = request.get('PATH_INFO')'进行判断请求数据的后缀回应不同的数据'if current_path == '/index':return [b'from index']if current_path == '/home':with open(r'Myhtml.html','rb')as f:return f.read()else:return [b'404 Error']# return [b'hello world!']  # 返回给客户单的真实数据if __name__ == '__main__':server = make_server('127.0.0.1', 8000, app=run)  # 分别代表:ip地址、端口号、由那个程序来处理请求server.serve_forever()  # 将服务器持续开启

在这里插入图片描述

从这里就已经实现了当时使用基于TCP协议的socket套接字的服务端的功能并且优化掉了代码重复写、请求数据格式的处理的缺陷。但是还没有解决针对不同网址后缀的匹配逻辑过于简单问题。并且按照上面的思路是不是一个页面堆满了if语句,所以我们需要将用户访问、已经处理响应用户的步骤进行拆分。那么我们可以通过代码的封装优化。

基于wsgiref模块搭建Web框架(最终版)

代码的封装优化

	解决问题:1.网址后缀的匹配问题2.每个后缀匹配成功后执行的代码有多有少面条版	函数版	模块版3.将分支的代码封装成一个个函数4.将网址后缀与函数名做对应关系5.获取网址后缀循环匹配6.如果想新增功能只需要先写函数在 添加一个对应关系即可7.根据不同的功能拆分不同的py文件views.py	存储核心业务逻辑(功能函数)urls.py		存储网址后缀与函数名对应关系templates目录	存储html页面文件(模块文件)start.py/run.py		启动文件、入口文件8.为了使函数体代码中业务逻辑有更多的数据可用将request大字典转手传给这个函数(可用不用但是不能没有)

先展示封装代码在一个页面中

from wsgiref.simple_server import make_server  # 导入模块def index():return 'from index'def home():return 'from home''定义一个元组用来存储想要书写的后缀对应的页面'
urls = (('/index', index),('/home', home)
)def run(request,respose):""":param request:  客户端的请求数据:param respose:  给客户端进行响应的数据:return:    返回给客户端的真实数据"""respose('200 ok', [])  # 返回响应状态给客户端print(request)  # 这个参数是wsgiref帮助我们封装的一个大字典,字典中携带的客户端的请求数据# 获取大字典中的ip和端口号后面的后缀current_path = request.get('PATH_INFO')# '''进行判断请求数据的后缀回应不同的数据'''# if current_path == '/index':#     # return [b'from index']#     res = index()#     return [res.encode('utf-8')]# elif current_path == '/home':#     with open(r'Myhtml.html','rb')as f:#         return f.read()# else:#     return [b'404 Error']'''循环这个元组来判断是否存在后缀'''func = None  # 定义一个空变量来存放for url in urls:  # ('/index', index),if current_path == url[0]:func = url[1]  # 后缀对应的函数名break  # 一旦匹配到了内容就立刻结束for循环'''判断当后缀存在时执行'''if func:res = func()return [res.encode('utf-8')]else:return [b'404 Error']if __name__ == '__main__':server = make_server('127.0.0.1', 8000, app=run)  # 分别代表:ip地址、端口号、由那个程序来处理请求server.serve_forever()  # 将服务器持续开启

到此发现如果后续需要添加更多的功能,还是会有很多重复,所以我们需要根据py文件中的功能不同划分不同的py文件

文件拆分
我们需要先建立一个文件夹,存放三个文件以及一个文件夹(用于存放模版文件html)

urls:用于表示用户输入的url应哪一个函数

	'''根据用户输入的url,返回该url对应的处理函数'''from views import *urls = (('/index', index),('/home', home),('/demo', demo))

views:用于处理用户的请求与响应用户数据

	'''接收用户请求、在对应函数可以进行一番处理然后响应给用户数据。'''def index():return 'from index'def home():return 'from home'def demo():with open(r'templates/dj.html', 'r', encoding='utf-8') as f:return f.read()

我们的Web框架的入口程序

from wsgiref.simple_server import make_server
from urls import urlsdef run(request,response):""":param request:  客户端的请求数据:param respose:  给客户端进行响应的数据:return:    返回给客户端的真实数据"""response('200 ok',[])  # 返回响应状态给客户端# 获取大字典中的ip和端口号后面的后缀current_path = request.get('PATH_INFO')func = None  # 定义一个空变量,用于接受处理用户请求的函数返回的数据'''循环这个元组来判断是否存在后缀'''for url in urls:# 判断用户输入的页面后缀地址,是否在我们定义的处理列表中if current_path == url[0]:func = url[1]   # 后缀对应的函数名break  # 一旦匹配到了内容就立刻结束for循环'''判断当后缀存在时执行'''if func:res = func()return [res.encode('utf-8')]else:return [b'404 Error']  # 当上述判断不执行时,执行else条件,返回404 errorif __name__ == '__main__':server = make_server('127.0.0.1', 8000, run)server.serve_forever()  # 服务器持续开启

还有最后一个是templates文件夹存放模版文件,也就是html文件
在这里插入图片描述


Python主流Web框架

1.Django:重量级框架

Django是基于Python的免费和开放源代码Web框架它遵循模型-模版-视图(MTV)体系结构模式。它封装的功能非常丰富并且非常多,所以它是重量级框架,Django的文档最完善、是市面最主流框架、市场占有率最高。但如果需要实现的功能很少的项目就会显得略微笨重。

2.Flask:轻量级框架

Flask是Python编写的一种轻量级(微)的Web开发框架,只提供Web框架的核心功能,较其他类型的框架更为的自由、灵活,更加适合高度定制化的Web项目。Flask在功能上面没有欠缺,Flask的第三方开源组件比较丰富,因此Flask对开发人员的水平有了一定的要求。使用Flask开发较为依赖于第三方组件

3.Tornado:异步非阻塞框架

Tornado是一种Web服务器软件的开源版本。Tornado和主流Web服务器框架(包括大多数Python的框架)有着明显的区别:它是非阻塞式的服务器,而且速度相当快。得利于其非阻塞的方式和对epoll的运用,Tornado每秒可以处理数以千计的连接,因此Tornado是实时Web服务的一个理想框架。但很多功能都需要开发者自己去编写,因此学习这个框架成本有点高。

4.fastapi框架

它主要用来写一些接口,制作不出来页面,它只负责写业务逻辑

相关文章:

Django框架的推导

文章目录 Web应用简介什么是Web框架?什么是Web?应用程序的两种模式Web应用程序的优缺点 手写Web框架HTTP协议的相关知识1.四大特性2.请求数据格式3.响应数据格式 手写框架 使用wsgiref模块基于wsgiref模块搭建Web框架(最初版)基于wsgiref模块搭建Web框架…...

广东开放大学:电大搜题助力学子迎考利器

近年来,广东开放大学一直致力于为广大学子提供优质的教育资源和学习服务。作为一所专注于远程教育的学府,广东开放大学不仅拥有雄厚的师资力量和丰富的教育经验,还致力于创新教学手段,为学生提供更便捷、高效的学习体验。在这个信…...

linux 7za 编译安装

本文主要介绍了在linux下安装7z命令的方法,同时介绍了7z命令的使用。7z压缩格式拥有众多优点,具有极高的压缩比率 wget https://zenlayer.dl.sourceforge.net/project/p7zip/p7zip/16.02/p7zip_16.02_src_all.tar.bz2 tar -xjvf p7zip_16.02_src_all.ta…...

【Edge】微软Edge每次启动自动导入Chrome收藏夹,无法取消“每次启动浏览器时导入浏览数据”功能的解决方法(202311)

写在前面 Edge现在也不管用户体验了吗? 这个BUG都快一个月了,还没见修复,从118.0.2088开始,我是在2023年10月份一次更新后发现的这个BUG,结果社区论坛什么信息都没有,英文也没收到。 Edge的BUG现象 不知道哪次Edge…...

报错RuntimeError: no valid convolution algorithms available in CuDNN

报错信息如下RuntimeError: no valid convolution algorithms available in CuDNN 出现这个问题既不是cuda与cudnn版本不匹配,也不是英伟达显卡驱动需要更新!而是因为你的显存过低不能训练,解决办法是使用混精度训练!&#xff01…...

JSP通用材料收集归档系统eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 通用材料收集归档系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发,数据库为Mysql5.0&#xff0c…...

网络安全-零基础小白自学要点

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类,我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一、是市场需求量高; 二、则是发展相对成熟…...

SpringCloud——服务注册——Eureka

1.Eureka概述 2.Eureka架构: Eureka中80服务要实现对8001和8002服务访问的负载均衡,需要在80服务的RestTemplate上面加LoadBalanced注解,默认采用的是轮询的策略。 3.Eureka自我保护 当一个EurekaClient注册进EurekaServer,Eurek…...

大模型时代的编码习惯

遇到问题,第一个问的再也不是百度,而是Chat-GPT,百度现在适合找佐证的资料,而非找答案,百度不到反而是在浪费时间,代码有问题找Chat-GPT和各类大模型...

程序员怎样才能学好算法?这本书送几本给大家!

目录 笔者对算法的理解 写书的初衷及过程 本书的内容 购买方式 数据结构和算法是计算机科学的基石,是计算机的灵魂,要想成为计算机专业人员,学习和掌握算法是十分必要的。不懂数据结构和算法的人不可能写出效率更高的代码。计算机科学的很…...

2023-11-08 monetdb-事务-只有RR隔离级别-原因分析

摘要: monetdb的事务隔离级别只有RR, 和mysql/innodb的具有RR和RC两个隔离级别不同. 本文分析monetdb的RR隔离级别的实现方式, 以及分析这种隔离级别方式如何导致只有RR隔离级别. 测试流程: 测试方式: 分别开两个mclient终端, 连接同一个mserver实例两个client终端分别叫做客…...

微信小程序:怎么在一个js中修改另一个js的数据(这里通过缓存进行实现)

实例:现有两个页面index.js和category.js,我现在想在index.js中修改category.js的数据 初始数据 category [{name: 物流配送,list: [{id: 1,job: 外卖骑手,checked: true}, {id: 2,job: 快递员,checked: false}, {id: 3,job: 司机,checked: false}, {id: 4,job: …...

01-基于IDEA,Spring官网,阿里云官网,手动四种方式创建SpringBoot工程

快速上手SpringBoot SpringBoot技术由Pivotal团队研发制作,功能的话简单概括就是加速Spring程序初始搭建过程和Spring程序的开发过程的开发 最基本的Spring程序至少有一个配置文件或配置类用来描述Spring的配置信息现在企业级开发使用Spring大部分情况下是做web开…...

map相关题目

KY264 单词识别 题目描述: 输入一个英文句子,把句子中的单词(不区分大小写)按出现次数按从多到少把单词和次数在屏幕上输出来,次数一样的按照单词小写的字典序排序输出,要求能识别英文单词和句号。 输入描述: 输入…...

JAVA 版小程序商城免费搭建 多商家入驻 直播带货 商城系统 B2B2C 商城源码之 B2B2C产品概述

1. 涉及平台 平台管理、商家端(PC端、手机端)、买家平台(H5/公众号、小程序、APP端(IOS/Android)、微服务平台(业务服务) 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…...

moc_ XX.cpp 中的函数没有定义

解决办法: 直接将 moc_OnlyTest.cpp 文件,添加到工程目录下,解决。...

11.8代码

利用gpiod子系统实现开发板六盏灯&#xff0c;安装驱动点亮&#xff0c;卸载驱动熄灭 #include <linux/init.h> #include <linux/module.h> #include <linux/of.h> #include <linux/gpio/consumer.h> /*myleds{core-leds{leds <&gpioz 5 0>…...

常用的表单校验规则——邮箱/QQ/身份证号码/微信/电话/数字字母/整数/文本/密码等

1.邮箱校验规则 //邮箱校验 export const validateEmail async (RuleObject, value) > {// const reg new RegExp(/^[A-Za-z0-9\u4e00-\u9fa5][a-zA-Z0-9_-]$/)const reg new RegExp(/^[a-zA-Z0-9_-]([a-zA-Z0-9]\.)(com|cn|net|org)$/)if (value) {if (!reg.test(value…...

Mysql数据库 11.SQL语言 储存过程 下 储存过程管理和游标

一、存储过程管理 1.查询存储过程 查询所有储存过程 语法 show procedure status; 代码实现 #查询存储过程 show procedure status; 运行结果 加入条件查询储存过程 语法 show procedure status where db储存过程名; 代码实现 #查询带有条件的储存过程 查询名字为pro…...

如何在Visual Studio上创建项目并运行【超级详细】

工欲善其事&#xff0c;必先利其器。想要学好编程&#xff0c;首先要把手中的工具利用好&#xff0c;今天小编教一下大家如何在史上最强大的编译器--Visual Studio上创建项目。&#x1f357; 一.打开编译器&#x1f357; 双击你电脑上的vs&#xff0c;(2012,2019,2022)都行。&…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...