Django中间件与csrf

news2024/11/16 3:34:53

一. django中间件

1. 什么是django中间件

# django中间件是django的门户
        1. 请求来的时候需要先经过中间件才能到达真正的django后端
        2. 响应走的时候最后也需要经过中间件才能发送出去

2. django中间件的个数

django自带七个中间件, 分别是SecurityMiddleware, SessionMiddleware,
        CommonMiddleware, CsrfViewMiddleware, AuthenticationMiddleware,
        MessageMiddleware, XFrameOptionMiddleware

3. django请求生命周期流程图

 

4. 研究django中间件代码规律

# settings.py配置文件中
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',
    ]

class SessionMiddleware(MiddlewareMixin):
    def process_request(self, request):
        ...
    def process_response(self, request, response):
        ...

class CsrfViewMiddleware(MiddlewareMixin):
    def process_request(self, request):
        ...
    def process_view(self, request, callback, callback_args, callback_kwargs):
        ...

    def process_response(self, request, response):
        ...

class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        ...   

5. 自定义中间件

# django支持程序员自定义中间件, 并且暴露给程序员五个可以自定义的方法
    # 掌握
        process_request
        process_response
    # 了解
        process_view
        process_template_response
        process_exception

5-1. 自定义中间件流程
1. 在项目名或者应用名下创建一个任意名称的文件夹
2. 在该文件夹内创建一个任意名称的py文件
3. 在该py文件内需要书写类(注意: 这个类必须继承MiddlewareMixin)
    然后在这个类里面就可以自定义五个方法了
    提示: 这五个方法并不是全部都需要书写,用几个写几个
4. 需要将类的路径以字符串的形式注册到settings.py配置文件中的MIDDLEWARE下才能生效
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',
    # 注册自己的中间件(在应用下创建路径有提示,但是如果在项目下创建就没有提示了 你就需要自己比对着书写)
    '你自己写的中间件的路径1',
    '你自己写的中间件的路径2',
    '你自己写的中间件的路径3',
]

5-2. 二种掌握自定义: process_request, process_response
'''
process_request
    1. 请求来的时候会依此走 MIDDLEWARE 中定义的该方法. 如果没有定义就跳过.
        执行顺序:  MIDDLEWARE 中从上到下
    2. 如果返回 HttpResponse 对象, 请求将不会继续往后执行, 而是原路返回
        目的: 用来做全局相关的所有限制功能
        应用: 校验失败不允许访问

process_response
    1. 响应走的时候会依此走 MIDDLEWARE 中定义的该方法. 如果没有定义就跳过.
        执行顺序:  MIDDLEWARE 中从下到上
    2. 该方法必须返回  HttpResponse 对象
        2.1 默认返回形参response
        2.2 返回自定义的
    拓展: 


综合2者: 如果 process_request 方法指定返回 HttpResponse对象.
     1. 后续 process_request 方法不执行.
     2. 从同级别 process_response 方法开始按照 MIDDLEWARE 从下到上依此返回.
     3. 如果 process_response 方法没有指定自定义返回结果, 默认返回的就是 process_request 中返回的结果. 否则返回 process_response 方法的结果
     
拓展: flask框架也有一个中间件但是它的规律
    只要返回数据了就必须经过所有中间件里面的类似process_reponse方法     
'''
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse


class FirstMiddleware(MiddlewareMixin):
    def process_request(self, request):
        """
        1. 请求来的时候需要经过每一个中间件里面的process_request方法
            结果的顺序是按照配置文件中注册的中间件从上往下的顺序依次执行
        2. 如果中间件里面没有定义该方法,那么直接跳过执行下一个中间件
        3 .如果该方法返回了HttpResponse对象,那么请求将不再继续往后执行
            而是直接原路返回(校验失败不允许访问...)
            process_request方法就是用来做全局相关的所有限制功能
        """
        print('我是 FirstMiddleware 类中的定义的 process_request 方法')

    def process_response(self, request, response):
        """
        1.响应走的时候需要结果每一个中间件里面的process_response方法
        该方法有两个额外的参数request,response
        2. 该方法必须返回一个HttpResponse对象. 不返回抛出异常: 'NoneType' object has no attribute 'get'
            2-1. 默认返回的就是形参response
            2-2. 你也可以自己返回自己的
        3. 顺序是按照配置文件中注册了的中间件从下往上依次经过
            如果你没有定义的话 直接跳过执行下一个
        :param response: 就是django后端返回给浏览器的内容
        """
        print('我是 FirstMiddleware 类中的定义的 process_response 方法')
        return response


class SecondMiddleware(MiddlewareMixin):
    def process_request(self, request):
        print('我是 SecondMiddleware 类中的定义的 process_request 方法')
        # return HttpResponse(
        #     '研究2: 如果 process_request 方法返回了 HttpResponse 对象,那么请求将不再继续往后执行而是直接原路返回. 响应走的时候是经过同级别的 process_response 返回')

    def process_response(self, request, response):
        print('我是 SecondMiddleware 类中的定义的 process_response 方法')
        # return HttpResponse('研究1: 如果 process_response 方法返回了 HttpResponse 对象,那么响应按照自己的返回结果作为标准返回.')
        return response

5-3. 三种了解自定义: process_view, process_template_response, process_exception
'''
process_view
    路由匹配之前 或者 执行视图函数之前 时触发
    执行顺序: MIDDLEWARE 中从上到下
process_template_response
    视图函数返回结果中含有render属性是触发
    执行顺序: MIDDLEWARE 中从下到上
process_exception
    视图函数出现异常时触发
    执行顺序: MIDDLEWARE 中从下到上
'''
from django.utils.deprecation import MiddlewareMixin


class FirstMiddleware(MiddlewareMixin):
    def process_view(self, request, view_name, *args, **kwargs):
        """
        路由匹配成功之后执行视图函数之前,会自动执行中间件里面的该放法
        顺序是按照配置文件中注册的中间件从上往下的顺序依次执行
        """
        print(view_name, args, kwargs)    # <function my_index at 0x000002345C28BEA0> ((), {}) {}
        print('我是第一个自定义中间件里面的 process_view')

    def process_template_response(self, request, response):
        """
        返回的HttpResponse对象有render属性的时候才会触发
        顺序是按照配置文件中注册了的中间件从下往上依次经过
            def index(request):
                print('我是视图函数index')
                obj = HttpResponse('index')

                def render():
                    print('内部的render')
                    return HttpResponse("O98K")

                obj.render = render
                return obj
        """
        print('我是第一个自定义中间件里面的 process_template_response')
        return response

    def process_exception(self, request, exception):
        """
        当视图函数中出现异常的情况下触发
        顺序是按照配置文件中注册了的中间件从下往上依次经过
        """
        print('我是第一个中间件里面的 process_exception')
        print(exception)


class SecondMiddleware(MiddlewareMixin):
    def process_view(self, request, view_name, *args, **kwargs):
        print(view_name, args, kwargs)
        print('我是第二个自定义中间件里面的 process_view')

    def process_template_response(self, request, response):
        print('我是第二个自定义中间件里面的 process_template_response')
        return response

    def process_exception(self, request, exception):
        print('我是第二个中间件里面的process_exception')
        print(exception)

二. csrf跨站请求伪造

1. csrf介绍

# csrf 全称 cross site request forgery 跨站请求伪造

# 举一个实例来描述什么是csrf:
    我搭建一个跟正规网站一模一样的界面(中国银行)
    用户不小心进入到了我们的网站,用户给某个人打钱
    打钱的操作确确实实是提交给了中国银行的系统,用户的钱也确确实实减少了
    但是唯一不同的时候打钱的账户不适用户想要打的账户变成了一个莫名其妙的账户

# 内部本质
    我们在钓鱼网站的页面 针对对方账户 只给用户提供一个没有name属性的普通input框
    然后我们在内部隐藏一个已经写好name和value的input框

# 如何规避上述问题: csrf跨站请求伪造校验
    网站在给用户返回一个具有提交数据功能页面的时候会给这个页面加一个唯一标识, 斌且这个唯一标识永远不一样
    当这个页面朝后端发送post请求的时候 我的后端会先校验唯一标识,如果唯一标识不对直接拒绝(403 forbbiden)如果成功则正常执行

2. CSRF跨站请求伪造及解决思路流程图

 

3. 针对form与ajax的符合校验设置来解决CSRF问题

# form表单符合校验: 只需要指定一个 {% load csrf_token %} 即可
    <head>
        {% load static %} {# 方式三 #}
        <script src="{% static 'js/pass_csrf.js' %}"></script>
    </head>
    <body>
    <h3>我是正规网站</h3>
    <form action="" method="post">
        {% csrf_token %}
        <p>转账账户: <input type="text" name="user"></p>
        <p>目标账户: <input type="text" name="target_user"></p>
        <p>转账金额: <input type="text" name="money"></p>
        <input type="submit" value="form表单提交">
    </form>
    <br>

# ajax符合校验设置
'''
方式一: 利用标签查找获取页面上的随机字符串
    'csrfmiddlewaretoken': $("[name='csrfmiddlewaretoken']").val()
方式二:  利用模版语法提供的快捷书写
    'csrfmiddlewaretoken': '{{ csrf_token }}'
    注意: 这里是 '{{ csrf_token }}' 而不是 {% csrf_token %}
方式三: 通用直接拷贝js代码并应用到自己的html页面上即可
    {% load static %}
    <script src="{% static 'js/pass_csrf.js' %}"></script>
'''
<button id="d1">ajax方式提交</button>
<script>
    $('#d1').on('click', function () {
        $.ajax({
            url: '',
            type: 'post',
            data: {
                'user': 'jason',
                {#'user': $("[name='user']").val(),#}
                {#'target_user': $("[name='target_user']").val(),#}
                'target_user': 'egon',
                {#'money': $("[name='money']").val(),#}
                'money': '100000',
                {#'csrfmiddlewaretoken': $("[name='csrfmiddlewaretoken']").val(),#}      // 方式一
                {#'csrfmiddlewaretoken': '{{ csrf_token }}',#}  // 方式二
            },
            success: function () {

            },
        })
    })
</script>

ajax符合校验设置第三种方法的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 protection
  return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
  beforeSend: function (xhr, settings) {
    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
      xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
  }
});

4. {% csrf_token%} 与 {{ csrf_token }}的表现形式及两者之间的关系

# {% csrf_token%}
    <input type="hidden" name="csrfmiddlewaretoken" value="Fuih8hBFfSw7usOBVz1FF8yWYlBVeqmJ59O0HGGZp9Rko4Ovm9F5QnS2Zm0dKV5K">

# {{ csrf_token }}
    # 对应的就是{% csrf_token %}input标签中的value值
    BTYOUHdtrTRzOKnSFn1yzu4hnbs2J88h1yuxt6iNBacMImnM6XFYKJonocRkfDRi

三. csrf相关装饰器

# 需求
'''
1. 网站整体都不校验csrf,就单单几个视图函数需要校验
2. 网站整体都校验csrf,就单单几个视图函数不校验
'''

1. 针对FBV

from django.views.decorators.csrf import csrf_protect, csrf_exempt


# @csrf_exempt
# @csrf_protect
def my_transfer(request):
    if request.method == "POST":
        user = request.POST.get('user')
        target_user = request.POST.get('target_user')
        money = request.POST.get('money')
        print(f'{user}给{target_user}转了{money}元')
    return render(request, 'my_transfer.html')

2. 争对CBV

"""
csrf_protect  需要校验
    针对csrf_protect符合装饰器的三种玩法
csrf_exempt   忽视校验
    针对csrf_exempt只能给dispatch方法加才有效
"""
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decorators


# @method_decorator(csrf_protect, name='post')
class MySelfCsrfToken(View):
    # @method_decorator(csrf_protect)
    def dispatch(self, request, *args, **kwargs):
        return super(MySelfCsrfToken, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return HttpResponse('get 请求')

    # @method_decorator(csrf_protect)
    def post(self, request):
        return HttpResponse('post 请求')

# @method_decorator(csrf_exempt, name='post')
class MySelfCsrfToken(View):
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(MySelfCsrfToken, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return HttpResponse('get 请求')

    # @method_decorator(csrf_exempt)
    def post(self, request):
        return HttpResponse('post 请求')

四. 总结

# django中间件
    # 什么是django中间件: 它是django的大门
        请求来的时候要先过中间件才能到达真正的django后端
        响应走的时候也需要经过中间件才能发送出去

    # django中间件个数: 自带七个
        SecurityMiddleware
        SessionMiddleware
        CommonMiddleware
        CsrfViewMiddleware
        AuthenticationMiddleware
        MessageMiddleware
        XFrameOptionMiddleware

    # django提供了5种自定义中间件方法
        process_request
        process_response
        process_view
        process_template_response
        process_exception

    # 自定义中间件流程
        1. 应用 或 项目 下创建任意文件夹
        2. 在创建的任意文件夹下创建任意的.py文件
        3. 在创建的任意的.py文件中书写类. 该类要继承MiddlewareMixin
        4. 到settings.py配置文件中找到MIDDLEWARE注册

    # 二种掌握自定义: process_request, process_response
        # process_request
            1. 请求来的时候会从上到下依此执行注册了中间件类中的方法. 没有定义就跳过
            2. 如果返回了HttpResponse对象, 请求将不会往下执行, 而是原路返回
                功能: 用来做全局相关的所有限制功能
                应用: 效验用户权限功能

        # process_response
            1. 响应走的时候会从下到上依此执行注册了中间件类中的方法. 没有定义就跳过
            2. 该方法必须返回HttpResponse对象
                2-1. 返回参数response
                2-2. 返回自定义HttpResponse对象

        # 二者综合:
            如果process_request方法返回的是HttpResponse对象. 请求将不会往下继续执行,
            开始按照同级别定义的process_response方法, 按照注册了中间件类中的顺序从下到上依此返回.
            如果在返回的途中的process_response方法没有使用自定义的HttpResponse对象的形式返回, 那么最终返回的结果就按照process_request方法返回的HttpResponse对象为准
            如果在返回的途中的process_response方法自定义的自己的HttpResponse对象,
            那么将会按照当前HttpResponse返回的结果作为标准. 同时如果上一层也定义了,
            就按照上一层的结果返回.

        # 基本使用
            from django.utils.deprecation import MiddlewareMixin

            class MyMiddleware(MiddlewareMixin):
                def process_request(self, request)
                    ...

                def process_response(self, request, response):
                    ...
                    return response

    # 三种了解自定义: process_view, process_template_response, process_exception
        # process_view
            在路由匹配之前视图函数执行之前触发
            执行顺序: 在注册了的中间件类中从上到下
        # process_template_response
            在视图函数返回的HttpResponse对象含有render属性时触发
            执行顺序: 在注册了的中间件类中从下到上
        # process_exception
            在视图函数执行过程中抛出异常时触发
            执行顺序: 在注册了的中间件类中从下到上

# csrf跨站请求伪造
    # csrf 全称 cross site request forgery  跨站请求伪造
    # 什么是CSRF
        就是基于不同的服务端发送出相同的展示页面, 假的页面与真的页面展示给用户看时候一模一样,
        在用户输入敏感信息的时候, 提交的不是用户想提交的内容, 而是隐藏在标签中的内容,
        虽然都是提交到同一个正规服务器, 但是提交的数据内容不是用户指定的了. 而是隐藏的内容.
    # 本质:
        钓鱼网站不提供用户输入的name属性值, 而是提供自己指定的隐藏的写好的name以及对应的value
    # 规避:
        在给用户返回一个具有提交数据的功能页面的时候附加一个唯一标识,
        在用户提交请求过来的时候, 服务端效验这个请求中是否含有对应的唯一标识,
        如果有则正常执行 如果没有则拒绝并返回403 forbbiden
    # 争对form与ajax的符合校验设置来解决CSRF问题
        # 争对form
            在返回的页面书写 {% csrf_token %}
        # 争对ajax: 在data参数中指定
            方式一: data: {'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken].val()')}
            方式二: {'csrfmiddlewaretoken': `{{ csrf_token }}`}
            方式三: 自定义js文件copy代码. 再配置静态文件导入.

    # csrf相关装饰器
        from django.utils.decorators.csrf import csrf_protect, csrf_exempt
        # 争对FBV
            @csrf_protect
            # @csrf_exempt
            def index(request):
                if request.method == 'POST':
                    return HttpResponse('index')
                return render(request, 'index.html')
                    
            
        # 争对CBV
            csrf_protect三种方式都可以
            csrf_exempt只争对dispatch方法有效

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

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

相关文章

Linux宝塔面板搭建Discuz论坛, 并内网穿透实现公网访问

Linux宝塔面板搭建Discuz论坛&#xff0c; 并内网穿透实现公网访问 文章目录 Linux宝塔面板搭建Discuz论坛&#xff0c; 并内网穿透实现公网访问前言1.安装基础环境2.一键部署Discuz3.安装cpolar工具4.配置域名访问Discuz5.固定域名公网地址6.配置Discuz论坛 &#x1f4f7; 江池…

深兰科技“汉境”入选2023年湖北省人工智能十大优秀应用案例

11月18日&#xff0c;央视“专精特新制造强国”城市大会在湖北武汉召开。会上&#xff0c;正式发布了“湖北省工业互联网标识十大优秀应用案例”&#xff0c;由深兰科技(武汉)股份有限公司基于AIGC多模态融合大模型技术开发打造的江汉路步行街元宇宙场景应用——汉境&#xff0…

Python爬虫基础教程之urllib和requests的区别详解

文章目录 前言1、获取网页数据第一步&#xff0c;引入模块。第二步&#xff0c;简单网页发起的请求。第三步&#xff0c;数据封装。 2、解析网页数据3.保存数据关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项…

关于ElectronVue3中集成讯飞星火AI

前言&#xff1a;我的最终目的是为了在QQ上集成一个AI机器人&#xff0c;因此在这里先实现一个简单的集成 先上效果图 总体还是很简单的&#xff0c;我在调用websock获取回复内容的基础上另外集成了一个事件总线&#xff0c;让我们在调用获取消息的时候能够更加方便快捷 工具代…

【SwiftUI】7.预览及其内部机制

上一篇讲到了组件及组件化&#xff0c;从概念和优/缺点两个方向说明了组件化的意义&#xff0c;更为重要的是&#xff0c;组件和组件化是一个在编程领域&#xff0c;放之四海皆可以的概念&#xff0c;理解和运用它是非常必要的&#xff0c;希望大家能掌握。今天我们介绍另一个特…

Spring第一课,了解IDEA里面的文件,回顾Cookie和Session,获取Session,Cookie,Header的方式

目录 IDEA第一课&#xff08;熟悉里面内容&#xff09; 建立连接 -RequestMapping 路由映射 请求 1.传递单个参数​编辑 2.多个参数​编辑 3.传递数组 4.传递一个集合&#xff0c;但是这里我们传递的时候发生了500的错误 简单介绍JSON 回顾Cookie和S…

软文推广中如何提炼好产品卖点,媒介盒子分享

内容同质化的时代下&#xff0c;企业应该如何让用户留下印象&#xff0c;并且成功将产品卖出去&#xff0c;核心思维就在于提炼产品卖点&#xff0c;产品卖点是销量提升的关键&#xff0c;相信企业在推广产品时都会有点困惑&#xff0c;感觉自家产品和竞品比起来只是logo、外观…

【SpringCloud】为什么选择微服务?

一般的平台会遇到的问题&#xff1a; 服务配置复杂。基础服务多&#xff0c;服务的资源配置复杂&#xff0c;传统方式管理服务复杂 服务之间调用复杂。检索服务、用户中心服务等&#xff0c;服务之间的调用复杂&#xff0c;依赖多 服务监控难度大。服务比较多&#xff0c;…

【SpringCloud】什么是微服务?

一、单体架构 单体架构就是把所有业务模块编写在一个项目&#xff0c;最终打包成一个 war 包&#xff0c;进行部署 单体架构的优点&#xff1a; 部署简单&#xff1a;由于是完整的结构体&#xff0c;可以直接部署在一个服务器上即可 技术单一&#xff1a;项目不需要复杂的…

世界这么大,极米投影仪RS Pro 3任意门带你“云旅游”

在繁忙的工作之后&#xff0c;许多小伙伴选择出门旅游&#xff0c;但也有不少人想在家“躺平”。其实&#xff0c;对于当代年轻人来说&#xff0c;行走在钢筋混凝土丛林&#xff0c;在家用智能投影观影娱乐好好放松身心也是不错的选择。有一台投影仪来相伴&#xff0c;能够抚平…

Let’s xrOS 一款让你优先体验社区创作者的 visionOS App工具

Let’s xrOS Apple Vision Pro 发布预示着空间计算时代的到来&#xff0c;让科技爱好者和开发者开始思考如何在新的交互、系统和硬件上打造独特的三维应用。 自 WWDC 2023 的发布会后&#xff0c;社交媒体上涌现了许多精美的 visionOS App 的效果图和演示视频&#xff0c;然而…

Mac安装配置typescript及在VSCode上运行ts

一、Mac上安装typescript sudo npm install -g typescript 测试一下&#xff1a;出现Version则证明安装成功 tsc -v 二、在VSCode上运行 新建一个xxx.ts文件&#xff0c;测试能否运行 console.log("helloworld") 运行报错&#xff1a;ts-node: command not…

【无标题】学习HTML

由于工作需求&#xff0c;学习了一些html的相关知识&#xff0c;最终应用到打印功能上使用。 HTML是指超文本标记语言&#xff08;HyperText Markup Language&#xff09;。它是一种用于创建和呈现互联网上页面的标准标记语言。HTML是Web开发的基础&#xff0c;是构建网页和应…

关于SseEmitter(SSE)在本地可以响应,部署到服务器后无法响应的问题

关于SseEmitter(SSE)在本地可以响应&#xff0c;部署到服务器后无法响应的问题 GetMapping(value "/v3/detail", produces MediaType.TEXT_EVENT_STREAM_VALUE) ResponseBody public SseEmitter v3Detail(String id) {SseEmitter emitter new SseEmitter((long) …

探究Kafka原理-2.Kafka基本命令实操

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44…

【开源】基于JAVA的高校实验室管理系统

项目编号&#xff1a; S 015 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S015&#xff0c;文末获取源码。} 项目编号&#xff1a;S015&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实…

2023年第十六届中国系统架构师大会(SACC2023)-核心PPT资料下载

一、峰会简介 本届大会以“数字转型 架构演进”为主题&#xff0c; 涵盖多个热门领域&#xff0c;如多云多活、海量分布式存储、容器、云成本、AIGC大数据等&#xff0c;同时还关注系统架构在各个行业中的应用&#xff0c;如金融、制造业、互联网、教育等。 与往届相比&#…

StarRocks 算子落盘:让大查询又快又稳

内存是对数据库非常重要的数据存储介质&#xff0c;它承载了所有查询计算的请求&#xff0c;在提升性能、实时分析等场景都有着重要的作用。正是由于内存如此重要&#xff0c;经常会遇到内存不够的情况&#xff0c;从而导致查询被强制终止&#xff0c;甚至对线上其他查询性能产…

UML建模图文详解教程04——对象图

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl本文参考资料&#xff1a;《UML面向对象分析、建模与设计&#xff08;第2版&#xff09;》吕云翔&#xff0c;赵天宇 著 对象图 对象图(object diagram)显示了某一时刻的一组…

OSG动画与声音-动画(3)

动画 动画是一种常见的动画形式(Frame ByFrame)&#xff0c;其原理是在连续的关键帧中分解动画动作&#xff0c;从另一个方面来说&#xff0c;也就是在时间轴的每帧上逐顿绘制不同的内容&#xff0c;使其连续播放而形成动画。 因为帧动画的帧序列内容不一样&#xff0c;不但给制…