Python Web 面试题
1 Web 相关
get 和 post 区别
-
get
:-
请求数据在
URL
末尾,URL
长度有限制 -
请求幂等,即无论请求多少次,服务器响应始终相同,这是因为
get
至少获取资源,而不修改资源 -
可以被浏览器缓存,以便以后的请求中更快地获取相同资源
-
可以在浏览器中输入或作为超链接点击
-
-
post
-
参数在请求体中,可以传递更多数据
-
不幂等,因为通常需要修改或创建资源
-
无法被浏览器缓存,因为可能会修改服务器资源
-
请求必须通过表单或
js
发送
-
cookies 和 session 的区别,cookie 的安全性
都是用于 web
开发中用于跟踪用户状态的技术,区别如下:
-
存储位置:
Cookie
存储在客户端浏览器小文件中,Session
是存储在服务器端的内存或数据库中 -
存储内容:
Cookie
中存储的是客户端的一些状态信息,例如用户的登录状态、语言偏好等;而Session
中存储的是服务器端保存的用户状态信息,例如用户 ID、购物车内容等。 -
安全性:
Cookie
因为存储在浏览器,容易被攻击,Session
存储在服务器端,安全性更高 -
有效期:
Cookie
可以设置一个过期时间,当超过这个时间后,Cookie
将自动失效,而Session
可以根据需要设置过期时间或者在用户关闭浏览器时自动过期
综上所述,Cookie 和 Session 都是用于跟踪用户状态的技术,但存储位置、存储内容、安全性和有效期等方面有所不同。在实际开发中,应该根据具体需求选择合适的技术。例如,对于需要跨多个页面和多个设备保存用户状态的应用程序,应该使用 Cookie;而对于需要保存更多用户状态信息和更高安全性要求的应用程序,应该使用 Session。
jwt token 和 session 的区别
JWT (JSON Web Token) 和 Session 都是用于认证和授权的技术,它们之间的区别如下:
-
数据存储:Session 是在服务器端存储用户状态信息的一种方式,通常使用内存或数据库来存储 Session 数据;而 JWT 是一种无状态的认证方式,Token 数据是通过编码后存储在客户端的 Cookie 或 LocalStorage 中,服务器不会存储 Token 数据。
-
跨域支持:由于 Session 是基于 Cookie 实现的,因此在跨域请求时需要特殊处理;而 JWT 则可以在不同域名之间共享,因为 Token 数据是存储在客户端的。
-
扩展性:JWT 可以扩展为不同的认证方式,例如基于 OAuth 的认证方式;而 Session 的扩展性相对较弱,需要在服务器端进行实现。
-
安全性:使用 Session 进行认证时,需要确保 Session ID 的安全,否则可能会被攻击者盗取;而使用 JWT 进行认证时,可以使用加密算法对 Token 数据进行加密,提高安全性。
-
无状态性:由于 JWT 是无状态的,因此可以避免服务器端的负载问题,特别适合于分布式系统和微服务架构。
总的来说,JWT 适合于分布式系统和无状态应用,而 Session 适合于传统的 Web 应用。使用哪种方式,取决于具体的需求和应用场景。
docker 镜像和容器的区别
Docker是一种用于构建和管理应用程序的开源平台。在Docker中,镜像和容器是两个重要的概念。
-
Docker镜像是应用程序的打包和分发方式。它包含了应用程序所需的所有文件、配置和依赖项,可以看作是一个轻量级的虚拟机模板。Docker镜像是只读的,一旦创建就不能更改。镜像通常是由Dockerfile文件定义的,Dockerfile文件是一种文本文件,用于指定构建Docker镜像所需的所有步骤。
-
Docker容器是Docker镜像的运行实例。容器是可运行的、独立的应用程序单元,可以在任何支持Docker的环境中运行。Docker容器是基于Docker镜像创建的,并且可以动态修改和更新容器中的应用程序和配置。容器可以启动、停止、暂停、恢复和删除。
可以将Docker镜像看作是应用程序的打包和分发方式,而Docker容器是应用程序的运行实例。在使用Docker时,通常首先构建一个Docker镜像,然后在Docker镜像的基础上创建多个Docker容器。这种分离的方式使得开发、测试、部署和运维过程更加高效、可靠和可重复。
输入一个网址,在浏览器的完整过程,越详细越好
-
解析URL(Uniform Resource Locator,统一资源定位符)。 URL是指定网络资源的地址。URL由多个部分组成,例如协议(例如http或https)、主机名(例如www.example.com)、端口号、路径和查询字符串。浏览器会解析URL以确定要访问的主机名和路径。
-
建立TCP连接。浏览器会使用HTTP(HyperText Transfer Protocol,超文本传输协议)或HTTPS(HTTP Secure,HTTPS是一种加密的HTTP)协议与Web服务器建立TCP连接。如果使用的是HTTPS,则还需要进行SSL/TLS握手以建立安全连接。
-
发送HTTP请求。一旦TCP连接建立,浏览器会向Web服务器发送HTTP请求。请求中包括HTTP方法(例如GET或POST)、资源路径、HTTP版本、请求标头和消息正文(对于某些请求,例如POST请求)。
-
接收HTTP响应。Web服务器将处理HTTP请求并生成HTTP响应。响应包括HTTP状态码、响应标头和响应正文。常见的HTTP状态码包括200 OK(请求成功)、404 Not Found(资源未找到)和500 Internal Server Error(服务器内部错误)。
-
处理响应。一旦浏览器接收到HTTP响应,它会解析响应并执行以下操作:
-
如果响应状态码为200,则解析响应正文并显示网页内容。
-
如果响应状态码为3xx,则浏览器将遵循响应中指定的重定向URL以获取重定向后的资源。
-
如果响应状态码为4xx或5xx,则浏览器将显示适当的错误页面。
-
-
渲染页面。浏览器会将HTML、CSS和JavaScript代码解析为可视化页面,并在屏幕上呈现出来。页面可能包括文本、图像、视频和其他媒体元素。
-
关闭TCP连接。一旦页面渲染完毕,浏览器会关闭TCP连接。
什么是 MVC?
模型、视图、控制器:解耦数据
-
M(Model)模型:负责业务对象和数据库的交互(ORM)
-
V(View)视图:负责与用户的交互展示
-
C(Control)控制器:接收请求参数调用模型和视图完成请求
ORM
ORM(Object Relational Mapping),对象关系映射,用于实现业务对象与数据表中的字段映射。比较出名的软件有:Sqlalchemy、Django ORM、Peewee
Web 框架对比 Django、flask、Fastapi、tornado
-
Django:高度集成的 Web 框架,适合开发复杂的 Web 应用程序,提供了大量的自带模块和插件,如:ORM、模板引擎、表单处理、认证等,非常适合快速搭建全功能的 Web 应用程序。但是自由度控制较少,有一定的学习曲线。
-
Flask:是一个轻量级的 Web 框架,比 Django 更为灵活,适合快速搭建小型的 Web 应用程序。提供了基本功能,如:路由、请求响应、模板引擎等,可通过插件来拓展功能。具有更高的自由度,但需要更多的手动配置和开发
-
FastAPI:FastAPI 是一个新兴的 Web 框架,以性能高和易用性强著称。FastAPI 基于 Python 3.7+ 的类型注解和异步编程模型,具有自动生成 API 文档、自动验证输入和输出数据等优秀特性。FastAPI 在处理高并发请求和异步 IO 方面表现出色,是构建高性能 Web 应用的不二之选。
-
Tornado:Tornado 是一个异步 Web 框架,特别适合处理大量的并发请求和实时流数据。Tornado 提供了基于协程的异步编程模型,其核心特性是非阻塞 IO 和事件驱动,比较适合构建长连接的 Web 应用程序,如聊天应用、实时推送等。
综上所述,选择哪个 Web 框架应该根据具体的应用场景和需求而定。如果需要开发高度集成、复杂的 Web 应用程序,可以选择 Django;如果需要开发轻量级、灵活的 Web 应用程序,可以选择 Flask;如果需要开发高性能的 Web 应用程序,可以选择 FastAPI 或 Tornado。
什么是 wsgi
WSGI(Web Server Gateway Interface)是 Python Web 应用程序和 Web 服务器之间的标准接口,它定义了 Web 服务器如何与 Python 应用程序进行通信。WSGI 规范主要包括两部分:服务器和应用程序之间的环境和通信协议。WSGI 的主要作用是为 Python Web 应用程序和 Web 服务器提供了一个标准的接口,让开发者可以使用不同的 Web 服务器来部署和运行他们的应用程序,同时也提高了 Web 应用程序的可移植性。
2 Django 框架
Django 中间件的使用场景是什么
是在请求和响应过程中位于视图函数前后的一系列可重用的组件,可用于拦截请求和响应,进行一些处理或修改,并将请求传递给下一个中间件或视图函数,应用场景:
-
认证和授权:验证是否登录或是否有权限访问特定页面
-
日志记录:记录请求和响应详细信息,包括请求时间、响应时间,请求方法、路径、响应状态码等,以便于调试和监控
-
缓存:提高网站性能和响应速度
-
异常处理:捕获视图函数中的异常,如发送邮件通知管理员等
Django 请求生命周期?
-
wsgi
: 获取解析HTTP
请求,并转发给Web
框架 -
中间件:对请求进行校验或在请求对象中添加其他相关数据,如:
csrf、request、session
-
路由匹配:根据请求
URL
去匹配不同的视图函数 -
视图函数:在视图函数中进行业务逻辑的出来,涉及到:
orm、templates => 渲染
-
中间件:对响应的数据进行处理
-
wsgi
:将响应的内容发送给浏览器
Django 内置组件?
-
Admin
:对model
中对应的数据表进行增删改查提供的组件 -
model
:负责操作数据库 -
form
组件:生成HTML
片段,对数据有效性进行校验 -
ModelForm
:用于数据库操作,也可以用于用户请求的验证
列举 Django
中间件的 5 个方法,及应用场景?
-
process_request
:请求进来时,权限验证 -
process_view
:路由匹配之后,能够得到视图函数 -
process_exception
:异常时执行 -
process_template_response
:模板渲染时执行 -
process_response
:请求有响应时执行
以上方法的返回值可以是 None
,或者是一个HttpResponse
对象,如果是 None
,则继续按照django定义的规则向后继续执行,如果是 HttpResponse
对象,则直接将改对象返回给用户。
Django 的 request
对象是在什么时候创建的?
class WSGIHandler(base.BaseHandler):request = self.request_class(environ)
请求到 WSGIHandler
类的时候,执行 __cell__
方法,将 environ
封装成 request
。
如何给 CBV
添加装饰器?
# 引入 method_decorator 模块 # 1. 直接给类加装饰器,所以请求方法(get、post 等) @method_decorator(test, name='dispatch') class LoginView(View):pass # 2. 单独给请求的函数添加装饰器 @method_decorator def post(self, request, *args, **kwargs):pass
Django 如何实现 csrf
?
只对 post
请求进行 csrf
防御,第一次请求时,会在服务端随机产生一个 token
,把这个 token
放到 cookie
中,然后每次 post
请求都会携带这个 token
,这样就能避免 csrf
攻击了。
Django 中如何实现单元测试?
使用 untest
模块,coverage
生成测试覆盖度报告。
简述 MVC
和 MTV
?
-
MVC
(Model View Controller)
:模型-视图-控制器,是一种Web
架构模式。特点:把业务逻辑、模型数据、用户界面分离开来,让开发者将数据与表现解耦-
Model
:模型,数据库层面 -
View
:视图,系统中选择显示什么和如何显示的部分 -
Controller
:系统中根据用户输入并视需要访问模型,以决定使用哪个视图的那部分
-
-
MTV
(Model Templates View
):模型-模板-视图-
Model
:数据存取层,处理与数据所以事务,操作数据模型,如何读取数据等 -
Templates
:表现层,将模型中的数据通过页面的形式展示给用户 -
View
:业务逻辑层,包含存取模型以及调取恰当模板的相关逻辑,如:从模板中获取用户输入,写入模型中;从模型中读取数据放到模板中显示灯。
-
简述什么是FBV和CBV?
FBV和CBV本质是一样的,基于函数的视图叫做FBV
,基于类的视图叫做CBV
,使用 CBV 的优点:
-
提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
-
可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
Django本身提供了runserver,为什么不能用来部署?(runserver与uWSGI的区别)
-
runserver方法是调试 Django 时经常用到的运行方式,它使用Django自带的 WSGI Server 运行,主要在测试和开发中使用,并且 runserver 开启的方式也是单进程 。
-
uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http 等协议。注意uwsgi是一种通信协议,而uWSGI是实现uwsgi协议和WSGI协议的 Web 服务器。uWSGI具有超快的性能、低内存占用和多app管理等优点,并且搭配着Nginx就是一个生产环境了,能够将用户访问请求与应用 app 隔离开,实现真正的部署 。相比来讲,支持的并发量更高,方便管理多进程,发挥多核的优势,提升性能。
Django如何实现websocket?
Django-channels 模块
Django 是 MVC 还是 MTV 模式
Django采用了类似于MVC的设计模式,但是由于模板层的引入,所以Django更常用的被称作MTV,即Model-Template-View。其中:
-
Model:负责业务对象和数据库的关系映射(ORM)。
-
Template:负责如何把页面展示给用户(html)。
-
View:负责业务逻辑,并在适当时候调用Model和Template。
3. Flask 框架
Flask 上下文
在 Flask 中,有两种上下文:应用上下文和请求上下文。应用上下文包含了应用的全局状态,而请求上下文则包含了关于当前请求的信息。
1、应用上下文:
在 Flask 中,应用上下文对象用于存储应用的全局状态,例如配置、插件、请求钩子等。应用上下文在应用启动时创建,并在应用关闭时销毁。在同一个线程中,应用上下文是共享的,可以使用 current_app
全局变量来访问应用上下文对象。
2、请求上下文:
在 Flask 中,请求上下文对象用于存储关于当前请求的信息,例如请求头、请求方法、URL 等。请求上下文对象在每个请求开始时创建,并在请求结束时销毁。在同一个线程中,请求上下文是独立的,可以使用 request
全局变量来访问请求上下文对象。
应用上下文和请求上下文可以使用 Flask 的 app_context()
和request_context()
函数进行手动创建,也可以使用 Flask 提供的 app 和 request 全局变量来隐式访问上下文对象。在使用 Flask 的扩展时,通常会隐式地使用上下文对象,因此开发者不需要手动创建。
下面是一个使用 Flask 上下文的简单示例:
from flask import Flask, request, current_app app = Flask(__name__) @app.route('/') def hello_world():# 访问应用上下文对象print(current_app.name) # 访问请求上下文对象print(request.method)print(request.url)print(request.headers) return 'Hello, World!'
Flask 中请求钩子的理解和应用?
Flask 中的请求钩子是一种机制,用于在请求的不同阶段执行特定的操作。在 Flask 中,请求钩子主要有两种类型:before_request 和 after_request。
before_request 钩子会在每个请求处理之前被调用,可以用来执行一些全局操作,比如验证用户的登录状态、设置一些全局变量等。
-
在 before_request 钩子中,可以通过返回 None 或一个 Response 对象来控制请求的继续处理或提前结束。如果返回 None,则请求会继续向下执行,而如果返回一个 Response 对象,则会提前结束请求处理,并返回该 Response 对象。
-
after_request 钩子会在每个请求处理结束之后被调用,可以用来执行一些请求结束后的全局操作,比如关闭数据库连接、设置一些响应头等。在 after_request 钩子中,可以修改响应对象并返回它,也可以返回原始的响应对象或一个新的 Response 对象。
下面是一个简单的例子,展示了如何使用 before_request
钩子来验证用户的登录状态:
from flask import Flask, request, abort app = Flask(__name__) @app.before_request def check_login():if request.path != '/login' and not request.args.get('token'):abort(401, 'Unauthorized') @app.route('/login') def login():token = generate_token() # 生成登录 tokenreturn {'token': token} @app.route('/data') def get_data():# 获取数据return {'data': data} if __name__ == '__main__':app.run()
上面的每个请求都会先经过 check_login()
函数验证是否登录,你也可以给不用验证的请求加白名单。
对 Flask 蓝图(Blueprint)的理解?
Flask 蓝图(Blueprint)是一种组织 Flask 应用的方式,它可以将应用拆分为一系列小的应用组件,从而使应用更加模块化和易于管理。蓝图可以包含一组相关的路由、模板、静态文件、错误处理等应用组件,并可以被注册到 Flask 应用中。在一个 Flask 应用中可以同时注册多个蓝图,它们之间相互独立,可以共同组成一个完整的应用。
Flask 蓝图的主要作用有以下几点:
-
模块化应用:通过将应用拆分为多个蓝图,可以将不同功能的代码分开组织,从而提高应用的可读性和可维护性。
-
组合多个应用:多个蓝图可以在一个 Flask 应用中并存,从而形成一个完整的应用,这样可以更灵活地组合多个应用。
-
分离功能:蓝图可以让你将不同功能的代码分离开来,这样可以更好地重用代码、测试代码和独立部署不同功能的应用。
-
分离权限:蓝图可以用来隔离不同权限的用户,从而更好地控制用户访问不同的功能。
使用 Flask 蓝图的基本步骤如下:
-
创建一个蓝图对象:使用 Flask 的 Blueprint 类创建一个蓝图对象,可以指定蓝图的名称、导入名称、静态文件夹、模板文件夹等属性。
-
注册路由和视图函数:在蓝图对象上使用装饰器注册路由和视图函数,与 Flask 应用中的路由和视图函数注册方式相同。
-
注册蓝图:在 Flask 应用对象上使用 register_blueprint() 方法注册蓝图对象,可以指定蓝图对象的 URL 前缀、子域名等属性。
下面是一个简单的 Flask 蓝图的例子:
from flask import Blueprint bp = Blueprint('auth', __name__, url_prefix='/auth') @bp.route('/login') def login():return 'Login page' @bp.route('/logout') def logout():return 'Logout page'
Flask 常用第三方组件
-
Flask-WTF:表单处理组件,提供了 CSRF 保护、表单验证等功能;
-
Flask-Login:用户认证组件,提供了登录、注销等功能;
-
Flask-Mail:邮件发送组件,可以方便地集成到应用中发送邮件;
-
Flask-RESTful:RESTful API 开发组件,提供了路由、参数解析、错误处理等功能;
-
Flask-SQLAlchemy:数据库 ORM 组件,支持多种关系型数据库,提供了简单易用的查询接口;
-
Flask-Caching:缓存组件,支持多种缓存类型,提供了简单的接口;
-
Flask-Admin:后台管理组件,提供了 CRUD 操作、搜索、过滤等功能;
-
Flask-Uploads:文件上传组件,支持多种存储方式,提供了上传验证、文件处理等功能;
-
Flask-Migrate:数据库迁移组件,可以方便地管理数据库结构的变更。
Web 安全
sql 注入
通过特殊的输入参数传入 web 应用,导致后端执行了恶意的 sql 语句
-
通常由于程序员未对输入进行过滤,直接动态拼接 sql 产生
-
可以使用开源工具
sqlmap
、sqlninja
检测
如何防范?
-
永远不要相信用户的输入
-
对输入参数做好检查(类型和范围),过滤和转义字符
-
不要拼接 sql,使用占位符或者 ORM 可以大大降低 sql 注入的风险
-
数据层:做好权限管理配置,不要明文存储存储信息
# sql 语句拼接(不推荐) sql = "select * from users where name='"+ name +"' + "and password=md5('"+password+"')"" # SQL 语句注入,'---' 将后面的 SQL语句注释掉,从而到达不需要输入密码就能取出数据的目的 rose '--' # 使用占位符 sql = "select * from users where name=%s and password=md5(%s)"
xss 跨站脚本攻击
恶意用户将代码植入到提供给其他用户使用的页面中,未经转义的恶意代码输出到其他用户浏览器被执行
-
用户浏览的页面被恶意植入 JS 语句,其他用户访问同一个页面时,JS文件被执行,从而到达攻击用户的目的。
-
主要分为两类:反射型(非持久型:放 url 中,发给用户,诱惑用户点击),存储型(持久型)
-
危害:盗取用户 cookie,获取敏感信息
如何防范?
过滤用户输入的特殊字符,如:<script>、<、>
等
bs4 = BeautifulSoup(article_content, 'html.parser') # 过滤 script、link 标签 for tag in bs4.find_all():if tag.name in ['script', 'link']:tag.decompose() # 删除
csrf 跨站请求伪造
CSRF(Cross-Site Request Forgery),也称为“跨站请求伪造”,是一种常见的网络攻击方式,攻击者利用用户在已登录的网站上的身份信息,发送一个伪造的请求,以达到攻击者的目的。
攻击者通常使用各种方式来诱导用户访问一个特定的网站或点击一个特定的链接,当用户在登录状态下访问该站点或点击该链接时,攻击者就可以利用用户的身份信息发送一个伪造的请求。这样,攻击者就可以在用户不知情的情况下执行一些非法操作,如修改用户信息、转账等。
为了避免 CSRF 攻击,可以采取以下措施:
-
验证来源站点:在服务端对请求的来源站点进行验证,只允许来自合法站点的请求。可以在请求中添加一个 token 来进行验证,防止伪造的请求被执行。
-
限制敏感操作:对于一些敏感操作,如修改用户信息、删除数据等,需要进行二次确认,或者设置必须使用 POST 方法才能执行的操作。
-
合理设置 Cookie:在 Cookie 中设置 HttpOnly 属性,防止 Cookie 被 JavaScript 获取。
-
使用验证码:在关键操作前添加验证码校验,确保操作是由人类进行的。
-
及时更新:定期更新软件和框架,并及时修复已知漏洞。
网络编程
TCP 和 UDP 区别
-
TCP是一种面向连接的协议,它在数据传输之前需要进行三次握手建立连接,建立连接后才能进行数据传输,而且在传输数据时需要保证数据的可靠性,即要保证数据的顺序和完整性,所以TCP具有高可靠性和安全性的特点,但是传输效率相对较低,适用于需要保证数据可靠性的场景,如文件传输、邮件传输等。
-
UDP是一种无连接的协议,它不需要进行连接的建立和断开,数据包可以直接发送到目的地址,但是由于不保证数据的可靠性和顺序,所以在传输数据时有可能丢失数据、数据包到达的顺序与发送时的不同等情况,但是传输效率相对较高,适用于需要高效传输数据的场景,如实时音视频传输、游戏等。
因此,TCP适用于需要保证数据可靠性的场景,UDP适用于需要高效传输数据的场景。
HTTP 常见状态码
-
1xx:服务器收到请求,需要请求者继续执行操作
-
2xx:操作被成功接收并处理
-
3xx:重定向,需要进一步操作完成请求
-
4xx(客户端错误):请求有语法错误或无法完成请求
-
5xx(服务端错误):服务器处理请求过程中发生错误
- 200:请求成功 - 301:资源被永久转义到其他 URL - 403:Forbidden - 404:请求资源不存在 - 500:内部服务器错误 - 504:充当网关或代理的服务器,未及时从远程服务器获取请求 - 400 Bad Request: /客户端请求有语法错误,不能被服务器所理解 - 503 Server Unavailable: 服务器当前不能处理客户端的请求,一段时间后可能恢复正常 - 401 Unauthorized: 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
http 和 https 区别
HTTP(HyperText Transfer Protocol)和HTTPS(HyperText Transfer Protocol Secure)都是应用层协议,用于在网络中传输数据。HTTP协议是不安全的,而HTTPS协议通过加密和身份验证来提供更高的安全性。
下面是HTTP和HTTPS之间的区别:
1.安全性:HTTP不提供数据加密,而HTTPS使用 SSL/TLS 协议对传输的数据进行加密,从而更加安全。
2.端口:HTTP使用端口80,而HTTPS使用端口443。
3.证书:HTTPS需要使用数字证书来验证网站的身份,确保网站是可信的,而HTTP不需要证书。
4.速度:由于加密和解密数据需要额外的计算资源,HTTPS比HTTP要慢一些。
5.使用场景:HTTPS适用于敏感数据的传输,如个人身份信息、支付信息等,而HTTP适用于不需要保密性的数据传输。
总的来说,HTTP适用于一些不需要保密性的场景,而HTTPS则更适用于需要保密性和数据安全的场景。
Unix 网络模型
-
阻塞 I/O:最基本的网络模型,在 I/O 时,进程会一直等待,直到 I/O 操作完成。等待过程中,进程无法进行其他操作,因此不能同时处理多个连接。适用于连接数较少的应用场景。
-
非阻塞 I/O:进程不会等待,而是立即返回。若操作未完成,进程会再次轮询。可以处理多个请求,但需要轮询技术,会导致 CPU 占用率较高。
-
I/O 多路复用:允许进程同时监听多个连接的 I/O 操作,它通过 select、poll 或 epoll 等系统调用实现。可以有效处理大量连接,而且 CPU 占用率比非阻塞 I/O 模型低。
-
信号驱动 I/O:通过信号函数来实现异步 I/O 操作,在进行 I/O 操作时,进程会发起一个系统调用,并注册一个信号处理函数,在 I/O 操作完成后,系统会向进程发送一个信号,进程就可以在信号处理函数中进行后续处理。优点是可以处理多个连接,而且 CPU 占用率也较低,但需要编写复杂的信号处理函数。
-
异步 I/O:最先进的网络模型,它通过 aio_read、aio_write 等异步 I/O 函数来实现。在进行 I/O 操作时,进程会发起一个异步 I/O 请求,并继续执行后续操作,当 I/O 操作完成时,系统会向进程发送一个信号或回调函数,进程可以在回调函数中进行后续处理。这种模型可以同时处理多个连接,而且 CPU 的占用率也很低,但需要操作系统支持异步 I/O 函数。
请介绍一下 三次握手和四次挥手
三次握手
-
客户端发送一个 SYN 数据包到服务器端口,进入 SYN_SEND 状态,等待服务器确认。
-
服务器收到 SYN 数据包,必须确认客户端的 SYN,同时也发送一个 SYN 数据包到客户端,进入 SYN_RECV 状态。
-
客户端收到服务器的 SYN 数据包,必须向服务器发送确认,此包发送完毕,客户端和服务器进入 ESTABLISHED 状态,完成三次握手。
四次挥手
-
客户端发送一个 FIN 数据包,表示客户端已经没有数据要发送了,进入 FIN_WAIT_1 状态。
-
服务器收到 FIN 数据包,返回一个 ACK 数据包,表示收到了客户端的关闭请求,进入 CLOSE_WAIT 状态,等待服务器端的数据发送完成。
-
服务器端数据发送完成,发送一个 FIN 数据包,请求关闭连接,进入 LAST_ACK 状态。
-
客户端收到服务器的 FIN 数据包,发送一个 ACK 数据包,表示已经收到服务器的关闭请求,进入 TIME_WAIT 状态。服务器收到 ACK 数据包后,进入 CLOSED 状态,连接关闭。
通过三次握手,保证了客户端和服务器都能够正常通信;四次挥手,则是保证了客户端和服务器都能够正确关闭连接,避免了数据丢失和重复发送等问题。
select、poll 和 epoll 的区别
select、poll、epoll 都是 I/O 多路复用的机制,用于实现同时监听多个文件描述符的可读/可写/异常事件,从而避免阻塞等待。
它们的主要区别如下:
-
select 和 poll 对文件描述符的管理采用的是线性扫描方式,每次调用都需要将全部的文件描述符从应用进程中复制到内核中,效率较低。而 epoll 采用基于事件驱动的方式,只有当描述符状态发生变化时,才会调用回调函数。
-
select 和 poll 的缺点在于,每次调用都需要重复地将描述符集合从用户态复制到内核态,而 epoll 利用了内核与用户空间共享内存的方式避免了这种复制开销。因此,当需要监听的文件描述符数量较大时,epoll 的效率会更高。
-
在 epoll 中,可以使用 ET(Edge Trigger)和 LT(Level Trigger)两种触发方式。LT 模式下,当一个文件描述符上有事件发生时,epoll_wait() 就会立即返回,应用程序可以进行相应的操作。ET 模式下,只有当文件描述符从无可读/写/异常状态转变为可读/写/异常状态时,才会通知应用程序。因此,在 ET 模式下需要注意一些细节问题,例如非阻塞 IO 和边缘触发模式的配合使用,避免遗漏事件等。
总之,epoll 是相比于 select 和 poll 更加高效的一种 I/O 多路复用机制,尤其在需要同时监听大量文件描述符的情况下表现更优秀。
相关文章:
Python Web 面试题
1 Web 相关 get 和 post 区别 get: 请求数据在 URL 末尾,URL 长度有限制 请求幂等,即无论请求多少次,服务器响应始终相同,这是因为 get 至少获取资源,而不修改资源 可以被浏览器缓存,以便以后…...

java日志框架之JUL(Logging)
文章目录 一、JUL简介1、JUL组件介绍 二、Logger快速入门三、Logger日志级别1、日志级别2、默认级别info3、原理分析4、自定义日志级别5、日志持久化(保存到磁盘) 三、Logger父子关系四、Logger配置文件 一、JUL简介 JUL全程Java Util Loggingÿ…...
ARM驱动学习之PWM
ARM驱动学习之PWM 1.分析原理图: GPD0_0 XpwmTOUT0定时器0 2.定时器上的资源: 1.5组32位定时器 2.定时器产生内部中断 3.定时器0,1,2可编程实现pwm 4.定时器各自分频 5.TCN--,TCN TCMPBN 6.分频器 24-2 7.24.3.4 例子࿱…...

我的AI工具箱Tauri版-VideoClipMixingCut视频批量混剪
本教程基于自研的AI工具箱Tauri版进行VideoClipMixingCut视频批量混剪。 VideoClipMixingCut视频批量混剪 是自研AI工具箱Tauri版中的一款强大工具,专为自动化视频批量混剪设计。该模块通过将预设的解说文稿与视频素材进行自动拼接生成混剪视频,适合需要…...

postgres_fdw访问存储在外部 PostgreSQL 服务器中的数据
文章目录 一、postgres_fdw 介绍二、安装使用示例三、成本估算四、 远程执行选项执行计划无法递推解决 参考文件: 一、postgres_fdw 介绍 postgres_fdw 模块提供外部数据包装器 postgres_fdw,可用于访问存储在外部 PostgreSQL 服务器中的数据。 此模块…...

什么是3D展厅?有何优势?怎么制作3D展厅?
一、什么是3D展厅? 3D展厅是一种利用三维技术构建的虚拟展示空间。它借助虚拟现实(VR)、增强现实(AR)等现代科技手段,将真实的展示空间数字化,呈现出逼真、立体、沉浸的展示效果。通过3D展厅&a…...

Linux下的CAN通讯
CAN总线 CAN总线简介 CAN(Controller Area Network)总线是一种多主从式 <font color red>异步半双工串行 </font> 通信总线,它最早由Bosch公司开发,用于汽车电子系统。CAN总线具有以下特点: 多主从式&a…...
【Python】pip安装加速:使用国内镜像源
【Python】pip安装加速:使用国内镜像源 零、使用命令行设置 设置全局镜像源 随便使用下面任一命令即可! 阿里云: pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/豆瓣: pip config set global.in…...
SpringBoot lombok(注解@Getter @Setter)
SpringBoot lombok(注解Getter Setter) 使用lombok注解的方式,在编译生成的字节码文件中就会存在setter/getter等方法,减少代码量,方便了代码的维护 添加依赖 <dependency><groupId>org.projectlombok</groupId><artif…...

descrTable常用方法
descrTable 为 R 包 compareGroups 的重要函数,有关该函数以及 compareGroups 包的详细内容见:R包compareGroups详细用法 加载包和数据 library(compareGroups)# 加载 REGICOR 数据(横断面,从不同年份纳入,每个变量有…...

回归预测 | Matlab实现ReliefF-XGBoost多变量回归预测
回归预测 | Matlab实现ReliefF-XGBoost多变量回归预测 目录 回归预测 | Matlab实现ReliefF-XGBoost多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.ReliefF-xgboost回归预测代码,对序列数据预测性能相对较高。首先通过ReleifF对输入特征计算权…...

年度最强悬疑美剧重磅回归,一集比一集上头
纽约的夜晚,平静被一声枪响打破,一场离奇的谋杀案悄然上演。《大楼里只有谋杀》正是围绕这样一桩扑朔迷离的案件展开的。三位主角,赛琳娜戈麦斯饰演的梅宝、史蒂夫马丁饰演的查尔斯、马丁肖特饰演的奥利弗,这些性格迥异的邻居因为…...
AI一点通: 简化大数据与深度学习工作流程, Apache Spark、PyTorch 和 Mosaic Streaming
在大数据和机器学习飞速发展的领域中,数据科学家和机器学习工程师经常面临的一个挑战是如何桥接像 Apache Spark 这样的强大数据处理引擎与 PyTorch 等深度学习框架。由于它们在架构上的固有差异,利用这两个系统的优势可能令人望而生畏。本博客介绍了 Mo…...
Python知识点:深入理解Python的模块与包管理
开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候! 深入理解Python的模块与包管理 Python的模块和包是代码组织、复用和分发的基本…...

倒排索引(反向索引)
倒排索引(Inverted Index)是搜索引擎和数据库管理系统中常用的一种数据结构,用于快速检索文档集合中的文档。在全文搜索场景中,倒排索引是一种非常高效的手段,因为它能够快速定位到包含特定关键词的所有文档。 1、基本…...
openCV的python频率域滤波
在OpenCV中实现频率域滤波通常涉及到傅里叶变换(Fourier Transform)和其逆变换(Inverse Fourier Transform)。傅里叶变换是一种将图像从空间域转换到频率域的数学工具,这使得我们可以更容易地在图像的频域内进行操作,如高通滤波、低通滤波等。 下面,我将提供一个使用Py…...

探索视频美颜SDK与直播美颜工具的开发实践方案
直播平台的不断发展,让开发出性能优异、效果自然的美颜技术,成为了技术团队必须面对的重要挑战。本篇文章,小编将深入讲解视频美颜SDK与直播美颜工具的开发实践方案。 一、视频美颜SDK的核心功能 视频美颜SDK是视频处理中的核心组件…...

Linux通过yum安装Docker
目录 一、安装环境 1.1. 旧的docker包卸载 1.2. 安装常规环境包 1.3. 设置存储库 二、安装Docker社区版 三、解决拉取镜像失败 3.1. 创建文件目录/etc/docker 3.2. 写入镜像配置 https://docs.docker.com/engine/install/centos/ 检测操作系统版本,我操作的…...

面部表情数据集合集——需要的点进来
文章目录 1、基本介绍2、每个数据集介绍2.1、FER2013(已预处理)2.2、FERPLUS(已预处理)2.3、RAF2.4、CK2.5、AffectNet2.6、MMAFEDB 3、获取方式 1、基本介绍 收集并整理了面部表情识别(Facial Emotion Recognition&am…...
AI学习指南深度学习篇-Adagrad的Python实践
AI学习指南深度学习篇-Adagrad的Python实践 在深度学习领域,优化算法是模型训练过程中至关重要的一环。Adagrad作为一种自适应学习率优化算法,在处理稀疏梯度和非凸优化问题时表现优异。本篇博客将使用Python中的深度学习库TensorFlow演示如何使用Adagr…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...

MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...