vue+springboot实现图形验证码Kaptcha

1、前端 form使用了element-ui的组件,主要还是看img标签,src绑定了form.imgCodeUrl数据,点击图片时触发refreshCode更新图片验证码。 <el-form-item prop="verificationCode" label="验证码" style="text-align: left;"> <el-input v-model="form.verificationCode" placeholder="请输入验证码" style="width: 120px;vertical-align: top;"></el-input> <img id="img" alt="验证码" @click="refreshCode" :src="form.imgCodeUrl" style="padding-left: 12px;"/> </el-form-item> data() { return { form: { username: '', password: '', verificationCode:'', imgCodeUrl:this.$verificationCodeUrl, }, ... ... refreshCode(){ this.form.imgCodeUrl=this.$verificationCodeUrl+"?d="+new Date().getTime(); } 上面refreshCode更新图片验证码的原理,其实就是在原网址后添加随机的参数来改变form.imgCodeUrl网址,实现img标签自动刷新请求。 this.$verificationCodeUrl是请求的网址,这里设置成全局常量写在了main.js中 //验证码地址 Vue.prototype.$verificationCodeUrl="http://127.0.0.1/api/createImageCode"; 2、后端实现生成createImageCode验证码图片 使用kaptcha生成图片验证码,添加如下依赖 <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> </dependency> 配置kaptcha图片生成规则 ... import java.util.Properties; @Configuration public class KaptchaConfig { @Bean public DefaultKaptcha getDefaultKaptcha() { DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); Properties properties = new Properties(); // 图片宽 properties.

通俗理解信号量

信号量本质上是一个加锁原语,让等待者进入睡眠状态,直到等待的资源变为空闲。信号量可分为内核信号量和IPC信号量(用于进程间同步),二者都是计数器,用来为多个进程或者线程共享的数据结构提供访问控制。此处主要讲IPC信号量。 若受保护的资源当前可用,则信号量的值为正整数,若资源现当前不可用,则信号量的值为0。当进程试图访问受信号量保护的资源时会把信号的值减1,但是内核会阻塞这个进程直到在这个信号量上的操作产生一个正值。当进程释放受保护的资源时,会把信号量的值加1。如果此时有进程正在休眠等待此信号量,则唤醒这些进程。一般是通过信号来唤醒这些进程,唤醒顺序遵循先进先出(这些操作对线程也适用)。 为了保证信号量工作正常,信号量值的测试以及增减操作都应当是原子操作。并且为实现进程间通信的目的,信号量一般是在内核中实现的(不排除部分项目使用了用户态的信号量,但是大部分用户态的信号量只能实现线程间通信, 用户态的信号量若需要实现进程间通信,还得搭配内存映射)。 一般而言,信号量的初始值可以是任意正值或者零值,该值表明有多少个共享资源单位可以被共享使用。但通常信号量的使用形式是二元信号量。二元信号量主要用于同步场景:消费者使用sem_wait()阻塞等待,直到生产者调用sem_post()唤醒它。此类场景多用于一个主线程等待多个异步任务(异步线程)调用返回。具体实现方法有多种,可以是最暴力的循环sem_wait,也可以是信号量+原子变量实现:由最后一个完成的异步任务(原子变量初始化为异步任务的数量,每一个异步任务返回时减一次原子变量,原子变量自减为0时为最后返回的那个异步任务)调用sem_post()唤醒主线程。 信号量与互斥锁的差别: 任何时刻只能有一个任务(进程、线程或者协程)持有mutex,即mutex的计数永远只能是1。 mutex的上锁者必须负责mutex的解锁,即只能在同一个上下文中加锁和解锁。而信号量的wait和post操作往往是处于不同的任务,不在同一个上下文之间,毕竟信号量就是为了同步而生的。 参考链接: 《unix环境高级编程第三版》 《深入理解Linux内核第三版》 《Linux内核设计与实现》

es查询修改

1.正则查询 GET ip:端口号/process_node/_search { "from" : 0, "size" : 100, "query": { "bool": { "must": [ { "term":{ "robotId" : { "value" : 1234 } } }, { "term":{ "type" : { "value" : "START" } } }, { "regexp": { "config": { "value": ".*TOPIC.*" } } } ] } } } //通配符查询,相当于like { "from" : 0, "size" : 100, "query": { "bool": { "must": [ { "term":{ "type" : { "

html表单和(横向)导航栏

在<form action="xxx.php" mothod="post/get"></form>下面 其中有属性值get是明文传输 <!-- 1输入框 --> UserName: <input type="text" name="" id=""> <!-- 2.密码框 --> <input type="password" name="" id=""> <!-- 3.单选框 --> <input type="radio" name="" id=""> <!-- 4.多选框 --> <input type="checkbox" name="" id=""> <!-- 5.文本选择 --> <input type="file" name="" id=""> <!-- 6.提交按钮1 --> <input type="submit" name="" id="">提交按钮1 <input type="reset" name="" id="">重置 <input type="buuton" name="" id="" οnclick="alert('###被点击了')">点击 <!-- button --> <button type="button" οnclick="alert('###被点击了')"></button> <button type="submit" ></button>提交 <button type="reset" ></button>重启 <!-- 8.

嵌入式设备时间同步(gpsd pps chrony 校时)

文章目录 二、时间同步方案三、chrony 介绍和使用3.1 chrony 介绍3.2 chrony 使用示例3.3 chrony.conf3.4 chronyd3.5 chronyc 四、gpsd + chrony + pps 介绍和使用4.1 gpsd 介绍4.1.1 gpsd 交叉编译4.1.2 gpsd 使用4.1.2 gpsd + chrony 4.2 pps 和 pps-tools 介绍和使用 五、比较两个设备时间差5.1 date 命令5.2 ntpdate命令5.2.1 使用示例5.2.2 ntpdate 交叉编译5.2.3 chronyd 命令 六、核心参考 二、时间同步方案 该部分转自:一文了解自动驾驶中的时间同步 时间同步包含哪些内容? 时间同步可分为几部分的内容:统一时钟源,硬件同步,软件同步。 1. 统一时钟源 1.1 PPS + NMEA GPS能够从卫星获得高精度的时钟信号,因此通常作为整个系统的时钟源。常规的GPS单元都支持输出精确到毫秒的秒脉冲信号PPS和包含年月日时分秒信息的NMEA指令,通过PPS和NMEA的组合就能够实现对激光雷达或主机的毫秒级时钟同步。 PPS+NMEA的优点是协议简单,容易实现;缺点是必须基于RS232。多个设备之间实现同步比较困难。 1.2 PTP(IEEE 1588或IEEE 802.1AS) PTP(Precision Time Protocol,1588 V2)是基于以太网的高精度时钟同步协议,能够实现以太网中多个从节点(各种传感器)与主节点(主机)之间的亚微秒级时钟同步,前提是所有节点之间都通过以太网互联,交换机支持PTP协议,并且每个节点都支持PTP协议。 与PTP同时出现的还有一种NTP,即网络时间协议,不同的是PTP是在硬件级实现的,NTP是在应用层级别实现的 。 2. 硬件同步 3. 软件同步 三、chrony 介绍和使用 3.1 chrony 介绍 chrony 官网v2.

Android8.1 MTK 去掉锁屏功能

1、源码: *****\vendor\mediatek\proprietary\packages\apps\SettingsProvider\res\values\defaults.xml <string name="def_wireless_charging_started_sound" translatable="false">/system/media/audio/ui/WirelessChargingStarted.ogg</string> //将false改为true即可,false锁屏,true不锁屏 <bool name="def_lockscreen_disabled">true</bool> <bool name="def_device_provisioned">false</bool> <integer name="def_dock_audio_media_enabled">1</integer> 2、源码: *****\vendor\mediatek\proprietary\packages\apps\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java loadBooleanSetting(stmt, Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD, R.bool.def_accessibility_speak_password); //将false改为true if (SystemProperties.getBoolean("ro.lockscreen.disable.default", true) == true) { loadSetting(stmt, Settings.System.LOCKSCREEN_DISABLED, "1"); } else { loadBooleanSetting(stmt, Settings.System.LOCKSCREEN_DISABLED, R.bool.def_lockscreen_disabled); } loadBooleanSetting(stmt, Settings.Secure.SCREENSAVER_ENABLED, com.android.internal.R.bool.config_dreamsEnabledByDefault); 注意:改之前,需要根据自己的项目配置,看清楚用的是哪个目录下的SettingsProvider

nuxt3官网搭建,适配pc和移动端支持一键切换中英文,使用pinia和持久化插件

、1使用命令行创建项目脚手架 npx nuxi@latest init may-app // my-app你的项目名称 一般情况下都会创建失败,这里有一个项目的模版,可以自行下载使用 Nuxt基础配置模板地址:https://github.com/Seven7v/Nuxt3-vue3-project 2、如何适配pc端和移动端? 文件middleware/auth.global.ts // 加上global后缀,默认全局中间件,进入所有路由都会通过这里在中间件文件中判断是什么设备,跳转至对应的路由 export default defineNuxtRouteMiddleware((to, from) => { if (process.server){ // 在服务器端处理路由 const nuxtApp = useNuxtApp() } else { // 在客户端处理路由 // 是否是移动端设备 const isMobile = /(Android|webOS|iPhone|iPod|tablet|BlackBerry|Mobile)/i.test(navigator.userAgent) // 是否是手机端路由 const isRouterMobile = /^\/m\//.test(to.fullPath); // 移动端并且 不是/m开头路由 if(isMobile && !isRouterMobile){ return navigateTo(`/m${to.fullPath}`) } // 不是移动端 是/m开头路由 if( !isMobile && isRouterMobile){ return navigateTo(`${to.fullPath.replace('/m','')}`) } } }) 适配移动端,使用插件 postcss-px-to-viewport 在nuxt.config.ts文件中设置css如下 css: { postcss: { plugins: [ postcsspxtoviewport({ unitToConvert: 'px', // 要转化的单位 viewportWidth: 750, // UI设计稿的宽度 unitPrecision: 6, // 转换后的精度,即小数点位数 propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换 viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw selectorBlackList: ['el-'], // 指定不转换为视窗单位的类名,例如van-(vantUI组件), minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换 mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false replace: true, // 是否转换后直接更换属性值 exclude: [/node_modules/], // 设置忽略文件,用正则做目录名匹配,最好不要排除node_modules 文件,排除后在项目中会发现字体不能跟随页面放大 landscape: false // 是否处理横屏情况 }) ] } } 3、如何实现一键切换中英文? 安装@intlify/unplugin-vue-i18n 和 vue-i18n两个依赖,如果安装不上,请使用强制命令 --force npm i @intlify/unplugin-vue-i18n vue-i18n 配置 nuxt.

MOS管的那些事——很火的MOS管电路工作原理及详解,建议收藏!

电流符号篇 开始之前,一个小测试: 请回答: 哪个脚是S(源极)? 哪个脚是D(漏极)? G(栅极)呢? 是P沟道还是N沟道MOS? 如果接入电路,D极和S极,哪一个该接输入,哪个接输出? 你答对了吗? 再来一个,试试看: 哪个脚是S(源极)? 哪个脚是D(漏极)? G(栅极)呢? 是P沟道还是N沟道MOS?依据是什么? 如果接入电路,D极和S极,哪一个该接输入,哪个接输出? 这次怎么样? 1 三个极怎么判定 MOS管符号上的三个脚的辨认要抓住关键地方 。 G极,不用说比较好认。 S极,不论是P沟道还是N沟道,两根线相交的就是。 D极,不论是P沟道还是N沟道,是单独引线的那边。 2 他们是N沟道还是P沟道? 三个脚的极性判断完后,接下就该判断是P沟道还是N沟道了: 当然也可以先判断沟道类型,再判断三个脚极性。 小测试: 先判断是什么沟道,再判断三个脚极性。 3 寄生二极管的方向如何判定? 接下来,是寄生二极管的方向判断: 它的判断规则就是: N沟道,由S极指向D极。 P沟道,由D极指向S极。 上面方法不太好记,一个简单的识别方法是: 不论N沟道还是P沟道MOS管,中间衬底箭头方向和寄生二极管的箭头方向总是一致的: 要么都由S指向D, 要么都由D指向S。 (想像DS边的三节断续线是连通的) 4 它能干吗用呢? MOS管有两大作用:开关作用、隔离作用 4.1 开关作用 以上MOS开关实现的是信号切换(高低电平切换),再来看个MOS开关实现电压通断的例子吧。 看过前面的例子,你能总结出“MOS管用做开关时在电路中的连接方法”吗? 其实关键就是: 确定哪一个极连接输入端;哪个极连接输出端。 控制极电平为“ ?V ” 时MOS管导通(饱和导通)? 控制极电平为“ ?V ” 时MOS管截止? 回顾前面的例子,你找到它们的规律了吗? 小提示:MOS管中的寄生二极管方向是关键。 小结:“MOS管用作开关时在电路中的连接方法” 反证: 小结:“MOS管的开关条件” 前面解决了MOS管的接法问题,接下来谈谈MOS管的开关条件: 控制极电平为“ ?V ” 时MOS管导通(饱和导通)? 控制极电平为“ ?V ” 时MOS管截止?

流媒体学习之路(机器学习应用)——了解我们的网络模型与CC算法

流媒体学习之路(机器学习应用)——了解我们的网络模型与CC算法 —— 我正在的github给大家开发一个用于做实验的项目 —— github.com/qw225967/Bifrost 目标:可以让大家熟悉各类Qos能力、带宽估计能力,提供每个环节关键参数调节接口并实现一个json全配置,提供全面的可视化算法观察能力。 欢迎大家使用 —— 文章目录 流媒体学习之路(机器学习应用)——了解我们的网络模型与CC算法一、导读二、基于学习的模型与算法2.1 丢包检测算法2.1.1 无线网络丢包模型2.1.2 多信道重排序丢包模型2.1.3 光脉冲网络切换模型 2.2 延迟检测算法2.2.1 延迟原因 2.3 队列长度控制算法2.3.1 论文提到的场景2.3.2 排队算法 三、基于无监督学习的算法3.1 丢包算法3.2 延迟算法3.3 基于窗口更新的算法 3.4 基于队列长度的算法四、实验 一、导读 最近在做机器学习与网络相关的内容,偶然间看到了一篇清华大学2020年发布的机器学习与网络相关综述论文,抽时间阅读了一下,感觉有所收获与大家分享——When Machine Learning Meets Congestion Control: A Survey and Comparison。在展开说的之前老规矩先给大家粘上他们的摘要翻译: 机器学习(ML)已经在许多不同的应用程序中得到了显著的普及。它提供的高度灵活性、适应性和计算能力扩展了在包括网络运营和管理在内的多个领域中使用的传统方法。许多调查都探讨了ML在网络环境中的应用,如流量工程、性能优化和网络安全。许多ML方法侧重于聚类、分类、回归和强化学习(RL)。本研究的创新和贡献在于对基于学习的拥塞控制(CC)方法的详细总结和比较。与通常基于规则的传统CC算法相比,从历史经验中学习的能力是非常可取的。从文献中可以观察到,RL是基于学习的CC算法中的一个关键趋势。在本文中,我们探索了基于RL的CC算法的性能,并提出了当前基于RL的CC算法存在的问题。我们概述了与基于学习的CC算法相关的挑战和趋势。 二、基于学习的模型与算法 2.1 丢包检测算法 随机、聚簇丢包模型相关的算法: 算法场景输入输出决策树 [1]Wireless networks单向延迟 + 包间延迟链路丢包 \ 拥塞丢包贝叶斯 [2]Networks with Reordered events丢失数据的RTT重排序丢包 \ 拥塞丢包Hidden Markov模型 [3]Optica Burst Switching两次突发发送之间成功接收包数竞争丢包 \ 拥塞丢包DT\Bagging\Boosting 神经网络 [4]Wireless networks队列延迟 + 到达时间差 + 包队列无线网络丢包 \ 拥塞丢包决策树\决策树集合\套袋\随机森林\额外树\多层\感知器\K-最近邻 [5]Wireless networks单向延迟的最大值、最小值、标准差 + 包间间隔的最大值、最小值、标准差无线丢包 \ 拥塞丢包 2.

C++常用格式化输出转换

在C语言中可以用printf以一定的格式打印字符,C++当然也可以。 输入输出及命名空间还不太了解的小伙伴可以看一看C++入门讲解第一篇。 在C++中,可以用流操作符(stream manipulators)控制数据的输出格式,这些流操作符定义在2个头文件(iomanip和ios)中,可以用输出运算符<<将一个操作符作用于输出流对象,即可输出该对象。 例如: #include <iostream> #include <stdbool.h> using namespace std; bool b = true; //两种输出如下 **cout << b << endl;** **cout << boolalpha << b << endl;** 运行后输出结果如下 1 true cout默认将bool类型的变量的值转化为0和1,如果在前边加上流操作符boolalpha,就以字符串“true”和“false”的形式输出bool类型变量的结果。 在这里,ios头文件已经自动被iostream头文件包含,这个头文件中的操作符不带任何参数,就比如用以下操作符将整形以特定的进制格式输出。 oct:后续的生疏都以八进制的形式输出。 dec:后续的整数都以十进制的形式输出。 hex:后续的整数都以十六进制的形式输出。 举例: cout << oct << 18 << '\t' << 25 << endl; cout << dec << 18 << '\t' << 25 << endl; cout << hex << 18 << '\t' << 25 << endl; 运行后输出结果如下

log4js日志管理(分级、格式化、切割等)使用详解

文章目录 log4js使用详解技术选型log4js基本使用方法1. 安装2. 基本功能日志级别:日志类型:1. 日志分类过滤2. 定义日志Logger的不同类型来源 日志落盘:日志过滤:日志格式(Layout): log4js使用详解 技术选型 在node服务端的日志收集工具中,比较火热的有winston、log4js、bunyan、npmlog等,对于日志收集的基本要求例如分布式集中收集、多渠道输出、日志格式化等上述npm库均可满足。现在分析下上述工具库的特点: winston:非常全面的日志管理库,但比较重一些log4js:定制灵活、比较全面的日志管理库,允许api配置也允许json方式配置,相对轻便、灵活bunyan:日志记录方式为JSON,相对来说形式比较单一npmlog:基础的日志记录器,不具备更多的高级功能、定制化功能。 对于本项目来说,并不需要复杂的winston来支持,log4js在兼顾功能的情况下也可以兼顾性能,因此使用log4js 但是对于express框架的后端,我们可以考虑使用express默认中间组件morgan log4js基本使用方法 1. 安装 使用npm下载即可 npm install log4js 2. 基本功能 在log4js中使用日志记录器,主要的功能如下: 日志级别: 日志分级可以将不同级别的日志在控制台中采用不同的颜色,也可以帮助在生产时有选择地生成不同级别的日志。 这一点理解上可以对应console api的调用,我们可以console.log、console.info、console.err,这是类似的。log4js默认的日志分级有9级,并且不像winston可以自定义配置日志级别,这是不可修改的: Level.addLevels({ ALL: { value: Number.MIN_VALUE, colour: 'grey' }, TRACE: { value: 5000, colour: 'blue' }, DEBUG: { value: 10000, colour: 'cyan' }, INFO: { value: 20000, colour: 'green' }, WARN: { value: 30000, colour: 'yellow' }, ERROR: { value: 40000, colour: 'red' }, FATAL: { value: 50000, colour: 'magenta' }, MARK: { value: 9007199254740992, colour: 'grey' }, // 2^53 OFF: { value: Number.

Debian11下源码编译Qt报错cannot find -lqmapboxgl

尝试在debian11中源码编译qt,在make install时候出现报错 cannot find -lqmapboxgl 后来废了很多功夫也没搞好,在Google搜到了一篇文章 由于协议的变化,debian11中底图库 MapBox 与 Cloudmade 不再内建支持,所以导致源码编译qt出现问题,qmapbox是qtlocation模块的插件,如果后续程序中用不到qtlocation的库,可以在编译时选择跳过,我搜索了一下我后续要编译的源码,没有调用qtlocation的内容,所以在configure阶段,增加跳过编译qtlocation的选项 ./configure -skip qtlocation

字符串数组排序(Java/JavaScript代码版)

Java public static void main(String[] args) throws Exception { String[] arr = new String[] { "abc", "xyz", "efg" }; // 默认按自然升序排 Arrays.sort(arr); System.out.println(Arrays.toString(arr)); } 降序排 降序排,可传入第二个参数,用于判断2个字符相对大小的比较器。 Arrays.sort(arr, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o2.compareTo(o1); } }); 降序排,第二个参数传入lambda表达式,JDK1.8及以后支持。 Arrays.sort(arr, (a,b)->{ return b.compareTo(a); }); 降序排,JDK1.8中已经定义了降序比较器。 Arrays.sort(arr, Comparator.reverseOrder()); JavaScript var x = ["abc","xyz","efg"]; x.sort();//['abc', 'efg', 'xyz'] x.sort().reverse();//['xyz', 'efg', 'abc'] x.sort(function(a,b){return b.localeCompare(a);});//['xyz', 'efg', 'abc']

Pinia 插件 pinia-plugin-persist 添加 persist 属性时报错:没有与此调用匹配的重载

项目场景: Vue3TS 语言Pinia插件:pinia-plugin-persist 问题描述 代码如下: import { defineStore } from 'pinia' export const useInfoStore = defineStore('info', { state: () => { return { activeIndex: 0 } }, actions: { updateIndex(active: number) { this.activeIndex = active } }, // 注意这里报错 // 没有与此调用匹配的重载 persist: { storage: localStorage } }) 解决方案: 卸载聪(S) 明(B) 的 pinia-plugin-persist 插件 pnpm uninstall pinia-plugin-persist 安装替换 pnpm install pinia-plugin-persistedstate 在 main.ts 中配置 ,大概代码如下 import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' const app = createApp(App) const pinia = createPinia() pinia.

Wireshark抓包工具配置以及MQTT抓包分析

1、Wireshark抓包工具使用 打开Wireshark选择,需要抓取的物理网卡,添加过滤设置。 单击“捕获”,选择选项,输入需要捕获的IP地址和端口号。 如: ip host 10.60.4.45 and tcp port 1883 ip host 10.60.4.45 and http port 80 单击开始,捕获即可。 2、Wireshark抓包工具常用过滤配置 抓包过滤器语法和实例 抓包过滤器类型Type(host、net、port)、方向Dir(src、dst)、协议Proto(ether、ip、tcp、udp、http、icmp、ftp等)、逻辑运算符(&& 与、|| 或、!非) (1)协议过滤 比较简单,直接在抓包过滤框中直接输入协议名即可。 tcp,只显示TCP协议的数据包列表 http,只查看HTTP协议的数据包列表 icmp,只显示ICMP协议的数据包列表 (2)IP过滤 host 192.168.1.104 src host 192.168.1.104 dst host 192.168.1.104 (3)端口过滤 port 80 src port 80 dst port 80 (4)逻辑运算符&& 与、|| 或、!非 src host 192.168.1.104 && dst port 80 抓取主机地址为192.168.1.80、目的端口为80的数据包 host 192.168.1.104 || host 192.168.1.102 抓取主机为192.168.1.104或者192.168.1.102的数据包 !broadcast 不抓取广播数据包 2、显示过滤器语法和实例 (1)比较操作符 比较操作符有== 等于、!= 不等于、> 大于、< 小于、>= 大于等于、<=小于等于。

如何使用java语言下载https的网络文件

import java.io.BufferedInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import javax.net.ssl.HttpsURLConnection; public class HttpsDownloader { public static void main(String[] args) { String fileURL = "https://example.com/file.txt"; // 要下载的文件URL String savePath = "downloaded_file.txt"; // 下载后保存的文件路径 try { URL url = new URL(fileURL); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect(); int responseCode = connection.getResponseCode(); if (responseCode == HttpsURLConnection.HTTP_OK) { InputStream inputStream = new BufferedInputStream(connection.getInputStream()); FileOutputStream outputStream = new FileOutputStream(savePath); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.

python_pycharm安装与jihuo

目录 环境: 安装包与jihuo文件: 安装python3.8.10 安装pycharm jihuo pycharm 概述 过程 jihuo 相关文件 环境: window11 python3.8.10 pycharm-professional-2019.1.3 安装包与jihuo文件: 安装python3.8.10 安装pycharm 注意:安装目录不要有中文 jihuo pycharm 概述 1 复制 jetbrains-agent.jar 到pycharm安装目录的bin目录下 2 首次打开pycharm,选择免费试用,创建一个项目 3 修改vm文件,在最后面加入一行 jetbrains-agent.jar 路径 4 关闭pycharm,重启pycharm 5 输入jihuo码 jihuo 过程 进入pycharm 安装目录下的bin文件下,将 jetbrains-agent.jar 文件 copy 到这个目录下 打开pycharm Help -> Edit Custom VM Options 将jetbrains-agent.jar路径写入 关闭pycharm,重启pycharm Help -> Register 查看到期时间 Help -> About jihuo 相关文件 链接:https://pan.baidu.com/s/1uU4_uCrI0-QL2xk_EwjoDw 提取码:lgkq

STM32CubeIDE的MCU开发

以前做stm32嵌入式开发均使用的是破解版的keil软件,现在工作需要无法按照此步骤进行,最近针对ST官方免费软件STM32CubeIDE进行了相关调研工作。 1 STM32CubeIDE简介 目前主流的STM32开发环境是ARM公司的KEIL软件, 由于KEIL对于STM32大部分型号是收费的, 使用需要破解, 存在版权问题。 并且使用KEIL编译大型工程, 编译太慢了, 编译耗时长。 STM32CubeIDE是ST公司推出的免费多功能STM32开发工具,采用了行业标准的开放式许可条款,为简化和加快基于STM32的嵌入式设计,新增了STM32专用功能,包括功能强大的STM32CubeMX微控制器配置和项目管理工具。用户能够最大限度地提高产品的功能和性能,缩短研发周期,降低开发成本。 STM32CubeIDE是一个多操作系统集成开发工具,它是STM32Cube软件生态系统的一部分。STM32CubeIDE具有STM32 MCU和MPU的外设配置、代码生成、代码编译和调试功能,它基于Eclipse®/CDT框架和GCC工具链进行开发,GDB进行调试。STM32CubeIDE集成了STM32的配置和项目创建功能,提供了一体化的工具体验,节省安装和开发时间。在开发过程中任何时间,用户都能返回到外设/中间件的初始化和配置,并且在不影响用户代码的情况下生成初始化代码。 2 STM32CubeIDE下载与安装 2.1 STM32CubeIDE下载 进入意法半导体的官网 STM32CubeIDE - STM32的集成开发环境 - STMicroelectronics,选择最新版本,按照提示下载STM32CubeIDE软件安装包,如下图所示。 图1 官网获取最新安装包 例如,作者的电脑是windows操作系统,选择了当前最新版本1.6.1 STM32CubeIDE-Win的安装包进行下载。 2.2 STM32CubeIDE安装 软件下载成功后,解压缩软件安装包,右键.exe文件 —> 以管理员身份运行,注意:安装目录中不允许有中文路径。 图2 管理员身份运行 弹出的界面,点击Next。 图3 安装界面 弹出的界面,点击I Agree。 图4 同意安装 选择安装路径,点击Next。 图5 选择安装路径 勾选“SEGGER J-Link drivers”和“ST-LINK drivers”,点击“Install”,等待安装完成。 图6 勾选调试工具 安装完成,点击Next。 图7 安装完成 弹出的界面,点击Finish。 图8 Finish 2.3 STM32CubeIDE器件包安装 双击软件STM32CubeIDE 1.6.1.exe ,点击help —> Manage Embedded Software Packages 。 图9 安装器件包

关于el-table+el-input+el-propover的封装

一、先放图片便于理解 需求: 1、el-input触发focus事件,弹出el-table(当然也可以为其添加搜索功能、分页) 2、el-table中的复选功能转化成单选共能 3、选择或取消的数据在el-input中动态显示 4、勾选数据后,因为分页过多,原先选好的数据容易被埋没,在el-input里手动删除或添加触发input事件,el-table根据原有数据能检索到对应数据 5、若不通过勾选选择信息,手动添加,触发input事件,可一边输入一边检索是否存在所输入的数据 6、选择全部勾选无效 二、封装成组件之后的调用 view部分: <selectUserInfo ref="selectUser" :inputUserData="form.quauser" @fatherSelect="selectMethod"></selectUserInfo> model部分: selectMethod(selection) { //selection参数接收从子组件中传过来的被勾选的用户信息 let common; //通过字符串或数组类型来判断是在table页面勾选后回显input数据还是手动输入input数据 if (selection instanceof Array) { // 无论勾选多少个,只取最新勾选的用户数据 let index = selection.length - 1 + "" common = selection[index]; } else { //规范输入操作,因为组件输入input框触发@input事件后根据“-”分割姓名和编号,进行实时检索,返回数据为空,这时操作者能及时修改输入内容,或者在输入过程中查找到对应数据直接勾选即可 let reg = /.-[1-9][0-9]{7}$/ if (!reg.test(selection)) { //不符合格式规范,会导致el-input表单校验confirm校验不通过 this.form.userInfo= ""; return } } }, 三、实现过程 1】el-popover代码 <el-popover placement="right" width="400" trigger="click"> <el-table :data="gridData" v-loading="loading" ref="userlist" @select="handleSelectionChange" :row-key="row => row.

Windows使用adb命令安装apk文件报错adb: failed to run abb_exec. Error: closedadb: retrieving the default device

在运行ADB(Android Debug Bridge)时遇到了一些问题。这是一个用于与安卓设备进行通信并执行各种操作的命令行工具。 首先,"com.lion.gallery.overlay.ovf" 这个程序无法运行可能是由于该应用程序存在错误或者与其他应用冲突导致的。你可以尝试卸载或更新此应用,然后重新安装以查看是否可以解决问题。 其次,"adb: failed to run abb_exec." 和 "adb: connect error for write:" 的报错可能表示你的ADB服务器没有正确地连接到设备或者是设备的驱动程序未被正确安装和配置。请确保你已经启动了USB调试模式并且已经按照正确的步骤连接设备和电脑。如果使用的是无线ADB,则需要检查网络设置以确保连接正常。 最后,"Performing Streamed Install" 表示正在进行流式安装,"com. lion. Handbook.Overlay" 表示Lion Handbook overlay 已经启动,这些信息可能与你的操作无关,但它们显示在你的系统崩溃截图中可能是因为系统的某些部分出现了故障。为了解决这个问题,你可能需要重启你的设备并再次尝试运行ADB操作。如果你仍然遇到困难,我建议你查阅更详细的文档、教程或在相关社区寻求帮助。

STM32F103C8T6+ESP8266+MQTT使用最新版的oneNet可视化View实现远程控制(详细)

本篇所实现的功能是我毕业设计的一部分,用于记录我的学习过程,以免忘记操作过程! 所使用的相关硬件:正点原子的esp8266模块、c8t6开发板一块、STLink v2、DHT11温湿度传感器一块、发光二级管一个、继电器两个 附上我的完整工程代码:代码 感谢博主:永栀哇 相关文章:1-ESP8266-AT指令初试化及部分基础知识2-STM32+ESP8266连接onenet并上传数据(HTTP)3-STM32+ESP8266连接onenet上传数据+远程控制(MQTT) 硬件接线: 最终呈现软硬件: 一、代码方面:(主要说明onenet.c和esp8266.c) onenet.c中: 第一步要修改处 那么具体的三个参数在哪里找到捏?如下图,具体如何打开,在下文有表述: 第二步用于与oneNET端创建连接,此处无需修改 //========================================================== // 函数名称: OneNet_DevLink // // 函数功能: 与onenet创建连接 // // 入口参数: 无 // // 返回参数: 1-成功 0-失败 // // 说明: 与onenet平台建立连接 //========================================================== _Bool OneNet_DevLink(void) { MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0}; //协议包 unsigned char *dataPtr; _Bool status = 1; printf("OneNet_DevLink\r\nPROID: %s, AUIF: %s, DEVID:%s\r\n", PROID, AUTH_INFO, DEVID); if(MQTT_PacketConnect(PROID, AUTH_INFO, DEVID, 256, 0, MQTT_QOS_LEVEL0, NULL, NULL, 0, &mqttPacket) == 0) { ESP8266_SendData(mqttPacket.

2023年原力计划第五季到期提醒

2023年原力计划第五季自3月份开启以来,已进行了近8个月,感谢各位小伙伴们一直以来对原力计划的支持,今年的原力计划将于11月16日(周四)到期,届时将对原力计划各个展示入口进行下线,还请博主知晓。明年我们将会带着全新的原力计划回归,敬请期待!大家对「原力计划」活动有建议也可以在本博文下进行反馈,我们会搜集大家的建议,争取下一季优化活动内容。 备注:我们的流量券活动也在进行中,欢迎各位博主们创作博文体验流量券~

Excel·VBA合并工作簿

目录 1,合并文件夹下所有工作簿1.1,合并且建立超链接目录举例 2,合并工作簿中所有工作表2.1,纵向合并举例 2.2,横向合并举例 3,合并文件夹下所有工作簿中所有工作表举例3.1,合并且显示原工作簿名称、原工作表名称 4,合并文件夹下所有工作簿中同名工作表4.1,合并且显示原工作簿名称举例 5,合并文件夹下所有工作簿中所有工作表,横向汇总数据举例 6,合并子文件夹所有工作簿中所有工作表,纵向汇总数据举例 7,合并子文件夹同名工作簿中同名工作表,纵向汇总数据7.1,实现方法17.2,实现方法2举例,2种实现方法对比 1,合并文件夹下所有工作簿 适用将所有工作簿中所有工作表复制到1个新建工作簿中,不修改数据,原本一共有多少个工作表,合并后就有多少个工作表 如果存在同名工作表,复制后工作表名称会自动添加序号,如Sheet1 (2) Sub 合并文件夹下所有工作簿() '文件夹下所有工作簿wb所有工作表ws合并为一个新工作簿(但不含子文件夹),不修改数据 Dim write_wb As Workbook, wb As Workbook, sht As Worksheet, file_path$, file_name$ file_path = "E:\测试\拆分表\" '待合并工作簿所在的文件夹 file_name = Dir(file_path & "*.xlsx") Application.ScreenUpdating = False '关闭屏幕更新,加快程序运行 Application.DisplayAlerts = False '不显示警告信息 Set write_wb = Workbooks.Add '新建工作簿,合并文件 Do While file_name <> "" Set wb = Workbooks.Open(file_path & file_name) For Each sht In wb.Worksheets sht.Copy After:=write_wb.Sheets(write_wb.Sheets.Count) Next wb.

虚谷数据库定时任务的dbms_scheduler使用方法

虚谷数据库提供定时作业机制,用于定时、定期、自动的进行某些操作,可通过系统包 dbms_scheduler 进行定时作业创建、调度、查看、删除等。 DBMS_SCHEDULER 系统包封装了以下过程/函数:ENABLE、DISABLE、SET_JOB_ARGUMENT_VALUE、DROP_JOB、RUN_JOB。 DBMS_SCHEDULER.CREATE_JOB:创建作业DBMS_SCHEDULER.ENABLE:表示启用作业。DBMS_SCHEDULER.DISABLE:表示禁用作业。DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE:表示对 job 调用存储过程进行参数赋值DBMS_SCHEDULER.RUN_JOB:表示显式调用定时作业。DBMS_SCHEDULER.DROP_JOB:表示删除定时作业。 1、DBMS_SCHEDULER.CREATE_JOB使用方法 DBMS_SCHEDULER.CREATE_JOB ( job_name IN VARCHAR2, job_type IN VARCHAR2, job_action IN VARCHAR2, number_of_arguments IN PLS_INTEGER DEFAULT 0, start_date IN TIMESTAMP DEFAULT NULL, repeat_interval IN VARCHAR2 DEFAULT NULL, end_date IN TIMESTAMP DEFAULT NULL, job_class IN VARCHAR2 DEFAULT 'DEFAULT_JOB_CLASS', enabled IN BOOLEAN DEFAULT FALSE, auto_drop IN BOOLEAN DEFAULT TRUE, comments IN VARCHAR2 DEFAULT NULL); 参数解释: job_name:作业名称。job_type:作业类型,可指定为 stored_procedure、plsql_block或plsql_command;若为 stored_procedure 则 job_action 内容为数据库存储过程名称;若为 plsql_block 则 job_action 为可执行块语句;若为plsql_command则job_action可调用包中的存储过程或存储函数。job_action:作业动作,与 job_type 相关。number_of_arguments:作业中存储过程、存储函数或包的参数个数。start_date:作业开始时间。repeat_interval:作业重复间隔说明。end_date:作业结束时间。job_class:作业类型——该参数暂时无效,预留。enabled:作业是否已激活,若该参数置为true则表示该作业默认为启用状态,作业根据其计划自动运行,若该参数置为false则该作业为禁用状态,不会自动执行,需手动执行作业或将该作业启用后方可自动执行。auto_drop:作业执行完是否自动删除。若该参数置为true则在作业完成后将自动删除作业,反之不会删除该作业。comments:作业备注说明。 参数说明:

《红蓝攻防对抗实战》十三.内网穿透之利用HTTP协议进行隧道穿透

内网穿透之利用HTTP协议进行隧道穿透 一.前言二.前文推荐三.利用HTTP协议进行隧道穿透1. Reduh进行端口转发2. ReGeorg进行隧道穿透3. Neo-reGeorg加密隧道穿透4. Tunna进行隧道穿透5 .Abptts加密隧道穿透6. Pivotnacci加密隧道穿透 四.本篇总结 一.前言 本文介绍了利用HTTP协议进行隧道穿透的方法。WEB tunnel即WEB隧道,可以进行局域网穿透控制,通过web tunnel可以桥接到局域网内的所有网络设备,让远程访问此设备就像在局域网内访问此设备一样。Web隧道允许用户通过HTTP连接发送非HTTP流量,这样就可以在HTTP上携带其他协议数据。Web tunnel适用于当目标开启防火墙时,此时入站和出站连接都受到限制,除了WEB服务的端口(80或443)。Webshell可以用于连接目标主机上的服务,这是目标主机上的本地端口连接,一般都会允许从服务端口读取数据,并将其封装到HTTP上,作为HTTP响应发送到本地代理,整个外部通讯都是通过HTTP协议完成的。 二.前文推荐 《红蓝攻防对抗实战》一. 隧道穿透技术详解 《红蓝攻防对抗实战》二.内网探测协议出网之TCP/UDP协议探测出网 《红蓝攻防对抗实战》三.内网探测协议出网之HTTP/HTTPS协议探测出网 《红蓝攻防对抗实战》四.内网探测协议出网之ICMP协议探测出网 《红蓝攻防对抗实战》五.内网探测协议出网之DNS协议探测出网 《红蓝攻防对抗实战》六.常规反弹之利用NC在windows系统执行反弹shell 《红蓝攻防对抗实战》七.常规反弹之利用NC在Linux系统执行反弹shell 《红蓝攻防对抗实战》八.利用OpenSSL对反弹shell流量进行加密 《红蓝攻防对抗实战》九.内网穿透之利用GRE协议进行隧道穿透 《红蓝攻防对抗实战》十.内网穿透之利用DNS协议进行隧道穿透 《红蓝攻防对抗实战》十一.内网穿透之利用SSH协议进行隧道穿透 《红蓝攻防对抗实战》十二.内网穿透之利用ICMP协议进行隧道穿透 《红蓝攻防对抗实战》十三.内网穿透之利用HTTP协议进行隧道穿透 ———————————————————————————————————————————— 三.利用HTTP协议进行隧道穿透 WEB tunnel即WEB隧道,可以进行局域网穿透控制,通过web tunnel可以桥接到局域网内的所有网络设备,让远程访问此设备就像在局域网内访问此设备一样。Web隧道允许用户通过HTTP连接发送非HTTP流量,这样就可以在HTTP上携带其他协议数据。Web tunnel适用于当目标开启防火墙时,此时入站和出站连接都受到限制,除了WEB服务的端口(80或443)。Webshell可以用于连接目标主机上的服务,这是目标主机上的本地端口连接,一般都会允许从服务端口读取数据,并将其封装到HTTP上,作为HTTP响应发送到本地代理,整个外部通讯都是通过HTTP协议完成的。 假设在内网渗透中发现主机,经测试发现存在网站,可以通过此站点的HTTP协议去搭建隧道,通过漏洞获取到webshell权限,当拥有webshell权限时就可以利用HTTP协议的webshell tunnel进行搭建,下面用一些案例来演示如何搭建web tunnel,具体实验环境如表1-1所示,实验拓扑如图1-1所示。 图1-1 HTTP协议实验拓扑图 表1-1 HTTP协议实验环境表 主机类型IP配置攻击机192.168.0.58Web服务器192.168.0.25,192.168.52.11靶机192.168.52.12 1. Reduh进行端口转发 Reduh是一款基于WEB服务的端口转发工具,它支持asp、jsp、php脚本环境,由客户端进行连接,客户端需要配置JDK环境,使用前需要获取到目标服务器webshell权限,才可以上传reDuh服务端对应脚本文件,reDuh文件再将内网服务器的端口通过HTTP/HTTPS服务转发到本地,形成一个连通回路。 1)通过上传reDuh.php文件搭建WEB隧道,将靶机的RDP远程连接服务通过reDuh.php文件转发到攻击机。首先检测到目标主机是PHP环境,通过文件上传漏洞获取到webshell权限,之后上传reDuh.php文件到网站根目录下,此时在攻击机访问网站[http://192.168.0.25/reDuh.php](http://192.168.0.25/reDuh.php)显示如图1-2所示结果,即表示文件部署成功。 图1-2 测试访问 2)接下来,我们使用攻击机进入工具目录reDuhClient/dis文件夹下,执行java -jar reDuhClient.jar http://192.168.0.25/reDuh.php命令,对Web服务器进行连接,这里搭建隧道时,默认会使用1010端口。注意,如果隧道连接未成功,有可能是服务端php环境配置问题,我们对Web服务器的PHP扩展设置,对其php.ini文件中的extension=php_sockets.dll代码去掉注释即可,命令执行成功,如图1-3所示。 图1-3 攻击机连接Web服务器 3)此时攻击机的1010端口会开启监听,我们可以利用nc工具连接本地1010端口,执行nc -nv 127.0.0.1 1010命令,即可对正向代理进行管理,执行后如图1-4所示。 图1-4 NC连接服务端 4)这里使用[createTunnel]的方法将靶机的远程连接服务映射到攻击机8888端口,执行[createTunnel]8888:192.168.52.12:3389命令,即可将靶机的3389端口转发到攻击机的8888 如图1-5所示。 图1-5 设置端口转发 5)这时靶机的3389端口的远程连接服务已经转发到本地的8888端口,可以尝试在攻击机中使用rdesktop命令连接本地8888端口,执行rdesktop 127.0.0.1:8888命令,发现可以远程连接,如图1-6所示。 图1-6 测试连接成功 2.

mysql、redis导入导出数据库数据

MySQL导入导出数据库数据: 导出数据库数据: 1.导出整个数据库 mysqldump -u username -p dbname > dbbackup.sql 其中,username是数据库用户名,dbname是要导出的数据库名,dbbackup.sql是输出的文件名。执行该命令后会要求输入数据库密码。 2.导出特定表的数据 mysqldump -u username -p dbname table1 table2 > dbbackup.sql 其中,table1和table2是要导出的表名。 导入数据库数据: mysql -u username -p dbname < dbbackup.sql 其中,username是数据库用户名,dbname是要导入的数据库名,dbbackup.sql是要导入的文件名。执行该命令后会要求输入数据库密码。 Redis导入导出数据库数据: 导出数据库数据: 1.导出整个数据库 redis-cli save 执行该命令后,Redis会将当前数据库的数据保存到硬盘中的dump.rdb文件中。 2.导出特定key的数据 redis-cli --rdb filename.rdb --key keyname 其中,filename.rdb是要导出的文件名,keyname是要导出的key名。 导入数据库数据: redis-cli --rdb filename.rdb 其中,filename.rdb是要导入的文件名。执行该命令后,Redis会将文件中的数据导入到当前数据库中。

DX runtime分析

最近简单研究了一下DX 的runtime里的DLL,主要使用了dependencies进行分析(以下以DX11为例) 一般来说,首先要经过校验层才能进入Runtime,所以我们首先看d3d11_3SDKLayer.dll 这里可以很清楚的看到d3d11_3SDKLayer.dll会加载真正Runtime d3d11.dll,这里d3d11_3SDKLayer.dll导出了两个接口,D3D11RegisterLayers和D3D11TranslateCreateDevice,其中又调用d3d11.dll的D3D11CoreRegisterLayers和D3D11CoreGetLayeredDeviceSize、D3D11CoreCreateLayeredDevice。(注意这里并不是CreateDevice) 在d3d11.dll中,查看如下 这里可以看到dxgi.dll就是在这里被加载的 d3d11.dll是DXRuntime的核心,这里可以看到导出的接口主要有2类,一类是D3DKMT这种,这种是UMD回调RunTime的接口。另一种就是openAdapter10.openAdapter10_2分别代表DX10,DX11。 这里可以简单再看下DX10的 观查system32下面的DX相关的dll,可以发现DX10都会有一个d3d10core.dll,d3d10_1core.dll,这两个导出接口类似,而DX11是没有的,但是我们对比d3d10core.dll和d3d11.dll的导出接口,可以发现导出接口也基本类似,因此可以把d3d11.dll看作和d3d10core.dll基本一样,但实际跑DX10测试发现,d3d10core和d3d11.dll都会被调用起来,其原因是d3d10.dll都会加载这两个,观察调用的接口,d3d10.dll调用了d310core.dll的D3D10CoreGetVersion和D3D10CoreRegisterLayers,并且调用了d3d11.dll的D3D11CreateDeviceAndSwapChain(现在DX10都是转成11?) 接下来看下Ref和warp的dll d3d10warp.dll 可以看到虽然叫d3d10,但是实际上支持dx9,dx11,dx12,通过调用msvcp相关dll,也可以看出确实是Warp的。 D3D11Ref.dll 这个就是refence了。可以看到referece是区分DX版本的,这个只支持DX10/11,不像warp,DX9/11/12都在一个dll里面,有意思的是这里会导出D3DKMT接口,而Warp是没有导出D3DKMT的。

STM32学习笔记(五) —— 按键翻转LED

STM32学习笔记(五) —— 按键翻转LED 前面我们分析过GPIO的各个寄存器,探讨了如何使用GPIO点亮LED,这里再验证一下GPIO的输入功能。 1.硬件连接 我们这里将按键连接到了PA0引脚,按键外接了上拉电阻,默认状态下PA0引脚处于高电平,当按键按下,PA0引脚就与GND短接,变为低电平,所以我们可以通过读取PA0引脚的电平状态来判断按键是否被按下。 2.软件编程 这里使用STM32CubeMX来配置PA0引脚的初始化: 生成代码后,可以看见程序中已经添加了PA0引脚初始化部分 在while循环中添加如下代码: 注意按键要进行软件消抖(按键按下与断开时都会有干扰产生,可以进行软件延时消抖,一般可以延时10-20ms,具体可以参考代码中的注释)。 while (1) { /* 读取PA0引脚电平 */ if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) { /* 如果是低电平, 表示有按键按下, 进行软件延时消抖 */ HAL_Delay(10); /* 再次读取PA0引脚电平, 如果还是低电平, 就认为有按键按下 */ if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) { /* 等待按键释放 */ while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET); /* 翻转一次按键标志 */ ek_key_flag = !ek_key_flag; printf("key pressed.\r\n"); } } /* 按键每次按下后, ek_key_flag会在0与1之间变换 */ if(ek_key_flag) /* 当ek_key_flag == 1时点亮LED */ HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET); else /* 当ek_key_flag不为1时熄灭LED */ HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } 将程序下载后可以打开串口调试助手,每当按键按下会打印“key pressed.

Pandas学习——物流行业数据分析

——————————————学习资料和数据来源于B站-Python-学习库—————————— 一.待分析问题 货品的配送服务有没有问题——交货情况分析有没有具有销售潜力的区域——货品销售情况分析货品质量问题——货品用户反馈情况分析 二.初识数据-清洗数据 data=pd.read_csv("data_wuliu.csv",encoding='gb2312') print(data.info()) print(data.describe()) 运行结果表明,需要的操作: 1.删除空行 2.数据格式(时间→datetime;销售金额→规整且统一格式、可计算) 3.删除重复值 4.异常值(销售额!=0的行) 清洗数据 #数据清洗 data=data.dropna(axis=0,how='any')#存在空,则删除该行 data=data.drop_duplicates(keep='first')#删除重复值,保留第一个 data=data.drop(columns=['订单行'],axis=1)#删除无用列 data=data[data["销售金额"]!=0]#保留销售金额不为0的数据 data['sale_time']=pd.to_datetime(data['销售时间'])#将销售时间格式转换成datetime格式 data['月份']=data['sale_time'].apply(lambda x:x.month)#对销售时间做映射,提取其中的月份信息,写入“月份”列 #对销售金额进行规整:对于 def amounts_deal(x): if x.find('万元')!=-1:#说明销售金额中存在万元,转换成以元为单位的浮点型 amounts=float(x[:x.find('万元')].replace(',',''))*10000 else: amounts=float(x[:x.find('元')].replace(',','')) return amounts #调用函数-处理销售金额 data['销售金额']=data['销售金额'].map(amounts_deal) #重新更新索引 data=data.reset_index(drop=True) 三.数据分析及可视化 """1.货品的配送服务有没有问题——交货情况分析""" data['货品交货状况']=data['货品交货状况'].str.strip()#货品交货状况改成字符串的格式,并去除前后空格 #a.时间维度看货品交货状态 data1=data.groupby(by=['月份','货品交货状况']).size().unstack() data1['按时交货率'] = data1['按时交货']/(data1['按时交货']+data1['晚交货']) data1['按时交货率'].plot(kind='line') plt.xlabel('月份') plt.ylabel('按时交货率') plt.title('月份-按时交货率分析') #b.货品维度 data2=data.groupby(by=['货品','货品交货状况']).size().unstack() data2['按时交货率'] = data2['按时交货']/(data2['按时交货']+data2['晚交货']) data2['按时交货率'].plot(kind='line') plt.xlabel('货品') plt.ylabel('按时交货率') plt.title('货品-按时交货率分析') #c.销售区域维度 data3=data.groupby(by=['销售区域','货品交货状况']).size().unstack() data3['按时交货率'] = data3['按时交货']/(data3['按时交货']+data3['晚交货']) data3['按时交货率'].plot(kind='line') plt.xlabel('销售区域') plt.ylabel('按时交货率') plt.title('销售区域-按时交货率分析') #d 货品和销售区域维度 data['货品交货状况']=data['货品交货状况'].str.strip() data2=data.groupby(['货品','销售区域','货品交货状况']).size().unstack() data2['按时交货率']=data2['按时交货']/(data2['按时交货']+data2['晚交货']) 结果:不同维度下交货率

爬虫项目实战2.1 Selenium爬取Boss招聘信息

完成: 1.爬取信息 2.基于爬取结果筛选符合条件的信息 岗位名称、薪资、岗位要求、地区、公司名称、公司规模、细节链接 3.筛选base杭州的岗位保存到csv文件中 """ [课 题]: Python爬取boss直聘 [开发环境]: python 3.8 pycharm 专业版 selenium3.141.0 代码编写思路 1. 打开一个浏览器 2. 打开一个网址 3. 获取数据 4. 保存数据 """ from selenium import webdriver # 操作浏览器的类 import csv f = open('boss-杭州.csv', mode='a', encoding='utf-8-sig', newline='') csv_writer = csv.writer(f) csv_writer.writerow(['岗位名称', '薪资待遇', '岗位详情', '岗位地区', '公司福利', '公司名称', '公司规模', '岗位需要技能', '岗位详情链接']) # 1. 打开一个浏览器 driver = webdriver.Edge()#Edge浏览器 # driver = webdriver.Chrome()#谷歌浏览器 for page in range(1, 11): # 2. 打开一个网址 driver.

【内网穿透】搭建我的世界Java版服务器,公网远程联机

目录 前言 1. 搭建我的世界服务器 1.1 服务器安装java环境 1.2 配置服务端 2. 测试局域网联机 3. 公网远程联机 3.1 安装cpolar内网穿透 3.1.1 windows系统 3.1.2 linux系统(支持一键自动安装脚本) 3.2 创建隧道映射内网端口 3.3 测试公网远程联机 4. 配置固定TCP端口地址 4.1 保留一个固定tcp地址 4.2 配置固定tcp地址 前言 本次教程将在windows本地搭建java版的MC服务器,并用cpolar内网穿透突破局域网限制,实现在公网环境下跟小伙伴远程联机,超简单配置,无需公网IP,也不用设置路由器。 如果你的服务器已经搭建成功,并可以正常在局域网内联机,可以直接跳到第三步,在本地配置cpolar内网穿透,创建隧道映射25565端口,实现异地远程联机。 1. 搭建我的世界服务器 以windows10系统为例,配置java环境,搭建服务器。 1.1 服务器安装java环境 下载java17 Java Downloads | Oracle 选择exe文件,下载完成后双击安装包一路默认安装即可。 java安装完成后,打开文件夹,找到java,将jdk安装路径复制下来,本例中为C:\Program Files\Java\jdk-17.0.5 在开始菜单栏搜索高级系统设置并打开系统属性,点击环境变量 点击新建一个系统环境变量 变量名:JAVA_HOME变量值:JDK的安装路径,本例中为C:\Program Files\Java\jdk-17.0.5 在系统变量列表中,双击Path变量 点击右侧的新建,在变量名值前面加%JAVA_HOME%\bin,点击确认 校验是否成功:开始菜单栏搜索cmd,打开命令提示符,输入javac,出现以下内容则说明配置成功。 1.2 配置服务端 下载MC服务端,最新版的服务器端可以官网下载 Download server for Minecraft | Minecraft 下载完成后,在文件所在的文件夹新建一个文本文档 然后打开这个文本文档输入以下信息 java -Xms1G -Xmx2G -jar server.jar nogui pause Xmx1024M:给服务器分配的最大内存Xms1024M:给服务器分配的最小内存server.

2023年最新!Java17于win10环境下的安装配置

2023年最新!Java17于win10环境下的安装配置 链接分享:oracle官网,Java17.exe,java17.zip 导航 文章目录 2023年最新!Java17于win10环境下的安装配置导航一、下载Java17二、安装Java三、配置Java环境变量四、检验 一、下载Java17 这里使用Java17.exe程序为例,首先我们可以根据上面我给出的链接直接去官网下载 二、安装Java 点击exe文件安装 至此,Java17开发环境已安装 三、配置Java环境变量 为什么要配置环境变量呢? (1)配置其它JDK环境变量时,可以方便地引用JDK的安装目录。例如:JDK安装目录为“C:\Program Files\Java\jdk1.8.0_151”,设置JAVA_HOME为该目录路径, 以后要使用这个路径的时候, 只需输入“%JAVA_HOME%”即可, 避免每次引用都输入很长的路径串; (2)从环境变量的易维护性出发,当JDK安装目录发生变化时,只需修改JAVA_HOME变量即可,其它变量无需修改; (3)Java类产品约定俗成的变量名称,第三方软件会引用约定好的JAVA_HOME变量, 获取JDK的安装目录。 配置步骤如下: 右击此电脑,点击属性 选择高级系统设置 选择环境变量 在系统变量窗口选择新建 变量名:JAVA_HOME,变量值:C:\Program Files\Java\jdk-17 注意,这里的变量值选择你实际安装的位置,我提供的是系统默认安装的位置 在系统变量窗口选择 path,点击编辑 选择新建,并输入%JAVA_HOME%\bin 四、检验 按键盘 win+r调出运行,输入cmd并回车,进入了命令行窗口,此时输入 java -version,如果跳出版本信息则说明安装并配置成功,要是失败了,则重新做一遍 配置Java环境变量的部分

Linux Makefile配置问题

编写一个简单的工程文件,制作Makefile需要包含lpthread,当Makefile写为如下配置时 #CROSSCOMPILE := arm-linux- CROSSCOMPILE := CFLAGS := -Wall -O2 -c CFLAGS += -I$(PWD) LDFLAGS := -lpthread LDFLAGS += -lm -ldl CC := $(CROSSCOMPILE)gcc #LD := $(CROSSCOMPILE)ld OBJS := main.o \ cJSON.o \ cmd.o \ mqtt.o \ socket_client.o all: $(OBJS) $(CC) $(LDFLAGS) -o mqtt_client $^ clean: rm -f mqtt_client rm -f $(OBJS) %.o:%.c $(CC) $(CFLAGS) -o $@ $< ~ 出现了错误 main.o:在函数‘main_loop’中: main.c:(.text+0x25):对‘pthread_create’未定义的引用 main.c:(.text+0x3a):对‘pthread_create’未定义的引用 参考博文:https://dontla.blog.csdn.net/article/details/122637407?spm=1001.2101.3001.6650.4&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-4-122637407-blog-105294018.235%5Ev38%5Epc_relevant_yljh&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-4-122637407-blog-105294018.235%5Ev38%5Epc_relevant_yljh&utm_relevant_index=9 参考博文将-lpthread放到编译后面,重新编译-lpthread错误解决。 编译cJSON相关的代码,出现如下错误: cJSON.o:在函数‘parse_value’中: cJSON.c:(.text+0x6e1):对‘pow’未定义的引用 添加编译选项:

vue-cli5.0.x优雅降级,配置项目兼容旧版浏览器

兼容低版本谷歌浏览器 vue-cli5.0.x脚手架下的,如何降低项目版本以适用于底版本的浏览器。 直接使用默认配置打包部署出来的项目再40,60、70版本的谷歌浏览器跑不起来,蓝屏或者浏览器白屏一般这种情况都需要通过Babel去做转换,我们是Vue Cli项目,实际上Vue项目在创建时就引入的Babel,直接使用即可,而且对于vue-cli5.0以上,配置更加简单舒适 解决方案: 修改package.json文件的browserslist配置,修改为你想要兼容的浏览器列表 "browserslist": [ "> 0.03%", "not dead" ] browerslist 指定了项目的目标浏览器的范围。这个值会被 @babel/preset-env 和 Autoprefixer 用来确定需要转译的 JavaScript 特性和需要添加的 CSS 浏览器前缀。 在项目下运行yarn browserslist,就可以查看到项目通过browserslist配置之后可以正常展示的浏览器以及版本信息。 解析一下这里的参数部分,可以看我这篇文章 vue项目优雅降级,es6降为es5,适应低版本浏览器渲染 这里有个网址可以帮助你快速的了解你的browserslist配置对于哪些浏览器有更好的兼容的测试。 网上搜索了很多方法,下载了babel-polyfill,@babel下的polyfill,再main.js引入再配置等等都不生效,原来cli5.0.x限制了webpack配置的browerslist的原因,>.<。 普通项目一般这样即可: "> 1%", "last 2 versions", "not dead", "Chrome 40.0", "ie >= 6"

Scrapy_pipelines管道文件详细教程保存csv,Mysql,Mongodb以及多个item返回pipelines的处理

文章目录 piplines的使用pipelines介绍pipelines常用方法pipelines注意点 保存为csv,Mysql,Mongodb多个item 返回pipeline的处理 piplines的使用 pipelines介绍 管道文件 pipelines.py 主要用来对抓取的数据进行处理:一般一个类即为一个管道,比如创建存入MySQL、MongoDB 的管道类。管道文件中 process_item() 方法即为处理所抓数据的具体方法。 pipelines常用方法 process_item(self,item,spider): 处理爬虫抓取的具体数据,在 process_item() 函数中 必须要 return item,因为存在多管道时,会把此函数的返回值继续交由下一个管道继续处理; init():爬虫项目启动时只执行一次,一般用于数据库连接; close_spider():爬虫项目结束时只执行一次,一般用于收尾工作,如数据库的关闭。 pipelines注意点 pipeline对应的值越小优先级越高pipeline中的process_item方法的名字不能够修改为其他的名称 保存为csv,Mysql,Mongodb settings.py文件 关于settings具体设置点击查看 Scrapy_settings配置文件设置 # 管道文件设置,保存为哪个,就打开对应的管道,可以同时保存 ITEM_PIPELINES = { # 300是最后一个 "douban.pipelines.DoubanPipeline": 300, # Mysql管道 "douban.pipelines.MysqlDoubanPipeline": 299, # mongodb管道 "douban.pipelines.MongodbDoubanPipeline": 298, } pipelines.py文件 # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html # useful for handling different item types with a single interface import csv import pymongo import pymysql from itemadapter import ItemAdapter # 保存csv class DoubanPipeline: def __init__(self): headers = ('title', 'score') self.

新加坡服务器搭建网站出现PHP错误怎么处理?

当您在新加坡服务器上搭建 PHP 网站时,显示错误信息是非常重要的。PHP 错误的及时检测和解决有助于提高网站的稳定性和安全性。以下是一些步骤,帮助您在新加坡服务器上实现这一目标: 步骤 1:编辑 PHP 配置文件 打开您的新加坡服务器上的 PHP 配置文件,通常位于 /etc/php/php.ini 或类似的位置。找到以下配置行并将其修改为相应的值: display_errors = On error_reporting = E_ALL 将 display_errors 的值设置为 “On”,以便在浏览器中显示错误信息。同时将 error_reporting 的值设置为 “E_ALL”,以确保显示所有类型的错误。 步骤 2:重启服务器 保存对 PHP 配置文件的更改后,重新启动您的服务器以使更改生效。您可以使用以下命令之一: sudo service php-fpm restart 或 sudo systemctl restart php-fpm 根据您的服务器配置和操作系统选择适合的命令。 步骤 3:错误日志文件 通过设置错误日志文件,您可以将 PHP 错误信息记录到日志中,以便随时查看。找到以下配置行并将其修改为合适的值: log_errors = On error_log = /var/log/php-errors.log 将 log_errors 的值设置为 “On”,以启用错误日志记录功能。然后,将 error_log 的值设置为您希望将日志文件保存的路径和文件名。 步骤 4:权限设置 确保指定的错误日志文件路径对于 PHP 进程可写。您可以使用以下命令更改文件权限: sudo chmod 666 /var/log/php-errors.log 这将允许 PHP 进程写入错误日志文件。

谈谈IVD之生化诊断与化学发光

一、体外诊断及其分类 谈谈IVD之生化诊断与化学发光 1何为体外诊断 体外诊断是指在人体之外,通过对人体样本(血液、体液、组织等)进行检测而获取临床诊断信息,进而判断疾病或机体功能的产品和服务。 换句话说,体外诊断(IVD)是指将血液、体液、组织等样本从人体中取出,使用体外检测试剂、仪器等对样本进行检测与校验,以便对疾病进行预防、诊断、治疗检测、后期观察、健康评价、遗传疾病预测等的过程,所以体外诊断的核心就是体外检测试剂以及检测仪器。 体外诊断是医学检验的强大工具,其提供的全方位(生化信息、免疫信息、基因信息)、多层次(定性、半定量、定量)的检验信息成为临床诊断信息的重要来源。 根据罗氏诊断的数据统计,体外诊断能够影响60%的临床治疗方案(有报告说这个数据是80%,精确的模糊),但其费用只占整个临床治疗费用的2%,因此体外诊断具有极大的商业价值以及实际意义。 2体外诊断的分类 体外诊断按检验原理或检验方法的不同,主要包括临床生化诊断、免疫诊断、分子生物学诊断、血液学诊断、微生物诊断、尿液诊断、凝血诊断等,其中生化诊断、免疫诊断、分子生物学诊断为临床体外诊断主要的三大领域。 如果按照技术水平,整个 IVD市场又大致可以分为高、中、低三个技术层次。 低端市场主要对应的是手动或半自动的普通酶联免疫产品, 中端市场又可分为中低端(生化、血液检测、尿液检测等) 中高端(化学发光免疫产品、荧光定量 PCR分子诊断等)两部分, 高端市场主要有流式细胞仪、高通量基因芯片等等。 从发展趋势来说,行业有继续平台不断升级的趋势,每次技术平台的升级往往伴随着细分市场增速/份额的变化(比较明显的例子就是近年来免疫学技术平台的提升所带来的化学发光免疫产品对于普通酶免产品的替代)。 注意一点,体外诊断过程中,诊断仪器、试剂以及耗材配套使用,我国体外诊断行业中,试剂占比73%(2015年数据)。 按照搭配试剂的方式,体外诊断仪器可以分为开放式系统和封闭式系统。开放式系统即诊断仪器可以搭配多家厂商的试剂使用,封闭式系统则同一厂家的仪器和试剂必须配套使用。 从这个角度来看的话,化学发光、基因芯片、基因测序等是封闭式的,其他的一般式开放式。 按检测环境及条件的不同,体外诊断又分为实验室诊断和床旁诊断(Point of care testing,POCT)。POCT是指利用便携式分析仪器或配套试剂在采样现场进行快速检测得到结果的一种方式,以其“便携性、操作简便性、结果及时性”等优势得到了快速发展和应用。 二、体外诊断行业分析 1整体行业的增长 (1)全球增速 全球体外诊断行业处于成熟发展阶段,2020年市场规模有望达到747亿美元,预计3-5年全球体外诊断行业年均复合增长率约为4-5%。 2016年,全球IVD行业市场规模约为617亿美元,据Allied Market Research预测,未来几年内全球IVD行业将以约5%的年均复合增长率增长,并在2020年达到747亿美元。 伴随着体外诊断技术不断升级和前沿科学应用的浪潮,全球人口基数不断增长,慢性病、肿瘤等发病率的不断提高,都成为了全球IVD市场持续发展的推动力。 (2)中国增速 我国体外诊断行业正处在飞速发展阶段,近几年一直保持20%的年均增长速度,2017 年我国IVD市场总规模预计约600亿元。 受市场规模基数低、医疗服务需求增长、检测技术更新换代等因素推动, 我国 IVD 市场仍将保持超越医药行业平均的增速,根KaloramaInformation《全球IVD市场(第10版)》报告预计,中国IVD市场在2016-2021年的复合增速约为15%。 (3)中国IVD发展空间 中国IVD处于行业的成长期,从人均诊断费用来看,是世界平均水平的一半,是日本的15%不到。与发达国家相比,我国体外诊断行业仍处在发展前期,我国人口约占全球的1/5,但体外诊断市场规模仅为全球的3%,规模仍然较小。 根据中国产业信息的统计,我国体外诊断产品人均年消费额为4.6美元,仅为全球平均消费水平的一半,日本的15%不到,更是远远低于发达国家的人均水平。全球IVD市场约占全部药品市场的5%左右,而我国仅为1-1.5%左右。 2细分行业的增长情况 从国际和国内的体外诊断结构来看,生化、免疫和分子占据市场上的绝大多少份额,国际是59%,我国是70%;如果说国际代表一种成熟的市场格局的话,那么是不是我国的体外诊断市场中,生化基本市场占有率稳定或者缩小(市场份额不代表规模),免疫的市场份额会因为其他诊断的快速发展,如分子、POCT而收缩呢? 在上文我们说过,中国未来3-5年体外诊断会保持15%的复合增长率,下文将重点分析我国体外诊断市场的细分结构以及发展速度,也就回答上述的问题。 (1) 问题一:我国生化诊断市场还有发展动力吗?市场竞争如何?国内厂商的机会在哪里? 首先,我们要问生化诊断会被淘汰吗?答案是不会,从实践的结果(欧美的发展结果)已经得出。 从逻辑上讲,市场上的不同诊断方法虽然从技术上有优劣,但是医院检验科或者是体检选择哪一种诊断方法会综合考虑其适配性,具备包括对精度的要求、效率、价格等。 如有一些生化诊断项目用化学发光免疫上去进行检测,结果更加准确可靠,但有些项目更适于应用生化诊断方法来进行检测,在血糖、血脂、胆固醇、酶等常规项目上,生化诊断具有不可替代的重要作用,若使用化学发光方法反而程序复杂,需要进行一系列前期准备,对样本进行清洗、筛除干扰因素。 更为关键的是,免疫检测通常成本较高,时间也较长,一般需要15-20分钟。而生化诊断一般需要10分钟左右,较快的项目2-3分钟即可出结果。 生化诊断目前技术成熟,检测成本低,未来主要以糖和非蛋白类基础指标为主,逐渐淡出其他领域,在基层市场占有率高。终端定价是几类检测中最低的,但由于成本低,因此无论对于医院还是产品供应商来说,都是毛利率最高的品种,可以超过80%。 其次,从市场占有率角度来看,国际市场行业集中度高,我国市场较为分散。国际市场四大巨头罗氏、贝克曼、西门子和强生凭借先发优势在国际市场占据了超过80%的市场份额,而在我国前五大厂商占比42%,相对分散。 并且,我国生化诊断的增速放缓,预计随后3-5年行业保持7%左右的增速,可见竞争非常激烈;从国产替代来看,进口仪器占据国内高端市场主导地位,而国产品牌试剂市场占比超三分之二。 由于生化诊断试剂的生产对技术要求也较低,生化诊断试剂成为了很多企业进入体外诊断领域的切入点,而在技术要求相对较高的生化检测分析仪上,国产产品已具备一定的竞争能力,但是在检测精确性和稳定性上与进口产品仍有较大差距。 目前,国内高端市场如三甲医院基本上被国外巨头所垄断,五大诊断巨头占据国内生化市场42.40%份额,而国产产品凭借明显的价格优势在中低端市场逐步替代进口产品。 从仪器与试剂的开放性来看,生化诊断方面,目前封闭、开放式并存,主要是生化诊断技术非常成熟,对仪器和配套试剂的使用要求相对较低。 开放式仪器经过仪器和试剂的校准后也可以达到较高的检测准确度,基本满足临床检测需求,很多国内三甲医院为降低使用成本,常购买进口的仪器,配套国产的试剂来使用,所以进口厂商迎合国内市场需求,其生化仪器很多也是开放的。 目前开放系统占70%,其他的30%都是国外的高端品牌,不过从趋势来看,目前国外很多品牌在中国设厂以及和中国本土公司合作销售以此来降低成本,仪器和试剂的封闭化是一种长期趋势,这样就会对本土的试剂厂商产生一定的冲击。 从生化诊断的发展趋势上看,主要是存量市场的竞争,市场的集中度提升是趋势。 目前生化诊断试剂基本完成进口替代,国产占有率已达70%,但高端仪器仍由外资主导,国产占有率不足10%仪器。 但因国外生化诊断龙头在中国的本土化进程加快,仪器和试剂封闭大势所趋,对国内的中小企业形成挤压,国内单一的仪器生产或者试剂生产商已经没有多大的竞争力,要想突围,要么仪器、试剂一体化发展,要么并购重组。 (图:生化诊断的市场格局) (图:生化诊断的市场增速) 总体来说,生化诊断未来发展的几个观点: (1)行业将保持低速稳健的增长(5%-6%); (2)仪器、试剂一体化是未来发展的趋势; (3)行业壁垒不高,存量竞争压力加大,未来行业整合加剧。 问题二:我国免疫诊断市场状况如何?国产如何替代? 免疫诊断(Immunodiagnostics)是利用抗原抗体之间的特异性免疫反应来测定免疫状态、检测各种疾病的诊断方法。所谓特异性就是指一种抗体只能和一种抗原相结合,这种一一对应的关系造就了免疫诊断较高的灵敏度。

【KVM-7】KVM管理工具

前言 大家好,我是秋意零。 👿 简介 🏠 个人主页: 秋意零🔥 账号:全平台同名, 秋意零 账号创作者、 云社区 创建者🧑 个人介绍:在校期间参与众多云计算相关比赛,如:🌟 “省赛”、“国赛”,并斩获多项奖项荣誉证书🎉 目前状况:24 届毕业生,拿到一家私有云(IAAS)公司 offer,目前已在实习💕欢迎大家:欢迎大家一起学习云计算,走向年薪 30 万💕推广:CSDN 主页左侧,是个人扣扣群推广。方便大家技术交流、技术博客互助。 KVM目前有 libvirt API、virsh 命令行工具到 OpenStack 云管理平台等一套管理工具。 一、Libvirt Libvirt 是一个开源的虚拟化 API 和工具集,也是KVM虚拟化进行管理的工具和应用程序接口。它也提供了统一的方式来管理多种虚拟化技术和 hypervisors(虚拟机监控程序)。 Libvirt 可以用来管理和配置 KVM、Xen、VirtualBox、VMware 等多种虚拟化技术,并提供了统一的编程接口,方便开发者编写跨平台的应用程序。 二、Virsh Virsh 是基于 Libvirt 的 Cli 工具,它可以用来管理虚拟机、虚拟化网络等资源。Virsh 命令行也是管理员进行运维必会的工具。 三、Virt-manager Virt-manager 是一个图形化管理工具,可以通过可视化操作来对虚拟机进行生命周期的管理和维护。

【KVM-6】KVM/QEMU软件栈

前言 大家好,我是秋意零。 👿 简介 🏠 个人主页: 秋意零🔥 账号:全平台同名, 秋意零 账号创作者、 云社区 创建者🧑 个人介绍:在校期间参与众多云计算相关比赛,如:🌟 “省赛”、“国赛”,并斩获多项奖项荣誉证书🎉 目前状况:24 届毕业生,拿到一家私有云(IAAS)公司 offer,目前已在实习💕欢迎大家:欢迎大家一起学习云计算,走向年薪 30 万💕推广:CSDN 主页左侧,是个人扣扣群推广。方便大家技术交流、技术博客互助。 一、内核模块 KVM内核模块是Linux内核的一部分,由于KVM的存在让Linux本身就变成了一个Hypervisor,可以原生地支持虚拟化功能。 目前,KVM支持多种处理器平台,它支持最常见的以Intel和AMD为代表的x86和x86 64平台,也支持PowerPC、S/390、ARM等非x86架构的平台。 KVM模块是KVM虚拟化的核心模块,KVM的主要功能是初始化CPU硬件,打开虚拟化模式,然后将虚拟客户机运行在该模式下,并对虚拟客户机的运行提供一定的支持。它在内核中由两部分组成: 一个是与处理器架构无关,用 lsmod 命令可以查看叫作 kvm 模块;处理器架构相关部分,在Inter平台上就是 kvm_intel 这个内核模块。 二、QEMU用户态设备模拟 QEMU介绍 QEMU是一个开源的虚拟机软件,而不是KVM虚拟机软件的一部分。 QEMU虚拟机是一个纯软件的实现,通过二进制翻译来实现虚拟化客户机中的CPU指令模拟,所以性能比较低。但是优点是跨平台,QEMU支持在Linux、Windows、MacOS等多种操作系统上运行。 除了二进制翻译的方式,QEMU也能与基于硬件虚拟化的Xen、KVM结合,为它们提供客户机的设备模拟。通过与KVM的结合,让虚拟化的性能提升非常高。 最早期的KVM开发者们为了简化软件架构和代码重用,根据KVM特性在QEMU的基础上进行了修改(当然这部分修改已经合并回QEMU的主干代码,故现在的QEMU已原生支持KVM虚拟化特性)。 工作过程 虚拟机运行期间,QEMU会通过KVM模块提供的系统调用进入内核,由KVM模块负责将虚拟机置于处理器的特殊模式下运行。遇到虚拟机进行I/O操作时,KVM模块会从上次的系统调用出口处返回QEMU,由QEMU来负责解析和模拟这些设备。 从QEMU角度来看,也可以说QEMU使用了KVM模块的虚拟化功能,为自己的虚拟机提供硬件虚拟化的加速,从而极大地提高了虚拟机的性能。 除此之外,虚拟机的配置和创建,虚拟机运行依赖的虚拟设备,虚拟机运行时的用户操作环境和交互,以及一些针对虚拟机的特殊技术(如: 动态迁移),都是由QEMU自己实现的。 QEMU除了提供完全模拟的设备 (如: e1000网卡、IDE磁盘等)以外,还支持virtio协议的设备模拟。 virtio是一个沟通客户机前端设备与宿主机上设备后端模拟的比较高性能的协议,在前端客户机中需要安装相应的virtio-blk、virtio.scsi、virtio-net等驱动,而QEMU就实现了virtio的虚拟化后端。 虚拟化后端:是指在宿主机上实现 virtio 协议的一方,也就是 QEMU。它负责实现 virtio 协议,并且与客户机中的 virtio 驱动程序协同工作,从而实现在客户机和宿主机之间的高效通信。virtio 后端也可以由其他虚拟化工具(如 Xen、KVM 等)来实现,但 QEMU 是最常见的 virtio 后端实现之一。 总结 QEMU既是一个功能完整的虚拟机监控器,也在QEMU/KVM的软件栈中承担设备模拟的工作。

数字电路基础知识系列(六)之LC滤波器的基础知识

LC滤波器,是指将电感(L)与电容器 ©进行组合设计构成的滤波电路,可去除或通过特定频率的无源器件。电容器具有隔直流通交流,且交流频率越高越容易通过的特性。而电感则具有隔交流通直流,且交流频率越高越不易通过的特性。因此,电容器和电感是特性完全相反的被动元器件,通过将电容和电感组合,就可去除或通过特定频率的信号。 1 LC滤波器的种类 LC滤波器按所通过信号的频段分为以下三类 1.1 低通滤波器(LPF) 低通滤波器是一种用于传递直流或者低频信号,衰减高频信号的滤波器。 作为被最广泛使用的滤波器电路,主要用于剔除高频噪声。此外,音响中用于剔除低音用扬声器的高音/中音成分。 1.2 高通滤波器(HPF) 高通滤波器是允许高于某一截频的频率通过,而大大衰减较低频率的一种滤波器。这种滤波器被用于剔除听阈的低频噪声,或剔除高音用扬声器的中音/低音成分等。 1.3 带通滤波器(BPF) 带通滤波器是用来只允许特定频率的信号通过,屏蔽其他频率信号的滤波器电路。这种滤波器被用于收音机的选台(调整频率)、或剔除中音用扬声器的低音/高音成分等。 2 低通滤波器的种类 电容器和电感,虽然各自单独具有噪声去除效果,但是通过将2个零部件进行组合,就可获得更大的噪声去除效果。串联连接的电感以隔断高频噪声,用并联连接的电容器来使高频噪声旁通的方式发挥作用。但是,噪声去除效果也会随输入侧和输出侧各自的外部阻抗的高低而改变。譬如,即使试图用低阻抗的电容器来使噪声旁通,如果输出阻抗更低,则噪声会流向负荷侧。相反,即使试图以高阻抗的电感来隔断噪声,如果输出阻抗更高,则噪声会流向负荷侧。因此,外部阻抗高时,将电容器配置在附近;外部阻抗低时,将电感配置在附近。如上所述,考虑外部阻抗,低通滤波器可区分为以下4类。 2.1 L型滤波器(1) 应用场景:输入阻抗 ⇒ 高;输出阻抗 ⇒ 低 时 2.2 L型滤波器(2) 应用场景:输入阻抗 ⇒ 低;输出阻抗 ⇒ 高 时 2.3 π型滤波器 应用场景输入阻抗 ⇒ 高;输出阻抗 ⇒ 高 时 2.4T型滤波器 应用场景:输入阻抗 ⇒ 低;输出阻抗 ⇒ 低 时 相比L型滤波器,π型和T型滤波器的噪声去除效果更好,因而还要考虑这方面的因素来选定电路。 3 低通滤波器的零部件选择 要在信号电路上从信号波形去除噪声时,必须选定在信号频率下不会衰减而在噪声频率下衰减会增大的零部件常数。要在电源电路上从直流电压去除噪声时,由于直流的衰减为零,因而只考虑噪声频率的衰减量。 滤波器的衰减特性(频率引起的衰减量的变化)可通过计算来求得,但实际的电容器和电感除了纯粹的静电电容和电感外还包含有影响性能的成分,因而无法单纯地计算。 在L型滤波器上标示出基于电容器和电感的实际等效电路的电路图。 电容器上除了静电电容©外还包含有等效串联电阻(ESR)和等效串联电感(ESL),电感上除了电感(L)外还包含有直流电阻(DCR)和杂散电容(Cp)。 电容器若只是C成分,频率越高阻抗低,噪声吸收效果越好,但在实际的电容器上则根据ESR来决定阻抗的下限值,并且阻抗在高频域会随ESL而升高,变得不易吸收噪声。 此外,电感若只是L成分,频率越高阻抗高,噪声隔断效果越好,但实际上阻抗会随电感器中所包含的Cp而在高频域下降,噪声的隔断效果下降。 再者,各自的成分也会随频率而发生值的变化,因而将这些因素全都考虑进来选定零部件就变得相当难。 因此,LC滤波器上经常会使用模拟工具来选定零部件。 通常,模拟工具上可使用按零部件的型号别提供的S参数或SPICE模型,来计算每个频率的正确的衰减量。 4 仿真 在线仿真路径 需求:射频噪声中包括AM频带(1MHz左右)和FM频带(80MHz左右),选定在这2个频带衰减量满足-60dB以上的零部件。 另外,前提条件是假定输入/输出阻抗为50Ω。 目标频率 : 1MHz, 80MHz

数字电路硬件设计系列(五)之AT89C51/C52最小系统设计

1 简介 AT89C51/C52是指两个系列的产品,具体包含AT89C51、AT89C52,但是最小系统的组成基本上相差不大。最小系统通常包括:电源、复位、时钟、程序下载。 2 最小系统分析 讲解内容以AT89C52为例,对AT89C52最小系统进行详细讲解。 2.1 电源设计 与STM32不同,AT89C52不仅可以3.3V供电,还能使用5V进行供电。通常情况下,单片机的供电时5V。其中EA为高时,选择内部程序存储。 2.2 复位电路设计 与STM32不同,AT89C52采用的高电平复位。系统正常工作时,复位管脚为低电平,系统复位时,将复位管脚拉高,整个系统将回到复位状态。 2.3 时钟电路 AT89C52的晶振电路采用的22.1184MHz的晶振,通常采用12MHz的晶振比较多。匹配电容的计算方式,请参考这篇文章:晶振匹配电容和电阻的计算。

vue 富文本编辑器 wangeditor 自定义上传图片 以及 解决 复制粘贴 word 没有图片的情况

本人比较喜欢用这一款编辑器,官方文档:(用于 Vue React | wangEditor),很详细。我主要来说说怎么使用customPaste 自定义粘贴的,怎么解决 复制粘贴 word ,没有图片的情况。 主要是关于wangeditor在vue2的使用 效果图: 先把完整代码放这里: <template> <div class="addpost_course"> <div id="editor" style="border: 1px solid #ccc; width: 534px"> <Toolbar style="border-bottom: 1px solid #ccc" :editor="editor" :defaultConfig="toolbarConfig" :mode="mode" /> <Editor style="height: 200px; overflow-y: hidden" v-model="content" :defaultConfig="editorConfig" :mode="mode" @onCreated="onCreated" @onChange="onChange" @onDestroyed="onDestroyed" @onMaxLength="onMaxLength" @onFocus="onFocus" @onBlur="onBlur" @customAlert="customAlert" @customPaste="customPaste" /> </div> </div> </template> <script> import { Editor, Toolbar } from "@wangeditor/editor-for-vue"; import { Loading, Message } from "element-ui"; export default { components: { Editor, Toolbar }, data() { return { // 富文本 editor: null, // 富文本里面的所有内容(带标签的) content: "

Linux-Docker的基础命令和部署code-server

1.安装docker 1.安装需要的安装包 yum install -y yum-utils 2.设置镜像仓库 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 3.安装docker yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 4.启动docker docker version #查看版本 systemctl start docker 5.测试hello-world docker run hello-world 安装完成; 阿里云镜像加速 2.基本命令 整个流程: 为什么docker更快? 帮助命令 docker version #显示docker版本信息 docker info #显示daocker的系统信息 docker 命令 --help #帮助命令 镜像命令 1.docker images :-a 列出所有的镜像 :-f :-q 只显示镜像的id 2.docker search mysql :--filters=STARS=300 #搜索大于3000的 3.docker pull 镜像名[tags] :不加tag下载最新版 4.docker rmi -f id 删除指定镜像 :docker rmi -f $(docker images -aq) 删除全部镜像 分层下载,若有更新,只需要更新需要更新的几层就行;

c++转编码---UTF8转GBK---GBK转UTF8

编码转换 #include "iconv.h" // 编码转换函数 static std::string encode_convert(const char* fromcode, const char* tocode, const char* text) { char* tmp = (char*)text; size_t lenSrc = strlen(tmp); size_t lenDst = lenSrc * 5; char* out = (char*)malloc(lenDst); memset(out, 0, lenDst); char* pFreeOut = out; iconv_t cd = iconv_open(tocode, fromcode); size_t ret = iconv(cd, &tmp, &lenSrc, &out, &lenDst); if (ret == -1) { return ""; } std::string retStr(pFreeOut); iconv_close(cd); free(pFreeOut); return retStr; } // GBK转utf-8 static std::string GBK_TO_UTF8(const char* text) { if (strlen(text) == 0) { return "

InputStream、byte[]、File相互转换工具类

import java.io.*; import java.nio.channels.FileChannel; public class FileUtils_Byte_Stream { /** * *byte数组转inputstream * * @param bytes * @return */ public static InputStream bytesToInputStream(byte[] bytes) { InputStream inputStream = new ByteArrayInputStream(bytes); return inputStream; } /** * *inputstream转byte数组 * * @param inputStream * @return * @throws IOException */ public static byte[] inputStreamToBytes(InputStream inputStream) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] buffer = new byte[4096]; int n = 0; while (-1 !

大数据技术相关概念--学习笔记

一.大数据定义 维基百科的定义:大数据是指其大小或复杂性无法通过现有常用的软件工具,以合理的成本并在可接受的时限内对其进行捕获、管理和处理的数据集。这些困难包括数据的收入、存储、搜索、共享、分析和可视化。 IBM的定义:大数据横跨三个层面:数量 ,速度和品种。IBM将大数据概括为三个V,即大规模(volume),高速度(velocity)和多样化 (variety),这些特点也反映了大数据所潜藏的价值。因此大数据的特征可以概括为海量+多样化+快速处理+价值。 SAS的定义:SAS在大数据传统3V模拟定义的基础上加入了“可变性”和“复杂性”两个重要特征。可变性主要反映可数据流可能具有高度的一致性,并存在周期性的峰值。复杂性主要提现在数据来源的多样性。连接、匹配、清洗、和转化 来自多个系统的数据是一件非常复杂的事情。 二.大数据的研究内容 大数据的研究工作面临5个方面的挑战: 数据获取问题,需要决策哪些数据需要保持或者丢弃等问题。数据结构问题 如何将没有语义的 内容转换为结构化的格式,并进行后续处理。数据集成问题 只有将数据进行关联,才能充分发挥数据的作用,因此数据集成也是一项挑战。数据分析、组织、抽取和建模是大数据本质的功能。如何呈现数据分析的结果,并与非技术的领域专家进行交互。 为应对上述挑战,白皮书建议采用现有的成熟技术解决大数据带来的挑战,并给出了大数据分析的分析步骤 ,大致分为 数据获取/记录、信息抽取/清洗/注记、数据集成/聚集/表现、数据分析/建模和数据解释五个主要阶段。 数据获取和记录 研究数据压缩中的科学问题,能够智能处理原始数据,在不丢失信息的情况下,将海量数据 压缩到人可以理解的程度;研究在线数据分析技术,能够处理实时流数据;研究元数据自动获取技术和相关系统;研究数据来源技术,追踪数据的处理和产生过程。 信息抽取和清洗 一般来说,收集到 的信息需要一个信息抽取过程 ,才能用来进行 数据分析。抽取的对象 可能包含图像 、视频等 具有复杂结构的数据,而且该过程是与应用高度相关的。一般认为大数据通常会反应事实情况,实际上大数据中广泛存在虚假数据。关于数据清洗的现有 工作通常假设数据是有效的、良好组织的,后对其错误模型具有良好的先验知识,这些 假设在大数据领域将不再正确。 数据集成、聚集和表示 由于大量异构数据的存在 ,大数据处理不仅仅是对数据进行记录,然后就将其放入存储中。如果仅仅 是将一堆数据放入存储中,那么其他人就可能无法查找、修改数据,更不能使用数据了。即使各个数据 都存在元数据,将异构数据整合在一起仍然是一项巨大的挑战。对大数据进行有效分析需要以自动化的方式对数据进行定位 、识别、理解和引用。为了实现该目标,需要研究数据结构和语义的统一描述方式与智能理解技术,实现机器自动处理,从 这一角度看,对数据结构与数据库的而设计也显得尤为重要。 查询处理、数据建模和分析 大数据的噪声很多,具有动态性、异构性、关联性,不可信任性等多种特征。尽管如此,即使是充满噪声的大数据也可能比小样本的数据更有价值,因为频繁模式和相关分析 得到的一般统计数据通常强于 具有波动性的个体数据,往往透露更可靠的隐藏模式和知识。互联的大数据可形成大型异构的信息网络,可以披露固有的社区,发现隐藏的关系和模式。 数据挖掘需要完整的、经过清洗的、可信的、可被高效访问的数据,以及声明性的查询和挖掘接口,还需要可扩展的挖掘算法及大数据计算环境。 解释 仅仅有能力分析大数据本身,而无法让用户理解分析结果,这样的效果价值不大。如果用户无法理解的分析,最终,一个决策者需要对数据分析结果进行解释。对数据的解释不能凭空出现,通常包括检查所有提出的假设并对分析过程进行追踪和折回分析。大数据由于其复杂性,这一过程特别具有挑战性,是一个重要的研究内容。 三.大数据的应用领域 1制造业的应用 制造业目前正在相信息化和自动化的方向发展 。在产品设计、生产和销售中,越来越多的企业使用计算机辅助设计(CAD)、计算辅助制造(CAM)等软件 ,数控机床,传感器等设备,物料需求计划,企业资源计划等系统。这些信息技术的应用大大提高了工作效率和产品质量。 然而随着信息化的不断深入,制造业目前所面临的挑战就是在 产业信息话之后。如何提升获取和开拓市场需求的能力,从而创造出更有价值的商品。 2服务业的应用 传统的服务行业有悠久的历史。当信息时代到来的时候,服务业就衍化出现了两种形态;一种是信息技术与服务 业相结合的信息服务业,另一种是应用信息技术改造传统服务业而来的服务业。在信息 服务业,最常见的大数据分析当属网络公司收集用户的网页点击 行为提供个性化的广告与 信息推送服务,需要注意的是这些行为需要考虑用户隐私的保护问题。在信息化改造后的服务业,大数据更是无处不在。在零售行业,厂商可以通过互联网点击流实时跟踪客户行为、更新客户偏好、建立可能行为的模型。在此基础上 ,产商能够确定客户下次购买的时间,通过捆绑优选商品、提供省钱的奖励性计划,对交易实施微调等措施,最终使得整个销售圆满结束。在金融行业,银行可以从大量数据中发现信用卡欺诈和盗用;理财网站从停机的消费数据中来测试宏观的经济趋势;保险公司通过大数据能够找出可以的权利要求。在旅游行业,企业致力于旅游预定数据的收集、分析与处理。 3交通行业的应用 当前,出行难问题对各大城市来说都是亟待解决。当前,可以利用新进的传感技术 、网络技术、计算技术、控制技术、智能技术,对道路和交通进行全面感知。而在大数据时代的智慧交通,需要融合传感器、监视视频和GPS等设备产生的海量数据,甚至与气象监测设备产生的天气状况等数据 相结合,从中提取出人们真正需要的信息,及时而准确地进行发布和推送,通过计算直接提供最佳的出行方式和路线。 4医疗行业的应用 医疗健康问题是当前社会普遍关注的焦点问题。以往,人们总是在发现自己生病时才看病 就医,而且到了医院还要经历挂号、求诊、配药等复杂流程,整个过程需要 耗费大量的时间,容易形成 就医困难的困境。如今,基于电子医疗记录技术,点子病例正逐渐被各大医疗机构所采用。在大数据时代,可以将医疗机构的电子病历记录标准化,形成全方位多维度的大数据仓库。系统首先全面分析 患者的基本资料、诊断结果、处方、医疗保险情况和付款记录等诸多数据,再将这些不同的数据综合起来,在医生的参与下通过决策支持 系统选择 最佳的医疗护理解决方案 。

JavaSE 基础知识

JavaSE 基础知识(一) 前言(一)对象和类1.类的声明1.1访问控制符1.2修饰符 2.变量的声明2.1访问控制符2.2修饰符 3.方法的声明3.1访问控制符3.2修饰符 (二)三大特性1.封装2.继承3.多态3.1方法的覆盖/重写3.2方法的重载 (三)接口1.1接口的声明1.2接口的实现 前言 本文将对Java的三大特性:封装、继承、多态进行简单的说明,涉及abstract、final、static、implements、extends……等关键字,主要对父类和子类的继承、方法的重载和重写进行详细的叙述。 Tips:小白一枚,分享一些学习心得,请大佬们指正! (一)对象和类 1.类的声明 [访问控制符] [修饰符] class 类名 [extends 父类] [implements 接口]{} extends关键字的意思是继承,使用该关键字可以让该类继承另外一个类(只能一个) implement关键字的意思是实现接口,使用该关键字可以实现一个或多个接口 1.1访问控制符 关键字含义public所修饰的类是公共的,任何类都可以访问private所修饰的类是私有的,自能被该类自身访问protected所修饰的类可以被该类本身和同一包下的其他类或不同包下的子类访问friendly(默认)所修饰的类只能被自身和同一包下的类访问 1.2修饰符 关键字含义static声明该类是静态类abstract声明该类是抽象类,抽象类中至少有一个方法是抽象的,被abstract关键字声明的类不能被实例化,即不能生成对象final声明该类为最终类,不能被继承 2.变量的声明 [访问控制符] [修饰符] 变量类型 方法名称 变量名称 2.1访问控制符 关键字含义public所修饰的成员变量是公共的,任何类都可以访问private所修饰的成员变量是私有的,自能被该类自身访问protected所修饰的成员变量可以被该类本身和同一包下的其他类或不同包下的子类访问friendly(默认)所修饰的成员变量是友好型的,只能被自身和同一包下的类访问 2.2修饰符 关键字含义static所修饰的变量称为静态变量,可以被该类所有对象共享final所声明的变量的值不能再被修改 一般用static和final共同定义一个常量,名称所有字母都大写,以便与变量区分。 private static final int MAX = 50; 3.方法的声明 [访问控制符] [修饰符] 方法返回值类型 方法名称 ([参数类型 参数列表]) [throws 异常] 3.1访问控制符 关键字含义public所修饰的方法是公共的,任何类都可以访问private所修饰的方法是私有的,自能被该类自身访问protected所修饰的方法可以被该类本身和同一包下的其他类或不同包下的子类访问friendly(默认)所修饰的方法是友好型的,只能被自身和同一包下的类访问 3.2修饰符 关键字含义static声明的方法为静态方法,可以被该类所有对象所共享(不用创建对象即可调用)abstract声明的方法是抽象方法,抽象方法只有声明,没有方法体final声明的方法不能被重写或覆盖 (二)三大特性 1.封装 封装就是把对象的属性和服务结合成一个独立相同的单位,并尽可能隐蔽对象的内部细节。 封装的两层含义: (1)把对象的所有属性和方法都打包在一起,形成一个独立相同的单位(对象)。对象的私有属性只能由对象的行为来读和写。 (2)尽可能隐蔽对象的内部细节,通过外部接口与外界实现进行联系。 封装的优点:高内聚,低耦合,减少依赖。 代码示例: (1)Person 类封装 name、gender、age 等属性,外部只能通过 get() 方法获取一个 Person 对象的 name 属性和 gender 属性,而无法获取 age 属性,但是 work() 方法可以使用age属性。

【mysql】将逗号分割的字段内容转换为多行并group by

先说需求: 公司想让我通过mysql导出一个报表,内容为公司每个人参加会议的次数,现在有一个会议表fusion_meeting,正常的逻辑是通过人员直接group by就可以得出结果,但是我们的参会人是通过逗号分割这种方式存在一个字段里,这就导致无法直接group by。 所以我们要通过将逗号分割的字段内容转换为多行然后再group by 1、原来的字段格式 2、将逗号分割的字段内容转换为多行 下面直接给出sql,并对sql的每一步做出解释,更有助于大家理解 首先要说明的是,mysql.help_topic本身是mysql的一张信息表,用来存储各种注释等帮助信息,help_topic拥有一个自增为1的id属性–help_topic_id ,并且可以当做下标来使用,拥有固定数量的数据 解释: length(a.attendee_uid) - length(REPLACE(a.attendee_uid, ‘,’, ‘’)) + 1第一步的意思是 字段attendee_uid的长度 - 字段attendee_uid去除掉逗号的长度,然后再+1就得到了通过逗号分割后有几条数据比如上一步得到是3 那就可以确定这个字段要拆分为3行 help_topic_id<3 也就是可以得到下标 0,1,2比如这条数据’zhangsan,lisi,wangwu’ 第一个substring_index的意思就是把’zhangsan,lisi,wangwu’通过逗号分割,然后取b.help_topic_id + 1(help_topic_id就是第3步得到的下标)结果就是zhangsan第二个substring_index的意思是 再从第4步的结果 从右边取第一个, 因为’zhangsan,lisi,wangwu’如果获取到下标为2的话那得到的就是’zhangsan,lisi’ 所以再从右边取第一个就得到了 ‘lisi’ SELECT a.id '会议id', a.attendee_uid '原始参会人列表', # 4、比如这条数据'zhangsan,lisi,wangwu' 第一个substring_index的意思就是把'zhangsan,lisi,wangwu'通过逗号分割, # 然后取b.help_topic_id + 1(help_topic_id就是第3步得到的下标)结果就是zhangsan # 5 第二个substring_index的意思是 再从第4步的结果 从右边取第一个, 因为'zhangsan,lisi,wangwu'如果获取到下标为2的话那得到的就是'zhangsan,lisi' 所以再从右边取第一个就得到了 'lisi' substring_index(substring_index(a.attendee_uid, ',', b.help_topic_id + 1), ',', -1) AS '分割后的参会人账号' FROM `fusion_meeting` a JOIN mysql.help_topic b # 1、length(a.