django企业开发实战-学习小结

写在前面

初次阅读此书是三年前,当时没经历过完整的项目 觉得这书就是扯淡 后来经历过项目加班与毒打 今天再翻开此书 觉得实乃不可多得之物 花些时间啃下来吧

django版本 3.2

本博客开源项目地址 kimsmith/django企业实战 (gitee.com)

有的代码因为版本混乱报错 自己调调

需求

需求文档

写文档,列举需要实现的功能,详细列举,不考虑技术实现细节

需求评审与分析

主要是将需求文档落实到技术细节,评审需求需要的技术栈,然后评审需求是否可实现,预估每个子需求的工作量等

此处可以考虑后续的衍生需求,考虑技术实现是否可行是否困难,技术需要的工作量等

功能分析

技术人员对需求评审的结果进行技术实现分析,模块划分等

模块划分可以基于数据实体制作ER图,或者建立UML图

模块划分

作用是将一个大项目分成几个小模块,让手下的人去按模块开发

框架基础和技术选型

需要选择 语言 框架 数据库 然后考虑团队开发与实现能力等

wsgi

wsgi,全称Web Server Gateway Interface,Web服务器网关接口,是用来规定web server应如何和程序交互的网关协议。可以理解为一个web应用的容器,适配了程序和操作系统之间功能,将操作系统一些功能抽象为接口提供给程序使用

可以使用wsgi,目的是使用实现统一协议的web server,不然换着乱

简单的web server

一个基本的socket监听程序

# coding:utf-8import socketEOL1 = b'\n\n'
EOL2 = b'\n\r\n'
body = 'hello, world<h1> from tjh </h1>'
resp_params = ['HTTP/1.0 200 OK','Date: Sun, 31 jul 2024 09:35:33 GMT','Content-Type: text/html; charset=utf-8','Content-Length: ()\r\n'.format(len(body.encode())),body
]resp = '\r\n'.join(resp_params)def handle_connection(conn, addr):req = b''while EOL1 not in req and EOL2 not in req:req += conn.recv(1024)print(req)conn.send(resp.encode())conn.close()def main():ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)ss.bind(('127.0.0.1', 8000))ss.listen(5)  # conn max queue numberprint('http://127.0.0.1:8000')try:while True:conn, addr = ss.accept()handle_connection(conn, addr)finally:ss.close()if __name__ == '__main__':main()

效果

注意 Content-Type为text/plain 还是text/html

多线程版web server

还是阻塞模式,非阻塞会报错 还没处理

# coding:utf-8import socket
import errno
import threading
import timeEOL1 = b'\n\n'
EOL2 = b'\n\r\n'
body = 'hello, world<h1> from tjh </h1>-from {thread_name}'
resp_params = ['HTTP/1.0 200 OK','Date: Sun, 31 jul 2024 09:35:33 GMT','Content-Type: text/html; charset=utf-8','Content-Length: {length}\r\n',body
]resp = '\r\n'.join(resp_params)def handle_connection(conn, addr):req = b''while EOL1 not in req and EOL2 not in req:req += conn.recv(1024)print(req)current_thread = threading.currentThread()content_length = len(body.format(thread_name=current_thread.name).encode())print(current_thread.name)conn.send(resp.format(thread_name=current_thread.name, length=content_length).encode())conn.close()def main():ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# ss.setblocking(0)  # set socket mode as non block # ss.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)ss.bind(('127.0.0.1', 8000))ss.listen(10)  # conn max queue numberprint('http://127.0.0.1:8000')# ss.setblocking(0)  # set socket mode as non block try:i = 0while True:try:conn, addr = ss.accept()except socket.error as e:if e.args[0] != errno.EAGAIN:raisecontinuei += 1print(i)t = threading.Thread(target=handle_connection, args=(conn, addr), name='thread-%s' % i)t.start()finally:ss.close()if __name__ == '__main__':main()

效果

简单wsgi application

wsgi协议分为两部分,一个是web server,一个是web application。接受请求时,会通过wsgi协议将数据发给web application,application处理完后,设置对应状体和header,之后返回body给web server,web server拿到数据后,进行http协议封装,返回完整http response

# coding: utf-8import os
import sysfrom app import simple_appdef wsgi_to_bytes(s):return s.encode()def run_with_cgi(app):environ = dict(os.environ.items())environ['wsgi.input'] = sys.stdin.bufferenviron['wsgi.errors'] = sys.stderrenviron['wsgi.version'] = (1, 0)environ['wsgi.multithread'] = Falseenviron['wsgi.multiprocess'] = Trueenviron['wsgi.run_once'] = Trueif environ.get('HTTPS', 'off') in ('on', '1'):environ['wsgi.url_scheme'] = 'https'else:environ['wsgi.url_scheme'] = 'http'headers_set = []headers_sent = []def write(data):out = sys.stdout.bufferif not headers_set:raise AssertionError('write() before start_response()')elif not headers_sent:status, resp_headers = headers_sent[:] = headers_setout.write(wsgi_to_bytes('Status: %s\r\n' % status))for header in resp_headers:out.write(wsgi_to_bytes('%s: %s\r\n' % header))out.write(wsgi_to_bytes('\r\n'))out.write(data)out.flush()def start_response(status, resp_headers, exc_info=None):if exc_info:try:if headers_sent:raise (exc_info[0], exc_info[1], exc_info[2])finally:exc_info = Noneelif headers_set:raise AssertionError('headers already set')headers_set[:] = [status, resp_headers]return writeresult = app(environ, start_response)try:for data in result:if data:write(data)if not headers_sent:write('')finally:if hasattr(result, 'close'):result.close()if __name__ == '__main__':run_with_cgi(simple_app)

理解wsgi

wsgi规定,application必须是一个可调用对象,则这个可调用对象可以是函数或实现了__call__方法的实例

wsgi中间件和werkzeug

flask 

截至目前 有了两种方法提供web服务:直接通过socket处理请求,或者通过实现wsgi application部分协议

入门推荐

py微型框架有比如web.py, bottle,flask等 flask是一个不错的微型框架

tornado

高性能。tornado不是基于wsgi协议的框架,但提供了wsgi的支持,特性是异步和非阻塞。可以使用自带的http server进行部署而不是wsgi,因为wsgi是一个同步接口

和flask相比,tornado更侧重性能,整体并不比flask丰富,flask更多的支持对业务的满足

django

和微型框架不同,django框架不是仅需要两三个py文件就能跑起来的web框架,django功能更全也更大

django起步

管理系统后台开发

先安装django,再django-admin startproject project_name创建初始项目

cd到project下,创建一个app

models.py

from django.db import models# Create your models here.
class Student(models.Model):SEX_ITEMS = [(1, '男'), (2, '女'), (0, '未知')]STATUS_ITEMS = [(0, '申请'), (1, '通过'), (2, '拒绝')]name = models.CharField(max_length=128, verbose_name='姓名')sex = models.IntegerField(choices=SEX_ITEMS, verbose_name='性别')profession = models.CharField(max_length=128, verbose_name='职业')email = models.EmailField(verbose_name='Email')qq = models.CharField(max_length=128, verbose_name='QQ')phone = models.CharField(max_length=128, verbose_name='电话')status = models.IntegerField(choices=STATUS_ITEMS, default=0, verbose_name='审核状态')created_time = models.DateTimeField(auto_now_add=True, editable=False, verbose_name='创建时间')def __str__(self):return '<Student: {}>'.format(self.name)class Meta:verbose_name = verbose_name_plural = '学员信息'

admin.py

from django.contrib import admin# Register your models here.
from .models import Studentadmin.site.register(Student)

将创建的app在setting中加到installed_apps下

创建数据库迁移文件 python manage.py makemigrations

创建表 python manage.py migrate

创建超级用户 python manage.py createsuperuser

运行测试服务器,访问127.0.0.1:8000 发现是默认页面

访问127.0.0.1:8000/admin会跳转到刚开发的管理员页面,然后用刚创的管理员用户名和密码登录

管理员页面语言是英文,时区也是UTC,可在setting进行配置

重新启动测试服务器,再次登入管理员页面,发现语言变成中文

管理系统前台开发

创一个默认视图函数index

from django.shortcuts import render# Create your views here.
def index(request):words = 'hello, world!'return render(request, 'index.html', context={'words': words})

视图函数使用了模板文件index.html,在app的templates目录下创建index.html,render渲染时会自动去寻找模板文件。django渲染时会去每个app下查找模板,寻找的目标app是在setting中注册的app,并且是按顺序寻找(从上到下)。如果两个不同app下有同名模板,则第一个app的模板会覆盖第二个app的模板

先在app下创建目录templates再在templates中创建index.html

<!DOCTYPE html>
<html>
<head><title>学员管理系统</title>
</head>
<body>
{{ words }}
</body>
</html>

模板用到了django模板语法 {{ words }},这个变量是从视图函数的context传过来的上下文

在urls.py中配置url

from django.contrib import admin
from django.urls import path, re_pathfrom admin_backend.views import indexurlpatterns = [re_path(r'^$', index, name='index'),path('admin/', admin.site.urls),
]

重新运行测试服务器,访问127.0.0.1:8000查看效果

在admin后台站点尝试手动创建几个学生数据用于练手,需要修改views.py

def index(request):students = Student.objects.all()return render(request, 'index.html', context={'students': students})
<body>
<ul>{% for student in students %}<li>{{ student.name }} - {{student.get_status_display }}</li>{% endfor %}
</ul>
</body>

注意到student的方法get_status_display,实际模型只有status字段没有这个方法,方法是django自己拼出来的,方法作用是展示这个字段实际打算展示的值。

还有一个,模板里的方法可以不用写括号,django会自己帮忙调用

开发提交数据的功能,使用模型表单

from django import formsfrom .models import Studentclass StudentForm(forms.Form):# name = forms.CharField(label='姓名', max_length=128)# sex = forms.ChoiceField(label='性别', choices=Student.SEX_ITEMS)# profession = forms.CharField(label='职业', max_length=128)# email = forms.EmailField(label='邮箱', max_length=128)# qq = forms.CharField(label='QQ', max_length=128)# phone = forms.CharField(label='手机', max_length=128)class Meta:model = Studentfields = ('name', 'sex', 'profession', 'email', 'qq', 'phone')

模型表单可以每一条字段一行,也可以直接复用models.py中对应的模型字段

当需要form和model不完全一致时,可以在模型表单里单独修改,比如增加qq号必须是纯数字校验

class StudentForm(forms.Form):def clean_qq(self):cleaned_data = self.cleaned_data['qq']if not cleaned_data.isdigit():raise forms.ValidationError('必须是数字')class Meta:model = Studentfields = ('name', 'sex', 'profession', 'email', 'qq', 'phone')

clean_qq是模型表单会自动调用处理每个字段的方法

有了表单,修改views.py逻辑,开始使用模型表单

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reversefrom .models import Student
from .forms import StudentForm# Create your views here.
def index(request):students = Student.objects.all()aif request.method == 'POST':form = StudentForm(request.POST)if form.is_valid():cleaned_data = form.cleaned_datastudent = Student()student.name = cleaned_data['name']student.sex = cleaned_data['sex']student.email = cleaned_data['email']student.profession = cleaned_data['profession']student.qq = cleaned_data['qq']student.phone = cleaned_data['phone']student.save()return HttpResponseRedirect(reverse('index'))else:form = StudentForm()context = {'students': students,'form': form,}return render(request, 'index.html', context=context)

form.cleaned_data是用户在页面输入完数据提交后,django根据字段类型转换后的字段

reverse方法避免了将url地址硬编码到视图函数中,如果要修改url地址,仅需在urls.py中改即可,无需修改views.py

表单模型提供了表单验证能力,减少了前端进行表单验证代码量

上述代码中,手动将字段值从form实例更新到模型实例可以省略,直接保存表单模型实例就可以

# Create your views here.
def index(request):students = Student.objects.all()if request.method == 'POST':form = StudentForm(request.POST)if form.is_valid():form.save()return HttpResponseRedirect(reverse('index'))else:form = StudentForm()context = {'students': students,'form': form,}return render(request, 'index.html', context=context)

当用户get的时候,页面是填写表单,提交时,保存表单

index.html

<!DOCTYPE html>
<html>
<head><title>学员管理系统</title>
</head>
<body>
<h3><a href="/admin/">Admin</a></h3>
<ul>{% for student in students %}<li>{{ student.name }} - {{ student.get_status_display }}</li>{% endfor %}
</ul>
<hr />
<form action="/" method="post">{% csrf_token %}{{ form }}<input type="submit" value="Submit"/>
</form>
</body>
</html>

csrf_token如果没有这个,提交的数据是无效的,这可以用来防止跨站伪造请求攻击

访问127.0.0.1:8000看下效果

发现提交后没有报错 也没有显示新提交的信息,原因是字段非法,视图函数也没报错

注意到视图函数中包含了查询数据的操作,当需要过滤查询条件,或者需要缓存数据,都需要修改视图函数代码,此时可将数据获取逻辑封装到model中

模型层代码

class Student(models.Model):@classmethoddef get_all(cls):return cls.objects.all()# 省略其他代码

视图函数代码

def index(request):students = Student.all()

管理系统进阶开发

class-based view

当有多个类似的view函数,可以考虑使用class-based抽象

# urls.py
urlpatterns = [re_path(r'^$', index, name='index'),# re_path(r'^$', IndexView.as_view(), name='index'),path('admin/', admin.site.urls),
]
# views.py
class IndexView(View):template_name = 'index.html'def get_context(self):students = Student.get_all()context = {'students': students}return contextdef get(self, request):context = self.get_context()form = StudentForm()context.update({'form': form})return render(request, self.template_name, context=context)def post(self, request):form = StudentForm(request.POST)if form.is_valid():form.save()return HttpResponseRedirect(reverse('index'))context = self.get_context()context.update({'form': form})return render(request, self.template_name, context=context)

创建一个middleware练手,用来统计django接受请求到返回请求的时间

先创建文件middlewares.py,与views.py同级别

# middlewares.py
import timefrom django.urls import reverse
from django.utils.deprecation import MiddlewareMixinclass TimeItMiddleware(MiddlewareMixin):def process_request(self, request):self.start_time = time.time()returndef process_view(self, request, func, *args, **kwargs):if request.path != reverse('index'):return Nonestart = time.time()response = func(request)costed = time.time() - startprint('process view: {:.2f}s'.format(costed))return responsedef process_exception(self, request, exception):passdef process_tempmlate_response(self, request, response):return responsedef process_response(self, request, response):costed = time.time() - self.start_timeprint('request to response cost: {:.2f}s'.format(costed))return response

请求来和返回相应一般会按顺序调用这些函数:process_request, process_view, process_exception, process_template_response, process_response

process_request是请求来第一个处理函数,此函数可放些请求头校验等任务

process_view是process_request之后执行,用来执行view函数,func参数就是视图函数。可以在此处进行视图函数执行耗时统计

process_template_response 当拿到视图函数的返回函数,且返回函数为模板渲染的函数,则会执行该函数

process_response 当处理完模板渲染的视图函数后,会执行该方法

process_exception 当在视图函数处理过程或返回模板渲染时发生异常,才会执行proces_exception函数。但如果在process_view中手动调用func,就不会触发process_exception

middleware写完后,在settings中的MIDDLEWARE加上middleware

运行web,查看控制台打印访问耗时

写单元测试

运行单元测试时,django会创建一个基于内存的测试数据库,也就是说,这对生产部署的环境没有影响

但对于mysql数据库,django会直接用配置的数据库用户名和密码创建一个名为test_modelname_db的数据库用于测试,此时需要保证有见表和建数据库的权限

也可以在settings指定测试创建的数据库名

对于测试用例,django提供了一个名为TestCase的基类,可以继承这个类实现自己的测试用例。基类的方法和python的单元测试方法差不多

# models.py@propertydef sex_show(self):return dict(self.SEX_ITEMS)[self.sex]
# tests.py
from django.test import TestCase, clientfrom .models import Student# Create your tests here.
class StudentTestCase(TestCase):def setUp(self):Student.objects.create(name='tjh',sex=1,email='test@qq.com',profession='coder',qq='2222',phone='3333',)def test_create_and_sex_show(self):student = Student.objects.creat(name='tjh',sex=1,email='aaa@dd.com',profession='coder',qq='4444',phone='5555')self.assertEqual(student.sex_show, '男', "性别字段内容和展示不一致")def test_filter(self):student = Student.objects.creat(name='tjh',sex=1,email='aaa@dd.com',profession='coder',qq='4444',phone='5555')name = 'tjhaa'students = Student.objects.filter(name=name)self.assertEqual(students.count(), 1, 'student count should be 1')

view层测试

# tests.pydef test_get_index(self):client = Client()resp = client.get('/')self.assertEqual(resp.status_code, 200, 'status code should be 200')def test_post_student(self):client = Client()data = dict(name='test_for_post',sex=1,email='123@qq.com',profession='coder',qq='1111',phone='9999')resp = client.post('/', data)self.assertEqual(resp.status_code, 302, 'status code should be 302')resp = client.get('/')self.assertTrue(b'test_for_post' in resp.context, 'resp content should include test_for_post')

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

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

相关文章

(一)SVG行业组件库描述

SVG教程 https://m.runoob.com/svg/菜鸟教程SVG 教程..https://m.runoob.com/svg/ 1、SVGO 1.1 konw是什么 用于优化SVG文件的Node.js库和命令行应用程序。 SVG文件&#xff0c;特别是那些从矢量编辑器导出的文件&#xff0c;通常包含大量冗余信息。这包括编辑器元数据、注…

51单片机-LED点阵屏实验(动态显示数据静态显示)

第一步喝口汤 个人理解&#xff1a;首先&#xff0c;这个LED点阵屏类似于数码的段选操作&#xff0c;这个LED点阵屏第一步就是利用595芯片来扩充IO&#xff0c;单片595就是能够把一个字节数据通过串行输入&#xff08;一个IO输入&#xff09;&#xff0c;并行输出&#xff08;…

【微信小程序】搭建项目步骤 + 引入Tdesign UI

目录 创建1个空文件夹&#xff0c;选择下图基础模板 开启/支持sass 创建公共style文件并引入 引入Tdesign UI: 1. 初始化&#xff1a; 2. 安装后&#xff0c;开发工具进行构建&#xff1a; 3. 修改 app.json 4. 使用 5. 自定义主题色 创建1个空文件夹&#xff0c;选择下…

谈谈 JS 中new的原理与实现

new 做了那些事&#xff1f;new 返回不同的类型时会有什么表现&#xff1f;手写 new 的实现过程 new 关键词的主要作用就是执行一个构造函数、返回一个实例对象&#xff0c;在 new 的过程中&#xff0c;根据构造函数的情况&#xff0c;来确定是否可以接受参数的传递。下面我们通…

python图像类型分类汇总

图型所在包样例例图热图seabornimport matplotlib.pyplot as plt import seaborn as sns sns.heatmap(df.isnull()) plt.show() Bitmap Bitmap import numpy as np # 获取数据 fraud data_df[data_df[Class] 1] nonFraud data_df[data_df[Class] 0] # 相关性计算 cor…

使用 import-linter 让你的 Python 项目架构更整洁

对于活跃的大型 Python 项目而言&#xff0c;维持架构的整洁性是一件颇具挑战的事情&#xff0c;这主要体现在包与包、模块与模块之间&#xff0c;难以保持简单而清晰的依赖关系。 一个大型项目&#xff0c;通常包含数以百记的子模块&#xff0c;各自实现特定的功能&#xff0…

【路径规划】在MATLAB中使用粒子群优化(PSO)进行最优移动机器人路径规划

摘要 本文介绍了使用粒子群优化&#xff08;Particle Swarm Optimization, PSO&#xff09;算法实现移动机器人的路径规划。PSO是一种基于群体智能的优化算法&#xff0c;通过模拟粒子群体在搜索空间中的迭代更新&#xff0c;找到全局最优路径。本文通过MATLAB仿真展示了PSO在…

python-小理帮老师改错

题目描述 老师给小理发了一封电子邮件&#xff0c;任务如下。 写一个程序&#xff0c;给你 n 个数&#xff0c;输出 X。 Xnum1^p1​​num2^p2​​⋯numn^pn​​ num1​&#xff0c;num2​&#xff0c;⋯⋯&#xff0c;numn​ 都是整数&#xff0c;p1​&#xff0c;p2​&#xf…

重大突破 谷歌DeepMind展示GenRM技术:AI推理能力的新里程碑

引言&#xff1a; 近日&#xff0c;谷歌DeepMind团队在arxiv平台上发表了一项突破性论文&#xff0c;正式推出了GenRM技术&#xff0c;这一创新成果显著提升了AI在复杂任务处理中的能力表现&#xff0c;再次跨越了技术界限&#xff0c;为人工智能的推理能力树立了崭新的标杆。 …

HMI触屏网关-VISION如何和OPC UA服务端通信

上文&#xff1a;HMI触屏网关-VISION如何与Node-red通信-CSDN博客 1. 准备工作 1.1. 创建OPC UA服务端 在与OPC UA服务端进行通信时&#xff0c;首先要确认服务端已就绪&#xff0c;本示例使用辅助软件1模拟OPC UA服务端。 1.2. 创建模拟点位 1.3. 测试通信 辅助软件2&…

【C语言从不挂科到高绩点】10-C语言中数组 01

Hello&#xff01;彦祖们&#xff0c;俺又回来了&#xff01;&#xff01;&#xff01;&#xff0c;继续给大家分享 《C语言从不挂科到高绩点》课程!! 本节课开始重点给大家讲讲C语言中的数组 本套课程将会从0基础讲解C语言核心技术&#xff0c;适合人群&#xff1a; 大学中开…

苹果手机显示“连接iTunes”是什么意思?

在日常使用苹果手机的过程中&#xff0c;有时我们可能会遇到屏幕突然显示“连接iTunes”的提示&#xff0c;这让不少用户感到困惑和不安。今天&#xff0c;我们就来深度解析一下这个提示的含义&#xff0c;并为大家提供详细的解决方案。 一、显示“连接iTunes”的含义 当苹果…

CasaOS系统本地安装Gopeed高速下载软件并实现异地远程访问下载文件

文章目录 前言1. 更新应用中心2.Gopeed安装与配置3. 本地下载测试4. 安装内网穿透工具5. 配置公网地址6. 配置固定公网地址 前言 本文主要介绍如何在轻NAS系统CasaOS小主机中安装支持全平台的高速下载器Gopeed&#xff0c;并结合内网穿透工具配置公网地址实现远程访问本地主机…

Nginx部署前端vue项目操作步骤和方法~小皮

部署前端Vue.js项目到Nginx上&#xff0c;是开发流程中至关重要的一步&#xff0c;它意味着将静态文件托管在Web服务器上&#xff0c;使应用程序能够被用户访问和交互。下面将详细介绍如何使用Nginx部署前端Vue项目的操作步骤和方法&#xff1a; 准备构建Vue项目 安装Node.js和…

在BrowserStack上进行自动化爬虫测试的终极指南

一、背景介绍 随着互联网的快速发展&#xff0c;数据变得越来越宝贵&#xff0c;爬虫技术已成为从网页中提取信息的重要工具。然而&#xff0c;在不同的环境中测试和运行爬虫脚本可能会带来挑战。尤其是在多浏览器、多平台的环境中确保爬虫的稳定性和兼容性是一个令人头疼的问…

HTTP 之 消息结构(二十二)

HTTP&#xff08;超文本传输协议&#xff09;是一种用于传输超媒体文档的协议&#xff0c;它定义了客户端和服务器之间请求和响应的消息结构。HTTP消息由一系列标准头部字段、一个空行和可选的消息体组成。 客户端请求消息 请求消息包括以下格式&#xff1a;请求行&#xff08;…

Flask_admin—快速搭建访客登记系统Web管理后台

简介&#xff1a;在《App Inventor 2—自制身份证识别及人证比对验证系统》和《MySQL—访客登记系统数据库及Web服务搭建》的基础上&#xff0c;通过在云服务器上的Python程序中使用Flask_admin扩展&#xff0c;快速搭建数据库Web管理后台。通过整合上述实验&#xff0c;了解全…

希尔排序的图解展示与实现

什么是希尔排序 对整个数组进行预排序&#xff0c;即分组排序&#xff1a;按间距为gap分为一组&#xff0c;分组进行插入排序。 预排序的作用与特点 大的数更快地到后面&#xff0c;小的数更快地到前面&#xff1b; gap越大&#xff0c;跳得越快&#xff0c;排完接近有序慢&…

电脑浏览器显示代理服务器拒绝连接的解决办法

问题&#xff1a; 打开电脑浏览器显示代理服务器拒绝连接 解决办法&#xff1a; 1、按住winq键&#xff0c;输入代理&#xff0c;出现更改代理设置 2、将下面的自动检测设置、使用设置脚本、使用代理服务器都设置为关闭&#xff0c;刷新网页即可

人工智能 | 大语言模型应用框架介绍

简介 大语言模型的英文全称为&#xff1a;Large Language Model&#xff0c;缩写为 LLM&#xff0c;也被称为大型语言模型&#xff0c;主要指的是在大规模文本语料上训练、包含百亿级别参数的语言模型&#xff0c;它用来做自然语言相关任务的深度学习模型。 自然语言的相关任…