防止SQL注入攻击的10种有效方法

目录 1. 使用参数化查询2. 输入验证和过滤3. 使用存储过程4. 最小权限原则5. 使用ORM框架6. 使用准备语句7. 使用安全的数据库连接8. 避免动态拼接SQL语句9. 使用防火墙和入侵检测系统10. 定期更新和维护数据库软件小结: 本文介绍了10种有效的方法来防止SQL注入攻击。SQL注入是一种常见的网络安全威胁,攻击者通过在用户输入中插入恶意的SQL代码,从而可以执行未经授权的数据库操作。这些方法包括使用参数化查询、输入验证和过滤、存储过程、最小权限原则、ORM框架、准备语句、安全的数据库连接、避免动态拼接SQL语句、使用防火墙和入侵检测系统以及定期更新和维护数据库软件。通过采取这些预防措施,可以大大降低SQL注入攻击的风险,保护数据库和应用程序的安全性。 1. 使用参数化查询 使用参数化查询可以防止SQL注入攻击,并提高代码的可读性和可维护性。在Java中,可以使用PreparedStatement来实现参数化查询。下面是一个使用参数化查询的Java代码示例: import java.sql.*; public class ParameterizedQueryExample { public static void main(String[] args) { Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { // 连接到数据库 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/database", "username", "password"); // 创建PreparedStatement对象 String query = "SELECT * FROM users WHERE username = ? AND password = ?"; stmt = conn.prepareStatement(query); // 设置参数值 String username = "

Spring创建Bean源码 - 加载配置类

在《Spring创建Bean源码 - 解析配置类》中已经介绍了Spring是怎么解析配置类的,这个章节主要介绍Spring是怎么将解析后的配置类加载并注册到Spring中的。 以下是包含了解析配置类和加载配置类的代码片段。**this.reader.loadBeanDefinitions(configClasses)**就是将解析后的配置类加载并注册到Spring的代码片段。 public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); //获取已经注册进来的Bean名称 String[] candidateNames = registry.getBeanDefinitionNames(); for (String beanName : candidateNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); //判断某个类中是否存在 configurationClass属性 if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } //判断BeanDefinition是否是一个配置类 else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { //配置类加入配置集合 configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // Return immediately if no @Configuration classes were found if (configCandidates.

Axure9中怎么删除整个的树菜单元件

步骤一:page中拖入树菜单元件 步骤二:此时通过选中元件,点击键盘delete按钮,无法完全删除树元件 步骤三:此时想要完全删除,可以点击左侧的导航栏中的概要tab页,找到要删除的树元件,选中树元件,点击delete按钮即可删除

一年左右工作经验前端面试分享(vue 方向)

当前更新日期:2023-06-28 学习的时候也要记得做做题哦 我做了一份 前端笔试题记录 请服用 还有一份 让GPT给我出JS笔试题 还有一份 中级前端工程师基础面试一面口吻 HTML部分 什么是 块级元素 和 行内元素?p标签是块级元素,常理来说,块级元素是可以嵌套块级元素和行内元素的,但是p标签是个特殊,它里面不能嵌套块级元素。网页中,rem 作为元素尺寸单位时,是相对 文档根节点的 font-size 进行计算的。块级元素实际占用的宽度与它的 background 属性有关。语义化标签的使用(写html不要只会div哦)。 HTML5 的有什么新特性和改进? 新增标签:HTML5引入了一些新的标签,如<video>、<audio>、<canvas>、<svg>等,使得在网页中嵌入多媒体内容和图形变得更加方便和直观。 语义化标签:HTML5引入了一系列语义化标签,如<header>、<nav>、<aside>、<article>、<section>、<footer>等,这些标签能够更准确地描述网页的结构和内容,有助于提高可访问性、搜索引擎优化和代码可读性。 表单增强:HTML5为表单提供了许多增强功能,如新增的输入类型(例如日期、时间、邮箱、电话等)、表单验证、自动完成和本地存储等,使得表单交互更加强大和用户友好。 离线应用:HTML5引入了离线应用缓存(Application Cache)机制,允许开发者将网页资源缓存到用户本地,即使在离线状态下也能访问网页,提供了更好的离线体验。 Web存储:HTML5提供了本地存储的能力,包括Web Storage(localStorage和sessionStorage)和IndexedDB,使得网页能够在客户端存储和检索数据,提供了更高效的数据管理。 多媒体和图形支持:HTML5通过新增的<video>、<audio>和<canvas>标签以及SVG(可缩放矢量图形)的支持,为多媒体内容和图形绘制提供了更直接、更强大的方式。 Web Components:HTML5引入了Web Components标准,包括自定义元素(Custom Elements)、影子DOM(Shadow DOM)和HTML模板(HTML Templates),使得开发者能够创建可重用的自定义组件,提升了代码的可维护性和复用性。 CSS部分 - CSS盒模型 box-sizing (常问) 标准模型 和 IE模型的区别就在于 width 和 height 的计算方式不同。 标准盒模型 content-box width 只等于内容区域,不包括border和padding怪异(IE)盒模型 border-box width = 内容区宽度 + border + padding - CSS权重 (常问) !important > 内联样式(1000) > id选择器(100) > class选择器(10) = 伪类选择器(10) = 属性选择器(10) > 元素选择器(1)

VS2019安装教程

安装工具如下图: 第一步:安装:双击运行可执行程序exe进行安装如下图 这里在进行安装文件的解压稍作等待 第二步:等待一段时间后进入到系统和安装文件验证界面,点击继续,继续等待 第三步:等待一段时间后自动进入到安装界面 上图的左下角部分为安装盘符路径选择,可以自定,但切记路径中不可以出现任何中文包括中文符号也不可以,安装时需要选择需要安装的插件部分,不要看上图所示,需要安装的插件以下图所列为准 勾选以下自己会需要用到的需要安装的插件 我是在windows下开发的连接Linux系统的C++语言开发,故选择以下插件 第四步:定好路径和插件点击安装进入以下界面,这里是根据个人电脑的性能不同可以消耗的时间也不同,我的电脑大概需要20分钟左右,在安装的过程中是需要全程联网的,安装结束后,会提示重启电脑,然后我们点击“立刻重启”

性能测试 —— Jmeter脚本编写

一、万能法 先把项目启动 打开项目接口文档,接口文档: 一般是开发 特别注意事项:当你的接口请求参数为json格式时,一定要写请求头,请求头中一定要有 Content-Type: application/json(响应体的格式) 如果没有这个信息,100%报错,不局限于jmeter http请求包括哪些部分 请求行:请求方法,请求地址URI 请求头:Content-Type、cookie、User-Agent 空一行 请求体:参数: 表单 和消息体数据: json 、xml json格式:{"key":"value","key1":1} 键值对 开发人员接口中定义的返回码code,和http response_code不一样 http response_code: 2xx: 网络请求超过 200 3xx: 重定向相关 301 4xx: 请求URL地址有问题 400 404 5xx: 服务器内部异常 500、502 bad gatway 而开发人员在接口中定义的code为响应代码,如0、1、2、3,会有码表来查询 写脚本 测试计划上右键, 添加 线程组 线程组上右键,添加 取样器> http请求 (http协议簇) 线程组上右键,添加 监听器 > 查看结果树 一个最简单的jmeter脚本,包括,线程组、取样器、监听器 线程组: 性能测试中用于场景设计的,写脚本阶段不用改动。 取样器: 根据不同的协议,编写不同的脚本(填空)。 监听器: 调试脚本时使用,性能测试执行时,禁用。原因是不管哪种监听器,都是对结果数据进行不同维度的展示,这些展示,是需要消耗本地资源的。 HTTP信息头管理器:添加 Content-Type:application/json 8. tomcat的默认端口:8080 http协议的默认端口:80 https协议默认端口: 443 内容编码:utf-8 脚本需要保存之后再运行:jmeter的默认保存路径,jmeter的bin文件夹,可以更改名字 二、请注意: 当请求体为json, 一定要有请求头 Content-Type:application/json。

使用UglifyJS实现一条指令打包发布项目实例

在前端页面开发中,使用Vue、Angular、React等框架构建的项目通常都会自动配置集成相关代码压缩发布的工具,开发者只需要执行指定命令即可完成项目的整体压缩发布操作。对于没有使用框架的项目,需要开发者手动配置使用相关工具完成对应操作,本文介绍使用UglifyJS实现代码打包压缩的方法。 1、建立示例项目 按照一般项目目录添加目录及文件如下: Demo目录为项目根目录,src目录下包含全部源文件。源文件包含一个index.html及其引用的三个js文件。 a.js包含了一个求和的方法: b.js包含一个求积的方法: index.js包含页面load方法,用于演示求和求积方法: 页面打开就显示两个运算结果: 此时,页面加载了全部的四个源文件,且都未经过压缩打包,能看到全部的源代码包括注释: 2、打包目标 为减少请求,将a.js、b.js、index.js合并为一个index.js(实际项目中根据实际需求考虑是否需要合并),使用一条指令(npm run build)就能完成打包发布操作。打包后文件存放于demo/dist/目录,不修改源文件。 3、安装UglifyJS UglifyJS是个包含JS解释器、代码最小化、压缩、美化的工具集,是前端开发打包的最常用工具之一。UglifyJS基于Node.js开发,所以要确保安装了Node.js环境。首先使用指令完成项目的node初始化配置: npm init -y 项目初始化完成后,为项目添加并安装UglifyJS依赖包: npm install uglify-js --save-dev 以上步骤完成后,项目的打包工具就安装完成了,此时项目多了package.json及安装的node_modules: 4、配置打包指令及脚本 在package.json的脚本节点添加打包指令: 当使用npm run build 指令时就会调用 node build.js 执行build.js脚本文件。 接下来就是编写build.js脚本文件,在项目根目录新建build.js文件。 脚本文件需要完成的工作有: 4.1、清除原有dist目录中的文件。 编写清空目录方法,清空dist目录: const fs = require('fs'); const path = require('path'); const UglifyJS = require("uglify-js"); //递归清空目录 function clearDirectory(dirPath) { if (!(fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory())) return; const files = fs.readdirSync(dirPath); for (const file of files) { const filePath = path.

Linux系统宝塔安装与卸载详解

安装宝塔 原文:Consider God’s handiwork.Who can straighten what he hath made crooked? 译文:你要察看神的作为。神使之为曲的,谁又能使之变直呢?——《传道书》第七章第十三节 一、准备工作 链接工具:Xshell (作者使用Xshell7) Linux系统:CentOS(作者使用CentOS7.9) 宝塔官网地址 二、Linux系统宝塔安装 常用Linux系统安装命令 Centos安装脚本 yum install -y wget && wget -O install.sh https://download.bt.cn/install/install_6.0.sh && sh install.sh ed8484bec Ubuntu/Deepin安装脚本 wget -O install.sh https://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh ed8484bec Debian安装脚本 wget -O install.sh https://download.bt.cn/install/install-ubuntu_6.0.sh && bash install.sh ed8484bec 万能安装脚本 if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec 国产龙芯架构安装脚本(其他CPU请勿使用) wget -O install_panel.

STM32单片机(二)STM32环境搭建

❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋。 🌙专栏目标:实现从零基础入门51单片机和STM32单片机,力求在玩好单片机的同时,能够了解一些计算机的基本概念,了解电路及其元器件的基本理论等。 ⭐️ 专栏主要内容: 主要学习STM32单片机的功能、各个模块、单片机的外设、驱动等,最终玩好单片机和单片机的外设,全程手敲代码,实现我们所要实现的功能。 🌴 专栏说明 :如果文章知识点有错误的地方,欢迎大家随时在文章下面评论,我会第一时间改正。让我们一起学习,一起进步。 💑专栏主页:http://t.csdn.cn/HCD8v 本学习过程参考:https://space.bilibili.com/383400717 STM3单片机安装软件、各种资料以及源码的路径: 链接:https://pan.baidu.com/s/1snD0uuTfMhchFqOMWvAiHA?pwd=asdf#list/path=%2F 提取码:asdf 链接里压缩包的解压密码:32 本节主要对STM32环境搭建过程进行简单介绍,其中包括软件安装和新建工程两部分;其中软件安装包括安装Keil5 MDK、安装器件支持包、软件注册、安装STLINK驱动、安装USB转串口驱动等;新建工程部分包括STM32开发方式简介以及新建标准库工程等。 文章目录 一、软件安装1.1 安装Keil5 MDK1.2 安装器件支持包1.2.1 离线安装1.2.2 在线安装 1.3 软件注册1.4 安装STLINK驱动1.5 安装USB转串口驱动 二、新建工程2.1 STM32开发方式简介2.2 新建标准库工程2.2.1 新建工程2.2.2 添加启动文件2.2.2.1 添加启动文件2.2.2.2 添加寄存器描述文件2.2.2.3 添加内核寄存器描述文件2.2.2.4 以上文件添加到工程2.2.2.5 在工程中添加头文件路径 2.2.3 新工程测试2.2.4 配置寄存器实现点灯2.2.5 使用库函数实现点灯2.2.6 补充:库函数中的启动文件选择2.2.7 总结:新建工程的步骤 一、软件安装 软件的下载链接: STM3单片机安装软件、各种资料以及源码的路径: 链接:https://pan.baidu.com/s/1snD0uuTfMhchFqOMWvAiHA?pwd=asdf#list/path=%2F 提取码:asdf 链接里压缩包的解压密码:32 1.1 安装Keil5 MDK 解压 资料/Keil5 MDK.zip,解压之后,(右键管理员权限打开)MDK524.EXE文件,开始安装软件,注意路径不要有英文,不要选择带有特殊权限的盘;选Next->勾选同意许可协议->Next->选择安装目录(如果不想放在C盘,也可以在创建英文目录,记得创建文件夹时起英文名字)->Next->填写个人信息(随便填)->Next,等待安装即可; 安装过程中会让选择是否安装ULINK驱动,选择是就行: 可以将Show Release Notes 取消勾选: 最后点击Finish,接下来就会自动弹出一个Pack Installer的窗口,这个窗口就是用来安装器件支持包的,我们先把它叉掉,后面再讲: 1.2 安装器件支持包 首先来介绍一下为什么需要要安装器件支持包,这个支持包是Keil5才需要安装的,想Keil4和之前的老版本,是不需要安装的;这是因为现在的ARM芯片型号是非常多的,升级换代速度也快;新型号的芯片也是不断地推出来,那Keil软件总不能出一款芯片就升级一下软件吧,而且同时支持所有型号的芯片,这个占用内存也是非常大的,所以Keil5之后,芯片的器件支持包就被独立出来了;我们开发哪种芯片,就安装对应的支持包就行;如果你不安装支持包,那在新建工程时,是不会出现相应的器件型号的;

Visual Studio (2022)安装配置pthread.h多线程库

各位好,之前尝试用DEVC++编写多线程库问题时遇到报错,然后发现解决不了后转战Visual Studio。顺带分享一下安装方法。 首先是pthread的下载网站:https://www.mirrorservice.org/sites/sourceware.org/pub/pthreads-win32/ 选择最新的(最下面)那个版本下载。 Windows选下面那个 解压完成后我们会得到三个文件夹,这里我们只用到第一个(Pre-built.2)。 接着我们打开Visual Studio,新建一个项目,然后再新建项目的解决方案资源管理器中对应的项目那里点击右键->属性。 然后再配置属性->VC++目录->常规中的包含目录和库目录中,分别添加我们刚才解压出来文件(Pre-built.2)中的include和lib目录地址。(包含目录添加include,库目录添加lib)具体操作如下: 库目录与包含目录的操作是一致的,这里不再演示,但要注意lib中含有两个文件夹,分别是X64和X86,这个要看自己电脑实际情况。 然后在链接器->输入->附加依赖项一栏中和刚才一样打开,在上面一栏中填入pthreadVC2.lib,然后确定。 这里我运行程序报了两个错,一是提示找不到pthreadVC2.dll,二是提示timespec”;”struct”类型重定义。我们一个一个解决。 一的问题在pthreadVC2.dll文件的定位,为了方便我们直接把pthreadVC2.dll复制到项目的Debug文件夹中。(pthreadVC2.dll位于pthreads-w32-2-9-1-release\Pre-built.2\dll\x64,这里也要根据自己电脑选择x86还是x64) Debug位于你创建的项目文件夹中。 Debug位置 第二个问题解决起来很简单,我们先在源程序中添加头文件#include <pthread.h>然后按住Ctrl鼠标左键单击<pthread.h>(这个头文件会变成一个超链接,我们就可以进入到头文件代码段) 然后在pthread.h加入这段代码: #define HAVE_STRUCT_TIMESPEC 完成就可以成功运行啦。 以上,谢谢阅读,感谢你的时间。

Spring创建Bean源码 - 解析配置类(一)

发现所有的配置类 主要作用发现BeanDefinitionRegistry对象中的配置类**(带有****@Configuration****注解的类),**利用配置类中的特定注解信息派生出更多的BeanDefinition。 public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); //获取已经注册进来的Bean名称 String[] candidateNames = registry.getBeanDefinitionNames(); for (String beanName : candidateNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); //判断某个类中是否存在 configurationClass属性 if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } //判断BeanDefinition是否是一个配置类 else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { //配置类加入配置集合 configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // Return immediately if no @Configuration classes were found if (configCandidates.

操作系统—复杂的生产者-消费者问题(C语言,线程,含代码)

各位好,这里是太阳终于出来啦,这次分享的是操作系统课程中的复杂的生产者-消费者问题的具体程序。 目录 一、写在前面 二、关于多线程在C语言中的使用 pthread_create() 函数声明 参数 pthread_join() 函数声明 参数 sem_init() 函数声明 参数 sem_wait()&sem_post() 三、题目要求 四、思路分析 五、代码及说明 一、写在前面 1.本人并不擅长编程,各位可以交流学习,如果有错误欢迎指出。 2.不保证思路和解决方式是最佳思路,也不能保证正确性,请勿将本文当做考试复习参考。其中涉及到专业名词的部分可能会有描述错误,请谅解。 3.本人个人写代码不习惯写注释,变量的命名也很随意,请谅解。 4.本文会讲述全部代码思路,代码需要自己整合,仅作为交流。如果是想要直接复制完整代码的本站有其他大佬的分享帖。 5.请谅解文章中的错别字,标点符号,以及的地得! 6.ncwu慎用。 二、关于多线程在C语言中的使用 关于pthread.h的配置请看这篇文章Visual Studio (2022)安装配置pthread.h多线程库 在这里只对我用到的几个函数做说明: 位于<pthread.h>部分的 pthread_create() 用于创建线程 函数声明 int_cdecl pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(_cdecl *start)(void *), void *arg) 参数 第一个参数为指向线程标识符的指针,type: pthread_t*第二个参数用来设置线程属性第三个参数是线程运行函数的起始地址, type: (void*)(*)(void*)第四个参数是运行函数的参数,type: void * pthread_join() 等待线程的结束,线程间同步的操作 函数声明 int_cdecl pthread_join(pthread_t *thread, void **value_ptr) 参数 第一个参数为指向线程标识符的指针,type: pthread_t*第二个参数用户定义的指针,用来存储被等待线程的返回值。type: void** 位于<semaphore.h>部分的 sem_init() 用于创建并初始化一个定位在 sem的匿名信号量。 函数声明 int_cdecl sem_init(sem_t *sem, int pshared, unsigned int value)

操作系统—电梯调度模拟程序(C语言,数据结构,含代码)

各位好,这里是太阳终于出来啦,这次分享的是操作系统课程中的电梯模拟程序,虽然个人的观点是这个程序和操作系统的关系不大,倒像是数据结构的练习。所以各位就姑且当数据结构来看吧。 目录 一、写在前面 二、题目要求 三、思路分析 四、主函数及变量说明 五、结果及说明 一、写在前面 1.本人并不擅长编程,各位可以交流学习,如果有错误欢迎指出。 2.不保证思路和解决方式是最佳思路,也不能保证正确性,请勿将本文当做考试复习参考。其中涉及到专业名词的部分可能会有描述错误,请谅解。 3.本人个人写代码不习惯写注释,变量的命名也很随意,请谅解。 4.本文会讲述全部代码思路,代码是按模块分段展示的(也会在文中提及主函数的编写逻辑),代码需要自己整合,有编程基础的朋友一定能在阅读后根据提示写出完整程序。因为看到很多朋友在解决此法时遇到困难,仅作为交流。如果是想要直接复制完整代码的本站有其他大佬的分享帖。 5.请谅解文章中的错别字,标点符号,以及的地得! 6.ncwu慎用。 二、题目要求 电梯的模拟程序 基本条件如下: 楼层:1-21 电梯容量:10个人 电梯每0.5s经过一个楼层 初始一楼有30人等电梯并且每5s会来0-2个人 每5s输出一次电梯一共走过的层数,电梯目前所在的层数,一楼所等待的人数 三、思路分析 这里,我的想法是为每一个乘客创建一个结构体,然后每一层的等待乘客是一个链表,电梯内的乘客自己也是一个链表,每有一个乘客上电梯,就把楼层链表中的相应乘客移动到电梯的列表中,而每有一个乘客下电梯就把电梯链表中的相应元素删除。 这里其实题目中只要求了一楼会每隔5秒来人,但是这里想优化一下就是,凡是有人下电梯(不是一楼)那么这个楼层也会来人(当然这里也是随机,且来的人数不能大于下电梯在这里楼的人数,虽然现实中会存在爬楼梯什么的不用考虑这么复杂,我们就先当这个大楼没有楼梯来着,主要是程序编好了才想到有楼梯这回事……) 具体说明如下: typedef struct LNode //每个乘客一个链表项 { int from; int to; int uod;//上行还是下行 ,1表示上行 struct LNode *next; }LNode,*LinkList; 这里方便管理用的是链表而不是顺序表。from是每个乘客出发的楼层,to是每个乘客到达的楼层,uod是up_or_down,记录电梯是上行还是下行,因为电梯是有点像磁盘的LOOK调度,他要一直同一个方向送到(当前乘客或有人等待的楼层)最大值(或最小值)然后再转向。所以只有电梯运行方向和乘客运行方向一致时,乘客才会上电梯。 这里一共创建了三个函数,分别是链表添加,链表转移和链表删除。 void createlinklist(LinkList &L,int n,int f); int addlinklist(LinkList &L,LinkList &LL,int a,int b);//a表示电梯状态 void movelinklist(LinkList &L,int a);//a表楼层 这里基本与链表操作一致,只说明适配这个程序的不同之处,这里的链表初始化我放在了主程序里,因为本身链表就不想多建一个函数,而在链表的添加函数中,开始需要移动指针到最后然后用后插法插入新的节点,要注意的有两点,一是生成的随机数不能与当前楼层相同,二是要判断上行还是下行。 完整代码如下: void createlinklist(LinkList &L,int n,int f){//n表示链表生成数量,f表示楼层 LNode *p=NULL, *r=NULL; int i,t; r=L; while(r->next) r=r->next; for(int i=1;i<=n;i++){//创建n个链表,每个链表就代表一个乘客 p=new LNode; p->from=f; t=random(1,21); while(t==f) t=random(1,21); p->to=t; if(f<t) p->uod=1; if(f>t) p->uod=0; p->next=NULL; r->next=p; r=p; } } Random为在程序开头的宏定义

正则表达式之match()

正则表达式是处理字符串的强大工具,有自己特定的语法结构,可以实现字符串的检索、替换、匹配验证。 开源中国提供的正则表达式测试工具,输入待匹配的文本,然后选择常用的正则表达式就可以得出相应的匹配结果了。 对于URL来说,可以用下面的正则表达式匹配:[a-zS-z]+://[^\s]*。 用这个正则表达式去匹配一个字符串,如果中国字符串包含类似URL的文本,就会被提取出来。 这个正则表达式看上去是乱糟糟的一团,其实不然。如a-z代表匹配任意小写字母,\s表示匹配任意的空白字符,*就代表匹配前面的字符可以任意多个。 python的re库提供了整个正则表达式的实现。 1.match() match()方法会尝试从字符串的起始位置匹配正则表达式,如果匹配,就返回匹配成功的结构;如果不匹配,就返回None。示例如下: import re content='Hello 1234567 World_This is a Regex Demo' result=re.match('^Hello\s(\d+)\sWorld',content) print(result) print(result.group()) print(result.group(1)) print(result.span()) 运行结果如下: <re.Match object; span=(0, 19), match='Hello 1234567 World'> Hello 1234567 World 1234567 (0, 19) group()会输出完整的匹配结果,而group1()会输出第一个被()包围的匹配结果。 1.通用匹配 .*(点星)是一个万能匹配。其中.(点)可以匹配任意字符(除换行符),*代表匹配前面的字符无限次。 import re content='Hello 1234567 World_This is a Regex Demo' result=re.match('^Hello.*Demo$',content) print(result) print(result.group()) print(result.span()) 这里我们将中间部分直接省略,全用.*来代替,最后加一个结尾字符串。运行结果如下: <re.Match object; span=(0, 40), match='Hello 1234567 World_This is a Regex Demo'> Hello 1234567 World_This is a Regex Demo

华为mindspore-如何训练一个gpt一样的文本生成模型

CausalLanguageModelingTrainer Task For Trainer. Args: model_name (str): The model name of Task-Trainer. Default: None Examples: >>> from mindformers import CausalLanguageModelingTrainer >>> gen_trainer = CausalLanguageModelingTrainer(model_name="gpt2") >>> gen_trainer.train() >>> res = gen_trainer.predict(input_data = "hello world [MASK]") Raises: NotImplementedError: If train method or evaluate method or predict method not implemented. 初始化 def __init__(self, model_name: str = None): super(CausalLanguageModelingTrainer, self).__init__("text_generation", model_name) 很简单的代码,用的是父类BaseTrainer,并传入两个参数:"text_generation", model_name 训练 def train(self, config: Optional[Union[dict, MindFormerConfig, ConfigArguments, TrainingArguments]] = None, network: Optional[Union[Cell, BaseModel]] = None, dataset: Optional[Union[BaseDataset, GeneratorDataset]] = None, wrapper: Optional[TrainOneStepCell] = None, optimizer: Optional[Optimizer] = None, callbacks: Optional[Union[Callback, List[Callback]]] = None, **kwargs): r"

Vue 项目中使用WebSocket 消息推送

一、功能需求 1.这是我在后台管理项目中使用到的,主要的作用是搞一个消息提醒的功能。 2.主要有右上角的提示和有下角的消息弹框。 3.主要实现的功能是如果用户有未读的消息,那么首次登录就弹框,如果用户关闭了页面,那么再次刷新页面的时候,也不再弹框,意思就是一个账户没有退出之前,也没有实时消息推送的时候,只弹一次框。 4.如果用户点击了未读消息,那么就会将此条消息置位历史(已读)。 页面展示: 二、页面代码 备注:我的是后台管理系统(用的是vue-element-admin),第一次写websocket,所以我写在了src->layout->AppMain.vue文件下面: <template> <section class="app-main"> <Message-remind :message-list="messageList" /> <transition name="fade-transform" mode="out-in"> <keep-alive :include="cachedViews"> <router-view :key="key" /> </keep-alive> </transition> </section> </template> <script> import MessageRemind from '@/components/MessageRemind/index.vue' import { getToken, getSid } from "@/utils/auth"; // get token from cookie export default { name: 'AppMain', components: { MessageRemind }, watch: { '$store.state.user': { handler: function (newValue, oldValue) { // 如果没有token,则表明退出了登录 if (!newValue.token) { this.closeWebSocket(); } }, immediate: true, deep: true } }, data() { return { // socket参数 socket: null, timeout: 60 * 1000, // 45秒一次心跳 timeoutObj: null, // 心跳心跳倒计时 serverTimeoutObj: null, // 心跳倒计时 timeoutnum: null, // 断开 重连倒计时 lockReconnect: false, // 防止 websocket: null, messageList: {} }; }, created() { const hasToken = getToken(); const sid = getSid(); if (hasToken) { this.

VS CODE利用SSH连接远程服务器

1.在VS CODE中下载插件:Remote - SSH 2. 找出SSH配置文件config 寻找步骤如下: 2.1 先点击左下角绿色图标"打开远程窗口" 2.2 选择Open SSH Configuration File 2.3 选择自己.ssh\config文件 3.按照如下格式进行填充 Host xxx HostName xxx Port xxx User xxx ForwardAgent yes 注意:xxx处是要自己填内容,Host代表自己登录名称(可能支持多个名称,这个随意),HostName是远端主机的IP地址,Port是远端主机的端口号,User是要登陆的用户名 4.尝试登录,还点第一步的绿色图标 再输入密码即可! 上面的步骤是之前写的,最近再次使用的时候,发现会出现一个问题,在此提供解决方案: 有时在连接远端开发环境时,可能会遇到: "Setting up SSH Host xxx: Downloading VS Code Server locally" 这个问题可能会持续超过10分钟。为了解决这个问题,步骤如下: 打开VS Code菜单"View"->“Command Palatte”->“Kill VS Code Server on Host”,然后杀掉上面的VS Code server。然后重新尝试登陆 参考:https://blog.csdn.net/blmoistawinde/article/details/109822984

Linux命令:Nvidia显卡状态监控命令

有时候需要在linux中一直监控显卡的状态,包括功率,温度,显存占用。 因此使用 Nvidia显卡状态监控命令: # 使用watch命令 watch -n 0 nvidia-smi 0是几秒刷新一下

电表的698通信协议

原文连接:https://blog.csdn.net/ss86655/article/details/109997891 该协议规定了用电信息的数据交换过程,一般用于主站与电能表之间、终端与电能表之间的数据交换,主站与终端一般用不同的客户机地址来区分。 1、通信架构 有两种方向的数据交换。 是请求/响应类型的数据交换,主机请求从机,从机提供响应,涉及到读取、设置、操作、代理等服务。通知/确认类型的数据交换,从机主动上报,主机回复确认,涉及到上报服务,在开发过程中,主机指客户机,包括主站(某上位机)或终端(集中器),从机指服务器,这里就是电表。 二:帧结构 (1)698采用异步传输,不需要接收方和发送方时钟的同步,会有起始字符,结束字符。帧格式如图: 举例: 68 1f 00 43 05 08 00 00 00 00 00 10 b5 0b 06 01 04 40 00 02 00 1c 07 e0 09 0b 12 1e 00 00 05 69 16 ①.起始的68:代表字符的起始码; ②.末尾的16:代表结束字符。 ③1f 00:长度域,由2字节组成,取bit0-bit13,指除起始字符和结束字符之外的帧字节数。注意此处实际应为00 1f,因为我用到的上位机软件设计如此。这里指这一串数据有1f字节,即31字节。 ④ 43:控制域,1字节,定义如下图,16进制的43转为二进制即:01000011。 4.1 bit7和bit6组合的意义如下图: 4.2 功能码定义如下图: 可看出来该帧是由客户机发起一个请求,功能码为应用连接管理及数据交换服务,实际上,这也是用得最多的一个功能码。 ⑤ 05 08 00 00 00 00 00:服务器地址。服务器地址定义如下: bit0-bit3:地址字节数,注意此处是加1表示字节长度 bit4-bit5:逻辑地址 bit6-bit7:0表示单地址,1表示通配地址,2表示组地址,3表示广播地址 此处05 08 00 00 00 00 00中,05表示单地址,地址长度为5+1,08 00 00 00 00 00表示真实地址00 00 00 00 00 08.