CentOS7下使用Docker安装Nacos 一、查看和nacos相关的镜像二、拉去镜像三、创建容器四、查看日志 一、查看和nacos相关的镜像 docker search nacos 二、拉去镜像 拉取 nacos/nacos-server:1.2.0 镜像
docker pull nacos/nacos-server:1.2.0 三、创建容器 docker run --env MODE=standalone --name nacos --restart=always -d -p 8848:8848 nacos/nacos-server:1.2.0 这是一个Docker命令,用于运行一个名为"nacos"的Nacos容器。具体参数解释如下:
--env MODE=standalone:设置环境变量MODE为standalone,表示以单机模式运行Nacos。--name nacos:为容器指定名称为"nacos"。--restart=always:设置容器在退出时自动重启。-d:以后台模式运行容器。-p 8848:8848:将容器的8848端口映射到宿主机的8848端口。nacos/nacos-server:1.2.0:指定要运行的Nacos镜像版本为1.2.0。 我在虚拟机上开放端口,在主机上用局域网访问http://192.168.223.10:8848/nacos/可以进入nacos主页后就是成功了
四、查看日志 docker logs -f 2cf20922a117 docker logs -f 2cf20922a117 这个命令用于实时查看名为 “2cf20922a117” 的 Docker 容器的日志。其中,-f 参数表示实时输出日志。
Cinema 4D 2024 for Mac是一款由德国Maxon Computer开发的专业三维建模、动画和渲染软件,广泛应用于电影、电视、广告、游戏、工业设计等多媒体制作领域。 它是一款功能强大的三维设计软件,提供丰富的建模、渲染、动画和特效工具,能够帮助设计师快速高效地创建复杂的模型、场景、动画和视觉效果。
Cinema 4D 2024 for Mac的建模工具包括强大的布尔运算、曲线和曲面建模、NURBS、多边形和子细分曲面等,可以帮助设计师创建各种形状和风格的模型。
它的渲染工具支持多种材质和纹理、多种渲染效果和模拟,包括全局光照、阴影、反射、折射、物理模拟等,可以帮助设计师创建逼真的渲染效果。
Cinema 4D 2024 for Mac还支持动态模拟和粒子效果,可以帮助设计师创建各种动画和特效。它还支持数字雕刻和细节处理工具,可以帮助设计师对模型进行细节处理。
Mac安装:Cinema 4D 2024 for mac(c4d 2024)v2024.1.0中文版
Win安装:Maxon Cinema 4D 2024(C4D 2024)v2024.1.0 (x64)特别版
在当今数字化时代,设计师们需要一个强大而灵活的工具来实现他们的创意。作为全球领先的设计软件提供商,Autodesk推出了全新的AutoCAD 2020,为设计师们打开了探索全新设计境界的大门。
AutoCAD 2020以其卓越的功能和直观的界面而闻名,为设计师们提供了丰富的工具和技术,帮助他们创造出精确、高效的设计作品。无论是建筑师、工程师还是室内设计师,AutoCAD 2020都能满足他们的需求。
首先,AutoCAD 2020引入了全新的DWG Compare功能,使设计师们能够快速比较不同版本的设计文件并查找差异。这将大大提高团队之间的协作效率,减少错误和重复工作。
其次,AutoCAD 2020还引入了全新的Purge功能,使设计师能够轻松清除不需要的图层、样式和块等元素,从而提高文件的整洁度和性能。
此外,AutoCAD 2020还增强了3D设计的功能,包括新的插入命令和实时修剪命令,使设计师能够更加方便地创建和编辑立体设计。
除了这些功能之外,AutoCAD 2020还提供了更快的性能和更强大的图形处理能力,使设计师能够更流畅地进行设计工作。
总之,Autodesk AutoCAD 2020是一个强大而全面的设计软件,无论是从功能还是性能方面,都能满足设计师们的需求。探索全新的设计境界,从现在开始使用AutoCAD 2020吧!
Mac安装:AutoCAD 2020 for Mac(cad设计绘图软件) 2020.3激活版
Win安装:Autodesk AutoCAD2020(附安装教程图解)激活特别版
介绍:
github地址:https://github.com/derronqi/yolov8-face
效果:
项目:
代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using OpenCvSharp; namespace FIRC { public partial class Form1 : Form { Mat src = new Mat(); FaceDetector fd = new FaceDetector(); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "图文件(*.*)|*.jpg;*.png;*.jpeg;*.bmp"; openFileDialog.RestoreDirectory = true; openFileDialog.
该内容还未完整,笔记内容,持续补充。
〇开发环境版本 vs2022
cmake3.21.1
ncnn20231027发行版
yolov5s v6.2(注意:这个版本是我目前模型转换通过的,其他版本自行测试)
vunlkan1.2.198.1
Protobuf3.20.0
Opencv3.4.1
一、模型转换 yolov5s v6.2训练的pt模型,直接导出tourchscript,然后使用ncnn里面的pnnx工具直接转换为ncnn。
这个地方别去pt转onnx转ncnn的了,踩了多少坑才出来的,有能力的可以去踩。
官方文档:
https://github.com/pnnx/pnnxhttps://github.com/pnnx/pnnx
导出tourchscript使用yolov5里面export.py
tourchscript转pnnx命令(pnnx可以自己编译也可以直接下载ncnn-windows里面有编译好的):
pnnx.exe best.torchscript inputshape=[1,3,640,640] 二、部署环境(该部分内容待修改,最新版本ncnn无需vunlkan可直接编译;) 注意:cmake编译需要使用x64 Native Tools Command Prompt for VS 2022工具里面,cmd是没效果的。
直接拉取GitHub源码,然后更新完整代码。
git clone https://github.com/Tencent/ncnn.git cd ncnn git submodule update --init 1.安装vunlkan 1.2.198.1版本,记得配置环境变量
官网下载(只有最新版,而且特别慢):
https://vulkan-tutorial.com/https://vulkan-tutorial.com/
GitHub下载:
https://github.com/KhronosGroup/Vulkan-Loaderhttps://github.com/KhronosGroup/Vulkan-Loader
2.安装Protobuf3.20.0版本
源码下载地址:
https://github.com/protocolbuffers/protobuf/releases/download/v3.20.0/protobuf-cpp-3.20.0.tar.gzhttps://github.com/protocolbuffers/protobuf/releases/download/v3.20.0/protobuf-cpp-3.20.0.tar.gz
官方文档:
https://github.com/Tencent/ncnn/wiki/FAQ-ncnn-protobuf-problem.zhhttps://github.com/Tencent/ncnn/wiki/FAQ-ncnn-protobuf-problem.zh
编译Protobuf命令 :
mkdir build_vs cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF ../cmake nmake nmake install 3.编译ncnn
下载ncnn完整源码:
https://github.com/Tencent/ncnn/releaseshttps://github.com/Tencent/ncnn/releases
在使用机器学习构建预测模型时,我们不只是想知道“预测值(点预测)”,而是想知道“预测值落在某个范围内的可能性有多大(区间预测)”。例如当需要进行需求预测时,如果只储备最可能的需求预测量,那么缺货的概率非常的大。但是如果库存处于预测的第95个百分位数(需求有95%的可能性小于或等于该值),那么缺货数量会减少到大约20分之1。
获得这些百分位数值的机器学习方法有:
scikit-learn:GradientBoostingRegressor(loss='quantile, alpha=alpha)LightGBM: LGBMRegressor(objective='quantile', alpha=alpha)XGBoost: XGBoostRegressor(objective='reg:quantileerror', quantile_alpha=alpha) (version 2.0~) 这种”预测值落在某个范围内的可能性有多大(区间预测)”的方法都被称作分位数回归,上面的这些机器学习的方法是用了一种叫做Quantile Loss的损失。
Quantile loss是用于评估分位数回归模型性能的一种损失函数。在分位数回归中,我们不仅关注预测的中心趋势(如均值),还关注在分布的不同分位数处的预测准确性。Quantile loss允许我们根据所关注的分位数来量化预测的不确定性。
假设我们有一个预测问题,其中我们要预测一个连续型变量的分布,并且我们关注不同的分位数,例如中位数、0.25分位数、0.75分位数等。对于第q分位数,Quantile Loss定义为:
这里:
yy 是真实值。yy 是模型的预测值。qq 是目标分位数,取值范围为0,10,1。 这个损失函数的核心思想是,当模型的预测值超过真实值时,损失是预测值与真实值的差值乘以q。当预测值低于真实值时,损失是预测值与真实值的差值乘以1−q。这确保了对于不同的分位数,我们有不同的惩罚。如果我们更关心较小分位数(例如,中位数),我们会设定较小的q,反之亦然。
用Pytorch实现分位数损失 下面是一个使用Pytorch将分位数损失定义为自定义损失函数的示例。
importtorch defquantile_loss(y_true, y_pred, quantile): errors=y_true-y_pred loss=torch.mean(torch.max((quantile-1) *errors, quantile*errors)) returnloss 对于训练来说,跟正常的训练方法一样:
for epoch in range(num_epochs): for batch_x, batch_y in dataloader: optimizer.zero_grad() outputs = model(batch_x) loss = quantile_loss(outputs, batch_y, quantile) loss.backward() optimizer.step() 让我们看看这个自定义的损失函数是否如预期的那样工作。
Pytorch分位数损失测试 首先,我们尝试为x生成均匀随机分布(-5~5),为y生成与x指数成比例的正态随机分布,看看是否可以从x预测y的分位数点。
# Generate dummy data num_samples = 10000 shape = (num_samples, 1) torch.
其他系列文章导航 Java基础合集
数据结构与算法合集
设计模式合集
多线程合集
分布式合集
ES合集
文章目录 其他系列文章导航
文章目录
前言
一、ECharts:现代数据可视化的利器
二、Excel:经典的数据处理与分析工具
三、ECharts与Excel的结合:火花碰撞
3.1 柱状图前端代码
3.2 饼图前端代码
3.3 后端通用代码
3.3.1 生成Excel表格
3.3.2 Excel表格数据导入ECharts
四、总结
前言 在数据爆炸的时代,如何有效地呈现和解析数据变得至关重要。
ECharts和Excel作为两种广泛使用的数据处理和可视化工具,各自拥有其独特的魅力和功能。
本文将深入探讨这两者之间的火花碰撞,以及如何结合它们以实现更强大的数据可视化效果。
一、ECharts:现代数据可视化的利器 ECharts是一款开源的数据可视化库,提供丰富的图表类型和高度定制化的选项。
ECharts支持折线图、柱状图、散点图、饼图等多种图表类型,并且可以根据需要轻松定制颜色、标签、提示框等视觉元素。
此外,ECharts还支持动态数据更新和高性能渲染,使其成为现代数据可视化的理想选择。
二、Excel:经典的数据处理与分析工具 Excel作为微软办公套件的核心组件,已经成为全球范围内广泛使用的数据处理和分析工具。
通过Excel,用户可以进行数据的排序、筛选、函数计算和可视化等多种操作。
Excel提供了丰富的图表类型和数据分析工具,使得用户能够轻松地进行数据处理和可视化工作。
三、ECharts与Excel的结合:火花碰撞 尽管ECharts和Excel都是强大的数据处理和可视化工具,但它们各有优缺点。将两者结合起来,可以取长补短,实现更强大的数据可视化效果。以下是一些结合ECharts和Excel的方法:
数据导入与处理:使用Excel进行数据清洗和处理,然后将处理后的数据导入ECharts进行可视化。这样可以充分发挥Excel在数据处理方面的优势,同时利用ECharts丰富的图表类型进行可视化。动态数据更新:在Excel中创建图表后,可以利用ECharts的动态数据更新功能,实时将最新数据传递给图表。这样可以实现数据的动态展示,使得图表更加生动和具有实时性。交互式数据探索:结合ECharts的交互式特性,可以在Excel中实现交互式的数据探索和分析。用户可以通过点击、拖拽等方式在图表上进行操作,获取更多关于数据的洞察。自定义图表类型:ECharts支持高度定制化的图表类型,而Excel也提供了丰富的图表模板。通过结合两者,可以创建出既满足个性化需求又具有专业视觉效果的图表。数据驱动的故事叙述:利用ECharts和Excel的组合,可以创建数据驱动的故事叙述。通过精心设计的图表和数据分析,将数据背后的故事生动地呈现给观众。 接下来通过两个例子给大家演示具体的实现!
3.1 柱状图前端代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>echarts-bar</title> <script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script> <script src="js/echarts.min.js"></script> <script src="../../plugins/element-ui/index.js"></script> </head> <body> <!-- 为ECharts准备一个具备大小(宽高)的Dom --> <div id="main" style="width:2000px; height:700px;"></div> <button onclick="generateExcel()">导出Excel文件</button> <script type="
基于springboot电商平台 摘 要
随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于电商平台当然也不能排除在外,随着网络技术的不断成熟,带动了电商平台,它彻底改变了过去传统的管理方式,不仅使服务管理难度变低了,还提升了管理的灵活性。这种个性化的平台特别注重交互协调与管理的相互配合,激发了管理人员的创造性与主动性,对电商平台而言非常有利。
本论文主要论述了如何使用java语言开发一个springboot电商平台,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述电商平台的当前背景以及系统开发的目的,后续章节将严格按照软件开发流程,对系统进行各个阶段分析设计。
关键字:电商平台 Mysql数据库 springboot框架
Abstract
With the rapid development of science and technology, all walks of life are trying to integrate with modern advanced technology and improve their own advantages through scientific and technological means; Of course, e-commerce platforms cannot be excluded. With the continuous maturity of network technology, e-commerce platforms have been driven. It has completely changed the traditional management methods in the past, not only making service management less difficult, but also improving the flexibility of management.
ssm 旅游网站管理系统
摘 要
信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对旅游网站等问题,对旅游网站进行研究分析,然后开发设计出旅游网站管理系统已解决问题。
旅游网站管理系统主要功能模块包括首页、网站管理(轮播图、公告信息)人员管理(管理员、系统用户)内容管理(交流论坛、论坛分类、旅游文化、文化分类)模块管理(景点信息、购票信息、旅游路线、酒店信息、类型管理、预订信息、咨询客服),采取面对对象的开发模式进行软件的开发和硬体的架设,能很好的满足实际使用的需求,完善了对应的软体架设以及程序编码的工作,采取Mysql作为后台数据的主要存储单元,采用SSM框架、Java技术、Ajax技术进行业务系统的编码及其开发,实现了本系统的全部功能。本次报告,首先分析了研究的背景、作用、意义,为研究工作的合理性打下了基础。针对旅游网站管理系统的各项需求以及技术问题进行分析,证明了系统的必要性和技术可行性,然后对设计系统需要使用的技术软件以及设计思想做了基本的介绍,最后来实现旅游网站管理系统和部署运行使用它。
关键词:旅游网站;ssm框架;Mysql数据库
SSM Tourism Website Management System
Abstract
In the information society, there is a need for targeted information acquisition channels, but the expansion of channels is basically the direction of people's efforts. Due to the deviation in perspective, people often can obtain different types of information, which is also the most difficult topic for technology to overcome. Research and analyze tourism websites and other issues, and then develop and design a tourism website management system to solve the problem.
一、常见的漏洞利用框架
Metasploit Framework:一个广泛使用的开源漏洞利用框架,用于测试和评估系统的安全性。
ExploitDB:一个在线漏洞利用数据库,包含各种漏洞的利用代码。
Canvas:由Immunity开发的商业漏洞利用框架,提供高级的漏洞利用技术和功能,用于渗透测试和漏洞研究。
Core Impact:一款商业漏洞利用框架,用于对网络和应用程序进行安全评估和渗透测试。
Cobalt Strike:一款商业网络攻击模拟工具,具有强大的漏洞利用和社会工程学功能,用于模拟真实的攻击场景。
BeEF:一个开源的漏洞利用框架,专注于浏览器和Web应用程序的漏洞利用和攻击。
Social Engineer Toolkit(SET):一个开源的社会工程学框架,提供了各种用于欺骗和攻击目标的工具和模块。
PowerSploit:一个适用于Windows系统的开源漏洞利用框架,提供了各种漏洞利用模块和攻击技术。
RouterSploit:一个专注于路由器漏洞利用的开源框架,用于测试和评估网络设备的安全性。
SETUID:一个开源的Unix/Linux漏洞利用框架,专注于利用特权升级和系统漏洞。
Bettercap:一个功能强大的网络攻击和嗅探工具,提供了各种中间人攻击和漏洞利用功能。
SocialFish:一个开源的社交工程框架,用于进行钓鱼攻击和收集用户凭据。
Armitage:Metasploit的一个图形化前端工具,用于管理和执行漏洞利用。
XSStrike:一个开源的自动化Web漏洞扫描器,用于检测和利用跨站脚本漏洞。
Wireshark:一个流行的网络分析工具,用于捕获和分析网络数据包,帮助发现漏洞和安全问题。
Nmap:一个强大的端口扫描工具,用于快速检测目标系统的开放端口和服务信息。
Nikto:一个常用的Web服务器漏洞扫描工具,可以自动化地检测服务器配置错误、已知漏洞和常见的安全问题。
Nessus:一个广泛使用的漏洞扫描工具,提供了大量的漏洞检测插件和安全配置审计功能。
OpenVAS:一个开源的漏洞扫描器,提供类似于商业漏洞扫描工具的功能,用于评估系统的安全性并提供修复建议。
Wfuzz:一个快速的Web应用程序漏洞扫描器,支持多种协议和漏洞类型,并提供了灵活的定制化选项。
THC Hydra:一个流行的登录破解工具,支持多种协议和服务,例如FTP、SSH、Telnet和SMTP。
Aircrack-ng:一个著名的WiFi密码破解工具,可以破解WEP和WPA/WPA2加密的无线网络密码。
BlackWidow:一个功能强大的Web应用程序漏洞扫描器,支持多种漏洞检测和利用模块,并提供了自定义选项。
Empire:一个开源的后渗透测试框架,提供了一系列强大的漏洞利用、持久化和管理工具,用于控制受攻击系统。
CrackMapExec:一个开源的网络渗透工具,主要用于利用Windows网络环境中的漏洞,获取系统访问权限。
Skipfish:一个快速的Web应用程序漏洞扫描器,使用先进的技术和算法来发现隐藏的漏洞。
Hydra:一个强大的网络登录破解工具,支持多种协议和服务,例如FTP、SSH、Telnet、SMTP等。
Sqlninja:一个专注于SQL注入漏洞利用的工具,能够绕过认证和审计控制,并提供后门访问功能。
Volatility:一个开源的内存取证工具,支持多种操作系统和文件格式,并提供了各种内存分析和漏洞利用功能。
FuzzDB:一个开源的漏洞利用载荷库,包含各种用于模糊测试和漏洞利用的有效载荷和模板。
Rouge:一个专注于路由器漏洞利用的开源框架,用于进行渗透测试和安全评估。
AutoSploit:一个开源的自动化漏洞利用工具,根据目标系统和漏洞信息自动选择和执行合适的漏洞利用模块。
SQLMap:一个开源的自动化SQL注入工具,用于检测和利用Web应用程序中的SQL注入漏洞。
Router Exploitation Framework(Rouge):一个专注于路由器漏洞利用的开源框架,用于进行渗透测试和安全评估。
二、下载或者官方地址
Metasploit Framework:https://www.metasploit.com/
ExploitDB:https://www.exploit-db.com/
Canvas:https://www.immunityinc.com/products/canvas/
Core Impact:https://www.coresecurity.com/core-impact-pro
Cobalt Strike:https://www.cobaltstrike.com/
BeEF:https://beefproject.com/
Social Engineer Toolkit(SET):https://github.com/trustedsec/social-engineer-toolkit
PowerSploit:https://github.com/PowerShellMafia/PowerSploit
RouterSploit:https://github.com/threat9/routersploit
SETUID:https://github.com/OlivierLaflamme/Cyberhebdo
Bettercap:https://www.bettercap.org/
SocialFish:https://github.com/UndeadSec/SocialFish
Armitage:https://www.metasploitunleashed.com/armitage/
XSStrike:https://github.com/s0md3v/XSStrike
Wireshark:https://www.wireshark.org/
Nmap:https://nmap.org/
Nikto:https://cirt.net/Nikto2
Nessus:https://www.tenable.com/products/nessus
OpenVAS:http://www.openvas.org/
Wfuzz:https://github.com/xmendez/wfuzz
生成密钥对: #include <stdio.h> #include <string.h> #include <stdlib.h> #include "e_os.h" #include "sm2ToOC.h" #include "string.h" # include <openssl/bn.h> # include <openssl/ec.h> # include <openssl/evp.h> # include <openssl/rand.h> # include <openssl/engine.h> # include <openssl/sm2.h> # include "sm2_lcl.h" # include "pkcs12.h" #include <openssl/pem.h> #include "ec/ec_lcl.h" #include "bn/bn_lcl.h" int genkey() { EC_KEY *keypair = NULL; EC_GROUP *group1 = NULL; keypair = EC_KEY_new(); if(!keypair) { printf("Failed to Gen Key"); exit(1); } group1 = EC_GROUP_new_by_curve_name(NID_sm2p256v1); if(group1 == NULL){ printf("
目录
前言
一、技术栈
二、系统功能介绍
前台首页功能模块
管理员功能模块
三、核心代码
1、登录模块
2、文件上传模块
3、代码封装
前言 随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,汽车评论分类系统当然也不能排除在外。汽车评论分类系统是以实际运用为开发背景,运用软件工程开发方法,采用SpringBoot技术构建的一个管理系统。整个开发过程首先对软件系统进行需求分析,得出系统的主要功能。接着对系统进行总体设计和详细设计。总体设计主要包括系统总体结构设计、系统数据结构设计、系统功能设计和系统安全设计等;详细设计主要包括模块实现的关键代码,系统数据库访问和主要功能模块的具体实现等。最后对系统进行功能测试,并对测试结果进行分析总结,及时改进系统中存在的不足,为以后的系统维护提供了方便,也为今后开发类似系统提供了借鉴和帮助。
本汽车评论分类系统采用的数据库是Mysql,使用SPRINGBOOT框架开发。在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。
一、技术栈 末尾获取源码
SpringBoot+Vue+JS+ jQuery+Ajax...
二、系统功能介绍 前台首页功能模块 汽车评论分类系统,在汽车评论分类系统可以查看首页、热门分类、新品分类、交流论坛、系统公告、个人中心、后台管理等内容
登录、用户注册,通过用户注册获取用户名、密码、姓名、性别、手机、邮箱等信息进行注册、登录
热门分类,在热门分类页面可以填写汽车名称、类型、品牌、发行日期等信息进行提交
新品分类,在新品分类页面可以填写汽车名称、品牌、点击次数等信息进行提交
交流论坛,在交流论坛页面可以填写标题、类型等信息进行提交
管理员功能模块 管理员登录,通过填写用户名、密码、角色等信息,输入完成后选择登录即可进入汽车评论分类系统
管理员登录进入汽车评论分类系统可以查看首页、个人中心、汽车类型管理、热门分类管理、新品分类管理、用户管理、管理员管理、交流论坛、系统管理等内容
汽车类型管理,在汽车类型管理页面可以查看类型等信息,并可根据需要对汽车类型管理进行详情,修改,删除或查看详细内容等操作
管理员在热门分类管理页面可以查看汽车名称、类型、图片、品牌、发行日期、视频介绍等信息,并可根据需要对热门分类管理进行详情,删除或查看详细内容等操作
新品分类管理,在新品分类管理页面可以查看汽车名称、类型、图片、品牌、视频介绍等信息,并可根据需要对新品分类管理进行详情,删除或查看详细内容操作
用户管理,在用户管理页面可以查看用户名、密码、姓名、性别、头像、手机、邮箱等内容,并可根据需要对用户管理进行详情、修改、删除操作
管理员管理,在管理员管理页面可以查看用户名、密码、角色等信息,并可根据需要对管理员管理进行详情,修改,删除操作
交流论坛,在交流论坛页面可以查看帖子标题、用户名、状态等内容,并可根据需要对交流论坛进行详情,修改,删除操作
轮播图;该页面为轮播图管理界面。管理员可以在此页面进行首页轮播图的管理,通过新建操作可在轮播图中加入新的图片,还可以对以上传的图片进行修改操作,以及图片的删除操作
三、核心代码 1、登录模块 package com.controller; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import com.
格式化之前的代码:
import matplotlib.pyplot as plt#绘图 import pandas as pd#读取数据集 from sklearn.preprocessing import scale from sklearn.cluster import DBSCAN#聚类 from sklearn import preprocessing#数据预处理的功能,包括缩放、标准化、正则化等 plt.rcParams["font.sans-serif"] = "Microsoft Yahei"#字体 df = pd.read_csv("country.txt",sep="\t") num_data = df[["面积km^2", "人口"]] X = preprocessing.minmax_scale(num_data,feature_range=(0,10000))#最小-最大缩放是一种常用的数据预处理方法,它将原始数据线性地缩放到给定的范围内,feature_range=(0,10000)指定了缩放后的特征值范围为0到10000。这意味着最小值将被缩放到0,最大值将被缩放到10000,而其他值将按比例缩放以保持数据的分布。 model = DBSCAN(eps=2000,min_samples=3)#DBSCAN是scikit-learn库中的一个聚类算法模型,eps=2000表示DBSCAN算法中的邻域半径,指定了两个样本被视为同一簇的最大距离。如果两个样本之间的距离小于等于eps,则这两个样本被认为是相邻的,min_samples=3表示DBSCAN算法中的核心点的最小样本数。当一个样本的邻域内包含至少min_samples个样本点时,该样本被认为是核心点。 model.fit(X) label = model.labels_ plt.figure(figsize=(5,5)) print(label) for i in df[label == -1].index: plt.scatter(df.loc[i,'面积km^2'],df.loc[i,"人口"],color = 'red')#绘图 plt.annotate(text=df.loc[i,"国家"],xy=(df.loc[i,'面积km^2'],df.loc[i,"人口"]))#注释 for i in df[label == 0].index: plt.scatter(df.loc[i,'面积km^2'],df.loc[i,"人口"],color = 'blue') plt.annotate(text=df.loc[i,"国家"],xy=(df.loc[i,'面积km^2'],df.loc[i,"人口"]))#df.loc用于按标签进行索引,i是索引值 for i in df[label == 1].
文章概叙 本文主要是介绍下在作为page以及component的时候的生命周期,以及调用API等应该在哪个生命周期使用。
书接上回 之前的博客已经结束了对底部栏的操作,现在开始需要关注到具体内容的对接了。
而开发的第一步,我们对页面的生命周期必须要有很深入的了解,因为有开发经验的同学们都知道,做前端开发的时候,我们获取数据API的接口,都是在页面创建完成时调用,而在页面即将被销毁的时候,我们需要去关闭定时器、数据监听等操作。所以我们必须知道在哪个阶段,我们应该做什么。这些可都是面试的知识点来的。
综上述,本篇博客最主要的内容是讲下生命周期,以及在开发的时候,我们调用API,初始化一些数据的操作应该在哪些生命周期中进行。
页面与自定义组件的区别 自定义组件:@Component装饰的UI单元,可以组合多个系统组件实现UI的复用,可以调用组件的生命周期。
页面:即应用的UI页面。可以由一个或者多个自定义组件组成,@Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。只有被@Entry装饰的组件才可以调用页面的生命周期。
像是我们的Mine以及Found组件,由于想要做到不使用tab的时候,也可以正常的访问,所以我们在其中加入了@Entry的修饰符,使其属于页面。
而文章中为什么要区分是否为页面组件,官网上也给出了具体原因,是因为页面组件以及自定义组件各有一套生命周期。
页面生命周期,即被@Entry装饰的组件生命周期,提供以下生命周期接口:
onPageShow 页面每次显示时触发一次,包括路由过程、应用进入前台等场景,仅@Entry装饰的自定义组件生效。
onPageHide 页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景,仅@Entry装饰的自定义组件生效。
onBackPress 当用户点击返回按钮时触发,仅@Entry装饰的自定义组件生效。
即当页面被切换显示的时候,各监听一次,当用户点击了返回按钮的时候,也会触发一次事件。
所以我们可以这么地去理解:
当onPageShow触发,既显示页面的时候,我们可以去拉数据显示出来
当onPageHide触发,即隐藏页面的时候,我们可以停止当前的一些操作,比如计时之类的。
当onBackPress触发,即用户想要退出当前页面的时候,我们就可以询问用户是否离开页面,以便做保存的操作。
而在@component修饰的组件中,还有一下两种方法
aboutToAppear 组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。
aboutToDisappear 在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。
也就是说,对于一些内部组件来说,并没有刚刚@Entry修饰器的返回、显示、隐藏之类的,所以我们在显示组件的时候,就只有以下两个生命周期:
当组件已经被实例化,但是还没显示在页面上的时候。aboutToAppear会被调用。
当组件即将被销毁的时候,aboutToDisappear会被调用。
而@Entry修饰的页面,则会含有上述的五个生命周期,
即下面的图
开始代码 在对生命周期有了基础准备工作之后,我们接下来只需要实验一些其中的生命周期,看是否符合我们的想法。
就拿我们的Mine页面做一次测试,测试代码如下,将五个都添加到了mine.ets中,接着从tab页面访问进入.
@Entry @Component export struct Mine { @State message: string = '这个是mine页面' onPageShow() { console.log("当前调用了pageShow方法") } onPageHide(){ console.log("当前调用了pageHide方法") } onBackPress(){ console.log("当前调用了onBackPress方法"); } aboutToAppear(){ console.log("当前调用了aboutToAppear方法"); } aboutToDisappear(){ console.log("当前调用了aboutToDisappear方法") } build() { Row() { Column() { Text(this.
目录
一、注意力机制
二、了解发展历程
2.1 早期萌芽:
2.2 真正意义的注意力机制:
2.3 2015 年及以后:
2.4 自注意力与 Transformer:
2.5 BERT 与预训练模型:
三、基本框架
1. 打分函数(Score Function)
2. 校准函数(Alignment Function / Softmax)
3. 融合(Fusion / Weighted Sum)
比如机器翻译任务
四、分类
4.1 根据注意力的计算区域分类
4.2 根据注意力的可微性分类
4.3 根据注意力的来源分类
4.4 根据注意力的层次结构分类
4.5 其他形式的注意力模型
一、注意力机制 从人工智能专家的角度来看,注意力机制(Attention Mechanism)是一种在深度学习模型中,尤其是在处理序列数据(如文本、语音、时间序列等)时非常重要的技术。其核心思想是让模型在处理信息时能够“集中注意力”在更相关的部分,而忽略不那么重要的信息。
视觉注意力机制是人类视觉所特有的大脑信号处理机制。人类视觉通过快速扫描全局图像,获得需要重点关注的目标区域,也就是一般所说的注意力焦点,而后对这一区域投入更多注意力资源,以获取更多所需要关注目标的细节信息,而抑制其他无用信息。这是人类利用有限的注意力资源从大量信息中快速筛选出高价值信息的手段,是人类在长期进化中形成的一种生存机制,人类视觉注意力机制极大地提高了视觉信息处理的效率与准确性。计算机视觉中的注意力机制从本质上讲和人类的选择性视觉注意力机制类似,核心目标也是从众多信息中选择出对当前任务目标更关键的信息。
以下是注意力机制的一些关键要点:
直观理解:想象一下你正在阅读一篇文章。你不会一字不漏地看完每一个字,而是会集中注意力在那些对你而言最重要或最相关的词或句子上。这就是注意力机制希望模拟的行为。
工作原理:在深度学习模型中,注意力机制通常通过计算一个权重分布来实现。这个分布决定了在生成输出时,输入序列中的哪些部分应该被更多地关注。例如,在机器翻译任务中,生成目标语言的一个词时,模型可能会更多地关注源语言中与之对应的词或短语。
数学表达:给定一个查询(Query)和一个键值对集合(Key-Value pairs),注意力机制可以计算出一个加权的输出。查询、键和值通常都是向量。输出的计算通常涉及查询与每个键的点积,然后应用一个softmax函数来得到权重分布,最后用这个分布加权所有的值来得到最终的输出。
类型:有多种注意力机制,包括但不限于:
全局注意力与局部注意力:全局注意力考虑输入序列的所有位置,而局部注意力只关注输入序列的特定子集。自注意力(Self-Attention):在自注意力中,查询、键和值都来自同一个输入序列。这种机制在Transformer模型中得到了广泛应用。多头注意力(Multi-Head Attention):在这种机制中,多个独立的注意力模块并行运行,并将它们的输出拼接或平均起来,以捕获输入数据的不同方面。 优势与应用:注意力机制可以提高模型的可解释性(因为可以看到模型关注了哪些输入),并允许模型处理变长输入序列。它们在各种NLP任务中都取得了巨大成功,如机器翻译、问答系统、情感分析和文本摘要等。此外,注意力机制也被应用于其他领域,如计算机视觉和语音识别。
二、了解发展历程 2.1 早期萌芽: 在深度学习兴起之前,注意力机制的思想已经在一些传统的机器学习模型中有所体现,比如隐马尔可夫模型(HMM)中的对齐(Alignment)概念,但这并不算是真正的“注意力”。 2.2 真正意义的注意力机制: 注意力机制在深度学习中的首次明确提出通常与 Bahdanau 等人在 2014 年的工作《Neural Machine Translation by Jointly Learning to Align and Translate》相关联。在这篇论文中,作者们为机器翻译任务引入了一种名为“加性注意力”(Additive Attention)的机制,允许模型在生成目标语言句子时自动搜索源语言句子中的相关部分。这种方法极大地改善了之前基于编码-解码(Encoder-Decoder)架构的机器翻译系统的性能,尤其是当处理长句子时。 2.
背景 起因是线上报了一个错误信息,Deadlock found when trying to get lock; try restarting transaction,这是Mysql检测到死锁后,自动回滚了事务引发的异常。spring框架里打印了异常堆栈,所以很快就定位到哪一行代码出了问题。
业务的伪代码如下:
val result = query("select * from game where user_id = xx and game_id = xx") if (result == null) { excute("Insert Into game_player(game_id,user_id) Values(?,?)") } -- table schema create table game ( id bigint, game_id bigint, user_id bigint, primary key(id), constraint unique_game_id_user_id unique (game_id, user_id) ) 看了代码逻辑,只有insert的时候会加一个行锁,死锁要有两个锁被多个线程账户等待,才会发生。就算有并发的情况,同时插入两条一样的记录,第二个事务也是处于等待锁的状态,等待锁超时后就报获取锁超时,也不会发生死锁。
查看死锁信息 然后通过show engine innodb status命令看一下死锁的相关信息。
------------------------ LATEST DETECTED DEADLOCK ------------------------ 2023-12-29 05:43:26 22399693092608 *** (1) TRANSACTION: TRANSACTION 3701497, ACTIVE 29 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 4 lock struct(s), heap size 1128, 2 row lock(s), undo log entries 1 MySQL thread id 43921, OS thread handle 22399139387136, query id 225853288 122.
在C++中,循环结构中变量的生命周期取决于变量的作用域和声明位置。
for(int i = 0; i < 5; i++) //i为循环变量,在循环结构刚开始时被创建,在整个循环结构结束时被销毁 { int x = i; // x为循环体中的变量,在每次开始循环体时会被创建,在每次结束循环体时会被销毁 cout << x << endl; } 1.循环体中的变量的生命周期:在循环结构的循环体中的变量会在每次循环体开始时被创建,在每次循环体结束时被销毁。
2.循环变量i的生命周期:在 C++ 的 for 循环中,循环变量(如 i)在循环开始时被定义一次,然后在每次循环迭代时更新其值。这个变量的生命周期是整个 for 循环,当整个循环结束时,i 的生命周期也就结束了。
参考视频:Word公式录入+自动编号
视频没有详细介绍word 域相关的用法,自己试了好几遍总结了一些要点,记录一下。
首先是插入域的快捷键:ctrl+f9
也就是先在章节标题的光标末尾按下插入域的快捷键,输入视频指示的公式。{SEQ seg \h } {SEQ eq \r \h}
然后在每个章节的公式光标后面同样按下插入键,根据视频指示输入{SEQ seq \c}-{SEQ eq}
注意,这时将光标移动到公式的最后但不要出公式框,按下回车。这时候应该能看到之前输入的那些公式现在右对齐了。
接下来需要进入域模式并退出域。
进入域和退出域用同一个快捷键alt+f9
按两次alt+f9就可以看到公式后面是一个编号了,让编号正常的方式是选中含有公式编号的文本,右键更新域,就可以看到自动编号了。
ps:还有一个常用快捷键,有时候需要检查之前输入的域公式是否正确,除了可以alt+f9进入域模式查看域代码外,还可以按下shift+f9显示光标处的局部域代码。适合局部检查。
系列文章 一、逆向工程
Sketchup 逆向工程(一)破解.skp文件数据结构
Sketchup 逆向工程(二)分析三维模型数据结构
Sketchup 逆向工程(三)软件逆向工程从何处入手
Sketchup 逆向工程(四)破解的乐趣 钩子 外挂 代码注入
二、OpenGL渲染模型
Python+OpenGL绘制3D模型(一)Python 和 PyQt环境搭建
Python+OpenGL绘制3D模型(二)程序框架PyQt5
Python+OpenGL绘制3D模型(三)程序框架PyQt6
Python+OpenGL绘制3D模型(四)绘制线段
Python+OpenGL绘制3D模型(五)绘制三角型
Python+OpenGL绘制3D模型(六)材质文件载入和贴图映射
Python+OpenGL绘制3D模型(七)制作3dsmax导出插件
Python+OpenGL绘制3D模型(八)绘制插件导出的插件
Python+OpenGL绘制3D模型(九)完善插件功能: 矩阵,材质,法线
Python+OpenGL 杂谈(一)
三、成果
疫情期间关在家里实在没事干,破解了Sketchup,成功做出可以读取并显示.skp文件的程序SuViewer
前言 Sketchup作为目前设计院最为流行的设计软件(非工程制图软件),深受设计师的喜爱,软件小巧,而功能强大,有不少为之开发的插件应运而生,不过呢,关于底层数据结构和工作原理相关的文章少之又少,本文意在填补一下这方面的空缺,通过逆向软件分析,展示软件内部奥秘。本文用到的工具:IDA Pro,Immunity Debugger,Visual Studio (逆向工程三件套)数据结构属于知识产权的核心机密:
Python+OpenGL绘制3D模型(六)材质文件载入和贴图映射 运行效果:
文章目录 系列文章前言Python+OpenGL绘制3D模型(六)材质文件载入和贴图映射一、从文件读取贴图二、glBindTexture三、指定贴图坐标四、运行图效果五、2个问题和原因六、源代码1、Draw1.py2、tOpenGLqt5.py 系列文章预告 一、从文件读取贴图 记得以前用c++写的时候,要编译链接图像库,用于对应图片格式的加载,每个用到的格式都要单独搞一遍,在网上找开源的图片库,下载,编译,测试,一套下来搞的人很累,现在,因为有Qt的加持,载入贴图变得非常简单,全部交给Qt来做,只需要几行代码
def load_texture_from_file( filepath ): with open(filepath, 'rb') as hf: data = hf.read() image = QImage() valid = image.loadFromData(data) if not valid: return False gl_tex_obj = QOpenGLTexture(image.mirrored()) return gl_tex_obj 图片载入到Qt后,还需要调用OpenGL的库加载贴图数据,另外Qt的图片坐标Y轴是向下增加的,符合显示屏幕坐标的习惯,而OpenGL中的Y轴坐标是正常向上的,所以Y轴需要mirror处理一下
【题目来源】
https://www.luogu.com.cn/problem/P1086
https://www.acwing.com/problem/content/description/420/
【题目描述】
鲁宾逊先生有一只宠物猴,名叫多多。这天,他们两个正沿着乡间小路散步,突然发现路边的告示牌上贴着一张小小的纸条:“欢迎免费品尝我种的花生! ——熊字”。
鲁宾逊先生和多多都很开心,因为花生正是他们的最爱。
在告示牌背后,路边真的有一块花生田,花生植株整齐地排列成矩形网格(如图 1)。
有经验的多多一眼就能看出,每棵花生植株下的花生有多少。
为了训练多多的算术,鲁宾逊先生说:“你先找出花生最多的植株,去采摘它的花生;然后再找 出剩下的植株里花生最多的,去采摘它的花生;依此类推,不过你一定要在我限定的时间内回到路边。”
我们假定多多在每个单位时间内,可以做下列四件事情中的一件:
(1)从路边跳到最靠近路边(即第一行)的某棵花生植株;
(2)从一棵植株跳到前后左右与之相邻的另一棵植株;
(3)采摘一棵植株下的花生;
(4)从最靠近路边(即第一行)的某棵花生植株跳回路边。
现在给定一块花生田的大小和花生的分布,请问在限定时间内,多多最多可以采到多少个花生?
注意:可能只有部分植株下面长有花生,假设这些植株下的花生个数各不相同。
例如在图 2 所示的花生田里,只有位于 (2,5),(3,7),(4,2),(5,4) 的植株下长有花生,个数分别为 13,7,15,9。
沿着图示的路线,多多在 21 个单位时间内,最多可以采到 37 个花生。
【输入格式】
输入文件的第一行包括三个整数,M,N 和 K,用空格隔开;表示花生田的大小为 M×N,多多采花生的限定时间为 K 个单位时间。
接下来的 M 行,每行包括 N 个非负整数,也用空格隔开;第 i+1 行的第 j 个整数 Pij 表示花生田里植株 (i,j) 下花生的数目,0 表示该植株下没有花生。
【输出格式】
输出文件包括一行,这一行只包含一个整数,即在限定时间内,多多最多可以采到花生的个数。
【数据范围】
1≤M,N≤20,
0≤K≤1000,
0≤Pij≤500
【输入样例】
6 7 21
0 0 0 0 0 0 0
0 0 0 0 13 0 0
【题目来源】
https://www.luogu.com.cn/problem/B3853
【题目描述】
给出三个整数 a,b,c,保证 b≠0。
如果a+b=c,请你输出 plus。
如果a−b=c,请你输出 minus。
如果以上两条均不满足,请输出 illegal。
【输入格式】
输入只有一行三个整数,依次表示 a,b,c。
【输出格式】
输出一行一个字符串表示答案。
【输入样例】
1 2 3
3 2 1
1 1 4
【输出样例】
plus
minus
illegal
【数据规模与约定】
对全部的测试点,保证 -2^31≤a, b, c<2^31,b≠0。
【算法代码】
#include <bits/stdc++.h> using namespace std; long long a,b,c; int main() { cin>>a>>b>>c; if(a+b==c) cout<<"plus"<<endl; else if(a-b==c) cout<<"minus"<<endl; else cout<<"illegal"<<endl; } /* in: 1 2 3 3 2 1 1 1 4 out: plus minus illegal */ 【参考文献】
文章目录 1. HTTP响应1.1 响应报文1.2 常见HTTP状态码1.3 在flask中如何生成响应1.3.1重定向1.3.2错误响应 1.4响应格式 在flask程序中,客户端发出的请求触发相应的视图函数,获取返回值会作为响应的主体,最后生成完整的响应,即响应报文。
1. HTTP响应 1.1 响应报文 响应报文主要由协议版本、状态码、原因短语、响应首部和响应主体组成。
协议版本:响应报文的开头通常包含协议版本信息,用于标识使用的通信协议的版本。如HTTP/1.1。状态码:状态码是一个三位数字的代码,用于表示请求的处理结果。常见的状态码有200(成功)、404(未找到)、500(服务器内部错误)等。原因短语:原因短语是对状态码的文本解释,用于提供关于请求处理结果的更详细的信息。响应首部:响应首部包含了一些额外的信息,如响应内容的类型、长度等。这些信息对于理解响应内容非常重要。响应主体:响应主体是实际的数据内容,即服务器返回给客户端的具体信息。 1.2 常见HTTP状态码 类型状态码原因短语说明成功200OK请求被正常处理成功201Created请求被处理,并创建了一个新资源成功204No Content请求处理成功,但无内容返回重定向301Move Permanently永久重定向重定向302Found临时性重定向重定向304Not Modified请求的资源未被修改,重定向缓存的资源客户端错误400Bad Request表示请求无效,即请求报文中存在错误客户端错误401Unauthorized类似403,表示请求资源未授权客户端错误403Forbidden表示请求资源被服务器拒绝访问客户端错误404Not Found表示服务器上找不到请求的资源或URL无效服务器端错误500Internal Server Error服务器内部发生错误 1.3 在flask中如何生成响应 响应大部分内容由服务器处理,大多数情况下,我们只负责返回主体内容。响应在flask中使用Response对象表示。
Flask会先判断是否可以找到与请求url相匹配的路由,如果没有返回404。如果找到,就会调用对应的视图函数,视图函数的返回值构成了响应报文的主题内容,正确返回的状态码为200。
1.3.1重定向 如果你访问http://localhost:5000/hi,你会发现页面加载后地址栏中的URL变成了http://localhost:5000/hellp。这种行为被称为重定向,你可以理解为网页跳转。
代码示例:
from flask import Flask, redirect, url_for @app.route('/hello') def hello(): # 直接返回网页 return redirect('/hi') @app.route('/hi') def hi(): return redirect(url_for('hello')) 1.3.2错误响应 如果你访问http://localhost:5000/brew/coffee,会获得一个418错误响应(I’m a teapot)
大多数情况下,flask可以自动处理常见的错误响应。Http错误对应的异常类在werkzeug的werkzeug.exceptions模块中被定义,抛出这些异常即可返回对应的错误响应。如果你想手动返回错误响应,你可以使用flask提供的abort()函数。
from flask import Flask, abort @app.route('/404') def not_found(): abort(404) abort 函数不需要使用return返回,但他之后的代码也不会在执行。
1.4响应格式 纯文本
MIME类型:text/plain
当MIME类型设置为纯文本时,浏览器会以文本形式显示返回值。HTML
为什么要选择React16 现在React18都早已实践很多,为何回过头来看16版本的代码理由如下 从实际出发,企业内老旧项目多为16版本,理解16的核心能够帮助我们快速解决问题16版本React是完全重写了核心代码, 是一次重大的更新 引入了 fiber 这个概念,从根本上解决了JS单线程运行问题引入了hooks,摆脱了 class component 的一些繁琐的内容… 关于React框架 React 是一个非常纯粹的 UI 框架,通过state映射UI的方式来屏蔽了dom操作现在业界的框架大多如此, 但是说React纯粹是因为它的API设计非常的纯粹 核心API就是 setState,其余所有的内容都围绕着组件化来设计没有directive双向绑定以及其他的一些API它要改变一个UI你只能通过setState来改变对应的状态这就给了react无比纯粹的开发体验, 一切基于组件同时react又是一个思想超前的框架而Vue框架是基于React发展而来,很多思想都是借鉴React的思路 深入研究React源码的意义 能在遇到bug的时候,从底层去思考如何去解决问题并且能够让你在开始项目之前就想好更好的架构方式React源码的很多设计细节都是非常高明的,学习源码能有助于你提升整体的编码能力React源码是由全世界最好的一部分前端开发人员一起维护了好几年才形成现在这个版本的代码它的代码质量肯定是非常高的, 它的一些解决方案是非常有效的研究这些编码的思维,对我们将来肯定也有非常大的帮助 React16 源码目录结构分析 1 )概述 比如: React 16.6 版本仓库地址: https://github.com/facebook/react/tree/v16.6.0/packages 核心结构
react/packages ├── event # 编译相关 ├── react # 核心 api ├── react-dom # 核心 api 操作dom ├── react-reconciler # 服务端渲染 ├── scheduler # .调度计划 ├── shared # 共享代码 ├── ... # 其他 2 )说明
event 事件系统
我们知道react使用的是onClick这种在标签上面写props的方法去绑定事件它跟原生的事件绑定是有一定的区别的它自己实现了一套事件的一个传播的体系这部分的代码就在events 目录下面 react 核心api
AccessibilityService辅助服务拦截注入Input事件 android11-release
frameworks\base\core\java\android\accessibilityservice\AccessibilityService.java
frameworks\base\services\accessibility\java\com\android\server\accessibility\AccessibilityInputFilter.java
设置中打开辅助服务 设置->无障碍
settings get secure accessibility_enabled
settings get secure enabled_accessibility_services
com.miui.securitycenter/com.miui.luckymoney.service.LuckyMoneyAccessibilityService 小米红包助手
google无障碍控制 com.google.android.marvin.talkback/com.android.switchaccess.SwitchAccessService 设置->无障碍中“开关控制”
AccessibilityService https://developer.android.google.cn/reference/android/accessibilityservice/AccessibilityService
AccessibilityManagerService和AccessibilityInputFilter private static final String ACCESSIBILITY_MANAGER_SERVICE_CLASS = "com.android.server.accessibility.AccessibilityManagerService$Lifecycle"; startOtherServices启动,AccessibilityService初始化 init 并监听registerBroadcastReceivers()、new AccessibilityContentObserver(...).register(...)scheduleUpdateInputFilter 最终注册AccessibilityInputFilterInputDispatcher事件被AccessibilityInputFilter拦截,不会被唤醒mLooper->wake()
Input事件传递到AccessibilityInputFilter的onInputEvent
AccessibilityService事件 Android AccessibilityService 事件分发原理
创建无障碍服务 创建自己的无障碍服务 InputDispatcher时序问题 请参考Android 无障碍服务导致的整机卡顿案例分析
AccessibilityInputFilter拦截,不会被InputReader通知Notify***唤醒下一个 Vsync 周期?的时候执行
目录
1 绘图函数介绍
1.1 点型绘制 1.2 颜色绘制 1.3 线型绘制 2 坐标轴状态与标识
2.1 坐标轴的控制
2.2 网格线、轴线分度以及标识
2.3 图形标识命令
3 多次叠绘与多子图
3.1 多次叠绘
3.2 多子图
1 绘图函数介绍 二维绘图常用的函数就是plot函数,基本调用格式如下:
% x,y 横纵坐标 % s 用于表示点型、颜色与线型 plot(x,y,'s') 1.1 点型绘制 点型预定义设置符 .实心点*米字符+十字符x叉字符o空心圆圈s方块符d菱形符p五角星符h六角星符<向左三角符>向右三角符 示例代码:
x = -10:0.1:10; %x轴 y = 2*x+2; %y轴 plot(x,y,'x'); %绘图,叉字符 运行效果如下(figure图像坐标已拉伸放大):
1.2 颜色绘制 颜色预定义设置符 b蓝色g 绿色
r红色c青色m紫红y黄色k黑色w白色 示例代码:
x = -10:0.1:10; %x轴 y = 2*x+2; %y轴 plot(x,y,'xr'); %绘图,叉字符,红色 运行效果如下:
1.3 线型绘制 线型预定义设置符 -细实线:点线-.
推荐阅读 轻松驾驭JDBC:一篇文章帮你搞定数据库连接
ChatGPT爆火一周年,快来拥有专属你的ChatGPT应用!
文章目录 推荐阅读GraalVM安装native-image安装自动安装手动安装 Visual Studio安装下载配置环境变量INCLUDE环境变量LIB环境变量 GraalVM安装 下载配置GraaIVM(下载地址) ,选择相应版本,进行下载。 将GraalVM的bin目录路径添加到系统环境变量中。在Windows 10中,可以按下Win + X键,选择“系统”,然后选择“关于”->“高级系统设置”->“环境变量”。 如果之前配置过java的环境变量,可以直接替换掉JAVA_HOME(这里采取的是该方法) 验证安装
java -version native-image安装 自动安装 官网教程安装命令:gu install native-image。
在这之前,可以先测试gu命令是否可以运行。
然后进行native-image安装。
可能在windows上是无法运行,不能识别gu命令。可以使用以下命令进行自动下载安装
gu.cmd install native-image 手动安装 进入官网(下载链接),下载与自己Java版本,操作系统对应的jar包。下载完成后,cmd进入jar所在目录,输入以下命令。 gu install -L native-image-installable-svm-java17-windows-amd64-22.3.0.jar(这里替换你下载的那个jar) Visual Studio安装 下载 进入官网,下载Visual Studio(下载链接)
下载配置windows10 sdk和msvc。
建议使用新版2022的,2019版的可能后续运行native-image会报错(至少我的是这样的)😭😭😭
22版同样下载相应的组件。msvc和windows10sdk,这两个必不可少。
配置环境变量 Path环境变量
在path中添加你vs目录下msvc的bin目录
windows sdk各个版本安装目录不同(容易搞错),搜索注册表进入注册表编辑器,找到对应的注册表路径。
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\Windows\v10.0
C:\Program Files (x86)\Windows Kits\10\ 接下来需要配置环境变量INCLUDE和LIB
INCLUDE环境变量 LIB环境变量 重新启动系统后,进行测试。
等待完成后,即可在设定路径下看到相关的exe文件,点击即可执行。
运行结果:
看到这一个页面,恭喜你,成功完成了所有的配置,可以继续愉快的玩耍了 。
在宝塔部署flask的步骤我已经写了一篇博客:宝塔部署flask项目-CSDN博客
之前说如果出现找不到application错误:
spawned uWSGI http 1 (pid: 3116) --- no python application found, check your startup logs for errors --- [pid: 3114|app: -1|req: -1/1] 127.0.0.1 () {62 vars in 1090 bytes} [Sat Dec 30 22:03:36 2023] GET / => generated 21 bytes in 0 msecs (HTTP/1.1 500) 2 headers in 83 bytes (0 switches on core 0) 可以修改运行代码:
if __name__ == '__main__': app.run() else: application = app 这样就有uwsgi.ini文件需要的application名字了.
还有一种方法,就是在uwsgi.ini里面设置访问的程序名不是默认的application,而是app:
简介 学习目的 我们在学习GUI开发的时候一般思考两个问题
如何来设计UI?如何实现前后端数据交互? 问题一
React引入了tsx语法,让我们能够在ts中自由的嵌入html,让我们能只写tsx代码,来实现UI的控制,而不是把所有的UI都放进一个html文件中,让各个部分更好维护
所react中,我们使用组件来表示各个小的部分
那与之而来的问题,react是如何将tsx代码变成网页的呢?
要知道,我们使用react可以不写任何html实现网页效果
答案是使用虚拟dom,即由react管理的dom,我们的tsx语法都会先映射到这个虚拟的dom上,然后react来对比改变的部分,然后render到浏览器中的dom上,这样还能减少对浏览器dom的更改,节省了性能
问题二
我们的数据通过hook来修改,根据不同需要,可以封装不同的修改
React(React.js或ReactJS)是由Facebook开发并维护的一款用于构建用户界面的JavaScript库。React主要用于构建单页面应用程序(Single Page Applications)中的用户界面,通过组件化开发的方式,可以更轻松地构建和维护复杂的前端应用。
React的设计目标是提高前端开发的效率和可维护性,使得开发者能够更容易地构建现代、响应式的用户界面。它广泛应用于各种Web应用开发项目,并且与其他技术(如React Native)结合,使得开发者可以用相似的方式构建Web、移动端等不同平台上的应用。
运行环境 1. 创建 React 应用
在工作目录下打开终端,输入下面命令,设置名称为my-app后全部yes
npx create-next-app@latest 2. 进入 create-react-app 创建的文件夹并安装 typescript
cd my-app 3.启动 React
npm run dev 然后会自动在浏览器打开localhost:3000网页,然后就能看到官方示例了
HOOK 格式如下,解释 : 用setTodos来设置todos,并初始值为<Todo[]>([])这个空列表
const [todos, setTodos] = useState<Todo[]>([]) 然后我们可以利用这个来管理todos,如下
const addTodo = (text: string) => { const newTodo = { id: Date.now(), text, completed: false } setTodos([...todos, newTodo])//打开旧的,添加新的 } const deleteTodo = (id: number) => { setTodos(todos.
知识点总结 第一章:软件工程概述 1、软件的定义:在运行中能提供所希望的功能与性能的程序+使程序能够正确运行的数据及其结构+描述软件研制过程和方法所用的文档。
2、软件危机:软件开发的生产率远远不能满足客观需要。开发的软件产品往往不能满足用户的实际需要。软件产品的质量低下且可维护性差。很难估计软件开发的进度计划与成本。
3、软件工程是将系统化的、严格约束的、可量化的方法应用于软件的开发、运行和维护,即将工程化应用于软件。
4、软件工程三个要素:方法、工具、过程
5、瀑布模型:软件需求的认识是明确的
6、演化模型:适用于对软件需求缺乏准确认识的情况。软件需求的认识是模糊的、不确定的
7、增量模型特别适用于:需求经常变化的软件开发;市场急需而开发人员和资金不能在设定的市场期限之前实现一个完善的产品的软件开发
8、原型是预期系统的一个可执行版本,它反映了系统性质的一个选定的子集。
9、螺旋模型:是瀑布模型和演化模型的结合,并增加了风险分析
10、喷泉模型:喷泉模型是一种支持面向对象开发的模型,体现迭代和无间隙特征。
第二章:系统策划 1、可行性研究的任务:技术可行性 、经济可行性和社会因素的考虑。
2、两种成本估算方法:代码行法(LOC)——每行代码的平均成本乘以程序的行数;功能点法(FP)——采用软件所提供的功能来测量的
第三章 需求分析 1、需求分析的重要性:需求分析是发现、求精、建模、规格说明和复审的过程;需求分析是系统设计的基础,关系到程的成败和软件产品的质量。
2、需求获取困难原因有三:一是用户需求的动态性(不稳定性);二是需求的模糊性(不准确性);三是需求必须得到用户的确认,否则毫无意义 。
3、需求分析任务:
确定对系统的综合要求:系统界面要求、系统功能要求、系统性能要求、完全性可靠性保密性要求、系统运行要求、异常处理要求、将来可能提出的要求、分析系统的数据要求;分析系统的数据要求;画出系统的逻辑模型;修正项目开发划。
4、评审、验证的四个方面:一致性、完整性、现实性和有效性。
5、结构化分析方法:面向数据的方法,以数据流为中心 。其核心概念包括:数据流、数据存储、外部实体、数据组和数据元素。基本思想:自顶向下和逐层分解。
6、面向对象的分析方法 :面向对象分析以对象及其服务作为建模标准,比较自然,对象也具有相对的稳定性。
7、数据流图(DFD)是一种图形化技术,它描绘信息和数据从输入到输出的过程中所经受的变换。
8、数据字典任务:对于数据流图中出现的所以被命名的图形元素在数据字典中作为一个词条加以定义,使得每一个图形元素的名字都有一个确切的解释。
9、数据元素:数据的最小单位
10、面向对象=对象+类+继承+通信
11、对象是现实世界中个体或事物的抽象表示,它封装了特殊的属性(数据)和行为方法(操作)。
12、类是具有相同属性和操作的一组相似对象的抽象
13、实例:是由某个特定的类所描述的一个具体的对象
14、属性:是类或对象中所定义的数据,它是描述客观世界实体静态特征的数据项。
15、方法是对象所能执行的操作,也就是类中所定义的服务。方法描述了对象执行操作的算法,响应消息的方法
16、一个消息由以下三部分组成:
•接收消息的对象;
•消息选择符即消息名;
•零个或多个变元。
17、封装就是把某个事物包起来,使外界不知道该事物的具体内容。在面向对象的程序中,把数据和实现操作的代码集中起来放在对象内部。
18、继承:类之间的继承关系是现实世界中遗传关系的直接模拟,它表示类之间的内在联系以及对属性和操作的共享,即子类可沿用父类(被继承)的某些特征。当然也可以具有自己独有的属性和操作。
19、多态是指在父类中定义的属性或服务被子类继承后,可以具有不同的数据类型或表现出不同的行为
20、向对象方法
Booch方法 :提出面象对象的软件工程的概念
OMT方法 :提出面象对象的建模技术方法
OOSE方法 :用例贯穿于软件整个开发过程
21、UML(重点放到下边来总结)
第四章 软件设计 1、软件设计是一个把需求转换为某种软件表达方式的过程。基本目标是用比较抽象概括的方式确定目标系统如何完成预定的任务。
2、概要设计:将软件需求转化为软件体系结构,确定系统级接口、全局数据结构或数据库模式。
3、详细设计:确立每个模块的实现算法、局部数据结构,用适当方法表示算法和数据结构的细节。
4、所谓模块,是指具有相对独立性的,由数据说明、执行语句等程序对象构成的集合。模块具体表现为函数、子程序、过程等。一个模块具有输入/输出(接口)、功能、内部数据和程序代码四个特征。
5、模块化是指将整个程序划分为若干个模块,每个模块用于实现一个特定的功能。
6、体系结构设计的主要任务
软件体系结构设计(功能性):设计软件的体系结构需要在对需求分析阶段生成的数据流图进一步分析和精化的基础上,首先将系统按照功能划分为模块,接着需要确定模块之间的调用关系及其接口,最后还应该对划分的结果进行优化和调整。良好的软件结构设计对详细设计及编码阶段的工作都是至关重要的。
数据结构和数据库设计:体系结构设计中应对需求分析阶段所生成的数据字典加以细化,从计算机技术实现的角度出发,确定软件涉及的文件系统及各种数据的结构。
系统可靠性、安全性设计(非功能性):可靠性设计也称为质量设计,目的是为了保证程序及其文档具有较高的正确性和容错性,并对可能出现的错误易于修改和维护。安全性设计的主要目的是为了增强系统的自我防护能力和运行的稳定性,防止系统遭受到有意或无意地入侵和破坏,保证系统在安全的环境下正常地工作。
7、体系结构设计的原则
(1)降低模块的耦合性,提高模块的内聚性。 为了提高软件中各个模块的独立性,提高程序的可读性、可测试性和可维护性。
(2)保持适中的模块规模。对于模块的适当规模并没有严格的规定,但普遍的观点是模块中的语句数最好保持在10~100之间。
(3)模块应具有高扇入和适当的扇出。模块的扇入越大,则说明共享该模块的上级模块数越多,或者说该模块在程序中的重用性越高,这正是程序设计所追求的目标之一。模块的扇出若过大,如在一个模块中要调用八个下级模块,则会使该模块的调用控制过于复杂。最常见的解决办法是通过在此模块和下级模块间增加一个中间层来控制模块分解的速度。根据实践经验,设计良好的典型系统中,模块的平均扇出通常为3或4。
(4)软件结构中的深度和宽度不宜过大。所谓深度,是指软件体系结构中控制的层数,它能够粗略地反映出软件系统的规模和复杂程度;所谓宽度,是指软件体系结构内同一层次上模块个数的最大值,通常宽度越大的系统越复杂。
今天看了大鹏导演的《保你平安》。我挺喜欢,因为凭良心讲,这片子讲事儿挺瓷实的,说了一些别人不敢说的的事儿,讲了一些别人不敢讲的答案。
点很多,说一点:平安哥女儿被霸凌的事儿。
霸凌听了好多了,从小学到大学,那是校园霸凌,再往后就是职场霸凌了。咱们对待校园霸凌的态度到底是什么?扩大一点儿,咱们对待有些人的“恶”,态度和做法是什么?再扩大点儿,对待“废除死刑”,态度和做法是什么?
我觉得最重要的是:负责任。大家都听过这个:“谁开发、谁保护,谁受益、谁补偿,谁污染、谁治理,谁破坏、谁修复”。现代社会的运行规律,在大部分时候和事情上是遵循这个的,比如离婚后,不养孩子的一方要付抚养费就是这个道理。所以我想这代表着一个普世价值”人人需为自己的行为负责”:某人做了某事,那么他必须为这事儿的后果负责,而且这和年龄、种族、宗教等等这些都没关系。否则,必然就会有人肆意妄为。
校园霸凌代表这一些人对另外一些人的“恶”。如果社会不打算接收这种“恶”,那么就必须让有些人为此付出代价。
生命很宝贵,因为每个人都只有一次机会。所以死亡至少是一个人所能付出的最大代价的一种方式。对于废除死刑,我认为这是某些人强制整个社会接受降低个人为其行为所能付的最大责任,或者后果,说白了就是容忍某些行为,降低上限。这是问题的一方面。
另一方面,人人生而平等的,没有人天生比其他人权利多一些,如果有人因为不能被社会接受的原因剥夺了其他人的权利,难道他不应该付出同等代价吗?所以无条件废除死刑实际上是剥夺了某些人的权利,比如被加害人的生存权,提出这些观点的人大概脑子不太清楚,搞不清楚现在的社会现实,这些人比坏蛋更坏。我想,按照他们说的相反去做就能平安吧。
tombstone墓碑生成机制 Android中程序在运行时会遇到各种各样的问题,相应的就会产生各种异常信号,比如常见的异常信号 Singal 11:Segmentation fault表示无效的地址进行了操作,比如内存越界、空指针调用等。
Android中在进程(主要指native进程)崩溃时会生成墓碑文件,这些文件中记录了崩溃时的调用堆栈、日志信息、寄存器二进制数据等等,用以帮助开发者已经崩溃问题。
墓碑文件默认保存在**/data/tombstones/**目录中,以tombstone_xxx(xxx表示编号)方式命名。墓碑文件数量有上限,达到上限时会删除最旧的墓碑文件,可以通过配置属性 tombstoned.max_tombstone_count来修改默认的墓碑文件数量。
本文源码基于Android12版本。
墓碑环境初始化 bionic为程序初始化墓碑生成环境 bionic是android提供的符合POSIX接口的标准C库,其中提供了Linker(动态连接器)。动态链接器的作用是在运行动态链接的可执行文件时,动态链接器负责加载程序到内存中,并解析对符号的引用。
bionic在Linker中初始化墓碑生成环境,下面的汇编代码中执行了__linker_init这个符号(函数)
//bionic/linker/arch/arm64/begin.S #include <private/bionic_asm.h> ENTRY(_start) // Force unwinds to end in this function. .cfi_undefined x30 mov x0, sp bl __linker_init /* linker init returns the _entry address in the main image */ br x0 END(_start) __linker_init这个函数定义在/bionic/linker/linker_main.cpp中,先后执行__linker_init、__linker_init_post_relocation、linker_main。在linker_main函数中,调用linker_debuggerd_init,初始化墓碑生成环境。另外,在linker_main函数中可以看到很多比较重要的初始化函数,比如__system_properties_init。
//bionic/linker/linker_main.cpp extern "C" ElfW(Addr) __linker_init(void* raw_args) { // Initialize TLS early so system calls and errno work. // 省略 return __linker_init_post_relocation(args, tmp_linker_so); } static ElfW(Addr) __attribute__((noinline)) __linker_init_post_relocation(KernelArgumentBlock& args, soinfo& tmp_linker_so) { // 省略 // 执行linker_main ElfW(Addr) start_address = linker_main(args, exe_to_load); if (g_is_ldd) _exit(EXIT_SUCCESS); INFO("
第一章 大数据的概念:海量数据的规模巨大到无法通过目前主流的计算机系统在合理时间内获取、存储、管理、处理并提炼以帮助使用者决策
大数据的特点:①数据量大,存储的数据量巨大,PB级别是常态;②多样,数据的来源及格式多样,数据格式除了传统的结构化数据外,还包括半结构化和非结构化数据;③快速,数据的增长速度快,而且越新的数据价值要求对数据的处理也要快;④价值密度低,要求设计一种在成本可接受的条件下,快速采集,发现和分析,从大量多种类别的数据提取价值的体系架构;⑤复杂度,对数据分析处理的难度大
云计算的概念:云计算是一种商业计算模型,将计算任务分布在大量计算机构成的资源池上,使各种应用系统能够根据需要获取计算力,存储空间等服务
短定义:云计算是通过网络按需提供可动态伸缩的廉价计算服务
云计算的特点:①超大规模②虚拟化,支持用户在任意位置在各种终端获取服务,但实际上不需要了解应用运行的具体位置③高可靠性,采用数据多副本容错,节点同构可互换的措施来保障服务的高可靠性④通用性,云的特殊容错措施使得可以采用及其廉价的节点来构成云⑤高可伸缩,云的规模可以伸缩⑥按需服务⑥极其廉价,云的特殊容错措施可以使得用极其廉价的节点来构成云
云计算的分类:
按照服务类型分类:
①将基础设施作为服务IaaS,给用户提供对所有设施的利用服务,弹性云计算ECS、AWS
②将平台作为服务PaaS,将软件研发的平台作为一种服务,百度BAE,新浪SAE,阿里ACE,京东JAE
③将软件作为服务SaaS,协同OA,CRM,财务系统,企业智能系统和企业邮箱
按照部署模式分类:
①公有云,向公众开放,任何人都能够租赁
②私有云,只向一个企业或单位内的人员使用;分为本地私有云(部署在企业内部,适合运行关键和机密业务),托管私有云(托管在第三方机房)
③混合云,只供两个或以上的特定企业或者单位内的人员使用,其他人无权租赁和使用
④社区云,由两个或者以上不同类型的云组成,但用户使用感觉是一个云端资源
第二章 NAT虚拟机可以访问外网,外网不能访问虚拟机,网段不可以调整NAT Network虚拟机可以访问外网,外网不能访问虚拟机,网段可调整Bridged虚拟机可以访问外网,外网可以访问虚拟机,网段和主机相同Host-Only虚拟机不可以访问外网,外网不可以访问虚拟机,网段和主机相同 系统环境配置的步骤:①下载安装VirtualBox,下载系统镜像
②最小化安装CentOS,出现安装引导页面时点击Tab键,打开kernel启动选项,增加选项:net.ifnames=0 biosdevname=0,进入后网卡名会按照eth0,eth1的规则命名,同时进入安装页面之后选择最小化安装
③配置虚拟网络,①设置Nat Network网段(192.168.56.0/24)和 Host-only网段(10.0.0.0/24),网卡一用于Nat网段,网卡二用于Host-only网段。②在/etc/sysconfig/network-script/中设置主机网络,自举协议为static,启动开机自启,设置IPADDR、NETMASK、GATEWAY、DNS1和DNS2;③/etc/hostname修改本主机名称;/etc/hosts修改其他主机名称解析,然后测试网络连接
④禁用防火墙和SELinux,关闭防火墙(临时关闭)systemctl stop firewalld ,防止自动启动systemctl disable firewalld ;关闭SELinux:修改配置文件/etc/sysconfig/selinux,设置SELINUX=disabled,检查关闭是否成功(systemctl status firewalld)
⑤配置EPEL,安装wget,然后使用淘宝等镜像源
⑥安装基础软件,安装工具软件包,服务器软件包,和开发工具(JAVA、node.js、gcc)
⑦创建快照并克隆虚拟机,克隆完成后需要进行网络连通性测试,随后对宿主机配置对所有虚拟机的免密登录
第三章 集群:一组相互独立的,通过高速网络互联的计算机,构成了一个组,并以单一系统的模式进行管理
集群的特性:一个用户与集群相互作用时,集群就像是一个独立的服务器
使用集群的目的:①提高性能;②降低成本;③提高可扩展性;④增强可靠性
集群的组织方式:①主从结构,将备份服务器连接到主服务器上,备份服务器一般不主动提供服务
②多级结构,多个服务器组成的集群服务器,对外都有一个统一的地址,每个集群服务器上都装有相同的应用程序
常用的命令:
取消开机启动systemctl disable nginx;
重启systemctl restart nginx ;
检查nginx进程ps aux | grep nginx;
检查端口netstat intp | grep 80或netstat intp | grep nginx
负载均衡的配置搭建 常见的负载均衡方案,分为硬件方案和软件方案;硬件方案采用F5等设备,但是比较贵。软件方案采用在四层使用LVS和在七层使用NginX实现负载均衡
Nginx仅仅是作为Nginx Proxy反向代理使用的,但我们称这个反向代理表现的效果是负载均衡的效果。所以可以称之为负载均衡;真正的负载均衡是转发用户请求的数据包,真正负载均衡是转发用户请求的数据包,而NginX反向代理是接收用户的请求然后重新发起请求去请求其后面的节点。
微信小程序开发系列目录 《微信小程序开发系列-01创建一个最小的小程序项目》《微信小程序开发系列-02注册小程序》《微信小程序开发系列-03全局配置中的“window”和“tabBar”》《微信小程序开发系列-04获取用户图像和昵称》《微信小程序开发系列-05登录小程序》《微信小程序开发系列-06事件》《微信小程序开发系列-07组件》 文章目录 微信小程序开发系列目录前言自定义组件模版特性数据绑定component-tag-name.wxmlcomponent-tag-name.jsindex.wxmlindex.js运行结果 多slotcomponent-tag-name.wxmlindex.html运行结果 抽象节点定义声明使用综合示例 总结 前言 本文将学习自定义组件模版的三个特性:数据绑定、多slot、抽象节点。
自定义组件模版特性 数据绑定 在自定义组件中也可像普通页面一样进行数据绑定,同样是使用{{}}语法。这样就可以向自定义组件传递动态数据。
component-tag-name.wxml 在自定义组件中,定义了两个text用来显示属性propA和propB。
<view class="wrapper"> <view>这里是组件的内部节点</view> <view> <text>propA: {{propA}}</text> </view> <view> <text>propB: {{propB}}</text> </view> <slot></slot> </view> component-tag-name.js 属性propA和propB的数据类型为String,并给了一个默认值。
Component({ /** * 组件的属性列表 */ properties: { propA: { type:String, value:"propA" }, propB: { type:String, value:"propB" } }, /** * 组件的初始数据 */ data: { }, /** * 组件的方法列表 */ methods: { } }) index.wxml 页面index绑定了数据dataFieldA和dataFieldB。
<view> <my-component prop-a="{{dataFieldA}}" prop-b="{{dataFieldB}}"> <!-- 这部分内容将被放置在组件 <slot> 的位置上 --> <view>这里是插入到组件slot中的内容</view> </my-component> </view> index.
文章目录 前言相关链接项目专栏运行环境匹配图片封装组件新增类库项目选择依赖顺序并添加Nuget修改原本矩形方法运行结果: 对矩形进行抽象封装抽象基类矩形抽象改造 圆形抽象封装代码运行结果 前言 为了更好地去学习WPF+Halcon,我决定去报个班学一下。原因无非是想换个工作。相关的教学视频来源于下方的Up主的提供的教程。这里只做笔记分享,想要源码或者教学视频可以和他联系一下。
相关链接 微软系列技术教程 WPF 年度公益课程
Halcon开发 CSDN博客专栏
个人学习的Gitee 项目地址仓库
项目专栏 WPF+Halcon实战项目
运行环境 .net core 8.0visual studio 2022halcon HDevelop 20.11windows 11 匹配图片 封装组件 Halcon官方的代码很多都是基于String的类型判断,我们要对Halcon的代码进行一步简单的封装。
新增类库项目 选择依赖顺序并添加Nuget 让我们的WPF主程序依赖于HalconExtension类库
添加Nuget
修改原本矩形方法 原来的方法
// 显示绘制图案 HalconWindow.HalconWindow.AttachDrawingObjectToWindow(rect); // 去除绘制图案 //HalconWindow.HalconWindow.DetachDrawingObjectFromWindow(rect); rect.OnDrag(new HDrawingObject.HDrawingObjectCallbackClass((id, window, type) => { var hv_type = id.GetDrawingObjectParams("type"); var row1 = id.GetDrawingObjectParams("row1"); var row2 = id.GetDrawingObjectParams("row2"); var column1 = id.GetDrawingObjectParams("column1"); var column2 = id.GetDrawingObjectParams("column2"); //打印坐标 NLogHelper.Debug($"拖动事件: {hv_type}:{row1} {column1} {row2} {column2} "
一:各文件的使用回顾 1.items的使用 items 文件主要用于定义储存爬取到的数据的数据结构,方便在爬虫和 Item Pipeline 之间传递数据。
items.py import scrapy class TencentItem(scrapy.Item): # define the fields for your item here like: title = scrapy.Field() position = scrapy.Field() date = scrapy.Field() 2.pipline的使用 (1)pipelines介绍 管道文件 pipelines.py 主要用来对抓取的数据进行处理:一般一个类即为一个管道,比如创建存入MySQL、MangoDB 的管道类。管道文件中 process_item() 方法即为处理所抓数据的具体方法。
(2)pipelines常用方法 process_item(self,item,spider):处理爬虫抓取的具体数据,在 process_item() 函数中 必须要 return item,因为存在多管道时,会把此函数的返回值继续交由下一个管道继续处理;open_spider():爬虫项目启动时只执行一次,一般用于数据库连接;close_spider():爬虫项目结束时只执行一次,一般用于收尾工作,如数据库的关闭。 (3)pipelines注意点 pipeline对应的值越小优先级越高pipeline中的process_item方法的名字不能够修改为其他的名称 二:工作流程回顾 1.如何处理翻页 2.scrapy.Request知识点 scrapy.Request(url, callback=None, method='GET', headers=None, body=None,cookies=None, meta=None, encoding='utf-8', priority=0, dont_filter=False, errback=None, flags=None) 常用参数为: callback:指定传入的URL交给那个解析函数去处理 meta:实现不同的解析函数中传递数据,meta默认会携带部分信息,比如下载延迟,请求深度 dont_filter:让scrapy的去重不会过滤当前URL,scrapy默认有URL去重功能,对需要重复请求的URL有重要用途 三:Scrapy下载中间件 下载中间件是scrapy提供用于用于在爬虫过程中可修改Request和Response,用于扩展scrapy的功能
使用方法:
编写一个Download Middlewares和我们编写一个pipeline一样,定义一个类,然后在settings中开启Download Middlewares默认方法处理请求,处理响应,对应两个方法: process_request(self,request,spider): 当每个request通过下载中间件时,该方法被调用 process_response(self,request,response,spider): 当下载器完成http请求,传递响应给引擎的时候调用 当每个Request对象经过下载中间件时会被调用,优先级越高的中间件,越先调用;该方法应该返回以下对象:None/Response对象/Request对象/抛出IgnoreRequest异常
目录
1.常用的git命令有哪些?
2.git rebase和git merge的区别
3.有哪些常见的Loader和Plugin?
4.webpack的构建流程
5.bundle,chunk,module是什么?
6.如何提高webpack的打包速度
7.vite比webpack快在哪里
8.说一下你对Monorepo的理解
9.如何减少打包后的代码体积
10.Webpack的Tree Shaking原理
1.常用的git命令有哪些? git clone:克隆远程仓库到本地git init:在当前目录初始化一个新的git仓库。git add:将文件添加到暂存区,准备提交。git commit -m "commit_message":提交暂存区的改动到本地仓库,附带提交信息。git status:查看工作区,暂存区的状态,显示文件的修改情况git diff:显示工作区与暂存区之间的差异。git diff --staged:显示暂存区与最后一次提交之间的差异git log:显示提交日志。git branch:列出所有分支,当前分支前会有一个星号。git checkout:切换到指定分支git checkout -b:创建并切换到新分支git merge:将指定分支合并到当前分支git pull:拉取远程仓库的更新并合并到当前分支。git push:将本地分支的更新推送到远程仓库 2.git rebase和git merge的区别 git rebase和 git merge都是用于合并分支的git命令,这两个命令都能将一个分支合并到另一个分支,但两者的合并方式有很大不同
git merge :将一个分支的更改合并到另一个分支,创建一个新的merge commit ,将两个分支的历史合并在一起,这个merge commit会在分支历史中保留,可以清晰的看到那些分支合并到主分支,合并后形成分叉结构 git rebase :两个分支在合并到时候,会将整个分支合并到另一个分支的顶端。首先找到两个分支的共同commit记录,然后提取之后所有的commit,然后将这个commit记录添加到另一个分支的最前面,两个分支合并后commit记录就变成线性记录 3.有哪些常见的Loader和Plugin? Loader:
image-loader:加载并压缩图片文件css-loader:加载css,支持模块化,压缩,文件导入等特性style-loader:把css代码注入到JavaScript中,通过DOM操作去加载CSSeslint-loader:通过ESlint检查JavaScript代码tslint-loader:通过TSLint检查TyepScript代码babel-loader:把ES6转化为ES5 Plugin:
define-plugin:定义环境变量html-webpack-plugin:简化HTML文件创建webpack-parallel-uglify-plugin : 多进程执行代码压缩,提升构建速度webpack-bundle-analyzer : 可视化 Webpack 输出文件的体积speed-measure-webpack-plugin : 可以看到每个 Loader 和 Plugin 执行耗时 (整个打包耗时、每个 Plugin 和 Loader 耗时)mini-css-extract-plugin : 分离样式文件,CSS 提取为独立文件,支持按需加载 4.
HarmonyOS 鸿蒙系统体系 一、OpenHarmony平台架构二、OpenHarmony源码下载* IDE开发工具HUAWEI DevEco Device ToolHUAWEI DevEco Studio HarmonyOS应用开发 HarmonyOS(鸿蒙系统) 鲲鹏 昇腾 EulerOS(欧拉系统) 仓颉\
Harmonyos官网
HarmonyOS Developer 华为开发者官网
HarmonyOS 鸿蒙系统 | 鸿蒙学堂
华为开发者联盟
华为鸿蒙系统_百度百科
鸿蒙论坛
一、OpenHarmony平台架构 OpenHarmony整体遵从分层设计,从下向上依次为:内核层、系统服务层、框架层和应用层。系统功能按照“系统 > 子系统 > 组件”逐级展开,在多设备部署场景下,支持根据实际需求裁剪某些非必要的组件。OpenHarmony技术架构如下所示:
内核层
内核子系统:采用多内核(Linux内核或者LiteOS)设计,支持针对不同资源受限设备选用适合的OS内核。内核抽象层(KAL,Kernel Abstract Layer)通过屏蔽多内核差异,对上层提供基础的内核能力,包括进程/线程管理、内存管理、文件系统、网络管理和外设管理等。
驱动子系统:驱动框架(HDF)是系统硬件生态开放的基础,提供统一外设访问能力和驱动开发、管理框架。
系统服务层
系统服务层是OpenHarmony的核心能力集合,通过框架层对应用程序提供服务。该层包含以下几个部分:
系统基本能力子系统集:为分布式应用在多设备上的运行、调度、迁移等操作提供了基础能力,由分布式软总线、分布式数据管理、分布式任务调度、公共基础库、多模输入、图形、安全、AI等子系统组成。
基础软件服务子系统集:提供公共的、通用的软件服务,由事件通知、电话、多媒体、DFX(Design For X) 等子系统组成。
增强软件服务子系统集:提供针对不同设备的、差异化的能力增强型软件服务,由智慧屏专有业务、穿戴专有业务、IoT专有业务等子系统组成。
硬件服务子系统集:提供硬件服务,由位置服务、用户IAM、穿戴专有硬件服务、IoT专有硬件服务等子系统组成。
根据不同设备形态的部署环境,基础软件服务子系统集、增强软件服务子系统集、硬件服务子系统集内部可以按子系统粒度裁剪,每个子系统内部又可以按功能粒度裁剪。
框架层
框架层为应用开发提供了C/C++/JS等多语言的用户程序框架和Ability框架,适用于JS语言的ArkUI框架,以及各种软硬件服务对外开放的多语言框架API。根据系统的组件化裁剪程度,设备支持的API也会有所不同。
应用层
应用层包括系统应用和第三方非系统应用。应用由一个或多个FA(Feature Ability)或PA(Particle Ability)组成。其中,FA有UI界面,提供与用户交互的能力;而PA无UI界面,提供后台运行任务的能力以及统一的数据访问抽象。基于FA/PA开发的应用,能够实现特定的业务功能,支持跨设备调度与分发,为用户提供一致、高效的应用体验。
二、OpenHarmony源码下载 OpenHarmony基础开发
开启 OpenHarmony 之旅
OpenHarmony 获取源码:开源代码仓库地址 https://openharmony.gitee.com。
OpenHarmony攻略之下载代码篇
* IDE开发工具 HUAWEI DevEco Device Tool HUAWEI DevEco Device Tool 使用指南
前言:
日常工作或学习过程中,我们可能会经常用到某些SQL,建议大家多多整理记录下这些常用的SQL,这样后续用到会方便很多。笔者在工作及学习过程中也整理了下个人常用的SQL,现在分享给你!可能有些SQL你还不常用,但还是希望对你有所帮助,说不定某日有需求就可以用到。
注:下文分享的SQL适用于MySQL 5.7 版本,低版本可能稍许不同。有些SQL可能执行需要较高权限。
1.show相关语句 # 查看实例参数 例如: show variables like '%innodb%'; show global variables like '%innodb%'; # 查看实例状态,例如: show status like 'uptime%'; show global status like 'connection%'; # 查看数据库链接: show processlist; show full processlist; # 查询某个表的结构: show create table tb_name; # 查询某个表的详细字段信息: show full columns from tb_name; # 查询某个表的全部索引信息: show index from tb_name; # 查询某个库以cd开头的表: show tables like 'cd%'; # 查询某个库中的所有视图: show table status where comment='view'; # 查询某个用户的权限: show grants for 'test_user'@'%'; 2.
一、Objective-C OC调用Swift: 创建桥接文件
使用@objcMembers修饰的swift类可以被OC使用
@objcMembers class SwiftExample: NSObject { @objc func OC_Call_Swift() { print("oc call swift") } @objc static func OC_Call_Swift_static() { print("oc call swift static") } @objc class func OC_Call_Swift_class() { print("oc call swift class") } } OC部分
#import "OCExample.h" #import "Runner-Swift.h" @implementation OCExample - (void)OC_Call_Swift { SwiftExample *swiftExample = [[SwiftExample alloc] init]; [swiftExample OC_Call_Swift]; [SwiftExample OC_Call_Swift_static]; [SwiftExample OC_Call_Swift_class]; } @end OC调用C和C++: 不需要桥接,可以直接调用
#ifndef CExample_h #define CExample_h #include <stdio.
循环链表与静态链表 导言一、循环链表1.1 循环单链表1.2 循环双链表 二、静态链表2.1 静态链表的创建2.2 静态链表的初始化2.3 小结 结语 导言 大家好!很高兴又和大家见面啦!!!
经过前面的介绍,相信大家对链式家族的成员——单链表与双链表的相关内容都已经熟练掌握了。前面我们重点介绍了通过C语言来实现单链表与双链表的一些基本操作,希望大家私下能够多多练习一下,帮助自己去吸收消化这些内容。
在今天的篇章中,我们要介绍的是线性表的链式存储另外两个成员——循环链表与静态链表,有了单链表与双链表的基础,相信大家应该能够很容易理解今天的内容。接下来我们就来一起看看吧!
一、循环链表 在前面介绍的单链表和双链表中,我们会发现,不管是单链表的表尾结点还是双链表的头结点和表尾结点,它们在创建好后指向的内容都是空指针,如下图所示:
正因为这种存储结构,导致我们在处理表头元素、表尾元素与表中元素时会有些许的差异,比如:
在双链表中,我们采用后插法插入元素时,就需要判断该结点的后继结点是否为空指针;在单链表中,如果我们需要找到结点的前驱结点,我们只能通过从表头元素开始查找; 为了完善单链表与双链表的缺点,我们就可以将单链表与双链表做一个调整,如下所示:
我们将单链表的表尾结点的指针域指向了头结点;
将双链表的表尾指针的后继指针指向了头结点,将双链表的头结点的前驱指针指向了表尾结点;
经过这个调整后我们会发现,此时的单链表和双链表都闭合起来了,这样闭合的链表我们将其称为循环链表。接下来我们就来分别介绍一下这两种循环链表相比于之前的改动;
1.1 循环单链表 循环单链表也就是表尾结点的指针域指向的是单链表的第一个结点,而头指针指向的也是单链表的第一个结点,所以我们可以认为,在循环单链表中,表尾结点的指针域指向的是头指针L。
正因为这个点所以在对循环单链表进行判空操作时我们就有了一个改动:
由原先的判断头结点的指针域指向指向的是不是NULL,改为指向的是不是L; 用C语言来表示则是:
//循环单链表的判空 bool Empty(LinkList L) { assert(L);//当指针L为空指针时报错 if (L->next == L) return true; else return false; } 不管是单链表还是循环单链表,它们的插入、删除是一致的,唯一的区别就是,我们在对表尾结点的处理上会有差异:
单链表的表尾结点的指针域判断指向的是NULL;循环单链表的表尾结点的指针域判断指向的是L; 用C语言来表式则是:
//循环链表的表尾结点判断 bool isTail(LinkList L,LNode* p) { assert(L && p);//当指针L与指针p其中一个为空指针时报错 if (p->next == L) return true;//当结点p的后继指针指向L时表明此时的结点p为表尾结点 else return false;//当它们不相等时表明此时的结点p不是表尾结点 } 我们在对单链表进行遍历时,只能是从头结点开始往后进行遍历,但是在循环链表中,我们可以从任意结点往后遍历,用C语言来表示的话我们则可以写成:
//循环链表的遍历 bool Ergodic(LNode* p) { assert(p);//当p为空指针时报错 LNode* r = p->next;//进行遍历的指针r while (r->next !
需求 我想做一个类似腾讯云网关日志最终以仪表方式呈现,比如说qps、p99、p95的请求响应时间等等 流程图 数据流转就像标题
nginx ----> rsyslog ----> kafka —> clickhouse —> grafana
部署 kafka kafka 相关部署这里不做赘述,只要创建一个topic 就可以
这里kafka地址是 192.168.1.180,topic是``
rsyslog 设置 rsyslog 具体是啥东西这个我这里也不做介绍,本人也是一个后端开发不是做运维的,只知道这个东西性能不错,算是logstash 平替把
# 安装rsyslog-kafka 插件 yum install -y rsyslog-kafka # 创建一个配置 vim /etc/rsyslog.d/rsyslog_nginx_kafka_cluster.conf conf 内容
module(load="imudp") input(type="imudp" port="514") # nginx access log ==> rsyslog server(local) ==> kafka module(load="omkafka") template(name="nginxLog" type="string" string="%msg%") if $inputname == "imudp" then { # 这里的名字和下面nginx 配置tag 相同 if ($programname == "nginx_access_log") then action(type="
Version : 1.2.2023.12.30
修改项:
增加部分格式的文本和视频浏览的功能
self.app.route('/view_file/<path:file_name>')(self.view_file) # 预览 self.app.route('/preview/<path:file_name>')(self.preview) # 跳转预览网页 self.app.route('/send_view_file/<path:filename>')(self.send_view_file) # 根据不同文件,发送文件给HTML显示 函数块:
def view_file(self, file_name): if not file_name.startswith('/'): if not re.match('.:', file_name): file_name = '/' + file_name return render_template('index.html', foldername=file_name, show_view_file=True, show_upload=False ) def preview(self, file_name): type_ = file_name.split('.')[-1] # 防止多个 .. 造成判断错误 if not file_name.startswith('/'): if not re.match('.:', file_name): file_name = '/' + file_name return render_template('preview.html', filename=file_name, pre_type=type_ ) def send_view_file(self, filename): # 设置文件文件夹路径 if not filename.
双链表及其基本操作的实现 导言一、单链表与双链表二、双链表类型的创建三、双链表的初始化四、双链表的创建五、双链表的遍历六、双链表的查找七、双链表的插入八、双链表的删除九、双链表基本操作完整代码展示结语 导言 大家好,很高兴又和大家见面啦!!!
经过前面几个篇章的内容分享,相信大家对顺序表和单链表的基本操作都已经熟练掌握了。今天咱们将继续分享线性表的链式存储的第二种形式——双链表。在今天的内容中,咱们将介绍双链表的创建以及一些基本操作,接下来跟我一起来看看吧!
一、单链表与双链表 线性表的链式存储称为链表,链表是由数据域和指针域组成。
由一个数据域和一个指针域组成的链表我们称为单链表,单链表的指针域指向后继结点,所以我们在访问单链表时只能从前往后访问。这就导致了一个问题:我们在访问后继结点时的时间复杂度为O(1),但是在访问前驱结点时的时间复杂度却是O(n)。
为了克服单链表的这种单一访问的缺点,于是我们在单链表的结点上新增了一个指针域,使得链表上的每个结点都由一个数据域和两个指针域组成,双链表的结点结构如下所示:
这两个指针域一个指向后继结点(next),一个指向前驱结点(prior),我们将由这种结构的结点构成的链表称为双链表。
双链表和单链表一样,双链表也有带头结点的双链表与不带头结点的双链表,在没有特殊说明的情况下,我们都是以带头结点的双链表进行说明。接下来我们就来看一下与双链表相关的基本操作;
二、双链表类型的创建 我们首先来看一下双链表的类型创建的基本格式:
//双链表类型创建的基本格式 typedef struct DNode { ElemType data;//数据域 struct DNode* prior, * next;//指针域 }DNode, * DLinkList;//数据类型重命名 //DNode——Double Node——强调的是双链表的结点 //DLinkList——强调的是指向双链表的指针,也就是整个双链表 //prior——在先的,在前的,先前的——指向前驱结点的指针 //next——下一个的,紧接着的,接下来的——指向后继结点的指针 //ElemType——数据元素的数据类型 //data——存储链表数据元素的变量 从格式中可以看到,其实双链表与单链表的类型创建格式是一致的,它们之间的差别有以下几点:
为了对这两种类型的链表有所区分,单链表的结点类型我们将其定义为LNode,双链表则是DNode;单链表的类型我们将其定义为LinkList,双链表则是DLinkList;在双链表中,我们定义了一个额外的指针prior用于指向前驱结点; 有了这个基本格式,我们同样还是以整型类型的数据元素为例来定义一个双链表,如下所示:
//创建双链表类型 typedef struct DNode { int data; struct DNode* prior, * next; }DNode, * DLinkList; int main() { DLinkList L;//定义指向双链表的头指针 return 0; } 有了双链表的头指针,接下来我们就可以来创建双链表的头结点并将其初始化了;
三、双链表的初始化 我们先来看一下双链表初始化的基本格式:
//双链表初始化的基本格式 bool InitDLinkList(DLinkList* L) { *L = (DNode*)calloc(1, sizeof(DNode));//创建头结点 assert(*L);//如果头结点创建失败,则报错 (*L)->prior = NULL;//初始化前驱指针 (*L)->next = NULL;//初始化后继指针 return true; } 可以看到,对于双链表来说,我们在初始化头结点时不仅要将后继指针进行初始化,还要将前驱指针进行初始化,这样是为了防止这两个指针变成野指针。
一、实验目的与环境 实验目的: MySQL是互联网中广泛使用的开源数据库。在开发时,我们通常使用单机服务,但在生产环境中,由于数据量庞大和高安全性要求,单机MySQL无法满足这些需求。因此,生产环境中的MySQL需要建立主从复制架构和基于工具的高可用架构,同时实现读写分离。对于极大的数据量,还需实现分库分表。这些架构的建立相对复杂,通常由专业运维人员完成。本次实验旨在让大家理解MySQL在生产环境下的架构,并应用于实际项目中,也为学习ShardingSphere分库分表做准备
实验环境: 1、Linux服务器两台:centos7
2、mysql版本:mysql-8.0.20
二、基础环境介绍 两台服务器,均安装CentOS7。
1、 192.168.232.128 作为mysql主节点部署
2、 192.168.232.129 作为mysql从节点部署
mysql版本:mysql-8.0.20
为了便于使用,两个mysql服务需要打开远程登录权限,开启方式需要在本机登录 mysql,执行以下语句。
#开启远程登录 use mysql; update user set host= '% ' where user= 'root '; flush privileges; 三、搭建主从集群 1、理论基础 主从架构的作用是缓解MySQL的数据存储和访问压力。这一架构不仅对提高系统性能至关重要,还对确保数据安全发挥着重要作用。
数据安全:通过在主服务增加一个备份,主从架构提升了数据的安全性。基于这个目的,可以构建标准的主从架构,或者更进一步,搭建互主架构以进一步增强安全性。
读写分离:考虑到大多数JAVA业务系统中读操作远多于写操作,主从架构使得从服务可以承担读请求,而主服务专注于处理写请求。这不仅减轻了数据库的访问压力,也提高了整体性能。但要注意,实现有效的读写分离还需要依赖特定的中间件,例如ShardingSphere。
故障转移与高可用性:在主服务发生故障时,从服务可以迅速转变为主服务,保证数据的连续可读写。要实现这种高可用性,主从数据同步是基础,但也需要依赖其他中间件,如MMM、MHA、MGR。在数据库访问压力不大的项目中,尽管读写分离可能不是必需的,但搭建主从架构和保证高可用性是基本要求。
2、同步的原理 MySQL的主从架构通常通过binlog日志文件进行数据同步。具体步骤如下:
在主服务上,开启binlog记录每一步的数据库操作。
从服务上有一个IO线程,负责与主服务建立TCP连接,请求主服务传输binlog。
主服务上有一个IO dump线程,通过TCP连接将Binlog日志传输给从库的IO线程。
从服务的IO线程将读取到的binlog日志数据写入自己的relay日志文件中。
从服务上的SQL线程读取relay日志中的内容,进行操作重演,以还原数据。
这种主从架构通常用于MySQL的读写分离配置。
MySQL的binlog不仅可以用于主从同步,还可用于缓存数据同步等情景。例如,Canal可以模拟一个从节点,向MySQL发起binlog同步,然后将数据传输到Redis、Kafka等其他组件,实现实时数据流转。
在搭建主从集群时,有两个必要的要求:
双方MySQL版本必须一致,至少需要主服务的版本低于从服务。
两节点间的时间需要同步。
3、搭建主从集群 3.1 配置master主服务器 首先,配置主节点的mysql配置文件: /etc/my.cnf 这一步需要对master进行配置,主要是需要打开binlog日志,以及指定severId。我们打开MySQL主服务的my.cnf文件,在文件中一行server-id以及一个关闭域名解析的配置。然后重启服 务。
[mysqld] server-id=47 #开启binlog log_bin=master-bin log_bin-index=master-bin.index skip-name-resolve # 设置连接端口 port=3306 # 设置mysql的安装目录 basedir=/usr/local/mysql # 设置mysql数据库的数据的存放目录 datadir=/usr/local/mysql/mysql-files # 允许最大连接数 max_connections=200 # 允许连接失败的次数。 max_connect_errors=10 # 服务端使用的字符集默认为UTF8 character-set-server=utf8 # 创建新表时将使用的默认存储引擎 default-storage-engine=INNODB # 默认使用“mysql_native_password”插件认证 #mysql_native_password default_authentication_plugin=mysql_native_password 重启MySQL服务, service mysqld restart
动态规划 动态规划就像是解决问题的一种策略,它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题,并将每个小问题的解保存起来。这样,当我们需要解决原始问题的时候,我们就可以直接利用已经计算好的小问题的解,而不需要重复计算。
动态规划与数学归纳法思想上十分相似。
数学归纳法:
基础步骤(base case):首先证明命题在最小的基础情况下成立。通常这是一个较简单的情况,可以直接验证命题是否成立。
归纳步骤(inductive step):假设命题在某个情况下成立,然后证明在下一个情况下也成立。这个证明可以通过推理推断出结论或使用一些已知的规律来得到。
通过反复迭代归纳步骤,我们可以推导出命题在所有情况下成立的结论。
动态规划:
状态表示:
状态转移方程:
初始化:
填表顺序:
返回值:
数学归纳法的基础步骤相当于动态规划中初始化步骤。
数学归纳法的归纳步骤相当于动态规划中推导状态转移方程。
动态规划的思想和数学归纳法思想类似。
在动态规划中,首先得到状态在最小的基础情况下的值,然后通过状态转移方程,得到下一个状态的值,反复迭代,最终得到我们期望的状态下的值。
接下来我们通过三道例题,深入理解动态规划思想,以及实现动态规划的具体步骤。
376. 摆动序列 - 力扣(LeetCode) 题目解析 状态表示 状态表示一般通过经验+题目意思得到。
经验是指以某个位置为结尾或者以某个位置为开始。
我们可以很容易定义这样一个状态表示,定义dp[i]表示以i位置元素为结尾的子序列中,最长的摆动序列长度。
我们可以尝试推导一下状态转移方程。
dp[i]表示以i位置元素为结尾的子序列中,最长的摆动序列长度。
我们针对于(以i位置元素为结尾的子序列,以及i位置元素状态)进行分析,想一想dp[i]能不能由其他状态推导得出。
如果只考虑i位置一个元素, 最长的摆动序列长度为1,故dp[i]=1。
如果不止考虑i位置一个元素, 我们发现还需要考虑i位置元素处于“上升”状态还是“下降”状态
如果i位置元素处于“上升”状态,i位置元素可以跟在前面任意(nums[j]<nums[i])的元素后面,我们假设i位置元素跟着j位置元素后面,j位置元素需要处于“下降”状态,而我们要考虑的是最长的摆动序列长度,所以j需要遍历(0~i-1),dp[i]=max(j位置元素(处于”下降“状态,最长的摆动序列长度)+1)j∈[0~i-1]。
如果i位置元素处于“下降”状态,i位置元素可以跟在前面任意(nums[j]>nums[i])的元素后面,我们假设i位置元素跟着j位置元素后面,j位置元素需要处于“上升”状态,而我们要考虑的是最长的摆动序列长度,所以j需要遍历(0~i-1),dp[i]=max(j位置元素(处于”上升“状态,最长的摆动序列长度)+1)j∈[0~i-1]。
我们发现只定义(dp[i]表示以i位置元素为结尾的子序列中,最长的摆动序列长度)这个状态表示是没办法推导出状态转移方程,所以我们修正一下状态表示。
定义 ,
f[i]表示以i位置元素为结尾的子序列中,处于“上升”状态时,最长的摆动序列长度。
g[i]表示以i位置元素为结尾的子序列中,处于“下降”状态时,最长的摆动序列长度。
状态转移方程 我们针对于(以i位置元素为结尾的子序列,以及i位置元素状态)进行分析,想一想dp[i]能不能由其他状态推导得出。
如果只考虑i位置一个元素, 最长的摆动序列长度为1,故f[i]=g[i]=1。
如果不止考虑i位置一个元素, 我们发现还需要考虑i位置元素处于“上升”状态还是“下降”状态
如果i位置元素处于“上升”状态,i位置元素可以跟在前面任意(nums[j]<nums[i])的元素后面,我们假设i位置元素跟着j位置元素后面,j位置元素需要处于“下降”状态,而我们要考虑的是最长的摆动序列长度,所以j需要遍历(0~i-1),f[i]=max(g[j]+1)j∈[0~i-1],g[i]=1。
如果i位置元素处于“下降”状态,i位置元素可以跟在前面任意(nums[j]>nums[i])的元素后面,我们假设i位置元素跟着j位置元素后面,j位置元素需要处于“上升”状态,而我们要考虑的是最长的摆动序列长度,所以j需要遍历(0~i-1),g[i]=max(f[i]+1)j∈[0~i-1],f[i]=1。
将上述情况进行简化和合并,我们发现有许多情况f[i]=g[i]=1,并且1是最低的标准,任何位置的状态最少都是1,所以我们可以把这些情况放在初始化部分处理,即先把所有位置的状态初始化为1。
所以我们可以得到状态转移方程,
for (int i = 1; i < n; i++) { for (int j = 0; j < i; j++) { if (nums[i] > nums[j]) { f[i] = fmax(f[i], g[j] + 1); } else if (nums[i] < nums[j]) { g[i] = fmax(g[i], f[j] + 1); } } } 初始化 根据状态转移方程,我们推导i位置的状态时,需要用到(0~i-1)位置的状态,所以我们应该初始化第一个位置的状态,即f[0]=g[0]=1。
本文来自“2023年服务器计算机CPU行业词条报告”,中国计算机CPU行业发展进入“快车道”,在2019-2021年间以6.91%的平均增速稳步快速增长,预计到2027年中国CPU市场规模将达710.75亿元。随着中国本土计算机CPU企业的技术创新和研发投入不断增加,中国与海外计算机CPU市场结构发生显著变化,中国企业的身影正逐步进入人们的视野,成为全球芯片产业中备受瞩目的一部分。
1、计算机CPU行业定义
计算机CPU全称为中央处理器,通常由控制单元、算术逻辑单元(ALU)和寄存器组成,是一种负责解释和运算计算机程序中的指令以及控制计算机操作的集成电路,对计算机的性能和运行效率具有重要影响。随着第四次工业革命的来临,CPU作为计算机的运算和控制核心,有望深入到自动化生产线控制、工业物联网、人机交互和机器学习等全新的应用场景,潜在市场和需求有稳步扩大的发展态势。
2、计算机CPU行业分类
按照计算机CPU所使用的指令集架构划分,目前主流的CPU可分为使用MIPS架构、X86架构、ARM架构和RISC-V架构的CPU。
3、计算机CPU行业特征
中国计算机CPU行业的特征包括:外企主导市场,中国与海外市场竞争激烈;技术依赖性强,自研阻力大;客户集中风险大,影响企业利润水平。随着国产CPU的逐步崛起,中国计算机CPU行业将朝着自主化、产业化的
外企主导市场,中国与海外市场竞争激烈
全球通用处理器市场主要由Wintel(微软与英特尔)和AA(谷歌与ARM)两大生态系统主导。2022年,Intel在全球服务器CPU市场占据了70.77%的份额,而AMD为19.8%,这两大巨头的CR2达到了90.57%,凸显了其在国际CPU市场的垄断地位。在中国,Intel和AMD在X86服务器CPU市场的份额分别为91.0%和5.7%。尽管近十年中国涌现出华为鲲鹏、龙芯等本土企业,但大多独立运作,且存在多种CPU架构,这种多样性可能导致资源分散,增加行业内部竞争,从而影响整体效益。如果此趋势持续,中国CPU行业可能难以产生能与全球主流厂商,如Intel和AMD,有效竞争的产品。
技术依赖性强,自研阻力大
在指令集架构上,中国CPU行业存在两种发展方向:一是“授权+自研”,发展自主可控的指令集架构,如龙芯中科脱胎于MIPS架构,自主研发的LoongArch架构和上海申威基于Alpha架构研发的SW64架构。这种方向的优势在于可以实现自主可控,很大程度上避免出现“卡脖子”的不利局面,并且能满足中国应用领域的需求;劣势在于基础薄弱,研发成本高,产品生态小众,难以进入国际主流CPU之列。
二是“纯授权”,通过与国外企业达成架构授权协议,使用现成的架构,如飞腾、华为海思均使用ARM架构,上海兆芯和海光信息均使用X86架构。但目前ARM和X86架构已停止向中国企业授权,即使拥有永久授权的企业,也将面临架构停止更新、技术逐步落后的难题。这种方向的优势在于可利用已成熟的技术和生态,拓宽下游市场,降低企业研发成本和技术门槛;劣势在于受架构知识产权制约和国际形势影响,很难实现自主可控,难以规避各种制裁,同时需要支付高额的架构版权费,降低企业利润。在芯片制造上,中国芯片国产化率低,在2020年该指标仅为16%,且主要集中在28nm级别以上的中低端芯片,高端芯片的渗透率低,14nm/16nm级别以下的芯片大多由台积电、AMSL等境外厂商代工。在芯片生产的供应链上游,中国CPU各大厂商均大量使用了国外的技术和设备。
4、计算机CPU产业链分析
中国计算机CPU产业链结构较为复杂,涉及众多外企和中国本土企业。上游环节包括圆晶代工、封装测试、架构设计和授权三个关键部分,代表企业有台积电、长电科技、Intel;中游环节包括CPU的设计和制造,代表企业有海光信息、龙芯中科、海思半导体;下游环节包括服务器、工作站、PC/平板、移动终端和嵌入式设备等,代表企业有华为、联想、比亚迪、海康威视。
中国CPU产业链上游拥有较强的议价能力,利润率较高,能够对中游企业进行纵向垄断,且垄断性强,呈外企/台企占据主导地位,中国大陆本土企业紧随其后的发展态势。产业链中游发展存在转移趋势。中国的芯片设计和制造能力在过去几年里有了显著提升,越来越多中国企业开始在CPU设计和制造领域投入大量资源,并取得了一定的成果。这表明产业链中游正在向中国发展,逐步减少对外依赖。
产业链下游市场正迎来拓展民用市场的重大机遇。中国CPU企业需要及时拓展业务范围,增加有效投资和技术开发,满足多样化的市场需求,实现全产业链的发展和突破。产业链发展堵点则主要集中在技术和知识产权方面的挑战。CPU的设计和制造涉及高度复杂的技术和专利,中国CPU企业在这方面的积累和创新仍然有一定的差距。此外,资金和人才的供给也是限制产业链发展的重要因素之一。
产业链上游
晶圆代工或晶圆专工指的是半导体产业的一种营运模式,专门从事半导体晶圆制造生产,接受其他IC设计公司委托制造,而不自己从事设计,目前多数CPU厂商均采用该模式。
(1)从供给角度分析,中国正逐步实现圆晶代工自给,增强圆晶代工环节的可控性,进一步保障中国CPU产业链在圆晶代工环节的国家安全。
(2)从议价能力角度分析,圆晶代工头部企业具有较高的毛利率。以具有一定代表性的行业龙头台积电、格芯、中芯国际为例,其毛利率分别为62.2%、60.1%和53.1%。
产业链中游
CPU设计企业执行芯片级的设计工作,将CPU架构转化为具体的电路设计。这包括利用硬件描述语言(如Verilog或VHDL)编写电路逻辑和功能,并进行验证、仿真和优化。
(1)从盈利能力角度分析,中国CPU设计企业的盈利能力存在较大的差异,行业平均水平处于中等水平。以龙芯中科招股说明书中公布的2021年中国CPU设计企业各上市公司毛利率为例,最大值为景嘉微的63.24%,最小值为北京君正的36.10%,最大值和最小值之间的差距超过27个百分点,而中值为46.72%。
(2)从技术水平角度分析,与国际一流CPU相比,中国国产CPU在制程、核心数、超线程、主频、内存通道数和最高内存频率等关键指标上仍存在一定差距,这种差距主要体现在设计能力上。以Intel和完全自主的龙芯对比,Intel在130nm工艺就做到了主频3.8G,而龙芯的3A1000在同等工艺和核数前提下,主频只有1G;如果将Intel产品降到1G,性能将是龙芯的5倍。纵向对比看,同样以龙芯为例,其第二代产品3A2000在没有提升主频的前提下,通过设计能力的改进,性能提升了2.5倍;
3A3000提升至28nm制程后,主频提升至1.5G,性能提升1.6倍;3A4000在原工艺基础上,通过设计提升性能2倍;3A5000提升至14nm制程,性能提升1.6倍;目前在研的3A6000,据龙芯介绍,其性能已经达到了Intel在14nm的性能水平。从纵向发展历程来看,相同工艺条件下,设计能力提升带来的产品性能提升十分显著,在fabless模式下,设计能力的差距显得尤为重要。
产业链下游
CPU下游应用端包括服务器、工作站、PC/平板、移动终端和嵌入式设备等,汽车是嵌入式设备中比较具有发展前景的细分市场。
(1)从应用场景角度分析,下游产业在中国与海外都拥有巨大市场,整体利润率高,但垄断情况相对较低。目前国产CPU主要需求来自服务器、政企、信创等市场,鲜少出现在消费级市场。“中国芯”在政务领域已进入大规模应用阶段。
(2)从应用需求角度分析,新能源汽车需求的激增将同步拉动对耐高温和可靠性强的CPU的市场需求,推动CPU设计企业朝定制化、多样化的方向进行产业转型。
5、计算机CPU行业规模
中国计算机CPU行业目前处于高速发展期,在2019-2021年期间以6.91%的平均增速稳步快速增长。2022年受新冠疫情反弹、全球CPU产业链受国际形势影响和“缺芯潮”等多种不利因素的冲击,计算机CPU行业规模下降至314.82亿元,较2021年下降了15.19%。随着中国政府出台一系列鼓励政策、国际局势的逐步稳定、5G和物联网等新兴领域的驱动,对高性能、低功耗、集成度高的CPU的需求将持续增加,中国CPU行业规模有望持续稳步发展。预计到2027年中国计算机CPU市场规模将达5109.49亿元。
中国CPU行业市场规模的稳步增长逻辑主要体现在两个方面:
(1)中国经济环境和科学技术的不断发展带动拉动需求增长和转型。一方面,中国消费者消费能力的提高和消费习惯的变化进一步拉动了CPU及其下游行业的发展。另一方面,新兴技术领域的发展推动了对高性能处理器的需求增加。随着中国5G技术的不断普及、人工智能和物联网的快速发展,对处理器性能的需求越来越高。根据中国工信部发布的数据,2020年中国5G终端出货量超过1.7亿台,5G终端的普及使得对高性能处理器的需求进一步增加。同时,人工智能在各个行业的应用也在不断扩大,对高性能CPU的需求正不断增加。
(2)中国供给侧结构性改革效果显著,全产业链的日益完善推动CPU行业的快速发展。一方面,中国政府出台了一系列支持性政策,鼓励本土企业在CPU领域进行技术研发和创新。另一方面,中国的CPU市场发展得益于完善的产业生态链系统。从芯片设计、制造到封装测试,整个CPU生态链系统得到不断完善,提高了供给效率和产品质量。随着产业链的蓬勃发展,中国成为全球CPU供应链的重要一环,进一步提升了中国CPU的供给能力。
6、计算机CPU竞争格局
中国计算机CPU行业的竞争格局涉及多家本土企业和国际企业,且以外企为主导,市场集中度较高。本土企业虽然占有的市场份额较少,但近年来行业整体得到快速发展,市场竞争日趋激烈。中国大陆本土CPU行业大致分为三个梯队:
(1)第一梯队是以海光信息、海思半导体、上海兆芯、龙芯中科等企业为代表的领军企业。这些企业多为上市公司或母公司上市,拥有较强的融资能力,在技术积累和市场拓展方面具有优势;同时较早布局多种类型的CPU应用市场及配套产品的研发,具有较为完善的产业链和广泛的业务范畴,在业内具有较强的影响力和品牌效应。如海思半导体推出鲲鹏920处理器时,同步推出了基于鲲鹏920的TaiShan服务器和华为云服务,形成独特的“端边云算力同构”的优势,通过软硬件协同进一步提升处理器性能。
(2)第二梯队是以飞腾信息、北京君正、炬芯科技等企业为代表的企业。这些企业拥有灵活的融资方式和政策支持,具备良好的研发和创新能力,但也面临产品的同质化程度上升、核心竞争力需要不断加强等问题。
(3)第三梯队是以平头哥、国芯科技、申威科技等企业为代表的企业。这些企业往往拥有独特的发展模式,业务类型较为专一,如平头哥在建立之初即明确了以RISC-V架构为基础的发展方向,深耕企业未来的发展价值;而飞腾信息则主要聚焦军用市场,产品侧重特种超算服务器领域,全可控技术与生态均有独家壁垒,预计后续仍将专注深耕原有领域。
从产业链整合角度,CPU行业上中游均存在较高的技术壁垒,中游企业对上游供应商的原材料、设备和技术依赖性强,资本实力雄厚的中游企业通过收购、兼并上游企业实现全产业链,避免关键技术和产业流程受限的趋势明显。在2022年全球芯片十大收购案中,有三项交易业务涉及芯片设计,涉及金额达1246.9亿美元;三项交易业务涉及圆晶代工,涉及金额达60.05亿美元。从技术和业务重合角度,当前中国大陆本土CPU行业整体技术水平相似度较高,业务重合度较高,可能存在同业业务兼并的趋势。
以上内容来自智能计算芯世界
多年来一直专注于科学计算服务器,入围政采平台,H100、A100、H800、A800、L40、L40S、RTX6000 Ada,RTX A6000,单台双路256核心服务器等。
学习视频:【编程不良人】Mybatis-Plus整合SpringBoot实战教程,提高的你开发效率,后端人员必备!
查询方法详解 普通查询
// 根据主键id去查询单个结果的。 @Test public void selectById() { User user = userMapper.selectById(1739970502337392641L); System.out.println(user); } //根据多个主键id批量查询结果的 @Test public void selectIds() { List<Long> list = Arrays.asList(1739970502337392641L, 1739983903621038082L, 1739984905459900417L); List<User> userList = userMapper.selectBatchIds(list); userList.forEach(System.out::println); } // 根据多个条件查询结果的 @Test public void selectByMap() { // map.put("name","小明") // map.put("age",30) // 相当于 where name ="小明" and age=30 Map<String, Object> columnMap = new HashMap<>(); columnMap.put("name", "小刚"); columnMap.put("age", "18"); List<User> userList = userMapper.selectByMap(columnMap); userList.forEach(System.out::println); } 条件构造器查询 【重要】
欢迎来到我的博客,代码的世界里,每一行都是一个故事 SSH -L:安全、便捷、无边界的网络通行证 前言1. SSH -L基础概念SSH -L 的基本语法:端口转发的原理和作用: 2. SSH -L的基本用法远程访问本地示例:访问本地Web服务示例:通过SSH跳板机访问内部服务 本地访问远程示例:通过本地访问远程MySQL服务 动态端口转发动态端口转发的基本语法:通过动态端口转发实现全局代理: 最佳实践最佳实践:安全注意事项: 前言 在网络的无边际世界里,有时候我们需要突破种种限制,安全地穿越网络的边界。这就像是一场奇妙的冒险,而SSH -L则是你的导航仪。想象一下,就像在网络空间中挖掘一条安全通道,让数据安全、便捷地流动,就像在网络的边界开辟一扇神奇的门。
SSH -L 是一种SSH(Secure Shell)命令行选项,用于实现本地端口转发。本地端口转发是一种在安全通信通道中将本地计算机上的端口映射到远程服务器的指定端口的技术。这种功能对于建立安全的连接、绕过防火墙、访问内部网络服务等场景非常有用。
1. SSH -L基础概念 SSH -L 的基本语法: ssh -L [local_bind_address:]local_port:remote_host:remote_port user@ssh_server local_bind_address:本地绑定地址,通常是 127.0.0.1 或 localhost。如果未指定,则默认为 localhost。local_port:本地计算机上要绑定的端口。remote_host:远程服务器的主机名或IP地址。remote_port:远程服务器上要映射的端口。user@ssh_server:SSH服务器的用户名和地址。 端口转发的原理和作用: 端口转发是通过SSH安全通道将本地端口映射到远程服务器上的指定端口,从而实现安全的数据传输。这种技术有两种主要类型:本地端口转发(Local Port Forwarding)和远程端口转发(Remote Port Forwarding)。
本地端口转发(Local Port Forwarding):
本地端口转发是将本地计算机上的端口映射到远程服务器上。当本地计算机上的应用程序连接到指定的本地端口时,SSH客户端会将流量加密并通过SSH通道传输到远程服务器上,然后将流量解密并转发到远程服务器上的指定端口。这种方式常用于访问远程服务器上的服务,如数据库、Web服务等,而不直接将这些服务暴露在公共网络中。 ssh -L 8080:localhost:80 user@ssh_server 上述例子中,本地计算机的端口 8080 被映射到远程服务器的本地地址(localhost)上的端口 80。
远程端口转发(Remote Port Forwarding):
远程端口转发是将远程服务器上的端口映射到本地计算机上。当远程服务器上的应用程序连接到指定的端口时,SSH客户端会将流量加密并通过SSH通道传输到本地计算机上,然后将流量解密并转发到本地计算机上的指定端口。这种方式可用于在远程服务器上访问本地计算机上的服务,如本地数据库、Web服务等。 ssh -R 2222:localhost:22 user@ssh_server 上述例子中,远程服务器的端口 2222 被映射到本地计算机的端口 22,允许在远程服务器上通过SSH连接到本地计算机。
总体而言,SSH的端口转发提供了一种安全、加密的通信通道,使得在不同网络中的计算机之间可以安全地共享服务和数据。
2. SSH -L的基本用法 远程访问本地 示例:访问本地Web服务 假设本地计算机上有一个运行在端口 8080 的Web服务,我们想通过SSH访问该服务。
△△请给“Python猫”加星标 ,以免错过文章推送
你好,我是猫哥。这里每周分享优质的 Python、AI 及通用技术内容,大部分为英文。本周刊开源,欢迎投稿[1]。另有电报频道[2]作为副刊,补充发布更加丰富的资讯。
🦄文章&教程 1、Flask 已死,FastAPI 是未来[3]
一篇标题十分吸睛引战的文章。说实话因见过太多“xxx 已死”、“再见了 xxx”这种煽动情绪的标题,我已经习惯绕道不读。比较框架优缺点,这非常合理,但刻意往贬低一方的角度引,就显狭隘了。(附:一篇回应文 Flask 已死,FastAPI 永生[4]、对回应文的回应文 理性参与讨论《Flask 已死,FastAPI 永生》[5])
2、Python + Flask 打造属于自己的 RSS 安全信息流[6]
如何用 Python 搭建属于自己的 RSS 信息流网站?文章介绍了一个完整的 Flask 项目,支持对接 RSS、解析文章、自动更新,最后部署上线并使用 Nginx 作反向代理。
3、Microdot:又一个 Python Web 框架[7]
作者介绍了自己开源的一个语法类似于 Flask 的 Web 框架,完全支持 asyncio 异步,支持 Websocket、SSE、CORS、Jinja 和 uTemplate 模板等功能。非常小(核心框架代码 700 多行),可以跟 MicroPython 一起使用。
4、周末 AI 项目:在 2004 年的诺基亚 9500 上运行 7B 大型语言模型[8]
在近 20 年前的早期智能手机上运行当下最火的大语言模型,这事感觉蛮有趣!作者使用大小为 4GB 的Llama-2–7B-Chat-GPTQ 模型,最先尝试用 Streamlit 创建应用,但发现它的浏览器不支持,最后用 Flask 开发一个简单的网页,实现与 LLM 的交互!