pt28django教程

news2024/11/18 1:29:49

缓存

缓存是一类可以更快的读取数据的介质统称,读取硬盘、较复杂的计算、渲染都会产生较大的耗时。数据变化频率不会很高的场景适合使用缓存。使用缓存场景:博客列表页、电商商品详情页、缓存导航及页脚。

Django中设置缓存

Django中提供多种缓存方式,如需使用需要在settings.py中进行配置

初始化配置
[root@vm ~]# mysql -uroot -p123456 -e 'create database mysite7 default charset utf8;'

[root@vm ~]# django-admin startproject mysite7
[root@vm ~]# cd mysite7/
[root@vm mysite7]# vim mysite7/settings.py

ALLOWED_HOSTS = ['*',]

DATABASES = {
    'default' : {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mysite7',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}
LANGUAGE_CODE = 'zh-Hans'

TIME_ZONE = "Asia/Shanghai"

[root@vm mysite7]# python3 manage.py runserver 0.0.0.0:8000
[root@vm mysite7]# python3 manage.py migrate
[root@vm mysite7]# mysql -uroot -p123456 -e 'use mysite7;show tables;'
1、数据库缓存

mysite7 改配置 migrate , 添加缓存配置项 createcachetable

Django可以将其缓存的数据存储在您的数据库中

[root@vm mysite7]# vim mysite7/settings.py
#添加到最后
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'my_cache_table',
        'TIMEOUT': 300,  #缓存保存时间 单位秒,默认值为300, 
        'OPTIONS':{
            'MAX_ENTRIES': 300, #缓存最大数据条数
            'CULL_FREQUENCY': 2,#缓存条数达到最大值时 删除1/2的缓存数据
        }
    }
}

创建缓存表

[root@vm mysite7]# python3 manage.py createcachetable
[root@vm mysite7]# mysql -uroot -p123456 -e 'desc mysite7.my_cache_table;'
+-----------+--------------+------+-----+---------+-------+
| Field     | Type         | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| cache_key | varchar(255) | NO   | PRI | NULL    |       |
| value     | longtext     | NO   |     | NULL    |       |
| expires   | datetime(6)  | NO   | MUL | NULL    |       |
+-----------+--------------+------+-----+---------+-------+
2、文件系统缓存
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': '/var/tmp/django_cache',#这个是文件夹的路径
        #'LOCATION': 'c:\test\cache',#windows下示例
    }
}
3、本地内存缓存
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake'
    }
}

Django中使用缓存

在urls中使用(较少)
from django.views.decorators.cache import cache_page

urlpatterns = [
    path('foo/', cache_page(60)(my_view)  ),
]
在模板中使用(较少)
{% load cache %}        

{% cache 500 sidebar username %}
    .. sidebar for logged in user ..
{% endcache %}
在Views中使用
from django.views.decorators.cache import cache_page

@cache_page(30)  -> 单位s
def my_view(request):
    ...

使用举例

[root@vm mysite7]# vim mysite7/urls.py
from . import views
urlpatterns = [
    path('test_cache/',views.test_cache),
...

[root@vm mysite7]# vim mysite7/views.py
from django.http import HttpResponse
import time

def test_cache(request):
    t = time.time()
    # 经历了复杂计算或复杂查询
    time.sleep(10)
    return HttpResponse("time is %s" % t)
http://192.168.1.11:8000/test_cache/     #访问很慢,network栏,看到用时10s
缓存装饰器

不灵活,不方便修改清理

[root@vm mysite7]# vim mysite7/views.py
from django.http import HttpResponse
import time
from django.views.decorators.cache import cache_page

@cache_page(600)
def test_cache(request):
    ...
http://192.168.1.11:8000/test_cache/     #第一次很慢,后面很快,但是时间没变化
[root@vm net_note]# mysql -uroot -p123456 -e 'select * from mysite7.my_cache_table\G'
缓存api

作用:局部缓存部分结果,

set、get、delete、add 、get_or_set、set_many、get_many、delete_many

#指定配置引入,多个缓存import  caches
from django.core.cache import caches
cache1 = caches['myalias']
cache2 = caches['myalias_2']

#默认配置引入【指的配置中的default项】 等同于 caches['default']
from django.core.cache import cache

#常规命令 set
#key: 字符串类型
#value: Python对象
#timeout:缓存存储时间  默认值为settings.py CACHES对应配置的TIMEOUT
#返回值:None
cache.set('my_key', 'myvalue', 30)

#常规命令 get
#返回值:为key的具体值,如果没有数据,则返回None
cache.get('my_key')
#可添加默认值,如果没取到返回默认值
cache.get('my_key', 'default值')

#常规命令 delete
#返回值  None
cache.delete('my_key')

#常规命令 add 只有在key不存在的时候 才能设置成功
#返回值 True or False
cache.add('my_key', 'value') #如果my_key已经存在,则此次赋值失效

#常规命令 get_or_set 如果未获取到数据 则执行set操作
#返回值 key的值
cache.get_or_set('my_key', 'value', 10)

#常规命令 get_many(key_list) set_many(dict,timeout)
#返回值  set_many:返回插入不成功的key数组 
#       get_many:取到的key和value的字典
>>> cache.set_many({'a': 1, 'b': 2, 'c': 3})
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}

#常规命令 delete_many
#返回值  成功删除的数据条数
cache.delete_many(['a', 'b', 'c'])
[root@vm mysite7]# python3 manage.py shell
>>> from django.core.cache import cache
>>> cahe.set('user','django',600)
>> cache.get('user')
'django'
>>> cache.delete('user')
>>> cache.get('user')

>>> cache.add('user','django',600)
True
>>> cache.add('user','django',600)
False
>>> cache.get('user')
'django'

>>> cache.get_or_set('user2','django',600)
'django'
>>> cache.get_or_set('user2','dj',600)
'django'

浏览器中的缓存

强缓存

不会向服务器发送请求,直接从缓存中读取资源

Expires

缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点
Expires: Thu, 02 Apr 2030 05:14:08 GMT
Expires是 HTTP/1 的产物,受限于本地时间,如果修改了本地时间,可能会造成缓存失效

Cache-Control

在HTTP/1.1中,Cache-Control主要用于控制网页缓存。
比如当Cache-Control:max-age=120  代表请求创建时间后的120秒,缓存失效

一般情况下两个值都会设置,浏览器查看Response Header里的Expires、Cache-Control

协商缓存

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程

Last-Modified和If-Modified-Since
第一次访问时,服务器会返回文件的最近修改时间 Last-Modified: 
浏览器下次请求时 携带If-Modified-Since这个header , 该值为 Last-Modified
服务器接收请求后,对比结果,若资源未发生改变,则返回304,否则返回200并将新资源返回给浏览器

缺点:只能精确到秒,容易发生单秒内多次修改,检测不到

ETag和If-None-Match

​ Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,Etag就会重新生成。流程同上,判断是否match。

对比Last-Modified:Etag精度高、Etag优先级高、性能不如Last-Modifi

中间件 Middleware

中间件是 Django 请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变 Django 的输入或输出。

每个中间件组件负责做一些特定的功能。例如,Django 包含一个中间件组件 AuthenticationMiddleware,它使用会话将用户与请求关联起来。

中间件类:

中间件类须继承自 django.utils.deprecation.MiddlewareMixin

中间件类须实现下列五个方法中的一个或多个:

  • def process_request(self, request): 执行路由之前被调用,在每个请求上调用,返回None或HttpResponse对象
  • def process_view(self, request, callback, callback_args, callback_kwargs): 调用视图之前被调用,在每个请求上调用,返回None或HttpResponse对象
  • def process_response(self, request, response): 所有响应返回浏览器 被调用,在每个请求上调用,返回HttpResponse对象
  • def process_exception(self, request, exception): 当处理过程中抛出异常时调用,返回一个HttpResponse对象
  • def process_template_response(self, request, response): 在视图函数执行完毕且试图返回的对象中包含render方法时被调用;该方法需要返回实现了render方法的响应对象

注: 中间件中的大多数方法在返回None时表示忽略当前操作进入下一项事件,当返回HttpResponese对象时表示此请求结束,直接返回给客户端

编写中间件类:
[root@vm mysite7]# mkdir middleware
[root@vm mysite7]# vim middleware/mymiddleware.py

from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin

class MyMiddleWare(MiddlewareMixin):
    def process_request(self, request):
        print("中间件方法 process_request 被调用")

    def process_view(self, request, callback, callback_args, callback_kwargs):
        print("中间件方法 process_view 被调用")

    def process_response(self, request, response):
        print("中间件方法 process_response 被调用")
        return response
注册中间件:
[root@vm mysite7]# vim mysite7/settings.py
...
MIDDLEWARE = [
    ...
    'middleware.mymiddleware.MyMiddleWare',
       ]
使用测试验证
[root@vm mysite7]# vim mysite7/urls.py
urlpatterns = [
...
    path('test_mw', views.test_mw),
    path('test_mw2', views.test_mw2),
    
[root@vm mysite7]# vim mysite7/views.py
...    
def test_mw(request):
    print('---view in test_mw---')
    return HttpResponse("test mw is OK!")


def test_mw2(request):
    print('---view in test_mw2---')
    return HttpResponse('test mw2 is OK!')    
访问http://192.168.1.11:8000/test_mw    test mw is OK!
终端日志:
    中间件方法 process_request 被调用
    中间件方法 process_view 被调用
    ---view in test_mw---
    中间件方法 process_response 被调用
访问http://192.168.1.11:8000/test_mw2  也会有日志显示,影响全局 
中间件执行的顺序

重新复制一套MyMiddleWare2 访问,执行顺序如下,进和出方向正好相反(洋葱图了解)

访问http://192.168.1.11:8000/test_mw 
    中间件方法 process_request 被调用
    中间件方法2 process_request 被调用
    中间件方法 process_view 被调用
    中间件方法2 process_view 被调用
    ---view in test_mw---
    中间件方法2 process_response 被调用
    中间件方法 process_response 被调用

在这里插入图片描述

练习

用中间件实现强制某个IP地址只能向/test 发送 5 次GET请求
    提示:
      - request.META['REMOTE_ADDR'] 可以得到远程客户端的IP地址
      - request.path_info 可以得到客户端访问的GET请求路由信息
      - 在进url之前统计次数,做出处理
[root@vm mysite7]# vim middleware/mymiddleware.py
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
import re

class MyMW(MiddlewareMixin):
    # 统计每一个客户端IP以及对应的访问次数
    visit_times = {}

    def process_request(self, request):
        # 1. 只对/test开头的路由做5次访问的限制
        if not re.match(r'^/test', request.path_info):
            return
        # 2. 获取客户端的IP地址
        cip = request.META['REMOTE_ADDR']
        # 3. 获取访问次数,回去cip的次数,默认是0次
        times = self.visit_times.get(cip, 0)
        # 4. 判断是否超过5次
        if times >= 5:
            return HttpResponse("no way!")
        # 5.每访问一次,次数+1
        self.visit_times[cip] = times + 1
        print('%s visit we %s times' % (cip,
                                        self.visit_times[cip]))
                                        
[root@vm mysite7]# vim mysite7/settings.py
    'middleware.mymiddleware.MyMW',                                   

访问测试,看日志输出 192.168.1.1 visit we 1 times 5次后看浏览器返回no way

跨站请求伪造攻击 CSRF

跨站请求伪造攻击

某些恶意网站上包含链接、表单按钮或者JavaScript,它们会利用登录过的用户在浏览器中的认证信息(cookie)试图在你的网站上完成某些操作,这就是跨站请求伪造(CSRF,即Cross-Site Request Forgey)。

说明: CSRF中间件和模板标签提供对跨站请求伪造简单易用的防护。

作用: 不让其它表单提交到此 Django 服务器

防范步骤:

打开MIDDLEWARE

打开MIDDLEWARE中django.middleware.csrf.CsrfViewMiddleware,默认打开

添加csrf_token

模板中,form标签下添加如下标签

    <form action=....>
        {% csrf_token %}
        ...
    </form>

关闭个别试图csrf

如果某个视图不需要django进行csrf保护,可以用装饰器关闭对此视图的检查

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
    return HttpResponse('Hello world')

使用测试

[root@vm mysite7]# vim mysite7/urls.py
    path('test_csrf', views.test_csrf),

[root@vm mysite7]# vim mysite7/views.py
from django.http import HttpResponse
from django.shortcuts import render

def test_csrf(request):
    if request.method == 'GET':
        return render(request, "test_csrf.html")
    elif request.method == 'POST':
        name = request.POST['name']
        return HttpResponse("欢迎您,%s" % name)
 
[root@vm mysite7]# vim mysite7/settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,'templates')],
         
[root@vm mysite7]# mkdir -p templates
[root@vm mysite7]# vim templates/test_csrf.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CSRF</title>
</head>
<body>
    <form action="/test_csrf" method="post">
        <p>
            名称:<input type="text" name="name">
        </p>
        <input type="submit" value="提交">
    </form>
</body>
</html>
#访问  http://192.168.1.11:8000/test_csrf   输入名称,提交,
# 报CSRF验证失败. 请求被中断. 看下面的help里的 {% csrf_token %} template tag
#写到form表单里
    <form action="/test_csrf" method="post">
        {% csrf_token %}
        <p>
            名称:<input type="text" name="name">
        </p>
        <input type="submit" value="提交">
    </form>
    
#再次访问查看网页源代码,多出一个csrf的token
<input type="hidden" name="csrfmiddlewaretoken" value="oqLeUQSpIy...>
     点击"提交"按钮,中间件的方法先于视图函数被调用,在中间方法中
     验证,先前给你的csrfmiddlewaretoken,验证存在并正确
     放行,调用视图函数完成相应的功能。

web分页功能

分页是指在web页面有大量数据需要显示,为了阅读方便在每个页页中只显示部分数据。

好处: 方便阅读;减少数据提取量,减轻服务器压力。

Django通过使用Paginator和Page这两个类来完成的分页

Paginator对象

负责分页数据整体的管理,位于django.core.paginator 模块中。

对象的构造方法paginator = Paginator(object_list, per_page)
参数
    object_list 需要分类数据的对象列表
     per_page 每页数据个数
返回值: Paginator的对象

Paginator属性
  - count:需要分类数据的对象总数
  - num_pages:分页后的页面总数
  - page_range:从1开始的range对象, 用于记录当前面码数
  - per_page 每页数据的个数

Paginator方法
  - page(number)
    - 参数 number为页码信息(从1开始)
    - 返回当前number页对应的页信息
    - 如果提供的页码不存在,抛出InvalidPage异常

Paginator异常exception
  - InvalidPage:总的异常基类,包含以下两个异常子类
    - PageNotAnInteger:当向page()传入一个不是整数的值时抛出
    - EmptyPage:当向page()提供一个有效值,但是那个页面上没有任何对象时抛出

Page对象

负责具体某一页的数据的管理,Paginator对象的page()方法返回Page对象

创建对象   page = paginator.page(页码)

Page对象属性
    - object_list:当前页上所有数据对象的列表
    - number:当前页的序号,从1开始
    - paginator:当前page对象相关的Paginator对象

Page对象方法
    - has_next():如果有下一页返回True
    - has_previous():如果有上一页返回True
    - has_other_pages():如果有上一页或下一页返回True
    - next_page_number():返回下一页的页码,如果下一页不存在,抛出InvalidPage异常
    - previous_page_number():返回上一页的页码,如果上一页不存在,抛出InvalidPage异常
    - len():返回当前页面对象的个数
    
说明:  Page 对象是可迭代对象,可以用 for 语句来 访问当前页面中的每个对象
参考文档 <https://docs.djangoproject.com/en/2.2/topics/pagination/>

分页示例:

视图函数

from django.core.paginator import Paginator
def book(request):  
    # 1. 准备要分页的数据
    bks = Book.objects.all()
    # 2. 创建分页器    
    paginator = Paginator(bks, 10)
    # 3. 获取当前页码
    cur_page = request.GET.get('page', 1)
    # 4. 根据页码获取页面对象
    page = paginator.page(cur_page)
    # 5. 返回响应
    return render(request, 'bookstore/book.html', locals())

模板设计

<html>
<head>
    <title>分页显示</title>
</head>
<body>
{% for b in page %}
    <div>{{ b.title }}</div>
{% endfor %}

{% if page.has_previous %}
<a href="{% url 'book' %}?page={{ page.previous_page_number }}">上一页</a>
{% else %}
上一页
{% endif %}

{% for p in paginator.page_range %}
    {% if p == page.number %}
        {{ p }}
    {% else %}
        <a href="{% url 'book' %}?page={{ p }}">{{ p }}</a>
    {% endif %}
{% endfor %}

{% if page.has_next %}
<a href="{% url 'book' %}?page={{ page.next_page_number }}">下一页</a>
{% else %}
下一页
{% endif %}
</body>
</html>

使用示例

[root@vm mysite7]# vim mysite7/urls.py
    path('test_page', views.test_page,
         name='book'),

[root@vm mysite7]# vim mysite7/views.py
...
from django.core.paginator import Paginator
def test_page(request):
    # 1. 准备要分页的数据
    list_data = ['a', 'b', 'c', 'd', 'e']
    # 2. 创建分页器
    paginator = Paginator(list_data, 2)
    # 3. 获取当前页码
    cur_page = request.GET.get('page', 1)
    # 4. 根据页码获取页面对象
    page = paginator.page(cur_page)
    # 5. 返回响应
    return render(request, "test_page.html",
                  locals())
                  
[root@vm mysite7]# vim templates/test_page.html
<html>
<head>
    <title>分页显示</title>
</head>
<body>
{% for b in page %}
    <div>{{ b }}</div>
{% endfor %}

{% if page.has_previous %}
<a href="{% url 'book' %}?page={{ page.previous_page_number }}">上一页</a>
{% else %}
上一页
{% endif %}

{% for p in paginator.page_range %}
    {% if p == page.number %}
        {{ p }}
    {% else %}
        <a href="{% url 'book' %}?page={{ p }}">{{ p }}</a>
    {% endif %}
{% endfor %}

{% if page.has_next %}
<a href="{% url 'book' %}?page={{ page.next_page_number }}">下一页</a>
{% else %}
下一页
{% endif %}
</body>
</html>     

#访问验证http://192.168.1.11:8000/test_page

csv文件下载

Django可直接在视图函数中生成csv文件 并响应给浏览器

import csv
from django.http import HttpResponse
from .models import Book

def make_csv_view(request):
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="mybook.csv"'
	all_book = Book.objects.all()
    writer = csv.writer(response)
    writer.writerow(['id', 'title'])
    for b in all_book:    
    	writer.writerow([b.id, b.title])

    return response
  • 响应获得一个特殊的MIME类型text / csv。这告诉浏览器该文档是CSV文件,而不是HTML文件
  • 响应会获得一个额外的Content-Disposition标头,其中包含CSV文件的名称。它将被浏览器用于“另存为…”对话框
  • 对于CSV文件中的每一行,调用writer.writerow,传递一个可迭代对象,如列表或元组。
[root@vm mysite7]# vim mysite7/urls.py
    path('test_csv', views.test_csv),
[root@vm mysite7]# vim mysite7/views.py
import csv
from django.http import HttpResponse
from .models import Book

def test_csv(request):
    # 1. 创建响应对象时,指定响应的内容的类型是csv
    response = HttpResponse(content_type='text/csv')
    # 2. 告诉浏览器以附件的方式处理响应数据,文件名为mybook.csv
    response['Content-Disposition'] = 'attachment; filename="mybook.csv"'
    # 3. 获取数据
    # all_book = Book.objects.all()
    all_book = [
        {'id': 1, 'title': 'java'},
        {'id': 2, 'title': 'python'},
        {'id': 3, 'title': 'php'},
    ]
    # 4. 创建一个csv格式的写入器,将数据写入到response
    writer = csv.writer(response)
    # 5. 调用写入器的方式writerow,写入一行数据,标题
    writer.writerow(['编号', '图书名称'])
    # 6. 写入数据
    for b in all_book:
        writer.writerow([b['id'], b['title']])
    return response


#访问  http://192.168.1.11:8000/test_csv     产生下载

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

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

相关文章

解决 MyBatis-Plus 中增加修改时,对应时间的更新问题

问题&#xff1a;在添加修改时&#xff0c;对应的 create_time 与 insert_time 不会随着添加修改而自动的更新时间 第一步&#xff1a;首先在对应的属性上&#xff0c;加上以下注解 如果只添加以下注解&#xff0c;在增加或者修改时&#xff0c;可能对应的 LocalDateTime 会出…

大学生登记国家证书软件著作权提升就业资质

大学生登记国家证书软件著作权提升就业资质 随着信息技术的快速发展&#xff0c;软件行业成为了许多大学生就业的热门选择之一。然而&#xff0c;在竞争激烈的就业市场中&#xff0c;除了掌握专业知识和技能外&#xff0c;如何提升自己的就业资质也显得尤为重要。其中&#xff…

【数据结构】冒泡排序,快速排序的学习知识总结

目录 1、冒泡排序 1.1 算法思想 1.2 代码实现 方式一&#xff1a;顺序表 方式二&#xff1a;链表 2、快速排序 2.1 算法思想 2.2 代码实现 2.3 例题分析 1、冒泡排序 1.1 算法思想 冒泡排序是一种简单的排序算法&#xff0c;它的基本思想是从数组的第一个元素开始…

2009 款沃尔沃 S80L 车换挡顿挫

故障现象 一辆2009款沃尔沃S80L车&#xff0c;搭载2.5T发动机和6速自动变速器&#xff0c;累计行驶里程约为30万km。车主反映&#xff0c;换入D挡或R挡时车辆会顿挫。 故障诊断 接车后试车&#xff0c;起动着机后仪表无故障灯点亮&#xff0c;踩住制动踏板&#xff0c;换入D挡或…

LetCode算法题---第2天

注:大佬解答来自LetCode官方题解 80.删除有序数组的重复项Ⅱ 1.题目 2.个人解答 var removeDuplicates function (nums) {let res [];for (let index 0; index < nums.length; index) {let num 0;if (res.includes(nums[index])) {for (let i 0; i < res.length; …

软考高级之系统架构师之软件需求工程

概述 一个完整的软件生存周期是以需求为出发点。软件需求是指用户对系统在功能、行为、性能、设计约束等方面的期望。 需求开发&#xff1a; 需求获取需求分析需求定义&#xff08;需求规格说明书&#xff09;需求验证 需求管理: 变更控制版本控制需求跟踪需求状态跟踪 需…

MATLAB 多信号显示方案

效果示例 重要参考资料 MATLAB官方资料 matlab plot3 函数说明 利用for循环和plot函数画多条曲线时如何添加图例&#xff1f; x1:100; krandperm(20)‘; A{‘aa’,‘bb’,‘ccc’,‘ddd’}; y(k*x)’ for i1:20 plot(x,y(:,i)) STRsprintf(‘曲线%d’,i); A(i)cellstr(STR); …

腾讯云 Cloud Studio 实战训练营结营活动获奖公示

点击链接了解详情 “腾讯云 Cloud Studio 实战训练营” 是由腾讯云联合 CSDN 推出的系列开发者技术实践活动&#xff0c;通过技术分享直播、动手实验项目、优秀代码评选、有奖征文活动等&#xff0c;让广大开发者沉浸式体验腾讯云开发者工具 Cloud Studio 的同时&#xff0c;实…

Docker——容器生命周期管理(下篇)

Docker 一、run1、options说明2、-p的三种写法3、实例14、实例25、实例36、实例47、实例58、实例69、实例78、实例89、退出容器 二、start/stop/restart1、语法格式2、stop/restart 命令的 options 三、kill1、重点2、说明3、实例 四、rm1、说明2、实例 五、create实例 六、exe…

【Qt】QTabWidget如何添加控件到Tab页水平位置

在开发中&#xff0c;QTabWidget控件经常出现在项目或软件中&#xff0c;有时为了美观兼顾操作便利&#xff0c;需要把按钮或其他控件添加到QTabWidget控件的Tab页水平位置。 实现思路&#xff1a; 查看帮助文档&#xff0c;发现该类有个方法void setCornerWidget()可以实现所…

Java笔记四(方法与递归)

方法 Java的方法类似于C语言的函数&#xff0c;是一段用来完成特定功能的代码片段&#xff0c;一般情况下&#xff0c;定义一个方法包含以下语法&#xff1a; 方法包含一个方法头和一个方法体&#xff0c;下面是一个方法的所有部分&#xff1a; ◆修饰符:修饰符,这是可选的&…

FPGA设计时序约束二、输入延时与输出延时

目录 一、背景 二、set_input_delay 2.1 set_input_delay含义 2.2 set_input_delay参数说明 2.3 使用样例 三、set_output_delay 3.1 set_output_delay含义 3.2 set_output_delay参数说明 3.3 使用样例 四、样例工程 4.1 工程代码 4.2 时序报告 五、参考资料 一、…

风光储一体化能源中心 | 图扑数字孪生

自“双碳”目标提出以来&#xff0c;我国能源产业不断朝着清洁低碳化、绿色化的方向发展。其中&#xff0c;风能、太阳能等可再生能源在促进全球能源可持续发展、共建清洁美丽世界中被寄予厚望。风能、太阳能具有波动性、间歇性、随机性等特点&#xff0c;主要通过转化为电能再…

如何在几分钟内创建一个对话机器人?

随着互联网的发展&#xff0c;人们迫切希望以快速高效的方式获取信息和解决问题&#xff0c;传统的人工客服渐渐地已经无法满足人们的需求。然而&#xff0c;对话机器人&#xff08;chatbot&#xff09;的出现可以很好地解决这个痛点。 对话机器人是一种人工智能工具&#xff…

[代码随想录]基本数据结构篇

文章目录 1.数组篇1.1 704-二分查找1.2 27-移除数组1.3 977-有序数组的平方1.4* 209--长度最小的子数组(滑动窗口)1.5* 59-螺旋矩阵II 2. 链表篇2.1 203-移除链表元素2.2 707-设计链表2.3 206-反转链表2.4* 24-两两交换链表中的节点(跳针)2.5* 19-删除链表的倒数第N个节点(快慢…

[Realtek sdk-3.4.14b]RTL8197FH-VG 2.4G to WAN吞吐量低于60%的问题分析及解决方案

问题描述 RTL8197FH-VG 2.4G wifi to WAN吞吐量低于65%的标准,正常2T2R的wifi 300Mbps x 65% = 195Mbps,但是实际只能跑到160Mbps,这个时候CPU的idl已经为0,sirq占用率达到98%左右 网络拓扑 一台PC通过2.4G WiFi连接到RTL8197FH-VG,另外一台PC直接通过WAN口连接到RTL8197…

求各区域热门商品Top3 - HiveSQL

背景&#xff1a;这是尚硅谷SparkSQL练习题&#xff0c;本文用HiveSQL进行了实现。 数据集&#xff1a;用户点击表&#xff0c;商品表&#xff0c;城市表 题目: ① 求每个地区点击量前三的商品&#xff1b; ② 在①的基础上&#xff0c;求出每个地区点击量前三的商品后&a…

SkyWalking搭配springboot应用(三)

title: “SkyWalking搭配springboot应用(三)” createTime: 2021-07-13T16:27:5708:00 updateTime: 2021-07-13T16:27:5708:00 slug: “SkyWalking搭配springboot应用(三)” draft: false author: “ggball” tags: [“skywalking”] categories: [“java”] description: “sk…

重新认识mysql

title: “重新认识mysql” createTime: 2022-03-06T15:52:4108:00 updateTime: 2022-03-06T15:52:4108:00 draft: false author: “ggball” tags: [“mysql”] categories: [“db”] description: “” 文章目录 title: "重新认识mysql" createTime: 2022-03-06T15:…

路由器配置静态和默认路由实现VLAN之间的通信

目录 华为路由器静态路由和默认路由的写法 静态路由和默认路由的区别 案例 华为路由器静态路由和默认路由的写法 配置静态路由&#xff1a; [Huawei] ip route-static <目标网络> <子网掩码> <下一跳地址> 实例&#xff1a;将目标网络192.168.10.0/24的流…