如何使用Cloudreve+Cpolar搭建个人PHP云盘系统并发布公网可访问

文章目录 1、前言2、本地网站搭建2.1 环境使用2.2 支持组件选择2.3 网页安装2.4 测试和使用2.5 问题解决 3、本地网页发布3.1 cpolar云端设置3.2 cpolar本地设置 4、公网访问测试5、结语 1、前言 自云存储概念兴起已经有段时间了,各互联网大厂也纷纷加入战局,一时间公有云盘遍地开花。但一段时间后,公有云盘潜在的安全问题也暴露出来,原有的共有云盘用户纷纷转为搭建私有云盘,也带动了群晖等一众私有云盘供应商的发展。可群晖硬件动辄数千,让个人消费者难以招架,是否能将个人电脑改造为私有云盘呢?答案自然是肯定的,今天我们就为大家介绍,如何使用Cpolar与Cloudreve,在个人Windows电脑上搭建一个强大的PHP云盘系统。 2、本地网站搭建 2.1 环境使用 Cloudreve是一个网页程序,由于其运行在本地电脑上,因此需要一个虚拟运行环境,这里我们使用的是PHPStudy这款软件。由于PHPStudy是独立软件,因此只需要在PHPStudy下载完成后,双击安装包内的安装程序,依照软件提示即可完成安装。 2.2 支持组件选择 与常见的网页程序一样,Cloudreve也是以PHP为基础,加上其文件传输功能,因此需要PHP、MySQL、Nginx、FTP、FileZilla、SQL-Front几个程序的支持。好在PHPStudy提供了这些支持软件的安装,省去了我们不少麻烦。 2.3 网页安装 在PHPStudy软件准备好后,我们就可以开始安装Cloudreve网页。在Cloudreve官网下载网页包(官网网页被挂在GitHub,网页打不开常态,可以从其他渠道下载) 网页压缩包下载完毕后,将Cloudreve压缩包解压至PHPStudy的WWW文件夹下,作为网页的根目录。本例中PHPStudy安装在D盘下,因此路径为此电脑 – D盘 – PHPStudy pro – WWW。 接着返回PHPStudy主界面的“网站”页面,点击该页面左上角的“创建网站”,开始对Cloudreve网页运行环境进行设置。 在“创建网站”页面,我们需要对网站运行环境进行几项基本设置,包括: 域名:本地访问网站的域名;端口:本地网页的输出端口号;根目录:即网页文件存放的路径,可以通过栏位右侧的“浏览”按钮进行选择;创建FTP和数据库:勾选这两项会弹出新窗口进行设置,设置内容主要为用户名、密码、名称几项;PHP版本:通常这项不必单独选择,PHPStudy会自动选择较高版本,但为避免安装后网站打开错误,最好选择7.2X版本的PHP。 在完成各项设置后,就可以点击页面下方的“确认”按钮,将这些配置保存下来。接着在浏览器地址栏中输入(localhost:80/cloudreveinstaller),进入网页安装程序。在这一步,Cloudreve会对运行环境和支持功能进行检查,只有必要项目自检通过,才能进行下一步部署。 下一步安装工作,主要是对数据库信息进行填写,我们只需要依照之前设定的数据库信息填入即可。 设置完数据库信息后,点击页面下方的“开始安装”,只需等待很短时间,Cloudreve就能安装完成。在网页安装完成页面,会给出Cloudreve后台地址、管理员登录信息和安全注意事项。 2.4 测试和使用 接着我们在浏览器地址栏中输入localhost:80(端口号需要根据实际设定输入,在这个例子中,我们使用的端口号为80),就能使用本地电脑上的Cloudreve网盘系统。 2.5 问题解决 在Cloudreve安装过程中,最容易出的一个问题,就是环境检查中URL Rewrite项目错误,这个问题解决方法也很简单,只要对网页进行伪静态设置即可。 首先我们打开PHPStudy,在Cloudreve网站条目右侧,点击“管理”选项,从中找到“伪静态”按钮,点击进入伪静态设置页面。 在伪静态设置框内,输入以下命令: location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=/$1 last; break; } } 输入完成后,点击下方的“确认”进行保存,再刷新一次安装页面,就能看到原本报错的URL Rewrite项目已经通过检查,我们就能继续进行下一步安装。 3、本地网页发布 3.1 cpolar云端设置 在Cloudreve网页安装完成后,我们就可以着手将位于本地电脑上的Cloudreve云盘,通过Cpolar创建的内网穿透数据隧道,将这个云盘发布到公共互联网上,在限定范围内接受注册用户(或分发已注册用户信息)访问该云盘。首先访问cpolar的官网,在官网页面,能找到cpolar客户端的下载按钮,我们可以先将cpolar下载至本地,等到对数据隧道关联本地网站时再进行安装。 Cpolar客户端下载完成后,先不着急离开官网页面,我们需要在官网页面预留一条空白数据隧道,用以承载本地Cloudreve。在以用户登录cpolar官网后,在“仪表盘”页面左侧点击“预留”按钮,进入cpolar云端空白数据隧道的预留设置页面。 在这个页面,我们可以选择预留“二级子域名”、“自定义域名”、“TCP地址”、“FTP地址”等多个项目(需要注意的是,云端保留各种数据隧道为高级功能,需要将cpolar升级至基础版及以上才能使用),对于Cloudreve网页来说,我们可选择“保留二级子域名”或“保留自定义域名”。其中“保留自定义域名”需要从域名供应商处购买域名,并对CNAME进行设置,为避免混淆,我们以“保留二级子域名”进行演示。 在“保留二级子域名”栏位,我们需要对拟保留的二级子域名进行简单设置,设置内容包括:

Everything结合内网穿透搭建在线资料库并实现随时随地远程访问

文章目录 前言1.软件安装完成后,打开Everything2.登录cpolar官网 设置空白数据隧道3.将空白数据隧道与本地Everything软件结合起来总结 前言 要搭建一个在线资料库,我们需要两个软件的支持,分别是cpolar(用于搭建内网穿透数据隧道,让我们能在公共互联网上访问到本地电脑)和Everything(用于快速检索本地电脑的资料,并提供下载服务)。这两款软件的下载地址如下。 Cpolar:*https://www.cpolar.com/download*Everything:*https://www.voidtools.com/zh-cn/downloads/* 软件下载完成后,就可以直接进行安装 1.软件安装完成后,打开Everything 软件安装完成后,我们先打开Everything,对文件服务器进行简单设定,即在Everything软件中开启http服务。为保证本地文件的安全,还可以对访问者设定用户名和密码。 2.登录cpolar官网 设置空白数据隧道 在完成Everything软件的设置后,我们就可以着手搭建能从公共互联网访问本地Everything的数据隧道。首先登录cpolar的官网,设置一条空白数据隧道,为之后的Everything公网发布做好准备。 3.将空白数据隧道与本地Everything软件结合起来 在完成cpolar云端的空白数据隧道设置后,就要转回本地电脑的cpolar客户端,将空白数据隧道与本地Everything软件结合起来。与cpolar云端设置空白数据隧道一样,在cpolar客户端也需要进行几项设置。 完成设置并创建数据隧道后,可以在“状态”项下的“在线隧道列表”中找到本地Everything的公共互联网地址。通过这个地址,我们能轻松查找并下载本地电脑上的文件和数据。 总结 至此,我们安装在本地电脑上的Everything软件,就能在公共互联网上访问到。并方便的搜索和下载所需文件资料。通过加载购买的自定义域名和安全证书,在cpolar客户端设置自定义域名或使用https协议,能让这条资料搜索的数据隧道变得更易记忆和安全。而使用cpolar发布本地电脑上的文件,只是cpolar内网穿透功能的一个应用场景,cpolar创建的数据隧道还能应用在更多场景中。

zookeeper【封神录】下篇

目录 🥞1.客户端API 🌭2.服务器动态上下线 🧂3.分布式锁 1.客户端API 1.1导入依赖 <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.14.1</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.5.7</version> </dependency> </dependencies> 1.2代码实现 public class zkClient { //一定不要有空格 private String connectString = "192.168.20.129:2181,192.168.20.130:2181,192.168.20.131:2181"; private int sessionTimeOut = 2000; private ZooKeeper zkClient; /** * 初始话zookeeper * 参数1:连接地址 * 参数2:超时时间 * 参数3:监听器 */ @Before public void init() throws IOException { zkClient = new ZooKeeper(connectString, sessionTimeOut, new Watcher() { @Override public void process(WatchedEvent watchedEvent) { List<String> children = null; try { children = zkClient.

9.java——(杂例)组合,代理,向上转型static,fianl,关键字(有道云笔记复制粘贴,大家整体性的把握)

组合——内部有类(心中有对象!!!)(足球 和足球运动员梅西和脚下的足球一样) has和is的区别,has是组合,是有,持有的意思;is是继承,是属于什么一类的意思 has是梅西踢着足球 is是梅西是足球运动员中的一员 组合其实不难理解,就是将对象引用置于新类中即可。组合也是—种提高类的复用性的—种方式。如果 你想让类具有更多的扩展功能,你需要记住—句话多用组合,少用继承 。 组合 1. public class SoccerPlayer { private String name; private Soccer soccer;(调用其他类,创建对象) } public class Soccer { private String soccerName; } 继承 2. public class SoccerPlayer { private String name; private Soccer soccer;(调用其他类,创建对象) } public class Meixi extends SoccerPlayer{ private double weight; private double height; } 代码中 SoccerPlayer 引用了 Soccer 类,通过引用 Soccer 类,来达到调用 soccer 中的属性和方法。 组合和继承是有区别的,它们的主要区别如下。 关于继承和组合勃优勃劣的争论没有结果,只要发挥各自的长处和优点即可, —般情况下,组合和继承 也是—对可以连用的好兄弟。 代理(这个没什么好讲的,) 除了继承和组合外,另外—种值得探讨的关系模型称为 代理 。代理的大致描述是, A 想要调用 B 类 的方法, A 不直接调用, A 会在自己的类中创建—个 B 对象的代理,再由代理调用 B 的方法。例如如 下代码

HTML如何设置多图片上传,并限制格式类型

在HTML如何设置多图片上传,并限制格式类型为jpg和png格式。 <input type="file" name="fileInput" id="fileInput"> 上面这行代码,只支持单个文件上传,且不支持文件类型过滤,在实际开发过程中,我们经常遇到会上传多张图片,并且有时候对上传的图片后缀格式有一定限制要求。那么我们可以用下面这行代码实现多图片文件上传,并限制格式为jpg和png格式。 <input type="file" id="fileInput" multiple accept="image/png, image/jpeg,image/jpg"> 最后我们应该如何获取上传图片信息呢?我们可以用JavaScript来获取上传的图片信息。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>文件上传多图简单例子</title> </head> <body> <input type="file" id="fileInput" multiple accept="image/png, image/jpeg,image/jpg"> <button onclick="getImages()">上传图片</button> <script> function getImages() { const fileInput = document.getElementById('fileInput'); const files = fileInput.files; for (let i = 0; i < files.length; i++) { const file = files[i]; console.log('文件名:', file.name); console.log('文件大小:', file.size); console.log('文件类型:', file.

【开源】基于JAVA+Vue+SpringBoot的农村物流配送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2.1 快递信息管理:2.2.2 位置信息管理:2.2.3 配送人员分配:2.2.4 路线规划:2.2.5 个人中心:2.2.6 退换快递处理:2.2.7 客户评价: 三、系统展示四、核心代码4.1 查询商家4.2 退换快递4.3 新增路线规划4.4 查询乡镇村社4.5 查询配送位置 五、免责说明 一、摘要 1.1 项目介绍 基于Vue+SpringBoot+MySQL的农村物流配送系统,包含快递客户管理模块、配送位置管理模块、配送人员模块、路线规划模块、商家管理模块、商品退换模块,还包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础模块,农村物流配送系统基于角色的访问控制,给物流管理员、配送人员使用,可将权限精确到按钮级别,您可以自定义角色并分配权限,系统适合设计精确的权限约束需求。 1.2 项目录屏 二、功能模块 2.1 系统登录、注册界面 1、快递员注册、登录此系统。 2、建立员工数据库,管理员工信息。 2.2 系统功能 2.2.1 快递信息管理: (1)添加客户信息:输入收货人,取件码,快递单号。 (2)查询客户信息:输入收货人,ID。 (3)删除客户信息: (4)修改客户信息; 2.2.2 位置信息管理: (1)添加位置信息:输入起始地点,输入终点 (2)删除位置信息: (3)修改位置信息: (4)定位信息:请输入地点信息 2.2.3 配送人员分配: (1)添加配送人员:输入性别,输入姓名,输入年龄 (2)删除配送人员信息: (3)修改配送人员信息: 2.2.4 路线规划: (1)划分路线图:输入乡镇名,村名, (2)为每个配送人员添加自己的路线: (3)删除路线: (4)修改路线: 2.2.5 个人中心: (1)员工个人信息管理:添加员工信息,输入姓名,性别,年龄;删除员工信息;查询员工信息;修改员工信息 (2)关于系统:系统版本 (3)退出系统: 2.2.6 退换快递处理: (1)输入退换产品理由; (2)输入商家信息:输入商家姓名,位置信息,联系方式 (3)输入客户信息:输入客户姓名,联系方式: (4)删除商家信息: (5)删除客户信息:

Windows找不到文件‘chrome‘,请确定文件名是否正确后,再试一次。

本文主要记录遇到vscode运行HTML文件提示: Windows找不到文件‘chrome‘,请确定文件名是否正确后,再试一次。问题的解决办法。 目录 一、打开设置 二 、搜索Live Server Config (1)安装Live Server插件 (2)打开settings.json编辑 (3)添加配置 三、如何查看chrome的安装路径 一、打开设置 打开路径:文件——首选项——设置(快捷键调用方式:CTRL+,) 二 、搜索Live Server Config 在搜索框中搜索Live Server Config(注意需要提前安装) (1)安装Live Server插件 (2)打开settings.json编辑 (3)添加配置 在文件的后面增加chrome浏览器应用运行路径地址。 "liveServer.settings.AdvanceCustomBrowserCmdLine": "C:/Users/Administrator/AppData/Local/Google/Chrome/Application/chrome.exe", 三、如何查看chrome的安装路径 在桌面图片右键属性——快捷方式——目标(T)

QT上位机开发(简易图像处理软件)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 大家都知道图像处理非常地重要,因为它不仅仅是可以用于拍照美颜,而且在工业、医疗和军事等方面也发挥着巨大的作用。另外一点大家有所不知的是,在工业上,图像处理排名靠前的几家公司,长期都是高毛利、高利润的代名词。这一次QT开发,我们正好可以借助于opencv开源库,做一个简单的图像处理软件。 1、创建一个简单的qt widget工程 我们需要这个工程,仅仅是引用它的一个框架。唯一需要注意的是,创建工程的时候,一定要选择64位,因为解析来下载的opencv库,也就是最新的opencv库OpenCV – 4.8.0,它只有64位的。 2、安装opencv库 之前一直认为windows上面opencv库都需要自己编译的,但是没想到在opencv官方网站,都是已经编译好的头文件和静态库和动态库。有了这几点,使用起来就非常方便了。这个安装包,就是编译好的压缩库,里面有头文件、lib文件和dll文件而已。 https://opencv.org/releases/ 3、设置include目录 安装了opencv之后,那么刚才创建的工程,就一定需要把opencv include目录包进来。注意选择的时候,一定是x64下面的目录,而不是x86下面的目录,这一点很容易混肴的。 4、设置静态库的链接 除了头文件的编译之外,opencv静态库链接也是非常需要的。不然的话,代码即使编译通过了,最后也会链接不过的。所以,还要在x64环境下选择静态库的链接地址, 5、修改main.cpp代码 main.cpp代码其实比较简单。首先注释掉原来所有代码,接着就是创建一个Mat的image,在二值化之后通过QImage转成QPixmap,最后把QPixmap贴到一个label标签上。有了前面的头文件和lib文件,这边编译应该没有什么问题了。 #include <QtWidgets/QApplication> #include <opencv2/opencv.hpp> #include <QImage> #include <QPixmap> #include <QLabel> int main(int argc, char *argv[]) { QApplication a(argc, argv); // 读取图像 cv::Mat originalImage = cv::imread("lena.png"); // 将图像灰度化 cv::Mat grayImage; cv::cvtColor(originalImage, grayImage, cv::COLOR_BGR2GRAY); // 将灰度图像进行二值化处理 cv::Mat binaryImage; cv::threshold(grayImage, binaryImage, 128, 255, cv::THRESH_BINARY); // 将OpenCV二值化图像转换为Qt图像 QImage qImage(binaryImage.data, binaryImage.cols, binaryImage.rows, binaryImage.step, QImage::Format_Grayscale8); QPixmap pixmap = QPixmap::fromImage(qImage); // 在Qt界面中显示二值化图像 QLabel label; label.

简易机器学习笔记(九)LeNet实例 - 在眼疾识别数据集iChallenge-PM上的应用

前言 上一节大概讲了一下LeNet的内容,这一章就直接来用,实际上用一下LeNet来进行训练和分类试试。 调用的数据集: https://aistudio.baidu.com/datasetdetail/19065 说明: 如今近视已经成为困扰人们健康的一项全球性负担,在近视人群中,有超过35%的人患有重度近视。近视会拉长眼睛的光轴,也可能引起视网膜或者络网膜的病变。随着近视度数的不断加深,高度近视有可能引发病理性病变,这将会导致以下几种症状:视网膜或者络网膜发生退化、视盘区域萎缩、漆裂样纹损害、Fuchs斑等。因此,及早发现近视患者眼睛的病变并采取治疗,显得非常重要。 数据集实际上用了这么几个部分: 其中DATADIR目录下的图片都是以下形式: 其中照片的成分是按照文件的名称来进行区分的,当其命名规则为P开头的,则代表其为病理性近视,N开头的为正常眼睛,而H开头的则代表为高度近视。 我们将病理性患者的图片作为正样本,标签为1; 非病理性患者的图片作为负样本,标签为0。从数据集中选取两张图片,通过LeNet提取特征,构建分类器,对正负样本进行分类,并将图片显示出来。 流程 正式开始之前,我们还是要将任务按照流程划分 我们在这次开发中,不仅要训练模型,计算Loss,还需要用数据集对成果进行准确性分析。 定义数据读取器 定义LeNet模型 编写训练过程 定义评估过程 进行模型计算 实际开发 定义数据读取器 我们需要读取两部分数据,分别是训练集和评估集,这两个集是分开的 首先我们需要进行一个预处理部分: # 对读入的图像数据进行预处理 def transform_img(img): # 将图片尺寸缩放道 224x224 img = cv2.resize(img, (224, 224)) # 读入的图像数据格式是[H, W, C] # 使用转置操作将其变成[C, H, W] img = np.transpose(img, (2,0,1)) img = img.astype('float32') # 将数据范围调整到[-1.0, 1.0]之间 img = img / 255. img = img * 2.0 - 1.0 return img 定义一个训练集数据读取器 类似之前的,我们需要将训练集划分batch,还需要将其打乱进行。

SpringBoot整合sentinel

1、引入依赖 <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> 2、 配置文件添加 spring: cloud: sentinel: transport: dashboard: ip:8858 项目重启,重启之后项目会和sentinel控制台关联,但是需要本地项目有访问之后,才能有数据监控。 补充一下,避坑: 如果是本地的项目,本地启动的话,还是下载jar包在本地终端启动吧,因为docker服务器中安装后,sentinel没办法回调本地服务,所以没办法监控,虽然你可以注册上去,但是却没办法用,难受。 如果你现在的sentinel控制台的jar包在终端报错,我建议你新开一个idea页面,在idea里面启动,就没有那么多问题了:

threejs在透视相机模式下,绘制像素大小固定的元素

要求:在透视相机模式下绘制一个图标,图标大小始终为32*32px。图标如下: 实现思路: 使用THREE.Sprite。因为 SpriteMaterial 支持配置 sizeAttenuation 使Sprite大小不随相机的深度而衰减。所以我们只要保证sprite的初始的大小合适,在以后的相机深度变化的时候就不会改变大小了。 开始操作 第一次的操作: drawAddSprite(type: InterActiveType = InterActiveType.Default) { // 这个sprite我是自己用canvas画出来的,比较简单,就不贴了 const texture = generateAddIconCanvasTexture(type); const material = new THREE.SpriteMaterial({ map: texture, sizeAttenuation: false }); material.map.colorSpace = 'srgb'; const sprite = new THREE.Sprite(material); scene.add(sprite) } 我们看一下效果 我设置sizeAttenuation: false之前,我以为这个图标会占满屏(高度上满屏),毕竟这个图标跟相机没关系了。但是并没有。后来意识到sizeAttenuation: false 只是设置了相机的深度跟Sprite没有关系,但是透视相机的fov还是会影响到sprite的大小的。我们去验证一下,当我不断修改相机的fov时,图标随着fov的增大而减小。 思路: 1. 第一步,我们找到一个fov值,在这个值下,我们看到的图标是占满屏幕的 2. 在第一步的fov值下,我们要求图标大小是32*32的,那只需要设置Sprite的scale为 32 / canvas.clientHeight 我们来实现一下上面的思路: 1. 我们来找这个fov 这个d就是相机的深度,既然设置了 sizeAttenuation: false,sprite不随相机的深度变化而变化,那这个d就要有一个默认值。我盲猜这个默认值是1。那这个fov的值计算如下 Math.atan(0.5) * 180 / Math.PI * 2 这个值经过计算是53.13010235415598 现在我们设置相机fov为这个值去看一下效果 果然是满屏的。所以这个d确实是1.

URLConnection()和openStream()两个方法产生SSRF的原理和修复方法

今年是自主研发的第三个年份,也是重视安全的年份。 转一篇小文章: 0x00 前言 SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定 URL 地址获取网页文本内容,加载指定地址的图片,下载等等。这里主要介绍java中URLConnection()和openStream()两个方法产生SSRF的原理和修复方法 0x01 URLConnection @RequestMapping(value = "/urlConnection/vuln", method = {RequestMethod.POST, RequestMethod.GET}) public String URLConnectionVuln(String url) { return HttpUtils.URLConnection(url); } 这里调用的是HttpUtils.URLConnection(url) public static String URLConnection(String url) { try { URL u = new URL(url); URLConnection urlConnection = u.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); //send request // BufferedReader in = new BufferedReader(new InputStreamReader(u.openConnection().getInputStream())); String inputLine; StringBuilder html = new StringBuilder(); while ((inputLine = in.readLine()) !

判断一个数是否是素数?并使用proxy检测该函数的性能

1、什么是素数 质数(prime number)又称素数,有无限个。 一个大于1的自然数,除了1和它本身外,不能被其他自然数整除 换句话说,就是这个数除了 1 和它本身以外不再有其他的因数;否则称为合数。 2、编程 // 判断一个数是否是素数 function isPrime(number) { if (number < 2) return true; for (let i = 2; i < number; i++) { if (number % i === 0) return false; } return true; } console.log(isPrime(1)); // true console.log(isPrime(2)); // true console.log(isPrime(8)); // false console.log(isPrime(12997)); // false 3、使用 proxy 检测该函数的性能 // 判断一个数是否是素数 function isPrime(number) { if (number < 2) return true; for (let i = 2; i < number; i++) { if (number % i === 0) return false; } return true; } let isPrimeProxy = new Proxy(isPrime, { apply: (target, thisArg, args) => { console.

2023 IoTDB Summit:宝武智维技术中心副主任赵刚《宝武集团设备智能运维超大规模分布式数据湖建设探索》...

12 月 3 日,2023 IoTDB 用户大会在北京成功举行,收获强烈反响。本次峰会汇集了超 20 位大咖嘉宾带来工业互联网行业、技术、应用方向的精彩议题,多位学术泰斗、企业代表、开发者,深度分享了工业物联网时序数据库 IoTDB 的技术创新、应用效果,与各行业标杆用户的落地实践、解决方案,并共同探讨时序数据管理领域的行业趋势。 我们邀请到宝武装备智能科技有限公司技术中心副主任赵刚参加此次大会,并做主题报告——《宝武集团设备智能运维超大规模分布式数据湖建设探索》。以下为内容全文。 目录 简介 痛点 方案 展望 大家好,今天我分享的题目是宝武集团在设备智能运维超大规模分布式数据湖建设的一个探索。我们公司和 IoTDB,实际上应该是在去年的时候,我们也是进行了一次全面的技术的对比,然后在 2023 年是全面的一个融合。 01 简介 我们公司全称是叫宝武装备智能科技有限公司,简称叫宝武智维。我们公司大概有 8000 人,是整个宝武集团设备智能运维专业化的一个平台化公司,我们的前身是宝钢检测和宝钢检修,这么一家公司。因为宝武集团这几年不断地在做吸收兼并,规模不断地扩大,那么公司跟着宝武集团的这么一个壮大的过程,我们也在不断地成长。我们的愿景是做产业生态圈智能运维的主体平台,我们的使命是为用户提供稳定可靠、智能高效的设备运行保障,我们的定位是中国宝武设备智能运维专业化平台公司,打造第三方的智能运维平台。 这是我们的一个拳头产品,我们把它叫宝武智维云。目前,宝武集团大概有接近 20 家的生产基地,已经全面覆盖了,就是它在我们每个基地都会部署一个设备智能运维的平台,负责将基地内的所有设备来接入其中,进行在线状态监测和一些智能运维业务。这个图中我们可以看出,我们是目前已经覆盖了 21 大基地,部署了有 27 个子平台,接入了 60 万以上的设备、240 万的数据项,总数据量超过了 5 个 PB。在平台上我们部署的这种具体规则超过 10 万条,我们现在已经沉淀下来的这种智能模型超过 40 大类,平台用户数超过了 1 万。 02 痛点 我们在全面的接入 IoTDB 之前,其实已经经过了多年的探索,在 2016 年的时候,宝武智维已经在开始这方面的探索了。我们之前的系统架构是,大家可以看右下角这个,我们实际上还是基于 Hadoop 的 HBase,上面用的是 OpenTSDB。应该说在初期,还是帮助我们的业务做到了非常好的一个效果,但是随着数据量的接入之后,现在慢慢的成为了制约我们企业发展的一个底层的瓶颈。 主要体现在两方面,一个是慢,包括什么呢?就是写入慢,常规的时候,正常情况下,可能勉勉强强。因为我们在每个基地的这个资源,也不可能说是在云上那么地丰富,所以说它的整个性能指标也是一个很一般的指标。特别是碰到比如网络断线的时候,大量的消息、数据堵塞之后,要快速的消费,但是后来大家就很心急,就看着那个消费的速度非常慢。 还有一个是查询慢,查询这个事情应该说还是非常影响用户使用效果的,对吧?我们那么多数据,有跨度为一年的,要快速的、要秒级的响应,这个基本上现在我们的平台上数据量之后,就是在未切换之前,基本上都是到 5 秒、10 秒、甚至半分钟才能刷出来,这个基本上就成为我们被诟病的很大的一点。 还有一个是加工慢。基于 OpenTSDB,要做各种各样的数据加工,包括聚合函数,这个里面的速度也是非常的慢,而且很容易导致整个数据架构的不稳定。 抽取也慢,当我们做这个数据资产的聚合的时候,我们不断地要往集团抽数据的时候,也发现这个瓶颈。在抽取的过程当中,一个是慢,另外一个对整个系统架构,它的这个稳定性的影响也比较大。 另一方面就是难。刚才讲了,一个是数据的汇聚难,还有一个是数据的清理难。因为大家知道基于 HBase 的这个数据清理,它非常的不灵活,我们基本上用一些 TTL 这种方式来进行一种删减,很麻烦。像我们有些数据给它定好,这个磁盘快爆了,然后我们必须还要写程序导出这部分数据,全部干掉,然后再导回去,所以这很多事情在我们运维上也是带来很大的痛苦。 还有备份难。我们一般做的是 3 节点的一个集群,那么这么大的一个体量之后,我们要备份,特别是策略化备份,非常困难,基本上就没有备份了,我们就是一个 3 节点的集群,来响应这个需求。

2172. Dinic/ISAP求最大流 (Dinic算法)

2172. Dinic/ISAP求最大流 - AcWing题库 给定一个包含 n 个点 m 条边的有向图,并给定每条边的容量,边的容量非负。 图中可能存在重边和自环。求从点 S 到点 T 的最大流。 输入格式 第一行包含四个整数 n,m,S,T。 接下来 m 行,每行三个整数 u,v,c,表示从点 u 到点 v 存在一条有向边,容量为 c。 点的编号从 1 到 n。 输出格式 输出点 S 到点 T 的最大流。 如果从点 S 无法到达点 T 则输出 0。 数据范围 2≤n≤10000 1≤m≤100000 0≤c≤10000 S≠T 输入样例: 7 14 1 7 1 2 5 1 3 6 1 4 5 2 3 2 2 5 3 3 2 2 3 4 3 3 5 3 3 6 7 4 6 5 5 6 1 6 5 1 5 7 8 6 7 7 输出样例: 14 解析: AcWing 2172.

汽车零部件开发需求与架构关系解析

经常有朋友同事问我汽车零部件开发中系统需求和软件需求,系统架构,软件架构之间的关系,应该怎么理解,实际开发中又怎么去操作,下图是我个人在多年工作中的一些感悟,整理成图,希望对大家有帮助,后续还会整理更多方法论的知识,放在专栏里,欢迎大家订阅专栏,一起讨论,共同进步。

LESS 和 SCSS 的区别

LESS 和 SCSS 的区别 相同点: LESS和SCSS都是css的预处理器,可以拥有变量,运算,继承,嵌套的功能,使用两者可以使代码更加的便于阅读和维护。都可以通过自带的插件,转成相对应的css文件。都可以参数混入,可以传递参数的class,就像函数一样嵌套的规则相同,都是class嵌套class 不同点: 声明和使用变量 LESS用@符号,SCSS用$符号表示 示范: @link-color:#632bca $to-color:#632bca .main{ color:@link-color //#632bca颜色LESS background-color:$to-color //#632bca颜色SCSS } 变量插值 LESS采用@{XXXX}的形式,SCSS采用${XXXX}的形式 作用: 可以用为LESS和SCSS声明变量,变量作为css的选择器 示范: LESS: @main-top : search; .@{ main-top } { font-size : 24px; color : #fff; } // 是用LESS,定义类,类选择器选中search标签,给其设置css样式 SCSS: $main-top : search; .@{ main-top } { font-size : 24px; color : #fff; } // 是用scss,定义类,类选择器选中search标签,给其设置css样式 SCSS支持条件语句,LESS不支持 SCSS可以使用if{}else,for循环等等,LESS不支持 示范: /* Sample Sass “if” statement */ @if lightness($color) > 30% { } @else { } /* Sample Sass “for” loop */ @for $i from 1 to 10 { .

vue前端常用工具类汇总

总结的工具类,可直接复用 utils文件夹中的util.js编写公共工具类 const initUtil = {} Byte 转 KB/MB/GB initUtil.getfilesize = (size = 0,) => { if (!size) return '0.00GB'; const num = 1000.00; //byte if (size < num) return size + "B"; if (size < Math.pow(num, 2)) return (size / num).toFixed(2) + "KB"; //kb if (size < Math.pow(num, 3)) return (size / Math.pow(num, 2)).toFixed(2) + "MB"; //M if (size < Math.pow(num, 4)) return (size / Math.pow(num, 3)).toFixed(2) + "

记模型训练损失为NAN

前段时间想把我模型的输入由DWT子带改为分块的图像块,一顿魔改后,模型跑着跑着损失就朝着奇怪的方向跑去了:要么突然增大,要么变为NAN。 为什么训练损失会突然变为NAN呢?这个作者将模型训练过程中loss为NAN或INF的原因解释得好好详尽(感谢):Pytorch训练模型损失Loss为Nan或者无穷大(INF)原因_pytorch loss nan-CSDN博客https://blog.csdn.net/ytusdc/article/details/122321907 我经过输入几番输入打印测试,确认我的输入确实没有问题,那么问题只能出现在模型的前向传播或者反向梯度传播过程中。我跟着这个作者的排查思路,最终定位问题出在梯度反向传播上,于是通过梯度剪裁成功解决NAN问题(我还增大了batch_size的大小,输入修改后,我发现模型运算量减小了,显存支持我每个step跑更大的batch_size了)。pytorch训练过程中出现nan的排查思路_torch判断nan-CSDN博客https://blog.csdn.net/mch2869253130/article/details/111034068修改部分: if mode == 'train': # # 1.debug loss # assert torch.isnan(total_loss).sum() == 0, print(total_loss) total_loss.backward() # # 2. 如果loss不是nan,那么说明forward过程没问题,可能是梯度爆炸,所以用梯度裁剪试试 nn.utils.clip_grad_norm(net.parameters(), max_norm=3, norm_type=2) optim.step() optim.zero_grad() 梯度剪裁: 对超出值域范围的梯度进行约束,避免梯度持续大于1,造成梯度爆炸。(没办法规避梯度消失) torch.nn.utils.clip_grad_norm_(parameters, max_norm, norm_type) parameters参数是需要进行梯度裁剪的参数列表。通常是模型的参数列表,即model.parameters();max_norm参数可以理解为梯度(默认是L2 范数)范数的最大阈值;norm_type参数可以理解为指定范数的类型,比如norm_type=1 表示使用L1 范数,norm_type=2 表示使用L2 范数。 【Pytorch】梯度裁剪——torch.nn.utils.clip_grad_norm_的原理及计算过程-CSDN博客https://blog.csdn.net/m0_46412065/article/details/131396098?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170435889016800215059432%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170435889016800215059432&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-131396098-null-null.142^v99^pc_search_result_base7&utm_term=%E6%A2%AF%E5%BA%A6%E5%89%AA%E8%A3%81&spm=1018.2226.3001.4187

Nginx(一)概述

1 概述 Nginx (engine x) 是一个轻量级的高性能的 HTTP 和反向代理 web 服务器,同时也提供了 IMAP/POP3/SMTP邮件服务。Nginx 是由伊戈尔·赛索耶夫为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本0.1.0 发布于 2004 年 10 月 4 日。 Nginx 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行,其特点是占有内存少,并发能力强。 备注:'web服务器'和'应用服务器'的区别-->前者是'静态'、后者是'动态' web服务器:nginx、apache、openrestry 应用服务器:tomcat、weblogic'收费'、jetty、Jboss ​2 工作模式 nginx 有两种工作模式:master-worker 模式和单进程模式 在 master-worker 模式下:有一个 master 进程和至少一个的 worker 进程 单进程模式:顾名思义只有一个进程 这两种模式有各自的特点和适用场景 master-worker:该模式下,nginx 启动成功后,会有一个 master 进程和至少一个的 worker 进程。 master '进程负责处理系统信号(control)',加载配置,管理 worker 进程(启动、杀死、监控、发送消息/信号等)。 worker '进程负责处理具体的业务逻辑',也就是说,对外部来说,真正提供服务的是 worker 进程 这种模式有以下优点 1. 稳定性高,只要还有 worker 进程存活,就能够提供服务,并且一个 worker 进程挂掉 master 进程会立即启动一个新的 worker 进程,保证 worker 进程数量不变,降低服务中断的概率。 2.

手把手教你实现:将后端SpringBoot项目部署到华为云服务器上

前言 前提:有一个后端项目,项目能够运行在本地,可以通过本地访问(localhost) 如果没有可以看这篇:一个基于SpringBoot的后端项目 注册华为云账号 华为云官网 购买云服务器 产品 -> 华为云耀云服务器L实例 或者 ESC弹性云服务器-> 购买 有免费试用的,也有包年的,也有三个月的,具体容量、带宽参数根据自己的需求(挑最便宜的)来定。 配置服务器环境 其实所谓的服务器就是 一台 远程的电脑主机,当你购买后,会给你一个账号和密码,让你通过远程登录去操作这台主机。 我们需要在这台主机上配置好项目运行的基本环境,如 JDK、Mysql数据库等。 然后只需要将项目编译打包成jar文件,并上传布置到 这台主机,运行启动即可。 登录服务器 根据购买提供的账号远程登录云主机。 登录后,你就可以看到一个黑乎乎的屏幕: 注意了: 如果你购买的是《云耀云服务器实例L》,那么是没有左侧的文件目录管理的,以及FTP上传功能,那么你需要借助第三方的工具才能看到 这里我推荐如下: 你的电脑是Windows, 那么推荐你使用 Xshell 你的电脑是Mac,那么推荐你使用 FinalShell. 配置JAVA SDK 21 先查看云服务器的主机类型,一般来说是购买的云主机都是 Linux操作系统 入口为华为云官网: 控制台 -> 我的资源 ->云服务器 下载Java Sdk 21: Java JDK 官网 找到和你云主机类型符合的包,比如这个: 下载后,在云主机上找到,opt文件夹,新建一个文件夹叫jdk, 然后将 下载的JDK上传到这个目录。 解压JDK 输入命令: 进入这个目录 # cd /opt/jdk 查看目录的文件 # ls 解压 # tar -zxvf jdk-21_linux-x64_bin.tar.gz 配置java home路径 # cd / # sudo vim /etc/profile 按下 键盘 “i” 键, 在后面新增以下内容:

第三章——语言基础(下)操作符、语句、函数

3.5 操作符 ECMA-262描述了一组可用于操作数据值的操作符,包括数学操作符(如加、减)、位操作符、关系操作符和相等操作符等。ECMAScript中的操作符是独特的,因为它们可用于各种值,包括字符串、数值、布尔值,甚至还有对象。在应用给对象时,操作符通常会调用valueOf()和/或toString()方法来取得可以计算的值。 3.5.1 一元操作符 只操作一个值的操作符叫一元操作符(unary operator)。一元操作符是ECMAScript中最简单的操作符。 1、递增/递减操作符 递增和递减操作符直接照搬自C语言,但有两个版本:前缀版和后缀版。顾名思义,前缀版就是位于要操作的变量前头,后缀版就是位于要操作的变量后头。前缀递增操作符会给数值加1,把两个加号(++)放到变量前头即可: let age = 29; ++age; 在这个例子中,前缀递增操作符把age的值变成了30(给之前的值29加1)。因此,它实际上等于如下表达式: let age = 29; age = age + 1; 前缀递减操作符也类似,只不过是从一个数值减1。使用前缀递减操作符,只要把两个减号(--)放到变量前头即可: let age = 29; --age; 执行操作后,变量age的值变成了28(从29减1)。无论使用前缀递增还是前缀递减操作符,变量的值都会在语句被求值之前改变。(在计算机科学中,这通常被称为具有副作用。)请看下面的例子: let age = 29; let anotherAge = --age + 2; console.log(age); // 28 console.log(anotherAge); // 30 在这个例子中,变量anotherAge以age减1后的值再加2进行初始化。因为递减操作先发生,所以age的值先变成28,然后再加2,结果是30。 前缀递增和递减在语句中的优先级是相等的,因此会从左到右依次求值。比如: let num1 = 2; let num2 = 20; let num3 = --num1 + num2; let num4 = num1 + num2; console.

okhttp网络请求工具

先依赖 implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0' implementation 'com.google.code.gson:gson:2.8.0' import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.util.Log; import android.widget.Toast; import com.artvrpro.yiwei.MyApplication; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.FileNameMap; import java.net.URLConnection; import java.util.Iterator; import java.util.Map; import java.util.concurrent.TimeUnit; import okhttp3.Call; import okhttp3.Callback; import okhttp3.FormBody; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; /** * *okhttp网络请求工具 * * */ public class HttpUtils { private static OkHttpClient client = null; private HttpUtils() { } public static OkHttpClient getInstance() { if (client == null) { synchronized (HttpUtils.

Spring Boot整合Spring Security:构建安全的Web应用

文章目录 1. 添加依赖2. 配置Spring Security3. 创建用户服务4. 控制器和视图5. 运行应用 🎈个人主页:程序员 小侯 🎐CSDN新晋作者 🎉欢迎 👍点赞✍评论⭐收藏 ✨收录专栏:Java框架 ✨文章内容:构建安全的Web应用 🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!🤗 Spring Security是一个强大的身份验证和访问控制框架,用于保护Spring应用程序。它提供了全面的安全服务,包括身份验证、授权、攻击防护等。本文将介绍如何在Spring Boot应用程序中整合Spring Security,以构建一个安全可靠的Web应用。 1. 添加依赖 首先,需要在pom.xml文件中添加Spring Security的依赖: <dependencies> <!-- Spring Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- 其他依赖... --> </dependencies> 2. 配置Spring Security 在Spring Boot应用程序中,可以通过创建一个配置类来配置Spring Security。创建一个类,并添加@EnableWebSecurity注解,继承WebSecurityConfigurerAdapter类: import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .

如何把文件名导入excel?

&nbsp; &nbsp; 如何把文件名导入excel?在进行今天的分享之前,我要问大家一个问题,为什么要将文件名导入到excel表格里呢?首先导入Excel可以创建一个文件清单或目录,以便更方便地查看和管理大量文件。在Excel中,你可以使用筛选、排序和搜索功能来快速找到需要的文件,而不必一个个进行手动查找。如果你需要对文件进行数据分析或生成报告,将文件名导入Excel可以使数据处理更加方便和灵活。你可以使用Excel的各种函数、公式和图表功能来分析文件名的特征、统计文件数量等信息,从而得出结论并生成相应的报告。 &nbsp;&nbsp;&nbsp;那么用什么方法可以一次性的快速的将大量文件的名称导入excel表格里面呢?今天小编将为大家介绍两个方法,第一个方法我们将使用一个文件名提取软件来完成,第二个方法将使用命令的方式进行导入,每个方法都有比较详细的步骤,感兴趣可以看一看哦。 方法一:使用文件名提取软件进行操作 &nbsp;&nbsp;&nbsp;&nbsp;这个方法中我们将使用“优速文件名提取器”来完成,从软件的名称我们便能知道这是一个专门提取文件名的软件,不管什么文件的名称都能提取,不仅可以提取到excel里,还可以提取到txt和word文档里。 步骤1,我们提前将用到的“优速文件名提取器”软件工具下载和安装,打开之后直接点击左上角【添加文件】按钮,将需要文件一次性导入到软件里,导入成功后文件名会在软件中看到。 步骤2,因为要将所有文件名导入到excel里,因此在导出格式右边下拉框中选择“xlsx”。下面几个参数根据大家的需要自行进行选择或者设置。 &nbsp; 步骤3,点击软件右上角的【开始提取】红色按钮启动软件,提取完成后软件会自动打开输出文件夹,可以看到包含所有文件名的excel导出文件保存在这里。 &nbsp; 步骤4,打开excel文件并进行检查,通过下图可以看到,所有文件的名称按照顺序依次导入到了excel表格的第一类里,效果非常的不错。 &nbsp; 方法二:用命令将文件名导入excel &nbsp;&nbsp;要用命令将文件名导入Excel,你可以使用命令行工具(如PowerShell或命令提示符)结合一些命令来实现。以下是一种常见的方法: ① 打开命令行工具(如PowerShell或命令提示符)。 ② 进入包含要导出文件名的目录,可以使用cd命令切换到相应目录。 ③ 运行以下命令来将文件名导入到文本文件中: &nbsp;&nbsp;dir /b > filenames.txt &nbsp;&nbsp;这将列出当前目录中所有文件的文件名,并将结果输出到一个名为filenames.txt的文本文件中。 ④ 打开Excel软件,并在空白工作表中选择"数据"选项卡。 ⑤ 在"获取外部数据"组中,选择"从文本"选项。 ⑥ 在弹出的导入向导中,选择刚才生成的filenames.txt文件并点击"导入"。 ⑦ 在导入向导的下一步中,选择适当的分隔符选项(如Tab或逗号),然后点击"下一步"。 ⑧ 在下一个界面中,选择将数据导入到现有工作表中或创建新的工作表,然后点击"完成"。 ⑨ Excel将导入文本文件中的文件名,并显示在你选择的工作表中。 &nbsp; &nbsp;&nbsp;将文件名导入Excel后,你可以利用Excel的强大计算和文本处理功能来批量重命名文件、批量修改文件属性、批量移动文件等。通过编写Excel宏或使用VBA脚本,你可以根据自己的需求进行灵活的批量操作。总之,将文件名导入Excel可以提供更方便和灵活的文件管理、数据分析和批量操作功能,使文件处理更加高效和可控。今天小编为大家介绍了两个“如何把文件名导入excel?”的方法,非常的详细,希望可以帮助到有需要的小伙伴。

【Storm实战】1.2 图解Storm的架构及其组件

文章目录 0. 前言1. 图解架构及其组件2. Storm的主要架构组件 0. 前言 上一章节,我们为了好理解,将storm中的抽象概念 通过画了一个水力发电系统的工作模式,相信大家一定可以直观地理解Storm中的流 (Stream) 、拓扑 (Topology)、Spout、Bolt、任务(Task)和工作者 (Worker)是如何协同工作处理数据的。 我们将流 (Stream) 比作河流,拓扑 (Topology)想象成是一个水力发电系统,Spout可以视为水力发电系统中的水轮机,它不断从河流(外部数据源)中截取水流。 Bolt就像是沿着水轮机的齿轮和发动机,它们接收从水轮机传来的动力(元组tuple),执行各种操作(处理数据),比如研磨谷物或发电。在Storm中,Bolts可以执行多种数据转换操作,如过滤、聚合、写入数据库等。 任务(Task)可以想象成是工人在水轮机和发电机之间的每个环节上工作。如果这个系统需要处理更多的水流(数据),我们就需要更多的工人(任务)。 在Storm中,增加任务的数量可以提高系统处理数据的能力。工作者 (Worker)看作是整个水力发电系统的工作站或工厂。在这些工作站里,每个工人(任务)负责操作一套齿轮与发动机(执行Spout和Bolt的逻辑)。工厂越多,系统的处理能力就越强。在Storm中,我们可以增加工作者(进程)的数量来扩展拓扑的处理能力。 1. 图解架构及其组件 本章节,我们着重来看下Storm的架构及其组件。还是老样子,我们以类比图解的方式讲解,我画了一个图, 我们想象一下一个水电站系统,这个系统的任务是利用水流来发电。在这个类比中, Storm的架构及其组件可以借助上面的图这样理解 Nimbus(控制中心):这就像是水电站的控制室,负责监控整个系统的运行,确保所有的水轮机(Spout)和发电机(Bolt)正常工作。如果某个设备出了问题,控制中心会及时派出人员去修理或替换。 Supervisor(转换站):这就像是电站的变压器,接收来自控制中心的指令并确保电力(任务)送到正确的地点。 Worker进程(发电机组):每个Worker就是一个包含多台发电机的发电机组,实际上转动产生电力。在Storm中,Worker进程运行在JVM中,执行实际的处理任务。 Task(单独的发电机):每个发电机都是发电机组的一部分,负责生成电力。在Storm中,每个任务都是处理流数据的最小工作单元。 Topology(发电网络):整个发电站的电网,确保电力能够从水流经过各种设备最终供到用户。Storm中的拓扑定义了数据流向和处理的逻辑结构。 Stream(水流):水电站中的水流就像Storm中流动的数据,水流的动力是发电的来源。 Spout(水轮机):水轮机是起始点,它抓住水流的动力并开始转化为电能。在Storm中,Spout从外部数据源捕获数据,生成元组流,是数据流开始的地方。 Bolt(发电机):发电机负责接收水轮机的动力并转换成电能。在Storm中,Bolt会处理Spout发送的元组,执行计算操作,可能还会将结果发送到下一个Bolt或存储起来。 通过这个类比,你可以更容易地理解Storm的组件是如何协同工作的,以及它们在数据处理流程中各自扮演的角色。 2. Storm的主要架构组件 Nimbus:这是Storm集群的主节点,负责分发代码,分配任务给Supervisor,监视失败的任务并重新分配。 Supervisor:运行在各工作节点上,负责接收从Nimbus分配的任务,然后把任务分配给这个节点的Worker进程。 Worker进程:运行在Supervisor节点下,负责执行具体的任务。每个任务都会运行在一个单独的JVM进程中。 Task:实际运行的工作单元,一个Worker进程可以运行一个或者多个Task。 Topology:Storm中处理逻辑的封装。 Stream:数据流,Storm中的主要数据结构,由多个tuple组成。 Spout:数据源,负责从数据源获取数据,转换为tuple发送给Bolt。 Bolt:数据处理的主要组件,可以接收数据、处理数据以及发送数据。 Storm的架构设计得非常合理,可以适应各种规模的实时处理任务,从而在大数据处理领域得到了广泛应用。

【Storm实战】1.1 图解Storm的抽象概念

文章目录 0. 前言1. Storm 中的抽象概念1.1 流 (Stream)1.2 拓扑 (Topology)1.3 Spout1.4 Bolt1.5 任务 (Task)1.6 工作者 (Worker) 2. 形象的理解Storm的抽象概念2.1 流 (Stream)2.2 拓扑 (Topology)2.3 Spout2.4 Bolt2.5 任务 (Task)2.6 工作者 (Worker)场景1场景2 3.参考文档 0. 前言 Storm 是一个分布式实时计算系统,用于处理大规模流式数据。它基于流处理模型,可以在一个分布式集群上运行,实时地处理和分析数据。Storm 提供了高可靠性、高吞吐量的数据流处理能力,可用于构建实时大数据分析应用和实时流处理任务。 在学习和使用 Storm 之前,我们需要对一些抽象概念有基本的了解。这些抽象概念包括流、拓扑、Spout、Bolt、任务和工作者。流是数据处理的基本单位,可以理解为一个无限的有序的元组序列。拓扑是一个由 Spout 和 Bolt 组成的数据流处理网络,定义了数据流从源头到最终目的地的路径。Spout 是数据源头,负责从外部源读取数据并封装成流。Bolt 是数据处理单元,负责接收输入流并进行处理。任务是在执行拓扑时运行在工作进程中的实际执行实例,每个 Spout 和 Bolt 组件可以配置为多个任务来实现并行处理。工作者是 Storm 运行在集群节点上的进程,可以执行一个或多个任务。 为了更好地理解这些抽象概念,可以将其类比为水力发电或水力传动系统。在这个类比中,流就像是河流,拓扑就像是水力发电系统,Spout 就像是水轮机,Bolt 就像是齿轮和发电机,任务就像是工人,工作者就像是工作站。 1. Storm 中的抽象概念 在学习Storm 之前,我们需要对Storm中的抽象概念有个基本的认识。方便我们后面写DEMO示例。 图片来源官方文档https://storm.apache.org/releases/2.6.0/Concepts.html 1.1 流 (Stream) 流是Storm中数据处理的基本概念。一个流可以理解为一个无限的、有序的元组(tuple)序列。在Storm中,元组是数据的基本单位,它是一个可以包含多种数据类型的键值对列表。流是可以在拓扑中的各个组件之间传输的。 1.2 拓扑 (Topology) 拓扑是Storm中最顶层的抽象,它定义了数据流从源头到最终目的地的整个路径。在Storm中,拓扑是由一系列的spouts和bolts组成的网络。Spouts用于生成数据流,而bolts则用于处理流经它们的数据。一旦提交到集群,拓扑将会不断运行,直到被显式地终止。 1.3 Spout Spout是Storm拓扑中的数据源头,负责从外部源(如数据库、消息队列、文件系统等)读取数据并将其封装成流以供拓扑内的bolts处理。Spout可以发射多个流,并且能够对外部源的数据进行可靠或不可靠的读取。 1.4 Bolt Bolt是拓扑中的数据处理单元,它负责接收来自spout或其他bolt的输入流,并进行处理,这些处理可以包括过滤、聚合、连接、写数据库等操作。处理完成后,bolt可以发射新的流到拓扑中的其他bolt进一步处理,或者将结果输出到外部系统。

ubuntu ssh 免密

# 生成key ssh-keygen -t rsa # 拷贝秘钥 # ssh-copy-id username@remote_host ssh-copy-id fxbox@192.168.31.123

vscode中uniapp项目无法编译生成dist 也不报错的解决办法

就在昨天,我修改项目的代码UI部分后,执行「npm run dev:mp-weixin 」这个指令,开发工具中的页面没有任何变化,然后终端的输出如下图: 毫无提示,当下就觉得不对劲,果然在微信开发工具里面看到编译后的代码的部分还是修改之前的代码,然后手动删除了dist文件夹,重新运行了指令,还是不行。 折腾半天,依旧不行,决定新建个项目,把代码一点点拷到新项目中去。 在新建项目后,新项目本身是自带一些基础文件的,如package.json,manifest.json等。 先拷了package.json覆盖过去,此时执行指令还是可以的。然后又拷贝manifest.json覆盖,然后就报错了。我寻思这manifest.json我也没改啥啊,但是当我还原回项目自带的manifest.json后,一切又都好了。 气不过,找了文档对比工具看了一下,原来是我不小心在manifest.json中的mp-weixin下的一个属性的后面加了一个「 ,」👇 啊,就是这个逗号导致我查了半天的错查不出来,😤。 把逗号删除,项目又恢复正常了。 不过新建项目来排查原来项目中的不易察觉的bug,貌似也是个方法。

Vue3 自定义Hooks大全:一站式解决你的疑惑!

前言 不知道喜欢 vue3 的小伙伴和我是不是一样,刚上手vue3 的时候 对自定义hooks 一脸懵逼,在一些视频网站学习的时候老师讲解到自定义hooks 最喜欢用 加减乘除来描述 自定义hooks 是咋用的,可能是我理解能力比较差吧,我看了这个 加减乘除的自定义hooks 之后感觉跟没看一样,还是一脸懵逼,所以个人觉得这种知识还是结合项目或者业务来说才是比较能让人理解的。 但是平时开发的过程中却好像也不怎么需要自定义hooks ,那我们到底需不需要自定义hooks,又该如何学习自定义hooks 呢,首先先在这跟你说结论:自定义hooks 不是必须的 他只是为我们提供一种 逻辑复用 的方式,但是他有利于你复用逻辑 代码更简洁,那如何学?学习别人的思想啊!然后自己融汇贯通即可。 介绍 其实我们平常说的 自定义hooks 在vue3 官方说法叫组合式 API (Composition API) 组合式 API (Composition API) 是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件虽然这套 API 的风格是基于函数的组合,但组合式 API 并不是函数式编程。组合式 API 是以 Vue 中数据可变的、细粒度的响应性系统为基础的,而函数式编程通常强调数据不可组合式 API 最基本的优势是它使我们能够通过组合函数来实现更加简洁高效的逻辑复用。在选项式 API 中我们主要的逻辑复用机制是 mixins,而组合式 API 解决了 mixins 的所有缺陷 使用 平时我们 写自定义hooks 可能有两种 一种是 基于业务的 自定义hooks 只是为了单纯提取 可复用的逻辑 ,缺点是只能用在自己项目中一种是 可复用行强的 可在全局使用的 比如对于弹框、表格、表单等等的自定义hooks 基于业务封装的 hooks 最近我在开发低代码的项目 我在项目中得封装一套组件 看下面的伪代码:

CPU平台做视频智能分析,Lnton视频分析平台不仅支持流分析,同时也支持图片分析了

LntonAIServer最新v1.0.09版本支持图片分析了,经过几个月的研发,在原有的视频流分析的基础上,我们终于支持大家都非常期待的图片分析功能了,图片分析的功能加上,能有利于很多场景的展开,比如在烟火、明厨亮灶等场景,不需要做视频流分析,图片分析完全可以解决问题! 来看看这几个月我们都干了啥: 2023.12.27 V1.0.09 1、增加图片分析接口; 2、修正多区域布防时告警叠加问题; 3、切换了流后可能不分析的问题; 2023.12.21 V1.0.08 1、告警图片分类型存储; 2、修正通过API接口批量切换视频源后不分析的问题; 3、按需播放实时视频时,等待时长由2秒改为5秒; 4、更新算法模型; 2023.12.04 V1.0.07 1、建立资源分析池,对于分析频率大于5秒每帧的通道,将从分析资源池中获取分析资源进行分析,不占用独立的分析通道; 2023.11.27 V1.0.06 1、增加"未戴安全帽检测"、"车辆检测", 更新"烟火检测"、"抽烟检测"; 2023.11.24 V1.0.05 1、同一通道可同时开启多路算法,每路算法可分别设置分析频率和时间计划; 2、对于行为分析(抽烟、戴帽、戴口罩), 由输出目标信息改为输出相关事件信息; 2023.11.15 V1.0.04 1、按需输出编码流:当有客户端播放时才编码输出,不播放时不编码以节省资源; 2、加固对接时客户端传参的检查; 3、增加批量设置告警推送接口; 4、算法升级--烟火检测模型和行人检测模型; 5、全部为 ORT CPU 推理; 6、模型加密; 2023.11.08 V1.0.03 1、修正分析计划; 2、自动更新存储路径:当配置文件中设置的路径不存在时,自动指定为当前路径; 2023.11.06 V1.0.02 1、算法升级--烟火检测模型,样本版本v0.6; 2023.10.31 1、增加确认告警操作; 2023.10.24 1、增加告警图片展示; 2、增加调试开关: 输出告警图片对应的原图; 3、增加鉴权; 2023.10.23: 1、新增版本号与版本迭代日志; 2、新增算法服务接口文档; 2023.10.16: 1、ROI区域不在实时流中显示,由前端在视频框外叠加显示; 2、新增告警查询页面; 3、新增10s/帧、20s/帧、30s/帧、60s/帧的分析选项; 4、支持设置算法启用时间段,比如8:00~18:00; 5、算法设置选项中新增“重复告警过滤窗口时间”,比如1s、2s、10s; 6、解决算法分析卡顿的问题; 7、进一步优化算法CPU计算耗时;

Qualcomm® AI Engine Direct 使用手册(19)

Qualcomm® AI Engine Direct 使用手册(19) 6.4.3 qnn-accuracy-debugger(实验)6.4.4 qnn 平台验证器6.4.5 qnn-个人资料查看器6.4.6 qnn-上下文-二进制-实用程序 6.4.3 qnn-accuracy-debugger(实验) 依赖关系 精度调试器取决于设置中概述的设置。具体来说,需要满足以下条件:首先,需要根据平台依赖关系满足平台依赖关系。需要安装所需的 ML 框架。还必须遵循环境设置中的环境设置说明。 应使用安装程序中提到的 check-python-dependency 脚本来满足 Python 依赖关系。此外,还需要以下软件包: absl==0.0 flatbuffers==23.3.3 onnxruntime==1.14.1 protobuf==4.22.4 xlsxwriter==3.1.9 本指南中使用了以下环境变量(用户可以根据需要更改以下路径): RESOURCESPATH = {所有模型和输入文件所在目录的路径} PROJECTREPOPATH = {准确性调试器项目目录的路径} 概述 准确性调试器工具可以发现层级神经网络中的不准确性。该工具将通过特定机器学习框架(即 Tensorflow、Onnx、TFlite)运行模型所产生的黄金输出与通过高通 QNN 推理引擎运行相同模型所产生的结果进行比较。推理引擎可以在多种计算介质上运行,包括GPU、CPU和DSP。 Accuracy Debugger 提供以下功能。每个功能都可以使用相应的选项来运行;例如,。qnn-accuracy-debugger --{option} qnn-accuracy-debugger -–framework_diagnosis此功能使用机器学习框架(例如tensorflow、tflite 或onnx)来运行模型以获得中间输出。 qnn-accuracy-debugger –-inference_engine此功能使用 QNN 引擎运行模型以检索中间输出。 qnn-accuracy-debugger –-verification此功能使用 CosineSimilarity、RtolAtol 等验证器来比较框架诊断和推理引擎功能生成的输出。 qnn-accuracy-debugger –compare_encodings此功能从给定的 QNN net JSON 文件中提取编码,将它们与给定的 AIMET 编码进行比较,并输出突出显示不匹配的 Excel 工作表。 qnn-accuracy-debugger –tensor_inspection此功能将给定的目标输出与参考输出进行比较。 提示: 您可以在 bin 命令后使用 –help 来查看可以添加哪些其他选项(必需或可选)。

Linux启动tomcat

文章目录 1、启动tomcat1.1 ./startup.sh或者sh startup.sh----没有控制台信息,关闭cmd就停止服务1.2 nohup ./startup.sh &------------作为服务启动tomcat,关闭cmd也不影响1.3 ./catalina.sh run-------有控制台信息,关闭cmd就停止服务 2、停止服务查看实时运行日志yum安装tomcat 1、启动tomcat 1、先到tomcat的目录中,找到bin文件夹,查看文件夹内容 三种方式启动tomcat 方式一:直接启动 ./startup.sh 方式二:作为服务启动 nohup ./startup.sh & 方式三:控制台动态输出方式启动 ./catalina.sh run 动态地显示tomcat后台的控制台输出信息,Ctrl+C后退出并关闭服务 1.1 ./startup.sh或者sh startup.sh----没有控制台信息,关闭cmd就停止服务 sh startup.sh ./startup.sh 用以上命令启动tomcat时没有输出启动的信息,直接就是如下的结果,这个效果跟我们一般启动的时候不一样,看的有点懵,因为以前都是启动以后很多信息输出,结果这个是这样的,就没了,也不知道有没有成功。 尝试访问,发现一直在转圈,过一会才能访问成功,看来还是可以的,怎么用常见的那种方式启动呢,使用以下命令, ./catalina.sh run 1.2 nohup ./startup.sh &------------作为服务启动tomcat,关闭cmd也不影响 nohup ./startup.sh & 1.3 ./catalina.sh run-------有控制台信息,关闭cmd就停止服务 2、停止服务 ./shutdown.sh 查看实时运行日志 启动tomcat时候没有控制台,想要看实时的运行日志,进入到tomcat的log下,使用命令tail -f catalina.out就可以了,退出按Ctrl+c yum安装tomcat yum的方式安装tomcat yum install tomcat //或者 yum -y install tomcat 安装后的tomcat目录在/usr/share/tomcat 查看 可以使用命令查看状态 systemctl status tomcat.service //或者 systemctl status tomcat 访问tomcat默认地址:localhost:8080,成功

table的最后一行需要加底色

<tr class="font12" v-for="(item, index) in OrderAuditDiscountList.list" :key="index" :class="OrderAuditDiscountList.list.length - 1 == index ? 'blodfont' : ''"> 其中: :class="OrderAuditDiscountList.list.length - 1 == index ? 'blodfont' : ''" .blodfont { background: #FDF5F4; font-weight: bold; }

FFMPEG结构体分析:AVPacket

AVPacket是存储压缩编码数据相关信息的结构体 例如对于H.264来说。1个AVPacket的data通常对应一个NAL。【注意:此处强调是“通常”,不是“所有”】 注意:在这里只是对应,而不是一模一样。他们之间有微小的差别:使用FFMPEG类库分离出多媒体文件中的H.264码流 因此在使用FFMPEG进行视音频处理的时候,常常可以将得到的AVPacket的data数据直接写成文件,从而得到视音频的码流文件。【如果.h264码流文件不能直接播放,参考上述使用FFMPEG类库分离出多媒体文件中的H.264码流】 涉及到的知识点:使用FFMPEG类库分离出多媒体文件中的H.264码流 博客地址:https://blog.csdn.net/leixiaohua1020/article/details/11800877 雷神这篇文章的意思是说,在裸流前面需要sps和pps信息,否则解码器无法解码。另外每个nalu的头部需要替换为标准头部0001【每个nalu之间的分隔符】 代码验证: 分离signtl.ts文件中的h.264码流: #include <stdio.h> #include <libavformat/avformat.h> int main(int argc, char *argv[]) { av_register_all(); AVFormatContext *formatCtx = NULL; int videoStreamIndex = -1; // 打开多媒体文件 if (avformat_open_input(&formatCtx, "E:\\BDWP\\小学期课程资料 - 基于FFmpeg+SDL的视频播放器的制作\\工具\\testvideo\\sintel.ts", NULL, NULL) != 0) { fprintf(stderr, "无法打开文件\n"); return -1; } // 查找视频流 if (avformat_find_stream_info(formatCtx, NULL) < 0) { fprintf(stderr, "无法获取流信息\n"); return -1; } // 寻找视频流 for (int i = 0; i < formatCtx->nb_streams; i++) { if (formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && formatCtx->streams[i]->codec->codec_id == AV_CODEC_ID_H264) { videoStreamIndex = i; break; } } if (videoStreamIndex == -1) { fprintf(stderr, "

c++学习笔记-提高篇-STL-常用六大算法(遍历、查找、排序、拷贝和替换、算术生成、集合算法)

目录 概述 一、常用遍历算法 (1)for_each (2)transform 二、常用查找算法 (1)find (2)find_if (3)adjacent_find (4)binary_search (5)count (6)count_if 三、常用排序算法 (1)sort (2)random_shuffle (3)reverse (4)merge 四、常用拷贝和替换算法 (1)copy (2)replace (3)replace_if (4)swap 五、常用算数生成算法 (1)accumulate (2)fill 六、常用集合算法 (1)set_intersection (2)set_union (3)set_difference 概述 算法主要由头文件<algorithm><functional><numeric>组成<algorithm>是所有STL头文件中最大的一个,范围涉及到比较、交换、查找、遍历操作、复制、修改等<numeric>体积很小,只包括几个在序列上面简单数学运算的函数模版<functional>定义了一下模版类,用以声明函数对象 一、常用遍历算法 1、学习目标:掌握常用的遍历算法 2、算法简介: for_each //遍历容器transform //搬运容器到另一个容器 3、常用遍历算法 (1)for_each 功能描述:实现遍历容器函数原型: for_each(iterator beg, iterator end, _func); //beg 开始迭代器 //end 结束迭代器 //_func 函数或者函数对象 示例: #include<iostream> #include<algorithm> #include<vector> using namespace std; //普通函数 void print01(int val) { cout << val << " "; } //仿函数 class print02 { public: void operator()(int val) { cout << val <<"

yolov8人脸识别-脸部关键点检测(代码+原理)

YOLOv8 脸部识别是一个基于YOLOv8算法的人脸检测项目,旨在实现快速、准确地检测图像和视频中的人脸。该项目是对YOLOv8算法的扩展和优化,专门用于人脸检测任务。 YOLOv8是一种基于深度学习的目标检测算法,通过将目标检测问题转化为一个回归问题,可以实现实时的目标检测。YOLOv8 Face项目在YOLOv8的基础上进行了改进,使其更加适用于人脸检测。以下是YOLOv8 Face项目的一些特点和关键技术: 高准确性:YOLOv8 Face采用了一系列的优化策略,包括网络结构的设计、数据增强和训练技巧等,从而提高了模型的准确性。它能够精确地检测出各种不同姿态、光照和遮挡条件下的人脸。 实时性能:YOLOv8Face具有较高的实时性能,可以在实时图像和视频流中快速检测人脸。它采用了一种轻量级的网络结构和高效的推理算法,以实现实时的人脸检测。 多尺度检测:为了适应不同大小和尺度的人脸,YOLOv8 Face使用了多尺度检测技术。通过在不同尺度下进行检测,可以提高模型对小尺寸人脸的检测能力。 数据增强:YOLOv8 Face使用了各种数据增强技术,如随机裁剪、旋转和缩放等,以增加训练数据的多样性和丰富性。这有助于提高模型的泛化能力和鲁棒性。 高效推理:为了提高推理效率,YOLOv8 Face使用了一些优化技术,如模型压缩、量化和推理引擎的优化等。这使得模型可以在嵌入式设备和移动端实现快速的人脸检测。 代码运行 数据准备 下载WIDERFace数据集 从Google Drive下载注释文件 进入data文件夹 运行python3 train2yolo.py /path/to/original/widerface/train` [/path/to/save/widerface/train],将训练集转换为YOLOv5格式 运行python3 val2yolo.py /path/to/original/widerface [/path/to/save/widerface/val],将验证集转换为YOLOv5格式 训练 运行CUDA_VISIBLE_DEVICES="0,1,2,3" python3 train.py --data data/widerface.yaml --cfg models/yolov5s.yaml --weights 'pretrained models',进行训练 WIDERFace评估 进入widerface_evaluate文件夹运行python3 evaluation.py,进行评估 demo代码 运行下列demo示例,可以帮助我们推理出结果!!!!!!1 import argparse import time from pathlib import Path import cv2 import torch import torch.backends.cudnn as cudnn from numpy import random from models.experimental import attempt_load from utils.

深度学习 Day23——J3DenseNet算法实战与解析

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制🚀 文章来源:K同学的学习圈子 文章目录 前言1 我的环境2 pytorch实现DenseNet算法2.1 前期准备2.1.1 引入库2.1.2 设置GPU(如果设备上支持GPU就使用GPU,否则使用CPU)2.1.3 导入数据2.1.4 可视化数据2.1.4 图像数据变换2.1.4 划分数据集2.1.4 加载数据2.1.4 查看数据 2.2 搭建densenet121模型2.3 训练模型2.3.1 设置超参数2.3.2 编写训练函数2.3.3 编写测试函数2.3.4 正式训练 2.4 结果可视化2.4 指定图片进行预测2.6 模型评估 3 tensorflow实现DenseNet算法3.1.引入库3.2.设置GPU(如果使用的是CPU可以忽略这步)3.3.导入数据3.4.查看数据3.5.加载数据3.6.再次检查数据3.7.配置数据集3.8.可视化数据3.9.构建DenseNet网络3.10.编译模型3.11.训练模型3.12.模型评估3.13.图像预测 4 知识点详解4.1 DenseNet算法详解4.1.1 前言4.1.2 设计理念4.1.2.1 标准神经网络4.1.2.2 ResNet4.1.2.3 DenseNet4.1.3 网络结构4.1.4 效果对比4.1.5 使用Pytroch实现DenseNet121 总结 前言 关键字: pytorch实现DenseNet算法,tensorflow实现DenseNet算法,DenseNet算法详解 1 我的环境 电脑系统:Windows 11语言环境:python 3.8.6编译器:pycharm2020.2.3深度学习环境: torch == 1.9.1+cu111 torchvision == 0.10.1+cu111 TensorFlow 2.10.1显卡:NVIDIA GeForce RTX 4070 2 pytorch实现DenseNet算法 2.1 前期准备 2.1.1 引入库 import torch import torch.

大创项目推荐 深度学习卫星遥感图像检测与识别 -opencv python 目标检测

文章目录 0 前言1 课题背景2 实现效果3 Yolov5算法4 数据处理和训练5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **深度学习卫星遥感图像检测与识别 ** 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:3分创新点:5分 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/postgraduate 1 课题背景 近年来,世界各国大力发展航空航天事业,卫星图像的目标检测在各行各业的应用得到了快速的发展,特别是军事侦查、海洋船舶和渔业管理等领域。由于卫星图像中有价值的信息极少,卫星图像数据规模巨大,这迫切需要智能辅助工具帮助相关从业人员从卫星图像中高效获取精确直观的信息。 本文利用深度学习技术,基于Yolov5算法框架实现卫星图像目标检测问题。 2 实现效果 实现效果如下:可以看出对船只、飞机等识别效果还是很好的。 3 Yolov5算法 简介 下图所示为 YOLOv5 的网络结构图,分为输入端,Backbone,Neck 和 Prediction 四个部分。其中, 输入端包括 Mosaic 数据增强、自适应图片缩放、自适应锚框计算,Backbone 包括 Focus 结构、CSP 结 构,Neck 包 括 FPN+PAN 结 构,Prediction 包 括GIOU_Loss 结构。 相关代码 ​ class Yolo(object): def __init__(self, weights_file, verbose=True): self.verbose = verbose # detection params self.S = 7 # cell size self.

IDEA 每次新建工程都要重新配置 Maven的解决方案

文章目录 IDEA 每次新建工程都要重新配置 Maven 解决方案一、选择 File -> New Projects Setup -> Settingsfor New Projects…二、选择 Build,Execution,Deployment -> Build Tools -> Maven IDEA 每次新建工程都要重新配置 Maven 解决方案 DEA 每次新建工程都要重新配置 Maven,是一件相当浪费时间的事情。这是因为在创建一个项目后,在 File -> Settings -> Build,Execution,Deployment -> Build Tools -> Maven下配置了 Maven home path 、 User settings file 和 Local repository,只对当前项目有效,再打开新项目还是默认的配置。而这个问题的解决方法就是进行全局配置。 idea默认配置如下图: 一、选择 File -> New Projects Setup -> Settingsfor New Projects… 注:其他低版本的 IDEA 选择 File -> Other settings -> Settings for new projets选项

为何Selenium这么火?

今天给大家带来的主题是自动化测试框架Selenium,话不多说,直接开始! 1.什么是 Selenium 自动化测试 Jason Huggins 于 2004 年创建了一个 JavaScript 框架,旨在将其从重复的手动测试中解放出来。 最初命名为 JavaScriptTestRunner 的产品可以直接在浏览器中执行测试,驱动页面上的交互,并在无需手动输入的情况下重新运行。 这个 JavaScript 工具在 Huggins 意识到它的潜力后开始流行,将其开源并重新命名为 Selenium Remote Control。 Selenium 的创新之处在于:之前没有其他任何工具允许测试人员使用他们选择的编程语言与浏览器对话。 然而,很快浏览器对 JavaScript 应用了安全限制,无法充分发挥该工具的全部功能。 那时,谷歌是 Selenium 的狂热用户,但工程师们在诸多限制方面苦苦挣扎。 其中有一个工程师叫 Simon Stewart,他开始研究一种可以与浏览器本地对话的产品,称之为 WebDriver。 Selenium 与 WebDriver 相结合,从此改变了至此以后十多年来软件测试的方式。 目前 Selenium 在 Github 上有超过 26.3k 的 star、7.5k 的 fork、超过 195k 的项目依赖它,代码贡献者达到了 670+,NPM 周下载量达到了 1764K,是前端自动化测试领域的佼佼者。 2.Selenium 套件开发和基础设施 Selenium 系列中的第一个产品是 Selenium Remote Control(现在称为 Selenium 1)。 由于其上述限制以及随后与 WebDriver 的合并,并成功孕育了 Selenium 2,它很快就被弃用并且不再受支持。 2016 年,Selenium 3 发布,将 Selenium RC 标记为遗留包,同时扩展了支持的浏览器列表和移动测试功能。

在英特尔AI开发板上用OpenVINO NNCF优化YOLOv7,2.15倍性能提升

作者:康瑶明 英特尔边缘计算创新大使 YOLO代表“You Only Look Once”,它是一种流行的实时物体检测算法系列。最初的YOLO物体检测器于2016年首次发布。从那时起,YOLO的不同版本和变体被提出,每个版本和变体都显着提高了性能和效率。YOLO算法作为one-stage目标检测算法最典型的代表,其基于深度神经网络进行对象的识别和定位,运行速度很快,可以用于实时系统。YOLOv7 是 YOLO 模型系列的下一个演进阶段,在不增加推理成本的情况下,大大提高了实时目标检测精度。 项目使用的代码在github开源,来源 github (GitHub - openvinotoolkit/openvino: OpenVINO™ is an open-source toolkit for optimizing and deploying AI inference_notebooks/tree/main/notebooks/226-yolov7-optimization)[] 1. 准备模型与环境 1.1安装openvino以及nncf包,并且clone yolov7的仓库 %pip install -q "openvino>=2023.2.0" "nncf>=2.5.0" import sys from pathlib import Path sys.path.append("../utils") from notebook_utils import download_file # Clone YOLOv7 repo if not Path('yolov7').exists(): !git clone https://github.com/WongKinYiu/yolov7 %cd yolov7 下图为代码执行后的输出 1.2 下载预训练模型 # Download pre-trained model weights MODEL_LINK = "https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-tiny.pt" DATA_DIR = Path("

Leetcode12-统一一致字符串的数目(1684)

1、题目 给你一个由不同字符组成的字符串 allowed 和一个字符串数组 words 。如果一个字符串的每一个字符都在 allowed 中,就称这个字符串是 一致字符串 。 请你返回 words 数组中 一致字符串 的数目。 示例 1: 输入:allowed = “ab”, words = [“ad”,“bd”,“aaab”,“baa”,“badab”] 输出:2 解释:字符串 “aaab” 和 “baa” 都是一致字符串,因为它们只包含字符 ‘a’ 和 ‘b’ 。 示例 2: 输入:allowed = “abc”, words = [“a”,“b”,“c”,“ab”,“ac”,“bc”,“abc”] 输出:7 解释:所有字符串都是一致的。 示例 3: 输入:allowed = “cad”, words = [“cc”,“acd”,“b”,“ba”,“bac”,“bad”,“ac”,“d”] 输出:4 解释:字符串 “cc”,“acd”,“ac” 和 “d” 是一致字符串。 提示: 1 <= words.length <= 104 1 <= allowed.length <= 26 1 <= words[i].

自定义圆角布局和圆角TextView

用到的资源文件,在res下面values文件夹创建attrs.xml资源文件: <?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName"> <!-- 以下是重用attr的正确姿势,一切为了在布局中可以自动提示--> <!-- 圆角矩形背景色 --> <attr name="rv_backgroundColor" format="color"/> <!-- 圆角矩形背景色press --> <attr name="rv_backgroundPressColor" format="color"/> <!-- 圆角弧度,单位dp--> <attr name="rv_cornerRadius" format="dimension"/> <!-- 圆角弧度,单位dp--> <attr name="rv_strokeWidth" format="dimension"/> <!-- 圆角边框颜色--> <attr name="rv_strokeColor" format="color"/> <!-- 圆角边框颜色press --> <attr name="rv_strokePressColor" format="color"/> <!-- 文字颜色press--> <attr name="rv_textPressColor" format="color"/> <!-- 圆角弧度是高度一半--> <attr name="rv_isRadiusHalfHeight" format="boolean"/> <!-- 圆角矩形宽高相等,取较宽高中大值--> <attr name="rv_isWidthHeightEqual" format="boolean"/> <!-- 圆角弧度,单位dp,TopLeft--> <attr name="rv_cornerRadius_TL" format="dimension"/> <!-- 圆角弧度,单位dp,TopRight--> <attr name="rv_cornerRadius_TR" format="dimension"/> <!-- 圆角弧度,单位dp,BottomLeft--> <attr name="

目标检测中的常见指标

概念引入: TP:True Positive IoU > 阈值 检测框数量 FP: False Positive IoU < 阈值 检测框数量 FN: False Negative 漏检框数量 Precision:查准率 Recall:查全率(召回率) AP:P-R曲线下的面积 P-R曲线:Precision-Recall曲线 mAP:mean Average Precision 各类别AP的平均值 coco数据集评价指标官网解释: COCO - Common Objects in Context (cocodataset.org)https://cocodataset.org/#detection-eval COCO Evaluation Result

上帝视角俯视工厂设计模式

引言 本篇聊聊设计模式中的简单工厂、工厂方法、抽象工厂设计模式,争取在看完这篇后不会再傻傻分不清以及能够应用在实际项目中 背景 以一个咱们都熟悉的场景举个例子,我们平时都会戴口罩,用来过滤一些普通病毒,大致的设计如下图,每当有一个新的用户需要用到口罩时,都自己new一个普通口罩 那么现在新冠来了,经过研究发现N95口罩可以更好的抵御新冠,那么要怎么改呢,大致设计如下图 就是对每一个使用普通口罩的用户改为N95口罩。假设这里的用户很多有上百个,那对应到代码就是我们要去上百个地方进行代码改动,这个改动成本以及风险都是比较大的,如果后续又有效果更好的口罩呢,是不是这么一想就觉得头都大了,这些问题也是切切实实的发生在我们的工作中。以下是以Java实现的案例 对应的普通口罩实现 public class Main { public static void main(String[] args) { CommonFaceMask commonFaceMask1 = new CommonFaceMask(); commonFaceMask1.filterViruses(); CommonFaceMask commonFaceMask2 = new CommonFaceMask(); commonFaceMask2.filterViruses(); CommonFaceMask commonFaceMask3 = new CommonFaceMask(); commonFaceMask3.filterViruses(); } } class CommonFaceMask { public CommonFaceMask() { System.out.println("创建了一个新的口罩"); } public void filterViruses() { System.out.println("过滤普通的病毒"); } } 对应的N95口罩实现 public class Main { public static void main(String[] args) { //CommonFaceMask commonFaceMask1 = new CommonFaceMask(); N95FaceMask commonFaceMask1 = new N95FaceMask(); commonFaceMask1.

linux查看文件占用情况

文章目录 linux查看那个目录占用空间df和du显示的不一致 linux查看那个目录占用空间 在Linux系统中,你可以使用 du 命令来查看目录占用的空间。以下是一些常用的 du 命令示例: 查看当前目录的总体空间占用情况: du -h 查看指定目录的空间占用情况(例如,查看 /var/log 目录): du -h /var/log 列出目录中每个子目录的空间占用情况: du -h --max-depth=1 这将显示每个子目录的总体大小,而不会进一步深入到子目录的子目录。 列出目录中每个文件的空间占用情况: du -h --max-depth=1 --all 这将显示目录中每个文件的大小,而不包括子目录。 -h 选项表示以人类可读的方式显示文件大小(例如,使用 KB、MB、GB 等),而 --max-depth 选项用于指定深度级别,以限制显示的深度。如果省略 --max-depth 选项,默认会显示所有子目录的空间占用情况。 请注意,du 命令默认以块为单位报告文件大小,你可以使用 -h 选项来将其转换为人类可读的格式。 pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。 df和du显示的不一致 df 和 du 显示的磁盘使用情况之间的不一致可能是因为一些文件已被删除,但仍然被某个进程占用。这是由于在Linux系统中,当一个文件被删除但仍然被一个进程打开,磁盘空间不会立即释放,直到该进程关闭该文件。 以下是一些可能导致 df 和 du 不一致的原因: 已删除但仍被打开的文件: 如果一个文件被删除但仍然被某个进程打开,它仍会占用磁盘空间,但不会在文件系统中显示。这种情况下,df 显示的空间使用情况会准确反映实际磁盘空间,而 du 显示的是被删除文件占用的空间。 文件系统的保留空间: 一些文件系统会保留一部分空间用于系统目的,这部分空间可能不会被 du 显示,但会被 df 显示。 打开但已删除的日志文件: 如果某个进程仍然在写入一个已删除的日志文件,磁盘空间可能会被占用,但 du 不会考虑这部分空间,而 df 会显示它。 为了找出确切的原因,你可以执行以下步骤:

pandas保存style到excel文件中

更多pandas style用法请参考:https://pandas.liuzaoqi.com/doc/chapter8/style.html 示例程序 import numpy as np import pandas as pd # 示例数据 dataframe = pd.DataFrame({ "date": pd.date_range("2024-01-01", "2024-02-01"), "num": np.random.random(size=32), }) # 样式数据 style_df = dataframe.style.applymap(lambda x: 'color:red', subset=["date"]) \ .applymap(lambda x: 'color:green', subset=["num"]) # 保存到文件中 writer = pd.ExcelWriter("样式文件.xlsx") style_df.to_excel(writer, index=False) writer.close() 最后的结果如下:

详解bookkeeper AutoRecovery机制

引言小故事 张三在一家小型互联网公司上班,由于公司实行的996,因此经常有同事“不辞而别”,为了工作的正常推进,团队内达成了某种默契,这种默契就是通过某个规则来选出一个同事,这个同事除了工作之余还有额外看看每天是否有同事“不辞而别”,当发现有同事李四离职时,就会去把李四负责的工作的内容进行拆分给其他的同事进行处理。整个过程大致如下图 由上图可以看到这个公司通过一个签到本和工作进度表来完成整个流程,每个同事上班时都要在签到本上进行签到,每天下班前要在工作进度表上同步今天的工作进展;例如今天李四“不辞而别”溜了,张三在签到本上看到李四没有签到记录,就判定这家伙不干了同时在工作进度表中把李四的任务进行拆分给大狗和二狗来做… 通过上面的故事会发现有几个问题 张三是通过什么规则被选成“监督者”的?如果张三也不辞而别呢?为啥要通过签到本的方式,而不是张三直接去挨个挨个看?… 咱们可以带着这些种种心里的疑惑看下面的文章,这个故事其实是一个分布式存储组件的雏形,刚刚所讨论的那些问题也是这些组件所会遇到的且大部分都是有解法的,所以咱们接下来就来看看bookkeeper这个分布式存储组件是如何解决上述问题的 bookkeeper基础 “硬件无法保证不故障”,在这个大前提下,所有运行在硬件上的存储组件都一定会做一件很重要的事情,这件事就是数据恢复,要么是在组件内部来做,要么是在组件外部来做。 bk是一个具有容错的分布式存储组件,同一份数据会有多个副本,分别存在多个bookie中来提供容错保证,那么当一台bookie不可用时,其上面保存的数据都少了一个副本,如果不进行数据恢复/复制的话再有其他的bookie不可用就很容易造成数据的丢失。因此bk自身内部提供了数据恢复的机制,今天通篇大论都是围绕bk的这个机制进行展开的 数据恢复一般分为手动和自动,bk同时支持这两种方式,接下来就看看具体怎么操作的 手动恢复 bin/bookkeeper shell recover 192.168.1.10:3181 指定bookie机器来恢复 bin/bookkeeper shell recover 192.168.1.10:3181 --ledger ledgerID 指定bookie机器上的某个ledgerId进行恢复 在执行手动恢复时,会发生以下四个步骤 客户端从zookeeper读取Ledger信息根据Ledger信息确定需要做数据复制的Ledger(根据Ledger中存有被哪些bookie存储的元信息来确定)在客户端启动一个做数据恢复的进程,针对需要做数据复制的Ledger进行数据恢复一旦所有Ledger被标记为全副本了,则恢复动作完成 自动恢复 bin/bookkeeper autorecovery bookie 集群开启自动恢复机制 bin/bookkeeper shell autorecovery -disable 关闭自动恢复机制 bin/bookkeeper shell autorecovery -enable 关闭恢复后再重新开启 除了通过指令的方式启动,bk还支持配置的方式,只需要在bookie节点配置autoRecoveryDaemonEnabled为false,这个bookie节点在启动的时候也同样会启动autorecovery服务 autorecovery机制 上一章节讲了怎么使用,本章节主要讲明autorecovery这个机制 自动恢复机制中有两个角色Auditor和replication worker,在启动自动恢复机制后,会在每个bookie实例中启动这两个角色 Auditor bk集群中的Auditor们会通过zookeeper选举产生一位leader,这个leader负责监听 zookeeper /ledgers/available 节点变化情况来判定是否要做数据恢复动作,因为所有节点启动都会注册在上面,如果有服务不可用由于zookeeper的临时目录机制,会自动删除在此目录下自己节点的信息,因此leader通过watch机制可以轻松感知到有节点不可用,当Auditor leader感知到有节点不可用时,会将此bookie所负责的所有Ledger加在zookeeper /ledgers/underreplicated 路径下,通过这种方式通知replication worker做数据恢复过程 replication worker 每个replication worker都会监听 /ledgers/underreplicated 地址,在监听到有数据恢复任务时,会在 /ledgers/underreplication/locks下添加锁从而避免并发问题;如果在开始恢复前发下当前Ledger的Fragment还处于写入中的状态,replication worker会先尝试等待它写完再做数据恢复动作,但如果等了一段时间还没写完会通过Fence机制处理再做复制,同时开启一个新的Fragment给客户端做数据的继续写入 启动工作流程 参照上图,在服务器节点上执行bin/bookkeeper autorecovery bookie 后会发生以下步骤 通过exec shell指令调用操作系统拉起AutoRecoveryMain 这个Java进程AutoRecoveryMain进程启动时会同时启动Auditor线程和ReplicationWorker线程,由于环境中可能会启动多个AutoRecoveryMain进程来做HA高可用,因此多个Auditor线程会通过zookeeper选举来产生一个Auditor Leader由于bookie集群用zookeeper来做集群感知,因此Auditor Leader只需要通过watch监听zookeeper上 bookie所注册的地址就能感知到是否有bookie节点不可用;当bookie节点不可用时一般就不会上报心跳给zookeeper,zookeeper就会将该节点创建的临时目录进行删除并告知添加watch的Auditor LeaderAuditor Leader收到通知后会去zookeeper查询该不可用bookie所负责的Ledger列表,理论上这些Ledger都是需要做数据恢复的,因此会将它们放在zookeeper的/ledgers/underreplicated 目录下来通知ReplicationWorkerReplicationWorker通过watch监听到此目录有需要做数据恢复的Ledger后,会先在zk加锁再进行数据恢复逻辑;通过将Ledger划分为多个Fragment来轮训进行数据恢复,通过读取其他正常bookie上该Ledger的数据并写到其他没有该数据的bookie的节点上从而保证每份数据都有多个副本,直到将/ledgers/underreplicated 下的所有Ledger进行复制完,本次 autorecovery就算完成了。而Auditor线程和ReplicationWorker线程会不停的监听zookeeper直到下一个bookie节点不可用 通过此机制给bookkeeper提高了稳定性以及高可用能力,在有个别节点挂掉的时候依然能自动做到数据完备不丢,这种设计是一个成熟的组件该具备的能力