React Query:高效管理API请求与缓存

React Query 是一个强大的状态管理库,专门用于处理数据获取、缓存和更新,尤其适合与 API 交互。它提供了许多高级特性,如自动缓存、离线状态管理、数据过期和重新获取等。 安装: npm install react-query 导入并配置 React Query: 在你的应用中,你需要导入 useQuery Hook 并设置配置对象。 import { useQuery } from 'react-query'; const queryClient = new QueryClient(); 可以通过 QueryClientProvider 将 queryClient 包裹在你的根组件周围,以便在整个应用中使用。 import { QueryClient, QueryClientProvider } from 'react-query'; const queryClient = new QueryClient(); function App() { return ( <QueryClientProvider client={queryClient}> {/* Your application */} </QueryClientProvider> ); } 使用 useQuery Hook: 使用 useQuery 来发起 API 请求并管理响应数据。 function MyComponent() { const { data, status, error } = useQuery('myQueryKey', () => fetch('https://api.

在 JavaScript 中实现数据加密与解密:Web Cryptography API 与 CryptoJS详解

在 JavaScript 中,可以使用 Web Cryptography API 或第三方库如 crypto-js 来实现加密和解密。本文将介绍如何使用这两种方法在客户端进行数据的加密和解密。 使用 Web Cryptography API Web Cryptography API 是现代浏览器提供的一个强大、原生的加密 API。它允许在客户端进行加密、解密、签名和验证等操作。 生成密钥对 首先,生成一个 RSA 密钥对: async function generateKeyPair() { const keyPair = await window.crypto.subtle.generateKey( { name: "RSA-OAEP", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" }, true, ["encrypt", "decrypt"] ); const publicKey = await window.crypto.subtle.exportKey("spki", keyPair.publicKey); const privateKey = await window.crypto.subtle.exportKey("pkcs8", keyPair.privateKey); return { publicKey: publicKey, privateKey: privateKey }; } generateKeyPair().then(keyPair => { console.

utf8mb4_general_ci和utf8mb4_0900_ai_ci

utf8mb4_general_ci和utf8mb4_0900_ai_ci 在 MySQL 数据库中,字符集和排序规则(collation)决定了如何存储和比较字符串数据。utf8mb4 是 MySQL 中用于支持完整的 UTF-8 字符(包括表情符号和其他 4 字节字符)的一种字符集。 utf8mb4 字符集有多种排序规则,其中常用的有 utf8mb4_general_ci 和 utf8mb4_0900_ai_ci。这两者的主要区别在于其排序和比较规则。以下是它们的详细说明: 1. utf8mb4_general_ci 名称解析:utf8mb4 是字符集,general_ci 是排序规则。ci 代表不区分大小写(case-insensitive)。性能:在排序和比较时,utf8mb4_general_ci 通常比其他utf8mb4 排序规则速度更快,因此性能上有优势。不支持的特性: 不完全的 Unicode 支持:不能处理一些非常特殊的 Unicode 比较和排序规则。例如,同一个字符的不同变体在 general_ci 中可能不会被认为是相同的字符。 排序和比较规则:简单地基于字母进行排序,不考虑任何语言学的复杂性。 适用于需要快速排序和比较、不太注重精确 Unicode 支持的应用场景。 2. utf8mb4_0900_ai_ci 名称解析:utf8mb4 是字符集,0900_ai_ci 是排序规则。ai 代表不区分重音(accent-insensitive),ci 代表不区分大小写(case-insensitive)。实现方式:基于 Unicode 9.0 的排序和比较规则,提供更精确、更现代的 Unicode 支持。特性支持: 更好的 Unicode 支持:处理非常复杂的 Unicode 场景,能够正确地进行语言学上的排序和比较。Accent and Case Insensitive:即不区分重音和大小写。例如,‘é’ 和 ‘e’ 被认为是相同的字符,‘A’ 和 ‘a’ 也被认为是相同的字符。 性能:由于要处理更复杂的排序和比较规则,性能可能不如 utf8mb4_general_ci。 适用于需要更高精确度和完整 Unicode 支持的应用场景,特别是需要按照国际化标准进行排序和比较的系统。 比较和选择 使用场景举例: utf8mb4_general_ci:

kafka 发送文件二进制流及使用header发送附属信息

文章目录 背景案例发送方接收方 背景 需要使用kafka发送文件二进制以及附属信息 案例 发送方 import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.ProducerRecord; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Properties; public class SendFileToKafka { public static void main(String[] args) { String filePath = "com/example/kafka/file/ConsumerFileByteArrayFromKafka.java"; Properties kafkaProps = new Properties(); kafkaProps.put("bootstrap.servers", "192.168.56.112:9092"); kafkaProps.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); kafkaProps.put("value.serializer", "org.apache.kafka.common.serialization.ByteArraySerializer"); KafkaProducer<String, byte[]> producer = new KafkaProducer<>(kafkaProps); InputStream in = SendFileToKafka.class.getResourceAsStream("/com/example/kafka/file/ConsumerFileByteArrayFromKafka.java"); try { byte[] buffer = new byte[in.available()]; // 读到buffer字节数组中 in.read(buffer); ProducerRecord<String, byte[]> record = new ProducerRecord<>("dataTopic", buffer); String header = "

PostgreSQL启动报错“could not map anonymous shared memory: Cannot allocate memory”

PostgreSQL启动报错“could not map anonymous shared memory: Cannot allocate memory” 基础信息 OS版本:Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本:16.2 pg软件目录:/home/pg16/soft pg数据目录:/home/pg16/data 端口:5777 报错 [pg16@test ~]$ pg_ctl start waiting for server to start....2024-06-01 22:20:02.156 PDT [68668] DEBUG: registering background worker "logical replication launcher" 2024-06-01 22:20:02.157 PDT [68668] DEBUG: loaded library "pg_stat_statements" 2024-06-01 22:20:02.157 PDT [68668] FATAL: could not map anonymous shared memory: Cannot allocate memory 2024-06-01 22:20:02.157 PDT [68668] HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages.

【Java】javafx界面布局

目录 一、面板类 (1)Pane面板 (2)HBox面板 (3)VBox面板 (4)BorderPane面板 (5)FlowPane面板 (6)GridPane面板 (7)StackPane面板 二、Color类和Font类 ​三、Line类(直线) 四、Text类 一、面板类 (1)Pane面板 package com.javafx; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.Rectangle; import javafx.stage.Stage; public class Panex extends Application { @Override public void start(Stage primaryStage) throws Exception { Circle circle=new Circle(25, Color.LIGHTCORAL); circle.setCenterX(100); circle.setCenterY(50); Rectangle rectangle=new Rectangle(100,40,Color.LIGHTBLUE); rectangle.relocate(100,50); //旋转 rectangle.setRotate(-33); Pane pane=new Pane(circle,rectangle); // pane.getChildren().addAll(circle, rectangle); Scene scene=new Scene(pane,300,200); primaryStage.setTitle("面板图形"); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { Application.

java jar包后台运行方式

在实际工作中,java开发的spring boot等通过jar包部署需要一直运行的程序部署到服务器上时,都希望后台运行,方便管理程序服务、防止被误操作关闭,本文结合自己工作经验讲解jar包后台运行的两种方式,分别是按操作系统支持的特殊方式和统一执行命令的方式。 方式一:按操作系统支持的方式后台运行 可执行jar包程序可以按操作系统支持的方式运行,不同操作系统执行命令和方式不一样,这里主要讲解linux操作系统和window操作系统下如何按操作系统支持的特殊方式后台运行。 linux操作系统 Linux操作系统java程序后台运行又主要分如下两种方式: 1.通过nohup命令和&符号运行。 终端关闭后程序也会继续运行,示例如下: nohup java -jar demo.jar > nohup.log 2>&1 & 示例命令说明: nohup:使得终端关闭,运行的命令也不中断。 java -jar demo.jar:用于启动jar包。 nohup.log:标准输出重定向到nohup.log文件。 2>&1:标准错误重定向到标准输出(即nohup.log文件)。 &:命令放入后台执行。 执行上述命令后,程序后台运行,日志记录到nohup.log里,可以使用tail等命令看日志文件,并且会得到一个进程ID(PID,这个PID可以通过ps ax|grep "demo.jar"查找),可以使用kill命令通过这个PID来终止进程。 2.jar配置为可自启动的服务。 在Linux上将jar文件设置为服务需要编写一个系统服务单元文件(.service文件),然后使用systemd来管理服务。以下是一个示例: 创建服务单元文件 ​​/etc/systemd/system/your-service.service​​: [Unit] Description=Your Java Application as a Service After=network.target [Service] User=<username> Type=simple ExecStart=/usr/bin/java -jar /path/to/your-application.jar Restart=on-failure [Install] WantedBy=multi-user.target 重新加载systemd管理器配置: sudo systemctl daemon-reload 启动服务: sudo systemctl start your-service.service 设置服务开机自启: sudo systemctl enable your-service.service 确保替换 ​​<username>​​​ 和 ​​/path/to/your-application.jar​​​ 为实际的用户名和jar文件路径。如果需要传递额外的Java选项,可以在 ​​ExecStart​​ 中添加。

如何注册及使用飞浆AI Studio资源跑模型

之前已经介绍过如何注册及使用Kaggle平台的资源跑模型,今天我们将介绍如何注册及使用飞浆AI Studio资源​。 一、AI Studio简介 飞桨AI Studio是基于百度深度学习开源平台飞桨(PaddlePaddle)的人工智能学习与实训社区。我们先让文心一言给对AI Studio介绍。以下是文心一言给出的答案。 飞浆AI Studio(通常指的是百度飞桨(PaddlePaddle)的AI Studio平台)在人工智能领域扮演着重要的角色,其作用和价值主要体现在以下几个方面: 提供高效的学习环境: 飞浆AI Studio为AI爱好者、学习者和研究者提供了一个云端的高效学习环境。用户无需配置复杂的本地环境,即可直接在线上进行深度学习模型的训练和实验。这大大降低了学习和研究的门槛,使更多人能够参与到人工智能的研究和应用中来。 免费GPU算力支持: 平台提供免费的GPU算力支持,这对于需要大规模计算资源的深度学习模型训练来说至关重要。用户可以通过AI Studio快速完成模型训练,验证算法效果,加速研究进程。 丰富的实训项目和课程: 飞浆AI Studio提供了大量的实训项目和课程,从基础到进阶,覆盖了人工智能的各个领域。用户可以通过完成这些项目和课程,系统地学习和掌握人工智能的核心技术,提高自己的实践能力和创新能力。 竞赛与合作的平台: AI Studio也是举办各类AI竞赛的平台,如国际大数据竞赛、CVPR挑战赛等。这些竞赛不仅为用户提供了展示自己才华的机会,也促进了学术界的交流与合作,推动了人工智能技术的创新和发展。 助力产业应用: 飞浆AI Studio致力于将人工智能技术与产业应用相结合,通过提供技术支持和解决方案,帮助企业和个人解决实际问题。这有助于推动人工智能技术的普及和应用,促进社会的智能化发展。 促进开源生态建设: 飞浆AI Studio支持开源项目,鼓励用户分享自己的研究成果和代码。这有助于构建一个开放、共享、合作的开源生态系统,推动人工智能技术的持续发展。 降低学习成本: 通过提供免费的资源和支持,飞浆AI Studio降低了学习人工智能的成本。这使得更多的人能够接触到先进的技术和工具,从而推动整个行业的发展。 综上所述,飞浆AI Studio在提供高效学习环境、支持技术创新、推动产业应用、促进开源生态建设等方面发挥了重要作用,对于推动人工智能技术的发展和应用具有重要意义。 总结来说,飞桨AI Studio是一个集学习、实训、竞赛于一体的综合性人工智能平台,旨在为开发者提供全方位的支持和服务,帮助他们更好地掌握和应用人工智能技术。 二、AI Studio注册​及登录 我们先让​文心一言给我们介绍如何注册AI Studio。以下是文心一言给出的建议。 ​ 注册AI Studio(以飞桨AI Studio为例)的步骤如下: 访问AIStudio官网: 打开浏览器,输入网址aistudio.baidu.com并打开飞桨AIStudio官网。 选择“注册”按钮: 在主页底部的导航菜单中,找到并点击“注册”按钮。 填写注册信息: 邮箱:是必填项,请务必使用您经常使用的邮箱地址进行注册。 密码:应至少包含六个字符,并且包括数字、字母和特殊字符,以提高账户安全性。在“确认密码”文本框中输入相同的密码。 昵称:必须包含两到六个字符。 在注册页面中,您需要填写各种个人信息: 填写完个人信息后,需要完成人机验证,以确保您是一个真实的用户。 阅读并同意相关协议: 勾选“已阅读并同意《计算资源服务使用协议》和《隐私政策》”的勾选框。 点击“注册”按钮: 完成上述步骤后,点击“注册”按钮提交注册信息。 验证邮箱: 打开您的邮件应用程序,并找到“飞桨AIStudio注册”标题的邮件。 在邮件中,您将找到一个链接,点击链接即可完成邮箱验证。 注册完成后,您需要前往您的邮箱进行验证。 登录AIStudio: 在主页底部的导航菜单中,选择“登录”按钮。 使用您注册时输入的邮箱和密码进行登录。 在完成邮箱验证后,您可以回到飞桨AIStudio官网并登录您的账户。 开始使用: 在这里,您可以轻松创建项目、访问各种机器学习小工具并访问丰富的学习资源。 您还可以参与各种开源社区,并与其他热衷于人工智能的用户进行交流和分享。 登录成功后,您将进入AIStudio的主页面。

超级好用的C++实用库之MD5信息摘要算法

💡 需要该C++实用库源码的大佬们,可搜索微信公众号“希望睿智”。添加关注后,输入消息“超级好用的C++实用库”,即可获得源码的下载链接。 概述 MD5信息摘要算法是一种广泛使用的密码散列函数,由Ronald L. Rivest在1991年设计并公布。它是MD4算法的增强版,用于确保信息的安全性和完整性。MD5接受任意长度的消息作为输入,并输出一个固定长度的128位(16字节)散列值,通常以32位的十六进制数形式表示,每个字节两位。 CHP_Md5 为了方便使用MD5信息摘要算法,我们封装了CHP_Md5类。MD5算法通过一系列复杂的非线性操作,包括:位运算、逻辑函数和加法运算,将输入信息分为512位的块进行处理。整个过程分为四个步骤,每一步使用不同的非线性函数和常数,经过多次迭代完成。 CHP_Md5类的头文件,可参考下面的示例代码。 #pragma once class CHP_Md5 { public: CHP_Md5(); ~CHP_Md5(); void Init(); int Update(unsigned char *pucInput, unsigned int uiInputLen); int Final(unsigned char pucOutput[16]); static int CalcDigest(unsigned char *pucInput, unsigned int uiInputLen, unsigned char pucOutput[16]); private: static void MD5Transform(unsigned int puiState[4], unsigned char pucBlock[64]); static void Encode(unsigned char *pucOutput, unsigned int *puiInput, unsigned int uiInputLen); static void Decode(unsigned int *puiOutput, unsigned char *pucInput, unsigned int uiInputLen); static void MD5Memcpy(unsigned char *pucDest, unsigned char *pucSrc, unsigned int uiLen); static void MD5Memset(unsigned char *pucData, int nData, unsigned int uiLen); private: typedef struct _TMd5ContextInfo { unsigned int state[4]; unsigned int count[2]; unsigned char buffer[64]; }TMd5ContextInfo; TMd5ContextInfo m_ctx; }; CHP_Md5类有4个公共成员函数,包括3个实例函数和1个静态函数,下面逐一进行介绍。

算法学习笔记——对数器

对数器 对数器的实现: 你想要测的方法a(最优解)实现复杂度不好但是容易实现的方法b(暴力解)实现一个随机样本产生器(长度也随机、值也随机)把方法a和方法b跑相同的输入样本,看看得到的结果是否一样如果有一个随机样本使得比对结果不一致,打印这个出错的样本进行人工干预,改对方法a和方法b当样本数量很多时比对测试依然正确,可以确定方法a(最优解)已经正确。 关键是第5步,找到一个数据量小的错误样本,便于你去带入debug 然后把错误例子带入代码一步一步排查 Print大法、断点技术都可以 对数器的门槛其实是比较高的,因为往往需要在两种不同思路下实现功能相同的两个方法,暴力一个、想象中的最优解是另一个。 以后的很多题目都用到对数器,几乎可以验证任何方法,尤其在验证贪心、观察规律方面很有用。 public static void main(String[] args){ // 随机数组最大长度 int N = 100; // 随机数组每个值,在1~V之间随机 int V = 1000; // testTimes : 测试次数 int testTimes = 50000; System.out.println("测试开始"); for (int i = 0; i < testTimes; i++){ // 随机得到一个长度,长度在[0~N-1] int n = (int) (Math.random() * N); // 得到随机数组 int[] arr = randomArray(n, V); int[] arr1 = copyArray(arr); int[] arr2 = copyArray(arr); int[] arr3 = copyArray(arr); selectionSort(arr1); bubbleSort(arr2); insertionSort(arr3); if (!

列表和列表项

一、列表和列表项简介 列表是 FreeRTOS 中的一个数据结构,列表被用来跟踪 FreeRTOS中的任务(任务当前的状态),列表项就是存放在列表中的项目 列表相当于链表,列表项相当于节点,FreeRTOS 中的列表是一个双向循环链表 列表项间的地址非连续的,列表项的数目随时可以改变 列表项的指向前一个、后一个指针,就相当于人的左右手,整个列表就相当于N个人互相拉着手,围成一个圈,而列表是管理这个圈 二、 列表与列表项 2.1 列表结构体 typedef struct xLIST { listFIRST_LIST_INTEGRITY_CHECK_VALUE /* 校验值 */ volatile UBaseType_t uxNumberOfItems; /* 列表中的列表项数量 */ ListItem_t * configLIST_VOLATILE pxIndex /* 用于遍历列表项的指针 */ MiniListItem_t xListEnd /* 末尾列表项 */ listSECOND_LIST_INTEGRITY_CHECK_VALUE /* 校验值 */ } List_t; 成员说明: 成员描述 listFIRST_LIST_INTEGRITY_CHECK_VALUE listSECOND_LIST_INTEGRITY_CHECK_VALUE 具有确定已知常量的宏 FreeRTOS通过检查这两个常量的值,来判断列表的数据在程序运行过程中,是否遭到破坏 ,该功能一般用于调试, 默认是不开启的 uxNumberOfItems用于记录列表中列表项的个数(不包含 xListEnd)pxIndex用于指向列表中的某个列表项,一般用于遍历列表中的所有列表项 xListEnd一个迷你列表项,排在最末尾 列表结构示意图: 2.2 列表项结构体 struct xLIST_ITEM { listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /* 用于检测列表项的数据完整性 */ configLIST_VOLATILE TickType_t xItemValue /* 列表项的值 */ struct xLIST_ITEM * configLIST_VOLATILE pxNext /* 下一个列表项 */ struct xLIST_ITEM * configLIST_VOLATILE pxPrevious /* 上一个列表项 */ void * pvOwner /* 列表项的拥有者 */ struct xLIST * configLIST_VOLATILE pxContainer; /* 列表项所在列表 */ listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /* 用于检测列表项的数据完整性*/ }; typedef struct xLIST_ITEM ListItem_t; 成员说明:

【深入学习Redis丨第二篇】Redis集群部署详解

文章目录 Redis集群部署Redis4 Cluster部署 Redis集群部署 1 Redis各节点部署 使用源码安装各节点,不过与非cluster方式不同的是,配置文件中需启动cluster相关的配置。 因本次为伪分布式部署,生产环境部署时建议至少3台机器部署(其中每台机器1主1从) ipport192.168.56.1017000192.168.56.1017001192.168.56.1017002192.168.56.1017003192.168.56.1017004192.168.56.1017005 1.1 启动cluster各节点 创建数据目录 mkdir -p /data/redis/cluster/{7000,7001,7002,7003,7004,7005} 配置文件中主要修改如下内容,其他的可按需调整,也可保持默认值,各节点中注意修改对应的端口号 bind 192.168.56.101 port 7000 daemonize yes pidfile /data/redis/cluster/7000/redis_7000.pid logfile "/data/redis/cluster/7000/redis_7000.log" appendonly yes appendfilename "appendonly.aof" appendfsync everysec cluster-enabled yes cluster-config-file nodes-7000.conf #注意此文件自动生成,且初始化时不要有和此重名的文件 cluster-node-timeout 5000 cluster-slave-validity-factor 10 cluster-migration-barrier 1 cluster-require-full-coverage yes cluster-slave-no-failover no 启动各节点,建议用redis用户启动 useradd redis chown -R redis:redis /data/redis/ su - redis cd /data/redis/cluster/7001 cp /data/redis/cluster/7000/redis.conf . sed -i "s#7000#7001#g" redis.conf redis-server redis.conf 其他节点和7001类似启动,启动后进程中会标记redis节点以cluster模式启动

基于MingGW64 GCC编译Windows平台上的 libuvc

安装cmake 打开cmake官网 https://cmake.org/download/,下载安装包: 安装时选择将cmake加到系统环境变量里。安装完成后在新的CMD命令窗口执行cmake --version可看到输出: D:\>cmake --version cmake version 3.29.3 CMake suite maintained and supported by Kitware (kitware.com/cmake). 安装Mingw64 GCC Mingw目标是为支持Windows平台上的GCC编译,它主要提供头文件和支持库,Mingw自身不包括GCC和binutils,所以官网提供了集成这些组件的各种安装包。列表里有Linux平台的安装包,那些是用来在Linux平台生成Widows程序的。 https://www.mingw-w64.org/ 这里我选择了w64devkit,点击后安装链接指向了github:https://github.com/skeeto/w64devkit/releases ,下载w64devkit-1.23.0.zip。 解压后放在C盘,将目录 C:\w64devkit\bin\ 加入系统PATH环境变量。 然后新打开的CMD命令窗口输入gcc –v 可以看到输出: D:\>gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=C:/w64devkit/bin/../libexec/gcc/x86_64-w64-mingw32/14.1.0/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: /gcc-14.1.0/configure --prefix=/w64devkit --with-sysroot=/w64devkit/x86_64-w64-mingw32 --with-native-system-header-dir=/include --target=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-static --disable-shared --with-pic --with-gmp-include=/deps/include --with-gmp-lib=/deps/lib --with-mpc-include=/deps/include --with-mpc-lib=/deps/lib --with-mpfr-include=/deps/include --with-mpfr-lib=/deps/lib --enable-languages=c,c++ --enable-libgomp --enable-threads=posix --enable-version-specific-runtime-libs --disable-dependency-tracking --disable-lto --disable-multilib --disable-nls --disable-win32-registry --enable-mingw-wildcard CFLAGS_FOR_TARGET=-Os CXXFLAGS_FOR_TARGET=-Os LDFLAGS_FOR_TARGET=-s CFLAGS=-Os CXXFLAGS=-Os LDFLAGS=-s Thread model: posix Supported LTO compression algorithms: zlib gcc version 14.

全文检索-ElasticSearch

1.基本概念 1.Index索引 动词:相当于MySQL中的insert; 名词:相当于MySQL中的DataBase; 2.Type(类型) 在Index(索引)中,可以定义一个或多个类型 类似于MySQL中的Table;每一种类型的数据放在一起 3.Document(文档) 保存在某个索引(index)下,某种类型(Type) 的一个数据(Document),文档是JSON格式的,Document就像是MySQL 中的某个Table里面的内容 类似一行数据 4.倒排索引 2.Docker 安装ElasticSearch 2.1 拉取镜像 docker pull elasticsearch:7.4.2 docker pull kibana:7.4.2 2.2 创建实例 2.2.1 创建挂载目录 mkdir ./config mkdir ./data 记得授予权限 chmod -R 777 ./elasticsearch 2.2.2 使容器外任何地址都能够访问 elasticsearch echo "http.host: 0.0.0.0">>./config/elasticsearch.yml elasticsearch.yml http.host: 0.0.0.0 2.2.3 docker 启动 docker run --name elasticsearch -p 9200:9200 -p9300:9300 \ -e "discovery.type=single-node" \ -e ES_JAVA_OPTS="-Xms512m -Xmx1024m" \ -v ./config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \ -v ./data:/usr/share/elasticsearch/data \ -v .

【C++】:vector容器的底层模拟实现&&迭代器失效&&隐藏的浅拷贝

目录 💡前言一,构造函数1 . 强制编译器生成默认构造2 . 拷贝构造3. 用迭代器区间初始化4. 用n个val值构造5. initializer_list 的构造 二,析构函数三,关于迭代器四,有关数据个数与容量五,交换函数swap六,赋值拷贝七,[ ]运算符八,预留空间(扩容)8.1 使用memcpy拷贝问题(重点) 九,尾插和尾删数据十,插入数据 insert十一,删除数据 erase十二,insert和erase的迭代器失效问题(重点)1. 什么是迭代器失效?2. insert 的迭代器失效2.1 insert 内部pos位置的失效2.2 insert 以后外部的实参失效 3. erase 以后的迭代器失效 💡前言 点击跳转到文章:vector容器的基本使用 上篇文章已经介绍了vector容器的基本使用,这篇文章主要选择vector中一些核心的,基本的接口进行模拟实现。 注意:由于我们模拟实现时使用了类模板,所以不建议进行文件分离,不然会产生链接错误。所以我们把函数都写在.h文件中,在Test.cpp文件中进行测试。 首先我们先给出vector类: #include <assert.h> #include <vector> #include <iostream> using namespace std; template<class T> class vector { public: // Vector的迭代器是一个原生指针 typedef T* iterator; typedef T* const_iterator; //...... private: iterator _start = nullptr;//指向开始位置的指针 iterator _finish = nullptr;//指向最后一个位置的下一个位置的指针 iterator _end_of_storage = nullptr;//指向存储容量的尾 }; 一,构造函数 在vector文档中,构造函数分为好几个类型,下面分别进行介绍:

SSM牙科诊所管理系统-计算机毕业设计源码98077

目 录 摘要 1 绪论 1.1研究目的与意义 1.2国内外研究现状 1.3ssm框架介绍 1.4论文结构与章节安排 2 牙科诊所管理系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用例分析 2.4 系统流程分析 2.4.1 数据流程 2.4.2 业务流程 2.5本章小结 3 牙科诊所管理系统总体设计 3.1 系统功能模块设计 3.1.1整体功能模块设计 3.1.2用户模块设计 3.1.3 评论管理模块设计 3.1.4商城管理模块设计 3.1.5订单管理模块设计 3.2 数据库设计 3.2.1 数据库概念结构设计 3.3.2 数据库逻辑结构设计 3.4本章小结 4 牙科诊所管理系统详细设计与实现 4.1用户功能模块 4.1.1 前台首页界面 4.1.2 用户注册界面 4.1.3 用户登录界面 4.1.4药品详情界面 4.1.5收货地址界面 4.1.6我的订单界面 4.1.7牙科诊所界面 4.1.8挂号预约界面 4.1.9住院预约界面 4.2管理人员功能模块 4.2.1系统公告管理界面 4.2.2 系统用户管理界面 4.

【C++】:string类底层的模拟实现

目录 引言1,构造函数2,析构函数3,取出字符串的地址4,计算有效数据个数5,[ ]运算符重载6,简单迭代器7,预开空间(扩容)8,尾插一个字符9,尾插一个字符串10,+=运算符重载11,在pos位置插入字符/字符串11.1 在pos位置插入字符11.2 尾插一个字符串 12,从pos位置开始删除长度为len的字符串13,从pos位置开始查找字符/字符串13.1 查找字符13.2 查找字符串 14,拷贝构造(传统)15,=赋值拷贝(传统)16,交换函数swap17,从pos位置开始取len个字符的串18. 字符串的比较19,清除函数clear20,流插入,流提取20.1 流插入20.2 流提取 21,拷贝构造和赋值拷贝的现代写法(重点)21.1 拷贝构造21.2 赋值拷贝 引言 点击跳转到文章:【string类的基本使用】 上一篇文章已经对string类进行了简单的介绍,大家只要能够正常使用即可。 这篇文章主要是对string类的一些重点接口函数进行模拟实现。本文依然采用多文件的方式,string.h放类的声明,string.cpp放成员函数的定义。 string.h #pragma once #include <iostream> #include <assert.h> #include <stdbool.h> using namespace std; //定义一个叫做bit的命名空间,隔离C++库里的string类 namespace bit { class string { public: //typedef实现二次封装 //由于string类是连续的空间,所以可以定义为原生指针 typedef char* iterator; //const迭代器,指针指向的内容不能修改 typedef const char* const_iterator; //实现迭代器,一定要实现为begin 和end //迭代器屏蔽了底层细节,提供了一种简单通用的访问容器的方式 iterator begin(); iterator end(); const_iterator begin()const; const_iterator end()const; // string();//无参构造 //有参与无参构造用全缺省进行合并,在声明处给缺省值 string(const char* str = "");//传参构造 //析构函数 ~string(); //拷贝构造 string(const string& s); //赋值运算重载(传统) //string& operator=(const string& s); //赋值运算重载(现代) string& operator=(string tmp); const char* c_str() const; //用下标的方式遍历字符串 size_t size()const; char& operator[](size_t pos); const char& operator[](size_t pos)const; //用于扩容,一般不缩容 void reserve(size_t n); void push_back(char ch);//尾插一个字符 void append(const char* str);//尾插字符串 //用运算符重载实现尾插 string& operator+=(char ch); string& operator+=(const char* str); //在指定位置插入 字符或是字符串 void insert(size_t pos, char ch); void insert(size_t pos, const char* str); //在指定位置删除长度为len void erase(size_t pos = 0, size_t len = npos); //从pos位置开始找字符或是字符串 size_t find(char ch, size_t pos =0); size_t find(const char* str, size_t pos = 0); //交换函数 void swap(string& s); //从pos位置找一个子串 string substr(size_t pos = 0, size_t len = npos); //字符串的比较 bool operator<(const string& s)const; bool operator>(const string& s)const; bool operator<=(const string& s)const; bool operator>=(const string& s)const; bool operator==(const string& s)const; bool operator!

C++的MQTT开发:使用Paho的C++接口实现消息发布、订阅、连接RabbitMQ

C++ Paho实现MQTT消息发布功能 要使用paho的cpp接口实现发布MQTT消息的功能,需要进行以下步骤: 安装paho库:首先从paho官方网站下载并安装paho的C++库。可以从https://www.eclipse.org/paho/clients/cpp/ 下载适合操作系统的版本。 创建MQTT客户端:可以使用mqtt::client类来创建一个客户端,如下所示: mqtt::client client("tcp://broker.example.com:1883", "clientId"); 在上面的代码中,broker.example.com是您的MQTT代理服务器的地址,1883是MQTT代理服务器的默认端口。clientId是客户端的唯一标识符,可以自己选择一个适合的名字。 设置连接选项:创建客户端后可以设置一些连接选项,例如设置用户名和密码,设置遗嘱消息等。以下是示例代码: mqtt::connect_options connOpts; connOpts.set_user_name("username"); connOpts.set_password("password"); connOpts.set_will(mqtt::message("topic", "offline", 1, true)); 在上面的代码中,username和password是您的MQTT代理服务器的登录凭据。topic是遗嘱消息的主题,offline是遗嘱消息的内容,1是遗嘱消息的QoS级别(Quality of Service),true表示遗嘱消息是保留的。 连接到MQTT代理服务器:使用mqtt::client对象的connect方法连接到MQTT代理服务器,如下所示: client.connect(connOpts); 发布消息:使用mqtt::client对象的publish方法发布消息。以下是一个示例代码: std::string payload = "Hello, MQTT!"; client.publish("topic", payload.c_str(), payload.length()); 在上面的代码中,topic是消息的主题,payload是消息的内容。您可以根据需要修改这些值。 断开连接:在完成消息发布后,您可以使用mqtt::client对象的disconnect方法断开与MQTT代理服务器的连接,如下所示: client.disconnect(); 这是使用paho的cpp接口发布MQTT消息的基本步骤,实际应用中可能需要处理更多的错误和异常情况。参考paho的官方文档和示例代码来进一步了解和掌握paho的cpp接口的使用。 完整的C++ Paho消息发布的代码演示 #include <iostream> #include <cstring> #include "mqtt/async_client.h" const std::string SERVER_ADDRESS("tcp://broker.example.com:1883"); const std::string CLIENT_ID("clientId"); const std::string TOPIC("topic"); class mqtt_callback : public virtual mqtt::callback { void connection_lost(const std::string& cause) override { std::cout << "

MySQL学习——从命令行调用MySQL 程序

从命令行(即你的 shell 或命令提示符)调用 MySQL 程序时,你需要输入程序名,后跟任何选项或其他参数,以指示程序你想要它执行什么操作。以下是一些示例程序调用的命令。 在这些示例中,$> 表示你的命令解释器的提示符;它并不是你需要输入的内容。你实际看到的提示符取决于你的命令解释器。典型的提示符包括 $ 用于 sh、ksh 或 bash,% 用于 csh 或 tcsh,以及 C:\> 用于 Windows 的 command.com 或 cmd.exe 命令解释器。 $> mysql --user=root test $> mysqladmin extended-status variables $> mysqlshow --help $> mysqldump -u root personnel 在命令行上使用选项时,需要遵循以下规则: 选项是在命令名之后给出的。选项参数以一个短划线(-)或两个短划线(--)开头,取决于它是选项名称的短形式还是长形式。许多选项都有短形式和长形式。例如,-? 和 --help 是指示 MySQL 程序显示其帮助消息的选项的短形式和长形式。选项名称是区分大小写的。-v 和 -V 都是合法的,但具有不同的含义。(它们分别是 --verbose 和 --version 选项的短形式。)一些选项在选项名称之后需要一个值。例如,-h localhost 或 --host=localhost 指示客户端程序 MySQL 服务器主机。选项值告诉程序 MySQL 服务器运行的主机名。对于一个需要值的长选项,使用等号(=)将选项名称和值分开。对于需要值的短选项,选项值可以紧跟在选项字母后面,或者它们之间可以有一个空格:-hlocalhost 和 -h localhost 是等效的。但有一个例外是指定 MySQL 密码的选项。这个选项可以以长形式给出为 --password=pass_val 或 --password。在后一种情况下(没有给出密码值),程序会交互式地提示你输入密码。密码选项也可以以短形式给出为 -ppass_val 或 -p。但是,对于短形式,如果给出了密码值,它必须紧跟在选项字母后面,中间没有空格:如果在选项字母后面有一个空格,程序无法判断后面的参数是否是密码值还是其他类型的参数。因此,以下两个命令具有完全不同的含义: mysql -ptest mysql -p test 第一个命令 mysql -u user -ptest database 指示 mysql 客户端使用用户名 user 和密码 test 连接到数据库,但并未指定默认的数据库。因为密码值 test 紧跟在 -p 后面,没有空格,所以 mysql 客户端会直接使用这个密码值进行连接。

Vue3-watch监听ref和reactive数据的五种情况及watchEffect

何为watch: 文档定义: 用于声明在数据更改时调用的侦听回调。 watch 选项期望接受一个对象,其中键是需要侦听的响应式组件实例属性 (例如,通过 data 或 computed 声明的属性)——值是相应的回调函数。该回调函数接受被侦听源的新值和旧值。 除了一个根级属性,键名也可以是一个简单的由点分隔的路径,例如 a.b.c。注意,这种用法不支持复杂表达式——仅支持由点分隔的路径。如果你需要侦听复杂的数据源,可以使用命令式的 $watch() API。 值也可以是一个方法名称的字符串 (通过 methods 声明),或包含额外选项的对象。当使用对象语法时,回调函数应被声明在 handler 中。额外的选项包含: immediate:在侦听器创建时立即触发回调。第一次调用时,旧值将为 undefined。deep:如果源是对象或数组,则强制深度遍历源,以便在深度变更时触发回调。详见深层侦听器。flush:调整回调的刷新时机。详见回调的触发时机及 watchEffect()。onTrack / onTrigger:调试侦听器的依赖关系。详见侦听器调试。 声明侦听器回调时避免使用箭头函数,因为它们将无法通过 this 访问组件实例。 概述: 作用:监视数据的变化(和Vue2中的watch作用一致) 特点:Vue3中的watch只能监视以下四种数据: ref定义的数据。 reactive定义的数据。 函数返回一个值(getter函数)。 一个包含上述内容的数组。 情况1: 监视ref定义的【基本类型】数据:直接写数据名即可,监视的是其value值的改变。 <template> <div class="person"> <h1>情况一:监视【ref】定义的【基本类型】数据</h1> <h2>当前求和为:{{sum}}</h2> <button @click="changeSum">点我sum+1</button> </div> </template> <script lang="ts" setup name="Person"> import {ref,watch} from 'vue' // 数据 let sum = ref(0) // 方法 function changeSum(){ sum.value += 1 } // 监视,情况一:监视【ref】定义的【基本类型】数据 const stopWatch = watch(sum,(newValue,oldValue)=>{ console.