Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wp-pagenavi domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /var/www/blog.zhujinhui.net/wp-includes/functions.php on line 6114

Notice: 函数 _load_textdomain_just_in_time 的调用方法不正确twentyseventeen 域的翻译加载触发过早。这通常表示插件或主题中的某些代码运行过早。翻译应在 init 操作或之后加载。 请查阅调试 WordPress来获取更多信息。 (这个消息是在 6.7.0 版本添加的。) in /var/www/blog.zhujinhui.net/wp-includes/functions.php on line 6114
面试 – 第 2 页 – 煅魂-JeffreyChu的修炼屋

Python面试官问:浅拷贝与深拷贝有何区别与应用?

在 Python 中,浅拷贝和深拷贝是两种复制对象的方法,它们在处理复杂数据结构(如列表、字典、对象等)时的行为不同。让我们来详细了解这两者的区别以及它们的应用场景。

概念与区别

浅拷贝(Shallow Copy)

概念:浅拷贝创建一个新对象,但不递归复制原对象内的子对象。相反,新对象中包含的子对象是对原对象中子对象的引用。因此,原对象和新对象共享相同的子对象。
使用:在 Python 中,使用 copy 模块中的 copy 函数进行浅拷贝:

import copy
original_list = [[1, 2, 3], [4, 5, 6]]
shallow_copy = copy.copy(original_list)

行为:浅拷贝后的对象是独立的对象,但子对象仍然是原对象中的相同引用。这意味着对新对象中的子对象的修改会影响原对象中的相同子对象。
应用场景:在你希望复制对象,但仍然保持对子对象的引用的情况下,可以使用浅拷贝。这在一些需要共享子对象的情况下可能是有用的。

深拷贝(Deep Copy)

概念:深拷贝创建一个新对象,并递归复制原对象中的所有子对象。因此,新对象与原对象完全独立,任何一方的修改都不会影响另一方。
使用:在 Python 中,使用 copy 模块中的 deepcopy 函数进行深拷贝:

import copy
original_list = [[1, 2, 3], [4, 5, 6]]
deep_copy = copy.deepcopy(original_list)

行为:深拷贝后的对象与原对象完全独立。你可以在新对象中自由修改子对象,而不会影响原对象中的子对象。
应用场景:在你希望创建一个完全独立的对象,而不共享任何子对象的引用的情况下,可以使用深拷贝。这在你希望确保对原对象的独立性和完整性时非常有用。
总结
区别:浅拷贝只复制对象本身,而不复制其内部的子对象。深拷贝递归复制对象及其内部的所有子对象。
应用场景:根据你的需求选择使用浅拷贝或深拷贝。如果你希望对象之间共享子对象的引用,可以使用浅拷贝;如果你希望对象完全独立,可以使用深拷贝。
例如:

import copy

# 示例数据
original_list = [[1, 2, 3], [4, 5, 6]]

# 浅拷贝
shallow_copy = copy.copy(original_list)

# 深拷贝
deep_copy = copy.deepcopy(original_list)

# 修改原列表中的子列表
original_list[0].append(99)

print("原列表:", original_list)
print("浅拷贝:", shallow_copy)  # 浅拷贝中的子列表也受影响
print("深拷贝:", deep_copy)  # 深拷贝中的子列表不受影响

在这个例子中,你可以看到对原列表中的子列表的修改会影响浅拷贝,但不会影响深拷贝。

应用场景

浅拷贝

浅拷贝在实际应用中非常有用,特别是在需要复制对象,但不需要完全独立的对象副本时。下面是一个用常见的学校班级换了数学老师的例子来展示浅拷贝,展示如何在管理对象引用、共享数据结构以及避免不必要的深拷贝时使用浅拷贝。

import copy

math_teacher = {"name": "AAA"}
# 学生模板
student_a = {
    "name": "student_a",
    "math_teacher": math_teacher
}

student_b = copy.copy(student_a)
# 浅拷贝出来的对象修改name属性是不会影响class1_student原对象的
student_b["name"] = "student_b"

print("换老师前", student_a, student_b)
# 学生b知道学校更换老师,学生a也会知道
student_b["math_teacher"]["name"] = "BBB"
print("换老师后", student_a, student_b)

# Outputs
# 换老师前 {'name': 'student_a', 'math_teacher': {'name': 'AAA'}} {'name': 'student_b', 'math_teacher': {'name': 'AAA'}}
# 换老师后 {'name': 'student_a', 'math_teacher': {'name': 'BBB'}} {'name': 'student_b', 'math_teacher': {'name': 'BBB'}}

这里可以看到浅拷贝出来的新对象(student_b),将子对象(math_teacher)老师的名字(name)改成“BBB”后,原对象(student_a)的老师名字也从“AAA”变成了“BBB”,说明了对新对象中的子对象的修改会影响原对象中的相同子对象。这里的不用深拷贝的原因,他们的老师是共享对象,改一个地方就可以了,否则每个深拷贝出来的对象都需要重新把子对象老师的名字给重新赋值一遍,增加操作复杂度。

深拷贝在 Python 中也有许多实际应用场景,特别是在需要复制复杂数据结构而不希望子对象之间共享引用的情况下。深拷贝通过递归复制对象及其子对象,确保原对象和副本之间完全独立。

比如某些全局配置是独一份的且不能随意修改的,如果浅拷贝后然后要将数据结构传递给不同的函数或模块使用,可能会产生一些意想不到副作用(可能会被函数/模块修改了影响全局);又或者是在一些数据结构需要备份的时候也会考虑深拷贝。

总结

浅拷贝和深拷贝是python面试中最常问到的问题,也是可变对象和不可变对象概念的延伸。

  • 对于不可变对象(如Python中的int、float、str、tuple等),深拷贝和浅拷贝的结果是相同的,因为这些对象本质上是不可改变的,并且在浅拷贝时并不会引用其他对象。
  • 对于可变对象(如Python中的list、dict、set等),浅拷贝和深拷贝的行为有很大不同。浅拷贝会导致共享引用,而深拷贝会创建完全独立的副本。

python后端面试:用chatgpt复习-web安全篇

CSRF网络安全攻击

CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种网络安全攻击,它允许攻击者冒充受害者对受信任的网站或应用程序发起请求。这种攻击通常发生在用户登录了一个受信任的网站(如银行网站)后,然后被诱导访问一个恶意网站。恶意网站中的脚本可以利用用户在受信任网站上的身份和权限发起请求,从而执行未授权的操作。

CSRF 攻击的过程

  1. 受害者登录受信任的网站:受害者登录一个受信任的网站,如银行、社交媒体或电子邮件账户,并在会话期间保持登录状态。
  2. 受害者访问恶意网站:受害者在登录状态下被诱导访问一个恶意网站,该网站包含恶意脚本。
  3. 恶意网站发起请求:恶意网站中的脚本会使用受害者的身份向受信任的网站发起请求。这些请求可能包含操作数据或提交表单的行为,例如转账、修改账户信息等。
  4. 受信任的网站执行请求:受信任的网站接收到请求并将其视为受害者所发送,因为请求携带了有效的身份验证凭证(如 cookie)。
  5. 受害者不知情:受害者可能完全不知道自己在恶意网站上触发了操作,因为恶意网站不会显示任何明显的迹象。

防止 CSRF 攻击的策略

为了防止 CSRF 攻击,可以采取以下措施:

  • CSRF 令牌:为每个请求生成一个唯一的 CSRF 令牌,并在服务器端验证令牌的有效性。这确保了请求是由受信任的用户发起的。
  • Cookie 属性:为身份验证 cookie 设置 HttpOnlySecure 属性,以防止客户端脚本访问 cookie,并确保 cookie 仅通过 HTTPS 传输。
  • 请求头检查:验证请求头中的 RefererOrigin 以确保请求来自受信任的来源。
  • 限制请求方法:对于更改数据的请求(如 POST、PUT、DELETE 等),可以使用 RESTful API 设计来限制请求方法的使用。
  • 内容安全策略(CSP):设置内容安全策略来限制哪些来源的脚本可以在网页上执行。

通过采用这些措施,可以有效地防止 CSRF 攻击,确保应用程序的安全性。

flask怎么防止csrf攻击

在 Flask 应用程序中,您可以通过使用 CSRF(跨站请求伪造)保护机制来防止 CSRF 攻击。Flask 提供了一个扩展库 Flask-WTF,可以轻松添加 CSRF 保护。以下是如何在 Flask 应用程序中防止 CSRF 攻击的详细步骤:

1. 安装 Flask-WTF

首先,确保您已经安装了 Flask-WTF 扩展库:

pip install flask-wtf

2. 启用 CSRF 保护

在 Flask 应用程序中导入 CSRFProtect 类,并将其与应用关联以启用 CSRF 保护:

from flask import Flask
from flask_wtf import CSRFProtect

app = Flask(__name__)
csrf = CSRFProtect(app)

在上述代码中,CSRFProtect(app) 会在 Flask 应用程序中启用 CSRF 保护。

3. 配置 CSRF 保护

您可以通过设置 Flask 应用程序的配置项来定制 CSRF 保护。例如:

  • WTF_CSRF_ENABLED:设置为 True 来启用 CSRF 保护(这是默认设置)。
  • WTF_CSRF_SECRET_KEY:设置一个随机且安全的密钥,用于生成和验证 CSRF 令牌。
  • WTF_CSRF_TIME_LIMIT:设置 CSRF 令牌的有效时间(以秒为单位)。
app.config['WTF_CSRF_SECRET_KEY'] = 'your-secret-key'
app.config['WTF_CSRF_TIME_LIMIT'] = 3600  # CSRF token is valid for 1 hour

4. 在表单中使用 CSRF 保护

在使用 Flask-WTF 创建的表单中,CSRF 保护是自动启用的。表单中会自动包含一个隐藏字段,用于存储 CSRF 令牌。您可以在模板中使用 {{ form.hidden_tag() }} 添加隐藏的 CSRF 令牌字段:

<form method="POST">
    {{ form.hidden_tag() }}
    <!-- 其他表单字段 -->
    <input type="submit" value="提交">
</form>

5. 处理 CSRF 验证失败

如果 CSRF 验证失败,Flask 会引发 CSRFError 异常。您可以通过添加错误处理来捕获 CSRFError 并处理它:

from flask_wtf.csrf import CSRFError

@app.errorhandler(CSRFError)
def handle_csrf_error(e):
    return "CSRF token is missing or invalid", 400

6. 其他注意事项

  • 确保在所有对数据有修改的请求(例如 POST、PUT、DELETE 请求)中启用 CSRF 保护。
  • 避免将敏感信息直接存储在 cookie 中,并确保 cookie 的 HttpOnlySecure 属性已设置。
  • 通过使用 HTTPS 来确保请求的安全传输。

通过采用上述策略和最佳实践,您可以在 Flask 应用程序中有效地防止 CSRF 攻击,提高应用程序的安全性。

XSS攻击

XSS(Cross-Site Scripting,跨站脚本)是一种常见的网络安全攻击,它允许攻击者在网页中注入恶意脚本。这些脚本可能被嵌入到网页的内容中,并在用户浏览时执行,从而劫持用户会话、窃取敏感数据、篡改网页内容或执行其他恶意操作。

XSS 攻击的类型

XSS 攻击通常分为三种类型:

  1. 存储型 XSS(也称为持久型 XSS):
    • 恶意脚本被存储在服务器上的持久数据存储中,例如数据库或文件系统。
    • 当用户访问受影响的页面时,恶意脚本会从存储中提取并注入到页面中。
  2. 反射型 XSS(也称为非持久型 XSS):
    • 恶意脚本被注入到 URL 或请求参数中,并立即反射回网页内容。
    • 当用户访问包含恶意脚本的 URL 或提交恶意请求时,网页会执行脚本。
  3. DOM 型 XSS
    • 恶意脚本通过在客户端的 DOM 中注入或修改数据而执行。
    • 攻击者利用客户端脚本中的漏洞(例如直接操作 innerHTML)来注入恶意脚本。

XSS 攻击的危害

  • 会话劫持:攻击者可以利用 XSS 攻击窃取用户的身份验证信息(如 cookie),从而劫持用户会话。
  • 数据窃取:攻击者可以利用 XSS 攻击窃取用户的敏感数据,例如信用卡信息、个人信息等。
  • 网页篡改:攻击者可以修改网页内容,添加或删除网页元素。
  • 恶意重定向:攻击者可以通过 XSS 攻击重定向用户到恶意网站。

防止 XSS 攻击的策略

  • 输出编码:在输出数据到网页时,对数据进行适当的编码,防止恶意脚本被执行。
  • 输入验证和清理:对用户输入数据进行严格的验证和清理,确保数据的格式和内容符合预期。
  • 内容安全策略(CSP):使用 CSP 限制网页上允许加载的脚本、样式表和其他资源。
  • 正确使用 HTML 元素属性:例如,使用 rel="noopener"rel="noreferrer" 属性来保护链接。

通过采取这些预防措施,可以有效地防止 XSS 攻击,保护应用程序和用户的安全。

flask如何防止xss攻击

在 Flask 应用程序中,可以通过采取一系列策略来防止 XSS(跨站脚本)攻击。以下是一些有效的防止 XSS 攻击的措施和最佳实践:

1. 输出编码

  • 在将用户输入数据或其他动态内容输出到网页时,进行适当的编码,确保数据被正确转义。
  • 使用 Flask 的 Jinja2 模板引擎,它会自动转义输出内容。
  • 如果需要在 Jinja2 模板中输出原始 HTML,可以使用 safe 过滤器,但要小心以防止未被验证的用户输入数据。

2. 输入验证和清理

  • 对用户输入数据进行严格的验证和清理,确保输入数据的格式、类型和范围符合预期。
  • 避免直接在输出中使用未经验证和清理的用户输入数据。

3. 内容安全策略(CSP)

  • 使用内容安全策略(Content Security Policy, CSP)限制网页上允许加载的资源,如脚本、样式表、图片等。
  • 在 Flask 应用程序的响应头中设置 Content-Security-Policy,以控制脚本的来源和执行。

4. 避免直接在页面中执行 JavaScript

  • 避免在页面中直接使用 eval()setTimeout()innerHTML 等操作。
  • 避免在页面中直接执行用户输入的脚本。

5. 正确设置 HTTP 头部

  • 使用 X-XSS-Protection 头部来启用浏览器的 XSS 过滤器。
  • 设置 X-Content-Type-Options: nosniff 来防止浏览器 MIME 嗅探。

6. 谨慎使用第三方库

  • 谨慎选择和使用第三方库,确保库的版本是最新的,并关注其安全更新。
  • 避免使用不受信任或未经过审查的库。

7. 用户教育

  • 教育用户不要点击可疑链接或下载不明附件。
  • 提醒用户在输入敏感信息时保持警惕。

通过在 Flask 应用程序中采取这些措施,可以有效地防止 XSS 攻击,提高应用程序的安全性。确保所有输出都经过正确转义,并采取适当的安全策略是防止 XSS 攻击的关键。

django中是怎么防御csrf攻击,原理是什么

在 Django 框架中,CSRF(跨站请求伪造)保护是一种防止恶意请求被提交的机制。Django 提供了内置的 CSRF 保护功能,可以在应用程序中轻松启用。下面是 Django 中 CSRF 保护的原理以及如何防御 CSRF 攻击的详细步骤:

CSRF 保护的原理

Django 的 CSRF 保护机制基于 CSRF 令牌。这些令牌是在服务器端生成的随机、唯一的值,用于验证请求的合法性。CSRF 保护的基本原理如下:

  1. 生成 CSRF 令牌:Django 在用户访问受保护的页面时,为用户生成一个唯一的 CSRF 令牌,并将其存储在 cookie 中或会话中。
  2. 嵌入 CSRF 令牌:在表单或请求中嵌入 CSRF 令牌。对于 HTML 表单,可以使用模板标记 {% csrf_token %} 来自动添加隐藏的 CSRF 令牌字段。
  3. 验证 CSRF 令牌:在处理请求时,Django 会验证请求中的 CSRF 令牌是否与服务器端存储的令牌匹配。如果令牌匹配,则请求被视为合法;否则,请求被拒绝。

在 Django 中启用 CSRF 保护

在 Django 应用程序中,CSRF 保护通常是默认启用的。以下是一些关键的设置和用法:

1.模板中的 CSRF 令牌在 HTML 表单中,通过在表单内添加 {% csrf_token %} 模板标记,Django 会自动嵌入隐藏的 CSRF 令牌字段:

<form method="POST" action="/submit-form/">
    {% csrf_token %}
    <!-- 其他表单字段 -->
    <input type="submit" value="提交">
</form>

2.CSRF 中间件Django 的 CSRF 保护是通过中间件 CsrfViewMiddleware 实现的。确保该中间件已在 MIDDLEWARE 列表中启用(它通常默认启用)。

3.视图中的 CSRF 验证在视图函数中,Django 会自动验证请求的 CSRF 令牌。如果验证失败,视图将引发 django.middleware.csrf.CsrfViewMiddleware 异常,您可以添加错误处理程序来处理该异常。

4.Ajax 请求中的 CSRF 令牌对于 Ajax 请求,您需要将 CSRF 令牌添加到请求的头部。例如,在 JavaScript 中:

var csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
fetch('/api/', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-CSRFToken': csrfToken
    },
    body: JSON.stringify({key: 'value'})
});

5.配置 CSRF 保护Django 的 CSRF 保护可以通过设置文件中的配置项进行定制,例如:

  • CSRF_COOKIE_SECURE:确保 CSRF cookie 仅通过 HTTPS 传输。
  • CSRF_TRUSTED_ORIGINS:指定受信任的源,允许来自这些源的请求通过 CSRF 保护。

    通过在 Django 应用程序中正确配置和使用 CSRF 保护,您可以有效地防止 CSRF 攻击,提高应用程序的安全性。