Elasticsearch向量检索的演进与变革:从基础到应用

上海-拼多多-基础平台招聘 我们是 PDD 基础平台团队,我们有优秀的技术和行业 top 的薪资待遇,hc 多多欢迎有志之士加入我们。岗位要求:熟练掌握Java/C/C++/go等任意一门 JAVA开发工具之Eclipse和MyEcli Eclipse 和 MyEclipse 都是广泛使用的集成开发环境(IDE),主要用于Java语言的开发,但也有其他插件支持如C++和Python等其他计算机语 题解 | #某店铺的各商品毛利率及店铺整体毛利率# # 店铺901在2021年10月以来的所有明细with temp as ( select t.order_id, product_id, price, c 恒生电子一面凉经 已挂我只能说,面试官很精确的每个靶子都没有命中到我[掉小珍珠了][掉小珍珠了][掉小珍珠了]自我介绍锁了解吗?怎么分的?Spring的AOP说一下吧,(又问了代 Elasticsearch向量检索的演进与变革:从基础到应用 Elasticsearch向量检索的演进与变革:从基础到应用1.引言向量检索已经成为现代搜索和推荐系统的核心组件。通过将复杂的对象(例如文本、图像或声音)转换为 题解 | #表达式求值# class Solution {public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 吉利面试2023(给春招或者明年的兄弟们介绍下) 分享下面试吉利的吧 我的总结就是 流程极长 想去的人一定要提早报名! 我很多朋友比我优秀的多但是报名完了没给面试1.简历关 这个我感觉会一定程度看本科学历和你投 理想汽车秋招补录开了! 校招内推码 NTAKyVV校招内推链接https://li.jobs.feishu.cn/s/idjqRBJp从链接进入选择投递城市和职位即可理想汽车社招内推码 求改简历 普通双非本科,大数据专业,想找大数据开发方向的,各位大佬们,简历怎么改啊。#简历被挂麻了,求建议##写简历别走弯路# 鹏新旭第二批应该是等不到了 在牛客上看到的大部分offer选择,基本有旭选旭了,上至top3爷下至本科哥,基本没多少人放弃旭子的oc,感觉第二批没名额了。因为笔试题没做完和一家公司失之交臂 金山笔试全a,然后9.27中午约我下午5 金山笔试全a,然后9.27中午约我下午5.30面试,然后到了5.10分,通知我取消,然后过节,一直到今天又打电话给我约面,中间二十多天,这么不重视?是给你脸了嘛 天翼云北京 有17号二面的uu收到测评的吗,我是不是寄了 2.4 CPP复习 2.4 CPP复习 TCL 今天hr给我打电话,说上次offer发错了,九月份开始基本工资降了500😫😫😫 #TCL求职进展汇总# TCL 今天hr给我打电话,说上次offer发错了,九月份开始基本工资降了500😫😫😫 #TCL求职进展汇总# 说个乐子事 #吉利求职进展汇总(4067

【Docker】004.1-Docker部署Nginx、MySQL、Redis

目录 Docker部署Nginx: 浏览器访问: Docker部署Nginx含挂载 一键启动并挂载MySQL 部署redis 第一步:拉取镜像 第二步:直接启动 第三步:本地连接redis 为了更好找,这里将一个常用的主题独立放在一篇文章 Docker部署Nginx: # 第一步:搜索镜像,建议去网站搜索https://hub.docker.com/ docker search nginx # 控制台 [root@zibo /]# docker search nginx NAME DESCRIPTION STARS OFFICIAL AUTOMATED nginx Official build of Nginx. 14630 [OK] jwilder/nginx-proxy Automated Nginx reverse proxy for docker con… 1995 [OK] richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable of… 811 [OK] jc21/nginx-proxy-manager Docker container for managing Nginx proxy ho… 164 linuxserver/nginx An Nginx container, brought to you by LinuxS… 142 tiangolo/nginx-rtmp Docker image with Nginx using the nginx-rtmp… 119 [OK] # 第二步:下载镜像 docker pull nginx # 控制台 [root@zibo /]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx a076a628af6f: Pull complete 0732ab25fa22: Pull complete d7f36f6fe38f: Pull complete f72584a26f32: Pull complete 7125e4df9063: Pull complete Digest: sha256:10b8cc432d56da8b61b070f4c7d2543a9ed17c2b23010b43af434fd40e2ca4aa Status: Downloaded newer image for nginx:latest docker.

nuxt使用i18n进行中英文切换

中文效果图: 英文效果图: 版本: 安装: npm install --save @nuxtjs/i18n 新建en.js与zh.js两个文件进行切换显示 en.js内容 import globals from './../js/global_val' export default { /****** * 公共内容开始 * *****/ seeMore: "More Information", //查看更多 seeAgenda: "View the conference schedule", //查看议程 jtlRegister: 'Register for the Golden Gyro Award', //金陀螺奖报名参评/投票 registrationChannel: 'FBEC Registration channel', //大会参会报名通道 fbecland: 'FBEC LAND', //大会官方微站 application: 'Click to register for the selection', //点击报名参评-pc applicationOver: 'The entry channel is closed', //参评已结束-pc mApplication: 'Click Register to vote', //点击报名参评/投票-手机端 mAplicationOver: 'Registration is closed', //点击报名参评/投票-手机端 headerData: [{ name: "

【调度算法】DTLZ问题家族

DTLZ问题家族 DTLZ(Deb-Thiele-Laumanns-Zitzler)问题家族是多目标优化中的一类标准测试问题集合。这个家族的问题由Kalyanmoy Deb、Lothar Thiele、Marco Laumanns和Eckart Zitzler于2002年提出,它旨在用于评估和比较不同多目标优化算法的性能。DTLZ问题家族包括一系列多目标优化问题,每个问题都有多个目标函数和一组决策变量。 DTLZ问题家族的主要特点如下: 多目标函数:每个DTLZ问题包括多个目标函数,通常大于等于2个。这些目标函数旨在模拟真实世界的多目标优化问题中的多个冲突目标。 决策变量:DTLZ问题家族包括一组决策变量,它们是优化问题的解空间。这些变量通常是实数值,而不是离散值。 Pareto前沿:每个DTLZ问题都有一个已知的Pareto前沿,即所有非支配解决方案的集合。这使得可以精确地评估多目标优化算法的性能。 可扩展性:DTLZ问题家族通常是可扩展的,即可以根据所需的目标函数数量和决策变量数量生成不同版本的问题。 冲突性:DTLZ问题家族中的目标函数通常是相互冲突的,即在优化一个目标时,可能会损害其他目标。这增加了优化的挑战。 DTLZ问题家族的主要目的是为多目标优化算法提供标准测试问题,以帮助研究人员和开发者评估算法的性能、比较不同算法之间的差异,并推动多目标优化领域的研究进展。通过在不同版本的DTLZ问题上进行测试,可以了解算法在处理多目标问题时的强度和弱点。 常用的DTLZ问题 参考链接:https://blog.csdn.net/a1920993165/article/details/114698765 大佬文章里的公式都没细看,因为看不太懂。按照目前理解,DTLZ问题指一系列有明确Pareto前沿(已知最优解)的多目标问题,用于测试多目标优化算法效果。 DTLZ1问题 DTLZ1(Deb-Thiele-Laumanns-Zitzler 1)是多目标优化问题中的一个经典问题之一。它是多目标优化问题的基准测试问题之一,用于评估和比较多目标优化算法的性能。DTLZ问题系列旨在研究多目标问题,其中目标函数的数量和复杂性较高。 DTLZ1 问题的定义通常如下: 问题描述: 在一个 D-维决策空间内,有 D+m 个变量,其中 D 代表决策变量的数量,m 代表目标函数的数量。目标函数是非线性函数,通常包括了三个部分:一个线性组合、一个多项式项和一个三角函数项。目标函数中的非线性部分涉及到决策变量之间的复杂交互。问题的目标是最小化目标函数,同时满足一些约束条件。 DTLZ1 问题通常被用来测试多目标优化算法的能力,特别是在高维度决策空间中。由于其复杂性和非线性特性,解决 DTLZ1 问题需要使用高级的多目标优化算法,如多目标遗传算法、多目标粒子群优化等。 解决 DTLZ1 问题的挑战在于找到一组 Pareto 最优解,这些解之间不存在单一目标的改进关系,因此需要一种算法来探索和维护 Pareto 前沿,这是一个包含最优解的集合,其中每个解都是在所有目标中都是最佳的,而没有其他解可以在所有目标上优于它们。

CentOS 7 中安装Kafka

文章目录 安装JDK解压环境变量验证 安装ZooKeeper下载解压环境变量配置启动开放端口 安装Kafka下载解压配置启动 CentOS 7.6 JDK 1.8 ZooKeeper 3.5.7 Kafka 2.11-2.4.0 安装JDK 解压 # 解压 tar -xzvf jdk-8u181-linux-x64.tar.gz mv jdk1.8.0_181 /usr/local/jdk1.8 环境变量 # 打开.bashrc文件 vi ~/.bashrc # 文件末尾添加如下内容 export JAVA_HOME=/usr/local/jdk1.8 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:$PATH # 输入下面的命令使之生效 source ~/.bashrc 验证 打开命令行终端,输入如下命令: java -version 显示版本信息,说明安装成功 安装ZooKeeper 下载 点击官网下载 解压 # 解压 tar -xzvf apache-zookeeper-3.5.7-bin.tar.gz sudo mv apache-zookeeper-3.5.7-bin /usr/local/zookeeper-3.5.7 环境变量 # 打开/etc/profile vi /etc/profile # 添加如下内容,然后保存 export ZOOKEEPER_HOME=/usr/local/zookeeper-3.5.7 export PATH=.

CentOS 7中安装ZooKeeper

文章目录 下载解压安装环境变量配置文件启动设置开机自启动开放端口 CentOS 7.6 ZooKeeper 3.5.7 本文介绍了如何在CentOS 7系统中安装单机版的ZooKeeper。 下载 点击官网下载 解压安装 # 解压 tar -xzvf apache-zookeeper-3.5.7-bin.tar.gz sudo mv apache-zookeeper-3.5.7-bin /usr/local/zookeeper-3.5.7 环境变量 # 打开/etc/profile vi /etc/profile # 添加如下内容,然后保存 export ZOOKEEPER_HOME=/usr/local/zookeeper-3.5.7 export PATH=.:$ZOOKEEPER_HOME/bin:$JAVA_HOME/bin:$PATH # 重新编译使环境变量生效 source /etc/profile 配置文件 # 切换到conf目录下 cd /usr/local/zookeeper-3.5.7/conf # 复制zoo_sample.cfg到zoo.cfg cp zoo_sample.cfg zoo.cfg # 打开zoo.cfg vi zoo.cfg # 修改配置如下,然后保存 # 存放数据 dataDir=/usr/local/zookeeper-3.5.7/dataDir # 存放日志文件 dataLogDir=/usr/local/zookeeper-3.5.7/dataLogDir # 端口默认为2181,单机版不需要配置 #clientPort=2181 # 创建文件夹 mkdir /usr/local/zookeeper-3.5.7/dataDir mkdir /usr/local/zookeeper-3.5.7/dataLogDir 启动 cd /usr/local/zookeeper-3.5.7/bin # 启动命令 .

4DRadarSLAM: 基于位姿图优化的大规模环境下的4D成像雷达SLAM系统

文章:4DRadarSLAM: A 4D Imaging Radar SLAM System for Large-scale Environments based on Pose Graph Optimization 作者:Jun Zhang, Huayang Zhuge , Zhenyu Wu, Guohao Peng, Mingxing Wen, Yiyao Liu and Danwei Wang 编辑:点云PCL 代码:https://github.com/zhuge2333/4DRadarSLAM 欢迎各位加入知识星球,获取PDF论文,欢迎转发朋友圈。文章仅做学术分享,如有侵权联系删文。 公众号致力于点云处理,SLAM,三维视觉,高精地图等领域相关内容的干货分享,欢迎各位加入,有兴趣的可联系dianyunpcl@163.com。侵权或转载联系微信cloudpoint9527。 摘要 基于激光雷达的SLAM在恶劣天气条件下(如雨、雪、烟、雾)容易出现故障,而毫米波雷达则不受影响。然而,目前的研究主要集中在2D(x,y)或3D(x,y, doppler )雷达和3D激光雷达上,很少有关于4D雷达(x,y,z, doppler )的研究。作为市场上的新产品,4D雷达输出带有高程信息的3D点云,而不是2D点云;与3D激光雷达相比,4D雷达的点云噪声大且稀疏,使其更具挑战性,难以提取几何特征(边缘和平面)。在本文中,我们提出了一个完整的4D雷达SLAM系统,包括三个模块: 前端模块执行扫描帧到扫描帧的匹配,基于GICP计算基于每个点的概率分布的里程计; 回环检测利用多个基于规则的回环预过滤步骤,然后是一个强度扫描上下文步骤来识别回环候选项,再通过里程计检查来拒绝假回环; 后端使用前端里程计、回环检测和可选GPS数据构建位姿图。通过g2o实现最佳位姿。 图1:提出了4DRadarSLAM,旨在利用4D成像雷达实现大规模SLAM。(a)测试了两种平台上的提出系统:手推车(低速:约1m/s),汽车(中速:25-30km/h)。展示了两个选定数据集的制图结果:(b)在一个花园中。(c)沿着校园主要道路。 主要贡献 这篇论文提出了4DRadarSLAM是一个包括三个部分的完整系统:前端、回环检测和后端。在前端执行扫描帧到扫描帧的匹配来计算里程计。由于从4D雷达点云中提取边缘和平面很困难,直接在原始点云上使用广义ICP(GICP)。通过考虑每个点的概率分布,我们提出的APDGICP(自适应概率分布-GICP)提高了性能。在回环检测中执行回环预处理过滤,以识别可能的回环候选项,然后利用强度扫描上下文来找到回环闭合。我们还进行里程计检查,以确保几何一致性。在后端,我们使用g2o构建并解决了一个位姿图,并输出了优化后的位姿。在图1和图7中,展示了测试平台和制图结果。主要贡献包括: 为4D成像雷达提出了一个完整的SLAM系统。我们开源了代码,以促进相关研究。 在前端(APDGICP)中,我们考虑了点测量的概率分布。 在回环检测中,我们引入了强度扫描上下文来查找回环候选项,结合回环预过滤和里程计检查,我们可以获得良好的回环闭合。 在后端位姿图中考虑了里程计、回环闭合和GPS。 我们进行了广泛的实验,使用了两种类型的平台和五个数据集,展示了其准确性、稳健性和实时性能。 内容概述 系统概述 4DRadarSLAM系统的概述如图2所示,由三个模块组成:前端、环路检测和后端。在前端,4D雷达点云用作输入,用于估算里程计和生成关键帧。环路检测模块评估每个新的关键帧,以确定它是否可以形成回环闭合。在后端使用g2o构建并优化位姿图,生成优化的姿势作为输出。 图2:提出的4DRadarSLAM系统概述。它由三个模块组成:(a) 前端:用于计算里程计。(b) 回环检测:用于检测回环闭合。(c) 后端:姿势图构建和优化。 前端 预处理:为了确保SLAM系统的鲁棒性,首先应该过滤掉动态物体。雷达的多普勒速度信息可用于识别这些物体。在本研究使用[33]中提出的线性最小二乘方法来估计毫米波雷达的自身速度。利用估计的多普勒速度和自身速度,我们能够确定物体的真实速度。 扫描匹配:在这一步中输入是上一个关键帧和一个新帧,目标是找到变换矩阵,由于4D雷达的点云含有噪声,不容易提取几何特征(如边和平面),GICP相对于ICP和NDT来说能够输出可接受的结果。因此提出了一种名为自适应概率分布-GICP(APDGICP)的新算法,它考虑了GICP中每个点的空间概率分布。根据毫米波雷达的手册,点的测距不确定性由σr = 0.00215r给出,其中r和σr分别是测得的距离和其不确定性。方位和俯仰角的精度分别为0.5°和1.0°,这导致了球坐标中方位和俯仰方向的不确定性,近似为σa ≈ sin(0.5°)r和σe ≈ sin(1.0°)r。所得的概率分布如图3所示,类似一个椭球(橙色),其中一个轴指向原点,三个半轴的长度分别为σr(距离)、σa(方位)和σe(俯仰)。 图3:一个点的概率分布。

Dreambooth工作原理

什么是Dreambooth 中文名:梦想亭。 Dreambooth 由 Google 研究团队于 2022 年发布,是一种通过向模型注入自定义主题来微调扩散模型(如稳定扩散)的技术。 所谓自定义主体,就是一张照片,但是照片主体要鲜明。比如一张小狗狗照片,那么狗和背景要有很高的区分度。 官方给出的一个例子:左边是三张小狗照片,通过dreamboothed 模型后,就能生成右边不同的照片。 小节下:就是使用少量的照片,给到dreamboothed 模型,dreamboothed 模型就能生成出风格不同的照片来。 为什么不直接训练照片呢? 为什么不直接使用这些照片来训练模型呢?因为少量的照片去训练,会造成过拟合和语言漂移的问题。 语言漂移 (Language drift) 用一个成语来形容它:流变不居。 “Language drift”(语言漂移)是指在机器学习中,训练模型的语言或数据分布与实际应用环境中的语言或数据分布之间的差异或变化。这种差异可能会导致模型在实际应用中表现不佳。 具体来说,语言漂移可能出现在以下情况: 时间漂移(Temporal Drift):语言随着时间的推移而变化。例如,社交媒体上的流行词汇、俚语或新兴语言可能会不断变化,而训练模型的数据可能是以前的数据,无法跟上最新的语言趋势。 领域漂移(Domain Drift):语言在不同领域之间可能有差异。模型在一个领域中训练,但在另一个领域中使用时,语言和术语可能不同,导致性能下降。 地理漂移(Geographical Drift):不同地理位置的语言和方言差异也可能导致漂移。一个地区的特定用语可能在另一个地区无法理解。 为了应对语言漂移,我们通常需要不断更新和微调模型,使用最新的数据以及适应特定领域或地理位置的语言变化。这有助于确保模型在实际应用中保持准确性和效用。 过拟合(Overfitting) 或者叫:过度拟合。 我先用一个成语来形容过拟合:墨守成规。 过拟合(Overfitting)是指在机器学习中,模型过度适应训练数据,导致在测试数据上表现不佳的现象。这通常发生在模型变得过于复杂或在训练数据相对较少的情况下。 过拟合的原因: 模型复杂度过高:当模型具有太多参数或太多层,它可以学会在训练数据上几乎完美匹配每个样本,但这不代表它在新数据上泛化良好。 训练数据不足:如果可用于训练的数据量有限,模型可能会记住训练数据中的噪声,而不是学习通用规律。 过拟合的表现: 在训练数据上表现很好,误差很低,但在测试数据上表现糟糕。 模型的预测波动很大,对新数据敏感。 应对过拟合的方法: 数据扩充:增加训练数据的数量和多样性,有助于模型更好地泛化。 减小模型复杂度:减少模型中的参数数量或层级,以降低模型的复杂性。 来限制参数的大小,减少过拟合的风险。 早停:在训练过程中监视模型在验证数据上的性能,一旦性能开始下降,就停止训练,以防止过拟合。 Dreambooth 如何解决这些问题呢? 先给照片的主体取个个性化或者说具有标识性的名字。比如,狗的名字叫:Devora。分类的预先保留:意思就是,Devora是啥呢?它是条狗,所以它的类目,就是Dog。 具体怎么做呢? Dreambooth 的训练 我们需要三样东西: 一些自定义图像:主体鲜明的照片唯一标识符(unique identifier)一个分类名(class name) 在上面的例子中。唯一标识符是 Devora。分类就是狗。 然后你需要构建你的 实例提示: a photo of [unique identifier] [class name] 例如:a photo of Devora dog

Kotlin 协程的挂起和阻塞的区别

一,简介 Kotlin协程引入了非常强大的异步编程模型,通过挂起而不是阻塞来实现并发操作。以下是有关Kotlin协程挂起和阻塞的详细介绍: 挂起(Suspending): 挂起是指一个协程的执行可以在不阻塞线程的情况下暂停和恢复。挂起函数是一种能够让协程挂起并释放线程的特殊函数,允许其他协程在该协程挂起期间运行。协程可以在执行IO操作、等待网络请求、休眠或执行任何可能导致阻塞的操作时挂起。 阻塞: 阻塞是指线程在执行某个操作时被暂停,直到该操作完成,而不能执行其他任务。在传统的多线程编程中,通常会使用阻塞调用(如Thread.sleep()或等待I/O操作完成),这会导致线程被阻塞,浪费了宝贵的资源。 协程的非阻塞特性: Kotlin协程通过将任务挂起到后台线程而不阻塞主线程,使得在同一线程上执行多个任务变得更加高效。由于协程不需要一直占用线程,所以可以运行大量协程而无需创建太多线程。 使用协程挂起函数: 在Kotlin中,使用suspend关键字声明挂起函数,这允许函数在协程中挂起。 例如,suspend fun fetchData(): String是一个可以在协程中挂起的函数,它可以执行异步操作而不阻塞线程。 协程调度器: 协程的执行受调度器的管理,调度器负责决定何时挂起和恢复协程,以及在哪个线程上运行它们。通过使用不同的调度器,可以控制协程的执行方式,例如在主线程、IO线程或自定义线程池中执行。 总之,Kotlin协程的挂起机制允许在不阻塞线程的情况下执行异步任务,这在编写高效且响应式的并发代码方面非常有用。挂起函数使协程可以在等待I/O或执行其他可能导致阻塞的操作时,让出线程,以提高应用程序的性能和响应性。 二,示例 以下是使用Kotlin协程的示例,演示了挂起和阻塞的区别: 首先,确保你的项目中已经引入了Kotlin协程库,以便使用协程。 kotlinCopy codeimport kotlinx.coroutines.* import kotlin.system.measureTimeMillis // 一个挂起函数,模拟网络请求 suspend fun fetchData(): String { delay(1000) // 模拟延迟1秒的网络请求 return "Data from the network" } fun main() = runBlocking { // 创建一个协程作用域 val time = measureTimeMillis { val result = async { fetchData() } // 启动一个协程来执行网络请求 println("Waiting for data...") println("Data received: ${result.await()}") } println("

Redis实现分页+多条件模糊查询组合方案

导言 Redis是一个高效的内存数据库,它支持包括String、List、Set、SortedSet和Hash等数据类型的存储,在Redis中通常根据数据的key查询其value值,Redis没有模糊条件查询,在面对一些需要分页、排序以及条件查询的场景时(如评论,时间线,检索等),只凭借Redis所提供的功能就不太好不处理了。 本文不对Redis的特性做过多赘述。由于之前基于业务问题需要实现基于Redis的条件查询和分页功能,在百度上查询了不少文章,基本不是只有分页功能就是只有条件查询功能的实现,缺少两者组合的解决方案。因此,本文将基于Redis提供条件查询+分页的技术解决方案。 注:本文只提供实现思路,并不提供实现的代码 本文将从四个部分进行说明: 分页实现 模糊条件查询实现 分页和模糊条件查询的组合实现 优化方案 大家可以直接跳到自己需要的部分进行阅读。 Redis的分页实现 我们通常习惯于在Mysql、Oracle这样持久化数据库中实现分页查询,但是基于某些特殊的业务场景下,我们的数据并未持久化到了数据库中或是出于查询速度上的考虑将热点数据加载到了缓存数据库中。因此,我们可能需要基于Redis这样的缓存数据库去进行分页查询。 Redis的分页查询的实现是基于Redis提供的ZSet数据结构实现的,ZSet全称为Sorted Set,该结构主要存储有序集合。下面是它的指令描述以及该指令在分页实现中的作用: ZADD:SortedSet的添加元素指令ZADD key score member [[score,member]…]会给每个添加的元素member绑定一个用于排序的值score,SortedSet就会根据score值的大小对元素进行排序。我们为通常习惯于将数据的时间属性当作score用于排序,当然大家也可以根据具体的业务场景去选择排序的目标。 ZREVRANGE:SortedSet中的指令ZREVRANGE key start stop可以返回指定区间内的成员,可以用来做分页。 ZREM:SortedSet的指令ZREM key member可以根据key移除指定的成员,能满足删评论的要求。 所以SortedSet用来做分页是非常适合的。下面是分页实现的演示图,包含插入新记录后的查询情况。 事实上,Redis中的List结构也是可以实现分页,但List无法实现自动排序,并且Zset还可以根据score进行数据筛选,取出目标score区间内数据。 所以在实现上,ZSet往往更加适合我们。当然如果你需要插入重复数据的情况下,分页就可能就需要借助List来实现了。具体使用那种结构来实现分页还是需要根据实际的业务场景来进行选择的。 Redis的多条件模糊查询实现 Redis是key-value类型的内存数据库,通过key直接取数据虽然很方便,但是并未提供像mysql那样方便的sql条件查询支持。因此我们需要借助Redis提供的结构和功能去自己实现模糊条件查询功能。 事实上,Redis的模糊条件查询是基于Hash实现的,我们可以将数据的某些条件值作为hash的key值,并数据本身作为value进行存储。然后通过Hash提供的HSCAN指令去遍历所有的key进行筛选,得到我们符合条件的所有key值(hscan可以进行模式匹配)。 为了方便,我们通常将符合条件的key全部放入到一个Set或是List中。这样一来,我们就可以根据得到的key值去取出相应的数据了。下面是模糊查询的演示图(其中field中的命名规则为<id>:<姓名>:<性别>,value为用户详情的json串)。 查询所有性别为女的用户 查询所有名字中姓阿的用户 HSCAN虽然为我们提供了模式匹配的功能,但这种匹配是基于遍历实现的,每一次匹配都需要遍历全部的key,效率上并不高。因此在下面一节会这方面进行补充,本节只谈如何实现模糊匹配。 Redis的分页+多条件模糊查询组合实现 前面分别单独叙述了如何实现Redis的分页和多条件某查询。在实际使用中,单独使用ZSet实现分页已经能够展现不错的性能了,但存在一个问题是我们所分页的数据往往是伴随着一些动态的筛选条件的,而ZSet并不提供这样的功能。 面对这种情况,我们通常有两种解决方案: 如果数据已经存储在了持久化数据库中,我们可以每次在数据库中做好条件查询再将数据放入Redis中进行分页。 在Redis中实现多条件模糊查询并分页。 前者方案其实是一个不错的选择,但缺点在于数据有时候并不一定都在持久化数据库中。在有些业务场景下,我们的数据为了展现更好的并发性以及高响应,我们的数据会先放置在缓存数据库中,等到某个时间或者满足某种条件时再持久化到数据库中。 在这种情况下我们第一个方案就不起作用了,需要使用第二个方案。因此,下面将介绍如何实现多条件模糊查询的基础上进行分页。 实现思路 首先我们可以采用多条件模糊查询章节所说的方式,将我们所涉及到的条件字段作为hash的field,而数据的内容则作为对应value进行存储(一般以json格式存储,方便反序列化)。 我们需要实现约定好查询的格式,用前面一节的例子来说,field中的命名规则为<id>:<姓名>:<性别>,我们每次可以通过"*"来实现我们希望的模糊匹配条件,比如“*:*:男”就是匹配所有男性数据,“100*:*:*”就是匹配所有id前缀为100的用户。 当我们拿到了匹配串后我们先去Redis中寻找是否存在以该匹配串为key的ZSet,如果没有则通过Redis提供的HSCAN遍历所有hash的field,得到所有符合条件的field,并将其放入一个ZSet集合,同时将这个集合的key设置为我们的条件匹配串。如果已经存在了,则直接对这个ZSet进行分页查询即可。对ZSet进行分页的方式已经在前面叙述过了。通过这样的方式我们就实现了最简单的分页+多条件模糊查询。 上图中,由于并未在缓存数据库中找到符合的ZSet集合,我们将根据匹配串生成一个新的集合用于分页。 性能优化方案 虽然上文实现了多条件模糊查询+分页的功能,但是在时间开发中,我们不能无限制的生成新的集合,因为匹配串是很多样化的,这会给缓存带来巨大的压力。 因此我们在生成集合时可以赋予这个集合一个过期时间,到期集合会自动销毁。因为根据时间局部性原理,我们在一段时间内不访问的数据大概率在很长一顿时间内也不会再访问。而对于命中的集合,我们将更新其过期时间。 同时,我们数据的实时性也是一个问题,因为我们的集合是在生成集合时的Hash内容决定的,对于新插入到Hash的数据,集合是无法探知的,因此有两种解决方案: 第一种是插入到Hash时同时再插入到其他相应的集合中,保证数据一直是最新的,这种方式需要增加特殊前缀用于识别,否则我们也不清楚到底要插入到哪些集合中。 第二种方式是定时更新,这种方式比较省力,但无法保证分页数据的实时性。因此具体怎么选择还是取决于业务场景。 总结 本文大概地描述了实现分页和多条件模糊查询的方案,希望能够对大家有所帮助。 来源:blog.csdn.net/qq_33905217/article/ details/129211947 又一个 SQL 神器,开源了! 如何优雅记录 HTTP 请求/ 响应数据 要想做好架构可视化,你必须弄懂这十个关系 多账号统一登陆,账号模块的系统设计 回复【干货】获取精选干货视频教程 回复【加群】加入疑难问题攻坚交流群

【CSDN文章代码获取说明】

一、获取代码方式: 本文介绍获取源代码的方式,获取代码者默认认同以下内容: 1.文章标题含“源码分享”的代码“基本免费”,不含“源码分享”的代码需“付费”。 2.关注CSDN后,CSDN私信回复对应文章期数或者标题,以及根据CSDN私信回复内容输入要求的指令,评论区回复无效。看到后会手动发送下载链接,查看权限为7天有效期,链接失效者请重新私信(取关者忽略)。 3.链接打开方式,可通过手机公众号/PC浏览器加载(不推荐使用APP或手机浏览器)。下载代码流程并不繁琐,若无法下载可私信。 二、关于加密 1.会对部分代码中的一个不影响调参的代码加密,含“源码分享”的代码大部分存在加密情况,加密位置为下载链接中标黄的内容。 2.为了降低代码在二手市场的流通性,保证代码的一定创新性,加密是必然的,公开只是时间问题。为了弥补加密造成的不便, 会投入更多精力售后答疑。 3.代码会不定期进行更新和完善,加密部分也会逐渐精简和边缘化。 三、关于售后 1.“源码分享”区用户在csdn私信或者评论区进行交流,抽空进行答疑。 2.非“源码分享”区用户加下载链接内联系方式,提供长期售后答疑。 3.部分代码来源于网络,若触碰版权可私信我。

Filter与Listener(过滤器与监听器)

1.Filter 1.过滤器概述 过滤器——Filter,它是JavaWeb三大组件之一。另外两个是Servlet和Listener 它可以对web应用中的所有资源进行拦截,并且在拦截之后进行一些特殊的操作 在程序中访问服务器资源时,当一个请求到来,服务器首先判断是否有过滤器与请求资源相关联,如果有,过滤器可以将请求拦截下来,完成一些特定的功能,再由过滤器决定是否交给请求资源。如果没有则像之前那样直接请求资源了。响应也是类似的 过滤器一般用于完成通用的操作,例如:登录验证、统一编码处理、敏感字符过滤等 2.Filter概述 Filter 是一个接口,如果想实现过滤器的功能,必须实现该接口 核心方法 返回值方法名作用voidinit(FilterConfig config)初始化方法voiddoFilter(ServletRequest req,ServletResponse resp,FilterChain chain)对请求资源和响应资源过滤voiddestory()销毁方法 配置方式 注解方式 配置文件 3.FilterChain FilterChain 是一个接口,代表过滤器链对象。由 Servlet 容器提供实现类对象,直接使用即可。 过滤器可以定义多个,就会组成过滤 核心方法 返回值方法名作用voiddoFilter(ServletRequest req,ServletResponse resp)放行方法 如果有多个过滤器,在第一个过滤器中调用下个过滤器,依次类推。直到到达最终访问资源 如果只有一个过滤器,放行时,就会直接到达最终访问资源 4.过滤器的使用 需求说明 通过Filter过滤器解决多个资源写出中文乱码的问题 实现步骤 1.创建一个web项目 2.创建两个Servlet功能类,都向客户端写出中文数据 3.创建一个Filter过滤器实现类,重写doFilter核心方法 4.在方法内部解决中文乱码,并放行 5.部署并启动项目 6.通过浏览器测试 package filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; /* 过滤器基本使用 */ @WebFilter("/*") public class FilterDemo01 implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.

vue3生成二维码

1、下载vue-qr npm install vue-qr --save 2\使用时引入 import VueQr from 'vue-qr/src/packages/vue-qr.vue'; 3、模板引用 <!-- vue-qr参数 text 二维码,即扫描二维码后跳转的页面 size 二维码大小 margin 二维码图像的外边距, 默认 20px bgSrc 嵌入的背景图地址 logoSrc 嵌入至二维码中心的 LOGO 地址 logoScale 中间图的尺寸 dotScale 二维码的点的大小 colorDark 实点的颜色(注意:和colorLight一起设置才有效) colorLight 空白的颜色(注意:和colorDark一起设置才有效) autoColor 若为 true, 背景图的主要颜色将作为实点的颜色, 即 colorDark,默认 true color-dark="#ff774b" color-light="#22252d" --> <VueQr :text="data.url" :size="120" :margin="10" logo-src="favicon.ico" />

pybind11:python联合c++编译

很多时候,单纯用python脚本编译出来的代码,运行速度会比较慢,可以将部分功能改用C++实现,然后与python联合编译,速度会比较快。 这里使用pybind11库,将C++代码转换为python可以识别的代码。 pybind11 是一个轻量级的仅标头库,它在 Python 中公开C++类型,反之亦然,主要用于创建现有C++代码的 Python 绑定。它的目标和语法类似于David Abrahams的优秀Boost.Python库:通过使用编译时自省推断类型信息来最小化传统扩展模块中的样板代码。 将此库视为 Boost.Python 的小型自包含版本,剥离了与绑定生成无关的所有内容。没有注释,核心头文件只需要~4K行代码,并且依赖于Python(3.6+或PyPy)和C++标准库。由于一些新的 C++11 语言功能(特别是:元组、lambda 函数和可变参数模板),这种紧凑的实现成为可能。自创建以来,该库在许多方面都超越了Boost.Python,导致在许多常见情况下的绑定代码大大简化。 1. 获取pybind11 pybind11是 header-only的,因此不需要编译动态链接库,直接解压使用即可。 下载地址:pybind/pybind11 :https://github.com/pybind/pybind11官方文档:Intro - pybind11 documentation :https://pybind11.readthedocs.io/en/stable/index.html 下载源码后的文件结构: . ├── CMakeLists.txt ├── docs ├── include ├── LICENSE ├── MANIFEST.in ├── noxfile.py ├── pybind11 ├── pyproject.toml ├── README.rst ├── SECURITY.md ├── setup.cfg ├── setup.py ├── tests └── tools 可以将下载的文件直接放进工程代码子目录,也可以使用 git submodule 的方法添加子模块 git submodule add https://github.com/pybind/pybind11.git third_party/pybind11-2.11.0 cd third_party/pybind11-2.11.0/ git checkout tags/v2.11.0 2.

Java虚线程 简介

虚线程是JDK19中新引入的一个功能,是用户级别的线程。旨在帮助开发者以更简单、清晰的方式开发出高性能,吞吐量更大的应用程序。 背景 以服务端应用为例,我们看一下Java中使用Thread的方式 thread-per-request(同步编程) 在thread-per-request的服务端应用中,一个request从始至终都运行在同一个线程上。这样开发出来的程序有几个特点 方便开发,方便理解上下文保持一致,便于调试同步阻塞,吞吐量不高 由于JDK的线程是在OS的线程上封装了一层,一个JDK线程对应了一个OS线程。如果线程过多会导致CPU频繁切换也会影响到系统的性能,所以我们在实际应用中通常会使用线程池来控制我们的线程数,同时减少创建、销毁线程所带来的开销。 asynchronous style (异步编程) 在同步编程的方式中,同时能够处理的请求数量依赖于线程池的数量。在异步编程中采用了另一种thread-sharing的方式,当一个请求遇到I/O操作时,它会将当前线程返还给线程池,这样该线程就可以为其他请求服务。通过异步编程的方式我们可以在资源有限的方式下开发出高性能的services,但是这也带来了不小的复杂度: 开发复杂,它需要所谓的异步编程风格,采用一组单独的 I/O 方法,这些方法不等待 I/O 操作完成,而是稍后将其完成通知给回调将完整的业务逻辑拆分为多个小阶段,然后使用lambda表达式和流式API组合起来(CompletableFuture, eg)难以调试,线程栈无法提供完整的上下文信息 虚线程 在前面的介绍中我们可以看到应用程序的开发便利性和高性能似乎不可兼得。Vritual Thread的提出就是为了解决这个问题,让开发者能够通过同步的方式进行编程,同时又能够获得异步模式的高吞吐量。 A virtual thread is an instance of java.lang.Thread that is not tied to a particular OS thread. A platform thread, by contrast, is an instance of java.lang.Thread implemented in the traditional way, as a thin wrapper around an OS thread. 虚线程 是java.lang.Thread的子类,但是并不和特定的OS线程绑定。当我们的代码运行在虚线程上时: 如果是在CPU上执行计算,虚线程会消费一个OS thread如果调用了java.*下的阻塞I/O方法,运行时会进行一个非阻塞的OS调用然后自动将当前的虚线程挂起 创建虚线程的开销很低,因此绝对不要池化虚线程,大多数虚线程的生命周期应该伴随着一个后台task或者一个http请求而创建,结束后销毁。 我们可以通过下面的实例看一下如何使用虚线程 try (var executor = Executors.

Python10.19

提取《唐诗.txt》文件中诗人名和诗篇名,统计收录的每位诗人的诗篇数量,保存在另一个文本文档中 # 读取文件——readline() # with open(r'C:\Users\Administrator\Desktop\唐诗.txt', mode='r') as f: # print(f.readline()) # print(f.readline()) # pass # 输出唐诗的编号和作者和诗名 lis = [] with open(r'C:\Users\Administrator\Desktop\唐诗.txt') as x: for li in x.readlines(): if '0' <= li[0] <= '9': lis.append(li) for i in lis: print(i, end="") num = {} for i in lis: i = i[3:6] for x in i: if x == ':': i = i[0:2] if i not in num.keys(): num[i] = 1 else: num[i] += 1 print(num) with open(r'C:\Users\Administrator\Desktop\唐诗1.

MAC 配置 Maven

Maven 是一个流行的 Java 项目管理和构建工具,它可以帮助我们管理项目依赖、构建和发布等过程。本文将指导您在 MAC 上配置 Maven 的详细步骤。 1、下载 Maven 首先,从 Maven 官方网站下载最新版本的 Maven 安装包。下载完成后,将其解压到您的一个目录中。 设置环境变量 打开终端,并编辑 ~/.bash_profile 文件,添加以下内容: export MAVEN_HOME=/path/to/your/maven/directory export PATH=$MAVEN_HOME/bin:$PATH 这里的 /path/to/your/maven/directory 应该替换为您实际的 Maven 安装目录。 然后,保存文件并执行以下命令使更改生效: source &#126;/.bash_profile 2、验证安装 执行以下命令验证 Maven 是否已成功安装: mvn -version 如果一切顺利,您将看到 Maven 的版本信息。 3、配置 Maven 接下来,我们需要配置 Maven。在终端中执行以下命令: cd /path/to/your/maven/conf/ 然后,使用文本编辑器打开 settings.xml 文件: nano settings.xml 在 settings.xml 文件中,您可以配置 Maven 的仓库、代理设置、镜像设置等。您可以根据自己的需要进行配置。这里是一个示例: <settings> <mirrors> <mirror> <id>mirrorId</id> <url>http://mirror.example.com/repo</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors> <profiles> <profile> <id>profileId</id> <repositories> <repository> <id>repoId</id> <url>http://repo.

python数据分析:如何使用机器学习算法进行数据预测?

使用机器学习算法进行数据预测是数据分析中常见的任务之一。 以下是具体的案例: 1. 线性回归:通过线性关系对数据进行预测。 解释:线性回归是一种基本的回归算法,适用于预测连续型变量。 代码示例: from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error # 假设有特征矩阵X和目标变量y X = [[1, 2], [2, 4], [3, 6], [4, 8]] y = [3, 6, 9, 12] # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 创建线性回归模型 model = LinearRegression() # 拟合模型 model.fit(X_train, y_train) # 预测测试集 y_pred = model.predict(X_test) # 计算均方误差 mse = mean_squared_error(y_test, y_pred) print("线性回归模型的均方误差:", mse) 2.

avue出现横线

如图: 解决方法: ::v-deep .el-table__fixed,::v-deep .el-table__fixed-right { height: 100% !important; }

el-select 下拉框全选、多选的几种方式组件

组件一、基础多选 适用性较广的基础多选,用 Tag 展示已选项 <template> <el-select v-model="value1" multiple placeholder="请选择"> <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </template> <script> export default { data() { return { options: [{ value: '选项1', label: '黄金糕' }, { value: '选项2', label: '双皮奶' }, { value: '选项3', label: '蚵仔煎' }, { value: '选项4', label: '龙须面' }, { value: '选项5', label: '北京烤鸭' }], value1: [] } } } </script> 为el-select设置multiple属性即可启用多选,此时v-model的值为当前选中值所组成的数组。默认情况下选中值会以 Tag 的形式展现,你也可以设置collapse-tags属性将它们合并为一段文字。 <template> <el-select v-model="

firewalld常用的基础配置

firewalld防火墙是centos7系统默认的防火墙管理工具,取代了之前的iptables防火墙,也是工作在网络层,属于包过滤防火墙。 支持IPv4、IPv6防火墙设置以及以太网桥支持服务或应用程序直接添加防火墙规则接口拥有两种配置模式:临时模式、永久模式 firewalld和iptables都是用来管理防火墙的工具(属于用户态)来定义防火墙的各种规则功能,内部结构都指向netfilter网络过滤子系统(属于内核态)来实现包过滤防火墙功能。 firewalld提供了支持网络区域所定义的网络连接以及接口安全等级的动态防火墙管理工具。 2 Firewalld和iptables的关系 2.1 Firewalld和iptables的关系 netfilter 位于Linux内核中的包过滤功能体系称为Linux防火墙的“内核态” Firewalld/iptables CentOS7默认的管理防火墙规则的工具(Firewalld)称为Linux防火墙的“用户态” 2.2 Firewalld和iptables的区别 1、对规则的设置不同: ptables主要是基于接口(网卡),来设置规则,从而判断网络的安全性。firewalld是基于区域,根据不同的区域来设置不同的规则,从而保证网络的安全。与硬件防火墙的设置相类似。 2、配置文件不同: iptables在/etc/sysconfig/iptables中储存配置; firewalld 将配置储存在/etc/firewalld/(优先加载)和/usr/lib/firewalld/(默认的配置文件)中的各种XML文件里。 当/etc/firewalld/中没有相关区域的配置文件时,才会加载/usr/lib/firewalld/中的配置文件。 3、对规则的修改: 使用iptables每一个单独更改,意味着清除所有旧的规则和从/etc/sysconfig/iptables里读取所有新的规则。使用firewalld却不会再创建任何新的规则,仅仅运行规则中的不同之处。因此firewalld可以在运行时间内,改变设置而不丢失现行连接。 4、防火墙类型不同: iptables防火墙类型为静态防火墙firewalld防火墙类型为动态防火墙 3 Firewalld区域 3.1 firewalld区域的概念 firewalld防火墙为了简化管理,将所有网络流量分为多个区域(zone)。然后根据数据包的源IP地址或传入的网络接口等条件将流量传入相应区域。每个区域都定义了自己打开或者关闭的端口和服务列表。 这些区域配置文件存在于/usr/lib/firewalld/zones目录中,还有一个目录/etc/firewalld/zones。firewalld使用规则时,会首先到/etc/firewalld/目录中查找,如果可以找到就直接使用,找不到会继续到/usr/lib/firewalld/目录中查找。 3.2 firewalld防火墙定义了9个区域 区域作用trusted(信任区域)允许所有的传入流量。public(公共区域)允许与ssh或dhcpv6-client预定义服务匹配的传入流量,其余均拒绝。是新添加网络接口的默认区域。external(外部区域)允许与ssh预定义服务匹配的传入流量其余均拒绝。home(家庭区域)允许与ssh、mdns、samba-client或dhcpv6-client预定义服务匹配的传入流量,其他均拒绝。internal(内部区域)默认值与home区域相同。work(工作区域)允许与ssh、dhcpv6-client预定义服务匹配的传入流量,其他均拒绝dmz(隔离区域也称非军事区域)允许与ssh预定义服务匹配的传入流量,其他均拒绝。block(限制区域)拒绝所有传入流量。drop(丢弃区域)丢弃所有传入流量,并且不产生包含icmp的错误响应。 3.3 firewalld区域介绍和区域优先级 firewalld区域介绍 最终一个区域的安全程度是取决于管理员在此区域中设置的规则。区域如同进入主机的安全门,每个区域都具有不同限制程度的规则,只会允许符合规则的流量传入。可以根据网络规模,使用一个或多个区域,但是任何一个活跃区域至少需要关联源地址或接口。默认情况下,public区域是默认区域,包含所有接口(网卡)。 firewalld数据处理流程 检查数据来源的源地址: 若源地址关联到特定的区域,则执行该区域所指定的规则若源地址未关联到特定的区域,则使用传入网络接口的区域 并执行该区域所指定的规则若网络接口未关联到特定的区域,则使用默认区域并执行该 区域所指定的规则 区域优先级:源地址绑定的区域 > 网卡绑定的区域 > 默认区域(只要没有绑定过指定区域的网卡,都适用于于默认区域的规则。默认区域可自定义,不修改则为public) 4 Firewalld防火墙的配置方法 1、firewall-config 图形化工具(生产环境一般只有字符界面,不使用这种方法) 2、firewall-cmd 命令行工具(生产环境中没有图形化界面,所以只能在命令行进行配置) 3、编写 /etc/firewalld 中的配置文件。 Firewalld 会优先使用/etc/firewalld/中的配置,如果不存在配置文件,则使用/usr/lib/firewalld/中的配置。 /etc/firewalld/:用户自定义配置文件,需要时可通过从/usr/lib/firewalld/ 中拷贝/usr/lib/firewalld/ :默认配置文件,不建议修改,若恢复至默认配置,可直接删除/etc/firewalld/ 中的配置 4.1 firewall-config 图形化工具 在命令行输入”firewall-config“,回车后会弹出图形化管理工具。生产环境一般只有字符界面,不使用这种方法。 4.2 firewall-cmd 命令行工具 常用的 firewall-cmd 命令选项:

微调Whisper语音识别模型和加速推理

前言 OpenAI在开源了号称其英文语音辨识能力已达到人类水准的Whisper项目,且它亦支持其它98种语言的自动语音辨识。Whisper所提供的自动语音识与翻译任务,它们能将各种语言的语音变成文本,也能将这些文本翻译成英文。本项目主要的目的是为了对Whisper模型使用Lora进行微调,目前开源了好几个模型,具体可以在openai查看,下面列出了常用的几个模型。另外项目最后还对语音识别加速推理,使用了CTranslate2加速推理,提示一下,加速推理支持直接使用Whisper原模型转换,并不一定需要微调。 openai/whisper-tinyopenai/whisper-baseopenai/whisper-smallopenai/whisper-mediumopenai/whisper-largeopenai/whisper-large-v2 源码地址:Whisper-Finetune 使用环境: Anaconda 3Python 3.8Pytorch 1.13.1Ubuntu 18.04GPU A100-PCIE-40GB*1 项目主要程序介绍 aishell.py:制作AIShell训练数据。finetune.py:微调模型。merge_lora.py:合并Whisper和Lora的模型。evaluation.py:评估使用微调后的模型或者Whisper原模型。infer_tfs.py:使用transformers直接调用微调后的模型或者Whisper原模型预测,只适合推理短音频。infer_ct2.py:使用转换为CTranslate2的模型预测,主要参考这个程序用法。infer_gui.py:有GUI界面操作,使用转换为CTranslate2的模型预测。infer_server.py:使用转换为CTranslate2的模型部署到服务器端,提供给客户端调用。 欢迎大家扫码入知识星球讨论,知识星球里面提供项目的模型文件和博主其他相关项目的模型文件,也包括其他一些资源。 ## 模型测试表 原始模型字错率测试表。 使用模型指定语言aishell_testtest_nettest_meeting模型获取whisper-tinyChinese0.318980.404820.75332加入知识星球获取whisper-baseChinese0.221960.304040.50378加入知识星球获取whisper-smallChinese0.138970.184170.31154加入知识星球获取whisper-mediumChinese0.095380.135910.26669加入知识星球获取whisper-largeChinese0.089690.129330.23439加入知识星球获取whisper-large-v2Chinese0.088170.123320.26547加入知识星球获取 微调数据集后字错率测试表。 使用模型指定语言数据集aishell_testtest_nettest_meeting模型获取whisper-tinyChineseAIShell0.130430.44630.57728加入知识星球获取whisper-baseChineseAIShell0.089990.330890.40713加入知识星球获取whisper-smallChineseAIShell0.054520.198310.24229加入知识星球获取whisper-mediumChineseAIShell0.036810.130730.16939加入知识星球获取whisper-large-v2ChineseAIShell0.031390.122010.15776加入知识星球获取whisper-tinyChineseWenetSpeech0.177110.247830.39226加入知识星球获取whisper-large-v2ChineseWenetSpeech0.054430.100870.19087加入知识星球获取 未加速和加速后的推理速度测试表,使用GPU为GTX3090(24G)。 使用模型原生模型实时率(float16)转换CTranslate2加速后实时率(float16)转换CTranslate2加速后实时率(int8_float16)whisper-tiny0.030.060.06whisper-base0.040.060.06whisper-small0.080.080.08whisper-medium0.130.100.10whisper-large-v20.190.120.12 经过处理的数据列表。 数据列表处理方式AiShellWenetSpeech添加标点符号加入知识星球获取加入知识星球获取添加标点符号和时间戳加入知识星球获取加入知识星球获取 重要说明: 在评估的时候移除模型输出的标点符号,并把繁体中文转成简体中文。aishell_test为AIShell的测试集,test_net和test_meeting为WenetSpeech的测试集。RTF= 所有音频总时间(单位秒) / ASR识别所有音频处理时间(单位秒)。测试速度的音频为dataset/test.wav,时长为8秒。训练数据使用的是带标点符号的数据,字错率高一点。微调AiShell数据不带时间戳,微调WenetSpeech带时间戳。 安装环境 首先安装的是Pytorch的GPU版本,如果已经安装过了,请跳过。 conda install pytorch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1 pytorch-cuda=11.6 -c pytorch -c nvidia 安装所需的依赖库。 python -m pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple 准备数据 训练的数据集如下,是一个jsonlines的数据列表,也就是每一行都是一个JSON数据,数据格式如下。Whisper是支持有标点符号的,所以训练的数据集中可以带有标点符号。本项目提供了一个制作AIShell数据集的程序aishell.py,执行这个程序可以自动下载并生成如下列格式的训练集和测试集,注意: 这个程序可以通过指定AIShell的压缩文件来跳过下载过程的,如果直接下载会非常慢,可以使用一些如迅雷等下载器下载该数据集,然后通过参数--filepath指定下载的压缩文件路径,如/home/test/data_aishell.tgz。如果不使用时间戳训练,可以不包含sentences部分的数据。 { "audio": { "path": "dataset/0.wav" }, "sentence": "近几年,不但我用书给女儿压岁,也劝说亲朋不要给女儿压岁钱,而改送压岁书。", "sentences": [ { "start": 0, "end": 1.4, "text": "

node重装-解铃还须系铃人

一、问题场景 node的重装真的浪费我一整天时间,必须写下这篇踩坑日记 我在做博客项目的时候,启动前端Vue项目的时候,由于之前的node版本是18.16.1,npm install的时候出现问题,原因是node的版本过高,应该配置node14.几的版本,这个版本的node比较稳定,并且有维护 于是我用geek(一个uninstall软件)卸载了我原有的node,当我去下载安装node.14.21.3-x64.msi的时候,出现了以下提示 提示内容是更高的版本已经安装了,不能安装 到这里我很纳闷,本来我已经删除了原来的node的文件,为什么还显示已安装。 我去百度,csdn啊各种搜索,有说npm缓存文件没删干净,有说注册表没有删除,有说环境变量没有删除,等等,我都一一尝试了,都删除,继续安装,仍然出现以上提示。 二、 问题解决 我在一篇博客中看到一个方法,说是重新下载之前卸载的node版本,然后不要下一步,点击remove 这里就把之前版本node全部删除干净了 我下载14.21.3的时候,一路下一步畅通无阻 三、问题总结 这个node的卸载重装,需要我们重新下载之前版本的msi,然后在上面点击remove,才能实现完全卸载 归根结底还是之前下载的node版本太新,导致不稳定,经过这几次的bug,才知道版本要用老的,稳定的,比如jdk8,node14等等 借鉴自: https://blog.csdn.net/m0_63666148/article/details/131072760

【学习记录】动态数组(vector)的基本操作,包括插入、删除、扩容、输出、释放内存等。用C语言编写

#include <iostream> #include<cstdlib> #include<ctime> using namespace std; // 我的代码所犯的错误记录: // 1. \n的换行打成了/n导致程序迟迟不能换行 // 2. rand()%4,是随机0~3的随机数,并不是0~4 // 3. 在main主函数中,首先声明int pos, val;如果在下方执行函数继续声明int pos, val;会导致变量初始化,从而使int pos, val这两个变量再次刷新,导致随机插入值不对 // 4. for循环的使用规则,内部变量i必须初始化为int类型,不然会报错 // 定义自定义结构体 vector,用于模拟动态数组 typedef struct vector { int size; // 数组容量 int count; // 数组元素数量 int* data; // 指向数据的指钨 } vector; // 创建一个新的 vector,n 表示初始容量 vector* getNewvector(int n) { vector* p = (vector*)malloc(sizeof(vector)); // 分配 vector 结构体内存 p->size = n; p->count = 0; // 初始化元素数量为 0 p->data = (int*)malloc(sizeof(int) * n); // 分配数据存储内存 return p; } // 扩展 vector 的容量 int expand(vector* v) { if (v == NULL) return 0; // 检查传入参数是否为空 int* p = (int*)realloc(v->data, sizeof(int) * 2 * v->size); // 重新分配内存为原来的两倍 if (p == NULL) return 0; // 检查内存分配是否成功 v->data = p; v->size *= 2; return 1; } // 插入元素到指定位置 int insert(vector* v, int pos, int val) { if (pos < 0 || pos > v->count) return 0; // 检查插入位置是否有效 if (v->size == v->count && !

Java 树构建最快算法

项目中经常会用到树构建,比如地区树型数据构建,测试中一个省到街道级别的地区数据,共有13828条,普通的递归构建树算法计算次数接近2亿次,内存暂用高,CPU占用高,耗时久,一般在5秒左右,数据量上万后基本无法使用。 思路: 普通树构建算法都是通过递归遍历所有节点来找出当前节点的子节点实现的,计算次数成指数级增长,数据量达到上万条效率就已经不能满足需求了,可以考虑利用LinkedHashMap来保存所有节点,查找过程用LinkedHashMap来实现,经过实践,运算次数从2亿次减少到了2万7千多次,耗时从5秒减少到了450ms左右,效率提升了10倍有余。 算法描述: 1、把所有数据放入LinkedHashMap中 2、然后遍历LinkedHashMap中的所有值,并从该LinkedHashMap中查找当前节点的父节点,把当前节点加入父节点的孩子中 3、从LinkedHashMap中将已经加入父节点子集中的节点移除掉,并将移除节点后的LinkedHashMap作为下一个递归的参数继续调用 4、直到LinkedHashMap中所有的节点都再找不到父节点为止,这些剩下的根节点就是一棵构造好的树 优点:时间复杂度和空间复杂度低,效率高速度快,处理大数据量效果好 import java.io.Serializable; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * @description: 树构造工厂 * @author: YinHeng * @date: 2020/11/6 16:27 **/ public class TreeFactory<K, T extends TreeNode<K, T>> implements Serializable { /** * 递归向上查找法 * * @param nodeList * @return */ public List<T> buildTree(List<T> nodeList) { Map<K, T> nodeMap = new LinkedHashMap<>(16); for (T node : nodeList) { nodeMap.put(node.getId(), node); } return buildTree(nodeMap); } /** * 递归向上查找父节点 * * @param nodeMap * @return */ public List<T> buildTree(Map<K, T> nodeMap) { return findParent(nodeMap); } /** * 利用HashMap高效率递归向上查找,并每次减少遍历节点数 * * @param nodeMap * @return */ public List<T> findParent(Map<K, T> nodeMap) { //该循环结束后可以移除掉的节点 List<K> removeNodes = new ArrayList<>(); for (T node : nodeMap.

Sketch 98.3(UI矢量绘图软件)

Sketch是一款为用户提供设计和创建数字界面的矢量编辑工具。它主要用于UI/UX设计师、产品经理和开发人员,帮助他们快速设计和原型各种应用程序和网站。 Sketch具有简洁直观的界面,以及丰富的功能集,使得用户可以轻松地创建、编辑和共享精美的界面设计。它支持矢量编辑、图层样式和符号库,使得设计师可以快速创建可重用的组件,并保持整个设计过程中的一致性。 该软件还提供了强大的布局和对齐工具,以及自动排列和分布元素的功能,使得设计过程更加高效。此外,Sketch还内置了大量的插件和扩展,可以进一步增强其功能,满足用户不同的需求。 总之,Sketch是一款功能强大、易于使用的界面设计工具,适用于各种设计项目,无论是移动应用程序、网站还是其他数字界面设计。 Sketch 98.3(UI矢量绘图软件)

Springboot下载jar包中的文件

Spring boot中下载文件的2种方式 通过HttpServletResponse的OutputStream实现 Spring MVC的下载功能通过ResponseEntity实现 使用Spring Boot的流媒体响应(StreamingResponseBody)功能 两种方法都可以实现文件的下载。 第一种方法适合下载较小的文件,而第二种方法则更适合下载大文件,因为它可以在处理过程中避免一次性加载整个文件到内存中,因此也被称为流式下载。 示例代码 主要展示一下方式二的写法 project ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ └── example │ │ │ └── AppConfig.java │ │ └── resources │ │ └── application.properties │ └── … @RestController public class MyController { @GetMapping("/download") public ResponseEntity<Object> downloadFile() { //获取jar包中文件 ClassPathResource classPathResource = new ClassPathResource("application.properties"); Resource resource = new InputStreamResource(classPathResource.getInputStream()); String filename = classPathResource.

QT学习笔记-QT程序执行Linux Shell命令实现动态添加路由

QT学习笔记-QT程序执行Linux Shell命令实现动态添加路由 背景关键代码程序界面 背景 在使用QT进行Linux下应用程序开发时,在特定业务需求下,需要在程序中执行Linux的Shell命令。QT中执行Linux命令可以通过QProcess类和system来实现,如果需要得到Shell命令的执行的结果则只能通过QProcess类来实现。本示例解决的一个业务需求是带双网卡的Linux工控机中需要通过增加路由访问其他网段的服务器,最开始是把添加动态路由的功能写在启动脚本(shell脚本)中了,但在测试的时候拔掉对应的网线后,动态添加的路由会丢失,这时再插上网线还是不能与其他网段的服务器进行通讯。 关键代码 /** * @brief execShellCommand 执行Linux Shell 命令 * @param cmd 要执行的命令 * @param args 参数列表 * @return 返回执行的结果 */ QString Widget::execShellCommand(QString cmd, QStringList args) { QProcess proc; proc.start(cmd, args, QIODevice::ReadWrite); proc.waitForFinished(); QString result = proc.readAllStandardOutput(); return result; } /** * @brief routeExists 判断系统路由表中是否存在对应的路由信息 * @param fromNetPart 源网段,比如:10.10.80.0 * @param toGateway 目标网关,比如:192.168.0.1 * @param netmask 子网掩码,比如:255.255.255.0 * @return */ bool Widget::routeExists(QString fromNetPart, QString toGateway, QString netmask) { bool flag = false; //是否存在对应的路由 QString cmd = "

k8s删除 Terminating 状态的 namespace

处于 Terminating 状态的 ns 经常无法正常删除。可尝试以下两种方法解决: 方法1、使用 --force 参数,【delnsname 为要删除的命名空间,需要替换掉哦】 kubectl delete ns delnsname --force --grace-period=0 这种方法一般情况下是有效的。但在ns长时间处于Terminating的时候也会失效 方法2、修改 finalize a、导出ns的json文件【delnsname 为要删除的命名空间,需要替换掉哦】 kubectl get ns delnsname -o json > delnsname.json b、修改 json文件,删除 “finalizers” 内的 “kubernetes” vi delnsname.json c、执行命令:【delnsname 为要删除的命名空间,需要替换掉哦】 kubectl replace --raw "/api/v1/namespaces/delnsname/finalize" -f ./delnsname.json 再检查就发现已经被删除了 原文:https://blog.csdn.net/babay550/article/details/130621569

QT学习笔记-QT访问各种关系数据库笔记汇总

QT学习笔记-QT访问各种关系数据库笔记汇总 1、QT访问Oracle数据库2、QT访问SQLServer数据库3、QT访问MySQL数据库4、QT访问PostgreSQL数据库5、QT访问Access数据库6、QT多线程中访问数据库的要点 在使用QT进行应用开发过程中,不可避免的会涉及到访问关系数据库,为了方便后期查阅笔记,在本文进行一下汇总。 1、QT访问Oracle数据库 1.1、关于QT访问Oracle数据库的驱动编译请参阅 1.1.1 《QT学习笔记-QT安装oracle oci驱动》 1.1.2 《QT学习笔记-oracle oci数据库驱动交叉编译并移植到ARM开发板》 1.2、关键步骤: 1.2.1 配置oracleclient的环境变量LD_LIBRARY_PATH,或者直接在代码中通过QLibrary加载依赖库 1.2.2 参考代码 void Widget::on_btnDbTest_clicked() { #ifdef Q_OS_WIN QLibrary *oci_lib = new QLibrary("D:/oracleinstantclient_19_19/oci.dll"); oci_lib->load(); if (!oci_lib->isLoaded()) { qDebug() << "oracle oci动态库加载失败!"; return; } #else QLibrary *oci_lib = new QLibrary("/usr/lib/oracleclient/instantclient_19_19/libclntsh.so"); bool loadresult = oci_lib->load(); qDebug() << "oracle oci动态库load result is " << loadresult; if (!loadresult) { qDebug() << oci_lib->errorString(); } if (!oci_lib->isLoaded()) { qDebug() << "oracle oci动态库libclntsh.so加载失败!"; return; } #endif //以下代码测试访问Oracle数据 QSqlDatabase db = QSqlDatabase::addDatabase("

waste-datasets-review - 包含任何类型的垃圾、垃圾、废物和垃圾的图像数据集列表

废物数据集审查 包含任何类型的垃圾、垃圾、废物和垃圾的数据集列表。在detectwaste.ml项目期间创建 今天,每年生产超过 3 亿吨塑料。塑料无处不在,我们在日常生活中不断使用它。 检测垃圾项目的想法是使用人工智能来检测环境中的塑料垃圾。我们的解决方案将适用于视频和摄影。我们的目标是将 AI 用于公益。 访问majsylw/litter-detection-review,查看有关环境中垃圾问题的论文、项目和其他资源的更广泛评论。 贡献 随意添加新数据集的简短描述问题或创建拉取请求- 将新数据集添加到表中或填写缺少的描述。 概括 姓名编号类别编号子类别编号图像注解评论网站描述垃圾桶 1.03347 212实例分割水下图像网站✔️垃圾-ICRA193345 700检测水下图像网站✔️塔可28601 500分割荒野中的废物网站✔️炸玉米饼盒子760在制品检测荒野中的废物在制品✔️无人机Vaste1——772分割无人机数据集github✔️垃圾网6——2 527分类清晰的背景github✔️瓦达巴8颜色、尺寸、形状或材料4 000分类塑料数据集,背景清晰网站✔️GLASSENSE-VISION71362 000分类家居用品,清晰的背景网站✔️废物分类数据2——~25 000分类从谷歌搜索中抓取卡格✔️废物分类数据 v23——~27 500分类从谷歌搜索中抓取卡格✔️寿司餐厅的废弃图片16——500分类清晰的背景卡格✔️打开垃圾 map11187> 100k多标签分类荒野中的废物网站✔️垃圾24尺寸、形状或材料~14 000检测野外废弃物,付费许可证网站✔️饮用废物分类4——9640检测清晰的背景,(罐头和瓶子)卡格✔️废物图片34——~24 000分类从谷歌搜索中抓取卡格✔️现场垃圾3——~2 400分类从 Bing 搜索中抓取kaggle github✔️深海垃圾5——3 055分类水下图像卡格✔️MJU-Waste v1.01——2475分割纯色背景,室内 RGBD 图像github✔️国内垃圾数据集10——> 9000分类/检测荒野废物旅馆,付费许可证,250 张免费图片github✔️烟头数据集1——2200检测荒野中的废弃旅馆,合成图像网站✔️ 描述 垃圾桶 1.0 垃圾观察的实例分割标记数据集 3 个主要类别下的 7212 张图像:生物、垃圾、未知。类别: bio = 海龟、鱿鱼、龙虾、未知、水母、黄貂鱼、虾、小龙虾、章鱼、鲨鱼、贝壳、螃蟹、海星、鳗鱼垃圾 = 衣服、管道、瓶子、袋子、零食包装纸、手套、轮胎、罐头、杯子、容器、树枝、残骸、防水布、盒子、软管、绳索、干草、网、纸、桶、电线未知 下载:直接从网站 TrashCan 1.0 An Instance-Segmentation Labeled Dataset of Trash Observations 垃圾-ICRA19: 从视频中提取的 5700 张水下图像的边界框标记数据集 About Jungseok - Jungseok Hong

【Java】将Base64格式的图片等比/非等比伸缩至目标尺寸代码实现

文章目录 等比伸缩需求代码实现 非等比 等比伸缩 需求 前端页面上传的图片是Base64字符串,需要根据目标尺寸进行伸缩,不能改变图片的比例 代码实现 使用图片处理工具:thumbnailator 引入Maven依赖: <dependency> <groupId>net.coobird</groupId> <artifactId>thumbnailator</artifactId> <version>0.4.8</version> </dependency> 核心代码: import net.coobird.thumbnailator.Thumbnails; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.math.RoundingMode; import java.text.DecimalFormat; import java.util.Base64; import java.util.Objects; public class Test { public static final String IMAGE_BASE64_PREFIX_REG = "data:image/[^;]+;base64,"; // 你的测试数据 private static final String IMG_BASE64 = ""; private static final String FILE_PATH = "/Users/xdf/Desktop/Temp/test.png"; private static Integer targetHeight = 400; private static Integer targetWidth = 400; public static void main(String[] args) throws IOException { DecimalFormat df = new DecimalFormat("

Unity Blend shape基本用法

Unity Blend Shapes 是一种非常有用的技术,它可以用于实现角色面部动画和形状变形效果。在本篇博客中,我们将介绍 Unity Blend Shapes 的基本概念,并提供一些代码示例来帮助你快速上手。 什么是 Blend Shapes? Blend Shapes,也被称为 Morph Targets 或是 Shape Keys,是一种用于实现角色面部表情和形状变形的技术。通过在角色模型上定义一系列不同的面部表情或形状,然后通过调整这些形状的权重,我们可以实现平滑的面部动画效果。 在 Unity 中,我们可以使用 Skinned Mesh Renderer 组件来实现 Blend Shapes。这个组件允许我们调整每个顶点的位置、法线和切线,从而实现形状的变化。 如何创建 Blend Shapes? 在 Unity 中创建 Blend Shapes 需要经过以下几个步骤: 首先,我们需要在角色模型的网格上定义 Blend Shapes。打开模型的编辑模式,选中需要调整的顶点,然后在 Inspector 窗口中点击 “Create Blend Shape” 按钮。这将为选定的顶点创建一个新的 Blend Shape。 继续为模型的其他部分创建 Blend Shapes,直到我们定义了所有需要的表情或形状。 在代码中,我们可以通过脚本来控制 Blend Shapes 的权重。通过调整权重的值,我们可以实现不同的面部表情或形状变化。 下面是一个简单的示例,展示了如何在 Unity 中创建和控制 Blend Shapes: using UnityEngine; public class BlendShapeController : MonoBehaviour { public SkinnedMeshRenderer skinnedMeshRenderer; public string blendShapeName; void Update() { // 获取当前 Blend Shape 的权重 float weight = skinnedMeshRenderer.

H265视频转码H264视频

LiveMedia视频平台提供H5网页web前端无插件视频码流,但目前主流浏览器和播放器都只支持H264的码流,但是随着编码技术的迭代,目前H265编码的视频已在安防行业得到了广泛的使用,平台仅支持H264需要客户修改前端的视频编码,这样会造成存储和带宽的浪费和压力,在此技术和应用背景下,平台兼容H265势在必行。平台端兼容H265有以下几种方案可选: 方案一:平台支持H265视频转发,由web前端做H265解码显示。 方案二:平台将H265视频在后台做转码成H264后,再转发至web前端进行显示。 采用方案一需要开发支持H265的基于WASM视频播放器,对技术门槛要求有点高,另外跨平台视频播放、小程序播放还需另外开发,综合考虑,最终我们选择了方案二,这样客户不需要修改原有的代码就能实现视频播放。 在介绍LiveMedia后台对H265视频进行转码,先普及下视频转码的知识 1、软编码和硬编码如何区分 软编码:使用CPU进行编码 硬编码:使用非CPU进行编码,如显卡GPU、专用的DSP、FPGA芯片等 2、软编码和硬编码比较 软编码:实现直接、简单,参数调整方便,升级易,但CPU负载重,性能较硬编码低,低码率下质量通常比硬编码要好一点。 硬编码:性能高,低码率下通常质量低于软编码器,但部分产品在GPU硬件平台移植了优秀的软编码算法(如X264)的,质量基本等同于软编码。 3、目前的主流GPU加速平台 NVIDIA、INTEL、AMD等 4、目前主流的GPU平台开发框架 CUDA:NVIDIA的封闭编程框架,通过框架可以调用GPU计算资源。 AMD APP:AMD为自己的GPU提出的一套通用并行编程框架,标准开放,通过在CPU、GPU同时支持OpenCL框架,进行计算力融合。 OpenCL:开放计算语言,为异构平台编写程序的该框架,异构平台可包含CPU、GPU以及其他计算处理器,目标是使相同的运算能支持不同平台硬件加速。 Inel QuickSync:集成于Intel显卡中的专用视频编解码模块。 LiveMedia平台后台视频转码采用NVIDA GPU加速平台,支持软/硬解码兼容,在GPU富足的情况下,优先使用硬解码。 在确定了GPU平台后,需要搭建开发和运行环境(NVIDIA 驱动安装和CUDA开发包安装就不缀述了,CSDN上博客很多),如有需要的小伙伴们可以留言。 在使用NVIDIA GPU做转码时需要根据官方提供的开发文档和产品详细配置,有些产品是不带H265解码核心的,详细的见图(从NVIDIA网站上截取部分),仅供参考 详情请参考NVIDIA官方说明Page Not Found | NVIDIA Developer 交流联系: 杭州厚航科技有限公司http://houhangkeji.com/ QQ技术交流群:698793654

c++ 原子变量-Memory fence

摘抄自:https://github.com/apache/brpc/blob/master/docs/cn/atomic_instructions.md#cacheline English version 我们都知道多核编程常用锁避免多个线程在修改同一个数据时产生race condition。当锁成为性能瓶颈时,我们又总想试着绕开它,而不可避免地接触了原子指令。但在实践中,用原子指令写出正确的代码是一件非常困难的事,琢磨不透的race condition、ABA problem、memory fence很烧脑,这篇文章试图通过介绍SMP架构下的原子指令帮助大家入门。C++11正式引入了原子指令,我们就以其语法描述。 顾名思义,原子指令是对软件不可再分的指令,比如x.fetch_add(n)指原子地给x加上n,这个指令对软件要么没做,要么完成,不会观察到中间状态。常见的原子指令有: 原子指令 (x均为std::atomic)作用x.load()返回x的值。x.store(n)把x设为n,什么都不返回。x.exchange(n)把x设为n,返回设定之前的值。x.compare_exchange_strong(expected_ref, desired)若x等于expected_ref,则设为desired,返回成功;否则把最新值写入expected_ref,返回失败。x.compare_exchange_weak(expected_ref, desired)相比compare_exchange_strong可能有spurious wakeup。x.fetch_add(n), x.fetch_sub(n)原子地做x += n, x-= n,返回修改之前的值。 你已经可以用这些指令做原子计数,比如多个线程同时累加一个原子变量,以统计这些线程对一些资源的操作次数。但是,这可能会有两个问题: 这个操作没有你想象地快。如果你尝试通过看似简单的原子操作控制对一些资源的访问,你的程序有很大几率会crash。 Cacheline 没有任何竞争或只被一个线程访问的原子操作是比较快的,“竞争”指的是多个线程同时访问同一个cacheline。现代CPU为了以低价格获得高性能,大量使用了cache,并把cache分了多级。百度内常见的Intel E5-2620拥有32K的L1 dcache和icache,256K的L2 cache和15M的L3 cache。其中L1和L2 cache为每个核心独有,L3则所有核心共享。一个核心写入自己的L1 cache是极快的(4 cycles, ~2ns),但当另一个核心读或写同一处内存时,它得确认看到其他核心中对应的cacheline。对于软件来说,这个过程是原子的,不能在中间穿插其他代码,只能等待CPU完成一致性同步,这个复杂的硬件算法使得原子操作会变得很慢,在E5-2620上竞争激烈时fetch_add会耗费700纳秒左右。访问被多个线程频繁共享的内存往往是比较慢的。比如像一些场景临界区看着很小,但保护它的spinlock性能不佳,因为spinlock使用的exchange, fetch_add等指令必须等待最新的cacheline,看上去只有几条指令,花费若干微秒并不奇怪。 要提高性能,就要避免让CPU频繁同步cacheline。这不单和原子指令本身的性能有关,还会影响到程序的整体性能。最有效的解决方法很直白:尽量避免共享。 一个依赖全局多生产者多消费者队列(MPMC)的程序难有很好的多核扩展性,因为这个队列的极限吞吐取决于同步cache的延时,而不是核心的个数。最好是用多个SPMC或多个MPSC队列,甚至多个SPSC队列代替,在源头就规避掉竞争。另一个例子是计数器,如果所有线程都频繁修改一个计数器,性能就会很差,原因同样在于不同的核心在不停地同步同一个cacheline。如果这个计数器只是用作打打日志之类的,那我们完全可以让每个线程修改thread-local变量,在需要时再合并所有线程中的值,性能可能有几十倍的差别。 一个相关的编程陷阱是false sharing:对那些不怎么被修改甚至只读变量的访问,由于同一个cacheline中的其他变量被频繁修改,而不得不经常等待cacheline同步而显著变慢了。多线程中的变量尽量按访问规律排列,频繁被其他线程修改的变量要放在独立的cacheline中。要让一个变量或结构体按cacheline对齐,可以include <butil/macros.h>后使用BAIDU_CACHELINE_ALIGNMENT宏,请自行grep brpc的代码了解用法。 Memory fence 仅靠原子技术实现不了对资源的访问控制,即使简单如spinlock或引用计数,看上去正确的代码也可能会crash。这里的关键在于重排指令导致了读写顺序的变化。只要没有依赖,代码中在后面的指令就可能跑到前面去,编译器和CPU都会这么做。 这么做的动机非常自然,CPU要尽量塞满每个cycle,在单位时间内运行尽量多的指令。如上节中提到的,访存指令在等待cacheline同步时要花费数百纳秒,最高效地自然是同时同步多个cacheline,而不是一个个做。一个线程在代码中对多个变量的依次修改,可能会以不同的次序同步到另一个线程所在的核心上。不同线程对数据的需求不同,按需同步也会导致cacheline的读序和写序不同。 如果其中第一个变量扮演了开关的作用,控制对后续变量的访问。那么当这些变量被一起同步到其他核心时,更新顺序可能变了,第一个变量未必是第一个更新的,然而其他线程还认为它代表着其他变量有效,去访问了实际已被删除的变量,从而导致未定义的行为。比如下面的代码片段: // Thread 1 // bool ready was initialized to false p.init(); ready = true; // Thread2 if (ready) { p.bar(); } 从人的角度,这是对的,因为线程2在ready为true时才会访问p,按线程1的逻辑,此时p应该初始化好了。但对多核机器而言,这段代码可能难以正常运行: 线程1中的ready = true可能会被编译器或cpu重排到p.init()之前,从而使线程2看到ready为true时,p仍然未初始化。这种情况同样也会在线程2中发生,p.bar()中的一些代码可能被重排到检查ready之前。即使没有重排,ready和p的值也会独立地同步到线程2所在核心的cache,线程2仍然可能在看到ready为true时看到未初始化的p。 注:x86/x64的load带acquire语意,store带release语意,上面的代码刨除编译器和CPU因素可以正确运行。

利用Windows11的投屏功能将电脑屏幕内容扩展到电视上

Windows 11不仅在界面和操作上进行了全面的优化和升级,其功能性也有所增强,尤其是在多屏互动方面。其中,投屏功能成为了家庭娱乐和工作展示的有力工具。下面,我们就来详细探讨如何利用Windows 11的投屏功能,将电脑屏幕内容扩展到电视上。 一、无线投屏 方法一: 1. 首先,确保您的Windows 11电脑已连接到Wi-Fi。按住Windows键,然后找到并打开您想观看的内容,例如使用“电影与电视”应用。 2. 当您打开想要观看的视频时,找到并点击屏幕右下角的菜单(通常表示为三个点),从中选择“投射到设备”。 3. 此时,您需要确保您的智能电视已经安装了相应的接收应用,如“乐播投屏”,并且电视与电脑在同一局域网下。系统会搜索并显示可用的设备,选择您的电视进行连接。 方法二: 1. 在Windows 11电脑上,您可以直接按下“Win + K”快捷键,快速启动无线投放功能。 2. 如果您希望通过任务栏进行操作,可能需要先到设置中添加“投放”功能到通知区域。 3. 添加完成后,在任务栏的通知区域点击“投放”,系统会自动搜索并列出当前可用的无线显示器。 4. 选择您的电视或投屏设备,点击连接,即可开始无线投屏。 本文来源于:win11系统怎么将影视投屏到电视 win11无线投屏到电视的方法-下载集 (xzji.com)https://www.xzji.com/news/13911.html

Go构建者模式

构建者模式是一种创建型设计模式,用于构建复杂的对象。它可以确保在一个 struct 有多个构造函数参数时依旧能保持代码的可读性与清晰性。 1、链式写法 type computer struct { cpu string arm string } func NewComputer() *computer { return &computer{} } func (c *computer) SetCPU(CPU string) *computer { c.cpu = CPU return c } func (c *computer) SetARM(ARM string) *computer { c.arm = ARM return c } func main() { c := NewComputer() c.SetCPU("Intel").SetARM("x86") fmt.Println(c) } 2、为什么使用构建者模式 分离 + 实施更细致的控制:使对象的构建逻辑与其表示相分离。 使用构建者模式,我们可以在调用Build()方法之前,执行更多的操作,比如验证属性的有效性,或者设置一些默认值。一般步骤如下: 编写原结构体编写原结构体的 Builder 结构体,为其编写 New 构建函数编写类似于之前链式调用的方法,但是返回 Builder 结构体编写 Build() 方法,返回值为原结构体 type computer struct { cpu string arm string } type computerBuilder struct { computer *computer } func NewComputerBuilder() *computerBuilder { return &computerBuilder{computer: &computer{}} } func (cb *computerBuilder) setCpu(cpu string) *computerBuilder { cb.

血泪教训!服务器被入侵怎么办?排查过程全分享

前言 一、服务器入侵现象 近期有一个朋友的服务器(自己做了网站)好像遭遇了入侵,具体现象是:服务器 CPU 资源长期 100%,负载较高。服务器上面的服务不能正常提供服务。 朋友处理了一会没有解决,我开始想说我不是搞安全的,我怎么会,但朋友开出了天价,一顿海底捞,我在生活和现实面前低头了,开始上手看看了。 二、服务器排查和处理 2.1、服务器被入侵的可能原因 服务器 ssh 密码 设置得很简单。腾讯云安全组范围放得很大。使用了宝塔,宝塔面板的密码也是很简单的密码(应该不是这个入侵入口)。 2.2、排查和处理步骤 1.ps -ef / top 找出占用进程最大的服务 问题现象 ps/top命令已经被替换了。 2.查找详细的入侵痕迹 last 或者 grep 'Accepted' /var/log/secure。 问题现象 [root@VM-12-12-centos ~]# grep 'Accepted' /var/log/secure Aug 26 21:51:37 VM-12-12-centos sshd[19822]: Accepted password for root from 34.215.138.2 port 36720 ssh2 Aug 27 08:52:05 VM-12-12-centos sshd[3053]: Accepted password for root from 127.0.0.1 port 57534 ssh2 Aug 27 08:58:50 VM-12-12-centos sshd[7038]: Accepted password for root from 127.

CentOS 6/7/8 操作系统镜像下载

CentOS Mirrors List ​编辑 DownloadAbout About CentOS Frequently Asked Questions (FAQs) Special Interest Groups (SIGs) CentOS Variants Governance Community Contribute Forums Mailing Lists IRC Calendar & IRC Meeting List Planet Submit a Bug Stories Documentation Wiki Manuals GPG Key Info Help In order to conserve the limited bandwidth available, ISO images are not downloadable from mirror.centos.org The following mirrors in your region should have the ISO images available: Index of /centos/7.

Leetcode学习记录(1)

1.unordered_map C++关联容器,内部hash表结构(检索) 通过key来检索value,不是通过绝对地址,内部无序,Map对应唯一值,动态管理 unordered_map<const Key, T> map; 如上述代码表述,则为2个参数<键,值> 2.auto auto:在块作用域、命名作用域、循环初始化语句等等中声明变量时,关键词auto用作类型指定符。 const:修饰符 ​ 想要拷贝元素:for(auto x:range) ​ 想要修改元素 : for(auto &&x:range) ​ 想要只读元素:for(const auto& x:range) 3.stringstream #include<sstream> #include<iostream> using namespace std; int main() { string line,word; while(getline(cin,line)) { stringstream stream(line); cout<<stream.str()<<endl; while(stream>>word){cout<<word<<endl;} } return 0; } 输入:shanghai no1 school 1989 输出:shanghi no1 school 1989 shanghai no1 school 1989 stringstream是字符串流。它将流与存储在内存中的string对象绑定起来。 在多种数据类型之间实现自动格式化。 4.数学相关定理

【超级简单】3步 安装conda + pytorch gpu版本

【超级简单】3步 安装conda + pytorch gpu版本 1. 创建虚拟环境至于python 3.X和cuda对应 ? 2. 下载cuda 驱动,cuda toolkit (可选)3. 虚拟环境中输入以下指令至于 怎么查看自己电脑对应的cuda版本号 ? 4.测试是否安装成功有疑惑可以再看看这篇文章写的。 下载anaconda,能让你高效管理不同版本运行环境。 conda + pytorch gpu 适用于linux 和window版本, 建议前提确保自己的显卡能用哈。 以下是在window10的示范。 1. 创建虚拟环境 conda create -n your_env_name python=3.X conda avtivate your_env_name 至于python 3.X和cuda对应 ? 参考Tensorflow 的资料: https://www.tensorflow.org/install/source_windows?hl=zh-cn 2. 下载cuda 驱动,cuda toolkit (可选) https://developer.nvidia.com/cuda-toolkit-archive 下载成功的话可以 在cmd 输入 nvcc -V, 显示版本号。 显示 not found 则说明没转成功。 3. 虚拟环境中输入以下指令 conda install pytorch torchvision torchaudio cudatoolkit=X.X -c pytorch X.

芯旺微chipon KF32A156系列ccp模块用于输出 pwm 的基本使用

原创扣字不易,转载请注明源出处!!! 芯旺微chipon KF32A156系列 CCP 模块的基本使用 在数据手册上可以看到引脚具备CCPxCHy等功能映射,如下图。 这些是capture、compara、pwm的首字母缩写。其中CCPx是以定时器为时基,CHy就是通道。通常一个通用定时器下的CCP模块是可以有4个通道,就PWM而言,这4个通道可以配置成频率相同,占空比不同的通道,支持中心对齐和边沿对齐。 下面我们以 PH1和PD14为例来进行配置 : 配置步骤如下: 1、首先查询数据手册可知:PH1可以配置为CCP1CH2,PD14可以配置为CCP1CH1,图中可以看到其实这两个脚也可以配置为其他通道的用来输出PWM,我们这里就都是用Timer1,也同时为了演示一个定时器如何配置多个通道。 小提示:配置流程三步走又来了: 2、老规矩, 第一步配置引脚 。既然引脚要配置功能,那就离不开重映射配置,先把引脚重映射功能根据数据手册指示的重映射通道来配置,程序如下: GPIO_Write_Mode_Bits (GPIOH_SFR,GPIO_PIN_MASK_1, GPIO_MODE_RMP); //预期输出20KHZ GPIO_Write_Mode_Bits (GPIOD_SFR,GPIO_PIN_MASK_14, GPIO_MODE_RMP); //预期输出20KHZ GPIO_Pin_RMP_Config(GPIOH_SFR,GPIO_Pin_Num_1, GPIO_RMP_AF10); //CCP1CH2 GPIO_Pin_RMP_Config(GPIOD_SFR,GPIO_Pin_Num_14, GPIO_RMP_AF2); //CCP1CH1 3、配置外设本身,那么PWM设计到的外设,一个是定时器,还有一个是CCP模块,定时器设置和频率相关,CCP模块可以配置有哪些通道打开,占空比多少,pwm输出方式等等。看下面的程序配置 TIM_Reset(CCP1_SFR); /* CCP 's PWM function channel mode */ CCP_PWM_Mode_Config(CCP1_SFR, CCP_CHANNEL_1, CCP_PWM_MODE); //配置t1通道1为pwm模式 CCP_PWM_Mode_Config(CCP1_SFR, CCP_CHANNEL_2, CCP_PWM_MODE);//配置t1通道2为pwm模式 /* Configure CCP channel output to control PWM output, high effective */ CCP_Channel_Output_Control(CCP1_SFR, CCP_CHANNEL_1, CCP_CHANNEL_OUTPUT_PWM_INACTIVE); //配置通道1对齐方式,可自行查询其他方式 CCP_Channel_Output_Control(CCP1_SFR, CCP_CHANNEL_2, CCP_CHANNEL_OUTPUT_PWM_INACTIVE); //配置通道2对齐方式,可自行查询其他方式 /* PWM duty cycle */ CCP_Set_Compare_Result(CCP1_SFR, CCP_CHANNEL_1, 6001); //设置占空比 CCP_Set_Compare_Result(CCP1_SFR, CCP_CHANNEL_2, 6001); //设置占空比 /* Timing mode selection */ GPTIM_Work_Mode_Config(CCP1_SFR, GPTIM_TIMER_MODE); /* Timer count value */ GPTIM_Set_Counter(CCP1_SFR, 0); /* Timer period value */ GPTIM_Set_Period(CCP1_SFR, 6000); /* Timer prescaler value */ GPTIM_Set_Prescaler(CCP1_SFR, 0); #if 1 /* Up-counting mode, that is, edge-aligned PWM signal */ GPTIM_Counter_Mode_Config(CCP1_SFR, GPTIM_COUNT_UP_OF); //边沿对齐的定时器计数模式设置 #else /* Up and down counting mode, that is, center-aligned PWM signal */ GPTIM_Counter_Mode_Config(CCP1_SFR, GPTIM_COUNT_UP_DOWN_OF); //中心对齐的定时器计数模式设置 #endif /* Configure working clock */ GPTIM_Clock_Config(CCP1_SFR, GPTIM_SCLK); GPTIM_Updata_Immediately_Config(CCP1_SFR, TRUE); GPTIM_Updata_Enable(CCP1_SFR, TRUE); GPTIM_Updata_Immediately_Config(CCP1_SFR, FALSE); /* Enable timer */ GPTIM_Cmd(CCP1_SFR, TRUE); 4、配置中断,由于pwm一般无需开中断,这里就不说明中断配置了,如果有特殊需求,可以自行开启对应的中断。一般使用ccp的capture或者compara的功能会使用到中断。

Nginx代理接口访问返回404

Nginx代理接口访问返回404 一、背景 因为不同业务系统间有接口调用,存在跨域问题,为了解决同源策略,需要将接口通过nginx去转发,但是配置完后通过postman请求一直存在访问404的问题。 访问地址:https://a.test.com/nsyapi/oauth/loginOther 被代理接口地址:https://b.prod.com/api/oauth/loginOther 二、Nginx配置后的现象 postman请求接口出现404报错 三、原因 由于proxy_pass请求头出现问题导致返回404。可以在配置中添加一些相关的请求头来解决这个问题。例如 在这个配置中,我们添加了三个新的请求头Host、X-Real-IP和X-Forwarded-For,这可以帮助我们正确地将请求传递到目标服务器,并确保我们收到正确的响应。 四、 解决办法 去掉 proxy_redirect off; 增加 proxy_set_header Host $proxy_host; postman请求接口正常 命令行验证接口请求成功 [root@Nginx-01 yukw]# curl -H "Content-Type: application/json" -X POST -d '{"mobile":"18763823456","source":"aa","type":"3","route":"orderList?order_id=233&renew=abc"}' "https://b.prod.com/api/oauth/loginOther" {"code":1,"result":"dbb1623e-1747-4017-b8e8-96ace309982f","msg":"登录成功"} [root@Nginx-01 yukw]# curl -H "Content-Type: application/json" -X POST -d '{"mobile":"18763823456","source":"aa","type":"3","route":"orderList?order_id=233&renew=abc"}' "https://a.test.com/nsyapi/oauth/loginOther" {"code":1,"result":"f23b2a24-dd7e-464e-bc1f-a4806097e252","msg":"登录成功"} 五、总结: 1、确认proxy_pass指向的地址是否正确; 2、确认目标服务器是否正常; 3、确认proxy_pass请求头的正确性; 好了,这就是Nginx代理接口访问返回404的解决办法了,如有问题可与博主一起交流讨论! 参考:https://pythonjishu.com/nvsknuuxbmoexma/ 

LDPC译码原理(公式推导)及其matlab代码实现(超详细)

目录 博文更改记录一、背景概述二、LDPC译码理论2.1 LDPC码的表示方法2.1.1LDPC码的矩阵表示2.1.2 Tanner图表示 2.2符号说明2.3LDPC译码算法2.3.1引理1及其证明2.3.2和积译码算法(概率域译码算法)2.3.3对数域BP译码算法(LLR BP)2.3.4最小和译码算法(Min-Sum BP)2.3.5改进的最小和译码算法(NMSA and OMSA) 三、LDPC译码算法的matlab实现3.1BPSK调制体制下关于SNR和 E b / N 0 E_b/N_0 Eb​/N0​与 δ \delta δ之间的关系3.2AWGN信道下的初始化3.3基于归一化最小和译码算法(Normalized min-sum algorithm,NMSA)的matlab实现3.4分层归一化最小和LDPC译码算法3.4.1LBP译码算法3.4.2 分层最小和译码算法的matlab实现3.4.3 LBP译码算法和NMSA译码算法收敛速度对比 四、LDPC译码的调度算法 博文更改记录 时间版本号更改内容2022年4月12日 15:20V1.0新建博文2022年4月20日 13:20V1.1完成初稿,并发布该博文,初稿内容包含相关背景概述,及相关LDPC译码理论公式推导。2022年4月21日 9:08v1.2补充2.4.2小节AWGN信道下的初始化的相关内容2022年5月1日 14:25v1.3补充3.3节和3.4节关于归一化最小和译码算法和分层最小和译码算法等内容2022年5月20日 11:26V1.4补充2.3.5小节关于改进的最小和译码算法,增加LBP算法和NMSA收敛速度比较的Monte Carlo仿真matlab代码 一、背景概述 低密度奇偶校验码(Low-Density Parity-Check Codes)凭借其逼近Shannon限的纠错性能,受到了信道编译码学者的广泛关注,已成为DVB-S2、IEEE802.16e、CCSDS、5G等无线通信标准首选的信道编码方案。2001年,S.Chung等人的研究结果表明,码率1/2、码长10^7的非规则LDPC码在AWGN信道下采用置信传播算法进行迭代译码,当错误概率为10 ^-6时,距离Shnnon限仅相差0.0045dB。 LDPC码最迷人的地方在于译码算法,本文主要关注基于置信传播的迭代译码算法,博主在初学时,在阅读论文和相关书籍过程中,发现关于LDPC译码理论方面的讲解,公式推导讲的不是很清楚,需要阅读大量的书籍和文献,才能对其有一个系统性的认识;且关于LDPC译码matlab代码实现没有详尽的注释,理解起来较为困难,入门较难,花费较多时间;本文主要介绍基于置信传播的迭代译码算法及其改进算法,对涉及的公式,进行了详细的推导,并附上自己的理解;除此之外给出了matlab实现代码。因本文内容较多,难免会出现错误,还请各位读者批评指正,希望这篇博文能对大家有所帮助和启发。 二、LDPC译码理论 2.1 LDPC码的表示方法 2.1.1LDPC码的矩阵表示 一个LDPC码 v v v 是一种( n n n, k k k)线性分组码,码长为 n n n,信息序列长度为 k k k,可由其校验矩阵H所唯一确定,校验矩阵中1的数目远小于0的数目,具有稀疏性。H的维数是 m × n m\times n m×n,每一行对应一个校验方程(也称校验节点),每一列对应码字的一位(也称变量节点)。每一行中非零元素的个数称为行重,每一列中非零元素的个数称为列重。 下面是一个5 × \times × 10的校验矩阵及其对应的校验方程:

VMware Workstation Pro 17 的下载、激活、使用

下载链接: https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html 进入官网下载安装 MC60H-DWHD5-H80U9-6V85M-8280D 镜像文件下载 win10 :https://www.microsoft.com/zh-cn/software-download/windows10 下载后安装,选择为iso下载。 在安装镜像时,出现time out 情况 需要在虚拟机一开始进入时,随意按下任何键进入安装。(不及时按就会超时,等待后面选择restart)

网上书店系统设计

目录 摘要 iii Abstract iv 第一章 绪论 1 1.1 网上书店系统概论 1 1.1.1 课题开发的背景 1 1.2 课题开发的意义 2 1.2.1网上书店的优势 2 1.2.2 目前国内网上书店存在的主要问题 3 1.3 结构模式 4 第二章 开发技术综述 6 2.1 开发工具与环境 6 2.2开发平台 7 2.2.1 硬件平台 7 2.2.2 软件平台 7 2.2.3 技术平台 7 2.3 开发语言 8 2.3.1 HTML超文本标识语言 8 2.3.2 脚本语言 9 2.3.3 文本编辑方式 9 2.3.4 利用可视化编辑工具软件 9 2.4数据库技术 10 2.4.1 Microsoft SQL SERVER 2005数据库简介 10 2.4.2 连接SQL SERVER 2005数据库 11

学习Vue的心路历程(二)用Vue实现一个简易的登录页面

一、创建一个Vue文件(作者选择的是vscode) 二、更改默认加载路径,打开router目录下的index.js文件,修改为下图 修改完后代码为 import Vue from 'vue' import VueRouter from 'vue-router' import Login from '../components/Login_ages.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Login', component: Login } ] const router = new VueRouter({ routes }) export default router 三、修改App.vue,如下图 修改前: 修改后: 代码为: <template> <div id="app"> <router-view></router-view> </div> </template> <script> </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> 每次修改完都记得按CTRl+S保存 四、编写登录界面Login_ages.

给大家推荐个生成前端代码的工具,支持vue代码,支持组件拖拽

我自己有一个服务器,一直想着做点网页什么的,不然放在那儿都浪费了。无奈作为一个后端,前端的知识不够,就找了一个生成前端代码的工具。我自己用下来,感觉还真不错,推荐给各位。下面这张图就是iVX这个工具的主页,我们直接进入iVX CN后,点击开始开发即可。 我这里为了演示,放了很多控件进去。可以看到有编辑框、按钮、Excel组件选项。还有高德地图的组件,不过需要api,我就没有放。我现在的打算是用iVX先开发一些网页,正好它生成的前端代码都是vue的,一直听说vue不错,所以趁这个机会接触学习一下vue。 在代码编辑器的右上角我们可以选择是使用手机,还是使用电脑,调成电脑后,分辨率会比较大些,也方便观察一些细节。其实我觉得搞明白iVX的组件界面是怎么放置的,非常重要。我因为用java所以顺带着学了Swing,在Swing中有GridLayout 以及 BorderLayout 等布局什么的,但是对于现在前端这一块儿,还有些模糊,但是我知道这个非常重要。毕竟大家学习前端就是画一张皮嘛。就是个浏览器端GUI界面。 首先我对这个布局的要求就是能够跟随窗体的变换而变化,而这个需求在业内有个术语叫做响应式布局,就是比如我在电脑上是一种界面,到了手机上会自动调整。那我了解了一下,在iVX中也有这样的一种布局,叫做栅格系统的页面布局。我们来一起看下。 进入这个布局页面,这是要给demo,我们点击右上角的下载。它就会自动加载这个demo。 如下图所示,这是iVX官网的栅格系统demo,我们也可以直接拿来使用需要做出调整的改一改就可以。 当然,iVX不止栅格系统布局一种,还有我们常用的居中布局和移动三段式布局,具体都可以在iVX的官网布局中看到。在这里我非常建议大家将iVX的官方教程视频教程全部看完。因为我自己瞎琢磨浪费了不少时间。。。发现官网居然直接有教程。。而且教程的制作者明显是个前端高手,iVX用的熟练的很。跟着视频教程学准没错。 接下来我们导出前端源码,在导出之前注意点击上方的保存按钮。 最后是导出后的代码vue文件代码。到这儿就结束了,后续我还想再研究研究,怎么把这个vue文件用在浏览器中,这一步非常关键,因为我们制作出来的代码文件不就是为了使用么,这可真难为一个后端了。在此我也非常推荐大家使用iVX,可以说让我涉足前端的阻力少了许多。 对了,这个iVX后续还会开源的哦,如果对你有用不要忘记点赞收藏评论关注!