思路:首先在小程序端通过wx.login向微信服务器发送请求拿到code,然后把这个code发送到我方服务器,我方服务器拿到前端发来的code之后,携带code, appid,secret,grant_type:'authorization_code这四个参数向微信服务器'https://api.weixin.qq.com/sns/jscode2session,这个接口发送请求拿到openid与session_key,并通过openid进行查询数据库里面这条信息看看有没有手机号,有的话就是老用户,并把这条信息发给前端,如果没有手机号,就说明是新用户,然后后端并把openid发送给前端,还携带一个isnew:true,小程序端按照这个判断获取手机号的按钮是否显示,前端在页面定义一个变量进行存一下这两个参数
接下来是新用户的思路因为是新用户,传过去的isnew:true,所以在小程序界面有两个按钮,一个是用来获取用户信息 wx.getUserProfile,一个是用来获取手机号<button wx:if="{{avatarUrl}}" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">绑定手机号</button>,用来获取用户信息先显示,因为他通过isnew:true判断是否显示,获取用户信息之后,变量存一下,这时候获取手机号是通过用户信息是否存在来控制显示,这时候获取手机号的按钮就会显示,在点击获取手机号按钮的时候,会传一个code,这个code与wx.login不一样,这时候前端调用一个接口,把用户信息与code,openid发给后端,后端接收到这些参数之后,首先通过这个接口获取access_token,需要两个参数还是appid与secret
`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret} 获取到access_token之后通过它为参数,并携带第二个code进行获取用户手机号,调用下面这个接口
const phoneUrl = `https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=${access_token}` const { data } = await axios.post(phoneUrl,{ code }) 此时拿到用户手机号.通过这个手机号去数据库查一下数据,要是存在就说明这个手机号已经绑定,要是不存在就把,手机号,openid,用户信息存到数据库里面,存完之后在取一下这条数据返回给前端,前端拿到用户信息,把头像与昵称进行渲染
拉新实现原理:
就是在小程序第二次返回后端的数据加上分享人id,与活动id,然后后端进行入库,通过用户表里面的分享人id,与活动id,进行返现
被灰产薅羊毛的漏斗
被灰产薅羊毛的漏斗就是,把手机号返回给了前端,前端通过调用接口进行入库,这样只要改变手机号,就会创建新用户进行返现,只要把手机号存在后端,在后端进行存库就解决了
后端代码
const Router = require("koa-router"); const user = require('../db/model/userModel') const {secret} = require("../config/config") const jsonWebToken = require("jsonwebtoken") const axios = require('axios') const router = new Router({prefix:'/user'}) router.post('/wxlogin',async (ctx)=>{ // 从body获取用户发送的参数 let {code} = ctx.request.body //这里的code是小程序前端通过wx.login获取到code,传到后端 // 请求微信的服务器 用code 换取opendid 用户在微信的主键id let url ='https://api.
A product information modeling framework for product lifecycle management Article in Computer Aided Design November 2005
Authors: S. J. Fenves, Ram D Sriram,R. Sudarsan, F. Wang
概述 产品生命周期管理(PLM)的理念承诺将产品生命周期所有阶段产生的所有信息无缝集成到组织内管理和技术层面的每个人以及关键的供应商和客户。PLM系统是实现PLM概念的工具。因此他们需要提供上述信息的能力并需要确保产品数据的内聚性和可追溯性。
我们描述了一个基于NIST核心产品模型(CPM)及其扩展、开放装配模型(OAM)、设计-分析集成模型(DAIM)和产品族进化模型(PFEM)的产品表示框架。这些都是具有通用语义的抽象模型,可以将特定领域的特殊语义嵌入到适用于该领域的具体模型中。CPM代表产品的功能、形式、行为、物理分解和功能分解以及概念间的关系。CPM的扩展提供了一种将设计原理与具体产品结合的方法。OAM定义了一个系统级的概念模型和相关的分层装配关系。DAIM定义了产品的一个主模型和一系列称为功能模型的抽象模型(一个用于产品的每个领域特定方面)以及主模型和每个功能模型之间的两个转换(理想化和映射)。PFEM将展示扩展到产品及其产品族;它还扩展了设计的基本原理以兼容族进化的基本原理。
该框架旨在:(1) 兼容从最早的概念设计阶段(设计师定义产品的功能和性能)到整个生命周期结束过程中产品、设计原理、装配和公差信息;(2) 促进下一代CAD/CAE/CAM系统的语义互操作性;(3) 兼容产品族的演变。我们的框架与产品生命周期管理(PLM)的相关性在于,框架中的任何数据组件都可以直接通过PLM系统访问,从而提供对产品描述和设计原理的细粒度访问。
介绍 PLM通常被定义为“有效管理和使用企业知识资本的战略商业方法”[1]。PLM系统在管理公司产品的整个生命周期所有信息方面正得到越来越多的认可。全球竞争是许多组织采用PLM概念和实施PLM系统的关键驱动因素之一。PLM的概念旨在简化产品开发促进制造业的创新。因此PLM的概念是一种有效创造、管理和使用企业智力资本的战略商业方法,从产品的最初概念到它的退休。
即使在当前(2003年)的经济低迷时期,许多制造公司仍在投资PLM系统——今年的投资额高达23亿美元。我们认为这些公司愿意承担风险的原因是这些公司看到了PLM的潜力,它可以极大地提高他们的创新能力,让产品更快地进入市场并减少错误。根据行业分析师CIMdata的说法,“对于一个想要在当今和未来的全球市场取得成功的企业来说,PLM不是一个选择——它是竞争的必需品”[1]。
PLM系统的一个关键方面是其产品信息建模体系结构。 在这里构建软件工具的传统分层方法呈现出一个严重的潜在陷阱:如果PLM系统继续通过产品数据管理(PDM)获取产品信息,PDM系统反过来从计算机辅助设计(CAD)系统获得几何描述,那么可用的信息将只会是后面这些系统支持的信息。
本文提出了一种向PLM系统提供信息的不同方法:一个产品信息的单一PLM系统支持框架可以在整个产品生命周期内访问、存储、服务和重用所有产品信息。在简要讨论PLM概念和主要PLM系统架构和互操作性问题之后,提出了这个框架及其组件。
1.1 PLM的概念 PLM承诺将产品生命周期的所有阶段产生的所有信息无缝集成并提供给组织中的每个人以及关键的供应商和客户。制造商可以通过多种方式缩短推出新产品的时间。产品工程师可以在扩展的设计链上大大缩短实施和批准工程变更的周期。采购代理可以更有效地与供应商合作重复使用零部件。从生产线的细节到从质保数据或现场收集的信息中获取的零部件故障率,高管们可以对所有重要的产品信息进行高级查看。
由于PLM系统是从产品设计软件发展而来的,公司管理层倾向于将PLM的概念委托给工程主管而这些主管传统上负责自己的技术推广。虽然这种不干预政策适用于选择点解决方案(例如CAD工具)但它不适用于公司范围内的集成平台。不同的业务功能以不同的方式生成和处理产品数据。例如制造和工程部门使用的材料清单(构成产品的零部件和组件清单)与采购部门不同,采购部门也依赖已批准的供应商清单和目录。
要使PLM概念获得成功,需要解决诸如建立数据标准和设计全公司范围的集成架构等问题,以便使以前分散的信息能够以可用的格式提供给个人。这样不同部门的人就有能力做出关键的决定,比如在产品设计阶段引入什么产品或在产品设计阶段包含什么特性而不是在零部件采购阶段甚至制造过程的中间阶段。
1.2 PLM系统结构和互用性问题 PLM系统是帮助企业实现PLM概念的工具。关于PLM系统的一个主要问题是:“什么构成了PLM系统的功能?”。完整的PLM系统功能可以通过图1所示的具体组件实现。这些是:(1)信息技术基础架构;(2)产品信息建模体系结构;(3)开发工具箱和环境;(4)一套商业应用程序。IT基础架构是包括硬件、软件和互联网技术、底层表达和计算语言以及分布式对象和组件的基础。
(图1. PLM系统架构概念图) 产品信息建模体系结构包括产品本体和互用性标准。开发工具包和环境提供了构建业务应用程序的方法,这些业务应用程序提供了初始功能并增强和扩展了PLM概念的功能,包括内核(例如几何、数学)、可视化工具、数据交换标准和机制以及数据库。商业应用程序提供了处理企业智力资本的PLM功能。
在2003年举行的两个最近的NIST研讨会中,人们试图描述一个全生命周期管理和产品数据集成的架构[4,5]。正如研讨会总结报告工作草案中所描述的那样,该架构旨在为各种信息技术和计算机科学概念的应用提供路线图,这些概念可能用于构建和运行支持完整产品生命周期[6]的PLM系统。
研讨会中考虑的结果PLM系统的应用的涉及领域从复杂工程到订单系统,如航空航天和国防工业。该体系结构定义了产品数据的两类视图:语义视图定义了信息解释和使用的约束;而基础结构视图则同这些数据在使用过程和工具中的编码和组成相关。关于这两类视图,工作草案中讨论了可能适用的技术。
在NIST规划会议上表达的一些主要关切是产品数据的凝聚力和可追溯性。结论是当前的数据管理实践没有为数据内聚和可追溯性提供足够的支持。然而当被视为信息系统的属性时,内聚和跟踪能力变为一个复杂和抽象的目标。信息技术不能直接解决这些问题,相反某些特性有助于解决此问题。在内聚性和追踪能力的主要组成属性中确定的是跨观点的联想性和逻辑一致性[6]。
PLM系统构成了企业软件层的顶点并且经常被实施,因此它们依赖于子系统来获取和传播详细的信息。PLM系统倾向于将管理描述产品自身信息的任务委托给产品数据管理(PDM)系统。此外在许多公司里只有计算机辅助设计(CAD)系统生成的产品的几何描述是直接管理的,在这些公司里PDM系统依赖于CAD系统来管理产品描述。
上述对PLM和子软件系统的分割导致了三个缺点。首先,虽然PLM系统可以跟踪产品从概念到退役的整个生命周期的变化,但描述实际变化的信息只能通过附属的PDM系统找到而变化的原因可能不会以计算机可处理的形式记录在任何地方。因此有必要直接从PLM系统访问产品描述及其设计原理而不需要透过中间软件层。第二,CAD形式的表达(几何)只出现在设计的后期阶段(在几何被分配到产品概念之后);因此在产品的CAD表达被创建完成前PLM系统是没有用的。为了实现PLM概念的全部潜力,PLM系统需要与产品概念和构思的早期阶段使用的产品信息进行交互,在这个阶段设计师和规划师处理的是产品的功能和性能而不是它们的形式。第三,在产品生命周期的另一端,在制造、安装、操作、维护和最终的退役过程中,产品的形式变化很小而在这些生命周期阶段收集了很多关于产品行为的信息。在这里只与产品的CAD表达联系在一起的PLM系统是没有用的;在生命周期的后期,PLM系统需要与产品行为信息进行交互。
PLM系统仍处于非常早期并不断变化的阶段之中。许多专有系统和接口的开发将导致额外的互用性问题。因此我们需要国家和国际的共同努力来制定标准,以缓解PLM系统未来的互用性问题。在美国国家标准与技术研究所的产品工程项目中,我们的目标是建立一个基于语义的、经过验证的产品表示方案,作为一种标准支持当前和下一代计算机辅助设计(CAD)系统之间以及CAD系统和其他生成和使用产品的系统之间的无缝互用性。作为这项工作的一部分,我们正在制定一个框架和一个表示方案以解决上述问题。
本文的重点是图1所示的PLM系统架构的第二部分(即产品信息建模架构)。本文的目的是论证产品工程项目的方法可以:(1)支持所有PLM信息需求;(2)克服了上述PLM软件划分的三个缺点。本文的组织结构如下:在第2节中我们将介绍NIST信息建模框架。在第3节中我们描述了NIST信息建模框架的四个组件。进一步的研究问题将在第4节中讨论。第五部分给出结论。
2. NIST信息建模框架 异构建模系统之间的产品、零件和装配信息交换是协同设计和制造的关键。产品几何的交换标准被广泛使用。然而在开发关于设计信息和产品知识的标准表达方面,我们做得很少。NIST信息建模框架旨在解决这个问题。
NIST正在开发的概念产品信息建模框架具有以下关键属性:(1) 它基于形式语义并最终将由适当的本体支持以允许自动推理;(2) 它是通用的:它处理的概念实体,如产品和特征,而不是具体的产品如电机、泵或齿轮;(3) 它是一个丰富多样的产品信息库,包括产品描述中目前尚未纳入的方面;(4) 旨在促进在信息较少的环境中无法实现的新应用和流程的开发;(5) 它包含了基本设计原理的明确表述,被认为与产品描述本身一样重要;(6) 对于通用表达方案与产品级互用性框架进行转换或交互有规定。信息建模框架的实现将:(1) 在设计过程的所有阶段提供所有产品信息的通用存储库;(2) 使用单一、统一的信息交换协议向PLM系统及其附属系统提供所有产品描述信息;(3) 支持CAD、CAE、CAM和其他需要高带宽、无缝信息交换的相关系统之间的直接互操作性。
今天写代码遇到了@AfterReturning(returning = ‘var’)
查了很多网络资料都只说这个是方法返回值,并没有说是什么方法返回值,这里坐下代码解释
// 被切方法 @RestController @RequestMapping("/show") public class ControllerTwo { @RequestMapping("/test") @Hh(status = "2") public String test(){ return "我是嫩爹"; } } // 自定义注解 @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Hh { // 当前注解参数status 默认值0 String status() default "0"; } // 定义切面 @Aspect @Component public class MyAspect { // 该后置返回后触发切点是被@Hh注释的方法 @AfterReturning(pointcut = "@annotation(com. example.aop.Hh)",returning = "result") public void show(JoinPoint joinPoint, Object result){ // 获取注解 MethodSignature signature = (MethodSignature)joinPoint.getSignature(); // 获取当前方法被Hh注解注释的注解对象 Hh annotation = signature.
detect_image
#---------------------------------------------------# # 检测图片 #---------------------------------------------------# def detect_image(self, image): start = timer() image_shape = np.array(np.shape(image)[0:2]) crop_img, x_offset, y_offset = letterbox_image(image, (self.model_image_size[0], self.model_image_size[1])) photo = np.array(crop_img, dtype=np.float64) # 图片预处理,归一化 photo = preprocess_input(np.reshape(photo, [1, self.model_image_size[0], self.model_image_size[1], 3])) preds = self.ssd_model.predict(photo) # 将预测结果进行解码 results = self.bbox_util.detection_out(preds, confidence_threshold=self.confidence) # print(results) if len(results[0]) <= 0: return image, [] # 筛选出其中得分高于confidence的框 det_label = results[0][:, 0] det_conf = results[0][:, 1] det_xmin, det_ymin, det_xmax, det_ymax = results[0][:, 2], results[0][:, 3], results[0][:, 4], results[0][:, 5] top_indices = [i for i, conf in enumerate(det_conf) if conf >= self.
S32K3学习笔记01-S32K3 RTD【MCAL&SDK】的使用和环境搭建 1 前言2 准备工作3 安装3.1 安装EB Tresos3.2 安装MCAL3.2 安装S32DS 4 SDK开发示例4.1 SDK包安装4.2 导入一个Demo4.3 新建一个工程 5 MCAL开发示例5.1 MCAL软件包组成5.2 通过EB配置MCAL并生成代码5.3 编译配套的MCAL Demo5.4 在S32DS中使用PE仿真器调试5.5 使用Lauterbach调试 end 1 前言 NXP最近又推出了新的GPIS系列MCU S32K3,也就是S32K1的升级版,虽然是升级版,但是性能提升的不是一点半点,那是贼凶啊,接下来一段时刻,我就要好好学习一下这个MCU,并且把我的学习过程写点笔记,分享给大家,欢迎大家建议和纠错。
这第一篇就介绍一下开发环境的搭建,在这里我使用S32DS进行SDK方式的开发,配合EB tresos进行MCAL开发。
简单的来说就是:EB tresos可以为MCAL开发提供图形化配置界面,而S32DS则为SDK开发提供图形化配置界面。
这篇文件介绍的方式流程如下:
SDK开发流程为:
在S32DS配置外设 在S32DS编译 在S32DS中调试 使用其他调试工具 MCAL开发流程
在EB配置MCAL 使用编译器编译 在S32DS中调试 其他调试工具 2 准备工作 准备工作当然就是下载一些东西喽。需要下载三个东西,分别是NXP官方的调试IDE,配置MCAL的EB tresos以及S32K3的RTD软件包。
RTD是什么,Real-time Driver,在S32K1时代,MCAL和SDK是两套不同的软件包,但是到了S32K3,就把两者集成了一下,MCAL和SDK共用一套代码,也就是RTD,意思其实就是这两个软件包里面的底层代码都是一样的。简单的来说,现在K3的MCAL就是在SDK的底层基础上封装了一层符合AUTOSAR标准的接口层,RTD的具体结构框架如下图:
图中High Level Interface指的就是符合AUTOSAR的MCAL接口层,而Low Level Interface就是传统意义上比较高效的SDK底层接口层。
如果有NXP的授权账号,就可以在下面链接下载到这些东西的安装包,登录账号后,点击MY_NXP:
点开 Software Licensing and support, 找到S32K3 Standard Software,点开就可以看到这三个东西的下载链接了:
①对于EB tresos的下载,需要记住标记的激活码。
②对于MCAL(SDK),就下载最新的就好了,这里我选择是1.0.0。
如果是MCAL开发的话,只需要下载MCAL安装包,如果是SDK开发的话,只需要下载SDK软件包。
③对于S32DS,可以看到这个版本需要S32DSV3.4,所以需要下载V3.4版本的S32DS就好了,另外还需要下载S32K3的支持补丁包。
下面就是一顿漫长的等待,等所有东西都下载好了之后,有如下东西:
背景 最近解决了python版本为啥执行不了trtexec.exe生成的trt文件的bug,是环境里pytorch自带的cuda和trt的冲突,卸了重装了CPU版本就OK了。但是在我尝试解决的过程中出现了问题,环境有点玩坏了,之后用trtexec.exe生成的engine直接摆烂,输出的全是NaN。行吧,那我在python环境里生成吧。但是网上搜索的onnx2tensorrt代码基本上是7代之前的,我之前试了一些跑不出东西来。今天参考官方代码,记录以下tensorrt8在python环境下如何把onnx转为engine。
参考 github代码
简单流程 实际上用不到官方代码的那么多,只需要选一部分就行了:
import tensorrt as trt import os EXPLICIT_BATCH = 1 << (int)(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) TRT_LOGGER = trt.Logger() def get_engine(onnx_file_path, engine_file_path=""): """Attempts to load a serialized engine if available, otherwise builds a new TensorRT engine and saves it.""" def build_engine(): """Takes an ONNX file and creates a TensorRT engine to run inference with""" with trt.Builder(TRT_LOGGER) as builder, builder.create_network( EXPLICIT_BATCH ) as network, builder.create_builder_config() as config, trt.OnnxParser( network, TRT_LOGGER ) as parser, trt.
背景 主要针对不同传感器的监测数据,从数据库实时获取,根据业务相关公式进行实时求解并绘制曲线图;
技术栈 开发语言:java+mdb
视图层:javafx,该语言包再jdk1.8以后已经独立出来,有需求的可自行查阅,jdk11以上javafx的使用方式。
框架:折线图框架用到的是开源框架jfreechart-1.5.0,模板所用框架freemarker-2.3.4
数据源:mdb格式,mysql数据源。
JFreeChart是JAVA平台上的一个开放的图表绘制类库。它完全使用JAVA语言编写,是为applications, applets, servlets 以及JSP等使用所设计。JFreeChart可生成饼图(pie charts)、柱状图(bar charts)、散点图(scatter plots)、时序图(time series)、甘特图(Gantt charts)等等多种图表,并且可以产生PNG和JPEG格式的输出,还可以与PDF和EXCEL关联。
程序部分界面 导出报告 导出报告用到了freemarker,该模板框架上手容易,比较适合报告格式固定的需求,例如本系统所需报告格式固定,只需要将word报告模板定义好,另存为xml格式,修改文件后缀为ftl即可。
package baogao; import com.aspose.words.Document; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import freemarker.template.TemplateExceptionHandler; import javafx.embed.swing.SwingFXUtils; import javafx.scene.Node; import javafx.scene.SnapshotParameters; import javafx.scene.image.WritableImage; import javax.imageio.ImageIO; import java.awt.image.RenderedImage; import java.io.*; import java.util.Locale; /** * @Auther * @Data 2021/8/2 22:19 * @TC */ public class WriteBaoGao { /** * 根据String模板生成HTML,模板中存在List循环 */ public static ByteArrayInputStream createHtmlFromStringList(WordBean wordbean) { FileWriter out = null; StringWriter writer = new StringWriter(); ByteArrayInputStream in = null; try { Configuration config=new Configuration(); config.
描述
在课程首页开发过程中,遇到一个问题,课程标签需要固定高度,宽度自适应,当时没有实现出来,现在从 同事@吴锋 处了解到,这个可以轻松实现,此处记录一下,下次遇到类似需求可以应用
控件:
AppCompatImageView(ImageView)
属性:
android:adjustViewBounds
属性值:
布尔值(boolean)
<attr name="adjustViewBounds" format="boolean" />
使用目的:
加载图片时,固定宽度,高度按比例自适应,或固定高度,宽度自适应
使用前提:
宽高有且仅有一个设置为 “wrapContent”
build.gradle中设置targetSdkVersion23以上
defaultConfig { targetSdkVersion 23 } 代码动态设置:
imgView.setAdjustViewBounds(true); 相关源码
@android.view.RemotableViewMethod public void setAdjustViewBounds(boolean adjustViewBounds) { mAdjustViewBounds = adjustViewBounds; if (adjustViewBounds) { setScaleType(ScaleType.FIT_CENTER); } } 这里可以看出,设置了 android:adjustViewBounds="true" 之后,scaleType默认就设置成了“ScaleType.FIT_CENTER”,所以在xml文件中不需要再设置scaleType了
END
目录
需求说明
组件设计
分页组件源码 TablePagination.vue
多级跨列组件 MultiColumn.vue
单元格渲染组件 GridRender.vue
集成结果 index.vue
组件示例
组件示例-基本使用
组件示例-分页配置
组件示例-关闭分页
组件示例-渲染原生标签
组件示例-渲染自定义组件
组件示例-多级跨列
组件示例-展示总计行
组件示例-开启单选功能
组件示例-开启复选功能
需求说明 1.列表支持复选/单选
2.列表支持分页展示
3.列表支持通过列数组配置进行渲染,可渲染原生标签以及自定义组件
4.列表支持多级表头展示
5.列表支持跨行展示
6.列表支持总计行展示
组件设计 根据业务功能将组件根据粒度拆分成分页组件,多级表头组件,单元格渲染组件以及最终集成组件入口
分页组件源码 TablePagination.vue 组件功能:提供分页布局样式,提供页码/页大小改变回调
<template> <div class="pagination-container"> <el-pagination :background="background" :current-page.sync="currentPage" :page-size.sync="currentPageSize" :layout="layout" :page-sizes="pageSizes" :total="total" v-bind="$attrs" /> </div> </template> <script> export default { name: 'Pagination', props: { total: { required: true, type: Number }, page: { type: Number, default: 1 }, pageSize: { type: Number, default: 10 }, pageSizes: { type: Array, default() { return [10, 20, 30, 50] } }, layout: { type: String, default: 'total, sizes, prev, pager, next, jumper' }, background: { type: Boolean, default: true }, autoScroll: { type: Boolean, default: true }, hidden: { type: Boolean, default: false } }, emits: ['change'], computed: { currentPage: { get() { return this.
目录
概念回顾
常用的数据类型
查看数据库
查看当前服务器中的数据库
查看数据库中包含的表
查看数据表的结构(字段)
查看mysql版本
SQL语句 创建及删除数据库和表(DDL)。
创建新的数据库
删除指定的数据库
编辑
创建新的表
DML 管理表中的数据记录
向数据表中插入新的数据记录
编辑
修改、更新数据表中的数据记录
在数据表中删除指定的数据记录
查询数据记录(DQL)
例2:查询指定数据
编辑 示例3:以列表方式竖向显示
例4:只显示前2行
例5:显示第一行后的前俩行
编辑修改表名和表结构(DCL)
修改表名
扩展表结构(增加字段)
修改字段(列)名,添加唯一键
编辑 删除字段
使用if判断,创建表并测试自增和填充(扩展)
数据表高级操作 克隆表——将数据表的数据记录生成到新的表中
先创建再导入
创建的时候同时导入
清空表——删除表内的所有数据
delete删除
truncate删除 创建临时表 总结
概念回顾 数据库 -》 数据表 –》行(记录):用来描述一个对象的信息
列(字段):用来描述对象的一个属性
常用的数据类型 int :整型 (用来定义整数类型的数据)
float :单精度浮点 4字节32位 (准确表示到小数点后六位)
double :双精度浮点 8字节64位
char :固定长度的字符类型 (用来定义字符类型数据)
varchar :可变长度的字符类型
text :文本
image :图片
decimal(5,2) :5个有效长度数字,小数点后面有2位 (指定长度数组)
Win10的【输入法切换快捷键】难用的要死,各种设置组合难以理解!!
对于输入法【我只需要一个中英文切换】的快捷键完全足够!其他的花里胡哨沙雕功能万年用不上一次,还和其他软件的经常有冲突,反而导致其他常用软件用起来很难受!!
特别是全屏游戏的时候,看不到输入法指示器是中文还是英文,各种组合键切来切去都切不到中文上真的极其蛋疼!!
好几次换电脑换系统都要查好久设置攻略!!!干脆自己记录!!
这里只保留了一个【ctrl+shift :切换中英文】,其他快捷键全部干掉!!!
设置方法如下:
备注:甚至不想用win10自带中文输入法的,下载个搜狗、百度等其他输入法都可以。
设置步骤:
按下win键输入【语言设置】点击【键盘】点击【输入语言热键】点击【高级键设置】选中【在输入语言之间】 —> 点击【更改按键顺序】,设置为【ctrl+shift】下面其他的,全部更改按键顺序,都关掉快捷键,如果关不掉就改为极其不常用的键位特别是下图最后一行:【中文(简体)输入法-输入法/非输入法切换】要改掉,我改成了ctrl+End。 如下图:
JDY-31蓝牙模块测试 一. 简介二. 测试所用模块三. JDY-31模块相关软件安装四. 测试五. 注意事项 原文链接:https://www.yourcee.com/newsinfo/2928859.html
一. 简介 JDY-31 蓝牙基于蓝牙 3.0 SPP 设计,这样可以支持 Windows、 Linux、 android 数据透传,工作频段 2.4GHZ,调制方式 GFSK,最大发射功率 8db,最大发射距离30 米,支持用户通过AT 命令修改设备名、 波特率等指令,方便快捷使用灵活。
二. 测试所用模块 JDY-31
点击图片购买 CH340模块
点击图片购买 三. JDY-31模块相关软件安装 CH340模块驱动安装与测试此处不再描述,可以看CH340测试那章,链接:
CH340测试
四. 测试 打开官方串口助手,按照自己需求配置相关指令
配置好后连接便可发送字符
到此JDY-31蓝牙模块测试完成,其它指令可以根据需要跟着手册去配置下。
五. 注意事项 打开软件搜索蓝牙前记得打开手机蓝牙尽量用官方串口助手,其它串口助手很可能出现异常USB转TTL模块记得TX RX交叉接线手机连接上蓝牙模块后在发AT指令串口助手是无反应的设置波特率后重新上电才会生效
USB转TTL(CH340)模块使用 一. 简介二. CH340模块驱动安装三. 测试四. 注意事项 原文链接:https://www.yourcee.com/newsinfo/2928561.html
一. 简介 点击图片购买 USB转TTL串口模块是一个非常实用的工具,可以测试模块的UART串口通信和通过单片机的UART接口给单片机等下载程序。
能够在电脑上的串口助手软件非常直观的显示出串口设备返回的数据以及发送相应的控制数据给串口设备。
常见的有CP2102、PL2303、FT232、CH340等串口芯片方案的USB转串口模块。以下以CH340串口模块为例,对其进行自检测试。
二. CH340模块驱动安装 1.将CH340模块插到电脑USB口,点开CH340驱动文件,双击这个EXE应用程序安装驱动
不同的芯片方案驱动不一样,使用前请查看手里的串口芯片型号。
2.点击安装
3.显示驱动安装成功代表驱动已安装,预安装成功可以认为是安装失败,直接显示安装失败要查下模块是否插好。
4.验证驱动是否正常,虽然安装成功,但是建议再去验证下这个驱动运行是否是正常的,进入设备管理器端口即可查验。右击左下角图标,点击设备管理器。
然后查看端口有没有出现CH340驱动,没有感叹号出现,如下图显示则表示安装成功,且驱动正常运行(括号内COM口编号根据实际情况变化,不同没关系)。
若要更改串口号则选中双击,弹出端口设置界面,进行设置
三. 测试 CH340模块测试,首先把模块TX RX两个引脚短接,插到电脑USB口,打开串口调试工具,按照图片上步骤操作即可。
若能自收自发数据,说明这个USB转TTL模块是好的
四. 注意事项 1.CH340模块插在USB2.0口时,5V排针输出口电流只有500MA左右,如过要接的功率比较的大模块建议接USB3.0或者给大功率模块单独外接电源且共地。
2. 切勿将VCC与GND短接,否则会烧坏模块,发现插上后模块灯不亮货模块发烫严重请立即拔掉检测是否接反或短路。
ST7735STFT屏幕的驱动 ST7735S简介TFT简介引脚说明程序驱动主要命令控制部分代码框架驱动展示总结 原文链接:https://www.yourcee.com/newsinfo/2928391.html
ST7735S简介 点击图片购买 ST7735S 是 262K 彩色图形型 TFT-LCD 的单芯片控制器/驱动程序。它由396条源线和162门线驱动电路组成。该芯片能够直接连接到外部微处理器,并接受串行外围接口 (SPI)、8 位/9 位/16 位/18 位并行接口。显示数据可以存储在 132 x 162 x 18 位的片上显示数据 RAM 中。它可以在没有外部操作时钟时执行显示数据 RAM 读写操作,以最大限度地降低功耗。此外,由于驱动液晶所需的集成电源电路,因此可以制造出组件较少的显示系统。
TFT简介 下方这款为 1.44寸 TFT彩屏,驱动IC使用ST7735S芯片,液晶驱动IC的SPI接口已经引出带板子外侧,以便使用杜邦线连接,为不想焊接的伙伴非常友好,此次驱动所使用的MCU为增强型51单片机STC12系列的MCU,如下图所示:
点击图片购买 引脚说明 PINParameterVCC5V/3.3V电源接入GND接地CS液晶屏片选信号,低电平使能RESET液晶屏复位信号,低电平复位A0液晶屏寄存器/数据选择信号,高电平:寄存器,低电平:数据SDASPI总线写数据信号SCKSPI总线时钟信号LED背光控制,高电平点亮,如无需控制则接3.3V常亮 程序驱动 流程框架如下
Created with Raphaël 2.3.0 初始化 编写显示函数 显示 结束 yes 主要命令控制 上图中我们可以看到如果想要软重启液晶屏的话,可以直接看我圈中的那一行,D/CX为0,意思就是需要选择写入命令,个人建议写SPI代码的时候传输数据代码选择高位在前,这样就可以直接使用HEX那一栏的数据,即直接使用MCU_write_TFT_Byte(0x01)即可,即可完成软重启。
上图中的三个命令2A,2B.2C,分别为配置地址选择区域和填色命令,在选择好地址写入对应的数据函数即可完成屏幕的取地址和填色处理。
部分代码框架 初始化代码,取自屏幕官方文档配置的驱动。
*配置好屏幕退出睡眠模式,配置帧速率等操作,如果有需求进行屏幕镜像的可以去参考文档中的36命令那里着重看下* void TFT_init() { TFT_BL=0;//背光关闭 TFT_RESET=0; TFT_delay500ms(); TFT_RESET=1; TFT_delay500ms(); MCU_write_TFT_Byte(0x11,TFT_COMMAND);//睡眠退出 TFT_delay500ms(); //ST7735R 帧速率 MCU_write_TFT_Byte(0xB1,TFT_COMMAND); MCU_write_TFT_Byte(0x01,TFT_DATA); MCU_write_TFT_Byte(0x2C,TFT_DATA); MCU_write_TFT_Byte(0x2D,TFT_DATA); MCU_write_TFT_Byte(0xB2,TFT_COMMAND); MCU_write_TFT_Byte(0x01,TFT_DATA); MCU_write_TFT_Byte(0x2C,TFT_DATA); MCU_write_TFT_Byte(0x2D,TFT_DATA); MCU_write_TFT_Byte(0xB3,TFT_COMMAND); MCU_write_TFT_Byte(0x01,TFT_DATA); MCU_write_TFT_Byte(0x2C,TFT_DATA); MCU_write_TFT_Byte(0x2D,TFT_DATA); MCU_write_TFT_Byte(0x01,TFT_DATA); MCU_write_TFT_Byte(0x2C,TFT_DATA); MCU_write_TFT_Byte(0x2D,TFT_DATA); MCU_write_TFT_Byte(0xB4,TFT_COMMAND);//列反转 MCU_write_TFT_Byte(0x07,TFT_DATA); //ST7735R Power Sequence MCU_write_TFT_Byte(0xC0,TFT_COMMAND); MCU_write_TFT_Byte(0xA2,TFT_DATA); MCU_write_TFT_Byte(0x02,TFT_DATA); MCU_write_TFT_Byte(0x84,TFT_DATA); MCU_write_TFT_Byte(0xC1,TFT_COMMAND); MCU_write_TFT_Byte(0xC5,TFT_DATA); MCU_write_TFT_Byte(0xC2,TFT_COMMAND); MCU_write_TFT_Byte(0x0A,TFT_DATA); MCU_write_TFT_Byte(0x00,TFT_DATA); MCU_write_TFT_Byte(0xC3,TFT_COMMAND); MCU_write_TFT_Byte(0x8A,TFT_DATA); MCU_write_TFT_Byte(0x2A,TFT_DATA); MCU_write_TFT_Byte(0xC4,TFT_COMMAND); MCU_write_TFT_Byte(0x8A,TFT_DATA); MCU_write_TFT_Byte(0xEE,TFT_DATA); MCU_write_TFT_Byte(0xC5,TFT_COMMAND);//VCOM MCU_write_TFT_Byte(0x0E,TFT_DATA); MCU_write_TFT_Byte(0x36,TFT_COMMAND);//MX,MY,RGB mode switch (DISPLAY_DIRECTION)//显示的方向(竖屏:0,横屏:1,竖屏旋转180度:2,横屏旋转180度:3) { case 0: MCU_write_TFT_Byte(0xC8,TFT_DATA);break;//竖屏 case 1: MCU_write_TFT_Byte(0xA8,TFT_DATA);break;//横屏 case 2: MCU_write_TFT_Byte(0x08,TFT_DATA);break;//竖屏翻转180度 default : MCU_write_TFT_Byte(0x68,TFT_DATA);break;//横屏翻转180度 } //ST7735R Gamma Sequence MCU_write_TFT_Byte(0xE0,TFT_COMMAND); MCU_write_TFT_Byte(0x0F,TFT_DATA); MCU_write_TFT_Byte(0x1A,TFT_DATA); MCU_write_TFT_Byte(0x0F,TFT_DATA); MCU_write_TFT_Byte(0x18,TFT_DATA); MCU_write_TFT_Byte(0x2F,TFT_DATA); MCU_write_TFT_Byte(0x28,TFT_DATA); MCU_write_TFT_Byte(0x20,TFT_DATA); MCU_write_TFT_Byte(0x22,TFT_DATA); MCU_write_TFT_Byte(0x1F,TFT_DATA); MCU_write_TFT_Byte(0x1B,TFT_DATA); MCU_write_TFT_Byte(0x23,TFT_DATA); MCU_write_TFT_Byte(0x37,TFT_DATA); MCU_write_TFT_Byte(0x00,TFT_DATA); MCU_write_TFT_Byte(0x07,TFT_DATA); MCU_write_TFT_Byte(0x02,TFT_DATA); MCU_write_TFT_Byte(0x10,TFT_DATA); MCU_write_TFT_Byte(0xE1,TFT_COMMAND); MCU_write_TFT_Byte(0x0F,TFT_DATA); MCU_write_TFT_Byte(0x1B,TFT_DATA); MCU_write_TFT_Byte(0x0F,TFT_DATA); MCU_write_TFT_Byte(0x17,TFT_DATA); MCU_write_TFT_Byte(0x33,TFT_DATA); MCU_write_TFT_Byte(0x2C,TFT_DATA); MCU_write_TFT_Byte(0x29,TFT_DATA); MCU_write_TFT_Byte(0x2E,TFT_DATA); MCU_write_TFT_Byte(0x30,TFT_DATA); MCU_write_TFT_Byte(0x30,TFT_DATA); MCU_write_TFT_Byte(0x39,TFT_DATA); MCU_write_TFT_Byte(0x3F,TFT_DATA); MCU_write_TFT_Byte(0x00,TFT_DATA); MCU_write_TFT_Byte(0x07,TFT_DATA); MCU_write_TFT_Byte(0x03,TFT_DATA); MCU_write_TFT_Byte(0x10,TFT_DATA); MCU_write_TFT_Byte(0xF0,TFT_COMMAND);//启动测试命令 MCU_write_TFT_Byte(0x01,TFT_DATA); MCU_write_TFT_Byte(0xF6,TFT_COMMAND);//禁用ram省电模式 MCU_write_TFT_Byte(0x00,TFT_DATA); MCU_write_TFT_Byte(0x3A,TFT_COMMAND);//65k mode MCU_write_TFT_Byte(0x05,TFT_DATA); MCU_write_TFT_Byte(0x29,TFT_COMMAND);//开启显示 //设置显示区域(行起始,行终止,列起始,列终止) TFT_set_region(0,127,0,127); TFT_clear(BLACK);//清屏(屏幕为黑色) TFT_BL=1;//背光开启 } 驱动展示 总结 关键初始化框架给出,方便直接配置使用,部分功能函数可在下方留言邮箱获取,上线发送,长期发布类似文章,欢迎关注,欢迎随时留言。
TB6612FNG电机驱动模块纯硬件调试 模块简介引脚定义硬件实现材料准备实验接线 原文链接:https://www.yourcee.com/newsinfo/2926465.html
模块简介 点击图片购买 TB6612FNG是一款新型驱动器件,能独立双向控制2个直流电机,它具有很高的集成度,同时能提供足够的输出能力,运行性能和能耗方面也具有优势,因此在集成化、小型化的电机控制系统中,它可以作为理想的电机驱动器件。
原理图如下:
注意: 由于坦电容的特性导致其容易炸开,不稳定的电源并不会导致每一个都炸开,使用的时候多检查电源是否稳定。
引脚定义 IN1IN2PWMSTBY输出状态HHH/LH制动LHHH反转LHLH制动HLHH正转HLLH制动LLHH停止---L待机 由上面的表可知:
STBY引脚在高电平的时候模块是正常工作,低电平模块待机;PWM要有信号输入或者处于高电平且IN1和IN2电平不同时,模块才会有输出。
(两路电机单独控制)
硬件实现 材料准备 TB6612FNG电机驱动模块一个(排针会送)
一个输出5V的电源
一个输出9V的电源
杜邦线诺干
面包板一个
电机一个
XY-PWM1一个(PWM可以实现电机调速,没有也行)
实验接线 本次实验为控制一路电机
首先把TB6612FNG电机驱动模块焊上排针,冷却后插在面包板上,引出公共地和VCC5V,两个电源的地和模块的地要接在一起,
VM接8V电源正极,VCC接5V电源正极(之前已经引出5V在面包板两旁),A01、A02接直流电机,STBY接5V。
PWM接5V,AIN1接5V,AIN2接地,
上电即可实现电机转动,AIN1接地AIN2接5V,电机就会反转
PWM引脚接上PWM信号,调节占空比,就可以控制电机的转速(提供PWM信号的模块一样要共地)。
通过上述的硬件实现,有点基础的都可以很轻松的写出相应的代码,通过代码来控制电机可以实现更多的功能,
有什么疑问,欢迎在下留言交流,更多电子模块的学习,欢迎关注一键三连!
单例模式 目的 单例是一种创造性的设计模式,它允许您确保一个类只有一个实例同时为这个实例提供一个全局访问点。
问题 单例模式同时解决了两个问题,违反了单责任原则:
确保一个类只有一个实例。为什么会有人想要控制一个类有多少个实例?最常见的原因是控制对某些共享资源(例如数据库或文件)的访问。它是这样工作的:假设您创建了一个对象,但过了一段时间后决定创建一个新对象。您将获得已经创建的对象而不是接收一个新的对象。注意这种行为不可能用常规构造函数实现,因为构造函数调用必须按照设计总是返回一个新对象。
为该实例提供一个全局访问点。还记得你用来存储一些基本对象的全局变量吗?虽然它们非常方便但也非常不安全,因为任何代码都可能覆盖这些变量的内容,从而导致应用程序崩溃。就像全局变量一样,单例模式允许您从程序中的任何地方访问某个对象。但是它还可以保护该实例不被其他代码覆盖。这个问题还有另一个方面:您不希望解决问题1的代码分散在您的程序中。最好将它放在一个类中,尤其是在其他代码已经依赖于它的情况下。 如今单例模式已经变得如此流行以至于人们可能会称某个类为单例,即使它只解决了列出的其中一个问题。
解决方案 所有单例模式的实现都有这两个共同的步骤:
将默认构造函数设为private,以防止其他对象对单例类使用new操作符。创建一个充当构造函数的静态创建方法。在实现中这个方法调用私有构造函数来创建一个对象并将其保存在一个静态字段中。对这个方法的所有后续调用都会返回缓存的对象。 如果您的代码能够访问单例类,那么它就能够调用单例类的静态方法。无论何时调用那个方法总是返回相同的对象。
与真实世界的对比 政府是单例模式的一个很好的例子。一个国家只能有一个官方政府。无论组成政府的个人身份如何,“政府of X”这个头衔都是一个全球性的访问点,可以识别出政府负责人的身份。
结构 单例类声明了一个静态方法getInstance,该方法返回它自己类的同一个实例。单例的构造函数应该对客户端代码隐藏。调用getInstance方法应该是获取Singleton对象的唯一方法。 伪码 在本例中数据库连接类充当单例。这个类没有公共构造函数,所以获得它的对象的唯一方法是调用getInstance方法。这个方法缓存第一个创建的对象,并在所有后续调用中返回它。
// The Database class defines the `getInstance` method that lets // clients access the same instance of a database connection // throughout the program. class Database is // The field for storing the singleton instance should be // declared static. private static field instance: Database // The singleton's constructor should always be private to // prevent direct construction calls with the `new` // operator.
EMQX——docker安装及简单使用 因为课设要用到MQTT服务器,索性自己搭一个吧,都说EMQX挺好用的。
后期会介绍课程设计中如何使用EMQX的。
EMQX是什么 先介绍一下EMQX是什么,可以简单理解为一个MQTT的服务器。
更重要的是看EMQ白皮书的内容摘要:
文章目录 EMQX——docker安装及简单使用EMQX是什么首先列出参考资料一、安装EMQX1.安装docker2.安装EMQX4.4.4 二、启动EMQX1.简单docker操作启动EMQX2.配置、启动docker-compose集群 三、登录EMQX web管理页面总结 首先列出参考资料 Emqx官方教程
docker compose的学习
EMQX docker安装及运行
读者可以阅读完博客内容后按顺序参考以上链接的内容。
一、安装EMQX 1.安装docker 首先安装以下顺序依次运行指令(如果更新过慢请先换源)
sudo apt update sudo apt upgrade sudo apt install docker.io -y 安装完成后输入
docker -v #查看docker的版本,出现如下类似字样则表示安装成功 2.安装EMQX4.4.4 先进入root用户,输入密码
su 使用docker pull指令安装emqx镜像
docker pull emqx/emqx:4.4.4 安装成功后,输入指令
docker images 出现红框字样,则表示镜像安装成功
二、启动EMQX 1.简单docker操作启动EMQX 启动 docker 容器,最后一个参数为IMAGE ID
docker run -d --name emqx -p 1883:1883 -p 8081:8081 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 68440db9c488 然后查看正在运行的容器,输入
IAR软件安装图文教程 简介:IAR软件下载:将下载好的IAR软件打开:点击安装IAR工作台:出现如下状况就把360关掉或者允许操作:进入到欢迎界面:选择同意软件许可:选择安装目录:选择安装USB Driver:选择工程的目录:安装dongle drivers提示:workbench安装开始:选择语言:安装完成跳出主界面: 安装驱动:选择完成:安装完成然后是对软件进行许可,首先退出安装窗口: 对软件进行许可:打开IAR manager for Arm8.32.4:选择license>offine activation离线激活:再打开之前下载的许可文件:打开文件夹是破解文件:解压后是如下图所示:打开如图所示的license generator.exe文件:把注册码粘到许可证码上面:然后点击下一步:选择no,取消license绑定硬件选择存放激活信息文件的地址:选择地址:选择响应文件来激活许可:在破解软件中添加许可基本信息,选择装有许可文件的地址:激活许可:选择存放响应文件的地址,我们可以存在和license信息相同的位置:确认后,成功创建会显示Done!然后在激活文件的响应文件里面填写响应文件地址:选择刚才创建的文件:license许可完毕:绿色方块表示通过许可: 简介: IAR 公司总部在北欧的瑞典,在美国、日本、英国、德国、比利时、巴西和中国设有分公司。它最著名的产品是C编译器-IAR Embedded Workbench, 支持众多知名半导体公司的微处理器。集成开发环境(IDE,Integrated Development Environment )用于提供程序开发环境的应用程序,包括代码编辑器、编译器、调试器和图形用户界面等工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件。 IAR软件下载: 将下载好的IAR软件打开: 点击安装IAR工作台: 出现如下状况就把360关掉或者允许操作: 进入到欢迎界面: 选择同意软件许可: 选择安装目录: 选择安装USB Driver: 选择工程的目录: 安装dongle drivers提示: workbench安装开始: 选择语言: 安装完成跳出主界面: 安装驱动: 选择完成: 安装完成然后是对软件进行许可,首先退出安装窗口: 对软件进行许可: 打开IAR manager for Arm8.32.4: 选择license>offine activation离线激活: 再打开之前下载的许可文件: 打开文件夹是破解文件: 解压后是如下图所示: 打开如图所示的license generator.exe文件: 把注册码粘到许可证码上面: 然后点击下一步: 选择no,取消license绑定硬件 dongle:软件保护器,简称软件狗。dongle经常被认为是硬件保护,它是一个可被附加在计算机并口、串口或USB上的小插件,它包含厂家烧制的EPROM和定制的专用集成电路。
选择存放激活信息文件的地址: 选择地址: 选择响应文件来激活许可: 在破解软件中添加许可基本信息,选择装有许可文件的地址: 激活许可: 选择存放响应文件的地址,我们可以存在和license信息相同的位置: 确认后,成功创建会显示Done! 然后在激活文件的响应文件里面填写响应文件地址: 选择刚才创建的文件: license许可完毕: 绿色方块表示通过许可: 上一篇 End 下一篇
前记 记于2022年6月15日晚23点32分,对qq的这个小世界咱也不多吐槽了,毕竟是同行的辛苦结果 打开手机QQ
→右滑拉出侧边栏
→选择“设置”
→选择“辅助功能”
→选择“主页底部导航栏设置”
最后自行选择就行了
后记:
勿动怒
forEach是es6新增的数组方法,本意是传递一个函数,然后循环数组调用该函数,如下
let arr = [{ a:1 }, { b:2 }] arr.forEach((ele,index,arr)=>{ console.log(ele); }) 其中这个函数接受三个参数,第一个是当前循环的元素,第二个是索引值,第三个是当前调用forEach的数组,输出如下
这样似乎就完了,但是有的场景中需要一些特殊的情况,比如
let arr = [{ a:1, flag:null }, { b:2, flag:null }] let selectArr = [false,true]; arr.forEach((ele,index,arr)=>{ console.log(ele); }) 数组中的对象有一个空的字段,该字段需要实时的从selectArr中获取与当前索引所对应的值去赋值,(当然直接在循环的时候传入也可以,但是这里只是假设一种情况,假设seleceArr随时会变化,我们需要获取循环当下的值)这时就可以用下面的写法;
let arr = [{ a: 1, flag: null }, { b: 2, flag: null }] let selectArr = [false, true]; arr.forEach(traverse(selectArr)) function traverse(ar) {//遍历方法 return (ele, index, arr) => { ele.flag = ar[index] //将selectArr对应的项插入 console.log(ele); } } 这里利用了闭包,高阶函数,在traverse函数中返回一个函数,这个函数会作为参数反馈给forEach,这样这个返回的函数就可以调用到传递来的selectArr了。
本节课完成user页面下的diolog表单,表单里的元素都是动态渲染,以一个CommonForm组件的形式放入user页面。
1.CommonForm组件 新建CommonForm.vue组件,添加props,用于接受3个参数,formLabel为一个数组,form的相关配置,form的表单数据,类型为Object,表单布局inline,为一个布尔值。el-form添加属性,首先是ref标识,可以通过refs拿到ref实例,label-width为初始高度,但是会根据内容变化而变化,并不固定。model用来数据的双向绑定(重要),我们传入的数据是form。inline属性表示dialog样式,inline表示上下排列。对传入的form进行遍历,label表示表单域名称。表单组件有input(姓名、年龄、地址)、select(性别选择)、switch、datepicker(日期)、option(下拉)。
首先判断组件的type,input组件设置placeholder属性,表示input框内的文字,使用字符串拼接。v-model进行数据绑定,拿到form下面的[item.model],form前面已经model过了,这里就可以使用。switch、select()、switch、datepicker、option的方法也类似。
最后对组件进行扩展,slot后面会讲个slot的作用。
<template> <el-form ref="form" label-width="100px" :model="form" :inline="inline"> <el-form-item v-for="item in formLabel" :key="item.label" :label="item.label"> <el-input v-if="item.type === 'input'" :placeholder="'请输入'+item.label" v-model="form[item.model]"> </el-input> <el-switch v-if="item.type === 'switch'" v-model="form[item.model]"> </el-switch> <el-date-picker v-if="item.type === 'date'" type="date" value-format="yyyy-MM-dd" placeholder="选择日期" v-model="form[item.model]"> </el-date-picker> <el-select v-if="item.type === 'select'" placeholder="请选择" v-model="form[item.model]"> <el-option v-for="item in item.opts" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> <el-form-item> <slot></slot> </el-form-item> </el-form> </template> <script> export default{ name:'CommonForm', // 由外部组件传入数据。 props:{ formLabel:Array, form:Object, inline:Boolean, }, data(){ } } </script> 2.
源码 保存格式:
.emf:word中使用emf格式.eps:Latex中使用eps格式svg:有色块是,使用svg格式更清晰 %% Matlab 基础绘图 % Author : Xu Zhe % Date : 2021-06-29 % Brief : %% 系统初始化 close all clear clc %% 数据 x = linspace(-pi,2*pi,100); y1 = sin(x); y2 = cos(x); %% 绘图 % 绘图全局参数 Wfig = 8; % 一般论文用图宽度,8cm Hfig = 5.5; fontsize = 9; fontEN = 'Times New Roman'; fontCN = '宋体'; % 配置窗口 figure('name','Matlab绘图格式化','color','w'); set(gcf,'unit','centimeters','position',[0,15,Wfig,Hfig]); % 绘图内容 plot(x,y1,'b-','linewidth',1.0); grid on hold on plot(x,y2,'r--','linewidth',1.
文章目录 前言一、pdf.js 是什么?二、使用步骤1.下载库文件2.使用方式微信小程序端——使用 web-view 标签H5 端——使用 iframe 标签(使用vue框架) 3.更改源码如何隐藏顶部工具栏如何让用户强制阅读一定时间如何获取pdf总页数如何获取pdf当前页数将总页数和当前页数发送给小程序 总结 前言 前一段时间遇到了一个需求,关于 pdf 文件的预览,客户要求如下:
只能在微信小程序内预览,不能调起本地浏览器预览;需要让用户强制阅读 10s 后才算阅读完成,进而进行下一步操作;用户不能下载预览的 pdf 文件; 因为一些原因(此处省略一万字🐎),这个项目具有 H5 端和原生微信小程序端,并且他们有着相同的业务逻辑😊,所以最好的办法就是设计出一套方案适用两端,前期做了一些尝试,可以看这篇文章,最后决定使用 pdf.js 来实现业务要求。
一、pdf.js 是什么? PDF.js 由 Mozilla 提供支持。目标是创建一个通用的、基于 Web 标准的平台,用于解析和呈现 PDF。
二、使用步骤 1.下载库文件 前往 pdf.js 的 官网 下载库文件,我们下载哪个版本都是可以的,后者适用于旧版浏览器,我这里下载的后者。
下载完成后,因为微信小程序打包的限制,我将库文件放到腾讯云服务器上,如果想测试可以联系我提供测试资源。
H5 可以放到本地,目录如下:
2.使用方式 通过web目录下 viewer.html 查看器 + pdf文件路径预览pdf文件
yourPath/web/viewer.html?file=pdfPath 微信小程序端——使用 web-view 标签 代码示例:
//.wxml <web-view src="{{pdfView+pdfUrl}}" ></web-view> //.js data: { // viewer.html 查看器的路径 pdfView:"yourPath/web/viewer.html?file=", // 要预览的 pdf 文件的路径 pdfUrl:"
1、下载 官网:https://www.mysql.com/
选择downloads往下拉
2、安装 把下载好的mysql压缩包解压到非中文路径下,切记:非中文!!
以管理员身份启动cmd
dos命令窗口下切换到刚才复制的路径(解压后的文件夹下的bin文件目录)
安装mysql服务:mysqld --install
接下来我们要进行mysql初始化,他会生成一个随机密码,务必拿小本本记下来,万一电脑睡觉了,那么就得重新搞一遍了
输入命令:mysqld --initialize --console
开启mysql服务
输入命令:net start mysql
登录mysql,如果前面没开启mysql服务,是运行不了的!!
输入命令:mysql -u root -p 回车再写密码(星星星)
注意:这里所说的密码是刚才叫你们用小本本记下来那个
登录成功代表mysql安装成功,但是你必须重新设置密码才可以使用 重新设置密码指令:set password for root@localhost = password('你的密码');
如果之前安装过mysql但没删除干净,再次安装会报错的!!!
先切到mysql的bin目录下,执行sc query mysql,如果返回内容说明之前确实安装过mysql,于是,我们再执行sc delete mysql删除掉之前的记录即可正常按照安装步骤执行
3、配置环境变量 此电脑右键——>属性——>高级系统设置——>环境变量——>系统变量
新建MYSQL_HOME,变量值就是mysql的安装目录(bin目录前)
修改Path,在其变量值中新建一个:%MYSQL_HOME%\bin
环境变量配置完毕,以后哪里都可以运行mysql了,不用在切到其bin目录下啦
1、下载步骤: 官网:VMware - Delivering a Digital Foundation For Businesses
2、VMware安装步骤: 安装前建议关闭windows防火墙
路径:控制面板\系统和安全\Windows Defender 防火墙\自定义设置
VMwarean安装好之后,就可以重新开启防火墙了
3、CentOS7下载、安装步骤: 2.1CentOS下载 说明:这里我是后补的教程,下载的是CentOS8
CentOS的服务器是在海外的,我们是没办法直接通过官方下载镜像文件的,在这里需要用到一些镜像网站来跳转下载,国内比较出名的有网易云镜像、阿里云镜像,还有上海交通大学的镜像。
打开百度,搜索CentOS Mirror
本教程以“CentOS-7”为例演示下载
2.2CentOS安装 4、关于ip地址 如果没有ip地址
回忆你在安装的过程当中有没有关闭防火墙,关闭杀毒软件看看有没有 3.观察你的服务有没有开启(计算机右键--->管理--->服务)
4.noboot是否处于yes状态
vim /etc/sysconfig/network-scripts/ifcfg-ens33
ONBOOT 值改为yes 自动启动(如果在安装过程中忘了勾选网络自动获取)
重启网卡systemctl restart network
Linux静态网络和静态ip设置:
ONBOOT=yes 值改为yes (如果在安装过程中忘了勾选网络自动获取)
查看以下信息,VMware窗口:编辑-->虚拟网络编辑器
IPADDR=192.168.x.xx x 需要查看虚拟机vm8的段位(第三位) xx 自定义,别跟物理机一样
NETMASK=255.255.255.0
GATEWAY=192.168.x.2 网关 按照虚拟机à编辑-à虚拟机网络编辑器àvm8 –》NAT设置—>查看网关
DNS1=114.114.114.114
修改完信息需重启网卡: 重启网卡systemctl restart network
静态ip配置完成,以后虚拟机不会因关机导致ip地址变化了~~~
5、使用Xshell远程连接控制Linux: 启动Xshell,配置连接Linux的参数
启动Xftp,并配置连接信息
1 前言 很多人认为,在C#中 for 和 foreach 功能是一样的,foreach 顶多就是比 for 要更方便一些。但是实际上真的是这样吗?在本文中,让我们通过一个实例来理解其底层的工作原理。
2 for VS foreach 首先,请看下面的代码段:
List<Person> people = new List<Person>(); for(int i = 0; i < 100; i++){ var p = people[i]; // TODO: 下面的代码处理 p } List<Person> people = new List<Person>(); foreach(var p in people) // TODO: 下面的代码处理p } 我们可以看到,在 TODO 下方,都是直接使用 p 就可以完成相关操作。两者从使用上来说,foreach 能够比 for 省去一个赋值语句(),也就仅此而已,两者感觉完全是一样的,但是实际上真的是这样吗?
3 一个示例 在回答问题之前,让我们再看这样的一个示例。以下代码先定义了一个列表 List<int> list并添加3亿个整型数,然后分别使用 for 和 foreach 进行累加求和,结果分别保存在 sum1 和 sum2 中,并对这两种方法进行计时,在最后输出计算结果和所用时间。
前言: 本文详细介绍了CLION下的opencv的编译环境搭建。一切从源码开始,指的是下载的源码, OpenCV,CMake。
文章先从Opencv的基础版本出发,介绍opencv下载的几种方法。然后,依此按照拍照CLION来编译Opencv的要求逐一配置项目系统:在安装好编译器,和CMAKE编译系统后,笔者先对Opencv的源码进行了编译,然后,在CLION里面设置好安装的编译器和 CMAKE编译系统,同时,将上述编译器和Opencv编译好的库的地址都添加到系统路径里面,然后,找到两个标定的opencv代码进行了编译,并编译成功。
小结: opencv的源码编译比较繁琐花时间,其实完全可以从官网直接下载已经编译好的库,其实,windows的默认下载的是VS的编译好的库。这些资源在文章后面都给出了链接。
本文目标: 基于opencv3.0的一个老的机器视觉项目,在Clion中构建编译环境,并跑起来。
系统以及软件环境: Cmake 3.22.3
MinGW 6.0 x86_64-8.1.0-release-posix-seh-rt_v6-rev0
GDB 11.1
GCC version 8.1.0
opencv 3.4.16
Opencv的版本 Releases - OpenCV
Opencv的沿革下,正在迈进5.0的版本,由于接口的变化,opencv3.0的版本在很多项目里面还继续广泛使用,导致opencv针对3.0的版本一直在做分支的bug修复工作,直到现在目前,还没有统一。下面的图,显示了最新的opencv的版本和3.0的修正版本的时间,几乎同时。
我们的目标是运行一个老的opencv的版本,那么我们选择最新的3.0系列的版本,3.4.16
上图有好几个下载的选项,在windows10下,我们选择windows这个选项,这个选项包括了一个编译好的vc(微软)支持的windows兼容版本 + 源码目录,所以,如果是要自己编译的话,选这个也可以,结果和选上面source是一样。 下载完毕后,我们新建一个文件夹,我们这里是:D:/OPENCV/VERSION3/ ,把下载的opencv安装执行文件解压到我们定义的目录里面:
目录结构,如下,正如我们之前讨论,他包括源码: sources 文件夹,和一个已经编译好的支持微软VS的一个库文件夹【如果配置到Visual Studio应该会更加简单】 Build是默认的vc 编译的结果。Souces 这是可以用你想要的编译器来做的结果:
MinGW编译器: MinGW的基础知识,可以参阅我之前的博客:
(1条消息) 【C++基础】【集成编译环境01】Clion的C++编译环境和Boost Test Framworks框架运行实践_Franklin的博客-CSDN博客https://dimensionspacex.blog.csdn.net/article/details/123651653?spm=1001.2014.3001.5502
具体Mingw的下载和安装配置,可参阅之前我写的博客:
(1条消息) MinGW 64的安装 - 官网sourceforge安装失败非翻墙解决办法_Franklin的博客-CSDN博客_sourceforge下载不了https://dimensionspacex.blog.csdn.net/article/details/124314331?spm=1001.2014.3001.5502
安装好的话,编译器确认:
PS C:\Users\frank_sj> gcc -v Using built-in specs. COLLECT_GCC=D:\mingw64\bin\gcc.exe COLLECT_LTO_WRAPPER=D:/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../../../src/gcc-8.1.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.
a. transaction的重载
基于现有的transaction格式,定义新的transaction,同时约定新的约束,之后,:
1. 新定义sequence来使用新的transaction;
2. 旧的sequence来使用新的transaction;
case中使用新/旧的sequence即可。
需要新增文件 new_transaction.sv, my_test1.sv,new_sequence.sv/修改sequence。
优化做法:
基于factory重载机制,新建新的transaction,
直接在case的,build_phase中:
factory.set_type_override_by_type(my_transaction::get_type(), new_transaction::get_type());
其余不变,这样涉及的修改更少;
b. 基于上面transaction的重载,可以对每个transaction定义一个sequence,然后放在sequence_lib中,用一个case直接启动即可;
需要新增,sequence*.sv, sequence_lib.sv;
c. 重载sequence
1. 在新的sequence中约束不同的transaction元素,这样就是现在同一个sequence发送不同transaction定向约束的场景;
之后在class build_phase中,采用factory重载<参考上文>
d. 重载component
万物可重载;
e. callback机制
实现方式:
定义callback类
class A extends uvm_callback;
virtual task pre_tran (my_driver drv, ref my_transaction tr);
endtask
endclass
//my_driver代表这个A_pool会给那个类使用;
typedef uvm_callbacks #(my_driver, A) A_pool;
使用类my_driver.cc:
typedef class A;
class my_driver extends uvm_driver #(my_transaction);
……
`uvm_register_cb(my_driver, A)
task main_phase(uvm_phase phase)
实现用户只能在微信中打开H5页面 思路就是:项目是单页面项目,所以页面都渲染在index.html页面中,所以只要在index.html中进行判断,当前用户使用的浏览器是什么,如果用户使用除了微信浏览器的其它浏览器,都会将页面加载到wxError.html页面内,提示用户“请在微信客户端打开链接”
具体步骤: 1、与index.html同级新建一个wxError.html文件
完整的代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> </head> <body> <script type="text/javascript"> var ua = navigator.userAgent.toLowerCase(); var isWeixin = ua.indexOf('micromessenger') != -1; var isAndroid = ua.indexOf('android') != -1; var isIos = (ua.indexOf('iphone') != -1) || (ua.indexOf('ipad') != -1); if (!isWeixin) { document.head.innerHTML = '<title>抱歉,出错了</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0"><link rel="stylesheet" type="text/css" href="https://res.wx.qq.com/open/libs/weui/0.4.1/weui.css">'; document.body.innerHTML = '<div class="weui_msg"><div class="weui_icon_area"><i class="weui_icon_info weui_icon_msg"></i></div><div class="weui_text_area"><h4 class="weui_msg_title">请在微信客户端打开链接</h4></div></div>'; } </script> </body> </html> 2、在index.
conda activate env_name 出现以下提示:
CommandNotFoundError: Your shell has not been properly configured to use ‘conda activate’.
原因:安装anaconda3时conda init没有选择yes
~/.bashrc文件中没有conda init的初始化信息
解决办法
vi ~/.bashrc 在conda activate env_name之前粘贴:
# >>> conda initialize >>> # !! Contents within this block are managed by 'conda init' !! __conda_setup="$('/home/ec2-user/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)" if [ $? -eq 0 ]; then eval "$__conda_setup" else if [ -f "/home/ec2-user/anaconda3/etc/profile.d/conda.sh" ]; then . "/home/ec2-user/anaconda3/etc/profile.d/conda.sh" else export PATH="/home/ec2-user/anaconda3/bin:$PATH" fi fi unset __conda_setup # <<< conda initialize <<< conda init source ~/.
需要从neo4j中导出数据,可以导出csv文件或者json文件。
导出:
进行处理:提取内容
csv:导出内容为文本,需要将文本转化为字典,导出后研究很久还是不会处理,放弃
json:
import json with open(filename,'r',encoding='utf-8-sig') as json1_file: # filename为导出文件路径 Data = json.load(json1_file) print(Data) 之后再对数据进行处理比较方便
1,安装DNS服务器 yum install -y bind
[root@localhost /]# vim /etc/named.conf //修改DNS主配置文件
listen-on port 53 { any; };
allow-query { any; }; //修改这两行的内容
2,修改子配置文件 [root@localhost ~]# vim /etc/named.rfc1912.zones
zone "test.com" IN {
type master;
file "test.com.zone";
};
zone "100.168.192.in-addr.arpa" {
type master;
file "100.168.192.zone";
}; ##在内容最后添加一个正向和一个反向解析区域
[root@localhost /]# cd /var/named/ ###进入DNS服务器区域配置文件目录
[root@localhost named]# cp -p named.localhost test.com.zone
[root@localhost named]#cp -p named.loopback 100.168.192.zone ###复制模板区域配置文件为指定区域配置文件。注:一定要保留源文件权限,如果未保留,须将属组改为named。
[root@localhost named]# vim test.com.zone ####编辑正向区域配置文件,修改并添加以下行
$TTL 1D
@ IN SOA dns.
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 前言一、数据挖掘定义及用途1.定义:2.用途: 二、决策树1.理论知识(1)概念(2)算法一般过程(C4.5为例) 2.小结 三、关联规则1.概述2.关联分析3.小结 四、聚类分析(K-means)1.K-means算法(K-均值算法)2.小结 五、数据库中的知识发现(KDD)1.KDD过程2.KDD应用 六、评估技术1.数据集划分2.混淆矩阵和正确率3.评估有指导的学习模型4.评估无指导聚类模型 七、神经网络八、统计技术1.回归分析(1)简单线性回归分析(2)多元线性回归(3)非线性回归 2.贝叶斯分类器 前言 数据挖掘基础
主要包含:决策树、关联规则、聚类分析、神经网络和统计分析。
一、数据挖掘定义及用途 1.定义: 数据挖掘是发现数据中潜在的有用的模式(信息、知识、规律、模型)的过程。
2.用途: 1、分类:
应用:评估信用卡申请者的风险等级-低、中、高。
方法:使用已知分类的实例建立分类模型,对未知分类的实例进行分类。
2、估值:
应用:根据购买模式,估计一个家庭的孩子个数、收入或财产。
*估值类似于分类,不同之处在于分类的输出是离散量,估值输出为连续值;分类的类别数确定,估值的量是不确定的。
3、预测:
应用:预测明天上证指数的收盘价
方法:通过历史数据得出预测模型,用该模型对未知变量的预测
4、聚类:
应用:在信用卡公司,发现输入属性的一-个集合,来区分接受寿险促销和未接受促销的持卡人.
方法:对实例分组,把相似的实例放在一个聚类中,发现最能区分各聚类的典型属性,使用这些属性开发预测未来结果的模型
二、决策树 1.理论知识 (1)概念 从数据产⽣决策树的机器学习技术称为决策树学习,简称决策树。
决策树是数据挖掘中最常⽤的⼀种分类和预测技术,使⽤其可建⽴分类和预测模型。
(2)算法一般过程(C4.5为例) 1)给定⼀个表示为“属性-值”格式的数据集T。数据集由多个具有多个输⼊ 属性和⼀个输出属性的实例组成。 2)选择⼀个最能区别T中实例的输⼊属性,C4.5使⽤增益率来选择该属 性。 3)使⽤该属性创建⼀个树节点,同时创建该节点的分⽀,每个分⽀为该节 点的所有可能取值。 4)使⽤这些分⽀,将数据集中的实例进⾏分类,成为细分的⼦类。 5)将当前⼦类的实例集合设为T,对数据集中的剩余属性重复(2)(3) 步,直到满⾜以下两个条件之⼀时,该过程终⽌。创建⼀个叶⼦节点,该节点 为沿此分⽀所表达的分类类别,其值为输出属性的值。 该⼦类中的实例满⾜预定义的标准,如全部分到⼀个输出类中,或者分到⼀个输出类中的实例达到某个⽐例;没有剩余属性。 算法过程中设计到几种关键技术:
·选择最能区别数据集中实例属性的⽅法(信息增益率最⼤)
C4.5使用了信息论(Information Theory)的方法,即使用增益率(Gain Ratio)的概念来选择属性;目的是使树的层次和节点数最小,使数据的概化程度最大化。
C4.5选择的基本思想:选择具有最大增益率的属性作为分支节点来分类实例数据。
1)信息熵
信息变化的平均信息量称为“信息熵”(信息量化)
在信息论中,信息熵是信息的不确定程度的度量。熵越大,信息就越不容易搞清楚,需要的信息量就越大,能传输的信息就越多。
2)信息增益
信息增益表示当x取属性xi值时,其对降低x的熵的贡献大小。信息增益值越大,越适于对x进行分类。C4.5使用信息量和信息增益的概念计算所有属性的增益,并计算所有属性的增益率,选择值最大的属性来划分数据实例
决策树计算实例1
决策树计算实例2
·剪枝方法
为控制决策树规模,优化决策树而采取的剪除部分分支的方法。分为预剪枝和后剪枝。
·检验方法
(1)use training set:使用在训练集实例上的预测效果进行检验。
(2)supplied test set:使用另外提供的检验集实例进行检验,此时需要单击 Set按钮来选择用来检验的数据集文件。
在上一篇文章中,我们介绍了如果在CentOS上安装docker环境,本文则是介绍docker的具体项目实践,主要介绍如果通过docker容器来部署vue前端项目。本文需要基于vue项目已经开发完成,并且docker环境已经准备好。思路是Docker镜像中使用nginx反向代理运行vue前端项目。
编译发布vue项目 编译发布vue项目,生成dist目录的待发布前端项目。将dist目录上传到CentOS上的相应项目目录下,这里CentOS上的项目目录叫demo-vue。
编写Dockerfile文件 vue的镜像中我们需要基于nginx,把发布后的vue文件复制到镜像中,自定义镜像中的nginx配置。
# 基于nginx:1.20.1版本,如果不指定版本则拉去最新的nginx版本 FROM nginx:1.20.1 MAINTAINER flyduck "flyduck@flyduck.com" # 将dist文件中的内容复制到 /usr/local/app/ 这个目录下面 # <目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建 COPY dist/ /usr/local/app/ # 自定义nginx配置 COPY demo-vue.conf /etc/nginx/conf.d/ 自定义vue前端项目的nginx配置放在demo-vue.conf 文件中,将自定义的nginx配置放入/etc/nginx/conf.d/目录下,该目录是nginx加载配置的目录。
server { listen 8080; server_name localhost; root /usr/local/app; gzip on; gzip_static on; gzip_min_length 1k; gzip_buffers 16 64k; gzip_http_version 1.1; gzip_comp_level 9; gzip_types text/plain text/javascript application/javascript image/jpeg image/gif image/png application/font-woff application/x-javascript text/css application/xml; gzip_vary on; gzip_disable "MSIE [1-6]\."; index index.html index.htm; location / { try_files $uri $uri/ /index.
一、前端报500 打开网络请求,看响应
1、
500错误码的官方解释是:
500服务器内部错误(Internal server error)主要是由于IWAM账号的密码错误造成的。该错误说明IIS服务器无法解析ASP代码,访问一个静态页面试试是否也出现这个问题,如果访问静态页面没问题,那就要分以下几种 情况来分析了: ① 你是否改变过计算机名称。 ② 站点所在的文件目录是否自定义了安全属性。 ③ 安装了域控制器后是否调整了域策略。如果是其中的一种情况,请一一将 改变的参数设置回来看是否解决问题。 如果静态空间也无法访问,则说明解析还没生效。
有些生涩,在开发中,常常和前后端约定的数据格式不同造成服务器无法正常处理前端数据,无法理解前端的数据格式。
例如我遇到过的问题:
前端传送的数据是:
然而后端同学给我看的截图是: { “id”:48 }
把请求改成了这个:
2、
出错信息:
1、前端报500错误,500服务器的错误,查看一下后台,没有报错。
2、打断点,也没有发现错误,但是请求返回空数据的时候,没有报错,返回有数据的结果报错了。
3、推测那应该是对象转Json的时候报错了,加入对象转Json代码到请求的最后查出错误原因。
ObjectMapper objectMapper = new ObjectMapper(); try { //output ,对象数据 objectMapper.writeValue(System.out,output); } catch (IOException e) { e.printStackTrace(); } 4、再次测试,果然发现报错了。ReportStatistics.getJobId()实体转Json的时候空指针。
Caused by: java.lang.NullPointerException
at com.audaque.datadiscovery.report.entity.ReportStatistics.getJobId(ReportStatistics.java:127)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.jackson.map.ser.BeanPropertyWriter.get(BeanPropertyWriter.java:483)
at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:418)
at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)
... 59 more
不管什么项目,或多或少都会遇到那么一点点转码的问题,
本片就提供两个实现Unicode和UTF8互转的函数。
环境为WINDOW 10, VS2010
(该函数在Windows下,也使用了windows的函数,如果使用通用的函数那么请使用C的库“mbstowcs()/wcstombs()”我还是觉得直接用系统的比较方便)
1.UNICODE转UTF8
#include <iostream> #include <windows.h> #include <wchar.h> /* * 从宽字符串转为utf8字符串 * @param [in] in_wStr 输入宽字符串 * @return 返回值为UTF8字符串,如果转换失败,返回NULL */ std::string UnicodeToUtf8(const std::wstring& in_wStr) { int nNeedChars = WideCharToMultiByte( CP_UTF8, 0, in_wStr.c_str(), -1, 0, 0, 0, 0 ); if (nNeedChars > 0)//再次判断一下 { std::vector<char> temp(nNeedChars); ::WideCharToMultiByte( CP_UTF8, 0, in_wStr.c_str(), -1, &temp[0], nNeedChars, 0, 0 ); return std::string(&temp[0]); } return std::string(); } 2.UTF8转为UNICODE
#include <iostream> #include <windows.
资源下载地址:https://download.csdn.net/download/sheziqiong/85638214
项目描述 给定三个数据集,每个数据集里面都有一些用户的历史请求内容,三个数据集分别来自三个基站。分别对三个数据集进行处理
首先对用户请求的视频内容进行一个分类,获取的json文件category_id里面有说明!然后进行视频流行度分析(播放量/喜欢/不喜欢/评论等数据)求出每两个数据集的排名的交集,将这些内容根据流行度的排名高低,选择那个排名较高的服务器进行缓存,缓存在这个服务器上的共享区域三个交集之外得到内容缓存在各自的缓存服务器的私有区中,每个缓存服务器的共享缓存区和私有缓存区一共最多缓存100个门类设置用户从所属基站的缓存服务器中获取内容,耗时t1,从其他基站的共享区获取内容,耗时t1+t2,从其他基站的私有区获取内容耗时t1+t2+t3如果基站中都没有这个内容,则向数据中心获取,耗时t1+T得到用户请求内容所需要的平均时间 大致效果图:
数据集获取 Youtube视频统计趋势:https://www.kaggle.com/datasnaek/youtube-new 数据预处理 项目需求说是需要使用三个数据集,而在搜索引擎中只发现了一条符合需求的大数据集,所以准备使用random间数据集随机筛选出三个子数据集
数据集描述 这个数据集是最热门的Youtube视频的每日记录,
该数据集包含有关Youtube每日热门视频的数月(且在不断增加)的数据。包括US,GB,DE,CA和FR地区(分别为美国,英国,德国,加拿大和法国)的数据,每天最多列出200个列出的趋势视频。
编辑:现在包括同一时间段内来自RU,MX,KR,JP和IN地区(分别为俄罗斯,墨西哥,韩国,日本和印度)的数据。每个区域的数据都在单独的文件中。数据包括视频标题,频道标题,发布时间,标签,观看次数,喜欢和不喜欢,描述以及评论数。数据还包括一个category_id字段,该字段在区域之间变化。要检索特定视频的类别,请在相关的中找到它JSON。数据集中的五个区域中的每个区域都包含一个这样的文件。
预处理步骤 使用os模块将不同国家的观看数据集分配到对应的操作目录下
处理前文件夹目录结构:
D:. │ 开发文档.md │ ├─.idea │ │ .gitignore │ │ 2021_03_30_课题.iml │ │ misc.xml │ │ modules.xml │ │ vcs.xml │ │ workspace.xml │ │ │ └─inspectionProfiles │ profiles_settings.xml │ ├─codes │ task1_数据集分开存放.py │ ├─datasets │ └─archive │ CAvideos.csv │ CA_category_id.json │ DEvideos.csv │ DE_category_id.json │ FRvideos.csv │ FR_category_id.json │ GBvideos.csv │ GB_category_id.json │ INvideos.
正常情况下,我们的鼠标右键菜单项是无法修改的,但是我们可以通过修改注册表来添加鼠标右键菜单项。这样的话,我们就可以直接使用鼠标右键很容易的选择关机、锁屏和重启了。那么这些功能该如何添加呢?
操作步骤如下:
1、在键盘上按【win+R】,输入【regedit】,点击【确定】。
2、依次展开路径到:HKEY_CLASSES_ROOT\DesktopBackground\Shell
3、鼠标点击【shell】,并在右侧窗口,鼠标右击选择【新建】→【项】
4、将新建的项命名为要添加的名称,比如:【关机】,我这里写成电脑睡眠(me),为了方便区分,我加了(me)
5、鼠标点击刚添加的电脑睡眠,双击右侧窗口中的【默认】,在【数值数据】处输入【睡眠】并点击【确定】
注意:这里的【睡眠】后面会显示到鼠标右键的,如果你想设置其它,自己把握即可
6、鼠标右击左侧【电脑睡眠】,选择【新建】→【项】,并命名为【command】
7、点击【command】,双击右侧窗口中的【默认】,在【数值数据】处输入 【Rundll32.exe powrprof.dll,SetSuspendState Hibernate】,并点击【确定】
8、回到桌面,在空白处点击鼠标右键,睡眠选项已经成功添加到右键菜单里了
说明: 如果需要取消鼠标右键菜单项,只需在注册表中把新建的项删除即可
10.如果想要添加其它的功能,可参考以上方法。在command项中设置不同的数值数据即可,同时修改相应的项名称
休眠 Rundll32.exe powrprof.dll,SetSuspendState Hibernate 关机 Shutdown.exe -S -F -T 0 (后面那个是数字零,表示等待0秒) 注销 Shutdown.exe -l 重启 Shutdown.exe -r -f -t 0 锁屏 Rundll32.exe User32.dll,LockWorkStation
1.首先先检查一下插件配置,点击File>Settings>Plugins
输入框输入lombok安装插件,然后点击ok,重新启动IDEA,然后大概率不会报错,假如还是报错,就接着看第二步。
2.假如第一步还是报错,点击File>Settings>Build,Execution,Deployment>Compiler>Annotation Processors
把下图红框位置打上对勾,然后点击保存退出(退出之后可以再进一次看是否打上对勾,本人第一次打上对勾,还是报错,第二次进去发现没有打上对勾),然后在运行项目就可以了。
由于操作问题,我不小心将已经暂存的文件删了,而且还找不到记录,这可愁死我了(第一次提交,由于把git当成云盘使用了),我第一时间在各大博客寻找同道中人。还真有好多人遇到类似情况。不过都是恢复代码的,没有文件的,这里我两种都说一下
使用git fsck --lost-found,查看记录,注意只有git add 过的代码才能找回
第一种:恢复代码
git fsck --lost-found,找到提交的id红线框
git show id 查看是不是需要恢复的代码
git merge id 合并被删除的记录
第二种:文件被删了,恢复文件到本地(我这里文件较大上传不了,删除了本地找不到了)
执行了上面的步骤后文件确实在暂存区了,但是在本地文件夹还是看不到
随后我执行了git status查看状态,就出现了框中的提示
看到第二条后,我都要感动哭了(恢复文件到工作目录,也可以是文件夹)
执行完后我的文件又回来了,超开心
文章目录 前言一、机器学习绪论1.1.相关术语1.2.假设空间 二、模型评估与选择2.1.经验误差与过拟合2.2.评估方法(数据集划分)(1)留出法(2)交叉验证法(3)自助法 2.3.性能度量 三、线性模型3.1.线性回归3.1.1线性模型(linear model):3.1.2线性回归算法3.1.3优化/损失函数3.1.4线性判别分析(LDA) 四、神经网络4.1 误差逆传播算法( 简称 BP)4.2激活函数 五、支持向量机(SVM)5.1核函数 六、卷积神经网络6.1.卷积层计算6.2.池化层6.3.Dropout层6.4.BN层 七、集成学习7.1AdaBoost7.2学习器结合策略7.3.多样性增强 八、图卷积总结 前言 机器学习相关知识。其中涉及到概率论、线性代数和离散数学知识。
一、机器学习绪论 1.1.相关术语 ◼标记(label):示例的结果信息。
◼样例(example):拥有了标记的示例。(Xi,Yi)表示第i个样例,其中Yi ∈ Y,Y是所有标记组成的集合,称为“标记空间”或“输出
空间”。
◼分类(classification):预测值为离散值的问题。例如,好瓜、坏瓜。
◼回归(regression):预测值为连续值的问题。例如,西瓜成熟度,
0.95、0.37等。
◼二分类(binary classification):只涉及两个类别,通常将其中一
个称为正类(positive class),另一个称为反类(negative class)
◼多分类(multi-class classification):涉及多个类别。
测试(testing):使用模型进行预测的过程。
◼测试样本(testing sample):被测试的样本。
◼泛化(generalization)能力:学得的模型适用于新样本的能力。
◼独立同分布(independent and identically distributed,IID):通
常假设样本空间中全体样本服从一个未知分布(distribution),获
得的每个样本都独立地从这个分布上采样获得,即“独立同分布”。
1.2.假设空间 ◼归纳(induction):从特殊到一般的泛化(generalization)过程,
也就是从具体的事实归纳出一般性规律。
◼演绎(deduction):从一般到特殊的特化(specialization)过程,
也就是从基础原理推演出具体状况。
◼归纳学习(inductive learning):从样例中学习显然是一个归纳的
过程。
◼广义的归纳学习:从样例中学习。
◼狭义的归纳学习:从训练数据中学习概念,因此称为概念生成/概
念(concept)学习。
计算:每个属性的值的种类数加一然后相乘,再加一。
二、模型评估与选择 2.1.经验误差与过拟合 ◼错误率(error rate):m个样本中有a个样本分错,则错误率为a/m。
◼精度(accuracy)、又称准确率 : 1-a/m,即“精度 =1-错误率”。
◼误差(error):学习器实际预测输出与样本真实输出间的差异。
◼经验误差(empirical error):在训练集上的误差,又称“训练误差”
(training error)
◼泛化误差(generalization error):在“未来”样本上的误差。
完整版下载超详细Python算法案例讲解100例.zip-Python文档类资源-CSDN下载 1.问题描述
编写程序模拟福利彩票的双色球开奖过程,由程序产生出6个红色
球和1个蓝色球。
要求:
1)每期开出的红色球号码不能重复,但蓝色球可以是红色球中的
一个。
2)红色球的范围是1~33,蓝色球的范围是1~16。
3)输出格式为“红色球:x x x x x x 蓝色球:x”。
2.问题分析
由问题描述可知,该问题是编程来模拟福利彩票中双色球开奖过
程,因此需要随机生成6个红色球号码和1个蓝色球号码,显然需要使
用Python语言中的random模块来生成随机数。
由题目要求可知“每期开出的红色球号码不能重复”,而使用随机
函数并不能保证每次产生的随机数都不相同,因此在程序设计时需要
判断每次新生成的红色球号码是否和已生成的红色球号码相同,如果
有重复,则需要重新生成新的红色球号码。
3.算法设计
随机生成6个不同红色球号码的功能可使用循环结构来实现。我们
使用数组来保存生成的6个红色球号码。在循环体中需要判断每次新生
成的红色球号码是否与已生成的红色球号码重复。
由于蓝色球号码只有1个,而且可以与红色球的号码重复,因此可
以直接使用随机函数来生成蓝色球号码,并保存在变量中。
4.确定程序框架
(1)产生随机数
产生1~33范围内的随机整数,代码如下:
tmp = random.randint(1, 33)
(2)随机产生红色球号码
定义red数组来保存产生的红色球号码。由题意可知,需要随机产
生6个红色球号码,因此可以使用red数组中下标为0~5的6个元素来保
存红色球号码。
随机产生红色球号码的过程使用while循环结构,循环变量为i,i初
值为0,i<6,在循环体中随机生成不同的红色球号码。需要注意的是,
因为红色球号码是随机生成的,因此有可能两次while循环中产生的红
色球号码恰好相同,这就要求在循环体中必须有相应的代码来判断每
次新生成的红色球号码是否与已生成的红色球号码不相同。如果不相
同,则在red数组的相应位置保存该新生成的红色球号码,否则应该重
新生成新的红色球号码。代码如下:
red = [1] * 6 # 定义red数组,保存随机生成的6个红色球号码,号码范围为1~33 i = 0 # 随机生成6个红色球号码 while i < 6: tmp = random.randint(1, 33) j = 0 while j < i: # 判断已生成的红色球号码是否与当前while循环中产生的随机红色球号码相同 # 如果相同,则重新生成新的红色球号码,否则在red[i]中保存新生成的红色球号码 if red[j] == tmp: break j += 1 if j == i: red[i] = tmp # 将新生成的红色球号码保存在red数组中 i += 1 程序流程图如图12.
1:没有设置之前,选中对应的类名,然后按 alt+enter 快捷键 的情况如下所示 2:设置自动生成 serialVersionUID 的方式如下图所示,关键点已逐个标识 3:设置之后,选中对应的类名,然后按 alt+enter 快捷键,情况如下图2所示,(请不要手敲单词serialversionUID,否则alt+enter不会出现提示结果)。 4:ok,生成成功。
目录 主要数据类型个人出行数据,轨迹数据高速公路观察点数据集其他 出行数据集高速公路数据集其他 赠人玫瑰
如今网上有非常多的数据集,在CSDN,知乎什么搜一下可以找到一大堆,在收集数据时,发现很多数据集整理的文章都是写的一些论文中以及经过预处理的数据,我感觉这样的数据在从新写论文时使用起来非常不方便,因为不知道很多细节,所以我想写一写我搜集数据时搜集到的数据。
主要数据类型 个人出行数据,轨迹数据 推荐使用纽约公开数据集
高速公路观察点数据集 推荐使用英国高速公路数据集
其他 卡口、地铁等等
出行数据集 郑宇,北京出租车数据集,应用于ST-ResNet,原始数据shape=(5596,2,32,32),"2"代表出In/Out两种流量。
北京出租车数据集 原地址
https://github.com/amirkhango/DeepST/blob/master/deepst/models/STConvolution.py
百度网盘分享
链接:https://pan.baidu.com/s/1LY7kg6EP_hkcdINrm_szHg
提取码:0zhl
纽约公开数据集,数据非常全面,谁用谁知道
纽约红绿出租车 https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page
滴滴盖亚计划数据集,链接就不放了。一搜就有
GeoLife GPS Trajectories
该GPS轨迹数据集出自微软研究GeoLift项目。从2007年四月到2012年八月收集了182个用户的轨迹数据。这些数据包含了一系列以时间为序的点,每一个点包含经纬度、海拔等信息。包含了17621个轨迹,总距离120多万公里,总时间48000多小时。这些数据不仅仅记录了用户在家和在工作地点的位置轨迹,还记录了大范围的户外活动轨迹,比如购物、旅游、远足、骑自行车。
https://www.microsoft.com/en-us/download/details.aspx?id=52367
T-Drive Taxi Trajectories
包含在2008年北京一万多俩出租车一周的轨迹数据。这个数据集包含了1500万个坐标点,轨迹的总距离达到900多万公里。 https://www.microsoft.com/en-us/research/publication/t-drive-trajectory-data-sample/
还有其他的数据集,大同小异,我感觉如何是分析出租车出行需求,使用上面这些,特别是纽约的就足够了,纽约数据集非常详细。
如果是要做这方面的,我有一些小小的思路
对数据进行处理方面
(方法一) 将数据根据经纬度与街道进行匹配,就像下面的图
(方法二) 将地图网络分成若干个小区域,
模型方法方面
方法一 CNN+LSTM CNN卷积图片,提取空间信息形成包含空间数据的时间序列,输入LSTM,预测
方法二 GCN 图卷积神经网络,这个还是比较新颖的,网上也有很多文章,就不展开说了(太菜)
高速公路数据集 如果你能翻墙的话,可以尝试Pems{http://pems.dot.ca.gov/},在网页的左下角好像有个data点进去就可以,还需要注册账号。有一些开源的论文中使用了pems的数据,但是大部分都是经过预处理以后的数据,而且观察点需要自己再去找,我感觉比较麻烦,而且在做新研究时,预处理过的数据不是特别适宜。
-下面就是一篇论文中提供的数据,我真的没办法用这样的数据去分析
还是放两个吧Attention Based Spatial-Temporal Graph Convolutional Networks for Traffic Flow Forecasting (ASTGCN) 论文中使用的数据集以及代码。 https://codechina.csdn.net/mirrors/wanhuaiyu/ASTGCN?utm_source=csdn_github_accelerator
内容包括 Diffusion Convolutional Recurrent Neural Network: Data-Driven Traffic Forecasting(DCRNN) https://codechina.
环境:
rk3566 android11
kernel 内核版本,4.19.172
问题描述:
hdmi热插拔相关的问题,当插入HDMI 系统开机启动,并正常运行,HDMI有显示且显示正常,进行热插拔也是没有问题的,当不插入HDMI接口系统启动后,再将HDMI显示接口插入HDMI显示无信号,也无法进行热插拔,无法正常显示画面。当系统启动一端时间后,再插入HDMI插入HDMI能够正常显示,且能够进行热插拔。
问题分析:
首先可以保证我们的HDMI显示驱动是没有问题的,因为我们HDMI是可以正常显示的,那么再来考虑热插拔的问题,以及HDMI中断插入脚是否检测有变化,是否能够检测到我们的HDMI插入变化,再来考虑硬件电路的问题。其逐个排查以上的猜想。
问题解决思路:
由上面的判断,可确认HDMI驱动显示部分是没有问题的,通过与硬件沟通,以及利用示波器量中断脚,当HDMI插入拔出时其HDMI的中断脚有电平的变化,HDMI插入时为高电平,拔出为低电平。分析插入HDMI启动系统与启动时不插入HDMI的kernel完全一样,HDMI的相关LOG完全相同,没有报错,且HDMI初始化正常。。。。。。,说实话到这感觉有点无语,无从下手解决该问题,但是没有办法继续干等着发货,思绪一波,突然发现:(重点)该项目外部显示接口比较多,有edp、hdmi、mipi、lvds显示接口,而rk3566只有一个显示控制器,即VOP,RK356X 平台只有一 VOP,但是分出不同的 PORT,RK3566 有 2 个 PORT 分别为 VP0、VP1。而我的项目上使用的是edp 与HDMI显示是通过VP0,而MIPI 与LVDS 使用的是VP1。而这就是设计到了多屏抢占与热插拔的问题了。而我们本文就是该问题引起的,我发现我的edp屏不管插入或是拔出其状态一直是处于连接状态,而在多屏抢占时,又将EDP设置的优先级设置的最高,这就导致了即使我们插入了HDMI无信号输出,而上面的问题也得以解释了,而上电初始化时,插入HDMI时,系统会优先加载HDMI显示模块,所以的HDMI就会有显示,且处于连接状态。
多屏抢占与热插拔分析:
display_subsystem: display-subsystem { compatible = "rockchip,display-subsystem"; memory-region = <&drm_logo>, <&drm_cubic_lut>; memory-region-names = "drm-logo", "drm-cubic-lut"; ports = <&vop_out>; devfreq = <&dmc>; route { route_dsi0: route-dsi0 { status = "disabled"; logo,uboot = "logo.bmp"; logo,kernel = "logo_kernel.bmp"; logo,mode = "center"; charge_logo,mode = "center"; connect = <&vp0_out_dsi0>; }; route_dsi1: route-dsi1 { status = "
1.http端口测试,使用postman访问即可
2.udp端口测试,在命令行下执行 nc -vu 服务器地址 端口号
四个方法: sort(T[] a):对指定数组进行升序排列。
sort(T[] a, int fromIndex, int toIndex):对指定数组的指定范围升序排列。
sort(T[] a, Comparator<? supre T> c): 根据指定比较器产生的顺序对指定对象数组进行排序。
sort(T[] a, int fromIndex, int toIndex, Comparator<? supre T> c): 根据指定比较器产生的顺序对指定对象数组的指定范围进行排序。
1. 一维数组降序 // 注意,要想改变默认的排列顺序,不能使用基本类型(int,double, char) // 而要使用它们对应的包装类 Integer[] nums = new Integer[]{12, 4, 6, 7, 2, 8, 3, 9}; Arrays.sort(nums, Collections.reverseOrder()); System.out.println(Arrays.toString(ints)); // 结果 :[12, 9, 8, 7, 6, 4, 3, 2] // 或者自定义规则 Arrays.sort(nums, new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o2 - o1; } }); // lambda 表达式 Arrays.
1.说明
在做接口并发测试的时候,由于并发的线程比较多,启动jmeter之后,报错,提示内存溢出,故,需要修改jmeter的内存配置
2.操作步骤
(1)找到jmeter.bat文件
在文件中找到 set HEAP=-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m
电脑---->右键“属性”,查看自己电脑的 内存
确认自己电脑内存大小之后,修改 set HEAP=-Xms1g -Xmx1g -XX:MaxMetaspaceSize=1024m ,建议修改为1024的倍速(1024m=1G)
修改完成之后保存
(2)确认修改是否生效
方案一:启动jmeter.bat 此时,我们会发现,显示的内存大小,并不是我们修改之后的,依鄙人n年的测试经验,断定——bug,绝对的bug,测试干久了总想追根问底;
通过jmeter的源码文件“JMeter.java”找,他这个显示是固定文字,所以不管你设置多少,他总是显示256,所以遇到情况不要慌,看方案二
方案二:通过jconsole.exe验证jmeter内存设置是否成功
打开cmd,输入命令jconsole.exe
可以看到,我们已经修改成功
本文将从UE角度对LTE网络RLC层的polling机制进行详细阐述。
文章目录 前言Polling的目的Polling的触发条件总结参考文献 前言 在LTE网络中,RLC层提供了两种服务模式,一种是保证数据无损传输(lossless)的AM模式(acknowledged mode),另一种是不保证数据可靠传输的UM模式(unacknowledged mode)。在AM模式下,RLC层要保证数据可靠传输,因此,此时的RLC协议是一种可靠性数据传输协议(reliable data transmission protocol, RDP)。
RDP是网络协议中常用的一种协议,TCP协议就是其中之一。与TCP协议相比,RLC位于无线通信协议栈的更底层,对时延的要求更高。因此,为了更快地实现数据的无损传输,RLC层引入了polling(问询)机制。
Polling的目的 UE1在向网络发送数据的过程中,由于物理层存在一定的误码率(BLER),有一些包(packet, 即RLC PDU)有时候可能会在传输过程中发送失败或者丢失。但是,哪一些包发送失败了,从UE侧是无法知道的。因此,为了实现数据的可靠传输,UE需要网络侧的反馈,告诉UE在网络侧哪一些包已经收到,哪一些还没有收到,从而让UE能够重传那些网络还没收到的包,这个反馈就是状态报告(status report)。
但是网络侧怎么能够知道什么时候给UE发送状态报告呢?如果网络侧频繁不停地给UE发送状态报告,那么虽然UE能够很及时地知道网络侧接收情况,但是这样就浪费了很多下行资源;而如果网络侧周期性地给UE发送状态报告,那么UE侧又无法及时得知网络侧的接收情况。引入Polling就是为了这个目的。UE需要向网络询问,哪一些包收到了,哪一些还没收到,这样网络就会回复状态报告,UE就能及时地重传那些没被网络收到(acknowledged)的包。
Polling的触发条件 在每个RLC data PDU的header部分,有一个P位的标志位,这个标志位就代表polling。当P位为1时,表示UE向网络侧发送polling,期望对方回复状态报告,反之亦然。在以下任一条件满足的情况下,UE都会触发polling:
PDU_WITHOUT_POLL >= pollPDUBYTE_WITHOUT_POLL >= pollByte在发送完当前的RLC data PDU后,buffer里不再剩余任何待发送的RLC data PDUt-PollRetransmit 定时器超时 UE每发送一个新的RLC data PDU时,PDU_WITHOUT_POLL会加1;BYTE_WITHOUT_POLL也会增加sizeof(RLC PDU payload)。在更新了PDU_WITHOUT_POLL和BYTE_WITHOUT_POLL后,假如PDU_WITHOUT_POLL ⩾ \geqslant ⩾pollPDU,或者BYTE_WITHOUT_POLL ⩾ \geqslant ⩾pollByte,那么UE需要将该RLC PDU header的P位置1,向网络发送polling。这两个条件保证了UE每向网络发送一部分数据后,都能及时地知道这些数据在网络侧的接收情况。pollPDU 和 pollByte 由网络配置,通过RRC层向RLC层下发。
当UE发送buffer里最后一个新传RLC data PDU时,也应该置P位为1。这也是符合直觉的。因为在发送完最后一个新传RLC data PDU后,UE有可能很长时间都不会发送新的数据了,这时候前两个条件就无法触发了。因此,这时候需要向网络发送polling,获取网络的接收状态报告,然后及时地将前面还没发送成功的包给发送出去。
假如在上面的polling触发,并且重传RLC PDU后,网络侧还是有一些包没收到,而此时UE不再有新的包发送了,那么网络侧岂不是再也收不到这些没收到的包了?针对这个问题,RLC层提供了最后一个polling触发条件,保证了在这种场景下,UE还能向网络发送这些丢失的包。UE在RLC层有一个 t-PollRetransmit 定时器,每当UE发送了polling后,都会启动 t-PollRetransmit 定时器(或者重启,假如此时定时器还在运行)。当 t-PollRetransmit 定时器超时时,假如
buffer(包括RLC data PDU新传队列和重传队列)为空或者无法发送新传RLC PDU(比如此时因为收不到给VT(A)的ACK,导致window stall了) 那么UE需要向网络重传一包RLC data PDU,并将该RLC data PDU的P位置1,向网络发送polling,这样就保证了在无法发送新传的数据时,UE还能收到网络的状态报告,从而重传之前丢失的包,补齐网络侧的接收窗口,而不至于让网络侧长时间无法完全收到这些包。UE在这种场景下向网络侧重传的RLC data PDU,可以选择以下两种之一:
函数Adc_DeInit应为预编译时,可通过配置参数:Adc Adc_DeInit进行配置。
AdcDevErrorDetect :打开或关闭开发错误检测和通知。·true:已启用了检测和通知。·false:检测和通知已被禁用。
AdcEnableLimitCheck :启用或禁用ADC驱动程序中的限制检查功能。
AdcEnableQueuing :如果优先级机制未激活,且静态配置参数AdcEnableQueuing设置为ON,则ADC模块应支持转换请求排队,并按“先到先得”的顺序为软件组服务。
确定在优先级机制被禁用的情况下,队列机制是否处于活动状态。注意:如果启用了优先级机制,则队列机制始终为排队活动且不计算参数 TREE:启用 False:禁用。
Adc_EnableStartStopGroupApi:函数Adc_StopGroupConversion应为预编译时,可通过配置参数AdcEnableStartStopGroupApi.配置开启/关闭
从代码中添加/删除服务Adc_StartGroupConversion()和Adc_StopGroupConversion()。true:可使用Adc_StartGroupConversion()和Adc_StopGroupConversion()。false:可以使用Adc_StartGroupConversion()和Adc_StopGroupConversion()不被使用。
AdcGrpNotifCapability :函数Adc_EnableGroupNotification应为预编译时间,可通过配置参数ON/OFF通知能力配置开启/关闭。
Adc_DisableGroupNotification功能应为预编译时间,可通过配置参数AdcGrpNotifCapability⌋进行开启/关闭配置
从代码中添加/删除服务Adc_EnableHardwareTrigger()和Adc_DisableHardwareTrigger()。
true:可以使用Adc_EnableHardwareTrigger()和Adc_DisableHardwareTrigger()。
false: Adc_EnableHardwareTrigger()和Adc_DisableHardwareTrigger()不能使用。
AdcCalibrationApi :api从代码中添加或删除服务Adc_ChangeCalibrationChannel()、Adc_SetCalibrationValue()、Adc_GetCalibrationAlternateValue()和Adc_GetCalibrationValue()。
AdcPriorityImplementation*:确定是否有优先级机制来确定转换请求的优先级,如果可用,则确定优先级机制的类型。此选择适用于具有触发源软件和触发源硬件的组。可以选择两种类型的优先级排序机制。硬件优先级排序机制(AdcPriorityHw)使用ADC硬件功能来对具有触发源硬件的组的软件转换请求和硬件触发信号进行优先级排序。混合硬件和软件优先级机制(AdcPriorityHwSw)使用ADC硬件特性对具有触发源硬件的组进行ADC硬件触发的优先级,并为具有触发源软件的组实现优先级机制。软件触发组的组优先级通常配置的优先级低于硬件触发组的组优先级。ImplementationType: Adc_PriorityImplementationType
AdcReadGroupApi :从代码中添加/删除服务Adc_ReadGroup()和服务。正确的:Adc_ReadGroup()可以被使用。错误:Adc_ReadGroup()不能被使用。
AdcResultAlignment :在ADC结果缓冲区中的ADC原始结果进行对齐(左右对齐)。实施类型:Adc_ResultAlignmentType。
当配置参数“AdcResultAlignment”设置为“ADC_ALIGN_LEFT”时,需要设置向左移动4位的配置值。如果启用了配置参数adcchannelresultsigned,则需要设置signed值。当配置参数AdcResultAlignment设置为adc_align_right时,可以使用此参数。否则,该参数禁用。
AdcVersionInfoApi:从代码中添加或删除服务Adc_GetVersionInfo()。
AdcErrorCalloutFunction:无论启用或禁用默认错误检测,都会对检测到的每个错误调用错误调出处理程序。错误调出处理程序是一个ASIL安全扩展,不是由AUTOSAR指定的。通过配置参数AdcErrorCalloutFunction配置。
设置该参数为FALSE将禁用通过DET通知开发错误。然而,与AUTOSAR规范相比,开发错误检测仍然是启用的,错误将通过AdcErrorCalloutFunction报告。
AdcErrorCalloutFunction用于指定错误调用函数名称。每次出现错误都会调用该函数。该函数的ASIL级别限制ADC驱动的ASIL级别。
当发生错误时,将调用错误钩子例程(通过参数AdcErrorCalloutFunction配置),并将错误码、服务ID、模块ID和实例ID作为参数传递。
AUTOSAR ADC模块需要一个错误调出处理程序。每个错误都报告给这个处理程序,错误检查不能关闭。要调用的函数名可以通过参数AdcErrorCalloutFunction来配置。
AdcChannelValueSigned :说明ADC驱动程序的结果值是否有符号信息(true)或(false)。如果将结果解释为signed值,则适用于c语言规则。
AdcGroupFirstChannelFixed: 告知ADC通道组的第一个通道是否可以配置(FALSE)或固定(TRUE)为由ADC HW单元确定的值。
AdcMaxChannelResolution: 以位为单位的最大通道分辨率(不指定精度)。