#导包 from sklearn import datasets import numpy as np from sklearn.model_selection import train_test_split #处理数据集并且进行分类 iris_datas = datasets.load_iris() X = iris_datas.data y = iris_datas.target # 将x数据划分在(0,1)区间内 # print(np.max(X)) # print(np.min(X)) X = X/8 *0.999+0.001 # 对数据集进行划分 X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2) # print(X_train.shape) # 对真实值的区间进行修改 ones = np.identity(3) # 定义一个三维的单位阵 for i in range(ones.shape[0]): for j in range(ones.shape[1]): if(ones[i,j]==1): ones[i,j]=0.999 else: ones[i,j]=0.001 y_true = ones[y_train] # 定义sigmoid函数 def sigmoid(x): return 1/(1+np.exp(-x)) # 计算准确率 def accuasy(y_test,rs): return sum(y_test == rs)/len(y_test) # 设置神经网络,将隐藏层设置为1层,即有两个w参数矩阵,隐藏层数目为10个 W1 = np.
fastgpt搭配chatglm3本地使用 安装并配置ChatGLM3安装并配置one-api安装fastgpt安装docker拉取fastgpt修改配置文件修改docker-compose.yml修改config.json 启动容器效果展示 安装并配置ChatGLM3 详见我的上一篇文章: 清华开源语言大模型ChatGLM3部署实战
安装并配置one-api 详见我的上一篇文章: 清华开源语言大模型ChatGLM3联通one-api实现快速部署
安装fastgpt 安装docker # 安装 Docker curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun systemctl enable --now docker # 安装 docker-compose curl -L https://github.com/docker/compose/releases/download/2.20.3/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose # 验证安装 docker -v docker-compose -v 拉取fastgpt mkdir fastgpt cd fastgpt curl -O https://raw.githubusercontent.com/labring/FastGPT/main/files/deploy/fastgpt/docker-compose.yml curl -O https://raw.githubusercontent.com/labring/FastGPT/main/projects/app/data/config.json 修改配置文件 修改docker-compose.yml # 非 host 版本, 不使用本机代理 version: '3.3' services: pg: image: ankane/pgvector:v0.
🎥 个人主页:深鱼~🔥收录专栏:cpolar🌄欢迎 👍点赞✍评论⭐收藏 目录
概述
1.搭建apache
2.安装cpolar内网穿透
3.公网访问配置
4.固定公网地址
5.添加站点
概述 Termux是一个Android终端仿真应用程序,用于在 Android 手机上搭建一个完整的Linux 环境,能够实现Linux下的许多基本操作,不需要root权限Termux就可以正常运行。
Apache是一个开源网页服务器软件,由于其跨平台和安全性,被广泛使用,是最流行的 Web 服务器软件之一。我们可以在Android手机上使用Termux来搭建Web服务器,同时做内网穿透,实现公网用户也可以访问,将Android变成小型的云服务器。
下面介绍在安卓Termux上搭建apache服务创建个人站点并且结合cpolar内网穿透工具实现公网访问。
1.搭建apache 执行命令安装apache,安装相对简单,一键安装即可
pkg install apache2 然后启动apache
apachectl start 启动的时候如出现以下问题
解决方法,修改配置文件,如果没有安装vim,执行命令安装一下
apachectl start 编辑修改配置文件
vim $PREFIX/etc/apache2/httpd.conf 找到ServerName解开注释,www.example.com改为127.0.0.1:8080,端口号可以自己改成自己喜欢的
修改后再次启动,即可
打开浏览器,输入http://127.0.0.1:8080,即可看到apahe欢迎页面,
停止apache
apachectl stop 重启apache
apachectl restart 2.安装cpolar内网穿透 cpolar官网:https://www.cpolar.com
成功创建了运行站点的一个apache容器后,我们接下来用cpolar做内网穿透来实现公网环境下的访问。
cpolar它是一个安全的内网穿透云服务,支持http/https/tcp协议,可以永久免费使用还不限制流量,支持映射80/443端口。它可以通过创建安全隧道,将本地服务暴露到公网上,让公网用户也可以正常访问内网服务,不需要公网IP,也不用设置路由器。
创建一个sources.list.d的文件夹:
mkdir -p $PREFIX/etc/apt/sources.list.d 添加cpolar下载源文件
echo "deb [trusted=yes] http://termux.cpolar.com termux extras" >> $PREFIX/etc/apt/sources.list.d/cpolar.list 更新仓库
pkg update 安装cpolar
pkg install cpolar 安装termux服务
注意:安装完成后记得关闭重启一下termux 才生效!
Linux 操作系统配置 SFTP sftp采用的是ssh加密隧道,安装性方面较ftp强,而且依赖的是系统自带的ssh服务,不像ftp还需要额外的进行安装基于 ssh 的 sftp 服务相比 ftp 有更好的安全性(非明文帐号密码传输)和方便的权限管理(限制用户的活动目录)。
实现目的:
1、设置 sftp 帐号,使用户只能 sftp 操作文件, 而不能 ssh 到服务器;
2、限定用户的活动目录,使用户只能在指定的目录下活动,使用 sftp 的 ChrootDirectory 配置;
查看ssh版本 ssh -V 1、添加用户组 sftp groupadd sftp 2、创建sftp用户 useradd -g sftp -s /bin/false baksftp -s /bin/false:不允许shell登录。
-g sftp:加入sftp组
3、设置密码 passwd baksftp 4、限定活动目录 mkdir -p /data/sftp/baksftp 5、配置Chroot目录权限 # 注意:此目录如果用于后续的 chroot 的活动目录,目录所有者必须是 root chown root:sftp /data/sftp/baksftp chmod 755 /data/sftp/baksftp chroot 可能带来的问题:
因为 chroot 会将会话的根目录切换至此,所以 ssh 登录很可能会提示 /bin/bash: No such file or directory 的错误,因为此会话的路径会为 [chroot]/bin/bash
1. 拉取镜像 docker pull rancher/rancher:v2.6.5 注:
上面命令中rancher的版本v2.6.5,仅仅是我因为我们环境中使用的k8s都是 1.20.1 到1.23.6 之间的版本。rancher支持的k8s版本,在github上查看:Release Release v2.6.5 · rancher/rancher · GitHub
2.部署rancher docker run -d --restart=unless-stopped -p 80:80 -p 443:443 --privileged rancher/rancher:v2.6.5 注:
由于我这台机器是专门部署rancher的,所以给docker开放的端口是80直接对应80,443直接对应443,这样可以直接通过机器IP访问rancher页面。此处,可以根据你的需求去映射端口。
3 配置rancher 完成后,访问https://<部署主机的ip或全限定域名>,进入rancher管理页面。
可以看到rancher的引导信息,提示你需要进行如下操作
# 找到您的容器ID docker ps | grep rancher # 找到密码 docker logs ${container-id} | grep "Bootstrap Password:" 然后将查询到的字符串复制到Password文本框中,点击Log in with Local User。
在下面这个页面您需要依次点击第一个和第三个箭头的选择框,并填写好密码和Server URL,然后点击Continue。
需要注意两点:
Server URL一定要填写IP地址,而不要填写全限定域名。密码长度要超过12位。 以后rancher就可以正常使用了。
0、版本说明 Spring Cloud Version:Spring Cloud 2021.0.4 Spring Cloud Gateway Version:3.1.4 Spring Boot Version:2.6.11 1、网关跨域问题说明 关于跨域的相关原理和理论,网上有大量文章对此进行说明,因此博主在这里就不再赘述,这里仅说明对于在同一注册中心中注册的服务,网关可以通过在注册中心注册的服务名对相应请求找到对应的服务进行路由转发,因此这种情况,不存在跨域问题,但是对于一些通过Nginx反向代理到网关服务下的请求进行访问时,就存在了跨域问题,所以下面网关配置也是针对此部分问题进行解决。
2、网关跨域解决 针对网关跨域解决,这里提供两种解决方案,仅供参考,下面配置均在线上环境测试通过,关于其他版本,仅供参考!
2.1、方案一:网关注入配置类 Spring Cloud Gateway提供了跨域的配置类,然后在网关项目代码中添加一个CorsWebFilter类即可实现,关于网关提供的Cors配置类,可参看官方文档(CorsConfiguration (Spring Framework 5.0.20.RELEASE API))
@Configuration public class GlobalCorsConfig { @Bean public CorsWebFilter corsWebFilter() { CorsConfiguration config = new CorsConfiguration(); // 这里仅为了说明问题,配置为放行所有域名,生产环境请对此进行修改 config.addAllowedOrigin("*"); // 放行的请求头 config.addAllowedHeader("*"); // 放行的请求方式,主要有:GET, POST, PUT, DELETE, OPTIONS config.addAllowedMethod("*"); // 暴露头部信息 config.addExposedHeader("*"); // 是否发送cookie config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return new CorsWebFilter(source); } } 说明:
使用 HTML、CSS 和 JavaScript 创建轮播图 在本文中,我们将讨论如何使用 HTML、CSS 和 JavaScript 构建轮播图。我们将演示两种不同的创建滑块的方法,一种是基于opacity的滑块,另一种是基于transform的。
创建 HTML 我们首先从 HTML 代码开始:
<div class="slider"> <div class="slide"> <img src="images/1.jpg" alt="demo image" /> </div> <div class="slide"> <img src="images/2.jpg" alt="demo image" /> </div> . . . <a class="prev" onclick="prevSlide()"><</a> <a class="next" onclick="nextSlide()">></a> </div> .slider元素充当整个图像滑块的容器。
单独的幻灯片.slide元素与图像一起封装在容器中。
滑块导航由.prev、.next两个按钮元素控制。
我们还为导航设置了onclick事件监听器,当点击它们时,相应的 JavaScript 函数将被激活。
添加样式 为了更轻松地设置元素样式,建议删除所有元素的默认内边距和边距,并将其box-sizing属性设置为border-box。这允许根据元素的尺寸border-box而不是content-box来调整元素的大小。
* { padding: 0px; margin: 0px; box-sizing: border-box; } 然后添加.slider样式。
.slider { width: 500px; height: 300px; margin: auto; overflow: hidden; transform: translateY(50%); } 以及.
最近在AMESIM与MATLAB进行联合仿真的时候遇到如下问题:
Make failed:Unable to create an excutable for the system.
看了网上的解决办法如下
配置环境变量重装AMESIM,有顺序要求,首先是VS,然后是AMESIM与MATLAB。在AMESIM安装过程中即可识别VC++,但是我在重装过程中,并没有识别到VC++,本人的各软件版本:AMESIM2021,MATLAB2021a,VC++2022另外是配置MINGW 本人还未解决这个问题,谨以此记录。
2023.11.24更新,花钱解决,看了一下主要是装的VS2019,以及各种环境变量。
2023.11.24二次更新,博主用编号命名搭建的模型,亦会报错,报错如下:
所以需要把文件名称改为英文即可
本文是AMESim与MATLAB联合仿真的demo,记录一下如何进行联合仿真。
AMESim与MATLAB联合仿真可以大幅度提高工作效率。
author:xiao黄 缓慢而坚定的生长 csdn:https://blog.csdn.net/Python_Matlab?type=blog 主页传送门
博主的联合仿真环境如下:
AMESIM 2021MATLAB 2021aVS 2019Windows 10 64位系统 安装的步骤,一般是先VS,然后是AMESIM,而MATLAB的顺序不影响。
废话少说,步入正题,联合仿真,启动!
首先打开AMESim,在草图模式(SKETCH)中点击Create interface block,会出现一个弹框,如下所示。
这时候要注意,需要选择Simulink (co-simulation) - AME2SLCosim
博主在此随便设置参数,如下所示。
然后得到下图结果
此时随机搭建一个简单模型,如下所示
接着就是常规步骤,先进入SUMODEL,设置元件的模型,然后设置PARAMETER(参数),在此使用默认的参数,最后进入SIMULATION中,会出现如下弹框。
此时,关闭上述弹窗,然后在Tools中选择MATLAB
会自动打开MATLAB,打开的时候如下所示
此时,需要进入到Simulink中
接着双击该模块
注意,需要选择**.mexw64**结尾的文件
然后,搭建一个简单的demo,此时便可以进行联合仿真,相关Simulink元件的参数默认,单击Run运行MATLAB仿真,需要注意的是,在运行MATLAB仿真中,AMESIM仿真模型不能关闭。
相关运行结果如下,可以查看AMESIM相关元件与MATLAB元件的波形输出。
仿真成功!
希望对各位有所帮助!
至此,已成艺术!
大家好,我是 Jack。
对于 Stable Diffusion,想必我的读者朋友们对此都不陌生。
自 Stability AI 公司发布 SD(全称:Stable Diffusion) 以来,受到了很多人的喜爱。
SDXL 效果
随后技术升级,又发布了 SDXL,名字很有喜感,XL、XXL、XXXL...
SDXL Logo
顾名思义,SDXL 就是 SD 的升级版,图片生成的效果更好、更逼真、分辨率更高!
图片领域做得不错了,Stability AI 再次发力,昨天又发布了 Stable Video Diffusion。
Stability AI 发布
也就是说,通过一句话描述,现在不仅可以生成图片,还可以生成视频了。
举几个例子。
输入:火箭升天
AI 算法直接生成对应的视频:
输入:太空中转动的地球:
AI 算法直接生成对应的视频:
看下更多的例子:
是不是效还不错?Stability AI 把 Stable Video Diffusion 也开源了!
Stable Video Diffusion 一共开源了两个模型:
SVD:能够生成帧率 14、分辨率 576x1024 的视频;
SVD-XT:SVD 的 finetune 升级版,分辨率不变,但能够生成帧率 25 的视频;
前排提醒: 想要本地跑 Stable Video Diffusion,显存得 20G 左右。
1、下载代码库
大家好,我是 Jack。
AI 写代码想必很多人都体验过了,使用 AI 编程工具是一个大趋势,越早学会使用 AI 辅助你写代码,你的效率也会越高。
甚至有些公司已经要求员工具备 AI 编程能力。
对于学生党,AI 编程可以帮助我们学习,做课后作业、做毕设;对于上班族,AI 编程可以帮助我们提高工作效率,甚至是翻译别人的“屎山”代码。
之前跟大家聊过各种 AI 工具,其中 CodeGeeX 的呼声很高,这个 Copilot 的国产免费平替版到底有着怎样的魅力?
我体验了一番后发现,它有着三个明显的优势。
对个人开发者完全免费;
不用使用科学上网非常方便;
对中文支持非常友好。
一、CodeGeeX GitHub Copilot 刚发不出来的时候,很多用户表示编程效率有了较大的提高。随后,就涌现了各种代码生成的大模型,包括:DeepMind 的 AlphaCode、Salesforce 的 CodeGen、Meta 的 InCoder 和 Google 的 PaLM-Coder-540B。
而国内较为出名的就是 CodeGeeX,它是清华和智谱 AI 联合打造的多语言代码生成模型。
可以看到,整体也是 Transformer 的结构,采用 KQV 这种经典的多头注意力机制。
除了词嵌入,也用到了位置嵌入,从而帮助模型学到位置之间的依赖关系和自然语言的时序特性。
CodeGeeX 的预训练预料也很丰富:
开源代码数据集:Pile 和 CodeParrot;
从 GitHub 爬取代码,选择的代码仓库至少有一个 star 且小于10MB,然后过滤文件: 每行超过 100 个字符;
自动生成的;
字母比例小于 40% 的;
大于 100KB 或者小于 1KB 的。
程序员干货学习资源(持续更新)_类似 cnbeta-CSDN博客
学fpga肯定是电子信息类、自动化类、计算机类等相关专业最好,
一般要求熟悉数字电路设计,以及C、verilog、 VHDL语言等,还要有一定的脚本语言shell、TCL等开发能力,另外熟悉Vivado/Quartus等fpga相关软件,还能熟练使用VCS/Modelsim等验证工具等。
所以电子类相关专业是最好学FPGA的,
那其他专业就不能学吗,肯定不是,其他专业也可以学,但是一般建议理工类专业的,最好是学过c、数电、或者其他编程语言的人学。
另外fpga的应用领域是比较广的,也可以根据相关领域的来确定哪些专业。
比如:人工智能、通讯、芯片设计、图像及视频处理、自动控制、数据获取和处理、高速接口设计等等,如果专业与应用领域比较契合的也是可以学FPGA的。
FPGA其本身为集成电路的一种,其发展也体现在集成电路的发展中;FPGA本身的优势有很多,特别是跟CPU、GPU和专用ASIC相比,有其本身的特点;结合这些优势,FPGA在很多领域是无法被替代的,所以学fpga确实是不错的选择。
另外2023 年,日本、荷兰继美国之后宣布实施尖端半导体设备出口限制,荷兰将禁止向中出口 14nm 及以下的 DUV 光刻机,日本将包括 EUV 在内的清洗、薄膜沉积、热处理、曝光、刻蚀、检测等 23 个种类半导体设备纳入出口管制清单,以美国为主导的集成电路技术封锁进一步升级。
集成电路产业链涉及环节众多,上游材料、设计、设备中的某一细分品类都可能成为整个产业卡脖子环节,随着半导体技术封锁升级,从外获取先进技术、高端人才的难度加大,对内的基础研究型人才的需求将进一步提升,而基础研究型人才目前仍较为匮乏,需求缺口持续扩大。
所以,如果专业合适,那选择学fpga也是个好的选择!
QueryWrapper OR 的用法
@Data public class ReimburseAwardQueryDTO extends PageQuery<ReimburseAwardDomain> { private static final long serialVersionUID = 1L; @ApiModelProperty("主键id") private Long id; @ApiModelProperty("手机号或账号") private String mobileOrUserName; @Override public QueryWrapper<ReimburseAwardDomain> toQueryWrapper() { QueryWrapper<ReimburseAwardDomain> queryWrapper = new QueryWrapper<>(); //----------------条件开始------------------- queryWrapper.eq(valid(id),"id",id); /**或者条件*/ if (valid(mobileOrUserName)) { queryWrapper.and(q -> q.eq("user_name", mobileOrUserName).or().eq("mobile", mobileOrUserName).or().eq("real_name", mobileOrUserName)); } //----------------排序倒序------------------- queryWrapper.orderByDesc("create_time").orderByDesc("id"); super.addOrder(queryWrapper); return queryWrapper; } } 用 queryWrapper.and( )开始, and里面用.or().eq(条件)
相当于以下Mybatis SQL代码
<select id="selectReimburseAwardList" parameterType="com.hq.admin.marketing.dto.ReimburseAwardQueryDTO"> SELECT <include refid="Base_Column_List" /> FROM t_reimburse_award <where> id = #{id} <if test="
如下阻塞队列+线程的代码,很常见,当服务停止时,如何停止被BlockingQueue阻塞的线程?
public class BlackingQueueTest { public static void main(String[] args) { BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue(10); blockingQueue.add(5); blockingQueue.add(-1); final Thread thread = new Thread(new Runnable() { @Override public void run() { while (true) { try { Integer el = blockingQueue.take(); System.out.println(el); } catch (InterruptedException e) { } } } }); thread.start(); } } 两种解决方案
方案一:使用poll代替take,这将允许处理线程在等待一段时间而没有新输入时超时并终止。
public class BlackingQueueTest { public static void main(String[] args) { BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue(10); blockingQueue.
目录标题 1. 引言1.1 内存映射的定义1.2 `mmap` 系统调用概述 2. 内存映射基础2.1 内存映射的定义2.2 `mmap` 系统调用概述示例代码 2.3 `mmap` 系统调用和直接使用IPC共享内存之间的差异 `mmap` 和页缓存:共享内存和内存页:总结: 3. `mmap` 与文件 I/O3.1. 传统文件 I/O 的局限性3.2. `mmap` 的优势2.2.1. 效率比较 2.3. `mmap` 的使用场景2.3.1 针对进程间通讯的场景权衡实时性的比较 4. 内存映射的工作原理(How Memory Mapping Works)4.1. 虚拟内存与物理内存(Virtual and Physical Memory)4.2. 延迟加载和页面缓存(Lazy Loading and Page Caching)页面缓存的机制 4.3. 写时复制机制(Copy-On-Write Mechanism)写时复制的应用 5. 内存管理和安全性(Memory Management and Security)5.1. 用户空间与内核空间的隔离(Separation of User Space and Kernel Space)5.2 内存越界的风险及其防范(Risks and Prevention of Memory Overflow)5.3 内存映射的安全性措施(Security Measures in Memory Mapping) 6.
调整占空比 要控制舵机,就要向舵机信号线输入PWM信号,信号频率大约50HZ,即周期=1/频率=1/50=0.02s,也就是20ms左右。通过调节不同的占空比来控制舵机旋转不同角度。
这里可以通过中断来改变占空比。首先设置定时器,定时0.5毫秒触发一次中断。
void timerInit() { TMOD = 0x01; TL0 = 0x33; TH0 = 0xFE; //0.5毫秒爆表 TF0 = 0; TR0 = 1; ET0 = 1; //开启定时器中断 EA = 1; } 0.5毫秒一到,让cnt+1。当cnt累计到40时,刚好就是一个周期的时间,也就是20ms。然后在这个周期当中,我们需要修改占空比。所以,在中断里面加入判断,在一个周期内的某个时间断输出高点平,其余时间段输出低电平。
void timeInterrupt() interrupt 1 //中断开始 { cnt++; TL0 = 0x33; //重置定时器 TH0 = 0xFE; if(cnt < jd){ //改变占空比 sg_con = 1; }else{ sg_con = 0; } if(cnt == 40){ //一个周期的时间,即20ms cnt = 0; sg_con = 1; } } 完整代码:
这文章写得很详细,忍不住转过来,原文地址:
BlockingQueue(阻塞队列)详解_codingXT的博客-CSDN博客
一. 前言 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题。通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利。本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景。
二. 认识BlockingQueue 阻塞队列,顾名思义,首先它是一个队列,而一个队列在数据结构中所起的作用大致如下图所示:
从上图我们可以很清楚看到,通过一个共享的队列,可以使得数据由队列的一端输入,从另外一端输出。
常用的队列主要有以下两种:(当然通过不同的实现方式,还可以延伸出很多不同类型的队列,DelayQueue就是其中的一种)。
先进先出(FIFO):先插入的队列的元素也最先出队列,类似于排队的功能。从某种程度上来说这种队列也体现了一种公平性。后进先出(LIFO):后插入队列的元素最先出队列,这种队列优先处理最近发生的事件。 多线程环境中,通过队列可以很容易实现数据共享,比如经典的“生产者”和“消费者”模型中,通过队列可以很便利地实现两者之间的数据共享。假设我们有若干生产者线程,另外又有若干个消费者线程。如果生产者线程需要把准备好的数据共享给消费者线程,利用队列的方式来传递数据,就可以很方便地解决他们之间的数据共享问题。但如果生产者和消费者在某个时间段内,万一发生数据处理速度不匹配的情况呢?理想情况下,如果生产者产出数据的速度大于消费者消费的速度,并且当生产出来的数据累积到一定程度的时候,那么生产者必须暂停等待一下(阻塞生产者线程),以便等待消费者线程把累积的数据处理完毕,反之亦然。然而,在concurrent包发布以前,在多线程环境下,我们每个程序员都必须去自己控制这些细节,尤其还要兼顾效率和线程安全,而这会给我们的程序带来不小的复杂度。好在此时,强大的concurrent包横空出世了,而它也给我们带来了强大的BlockingQueue。(在多线程领域:所谓阻塞,在某些情况下会挂起线程(即阻塞),一旦条件满足,被挂起的线程又会自动被唤醒),下面两幅图演示了BlockingQueue的两个常见阻塞场景:
如上图所示:当队列中没有数据的情况下,消费者端的所有线程都会被自动阻塞(挂起),直到有数据放入队列。
如上图所示:当队列中填满数据的情况下,生产者端的所有线程都会被自动阻塞(挂起),直到队列中有空的位置,线程被自动唤醒。
这也是我们在多线程环境下,为什么需要BlockingQueue的原因。作为BlockingQueue的使用者,我们再也不需要关心什么时候需要阻塞线程,什么时候需要唤醒线程,因为这一切BlockingQueue都给你一手包办了。既然BlockingQueue如此神通广大,让我们一起来见识下它的常用方法。
三. BlockingQueue的核心方法 1.放入数据 offer(E e):表示如果可能的话,将e加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false(本方法不阻塞当前执行方法的线程)。offer(E e, long timeout, TimeUnit unit):可以设定等待的时间,如果在指定的时间内,还不能往队列中加入e,则返回失败。put(E e):把e加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻塞,直到BlockingQueue里面有空间再继续。add(E e): 如果可以在不违反容量限制的情况下立即将指定元素插入此队列,则在成功时返回true ,如果当前没有可用空间则IllegalStateException 。 当使用容量受限的队列时,通常最好使用offer 2.获取数据 poll(long timeout, TimeUnit unit):从BlockingQueue取出一个队首的对象,如果在指定时间内,队列一旦有数据可取,则立即返回队列中的数据。否则时间超时还没有数据可取,返回失败。take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻塞进入等待状态直到BlockingQueue有新的数据被加入。drainTo(Collection<? super E> c):一次性从BlockingQueue获取所有可用的数据对象(还可以指定获取数据的个数drainTo(Collection<? super E> c, int maxElements)),通过该方法,可以提升获取数据效率;不需要多次分批加锁或释放锁。 3.删除数据 remove(Object o):从此队列中移除指定元素的单个实例(如果存在)。则返回true 。 无法向一个 BlockingQueue 中插入 null。如果你试图插入 null,BlockingQueue 将会抛出一个 NullPointerException。
可以访问到 BlockingQueue 中的所有元素,而不仅仅是开始和结束的元素。比如说,你将一个对象放入队列之中以等待处理,但你的应用想要将其取消掉。那么你可以调用诸如 remove(o) 方法来将队列之中的特定对象进行移除。但是这么干效率并不高(译者注:基于队列的数据结构,获取除开始或结束位置的其他对象的效率不会太高),因此你尽量不要用这一类的方法,除非你确实不得不那么做。
四. 常见BlockingQueue 在了解了BlockingQueue的基本功能后,让我们来看看BlockingQueue家庭大致有哪些成员?
1. ArrayBlockingQueue 基于数组的阻塞队列实现,在ArrayBlockingQueue内部,维护了一个定长数组,以便缓存队列中的数据对象,这是一个常用的阻塞队列,除了一个定长数组外,ArrayBlockingQueue内部还保存着两个整形变量,分别标识着队列的头部和尾部在数组中的位置。
ArrayBlockingQueue在生产者放入数据和消费者获取数据,都是共用同一个锁对象,由此也意味着两者无法真正并行运行,这点尤其不同于LinkedBlockingQueue;按照实现原理来分析,ArrayBlockingQueue完全可以采用分离锁,从而实现生产者和消费者操作的完全并行运行。Doug Lea之所以没这样去做,也许是因为ArrayBlockingQueue的数据写入和获取操作已经足够轻巧,以至于引入独立的锁机制,除了给代码带来额外的复杂性外,其在性能上完全占不到任何便宜。 ArrayBlockingQueue和LinkedBlockingQueue间还有一个明显的不同之处在于,前者在插入或删除元素时不会产生或销毁任何额外的对象实例,而后者则会生成一个额外的Node对象。这在长时间内需要高效并发地处理大批量数据的系统中,其对于GC的影响还是存在一定的区别。而在创建ArrayBlockingQueue时,我们还可以控制对象的内部锁是否采用公平锁,默认采用非公平锁。
部署⽹站都有类似过程:(每⼀步都有很多细节,需要⾃⼰试验、采坑才能掌握) 1.搭建LAMP平台(或LNMP平台),安装搭建⽹站所需的软件包,启动服务 2. 将开发⼈员写好的⽹站资源放置在⽹站的默认⽬录(在配置⽂件可修改) 3.修改⽹站所有⽂件的SELinux的安全属性,或者直接将SELinux修改为宽松,或者直接 关闭SELinux(后两者不安全) 4. 设置防⽕墙允许对应端⼝、服务,或者直接关闭防⽕墙(不安全) 5. 配置虚拟主机,实现同时搭建多个⽹站 6. 修改hosts⽂件(此处只是试验做法,真正场景是搭建WEB服务之后,做端⼝映射,申 请域名,将域名和公⽹IP最绑定)
目录
论坛系统概述
关于Discuz!论坛/社区系统
部署Discuz!论坛
论坛系统概述 Bulletin Board System ,论坛 指的是 Internet 上的⼀种电⼦信息服务系统 提供公共电⼦⽩板,每个⽤⼾都可以在上⾯书写、发布信息或提出看法 关于Discuz!论坛/社区系统 腾讯旗下北京康盛公司 Comsenz 出品 使⽤ PHP 语⾔编写,⽀持 MySQL 等多种数据库 免费提供源代码,⽤于学习、测试;商业站点需购买授权许可 部署Discuz!论坛 1 、下载 Discuz !论坛程序包,部署为⽹站⽬录;将压缩包中的 upload ⽬录上传到 Web 服务 器 [root@bogon ~]# unzip -d /var/www/html /var/www/html/Discuz_X3.4_SC_UTF8.zip //将压缩包解压到 /var/www/html ⽬录下 // -d:指定解压到的⽬录 2 、修改⽂件名(可选) [root@bogon ~]# mv /var/www/html/upload/ /var/www/html/bbs 3 、浏览器访问 bbs , http://192.168.189.136/bbs 💡 如果不能访问: 1.
目录
YUM
软件资源哪⾥来?
1、准备软件仓库⽬录
2、更改yum软件源
3、结果验证
yum查询软件资源
list 列出软件
info获取软件描述
provides查询供给信息
yum安装软件
install安装软件
remove卸载软件
reinstall重装软件
LAMP动态⽹站
B/S服务架构
如何获取⽹⻚资源
静态⽹站与动态⽹站
什么是LAMP?
快速安装LAMP平台组件
YUM YUM , Yellowdog Updater Modified ,⻩狗升级器 软件仓库:集中分发 .rpm 软件包资源,并解决软件之间的依赖关系 客⼾机:使⽤ yum 查询 / 安装 / 卸载软件 软件资源哪⾥来? 1、准备软件仓库⽬录 CentOS7安装盘已预先配置成软件仓库,可以直接使⽤ [root@bogon ~]# mkdir -p /repo/cos7dvd [root@bogon ~]# mount /dev/cdrom /repo/cos7dvd //将cdrom⽂件(镜像⽂件)挂载到/repo/cos7dvd mount: /dev/sr0 写保护,将以只读⽅式挂载 [root@bogon ~]# ls /repo/cos7dvd/ CentOS_BuildTag EULA images LiveOS repodata RPM-GPG-KEY-CentOS-Testing-7 EFI GPL isolinux Packages RPM-GPG-KEY-CentOS-7 TRANS.
零.前情提要 这篇文章主要借鉴B站三更大大关于spring security的教程,这篇文章的大部分内容也来自于那个教程,写这个的主要目的是记录加强印象,总结,并且在文章中我也有穿插自己的想法。
前面的文章【spring security学习笔记(一)–认证】:
https://blog.csdn.net/bjjx123456/article/details/132414814?spm=1001.2014.3001.5501
我们知道spring security的功能主要有两部分:
一个是认证,就是检验访问系统的用户是不是本系统的用户,能不能访问只有系统用户才能访问的接口。
另外一个是授权,是指用户是什么身份,能访问系统哪些接口。
总结起来不同用户可以使用不同功能/接口,这就是权限系统要去实现的效果。
举个例子:
我们设计一个考勤系统,由督导调用接口来负责对班级成员的点名。
如果普通学生知道那个接口的地址,而我们后端如果没有对调用接口用户的身份进行识别,判断调用接口的用户是学生还是督导,该有没有权利使用该接口,那么这个接口就会被利用来修改整个班级的课程考勤情况。
一.权限基本流程(简单看一下就好) 在SpringSecurity中,会使用默认的FilterSecurityInterceptor来进行权限校验。在FilterSecurityInterceptor中会从SecurityContextHolder获取其中的Authentication,然后获取其中的权限信息。当前用户是否拥有访问当前资源所需的权限。
所以我们在项目中只需要把当前登录用户的权限信息也存入Authentication,再将Authentication存入SecurityContextHolder。
然后设置我们的资源所需要的权限即可。
二.授权实现 1.限制访问资源所需权限 SpringSecurity为我们提供了基于注解的权限控制方案,我们可以使用注解去指定访问对应的资源所需的权限。
我们现在原来配置类的上方添加注解:@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { //之前的代码 } 然后就可以使用对应的注解:@PreAuthorize
@RestController public class HelloController { @RequestMapping("/hello") @PreAuthorize("hasAuthority('test')") public String hello(){ return "hello"; } } 注:因为hasAuthority外是双引号,所以里面就只能是单引号。
对这个注解的理解:实际上是读取注解里面的属性值,读取注解的内容作为表达式/代码进行执行,所以实际上是方法的调用。
2.封装权限信息 我们前面在写UserDetailsServiceImpl的时候说过,在查询出用户后还要获取对应的权限信息,封装到UserDetails中返回。
我们先直接把权限信息写死封装到UserDetails中进行测试。
我们之前定义了UserDetails的实现类LoginUser,想要让其能封装权限信息就要对其进行修改。
修改内容:增加permissions及authorities的list变量,并重写之前直接返回null的getAuthorities()方法,然后还加了有参构造方法,对user和permissions变量进行构造。
@Data @NoArgsConstructor @AllArgsConstructor public class LoginUser implements UserDetails{ private User user; //存储权限信息 private List<String> permissions; //存储SpringSecurity所需要的权限信息的集合 //为了避免下面获取权限的方法调用都需要进行封装,我们将这个变量作为成员变量 //redis默认在存储的时候不会将SimpleGrantedAuthority序列化,加上这个注解使得成员变量不会存储到redis @JSONField(serialize = false) private List<SimpleGrantedAuthority> authorities; //有参构造 public LoginUser(User user,List<String> permissions) { this.
使用langchain时,import langchain时报错内容如下:
pydantic.errors.PydanticUserError: If you use `@root_validator` with pre=False (the default) you MUST specify `skip_on_failure=True`. Note that `@root_validator` is deprecated and should be replaced with `@model_validator`. For further information visit https://errors.pydantic.dev/2.4/u/root-validator-pre-skip 环境为:
python 3.7
langchain 0.0.27
这个问题最主要的问题是pydantic的版本问题,由报错内容“For further information ...”也可以了解到,最终将pydantic库的版本降低到1.10.13,pydantic_core等相关依赖库的版本也会自动降低,出现此问题的根本就是pydantic的版本问题,与python版本等并无直接关系。使用如下代码安装即可:
pip install pydantic==1.10.13 -i https://pypi.douban.com/simple
若有侵权,联系必删 论文地址:
Focal and Global Knowledge Distillation for Detectors
一、什么是知识蒸馏 首次提出知识蒸馏的概念由Hinton于2015年提出:
知识蒸馏开山之作
中文知识蒸馏研究综述:
知识蒸馏研究综述
一般地,大模型往往是单个复杂网络或者是若干网络的集合,拥有良好的性能和泛化能力,而小模型因为网络规模较小,表达能力有限。因此,可以利用大模型学习到的知识去指导小模型训练,使得小模型具有与大模型相当的性能,但是参数数量大幅降低,从而实现模型压缩与加速,这就是知识蒸馏与迁移学习在模型优化中的应用。
软硬标签 类别
Soft Target
Hard Target
马
0.7
1
狗
0.05
0
驴
0.1
0
牛
0.1
0
汽车
0.05
0
传统目标检测训练任务,通过Hard targets的标签进行训练,之后将图片出入模型进行识别,可以得到一个Soft Target。从上图可以看出,Soft Target比Hard Target传递出更多的信息,因此可以通过Soft Target作为学生模型的输入进行训练。
蒸馏温度T Soft Target的输出还不足够“Soft“,因此在对其进行处理,新增一个蒸馏温度T,T使用在softmax函数中,修正输出标签的soft度,公式如下:
随T变化各概率分布如下,当T变大,每个分类所获得的相似度就越平均(越soft),太大的话每个分类的相似度就会相同,越小会发现每个类别的差异会很大。
T的变化程度决定了学生模型关注负类别的程度,当温度很低时,模型就不会太关注负类别,特别是那些小于均值的负类别。当温度很高时,模型就会更多的关注负类别。
在训练时,从有部分信息量的负样本中学习,则温度设定高些。
防止受负样本中标签噪声的影响,温度设定低些。
蒸馏过程 训练老师模型使用较高的温度去构建Soft Labels同时使用较高的Soft Labels和T=1的Soft Labels去训练学生模型把T改为1在学生模型上做预估 损失函数: disiliation loss(soft)和student loss(hard)的加权求和
总损失:
soft Loss:
hard Loss:
其中:
piT 指Teacher模型在温度等于T的条件下softmax输出在第 i 类上的值。qiT 指Student的在温度等于T的条件下softmax输出在第 i 类上的值。vi指Teacher模型的logits, zi 指Student模型的logits, N 指总标签数量。
最新发布 PP-YOLOE+,最高精度提升2.4% mAP,达到54.9% mAP,模型训练收敛速度提升3.75倍,端到端预测速度最高提升2.3倍;多个下游任务泛化性提升。PicoDet-NPU模型,支持模型全量化部署;新增PicoDet版面分析模型。超轻量目标检测算法。PP-TinyPose增强版,在健身、舞蹈等场景精度提升9.1% AP,支持侧身、卧躺、跳跃、高抬腿等非常规动作。超轻量关键点检测算法。 新增能力 发布行人分析工具PP-Humanv2,新增打架、打电话、抽烟、闯入四大行为识别,底层算法性能升级,覆盖行人检测、跟踪、属性三类核心算法能力,提供全流程开发及模型优化策略,支持在线视频流输入。首次发布PP-Vehicle,提供车牌识别、车辆属性分析(颜色、车型)、车流量统计以及违章检测四大功能,兼容图片、在线视频流、视频输入,提供完善的二次开发文档教程。 应用场景 智能健身 智能化的对健身动作进行识别、矫正、计数
2. 打架识别
3. 来客分析
通过对来店客人的属性识别、行为预警、时长和轨迹记录等数据进行统计分析, 可以应用于 相关场所的客流通统计、用户画像、客户留存分析等功能, 进而提升 相关场所的经营和服务水平
4. 车辆结构化识别
车牌识别、车辆属性分析、违章检测、车流量计数
论文介绍 4.1 PP-YOLOE 论文地址:PP-YOLOE+
主要创新点:
Anchor free无锚盒机制可扩展的backbone和neck,由CSPRepResStage(CSPNet+RMNet)构成使用Varifocal Loss(VFL)和Distribution focal loss(DFL)的头部机制ET-head动态标签分配算法Task Alignment Learning(TAL) YOLOV5
YOLOX
PPYOLOE
YOLOV6
数据增广
mosaic、mixup等
mosaic、mixup等
只有最基本的
同yolov5
backbone
cspdarknet
cspdarknet
CSPRepResNet
EfficientRep
neck
PAN
PAN
PAN
Rep-PAN
Head
耦合
解耦
ET-Head
解耦+加速
label assignment
max-iou-assign
simOTA
TAL
simOTA
Anchor-free
anchor-based
Anchor-free
Anchor-free
Anchor-free
0 前言 曙光超算平台是一款高性能、高可靠性和高可扩展性的超级计算机平台。它采用了自主研发的曙光超算架构,并采用国产GPU(即DCU),硬件基于ROCm平台。其核心技术包括:
曙光超算架构:采用高性能处理器和互连网络,实现超高速的数据传输和处理能力。计算加速技术:支持GPU加速和FPGA加速,进一步提升计算性能和效率。高可靠性设计:采用冗余设计和错误检测纠正技术,实现硬件故障自动切换和修复,保证计算任务的连续性。可扩展性:支持多机房间级联,实现大规模计算任务的并行处理。多编程模型和开发工具:提供多种编程模型和开发工具,方便用户进行软件开发和优化。 本文对中科曙光超算平台的使用进行介绍
环境搭建 1.1 pytorch 安装包安装记录 由于曙光云使用的是国产GPU(即DCU),硬件是基于ROCm的,因此不能适配PyTorch官网下载的包(无法调用DCU),因此只能使用曙光云平台提供的编译好的PyTorch包进行安装。切忌不能使用pip install torch==1.7.0 torchvision的命令直接安装,而应该选择曙光云本地提供的包进行安装。
本次安装基于python 3.9版本进行安装,pytorch版本为1.13.1
1.1.1 环境创建、依赖包安装
首先,和conda创建环境相同,创建py39环境,并激活环境
conda create -n env_py39 python=3.9
conda activate env_py39
1.1.2 本地安装pytorch1.13.1(由曙光编译好的版本)
查看本地whl包所在目录
其他所需用到GPU的whl包可以在相关目录下找到,例如这里的dtk-22.04.1,不同名称下对应不同依赖包版本
安装pytorch1.13.1
# 安装torch pip install /public/software/apps/DeepLearning/whl/torch-1.13.1a0+git4c8a1fe.abi0.dtk2304-cp39-cp39-linux_x86_64.whl 除了与GPU相关的包(比如torch和torchvision),其他包可直接通过pip install从网上进行安装,无需曙光云本地提供。例如以下安装numpy(注意先激活环境)
# 安装numpy pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple 安装完毕后,可通过pip list所安装的包,到此步只是完成安装工作。
pip list 1.1.3 节点申请、环境变量配置(测试能否调用到dcu)
查看所在队列
whichpartition 申请并登录计算节点,进行测试
salloc -p kshdtest -N 1 -n 8 --gres=dcu:1 登录计算节点
# ssh 节点 ssh b02r1n02 切换rocm编译器版本(加载dtk23.04),跟后续使用GPU的关系很大
大模型并行训练 1. 背景 大语言模型(Large Language Mode,缩写LLM)是一种人工智能模型,旨在理解和生成人类语言。通过在大量文本数据上进行训练,可执行广泛的任务(包括文本总结、翻译、情感分析等等)。其规模庞大,包含数十亿的参数,来学习复杂的模型结构。随着ChatGpt的兴起,大语言模型进入百花齐放的发展阶段,各行各业都将注意力集中到通用大模型和垂直领域大模型的研发当中。目前,典型的大模型代表如下:
大模型名称
所属公司
chatgpt系列(gpt3.5/gpt4)
OpenAI
文心一言
百度
Baichuan7B/13B
百川智能
Qwen7B/14B
阿里云
LLaMA/LLaMA2
Meta
ChatGLM
智谱AI
以上大模型在通用领域(例如介绍下中国四大名著)有着不俗的效果,但在特定领域效果一般,好在可以通过搜集领域内数据对大模型进行微调(SFT)和训练预训练模型(PRE)来实现。主要目标是通过sft或pre得到的大模型效果上超过传统深度学习方法且超过开源通用大模型。本文基于此介绍下大模型训练所涉及的单机多卡、多机多卡等概念,以及并行训练的相关策略。
2. 概念介绍 2.1 预训练模型(Pre)和大模型微调(Sft) 预训练模型(Pretrained Models)和大模型微调(SFT,Scaled Fine-Tuning)是两种常见的深度学习技术。
预训练模型是指在大规模数据集上进行事先训练的深度神经网络模型。这些模型通常使用无监督学习方法,如自编码器、生成对抗网络或其他无监督学习方法来实现,并在大量未标记的数据上进行训练。预训练模型的目标是学习到数据的潜在表示,以捕捉数据中的统计特性和结构,从而使得在特定任务上的微调更加高效。它们能够学习到通用的特征表示,使得在特定任务上的微调更加高效。
相比之下,大模型微调是指在预训练模型的基础上,使用特定任务的有标签数据进行进一步的微调。在微调过程中,预训练模型的权重会被调整以适应特定任务的要求。大模型微调通常需要较少的标注数据,因为预训练模型已经学习到了许多通用的特征和知识,可以在特定任务上进行迁移学习。
两者的区别在于预训练模型是在大规模数据上进行无监督学习,目标是学习到通用的特征表示;而大模型微调是在预训练模型的基础上,使用有标签数据进行有监督学习,目标是在特定任务上进行优化和调整。预训练模型可以看作是一种通用的知识库,而大模型微调则是将这个知识库应用到具体任务中的过程。
图1 pre和sft
总体来说,如果目标是解决具体领域的某些具体的任务,且基模型已经具备了该领域的基础元知识,用SFT微调可以满足需求,SFT主要解决的问题是让基模型能够理解具体的任务指令。如果要解决的问题是泛领域的多目标任务,且基模型未具备目标领域的基础元知识,这时就需要先进行Pre-train预训练,让基模型充分吸收目标领域的基础语料,即丰富基模型的元知识后,再基于预训练后得到的新的基模型进行SFT,对齐想要解决问题的指令。
2.2 并行计算 在大模型训练中,为了加快训练速度并处理大量数据,通常会使用并行计算技术。并行计算是指将计算任务(通常指模型和数据)分解成多个子任务,并分配给不同的计算设备进行处理。本章就并行计算中所涉及的数据并行、模型并行、分布式训练(例如DP,DDP,DeepSpeed等)进行介绍。
2.2.1 数据并行 数据并行将大规模的大规模的数据集分成N份,每一份分别装在到N个GPU节点中。同时每个GPU节点持有一个完整的模型副本,分别基于每个GPU中的数据去进行梯度求导。最后,通过通信机制将梯度进行聚合,并更新模型参数。
数据并行通常有三种方式:
以参数服务器GPU0对每个GPU中的梯度进行累加。最后,再将GPU0聚合后的结果广播到其他GPU节点进行更新。以CPU作为参数服务器进行梯度的聚合和更新,但这种方式通常比较慢。通常情况下,GPU与CPU之间通信使用PCIe,而GPU与GPU之间通信使用Nvlink(前者更常用,后者速度更快)。将参数服务器分布在所有GPU节点上面,每个GPU只更新其中的一部分梯度。 值得注意的是,数据并行不仅仅指对训练的数据进行并行操作,还是对网络模型梯度、权重参数、优化器状态等数据进行并行。
图2 数据并行
2.2.2 模型并行 与数据并行相同的是,模型并行也是将一个大型模型拆解成多个子模型,并将这些子模型分配给不同的计算设备进行并行计算。每个计算设备负责计算模型的一部分,并将结果传递给其他设备进行进一步处理。
图3 模型并行
上图中,把模型拆成了Machine1~4,并可以看成两种切分方式:(1)水平切分(2)垂直切分。这里,也可以把模型的垂直切分看成Pipeline并行,因为垂直切分模型的时候,中间的某一层计算需要上一层所有的数据都计算完才能开始自己的计算,如果有数据未完成,整个计算都会延迟。所以,和数据并行不同的是,模型并行带来的通信开销和同步消耗会远超过数据并行,且消耗是完全不在一个数量级上。
这里,可以回顾下最早提出模型并行的网络AlexNet:
图4 AlexNet网络结构
由于当时(2012年)的设备资源更不上神经网络的参数量,AlexNet不得不进行模型的并行计算(水平切分)。由上图,上下两部分的网络结构是一样的,采用两块GPU进行模型和数据的并行计算,并且GPU只在最后的全连接层进行通信。因为是单机,所以模型之间采用共享内存进行通信,如果分布在通过网络连接的多台机器上,那么就需要考虑延迟、带宽和消息速率,这也是分布式训练要着重要解决的问题。
模型并行要解决的一个问题就是神经网络中的每一层都对它前面一层具有数据依赖性,也就是说,仅仅把一些层放在不同的设备中并不意味着它们可以并行计算,甚至还有可能会起到相反的效果,当设备2等待设备1的数据的时候,设备2就处于空闲状态。所以真正的模型并行,意味着把模型按照一种方式拆分之后,每个部分都可以同时进行计算,顺序无关紧要。
当然,也有论文One weird trick for parallelizing convolutional neural networks提出优化方案:在卷积层上采用数据并行(计算量大,参数量少),在全连接层上采用模型并行(计算量小,参数量大),但考虑到模型并行的通信成本,并不建议用太多机器。
通常在大模型训练任务中采用DeepSpeed中的3D并行技术(数据并行,流水线并行和张量切片模型并行)来实现万亿参数模型训练,提高了显存扩展性和吞吐量扩展效率。
2.2.3 分布式训练(DP,DPP,DeepSpeed+Zero) DP DP(torch.nn.DataParallel)作为pytorch中常用也是较为简单的API,其代码量少,原理也较为简单。但DP只支持单机多卡,计算过程如下:
基于matlab GUI的图像处理,功能包括图像颜色处理(灰度图像、二值图像、反色变换、直方图、拉伸变换);像素操作(读取像素、修改像素)、平滑滤波(均值平滑、高斯平滑、中值平滑)、图像锐化(robert交叉梯度锐化、sobel梯度锐化、拉普拉斯锐化)、图像边缘检测(拉普拉斯算子、sobel算子、prewitt算子、roberts算子、canny算子)。通过GUI以可视化的形式展现。数据可更换自己的,程序已调通,可直接运行。
81像素操作平滑滤波边缘检测 (xiaohongshu.com)
一、初识定时器TIM 定时器就是计数器,定时器的作用就是设置一个时间,然后时间到后就会通过中断等方式通知STM32执行某些程序。定时器除了可以实现普通的定时功能,还可以实现捕获脉冲宽度,计算PWM占空比,输出PWM波形,编码器计数等。
STM32共11个定时器,2个高级控制定时器TIM1和TIM8,4个通用定时器TIM2~TIM5,两个基本定时器TIM6和TIM7,两个看门狗定时器和一个系统滴答定时器Systick.
高级定时器TIM1和TIM8的时钟由APB1产生,其它六个通用定时器的时钟由APB2产生。它们的最大频率都可以配置成系统时钟的频率。
定时器种类位数计数模式捕获/比较通道应用场景通用定时器
TIM2~TIM516向上,向下,双向4定时计数,PWM,输入捕获,输出比较高级定时器
TIM1和TIM816向上,向下,双向4在通用的基础上,多了刹车信号输入,死区时间互补输出等工业电机功能基本定时器
TIM6和TIM716向上,向下,双向4定时计数 二、基本定时器 (1)计数功能原理 在上一期文章提到,时钟树提供稳定频率的方波信号,APB1上的时钟线连接了基本定时器和通用寄存器,APB2上的时钟线连接了高级定时器。
对于实现计数功能,只需要一个寄存器就可以满足,寄存器只需要读到时钟信号的上升沿数值就加1。假如72MHZ的时钟信号作为输入,当该寄存器数值累加到7.2*10^7,就代表时间过去了1秒。但是寄存器通常只有16bit,最多能计数 65536个数。因此在该寄存器前面还要加一个类似的计数器,当计数满足条件时才往后续电路发送高电平,预分频器就可以充当这个角色,其本质也是一个16bit的计数器。当只需要将其设置为n-1,就可以进行n分频,从0开始计数,一直计数到n-1才会向后续电路发送高电平。预分频器最多可以进行65536分频。因此一个由预分频器和一个计数器组合成的定时器,最多可以计数65536^2次。m个定时器串联,就可以计数65536^(2*m)次。 (2) 自动重装载寄存器 自动重装载寄存器,它的作用就是实时监控计数器的值是否与自己的值相同。当计数器的值与自己的值相同时,便将计数器重置为0,并触发定时器更新中断。
(3)影子寄存器 所谓的影子寄存器就是某个寄存器的拷贝。在上图中工作在一线的预分频器和自动重装载寄存器其实都是自己的影子寄存器。当定时器正在工作时,如果重新设置预分频器值或者重新这是自动重装载寄存器的值,那么只有当计数器和自动重装载寄存器的值一样时才会将新值更新到自身影子寄存器中。也就是给定时器设置的新参数值要等下个计数周期才生效。
自动重装载寄存器可以根据程序员选择是否开启影子寄存器。如果不开启,那么将自动重装载寄存器数值调小时,可能会错过计数器的值,使计数器一路上到65536才会归0。
三、定时程序 (1)准备工作 为了发送数据进行模拟,需打开USART2用于设置模式为“异步”,在NVIC Settings中打开中断,打上√,在DMA Settings,打开DMA传输功能,添加传输通道。
为提高计数精度,将外部时钟源设置为"晶振",在时钟设置界面中的HCLK的频率设置为72MHZ,自动调整其它器件的时钟频率。
对于我使用的STM32F108T6芯片只有4个定时器,即1个高级,3个通用寄存器。虽然没有基本定时器,但是这些定时器都包含了基本定时器功能。只需要对定时器的时钟源选择 Internal Clock (内部时钟源)就算打开了定时器。因为本次模拟的时钟频率是72MHZ,设置预分频器7200,自动重装载寄存器为10000,那么完成一个周期的计数就是1s,也就是1s触发一次定时器更新中断。同第一步类似,TIM也可以开启中断和DMA通道。保存并生成代码。
(2)实现定时任务和获取计数器数值: 以下示例代码为开启TIM中断和USART2中断实现,以及开启了自动重装载寄存器的影子寄存器
1.开启定时器 HAL_TIM_Base_Start(&htim); //用阻塞的方式开始定时器
HAL_TIM_Base_Start_IT(&htim); //用中断(非阻塞)的方式开始定时器
HAL_TIM_Base_Start_DMA(&htim); //用DMA(非阻塞)的方式开始定时器
2.中断回调函数 在路径 ~/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c中
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
当计数器数值和自动重装载寄存器值一样时调用
3.读写定时器中寄存器的宏定义操作 __HAL_TIM_GET_ANTORELOAD //获取自动重装载寄存器数值
__HAL_TIM_SET_ANTORELOAD //设置自动重装载寄存器数值
__HAL_TIM_GET_COUNTER //获取计数器数值
__HAL_TIM_SET_COUNTER //设置计数器数值
__HAL_TIM_SET_PRESCALER //设置预分频器数值
4.示例代码 /* USER CODE BEGIN Includes */ #include <string.h> #include <stdio.h> /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ TIM_HandleTypeDef htim4; UART_HandleTypeDef huart2; DMA_HandleTypeDef hdma_usart2_rx; DMA_HandleTypeDef hdma_usart2_tx; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_DMA_Init(void); static void MX_USART2_UART_Init(void); static void MX_TIM4_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ char message2[]="
知识图谱,也称为语义网络,表示现实世界实体(即对象、事件、情境或概念)的网络,并说明它们之间的关系。这些信息通常存储在图形数据库中,并可视化为图形结构,从而引发了术语知识“图”。
知识图谱由三个主要部分组成:节点、边和标签。任何物体、地点或人都可以是节点。边定义节点之间的关系。例如,节点可以是客户(如 IBM)和代理机构(如 Ogilvy)。一个优势是将这种关系归类为 IBM 和奥美之间的客户关系。
A代表主语,B代表谓语,C代表宾语
还值得注意的是,知识图谱的定义各不相同,并且有研究(链接位于 ibm.com 之外),这表明知识图谱与知识库或本体论没有什么不同。相反,它认为这个词是在2012年由谷歌的知识图谱推广的。
本体 本体论在知识图谱的上下文中也经常被提及,但同样,关于它们与知识图谱的区别仍然存在争议。最终,本体用于创建图中实体的正式表示。它们通常基于分类法,但由于它们可以包含多个分类法,因此它保持自己的单独定义。由于知识图谱和本体以类似的方式表示(即通过节点和边),并且基于资源描述框架 (RDF) 三元组,因此它们在可视化中往往彼此相似。
本体论的一个例子可能是,如果我们检查一个特定的场所,比如麦迪逊广场花园。本体使用变量(如时间)来区分该位置的事件。像纽约游骑兵队这样的运动队,在一个赛季中有一系列的比赛将在该竞技场举办。它们都是曲棍球比赛,而且都位于同一个场地。但是,每个事件都按其日期和时间进行区分。
Web 本体语言 (OWL) 是被广泛采用的本体的一个例子,它得到了万维网联盟 (W3C) 的支持,W<>C 是一个倡导开放标准以维护互联网寿命的国际社区。归根结底,这种知识组织得到了数据库、API 和机器学习算法等技术基础设施的支持,这些基础设施的存在是为了帮助人们和服务更有效地访问和处理信息。
知识图谱的工作原理 知识图谱通常由来自各种来源的数据集组成,这些数据集的结构通常不同。架构、标识和上下文协同工作,为各种数据提供结构。架构为知识图谱提供框架,标识对基础节点进行适当分类,上下文确定该知识存在的设置。这些组件有助于区分具有多种含义的单词。这使得产品,如谷歌的搜索引擎算法,可以确定苹果品牌和苹果水果之间的区别。
由机器学习驱动的知识图谱利用自然语言处理 (NLP) 通过称为语义丰富的过程构建节点、边缘和标签的综合视图。引入数据时,此过程允许知识图谱识别单个对象并了解不同对象之间的关系。然后将这些工作知识与其他数据集进行比较和整合,这些数据集在性质上是相关且相似的。一旦知识图谱完成,它允许问答和搜索系统检索和重用给定查询的综合答案。虽然面向消费者的产品展示了其节省时间的能力,但相同的系统也可以应用于商业环境,消除了手动数据收集和集成工作,以支持业务决策。
围绕知识图谱的数据集成工作还可以支持新知识的创建,在以前可能没有实现的数据点之间建立联系。
知识图谱使用案例 有许多流行的、面向消费者的知识图谱,它们为整个企业的搜索系统设定了用户的期望。其中一些知识图谱包括:
DBPedia 和 Wikidata 是两种不同的知识图谱,用于 Wikipedia.org 数据。DBPedia 由来自维基百科信息框的数据组成,而维基数据则侧重于二级和三级对象。两者通常都以 RDF 格式发布。谷歌知识图谱通过谷歌搜索引擎结果页面(SERP)表示,根据人们搜索的内容提供信息。该知识图谱由超过 500 亿个对象组成,数据来自 Freebase、维基百科、CIA World Factbook 等。 但是,知识图谱在其他行业也有应用,例如:
零售:知识图谱一直用于追加销售和交叉销售策略,根据个人购买行为和人口统计群体的流行购买趋势推荐产品。娱乐:知识图谱还用于基于人工智能 (AI) 的内容平台(如 Netflix、SEO 或社交媒体)的推荐引擎。根据点击和其他在线互动行为,这些提供商会推荐新内容供用户阅读或观看。金融:该技术还被用于金融行业的了解你的客户 (KYC) 和反洗钱计划。他们协助金融犯罪预防和调查,使银行机构能够了解其客户的资金流动并识别不合规的客户。医疗:知识图谱还通过组织和分类医学研究中的关系使医疗保健行业受益。这些信息通过验证诊断和根据个人需求确定治疗计划来帮助提供者。
1、赛事背景 来到泾阳,就来到了中国大地原点;
来到泾阳,就来到了陕西的“白菜心心”;
来到泾阳,就来到了具有2000多年的历史长河;
泾河水缓缓流,流过郑国渠;
泾河水缓缓流,流过泾河床;
泾河水缓缓流,灌溉三秦沃野;
泾河水缓缓流,讲述着古人的大气与智慧
1.1 赛事成绩 半马男子:
1、张校瑞,1小时5分49秒
2、王涛
3、杨博文
半马女子:
1、王蕾,1小时20分36秒
2、程敏
3、张军艳
2、赛前目标及准备 赛事领物也在泾阳县城,参赛选手都获赠2张泾阳郑国渠门票,还是比较有价值的。
第一次来泾阳县城,看了马拉松赛道后,非常平坦的路线,没有大坡,很适合PB。
周六还下雪了,好在中午就停了,看了泾阳的天气预报,比赛的周日是晴天,温度是0度~12度,在周六晚上收到了组委会的短信,因为气温比较低,为了安全起见,从8点的起跑时间延迟到10点开始。这个举措也是情理之中的,毕竟同一天比赛的延安新区马拉松因为下大雪已经取消了,下的有多大,路面都有积雪。
3、 赛事过程 3.1 赛前 周日早上9点坐车来到泾阳县城,交警在指挥交通,赛道附近的禁行区域改为临时停车场,这个决定非常赞,不少从外地过来的运动员很苦恼停车地方。
3.2 赛前热身 天气虽然很冷,到了9点多也有6度了,11点气温会升到13度,也不冷了,选择短袖短裤出战。
看着大多数人都准备很好,带了长袖长裤,穿的紧身裤,穿短裤的人都很少,我还真是有点彪,不过气温的上升证明了我的选择没错。
进入检录区后拉伸肌肉,包括小腿后侧、大腿后侧、髂筋束、背部肌肉等都要充分拉伸,因为天气冷,安全无伤完赛才是最关键的。
这次比赛,半马人员有5000人,分了AB区,A区标准是PB1小时45分以内,我自然就从B区出发,出发前我挤一挤,挤到B区前面,到时候容易跑开,不会被堵着。
3.3 赛中 10点准时起跑了。其实路面挺宽敞的,架不住人比较多,起跑后只能慢悠悠的跟跑,跑了1公里后来到双向四车道的大路上了,跑的就不拥挤了。大部分的路在县城南郊的大路上跑,观众不多,道路没有坡度,吹点小风,选择跟一个配速5分左右小团队,速度可以稳定,跑起来也不无聊。
跑到15公里,该吃最后一根能量胶了,高能量的能量胶很浓稠,撕开能量胶一挤,撒了一小半出去,我丢,什么情况,拿错了能量胶,带了一个等渗能量胶,这种等渗能量胶含水量比较大,补给的能量不多,还在担心这点能量够不够,其实跑到最后都没有掉速。后半程均速达到4分45秒/公里。
跑到18KM,终于追上了145的兔子,也是第一次遇见145的兔子,跟着他们跑能顺利145完赛,但是跑着感觉体力还行,就超过了兔子。
跑到快20公里,算是跑进了县城,观众多了很多,还有很多小朋友,在为我们加油,突然就感觉能量加满,状态回升。
跟小朋友击掌庆祝,不知道在他们心中有没有种下热爱运动的种子。
看到了21公里的指示牌,意味着这次比赛即将完成,冲线成绩达到1小时44分多,净成绩达到1小时43分多,比上次最好成绩PB了8分多钟,非常可观的成绩。
4、赛事体验和赛后感想 4.1赛事体验: 1、赛前预留大片禁行道路供停车,体验非常棒;
2、提前一天通知发枪时间延迟,通知很及时,避免去太早冷着;
3、赛道很平坦,适合PB冲击好成绩;
4、观众热情加油,感染力很强
5、赛道上水的补给很多,避免取水拥挤
PB赛道不是吹的
4.2完赛包 5、下一步计划 冬天来了,启动冬训,锻炼长距离有氧能力,储备能量,来年达成半马成绩PB,完成至少一场全马比赛。
参考:
[1] 雅泰乳业·2023泾阳郑国渠半程马拉松
我的个人博客主页,欢迎访问 我的CSDN主页,欢迎访问 我的GitHub主页,欢迎访问 我的知乎主页,欢迎访问
1.Makefile的功能和原理 Makefile是一种用于自动化构建和管理软件项目的工具,由make命令执行。Makefile文件描述了整个工程所有文件的编译顺序、编译规则,Makefile有自己的书写格式、关键字、函数。
Makefile的产生原因是为了解决编译过程中的依赖关系问题,使得在开发过程中能够轻松地进行代码的编译、链接和部署。在链接过程中,如果我们链接的目标文件过多,那么挨个指出目标文件名称,就很不方便,所以,使用makefile可以批量,流程的指出连接
2.Linux平台的Makefile用法 在Linux开发中,Makefile文件给我们带来很多的便利。在Linux系统下并不会像Windows那么多开发工具,工程源文件的编写往往是使用一个简单的编辑器(VIM),然后通过Makefile文件进行自动化编译。
make命令是读取当前目录下的文件名为makefile的文件,然后按照makefile的文件内容将其项目一次性编译。
当我们输入make命令的时候,make命令会在当前目录下找寻名字是Makefile或者makefile的文件。
也可以使用-f参数指定目标文件。
make -f Makefile.typename 3.Windows平台的Makefile用法 在Windows平台可以使用Makefile批量链接编译和gcc,g++等编译器的帮助下,不需要下载vs等工具进行编程。
1)安装对应语言的编译器 以c语言为例,gcc编译器下载,TDM-GCC,打开根据自己电脑的类型选择合适的程序,
gcc的安装与下载可以找教程。注意安装路径不要有中文
2)检查编译器安装和环境变量是否成功设置 cmd窗口输入gcc -v
输入mingw32-make -v
4.Makefile的基本语法 1)基本格式 目标文件:依赖文件
【tab】命令
命令都需要以tab开始,且不能用四个空格替代。
hello:hello.o g++ hello.o -o hello hello.o:hello.S g++ -c hello.S -o hello.o hello.S:hello.i g++ -S hello.i -o hello.S hello.i:hello.cpp g++ -E hello.cpp -o hello.i 2)赋值 = 替换
+= 追加
:= 恒等于
3)通配符 %.o 任意以.o结尾的文件
*.o 所有以.o结尾的文件
4)特殊 $^ 所有依赖文件
$@ 所有目标文件
$< 所有依赖文件的第一个文件
5).PHONY次目标(附加处理) 固定以.
基本思想:学习一下cuda编程,随手记录一下 如何使用grind block thread 线程块和编号的概念和应用方法
一、使用工具clion+ubuntu
CMakeLists.txt
cmake_minimum_required(VERSION 3.0) project(untitled18) set(CMAKE_CXX_STANDARD 14) find_package(CUDA REQUIRED) include_directories(${CUDA_INCLUDE_DIRS}) cuda_add_executable(untitled18 main.cu) main.cu
#include <iostream> #include <stdio.h> #include "cuda.h" __global__ void hello_from_gpu() { int x=blockDim.x*blockIdx.x+threadIdx.x; printf("blockIdx.x %d threadIdx.x %d x %d\n",blockIdx.x,threadIdx.x,x); //printf(" %d \n",x); //printf(" hello world\n"); } int main() { hello_from_gpu<<<2,9>>>();// grid_dim block_dim ===> block_id thread_id cudaDeviceSynchronize(); return 0; } 测试结果
/home/ubuntu/CLionProjects/untitled18/cmake-build-debug/untitled18 blockIdx.x 0 threadIdx.x 0 x 0 blockIdx.x 0 threadIdx.x 1 x 1 blockIdx.
ECDH X25519是一种快速密钥交换的算法,使用GO语言实现其密钥交换流程。
Go语言版本1.20,之前版本的一些方法已经被弃用
[root@node2 client]# go version go version go1.20.6 linux/amd64 client.go package main import ( "bytes" "encoding/hex" "encoding/json" "fmt" "math/rand" "net/http" "golang.org/x/crypto/curve25519" ) type KeyExchangeRequest struct { ClientPublicKey string `json:"public_key"` } type KeyExchangeResponse struct { ServerPublicKey string `json:"public_key"` } func generateKeyPair() ([]byte, []byte) { var privateKey [32]byte for i := range privateKey[:] { privateKey[i] = byte(rand.Intn(256)) } var publicKey [32]byte curve25519.ScalarBaseMult(&publicKey, &privateKey) return privateKey[:], publicKey[:] } func ECDH_sharekey(privateKey, peerPublicKey []byte) ([]byte, error) { //var sharedKey [32]byte // 使用私钥和对方的公钥计算共享密钥 sharedKey, err := curve25519.
axios axios请求方法有get、post、put、patch、delete
get 作用:获取数据
默认’Content-Type’: ‘application/json’
不需要传参 axios.get('/url/adrress') // 发请求 .then((res)=>{ // 处理响应数据 console.log(res.data) }).catch((err) => { consloe.log(err) //处理错误 }) 2.要传参 params 会将传参拼接到请求地址url中:http://localhost:8080/url/address?id=12
(a)对象写法:
传参格式: {params: param}
axios.get('/url/adrress',{ params: { id: 12 } }).then((res)=>{ console.log(res) }) 或写为:
axios({ method: 'get', url: '/url/adrress', params: { id: 12 }, }).then((res)=>{ console.log(res) }) (b)字符串拼接写法:
axios({ method: 'GET', url: '/url/adrress?id=' + '12', }).then((res)=>{ console.log(res) }) post 作用: 提交数据(表单提交+ 文件上传)
post接受三个参数,url,data,config
[1] 传参格式为raw,即JSON格式 (application/json) 如果你想以JSON格式发送数据,你可以设置请求头为’application/json’,并将数据作为JSON字符串发送。
起因: 连接 Redis 的时候报错:由于目标计算机积极拒绝,无法连接
系统: Windows
解决方法:
按照下列步骤操作
进入 Redis 安装目录。打开 CMD运行 redis-server.exe redis.windows.conf
到这里就好了。
测试方法:
在 redis 安装目录,重新打开一个 CMD运行 redis-cli.exe -h 127.0.0.1 -p 6379输入 set a 123 设置值输入 get a 看是否获取到值 下面的可以不看
如果是使用 phpstudy 的话,按照下列步骤。
安装 redis 客户端
连接 redis
redis客户端 -> 管理 -> Redis servers 右键 -> 添加服务 -> 输入信息(信息在 redis 管理里面可以看到)
进入 phpstudy 首页, 启动 redis 就可以了
`Q_DISABLE_COPY(QGraphicsEllipseItem)` 是一个宏,用于禁用 `QGraphicsEllipseItem` 类的拷贝构造函数和拷贝赋值运算符。
在C++中,如果一个类没有显式定义拷贝构造函数和拷贝赋值运算符,编译器会自动生成默认的拷贝构造函数和拷贝赋值运算符。
这些默认的函数执行的是浅拷贝操作,即将对象的成员变量逐个拷贝到新对象中。
但有些类不适合进行拷贝操作,比如涉及到资源管理的类,如果进行浅拷贝可能导致资源重复释放或者内存泄漏等问题。
`Q_DISABLE_COPY` 宏的作用就是禁用类的拷贝构造函数和拷贝赋值运算符,以防止误用和不适当的拷贝操作。在上述代码中,`Q_DISABLE_COPY(QGraphicsEllipseItem)` 表示禁用了 `QGraphicsEllipseItem` 类的拷贝构造函数和拷贝赋值运算符。
通过禁用拷贝操作,可以在编译阶段防止对该类进行拷贝操作,以确保对象的正确使用和资源管理。
起因: 使用 redis 时候,thinkphp 报错。
解决方法: 打开 php.ini 文件,增加 extension=php_redis.dll 即可
各参数说明 ## 属性 dragableRange: 拖动范围。parent 父级 window 可视窗口 dragable: 是否可拖动。默认 true position:初始位置。[object Object] top、left、right、bottom indent:是否需要缩进。默认 false indentDelayTime:延时缩进。单位:ms, 为 0 则不缩进 indentDistance:缩进距离。单位:px needNearEdge:拖动悬浮球后是否需要贴边。默认:false nearEdgeTransition: 贴边过渡动画,transition 属性值。默认:'all ease 0.3s' nearEdgeDirection:拖动悬浮球后贴边方向。默认贴边方向为距离最近的方向。 indentNearEdge:悬浮球贴边后是否需要缩进(此时缩进方向为贴边的方向)。默认 false indentNearEdgeDelay: 悬浮球贴边后延时缩进。单位:ms,默认 1000,为 0 则不延时 ## 事件 touchFunc:点击悬浮球后回调事件 ## slots slotsDirection:插槽内容方向,默认置于悬浮球右边(如不设置且已开启 needNearEdge,则自动根据贴边情况来改变方向) 如果有用的话,可以点个赞吗?
组件实现 <template> <div class="suspend_ball_wrapper" :style="{ position: dragableRange === 'window' ? 'fixed' : 'absolute', ...position, }" > <div v-if="dragable" class="suspend_ball" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend" > <div class="slots" :class="[slotsDirectionData]"> <slot /> </div> </div> <div v-else class="
前言: Sourcetree 作为 免费的 Git 客户端工具,有许多优点。Sourcetree 简化了与Git存储库交互的方式,因此我们可以专注于编码。通过 Sourcetree 简单又快捷的管理我们 的存储库。
下载安装包 进入 官网 选择Windows系统的安装包 ,点击下载 ( 建议下载之前的老版本,我这里演示的是 3.4.9 版本)
运行安装包 这里我下载的 是 3.4.9 版本的, 双击运行 .exe 文件
安装过程 运行安装包的过程可能会比较慢 ,要耐心等待 依次点击 下一步 或者 跳过
破解账户登陆 Registration 这一步直接 点击右上角的 ‘x’ 号就行了 或者这一步可以 点击右下角的跳过 ,然后下面进行破解账户登录
在电脑目录下 搜索 %LocalAppData%\Atlassian\SourceTree\ 修改里面的 accounts.json 文件 ,没有这个文件就自己新创建一个(可以创建 .txt 文件 然后 修改文件后缀变成 .json)
account.json 文件内容如下
[
{
"$id": "1",
"$type": "SourceTree.Api.Host.Identity.Model.IdentityAccount, SourceTree.Api.Host.Identity",
"Authenticate": true,
"HostInstance": {
"$id": "
NGINX梳理脚本 在这个脚本中,我们假设您的 Nginx 配置文件都存放在同一个目录下(在target_directory中指定),并且这些配置文件都以.conf扩展名结尾。脚本会使用每个配置文件,提取其中的指令和参数,并输出到控制台。
请确保将target_directory替换为您实际的配置文件所在目录。
这只是一个简单的示例,实际上,您可能需要根据您的具体情况对脚本进行更多的定制和改进。例如,您可以考虑处理包含指令的情况,处理蚀刻块,实现更高级的分析和报告功能等。
#! /usr/bin/python3 import os def extract_directives(file_path): directives = [] with open(file_path, 'r') as f: lines = f.readlines() for line in lines: line = line.strip() if line.startswith('#') or not line: continue parts = line.split() directive = parts[0] arguments = parts[1:] if len(parts) > 1 else [] directives.append((directive, arguments)) return directives def analyze_config_files(directory): config_files = [f for f in os.listdir(directory) if f.endswith('.conf')] result = {} for file_name in config_files: file_path = os.
搭建RabbitMQ Server高可用集群 目录 文章目录 搭建RabbitMQ Server高可用集群目录1.背景介绍2.环境介绍3 架构视图4 RabbitMQ和Erlang的版本5 准备工作6 搭建RabbitMQ Server单机版7 RabbitMQ Server高可用集群的相关概念7.1 设置集群目的7.2 集群配置方式7.3节点类型7.4 Erlang Cookie7.5镜像队列 8 搭建RabbitMQ Server高可用集群9 搭建HAproxy负载均衡(可选)10 RabbmitMQ搭建踩坑 1.背景介绍 由于客户的成本预算不足,不想在华为云购买单独的MQ的产品,只能在华为云购买云服务器,然后自己搭建RabbitMQ Server集群。但也是预算不足,仅有两台服务器,还是要集群。
2.环境介绍 RabbitMQ-nodeIP地址工作模式操作系统EIPhy-mq-0001172.16.1.244(内网)DISKCentOS7.9116.205.189.205hy-mq-0002172.16.1.86DISKCentOS7.9 3 架构视图 这个网络上找的一个高可用集群架构,仅供参考,在云上的负载可以使用LB来代替,但必然会造成成本的增加,最后还是需要以客户的意愿会导向。
4 RabbitMQ和Erlang的版本 由于客户所需要的版本是指定的,又是在rhel系列上,所以从官网直接找出对应的版本进行下载下来,有各种不同的方式下载,下面是下载的地址,本实验采用的rabbitmq-server-3.8.5,erlang-23.2.7-2。
下面是下载的官网。
rabbitmq官网 https://www.rabbitmq.com/ rabbitmq-下载的地址 https://github.com/rabbitmq/signing-keys/releases/ erlang官网 https://www.erlang.org/ erlang下载地址 https://www.erlang.org/downloads 5 准备工作 首先将两台的服务器的hostname的名字设置,你需要的nodename,命令如下:
hostnamectl set-hostname NAME 接着将修改两台的/etc/hosts文件
[root@hy-mq-0001 ~]# cat /etc/hosts ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 127.0.0.1 hy-mq-0001 hy-mq-0001 172.16.1.244 hy-mq-0001 172.16.1.86 hy-mq-0002 6 搭建RabbitMQ Server单机版 以下使用mq-0001服务作为单机版的演示实例。
参考:https://blog.csdn.net/yeahPeng11/article/details/120394276
https://blog.csdn.net/yeahPeng11/article/details/120330630
https://www.cnblogs.com/CF1314/p/16580232.html
通过现有注解,明白注解是什么东东。
在 SpringBoot中,我们会用到返回值@ResponseBody注解。@ResponseBody返回的是字符串类型数据。
@Target(ElementType.METHOD) //作用于方法上 @Retention(RetentionPolicy.RUNTIME) //作用在运行时 @Documented //生成到文档里 public @interface ResponseBody { String value(); } 元注解
用于定义注解的注解,包括@Target、@Retention、@Documented、@Inherited。
@Target(目标)
Target意为 目标,指定定义的注解起作用的场景。限定注解的使用场景、使用对象等,注解的使用变得十分明确。它的取值由ElementType类提供。
ElementType.TYPE :作用于类、接口(包括注解类型接口)或者枚举类型。 ElementType.FIELD:作用于字段属性。 ElementType.METHOD:作用于方法。 ElementType.PARAMETER:作用于参数。 ElementType.CONSTRUCTOR:作用于构造器。 ElementType.LOCAL_VARIABLE:作用于局部变量。 ElementType.ANNOTATION_TYPE:作用于注解。 ElementType.PACKAGE:作用于包。 ElementType.TYPE_PARAMETER:作用于类型参数(since jdk1.8)。 ElementType.TYPE_USE:作用于使用的类型(since jdk1.8)。 ElementType.MODULE:作用于模块声明(since jdk9)。 在@ResponseBody中,ElementType.METHOD 代表作用在方法上。 @Retention(保留)
Retention意为 保留,解释这个注解的保留的时间(存活的时间)。它的取值由RetentionPolicy类提供。
RetentionPolicy.SOURCE:注解只在源码阶段保留,将被编译器丢弃。
RetentionPolicy.CLASS:默认行为,注解只被保留到编译进行的时候,不会被加载到 JVM 中。
RetentionPolicy.RUNTIME:注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,程序运行时可读取,可被反射读取到。
Java代码保留(存活)的时间段分为 source -> class -> runtime 三个。
@ResponseBody 注解中,@Retention(RetentionPolicy.RUNTIME) 代表作用在运行时。
@Documented(文档)
Documented意为 文档,解释此注解可以生成在 Javadoc 中。
win+R 输入cmd
进到本地签名文件的目录下
输入
keytool -list -v -keystore <keystore文件路径> -alias <别名> 请将 <keystore文件路径> 替换为您的密钥库文件(通常是 .jks 或 .keystore 文件)的路径,而 <别名> 则是您在密钥库中用于识别证书的别名。
假设您的密钥库文件名为 mykeystore.jks,并且您想要获取别名为 myalias 的证书的签名信息的 MD5,那么命令应该如下所示:
keytool -list -v -keystore mykeystore.jks -alias myalias 运行命令后,您会看到与所选别名相关的证书的详细信息,包括签名算法和证书指纹。在其中的证书指纹部分,您可以找到以 MD5 开头的指纹值。
MD5去掉冒号就是平台所需的应用签名
参考:微信开放平台Android平台应用签名怎么填写
建议:
建议发布应用保存好密钥库文件(通常是 .jks 或 .keystore 文件)和应用签名,因为生成新的密钥库文件需要修改应用签名,而且会导致之前发布应用的一些相关内容丢失
生成新的密钥库文件并更改应用的签名将会带来一些潜在的影响和丢失,主要包括以下几个方面:
签名验证:应用的签名用于验证应用的完整性和身份。如果您生成了新的密钥库文件并更改了应用的签名,那么之前发布的应用将无法通过验证,您需要向应用商店、推广平台或其他相关服务注册并重新发布新的应用。
用户数据:如果您使用了基于应用签名的加密或者身份验证机制,更改应用签名可能导致无法访问之前加密的数据或者导致用户在应用中的身份验证失败。
应用更新:如果应用使用了应用签名作为版本管理的一部分,更改签名将导致与旧签名不兼容。这意味着您将无法通过应用商店的自动更新机制发布新版本,而需要用户手动下载和安装新版本。
用户评级和评论:通过生成新的密钥库文件和更改应用签名,您可能会丢失应用商店中关于旧版本应用的用户评级、评论和下载量等相关内容。
要确保减少这些丢失的影响,建议您在生成新的密钥库文件和更改应用签名之前进行充分的备份和测试,并向用户提供适当的迁移和更新的指导。此外,如果您的应用依赖于与应用签名相关的特定服务或功能,请先了解对现有用户的影响,并向相关服务提供商咨询是否有迁移方案可供使用。
选择CUDA版本号 需要考虑的有两点:
(1)pytorch适配
https://pytorch.org/get-started/locally/
(2)显卡驱动适配
https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html
安装cuda 打开下载链接选择操作系统、架构、版本、安装方式
ps:如果要选择非最新版本cuda, 点击下方的legacy releases
输入Installation Instructions中的指令获取安装包并开始安装 ### 获取安装包 wget http://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda_10.1.243_418.87.00_linux.run ### 开始安装 sudo sh cuda_10.1.243_418.87.00_linux.run 安装过程 首先会出现一系列协议,一直按住Enter键。之后会出现一系列选项。第一个选择accept第二个记得取消驱动选项.后面全部选择y
设置cuda环境变量
输入 sudo gedit ~/.bashrc 打开主目录下的 .bashrc文件添加如下内容: ### 注意 12.2为版本号,应当替换为刚刚下载的版本 export PATH="/usr/local/cuda-12.2/bin:$PATH" export LD_LIBRARY_PATH="/usr/local/cuda-12.2/lib64:$LD_LIBRARY_PATH" 终端运行:source ~/.bashrc 使之生效检查是否安装成功:
输入nvcc --version,如果显示如下文字就说明安装成功
如果显示错误,注销一下用户 安装cudnn 官方教程
打开下载链接,选择相应的版本并下载。选择方法可参考https://blog.csdn.net/MumuziD/article/details/118760650,建议直接选择cuDNN Library for Linux (x86_64)进入cudnn压缩包所在的文件夹,解压文件 tar -xvf cudnn-10.1-linux-x64-v7.6.4.38.tgz 将文件拷贝到相应cuda目录下 ### 注意 10.1为版本号,应当替换为刚刚下载的版本 ### 注意安装过程中不要随意切换路径 sudo cp cuda/include/cudnn.h /usr/local/cuda-10.1/include/ sudo cp cuda/lib64/libcudnn* /usr/local/cuda-10.1/lib64/ sudo chmod a+r /usr/local/cuda-10.
Vue 发布到服务器,页面刷新404,访问后端404,解决办法 //在vue中配置的VUE_APP_BASE_API: /dev-api
## nginx配置 #代理目标的链接 location /dev-api/ { proxy_pass http://192.168.110.119:38080/; proxy_connect_timeout 60; proxy_read_timeout 60; proxy_send_timeout 60; } #刷新页面404 location / { try_files $uri $uri/ /index.html; }
STM32微控制器系列提供了多种GPIO模式,允许你根据应用的需求配置GPIO引脚的功能。以下是一些常见的STM32 GPIO模式:
输入模式 (Input Mode):
浮空输入 (Floating Input):GPIO引脚作为输入,stm32没有内部上拉或下拉电阻,需要外部电路提供上下拉电阻。上拉输入 (Pull-Up Input):在上拉输入模式下,GPIO引脚内部会有一个上拉电阻。当端口处于空闲时为高电平。下拉输入 (Pull-Down Input):GPIO引脚作为输入,具有内部下拉电阻,可以连接到外部电路,以便输入信号在未连接时被拉低。则端口空闲时为低电平。 输出模式 (Output Mode):
推挽输出 (Push-Pull Output):可以输出高电平或低电平。输出0/1。开漏输出 (Open-Drain Output):只能输出低电平。只能输出0。 复用功能模式 (Alternate Function Mode)(哪些端口具有复用功能需要查看芯片手册):
一个GPIO如果可以复用为内置外设的功能引脚,那么当这个GPIO作为内置外设使用的时候,就叫做复用。例如串口1 的发送接收引脚是PA9,PA10,当我们把PA9,PA10不用作GPIO,而用做复用功能串口1的发送接收引脚的时候,叫端口复用。在此情况下,我们就需要用复用功能模式。
复用推挽输出 (Alternate Function Push-Pull Output):可以用于输出定时器、串口通信等信号。复用开漏输出 (Alternate Function Open-Drain Output):可以用于输出定时器、串口通信等信号。复用上拉输入 (Alternate Function Pull-Up Input):可以用于输入外部信号,具有内部上拉电阻。复用下拉输入 (Alternate Function Pull-Down Input):可以用于输入外部信号,具有内部下拉电阻。 模拟模式 (Analog Mode):
模拟输入 (Analog Input):GPIO引脚用于连接模拟传感器或其他模拟信号。模拟输出 (Analog Output):GPIO引脚用于输出模拟信号。 中断模式 (Interrupt Mode):
上升沿触发中断 (Interrupt on Rising Edge):端口产生上升沿时触发中断。下降沿触发中断 (Interrupt on Falling Edge):端口产生下降沿时触发中断。上升/下降沿都触发中断 (Interrupt on Rising/Falling Edge):GPIO引脚配置为触发上升沿或下降沿时产生中断。 串口USRAT :
1.ubuntu安装make: sudo apt install make
sudo apt install make-guile
2.ubuntu上安装git: 运行Ubuntu的主机
打开终端,输入【sudo apt update】命令。
输入密码,确认授权。
输入【sudo apt install git】命令。
输入【Y】,确认命令执行。
输入【git --version】命令,查看安装版本。
Git当前版本为【2.30.2】,就此安装完成。
3.Ubuntu与windows之间实现复制粘贴 打开Ubuntu终端,输入两条命令即可。
先输入第一条命令:
sudo apt-get autoremove open-vm-tools 然后输入第二条命令:
sudo apt-get install open-vm-tools-desktop 最后重启虚拟机即可实现复制粘贴。
执行过后界面太小的问题也可以解决。
4.Ubuntu查看IP信息连接网络 在终端中使用命令“ifconfig -a”,如果提示找不到“ifconfig”,根据提示安装“net-tools”,运行命令“
sudo apt install net-tools”即可安装。,然后再运行命令“ifconfig -a”就可以查看网络连接信息了。
5.Ubuntu 和 Windows 文件互传 开启 Ubuntu 下的 FTP 服务 打开 Ubuntu 的终端窗口,然后执行如下命令来安装 FTP 服务:
sudo apt-get install vsftpd 等待软件自动安装,
安装完成以后使用如下 VI 命令打开/etc/vsftpd.conf,
命令如下: sudo vi /etc/vsftpd.
文章目录 介绍分布式锁一、 redis-分布式锁1、redis1.1、处理死锁1.2、处理误删 2、可重入锁3、阶段总结3.1、升级阶段3.2、加锁操作3.3、解锁操作 3、redLock(红锁)4、Redisson4.1、配置4.2、可重入锁4.3、公平锁4.4、连锁、红锁4.5、读写锁4.6、semaphore(信号量)4.7、CountDownLatch(闭锁) 二、zookeeper-分布式锁2.1、实现思路2.2、相关问题2.2.1、防死锁2.2.2、阻塞锁2.2.3、可重入 2.3、Curator2.3.1、可重入锁InterProcessMutex2.3.2、不可重入锁InterProcessSemaphoreMutex2.3.3、可重入读写锁InterProcessReadWriteLock2.3.4、 联锁InterProcessMultiLock2.3.5、信号量InterProcessSemaphoreV2 三、mysql-分布式锁 介绍分布式锁 单机多线程: 在传统的单机服务中,涉及到并发相关的场景,通常使用的 ReetrantLock 类、synchronized 关键字来控制并发,或者是在特殊的场景的,可能会使用Semaphore、CountDownLatch、ReadWriteLock等锁来控制并发访问。
分布式系统: 在分布式系统,如果继续使用传统的锁,不可以满足自己的想要的结果,因为不同的服务/客户端通常运行在独立的 各自的JVM 进程上,多个 JVM 进程共享同一份资源的话,此时就考虑分布式锁。
在一个最基本的分布式锁需要同时满足:
互斥性:在任何时刻,对于同一条数据,只有一台应用可以获取到分布式锁;高可用性:在分布式场景下,一小部分服务器宕机不影响正常使用,这种情况就需要将提供分布式锁的服务以集群的方式部署;防止锁超时:如果客户端没有主动释放锁,服务器会在一段时间之后自动释放锁,防止客户端宕机或者网络不可达时产生死锁;独占性:加锁解锁必须由同一台服务器进行,也就是锁的持有者才可以释放锁,不能出现你加的锁,别人给你解锁了。 分布式锁的常用实现方式
基于 redis 缓存实现分布式锁基于 zookeeper 实现分布式锁基于 mysql 实现分布式锁 三种方式的进行比对:
考虑在性能方面: redis > zookeeper > 数据库
考虑复杂性或者难度: Zookeeper > redis > 数据库
考虑可靠性: Zookeeper > redis = 数据库
一、 redis-分布式锁 1、redis 客户端借助 redis 中的命令 setnx(key value) 该命令作用在创建的值会进行判断,如果该值存在则忽略,不存在则创建。运用到分布式中,多个客户端发送setnx命令,只用一个客户端可以执行成功
存在问题:
死锁 : 当一个客户端设置成功后,宕机无法释放key,则存在死锁问题;误删 : 因为锁得名称是一样,就会存在一个客户端执行完,刚好自己设置锁到期了,仍要执行delete操作,此时就会把其他客户端的锁删除掉 1.1、处理死锁 在使用redis客户端 setnx 值的同时可额外添加参数
本系列为使用野火IMX6ULL开发的学习笔记,使用的开发板为如下:
具有的硬件资源有如下:
文章目录 一、环境搭建Win11安装WSL安装串口驱动安装串口工具安装Ubuntu与windows文件互传 二、镜像烧录修改串口终端登录前信息 三、fire-config工具配置EMMC/NAND FLASH刷机 四、WIFI连接 一、环境搭建 Win11安装WSL https://blog.csdn.net/weixin_44301630/article/details/122390018
安装虚拟机也可以,需要安装一个Ubuntu系统。直接在微软商城中搜索ubuntu20.04。
安装串口驱动 CH340(波特率115200)
https://www.wch.cn/products/CH340.html
安装串口工具 在 Windows 下有很多种终端工具,例如 MobaXterm、secureCRT、xShell、Putty 等,但是最推荐的还是MobaXterm:
MobaXterm:https://mobaxterm.mobatek.net/download.html 安装Ubuntu与windows文件互传 FileZilla下载地址:https://www.filezilla.cn/download
开启Ubuntu下的FTP服务:sudo apt-get install vsftpd
等待软件自动安装,安装后打开配置文件:sudo vi /etc/vsftpd.conf
打开 vsftpd.conf 文件以后找到如下两行,输入i进行编辑,按下Esc,输入“:和wq”保存:
local_enable=YES write_enable=YES 确保上面两行不能注释,把他打开:
使用如下命令重启FTP服务:
sudo /etc/init.d/vsftpd restart
使用FileZillla连接到Ubuntu的FTP服务器:
二、镜像烧录 安装Ubuntu系统时,我们使用到了Ubuntu提供的“iso”后缀的系统镜像文件,这是在PC上常用的系统镜像文件格式。
所谓镜像文件其实与压缩包类似,它将一系列文件按照特定的格式制作成单个文件,方便用户下载和使用。 iso文件的一个重要特性是它能被某些软件识别直接刻录到光盘上,而虚拟机虚拟的光驱则可以直接把iso文件像光盘一样加载读取, 从而通过iso系统镜像安装操作系统。
对于img文件格式,主要用于创建磁盘的镜像文件(disk image), 它可以用来打包整个磁盘或光盘的内容。img是iso文件格式的超集,它向后兼容iso文件格式。
嵌入式单板机一般没有光驱,而它们通常支持运行SD卡里的操作系统,所以嵌入式的系统镜像通常使用img文件的形式发布。 人们通常在PC上使用软件通过读卡器把img镜像文件烧录至SD卡,然后把SD接入到嵌入式单板机上运行。
准备一张Micro SD卡,容量需要2GB以上。下载 Etcher 软件,用于烧录镜像至 SD 卡,下载地址:https://www.balena.io/etcher ,根据自 己的电脑系统下载对应版本即可。下载野火最新的 Debian 镜像:https://pan.baidu.com/s/1pqVHVIdY97VApz-rVVa8pQ 提取码:uge1 imx6ull-lubancat-carp-console-armhf-2022-02-10.img.xz: Debian的纯净版固件,没有带桌面环境和野火的QT App。
imx6ull-lubancat-carp-qt-armhf-2022-02-10.img.xz: 具有QT App功能的Debian固件,系统启动后会进入QT App的界面。
电脑实在忒垃圾了,出现问题耗费了至少一刻钟time,然后才搞出来正常的效果; 效果镇楼
另外重新安装了VScode软件,原来的老是报错,bug。。;
2个必要的安装命令; 然后建立必要的文件夹和文件,放到自己合适合理的本地路径下面
express.js 代码
//1 引入express const express = require('express'); //2创建应用对象 const app=express(); //3 创建路由规则; request 是对请求报文的封装 response 是对响应报文的封装 app.get('/',(request,response)=>{ //设置响应 response.send('Hello express'); }); //4 监听端口 启动服务 app.listen(8000,()=>{ console.log("服务已经启动,8000端口监听中,,,..."); }) 执行运行命令,成功效果