1.在src\locales\index.js文件修改默认语言
// import enUS from './lang/en-US' import zhCN from './lang/zh-CN' Vue.use(VueI18n) // export const defaultLang = 'en-US' export const defaultLang = 'zh-CN' const messages = { // 'en-US': { // ...enUS // } 'zh-CN': { ...zhCN } } 2.在src\core\bootstrap.js文件,修改初始化的语言
// store.dispatch('setLang', storage.get(APP_LANGUAGE, 'en-US')) store.dispatch('setLang', storage.get(APP_LANGUAGE, 'zh-CN')) 3.在src\store\modules\app.js文件,修改app对象里state中的lang属性
lang: 'zh-CN', 4.改完之后发现侧边栏主题设置变成了类似app.setting…的字样,接着在src\locales\lang\zh-CN.js里添加配置,因为英文的这里有这个配置文件,中文的没有,所以手动添加一个
'app.setting.pagestyle': '主题风格设置', 'app.setting.pagestyle.light': '白色', 'app.setting.pagestyle.dark': '黑色', 'app.setting.pagestyle.realdark': '全黑', 'app.setting.themecolor': '主题颜色', 'app.setting.navigationmode': '导航模式', 'app.setting.content-width': '内容宽度', 'app.setting.fixedheader': '固定头部', 'app.setting.fixedsidebar': '固定侧边', 'app.setting.sidemenu': '侧菜单布局', 'app.
Pytorch: 空洞卷积神经网络 Copyright: Jingmin Wei, Pattern Recognition and Intelligent System, School of Artificial and Intelligence, Huazhong University of Science and Technology
Pytorch教程专栏链接
文章目录 Pytorch: 空洞卷积神经网络 @[toc]空洞卷积神经网络搭建数据预处理空洞卷积神经网络的训练和预测 本教程不商用,仅供学习和参考交流使用,如需转载,请联系本人。
相对于普通卷积,空洞卷积通过在卷积核中添加空洞( 0 0 0 元素),从而增大感受野,获取更多信息。感受野为在卷积神经网络中,决定某一层输出结果中一个元素对应的输入层的区域大小,通俗解释就是特征映射上的一个点对应输入图上的区域大小。
对于一个 3 × 3 3\times3 3×3 的 2 2 2-空洞卷积运算,实际的卷积核大小还是 3 × 3 3\times3 3×3 。但是空洞为 1 1 1 ,这样卷积核就会扩充一个 7 × 7 7\times7 7×7 的图像块,但只有 9 9 9 个红色的点会有权重取值进行卷积操作。也可以理解为卷积核的大小为 7 × 7 7\times7 7×7 ,但只有图中的 9 9 9 个点的权重不为 0 0 0 ,其他均为 0 0 0 。实际卷积权重只有 3 × 3 3\times3 3×3 ,但感受野实际为 7 × 7 7\times7 7×7 。对于 15 × 15 15\times15 15×15 的,实际卷积只有 9 × 9 9\times9 9×9 。
在前几天的数据库学习中,遇到了需要删除数据表所有数据的问题,在网上查阅了相关资料,发现两种比较常用的清楚数据的方式,就是delete和truncate这两个关键字:
下面是自己总结的二者的区别:
相同点:
delete和truncate它们都可以用来清除表数据,而且都不会改变原有的表的结构相应语法格式: delete关键字:delete from 表名 truncate关键字:truncate 表名 不同点:
truncate可以在清除表数据的同时,可以时自增列的“计数器”归零还有就是不会影响事务(这个还没有体会到) 总结:在需要清除数据时建议使用truncate关键字
以上就是我目前对二者的全部理解,如有错误请大家多多纠正,谢谢。
1 概述 Spring Boot上传文件,根据官方上传文件示例修改的,打包成WAR上传到Tomcat上,主要步骤是创建异常类,属性类,接口类与控制器类,最后进行少量修改打包部署到服务器上。
2 环境 Tomcat 9.0.30Spring boot 2.2.2 3 新建工程 选择Spring initializer:
改一下包名,打包选项JAR/WAR均可,选JAR的话可以在构建的时候再生成WAR。
这里用的是模板引擎Thymeleaf,选择Spring Web与Thymeleaf。
最后点击完成。
4 新建包 4个包,service,properties,controller,exception。
5 异常 处理两个异常,分别是存储异常与存储文件找不到异常。
5.1 StorageException package kr.test.exception; public class StorageException extends RuntimeException { public StorageException(String message) { super(message); } public StorageException(String message,Throwable cause) { super(message,cause); } } 5.2 StorageFileNotFoundException package kr.test.exception; public class StorageFileNotFoundException extends StorageException { public StorageFileNotFoundException(String message) { super(message); } public StorageFileNotFoundException(String message,Throwable cause) { super(message,cause); } } Exception(String message,Throwable cause); 这个构造函数中的cause是引起这个异常的异常,允许空值,如果是空值则表示这个引起这个异常的异常不存在或者未知。
Java获取python返回值时,可以通过print()来获取,但如果数据量过长,打印出的结果将会包含省略号。同样,Java接受到的数据也是包含省略号的。也就是说,python本地打印出是什么样子,Java接收到的就是什么样子。
处理大量数据中打印省略的问题: 1. 对于Numpy数据: 在输出print()位置前加入:
1 np.set_printoptions(threshold=np.inf) 通过设置输出选项,将阈值设置为一个较大的数,从而实现完整长度的打印。
2. 对于pandas数据: pandas数据的设置分为行列的设置:
1 #显示所有列 2 pd.set_option('display.max_columns', None) 3 #显示所有行 4 pd.set_option('display.max_rows', None) 5 #设置value的显示长度为100,默认为50 6 pd.set_option('max_colwidth',100) 项目中使用的方式:
1 pd.set_option('display.max_columns', 1000000) # 可以在大数据量下,没有省略号 2 pd.set_option('display.max_rows', 1000000) 3 pd.set_option('display.max_colwidth', 1000000) 4 pd.set_option('display.width', 1000000) 3. 对于tensor数据: 将数据转成list就好。
tensor数据省略问题,numpy和pandas的设置都是无效的。
前提,我尝试过很多种安装的方法都不行,最后才使用了本文的方法,最终达到了自己的要求。 首先下载visual studio 2019
地址:https://visualstudio.microsoft.com/zh-hans/vs/
3.下载好以后点击安装
必选C++环境,python环境可以勾选,也可以自己单独下载python解释器。
python3.7.3下载地址:https://www.python.org/ftp/python/3.7.3/python-3.7.3-amd64.exe
4.设置Cmake环境为系统环境变量
我们之所以安装visual studio就是为了正确的安装cmake,因为visual studio 在之前勾选了c++选项以后,可以正确的安装cmake。
那么我们现在就找到visual studio 安装好的cmake 文件路径,在我的电脑上路径是:
D:\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin
复制路径设置环境变量(如果看图片看不懂,自己百度系统环境变量设置),如下图所示:
5.然后运行cmd
输入pip install dlib
如果提示没有这个命令,自行百度设置python为系统环境变量。
运行这个命令以后,稍等片刻就可以了,如果用的不是国内源的话就会很慢,要稍微等一下。
————————————————
版权声明:本文为CSDN博主「小舒」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_25858235/article/details/96424333
系统设置 创建用户 右键“此电脑—>管理—>本地用户和组“,右键”用户—>新用户“,添加用户名,设置密码(勾选密码永不过期)。然后点击创建即可。
“设置——>系统——>远程桌面——>选择可远程访问这台电脑的用户——>添加”,把新创建的用户添加进去
配置本地组策略 运行 gpedit.msc 打开本地组策略编辑器。
选择“【管理模板】—>【Windows组件】—>【远程桌面服务】—>【远程桌面会话主机】—>【连接】
配置【限制连接的数量】
配置【将远程桌面服务用户限制到单独的远程桌面服务会话】
配置【允许用户通过使用远程桌面服务进行远程连接】
测试用户 使用新建的用户通过remote desktop尽心登陆,确保新建用户可以正常使用
系统打补丁 下载补丁 从https://github.com/stascorp/rdpwrap/releases下载补丁程序的最新版本
运行 解压,以管理员身份运行脚本install.bat,需要联网
运行结果
双击运行程序RDPConf.exe
如果显示“not supported”,需要下载对应版本的配置文件,版本号即“Service state”,我这里是“10.0.1904.1503”
到网址https://github.com/stascorp/rdpwrap/issues找到自己对应版本的配置文件rdpwrap.ini,并下载到本地,替换掉本地文件
我使用的配置文件放在了https://download.csdn.net/download/fleaxin/80399377
如果复制黏贴时提示
给原始文件增加操作权限,右键rdpwrap.ini文件,“属性——>安全——>编辑”,给Users用户增加读写权限
再次以管理员身份运行脚本install.bat
双击运行RDPConf.exe程序
只要显示“fully supported”,则便是打补丁成功,否则,更换配置文件再次尝试
测试 打补丁成功后,重启电脑,或者重启remote desktop服务
双击运行RDPCheck.exe
选择新建的用户登陆
可以正常登陆,且主账户没有推出,则表示成功,否则,更换其他配置文件再次尝试
【软件环境】
MiKTeX(本文选用 basic-miktex-21.12-x64)
https://miktex.org/
Texmaker(本文选用 Texmaker_5.1.2_Win_x64)
https://www.xm1math.net/texmaker/download.html
【设置步骤】
MiKTeX + Texmaker 组合下使.tex文件支持中文,核心在于只需设置MiKTeX。
而MiKTeX设置的核心,在于只需选择宏包的国内镜像下载地址(如清华镜像:https://mirrors. tuna. tsinghua. edu. en)。从而,在需要时,使MiKTeX可以快速下载安装需要的宏包。
具体设置MiKTeX的步骤如下:
【样例测试】
设置完MiKTeX后,在Texmaker中输入如下包含中文内容的.tex文件样例:
\documentclass{article} \usepackage[UTF8]{ctex} \begin{document} Test 测试中文 \end{document} 然后,在Texmaker下运行此包含中文内容的.tex文件,会自动弹出需要安装某些需要的宏包的窗口,按提示进行安装操作便OK。(若在此步中没有自动弹出安装宏包的相关窗口,可先在MiKTeX下搜索宏包 ctex 进行安装,然后再执行此步骤)
下图是在Texmaker下成功运行包含中文的.tex文件的截图。
【参考文献】
https://blog.sciencenet.cn/blog-478347-1215384.html
https://blog.csdn.net/hnjzsyjyj/article/details/122894417
https://jingyan.baidu.com/article/ff411625e229d512e482379c.html
api-ms-win-crt-runtime-l1-1-0.dll是一个Windows系统的应用程序拓展文件,也叫动态链接库文件。这个文件能帮助绝大多数用户解决在安装或启动部分游戏软件时出现计算机中丢失api-ms-win-crt-runtime-l1-1-0.dll这样的问题。
缺少api-ms-win-crt-runtime-l1-1-0.dll的主要表现
1、软件游戏等应用程序无法正常安装或运行。
2、使用应用程序时出现弹窗,提示缺少该文件。
3、严重时甚至可造成系统程序无法运行使用。
api-ms-win-crt-runtime-l1-1-0.dll使用方法
1.首先在华军软件园下载api-ms-win-crt-runtime-|1-1-0.dll文件,将该文件复制到系统目录里,具体路径为:C:WindowsSystem32,64位操作系统路径为:C:WindowsSysWOW64。
2.放置文件后,还需启用这个文件。具体操作为:在开始菜单中找到“运行(R)” (按快捷键“Win键+R”),此时会弹出一个对话框,在框内输入 regsvr32 api-ms-win-crt-runtime-l1-1-0.dll ,然后按回车,一般情况下这样就能解决“api-ms-win-crt-runtime-l1-1-0.dll 丢失”这个问题。
说明:下载的文件要与操作系统相对于,否则无法解决问题。
api-ms-win-crt-runtime-l1-1-0.dll常见问题
1.放置或更换过该组件后还是不能解决这个问题,该怎么办?
可以尝试通过更换程序库来解决,即重新安装VC redit.exe程序来解决“api-ms-win-crt-runtime-l1-1-0.dll 丢失”这个问题。注:由于该方法操作较为专业,这里简要列出方法:
1.首先先下载Visual Studio 2015组件,删掉原有的api-ms-win-crt-runtime-l1-1-0.dll文件,具体路径为:C:WindowsSystem32;64位操作系统路径为:C:WindowsSysWOW64。
2.安装完VC redit.exe后,重启电脑
说明:下载文件之前,一定要确定下该文件是否适合您电脑的操作系统,否则还是会出现问题
2.api-ms-win-crt-runtime-l1-1-0.dll可以删除吗?
不可以,这是系统接口程序,删除会造成响应系统无法运行!
软件获取
点击下方名片进入公众号『Python语言空间』,添加微信即可,请大家点赞收藏!!
python语言空间
该账号分享python基础语法、干货,开发软件,web语言,网络安全渗透方面知识,用于日常学习交流。
定义如下形式的字符串
char *testString = “This is test string…” 编译器显示这段代码错误,运行后显示为C2664错误
这时候我们只需要修改一下项目设置
具体步骤: 一、标签页点击项目,下拉找到自己的项目名称 二、找到 C/C++ -> 语言 ->符合模式 ->将‘是’改为‘否’ 如下图所示
这样问题就顺利解决了
😜 相 见 就 是 【 猿 分 】 🐒
.
👀 感谢您阅读完此文章 👀
.
❓ 希望能够对你有所帮助 🎯
.
❌ 如果文章中有错误的地方请指正 ✔️
.
💪 感谢支持,一起加油,共同进步 🏃
shell脚本中文件描述符 文件描述符特征 文件描述符是一个非负整数,内核需要通过这个文件描述符才可以访问文件当在系统中打开已有的文件或者新建文件时,内核每次都会给特定的进程返回一个文件描述符,进程需要对文件进行读或写操作时,都要依赖这个文件描述符文件描述符就像一个索引,指向系统中对应的文件内核默认为每个进程创建3个标准的文件描述符,分别为0标准输入、1标准输出、2标准错误文件描述符中还包含有很多文件相关的信息,如权限、文件偏移量等。使用文件描述符读写文件要注意文件偏移量指针的变化情况 查看文件描述符 #通过查看/proc/进程pid/fd/目录下的文件可以查看到对应进程拥有的所有文件描述符 [root@mao_aliyunserver bin]# pgrep -f 'top' 14963 [root@mao_aliyunserver bin]# ll /proc/14963/fd total 0 lrwx------ 1 root root 64 Feb 10 23:04 0 -> /dev/pts/3 lrwx------ 1 root root 64 Feb 10 23:04 1 -> /dev/pts/3 l-wx------ 1 root root 64 Feb 10 23:04 2 -> /dev/null lrwx------ 1 root root 64 Feb 10 23:04 3 -> /dev/pts/3 lr-x------ 1 root root 64 Feb 10 23:04 4 -> /proc/stat lr-x------ 1 root root 64 Feb 10 23:04 5 -> /proc/uptime lr-x------ 1 root root 64 Feb 10 23:04 6 -> /proc/meminfo lr-x------ 1 root root 64 Feb 10 23:04 7 -> /proc/loadavg 创建和关闭文件描述符 #创建文件描述符: exec 文件描述符<>文件名 (<>表示可读写,<可读 >可写,注意<>两边不能有空格) #创建文件描述符时,如果描述符对应的文件不存在,系统会自动创建一个新的空文件 [root@mao_aliyunserver bin]# touch mao.
栈(stack):
再来说说栈的几个概念与常见操作:
栈的设计思路:
下面说一下栈的顺序存储原理:
具体代码设计思想:
话不多说,直接上代码:
stack.h:
#ifndef _STACK_H_ #define _STACK_H_ #define EMPTY_INDEX -1 //代表栈里面没有元素 #define MAX_SIZE 100 //这里设计可以大一点,防止数据溢出 //定义抽象的数据存放类型 typedef int element_type;//以后不想要这个类型就从这改 typedef struct _t_seq_stack { int top_of_index;//当前栈顶的索引角标 element_type array[MAX_SIZE]; }t_seq_stack; //创建栈 t_seq_stack *create_stack(); //判断栈是否为空 int is_empty(t_seq_stack *stack); //销毁栈 void destroy_stack(t_seq_stack *stack); //从理论上清空栈,也就是把长度变为-1,但是元素还是存放在相应的数组空间 void make_empty(t_seq_stack *stack); //出栈,从理论上出栈,数据还是存在元素中 void pop_stack(t_seq_stack *stack); //入栈 void push_stack(t_seq_stack *stack,element_type value); //拿到栈顶元素 element_type top_stack(t_seq_stack *stack); #endif stack.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "
Mybatis 一级缓存作用域是 session,session commit 之后缓存就失效了。
Mybatis 二级缓存作用域是 sessionfactory,该缓存是以 namespace 为单位的(也就是一个 Mapper.xml 文件),不同 namespace 下的操作互不影响。
所有对数据表的改变操作都会刷新缓存。但是一般不要用二级缓存,例如在 UserMapper.xml 中有大多数针对 user 表的操作。但是在另一个 XXXMapper.xml 中,还有针对 user 单表的操作。这会导致 user 在两个命名空间下的数据不一致。
如果在 UserMapper.xml 中做了刷新缓存的操作,在 XXXMapper.xml 中缓存仍然有效,如果有针对 user 的单表查询,使用缓存的结果可能会不正确,读到脏数据。
Redis 很好的解决了这个问题,而且比之一、二级缓存的好处很多,Redis 可以搭建在其他服务器上,缓存容量可扩展。Redis 可以灵活的使用在需要缓存的数据上,比如一些热点数据,统计点赞啊
本文禁止转载!!!!
首先,由于Unity3D团队在持续更新IDE,Unity3D的开发环境的安装也是在不停的改变。本文安装的Unity3D环境是在2022年2月安装的,还算是比较新的。
安装步骤:
1、首先,进入官网下载软件
官网地址:https://unity.cn/
进入官网后,会看到如下界面
在这个界面下面,会看到下面的下载按钮:
我们选在下载“Unity Hub”
为什么要选在下载“Unity Hub”,而不是直接下载“Unity”?
因为,这个“Hub”就像一个集线器,把所有的东西都集成在里面了,通过这个Hub,可以快速的安装和注册。而不需要手动的安装或者注册。也就是说,选择这个Hub,安装起来会比较方便。
2、提示没有账号,需要注册一个账号
3、开始注册
注册过程中需要经过人机验证(防止恶意注册账号)
注册完毕后,会看到上面的界面,提示需要到邮箱中去激活账号
下图是邮箱中的激活连接:
激活后,需要更新个人的一些信息
4、需要绑定手机号,以上就创建UnityID成功,需要登录才可以下载相关的软件 然后再回到之前的下载"Unity Hub"的界面,登录之后,就可以下载了
5、UnityHub下载成功:UnityHubSetup.exe。 双击安装。安装直接下一步就可以了。
安装的过程中可能会遇到防火墙的阻止,允许即可
6、安装好后,需要激活License
选择手动激活
把许可证文件Unity_lic.alf保存在本地,方便后期使用
(本来理论上应该是可以按照上图在Unity3D Hub上激活的,但是不知道为什么,我会跳转到官网以web网页的方式激活(下图),不管了,就采用web网页的方式激活了)
在Browse里面加载刚才的License文件,加载好之后,一步步往下操作(这里面会提示你选择,你是普通用户还是企业用户,普通用户是免费的,企业用户专业版是要收费的。企业用户版本的Unity3D功能会更加强大),会弹出保存另外一个License文件,保存下来,放到刚才的Hub里面再激活
许可证激活成功
7、
进行实际的Unity3D IDE的安装 。在Hub里点击安装
Hub里面也要再登录一下自己的账号
选择2020 的版本,不要选择最高的版本(最新的版本可能会有一些bug)。推荐的版本是稳定的版本并且是长期支持的版本。
Unity3D采用的是C#开发,本质上底层需要支持 .net framewrok框架,所以必须要安装MS VS2019 下面的是安卓版本支持,也勾选上,意味着Unity3D做的游戏可以平移到安卓手机上运行
勾选许可证协议
整式开始下载安装包
安装包下载完毕后,会出现“正在安装”四个字
以上就安装完毕。安装完毕后的桌面图标如下:
问题描述:
pip install pandas 失败,报错如下:
ERROR: Could not find a version that satisfies the requirement pandas (from versions: none)
ERROR: No matching distribution found for pandas
解决方法:
pip install pandas -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
原因说明:网络差
相关标签 一、题目要求
二、题解和代码实现
1.题解 非官方题解,看视频理解思路
2.代码实现 代码如下(示例):
class Solution { public int eraseOverlapIntervals(int[][] intervals) { Arrays.sort(intervals, new Comparator<int[]>() {//排序 @Override public int compare(int[] o1, int[] o2) { return o1[0]-o2[0]; } }); int res = 0;//移除的个数 int end = intervals[0][1];//第一个数组的end值 for (int i = 1; i < intervals.length; i++) { if (end <= intervals[i][0]){//当数组的start值 >=end时,说明不重复 end = intervals[i][1];//把end 修改为当前元素数组的end值 }else {//说明重复,去除交集部分,保留end 小的元素数组 end = Math.min(end,intervals[i][1]);//保留end 和当前元素end 中的 最小值 res++;//移除个数+1 } } return res; } }
shell脚本中[[ ]]和[ ]的区别及注意事项 [[ ]]和[ ]的区别 一. test和[]是符合posix标准的测试语句,兼容性相对更强,几乎可以运行在所有的shell解释器中 二. [ ]同时支持多个条件的逻辑测试,但在[ ]需要使用-a或-o,在[[ ]]中可以直接使用&&和||。且&&和||短路,-a和-o不短路 [ ]中使用-a或-o
[root@mao_aliyunserver bin]# cat test.sh #!/bin/bash a=$1 b=$2 c=$3 if [ $a = $b -a $a = $c ]; then echo "abc全部相等" elif [ $a = $b -o $a = $c -o $b = $c ]; then echo "abc其中两个相等" fi [root@mao_aliyunserver bin]# sh test.sh 1 1 2 abc其中两个相等 [root@mao_aliyunserver bin]# sh test.sh 1 1 1 abc全部相等 [root@mao_aliyunserver bin]# sh test.
Floyd模板 见这
Floyd算法思路 首先要假定不存在负环,因为有负环的话那么最短距离就无解了;
这个算法和SPFA一样是基于 D P DP DP的;
用 f ( k , i , j ) f(k,i,j) f(k,i,j)表示从 i i i出发,最终走到 j j j,经过的节点编号不超过 k k k的所有路径的最小值;
考虑最后一步,我们可以划分出包含节点 k k k与不包含节点 k k k两部分;
不包含节点 k k k那么就是 f ( k − 1 , i , j ) f(k-1,i,j) f(k−1,i,j);
包含节点 k k k,那么路径分为 i → k i→k i→k加上 k → j k→j k→j两部分;
因为要求最小且两边互不影响,那么就是两边取最小;
则为 f ( k − 1 , i , k ) + f ( k − 1 , k , j ) f(k-1,i,k)+f(k-1,k,j) f(k−1,i,k)+f(k−1,k,j)
void acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) { int ret; if (ignore_ppc || !pr->performance) { /* * Only when it is notification event, the _OST object * will be evaluated. Otherwise it is skipped. */ if (event_flag) acpi_processor_ppc_ost(pr->handle, 1); return; } ret = acpi_processor_get_platform_limit(pr); /* * Only when it is notification event, the _OST object * will be evaluated. Otherwise it is skipped. */ if (event_flag) { if (ret < 0) acpi_processor_ppc_ost(pr->handle, 1); else acpi_processor_ppc_ost(pr->handle, 0); } if (ret >= 0) cpufreq_update_limits(pr->id);//调用下面的update_limits入口, } /** * cpufreq_update_limits - Update policy limits for a given CPU.
新频率在被设置时需要检查是否在可用范围内.
static struct cpufreq_driver longrun_driver = {
.flags = CPUFREQ_CONST_LOOPS,
.verify = longrun_verify_policy,
.setpolicy = longrun_set_policy,
.get = longrun_get,
.init = longrun_cpu_init,
.name = “longrun”,
};
When the user decides a new policy (consisting of
“policy,governor,min,max”) shall be set, this policy must be validated
so that incompatible values can be corrected. For verifying these
values cpufreq_verify_within_limits(struct cpufreq_policy *policy,
unsigned int min_freq, unsigned int max_freq) function might be helpful.
See section 2 for details on frequency table helpers.
dubbo 使用说明 自动配置类 DubboAutoConfiguration
@ConditionalOnProperty( prefix = "dubbo", name = {"enabled"}, matchIfMissing = true ) @Configuration @AutoConfigureAfter({DubboRelaxedBindingAutoConfiguration.class}) @EnableConfigurationProperties({DubboConfigurationProperties.class}) //dubbo配置类 @EnableDubboConfig //开启dubbo配置 public class DubboAutoConfiguration { public DubboAutoConfiguration() { } @ConditionalOnProperty( prefix = "dubbo.scan.", name = {"base-packages"} ) //存在dubbo.scan.base-packages属性 @ConditionalOnBean( name = {"dubbo-service-class-base-packages"} ) //并且存在名为dubbo-service-class-base-packages的bean时, @Bean public ServiceAnnotationPostProcessor serviceAnnotationBeanProcessor(@Qualifier("dubbo-service-class-base-packages") Set<String> packagesToScan) { return new ServiceAnnotationPostProcessor(packagesToScan); } //创建ServiceAnnotationPostProcessor的bean } EnableDubboConfig:是否开启dubbo配置bean多值绑定,默认开启
/** * As a convenient and multiple {@link EnableConfigurationBeanBinding} * in default behavior , is equal to single bean bindings with below convention prefixes of properties: * <ul> * <li>{@link ApplicationConfig} binding to property : "
keil下载和pack下载 keil下载如何找到keil老版本所在下载页面 pack下载 keil下载 链接: keil老版本.
链接: keil新版本.
如何找到keil老版本所在下载页面 pack下载 链接: pack下载.
初始化const引用时允许用任意表达式作为初始值,只要该表达式的结果能转化成引用的类型即可。允许为一个常量引用绑定非常量的对象、字面值、甚至是一个表达式:
int i = 42; const int &r1 = i; //允许将cont int&绑定到普通int对象上 const int &r2 = 42; //正确:绑定到字面值 const int &r3 = r1 * 2; //正确:绑定到表达式 int &r4 = r1 * 2; //错误:r4是一个普通的非常量引用,不能绑定到一个右值 当一个const引用绑定到另外一种类型上时,会发生什么?
先看看当一个const引用绑定到相同的类型时:
int i = 42; int &ri = i; //ri是一个普通引用,绑定到i const int &cri = i; //const int& 绑定到普通int对象 cout << cri << endl; ri = 0; //通过ri改变了i cout << cri << endl; 输出结果是:
42
0
这个方法可以在spring创建对象前后去自定义一些方法
举个栗子:
我想在helloworld对象创建之前输出一段话,创建之后输出一句话,那我该如何去配置呢?
声明一个后置处理类
public class InitHello implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("在init之前调用了该方法"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("在init方法之后调用了该方法"); return bean; } 在xml文件中去导入相应的处理类
<bean class="com.LL.sp1.InitHello"></bean> 输出即可
需要注意的是,spring会在每次创建对象时都去调用该方法,若配置文件中的scope="singleton",则不管去获取几次对象,它都只会输出一次,因为这是单例,并没有去新的创建一个对象。
HelloWord he = (HelloWord) context.getBean("helloWorld"); HelloWord h = (HelloWord) context.getBean("helloWorld"); 如果将scope设置为prototype,那么每次去获取对象时,都相当于去new一个新的对象,所以每次都会调用后置处理方法。
Coreldraw2022基本简介
Coreldraw2022是深受广大用户喜爱的专业矢量图设计软件,这款软件在继承一套完整的专业图形设计工具和功能同时,还新增了透视图、多页试图、图像调整、实时评论等全面的功能,能够很好用于商标设计、标志制作、模型绘制及分色输出等等诸多领域。
Coreldraw2022具有一体化设计和布局,同时还提供了矢量插图、页面布局、页面排版等多方面你意想不到的专业设计工具,让用户能够在这里随意编辑png、jpg、hiff、tiff、dwg等多种文件格式图像。
Coreldraw2022特色
1、新的透视图
以透视图的方式绘制对象或插图场景,比以往更快,更轻松。从1、2或3点透视图中进行选择,在共享透视图平面上绘制或添加现有对象组,并在不丢失透视图的情况下自由移动和编辑对象。
2、新的灵活的设计空间
借助新的工作流程,您可以在控制时间内从构思到输出,这使您可以控制页面和资产。
(1)多页视图
在一个视图中查看、管理和编辑项目的所有数字资产,这是一个全新的创意乐园!流畅地在页面间移动对象,并排比较设计,自由地移动页面以按照您的意愿排列它们。
(2)多资产导出
完成设计后,创建自定义的页面和对象项目列表,一键导出!
(3)符号工作流程增强
增强的“符号”工作流程可以让您在大型库中快速搜索符号,并在其他对象中更容易地识别符号,从而节省您的时间。
3、新的渐进式图像编辑
强大的新照片编辑功能可减轻您的工作负担,该功能专为以更少的步骤增强图像而设计。
(1)增强的颜色替换
试用令人印象深刻的全新替换颜色工具,以获得更快、更简单的完美照片。
(2)重新设想的调整工作流程
以 Corel PHOTO-PAINT 中完全转换的调整工作流程为例,在背景中非破坏性地实时应用关键图像调整
(3)HEIF 文件格式支持
享受对 iPhone 上使用的标准照片格式的支持
4、新的下一代合作
浪费的时间已经够多了!随着远程工作成为我们的新常态,与同事和客户保持联系。
(1)可以在共享的CorelDRAW设计文件中收集来自一个或多个贡献者的实时注释和注释。
(2)直观的新项目仪表板使存储,组织和共享云文件变得轻而易举。
(3)增强的评论泊坞窗简化了反馈过滤,并具有搜索审阅者评论的功能。
5、新的CorelDRAW无处不在
告别技术限制,打招呼,体验跨Windows,Mac,Web,iPad和其他移动设备的真正跨平台体验。凭借针对触摸优化的新用户体验,CorelDRAW.app扩展了移动设备和平板电脑上的功能,而新的iPad应用程序使旅途中的设计变得更加轻松。
6、颜色,填充和透明胶片
使用色板轻松将颜色应用于填充和轮廓,或基于颜色和声生成颜色。更改对象的透明度,并用图案,渐变,网格填充等填充对象。
7、无损编辑
知道您不会损害原始图像或对象的情况下,编辑位图和矢量。无损创建块阴影,对称图和透视图,并在CorelDRAW和Corel PHOTO-PAINT中应用许多可逆的调整和效果。
8、位图到矢量跟踪
令人印象深刻的AI辅助PowerTRACE?享受出色的位图到矢量跟踪结果。受益于高级图像优化选项,这些选项可帮助您在跟踪位图时提高其质量。
9、广泛的文件兼容性
由于支持大量的图形,发布和图像文件格式,因此可以根据客户提供的文件或需求轻松导入和导出各种项目资产。
Coreldraw2022功能
1、从业余爱好到家居办公,点燃您的设计激情
无论您是出于业余爱好还是一定的目的涉猎图形设计,软件都能为您提供为家庭项目或小型企业创作迷人图形所需要的一切
2.多合一设计和布局软件
能在一个应用程序中为您提供重要的图形设计和布局功能。
3.连接
完美无瑕的照片编辑功能,使用 Corel PHOTO-PAINT? Standard 中基于图层的强大照片编辑功能,提升图像效果。
4.完成
简单易用,无论您的技能水平如何或从事何种专业领域,直观的工具、提示和教程可以让您满怀信心地创建。
5、激发创意的工具
使用一套对用户友好的图形、布局、插图、描摹、照片编辑、网络图像和美术工具,创作出最棒的作品。
6、矢量插图
将基本的线条和形状变成复杂的艺术品。借助多种通用形状和绘图工具创建曲线。
7、页面布局
创建宣传册、多页文档等的布局。使用页面标尺、网格与辅助线,帮助您组织对象并将对象准确放置在需要之处。
8、照片编辑
使用 Corel PHOTO-PAINT? Standard 中基于图层的强大 照片编辑工具, 润饰并增强您的照片效果。调整颜色和色调,应用效果,消除瑕疵,等等。
说白了:分组的作用就是精准验证,解耦 Spring 中@Validated 分组校验使用 转载:Spring 中@Validated 分组校验使用_wangxuelei036的博客-CSDN博客_spring valid 分组
通过本文你能学习到@Validated 的基本使用,以及如何再spring-boot 中进行数据异常的统一处理
Spring Validation验证框架对参数的验证机制提供了@Validated(Spring’s JSR-303规范,是标准JSR-303的一个变种),javax提供了@Valid(标准JSR-303规范),配合BindingResult可以直接提供参数验证结果。
在检验入参是否符合规范时,使用@Validated或者@Valid在基本验证功能上没有太多区别。但是在分组、注解地方、嵌套验证等功能上两个有所不同,总体来说@validated 相当于 @Valid 验证的升级版,功能更加强大。
接下来我们直接看下如何使用
引入POM依赖
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
定义公共分组class(用于标记分组,可以像后面定义在Vo里面,但是建议一些常用的定义在外部),如下:
public interface Add {
}
public interface Edit {
}
定义接收数据的Vo
注意注解中分组的的使用,为了演示,同时在内部定义了一个特殊分组类
import com.example.jsr.commmon.Add;
import com.example.jsr.commmon.Edit;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.Pattern;
public class ParamsVo {
//特殊用于修改年龄 标记使用 灵活放置位置
public interface ModifyAge {
}
//年龄是1-120之间有效
public static final String AGE_REG = "/^(?:[1-9][0-9]?|1[01][0-9]|120)$/";
@NotBlank(
groups = {Edit.
原因: ElasticSearch 7.x 默认不在支持指定索引类型
在postman中用以下数据执行put请求:
{"mappings": {
"person" :{
"properties": {
"age": {
"type": "integer"
},
"hobby": {
"type": "text"
},
"mail": {
"type": "text"
},
"name": {
"type": "keyword"
}
}
}
}
}
报错:
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "Root mapping definition has unsupported parameters: [person : {properties={mail={type=text}, name={type=keyword}, age={type=integer}, hobby={type=text}}}]"
}
],
"type": "mapper_parsing_exception",
"reason": "Failed to parse mapping [_doc]: Root mapping definition has unsupported parameters: [person : {properties={mail={type=text}, name={type=keyword}, age={type=integer}, hobby={type=text}}}]"
Verdi基础知识整理_小小黑的博客-CSDN博客_verdi
原因:
安卓系统未打开adb网络调试功能
通过USB方式连接到安卓系统设置即可
解决方案:
通过USB线连接安卓机和电脑
确保安卓系统中的开发者选项打开,USB调试项也是是开启的
通过cmd打开命令行窗口界面,输入adb devices 能看到所连接的设备情况下
adb root 权限提权
adb shell 进入到安卓系统的shell
① setprop service.adb.tcp.port 5555 设置adb服务端口为5555, 打开adb网络调试功能
附加说明: setprop service.adb.tcp.port -1 表示打开adb的usb调试功能
② exit 退出android shell
adb tcpip 5555 让设备在 5555 端口监听 TCP/IP 连接
拔掉USB线
adb connect x.x.x.x:x连接即可
问题描述 为了解决前端异步函数多层嵌套会产生回调地狱问题,以及回调地狱错误不方便捕捉的问题。那些制造规则的大佬们,就在ES6中加入了一个新功能~Promise。
Promise.all接收的是数组,得到的结果也是数组,并且一一对应,也可以理解为Promise.all照顾跑的最慢的,最慢的跑完才结束。
Promise.race接收的也是数组,不过,得到的却是数组中跑的最快的那个,当最快的一跑完就立马结束。
Promise.all方法 Promise.all( ).then( )适用于处理多个异步任务,且所有的异步任务都得到结果时的情况。
比如:用户点击按钮,会弹出一个弹出对话框,对话框中有两部分数据呈现,这两部分数据分别是不同的后端接口获取的数据。
弹框弹出后的初始情况下,就让这个弹出框处于数据加载中的状态,当这两部分数据都从接口获取到的时候,才让这个数据加载中状态消失。让用户看到这两部分的数据。
那么此时,我们就需求这两个异步接口请求任务都完成的时候做处理,所以此时,使用Promise.all方法,就可以轻松的实现,我们来看一下代码写法
<template> <div class="box"> <el-button type="primary" :loading="loading" plain @click="clickFn">点开弹出框</el-button> </div> </template> <script> export default { name: "App", data () { return { loading:false, alertMask:false, } }, methods: { clickFn() { this.alertMask = true; // 打开弹出框 this.loading = true; // 暂时还没数据,所以就呈现loading加载中效果 // 第一个异步任务 function asyncOne() { let async1 = new Promise(async (resolve, reject) => { setTimeout(() => { // 这里我们用定时器模拟后端发请求的返回的结果,毕竟都是异步的 let apiData1 = "
ES(Evolutionary Strategy)
在20世纪60年代初,柏林工业大学的I. Rechenberg和H.-P. Schwefel等在进行风洞实验时,由于在设计中描述物体形状的参数难以用传统的方法进行优化,从而他们利用生物变异的思想来随机地改变参数值并获得了较好的结果。随后,他们便对这种方法进行了深入的研究和发展,形成了演化计算的另一个分支—演化策略。 关键理念:“演化的演化”
以个体的变异算子为主,重组算子为辅
认为变异强度是演化的关键,称为演化策略参数
将演化策略参数纳入演化本身,不断优化参数
演化策略的基本框架 个体表示:
(x1,x2,…,xn,σ1,σ2,…,σn),前面的x为一个个体n维,而后面的σ为此个体的各个维度变异强度。一个个体的强度可以相同
接下来介绍ES算法的主要部分——变异和生存选择:
ES算法的变异对于使用这个算法的人来说也是非常友好的,因为它也和EP一样直接给出了公式:
当μ个父代个体的都产生了子代,那么就会存在μ+μ个个体,如何从这μ+μ个个体中选出下一代呢?这个就是生存选择索要解决的事情,我们可以采用(μ+μ)随机q竞争选择,也可以简单排序择优选择。
当然ES相较于EP还多了一个重组,这里的重组对于变量部分是全局重组,要想重组出一个子代,那就要随机选取2倍维度数量的父代然后从每两个父代中诞生子代的每一维,至于怎么诞生,可以从两个父代的第随机个维随机选择一个。 策略部分的重组则是采用这两个父代的第随机个维的均值。当然重组这个模块对于演化策略似乎并不是太重要。
有了这些东西我们就可以编出相应的代码:
function [answer,best]=ESpro(fun) global popnum ubound lbound vs dim cost times best=inf; answer=zeros(times,cost/popnum); for i=1:times [X,D]=initpop(); for j=1:(cost/popnum) [newX,newD]=rcb(X,D); [newX,newD]=variant(newX,newD); [luck,fa]=selecsur(X,newX); x=[X;newX]; X=x(luck,:); d=[D;newD]; D=d(luck); last=keepbest(fa); answer(i,j)=last; if last<best best=last; end end end function [X,D]=initpop() X=unifrnd(lbound,ubound,popnum,dim); D=unifrnd(0,ubound,popnum,1); end function [newX,newD]=rcb(X,D) newX=zeros(popnum,dim); for i1=1:popnum for j1=1:dim select=randperm(popnum,2); %随机选出两个父代个体的下标 choose=X(select,:); %提取被选中的父代个体 newX(i1,j1)=choose(unidrnd(2),j1); %重被选中的父代个体中随机选择一个 end end newD=zeros(popnum,1); for i2=1:popnum select=randperm(length(D),2); choose=D(select); newD(i2)=mean(choose); end end function [newX,newD]=variant(X,D) newX=zeros(popnum,dim); newD=zeros(popnum,1); rho0=randn(); rho=randn(popnum,1); for i3=1:popnum newD(i3)=D(i3)*exp(sqrt(2*popnum)*rho0+sqrt(2*sqrt(popnum))*rho(i3)); if newD(i3)<vs newD(i3)=vs; end for j3=1:dim newX(i3,j3)=X(i3,j3)+newD(i3)*randn(); end end end function f=fit(X) f=zeros(length(X),1); for i4=1:length(X) f(i4)=fun(X(i4,:)); end end function [luck,fa]=selecsur(X,newX) X=[X;newX]; f=fit(X); [~,b]=sort(f); luck=b(1:length(b)/2); fa=f(luck); end end function best=keepbest(X) best=min(X); end 测试branin函数:
问题:
如果你使用CentOS 8,你可能已经注意到,从2022年1月31日开始,安装yum包不再工作与错误镜像列表中没有url,类似如下:
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist 如果你使用基于centos的Docker容器镜像,也会遇到同样的问题。
原因
在2022年1月31日,CentOS团队终于从官方镜像中移除CentOS 8的所有包。
CentOS 8已于2021年12月31日寿终正非,但软件包仍在官方镜像上保留了一段时间。现在他们被转移到https://vault.centos.org
解决方法
如果你仍然需要运行你的旧CentOS 8,你可以在/etc/yum.repos中更新repos.d使用vault.centos.org代替mirror.centos.org。
下面是两个简单的命令,都需要使用sudo来运行
# sudo sed -i -e "s|mirrorlist=|#mirrorlist=|g" /etc/yum.repos.d/CentOS-*
# sudo sed -i -e "s|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g" /etc/yum.repos.d/CentOS-*
本质上是用仍在运行的URL替换之前的URL。这一段时间内应该可以解决这个问题,但请记住,你将不会收到任何CentOS 8的更新。从长远来看,尝试升级到Stream版本。
IDEA 2021.3创建java web项目(最新版,很详细,手把手创建)
IntelliJ IDEA:官网下载地址
IntelliJ IDEA是一种商业化销售的Java集成开发环境(Integrated Development Environment,IDE)工具软件,由JetBrains软件公司(前称为IntelliJ)开发,提供Apache 2.0开放式授权的社区版本以及专有软件的商业版本,开发者可选择其所需来下载使用。
因为自身学习的时候第一次使用IDEA,初次创建javaweb项目的时候,发现现在很多的教程都已经是过去式的了,版本很老了,有些创建项目的方式已经不适用于现在,所以我收集整理一下,总结出一套完善详细的解决方式。
我使用的版本是:IDEA 2021.3
1、创建项目 File ---> New ---> Finish Next ---> Next ---> Project 项目创建成功
2、 导入依赖包 3、 创建两个文件夹分别是 classes 和 lib ,classes用来存放out文件(等等用得上),lib用来存放依赖包 4、 配置tomcat服务器 tomcat配置好后
5、配置artifacts 6、启动项目 第一次运行时间稍长一些
成功
一个java web 项目就这样创建并且启动成功了
短窗口的计算由于其窗口期较短,那么很快就能获取到结果,但是对于长窗口来说短窗口时间比较长,如果等窗口期结束才能看到结果,那么这份数据就不具备实时性,大多数情况我们希望能够看到一个长窗口的结果不断变动的情况,
对此Flink提供了ContinuousEventTimeTrigger连续事件时间触发器与ContinuousProcessingTimeTrigger连续处理时间触发器,指定一个固定时间间隔interval,不需要等到窗口结束才能获取结果,能够在固定的interval获取到窗口的中间结果。
ContinuousEventTimeTrigger 该类表示连续事件时间触发器,用在EventTime属性的任务流中,以事件时间的进度来推动定期触发。
<1> 其中的onElement方法:
@Override public TriggerResult onElement(Object element, long timestamp, W window, TriggerContext ctx) throws Exception { if (window.maxTimestamp() <= ctx.getCurrentWatermark()) { // if the watermark is already past the window fire immediately return TriggerResult.FIRE; } else { ctx.registerEventTimeTimer(window.maxTimestamp()); } ReducingState<Long> fireTimestamp = ctx.getPartitionedState(stateDesc); if (fireTimestamp.get() == null) { long start = timestamp - (timestamp % interval); long nextFireTimestamp = start + interval; ctx.registerEventTimeTimer(nextFireTimestamp); fireTimestamp.add(nextFireTimestamp); } return TriggerResult.
idea的VM options命令 -Xms 设置初始化内存(堆内存)分配大小,默认是电脑内存的1/64-Xmx 设置最大分配内存,默认是电脑内存的1/4-XX:+PrintGCDetails 打印GC垃圾回收信息-XX:+HeapDumpOnOutOfMemoryError oom dump信息 使用:-Xms1024m -Xmx1024m -XX:+heapDumpOnOutOfMemoryError -XX:MaxTenuringThreshold=5 通过这个参数可以设定进入老年代的时间,默认是15次。
在echarts中如果请求数据为空时候需要将echarts图进行清空,但是在正常情况下会发现echarts图并没有进行清空,其实setOption中还有第二个参数,如下:
//将数据中的第二个参数设置为true就能在请求不到数据的时候将echarts图进行清空 option && chart.setOption(option,true);
pod的内存yucpu使用查看方法:
kubectl top pod podName -n namespaceName
kubuctl修改当前命名空间
kubectl config set-context $(kubectl config current-context) --namespace=peiyou-xiaohoucode
事件相关
kubectl get events -A // 获取命名空间所有
kubectl describe deployment coding-judge-judge-test // 获取某个deployment的详情,包括事件
资源创建
kubectl create -f my-service.yaml -f my-rc.yaml #一次性创建service和rc
kubectl create -f <directory> #路径下所有的yaml yml json进行文件的创建
资源查看
kubectl get pods #查看所有pod列表
kubectl get service,rc
资源描述(详情)
kubectl describe nodes <node-name> #获取某规则资源的详情
kubectl describe pods/<pod-name> kubectl describe pods <rc-name>
删除资源
kubectl delete -f pod.yml #基于yaml的定义删除pod
1.新建文件:chtr+n 2.新开窗口:ctrl+shift+n 3.分屏:ctrl+1/2/3 4.关闭当前窗口:ctrl+w 5.关闭所有已保存窗口:ctrl+k+w 6.显示/隐藏左侧边栏:ctrl+b 7.文件重命名:鼠标选中+f2 8.自动换行:alt+z(标签过长需要拖动编辑器下方滚动条阅读时不太方便,可以一键换行) 9.注释:ctrl+/ 10.隐藏/显示终端:ctrl+~ 11.查找并打开文件:ctrl+p 12.选定当前单词: ctrl + d 13.如果想选中所有此单词:ctrl+shift+L 14.转到文件头部/尾部:ctrl+home/end 15. 快速复制一行 :shift+alt+ 下箭头(上箭头) 或者 ctrl+c 然后 ctrl+v 16. 添加多个光标 : ctrl + Alt + 上箭头(下箭头) 17.文件内容查找替换:ctrl+f ctrl+h ,替换一个ctrl+shift+1,替换所有ctrl+alt+enter 18. 快速定位到某一行 : ctrl + g 19. 选择某个区块: 按住shift + alt 然后拖动鼠标 20.放大缩小整个编辑器界面: ctrl + + / - ctrl + 加号或者减号 21.移动当前行,向上alt+up(方向键↑) 向下alt+down 22.在当前行上方插入一行:ctrl+shift+enter 23.选中光标到行首/行尾文本:shift+home/end 24.选中部分文字:shift+left/right/up/down 25.自定义快捷键 比如js 的多行注释是 shift + alt + a ,我们想修改为 ctrl + shfit + / 设置方法: 管理按钮 --- 键盘快捷方式 --- 输入 shift + alt + a 找到这个快捷键 ----- 点击编辑按钮 ---- 直接按下 ctrl + shift + / ---- 最后按下回车 修改完毕。
Javascript变量 一.变量
变量:变量是一个存放数据的容器
变量的声明:
//定义变量 var num ; //变量的赋值和初始化 var name = "你好呀" var name = "小明" var age = 18 var gender = "女" console.log(name,age,gender) 变量扩展:
更新变量:当变量被多次赋值时候,变量的值以最后一次赋值为准
声明多个变量:
var age = 18,name = "hahaha",gender = "男" 声明变量的特殊情况:
3.1只声明不赋值:
var gender; console.log(gender) //undefined 3.2不声明不赋值
//报错 3.3不声明直接赋值
//可以使用但是不建议使用
前端React实现pdf在线阅读和电子合同
文章目录 介绍1. 搭建页面思路1. 读取、展示合同内容 附录1. `jsPDF`实现1. 下载`pdf`文件2. 显示`pdf`文件 介绍 前段时间看到网上有个趋势,今后合同也开始变成无纸化,如果要签约,只需要在网上签名,不需要本人去现场。之前没有做过,决定试试看效果。
1. 搭建页面 因为是我自建的脚手架,所以暂时先搭建个骨架用来做测试页面的开发。
提供一个简单的搭建步骤:
npx create-react-app [name] --template typescript [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zEGRKtws-1644143802262)(./ReadMe.assets/image-20220206175120080.png)]
搭建好页面骨架后,我在前端周报上面翻了翻,找到了2个不错的库: js-pdf和react-pdf
jsPdf: 前端生成pdf文件。支持直接下载、转成data url。react-pdf: 实时展示pdf内容。支持打开文件和打开链接。 注意: 如果使用webpack5的话,不要使用国内的npm源,一定要用国外最新版本的,否则会出现dev-server崩溃栈溢出的问题。 思路 如果要实现pdf版本的合同,我个人分为4步:
读取、展示合同内容。制作合同。制作合同的同时,能实时看到内容。下载文件。 后期扩展:
5. 线上签名。
6. 盖章留戳。
1. 读取、展示合同内容 利用react-pdf的展示和读取功能,实现pdf文件的展示。首先,先不考虑文件的来源,我们以本地的测试pdf为准。
在开发页面引入react-pdf,下面是实现源码
import React, { useState } from 'react'; import { Document, Page } from 'react-pdf/dist/esm/entry.webpack'; // 引入样式,修复不对齐的问题 import 'react-pdf/dist/esm/Page/AnnotationLayer.css'; import sample from './test.pdf'; const PDFDisplay = () => { const [totalPages, setTotalPages] = useState<number>(0) const [pageNumber, setPageNumber] = useState<number>(1) const [file, setFile] = useState(sample) return ( <> <Card style = {{ margin: 8, }}> <Title level={3}> React-pdf 查看/显示 pdf内容 </Title> <div style = {{ margin: 8, }}> <div style = {{ margin: 6, display: 'flex', flexDirection: 'row-reverse', }}> <div className="
今天分享一个小问题,内容不多。
双y轴图表中,为了图表的美观,经常会隐藏一侧的y轴刻度线,仅显示一侧的刻度线。那么问题就来了,两个y轴的数据数值大小不同,常常会导致刻度线的刻度分布不均匀,该如何解决呢?
这里分享下我在项目中所作的处理:
首先是要找出当前y轴数据的最大值,与100相除,再对得到的商进行向上取整,最后把结果乘100。 有一点要注意,取整这里必须是向上取整(Math.ceil)。备注:Math.round是四舍五入取整,Math.floor是向下取整,使用这两个方法可能会导致数据显示不全 并且要注意极端情况:当得到的结果为0,也即是最大值小于100的时候,我们要把最终的结果设置成100。 简单代码如下:
let yData = [100,120,140,110,160,130]; let zData = [70,50,40,80,60,90,100]; function getSplitInterval(data){ let max = Math.ceil(Math.max(...data) / 100) * 100; if(max===0){max=100} return max } let ymax = getSplitInterval(yData) let zmax = getSplitInterval(zData) 当然,肯定会有同学产生疑问:为什么要与100进行运算?这个实际上是为了后面的刻度分隔提供便利,后面我是把刻度分成了5段,刚好可以被100整除。
也不一定是非要选择100,只要左后刻度均匀即可。
y轴属性设置如下:
yAxis:[ { ... min: 0, max: ymax, splitNumber: 5, minInterval:1, interval: ymax / 5, ... }, { ... min: 0, max: zmax, splitNumber: 5, minInterval:1, interval: zmax / 5, .
Python Selenium.WebDriver 清除输入框再输入『详解』 文章目录 Python Selenium.WebDriver 清除输入框再输入『详解』一、如何清除输入框中的默认内容二、WebDriverWait 的功能键实现三、退格大法好😍四、不靠谱的拖动鼠标🤐五、双击后替换😲六、全选后替换「推荐」七、自带清空元素的内容方法「推荐」八、总结参考资料💟相关博客😏 一、如何清除输入框中的默认内容 首先,要明确一点的是,Selenium是模拟人们去操作浏览器,它能操作的事大部分都是我们人们能够自己手动实现的事情。
知道这一点后,我们再想想平时浏览网页时遇到存在默认文本内容的输入框时,我们会怎么将其清除掉再输入呢?
慢慢敲退格键?虽然麻烦但也是一个方法;拖动并点击鼠标,将默认内容选中后再按退格键将其删除;双击默认文本内容,在选中后的情况下输入我们想要的内容将其替换掉;与双击有着同样原理的是使用ctrl + a 全选快捷键将其全部选中,这个会比双击能够更可靠地选中默认文本内容,再输入我们想要的内容将其替换掉;不断刷新网页,祈祷输入框中的默认文本内容不再出现,哈哈别逗了,这不太可能 二、WebDriverWait 的功能键实现 在上诉的实现方法,都离不开对键盘的操作,全选、回车这些都是需要在代码中去实现,那么如何使用Selenium实现这些操作呢,这就需要用到 Selenium WebDriver 的功能键API(接口)
使用下列导入语句将其导入
from selenium.webdriver.common.keys import Keys 其实源码实现原理很简单,我们来看看源码,只要明白了规则甚至连该模块都不用导入就能实现功能键的输入
class Keys(object): """ Set of special keys codes. """ NULL = '\ue000' CANCEL = '\ue001' # ^break HELP = '\ue002' BACKSPACE = '\ue003' BACK_SPACE = BACKSPACE TAB = '\ue004' CLEAR = '\ue005' RETURN = '\ue006' ENTER = '\ue007' SHIFT = '\ue008' LEFT_SHIFT = SHIFT CONTROL = '\ue009' LEFT_CONTROL = CONTROL ALT = '\ue00a' LEFT_ALT = ALT PAUSE = '\ue00b' ESCAPE = '\ue00c' SPACE = '\ue00d' PAGE_UP = '\ue00e' PAGE_DOWN = '\ue00f' END = '\ue010' HOME = '\ue011' LEFT = '\ue012' ARROW_LEFT = LEFT UP = '\ue013' ARROW_UP = UP RIGHT = '\ue014' ARROW_RIGHT = RIGHT DOWN = '\ue015' ARROW_DOWN = DOWN INSERT = '\ue016' DELETE = '\ue017' SEMICOLON = '\ue018' EQUALS = '\ue019' NUMPAD0 = '\ue01a' # number pad keys NUMPAD1 = '\ue01b' NUMPAD2 = '\ue01c' NUMPAD3 = '\ue01d' NUMPAD4 = '\ue01e' NUMPAD5 = '\ue01f' NUMPAD6 = '\ue020' NUMPAD7 = '\ue021' NUMPAD8 = '\ue022' NUMPAD9 = '\ue023' MULTIPLY = '\ue024' ADD = '\ue025' SEPARATOR = '\ue026' SUBTRACT = '\ue027' DECIMAL = '\ue028' DIVIDE = '\ue029' F1 = '\ue031' # function keys F2 = '\ue032' F3 = '\ue033' F4 = '\ue034' F5 = '\ue035' F6 = '\ue036' F7 = '\ue037' F8 = '\ue038' F9 = '\ue039' F10 = '\ue03a' F11 = '\ue03b' F12 = '\ue03c' META = '\ue03d' COMMAND = '\ue03d' 将源码中的常用的功能键总结整理成表格 键位中文释义Unicode码BACKSPACE / BACK_SPACE退格\ue003DELETE删除\ue017HOME开头\ue011END末尾\ue010ENTER回车\ue007CONTROL(CTRL)控制(CTRL)\ue009ALTALT\ue00aSPACE空格\ue00d 三、退格大法好😍 万能的退格,输入框里有都是内容那就退格多少次,这是一个比较容易想出的方法,相信也有不少人也是一直在使用这个方法
看到了这篇博客无人车系统(十):c++与python非线性规(优)划(化)工具
突然发现python也有mpc工具,所以干脆不用matlab了,直接使用python做mpc的轨迹跟踪。
pyomo的简单了解 pyomo的安装 在VSCode上面安装了半天,各种BUG,最后还是先安装了Ananconda,然后再安装pyomo
在Ubuntu20.04 + Anaconda环境下安装pyomo与ipopt:
conda update conda conda install -c conda-forge ipopt conda install -c conda-forge coincbc conda install -c conda-forge pyomo conda install -c conda-forge pyomo.extras Anaconda与ros结合使用 在调好Anaconda之后打开VSCode,使用roscore命令会报错:
Command 'roscore' not found, but can be installed with: sudo apt install python3-roslaunch 这个时候
source ./devel/setup.bash 一下就好了
而且发现也可以使用rosrun,Anaconda里面的包也都可以使用。
基本使用 官网:pyomo之后有空会翻译一下。
例子 尝试解决优化问题:
m i n i m i z e x 1 x 4 ( x 1 + x 2 + x 3 ) + x 3 s .
目录
ZK介绍和搭建
zk基础知识
znode-常用命令
znode-数据结构
zk中znode的结构:
zk中节点znode类型-持久节点和持久序号节点
临时节点用于服务发现原理图
ZK客户端Curator:
Curator介绍:
maven配置pom.xml文件
ZK持久化机制
快照数据
事务日志
数据相关过程
初始化
数据同步 小结:
ZK权限
权限设置:
ZK锁
zk锁的类型:
ZooKeeper分布式锁的原理
(一) ZooKeeper的每一个节点,都是一个天然的顺序发号器。
(二) ZooKeeper节点的递增有序性,可以确保锁的公平 (三)ZooKeeper的节点监听机制,可以保障占有锁的传递有序而且高效
(四)ZooKeeper的节点监听机制,能避免羊群效应
图解:分布式锁的抢占过程
客户端A发起一个加锁请求
客户端B过来排队
客户端B开启监听客户端A
客户端B抢锁成功
分布式锁的基本思路
curator代码
对比ZooKeeper分布式锁和redis锁:
ZK的watch机制
ZK集群
ZK集群搭建
创建myid文件
修改zoo.cfg文件
启动服务
客户端连接
ZK集群原理
ZK服务器节点(非znode)分为3种角色:
ZBA协议
选举leader过程:
选票数据格式:
选举流程简介:
选举规则:
运行过程中检测主节点宕机
选举流程代码解析
ZK中NIO和BIO应用:
ZK介绍和搭建 ZooKeeper 是一个典型的分布式数据一致性解决方案,分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。
Zookeeper 一个最常用的使用场景就是用于担任服务生产者和服务消费者的注册中心(提供发布订阅服务)。 服务生产者将自己提供的服务注册到Zookeeper中心,服务的消费者在进行服务调用的时候先到Zookeeper中查找服务,获取到服务生产者的详细信息之后,再去调用服务生产者的内容与数据。
ZK官网:
Welcome to The Apache Software Foundation!
点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达 仅作学术分享,不代表本公众号立场,侵权联系删除
转载于:https://zhuanlan.zhihu.com/p/51372134, 知乎ID:搬砖的旺财
1.自主机器人近距离操作运动规划体系
在研究自主运动规划问题之前,首先需建立相对较为完整的自主运动规划体系,再由该体系作为指导,对自主运动规划的各项具体问题进行深入研究。本节将根据自主机器人的思维方式、运动形式、任务行为等特点,建立与之相适应的自主运动规划体系。并按照机器人的数量与规模,将自主运动规划分为单个机器人的运动规划与多机器人协同运动规划两类规划体系。
1.1 单个自主机器人的规划体系 运动规划系统是自主控制系统中主控单元的核心部分,因此有必要先研究自主控制系统和其主控单元的体系结构问题。
自主控制技术研究至今,先后出现了多种体系结构形式,目前被广泛应用于实践的是分布式体系结构,其各个功能模块作为相对独立的单元参与整个体系。随着人工智能技术的不断发展,基于多Agent的分布式体系结构逐渐成为了主流,各功能模块作为独立的智能体参与整个自主控制过程,该体系结构应用的基本形式如图1所示。一方面,主控单元与测控介入处理、姿态控制系统、轨道控制系统、热控系统、能源系统、数传、有效载荷控制等功能子系统相互独立为智能体,由总线相连;另一方面,主控单元为整个系统提供整体规划,以及协调、管理各子系统Agent的行为。测控介入处理Agent保证地面系统对整个系统任意层面的控制介入能力,可接受上行的使命级任务、具体的飞行规划和底层的控制指令;各子系统Agent存储本分系统的各种知识和控制算法,自主完成主控单元发送的任务规划,并将执行和本身的健康等信息传回主控单元,作为主控单元Agent运行管理和调整计划的依据。
图1 基于多Agent的分布式自主控制系统体系结构基本形式示意图
主控单元Agent采用主流的分层递阶式结构,这种结构层次鲜明,并且十分利于实现,其基本结构如图2所示。主控单元由任务生成与调度、运动行为规划和控制指令生成三层基本结构组成,由任务生成与调度层获得基本的飞行任务,经过运动行为规划层获得具体的行为规划,再由控制指令生成层得到最终的模块控制指令,发送给其它功能Agent。各功能Agent发送状态信息给主控单元的状态检测系统,状态检测系统将任务执行情况和子系统状态反馈回任务生成与调度层,以便根据具体情况对任务进行规划调整。当遇到突发情况时,还可启用重规划模块,它可根据当时情况迅速做出反应快速生成行为规划,用以指导控制指令生成层得到紧急情况的控制指令。
此外,地面控制系统在三个层次上都分别具有介入能力。图2中,点划线内是主控单元全部模块,虚线内为运动规划系统,包括运动行为规划模块和重规划模块,这也是运动规划系统的主要功能。
图2 主控单元基本结构示意图
明确了自主控制系统与其主控单元的基本结构,以及运动规划系统在主控单元中的基本功能,便可建立运动规划系统的体系结构。运动规划系统的体系结构如图3所示,该系统由规划器和重规划器两大执行单元组成,分别承担对飞行任务的一般规划和对突发事件紧急处理的运动规划。当然,这两部分也可理解为离线规划与在线规划两种,离线规划一般解决平时按部就班的飞行任务,在线规划一般解决突然下达的飞行任务。除规划器以外,系统还配有知识域模块,用以利用特定语言描述相关知识。知识域包括行为域和模型域两个部分,行为域用来存储服务系统一般的运动行为描述和紧急情况下的一些运动行为方面的处理方法(如急停、转向等),模型域用来存储规划所需模型知识,包括环境模型、组装体模型、组装任务对象模型和任务模型等等。
图3 运动规划系统体系结构示意图
1.2 多自主机器人协同规划体系 多智能体系统的群体体系结构一般分为集中式、分散式两种基本结构,分散式结构又可以进一步分为分层式和分布式结构。集中式结构通常由一个主控单元掌握全部环境和受控机器人信息,运用规划算法对任务进行分解,并分配给各受控机器人,组织它们完成任务。其优点是理论条理清晰,实现较为直观;缺点是容错性、灵活性和对环境的适应性较差,与各受控机器人存在通讯瓶颈问题。相对于集中式结构,分散式结构无法得到全局最优解,但它凭借着可靠性、灵活性和较强的环境适应性越来越受到广泛的青睐。分散式结构中的分布式结构没有主控单元,各智能体地位平等,通过各智能体间的通讯和信息交流达到协商的目的,实现最终的决策,但该结构容易片面强调个体,导致占用资源过多,且难于得到磋商结果。分层式结构介乎于集中式和分布式之间,存在主控单元,但并不是由主控单元掌控一切,各智能体也具备一定的自主性,上下级之间按照一定的规则,通过信息流形成完整的整体,共同完成协同任务。
多自主机器人系统应采用分层式结构,以保证整个系统既适于统一领导,又满足系统灵活、快速的需求。多自主机器人协同规划体系结构如图4所示,按照分层式结构建立两种工作模式:事先的离线规划由主控单元负责,首先获得协同任务,经过规划器得到具体的行为运动规划,并分发给各分系统执行单元,相关的知识域中主要是用于描述各分系统协商规则的协商域,主控单元从外界获取环境信息,从各分系统获取状态信息;当遇到突发事件或紧急任务变更以及主控单元停止工作时,各分系统采用分布式结构,单独规划各自运动行为,并从各自的知识域中获取协商方式,外界环境信息由主控单元发送和自我感知相结合获得(主控单元停止工作时,仅靠自我感知获取信息),其它机器人信息的传输由机器人间的数据链实现。
图4 多自主机器人协同规划体系结构示意图
2.路径规划研究
当给定了某一特定的任务之后,如何规划机器人的运动方式将至关重要。机器人的规划包括两部分内容:基座移动到适合操作的位置和转动手臂关节完成操作。包括三个问题:基座点到点运动规划;关节空间规划;综合规划。
本章研究几种常用的运动规划算法:图搜索法、RRT算法、人工势场法、BUG算法。并对部分算法的自身缺陷进行了一些改进。
2.1 图搜索法 图搜索法依靠已知的环境地图以及地图中的障碍物信息构造从起点到终点的可行路径。主要分成深度优先和广度优先两个方向。深度优先算法优先扩展搜索深度大的节点,可以快速的得到一条可行路径,但是深度优先算法得到的第一条路径往往是较长的路径。广度优先算法优先扩展深度小的节点,呈波状的搜索方式。广度优先算法搜索到的第一条路径就是最短路径。
2.1.1 可视图法 可视图法由Lozano-Perez和Wesley于1979年提出,是机器人全局运动规划的经典算法。可视图法中,机器人用点来描述,障碍物用多边形描述。将起始点 、目标点 和多边形障碍物的各顶点(设 是所有障碍物的顶点构成的集合)进行组合连接,要求起始点和障碍物各顶点之间、目标点和障碍物各顶点之间以及各障碍物顶点与顶点之间的连线均不能穿越障碍物,即直线是“可视的”。给图中的边赋权值,构造可见图 。其中点集 , 为所有弧段即可见边的集合。然后釆用某种优化算法搜索从起始点 到目标点 的最优路径,那么根据累加和比较这些直线的距离就可以获得从起始点到目标点的最短路径。
图5 可视图
由此可见,利用可视图法规划避障路径主要在于构建可视图,而构建可视图的关键在于障碍物各顶点之间可见性的判断。判断时主要分为两种情况,同一障碍物各顶点之间可见性的判断以及不同障碍物之间顶点可见性的判断。
同一障碍物中,相邻顶点可见(通常不考虑凹多边形障碍物中不相邻顶点也有可能可见的情况),不相邻顶点不可见,权值赋为 。
不同障碍物之间顶点可见性的判断则转化为判断顶点连线是否会与其它顶点连线相交的几何问题。如下图虚线所示,、 分别是障碍物 、 的顶点,但 与 连线与障碍物其它顶点连线相交,故 、 之间不可见;而实线所示的 与 连线不与障碍物其它顶点连线相交,故 、 之间可见。
图6 顶点可见性判断
可视图法能求得最短路径,但搜索时间长,并且缺乏灵活性,即一旦机器人的起始点和目标点发生改变,就要重新构造可视图,比较麻烦。可视图法适用于多边形障碍物,对于圆形障碍物失效。切线图法和Voronoi图法对可视图法进行了改进。切线图法用障碍物的切线表示弧,因此是从起始点到目标点的最短路径的图,移动机器人必须几乎接近障碍物行走。其缺点是如果控制过程中产生位置误差,机器人碰撞障碍物的可能性会很高。Voronoi图法用尽可能远离障碍物和墙壁的路径表示弧。因此,从起始点到目标点的路径将会增长,但采用这种控制方式时,即使产生位置误差,移动机器人也不会碰到障碍物。
2.1.2 Dijkstra算法 Dijkstra算法由荷兰计算机科学家艾兹赫尔·戴克斯特拉(Edsger Wybe Dijkstra)发明,通过计算初始点到自由空间内任何一点的最短距离可以得到全局最优路径。算法从初始点开始计算周围4个或者8个点与初始点的距离,再将新计算距离的点作为计算点计算其周围点与初始点的距离,这样计算像波阵面一样在自由空间内传播,直到到达目标点。这样就可以计算得到机器人的最短路径。
Dijkstra算法是一种经典的广度优先的状态空间搜索算法,即算法会从初始点开始一层一层地搜索整个自由空间直到到达目标点。这样会大大增加计算时间和数据量。而且搜索得到的大量对于机器人运动是无用的。
废话少说! show me the fucking source code!
// 目录结构 . ├── config.sh └── main.sh 场景1: main脚本引用子脚本中的变量
# config.sh export NAME1="name1 in config"; NAME2="name2 in config"; # !/bin/bash # main.sh # 这样无法引用到config.sh中的变量 ./config.sh echo "name3 = ${NAME1}"; echo "name4 = ${NAME2}"; # 这样也无法引用到config.sh中的变量 sh ./config.sh echo "name3 = ${NAME1}"; echo "name4 = ${NAME2}"; # 这样就可以引用到config.sh中的变量 source ./config.sh echo "name3 = ${NAME1}"; echo "name4 = ${NAME2}"; # 通过分析./config.sh还是 sh config.sh作用是一样的,都是新开启了一个shell进行,去执行config.sh # 而接下来的echo语句是在主shell进程执行的。 # 可以通过 echo $$来打印当前shell执行的pid。 场景2: 子脚本引用主脚本中的变量
instance of package com.oop.demo06; public class Teacher extends Person{ } package com.oop.demo06; public class Person { public void run(){ System.out.println("run"); } } package com.oop.demo06; public class Studenr2 extends Person{ public void go(){ System.out.println("go"); } } /*测试 //Object>String //Object>Person>Teacher //Object>Person>Student2 //System.out.println(x instanceof y);判断x与y是否存在父子关系 左边类名级别决定能跟哪一级编译判断,不能和并列级判断 Object studenr1 = new Studenr2(); System.out.println(studenr1 instanceof Studenr2); System.out.println(studenr1 instanceof com.oop.demo06.Person); System.out.println(studenr1 instanceof Object);//true System.out.println(studenr1 instanceof com.oop.demo06.Teacher);//false System.out.println(studenr1 instanceof String); System.out.println("==============================================="); com.oop.demo06.Person person1 = new Studenr2(); System.
【Log】(一)Java 中的日志框架 JUL、Log4j
【Log】(二)Java 中的日志框架 JCL、SLF
【Log】(三)Java 中的日志框架 logback、log4j2
1. logback 学习 1.1 logback 介绍 logback 是由 log4j 创始人设计的另一个开源日志组件,性能比 log4j 好
logback 主要分为 3 个模块:
logback-core:其它两个模块的基础模块logback-classic:它是 log4j 的一个改良版本,同时它完整实现了 slf4j APIlogback-access:访问模块与 Servlet 容器集成提供通过 http 来访问日志的功能 1.2 快速入门 新建一个 Maven 工程,引入依赖,POM 文件:
<!--slf日志门面--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.26</version> </dependency> <!--logback--> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> 1. 入门案例:
public class LogbackTest { public static final Logger LOGGER = LoggerFactory.getLogger(LogbackTest.class); @Test public void testQuick() { LOGGER.
set与get函数参数介绍 config_db机制用于UVM验证平台之间的参数传递。set函数为寄信,get函数为收信,它们通常成对出现。比如:在某个用例的build_phase中使用如下方式寄信:
uvm_config_db#(int)::set(this,"env.agt.driver","para",10); set函数中,第一个参数和第二个参数组成目标路径,与此目标路径相同的目标才会成功收信。第一个参数必须是一个uvm_component实例的指针,第二个参数是相对此实例的路径。第三个参数表示一个记号,用于说明该值传给目标中的哪个成员,第四个参数是要设置的值。
在目标路径driver中的build_phase使用如下方式收信:
uvm_config_db#(int)::get(this,"","para",para_value); get函数中,第一个参数和第二个参数组成路径。第一个参数必须是一个uvm_component实例的指针,第二个参数是相对此实例的路径。通常,如果第一个参数设置为this,第二个参数可以是一个空的字符串。第三个参数为set函数中的第三个参数,这两个参数必须完全相同,第四个参数是要设置的变量。
set和get函数执行之后,para_value的值变为10。
需要特别注意的是:在寄信和收信时,寄信必须在收信之前完成,否则将会收信失败。换言之,可以只有set函数,但是当有get函数时必须有set函数,且必须在get函数之前执行完成。
大家好,本文以真实案为例手把手教你搭建电商系统的用户画像。
先来看该电商用户画像用到的标签。
数据内容包括user_id(用户身份)、item_id(商品)、IDbehavior_type(用户行为类型,包含点击、收藏、加购物车、支付四种行为,分别用数字1、2、3、4表示)、user_geohash(地理位置)、item_category(品类ID,即商品所属的品类)、Time(用户行为发生的时间),其中user_id和item_id因为涉及隐私,做了脱敏处理,显示的是数字编号。
下面是具体的代码实现过程。
导入库 本示例除了用到numpy、pandas、matplotlib,还用到其他一些模块。
# 导入所需的库 %matplotlib inline import numpy as np import pandas as pd from matplotlib import pyplot as plt from datetime import datetime 参数说明如下。
%matplotlib inline: 一个魔法函数,由于%matplotlib inline的存在,当输入plt.plot()后,不必再输入plt.show(),图像将自动显示出来。
datetime: 用来显示时间的模块。
数据准备 # 导入数据集 df_orginal = pd.read_csv('./taobao_persona.csv') # 抽取部分数据 df = df_orginal.sample(frac=0.2,random_state=None) 此处使用Pandas的read_csv方法读取数据文件,由于数据集太大,为了提高运行效率,使用sample函数随机抽取20%的数据。
DataFrame.sample()是Pandas中的函数,DataFrame是一种数据格式,代指df_orginal。frac(fraction)是抽取多少数据,random_state是随机数种子,目的是保证每次随机抽取的数据一样,防止执行命令时使用不一样的数据。
数据预处理 # 查看其中是否有缺失值,统计各字段缺失值 df.isnull().any().sum() # 发现只有user_geohash有缺失值,且缺失的比例很高,无统计分析的意义,将此列删 df.drop('user_geohash',axis=1,inplace=True) # 将time字段拆分为日期和时段 df['date'] = df['time'].str[0:10] df['time'] = df['time'].str[11:] df['time'] = df['time'].astype(int) # date用str方法取0-9位的字符,time取11位到最后一位,将time转化成int类型。 # 将时段分为'凌晨','上午','中午','下午','晚上' df['hour'] = pd.