Django中间件与csrf

一. 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方法有效

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WordPress站点屏蔽过滤垃圾评论教程(Akismet反垃圾评论插件)

前段时间我的WordPress站点经常收到垃圾评论的轰炸&#xff0c;严重时一天会收到几十条垃圾评论。我这个小破站一没啥流量&#xff0c;二又不盈利&#xff0c;实在是不太理解为啥有人要这么执着地浪费资源在上面。 Akismet反垃圾评论插件 其实用了 Akismet 反垃圾评论插件后&a…

Python BDD 框架比较之 pytest-bdd vs behave

pytest-bdd和behave是 Python 的两个流行的 BDD 测试框架&#xff0c;两者都可以用来编写用户故事和可执行的测试用例&#xff0c; 具体选择哪一个则需要根据实际的项目状况来看。 先简单看一下两者的功能&#xff1a; pytest-bdd 基于pytest测试框架&#xff0c;可以与pytest…

PCIE链路训练-状态机描述2

Configuration.Lanenum.Accept 如果use_modified_TS1_TS2_Ordered_Set为1&#xff0c;需要注意&#xff1a; &#xff08;1&#xff09;tx需要发送Modified TS1而不是正常的TS1&#xff1b; &#xff08;2&#xff09;rx端必须检查是否收到Modified TS1&#xff08;注意一开…

STM32_6(TIM)

TIM定时器&#xff08;第一部分&#xff09; TIM&#xff08;Timer&#xff09;定时器定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断16位计数器、预分频器、自动重装寄存器的时基单元&#xff0c;在72MHz计数时钟下可以实现最大59.65s的定时不仅…

测试Bard和ChatGPT对双休有关法规的认知和简单推理

Bard是试验品&#xff0c;chatgpt是3.5版的。 首先带着问题&#xff0c;借助网络搜索&#xff0c;从政府官方网站等权威网站进行确认&#xff0c;已知正确答案的情况下&#xff0c;再来印证两个大语言模型的优劣。 想要了解的问题是&#xff0c;在中国&#xff0c;跟法定工作…

通过Whisper模型将YouTube播放列表中的视频转换成高质量文字稿的项目

项目简介 一个通过Whisper模型将YouTube播放列表中的视频转换成高质量文字稿的项目。 这个基于 Python 的工具旨在将 YouTube 视频和播放列表转录为文本。它集成了多种技术&#xff0c;例如用于转录的 Fast-Whisper、用于自然语言处理的 SpaCy 以及用于 GPU 加速的 CUDA&…

使用Pytorch从零开始构建LSTM

长短期记忆&#xff08;LSTM&#xff09;网络已被广泛用于解决各种顺序任务。让我们了解这些网络如何工作以及如何实施它们。 就像我们一样&#xff0c;循环神经网络&#xff08;RNN&#xff09;也可能很健忘。这种与短期记忆的斗争导致 RNN 在大多数任务中失去有效性。不过&a…

解决mv3版本浏览器插件,不能注入js脚本问题

文章目录 背景引入ifream解决ifream和父页面完全跨域问题参考链接 背景 浏览器插件升级mv3版本后&#xff0c;不能再使用content_script内容脚本向原浏览器&#xff08;top&#xff09;注入script标签达到注入脚本的目的。浏览器认为插入未经审核的脚本是不安全的行为。 引入…

经常喝羊奶,羊大师告诉你会有何不同

经常喝羊奶&#xff0c;羊大师告诉你会有何不同 羊奶&#xff0c;与人们日常饮用的牛奶相比&#xff0c;一直都没有得到足够的关注。然而&#xff0c;羊奶在一些特定方面却具有独特的优势。它不仅具有丰富的营养价值&#xff0c;还有助于提升人体的健康水平。本文小编羊大师将…

【Skynet 入门实战练习】游戏模块划分 | 基础功能模块 | timer 定时器模块 | logger 日志服务模块

文章目录 游戏模块基础功能模块定时器模块日志模块通用模块 游戏模块 游戏从逻辑方面可以分为下面几个模块&#xff1a; 注册和登录网络协议数据库玩法逻辑其他通用模块 除了逻辑划分&#xff0c;还有几个重要的工具类模块&#xff1a; Excel 配置导表工具GM 指令测试机器人…

【CCF-PTA】第03届Scratch第01题 -- 梦醒时分

梦醒时分 【题目描述】 睡眠是人体正常的生理需要&#xff0c;同年龄男女睡眠时间无明显差别&#xff0c;一般是8小时左右。居家的小明作息生活很规律&#xff0c;晚上11点睡觉&#xff0c;早晨7点起床学习。请你编写程序来判断&#xff0c;每周&#xff08;共168小时&#x…

Elasticsearch:ES|QL 函数及操作符

如果你对 ES|QL 还不是很熟悉的话&#xff0c;请阅读之前的文章 “Elasticsearch&#xff1a;ES|QL 查询语言简介​​​​​​​”。ES|QL 提供了一整套用于处理数据的函数和运算符。 功能分为以下几类&#xff1a; 目录 ES|QL 聚合函数 AVG COUNT COUNT_DISTINCT 计数为近…

【计算机网络笔记】数据链路层概述

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

IAR为恩智浦S32M2提供全面支持,提升电机控制能力

IAR Embedded Workbench for Arm已全面支持恩智浦最新的S32系列&#xff0c;可加速软件定义汽车的车身和舒适性应用的开发 瑞典乌普萨拉&#xff0c;2023年11月22日 – 嵌入式开发软件和服务的全球领导者IAR现已全面支持恩智浦半导体&#xff08;NXP Semiconductors&#xff0…

好工具|datamap,一个好用的地图可视化Excel插件,在Excel中实现地理编码、拾取坐标

在做VRP相关研究的时候&#xff0c;需要对地图数据做很多处理&#xff0c;比如地理编码&#xff0c;根据“重庆市沙坪坝区沙正街174号”这样的一个文本地址知道他的经纬度&#xff1b;再比如绘制一些散点图&#xff0c;根据某个位置的经纬度在地图上把它标注出来。还有有的时候…

Redis-Redis高可用集群之水平扩展

Redis3.0以后的版本虽然有了集群功能&#xff0c;提供了比之前版本的哨兵模式更高的性能与可用性&#xff0c;但是集群的水平扩展却比较麻烦&#xff0c;今天就来带大家看看redis高可用集群如何做水平扩展&#xff0c;原始集群(见下图)由6个节点组成&#xff0c;6个节点分布在三…

一致性 Hash 算法 Hash 环发生偏移怎么解决

本篇是对文章《一文彻底读懂一致性哈希算法》的重写&#xff0c;图文并茂&#xff0c;篇幅较长&#xff0c;欢迎阅读完提供宝贵的建议&#xff0c;一起提升文章质量。如果感觉不错不要忘记点赞、关注、转发哦。原文链接&#xff1a; 《一文彻底读懂一致性Hash 算法》 通过阅读本…

界面组件Telerik UI for WinForms中文教程 - 创建明暗模式的桌面应用

黑暗模式现在在很多应用程序中都挺常见的&#xff0c;但如何在桌面应用程序中实现它呢&#xff1f;这很简单&#xff0c;本文将为大家介绍如何使用一个类和命令行调用来实现&#xff01; Telerik UI for WinForms拥有适用Windows Forms的110多个令人惊叹的UI控件。所有的UI fo…

绝地求生:PGC 2023 赛事直播期间最高可获:2000万G-Coins,你还不来吗?

今年PGC直播期间将有最高2000万G-Coin掉落&#xff0c;究竟花落谁家咱们拭目以待 公告原文&#xff1a;Watch PGC 2023 Live And Earn G-Coins! 如何赚取高额G-Coin&#xff1f; Throughout the PGC 2023, an astounding 20,000,000 G-Coins will be up for grabs as part of …

关于「光学神经网络」的一切:理论、应用与发展

/目录/ 一、线性运算的光学实现 1.1. 光学矩阵乘法器 1.2. 光的衍射实现线性运行 1.3. 基于Rayleigh-Sommerfeld方程的实现方法 1.4. 基于傅立叶变换的实现 1.5. 通过光干涉实现线性操作 1.6. 光的散射实现线性运行 1.7. 波分复用&#xff08;WDM&#xff09;实现线性运…