Django 中间件

【一】Django框架之生命周期流程图

在这里插入图片描述

【二】介绍

【1】概述

  • Django 中的中间件(Middleware)是一个轻量级底层的“插件”系统,用来全局改变 Django 的输入输出
  • 每个中间件组件负责处理特定的全局任务,例如处理会话、处理跨站请求伪造保护、实现缓存处理等。

【2】主要作用

  • 请求处理

    • 在 Django 处理视图之前,中间件可以对请求进行预处理。
    • 例如,某些中间件可以更改 HTTP 请求头,或者在请求对象上设置其他属性。
  • 响应处理

    • 在 Django 完成视图处理后,中间件可以对响应进行后处理。
    • 例如,某些中间件可以更改 HTTP 响应头,或者在响应内容中添加额外的数据。
  • 异常处理

    • 如果视图抛出异常,中间件可以捕获这些异常并进行处理。
    • 例如,某些中间件可以将异常记录到日志中,或者显示一个友好的错误页面。
  • 全局任务

    • 中间件可以处理那些需要在每个请求和响应中都执行的任务。
    • 例如,Django 的 SessionMiddleware 在每个请求开始时加载会话数据,并在每个响应结束时保存会话数据。
  • 大致顺序

    • 中间件是按照在 settings.py 文件的 MIDDLEWARE 设置中定义的顺序执行的。
    • 当一个请求到来时,Django 会按照从上到下的顺序应用每个中间件,然后调用相应的视图。
    • 当视图处理完成后,Django 会按照从下到上的顺序应用每个中间件,然后返回响应。

【三】默认的中间件

【1】七大中间件

(1)SecurityMiddleware

  • django.middleware.security.SecurityMiddleware

  • 安全中间件

    • 负责处理与网站安全相关的任务
  • 例如:

    • 自动转换非HTTPS请求到HTTPS(如果 SECURE_SSL_REDIRECT 设置为 True
    • 添加 HTTP Strict Transport Security(HSTS)头部(如果 SECURE_HSTS_SECONDS 设置的值大于0)
    • 以及防止点击劫持(如果 X_FRAME_OPTIONS 设置为 'DENY''SAMEORIGIN')。
  • 它可以通过配置自定义安全策略来确保网站的安全性。

(2)SessionMiddleware

  • django.contrib.sessions.middleware.SessionMiddleware
  • 会话中间件
    • 它在每个请求开始时加载会话数据,并在每个响应结束时保存会话数据。

(3)CommonMiddleware

  • django.middleware.common.CommonMiddleware
  • 通用中间件
    • 提供了一些常见而关键的HTTP请求处理功能
    • 例如,根据请求的HTTP头信息设置语言、时区等。

(4)CsrfViewMiddleware

  • django.middleware.csrf.CsrfViewMiddleware
  • 跨站请求伪造中间件CSRF(Cross-Site Request Forgery)
    • 用于防止跨站请求伪造攻击。
    • 它在每个POST请求中验证一个CSRF标记,确保请求是通过合法的表单提交得到的,从而保护用户免受恶意站点的攻击。

(5)AuthenticationMiddleware

  • django.contrib.auth.middleware.AuthenticationMiddleware
  • 认证中间件
    • 负责处理用户身份认证相关的任务
    • 这个中间件为每个请求添加一个 user 属性,表示当前的登录用户。如果用户没有登录,request.user 将是一个 AnonymousUser 实例。否则,request.user 将是一个 User 实例。

(6)MessageMiddleware

  • django.contrib.messages.middleware.MessageMiddleware
  • 消息中间件
    • 用于在请求处理过程中存储和传递临时的、一次性的用户消息。
    • 它允许在HTTP重定向之间跨请求传递消息,例如成功或错误提示,以改善用户体验。

(7)XFrameOptionsMiddleware

  • django.middleware.clickjacking.XFrameOptionsMiddleware
  • 点击劫持中间件
    • 用于防止页面被嵌入到其他网站中,从而提供一定的点击劫持保护。
    • 它通过设置X-Frame-Options HTTP头部来限制页面的显示方式,从而防止恶意网页通过iframe等方式嵌入当前网页。

【2】中间件方法

(1)process_request

  • process_request(self, request)
    • 他会在Django开始处理每个请求之前被调用
    • 这个方法接收一个request参数,这参数是一个HttpResponse对象,包含关于当前请求的所有信息
    • 这个方法可以修改request对象,或者直接返回一个HttpResponse对象来终止请求的处理
    • 这个参数如果是None,Django将会继续处理这个请求
# Django 1.10 以前的旧的中间件风格
from django.http import HttpResponseRedirect
from django.urls import reverse
class AuthenticationMiddleware:def process_request(self, request):# 在这里进行身份验证操作if not request.user.is_authenticated:# 如果用户未经身份验证,则返回HttpResponse或重定向到登录页面return HttpResponseRedirect(reverse('login'))
# Django 1.10 以后的新的中间件风格,它需要定义 __call__ 方法。__call__ 方法在每个请求上都会被调用
from django.http import HttpResponseRedirect
from django.urls import reverseclass AuthenticationMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):# 在这里进行身份验证操作if not request.user.is_authenticated:# 如果用户未经身份验证,则重定向到登录页面return HttpResponseRedirect(reverse('login'))# 如果用户已经通过身份验证,继续处理请求# get_response 是一个回调函数,当我们在中间件中调用它时,Django 会继续处理请求,调用视图函数并生成响应。response = self.get_response(request)return response

(2)process_response

  • process_response(self, request, response)
    • 它会在 Django 完成处理每个请求之后被调用
    • 这个方法接收两个参数:request 是一个 HttpRequest 对象,包含了关于当前请求的所有信息response 是一个 HttpResponse 对象,包含了当前请求的响应
    • 这个方法可以修改 response 对象,或者返回一个全新的 HttpResponse 对象。
    • 无论这个方法返回什么,这个返回值都将作为请求的最终响应。
# # Django 1.10 以前的旧的中间件风格
class CustomResponseMiddleware:def process_response(self, request, response):# 在这里对响应进行处理response['X-Custom-Header'] = 'Custom Value'return response
# # Django 1.10 以后的新的中间件风格,它需要定义 __call__ 方法。__call__ 方法在每个请求上都会被调用
class CustomResponseMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):# 在这里,可以添加在请求被处理之前需要执行的逻辑response = self.get_response(request)# 在这里对响应进行处理response['X-Custom-Header'] = 'Custom Value'return response
  • 每个中间件都是依次处理的,而不是并行处理的。尽管在新的中间件风格(Django 1.10 及更高版本)中,__call__ 方法同时处理进入和离开的请求,但这并不意味着中间件是并行运行的。

    当一个请求到达 Django 应用时,它会按照 MIDDLEWARE 列表的顺序,依次通过每个中间件的 __call__ 方法。当在 __call__ 方法中调用 get_response(request) 时,控制权会传递给下一个中间件,直到所有的中间件都运行完毕,然后才会执行视图函数。

    在视图函数执行完毕并生成响应后,控制权会按照与进入时相反的顺序,回到每个中间件的 __call__ 方法。在这个阶段,中间件可以修改响应或执行其他后处理操作。

    所以,尽管 __call__ 方法看起来同时处理进入和离开的请求,但实际上,中间件仍然是按照特定的顺序依次执行的。这就是为什么 Django 中间件有时被描述为像洋葱一样的结构:每个中间件都像洋葱的一层,请求和响应都必须穿过所有的层。

(3)process_view

  • process_view(request, view_func, view_args, view_kwargs)
    • 路由匹配成功后执行视图函数之前
    • 这个方法的参数包括请求对象、视图函数、视图函数的参数和关键字参数。
    • 如果这个方法返回一个 HttpResponse 对象视图函数将不会被调用
import logging
logger = logging.getLogger(__name__)class LoggingMiddleware:def process_view(self, request, view_func, view_args, view_kwargs):# 在这里记录日志logger.info(f"Request received: {request.path}")# 返回None,继续执行原视图函数return None

(4)process_template_response

  • process_template_response(request, response)
    • 这个方法在视图函数处理完请求并生成了一个模板响应对象后返回的 HttpResponse 对象有 render 属性的时候才会触发
    • 顺序是按照配置文件中注册了的中间件从下往上依次经过。
    • 这个方法的参数包括请求对象和视图函数返回的响应对象。必须返回一个TemplateResponse对象,通常是传入的响应对象或者一个新的响应对象。

(5)process_exception

  • process_exception(request, exception)
    • 这个方法在视图函数或者其他的中间件方法抛出异常时运行。
    • 顺序是按照配置文件中注册了的中间件从下往上依次经过
    • 例如返回一个定制的错误页面或进行日志记录等。
    • 这个方法的参数包括请求对象和抛出的异常对象。
    • 如果这个方法返回一个 HttpResponse 对象,这个响应将会被发送到客户端,而且其他的 process_exception 方法将不会被调用
class SimpleMiddleware:def process_exception(self, request, exception):# 在这里处理异常# 如果返回 HttpResponse 对象,Django 将停止调用其他的 process_exception 方法# 如果返回 None 或者没有明确的返回值,Django 将继续调用其他的 process_exception 方法return None
class ErrorHandlerMiddleware:def process_exception(self, request, exception):# 在这里处理异常if isinstance(exception, CustomException):# 如果自定义异常,返回一个定制的错误页面return render(request, 'error.html', {'error': str(exception)})else:# 默认情况,返回一个500服务器错误return HttpResponseServerError("Internal Server Error")

【四】自定义中间件

【1】简单示例

(1)自定义

  • 自定义中间件位置
    • 可以在项目的根目录或者在应用目录下创建任意名称的文件夹
  • 创建py文件
    • py文件的名字也是任意
  • 创建自定义中间件类
    • 需要继承MiddlewareMixin混入类
  • 版本
    • 在 Django 1.10 之前,中间件需要定义一些特定的方法,如 process_request(request)process_response(request, response) 等,并且需要继承 MiddlewareMixin 混入类
    • 在 Django 1.10 及之后的版本中,推荐的写法是定义一个只有两个方法(__init____call__)的类。
from django.utils.deprecation import MiddlewareMixinclass MyMiddleWare1(MiddlewareMixin):def process_request(self, request):print("第一个中间件的process_request")def process_response(self, request, response):print("第一个中间件的process_response")return responseclass MyMiddleWare2(MiddlewareMixin):def process_request(self, request):print("第二个中间件的process_request")def process_response(self, request, response):print("第二个中间件的process_response")return response

(2)添加到配置文件

  • 在settings文件的
    • MIDDLEWARE列表里面添加自定中间件
    • 整体是字符串格式
    • 路径之间通过.符号连接
    • 多个中间件之间以,逗号连接
  • 这里按照中间件1然后中间件2的顺序注册
MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',# 添加自定义中间件'app01.mymiddleware.my_middleware.MyMiddleWare1','app01.mymiddleware.my_middleware.MyMiddleWare2',
]

(3)测试

  • 视图函数
def home(request):print("访问主页")return HttpResponse("主页")
  • 输出结果
第一个中间件的process_request
第二个中间件的process_request
访问主页
第二个中间件的process_response
第一个中间件的process_response

【2】测试process_request

(1)django框架

  • 如果将第一个中间件的process_request
    • 添加返回值HttpResponse
    • 那么将直接走当前中间件的process_response
def process_request(self, request):print("第一个中间件的process_request")print("第一个中间价process_request拦截")return HttpResponse("中间件一拦截")
  • 结果
第一个中间件的process_request
第一个中间价process_request拦截
第一个中间件的process_response

(2)flask框架

  • flask框架的中间件也有类似的方法
  • 但是Flask 的中间件处理方式与 Django 略有不同。
    • 方法名字不同:
      • Flask 使用称为 “before_request” 和 “after_request” 的装饰器来处理请求前和请求后的操作。
    • 处理结果不同:
      • 在 Flask 中,如果在第一个中间件的 before_request 中返回了一个 Response 对象,那么 Flask 将立即停止处理后续的 before_request 函数,并且立即开始处理所有已注册的 after_request 函数。
      • 和djanfo相同的是都是倒叙

【五】跨站请求伪造

【1】介绍

(1)概述

  • 跨站请求伪造
    • (Cross-Site Request Forgery,CSRF)是一种网络攻击方式
    • 攻击者通过伪造用户的请求来让被攻击的网站执行非预期的操作
  • 例如:
    • 假设你已经登录了一个网站,并且在这个网站上有一些敏感操作,比如更改密码或者转账。
    • 一个 CSRF 攻击可能会在你访问一个恶意网站时,伪造一个请求到这个网站,尝试更改你的密码或者转账。
    • 因为你已经登录了这个网站,所以这个请求可能会被这个网站接受,并执行这个操作。

(2)html示例

<!DOCTYPE html>
<html>
<head><title>Test Page</title>
</head>
<body><form action="没被攻击的网站" method="post"><input type="text" placeholder="请输入转账目标用户"><input type="text" name="hiddenField" value="实际被更改的收款方" style="display: none;"><input type="submit" value="Submit"></form>
</body>

(3)防止 CSRF 攻击措施

  1. 使用 CSRF 令牌
    • 在每个需要用户交互的请求中,服务器都会生成一个唯一的 CSRF 令牌,并将其嵌入到表单中。
    • 当用户提交表单时,服务器会检查请求中的 CSRF 令牌是否与之前生成的令牌匹配。
    • 如果不匹配,服务器就会拒绝这个请求。因为攻击者无法预测 CSRF 令牌,所以这可以有效地防止 CSRF 攻击。
  2. 检查 Referer 头
    • 服务器可以检查每个请求的 Referer 头,以确保它来自于一个可信的源。
    • 如果一个请求来自于一个不可信的源,服务器就可以拒绝这个请求。
  3. 使用 SameSite Cookie 属性
    • 这是一个相对较新的方法,通过设置 Cookie 的 SameSite 属性,可以限制 Cookie 只能在同一个站点中使用。
    • 这可以防止攻击者在其他站点中使用用户的 Cookie。
  4. 使用验证码
    • 在执行敏感操作时,要求用户输入验证码,可以防止 CSRF 攻击,因为攻击者无法预测验证码。
  5. 使用双重 Cookie 验证:
    • 在这种方法中,当用户登录时,服务器会发送两个 Cookie:一个是常规的会话 Cookie,另一个是 CSRF Cookie,它包含一个随机生成的 CSRF 令牌。
    • 然后,每当用户发送一个修改数据的请求(例如 POST 请求)时,客户端都需要在请求的参数中包含这个 CSRF 令牌。
    • 服务器会检查这个 CSRF 令牌是否与 CSRF Cookie 中的令牌匹配。如果不匹配,服务器就会拒绝这个请求。

【2】POST请求校验CSRF

  • 首先取消settings文件中的注释
  • 开启csrf检查

(1)form表单提交csrf

  • 在form表单里面添加
    • {% csrf_token%}
<form action="" method="post">{% csrf_token %}<p>username: <input type="text" name="username"></p><p>password: <input type="password" name="password"></p><button class="" id="b1">提交</button>
</form>
  • 前端源码会自动出现一个标签
    • name是csrfmiddlewaretoken
    • value是实时刷新的csrf令牌
<input type="hidden" name="csrfmiddlewaretoken" value="xKeMNRcsTZ1ws40kq8MXKSAfdsVIu9pVIwQZaOdYpAPyPXKXYr6CMYlVN8p5bbcn">
  • 后端可以拿到的数据
    • 堕落一个csrf令牌
<QueryDict: {'csrfmiddlewaretoken': ['xKeMNRcsTZ1ws40kq8MXKSAfdsVIu9pVIwQZaOdYpAPyPXKXYr6CMYlVN8p5bbcn'], 'username': [''], 'password': ['']}>

(2)使用ajax提交csrf

  • 通过jquery语法捕获表单的内容传递给后端
<script>$(document).ready(function () {$("#b1").on('click', function (event) {event.preventDefault();$.ajax({url: "",type: "post",data: {username: $("input[name='username']").val(),password: $("input[name='password']").val(),csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val(),},success: function () {}})})})
</script>
  • 使用jquery的serialize()方法
<script>$(document).ready(function () {$("#b1").on('click', function (event) {event.preventDefault();let formData = $("form").serialize()$.ajax({url: "",type: "post",data: formData,success: function () {}})})})
</script>
  • 使用模板语法取值
<script>$(document).ready(function () {$("#b1").on('click', function (event) {event.preventDefault();$.ajax({url: "",type: "post",data: {username: $("input[name='username']").val(),password: $("input[name='password']").val(),csrfmiddlewaretoken: "{{ csrf_token }}",},success: function () {}})})})
</script>

(3)添加Js文件

  • 在static文件夹内添加js文件
function getCookie(name) {var cookieValue = null;if (document.cookie && document.cookie !== '') {var cookies = document.cookie.split(';');for (var i = 0; i < cookies.length; i++) {var cookie = jQuery.trim(cookies[i]);// Does this cookie string begin with the name we want?if (cookie.substring(0, name.length + 1) === (name + '=')) {cookieValue = decodeURIComponent(cookie.substring(name.length + 1));break;}}}return cookieValue;
}
var csrftoken = getCookie('csrftoken');function csrfSafeMethod(method) {// these HTTP methods do not require CSRF protectionreturn (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}$.ajaxSetup({beforeSend: function (xhr, settings) {if (!csrfSafeMethod(settings.type) && !this.crossDomain) {xhr.setRequestHeader("X-CSRFToken", csrftoken);}}
});
  • ajax发送
    • 此时后端可以拿到传输的数据
    • 不过csrf令牌不在以出现在request.POST中
{% load static %}
<script src="{% static 'js/csrf_check.js' %}"></script>
<script>$(document).ready(function () {$("#b1").on('click', function (event) {event.preventDefault();$.ajax({url: "",type: "post",data: {username: $("input[name='username']").val(),password: $("input[name='password']").val(),},success: function () {}})})})
</script>

【3】CSRF装饰器

  • 校验csrf总体有两种策略
    • 网站整体都校验csrf,部分不校验csrf
    • 网站整体都不校验csrf,部分校验csrf

(1)介绍

  • 导入
from django.views.decorators.csrf import csrf_exempt, csrf_protect
  • csrf_protect装饰器
    • 以确保视图函数在处理 POST 请求时进行 CSRF 验证。
    • 这对于某些视图函数来说是非常有用的,特别是当全局设置中禁用了 CSRF 中间件,但你仍然想要在某些特定的视图函数中启用 CSRF 保护。
    • 如果请求中没有有效的CSRF令牌或令牌校验失败,Django将返回403 Forbidden响应。
  • csrf_exempt装饰器
    • 可以使特定的视图函数免于 CSRF 验证。
    • 这在某些情况下是非常有用的,例如,当全局设置中启用了 CSRF 中间件,但你想要在某些特定的视图函数中禁用 CSRF 保护。
    • 比如与第三方系统进行集成、开放API接口等

(2)FBV使用

  • 没有特殊要求和特殊情况
  • 直接使用即可

(3)CBV使用

  • 在给CBV添加装饰器中
    • 三种方式都可以使用@csrf_protect装饰器
    • 针对@csrf_exempt装饰器只能给dispath方法,其他无效

【六】中间件思想importlib

【1】中间件的导入方式

  • 在settings配置文件中
    • MIDDLEWARE列表里面添加自定中间件
    • 整体是字符串格式
    • 路径之间通过.符号连接
    • 多个中间件之间以,逗号连接
  • 优势
    1. 想要添加具有同样方法的类,直接创建文件以后,添加配置即可
    2. 不想使用某个类的方法了,直接注释掉配置的响应配置
  • 总结
    1. 动态加载
    2. 灵活、可拓展
MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]

【2】分析

  • 这种方式中

    • 在最后一个.点符号之前,都是文件路径

    • 最后一个.点符号之后,就是类名了

    • 这不就是

      • from 路径 import 类名
        
  • 有这么一个模块importlib

    • 他提供了动态导入模块的方式
    • 即程序运行时,而不是在编译时
import importlib# 动态导入 math 模块
math = importlib.import_module('math')# 现在可以使用 math 模块了
print(math.sqrt(16))  # 输出:4.0

【3】使用反射函数和importlib

(1)模仿创建多个类文件

  • my_class/qq.py
class QQ(object):def send(self, content):print(f"QQ发送消息:>>>{content}")
  • my_class/dingding.py
class DingDing(object):def send(self, content):print(f"DingDing发送消息:>>>{content}")
  • my_class/wechat.py
class WeChat(object):def send(self, content):print(f"WeChat发送消息:>>>{content}")

(2)模仿创建配置文件settings

  • my_class/settings.py
MODEL_LIST = ['dingding.DingDing','qq.QQ','wechat.WeChat',
]

(3)配置__init__.py

  • my_class/__init__.py
import os
import sys
from my_class import settings
import importlib# 添加当前文件夹到工作目录
sys.path.append(os.path.dirname(__file__))# 创建共同的方法接口
def send_all(content):for path_str in settings.MODEL_LIST:# 最右按照点符号侧切分一次,得到路径和类名model_path, class_name = path_str.rsplit('.', maxsplit=1)# 导入每个类的文件对象model = importlib.import_module(model_path)# 使用反射方法拿到类名cls = getattr(model, class_name)# 实例化类obj = cls()# 执行统一方法obj.send(content)if __name__ == '__main__':send_all("hello world")# DingDing发送消息:>>>hello world# QQ发送消息:>>>hello world# WeChat发送消息:>>>hello world

(4)外部文件使用

import my_classmy_class.send_all("Hi")
# DingDing发送消息:>>>Hi
# QQ发送消息:>>>Hi
# WeChat发送消息:>>>Hi

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

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

相关文章

【有限状态机】- FSM详细讲解 【附Autoware有限状态机模型代码讲解】

参考博客&#xff1a; &#xff08;1&#xff09;FSM&#xff08;有限状态机&#xff09; &#xff08;2&#xff09;关于有限状态机(FSM)的一些思考 &#xff08;3&#xff09;状态设计模式 1 状态机简介 有限状态机FSM&#xff1a;有限个状态以及在这些状态之间的转移和动作…

2024年最新最全Vue3开源后台管理系统复盘总结

在现代前端开发中&#xff0c;搭建一个高效、灵活、易用的后台管理系统并不容易。然而&#xff0c;Vue3 的出现为我们提供了一个备受瞩目的选择。作为一个现代化的前端框架&#xff0c;Vue3 具有众多优点&#xff0c;能够帮助开发者快速搭建企业级中后台产品原型。 今天&#…

iphoneX系统的参数

1. 2. 3. 4. 5.相关的网址信息 Apple iPhone X 規格、价格和评论 | Kalvo Apple iPhone X 規格、价格和评论 | Kalvo

UOS、Linux下的redis的详细部署流程(适用于内网)

提示&#xff1a;适用于Linux以及UOS等内外网系统服务器部署。 文章目录 一.上传离线包二.部署基本环境三.解压并安装redis四.后台运行redis五.uos系统可能遇到的问题六.总结 一.上传离线包 1.自己去Redis官网下载适配自己部署系统的redis安装包。 2.通过文件传输工具&#xf…

Rust使用原始字符串字面量实现Regex双引号嵌套双引号正则匹配

rust使用Regex实现正则匹配的时候&#xff0c;如果想实现匹配双引号&#xff0c;就需要使用原始字符串字面量&#xff0c;不然无法使用双引号嵌套的。r#"..."# 就表示原始字符串字面量。 比如使用双引号匹配&#xff1a; use regex::Regex;fn main() {println!(&qu…

快速幂算法在Java中的应用

引言&#xff1a; 在计算机科学和算法领域中&#xff0c;快速幂算法是一种用于高效计算幂运算的技术。在实际编程中&#xff0c;特别是在处理大数幂运算时&#xff0c;快速幂算法能够显著提高计算效率。本文将介绍如何在Java中实现快速幂算法&#xff0c;并给出一些示例代码和应…

151 shell编程,正则表达式,在C语言中如何使用正则表达式

零&#xff0c;坑点记录&#xff1a;bash 和 dash 的区别&#xff0c;导致的坑点 查看当前用的shell 是啥&#xff0c;用的是/bin/bash hunandedehunandede-virtual-machine:~$ echo $SHELL /bin/bash 当shell 脚本运行的时候&#xff08;后面会学到方法&#xff0c;这里是最…

全局UI方法-弹窗一警告弹窗(AlertDialog)

1、描述 显示警告弹窗组件&#xff0c;可设置文本内容与响应回调。 2、属性 名称参数类型参数描述showAlertDialogParamWithConfirm | AlertDialogParamWithButtons定义并显示AlertDialog组件。 2.1、AlertDialogParamWithConfirm对象说明&#xff1a; 参数名称参数类型必填…

『Apisix安全篇』探索Apache APISIX身份认证插件:从基础到实战

&#x1f680;『Apisix系列文章』探索新一代微服务体系下的API管理新范式与最佳实践 【点击此跳转】 &#x1f4e3;读完这篇文章里你能收获到 &#x1f6e0;️ 了解APISIX身份认证的重要性和基本概念&#xff0c;以及如何在微服务架构中实施API安全。&#x1f511; 学习如何使…

FreeRTOS(三)

第二部分 事件组 一、事件组的简介 1、事件 事件是一种实现任务间通信的机制&#xff0c;主要用于实现多任务间的同步&#xff0c;但事件通信只能是事件类型的通信&#xff0c;无数据传输。其实事件组的本质就是一个整数(16/32位)。可以是一个事件发生唤醒一个任务&#xff…

ClickHouse初体验

1.clickHouse是啥&#xff1f; ClickHouse 是俄罗斯的 Yandex 于 2016 年开源的列式存储数据库(DBMS)&#xff0c;使用 C语言编写&#xff0c;主要用于在线分析处理查询(OLAP)&#xff0c;能够使用SQL查询实时生成分析数据报告 2.clickHouse的特点 2.1列式存储 对于列的聚合&…

城市内涝排水新模式:慧天[HTWATER]

慧天[HTWATER]软件&#xff1a;慧天排水数字化分析平台针对城市排水系统基础设施数据管理的需求&#xff0c;以及水文、水力及水质模拟对数据的需求&#xff0c;实现了以数据库方式对相应数据的存储。可以对分流制排水系统及合流制排水系统进行地表水文、管网水力、水质过程的模…

Transformers 直观解释——不仅是如何工作,而且为什么工作得这么好

输入序列如何到达Attention模块 注意力模块存在于编码器堆栈中的每个编码器中&#xff0c;以及解码器堆栈中的每个解码器中。我们将首先放大编码器的注意力。 Attention in the Encoder&#xff1a; 举个例子&#xff0c;假设我们正在研究一个英语到西班牙语的翻译问题&…

【旅游】泉州攻略v1.0.0

一、泉州古城 泉州市距离深圳大约520公里&#xff0c;从深圳北站出发&#xff0c;高铁大约3小时30分。 到达泉州西站后&#xff0c;往东南方向大约8公里&#xff0c;就可以到达主要的旅游景点泉州古城。 古城很适合使用一天玩耍&#xff0c;核心路线如下&#xff1a; 一路的景…

C++ STL教程

C STL教程 文章目录 C STL教程1.1 std::vector1.1.1vector的定义1.1.2vector容器的初始化1.1.3vector容器内元素的访问和修改1.1.4vector中的常用函数 1.2 std::string1.2.1string的定义1.2.2string的初始化1.2.3string中元素的访问和修改1.2.4string中连接字符串1.2.5string中…

AtCoder Beginner Contest 337 A - E

A - Scoreboard 大意 高桥队和青木队进行了场比赛&#xff0c;给出每场比赛中高桥队和青木队的积分&#xff0c;问最后谁总分更高或平局。 思路 统计总分比较即可。 代码 #include<iostream> using namespace std; int main(){int n, a0, b0;cin >> n;while(…

介绍部署esxi8.0产品的方式

什么是esxi esxi的中文叫裸机虚拟机管理器 ESXi是由VMware公司开发的一种裸机虚拟机管理器&#xff0c;全称为VMware ESXi。 ESXi是一种虚拟化技术&#xff0c;专门设计用于在物理服务器上运行虚拟机&#xff0c;它的主要特点是能够最大限度地降低硬件配置要求并简化部署过程…

vcf文件可以用excel打开吗?四种解决方案

vcf文件可以用excel打开吗&#xff1f; 当然可以。 一、VCF文件简介 VCF&#xff08;vCard&#xff09;文件是一种用于存储联系人信息的文件格式。它通常包含姓名、电话号码、电子邮件地址、地址等详细信息。VCF文件在多种设备和操作系统中广泛使用&#xff0c;特别是在电子邮…

2024全国水科技大会【高峰对话】北京排水集团(附部分报告题目)

北京排水集团坚持“服务社会、造福百姓、企业利益与公众利益高度一致”的宗旨&#xff0c;充分认知自身在地区经济发展中的社会责任&#xff0c;以满足政府与公众对公用事业企业服务的需求为首要任务&#xff0c;通过“现代化的队伍、现代化的手段、现代化的设备和现代化的管理…

springBoot+ureport报表引擎

UReport是一款基于单元格迭代模型的纯Java中式报表引擎。它架构于Spring之上&#xff0c;因此与企业应用具有良好的集成能力。UReport提供了基于Eclipse插件与基于网页的两种报表模版设计方式&#xff0c;采用类Excel报表模版设计风格&#xff0c;简单、易上手&#xff0c;可在…