一:语法执行背景 ES boo查询中过多的拼接bool导致报maxClauseCount is set to 5000
{
"caused_by": { "type": "too_many_clauses","reason": "maxClauseCount is set to 5000" } }
查询DSL语句:
{
"from": 0,
"size": 20,
"query": {
"bool": {
"must": [
{
"match": {
"name": {
"query": "普通硅酸盐水泥(P·O)",
"boost": 5
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"min_score": 5,
"sort": [
{
"_score": {
"order": "desc"
}
}
]
}
二:分析原因 报错原因:是Search限制一个bool查询中最多只能有5000个值或子查询,当超过5000时,会抛出异常。
实际原因:name字段使用的分词器使用了同义词,导致“普通硅酸盐水泥(P·O) 42.5级”,被识别成了“水泥,复合硅酸盐水泥(P·O) 42.5级,普通硅酸盐水泥(P·O) 42.5级”,再经过分词器分词之后,会出现很多个term,导致查询bool超过限制。
在汽车行业,行人检测一直是一个研究热点与难点。
自动驾驶对于行人检测的准确性要求极高,行人姿态变化、衣着打扮、随机运动甚至室外光线等问题都会影响到检测的准确性。
使用高精度的传感器有利于算法结果准确,但高精度的传感器非常昂贵,成本和精度无法兼得,这种矛盾在过去一直很难解决。
相比之下,使用廉价的摄像机获取图像,通过处理图像来检测到行人的位置以及运动趋势,从而取代雷达,压缩成本,该过程就是行人检测技术。
目前为止,面向智慧交通的行人检测技术已经取得了不少的成就,本文将从行为检测的技术构成、主要分类及特点等方向进行简要阐述。
行人检测的主要特点 在自动驾驶中,行人检测主要是指对车载摄像设备获取的实时视频进行检测,通过获取行人的相关信息来辅助车辆自动行驶的相关技术。
行人检测与一般的目标检测存在着较大差异,大多数目标检测方法并不完全适用于行人定位,主要原因有以下几点:
**1)小目标行人定位准确度较低。**远距离成像的行人通常目标较小、分辨率较低,缺乏明显的特征信息,易受到噪声影响,因此,检测算法难以精准定位小目标行人,识别难度较大。
**2)行人多姿态的特性导致定位准确度低。**区别于一般的目标检测,道路行人往往具有多姿态、随性的特征,此类不确定性会加大算法识别难度。
**3)背景影响对检测的干扰。**行人检测受背景影响较大,如光照变化、行人周围轮廓等干扰都会直接影响算法定位,从而出现误判、漏判,加大准确识别难度。
**4)目标重叠、遮挡对算法识别的影响。**道路通常会出现人挨人、人挤人现象,这无意加大了识别难度,尽管目前的行人检测方法已能处理局部遮挡问题,但对于大面积、较严重的遮挡问题仍难以解决。
这些问题是行人检测技术的难点,同时也是目标检测领域的研究热点。
在实际应用中,行人检测系统面临的是一个开放的环境,要考虑不同的路况、 天气和光线变化,不仅要具备高实时性,同时也对算法的鲁棒性提出较高要求。
随着图像处理技术的发展,越来越多的研究人员提出了基于图像分割、深度学习、混合模态 等行人检测方法来解决以上问题,这也让行人检测技术得到了长足的进步。
图像分割行人检测法 顾名思义,图像分割是将图像分解为若干个特定区域,再将这些区域划为不同的类别,以便提取不同的目标区域。
传统的行人检测技术主要依赖于图像分割法,该方法不仅计算速度快,且节约硬件资源,但该方法易受其他因素干扰,如背景、遮挡等,对行人检测的准确度不高。
现阶段,有三种基于图像分割的行人检测技术应用甚广,分别为阈值分割检测法、边缘分割检测法和语义分割检测法。
其中,阈值分割检测法是最常见的检测方法,该方法使用图像灰度特征进行灰度计算,通过设定不同的特征阈值,将图像中的像素点划分为若干类,进而与阈值进行对比来完成分割。
边缘检测法则是寻找出图像的灰度、颜色、肌理等图像特点忽然改变的地方,从而将其作为图像边缘进行分割。该方法受复杂背景影响较小,对于边界特征较明显的行人检测精度较高。
语义分割检测法是利用卷积神经网络对复杂环境进行分割,该方法通常具有较好的检测精度,稳定性较高。使用语义分割方法可以使提取到的行人特征更典型,增强模型的泛化能力。
深度学习行人检测法 相较传统机器学习检测方法,基于深度学习的行人检测方法具备更高的准确率和鲁棒性。
近年来,深度学习技术已广泛应用于各类图像处理中,非常适用于行人检测,促进了无人驾驶车辆系统在行人检测等多个核心领域的发展。
主流的深度学习行人检测方法可以分为两类:
1)以区域卷积神经网络(R-CNN)、快速区域卷积神经网络(Fast R-CNN)、高速区域卷积神经网络(Faster R-CNN)为代表的基于候选框的方法。
2)以 YOLO(You Only Look Once)、轻量级目标检测(Single Shot MultiBox Detector,SSD)为代表的基于回归的方法。
这两种方法的差异性在于前者将候选区域的选定和目标边界框的推理识别放置于两个完全不同的过程阶段中,而后者则是一步到位,省去了网络训练和推理计算的复杂性,这也是目前主流的方案都是单阶段的主要原因。
未完待续…
1.indexDb.js
const indexDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB; class IndexDBCache { // 构造函数 constructor() { this._db = null; //数据库 this._transaction = null; //事务 this._request = null; this._dbName = "loginInfoDb"; //数据库名 this._cacheTableName = "loginInfoTable"; //表名 this._dbversion = 1; //数据库版本 } initDB(val) { return new Promise((resolve, reject) => { this._request = indexDB.open(this._dbName, this._dbversion); // 打开数据库 // 数据库初始化成功 this._request.onsuccess = (event) => { this._db = this._request.result; resolve(event); }; // 数据库初始化失败 this._request.onerror = (event) => { reject(event); }; // 数据库初次创建或更新时会触发 this.
Java中可以使用观察者模式开发,有三种简单的方式可以实现。
自定义接口实现
观察者 public interface Observer { public void update(Object o); } 观察者的实现
public class ObserverImpl implements Observer{ private Object str; @Override public void update(Object o) { this.str = o; System.out.println(this.str); } } 观察者的注入和方法调用
@Autowired private List<Observer> observers; @GetMapping("impl/{str}") public void impl(@PathVariable("str") String str){ for (Observer observer : observers){ observer.update(str); } } 基于spring的事件
先定义spring事件 public class CustEvent extends ApplicationEvent { public String msg; public CustEvent(Object source, String msg) { super(source); this.
SharpContour: A Contour-based Boundary Refinement Approach for Efficient and Accurate Instance Segmentation 论文链接:[2203.13312] SharpContour: A Contour-based Boundary Refinement Approach for Efficient and Accurate Instance Segmentation (arxiv.org)
代码链接:无
1. 背景和动机 实例分割是计算机视觉中的一个重要任务,它旨在识别并分割图像中的每个目标实例。近年来,基于深度学习的实例分割方法取得了显著的进展,但是在边界区域的分割质量仍然不尽如人意,导致实例分割的准确性和鲁棒性受到限制。
为了提高边界区域的分割质量,近些年出现了一些边界细化的方案,本文指出一个好的边界细化方案应该需要满足以下三个基本要求:准确、高效以及通用。
然而目前效果最好的方案均无法同时满足以上三个要求:
准确、通用但不高效
[2104.05239] Look Closer to Segment Better: Boundary Patch Refinement for Instance Segmentation (arxiv.org):BPR需要基于实例分割模型输出的Mask的边缘去提取大量Patch,并独立对各个Patch进行计算,这会带来比较大的计算成本。
[1912.02801] PolyTransform: Deep Polygon Transformer for Instance Segmentation (arxiv.org):PolyTransform提出了第一个基于contour的边缘优化方案,它使用mask-based模型输出的Mask生成初始的contour,然后再通过Transformer网络对Contour进行Refine,Transformer网络会带来较大的计算量。
准确、高效但不通用(大都仅能对一些mask-based模型的输出进行Refine,无法应用于contour-based模型)
[1912.08193] PointRend: Image Segmentation as Rendering (arxiv.org):PointRend仅在一些模糊边界点上进行分割,从而降低了计算量。[2104.08569] RefineMask: Towards High-Quality Instance Segmentation with Fine-Grained Features (arxiv.
前言:本篇是 Linux 基本操作篇章的内容!
笔者使用的环境是基于腾讯云服务器:CentOS 7.6 64bit。
学习集:
C++ 入门到入土!!!学习合集Linux 从命令到网络再到内核!学习合集 注:本文涉及文件内容查看或编辑,故有预先准备的测试示例,若读者无测试示例,可参照 第 0 点 目录进行操作生成!
目录索引:
0. 测试使用用例命令 1. 基本语法及功能 2. 两个指令的注意点及异同点(重点) 3. 两个指令找内容对比 4. 指令可选项及使用示例 - - 4.1 more 指令 [-x]:指定显示前 x 行内容 - - 4.2 less 指令 [-N]:显示每行的行号 5. less 指令的其他可选项
6. 相关文章或系列推荐
0. 测试使用用例命令 第一个测试用例:源自《Linux :: 【基础指令篇 :: 文件内容操作:(1)】:: nano 指令 :: 使用自带文件编辑器及简单演示Linux下gcc编译执行可执行程序(仅作了解:会用来创建文件即可)【基本不会用到】》中的第三点:简单演示Linux下gcc编译执行可执行程序【打印 Hello Linux 程序】;第二个测试用例:命令行输入如下指令: count=0; while [ $count -le 100 ]; do echo "hello ${count}"
异常信息 Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java. base does not "opens java. lang" to unnamed module @661972b0 ———————————————— jdk1.8正常运行,而高版本jdk17运行报错
java.lang.reflect.InaccessibleObjectException: Unable to make field transient java.util.HashMap$Node[] java.util.HashMap.table accessible: module java.base does not “opens java.util” to unnamed module @200a570f,
解决方法:(针对于Idea2023.3版本)
Run—>EditConfigurations…—>Modify options—>Add VM options—>JVM options
在JVM options 内添加下面指令:
--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens java.
问题背景:在本人的个人项目中,在搭建Map地图服务时,需要调用高德地图的API。这个时候一般我们有以下几种方式可以选择:
1. 通过java.net.HttpURLConnection (原生)。
2. 通过org.apache.http.client.HttpClient (Apache HttpComponents)。
3. 通过Spring框架自带的RestTemplate对象。
4. 通过OpenFeign/Retrofit远程调用。
由于本人在项目中采用的是SpringCloud微服务架构,所以采用了自己比较熟悉的OpenFeign远程调用框架。
而使用OpenFeign调用其他平台的API,则需要定义声明式Feign接口。
问题描述:通过声明式Feign调用接口,返回来的参数一直是空的。
问题原因:接参的对象 和 返回的JSON对象 对不上。因为之前Feign接口一直用的是统一返回对象ResponseResult<T>,没有使用过声明式的Feign接口,所以导致忘记修改接参对象导致对象反序列化失败,数据为空。
解决方案:接参对象直接改为Vo,不用ResponseResult封装。
直接上调用链路:
Step0:先看看Feign接口代码和FeignConfig拦截器配置。 这一块是该声明式Feign接口的代码,可以看到里面包含了Feign声明式接口的所有配置,前置URL是高德地图平台提供的。
这块是FeignConfig配置类,对GET请求添加了key秘钥和返回类型的参数(也是高德地图提供的)。
Step1:Controller层代码。 Controller层代码没什么问题,主要是做了数据校验。
Step2:Service层代码。(上图的业务代码) 在Service层中,我们在return语句处打一个断点,看看具体的数据有没有问题。
看URL好像并没有什么问题,前置URL是正确的,那我们就需要查看完整的URL对不对了。
Step3:打开Feign日志,打印详细的Feign请求信息。 这一步,我们成功打开了Feign的详情日志。
Step4:再次调用接口,查看请求详细信息。 这一步发现,调用了接口是有数据返回回来的,那问题就很清楚了:
接参的对象 和 返回的JSON对象 对不上。
datagrip连接本地主机时报错
导致原因:数据库连接权限问题
用“Win+R”键进入命令提示符
之后连接测试成功
项目中使用扫码二维码获取设备信息
初始化设备二维码信息 : {"id": 1646692300021080066,"pwd": "Safety"}
扫描后获取结果 {"id": 1646692300021080066,"pwd": "Safety"}
使用 JSON.parse() 可以看出 id值后面发生错误,导致id值不准确
解决办法
初始化设备二维码信息 : {"id": "1646692300021080066","pwd": "Safety"}
再使用 JSON.parse() 返回结果就OK了
1.创建namesrv服务
1.1 拉镜像
docker pull rocketmqinc/rocketmq 1.2 加挂载目录
以我的本机为例,E:\data\rocketmq-data下创建broker和nameserver文件夹
nameserver文件夹下建logs和store目录
1.3 启动
#启动nameserver docker run -d --restart=always --name rmqnamesrv --privileged=true -p 9876:9876 -v E:/data/rocketmq-data/nameserver/logs:/root/logs -v E:/data/rocketmq-data/nameserver/store:/root/store -e "MAX_POSSIBLE_HEAP=100000000" rocketmqinc/rocketmq sh mqnamesrv 2.创建broker
2.1 加挂载目录
broker文件夹下建conf,logs,store 三个文件夹
conf文件夹下建broker.conf文件
broker.conf文件内容如下
brokerClusterName = DefaultCluster brokerName = broker-a brokerId = 0 deleteWhen = 04 fileReservedTime = 48 brokerRole = ASYNC_MASTER flushDiskType = ASYNC_FLUSH brokerIP1 = 192.168.2.101 2.2 启动broker
#启动broker docker run -d --restart=always --name rmqbroker --link rmqnamesrv:namesrv -p 10911:10911 -p 10909:10909 --privileged=true -v E:/data/rocketmq-data/broker/logs:/root/logs -v E:/data/rocketmq-data/broker/store:/root/store -v E:/data/rocketmq-data/broker/conf/broker.
Compose 中 TextField 的有效状态管理 为了防止同步问题和意外行为:
避免在输入和更新TextField状态之间出现延迟/异步行为。避免使用响应式流收集StateFlow的数据来保存TextField状态,例如使用默认调度程序。使用Compose API,例如MutableState<String>,定义TextField状态变量。 需要时,将TextField状态提升到ViewModel,例如将业务验证应用于TextField内容。 假设我们必须在Jetpack Compose应用中实现注册页面,并收到以下设计:
我们有两个文本输入框和一个按钮。
让我们从顶部的文本输入框开始,它是用户名字段。
为了在Compose中实现一个文本输入框,我们需要定义一个状态变量:
存储当前显示的值,并将其传递给TextField的值参数。每当用户在TextField的onValueChange回调中输入新文本时,就会更新它。 /* Copyright 2022 Google LLC. SPDX-License-Identifier: Apache-2.0 */ var myValue = ... OutlinedTextField( value = myValue, // #1 onValueChange = { newValue -> myValue = newValue } // #2 ... ) } 在处理状态时,重要的事情是决定将状态变量放在何处。在我们的例子中,我们希望对用户名进行一些业务逻辑校验,因此我们将状态提升到ViewModel中,而不是将其保留在组成函数中。如需更多关于此及如何组织应用架构的信息,可以阅读我们的架构指南。
通过将状态放在ViewModel中,TextField值将在配置更改时免费持久化。
基于这些要求,我们创建一个包含类似于此的OutlinedTextField组件的组合注册屏幕:
/* Copyright 2022 Google LLC. SPDX-License-Identifier: Apache-2.0 */ // SignUpScreen.kt @Composable fun SignUpScreen(...) { OutlinedTextField( ... value = viewModel.username.collectAsStateWithLifecycle(), onValueChange = { viewModel.
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency> import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class WriteToExcel { private static XSSFWorkbook workbook; private static XSSFSheet sheet; private static XSSFRow row; private static XSSFCell cell; private static File file; //创建sheet页 public static void setSheet(String sheetName) { workbook = new XSSFWorkbook(); sheet = workbook.createSheet(sheetName); } //创建表头 public static void createHead(List<String> headList) { //创建表头,也就是第一行 row = sheet.
由于c++中的replace函数只能替换一次字符串中的字符/子串,所有需要通过循环遍历方式,多次替换。根据循环方法不同,分为以下几个方法:
方法1:通过size_type pos 指针 加上简单的while(true)循环进行遍历
string::size_type pos(0);
while (true)
{
pos = modi_reason.find(“ ”);
if( pos != string::npos )
{
modi_reason.replace(pos , 1 , “” );
}
else
{
break;
}
}
方法2,(同方法1)
while(true)
{
string::iterator p = find( old_string.begin(), old_string.end(), 'new_char' );
if ( p!= old_string.end() )
{
old_string.replace( p , old_sub_string.length() , new_sub_string )
}
}
方法3:通过size_type pos 指针进行遍历
string& replace_all(string& src, const string& old_value, const string& new_value) {
文章目录 1.variant技巧2.std::enable_if_t用法(1)C++模板 SFINAE(2)C++模板 匿名类型参数(3)enable_if(4)enable_if_t(5)后面那个 = 0 是个什么东西? 3.PIMPL模式4.二维数组5.折叠表达式 1.variant技巧 自定义match模板函数可以将多个lamda打包成一个,通过重载来调用
#include <iostream> #include <variant> template <class ...Fs> struct match: protected Fs...{ explicit match(Fs const&... fs) :Fs(fs)... {} using Fs::operator()...; }; template <class ...Fs> match(Fs const&... fs) -> match<Fs...>; int main() { std::variant<float, int, std::string> v; v = "abcd"; std::visit(match[&](auto x){ std::cout<<x<<std::endl;}, [&](std::string x){std::cout<<x<<std::endl;},v) return 0; } 测试:
也可以利用C++17 新增的 overloaded 模板,可以直接生成匿名访问器,简化代码, 下面的代码是等价的 int main() { std::variant<int, float, string> value = 1.
Vue-Rules表单验证组件的相关使用: 基本用法([ ] 内容为测试内容,可以按照自己代码修改):
<el-form :model="[form]" :rules="[rules]" ref="[form]"> <el-form-item label="[评分]" prop="[score(需要验证的数值)]"> <el-input v-model="[form.score(输入框输入的数值,需要被验证)]"></el-input> <!-- 表单验证的测试事件 --> <el-buttpn @click="test">测试按钮</el-button> </el-form-item> </el-form> <script> export default { name:"Test", data(){ return{ form:{}, rules:{ score:[ [(该验证规则为:必填,输入为整数的1至5)] { pattern:/^[1-5]\d*$/,required: true,message:"请输入1~5",trigger:'blur'}, ] } } }, methods:{ test(){ this.$refs['form'].validate((valid) =>{ if (valid) { //表单检验合法 [(事件内容)] } }) } } </script>
前言 在开发 Java 项目时,依赖注入是一种常见的实现方式。Spring Boot 框架通过 @Autowired 注解来实现依赖注入的功能,这也是 Spring Boot 开发工程师必须要掌握的一个技能点。本文将介绍 Spring Boot 中 @Autowired 注解实现的原理。
1. 什么是 @Autowired 注解 @Autowired 是 Spring 框架提供的一种依赖注入方式,它可以自动装配 Bean,并将成员变量、方法参数或构造函数中需要的对象注入到对应的位置。它是基于 Java 的反射机制实现的,能够方便地管理对象之间的依赖关系。
2. @Autowired 注入的方式 Spring Boot 中,@Autowired 注解可以用于在类的成员变量、构造函数和方法中注入 Bean。下面是具体的使用方法:
2.1 在成员变量中使用 @Autowired 注解 将 @Autowired 注解放在类的成员变量上,可以让 Spring 将指定类型的 Bean 自动注入到成员变量中。例如:
@Component public class UserService { @Autowired private UserDao userDao; // ... } 在上面的例子中,UserService 类中的 userDao 成员变量会被自动注入 UserDao 类型的 Bean。
2.2 在构造函数中使用 @Autowired 注解 将 @Autowired 注解放在类的构造函数上,可以让 Spring 自动地将所需要的 Bean 注入到构造函数参数中。例如:
高可用环境介绍 搭建高可用环境,可以消除单点故障的影响,使系统在出现故障时自动地切换到其它节点,保障系统的平稳运行,提高系统的可靠性和可用性,同时保证数据的安全性,高可用环境已经是现代企业应用的标配。
本文介绍如何快速搭建一个小型的高可用环境,涉及的产品包括:2台云主机(CenTOS 7.6系统)、数据库和负载均衡。
二、前置准备 正式开始部署前,您需完成如下的准备工作:
开通京东云账户,若您还未注册京东云账号,可在京东云官网进行注册;账户开通后,需要进行实名认证。 三、搭建第一台云主机环境 购买1台云主机,本文选择CenTOS 7.6系统进行操作演示
购买完成后,访问云主机控制台
点击一台云主机操作中的远程连接
输入密码进行登录,如果忘记密码可以返回控制台修改密码
安装Java的JDK
yum install java-1.8.0-openjdk 安装tomcat
yum install -y ca-certificates wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.87/bin/apache-tomcat-8.5.87.tar.gz 解压缩tomcat,您Java应用的war包可以部署到tomcat上进行发布
tar -zxvf ./apache-tomcat-8.5.87.tar.gz 启动tomcat
cd apache-tomcat-8.5.87/bin ./startup.sh 在浏览器访问IP:8080 查看启动效果,如果访问失败,请查看8080端口是否在安全组中开放
四、搭建第二台云主机环境 访问云主机控制台,选择第一台搭建好环境的云主机,点击操作中的制作镜像
输入镜像名称和描述,进行镜像制作
镜像创建好后,可以点击创建云主机,使用该镜像购买一个新的云主机;如果已经有了第二台云主机,可以在实例列表页选择刚创建的镜像进行系统重装
本文选择第二台云主机进行重装系统进行操作演示
重装系统后,登录到云主机,查看Java环境
java -version 启动tomcat
cd apache-tomcat-8.5.87/bin ./startup.sh 在浏览器访问IP:8080 查看启动效果,如果访问失败,请查看8080端口是否在安全组中开放
五、配置数据库 购买云数据库后,访问数据库控制台页面
点击数据库名称位置进入配置页
切换到库管理标签页,点击创建库按钮创建新数据库
切换到账号管理标签页,先创建一个账号,然后点击账号操作中的修改权限
选择刚才创建的数据库,授权权限
您在云主机上部署的Java应用,可以通过下图的内网域名链接数据库,账户和密码使用上面步骤刚创建的信息
六、配置负载均衡 购买负责均衡后, 访问实例列表页 ,点击负载均衡实例的名称,进入配置页
切换到虚拟服务器组标签页,新创建一个服务器组,创建后点击服务器组操作中的编辑
选择主机实例,点击添加后,进行确定
切换到监听器标签,新建监听器,端口为8080
后端转发配置,修改端口为8080
健康检测端口为8080
选择刚才创建的服务器组,点击确定
在浏览器输入负载均衡的IP进行访问
前文:
《Tomcat源码:启动类Bootstrap与Catalina的加载》
《Tomcat源码:容器的生命周期管理与事件监听》
《Tomcat源码:StandardServer与StandardService》
《Tomcat源码:Container接口》
《Tomcat源码:StandardEngine、StandardHost、StandardContext、StandardWrapper》
《Tomcat源码:Pipeline与Valve》
《Tomcat源码:连接器与Executor、Connector》
《Tomcat源码:ProtocolHandler与Endpoint》
《Tomcat源码:Acceptor与Poller、PollerEvent》
前言 前文中我们介绍了Acceptor与Poller,其中Acceptor负责监听socket连接,并将请求转交到Poller中调用processSocket方法处理。
结合我们之前介绍连接器时的讲解,EndPoint 接收到 Socket 连接后,生成一个 SocketProcessor 任务提交到线程池去处理,SocketProcessor 的 Run 方法会调用 Processor 组件去解析应用层协议,这一操作的起点就是processSocket方法,下面我们就从该方法开始讲起。
目录
前言
一、SocketProcessor
1、processSocket
2、createSocketProcessor
3、doRun
3.1、isHandshakeComplete 3.2、ConnectionHandler 3.3、registerReadInterest、registerWriteInterest 二、ConnectionHandler
1、构造方法
2、process
2.1、removeWaitingProcessor、addWaitingProcessor
2.2、longPoll
2.3、release
三、Http11Processor
1、Http11Processor的创建
1.1、createProcessor
1.2、构造方法
2、process
3、service
一、SocketProcessor 1、processSocket 首先尝试从processorCache(AbstractEndpoint中的成员变量,前文中有过介绍,类型为SynchronizedStack<SocketProcessorBase<S>>)中获取现有的SocketProcessorBase对象,如果没有则调用createSocketProcessor方法创建,有的话则调用rest方法重置socket包装类与监听事件。
在SocketProcessor创建完了后,根据dispatch是否为true与 executor 是否为空来判断是否将当前连接的处理放入线程池中等待处理还是直接进行方法调用处理。
public abstract class AbstractEndpoint<S,U> { public boolean processSocket(SocketWrapperBase<S> socketWrapper, SocketEvent event, boolean dispatch) { try { if (socketWrapper == null) { return false; } SocketProcessorBase<S> sc = null; if (processorCache !
1.如果安装库报错: PackagesNotFoundError: The following packages are not available from current channels:
检查一下下载的annconda版本是否安成x86
import platform platform.platform() 正确输出应该为:
‘macOS-12.6.3-arm64-arm-64bit’
如果版本正确说明已经安装了正确annconda:
那么可能是别的问题,参考解决:
https://blog.csdn.net/weixin_45552562/article/details/109668589
2. 如果是annconda版本安错了: 1.参考https://blog.csdn.net/RinaWong/article/details/122913285
删除当前annconda
2.安装annconda并安装tensorflow:
参考:https://zhuanlan.zhihu.com/p/385449229
在 UniApp 中,Cover-View 组件是一种用于展示覆盖在页面上方的视图元素的组件。它可以用于创建各种遮罩、弹出层、悬浮按钮等效果,提供了更多自定义样式和交互的可能性。本教程将详细介绍 Cover-View 组件的用法和示例代码。
步骤1:创建一个 UniApp 项目 首先,确保已经安装了最新版本的 UniApp。然后,创建一个新的 UniApp 项目或者打开一个现有的项目。
步骤2:添加 Cover-View 组件到页面 在需要使用 Cover-View 组件的页面中,找到需要添加的位置。可以在页面的 .vue 文件中直接编辑。
<template> <view> <cover-view class="cover">这是一个 Cover-View 组件示例</cover-view> </view> </template> <style> .cover { width: 200rpx; height: 100rpx; background-color: #ff0000; color: #ffffff; font-size: 16px; text-align: center; line-height: 100rpx; } </style> 在上面的示例代码中,我们创建了一个包含一个 Cover-View 组件的页面。该组件具有一个自定义的类名 “cover”,设置了宽度、高度、背景颜色、文字颜色等样式。
步骤3:编译和预览 保存上述代码后,使用相应的编译命令将 UniApp 项目编译为目标平台的应用程序。然后在目标平台上预览页面,可以看到一个红色背景、白色文字的矩形框覆盖在页面上方。
步骤4:更多样式和交互效果 Cover-View 组件还支持更多的样式和交互效果,可以根据需要进行自定义。以下是一些常用的属性和事件示例:
<template> <view> <cover-view class="cover" :style="{ width: viewWidth + 'rpx', height: viewHeight + 'rpx', backgroundColor: bgColor }"
一、安装 1. selenium其实虽然称之为工具,但是实际是python中一个库 pip install selenium==3.14 2.安装浏览器 谷歌、火狐、edge
3.下载浏览器驱动 根据浏览器版本下载
详情看下文链接:
https://blog.csdn.net/qq_37515374/article/details/128651883
二、八大元素定位方式 1、id定位 如果某个元素的有id属性,那么如果id属性的值唯一,则可以利用该属性的值定位
如果id属性的值是一串无序的字母或者数字,则不能使用,有可能是动态id
driver.find_element_by_id("id属性的值") 2、name定位 根据name属性的值来定位,但是如果name属性的值在当前页面不唯一,则是无法定位的
driver.find_element_by_name("keyWord") 3、class name class属性的值,不唯一的可能性很大
driver.find_element_by_class_name('s_ipt') 4、tag name (通过标签名本身选择,一般无法使用,不推荐) driver.find_element_by_tag_name("标签名") 5、link text (一般不要使用) driver.find_element_by_link_text("搜索") 6、partial link text(一般不要使用) driver.find_element_by_partial_link_text("搜") 7、xpath //标签名[@属性名=‘属性值’],其中// 表示全局搜索;标签名 表示要查找的元素的标签名;@属性名 表示该元素的某个属性名;‘属性值’ 表示该属性的值。/父元素/子元素,用 / 来表示层级关系,可以选取某个父元素下的直接子元素。//*[@属性名=‘属性值’],用 * 表示匹配所有的元素,并加上 [@属性名=‘属性值’] 来选择符合条件的元素。//*[contains(text(),‘文本内容’)],用 contains() 函数来匹配元素时,文本内容必须保持一致。使用逻辑运算符、通配符、使用轴 driver.find_element_by_xpath("//div[@class='source']//*[text()='删除']").click() 8、css selector 根据标签以及标签的属性进行定位
driver.find_element_by_css_selector('input[name="keyWord"]') # 如果class属性的值唯一,也可以将其写成css的语法.s_iptdriver.find_element_by_css_selector('.s_ipt') 三、webdriver常用方法 1、浏览器的操作 from selenium import webdriver import time # 打开浏览器 driver = webdriver.
一.NFS是什么 NFS(Network File System)是一种分布式文件系统协议,它允许在网络上的计算机之间共享文件和目录。NFS的工作原理是将文件系统挂载到远程计算机上,使得远程计算机可以像本地文件系统一样访问共享的文件和目录。NFS使用客户端-服务器模型,其中客户端计算机通过网络连接到NFS服务器,请求访问共享的文件和目录。NFS服务器将文件和目录的内容传输到客户端计算机上,使得客户端可以像访问本地文件系统一样访问共享的文件和目录。
NFS协议支持多种安全机制,包括基于主机的访问控制、基于用户的访问控制和加密传输。它还支持文件锁定和缓存机制,以提高性能和可靠性。
NFS是NAS的一种。NAS系统通常由一个或多个硬盘驱动器组成,可以提供大量的存储空间,同时也可以提供文件共享、备份和远程访问等功能。NAS系统通常使用标准的网络协议(如TCP/IP)进行通信,可以在局域网或广域网上使用。NAS系统的优点包括易于安装和管理、可扩展性强、数据安全性高等。
二.NFS部署 服务端 1.安装
nfs-utils-1.3.0-0.33.el7.x86_64 主程序包
yum install nfs-utils -y 2.服务端配置要共享的资源
例:服务器共享/webdata目录
[root@192 ~]# mkdir /webdata
[root@192 ~]# echo "nfs test" > /webdata/index.html
3.配置共享/webdata目录
[root@192 ~]# vim /etc/exports
/webdata 192.168.220.0/24(rw) 共享资源 共享给谁(共享的属性)
4.启动服务
[root@192 ~]# systemctl start nfs
5.查看共享资源
[root@192 ~]# exportfs -v
/webdata 192.168.220.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,ro,secure,root_squash,no_all_squash)
客户端 1.布置本地网站服务
[root@localhost ~]# yum -y install httpd
[root@localhost ~]# systemctl start httpd
2.查看共享资源 [root@localhost ~]# showmount -e 192.168.220.4
1.左侧固定,右侧自适应
<style> .left { width: 200px; height: 600px; background-color: rgb(247, 10, 10); float: left; } .right { height: 600px; margin-left: 200px; background-color: blue; } </style> <body> <div class="box"> <div class="left"></div> <div class="right"></div> </div> </body> 2.浮动+BFC
<style> .left { width: 200px; height: 600px; background-color: rgb(247, 10, 10); float: left; } .right { height: 600px; /* 触发BFC */ overflow: hidden; background-color: blue; } </style> <body> <div class="box"> <div class="left"></div> <div class="right"></div> </div> </body> 3.
最近很幸运的通过了WPS AI海外版的内测waitlist,这里和大家分享一下使用的体验和评价。
申请与安装 WPS AI分为国内版和海外版两种,其中根据WPS自己的介绍,国内版本的模型由MinMax公司提供,海外版则是直接使用OpenAI的接口。
国内版目前还在开发中,因此我们需要去申请海外版的使用资格,首先前往海外WPS官网,注册账号并登录。
然后前往WPS AI,填写waitlist申请表,如实填写即可。
然后就是等待,我等了两天就通过了,速度还是挺快的,通过时WPS会发送通知邮件,邮件内附有WPS AI内测版软件的链接,需要下载并安装。
需要注意的是,经过测试WPS海外版的AI相关功能不支持国内直接访问使用,请添加新的分流规则,将域名关键词wps加入到需要代理的列表内,或者直接开全局,否则打开软件也无法使用WPS AI。主要需要处理的两个域名是wps.com和wpscdn.com。
功能测试 WPS AI的官方介绍地址中介绍了目前在内测的一些主要功能,不像发布会上介绍的文字、表格、PPT等的全能版,目前内测版只开放了PDF和Word相关的功能。
PDF总结与搜索 这部分的功能和chatPDF比较类似,点击右上角的WPS AI按钮后会弹出侧边栏,有两个功能Insight和Inquiry,也就是总结与搜索。
使用前需要先上传PDF文件,然后会自动进行分析,这里的上传感觉可能会涉及到隐私泄露问题,需要注意一下。
分析速度上,一篇14页的论文花费了大概1分钟左右的时间,默认显示语言为英文,右上角有选项可以切换到中文,但不知道为什么,只要切换为中文就会报错无法使用。
总结部分,基本提炼出了文章的重点,而且还给出了每部分对应的原文页码。
搜索部分是类似chatGPT的聊天形式,可以询问与PDF内容相关的问题进行解答,同时what can I ask?部分也有一些自动推荐的问题。
文本相关 文本功能目前在Word文档里可用,可以通过点击页面右上角的WPS AI按钮,输入@AI,点击页面抬头的浮动栏或者选择文本后的浮动工具栏进行使用。
文本生成功能里内置了一些prompt,可以根据自己的需要使用,或者直接在输入栏里输入prompt也可以,但预设的prompt不能进行调整,也不能添加自定义prompt到列表里,后续感觉可以进行下优化。
生成的语言与prompt相关,支持中文输出。
如果已经有了写好的文本,选中后唤出AI工具栏也有一些预设的操作,包括润色,精简,扩写,续写等,还支持调整文本格式,比如改写成列表或者表格。
使用下来整体生成速度比较慢,而且不支持流式输出,只能等待整段文字一次性输出。
总结 目前来看内测版本的WPS AI功能还是比较少,可以认为是chatPDF和Word GPT Plus的内置加强版。
PDF部分,英文相关使用体验不错,但中文一用就报错就有点emmm了。
文本部分,生成文本的质量目前看比官网的GPT3.5要差一点,而且生成的速度比较慢,希望后面可以增加保存自定义prompt的功能。
当然,文本相关功能已经有很多实现了,还是希望PPT相关功能能尽快推出,这才是真正的生产力大提升~
DataFrame 和 Series 都可以用.sort_index()或.sort_values() 进行排序。
一、sort_values() def sort_values(self, axis: Any = 0, ascending: bool | int | Sequence[bool | int] = True, # ascending = True 默认升序排列; inplace: bool = False, # If True, perform operation in-place. kind: str = "quicksort", na_position: str = "last", # Argument ‘first’ puts NaNs at the beginning, ‘last’ puts NaNs at the end. ignore_index: bool = False, # If True, the resulting axis will be labeled 0, 1, …, n - 1.
一、输入和输出 输出和输入也可理解为人和计算机的交互,用户通过键盘、鼠标等向计算机输入信息,计算机处理后再展示结果给用户,这便是一次输入和输出的过程。
1、文档输出语句
document.write('我爱我家') 输出标题
document.write('<h1>我爱我家</h1>'); 2、控制台打印输出
console.log('错误在哪个地方'); 3、弹框提示信息显示
alert('请输入信息'); 4、输入语句
prompt('请输入你的年龄:'); 作用:显示对话框,
(1)以数字为例,向 alert() 或 document.write()输入任意数字,他都会以弹窗形式展示(输出)给用户。
(2)向 prompt() 输入任意内容会以弹窗形式出现在浏览器中,一般提示用户输入一些内容。
js代码执行顺序:
(1)按照html的文档流顺序执行JavaScript代码
(2)alert()和prompt()会跳过页面渲染先被执行。
字面量 字面量在计算机中描述事或者物
例如:
我的年龄是18,此时18就是“数字面变量”
'我爱js’字符串字面量
[ ]为数组字面量
{ }为对象字面量
前言 如果,想要深入的学习标准C库中perror、strerror函数,还是需要去自己阅读Linux系统中的帮助文档。
具体输入命令:
man 3 perror man 3 strerror 即可查阅到完整的资料信息。
perror函数 perror函数是C语言标准库中的一个函数,用于在发生系统调用错误时输出有关错误信息的描述。该函数定义在stdio.h头文件中。perror根据传入的参数(通常是一个字符串)生成一个描述性的错误消息,然后将这个消息输出到标准错误流(stderr)。
函数原型如下:
#include <stdio.h> //使用此函数需引入此头文件 void perror(const char *str); 参数:
str:一个指向常量字符的指针,用于提供上下文信息。在输出错误消息时,这个字符串将作为错误消息的前缀(也就是说,你可以手动的去描述这个错误是怎么发生的)。 perror的工作原理:当一个系统调用或库函数发生错误时,通常会将全局变量errno设置为一个特定的错误码。perror函数读取errno的值,并根据这个值生成相应的错误描述。然后,将错误描述与传入的字符串参数拼接,并输出到标准错误流。
使用示例:
#include <stdio.h> #include <stdlib.h> int main() { FILE *file_ptr; file_ptr = fopen("non_existent_file.txt", "r"); if (file_ptr == NULL) { perror("Error opening file"); return 1; } // ... 其他操作 ... fclose(file_ptr); return 0; } 在上面的示例中,当试图打开一个不存在的文件时,fopen函数会返回NULL,并将errno设置为一个特定的错误码。
调用perror函数输出类似于以下内容的错误消息:
Error opening file: No such file or directory 这里的"Error opening file"是传入的字符串参数,而"No such file or directory"
在进行(单片机)嵌入式开发的时候,我们为了调试方便,通常会使用 OLED / LCD / 串口助手 等去帮助我们调试程序,常常会使用到 LCD 或 OLED 点阵字模,下面是搜集到的几个在线取字模的软件,希望能对使用者产生一定的帮助!!!
简体汉字字模:
1. LCD/OLED汉字字模提取软件,(HZK12宋体)GB2312中文12_12点阵字库
2. LCD/OLED汉字字模提取软件,(HZK16宋体)GB2312中文16_16点阵字库
3. LCD/OLED汉字字模提取软件,(HZK16宋粗体)GB2312中文16_16点阵字库
4. LCD/OLED汉字字模提取软件,(HZK24宋体)GB2312中文24_24点阵字库
5. LCD/OLED汉字字模提取软件,(HZK24仿宋)GB2312中文24_24点阵字库
6. LCD/OLED汉字字模提取软件,(HZK24黑体)GB2312中文24_24点阵字库
7. LCD/OLED汉字字模提取软件,(HZK24楷体)GB2312中文24_24点阵字库
ASCII字模:
1. LCD/OLED字模提取软件,ASCII字符5_8点阵字库
2. LCD/OLED字模提取软件,ASCII字符6_12点阵字库
3. LCD/OLED字模提取软件,ASCII字符8_16点阵字库
4. LCD/OLED字模提取软件,ASCII字符12_24点阵字库
5. LCD/OLED字模提取软件,ASCII字符20_40点阵字库
6. LCD/OLED字模提取软件,ASCII字符24_48点阵字库
繁体汉字字模:
1. LCD/OLED汉字字模提取软件,(HZK16宋繁体)GB2312中文16_16点阵字库
图像取模软件:
1. LCD/OLED点阵图片取模,BMP点阵图像提取软件
16进制数据转图像或文字软件:
1. LCD点阵字库(16进制)数据转字模/图像工具
正点提供了PCtoLCD2002取字模软件,也可以使用这个软件进行字符或者汉字的取模;
添加font标签, 设置颜色, 一定要使用\"包围色号, 否则手机不显示颜色, 不支持英文颜色如red, blue… 只支持pc变色 <font color='#0000FF'> Test Content </font> 支持pc和app变色 <font color=\"#0000FF\"> Test Content </font>
在web页面中,经常遇到一些弹窗内部有滚动条,可以滚动,弹窗后面的文档流也可以滚动,两个滚动区域会相互影响,用户体验不太好。
方案一、封装禁止、允许滚动方法
1、弹出弹窗,禁止滚动,并停留在当前位置
const disableScroll = (domId) => { var scrollTopVal = document.documentElement.scrollTop || document.body.scrollTop; // 禁止滑动 const selectId = domId || 'app' const selectDom = document.getElementById(selectId) if (selectDom && selectDom.style.position !== 'fixed') { selectDom.style.position = 'fixed' selectDom.style.top = '-' + scrollTopVal + 'px' selectDom.style.width = '100%' selectDom.style.overflow = 'hidden' } } 2、关闭弹窗,恢复滚动,并恢复在停留位置
const enableScroll = (domId) => { /** *取消滑动限制***/ const selectId = domId || 'app' const selectDom = document.
使用vue3+vite+vue-i18n时,在对不同环境打包时出现development的包翻译失效问题,具体报错如下: “[intlify] The message format compilation is not supported in this build. Because message compiler isn’t included. You need to pre-compilation all message format. So translate function return ‘book.genderOptionWomen’.”
解决方案:
在vite.config.js配置文件中增加runtimeOnly: false属性,
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vueI18n from '@intlify/vite-plugin-vue-i18n' export default defineConfig({ plugins: [ vue(), vueI18n({ runtimeOnly: false }) ] })
框架:SSM
数据库:MySQL
语言:Java
下载链接:
https://download.csdn.net/download/yw1990128/87853243
B站演示链接:
基于SSM框架的酒店管理系统_哔哩哔哩_bilibili
1.1 课题研究背景及意义 随着我国改革开放的不断推进,国内人民生活水平的不断提高,旅游出行的人民越 来越多,商务活动也相当的活跃;再加上入境旅游的人也越来越多,入境从事商务活动 的外宾也越来越多。传统的手工己不适应现代酒店管理的需要,及时、准确、全方位的 网络化信息管理成为必需。在酒店的管理及业务日益复杂、要求在不断提高的现状下, 利用高科技、现代化的电脑自动化管理系统来处理日益繁重的酒店业务,对于大型的酒 店是必须具备的管理方式。
因此,随着计算机技术的广泛应用,在酒店客房管理中引入计算机管理技术,成为 -个值得深入研究的问题。经济的飞速发展正促使酒店向着大型化、现代化发展,而对 于中、小型酒店来说,客房、顾客等有关信息的管理随之急剧增加。在酒店管理的过程 中管理者开始大量运用电脑自动化管理,利用酒店客房管理系统,来实现由计算机来代 替人工执行-系列诸如增加新客房、删除客房、客户管理、领导决策管理等操作,从而 使中小型客房信息管理变得简单、快捷、安全,为社会的发展产生无形的效益:(1)经 济效益,该系统虽然无法直接产生经济来源,却能通过减少劳动力,提高劳动效率,节 约劳动成本支出来产生隐形经济效益;(2)社会效益,该系统对大量信息进行快捷、安 全处理,有利于促进酒店行业现代化发展,提升竞争优势,提高信息的保密性和安全性。
1.2 研究现状 目前,基于web的酒店管理系统已经成为了酒店管理的主流方式,许多酒店都在采用此类系统。下面是关于基于web的酒店管理系统的研究现状:
1. 基础功能已经成熟:许多基于web的酒店管理系统已经具备了基本的客户管理、订单管理、房态管理等功能,可以实现酒店日常运营管理的要求。
2. 数据分析功能越来越受重视:现在的基于web的酒店管理系统也开始着重发展数据分析功能,帮助酒店管理者深入了解经营状况,以便调整经营策略。
3. 移动端应用趋势明显:随着移动设备的普及,基于web的酒店管理系统也开始向移动端方向扩展,开发出移动版应用程序,以方便酒店管理者随时随地管理酒店。
4. 数据安全是必须考虑的问题:酒店管理系统中包含了大量敏感信息,数据安全问题已成为必须考虑的问题,许多基于web的酒店管理系统开始加强数据加密、访问权限控制等安全性设计。
总的来说,基于web的酒店管理系统在发展过程中已经取得了一定的成果,但是在安全性、用户体验等方面仍需不断完善。
1.3开发技术简介 1、idea
在开发本平台中所有的开发软件是idea, IDEA全称IntelliJ IDEA,是java编程 语言开发的集成环境。IntelliJ在业界被公认为最好的java开发工具,尤其在智能代 码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit. CVS 整合、代码分析、创新的GUI设计等方面的功能可以说是超常的。IDEA是JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧 程序员为主。它的旗舰版本还支持HTML, CSS, PHP, MySQL, Python等。免费版只支持 Java, Kotlin等少数语言。
2、jsp
JSP全称Java Server Pages,是-种动态网页开发技术。它使用JSP标签在HTML 网页中插入Java代码。标签通常以〈%开头以%〉结束。它是-种Java servlet,主要用 于实现Java web应用程序的用户界面部分。网页开发者们通过结合HTML代码、XHTML 代码、XML元素以及嵌入JSP操作和命令来编写JSP, JSP通过网页表单获取用户输入数 据、访问数据库及其他数据源,然后动态地创建网页。3、 3、数据库
数据库使用的是MySOL开源数据库。MySQL使用C和C++编写,并使用了多种编译 器进行测试,保证源代码的可移植性。
MySQL与其他的大型数据库例如Oracle DB2. SQLServer等相比,自有它的不足之 处,如规模小、功能有限(MSQLCluster的功能和效率都相对比较差)等,但是这丝毫 也没有减少它受欢迎的程度。对于一般的个人使用者和中小型企业来说,MySOL提供的 功能己经绰绰有余,而且由于MySQL是开放源码软件,因此可以大大降低总体成本。
在此记录下在银河麒麟(Kylin V10)下使用SVN的方法以及一些命令的简单使用,其实对个人而言知道一些简单用法就够了。
1、安装: sudo apt install subversion 在kylin操作系统下,目前只找到了在线安装的方式,离线安装的方式还未找到(欢迎各位大佬不吝赐教)。
2、查看svn版本号: svn --version 3、检出: 在指定目录下执行以下语句,svn就会将服务器上的库下载到该目录下。
svn checkout http://192.4.2.8/projects/Kkkk --username=user //简写 svn co 然后按照提示输入该用户对应的密码。
其中,http://192.4.2.8/projects/Kkkk为SVN仓库的地址。
另外,经实际测试,在Kylin操作系统使用下面这种形式的SVN仓库地址:
svn checkout svn://192.4.2.8/projects/Kkkk --username=user 会提示连接不上svn服务器,连接超时(防火墙关闭,浏览器能访问)。
4、查看工作副本的状态 svn status //简写 svn stat svn st 如果要查看某个目录下文件的状态,只需进入到该工作目录下执行该命令。
状态码的含义:
单个字母情况:
空白 表示无改动
M 表示改动
A 表示添加
D 表示删除
R 表示替换
C 表示冲突
X 表示未纳入版本控制的目录,被外部引用的目录所创建
? 表示未纳入版本控制
! 表示该项目已遗失(被非 svn 命令删除)或不完整
两个字母情况:
UU 表示文件内容改变,文件属性改变
5、更新 svn update //更新当前目录下的所有 //简写 svn up 进入某个目录下执行该命令,则该目录下的所有文件都会更新。
1.什么是窗口函数 Flink窗口函数是指对数据流中的数据进行分组和聚合操作的函数。
FlinkSQL支持对一个特定的窗口的聚合。例如有用户想统计在过去的1分钟内有多少用户点击了某个的网页。在这种情况下,我们可以定义一个窗口,用来收集最近一分钟内的数据,并对这个窗口内的数据进行计算。
在Flink中,窗口函数可以分为两种类型:时间窗口和计数窗口。时间窗口是指按照时间对数据流进行分组和聚合操作。计数窗口是指按照数据条数对数据流进行分组和聚合操作。
FlinkSQL支持的窗口聚合主要是两种:window aggregate和over aggregate。他们最核心的区别是over aggregate从语义上保障了对每个输入都有一个输出,因此over agregate常被用于ranking,moving average等场景。
Window aggregate支持两种时间类型做窗口:Event Time和Processing Time。每种类型下,又分别支持三种窗口类型:滚动窗口(TUMBLE),滑动窗口(HOP)和会话窗口(SESSION)。
2.时间类型 BlinkSQL支持两种时间:
Event Time:用户提供的事件时间(通常是数据的最原始的创建时间),event time一定是用户提供在表的schema里的数据Processing Time:表示系统对事件进行处理的本地系统时间 具体见上篇文章。Flink时间属性_土豆马铃薯的博客-CSDN博客
3.实时计算中的窗口类型 3.1滚动窗口(Tumble Window) 滚动窗口将每个元素分配到一个指定窗口大小的窗口中,滚动窗口有一个固定的大小,并且不会出现重叠。例如:如果指定了一个5分钟大小的滚动窗口,那么无限流的数据会根据时间划分成[0:00 - 0:05), [0:05, 0:10),[0:10, 0:15)... 等窗口。如下图展示了一个 30秒大小的滚动窗口划分。
函数语法:用在GROUP BY子句中,定义window。
TUMBLE(time_attr, size_interval)
说明:
1. time_attr:参数必须是流中的一个合法的时间属性字段,即指定了 processing time 或是 event time;
2. size_interval:窗口时间间隔; 使用案例:
INSERT INTO dts_ds_merchant_target SELECT SUM(buy_amount) AS totalsale, TUMBLE_START(ROWTIME, INTERVAL '10' SECOND) AS tms, TUMBLE_END(ROWTIME, INTERVAL '1' SECOND) AS tme FROM dts_ds_merchant_source GROUP BY tumble(ROWTIME, INTERVAL '1' SECOND) 3.
Lifecycle-Hook¶ v3.3 and after
Introduction¶ A LifecycleHook triggers an action based on a conditional expression or on completion of a step or template. It is configured either at the workflow-level or template-level, for instance as a function of the workflow.status or steps.status, respectively. A LifecycleHook executes during execution time and executes once. It will execute in parallel to its step or template once the expression is satisfied.
In other words, a LifecycleHook functions like an exit handler with a conditional expression.
工作的时候遇到一个需要用echarts自动轮播全国地图数据的tooltip,并且鼠标放上去不影响操作的需求,感觉这个功能写出来应该会经常使用,所以来记录一下这部分的代码。
//自动轮播tooltip var currentIndex = -1; var tooltip_timer = null; tooltip_timer = setInterval(function() { var dataLen = option.series[0].data.length; // 取消之前高亮的图形 myChart.dispatchAction({ type: 'downplay', seriesIndex: 0, dataIndex: currentIndex }); currentIndex = (currentIndex + 1) % dataLen; // 高亮当前图形 myChart.dispatchAction({ type: 'highlight', seriesIndex: 0, dataIndex: currentIndex }); // 显示 tooltip myChart.dispatchAction({ type: 'showTip', seriesIndex: 0, dataIndex: currentIndex }); }, 1000); myChart.on('mouseout', function() { tooltip_timer = setInterval(function() { var dataLen = option.series[0].data.length; // 取消之前高亮的图形 myChart.
使用
sudo apt-get install gcc-11 想安装高版本的gcc但是怎么更新源都提示
Unable to locate package gcc-11 升级到ubuntu20.04也没解决,
最后是添加了
sudo add-apt-repository ppa:ubuntu-toolchain-r/test 然后再
sudo apt-get install gcc-11 竟然有了 然后不要忘记切换下版本
设备:NUC972DF61YC
使用的虚拟机环境:官方提供的NUC972DF61YC - Nuvoton
板载NAND FLASH,前期主要学习怎么uboot、ubootspl、uimage、env烧录。官方配置没有使用rootfs在flash中,所以数据会掉电丢失。即文件系统在RAM中。
这里仅仅整理移植时遇到的问题:
问题一:
【VFS: Mounted root (yaffs2 filesystem) readonly on device 31:2.】报错
yaffs: dev is 32505858 name is "mtdblock2" ro yaffs: passed flags "inband-tags" VFS: Mounted root (yaffs2 filesystem) readonly on device 31:2. devtmpfs: error mounting -2 刚刚学习挂载.dtb设备树文件,一直没有更新rootfs所以导致报错,重新编译下载rootfs解决。
问题二:
【VFS: Cannot open root device "mtdblock2" or unknown-block(0,0): error -6】报错
VFS: Cannot open root device "mtdblock2" or unknown-block(0,0): error -6 查找问题的思路:
1、 首先这里是说没法挂载mtdblock2分区,可以先往上看log,有没有下面这种:
3 ofpart partitions found on MTD device nand0 Creating 3 MTD partitions on "
Hive 常用函数 一、常用内置函数1、空字段赋值2、CASE WHEN THEN ELSE END3、行转列4、列转行5、窗口函数(开窗函数)6、Rank 二、常用日期函数三、常用取整函数四、常用字符串操作函数五、集合操作 一、常用内置函数 查看系统自带的函数 show functions; 显示自带的函数的用法 desc function upper; 详细显示自带的函数的用法 desc function extended upper; 1、空字段赋值 NVL:给值为NULL的数据赋值,它的格式是NVL( value,default_value)。如果value为NULL,则返回default_value的值,否则返回value的值。
2、CASE WHEN THEN ELSE END 求出不同部门男女各多少人。结果如下:
select dept_id, sum(case sex when '男' then 1 else 0 end) male_count, sum(case sex when '女' then 1 else 0 end) female_count from emp_sex group by dept_id; 3、行转列 CONCAT(string A/col, string B/col…):返回输入字符串连接后的结果,支持任意个输入字符串;
CONCAT_WS(separator, str1, str2,...):它是一个特殊形式的 CONCAT()。separator为参数间的分隔符。这个函数会跳过分隔符参数后的任何 NULL 和空字符串。
注意: CONCAT_WS must be "
一、STL初始
1.1 STL的六大组件
1.2 STL中的容器、算法、迭代器
二、容器算法迭代器初始
2.1 vector存放数据
2.1.1 vector存放内置数据类型
2.1.2 vector存放自定义数据类型
2.1.3 vector 容器嵌套容器
二、string容器
2.1 string容器——构造函数
2.2 string赋值操作
2.3 string字符串拼接
2.4 string查找和替换
2.5 string字符串比较
2.6 string字符存取
2.7 string插入和删除
2.8 string子串
一、STL初始 1.1 STL的六大组件 STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器、空间配置器
容器:各种数据类型,比如vector、list、deque、set等等,用来存放数据算法:各种常用的算法,比如sort、find、copy、for_each等等迭代器:扮演了容器与算法之间的胶合剂访函数:行为类型函数、可作为算法的某种策略适配器:一种用来修饰容器或者仿函数或者迭代器接口的东西空间配置器:负责空间的配制与管理 1.2 STL中的容器、算法、迭代器 容器:置物之所也
算法:问题之解法也
迭代器:容器与算法之间粘合剂
迭代器使用非常类似于指针,初学阶段我们可以先理解迭代器为指针
二、容器算法迭代器初始 2.1 vector存放数据 2.1.1 vector存放内置数据类型 容器:vector
算法:for_each
迭代器:vector<int>::iterator
vector的具体创建与尾插法以及遍历见下面代码
#include<iostream> using namespace std; #include<string> #include<vector> int main() { //创建了一个vector容器,类似数组 vector<int> v; //尾插数据 v.push_back(10); v.push_back(20); v.push_back(30); vector<int>::iterator itbegin = v.
上个电脑是2017年买的联想的拯救者,显卡rtx1060,但是感觉配置很高了,但是一直没有被充分利用,现在拿出来用发现已经过时了,在Ubuntu系统都会比较卡,所以我买了一个新笔记本,lenovo GEEKPro G5000,i7-13700H, 32G 内存,RTX 4060 Nvidia显卡。收到货迫不及待的安装了双系统,ubuntu22.04,但是不幸的事发生了,重启之后,WiFi图标没有,幸亏还可以插网线上网。
sudo lshw -C network
显示我的无线网卡是"network UNCLAIMED"的状态
无线网卡驱动安装的有问题需要重新安装,千辛万苦找到了这个,帮我解决了问题:
安装成Ubuntu以后发现不能上网,网络里没有wifi的选项。找了好多解决的办法,都是失败。求能其办法?感激。? - 知乎
GitHub - lwfinger/rtw89: Driver for Realtek 8852AE, an 802.11ax device
安装成功后,要重启
Kubernetes,简称k8s ,2014年发布,其核心特性脱胎于Google基础设施系统(Borg/Omega)的设计经验,并得益于Docker 项目和容器技术发展演进,使用声明式API定义容器化业务和容器间关系,为用户提供一个功能强大的容器编排工具;同时,按照某种规则,把容器调度到某个节点上运行起来并管理其生命周期;此外,k8s还提供了路由网关、水平扩展、监控、备份、灾难恢复等一系列运维能力。k8s的真正价值在于提供了一套基于容器构建分布式系统的基础依赖
本文主要介绍k8s持久卷,需要对k8s有一定的了解,知晓基本的k8s操作,并有可用k8s环境
k8s全局架构 k8s由 Master 和 Node 两种节点组成,分别对应着控制节点和计算节点。控制节点,包括三个独立组件,kube-apiserver负责 API 服务,kube-scheduler负责调度,kube-controller-manager负责容器编排,三个组件紧密协作,协同完成编排、管理、调度用户提交的作业。集群持久化数据,则由 kube-apiserver 处理后保存在 Etcd 中。计算节点,核心是一个叫作 kubelet 的组件,主要负责,调用CRI(Container Runtime Interface)远程调用接口同容器运行时(比如 Docker 项目)打交道,CRI定义了容器运行时的各项核心操作,比如:启动一个容器需要的所有参数
具体的容器运行时,通过 OCI 这个容器运行时规范同底层的 Linux 操作系统进行交互,即:把 CRI 请求翻译成对 Linux 操作系统的调用(操作 Linux Namespace 和 Cgroups 等)。此外,kubelet 还通过 gRPC 协议同Device Plugin 的插件进行交互。另外,kubelet调用网络插件CNI(Container Networking Interface)为容器配置网络,存储插件CSI(Container Storage Interface)为容器配置持久化存储
k8s持久化存储卷 Linux开源存储漫谈(8)容器及容器存储_arvey8888的博客-CSDN博客详细阐述了Docker Volume,Docker通过挂载本地目录进入容器的方式,解除存储卷与容器生命周期的紧耦合,完成容器的持久化。这一套方案有以下明显的不足,其一,不够灵活,需要与宿主机绑定;其二,不够通用,受限于文件系统;其三,难于运维管理。
开篇讲过,k8s使用声明式API定义容器化业务和容器间关系,不同于命令式,声明式API是面向对象的设计思想,业务被抽象成API对象,操作则被设计为对象的行为。k8s持久化存储相关API对象包括PV(Persistent Volume)、PVC(Persistent Volume Claim)、StorageClass
PV(Persistent Volume) PV描述的,是持久化存储数据卷,不同于临时卷持久化存储卷的生命周期不受Pod生命周期的限制,PV是独立的k8s API对象,有独立的生命周期管理。而PV的类型包括诸如FlexVolume、iSCSI、hostPath、NFS等等,比较低入门坎的如NFS,只用有一个网络连通的NFS server (搭建NFS服务器),并且,在每一台k8s的Node节点上安装NFS相关软件包(Ubuntu 22.04,运行apt install -y nfs-common),就可以开启NFS类型的PV的测试。如下所示:
root@k8s01:~/k8s# cat > nfs-pv.yml << EOF > apiVersion: v1 > kind: PersistentVolume > metadata: > name: nfs-pv > spec: > capacity: > storage: 10Gi > accessModes: > - ReadWriteMany > nfs: > server: 192.
今天看log4j的接口文档,看到有个接口定义前面加了static修饰符,不明白为什么要加。
log4j的ThreadContext.ContextStack接口定义如下:
于是查看了Java规范中的定义,发现嵌套接口其实隐含的含义就是static的,也就是说,成员接口或者局部接口就是static的。
在定义成员接口前面可以加static。当然,加这个static也是多余的,加与不加含义相同。
而在定义局部接口时,前面不能加static修饰符,加了会编译报错。
java规范中的描述如下:
https://docs.oracle.com/javase/specs/jls/se20/html/jls-9.html#jls-9.1
代码验证:
1)下面的两种代码写法都正确:
2)但如果在局部接口定义前面加static,就会报错:
1.锁的概念 之前我们学习过多线程,多线程当中如果想保证数据的准确性是如何实现的呢?没错,通过同步实现。同步就相当于是加锁。加了锁以后有什么好处呢?当一个线程真正在操作数据的时候,其他线程只能等待。当一个线程执行完毕后,释放锁。其他线程才能进行操作!
那么我们的MySQL数据库中的锁的功能也是类似的。在我们学习事务的时候,讲解过事务的隔离性,可能会出现脏读、不可重复读、幻读的问题,当时我们的解决方式是通过修改事务的隔离级别来控制,但是数据库的隔离级别呢我们并不推荐修改。所以,锁的作用也可以解决掉之前的问题!
锁机制 : 数据库为了保证数据的一致性,而使用各种共享的资源在被并发访问时变得有序所设计的一种规则。
举例,在电商网站购买商品时,商品表中只存有1个商品,而此时又有两个人同时购买,那么谁能买到就是一个关键的问题。
这里会用到事务进行一系列的操作:
先从商品表中取出物品的数据
然后插入订单
付款后,再插入付款表信息
更新商品表中商品的数量
以上过程中,使用锁可以对商品数量数据信息进行保护,实现隔离,即只允许第一位用户完成整套购买流程,而其他用户只能等待,这样就解决了并发中的矛盾问题。
在数据库中,数据是一种供许多用户共享访问的资源,如何保证数据并发访问的一致性、有效性,是所有数据库必须解决的一个问题,MySQL由于自身架构的特点,在不同的存储引擎中,都设计了面对特定场景的锁定机制,所以引擎的差别,导致锁机制也是有很大差别的。
2.锁的分类 按操作分类: 共享锁:也叫读锁。针对同一份数据,多个事务读取操作可以同时加锁而不互相影响 ,但是不能修改数据记录。
排他锁:也叫写锁。当前的操作没有完成前,会阻断其他操作的读取和写入
按粒度分类: 表级锁:操作时,会锁定整个表。开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低。偏向于MyISAM存储引擎!
行级锁:操作时,会锁定当前操作行。开销大,加锁慢;会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高。偏向于InnoDB存储引擎!
页级锁:锁的粒度、发生冲突的概率和加锁的开销介于表锁和行锁之间,会出现死锁,并发性能一般。
按使用方式分类: 悲观锁:每次查询数据时都认为别人会修改,很悲观,所以查询时加锁。
乐观锁:每次查询数据时都认为别人不会修改,很乐观,但是更新时会判断一下在此期间别人有没有去更新这个数据
不同存储引擎支持的锁
存储引擎表级锁行级锁页级锁MyISAM支持不支持不支持InnoDB支持支持不支持MEMORY支持不支持不支持BDB支持不支持支持 3.演示InnoDB锁 数据准-- 标准语法
SELECT语句 LOCK IN SHARE MODE;备
-- 创建db13数据库 CREATE DATABASE db13; -- 使用db13数据库 USE db13; -- 创建student表 CREATE TABLE student( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(10), age INT, score INT ); -- 添加数据 INSERT INTO student VALUES (NULL,'张三',23,99),(NULL,'李四',24,95), (NULL,'王五',25,98),(NULL,'赵六',26,97); 共享锁 -- 标准语法 SELECT语句 LOCK IN SHARE MODE; -- 窗口1 /* 共享锁:数据可以被多个事务查询,但是不能修改 */ -- 开启事务 START TRANSACTION; -- 查询id为1的数据记录。加入共享锁 SELECT * FROM student WHERE id=1 LOCK IN SHARE MODE; -- 查询分数为99分的数据记录。加入共享锁 SELECT * FROM student WHERE score=99 LOCK IN SHARE MODE; -- 提交事务 COMMIT; -- 窗口2 -- 开启事务 START TRANSACTION; -- 查询id为1的数据记录(普通查询,可以查询) SELECT * FROM student WHERE id=1; -- 查询id为1的数据记录,并加入共享锁(可以查询。共享锁和共享锁兼容) SELECT * FROM student WHERE id=1 LOCK IN SHARE MODE; -- 修改id为1的姓名为张三三(不能修改,会出现锁的情况。只有窗口1提交事务后,才能修改成功) UPDATE student SET NAME='张三三' WHERE id = 1; -- 修改id为2的姓名为李四四(修改成功,InnoDB引擎默认是行锁) UPDATE student SET NAME='李四四' WHERE id = 2; -- 修改id为3的姓名为王五五(注意:InnoDB引擎如果不采用带索引的列。则会提升为表锁) UPDATE student SET NAME='王五五' WHERE id = 3; -- 提交事务 COMMIT; 排他锁 -- 标准语法 SELECT语句 FOR UPDATE; -- 窗口1 /* 排他锁:加锁的数据,不能被其他事务加锁查询或修改 */ -- 开启事务 START TRANSACTION; -- 查询id为1的数据记录,并加入排他锁 SELECT * FROM student WHERE id=1 FOR UPDATE; -- 提交事务 COMMIT; -- 窗口2 -- 开启事务 START TRANSACTION; -- 查询id为1的数据记录(普通查询没问题) SELECT * FROM student WHERE id=1; -- 查询id为1的数据记录,并加入共享锁(不能查询。因为排他锁不能和其他锁共存) SELECT * FROM student WHERE id=1 LOCK IN SHARE MODE; -- 查询id为1的数据记录,并加入排他锁(不能查询。因为排他锁不能和其他锁共存) SELECT * FROM student WHERE id=1 FOR UPDATE; -- 修改id为1的姓名为张三(不能修改,会出现锁的情况。只有窗口1提交事务后,才能修改成功) UPDATE student SET NAME='张三' WHERE id=1; -- 提交事务 COMMIT; 注意:锁的兼容性 共享锁和共享锁 兼容
原理 在微服务架构中,不同的业务被划分成不同的 微服务,这些微服务通过相互调用进行通信,每个微服务运行在不同的进程中,这样就可能出现一种情况,消费者调用提供者,提供者服务出现网络延迟或者错误,消费者服务也会因提供服务无法相应出现延迟;当消费服务被更多的被调用,而服务消费者因为延迟的问题,tomcat中占用的线程资源不会释放,这样会导致更多的线程被消耗,直至tomcat资源耗尽,这会导致严重的问题——其他的服务不能正常提供服务(雪崩效应)
为了解决这类问题,Hystrix横空出世,他封装了每个依赖,使依赖相互隔离,当延迟情况发生时,他便会被限制在资源中,并包含回退逻辑,该逻辑决定在依赖发生任何类型故障时做出相应响应。
简单实践 拓扑图: 实验目的:当服务提供者不可用时,配置了Hystrix的客户端将会进行熔断保护,回调失败处理类 步骤: 前提:有fegin实现restful的声明式服务调用的项目基础
可参考:声明式服务调用客户端fegin_杜小白也想的美的博客-CSDN博客
以下都是对服务消费者的配置
1、在服务消费者中添加hystrix-client依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.2.6.RELEASE</version> </dependency> 2、将服务消费者中yml文件添加熔断配置——开启熔断配置
server: port: 8764 #配置端口号 spring: application: name: hystrix-client #指定用户名 feign: #开启熔断配置 circuitbreaker: enabled: true eureka: client: service-url: defaultZone: http://localhost:7000/eureka 3、在启动类中中添加@EnableHystrix
4、在service包中新建失败处理逻辑类TestSerivceImpl,并实现@FeginClient注解接口
@Component public class TestServiceImpl implements TestService{ @Override @RequestMapping("/hi") public String hi() { return "bad request"; } @Override public String hi(String id) { return String.format("bad request is :%s",id); } } 5、将service包的TestService类中@FeginClient注解中增加fallback属性配置
版本背景
flink:1.14.3
flinkcdc 2.3.0 /2.2.0
现象:
java.lang.NullPointerException: Name is null at java.lang.Enum.valueOf(Enum.java:236) ~[?:1.8.0_312] at com.ververica.cdc.connectors.mysql.source.offset.BinlogOffsetKind.valueOf(BinlogOffsetKind.java:26) ~[flink-connector-mysql-cdc-2.3.0.1.jar:2.3.0] at com.ververica.cdc.connectors.mysql.source.offset.BinlogOffset.getOffsetKind(BinlogOffset.java:136) ~[flink-connector-mysql-cdc-2.3.0.1.jar:2.3.0] at com.ververica.cdc.connectors.mysql.source.utils.SerializerUtils.readBinlogPosition(SerializerUtils.java:73) ~[flink-connector-mysql-cdc-2.3.0.1.jar:2.3.0] at com.ververica.cdc.connectors.mysql.source.utils.SerializerUtils.readBinlogPosition(SerializerUtils.java:59) ~[flink-connector-mysql-cdc-2.3.0.1.jar:2.3.0] at com.ververica.cdc.connectors.mysql.source.split.MySqlSplitSerializer.deserializeSplit(MySqlSplitSerializer.java:153) ~[flink-connector-mysql-cdc-2.3.0.1.jar:2.3.0] at com.ververica.cdc.connectors.mysql.source.split.MySqlSplitSerializer.deserialize(MySqlSplitSerializer.java:122) ~[flink-connector-mysql-cdc-2.3.0.1.jar:2.3.0] at com.ververica.cdc.connectors.mysql.source.split.MySqlSplitSerializer.deserialize(MySqlSplitSerializer.java:46) ~[flink-connector-mysql-cdc-2.3.0.1.jar:2.3.0] at org.apache.flink.core.io.SimpleVersionedSerialization.readVersionAndDeSerialize(SimpleVersionedSerialization.java:165) ~[flink-core-1.13.5.jar:1.13.5] at org.apache.flink.streaming.api.operators.util.SimpleVersionedListState$DeserializingIterator.next(SimpleVersionedListState.java:138) ~[flink-streaming-java_2.11-1.13.5.jar:1.13.5] at java.util.Iterator.forEachRemaining(Iterator.java:116) ~[?:1.8.0_312] at org.apache.flink.util.CollectionUtil.iterableToList(CollectionUtil.java:95) ~[flink-core-1.13.5.jar:1.13.5] at org.apache.flink.streaming.api.operators.SourceOperator.open(SourceOperator.java:251) ~[flink-streaming-java_2.11-1.13.5.jar:1.13.5] at org.apache.flink.streaming.runtime.tasks.OperatorChain.initializeStateAndOpenOperators(OperatorChain.java:442) ~[flink-streaming-java_2.11-1.13.5.jar:1.13.5] at org.apache.flink.streaming.runtime.tasks.StreamTask.restoreGates(StreamTask.java:585) ~[flink-streaming-java_2.11-1.13.5.jar:1.13.5] at org.apache.flink.streaming.runtime.tasks.StreamTaskActionExecutor$1.call(StreamTaskActionExecutor.java:55) ~[flink-streaming-java_2.11-1.13.5.jar:1.13.5] at org.apache.flink.streaming.runtime.tasks.StreamTask.executeRestore(StreamTask.java:565) ~[flink-streaming-java_2.11-1.13.5.jar:1.13.5] at org.apache.flink.streaming.runtime.tasks.StreamTask.runWithCleanUpOnFail(StreamTask.java:650) ~[flink-streaming-java_2.11-1.13.5.jar:1.13.5] at org.apache.flink.streaming.runtime.tasks.StreamTask.restore(StreamTask.java:540) ~[flink-streaming-java_2.11-1.13.5.jar:1.13.5] at org.apache.flink.runtime.taskmanager.Task.doRun(Task.java:759) ~[flink-runtime_2.
protobuf 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。
在网络传输方面,相比传统的json,有着更快、更小,且加密性好的特点。
在实际应用中,万方数据库官网发送的请求,就用到了这。
一般网站,比如cnki,我们检索内容,只需要拼接一个http请求,便能获取到数据。
但是,万方数据库,却是这样的,看不到请求body都是一些乱码一样的数据,连返回的数据也是。
这正是由于其使用了protobuf序列化,我们通过它发送请求头中也可以看到有 “application/grpc-web+proto” 这样的字样。
其大致流程:实例化一个proto格式对象(长得类似c的结构体),将检索式塞到该对象属性中,对其进行序列化为二进制,发送请求,对接收到的数据进行反序列化。
因此我们重点就在于拿到这个proto对象的结构。
有关万方protobuf发送请求的大部分内容,可以参考大佬的文章: https://blog.csdn.net/qq_35491275/article/details/111721639
这里就只对拿到数据,将其反序列化的大致步骤,进行讲解。
本人是通过python发送请求,根据上面参考文章说的,要将数据反序列化,便需要获取到proto格式,比如有哪些变量和变量类型。
而这都需要通过在浏览器F12,打断点,一步步调试js函数才能获得。本人由于对js不了解,也不太会调试js,所以也是变相换个方法去实现。
F12------》Source------》XHR/fetch Breakpoints,将接口请求地址复制进去,这样调试的时候就会自动在相关位置断点了。
在Call Stack调用栈中,看到了SearchService字样,点击进去。
后面通过打断点,一步步调试,便能在一些方法名中找到需要的变量和类型。
本人这里就不做调试,我说说自己当时的思路。
因为整个检索流程,就主要经过了两份js,所以我直接ctrl+F,搜索SearchService字样,发现都在api.1f9fdaa9.js这一份当中。
然后我再ctrl+F,搜索 “toObject = function(e, t) {” 字样,一般每个message结构对应的变量名和序号就在这个函数中,变量类型则一般在 “serializeBinaryToWriter = function(e, t) {” 函数中,大概有90多个匹配的。这一步不清楚可以看上面参考博客,便知道为什么这样找这些message结构。将他们列出来,写入一份.proto文件中。
这里变量名好像可以自己命名,主要是序号需要保持一致,但为了解析数据方便,这里变量名也尽量保持了和js中的一致,最终得到右边的proto文件。
然后通过protoc.exe编译器,输入命令 protoc proto文件名 --python_out=./ 得到相关py文件。
新建一个python工程,将刚刚生成的py文件丢入工程中。便可成功反序列化出数据。
这里请求时使用了blackboxprotobuf模块,可以减少去获取请求的proto结构这一步骤。具体一些点的可以参考他人博客。
参考代码:main.py
# This is a sample Python script. # Press Shift+F10 to execute it or replace it with your code. # Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
前言 我提到的这些部分,是我在自学C与C++中遇到的比较困难的点。因为初学者的编程,不太容易使用到这些点,所以很容易造成遗忘,并且自己写很容易出错。
最近在看标准C库的源码的时候遇到了这样的困惑,就是关于函数指针,或者说,把一个函数作为另一个函数的参数的这种行为。在读原码的函数原型的时候我发现我尽然读不懂这里的语法是什么。
所以特此写一篇文章来记录一下我认为比较难的知识点。
因为我觉得数组参数,或者说多维数组参数这个点可以作为函数参数,函数指针的铺垫知识,因为性质比较相似,又比较简单。所以就一起跟着讲了。
数组形参 数组形参指的是在函数中使用数组作为形参的情况。在C++等编程语言中,函数可以接受一个或多个数组作为参数,就像接受其他类型的参数一样。
但是呢,数组作为形参,又和一些其他的形参有很大程度的不同。这是由数组的两个性质导致的。所以我们要从数组的两个性质开始讲起。
数组是不允许拷贝的:这意味着我们不能将一个数组直接赋值给另一个数组,也不能将一个数组直接传递给函数。所以,如果我们试图将数组作为函数的参数,实际上我们在传递的是数组的引用或者说是指向数组第一个元素的指针。
使用数组时,通常会将其转换成指针:当数组被用作函数的参数时,它会被自动转换为一个指向数组第一个元素的指针。这就是为什么函数内部看到的是一个指针,而不是实际的数组。
这两个特性解释了为什么我们不能直接将数组作为参数传递给函数,而需要以指针的形式来传递。
现在让我们来看一下数组形参的三种主要写法,或者称为表示方式:
1、类型名后跟对应类型的空方括号:
void myFunction(int arr[]) { // ... } 2、类型名后跟对应类型的非空方括号:
注意这种写法其实是一种语法糖,编译器会自动忽略方括号中的数字,仍然将它视作指针。 void myFunction(int arr[10]) { // ... } 3、指针形式:
void myFunction(int* arr) { // ... } 以上三种形式在语义上是相同的,都表示一个指向整型的指针。但是,仅仅通过这个指针,函数是无法知道数组的大小的。因此,通常的做法是将数组的大小作为另一个参数传递给函数。
这就是为什么你通常会看到如下的函数定义:
void myFunction(int arr[], int size) { // ... } 所以,在这三种情况下,我其实最推崇的就是类型名后跟对应类型的空方括号这种定义方式了,因为简单直接,容易阅读,也不容易出错。
再深入了解一下多维数组参数 在C++中,你可以将多维数组作为函数的参数。但是你必须为除第一维度外的其他所有维度提供大小。原因是编译器需要这些信息来正确地计算内存中的元素位置。
以下是将二维数组作为函数参数的几种方式:
直接指定维度大小:
void myFunction(int arr[10][10]) { // ... } 在这个例子中,我们将一个10x10的二维整数数组作为参数传递给myFunction函数。 使用空的第一维度:
void myFunction(int arr[][10]) { // ... } 在这个例子中,我们不指定第一维度的大小。函数接受任意大小的第一维度,但是第二维度必须是10。 使用指针表示法:
框架:Springboot
数据库:MySQL
下载链接:
https://download.csdn.net/download/yw1990128/87851197
B站运行链接:
基于Springboot的图书商城管理系统_哔哩哔哩_bilibili
引言 项目开发背景 Internet最早在美国出现,如今,世界各国纷纷加入到这个行列,便Internet成 为全球化的网际网络。随着用户的不断增加,其规模迅速扩大,它的领域也走向多元 化。除了原先的科学技术和教育外,Internet己进入了文化、经济、政治、新闻.体 育、娱乐、商业和服务业。可以预见,Internet将为我们构筑未来崭新的生活方式。
另外电子商务发展在世界范围内都是刚刚开始,其发展速度极为迅速,传统的商 业模式正不断地被新的商业模式所代替,无论什么模式都不具有固定性和成熟性。对 于任何国家来说,都有一个探索与创新的问题,这也为我国加快和跨越发展提供了难 得的机遇。我们要大胆进行创新,积极探索符合实际的商业模式,壮大企业的市场竞 争能力,以适应全球化的激烈竞争。
网上书店就是Internet和电子商务发展的产物,近几年在我国发展迅猛,如同一 些书店纷纷在各地开设分店以拉近书店与顾客间距离-样。随着科学技术得分速发 展,Internet这个昔日只被少数科学家接触和使用的科研工具已经成了普通百姓都可 以触及的大众型媒体传播手段。随着现金全民素质和科学技术水平的不断提高,知识 更新的越来越快。人们随时都会有被淘汰的危机,为了不让社会淘汰,做到与时俱进 就必须多读书不断的学习,21世纪是网络的时代、信息的时代,时间是非常宝贵的, 人们由于种种原因没有时间到书店去,也不知道哪家书店有自己需要的书籍,同时那 些传统书店的经营者又没什么好的方法让人们知道我这就有顾客需要的书籍,这种买 卖双方之间信息交流上的阻碍成为“网上书店”网站发展的原动力。
网上书店网站的建立可以跟好的解决这方面的问题,我们向广大用户推出的是一 种全新的网上信息服务,旨在书店与消费者之间架起了一座高速、便捷的网上信息桥 梁,我们的目的是节省您的吋间、方便您的购书,使您永远走在吋代的前沿。
需求分析 系统开发目的 本项目主要目的是开发一个功能相对完善、操作方便高效的网上书城系统来解决 目前书店事务落后、工作效率较低等问题。
功能需求分析 通过对己有网上书城系统事务的分析,得出本系统的功能需求有:
后端:
(1) 登录注册模块
管理员注册、登录后台系统。
(2) 书籍列表管理模块
管理员对书籍列表进行添加、修改、删除和查询操作。
(3) 书籍分类管理模块
管理员对书籍分类进行添加、修改、删除和査询操作。
(4) 订单管理模块
管理员对订单进行添加、修改、删除和查询操作
(5) 用户管理模块
管理员对用户进行添加、修改、删除和查询操作。
(6) 上架书籍模块
管理员对书籍进行上架。
前端:
(1)购物车模块
实现用户对购买图书的暫时储存,用户可以结账,清空购物车,继续购书和修改购 买数量。
整体功能框架如下:
用户登录功能 系统的首页登录界而如图4-1所示。
图4-1首页登录页面
系统管理界面如图4-2所示。
功能:输入操作员姓名和密码,系统验证,若成功,进入系统的首页;否则,提示
错误信息。当用户输入用姓名后,点击提交后,会访问数据库,查询数据库中是否有该用户,如果存在改用户,则实现用户登录。
<body>
<div class="layui-container">
<div class="
在 Maven 中,任何一个依赖、插件或者项目构建的输出,都可以称为构件。
Maven 在某个统一的位置存储所有项目的构件,这个统一的位置,我们就称之为仓库。换言之,仓库就是存放依赖和插件的地方。
任何的构件都有唯一的坐标,该坐标定义了构件在仓库中的唯一存储路径。当 Maven 项目需要某些构件时,只要其 POM 文件中声明了这些构件的坐标,Maven 就会根据这些坐标找自动到仓库中找到并使用它们。
项目构建完成生成的构件,也可以安装或者部署到仓库中,供其他项目使用。
仓库的分类 Maven 仓库可以分为 2 个大类:
本地仓库远程仓库 当 Maven 根据坐标寻找构件时,它会首先查看本地仓库,若本地仓库存在此构件,则直接使用;若本地仓库不存在此构件,Maven 就会去远程仓库查找,若发现所需的构件后,则下载到本地仓库使用。如果本地仓库和远程仓库都没有所需的构件,则 Maven 就会报错。
远程仓库还可以分为 3 个小类:中央仓库、私服、其他公共仓库。
中央仓库是由 Maven 社区提供的一种特殊的远程仓库,它包含了绝大多数流行的开源构件。在默认情况下,当本地仓库没有 Maven 所需的构件时,会首先尝试从中央仓库下载。私服是一种特殊的远程仓库,它通常设立在局域网内,用来代理所有外部的远程仓库。它的好处是可以节省带宽,比外部的远程仓库更加稳定。 除了中央仓库和私服外,还有很多其他公共仓库,例如 JBoss Maven 库,Java.net Maven 库等等。Maven 仓库的分类如下图: 本地仓库 Maven 本地仓库实际上就是本地计算机上的一个目录(文件夹),它会在第一次执行 Maven 命令时被创建。
Maven 本地仓库可以储存本地所有项目所需的构件。当 Maven 项目第一次进行构建时,会自动从远程仓库搜索依赖项,并将其下载到本地仓库中。当项目再进行构建时,会直接从本地仓库搜索依赖项并引用,而不会再次向远程仓库获取。
Maven 本地仓库默认地址为 C:\%USER_HOME%\.m2\repository ,但出于某些原因(例如 C 盘空间不够),我们通常会重新自定义本地仓库的位置。这时需要修改 %MAVEN_HOME%\conf 目录下的 settings.xml 文件,通过 localRepository 元素定义另一个本地仓库地址,例如:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <localRepository>D:/myRepository/repository</localRepository> </settings> 构件只有储存在本地仓库中,才能被其他的 Maven 项目使用。构件想要进入本地仓库,除了从远程仓库下载到本地仓库外,还可以使用命令 mvn install 将本地项目的输出构件安装到本地仓库中。
一、问题背景
雪花算法生成的id经过浏览器后id后几位全部变成"0000",导致列表展示后进入详情无法查询详情。
经dubbo服务调用,返回正常的id,经网关后查询日志也返回正常id,经Postmain调用也返回正常的id,经页面点击查询后查看列表信息,经谷歌浏览器开发工具Network查看,返回数据id的结尾已经变成"0000";
三、问题原因
Java中Long的取值范围为-9223372036854775808到9223372036854775807(即-2^64“ 到”2^64-1)
而JavaScript中的Number取值范围为-9007199254740992 到9007199254740991 (即-2^53 到2^53-1)
四、解决方案
在传的时候把Long转换成String类型
使用spring的Json解析器时使用@JsonSerialize(using = ToStringSerializer.class) 注解
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
五、 延伸探究
为什么avaScript中的Number取值范围是-2^53 到2^53-1?
IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。
Number类型使用的便是其中的双精确度(64位)数据结构如下
Number类型的51-62位为指数位,63位为符号位,所以取值范围是-2^53 到2^53-1
复制来对 Number类型 相对官方的解释.
ECMAScript 中最有意思的数据类型或许就是 Number 了。Number 类型使用IEEE 754 格式表示整数和浮点值(在某些语言中也叫双精度值)。 ---红宝书
在 JavaScript 中, Number 是一种 定义为 64位双精度浮点型(double-precision 64-bit floating point format) (IEEE 754)的数字数据类型。 ---MDN
Number 类型使用IEEE 754 格式。
IEEE 754 格式
IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。
Number类型使用的便是其中的双精确度(64位)。
这张图就把结构说清了。
举个例子
十进制数值:10.25转化为二进制 => 1010.
文章目录 原理方式证书 原理 HTTPS = HTTP + TLS/SSL(数据的加密解密层)
HTTP是应用层的协议,当应用层向下访问的时候并不是直接访问到socket层,而是先通过TLS/SSL加密解密层后再进行后续工作。此时得到的协议就是HTTPS。
举个例子:如何防止一个文本中的内容被篡改?以及说识别到是否被篡改?
加密理论:
数据传输过程是以加密以后的形式传输的,即数据+数字签名。
一方接收到数据后:
方式 加密方式有两种:
对称加密
非对称加密
对称加密 密钥只有一个,用X表示。发送的数据用X加密,收到的时候也要用X来解密。
对于对称加密来说,密钥协商的方式是不合适的,因为第一次传输密钥的时候就可能会被知道密钥是什么。
非对称加密 有一对密钥:公钥和私钥。
用公钥加密,但是要用私钥解密;反过来用私钥加密,要用公钥解密。常见的非对称加密有RSA。
一般而言,公钥是全世界公开的,私钥是自己私有保存的。
方式一 server端先把公钥给到client端,然后client端利用这个公钥进行数据加密,再将其传输给server端。这种方式在公钥加密的数据被拦截后,依旧无法破解,因为只有server端拥有解密的私钥。
目前为止数据是安全的,但是当server端将数据发送回client端的时候,如果用私钥加密,此时的所有人都可以对其进行解密,这就显得徒劳无功了。
所以一对非对称公钥私钥是无法完成安全传输的。
方式二 既然一对不行就用两对,分别在通信前交换双方的公钥进行加密,在通信时也能分别用自己的私钥解密。
这听起来很好,但是也有两个弊端:首先这种方式也有被窃取数据的风险,其次非对称加密算法是很复杂的,这种方式会很消耗时间,效率低下。
因此我们都是采用对称+非对称相结合的方式。
方式三 协商阶段—非对称加密
数据传输阶段—对称加密
在通信前,server端将自己的公钥S给到client端,然后client端用这个公钥S给自己的私钥-C进行加密,传输给server端,这是非对称方式的通信。
此时双方就都知道了需要进行通信的密钥-C,那么就可以通过-C,以对称的方式进行通信。
这个过程是安全的,因为私钥-S仅在server端,所以不用担心第一次传输公钥S的时候会被破坏。
但是这是没有刻意攻击的前提下,如果有人刻意攻击,是可以将第一次传输公钥给拦截然后包装成它自己的,进而获取待会client发送来的私钥。
这里的本质问题是,client端不知道此时的公钥已经被做了手脚了。此时的解决方法就是证书。
证书 CA证书机构是一个服务商,经过权威认证,该机构就是合法的。
该机构拥有自己的公钥和私钥。
申请证书的过程:申请证书需要提供企业的基本信息、域名、公钥。
原理 CA机构利用自己的公钥将数据进行加密,利用私钥-A形成该机构的数字签名,此时只有公钥A才能解开该数字签名。
在上述提到的过程中,并不是直接将公钥发送到client,而是发送证书:
所以证书的构成就是:数据+该机构的数字签名。
这里几种情况:
攻击者想篡改整个证书攻击者想篡改数据但不改数字签名攻击者想篡改数字签名但不改数据 首先篡改整个证书是可行的,因为改CA机构的A公钥大家都有,但是这样的话就无法重新形成数字签名了,因为这个数字签名是CA机构自己用-A私钥生成的。也就是说,只有CA机构能够重新形成数字签名。那么此时的攻击者即使篡改了整个证书,也是无法获得client端的认可的。
其次最后两种情况都是不可能的,因为一旦数字签名和数据内容不一样,散列/解密以后一对比就会自动被识别出来。
这里有个前提,client端必须要知道CA机构的公钥,这基本上是内置的。
还有一个问题就是如果攻击者也是一个合法的机构,它将整个报文都给修改了,而使用自己的报文,该怎么办? 这其实也是不可能的,因为证书里面已经包含了目标域名,那么client端识别出来以后自然也就弃用了。
这也是有证书和无证书的很大差别,如果没有证书的话,client端并不会知道自己获得的公钥是否是自己想要的,但是有了证书以后就能通过域名知道是否合法。
下面是有证书的情况下的加密过程(内容来自博主:牛客网):
客户端发起 HTTPS 请求:当客户端(如 Web 浏览器)向服务器发起 HTTPS 请求时,会先向服务器请求其公钥。
服务器发送公钥:服务器收到请求后,将发送一个包含其公钥和数字证书的响应给客户端。数字证书由可信的第三方证书颁发机构(CA)颁发,用于证明服务器的身份。
客户端验证证书:客户端收到响应后,首先会验证数字证书的有效性。客户端会检查证书的颁发者是否是可信的 CA,并验证证书是否过期。如果证书有效,客户端会信任服务器的公钥。
生成会话密钥:客户端生成一个随机的对称密钥,称为会话密钥。这个密钥将用于后续的数据传输过程中的对称加密和解密。
加密会话密钥:客户端使用服务器提供的公钥对会话密钥进行非对称加密。由于只有服务器持有与公钥匹配的私钥,因此只有服务器能够解密这个加密后的会话密钥。
本文仅用以参考记录与分享,纯个人经验,pycharm版本是官网下载的社区版新版本,挺好用的,因为不习惯新版本的UI,没有使用新版本的UI截图,参考本文时可以关闭新版本UI体验。 一、安装pyqt5相关库 1、使用pycharm安装
这个方式不知道是不是新版才能用,之前好像需要镜像源。刚使用新版,原本旧版设置镜像源的地方已经没有了,可以直接下载相关库
Pycharm->File->setting->project
如图所示步骤装好PyQt5和PyQt5-tool两个库。
2、使用终端安装
如上图所示,点击终端,进入项目目录,使用pip install pyqt5和pip install pyqt5-tool,上图已经安装过pyqt5了,如果出现标记三的提示直接执行 python.exe -m pip install --upgrade pip命令升级pip。
二、配置qt designer和PyUIC 1、配置qt designer
File->setting->Tools 第一步,点击External Tools
第二步,点击+号会弹出一个编辑框
第三步,给扩展的工具命名,随你喜欢
第四步,选择designer.exe前面pyqt5 的库已经包含了,库再python的文件夹里面,注意是python不是pycharm!!!我附上我的文件路径
第五步,工作文件夹写 $FileDir$ 就好
然后一路Ok和Apply就行。
接下来使用qt designer,上述配置好后可以在下面找到qt designer,这里的名字是你之前命名的,点击就可以打开使用qt 画UI了。
2、配置pyuic
pyuic是用来将你使用Qt designer画的UI的.ui文件转成.py文件用的。下面配置扩展工具pyuic。步骤同配置qt designer一样。下面直接到需要说明的点。
第一步,是选择python.exe。在你的python安装路径就能找到
第二步,作用是,将qt的.ui文件转成.py文件时的自动命名,完整为
-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$_ui.py
后面的_ui为我的前辈传给我的经验,方便python项目管理和区分。
第三步,直接填$FileDir$
然后ok和apply就行
3、将一个qt的.ui文件转成.py文件
第一步,这里已经生产了一个空白的Wgt保存在项目里面了
第二步,右键.ui文件,选择External Tools
第三步,点击PyUIC,点击后就会生成 序号4 这个.py文件。这个文件python就可以调用了,不过通常会继承这个.py来包一层,尽量不破坏原始的ui。在外面包的那一层可以随意的用python语言添加yang'ya
路径栏中输入wt即可。
不过和cmd不同,wt打开后默认目录不是刚才的文件夹,而是用户目录。
可以通过修改下面的配置,实现cmd类似的效果,即打开wt后默认就是当前目录。
左下角打开json文件
添加启动目录
"startingDirectory": "." 如果你使用的不是powershell,list中每一个元素都可以加一下这个配置。
再次尝试,成功了。
1.生命周期
(1)beforeCreate()
这是我们遇到的第一个生命周期函数,表示实例完全被创建出来之前,会执行它
注意: 在 beforeCreate 生命周期函数执行的时候,data 和 methods 中的 数据都还没有没初始化
(2)created() 这是第二个生命周期函数
在 created 中,data 和 methods 都已经被初始化好了!
如果要调用 methods 中的方法,或者操作 data 中的数据,最早,只能在 created 中操作
(3)beforeMount()
这是遇到的第3个生命周期函数,表示 模板已经在内存中编辑完成了,但是尚未把 模板渲染到 页面中
在 beforeMount 执行的时候,页面中的元素,还没有被真正替换过来,只是之前写的一些模板字符串
(4)mounted()
这是遇到的第4个生命周期函数,表示,内存中的模板,已经真实的挂载到了页面中,用户已经可以看到渲染好的页面了
mounted 是 实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,此时,如果没有其它操作的话,这个实例,就静静的 躺在我们的内存中,一动不动
(5)beforeUpdate()
这时候,表示 我们的界面还没有被更新【数据被更新了吗? 数据肯定被更新了
当执行 beforeUpdate 的时候,页面中的显示的数据,还是旧的,此时 data 数据是最新的,页面尚未和 最新的数据保持同步
(6)updated()
updated 事件执行的时候,页面和 data 数据已经保持同步了,都是最新的
(7)beforedestroyed()
退出操作之前
(8)destroyed()
关闭缓存
<script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { msg: 'ok' }, methods: { show() { console.
select * from girls where age between 18 and 20 and boyfriend is null order by cup desc
文件上传报错如图: 表单上传excel文件,报错为write Javabean error
原因与解决: 接口接收到的MultipartFile对象不可使用fastjson的toJsonString方法打印日志!!!!!
报错位置:
log.info(“分账规则模板新增入参 {}”, JSONObject.toJSONString(file));
原因:
1、torch和torchvision版本不同,比如torch是支持cuda的,但是torchvision不支持cuda
2、torch和cuda版本不对
解决方式:
1、卸载torch或者torchvision,重新安装 相同版本的torch和torchvision
2、卸载torchvision或者cuda,并分别重新安装,使版本匹配
我查看了自己pytorch环境下了的torch和torchvision的两个版本,发现这个两个依赖的版本不一样,对于torch来说,它是支持CUDA版本的,在下面的图片中也可以看出;而torchvision并不支持CUDA所以需要重新安装一下,使他们的版本对应。
重新安装torchvision, 点击安装pytorh或torchvision包
下载对应的包放在对应的项目的目录下,进入该项目的环境中进行pip 安装
pip install torchvision-0.11.1+cu113-cp36-cp36m-win_amd64.whl
需求: 只需要展示省市区名字就行了
难点: uview没有专门的省市区选择器,而且他的选择器也做的不太好,不支持tree树,所以要自己准备好省市区json数据,还需要处理数据变成多维数组
这里我借鉴了csdn众多人的示例代码,封装的独立组件
组件代码: <template> <view class="addressPicker"> <u-picker :show="shows" ref="uPicker" :defaultIndex="defaultIndex" :columns="columns" keyName="name" @change="changeHandler" @cancel="cancel" @confirm="confirm"></u-picker> </view> </template> <script> import address from '@/utils/address.json' export default { name: "addressPicker", props: { show: { type: Boolean, default: false, }, defaultIndex: { type: Array, default: () => { return [0, 0, 0] }, } }, watch: { show: { handler(newVal) { this.shows = newVal; }, // deep: true, //true 深度监听 immediate: true, //声明后立刻调用 } }, data() { return { shows: false, columns: [], //省份数据显示,三级联动需要三维数组,展示初始数据 columnData: [], //市数据 columnDatas: [], //区地址 }; }, created() { this.
目录
医疗器械安全要求检查GB9706.1-2020标准注册检报告_安规性能试验
GB9706的内容变化在此不多做赘述,新标实施在即,那么有源医疗器械企业该如何应对呢?
1) 还未完成检测的医疗器械产品
2) 已获得检测报告的医疗器械产品但还未注册受理
3) 已完成注册的医疗器械产品
GB 9706.1-2020 和GB 9706.1-2007标准主要差异解析
GB 9706.1-2020标准的主要变化
重点变化解析
新版GB9706.1-2020风险管理要求对企业质量体系的影响
1.风险管理相关法规要求
2.企业风险管理现状
3.GB9706.1-2020标准[8] 要求对企业质量体系中风险管理过程的影响
3.1 风险管理计划及风险可接受准则
3.2 风险分析与风险评价
3.3 替代风险控制措施或试验方法
3.4 基本性能的识别
3.5 与患者接触部分的识别
3.6 单一故障试验识别
3.7 高完善性元器件使用
3.8 可用性工程
3.9 可编程医用电气系统
4.小结
医疗器械安全要求检查GB9706.1-2020标准注册检报告_安规性能试验 继2020年发布新版GB9706.1后,中国陆续发布了55个9706系列补充标准,这些标准大部分的实施时间为2023年5月1号,有源医疗器械企业应于2023年5月1日前完成相应医疗器械产品的变更和验证,符合新版9706系列标准的要求。
比较新版GB9706.1,2020版与2007版从结构到内容上都有了较大的改变。比较明显的变化是引入了风险管理的概念,在医疗器械检测时需要提供风险管理文件验证标准的符合性。在进行风险管理时应识别9706系列标准已识别的风险源以及其他未识别的风险源,这意味着在进行风险评价时,应逐一核对9706标准的条款,考虑9706标准中的危险源及其控制方法和风险接受标准。
新版9706还要求识别基本性能,基本性能的识别过程应体现在风险管理当中。对于未识别基本性能的,则在检测过程中会将产品的所有性能都视为基本性能,这会提高产品EMC检测通过的难度。
还有另一个比较直观改变的是需要提供可用性工程文档。可用性的研究在既往的医疗器械研发中要求较少,故而企业在这方面的认知和考虑都较不充分,这也成为企业满足新版9706的一大难点。
GB9706的内容变化在此不多做赘述,新标实施在即,那么有源医疗器械企业该如何应对呢? 1) 还未完成检测的医疗器械产品 由于距离新标实施的时间还剩7个月左右的时间,在这期间,还未送检的企业很难快速完成注册资料准备完成注册申报受理,故而建议还未完成检测的产品直接按照新版GB9706的要求进行检测。
2) 已获得检测报告的医疗器械产品但还未注册受理 对于已经获取检测报告,但还未注册受理的医疗器械产品,如果能在2023年5月1号前完成受理的话可以直接采用旧版GB9706的报告。但是如果不能保证在2023年5月1号前完成受理的话,建议重新按照新版9706的要求进行检测。
3) 已完成注册的医疗器械产品 已经完成注册的医疗器械产品,产品技术要求引用强制性标准的形式为“直接引用强制性标准条款具体内容”、“标准编号”或者“标准编号+年代号”。强制性标准更新,标准编号和/或年代号发生变化,涉及产品技术要求引用的强制性标准条款内容未发生变化的可以不申请变更注册。
鉴于GB9706的内容具有重大变化,因此有源医疗器械企业应申请变更注册。部分省局可以接受在延续时受理强制性标准的变更,具体操作细节可以与当地省局沟通确认。如无特殊情况的,都应该申请变更注册。有源医疗器械产品应在2023年5月1号后满足新版GB9706系列标准的要求,故而至少在23年5月1号前应完成新版GB9706的检测,确保产品能够满足新标要求,并尽快完成变更注册。
GB 9706.1-2020 和GB 9706.1-2007标准主要差异解析 GB 9706.1-2020标准的主要变化 第一 引入了基本性能的概念和风险管理的内容。
第二 适用范围增加了行动不方便的人使用的设备和非医疗监护使用的设备。
第三 对患者和操作者采取不同的防护方式。
第四 引入了接触电流和总患者漏电流的概念。
目录
有源医疗器械电磁兼容的测试标准、测试项目以及测试方法
一、什么是电磁兼容
1.1电磁兼容概念
1.2电磁兼容三要素
1.3为什么要做电磁兼容
1.4电磁兼容测试项目
二、电磁兼容标准
2.1基础标准
2.2通用标准
2.3产品族标准
2.4产品专用标准
2.5试验介绍及注意事项
医疗设备电磁兼容主要依据标准
家用电器电磁兼容主要依据标准
通信设备电磁兼容主要依据标准
三、辐射发射(辐射骚扰)试验
3.1定义
3.2试验目的
3.3试验设备及必备条件
3.4试验方法及配置
3.5举例
四、何为分贝
4.1众人眼中的分贝
4.2分贝的来龙去脉
4.3如何定义分贝?
总结一下:
4.4 dB在EMC测试中的应用
4.5 dB的计算公式
关于-3dB
(2)dBmV、dBµV与dBm的换算
举个例子巩固一下:
五、传导发射(传导骚扰)试验
5.1定义
5.2试验目的
5.3试验设备及必备条件
5.4试验方法及配置
5.5举例
六、谐波电流测试
6.1什么是谐波电流
6.2谐波电流试验目的
6.3试验设备及必备条件
6.4试验方法及配置
6.5举例
七、射频电磁场辐射抗扰度试验
7.1什么是辐射抗扰度
7.2辐射抗扰度试验目的
7.3试验设备及必备条件
7.4试验方法及配置
7.5试验程序及举例
EMC-检验设备及检验方法
有源医疗器械电磁兼容的测试标准、测试项目以及测试方法 有源医疗器械电磁兼容的测试标准、测试项目以及测试方法_检测资讯_嘉峪检测网
我们都知道对于有源医疗器械来说,其注册检验通用的无非就是四大项:安规、电磁兼容、环境试验以及产品自身的性能测试,若适用的话还有产品专标的测试以及报警的测试。本篇文章从EMC概念、EMC标准、EMC测试的意义、EMC测试项目以及具体测试方法来介绍一下EMC相关知识,对有源医疗器械研发、测试、注册、法规、生产、体系等相关人员应该有所帮助。
一、什么是电磁兼容 1.1电磁兼容概念 电磁兼容EMC(Electro Magnetic Compatibility):是一门新兴的综合性学科,是电子、电气设备或系统的重要技术性能。国家标准GB/T 4365-2003《电磁兼容术语》对电磁兼容所下的定义为“设备或系统在其电磁环境中能正常工作且不对该环境中任何事物构成不能承受的电磁骚扰的能力”,即电子、电气设备或系统在同一电磁环境中能良好执行各自功能的这样一个共存状态,简单点说,就是各种设备都能正常工作又互不干扰,达到“兼容”状态。要注意电磁兼容所要求的两个基本方面:在共同的电磁环境中,不受干扰且不干扰其他设备。
那么明白了以上呢我们知道,EMC包括两个方面的要求:一方面是指电子、电气设备或系统在正常运行过程中不会影响处在同一环境下的其他设备正常运行,具体如何判断呢?即对所在环境产生的电磁干扰不能超过一定的限值,这就是我们常说的EMI(Electro Magnetic Interference)电磁干扰。
另一方面是指电子、电气设备或系统能不受同一环境下的其他电子电器设备或系统的影响以至于不能正常工作,我们知道医院具备一个复杂的电磁环境,同一病房可能多种设备同时运行,这也就要求设备对所在环境中存在的电磁干扰具有一定程度的抗扰度,即我们常说的EMS(Electro Magnetic Susceptibility)电磁抗扰度,EMS是没有一个具体的限值的,而是有一个符合性准则,后面再谈。
EMC(电磁兼容)=EMI(电磁干扰)+EMS(电磁抗扰度)
Linux系统Docker使用指北 文章目录 Linux系统Docker使用指北写在前面什么是 Docker 镜像和 Docker 容器?Docker新手入门1.Linux Docker安装、卸载2.Docker镜像加速3.搜索Docker镜像4.下载Docker镜像5.查看已下载Docker镜像6.运行Docker容器6.1 通过 TAG 运行容器6.2 通过 Image ID 运行容器6.3 从运行中的容器中脱离6.4 以脱离形式运行容器 7.查看运行中的容器8.从运行中的容器脱离或连接9.启动、重启、暂停和终止容器10.强制终止容器11.在关闭容器后自动删除容器12.容器命名13.创建自己的容器14.移除容器15.删除镜像16.Docker数据集(数据挂载) Docker项目练手参考文献 工具名称: Docker 要求掌握程度:熟练掌握
写在前面 本文为一位不知名 Cpper 学习Docker容器的学习笔记,不谈原理,只谈使用方法,不喜勿喷。
记录自己的学习过程,与自己赛跑,永远在路上。
如有遗漏或者错误,请评论区理性交流、指正。别杠我,杠就是你对。
什么是 Docker 镜像和 Docker 容器? 在开始 Docker 之前,我先说明一下 Docker 镜像和 Docker 容器是什么。
Docker 镜像是一个描述容器如何运行的的文件,Docker 容器是 Docker 镜像在运行或被终止时的一个阶段。
容器和主机上的其他文件是隔离的。
当我们运行一个 Docker 容器的时候,它会使用一个被隔离出来的文件系统,这个文件系统是由一个 Docker 镜像提供的。Docker 镜像包含了运行应用程序所需要的一切东西 - 所有的依赖、配置、脚本、二进制文件等等。
镜像也包含容器所需要的其他配置项,比如说环境变量、默认运行的命令,以及其他元数据。
Docker 优点:
快速、一致地交付您的应用程序响应式部署和扩展轻巧快速,可以在同一硬件上运行更多工作负载 Docker新手入门 1.Linux Docker安装、卸载 这里仅介绍 Ubuntu Docker 安装,更多安装方法可参考:Docker菜鸟教程。
直接官方安装 shell 脚本自动安装,大佬想手动安装请随意,具体参考上面的菜鸟教程链接。
curl -fsSL https://test.
安装vscode环境 首先,需要安装最新版的 Rust 编译工具和 Visual Studio Code。
Rust 编译工具:安装 Rust - Rust 程序设计语言
Visual Studio Code:Download Visual Studio Code - Mac, Linux, Windows
初次编译时 遇到报错 error: linker `link.exe` not found
rustup toolchain install stable-x86_64-pc-windows-gnu
rustup default stable-x86_64-pc-windows-gnu
执行上面两个命令。解决了
一、Rust基础语法 1.变量 用let关键字声明变量,Rust具有自动判断变量类型的能力。
let a = 111; a = "abc"; //错误,当声明 a 是111以后,a 就被确定为整型数字,不能把字符串类型的值赋给它。 a = 4.56; //错误,自动转换数字精度有损失,Rust 语言不允许精度有损失的自动数据类型转换。 Rust 语言为了高并发安全而做的设计:在语言层面尽量少的让变量的值可以改变。所以 a 的值不可变。但这不意味着 a 不是"变量"(英文中的 variable),官方文档称 a 这种变量为"不可变变量"。如果我们编写的程序的一部分在假设值永远不会改变的情况下运行,而我们代码的另一部分在改变该值,那么代码的第一部分可能就不会按照设计的意图去运转。由于这种原因造成的错误很难在事后找到。这是 Rust 语言设计这种机制的原因。
Rust 编译器保证,如果声明一个值不会变,它就真的不会变,所以你不必自己跟踪它。这意味着你的代码更易于推导。
什么是DataDome? DataDome是一家专注于为网站、移动应用和API提供机器人保护的安全公司。它使用人工智能(AI)和机器学习算法分析流量模式,识别类似机器人的行为。其目标是保护企业免受各种有害机器人活动的影响,如内容抓取、账户接管、欺诈交易、统计数据扭曲等。
DataDome旨在检测和阻止甚至模仿人类行为的复杂机器人。它提供实时保护,以毫秒为单位作出决策,阻止有害机器人的访问,而不会影响合法用户的使用体验。
该公司的解决方案易于实施,并可与各种平台、系统和网页服务器集成。它提供详细的分析数据,帮助企业了解他们面临的机器人流量的性质和范围。
DataDome CAPTCHA是DataDome用于区分人类用户和机器人的工具之一。 CAPTCHA即"Completely Automated Public Turing test to tell Computers and Humans Apart"(全自动公共图灵测试,以区分计算机和人类)的缩写。这是一种旨在易于人类通过但对机器人难以通过的测试。
当DataDome的系统检测到可能表示机器人的可疑活动时,它可以触发CAPTCHA挑战。用户必须通过CAPTCHA来证明自己是人类而不是机器人。
DataDome CAPTCHA挑战可能看起来像这个代表:
在这个代表中,用户被呈现一个CAPTCHA图像和一个滑块按钮,用户必须完成这个拼图。成功完成CAPTCHA后,用户可以继续访问网站。如果他们失败或者CAPTCHA没有完成,系统可能会拒绝访问或者提供另一个CAPTCHA挑战。
总之,DataDome是一个综合的机器人保护解决方案,使用AI和机器学习来识别和阻止有害的机器人活动。它的CAPTCHA挑战是其验证用户是否是人类还是机器人的工具之一,有助于保护其所保护的网站的安全和完整性。
在本博客中,我们将重点介绍如何解决Datadome Captcha。
如何解决DataDome Captcha 在我们开始解决DataDome之前,有些要求和要点需要知道。
要求:
Capsolver密钥
代理(建议使用https://metaproxies.net/)
需要知道的要点:
验证码url的查询参数是动态获取的。这意味着您不能一次又一次地发送静态CAPTCHA url。 查询参数是加粗字体:https://geo.captcha-delivery.com/captcha/?initialCid=yourInitialCid&cid=yourCid&t=fe&referer=https%3A%2F%2Fantoinevastel.com%2Fbots%2Fdatadome&s=YourSParam&e=youreParam在第一个GET中获得此验证码。
查询参数t需要具有t=fe的值,如果有t=bv,则表示captchaUrl被禁止,并且不能提交。
匹配chrome版本的TLS、标头和标头顺序。
匹配用于解决验证码与交互页面的代理。
为了解决DataDome验证码,请遵循我们的文档。某些参数是必需的,某些是可选的。对于此示例,我们仅使用必需的参数。Datadome的任务类型包括:
DatadomeSliderTask:此任务类型需要您自己的代理。
对于这个示例,我们将使用DatadomeSliderTask作为该网站使用Datadome验证码。
如果缺少任何参数,您可能会遇到令牌无法被网站接受的问题。
文档中需要使用的第一种方法是createTask。此方法需要图片的参数,其中一些是必需的,一些是可选的,具体取决于我们要使用的网站。
步骤1:提交信息到capsolver 使用createTask方法提交信息:
POST https://api.capsolver.com/createTask { "clientKey": "Your_API_KEY", "task": { "type": "DatadomeSliderTask", "websiteURL": "https://antoinevastel.com/bots/datadome", "captchaUrl": "https://geo.captcha-delivery.com/captcha/?initialCid=yourInitialCid&cid=yourCid&t=fe&referer=https%3A%2F%2Fantoinevastel.com%2Fbots%2Fdatadome&s=YourSParam&e=youreParam", "proxy": "yourproxy", "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.
今天,我们将专注于FunCaptcha,这是一种独特而具有挑战性的CAPTCHA类型,在整个网络上越来越流行。我们将深入探讨FunCaptcha是什么,不同类型的FunCaptcha挑战,如何使用CapSolver解决它们等等。
什么是FunCaptcha? FunCaptcha是一种先进的CAPTCHA系统,旨在保护网站免受垃圾邮件和滥用攻击。它使用吸引人的迷你游戏来取代传统的基于文本的CAPTCHA系统,这些游戏对于机器人来说很难解决,但对于人来说易于,且很有趣。主要目标是提供用户友好的安全措施,以增强用户体验,同时保持对机器人和垃圾邮件的强大保护。
FunCaptcha由人工智能驱动,提供几乎不可能由机器人完成的挑战。这使得FunCaptcha成为一种非常有效和可靠的网站安全工具。截至最后更新,由于其独特的用户参与和安全性组合,FunCaptcha已被全球数千个网站使用。
FunCaptcha挑战类型 FunCaptcha向用户展示多种挑战,每个都旨在对人类容易但对机器人具有挑战性。以下是几种常见类型:
图像旋转:用户被呈现一个未对齐的图像(通常是动物),任务是将图像旋转到正立。这需要空间意识,这是机器人通常缺乏的技能。
对象识别:用户必须在复杂的图像中识别特定的对象。这测试用户理解上下文和细节的能力,这是目前人工智能难以复制的。
滑动配对:此挑战涉及将对象移动到图像中的正确位置。这测试用户识别模式和形状的能力,这是机器人另一个复杂的任务。
在本博客中,我们将专注于解决funcaptcha:
如何解决FunCaptcha 如何使用CapSolver解决FunCaptcha
CapSolver提供了一个可靠的解决方案,可以快速准确地解决FunCaptcha挑战。以下是一步步的指南:
创建账户:如果您是CapSolver的新用户,第一步是创建一个账户。您可以通过访问CapSolver网站并单击“注册”来完成此操作。提供所需的详细信息并完成注册过程。
添加资金:要使用CapSolver,您需要向您的账户添加资金。CapSolver提供多种付款选择,包括信用/借记卡和加密货币等。
API设置:一旦您的账户中有资金,就可以设置CapSolver API。CapSolver网站(docs.capsolver.com)提供的API文档将指导您完成该过程。它很简单,只需要基本技术知识即可。
发送FunCaptcha挑战:一旦设置了API,就可以将FunCaptcha挑战发送到CapSolver API。API将返回解决方案的响应。
提交解决方案:最后一步是将CapSolver提供的解决方案提交回FunCaptcha原始网站。
价格 通过CapSolver获取FunCaptcha解决方案的价格取决于您需要解决的CAPTCHA数量。CapSolver使用积分系统,每个解决的CAPTCHA都有一定数量的积分。有关最新的定价细节,请参阅CapSolver网站。
为什么选择CapSolver? CapSolver为解决FunCaptcha和其他CAPTCHA类型提供了强大、可靠和高效的解决方案。它非常适合需要快速准确地解决大量CAPTCHA的企业和个人。CapSolver的API易于集成,平台提供出色的客户支持,以确保您可以轻松应对任何挑战。
总之,FunCaptcha是一种独特而有趣的CAPTCHA系统,有了CapSolver,您可以轻松应对这些挑战。请继续关注我们的博客,以获得有关解决各种类型CAPTCHA的更新和指南!
如何解决FunCaptcha 在我们开始解决FunCaptcha之前,我们需要了解一些要求和注意事项:
要求:
Capsolver Key:这是该过程中的必要组件。Capsolver Key是一种唯一的标识符,用于验证您的CAPTCHA解决服务请求。
代理:虽然不是必需的,但在处理funcaptcha时强烈建议使用代理。代理服务器作为客户端请求其他服务器资源的中介,提供了额外的安全性和匿名性。为了获得最佳结果,您可以考虑使用可靠的服务,如MetaProxies。
尽管代理是可选的,但请记住,funcaptcha非常重视IP地址。因此,使用自己的代理通常是有益的。
需要注意一些点,如果不遵循,解决方案将无效:
为确保解决方案的有效性,必须严格遵守以下要点。未能这样做可能导致解决方案无效: Arkose Labs实现可能需要一个额外的参数。该参数用于传输一个blob值,即已转换为字符串的对象。以下是示例:
{"\blob":"INSERT_THE_blob_VALUE_HERE"}。
推荐使用自己的代理:您使用的代理质量可以极大地影响解决方案的有效性。质量差的代理可能导致得分低。 有关解决funcaptcha的更多详细信息,请参阅我们的文档。
对于此示例,我们将仅使用必需的参数。funCaptcha的任务类型为:
FunCaptchaTask:此任务类型需要使用您自己的代理。FunCaptchaTaskProxyLess使用服务器内置的代理。
我们将使用FunCaptchaTaskProxyLess。示例将是一个测试页面,其中有funcaptcha。该页面将是
要解决测试站点的funcaptcha,我们只需要向Capsolver发送以下信息: 要获得解决方案,请首先提交所有所需信息,为此我们使用createTask方法:
步骤1:向capsolver提交信息 POST https://api.capsolver.com/createTask { "clientKey":"Your_API_KEY", "task": { "type":"FunCaptchaTaskProxyless", "websiteURL":"https://client-demo.arkoselabs.com/solo-animals", "websitePublicKey":"029EF0D3-41DE-03E1-6971-466539B47725", "funcaptchaApiJSSubdomain":"https://client-api.arkoselabs.com" } } 步骤2:获取结果 要验证结果,您需要不断轮询getTaskResult API端点,直到captcha解决为止。
以下是一个示例请求:
POST https://api.capsolver.com/getTaskResult Host: api.capsolver.com Content-Type: application/json { "
一、项目背景 因本人的公司是做短信通信服务的,所以客户需要将短信的发送量,按照他们给定的PPT样例模板,来生成PDF报表数据,即PPT的样式,数据如何展示都是规定好了的,而我需要做的就是将真实的数据,渲染到样例PPT上去,并输出PDF即可。
二、思路 首先是将原生的PPT转换成xml模板,然后将xml模板的中样例数据转换成真实数据,最后输出PDF
1、注意点 将PPT生成xml可以借助一个解压工具,7zip提取xml文件
将PPT生成PDF需要借助LibreOffice 7.5,这个软件免费且无水印,需要本地安装
三、需求展示 以下为样例模板,我们需要做的 就是将真实的发送数据,进行替换
四、生成xml 通过7zip提取xml文件,提取后如下
其中的slide.xml为单纯的文字或者表,chart.xml为饼图,柱状图对应的xml
将样例模板PPT也拷贝到项目中 ,然后将xml拷贝到项目中,需要哪些表图或者柱状图就拷贝哪些xml
我们打开一个xml看下,如近三天发送总量表对应的xml,我们需要替换的就是如下的数据
五、伪代码 1、引入依赖 <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>${freemarker.version}</version> </dependency> <dependency> <groupId>org.jodconverter</groupId> <artifactId>jodconverter-core</artifactId> <version>${jodconverter.version}</version> </dependency> <dependency> <groupId>org.jodconverter</groupId> <artifactId>jodconverter-local</artifactId> <version>${jodconverter.version}</version> </dependency> <dependency> <groupId>org.jodconverter</groupId> <artifactId>jodconverter-spring-boot-starter</artifactId> <version>${jodconverter.version}</version> </dependency> <dependency> <groupId>org.libreoffice</groupId> <artifactId>ridl</artifactId> <version>${ridl.version}</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>${poi-ooxml.version}</version> </dependency> 2、定义数据实体 实体的属性值,就是最终要替换到xml中的key
@Data public class SmsReportPaper { private String year; private String month; private String day; /** * 昨天日期/上月 */ private String yesterday; /** * 上周同天日期/上年同期同月 */ private String lastWeek; /** * 上月同天日期 */ private String lastMonth; /** * 两个月以前 */ private String twoMonthAgo; /** * 三个月以前 */ private String threeMonthAgo; /** * (近三天/三个月) 发送量统计情况 */ private List<SmsDailyStatistics> lastThreeDayList; /** * (昨日/上个月)发送量:按运营商统计 */ private List<SmsDailyIndex> operatorDailyList; /** * (昨日/上个月)发送量:按序列号 */ private List<SmsDailyIndex> cdkeyDailyList; /** * (昨日/上个月)发送量:按通道 */ private List<SmsDailyIndex> channelDailyList; /** * (昨日/上个月)发送量:按部门 */ private List<SmsDailyIndex> departmentDailyList; /** * 运营商发送短信发送变化趋势图 */ private List<SmsPaperContrast> operatorPaperContrasts; /** * 序列号发送变化趋势图 */ private List<SmsPaperContrast> cdkeyPaperContrasts; /** * 通道发送变化趋势图 */ private List<SmsPaperContrast> channelPaperContrasts; /** * 序列号发送变化趋势表数据 */ private List<SmsCdKeyVariationTrendData> smsCdKeyVariationTrendDataList; } 需要注意的是,定义实体的时候,需要根据PPT模板的key来确定层级关系
一、问题描述 先上情况:
Tables 已经展开了,空空如也!!!
Procedures也是同样问题!!!
用语句查询,表这些都是有的!!!
二、解决方法 将 <当前用户> 与 <所有用户> ,来回切换,再次展开 Tables 就显示表了。
这里写自定义目录标题 ajax跨域请求完整解决方案简介跨域请求解决方案JSONPCORS简单请求:请求方法是以下三种方法之一:HTTP的头信息不超出以下几种字段:如果上述两个条件没有同时满足则属于非简单请求被调用方代码实现nginx实现 隐藏跨域 ajax跨域请求完整解决方案 简介 在发送Ajax请求的时候,由于浏览器的同源策略,会对跨域请求进行检测。
什么情况属于跨域请求:
协议不同 ,例如http与https;域名不同 ,例如www.a.com与www.b.com;端口号不同 ,例如http://localhost:8080与http://localhost:8081;
以上三种情况符合一种即为跨域请求。 跨域请求解决方案 JSONP jsonp实现跨域请求的原理简单的说就是动态台创建script标签,然后利用script的src不受同源策略约束来跨域获取数据(script中src请求静态资源例如图片等都不受同源策略约束
jsonp由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的json数据。
前端ajax请求
function getinfo(){ $.ajax( { url: "http://127.0.0.1:8082/test/submit", type: "GET", contentType: "jsonp", data:JSON.stringify({ "username": username, "password": password }) , jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据 success:function (data) { alert(data["username"]); }, error:function (data) { alert("请求失败") } } ) } //也可以在回调函数中获取返回值与ajax中的success的函数作用相同 function flightHandler(){ alert(data.username); } Java后台代码
我后台用的spring框架,因此新建一个类添加@ControllerAdvice注解用于操作controller层
(PS:spring boot2.0以后不推荐使用jsonp,因此没有AbstractJsonResponseBodyAdvice类)
@RestControllerAdvice public class JsonpAdvice extends AbstractJsonResponseBodyAdvice{ public JsonAdvice(){ super("callback");//参数与前端ajax请求中jsonp参数相同 } } 需要注意的一点:使用jsonp时只能发送get请求,但数据量大时jsonp方法就不适用了,因此可以采用cros方法
题目 原题链接
问题描述 有一架天平和 n ( 1 ≤ n ≤ 100 ) n(1\leq n \leq 100) n(1≤n≤100)个砝码,问通过灵活的使用砝码,这个天平可以称出多少种不同的质量。
分析 步骤一:确定状态
步骤二:确定状态转移方程
步骤三:确定边界情况和初始条件
步骤四:确定计算顺序
步骤一:确定状态
以 d p [ i ] [ j ] dp[i][j] dp[i][j]表示有 i i i个砝码时,能否称量出质量 j j j,1表示可行,0表示不可行。
步骤二:确定状态转移方程
欲求 d p [ i ] [ j ] dp[i][j] dp[i][j],已知在有 i − 1 i-1 i−1个砝码的条件下的所有称量情况,接下来就是求处理第 i i i个砝码时的所可以得到的称量情况。
1.若不放该砝码,则 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j]=dp[i-1][j] dp[i][j]=dp[i−1][j];
法一:采用临时变量,赋值
a = 10 b = 33 temp = a a = b b = temp print(a) print(b) 法二:python特有的交换方式
a = 10 b = 33 a,b = b,a print(a) print(b) 法三:使用加减法,先求a,b之和,再求和数a,b
a = 10 b = 33 a = a + b # a = 43 b = a - b a = a - b print(a) print(b) 法四:异或法
异或的规则:相同为0,不同为1
原理是二进制运算;
a = 10 b = 33 # a = 001010 # b = 100001 a = a ^ b # a = 43 (二进制数:101011) b = a ^ b a = a ^ b print("
一:微信小程序bindtap点击事件与事件冒泡 原文链接
事件冒泡就是指嵌套事件发生,如果多层标签嵌套, 里层事件发生后, 其外层会相应发生, 如:
<view bindtap='handout'> outer <view bindtap='handmiddle'> middle <view bindtap='handinner'>inner</view> </view> </view> handout: function () { console.log("out"); }, handmiddle: function () { console.log("middle"); }, handinner: function () { console.log("inner"); } 点击inner三个事件都执行, 点击middlek执行handmiddle和handout, 点击out只执行handout 阻止事件冒泡行为: 将bindtap改为catchtap就行了。
catchtap只会触发自身的点击事件,会阻断自身的冒泡行为,可以理解为,不管是不是自身触发的点击行为, 传到我这里, 我就将它阻断(不再向上传递)。如:
<view bindtap='handout'> outer <view catchtap='handmiddle'> middle <view bindtap='handinner'>inner</view> </view> </view> 点击inner, 执行的是handinner和handmiddle两个函数,因为midd的catchtap阻止了事件冒泡行为,所以outer不会执行。
二:如何禁止掉view的bindtap事件? 解决这个问题: 借助了css3中的一个非常好用的特性 在指定的类上添加一个pointer-events: none就可以了的。
代码如下:
<!--pages/news/index.wxml--> <view> <text>消息页</text> <view class="btn {{is_able ? 'btn_able':'btn-disabled'}}" bindtap="handeBtn">{{is_able ?
首先从网上查去官网下载好 点击安装发现说
破坏的映像
然后去系统偏好设置 -----通用------有个任何来源 点击就好 如果没有去命令框输入sudo spctl --master-disable 执行一下就有了
本人测试还是 显示破坏的映像
于是第一步: /bin/bash -c “$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)”
用个命令 然后选:注意注意注意 :输入序列号:1
一步步完成安装就好了
**第二步:**安装docker
brew install --cask --appdir=/Applications docker
大概的写一下 不要介意 欢迎参考 谢谢
windows、linux、Python、Pytorch、AI算法开发过程中遇到的一些问题及其解决方法 自备的,以便后面遇到同样问题时查阅,如果对你没有帮助可以划走了,内容都是临时记录的,没有格式编排,但有问题目录,点击即可跳转,如果目录中没有你想要的问题,可以划走了 文章目录 windows、linux、Python、Pytorch、AI算法开发过程中遇到的一些问题及其解决方法▶windows powershell无法使用conda虚拟环境,windows cmd中无法使用conda虚拟环境▶dtype="<U5"表示字符串不超过5位▶Pycharm提示:cannot find reference ‘***’ in (input:(any,```),kwargs:dict) -> any',但是可以正常跑?▶卷积参数量、计算量▶ 求完损失以后在进行反向传播 loss.backward()时报一个类型错误(RuntimeError: expected dtype Float but got dtype Long):▶ 网络一个batch的输出不是我们想用来计算的数据,我们希望将一轮(多个batch/多次输出)的结果拿来计算,但是,Tensor不能append,如果用cat,那初始化也是个难题,这时借助列表,将多次输出append到列表,再用torch.cat()将列表连接并转换成tensor数据。▶ CNN中Conv2d的padding方式▶ Pycharm中run控制台的可显示长度、显示精度、取消科学计数法……设置方式: ▶损失为Nan、nan;loss为nan▶过拟合、发现与解决▶二范数、欧氏距离、向量求模▶二维向量按某列排序用lambda匿名函数▶RuntimeError: cuDNN error: CUDNN_STATUS_BAD_PARAM▶PIL和OpenCV互转PIL >> CV2:CV2 >> PIL:判断图像数据是否是OpenCV格式: ▶python+openCV通道拆分(R、G、B)和合并▶PIL的save命令保存下来的图片的质量问题▶ reduce failed to synchronize: cudaErrorAssert: device-side assert triggeredall elements of input should be between 0 and 1 ▶Pytorch跑RNN、LSTM等结构时报:'UserWarning: RNN module weights are not part of single contiguous chunk of memory▶ValueError: Expected more than 1 value per channel when training, got input size torch.
JavaScript 删除数组中指定元素 在 JavaScript 中,数组是一种常见的数据类型,可以存储多个元素。有时候,我们需要从数组中删除某些特定的元素。本文将介绍如何使用 JavaScript 删除数组中指定的元素。
1.使用splice()方法删除元素 JavaScript 中的 splice() 方法可用于在数组中添加或删除元素。如果我们需要删除数组中的元素,可以使用 splice() 方法。该方法接受两个参数,第一个参数指定要删除的元素的位置,第二个参数指定要删除的元素个数。例如,我们可以使用以下代码删除数组中的第二个元素:
let myArray = ["apple", "banana", "orange", "grape"]; myArray.splice(1, 1); console.log(myArray); // ["apple", "orange", "grape"] 输出结果为:["apple", "orange", "grape"]
2.使用filter()方法删除元素 除了使用 splice() 方法,我们还可以使用 filter() 方法来删除数组中的元素。该方法可用于创建一个新的数组,其中包含符合特定条件的元素。我们可以使用以下代码删除数组中的所有 “banana” 元素:
let myArray = ["apple", "banana", "orange", "grape"]; myArray = myArray.filter(function(item) { return item !== "banana" }); console.log(myArray); // ["apple", "orange", "grape"] 输出结果为:["apple", "orange", "grape"]
3.使用pop()和shift()方法删除元素 pop() 和 shift() 方法可用于删除数组的最后一个元素和第一个元素。如果我们想删除数组中的特定元素,可以使用这些方法与 indexOf() 方法结合使用。例如,以下代码可以删除数组中的第二个元素:
请关注【来玩AI】公众号体验人工智能
来玩AI >>>
Python实现适配器模式 简介Python实现适配器模式适配器的应用场景3.1 将不兼容的接口转换成可兼容的接口3.2 将已有的接口进行二次封装3.3 在不修改原有代码的情况下,增加新的功能3.4 软件系统扩展时的接口协作3.5 对象或类的子系统需要独立于其它子系统或者客户端 简介 适配器模式是一种常用的结构型设计模式,它的主要目的是将一个类的接口转化为客户端所期望的另一个接口。适配器可以充当两个不兼容接口之间的桥梁,使得原本由于接口不匹配而无法一起工作的类能够协同工作。
适配器模式通常包含几个组成部分,其中最关键的是适配器类,该类实现了客户端所期望的接口,并持有适配者(即需要被适配的类)的一个实例引用。当客户端调用适配器的方法时,该方法会通过适配者的实例来调用适配者的方法,以完成客户端的请求。
适配器模式的优点在于它可以让客户端与适配者解耦,从而提高代码的复用性和灵活性。它还可以简化系统设计,使得系统的不同部分可以更加方便地进行集成和协同工作。适配器模式的缺点在于它可能会增加系统复杂性,并且在使用多个适配器时需要谨防适配器的复杂嵌套,以避免代码难以维护。
Python实现适配器模式 在 Python 中实现适配器可以使用面向对象编程的方式,代码如下:
class Target: """ 客户端所期望使用的接口 """ def target_method(self): pass class Adaptee: """ 需要被适配的类 """ def adaptee_method(self): pass class Adapter(Target): """ 适配器类,将 Adaptee 类的接口转化为 Target 类的接口 """ def __init__(self, adaptee): self.adaptee = adaptee def target_method(self): self.adaptee.adaptee_method() 在上面的代码中,我们定义了一个 Target 接口,以及一个需要被适配的 Adaptee 类和一个适配器 Adapter 类。Adapter 类持有一个 Adaptee 的实例引用,并实现了 Target 接口的方法,该方法会通过 Adaptee 的实例来调用 Adaptee 的方法,从而完成客户端的请求。
使用时,我们可以先创建一个 Adaptee 的实例,然后将其传入 Adapter 类中,以创建一个适配器实例。最后,我们就可以使用适配器实例来调用 Target 接口的方法了。
这两天用pyinstaller打包python文件,出现一个问题。python成功打包出exe文件,但exe文件在运行时会报错failed to execute script 'start' due to unhandled exception:No module named 'charset _normalizer.md_mypyc'。
之后尝试了”pyinstaller -Fw -i .\pdf.ico --hidden-import=ctypes --hidden-import=psutil --hidden-import=uuid --hidden-import=win32file --hidden-import=pywintypes .\output\main.py”和“pyinstaller -F -c”显示出它的控制台结果都不好使。最后使用了auto_py_to_exe的方式。
pip install auto-py-to-exe#安装auto-py-to-exe
python -m auto_py_to_exe biquge_noval.py#使用auto-py-to-exe打包biquge_noval.py文件
命令运行后出现这个页面
点击转换按钮即可。问题解决。
在FastAdmin中,可以将一个数组显示在Bootstrap Table中,具体步骤如下:
创建一个控制器,利用Model获取需要显示的数据,并传入模板;在模板中引入Bootstrap Table和jQuery库,并将获取到的数据输出至表格中;在每一列的后面添加一个输入框和一个提交按钮,并利用jQuery获取输入框内容,将数据通过AJAX请求发送给控制器。 下面是一个示例代码:
控制器:
namespace app\admin\controller; use think\Controller; use app\admin\model\TestModel; class TestController extends Controller { public function index() { $test = new TestModel(); $data = $test->field('id,name,age')->select(); $this->assign('data', $data); return $this->fetch(); } public function update() { $id = input('post.id'); $name = input('post.name'); $age = input('post.age'); // 更新数据的逻辑 return json(['code' => 1, 'msg' => '更新成功']); } } 模板:
{extend name="layout/layout"} {block name="content"} <table class="table" data-toggle="table"> <thead> <tr> <th>ID</th> <th>名称</th> <th>年龄</th> <th>操作</th> </tr> </thead> <tbody> {volist name="
感觉没什么好的学习材料和网站,网上资料本就很少,有代码的更少,而且呢,这些代码还基本上都是TensorFlow1.x版本的,和2.x不兼容,需要修改
我想了想既然我一直在debug,那不如把这一篇文章写成一个debug集锦,也方便以后解决问题
error No1
Using TensorFlow backend. Traceback (most recent call last): File "E:/Code/pythoprogram/Reinforcement-learning-with-tensorflow-master/contents/5_Deep_Q_Network/run_this.py", line 2, in <module> from RL_brain import DeepQNetwork File "E:\Code\pythoprogram\Reinforcement-learning-with-tensorflow-master\contents\5_Deep_Q_Network\RL_brain.py", line 18, in <module> tf.set_random_seed(1) AttributeError: module 'tensorflow' has no attribute 'set_random_seed' solution No1
tf.random.set_seed(1) error No2
Using TensorFlow backend. Traceback (most recent call last): File "E:/Code/pythoprogram/Reinforcement-learning-with-tensorflow-master/contents/5_Deep_Q_Network/run_this.py", line 47, in <module> memory_size=2000, File "E:\Code\pythoprogram\Reinforcement-learning-with-tensorflow-master\contents\5_Deep_Q_Network\RL_brain.py", line 54, in __init__ self._build_net() File "E:\Code\pythoprogram\Reinforcement-learning-with-tensorflow-master\contents\5_Deep_Q_Network\RL_brain.py", line 71, in _build_net self.
Linux命令之more 1.more介绍 linux命令more是用来查看文件内容,如果文件内容多余一页,则会一页一页的显示,方便浏览者查阅
2.more用法 more [参数] [文件名称]
more常用参数 参数说明-num一次显示num行数+num从第num行开始显示-s当遇到有连续两行以上的空白行,就替换为一行的空白行显示 3.实例 3.1.一次显示3行zzz.txt中的文件内容 3.2.从第三行显示zzz.txt中的文件内容 3.3.ztj.txt文件的连续多个空白行显示为一行
C语言实现守护进程 守护进程(daemon)是在后台运行的一种特殊进程,它没有控制终端,通常用于在系统启动时启动一些需要常驻后台的服务程序。
Linux的大多数服务器就是用守护进程的方式实现的。如web服务器进程http等。守护进程在后台运行,类似于Windows中的系统服务。
查看系统中的进程:
ps axj 参数a表示不仅列当前用户的进程,也列出所有其他用户的进程,
参数x表示不仅列有控制终端的进程,也列出所无控制终端的进程,
参数j表示列出与作业控制相关的信息。
凡是TPGID一栏写着-1的都是没有控制终端的进程,也就是守护进程。在COMMAND一列用[]括起来的名字表示内核线程,这些线程在内核里创建,没有用户空间代码,
因此没有程序文件名和命令行, 通常采用以k开头的名字,表示Kernel。守护进程通 常采用以d结尾的名字,表示Daemon。
守护进程的原理是通过fork()创建一个子进程,让子进程脱离控制终端,设置新的会话组,关闭标准输入输出和错误输出,最后通过umask()函数来设置文件的权限掩码,使得守护进程在运行过程中不会被其他用户所访问。
daemon()守护进程函数
原型
int daemon(int nochdir,int noclose) 其中,nochdir参数用于指定是否改变工作目录,如果给它传递0,则工作目录将被设置为“/”(根目录),否则继续使用当前工作目录。
noclose参数为0时,标准输入、标准输出和标准错误输出都被重定向到/dev/null文件,否则依然使用原来的设备。
该函数成功时返回0,失败返回-1,并设置errno。
例如:
daemon(0,0):nochdir为0 改为根目录,noclose为0 关闭所有文件描述符;
将当前工作目录更改为根目录的作用:
防止当前目录有一个目录被删除,导致守护进程无效。
使用fork()创建的子进程是继承了父进程的当前工作目录,由于在进程运行中,当前目录所在的文件系统是不能卸载的,这对以后使用会造成很多的麻烦。
因此通常的做法是让“/”作为守护进程的当前目录,当然也可以指定其他的别的目录来作为守护进程的工作目录。
以下是用C语言实现守护进程的完整代码:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> void daemonize() { pid_t pid; /* Step 1: Create a child process */ pid = fork(); if(pid < 0) /* Error occurred */ { perror("
目录
一、云上资源效能挑战
云上资源浪费现状
云原生时代的成本管理挑战
成本优化思路与常用手段
编辑FinOps概念
成本构成
节点成本
工作负载成本
资源利用率优化模型
横向伸缩和纵向伸缩
kubernetes原生能力的不足编辑
二、云原生场景下的成本优化挑战
成本分析
场景一:成本可视化
场景二:规格推荐
场景三:智能预测与自动扩缩容
三、Crane智能调度助力成本优化
负载感知调度
拓扑感知调度
支持模拟调度的重调度器
混部内核确保高优业务稳定性 Crane 项目介绍
内部大规模落地的成效
外部优化成效
软件清单
一、云上资源效能挑战 云上资源浪费现状 Flexera 2022云计算市场发展状态报告:32%的云支出被浪费
云原生时代的成本管理挑战 去中心化 随着kubernetes为核心的云原生应用的蓬勃发展,传统的集中式财务预算和IT管理模式在向以业务为导向的分布式决策转型不断上涨 CNCF调查显示,随着业务的快速发展,企业的云费用以24%的年增长快速增加动态变化 与原生的动态环境和弹性能力导致云费用随业务负载不断变化浪费严重 业务上云以后缺乏资源优化意识,依然以传统资源配置思维管理资源,浪费严重 由于存在此类问题所以得出FinOps概念来解决此类问题
成本优化思路与常用手段 成本优化思路 最大化资源利用率限制资源清理厂商折扣以单位经济学驱动成本优化费率优化 统一采购,销售费率折扣预留实例,包年包月,享受承诺使用费率折扣自动扩缩容,按需付费竞价实例,牺牲SLA使用廉价闲置资源用量优化 业务侧 规格优化实时、自动扩缩容平台侧 利用率优化 调度优化提升混部闲置资源识别与清理 闲置节点降配非活跃存储降配、清理非活跃CLB,EIP网络资源清理 FinOps概念 FinOps是一种将财务管理(Finance)与云操作(Ops)相结合的模式,旨在优化云计算支出并提高业务绩效。
云计算是一种流量密集型的技术,意味着云成本管理在很大程度上取决于如何优化云资源消耗,并根据需要提高或降低开支。FinOps通过建立流程、原则和工具来实现这一目标,可以帮助企业更好地理解和控制云成本,同时保持效率和创新。
FinOps的关键原则是建,立透明度并将云成本降低到最小水平。为了实现这一点,需要结合使用财务、技术和业务信息,以确定最佳的资源使用方式。同时,需要确定哪些资源实际上为贡献产生了价值,并分配成本以实现真正的透明度和可控性。
总之,FinOps作为一种模式结合了财务和技术的因素,可以帮助企业实现优化云支出和提高业务绩效的目标。
FinOps定义了一系列云财务管理规则和最佳实践,通过助力工程和财务团队、技术和业务团队彼此合作,进行数据驱动的成本决策,使组织能够获得最大收益。
成本构成 节点成本 CPU成本=CPU单价*节点CPU核数*节点使用时长内存成本=内存单价*节点内存内容*节点使用时长其他,如GPU卡成本,储存成本节点成本=CPU成本+内存成本+其他 工作负载成本 工作负载通常按资源分配量或使用量独立计价 分配成本=分配量*使用时长*单价使用时间=使用量*使用时长*单价工作负载需要分摊的成本 限制成本=闲置资源量*闲置时长*单价公开开销成本=集群管理组件公共服务的资源成本 资源利用率优化模型 横向伸缩和纵向伸缩 应用扩容市值在应用接收到的并发请求已经处于其处理请求极限便捷的情形下,扩展处理能力而确保应用高可用的技术手段 horizontal scaling 所谓横向伸缩市值听过增加实用案例数量分担负载的方式来提升应用整体处理能力的方式 vertical scaling 所谓纵向伸缩是指通过增加单个应用实例资源以提升单个实例处理能力,进而提升应用整体处理能力的方法 kubernetes原生能力的不足 开源地址 https://github.
文章目录 一、概述方式一(不推荐):方式二: 一、概述 logback日志脱敏。
Github| https://github.com/duke147/springboot-logback
方式一(不推荐): 这种方式只能脱敏一个字段。
因为 replace 的规则在找到第一个匹配后就会立即停止,这就导致只有第一个匹配到的字段被替换。
<encoder> <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %replace(%msg){ 'bankNo":"(\d{4})\d+(\d{4})', 'bankNo":"$1****$2' }%n </pattern> </encoder> 方式二: 自定义匹配规则,新建类MaskingConverter.java
import ch.qos.logback.classic.pattern.ClassicConverter; import ch.qos.logback.classic.spi.ILoggingEvent; import java.util.regex.Matcher; import java.util.regex.Pattern; public class MaskingConverter extends ClassicConverter { /*********** 匹配JSON格式字段:"name":"张三" ************/ // 银行卡脱敏 private static final Pattern BANKNO_PATTERN = Pattern.compile("\"bankNo\":\"(\\d{4})\\d+(\\d{4})\""); // 姓名脱敏 private static final Pattern NAME_PATTERN = Pattern.compile("\"(legalName|name|personName)\":\"([\\u4e00-\\u9fa5])([\\u4e00-\\u9fa5]*)\""); // 手机号脱敏 private static final Pattern PHONE_PATTERN = Pattern.
文章目录 前言一、HTTP请求和响应是什么?二、Springboot项目的使用步骤1.Springboot项目的简单了解2.简单了解Springboot项目所使用的标签:3.开始使用Springboot项目使用mybaits连接数据库创建三层架构的相关类创建相关数据库(选读) 4.对代码进行验证 总结 前言 Spring Boot是一个快速开发框架,可以帮助开发者快速搭建Web应用。在Spring Boot项目中,与前台进行交互通常采用RESTful API的方式,即通过HTTP请求和响应来传输数据。开发者可以使用Spring Boot的注解和相关工具来定义API接口,以及处理请求和返回响应。同时,前台可以通过Ajax等技术向后端发送请求,获取数据并进行展示。通过这种方式,Spring Boot可以与前台进行简单而高效的交互,为用户提供更好的使用体验。
一、HTTP请求和响应是什么? HTTP请求和响应是互联网上数据传输的基础。HTTP请求是由客户端发送给服务器的数据包,用于请求特定的资源或执行某种操作。而HTTP响应则是服务器对请求作出的回应,其中包含了请求的资源或操作的结果。这些请求和响应的格式都是按照HTTP协议规定的,以确保数据的完整性和正确性。虽然HTTP请求和响应的技术细节比较复杂,但它们是许多互联网应用的基础,比如浏览网页、发送电子邮件等。
二、Springboot项目的使用步骤 1.Springboot项目的简单了解 打开我们的IDEA,我们先来了解一下我们等下使用到HTTP协议的相关标签:
***这里需要强调一点:***以后创建的所有包或类都要放在主包中,这关系这你的Springboot项目能否成功运行!!!
2.简单了解Springboot项目所使用的标签: 1.@SpringBootApplication(出现在主类中):通常用于Spring Boot应用程序的主类上。它充分利用了Spring框架中的自动配置特性和约定大于配置的理念,使得开发者可以更加便捷地搭建一个基于Spring Boot的应用程序。该注解包含了几个常用注解的组合,如@ComponentScan、@EnableAutoConfiguration和@Configuration等。通过@SpringBootApplication注解,开发者可以快速搭建出一个功能完备的Spring Boot应用程序,而无需手动配置大量的Spring组件。
2.@Mapper(出现在mapper类中):用于标识MyBatis框架中的Mapper接口,可以将Mapper接口与对应的映射文件(xml文件)关联起来,实现SQL语句与Java方法之间的映射。使用@Mapper注解可以简化MyBatis的配置过程,提高开发效率。
3.@RestController(出现在controller类中):它是Spring Framework中用于创建RESTful Web服务的一个方便的方式。它可以将Java类定义为RESTful Web服务的控制器,使得开发人员可以很方便地处理HTTP请求和响应。使用@RestController注解,开发人员可以将数据以JSON、XML等格式返回给客户端,从而实现前后端分离,提高Web应用程序的可扩展性和可维护性。
4.@Service(出现在service类中):它通常用于标注Java类,表示该类是一个服务(Service)组件。服务组件的作用是实现业务逻辑,为其他组件提供可重用的函数和方法。在开发过程中,@Service注解可以帮助开发者更好地组织代码,提高代码的可读性和可维护性。
5.@RequestMapping(出现在controller类中):用于在Spring框架中定义HTTP请求的处理方法。它可以将HTTP请求映射到控制器中的特定方法上,并允许开发人员指定请求的URL、请求方法、请求头、请求参数等信息,以便更精确地处理请求。这是一个非常有用的工具,可以帮助开发人员更好地管理他们的应用程序,并提供更好的用户体验。
6.@PostMapping(出现在controller类中):通常在Spring Framework中使用,用于将HTTP POST请求映射到处理程序方法上。它是Spring MVC框架中@RequestMapping注解的一种特殊情况,用于限定HTTP请求的类型。使用@PostMapping注解时,处理程序方法将只处理HTTP POST请求,并且可以根据需要访问POST请求的正文。总的来说,它是一种方便的方式来处理Web应用程序中的表单提交和其他POST请求。
7.@GetMapping(出现在controller类中):它可以用于将HTTP GET请求映射到特定的处理程序方法上。它是Spring Framework中的一个注解,用于构建RESTful Web服务。通过这个注解,我们可以在Spring Boot应用程序中很容易地处理HTTP GET请求,并将其映射到正确的处理程序方法上。
8.@DeleteMapping(出现在controller类中):用于将HTTP DELETE请求映射到特定的处理程序方法上。它通常与Spring MVC框架一起使用,用于创建RESTful Web服务。使用该注解,开发人员可以轻松地将HTTP DELETE请求映射到处理程序方法,以实现删除资源或执行其他自定义操作。
9.@Resource(三层架构所用到的注解):用于标记需要注入的资源,如数据库连接、JMS 连接工厂等。它可以替代传统的 XML 配置文件,使得代码更加简洁和易于维护。同时,@Resource 还可以指定注入的资源的名称或者类型,提高了代码的灵活性和可读性。
10.@RequestBody(注解特殊的形参):通常用于Spring框架中的Web应用程序开发中,用于指定HTTP请求的请求体应该绑定到方法的哪个参数上。具体来说,当客户端发送请求时,请求体通常包含需要传递给服务器的数据,例如JSON、XML或文本数据等。通过使用@RequestBody注解,开发人员可以将请求体中的数据映射到Java对象中,并在方法中进行处理。这种方式非常灵活,可以方便地处理不同类型的请求体数据。
11.@PathVariable(注解特殊的形参):用于从URL中提取参数值并将其注入到方法参数中。它通常与@RequestMapping注解一起使用,用于处理RESTful风格的请求。虽然@RequestMapping注解可以处理URL路径中的参数,但是@PathVariable注解可以更方便地获取路径中的参数值,并将其作为方法的参数使用。这对于处理动态URL非常有用,可以让代码更加简洁和易于维护。
3.开始使用Springboot项目 使用mybaits连接数据库 在使用mybaits插件时,我们实现需要在创建项目时选择mybaits的相关依赖,这个在我上一个博客中讲到了,不了解的小伙伴可以点击我连接一下,那么这里就不再多说;另外还需要mysql-connector-j的依赖,我会将依赖放在如下代码块中:
<dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> 完成后可以在我们项目中的pom.xml文件中查看:
接下来在我们在java目录下的resources文件下创建一个新的文件:
新文件名可以随便取,但是得以.yml结尾就行,我这里就叫:application.yml
可能就有人有疑问了,什么是yml文件呢?来看看AI的解答:
.yml文件是一种文本文件,通常用于存储和传输数据。它是一种轻量级的数据交换格式,常用于配置文件和数据序列化。.yml文件采用类似于XML的键值对格式,但语法更加简洁易读。许多软件和框架都使用.yml文件来配置应用程序的行为和属性。
接下来我们来配置连接数据库的相关信息:
在我们的application.yml中配置如下信息:
spring: datasource: driver-class-name: com.
在python中执行其他python文件的一种方法 可以利用模型导入的方法
要运行的其他代码need_run.py
print("hellow world") a = 1 可以采用如下方式运行并保存变量:
把need_run.py内容换成函数 def aa(): print("hellow world") result = 1 return result 在另一个python文件中运行如下代码(导入模块) from need_run import aa res = aa() print(res) 另见
在python中运行命令行命令的四种方案-小羽的知识库 (stackoverflow.club)
在学完C语言后,自己闲的没事做的,主要就是模拟电脑的磁盘的创建文件/文件夹、删除之类的,主要写的是实现逻辑,作为大作业什么的也不错,如果有大作业程序需求,可以私信我
(*>.<*)(*>.<*)
如果使用的是Visual Studio 2022,记得在项目属性中禁用警告4996
如果能帮助您,还请点个赞,谢谢!(*>.<*)
#include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include<string.h> #define MAX_NameLength 20//文件名最长长度 #define MAX_ContentLength 200//文件内容最长长度 #define MAX_RouteLength 20//文件路径个数 #define STR "D"//一级目录名称 #define MAX_USERNAME_LEN 10//用户名长度 #define MAX_PASSWORD_LEN 10//用户密码长度 #define MAX_USERS_NUM 16//最多用户数量 /* *本系统实现了用户注册、登录,将用户名、密码存放在文件里 * 模拟了电脑D盘的文件结构 */ typedef struct User { char username[MAX_USERNAME_LEN + 1];//用户名 char password[MAX_PASSWORD_LEN + 1];//用户密码 }User; typedef struct FileNode//文件结构体 { char fileName[MAX_NameLength];//文件名 struct FileNode* next;//同级目录的下一个文件 char content[MAX_ContentLength];//文件内容 }FileNode; typedef struct FolderNode//文件夹结构体 { char folderName[MAX_NameLength];//文件夹名 struct FolderNode* next;//同级目录的下一个文件夹 struct FolderNode* nextFolder;//下一级目录的文件夹 struct FolderNode* previous;//前一个文件夹结构体 struct FileNode* nextFile;//下一级目录的文件 struct FileNode* SameLevelFileHead;//同级文件头结点,只有头结点才有 bool is_Head;//是否头结点 }FolderNode; void initialFirstHead(FileNode** FirstFileHead, FolderNode** FirstFolderHead);//初始化一级目录头结点 void initial(FileNode** file, FolderNode** folder, FolderNode* head);//初始化文件夹链表的头结点、文件链表头结点 void AddFolder(FolderNode* head); //同级增加文件夹 void AddFile(FileNode* head);//同级增加文件 void PrintDirectory(FolderNode* folderHead, FileNode* fileHead);//打印文件目录 void OpenFile(FileNode* fileHead);//打印文件 void OpenFolder(FileNode** fileHead, FolderNode** folderHead);//打开文件夹 bool StartInterface();//开始界面 void PrintSystemName(FolderNode* folderHead);//打印当前路径 void MainMenu();//主菜单 void SelectMenu(FileNode** fileHead, FolderNode** folderHead);//选择菜单 void ClearScreen()//清屏 { system("
1、SkyWalking简介 SkyWalking是国内开源的基于字节码注入的调用链分析以及应用监控分析工具。特点是支持多种插件,UI功能较强,接入端无代码侵入。目前使用厂商最多,版本更新较快,已成为 Apache 基金会顶级项目。
它有哪些功能呢?
多种监控手段。可以通过语言探针和 service mesh 获得监控是数据。多个语言自动探针。包括 Java,.NET Core 和 Node.JS。轻量高效。无需大数据平台,和大量的服务器资源。模块化。UI、存储、集群管理都有多种机制可选。支持告警。优秀的可视化解决方案。 SkyWalking在逻辑上分为四个部分:探针,平台后端,存储和UI。
探测器收集遥测数据,包括各种格式(SkyWalking,Zipkin,OpenTelemetry,Prometheus,Zabbix等)的指标,跟踪,日志和事件。平台后端支持数据聚合、分析和流流程,涵盖跟踪、指标、日志和事件。充当聚合器角色和/或接收者角色。存储通过开放/可插拔接口存储SkyWalking数据。您可以选择现有实现,例如 ElasticSearch,H2,MySQL,TiDB,BanyanDB,或者实现你自己的。UI是一个高度可定制的基于Web的界面,允许SkyWalking最终用户可视化和管理SkyWalking数据。 2、Skywalking部署(这里选择ElasticSearch作为储存) 2.1安装ElasticSearch 官网:Download Elasticsearch | Elastic
这里我下载的是windows的7.4.2版本
直接运行即可
可以访问本机9200端口看看有没有成功运行
2、安装Skywalking 官网:Downloads | Apache SkyWalking
1.下载最新版 2.修改配置,主要是指定elasticsearch 修改成自己配置的地址 3.启动 注意!JDK版本需要在11-17,其他版本可能运行不了,试过JDK8的不行。 4.访问8080端口,查看是否启动成功 3、配置agent 官网地址:Downloads | Apache SkyWalking
下载对应版本
agent包直接放在项目主目录下
agent运行步骤
1.修改应用名,为了区分 2.修改skywalkingip地址 3.添加运行参数,就是agent jar包的位置 4.运行项目即可 测试,可以看见应用在skywalking以及可以看见了 需要资源或者有什么问题可以留言讨论哦。
题目描述 设计和构建一个“最近最少使用”缓存,该缓存会删除最近最少使用的项目。缓存应该从键映射到值(允许你插入和检索特定键对应的值),并在初始化时指定最大容量。当缓存被填满时,它应该删除最近最少使用的项目。
题目传送门:面试题 16.25. LRU 缓存
它应该支持以下操作: 获取数据 get 和 写入数据 put 。
获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最近最少使用的数据值,从而为新的数据值留出空间。
示例:
LRUCache cache = new LRUCache( 2 /* 缓存容量 */ ); cache.put(1, 1); cache.put(2, 2); cache.get(1); // 返回 1 cache.put(3, 3); // 该操作会使得密钥 2 作废 cache.get(2); // 返回 -1 (未找到) cache.put(4, 4); // 该操作会使得密钥 1 作废 cache.get(1); // 返回 -1 (未找到) cache.get(3); // 返回 3 cache.
list容器的基础概念 在 C++ 标准库中,list 是一种双向链表,允许在任何位置进行快速的插入和删除操作。
以下是一些关于 list 的基本信息。
存储:list 是一种双向链表结构,它不像 vector 或 array 那样提供连续的内存存储。
时间复杂度:list 在链表的开始、结束或中间位置插入和删除元素的时间复杂度是 O(1)。然而,查找元素的时间复杂度是 O(n)。
空间复杂度:由于链表中每个元素都需要额外存储其前后节点的信息,因此 list 相比于使用连续内存的容器(如 vector 或 array)具有更高的空间复杂度。
迭代器失效:当你插入或删除元素时,list 的所有迭代器,包括指向链表开始和结束位置的迭代器,都不会失效。唯一的例外是当你删除一个元素时,指向该元素的迭代器将失效。
元素访问:list 不支持随机访问。要访问 list 中的元素,你必须从链表的开始(或结束)位置遍历到你要访问的位置。因此,list 不提供 operator[] 函数(下标运算符)。
list的函数解析 list有各种各样的成员函数,下面我将以函数的功能对这些函数分一下类,然后按照类别,一一介绍这些函数的用处。 构造函数 list(): 创建一个空的 listlist(n, elem): 创建一个包含 n 个元素的 list,每个元素的值都是 elemlist(begin, end): 创建一个包含 [begin, end) 区间元素的 list 以下是使用这些构造函数创建 std::list 的示例:
#include <iostream> #include <list> #include <vector> int main() { // 创建一个空的 list std::list<int> list1; // 创建一个包含 5 个元素的 list,每个元素的值都是 10 std::list<int> list2(5, 10); // 从 vector 创建 list std::vector<int> vec = {1, 2, 3, 4, 5}; std::list<int> list3(vec.
先上代码: 网上找的脚本python 实现将视频转换为图片。
""" 将视频转换为图片,可以为多个文件夹下的图片。 注:在程序使用前需先配置好main中的地址 视频路径:video_path_list = [path1, path2, ...](路径数量可以为[1,n],每个路径下的视频数也可为[1,m]) paht1 path2 .... |------video1.avi |-----video1.avi |------vidoe2.avi |-----... |------.... 图片存储路径:image_save_dir = save_path(存储方式则将按以下方式) save_path | -------path1_name |----video1 |----jpg1.jpg |----jpg2,jpg |----video2 ... |-------path2_name ... """ import cv2 import os from pathlib import Path VID_FORMATS = ('.mov', '.avi', '.mp4', '.mpg', '.mpeg', '.m4v', '.wmv', '.mkv', '.mp3') def videos2images(root_video_path, root_save_dir): for video_dir_path in root_video_path: # 1.检测读取文件路径是否正确 path_video = Path(video_dir_path) if path_video.is_dir(): print(video_dir_path + '\t ok') videos = os.
今天和大家聊一下mysql中的count()方法 我们日常开发中,经常会用到count()命令,有的人用count(*),有的人用count(1),还有的人用count(id),那么这几种写法都有什么区别呢?哪种方法效率更高呢?今天我们就来解密一下 1 首先我们要先了解count()方法的原理 count()方法的作用就是计算当前sql语句所能查到的非NULL的行数,
mysql分为server层和存储引擎层,具体结构如下:
常见的存储引擎是InnoDB、myisam。
为什么要介绍引擎种类呢?因为count()方法在不同的存储引擎下,他的实现方式是不一样的。
例如语句 select count(*) from table1;
在myisam引擎的数据表里,会有个单独的字段,用来记录当前表里有几行数据,因此当查询行数的时候,直接返回这个字段就可以了,速度自然是相当迅速。
在InnoDB引擎里,实现方式则是选择体积最小的索引树,然后通过遍历叶子节点的个数,以此来获取全表的数据。
所以在InnoDB中,当count()需要扫描的数据量越大的时候,所消耗的时间就会越长。
2 也许有人会问为什么InnoDB不能像MyIsam那样单独记录表行数呢? MyIsam和InnoDB最大的区别就是MyIsam不支持事务,InnoDB支持事务。
而事务有四种隔离级别,其中默认的就是可重复读。
InnoDB通过MVCC实现了可重复读隔离级别,事务开启之后多次执行同样的select,执行的结果都会是同样的数据。
我们看个例子:
如上图所示,有两个事务A、B,一开始table1表里就2条数据,事务A也确实查到了2条,在A第一次查完之后,事务B插入了一条数据,此时table1表里会有3条数据,事务A再次查询还是只能查到2条数据。这就是MVCC保证了在同一事务中,查询的结果是一样的。
也正因为有事务隔离级别,所以不同的事务在同一时间下,查询的表内数据会是不一致的,以此InnoDB是没办法像MyIsam那样,在表里单纯的加个字段来存储表数据行数的。
3 回到正题,count()括号里可以放置各种字段,甚至是非字段,那么他们都有什么区别呢? count方法的大原则是server层会从innodb存储引擎里读来一行行数据,并且只累计非null的值。但这个过程,根据count()方法括号内的传参,有略有不同。
(1) count(*) server层拿到innodb返回的行数据,不对里面的行数据做任何解析和判断,默认取出的值肯定都不是null,直接行数+1。
(2) count(1) server层拿到innodb返回的行数据,每行放个1进去,默认不可能为null,直接行数+1。
(3) count(某个列字段) 由于指明了要count某个字段,innodb在取数据的时候,会把这个字段解析出来返回给server层,所以会比count(1)和count(*)多了个解析字段出来的流程。
如果这个列字段是主键id,主键是不可能为null的,所以server层也不用判断是否为null,innodb每返回一行,行数结果就+1.如果这个列是普通索引字段,innodb一般会走普通索引,每返回一行数据,server层就会判断这个字段是否为null,不是null的情况下+1。当然如果建表sql里字段定义为not null的话,那就不用做这一步判断直接+1。如果这个列没有加过索引,那innodb可能会全表扫描,返回的每一行数据,server层都会判断这个字段是否为null,不是null的情况下+1。同上面的情况一样,字段加了not null也就省下这一步判断了。 现在应该对他们的执行效率有数了吧
大概如下:
count(*) = count(1) > count(主键id) > count(普通索引列) > count(未加索引列)
所以说count(*)是最快的
贝叶斯优化方法 目录 贝叶斯优化方法历史优点与其他方法的不同之处步骤理论推导过程高斯过程选择下一次采样点计算步骤 结构图Python示例代码数组说明计算过程 历史 贝叶斯优化方法(Bayesian optimization method)起源于1960年代,主要用于实验设计和高效参数调整。在贝叶斯优化方法出现之前,常用的优化方法包括网格搜索、随机搜索、演化算法等。这些方法普遍需要进行大量的实验才能得到最佳超参数,比较耗时耗力。贝叶斯优化方法则采用贝叶斯思想,通过不断探索各种参数组合的结果,根据已有信息计算期望值,并选择期望值最大的组合作为最佳策略,从而在尽可能少的实验次数下达到最优解。
优点 相对于传统的优化方法,贝叶斯优化方法具有以下优点:
高效:通过智能地选择下一次实验的参数,减少了实验的次数,提高了效率。准确:对于非凸优化问题,可以精确地找到全局最优点。可扩展性:可以应用于各种领域,如深度学习、计算机视觉、自然语言处理等。 与其他方法的不同之处 与其他优化方法相比,贝叶斯优化方法通过建立一个高斯过程来表示未知函数,并利用加权期望的方式选择下一次采样点。这与其他优化方法如梯度优化、随机搜索等不同。
步骤 贝叶斯优化方法的主要步骤包括:
建立高斯过程选择下一次采样点(即参数组合)进行实验并更新高斯过程重复步骤2-3,直到达到最大迭代次数或满足终止条件 理论推导过程 高斯过程 假设 f ( x ) f(x) f(x)为一个任意的函数,其中 x x x为输入, y = f ( x ) y=f(x) y=f(x)为输出。在贝叶斯优化方法中,我们假设 f ( x ) f(x) f(x)由高斯过程生成:
f ( x ) ∼ G P ( m ( x ) , k ( x , x ′ ) ) f(x) \sim GP(m(x), k(x, x^{\prime})) f(x)∼GP(m(x),k(x,x′))
1、Window是显示屏上独立的本机窗口,它独立于其它容器,Window的两种形式是() A、 Frame个Dialog
B、 Panel和Frame
C、 Container和Component
D、 LayoutManager和Container
答案: A
解析:Window的两种形式是Frame个Dialog
2、java.awt包提供了基本的java程序的GUI设计工具,包含控件、容器和() A、 布局管理器
B、 数据传送器
C、 图形和图像工具
D、 用户界面控件
答案: A
3、所有Swing构建都实现了()接口 A、 ActionListener
B、 Serializable
C、 Accessible
D、 MouseListener
答案: C
解析:所有Swing构件都实现了Accessible接口,提供对可存取性的支持,使得辅助功能 (如屏幕阅读器)能够方便地从Swing构件中得到信息。
4、下面JFrame类的常用操作方法中,哪个方法是用来设置组件的显示位置的?() A、 public void setSize(int width,int height)
B、 public void Background(Color c)
C、 public void setLocation(Point p)
D、 public void setVisiable(boolean b)
答案: C
5、以下不属于容器的是() A、 Window
B、 Frame
C、 Panel
D、 Lable
嘿,你好啊!PHP中的函数就像是一个超级有技能的工人,可以帮助我们更快更好地完成任务。它们就像是一个个工具箱,里面装满了各种用途的工具。
函数可以执行各种任务,比如计算两个数的和、检查字符串是否包含某个字符、读取文件等等。使用函数可以让我们的代码更加简洁、易于维护,也可以避免重复编写相同的代码。
如何使用函数呢?很简单,就像打电话一样。首先,你需要知道函数的名称和参数,然后通过调用函数来执行它。下面是一个简单的例子:
<?php function add($a, $b) { return $a + $b; } $result = add(3, 5); echo $result; // 输出 8 ?> 在这个例子中,我们定义了一个名为add的函数,它接受两个参数a和b,并返回它们的和。然后,我们通过调用add(3, 5)来执行函数,并将结果存储在变量$result中。最后,我们使用echo语句来输出结果。
当然,PHP中的函数还有许多其他用途。有时候,你需要定义一个函数来处理某些特定的任务,或者将某些功能封装成一个函数以便在代码中多次使用。下面是一个简单的例子:
<?php function sayHello($name) { echo "Hello, " . $name . "!"; } sayHello("John"); // 输出 "Hello, John!" ?> 在这个例子中,我们定义了一个名为sayHello的函数,它接受一个参数$name,并输出一个问候语。然后,我们通过调用sayHello(“John”)来执行函数,并将结果输出到屏幕上。
总之,PHP中的函数就像是一个个工具箱,可以帮助我们更快更好地完成任务。使用函数可以让我们的代码更加简洁、易于维护。
使用函数还可以让我们的代码更加模块化和易于扩展。如果你在编写一个大型的PHP应用程序,那么使用函数可以帮助你更好地组织和管理代码,并且可以轻松地添加、修改或删除某些功能。
在PHP中,你可以定义两种类型的函数:全局函数和静态函数。全局函数是在整个脚本中都可以使用的函数,而静态函数则是在类中定义的函数,只能在该类中使用。下面是一个简单的例子:
<?php function globalFunction() { // 全局函数 } class MyClass { static function staticFunction() { // 静态函数 } } ?> 在这个例子中,我们定义了一个全局函数globalFunction和一个静态函数staticFunction。全局函数可以在整个脚本中都可以使用,而静态函数只能在该类中使用。
还有一点需要注意的是,在PHP中定义函数时,你需要遵循一定的语法和规范。函数名称应该使用驼峰式命名法,并且应该尽可能描述性地命名。函数的参数也应该描述性地命名,并且应该有一个有意义的默认值。函数的返回值也应该明确地定义,并且应该有一个返回语句。
一、初识 在MediaPipe中进行人脸特征点检测,可以使用其提供的预训练模型和库。MediaPipe提供了一个名为"FaceMesh"的模型,用于实时检测人脸的468个特征点。
以下是使用MediaPipe进行人脸特征点检测的基本步骤:
安装MediaPipe:首先,你需要安装MediaPipe框架。
设置输入和输出:确定输入数据的来源,可以是摄像头、视频文件或图像。同时,设置输出来存储检测到的人脸特征点。
创建MediaPipe图:使用MediaPipe框架的API,创建一个图来加载"FaceMesh"模型并处理输入数据。
运行图:通过将输入数据传递给MediaPipe图的输入节点,并通过图的输出节点获取结果,运行图进行人脸特征点检测。
处理结果:从输出节点获取检测到的人脸特征点结果,并对其进行进一步的分析或应用程序集成。
MediaPipe的"FaceMesh"模型可以自动定位和识别出人脸图像中的关键特征点,如眼睛、眉毛、鼻子、嘴巴等。我们可以根据需要选择使用特定的特征点。
此外,MediaPipe还提供了其他功能和模型,例如手部检测、姿态估计等。
二、人脸特征点检测 (1)安装环境
pip install opencv-python pip install mediapipe==0.8.3.1 (2)OpenCV加载视频
代码:
import cv2 import mediapipe as mp import time cap = cv2.VideoCapture("Video/6.mp4") # 加载视频 pTime = 0 while True: success, img = cap.read() imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 帧数 cTime = time.time() fps = 1 / (cTime - pTime) pTime = cTime cv2.putText(img, f'FPS:{int(fps)}', (20, 70), cv2.FONT_HERSHEY_PLAIN, 3, (0, 255, 0), 3) cv2.
客户 · 介绍
北京度量科技有限公司专注于自主研发、生产制造和销售光学三维动作捕捉系统。公司现已获得专精特新企业、高新技术企业、瞪羚企业、展翼企业等一系列称号。
度量的核心产品——NOKOV(度量)光学三维动作捕捉系统,采用高性能红外摄像头捕捉反光标识点,采集并生成精准、实时的动作信息,可广泛应用于无人机室内定位追踪、多智能体协同控制、虚拟数字人、军事军工等领域。
客户 · 遇到的问题 日常工作中,往往涉及到各种各样的物料采购、活动经费付款、员工报销等审批单据,为了应对大量的审批单据,财务部门选择企业微信作为OA审批系统,但OA系统和网银系统间无法打通,实收实付环节需要财务人员登录到网银系统中手动输入付款信息进行支付。
随着企业不断发展,业务销量不断提高,公司每月的报销、采购等付款审批票据达上百张,依靠人工已无法支撑对企业费用精细化的管理需求,长时间的人工运转存在诸多问题:
时间成本高:每天需要花费数小时来录入支付数据,耗费大量的时间和人力
错误率高:手动录入数据容易出现误差,例如输入错误的金额、银行账号等,可能需要进行多次审核和修改,增加了额外的工作量。
审核效率低:手动录入支付信息需要经过多重审核流程,包括计算金额,核对账户等,减缓整个支付流程的速度。
作为高新技术企业,度量科技当然希望在财务管理上同样实现“数智化”,但如果想自己研发软件连接网银系统,往往伴随着高昂的研发成本和大量的精力去不断地调试与开发。即便完成了系统对接,但是使用的场景随时可能会调整,使用的软件系统可能会替换。
那么到底有没有更便捷、效率更高、成本更低,同时也能满足企业需求的方案呢?
集简云 · 解决方案 集简云是一款超级软件连接器,通过集简云无需任何开发就可以将企业微信OA审批功能与招银云直联进行对接,只需要在集简云搭建一个数据流程即可让整个工作流程实现自动化运转,让系统之间的数据实现自动同步,操作简单,成本低,而且无需代码开发。
“企业微信OA审批通过后,付款信息自动同步至网银待办”自动化方案如下:
步骤流程
步骤1:触发流程【企业微信(代开发)-当有审批状态变更时】
步骤2:执行动作【招商银行云直联-发起单笔企业支付】
点击使用此模板
实现效果:员工在企业微信发起付款审批,审批通过时,即可将所需要付款要素(付款账号、付款人信息、付款金额等)自动同步至网银待办,财务人员在网银复核通过后即完成支付,无需人工手动复制,省时省力,大大提高财务人员的工作效率。
客户反馈 通过集简云实现了与招银云直联的连接,为企业带来了实打实的业财资金一体化的便利,使用此自动化流程后,各项付款流程变得更加高效和精确,不再需要手动录入付款数据,也不用再担心出现丢失或错误的付款单据,真正做到了:
账务信息银企同步,实时反映账户资金变化状况,便于企业财务监控和决策。
实现资金流与业务流匹配,资金更安全,降低资金风险,提升内控的有效性。
减少财务人员手工操作环节和核算工作量,有效减少出错率,提高工作效率。
在数字化时代下,“数智化”无疑是让财务工作自动化管理最好的抓手,集简云帮助企业实现交易数据在系统间有效传递,为后续决策提供有效支持,帮助企业实现一体化管理!
Q
关于集简云
ABOUT JIJYUN
集简云:让连接更简单
集简云是一款超级软件连接器,无需开发,无需代码知识就可以轻松打通数百款软件之间的数据连接,构建自动化与智能化的业务流程。通过自动化业务流程,每月可节省您数百甚至数万小时的人工成本。
600+集成应用
集简云平台
,赞2
集简云介绍
集简云开放平台:让您的系统拥有与600+款软件连接的能力
集简云开放平台现开启“优质应用招募计划”,诚邀您参加!免费入驻集简云应用中心,让您的产品拥有与600+款软件连接的能力!
前100位入驻将获得专属技术支持,助您快速完成上架!
百万级市场曝光,帮您获取更多商机!
如您资源紧张无排期,也可将您的产品介绍、接口文档及测试账号发送至chengguo@email.jijyun.cn,评估后我们将按照排期顺序安排接入。如需了解更多,请扫码联系我们
import pandas as pd xls_path = r'C:\Users\xxx\Desktop\面经_搜索_socket.xlsx' key_word = 'socket' output_file = r'E:\myfile.txt' items_per_file = 20 df = pd.read_excel(xls_path, sheet_name='datatable') def hasKeyWord(line): return key_word in line.lower() line_cnt = 0 node_idx = 0 with open(output_file, 'w', encoding='utf-8') as f: f.write(str(int(node_idx)) + '\n') for index, row in df.iterrows(): lines = row['正文'].split("\n") flt_lines = filter(hasKeyWord, lines) for line in flt_lines: outLine = line + '\n\t\t链接\n\t\t\t' + row['链接'] + '\n' outLine = outLine.lstrip() outLine = '\t' + outLine print(outLine) f.
新人第一次发帖,也是根据自己在公司遇到的问题去找解决办法,如有不妥或遗漏欢迎各位大佬指正或建议,在这万分感谢!!!!!
小菜只因(本人)需要运行vue项目,在运行npm install遇到的报错情况如下
在查阅各种资料后还是没有结果,在这里参考了几位大佬的博文
npm install报error code 1
npm ERR! git dep preparation failed
npm install 失败解决方案之一
在这里感谢几位大佬提供的帮助
下面讲本只因是如何解决这个问题的
1.请确保你的node -v和npm -v还有cnpm -v是可以成功的
2.使用以下指令进行清除
npm cache clean --force
3.删除以下的文件
(1)在vue项目的文件目录中,删除node_modules文件夹
(2)在vue项目的文件目录中,删除package-lock.json文件夹
(3)在C:\Users\Administrator\AppData\Roaming(也有人可能是C:\用户\Administrator\AppData\Roaming)下删除npm文件夹
注意!不是nodejs安装目录下的npm文件夹
4.使用淘宝镜像
npm install cnpm -g --registry=https://registry.npm.taobao.org
5.在vue项目目录下运行cmd
cnpm install
npm install
这里本只因只有一次npm install指令是成功过的
6.不管有没有报错,去到vue目录下的文件夹查看,发现模块已经安装好了
7.使用npm run serve运行,成功启动
同样给项目打包也是成功的
1. 什么是单元测试 (1)单元测试环节:
测试过程按照阶段划分分为:单元测试、集成测试、系统测试、验收测试等。相关含义如下:
1) 单元测试: 针对计算机程序模块进行输出正确性检验工作。
2) 集成测试: 在单元测试基础上,整合各个模块组成子系统,进行集成测试。
3) 系统测试: 将整个交付所涉及的协作内容都纳入其中考虑,包含计算机硬件、软件、接口、操作等等一系列作为一个整体,检验是否满足软件或需求说明。
4) 验收测试: 在交付或者发布之前对所做的工作进行测试检验。
单元测试是阶段性测试的首要环节,也是白盒测试的一种,该内容的编写与实践可以前置在研发完成,研发在编写业务代码的时候就需要生成对应代码的单元测试。单元测试的发起人是程序设计者,受益人也是编写程序的人,所以对于程序员,非常有必要形成自我约束力,完成基本的单元测试用例编写。
(2)单元测试特征:
由上可知,单元测试其实是针对软件中最小的测试单元来进行验证的。这里的单元就是指相关的功能子集,比如一个方法、一个类等。值得注意的是作为最低级别的测试活动,单元测试验证的对象仅限于当前测试内容,与程序其它部分内容相隔离,总结起来单元测试有以下特征:
1) 主要功能是证明编写的代码内容与期望输出一致。
2) 最小最低级的测试内容,由程序员自身发起,保证程序基本组件正常。
3) 单元测试尽量不要区分类与方法,主张以过程性的方法为测试单位,简单实用高效为目标。
4) 不要偏离主题,专注于测试一小块的代码,保证基础功能。
5) 剥离与外部接口、存储之间的依赖,使单元测试可控。
6) 任何时间任何顺序执行单元测试都需要是成功的。
2. 为什么要单元测试 (1)单元测试意义:
程序代码都是由基本单元不断组合成复杂的系统,底层基本单元都无法保证输入输出正确性,层级递增时,问题就会不断放大,直到整个系统崩溃无法使用。所以单元测试的意义就在于保证基本功能是正常可用且稳定的。而对于接口、数据源等原因造成的不稳定因素,是外在原因,不在单元测试考虑范围之内。
(2)使用 main 方法进行测试:
@PostMapping(value="/save") public Map<String,Object> save(@RequestBody Student stu) { studentService.save(stu); Map<String,Object> params = new HashMap<>(); params.put("code",200); params.put("message","保存成功"); return params; } 假如要对上面的 Controller 进行测试,可以编写如下的代码示例,使用 main 方法进行测试的时候,先启动整个工程应用,然后编写 main 方法如下进行访问,在单步调试代码。
public static void main(String[] args) { HttpHeaders headers = new HttpHeaders(); headers.
文章目录 一、Yolov5网络结构1.1 Input1.2 Backbone1.2.1 Conv模块1.2.2 C3模块1.2.3 SPPF模块 1.3 Neck1.4 Head1.4.1 head1.4.2 目标框回归1.4.3 目标的建立1.4.4 NMS(Non-Maximum Suppression) 二、损失函数2.1 分类损失2.2 置信度损失2.3 定位损失 Location loss 参考文献 yolov5于2020年由glenn-jocher首次提出,直至今日yolov5仍然在不断进行升级迭代。 Yolov5有YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x四个版本。文件中,这几个模型的结构基本一样,不同的是depth_multiple模型深度和width_multiple模型宽度这两个参数。
一、Yolov5网络结构 yolov5主要分为以下几部分:
Input:输入Backbone:New CSP-Darknet53Neck:SPFF和New CSP-PANHead(prediction):Yolov3 head yolov5 6.0版本的主要架构如下图所示:
Yolov5网络结构图 1.1 Input YOLOv5在输入端Input采用了Mosaic数据增强,参考了CutMix数据增强的方法,Mosaic数据增强由原来的两张图像提高到四张图像进行拼接,并对图像进行随机缩放,随机裁剪和随机排列。使用数据增强可以改善数据集中,小、中、大目标数据不均衡的问题。
Mosaic数据增强的主要步骤为:
MosaicCopy pasteRandom affine(Scale, Translation and Shear)MixupAlbumentationsAugment HSV(Hue, Saturation, Value)Random horizontal flip.
采用Mosaic数据增强的方式有几个优点:
丰富数据集:随机使用4张图像,随机缩放后随机拼接,增加很多小目标,大大丰富了数据集,提高了网络的鲁棒性。减少GPU占用:随机拼接的方式让一张图像可以计算四张图像的数据,减少每个batch的数量,即使只有一个GPU,也能得到较好的结果。同时通过对识别物体的裁剪,使模型根据局部特征识别物体,有助于被遮挡物体的检测,从而提升了模型的检测能力。 1.2 Backbone 在Backbone中,有Conv,C3,SPFF是我们需要阐明的。
1.2.1 Conv模块 Conv卷积层由卷积,Batch Normalization和SiLu激活层组成。
batch normalization具有防止过拟合,加速收敛的作用。
SiLu激活函数是Sigmoid 加权线性组合,SiLU 函数也称为 swish 函数。
公式:silu(x)=x∗σ(x), where σ(x) is the logistic sigmoid.