public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int count = Integer.parseInt(br.readLine()); StringBuilder totalSB = new StringBuilder(); Runner runner = new Runner(totalSB, count); new Thread(runner, "A").start(); new Thread(runner, "B").start(); new Thread(runner, "C").start(); new Thread(runner, "D").start(); // 阻塞直到计数器减为0 while (Runner.count != 0) {} System.out.println(totalSB.toString()); } static class Runner implements Runnable { /** * 对象锁 */ private Object lock = new Object(); /** * 最终显示结果 */ private StringBuilder totalSB; /** * 全线程可见的索引位置 */ private volatile int index = 0; /** * 单词表 */ private final String[] words = {"
1.两数之和 题目来源:https://leetcode-cn.com/problems/two-sum/
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] 思路:建立一个字典存下,{target-n:序号}。然后遍历nums看每个n是否在字典中,在的话就返回n的序号与targrt-n的value。
class Solution(object): def twoSum(self, nums, target): """ :type nums: List[int] :type target: int :rtype: List[int] """ dic = {} for i,n in enumerate(nums): dic[target - n] = i for i,n in enumerate(nums): j = dic.get(n) if j is not None and i !
下载安装包 https://china.xilinx.com/support/download.html
解压 tar -zxvf XXXXX你下载文件的名称
运行xsetup 使用cd命令进入解压文件的目录下
找到xsetup文件
修改权限
chmod +x xsetup 生成安装配置文件 ./xsetup -b ConfigGen 记住这个地方的生成配置文件的位置
例如这个位置
/public/home/xqq/.Xilinx/install_config.txt 同时也可以对配置文件进行修改
nano /public/home/xqq/.Xilinx/install_config.txt 可以在里面对安装位置进行修改
运行安装程序 运行下面命令开始安装
./xsetup -a XilinxEULA,3rdPartyEULA,WebTalkTerms -b Install -c /public/home/xqq/.Xilinx/install_config.txt 等待安装完成
配置环境变量 nano ~/.bashrc #添加下面这行语句,注意更换为自己的安装目录 source /home/mynameis/Xilinx/Vivado/2018.3/settings64.sh #保存退出 source ~/.bashrc 启动vivado 直接输入下面指令启动
vivado
源文件下载 https://developer.nvidia.com/cuda-10.2-download-archive
可以在官网直接下载.run文件。
cudnn需要注册账号后下载。
安装 CUDA 修改运行权限 chmod +x cuda_10.2.89_440.33.01_linux.run #先将打开目录到安装文件所在目录 运行安装程序 ./cuda_10.2.89_440.33.01_linux.run 等待一会儿出现如下界面
输入 accept 回车
勾选对话框 只安装CUDA Toolkit 这里面在无root 与 sudo权限中 Driver 是不可安装的,没有权限
CUDA Samples 、CUDA Demo 、CUDA Documentation 可以选择安装,但需要修改相关的安装路径在用户自己的文件夹中,否则无写入权限。
修改安装路径 光标移动到Options 回车
这里我们需要修改Toolkit Options 、Library install path 这两项的路径。
修改Toolkit Options路径 光标移动到Toolkit Options 回车
这里我们回车修改安装路径,同时将下面的选项全部取消
我们这里是将原本安装在系统目录下的位置修改为我们用户自己的目录下
/usr/local/cuda-10.2 /public/home/xqq/cuda-10.2 这里如果使用的家里自己安装的Linux系统则无前面的/public 如果无发确认可以通过pwd命令查看文件路径
回车确认 出现如下界面
光标移动到Doen 回车
修改Library install path 路径 移动光标到Library install path 回车修改路径
在这里将空白路径修改为和上面Toolkit Options路径相同
回车 然后移动光标到Done 回车 路径修改完成
AXI-memory接口 转 AXI-stream 接口 AXI-memory接口介绍具体详情可以查看源码。 AXI-memory接口介绍 从图中我们可以看出memory接口有5个通道,分别是读地址通道,写地址通道,写响应通道,读数据通道,和写数据通道。
读写相互独立。
对于他们的时序为:master通过读地址通道,写地址通道下发写入和读取 数据 的地址 长度 和 ID号,写数据通道开始发送数据,此时应将写数据通道read信号拉高,待写入数据完毕后last信号会拉高一个时钟周期,随后我们应当通过写响应通道回复master写入数据已收到,完成此次写入数据操作。对于读取通道我们需要提取出读取命令中的长度和ID号,根据这两个信号来判断我们需要回复数据长度、ID号、以及last信号所在的位置。
这里我们应当注意的是:master端下发命令时并不是发一次命令等你执行完成后再发下一次指令,这里我们采用两种方法控制,一是单纯的使用ready信号来限制master的指令下发,但这样会导致较大的时间开销,从而会影响memory接口的传输速率;二是采用fifo来缓冲下发的指令,使用fifo的满信号来控制ready信号,这样可以平滑指令的扇出速率,降低对memory接口速率的影响。
最后就是将stream接口和memory接口中的读写数据通道进行对接完成接口转换。
具体详情可以查看源码。 axi-mm to axis.v
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>导出图片和数据到Excel</title> </head> <body> </body> <script> /* eslint-disable */ let idTmr; const getExplorer = () => { let explorer = window.navigator.userAgent; //ie if (explorer.indexOf("MSIE") >= 0) { return 'ie'; } //firefox else if (explorer.indexOf("Firefox") >= 0) { return 'Firefox'; } //Chrome else if (explorer.indexOf("Chrome") >= 0) { return 'Chrome'; } //Opera else if (explorer.indexOf("Opera") >= 0) { return 'Opera'; } //Safari else if (explorer.
squid正向代理(传统代理与透明代理)的配置、ACL访问控制与日志分析工具sarg的使用 一:squid代理服务概述二:传统代理的配置2.1:实验环境介绍2.2:实验步骤2.2.1:在squid服务器上安装squid服务2.2.2:优化执行路径2.2.3:更改权限2.2.4:修改配置文件、添加缓存用户与组2.2.5:检查配置文件的语法2.2.6:初始化缓存目录2.2.7:启动squid服务2.2.8:编写squid的启动脚本2.2.9:配置传统代理服务2.2.10:客户端配置2.2.11:在web服务器上安装http服务2.2.12:客户端访问web站点,查看web服务器的访问日志 三:透明代理的配置3.1:实验环境介绍3.2:实验拓扑3.3:实验步骤3.3.1:squid代理服务上增加一块网卡3.3.2:squid服务器开启路由转发功能3.3.4:透明代理配置3.3.5:设置防火墙规则3.3.6:客户端验证3.3.7:查看web站点的访问日志 四:ACL访问控制4.1:acl访问控制方式4.2:acl访问控制类型4.3:acl规则的优先级 五:日志分析工具sarg5.1:在squid服务器上部署sarg5.2:修改sarg的配置文件5.3:添加不计入站点文件,添加的域名将不被显示在排序中5.4:开启sarg5.5:安装、启动http5.6:查看sarg的统计日志5.7:执行周期性计划任务,每天生成报告 一:squid代理服务概述 Squid是一个高性能的代理缓存服务器,Squid支持FTP、gopher、HTTPS和HTTP协议。和一般的代理缓存软件不同,Squid用一个单独的、非模块化的、I/O驱动的进程来处理所有的客户端请求。
工作机制
Squid是一种用来缓冲Internet数据的软件。它是这样实现其功能的,接受来自人们需要下载的目标(object)的请求并适当地处理这些请求。也就是说,如果一个人想下载一web页面,他请求Squid为他取得这个页面。Squid随之连接到远程服务器(比如:www.163.com)并向这个页面发出请求。然后,Squid显式地聚集数据到客户端机器,而且同时复制一份。当下一次有人需要同一页面时,Squid可以简单地从磁盘中读到它,那样数据迅即就会传输到客户机上。正向代理的基本类型
传统代理:普通的代理服务,适用于Internet,需明确指定服务端
透明代理:客户机不需要指定代理服务器的地址和端口,是通过默认路由,防火墙将web重定向给代理使用代理的好处
提高web访问速度
隐藏客户机的真实IP地址 二:传统代理的配置 2.1:实验环境介绍 VMware软件
一台centos7虚拟机作为squid服务器,IP地址为:192.168.209.145
一台centos7虚拟机作为web服务器,IP地址为:192.168.209.146
一台win10虚拟机作为client测试机,IP地址为:192.168.209.128
2.2:实验步骤 2.2.1:在squid服务器上安装squid服务 [root@squid ~]# yum install gcc gcc-c++ -y [root@squid ~]# ls anaconda-ks.cfg initial-setup-ks.cfg squid-3.4.6.tar.gz 公共 模板 视频 图片 文档 下载 音乐 桌面 [root@squid ~]# tar zxvf squid-3.4.6.tar.gz [root@squid ~]# cd squid-3.4.6/ [root@squid squid-3.4.6]# ./configure \ > --prefix=/usr/local/squid \ //安装路径 > --sysconfdir=/etc \ //配置文件目录 > --enable-arp-acl \ //支持acl访问控制 > --enable-linux-netfilter \ //支持网络筛选 > --enable-linux-tproxy \ //支持透明代理 > --enable-async-io=100 \ //io优化 > --enable-err-language="
当创建一个 Router 实例,可以提供一个 scrollBehavior 方法:
注意: 这个功能只在 html5 history 模式下可用。 const router = new vueRouter({ routes: [...], scrollBehavior (to, from, savedPosition) { // return 期望滚动到哪个的位置 } }) scrollBehavior 方法接收 to 和 from 路由对象。第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。
scrollBehavior (to, from, savedPosition) { return { x: 0, y: 0 } } 对于所有路由导航,简单地让页面滚动到顶部。返回 savedPosition,在按下 后退/前进 按钮时,在滚动条位置,就会像浏览器的原生表现那样:
scrollBehavior (to, from, savedPosition) { if (savedPosition) { return savedPosition } else { return { x: 0, y: 0 } } } 模拟『滚动到锚点』的行为
设置typeAliasesPackage支持**通配符匹配 mybatis的typeAliasesPackage属性的作用是,搜索指定包别名。
配置了以后xml文件中的resultType和parameterType就不需要指定全类名com.example.system.domain.SysUser,我们只需要写SysUser,会到我们配置的typeAliasesPackage包下搜索。
转到MybatisProperties文件中,发现typeAliasesPackage是String类型。
@ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX) public class MybatisProperties { /** * Packages to search type aliases. (Package delimiters are ",; \t\n") */ private String typeAliasesPackage; 如果有多个包的话,只能以逗号分隔的形式赋值,如下:
mybatis: typeAliasesPackage: com.example.system.domain,com.example.common.domain 秉着“不想多敲一点代码”的做法,
我不想每次多一个包,就在typeAliasesPackage后面多加一个包名,
我想要的是可不可以配置一个通配符,就算加再多的包,也不用重新给typeAliasesPackage赋值。
mybatis: # 规则是,新加的包的名字必须是 com.example.xxx.domain typeAliasesPackage: com.example.**.domain 如果想要实现上述想法,我们需要自定义SqlSessionFactory,以代码的方式找到匹配com.example.**.domain的所有包名,然后赋值给typeAliasesPackage。
代码实现方式如下:
import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import javax.sql.DataSource; import org.apache.ibatis.io.VFS; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.
splice删除我们常见的是如下,我们要删除addr数组中,包含属性a为空的元素
for(let i=0;i<==arrd.length-1;i++){ if(addr[i].a==''){ addr.splice(i, 1) } } 但是这样是不能删除数组中所有a属性为空的数组的,因为splice会改变原数组,会导致i的变化,所以我们可以使i一直等于数组的长度-1
for(let i<=arrd.length-1;i>=0;i--){ if(addr[i].a==''){ addr.splice(i, 1) } }
这两天发现一个很奇怪的问题,DNS CLIENT服务的CPU一直在10%到20%之间,导致用电脑时过于卡顿。
尝试过
1、重启,无效
2、关闭DNS CLIENT,导致网站无法访问
3、使用IPCONFIG /FLUSHDNS 刷新DNS缓存,无解
4、将HOST文件清空,无效
5、重置WINSOCK,未尝试
最终解决的方法很简单,将无线和有线只使用一种,将无线连接关闭后马上恢复正常。
原因暂时无法解释,供大家参考。
如何看待向量之间的叉乘和点乘
首先明显的区别在于:两个向量点乘的结果是一个标量,而两个向量叉乘的结果则还是一个向量。如下面的例子:
点乘:
向量a = (a1, a2, a3), 是一个1行3列的向量。向量b=(b1, 是一个3行1列的向量。两者点乘的结果为 a1b1+a2b2+a3b3(若我们这里
b2,
b3)
将a1,a2,a3,b1,b2,b3全部赋值为1,那么向量a 点乘 向量b = 1 + 1 + 1 = 3,是一个标量)
叉乘:
向量a = (a1, a2, a3), 是一个1行3列的向量。向量b=(b1, b2, b3)同样是一个1行3列的向量。两者叉乘的结果如下:
向量a 叉乘 向量b = 解上面的行列式可以得到:向量a 叉乘 向量b = (a2*b3-a3*b2)i + (a3*b1-a1*b3)j + (a1*b2 - a2*b1)k,这里的i = (1,0,0),j=(0,1,0), k=(0,0,1), 所以最后向量a 叉乘 向量b = (a2*b3-a3*b2,a3*b1-a1*b3,a1*b2 - a2*b1),是一个向量。
·
·
·
·
·
·
·
·
·
·
↓↓↓↓↓↓↓↓↓
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
你愿意吗?
点击下方海报,1块做好事!!!
↓↓↓↓↓↓↓↓↓
1:close现在的工程
2:重新import工程
欢迎加入技术讨论群,无广告,纯技术,欢迎各位大佬,也欢迎新手,群内禁止歧视新手,大佬自愿回答问题。
前言 本文介绍如何在ubuntu上部署k8s集群,大致可以分为如下几个步骤:
修改ubuntu配置安装docker安装kubeadm、kubectl以及kubelet初始化master节点将slave节点加入网络 如果你对上面的某些名字感到陌生,没关系,下文会一一进行讲解,如果你想先了解一下 docker 和 k8s,可以参考 10分钟看懂Docker和K8S。好了,在正式开始之前,首先看一下我们都有哪些服务器,如果你对如何组建如下虚拟机网络感兴趣的话,可以参考 virtualbox 虚拟机组网:
主机名主机ip版本CPU内存master1192.168.56.11Ubuntu server 18.042核1Gworker1192.168.56.21Ubuntu server 18.042核1G 因为k8s分为管理节点和工作节点,所以我们将要 在master1上部署管理节点,在worker1上部署工作节点。如果想了解如何创建这两个节点,可以参考 virtualbox 虚拟机组网 。服务器配置上,k8s 要求 CPU 最低为 2 核,不然在安装过程中会报错,虽然这个错误可以避免,但是为了稳定起见还是把虚拟机的配置成它想要的,至于内存 k8s 没有硬性要求,所以我就按我电脑的性能来分配了。
注意,本文的 docker、k8s 等软件安装均未指定具体版本,在本文完成时2019/6/27,下载到的版本如下,如有特殊版本需要请自行指定版本。
软件名版本docker18.09.5kubectl1.15.0-00 amd64kubeadm1.15.0-00 amd64kubelet1.15.0-00 amd64 一. 修改 ubuntu 配置 首先,k8s 要求我们的 ubuntu 进行一些符合它要求的配置。很简单,包括以下两步:关闭 Swap 内存 以及 配置免密登录,这一步两台主机都需要进行配置。
关闭 swap 内存 这个swap其实可以类比成 windows 上的虚拟内存,它可以让服务器在内存吃满的情况下可以保持低效运行,而不是直接卡死。但是 k8s 的较新版本都要求关闭swap。所以咱们直接动手,修改/etc/fstab文件:
sudo vi /etc/fstab 你应该可以看到如下内容,把第二条用#注释掉就好了,注意第一条别注释了,不然重启之后系统有可能会报file system read-only错误。
UUID=e2048966-750b-4795-a9a2-7b477d6681bf / ext4 errors=remount-ro 0 1 # /dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0 然后输入reboot重启即可,重启后使用top命令查看任务管理器,如果看到如下KiB Swap后均为 0 就说明关闭成功了。
文章目录 正则表达式名词解释工具场景示例 元字符定义分类基本正则表达式元字符扩展正则表达式元字符 grep目的分类grepegrepfgrep 返回值参数示例 sed格式返回值sed和正则表达式汇总示例删除命令: d替换命令: s读文件命令:r写文件命令:w(另存为)追加命令: a(之后)插入命令: i(之前)替换整行命令: c获取下一行命令:n多重编辑 e实战案例 awk1.前言2.工作原理3.语法内部变量① FS② OFS③ RS④ ORS⑤ FNR ,NR⑥ NF 格式化输出① print 函数② printf 函数 模式(正则表达)和动作① 字符串比较② 数值比较 awk脚本编程变量条件判断循环数组awk编程案例 正则表达式 名词解释 正则表达式(regular expression, RE)是一种字符模式, 用于在查找过程中匹配指定的字符。 在大多数程序里,正则表达式都被置于两个正斜杠之间; 例如/l[oO]ve/就是由正斜杠界定的正则表达式, 它将匹配被查找的行中任何位置出现的相同模式。 在正则表达式中,元字符是最重要的概念。 工具 被vim、sed、awk、grep调用 场景 mysql、oracle、php、python ,Apache,Nginx... 需要正则 示例 需求 匹配数字的脚本:用户输入创建账号的数量 语法 [[ ^[0-9]+$ ]] 示范 read -p "输入数字才退出: " num while : do if [[ ! $num =~ ^[0-9]+$ ]];then echo "
一、历史对比 关于QCPLayoutElement这个元素的讲解之前,我想先对1.3.2release版本和2.0.0beta版本的该元素做以简单的对比介绍,首先,1.3.2release版本时,鼠标单击时,如果按下的位置是一个布局元素,那么QCustomPlot首先会把这个事件回调给该被点击的元素,并且mouse系列的方法都是这样传递给QCPLayoutElement对象,该布局元素的声明会像这样QPointer<QCPLayoutElement> mMouseEventElement;但是到了2.0.0beta版本时,QCustomPlot源码做出了很大的调整,不仅仅是QCPLayoutElement布局元素可以接收鼠标事件,凡事继承自QCPLayerable类的元素都可以支持鼠标事件,因为mouse一系列的方法被移到了QCPLayerable类中。下面我分别贴出这两个版本时的mousePressEvent处理方法
1.3.2release版本鼠标按下处理方式
1 void QCustomPlot::mousePressEvent(QMouseEvent *event) 2 { 3 emit mousePress(event); 4 mMousePressPos = event->pos(); // need this to determine in releaseEvent whether it was a click (no position change between press and release) 5 6 // call event of affected layout element: 7 mMouseEventElement = layoutElementAt(event->pos());//后去当前选中布局元素 并调用其相关接口 8 if (mMouseEventElement) 9 mMouseEventElement->mousePressEvent(event); 10 11 QWidget::mousePressEvent(event); 12 } 2.0.0beta版本鼠标按下处理方式
1 void QCustomPlot::mousePressEvent(QMouseEvent *event) 2 { 3 emit mousePress(event); 4 // save some state to tell in releaseEvent whether it was a click: 5 mMouseHasMoved = false; 6 mMousePressPos = event->pos(); 7 8 if (mSelectionRect && mSelectionRectMode !
3个等于表示数据类型和数值都相同。
1.===:三个等号我们称为等同符,当等号两边的值为相同类型的时候,直接比较等号两边的值,值相同则返回true,若等号两边的值类型不同时直接返回false。
例:100===“100” //返回false abc===“abc” //返回false ‘abc’===“abc” //返回true NaN===NaN //返回false false===false //返回true 2.==:两个等号我们称为等值符,当等号两边的值为相同类型时比较值是否相同,类型不同时会发生类型的自动转换,转换为相同的类型后再作比较。
类型转换规则:1)如果等号两边是boolean、string、number三者中任意两者进行比较时,优先转换为数字进行比较。 2)如果等号两边出现了null或undefined,null和undefined除了和自己相等,就彼此相等 例:100==“100” //返回true 1==true //返回true “1”==“01” //返回false,此处等号两边值得类型相同,不要再转换类型了!! NaN==NaN //返回false,NaN和所有值包括自己都不相等。
同一个类中BookService: buyBook方法(a)updatePrice方法(b)两个方法是否报错现象transactional不加注解a报错 b不报错a,b事务回滚transactional不加注解b报错 a不报错a,b事务回滚不加注解transactionala报错 b不报错 a,b事务都不回滚不加注解transactionalb报错 a不报错a,b事务都不回滚 两个类BookService MultService两个类:
buyBook方法(a)updatePrice方法(b)两个方法是否报错现象transactional不加注解a报错 b不报错a,b事务回滚transactional不加注解b报错 a不报错a,b事务回滚不加注解transactionala报错 b不报错 a,b事务都不回滚不加注解transactionalb报错 a不报错 a不回滚,b回滚
导读 本文主要分为四个部分:
用pandas处理时序数据
怎样检查时序数据的稳定性
怎样让时序数据具有稳定性
时序数据的预测
用pandas导入和处理时序数据 第一步:导入常用的库
import pandas as pd import numpy as np import matplotlib.pylab as plt from matplotlib.pylab import rcParams #rcParams设定好画布的大小 rcParams['figure.figsize'] = 15, 6 第二步:导入时序数据
数据文件可在github:
http://github.com/aarshayj/Analytics_Vidhya/tree/master/Articles/Time_Series_Analysis 中下载
#导入数据 data = pd.read_csv("../testdata/AirPassengers.csv") print (data.head()) print ('\n Data types:') print (data.dtypes) 运行结果如下:数据包括每个月对应的passenger的数目。
可以看到data已经是一个DataFrame,包含两列Month和#Passengers,其中Month的类型是object,而index是0,1,2…
第三步:处理时序数据
我们需要将Month的类型变为datetime,同时作为index。
#处理时序数据 #我们需要将Month的类型变为datetime,同时作为index dateparse = lambda dates: pd.datetime.strptime(dates, '%Y-%m') #---其中parse_dates 表明选择数据中的哪个column作为date-time信息, #---index_col 告诉pandas以哪个column作为 index #--- date_parser 使用一个function(本文用lambda表达式代替),使一个string转换为一个datetime变量 data = pd.read_csv('../testdata/AirPassengers.csv', parse_dates=['Month'], index_col='Month',date_parser=dateparse) print (data.
【Maven】 IDEA中Maven生命周期 IDEA工具Maven projects里面有9种生命周期,今天刚好遇到,顺便分享下自己的理解。
Maven生命周期(lifecycle)由各个阶段组成,每个阶段由Maven的插件plugin来执行完成。
生命周期(lifecycle)主要包括clean、resources、complie、install、pacakge、testResources、testCompile、deploy等,其中带test开头的都是用业编译测试代码或运行单元测试用例的。
最常用的两种打包方法:
(1)clean,package(如果报错,很可能就是jar依赖的问题)
(2)clean,install
9种生命周期:
1 clean 清理,在进行真正的构建之前进行一些清理工作,移除所有上一次构建生成的文件。执行该命令会删除项目路径下的target文件,但是不会删除本地的maven仓库已经生成的jar文件。
2 valitate 验证,验证工程是否正确,所需的信息是否完整。
3 compile 编译源码,编译生成class文件,编译命令,只编译选定的目标,不管之前是否已经编译过,会在你的项目路径下生成一个target目录,在该目录中包含一个classes文件夹,里面全是生成的class文件及字节码文件。
4 test 单元测试,测试。
5 package 打包,将工程文件打包为指定的格式,例如JAR,WAR等。这个命令会在你的项目路径下一个target目录,并且拥有compile命令的功能进行编译,同时会在target目录下生成项目的jar/war文件。如果a项目依赖于b项目,打包b项目时,只会打包到b项目下target下,编译a项目时就会报错,因为找不到所依赖的b项目,说明a项目在本地仓库是没有找到它所依赖的b项目,这时就用到install命令了。
6 verify 核实,检查package是否有效、符合标准。
7 install 安装至本地仓库,将包安装至本地仓库,以让其它项目依赖。该命令包含了package命令功能,不但会在项目路径下生成class文件和jar包,同时会在你的本地maven仓库生成jar文件,供其他项目使用(如果没有设置过maven本地仓库,一般在用户/.m2目录下。如果a项目依赖于b项目,那么install b项目时,会在本地仓库同时生成pom文件和jar文件,解决了上面打包package出错的问题)
8 build 功能类似compile,只是只对整个项目进行编译。
9 site 站点,生成项目的站点文档。
10 deploy 复制到远程仓库。
build和compile的区别 Compile:只编译选定的目标,不管之前是否已经编译过。
Build:是对整个工程进行彻底的重新编译,而不管是否已经编译过。Build过程往往会生成发布包,这个具体要看对IDE的配置了,Build在实际中应用很少,因为开发时候基本上不用,发布生产时候一般都用ANT等工具来发布。Build因为要全部编译,还要执行打包等额外工 作,因此时间较长。
package、install和deploy的区别 package命令完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库。
install命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库,但没有布署到远程maven私服仓库。
deploy命令完成了项目编译、单元测试、打包功能,同时把打好的可执行jar包(war包或其它形式的包)布署到本地maven仓库和远程maven私服仓库。
1.需求概要
可视化界面显示气象云图及台风中心运动变化,实时数据显示;
2.效果预览
方案实施
1.>图层构成分析:
可视范围内构成的应该包含基础图层和动态移动图层,运动线路,运动风标,及运动信息框;
2.>结构拆分:
//:基于单图层创建多个根据风力大小为半径的风面圆图层;
数据组装:
/** * @Description:圆心处理 * @Author: ShiWei * @Date: 2020-09-07 */ makeWindGeo(fea,i) { const cen = turf.point(fea[i].geometry.coordinates) // 圆形展示 return turf.sector(cen, fea[i].properties.r10, 0, 360) }, if( winData.length!==0){ let dataObj=winData.data; let r7=Math.floor(Math.random() * 200 + 20); let r10= Math.floor(Math.random() * 300 + 50); dataObj.map((item,index) =>{ let properties={wl:parseFloat(item.mws),r10:r10,r7:r7,startTime:item.startTime, endTime:item.endTime, centerPres:item.centerPres, mws:item.mws, mwsMax:item.mws}; let point=[]; //单点信息 point.push(parseFloat(item.lon),parseFloat(item.lat)) stp.push(this.mapController.makeFeature("Point",point,properties)) features.push(this.makeWindGeo(stp,index)) }) let source = this.mapController.makeFeatureCollection(features) this.
vue props 属性值接受多个类型 直接上代码:
props: { someData: { type: Array | Object, default () { return [] } }, ... } 如果我们自己写不限制类型的props,可以使用数组的形式
props:['someData'] 但是有时我们做已经搭好的框架,
里面组件比较成熟都能直接用,
但是发现别人写的组件里限制了类型,
这时候我们由于业务需求想扩展组件功能增加一些类型,
这时我们就需要用到第一种方法了
希望这篇帖子能帮到你!
时间序列预测之–ARIMA模型 什么是 ARIMA模型
ARIMA模型的全称叫做自回归移动平均模型,全称是(ARIMA, Autoregressive Integrated Moving Average Model)。也记作ARIMA(p,d,q),是统计模型(statistic model)中最常见的一种用来进行时间序列 预测的模型。
1. ARIMA的优缺点
优点: 模型十分简单,只需要内生变量而不需要借助其他外生变量。
缺点:
1.要求时序数据是稳定的(stationary),或者是通过差分化(differencing)后是稳定的。
2.本质上只能捕捉线性关系,而不能捕捉非线性关系。
注意,采用ARIMA模型预测时序数据,必须是稳定的,如果不稳定的数据,是无法捕捉到规律的。比如股票数据用ARIMA无法预测的原因就是股票数据是非稳定的,常常受政策和新闻的影响而波动。
2. 判断是时序数据是稳定的方法。
严谨的定义: 一个时间序列的随机变量是稳定的,当且仅当它的所有统计特征都是独立于时间的(是关于时间的常量)。
判断的方法:
稳定的数据是没有趋势(trend),没有周期性(seasonality)的; 即它的均值,在时间轴上拥有常量的振幅,并且它的方差,在时间轴上是趋于同一个稳定的值的。
可以使用Dickey-Fuller Test进行假设检验。(另起文章介绍)
3. ARIMA的参数与数学形式
ARIMA模型有三个参数:p,d,q。
p–代表预测模型中采用的时序数据本身的滞后数(lags) ,也叫做AR/Auto-Regressive项
d–代表时序数据需要进行几阶差分化,才是稳定的,也叫Integrated项。
q–代表预测模型中采用的预测误差的滞后数(lags),也叫做MA/Moving Average项
先解释一下差分: 假设y表示t时刻的Y的差分。
if d=0, yt=Ytif d=1, yt=Yt−Yt−1if d=2, yt=(Yt−Yt−1)−(Yt−1−Yt−2)=Yt−2Yt−1+Yt−2 ARIMA的预测模型可以表示为:
Y的预测值 = 常量c and/or 一个或多个最近时间的Y的加权和 and/or 一个或多个最近时间的预测误差。
假设p,q,d已知,
ARIMA用数学形式表示为:
ytˆ=μ+ϕ1∗yt−1+...+ϕp∗yt−p+θ1∗et−1+...+θq∗et−q 其中,ϕ表示AR的系数,θ表示MA的系数
4.ARIMA模型的几个特例
1.ARIMA(0,1,0) = random walk:
当d=1,p和q为0时,叫做random walk,如图所示,每一个时刻的位置,只与上一时刻的位置有关。
file-list
预测公式如下:
Yˆt=μ+Yt−1
2. ARIMA(1,0,0) = first-order autoregressive model:
加密函数 create or replace function
encrypt_des(p_text varchar2, p_key varchar2) return varchar2 is
v_text varchar2(4000);
v_enc varchar2(4000);
raw_input RAW(128) ;
key_input RAW(128) ;
decrypted_raw RAW(2048);
begin
v_text := rpad( p_text, (trunc(length(p_text)/8)+1)*8, chr(0));
raw_input := UTL_RAW.CAST_TO_RAW(v_text);
key_input := UTL_RAW.CAST_TO_RAW(p_key);
dbms_obfuscation_toolkit.DESEncrypt(input => raw_input,key => key_input,encrypted_data =>decrypted_raw);
v_enc := rawtohex(decrypted_raw);
dbms_output.put_line(v_enc);
return v_enc;
end;
解密函数 create or replace function decrypt_des(p_text varchar2,p_key varchar2) return varchar2 is
v_text varchar2(2000);
begin
dbms_obfuscation_toolkit.DESDECRYPT(input_string => UTL_RAW.CAST_TO_varchar2(p_text),key_string =>p_key, decrypted_string=> v_text);
RC.exe 此程序为windows sdk中将 .rc 资源文件打包为 .res 文件的系统工具一篇1999年的介绍该工具使用方法的文章注意RC.exe 程序依赖于rcdll.dll和部分系统库,单独拷贝使用时需要 rcdll.dll重点:形如如下格式的rc文件: STRINGTABLE LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED { 103, "hello" 104, "world" } 如果直接执行命令 (/r 以及 /fo 的含义可以使用 rc.exe /? 来获取参数列表的含义 或者参见官方文档 using-rc-the-rc-command-line-) rc.exe /r /fo testA.res .\testA.rc 将会出现报错: Microsoft (R) Windows (R) Resource Compiler Version 10.0.10011.16384 Copyright (C) Microsoft Corporation. All rights reserved. .\testA.rc(2) : error RC2144 : PRIMARY LANGUAGE ID not a number .\testA.rc(2) : error RC2105 : BEGIN expected in string table 出现error原因 testA.
mysql集群MHA高可用配置详解 一:mysql概述1.1:什么是MHA1.2:MHA的组成1.3:MHA特点1.4:MHA的由来 二:MHA配置2.1:实验环境介绍2.2:实验架构图2.3:实验目的2.4:实验步骤2.4.1:所有节点上安装环境包和node组件2.4.2:配置所有节点之间的无密码认证2.4.3:MHA的配置2.4.4:故障模拟 2.5:实验验证 一:mysql概述 1.1:什么是MHA 日本DeNA公司 youshimaton(现就职于 Facebook公司)开发一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件支持故障切换在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用MHA还提供在线主库切换的功能,能够安全地切换当前运行的主库到一个新的主库中(通过将从库提升为主库),大概0.5-2秒内即可完成 1.2:MHA的组成 MHA Manager(管理节点)
用来接收外部信号,监控下方数据节点的工作状态MHA Node(数据节点)
工作的单位,负责具体的工作 1.3:MHA特点 自动故障切换过程中,MHA试图从宕机的主服务器上保持二进制日志,最大程度的保证数据不丢失使用半同步复制,可以大大降低数据丢失的风险目前MHA支持一主多从架构,至少三台服务器,即一主两从 1.4:MHA的由来 传统的mysql主从架构存在的问题
单点故障 master只有一台,所以当出现单点故障的时候,整个服务器群集就会瘫痪掉
为了解决这种情况,我们需要在主服务器宕机的时候,重新建立一台主服务器,负责监控等工作
二:MHA配置 2.1:实验环境介绍 VMware软件
一台centos7作为MHA
三台centos7作为mysql服务器
搭建好mysql主从复制环境(主从复制参见之前的博客)
2.2:实验架构图 2.3:实验目的 通过MHA监控MySQL数据库,在故障时自动进行切换,不影响业务
当主库失效时,备选主库自动成为主库
2.4:实验步骤 2.4.1:所有节点上安装环境包和node组件 安装环境包,以manager为例 [root@mha ~]# yum install epel-release --nogpgcheck -y [root@mha ~]# yum install -y perl-DBD-MySQL \ perl-Config-Tiny \ perl-Log-Dispatch \ perl-Parallel-ForkManager \ perl-ExtUtils-CBuilder \ perl-ExtUtils-MakeMaker \ perl-CPAN 安装node组件,以salve为例 [root@slave01 ~]# ls anaconda-ks.cfg 公共 视频 文档 音乐 initial-setup-ks.
1)coalesce
def coalesce(numPartitions: Int, shuffle: Boolean = false)(implicit ord: Ordering[T] = null): RDD[T]
该函数用于将RDD进行重分区,使用HashPartitioner。
第一个参数为重分区的数目,第二个为是否进行shuffle,默认为false;
作用
缩减分区数,用于大数据集过滤后,提高小数据集的执行效率。
val ListRDD: RDD[Int] = context.makeRDD(Range(1, 15, 2), 4) println("缩减分区前: ") ListRDD.glom.collect.foreach(data => println(data.mkString(","))) val coalesceRDD: RDD[Int] = ListRDD.coalesce(3) println("缩减分区后: ") coalesceRDD.glom.collect.foreach(data => println(data.mkString(","))) 输出:
缩减分区前:
1
3,5
7,9
11,13
缩减分区后:
1
3,5
7,9,11,13
将coalesce参数设置为2:
缩减分区前:
1
3,5
7,9
11,13
缩减分区后:
1,3,5
7,9,11,13
coalesce进行收缩合并分区,减少分区的个数,并没有shuffle操作,但这块也有隐患,数据倾斜是一个问题.
repartition
def repartition(numPartitions: Int)(implicit ord: Ordering[T] = null): RDD[T] = withScope {
今年走访了一些行业内的客户,总结了一些常见的问题:
很多运营商都想开发一套属于自己的部标主动安全平台,部标协议推出至今十年了,协议类型加地市级扩展的有JT808-2011、JT808-2013、JT1078、主动安全、JT808-2019、JT809,从零开发都是一场噩梦。投入的资金人力很大,开发周期长,还需要有对终端协议和行业需求特别熟悉的人才。今年疫情特殊,很多企业在缩减开支,不敢盲目投入太多资金。系统架构要成熟稳定。网上开源的代码只是demo离商用还有很大差距,或者代码质量差架构落后导致学习成本高。平台厂商的系统授权昂贵而且只开放web部分接口,底层的数据不能自由获取和定制。或者以免费的名义获取客户的数据。 针对以上问题,我们将这几年研发的主动安全云平台的所有后台模块免费开放给全国客户,无须授权,web后台代码和平台公共包开源,底层终端数据自由获取和处理。客户只需要将精力放在开发web界面和web后台,可以降低成本和开发周期。
为了兼容不同客户的服务器,部署包分Windows和Linux两种版本,两种版本都实现了一键启停服务,客户可根据自己的需求下载并按照手册部署。
协议支持 网关协议:JT808-2011、JT808-2013、JT808-2019、JT1078、苏标主动安全 流媒体播放协议:websocket-flv、http-flv 模块介绍 模块开发语言跨平台开源描述Redis C 是 是 基于内存key/value存储系统,缓存终端信息、服务器配置、终端最后位置等RabbitMQErlang是是实现了AMQP的消息中间件,各模块的消息传递全部基于MQgnss-commonJava是是整个系统的核心公共包,定义了各模块使用的常量、实体类、工具类、指令注册器、Redis服务、RabbitMQ交换机和队列、RabbitMQ序列化转换器gnss-webJava是是整个系统的web后台,提供前端接口jt808-serverJava是开放Jar包JT808网关,处理部标终端的交互file-serverJava是开放Jar包文件服务器,处理主动安全附件消息,JT1078的FTP文件上传,处理文件播放和下载的HTTP请求media-serverJava是开放Jar包流媒体服务器,处理JT1078音视频数据并封装flv供客户端播放 PS:这里提供的是Java版的流媒体服务器,性能肯定不如C/C++和GO编写的流媒体服务器,客户可替换自己的,需要修改Redis缓存的服务器配置信息
开源代码 系统公共包:https://github.com/gnss-pro/gnss-common gnss-web:https://github.com/gnss-pro/gnss-web 后台部署
最近两个月JT808网关和文件服务器已让华为工程师朋友帮忙优化了一版,现在发布的部署包是最新的,六七八月份的客户需要免费升级源码的请联系技术支持。
下载部署包后请按照《主动安全云平台后台部署手册》部署。
如果需要基于开源的gnss-web和gnss-common二次开发的,请按照《主动安全云平台开发环境搭建》的步骤搭建开发环境,再按照《gnss-web开发手册》的规范开发。 部署包下载地址:链接:https://pan.baidu.com/s/1VzBSGJLIOBUlqPuw7sxgcQ 提取码:p9rg 技术支持 致歉声明:由于我司以前一个技术支持从其他渠道获取了GPS产品经理、中位科技的代码,利用公司便利向其他客户兜售,被公司及早发现并解除合同,我司郑重向这些作者正式道歉。我司严正声明所有的核心代码都是自研,使用的技术框架全部基于开源,客户可以放心使用没有版权风险。 如果使用中出现问题,请发送私信或者联系扣扣:2645908325 Windows部署效果,实现一键启停服务,监控所有服务运行状态。 Linux部署效果,中间件使用docker部署
最近复习c++,发现原码反码补码以及数据类型的表示范围这方面的概念很模糊,现整理如下,供大家参考。
1、原码:
最高位表示数的符号,其他位表示数值
例如:[+7]原 = 0000 0111 [-7]原 = 1000 0111
2、反码:
正数的反码与原码相同
例如:[+7]反 = 0000 0111
负数的反码是由原码的符号位不变,其余为按位取反
例如:[-7]反 = 1111 1000
3、补码
正数的补码与原码相同
例如:[+7]补 = 0000 0111
负数的补码是由其反码的基础上加一
例如:[-7]补 = [-7]反 + 1 = 1111 1000 +1 = 1111 1001
4、反码和补码的产生原因(顺带解释了byte型数据的表示范围为什么是-128~127)
实际上,计算机对于正数的存储方式就是二进制本身,而反码和补码的出现,是计算机为了简化和方便处理,才将负数用补码的形式存储,为什么这样说呢?请看下面的解释:
首先我们来看下计算机怎么做减法:
为了减少成本,计算机采用的用加法来代替减法,思路如下:
以时钟表盘为例,要想将时针从从3点拨到5点,有两种解决方案:
1)将时针顺时针转动2小时 3 + 2 = 5
2)将时针逆时针转动10小时 3 - 10 = 5
可以将钟表盘理解为一个模12的循环,即走完12个小时后又会走回原点
同理,对于数据类型也是如此,以byte(8位)类型为例,从 0000 0000~1111 1111是一个模256(2^8)的循环,即1111 1111加一之后又会回到0000 0000
类比钟表,我们可以将减法转换为加法,例如 3 - 2 = 3 + 254 = 256 + 1 = 1(结果正确)
这个网上资源还是挺多哒。
我的作用仅是调试出来。
老规矩,注释必须全。抱拳。
%主文件 clc; clear; y=[7.6030 -4.1781 3.1123 1.0586 7.8053]'; A=[0.5377 -1.3077 -1.3499 -0.2050 0.6715 1.0347 0.8884; 1.8339 -0.4336 3.3049 -0.1241 -1.2075 0.7269 -1.1471; -2.2588 0.3426 0.7254 1.4897 0.7172 -0.3034 -1.0689; 0.8622 3.5784 -0.0631 1.4090 1.6302 0.2939 0.8095; 0.3188 2.7694 0.7147 1.4172 0.4889 -0.7873 -2.9443]; CS_OMP(y,A,7); %函数:CS_OMP function [theta]=CS_OMP(y,A,t) %size可算出行和列分别是多少 [y_rows,y_columns]=size(y); if y_rows<y_columns y=y'; end [M,N]=size(A); %传感矩阵A为M*N矩阵 theta=zeros(N,1); %用来存储恢复的theta(列向量) theta_ls=zeros(N,1); At=zeros(M,t); %用来迭代过程中存储A被选择的列 Pos_theta=zeros(1,t); %用来迭代过程中存储A被选择的列序号 r_n=y; %初始化残差(residual)为y for ii=1:t %迭代t次,t为输入参数 fprintf('迭代次数:%d\n',ii); product=A'*r_n; %传感矩阵A各列与残差的内积 fprintf('内积:'); disp(product'); %显示内积 [value,pos]=max(abs(product)); %找到最大内积绝对值,即与残差最相关的列 At(:,ii)=A(:,pos); %存储这一列 fprintf('theta:\n') disp(At); Pos_theta(ii)=pos; %存储这一列的序号 fprintf('已选择序列:'); disp(Pos_theta); A(:,pos)=zeros(M,1); %清零A的这一列,其实此行可以不要,因为它与残差正交 theta_ls=(At(:,1:ii)'*At(:,1:ii))^(-1)*At(:,1:ii)'*y; %正交化 fprintf('当前系数:'); disp(theta_ls'); r_n=y-At(:,1:ii)*theta_ls; %更新残差,y一直是原始值 fprintf('残差:'); disp(r_n'); error=sum(r_n.
<?php $arr = [ [ 'id' => 2135, 'first_name' => 'John', 'last_name' => 'Doe', ], [ 'id' => 3245, 'first_name' => 'Sally', 'last_name' => 'Smith', ], [ 'id' => 5342, 'first_name' => 'Jane', 'last_name' => 'Jones', ], [ 'id' => 5623, 'first_name' => 'Peter', 'last_name' => 'Doe', ] ]; /** * 1.使用array_column()函数,要求php版本5.5+ * array_column()返回数组中某一列的值 * array_column(array,column_key,index_key); */ var_dump(array_column($arr,'first_name')); /** * 2.array_walk()函数使用用户自定义函数对数组中的每个元素做回调处理 */ $first_names = []; array_walk($arr, function ($value, $key) use (&$first_names) { $first_names[] = $value['first_name']; }); var_dump($first_names); /** * 3.
一、前言
背景:ABTester实验是具有一定前瞻性,统计性,科学性的特点。用好了就实现了在大数据时代的充分利用数据分析问题,解决问题,为决策提供强有力的依据,但是有时候用户在使用ABTester时候,会出现一些痛点和疑惑。
痛点:
每次实验需要多少流量
实验时间开多长没有概念
解决问题:
为了验证某一个功能特性,一个实验需要开多少流量。
一个实验需要开多长时间
二、基础概念 1、研究对象 总体X:研究问题某个数量指标。
2、入手点 个体:总体中的一个元素xi 样本:一部分个体Xi
3、工具--统计量 4、抽样分布 标准正态分布N(0, 1)
Ka方分布
t-分布
F-分布
5、抽样定理 简单介绍几个
6、参数估计 通俗的说:样本参数去估计总体的参数。举个????:
样本均值估计总体均值,
用样本比例去估计总体比例,
用样本方差估计总体方差
(1)分类:点估计和区间估计
点估计通俗的说:用样本的统计量的值直接作为总体参数的估计值。
区间估计通俗的说:在点估计的基础上,给出总体参数估计的一个区间范围。
(2)置信区间和置信水平 通俗的说:区间估计中,样本统计量构造的总体参数的估计区间,称为置信区间。举个????:
100个样本,每一个样本构造一个置信区间,100个样本构造的总体参数的100个置信区间中,有95%的区间包含了总体参数的真值,5%则没有包含。
大样本下,样本均值的置信区间:
(3)总体均值的区间估计原理 大样本下,根据中心极限定理,可以得到的样本均值的抽样分布。
7、假设检验
我们来看一下一个简单的假设性检验的例子:根据水稻长势,估计平均亩产310kg,收割时,抽取10块地,测平均亩产320kg,如水稻产量服从正态分布N(u, 144),问所估计平均亩产是否正确?(a = 0.05,Z0.05 = 1.645,Z0.025 = 1.96) 分析:当方差已经的情况下,使用Z检验;未知的时候,使用t检验
三、一个简单并完整的ABTester例子
1、背景和设置 背景:有个web应用,接入了咱们sdk,上报各种事件埋点。
确认优化的目标:注册流程改版,从而提供注册转换率。
注册流程的A/B测试:之前是使用了图片校验码的方式,但是注册转化率偏低。提出设想:图片校验码方式改成短信校验码方式,是因为降低了用户输入的难度从而可以提高注册转换率。
我们设置
核心指标:注册转化率
设置版本:1个对照版本(图片校验码)。1个实验版本(短信验证码)。
设置版本流量:总流量我们设置50%,各个版本均匀分配。
web应用引入我们客户端分流sdk的,然后将版本代码插入到项目中。
2、结果分析 分别为两个版本分配了25%的用户流量,通过2个自然周左右的实验观察,数据显示。结果:新版本(短信校验码)的注册转化率提升了接近10%,并且95%置信区间是[8%, 12%], 分析:说明这个实验版本推广到全量用户之后,95%的概率下至少会有8%到12%的提升。决策:基于这个实验结果,产品经理选择将新版本注册流程推送给全部用户,显著提升了注册转化率。
四、详细介绍样本量计算 1、注册流程改版例子???? 实验运行后,用户开始进组。1天后数据统计
这就能说明:短信验证码的功能有效提高注册转换率?
2天后数据统计
这就能说明:图片验证码的功能有效提高注册转换率?
那么到底,注册流程改版对于提高注册转换率是否有显著性提高呢?暂时是不能给出结论的,因为数据样本还不够大,不能充分说明。
理论上:样本量越多越好。现实上:1、自身样本不够大;2、试错成本大。
redis cluster 架构图Redis 集群的数据分片redis集群主从复制模型Redis 一致性保证集群的使用 架构图 redis cluster从3.0之后,采取了无中心化得架构模式,即所有的节点都相互连接。官方推荐使用6个实例,3个主,3个从。 上图为了方便,所以画了两个。 redis cluster提供了主从复制、故障转移等一系列高可用 。
redis中文文档
Redis 集群的数据分片 Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念.
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:
节点 A 包含 0 到 5500号哈希槽.
节点 B 包含5501 到 11000 号哈希槽.
节点 C 包含11001 到 16384号哈希槽.
这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可. 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态.
redis集群主从复制模型 redis集群中直接涵盖了主从复制,例如上边的A/B/C三个主节点,在此基础上再添加A1,B1,B3三个从节点,这样当主节点的任何一个断开之后,与之对应的从节点会自动补上、但是如果A和A1坏掉,整个集群就不可用了 。
Redis 一致性保证 Redis 并不能保证数据的强一致性. 这意味这在实际中集群在特定的条件下可能会丢失写操作.
第一个原因是因为集群是用了异步复制. 写操作过程:
客户端向主节点B写入一条命令.
主节点B向客户端回复命令状态.
主节点将写操作复制给他得从节点 B1, B2 和 B3.
主节点对命令的复制工作发生在返回命令回复之后, 因为如果每次处理命令请求都需要等待复制操作完成的话, 那么主节点处理命令请求的速度将极大地降低 —— 我们必须在性能和一致性之间做出权衡。 注意:Redis 集群可能会在将来提供同步写的方法。 Redis 集群另外一种可能会丢失命令的情况是集群出现了网络分区, 并且一个客户端与至少包括一个主节点在内的少数实例被孤立。
1.泛型 1.1泛型概述【理解】(视频01) 1.什么是泛型(泛型概述)
泛型就是参数化类型,也可称为类型参数。格式为:<类型>.(ArrayList)
2.为什么要使用泛型(泛型的好处)
它提供了编译时类型安全检测机制,把运行时期的问题提前到了编译期间避免了强制类型转换 package com.itheima.genericitysummarize; import java.util.ArrayList; import java.util.Iterator; /** * 不写泛型的弊端 */ public class GenericitySummarize { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add(123); Iterator it = list.iterator(); while(it.hasNext()){ String next = (String) it.next(); int len = next.length(); System.out.println(len); } } } 1.2泛型类的使用【应用】(视频02) 1.泛型用在什么地方(泛型可以使用的地方)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F2iYzUxz-1599473380859)(img/1596093650953.png)]
2.什么是泛型类(ArrayList)
如果一个类的后面有 ,表示这个类是一个泛型类
3.如何使用泛型类
创建泛型类对象时,必须要给这个泛型确定具体的数据类型
1.3 泛型-自定义泛型类(应用)(视频03) 1.如何定义泛型(泛型的定义格式)
<类型>: 指定一种类型的格式.
尖括号里面可以任意书写,一般只写一个字母.
折半查找 定义:
计算机科学中,折半搜索(英语:half-interval search),也称二分搜索(英语:binary search)、对数搜索(英语:logarithmic search),是一种在有序数组中查找某一特定元素的搜索算法。
搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。
#include <iostream> using namespace std; int Search_Bin(int A[],int key,int n){ int low = 0; int high = n-1; int mid; while(low<=high){ mid=(low+high)/2; if(key==A[mid]){ return mid; } else if(key<A[mid]){ high=mid-1; } else{ low=mid+1; } } return 0; } void sort(int A[],int n){ //冒泡法排序 for(int i=0;i<n-1;i++){ for(int j=0;j<n-i-1;j++){ if(A[j]>A[j+1]){ int t=A[j]; A[j]=A[j+1]; A[j+1]=t; } } } } void Print(int A[],int n){ for(int i=0;i<n;i++){ cout<<A[i]<<" "
一、什么是SNMPTRAP
SNMP trap(SNMP 陷阱):某种入口,到达该入口会使SNMP被管设备主动通知SNMP管理器,而不是等待SNMP管理器的再次轮询。在网管系统中,被管理设备中的代理可以在任何时候向网络管理工作站报告错误情况,例如预制定阈值越界程度等等。代理并不需要等到管理工作站为获得这些错误情况而轮询他的时候才会报告。正如人们用中断通知 CPU 数据的到达,而不是让 CPU 进行轮询一样。Trap 通知是更加合理的选择。用一句话来说的话,SNMP Trap 就是被管理设备主动发送消息给 NMS 的一种机制。 二、SNMPTRAP功能特点
1、事件驱动,第一时间收到设备故障告警
以事件为驱动,由被监控的主机、网络设备、应用在发生故障时向NMS发送SNMP Trap,通过对接收到的SNMP Trap进行翻译和展现,以最快速度向管理人员发送告警。SNMP Trap不同于SNMP的主动采集,SNMP采集服务器按照固定的时间间隔,由网管系统以询问的方式,采集被监控端性能指标,因此发现被监控端性能问题的快慢取决于采集的频率间隔。而SNMP Trap是以事件为驱动,在被监控端设置陷阱,一旦被监控端设备出现相关问题,立刻发送SNMP Trap,因此能够在最短的时间内发现故障,避免因为设备故障带来的经济损失。2、提供SNMPTrap的接收,并通过对Trap信息翻译,展现事件
支持设备,主机和应用的SNMP Trap信息,从被动变为主动,全面监控IT系统。通过对SNMP Trap的翻译和展现,一旦某个IT组件出现问题,可以在短时间之内,即可收到故障信息,满足企业的快速发现问题的需要。
通过SNMPTrap的接收规则定义,管理员可以过滤非重要设备的Trap信息,也可以过滤被监控设备的非重要故障信息,帮助管理员在第一时间收到真正需要的管理信息。3、支持事件导出
汇总特定时间内特定SNMPTrap事件,同时可以以Excel格式导出事件数据,便于管理人员对故障信息进行统计和分析。4、支持各类设备厂家MIB库的导入
虽然国内各种网络设备都支持SNMP Trap,但是各个厂家的MIB库并不能很好的支持公共标准,因此,很多监控系统都支持私有MIB库的导入,确保能够全面兼容各个厂家设备的SNMP Trap信息. 三、SNMPTRAP工作流程
1、Agent端
A、编写MIB文件,确定好TRAP名称等信息
B、命令方式:发送各种TRAP命令(Manager地址后面一定要加端口号162),在Manager端看反应结果,在Agent端无反应
C、自动触发:配置snmpd.conf设置触发TRAP,系统发生某类错误时会自动触发相应类型的TRAP,发送给Manager
D、程序方式:一部份TRAP需要写C语言程序,用相应的api(send_easy_trap或send_v2trap)发送2、Manager端
A、配置snmptrapd.conf文件,设置访问权限
B、将MIB文件导入到mibs文件夹中
C、用perl等脚本语言编写处理trap的程序
D、配置snmptrapd.conf文件,添加traphandler项,将不同的TRAP对应到不同的处理程序上 四、TRAP MIB编写及编译
NET-SNMP中TRAP的实现是基于一个由NOTIFICATION-TYPE 定义的MIB对象实现的。该对象在TrapPDU中头部位置,后续紧跟着该Trap携带的其他节点的信息,这些节点信息是Trap中有意义的信息,体现本次“告警”的真正内容,这些节点一般为普通的MIB对象。其中OBJECTS 子句中可以包含多个对象。
实现私有Trap的方法与之前的普通MIB开发方法类型:
先定义Trap的MIB对象,然后借由mib2c和相应的框架代码配置文件,“mib2c.notify.conf”,生成Trap框架代码。
命令如下:
mib2c -c mib2c.notify.conf TEST-TRAP-MIB::TestTraps 其生成的框架代码:
注册Trap对象绑定对象发送列表最后调用API发送:send_easy_trap() send_v2trap() send_v3trap(). Trap的发送逻辑一般具有重复发送的特性,这一特性可有snmp_alarm_register()实现。该API能够准确地实现计时器功能。示例代码中也是由该API实现重复,周期调用的功能。
五、TRAP MIB示例文件
TEST-TRAP-MIB DEFINITIONS ::= BEGIN IMPORTS MODULE-IDENTITY, OBJECT-TYPE, TimeTicks FROM SNMPv2-SMI DisplayString, FROM SNMPv2-TC jsHostInfo FROM JS-MAIN-MIB ; TestTraps OBJECT IDENTIFIER ::= { jsHostInfo 99 } cpuRatioHigh NOTIFICATION-TYPE OBJECTS {TestTrapDescription} --可以包含多个对象 STATUS current DESCRIPTION "
centos搭建kong+konga 前言:最近正在学习kong网关 记录一下搭建服务的过程 也是百度东拼西凑出来的 基于华为云服务器 保证可用!
gccpcrezlibopensslpostgresql9.6+konga 安装 gcc 编译环境:
sudo yum install -y pcre pcre-devel pcre 安装
sudo yum install -y pcre pcre-devel zlib 安装
sudo yum install -y zlib zlib-devel openssl 安装
sudo yum install -y openssl openssl-devel postgresql 安装
kong持久化数据有postgresql和cassandra两种数据库选择 这里选择postgresql
PS:不要图省事直接 yum install postgresql,因为这个版本比较低,kong不适用,至少要9.5+。
sudo yum install -y https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-6-x86_64/pgdg-redhat-repo-42.0-11.noarch.rpm yum install postgresql96-server #启动 service postgresql-9.6 start postgresql配置
为kong创建用户以及数据库
// 新建 linux kong 用户 sudo adduser kong // 使用管理员账号登录 psql 创建用户和数据库 // 切换 postgres 用户 // 切换 postgres 用户后,提示符变成 `-bash-4.
npm 设置淘宝源 npm config set registry http://registry.npm.taobao.org/ 还原的话就是 npm config set registry https://registry.npmjs.org/
下面以QQ邮箱为例进行说明
1、首先要在邮箱的设置中,开启,POP3服务,如下图所示
2、生成授权
注意不能用密码,用密码则会提示标题中的错误
3、用生成的授权码进行第三方登录发送邮件,成功
DVB-S2 LDPC校验矩阵生成方法 H = [ H 1 H 2 ] H=[H_1\ H_2] H=[H1 H2]
参数说明:
F_NUM: H 1 H_1 H1矩阵中第一种列重每列中的1;
S_NUM: H 1 H_1 H1矩阵中第二种列重每列中的1;;
F_ADDR: H 1 H_1 H1矩阵中第一种列重每360列一组中每行的1;
S_ADDR: H 1 H_1 H1矩阵中第一种列重每360列一组中每行的1;
H 1 T H_1^{T} H1T是一个稀疏矩阵,标准中有 H 1 T H_1^{T} H1T矩阵中1的详细位置
H 2 H_2 H2是一个满秩的下三角矩阵,即一个简单的累加器
H H H矩阵的存储方法:
每360列存为1组,存储其中第一列的1的位置; 恢复时,取出存储矩阵的一行,恢复第一列,然后根据移位Q恢复一组
(该方法与MATLAB中dvbs2ldpc的存储方式一致)
DVBS2标准中 长码 R=5/6的存储矩阵:
H1 = [0 4362 416 8909 4156 3216 3112 2560 2912 6405 8593 4969 6723
CDA数据分析师 出品 作者:Mika
数据:真达 后期:Mika
【导读】手把手教你如何用python写出心血管疾病预测模型。
全球每年约有1700万人死于心血管疾病,当中主要表现为心肌梗死和心力衰竭。当心脏不能泵出足够的血液来满足人体的需要时,就会发生心力衰竭,通常由糖尿病、高血压或其他心脏疾病引起。
在检测心血管疾病的早期症状时,机器学习就能派上用场了。通过患者的电子病历,可以记录患者的症状、身体特征、临床实验室测试值,从而进行生物统计分析,这能够发现那些医生无法检测到的模式和相关性。
尤其通过机器学习,根据数据就能预测患者的存活率,今天我们就教大家如何用Python写一个心血管疾病的预测模型。
研究背景和数据来源
我们用到的数据集来自Davide Chicco和Giuseppe Jurman发表的论文:《机器学习可以仅通过血肌酐和射血分数来预测心力衰竭患者的生存率》。
他们收集整理了299名心力衰竭患者的医疗记录,这些患者数据来自2015年4月至12月间巴基斯坦费萨拉巴德心脏病研究所和费萨拉巴德联合医院。这些患者由105名女性和194名男性组成,年龄在40至95岁之间。所有299例患者均患有左心室收缩功能不全,并曾出现过心力衰竭。
Davide和Giuseppe应用了多个机器学习分类器来预测患者的生存率,并根据最重要的危险因素对特征进行排序。同时还利用传统的生物统计学测试进行了另一种特征排序分析,并将这些结果与机器学习算法提供的结果进行比较。
他们分析对比了心力衰竭患者的一系列数据,最终发现根据血肌酐和射血分数这两项数据能够很好的预测心力衰竭患者的存活率。
今天我们就教教大家,如果根据这共13个字段的299 条病人诊断记录,用Python写出预测心力衰竭患者存活率的预测模型。
下面是具体的步骤和关键代码。
01、数据理解
数据取自于kaggle平台分享的心血管疾病数据集,共有13个字段299 条病人诊断记录。具体的字段概要如下:
02、数据读入和初步处理
首先导入所需包。
# 数据整理 import numpy as np import pandas as pd # 可视化 import matplotlib.pyplot as plt import seaborn as sns import plotly as py import plotly.graph_objs as go import plotly.express as px import plotly.figure_factory as ff # 模型建立 from sklearn.linear_model import LogisticRegression from sklearn.tree import DecisionTreeClassifier from sklearn.
在线教育开发之四级联动 为了实现地区的四级联动选择,可以使用ajax提交数据到控制器,控制器接收数据之后查询pid对应的area。
1.生成地区数据表,需要四级联动表源码请添+Q1143157804(全球行政区划四级联动数据.sql)免费提供!!
2.显示所有国家
2.1 在控制器中查询数据
2.2 在视图中显示所有数据
3.当点击国家时,显示所有省份
3.1在控制器中接收数据,并用json格式返回数据给视图层
3.2 视图层接收返回数据并循环输出
注意:这里的 “清除追加” 段的代码如果未添加的话,那么,当选择另一个国家时,省份会追加显示;
如下:
4.继续为省份、市添加联动,代码和上方基本相识
注意:每一级的选择器需要修改,还有 “清除追加” 段的代码也需要添加,不然第三级还是会出现 “当选择另一个国家时,省份会追加显示”相类似的情况!!
至此,四级联动实现。
效果如下:
R语言数据分析 R语言与数据分析概述基本操作命令基本数据类型数据类型的转换运算符R中的数据结构代码展示 R语言与数据分析概述 R语言是一种开源的脚本语言,诞生于1993年,R系统是开源、免费的。
数据分析过程:
数据导入——数据清洗——数据探索——数据建模——可视化——报告发现
基本操作命令 注:*处写包名
函数说明getwed()显示当前工作目录setwd ()修改当前工作目录ls ()显示当前工作空间中的所有对象str ()显示对象的结构ls.str ()显示对象中每一个变量的结构exists ()当前工作空间内是否存在某个对象rm ()删除一个多或多个对象q ()退出R。在这之前会询问是否保存工作空间.libPaths ()查看该文件夹在计算机中的具体路径install.packages ()安装包library ()显示已安装的包的列表search()显示已加载的包的列表library("*")加载这个包detach(“packages:*”)移除包remove.packages(“*”)卸载包 基本数据类型 类型说明判断函数R语言形式逻辑型表示逻辑值的二值数据,只有TRUE或 FALSE两个取值。在R中,逻辑表达式 的赋值会得到逻辑型数据,例如比较 两个数的大小2>1等于TRUEis.logocal()TRUE , 2 <= 1浮点型用十进制表示的实数,如1,1.1等, 是用于计算的基本数据形式is.double ()3.14整数型用于描述整数,如1,2,3。需要注意 的是,在R语言中,在整数后加上字符 L才代表整型数,否则会被视为浮点is.integer()3L字符型用于表示一个字符串is.character ()“Hello”,“3.14”复数型用于表示复数值,其中虚部用i表示, 例如2+3iis.complex ()1+i原始型用于保存原始的字节,其中每个字节 用两个十六进制数表示,例如A3is.raw ()00 数据类型的转换 逻辑型 ——整数型 ——浮点型 ——字符型
运算符 R中的数据结构 ➢向量 ➢矩阵 ➢数组 ➢列表 ➢数据框 ➢因子
向量功能:
✓创建向量
✓访问元素
✓添加元素
✓删除元素
✓获取向量长度
代码展示 #基本数据类型 getwd() install.packages("stringr") .libPaths() library() search() library("stringr") str_length ("Hello R!") detach("package:stringr") str_length ("
介绍 Java开发工具 Java Development Kit 简称JDK
Java运行时环境 Java Runtime Environment 简称JRE
Java虚拟机 Java Virtual Machine 简称JVM
详细介绍 JDK: JDK是java开发工具包,是整个Java的核心,包括了Java运行环境(Java Runtime Environment )简称jre,一堆Java工具(javac.exe/java.exe/jdb等)和Java基础的类库(即Java API 包括rt.jar)。jdk中包含jre(jdk11以后没有jre文件夹需要手动添加)。在jre的目录下,有bin和lib文件夹,在这里可以认为bin里面就是jvm,lib是java工作需要的类库,它们两者结合就称为jre。
注意:
jre文件夹下的bin和jdk下的bin是不同的,JDK是用于java程序的开发的(bin下有javac.exe、java.exe等),而jre则只能运行class而没有编译的功能。
JRE: 是运行基于java语音编写的程序必不可小的运行环境,也是通过它,java开发者才可以将自己开发的程序发布到用户手中,让用户使用。jre是运行环境,并不是开发环境,所以没有包含任何开发工具(如编译器,调试器等)。
JRE包含JVM标准实现及Java核心类库,光有JVM还不能执行class文件,因为解释class的时候JVM需要调用解释所需要的类库lib(jre里有运行.class的java.exe)
JVM: JVM就是我们常说的Java虚拟机,它是整个Java实现跨平台的最核心的部分,所有的Java程序首先被编译为.class文件,这种文件可以在虚拟机上运行,也就是说class并不直接与机器的操作系统相对应,是有我们的JVM解释处理,再交给操作系统处理。
JDK与JRE的关系 1、两者是包含关系,JDK包含JRE
2、应用区别:如果只要运行Java程序,则只需要安装JRE运行环境;如果要做Java开发则必须安装JDK,如果安装了JDK则无需安装JRE。
三者联系 JVM不能单独搞定class的执行,解释class的时候JVM需要调用解释所需要的类库lib。在JDK下面的的jre目录里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib和起来就称为jre。
Java的运行过程 字节码文件:
是一种和任何具体机器环境及操作系统环境无关的中间代码,它是一种二进制文件,是有Java编译器编译后生成的目标代码文件,编程人员和计算机都无法直接读懂字节码文件,它必须由java解释器来解释执行。
Java解释器:
Java解释器是Java虚拟机的一部分,在运行Java文件时,首先启动JVM,然后由它来负责解释执行 Java 的字节码程序,并且 Java 字节码程序只能运行于 JVM 之上。
**注意:**Java程序通过JVM可以实现跨平台特性,但JVM是 不跨平台的。也就是说,不同操作系统上的JVM不一样,如:Windows和Linux平台上用的JDK是不一样的。
要在某个指标上对比两个模型的好坏,我们可以直接进行比较,同时为了使比较结果更具说服力,我们可以使用统计检验的方法,即将两个模型分别跑k次,使用t检验比较这两组k个样本的均值、使用F检验比较这两组k个样本的方差,均值越大、方差越小说明在当前指标上该模型更好更稳定(这里说的指标是正向指标)。那么下面我们以具体代码来进行说明。
from scipy.stats import ttest_rel, f import numpy as np # 模型一10组实验结果 x = [44.2, 36.1, 46.5, 40.7, 61.6, 55.4, 59.9, 55.2, 65.5, 58.5] # 模型二10组实验结果 y = [44.1, 35.9, 45.6, 39.5, 60.1, 55.1, 59.9, 54.2, 65.6, 58.2] print('t检验结果:p值') print(ttest_rel(x, y)) # 计算组内样本方差 var1 = np.var(x, ddof=1) var2 = np.var(y, ddof=1) # 计算统计量F F = var1 / var2 # 计算自由度 df1 = len(x) - 1 df2 = len(y) - 1 # 计算p值 p_value = 1 - 2 * abs(0.
一、R语言数据分析是什么? R 是一种免费的、开源的语言和操作环境,一开始是为了统计计算和画图,R语言现在可以在诸多领域进行应用,比如,数据挖掘、机器学习、社交网络、生物信息、金融数据分析,数据分析等。同时,R 提供了专业模块和实用工具,是从大数据中获取有用信息的工具。
二、R语言代码 1.基本数据类型 代码如下(示例):
num <-100;num is.integer(num)#? is.double(num)#? typeof(num) num2 <- 100L typeof(num2) is.logical(TRUE) is.logical(T) is.logical(5)#? is.logical(0)#? is.character("R program") 2.数据类型转换 代码如下(示例):
logi_vec <- T typeof(logi_vec) int_vec <- c (100L,200L) typeof(int_vec) double_vec <- c(10,20) typeof(double_vec) chr_vec <- c("伟大的","中国人民") typeof(chr_vec) typeof(c(logi_vec,int_vec)) #?验证逻辑型与整数型 typeof(c(int_vec,double_vec)) #?验证整数型与浮点型 typeof(c(double_vec,chr_vec)) #?验证浮点型与字符型 typeof(c(logi_vec,int_vec,double_vec,chr_vec)) #?验证兼容性最大的是字符型 1=='1'#? 3.运算符 代码如下(示例):
logi_vec1 <- c(T,F,T) logi_vec2 <- c(F,T,T) logi_vec1 & logi_vec2 #? logi_vec1 && logi_vec2 #? logi_vec1 <- c(T,F,T)#向量长度不同,短的循环补齐 logi_vec2 <- c(T,T,T,F) logi_vec1 & logi_vec2 #?
出现这种情况大多是因为电脑上之前安装过JDK,卸载重装之后,运行java命令会出现error:could not open …jvm.cfg的错误。
打开系统环境变量,查看PATH,会看到诸如此类的配置信息: %SystemRoot%\system32;%SystemRoot%;......%JAVA_HOME%\lib;%JAVA_HOME%\bin 原因:在运行java时,默认会按照PATH中设置的路径去寻找java.exe文件,按上述PATH信息首先会去找%SystemRoot%\system32目录下的文件,而该目录下的java.exe对应的jdk安装目录已被卸载,自然会出现文件打不开的提示。 看到这儿或许你明白了,简单的解决方法有二: 1、直接删除system32目录(或windows目录,视PATH中的路径设置而定)下的java.exe(其实看下文件日期就会发现,该文件与当前安装的JAVA bin目录下的文件日期不一样); 2、直接将%JAVA_HOME%\bin;放在PATH路径的最前面(知道为什么了吧); 再试试,是不是OH了~~ 将JAVA_HOME的配置移动到最上面,解决这个问题 添加这个字符编码的格式,这样的话编码格式就修改完成了
-Dfile.encoding=UTF-8
1、代码下载:https://github.com/niessner/BundleFusion
2、依赖库MLib:https://github.com/niessner/mLib
依赖库mLib external libraries:http://kaldir.vc.in.tum.de/mLib/mLibExternal.zip
3、最终的目录结构如下:
BundleFusion-master/ external/ mLib/ # this is the submodule you replaced data/ src/ [...] FriedLiver/ [...] FriedLiver.sln [...] mLibExternal/ # you downloaded this from Dropbox include libsWindows [...] 4、推荐使用NotePad++打开“FriedLiver.vcxproj”,或是使用VSCODE打开工程对其属性进行修改,一共有两处需要修改(当然前提是你的电脑已经安装好了CUDA8.0,参考:https://blog.csdn.net/ffcjjhv/article/details/89221992)
5、安装DirectX SDK:https://www.microsoft.com/en-us/download/details.aspx?id=6812
直接安装即可,如果出现错误,通过控制面板卸载以下两项
如果还不行,参考博客:https://blog.csdn.net/ffcjjhv/article/details/89221992
6、打开工程,先不急编译,需要修改一些内容
首先:打开GlobalAppState.h文档,将相机模块全部注释掉:
然后,将前面安装的DirectX SDK库添加到工程:包括头文件和库文件以及可执行文件
添加好了后,确认工程为Release x64版本,确认所有的三方库路径正确,确认自己的GPU运算能力,
可以通过下面网址查找自己的显卡运算能力:https://developer.nvidia.com/cuda-gpus#collapseOne,注意运算能力一定要对应,否则可能出错。
添加对应的CUDA工具:
完成以上确认后,开始编译,如果没有意外,则编译通过:
7、由于我是win7系统,用不了KineceV2,所以使用xtion试试,参考:
kinectv1:https://blog.csdn.net/ffcjjhv/article/details/89221992
kinectv2:https://blog.csdn.net/weixin_36788761/article/details/100702469
xtion:https://blog.csdn.net/renye_lpl/article/details/80599408
首先安装OpenNI2:https://structure.io/openni 直接下载对应的版本安装即可,同样地,需要将一下三项配置到工程当中:
取消GlobalAppState.h文件中OpenNI的注释
//#define KINECT //#define KINECT_ONE #define OPEN_NI //#define BINARY_DUMP_READER //#define INTEL_SENSOR //#define REAL_SENSE //#define STRUCTURE_SENSOR 然后找到PrimeSenseSensor.h文件,在其中添加一个函数getSensorName():
前言 配套视频:
https://www.bilibili.com/video/BV1et411b73Z
只是为方便学习,不做其他用途,在此发布C++基础入门部分配套讲义,原作者为黑马程序
C++提高编程 本阶段主要针对C++泛型编程和STL技术做详细讲解,探讨C++更深层的使用 1 模板 1.1 模板的概念 模板就是建立通用的模具,大大提高复用性
模板的特点:
模板不可以直接使用,它只是一个框架模板的通用并不是万能的 1.2 函数模板 C++另一种编程思想称为 泛型编程 ,主要利用的技术就是模板
C++提供两种模板机制:函数模板和类模板
1.2.1 函数模板语法 函数模板作用:
建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。
语法:
template<typename T> 函数声明或定义 解释:
template — 声明创建模板
typename — 表面其后面的符号是一种数据类型,可以用class代替
T — 通用的数据类型,名称可以替换,通常为大写字母
示例:
//交换整型函数 void swapInt(int& a, int& b) { int temp = a; a = b; b = temp; } //交换浮点型函数 void swapDouble(double& a, double& b) { double temp = a; a = b; b = temp; } //利用模板提供通用的交换函数 template<typename T> void mySwap(T& a, T& b) { T temp = a; a = b; b = temp; } void test01() { int a = 10; int b = 20; //swapInt(a, b); //利用模板实现交换 //1、自动类型推导 mySwap(a, b); //2、显示指定类型 mySwap<int>(a, b); cout << "
文章目录 一、git submodule背景1. git将submodule有关的信息在哪?2. 子模块的添加3. 子模块仓库更新子模块的更新 4. 删除子模块过程中问题 参考 一、git submodule背景 项目中经常使用别人维护的模块,在git中使用子模块的功能能够大大提高开发效率。
使用子模块后,不必负责子模块的维护,只需要在必要的时候同步更新子模块即可。
1. git将submodule有关的信息在哪? git将submodule有关的信息保存在两个地方:
.gitmodules在仓库中,有版本控制,修改之后会同步到其他仓库,使用submodule相关命令的时候会自动更新.git/config在本地,需要手动更新,或者执行git submodule sync将新的配置从.gitmodules拷贝到.git/configgit submodule sync会将submodule远程的 url 配置设置到.gitmodules,并且只会影响.git/config已经有 url 的条目,指定–recursive,将会递归更新注册的submodule 2. 子模块的添加 添加子模块非常简单,命令如下:
git submodule add 其中,url为子模块的路径,path为该子模块存储的目录路径。
执行成功后,git status会看到项目中修改了.gitmodules,并增加了一个新文件(为刚刚添加的路径)
git diff --cached查看修改内容可以看到增加了子模块,并且新文件下为子模块的提交hash摘要
git commit提交即完成子模块的添加
3. 子模块仓库更新 github 子模块多仓库代码更新。
git submodule sync git submodule update --init 当使用git clone下来的工程中带有submodule时,初始的时候,submodule的内容并不会自动下载下来的,此时,只需执行如下命令:
git submodule init
git submodule update
或:
git submodule update --init --recursive
执行后,子模块目录下就有了源码,再执行相应的makefile即可。
子模块的更新 子模块的维护者提交了更新后,使用子模块的项目必须手动更新才能包含最新的提交。
在项目中,进入到子模块目录下,执行 git pull更新,查看git log查看相应提交。
//二分法查找 public class TestBinarySearch { public static void main(String[] args) { //目标数组 int[] arr=new int[] {1,2,3,4,5,6,7,8,9}; //目标元素 int target=1; //记录开始位置 int begin=0; //记录结束位置 int end=arr.length-1; //目标元素位置 int index=-1; //循环查找 while(begin<=end) { //记录中间位置 int mid=(begin+end)/2; //判断中间元素是不是要查找的元素 if(arr[mid]==target) { index=mid; break; }else { //中间元素比目标元素大 if(arr[mid]>target) { //结束位置调整到中间位置的前一个元素 end=mid-1; }else {//中间元素比目标元素小 //开始位置调整到中间位置的后一个元素 begin=mid+1; } } } System.out.println("index:"+index); } } 注意:目标数组必须有序排列。
pytorch实现文本分类
‘Attention Is All You Need’
“注意力就是你所需要的” New deep learning models are introduced at an increasing rate and sometimes it’s hard to keep track of all the novelties .
新的深度学习模型被引入的速度越来越快,有时很难跟踪所有新颖性。 in this Article we will talk about Transformers with attached notebook(text classification example) are a type of neural network architecture that have been gaining popularity .
在本文中,我们将讨论带有笔记本的变压器 (文本分类示例)是一种已经越来越流行的神经网络体系结构。 In this post, we will address the following questions related to Transformers :
[OC RunLoop_翻译]一、介绍 & 二、剖析运行循环
[OC RunLoop_翻译]三、 什么时候使用运行循环 & 四、使用运行循环对象
[OC RunLoop_翻译]五、配置运行循环源
注:pdf翻译文档百度云下载链接,密码:zcs2
注: _Run Loops _链接
下面的部分展示了如何在Cocoa和corefoundation中设置不同类型的输入源的示例
5-1、定义自定义输入源 创建自定义输入源需要定义以下内容:
希望输入源处理的信息.调度程序,让感兴趣的客户知道如何联系您的输入源.处理程序,用于执行任何客户端发送的请求。.取消例程,用于使您的输入源无效. 因为您创建了一个自定义输入源来处理自定义信息,所以实际配置的设计是灵活的。调度程序、处理程序和取消例程是自定义输入源几乎总是需要的关键例程。然而,其余的输入源行为大多发生在这些处理程序例程之外。例如,由您定义将数据传递到输入源以及将输入源的存在与其他线程通信的机制。
图3-2显示了自定义输入源的示例配置。在此示例中,应用程序的主线程维护对输入源、该输入源的自定义命令缓冲区以及安装该输入源的运行循环的引用。当主线程有一个要移交给工作线程的任务时,它将一个命令连同工作线程启动该任务所需的所有信息一起发布到命令缓冲区。 (由于主线程和工作线程的输入源都可以访问命令缓冲区,所以该访问必须同步。)一旦发布命令,主线程将向输入源发出信号并唤醒工作线程的运行循环。收到唤醒命令后,运行循环将调用输入源的处理程序,该处理程序将处理在命令缓冲区中找到的命令。
Figure 3-2 操作自定义输入源
以下部分将解释上图中自定义输入源的实现,并显示需要实现的关键代码。
定义输入源 定义自定义输入源需要使用Core Foundation例程来配置您的运行循环源并将其附加到运行循环。尽管基本处理程序是基于C的函数,但这并不妨碍您编写这些函数的包装程序并使用Objective-C或C ++来实现代码主体。
图 Figure 3-2 中引入的输入源使用一个Objective-C对象来管理命令缓冲区并与运行循环协调。清单3-3显示了此对象的定义。 RunLoopSource对象管理命令缓冲区,并使用该缓冲区从其他线程接收消息。此清单还显示了**RunLoopContext**对象的定义,该对象实际上只是一个容器对象,用于传递RunLoopSource对象和对应用程序主线程的运行循环引用
Listing 3-3 自定义输入对象定义
@interface RunLoopSource : NSObject { CFRunLoopSourceRef runLoopSource; NSMutableArray* commands; } - (id)init; - (void)addToCurrentRunLoop; - (void)invalidate; // Handler method 处理程序方法 - (void)sourceFired; // Client interface for registering commands to process //客户端接口,用于注册要处理的命令 - (void)addCommand:(NSInteger)command withData:(id)data; - (void)fireAllCommandsOnRunLoop:(CFRunLoopRef)runloop; @end // These are the CFRunLoopSourceRef callback functions.
LVS负载均衡:LVS-NAT搭建web群集 一:实验环境介绍二:实验架构三:实验目的四:实验步骤4.1:NFS服务器配置4.2:两台Apache服务的配置4.3:LVS配置 五:实验验证 一:实验环境介绍 VMware软件
一台centos7作为LVS网关,双网卡
两台centos7作为Apache服务器
一台centos7作为NFS存储
一台win10作为客户端
二:实验架构 三:实验目的 win10客户机访问12.0.0.1的网址,通过nat地址转换,轮询的访问到Apache1和Apache2主机
四:实验步骤 4.1:NFS服务器配置 添加两块硬盘,作为Apache1和Apache2的挂载点 [root@nfs ~]# fdisk -l //查看添加的磁盘 格式化磁盘 [root@nfs ~]# fdisk /dev/sdb //n 新建 一路回车 最后w保存退出// [root@nfs ~]# mkfs.xfs /dev/sdb1 //创建文件系统 另一块磁盘做同样操作
创建挂载点、挂载磁盘 [root@nfs ~]# mkdir /opt/apache1 /opt/apache2 [root@nfs ~]# vim /etc/fstab //末行添加 /dev/sdb1 /opt/apache1 xfs defaults 0 0 /dev/sdc1 /opt/apache2 xfs defaults 0 0 [root@nfs ~]# mount -a [root@nfs ~]# df -Th 文件系统 类型 容量 已用 可用 已用% 挂载点 /dev/mapper/centos-root xfs 47G 4.
来源:极市平台
本文约13600字,建议阅读10分钟
本文从工程基础、算法基础、算法工程交叉、工程深入方向、算法深入方向等方面给出建议,并设计了自我考核模块,帮助大家查漏补缺,自我提升。
[ 导读 ]算法工程师如何获得技术方面的成长?本文从工程基础、算法基础、算法工程交叉、工程深入方向、算法深入方向等方面给出建议,并设计了自我考核模块,帮助大家查漏补缺,自我提升。
前言 这是一份写给公司算法组同事们的技术路线图,其目的主要是为大家在技术路线的成长方面提供一些方向指引,配套一些自我考核项,可以带着实践进行学习,加深理解和掌握。
内容上有一定的通用性,所以也分享到知乎上。欢迎大家给出建议,如有错误纰漏,还望不吝指正 :)
工程师能力层级概览 对于不同级别的算法工程师技能要求,我们大致可以分成以下几个层级:
初级:可以在一些指导和协助下独立完成开发任务。具体到算法方面,需要你对于工具框架,建模技术,业务特性等方面有一定的了解,可以独立实现一些算法项目上的需求。
中级:可以基本独立完成一个项目的开发与交付。在初级工程师的基础上,对于深入了解技术原理的要求会更高,并且能够应对项目中各种复杂多变的挑战,对于已有技术和工具进行改造适配。在整体工程化交付方面,对于代码质量,架构设计,甚至项目管理方面的要求会开始显现。另外从业务出发来评估技术选型和方案也变得尤为重要。
高级:可以独立负责一条产品线的运作。在中级工程师的基础上,需要更广阔的技术视野与开拓创新能力,定义整个产品线的前进方向。解决问题已经不是关键,更重要的是提出和定义问题,能够打造出在业界具有领先性和差异性的产品,为公司创造更大的价值。
事实上对于不同层级的工程师,非技术部分的要求都有一定占比。本文主要聚焦在技术路线图上,对于其他方面的学习进阶路线不会做覆盖。
阅读建议:
以下内容分工程基础、算法基础、算法工程交叉、工程深入方向、算法深入方向几个部分,在各个部分内部会进一步区分一些主题。在各个主题内部,也是有深入程度的区别的,不过限于篇幅没有进行详细的说明。建议学习路线可以先把两个基础部分与工作中较为相关的内容做一个整体基础的夯实,然后可以在后续交叉和深入方向的主题中选择感兴趣的进行深入了解和学习,过程中发现基础部分欠缺的,可以再回到基础部分查漏补缺,迭代前行。
工程基础 1)编程语言
Python Python是算法工程师日常工作中最常用的语言,应该作为必须掌握的一门技术。大致的学习路线如下:
学习掌握Python的基本语法,可以通过各类入门教程来看,个人推荐《Learn Python the Hard Way》。
自我考核:能够读懂大多数的内部项目及一些开源项目代码的基本模块,例如pandas, sklearn等。
学习Python的编程风格,建议学习观远内部的Python代码规范。
自我考核:编写的代码符合编码规范,能够通过各类lint检查。
Python进阶,这方面有一本非常著名的书《Fluent Python》,深入介绍了Python内部的很多工作原理,读完之后对于各类疑难问题的理解排查,以及语言高级特性的应用方面会很有帮助。另外动态语言元编程这块,《Ruby元编程》也是一本非常值得推荐的书。
自我考核:能够读懂一些复杂的Python项目,例如sqlalchemy中就大量使用了元编程技巧。在实际工程项目中,能够找到一些应用高级技巧的点进行实践,例如基于Cython的性能优化等。
领域应用,Python的应用相当广泛,在各个领域深入下去都有很多可以学习的内容,比如Web开发,爬虫,运维工具,数据处理,机器学习等。这块主要就看大家各自的兴趣来做自由选择了,个人推荐熟悉了解一下Python web开发,测试开发相关的内容,开拓视野。
自我考核:以Web开发和测试开发为例,尝试写一个简单的model serving http服务,并编写相应的自动化测试。
Scala/Java Java目前是企业级开发中最常用的软件,包括在大数据领域,也是应用最广泛的语言,例如当年的Hadoop生态基本都是基于Java开发的。Scala由于其函数式编程的特性,在做数据处理方面提供了非常方便的API,也因为Spark等项目的火热,形成了一定的流行度。在进行企业级的软件开发,高性能,大规模数据处理等方面,JVM上的这两门语言有很大的实用价值,值得学习。
顺带一提,Scala本身是一门非常有意思的语言,其中函数式编程的思想与设计模式又是非常大的一块内容,对于拓宽视野,陶冶情操都是挺不错的选择。
考虑到算法工程师的工作内容属性,这边给出一个Scala的学习路线:
学习掌握Scala的基本语法,开发环境配置,项目编译运行等基础知识。这里推荐Coursera上Martin Odersky的课程,《快学Scala》或《Programming in Scala》两本书也可以搭配着浏览参考。
自我考核:能使用Scala来实现一些简单算法问题,例如DFS/BFS。或者使用Scala来处理一些日常数据工作,例如读取日志文件,提取一些关键信息等。
学习使用Scala来开发Spark应用,推荐edX上的《Big Data Analytics Using Spark》或者Coursera上的《Big Data Analytics with Scala and Spark》,另外有些相关书籍也可以参考,比如《Spark快速大数据分析》等。
自我考核:能够使用Spark的Scala API来进行大规模的数据分析及处理,完成lag feature之类的特征工程处理。
JVM的原理学习,Scala/Java都是JVM上运行的优秀语言,其背后是一个非常大的生态,包括在Web,Android,数据基础架构等方面有广泛的应用。JVM相比Python虚拟机,发展更加成熟,有一套非常完善的JDK工具链及衍生的各类项目,便于开发者debug,调优应用。这方面推荐学习周志明的《深入理解Java虚拟机》。
自我考核:理解JVM GC原理,能通过JDK中相关工具或者优秀的第三方工具如arthas等,排查分析Spark数据应用的资源使用情况,GC profiling,hot method profiling等,进而进行参数优化。
计算机语言理论。Programming Language作为计算机科学的一个重要分支,包含了很多值得深入研究的主题,例如类型论,程序分析,泛型,元编程,DSL,编译原理等。这方面的很多话题,在机器学习方面也有很多实际应用,比如TVM这类工作,涉及到大量编译原理的应用,知乎大佬“蓝色”也作为这个领域的专家在从事深度学习框架相关的工作。llvm, clang作者Chris Lattner也加入Google主导了Swift for Tensorflow等工作。Scala作为一门学术范非常强的语言,拥有极佳的FP,元编程等能力支持,强大的类型系统包括自动推理,泛型等等高级语言特性,相对来说是一门非常“值得”学习的新语言,也是一个进入PL领域深入学习的"
Java中,时间戳的精度是13位,而在Php中则是10位,在api接口开发中就要相互的转换。
java => php 我的方法:截取得到的时间戳的前十位,可以用字符串截取函数substr()
substr(字符串,0,10)
php => java 对获取的时间戳乘以1000即可
拓展:
PHP可以用strtotime()函数:将任何字符串形式的日期,时间转换成对应的Unix 时间戳。反之则用 date("Y-m-d");
用法:strtotime($str)
目录
一、安装环境
二、pg数据库安装包下载
三、安装依赖包
四、安装postgres
五、创建用户组postgres并创建用户postgres 六、创建postgresql数据库的数据主目录并修改文件所有者
七、配置环境变量
八、切换用户到postgres并使用initdb初使用化数据库
九、配置服务
十、设置PostgreSQL开机自启动
十一、开始测试
一、安装环境 postgresql-11.1CentOS-6.4注意:确认linux系统可以正常连接网络,因为在后面需要添加依赖包。 二、pg数据库安装包下载 下载地址:http://www.postgresql.org/ftp/source/
选择要安装的版本进行下载:
三、安装依赖包 在要安装postgresql数据库的Linux服务器(hostname:weekend02)上执行以下命令安装所需要的依赖包:
yum install -y perl-ExtUtils-Embed readline-devel zlib-devel pam-devel libxml2-devel libxslt-devel openldap-devel python-devel gcc-c++ openssl-devel cmake
四、安装postgres 1、在根目录下新建pgsql文件夹,并将pgsql的压缩包移入。
[root@weekend02 pgsql]# ls postgresql-11.1.tar.gz [root@weekend02 pgsql]# pwd //pgsql 2、解压压缩包
[root@weekend02 pgsql]# tar -zxvf postgresql-11.1.tar.gz 3、进入解压后的文件夹 [root@weekend02 pgsql]# cd postgresql-11.1 [root@weekend02 postgresql-11.1]# ls aclocal.m4 configure contrib doc HISTORY Makefile src config configure.in COPYRIGHT GNUmakefile.in INSTALL README 4、编译postgresql源码
一、IPSec VPN场景特点 1、一般用于总部和分支机构,中间通过互联网线路传输数据,保证数据的安全传输。
2、机密性 : 数据加密保护。
3、完整性:对数据进行认证,确保数据没有篡改。
4、防重放性:防止恶意用户进行攻击。
二、 IPSec VPN参数 1、AH: 数据的完整性,无法加密
2、ESP:对IP报文的加密
3、IKE:协商AH和ESP使用的算法 , 建立和维护安全联盟SA
建立SA:手工和动态协商两种方式
IPSec 传输和隧道两种模式
三、配置步骤 1、网络互联互通
2、配置ACL
3、安全提议
4、安全策略
5、应用
四、IPSec配置 1、R1 R2关键配置:
[R1]ip route-static 192.168.2.0 255.255.255.0 20.1.1.2 //实现路由可达
[R2]ip route-static 192.168.1.0 255.255.255.0 20.1.1.1 //实现路由可达
R1和R2配置ACL,思路一样此处R2配置略。
[R1]acl number 3001 //配置定义ACL感兴趣流进行IPSec加密的数据
[R1-acl-adv-3001]rule 5 permit ip source 192.168.1.0 0.0.0.255 destination 192.168.2.0 0.0.0.255
[R1]ipsec proposal IPSEC //创建IPSec安全提议
[R1-ipsec-proposal-IPSEC]esp authentication-algorithm md5//esp加密算法使用MD5
R1和R2分别配置安全策略。R2配置思路一样。
[R1-ipsec-policy-manual-IPS1-10]di th
ipsec policy IPS1 10 manual //配置安全策略
文章目录 前言一、程序所用到的函数1、fork函数2、pipe函数3、execvp函数4、dup2函数5、waitpid函数6、getcwd函数和chdir函数7、strtok函数7、fgets函数 二、程序所实现的功能三、程序功能的实现四、执行效果五、总结 前言 最近学习了fork、pipe、exec族等的linux系统调用函数,现在将这几天所学的结合起来,做一个简单地shell终端。
一、程序所用到的函数 1、fork函数 定义:pid_t fork(void)
功能:创建一个子进程
使用例程
//包含的头文件 #include <sys/types.h> #include <unistd.h> pid_t pid; pid = fork(void); if(pid<0){}//表示创建失败 else if(pid==0){}//表示子进程 else if(pid>0){}//表示父进程 pid为子进程的PID 2、pipe函数 定义:int pipe(int pipefd[2]);
功能:创建一个管道 pipefd[0]为读端 pipefd[1]为写端,读端写端实质是两个文件描述符
使用例程
//包含头文件 #include <unistd.h> int fd[2],ret; ret = pipe(fd); if(ret==-1){}//表示创建失败 3、execvp函数 定义:int execvp(const char *file, char *const argv[]);
功能:会根据当前系统环境变量,找到file执行,传入参数为 argv[] 指针数组 执行之后,当前进程的所有内容会被替换
使用例程
//包含头文件 #include <unistd.h> char *argv[] = {"ls", "-al", NULL};//最后一个参数要为NULL,表示传入的参数到这里就已经结束 execvp(argv[0], argv);//执行ls命令 4、dup2函数 定义:int dup2(int oldfd, int newfd);
今天新pull的项目启动时,报错:
class path resource [xxx.class] cannot be opened because it does not exist
经确认target目录下存在xxx.class,但是还是报此错;
尝试删除所有target文件夹,重新build项目启动后解决,项目正常启动
(一)线性表的介绍 线性表:线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
(1)逻辑上是线性结构,物理结构连续——顺序表。
(2)逻辑上是线性结构,物理结构不连续——链表。
(二) 顺序表基本运算的实现 链接: 顺序表基本运算的实现(第二章:线性表)
(三) 线性表顺序存储的应用: 问题: 已知长度为n的线性表A采用顺序存储结构,设计算法,删除线性表中所有值为x的数据元素。
要求: 时间复杂度为O(n)、空间复杂度为O(1)的算法
一般解法: 用基本运算实现
void delnode1(SqList *&L,ElemType x) { int i; ElemType e; 查找第1个值域与x相等的元 素的逻辑位序。若这样的元 素不存在,则返回值为0 while((i=LocateElem(L,x))>0) { ListDelete(L, i, e); } //删除顺序表L的第i个元素 } 这样的解法会消耗大量的时间,假设数组的长度为n,要删除第一个值为x下标为 i 的元素,就要把整体的位置向前移动 n-i 个位置,删除其它一个值为x的元素,也是需要移动所被删除元素之后的那些元素的位置!
举个🌰栗子吧,就像排队买东西,第一个买完东西的人走掉了,后面的每个人都要向前移动一个位置。每走掉一个人就要向前移动。
高级解法: 复制要保留的元素,新的空间存在于内存中,是暂时的,结束后会释放。
算法
void delnode1(SqList *&L,ElemType x) { int k=0,i; //k记录非x的元素个数 for (i=0; i<L->length; i++) if (L->data[i]!=x) { L->data[k]=L->data[i]; k++; } L->length=k; } 算法思想:
方法1.(1)修改index文件的host值,将localhost换成0.0.0.0,此时访问是0.0.0.0:80xx
(2) 可在build/webpack.dev.conf.js中找到
devServer:--添加
useLocalIp: true,
方法2.package.json中
scripts:
dev:最后添加 --host 0.0.0.0
原因:
webpack-dev-server 配置 host 时,默认是localhost。如果想被外部访问,需要
gif动态表情是聊天沟通活跃气氛常用的方式,有趣好玩的gif动态表情图能够更好的带动聊天的氛围,并且能够减少尴尬的气氛,一半获取gif动态表情的方式都是从网上找,或者将好友发布的表情进行收藏使用,那么怎样才能自己制作专属自己的gif动态图呢?接下来教大家使用手机视频转gif(https://www.gif.cn/)功能,在线制作gif的方法。
打开手机自带浏览器,搜索gif中文网,选择“添加视频”功能,上传用来制作gif的视频。
在弹窗中,找到gif截取的第一个画面的时间,然后点击开始取图,点击完成取图,获取最后一个画面,然后点击取图完成,跳转到首页。
设置生成gif动图的宽或者高,设定延迟值,如果想要添加水印的话,可以在水印设置中输入文字,然后调整摆放在图片的位置,或者删除链接即可生成无水印动图,勾选压缩选项,调整图片质量保证gif动图生成的清晰度,点击开始生成gif。
gif转换生成之后,在弹出层查看效果,并点击下载图片,即可下载到手机中。
在上一篇博客 《使用Intel RealSense D435i自制离线数据集跑通BundleFusion》 中,我们主要介绍了如何自制离线数据集跑通 BundleFusion 。在这篇博客中,我们对于格式转换过程中所涉及的 bag 文件解析、时间戳对齐以及制作源格式部分融合为 bag2org.py ,输入为 bag 文件,输出为 BundleFusion 所要求的输入源格式,从而避免程序间的频繁切换。
首先,需创建三个文件夹 depth、rgb 以及 result,分别用于存放深度图像、彩色图像以及源格式数据。
同时,创建并初始化 info.txt 文件。修改项主要为深度与彩色图像的分辨率、相机内参标定以及总帧数。其中,相机内参标定可通过 Intel RealSense Viewer 进行查看,总帧数将在程序执行过程中根据数据集的实际大小自动修改,可先任意设定一个值。
m_versionNumber = 4 m_sensorName = StructureSensor m_colorWidth = 640 # 修改项 m_colorHeight = 480 # 修改项 m_depthWidth = 640 # 修改项 m_depthHeight = 480 # 修改项 m_depthShift = 1000 m_calibrationColorIntrinsic = 582.871 0 320 0 0 582.871 240 0 0 0 1 0 0 0 0 1 # 修改项 m_calibrationColorExtrinsic = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 m_calibrationDepthIntrinsic = 583 0 320 0 0 583 240 0 0 0 1 0 0 0 0 1 # 修改项 m_calibrationDepthExtrinsic = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 m_frames.
XGBoost学习(一):原理
XGBoost学习(二):安装及介绍
XGBoost学习(三):模型详解
XGBoost学习(四):实战
XGBoost学习(五):参数调优
XGBoost学习(六):输出特征重要性以及筛选特征
完整代码及其数据
XGBoost输出特征重要性以及筛选特征 1,梯度提升算法是如何计算特征重要性的? 使用梯度提升算法的好处是在提升树被创建后,可以相对直接地得到每个属性的重要性得分。一般来说,重要性分数,衡量了特征在模型中的提升决策树构建中的价值。一个属性越多的被用来在模型中构建决策树,它的重要性就相对越高。
属性重要性是通过对数据集中的每个属性进行计算,并进行排序得到。在单个决策树中通过每个属性分裂点改进性能度量的量来计算属性重要性。由节点负责加权和记录次数,也就是说一个属性对分裂点改进性能度量越大(越靠近根节点),权值越大;被越多提升树所选择,属性越重要。性能度量可以是选择分裂节点的Gini纯度,也可以是其他度量函数。
最终将一个属性在所有提升树中的结果进行加权求和后然后平均,得到重要性得分。
2,绘制特征重要性 一个已训练的Xgboost模型能够自动计算特征重要性,这些重要性得分可以通过成员变量feature_importances_得到。可以通过如下命令打印:
print(model.feature_importances_) 我们可以直接在条形图上绘制这些分数,以便获得数据集中每个特征的相对重要性的直观显示,例如:
# plot pyplot.bar(range(len(model.feature_importances_)), model.feature_importances_) pyplot.show() 我们可以通过在the Pima Indians onset of diabetes 数据集上训练XGBoost模型来演示,并从计算的特征重要性中绘制条形图。
# plot feature importance manually from numpy import loadtxt from xgboost import XGBClassifier from matplotlib import pyplot from sklearn.datasets import load_iris # load data dataset = load_iris() # split data into X and y X = dataset.data y = dataset.target # fit model no training data model = XGBClassifier() model.
XGBoost学习(一):原理
XGBoost学习(二):安装及介绍
XGBoost学习(三):模型详解
XGBoost学习(四):实战
XGBoost学习(五):参数调优
XGBoost学习(六):输出特征重要性以及筛选特征
完整代码及其数据
Xgboost参数调优的一般方法 调参步骤:
1,选择较高的学习速率(learning rate)。一般情况下,学习速率的值为0.1.但是,对于不同的问题,理想的学习速率有时候会在0.05~0.3之间波动。选择对应于此学习速率的理想决策树数量。Xgboost有一个很有用的函数“cv”,这个函数可以在每一次迭代中使用交叉验证,并返回理想的决策树数量。
2,对于给定的学习速率和决策树数量,进行决策树特定参数调优(max_depth , min_child_weight , gamma , subsample,colsample_bytree)在确定一棵树的过程中,我们可以选择不同的参数。
3,Xgboost的正则化参数的调优。(lambda , alpha)。这些参数可以降低模型的复杂度,从而提高模型的表现。
4,降低学习速率,确定理想参数。
下面详细的进行这些操作。
第一步:确定学习速率和tree_based参数调优的估计器数目
为了确定Boosting参数,我们要先给其他参数一个初始值。咱们先按照如下方法取值:
1,max_depth = 5:这个参数的取值最好在3-10之间,我选的起始值为5,但是你可以选择其他的值。起始值在4-6之间都是不错的选择。
2,min_child_weight = 1 :这里选择了一个比较小的值,因为这是一个极不平衡的分类问题。因此,某些叶子节点下的值会比较小。
3,gamma = 0 :起始值也可以选择其它比较小的值,在0.1到0.2之间就可以,这个参数后继也是要调整的。
4,subsample,colsample_bytree = 0.8 这个是最常见的初始值了。典型值的范围在0.5-0.9之间。
5,scale_pos_weight =1 这个值时因为类别十分不平衡。
注意,上面这些参数的值知识一个初始的估计值,后继需要调优。这里把学习速率就设成默认的0.1。然后用Xgboost中的cv函数来确定最佳的决策树数量。
from xgboost import XGBClassifier xgb1 = XGBClassifier( learning_rate =0.1, n_estimators=1000, max_depth=5, min_child_weight=1, gamma=0, subsample=0.8, colsample_bytree=0.8, objective= 'binary:logistic', nthread=4, scale_pos_weight=1, seed=27) 第二步:max_depth和min_weight参数调优
我们先对这两个参数调优,是因为他们对最终结果有很大的影响。首先,我们先大范围地粗略参数,然后再小范围的微调。
注意:在这一节我会进行高负荷的栅格搜索(grid search),这个过程大约需要15-30分钟甚至更久,具体取决于你系统的性能,你也可以根据自己系统的性能选择不同的值。
网格搜索scoring = ‘roc_auc’ 只支持二分类,多分类需要修改scoring(默认支持多分类)
一、Java对象的内存布局 在JVM中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充,如下所示:
实例变量:存放类的属性数据信息,包括父类的属性信息,如果是数组的实例部分还包括数组的长度,这部分内存按4字节对齐。填充数据:由于虚拟机要求对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐,这点了解即可。 而Java头对象则是实现synchronized的锁对象的基础。
二、对象头形式 JVM中对象头的方式有以下两种(以32位JVM为例)
2.1 普通对象 2.2 数组对象 三、对象头的组成 3.1 Mark Word 这部分主要用来存储对象自身的运行时数据,如hashcode、gc分代年龄等。mark word的位长度为JVM的一个Word大小,也就是说32位JVM的Mark word为32位,64位JVM为64位。
为了让一个字大小存储更多的信息,JVM将字的最低两个位设置为标记位,不同标记位下的Mark Word示意如下:
其中各部分的含义如下:
lock:2位的锁状态标记位,由于希望用尽可能少的二进制位表示尽可能多的信息,所以设置了lock标记。该标记的值不同,整个mark word表示的含义不同。
bias_lock:对象是否启动偏向锁标记,只占1个二进制位。为1时表示对象启动偏向锁,为0时表示对象没有偏向锁。age:4位的Java对象年龄。在GC中,如果对象在Survivor区复制一次,年龄增加1。当对象达到设定的阈值时,将会晋升到老年代。默认情况下,并行GC的年龄阈值为15,并发GC的年龄阈值为6。由于age只有4位,所以最大值为15,这就是-XX:MaxTenuringThreshold选项最大值为15的原因。identity_hashcode:25位的对象标识Hash码,采用延迟加载技术。调用方法System.identityHashCode()计算,并会将结果写到该对象头中。当对象被锁定时,该值会移动到管程Monitor中。thread:持有偏向锁的线程ID。epoch:偏向时间戳。ptr_to_lock_record:指向栈中锁记录的指针。ptr_to_heavyweight_monitor:指向monitor对象(也称为管程或监视器锁)的起始地址,每个对象都存在着一个monitor与之关联,对象与其monitor之间的关系有存在多种实现方式,如monitor对象可以与对象一起创建销毁或当前线程试图获取对象锁时自动生,但当一个monitor被某个线程持有后,它便处于锁定状态。 64位下的标记字与32位的相似:
3.2 class pointer 这一部分用于存储对象的类型指针,该指针指向它的类元数据,JVM通过这个指针确定对象是哪个类的实例。该指针的位长度为JVM的一个字大小,即32位的JVM为32位,64位的JVM为64位。
如果应用的对象过多,使用64位的指针将浪费大量内存,统计而言,64位的JVM将会比32位的JVM多耗费50%的内存。为了节约内存可以使用选项+UseCompressedOops开启指针压缩,其中,oop即ordinary object pointer普通对象指针。开启该选项后,下列指针将压缩至32位:
每个Class的属性指针(即静态变量)每个对象的属性指针(即对象变量)普通对象数组的每个元素指针 当然,也不是所有的指针都会压缩,一些特殊类型的指针JVM不会优化,比如指向PermGen的Class对象指针(JDK8中指向元空间的Class对象指针)、本地变量、堆栈元素、入参、返回值和NULL指针等。
3.3 array length 如果对象是一个数组,那么对象头还需要有额外的空间用于存储数组的长度,这部分数据的长度也随着JVM架构的不同而不同:32位的JVM上,长度为32位;64位JVM则为64位。64位JVM如果开启+UseCompressedOops选项,该区域长度也将由64位压缩至32位。
四、monitor介绍 在Java虚拟机(HotSpot)中,monitor是由ObjectMonitor实现的,其主要数据结构如下(位于HotSpot虚拟机源码ObjectMonitor.hpp文件,C++实现的)
ObjectMonitor() { _header = NULL; _count = 0; //记录个数 _waiters = 0, _recursions = 0; _object = NULL; _owner = NULL; _WaitSet = NULL; //处于wait状态的线程,会被加入到_WaitSet _WaitSetLock = 0 ; _Responsible = NULL ; _succ = NULL ; _cxq = NULL ; FreeNext = NULL ; _EntryList = NULL ; //处于等待锁block状态的线程,会被加入到该列表 _SpinFreq = 0 ; _SpinClock = 0 ; OwnerIsThread = 0 ; } ObjectMonitor中有两个队列,_WaitSet 和 _EntryList,用来保存ObjectWaiter对象列表( 每个等待锁的线程都会被封装成ObjectWaiter对象),_owner指向持有ObjectMonitor对象的线程,当多个线程同时访问一段同步代码时,首先会进入 _EntryList 集合,当线程获取到对象的monitor 后进入 _Owner 区域并把monitor中的owner变量设置为当前线程同时monitor中的计数器count加1,若线程调用 wait() 方法,将释放当前持有的monitor,owner变量恢复为null,count自减1,同时该线程进入 WaitSe t集合中等待被唤醒。若当前线程执行完毕也将释放monitor(锁)并复位变量的值,以便其他线程进入获取monitor(锁)。如下图所示:
nextcloud 是基于云技术的工程教育平台,利用云技术,提高工程教育过程中教学、实验与创新的效率与效果。
1.今天只做nextcloud 记录与讲解,当前现在很多开源网盘很好用,都可以去尝试自己去搞一下
主要特点:
1>开源且免费,可以自定义插件开发
2>全客户端的支持,免费更好,ui还算不错
3>支持外挂磁盘,可以随时更改,不需要分块、加密和过多的文件控制、权限控制等等
4>搭建简单,建议使用docker
2.docker下载nextcloud
# 通过yum源安装docker sudo yum -y install docker # 启动docker sudo systemctl start docker # 开机自启 sudo systemctl enable docker #查看是否启动 systemctl status docker #下载nextcloud docker run -d -p 8080:80 nextcloud #执行以下命令,启动 Nextcloud 容器 docker run -d --restart=always --name nextcloud -p 80:80 nextcloud 简单解释一下上述命令: docker run :启动一个容器 -d:后台运行容器 --restart=always:Docker 重启的时候容器也会重启 --name nextcloud:命名容器的 name 为 nextcloud,可以替代容器 id 使用 -p 80:80:将容器的 80 端口映射到服务器的 80 端口 nextcloud:要启动的镜像名称 #查看容器是否正常运行 docker ps 出现以下一串内容说明容器启动
1. no module named rospkg 首先在终端使用python -V看一下当前环境使用的python版本,如果版本不是python2.7则需要更改到python2.7。
如果是之前系统安装了anaconda或者miniconda则需要在bashrc里面屏蔽其环境。如果是之前切换了版本则使用 sudo update-alternatives --config python 切换回python2.7 如果此时依然出现这个错误,则可能是没有安装这个包,sudo pip install rospkg安装,若安装后仍然添出错,则可能是没有加python2.7的环境变量,使用命令
echo $PYTHONPATH 查看是否有包含
/usr/lib/python2.7/dist-packages 没有则输入
export PYTHONPATH=$PYTHONPATH:/usr/lib/python2.7/dist-packages 或将其者添加到bashrc里面。此时编译应该不会再报错。
注意:如果build目录下之前有编译生成的文件,在调整后再次编译之前最好将其删除重新编译。原因是之前生成的文件中包含原有环境变量,如果再次编译依然会加载原有的环境。
2.在编译ROS接口时出现的系列错误 GeometricCamera.h、KannalaBrandt8.h、Pinhole.h文件找不到 这三个文件其实在 ORB_SLAM3/include/CameraModels 目录下,可以将其复制到include目录下即可。
rospack found package "ORB_SLAM2" 将src里面的所有源码中的ORB_SLAM2改为ORB_SLAM3即可。
如果之前编译过ORB_SLAM其他版本,可能会出现找不到boost库的情况 在cmakelist里面${LIB}里面添加boost_system boost_filesystem即可。
#include<iostream>
using namespace std;
//mutable
int main00()
{
int a = 10;
//auto f = [a]() {
// return ++a;//[a]只是单纯的将a捕获住了,a的性质仍然为const,不能修改,所以报错。
// //如果想要修改a的值,需要加关键字mutable
//};
//按值捕获,所以内部的a无论如何修改都不会影响外面的值,所以a的值为10
auto f = [a]()mutable {//使用mutable捕获的时候,在匿名函数的作用于范围内,
//这个a是独自拥有的拷贝,和main函数里面的a不是同一份数据
//不会影响外部的a,维持的是自己的变量。
return ++a;
};
auto f2 = [a]()mutable {
return ++a;
};
cout << f() << endl;//11
cout << f2() << endl;//11,与上一个lambda表达式的a的值没有关系。
cout << f() << endl;//12
cout << f2() << endl;//12
cout << a << endl;//10
return 0;
链表翻转、插入、删除 反转
class Solution { public ListNode reverseList(ListNode head) { if(head==null||head.next==null){ return head; } ListNode cur=head; ListNode reversehead=null; ListNode temp=null; while(cur!=null){ temp=cur.next; cur.next=reversehead; reversehead=cur; cur=temp; } return reversehead; } } 删除链表节点
class Solution { public ListNode deleteNode(ListNode head, int val) { ListNode dummyhead=new ListNode(0);//采用了虚拟头节点 dummyhead.next=head; ListNode cur=head; ListNode pre=dummyhead; while(cur!=null){ if(cur.val==val){ pre.next=cur.next; break; } pre=cur; cur=cur.next; } return dummyhead.next; } } 链表中倒数第K个结点
class Solution { public ListNode getKthFromEnd(ListNode head, int k) { if(k==0||head==null){ return null; } ListNode first=head; ListNode second=head; for(int i=0;i<k-1;i++){ second=second.
文章目录 5GIoT物联网场景5G专网技术专网5G专网要求WIFI 6、LTE专网和5G专网5G专网七大部署方案挑战部署案例 Local 5G 5G 今天有幸接触到5G分享,就在网上搜搜看,就当是了解一下新方向。以下内容来源在文章结尾标明。
IoT物联网场景5G专网技术 5G专用网络(private 5G network)是一种局域网(LAN),它将使用5G技术创建具有统一连接性、优化服务和特定区域内安全通信方式的专用网络 。此前,机构曾预测2020年全球5G专网市场规模将达到9.197亿美元, 2020年至2027年间的复合年增长率将达到37.8%。而北美将以31.2%的份额在5G专网市场中占主导地位。
专网 早在2/3/4G时代,专网的概念就有了,对我们来说并不陌生。所谓专网,就是指在特定区域实现网络信号覆盖,为特定用户提供网络通信服务的专用网络。公网与专网的区别主要在于公网为社会大众服务,而专网为特定对象服务。
5G网络有三大特点:高带宽、低延迟、多接入
但很多时候,企业并不是同时需要这些业务特性。另外,有的企业希望可以获得对5G网络的所有控制权、高度的可靠性、安全性、隐私性等,公网无法完全满足这些特定需求。
5G专网提供了企业定制化网络的自由度,可以根据使用场所、工作类型提供不同的配置,在隐私和安全方面都有明显的优势。
5G专网要求 Availability, Security, Quality of service, Interworking, Reliability
高可用性:意味着用户可以始终使用该网络服务,可以确保最大的可用性。
可靠性:是指在预定持续时间内高可靠地传输一定数量业务的能力,需要足够的网络覆盖范围和容量,以及强大的业务切换功能。
互通:与公网互通是一项重要功能,例如医疗救护车等关键服务从一个网络迁移到另一个网络(例如从专网到公网)时需要服务连续性,这就要求网络之间需要一定程度的集成。
服务:质量QoS包括吞吐量、延迟、抖动、丢包率等,在专用频谱上运行专用网络可以得到更好地控制。此外,可以针对专用网络部署中的特定需求量身定制不同服务的系统性能和资源使用。
安全性:专用网络有望提供全面的端到端安全性,以确保信息、基础架构和人员免受威胁。专用网络可以利用网络隔离、数据保护和设备/用户身份验证来保护关键资产,企业还可以控制保留数据主权,以确保敏感信息保留在本地。
WIFI 6、LTE专网和5G专网 与专用蜂窝网络相比,Wi-Fi的部署更加快速、简便且便宜,专用Wi-Fi网络在工厂中也已经开始使用,通常用于一些非关键应用。
在拥有完整的5G工业网络之前,一些企业可能会使用专用LTE网络作为过渡, LTE的覆盖范围和移动性比固定以太网或Wi-Fi大,通常是工业环境中实现连接的首选技术。
例如,全球最大自动化码头洋山港就是基于5.8GHz的LTE打造的工业无线网络,“区域内将不再有人,完全实现自动化,不仅岸桥不需要人驾驶,可以后台操作,连集卡也不再需要,直接由自动运行的AGV小车装载运输货物。”;英国Ocado也部署了一个专用LTE网络,以控制物流中心的1,000个快速移动的机器人在线处理订单;诺基亚利用专用LTE网络(4.9G)使基站工实现了厂自动化业务。
5G专网七大部署方案 目前5G专网主要有以下七大部署方案:
企业自建5G专网(本地5G频段、完全私有、不共享)
企业基于专网频段,部署全套5G网络(gNB,UPF,5GC CP,UDM,MEC)。这里使用的频谱是私有5G频谱,而不是运营商的授权频谱。企业自建的5G专网隐私与安全性高、具有超低延迟、独立可控性。
但自建专网部署成本高,普通企业特别是小型企业无法承担购买和部署全套5G网络的费用,另外后期还需要一些专业的运维人员来维护网络(代价可能比部署的成本还要高)。
运营商帮助企业构建5G专网(基于运营商的5G频段,完全私有,不共享),与第一种方案部署方式相似,唯一的区别是,使用的是运营商许可的5G频段来构建和运行5G专网。
公网和专网之间RAN共享。专网和公网之间仅共享5G基站(gNB)(RAN共享),而UPF、5GC CP、UDM和MEC部署在企业中,并于公网在物理上隔离。
属于专网的数据流量被传送到企业中的专网UPF,属于公网的数据流量交付给运营商边缘云的UPF。换句话说,内部设备控制的专用网络流量仅保留在企业中,而像语音和Internet之类的公共网络服务流量则被传输到运营商的网络。
公网和专网之间RAN和控制平面共享。专网和公网之间共享5G基站(gNB)和5GC CP、UDM(RAN和控制平面共享),专用的UPF、MEC内置于企业中,企业专网的gNB和UPF通过N2、N4接口连接到运营商的网络并由其管理。这种部署方案相较于前几种,企业专网的设备信息存储在运营商的服务器中,而不是企业内部,因此在私密性方面会稍弱。
公网和专网之间RAN和核心共享(端到端网络切片)。专网与公网共享UDM、5GC CP、UPF、MEC和5G基站,也就是端到端网络切片,用户信息和数据流量的安全性取决于网络切片能力,但与前几种方案相比,这种架构的成本最低。
N3 LBO(Local Breakout,本地疏导):韩国SK Telecom的案例。企业引入了MEC数据平面和MEC应用,运营商的移动边缘平台(MEP)通过Mp2接口将流量规则发送到MEC DP。MEC DP查看来自gNB的所有GTP隧道的数据包的目标IP地址(GTP Decap),并将用户IP包路由到内部专用网络。
与方案3和方案4不同的是,通过添加低成本的MEC DP(实际上是SDN/P4交换机),可以大大降低构建专用5G网络的成本,而无需购入昂贵的UPF设备。
F1 LBO(Local Breakout):韩国KT案例。与方案6相同,区别在于仅部署了企业中的RU/DU,并且CU放置在移动网络的边缘云中,专用网络流量是从F1接口本地断开,而不是从N3接口。
挑战 1.频谱问题
建立专网不是一件容易的事,目前网络切片仍处于发展阶段,其他几种5G专网部署方式面临的关键问题还是频谱的获取。频谱资源是有限的,并非随需随得,在大多数国家,频谱被视为一种自然资源,其使用受到国家主管部门的控制,国家主管部门根据国家的需求分配资源。
在专用频谱难以获取的情况下,共享频谱和非授权频谱也不失为建立私网的好方法,越来越多的运营商也开始投资非授权和共享频谱资源。共享频谱是一种“轻授权”的频谱使用方式,某些国家监管机构会出台一些共享使用的频谱使用制度,行业用户可以采用共享频谱部署其专有网络。非授权频谱是一个公共资源,企业机构都可以公平接入,因此需要更精细的频谱规划技术,来减少互相之间的干扰。
2.国家政策
专网想要大规模地部署,除了频谱技术的不断发展外,还需要国家的支持。目前一些国家正在思考开放更多的频谱资源,提供政策保障,让5G专网能够快速发展。
根据用户ID查询数据
1,修改映射配置文件UsersMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.lying.mapper.UserMapper"> <!--根据用户ID查询用户--> <select id="selectUsersById" parameterType="int" resultType="com.lying.pojo.Users" > select * from users where userid=#{suibian} </select> </mapper> 2,修改UserDao接口
UserDao.java
package com.lying.dao; import com.lying.pojo.Users; import java.io.IOException; import java.util.List; /** * @Author:Lying * @Date:2020/8/30 * @Description:com.lying.dao * @version:1.0 */ public interface UsersDao { Users selectUsersById(int userid) throws IOException; } 3,修改UserDao接口实现类
UserDaoImpl.java
package com.lying.dao.com.lying.dao.impl; import com.lying.dao.UsersDao; import com.lying.pojo.Users; import org.apache.ibatis.io.Resources; import org.
在实际的应用和工作当中, 我们经常会遇到在海量的数据当中寻找出前K个最大值或最小值的问题, 为了实现这个功能, 我们最先想到的方法可能就是排序, 在排序之后的序列当中取出前K个即可, 这样的方法确实可以, 但是存在一定的问题, 千万不要忘了这个问题的前提海量数据, 这就也就是说当数据规模过大内存放不下的时候, 我们再去使用常见的排序就无法解决.
因此, 对于这种海量数据的TopK问题, 一种经常使用的方法就是借助堆去解决
使用堆去解决TopK问题的原理 首先我们需要考虑清楚, 我们需要建立一个大堆还是小堆.
如果我们需要的是前K个最大值, 那么建立可以存储K个值的小堆
如果我们需要的是前K个最大值, 那么建立可以存储K个值的大堆
我们那一种情况去距离说明, 假如我们需要取到海量数据前K个最大的值, 首先我们建立K个数据的小堆, 因为我们建立的是小堆, 这也就是说此时堆顶的数据是最小的! 因此, 接下来的操作就是, 将剩下的数据依次拿出来与堆顶数据做比较, 假如当前数据大于堆顶数据, 就删除堆顶数据, 插入当前数据, 最终堆中所存储的K个值就是我们想要的.
在C++的STL库中提供了优先级队列 priority_queue ,默认为大堆, 可以通过传入仿函数的方式改变优先级队列的优先级.
应用场景 关于时间复杂度: 假设数据量为n, 要找到TopK元素, 堆每次插入和删除的时间复杂度为O(logK). 在最坏的情况下, 对于每一个元素都需要进行堆的插入和删除, 也就是说最坏的时间复杂度为O(nlogK), 最好的情况是, 前K个元素即为我们要寻找的TopK, 这个时候堆不需要调整, 此时时间复杂度为O(n).
使用场景 关于TopK的使用场景非常多, 比如统计前K个高频元素, 海量字符串查询记录, 某天访问网站次数最多的前K个IP等等, 这些都属于TopK问题, 这里给出一个TopK问题的题目, 可以做一做, 加深影响.
前 K 个高频元素
代码示例:
class Solution { public: vector<int> topKFrequent(vector<int>& nums, int k) { vector<int> ret; unordered_map<int, int> m; for (int i = 0; i < (int)nums.
Controller ApplicationController Annotation **@RestController //source code @org.springframework.web.bind.annotation.RestController @Controller @ResponseBody @Target(value={TYPE}) @Retention(value=RUNTIME) @Documented A convenience annotation that is itself annotated with @Controller and @ResponseBody. Types that carry this annotation are treated as controllers where @RequestMapping methods assume @ResponseBody semantics by default.
@RequestMapping; @org.springframework.web.bind.annotation.RequestMapping @Mapping @Target(value={METHOD, TYPE}) @Retention(value=RUNTIME) @Documented Annotation for mapping web requests onto methods in request-handling classes with flexible method signatures. Both Spring MVC and Spring WebFlux support this annotation through a RequestMappingHandlerMapping and RequestMappingHandlerAdapter in their respective modules and package structure.
2018-8-18SQL 结构化查询语言 structured query language sql 语句对于不同数据域库有微小差距 结构化查询语言 structured query language 1. DDL数据定义语言 create 创建表,视图、索引…
drop 删除表、视图、索引…
alter 修改
truncate 截断
2.DML数据操控语言(90%) insert 插入数据
update修改
delete 删除
select 查询
3.DCL数据控制语言 grant 授权
revoke 回收权限
4. TCL 事务控制语言 transaction control start transaction 开始事务(begin)
commit
rollback
结构化查询语言 (祥) 1.DDL unique 唯一
not null 非空
primary key 主键 (只要有一个)
foreign key 外键 (需要引用另外一个表的主键或唯一列)
联合唯一约束
primary key (列名1,列名2) /组 (复)合主键/
2.1 alter 修改 desc +组名 显示表
c++ string功能函数 一. string的构造函数的形式二. string的大小和容量三. string的字符串比较四. string的插入:push_back() 和 insert()五、string拼接字符串:append() 、 +六、 string的遍历:借助迭代器 或者 下标法七、 string的删除:erase()八、 string的字符替换九、string大小写转换:tolower() 和 toupper() 或者 STL中的 transform 算法十、 string的查找:find十一、 string的排序十二、 string的分割/截取字符串:substr() 一. string的构造函数的形式 string str:生成空字符串
string s(str):生成字符串为str的复制品
string s(str, str_begin, str_len):将字符串str中从下标strbegin开始、长度为strlen的部分作为字符串初值
string s(cstr, char_len):以C_string类型cstr的前char_len个字符串作为字符串s的初值
string s(num, char):生成num个c字符的字符串
string s(str, str_index):将字符串str中从下标str_index开始到字符串结束的位置作为字符串初值
string str1; //生成空字符串
string str2(“123456789”); //生成"1234456789"的复制品
string str3(“12345”, 0, 3); //结果为"123"
string str4(“012345”, 5); //结果为"01234"
string str5(5, ‘1’); //结果为"11111"
string str6(str2, 2); //结果为"3456789"
二. string的大小和容量 size()和length():返回string对象的字符个数,他们执行效果相同。
目录 前言一、我的思考二、图解出现的原因三、解决问题 前言 问题来自知乎朋友:https://www.zhihu.com/question/277812143
开启10000个线程,每个线程给员工表的money字段【初始值是0】加1,没有使用悲观锁和乐观锁,但是在业务层方法上加了synchronized关键字,问题是代码执行完毕后数据库中的money 字段不是10000,而是小于10000 问题出在哪里?
Service层代码:
@Transactional public synchronized void increaseMoneyWithPessimistickLock(Integer id){ Employee employee = synDao.findByIdWithPessimistickLock(id); logger.debug(employee.getMoney() + "==============================="); final Integer oldMoney = employee.getMoney(); logger.debug("oldMoney: {}", oldMoney); employee.setMoney(oldMoney + 1); synDao.updateEmployee(employee); } SQL 代码(没有加悲观锁/乐观锁):
简单来说:多线程跑一个使用synchronized关键字修饰的方法,方法内操作的是数据库,按正常逻辑应该最终的值是10000,但经过多次测试,结果是低于10000。这是为什么呢?
一、我的思考 既然测试出来的结果是低于1000,那说明这段代码不是线程安全的。不是线程安全的,那问题出现在哪呢?众所周知,synchronized方法能够保证所修饰的代码块、方法保证有序性、原子性、可见性。
讲道理,以上的代码跑起来,问题中Service层的increaseMoney()是有序的、原子的、可见的,所以断定跟synchronized应该没关系。
(参考我之前写过的synchronize锁笔记:Java锁机制了解一下)
既然Java层面上找不到原因,那分析一下数据库层面的吧(因为方法内操作的是数据库)。在increaseMoney()方法前加了@Transcational注解,说明这个方法是带有事务的。事务能保证同组的SQL要么同时成功,要么同时失败。讲道理,如果没有报错的话,应该每个线程都对money值进行+1。从理论上来说,结果应该是10000的才对。
(参考我之前写过的Spring事务:一文带你看懂Spring事务!)
根据上面的分析,我怀疑是提问者没测试好(hhhh,逃),于是我也跑去测试了一下,发现是以提问者的方式来使用是真的有问题。
@RestController public class EmployeeController { @Autowired private EmployeeService employeeService; @RequestMapping("/add") public void addEmployee() { for (int i = 0; i < 1000; i++) { new Thread(() -> employeeService.
在装双系统的时候,会遇到磁盘分区的问题。因此去网上查找了方法,在此做个笔记记录一下。
1.打开磁盘管理
右击我的电脑,选择管理,在弹出的界面选择存储下面的磁盘管理;
或者windows+x键,选择磁盘管理。如下图所示。
2.选择想要切分的磁盘,进行切分。
如想切分D盘,右击,选择压缩卷,则自动扫描,查询压缩空间。扫描完成后,输入想压缩的空间大小。如下图。点击压缩。
3.对切分出的空间进行设置。
如上图,绿色部分即为切分出的空间。
右击,选择新建简单卷,点击下一步,选择简单卷大小,选择盘符(即该盘的名称,A盘、B盘等),选择磁盘格式,一般选择’NTFS’系统,点击完成即可。
注:一般来说,机械硬盘和固态硬盘使用NTFS较为合适,存储能力和通用性好;而移动设备如U盘和移动硬盘等使用FAT64较为合适,读写速度相对较快。
9月1日,科大讯飞在北京召开以“声来 即王者”为主题的消费类新品发布会,科大讯飞轮值总裁胡郁、科大讯飞副总裁李传刚出席此次发布会,并在现场发布了讯飞智能录音笔SR901、SR702、SR101,讯飞首款智能TWS耳机iFLYBUDS四款新品。
科大讯飞轮值总裁胡郁表示,科大讯飞坚持“To B+To C"双轮驱动战略,让AI应用服务大众。秉承着助力用户高效办公、智慧生活的理念,讯飞消费者业务连续三年保持超过30%的高增速。随着讯飞智能硬件产品体系不断完善,C端营收占比在2020年上半年达 37.59%。在AI转写赛道上,我们希望讯飞消费者产品不仅为文字工作者的记录场景赋能,更成为每个人的知识管理工具,开启高效记录新时代。
目前,全新发布的讯飞智能录音笔SR702、SR101,讯飞智能耳机iFLYBUDS已在9月1日0点开启预售,9月9日0点在天猫京东等电商平台同步现货开售。而SR901将在9月下旬开启预售。新品预售期享有不同程度分期免息计划、预定金充抵、赠品等多重优惠,参与预售有机会赢得讯飞智能录音笔SR301。
讯飞智能录音笔全系列布局完成,继续领跑AI录音笔市场
科大讯飞此次发布三款智能录音笔新品,补全了智能录音笔全系列,覆盖了从入门、旗舰再到尊享版全线机型,为不同需求的消费者提供最满意的选择。
讯飞智能录音笔SR101是面向职场新人和学生推出的入门级新品,融便携体验、高性价比和智能体验于一身。其拥有星空灰、深海蓝、象牙白三种配色可选,标配1.4英寸触摸屏使得转写实时可见,同时搭载1颗定向麦克风+2颗矩阵麦克风的组合,四核处理芯片,8GB存储空间和1500mAh电池容量,在硬件配置上毫不妥协。SR101售价599元,转写终身免费并享有3年5GB云空间服务。
【讯飞智能录音笔SR101】
讯飞智能录音笔SR702则是讯飞继SR701之后的旗舰之作。SR702采用星空灰配色,一体设计的3D陶瓷背板和航空级铝合金,其采用高密度2600mAh大容量电池,搭载2颗定向麦克和6颗矩阵麦克风,配置3.5英寸高清屏幕,并配备800万像素数字变焦后置摄像头。而讯飞智能录音笔SR901尊享版采用钢琴黑全陶瓷机身,搭载6.01英寸AMOLED屏幕,64GB存储空间及4000mAh支持18W快充大容量聚合物锂电池。
【讯飞智能录音笔SR702】
讯飞智能录音笔SR901拥有豪华三摄配置和2颗哈曼MEMS定向麦克风+10颗全向麦克风。通过全面升级的转写引擎,SR702和SR901搭载了行业首发的离线转写、OCR图文识别、视频字幕等新功能,再次拓宽了转写记录的易用性和使用场景。SR702售价3699元,SR901售价5999元,两款产品购买随硬件赠送终身免费会员服务,包含转写和翻译服务等,同时自激活之日起,另赠3年20GB云空间服务。
【讯飞智能录音笔SR901】
上述三款新品均沿袭了讯飞智能录音笔的四大标准——识别准、录得远、录得清、语种全。识别准方面,讯飞智能录音笔新品语音识别模块采用基于深度全序列卷积神经网络的语音识别框架,识别准确率达98%;录得远方面,讯飞智能录音笔新品最远拾音距离均可达15米;录得清方面,讯飞智能录音笔新品采用AI算法降噪处理前端语音信号,保证拾音的准确性,并提供高清无损音质的音频格式;语种全方面,讯飞智能录音笔新品同样支持粤语、河南话、四川话、重庆话、云南话、贵州话、天津话、河北话、东北话、甘肃话、山东话、太原话12种方言转写、藏语、维吾尔语2种少数民族语言转写、中、英、日、韩、俄、法、越南、西班牙8种语言转写和IT科技、财经贸易、文化体育、医疗、政法、运营商、教育7大专业领域转写优化。同时,中英文混读识别功能也可在转写时自动识别夹杂着中英文的语音内容。
而得益于全新升级的转写引擎,讯飞智能录音笔SR901和SR702两款新品在行业率先搭载了离线转写功能。无需4G/WIFI网络,用户也能实现语音实时转文字、转写后的文字内容即刻保存,离线转写准确率高达95%,无惧断网环境。同时离线转写也防止了高度机密信息的泄露,保障了用户信息安全和特有转写需求的实现。同时,通过SR901和SR702的摄像头可将图片上的文字内容提取出来并实时呈现,便于用户实现重要音频和图文信息的混合记录,用于后期记录及整理。同时,这两款新品还支持录制视频、实时收音并实时生成字幕,同时后期也可编辑字幕,打造多场景重要信息记录的全新AI交互体验。
在讯飞智能录音笔前端降噪处理上,通过讯飞原创神经网络与传统信号处理深度结合的降噪算法(SSA-IME),可以有效降低环境干扰噪声,并有效消除干扰说话人的声音,从而大幅降低语音识别的处理难度。在无喇叭的情况下3-10米远距离提升相对30%,有喇叭的情况超远距离(20-50m)演讲场景效果达到90%以上。而为了满足用户快速出稿的需求,讯飞大力投入语音识别后处理技术并运用到讯飞智能录音笔上,先后上线语气过滤词、口语规整、文本语义分段、文本智能摘要等文本理解能力。针对多人交谈会议场景,上线了分离与ASR联合建模的说话人分离方案,说话人分离的准确率达到95%让用户能够快速检索到目标说话人数据,提升编辑体验。
讯飞首款TWS智能耳机发布,语音实时转写打造移动商务新标配
与讯飞智能录音笔三款新品同时发布的还有讯飞首款TWS智能耳机iFLYBUDS。凭借通话实时转写、智能拨号识别、通话译文对照三大核心AI功能,能够轻松满足商务人士在自驾、通勤、会议等多场景中,解放双手、重要信息记录和从容沟通的需求。
讯飞智能耳机iFLYBUDS采用珍珠白配色,弧形美学设计,耳机单只仅重4.6g,半入耳仿生设计,持久佩戴也舒适。该设备搭载旗舰级芯片,保证了连接的稳定性和超低延迟。此外,iFLYBUDS还拥有悦耳音质,通过智能降噪在机场、健身房等嘈杂环境也能带来清晰流畅的通话体验。iFLYBUDS支持智能语音助手,只要说“小飞小飞”即可快速唤醒语音助手。同时iFLYBUDS的特点还包括:支持轻击耳机交互,并且支持自定义功能;佩戴检测,摘下耳机时暂停播放,再次戴上音乐继续。不仅如此,讯飞智能耳机iFLYBUDS续航可以满足日常商务沟通。
讯飞智能耳机iFLYBUDS的核心功能之一通话实时转写支持常规电话和网络电话(微信语音、腾讯会议、钉钉语音、Skype、Zoom等),随时随地可以接听网络电话会议。且对于多人会议还支持自动区分讲话人,查找通话内容更加方便。通话开始时一键录音,通话过程转成文字,转写准确率在98%以上。而在通话结束后可以形成智能摘要,自动提炼重点内容,还支持对通话内容进行快速查找、多终端分享(手机端和电脑端)和编辑。
智能拨号识别则让讯飞智能耳机iFLYBUDS解决了商务人士的通讯录里联系人繁多,并且多重名、同音联系人的痛点,针对拨号对象重名、同音等情况,iFLYBUDS可通过多种方式区分,例如章子怡的章、立早章;归属地名称区分,例如北京的李总、科大讯飞的李总。避免复杂查找,拨号效率成倍提升。与Siri等语音助手相比,iFLYBUDS的语音拨号功能专注拨号,更智能、精准,具备明显的优势:说法更自然,只说姓名即可拨号;纯语音交互,无需看屏;一句搞定,避免重复。
而在外语电话交流场景中,面对行业术语、俚语等生僻的专业词汇,经常会遇到语言沟通障碍,针对这一点,iFLYBUDS专为商务人士打造的核心功能之三就是通话译文对照。它在英语通话时,可将通话内容实时转译为汉字,辅助英语沟通,是你耳朵上的助理翻译官,沟通更加自信、简单。未来将会支持更多的语种。
二十一年AI技术深厚积累,讯飞消费者新品让消费者买的放心
在发布会现场,科大讯飞副总裁李传刚表示“技术革新与消费升级双轮驱动,将出现巨大的颠覆式创新机会,并催生新的领导品牌。讯飞智能录音笔和讯飞智能耳机均是这一理念的实践。通过顶尖的AI语音技术、优质的硬件和软件三位一体,打造极致便捷的体验,帮助用户有效提升效率,享受高品质智慧生活。
除了优秀的市场成绩外,讯飞消费者产品也在业界获得高度认可,这和科大讯飞在智能语音领域二十一年的深耕分不开。以语音转写功能应用到的语音识别技术为例,早在2016年9月,在业界影响力最大、参赛队伍最多、水平最高的国际多通道语音分离和识别大赛CHiME-4中,科大讯飞包揽了全部三个项目的冠军;2018年再次包揽CHiME-5大赛全部四个项目的冠军并大幅刷新了各项目的最好成绩;2020年的CHiME-6,在被称为“史上最难的语音识别任务”中,科大讯飞不仅在给定说话人边界的多通道语音识别两个参赛任务上夺冠,更一鼓作气刷新自己在CHiME-5中46.1%的语音识别错误率冠军成绩,直降至30.5%。
而在说话人识别技术方面,近期在VoxSRC国际说话人识别比赛限定训练数据任务中(公开刷榜阶段),科大讯飞刷新世界纪录,等错误率(EER)降低到0.81%。同时,科大讯飞在学术界公开测试集合VoxCeleb1上取得0.63%的EER,是截止目前的State Of The Art(最好结果),上述两个新纪录表明科大讯飞说话人识别技术站在了世界前列。
前提因素 我是以前在本地已安装了Python的情况下,然后再安装的miniconda3。 不怎么经常使用anaconda各种包的,推荐使用miniconda。大部分踩坑,根据网上的博客解决了很多问题,在此总结了我遇到的问题和经验 不是很熟练markdown,请多谅解 下载 我是在官网下载的,速度还挺快的。官网地址:https://mirrors.bfsu.edu.cn/help/anaconda/
也可以在一些镜像源里下载
安装 一直点next,安装用户我选择“just me”,addpath那里我选择了第二个,没有选择第一个(好像是添加到环境变量),然后完成安装。
环境变量配置 控制面板——系统——高级设置(没打完)——环境变量——path—>编辑
加入miniconda安装文件的路径,我的安装路径是c:\Miniconda3.即c:\Miniconda3和c:\Miniconda3\Scripts和C:\Miniconda3\Library\bin
查看是否安装成功 开始界面会有anaconda的命令窗口
有些时候可能安装了,但是没有显示这个。
解决方法1:WIN+R——cmd——cd (miniconda安装的文件夹)
输入 python .\Lib_nsis.py mkmenus 然后出现什么什么sucessfully
更换conda源 这里我就不写了网上有很多,这是我当时就参考的一个链接更换conda源操作链接
https://blog.csdn.net/weixin_44003563/article/details/105057650?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.channel_param
卸载 在安装目录下的Uninstall-Miniconda.exe,这个只能卸载大部分文件,不能完全卸干净。别问我怎么知道的,我可是反复卸载安装,然后得出来的血泪教训。
不完全卸载miniconda方法:点击安装目录下的Uninstall-Miniconda.exe
完全卸载miniconda的方法如下:
安装卸载包(我自己乱说的)
conda install anaconda-clean 使用包进行卸载
anaconda-clean --yes 窗口显示了C:Users\(我的用户名).anaconda_backup\2020-09-01T115126,我看网上说这个好像是备份,反正我没管他
下一步:点击安装目录下的Uninstall-Miniconda3.exe
问题总结 遇到
An HTTP error occurred when trying to retrieve this URL. 或者time out 我一般都是在运行一次命令
参考博客 我在解决问题的时候看过很多博客,大概列出几个
https://blog.csdn.net/ITLearnHall/article/details/81708148?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
https://www.jianshu.com/p/edaa744ea47d
https://blog.csdn.net/qq_36015370/article/details/79484455
其他问题 【解决问题】RemoveError: ‘requests’ is a dependency of conda and cannot be removed from…:
装箱和拆箱 装箱:值 -> 对象。拆箱:对象 -> 值。 c#中的数据类型可以分为 值 和 引用。
值 包括byte,short,int,long,float,double,decimal,char,bool,enum,struct,变量直接存储数据,编译器分配内存 ;
引用。string,object,和 class 统称为引用类型。当声明一个类时,只在栈中分配一小片内存用于容纳一个地址,而此时并没有为其分配堆上的内存空间。当使用 new 创建一个类的实例时,分配堆上的空间,并把堆上空间的地址保存到栈上分配的小片空间中。
实际上 值 和 引用 都由基类System.Object继承而来,因此可以通过装箱和拆箱来相互转换。
装箱:值 -> 对象。 int val = 100; object obj = val; 对值类型在堆中分配一个对象实例,并将该值复制到新的对象中。按三步进行:
首先从托管堆中为新生成的引用对象分配内存(大小为值类型实例大小加上一个方法表指针和一个SyncBlockIndex)。然后将值类型的数据拷贝到刚刚分配的内存中。返回托管堆中新分配对象的地址。这个地址就是一个指向对象的引用了。 可以看出,进行一次装箱要进行分配内存和拷贝数据这两项比较影响性能的操作。
PS:o 和 i 的改变将互不影响,因为装箱使用的是 i 的一个副本
拆箱:对象 -> 值。 int val = 100; object obj = val; int num = (int) obj; 1、首先获取托管堆中属于值类型那部分字段的地址,这一步是严格意义上的拆箱。
2、将引用对象中的值拷贝到位于线程堆栈上的值类型实例中。
经过这2步,可以认为是同boxing是互反操作。严格意义上的拆箱,并不影响性能,但伴随这之后的拷贝数据的操作就会同boxing操作中一样影响性能。
PS:o 和 i 的改变将互不影响
什么时候会发生拆箱和装箱?
CLR对值类型进行装箱时,会将值包装在 System.Object 实例中并将其存储在托管堆中。拆箱将从对象中提取值类型。 装箱是隐式的;拆箱是显式的。
经常与网络打交道的IT男,经常碰到朋友、客户会问怎么我们,宽带明明是多少多少兆的,怎么下载时且没有那么多呢等问题。网络时代,基本每个家庭都装有宽带,比如10M、50M、100M等等,今天就给大家做个解释。
M也叫兆,实际生活中差不多为一百万,K为千,实际生活中为1000。由于计算机以2进制单位,所以是1024。
上面这个1024首先要说下,就好比我们的1千米跟1000米中的1000一样;
还有1kg跟1000g中的1000一个概念。
单位换算公式(注意 B、b 大小写)
1TB=1024GB
1GB=1024MB
1MB=1024KB
1KB=1024B
1B=8b(1Byte=8bit ,1字节=8位)Byte为字节,bit为位。
通过上面的图文解说,相信大家应该明白其实就是个单位换算问题。
在我们实际上网应用中,下载软件时常常看到下载速度显示为128KBps(KB/s),10KB/s等等宽带速率大小字样,因为运营商ISP提供的线路带宽使用的单位是比特(Byte),而一般下载软件显示的是字节bit(1字节=8比特),所以要通过换算,才能得实际值。
10Mb的带宽下载速率是多少呢(其实速率是要加上秒S的,我这里先将带宽,由于速率的单位总是秒,我就不多说了,不管你怎么换算最终都是秒s)。
10Mb=10*1024Kb(把M转换成K)
10240Kb=10240/8=1280KB(把小b转换成大B)
1280KB=1280/1024=1.25MB(数字长了不好看,在把K转换成M)
以上主要是让大家看出计算的每一步,方便理解,其实可以直接如下计算。
10Mb的下载速率=10Mb/8=1.25MB(除以8就是将小b转换成大B就可以了)
所以10Mb的宽带下载速率理论上最大值是1.25MB/s,网络就像我们的交通一样,不是理想状况的,总有拥堵,损耗什么的,所以一般下载在1MB/S就很正常了。
50M宽带下载理论值是50/8=6.25MB/s;
100M宽带下载理论值是100/8=12.5MB/s。
VeCloud微云网络的总部位于香港,并在中国北京和深圳设有分支机构,是一家面向企业提供云交换网络服务为核心业务的技术创新企业。基于创新的云网技术,以及优质的全球网络与IDC数据中心资源,推出了全球直连,快速可达的VeConnect平台,实现网络服务商、IDC数据中心、云服务商以及企业应用服务商的直连互通,为企业提供高效、安全、稳定、可靠的网络连接服务。
一、背景
主要介绍如何使用后端Django + 前端Vue 的技术栈快速地搭建起一套web项目的框架。 为什么使用Django和Vue?
Django是Python体系下最成熟的web框架之一,由于Python语言的易用性和受众面广,Django框架也因其能够快速开发网站应用的特性成为了中小型网站开发框架首选。
Vue是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
使用Vue作为前端框架,代替Django本身较为孱弱的模板引擎,Django则作为服务端提供api接口,使得前后端实现完全分离,更适合单页应用的开发构建。
二、环境准备
Django:
Python 3.7
Django 2.2.5 使用python自带的pip安装器安装。命令:pip install django即可 安装最新版本的django
Mysql 5.7 安装连接Mysql的库 pip3 install pymysql
Vue:
Node.js v14.3.0
官网下载:http://nodejs.cn
有关Vue的模块(包括vue)我们都使用node自带的npm包管理器安装
三、构建Django项目 首先使用Django来搭建web后端api框架。
1、mac os系统上执行pip3安装:
$pip3 install Django
2、查看安装是否OK:
$python3 -m django --version
3、创建工程(工程名为ATS_Web)
$django-admin startproject ATS_Web
如果命令不存在,寻找到django-admin,用下面的命令:
$ python3 /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/bin/django-admin.py startproject ATS_Web
4、创建应用(一个工程有多个应用)
$cd /Users/mac/ATS_Web
$python3 manage.py startapp myApp
5、在ATS_Web下的settings.py配置文件中,把默认的sqllite3数据库换成我们的mysql数据库, 并把app加入到installed_apps列表里:
# Database # https://docs.djangoproject.com/en/2.2/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.
文章目录 代码总结一下 PIL 和 cv2 打开图片的不同: 代码 第一部分展示了,使用 PIL 打开图片并且获得图片数据并转换成矩阵的过程第二部分展示了,使用 opencv 打开图片并且直接输出 矩阵的过程 import cv2 from PIL import Image import numpy as np import pandas as pd img = Image.open('1.jpg') # 使用 PIL 打开图片 data = img.getdata() # 获取图片的数据信息 class <'ImagingCore'> print(type(data)) data = np.array(data) # 把这个数据通过 numpy 转换成多维度的张量 print(data) print(data.shape) # 查看图片的 shape 信息 # = ======================== 分割线 img2 = cv2.imread('1.jpg') # 使用 cv2 来打开图片 print(img2) print(img2.shape) 通过比较可以发现, PIL 读取的数据是个二位的矩阵,第一维度的信息为图片的尺寸大小(长*宽)信息Opencv 读取的信息是个三维的数组,其中第一维度为行数,第二维度为列数,第三维度为通道的信息(b,g,r) 三通道。通过图示来看这两个的差别就是
问题描述: 笔者在试着用java读取深度模型时,在模型转化为byte[]传入Graph后,模型在读取输出的时候读取的维度不正确。
原因分析: 经过笔者的多次尝试,终于找到了问题的关键。问题出在h5转pb的过程中。下面是网上常见的h5转pb的python代码。使用如下代码所转化的pb文件,在使用java读取的时候就会出现输出的维度不是java想要的维度。
#*-coding:utf-8-* """ 将keras的.h5的模型文件,转换成TensorFlow的pb文件 """ # ========================================================== from keras.models import load_model import tensorflow as tf import os.path as osp import os from keras import backend #from keras.models import Sequential def h5_to_pb(h5_model, output_dir, model_name, out_prefix="output_", log_tensorboard=True): """.h5模型文件转换成pb模型文件 Argument: h5_model: str .h5模型文件 output_dir: str pb模型文件保存路径 model_name: str pb模型文件名称 out_prefix: str 根据训练,需要修改 log_tensorboard: bool 是否生成日志文件 Return: pb模型文件 """ if os.path.exists(output_dir) == False: os.mkdir(output_dir) out_nodes = [] for i in range(len(h5_model.
文章目录 前言一、传统RNN双向RNN深层双向RNN 二、LSTM第一层第二层第三层第四层 三、GRU四、 LSTM和GRU区别参考 前言 为了复习NLP自己的相关知识,整理一个博客
一、传统RNN 传统的RNN也即BasicRNNcell单元。内部的运算过程为,(t-1)时刻的隐层输出与w矩阵相乘,与t时刻的输入乘以u之后的值进行相加,然后经过一个非线性变化(tanh或Relu),然后以此方式传递给下一个时刻。
传统的RNN每一步的隐藏单元只是执行一个简单的tanh或者Relu操作。对于激活函数有遗忘的话,可以参考下面文章复习一下。(博主在前几天的面试就被问到了最基本的激活函数问题)
神经网络激活函数汇总(Sigmoid、tanh、ReLU、LeakyReLU、pReLU、ELU、maxout)
常用激活函数优缺点及性能对比
比如一个句子中有5个词,要给这5个词标注词性,那相应的RNN就是个5层的神经网络,每一层的输入是一个词,每一层的输出是这个词的词性。
聊聊文本的分布式表示: Distributional Representation和Distributed Representation的区别
RNN什么时候网络层次比较深呢?
RNN如果有多个时刻输入的时候,网络层次比较深,此时反向传播的路径比较长。反向传播是根据链式法则,如果开始的梯度小于1的话,则最后时刻的梯度几乎为0,则可理解为梯度消失;反之,若开始的梯度大于1的话,则最后时刻的梯度则非常大,可理解为梯度爆炸。这种情况下,开始应用Relu激活函数。
为什么应用Relu函数呢?
Relu函数在小于0时的梯度为0,大于0的时候梯度为1。使用Relu的好处:1 梯度容易求解;2 不会产生梯度消失或梯度爆炸。
双向RNN 双向RNN认为otot不仅依赖于序列之前的元素,也跟tt之后的元素有关,这在序列挖掘中也是很常见的事实。
深层双向RNN 在双向RNN的基础上,每一步由原来的一个隐藏层变成了多个隐藏层。
二、LSTM 优点:
可以在解决梯度消失和梯度爆炸的问题,还可以从语料中学习到长期依赖关系。
图中可以看出,t时刻有两个输出,上面代表长期输出,下面代表短期输出,用短期的输出与矩阵v运算得到t时刻的输出。
Tanh和sigmoid激活函数的优点?
首先tanh激活函数的范围是(-1,1),负的部分可以减一些信息,也即来控制忘记还是记忆信息,而sigmoid激活函数是用来表示记住多少的信息。
第一层 第一层是个忘记层,决定细胞状态中丢弃什么信息。把 ht-1 和 xt 拼接起来,传给一个Ct-1函数,该函数输出0到1之间的值,这个值乘到细胞状态 [公式] 上去。sigmoid函数的输出值直接决定了状态信息保留多少。比如当我们要预测下一个词是什么时,细胞状态可能包含当前主语的性别,因此正确的代词可以被选择出来。当我们看到新的主语,我们希望忘记旧的主语。
第二层 上一步的细胞状态 Ct-1已经被忘记了一部分,接下来本步应该把哪些信息新加到细胞状态中呢?这里又包含2层:一个tanh层用来产生更新值的候选项 Ct ,tanh的输出在[-1,1]上,说明细胞状态在某些维度上需要加强,在某些维度上需要减弱;还有一个sigmoid层(输入门层),它的输出值要乘到tanh层的输出上,起到一个缩放的作用,极端情况下sigmoid输出0说明相应维度上的细胞状态不需要更新。在那个预测下一个词的例子中,我们希望增加新的主语的性别到细胞状态中,来替代旧的需要忘记的主语。
第三层 现在可以让旧的细胞状态 Ct-1 与 ft (f是forget忘记门的意思)相乘来丢弃一部分信息,然后再加个需要更新的部分 it*Ct (i是input输入门的意思),这就生成了新的细胞状态Ct
第四层 最后该决定输出什么了。输出值跟细胞状态有关,把 [公式] 输给一个tanh函数得到输出值的候选项。候选项中的哪些部分最终会被输出由一个sigmoid层来决定。在那个预测下一个词的例子中,如果细胞状态告诉我们当前代词是第三人称,那我们就可以预测下一词可能是一个第三人称的动词。
三、GRU GRU(Gated Recurrent Unit)是LSTM最流行的一个变体,比LSTM模型要简单。
GRU 有两个有两个门,即一个重置门(reset gate)和一个更新门(update gate)。从直观上来说,重置门决定了如何将新的输入信息与前面的记忆相结合,更新门定义了前面记忆保存到当前时间步的量。如果我们将重置门设置为 1,更新门设置为 0,那么我们将再次获得标准 RNN 模型。使用门控机制学习长期依赖关系的基本思想和 LSTM 一致,但还是有一些关键区别:
线程 Thread 应用程序一进程为单位运行,一个进程可以分为一到多个线程
windows系统下可以通过任务管理器查看进程
Linux 下可以通过ps-fe
进程,线程都可以并行执行,CPU
---程序1 ---程序2 ---程序1 操作系统中有一个组价叫任务调度器,将cpu的时间分给不同的程序使用,微观上是串行执行(单核),宏观上是并行。(多核CPU才能真正实现并行)
好处:
1)多进程和多线程可以让程序不被堵塞。
2)充分利用多核CPU的优势,提高运行效率。
1.Java中的多线程 Thread类
创建线程方法1: Thread t =new Thread(){ public void run(){//运行 //线程需要执行的代码 //不能抛出检查异常,只能自己处理检查异常 } }; Thread t1=new Thread(){ @Override public void run() { for (int i = 0; i < 10000; i++) { System.out.println(Thread.currentThread()+"###############"); } } }; 启动线称 start();
Ctrl+ O 方法重写
并行(parallel)和并发(concurrent)
创建线程的方法2: 把线程和要执行的代码分开
Thread 代表线程
Runnable可运行的 (线程要执行的代码)
Runnable runnable= new Runnable(){ public void run(){ //要执行的代码 }; } Thread t = new Thread(runnable对象) t.
在线直达地址: https://chp.shadiao.app/
彩虹屁生成器的工作原理很简单, 每次打开页面或点击按钮,都会生成一句彩虹屁 t027-chp 我渴望你,想和你产生更多的联系,要和你交换香气和灵魂。有时候觉得,你应该遇见一个比我更好的人,可是我喜欢你的时候,觉得自己也是值得喜欢的。
月亮藏进云里,如果你已经睡了,那我要偷偷吻吻你。你比一百只猫猫加起来可爱,我呢,比一百只猫猫加起来好睡,你要不要来试试?
总想要透过你眼睛,
去找寻最原始的野性,
没想到最后却闯进,
一整座,森林的宁静。
世间万物皆苦,你明目张胆的偏爱就是救赎。
还没到迪士尼就见到公主了
谁的童话书又没合好,让公主跑出来了?
我第一次见你,就想到了可乐、奶茶、巧克力,我最爱的甜蜜。
夏季限定,本人半糖加冰。🍊
心动于你只在一瞬之间,痴迷于你却是余生每天!
与你一起的回忆被密封在琥珀里,每一个瞬间都闪闪发亮
通过开发者工具分析网页, 可以得知, 在浏览器访问以下链接,即可获得一句彩虹屁 https://chp.shadiao.app/api.php
小结 没有那个人不喜欢赞美~
如何定义 Java 中的方法 public class HelloWorld { //定义了一个方法名为 print 的方法,实现输出信息功能 public void print1() { System.out.println("Hello World"); } public static void main(String[] args){ //在 main 方法中调用 print 方法 HelloWorld test=new HelloWorld(); test.print1(); HelloWorld test1=new HelloWorld(); test1.print1(); } } public class HelloWorld { public static void main(String[] args) { // 创建对象,对象名为hello HelloWorld hello=new HelloWorld(); // 调用方法 hello.showMyLove(); } /* * 定义无参无返回值的方法 */ public void showMyLove() { System.out.println("我爱慕课网!"); } } public class HelloWorld { public static void main(String[] args) { // 创建名为hello的对象 HelloWorld hello = new HelloWorld(); // 调用hello对象的calcAvg()方法,并将返回值保存在变量avg中 double avg = hello.
一、使用步骤 虽然Runnable接口实现多线程比继承Thread类实现多线程方法要好,但是Runnable接口里的run方法并不能返回操作结果。为了解决这样的矛盾,java提供了Callable接口。
创建并启动有返回值的线程的步骤如下:
创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,且该call()方法有返回值,再创建Callable实现类的实例使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值使用FutureTask对象作为Thread对象的target创建并启动新线程调用FutureTask对象的get()方法来获得子线程执行结束后的返回值 二、源码 这个接口的源码如下:
@FunctionalInterface public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception; } call方法执行完线程的主体功能之后(类似于Runnable的run方法)会返回值,而返回值类型由Callable接口上的泛型决定。
以下是一个定义使用Callable接口的例子,定义了一个线程主体类:
class MyThread implements Callable<String>{ private int ticket=10; @Override public String call() throws Exception{ for(int i=0;i<200;i++){ if(this.ticket>0){ System.out.println("ticket="+ticket--); } } return "ticket sold out!
目录 基础知识多线程与高并发Java多线程涉及技术点高并发技术解决方案 并发编程的优劣为什么要使用并发编程(并发编程的优点)并发编程有什么缺点并发编程三要素是什么?在 Java 程序中怎么保证多线程的运行安全?并行和并发有什么区别?什么是多线程,多线程的优劣? 线程和进程区别什么是线程和进程?什么是上下文切换?(重点)守护线程和用户线程有什么区别呢?如何在 Windows 和 Linux 上查找哪个线程cpu利用率最高?什么是线程死锁形成死锁的四个必要条件是什么如何避免线程死锁? 创建线程的四种方式创建线程有哪几种方式?说一下 runnable 和 callable 有什么区别?线程的 run()和 start()有什么区别?为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 方法?(重要)什么是 Callable 和 Future?什么是 FutureTask 线程的状态和基本操作说说线程的生命周期及五种基本状态?Java 中用到的线程调度算法是什么?线程的调度策略什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing )?请说出与线程同步以及线程调度相关的方法。sleep() 和 wait() 有什么区别?(重点)你是如何调用 wait() 方法的?使用 if 块还是循环?为什么?为什么线程通信的方法 wait(), notify()和 notifyAll()被定义在 Object 类里?为什么 wait(), notify()和 notifyAll()必须在同步方法或者同步块中被调用?Thread 类中的 yield 方法有什么作用?为什么 Thread 类的 sleep()和 yield ()方法是静态的?线程的 sleep()方法和 yield()方法有什么区别?如何停止一个正在运行的线程?Java 中 interrupted 和 isInterrupted 方法的区别?什么是阻塞式方法?Java 中你怎样唤醒一个阻塞的线程?notify() 和 notifyAll() 有什么区别?(重点)如何在两个线程间共享数据?(重点)Java 如何实现多线程之间的通讯和协作?同步方法和同步块,哪个是更好的选择?什么是线程同步和线程互斥,有哪几种实现方式?在监视器(Monitor)内部,是如何做线程同步的?程序应该做哪种级别的同步?如果你提交任务时,线程池队列已满,这时会发生什么?什么叫线程安全?servlet 是线程安全吗?在 Java 程序中怎么保证多线程的运行安全?你对线程优先级的理解是什么?线程类的构造方法、静态块是被哪个线程调用的Java 中怎么获取一份线程 dump 文件?你如何在 Java 中获取线程堆栈?一个线程运行时发生异常会怎样?Java 线程数过多会造成什么异常? 并发理论Java内存模型Java中垃圾回收有什么目的?什么时候进行垃圾回收?如果对象的引用被置为null,垃圾收集器是否会立即释放对象占用的内存?finalize()方法什么时候被调用?析构函数(finalization)的目的是什么?重排序与数据依赖性为什么代码会重排序? as-if-serial规则和happens-before规则的区别?(JMM方面内容)数据依赖重排序带来的问题 并发关键字(重要)synchronizedsynchronized的作用?说说自己是怎么使用 synchronized 关键字,在项目中用到了吗?说一下 synchronized 底层实现原理?什么是自旋多线程中 synchronized 锁升级的原理是什么?线程 B 怎么知道线程 A 修改了变量当一个线程进入一个对象的 synchronized 方法 A 之后,其它线程是否可进入此对象的 synchronized 方法 B?synchronized、volatile、CAS 比较synchronized 和 Lock 有什么区别?synchronized 和 ReentrantLock 区别是什么? volatile你能说说volatile 关键字的作用吗?Java 中能创建 volatile 数组吗?volatile 变量和 atomic 变量有什么不同?volatile 能使得一个非原子操作变成原子操作吗?volatile 修饰符的有过什么实践?synchronized 和 volatile 的区别是什么?(重点) final什么是不可变对象,它对写并发应用有什么帮助? Lock体系Lock简介与初识AQSJava Concurrency API 中的 Lock 接口(Lock interface)是什么?对比同步它有什么优势?乐观锁和悲观锁的理解及如何实现,有哪些实现方式?什么是 CASCAS 的会产生什么问题?(重要)什么是死锁?产生死锁的条件是什么?怎么防止死锁?(重要)死锁与活锁的区别,死锁与饥饿的区别?多线程锁的升级原理是什么? AQS(AbstractQueuedSynchronizer)详解与源码分析 (重点)AQS 介绍AQS 原理分析 ReentrantLock(重入锁)实现原理与公平锁非公平锁区别什么是可重入锁(ReentrantLock)?(重点) 读写锁ReentrantReadWriteLock源码分析ReadWriteLock 是什么 Condition源码分析与等待通知机制LockSupport详解 并发容器并发容器之ConcurrentHashMap详解(JDK1.
Dji Manifold2-G、Jetson TX2源码编译安装pytorch 最近由于所承担项目的实际需求,需要在Dji Manifold2-G上面配置深度学习的网络框架pytorch。Dji Manifold2-G实际上是集成了一块NVIDIA Jetson TX2的GPU模块,并提供多种接口用来连接不同的外部设备,体积小,操作便捷,非常适合于作为机载的一种处理器。自己在实际的编译过程中遇到各种Bug,各种网上寻找解决方案,现在将自己的源码编译安装pytorch过程整理处理,方便以后需要的开发者们节省更多时间。
一、安装cudnn 源码编译安装pytorch的时候会使用cuda和cudnn,Dji Manifold2-G出厂自带的有cuda9.0,因此不需要安装cuda,只需要安装对应cuda9.0版本的cudnn,Dji Manifold2-G的CPU是基于ARM架构的,即对应的是aarch64,因此去官网下载的时候应该下载对应版本的cudnn,下面给出我自己使用版本的一个链接。
http://developer.download.nvidia.com/compute/redist/cudnn/v7.1.1/cudnn-9.0-linux-x64-v7.1.tgz
安装cudnn
~$ cd data/ ~$ sudo tar xvf cudnn-9.0-linux-x64-v7.1.tgz ~$ mkdir cudnn7 ~$ sudo cp -r cuda cudnn7 ~$ cd cudnn7 ~$ sudo cp include/cudnn.h /usr/local/cuda/include/ ~$ sudo cp lib64/* /usr/local/cuda/lib64/ ~$ cd /usr/local/cuda/lib64/ /usr/local/cuda/lib64$ sudo chmod +r libcudnn.so.7.1.1 /usr/local/cuda/lib64$ sudo rm -rf libcudnn.so libcudnn.so.7 /usr/local/cuda/lib64$ sudo ln -s libcudnn.so.7.1.1 libcudnn.so.7 /usr/local/cuda/lib64$ sudo ln -s libcudnn.so.7 libcudnn.
网络安全工程师千峰学习总结第四天 前期回顾 1.虚拟化技术:vmware vsphere
2.格式化格式:NTFS FAT
3.ctrl+alt
4.企业 Enterprise 专业 professional 服务器 server 客户端 client C/S客户机服务器----BS浏览器服务器
5.虚拟机克隆:链接克隆,完全克隆
第三章IP地址详解 一、局域网
局域网:一般称为内网
简单局域网的构成:交换机、网线、pc
交换机:用来组建内网的局域网的设备
二、IP地址
IP地址是一个唯一标识,是一段网络编码(二进制)由32位组成
将32位二进制转换成4位十进制 (点分十进制)
ip地址范围(0-255)
三、子网掩码
局域网通行规则:在同一个局域网中,所有的ip必须在同一个网段中才可以互相通信
IP地址构成:网络位+主机位(网络位相同的IP地址,为同一网段)
子网掩码如何确认网络位:与255对应的数字为网络位,与0对应的数字为主机位
四、IP地址详解
ISO( 国际标准化组织)定义地址分类:五大类(是以IP地址的第一位进行区分的)
A类 :1-126 默认子网掩码:255.0.0.0(主机位全部为0,代表网段,主机位全部为255,代表该网段的广播地址)
127.0.0.1回环地址(代表自己)
B类:128-191 默认子网掩码:255.255.0.0(主机位不能全为0,也不能全为255)
C类:192-223 默认子网掩码:255.255.255.0
D类:224-239 组播地址(一个地址代表一组人)单播地址(一个地址代表一个人)
E类:240-255 科研使用
配置ip地址:点击网上邻居–》右击网络连接–》属性–》tcp/ip协议–》使用下面ip地址 注:目前我们可以使用的只有ABC三类ip地址 案例一、
10.1.1.1
255.255.255.0
问:10.1.1.1属于哪个网段?所在网段有多少个可用的ip地址?该网段的广播地址是什么?
答:属于10.1.1.0网段 10.1.1.1-10.1.1.254 10.1.1.255为广播地址(网络的大喇叭)
案例二、
10.1.1.1
255.255.0.0
问:10.1.1.1属于哪个网段?所在网段有多少个可用的ip地址?该网段的广播地址是什么?
答:属于10.1.0.0网段 10.1.0.1-10.1.255.254 (65536) 10.1.255.255为广播地址(网络的大喇叭)
五、网关
网关:一个网络的出口,Gateway=GW,一般网关是在路由器上(一般都是该网段的第一个或者最后一个,如下图网关为10.1.1.254)
路由器:可用连接内外网的设备
网络工程师面试题:这台pc访问另一台pc它的心理活动
1.当这个地址尝试向另一台pc发送地址包,先把自己的ip与目的ip进行比较是否在同一网段
2.在同一网段,直接发出去,不找网关,不在同一网段时,与路由器(网关)进行通信,网关进行转发(总出口)
什么是numpy? 》一个在python中做科学计算的基础库,重在数值计算,也是大部分python科学计算库的基础库,多用于大型、多维数组上执行数值运算
一、数组(numpy)的创建和基本使用 》代码讲解
import numpy as np import random # numpy创建数组 都是该类型:<class 'numpy.ndarray'> t1 = np.array([1, 2, 3]) # [1 2 3] t2 = np.array(range(10)) # [0 1 2 3 4 5 6 7 8 9] t3 = np.arange(10) # [0 1 2 3 4 5 6 7 8 9] # dtype用于查看数组中的数据类型 print(t3.dtype) # int32 # 给数组指定数据类型(以下两种写法皆可) t4 = np.array(range(1, 4), dtype=float) # [1. 2. 3.] t41 = np.
在这里为了举例的方便,没有使用线程池来执行任务,而是调用了Thread对象的方法,要注意推荐执行多线程的方式还是线程池。
多线程实现步骤:
定义Runnable接口的实现类,并重写该接口的run()方法,run()方法的内容就是该线程要执行的内容创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象调用线程对象的start()方法来启动该线程 与直接继承Thread类相比,通过Runnable接口实现多线程有一点区别,如果继承了Thread类,同时也会直接继承start()方法,但是如果实现的是Runnable接口,那此时并没有start()方法可以调用。
所以要想启动多线程,可以依靠Thread类完成。Thread类有如下的构造方法:
public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); } 接受的是Runnable接口对象,自然可以接收Runnable子类。
使用Runnable接口实现完整多线程的过程如下:
public class test extends Thread{ public static void main(String[] args) { MyThread thread1=new MyThread("test1"); MyThread thread2=new MyThread("test2"); MyThread thread3=new MyThread("test3"); new Thread(thread1).start(); new Thread(thread2).start(); new Thread(thread3).start(); } } class MyThread implements Runnable{ private String name; public MyThread(String name){ this.name=name; } @Override public void run(){ for(int i=0;i<200;i++){ System.out.println(this.name+"--->"+i); } } } 输出的部分结果如下:
慢查询日志:MYSQL提供的一种日志记录,用于记录MYSQL的响应时间超过阈值的sql语句(long_query_time默认10秒)。
检查是否开启了慢查询日志的命令:show variables like '%slow_query_log%';
l临时开启mysql的命令:set global slow_query_log = 1;
注意:这里的临时开启指的是关闭mysql服务后再次进入mysql
查询慢查询阈值的命令:show variables like 'long_query_time';
临时设置阈值:set global long_query_time = 5;
注意:这里的临时开启指的是重新登陆后就起效,不需要重启服务
mysql慢sql日志文件保存的位置:
/var/lib/mysql/hadoop1-slow.log(每个人的电脑上的位置可能不一样)
查看慢sql查询的方法:
(1)通过cat /var/lib/mysql/hadoop1-slow.log查看日志信息。
(2)使用mysqldumpslow工具查看。(不再数据库中,在linux系统中进行操作)
使用mysqldump --help可以查看指令的含义。
–获取返回记录最多的3个SQL
mysqldumpslow -s r -t 3 /var/lib/mysql/handoop1-slow.log
--获取访问次数最多的3个SQL mysqldumpslow -s c -t 3 /var/lib/mysql/handoop1-slow.log --按照时间排序,前10条包含left join查询语句的SQL mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/handoop1-slow.log 语法: mysqldumpslow 各种参数 慢查询日志的文件
今天运行一个程序,发现一个很有意思的情况,可以看到代码如下所示
public static void main(String[] args) { float a = 1; for (int i = 0; i<20000000; i++) { a++; } System.out.println(a); } public static void main(String[] args) { float a = 20000000; float b = a + 1; float c = b - a; System.out.println(b); System.out.println(c); } 上面两段代码的输出结果是什么呢?输出结果如下:
1.6777216E7
2.0E7
0.0
好像和我们预期的不太一样,为什么会出现这种情况呢?那就要从我们的计算机底层说起,计算机内只有0,1来表示内容,对于整数我们知道可以转化为2进制去表示,那么对于小数,计算机内部是怎么表示的呢?在计算机内部有一个公式来表示小数;公式如下:
以32位计算机来说
其中:s-为符号位。占用一个bit位,表示是正数还是负数的作用。
e-为指数位,占用8个bit位,也就是可以表示0~255个数字。
f-为有效位,占用23个bit位,用来表示小数点后的有效位数。
以小数0.5为例,转化成上面的公式就表示如下:
为什么浮点数进行相加会出现精度丢失呢?
首先我们要知道浮点数进行相加需要遵守的原则就是先对齐,在计算,因为两个浮点数进行加法运算的时候,可能指数位是不一致的,所以需要先把指数位保持一致,然后再去计算有效位的加法就可以了。
以0.5 + 0.125为例:
数字s位大小e位大小f位0.50-11.0...0.1250-31.00...0.125向0.5进行指数对齐后0-10.01.... 所以计算结果为
所以在加法运算过程中,指数位较小的数,需要在有效位进行右移,在右移的过程中,最右侧的有效位就被丢弃掉了。这会导致对应的指数位较小的数,在加法发生之前,就丢失精度。其中有效位置有23位,当两个数的指数位相差23位后,对应的右移23位后,所有的有效位全部丢失,所以就会出现相面的计算情况。