Django 铺垫

【一】基础知识点

【1】web框架的本质

  • Web框架本质上可以看成是一个功能强大的socket服务端
  • 用户的浏览器可以看成是拥有可视化界面的socket客服端
  • 两种通过网络请求实现数据交互

【2】浏览器发送请求

(1)HTTP协议

  • HTTP协议是超文本传输协议,用于规定服务器和浏览器之间数据交互的格式。

(2)HTTP四大特性

  • 基于请求-响应模式:客户端发送请求,服务器返回响应。
  • 基于TCP/IP之上:作用于应用层之上的协议。
  • 无状态:HTTP协议本身不保存用户的信息,每个请求都是独立的。为了记录用户状态,出现了一些技术,如cookie、session和token。
  • 无/短链接:HTTP 1.0默认使用短链接,即请求-响应后立即断开连接。HTTP 1.1支持长链接,即双方建立连接后不会立即断开,如WebSocket。

(3)HTTP协议格式

  • 请求数据格式
    • 请求首行:标识HTTP协议和当前请求方式。
    • 请求头:多组键值对,包含请求的附加信息。
    • 空行:用于分隔请求头和请求体。
    • 请求体:并非所有请求都有,主要用于存放POST请求提交的敏感数据。
  • 响应数据格式
    • 响应首行:标识HTTP协议、当前请求方式和响应状态码。
    • 响应头:多组键值对,包含响应的附加信息。
    • 空行:用于分隔响应头和响应体。
    • 响应体:返回给浏览器展示给用户的数据。

(4)状态码

  • 1xx信息性状态码:请求已被接收,服务器正在处理
  • 2xx成功状态码:请求已被服务器接收、理解和处理
  • 3xx重定向状态码:表示需要进一步操作完成请求,移动到了新的URL
  • 4xx客户端错误状态码:客户端发送的请求错误
  • 5xx服务器错误状态码:服务器在处理请求时发生了错误

【3】动、静态网页

(1)静态网页

  • 介绍:

    • 静态网页是指在服务器上事先准备好的网页文件,其内容在用户访问时不会发生变化。静态网页通常由HTML、CSS和JavaScript等静态资源组成。
  • 特点:

    • 内容固定不变:静态网页的内容在服务器上生成,并在用户访问时以相同的形式呈现。

    • 简单易部署:静态网页不需要服务器端的动态处理,部署和维护相对简单。

    • 性能高效:由于没有动态处理的开销,静态网页加载速度较快。

  • 示例:

    • 一个静态网页的示例可以是一个展示公司产品信息的网页,其中包含公司的介绍、产品列表和联系方式等信息。
    • 还有错误页面等error.html

(2)动态网页

  • 介绍:

    • 动态网页是指在用户访问时通过服务器端的动态处理生成的网页,内容可以根据用户的请求和其他条件而变化。
  • 特点:

    • 内容可变:动态网页的内容可以根据用户的请求、数据库查询结果、用户状态等动态生成。

    • 复杂交互:动态网页可以支持更复杂的用户交互,如表单提交、数据验证、用户登录等。

    • 数据库和后端处理:动态网页通常需要与数据库进行交互,并由服务器端的程序处理用户请求。

  • 示例:

    • 一个动态网页的示例可以是一个在线商城,用户可以浏览商品、添加到购物车、下订单等操作,而这些操作都需要与服务器端进行交互并动态生成网页内容。

(3)总结

  • 静态网页是事先准备好的内容固定的网页,部署简单且加载速度快
  • 动态网页是根据用户请求和服务器端处理生成的网页,内容可变且支持复杂的交互操作。

【一】socket服务端搭建

【1】模板

(1)基础模板

  • 在web中输入127.0.0.1

  • 无法看任何信息

  • 因为没有按照HTTP协议传输内容

import socket# 创建socket对象
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 避免重启后端口被占用
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 监听端口
server.bind(("127.0.0.1", 8080))
# 创建半连接池
server.listen(5)while True:# 等待连接conn, addr = server.accept()# 接收数据recv_data = conn.recv(1024).decode('utf8')print(f"recv:>>>{recv_data}")# 二级制数据http_data = b"HTTP1.1 200 ok \r\n\r\n"data = b"hello world"# 发送数据conn.send(http_data + data)

(2)web端可以看到信息版

  • 按照HTTP协议格式发送
    • 响应首行 响应头 空行 响应体
import socket# 创建socket对象
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 避免重启后端口被占用
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 监听端口
server.bind(("127.0.0.1", 8080))
# 创建半连接池
server.listen(5)while True:# 等待连接conn, addr = server.accept()# 接收数据recv_data = conn.recv(1024).decode('utf8')print(f"recv:>>>{recv_data}")# 响应首行 响应头 空行http_data = b"HTTP1.1 200 ok \r\n\r\n"# 二级制数据send_data = b"hello world"# 发送数据conn.send(http_data + send_data)

【2】任务:接收浏览器信息

  • 在web中输入任意字符串
    • 在socket中找到这个字符串
  • 示例:127.0.0.1:8080/index
    • 拿到index
  • 示例:127.0.0.1:8080/home
    • 拿到home
  • 将服务端按照空格切分,发现是第二个数据
    • 所以通过recv_data.split(' ')[1]可以拿到
import socket# 创建socket对象
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 避免重启后端口被占用
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 监听端口
server.bind(("127.0.0.1", 8080))
# 创建半连接池
server.listen(5)while True:# 等待连接conn, addr = server.accept()# 接收数据recv_data = conn.recv(1024).decode('utf8')print(f"recv:>>>{recv_data.split(' ')[1]}")# 响应首行 响应头 空行http_data = b"HTTP1.1 200 ok \r\n\r\n"# 二级制数据send_data = b"hello world"# 发送数据conn.send(http_data + send_data)
recv:>>>/
recv:>>>/index
recv:>>>/home
recv:>>>/favicon.ico # 现在不用管

【二】基于wsgiref模块

  • 内置模块

【1】模板

(1)基础模板

  • 访问127.0.0.1:8080
  • 便会返回hello world
from wsgiref import simple_serverdef run(request, response):""":param request: 请求相关的数据:param response: 响应相关的数据:return: 返回给客户端的展示数据"""# 固定编写response("200 OK", [])return [b"hello world"]if __name__ == '__main__':# 端口和IPIP = "127.0.0.1"PORT = 8080# 创建服务端对象,只要有请求访问,便会执行run方法server = simple_server.make_server(IP, PORT, run)server.serve_forever()

(2)任务:根据请求返回不同信息

  • 同理通过分析response
    • 首先这是一个字典
    • 然后每次浏览器请求的后缀在PATH_INFO
    • 所以根据这个返回不同信息
from wsgiref import simple_serverdef run(request, response):""":param request: 请求相关的数据:param response: 响应相关的数据:return: 返回给客户端的展示数据"""# 固定编写response("200 OK", [])# 获取后缀内容get_path = request.get("PATH_INFO")if get_path == "/index":return [b"welcome index"]elif get_path == "/home":return [b"welcome home"]else:return [b"404 error"]if __name__ == '__main__':# 端口和IPIP = "127.0.0.1"PORT = 8080# 创建服务端对象,只要有请求访问,便会执行run方法server = simple_server.make_server(IP, PORT, run)server.serve_forever()

【2】存在的不足和优化

(1)问题

  • 如果网站很多,那么需要人为的写很多的elif
  • 每个分支下的功能根据业务逻辑的不同可能会比较复杂的逻辑

(2)函数和模块优化

  • urls
    • 后缀与函数名对应关系
    • (‘/index’,register)
    • 后缀专业名词称之为’路由’
    • 函数名专业名词称之为’视图函数’
    • urls.py专业名词称之为’路由层’
  • views
    • 专门编写业务逻辑代码
    • 可以是函数 也可以是类
    • 函数专业名词称之为’视图函数’
    • 类专业名词称之为’视图类’
    • views.py专业名词称之为’视图层’
  • templates
    • 专门存储html文件
    • html文件专业名词称之为’模板文件’
    • templates文件夹专业名词称之为’模板层’
  • static
    • 专门存储静态文件资源
    • 页面所需css文件、js文件、图片文件、第三方文件可统称为’静态资源’
项目文件夹  
├── server.py            // 主应用
├── urls.py             // 对应关系的存储
├── views.py        	// 业务逻辑的编写
├── templates文件夹      // 存储项目所需的html文件
│       └── home.html	// home页面
├── static文件夹         // 存储项目所需的静态文件
│       └── jquery-3.7.1.min.js		// jquery框架
│       └── bootstrap-grid.min.css  // bootstrap框架
......

(3)示例

  • server.py:主应用
from wsgiref import simple_server
from urls import urls
from views import errordef run(request, responce):responce('200 OK', []) current_path = request.get("PATH_INFO")func_name = Nonefor url_tuple in urls:  # ('/register', register)if current_path == url_tuple[0]:func_name = url_tuple[1]breakif func_name:res = func_name(request)else:res = error(request) return [res.encode('utf8')]if __name__ == '__main__':server = simple_server.make_server('127.0.0.1', 8080, run)server.serve_forever()
  • urls:对应关系的存储
from views import *urls = (('/home', login),('/index', index),
)
  • views:业务逻辑代码
# 功能函数
def register(request):return 'home'def index(request):return 'index'def error(request):return open(r'static/error.html', 'r', encoding='utf8').read()
  • static->error.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><meta name="viewport" content="width=device-width,initial-scale=1.0"><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script><link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css"><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script></head>
<body><h1>404 Error</h1>
</body>
</html>

【三】基于jinjia2模块

【1】任务:页面显示当前时间

  • server.py:主应用

    • 不做任何改变
  • urls:对应关系的存储

from views import *urls = (('/show_time', show_time),
)
  • views:业务逻辑代码
import timedef show_time(request):now_time = time.strftime("%x %X", time.localtime())return open(r"templates/time.html", 'r', encoding='utf8').read().replace("time", now_time)def error(request):return open(r'static/error.html', 'r', encoding='utf8').read()
  • templates->time.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><meta name="viewport" content="width=device-width,initial-scale=1.0"><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script><link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css"><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script></head>
<body><h1 style="text-align: center">time</h1>
</body>
</html>

【2】jinja2模块

(1)基础介绍

  • Jinja2是一个流行的Python模板引擎,它提供了一种灵活而强大的方式来生成动态内容。
  • Jinja2模板引擎可以用于各种应用程序,包括Web开发、生成配置文件、邮件模板等。

(2)特点和使用方法

  • 模板语法:
    • Jinja2使用一种类似于HTML的模板语法,通过插入变量、控制流语句和过滤器等,可以动态生成内容。
    • 例如,使用{{ variable }}表示插入变量,{% if condition %}...{% endif %}表示条件语句,{% for item in collection %}...{% endfor %}表示循环语句。
  • 模板继承:
    • Jinja2支持模板继承,可以定义一个基础模板,然后在子模板中继承基础模板并覆盖特定的部分。
  • 过滤器和函数:
    • Jinja2提供了一些内置的过滤器和函数,用于对变量进行格式化、转换和处理。例如,可以使用{{ variable|filter }}的语法来应用过滤器。
  • 变量上下文:
    • 在渲染模板时,可以通过向模板引擎提供一个变量上下文来传递数据。
    • 上下文可以是一个字典,其中包含模板中使用的变量和对应的值。
  • 扩展和自定义:
    • Jinja2允许通过扩展和自定义来增强模板引擎的功能。
    • 可以编写自定义的过滤器、函数和标签,或者使用现有的扩展库来扩展Jinja2的功能。

【3】使用jinja2模块

(1)演示

  • templates -> show_jinja2.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><meta name="viewport" content="width=device-width,initial-scale=1.0"><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script><link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css"><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script></head>
<body>
<h1>字典数据展示</h1>
<p>{{ user }}</p>
<p>{{ user.name }}</p>
<p>{{ user['pwd'] }}</p>
<p>{{ user.get('hobby') }}</p>
<h1>列表数据展示</h1>
<p>{% for i in new_list %}<span>元素:{{ i }}</span>{% endfor %}
</p>
</body>
</html>
  • views
import time
from jinja2 import Template# 功能函数
def show_time(request):now_time = time.strftime("%x %X", time.localtime())return open(r"templates/time.html", 'r', encoding='utf8').read().replace("time", now_time)def show_jinja2(request):user_dict = {"name": "bruce", "age": 18, "hobby": "playing"}new_list = ["aa", "bb", "cc", 11, 22, 33]data = open("templates/show_jinja2.html", 'r', encoding='utf8').read()temp_obj = Template(data)res = temp_obj.render({"user": user_dict, "new_list": new_list})return resdef error(request):return open(r'static/error.html', 'r', encoding='utf8').read()
  • urls
from views import *urls = (('/show_time', show_time),('/show_jinja2', show_jinja2),
)

(2)任务:页面显示时间

  • templates->time.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><meta name="viewport" content="width=device-width,initial-scale=1.0"><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script><link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css"><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script></head>
<body><h1 style="text-align: center">{{ time }}</h1>
</body>
</html>
  • views
import time
from jinja2 import Template# 功能函数
def show_time(request):now_time = time.strftime("%x %X", time.localtime())return open(r"templates/time.html", 'r', encoding='utf8').read().replace("time", now_time)def show_time_jinja2(request):now_time = time.strftime("%x %X", time.localtime())data = open(r"templates/time.html", 'r', encoding='utf8').read()temp_obj = Template(data)res = temp_obj.render({"time":now_time})return resdef error(request):return open(r'static/error.html', 'r', encoding='utf8').read()
  • urls
from views import *urls = (('/show_time', show_time),('/show_time_jinja2', show_time_jinja2)
)

【四】网络框架和MVC架构

【1】网络框架

  • 网络框架是一种软件框架,用于构建Web应用程序。它提供了一系列工具、库和规范,以简化Web开发过程,包括路由处理、请求处理、模板引擎、数据库连接等功能。
  • 网络框架通常提供了一种结构和组织应用程序的方式,使得开发者可以更加高效地开发和维护Web应用程序。
  • 网络框架可以是基于某种编程语言的,如Python的Flask和Django框架,JavaScript的Express框架等。

【2】MVC架构

  • MVC(Model-View-Controller)是一种常见的软件设计模式,用于组织和分离应用程序的逻辑和视图。
  • MVC架构将应用程序分为三个核心组件:
    • 模型(Model):负责处理数据和业务逻辑。模型通常与数据库交互,处理数据的读取、写入和验证等操作。
    • 视图(View):负责展示数据给用户,并接收用户的输入。视图通常是用户界面的一部分,如网页、移动应用程序的界面等。
    • 控制器(Controller):负责处理用户的请求,协调模型和视图之间的交互。控制器接收用户的输入,根据业务逻辑来更新模型,并将更新后的数据传递给视图进行展示。
  • MVC架构的优势在于将应用程序的不同功能模块进行了分离,使得代码更加可维护、可扩展和易于测试。

【3】小结

  • 在Web开发中,网络框架通常采用MVC架构来组织应用程序的代码。
  • 框架提供了路由处理、请求处理和模板引擎等功能,而开发者则可以按照MVC的思想将应用程序的逻辑和视图进行分离,提高开发效率和代码质量。
  • 通过网络框架和MVC架构的结合,开发者可以更好地组织和管理Web应用程序,并实现灵活、可扩展的应用开发。

【五】主流后端框架

【1】Django

(1)介绍

  • Django是一个使用Python编写的高级Web应用程序框架。它以快速开发和可扩展性为目标,提供了一系列工具和功能,使得构建复杂的Web应用程序变得简单和高效。

(2)特点

  • 完整的功能集:Django提供了许多内置的功能和模块,包括数据库ORM、表单处理、用户认证、管理界面等。这些功能的集成使得开发者可以更快速地构建功能完善的Web应用程序,而无需从头开始编写大量的代码。
  • 高度可扩展:Django采用了松散耦合的设计,使得开发者可以方便地扩展和定制应用程序。它支持插件和第三方应用的集成,以及自定义模型、视图和模板等。
  • 强大的模板引擎:Django的模板引擎提供了丰富的模板语法和功能,使得开发者可以轻松地生成动态内容和处理数据。它支持模板继承、过滤器、标签等特性,使得模板的重用和组织变得更加简单。
  • 自动化的管理界面:Django自带了一个强大的管理界面,可以自动生成数据库管理界面,使得开发者可以方便地管理和操作数据。这个管理界面提供了增删改查等常见操作的功能,并且可以进行自定义扩展。

(3)组成结构

  • Django的组成结构基于MVC(Model-View-Controller)架构,但在Django中,通常称之为MTV(Model-Template-View):
    • 模型(Model):模型负责处理数据和业务逻辑。它定义了数据模型和数据库表之间的映射关系,并提供了对数据的增删改查等操作。
    • 模板(Template):模板负责展示数据给用户。它使用Django的模板语言,将数据和逻辑结合起来生成最终的HTML页面。
    • 视图(View):视图负责处理用户的请求和逻辑处理。它接收用户的请求,从数据库中获取数据,然后将数据传递给模板进行渲染,并返回生成的HTML页面给用户。

【2】Flask

(1)介绍

  • Flask是一个使用Python编写的微型Web框架,它以简洁和灵活为特点。Flask提供了一些基本的工具和库,使得构建Web应用程序变得简单和可扩展。

(2)特点

  • 简洁而灵活:Flask的设计理念是保持简单和可扩展性,它提供了一些核心功能,但并没有强制性的约束。开发者可以根据需求自由选择和集成其他库和工具,以满足特定的应用需求。
  • 轻量级:Flask是一个轻量级的框架,它的核心库非常小巧,并且没有多余的依赖。这使得Flask在资源消耗和性能方面表现出色,适合构建小型和简单的Web应用程序。
  • 易学易用:Flask的API设计简单直观,容易学习和使用。它提供了路由处理、请求处理、模板引擎等基本功能,使得开发者可以快速上手并进行开发。
  • 可扩展性:尽管Flask本身是一个微型框架,但它支持通过插件和扩展来增加功能。开发者可以根据需要选择和集成各种扩展,以满足特定的应用需求。

【3】Tornado

(1)介绍

  • Tornado是一个使用Python编写的高性能Web框架和异步网络库。它以处理大量并发连接和高性能为目标,适用于构建高性能的Web应用程序和实时Web服务。

(2)特点

  • 高性能:Tornado采用了异步的事件驱动编程模型,通过非阻塞的I/O操作和事件循环机制,实现了高性能的网络通信。它可以处理大量的并发连接,并具有出色的响应能力。
  • 内置异步支持:Tornado内置了对异步编程的支持,包括异步请求处理、异步HTTP客户端和异步数据库访问等。这使得开发者可以编写高效的异步代码,处理并发请求和I/O操作。
  • 轻量级:Tornado是一个轻量级的框架,它的核心库非常小巧,并且没有多余的依赖。这使得Tornado在资源消耗和性能方面表现出色,适合构建高性能的Web应用程序。
  • WebSocket支持:Tornado提供了对WebSocket的原生支持,使得开发者可以方便地构建实时Web应用程序和实时通信服务。

【4】FastAPI

(1)介绍

  • FastAPI是一个使用Python编写的现代化Web框架,它旨在提供高性能和易用性。FastAPI基于Python 3.7+的类型注解和异步编程模型,使得开发者可以快速构建高性能的Web API应用程序。

(2)特点

  • 高性能:FastAPI基于异步编程模型,利用Python 3.7+的类型注解和静态类型检查,实现了高性能的请求处理。它使用基于Starlette的异步服务器,能够处理大量的并发请求。
  • 快速开发:FastAPI的设计目标是提供快速开发的体验。它提供了自动生成API文档、输入数据验证、请求处理等功能,使得开发者可以快速构建和部署Web API应用程序。
  • 类型注解和自动文档:FastAPI利用Python的类型注解,可以自动生成API文档和输入数据验证。开发者可以通过类型注解定义输入和输出的数据模型,并自动生成交互式的API文档。
  • 异步支持:FastAPI完全支持异步编程,可以处理异步请求和异步操作。它基于Python的协程和异步IO,能够处理高并发和高负载的请求。

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

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

相关文章

【云开发笔记No.15】持续改进与反馈

一、引言 在产品研发过程中&#xff0c;反馈机制是确保项目顺利进行并最终达到预期目标的关键环节。它不仅能够及时发现和纠正开发过程中的问题&#xff0c;还能促进团队成员之间的有效沟通&#xff0c;提高开发效率。持续改进作为现代研发管理的重要理念&#xff0c;与反馈机…

RabbitMQ的事务机制

想要保证发送者一定能把消息发送给RabbitMQ&#xff0c;一种是通过Confirm机制&#xff0c;另一种就是通过事务机制。 RabbitMQ的事务机制&#xff0c;允许生产者将一组操作打包成一个原子事务单元&#xff0c;要么全部执行成功&#xff0c;要么全部失败。事务提供了一种确保消…

wireshark下载

一、官网下载 www.wireshark.org 二、各版本链接 链接&#xff1a;Index of /download/

FPGA使用XADC测量外部模拟输入电压

一、XADC简介 1.1、特性 Xilinx系列的FPGA中都包含了一个内置的XADC&#xff0c;我们可以通过这个XADC进行一些精度不高的外部模拟信号采样以及FPGA片内传感器信号采集。XADC的分辨率为12位&#xff0c;采样率为1MSPS。 1.2、结构框图 两片XADC&#xff0c;ADC A可用于片内…

SpringJPA 做分页条件查询

前言: 相信小伙伴们的项目很多都用到SpringJPA框架的吧,对于单表的增删改查利用jpa是很方便的,但是对于条件查询并且分页 是不是很多小伙伴不经常写到. 今天我整理了一下在这里分享一下. 话不多说直接上代码: Controller: RestController public class ProductInstanceContr…

12 React 组件通信 兄弟组件之间通信

12 React 组件通信 兄弟组件之间通信 在React中实现兄弟组件通信相对于父子组件通信来说稍微复杂一些&#xff0c;因为React本身是基于单向数据流的&#xff0c;兄弟组件之间并没有直接的通信途径。不过可以通过以下几种方式实现兄弟组件通信&#xff1a; 通过共同的父组件传递…

Apache HTTP服务器(Linux离线编译安装)

Apache HTTP服务器&#xff08;Linux离线编译安装&#xff09; Apache是普通服务器&#xff0c;本身只支持html即普通网页。可以通过插件支持PHP,还可以与Tomcat连通(单向Apache连接Tomcat,就是说通过Apache可以访问Tomcat资源。反之不然)。 Apache和Tomcat都可以做为独立的w…

8个常见的数据可视化错误以及如何避免它们

在当今以数据驱动为主导的世界里&#xff0c;清晰且具有洞察力的数据可视化至关重要。然而&#xff0c;在创建数据可视化时很容易犯错误&#xff0c;这可能导致对数据的错误解读。本文将探讨一些常见的糟糕数据可视化示例&#xff0c;并提供如何避免这些错误的建议。 本文总结了…

Javascript由浅到深

关注我&#xff0c;持续分享逻辑思维&管理思维&#xff1b; 可提供大厂面试辅导、及定制化求职/在职/管理/架构辅导&#xff1b; 有意找工作的同学&#xff0c;请参考博主的原创&#xff1a;《面试官心得--面试前应该如何准备》&#xff0c;《面试官心得--面试时如何进行自…

蓝桥杯day11刷题日记

P8615 [蓝桥杯 2014 国 C] 拼接平方数 思路&#xff1a;先把数据范围内的平方数打上标记&#xff0c;然后就是遍历这个区间&#xff0c;转成字符串&#xff08;好拆数据&#xff09;&#xff0c;用substr拆开数据&#xff0c;再强转成整数类型&#xff0c;最后查看拆开的数据是…

【WPF应用13】WPF基本控件-DockPanel布局详解与示例

引言 WPF (Windows Presentation Foundation) 是微软 .NET 框架的一个组成部分&#xff0c;它用于构建桌面应用程序的用户界面。在 WPF 中&#xff0c;控件是构建用户界面的基本元素&#xff0c;而布局控件则负责安排其他控件的位置和大小。DockPanel 是 WPF 中的一个布局控件&…

如何使用PHP和RabbitMQ实现消息队列?

前言 今天我们来做个小试验&#xff0c;用PHP和RabbitMQ实现消息队列功能。 前期准备&#xff0c;需要安装好docker、docker-compose的运行环境。 如何使用docker部署php服务_php如何使用docker发布-CSDN博客 一、安装RabbitMQ 1、创建相关目录&#xff0c;执行如下命令。…

计算机网络⑦ —— 网络层协议

1. ARP协议 在传输⼀个 IP 数据报的时候&#xff0c;确定了源 IP 地址和⽬标 IP 地址后&#xff0c;就会通过主机路由表确定 IP 数据包下⼀跳。然⽽&#xff0c;⽹络层的下⼀层是数据链路层&#xff0c;所以我们还要知道下⼀跳的 MAC 地址。由于主机的路由表中可以找到下⼀跳的…

手撕算法-接雨水

描述 分析 i位置能积累的雨水量&#xff0c;等于其左右两边最大高度的最小值。为了能获取i位置左右两边的最大高度。使用动态规划。两个dp数组&#xff1a; leftMaxrightMax 其中 leftMax[i] 代表i位置左边的最大高度rightMax[i] 代表i位置右边的最大高度 初始状态&#x…

npm 包管理工具:常用命令详解与使用指南

npm常用命令的更详细解释和使用场景&#xff1a; npm init 详细说明&#xff1a;此命令用于初始化一个新的Node.js项目。它会创建一个package.json文件&#xff0c;其中包含项目的基本信息&#xff0c;如名称、版本、描述、入口点&#xff08;main file&#xff09;、测试命令、…

Python Flask 自定义过滤器

{{ data.list | li2 }} li2就是自定义的 from flask import Flask, render_templateapp Flask(__name__)app.route("/index") def index():data {name: "张三","age": 18,list: [123123, 41, 123]}return render_template("index2.html…

[AIGC] 使用Spring Boot进行单元测试:一份指南

在现代软件开发过程中&#xff0c;确认你的应用正确运行是至关重要的一步。Spring Boot提供了一组实用工具和注解来辅助你在测试你的应用时&#xff0c;使得这个过程变得简单。下面就来分享一下如何在Spring Boot中进行单元测试。 文章目录 为什么需要单元测试Spring Boot单元测…

Redis中RDB中的文件写入

RDB文件的创建与载入。 有两个Redis命令可以用于生成RDB文件&#xff0c;一个是SAVE&#xff0c;另一个是BGSAVE. SAVE命令会阻塞Redis服务器进程&#xff0c;直到RDB文件创建完毕为止&#xff0c;在服务器进程阻塞期间&#xff0c;服务器 不能处理任何命令请求: 127.0.0.1:6…

枚举的详解

枚举的讲解 在C语言中&#xff0c;没有内置的枚举&#xff08;enum&#xff09;数据类型&#xff0c;但我们可以使用整数类型来模拟枚举的行为。C99标准之前&#xff0c;C语言使用#define指令来定义枚举&#xff0c;但这种方式并不安全&#xff0c;因为如果枚举值发生变化&…

Ubuntu Desktop Server - user 用户与 root 用户切换

Ubuntu Desktop Server - user 用户与 root 用户切换 1. user 用户与 root 用户切换2. root 用户与 user 用户切换References 1. user 用户与 root 用户切换 strongforeverstrong:~$ strongforeverstrong:~$ sudo su [sudo] password for strong: rootforeverstrong:/home/s…