本文转自:https://gitee.com/linlion/gitlab-docker-k8s 此文档主要说明怎样基于GitLab进行持续集成和持续交付,该持续集成与交付集成了gitlab-runner 、mvnw、Docker、harbor、k8s等技术,同时展示了在k8s平台利用EFK(elasticsearch,fluentd,kibana)技术完成了集群统一日志管理,使用kube-prometheus技术进行集群实时监控以及kube-dashboard管理集群中的应用部署,为了不引入网络问题,本环境的相关VPC机器已经关闭了本机防火墙。
一、场景问题 配置应用的部署环境复杂繁琐、已经配置好的环境很难移植、存在大量重复劳动、时间成本人力成本增加,由于各种应用服务配置复杂,部署运维手册更新不及时、缺少甚至没有部署操作记录时,导致部署更加难上加难,大量时间浪费在环境部署上,应用的部署越来越需要自带依赖环境,无需或只需少量配置就能运行机器资源不能有效利用、机器CPU、内存、带宽、硬盘等资源存在浪费,需要好的度量或监控方式了解实际利用率应用程序可移植性和扩展性差,负载不够时需要重复部署配置,不能根据业务进行有效自动调整部署运维困难、很难保证7x24小时服务稳定性和可用性,不得不增加运维人力且对运维要求颇高由于机房相关环境变动或系统升级,不得不对应用服务各个方面进行检查,并修改相关配置以应对各种调整、重新部署应用速度慢、不能快速拉起应用服务随着应用程序的业务规模、开发人员很难在单机上部署开发环境模拟整个业务流程,越来越需要把复杂应用拆分为微服务化,允许开发人员以微服务方式自动注册到应用中变成开发环境的一部分集中主要精力解决实际问题即self-hosting,而不是耗费大量时间在整个应用的部署上日志收集排错能力会随着业务系统的复杂度越来越难控制,传统方式查找日志已经不能应对快速的应用修复和变更应用服务应该具备Develop、Stage、Production三种部署范围,develop负责开发,stage负责阶段演示,production负责生产,且支持在不同的环境中快速部署切换,允许模拟在不同的网络拓扑结构下验证bug解决或功能的可行性应用业务之间由于模块、项目的划分很难追踪服务之间的依赖或调用关系,程序之间的调用越来越复杂需要有清晰的方式记录、自说明这些配置,使用统一的格式管理、解析,版本控制,允许运维人员通过查看统一配置明确服务之间的调用关系,而不需要侵入代码随着应用开发的多变性,依赖ACL的变更调整策略被动防御攻击反而加重了开发、运维的负担,也不能实时进行相关统计,反而需要为应用服务集群构建统一的实时监控方案,监控方案不止涉及传统操作系统的关键环节,还要监控应用服务的业务时态,支持实时分析系统之间的调用情况,允许通过实时统计评估模块、项目的质量和可用性,允许发生系统故障时迅速隔离业务或熔断调用关系,防止错误灾难迅速扩大导致其他业务不可用、并支持报警机制应用系统的代码托管、版本控制、编译、测试与部署应该支持自动化,应对上传内外网安全限制策略安全方面应用服务的部分漏洞导致宿主集群被攻破时,需要有能力迅速隔离感染环境,防止整个机房内部服务的感染 二、引入容器技术的可行性(Docker) 应用程序和依赖环境打包成镜像,直接运行镜像即可运行应用程序,解耦了应用程序和宿主系统,应用程序更容易移植,且不受限于应用开发依赖的特定计算机语言无需担心因宿主系统版本升级、依赖库升级或部署其他相关应用,导致应用系统因版本冲突或意外覆盖问题不能运行,因为应用程序和依赖环境打包到了一起,宿主系统的环境更改不会影响运行环境镜像启动速度快轻便捷,像虚拟机一样敏捷 ,在Bare Metal或VPC上布署像点个按钮一样简单可以在docker hub/docker store 镜像市场以及第三方镜像市场寻找现成基础镜像,拉取现有镜像,免去了繁重的基础应用环境的部署配置,如:nginx,tomcat,mysql,redis,mongodb等等可移植性,可在各种环境中自由迁移应用,支持内网Bare Metal,VM,和公有云VPC,易于横向自由扩展部署系统安全性,进程在cgroups空间内运行犹如在沙箱中运行 ,即便应用被攻陷获取root权限,由于非真实宿主系统环境,很难伤害宿主机 三、引入容器编排技术的可行性(k8s--kubernetes) docker等容器技术解决的是单机部署、应用和依赖环境打包的可移植问题,集群中自动部署镜像需要解决k8s天然适合微服务的部署支持通过简单命令构建镜像部署集群,将Bare Metal或VPC抽象成资源消耗,资源告急时,仅需运行简单命令即可加入集群镜像自动部署到集群中无需人工干预,k8s自动监控应用存活状态,当宿主机节点由于故障原因脱离集群时,运行其上的应用就会自动转移到其他机器,无需人工干预,保证了应用程序的高可用性k8s内置自动负载均衡,无需为应用配置繁琐的负载均衡功能k8s支持自动扩容,无需人工干预,系统可根据消耗自动扩容或收缩应用k8s支持应用在线发布和回滚k8s支持内网和公有云迁移,应用部署无需修改或仅进行少量相关配置即可快速部署,k8s已经成为各大云生产商的标配支持docker overlay覆盖型网络,意味着微服务可以和实际宿主机VPC网络解耦有大量现成可行性方案支持集群基础能力问题,如:EFK解决统一日志收集、kube-prometheus支持集群监控等等支持众多云或本地存储方案,如:GFS,CEPH、NFS等等管理集群方便简洁,仅需少量人员轻松管理上百台VPC,官方在云环境下测试最高支持到5000台VPC, 平均每台上VPC运行30个pod应用 k8s的架构原理图:
四、Docker安装(centos7) 如之前安装过移除老旧版本 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-selinux \ docker-engine-selinux \ docker-engine 使用阿里镜像库安装 # Step 1: 安装必要的一些系统工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # Step 2: 添加软件源信息 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # Step 3: 更新并安装 Docker-CE sudo yum makecache fast sudo yum -y install docker-ce # Step 4:添加当前用户到docker组中允许普通用户运行docker命令,此步需要登出linux环境重新再登录方能生效 sudo usermod -aG docker $USER # Step 5:添加开机启动 sudo systemctl enable docker.
文章目录 点赞功能点赞功能分析功能实现功能测试 查看点赞功能分析功能实现功能测试 关注功能关注、取消关注功能分析功能实现功能测试 查看关注、查看粉丝功能分析功能实现功能测试 优化登录功能分析功能实现 点赞功能 点赞 功能分析 可以对帖子、评论点赞;
第一次点赞,第二次取消点赞;
统计帖子或评论的点赞数量;
前端显示帖子或评论点赞数量和点赞状态;
功能实现 为了方便获取RedisKey,在util包下新建 RedisKeyUtil工具类,代码如下:
public class RedisKeyUtil { public static final String SPLIT = ":"; private static final String PREFIX_ENTITY_LIKE = "like:entity"; // 某个实体的赞 // like:entity:entityType:entityId -> set(userId) public static String getEntityLikeKey(int entityType, int entityId) { return PREFIX_ENTITY_LIKE + SPLIT + entityType + SPLIT + entityId; } } service层,新建LikeService类,代码如下:
@Service public class LikeService { @Autowired private RedisTemplate redisTemplate; // 点赞 public void like(int userId, int entityType, int entityId) { String entityLikeKey = RedisKeyUtil.
案例:电脑没有声音了怎么恢复
【谁懂啊!电脑没有声音实在太磨人了,看剧就像在看哑剧,听音乐也只能看歌词。跪求一个恢复电脑声音的方法!感谢大家!】
电脑突然没有声音了确实会很让人崩溃,也会给我们使用电脑带来很多不便。电脑没有声音可能是由于多种原因引起的,包括软件问题、硬件故障、设置错误等。电脑没有声音了怎么恢复?下列这5种简单的方法,一起来看看吧!
一、电脑没有声音怎么恢复 电脑的声音对我们在电脑上听音乐、看剧等都很重要,笔记本莫名其妙没声音怎么办?下列5种方法可以有效解决。
方法一:检查音量设置 在大多数情况下,电脑没有声音是由于音量设置不正确所致。在这种情况下,我们可以通过以下步骤来检查和更改音量设置:
1.右键单击任务栏上的【音量】图标;
2.点击【打开声音合成器】;
3.确保【设备】和【应用程序】音量都处于开启状态。
方法二:检查音频设备 如果使用方法一电脑仍然没有声音,可能是因为音频设备出现了问题。在这种情况下,我们可以通过以下步骤来检查音频设备:
1.在【控制面板】中打开【设备管理器】;
2.展开【音频输入和输出】,右键单击音频设备并点击【属性】;
3.确保设备没有禁用,并且其状态为【运转正常】。
注意:如果设备有问题,我们可以尝试更新或重新安装驱动程序来解决问题。 方法三:检查音频线缆和插头 电脑没有声音,也可能是由于音频线缆或插头出现了问题。在这种情况下,我们可以尝试以下步骤来解决问题:
1.检查音频线缆是否正确连接到电脑和扬声器或耳机。
2.检查插头是否松动或脏污。
3.尝试用另一条音频线缆或插头连接电脑和扬声器或耳机。
方法四:运行音频故障排除程序 如果电脑没有声音,我们可以运行Windows的内置音频故障排除程序来解决问题。以下是如何运行故障排除程序的步骤:
打开【设置】,点击【更新和安全】;点击【答疑解难】,选择【其他答疑解难】;找到【播放音频】并点击【运行答疑解难】;选择无法播放声音的设备 ,并依据提示进行即可。 方法五:重启电脑 有时,电脑没有声音可能是由于临时故障所致。在这种情况下,我们可以尝试简单地重启电脑来解决问题。
如果以上方法都无法解决问题,我们可以考虑更深入的故障排除方法或寻求专业技术支持。电脑没有声音了怎么恢复?可以按照上述方法进行尝试了!
往期推荐:
5招教你硬盘坏了数据恢复的方法!https://blog.csdn.net/datarecover/article/details/129835100?spm=1001.2014.3001.5501增加c盘空间,这样做就对了!https://blog.csdn.net/datarecover/article/details/129856044?spm=1001.2014.3001.5501
安装anaconda 下载安装 首先找到一个下载conda的地址
清华源anaconda地址
可以看到conda在不同系统环境下有如下版本
鉴别不同国产系统可参考:国产的开源操作系统都有哪些?
这里用阿里arm/aarch64架构
所以下载连接为
https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2023.03-Linux-aarch64.sh
可以手动下载上传,也可使用wget下载
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2023.03-Linux-aarch64.sh 安装
/bin/bash Anaconda3-2023.03-Linux-aarch64.sh -f -b -p /opt/conda 不知道为啥没让看文档,然后一直选是。
查询是否安装成功(也可能没添加conda到环境变量)
conda -V 可能出现环境变量问题 如出现以下情况
[root@XXXX ~]# conda -V -bash: conda: command not found 则需要添加conda至环境变量。
添加conda到环境变量 打开文件/etc/profile
vim /etc/profile 添加以下语句
# conda,这是把conda的环境加入系统的环境变量 export PATH=/opt/conda/bin:$PATH # 这一步是系统进入conda的默认base环境 source activate # 下面6行内容先不要看,暂时没搞明白~~~~~~~~~~~~~~~~~~~~ # conda,这是把conda的环境加入系统的环境变量 export conda=/root/miniconda3 export PATH=$PATH:$conda/bin alias liuzhenPython='/home/riki/anaconda3/bin/python' export PATH="/home/riki/anaconda3/bin:$PATH" 然后执行语句
source /etc/profile 执行以上步骤后,即可在linux上使用conda命令
在window环境下安装包有选项可以直接添加,在anaconda安装过程中会提示是否将环境变量加入到path中,点击即可。
添加清华源 查看当前conda配置
conda config --show channels 设置通道
nginx是一个高性能的反向代理服务器
正向代理代理的是客户端
反向代理代理的是服务端
安装步骤如下
1、下载安装文件 nginx-1.12.2.tar.gz 并移动到nginx文件夹下
2、依次执行如下命令 解压文件 并修改解压后的文件夹名称为 nginx112
tar -zvxf nginx-1.12.2.tar.gz
mv nginx-1.12.2 nginx112
[root@zk03 nginx]# ll 总用量 960 drwxr-xr-x. 9 1001 1001 186 1月 22 17:33 nginx112 -rw-r--r--. 1 root root 981687 2月 19 2019 nginx-1.12.2.tar.gz 3、安装 c++编译环境 及依赖环境
yum install gcc-c++ yum install -y gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel perl 4、到nginx112目录下安装 nginx
[root@zk03 nginx112]# ./configure 提示 需要 PCRE library 如下:
./configure: error: the HTTP rewrite module requires the PCRE library.
如何让页面自动滚动到某个位置(比如点击某一个按钮,需要自动滚动到对应内容的位置),在小程序是很简单的,官方提供获取元素位置和滚动到目标位置API:
1.使用uni.createSelectorQuery().select().boundingClientRect()查询到需要滚动到的元素位置
2.滚动到目标位置: uni.pageScrollTo()
微信原生也是一样的,使用wx.createSelectorQuery()和wx.pageScrollTo()
小程序很多api都很简单,拿来可以直接使用,下面总体使用方法案例:
toScroll() { // 1.使用uni.createSelectorQuery()查询到需要滚动到的元素位置 const query = uni.createSelectorQuery().in(this); query.select('.recommend-list').boundingClientRect(data => { console.log(data.top) // 滚动到的位置(距离顶部 px) // 到这里我们可以从data中读到top,即离顶部的距离(px) // 2使用uni.pageScrollTo()将页面滚动到对应位置 uni.pageScrollTo({ scrollTop: data.top, // 滚动到的位置(距离顶部 px) duration: 300 }); }).exec(); },
1. SRS安装 写在前面:我用自己电脑windows10系统,可以通过安装docker来安装srs,但是阿里云服务器的window server镜像安装不了docker,咨询了客服说是window server本身就是一个虚拟机,无法开启虚拟化操作,因此用了阿里云服务器的Linux系统来安装。如果有大佬知道window server能成功安装并启用docker的请告知下。。。
1.1 下载srs安装包zip 下载链接:https://github.com/ossrs/srs
我这里是直接下载srs4.0release.zip
1.2 编译安装运行 ① 将srs.zip解压到/usr/local/soft/目录下,更名为srs4.0:mv simple-rtmp-server-4.0release srs4.0
② 进入 /usr/local/soft/srs4.0/trunk/ 目录下,执行命令:./configure && make
③ 修改配置文件srs.conf
进入 /usr/local/soft/srs4.0/trunk/conf/ 目录下,执行命令:vim srs.conf
修改两处地方:
Esc + :wq 保存退出
④ 启动srs
进入 /usr/local/soft/srs4.0/trunk/ 目录下,执行命令:./objs/srs -c conf/srs.conf
⑤ 开放端口
阿里云服务器开放端口:
TCP:8080、1935、1985
UDP:8000
⑥ 页面访问
访问:ip:8080,跳出以下页面即为成功
2. OBS推流 我这里是直接在自己电脑windows10系统上安装的OBS可视化界面,相关安装教程自己搜索下哈
2.1 配置srs webrtc拉流地址 我这里直接用OBS推流网页上的时间,打开一个中国时间网页,通过窗口采集来采集网页上的时间
点击 文件 -> 设置 -> 直播:
服务器:rtmp://ip/live/livestream,
推流码:123456
回到OBS主页面,点击 开始直播,即向srs进行推流
3. 使用srs拉流webrtc 进入srs播放器,选择RTC播放器,输入rtmp://ip/live/livestream/推流码
云服务器的带宽不能太小,否则会一直黑屏转圈圈,我这里是5M的宽带,延迟在1s以内
一般情况下,使用ssl证书需要三个操作步骤:1.生成密钥对;2.生成证书请求文件;3.生成证书文件。从单纯的开发者角度来说,可以使用开源的openssl生成密钥和证书,且通过openssl的req命令,可以一个命令完成上述3个操作。
一、openssl生成证书 1.1、req命令简介 req命令主要的功能:生成证书请求文件、验证证书请求文件和自签名证书(创建根证书)。
通过向openssl 提供一个无效的命令参数,比如:-help 就可以获得可用的命令帮助说明,如下图
1.2、req命令的配置模板文件 使用config参数,需要编写模板文件req.cnf,如下:
# 定义输入用户信息选项的"特征名称"字段名,该扩展字段定义了多项用户信息。 distinguished_name = req_distinguished_name # 生成自签名证书时要使用的证书扩展项字段名,该扩展字段定义了要加入到证书中的一系列扩展项。 x509_extensions = v3_req # 如果设为no,那么 req 指令将直接从配置文件中读取证书字段的信息,而不提示用户输入。 prompt = no [req_distinguished_name] # 国家代码 C = CN # 省份 ST = HeBei # 城市 L = ShiJiaZhuang # 企业/单位名称 O = Network # 企业部门 OU = Development # Common Name CN = www.network.cn ##### 要加入到证书请求中的一系列扩展项 ##### [v3_req] keyUsage = critical, digitalSignature, keyAgreement extendedKeyUsage = serverAuth subjectAltName = @alt_names [ alt_names ] DNS.
本次项目所有能够使用的静态资源可以免费进行下载 静态资源 在本篇代码DAO层将通过Java文件去实现,在这里就不连接数据,然后通过jdbc将数据库内容的内容显示出来
案例:员工管理系统
创建DAO层 创建储存用户属性信息的工具类 package com.example.demo2.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.Date; @Data //生成属性的set和get方法 @NoArgsConstructor //注解:自动化自己主动生成无参构造方法 public class Employee { private Integer id; private String lastname; private String Email; private Integer gender; private department department; private Date date; public Employee(Integer id, String lastname, String email, Integer gender, com.example.demo2.pojo.department department) { this.id = id; this.lastname = lastname; Email = email; this.gender = gender; this.department = department; this.
C语言 结构注释变量定义与赋值数据类型强制转换 前言:我们都知道单片机要对其写指令、编程等就需要一种编程语言。在众多的编程语言中不可否认的是c语言是最适合成为单片机的编程语言的。我们在这里分享一下c语言的知识点。 结构 一般来说c语言的结构,一般都是包括若干个头文件(以#include" xxx ")和函数组合而成的。例:
#include "stdio.h" int main(void) { printf("hello wold"); return 0; } 在这里我们看到有两部分#include "stdio.h"、int main(void)。
#include <stdio.h>就是一条预处理命令, 它的作用是通知C语言编译系统在对C程序进行正式编译之前需做一些预处理工作。
int main(void)则是函数,并且是主函数在一个C语言中只有一个主函数,即main函数。C语言主要就是执行main函数里面的内容,并且我们看到main函数下有一对花括号“{}”,花括号里面就是函数要编写的主要内容。另外我们发现在每一句结尾的时候都要加上一个分号“;”。这个分号主要就是结束这个语句的意思。如果不加这个分号的话编译器就会报错。因此,分号是必须在语句结束的时候在结尾加上。
注释 当语句过长的时候,可读性不是很高的时候。这个时候注释就起到了很大的作用。他可以让我们的可读性增高很多。并且我们知道注释是给程序员看的,不是给电脑读的。在c语言中主要有两种的注释方法。即
/* 多行注释*/ //单行注释 例如:
#include "stdio.h" int main(void) { // printf("hello wold"); return 0; //注释........... } 在printf前面加上了// ,即单行注释,注释的这一行电脑就不会读取printf了。
多行注释也是一样的情况的。
变量定义与赋值 变量就是可以变化的量,而每个变量都会有一个名字。变量占据内存中一定的存储单元。使用变量之前必须先定义变量,要区分变量名和变量值是两个不同的概念。变量名,即为变量的名称;变量值,即为赋值给变量的值。
例:
int a=10; //定义int型变量,变量名为a赋值10 int b; b=10; 值得注意的是在定义中不允许连续赋值,连续的赋值是不合法的。例:
int a=b=c=5; //不合法的赋值操作 变量的赋值分为两种方式:
①先声明再赋值
②声明的同时赋值
数据类型 在c语言中数据类型有很多,整形、字符型、浮点型。
① 整型数据是指不带小数的数字(int,short int,long int, unsigned int, unsigned short int,unsigned long int),在这些整形数据,他们的区别也就是字节和取值的范围不同。
Docker的安装 说明:本篇文章为学习 docker 使用时记录的笔记,方便查询。
Docker 官方建议在 Ubuntu 中安装,因为 Docker 是基于 Ubuntu 发布的,而且一般 Docker 出现的问题,Ubuntu 是最先更新或者打补丁的。在很多版本的 CentOS 中是不支持更新最新的一些补丁包的。
由于部署 CentOS 环境,因此这里建议安装在 CentOS 7.0 及以上的版本,在 CentOS 6.x 的版本中,安装前需要安装其他很多的环境而且 Docker 很多补丁不支持更新。
因此请移步到 CentOS7 或 Ubuntu 系统。
(1)yum 源更新到最新 (可暂缓)
sudo yum update (2)安装需要的软件包,yum-util 提供 yum-config-manager 功能,另外两个是 devicemapper 驱动依赖的。
sudo yum install -y yum-utils device-mapper-persistent-data lvm2 (3)设置 yum 源为阿里云(加速镜像下载)
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo (4)安装docker
## 安装当前符合的最新版 sudo yum -y install docker-ce ## 指定版本安装 # 查阅已知的版本 yum list docker-ce --showduplicates | sort -r # 例如:指定安装 18.
#include "user_uart.h" #include "stm32f10x.h" #include <stdio.h> /******************************************************************************************/ /*串口接收部分代码移植需要改动3处*/ /******************************************************************************************/ /******************************************************************************************/ /********************************串口接收部分代码*******************************************/ /******************************************************************************************/ /******************************************************************************************/ /*此结构体类型无需改动*/ /******************************************************************************************/ typedef struct { volatile unsigned int uart_delay_flag; //串口进入中断后,定时器开启标志位 volatile unsigned int uart_delay_count; //串口进入中断后,定时器计数变量,自加 volatile unsigned char uart_array_num; //接受数据的数组的序号 volatile unsigned char uart_receive_flag; //串口接收数据完成标志位 }User_Uart_InitTypeDef; /*******************************************************************************************/ /******************************************************************************************************/ /*串口结构体数组,预设5个串口,如增加新串口,可按格式增加,如不需要增加串口,此结构体无需改动*/ /******************************************************************************************************/ User_Uart_InitTypeDef uart_array[UART_NUM_ALL] = { {0,0,0,0,}, #if UART_NUM_ALL > 1 {0,0,0,0,}, #endif #if UART_NUM_ALL > 2 {0,0,0,0,}, #endif #if UART_NUM_ALL > 3 {0,0,0,0,}, #endif #if UART_NUM_ALL > 4 {0,0,0,0,}, #endif }; /***************************************************************************************************/ /***************************************************************************************************/ /*串口接收数组声明,预设5个串口,如增加新串口,可按格式增加,如不需要增加串口,此结构体无需改动*/ /***************************************************************************************************/ volatile unsigned char uart1_array_receive_buff[N1_UART]; #if UART_NUM_ALL > 1 volatile unsigned char uart2_array_receive_buff[N2_UART]; #endif #if UART_NUM_ALL > 2 volatile unsigned char uart3_array_receive_buff[N3_UART]; #endif #if UART_NUM_ALL > 3 volatile unsigned char uart4_array_receive_buff[N4_UART]; #endif #if UART_NUM_ALL > 4 volatile unsigned char uart5_array_receive_buff[N5_UART]; #endif /***************************************************************************************************/ /**********************************移植需改动的第1处***********************************/ /*串口初始化代码*/ /*************************************************************************************/ void user_uart_init(void) { GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); GPIO_InitStruct.
1、@Repository的作用 @Repository是属于Spring的注解。它用来标注访问层的类(Dao层),它表示一个仓库,主要用于封装对于数据库的访问。其实现方式与@Component注解相同,只是为了明确类的作用而设立。
即@Repository是@Component注解的一个派生品,与@Service和@Controller都可以理解为@Component注解的扩展。他们的作用都是在类上实例化bean,并把当前类对象的实现类交给spring容器进行管理。
换句话说,@Repository注解修饰哪个类表明这个类具有对数据库CRUD的功能,用在持久层的接口上。
另外,作为spring的注解,他还能把所标注的类中抛出的数据访问异常封装为spring的数据访问异常类型。
2、@Repository与@Service和@Component有什么区别? @Repository作用如上所说。
@Service注解用来标注服务层中的类,用于处理业务逻辑。在使用@Service注解标记的类中,通常会注入@Reposity的类。
@Component注解是通用的注解,用来标记所有被spring容器管理的组件。在使用@Component注解标记的类中,通常会注入@Service和@Repository标记的类。
本质上都是把实例化对象交给spring管理。
3、@Repository和@Mapper的异同 @Mapper是属于mybatis的注解。在程序中,mybatis需要找到对应的mapper,在编译时候动态生成代理类,实现数据库查询功能。
@Mapper和@Repository注解的使用方式一样,都是在持久层的接口上添加注解。
但是如果只是单独的使用@Mapper注解的话,在idea中进行自动装配的时候,会出现警告,提示找不到这个bean。但是这个不影响程序运行,可以直接忽略。
想要不出现这个警告,可以在idea设置中对这种警告进行忽略,也可以在使用@Mapper的地方同时使用
@Repository注解。这样spring会扫描@Repository并识别这个bean,就不会出现这个警告。
正常情况下的使用,我们都是使用@Mapper居多,而不使用@Repository注解。
不使用@Repository注解,而实现注入这个接口的实现类主要有以下3种方法:
1、在spring的配置文件中,配置了MapperScannerConfigure这个bean,他会扫描持久层接口创建实现类交给spring来管理。
2、接口使用@Mapper注解。
3、springboot的启动类上使用@MapperScan注解,和MapperScannerConfigure的作用一样。
4、正确的单独使用@Repository @Repository注解是用于标记数据访问层的组件的注解,它会被spring扫描并注入到ioc容器中。即使没有使用@MapperScan注解或MapperScannerConfigurer,只要@Repository注解标记的组件与Mybatis的mapper接口实现相同,它也可以生效。
但是,在mybatis中使用@Repository注解可能会有一些问题。当使用@Repository注解时,spring会将其视为spring的组件,即为该类创建一个代理对象并在ioc容器进行管理。但是,mybatis中的mapper接口实现并不是spring的组件,他们是由mybatis创建的代理对象。使用@Repository注解可能会导致mybatis创建的代理对象被spring重新创建代理,进而出现问题。
因此,建议在mybatis中使用@MapperScan注解或者MapperScannerConfigurer来扫描mapper接口实现,并将他们注入到ioc容器中,而不是使用@Repository注解。
5、总结: 1、@Repository是spring的注解,@Mapper是mybatis的注解。
2、@Repository与@Mapper都可以使用,二者可以同时出现,也可以单一使用。
3、单独使用@Repository,需要配合使用MapperScannerConfigurer或者@MapperScan注解。
4、单独使用@Mapper时,可能会在编辑器出现警告,不影响程序运行。可以配合使用@Repository消除警告。(也可以在编辑器中设置忽略这种警告)
思路 维护双链表 head代表最久没被使用的节点,当我们要更新时 普通链表操作需要遍历,这里我们拿哈希表索引链表的位置,直接o1删除,挺麻烦的。
struct node{ node* pre; node* ne; int key; int value; node(int k,int v){ key = k; value = v; } }; class LRUCache { public: node* head; node* tail; unordered_map<int ,node*>mp; int sz = 0 ; LRUCache(int capacity) { mp.clear(); sz = capacity; head=new node(0,0); tail = new node(0,0); head->ne = tail; tail->pre = head; } int get(int key) { if(!mp.count(key)) return -1; node* tt = new node(key,mp[key]->value); node* zz = mp[key]; node* pp = zz->pre; node* dd = zz->ne; add(pp,dd); node* pt = tail->pre; add(pt,tt); add(tt,tail); mp[key] = tt; return mp[key]->value; } void add(node *a,node *b) { a->ne = b; b->pre = a; } void put(int key, int value) { node *tt = new node(key,value); if(!
最近也是刚把第十一届的题目写完,我们一起来看看2020年的省赛题目吧。
题目 这次题目照样还是LED、数码管、按键三大模块 ,还有模拟电压输入(ADC)、AT24C02(EEPROM),都是常见的外设,且之前题目出现过的,所以不难,考的都是基本功。
1 数码管显示 数码管主要显示获取的电压、计数和参数设置三个界面,不过要注意上电之后就要显示电压数据界面。
2 LED 当电压小于设置的参数时5s后L1亮,这个还是很好做的。当计数为奇数时L2亮,计数的话,我是先判断电压是比参数大还是小然后过个一段时间在判断电压是比参数大还是小,如果两次比较结果不一样就是电压和参数有过交点。定义一个变量mis,每次错误的按键都mis++,当count>=3时L3亮,正确的按键就让mis=0。
3 按键模块 这次使用的是一个矩阵键盘和之前的有所不一样。s12是电压、计数和参数设置三个界面的切换,s13是可以把计数清零的按键,s16,s17是加减按键不过要注意范围为[0,5]。
4 ADC 就是改写底层驱动代码部分(IIC)。
5 EEPROM 就是改写底层驱动代码部分(IIC),注意在加减后要把参数*10后才保存到EEPROM中,所以在加减完后直接/10.0这样*10也是原来的值,此外还指定的保存的地址为0。
IIC.c #include"IIC.h" #define DELAY_TIME 5 #define SlaveAddrW 0xA0 #define SlaveAddrR 0xA1 sbit SDA = P2^1; sbit SCL = P2^0; void IIC_Delay(unsigned char i) { do{_nop_();} while(i--); } void IIC_Start(void) { SDA = 1; SCL = 1; IIC_Delay(DELAY_TIME); SDA = 0; IIC_Delay(DELAY_TIME); SCL = 0; } void IIC_Stop(void) { SDA = 0; SCL = 1; IIC_Delay(DELAY_TIME); SDA = 1; IIC_Delay(DELAY_TIME); } bit IIC_WaitAck(void) { bit ackbit; SCL = 1; IIC_Delay(DELAY_TIME); ackbit = SDA; SCL = 0; IIC_Delay(DELAY_TIME); return ackbit; } void IIC_SendByte(unsigned char byt) { unsigned char i; for(i=0; i<8; i++) { SCL = 0; IIC_Delay(DELAY_TIME); if(byt & 0x80) SDA = 1; else SDA = 0; IIC_Delay(DELAY_TIME); SCL = 1; byt <<= 1; IIC_Delay(DELAY_TIME); } SCL = 0; } unsigned char IIC_RecByte(void) { unsigned char i, da; for(i=0; i<8; i++) { SCL = 1; IIC_Delay(DELAY_TIME); da <<= 1; if(SDA) da |= 1; SCL = 0; IIC_Delay(DELAY_TIME); } return da; } unsigned char AD_input() { unsigned char temp; IIC_Start(); IIC_SendByte(0x90); IIC_WaitAck(); IIC_SendByte(0x03); IIC_WaitAck(); IIC_Stop(); IIC_Start(); IIC_SendByte(0x91); IIC_WaitAck(); temp=IIC_RecByte(); IIC_Stop(); return temp; } void write_eeprom(unsigned char add,unsigned char para) { IIC_Start(); IIC_SendByte(0xa0); IIC_WaitAck(); IIC_SendByte(add); IIC_WaitAck(); IIC_SendByte(para); IIC_WaitAck(); IIC_Stop(); } unsigned char read_eeprom(unsigned char add) { unsigned char para; IIC_Start(); IIC_SendByte(0xa0); IIC_WaitAck(); IIC_SendByte(add); IIC_WaitAck(); IIC_Stop(); IIC_Start(); IIC_SendByte(0xa1); IIC_WaitAck(); para=IIC_RecByte(); IIC_Stop(); return para; } IIC.
问CSDN 以下是一个简单的光追里射线和三角形求交的代码,使用了C++语言和OpenGL库。
首先,我们需要定义一个射线类(Ray),包含起点(origin)和方向向量(direction):
复制class Ray { public: vec3 origin; vec3 direction; Ray(vec3 o, vec3 d) { origin = o; direction = d; } }; 接下来,我们定义一个三角形类(Triangle),包含三个点(p1, p2, p3),以及计算法向量(normal)的方法:
复制class Triangle { public: vec3 p1, p2, p3; vec3 normal; Triangle(vec3 v1, vec3 v2, vec3 v3) { p1 = v1; p2 = v2; p3 = v3; normal = normalize(cross(p2 - p1, p3 - p1)); } bool intersect(Ray ray, float& t) { vec3 e1 = p2 - p1; vec3 e2 = p3 - p1; vec3 h = cross(ray.
在本文中,我将为您介绍如何在Linux服务器上搭建Baota面板。宝塔面板是一个功能强大的Web服务器管理面板,它可以帮助您轻松地管理您的站点和服务器。
以下是搭建Baota面板的详细过程:
1. 安装Linux操作系统
如果您还没有安装Linux,请先选择一款适合您的发行版并进行安装。
2. 安装宝塔面板
在您的Linux服务器上安装宝塔面板非常简单。只需运行以下命令:
curl -sSO http://download.bt.cn/install/install_6.0.sh && sudo bash install_6.0.sh 这个命令将从宝塔面板的官方网站下载安装脚本,并将其运行以自动完成安装流程。请务必在执行此命令之前确认您的服务器已连接到互联网。
3. 访问宝塔面板
安装完成后,您可以通过浏览器访问您的宝塔面板。默认情况下,宝塔面板使用8888端口。因此,只需输入以下地址即可访问:
http://your_server_ip:8888 4. 配置宝塔面板
第一次登录宝塔面板时,您需要进行一些基本配置。首先,您需要设置管理员账户和密码,并选择您的语言和时区。
然后,您需要配置您的服务器。您可以添加Web服务器、数据库服务器和FTP服务器等服务。宝塔面板支持多种Web服务器,例如Nginx、Apache和OpenLiteSpeed。您可以根据自己的需求选择合适的服务器。
5. 添加网站
在宝塔面板中添加网站非常简单。只需单击“网站”选项卡,然后单击“添加站点”按钮即可。您需要输入网站域名、目录和其他相关配置信息,以便宝塔面板能够正确地管理您的站点。
6. 安装SSL证书
为了保护您的网站和用户数据,您应该为您的网站安装SSL证书。宝塔面板提供了内置的Let's Encrypt SSL证书功能,使得安装SSL证书变得十分简单。
只需在宝塔面板中选择您的网站,然后单击“SSL”选项卡,即可开始安装证书。一旦安装完成,您的网站将使用HTTPS加密进行通信。
7. 管理您的网站
现在,您已经成功地搭建了Baota面板并添加了您的第一个网站。通过宝塔面板,您可以轻松地管理您的网站,包括备份、日志查看、流量统计和数据库管理等。
总之,宝塔面板是一个非常强大且易于使用的Web服务器管理面板。如果您正在寻找一种轻松管理您的服务器和网站的方法,那么宝塔面板是一个很好的选择。
8.搭建过程中的小问题
搭建过程中遇见的问题:不知道为啥,就是进不去后台。。。真是服了。后来发现是我的阿里云服务器的防火墙的问题,建议大家搭建过程中如果出现了类似于我的问题的时候,可以尝试去阿里云服务器的控制台里面添加相应的端口!第一次写博客,希望大家多多包涵,让我们一起共同进步。
在Android的开发中,对于点击事件的OnClickListener有下面四种实现方式,可以根据实际场景的需要选择合适的用法。下面以Button按钮来举例说明。
方法一:匿名内部类 适合场景:任何场景都通用,但对于一个Activity中要是有多个控件要实现onClick方法就会显得代码冗余。
Button bt_Demo = (Button)findViewById(R.id.bt_Demo); bt_Demo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //具体点击操作的逻辑 } }); 方法二:自定义单击事件监听类 同方法一,两者差别不大
Button bt_Demo = (Button)findViewById(R.id.bt_Demo); bt_Demo.setOnClickListener(new ButtonListener()); private class ButtonListener implements View.OnClickListener{ @Override public void onClick(View arg0) { // TODO Auto-generated method stub switch(arg0.getId()){ case R.id.btn_Demo: //具体点击操作的逻辑 break; default: break; } } } 方法三:Activity继承View.OnClickListener 适合场景:适合界面上有不同类型的控件,这种方式将所有控件的onClick方法在一个方法里面实现,看起来比较简洁
public class MyActivity extends Activity implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.
1.查看当前使用的语言:
echo $LANG 修改之前: en_US.UTF-8 英文 修改之后: zh_CN.UTF-8 中文 2.查看当前系统默认采用的字符集
locale 修改之前: [root@root ~]# locale LANG=en_US.UTF-8 LC_CTYPE="en_US.UTF-8" LC_NUMERIC="en_US.UTF-8" LC_TIME="en_US.UTF-8" LC_COLLATE="en_US.UTF-8" LC_MONETARY="en_US.UTF-8" LC_MESSAGES="en_US.UTF-8" LC_PAPER="en_US.UTF-8" LC_NAME="en_US.UTF-8" LC_ADDRESS="en_US.UTF-8" LC_TELEPHONE="en_US.UTF-8" LC_MEASUREMENT="en_US.UTF-8" LC_IDENTIFICATION="en_US.UTF-8" 修改之后: [root@root conf]# locale LANG=zh_CN.UTF-8 LC_CTYPE="zh_CN.UTF-8" LC_NUMERIC="zh_CN.UTF-8" LC_TIME="zh_CN.UTF-8" LC_COLLATE="zh_CN.UTF-8" LC_MONETARY="zh_CN.UTF-8" LC_MESSAGES="zh_CN.UTF-8" LC_PAPER="zh_CN.UTF-8" LC_NAME="zh_CN.UTF-8" LC_ADDRESS="zh_CN.UTF-8" LC_TELEPHONE="zh_CN.UTF-8" LC_MEASUREMENT="zh_CN.UTF-8" LC_IDENTIFICATION="zh_CN.UTF-8" LC_ALL= 3.下载安装中文语言包
yum install kde-l10n-Chinese 4.修改系统字符集
临时修改: export LANG="zh_CN.UTF-8" 永久修改: #将单引号中的语句写入到 /etc/profile 文件 echo 'export LANG="zh_CN.UTF-8"' >> /etc/profile #修改之后,重新加载 profile 文件(使之立即生效) source /etc/profile 5.修改文件的字符集
背景
OceanBase数据库是分布式数据库,每个表甚至每个表的不同分区都可能存放在不同的机器上。想要对表进行读写,必须 先要定位到数据所属的表或是分区的主副本位置,然后才能执行相应的SQL DML语句,这在应用层面而言是几乎不可能做到的
OBProxy作为OceanBase数据库专用的反向代理软件,其核 心功能就是路由以将客户端发起的数据访问请求转发到正确的OBServer上
客户端通过OBProxy访问OceanBase数据库的数据链路如 图所示,用户通过任意Client驱动发出请求,请求通过负载 均衡组件访问到任意一台无状态的 OBProxy上,然后OBProxy 再将用户请求转发到后端 OceanBase 集群中最佳的 OBServer 上去执行
OBProxy核心功能(路由)
OBProxy作为OceanBase的高性能反向代理服务器,其核心功能就是路由转发
OBProxy路由的目标是将具体SQL转发到最恰当的Server上执行,路由的核心过程包括:
简单的SQL Parser,LDC路由,读写分离,备优先读,黑名单机制,下图为OBproxy的路由逻辑
路由功能举例
OBProxy核心功能(连接管理)
在observer宕机/升级/重启时,客户端与OBProxy的连接不会断开,OBProx可以迅速切换到正常的server上,对应用透明
OBProxy支持用户通过同一个OBProxy访问多个OceanBase集群
Server session对于每个client session独占
同一个client session对应server session状态保持相同(session变量同步)
OBProxy核心功能(监控&&运维)
周期性汇报统计项到OCP,实现了语句级别,事务级别,session级别,Obproxy级别的各种统计
Xflush日志监控(包括慢查询监控、error包监控等)
SQL Audit功能
实现了大量内部命令来实现远程监控,查询和运维
C++ 后端都是干什么的? C++ 后端开发主要涉及到构建和维护基于 C++ 的服务器端应用程序。C++ 是一种高性能的编程语言,广泛应用于需要高性能和底层系统访问的场景。C++ 后端开发人员通常专注于以下几个方面:
性能优化:C++ 具有良好的性能特性,因此后端开发人员通常会关注代码性能优化,以确保应用程序运行得更快、更高效。
服务器端应用程序开发:C++ 后端开发人员负责构建和维护基于 C++ 的服务器端应用程序,包括处理客户端请求、与数据库交互、实现业务逻辑等。
分布式系统:构建和维护大规模分布式系统,以支持高并发、高吞吐量的需求。
网络编程:C++ 后端开发人员需要具备网络编程知识,如套接字编程、TCP/IP、HTTP 等,以便更好地处理服务器端与客户端之间的通信。
安全性:确保服务器端应用程序和数据的安全,通过加密、安全传输和访问控制等手段来保护数据和应用程序。
内存管理:C++ 后端开发人员需要关注内存管理,以避免内存泄漏、内存溢出等问题。
C++后端都有哪些工作岗位呢? 在 C++ 后端领域,有以下一些典型的工作岗位:
后端开发工程师:负责服务器端应用程序的开发和维护。
系统架构师:负责设计和规划后端系统的架构,以满足性能、可扩展性和可维护性的要求。
性能工程师:专注于优化代码性能,提升应用程序的运行效率。
网络工程师:负责处理网络相关的问题,如网络通信、协议实现等。
数据库工程师:专注于后端数据存储、检索和优化。
这些岗位可能会有一定的重叠,具体职责可能因公司和项目而异。不同公司可能会有不同的职位名称,但核心技能和职责通常是相似的。
做完大学生的你,该为你的面试准备些什么 想要从事 C++ 后端开发工作,您需要掌握一定的技能和知识。以下是一些建议,可以帮助您为未来的职业做好准备:
掌握 C++ 语言基础:学习 C++ 的基本语法、数据结构、面向对象编程等基本概念。您可以通过阅读书籍、在线课程和教程来学习 C++。
学习操作系统基础:熟悉操作系统的基本概念,如进程、线程、内存管理等。这对于理解 C++ 后端开发中的底层概念非常重要。
学习计算机网络:掌握网络基本概念,如 OSI 模型、TCP/IP 协议栈、网络编程等。这将帮助您更好地理解服务器与客户端之间的通信。
学习数据结构与算法:掌握常见的数据结构(如链表、队列、栈、树等)和算法(如排序、查找等)。这将有助于您编写高效且可维护的代码。
了解数据库技术:学习数据库的基本原理和常用数据库管理系统(如 MySQL、PostgreSQL 等),了解 SQL 语言以及如何在 C++ 代码中与数据库交互。
学习后端框架和库:熟悉一些常用的 C++ 后端框架和库,如 Boost.Asio、Poco、cpprestsdk 等,这将帮助您更快地开发后端应用程序。
实践项目经验:尝试参与一些实际的项目,这可以是开源项目、课程作业或个人项目。通过实践项目经验,您可以更好地理解 C++ 后端开发的实际工作,并巩固所学知识。
跟踪行业动态:关注 C++ 社区和后端开发领域的最新动态,了解最新的技术和趋势。
培养良好的编程习惯:学会编写简洁、易读、可维护的代码,并养成编写文档和注释的习惯。
拓展相关技能:了解与后端开发相关的其他技能,如 DevOps、容器技术(如 Docker)、云计算等。
CLIP论文翻译、Learning Transferable Visual Models From Natural Language Supervision翻译 文章目录 CLIP论文翻译、Learning Transferable Visual Models From Natural Language Supervision翻译Abstract1. Introduction and Motivating Work2. Approach2.1 Natural Language Supervision2.2 Creating a Suffificiently Large Dataset2.3 Selecting an Effificient Pre-Training Method2.4 Choosing and Scaling a Model2.5 Training 3. Experiments3.1 Zero-Shot Transfer3.1.1. MOTIVATION3.1.2. USING CLIP FOR ZERO-SHOT TRANSFER3.1.3. INITIAL COMPARISON TO VISUAL N-GRAMS3.1.4. PROMPT ENGINEERING AND ENSEMBLING3.1.5. ANALYSIS OF ZERO-SHOT CLIP PERFORMANCE 别着急,还没翻译完,论文太长了,这段时间工作也忙,会把他研究完的,记得收藏回来看啊 Abstract State-of-the-art computer vision systems are trained to predict a fixed set of predetermined object categories.
matlab:人脸识别 Matlab人脸识别是一种利用计算机技术进行人脸识别的方法,其基本流程如下: 数据采集:使用数字相机或摄像机采集人脸图像,得到一系列图像数据。 图像预处理:对采集到的图像数据进行预处理,包括图像去噪、图像增强、图像对齐等操作。 特征提取:从预处理后的图像数据中提取出人脸的特征,包括颜色、纹理、形状等特征。 特征匹配:将提取出的特征与已知的人脸特征进行比对匹配,找到最相似的人脸。 结果输出:根据匹配结果输出识别结果,即识别出的人脸信息。 Matlab人脸识别常用的算法包括PCA(Principal Component Analysis,主成分分析)、LDA(Linear Discriminant Analysis,线性判别分析)、SVM(Support Vector Machine,支持向量机)等。这些算法都是基于数学模型,利用图像处理、模式识别等技术来实现人脸识别。 在Matlab中,可以使用一些开源的人脸识别工具箱,如Face Recognition Toolbox、Face Recognition System Toolbox等,来实现人脸识别应用。这些工具箱提供了一些常用的算法和函数,方便用户进行开发和测试。同时,Matlab还提供了一些图像处理和机器学习的函数库,可以辅助完成人脸识别算法的开发和实现。 该博文为原创文章,未经博主同意不得转载。
本文章博客地址:https://cplusplus.blog.csdn.net/article/details/129862222
Java使用WebService 说明:仅提供了如何使用,原理无
文章目录 Java使用WebService一、服务端1、引入依赖2、编写配置类3、编写接口4、编写实现类 二、客户端1、引入依赖2、配置3、创建客户端4、创建使用工具类5、接口共通6、调用 一、服务端 1、引入依赖 <!-- webservice --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.3.3</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>3.2.2</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.1.12</version> </dependency> <!-- 有的需要这个有的不需要这个,我没用到 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web-services</artifactId> </dependency> 2、编写配置类 package com.access.config; import javax.xml.ws.Endpoint; import com.access.service.AccessService; import lombok.extern.slf4j.Slf4j; import org.apache.cxf.Bus; import org.apache.cxf.bus.spring.SpringBus; import org.apache.cxf.jaxws.EndpointImpl; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.annotation.Resource; /** * webservice配置类 * * @author 微笑 * @version 1.0 * @since 2023/2/23 15:52 */ @Slf4j @Configuration public class WebServiceConfig { @Resource private AccessService accessService; /** * Apache CXF 核心架构是以BUS为核心,整合其他组件。 * Bus是CXF的主干, 为共享资源提供一个可配置的场所,作用类似于Spring的ApplicationContext,这些共享资源包括 * WSDl管理器、绑定工厂等。通过对BUS进行扩展,可以方便地容纳自己的资源,或者替换现有的资源。默认Bus实现基于Spring架构, * 通过依赖注入,在运行时将组件串联起来。BusFactory负责Bus的创建。默认的BusFactory是SpringBusFactory,对应于默认 * 的Bus实现。在构造过程中,SpringBusFactory会搜索META-INF/cxf(包含在 CXF 的jar中)下的所有bean配置文件。 * 根据这些配置文件构建一个ApplicationContext。开发者也可以提供自己的配置文件来定制Bus。 */ @Bean(name = Bus.
对于测试来说,要做可视化工具,需要GUI界面(就是可视化的UI界面)的工具开发,java模块有提到过,现在python我们也来一版,python主页上有支持的GUI插件,总有一款适合你。
Welcome to Python.org
像这种GUI界面的开发,本人特喜欢拖动控件方式编辑,简单方便,所以这里选择PyQt5插件。
参考:Python如何直接拖拽控件实现GUI编程?可以实现吗?-电脑设置问题-东森IT信息网
一、安装:
pip install pyqt5 pyqt5designer 安装完成后,在Python安装目录Lib->site-packages->PyQt5->Qt->bin中找到designer.exe程序,也就是QtDesigner设计工具,双击运行这个程序,如图:
设置你的UI界面完成后,即保存D:\gui.ui,此时保存的不是py文件,所以需要pyuic5转换为py文件。
pyuic5 -o gui.py D:\gui.ui
从一个git仓库拷贝到另一个git仓库,保留git提交记录
1. 从原地址克隆一份裸版本库 –bare 创建的克隆版本库都不包含工作区,直接就是版本库的内容,这样的版本库称为裸版本库。
git clone --bare http: //....(原始old仓库地址) 2、进入克隆下来的目录 cd project.git(project即为你的项目名称) 3、以镜像推送的方式上传代码到新的仓库地址 git push --mirror http://...(目标new仓库地址) 4、删除旧仓库的克隆版 cd .. rm -rf project.git
R-CNN算法详细解读 R-CNN系列from R-CNN to Mask-RCNNsliding windows detectorSelective searchR-CNNFast R-CNNFaster R-CNNFPNMask-RCNN R-CNN系列 比较好的博客参考:RCNN系列 from R-CNN to Mask-RCNN R-CNNFast R-CNNFaster R-CNNFPNFPN + RPN + Fast R-CNNFPN + RPN + Fast R-CNN + Mask Prediction sliding windows detector 滑动窗口是最开始用的一种目标检测的方法,是一种比较暴力的方法
过程:输入一张图片,设置多种尺度的BBox,对输入图片从左到右、从上到下进行滑动BBox,裁剪出BBox_img,然后输入到CNN中进行识别判断。
缺点:暴力搜索,非常耗时
Selective search 为了解决暴力搜索太耗时的问题,R-CNN使用选择性搜索的方法,生成候选区域。生成候选区域的方法有很多种,作者选着了selective search方法,因为R-CNN检测图像时,是不知道这个图像中有什么的,也就没法针对某种目标来生成候选区域,selective search方法是以颜色,纹理等特征的相似度将像素点合并成区域的算法,相比于滑动窗口的方法复杂度更低。选择性搜索方法,进行区域建议,在输入图片中对像素进行“聚类”处理(相似的区域进行融合,得到bbox),得到很多ROIs,然后将ROIs输入到CNN中进行识别。
R-CNN 整体框架
整体描述:①输入图片首先经过 Region proposal ,使用 selective search 方法得到2000 ROIs;生成的ROIs可能大小不一样,然后resize成相同大小ROI;②接着将相同尺寸的ROIs输入到CNN网络进行特征提取;③最后将特征送入每一类的SVM 分类器,判别是否属于该类;④并且进行位置精修,即使用回归器(边框回归)精细修正候选框位置。注意:为什么要进行边框回归,因为Selective search得到的ROIs应该是不准确的,所以需要回归!
具体说:
区域候选框的生成: Selective Search 的前期工作就是利用Graph-Based Image Segmentation的分割算法产生初始的分割区域,然后使用相似度计算方法合并一些小的区域,参考
(CNN)特征提取:采用的是AlexNet,由五个卷积层,两个全连接层组成,输出的特征是4096维的向量。由于这个网络要求的输入格式是227x227的RGB图像,所以将候选区域全部resize成227x227(最简单的变换方法),然后减均值输入到网络中。注意,resize前,在边框四周填充16个像素,再进行 各向异性 缩放, 这种形变使得mAp提高了3到5个百分点。
关于ROI缩放到固定尺寸的方法: 主要分为各向异性和各向同性两种方法,参考。结合下图讲,其中各向异性就是最简单的变换,就是不管图片的长宽比例,管它是否扭曲,进行缩放就是了(D)。因为图片扭曲后,估计会对后续CNN的训练精度有影响,作者也测试了“各向同性缩放”方案,有两种办法:①先扩充后裁剪(B);②先裁剪后扩充(C)。文献还有个padding处理,下面的示意图中,每个例子,上面的行采用padding=0,下面一行采用padding=16。经过最后的试验,作者发现采用各向异性缩放、padding=16的精度最高。
边框回归怎么做(重点,目标检测中都用)
参考链接 Visual Studio中的C++程序如何使用第三方静态库和动态库? - 掘金
1,添加库文件路径 在 Visual Studio 2022 中,可以通过在项目属性页面中添加库文件的目录,让编译器知道需要链接的库文件的位置。具体步骤如下:
打开项目属性页面:在“解决方案资源管理器”中右键单击要配置的项目,选择“属性”菜单项。
选择“VC++ 目录”选项卡:在“属性页”中选择“VC++ 目录”选项卡。添加包含目录:在“包含目录”中添加库文件的路径,包括 .h 文件所在的目录。
添加库目录:在“库目录”中添加库文件的路径,包括 .lib 文件所在的目录和 .dll 文件所在的目录。
添加库文件名 同样是在项目属性页面中添加库文件的名称,让编译器知道需要链接的库文件的名称。具体步骤如下:
打开项目属性页面:在“解决方案资源管理器”中右键单击要配置的项目,选择“属性”菜单项。
选择“链接器”选项卡:在“属性页”中选择“链接器”选项卡。
需要注意的是,对于 .dll 文件,还需要将其复制到可执行文件所在的目录下。也就是需要拷贝库文件到生成exe程序的路径下
除了将 DLL 文件复制到可执行文件所在的目录下,还可以通过设置动态链接库的路径来指定 DLL 文件的位置。具体来说,可以通过以下方法之一来设置动态链接库的路径:
使用 SetDllDirectory 函数来设置 DLL 文件所在目录的路径。
#include <Windows.h> int main() { SetDllDirectory(L"C:\\path\\to\\dlls"); // ... return 0; } 复制代码 在程序中使用 LoadLibrary 函数加载 DLL 文件时,指定 DLL 文件的完整路径。
#include <Windows.h> int main() { HMODULE hDll = LoadLibrary(L"C:\\path\\to\\mydll.dll"); if (hDll == NULL) { // 处理加载失败的情况 } // .
一维数组与二维数组 前言一、 一维数组1.1 一维数组定义和使用1.2 例子 :列出0-9的数字1.3 一维数组的初始化1.4 数组名 二、二维数组2.1 二维数组的定义2.2 例题:一个学习小组有 5 个人,每个人有 3 门课程的考试成绩,求该小组各科的平均分和总平均分。2.3 二维数组初始化 总结 前言 数组:
相当于在程序设计中,为了方便处理数据把具有相同类型的若干变量并有序形式组织排列起来,数组就是在内存中连续的相同类型的变量空间。同一个数组所有的成员都是相同的数据类型,同时所有的成员在内存中的地址是连续的。
一、 一维数组 1.1 一维数组定义和使用 注意事项:
1、数组名字符合标识符的书写规定(数字、英文字母、下划线)。
2、数组名不能与其它变量名相同,同一作用域内是唯一的。
3、方括号 [ ] 中常量表达式表示数组元素的个数。
int a[3]表示数组a有3个元素
其下标从0开始计算,因此3个元素分别为a[0],a[1],a[2]
定义数组时 [ ] 内最好是常量,使用数组时 [ ] 内即可是常量,也可以是变量
1.2 例子 :列出0-9的数字 代码:
#include <stdio.h> int main() { int a[10];//定义了一个数组,名字叫a,有10个成员,每个成员都是int类型 //a[0]…… a[9],没有a[10] //没有a这个变量,a是数组的名字,但不是变量名,它是常量 a[0] = 0; //…… a[9] = 9; int i = 0; for (i = 0; i < 10; i++) { a[i] = i; //给数组赋值 } //遍历数组,并输出每个成员的值 for (i = 0; i < 10; i++) { printf("
流式数据湖存储技术,Apache Paimon是什么? 00 导读01 什么是 Apache Paimon02 开放的数据格式03 大规模实时更新04 数据表局部更新05 流批一体数据读写 来源:https://paimon.apache.org/
00 导读 2023年3月12日,Flink Table Store 项目顺利通过投票,正式进入 Apache 软件基金会 (ASF) 的孵化器,改名为 Apache Paimon (incubating)。
Flink 社区希望能够将 Flink 的 Streaming 实时计算能力和 Lakehouse 新架构优势进一步结合,推出新一代的 Streaming Lakehouse 技术,促进数据在数据湖上真正实时流动起来,并为用户提供实时离线一体化的开发体验。
01 什么是 Apache Paimon Apache Paimon (incubating) 是一项流式数据湖存储技术,可以为用户提供高吞吐、低延迟的数据摄入、流式订阅以及实时查询能力。
Paimon 采用开放的数据格式和技术理念,可以与 Apache Flink / Spark / Trino 等诸多业界主流计算引擎进行对接,共同推进 Streaming Lakehouse 架构的普及和发展。
02 开放的数据格式 Paimon 以湖存储的方式基于分布式文件系统管理元数据,并采用开放的 ORC、Parquet、Avro 文件格式,支持各大主流计算引擎,包括 Flink、Spark、Hive、Trino、Presto。未来会对接更多引擎,包括 Doris 和 Starrocks。
03 大规模实时更新 得益于 LSM 数据结构的追加写能力,Paimon 在大规模的更新数据输入的场景中提供了出色的性能。
注:本文仅适用于有Docker容器使用基础、Linux命令基础的编程人员,请确保Linux中已经安装了Docker。
Step1:创建Docker容器网络 由于Kafka在2.8.0版本以前,强依赖于Zookeeper,所以我们需要创建一个Docker容器网络以用于Kafka容器和Zookeeper容器的互通。
注:本文使用的是CentOS7系统作为虚拟环境,并确保登录的账号拥有足够的权限。
执行以下命令,即可创建一个Docker网络:
docker network create --driver bridge --subnet 172.0.0.0/16 toneyma_network 以上命令解释为:创建一个名为"toneyma_network",地址池为"172.0.0.0/16"的容器网络。
172.0.0.0 #地址池
16 #子网掩码(用于划分网段)
toneyma_network #名称(随便起)
Step2:拉取Zookeeper容器并启动 本文中,直接使用VMware提供的最新版(3.8.1)的Zookeeper容器。
注:在DockerHub提供的信息中,bitnami版本即为VMware提供的版本。
执行以下命令,获取最新的Zookeeper容器:
docker pull bitnami/zookeeper:latest 执行以下命令,启动Zookeeper容器:
docker run -d --name zookeeper-server \ --network toneyma_network \ -p 2181:2181 \ -e ALLOW_ANONYMOUS_LOGIN=yes \ bitnami/zookeeper:latest 以上命令解释为:启动"bitnami/zookeeper:latest"容器,该容器命名为"zookeeper-server",并使用名为"toneyma_network"的容器网络。
参数:
--name zookeeper-server #指定容器名称为"zookeeper-server"
--network toneyma_network #指定容器网络为"toneyma_network"
-p 用来访问的端口号:2181 #端口映射(格式为 外部访问用的端口号:容器内应用的端口号 外部访问用的端口号不能在本机被占用,容器内应用使用的端口号需要从DockerHub中查询,或者是官方默认端口号)
-e ALLOW_ANONYMOUS_LOGIN=yes #是否允许接受来自未经身份验证的用户的连接。(默认为no,所以这里要改为yes,方便本地连接)
其他参数请在以下链接中查询:bitnami/zookeeper - Docker Image | Docker Hubhttps://hub.docker.com/r/bitnami/zookeeper
Step3:拉取Kafka容器并依赖Zookeeper启动 本文中,直接使用VMware提供的最新版(3.2.3)的Kafka容器。
1、WT588D 模块内部电路
WT588D 模块目前有 WTW-16P(16 脚模块)及 WTW-28P(28 脚模块)两种。
1.1、WTW-16P 模块内部电路
WTW-16P 采用 WT588D-20SS 做为核心控制电路,WTW-16P 内部包含了 WT588D-20SS 外围所需的 SPI-FLASH、 震荡电路、复位电路。外部只需要接上电源、控制端以及扬声器(或者功放)就能正常工作。
1.2、WTW-28P 模块内部电路
WTW-28P 采用 WT588D-32L 做为核心控制电路,WTW-28P 内部包含了 WT588D-32L 外围所需的 SPI-FLASH、震荡电路、复位电路。外部只需要接上电源、控制端以及扬声器(或者功放)就能正常工作。
2、WT588D-18P 应用电路
2.1、WT588D-18P 按键控制 PWM 输出应用电路
软件设置: 按键控制模式。
I/O 口定义: 选取 I/O 口 P00、P01、P02、P03 作为触发口,在编辑 WT588D 语音工程时,把触发口的按键定义为可触发播放的触发方式,就可进行工作。
BUSY 输出: P17 为 BUSY 忙信号输出端,可从上位机软件端设置为播放状态输出为高电平或低电平。高电平时电压接近 VDD供电电压。用于接发光二极管做放音状态指示或忙信号判断。
供电电压: VDD=DC2.8~5.5V,VCC=DC2.7~3.5V。采用 DC3.3V 供电时,可以直接短接 VDD 跟 VCC,采用 DC5V 供电时,VDD 端接 5V,VCC 端需要从 VDD 端串接两个二极管以提供工作电压。
音频输出: PWM 输出方式,直接接扬声器。此种输出方式下,PWM+、PWM-均不能短接到地或者接电阻电容到地。
文章目录 游戏结束以及重启游戏建个游戏结束页面编写委托类 游戏主角 以及 ui管理类的脚本重启游戏 游戏结束以及重启游戏 思路:利用Canvas创建好覆盖全屏的结束页面,默认关闭。游戏结束时,玩家控制的对象发起委托,ui管理收下委托,显示游戏结束页面,停止游戏。游戏重新开始就是点击设置好的按钮,启动ui管理里的重新开始场景
建个游戏结束页面 编写委托类 游戏主角 以及 ui管理类的脚本 委托类
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; public class EventHander : MonoBehaviour { //通知游戏结束 public static event Action GetGameOverEvent; public static void CallGetGameOverEvent () { GetGameOverEvent ? .Invoke(); } } 游戏主角脚本
//青蛙是否死亡 private bool isdead; //游戏结束 if (isdead) { EventHander.CallGetGameOverEvent(); } 在游戏结束的一些判断里把isdead改成true即可。
ui管理脚本
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class UiManager : MonoBehaviour { //游戏结束页面的操作 public GameObject gameOverPanel; //脚本刚被调用时使用 private void OnEnable() { //恢复游戏速度游戏正常进行 Time.
使用Gradle进行项目构建管理 安装配置Gradle
Gradle的安装与配置
创建项目
使用gradle init命令创建root项目
E:\code\myself\china-unicorn>gradle init Starting a Gradle Daemon, 1 busy Daemon could not be reused, use --status for details Select type of project to generate: 1: basic 2: application 3: library 4: Gradle plugin Enter selection (default: basic) [1..4] 1 Select build script DSL: 1: Groovy 2: Kotlin Enter selection (default: Groovy) [1..2] 1 Generate build using new APIs and behavior (some features may change in the next minor release)?
Rocky linux9 配置网卡 #编辑网卡,ens160是网卡名字 vi /etc/NetworkManager/system-connections/ens160.nmconnection connection] id=ens160 uuid=1e1529bf-0e33-3b5d-bd1e-7dc5e8174302 type=ethernet autoconnect-priority=-999 interface-name=ens160 timestamp=1668440312 [ethernet] [ipv4] address1=192.168.0.113/24,192.168.0.254 #第一个是网卡IP后面的是网卡网关 dns=192.168.0.113; #DNS配置 may-fail=false #加上 method=manual [ipv6] addr-gen-mode=eui64 method=auto [proxy] ~ #保存并退出:wq #然后直接连接机活重启网卡 nmcli c r ens160 nmcli c u ens160 ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 00:0c:29:72:77:2e brd ff:ff:ff:ff:ff:ff altname enp3s0 inet 192.
一、打开与显示 import cv2 from PIL import Image import matplotlib.pyplot as plt img_path = 'E:\\360MoveData\\Users\\Administrator\\Desktop\\111.JPG' img_cv = cv2.imread(img_path) cv2.imshow('111', img_cv) cv2.waitKey() img_PIL = Image.open(img_path) plt.imshow(img_PIL) plt.show() 二、CV2转PIL img_PIL = Image.fromarray(cv2.cvtColor(img_cv,cv2.COLOR_BGR2RGB)) 三、PIL转CV2 import numpy as np img_cv = cv2.cvtColor(np.asarray(img_PIL), cv2.COLOR_RGB2BGR) 四、判断一张图是CV2 flag = isinstance(img_cv,np.ndarray) 五、判断一张图是PIL from PIL import ImageFile flag = isinstance(img_PIL,ImageFile.ImageFile) 六、区别 Opencv 读取为BGR,PIL读取为RGB(误X),对普通的图像是RGB,如果图片本身是其他模式,就不是RGB了
七、比较PIL和jpeg读取图像是否一致 img = cv2.imread(img_path) fd = Image.open(img_path) # opencv BGR ,PIL RGB, 读出来的图片不一样 pil_fd = cv2.cvtColor(np.array(fd), cv2.
团队模型、论文、博文、直播合集,点击此处浏览 一、论文 论文链接: Improved Fine-Tuning by Better Leveraging Pre-Training Data 代码链接:https://github.com/ziquanliu/NeurIPS2022_UOT_fine_tuning
二、背景 在下游任务中对预训练模型进行微调被广泛用于许多深度学习的应用中。最近的深度学习的研究主要聚焦在预训练数据充分的情况下如何训练更强大的预训练模型,然而预训练模型在下游的使用往往面临着数据不充分的困难。另一方面,最近的研究经验表明,一旦在某些视觉任务中增加了训练样本的数量,从头开始训练的最终性能并不比这种预训练策略差。在这项工作中,我们使用学习理论中流行的超额风险界限,从泛化分析的角度重新审视了这一现象。当下游数据有限时,我们提出利用预训练数据进行微调。使用预训练数据来进行微调的泛化结果表明,当微调中包含适当的预训练数据时,可以改善目标任务的过度风险界限。基于我们的理论分析,我们提出了一种新的选择策略,从预训练数据中选择一个子集,以帮助提高对目标任务的泛化能力。我们的方法如下图所示。
三、理论分析 首先定义下游的目标函数和上游预训练函数,然后我们对这两个函数的性质做出如下四个假设。其中第一个假设是对两个训练分布的相似性给一个上界,第二和第三是描述优化目标函数的unbiased, bounded variance和smoothness性质,第四个是常用的PL condition.
给定以上四个假设,我们可以得到下面的引理。引理1说明了当下游数据的数据量到达一定程度的时候,预训练模型对于随机初始化来说其实没有什么优势。这个引理也解释了之前人们在实验中发现的现象[1]。
当下游任务的数据量有限时,我们提出在fine-tuning时重复利用预训练数据。具体来说我们在fine-tuning时把两个训练数据的损失函数做一个加权,然后用两部分数据训练这个网络。在实际的操作中,我们对于下游数据和预训练数据使用不同的线性分类器,以便我们可以使用任意数量的下游类别,而且下游和预训练的标签互不影响。
对于这种joint fine-tuning的效果,我们推导了如下定理。该定理说明,如果我们能够选取适当的预训练数据,使得两个训练数据的距离缩小,那么joint fine-tuning的效果会变得更好。
四、数据选择 我们提出一种基于unbalanced optimal transport的通用的数据选择方法,简记为UOT数据选择。我们的思想是找到一个运输方式把预训练数据运输到下游数据,而这种运输方式体现了预训练数据的某个类和下游数据的距离。我们发现这种UOT数据选择的方式在选择相似数据上非常的有效,如下图所示。因为CUB数据只包含鸟类图片,所以我们知道这时候需要从预训练集上选择的数据是鸟类。UOT成功地选择了几乎所有ImageNet中的鸟类
五、结果 1. 效果展示 我们分别用有监督和无监督的预训练模型在8个下游数据集上做了我们的实验。当预训练数据集无标签时,我们用K-means聚类给数据打上伪标签。实验结果表明,我们的UOT joint-fine-tuning在多数数据集上取得了最优的效果。
2. 小数据集与长尾类分布 我们进一步模拟了下游的小数据集和长尾类分布的情况。左图中我们展示了对CUB和Caltech数据集按类进行数据量下采样的实验结果。当数据量越小时,我们的UOT方法取得了越大的提升。右表显示了我们对于3个数据集进行长尾累分布采样后,再进行UOT和标准微调的结果。我们的方法在这种情况下取得了显著更好的结果。
六、参考文献 [1] He, Kaiming, Ross Girshick, and Piotr Dollár. "Rethinking imagenet pre-training." Proceedings of the IEEE/CVF International Conference on Computer Vision. 2019.
七、应用 接下来给大家介绍下我们研发的各个域上的开源免费模型,欢迎大家体验、下载(大部分手机端即可体验):
ModelScope 魔搭社区
ModelScope 魔搭社区
ModelScope 魔搭社区
ModelScope 魔搭社区
ModelScope 魔搭社区
背景 公司业务需要用到RK3588 的RGA进行图像处理加速,网上搜了下,这方面的资料很少,在此记录下自己从熟悉文档到应用的整个过程,给有相关需求的小伙伴做个参考。
一、什么是RGA RGA (Raster Graphic Acceleration Unit)是一个独立的2D硬件加速器,可用于加速点/线绘制,执行图像缩放、旋转、格式转换等常见的2D图形操作。
二、RK3588 RGA及代码示例 2.1 从git拉取官方文档及sample示例 git clone https://github.com/airockchip/librga cd librga 其中 include 是相关头文件,libs是运行库,samples是代码示例。注意:官方demo是有默认的验证源文件,开始前先看下图对应的md文件。
2.2 图像缩放或者放大 本示例代码是在官方resize_demo的基础上进行改动、验证。说明:因为是Debian系统,安装opencv会报错,缺少libjasper库。网上搜了下比较麻烦,本人使用的先在Ubuntu先编译好的opencv库。
代码功能:使用opencv读取本地 1.jpg 图片,调用RGA resize接口进行图片缩小和放大,再使用opencv保存为新的文件。BIG宏定义是用来执行控制放大还缩操作。
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "im2d_version.h" #include "im2d_type.h" #include "im2d_single.h" #include "im2d_common.h" #include "im2d_buffer.h" #include "RgaUtils.h" #include "src/utils/utils.h" #include "./opencv2/core/core.hpp" #include "./opencv2/highgui/highgui.hpp" using namespace std; using namespace cv; #define BIG #ifdef BIG #define RESIZE_WIDTH 1920 #define RESIZE_HEIGHT 1080 #define SCALE_NAME "
出现过问题
ERROR: Failed building wheel for numpy下载了whl文件后报错ERROR: numpy-1.22.4+mkl-cp38-cp38-win_amd64.whl is not a supported wheel on this platform. 综合多篇博客的解决方法:
1. 使用pip debug --verbose 命令即可看 pip 支持 在compatible tags中查看pip支持的版本 然后在https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta官网中下载对应的轮子 将下载的轮子存储在python所在的Scripts文件中 然后在vscode终端输入pip install numpy -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com 我根据上述步骤最终是成功了
踩过的雷
直接pip install 轮子文件(❌)
使用pip._internal命令查看支持版本(❌)
祝成功!加油!
害怕的本身是最可怕的,除此之外,没什么是可怕的。 ——杀死一只知更鸟
使用字符串的replace方法匹配正则替换,直接上代码:
var str = "<p>这是一一段文字</p>" str = str.replace(/<.+?>/g,"") console.log(str) //这是一段文字
寻路系统简介 寻路系统是游戏开发中非常重要的一部分,它决定了游戏中角色的移动方式以及如何避免障碍物。在Unity中,有多种寻路方式可供选择,包括NavMesh、A*算法、Dijkstra算法等等。本文将介绍一种基于NavMesh的寻路系统,并提供代码示例。
NavMesh简介 NavMesh是Unity中用来表示地形的网格。它可以被用来制作一个可行走的路径,使得游戏中的角色可以沿着该路径进行移动。NavMesh由多个三角形组成,其中每个三角形都有一个法线和顶点信息。
寻路系统实现 以下是一个简单的NavMesh寻路系统的实现过程:
创建NavMesh: 在Unity中,首先需要设置一个NavMesh区域。这可以通过选择场景中的对象并在Inspector窗口中启用NavMesh组件来完成。
添加Agent: 对象需要添加一个NavMeshAgent组件才能进行移动。该组件定义了对象的移动速度、转弯速度等参数。
设置目的地: 为了让对象移动,需要向其提供一个目标点。这可以通过调用NavMeshAgent组件的SetDestination()函数来完成。
移动对象: 一旦设置了目的地,对象将自动沿着路径移动。可以使用NavMeshAgent组件的velocity属性检查对象的当前速度。如果需要对对象进行更精细的控制,可以使用NavMeshAgent组件的Move()函数代替SetDestination()函数。
避免障碍物: 如果场景中有障碍物,需要确保对象能够避免它们。这可以通过设置NavMeshAgent组件的obstacleAvoidanceType属性为高级或者通过手动调整NavMesh来实现。
代码示例 以下是一个简单的代码示例,演示如何在Unity中使用NavMesh来实现寻路系统:
using UnityEngine; using UnityEngine.AI; public class NavMeshExample : MonoBehaviour { public Transform target; private NavMeshAgent agent; void Start () { agent = GetComponent<NavMeshAgent>(); } void Update () { if (target != null) { agent.SetDestination(target.position); } } } 在此示例中,我们创建了一个名为NavMeshExample的脚本,并向其添加了一个目标点。然后,我们在Start()函数中获取了NavMeshAgent组件。在Update()函数中,我们使用SetDestination()函数设置对象的目标点。
总结 使用NavMesh来实现游戏中的寻路系统非常方便,因为它可以自动避开障碍物并提供高效的路径计算。这篇文章提供了一个简单的代码示例,以帮助开发人员更好地理解如何在Unity中使用NavMesh来实现寻路系统。
对于后端返回的数据处理:挑选出电话号码,点击可以拨号
重点:
<a href="tel:电话号码">电话号码</a> 示例:
const checkPhone = function (data) { // 校验座机(可以根据需求对数据进行修改) let regtel = /\d{3,4}-\d{7,8}/g // 校验手机(可以根据需求对数据进行修改) let regphone = /[1][3,4,5,7,8][0-9]{9}/g let reslut = data let testData // 利用a标签承接电话号码 while ((testData = regtel.exec(data)) !== null) { reslut = reslut.replace(testData[0], `<a href="tel:${testData[0]}">${testData[0]}</a>`) } while ((testData = regphone.exec(data)) !== null) { reslut = reslut.replace(testData[0], `<a href="tel:${testData[0]}">${testData[0]}</a>`) } //返回新的结果 return reslut }
Ajax的核心是XMLHttpRequest对象
1、原生
/* let xhr=new XMLHttpRequest(); (1)XMLHttpRequest 对象方法 方法 描述 newXMLHttpRequest() 创建新的XMLHttpRequest对象 abort() 取消当前请求 getAllResponseHeaders() 返回头部信息 getResponseHeader() 返回特定的头部信息 open(method,url,async,user,psw) 规定请求 method:请求类型;GET或POSTurl:文件位置;async:true(异步)或false(同步);user:可选的用户名称;psw:可选的密码 send() 将请求发送到服务器,用于GET请求 send(string) 将请求发送到服务器,用于POST请求 setRequestHeader() 向要发送的报头添加标签/值对 (2)XMLHttpRequest对象属性 属性 描述 onreadystatechange 定义当readyState属性发生变化时被调用的函数 readyState 保存XMLHttpRequest的状态。0:请求未初始化;1:服务器连接已建立;2:请求已收到;3:正在处理请求;4:请求已完成且响应已就绪 responseText 以字符串返回响应数据 responseXML 以XML数据返回响应数据 status 返回请求的状态号 200:"OK";403:"Forbidden";404:"NotFound" statusText 返回状态文本(比如"OK"或"NotFound") */ //创建xhr对象 let xhr = new XMLHttpRequest(); // 准备发送,语法:xhr.open('请求方式get/post','url地址',boolean); 默认boolean:true:异步请求 xhr = open('get', '路径.php', 'true') //发送 send()get请求send() xhr.send(); // 监听函数,函数的功能:监听当前Ajax请求进行到哪一步,只有响应数据才能渲染数据 xhr.onreadystatechange = function () { if (xhr.
目录
一、问题的引入
二、问题的思考过程 三、问题的解决
四、总结
1、问题引入
在我学习springsecurity框架时,发现了这么一个报错,如下图所示:
报错信息很明显,大概意思就是UserLogin这种类型不支持反序列化,通过debug也很明显的知道是从Redis中将对象反序列出来时,出现了问题,因为无法执行到59行(这里浅说一下debug小技巧:这其实也是一种很好的排错手段,通过在一个区域内设置多个断点,逐次跳跃断点,当到某一个断点就已经出现报错了,就明白,错误区间一定是上一个好的断点到最后这个断点之间,另外如果是想快速跳跃到某段代码,可以采用打多个断点的方式,即使是相邻行的代码,也可以打上多个断点,因为你一行一行的执行时,可能还会深入源码,而这样的话就能真正的依次执行我们的代码了)。
二、问题的思考过程
既然这里很明确的告诉我是反序列化出现了问题,那么我就着重于序列化这里,既然我这又是从Redis中获取对象时出了问题,那么问题可能就出现在Redis的序列化配置上面,由于这个Redis序列化配置我也是第一次接触,还是看网课视频才了解到的,这些配置也是cv了老师的代码,所以也没怎么多想,后面是我实在没办法了,询问网上的大佬,才发现我的配置确实是有一点问题的,缺失了一点配置。
三、问题的解决 其实啊,仔细比对老师和网友的代码就可以发现,老师的代码其实是缺少ObjectMapper的配置的,而Object Mapper就是Jackson对象映射器(Object Mapper)可以把JSON解析为用户自定义类对象, 或者解析为JSON内置的树模型的对象,简单来说就是Jackson提供的一个类,用于转换json与Java对象的,所以在我的代码中,正是缺少了这一配置,因此无法进行反序列化,补上Object Mapper配置即可,附上之前的代码,以及加上Object Mapper配置的代码如下:
序列化器FastJsonJsonRedisSerializer的配置: 之前的:
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); private Class<T> clazz; static { ParserConfig.getGlobalInstance().setAutoTypeSupport(true); } public FastJsonRedisSerializer(Class<T> clazz) { super(); this.clazz = clazz; } @Override public byte[] serialize(T t) throws SerializationException { if (t == null) { return new byte[0]; } return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET); } @Override public T deserialize(byte[] bytes) throws SerializationException { if (bytes == null || bytes.
目录
1.类的继承概念 2.类的继承格式
3.作用
4.方法重写
5.自动转型(向上转型)
1.类的继承概念 类的继承就是子类继承父类的属性和方法,使得子类具有与父类相同的属性和方法。
举一个生活中的例子就是:汽车属于一个类,汽车品牌奥迪、奔驰就属于其子类,其具有汽车的一般特性,但二者在性能上也有一定的差别。所以子类会具有父类的一般特性,也会具有其自身的特性。
2.类的继承格式 在Java中通过extends关键字可以生命一个类是从另一个类继承而来的,形式如下:
class 父类{ } class 子类 extends 父类{ } 3.作用 为什么需要继承类呢?接下来我们举一个例子来说明:
比如说,有一个电脑类,其中有两种品牌联想和惠普,要求如下:
联想 属性:品牌名 方法:游戏
惠普 属性:品牌名 方法:游戏
代码示例如下:
联想类:
public class Legend { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } public void game() { System.out.println(name+"可以游戏"); } } 惠普类:
public class Hp { private String name; public void setName(String name) { this.
文章目录 1 重要参数1.1 七个构造参数1.2 重要成员变量 2 提交任务3 工作线程3.1 线程创建3.2 任务执行3.3 线程保活 4 总结ref 1 重要参数 1.1 七个构造参数 众所周知,Java 提供的线程池(ThreadPoolExecutor)构造函数中有几个重要的参数:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { corePoolSize:核心线程数,线程池至死都要维护的活跃线程数量,除非设置了 allowCoreThreadTimeOut 参数maximumPoolSize:最大线程数,线程池允许同时活跃的最大线程数量keepAliveTime:当线程数大于核心数时,多余空闲线程在终止前等待新任务的最长时间unit:上述等待时间的时间单位workQueue:任务队列threadFactory:线程工厂handler:拒绝策略 Java 自带了四种拒绝策略,分别是:
CallerRunsPolicy:让调用者直接在自己的线程里面执行,线程池不做处理AbortPolicy:线程池直接抛出异常(默认)DiscardPolicy:线程池直接把任务丢掉,当做什么也没发生DiscardOldestPolicy:把队列中最老的任务删除掉,把该任务放到队列中 1.2 重要成员变量 其实除了这几个构造参数以外,还有几个非常重要的参数需要我们理解。
ctl:线程池的控制状态,是一个 32 位 的 AtomicInteger 类型,高 3 位为线程池的状态,低 29 位为线程池的工作线程数 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); 线程池的状态有五种,分别是 RUNNING(-1)、SHUTDOWN(0)、STOP(1)、TIDYING(2)和 TERMINATED(3),其关系如下图所示:
workers:线程池中工作线程集合 private final HashSet<Worker> workers = new HashSet<>(); 通过 workers 参数可以发现线程池并未执行使用 Thread 去执行 Runable 任务,而是将二者封装成了一个 Worker 对象,方便对线程的复用以及状态控制:
一、构图 解释:在心中形成理念,突出画面的重心确立好画面的主体,用引导线有组织有安排引导观众的视线看向主体。
两个步骤:1、确定主体,2、有引导有组织的让观众的视线看向主体。
确认主体的方法:大小、形状、颜色、光影、虚实
确认主体
大小:放大主体,或者缩小主体
形状:
颜色:
光影:1、光的遮挡,2、光影对比
虚实:模糊掉除主体以外的其他物体
画面引导线:
三角形构图:正三角,斜三角,倒三角(倒三角有危机感)
平行线构图:辽阔的画面(纯平行线构图,容易显得单薄结合曲线构图使用)
垂直线构图:适用于城市、森林,特点庄严肃穆,容易表示高度和深度
对角线构图:展示画面动感和紧张感
曲线构图:特点是延伸性和指引性
圆形构图:特点是聚拢
均衡
摆放物体有聚拢和分散一说:
聚拢在主体中心进行聚拢,分散就是在非中心的地方进行二级点缀。
置换法则
个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~
个人主页:.29.的博客
学习社区:进去逛一逛~
SpringBoot-SSMP整合案例 一、实现方案二、案例实现1.快速搭建springboot工程2. 实体类快速开发(Lombok)3.数据层开发4.业务层开发①普通方式开发②快速方式开发 5. 表现层开发6.前端页面7. 源码免费下载 一、实现方案 案例实现方案分析:
实体类开发 —— 使用Lombok快速制作实体类
Dao开发 —— 整合MyBatisPlus,制作数据层测试类
Service开发 —— 整合MyBatisPlus进行增量开发,制作业务层测试类
Controller开发 —— 基于Restful开发,使用PostMan测试接口功能
Controller开发 —— 前后端开发协议制作
页面开发 —— 基于VUE+ElementUI制作,前后端联调,页面数据处理,页面消息处理
列表、新增、修改、删除、分页、查询 项目异常处理
按条件查询 —— 页面功能调整、Controller修正功能、Service修正功能
二、案例实现 1.快速搭建springboot工程 1.快速搭建:
2.勾选需要的起步依赖:
2. 实体类快速开发(Lombok) Lombok:一个Java类库,提供了一组注解,简化了POJO实体类开发 pom.xml导入lombok依赖: lombok版本由SpringBoot提供,故无需额外指定 <!--lombok依赖--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> 快速利用lombok开发实体类: @Data注解:自动创建实体类属性的Getter、Setter方法 import lombok.Data; /** * @author .29. * @create 2023-03-27 20:58 */ @Data public class Book { private int id; private String type; private String name; private String description; } 3.
事情是这样的,小明是一个工作五年的老程序员,半秃着的头已经彰显了他深不可测的技术实力。
这一天,小明收到了领导给过来的一个需求。
领导对小明说:“小明啊,你工作五年了,这个需求我交给你一个人负责很是放心,你可要保质保量按时落地呀”
小明当即立下军令状,拍着胸脯说到:“放心领导,交给我了”
小明承诺之后就开始认真看起了需求,过了五分钟以后,小明一拍脑袋,发现这需求还蛮简单,就是异步发个RocketMQ然后再由下游系统消费去修改Redis的一些信息,于是小明三下五除二,没花几天就把这事给干完了,于是开启了快乐的摸鱼,等待发布的那一天…
发布上线的这一天在小明的摸鱼下很快到来了…
因为部署的服务器很多,然后需要保证兼容性发布,不能直接停机,所以小明采取的是与往日一贯的兼容性发布方案,也就是分批发布。
准备好所有环境数据以后小明就开始发布了。
在重启第一批机器时,令人意想不到的事发生了,生产疯狂打印如下报错信息
吓的小明直接就给回滚了,为此这件事还惊动到了领导,让领导给铺天盖地一顿哐哐哐
接收完领导的批评以后,小明开始认真复盘为什么会出现这样的问题。
于是小明先画了一个简单的事故回顾分析图来帮助自己分析
正常运行时,应用如下图所示
小明看着这幅图仔细思索,突然小明敏锐的察觉到,难道是Redis与RocketMQ的关闭顺序导致的吗?带着这个问题点,小明开启了对应的源码解析之路
小明先是分析了Redis关闭核心源码(注意:案例使用的都是标准的SpringBoot集成Redis)
紧接着小明继续分析了RocketMQ关闭的核心源码(注意:案例使用的都是标准的SpringBoot集成RocketMQ)
然后小明结合上面两个中间件,继而分析了Spring在进行容器关闭时是如何关闭各类bean的
果然就是这个问题导致的,我们再来画一个图来梳理一下这个事故
分析完原因后,小明就开始思考解决方案了,经过几个夜晚的抓耳挠腮以及对Spring源码的阅读,小明终于找到了解决方案
小明是这样来设计的
步骤一、Spring容器启动快完成时会发送一个ContextRefreshedEvent事件,可以通过这个事件把RocketMQ自己注册的DefaultRocketMQListenerContainer类型的bean取出,存放在一个自己装配的config当中,目的是为了可以自己来控制RocketMQ shutDown的时机
(PS:这里是一定要通过这个事件来做的,不要想着通过@Bean去找或者通过实现ApplicationContextAware接口然后拿到ApplicationContext去getBean的方式获取,因为这个执行过程在RocketMQ自己注册DefaultRocketMQListenerContainer的步骤之前,所以你是拿不到的)
拿不到的原因给大家看一下两张源码图
步骤二、在应用进行关闭时一般是接收到了kill -9
或者调用了exit方法,这个时候Spring会在关闭时发出closeEvent事件,而这个事件是在destoryBean之前发出来的,这个时候我们就可以提前主动对所有的DefaultRocketMQListenerContainer进行shutDown了
步骤三、Redis的shutDown这个时候就可以放心的交给Spring自己的destoryBean方法来执行了
最后直接给大家看解决方案的代码
做完这一系列改造之后,于是乎小明再一次信心满满的开始了发布之旅,这一次就很顺利啦,线上没有再出现该类报错问题,顺利的完成了领导布置的任务,经过这件事后小明的实力又变强了几分
1. 在docker仓库中搜索mysql的镜像:
docker search mysql 下载镜像: docker pull mysql
2. 查看本地镜像:
docker images -a 参数-a 表示所有 3.运行mysql
docker run --name mysql \ --restart=always \ -p 3306:3306 \ -v /data/mysql/log:/var/log/mysql \ -v /data/mysql/data:/var/lib/mysql \ -v /data/mysql/conf:/etc/mysql/conf.d \ -e MYSQL_ROOT_PASSWORD=root \ -d mysql 命令说明:
-p 3306:3306:将容器的3306端口映射到主机的3306端口,主机端口:docker端口--name 容器名称1.-v /mydata/mysql/log:/var/log/mysql(日志文件挂载)
将容器中的日志文件夹/var/log/mysql挂载到主机对应的/mydata/mysql文件夹中
2.-v /mydata/mysql/data:/var/lib/mysql(数据文件挂载)
将容器中的数据文件夹/var/lib/mysql挂载到主机对应的/mydata/mysql/data文件夹中
3.-v /mydata/mysql/conf:/etc/mysql(配置文件挂载)
将容器的配置文件夹/etc/mysql挂载到主机对应的/mydata/mysql/conf文件夹中-e MYSQL_ROOT_PASSWORD=123456:初始化root用户的密码-d: 后台运行容器,并返回容器ID--restart=always 自动启动mysql:指定用这个镜像来创建运行实例 4. 查看运行中的容器:
docker ps (可加参数 -a 表示所有,如果不加这个参数只会展示运行状态的容器,
按容器即服务的思想,某种程度上可以把容器也当作服务,)
这样 mysql 就已安装并成功启动,处于运行状态了。
可以通过 docker port 容器name 查看对应端口
文章目录 前言一、串口数据的发送1.串口普通发送2.串口定时发送 二、串口数据的接收总结 前言 本篇文章将带大家实现串口的接收和发送功能。
一、串口数据的发送 1.串口普通发送 首先我们先从数据发送区域得到发送的字符串,QtSerialPort可以使用write函数进行数据的发送,QSerialPort的write函数接受的数据类型是QByteArray,这是因为它是Qt软件框架提供的一个二进制数据缓冲区类。在串口通信时,一般都需要发送二进制数据或者字节数组。因此,QSerialPort的write函数设计为接受QByteArray类型的数据。
首先需要得到发送区域的字符串
/*按下发送按键*/ void SerialPort::on_sendbtn_clicked() { /*得到发送数据区域的字符串*/ QString sendstring = ui->sendEdit->text(); /*将数据发送出去*/ SendData(sendstring); } 编写发送数据函数:
这里传入得到的字符串,将字符串转换为QByteArray类型的数据发送出去。
当选择了发送新行的时候SendString需要加上换行符:"\r\n"。
/*发送数据*/ void SerialPort::SendData(QString SendString) { QByteArray data; if(ui->SendNewck->isChecked()) { /*选择了发送新行*/ SendString += "\r\n"; data = QByteArray(SendString.toUtf8()); } if(ui->HexSendck->isChecked()) { /*选择了以Hex格式发送*/ data = QByteArray::fromHex(SendString.toUtf8().toHex()); } if(!ui->SendNewck->isChecked() && !ui->HexSendck->isChecked()) { /*没有选择发送新行和Hex格式*/ data = QByteArray(SendString.toUtf8()); } /*将数据发送出去*/ m_SerialPort.write(data, data.length()); /*显示当前发送的数据字节总数*/ ShowNowSendRecvSize(data, true); } 这里还需要编写一个显示当前发送的数据字节总数的函数:
这个函数是非常简单的,这里就不多讲解。
/*显示当前发送或者接收了多少字节数据*/ void SerialPort::ShowNowSendRecvSize(QString data, bool Status) { /*计算当前发送了多少字节的数据*/ int nowsize = QString(data).
文件搜素专栏全部文章
如何使用find命令搜索到自己想要的文件
ack 命令的基本用法详解
ag命令的使用详解
在 Linux 中查找文件名包含某个关键字的文件,可以使用 find 命令来实现。find 命令可以在指定目录下递归搜索文件,并根据指定的条件进行过滤。
下面是使用 find 命令查找文件名包含某个关键字的文件的命令格式:
find /path/to/directory -name "*keyword*" 其中,/path/to/directory 是要搜索的目录,*keyword* 表示要搜索的关键字,可以使用通配符 *。
例如,要在当前目录下查找文件名包含关键字 test 的文件,可以使用以下命令:
find . -name "*test*" 这个命令会递归搜索当前目录下所有文件名包含 test 关键字的文件。如果要搜索特定类型的文件,可以通过 -type 选项来指定,例如:
find . -type f -name "*test*" 这个命令会递归搜索当前目录下所有文件名包含 test 关键字的普通文件。如果要在搜索结果中排除某些目录或文件,可以通过 -prune 选项来指定,例如:
find . -type f -name "*test*" -not -path "./exclude/*" 这个命令会递归搜索当前目录下所有文件名包含 test 关键字的普通文件,但会排除名为 exclude 的子目录。
举一反三:如果我们把前后的星号去掉就变成精确搜索了!!
UV网格颜色图片上色 相关资料1 进行多窗口的模式
三色图
背景为透明通道的JPG图片。 使图片与 UV 进行关联 在下面的窗口中 选择 SHADER EDITOR,拖入事先准备好的 3色图 图片到如下图所示 的位置,
使其COLOR 与 PRINCIPLED BSDF的 BASE COLOR连接。使得 3色图.PNG 的设置卫CLOSEST。
物体模式为 编辑模式,移动鼠标 至 如下图所示的 绿色方框位置,滑动鼠标中键,
四个球体中的Viewport Shading,如下图所示左上角红色小方框。
然后点击向右数第3个按钮,向下的按钮,鼠标左键点击一下。
然后切换COLOR从 MATERIALS 为TEXTURE
在 UV EDITOR 窗口,鼠标左键选中全部的点,或者 按下 键盘 快捷键A,全选
按下 键盘 快捷键 S,拖动鼠标进行缩放,保证 UV EDITOR窗口 下 所有的点都在一个颜色下,方块的所有面的颜色都发生了改变,为红色。
UV EDITOR窗口下,保持全选 点,然后 按下键盘 快捷键 G,进行移动,如下图所示,方块变为绿色。
对点进行上色 UV EDITOR窗口下,选中部分的点,按下 键盘 快捷键G,移动选中的点,如下图所示。
对面进行上色 3D VIEW PORT窗口,EDITOR MODE 模式下 选择 面 模式。
1.修改密码
create user 'root'@'%' identified by '123456'; 或
ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; 2.授权
grant all on *.* to 'root'@'%'; alter user 'root'@'%' identified with mysql_native_password by '123456'; 3.刷新
flush privileges; 记录常用命令 1.登录
mysql -uroot -p 2.查看所有数据库
show databases; 3.退出
exit/quit 4.使用数据库
use 库名; 5.创建数据库:
create 库名; 6.查看表结构
desc 表名; 7.删除表
drop table 表名; 8.删除库
drop database 库名; 9.查询表结构
show create table 表名;
更新时间:2023-03-27 参考:
ciky奇
一万六++
当前版本:
python:3.7.0
opencv:3.4.1
所需库:
海康官网的sdk:CH-HCNetSDKV6.1.9.47_build20221111_win64
swigwin-4.0.2
boost_1_81_0
opencv-swig-master
1. 使用swig编译生成python和c++数据交换需要的.py和.cxx文件 opencv-swig-master\lib
当前路径cmd:
运行
swig -IE:\opencv\build\include -python -c++ HKIPcamera.i
(E:\opencv\build\include为opencv路径)
生成上图的2个文件。
2.生成动态链接库文件,dll 新建一个空项目,并配置以下依赖:include,lib
海康sdk
boost_1_81_0
opencv
python
链接器->输入->附加依赖项中添加:
HCNetSDK.lib
GdiPlus.lib
HCAlarm.lib
HCCore.lib
HCGeneralCfgMgr.lib
HCPreview.lib
PlayCtrl.lib
opencv_world341.lib
编译后生成:
HKIPcamera.dll
HKIPcamera.lib
新建一个文件夹:
把海康sdk的所有文件放置这里:
CH-HCNetSDKV6.1.9.47_build20221111_win64\库文件
然后放置生成的文件:
一共需要的是5个文件: HKIPcamera.py(第一步生成的py文件)
_HKIPcamera.pyd(第二步HKIPcamera.dll改名为这个)
opencv_world341.dll(opencv依赖dll)
最后放2个openssl库,不加会报错:29
libeay32.dll
ssleay32.dll
调用例子:
import HK.HKIPcamera import time import numpy as np import matplotlib.pyplot as plt import cv2 ip = str('192.
1.打开idea-Settings...
2.搜索 file encodings
设置Encoding为UTF-8 2.搜索 code style
设置换行符编码格式为Unix
SpringCloud微服务技术栈.黑马跟学 十一 今日目标1.什么是多级缓存2.JVM进程缓存2.1.导入案例2.1.1.安装MySQL2.1.1.1.准备目录2.1.1.2.运行命令2.1.1.3.修改配置 2.1.1.4.重启2.1.2.导入SQL2.1.3.导入Demo工程2.1.3.1.分页查询商品2.1.3.2.新增商品2.1.3.3.修改商品2.1.3.4.修改库存2.1.3.5.删除商品2.1.3.6.根据id查询商品2.1.3.7.根据id查询库存2.1.3.8.启动 2.1.4.导入商品查询页面2.1.4.1.运行nginx服务2.1.4.2.反向代理 2.2.初识Caffeine2.3.实现JVM进程缓存2.3.1.需求2.3.2.实现 3.Lua语法入门3.1.初识Lua3.1.HelloWorld3.2.变量和循环3.2.1.Lua的数据类型3.2.2.声明变量3.2.3.循环 3.3.条件控制、函数3.3.1.函数3.3.2.条件控制3.3.3.案例 4.实现多级缓存4.1.安装OpenResty4.1.1.安装1)安装开发库2)安装OpenResty仓库3)安装OpenResty4)安装opm工具5)目录结构6)配置nginx的环境变量 4.1.2.启动和运行4.1.3.备注 4.2.OpenResty快速入门4.2.1.反向代理流程4.2.2.OpenResty监听请求4.2.3.编写item.lua 4.3.请求参数处理4.3.1.获取参数的API4.3.2.获取参数并返回 4.4.查询Tomcat4.4.1.发送http请求的API4.4.2.封装http工具4.4.3.CJSON工具类4.4.4.实现Tomcat查询4.4.5.基于ID负载均衡1)原理2)实现3)测试 4.5.Redis缓存预热4.6.查询Redis缓存4.6.1.封装Redis工具4.6.2.实现Redis查询 4.7.Nginx本地缓存4.7.1.本地缓存API4.7.2.实现本地缓存查询 5.缓存同步5.1.数据同步策略5.2.安装Canal5.2.1.认识Canal5.2.2.安装Canal1.开启MySQL主从1.1.开启binlog1.2.设置用户权限 2.安装Canal2.1.创建网络2.2.安装Canal 5.3.监听Canal5.3.1.引入依赖:5.3.2.编写配置:5.3.3.修改Item实体类5.3.4.编写监听器 今日目标 1.什么是多级缓存 传统的缓存策略一般是请求到达Tomcat后,先查询Redis,如果未命中则查询数据库,如图:
存在下面的问题:
•请求要经过Tomcat处理,Tomcat的性能成为整个系统的瓶颈
•Redis缓存失效时,会对数据库产生冲击
多级缓存就是充分利用请求处理的每个环节,分别添加缓存,减轻Tomcat压力,提升服务性能:
浏览器访问静态资源时,优先读取浏览器本地缓存访问非静态资源(ajax查询数据)时,访问服务端请求到达Nginx后,优先读取Nginx本地缓存如果Nginx本地缓存未命中,则去直接查询Redis(不经过Tomcat)如果Redis查询未命中,则查询Tomcat请求进入Tomcat后,优先查询JVM进程缓存如果JVM进程缓存未命中,则查询数据库 在多级缓存架构中,Nginx内部需要编写本地缓存查询、Redis查询、Tomcat查询的业务逻辑,因此这样的nginx服务不再是一个反向代理服务器,而是一个编写业务的Web服务器了。
因此这样的业务Nginx服务也需要搭建集群来提高并发,再有专门的nginx服务来做反向代理,如图:
另外,我们的Tomcat服务将来也会部署为集群模式:
可见,多级缓存的关键有两个:
一个是在nginx中编写业务,实现nginx本地缓存、Redis、Tomcat的查询
另一个就是在Tomcat中实现JVM进程缓存
其中Nginx编程则会用到OpenResty框架结合Lua这样的语言。
这也是今天课程的难点和重点。
2.JVM进程缓存 为了演示多级缓存的案例,我们先准备一个商品查询的业务。
2.1.导入案例 参考课前资料的:《案例导入说明.md》
案例导入说明
为了演示多级缓存,我们先导入一个商品管理的案例,其中包含商品的CRUD功能。我们将来会给查询商品添加多级缓存。
2.1.1.安装MySQL 后期做数据同步需要用到MySQL的主从功能,所以需要大家在虚拟机中,利用Docker来运行一个MySQL容器。
2.1.1.1.准备目录 为了方便后期配置MySQL,我们先准备两个目录,用于挂载容器的数据和配置文件目录:
因为之前安装过,这里我改名为mysql_cluster
# 进入/tmp目录 cd /tmp # 创建文件夹 mkdir mysql_cluster # 进入mysql目录 cd mysql_cluster 2.1.1.2.运行命令 进入mysql_cluster目录后,执行下面的Docker命令:
docker run \ -p 3306:3306 \ --name mysql \ -v $PWD/conf:/etc/mysql_cluster/conf.
目录
前言
一、Git的下载与安装
1.下载
2.安装
二、生成及配置SSH密钥
1.生成SSH密钥
2.配置SSH密钥
三、本地仓库与远程仓库连接并推送到远程仓库
总结
前言 每次进一个新公司都要下载配置git,这些东西也就配置那一次,所以每次都是网上搜教程,跟着配置,中间会出现一些问题,所以就做个笔记,方便以后查看。
一、Git的下载与安装 1.下载 登陆git官网:git下载地址
window国内镜像下载:CNPM Binaries Mirror
点进去,根据需求下载(一般点击“Git for Windows Setup”下面“64-bit Git for Windows Setup”进行下载),下载即可。
2.安装 以下步骤可以直接点击下一步,使用默认选项即可快速安装,此步骤可跳过。
选择组件,一般只需点击Additional icons(添加图标到桌面)其他都是默认勾选的,然后点击“Next”进入下个页面
选择Git使用的默认编辑器,默认即可(GIt提供多种编辑器,这里不详细介绍了),点击“Next”进入下个页面
初始化新项目(仓库)名称,默认即可(也可以自定义),点击“Next”进入下个页面
配置PATH环境,一般默认即可,点击“Next”进入下个页面
选择HTTPS传输后端,一般默认即可,点击“Next”进入下个页面
配置行结束转换,一般默认即可,点击“Next”进入下个页面
选择Git Bash使用的终端模拟器,一般默认即可,点击“Next”进入下个页面
选择默认的”git pull”行为,一般默认即可,点击“Next”进入下个页面
选择一个凭证程序,一般默认即可,点击“Next”进入下一个页面
配置额外的选项,一般默认即可,点击“Next”进入下个页面
配置实验性选项,一般默认即可,点击“Install”开始安装
至此,git下载及安装步骤完成。
二、生成及配置SSH密钥 1.生成SSH密钥 在任意一空白地方,鼠标右击,选择“Git Bash Here”,打开Git命令窗口;
查看和配置本地账户
r
如果是第一次使用,需要配置账号,输入以下命令:
git config --global user.name "用户名"
git config --global user.email "用户自己的邮箱地址"
此时会在C:\Users\Administrator目录下生成.gitconfig配置文件(此文件不能删除);
查看.gitconfig配置文件里的内容:
继续在Git命令窗口中输入以下命令,即可生成公钥和私钥
ssh-keygen -t rsa -C "自己的邮箱地址"
centos下安装docker官方文档传送门
安装docker方法 您可以根据需要以不同的方式安装 Docker Engine:
您可以 设置 Docker 的存储库并从中安装,以简化安装和升级任务。这是推荐的方法。存储库类似于maven的中央仓库的概念。您可以下载 RPM 包并 手动安装并完全手动管理升级。这在诸如在无法访问 Internet 的气隙系统上安装 Docker 等情况下非常有用。在测试和开发环境中,您可以使用自动化的 便捷脚本来安装 Docker。 使用存储库安装 在新主机上首次安装 Docker Engine 之前,您需要设置 Docker 存储库。之后,您可以从存储库安装和更新 Docker。
设置存储库 # 安装yum-utils包(提供yum-config-manager 实用程序) sudo yum install -y yum-utils # 设置存储库 sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo # 可以设置淘宝的镜像源 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 安装 docker引擎 安装最新版本的docker # 此命令安装 Docker,但不会启动 Docker。它还会创建一个 docker组,但是默认情况下不会向该组添加任何用户。 sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 安装指定版本的docker 启动docker sudo systemctl start docker 验证是否安装成功 # 通过运行映像验证 Docker Engine 安装是否成功hello-world sudo docker run hello-world 此命令下载测试图像并在容器中运行它。当容器运行时,它会打印一条确认消息并退出。如果出现下图的打印信息则表示docker安装成功!
Webmin的安装和卸载 在centos里安装webmin
选择安装最新版本的安装包
官方下载路径可以查看下载版本http://download.webmin.com/download/yum/
wget http://download.webmin.com/download/yum/webmin-2.021-1.noarch.rpm
安装依赖 如果你的系统没有Perl,那么安装Webmin之前要满足该依赖项。你可能还要在安装Webmin之前安装Encode :: Detect Perl模块:
yum install perl-Encode-Detect sudo yum -y install openssl perl perl-Net-SSLeay perl-IO-Tty perl-Crypt-SSLeay perl-Encode-Detect autoconf 安装 rpm -ivh webmin-2.021-1.noarch.rpm 或 rpm -ivh webmin-2.021-1.noarch.rpm --force --nodeps 重置密码 /usr/libexec/webmin/changepass.pl /etc/webmin root sober webmin的用户名是root,密码为sober
webmin的配置目录是/etc/webmin
如果有安全需要,则更改webmin服务默认端口号 进入miniserv.conf 配置文件
nano /etc/webmin/miniserv.conf 修改默认端口号port=10000和listen=10000为如下即可(自己随便设置端口号)
port=6666 listen=6666 webmin服务命令 配置好密码或者端口号后重启下服务
# 重启 /etc/webmin/restart # 启动 /etc/webmin/start # 停止 /etc/webmin/stop 防火墙开放端口号 # 防火墙开放10000端口 firewall-cmd --zone=public --add-port=6666/tcp --permanent # 更新防火墙配置 firewall-cmd --reload # 查看已经开放的端口号 firewall-cmd --zone=public --list-ports webmin访问登录 访问http://自己的ip:6666,使用重置后的账号和密码即可登录
如何做到 ueditor批量上传word图片?
1、前端引用代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type"content="text/html; charset=utf-8"/>
<title>编辑器完整版实例-1.2.6.0</title>
<script type="text/javascript"src="ueditor.config.js"charset="utf-8"></script>
<script type="text/javascript"src="ueditor.all.js"charset="utf-8"></script>
<link type="text/css"rel="Stylesheet"href="WordPaster/css/WordPaster.css"/>
<link type="text/css"rel="Stylesheet"href="WordPaster/js/skygqbox.css"/>
<scrip ttype="text/javascript"src="WordPaster/js/json2.min.js"charset="utf-8"></script>
<scrip ttype="text/javascript"src="WordPaster/js/jquery-1.4.min.js"charset="utf-8"></script>
<scrip ttype="text/javascript"src="WordPaster/js/WordPaster.js"charset="utf-8"></script>
<scrip ttype="text/javascript"src="WordPaster/js/skygqbox.js"charset="utf-8"></script>
</head>
<body>
<textarea name="后台取值的key"id="myEditor">这里写你的初始化内容</textarea>
<script type="text/javascript">
var pasterMgr = new WordPasterManager();
pasterMgr.Config["PostUrl"] = "http://localhost:81/WordPaster2/WordPasterUEditor1x/php/upload.php"
pasterMgr.Load();//加载控件
UE.getEditor('myEditor',{onready:function(){//创建一个编辑器实例
pasterMgr.SetEditor(this);
}});
</script>
</body>
</html>
请求
文件上传的默认请求是一个文件,作为具有“upload”字段的表单数据。
响应:文件已成功上传
当文件成功上传时的JSON响应:
uploaded- 设置为1。
fileName - 上传文件的名称。
url - 上传文件的URL。
响应:文件无法上传
uploaded- 设置为0。
1 Variable 'exec_prefix' not defined in '/usr/local/lib/pkgconfig/opencv.pc' 经过网上详细查询资料后,是缺失了opencv.pc这个配置信息文件或者文件里面内容有问题,故解决方法就是添加这个文件然后将其导入到环境变量中
1.1 创建opencv.pc文件
sudo touch opencv.pc
因为你没有权限修改,首先修改文件的权限
更改文件的权限
进入该同目录下的终端:
sudo chmod 777 opencv.pc
把以下内容复制到opencv.pc中即可
prefix=/usr/local
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/lib
Name: opencv
Description: The opencv library
Version:4.1.1
#这个4.1.1是OpenCV版本需要改成你自己的版本
Cflags: -I${includedir}/opencv4
Libs: -L${libdir} -lopencv_shape -lopencv_stitching -lopencv_objdetect -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_ml -lopencv_imgproc -lopencv_flann -lopencv_core
~ 1.2 保存后退出,然后将文件导入到环境变量:(进入环境变量方式:gedit ~/.bashrc)
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
然后在source一下:
source ~/.bashrc
最后输入以下就可以看到OpenCV的版本了
pkg-config --modversion opencv
2 记录catkin_make时遇到的问题 at /opt/ros/noetic/share/catkin/cmake/catkinConfig.
@Import注解使用详解 @Import注解可以用来导入配置类,功能与 xml 中的 import 标签等效。
Import注解定义源码 /** * 可以导入的一个或多个 @Configuration 类 Indicates one or more {@link Configuration @Configuration} classes to import. * @Import的功能与 xml 中的 <import/>标签等效 * <p>Provides functionality equivalent to the {@code <import/>} element in Spring XML. 允许导入 @Configuration 类 、ImportSelector 和 ImportBeanDefinitionRegistrar 的实现 以及导入普通类(4.2版本开始支持;类似 AnnotationConfigApplicationContext#register(java.lang.Class<?>) * Allows for importing {@code @Configuration} classes, {@link ImportSelector} and * {@link ImportBeanDefinitionRegistrar} implementations, as well as regular component * classes (as of 4.
[UE C++] Timer定时器 1. 要点: UE的Timer包括了两个功能,延时和定时,通过bLoop来设置Timer在 FTimerManager 中进行管理,FTimerManager 存在于UGameInstance实例中,每个场景物品都可以获取设置Timer有两个SetTimer与SetTimerForNextTick两个接口Timer通过一个 FTimerHandle 对象进行管理,包括暂停,恢复,取消等操作 2. FTimerManager 管理所有的Timer,存在于UGameInstance实例中,每个场景物品都可以获取,获取方法如下:
GetGameInstance()->GetTimerManager(); GetWorld()->GetTimerManager(); GetWorldTimerManager(); 本质上都是通过UGameInstance::GetTimerManager()来获取
inline FTimerManager& GetTimerManager() const { return (OwningGameInstance ? OwningGameInstance->GetTimerManager() : *TimerManager); } FTimerManager& AActor::GetWorldTimerManager() const { return GetWorld()->GetTimerManager(); } 3. FTimerHandle Timer的句柄,用于暂停,恢复,取消Timer,对Timer进行管理
3.1 声明 FTimerHandle TestTimerHandle; 3.2 暂停和恢复 GetWorldTimerManager().PauseTimer(TestTimerHandle); GetWorldTimerManager().UnPauseTimer(TestTimerHandle); 3.3 Cancel GetWorldTimerManager().ClearTimer(TestTimerHandle); //取消指定对象的所有Timer GetWorldTimerManagerr().ClearAllTimersForObject(this); 3.4 获取Timer状态 //Get Rate TimerHandle无效返回-1 GetWorldTimerManager().GetTimerRate(TestTimerHandle); //是否暂停 GetWorldTimerManager().IsTimerPaused(TestTimerHandle); //是否活跃且未暂停 GetWorldTimerManager().IsTimerActive(TestTimerHandle); //是否存在且等待运行 GetWorldTimerManager().IsTimerPending(TestTimerHandle); //是否存在 GetWorldTimerManager().TimerExists(TestTimerHandle); //剩余时间 TimerHandle无效返回-1 GetWorldTimerManager().
早上刚到公司,打开DEM发现打开失败,查看DEM数据库服务器,无数据库进程
查看实例日志,报错信息如下:
2023-03-29 07:40:41.610 [INFO] database P0002226002 T0000000000002226015 ckpt2_log_adjust: full_status: 160, ptx_reserved: 0
2023-03-29 07:40:42.193 [INFO] database P0002226002 T0000000000002226015 ckpt2_log_adjust: ckpt_lsn(730729202), ckpt_fil(0), ckpt_off(90926592), cur_lsn(730738292), l_next_seq(82142489), g_next_seq(82142489), cur_free(94491136), total_space(4294959104), used_space(3561984), free_space(4291397120), n_ep(1)
2023-03-29 07:40:43.165 [INFO] database P0002226002 T0000000000002226015 checkpoint end, 160 pages flushed, used_space[3567104], free_space[4291392000].
2023-03-29 07:41:48.702 [INFO] database P0002226002 T0000000000002623321 socket_err_should_retry errno:11, adjust to 110
2023-03-29 07:41:48.691 [INFO] database P0002226002 T0000000000002623320 socket_err_should_retry errno:11, adjust to 110
2023-03-29 07:41:49.719 [INFO] database P0002226002 T0000000000002623325 socket_err_should_retry errno:11, adjust to 110
Linux命令行操作 目录信息
文章目录 Linux命令行操作1、目录及文件操作1.1、创建文件夹1.1.1、创建目录1.1.2、创建文件 1.2、删除文件夹/文件1.2.1、删除目录操作1.2.2、删除文件 1.3、重命名目录或者文件名称1.4、目录切换1.5、目录以及文件列表查看1.6、复制目录或者文件1.7剪切目录或文件1.8搜索目录或文件1.9、查看并且修改文件内容信息1.9.1、查看文件并且只是修改文件内容信息1.9.2、查看文件信息但是仅仅支持查看,并不只是修改操作 1.10、终止命令操作1.11、重定向功能 2、文件打包和压缩以及解压操作2.1文件打包和压缩命令:tar/unzip/zip 2.2 文件解压命令:tar [-zxvf] 压缩文件解压缩(unzip) 3、文件中查找命令grep4、ssh远程登录命令 参考链接 Linux常用操作命令大全 1、目录及文件操作 1.1、创建文件夹 1.1.1、创建目录 mkdir abc 在当前文件夹下创建一个名字为abc的文件夹 mkdir /abc/test 在指定目录下创建一个名字为 test的文件夹 mkdir -p test/a/b#在当前目录下递归创建test/a/b文件夹 # 如果此处不加 -p的话,那么就不能递归的进行创建操作,如果没有上一级文件夹的话,那么就会发生错误信息 1.1.2、创建文件 touch命令操作
1.在当前目录创建一个名为aa.txt的文件 touch aa.tx 1.2、删除文件夹/文件 1.2.1、删除目录操作 1.rm -r 目录1 递归删除当前目录下的指定目录1 2.rm -rf 目录2 递归删除当前目录下的指定目录2(不询问) 3.rm -rf * 将当前目录下的所有目录和文件全部删除 4.rm -rf /* 【自杀行为命令!谨慎使用!】将会把根目录下的所有目录及文件全部删除 # 删除当前目录下的所有.c 文件 find . -name "*.c" -maxdepth 1 | xargs rm 表示找到.(当前目录下)名字为以“.c”为后缀的文件,-maxdepth 1表示目录深度为1,也即寻找当前目录 用 xargs 是由于很多命令不支持 | 管道来传递参数,而日常工作中有有这个必要,所以就有了 xargs 命令 1.
遇到一个控件样式不对的问题。
原因是,下方代码原先是写在mainwindow.cpp中的构造函数的,如下:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); ui->textedit->setStyleSheet("border:0px; background-color:#FFFFFF"); } 当我自定义了一个LNTextEdit.cpp类后,并继承了QTextEdit。为了实现某种自定义效果
故我讲上方代码中的ui->textedit->setStyleSheet这句代码迁移到了LNTextEdit.cpp中,如下:
#include "lntextedit.h" LNTextEdit::LNTextEdit(QWidget *parent) : QTextEdit(parent) { this->setStyleSheet("border:0px; background-color:#FFFFFF"); } 当我重新运行代码时,发现样式没有生效,背景色和边框都恢复到了原始状态。
原因如下:
控件的set StyleSheet方法是会被覆盖的,当我们在mainwindow.cpp中写时,
由于ui->setupUi(this);这句代码中其实已经设置过一遍textedit的set StyleSheet,代码如下:
进入到 ui->setupUi(this);这个方法中,可以看到上图中的这段代码,这段代码是有qdesigner自动生成的,详细可见:QT新增自定义控件类并在QT Designer中将系统父类替换
所以在mainwindow.cpp中,设置setstylesheet,实际上是把上面这句代码覆盖掉了,因此能正常显示。先来后到,后写的会覆盖先写的。
然而写在自定义类LNTextEdit中构造函数的这句setstylesheet,是被上图这句setstylesheet给覆盖了,因为是写在了构造函数中,先执行了构造函数,再执行下面的这句setstylesheet。
所以样式失效了。
我又检查了一下我的ui文件,发现我并没有在textedit的stylesheet中写任何东西
然后仔细看了下,应该是多敲了一个空格,如下图:
最右方的返回红色按钮其实是可以点击的 ,也就是说确实该动过ui文件中textedit的stylesheet属性,导致在自动生成 ui->setupUi(this);这句代码时,加入了一句setsheetstyle
其实在ui文件中,也就是xml形式中,也可以看到这句话:
解决方案:点击下ui视图中,textedit的stylesheet属性,点击撤回按钮。
这样就能保证不在setupui方法中,自动设置stylesheet了,也保证了在自定义类中的setstylesheet不被覆盖了
引言 我下载的是2023年最新版本的pycharm,不知道怎么安装pycharm的看我这篇文章。新版的 pycharm 安装好了之后就会出现一个问题,就是在配置 conda 虚拟环境找不到 conda 的可执行文件,出现了以下问题。
遇到这个问题有两种解决办法。
解决办法 1、第一种 按照以下步骤,找到condabin文件下面,conda.bat 文件,把路径给复制下来,粘贴到 Conda 可执行文件,即可。
然后再点击加载环境,我这里是已经汉化了 pycharm ,如何汉化,可见其他文章。
这样所创建的虚拟环境就可以用起来了。
第二种解决办法 只需要在 ‘Conda 可执行文件’ 的输入框里面,找到 anaconda 路径下的“ _conda.exe ” ,在点击‘ 加载环境 ’,即可出现 ‘ 使用现有环境 ’ 的输入框,如图所示。
最后在输入框内,输入conda虚拟环境的‘python.exe’即可成功添加conda的虚拟环境最后在输入框内,输入conda虚拟环境的‘python.exe’即可成功添加conda的虚拟环境。
以上就是解决最新版 pycharm 找不到 conda 可执行文件的解决办法。欢迎大家评论区交流
在游戏或者仿真虚拟环境中需要模拟现实中的物理碰撞,由于模型边缘复杂,在精确度不高的游戏中经常把它处理为正方体盒子,然后再检测物理碰撞,常用的算法为AABB碰撞盒算法
先遍历模型所有顶点遍历所有顶点,然后再不同方向上分别找出最大最小值来构成AABB盒子的最大最小顶点,模型就被处理成如下图的粗模型:
下面给出一个简化的原理图
如果物品没有发生碰撞的时候X轴上的顺序为X1,X2,X3,X4,但是X3和X2发生了交换,说明在X轴方向上面,物体的投影重合
同理在Y1,Y2,Y3,Y4上,Y2和Y3发生了交换,说明在Y轴方向上面,物体的投影重合
只有当物体在X轴和Y轴上发生投影重合的时候,说明两个图形有相交的部分
同理,在三维空间下,三个轴都发生投影重合的时候,说明两个盒子发生了穿透
1. 函数封装 function Split(input, delimiter) input = tostring(input) delimiter = tostring(delimiter) if (delimiter == "") then return false end local pos, arr = 0, {} for st, sp in function() return string.find(input, delimiter, pos, true) end do table.insert(arr, string.sub(input, pos, st - 1)) pos = sp + 1 end table.insert(arr, string.sub(input, pos)) return arr end 2. 调用及输出 local TimerStr = '00:11' Split(TimerStr , ":") for i, v in pairs(TimerStr ) do print(v) end -- 输出结果 -- 00 -- 11
20230329更新 官方的源代码中,训练的时候将rect开启,即可进行长方形训练同时也会进一步降低训练时的显存。
Imagesz只需要设置图像最大尺寸即可,在dataload中,读取图像时候会进行判断处理,
在load_image过程中,会将图像等比例缩放
比如原图为1280*640。
输入的imagesize为1280的话,则读取的图像为1280*640,
输入的imagesize为640的话,则读取的图像为640*320
但是需要注意开始Rect后 不会再对图像进行mosaic的增强,如果实在需要的话可以参考原来的长方形训练(下面的文章进行更改)
长方形图像训练: Step1: 修改训练图片的尺寸,因为默认尺寸是是对训练集和验证集的。所以此处进行修改长方形时,需要分别赋值构建一个数组。 Step2:Train.py中修改对图像尺寸检查的功能。 Step3: Train.py中修改模型属性功能。原来640 是int类型,现在【640,320】是一个数组。所以需要进行修改。 Step4: 对LoadImageAndLabels中的代码进行修改 修改mosic功能 修改Load_image功能 修改load_mosaic功能 修改mosaic拼接功能以及label拼接的功能。 注意看if isinstance 做判断的位置,都会进行修改。 def load_mosaic(self, index): # YOLOv5 4-mosaic loader. Loads 1 image + 3 random images into a 4-image mosaic labels4, segments4 = [], [] if isinstance(self.img_size, int): s = self.img_size yc, xc = (int(random.uniform(-x, 2 * s + x)) for x in self.mosaic_border) # mosaic center x, y else: s_h, s_w = self.
快速导读 1、安装 Arduino IDE —— 1.8.132、安装 ESP8266 —— 2.7.43、配置Arduino IDE 首选项4、硬件开发板 —— ESP8266 NodeMcu 和 ESP32 NodeMcu5、ESP8266 NodeMcu 开发板5.1 引脚定义5.2 跟启动相关的引脚5.3 ADC输入5.4 板载LED灯5.5 复位按键5.6 GPIO0 —— 烧录 or 工作5.7 GPIO16 —— 睡眠唤醒5.8 IIC总线5.9 SPI总线5.10 PWM引脚5.11 中断引脚 6. ESP32 NodeMcu开发板6.1 引脚定义6.2 只能作为输入引脚6.3 SPI Flash占用引脚,不需要使用6.4 电容式触摸GPIO6.5 ADC6.6 DAC6.7 RTC6.8 PWM6.9 I2C 手把手代码注释,完整案例讲解开发过程以及细节,一键式运行代码。
ESP保姆级付费专栏群 707958244,不喜勿加,凭借付费专栏订单号加入
ESP 保姆级教程 系列导读(订阅前请务必阅读) 参考:
ESP8266开发之旅 基础篇② 如何安装ESP8266的Arduino开发环境 1、安装 Arduino IDE —— 1.8.13 2、安装 ESP8266 —— 2.7.4 双击安装完毕后,可以查看环境是否配置成功。
Java实现公众号功能开发 文章目录 Java实现公众号功能开发描述引入依赖注册公众号配置公众号各事件处理实现公众号事件处理类实现公众号日志记录处理器实现公众号用户关注处理器实现公众号用户取消关注处理器实现公众号用户发送消息处理器用户消息事件分类处理Builder定义处理抽象类实现处理抽象类--子类--文本消息实现处理抽象类--子类--图片消息 公众号模板消息推送 描述 使用Java实现公众号功能的接入,配合业务实现: 用户关注、取消关注、推送数据服务、用户在公众号信息转发人工服务等功能 本文章说明公众号代码配置实现,公众号申请,注册方式,自行查看官网说明 引入依赖 <!--微信公众号(包括订阅号和服务号)--> <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-mp</artifactId> <version>4.4.2.B</version> </dependency> 注册公众号配置 @Slf4j @Configuration @RequiredArgsConstructor @ConditionalOnClass(WxMpService.class) @EnableConfigurationProperties() public class WxMpConfiguration { private final MpConfigMapper mpConfigMapper; private final LogHandler logHandler; private final SubscribeHandler subscribeHandler; private final UnsubscribeHandler unsubscribeHandler; private final TextMsgHandler textMsgHandler; /** * 用户配置(获取用户客户代码) */ private static Map<String, Integer> MP_USER_CONF = new HashMap<>(); public static Long getCustomId(String appid) { return Long.valueOf(MP_USER_CONF.getOrDefault(appid, 0)); } /** * 加载公众号配置,注册Bean对象 */ @Bean public WxMpService wxMpService() { //这个是数据库公众号信息配置表 List<MpConfig> mpConfigs = mpConfigMapper.
### es6 数据类型 ##### map 数据类型 ===>Map 对象保存键值对。 >用途 : > * Object的key无法支持该数据时 > * 需要了解对象大小时 - map 数据类型任何值(对象或者原始值) 都可以作为一个键。 Object 的键只能是字符串 ```javascript let myMap = new Map(); let myMap1 = new Map(); var keyString = 'a string'; var keyObj = { a: 1 }; myMap.set(keyString, "和键'a string'关联的值"); myMap1.set(keyObj, '和键 keyObj 关联的值'); console.log(myMap1.get(keyObj)); //和键 keyObj 关联的值 console.log(myMap); //Map {'a string' => "和键'a string'关联的值"} console.log(myMap1); //Map {'a string' => "和键'a string'关联的值"
本文主要解决古典密码中的Hill体制密码在已知明文M和密文C的情况下求解密钥矩阵K的两种方法:①求逆矩阵②待定系数法。
如若不懂Hill体制的古典密码可以参照我上一篇文章密码学——几种典型的古典密码体制(Caesar体制、Playfair体制、Vigenere体制、Beaufort体制以及Hill体制)
文章目录 引入题目一、求解逆矩阵二、求解方法1.逆矩阵求解法2.待定系数求解法 结束语 引入题目 设英文字母A,B,C,…,Z分别对应编码为0,1,2,…,25。已知Hill密码中的明文长度为2,密钥K为 Z 26 Z_{26} Z26上的一个二阶可逆方阵,现给出明文FRID,所对应的密文为PQCF,试求解密钥矩阵K
一、求解逆矩阵 此处只是简单的描述线性代数中求解逆矩阵的步骤
设矩阵 M = ( 5 17 8 3 ) M=\begin {pmatrix}5 & 17 \\ 8 &3 \end{pmatrix} \\ M=(58173)
解:① ∣ M ∣ = 5 × 3 − 8 × 17 = − 121 = 9 ( m o d 26 ) \vert M \vert =5\times3-8\times17=-121=9\ (mod\ 26) ∣M∣=5×3−8×17=−121=9 (mod 26)注意,在模运算中-121模26等同于9模26 ∣ M ∣ − 1 = 3 ( m o d 26 ) ∵ 3 × 9 = 27 ≡ 1 ( m o d 26 ) \vert M \vert^{-1} =3\ (mod\ 26) \because 3\times 9=27\equiv1\ (mod\ 26) ∣M∣−1=3 (mod 26)∵3×9=27≡1 (mod 26)注意,在模运算中逆元的求解为相乘模26余1
目录: 一、项目描述
二、项目环境
三、项目步骤
四、项目实现
4.1、创建一个需求文档存放需求文件,文件内包含本次项目的所有需求
4.2、新建一个配置文件config.py,用来存放配置条目,如农产品的种类、所查询的年份、进口国、出口国、以及URL的请求、需要连接的mysql数据库等
4.3、导入country.py文件,里面存放了所有的国家和国家对应的id,如需请自行复制。
4.4、创建recv_data.py文件,用来请求联合国贸易的接口,获取所设定年份的所有国家跟中国的玉米贸易数据,并将请求好的数据文件保存在本地的data目录下
4.5、打开CentOS虚拟机创建mysql库,并配置对应的环境
4.6、创建一个insert_mysql.py的文件,用于连接数据库,并将所有数据都保存到mysql数据库内、等待后续数据的处理分析。
4.7创建一个analysis.py文件,用来分析数据、提取出与中国玉米交易进出口量前三的国家,并绘制柱状图
4.8、创建一个sendmail.py的文件,用来将最后的柱状图发送给老师的邮箱
五、项目心得
一、项目描述 该项目旨在通过对联合国农业组织(FAO)提供的全球农产品数据进行分析,为农业决策制定者提供有用的信息和见解。该项目是从联合国的农业贸易数据里,爬取到各个国家农产品的交易记录,并且对这个数据进行分析,方便他人可以通过图表对我国农产品的进出口有个很清晰的了解。
二、项目环境 运用python3.10(requests、os、pandas、pymysql、matplotlib等库)、sql语言、mysql5.7.35、CentOS Linux release 7.9.2009 (Core)
三、项目步骤 1、进行需求分析,并将需求写入需求文档
#爬取联合国玉米的交易数据 #需求年份 2020 - 2022 年 这个年份最好不要写死、 以后方便更改、 最好用配置文件取管理 #保存成csv文件 放到data目录 这个data目录路径你要自己设计好 #入库到数据库 #url = "https://comtrade.un.org/api/get/plus?max=10000&type=C&freq=A&px=HS&ps=2020&r=156&p=all&rg=all&cc=1006&fmt=csv" #下一步 #1、 使用pandas 将爬取的数据进行入库 #2、 使用matplotlib 作图 画出与中国玉米交易进出口量前三的国家 以及他们的进出口量分别是多少 # 形成柱状图 #3、将柱状图以邮件的形式发给老师 2、查看联合国的贸易网站(UN Comtrade),并查看网站接口api的文档
3、编写爬取网页数据的代码(python语言),使用requests库发起请求,并将爬取的数据通过csv文件的形式保存在本地,以便于后续数据的总结与分析。
4、将csv文件使用pandas库进行合并送入mysql库中
5、对入库的数据进行分析,选择出最近几年内该农产品贸易数量最多的数据,并绘制图表(matplotlib),然后将图表结果通过邮件发送给老师。
四、项目实现 4.1、创建一个需求文档存放需求文件,文件内包含本次项目的所有需求 4.2、新建一个配置文件config.py,用来存放配置条目,如农产品的种类、所查询的年份、进口国、出口国、以及URL的请求、需要连接的mysql数据库等 """ @data:2023/3/8 @file:config @author:Claylpf config作为我们的配置模块 可以用来配置年份、产品等信息 保存项目的配置 """ #如果需要获取别的年份、 直接修改如下的配置 Start_Year = 2020 #开始年份 End_Year = 2022 #结束年份 #要获取的产品 #其他农产品的id可以去网址查询,此项目以玉米来举例说明 Products = "
目录
① 为什么使用
② 如何安装
1.安装lombok插件:
2.添加lombok的maven的pom.xml依赖: 3.实体类示例代码Student.java
4.测试类LombokTest.java
5. 输出结果: ③ 常用且特殊注解
① 为什么使用 项目中经常使用bean,entity等类,绝大部分数据类类中都需要get、set、toString、equals和hashCode方法,虽然eclipse和idea开发环境下都有自动生成的快捷方式,但自动生成这些代码后,如果bean中的属性一旦有修改、删除或增加时,需要重新生成或删除get/set等方法,给代码维护增加负担。而使用了lombok则不一样,使用了lombok的注解(@Setter,@Getter,@ToString,@@RequiredArgsConstructor,@EqualsAndHashCode或@Data)之后,就不需要编写或生成get/set等方法,很大程度上减少了代码量,而且减少了代码维护的负担。故强烈建议项目中使用lombok,去掉bean中get、set、toString、equals和hashCode等方法的代码。
② 如何安装 当前你使用的ide未安装lombok. lombok能够达到的效果就是在源码中不需要写一些通用的方法,但是在编译生成的字节码文件中会帮我们生成这些方法,减少代码冗余.
1.安装lombok插件: 具体流程如图:
点击下载就好啦,此处已经下载,创建项目测试
2.添加lombok的maven的pom.xml依赖: <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> </dependency> 3.实体类示例代码Student.java package com.lombok.demo; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; @Setter @Getter @ToString @EqualsAndHashCode public class Student { private String name; private int age; private String male; private String studentNo; } 4.测试类LombokTest.java package com.lombok.demo; import lombok.extern.java.Log; @Log public class LombokTest { public static void main(String[] args) { Student student = new Student(); student.
Python使用SMTP协议向指定邮箱发送邮件 前言一、前期准备(一定要做!)1.QQ邮箱**授权码**2.email库的安装 二、代码部分三、实际效果 前言 操作系统:Windows10专业版
Python版本:Python 3.8
开发软件:Pycharm Community 2022.3
第三方库:email
发送电子邮件是个很常见的开发需求。
比如你写的天气预报程序、日程待办程序、商品降价提醒等等,你都可以采用这种方式来写一个邮件发送函数来为自己服务。
Python发送邮件并不复杂,各个国家各个公司都有自己不同的安全策略,我们只演示腾讯的QQ邮箱。
一、前期准备(一定要做!) 我们想要用QQ邮箱发送邮件,不可能只填写一个邮箱账号就可以的,而使用用户登录密码的方式不太安全,所以我们需要一个授权码。
1.QQ邮箱授权码 在这个网站 登录QQ邮箱 登录自己的QQ账号,不推荐重新注册新的,QQ邮箱重新注册的邮箱的话是两周内是不能获取授权码的。
登录进去后点击此处设置
在设置界面点击这个 “账户”
往下翻,直到看见下图的东西
我们要将第一个服务开启,也就是POP3/SMTP服务,这时候需要我们用注册的手机号给指定号码发短信,资费是0.1元/条。
然后点击生成授权码,这个也是与上图一样是需要发短信的。
上一个是启用pop3协议,这一个是获取授权码。
发送好后点击我已发送,然后就会弹出你的授权码
复制这一串字符,这个就是你的所登录的账号QQ邮箱的授权码了,记得要复制好后再关闭这个界面,否则的话又要重新发短信(身家 - 0.1元)。
2.email库的安装 这里我推荐使用Pycharm来安装:设置–>项目–>项目–>Python解释器–>小加号–>输入email然后安装就好了
等它安装好以后那么就可以继续下一步了。
二、代码部分 # code:utf-8 # Create by __H2__ # 2023/3/28 import smtplib from email.mime.text import MIMEText # 下面两行是发件人信息,这里要填你自己的账号信息 msg_from = '**********' # 这里填写你自己的邮箱 key = '*********' #这里填写我让你注册的邮箱授权码, # 下面三个变量分别是收件人、邮件标题、邮件内容 msg_to = "1322386539@qq.com" # 填收件人邮箱(如你的室友,这个是我自己的) title = "
文章目录 算法刷题(一)二分机器人跳跃问题带分数 递归递归求斐波那契数列递归实现组合型枚举递归实现排列型枚举翻硬币 算法刷题(一) 以下题部分来自于AcWing,蓝桥杯等地。
二分 机器人跳跃问题 输入样例1:
5 3 4 3 2 4 输出样例1:
4 输入样例2:
3 4 4 4 输出样例2:
4 输入样例3:
3 1 6 4 输出样例3:
3 #include <bits/stdc++.h> using namespace std; int n; const int N=100010; int a[N]; bool check(int e) { for(int i=0;i<n;i++) { e=e*2-a[i]; if(e>=1e5) return true; if(e<0) return false; } return true; } int main() { cin>>n; for(int i=0;i<n;i++) { cin>>a[i]; } int l=0,r=1e5; while(l<r) { int mid=l+(r-l)/2; if(check(mid)) r=mid; else l=mid+1; } cout<<r<<endl; return 0; } 带分数 资源限制
订阅 Python全栈白宝书-零基础入门篇 可报销!白嫖入口-请点击我。推荐他人订阅,可获取扣除平台费用后的35%收益,文末名片加V!说明:该文属于 Python全栈白宝书专栏,免费阶段订阅数量4300+,购买任意白宝书体系化专栏可加入TFS-CLUB 私域社区。福利:加入社区的小伙伴们,除了可以获取博主所有付费专栏的阅读权限之外,还有机会加入 星荐官共赢计划 ,详情请戳我 。 作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 跨域学习者,从事过全栈研发、产品经理等工作,目前任某金融品类App负责人。荣誉:2022年度博客之星Top4、博客专家认证、全栈领域优质创作者、新星计划导师,“星荐官共赢计划” 发起人。现象级专栏《白宝书系列》作者,文章知识点浅显易懂且不失深度;TFS-CLUB社区创立者,旨在以“赋能 共赢”推动共建技术人成长共同体。 🏆 白宝书系列 🏅 Python全栈白宝书🏅 产品思维训练白宝书🏅 全域运营实战白宝书🏅 大前端全栈架构白宝书 专栏系列(点击解锁)学习路线(点击解锁) Python全栈白宝书 零基础入门篇 语法进阶篇 自动化办公篇 自动化测试实战篇 数据库开发实战篇 爬虫入门与实战 数据分析篇 前端入门+flask 全栈篇 django+vue全栈篇 拓展-人工智能入门 文章目录 详解 sys.argv 详解 sys.argv 关于 sys.argv 可得好好说道说道了。当初我可是被折磨的不要不要的,上一章节我们提到 argv 是获取程序外部的参数,返回值是一个列表。
说实话我一直在 python 解释器、idea 运行,试图从结果发现它的用途,然而结果一直都是没结果,也在网上查了许多资料,大部分都是转裁和复制的。给的都是简明python教程上那个一长串代码的例子,说看了就明白了,可我看得晕头转向的还是没真正明白,只知道 sys.argv[0] 表示当前脚本本身文件路径的该脚本文件。后来经过大量努力,多方求教才真正明悟了,谨以记录和分享,希望能从另一个角度给同在求索过程中的同学一点启发。
sys.argv 其实就是一个从程序外部获取参数 的桥梁,这里所说的 外部 很关键,所以那些试图从代码来说明它作用的解释一直没看明白。因为我们需要先在终端执行脚本, 并从外部传入参数(可以是多个),所以获得的是一个列表(list),也就是说sys.argv其实可以看作是一个列表,所以才能用[ ]提取其中的元素。其第一个元素是程序本身,随后才依次是外部传入的参数。
我们先来看一下 sys.argv 返回的是什么?
import sys print(sys.argv) # >>> 执行结果如下: # >>> ['/Users/username/PycharmProjects/XXXXX/XXXXX/animal/package_sys.py'] # >>> 从执行结果可以看出 其输出的就是当前路径下的当前脚本本身,也就可以理解为 'sys.
最终程序图 程序分析——精灵对象与功能分析 基本精灵对象,继承 pygame.sprite.Sprite
属性:加载图片、设置初始速度
功能:纵向更新速度
程序对象代码 import random import pygame SCREEN_PRO = pygame.Rect(0, 0, 512, 768) # 自定义派生精灵子类,继承pygame.sprite.Sprite class GameSprites(pygame.sprite.Sprite): """游戏精灵基类""" def __init__(self, img_name, speed=1): # 调用父类的初始化方法 super().__init__() if img_name is None: return # 加载图像 self.image = pygame.image.load(img_name) # 设置尺寸; get_rect()可以获取图像的原始大小 self.rect = self.image.get_rect() # 设置速度 self.speed = speed def update(self): # 默认在屏幕上垂直方向移动 self.rect.y += self.speed 背景图对象(继承精灵基类)
属性:背景图片、背景音乐
位置:从屏幕0,0 开始绘制(屏幕大小与背景图一样大小)
功能:更新图片纵向移动,当移出屏幕后重置到屏幕上方(需要两张背景图,不断交替纵向下移动,表现出飞机不停飞的现象)
程序对象代码 class BackGround(GameSprites): """背景精灵""" # 初始化背景图片 def __init__(self, is_alternate=False): super().
import pandas as pd import numpy as np from sklearn.metrics import silhouette_score from sklearn.decomposition import PCA from sklearn.cluster import KMeans,AgglomerativeClustering from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt import datetime plt.rcParams['font.sans-serif']=['SimHei'] #中文正常显示 plt.rcParams['axes.unicode_minus']=False #让负号正常显示 # 数据集路径: # 格式:url/dataSet/systemLib/c3b5c0f37fe24797808613bc713d5585.rar,url参见实验窗口右侧菜单“实验资源下载”。例如:https://staticfile.eec-cn.com/dataSet/systemLib/c3b5c0f37fe24797808613bc713d5585.rar。压缩包中的数据为csv数据,解压并将该数据移动到C:/ 数据分析/data目录中。 # 读取和查看数据 air_data=pd.read_csv('air_data.csv',encoding='ANSI') print(air_data.head()) print(air_data.info()) exp1 = air_data['SUM_YR_1'].notnull() # 第一年票价不为空记录的索引 exp2 = air_data['SUM_YR_2'].notnull() # 第二年票价不为空记录的索引 air_data = air_data.loc[exp1 & exp2, :] # 票价不为空的记录 print(air_data.shape) # 可以看到,数据减少近700个样本 # 去除掉第一年、第二年票价均为0,同时平均折扣系数大于零和飞行里程大于零的数据 index1 = air_data['SUM_YR_1'] == 0 # 第一年票价为零 index2 = air_data['SUM_YR_2'] == 0 # 第二年票价为零 index3 = air_data['avg_discount'] > 0 # 平均折扣系数大于零 index4 = air_data['SEG_KM_SUM'] > 0 # 飞行里程大于零 airline = air_data.
随着现在拍摄设备像素的提升,现在拍照得到的照片越来越清晰,但是同时也让照片的大小kb变得越来越大,这让我们在使用的时候经常会碰到由于大小限制照片无法上传的情况,很多小伙伴在碰到这种情况的时候都不知道该怎么办了。今天就让小编来为大家介绍一下照片是什么格式的,这种格式有什么优缺点以及如何将照片压缩变小,下面一起来看一下吧。
照片格式有哪些优缺点?
对于我们使用普通手机、相机拍摄得到的照片,一般都是JPG格式的,JPG格式是目前最流行的格式之一,几乎所有的拍摄设备以及图片读取设备都能支持JPG格式的文件,是一种有损压缩的标准方法,有着占用空间小、上传下载速度快等优点,一般情况下能够满足绝大部分的需求;缺点是不如其他图片格式精细,如果是对图片做非常精细的后期处理的话,JPG格式就无法满足需要了。
怎么压缩照片大小?
1.打开压缩啦网站,点击选择图片压缩进行上传图片。
2.图片上传后,系统会默认按照70压缩等级来对图片压缩,可以调整压缩等级进行二次压缩,压缩等级越低则压缩后图片越小。图片压缩到合适的大小之后,点击保存图片。
以上就是照片怎么改大小kb的方法了,是不是非常简单呢,除了能够压缩jpg、png、gif等格式的图片以外,压缩啦网站还支持图片裁剪、图片尺寸修改、图片转ico、图片去底色等功能,需要的小伙伴们快来试一下吧!
目录 1.GET请求1.1 形式1:1.2 形式2: 2.POST请求2.1 无入参:2.2 form传参(文件):2.3 json入参:2.4 json文件入参: 3.请求计时3.1 time命令(Linux):3.2 -w 显示响应时长 4.-s 不显示 %Total% 等统计信息。5 -v 显示详细请求信息 1.GET请求 1.1 形式1: curl http://localhost:8080?param1=XXX\¶m2=XXX 1.2 形式2: curl 'http://localhost:8080?param1=XXX¶m2=XXX' 注意:如果有多个请求参数,在不使用引号的情况下,连接参数之间的 & 前面要加反斜杠\转义一下,如:\&
2.POST请求 2.1 无入参: curl -X POST http://localhost:8080 2.2 form传参(文件): file:传文件示例;
dirName:传字符串示例。
(form传参可以直接将参数拼接到地址后面)
curl -X POST -F 'file=@/tmp/test.txt' -F 'dirName="/tmp"' http://localhost:8080/upload 2.3 json入参: curl -H 'Content-Type:application/json' -X POST -d '{"param1":123,"param2":"hello"}' http://localhost:8080 2.4 json文件入参: curl -H 'Content-Type:application/json' -X POST -d @test.
安装包下载 MySQL 5.7 Linux安装包下载:https://dev.mysql.com/downloads/mysql/5.7.html
选择 5.7.41
选择安装包
卸载Mariadb rpm -qa | grep mariadb rpm -e --nodeps ⽂件名 新建⽤户、组 # 添加mysql⽤户组 groupadd mysql # 添加mysql⽤户 useradd -g mysql mysql -d /home/mysql # 修改mysql⽤户的登陆密码 passwd mysql 创建数据库相关⽬录 /home/mysql/3306/data /home/mysql/3306/log /home/mysql/3306/tmp 解压下载mysql.tar tar -xvf mysql-5.7.22-el7-x86_64.tar tar -zxvf mysql-5.7.22-el7-x86_64.tar.gz # 修改mysql⽂件夹下所有⽂件的⽤户和⽤户组 chown -R mysql:mysql mysql/ 配置⽂件 # 创建配置⽂件 cd /etc # 在my.cnf⽂件中添加对应的配置项,末尾会提供⼀个默认的my.cnf配置 vi my.cnf 安装数据库 # 初始化数据库,并指定启动mysql的⽤户 ./mysqld --initialize --user=mysql 安装完成后,在my.cnf中配置的datadir⽬录下⽣成⼀个error.log⽂件,⾥⾯记录了root⽤户的
随机密码。 设置开机启动 # 复制启动脚本到资源⽬录 cp .
文章目录 一. 预备知识1. IP地址2. 端口号(port)3. socket网络通信4. 认识TCP/UDP协议5. 网络字节序 二. socket编程1. 套接字说明2. socket函数简介3. socket编程说明4. socket地址说明及转换函数4.1 三种常见的结构类型4.2 整型数据字节序转化函数4.3 IP地址转换函数 5. socket主要函数说明5.1 基本套接字函数5.2 UDP读写函数 三. UDP套接字编程1. 普通UDP服务器编程模型1.1 UDP服务器端流程1.2 UDP客户端流程1.3 UDP服务器、客户端的编程模型图 2. 普通UDP服务器编程实现2.1 UDP服务器服务端代码2.2 UDP客户端客户端代码2.3 测试普通UDP服务器 四. TCP套接字编程1. TCP套接字编程模型图2. TCP编程流程说明2.1 服务器编程流程2.2 客户端编程流程 3. TCP网络数据读写说明4. 迭代服务器编程4.1 服务端代码4.2 客户端代码4.3 测试迭代服务器 5. 并发服务器编程5.1 并发服务器编程注意事项5.2 并发服务器文件描述符变化图5.3 TCP并发服务器代码实现 一. 预备知识 1. IP地址 因特网是在网络级进行互联的,因此,因特网在网络层(IP层)完成地址的统一工作,即将不同物理网络的地址统一到具有全球惟一性的IP地址上,IP层所用到的地址叫作因特网地址,又叫IP地址。
因特网采用一种全局通用的地址格式,为每一台主机都分配一个IP地址,以此屏蔽物理网络地址的差异,即IP地址的意义就是标识公网内唯一一台主机。
在IP数据包中的信息带有源IP地址和目的IP地址,它们分别标识通信的源结点和目的结点,即信源和信宿。IP数据包经由路由转发的时候,源IP和目的IP不会改变,除非做了NAT转换才能改变。
2. 端口号(port) 网络通信的本质是进程间通信,有了IP就可以标识公网内唯一的一台主句,想要完成网络通信我们还需要一个东西来标识一台主机上的某个进程,这个标识就是端口号(port)。
端口号是传输层协议的内容,它包括如下几个特点:
端口号是一个2字节,16比特位的整数。一台主机中,一个端口号只能被一个进程所占用。 理解 “端口号” 和 “进程ID”
我们之前在学习操作系统的时候,知道pid可以用来标识进程;此处我们的端口号也是唯一标识一个进程。那么这两者之间又存在怎样的关系呢?
二者的相同点都是唯一标识主机内的一个进程,区别在于pid强调在系统的范围呢标识进程;而端口号强调在网络的范围内去标识进程。
既然pid已经做到唯一标识一个进程,为何还要引入端口号呢?我们可以从生活的角度去理解这种情况:即然每个人都有了唯一标识自己的身份照号,为何学校还要给我们分配学号呢?直接用身份照号不行吗?
学校给学生引入学号后,除了唯一标识学生这个作用外还有其他两个优点:
写入hdfs发现日志报错:
2023-03-28 13:50:14,988 [Thread-12] WARN org.apache.hadoop.hdfs.DFSClient - DataStreamer Exception
org.apache.hadoop.ipc.RemoteException: File /datas/xinfo/tmp/4g nt_tmp/day=2023328/hour=13/4g_xdrvent_tmp_2034923_46bd4a785
-d42a-455e-90e5-0b9082a4b399.tmp could only be replicated to 0 nodes instead of minReplication (=1). There are 14 datanode(s) running and no node(s) are
excluded in this operation.
at org.apache.hadoop.hdfs.server.blockmanagement.BlockManager.chooseTarget4NewBlock(BlockManager.java:1620)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getNewBlockTargets(FSNamesystem.java:3135)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:3059)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.addBlock(NameNodeRpcServer.java:725)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.addBlock(ClientNamenodeProtocolServerSideTranslatorPB.java:493)
at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos$ClientNamenodeProtocol 2. c a l l B l o c k i n g M e t h o d ( C l i e n t N a m e n o d e P r o t o c o l P r o t o s .
✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
📚专栏地址:Linux系统编程
📣专栏定位:整理一下 C++ 相关的知识点,供大家学习参考~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
🎏唠叨唠叨:在这个专栏里我会整理一些琐碎的 C++ 知识点,方便大家作为字典查询~
静态库和共享库 1. 区别 静态库
静态库在文件中静态展开,所以有多少文件就展开多少次,非常吃内存,100M 展开 100 次,就是 1G ,但是这样的好处就是静态加载的速度快。
动态库
使用动态库会将动态库加载到内存,10 个文件也只需要加载一次,然后这些文件用到库的时候临时去加载,速度慢一些,但是很省内存。
优缺点
动态库和静态库各有优劣,根据实际情况合理选用即可。
静态库:对空间要求较低,而时间要求较高的核心程序中。动态库:对时间要求较低,对空间要求较高。 2. 静态库制作 Linux :libxxx.a
lib :前缀(固定)xxx :库的名字,自己起.a :后缀(固定) Windows :libxxx.lib
静态库生成指令
ar rcs libmylib.a file1.o r - 将文件插入备存文件中c - 建立备存文件s - 索引 生成步骤
第一步: 写好源代码。
第二步: 编译源代码生成 .o 文件。
第三步: 制作静态库。
第四步: 编译静态库到可执行文件中。
gcc test.c lib库名.a -o a.out 编译时出现了函数未定义的警告,可以忽略,让系统生成默认的定义。
下图可以发现 test.c 只占用了 209 大小,而 test 却占用了 16752 ,说明静态库是直接编译到文件中。
1.创建虚拟环境 conda create -n xxx python=3.8 #创建python3.5的xxxx虚拟环境 conda activate xxx #开启xxxx环境 conda deactivate #关闭环境 2.安装gpu版本的pytorch 通过官网引导就可以完成安装,或者通过下面网址复制conda安装命令,安装历史版本
Previous PyTorch Versions | PyTorch
3.测试安装是否成功 import torch torch.__version__ 输出:
参考:
Windows环境下Gpu版本的Pytorch安装_pytorch向下兼容吗_晓码bigdata的博客-CSDN博客
文章目录 1、邮件功能功能分析设置邮箱Spring Mail导入jar包添加配置文件使用 JavaMailSender 发送邮件使用thymeleaf模版发送邮件 2、注册功能功能分析注册页面访问注册和激活加密工具类功能测试 3、验证码功能功能分析导入jar包编写配置类功能测试 1、邮件功能 功能分析 邮件功能,在用户注册时,用于验证用户邮箱并激活用户账号,用户输入正确邮箱地址并注册成功之后,需要向用户注册邮箱发送激活邮件。本功能旨在实现向指定邮箱发送邮件的功能。
设置邮箱 开通发送方邮箱的SMTP协议,如下图为QQ邮箱,设置完成后,保存更改
Spring Mail 导入jar包 在项目pom.xml文件中导入对应的jar包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> <version>2.2.6.RELEASE</version> </dependency> 添加配置文件 在 application.properties 中配置邮箱的相关设置,这里演示的是qq邮箱的相关配置。
# MailProperties spring.mail.host=smtp.qq.com spring.mail.port=465 #自己的邮箱账号 spring.mail.username=111111111@qq.com #邮箱授权码,邮箱设置页面生成,并不是邮箱登录密码 spring.mail.password=******** spring.mail.protocol=smtp spring.mail.test-connection: true spring.mail.default-encoding=utf-8 spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory spring.mail.properties.mail.smtp.port:${spring.mail.port} spring.mail.properties.mail.smtp.auth:true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true 使用 JavaMailSender 发送邮件 在community包下新建util工具包,在工具类 util 包下创建 MailClient类,用于发送邮件:
@Component public class MailClient { /**定义日志记录信息*/ private static final Logger logger = LoggerFactory.getLogger(MailClient.class); /**注入发送邮件的Java类*/ @Autowired private JavaMailSender mailSender; /**注意这个括号一定要是花括号*/ @Value("${spring.mail.username}") private String from; /** * 发送邮件 * @param to 发送对象 * @param subject 发送主题 * @param content 发送内容 */ public void sendMail(String to, String subject, String content){ try { /**创建发送的邮件类模版*/ MimeMessage mimeMessage = mailSender.
IDEA集成chatGPT目前需要准备
1.爬墙的梯子 2.一个chatGPT的登录账号
一.GPT现在开放的是gpt-3.5-Turbo
下载插件
在Idea右侧可以看到chatGPTer
二.登录gpt网址
此链接:https://platform.openai.com/account/api-keys
获取Create key然后到Idea 找到这个工具
配置chatGPT的key
然后就可以使用chatGPT-3.5-Turdo了
欢迎大家留言讨论!!!
2022山东省赛赛题 服务器配置及应用项目 三、linux 服务配置 (一)dns 服务 1.所有 linux 主机启用防火墙,防火墙区域为 public,在防火墙中放行对
应服务端口。
2.利用 chrony,配置 linux1 为其他 linux 主机提供 NTP 服务。
3.所有linux主机root用户使用完全合格域名免密码ssh登录到其他linux
主机。
4.利用 bind 配置 linux1 为主 dns 服务器,linux2 为备用 dns 服务器;为
所有 linux 主机提供冗余 dns 正反向解析服务。
yum -y install chronyd #chrony时间服务 #编辑服务端chrony的配置文件 vim /etc/chrony.conf server 10.10.21.101 iburst #line 3 allow 10.10.21.0/24 #line 23 local stratum 10 #line 26 systemctl start chronyd #放行防火墙 firewall-cmd --add-service=ntp #复制一份客户端配置文件 cp -p /etc/chrony.conf / #编辑客户端chrony的配置文件 vim /chrony.
问题描述 在SpringMVC框架中使用PageHelper插件进行分页时,查询结果返回全部数据,分页未生效。
Controller中的代码
··· PageHelper.startPage(1, 10); List<Map<String,Object>> list = userinfoMapper.queryAll(bean); if(CollectionUtils.isEmpty(list)){ list = new ArrayList<>(); } ··· 解决方案: 经过仔细排查后发现并非代码问题,由于配置文件是多数据源配置,其中一个数据源未引入PageHelper插件,导致分页不生效,添加上PageHelper配置之后分页生效。很坑,,
<!-- 创建SqlSessionFactory --> <bean id="sqlSessionFactoryBack" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSourceBack"/> <property name="plugins"> <array> <bean class="com.github.pagehelper.PageHelper"> <property name="properties"> <value> helperDialect=Oracle reasonable=true <!-- 配置pageNum参数合理化,比如第0页,和超过最后一页,则返会第一页和最后一页。而不是意想不到的数据 --> supportMethodsArguments=true <!-- 支持通过 Mapper 接口参数来传递分页参数”,通过interface传给mapper.xml,默认false不支持. --> params=count=countSql <!-- 为了支持PageHelper.startPage(Object params)方法,默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero --> autoRuntimeDialect=true <!-- 运行时多数据源(数据库)自动识别,默认值false。true则允许自动识别对应方言的分页. --> </value> </property> </bean> </array> </property> </bean>
文章目录 Leetcode 2. 两数相加Leetcode 24. 两两交换链表中的节点Leetcode 21. 合并两个有序链表Leetcode 206:反转链表Leetcode 25. K 个一组翻转链表Leetcode 141. 环形链表Leetcode 160. 相交链表Leetcode 143. 重排链表Leetcode237. 删除链表中的节点Leetcode19. 删除链表的倒数第 N 个结点Leetcode61. 旋转链表Leetcode234. 回文链表Leetcode445. 两数相加 IILeetcode23. 合并 K 个升序链表Leetcode148. 排序链表Leetcode146. LRU 缓存 Leetcode 2. 两数相加 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4] 输出:[7,0,8] 解释:342 + 465 = 807. 示例 2:
输入:l1 = [0], l2 = [0] 输出:[0] 示例 3:
👇👇关注后回复 “进群” ,拉你进程序员交流群👇👇
作者丨行者
来源丨架构师社区(ID:devabc)
人生真是荒唐,永远充斥着你想不到的变化。
一位Github上的开源技术大佬发帖称自己不得不暂停更新,因为他找不到工作,被生活所迫,他不得不送外卖谋生,现在又转行做出纳。这位大佬在Github上的开源项目“阿里云盘小白羊”已有1.1K的粉丝和过万的赞,但没有任何收益。
他说程序是自己的爱好,不会停止也无法割舍,但出纳是为了养家,因为他已经穷到舍不得买一瓶5.5元的2L可乐了。
许多网友表示看完他的经历后非常难受,程序员太难了,大佬都过得这么拮据,不知道自己到时候是什么结局。
有人说,做前端就是这样的,没有核心竞争力,就是农民工。
有人说,程序员光有技术没有用,就是个螺丝钉,赶紧想办法当管理才是王道。
有人问,程序员为什么要搞开源?不是自己砸自己饭碗吗?
答:因为程序员的成长过程就是学别人的开源内容。
有人说,程序员把自己的核心竞争力免费送给大家,开源就是大企业的陷阱,对程序员一点好处都没有。
有人说,开源就是乌托邦,就是自掘坟墓。
有人说,大佬们应该少做点技术分享,把行业壁垒立起来。
有人说,开源本来是一种精神,让大家平等获取信息,开源不等于免费。正因为程序员圈子里没有这种开源精神,也没有版权付费,才导致这样的情况出现。
有人说,代码可以开源,商业使用就得交钱。
有人说,开源就该对所有企业收费,企业下载一次收一次钱,这样的话,企业要么交钱用开源的包,要么花钱找程序员自研。说到底还是程序员不够团结,现在都免费,导致企业认为技术没用。
有人说,这位大佬不会玩开源,没有组织一个圈子,建几个群,总会有人内推。
有人说,既然项目有了流量,应该上点广告,不要自绝活路。
有人说,他的项目风险太高,会被阿里告。
一位网友总结:
1.从私人开发者的角度看,这位大佬很成功,但他的生活也很拮据,从年纪看应该是经历过互联网最后一波红利期的人。
2.他把所有的盈利模式都堵死了,程序员真是个很傻的群体。
3.理想固然重要,但如果长时间坚持下去没有收入,还是要放弃,毕竟有一家人需要照顾。
热爱程序且愿意开源的技术大佬,却不得不为了生活放弃理想和爱好,对此我们只觉得心痛,就像有位网友所说,看到他犹豫买可乐那一段,忍不住破防了。
从长远来看,开源能够促进技术的进步,但从开发者自身来看,开源会降低开发者个人的核心竞争力。所谓“教会徒弟饿死师傅”,人们通过信息差的存在构建起技术壁垒,才能维持自己的竞争力。由于开源项目具有的特殊性,开发者很难从中盈利,而且很多开发者也不愿以此盈利,导致他们的付出与回报不成正相关。
开源是乌托邦,是理想主义,开源本无罪,但如何在理想和现实、爱好与生存之间寻求一个平衡,这是我们一生都在寻找的答案。希望这样的悲剧越来越少,希望愿意帮助别人的人也能得到别人的帮助,让这个圈子、这个行业都能良性循环起来。
-End-
最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!
点击👆卡片,关注后回复【面试题】即可获取
在看点这里好文分享给更多人↓↓
目录 PCB模块化设计09——RJ45-以太网口PCB布局布线设计规范1、以太网口概述2、RJ45的典型应用3、以太网的典型电路设计①集成网络变压器的RJ45设计方式②变压器分离的的RJ45设计方式 4、布局要求5、布线要求 PCB模块化设计09——RJ45-以太网口PCB布局布线设计规范 1、以太网口概述 以太网(Ethernet)是一种计算机局域网组网技术,该技术基于IEEE制定的IEEE 802.3标准,它规定了包括物理层的连线、电信号和介质访问层协议的内容。
以太网是当前应用最普遍的局域网技术。Ethernet的接口是实质是MAC通过MII总线控制PHY的过程。
以太网接口电路主要由MAC控制器和物理层接口(Physical Layer,PHY)两大部分构成,目前常见的以太网接口芯片,如LXT971、RTL8019、RTL8201、、CS8900、DM9008 等,其内部结构也主要包含这两部分。一般32位处理器内部实际上已包含了以太网MAC控制,但并未提供物理层接口,因此,需外接一片物理层芯片以提供以太网的接入通道。
常用的单口10M/100Mbps 高速以太网物理层接口器件主要有 RTL8201、LXT971等,均提供MII接口和传统7线制网络接口,可方便的与CPU接口。以太网物理层接口器件主要功能一般包括:物理编码子层、物理媒体附件、双绞线物理媒体子层、10BASE-TX 编码/解码器和双绞线媒体访问单元等。
2、RJ45的典型应用 RJ45常用于路由器、工业控制板、消费TV-Dangle以及一些特殊平板案例里面。
图1 常见RJ45接口的应用案例
3、以太网的典型电路设计 常见RJ45接口可以分为集成型(集成网络变压器和RJ45)和非集成型(网络变压器和RJ45分离)两种。
①集成网络变压器的RJ45设计方式 图2 集成型RJ45接口
②变压器分离的的RJ45设计方式 图3 非集成型RJ45接口
4、布局要求 1)变压器和RJ45接口分离的情况下,如图4所示,RJ45接口和变压器之间的距离尽可能的缩短(在满足工艺要求的情况下);
图4 变压器和RJ45接口的间距
2)以太网转换芯片PHY和变压器之间的距离也应该尽可能的短,距离一般不超过5inch,若RJ45接口自带变压器,则以太网转换芯片尽可能的靠近RJ45接口放置,如5所示。
图5 PHY芯片的间距要求
3)如图6所示交流端接电阻的放置,一般先按照芯片手册推荐的放置,有的芯片会要求放置在以太网转换器端,如没有特殊要求,就靠近以太网转换芯片放置;
图6 交流端接电阻的放置
4)复位电路信号应当尽可能的靠近以太网转换芯片,如果可能的话应当远离TX+/-、RX+/-差分信号和时钟信号;
5)时钟电路应当尽可能的靠近以太网转换芯片,远离电路板的边缘以及其它高频信号、IO端口走线和其它磁性元器件;
根据以上布局要求,总体布局示意可以归纳如图7所示
图7 RJ45布局总体示意图
5、布线要求 1)TX+,TX-和RX+,RX-尽量走表层,这两组差分对之间的间距至少4w以上,对内的等长约束为5mil,两组差分对之间不需要等长,如图4-22。
图8 RX、TX差分布线要求
2)考虑到变压器为干扰源,变压器下面所有层需要进行挖空处理,挖到变压器的丝印即可,不用挖到焊盘,如图9。
图9 变压器本体下面挖空
3)PHY芯片到CPU的发送部分( GTX_CLK\TX_EN\TX_ER\TXD[7:0])和接收部分(GRX_CLK\RX_DV\RX_ER\RXD[7:0])要分开布线,不要将接收和发送网络混合布线、线与线直接的间距满足3W,RX和TX分别等长,等长范围在100mil,阻抗控制50欧姆。
4)电源信号的走线,包括退耦电容的走线、电源线、地线应保持短而宽,退耦电容上的过孔直径最好稍大一点,每一个电容都应该有一个独立的过孔到地,不要共用地过孔;
5)交流端接一般要通过电阻以后再连接到芯片或者变压器上面,不允许有STUB线的出现;
6)对于千兆以太网的差分对,要优先选择最优的信号层进行布线,过孔的数量不要超过两个,并且打孔换层的时候,要在200mil的范围内增加回流地过孔,如图10。
图10 回流孔的放置
7)电源和地的处理原则:
RJ45底盘接地和数字地通过一个1M欧姆的电阻和一个0.1uF的去耦电容隔离。其底盘接地和数字地的间距,必须比60mil宽。如图11及图12所示。
图11 典型变压器集成单RJ45的机箱/数字地平面
图12 典型RJ45和变压器分开的机箱/数字地平面
‚所有不同的电源电压的的数字和模拟电源平面应当隔离。如图13及图14所示。
图13 典型变压器集成单RJ45的数字/模拟电源平面
图14 典型RJ45和变压器独立的数字/模拟电源平面
提示小助手:
从以太网物理层接口器件过来的信号接往RJ45网口插座时需要注意:金属机壳以及与印制板相连的金属前面板应与印制板内部电路(包括信号和地线层)隔离至少 5mm 以上,印制板静电电流泄放通路的地应优先选择机壳地,板上的金属部件和金属接插件能就近接机壳的应就近接机壳,无法就近接机壳的接静电保护地环或工作地,工作地应是大面积的地层。
Neofetch:在终端中显示 Linux 系统信息 Neofetch 是一个简单但有用的命令行系统信息工具,它用 Bash 编写。它会收集有关系统软硬件的信息,并在终端中显示结果。默认情况下,系统信息将与操作系统的 logo 一起显示。但是,你可以进一步地自定义使用 ascii 图像或其他任何图片。你还可以配置 Neofetch 显示的信息、信息的显示位置和时间。Neofetch 主要用于系统信息的截图。它支持 Linux、BSD、Mac OS X、iOS 和 Windows 操作系统。在这个简短的教程中,让我们看看如何使用 Neofetch 显示 Linux 系统信息。
Rocky Linux EL9 or EL8 安装Neofetch 1、更新Rocky Linux
在安装Neofetch之前,更新软件包列表以确保安装的是最新版本是很重要的。要执行此操作,请打开终端并输入以下命令。
sudo dnf upgrade --refresh 2、导入EPEL存储库
在Rocky Linux上导入Extra Packages for Enterprise Linux(EPEL)存储库非常简单。EPEL存储库提供了默认Rocky Linux存储库中未包含的其他软件包。以下命令将演示如何做到这一点,但请确保为Rocky Linux发行版使用正确的命令。
为Rocky Linux 9导入EPEL
首先,启用CRB。
sudo dnf config-manager --set-enabled crb 3、接下来,使用以下(dnf)terminal命令安装EPEL。
sudo dnf install \ https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm \ https://dl.fedoraproject.org/pub/epel/epel-next-release-latest-9.noarch.rpm 为Rocky Linux 8导入EPEL
Rocky Linux 8的命令与9的命令相同,只是Enterprise Linux 8版本的路径不同。
一、数据库表设计 二、程序结构 2.1、App类配置 在app.config中配置链接数据库的字段 <connectionStrings> 部分 <?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /> </startup> <connectionStrings><add name="con" connectionString="Data Source = WIN-20230216VRB; Initial Catalog = Test01; User ID = sa; Password=jk123"/></connectionStrings> </configuration> 2.2、SelectMethod类 创建SelectMethod类,并在类中创建方法
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApp1 { class SelectMethod { //查询并返回值 public int Ex(string sql) { string con = ConfigurationManager.ConnectionStrings["con"].ToString(); SqlConnection conn = new SqlConnection(con); try { SqlCommand com = new SqlCommand(sql, conn); if (conn.
1、具体操作 具体操作参考这篇文章,非常好用!但是注意最下面的postData()函数中,url中还要改成自己的设备id。
(1条消息) arduino通过esp8266模块发送数据到云服务器_arduino esp8266 上传数据_代码小白101的博客-CSDN博客
2、代码修改 由于我的传感器数据比较多(6个),所以在使用次代码时出现了上传失败的问题,于是我把6个数据拆成了3次发送,代码如下:
主要修改了updateTemp()函数、postData()函数。
#include <stdlib.h> #include <SoftwareSerial.h> #define SSID "VIVO X27" //wifi名 #define PASS "l123321000" //wifi密码 #define IP "api.heclouds.com" // 连接thingspeak.com服务器 const char OneNetServer[] = "api.heclouds.com"; //String GET = "GET /update?key=ylZJctZfVULDM4NvVRfec97Axxw="; //输入前面记下的API const char APIKEY[] = "Zxc7y94ESpWDm=uu310H8CHWlME="; int32_t DeviceId = 1062145212; const char DS_ax[] = "ax"; const char DS_ay[] = "ay"; const char DS_az[] = "az"; const char DS_press[] = "F"; const char DS_temp[] = "